summaryrefslogtreecommitdiffstats
path: root/target
diff options
context:
space:
mode:
Diffstat (limited to 'target')
-rw-r--r--target/imagebuilder/Makefile3
-rw-r--r--target/linux/apm821xx/dts/netgear-wndap6x0.dtsi2
-rw-r--r--target/linux/archs38/Makefile2
-rw-r--r--target/linux/archs38/config-6.1268
-rw-r--r--target/linux/archs38/config-6.6279
-rw-r--r--target/linux/archs38/generic/target.mk2
-rw-r--r--target/linux/armsr/armv8/config-6.63
-rw-r--r--target/linux/armsr/base-files/etc/inittab2
-rw-r--r--target/linux/armsr/config-6.61
-rw-r--r--target/linux/armsr/image/Makefile1
-rw-r--r--target/linux/armsr/patches-6.1/701-v6.2-0011-net-dpaa2-switch-serialize-changes-to-priv-mac-with.patch2
-rw-r--r--target/linux/armsr/patches-6.1/701-v6.2-0012-net-dpaa2-mac-move-rtnl_lock-only-around-phylink.patch2
-rw-r--r--target/linux/ath79/dts/ar7242_tplink_tl-wr2543-v1.dts2
-rw-r--r--target/linux/ath79/dts/ar9344_huawei_ap6010dn.dts243
-rw-r--r--target/linux/ath79/dts/ar9344_nec_aterm.dtsi300
-rw-r--r--target/linux/ath79/dts/ar9344_nec_wg600hp.dts16
-rw-r--r--target/linux/ath79/dts/ar9344_nec_wr8750n.dts16
-rw-r--r--target/linux/ath79/dts/ar9344_nec_wr9500n.dts39
-rw-r--r--target/linux/ath79/dts/ar9344_qihoo_c301.dts8
-rw-r--r--target/linux/ath79/dts/qca9557_sophos_ap15.dts148
-rw-r--r--target/linux/ath79/dts/qca9557_zyxel_nbg6616.dts2
-rw-r--r--target/linux/ath79/dts/qca9558_sophos_ap15.dts163
-rw-r--r--target/linux/ath79/dts/qca9558_zyxel_emg2926_q10a.dts2
-rw-r--r--target/linux/ath79/dts/qca9558_zyxel_nbg6716.dts2
-rw-r--r--target/linux/ath79/dts/qca955x_elecom_wab.dtsi17
-rw-r--r--target/linux/ath79/dts/qca9561_nec_wf1200cr.dts7
-rw-r--r--target/linux/ath79/dts/qca9563_nec_wg1200cr.dts7
-rw-r--r--target/linux/ath79/dts/qca9563_nec_wg800hp.dts29
-rw-r--r--target/linux/ath79/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c31
-rw-r--r--target/linux/ath79/generic/base-files/etc/board.d/02_network5
-rw-r--r--target/linux/ath79/generic/base-files/etc/hotplug.d/firmware/10-ath9k-eeprom10
-rw-r--r--target/linux/ath79/generic/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac12
-rw-r--r--target/linux/ath79/generic/base-files/lib/upgrade/platform.sh3
-rw-r--r--target/linux/ath79/image/common-nec.mk25
-rw-r--r--target/linux/ath79/image/generic-ubnt.mk1
-rw-r--r--target/linux/ath79/image/generic.mk22
-rw-r--r--target/linux/ath79/image/lzma-loader/src/ar71xx_regs.h1
-rw-r--r--target/linux/ath79/image/lzma-loader/src/board.c89
-rw-r--r--target/linux/ath79/image/nand.mk2
-rw-r--r--target/linux/ath79/image/tiny.mk31
-rw-r--r--target/linux/ath79/patches-6.6/317-MIPS-pci-ar724x-clear-power-down-of-pll-on-AR934x.patch34
-rw-r--r--target/linux/ath79/patches-6.6/318-MIPS-pci-ar724x-deassert-the-reset-of-PCIe-endpoint.patch41
-rw-r--r--target/linux/ath79/patches-6.6/330-missing-registers.patch2
-rw-r--r--target/linux/ath79/patches-6.6/331-MIPS-ath79-add-missing-QCA955x-GMAC-registers.patch4
-rw-r--r--target/linux/ath79/patches-6.6/332-ath79-sgmii-config.patch2
-rw-r--r--target/linux/ath79/patches-6.6/340-register_gpio_driver_earlier.patch26
-rw-r--r--target/linux/ath79/patches-6.6/360-MIPS-ath79-export-UART1-reference-clock.patch4
-rw-r--r--target/linux/ath79/patches-6.6/430-mtd-ar934x-nand-driver.patch2
-rw-r--r--target/linux/ath79/patches-6.6/810-ath79-ignore-the-abused-interrupt-map-on-pcie-node.patch2
-rw-r--r--target/linux/ath79/patches-6.6/900-unaligned_access_hacks.patch14
-rw-r--r--target/linux/ath79/patches-6.6/910-mikrotik-rb4xx.patch2
-rw-r--r--target/linux/ath79/patches-6.6/911-mikrotik-rb91x.patch2
-rw-r--r--target/linux/ath79/tiny/base-files/etc/board.d/02_network17
-rw-r--r--target/linux/ath79/tiny/base-files/lib/upgrade/platform.sh18
-rw-r--r--target/linux/bcm27xx/bcm2708/config-6.64
-rw-r--r--target/linux/bcm27xx/bcm2709/config-6.64
-rw-r--r--target/linux/bcm27xx/bcm2710/config-6.67
-rw-r--r--target/linux/bcm27xx/bcm2711/config-6.67
-rw-r--r--target/linux/bcm27xx/bcm2712/config-6.68
-rw-r--r--target/linux/bcm27xx/config-6.61
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0058-Revert-Bluetooth-Always-request-for-user-confirmatio.patch6
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0065-cgroup-Disable-cgroup-memory-by-default.patch8
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0070-spi-spidev-Completely-disable-the-spidev-warning.patch2
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0103-Improve-__copy_to_user-and-__copy_from_user-performa.patch2
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0106-Add-support-for-all-the-downstream-rpi-sound-card-dr.patch4
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0113-ARM64-Force-hardware-emulation-of-deprecated-instruc.patch2
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0161-xhci-implement-xhci_fixup_endpoint-for-interval-adju.patch4
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0163-usb-xhci-drop-and-add-the-endpoint-context-in-xhci_f.patch2
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0169-hid-usb-Add-device-quirks-for-Freeway-Airmouse-T3-an.patch2
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0214-gpiolib-Don-t-prevent-IRQ-usage-of-output-GPIOs.patch6
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0277-kbuild-Silence-unavoidable-dtc-overlay-warnings.patch2
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0320-spi-spidev-Restore-loading-from-Device-Tree.patch2
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0416-gpio-pca953x-Add-ti-tca9554-compatible-string.patch2
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0441-Bluetooth-hci_sync-Add-fallback-bd-address-prop.patch4
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0485-usb-xhci-add-XHCI_VLI_HUB_TT_QUIRK.patch6
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0490-input-ads7846-Add-missing-spi_device_id-strings.patch49
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0519-usb-dwc3-Set-DMA-and-coherent-masks-early.patch16
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0526-mfd-Add-rp1-driver.patch10
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0679-drm-fb-helper-Look-up-preferred-fbdev-node-number-fr.patch4
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0684-drm-fb_helper-Change-query-for-FB-designation-from-d.patch2
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0714-spi-dw-dma-Get-the-last-DMA-scoop-out-of-the-FIFO.patch41
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-0853-drivers-usb-dwc3-add-FS-LS-bus-instance-parkmode-dis.patch4
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1141-fs-ntfs3-Fix-memory-corruption-when-page_size-change.patch2
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1146-drivers-dwc_otg-use-C11-style-variable-array-declara.patch260
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1147-media-uapi-pixfmt-luma-Document-MIPI-CSI-2-packing.patch27
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1148-media-uapi-Add-a-pixel-format-for-BGR48-and-RGB48.patch101
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1149-media-uapi-Add-Raspberry-Pi-PiSP-Back-End-uAPI.patch1171
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1150-media-uapi-Document-meta-pixel-format-for-PiSP-BE-co.patch86
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1151-media-uapi-Document-PiSP-Compressed-RAW-Bayer-format.patch106
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1152-media-dt-bindings-Add-bindings-for-Raspberry-Pi-PiSP.patch97
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1153-media-admin-guide-Document-the-Raspberry-Pi-PiSP-BE.patch162
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1154-media-pisp-be-Backport-the-mainline-PiSP-BE-driver.patch2927
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1155-media-uapi-pisp_be_config-Drop-BIT-from-uAPI.patch29
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1156-media-uapi-pisp_common-Add-32-bpp-format-test.patch32
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1157-media-uapi-Capitalize-all-macros.patch89
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1158-media-uapi-pisp_be_config-Re-sort-pisp_be_tiles_conf.patch30
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1159-media-uapi-pisp_be_config-Add-extra-config-fields.patch82
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1160-media-pisp_be-Re-introduce-multi-context-support.patch886
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1161-media-pisp_be-Re-introduce-video-node-offset.patch36
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1163-dts-Make-camN_reg-and-camN_reg_gpio-overrides-generi.patch158
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1164-spi-dt-bindings-Add-RPI-RP2040-GPIO-Bridge.patch108
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1165-spi-Add-a-driver-for-the-RPI-RP2040-GPIO-bridge.patch1288
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1166-dmaengine-dw-axi-dmac-Honour-snps-block-size.patch52
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1167-mmc-restrict-posted-write-counts-for-SD-cards-in-CQ-.patch157
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1168-fixup-mmc-restrict-posted-write-counts-for-SD-cards-.patch70
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1169-mmc-brcmstb-don-t-squash-card-busy-detection-on-bcm2.patch28
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1172-Revert-Update-DAC8x-to-support-384khz-6187.patch25
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1176-dt-bindings-clk-rp1-Add-clocks-representing-MIPI-DSI.patch25
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1177-clk-clk-rp1-Add-varsrc-clocks-to-represent-MIPI-byte.patch132
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1178-dts-rp1-DSI-drivers-to-use-newly-defined-MIPI-byte-s.patch92
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1179-drm-rp1-rp1-dsi-Switch-to-PLL_SYS-source-for-DPI-whe.patch313
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1180-arm64-dts-Move-bcm2712-and-rp1-here.patch9749
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1181-arm64-dts-Add-cm5l-files.patch92
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1182-dts-bcm2712-Dedup-the-aliases-and-overrides.patch408
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1183-arm64-dts-Give-cm5l-its-own-model-name.patch24
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1185-pinctrl-rp1-jump-through-hoops-to-avoid-PCIe-latency.patch288
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1186-staging-bcm2835-codec-Disable-HEADER_ON_OPEN-for-vid.patch36
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1188-staging-bcm2835-codec-Add-support-for-H264-level-5.0.patch36
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1189-spi-dw-Save-bandwidth-with-the-TMOD_TO-feature.patch66
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1190-spi-dw-Save-bandwidth-with-the-TMOD_RO-feature.patch186
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1191-spi-dw-don-t-immediately-kill-DMA-transfers-if-an-er.patch41
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1192-dts-rp1-hobble-DMA-AXI-burst-lengths.patch35
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1193-drivers-dw-axi-dmac-make-more-sensible-choices-about.patch124
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1195-tty-serial-pl011-restrict-RX-burst-FIFO-threshold.patch30
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1196-DT-bindings-add-a-dma-maxburst-property-to-snps-desi.patch27
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1197-sound-soc-dwc-i2s-choose-FIFO-thresholds-based-on-DM.patch99
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1198-dts-rp1-restrict-i2s-burst-lengths-to-4.patch30
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1199-drm-vc4-Disable-the-2pixel-clock-odd-timings-workaro.patch204
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1200-ARM-dts-bcm2712-Fix-invalid-polling-delay-passive-se.patch26
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1201-spi-dw-Fix-non-DMA-transmit-only-transfers.patch143
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1202-spi-dw-Clamp-the-minimum-clock-speed.patch26
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1203-overlays-i2c-rtc-Correct-bq32000-property-name.patch26
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1204-hwmon-adt7410-Add-DT-compatible-strings.patch31
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1205-fixup-pinctrl-bcm2712-pinctrl-pinconf-driver.patch23
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1206-dtoverlays-Add-overlay-for-HD44780-via-I2C-PCF8574-b.patch125
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1207-dtoverlays-Document-display_-width-height-on-hd44780.patch28
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1208-DTS-bcm2712-enable-SD-slot-CQE-by-default-on-Pi-5.patch39
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1211-gpiolib-Override-gpiochip-numbers-with-DT-aliases.patch50
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1212-dts-bcm2712-rpi-Add-gpiochip0-alias.patch23
-rw-r--r--target/linux/bcm27xx/patches-6.6/950-1213-dts-bcm2712-rpi-The-SoC-gpiochips-start-at-10.patch24
-rw-r--r--target/linux/bcm47xx/patches-6.6/830-huawei_e970_support.patch8
-rw-r--r--target/linux/bcm4908/Makefile3
-rw-r--r--target/linux/bcm4908/config-6.1245
-rw-r--r--target/linux/bcm4908/patches-6.1/035-v6.2-0001-arm64-dts-broadcom-bcmbca-bcm4908-add-TWD-block-time.patch31
-rw-r--r--target/linux/bcm4908/patches-6.1/035-v6.2-0002-arm64-dts-broadcom-bcmbca-bcm6858-add-TWD-block.patch46
-rw-r--r--target/linux/bcm4908/patches-6.1/035-v6.2-0003-arm64-dts-Update-cache-properties-for-broadcom.patch134
-rw-r--r--target/linux/bcm4908/patches-6.1/036-v6.4-0001-arm64-dts-broadcom-bcmbca-Add-spi-controller-node.patch367
-rw-r--r--target/linux/bcm4908/patches-6.1/036-v6.4-0005-arm64-dts-broadcom-bcmbca-bcm4908-add-on-SoC-USB-por.patch81
-rw-r--r--target/linux/bcm4908/patches-6.1/036-v6.4-0006-arm64-dts-broadcom-bcmbca-bcm4908-add-Netgear-R8000P.patch38
-rw-r--r--target/linux/bcm4908/patches-6.1/036-v6.4-0007-arm64-dts-broadcom-bcmbca-bcm4908-add-TP-Link-C2300-.patch41
-rw-r--r--target/linux/bcm4908/patches-6.1/072-v6.2-0001-net-broadcom-bcm4908_enet-use-build_skb.patch152
-rw-r--r--target/linux/bcm4908/patches-6.1/072-v6.2-0002-net-broadcom-bcm4908_enet-report-queued-and-transmit.patch45
-rw-r--r--target/linux/bcm4908/patches-6.1/130-arm64-dts-broadcom-bcmbca-bcm4908-set-brcm-wp-not-co.patch31
-rw-r--r--target/linux/bcm4908/patches-6.1/180-leds-bcm63138-rename-dependency-symbol-ARCH_BCM4908-.patch32
-rw-r--r--target/linux/bcm4908/patches-6.1/300-arm64-dts-broadcom-bcmbca-bcm4908-limit-amount-of-GP.patch23
-rw-r--r--target/linux/bcm4908/patches-6.1/301-arm64-don-t-issue-HVC-on-boot.patch30
-rw-r--r--target/linux/bcm4908/patches-6.1/700-net-dsa-bcm_sf2-enable-GPHY-for-switch-probing.patch46
-rw-r--r--target/linux/bcm4908/patches-6.1/701-net-dsa-bcm_sf2-keep-GPHY-enabled-on-the-BCM4908.patch30
-rw-r--r--target/linux/bcm4908/patches-6.6/700-net-dsa-bcm_sf2-enable-GPHY-for-switch-probing.patch2
-rw-r--r--target/linux/bcm4908/patches-6.6/701-net-dsa-bcm_sf2-keep-GPHY-enabled-on-the-BCM4908.patch2
-rw-r--r--target/linux/bcm53xx/Makefile3
-rw-r--r--target/linux/bcm53xx/config-5.15317
-rw-r--r--target/linux/bcm53xx/config-6.1339
-rw-r--r--target/linux/bcm53xx/image/Makefile4
-rw-r--r--target/linux/bcm53xx/patches-5.15/030-v5.15-0001-ARM-dts-NSP-add-device-names-to-compatible.patch97
-rw-r--r--target/linux/bcm53xx/patches-5.15/030-v5.15-0002-ARM-dts-NSP-enable-DMA-on-bcm988312hr.patch29
-rw-r--r--target/linux/bcm53xx/patches-5.15/030-v5.15-0003-ARM-dts-NSP-disable-qspi-node-by-default.patch113
-rw-r--r--target/linux/bcm53xx/patches-5.15/030-v5.15-0004-ARM-dts-NSP-add-MDIO-bus-controller-node.patch30
-rw-r--r--target/linux/bcm53xx/patches-5.15/030-v5.15-0005-ARM-dts-NSP-Move-USB3-PHY-to-internal-MDIO-bus.patch85
-rw-r--r--target/linux/bcm53xx/patches-5.15/030-v5.15-0006-ARM-dts-NSP-Add-common-bindings-for-MX64-MX65.patch148
-rw-r--r--target/linux/bcm53xx/patches-5.15/030-v5.15-0007-ARM-dts-NSP-Add-Ax-stepping-modifications.patch90
-rw-r--r--target/linux/bcm53xx/patches-5.15/030-v5.15-0008-ARM-dts-NSP-Add-DT-files-for-Meraki-MX64-series.patch340
-rw-r--r--target/linux/bcm53xx/patches-5.15/030-v5.15-0009-ARM-dts-NSP-Add-DT-files-for-Meraki-MX65-series.patch386
-rw-r--r--target/linux/bcm53xx/patches-5.15/030-v5.16-0013-ARM-dts-NSP-Add-bcm958623hr-board-name-to-dts.patch27
-rw-r--r--target/linux/bcm53xx/patches-5.15/030-v5.16-0015-ARM-dts-NSP-Fix-MDIO-mux-node-names.patch47
-rw-r--r--target/linux/bcm53xx/patches-5.15/030-v5.16-0016-ARM-dts-NSP-Fix-MX64-MX65-eeprom-node-name.patch28
-rw-r--r--target/linux/bcm53xx/patches-5.15/030-v5.16-0017-ARM-dts-NSP-Fix-MX65-MDIO-mux-warnings.patch52
-rw-r--r--target/linux/bcm53xx/patches-5.15/030-v5.16-0018-ARM-dts-BCM5301X-Specify-switch-ports-for-more-devic.patch290
-rw-r--r--target/linux/bcm53xx/patches-5.15/030-v5.16-0020-ARM-dts-BCM53573-Add-Tenda-AC9-switch-ports.patch59
-rw-r--r--target/linux/bcm53xx/patches-5.15/030-v5.16-0021-ARM-BCM53016-Specify-switch-ports-for-Meraki-MR32.patch57
-rw-r--r--target/linux/bcm53xx/patches-5.15/030-v5.16-0022-ARM-BCM53016-MR32-get-mac-address-from-nvmem.patch41
-rw-r--r--target/linux/bcm53xx/patches-5.15/030-v5.16-0023-ARM-dts-BCM5301X-Add-DT-for-Asus-RT-AC88U.patch242
-rw-r--r--target/linux/bcm53xx/patches-5.15/031-v5.17-0001-ARM-dts-NSP-MX65-add-qca8k-falling-edge-PLL-properti.patch42
-rw-r--r--target/linux/bcm53xx/patches-5.15/031-v5.17-0002-ARM-dts-BCM5301X-remove-unnecessary-address-size-cel.patch29
-rw-r--r--target/linux/bcm53xx/patches-5.15/031-v5.17-0003-ARM-dts-BCM5301X-define-RTL8365MB-switch-on-Asus-RT-.patch104
-rw-r--r--target/linux/bcm53xx/patches-5.15/031-v5.17-0004-ARM-BCM53016-MR32-convert-to-Broadcom-iProc-I2C-Driv.patch104
-rw-r--r--target/linux/bcm53xx/patches-5.15/031-v5.17-0006-ARM-dts-BCM5301X-use-non-deprecated-USB-2.0-PHY-bind.patch54
-rw-r--r--target/linux/bcm53xx/patches-5.15/031-v5.17-0007-ARM-dts-NSP-Fixed-iProc-PCIe-MSI-sub-node.patch42
-rw-r--r--target/linux/bcm53xx/patches-5.15/031-v5.17-0008-ARM-dts-NSP-Rename-SATA-unit-name.patch25
-rw-r--r--target/linux/bcm53xx/patches-5.15/031-v5.17-0009-ARM-dts-BCM5301X-correct-RX-delay-and-enable-flow-co.patch45
-rw-r--r--target/linux/bcm53xx/patches-5.15/031-v5.17-0010-Revert-ARM-dts-BCM5301X-define-RTL8365MB-switch-on-A.patch109
-rw-r--r--target/linux/bcm53xx/patches-5.15/032-v5.18-0001-ARM-dts-BCM5301X-define-RTL8365MB-switch-on-Asus-RT-.patch103
-rw-r--r--target/linux/bcm53xx/patches-5.15/032-v5.18-0002-ARM-dts-NSP-MX6X-get-mac-address-from-eeprom.patch40
-rw-r--r--target/linux/bcm53xx/patches-5.15/032-v5.18-0003-ARM-dts-NSP-MX6X-correct-LED-function-types.patch62
-rw-r--r--target/linux/bcm53xx/patches-5.15/032-v5.18-0004-ARM-dts-BCM5301X-Add-Ethernet-MAC-address-to-Luxul-X.patch42
-rw-r--r--target/linux/bcm53xx/patches-5.15/033-v5.19-0002-ARM-dts-BCM5301X-Fix-DTC-warning-for-NAND-node.patch31
-rw-r--r--target/linux/bcm53xx/patches-5.15/033-v5.19-0003-ARM-dts-BCM5301X-Remove-cell-properties-from-srab-po.patch40
-rw-r--r--target/linux/bcm53xx/patches-5.15/033-v5.19-0004-ARM-dts-BCM5301X-Add-rgmii-to-port-5-of-Broadcom-swi.patch29
-rw-r--r--target/linux/bcm53xx/patches-5.15/033-v5.19-0005-ARM-dts-BCM5301X-Retrieve-gmac1-MAC-address-from-NVR.patch43
-rw-r--r--target/linux/bcm53xx/patches-5.15/033-v5.19-0006-ARM-dts-BCM5301X-Fix-compatible-strings-for-BCM53012.patch65
-rw-r--r--target/linux/bcm53xx/patches-5.15/033-v5.19-0007-ARM-dts-BCM5301X-Disable-gmac0-and-enable-port-8-on-.patch39
-rw-r--r--target/linux/bcm53xx/patches-5.15/033-v5.19-0008-ARM-dts-BCM5301X-Add-DT-for-WZR-1166DHP-DHP2.patch300
-rw-r--r--target/linux/bcm53xx/patches-5.15/033-v5.19-0009-Revert-ARM-dts-BCM5301X-Fix-DTC-warning-for-NAND-nod.patch32
-rw-r--r--target/linux/bcm53xx/patches-5.15/034-v6.0-0001-ARM-dts-broadcom-align-gpio-key-node-names-with-dtsc.patch912
-rw-r--r--target/linux/bcm53xx/patches-5.15/034-v6.0-0002-ARM-dts-broadcom-correct-gpio-keys-properties.patch108
-rw-r--r--target/linux/bcm53xx/patches-5.15/035-v6.2-0001-ARM-dts-bcm53016-Add-devicetree-for-D-Link-DWL-8610A.patch165
-rw-r--r--target/linux/bcm53xx/patches-5.15/035-v6.2-0002-ARM-dts-bcm47094-Add-devicetree-for-D-Link-DIR-890L.patch242
-rw-r--r--target/linux/bcm53xx/patches-5.15/035-v6.2-0003-ARM-dts-BCM5301X-Correct-description-of-TP-Link-part.patch99
-rw-r--r--target/linux/bcm53xx/patches-5.15/035-v6.2-0004-ARM-dts-broadcom-align-LED-node-names-with-dtschema.patch1698
-rw-r--r--target/linux/bcm53xx/patches-5.15/036-v6.5-0001-ARM-dts-BCM5301X-Relicense-Rafa-s-code-to-the-GPL-2..patch487
-rw-r--r--target/linux/bcm53xx/patches-5.15/036-v6.5-0002-ARM-dts-BCM5301X-Relicense-Florian-s-code-to-the-GPL.patch136
-rw-r--r--target/linux/bcm53xx/patches-5.15/036-v6.5-0004-ARM-dts-BCM5301X-Relicense-Hauke-s-code-to-the-GPL-2.patch249
-rw-r--r--target/linux/bcm53xx/patches-5.15/036-v6.5-0005-ARM-dts-BCM5301X-Relicense-AXI-interrupts-code-to-th.patch203
-rw-r--r--target/linux/bcm53xx/patches-5.15/036-v6.5-0006-ARM-dts-BCM5301X-Specify-MAC-addresses-on-Luxul-devi.patch336
-rw-r--r--target/linux/bcm53xx/patches-5.15/036-v6.5-0007-ARM-dts-BCM5301X-Use-updated-device-compatible-strin.patch90
-rw-r--r--target/linux/bcm53xx/patches-5.15/036-v6.5-0008-ARM-dts-BCM5301X-Use-updated-spi-gpio-binding-proper.patch82
-rw-r--r--target/linux/bcm53xx/patches-5.15/036-v6.5-0009-ARM-dts-BCM5301X-Drop-invalid-usb-cells.patch54
-rw-r--r--target/linux/bcm53xx/patches-5.15/036-v6.5-0010-ARM-dts-BCM5301X-Drop-invalid-properties-from-Meraki.patch31
-rw-r--r--target/linux/bcm53xx/patches-5.15/036-v6.5-0011-ARM-dts-BCM5301X-Relicense-Christian-s-code-to-the-G.patch106
-rw-r--r--target/linux/bcm53xx/patches-5.15/036-v6.5-0012-ARM-dts-BCM5301X-Describe-switch-ports-in-the-main-D.patch838
-rw-r--r--target/linux/bcm53xx/patches-5.15/036-v6.5-0013-ARM-dts-BCM5301X-MR26-MR32-remove-bogus-nand-ecc-alg.patch63
-rw-r--r--target/linux/bcm53xx/patches-5.15/036-v6.5-0014-ARM-dts-BCM5301X-MR32-remove-partition-index-numbers.patch54
-rw-r--r--target/linux/bcm53xx/patches-5.15/036-v6.5-0016-ARM-dts-BCM5301X-Add-Netgear-R8000-WiFi-regulator-ma.patch61
-rw-r--r--target/linux/bcm53xx/patches-5.15/036-v6.5-0017-ARM-dts-BCM5301X-Add-cells-sizes-to-PCIe-nodes.patch59
-rw-r--r--target/linux/bcm53xx/patches-5.15/037-v6.6-0001-ARM-dts-broadcom-add-missing-space-before.patch37
-rw-r--r--target/linux/bcm53xx/patches-5.15/037-v6.6-0002-ARM-dts-BCM5301X-Add-Wi-Fi-regulatory-mappings-for-L.patch107
-rw-r--r--target/linux/bcm53xx/patches-5.15/037-v6.6-0003-ARM-dts-BCM5301X-Add-Ethernet-interfaces-links.patch53
-rw-r--r--target/linux/bcm53xx/patches-5.15/037-v6.6-0009-ARM-dts-BCM53573-Fix-Ethernet-info-for-Luxul-devices.patch75
-rw-r--r--target/linux/bcm53xx/patches-5.15/037-v6.6-0010-ARM-dts-bcm5301x-Add-SEAMA-compatibles.patch36
-rw-r--r--target/linux/bcm53xx/patches-5.15/037-v6.6-0011-ARM-dts-BCM53573-Fix-Tenda-AC9-switch-CPU-port.patch31
-rw-r--r--target/linux/bcm53xx/patches-5.15/037-v6.6-0012-ARM-dts-BCM53573-Describe-BCM53125-switch-ports-in-t.patch97
-rw-r--r--target/linux/bcm53xx/patches-5.15/037-v6.6-0013-ARM-dts-BCM53573-Add-BCM53125-switch-port-5.patch36
-rw-r--r--target/linux/bcm53xx/patches-5.15/037-v6.6-0014-ARM-dts-BCM53573-Add-Ethernet-interfaces-links.patch73
-rw-r--r--target/linux/bcm53xx/patches-5.15/037-v6.6-0015-ARM-dts-BCM53573-Disable-second-Ethernet-on-Luxul-de.patch39
-rw-r--r--target/linux/bcm53xx/patches-5.15/037-v6.6-0016-ARM-dts-BCM5301X-Add-DT-for-Asus-RT-AC3100.patch431
-rw-r--r--target/linux/bcm53xx/patches-5.15/038-v6.7-0001-ARM-dts-BCM5301X-Set-MACs-for-D-Link-DIR-885L.patch56
-rw-r--r--target/linux/bcm53xx/patches-5.15/038-v6.7-0002-ARM-dts-BCM5301X-Set-MAC-address-for-Asus-RT-AC87U.patch44
-rw-r--r--target/linux/bcm53xx/patches-5.15/038-v6.7-0003-ARM-dts-BCM5301X-Relicense-Felix-s-code-to-the-GPL-2.patch57
-rw-r--r--target/linux/bcm53xx/patches-5.15/038-v6.7-0004-ARM-dts-BCM5301X-Relicense-Vivek-s-code-to-the-GPL-2.patch104
-rw-r--r--target/linux/bcm53xx/patches-5.15/038-v6.7-0005-ARM-dts-BCM5301X-Explicitly-disable-unused-switch-CP.patch377
-rw-r--r--target/linux/bcm53xx/patches-5.15/038-v6.7-0006-ARM-dts-BCM5301X-Set-fixed-link-for-extra-Netgear-R8.patch47
-rw-r--r--target/linux/bcm53xx/patches-5.15/038-v6.7-0007-ARM-dts-BCM5301X-Set-switch-ports-for-Linksys-EA9200.patch63
-rw-r--r--target/linux/bcm53xx/patches-5.15/070-v5.17-phy-bcm-ns-usb2-support-updated-DT-binding-with-PHY-.patch129
-rw-r--r--target/linux/bcm53xx/patches-5.15/080-v6.2-bcma-support-SPROM-rev-11.patch28
-rw-r--r--target/linux/bcm53xx/patches-5.15/140-mtd-parsers-trx-parse-firmware-MTD-partitions-only.patch43
-rw-r--r--target/linux/bcm53xx/patches-5.15/180-usb-xhci-add-support-for-performing-fake-doorbell.patch119
-rw-r--r--target/linux/bcm53xx/patches-5.15/300-ARM-BCM5301X-Disable-MMU-and-Dcache-during-decompres.patch101
-rw-r--r--target/linux/bcm53xx/patches-5.15/304-ARM-dts-BCM5301X-Specify-switch-ports-for-remaining-.patch675
-rw-r--r--target/linux/bcm53xx/patches-5.15/310-ARM-BCM5301X-Add-DT-for-Netgear-R7900.patch64
-rw-r--r--target/linux/bcm53xx/patches-5.15/500-UBI-Detect-EOF-mark-and-erase-all-remaining-blocks.patch59
-rw-r--r--target/linux/bcm53xx/patches-5.15/600-net-disable-GRO-by-default.patch36
-rw-r--r--target/linux/bcm53xx/patches-5.15/700-bgmac-reduce-max-frame-size-to-support-just-MTU-1500.patch33
-rw-r--r--target/linux/bcm53xx/patches-5.15/905-BCM53573-minor-hacks.patch80
-rw-r--r--target/linux/bcm53xx/patches-6.1/030-v6.2-0001-ARM-dts-bcm53016-Add-devicetree-for-D-Link-DWL-8610A.patch165
-rw-r--r--target/linux/bcm53xx/patches-6.1/030-v6.2-0002-ARM-dts-bcm47094-Add-devicetree-for-D-Link-DIR-890L.patch242
-rw-r--r--target/linux/bcm53xx/patches-6.1/030-v6.2-0003-ARM-dts-BCM5301X-Correct-description-of-TP-Link-part.patch99
-rw-r--r--target/linux/bcm53xx/patches-6.1/030-v6.2-0004-ARM-dts-broadcom-align-LED-node-names-with-dtschema.patch1700
-rw-r--r--target/linux/bcm53xx/patches-6.1/031-v6.5-0001-ARM-dts-BCM5301X-Relicense-Rafa-s-code-to-the-GPL-2..patch487
-rw-r--r--target/linux/bcm53xx/patches-6.1/031-v6.5-0002-ARM-dts-BCM5301X-Relicense-Florian-s-code-to-the-GPL.patch136
-rw-r--r--target/linux/bcm53xx/patches-6.1/031-v6.5-0004-ARM-dts-BCM5301X-Relicense-Hauke-s-code-to-the-GPL-2.patch249
-rw-r--r--target/linux/bcm53xx/patches-6.1/031-v6.5-0005-ARM-dts-BCM5301X-Relicense-AXI-interrupts-code-to-th.patch203
-rw-r--r--target/linux/bcm53xx/patches-6.1/031-v6.5-0006-ARM-dts-BCM5301X-Specify-MAC-addresses-on-Luxul-devi.patch336
-rw-r--r--target/linux/bcm53xx/patches-6.1/031-v6.5-0007-ARM-dts-BCM5301X-Use-updated-device-compatible-strin.patch90
-rw-r--r--target/linux/bcm53xx/patches-6.1/031-v6.5-0008-ARM-dts-BCM5301X-Use-updated-spi-gpio-binding-proper.patch82
-rw-r--r--target/linux/bcm53xx/patches-6.1/031-v6.5-0009-ARM-dts-BCM5301X-Drop-invalid-usb-cells.patch54
-rw-r--r--target/linux/bcm53xx/patches-6.1/031-v6.5-0010-ARM-dts-BCM5301X-Drop-invalid-properties-from-Meraki.patch31
-rw-r--r--target/linux/bcm53xx/patches-6.1/031-v6.5-0011-ARM-dts-BCM5301X-Relicense-Christian-s-code-to-the-G.patch106
-rw-r--r--target/linux/bcm53xx/patches-6.1/031-v6.5-0012-ARM-dts-BCM5301X-Describe-switch-ports-in-the-main-D.patch838
-rw-r--r--target/linux/bcm53xx/patches-6.1/031-v6.5-0013-ARM-dts-BCM5301X-MR26-MR32-remove-bogus-nand-ecc-alg.patch63
-rw-r--r--target/linux/bcm53xx/patches-6.1/031-v6.5-0014-ARM-dts-BCM5301X-MR32-remove-partition-index-numbers.patch54
-rw-r--r--target/linux/bcm53xx/patches-6.1/031-v6.5-0016-ARM-dts-BCM5301X-Add-Netgear-R8000-WiFi-regulator-ma.patch61
-rw-r--r--target/linux/bcm53xx/patches-6.1/031-v6.5-0017-ARM-dts-BCM5301X-Add-cells-sizes-to-PCIe-nodes.patch59
-rw-r--r--target/linux/bcm53xx/patches-6.1/032-v6.6-0001-ARM-dts-broadcom-add-missing-space-before.patch37
-rw-r--r--target/linux/bcm53xx/patches-6.1/032-v6.6-0002-ARM-dts-BCM5301X-Add-Wi-Fi-regulatory-mappings-for-L.patch107
-rw-r--r--target/linux/bcm53xx/patches-6.1/032-v6.6-0003-ARM-dts-BCM5301X-Add-Ethernet-interfaces-links.patch53
-rw-r--r--target/linux/bcm53xx/patches-6.1/032-v6.6-0004-ARM-dts-BCM53573-Drop-nonexistent-default-off-LED-tr.patch57
-rw-r--r--target/linux/bcm53xx/patches-6.1/032-v6.6-0009-ARM-dts-BCM53573-Fix-Ethernet-info-for-Luxul-devices.patch75
-rw-r--r--target/linux/bcm53xx/patches-6.1/032-v6.6-0010-ARM-dts-bcm5301x-Add-SEAMA-compatibles.patch36
-rw-r--r--target/linux/bcm53xx/patches-6.1/032-v6.6-0012-ARM-dts-BCM53573-Describe-BCM53125-switch-ports-in-t.patch97
-rw-r--r--target/linux/bcm53xx/patches-6.1/032-v6.6-0013-ARM-dts-BCM53573-Add-BCM53125-switch-port-5.patch36
-rw-r--r--target/linux/bcm53xx/patches-6.1/032-v6.6-0014-ARM-dts-BCM53573-Add-Ethernet-interfaces-links.patch73
-rw-r--r--target/linux/bcm53xx/patches-6.1/032-v6.6-0015-ARM-dts-BCM53573-Disable-second-Ethernet-on-Luxul-de.patch39
-rw-r--r--target/linux/bcm53xx/patches-6.1/032-v6.6-0016-ARM-dts-BCM5301X-Add-DT-for-Asus-RT-AC3100.patch431
-rw-r--r--target/linux/bcm53xx/patches-6.1/033-v6.7-0001-ARM-dts-BCM5301X-Set-MACs-for-D-Link-DIR-885L.patch56
-rw-r--r--target/linux/bcm53xx/patches-6.1/033-v6.7-0002-ARM-dts-BCM5301X-Set-MAC-address-for-Asus-RT-AC87U.patch44
-rw-r--r--target/linux/bcm53xx/patches-6.1/033-v6.7-0003-ARM-dts-BCM5301X-Relicense-Felix-s-code-to-the-GPL-2.patch57
-rw-r--r--target/linux/bcm53xx/patches-6.1/033-v6.7-0004-ARM-dts-BCM5301X-Relicense-Vivek-s-code-to-the-GPL-2.patch104
-rw-r--r--target/linux/bcm53xx/patches-6.1/033-v6.7-0005-ARM-dts-BCM5301X-Explicitly-disable-unused-switch-CP.patch377
-rw-r--r--target/linux/bcm53xx/patches-6.1/033-v6.7-0006-ARM-dts-BCM5301X-Set-fixed-link-for-extra-Netgear-R8.patch47
-rw-r--r--target/linux/bcm53xx/patches-6.1/033-v6.7-0007-ARM-dts-BCM5301X-Set-switch-ports-for-Linksys-EA9200.patch63
-rw-r--r--target/linux/bcm53xx/patches-6.1/080-v6.2-bcma-support-SPROM-rev-11.patch28
-rw-r--r--target/linux/bcm53xx/patches-6.1/140-mtd-parsers-trx-parse-firmware-MTD-partitions-only.patch43
-rw-r--r--target/linux/bcm53xx/patches-6.1/180-usb-xhci-add-support-for-performing-fake-doorbell.patch118
-rw-r--r--target/linux/bcm53xx/patches-6.1/300-ARM-BCM5301X-Disable-MMU-and-Dcache-during-decompres.patch101
-rw-r--r--target/linux/bcm53xx/patches-6.1/304-ARM-dts-BCM5301X-Specify-switch-ports-for-remaining-.patch675
-rw-r--r--target/linux/bcm53xx/patches-6.1/310-ARM-BCM5301X-Add-DT-for-Netgear-R7900.patch64
-rw-r--r--target/linux/bcm53xx/patches-6.1/500-UBI-Detect-EOF-mark-and-erase-all-remaining-blocks.patch59
-rw-r--r--target/linux/bcm53xx/patches-6.1/600-net-disable-GRO-by-default.patch36
-rw-r--r--target/linux/bcm53xx/patches-6.1/700-bgmac-reduce-max-frame-size-to-support-just-MTU-1500.patch33
-rw-r--r--target/linux/bcm53xx/patches-6.1/905-BCM53573-minor-hacks.patch80
-rw-r--r--target/linux/bcm53xx/patches-6.6/600-net-disable-GRO-by-default.patch2
-rw-r--r--target/linux/bmips/bcm6318/base-files/etc/board.d/01_leds3
-rw-r--r--target/linux/bmips/bcm6318/base-files/etc/board.d/02_network3
-rw-r--r--target/linux/bmips/bcm6318/base-files/etc/uci-defaults/09_fix_crc3
-rw-r--r--target/linux/bmips/bcm6328/base-files/etc/board.d/01_leds1
-rw-r--r--target/linux/bmips/bcm6328/base-files/etc/board.d/02_network1
-rw-r--r--target/linux/bmips/bcm6328/base-files/etc/uci-defaults/09_fix_crc1
-rw-r--r--target/linux/bmips/dts/bcm6318-tp-link-td-w8968-v3.dts253
-rw-r--r--target/linux/bmips/dts/bcm6328-dlink-dsl-2750b-b1.dts273
-rw-r--r--target/linux/bmips/dts/bcm6328-inteno-xg6846.dts279
-rw-r--r--target/linux/bmips/dts/bcm6358-huawei-hg556a-b.dts28
-rw-r--r--target/linux/bmips/dts/bcm6362-huawei-hg253s-v2.dts4
-rw-r--r--target/linux/bmips/dts/bcm6362-netgear-dgnd3700-v2.dts4
-rw-r--r--target/linux/bmips/dts/bcm6368-actiontec-r1000h.dts14
-rw-r--r--target/linux/bmips/dts/bcm6368-comtrend-vr-3025u.dts10
-rw-r--r--target/linux/bmips/dts/bcm6368-comtrend-vr-3025un.dts10
-rw-r--r--target/linux/bmips/dts/bcm6368-netgear-dgnd3700.dtsi22
-rw-r--r--target/linux/bmips/dts/bcm6368-observa-vh4032n.dts16
-rw-r--r--target/linux/bmips/dts/bcm6369-comtrend-wap-5813n.dts12
-rw-r--r--target/linux/bmips/dts/bcm6369-netgear-evg2000.dts18
-rw-r--r--target/linux/bmips/image/bcm6318.mk20
-rw-r--r--target/linux/bmips/image/bcm6328.mk21
-rw-r--r--target/linux/gemini/config-6.62
-rw-r--r--target/linux/generic/backport-5.15/836-v6.9-0002-nvmem-mtk-efuse-Register-MediaTek-socinfo-driver-fro.patch69
-rw-r--r--target/linux/generic/backport-5.15/836-v6.9-0003-nvmem-zynqmp_nvmem-zynqmp_nvmem_probe-cleanup.patch97
-rw-r--r--target/linux/generic/backport-5.15/836-v6.9-0004-nvmem-zynqmp_nvmem-Add-support-to-access-efuse.patch243
-rw-r--r--target/linux/generic/backport-5.15/836-v6.9-0005-nvmem-mtk-efuse-Drop-NVMEM-device-name.patch35
-rw-r--r--target/linux/generic/backport-5.15/836-v6.9-0007-nvmem-core-Print-error-on-wrong-bits-DT-property.patch32
-rw-r--r--target/linux/generic/backport-5.15/837-v6.10-0001-nvmem-layouts-store-owner-from-modules-with-nvmem_la.patch61
-rw-r--r--target/linux/generic/backport-5.15/837-v6.10-0002-nvmem-layouts-onie-tlv-drop-driver-owner-initializat.patch28
-rw-r--r--target/linux/generic/backport-5.15/837-v6.10-0003-nvmem-layouts-sl28vpd-drop-driver-owner-initializati.patch28
-rw-r--r--target/linux/generic/backport-5.15/837-v6.10-0004-nvmem-sc27xx-fix-module-autoloading.patch26
-rw-r--r--target/linux/generic/backport-5.15/837-v6.10-0005-nvmem-sprd-fix-module-autoloading.patch26
-rw-r--r--target/linux/generic/backport-5.15/837-v6.10-0006-nvmem-core-switch-to-use-device_add_groups.patch32
-rw-r--r--target/linux/generic/backport-5.15/837-v6.10-0007-nvmem-lpc18xx_eeprom-Convert-to-platform-remove-call.patch57
-rw-r--r--target/linux/generic/backport-5.15/837-v6.10-0008-nvmem-meson-mx-efuse-Remove-nvmem_device-from-efuse-.patch50
-rw-r--r--target/linux/generic/backport-5.15/837-v6.10-0009-nvmem-rmem-Fix-return-value-of-rmem_read.patch42
-rw-r--r--target/linux/generic/backport-5.15/837-v6.10-0010-nvmem-meson-efuse-Fix-return-value-of-nvmem-callback.patch59
-rw-r--r--target/linux/generic/backport-5.15/837-v6.10-0011-nvmem-core-only-change-name-to-fram-for-current-attr.patch39
-rw-r--r--target/linux/generic/backport-5.15/837-v6.10-0012-nvmem-core-limit-cell-sysfs-permissions-to-main-attr.patch37
-rw-r--r--target/linux/generic/backport-5.15/838-v6.11-0001-nvmem-add-missing-MODULE_DESCRIPTION-macros.patch48
-rw-r--r--target/linux/generic/backport-5.15/838-v6.11-0002-nvmem-meson-efuse-Replacing-the-use-of-of_node_put-t.patch48
-rw-r--r--target/linux/generic/backport-5.15/838-v6.11-0003-nvmem-rockchip-otp-set-add_legacy_fixed_of_cells-con.patch28
-rw-r--r--target/linux/generic/backport-5.15/838-v6.11-0004-nvmem-rockchip-otp-Set-type-to-OTP.patch25
-rw-r--r--target/linux/generic/backport-5.15/838-v6.11-0005-nvmem-rockchip-efuse-set-type-to-OTP.patch26
-rw-r--r--target/linux/generic/backport-5.15/838-v6.11-0006-nvmem-core-add-single-sysfs-group.patch42
-rw-r--r--target/linux/generic/backport-5.15/838-v6.11-0007-nvmem-core-remove-global-nvmem_cells_group.patch83
-rw-r--r--target/linux/generic/backport-5.15/838-v6.11-0008-nvmem-core-drop-unnecessary-range-checks-in-sysfs-ca.patch61
-rw-r--r--target/linux/generic/backport-5.15/838-v6.11-0009-nvmem-Use-sysfs_emit-for-type-attribute.patch30
-rw-r--r--target/linux/generic/backport-5.15/838-v6.11-0010-nvmem-core-Implement-force_ro-sysfs-attribute.patch122
-rw-r--r--target/linux/generic/backport-5.15/838-v6.11-0011-nvmem-u-boot-env-error-if-NVMEM-device-is-too-small.patch40
-rw-r--r--target/linux/generic/backport-5.15/838-v6.11-0012-nvmem-Fix-return-type-of-devm_nvmem_device_get-in-ke.patch37
-rw-r--r--target/linux/generic/backport-5.15/839-v6.12-0001-nvmem-imx-ocotp-ele-support-i.MX95.patch73
-rw-r--r--target/linux/generic/backport-5.15/839-v6.12-0002-nvmem-sunplus-ocotp-Use-devm_platform_ioremap_resour.patch44
-rw-r--r--target/linux/generic/backport-5.15/839-v6.12-0003-nvmem-layouts-add-U-Boot-env-layout.patch515
-rw-r--r--target/linux/generic/backport-6.1/020-v6.3-01-UPSTREAM-mm-multi-gen-LRU-rename-lru_gen_struct-to-l.patch8
-rw-r--r--target/linux/generic/backport-6.1/020-v6.3-03-UPSTREAM-mm-multi-gen-LRU-remove-eviction-fairness-s.patch10
-rw-r--r--target/linux/generic/backport-6.1/020-v6.3-04-BACKPORT-mm-multi-gen-LRU-remove-aging-fairness-safe.patch8
-rw-r--r--target/linux/generic/backport-6.1/020-v6.3-05-UPSTREAM-mm-multi-gen-LRU-shuffle-should_run_aging.patch2
-rw-r--r--target/linux/generic/backport-6.1/020-v6.3-06-BACKPORT-mm-multi-gen-LRU-per-node-lru_gen_folio-lis.patch30
-rw-r--r--target/linux/generic/backport-6.1/020-v6.3-07-BACKPORT-mm-multi-gen-LRU-clarify-scan_control-flags.patch12
-rw-r--r--target/linux/generic/backport-6.1/020-v6.3-09-UPSTREAM-mm-multi-gen-LRU-avoid-futile-retries.patch6
-rw-r--r--target/linux/generic/backport-6.1/020-v6.3-10-UPSTREAM-mm-add-vma_has_recency.patch2
-rw-r--r--target/linux/generic/backport-6.1/020-v6.3-15-UPSTREAM-mm-multi-gen-LRU-section-for-memcg-LRU.patch4
-rw-r--r--target/linux/generic/backport-6.1/020-v6.3-16-UPSTREAM-mm-multi-gen-LRU-improve-lru_gen_exit_memcg.patch2
-rw-r--r--target/linux/generic/backport-6.1/020-v6.4-19-mm-Multi-gen-LRU-remove-wait_event_killable.patch4
-rw-r--r--target/linux/generic/backport-6.1/412-v6.3-01-spidev-Add-Silicon-Labs-EM3581-device-compatible.patch32
-rw-r--r--target/linux/generic/backport-6.1/412-v6.3-02-spidev-Add-Silicon-Labs-SI3210-device-compatible.patch8
-rw-r--r--target/linux/generic/backport-6.1/715-07-v6.2-net-remove-explicit-phylink_generic_validate-referen.patch2
-rw-r--r--target/linux/generic/backport-6.1/715-26-v6.5-net-phylink-pass-neg_mode-into-phylink_mii_c22_pcs_c.patch6
-rw-r--r--target/linux/generic/backport-6.1/797-6.7-net-dsa-mv88e6xxx-fix-marvell-6350-switch-probing.patch8
-rw-r--r--target/linux/generic/backport-6.1/804-v6.5-11-leds-trigger-netdev-expose-netdev-trigger-modes-in-l.patch2
-rw-r--r--target/linux/generic/backport-6.1/805-v6.5-01-leds-trigger-netdev-add-additional-specific-link-spe.patch2
-rw-r--r--target/linux/generic/backport-6.1/805-v6.5-02-leds-trigger-netdev-add-additional-specific-link-dup.patch2
-rw-r--r--target/linux/generic/backport-6.1/807-v6.5-04-net-dsa-mv88e6xxx-fix-88E6393X-family-internal-phys-.patch6
-rw-r--r--target/linux/generic/backport-6.1/807-v6.5-06-net-dsa-mv88e6xxx-enable-support-for-88E6361-switch.patch2
-rw-r--r--target/linux/generic/backport-6.1/809-v6.3-0001-nvmem-core-remove-spurious-white-space.patch2
-rw-r--r--target/linux/generic/backport-6.1/809-v6.3-0002-nvmem-core-add-an-index-parameter-to-the-cell.patch18
-rw-r--r--target/linux/generic/backport-6.1/809-v6.3-0004-nvmem-core-drop-the-removal-of-the-cells-in-nvmem_ad.patch4
-rw-r--r--target/linux/generic/backport-6.1/809-v6.3-0005-nvmem-core-add-nvmem_add_one_cell.patch4
-rw-r--r--target/linux/generic/backport-6.1/809-v6.3-0006-nvmem-core-use-nvmem_add_one_cell-in-nvmem_add_cells.patch4
-rw-r--r--target/linux/generic/backport-6.1/810-v6.3-i915-Move-list_count-to-list.h-as-list_count_nodes-f.patch4
-rw-r--r--target/linux/generic/backport-6.1/811-v6.4-0002-nvmem-core-introduce-NVMEM-layouts.patch10
-rw-r--r--target/linux/generic/backport-6.1/811-v6.4-0003-nvmem-core-handle-the-absence-of-expected-layouts.patch6
-rw-r--r--target/linux/generic/backport-6.1/811-v6.4-0004-nvmem-core-request-layout-modules-loading.patch2
-rw-r--r--target/linux/generic/backport-6.1/811-v6.4-0005-nvmem-core-add-per-cell-post-processing.patch6
-rw-r--r--target/linux/generic/backport-6.1/811-v6.4-0006-nvmem-core-allow-to-modify-a-cell-before-adding-it.patch4
-rw-r--r--target/linux/generic/backport-6.1/811-v6.4-0008-nvmem-cell-drop-global-cell_post_process.patch4
-rw-r--r--target/linux/generic/backport-6.1/811-v6.4-0009-nvmem-core-provide-own-priv-pointer-in-post-process-.patch4
-rw-r--r--target/linux/generic/backport-6.1/811-v6.4-0017-nvmem-core-support-specifying-both-cell-raw-data-pos.patch8
-rw-r--r--target/linux/generic/backport-6.1/813-v6.5-0011-nvmem-core-add-support-for-fixed-cells-layout.patch10
-rw-r--r--target/linux/generic/backport-6.1/814-v6.6-0014-nvmem-core-Create-all-cells-before-adding-the-nvmem-.patch2
-rw-r--r--target/linux/generic/backport-6.1/814-v6.6-0016-nvmem-core-Do-not-open-code-existing-functions.patch2
-rw-r--r--target/linux/generic/backport-6.1/814-v6.6-0017-nvmem-core-Notify-when-a-new-layout-is-registered.patch2
-rw-r--r--target/linux/generic/backport-6.1/816-v6.7-0002-nvmem-add-explicit-config-option-to-read-old-syntax-.patch4
-rw-r--r--target/linux/generic/backport-6.1/816-v6.7-0004-Revert-nvmem-add-new-config-option.patch2
-rw-r--r--target/linux/generic/backport-6.1/816-v6.7-0005-nvmem-Do-not-expect-fixed-layouts-to-grab-a-layout-d.patch2
-rw-r--r--target/linux/generic/backport-6.1/819-v6.8-0001-nvmem-Move-of_nvmem_layout_get_container-in-another-.patch2
-rw-r--r--target/linux/generic/backport-6.1/819-v6.8-0003-nvmem-Simplify-the-add_cells-hook.patch2
-rw-r--r--target/linux/generic/backport-6.1/819-v6.8-0004-nvmem-Move-and-rename-fixup_cell_info.patch6
-rw-r--r--target/linux/generic/backport-6.1/819-v6.8-0005-nvmem-core-Rework-layouts-to-become-regular-devices.patch20
-rw-r--r--target/linux/generic/backport-6.1/819-v6.8-0006-nvmem-core-Expose-cells-through-sysfs.patch6
-rw-r--r--target/linux/generic/backport-6.1/819-v6.8-0008-nvmem-layouts-refactor-.add_cells-callback-arguments.patch2
-rw-r--r--target/linux/generic/backport-6.1/819-v6.8-0009-nvmem-drop-nvmem_layout_get_match_data.patch2
-rw-r--r--target/linux/generic/backport-6.1/819-v6.8-0010-nvmem-core-add-nvmem_dev_size-helper.patch2
-rw-r--r--target/linux/generic/backport-6.1/823-v6.9-0002-nvmem-mtk-efuse-Register-MediaTek-socinfo-driver-fro.patch69
-rw-r--r--target/linux/generic/backport-6.1/823-v6.9-0003-nvmem-zynqmp_nvmem-zynqmp_nvmem_probe-cleanup.patch97
-rw-r--r--target/linux/generic/backport-6.1/823-v6.9-0004-nvmem-zynqmp_nvmem-Add-support-to-access-efuse.patch243
-rw-r--r--target/linux/generic/backport-6.1/823-v6.9-0005-nvmem-mtk-efuse-Drop-NVMEM-device-name.patch35
-rw-r--r--target/linux/generic/backport-6.1/823-v6.9-0007-nvmem-core-Print-error-on-wrong-bits-DT-property.patch32
-rw-r--r--target/linux/generic/backport-6.1/827-v6.3-0001-of-base-add-of_parse_phandle_with_optional_args.patch2
-rw-r--r--target/linux/generic/backport-6.1/828-v6.4-0003-of-Rename-of_modalias_node.patch2
-rw-r--r--target/linux/generic/backport-6.1/828-v6.4-0004-of-Move-of_modalias-to-module.c.patch4
-rw-r--r--target/linux/generic/backport-6.1/828-v6.4-0005-of-Move-the-request-module-helper-logic-to-module.c.patch4
-rw-r--r--target/linux/generic/backport-6.1/829-v6.10-0001-nvmem-layouts-store-owner-from-modules-with-nvmem_la.patch61
-rw-r--r--target/linux/generic/backport-6.1/829-v6.10-0002-nvmem-layouts-onie-tlv-drop-driver-owner-initializat.patch28
-rw-r--r--target/linux/generic/backport-6.1/829-v6.10-0003-nvmem-layouts-sl28vpd-drop-driver-owner-initializati.patch28
-rw-r--r--target/linux/generic/backport-6.1/829-v6.10-0004-nvmem-sc27xx-fix-module-autoloading.patch26
-rw-r--r--target/linux/generic/backport-6.1/829-v6.10-0005-nvmem-sprd-fix-module-autoloading.patch26
-rw-r--r--target/linux/generic/backport-6.1/829-v6.10-0006-nvmem-core-switch-to-use-device_add_groups.patch32
-rw-r--r--target/linux/generic/backport-6.1/829-v6.10-0007-nvmem-lpc18xx_eeprom-Convert-to-platform-remove-call.patch57
-rw-r--r--target/linux/generic/backport-6.1/829-v6.10-0008-nvmem-meson-mx-efuse-Remove-nvmem_device-from-efuse-.patch50
-rw-r--r--target/linux/generic/backport-6.1/830-04-v6.5-cpufreq-qcom-nvmem-use-SoC-ID-s-from-bindings.patch2
-rw-r--r--target/linux/generic/backport-6.1/830-05-v6.5-cpufreq-qcom-nvmem-use-helper-to-get-SMEM-SoC-ID.patch2
-rw-r--r--target/linux/generic/backport-6.1/834-v6.8-leds-trigger-netdev-Extend-speeds-up-to-10G.patch2
-rw-r--r--target/linux/generic/backport-6.1/840-v6.11-0001-nvmem-add-missing-MODULE_DESCRIPTION-macros.patch48
-rw-r--r--target/linux/generic/backport-6.1/840-v6.11-0002-nvmem-meson-efuse-Replacing-the-use-of-of_node_put-t.patch48
-rw-r--r--target/linux/generic/backport-6.1/840-v6.11-0003-nvmem-rockchip-otp-set-add_legacy_fixed_of_cells-con.patch28
-rw-r--r--target/linux/generic/backport-6.1/840-v6.11-0004-nvmem-rockchip-otp-Set-type-to-OTP.patch25
-rw-r--r--target/linux/generic/backport-6.1/840-v6.11-0005-nvmem-rockchip-efuse-set-type-to-OTP.patch26
-rw-r--r--target/linux/generic/backport-6.1/840-v6.11-0006-nvmem-core-add-single-sysfs-group.patch42
-rw-r--r--target/linux/generic/backport-6.1/840-v6.11-0007-nvmem-core-remove-global-nvmem_cells_group.patch83
-rw-r--r--target/linux/generic/backport-6.1/840-v6.11-0008-nvmem-core-drop-unnecessary-range-checks-in-sysfs-ca.patch61
-rw-r--r--target/linux/generic/backport-6.1/840-v6.11-0009-nvmem-Use-sysfs_emit-for-type-attribute.patch30
-rw-r--r--target/linux/generic/backport-6.1/840-v6.11-0010-nvmem-core-Implement-force_ro-sysfs-attribute.patch122
-rw-r--r--target/linux/generic/backport-6.1/840-v6.11-0011-nvmem-u-boot-env-error-if-NVMEM-device-is-too-small.patch40
-rw-r--r--target/linux/generic/backport-6.1/840-v6.11-0012-nvmem-Fix-return-type-of-devm_nvmem_device_get-in-ke.patch37
-rw-r--r--target/linux/generic/backport-6.1/841-v6.12-0001-nvmem-imx-ocotp-ele-support-i.MX95.patch73
-rw-r--r--target/linux/generic/backport-6.1/841-v6.12-0002-nvmem-sunplus-ocotp-Use-devm_platform_ioremap_resour.patch44
-rw-r--r--target/linux/generic/backport-6.1/841-v6.12-0003-nvmem-layouts-add-U-Boot-env-layout.patch525
-rw-r--r--target/linux/generic/backport-6.1/851-v6.2-bus-mhi-host-pci_generic-Add-HP-variant-of-T99W175.patch2
-rw-r--r--target/linux/generic/backport-6.1/852-v6.2-bus-mhi-host-pci_generic-Add-definition-for-some-VID.patch4
-rw-r--r--target/linux/generic/backport-6.1/853-v6.2-bus-mhi-host-pci_generic-Drop-redundant-pci_enable_p.patch6
-rw-r--r--target/linux/generic/backport-6.1/854-v6.4-bus-mhi-pci_generic-Add-Foxconn-T99W510.patch2
-rw-r--r--target/linux/generic/backport-6.1/856-v6.6-bus-mhi-host-pci_generic-Add-support-for-Quectel-EM1.patch2
-rw-r--r--target/linux/generic/backport-6.1/857-v6.6-bus-mhi-host-pci_generic-Add-support-for-Quectel-RM5.patch2
-rw-r--r--target/linux/generic/backport-6.1/858-v6.6-bus-mhi-host-pci_generic-Add-support-for-Dell-DW5932.patch2
-rw-r--r--target/linux/generic/backport-6.1/859-v6.6-bus-mhi-host-pci_generic-Add-support-for-Quectel-RM5.patch2
-rw-r--r--target/linux/generic/backport-6.1/860-v6.6-bus-mhi-host-pci_generic-add-support-for-Telit-FE990.patch33
-rw-r--r--target/linux/generic/backport-6.1/894-v6.8-net-ethtool-implement-ethtool_puts.patch2
-rw-r--r--target/linux/generic/backport-6.6/200-regmap-maple-work-around-false-positive-warning.patch47
-rw-r--r--target/linux/generic/backport-6.6/310-v6.7-mips-kexec-fix-the-incorrect-ifdeffery-and-dependenc.patch20
-rw-r--r--target/linux/generic/backport-6.6/320-v6.11-mips-bmips-rework-and-cache-CBR-addr-handling.patch (renamed from target/linux/bmips/patches-6.6/020-v6.11-mips-bmips-rework-and-cache-CBR-addr-handling.patch)0
-rw-r--r--target/linux/generic/backport-6.6/321-v6.11-mips-bmips-setup-make-CBR-address-configurable.patch (renamed from target/linux/bmips/patches-6.6/021-v6.11-mips-bmips-setup-make-CBR-address-configurable.patch)0
-rw-r--r--target/linux/generic/backport-6.6/322-v6.11-mips-bmips-enable-RAC-on-BMIPS4350.patch (renamed from target/linux/bmips/patches-6.6/022-v6.11-mips-bmips-enable-RAC-on-BMIPS4350.patch)0
-rw-r--r--target/linux/generic/backport-6.6/610-v6.9-net-mdio-add-2.5g-and-5g-related-PMA-speed-constants.patch30
-rw-r--r--target/linux/generic/backport-6.6/611-01-v6.11-udp-Allow-GSO-transmit-from-devices-with-no-checksum.patch94
-rw-r--r--target/linux/generic/backport-6.6/611-02-v6.11-net-Make-USO-depend-on-CSUM-offload.patch69
-rw-r--r--target/linux/generic/backport-6.6/611-03-v6.11-udp-Fall-back-to-software-USO-if-IPv6-extension-head.patch86
-rw-r--r--target/linux/generic/backport-6.6/752-04-v6.6-net-ethernet-mtk_wed-check-update_wo_rx_stats-in-mtk.patch26
-rw-r--r--target/linux/generic/backport-6.6/752-06-v6.7-net-ethernet-mtk_wed-introduce-versioning-utility-ro.patch4
-rw-r--r--target/linux/generic/backport-6.6/752-13-v6.7-net-ethernet-mtk_wed-add-mtk_wed_soc_data-structure.patch4
-rw-r--r--target/linux/generic/backport-6.6/752-14-v6.7-net-ethernet-mtk_wed-introduce-WED-support-for-MT798.patch2
-rw-r--r--target/linux/generic/backport-6.6/752-17-v6.7-net-ethernet-mtk_wed-introduce-hw_rro-support-for-MT.patch2
-rw-r--r--target/linux/generic/backport-6.6/780-01-v6.8-r8169-add-support-for-LED-s-on-RTL8168-RTL8101.patch319
-rw-r--r--target/linux/generic/backport-6.6/780-01-v6.8-r8169-improve-RTL8411b-phy-down-fixup.patch173
-rw-r--r--target/linux/generic/backport-6.6/780-02-v6.8-r8169-fix-building-with-CONFIG_LEDS_CLASS-m.patch75
-rw-r--r--target/linux/generic/backport-6.6/780-02-v6.8-r8169-remove-not-needed-check-in-rtl_fw_write_firmwa.patch27
-rw-r--r--target/linux/generic/backport-6.6/780-03-v6.8-r8169-remove-multicast-filter-limit.patch47
-rw-r--r--target/linux/generic/backport-6.6/780-03-v6.9-r8169-add-support-for-RTL8126A.patch355
-rw-r--r--target/linux/generic/backport-6.6/780-04-v6.8-r8169-improve-handling-task-scheduling.patch41
-rw-r--r--target/linux/generic/backport-6.6/780-05-v6.8-r8169-add-support-for-LED-s-on-RTL8168-RTL8101.patch319
-rw-r--r--target/linux/generic/backport-6.6/780-05-v6.9-r8169-add-LED-support-for-RTL8125-RTL8126.patch244
-rw-r--r--target/linux/generic/backport-6.6/780-06-v6.8-r8169-fix-building-with-CONFIG_LEDS_CLASS-m.patch75
-rw-r--r--target/linux/generic/backport-6.6/780-06-v6.9-r8169-add-MODULE_FIRMWARE-entry-for-RTL8126A.patch25
-rw-r--r--target/linux/generic/backport-6.6/780-07-v6.10-r8169-add-support-for-RTL8168M.patch30
-rw-r--r--target/linux/generic/backport-6.6/780-07-v6.9-r8169-simplify-EEE-handling.patch96
-rw-r--r--target/linux/generic/backport-6.6/780-08-v6.10-r8169-fix-LED-related-deadlock-on-module-removal.patch147
-rw-r--r--target/linux/generic/backport-6.6/780-08-v6.9-r8169-add-support-for-RTL8126A.patch355
-rw-r--r--target/linux/generic/backport-6.6/780-09-v6.10-r8169-add-missing-conditional-compiling-for-call-to-.patch31
-rw-r--r--target/linux/generic/backport-6.6/780-09-v6.9-r8169-improve-checking-for-valid-LED-modes.patch (renamed from target/linux/generic/backport-6.6/780-04-v6.9-r8169-improve-checking-for-valid-LED-modes.patch)0
-rw-r--r--target/linux/generic/backport-6.6/780-10-v6.9-r8169-simplify-code-by-using-core-provided-pcpu-stat.patch39
-rw-r--r--target/linux/generic/backport-6.6/780-11-v6.9-r8169-add-LED-support-for-RTL8125-RTL8126.patch244
-rw-r--r--target/linux/generic/backport-6.6/780-12-v6.9-r8169-add-generic-rtl_set_eee_txidle_timer-function.patch91
-rw-r--r--target/linux/generic/backport-6.6/780-13-v6.9-r8169-support-setting-the-EEE-tx-idle-timer-on-RTL81.patch30
-rw-r--r--target/linux/generic/backport-6.6/780-14-v6.9-r8169-add-support-for-returning-tx_lpi_timer-in-etht.patch55
-rw-r--r--target/linux/generic/backport-6.6/780-15-v6.9-r8169-add-MODULE_FIRMWARE-entry-for-RTL8126A.patch25
-rw-r--r--target/linux/generic/backport-6.6/780-16-v6.9-r8169-fix-LED-related-deadlock-on-module-removal.patch147
-rw-r--r--target/linux/generic/backport-6.6/780-17-v6.9-r8169-add-missing-conditional-compiling-for-call-to-.patch31
-rw-r--r--target/linux/generic/backport-6.6/780-18-v6.10-r8169-add-support-for-RTL8168M.patch30
-rw-r--r--target/linux/generic/backport-6.6/780-19-v6.10-net-annotate-writes-on-dev-mtu-from-ndo_change_mtu.patch60
-rw-r--r--target/linux/generic/backport-6.6/780-20-v6.11-r8169-disable-interrupt-source-RxOverflow.patch34
-rw-r--r--target/linux/generic/backport-6.6/780-21-v6.11-r8169-remove-detection-of-chip-version-11-early-RTL8.patch32
-rw-r--r--target/linux/generic/backport-6.6/781-01-v6.9-net-phy-realtek-add-support-for-RTL8126A-integrated-.patch40
-rw-r--r--target/linux/generic/backport-6.6/781-02-v6.9-net-phy-realtek-use-generic-MDIO-constants.patch93
-rw-r--r--target/linux/generic/backport-6.6/781-03-v6.9-net-phy-realtek-add-5Gbps-support-to-rtl822x_config_.patch42
-rw-r--r--target/linux/generic/backport-6.6/781-04-v6.9-net-phy-realtek-use-generic-MDIO-helpers-to-simplify.patch52
-rw-r--r--target/linux/generic/backport-6.6/781-05-v6.10-net-phy-realtek-configure-SerDes-mode-for-rtl822xb-P.patch209
-rw-r--r--target/linux/generic/backport-6.6/781-06-v6.10-net-phy-realtek-add-get_rate_matching-for-rtl822xb-P.patch77
-rw-r--r--target/linux/generic/backport-6.6/781-07-v6.10-net-phy-realtek-Add-driver-instances-for-rtl8221b-vi.patch218
-rw-r--r--target/linux/generic/backport-6.6/781-08-v6.10-net-phy-realtek-Change-rtlgen_get_speed-to-rtlgen_de.patch125
-rw-r--r--target/linux/generic/backport-6.6/781-09-v6.10-net-phy-realtek-add-rtl822x_c45_get_features-to-set-.patch48
-rw-r--r--target/linux/generic/backport-6.6/781-10-v6.11-net-phy-realtek-add-support-for-rtl8224-2.5Gbps-PHY.patch33
-rw-r--r--target/linux/generic/backport-6.6/781-11-v6.11-net-phy-realtek-Add-support-for-PHY-LEDs-on-RTL8211F.patch151
-rw-r--r--target/linux/generic/backport-6.6/781-12-v6.11-net-phy-realtek-Fix-setting-of-PHY-LEDs-Mode-B-bit-o.patch42
-rw-r--r--target/linux/generic/backport-6.6/816-v6.7-0004-Revert-nvmem-add-new-config-option.patch2
-rw-r--r--target/linux/generic/backport-6.6/819-v6.8-0001-nvmem-Move-of_nvmem_layout_get_container-in-another-.patch2
-rw-r--r--target/linux/generic/backport-6.6/819-v6.8-0003-nvmem-Simplify-the-add_cells-hook.patch2
-rw-r--r--target/linux/generic/backport-6.6/819-v6.8-0004-nvmem-Move-and-rename-fixup_cell_info.patch6
-rw-r--r--target/linux/generic/backport-6.6/819-v6.8-0005-nvmem-core-Rework-layouts-to-become-regular-devices.patch20
-rw-r--r--target/linux/generic/backport-6.6/819-v6.8-0006-nvmem-core-Expose-cells-through-sysfs.patch6
-rw-r--r--target/linux/generic/backport-6.6/819-v6.8-0008-nvmem-layouts-refactor-.add_cells-callback-arguments.patch2
-rw-r--r--target/linux/generic/backport-6.6/819-v6.8-0009-nvmem-drop-nvmem_layout_get_match_data.patch2
-rw-r--r--target/linux/generic/backport-6.6/819-v6.8-0010-nvmem-core-add-nvmem_dev_size-helper.patch2
-rw-r--r--target/linux/generic/backport-6.6/820-v6.9-0002-nvmem-mtk-efuse-Register-MediaTek-socinfo-driver-fro.patch69
-rw-r--r--target/linux/generic/backport-6.6/820-v6.9-0003-nvmem-zynqmp_nvmem-zynqmp_nvmem_probe-cleanup.patch97
-rw-r--r--target/linux/generic/backport-6.6/820-v6.9-0004-nvmem-zynqmp_nvmem-Add-support-to-access-efuse.patch243
-rw-r--r--target/linux/generic/backport-6.6/820-v6.9-0005-nvmem-mtk-efuse-Drop-NVMEM-device-name.patch35
-rw-r--r--target/linux/generic/backport-6.6/820-v6.9-0006-nvmem-core-make-nvmem_layout_bus_type-const.patch33
-rw-r--r--target/linux/generic/backport-6.6/820-v6.9-0007-nvmem-core-Print-error-on-wrong-bits-DT-property.patch32
-rw-r--r--target/linux/generic/backport-6.6/821-v6.10-0001-nvmem-layouts-store-owner-from-modules-with-nvmem_la.patch61
-rw-r--r--target/linux/generic/backport-6.6/821-v6.10-0002-nvmem-layouts-onie-tlv-drop-driver-owner-initializat.patch28
-rw-r--r--target/linux/generic/backport-6.6/821-v6.10-0003-nvmem-layouts-sl28vpd-drop-driver-owner-initializati.patch28
-rw-r--r--target/linux/generic/backport-6.6/821-v6.10-0004-nvmem-sc27xx-fix-module-autoloading.patch26
-rw-r--r--target/linux/generic/backport-6.6/821-v6.10-0005-nvmem-sprd-fix-module-autoloading.patch26
-rw-r--r--target/linux/generic/backport-6.6/821-v6.10-0006-nvmem-core-switch-to-use-device_add_groups.patch32
-rw-r--r--target/linux/generic/backport-6.6/821-v6.10-0007-nvmem-lpc18xx_eeprom-Convert-to-platform-remove-call.patch57
-rw-r--r--target/linux/generic/backport-6.6/821-v6.10-0008-nvmem-meson-mx-efuse-Remove-nvmem_device-from-efuse-.patch50
-rw-r--r--target/linux/generic/backport-6.6/822-v6.11-0001-nvmem-add-missing-MODULE_DESCRIPTION-macros.patch48
-rw-r--r--target/linux/generic/backport-6.6/822-v6.11-0002-nvmem-meson-efuse-Replacing-the-use-of-of_node_put-t.patch48
-rw-r--r--target/linux/generic/backport-6.6/822-v6.11-0004-nvmem-rockchip-otp-Set-type-to-OTP.patch25
-rw-r--r--target/linux/generic/backport-6.6/822-v6.11-0005-nvmem-rockchip-efuse-set-type-to-OTP.patch26
-rw-r--r--target/linux/generic/backport-6.6/822-v6.11-0006-nvmem-core-add-single-sysfs-group.patch42
-rw-r--r--target/linux/generic/backport-6.6/822-v6.11-0007-nvmem-core-remove-global-nvmem_cells_group.patch83
-rw-r--r--target/linux/generic/backport-6.6/822-v6.11-0008-nvmem-core-drop-unnecessary-range-checks-in-sysfs-ca.patch61
-rw-r--r--target/linux/generic/backport-6.6/822-v6.11-0009-nvmem-Use-sysfs_emit-for-type-attribute.patch30
-rw-r--r--target/linux/generic/backport-6.6/822-v6.11-0010-nvmem-core-Implement-force_ro-sysfs-attribute.patch122
-rw-r--r--target/linux/generic/backport-6.6/822-v6.11-0011-nvmem-u-boot-env-error-if-NVMEM-device-is-too-small.patch40
-rw-r--r--target/linux/generic/backport-6.6/822-v6.11-0012-nvmem-Fix-return-type-of-devm_nvmem_device_get-in-ke.patch37
-rw-r--r--target/linux/generic/backport-6.6/823-v6.12-0001-nvmem-imx-ocotp-ele-support-i.MX95.patch73
-rw-r--r--target/linux/generic/backport-6.6/823-v6.12-0002-nvmem-sunplus-ocotp-Use-devm_platform_ioremap_resour.patch44
-rw-r--r--target/linux/generic/backport-6.6/823-v6.12-0003-nvmem-layouts-add-U-Boot-env-layout.patch525
-rw-r--r--target/linux/generic/backport-6.6/834-v6.8-leds-trigger-netdev-Extend-speeds-up-to-10G.patch2
-rw-r--r--target/linux/generic/backport-6.6/894-v6.8-net-ethtool-implement-ethtool_puts.patch2
-rw-r--r--target/linux/generic/backport-6.6/896-01-v6.9-net-dsa-mv88e6xxx-rename-mv88e6xxx_g2_scratch_gpio_s.patch2
-rw-r--r--target/linux/generic/backport-6.6/896-02-v6.9-net-dsa-mv88e6xxx-add-Amethyst-specific-SMI-GPIO-fun.patch2
-rw-r--r--target/linux/generic/config-5.1510
-rw-r--r--target/linux/generic/config-6.113
-rw-r--r--target/linux/generic/config-6.630
-rw-r--r--target/linux/generic/files/drivers/net/phy/rtl8366_smi.h14
-rw-r--r--target/linux/generic/files/drivers/net/phy/rtl8367.c47
-rw-r--r--target/linux/generic/files/drivers/net/phy/rtl8367b.c561
-rw-r--r--target/linux/generic/hack-5.15/911-kobject_add_broadcast_uevent.patch2
-rw-r--r--target/linux/generic/hack-6.1/230-openwrt_lzma_options.patch2
-rw-r--r--target/linux/generic/hack-6.1/253-ksmbd-config.patch2
-rw-r--r--target/linux/generic/hack-6.1/780-usb-net-MeigLink_modem_support.patch6
-rw-r--r--target/linux/generic/hack-6.1/902-debloat_proc.patch8
-rw-r--r--target/linux/generic/hack-6.1/904-debloat_dma_buf.patch2
-rw-r--r--target/linux/generic/hack-6.1/911-kobject_add_broadcast_uevent.patch4
-rw-r--r--target/linux/generic/hack-6.1/930-Revert-Revert-Revert-driver-core-Set-fw_devlink-on-b.patch2
-rw-r--r--target/linux/generic/hack-6.6/230-openwrt_lzma_options.patch2
-rw-r--r--target/linux/generic/hack-6.6/253-ksmbd-config.patch4
-rw-r--r--target/linux/generic/hack-6.6/600-net-enable-fraglist-GRO-by-default.patch2
-rw-r--r--target/linux/generic/hack-6.6/780-usb-net-MeigLink_modem_support.patch6
-rw-r--r--target/linux/generic/hack-6.6/800-GPIO-add-named-gpio-exports.patch6
-rw-r--r--target/linux/generic/hack-6.6/902-debloat_proc.patch8
-rw-r--r--target/linux/generic/hack-6.6/904-debloat_dma_buf.patch2
-rw-r--r--target/linux/generic/hack-6.6/911-kobject_add_broadcast_uevent.patch4
-rw-r--r--target/linux/generic/hack-6.6/930-Revert-Revert-Revert-driver-core-Set-fw_devlink-on-b.patch2
-rw-r--r--target/linux/generic/pending-5.15/491-ubi-auto-create-ubiblock-device-for-rootfs.patch2
-rw-r--r--target/linux/generic/pending-5.15/802-nvmem-u-boot-env-align-endianness-of-crc32-values.patch10
-rw-r--r--target/linux/generic/pending-5.15/804-nvmem-core-support-mac-base-fixed-layout-cells.patch4
-rw-r--r--target/linux/generic/pending-6.1/120-Fix-alloc_node_mem_map-with-ARCH_PFN_OFFSET-calcu.patch2
-rw-r--r--target/linux/generic/pending-6.1/491-ubi-auto-create-ubiblock-device-for-rootfs.patch2
-rw-r--r--target/linux/generic/pending-6.1/510-block-add-uImage.FIT-subimage-block-driver.patch2
-rw-r--r--target/linux/generic/pending-6.1/630-packet_socket_type.patch16
-rw-r--r--target/linux/generic/pending-6.1/666-Add-support-for-MAP-E-FMRs-mesh-mode.patch18
-rw-r--r--target/linux/generic/pending-6.1/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch2
-rw-r--r--target/linux/generic/pending-6.1/680-net-add-TCP-fraglist-GRO-support.patch14
-rw-r--r--target/linux/generic/pending-6.1/701-netfilter-nf_tables-ignore-EOPNOTSUPP-on-flowtable-d.patch2
-rw-r--r--target/linux/generic/pending-6.1/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch2
-rw-r--r--target/linux/generic/pending-6.1/774-net-dsa-b53-mmap-allow-passing-a-chip-ID.patch2
-rw-r--r--target/linux/generic/pending-6.1/777-net-dsa-b53-mdio-add-support-for-BCM53134.patch4
-rw-r--r--target/linux/generic/pending-6.1/802-nvmem-u-boot-env-align-endianness-of-crc32-values.patch10
-rw-r--r--target/linux/generic/pending-6.1/804-nvmem-core-support-mac-base-fixed-layout-cells.patch4
-rw-r--r--target/linux/generic/pending-6.1/834-ledtrig-libata.patch4
-rw-r--r--target/linux/generic/pending-6.6/410-mtd-spinand-set-bitflip_threshold-to-75-of-ECC-strength.patch63
-rw-r--r--target/linux/generic/pending-6.6/451-block-partitions-populate-fwnode.patch99
-rw-r--r--target/linux/generic/pending-6.6/452-block-add-support-for-notifications.patch49
-rw-r--r--target/linux/generic/pending-6.6/453-block-add-new-genhd-flag-GENHD_FL_NVMEM.patch33
-rw-r--r--target/linux/generic/pending-6.6/489-mtd-spinand-winbond-add-support-for-W25N01KV.patch63
-rw-r--r--target/linux/generic/pending-6.6/491-ubi-auto-create-ubiblock-device-for-rootfs.patch2
-rw-r--r--target/linux/generic/pending-6.6/510-block-add-uImage.FIT-subimage-block-driver.patch2
-rw-r--r--target/linux/generic/pending-6.6/630-packet_socket_type.patch16
-rw-r--r--target/linux/generic/pending-6.6/640-net-bridge-fix-switchdev-host-mdb-entry-updates.patch42
-rw-r--r--target/linux/generic/pending-6.6/666-Add-support-for-MAP-E-FMRs-mesh-mode.patch18
-rw-r--r--target/linux/generic/pending-6.6/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch2
-rw-r--r--target/linux/generic/pending-6.6/680-net-add-TCP-fraglist-GRO-support.patch14
-rw-r--r--target/linux/generic/pending-6.6/681-net-remove-NETIF_F_GSO_FRAGLIST-from-NETIF_F_GSO_SOF.patch129
-rw-r--r--target/linux/generic/pending-6.6/701-netfilter-nf_tables-ignore-EOPNOTSUPP-on-flowtable-d.patch2
-rw-r--r--target/linux/generic/pending-6.6/720-01-net-phy-realtek-use-genphy_soft_reset-for-2.5G-PHYs.patch81
-rw-r--r--target/linux/generic/pending-6.6/720-02-net-phy-realtek-disable-SGMII-in-band-AN-for-2-5G-PHYs.patch63
-rw-r--r--target/linux/generic/pending-6.6/720-03-net-phy-realtek-make-sure-paged-read-is-protected-by.patch35
-rw-r--r--target/linux/generic/pending-6.6/720-04-net-phy-realtek-use-inline-functions-for-10GbE-adver.patch26
-rw-r--r--target/linux/generic/pending-6.6/720-05-net-phy-realtek-check-validity-of-10GbE-link-partner.patch28
-rw-r--r--target/linux/generic/pending-6.6/720-06-net-phy-realtek-introduce-rtl822x_probe.patch100
-rw-r--r--target/linux/generic/pending-6.6/720-07-net-phy-realtek-detect-early-version-of-RTL8221B.patch52
-rw-r--r--target/linux/generic/pending-6.6/720-08-net-phy-realtek-support-interrupt-of-RTL8221B.patch102
-rw-r--r--target/linux/generic/pending-6.6/721-net-phy-realtek-rtl8221-allow-to-configure-SERDES-mo.patch106
-rw-r--r--target/linux/generic/pending-6.6/722-net-phy-realtek-support-switching-between-SGMII-and-.patch61
-rw-r--r--target/linux/generic/pending-6.6/724-net-phy-realtek-use-genphy_soft_reset-for-2.5G-PHYs.patch65
-rw-r--r--target/linux/generic/pending-6.6/725-net-phy-realtek-disable-SGMII-in-band-AN-for-2-5G-PHYs.patch43
-rw-r--r--target/linux/generic/pending-6.6/726-net-phy-realtek-make-sure-paged-read-is-protected-by.patch35
-rw-r--r--target/linux/generic/pending-6.6/727-net-phy-realtek-use-inline-functions-for-10GbE-adver.patch60
-rw-r--r--target/linux/generic/pending-6.6/728-net-phy-realtek-check-validity-of-10GbE-link-partner.patch28
-rw-r--r--target/linux/generic/pending-6.6/729-net-phy-realtek-introduce-rtl822x_probe.patch84
-rw-r--r--target/linux/generic/pending-6.6/730-net-phy-realtek-detect-early-version-of-RTL8221B.patch71
-rw-r--r--target/linux/generic/pending-6.6/741-net-phy-realtek-support-interrupt-of-RTL8221B.patch75
-rw-r--r--target/linux/generic/pending-6.6/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch2
-rw-r--r--target/linux/generic/pending-6.6/802-nvmem-u-boot-env-align-endianness-of-crc32-values.patch10
-rw-r--r--target/linux/generic/pending-6.6/804-nvmem-core-support-mac-base-fixed-layout-cells.patch4
-rw-r--r--target/linux/imx/Makefile3
-rw-r--r--target/linux/imx/config-6.1486
-rw-r--r--target/linux/imx/config-6.63
-rw-r--r--target/linux/imx/image/cortexa7.mk2
-rw-r--r--target/linux/imx/image/cortexa9.mk2
-rw-r--r--target/linux/imx/patches-6.1/001-6.2-phy-freescale-imx8m-pcie-Refine-register-definitions.patch49
-rw-r--r--target/linux/imx/patches-6.1/003-6.3-phy-freescale-imx8m-pcie-Add-i.MX8MP-PCIe-PHY-suppor.patch99
-rw-r--r--target/linux/imx/patches-6.1/100-bootargs.patch11
-rw-r--r--target/linux/imx/patches-6.1/300-ARM-dts-imx6q-apalis-ixora-add-status-LEDs-aliases.patch96
-rw-r--r--target/linux/imx/patches-6.1/301-ARM-dts-imx6q-apalis-ixora-make-switch3-reset-button.patch78
-rw-r--r--target/linux/imx/patches-6.1/310-ARM-dts-imx7d-pico-pi-set-aliases.patch24
-rw-r--r--target/linux/imx/patches-6.1/311-ARM-imx7d-pico-pi.dts-add-default-stdout-path.patch23
-rw-r--r--target/linux/ipq40xx/Makefile2
-rw-r--r--target/linux/ipq40xx/config-6.66
-rw-r--r--target/linux/ipq40xx/files-6.6/arch/arm/boot/dts/qcom/qcom-ipq4018-nbg6617.dts4
-rw-r--r--target/linux/ipq40xx/files-6.6/arch/arm/boot/dts/qcom/qcom-ipq4018-wre6606.dts2
-rw-r--r--target/linux/ipq40xx/generic/config-default6
-rw-r--r--target/linux/ipq40xx/generic/target.mk2
-rw-r--r--target/linux/ipq40xx/image/generic.mk9
-rw-r--r--target/linux/ipq40xx/mikrotik/config-default6
-rw-r--r--target/linux/ipq40xx/mikrotik/target.mk2
-rw-r--r--target/linux/ipq40xx/patches-6.6/700-net-ipqess-introduce-the-Qualcomm-IPQESS-driver.patch2
-rw-r--r--target/linux/ipq40xx/patches-6.6/999-atm-mpoa-intel-dsl-phy-support.patch4
-rw-r--r--target/linux/ipq806x/files-6.6/arch/arm/boot/dts/qcom/qcom-ipq8065-nbg6817.dts2
-rw-r--r--target/linux/ipq806x/image/generic.mk6
-rw-r--r--target/linux/kirkwood/Makefile3
-rw-r--r--target/linux/kirkwood/config-6.1309
-rw-r--r--target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-nsa310b.dts2
-rw-r--r--target/linux/kirkwood/files-6.6/arch/arm/boot/dts/marvell/kirkwood-nsa310b.dts2
-rw-r--r--target/linux/kirkwood/image/Makefile8
-rw-r--r--target/linux/kirkwood/image/generic.mk177
-rw-r--r--target/linux/kirkwood/patches-6.1/002-6.2-ARM-dts-kirkwood-Add-Zyxel-NSA310S-board.patch301
-rw-r--r--target/linux/kirkwood/patches-6.1/003-6.5-ARM-dts-kirkwood-Add-Endian-4i-Edge-200-board.patch249
-rw-r--r--target/linux/kirkwood/patches-6.1/004-6.4-ARM-dts-kirkwood-Add-missing-phy-mode-and-fixed-link.patch108
-rw-r--r--target/linux/kirkwood/patches-6.1/100-ib62x0.patch53
-rw-r--r--target/linux/kirkwood/patches-6.1/101-iconnect.patch80
-rw-r--r--target/linux/kirkwood/patches-6.1/102-dockstar.patch62
-rw-r--r--target/linux/kirkwood/patches-6.1/103-iomega-ix2-200.patch71
-rw-r--r--target/linux/kirkwood/patches-6.1/105-linksys-viper-dts.patch59
-rw-r--r--target/linux/kirkwood/patches-6.1/106-goflexnet.patch53
-rw-r--r--target/linux/kirkwood/patches-6.1/107-01-zyxel-nsa3x0-common-nand-partitions.patch48
-rw-r--r--target/linux/kirkwood/patches-6.1/107-03-nsa325.patch54
-rw-r--r--target/linux/kirkwood/patches-6.1/109-pogoplug_v4.patch87
-rw-r--r--target/linux/kirkwood/patches-6.1/110-pogo_e02.patch68
-rw-r--r--target/linux/kirkwood/patches-6.1/111-l-50.patch47
-rw-r--r--target/linux/kirkwood/patches-6.1/112-sheevaplug.patch47
-rw-r--r--target/linux/kirkwood/patches-6.1/113-readynas_duo_v2.patch76
-rw-r--r--target/linux/kirkwood/patches-6.1/114-ctera-c-200-v1.patch58
-rw-r--r--target/linux/kirkwood/patches-6.1/115-nsa310s.patch35
-rw-r--r--target/linux/kirkwood/patches-6.1/116-4i-edge-200.patch34
-rw-r--r--target/linux/kirkwood/patches-6.1/117-netgear_stora.patch10
-rw-r--r--target/linux/kirkwood/patches-6.1/118-dns-320l.patch35
-rw-r--r--target/linux/kirkwood/patches-6.1/201-enable-sata-port-specific-led-triggers.patch10
-rw-r--r--target/linux/kirkwood/patches-6.1/202-linksys-find-active-root.patch62
-rw-r--r--target/linux/kirkwood/patches-6.1/203-blackarmor-nas220.patch99
-rw-r--r--target/linux/lantiq/files/arch/mips/boot/dts/lantiq/ar9_zyxel_p-2601hn.dts2
-rw-r--r--target/linux/lantiq/files/arch/mips/boot/dts/lantiq/danube_arcadyan_arv7525pw.dts7
-rw-r--r--target/linux/lantiq/files/arch/mips/boot/dts/lantiq/vr9_arcadyan_vgv7510kw22.dtsi3
-rw-r--r--target/linux/lantiq/files/arch/mips/boot/dts/lantiq/vr9_zyxel_p-2812hnu-f1.dts2
-rw-r--r--target/linux/lantiq/files/arch/mips/boot/dts/lantiq/vr9_zyxel_p-2812hnu-f3.dts2
-rw-r--r--target/linux/lantiq/image/ar9.mk2
-rw-r--r--target/linux/lantiq/image/vr9.mk4
-rw-r--r--target/linux/lantiq/patches-6.6/0001-MIPS-lantiq-add-pcie-driver.patch2
-rw-r--r--target/linux/lantiq/patches-6.6/0027-v6.11-net-ethernet-lantiq_etop-remove-redundant-device-nam.patch31
-rw-r--r--target/linux/lantiq/patches-6.6/0028-NET-lantiq-various-etop-fixes.patch112
-rw-r--r--target/linux/lantiq/patches-6.6/0035-owrt-lantiq-wifi-and-ethernet-eeprom-handling.patch2
-rw-r--r--target/linux/lantiq/patches-6.6/0701-NET-lantiq-etop-of-mido.patch4
-rw-r--r--target/linux/lantiq/xrx200/base-files/etc/board.d/02_network4
-rw-r--r--target/linux/layerscape/Makefile3
-rw-r--r--target/linux/layerscape/armv7/config-6.14
-rw-r--r--target/linux/layerscape/armv7/config-6.64
-rw-r--r--target/linux/layerscape/armv8_64b/config-6.111
-rw-r--r--target/linux/layerscape/armv8_64b/config-6.611
-rw-r--r--target/linux/layerscape/armv8_64b/target.mk1
-rw-r--r--target/linux/layerscape/image/armv7.mk4
-rw-r--r--target/linux/layerscape/patches-6.1/302-arm64-dts-ls1012a-update-with-ppfe-support.patch288
-rw-r--r--target/linux/layerscape/patches-6.1/303-arm64-dts-ls1012a-frdm-workaround-by-updating-qspi-f.patch41
-rw-r--r--target/linux/layerscape/patches-6.1/304-arm64-dts-ls1012a-rdb-workaround-by-updating-qspi-fl.patch29
-rw-r--r--target/linux/layerscape/patches-6.1/305-arm64-dts-ls1046a-rdb-Update-qspi-spi-rx-bus-width-t.patch34
-rw-r--r--target/linux/layerscape/patches-6.1/400-LF-20-3-mtd-spi-nor-Use-1-bit-mode-of-spansion-s25fs.patch27
-rw-r--r--target/linux/layerscape/patches-6.1/701-staging-add-fsl_ppfe-driver.patch11808
-rw-r--r--target/linux/layerscape/patches-6.1/702-phy-Add-2.5G-SGMII-interface-mode.patch54
-rw-r--r--target/linux/layerscape/patches-6.1/703-layerscape-6.1-fix-compilation-warning-for-fsl-ppfe-.patch239
-rw-r--r--target/linux/layerscape/patches-6.1/704-net-phylink-treat-PHY_INTERFACE_MODE_2500SGMII-in-ph.patch42
-rw-r--r--target/linux/loongarch64/config-6.64
-rw-r--r--target/linux/malta/config-6.63
-rw-r--r--target/linux/mediatek/base-files/lib/preinit/05_set_preinit_iface1
-rw-r--r--target/linux/mediatek/base-files/lib/preinit/07_trigger_fip_scrubbing16
-rw-r--r--target/linux/mediatek/dts/mt7629-linksys-ea7500-v3.dts300
-rw-r--r--target/linux/mediatek/dts/mt7981a-edgecore-eap111.dts1
-rw-r--r--target/linux/mediatek/dts/mt7981a-glinet-gl-x3000-xe3000-common.dtsi2
-rw-r--r--target/linux/mediatek/dts/mt7981b-abt-asr3000.dts275
-rw-r--r--target/linux/mediatek/dts/mt7981b-cmcc-rax3000m-emmc.dtso74
-rw-r--r--target/linux/mediatek/dts/mt7981b-cmcc-rax3000m-nand.dtso31
-rw-r--r--target/linux/mediatek/dts/mt7981b-cmcc-rax3000m.dts3
-rw-r--r--target/linux/mediatek/dts/mt7981b-cudy-ap3000outdoor-v1.dts209
-rw-r--r--target/linux/mediatek/dts/mt7981b-glinet-gl-mt2500.dts2
-rw-r--r--target/linux/mediatek/dts/mt7981b-h3c-magic-nx30-pro.dts9
-rw-r--r--target/linux/mediatek/dts/mt7981b-jcg-q30-pro.dts9
-rw-r--r--target/linux/mediatek/dts/mt7981b-openwrt-one.dts30
-rw-r--r--target/linux/mediatek/dts/mt7981b-qihoo-360t7.dts9
-rw-r--r--target/linux/mediatek/dts/mt7981b-unielec-u7981-01-emmc.dts2
-rw-r--r--target/linux/mediatek/dts/mt7981b-xiaomi-mi-router-ax3000t-ubootmod.dts12
-rw-r--r--target/linux/mediatek/dts/mt7981b-xiaomi-mi-router-wr30u-ubootmod.dts12
-rw-r--r--target/linux/mediatek/dts/mt7981b-zyxel-nwa50ax-pro.dts2
-rw-r--r--target/linux/mediatek/dts/mt7986a-glinet-gl-mt6000.dts2
-rw-r--r--target/linux/mediatek/dts/mt7986a-jdcloud-re-cp-03.dts4
-rw-r--r--target/linux/mediatek/dts/mt7986a-netcore-n60.dts9
-rw-r--r--target/linux/mediatek/dts/mt7986a-tplink-tl-xtr8488.dts390
-rw-r--r--target/linux/mediatek/dts/mt7986a-zyxel-ex5601-t0-ubootmod.dts17
-rw-r--r--target/linux/mediatek/dts/mt7986a-zyxel-ex5700-telenor.dts4
-rw-r--r--target/linux/mediatek/files-6.6/arch/arm64/boot/dts/mediatek/mt7981-rfb-spim-nand.dtso14
-rw-r--r--target/linux/mediatek/files-6.6/arch/arm64/boot/dts/mediatek/mt7981-rfb.dts3
-rw-r--r--target/linux/mediatek/files-6.6/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-emmc.dtso2
-rw-r--r--target/linux/mediatek/files-6.6/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-sd.dtso2
-rw-r--r--target/linux/mediatek/files-6.6/arch/arm64/boot/dts/mediatek/mt7988a.dtsi17
-rw-r--r--target/linux/mediatek/files-6.6/drivers/net/phy/mediatek-2p5ge.c321
-rw-r--r--target/linux/mediatek/files/block/partitions/fit.c307
-rw-r--r--target/linux/mediatek/filogic/base-files/etc/board.d/01_leds5
-rw-r--r--target/linux/mediatek/filogic/base-files/etc/board.d/02_network28
-rw-r--r--target/linux/mediatek/filogic/base-files/etc/hotplug.d/firmware/11-mt76-caldata7
-rw-r--r--target/linux/mediatek/filogic/base-files/etc/hotplug.d/ieee80211/11_fix_wifi_mac22
-rwxr-xr-xtarget/linux/mediatek/filogic/base-files/lib/upgrade/platform.sh103
-rw-r--r--target/linux/mediatek/filogic/config-6.63
-rw-r--r--target/linux/mediatek/image/filogic.mk59
-rw-r--r--target/linux/mediatek/image/mt7622.mk12
-rw-r--r--target/linux/mediatek/image/mt7629.mk16
-rwxr-xr-xtarget/linux/mediatek/mt7622/base-files/lib/upgrade/platform.sh21
-rw-r--r--target/linux/mediatek/mt7622/config-6.63
-rwxr-xr-xtarget/linux/mediatek/mt7623/base-files/lib/upgrade/platform.sh7
-rw-r--r--target/linux/mediatek/mt7623/config-6.61
-rw-r--r--target/linux/mediatek/mt7629/base-files/etc/board.d/02_network8
-rwxr-xr-xtarget/linux/mediatek/mt7629/base-files/etc/init.d/bootcount3
-rwxr-xr-xtarget/linux/mediatek/mt7629/base-files/lib/upgrade/platform.sh5
-rw-r--r--target/linux/mediatek/mt7629/config-6.61
-rw-r--r--target/linux/mediatek/patches-6.6/041-block-fit-partition-parser.patch216
-rw-r--r--target/linux/mediatek/patches-6.6/330-snand-mtk-bmt-support.patch6
-rw-r--r--target/linux/mediatek/patches-6.6/351-pinctrl-add-mt7988-pd-pulltype-support.patch16
-rw-r--r--target/linux/mediatek/patches-6.6/432-drivers-spi-Add-support-for-dynamic-calibration.patch2
-rw-r--r--target/linux/mediatek/patches-6.6/733-01-net-phy-mediatek-Re-organize-MediaTek-ethernet-phy-d.patch3513
-rw-r--r--target/linux/mediatek/patches-6.6/733-02-net-phy-mediatek-Fix-spelling-errors-and-rearrange-v.patch62
-rw-r--r--target/linux/mediatek/patches-6.6/733-03-net-phy-mediatek-Move-LED-helper-functions-into-mtk-.patch742
-rw-r--r--target/linux/mediatek/patches-6.6/733-04-net-phy-mediatek-Improve-readability-of-mtk-phy-lib..patch70
-rw-r--r--target/linux/mediatek/patches-6.6/733-05-net-phy-mediatek-Integrate-read-write-page-helper-fu.patch141
-rw-r--r--target/linux/mediatek/patches-6.6/733-06-net-phy-mediatek-Hook-LED-helper-functions-in-mtk-ge.patch146
-rw-r--r--target/linux/mediatek/patches-6.6/733-07-net-phy-mediatek-add-MT7530-MT7531-s-PHY-ID-macros.patch54
-rw-r--r--target/linux/mediatek/patches-6.6/733-08-net-phy-mediatek-Change-mtk-ge-soc.c-line-wrapping.patch182
-rw-r--r--target/linux/mediatek/patches-6.6/733-09-net-phy-mediatek-Add-token-ring-access-helper-functi.patch614
-rw-r--r--target/linux/mediatek/patches-6.6/733-10-net-phy-mediatek-Extend-1G-TX-RX-link-pulse-time.patch219
-rw-r--r--target/linux/mediatek/patches-6.6/733-11-net-phy-add-driver-for-built-in-2.5G-ethernet-PHY-on.patch477
-rw-r--r--target/linux/mediatek/patches-6.6/733-12-net-phy-mediatek-Fix-alignment-in-callback-functions.patch130
-rw-r--r--target/linux/mediatek/patches-6.6/733-13-net-phy-mediatek-Remove-unnecessary-outer-parens-of-.patch65
-rw-r--r--target/linux/mediatek/patches-6.6/733-net-phy-add-driver-for-MediaTek-2.5G-PHY.patch39
-rw-r--r--target/linux/mediatek/patches-6.6/901-arm-add-cmdline-override.patch2
-rw-r--r--target/linux/mediatek/patches-6.6/911-dts-mt7622-bpi-r64-add-rootdisk.patch4
-rw-r--r--target/linux/mpc85xx/Makefile5
-rw-r--r--target/linux/mpc85xx/base-files/etc/board.d/02_network5
-rw-r--r--target/linux/mpc85xx/base-files/etc/hotplug.d/firmware/10-ath9k-eeprom33
-rw-r--r--target/linux/mpc85xx/config-6.1295
-rw-r--r--target/linux/mpc85xx/files/arch/powerpc/boot/dts/panda.dts5
-rw-r--r--target/linux/mpc85xx/files/arch/powerpc/boot/dts/tl-wdr4900-v1.dts166
-rw-r--r--target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/br200-wp.c16
-rw-r--r--target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/firebox_t10.c16
-rw-r--r--target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/hiveap-330.c16
-rw-r--r--target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/msm460.c16
-rw-r--r--target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/panda.c16
-rw-r--r--target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/red15w_rev1.c16
-rw-r--r--target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/tl_wdr4900_v1.c73
-rw-r--r--target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/ws-ap3710i.c16
-rw-r--r--target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/ws-ap3715i.c16
-rw-r--r--target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/ws-ap3825i.c16
-rw-r--r--target/linux/mpc85xx/image/p1010.mk1
-rw-r--r--target/linux/mpc85xx/image/p1020.mk2
-rw-r--r--target/linux/mpc85xx/p1010/config-default3
-rw-r--r--target/linux/mpc85xx/p1020/config-default19
-rw-r--r--target/linux/mpc85xx/patches-6.1/001-powerpc-85xx-add-gpio-keys-to-of-match-table.patch10
-rw-r--r--target/linux/mpc85xx/patches-6.1/010-powerpc-add-compressed-zImage-for-mpc85xx.patch61
-rw-r--r--target/linux/mpc85xx/patches-6.1/100-powerpc-85xx-tl-wdr4900-v1-support.patch83
-rw-r--r--target/linux/mpc85xx/patches-6.1/101-powerpc-85xx-hiveap-330-support.patch58
-rw-r--r--target/linux/mpc85xx/patches-6.1/102-powerpc-add-cmdline-override.patch37
-rw-r--r--target/linux/mpc85xx/patches-6.1/103-powerpc-85xx-red-15w-rev1.patch29
-rw-r--r--target/linux/mpc85xx/patches-6.1/104-powerpc-mpc85xx-change-P2020RDB-dts-file-for-OpenWRT.patch170
-rw-r--r--target/linux/mpc85xx/patches-6.1/105-powerpc-85xx-panda-support.patch30
-rw-r--r--target/linux/mpc85xx/patches-6.1/106-powerpc-85xx-ws-ap3710i-support.patch60
-rw-r--r--target/linux/mpc85xx/patches-6.1/107-powerpc-85xx-add-ws-ap3825i-support.patch67
-rw-r--r--target/linux/mpc85xx/patches-6.1/108-powerpc-85xx-firebox-t10-support.patch.patch29
-rw-r--r--target/linux/mpc85xx/patches-6.1/109-powerpc-85xx-add-ws-ap3715i-support.patch48
-rw-r--r--target/linux/mpc85xx/patches-6.1/110-powerpc-85xx-br200-wp-support.patch57
-rw-r--r--target/linux/mpc85xx/patches-6.1/111-powerpc-85xx-hpe-msm-support.patch31
-rw-r--r--target/linux/mpc85xx/patches-6.1/150-arch-powerpc-simpleboot-prevent-overwrite-of-CPU1-sp.patch41
-rw-r--r--target/linux/mpc85xx/patches-6.1/900-powerpc-bootwrapper-disable-uImage-generation.patch42
-rw-r--r--target/linux/mvebu/config-6.61
-rw-r--r--target/linux/mvebu/files-6.6/arch/arm64/boot/dts/marvell/armada-3720-gl-mv1000.dts1
-rw-r--r--target/linux/mvebu/image/cortexa53.mk1
-rw-r--r--target/linux/mvebu/image/cortexa9.mk3
-rw-r--r--target/linux/mvebu/image/gl-mv1000.bootscript28
-rw-r--r--target/linux/mvebu/modules.mk21
-rw-r--r--target/linux/mvebu/patches-6.6/820-v6.11-01-dt-bindings-firmware-add-cznic-turris-omnia-mcu-bind.patch125
-rw-r--r--target/linux/mvebu/patches-6.6/820-v6.11-02-platform-cznic-Add-preliminary-support-for-Turris-Om.patch922
-rw-r--r--target/linux/mvebu/patches-6.6/820-v6.11-03-platform-cznic-turris-omnia-mcu-Add-support-for-MCU-.patch1311
-rw-r--r--target/linux/mvebu/patches-6.6/820-v6.11-04-platform-cznic-turris-omnia-mcu-Add-support-for-powe.patch415
-rw-r--r--target/linux/mvebu/patches-6.6/820-v6.11-05-platform-cznic-turris-omnia-mcu-Add-support-for-MCU-.patch250
-rw-r--r--target/linux/mvebu/patches-6.6/820-v6.11-06-platform-cznic-turris-omnia-mcu-Add-support-for-MCU-.patch225
-rw-r--r--target/linux/mvebu/patches-6.6/820-v6.11-07-ARM-dts-turris-omnia-Add-MCU-system-controller-node.patch69
-rw-r--r--target/linux/mvebu/patches-6.6/820-v6.11-08-ARM-dts-turris-omnia-Add-GPIO-key-node-for-front-but.patch46
-rw-r--r--target/linux/mvebu/patches-6.6/820-v6.11-09-platform-cznic-turris-omnia-mcu-Depend-on-OF.patch32
-rw-r--r--target/linux/mvebu/patches-6.6/820-v6.11-10-platform-cznic-turris-omnia-mcu-Depend-on-WATCHDOG.patch32
-rw-r--r--target/linux/mvebu/patches-6.6/820-v6.11-11-platform-cznic-turris-omnia-mcu-fix-Kconfig-dependen.patch45
-rw-r--r--target/linux/mvebu/patches-6.6/907-MAINTAINERS-Add-an-entry-for-the-IEI-WT61P803-PUZZLE.patch2
-rw-r--r--target/linux/octeon/Makefile2
-rw-r--r--target/linux/octeon/base-files/lib/preinit/79_move_config28
-rwxr-xr-xtarget/linux/octeon/base-files/lib/upgrade/platform.sh62
-rw-r--r--target/linux/octeon/config-6.1274
-rw-r--r--target/linux/octeon/config-6.6283
-rw-r--r--target/linux/octeon/image/Makefile8
-rw-r--r--target/linux/octeon/patches-6.1/100-mips_image_cmdline_hack.patch38
-rw-r--r--target/linux/octeon/patches-6.1/130-add_itus_support.patch42
-rw-r--r--target/linux/octeon/patches-6.1/150-ubnt_usg_support.patch46
-rw-r--r--target/linux/octeon/patches-6.6/100-mips_image_cmdline_hack.patch38
-rw-r--r--target/linux/octeon/patches-6.6/100-ubnt_edgerouter2_support.patch (renamed from target/linux/octeon/patches-6.1/100-ubnt_edgerouter2_support.patch)0
-rw-r--r--target/linux/octeon/patches-6.6/110-er200-ethernet_probe_order.patch (renamed from target/linux/octeon/patches-6.1/110-er200-ethernet_probe_order.patch)0
-rw-r--r--target/linux/octeon/patches-6.6/120-cmdline-hack.patch (renamed from target/linux/octeon/patches-6.1/120-cmdline-hack.patch)0
-rw-r--r--target/linux/octeon/patches-6.6/130-add_itus_support.patch42
-rw-r--r--target/linux/octeon/patches-6.6/150-ubnt_usg_support.patch46
-rw-r--r--target/linux/octeon/patches-6.6/700-allocate_interface_by_label.patch (renamed from target/linux/octeon/patches-6.1/700-allocate_interface_by_label.patch)0
-rw-r--r--target/linux/octeon/patches-6.6/701-honor_sgmii_node_device_tree_status.patch (renamed from target/linux/octeon/patches-6.1/701-honor_sgmii_node_device_tree_status.patch)0
-rw-r--r--target/linux/omap/Makefile2
-rw-r--r--target/linux/omap/config-6.12
-rw-r--r--target/linux/omap/patches/900-use-cpsw-ethernet-driver.patch93
-rw-r--r--target/linux/pistachio/config-6.12
-rw-r--r--target/linux/pistachio/config-6.62
-rw-r--r--target/linux/qoriq/Makefile1
-rw-r--r--target/linux/qoriq/config-6.12
-rw-r--r--target/linux/qoriq/config-6.6430
-rw-r--r--target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6010-xe3-4.dts454
-rw-r--r--target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6018-fixed-smps.dtsi52
-rw-r--r--target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-eap660hd-v1.dts131
-rw-r--r--target/linux/qualcommax/image/ipq60xx.mk13
-rw-r--r--target/linux/qualcommax/image/ipq807x.mk14
-rw-r--r--target/linux/qualcommax/ipq60xx/base-files/etc/board.d/02_network3
-rw-r--r--target/linux/qualcommax/ipq60xx/base-files/etc/hotplug.d/firmware/11-ath11-caldata10
-rw-r--r--target/linux/qualcommax/ipq60xx/base-files/lib/upgrade/platform.sh4
-rw-r--r--target/linux/qualcommax/ipq807x/base-files/etc/board.d/02_network7
-rw-r--r--target/linux/qualcommax/ipq807x/base-files/etc/hotplug.d/firmware/11-ath11k-caldata7
-rw-r--r--target/linux/qualcommax/ipq807x/base-files/lib/preinit/09_mount_factory_data19
-rw-r--r--target/linux/qualcommax/ipq807x/base-files/lib/upgrade/platform.sh76
-rw-r--r--target/linux/qualcommax/patches-6.6/0025-v6.7-cpufreq-qcom-nvmem-add-support-for-IPQ6018.patch6
-rw-r--r--target/linux/qualcommax/patches-6.6/0026-v6.7-cpufreq-qcom-nvmem-add-support-for-IPQ8074.patch6
-rw-r--r--target/linux/qualcommax/patches-6.6/0028-v6.7-arm64-dts-qcom-ipq8074-include-the-GPLL0-as-clock-pr.patch2
-rw-r--r--target/linux/qualcommax/patches-6.6/0052-v6.7-arm64-dts-qcom-ipq6018-include-the-GPLL0-as.patch2
-rw-r--r--target/linux/qualcommax/patches-6.6/0056-v6.9-arm64-dts-qcom-Fix-hs_phy_irq-for-QUSB2-targets.patch2
-rw-r--r--target/linux/qualcommax/patches-6.6/0059-v6.9-arm64-dts-qcom-ipq6018-add-thermal-zones.patch2
-rw-r--r--target/linux/qualcommax/patches-6.6/0111-arm64-dts-qcom-ipq8074-use-msi-parent-for-PCIe.patch6
-rw-r--r--target/linux/qualcommax/patches-6.6/0120-arm64-dts-qcom-Enable-Q6v5-WCSS-for-ipq8074-SoC.patch2
-rw-r--r--target/linux/qualcommax/patches-6.6/0121-arm64-dts-ipq8074-Add-WLAN-node.patch2
-rw-r--r--target/linux/qualcommax/patches-6.6/0906-arm64-dts-qcom-ipq6018-add-wifi-node.patch2
-rw-r--r--target/linux/qualcommax/patches-6.6/0907-soc-qcom-fix-smp2p-ack-on-ipq6018.patch2
-rw-r--r--target/linux/qualcommax/patches-6.6/0909-arm64-dts-qcom-ipq6018-assign-QDSS_AT-clock-to-wifi-.patch2
-rw-r--r--target/linux/ramips/dts/mt7620a_iodata_wn-ac733gr3.dts2
-rw-r--r--target/linux/ramips/dts/mt7620a_tplink_archer-c2-v1.dts2
-rw-r--r--target/linux/ramips/dts/mt7620a_tplink_archer-c5-v4.dts2
-rw-r--r--target/linux/ramips/dts/mt7620a_tplink_ec220-g5-v2.dts2
-rw-r--r--target/linux/ramips/dts/mt7620a_wavlink_wl-wn531g3-a2.dts201
-rw-r--r--target/linux/ramips/dts/mt7620a_zyxel_keenetic-viva.dts4
-rw-r--r--target/linux/ramips/dts/mt7620n_zyxel_keenetic-lite-iii-a.dts2
-rw-r--r--target/linux/ramips/dts/mt7620n_zyxel_keenetic-omni-ii.dts2
-rw-r--r--target/linux/ramips/dts/mt7620n_zyxel_keenetic-omni.dts2
-rw-r--r--target/linux/ramips/dts/mt7621_keenetic_kn-3510.dts247
-rw-r--r--target/linux/ramips/dts/mt7621_mtc_wr1201.dts10
-rw-r--r--target/linux/ramips/dts/mt7621_netgear_wax214v2.dts228
-rw-r--r--target/linux/ramips/dts/mt7621_wodesys_wd-r1802u.dts153
-rw-r--r--target/linux/ramips/dts/mt7621_zbtlink_zbt-we1326.dts168
-rw-r--r--target/linux/ramips/dts/mt7621_zbtlink_zbt-we3526.dts165
-rw-r--r--target/linux/ramips/dts/mt7621_zbtlink_zbt-wexx26.dtsi171
-rw-r--r--target/linux/ramips/dts/mt7621_zyxel_lte3301-plus.dts2
-rw-r--r--target/linux/ramips/dts/mt7621_zyxel_lte5398-m904.dts2
-rw-r--r--target/linux/ramips/dts/mt7621_zyxel_nr7101.dts2
-rw-r--r--target/linux/ramips/dts/mt7621_zyxel_nwa50ax.dts2
-rw-r--r--target/linux/ramips/dts/mt7621_zyxel_nwa55axe.dts2
-rw-r--r--target/linux/ramips/dts/mt7621_zyxel_wap6805.dts2
-rw-r--r--target/linux/ramips/dts/mt7621_zyxel_wsm20.dts2
-rw-r--r--target/linux/ramips/dts/mt7628an_xiaomi_mi-router-4a-100m-intl-v2.dts94
-rw-r--r--target/linux/ramips/dts/mt7628an_yuncore_cpe200.dts165
-rw-r--r--target/linux/ramips/dts/mt7628an_yuncore_m300.dts148
-rw-r--r--target/linux/ramips/dts/mt7628an_zyxel_keenetic-extra-ii.dts2
-rw-r--r--target/linux/ramips/dts/rt3052_zyxel_keenetic.dts2
-rw-r--r--target/linux/ramips/dts/rt3052_zyxel_nbg-419n.dts2
-rw-r--r--target/linux/ramips/dts/rt3352_zyxel_nbg-419n-v2.dts2
-rw-r--r--target/linux/ramips/dts/rt3662_asus_rt-n56u.dts2
-rw-r--r--target/linux/ramips/dts/rt3662_dlink_dir-645.dts2
-rw-r--r--target/linux/ramips/dts/rt3662_edimax_br-6475nd.dts2
-rw-r--r--target/linux/ramips/dts/rt3662_samsung_cy-swr1100.dts2
-rw-r--r--target/linux/ramips/dts/rt3883_belkin_f9k110x.dtsi2
-rw-r--r--target/linux/ramips/dts/rt5350_zyxel_keenetic-4g-b.dts2
-rw-r--r--target/linux/ramips/dts/rt5350_zyxel_keenetic-lite-b.dts2
-rw-r--r--target/linux/ramips/dts/rt5350_zyxel_keenetic-start.dts2
-rw-r--r--target/linux/ramips/files/drivers/mtd/nand/raw/mt7621_nand.c41
-rw-r--r--target/linux/ramips/files/drivers/net/ethernet/ralink/gsw_mt7620.c2
-rw-r--r--target/linux/ramips/files/drivers/net/ethernet/ralink/mtk_eth_soc.c3
-rw-r--r--target/linux/ramips/files/drivers/pinctrl/pinctrl-aw9523.c1128
-rw-r--r--target/linux/ramips/image/mt7620.mk22
-rw-r--r--target/linux/ramips/image/mt7621.mk60
-rw-r--r--target/linux/ramips/image/mt76x8.mk28
-rw-r--r--target/linux/ramips/image/rt305x.mk12
-rw-r--r--target/linux/ramips/mt7620/base-files/etc/board.d/02_network5
-rw-r--r--target/linux/ramips/mt7621/base-files/etc/board.d/02_network7
-rw-r--r--target/linux/ramips/mt7621/base-files/etc/hotplug.d/ieee80211/05-wifi-migrate3
-rw-r--r--target/linux/ramips/mt7621/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac9
-rwxr-xr-xtarget/linux/ramips/mt7621/base-files/lib/upgrade/platform.sh2
-rw-r--r--target/linux/ramips/mt76x8/base-files/etc/board.d/01_leds7
-rw-r--r--target/linux/ramips/mt76x8/base-files/etc/board.d/02_network11
-rw-r--r--target/linux/ramips/mt76x8/config-6.62
-rw-r--r--target/linux/ramips/patches-6.6/410-mtd-rawnand-add-driver-support-for-MT7621-nand-flash.patch2
-rw-r--r--target/linux/ramips/patches-6.6/805-01-v6.9-pinctrl-Add-driver-for-Awinic-AW9523-B-I2C-GPIO-Expa.patch1190
-rw-r--r--target/linux/ramips/patches-6.6/805-02-v6.9-pinctrl-aw9523-Add-proper-terminator.patch26
-rw-r--r--target/linux/ramips/patches-6.6/805-03-v6.10-pinctrl-aw9523-Destroy-mutex-on-remove.patch41
-rw-r--r--target/linux/ramips/patches-6.6/805-04-v6.10-pinctrl-aw9523-Use-correct-error-code-for-not-suppor.patch62
-rw-r--r--target/linux/ramips/patches-6.6/805-05-v6.10-pinctrl-aw9523-Always-try-both-ports-in-aw9523_gpio_.patch47
-rw-r--r--target/linux/ramips/patches-6.6/805-06-v6.10-pinctrl-aw9523-Make-use-of-struct-pinfunction-and-PI.patch72
-rw-r--r--target/linux/ramips/patches-6.6/805-07-v6.10-pinctrl-aw9523-Use-temporary-variable-for-HW-IRQ-num.patch50
-rw-r--r--target/linux/ramips/patches-6.6/805-08-v6.10-pinctrl-aw9523-Get-rid-of-redundant-U8_MAX-pieces.patch61
-rw-r--r--target/linux/ramips/patches-6.6/805-09-v6.10-pinctrl-aw9523-Remove-unused-irqchip-field-in-struct.patch52
-rw-r--r--target/linux/ramips/patches-6.6/805-10-v6.10-pinctrl-aw9523-Make-use-of-dev_err_probe.patch40
-rw-r--r--target/linux/ramips/patches-6.6/805-11-v6.10-pinctrl-aw9523-Sort-headers-and-group-pinctrl.patch41
-rw-r--r--target/linux/ramips/patches-6.6/805-12-v6.10-pinctrl-aw9523-Fix-indentation-in-a-few-places.patch62
-rw-r--r--target/linux/ramips/patches-6.6/805-pinctrl-AW9523.patch72
-rw-r--r--target/linux/ramips/patches-6.6/810-uvc-add-iPassion-iP2970-support.patch18
-rw-r--r--target/linux/realtek/dts-5.15/rtl8380_zyxel_gs1900-10hp.dts2
-rw-r--r--target/linux/realtek/dts-5.15/rtl8380_zyxel_gs1900-8.dts2
-rw-r--r--target/linux/realtek/dts-5.15/rtl8380_zyxel_gs1900-8hp-v1.dts2
-rw-r--r--target/linux/realtek/dts-5.15/rtl8380_zyxel_gs1900-8hp-v2.dts2
-rw-r--r--target/linux/realtek/dts-5.15/rtl8382_zyxel_gs1900-16.dts2
-rw-r--r--target/linux/realtek/dts-5.15/rtl8382_zyxel_gs1900-24-v1.dts2
-rw-r--r--target/linux/realtek/dts-5.15/rtl8382_zyxel_gs1900-24e.dts2
-rw-r--r--target/linux/realtek/dts-5.15/rtl8382_zyxel_gs1900-24ep.dts2
-rw-r--r--target/linux/realtek/dts-5.15/rtl8382_zyxel_gs1900-24hp-v1.dts2
-rw-r--r--target/linux/realtek/dts-5.15/rtl8382_zyxel_gs1900-24hp-v2.dts2
-rw-r--r--target/linux/realtek/image/common.mk2
-rw-r--r--target/linux/realtek/image/rtl838x.mk2
-rw-r--r--target/linux/rockchip/armv8/base-files/etc/board.d/01_leds5
-rw-r--r--target/linux/rockchip/armv8/base-files/etc/board.d/02_network18
-rw-r--r--target/linux/rockchip/armv8/base-files/etc/hotplug.d/net/40-net-smp-affinity16
-rw-r--r--target/linux/rockchip/armv8/config-6.622
-rw-r--r--target/linux/rockchip/armv8/target.mk4
-rw-r--r--target/linux/rockchip/image/armv8.mk102
-rw-r--r--target/linux/rockchip/image/default.bootscript2
-rw-r--r--target/linux/rockchip/image/rock-pi-s.bootscript7
-rw-r--r--target/linux/rockchip/patches-6.6/001-v6.8-arm64-dts-rockchip-Add-ethernet0-alias-to-the-dts-for-RK3566-boards.patch (renamed from target/linux/rockchip/patches-6.6/023-v6.8-arm64-dts-rockchip-Add-ethernet0-alias-to-the-dts-for-RK3566-boards.patch)0
-rw-r--r--target/linux/rockchip/patches-6.6/002-v6.9-arm64-dts-rockchip-adjust-vendor-on-Banana-Pi-R2-Pro.patch (renamed from target/linux/rockchip/patches-6.6/030-v6.9-arm64-dts-rockchip-adjust-vendor-on-Banana-Pi-R2-Pro.patch)0
-rw-r--r--target/linux/rockchip/patches-6.6/003-v6.10-arm64-dts-rockchip-Add-cache-information-to-the-SoC-dtsi-.patch (renamed from target/linux/rockchip/patches-6.6/031-v6.10-arm64-dts-rockchip-Add-cache-information-to-the-SoC-dtsi-.patch)0
-rw-r--r--target/linux/rockchip/patches-6.6/004-next-soc-rockchip-io-domain-Add-RK3308-IO-voltage-domains.patch86
-rw-r--r--target/linux/rockchip/patches-6.6/005-v6.11-arm64-dts-rockchip-Add-rk3308-IO-voltage-domains.patch28
-rw-r--r--target/linux/rockchip/patches-6.6/006-v6.8-arm64-dts-rockchip-add-gpio-line-names-to-rk3308-roc.patch84
-rw-r--r--target/linux/rockchip/patches-6.6/007-v6.8-arm64-dts-rockchip-rk3308-rock-pi-s-gpio-line-names-.patch152
-rw-r--r--target/linux/rockchip/patches-6.6/008-v6.11-arm64-dts-rockchip-Add-io-domains-to-rk3308-rock-pi-.patch35
-rw-r--r--target/linux/rockchip/patches-6.6/009-v6.10-arm64-dts-rockchip-Add-Radxa-ROCK-3C.patch769
-rw-r--r--target/linux/rockchip/patches-6.6/010-v6.11-arm64-dts-rockchip-change-spi-max-frequency-for-Radx.patch26
-rw-r--r--target/linux/rockchip/patches-6.6/011-v6.11-arm64-dts-rockchip-Add-Radxa-ZERO-3W-3E.patch657
-rw-r--r--target/linux/rockchip/patches-6.6/012-v6.11-arm64-dts-rockchip-fix-mmc-aliases-for-Radxa-ZERO-3E.patch64
-rw-r--r--target/linux/rockchip/patches-6.6/013-v6.11-arm64-dts-rockchip-add-gpio-line-names-to-radxa-zero.patch101
-rw-r--r--target/linux/rockchip/patches-6.6/014-v6.11-arm64-dts-rockchip-Add-Radxa-ROCK-3B.patch815
-rw-r--r--target/linux/rockchip/patches-6.6/015-v6.10-arm64-dts-rockchip-correct-the-model-name-for-Radxa-.patch29
-rw-r--r--target/linux/rockchip/patches-6.6/030-01-v6.9-clk-rockchip-rk3588-fix-CLK_NR_CLKS-usage.patch78
-rw-r--r--target/linux/rockchip/patches-6.6/030-02-v6.9-dt-bindings-clock-rk3588-drop-CLK_NR_CLKS.patch27
-rw-r--r--target/linux/rockchip/patches-6.6/030-03-v6.9-dt-bindings-clock-rk3588-add-missing-PCLK_VO1GRF.patch26
-rw-r--r--target/linux/rockchip/patches-6.6/030-04-v6.9-clk-rockchip-rk3588-fix-pclk_vo0grf-and-pclk_vo1grf.patch59
-rw-r--r--target/linux/rockchip/patches-6.6/030-05-v6.9-clk-rockchip-rk3588-fix-indent.patch26
-rw-r--r--target/linux/rockchip/patches-6.6/030-06-v6.9-clk-rockchip-rk3588-use-linked-clock-ID-for-GATE_LINK.patch78
-rw-r--r--target/linux/rockchip/patches-6.6/030-07-v6.10-dt-bindings-reset-Define-reset-id-used-for-HDMI-Receiver.patch24
-rw-r--r--target/linux/rockchip/patches-6.6/030-08-v6.10-clk-rockchip-rk3588-Add-reset-line-for-HDMI-Receiver.patch25
-rw-r--r--target/linux/rockchip/patches-6.6/031-01-v6.7-mfd-rk8xx-Add-support-for-standard-system-power-controlle.patch28
-rw-r--r--target/linux/rockchip/patches-6.6/031-02-v6.7-mfd-rk8xx-Add-support-for-RK806-power-off.patch29
-rw-r--r--target/linux/rockchip/patches-6.6/032-01-v6.10-phy-rockchip-add-usbdp-combo-phy-driver.patch1670
-rw-r--r--target/linux/rockchip/patches-6.6/032-02-v6.10-phy-rockchip-usbdp-fix-uninitialized-variable.patch35
-rw-r--r--target/linux/rockchip/patches-6.6/032-03-v6.10-phy-rockchip-fix-CONFIG_TYPEC-dependency.patch43
-rw-r--r--target/linux/rockchip/patches-6.6/032-04-v6.10-phy-rockchip-Fix-typo-in-function-names.patch79
-rw-r--r--target/linux/rockchip/patches-6.6/032-05-v6.10-phy-rockchip-snps-pcie3-add-support-for.patch106
-rw-r--r--target/linux/rockchip/patches-6.6/034-v6.7-usb-dwc3-add-optional-PHY-interface-clocks.patch91
-rw-r--r--target/linux/rockchip/patches-6.6/050-01-v6.8-arm64-dts-rockchip-Add-sfc-node-to-rk3588s.patch35
-rw-r--r--target/linux/rockchip/patches-6.6/050-02-v6.8-arm64-dts-rockchip-Add-I2S2-M0-pin-definitions-to-rk3588s.patch58
-rw-r--r--target/linux/rockchip/patches-6.6/050-03-v6.8-arm64-dts-rockchip-Add-UART9-M0-pin-definitions-to-rk3588.patch32
-rw-r--r--target/linux/rockchip/patches-6.6/050-04-v6.8-arm64-dts-rockchip-Add-AV1-decoder-node-to-rk3588s.patch37
-rw-r--r--target/linux/rockchip/patches-6.6/050-05-v6.8-arm64-dts-rockchip-Add-DFI-to-rk3588s.patch50
-rw-r--r--target/linux/rockchip/patches-6.6/050-06-v6.8-arm64-dts-rockchip-rk3588s-Add-USB3-host-controller.patch48
-rw-r--r--target/linux/rockchip/patches-6.6/050-07-v6.7-arm64-dts-rockchip-drop-interrupt-names-property-from.patch27
-rw-r--r--target/linux/rockchip/patches-6.6/050-08-v6.8-arm64-dts-rockchip-move-rk3588-serial-aliases-to-soc-dtsi.patch139
-rw-r--r--target/linux/rockchip/patches-6.6/050-09-v6.8-arm64-dts-rockchip-add-rk3588-i2c-aliases-to-soc-dtsi.patch38
-rw-r--r--target/linux/rockchip/patches-6.6/050-10-v6.8-arm64-dts-rockchip-add-rk3588-gpio-aliases-to-soc-dtsi.patch34
-rw-r--r--target/linux/rockchip/patches-6.6/050-11-v6.8-arm64-dts-rockchip-add-rk3588-spi-aliases-to-soc-dtsi.patch34
-rw-r--r--target/linux/rockchip/patches-6.6/050-12-v6.8-arm64-dts-rockchip-Add-vop-on-rk3588.patch120
-rw-r--r--target/linux/rockchip/patches-6.6/050-13-v6.9-arm64-dts-rockchip-Add-HDMI0-PHY-to-rk3588.patch51
-rw-r--r--target/linux/rockchip/patches-6.6/050-14-v6.9-arm64-dts-rockchip-add-clock-to-vo1-grf-syscon-on-rk3588.patch25
-rw-r--r--target/linux/rockchip/patches-6.6/050-15-v6.10-arm64-dts-rockchip-Add-rk3588-GPU-node.patch81
-rw-r--r--target/linux/rockchip/patches-6.6/050-16-v6.10-arm64-dts-rockchip-Fix-ordering-of-nodes-on-rk3588s.patch384
-rw-r--r--target/linux/rockchip/patches-6.6/050-17-v6.10-arm64-dts-rockchip-fix-usb2phy-nodename-for-rk3588.patch35
-rw-r--r--target/linux/rockchip/patches-6.6/050-18-v6.10-arm64-dts-rockchip-reorder-usb2phy-properties-for-rk3588.patch53
-rw-r--r--target/linux/rockchip/patches-6.6/050-19-v6.10-arm64-dts-rockchip-add-USBDP-phys-on-rk3588.patch175
-rw-r--r--target/linux/rockchip/patches-6.6/050-20-v6.10-arm64-dts-rockchip-add-USB3-DRD-controllers-on-rk3588.patch75
-rw-r--r--target/linux/rockchip/patches-6.6/050-21-v6.10-arm64-dts-rockchip-add-rk3588-pcie-and-php-IOMMUs.patch74
-rw-r--r--target/linux/rockchip/patches-6.6/050-22-v6.11-arm64-dts-rockchip-Prepare-RK3588-SoC-dtsi-files-for.patch14208
-rw-r--r--target/linux/rockchip/patches-6.6/050-23-v6.11-arm64-dts-rockchip-add-thermal-zones-information-on-RK358.patch193
-rw-r--r--target/linux/rockchip/patches-6.6/050-24-v6.11-arm64-dts-rockchip-add-passive-GPU-cooling-on-RK3588.patch50
-rw-r--r--target/linux/rockchip/patches-6.6/050-25-v6.11-arm64-dts-rockchip-Add-OPP-data-for-CPU-cores-on-RK3588.patch205
-rw-r--r--target/linux/rockchip/patches-6.6/050-26-v6.11-arm64-dts-rockchip-Add-OPP-data-for-CPU-cores-on-RK3588j.patch140
-rw-r--r--target/linux/rockchip/patches-6.6/050-27-v6.11-arm64-dts-rockchip-Split-GPU-OPPs-of-RK3588-and-RK3588j.patch177
-rw-r--r--target/linux/rockchip/patches-6.6/051-01-v6.8-arm64-dts-rockchip-add-USB3-host-to-rock-5a.patch39
-rw-r--r--target/linux/rockchip/patches-6.6/051-02-v6.10-arm64-dts-rockchip-add-upper-USB3-port-to-rock-5a.patch56
-rw-r--r--target/linux/rockchip/patches-6.6/051-03-v6.11-arm64-dts-rockchip-add-but-disabled-SFC-node-for-Radxa.patch45
-rw-r--r--target/linux/rockchip/patches-6.6/051-04-v6.12-arm64-dts-rockchip-enable-PCIe-on-M.2-E-key-for-Radxa-ROC.patch110
-rw-r--r--target/linux/rockchip/patches-6.6/052-01-v6.7-arm64-dts-rockchip-add-PCIe-network-controller-to-rock-5b.patch72
-rw-r--r--target/linux/rockchip/patches-6.6/052-02-v6.7-arm64-dts-rockchip-add-PCIe-for-M.2-M-key-to-rock-5b.patch73
-rw-r--r--target/linux/rockchip/patches-6.6/052-03-v6.7-arm64-dts-rockchip-add-PCIe-for-M.2-E-Key-to-rock-5b.patch80
-rw-r--r--target/linux/rockchip/patches-6.6/052-04-v6.7-arm64-dts-rockchip-Add-sdio-node-to-rock-5b.patch93
-rw-r--r--target/linux/rockchip/patches-6.6/052-05-v6.8-arm64-dts-rockchip-Remove-duplicate-regulator-vcc3v3_wf.patch65
-rw-r--r--target/linux/rockchip/patches-6.6/052-06-v6.8-arm64-dts-rockchip-Enable-UART6-on-rock-5b.patch32
-rw-r--r--target/linux/rockchip/patches-6.6/052-07-v6.8-arm64-dts-rockchip-add-status-LED-to-rock-5b.patch57
-rw-r--r--target/linux/rockchip/patches-6.6/052-08-v6.8-arm64-dts-rockchip-add-USB3-host-to-rock-5b.patch39
-rw-r--r--target/linux/rockchip/patches-6.6/052-09-v6.9-arm64-dts-rockchip-support-poweroff-on-the-rock-5b.patch31
-rw-r--r--target/linux/rockchip/patches-6.6/052-10-v6.9-arm64-dts-rockchip-correct-gpio_pwrctrl1-typo-on-rock-5b.patch27
-rw-r--r--target/linux/rockchip/patches-6.6/052-11-v6.9-arm64-dts-rockchip-add-rfkill-node-for-M-2-Key-E-WiFi-on-.patch34
-rw-r--r--target/linux/rockchip/patches-6.6/052-12-v6.10-arm64-dts-rockchip-Enable-GPU-on-rk3588-rock5b.patch29
-rw-r--r--target/linux/rockchip/patches-6.6/052-13-v6.10-arm64-dts-rockchip-Correct-the-model-names-for-Radxa-ROCK.patch43
-rw-r--r--target/linux/rockchip/patches-6.6/052-13-v6.10-arm64-dts-rockchip-add-lower-USB3-port-to-rock-5b.patch55
-rw-r--r--target/linux/rockchip/patches-6.6/052-14-v6.11-arm64-dts-rockchip-enable-automatic-fan-control-on-Rock-5.patch67
-rw-r--r--target/linux/rockchip/patches-6.6/052-15-v6.11-arm64-dts-rockchip-add-SFC-support-for-Radxa-ROCK-5B.patch39
-rw-r--r--target/linux/rockchip/patches-6.6/052-16-v6.11-arm64-dts-rockchip-enable-thermal-management-on-all-RK358.patch66
-rw-r--r--target/linux/rockchip/patches-6.6/053-v6.9-arm64-dts-rockchip-Add-support-for-NanoPi-R6S.patch792
-rw-r--r--target/linux/rockchip/patches-6.6/113-rock-pi-s-add-led-aliases-and-stop-heartbeat.patch38
-rw-r--r--target/linux/rockchip/patches-6.6/114-rock-pi-e-add-led-aliases-and-stop-heartbeat.patch27
-rw-r--r--target/linux/rockchip/patches-6.6/115-rock-3a-add-led-aliases-and-stop-heartbeat.patch29
-rw-r--r--target/linux/rockchip/patches-6.6/116-arm64-dts-rockchip-Update-LED-properties-for-Radxa-Ro.patch38
-rw-r--r--target/linux/rockchip/patches-6.6/117-arm64-dts-rockchip-lower-mmc-speed-for-Radxa-Rock-5A.patch26
-rw-r--r--target/linux/rockchip/patches-6.6/118-arm64-dts-rockchip-Update-LED-properties-for-Radxa-Ro.patch38
-rw-r--r--target/linux/rockchip/patches-6.6/119-arm64-dts-rockchip-lower-mmc-speed-for-Radxa-Rock-5B.patch26
-rw-r--r--target/linux/rockchip/patches-6.6/120-arm64-dts-rockchip-add-led-aliases-and-stop-heartbeat-for-nanopc-t6.patch22
-rw-r--r--target/linux/rockchip/patches-6.6/121-arm64-dts-rockchip-lower-mmc-speed-for-nanopc-t6.patch11
-rw-r--r--target/linux/rockchip/patches-6.6/122-rock-3c-add-led-aliases-and-stop-heartbeat.patch29
-rw-r--r--target/linux/rockchip/patches-6.6/123-radxa-zero-3-add-led-aliases-and-stop-heartbeat.patch30
-rw-r--r--target/linux/rockchip/patches-6.6/124-rock-3b-add-led-aliases-and-stop-heartbeat.patch27
-rw-r--r--target/linux/rockchip/patches-6.6/300-hwrng-add-Rockchip-SoC-hwrng-driver.patch340
-rw-r--r--target/linux/rockchip/patches-6.6/300-hwrng-add-hwrng-driver-for-Rockchip-RK3568-SoC.patch290
-rw-r--r--target/linux/rockchip/patches-6.6/301-arm64-dts-rockchip-add-DT-entry-for-RNG-to-RK3568.patch49
-rw-r--r--target/linux/rockchip/patches-6.6/301-arm64-dts-rockchip-add-DT-entry-for-RNG-to-RK356x.patch56
-rw-r--r--target/linux/starfive/Makefile2
-rw-r--r--target/linux/starfive/config-6.1555
-rw-r--r--target/linux/starfive/config-6.6579
-rw-r--r--target/linux/starfive/patches-6.1/0001-dt-bindings-clock-Add-StarFive-JH7110-system-clock-a.patch482
-rw-r--r--target/linux/starfive/patches-6.1/0002-dt-bindings-clock-Add-StarFive-JH7110-always-on-cloc.patch176
-rw-r--r--target/linux/starfive/patches-6.1/0003-clk-starfive-Replace-SOC_STARFIVE-with-ARCH_STARFIVE.patch53
-rw-r--r--target/linux/starfive/patches-6.1/0004-clk-starfive-Factor-out-common-JH7100-and-JH7110-cod.patch749
-rw-r--r--target/linux/starfive/patches-6.1/0005-clk-starfive-Rename-clk-starfive-jh7100.h-to-clk-sta.patch290
-rw-r--r--target/linux/starfive/patches-6.1/0006-clk-starfive-Rename-jh7100-to-jh71x0-for-the-common-.patch1249
-rw-r--r--target/linux/starfive/patches-6.1/0007-reset-starfive-Replace-SOC_STARFIVE-with-ARCH_STARFI.patch30
-rw-r--r--target/linux/starfive/patches-6.1/0008-reset-Create-subdirectory-for-StarFive-drivers.patch436
-rw-r--r--target/linux/starfive/patches-6.1/0009-reset-starfive-Factor-out-common-JH71X0-reset-code.patch390
-rw-r--r--target/linux/starfive/patches-6.1/0010-reset-starfive-Extract-the-common-JH71X0-reset-code.patch215
-rw-r--r--target/linux/starfive/patches-6.1/0011-reset-starfive-Rename-jh7100-to-jh71x0-for-the-commo.patch167
-rw-r--r--target/linux/starfive/patches-6.1/0012-reset-starfive-jh71x0-Use-32bit-I-O-on-32bit-registe.patch146
-rw-r--r--target/linux/starfive/patches-6.1/0013-clk-starfive-Add-StarFive-JH7110-system-clock-driver.patch557
-rw-r--r--target/linux/starfive/patches-6.1/0014-clk-starfive-Add-StarFive-JH7110-always-on-clock-dri.patch206
-rw-r--r--target/linux/starfive/patches-6.1/0015-reset-starfive-Add-StarFive-JH7110-reset-driver.patch113
-rw-r--r--target/linux/starfive/patches-6.1/0016-MAINTAINERS-generalise-StarFive-clk-reset-entries.patch50
-rw-r--r--target/linux/starfive/patches-6.1/0017-clk-starfive-Avoid-casting-iomem-pointers.patch128
-rw-r--r--target/linux/starfive/patches-6.1/0018-dt-bindings-timer-Add-StarFive-JH7110-clint.patch27
-rw-r--r--target/linux/starfive/patches-6.1/0019-dt-bindings-interrupt-controller-Add-StarFive-JH7110.patch28
-rw-r--r--target/linux/starfive/patches-6.1/0020-dt-bindings-riscv-Add-SiFive-S7-compatible.patch27
-rw-r--r--target/linux/starfive/patches-6.1/0021-riscv-dts-starfive-Add-initial-StarFive-JH7110-devic.patch549
-rw-r--r--target/linux/starfive/patches-6.1/0022-riscv-dts-starfive-Add-StarFive-JH7110-pin-function-.patch331
-rw-r--r--target/linux/starfive/patches-6.1/0023-riscv-dts-starfive-Add-StarFive-JH7110-VisionFive-2-.patch290
-rw-r--r--target/linux/starfive/patches-6.1/0024-riscv-dts-starfive-Add-StarFive-VisionFive-V1-device.patch43
-rw-r--r--target/linux/starfive/patches-6.1/0025-riscv-dts-starfive-Add-common-DT-for-JH7100-based-bo.patch349
-rw-r--r--target/linux/starfive/patches-6.1/0026-dt-bindings-pinctrl-Add-StarFive-JH7110-sys-pinctrl.patch303
-rw-r--r--target/linux/starfive/patches-6.1/0027-dt-bindings-pinctrl-Add-StarFive-JH7110-aon-pinctrl.patch176
-rw-r--r--target/linux/starfive/patches-6.1/0028-pinctrl-starfive-Add-StarFive-JH7110-sys-controller-.patch1581
-rw-r--r--target/linux/starfive/patches-6.1/0029-pinctrl-starfive-Add-StarFive-JH7110-aon-controller-.patch224
-rw-r--r--target/linux/starfive/patches-6.1/0030-config-add-jh7110-defconfig-for-test-mini.patch228
-rw-r--r--target/linux/starfive/patches-6.1/0031-dt-bindings-clock-Add-StarFive-JH7110-PLL-clock-gene.patch80
-rw-r--r--target/linux/starfive/patches-6.1/0032-clk-starfive-Add-StarFive-JH7110-PLL-clock-driver.patch786
-rw-r--r--target/linux/starfive/patches-6.1/0033-dt-bindings-clock-jh7110-syscrg-Add-PLL-clock-inputs.patch75
-rw-r--r--target/linux/starfive/patches-6.1/0034-clk-starfive-jh7110-sys-Modify-PLL-clocks-source.patch71
-rw-r--r--target/linux/starfive/patches-6.1/0035-dt-bindings-power-Add-starfive-jh7110-pmu.patch86
-rw-r--r--target/linux/starfive/patches-6.1/0036-soc-starfive-Add-StarFive-JH71XX-pmu-driver.patch478
-rw-r--r--target/linux/starfive/patches-6.1/0037-dt-bindings-soc-starfive-Add-StarFive-syscon-module.patch98
-rw-r--r--target/linux/starfive/patches-6.1/0038-riscv-dts-starfive-jh7110-Add-syscon-nodes.patch52
-rw-r--r--target/linux/starfive/patches-6.1/0039-riscv-dts-starfive-jh7110-Add-PLL-clock-node-and-mod.patch48
-rw-r--r--target/linux/starfive/patches-6.1/0040-dt-bindings-net-snps-dwmac-Add-dwmac-5.20-version.patch49
-rw-r--r--target/linux/starfive/patches-6.1/0041-net-stmmac-platform-Add-snps-dwmac-5.20-IP-compatibl.patch29
-rw-r--r--target/linux/starfive/patches-6.1/0042-dt-bindings-net-snps-dwmac-Add-ahb-reset-reset-name.patch46
-rw-r--r--target/linux/starfive/patches-6.1/0043-dt-bindings-net-Add-support-StarFive-dwmac.patch190
-rw-r--r--target/linux/starfive/patches-6.1/0044-net-stmmac-Add-glue-layer-for-StarFive-JH7110-SoC.patch187
-rw-r--r--target/linux/starfive/patches-6.1/0045-net-stmmac-dwmac-starfive-Add-phy-interface-settings.patch93
-rw-r--r--target/linux/starfive/patches-6.1/0046-riscv-dts-starfive-jh7110-Add-ethernet-device-nodes.patch101
-rw-r--r--target/linux/starfive/patches-6.1/0047-riscv-dts-starfive-visionfive-2-Add-configuration-of.patch128
-rw-r--r--target/linux/starfive/patches-6.1/0048-dt-bindings-net-Add-Motorcomm-yt8xxx-ethernet-phy.patch147
-rw-r--r--target/linux/starfive/patches-6.1/0049-dt-bindings-net-motorcomm-Add-pad-driver-strength-cf.patch34
-rw-r--r--target/linux/starfive/patches-6.1/0050-riscv-dts-starfive-visionfive-2-v1.3B-Set-the-driver.patch34
-rw-r--r--target/linux/starfive/patches-6.1/0051-dt-bindings-clock-Add-StarFive-JH7110-System-Top-Gro.patch193
-rw-r--r--target/linux/starfive/patches-6.1/0052-clk-starfive-Add-StarFive-JH7110-System-Top-Group-cl.patch218
-rw-r--r--target/linux/starfive/patches-6.1/0053-dt-bindings-clock-Add-StarFive-JH7110-Image-Signal-P.patch156
-rw-r--r--target/linux/starfive/patches-6.1/0054-clk-starfive-Add-StarFive-JH7110-Image-Signal-Proces.patch293
-rw-r--r--target/linux/starfive/patches-6.1/0055-dt-bindings-clock-Add-StarFive-JH7110-Video-Output-c.patch163
-rw-r--r--target/linux/starfive/patches-6.1/0056-clk-starfive-Add-StarFive-JH7110-Video-Output-clock-.patch284
-rw-r--r--target/linux/starfive/patches-6.1/0057-reset-starfive-jh7110-Add-StarFive-STG-ISP-VOUT-rese.patch61
-rw-r--r--target/linux/starfive/patches-6.1/0058-clk-starfive-update-jh7110-PLL-clock-driver.patch819
-rw-r--r--target/linux/starfive/patches-6.1/0059-dt-bindings-timer-Add-timer-for-StarFive-JH7110-SoC.patch113
-rw-r--r--target/linux/starfive/patches-6.1/0060-clocksource-Add-StarFive-timer-driver.patch540
-rw-r--r--target/linux/starfive/patches-6.1/0061-dt-bindings-net-motorcomm-Add-pad-driver-strength-cf.patch36
-rw-r--r--target/linux/starfive/patches-6.1/0062-dt-bindings-PWM-Add-StarFive-PWM-module.patch71
-rw-r--r--target/linux/starfive/patches-6.1/0063-pwm-starfive-Add-PWM-driver-support.patch294
-rw-r--r--target/linux/starfive/patches-6.1/0064-dt-bindings-crypto-Add-StarFive-crypto-module.patch90
-rw-r--r--target/linux/starfive/patches-6.1/0065-crypto-starfive-Add-crypto-engine-support.patch337
-rw-r--r--target/linux/starfive/patches-6.1/0066-crypto-starfive-Fix-driver-dependencies.patch29
-rw-r--r--target/linux/starfive/patches-6.1/0067-riscv-Kconfig-Add-select-ARM_AMBA-to-SOC_STARFIVE.patch23
-rw-r--r--target/linux/starfive/patches-6.1/0068-ASoC-dt-bindings-Add-TDM-controller-bindings-for-Sta.patch117
-rw-r--r--target/linux/starfive/patches-6.1/0069-ASoC-starfive-Add-JH7110-TDM-driver.patch744
-rw-r--r--target/linux/starfive/patches-6.1/0070-dt-bindings-power-Add-power-domain-header-for-JH7110.patch32
-rw-r--r--target/linux/starfive/patches-6.1/0071-soc-starfive-Replace-SOC_STARFIVE-with-ARCH_STARFIVE.patch28
-rw-r--r--target/linux/starfive/patches-6.1/0072-soc-starfive-Extract-JH7110-pmu-private-operations.patch175
-rw-r--r--target/linux/starfive/patches-6.1/0073-soc-starfive-Add-JH7110-AON-PMU-support.patch119
-rw-r--r--target/linux/starfive/patches-6.1/0074-dt-bindings-phy-Add-starfive-jh7110-dphy-rx.patch88
-rw-r--r--target/linux/starfive/patches-6.1/0075-phy-starfive-Add-mipi-dphy-rx-support.patch365
-rw-r--r--target/linux/starfive/patches-6.1/0076-media-dt-bindings-cadence-csi2rx-Convert-to-DT-schem.patch306
-rw-r--r--target/linux/starfive/patches-6.1/0077-media-dt-bindings-cadence-csi2rx-Add-resets-property.patch55
-rw-r--r--target/linux/starfive/patches-6.1/0078-media-cadence-Add-operation-on-reset.patch129
-rw-r--r--target/linux/starfive/patches-6.1/0079-media-cadence-Add-support-for-external-dphy.patch141
-rw-r--r--target/linux/starfive/patches-6.1/0080-media-cadence-Add-support-for-JH7110-SoC.patch23
-rw-r--r--target/linux/starfive/patches-6.1/0081-media-dt-bindings-Add-JH7110-Camera-Subsystem.patch197
-rw-r--r--target/linux/starfive/patches-6.1/0082-media-admin-guide-Add-starfive_camss.rst-for-Starfiv.patch106
-rw-r--r--target/linux/starfive/patches-6.1/0083-media-starfive-Add-basic-driver.patch630
-rw-r--r--target/linux/starfive/patches-6.1/0084-media-starfive-Add-video-driver.patch992
-rw-r--r--target/linux/starfive/patches-6.1/0085-media-starfive-Add-ISP-driver.patch1667
-rw-r--r--target/linux/starfive/patches-6.1/0086-media-starfive-Add-VIN-driver.patch1694
-rw-r--r--target/linux/starfive/patches-6.1/0087-dt-bindings-phy-Add-StarFive-JH7110-USB-PHY.patch68
-rw-r--r--target/linux/starfive/patches-6.1/0088-dt-bindings-phy-Add-StarFive-JH7110-PCIe-PHY.patch77
-rw-r--r--target/linux/starfive/patches-6.1/0089-phy-starfive-Add-JH7110-USB-2.0-PHY-driver.patch192
-rw-r--r--target/linux/starfive/patches-6.1/0090-phy-starfive-Add-JH7110-PCIE-2.0-PHY-driver.patch250
-rw-r--r--target/linux/starfive/patches-6.1/0091-dt-bindings-usb-Add-StarFive-JH7110-USB-controller.patch135
-rw-r--r--target/linux/starfive/patches-6.1/0092-dt-bindings-qspi-cdns-qspi-nor-constrain-minItems-ma.patch78
-rw-r--r--target/linux/starfive/patches-6.1/0093-usb-cdns3-Add-StarFive-JH7110-USB-driver.patch298
-rw-r--r--target/linux/starfive/patches-6.1/0094-dt-binding-pci-add-JH7110-PCIe-dt-binding-documents.patch181
-rw-r--r--target/linux/starfive/patches-6.1/0095-spi-cadence-quadspi-Add-support-for-StarFive-JH7110-.patch79
-rw-r--r--target/linux/starfive/patches-6.1/0096-pcie-starfive-add-StarFive-JH7110-PCIe-driver.patch1004
-rw-r--r--target/linux/starfive/patches-6.1/0097-cpufreq-dt-platdev-Add-JH7110-SOC-to-the-allowlist.patch24
-rw-r--r--target/linux/starfive/patches-6.1/0098-riscv-dts-starfive-Add-full-support-for-JH7110-and-V.patch1034
-rw-r--r--target/linux/starfive/patches-6.1/0099-update-jh7110_defconfig-for-test.patch48
-rw-r--r--target/linux/starfive/patches-6.1/0100-Add-readme.patch75
-rw-r--r--target/linux/starfive/patches-6.1/0101-dt-bindings-rng-Add-StarFive-TRNG-module.patch76
-rw-r--r--target/linux/starfive/patches-6.1/0102-hwrng-starfive-Add-TRNG-driver-for-StarFive-SoC.patch457
-rw-r--r--target/linux/starfive/patches-6.1/0103-hwrng-starfive-Enable-compile-testing.patch28
-rw-r--r--target/linux/starfive/patches-6.1/0104-dt-bindings-watchdog-Add-watchdog-for-StarFive-JH710.patch91
-rw-r--r--target/linux/starfive/patches-6.1/0105-drivers-watchdog-Add-StarFive-Watchdog-driver.patch675
-rw-r--r--target/linux/starfive/patches-6.1/0106-riscv-dts-starfive-jh7100-Add-watchdog-node.patch31
-rw-r--r--target/linux/starfive/patches-6.1/0107-dt-bindings-mmc-Add-StarFive-MMC-module.patch95
-rw-r--r--target/linux/starfive/patches-6.1/0108-mmc-starfive-Add-sdio-emmc-driver-support.patch250
-rw-r--r--target/linux/starfive/patches-6.1/0109-dt-bindings-hwmon-Add-starfive-jh71x0-temp.patch89
-rw-r--r--target/linux/starfive/patches-6.1/0110-hwmon-sfctemp-Add-StarFive-JH71x0-temperature-sensor.patch451
-rw-r--r--target/linux/starfive/patches-6.1/0111-dt-bindings-dma-snps-dw-axi-dmac-constrain-the-items.patch62
-rw-r--r--target/linux/starfive/patches-6.1/0112-dmaengine-dw-axi-dmac-Add-support-for-StarFive-JH711.patch122
-rw-r--r--target/linux/starfive/patches-6.1/0113-dmaengine-dw-axi-dmac-Increase-polling-time-to-DMA-t.patch29
-rw-r--r--target/linux/starfive/patches-6.1/0114-RISC-V-Change-suspend_save_csrs-and-suspend_restore_.patch50
-rw-r--r--target/linux/starfive/patches-6.1/0115-RISC-V-Factor-out-common-code-of-__cpu_resume_enter.patch136
-rw-r--r--target/linux/starfive/patches-6.1/0116-RISC-V-Add-arch-functions-to-support-hibernation-sus.patch673
-rw-r--r--target/linux/starfive/patches-6.1/0119-riscv-dts-visionfive2-add-EEPROM-node.patch25
-rw-r--r--target/linux/starfive/patches-6.1/0120-riscv-dts-visionfive2-add-mmc-aliases.patch21
-rw-r--r--target/linux/starfive/patches-6.1/0121-drivers-include-cpufreq-Kconfig-for-riscv.patch21
-rw-r--r--target/linux/starfive/patches-6.1/0126-clk-starfive-jh7110-sys-Fix-lower-rate-of-CPUfreq-by.patch92
-rw-r--r--target/linux/starfive/patches-6.1/1000-net-stmmac-dwmac-starfive-Add-JH7100-support.patch63
-rw-r--r--target/linux/starfive/patches-6.1/1001-dt-bindings-mfd-syscon-Add-StarFive-JH7100-sysmain-c.patch23
-rw-r--r--target/linux/starfive/patches-6.1/1002-serial-8250_dw-Add-starfive-jh7100-hsuart-compatible.patch25
-rw-r--r--target/linux/starfive/patches-6.1/1003-riscv-dts-starfive-Group-tuples-in-interrupt-propert.patch40
-rw-r--r--target/linux/starfive/patches-6.1/1004-RISC-V-Add-StarFive-JH7100-audio-clock-node.patch32
-rw-r--r--target/linux/starfive/patches-6.1/1005-RISC-V-Mark-StarFive-JH7100-as-having-non-coherent-D.patch21
-rw-r--r--target/linux/starfive/patches-6.1/1006-drivers-tty-serial-8250-update-driver-for-JH7100.patch28
-rw-r--r--target/linux/starfive/patches-6.1/1007-dmaengine-dw-axi-dmac-Handle-xfer-start-while-non-id.patch55
-rw-r--r--target/linux/starfive/patches-6.1/1008-dmaengine-dw-axi-dmac-Add-StarFive-JH7100-support.patch64
-rw-r--r--target/linux/starfive/patches-6.1/1009-pinctrl-starfive-Reset-pinmux-settings.patch127
-rw-r--r--target/linux/starfive/patches-6.1/1010-clk-starfive-Add-flags-argument-to-JH71X0__MUX-macro.patch302
-rw-r--r--target/linux/starfive/patches-6.1/1011-clk-starfive-jh7100-Add-CLK_SET_RATE_PARENT-to-gmac_.patch25
-rw-r--r--target/linux/starfive/patches-6.1/1012-clk-starfive-jh7100-Keep-more-clocks-alive.patch94
-rw-r--r--target/linux/starfive/patches-6.1/1013-net-stmmac-use-GFP_DMA32.patch30
-rw-r--r--target/linux/starfive/patches-6.1/1014-hwrng-Add-StarFive-JH7100-Random-Number-Generator-dr.patch477
-rw-r--r--target/linux/starfive/patches-6.1/1015-pwm-sifive-ptc-Add-SiFive-PWM-PTC-driver.patch309
-rw-r--r--target/linux/starfive/patches-6.1/1016-riscv-Implement-non-coherent-DMA-support-via-SiFive-.patch105
-rw-r--r--target/linux/starfive/patches-6.1/1017-dt-bindings-riscv-sifive-ccache-Add-uncached-offset-.patch30
-rw-r--r--target/linux/starfive/patches-6.1/1018-soc-sifive-ccache-Add-StarFive-JH71x0-support.patch77
-rw-r--r--target/linux/starfive/patches-6.1/1019-soc-sifive-ccache-Add-non-coherent-DMA-handling.patch159
-rw-r--r--target/linux/starfive/patches-6.1/1020-dt-bindings-reset-Add-StarFive-JH7100-audio-reset-de.patch48
-rw-r--r--target/linux/starfive/patches-6.1/1021-dt-bindings-reset-Add-starfive-jh7100-audrst-binding.patch56
-rw-r--r--target/linux/starfive/patches-6.1/1022-reset-starfive-Add-JH7100-audio-reset-driver.patch144
-rw-r--r--target/linux/starfive/patches-6.1/1023-RISC-V-Add-StarFive-JH7100-audio-reset-node.patch28
-rw-r--r--target/linux/starfive/patches-6.1/1024-riscv-dts-Add-full-JH7100-Starlight-and-VisionFive-s.patch1265
-rw-r--r--target/linux/starfive/patches-6.1/1025-riscv-dts-visionfive1-enable-QSPI.patch20
-rw-r--r--target/linux/starfive/patches-6.6/0001-clk-starfive-jh7110-sys-Fix-lower-rate-of-CPUfreq-by.patch76
-rw-r--r--target/linux/starfive/patches-6.6/0002-dt-bindings-timer-Add-timer-for-StarFive-JH7110-SoC.patch114
-rw-r--r--target/linux/starfive/patches-6.6/0003-clocksource-Add-JH7110-timer-driver.patch428
-rw-r--r--target/linux/starfive/patches-6.6/0004-dt-bindings-mmc-starfive-Remove-properties-from-requ.patch34
-rw-r--r--target/linux/starfive/patches-6.6/0005-mmc-starfive-Change-tuning-implementation.patch199
-rw-r--r--target/linux/starfive/patches-6.6/0006-dt-bindings-pwm-Add-bindings-for-OpenCores-PWM-Contr.patch79
-rw-r--r--target/linux/starfive/patches-6.6/0007-pwm-opencores-Add-PWM-driver-support.patch285
-rw-r--r--target/linux/starfive/patches-6.6/0008-crypto-starfive-remove-unnecessary-alignmask-for-aha.patch117
-rw-r--r--target/linux/starfive/patches-6.6/0009-crypto-starfive-Update-driver-dependencies.patch25
-rw-r--r--target/linux/starfive/patches-6.6/0010-crypto-starfive-RSA-poll-csr-for-done-status.patch200
-rw-r--r--target/linux/starfive/patches-6.6/0011-crypto-starfive-Pad-adata-with-zeroes.patch46
-rw-r--r--target/linux/starfive/patches-6.6/0012-crypto-starfive-Remove-cfb-and-ofb.patch125
-rw-r--r--target/linux/starfive/patches-6.6/0013-crypto-starfive-Remove-unneeded-NULL-checks.patch33
-rw-r--r--target/linux/starfive/patches-6.6/0014-dt-bindings-PCI-Add-PLDA-XpressRICH-PCIe-host-common.patch183
-rw-r--r--target/linux/starfive/patches-6.6/0015-PCI-microchip-Move-pcie-microchip-host.c-to-plda-dir.patch2523
-rw-r--r--target/linux/starfive/patches-6.6/0016-PCI-microchip-Move-PLDA-IP-register-macros-to-pcie-p.patch259
-rw-r--r--target/linux/starfive/patches-6.6/0017-PCI-microchip-Add-bridge_addr-field-to-struct-mc_pci.patch107
-rw-r--r--target/linux/starfive/patches-6.6/0018-PCI-microchip-Rename-two-PCIe-data-structures.patch347
-rw-r--r--target/linux/starfive/patches-6.6/0019-PCI-microchip-Move-PCIe-host-data-structures-to-plda.patch87
-rw-r--r--target/linux/starfive/patches-6.6/0020-PCI-microchip-Rename-two-setup-functions.patch76
-rw-r--r--target/linux/starfive/patches-6.6/0021-PCI-microchip-Change-the-argument-of-plda_pcie_setup.patch49
-rw-r--r--target/linux/starfive/patches-6.6/0022-PCI-microchip-Move-setup-functions-to-pcie-plda-host.patch200
-rw-r--r--target/linux/starfive/patches-6.6/0023-PCI-microchip-Rename-interrupt-related-functions.patch336
-rw-r--r--target/linux/starfive/patches-6.6/0024-PCI-microchip-Add-num_events-field-to-struct-plda_pc.patch65
-rw-r--r--target/linux/starfive/patches-6.6/0025-PCI-microchip-Add-request_event_irq-callback-functio.patch114
-rw-r--r--target/linux/starfive/patches-6.6/0026-PCI-microchip-Add-INTx-and-MSI-event-num-to-struct-p.patch56
-rw-r--r--target/linux/starfive/patches-6.6/0027-PCI-microchip-Add-get_events-callback-and-add-PLDA-g.patch167
-rw-r--r--target/linux/starfive/patches-6.6/0028-PCI-microchip-Add-event-irqchip-field-to-host-port-a.patch144
-rw-r--r--target/linux/starfive/patches-6.6/0029-PCI-microchip-Move-IRQ-functions-to-pcie-plda-host.c.patch1028
-rw-r--r--target/linux/starfive/patches-6.6/0030-pci-plda-Add-event-bitmap-field-to-struct-plda_pcie_.patch67
-rw-r--r--target/linux/starfive/patches-6.6/0031-PCI-plda-Add-host-init-deinit-and-map-bus-functions.patch256
-rw-r--r--target/linux/starfive/patches-6.6/0032-dt-bindings-PCI-Add-StarFive-JH7110-PCIe-controller.patch140
-rw-r--r--target/linux/starfive/patches-6.6/0033-PCI-Add-PCIE_RESET_CONFIG_DEVICE_WAIT_MS-waiting-tim.patch55
-rw-r--r--target/linux/starfive/patches-6.6/0034-PCI-starfive-Add-JH7110-PCIe-controller.patch623
-rw-r--r--target/linux/starfive/patches-6.6/0035-ASoC-dt-bindings-Add-StarFive-JH7110-PWM-DAC-control.patch97
-rw-r--r--target/linux/starfive/patches-6.6/0036-ASoC-starfive-Add-JH7110-PWM-DAC-driver.patch574
-rw-r--r--target/linux/starfive/patches-6.6/0037-ASoC-Update-jh7110-PWM-DAC-for-ops-move.patch32
-rw-r--r--target/linux/starfive/patches-6.6/0038-ASoC-starfive-jh7110-pwmdac-Convert-to-platform-remo.patch52
-rw-r--r--target/linux/starfive/patches-6.6/0039-dt-bindings-power-Add-power-domain-header-for-JH7110.patch35
-rw-r--r--target/linux/starfive/patches-6.6/0040-pmdomain-starfive-Replace-SOC_STARFIVE-with-ARCH_STA.patch31
-rw-r--r--target/linux/starfive/patches-6.6/0041-pmdomain-starfive-Extract-JH7110-pmu-private-operati.patch179
-rw-r--r--target/linux/starfive/patches-6.6/0042-pmdomain-starfive-Add-JH7110-AON-PMU-support.patch122
-rw-r--r--target/linux/starfive/patches-6.6/0043-pmdomain-Prepare-to-move-Kconfig-files-into-the-pmdo.patch36
-rw-r--r--target/linux/starfive/patches-6.6/0044-pmdomain-starfive-Move-Kconfig-file-to-the-pmdomain-.patch69
-rw-r--r--target/linux/starfive/patches-6.6/0045-dt-bindings-power-Update-prefixes-for-AON-power-doma.patch31
-rw-r--r--target/linux/starfive/patches-6.6/0046-pmdomain-starfive-Update-prefixes-for-AON-power-doma.patch32
-rw-r--r--target/linux/starfive/patches-6.6/0047-riscv-dts-starfive-pinfunc-Fix-the-pins-name-of-I2ST.patch30
-rw-r--r--target/linux/starfive/patches-6.6/0048-riscv-dts-starfive-Add-full-support-except-VIN-and-V.patch549
-rw-r--r--target/linux/starfive/patches-6.6/0049-MAINTAINERS-Update-all-StarFive-entries.patch147
-rw-r--r--target/linux/starfive/patches-6.6/0050-mmc-starfive-Change-the-voltage-to-adapt-to-JH7110-E.patch64
-rw-r--r--target/linux/starfive/patches-6.6/0051-spi-spl022-Get-and-deassert-reset-in-probe.patch60
-rw-r--r--target/linux/starfive/patches-6.6/0052-ASoC-dwc-i2s-Fix-getting-platform-data-error-for-Sta.patch30
-rw-r--r--target/linux/starfive/patches-6.6/0053-ASoC-dwc-i2s-Add-RX-master-support-for-StarFive-JH71.patch67
-rw-r--r--target/linux/starfive/patches-6.6/0054-pinctrl-starfive-jh7110-Unset-.strict-in-pinmux_ops.patch24
-rw-r--r--target/linux/starfive/patches-6.6/0055-mm-pgtable-generic.c-Export-symbol-__pte_offset_map.patch22
-rw-r--r--target/linux/starfive/patches-6.6/0056-riscv-dts-starfive-Add-JH7110-EVB-device-tree.patch2623
-rw-r--r--target/linux/starfive/patches-6.6/0057-riscv-dts-starfive-Add-JH7110-EVB-expanded-device-tr.patch728
-rw-r--r--target/linux/starfive/patches-6.6/0058-riscv-dts-starfive-Add-evb-overlay-dtso-subdir.patch485
-rw-r--r--target/linux/starfive/patches-6.6/0059-riscv-configs-Add-starfive_jh7110_defconfig.patch385
-rw-r--r--target/linux/starfive/patches-6.6/0060-of-configfs-Add-configfs-function.patch318
-rw-r--r--target/linux/starfive/patches-6.6/0061-usr-Add-gen_initramfs_list.sh.patch344
-rw-r--r--target/linux/starfive/patches-6.6/0062-i2c-designware-Delete-SMBus-functionalities.patch33
-rw-r--r--target/linux/starfive/patches-6.6/0063-drivers-mtd-gigadevice-add-gd25lq256d-32M-flash-supp.patch26
-rw-r--r--target/linux/starfive/patches-6.6/0064-driver-mailbox-Add-mailbox-driver.patch808
-rw-r--r--target/linux/starfive/patches-6.6/0065-driver-rtc-Add-StarFive-JH7110-rtc-driver.patch789
-rw-r--r--target/linux/starfive/patches-6.6/0066-uart-8250-Add-dw-auto-flow-ctrl-support.patch96
-rw-r--r--target/linux/starfive/patches-6.6/0067-driver-uart-fix-up-uart-communicate-fail.patch29
-rw-r--r--target/linux/starfive/patches-6.6/0068-uart-8250-add-reset-operation-in-runtime-PM.patch32
-rw-r--r--target/linux/starfive/patches-6.6/0069-dt-bindings-CAN-Add-StarFive-CAN-module.patch113
-rw-r--r--target/linux/starfive/patches-6.6/0070-CAN-starfive-Add-CAN-engine-support.patch1317
-rw-r--r--target/linux/starfive/patches-6.6/0071-regulator-starfive-jh7110-Add-regulator-support-for-.patch204
-rw-r--r--target/linux/starfive/patches-6.6/0072-drivers-nvme-Add-precheck-and-delay-for-CQE-pending-.patch40
-rw-r--r--target/linux/starfive/patches-6.6/0073-RISC-V-Create-unique-identification-for-SoC-PMU.patch93
-rw-r--r--target/linux/starfive/patches-6.6/0074-RISC-V-Support-CPUID-for-risc-v-in-perf.patch55
-rw-r--r--target/linux/starfive/patches-6.6/0075-RISC-V-Added-generic-pmu-events-mapfile.patch42
-rw-r--r--target/linux/starfive/patches-6.6/0076-perf-sbi-disable-cpu-hotplug-callback.patch30
-rw-r--r--target/linux/starfive/patches-6.6/0077-dmaengine-dw-axi-dmac-Drop-unused-print-message.patch24
-rw-r--r--target/linux/starfive/patches-6.6/0079-ASoC-codecs-Add-AC108-Codec-driver.patch4748
-rw-r--r--target/linux/starfive/patches-6.6/0080-ASoC-starfive-Add-SPDIF-and-PCM-driver.patch1169
-rw-r--r--target/linux/starfive/patches-6.6/0081-ASoC-starfive-Add-JH7110-PDM-driver.patch537
-rw-r--r--target/linux/starfive/patches-6.6/0082-dt-binding-input-Add-tink_ft5406.patch55
-rw-r--r--target/linux/starfive/patches-6.6/0083-input-touchscreen-Add-tinker_ft5406-driver-support.patch444
-rw-r--r--target/linux/starfive/patches-6.6/0084-dt-binding-media-Add-JH7110-Camera-Subsystem.patch246
-rw-r--r--target/linux/starfive/patches-6.6/0085-media-starfive-Add-vin-driver-support.patch24014
-rw-r--r--target/linux/starfive/patches-6.6/0086-dt-bindings-media-i2c-Add-IMX708-CMOS-sensor-binding.patch135
-rw-r--r--target/linux/starfive/patches-6.6/0087-media-i2c-Add-imx708-support.patch1971
-rw-r--r--target/linux/starfive/patches-6.6/0088-media-i2c-imx708-Delete-gain.patch69
-rw-r--r--target/linux/starfive/patches-6.6/0089-dt-bindings-display-Add-yamls-for-JH7110-display-sys.patch270
-rw-r--r--target/linux/starfive/patches-6.6/0090-soc-starfive-jh71xx_pmu-Add-EVENT_TURN_OFF-register-.patch82
-rw-r--r--target/linux/starfive/patches-6.6/0091-workqueue-Enable-flush_scheduled_work.patch22
-rw-r--r--target/linux/starfive/patches-6.6/0092-riscv-Optimize-memcpy-with-aligned-version.patch506
-rw-r--r--target/linux/starfive/patches-6.6/0093-riscv-purgatory-Change-memcpy-to-the-aligned-version.patch37
-rw-r--r--target/linux/starfive/patches-6.6/0094-Add-16-ISP-controls-remove-the-frame-SYNC-event-to-v.patch856
-rw-r--r--target/linux/starfive/patches-6.6/0095-Expand-2-bytes-after-the-SC-buffer-for-the-AE-AWB-fl.patch249
-rw-r--r--target/linux/starfive/patches-6.6/0096-Add-ISP-control-for-video2-and-video3.patch117
-rw-r--r--target/linux/starfive/patches-6.6/0097-media-starfive-Update-ISP-initialzation.patch226
-rw-r--r--target/linux/starfive/patches-6.6/0098-crypto-jh7110-Comment-RSA-algo-register.patch36
-rw-r--r--target/linux/starfive/patches-6.6/0099-riscv-dts-starfive-jh7110-evb-Add-qspi-norflash-part.patch26
-rw-r--r--target/linux/starfive/patches-6.6/0100-driver-regulator-pmic-driver-support-kernel-6.6.patch22
-rw-r--r--target/linux/starfive/patches-6.6/0101-spi-pl022-starfive-Add-platform-bus-register-to-adap.patch232
-rw-r--r--target/linux/starfive/patches-6.6/0102-spi-pl022-starfive-Avoid-power-device-error-when-CON.patch92
-rw-r--r--target/linux/starfive/patches-6.6/0103-spi-pl022-starfive-fix-the-problem-of-spi-overlay-re.patch403
-rw-r--r--target/linux/starfive/patches-6.6/0104-spi-pl022-starfive-Enable-spi-to-be-compiled-into-mo.patch38
-rw-r--r--target/linux/starfive/patches-6.6/0105-riscv-configs-add-visionfive2-defconfig-to-kernel-6..patch444
-rw-r--r--target/linux/starfive/patches-6.6/0106-riscv-dts-starfive-update-dts-to-kernel-6.6.patch759
-rw-r--r--target/linux/starfive/patches-6.6/0107-riscv-dts-starfive-evb-overlay-Support-SPI-overlay.patch71
-rw-r--r--target/linux/starfive/patches-6.6/0108-riscv-configs-visionfive2-Add-standard-partition-for.patch23
-rw-r--r--target/linux/starfive/patches-6.6/0109-usb-xhci-To-improve-performance-usb-using-lowmem-for.patch297
-rw-r--r--target/linux/starfive/patches-6.6/0110-usb-xhci-using-dma_alloc_noncoherent-to-alloc-low-me.patch106
-rw-r--r--target/linux/starfive/patches-6.6/0111-riscv-dts-starfive-Add-vf2-overlay-dtso-subdir.patch139
-rw-r--r--target/linux/starfive/patches-6.6/0112-riscv-dts-starfive-visionfive-2-Add-aliases-for-i2c-.patch34
-rw-r--r--target/linux/starfive/patches-6.6/0113-driver-bluetooth-add-aic8800-driver-support.patch6063
-rw-r--r--target/linux/starfive/patches-6.6/0114-riscv-dts-starfive-visionfive-2-Sync-the-sound-card-.patch67
-rw-r--r--target/linux/starfive/patches-6.6/0115-clk-starfive-jh7110-Change-uart3-uart5-clk-register-.patch53
-rw-r--r--target/linux/starfive/patches-6.6/0116-riscv-dts-starfive-visionfive-2-Quote-corresponding-.patch32
-rw-r--r--target/linux/starfive/patches-6.6/1000-serial-8250_dw-Add-starfive-jh7100-hsuart-compatible.patch25
-rw-r--r--target/linux/starfive/patches-6.6/1001-RISC-V-Add-StarFive-JH7100-audio-clock-node.patch32
-rw-r--r--target/linux/starfive/patches-6.6/1002-drivers-tty-serial-8250-update-driver-for-JH7100.patch28
-rw-r--r--target/linux/starfive/patches-6.6/1003-dmaengine-dw-axi-dmac-Handle-xfer-start-while-non-id.patch55
-rw-r--r--target/linux/starfive/patches-6.6/1004-dmaengine-dw-axi-dmac-Add-StarFive-JH7100-support.patch64
-rw-r--r--target/linux/starfive/patches-6.6/1005-pinctrl-starfive-Reset-pinmux-settings.patch127
-rw-r--r--target/linux/starfive/patches-6.6/1006-clk-starfive-Add-flags-argument-to-JH71X0__MUX-macro.patch302
-rw-r--r--target/linux/starfive/patches-6.6/1007-clk-starfive-jh7100-Add-CLK_SET_RATE_PARENT-to-gmac_.patch25
-rw-r--r--target/linux/starfive/patches-6.6/1008-clk-starfive-jh7100-Keep-more-clocks-alive.patch94
-rw-r--r--target/linux/starfive/patches-6.6/1009-net-stmmac-use-GFP_DMA32.patch30
-rw-r--r--target/linux/starfive/patches-6.6/1010-hwrng-Add-StarFive-JH7100-Random-Number-Generator-dr.patch477
-rw-r--r--target/linux/starfive/patches-6.6/1011-pwm-sifive-ptc-Add-SiFive-PWM-PTC-driver.patch309
-rw-r--r--target/linux/starfive/patches-6.6/1012-dt-bindings-reset-Add-StarFive-JH7100-audio-reset-de.patch48
-rw-r--r--target/linux/starfive/patches-6.6/1013-dt-bindings-reset-Add-starfive-jh7100-audrst-binding.patch56
-rw-r--r--target/linux/starfive/patches-6.6/1014-reset-starfive-Add-JH7100-audio-reset-driver.patch144
-rw-r--r--target/linux/starfive/patches-6.6/1015-RISC-V-Add-StarFive-JH7100-audio-reset-node.patch28
-rw-r--r--target/linux/starfive/patches-6.6/1016-soc-sifive-ccache-Add-StarFive-JH7100-support.patch160
-rw-r--r--target/linux/starfive/patches-6.6/1017-riscv-errata-Add-StarFive-JH7100-errata.patch44
-rw-r--r--target/linux/starfive/patches-6.6/1018-riscv-dts-starfive-Mark-the-JH7100-as-having-non-coh.patch26
-rw-r--r--target/linux/starfive/patches-6.6/1019-riscv-dts-starfive-Add-JH7100-cache-controller.patch50
-rw-r--r--target/linux/starfive/patches-6.6/1020-riscv-dts-starfive-Add-pool-for-coherent-DMA-memory-.patch61
-rw-r--r--target/linux/starfive/patches-6.6/1021-riscv-dts-starfive-Add-JH7100-MMC-nodes.patch49
-rw-r--r--target/linux/starfive/patches-6.6/1022-riscv-dts-starfive-Enable-SD-card-on-JH7100-boards.patch85
-rw-r--r--target/linux/starfive/patches-6.6/1023-riscv-errata-Make-ERRATA_STARFIVE_JH7100-depend-on-D.patch33
-rw-r--r--target/linux/starfive/patches-6.6/1024-riscv-dts-Add-full-JH7100-Starlight-and-VisionFive-s.patch1138
-rw-r--r--target/linux/sunxi/config-6.62
-rw-r--r--target/linux/sunxi/patches-6.6/017-v6.10-firmware-smccc-Export-revision-soc_id-function.patch32
-rw-r--r--target/linux/sunxi/patches-6.6/018-v6.10-cpufreq-dt-platdev-Blocklist-Allwinner-H616-618-SoCs.patch29
-rw-r--r--target/linux/sunxi/patches-6.6/019-v6.10-cpufreq-sun50i-Refactor-speed-bin-decoding.patch149
-rw-r--r--target/linux/sunxi/patches-6.6/020-v6.10-cpufreq-sun50i-Add-support-for-opp_supported_hw.patch132
-rw-r--r--target/linux/sunxi/patches-6.6/021-v6.10-cpufreq-sun50i-Add-H616-support.patch122
-rw-r--r--target/linux/sunxi/patches-6.6/022-v6.10-arm64-dts-allwinner-h616-Add-CPU-OPPs-table.patch188
-rw-r--r--target/linux/sunxi/patches-6.6/023-v6.10-arm64-dts-allwinner-h616-enable-DVFS-for-all-boards.patch86
-rw-r--r--target/linux/sunxi/patches-6.6/024-v6.10-cpufreq-sun50i-Fix-build-warning-around-snprint.patch51
-rw-r--r--target/linux/sunxi/patches-6.6/025-v6.10-cpufreq-sun50i-fix-error-returns-in-dt_has_supported_hw.patch34
-rw-r--r--target/linux/sunxi/patches-6.6/410-sunxi-add-bananapi-p2-zero.patch2
-rw-r--r--target/linux/sunxi/patches-6.6/451-sunxi-add-csi-video-support-for-nanopi-neo-air.patch107
-rw-r--r--target/linux/x86/64/config-6.65
-rw-r--r--target/linux/x86/base-files/etc/board.d/02_network3
-rw-r--r--target/linux/x86/generic/config-6.65
-rw-r--r--target/linux/x86/image/Makefile2
-rw-r--r--target/linux/x86/legacy/config-6.65
-rw-r--r--target/linux/zynq/Makefile2
-rw-r--r--target/linux/zynq/config-6.1566
-rw-r--r--target/linux/zynq/config-6.6570
-rw-r--r--target/linux/zynq/image/Makefile1
1374 files changed, 145682 insertions, 82745 deletions
diff --git a/target/imagebuilder/Makefile b/target/imagebuilder/Makefile
index 7fd2aa0920..7127df5ebc 100644
--- a/target/imagebuilder/Makefile
+++ b/target/imagebuilder/Makefile
@@ -112,6 +112,9 @@ endif
-cp $(LINUX_DIR)/.config $(IB_LDIR)/
rm -f $(IB_KDIR)/root.*
rm -f $(IB_KDIR)/vmlinux.debug
+ # remove any file for initramfs and Per Device Rootfs initramfs files
+ rm -f $(IB_KDIR)/vmlinux-initramfs*
+ rm -f $(IB_KDIR)/Image-initramfs*
if [ -x $(LINUX_DIR)/scripts/dtc/dtc ]; then \
$(INSTALL_DIR) $(IB_LDIR)/scripts/dtc; \
$(INSTALL_BIN) $(LINUX_DIR)/scripts/dtc/dtc $(IB_LDIR)/scripts/dtc/dtc; \
diff --git a/target/linux/apm821xx/dts/netgear-wndap6x0.dtsi b/target/linux/apm821xx/dts/netgear-wndap6x0.dtsi
index 9d98776626..7c9faa883f 100644
--- a/target/linux/apm821xx/dts/netgear-wndap6x0.dtsi
+++ b/target/linux/apm821xx/dts/netgear-wndap6x0.dtsi
@@ -224,7 +224,7 @@
rtl8367b {
compatible = "realtek,rtl8367b";
- realtek,extif0 = <1 2 1 1 1 1 1 1 2>;
+ realtek,extif = <5 1 2 1 1 1 1 1 1 2>;
mii-bus = <&mdio0>;
};
};
diff --git a/target/linux/archs38/Makefile b/target/linux/archs38/Makefile
index e352c58957..0b3feb9889 100644
--- a/target/linux/archs38/Makefile
+++ b/target/linux/archs38/Makefile
@@ -11,7 +11,7 @@ BOARDNAME:=Synopsys DesignWare ARC HS38
FEATURES:=source-only
SUBTARGETS:=generic
-KERNEL_PATCHVER:=6.1
+KERNEL_PATCHVER:=6.6
DEVICE_TYPE:=basic
diff --git a/target/linux/archs38/config-6.1 b/target/linux/archs38/config-6.1
deleted file mode 100644
index 9fe6ba2932..0000000000
--- a/target/linux/archs38/config-6.1
+++ /dev/null
@@ -1,268 +0,0 @@
-# CONFIG_16KSTACKS is not set
-CONFIG_ARC=y
-CONFIG_ARCH_32BIT_OFF_T=y
-CONFIG_ARC_BUILTIN_DTB_NAME=""
-CONFIG_ARC_CACHE=y
-CONFIG_ARC_CACHE_LINE_SHIFT=6
-CONFIG_ARC_CACHE_PAGES=y
-CONFIG_ARC_CPU_HS=y
-CONFIG_ARC_CURR_IN_REG=y
-CONFIG_ARC_DBG=y
-# CONFIG_ARC_DSP_AGU_USERSPACE is not set
-# CONFIG_ARC_DSP_KERNEL is not set
-CONFIG_ARC_DSP_NONE=y
-# CONFIG_ARC_DSP_USERSPACE is not set
-CONFIG_ARC_DW2_UNWIND=y
-CONFIG_ARC_FPU_SAVE_RESTORE=y
-CONFIG_ARC_HAS_ACCL_REGS=y
-CONFIG_ARC_HAS_DCACHE=y
-# CONFIG_ARC_HAS_DCCM is not set
-CONFIG_ARC_HAS_DIV_REM=y
-CONFIG_ARC_HAS_ICACHE=y
-# CONFIG_ARC_HAS_ICCM is not set
-CONFIG_ARC_HAS_LL64=y
-CONFIG_ARC_HAS_LLSC=y
-# CONFIG_ARC_HAS_PAE40 is not set
-CONFIG_ARC_HAS_SWAPE=y
-CONFIG_ARC_IRQ_NO_AUTOSAVE=y
-CONFIG_ARC_KVADDR_SIZE=256
-# CONFIG_ARC_LPB_DISABLE is not set
-CONFIG_ARC_MCIP=y
-# CONFIG_ARC_METAWARE_HLINK is not set
-CONFIG_ARC_MMU_V4=y
-# CONFIG_ARC_PAGE_SIZE_16K is not set
-# CONFIG_ARC_PAGE_SIZE_4K is not set
-CONFIG_ARC_PAGE_SIZE_8K=y
-CONFIG_ARC_PLAT_AXS10X=y
-# CONFIG_ARC_PLAT_TB10X is not set
-# CONFIG_ARC_SMP_HALT_ON_RESET is not set
-CONFIG_ARC_SOC_HSDK=y
-CONFIG_ARC_TIMERS=y
-CONFIG_ARC_TIMERS_64BIT=y
-CONFIG_ARC_TUNE_MCPU=""
-CONFIG_ARC_USE_UNALIGNED_MEM_ACCESS=y
-CONFIG_AXS103=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_BLK_DEV_SD=y
-CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
-CONFIG_CC_NO_ARRAY_BOUNDS=y
-CONFIG_CLK_HSDK=y
-CONFIG_CLONE_BACKWARDS=y
-CONFIG_COMMON_CLK=y
-CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
-CONFIG_COMPAT_32BIT_TIME=y
-CONFIG_CONTEXT_TRACKING=y
-CONFIG_CONTEXT_TRACKING_IDLE=y
-CONFIG_CPU_RMAP=y
-CONFIG_CRC16=y
-CONFIG_CRYPTO_CRC32C=y
-CONFIG_CRYPTO_DRBG=y
-CONFIG_CRYPTO_DRBG_HMAC=y
-CONFIG_CRYPTO_DRBG_MENU=y
-CONFIG_CRYPTO_ECHAINIV=y
-CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_JITTERENTROPY=y
-CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
-CONFIG_CRYPTO_LIB_POLY1305_RSIZE=1
-CONFIG_CRYPTO_LIB_SHA1=y
-CONFIG_CRYPTO_LIB_SHA256=y
-CONFIG_CRYPTO_LIB_UTILS=y
-CONFIG_CRYPTO_RNG=y
-CONFIG_CRYPTO_RNG2=y
-CONFIG_CRYPTO_RNG_DEFAULT=y
-CONFIG_CRYPTO_SHA256=y
-CONFIG_CRYPTO_SHA512=y
-CONFIG_DEBUG_INFO=y
-CONFIG_DMADEVICES=y
-CONFIG_DMA_DIRECT_REMAP=y
-CONFIG_DMA_ENGINE=y
-CONFIG_DMA_OF=y
-CONFIG_DMA_VIRTUAL_CHANNELS=y
-CONFIG_DTC=y
-CONFIG_DWMAC_ANARION=y
-CONFIG_DWMAC_GENERIC=y
-CONFIG_DW_APB_ICTL=y
-CONFIG_DW_AXI_DMAC=y
-CONFIG_EXCLUSIVE_SYSTEM_RAM=y
-CONFIG_EXT4_FS=y
-CONFIG_FAT_FS=y
-CONFIG_FB=y
-CONFIG_FB_CMDLINE=y
-CONFIG_FIXED_PHY=y
-CONFIG_FS_IOMAP=y
-CONFIG_FS_MBCACHE=y
-CONFIG_FS_POSIX_ACL=y
-CONFIG_FWNODE_MDIO=y
-CONFIG_FW_LOADER_PAGED_BUF=y
-CONFIG_FW_LOADER_SYSFS=y
-CONFIG_GCC11_NO_ARRAY_BOUNDS=y
-CONFIG_GCC_ASM_GOTO_OUTPUT_WORKAROUND=y
-CONFIG_GENERIC_ALLOCATOR=y
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_GENERIC_CSUM=y
-CONFIG_GENERIC_IRQ_CHIP=y
-CONFIG_GENERIC_IRQ_SHOW=y
-CONFIG_GENERIC_PCI_IOMAP=y
-CONFIG_GENERIC_PENDING_IRQ=y
-CONFIG_GENERIC_SCHED_CLOCK=y
-CONFIG_GENERIC_SMP_IDLE_THREAD=y
-CONFIG_GENERIC_STRNCPY_FROM_USER=y
-CONFIG_GENERIC_STRNLEN_USER=y
-CONFIG_GPIOLIB_IRQCHIP=y
-CONFIG_GPIO_CDEV=y
-CONFIG_GPIO_DWAPB=y
-CONFIG_GPIO_GENERIC=y
-CONFIG_GPIO_SNPS_CREG=y
-CONFIG_GRACE_PERIOD=y
-CONFIG_HAS_DMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HZ_PERIODIC=y
-CONFIG_I2C=y
-CONFIG_I2C_BOARDINFO=y
-CONFIG_IIO=y
-CONFIG_IIO_BUFFER=y
-CONFIG_IIO_KFIFO_BUF=y
-CONFIG_IIO_ST_PRESS=y
-CONFIG_IIO_ST_PRESS_I2C=y
-CONFIG_IIO_ST_PRESS_SPI=y
-CONFIG_IIO_ST_SENSORS_CORE=y
-CONFIG_IIO_ST_SENSORS_I2C=y
-CONFIG_IIO_ST_SENSORS_SPI=y
-CONFIG_IIO_TRIGGER=y
-CONFIG_IIO_TRIGGERED_BUFFER=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_IRQCHIP=y
-CONFIG_IRQ_DOMAIN=y
-CONFIG_IRQ_DOMAIN_HIERARCHY=y
-CONFIG_IRQ_WORK=y
-# CONFIG_ISA_ARCOMPACT is not set
-CONFIG_ISA_ARCV2=y
-CONFIG_JBD2=y
-CONFIG_KALLSYMS=y
-CONFIG_KERNEL_GZIP=y
-CONFIG_LIBFDT=y
-CONFIG_LINUX_LINK_BASE=0x90000000
-CONFIG_LINUX_RAM_BASE=0x80000000
-CONFIG_LOCKD=y
-CONFIG_LOCKUP_DETECTOR=y
-CONFIG_LOCK_DEBUGGING_SUPPORT=y
-CONFIG_LOCK_SPIN_ON_OWNER=y
-CONFIG_MDIO_BUS=y
-CONFIG_MDIO_DEVICE=y
-CONFIG_MDIO_DEVRES=y
-CONFIG_MEMFD_CREATE=y
-CONFIG_MFD_SYSCON=y
-CONFIG_MICREL_PHY=y
-CONFIG_MIGRATION=y
-CONFIG_MMC=y
-CONFIG_MMC_BLOCK=y
-CONFIG_MMC_DW=y
-# CONFIG_MMC_DW_BLUEFIELD is not set
-# CONFIG_MMC_DW_EXYNOS is not set
-# CONFIG_MMC_DW_HI3798CV200 is not set
-# CONFIG_MMC_DW_K3 is not set
-CONFIG_MMC_DW_PLTFM=y
-CONFIG_MMC_SDHCI=y
-CONFIG_MMC_SDHCI_PLTFM=y
-CONFIG_MODULES_USE_ELF_RELA=y
-CONFIG_MTD_SPI_NOR=y
-CONFIG_MUTEX_SPIN_ON_OWNER=y
-CONFIG_NAMESPACES=y
-CONFIG_NATIONAL_PHY=y
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NET_FLOW_LIMIT=y
-CONFIG_NET_NS=y
-CONFIG_NET_PTP_CLASSIFY=y
-CONFIG_NET_SELFTESTS=y
-CONFIG_NFS_ACL_SUPPORT=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3_ACL=y
-CONFIG_NLS=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_NO_IOPORT_MAP=y
-CONFIG_NR_CPUS=4
-CONFIG_OF=y
-CONFIG_OF_ADDRESS=y
-CONFIG_OF_EARLY_FLATTREE=y
-CONFIG_OF_FLATTREE=y
-CONFIG_OF_GPIO=y
-CONFIG_OF_IRQ=y
-CONFIG_OF_KOBJ=y
-CONFIG_OF_MDIO=y
-CONFIG_PADATA=y
-CONFIG_PAGE_POOL=y
-CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
-CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
-CONFIG_PAHOLE_HAS_LANG_EXCLUDE=y
-CONFIG_PCS_XPCS=y
-CONFIG_PGTABLE_LEVELS=2
-CONFIG_PHYLIB=y
-CONFIG_PHYLIB_LEDS=y
-CONFIG_PHYLINK=y
-CONFIG_PPS=y
-CONFIG_PREEMPT=y
-CONFIG_PREEMPTION=y
-CONFIG_PREEMPT_BUILD=y
-CONFIG_PREEMPT_COUNT=y
-# CONFIG_PREEMPT_NONE is not set
-CONFIG_PREEMPT_RCU=y
-# CONFIG_PREVENT_FIRMWARE_BUILD is not set
-CONFIG_PTP_1588_CLOCK=y
-CONFIG_PTP_1588_CLOCK_OPTIONAL=y
-CONFIG_RANDSTRUCT_NONE=y
-CONFIG_RATIONAL=y
-CONFIG_REGMAP=y
-CONFIG_REGMAP_I2C=y
-CONFIG_REGMAP_MMIO=y
-CONFIG_REGMAP_SPI=y
-CONFIG_RESET_AXS10X=y
-CONFIG_RESET_CONTROLLER=y
-CONFIG_RESET_HSDK=y
-CONFIG_RESET_SIMPLE=y
-CONFIG_RFS_ACCEL=y
-CONFIG_RPS=y
-CONFIG_RWSEM_SPIN_ON_OWNER=y
-CONFIG_SCSI=y
-CONFIG_SCSI_COMMON=y
-CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y
-CONFIG_SERIAL_8250_DW=y
-CONFIG_SERIAL_8250_DWLIB=y
-CONFIG_SERIAL_8250_NR_UARTS=4
-CONFIG_SERIAL_8250_RUNTIME_UARTS=4
-CONFIG_SERIAL_ARC=y
-CONFIG_SERIAL_ARC_CONSOLE=y
-CONFIG_SERIAL_ARC_NR_PORTS=1
-CONFIG_SERIAL_MCTRL_GPIO=y
-CONFIG_SERIAL_OF_PLATFORM=y
-CONFIG_SG_POOL=y
-CONFIG_SMP=y
-CONFIG_SOCK_RX_QUEUE_MAPPING=y
-CONFIG_SOFTLOCKUP_DETECTOR=y
-CONFIG_SPI=y
-CONFIG_SPI_DESIGNWARE=y
-# CONFIG_SPI_DW_DMA is not set
-CONFIG_SPI_DW_MMIO=y
-CONFIG_SPI_MASTER=y
-CONFIG_SPI_MEM=y
-CONFIG_SRCU=y
-CONFIG_STACKTRACE=y
-# CONFIG_STANDALONE is not set
-CONFIG_STMMAC_ETH=y
-CONFIG_STMMAC_PLATFORM=y
-CONFIG_SUNRPC=y
-CONFIG_SWPHY=y
-CONFIG_TICK_CPU_ACCOUNTING=y
-CONFIG_TIMER_OF=y
-CONFIG_TIMER_PROBE=y
-CONFIG_TI_ADC108S102=y
-CONFIG_TREE_RCU=y
-CONFIG_TREE_SRCU=y
-CONFIG_UNINLINE_SPIN_UNLOCK=y
-CONFIG_USB_SUPPORT=y
-# CONFIG_USER_NS is not set
-CONFIG_VFAT_FS=y
-CONFIG_WATCHDOG_CORE=y
-CONFIG_XPS=y
diff --git a/target/linux/archs38/config-6.6 b/target/linux/archs38/config-6.6
new file mode 100644
index 0000000000..6298ce9e46
--- /dev/null
+++ b/target/linux/archs38/config-6.6
@@ -0,0 +1,279 @@
+# CONFIG_16KSTACKS is not set
+CONFIG_ARC=y
+CONFIG_ARCH_32BIT_OFF_T=y
+CONFIG_ARC_BUILTIN_DTB_NAME=""
+CONFIG_ARC_CACHE=y
+CONFIG_ARC_CACHE_LINE_SHIFT=6
+CONFIG_ARC_CACHE_PAGES=y
+CONFIG_ARC_CPU_HS=y
+CONFIG_ARC_CURR_IN_REG=y
+CONFIG_ARC_DBG=y
+# CONFIG_ARC_DSP_AGU_USERSPACE is not set
+# CONFIG_ARC_DSP_KERNEL is not set
+CONFIG_ARC_DSP_NONE=y
+# CONFIG_ARC_DSP_USERSPACE is not set
+CONFIG_ARC_DW2_UNWIND=y
+CONFIG_ARC_FPU_SAVE_RESTORE=y
+CONFIG_ARC_HAS_ACCL_REGS=y
+CONFIG_ARC_HAS_DCACHE=y
+# CONFIG_ARC_HAS_DCCM is not set
+CONFIG_ARC_HAS_DIV_REM=y
+CONFIG_ARC_HAS_ICACHE=y
+# CONFIG_ARC_HAS_ICCM is not set
+CONFIG_ARC_HAS_LL64=y
+CONFIG_ARC_HAS_LLSC=y
+# CONFIG_ARC_HAS_PAE40 is not set
+CONFIG_ARC_HAS_SWAPE=y
+CONFIG_ARC_IRQ_NO_AUTOSAVE=y
+CONFIG_ARC_KVADDR_SIZE=256
+# CONFIG_ARC_LPB_DISABLE is not set
+CONFIG_ARC_MCIP=y
+# CONFIG_ARC_METAWARE_HLINK is not set
+CONFIG_ARC_MMU_V4=y
+# CONFIG_ARC_PAGE_SIZE_16K is not set
+# CONFIG_ARC_PAGE_SIZE_4K is not set
+CONFIG_ARC_PAGE_SIZE_8K=y
+CONFIG_ARC_PLAT_AXS10X=y
+# CONFIG_ARC_PLAT_TB10X is not set
+# CONFIG_ARC_SMP_HALT_ON_RESET is not set
+CONFIG_ARC_SOC_HSDK=y
+CONFIG_ARC_TIMERS=y
+CONFIG_ARC_TIMERS_64BIT=y
+CONFIG_ARC_TUNE_MCPU=""
+CONFIG_ARC_USE_UNALIGNED_MEM_ACCESS=y
+CONFIG_AXS103=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_SD=y
+CONFIG_BUFFER_HEAD=y
+CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
+CONFIG_CC_NO_ARRAY_BOUNDS=y
+CONFIG_CLK_HSDK=y
+CONFIG_CLONE_BACKWARDS=y
+CONFIG_COMMON_CLK=y
+CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
+CONFIG_COMPAT_32BIT_TIME=y
+CONFIG_CONTEXT_TRACKING=y
+CONFIG_CONTEXT_TRACKING_IDLE=y
+CONFIG_CPU_MITIGATIONS=y
+CONFIG_CPU_RMAP=y
+CONFIG_CRC16=y
+CONFIG_CRYPTO_CRC32C=y
+CONFIG_CRYPTO_DRBG=y
+CONFIG_CRYPTO_DRBG_HMAC=y
+CONFIG_CRYPTO_DRBG_MENU=y
+CONFIG_CRYPTO_ECHAINIV=y
+CONFIG_CRYPTO_GENIV=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_JITTERENTROPY=y
+CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
+CONFIG_CRYPTO_LIB_GF128MUL=y
+CONFIG_CRYPTO_LIB_POLY1305_RSIZE=1
+CONFIG_CRYPTO_LIB_SHA1=y
+CONFIG_CRYPTO_LIB_SHA256=y
+CONFIG_CRYPTO_LIB_UTILS=y
+CONFIG_CRYPTO_RNG=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_RNG_DEFAULT=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA3=y
+CONFIG_CRYPTO_SHA512=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DMADEVICES=y
+CONFIG_DMA_DIRECT_REMAP=y
+CONFIG_DMA_ENGINE=y
+CONFIG_DMA_OF=y
+CONFIG_DMA_VIRTUAL_CHANNELS=y
+CONFIG_DTC=y
+CONFIG_DWMAC_ANARION=y
+CONFIG_DWMAC_GENERIC=y
+CONFIG_DW_APB_ICTL=y
+CONFIG_DW_AXI_DMAC=y
+CONFIG_EXCLUSIVE_SYSTEM_RAM=y
+CONFIG_EXT4_FS=y
+CONFIG_FAT_FS=y
+CONFIG_FB=y
+CONFIG_FB_CORE=y
+CONFIG_FB_IOMEM_FOPS=y
+CONFIG_FIXED_PHY=y
+CONFIG_FS_IOMAP=y
+CONFIG_FS_MBCACHE=y
+CONFIG_FUNCTION_ALIGNMENT=0
+CONFIG_FWNODE_MDIO=y
+CONFIG_FW_LOADER_PAGED_BUF=y
+CONFIG_FW_LOADER_SYSFS=y
+CONFIG_GCC10_NO_ARRAY_BOUNDS=y
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CSUM=y
+CONFIG_GENERIC_IOREMAP=y
+CONFIG_GENERIC_IRQ_CHIP=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_PENDING_IRQ=y
+CONFIG_GENERIC_SCHED_CLOCK=y
+CONFIG_GENERIC_SMP_IDLE_THREAD=y
+CONFIG_GENERIC_STRNCPY_FROM_USER=y
+CONFIG_GENERIC_STRNLEN_USER=y
+CONFIG_GPIOLIB_IRQCHIP=y
+CONFIG_GPIO_CDEV=y
+CONFIG_GPIO_DWAPB=y
+CONFIG_GPIO_GENERIC=y
+CONFIG_GPIO_SNPS_CREG=y
+CONFIG_GRACE_PERIOD=y
+CONFIG_HAS_DMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HZ_PERIODIC=y
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_IIO=y
+CONFIG_IIO_BUFFER=y
+CONFIG_IIO_KFIFO_BUF=y
+CONFIG_IIO_ST_PRESS=y
+CONFIG_IIO_ST_PRESS_I2C=y
+CONFIG_IIO_ST_PRESS_SPI=y
+CONFIG_IIO_ST_SENSORS_CORE=y
+CONFIG_IIO_ST_SENSORS_I2C=y
+CONFIG_IIO_ST_SENSORS_SPI=y
+CONFIG_IIO_TRIGGER=y
+CONFIG_IIO_TRIGGERED_BUFFER=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_IRQCHIP=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_DOMAIN_HIERARCHY=y
+CONFIG_IRQ_WORK=y
+# CONFIG_ISA_ARCOMPACT is not set
+CONFIG_ISA_ARCV2=y
+CONFIG_JBD2=y
+CONFIG_KALLSYMS=y
+CONFIG_KERNEL_GZIP=y
+CONFIG_LEGACY_DIRECT_IO=y
+CONFIG_LIBFDT=y
+CONFIG_LINUX_LINK_BASE=0x90000000
+CONFIG_LINUX_RAM_BASE=0x80000000
+CONFIG_LOCKD=y
+CONFIG_LOCKUP_DETECTOR=y
+CONFIG_LOCK_DEBUGGING_SUPPORT=y
+CONFIG_LOCK_SPIN_ON_OWNER=y
+CONFIG_MDIO_BUS=y
+CONFIG_MDIO_DEVICE=y
+CONFIG_MDIO_DEVRES=y
+CONFIG_MFD_SYSCON=y
+CONFIG_MICREL_PHY=y
+CONFIG_MIGRATION=y
+CONFIG_MMC=y
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_DW=y
+# CONFIG_MMC_DW_BLUEFIELD is not set
+# CONFIG_MMC_DW_EXYNOS is not set
+# CONFIG_MMC_DW_HI3798CV200 is not set
+# CONFIG_MMC_DW_K3 is not set
+CONFIG_MMC_DW_PLTFM=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMU_LAZY_TLB_REFCOUNT=y
+CONFIG_MODULES_USE_ELF_RELA=y
+CONFIG_MTD_SPI_NOR=y
+CONFIG_MUTEX_SPIN_ON_OWNER=y
+CONFIG_NAMESPACES=y
+CONFIG_NATIONAL_PHY=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_NET_EGRESS=y
+CONFIG_NET_FLOW_LIMIT=y
+CONFIG_NET_HANDSHAKE=y
+CONFIG_NET_INGRESS=y
+CONFIG_NET_NS=y
+CONFIG_NET_PTP_CLASSIFY=y
+CONFIG_NET_SELFTESTS=y
+CONFIG_NET_XGRESS=y
+CONFIG_NFS_ACL_SUPPORT=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NLS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NO_IOPORT_MAP=y
+CONFIG_NR_CPUS=4
+CONFIG_OF=y
+CONFIG_OF_ADDRESS=y
+CONFIG_OF_EARLY_FLATTREE=y
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_GPIO=y
+CONFIG_OF_IRQ=y
+CONFIG_OF_KOBJ=y
+CONFIG_OF_MDIO=y
+CONFIG_PADATA=y
+CONFIG_PAGE_POOL=y
+CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
+CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
+CONFIG_PCS_XPCS=y
+CONFIG_PGTABLE_LEVELS=2
+CONFIG_PHYLIB=y
+CONFIG_PHYLIB_LEDS=y
+CONFIG_PHYLINK=y
+CONFIG_PPS=y
+CONFIG_PREEMPT=y
+CONFIG_PREEMPTION=y
+CONFIG_PREEMPT_BUILD=y
+CONFIG_PREEMPT_COUNT=y
+# CONFIG_PREEMPT_NONE is not set
+CONFIG_PREEMPT_RCU=y
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+CONFIG_PTP_1588_CLOCK=y
+CONFIG_PTP_1588_CLOCK_OPTIONAL=y
+CONFIG_RANDSTRUCT_NONE=y
+CONFIG_RATIONAL=y
+CONFIG_REGMAP=y
+CONFIG_REGMAP_I2C=y
+CONFIG_REGMAP_MMIO=y
+CONFIG_REGMAP_SPI=y
+CONFIG_RESET_AXS10X=y
+CONFIG_RESET_CONTROLLER=y
+CONFIG_RESET_HSDK=y
+CONFIG_RESET_SIMPLE=y
+CONFIG_RFS_ACCEL=y
+CONFIG_RPS=y
+CONFIG_RWSEM_SPIN_ON_OWNER=y
+CONFIG_SCSI=y
+CONFIG_SCSI_COMMON=y
+CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y
+CONFIG_SERIAL_8250_DW=y
+CONFIG_SERIAL_8250_DWLIB=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+CONFIG_SERIAL_ARC=y
+CONFIG_SERIAL_ARC_CONSOLE=y
+CONFIG_SERIAL_ARC_NR_PORTS=1
+CONFIG_SERIAL_MCTRL_GPIO=y
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_SG_POOL=y
+CONFIG_SMP=y
+CONFIG_SOCK_RX_QUEUE_MAPPING=y
+CONFIG_SOFTLOCKUP_DETECTOR=y
+CONFIG_SPI=y
+CONFIG_SPI_DESIGNWARE=y
+# CONFIG_SPI_DW_DMA is not set
+CONFIG_SPI_DW_MMIO=y
+CONFIG_SPI_MASTER=y
+CONFIG_SPI_MEM=y
+CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y
+CONFIG_STACKTRACE=y
+# CONFIG_STANDALONE is not set
+CONFIG_STMMAC_ETH=y
+CONFIG_STMMAC_PLATFORM=y
+CONFIG_SUNRPC=y
+CONFIG_SWPHY=y
+CONFIG_TICK_CPU_ACCOUNTING=y
+CONFIG_TIMER_OF=y
+CONFIG_TIMER_PROBE=y
+CONFIG_TI_ADC108S102=y
+CONFIG_TREE_RCU=y
+CONFIG_TREE_SRCU=y
+CONFIG_UNINLINE_SPIN_UNLOCK=y
+CONFIG_USB_SUPPORT=y
+# CONFIG_USER_NS is not set
+CONFIG_VFAT_FS=y
+CONFIG_VIDEO_CMDLINE=y
+CONFIG_WATCHDOG_CORE=y
+CONFIG_XPS=y
diff --git a/target/linux/archs38/generic/target.mk b/target/linux/archs38/generic/target.mk
index 7642c6b261..dfe0474fd8 100644
--- a/target/linux/archs38/generic/target.mk
+++ b/target/linux/archs38/generic/target.mk
@@ -1,5 +1,5 @@
BOARDNAME:=Generic
-FEATURES += ext4 usb ramdisk
+FEATURES += ext4 usb ramdisk rootfs-part
define Target/Description
Build firmware images for ARC HS38 based boards.
diff --git a/target/linux/armsr/armv8/config-6.6 b/target/linux/armsr/armv8/config-6.6
index 3ce25c60d8..a5a90ff9a8 100644
--- a/target/linux/armsr/armv8/config-6.6
+++ b/target/linux/armsr/armv8/config-6.6
@@ -59,10 +59,8 @@ CONFIG_ARM64=y
CONFIG_ARM64_4K_PAGES=y
CONFIG_ARM64_AMU_EXTN=y
CONFIG_ARM64_BTI=y
-CONFIG_ARM64_CNP=y
CONFIG_ARM64_CRYPTO=y
CONFIG_ARM64_E0PD=y
-CONFIG_ARM64_EPAN=y
CONFIG_ARM64_ERRATUM_1024718=y
CONFIG_ARM64_ERRATUM_1165522=y
CONFIG_ARM64_ERRATUM_1286807=y
@@ -93,7 +91,6 @@ CONFIG_ARM64_HW_AFDBM=y
CONFIG_ARM64_LD_HAS_FIX_ERRATUM_843419=y
CONFIG_ARM64_MTE=y
CONFIG_ARM64_PAGE_SHIFT=12
-CONFIG_ARM64_PAN=y
CONFIG_ARM64_PA_BITS=48
CONFIG_ARM64_PA_BITS_48=y
CONFIG_ARM64_PTR_AUTH=y
diff --git a/target/linux/armsr/base-files/etc/inittab b/target/linux/armsr/base-files/etc/inittab
index b3033a3ced..7ca0231a22 100644
--- a/target/linux/armsr/base-files/etc/inittab
+++ b/target/linux/armsr/base-files/etc/inittab
@@ -2,7 +2,7 @@
::shutdown:/etc/init.d/rcS K shutdown
ttyAMA0::askfirst:/usr/libexec/login.sh
@GRUB_SERIAL@::askfirst:/usr/libexec/login.sh
-tty0::askfirst:/usr/libexec/login.sh
+tty1::askfirst:/usr/libexec/login.sh
hvc0::askfirst:/usr/libexec/login.sh
ttymxc0::askfirst:/usr/libexec/login.sh
ttymxc1::askfirst:/usr/libexec/login.sh
diff --git a/target/linux/armsr/config-6.6 b/target/linux/armsr/config-6.6
index 304602ebbd..2588ccd3b9 100644
--- a/target/linux/armsr/config-6.6
+++ b/target/linux/armsr/config-6.6
@@ -55,6 +55,7 @@ CONFIG_ARCH_WANTS_NO_INSTR=y
CONFIG_ARM64=y
CONFIG_ARM64_4K_PAGES=y
# CONFIG_ARM64_ACPI_PARKING_PROTOCOL is not set
+CONFIG_ARM64_ERRATUM_3194386=y
CONFIG_ARM64_LD_HAS_FIX_ERRATUM_843419=y
CONFIG_ARM64_PAGE_SHIFT=12
CONFIG_ARM64_PA_BITS=48
diff --git a/target/linux/armsr/image/Makefile b/target/linux/armsr/image/Makefile
index 7d04a2e8f6..66f027c732 100644
--- a/target/linux/armsr/image/Makefile
+++ b/target/linux/armsr/image/Makefile
@@ -12,6 +12,7 @@ GRUB_TERMINAL_CONFIG =
GRUB_CONSOLE_CMDLINE = earlycon
ifneq ($(CONFIG_GRUB_CONSOLE),)
+ GRUB_CONSOLE_CMDLINE += console=tty1
GRUB_TERMINALS += console
endif
diff --git a/target/linux/armsr/patches-6.1/701-v6.2-0011-net-dpaa2-switch-serialize-changes-to-priv-mac-with.patch b/target/linux/armsr/patches-6.1/701-v6.2-0011-net-dpaa2-switch-serialize-changes-to-priv-mac-with.patch
index 9d6f5c52dc..abf127b155 100644
--- a/target/linux/armsr/patches-6.1/701-v6.2-0011-net-dpaa2-switch-serialize-changes-to-priv-mac-with.patch
+++ b/target/linux/armsr/patches-6.1/701-v6.2-0011-net-dpaa2-switch-serialize-changes-to-priv-mac-with.patch
@@ -181,7 +181,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
dpaa2_switch_port_disconnect_mac(port_priv);
else
dpaa2_switch_port_connect_mac(port_priv);
-@@ -3249,6 +3272,8 @@ static int dpaa2_switch_probe_port(struc
+@@ -3250,6 +3273,8 @@ static int dpaa2_switch_probe_port(struc
port_priv->netdev = port_netdev;
port_priv->ethsw_data = ethsw;
diff --git a/target/linux/armsr/patches-6.1/701-v6.2-0012-net-dpaa2-mac-move-rtnl_lock-only-around-phylink.patch b/target/linux/armsr/patches-6.1/701-v6.2-0012-net-dpaa2-mac-move-rtnl_lock-only-around-phylink.patch
index 5de2137002..d71b85b452 100644
--- a/target/linux/armsr/patches-6.1/701-v6.2-0012-net-dpaa2-mac-move-rtnl_lock-only-around-phylink.patch
+++ b/target/linux/armsr/patches-6.1/701-v6.2-0012-net-dpaa2-mac-move-rtnl_lock-only-around-phylink.patch
@@ -101,7 +101,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
}
out:
-@@ -2951,9 +2949,7 @@ static void dpaa2_switch_remove_port(str
+@@ -2952,9 +2950,7 @@ static void dpaa2_switch_remove_port(str
{
struct ethsw_port_priv *port_priv = ethsw->ports[port_idx];
diff --git a/target/linux/ath79/dts/ar7242_tplink_tl-wr2543-v1.dts b/target/linux/ath79/dts/ar7242_tplink_tl-wr2543-v1.dts
index 77eeedc588..0124ddff87 100644
--- a/target/linux/ath79/dts/ar7242_tplink_tl-wr2543-v1.dts
+++ b/target/linux/ath79/dts/ar7242_tplink_tl-wr2543-v1.dts
@@ -78,7 +78,7 @@
compatible = "realtek,rtl8367";
gpio-sda = <&gpio 1 GPIO_ACTIVE_HIGH>;
gpio-sck = <&gpio 6 GPIO_ACTIVE_HIGH>;
- realtek,extif0 = <1 0 1 1 1 1 1 1 2>;
+ realtek,extif = <9 1 0 1 1 1 1 1 1 2>;
mdio-bus {
#address-cells = <1>;
diff --git a/target/linux/ath79/dts/ar9344_huawei_ap6010dn.dts b/target/linux/ath79/dts/ar9344_huawei_ap6010dn.dts
new file mode 100644
index 0000000000..2f2e6e2331
--- /dev/null
+++ b/target/linux/ath79/dts/ar9344_huawei_ap6010dn.dts
@@ -0,0 +1,243 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "ar9344.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+ model = "Huawei AP6010DN";
+ compatible = "huawei,ap6010dn", "qca,ar9344";
+
+ chosen {
+ bootargs = "console=ttyS0,9600n8";
+ };
+
+ aliases {
+ led-boot = &led_function_green;
+ led-failsafe = &led_function_red;
+ led-running = &led_function_green;
+ led-upgrade = &led_function_red;
+ label-mac-device = &eth0;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led_function_green: led-status-green {
+ function = LED_FUNCTION_STATUS;
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&gpio 13 GPIO_ACTIVE_HIGH>;
+ };
+
+ led_function_red: led-status-red {
+ function = LED_FUNCTION_STATUS;
+ color = <LED_COLOR_ID_RED>;
+ gpios = <&gpio 14 GPIO_ACTIVE_HIGH>;
+ };
+
+ };
+
+ keys {
+ compatible = "gpio-keys";
+
+ restart {
+ label = "reset";
+ linux,code = <KEY_RESTART>;
+ gpios = <&gpio 21 GPIO_ACTIVE_LOW>;
+ debounce-interval = <60>;
+ };
+ };
+
+ watchdog {
+ pinctrl-names = "default";
+ pinctrl-0 = <&wdt_gpio15>;
+
+ compatible = "linux,wdt-gpio";
+ gpios = <&gpio 15 GPIO_ACTIVE_HIGH>;
+ hw_algo = "toggle";
+ hw_margin_ms = <100>;
+ always-running;
+ };
+
+ virtual_flash {
+ compatible = "mtd-concat";
+ devices = <&fwconcat0 &fwconcat1>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "firmware";
+ reg = <0x0 0x1e00000>;
+ compatible = "openwrt,uimage", "denx,uimage";
+ };
+ };
+ };
+};
+
+&spi {
+ status = "okay";
+
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <25000000>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "u-boot-a";
+ reg = <0x0 0x80000>;
+ read-only;
+ };
+
+ partition@80000 {
+ label = "BootupA";
+ reg = <0x80000 0x20000>;
+ };
+
+ partition@a0000 {
+ label = "BootupB";
+ reg = <0xa0000 0x20000>;
+ };
+
+ partition@c0000 {
+ label = "u-boot-env";
+ reg = <0xc0000 0x20000>;
+ read-only;
+ };
+
+ partition@e0000 {
+ label = "BoardData";
+ reg = <0xe0000 0x20000>;
+ read-only;
+ };
+
+ // In the vendor layout, there are the "SysImageA" (12 MiB)
+ // and the "ConfigA" (3 MiB) partitions here.
+ fwconcat0: partition@100000 {
+ label = "fwconcat0";
+ reg = <0x100000 0xf00000>;
+ };
+
+ partition@1000000 {
+ label = "u-boot-b";
+ reg = <0x1000000 0x80000>;
+ read-only;
+ };
+
+ partition@1080000 {
+ label = "ResultA";
+ reg = <0x1080000 0x20000>;
+ read-only;
+ };
+
+ partition@10a0000 {
+ label = "ResultB";
+ reg = <0x10a0000 0x20000>;
+ read-only;
+ };
+
+ // In the vendor layout, there are the "SysImageB" (12 MiB)
+ // and the "ConfigB" (3 MiB) partitions here.
+ fwconcat1: partition@10c0000 {
+ label = "fwconcat1";
+ reg = <0x10c0000 0xf00000>;
+ };
+
+ art: partition@1fc0000 {
+ label = "art";
+ reg = <0x1fc0000 0x40000>;
+ read-only;
+
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ macaddr_art_2005b: macaddr@2005b {
+ compatible = "mac-base";
+ reg = <0x2005b 0x6>;
+ #nvmem-cell-cells = <1>;
+ };
+
+ cal_art_1000: cal@1000 {
+ reg = <0x1000 0x440>;
+ };
+
+ cal_art_5000: cal@5000 {
+ reg = <0x5000 0x844>;
+ };
+ };
+ };
+ };
+ };
+};
+
+&wmac {
+ status = "okay";
+
+ nvmem-cells = <&macaddr_art_2005b 1>, <&cal_art_1000>;
+ nvmem-cell-names = "mac-address", "calibration";
+};
+
+&pcie {
+ status = "okay";
+
+ ath9k: wifi@0,0 {
+ compatible = "pci168c,0033";
+ reg = <0x0000 0 0 0 0>;
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ nvmem-cells = <&macaddr_art_2005b 2>, <&cal_art_5000>;
+ nvmem-cell-names = "mac-address", "calibration";
+ };
+};
+
+&ref {
+ clock-frequency = <40000000>;
+};
+
+&eth0 {
+ status = "okay";
+
+ nvmem-cells = <&macaddr_art_2005b 0>;
+ nvmem-cell-names = "mac-address";
+
+ pll-data = <0x06000000 0x04000101 0x0c001313>;
+ phy-mode = "rgmii-id";
+ phy-handle = <&phy>;
+
+ gmac-config {
+ device = <&gmac>;
+ rgmii-gmac0 = <1>;
+ rxdv-delay = <3>;
+ rxd-delay = <3>;
+ };
+};
+
+&mdio0 {
+ status = "okay";
+
+ phy: ethernet-phy@18 {
+ reg = <0x4>;
+ };
+};
+
+&pinmux {
+ wdt_gpio15: pinmux_wdt_gpio15 {
+ pinctrl-single,bits = <0xc 0x0 0xFF000000>;
+ };
+};
+
+&wdt {
+ status = "disabled";
+};
diff --git a/target/linux/ath79/dts/ar9344_nec_aterm.dtsi b/target/linux/ath79/dts/ar9344_nec_aterm.dtsi
new file mode 100644
index 0000000000..dfe2b064b7
--- /dev/null
+++ b/target/linux/ath79/dts/ar9344_nec_aterm.dtsi
@@ -0,0 +1,300 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+
+#include "ar9344.dtsi"
+
+/ {
+ aliases {
+ led-running = &led_power_green;
+ led-upgrade = &led_power_green;
+ };
+
+ chosen {
+ /*
+ * don't specify bootargs property in DeviceTree to
+ * enable a console with a default baudrate (9600)
+ * or passed console= parameter from the bootloader
+ */
+ /delete-property/ bootargs;
+ stdout-path = &uart;
+ };
+
+ keys: keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&jtag_disable_pins>;
+
+ button-eco {
+ label = "eco";
+ gpios = <&gpio 3 GPIO_ACTIVE_LOW>;
+ linux,code = <BTN_0>;
+ debounce-interval = <60>;
+ };
+
+ switch-ap {
+ label = "ap";
+ gpios = <&gpio 11 GPIO_ACTIVE_LOW>;
+ linux,code = <BTN_1>;
+ debounce-interval = <60>;
+ };
+
+ button-reset {
+ label = "reset";
+ gpios = <&gpio 15 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_RESTART>;
+ debounce-interval = <60>;
+ };
+
+ button-wps {
+ label = "wps";
+ gpios = <&gpio 16 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_WPS_BUTTON>;
+ debounce-interval = <60>;
+ };
+ };
+
+ ath9k_leds: ath9k-leds {
+ /* all LEDs are connected to ath9k chip (AR938x) */
+ compatible = "gpio-leds";
+
+ led_power_green: led-0 {
+ gpios = <&ath9k 0 GPIO_ACTIVE_LOW>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_POWER;
+ default-state = "on";
+ };
+
+ led-1 {
+ gpios = <&ath9k 1 GPIO_ACTIVE_LOW>;
+ color = <LED_COLOR_ID_RED>;
+ function = LED_FUNCTION_POWER;
+ };
+
+ led-2 {
+ gpios = <&ath9k 2 GPIO_ACTIVE_LOW>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_WAN_ONLINE;
+ };
+
+ led-3 {
+ gpios = <&ath9k 3 GPIO_ACTIVE_LOW>;
+ color = <LED_COLOR_ID_RED>;
+ function = LED_FUNCTION_WAN_ONLINE;
+ };
+
+ led-4 {
+ gpios = <&ath9k 4 GPIO_ACTIVE_LOW>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_WLAN_2GHZ;
+ linux,default-trigger = "phy0tpt";
+ };
+
+ led-5 {
+ gpios = <&ath9k 5 GPIO_ACTIVE_LOW>;
+ color = <LED_COLOR_ID_RED>;
+ function = LED_FUNCTION_WLAN_2GHZ;
+ };
+
+ led-6 {
+ gpios = <&ath9k 6 GPIO_ACTIVE_LOW>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_WLAN_5GHZ;
+ linux,default-trigger = "phy1tpt";
+ };
+
+ led-7 {
+ gpios = <&ath9k 7 GPIO_ACTIVE_LOW>;
+ color = <LED_COLOR_ID_RED>;
+ function = LED_FUNCTION_WLAN_5GHZ;
+ };
+
+ led-8 {
+ gpios = <&ath9k 12 GPIO_ACTIVE_LOW>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = "tv";
+ };
+
+ led-9 {
+ gpios = <&ath9k 13 GPIO_ACTIVE_LOW>;
+ color = <LED_COLOR_ID_RED>;
+ function = "tv";
+ };
+ };
+
+ regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "usb-vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio 20 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ regulator-always-on;
+ };
+};
+
+&ref {
+ clock-frequency = <40000000>;
+};
+
+&spi {
+ status = "okay";
+
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <25000000>;
+
+ partitions: partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ /*
+ * since the OEM bootloader requires unknown
+ * filesystem on firmware area, needs to be
+ * replaced to u-boot before OpenWrt installation
+ */
+ partition@0 {
+ label = "bootloader";
+ reg = <0x000000 0x020000>;
+ };
+
+ /* not compatible with u-boot */
+ partition@20000 {
+ label = "config";
+ reg = <0x020000 0x010000>;
+ read-only;
+
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ macaddr_config_6: macaddr@6 {
+ reg = <0x6 0x6>;
+ };
+ };
+ };
+
+ partition@30000 {
+ label = "art";
+ reg = <0x030000 0x010000>;
+ read-only;
+
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ cal_art_1000: calibration@1000 {
+ reg = <0x1000 0x440>;
+ };
+
+ cal_art_5000: calibration@5000 {
+ reg = <0x5000 0x440>;
+ };
+ };
+ };
+ };
+ };
+};
+
+&mdio0 {
+ status = "okay";
+
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+
+ qca,ar8327-initvals = <
+ 0x04 0x07a00000 /* PORT0_PAD_MODE_CTRL */
+ 0x08 0x00000000 /* PORT5_PAD_MODE_CTRL */
+ 0x0c 0x00000000 /* PORT6_PAD_MODE_CTRL */
+ 0x10 0x81000080 /* POWER_ON_STRAP */
+ 0x50 0xcf37cf37 /* LED_CTRL0 */
+ 0x54 0x00000000 /* LED_CTRL1 */
+ 0x58 0x00000000 /* LED_CTRL2 */
+ 0x5c 0x03ffff00 /* LED_CTRL3 */
+ 0x7c 0x0000007e /* PORT0_STATUS */
+ >;
+ };
+};
+
+&eth0 {
+ status = "okay";
+
+ pll-data = <0x06000000 0x00000101 0x00001616>;
+
+ phy-mode = "rgmii";
+ phy-handle = <&phy0>;
+
+ nvmem-cells = <&macaddr_config_6>;
+ nvmem-cell-names = "mac-address";
+
+ gmac-config {
+ device = <&gmac>;
+
+ rgmii-gmac0 = <1>;
+ rxdv-delay = <0>;
+ rxd-delay = <0>;
+ txd-delay = <0>;
+ txen-delay = <0>;
+ };
+};
+
+&gpio {
+ switch-reset {
+ gpio-hog;
+ gpios = <13 GPIO_ACTIVE_HIGH>;
+ output-high;
+ };
+};
+
+&pcie {
+ status = "okay";
+
+ ath9k: wifi@0,0 {
+ compatible = "pci168c,0030";
+ reg = <0x0000 0 0 0 0>;
+ #gpio-cells = <2>;
+ gpio-controller;
+
+ nvmem-cells = <&cal_art_5000>;
+ nvmem-cell-names = "calibration";
+
+ usb-hub-reset {
+ gpio-hog;
+ gpios = <10 GPIO_ACTIVE_HIGH>;
+ output-high;
+ };
+ };
+};
+
+&usb_phy {
+ status = "okay";
+};
+
+&usb {
+ status = "okay";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ dr_mode = "host";
+
+ /delete-node/ port@1;
+
+ /* NEC uPD720114 */
+ hub@1 {
+ compatible = "usb0409,005a";
+ reg = <1>;
+ };
+};
+
+&wmac {
+ status = "okay";
+
+ nvmem-cells = <&cal_art_1000>;
+ nvmem-cell-names = "calibration";
+};
diff --git a/target/linux/ath79/dts/ar9344_nec_wg600hp.dts b/target/linux/ath79/dts/ar9344_nec_wg600hp.dts
new file mode 100644
index 0000000000..e586dce7ca
--- /dev/null
+++ b/target/linux/ath79/dts/ar9344_nec_wg600hp.dts
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "ar9344_nec_aterm.dtsi"
+
+/ {
+ compatible = "nec,wg600hp", "qca,ar9344";
+ model = "NEC Aterm WG600HP";
+};
+
+&partitions {
+ partition@40000 {
+ compatible = "denx,uimage";
+ label = "firmware";
+ reg = <0x040000 0x7c0000>;
+ };
+};
diff --git a/target/linux/ath79/dts/ar9344_nec_wr8750n.dts b/target/linux/ath79/dts/ar9344_nec_wr8750n.dts
new file mode 100644
index 0000000000..47e49dddc5
--- /dev/null
+++ b/target/linux/ath79/dts/ar9344_nec_wr8750n.dts
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "ar9344_nec_aterm.dtsi"
+
+/ {
+ compatible = "nec,wr8750n", "qca,ar9344";
+ model = "NEC Aterm WR8750N";
+};
+
+&partitions {
+ partition@40000 {
+ compatible = "denx,uimage";
+ label = "firmware";
+ reg = <0x040000 0x7c0000>;
+ };
+};
diff --git a/target/linux/ath79/dts/ar9344_nec_wr9500n.dts b/target/linux/ath79/dts/ar9344_nec_wr9500n.dts
new file mode 100644
index 0000000000..1919e09829
--- /dev/null
+++ b/target/linux/ath79/dts/ar9344_nec_wr9500n.dts
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "ar9344_nec_aterm.dtsi"
+
+/ {
+ compatible = "nec,wr9500n", "qca,ar9344";
+ model = "NEC Aterm WR9500N";
+};
+
+&keys {
+ switch-converter {
+ label = "cnv";
+ gpios = <&gpio 12 GPIO_ACTIVE_LOW>;
+ linux,code = <BTN_2>;
+ debounce-interval = <60>;
+ };
+};
+
+&ath9k_leds {
+ led-10 {
+ gpios = <&ath9k 14 GPIO_ACTIVE_LOW>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = "converter";
+ };
+
+ led-11 {
+ gpios = <&ath9k 15 GPIO_ACTIVE_LOW>;
+ color = <LED_COLOR_ID_RED>;
+ function = "converter";
+ };
+};
+
+&partitions {
+ partition@40000 {
+ compatible = "denx,uimage";
+ label = "firmware";
+ reg = <0x040000 0xfc0000>;
+ };
+};
diff --git a/target/linux/ath79/dts/ar9344_qihoo_c301.dts b/target/linux/ath79/dts/ar9344_qihoo_c301.dts
index 1d9c6ca9a4..0e9104dbb9 100644
--- a/target/linux/ath79/dts/ar9344_qihoo_c301.dts
+++ b/target/linux/ath79/dts/ar9344_qihoo_c301.dts
@@ -166,6 +166,10 @@
#address-cells = <1>;
#size-cells = <1>;
+ cal_radiocfg_1000: calibration@1000 {
+ reg = <0x1000 0x440>;
+ };
+
cal_radiocfg_5000: calibration@5000 {
reg = <0x5000 0x844>;
};
@@ -220,7 +224,9 @@
&wmac {
status = "okay";
- qca,no-eeprom;
+
+ nvmem-cells = <&cal_radiocfg_1000>;
+ nvmem-cell-names = "calibration";
};
&eth1 {
diff --git a/target/linux/ath79/dts/qca9557_sophos_ap15.dts b/target/linux/ath79/dts/qca9557_sophos_ap15.dts
new file mode 100644
index 0000000000..773b423cde
--- /dev/null
+++ b/target/linux/ath79/dts/qca9557_sophos_ap15.dts
@@ -0,0 +1,148 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "qca955x.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+ compatible = "sophos,ap15", "qca,qca9557";
+ model = "Sophos AP15";
+
+ aliases {
+ led-boot = &led_status_green;
+ led-failsafe = &led_status_yellow;
+ led-running = &led_status_green;
+ led-upgrade = &led_status_yellow;
+ label-mac-device = &eth0;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200n8";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led_status_green: status_green {
+ function = LED_FUNCTION_STATUS;
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&gpio 13 GPIO_ACTIVE_LOW>;
+ default-state = "on";
+ };
+
+ led_status_yellow: status_yellow {
+ function = LED_FUNCTION_STATUS;
+ color = <LED_COLOR_ID_YELLOW>;
+ gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
+
+&spi {
+ status = "okay";
+
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <25000000>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "u-boot";
+ reg = <0x000000 0x040000>;
+ read-only;
+ };
+
+ partition@40000 {
+ label = "u-boot-env";
+ reg = <0x040000 0x010000>;
+ };
+
+ partition@50000 {
+ label = "art";
+ reg = <0x050000 0x010000>;
+ read-only;
+
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ cal_art_1000: calibration@1000 {
+ reg = <0x1000 0x440>;
+ };
+ };
+ };
+
+ partition@60000 {
+ label = "config";
+ reg = <0x060000 0x010000>;
+ read-only;
+
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ macaddr_config_201a: macaddr@201a {
+ reg = <0x201a 0x6>;
+ };
+ };
+ };
+
+ partition@70000 {
+ compatible = "denx,uimage";
+ label = "firmware";
+ reg = <0x070000 0xf90000>;
+ };
+ };
+ };
+};
+
+&mdio0 {
+ status = "okay";
+
+ phy-mask = <0x10>;
+
+ phy4: ethernet-phy@4 {
+ reg = <4>;
+ eee-broken-100tx;
+ eee-broken-1000t;
+ };
+};
+
+&eth0 {
+ status = "okay";
+
+ pll-data = <0xa6000000 0xa0000101 0xa0001313>;
+
+ nvmem-cells = <&macaddr_config_201a>;
+ nvmem-cell-names = "mac-address";
+
+ phy-mode = "rgmii-id";
+ phy-handle = <&phy4>;
+
+ gmac_config: gmac-config {
+ device = <&gmac>;
+
+ rgmii-enabled = <1>;
+
+ rxdv-delay = <3>;
+ rxd-delay = <3>;
+ txen-delay = <3>;
+ txd-delay = <3>;
+ };
+};
+
+&wmac {
+ status = "okay";
+
+ nvmem-cells = <&cal_art_1000>;
+ nvmem-cell-names = "calibration";
+};
diff --git a/target/linux/ath79/dts/qca9557_zyxel_nbg6616.dts b/target/linux/ath79/dts/qca9557_zyxel_nbg6616.dts
index 4372a07d51..828096f8f6 100644
--- a/target/linux/ath79/dts/qca9557_zyxel_nbg6616.dts
+++ b/target/linux/ath79/dts/qca9557_zyxel_nbg6616.dts
@@ -6,7 +6,7 @@
/ {
compatible = "zyxel,nbg6616", "qca,qca9557";
- model = "ZyXEL NBG6616";
+ model = "Zyxel NBG6616";
aliases {
led-boot = &led_power;
diff --git a/target/linux/ath79/dts/qca9558_sophos_ap15.dts b/target/linux/ath79/dts/qca9558_sophos_ap15.dts
deleted file mode 100644
index 7949d3e88f..0000000000
--- a/target/linux/ath79/dts/qca9558_sophos_ap15.dts
+++ /dev/null
@@ -1,163 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-
-#include "qca955x.dtsi"
-
-#include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/input/input.h>
-#include <dt-bindings/leds/common.h>
-
-/ {
- compatible = "sophos,ap15", "qca,qca9558";
- model = "Sophos AP15";
-
- aliases {
- led-boot = &led_status_green;
- led-failsafe = &led_status_yellow;
- led-running = &led_status_green;
- led-upgrade = &led_status_yellow;
- label-mac-device = &eth0;
- };
-
- chosen {
- bootargs = "console=ttyS0,115200n8";
- };
-
- leds {
- compatible = "gpio-leds";
-
- led_status_green: status_green {
- function = LED_FUNCTION_STATUS;
- color = <LED_COLOR_ID_GREEN>;
- gpios = <&gpio 13 GPIO_ACTIVE_LOW>;
- default-state = "on";
- };
-
- led_status_yellow: status_yellow {
- function = LED_FUNCTION_STATUS;
- color = <LED_COLOR_ID_YELLOW>;
- gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
- };
- };
-};
-
-&pcie0 {
- status = "okay";
-
- wifi@0,0 {
- compatible = "qcom,ath10k";
- reg = <0x0000 0 0 0 0>;
- nvmem-cells = <&cal_art_5000>;
- nvmem-cell-names = "calibration";
- };
-};
-
-&spi {
- status = "okay";
-
- flash@0 {
- compatible = "jedec,spi-nor";
- reg = <0>;
- spi-max-frequency = <25000000>;
-
- partitions {
- compatible = "fixed-partitions";
- #address-cells = <1>;
- #size-cells = <1>;
-
- partition@0 {
- label = "u-boot";
- reg = <0x000000 0x040000>;
- read-only;
- };
-
- partition@40000 {
- label = "u-boot-env";
- reg = <0x040000 0x010000>;
- };
-
- partition@50000 {
- label = "art";
- reg = <0x050000 0x010000>;
- read-only;
-
- nvmem-layout {
- compatible = "fixed-layout";
- #address-cells = <1>;
- #size-cells = <1>;
-
- cal_art_1000: calibration@1000 {
- reg = <0x1000 0x440>;
- };
-
- cal_art_5000: calibration@5000 {
- reg = <0x5000 0x844>;
- };
- };
- };
-
- partition@60000 {
- label = "config";
- reg = <0x060000 0x010000>;
- read-only;
-
- nvmem-layout {
- compatible = "fixed-layout";
- #address-cells = <1>;
- #size-cells = <1>;
-
- macaddr_config_201a: macaddr@201a {
- reg = <0x201a 0x6>;
- };
- };
- };
-
- partition@70000 {
- compatible = "denx,uimage";
- label = "firmware";
- reg = <0x070000 0xf90000>;
- };
- };
- };
-};
-
-&mdio0 {
- status = "okay";
-
- phy-mask = <0x10>;
-
- phy4: ethernet-phy@4 {
- reg = <4>;
- eee-broken-100tx;
- eee-broken-1000t;
- };
-};
-
-&eth0 {
- status = "okay";
-
- pll-data = <0xa6000000 0xa0000101 0xa0001313>;
-
- nvmem-cells = <&macaddr_config_201a>;
- nvmem-cell-names = "mac-address";
-
- phy-mode = "rgmii-id";
- phy-handle = <&phy4>;
-
- gmac_config: gmac-config {
- device = <&gmac>;
-
- rgmii-enabled = <1>;
-
- rxdv-delay = <3>;
- rxd-delay = <3>;
- txen-delay = <3>;
- txd-delay = <3>;
- };
-};
-
-&wmac {
- status = "okay";
-
- nvmem-cells = <&cal_art_1000>;
- nvmem-cell-names = "calibration";
-};
diff --git a/target/linux/ath79/dts/qca9558_zyxel_emg2926_q10a.dts b/target/linux/ath79/dts/qca9558_zyxel_emg2926_q10a.dts
index c00109a5b4..bf8d0f2f95 100644
--- a/target/linux/ath79/dts/qca9558_zyxel_emg2926_q10a.dts
+++ b/target/linux/ath79/dts/qca9558_zyxel_emg2926_q10a.dts
@@ -4,5 +4,5 @@
/ {
compatible = "zyxel,emg2926-q10a", "zyxel,nbg6716", "qca,qca9558";
- model = "ZyXEL EMG2926-Q10A";
+ model = "Zyxel EMG2926-Q10A";
};
diff --git a/target/linux/ath79/dts/qca9558_zyxel_nbg6716.dts b/target/linux/ath79/dts/qca9558_zyxel_nbg6716.dts
index 19f1245022..463553fe27 100644
--- a/target/linux/ath79/dts/qca9558_zyxel_nbg6716.dts
+++ b/target/linux/ath79/dts/qca9558_zyxel_nbg6716.dts
@@ -6,7 +6,7 @@
/ {
compatible = "zyxel,nbg6716", "qca,qca9558";
- model = "ZyXEL NBG6716";
+ model = "Zyxel NBG6716";
aliases {
led-boot = &led_power;
diff --git a/target/linux/ath79/dts/qca955x_elecom_wab.dtsi b/target/linux/ath79/dts/qca955x_elecom_wab.dtsi
index 43e34c6029..53bb5b0141 100644
--- a/target/linux/ath79/dts/qca955x_elecom_wab.dtsi
+++ b/target/linux/ath79/dts/qca955x_elecom_wab.dtsi
@@ -8,6 +8,7 @@
/ {
aliases {
+ label-mac-device = &eth0;
led-boot = &led_status;
led-failsafe = &led_status;
led-upgrade = &led_status;
@@ -107,6 +108,9 @@
phy-mode = "rgmii-rxid";
pll-data = <0xae000000 0x80000101 0x80001313>;
+ nvmem-cells = <&macaddr_uboot_ethaddr 0>;
+ nvmem-cell-names = "mac-address";
+
gmac-config {
device = <&gmac>;
@@ -144,8 +148,8 @@
wifi@0,0 {
compatible = "qcom,ath10k";
reg = <0x0000 0 0 0 0>;
- nvmem-cells = <&cal_art_5000>;
- nvmem-cell-names = "calibration";
+ nvmem-cells = <&cal_art_5000>, <&macaddr_uboot_ethaddr 1>;
+ nvmem-cell-names = "calibration", "mac-address";
};
};
@@ -169,9 +173,14 @@
};
partition@40000 {
+ compatible = "u-boot,env";
label = "u-boot-env";
reg = <0x40000 0x10000>;
read-only;
+
+ macaddr_uboot_ethaddr: ethaddr {
+ #nvmem-cell-cells = <1>;
+ };
};
partition@50000 {
@@ -252,6 +261,6 @@
&wmac {
status = "okay";
- nvmem-cells = <&cal_art_1000>;
- nvmem-cell-names = "calibration";
+ nvmem-cells = <&cal_art_1000>, <&macaddr_uboot_ethaddr 0>;
+ nvmem-cell-names = "calibration", "mac-address";
};
diff --git a/target/linux/ath79/dts/qca9561_nec_wf1200cr.dts b/target/linux/ath79/dts/qca9561_nec_wf1200cr.dts
index c4671bf57f..4e66f45ebe 100644
--- a/target/linux/ath79/dts/qca9561_nec_wf1200cr.dts
+++ b/target/linux/ath79/dts/qca9561_nec_wf1200cr.dts
@@ -114,6 +114,10 @@
#address-cells = <1>;
#size-cells = <1>;
+ cal_art_1000: calibration@1000 {
+ reg = <0x1000 0x440>;
+ };
+
precal_art_5000: pre-calibration@5000 {
reg = <0x5000 0x2f20>;
};
@@ -177,5 +181,6 @@
&wmac {
status = "okay";
- qca,no-eeprom;
+ nvmem-cells = <&cal_art_1000>;
+ nvmem-cell-names = "calibration";
};
diff --git a/target/linux/ath79/dts/qca9563_nec_wg1200cr.dts b/target/linux/ath79/dts/qca9563_nec_wg1200cr.dts
index 7f8866bd36..c9e47938d3 100644
--- a/target/linux/ath79/dts/qca9563_nec_wg1200cr.dts
+++ b/target/linux/ath79/dts/qca9563_nec_wg1200cr.dts
@@ -129,6 +129,10 @@
#address-cells = <1>;
#size-cells = <1>;
+ cal_art_1000: calibration@1000 {
+ reg = <0x1000 0x440>;
+ };
+
precal_art_5000: pre-calibration@5000 {
reg = <0x5000 0x2f20>;
};
@@ -178,5 +182,6 @@
&wmac {
status = "okay";
- qca,no-eeprom;
+ nvmem-cells = <&cal_art_1000>;
+ nvmem-cell-names = "calibration";
};
diff --git a/target/linux/ath79/dts/qca9563_nec_wg800hp.dts b/target/linux/ath79/dts/qca9563_nec_wg800hp.dts
index d2621fa304..d8ecf46201 100644
--- a/target/linux/ath79/dts/qca9563_nec_wg800hp.dts
+++ b/target/linux/ath79/dts/qca9563_nec_wg800hp.dts
@@ -142,6 +142,24 @@
#address-cells = <1>;
#size-cells = <1>;
+ macaddr_board_data_280: macaddr@280 {
+ compatible = "mac-base";
+ reg = <0x280 0x11>;
+ #nvmem-cell-cells = <1>;
+ };
+
+ macaddr_board_data_480: macaddr@480 {
+ compatible = "mac-base";
+ reg = <0x480 0x11>;
+ #nvmem-cell-cells = <1>;
+ };
+
+ macaddr_board_data_680: macaddr@680 {
+ compatible = "mac-base";
+ reg = <0x680 0x11>;
+ #nvmem-cell-cells = <1>;
+ };
+
macaddr_board_data_880: macaddr@880 {
compatible = "mac-base";
reg = <0x880 0x11>;
@@ -160,6 +178,10 @@
#address-cells = <1>;
#size-cells = <1>;
+ cal_art_1000: calibration@1000 {
+ reg = <0x1000 0x440>;
+ };
+
cal_art_5000: calibration@5000 {
reg = <0x5000 0x844>;
};
@@ -191,6 +213,9 @@
phy-mode = "sgmii";
phy-handle = <&phy0>;
+
+ nvmem-cells = <&macaddr_board_data_280 0>;
+ nvmem-cell-names = "mac-address";
};
&pcie {
@@ -206,5 +231,7 @@
&wmac {
status = "okay";
- qca,no-eeprom;
+
+ nvmem-cells = <&macaddr_board_data_680 0>, <&cal_art_1000>;
+ nvmem-cell-names = "mac-address", "calibration";
};
diff --git a/target/linux/ath79/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c b/target/linux/ath79/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c
index f63e93f978..c6fcea1abd 100644
--- a/target/linux/ath79/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c
+++ b/target/linux/ath79/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c
@@ -1162,33 +1162,10 @@ static int ag71xx_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
struct ag71xx *ag = netdev_priv(dev);
+ if (ag->phy_dev == NULL)
+ return -ENODEV;
- switch (cmd) {
- case SIOCSIFHWADDR:
- if (copy_from_user
- ((void*)dev->dev_addr, ifr->ifr_data, sizeof(dev->dev_addr)))
- return -EFAULT;
- return 0;
-
- case SIOCGIFHWADDR:
- if (copy_to_user
- (ifr->ifr_data, dev->dev_addr, sizeof(dev->dev_addr)))
- return -EFAULT;
- return 0;
-
- case SIOCGMIIPHY:
- case SIOCGMIIREG:
- case SIOCSMIIREG:
- if (ag->phy_dev == NULL)
- break;
-
- return phy_mii_ioctl(ag->phy_dev, ifr, cmd);
-
- default:
- break;
- }
-
- return -EOPNOTSUPP;
+ return phy_mii_ioctl(ag->phy_dev, ifr, cmd);
}
static void ag71xx_oom_timer_handler(struct timer_list *t)
@@ -1501,7 +1478,7 @@ static const struct net_device_ops ag71xx_netdev_ops = {
.ndo_open = ag71xx_open,
.ndo_stop = ag71xx_stop,
.ndo_start_xmit = ag71xx_hard_start_xmit,
- .ndo_do_ioctl = ag71xx_do_ioctl,
+ .ndo_eth_ioctl = ag71xx_do_ioctl,
.ndo_tx_timeout = ag71xx_tx_timeout,
.ndo_change_mtu = ag71xx_change_mtu,
.ndo_set_mac_address = eth_mac_addr,
diff --git a/target/linux/ath79/generic/base-files/etc/board.d/02_network b/target/linux/ath79/generic/base-files/etc/board.d/02_network
index 7905d6e496..742892a2f3 100644
--- a/target/linux/ath79/generic/base-files/etc/board.d/02_network
+++ b/target/linux/ath79/generic/base-files/etc/board.d/02_network
@@ -52,6 +52,7 @@ ath79_setup_interfaces()
glinet,gl-ar300m-lite|\
glinet,gl-usb150|\
hak5,wifi-pineapple-nano|\
+ huawei,ap6010dn|\
meraki,mr16|\
netgear,ex7300|\
netgear,ex7300-v2|\
@@ -711,9 +712,6 @@ ath79_setup_macs()
lan_mac=$(mtd_get_mac_ascii devdata "lanmac")
wan_mac=$(mtd_get_mac_ascii devdata "wanmac")
;;
- elecom,wab-i1750-ps|\
- elecom,wab-s1167-ps|\
- elecom,wab-s600-ps|\
engenius,ecb1200|\
engenius,ecb1750)
lan_mac=$(mtd_get_mac_ascii u-boot-env ethaddr)
@@ -783,7 +781,6 @@ ath79_setup_macs()
label_mac=$wan_mac
;;
nec,wg800hp)
- lan_mac=$(mtd_get_mac_text board_data 0x280)
wan_mac=$(mtd_get_mac_text board_data 0x480)
label_mac=$wan_mac
;;
diff --git a/target/linux/ath79/generic/base-files/etc/hotplug.d/firmware/10-ath9k-eeprom b/target/linux/ath79/generic/base-files/etc/hotplug.d/firmware/10-ath9k-eeprom
index ddcef7b685..6341c56a8b 100644
--- a/target/linux/ath79/generic/base-files/etc/hotplug.d/firmware/10-ath9k-eeprom
+++ b/target/linux/ath79/generic/base-files/etc/hotplug.d/firmware/10-ath9k-eeprom
@@ -30,8 +30,6 @@ case "$FIRMWARE" in
dlink,dir-842-c1|\
dlink,dir-842-c2|\
dlink,dir-842-c3|\
- nec,wf1200cr|\
- nec,wg1200cr|\
wd,mynet-n600|\
wd,mynet-n750)
caldata_extract "art" 0x1000 0x440
@@ -63,14 +61,6 @@ case "$FIRMWARE" in
caldata_extract "art" 0x1000 0x440
ath9k_patch_mac $(mtd_get_mac_ascii u-boot-env mac_addr)
;;
- nec,wg800hp)
- caldata_extract "art" 0x1000 0x440
- ath9k_patch_mac $(mtd_get_mac_text board_data 0x680)
- ;;
- qihoo,c301)
- caldata_extract "radiocfg" 0x1000 0x440
- ath9k_patch_mac $(mtd_get_mac_ascii devdata "wlan24mac")
- ;;
tplink,deco-s4-v2)
caldata_extract "art" 0x1000 0x440
base_mac=$(mtd_get_mac_encrypted_deco $(find_mtd_part config))
diff --git a/target/linux/ath79/generic/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac b/target/linux/ath79/generic/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac
index 2a1f230eb4..6676e4d509 100644
--- a/target/linux/ath79/generic/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac
+++ b/target/linux/ath79/generic/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac
@@ -42,16 +42,6 @@ case "$board" in
[ "$PHYNBR" -eq 1 ] && \
mtd_get_mac_ascii bdcfg "wlanmac" > /sys${DEVPATH}/macaddress
;;
- elecom,wab-i1750-ps|\
- elecom,wab-s1167-ps|\
- elecom,wab-s600-ps)
- # set the 5G MAC address (= ethaddr + 1)
- [ "$PHYNBR" -eq 0 ] && \
- macaddr_add "$(mtd_get_mac_ascii u-boot-env ethaddr)" 1 > /sys${DEVPATH}/macaddress
- # set the 2.4G MAC address (= ethaddr)
- [ "$PHYNBR" -eq 1 ] && \
- mtd_get_mac_ascii u-boot-env "ethaddr" > /sys${DEVPATH}/macaddress
- ;;
engenius,ecb1200|\
engenius,ecb1750)
[ "$PHYNBR" -eq 0 ] && \
@@ -93,6 +83,8 @@ case "$board" in
qihoo,c301)
[ "$PHYNBR" -eq 0 ] && \
mtd_get_mac_ascii devdata wlan5mac > /sys${DEVPATH}/macaddress
+ [ "$PHYNBR" -eq 1 ] && \
+ mtd_get_mac_ascii devdata wlan24mac > /sys${DEVPATH}/macaddress
;;
phicomm,k2t)
[ "$PHYNBR" -eq 0 ] && \
diff --git a/target/linux/ath79/generic/base-files/lib/upgrade/platform.sh b/target/linux/ath79/generic/base-files/lib/upgrade/platform.sh
index 076a785cbf..c61c48b00e 100644
--- a/target/linux/ath79/generic/base-files/lib/upgrade/platform.sh
+++ b/target/linux/ath79/generic/base-files/lib/upgrade/platform.sh
@@ -68,7 +68,8 @@ platform_do_upgrade() {
ROOTFS_FILE="root.squashfs"
platform_do_upgrade_failsafe_datachk "$1"
;;
- huawei,ap5030dn)
+ huawei,ap5030dn|\
+ huawei,ap6010dn)
# Store beginning address of the "firmware" partition
# as KernelA address and KernelB address, each to BootupA & BootupB
# This is the address from which the bootloader will try to load the kernel.
diff --git a/target/linux/ath79/image/common-nec.mk b/target/linux/ath79/image/common-nec.mk
new file mode 100644
index 0000000000..7981a72d8e
--- /dev/null
+++ b/target/linux/ath79/image/common-nec.mk
@@ -0,0 +1,25 @@
+DEVICE_VARS += NEC_FW_TYPE
+
+define Build/nec-usbaterm-fw
+ $(STAGING_DIR_HOST)/bin/nec-usbatermfw $@.new -t $(NEC_FW_TYPE) $(1)
+ mv $@.new $@
+endef
+
+define Device/nec-netbsd-aterm
+ DEVICE_VENDOR := NEC
+ LOADER_TYPE := bin
+ KERNEL := kernel-bin | append-dtb | lzma | loader-kernel | uImage none
+ KERNEL_INITRAMFS := kernel-bin | append-dtb | lzma | loader-kernel | uImage none
+ ARTIFACTS := uboot.bin
+ifneq ($(CONFIG_TARGET_ROOTFS_INITRAMFS),)
+ COMPILE := loader-$(1).bin
+ COMPILE/loader-$(1).bin := loader-okli-compile
+ ARTIFACTS += initramfs-factory.bin
+ ARTIFACT/initramfs-factory.bin := append-image-stage initramfs-kernel.bin | \
+ pad-to 4 skip=16 | \
+ nec-usbaterm-fw -f 0x0003 -d $$(KDIR)/loader-$(1).bin -d $$$$@ | check-size
+endif
+ UBOOT_PATH := $$(STAGING_DIR_IMAGE)/$$(SOC)_nec_aterm-u-boot.bin
+ ARTIFACT/uboot.bin := append-uboot | check-size 128k
+ DEVICE_PACKAGES := kmod-usb2 -uboot-envtools
+endef
diff --git a/target/linux/ath79/image/generic-ubnt.mk b/target/linux/ath79/image/generic-ubnt.mk
index f7bab4b697..2faf51949a 100644
--- a/target/linux/ath79/image/generic-ubnt.mk
+++ b/target/linux/ath79/image/generic-ubnt.mk
@@ -24,6 +24,7 @@ define Device/ubnt_amplifi-router-hd
UBNT_TYPE := AFi-R
UBNT_VERSION := 3.6.3
SOC := qca9563
+ DEVICE_VENDOR := Ubiquiti
DEVICE_MODEL := AmpliFi Router HD
UBNT_CHIP := qca956x
DEVICE_PACKAGES += kmod-ath10k-ct-smallbuffers ath10k-firmware-qca988x-ct kmod-usb2
diff --git a/target/linux/ath79/image/generic.mk b/target/linux/ath79/image/generic.mk
index f6dba8604d..459d595a42 100644
--- a/target/linux/ath79/image/generic.mk
+++ b/target/linux/ath79/image/generic.mk
@@ -1806,6 +1806,21 @@ define Device/huawei_ap5030dn
endef
TARGET_DEVICES += huawei_ap5030dn
+define Device/huawei_ap6010dn
+ SOC := ar9344
+ DEVICE_VENDOR := Huawei
+ DEVICE_MODEL := AP6010DN
+ LOADER_TYPE := bin
+ LOADER_FLASH_OFFS := 0x111DC0
+ KERNEL_SIZE := 15360k
+ IMAGE_SIZE := 30720k
+ COMPILE := loader-$(1).bin
+ COMPILE/loader-$(1).bin := loader-okli-compile | pad-to 64k | uImage none
+ KERNEL := kernel-bin | append-dtb | lzma | uImage lzma -M 0x4f4b4c49 | loader-okli $(1) 8128
+ KERNEL_INITRAMFS := kernel-bin | append-dtb | lzma | loader-kernel | uImage none
+endef
+TARGET_DEVICES += huawei_ap6010dn
+
define Device/iodata_etg3-r
SOC := ar9342
DEVICE_VENDOR := I-O DATA
@@ -2898,10 +2913,9 @@ endef
TARGET_DEVICES += sitecom_wlr-8100
define Device/sophos_ap15
- SOC := qca9558
+ SOC := qca9557
DEVICE_VENDOR := Sophos
DEVICE_MODEL := AP15
- DEVICE_PACKAGES := kmod-ath10k-ct ath10k-firmware-qca988x-ct
IMAGE_SIZE := 15936k
endef
TARGET_DEVICES += sophos_ap15
@@ -3248,7 +3262,7 @@ TARGET_DEVICES += zbtlink_zbt-wd323
define Device/zyxel_nwa11xx
$(Device/loader-okli-uimage)
SOC := ar9342
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
LOADER_FLASH_OFFS := 0x050000
KERNEL := kernel-bin | append-dtb | lzma | uImage lzma -M 0x4f4b4c49
IMAGE_SIZE := 8192k
@@ -3295,7 +3309,7 @@ TARGET_DEVICES += zyxel_nwa1123-ni
define Device/zyxel_nbg6616
SOC := qca9557
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
DEVICE_MODEL := NBG6616
DEVICE_PACKAGES := kmod-usb2 kmod-usb-ledtrig-usbport kmod-rtc-pcf8563 \
kmod-ath10k-ct ath10k-firmware-qca988x-ct
diff --git a/target/linux/ath79/image/lzma-loader/src/ar71xx_regs.h b/target/linux/ath79/image/lzma-loader/src/ar71xx_regs.h
index e7d7683973..9dc7c0f817 100644
--- a/target/linux/ath79/image/lzma-loader/src/ar71xx_regs.h
+++ b/target/linux/ath79/image/lzma-loader/src/ar71xx_regs.h
@@ -670,6 +670,7 @@
#define AR934X_GPIO_FUNC_SPI_CS_0_EN BIT(13)
#define AR934X_GPIO_OUT_GPIO 0x00
+#define AR934X_GPIO_OUTSEL_CLK_OBS4 0x14
#define QCA955X_GPIO_OUTSEL_CLK_OBS5 0x54
diff --git a/target/linux/ath79/image/lzma-loader/src/board.c b/target/linux/ath79/image/lzma-loader/src/board.c
index 13926e9b1e..0d92f3174b 100644
--- a/target/linux/ath79/image/lzma-loader/src/board.c
+++ b/target/linux/ath79/image/lzma-loader/src/board.c
@@ -182,34 +182,107 @@ static inline void mr18_init(void)
static inline void mr18_init(void) { }
#endif
-#ifdef CONFIG_BOARD_HUAWEI_AP5030DN
-static inline void ap5030dn_init(void)
+#if defined(CONFIG_BOARD_HUAWEI_AP5030DN) || defined(CONFIG_BOARD_HUAWEI_AP6010DN)
+static inline void huawei_ap_init(void)
{
- const unsigned int ap5030dn_watchdog_gpio = 15;
+ const unsigned int watchdog_gpio = 15;
unsigned int gpiobase, reg;
gpiobase = KSEG1ADDR(AR71XX_GPIO_BASE);
- printf("Huawei AP5030DN\n");
+ printf("Huawei AP\n");
reg = READREG(gpiobase + AR71XX_GPIO_REG_OE);
WRITEREG(gpiobase + AR71XX_GPIO_REG_OE,
- reg & ~(1 << ap5030dn_watchdog_gpio));
+ reg & ~(1 << watchdog_gpio));
/* Set GPIO15 MUX to output CLK_OBS5 (= CPU_CLK/4)
- * to keep the watchdog happy until wdt-gpio takes over
+ * or CLK_OBS4 (= AHB_CLK/2) to keep the watchdog happy
+ * until wdt-gpio takes over
*/
reg = READREG(gpiobase + AR934X_GPIO_REG_OUT_FUNC3);
+#if defined(CONFIG_BOARD_HUAWEI_AP5030DN)
WRITEREG(gpiobase + AR934X_GPIO_REG_OUT_FUNC3,
reg | (QCA955X_GPIO_OUTSEL_CLK_OBS5 << 24));
+#else if defined(CONFIG_BOARD_HUAWEI_AP6010DN)
+ WRITEREG(gpiobase + AR934X_GPIO_REG_OUT_FUNC3,
+ reg | (AR934X_GPIO_OUTSEL_CLK_OBS4 << 24));
+#endif
+}
+#else
+static inline void huawei_ap_init(void) {}
+#endif
+
+#if defined(CONFIG_BOARD_NEC_WG600HP) || \
+ defined(CONFIG_BOARD_NEC_WR8750N) || \
+ defined(CONFIG_BOARD_NEC_WR9500N)
+
+#define AR934X_PLL_SWITCH_CLK_CTRL_REG 0x24
+#define AR934X_PLL_SWITCH_CLK_CTRL_SWITCHCLK_SEL BIT(0)
+
+static inline void nec_aterm_init(void)
+{
+ unsigned int reg, val;
+
+ printf("NEC Aterm series (AR9344)\n");
+
+ /* set REFCLK=40MHz to switch PLL */
+ reg = KSEG1ADDR(AR71XX_PLL_BASE);
+ val = READREG(reg + AR934X_PLL_SWITCH_CLK_CTRL_REG);
+ val &= ~AR934X_PLL_SWITCH_CLK_CTRL_SWITCHCLK_SEL;
+ WRITEREG(reg + AR934X_PLL_SWITCH_CLK_CTRL_REG, val);
+
+ reg = KSEG1ADDR(AR71XX_RESET_BASE);
+#ifndef LOADADDR
+ /*
+ * This is for initramfs-factory image.
+ * When the system was reset by power source or FULL_CHIP_RESET
+ * and started from the OEM bootloader with a dummy tp data
+ * (this loader), reset again by timeout of the watchdog timer
+ * to load an actual OpenWrt initramfs image in firmware block
+ * in a factory image.
+ * Note: On the stock firmware, TP block contains a POST function
+ * and sub commands of "tp" command.
+ *
+ * Behaviors of OEM bootloader:
+ *
+ * - reset by watchdog (ex.: rebooting on the stock firmware):
+ * called as "SOFT-RESET", boot a firmware without POST
+ *
+ * - reset by FULL_CHIP_RESET (or powering on):
+ * called as "HARD-RESET", run POST and boot a firmware
+ */
+ printf("\n## booted with dummy tp (lzma-loader),"
+ " waiting reset... (count: 0x%08x) ##\n",
+ READREG(reg + AR71XX_RESET_REG_WDOG));
+ while (1);
+#endif
+ /*
+ * set maximum watchdog count to avoid reset while
+ * booting from stock bootloader
+ */
+ WRITEREG(reg + AR71XX_RESET_REG_WDOG, 0xffffffff);
+
+ /*
+ * deassert some RESET bits not handled by drivers
+ * and mainline U-Boot
+ *
+ * - ETH_SWITCH(_ANALOG): eth0
+ * - RTC : wmac
+ */
+ val = READREG(reg + AR934X_RESET_REG_RESET_MODULE);
+ val &= ~(AR934X_RESET_ETH_SWITCH | AR934X_RESET_ETH_SWITCH_ANALOG |
+ AR934X_RESET_RTC);
+ WRITEREG(reg + AR934X_RESET_REG_RESET_MODULE, val);
}
#else
-static inline void ap5030dn_init(void) { }
+static inline void nec_aterm_init(void) {}
#endif
void board_init(void)
{
tlwr1043nd_init();
mr18_init();
- ap5030dn_init();
+ huawei_ap_init();
+ nec_aterm_init();
}
diff --git a/target/linux/ath79/image/nand.mk b/target/linux/ath79/image/nand.mk
index 1a7eebc92a..a3bdedaf6d 100644
--- a/target/linux/ath79/image/nand.mk
+++ b/target/linux/ath79/image/nand.mk
@@ -487,7 +487,7 @@ TARGET_DEVICES += zte_mf286r
define Device/zyxel_nbg6716
SOC := qca9558
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
DEVICE_MODEL := NBG6716
DEVICE_PACKAGES := kmod-usb2 kmod-usb-ledtrig-usbport kmod-ath10k-ct \
ath10k-firmware-qca988x-ct
diff --git a/target/linux/ath79/image/tiny.mk b/target/linux/ath79/image/tiny.mk
index 955d0fbff2..53111119d8 100644
--- a/target/linux/ath79/image/tiny.mk
+++ b/target/linux/ath79/image/tiny.mk
@@ -1,4 +1,5 @@
include ./common-buffalo.mk
+include ./common-nec.mk
include ./common-senao.mk
define Device/buffalo_whr-g301n
@@ -120,6 +121,36 @@ define Device/engenius_enh202-v1
endef
TARGET_DEVICES += engenius_enh202-v1
+define Device/nec_wg600hp
+ DEVICE_MODEL := Aterm WG600HP
+ SOC := ar9344
+ BLOCKSIZE := 4k
+ IMAGE_SIZE := 7936k
+ NEC_FW_TYPE := H044
+ $(Device/nec-netbsd-aterm)
+endef
+TARGET_DEVICES += nec_wg600hp
+
+define Device/nec_wr8750n
+ SOC := ar9344
+ DEVICE_MODEL := Aterm WR8750N
+ BLOCKSIZE := 4k
+ IMAGE_SIZE := 7936k
+ NEC_FW_TYPE := H033a
+ $(Device/nec-netbsd-aterm)
+endef
+TARGET_DEVICES += nec_wr8750n
+
+define Device/nec_wr9500n
+ SOC := ar9344
+ DEVICE_MODEL := Aterm WR9500N
+ BLOCKSIZE := 4k
+ IMAGE_SIZE := 16128k
+ NEC_FW_TYPE := H033
+ $(Device/nec-netbsd-aterm)
+endef
+TARGET_DEVICES += nec_wr9500n
+
define Device/pqi_air-pen
SOC := ar9330
DEVICE_VENDOR := PQI
diff --git a/target/linux/ath79/patches-6.6/317-MIPS-pci-ar724x-clear-power-down-of-pll-on-AR934x.patch b/target/linux/ath79/patches-6.6/317-MIPS-pci-ar724x-clear-power-down-of-pll-on-AR934x.patch
new file mode 100644
index 0000000000..dfb7e483a7
--- /dev/null
+++ b/target/linux/ath79/patches-6.6/317-MIPS-pci-ar724x-clear-power-down-of-pll-on-AR934x.patch
@@ -0,0 +1,34 @@
+From f2ca10b22ace3ce53b4e3f189bf1dd53a4482475 Mon Sep 17 00:00:00 2001
+From: INAGAKI Hiroshi <musashino.open@gmail.com>
+Date: Fri, 26 Apr 2024 23:53:58 +0900
+Subject: [PATCH 1/2] MIPS: pci-ar724x: clear power down of pll on AR934x
+
+Fix PCIe initialization on AR934x by clearing PLL_PWD bit in addition to
+PPL_RESET bit of AR724x.
+
+Signed-off-by: INAGAKI Hiroshi <musashino.open@gmail.com>
+---
+
+--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
++++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
+@@ -347,6 +347,8 @@
+ #define AR934X_PLL_CPU_DDR_CLK_CTRL_DDRCLK_FROM_DDRPLL BIT(21)
+ #define AR934X_PLL_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL BIT(24)
+
++#define AR934X_PLL_PCIE_CONFIG_PLL_PWD BIT(30)
++
+ #define AR934X_PLL_SWITCH_CLOCK_CONTROL_MDIO_CLK_SEL BIT(6)
+
+ #define QCA953X_PLL_CPU_CONFIG_REG 0x00
+--- a/arch/mips/pci/pci-ar724x.c
++++ b/arch/mips/pci/pci-ar724x.c
+@@ -360,7 +360,8 @@ static void ar724x_pci_hw_init(struct ar
+ } else {
+ /* remove the reset of the PCIE PLL */
+ ppl = ath79_pll_rr(AR724X_PLL_REG_PCIE_CONFIG);
+- ppl &= ~AR724X_PLL_REG_PCIE_CONFIG_PPL_RESET;
++ ppl &= ~(AR934X_PLL_PCIE_CONFIG_PLL_PWD |
++ AR724X_PLL_REG_PCIE_CONFIG_PPL_RESET);
+ ath79_pll_wr(AR724X_PLL_REG_PCIE_CONFIG, ppl);
+
+ /* deassert bypass for the PCIE PLL */
diff --git a/target/linux/ath79/patches-6.6/318-MIPS-pci-ar724x-deassert-the-reset-of-PCIe-endpoint.patch b/target/linux/ath79/patches-6.6/318-MIPS-pci-ar724x-deassert-the-reset-of-PCIe-endpoint.patch
new file mode 100644
index 0000000000..c906bdbbb6
--- /dev/null
+++ b/target/linux/ath79/patches-6.6/318-MIPS-pci-ar724x-deassert-the-reset-of-PCIe-endpoint.patch
@@ -0,0 +1,41 @@
+From 859c93981a8994ffa69967b44b247d2e7d6a01f1 Mon Sep 17 00:00:00 2001
+From: INAGAKI Hiroshi <musashino.open@gmail.com>
+Date: Fri, 26 Apr 2024 23:54:57 +0900
+Subject: [PATCH 2/2] MIPS: pci-ar724x: deassert the reset of PCIe endpoint
+
+Fix PCIe initialization by de-assertion of PCIe endpoint reset.
+
+Signed-off-by: INAGAKI Hiroshi <musashino.open@gmail.com>
+---
+
+--- a/arch/mips/pci/pci-ar724x.c
++++ b/arch/mips/pci/pci-ar724x.c
+@@ -25,6 +25,7 @@
+
+ #define AR724X_PCI_APP_LTSSM_ENABLE BIT(0)
+
++#define AR724X_PCI_RESET_EP_RESET_L BIT(2)
+ #define AR724X_PCI_RESET_LINK_UP BIT(0)
+
+ #define AR724X_PCI_INT_DEV0 BIT(14)
+@@ -340,7 +341,7 @@ static void ar724x_pci_irq_init(struct a
+
+ static void ar724x_pci_hw_init(struct ar724x_pci_controller *apc)
+ {
+- u32 ppl, app;
++ u32 ppl, rst, app;
+ int wait = 0;
+
+ /* deassert PCIe host controller and PCIe PHY reset */
+@@ -370,6 +371,11 @@ static void ar724x_pci_hw_init(struct ar
+ ath79_pll_wr(AR724X_PLL_REG_PCIE_CONFIG, ppl);
+ }
+
++ /* deassert the reset state of the PCIE endpoint */
++ rst = __raw_readl(apc->ctrl_base + AR724X_PCI_REG_RESET);
++ rst |= AR724X_PCI_RESET_EP_RESET_L;
++ __raw_writel(rst, apc->ctrl_base + AR724X_PCI_REG_RESET);
++
+ /* set PCIE Application Control to ready */
+ app = __raw_readl(apc->ctrl_base + AR724X_PCI_REG_APP);
+ app |= AR724X_PCI_APP_LTSSM_ENABLE;
diff --git a/target/linux/ath79/patches-6.6/330-missing-registers.patch b/target/linux/ath79/patches-6.6/330-missing-registers.patch
index 74789437ec..d05e741c7e 100644
--- a/target/linux/ath79/patches-6.6/330-missing-registers.patch
+++ b/target/linux/ath79/patches-6.6/330-missing-registers.patch
@@ -7,7 +7,7 @@ Subject: [PATCH] ath79: gmac: add parsers for rxd(v)- and tx(d|en)-delay for
--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
+++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
-@@ -1231,6 +1231,10 @@
+@@ -1233,6 +1233,10 @@
#define AR934X_ETH_CFG_RDV_DELAY BIT(16)
#define AR934X_ETH_CFG_RDV_DELAY_MASK 0x3
#define AR934X_ETH_CFG_RDV_DELAY_SHIFT 16
diff --git a/target/linux/ath79/patches-6.6/331-MIPS-ath79-add-missing-QCA955x-GMAC-registers.patch b/target/linux/ath79/patches-6.6/331-MIPS-ath79-add-missing-QCA955x-GMAC-registers.patch
index c2f228dfe1..5d9c77c69f 100644
--- a/target/linux/ath79/patches-6.6/331-MIPS-ath79-add-missing-QCA955x-GMAC-registers.patch
+++ b/target/linux/ath79/patches-6.6/331-MIPS-ath79-add-missing-QCA955x-GMAC-registers.patch
@@ -16,7 +16,7 @@ Signed-off-by: David Bauer <mail@david-bauer.net>
--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
+++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
-@@ -1251,7 +1251,12 @@
+@@ -1253,7 +1253,12 @@
*/
#define QCA955X_GMAC_REG_ETH_CFG 0x00
@@ -29,7 +29,7 @@ Signed-off-by: David Bauer <mail@david-bauer.net>
#define QCA955X_ETH_CFG_RGMII_EN BIT(0)
#define QCA955X_ETH_CFG_MII_GE0 BIT(1)
-@@ -1273,9 +1278,58 @@
+@@ -1275,9 +1280,58 @@
#define QCA955X_ETH_CFG_TXE_DELAY_MASK 0x3
#define QCA955X_ETH_CFG_TXE_DELAY_SHIFT 20
diff --git a/target/linux/ath79/patches-6.6/332-ath79-sgmii-config.patch b/target/linux/ath79/patches-6.6/332-ath79-sgmii-config.patch
index a6a50e4a8a..6f6217ce75 100644
--- a/target/linux/ath79/patches-6.6/332-ath79-sgmii-config.patch
+++ b/target/linux/ath79/patches-6.6/332-ath79-sgmii-config.patch
@@ -21,7 +21,7 @@ Submitted-by: David Bauer <mail@david-bauer.net>
--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
+++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
-@@ -1380,5 +1380,6 @@
+@@ -1382,5 +1382,6 @@
#define QCA956X_SGMII_CONFIG_MODE_CTRL_SHIFT 0
#define QCA956X_SGMII_CONFIG_MODE_CTRL_MASK 0x7
diff --git a/target/linux/ath79/patches-6.6/340-register_gpio_driver_earlier.patch b/target/linux/ath79/patches-6.6/340-register_gpio_driver_earlier.patch
new file mode 100644
index 0000000000..a3bdf890c4
--- /dev/null
+++ b/target/linux/ath79/patches-6.6/340-register_gpio_driver_earlier.patch
@@ -0,0 +1,26 @@
+From: John Crispin <john@phrozen.org>
+Subject: ath79: Register GPIO driver earlier
+
+HACK: register the GPIO driver earlier to ensure that gpio_request calls
+from mach files succeed.
+
+Submitted-by: John Crispin <john@phrozen.org>
+---
+ drivers/gpio/gpio-ath79.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpio/gpio-ath79.c
++++ b/drivers/gpio/gpio-ath79.c
+@@ -300,7 +300,11 @@ static struct platform_driver ath79_gpio
+ .probe = ath79_gpio_probe,
+ };
+
+-module_platform_driver(ath79_gpio_driver);
++static int __init ath79_gpio_init(void)
++{
++ return platform_driver_register(&ath79_gpio_driver);
++}
++postcore_initcall(ath79_gpio_init);
+
+ MODULE_DESCRIPTION("Atheros AR71XX/AR724X/AR913X GPIO API support");
+ MODULE_LICENSE("GPL v2");
diff --git a/target/linux/ath79/patches-6.6/360-MIPS-ath79-export-UART1-reference-clock.patch b/target/linux/ath79/patches-6.6/360-MIPS-ath79-export-UART1-reference-clock.patch
index b24ff21692..ae2f5aa0cd 100644
--- a/target/linux/ath79/patches-6.6/360-MIPS-ath79-export-UART1-reference-clock.patch
+++ b/target/linux/ath79/patches-6.6/360-MIPS-ath79-export-UART1-reference-clock.patch
@@ -45,8 +45,8 @@ Submitted-by: Daniel Golle <daniel@makrotopia.org>
goto err_iounmap;
--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
+++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
-@@ -348,6 +348,7 @@
- #define AR934X_PLL_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL BIT(24)
+@@ -350,6 +350,7 @@
+ #define AR934X_PLL_PCIE_CONFIG_PLL_PWD BIT(30)
#define AR934X_PLL_SWITCH_CLOCK_CONTROL_MDIO_CLK_SEL BIT(6)
+#define AR934X_PLL_SWITCH_CLOCK_CONTROL_UART1_CLK_SEL BIT(7)
diff --git a/target/linux/ath79/patches-6.6/430-mtd-ar934x-nand-driver.patch b/target/linux/ath79/patches-6.6/430-mtd-ar934x-nand-driver.patch
index 603750cbe9..fc4c3804a7 100644
--- a/target/linux/ath79/patches-6.6/430-mtd-ar934x-nand-driver.patch
+++ b/target/linux/ath79/patches-6.6/430-mtd-ar934x-nand-driver.patch
@@ -9,7 +9,7 @@ SVN-Revision: 33385
--- a/drivers/mtd/nand/raw/Kconfig
+++ b/drivers/mtd/nand/raw/Kconfig
-@@ -543,4 +543,12 @@ config MTD_NAND_DISKONCHIP_BBTWRITE
+@@ -542,4 +542,12 @@ config MTD_NAND_DISKONCHIP_BBTWRITE
load time (assuming you build diskonchip as a module) with the module
parameter "inftl_bbt_write=1".
diff --git a/target/linux/ath79/patches-6.6/810-ath79-ignore-the-abused-interrupt-map-on-pcie-node.patch b/target/linux/ath79/patches-6.6/810-ath79-ignore-the-abused-interrupt-map-on-pcie-node.patch
index 980c265fe6..330c0d139b 100644
--- a/target/linux/ath79/patches-6.6/810-ath79-ignore-the-abused-interrupt-map-on-pcie-node.patch
+++ b/target/linux/ath79/patches-6.6/810-ath79-ignore-the-abused-interrupt-map-on-pcie-node.patch
@@ -22,7 +22,7 @@ Signed-off-by: Shiji Yang <yangshiji66@outlook.com>
--- a/drivers/of/irq.c
+++ b/drivers/of/irq.c
-@@ -86,6 +86,8 @@ EXPORT_SYMBOL_GPL(of_irq_find_parent);
+@@ -89,6 +89,8 @@ EXPORT_SYMBOL_GPL(of_irq_find_parent);
* drawing board.
*/
static const char * const of_irq_imap_abusers[] = {
diff --git a/target/linux/ath79/patches-6.6/900-unaligned_access_hacks.patch b/target/linux/ath79/patches-6.6/900-unaligned_access_hacks.patch
index df672946d8..46811ab21c 100644
--- a/target/linux/ath79/patches-6.6/900-unaligned_access_hacks.patch
+++ b/target/linux/ath79/patches-6.6/900-unaligned_access_hacks.patch
@@ -259,7 +259,7 @@ SVN-Revision: 35130
#include <linux/uaccess.h>
#include <linux/ipv6.h>
#include <linux/icmpv6.h>
-@@ -897,10 +898,10 @@ static void tcp_v6_send_response(const s
+@@ -893,10 +894,10 @@ static void tcp_v6_send_response(const s
topt = (__be32 *)(t1 + 1);
if (tsecr) {
@@ -350,7 +350,7 @@ SVN-Revision: 35130
list_for_each_entry(p, head, list) {
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
-@@ -620,48 +620,53 @@ static void tcp_options_write(struct tcp
+@@ -622,48 +622,53 @@ static void tcp_options_write(struct tcp
u16 options = opts->options; /* mungable copy */
if (unlikely(OPTION_MD5 & options)) {
@@ -427,7 +427,7 @@ SVN-Revision: 35130
}
if (unlikely(opts->num_sack_blocks)) {
-@@ -669,16 +674,17 @@ static void tcp_options_write(struct tcp
+@@ -671,16 +676,17 @@ static void tcp_options_write(struct tcp
tp->duplicate_sack : tp->selective_acks;
int this_sack;
@@ -451,7 +451,7 @@ SVN-Revision: 35130
}
tp->rx_opt.dsack = 0;
-@@ -691,13 +697,14 @@ static void tcp_options_write(struct tcp
+@@ -693,13 +699,14 @@ static void tcp_options_write(struct tcp
if (foc->exp) {
len = TCPOLEN_EXP_FASTOPEN_BASE + foc->len;
@@ -751,7 +751,7 @@ SVN-Revision: 35130
EXPORT_SYMBOL(xfrm_parse_spi);
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
-@@ -4205,14 +4205,16 @@ static bool tcp_parse_aligned_timestamp(
+@@ -4221,14 +4221,16 @@ static bool tcp_parse_aligned_timestamp(
{
const __be32 *ptr = (const __be32 *)(th + 1);
@@ -867,7 +867,7 @@ SVN-Revision: 35130
iph->daddr == iph2->daddr && iph->saddr == iph2->saddr)
return segs;
-@@ -255,7 +255,7 @@ struct sk_buff *tcp_gro_lookup(struct li
+@@ -258,7 +258,7 @@ struct sk_buff *tcp_gro_lookup(struct li
continue;
th2 = tcp_hdr(p);
@@ -876,7 +876,7 @@ SVN-Revision: 35130
NAPI_GRO_CB(p)->same_flow = 0;
continue;
}
-@@ -321,8 +321,8 @@ struct sk_buff *tcp_gro_receive(struct l
+@@ -324,8 +324,8 @@ struct sk_buff *tcp_gro_receive(struct l
~(TCP_FLAG_CWR | TCP_FLAG_FIN | TCP_FLAG_PSH));
flush |= (__force int)(th->ack_seq ^ th2->ack_seq);
for (i = sizeof(*th); i < thlen; i += 4)
diff --git a/target/linux/ath79/patches-6.6/910-mikrotik-rb4xx.patch b/target/linux/ath79/patches-6.6/910-mikrotik-rb4xx.patch
index 980f29eef1..674cc2fe66 100644
--- a/target/linux/ath79/patches-6.6/910-mikrotik-rb4xx.patch
+++ b/target/linux/ath79/patches-6.6/910-mikrotik-rb4xx.patch
@@ -97,7 +97,7 @@ Submitted-by: Christopher Hill <ch6574@gmail.com>
obj-$(CONFIG_GPIO_RDA) += gpio-rda.o
--- a/drivers/mtd/nand/raw/Kconfig
+++ b/drivers/mtd/nand/raw/Kconfig
-@@ -551,4 +551,11 @@ config MTD_NAND_AR934X
+@@ -550,4 +550,11 @@ config MTD_NAND_AR934X
Enables support for NAND controller on Qualcomm Atheros SoCs.
This controller is found on AR934x and QCA955x SoCs.
diff --git a/target/linux/ath79/patches-6.6/911-mikrotik-rb91x.patch b/target/linux/ath79/patches-6.6/911-mikrotik-rb91x.patch
index e610a4ff14..ddb7b52cbe 100644
--- a/target/linux/ath79/patches-6.6/911-mikrotik-rb91x.patch
+++ b/target/linux/ath79/patches-6.6/911-mikrotik-rb91x.patch
@@ -73,7 +73,7 @@ Tested-by: Koen Vandeputte <koen.vandeputte@ncentric.com>
obj-$(CONFIG_GPIO_RDA) += gpio-rda.o
--- a/drivers/mtd/nand/raw/Kconfig
+++ b/drivers/mtd/nand/raw/Kconfig
-@@ -558,4 +558,10 @@ config MTD_NAND_RB4XX
+@@ -557,4 +557,10 @@ config MTD_NAND_RB4XX
Enables support for the NAND flash chip on Mikrotik Routerboard
RB4xx series.
diff --git a/target/linux/ath79/tiny/base-files/etc/board.d/02_network b/target/linux/ath79/tiny/base-files/etc/board.d/02_network
index fa2ea3aa6f..a204e820ca 100644
--- a/target/linux/ath79/tiny/base-files/etc/board.d/02_network
+++ b/target/linux/ath79/tiny/base-files/etc/board.d/02_network
@@ -69,6 +69,13 @@ ath79_setup_interfaces()
ucidef_add_switch "switch0" \
"0@eth1" "4:lan:1"
;;
+ nec,wg600hp|\
+ nec,wr8750n|\
+ nec,wr9500n|\
+ tplink,tl-wr941n-v7-cn)
+ ucidef_add_switch "switch0" \
+ "0@eth0" "2:lan:1" "3:lan:2" "4:lan:3" "5:lan:4" "1:wan"
+ ;;
tplink,tl-mr3220-v1|\
tplink,tl-mr3420-v1|\
tplink,tl-mr3420-v3|\
@@ -105,10 +112,6 @@ ath79_setup_interfaces()
tplink,tl-wr941-v2)
ucidef_set_interfaces_lan_wan "lan1 lan2 lan3 lan4" "wan"
;;
- tplink,tl-wr941n-v7-cn)
- ucidef_add_switch "switch0" \
- "0@eth0" "2:lan:1" "3:lan:2" "4:lan:3" "5:lan:4" "1:wan"
- ;;
ubnt,airrouter)
ucidef_set_interface_wan "eth1"
ucidef_add_switch "switch0" \
@@ -152,6 +155,12 @@ ath79_setup_macs()
ubnt,picostation-m)
label_mac=$(cat /sys/class/ieee80211/phy0/macaddress)
;;
+ nec,wg600hp|\
+ nec,wr8750n|\
+ nec,wr9500n)
+ wan_mac=$(mtd_get_mac_binary config 0xc)
+ label_mac=$wan_mac
+ ;;
tplink,tl-wr941-v2|\
tplink,tl-wr941n-v7-cn)
base_mac=$(mtd_get_mac_binary u-boot 0x1fc00)
diff --git a/target/linux/ath79/tiny/base-files/lib/upgrade/platform.sh b/target/linux/ath79/tiny/base-files/lib/upgrade/platform.sh
index eb8441c6d2..8fc0efcfbd 100644
--- a/target/linux/ath79/tiny/base-files/lib/upgrade/platform.sh
+++ b/target/linux/ath79/tiny/base-files/lib/upgrade/platform.sh
@@ -9,7 +9,23 @@ RAMFS_COPY_BIN='fw_setenv'
RAMFS_COPY_DATA='/etc/fw_env.config'
platform_check_image() {
- return 0
+ local board=$(board_name)
+
+ case "$board" in
+ nec,wg600hp|\
+ nec,wr8750n|\
+ nec,wr9500n)
+ local uboot_mtd=$(find_mtd_part "bootloader")
+
+ # check "U-Boot <year>.<month>" string in the "bootloader" partition
+ if ! grep -q "U-Boot [0-9]\{4\}\.[0-9]\{2\}" $uboot_mtd; then
+ v "The bootloader doesn't seem to be replaced to U-Boot!"
+ return 1
+ fi
+ ;;
+ *)
+ return 0
+ esac
}
platform_do_upgrade() {
diff --git a/target/linux/bcm27xx/bcm2708/config-6.6 b/target/linux/bcm27xx/bcm2708/config-6.6
index cd978837ea..a50596e45e 100644
--- a/target/linux/bcm27xx/bcm2708/config-6.6
+++ b/target/linux/bcm27xx/bcm2708/config-6.6
@@ -142,8 +142,6 @@ CONFIG_EDAC_ATOMIC_SCRUB=y
CONFIG_EDAC_SUPPORT=y
CONFIG_EXCLUSIVE_SYSTEM_RAM=y
CONFIG_EXT4_FS=y
-CONFIG_EXT4_FS_POSIX_ACL=y
-CONFIG_EXT4_FS_SECURITY=y
CONFIG_EXTCON=y
CONFIG_F2FS_FS=y
CONFIG_FB=y
@@ -168,7 +166,6 @@ CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
CONFIG_FREEZER=y
CONFIG_FS_IOMAP=y
CONFIG_FS_MBCACHE=y
-CONFIG_FS_POSIX_ACL=y
CONFIG_FUNCTION_ALIGNMENT=0
CONFIG_FWNODE_MDIO=y
CONFIG_FW_CACHE=y
@@ -372,7 +369,6 @@ CONFIG_TICK_CPU_ACCOUNTING=y
CONFIG_TIMER_OF=y
CONFIG_TIMER_PROBE=y
CONFIG_TINY_SRCU=y
-CONFIG_TMPFS_POSIX_ACL=y
CONFIG_UEVENT_HELPER_PATH=""
# CONFIG_UID16 is not set
CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
diff --git a/target/linux/bcm27xx/bcm2709/config-6.6 b/target/linux/bcm27xx/bcm2709/config-6.6
index 1a034b3e71..23e93241df 100644
--- a/target/linux/bcm27xx/bcm2709/config-6.6
+++ b/target/linux/bcm27xx/bcm2709/config-6.6
@@ -180,8 +180,6 @@ CONFIG_EDAC_ATOMIC_SCRUB=y
CONFIG_EDAC_SUPPORT=y
CONFIG_EXCLUSIVE_SYSTEM_RAM=y
CONFIG_EXT4_FS=y
-CONFIG_EXT4_FS_POSIX_ACL=y
-CONFIG_EXT4_FS_SECURITY=y
CONFIG_EXTCON=y
CONFIG_F2FS_FS=y
CONFIG_FB=y
@@ -208,7 +206,6 @@ CONFIG_FS_ENCRYPTION=y
CONFIG_FS_ENCRYPTION_ALGS=y
CONFIG_FS_IOMAP=y
CONFIG_FS_MBCACHE=y
-CONFIG_FS_POSIX_ACL=y
CONFIG_FUNCTION_ALIGNMENT=0
CONFIG_FWNODE_MDIO=y
CONFIG_FW_CACHE=y
@@ -466,7 +463,6 @@ CONFIG_THREAD_INFO_IN_TASK=y
CONFIG_TICK_CPU_ACCOUNTING=y
CONFIG_TIMER_OF=y
CONFIG_TIMER_PROBE=y
-CONFIG_TMPFS_POSIX_ACL=y
CONFIG_TREE_RCU=y
CONFIG_TREE_SRCU=y
# CONFIG_UCLAMP_TASK is not set
diff --git a/target/linux/bcm27xx/bcm2710/config-6.6 b/target/linux/bcm27xx/bcm2710/config-6.6
index 4ab0e03ee2..5b7d6ae4f1 100644
--- a/target/linux/bcm27xx/bcm2710/config-6.6
+++ b/target/linux/bcm27xx/bcm2710/config-6.6
@@ -23,8 +23,6 @@ CONFIG_ARCH_WANTS_NO_INSTR=y
CONFIG_ARCH_WANTS_THP_SWAP=y
CONFIG_ARM64=y
CONFIG_ARM64_4K_PAGES=y
-CONFIG_ARM64_CNP=y
-CONFIG_ARM64_EPAN=y
CONFIG_ARM64_ERRATUM_819472=y
CONFIG_ARM64_ERRATUM_824069=y
CONFIG_ARM64_ERRATUM_826319=y
@@ -34,7 +32,6 @@ CONFIG_ARM64_ERRATUM_843419=y
CONFIG_ARM64_HW_AFDBM=y
CONFIG_ARM64_LD_HAS_FIX_ERRATUM_843419=y
CONFIG_ARM64_PAGE_SHIFT=12
-CONFIG_ARM64_PAN=y
CONFIG_ARM64_PA_BITS=48
CONFIG_ARM64_PA_BITS_48=y
CONFIG_ARM64_PTR_AUTH=y
@@ -188,8 +185,6 @@ CONFIG_DUMMY_CONSOLE=y
CONFIG_EDAC_SUPPORT=y
CONFIG_EXCLUSIVE_SYSTEM_RAM=y
CONFIG_EXT4_FS=y
-CONFIG_EXT4_FS_POSIX_ACL=y
-CONFIG_EXT4_FS_SECURITY=y
CONFIG_EXTCON=y
CONFIG_F2FS_FS=y
CONFIG_FB=y
@@ -217,7 +212,6 @@ CONFIG_FS_ENCRYPTION=y
CONFIG_FS_ENCRYPTION_ALGS=y
CONFIG_FS_IOMAP=y
CONFIG_FS_MBCACHE=y
-CONFIG_FS_POSIX_ACL=y
CONFIG_FUNCTION_ALIGNMENT=4
CONFIG_FUNCTION_ALIGNMENT_4B=y
CONFIG_FWNODE_MDIO=y
@@ -465,7 +459,6 @@ CONFIG_THREAD_INFO_IN_TASK=y
CONFIG_TICK_CPU_ACCOUNTING=y
CONFIG_TIMER_OF=y
CONFIG_TIMER_PROBE=y
-CONFIG_TMPFS_POSIX_ACL=y
CONFIG_TRACE_IRQFLAGS_NMI_SUPPORT=y
CONFIG_TREE_RCU=y
CONFIG_TREE_SRCU=y
diff --git a/target/linux/bcm27xx/bcm2711/config-6.6 b/target/linux/bcm27xx/bcm2711/config-6.6
index 915fe29cae..33458c27d7 100644
--- a/target/linux/bcm27xx/bcm2711/config-6.6
+++ b/target/linux/bcm27xx/bcm2711/config-6.6
@@ -23,13 +23,10 @@ CONFIG_ARCH_WANTS_NO_INSTR=y
CONFIG_ARCH_WANTS_THP_SWAP=y
CONFIG_ARM64=y
CONFIG_ARM64_4K_PAGES=y
-CONFIG_ARM64_CNP=y
-CONFIG_ARM64_EPAN=y
CONFIG_ARM64_ERRATUM_1319367=y
CONFIG_ARM64_HW_AFDBM=y
CONFIG_ARM64_LD_HAS_FIX_ERRATUM_843419=y
CONFIG_ARM64_PAGE_SHIFT=12
-CONFIG_ARM64_PAN=y
CONFIG_ARM64_PA_BITS=48
CONFIG_ARM64_PA_BITS_48=y
CONFIG_ARM64_PTR_AUTH=y
@@ -188,8 +185,6 @@ CONFIG_DUMMY_CONSOLE=y
CONFIG_EDAC_SUPPORT=y
CONFIG_EXCLUSIVE_SYSTEM_RAM=y
CONFIG_EXT4_FS=y
-CONFIG_EXT4_FS_POSIX_ACL=y
-CONFIG_EXT4_FS_SECURITY=y
CONFIG_EXTCON=y
CONFIG_F2FS_FS=y
CONFIG_FB=y
@@ -217,7 +212,6 @@ CONFIG_FS_ENCRYPTION=y
CONFIG_FS_ENCRYPTION_ALGS=y
CONFIG_FS_IOMAP=y
CONFIG_FS_MBCACHE=y
-CONFIG_FS_POSIX_ACL=y
CONFIG_FUNCTION_ALIGNMENT=4
CONFIG_FUNCTION_ALIGNMENT_4B=y
CONFIG_FWNODE_MDIO=y
@@ -471,7 +465,6 @@ CONFIG_THREAD_INFO_IN_TASK=y
CONFIG_TICK_CPU_ACCOUNTING=y
CONFIG_TIMER_OF=y
CONFIG_TIMER_PROBE=y
-CONFIG_TMPFS_POSIX_ACL=y
CONFIG_TRACE_IRQFLAGS_NMI_SUPPORT=y
CONFIG_TREE_RCU=y
CONFIG_TREE_SRCU=y
diff --git a/target/linux/bcm27xx/bcm2712/config-6.6 b/target/linux/bcm27xx/bcm2712/config-6.6
index f61986338b..734b19612b 100644
--- a/target/linux/bcm27xx/bcm2712/config-6.6
+++ b/target/linux/bcm27xx/bcm2712/config-6.6
@@ -24,15 +24,13 @@ CONFIG_ARCH_WANTS_NO_INSTR=y
CONFIG_ARCH_WANTS_THP_SWAP=y
CONFIG_ARM64=y
CONFIG_ARM64_4K_PAGES=y
-CONFIG_ARM64_CNP=y
-CONFIG_ARM64_EPAN=y
CONFIG_ARM64_ERRATUM_1165522=y
CONFIG_ARM64_ERRATUM_1286807=y
CONFIG_ARM64_ERRATUM_1463225=y
+CONFIG_ARM64_ERRATUM_3194386=y
CONFIG_ARM64_HW_AFDBM=y
CONFIG_ARM64_LD_HAS_FIX_ERRATUM_843419=y
CONFIG_ARM64_PAGE_SHIFT=12
-CONFIG_ARM64_PAN=y
CONFIG_ARM64_PA_BITS=48
CONFIG_ARM64_PA_BITS_48=y
CONFIG_ARM64_PTR_AUTH=y
@@ -230,8 +228,6 @@ CONFIG_DUMMY_CONSOLE=y
CONFIG_EDAC_SUPPORT=y
CONFIG_EXCLUSIVE_SYSTEM_RAM=y
CONFIG_EXT4_FS=y
-CONFIG_EXT4_FS_POSIX_ACL=y
-CONFIG_EXT4_FS_SECURITY=y
CONFIG_EXTCON=y
CONFIG_F2FS_FS=y
CONFIG_FB=y
@@ -259,7 +255,6 @@ CONFIG_FS_ENCRYPTION=y
CONFIG_FS_ENCRYPTION_ALGS=y
CONFIG_FS_IOMAP=y
CONFIG_FS_MBCACHE=y
-CONFIG_FS_POSIX_ACL=y
CONFIG_FUNCTION_ALIGNMENT=4
CONFIG_FUNCTION_ALIGNMENT_4B=y
CONFIG_FWNODE_MDIO=y
@@ -589,7 +584,6 @@ CONFIG_THREAD_INFO_IN_TASK=y
CONFIG_TICK_CPU_ACCOUNTING=y
CONFIG_TIMER_OF=y
CONFIG_TIMER_PROBE=y
-CONFIG_TMPFS_POSIX_ACL=y
CONFIG_TRACE_IRQFLAGS_NMI_SUPPORT=y
CONFIG_TREE_RCU=y
CONFIG_TREE_SRCU=y
diff --git a/target/linux/bcm27xx/config-6.6 b/target/linux/bcm27xx/config-6.6
index 55f5523ab5..b44aa9f8a9 100644
--- a/target/linux/bcm27xx/config-6.6
+++ b/target/linux/bcm27xx/config-6.6
@@ -23,6 +23,7 @@
# CONFIG_RASPBERRYPI_GPIOMEM is not set
# CONFIG_REGULATOR_RASPBERRYPI_TOUCHSCREEN_V2 is not set
# CONFIG_SENSORS_RP1_ADC is not set
+# CONFIG_SPI_RP2040_GPIO_BRIDGE is not set
# CONFIG_VIDEO_AD5398 is not set
# CONFIG_VIDEO_ARDUCAM_64MP is not set
# CONFIG_VIDEO_ARDUCAM_PIVARIETY is not set
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-0058-Revert-Bluetooth-Always-request-for-user-confirmatio.patch
index 6b5bd616e6..e72c69bb39 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-0058-Revert-Bluetooth-Always-request-for-user-confirmatio.patch
@@ -24,16 +24,16 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
-@@ -2221,7 +2221,7 @@ mackey_and_ltk:
+@@ -2222,7 +2222,7 @@ mackey_and_ltk:
if (err)
return SMP_UNSPECIFIED;
- if (smp->method == REQ_OOB) {
+ if (smp->method == JUST_WORKS || smp->method == REQ_OOB) {
- if (hcon->out) {
+ if (test_bit(SMP_FLAG_INITIATOR, &smp->flags)) {
sc_dhkey_check(smp);
SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
-@@ -2236,9 +2236,6 @@ mackey_and_ltk:
+@@ -2237,9 +2237,6 @@ mackey_and_ltk:
confirm_hint = 0;
confirm:
diff --git a/target/linux/bcm27xx/patches-6.6/950-0065-cgroup-Disable-cgroup-memory-by-default.patch b/target/linux/bcm27xx/patches-6.6/950-0065-cgroup-Disable-cgroup-memory-by-default.patch
index 71ba361232..8a06ec387e 100644
--- a/target/linux/bcm27xx/patches-6.6/950-0065-cgroup-Disable-cgroup-memory-by-default.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-0065-cgroup-Disable-cgroup-memory-by-default.patch
@@ -17,7 +17,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.org>
--- a/kernel/cgroup/cgroup.c
+++ b/kernel/cgroup/cgroup.c
-@@ -6051,6 +6051,9 @@ int __init cgroup_init_early(void)
+@@ -6060,6 +6060,9 @@ int __init cgroup_init_early(void)
return 0;
}
@@ -27,7 +27,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.org>
/**
* cgroup_init - cgroup initialization
*
-@@ -6084,6 +6087,12 @@ int __init cgroup_init(void)
+@@ -6093,6 +6096,12 @@ int __init cgroup_init(void)
cgroup_unlock();
@@ -40,7 +40,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.org>
for_each_subsys(ss, ssid) {
if (ss->early_init) {
struct cgroup_subsys_state *css =
-@@ -6724,6 +6733,10 @@ static int __init cgroup_disable(char *s
+@@ -6733,6 +6742,10 @@ static int __init cgroup_disable(char *s
strcmp(token, ss->legacy_name))
continue;
@@ -51,7 +51,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.org>
static_branch_disable(cgroup_subsys_enabled_key[i]);
pr_info("Disabling %s control group subsystem\n",
ss->name);
-@@ -6742,6 +6755,31 @@ static int __init cgroup_disable(char *s
+@@ -6751,6 +6764,31 @@ static int __init cgroup_disable(char *s
}
__setup("cgroup_disable=", cgroup_disable);
diff --git a/target/linux/bcm27xx/patches-6.6/950-0070-spi-spidev-Completely-disable-the-spidev-warning.patch b/target/linux/bcm27xx/patches-6.6/950-0070-spi-spidev-Completely-disable-the-spidev-warning.patch
index cbd2877f51..47d727af5b 100644
--- a/target/linux/bcm27xx/patches-6.6/950-0070-spi-spidev-Completely-disable-the-spidev-warning.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-0070-spi-spidev-Completely-disable-the-spidev-warning.patch
@@ -13,7 +13,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.org>
--- a/drivers/spi/spidev.c
+++ b/drivers/spi/spidev.c
-@@ -719,7 +719,7 @@ MODULE_DEVICE_TABLE(spi, spidev_spi_ids)
+@@ -720,7 +720,7 @@ MODULE_DEVICE_TABLE(spi, spidev_spi_ids)
*/
static int spidev_of_check(struct device *dev)
{
diff --git a/target/linux/bcm27xx/patches-6.6/950-0103-Improve-__copy_to_user-and-__copy_from_user-performa.patch b/target/linux/bcm27xx/patches-6.6/950-0103-Improve-__copy_to_user-and-__copy_from_user-performa.patch
index 2d546c7502..92fd35d936 100644
--- a/target/linux/bcm27xx/patches-6.6/950-0103-Improve-__copy_to_user-and-__copy_from_user-performa.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-0103-Improve-__copy_to_user-and-__copy_from_user-performa.patch
@@ -99,7 +99,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
#endif
--- a/arch/arm/include/asm/uaccess.h
+++ b/arch/arm/include/asm/uaccess.h
-@@ -509,6 +509,9 @@ do { \
+@@ -499,6 +499,9 @@ do { \
extern unsigned long __must_check
arm_copy_from_user(void *to, const void __user *from, unsigned long n);
diff --git a/target/linux/bcm27xx/patches-6.6/950-0106-Add-support-for-all-the-downstream-rpi-sound-card-dr.patch b/target/linux/bcm27xx/patches-6.6/950-0106-Add-support-for-all-the-downstream-rpi-sound-card-dr.patch
index 0474076e77..b35df5a381 100644
--- a/target/linux/bcm27xx/patches-6.6/950-0106-Add-support-for-all-the-downstream-rpi-sound-card-dr.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-0106-Add-support-for-all-the-downstream-rpi-sound-card-dr.patch
@@ -1541,7 +1541,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+zidoo Shenzhen Zidoo Technology Co., Ltd.
+zii Zodiac Inflight Innovations
+zte ZTE Corp.
-+zyxel ZyXEL Communications Corp.
++zyxel Zyxel Communications Corp.
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -196,6 +196,8 @@ patternProperties:
@@ -17583,7 +17583,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
* For devices with more than one control interface, we assume the
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
-@@ -2185,6 +2185,8 @@ static const struct usb_audio_quirk_flag
+@@ -2191,6 +2191,8 @@ static const struct usb_audio_quirk_flag
QUIRK_FLAG_ALIGN_TRANSFER),
DEVICE_FLG(0x534d, 0x2109, /* MacroSilicon MS2109 */
QUIRK_FLAG_ALIGN_TRANSFER),
diff --git a/target/linux/bcm27xx/patches-6.6/950-0113-ARM64-Force-hardware-emulation-of-deprecated-instruc.patch b/target/linux/bcm27xx/patches-6.6/950-0113-ARM64-Force-hardware-emulation-of-deprecated-instruc.patch
index 14f92dfadd..1a84fb14b1 100644
--- a/target/linux/bcm27xx/patches-6.6/950-0113-ARM64-Force-hardware-emulation-of-deprecated-instruc.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-0113-ARM64-Force-hardware-emulation-of-deprecated-instruc.patch
@@ -10,7 +10,7 @@ Subject: [PATCH 0113/1085] ARM64: Force hardware emulation of deprecated
--- a/arch/arm64/kernel/armv8_deprecated.c
+++ b/arch/arm64/kernel/armv8_deprecated.c
-@@ -539,9 +539,14 @@ static void __init register_insn_emulati
+@@ -542,9 +542,14 @@ static void __init register_insn_emulati
switch (insn->status) {
case INSN_DEPRECATED:
diff --git a/target/linux/bcm27xx/patches-6.6/950-0161-xhci-implement-xhci_fixup_endpoint-for-interval-adju.patch b/target/linux/bcm27xx/patches-6.6/950-0161-xhci-implement-xhci_fixup_endpoint-for-interval-adju.patch
index 73baf3312b..f5eea9b47d 100644
--- a/target/linux/bcm27xx/patches-6.6/950-0161-xhci-implement-xhci_fixup_endpoint-for-interval-adju.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-0161-xhci-implement-xhci_fixup_endpoint-for-interval-adju.patch
@@ -15,7 +15,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.org>
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
-@@ -1487,6 +1487,109 @@ command_cleanup:
+@@ -1497,6 +1497,109 @@ command_cleanup:
}
/*
@@ -125,7 +125,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.org>
* non-error returns are a promise to giveback() the urb later
* we drop ownership so next owner (or urb unlink) can get it
*/
-@@ -5316,6 +5419,7 @@ static const struct hc_driver xhci_hc_dr
+@@ -5328,6 +5431,7 @@ static const struct hc_driver xhci_hc_dr
.endpoint_reset = xhci_endpoint_reset,
.check_bandwidth = xhci_check_bandwidth,
.reset_bandwidth = xhci_reset_bandwidth,
diff --git a/target/linux/bcm27xx/patches-6.6/950-0163-usb-xhci-drop-and-add-the-endpoint-context-in-xhci_f.patch b/target/linux/bcm27xx/patches-6.6/950-0163-usb-xhci-drop-and-add-the-endpoint-context-in-xhci_f.patch
index 957ed42407..1e5bb6059d 100644
--- a/target/linux/bcm27xx/patches-6.6/950-0163-usb-xhci-drop-and-add-the-endpoint-context-in-xhci_f.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-0163-usb-xhci-drop-and-add-the-endpoint-context-in-xhci_f.patch
@@ -19,7 +19,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
-@@ -1576,7 +1576,7 @@ static void xhci_fixup_endpoint(struct u
+@@ -1586,7 +1586,7 @@ static void xhci_fixup_endpoint(struct u
return;
}
ctrl_ctx->add_flags = xhci_get_endpoint_flag_from_index(ep_index);
diff --git a/target/linux/bcm27xx/patches-6.6/950-0169-hid-usb-Add-device-quirks-for-Freeway-Airmouse-T3-an.patch b/target/linux/bcm27xx/patches-6.6/950-0169-hid-usb-Add-device-quirks-for-Freeway-Airmouse-T3-an.patch
index a64754310d..c3c3353f91 100644
--- a/target/linux/bcm27xx/patches-6.6/950-0169-hid-usb-Add-device-quirks-for-Freeway-Airmouse-T3-an.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-0169-hid-usb-Add-device-quirks-for-Freeway-Airmouse-T3-an.patch
@@ -33,7 +33,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.org>
#define USB_VENDOR_ID_BELKIN 0x050d
#define USB_DEVICE_ID_FLIP_KVM 0x3201
-@@ -1405,6 +1408,9 @@
+@@ -1407,6 +1410,9 @@
#define USB_VENDOR_ID_XIAOMI 0x2717
#define USB_DEVICE_ID_MI_SILENT_MOUSE 0x5014
diff --git a/target/linux/bcm27xx/patches-6.6/950-0214-gpiolib-Don-t-prevent-IRQ-usage-of-output-GPIOs.patch b/target/linux/bcm27xx/patches-6.6/950-0214-gpiolib-Don-t-prevent-IRQ-usage-of-output-GPIOs.patch
index 9b5a0fa088..29f8ebf0d6 100644
--- a/target/linux/bcm27xx/patches-6.6/950-0214-gpiolib-Don-t-prevent-IRQ-usage-of-output-GPIOs.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-0214-gpiolib-Don-t-prevent-IRQ-usage-of-output-GPIOs.patch
@@ -17,7 +17,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.org>
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
-@@ -57,6 +57,8 @@
+@@ -58,6 +58,8 @@
#define extra_checks 0
#endif
@@ -26,7 +26,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.org>
/* Device and char device-related information */
static DEFINE_IDA(gpio_ida);
static dev_t gpio_devt;
-@@ -2591,8 +2593,8 @@ int gpiod_direction_output(struct gpio_d
+@@ -2592,8 +2594,8 @@ int gpiod_direction_output(struct gpio_d
value = !!value;
/* GPIOs used for enabled IRQs shall not be set as output */
@@ -37,7 +37,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.org>
gpiod_err(desc,
"%s: tried to set a GPIO tied to an IRQ as output\n",
__func__);
-@@ -3470,8 +3472,8 @@ int gpiochip_lock_as_irq(struct gpio_chi
+@@ -3471,8 +3473,8 @@ int gpiochip_lock_as_irq(struct gpio_chi
}
/* To be valid for IRQ the line needs to be input or open drain */
diff --git a/target/linux/bcm27xx/patches-6.6/950-0277-kbuild-Silence-unavoidable-dtc-overlay-warnings.patch b/target/linux/bcm27xx/patches-6.6/950-0277-kbuild-Silence-unavoidable-dtc-overlay-warnings.patch
index b5e790665e..2e3de46259 100644
--- a/target/linux/bcm27xx/patches-6.6/950-0277-kbuild-Silence-unavoidable-dtc-overlay-warnings.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-0277-kbuild-Silence-unavoidable-dtc-overlay-warnings.patch
@@ -16,7 +16,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
-@@ -428,6 +428,12 @@ cmd_dtco = mkdir -p $(dir ${dtc-tmp}) ;
+@@ -432,6 +432,12 @@ cmd_dtco = mkdir -p $(dir ${dtc-tmp}) ;
$(DTC) -@ -H epapr -O dtb -o $@ -b 0 \
-i $(dir $<) $(DTC_FLAGS) \
-Wno-interrupts_property \
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-0320-spi-spidev-Restore-loading-from-Device-Tree.patch
index 6f22bfd578..a45389d9ef 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-0320-spi-spidev-Restore-loading-from-Device-Tree.patch
@@ -20,6 +20,6 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
static const struct spi_device_id spidev_spi_ids[] = {
+ { .name = "spidev" },
+ { .name = "bh2228fv" },
{ .name = "dh2228fv" },
{ .name = "ltc2488" },
- { .name = "sx1301" },
diff --git a/target/linux/bcm27xx/patches-6.6/950-0416-gpio-pca953x-Add-ti-tca9554-compatible-string.patch b/target/linux/bcm27xx/patches-6.6/950-0416-gpio-pca953x-Add-ti-tca9554-compatible-string.patch
index b9ec31caa5..aa11729b71 100644
--- a/target/linux/bcm27xx/patches-6.6/950-0416-gpio-pca953x-Add-ti-tca9554-compatible-string.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-0416-gpio-pca953x-Add-ti-tca9554-compatible-string.patch
@@ -10,7 +10,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
--- a/drivers/gpio/gpio-pca953x.c
+++ b/drivers/gpio/gpio-pca953x.c
-@@ -1345,6 +1345,7 @@ static const struct of_device_id pca953x
+@@ -1347,6 +1347,7 @@ static const struct of_device_id pca953x
{ .compatible = "ti,tca6424", .data = OF_953X(24, PCA_INT), },
{ .compatible = "ti,tca9538", .data = OF_953X( 8, PCA_INT), },
{ .compatible = "ti,tca9539", .data = OF_953X(16, PCA_INT), },
diff --git a/target/linux/bcm27xx/patches-6.6/950-0441-Bluetooth-hci_sync-Add-fallback-bd-address-prop.patch b/target/linux/bcm27xx/patches-6.6/950-0441-Bluetooth-hci_sync-Add-fallback-bd-address-prop.patch
index 9aa16d6b25..51ba7c697c 100644
--- a/target/linux/bcm27xx/patches-6.6/950-0441-Bluetooth-hci_sync-Add-fallback-bd-address-prop.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-0441-Bluetooth-hci_sync-Add-fallback-bd-address-prop.patch
@@ -20,7 +20,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
--- a/net/bluetooth/hci_sync.c
+++ b/net/bluetooth/hci_sync.c
-@@ -4659,6 +4659,7 @@ static const struct {
+@@ -4707,6 +4707,7 @@ static const struct {
*/
static int hci_dev_setup_sync(struct hci_dev *hdev)
{
@@ -28,7 +28,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
int ret = 0;
bool invalid_bdaddr;
size_t i;
-@@ -4687,7 +4688,8 @@ static int hci_dev_setup_sync(struct hci
+@@ -4735,7 +4736,8 @@ static int hci_dev_setup_sync(struct hci
test_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks);
if (!ret) {
if (test_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks) &&
diff --git a/target/linux/bcm27xx/patches-6.6/950-0485-usb-xhci-add-XHCI_VLI_HUB_TT_QUIRK.patch b/target/linux/bcm27xx/patches-6.6/950-0485-usb-xhci-add-XHCI_VLI_HUB_TT_QUIRK.patch
index 1280d2c27d..e1846dc8f5 100644
--- a/target/linux/bcm27xx/patches-6.6/950-0485-usb-xhci-add-XHCI_VLI_HUB_TT_QUIRK.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-0485-usb-xhci-add-XHCI_VLI_HUB_TT_QUIRK.patch
@@ -75,7 +75,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA &&
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
-@@ -3658,6 +3658,48 @@ static int xhci_align_td(struct xhci_hcd
+@@ -3657,6 +3657,48 @@ static int xhci_align_td(struct xhci_hcd
return 1;
}
@@ -124,7 +124,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
/* This is very similar to what ehci-q.c qtd_fill() does */
int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
struct urb *urb, int slot_id, unsigned int ep_index)
-@@ -3814,6 +3856,8 @@ int xhci_queue_bulk_tx(struct xhci_hcd *
+@@ -3813,6 +3855,8 @@ int xhci_queue_bulk_tx(struct xhci_hcd *
}
check_trb_math(urb, enqd_len);
@@ -133,7 +133,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
giveback_first_trb(xhci, slot_id, ep_index, urb->stream_id,
start_cycle, start_trb);
return 0;
-@@ -3949,6 +3993,8 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *
+@@ -3948,6 +3992,8 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *
/* Event on completion */
field | TRB_IOC | TRB_TYPE(TRB_STATUS) | ep_ring->cycle_state);
diff --git a/target/linux/bcm27xx/patches-6.6/950-0490-input-ads7846-Add-missing-spi_device_id-strings.patch b/target/linux/bcm27xx/patches-6.6/950-0490-input-ads7846-Add-missing-spi_device_id-strings.patch
deleted file mode 100644
index 1b0a29a777..0000000000
--- a/target/linux/bcm27xx/patches-6.6/950-0490-input-ads7846-Add-missing-spi_device_id-strings.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-From 3b391ceadf0d4ab5ce45f98d2f1d41f40e5aedd7 Mon Sep 17 00:00:00 2001
-From: Dave Stevenson <dave.stevenson@raspberrypi.com>
-Date: Fri, 1 Sep 2023 12:23:30 +0100
-Subject: [PATCH 0490/1085] input: ads7846: Add missing spi_device_id strings
-
-The SPI core logs error messages if a compatible string device
-name is not also present as an spi_device_id.
-
-No spi_device_id values are specified by the driver, therefore
-we get 4 log lines every time it is loaded:
-SPI driver ads7846 has no spi_device_id for ti,tsc2046
-SPI driver ads7846 has no spi_device_id for ti,ads7843
-SPI driver ads7846 has no spi_device_id for ti,ads7845
-SPI driver ads7846 has no spi_device_id for ti,ads7873
-
-Add the spi_device_id values for these devices.
-
-Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
----
- drivers/input/touchscreen/ads7846.c | 11 +++++++++++
- 1 file changed, 11 insertions(+)
-
---- a/drivers/input/touchscreen/ads7846.c
-+++ b/drivers/input/touchscreen/ads7846.c
-@@ -1114,6 +1114,16 @@ static const struct of_device_id ads7846
- };
- MODULE_DEVICE_TABLE(of, ads7846_dt_ids);
-
-+static const struct spi_device_id ads7846_spi_ids[] = {
-+ { "tsc2046", 0 },
-+ { "ads7843", 0 },
-+ { "ads7845", 0 },
-+ { "ads7846", 0 },
-+ { "ads7873", 0 },
-+ { }
-+};
-+MODULE_DEVICE_TABLE(spi, ads7846_spi_ids);
-+
- static const struct ads7846_platform_data *ads7846_get_props(struct device *dev)
- {
- struct ads7846_platform_data *pdata;
-@@ -1390,6 +1400,7 @@ static struct spi_driver ads7846_driver
- .pm = pm_sleep_ptr(&ads7846_pm),
- .of_match_table = ads7846_dt_ids,
- },
-+ .id_table = ads7846_spi_ids,
- .probe = ads7846_probe,
- .remove = ads7846_remove,
- };
diff --git a/target/linux/bcm27xx/patches-6.6/950-0519-usb-dwc3-Set-DMA-and-coherent-masks-early.patch b/target/linux/bcm27xx/patches-6.6/950-0519-usb-dwc3-Set-DMA-and-coherent-masks-early.patch
index d01a37d690..78cdcc7139 100644
--- a/target/linux/bcm27xx/patches-6.6/950-0519-usb-dwc3-Set-DMA-and-coherent-masks-early.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-0519-usb-dwc3-Set-DMA-and-coherent-masks-early.patch
@@ -212,7 +212,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
},
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
-@@ -1181,6 +1181,24 @@ static void dwc3_config_threshold(struct
+@@ -1202,6 +1202,24 @@ static void dwc3_config_threshold(struct
}
}
@@ -237,7 +237,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
/**
* dwc3_core_init - Low-level initialization of DWC3 Core
* @dwc: Pointer to our controller context structure
-@@ -1246,6 +1264,8 @@ static int dwc3_core_init(struct dwc3 *d
+@@ -1267,6 +1285,8 @@ static int dwc3_core_init(struct dwc3 *d
dwc3_set_incr_burst_type(dwc);
@@ -246,7 +246,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
ret = dwc3_phy_power_on(dwc);
if (ret)
goto err_exit_phy;
-@@ -1320,6 +1340,24 @@ static int dwc3_core_init(struct dwc3 *d
+@@ -1341,6 +1361,24 @@ static int dwc3_core_init(struct dwc3 *d
dwc3_config_threshold(dwc);
@@ -271,7 +271,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
return 0;
err_power_off_phy:
-@@ -1463,6 +1501,7 @@ static void dwc3_get_properties(struct d
+@@ -1484,6 +1522,7 @@ static void dwc3_get_properties(struct d
u8 tx_thr_num_pkt_prd = 0;
u8 tx_max_burst_prd = 0;
u8 tx_fifo_resize_max_num;
@@ -279,7 +279,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
const char *usb_psy_name;
int ret;
-@@ -1485,6 +1524,9 @@ static void dwc3_get_properties(struct d
+@@ -1506,6 +1545,9 @@ static void dwc3_get_properties(struct d
*/
tx_fifo_resize_max_num = 6;
@@ -289,7 +289,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
dwc->maximum_speed = usb_get_maximum_speed(dev);
dwc->max_ssp_rate = usb_get_maximum_ssp_rate(dev);
dwc->dr_mode = usb_get_dr_mode(dev);
-@@ -1606,6 +1648,9 @@ static void dwc3_get_properties(struct d
+@@ -1627,6 +1669,9 @@ static void dwc3_get_properties(struct d
dwc->dis_split_quirk = device_property_read_bool(dev,
"snps,dis-split-quirk");
@@ -299,7 +299,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
dwc->lpm_nyet_threshold = lpm_nyet_threshold;
dwc->tx_de_emphasis = tx_de_emphasis;
-@@ -1623,6 +1668,8 @@ static void dwc3_get_properties(struct d
+@@ -1644,6 +1689,8 @@ static void dwc3_get_properties(struct d
dwc->tx_thr_num_pkt_prd = tx_thr_num_pkt_prd;
dwc->tx_max_burst_prd = tx_max_burst_prd;
@@ -308,7 +308,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
dwc->imod_interval = 0;
dwc->tx_fifo_resize_max_num = tx_fifo_resize_max_num;
-@@ -1898,6 +1945,12 @@ static int dwc3_probe(struct platform_de
+@@ -1919,6 +1966,12 @@ static int dwc3_probe(struct platform_de
dwc3_get_properties(dwc);
diff --git a/target/linux/bcm27xx/patches-6.6/950-0526-mfd-Add-rp1-driver.patch b/target/linux/bcm27xx/patches-6.6/950-0526-mfd-Add-rp1-driver.patch
index 764a38ff19..b900c1edae 100644
--- a/target/linux/bcm27xx/patches-6.6/950-0526-mfd-Add-rp1-driver.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-0526-mfd-Add-rp1-driver.patch
@@ -39,11 +39,11 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
depends on I2C && OF
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
-@@ -285,3 +285,5 @@ rsmu-i2c-objs := rsmu_core.o rsmu_i2c.
- rsmu-spi-objs := rsmu_core.o rsmu_spi.o
- obj-$(CONFIG_MFD_RSMU_I2C) += rsmu-i2c.o
- obj-$(CONFIG_MFD_RSMU_SPI) += rsmu-spi.o
-+
+@@ -283,3 +283,5 @@ obj-$(CONFIG_MFD_ATC260X_I2C) += atc260x
+
+ obj-$(CONFIG_MFD_RSMU_I2C) += rsmu_i2c.o rsmu_core.o
+ obj-$(CONFIG_MFD_RSMU_SPI) += rsmu_spi.o rsmu_core.o
++
+obj-$(CONFIG_MFD_RP1) += rp1.o
--- /dev/null
+++ b/drivers/mfd/rp1.c
diff --git a/target/linux/bcm27xx/patches-6.6/950-0679-drm-fb-helper-Look-up-preferred-fbdev-node-number-fr.patch b/target/linux/bcm27xx/patches-6.6/950-0679-drm-fb-helper-Look-up-preferred-fbdev-node-number-fr.patch
index f1eafeefe7..f94efc25b2 100644
--- a/target/linux/bcm27xx/patches-6.6/950-0679-drm-fb-helper-Look-up-preferred-fbdev-node-number-fr.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-0679-drm-fb-helper-Look-up-preferred-fbdev-node-number-fr.patch
@@ -15,7 +15,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
-@@ -1840,7 +1840,7 @@ __drm_fb_helper_initial_config_and_unloc
+@@ -1851,7 +1851,7 @@ __drm_fb_helper_initial_config_and_unloc
struct drm_device *dev = fb_helper->dev;
struct fb_info *info;
unsigned int width, height;
@@ -24,7 +24,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
width = dev->mode_config.max_width;
height = dev->mode_config.max_height;
-@@ -1868,6 +1868,15 @@ __drm_fb_helper_initial_config_and_unloc
+@@ -1879,6 +1879,15 @@ __drm_fb_helper_initial_config_and_unloc
* register the fbdev emulation instance in kernel_fb_helper_list. */
mutex_unlock(&fb_helper->lock);
diff --git a/target/linux/bcm27xx/patches-6.6/950-0684-drm-fb_helper-Change-query-for-FB-designation-from-d.patch b/target/linux/bcm27xx/patches-6.6/950-0684-drm-fb_helper-Change-query-for-FB-designation-from-d.patch
index 588d113376..60cabdffc3 100644
--- a/target/linux/bcm27xx/patches-6.6/950-0684-drm-fb_helper-Change-query-for-FB-designation-from-d.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-0684-drm-fb_helper-Change-query-for-FB-designation-from-d.patch
@@ -12,7 +12,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
-@@ -1868,11 +1868,11 @@ __drm_fb_helper_initial_config_and_unloc
+@@ -1879,11 +1879,11 @@ __drm_fb_helper_initial_config_and_unloc
* register the fbdev emulation instance in kernel_fb_helper_list. */
mutex_unlock(&fb_helper->lock);
diff --git a/target/linux/bcm27xx/patches-6.6/950-0714-spi-dw-dma-Get-the-last-DMA-scoop-out-of-the-FIFO.patch b/target/linux/bcm27xx/patches-6.6/950-0714-spi-dw-dma-Get-the-last-DMA-scoop-out-of-the-FIFO.patch
deleted file mode 100644
index 2a2ba5d037..0000000000
--- a/target/linux/bcm27xx/patches-6.6/950-0714-spi-dw-dma-Get-the-last-DMA-scoop-out-of-the-FIFO.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From 6aab06ff9f81e186b1a02b53b514e691472e5a61 Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.com>
-Date: Tue, 7 Nov 2023 14:49:47 +0000
-Subject: [PATCH 0714/1085] spi: dw-dma: Get the last DMA scoop out of the FIFO
-
-With a DMA FIFO threshold greater than 1 (encoded as 0), it is possible
-for data in the FIFO to be inaccessible, causing the transfer to fail
-after a timeout. If the transfer includes a transmission, reduce the
-RX threshold when the TX completes, otherwise use 1 for the whole
-transfer (inefficient, but not catastrophic at SPI data rates).
-
-See: https://github.com/raspberrypi/linux/issues/5696
-
-Signed-off-by: Phil Elwell <phil@raspberrypi.com>
----
- drivers/spi/spi-dw-dma.c | 6 +++++-
- 1 file changed, 5 insertions(+), 1 deletion(-)
-
---- a/drivers/spi/spi-dw-dma.c
-+++ b/drivers/spi/spi-dw-dma.c
-@@ -315,8 +315,10 @@ static void dw_spi_dma_tx_done(void *arg
- struct dw_spi *dws = arg;
-
- clear_bit(DW_SPI_TX_BUSY, &dws->dma_chan_busy);
-- if (test_bit(DW_SPI_RX_BUSY, &dws->dma_chan_busy))
-+ if (test_bit(DW_SPI_RX_BUSY, &dws->dma_chan_busy)) {
-+ dw_writel(dws, DW_SPI_DMARDLR, 0);
- return;
-+ }
-
- complete(&dws->dma_completion);
- }
-@@ -642,6 +644,8 @@ static int dw_spi_dma_transfer(struct dw
-
- nents = max(xfer->tx_sg.nents, xfer->rx_sg.nents);
-
-+ dw_writel(dws, DW_SPI_DMARDLR, xfer->tx_buf ? (dws->rxburst - 1) : 0);
-+
- /*
- * Execute normal DMA-based transfer (which submits the Rx and Tx SG
- * lists directly to the DMA engine at once) if either full hardware
diff --git a/target/linux/bcm27xx/patches-6.6/950-0853-drivers-usb-dwc3-add-FS-LS-bus-instance-parkmode-dis.patch b/target/linux/bcm27xx/patches-6.6/950-0853-drivers-usb-dwc3-add-FS-LS-bus-instance-parkmode-dis.patch
index 3028b82619..d91a989526 100644
--- a/target/linux/bcm27xx/patches-6.6/950-0853-drivers-usb-dwc3-add-FS-LS-bus-instance-parkmode-dis.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-0853-drivers-usb-dwc3-add-FS-LS-bus-instance-parkmode-dis.patch
@@ -16,7 +16,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
-@@ -1330,6 +1330,9 @@ static int dwc3_core_init(struct dwc3 *d
+@@ -1351,6 +1351,9 @@ static int dwc3_core_init(struct dwc3 *d
if (dwc->parkmode_disable_hs_quirk)
reg |= DWC3_GUCTL1_PARKMODE_DISABLE_HS;
@@ -26,7 +26,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
if (DWC3_VER_IS_WITHIN(DWC3, 290A, ANY) &&
(dwc->maximum_speed == USB_SPEED_HIGH ||
dwc->maximum_speed == USB_SPEED_FULL))
-@@ -1628,6 +1631,8 @@ static void dwc3_get_properties(struct d
+@@ -1649,6 +1652,8 @@ static void dwc3_get_properties(struct d
"snps,parkmode-disable-ss-quirk");
dwc->parkmode_disable_hs_quirk = device_property_read_bool(dev,
"snps,parkmode-disable-hs-quirk");
diff --git a/target/linux/bcm27xx/patches-6.6/950-1141-fs-ntfs3-Fix-memory-corruption-when-page_size-change.patch b/target/linux/bcm27xx/patches-6.6/950-1141-fs-ntfs3-Fix-memory-corruption-when-page_size-change.patch
index 113b3fdf53..b05a8276df 100644
--- a/target/linux/bcm27xx/patches-6.6/950-1141-fs-ntfs3-Fix-memory-corruption-when-page_size-change.patch
+++ b/target/linux/bcm27xx/patches-6.6/950-1141-fs-ntfs3-Fix-memory-corruption-when-page_size-change.patch
@@ -25,7 +25,7 @@ Signed-off-by: Dom Cobley <popcornmix@gmail.com>
--- a/fs/ntfs3/fslog.c
+++ b/fs/ntfs3/fslog.c
-@@ -3907,6 +3907,8 @@ check_restart_area:
+@@ -3914,6 +3914,8 @@ check_restart_area:
log->l_size = log->orig_file_size;
log->page_size = norm_file_page(t32, &log->l_size,
t32 == DefaultLogPageSize);
diff --git a/target/linux/bcm27xx/patches-6.6/950-1146-drivers-dwc_otg-use-C11-style-variable-array-declara.patch b/target/linux/bcm27xx/patches-6.6/950-1146-drivers-dwc_otg-use-C11-style-variable-array-declara.patch
new file mode 100644
index 0000000000..b5f117f7f7
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1146-drivers-dwc_otg-use-C11-style-variable-array-declara.patch
@@ -0,0 +1,260 @@
+From 65fddc7301f52470fd846acede96d240a1902e67 Mon Sep 17 00:00:00 2001
+From: Jonathan Bell <jonathan@raspberrypi.com>
+Date: Fri, 5 Jul 2024 14:00:38 +0100
+Subject: [PATCH 1146/1215] drivers: dwc_otg: use C11 style variable array
+ declarations
+
+The kernel C standard changed in 5.18.
+
+Remove a layer of indirection around the FIQ bounce buffers, be consistent
+with pointers to FIQ bounce buffers, and remove open-coded 32-bit clamping
+of DMA addresses.
+
+Also remove a pointless fiq_state initialisation loop.
+
+Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
+---
+ drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c | 12 ++++----
+ drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.h | 8 ++---
+ drivers/usb/host/dwc_otg/dwc_otg_hcd.c | 34 ++++++++++-----------
+ drivers/usb/host/dwc_otg/dwc_otg_hcd.h | 4 +--
+ drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 4 +--
+ 5 files changed, 28 insertions(+), 34 deletions(-)
+
+--- a/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c
++++ b/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c
+@@ -240,8 +240,8 @@ static int notrace fiq_increment_dma_buf
+ hcdma_data_t hcdma;
+ int i = st->channel[n].dma_info.index;
+ int len;
+- struct fiq_dma_blob *blob =
+- (struct fiq_dma_blob *)(uintptr_t)st->dma_base;
++ struct fiq_dma_channel *split_dma =
++ (struct fiq_dma_channel *)(uintptr_t)st->dma_base;
+
+ len = fiq_get_xfer_len(st, n);
+ fiq_print(FIQDBG_INT, st, "LEN: %03d", len);
+@@ -250,7 +250,7 @@ static int notrace fiq_increment_dma_buf
+ if (i > 6)
+ BUG();
+
+- hcdma.d32 = (u32)(uintptr_t)&blob->channel[n].index[i].buf[0];
++ hcdma.d32 = lower_32_bits((uintptr_t)&split_dma[n].index[i].buf[0]);
+ FIQ_WRITE(st->dwc_regs_base + HC_START + (HC_OFFSET * n) + HC_DMA, hcdma.d32);
+ st->channel[n].dma_info.index = i;
+ return 0;
+@@ -290,8 +290,8 @@ static int notrace fiq_iso_out_advance(s
+ hcsplt_data_t hcsplt;
+ hctsiz_data_t hctsiz;
+ hcdma_data_t hcdma;
+- struct fiq_dma_blob *blob =
+- (struct fiq_dma_blob *)(uintptr_t)st->dma_base;
++ struct fiq_dma_channel *split_dma =
++ (struct fiq_dma_channel *)(uintptr_t)st->dma_base;
+ int last = 0;
+ int i = st->channel[n].dma_info.index;
+
+@@ -303,7 +303,7 @@ static int notrace fiq_iso_out_advance(s
+ last = 1;
+
+ /* New DMA address - address of bounce buffer referred to in index */
+- hcdma.d32 = (u32)(uintptr_t)blob->channel[n].index[i].buf;
++ hcdma.d32 = lower_32_bits((uintptr_t)&split_dma[n].index[i].buf[0]);
+ //hcdma.d32 = FIQ_READ(st->dwc_regs_base + HC_START + (HC_OFFSET * n) + HC_DMA);
+ //hcdma.d32 += st->channel[n].dma_info.slot_len[i];
+ fiq_print(FIQDBG_INT, st, "LAST: %01d ", last);
+--- a/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.h
++++ b/drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.h
+@@ -263,10 +263,6 @@ struct fiq_dma_channel {
+ struct fiq_split_dma_slot index[6];
+ } __attribute__((packed));
+
+-struct fiq_dma_blob {
+- struct fiq_dma_channel channel[0];
+-} __attribute__((packed));
+-
+ /**
+ * struct fiq_hs_isoc_info - USB2.0 isochronous data
+ * @iso_frame: Pointer to the array of OTG URB iso_frame_descs.
+@@ -352,7 +348,7 @@ struct fiq_state {
+ mphi_regs_t mphi_regs;
+ void *dwc_regs_base;
+ dma_addr_t dma_base;
+- struct fiq_dma_blob *fiq_dmab;
++ struct fiq_dma_channel *fiq_dmab;
+ void *dummy_send;
+ dma_addr_t dummy_send_dma;
+ gintmsk_data_t gintmsk_saved;
+@@ -365,7 +361,7 @@ struct fiq_state {
+ char * buffer;
+ unsigned int bufsiz;
+ #endif
+- struct fiq_channel_state channel[0];
++ struct fiq_channel_state channel[];
+ };
+
+ #ifdef CONFIG_ARM64
+--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
++++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c
+@@ -58,6 +58,7 @@ static int last_sel_trans_num_avail_hc_a
+ static int last_sel_trans_num_avail_hc_at_end = 0;
+ #endif /* DEBUG_HOST_CHANNELS */
+
++static_assert(FIQ_PASSTHROUGH == 0);
+
+ dwc_otg_hcd_t *dwc_otg_hcd_alloc_hcd(void)
+ {
+@@ -876,7 +877,7 @@ void dwc_otg_hcd_power_up(void *ptr)
+ void dwc_otg_cleanup_fiq_channel(dwc_otg_hcd_t *hcd, uint32_t num)
+ {
+ struct fiq_channel_state *st = &hcd->fiq_state->channel[num];
+- struct fiq_dma_blob *blob = hcd->fiq_dmab;
++ struct fiq_dma_channel *split_dma = hcd->fiq_dmab;
+ int i;
+
+ st->fsm = FIQ_PASSTHROUGH;
+@@ -898,7 +899,7 @@ void dwc_otg_cleanup_fiq_channel(dwc_otg
+ st->hs_isoc_info.iso_desc = NULL;
+ st->hs_isoc_info.nrframes = 0;
+
+- DWC_MEMSET(&blob->channel[num].index[0], 0x6b, 1128);
++ DWC_MEMSET(&split_dma[num].index[0], 0x6b, 1128);
+ }
+
+ /**
+@@ -1045,9 +1046,6 @@ int dwc_otg_hcd_init(dwc_otg_hcd_t * hcd
+ spin_lock_init(&hcd->fiq_state->lock);
+ #endif
+
+- for (i = 0; i < num_channels; i++) {
+- hcd->fiq_state->channel[i].fsm = FIQ_PASSTHROUGH;
+- }
+ hcd->fiq_state->dummy_send = DWC_DMA_ALLOC_ATOMIC(dev, 16,
+ &hcd->fiq_state->dummy_send_dma);
+
+@@ -1561,7 +1559,7 @@ int fiq_fsm_setup_periodic_dma(dwc_otg_h
+ int frame_length, i = 0;
+ uint8_t *ptr = NULL;
+ dwc_hc_t *hc = qh->channel;
+- struct fiq_dma_blob *blob;
++ struct fiq_dma_channel *split_dma;
+ struct dwc_otg_hcd_iso_packet_desc *frame_desc;
+
+ for (i = 0; i < 6; i++) {
+@@ -1576,10 +1574,10 @@ int fiq_fsm_setup_periodic_dma(dwc_otg_h
+ * Pointer arithmetic on hcd->fiq_state->dma_base (a dma_addr_t)
+ * to point it to the correct offset in the allocated buffers.
+ */
+- blob = (struct fiq_dma_blob *)
++ split_dma = (struct fiq_dma_channel *)
+ (uintptr_t)hcd->fiq_state->dma_base;
+- st->hcdma_copy.d32 =(u32)(uintptr_t)
+- blob->channel[hc->hc_num].index[0].buf;
++ st->hcdma_copy.d32 = lower_32_bits((uintptr_t)
++ &split_dma[hc->hc_num].index[0].buf[0]);
+
+ /* Calculate the max number of CSPLITS such that the FIQ can time out
+ * a transaction if it fails.
+@@ -1600,7 +1598,7 @@ int fiq_fsm_setup_periodic_dma(dwc_otg_h
+ frame_length = frame_desc->length;
+
+ /* Virtual address for bounce buffers */
+- blob = hcd->fiq_dmab;
++ split_dma = hcd->fiq_dmab;
+
+ ptr = qtd->urb->buf + frame_desc->offset;
+ if (frame_length == 0) {
+@@ -1613,11 +1611,11 @@ int fiq_fsm_setup_periodic_dma(dwc_otg_h
+ } else {
+ do {
+ if (frame_length <= 188) {
+- dwc_memcpy(&blob->channel[hc->hc_num].index[i].buf[0], ptr, frame_length);
++ dwc_memcpy(&split_dma[hc->hc_num].index[i].buf[0], ptr, frame_length);
+ st->dma_info.slot_len[i] = frame_length;
+ ptr += frame_length;
+ } else {
+- dwc_memcpy(&blob->channel[hc->hc_num].index[i].buf[0], ptr, 188);
++ dwc_memcpy(&split_dma[hc->hc_num].index[i].buf[0], ptr, 188);
+ st->dma_info.slot_len[i] = 188;
+ ptr += 188;
+ }
+@@ -1634,10 +1632,10 @@ int fiq_fsm_setup_periodic_dma(dwc_otg_h
+ * dma_addr_t) to point it to the correct offset in the
+ * allocated buffers.
+ */
+- blob = (struct fiq_dma_blob *)
++ split_dma = (struct fiq_dma_channel *)
+ (uintptr_t)hcd->fiq_state->dma_base;
+- st->hcdma_copy.d32 = (u32)(uintptr_t)
+- blob->channel[hc->hc_num].index[0].buf;
++ st->hcdma_copy.d32 = lower_32_bits((uintptr_t)
++ &split_dma[hc->hc_num].index[0].buf[0]);
+
+ /* fixup xfersize to the actual packet size */
+ st->hctsiz_copy.b.pid = 0;
+@@ -1917,14 +1915,14 @@ int fiq_fsm_queue_split_transaction(dwc_
+ if (hc->align_buff) {
+ st->hcdma_copy.d32 = hc->align_buff;
+ } else {
+- st->hcdma_copy.d32 = ((unsigned long) hc->xfer_buff & 0xFFFFFFFF);
++ st->hcdma_copy.d32 = lower_32_bits((uintptr_t)hc->xfer_buff);
+ }
+ }
+ } else {
+ if (hc->align_buff) {
+ st->hcdma_copy.d32 = hc->align_buff;
+ } else {
+- st->hcdma_copy.d32 = ((unsigned long) hc->xfer_buff & 0xFFFFFFFF);
++ st->hcdma_copy.d32 = lower_32_bits((uintptr_t)hc->xfer_buff);
+ }
+ }
+ /* The FIQ depends upon no other interrupts being enabled except channel halt.
+@@ -1944,7 +1942,7 @@ int fiq_fsm_queue_split_transaction(dwc_
+ if (hc->align_buff) {
+ st->hcdma_copy.d32 = hc->align_buff;
+ } else {
+- st->hcdma_copy.d32 = ((unsigned long) hc->xfer_buff & 0xFFFFFFFF);
++ st->hcdma_copy.d32 = lower_32_bits((uintptr_t)hc->xfer_buff);
+ }
+ }
+ DWC_WRITE_REG32(&hc_regs->hcdma, st->hcdma_copy.d32);
+--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd.h
++++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.h
+@@ -88,7 +88,7 @@ struct dwc_otg_hcd_urb {
+ uint32_t flags;
+ uint16_t interval;
+ struct dwc_otg_hcd_pipe_info pipe_info;
+- struct dwc_otg_hcd_iso_packet_desc iso_descs[0];
++ struct dwc_otg_hcd_iso_packet_desc iso_descs[];
+ };
+
+ static inline uint8_t dwc_otg_hcd_get_ep_num(struct dwc_otg_hcd_pipe_info *pipe)
+@@ -592,7 +592,7 @@ struct dwc_otg_hcd {
+ struct fiq_state *fiq_state;
+
+ /** Virtual address for split transaction DMA bounce buffers */
+- struct fiq_dma_blob *fiq_dmab;
++ struct fiq_dma_channel *fiq_dmab;
+
+ #ifdef DEBUG
+ uint32_t frrem_samples;
+--- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
++++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
+@@ -2332,7 +2332,7 @@ void dwc_otg_fiq_unmangle_isoc(dwc_otg_h
+ int dwc_otg_fiq_unsetup_per_dma(dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh, dwc_otg_qtd_t *qtd, uint32_t num)
+ {
+ dwc_hc_t *hc = qh->channel;
+- struct fiq_dma_blob *blob = hcd->fiq_dmab;
++ struct fiq_dma_channel *split_dma = hcd->fiq_dmab;
+ struct fiq_channel_state *st = &hcd->fiq_state->channel[num];
+ uint8_t *ptr = NULL;
+ int index = 0, len = 0;
+@@ -2352,7 +2352,7 @@ int dwc_otg_fiq_unsetup_per_dma(dwc_otg_
+
+ for (i = 0; i < st->dma_info.index; i++) {
+ len += st->dma_info.slot_len[i];
+- dwc_memcpy(ptr, &blob->channel[num].index[i].buf[0], st->dma_info.slot_len[i]);
++ dwc_memcpy(ptr, &split_dma[num].index[i].buf[0], st->dma_info.slot_len[i]);
+ ptr += st->dma_info.slot_len[i];
+ }
+ return len;
diff --git a/target/linux/bcm27xx/patches-6.6/950-1147-media-uapi-pixfmt-luma-Document-MIPI-CSI-2-packing.patch b/target/linux/bcm27xx/patches-6.6/950-1147-media-uapi-pixfmt-luma-Document-MIPI-CSI-2-packing.patch
new file mode 100644
index 0000000000..14d0a79a73
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1147-media-uapi-pixfmt-luma-Document-MIPI-CSI-2-packing.patch
@@ -0,0 +1,27 @@
+From 8dea9155ab081289edd618f8373d5f980d5bb664 Mon Sep 17 00:00:00 2001
+From: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+Date: Fri, 23 Feb 2024 10:40:47 +0100
+Subject: [PATCH 1147/1215] media: uapi: pixfmt-luma: Document MIPI CSI-2
+ packing
+
+The Y10P, Y12P and Y14P format variants are packed according to
+the RAW10, RAW12 and RAW14 formats as defined by the MIPI CSI-2
+specification. Document it.
+
+Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
+---
+ Documentation/userspace-api/media/v4l/pixfmt-yuv-luma.rst | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/Documentation/userspace-api/media/v4l/pixfmt-yuv-luma.rst
++++ b/Documentation/userspace-api/media/v4l/pixfmt-yuv-luma.rst
+@@ -161,3 +161,7 @@ are often referred to as greyscale forma
+ For Y012 and Y12 formats, Y012 places its data in the 12 high bits, with
+ padding zeros in the 4 low bits, in contrast to the Y12 format, which has
+ its padding located in the most significant bits of the 16 bit word.
++
++ The 'P' variations of the Y10, Y12 and Y14 formats are packed according to
++ the RAW10, RAW12 and RAW14 packing scheme as defined by the MIPI CSI-2
++ specification.
diff --git a/target/linux/bcm27xx/patches-6.6/950-1148-media-uapi-Add-a-pixel-format-for-BGR48-and-RGB48.patch b/target/linux/bcm27xx/patches-6.6/950-1148-media-uapi-Add-a-pixel-format-for-BGR48-and-RGB48.patch
new file mode 100644
index 0000000000..2f459044a3
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1148-media-uapi-Add-a-pixel-format-for-BGR48-and-RGB48.patch
@@ -0,0 +1,101 @@
+From 814c088cb7183f79ba68c8f9459505e2ac4dde3a Mon Sep 17 00:00:00 2001
+From: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+Date: Fri, 26 Jan 2024 15:03:18 +0100
+Subject: [PATCH 1148/1215] media: uapi: Add a pixel format for BGR48 and RGB48
+
+Add BGR48 and RGB48 16-bit per component image formats.
+
+Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
+Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
+---
+ .../userspace-api/media/v4l/pixfmt-rgb.rst | 54 +++++++++++++++++++
+ drivers/media/v4l2-core/v4l2-common.c | 2 +
+ include/uapi/linux/videodev2.h | 2 +
+ 3 files changed, 58 insertions(+)
+
+--- a/Documentation/userspace-api/media/v4l/pixfmt-rgb.rst
++++ b/Documentation/userspace-api/media/v4l/pixfmt-rgb.rst
+@@ -996,6 +996,60 @@ arranged in little endian order.
+
+ \normalsize
+
++16 Bits Per Component
++=====================
++
++These formats store an RGB triplet in six bytes, with 16 bits per component
++stored in memory in little endian byte order. They are named based on the order
++of the RGB components as stored in memory. For instance, RGB48 stores R\
++:sub:`7:0` and R\ :sub:`15:8` in bytes 0 and 1 respectively. This differs from
++the DRM format nomenclature that instead uses the order of components as seen in
++the 48-bits little endian word.
++
++.. raw:: latex
++
++ \small
++
++.. flat-table:: RGB Formats With 16 Bits Per Component
++ :header-rows: 1
++
++ * - Identifier
++ - Code
++ - Byte 0
++ - Byte 1
++ - Byte 2
++ - Byte 3
++ - Byte 4
++ - Byte 5
++
++ * .. _V4L2-PIX-FMT-BGR48:
++
++ - ``V4L2_PIX_FMT_BGR48``
++ - 'BGR6'
++
++ - B\ :sub:`7-0`
++ - B\ :sub:`15-8`
++ - G\ :sub:`7-0`
++ - G\ :sub:`15-8`
++ - R\ :sub:`7-0`
++ - R\ :sub:`15-8`
++
++ * .. _V4L2-PIX-FMT-RGB48:
++
++ - ``V4L2_PIX_FMT_RGB48``
++ - 'RGB6'
++
++ - R\ :sub:`7-0`
++ - R\ :sub:`15-8`
++ - G\ :sub:`7-0`
++ - G\ :sub:`15-8`
++ - B\ :sub:`7-0`
++ - B\ :sub:`15-8`
++
++.. raw:: latex
++
++ \normalsize
++
+ Deprecated RGB Formats
+ ======================
+
+--- a/drivers/media/v4l2-core/v4l2-common.c
++++ b/drivers/media/v4l2-core/v4l2-common.c
+@@ -253,6 +253,8 @@ const struct v4l2_format_info *v4l2_form
+ { .format = V4L2_PIX_FMT_RGB555, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
+ { .format = V4L2_PIX_FMT_BGR666, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
+ { .format = V4L2_PIX_FMT_BGR48_12, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 6, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
++ { .format = V4L2_PIX_FMT_BGR48, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 6, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
++ { .format = V4L2_PIX_FMT_RGB48, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 6, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
+ { .format = V4L2_PIX_FMT_ABGR64_12, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 8, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
+
+ /* YUV packed formats */
+--- a/include/uapi/linux/videodev2.h
++++ b/include/uapi/linux/videodev2.h
+@@ -587,6 +587,8 @@ struct v4l2_pix_format {
+
+ /* RGB formats (6 or 8 bytes per pixel) */
+ #define V4L2_PIX_FMT_BGR48_12 v4l2_fourcc('B', '3', '1', '2') /* 48 BGR 12-bit per component */
++#define V4L2_PIX_FMT_BGR48 v4l2_fourcc('B', 'G', 'R', '6') /* 48 BGR 16-bit per component */
++#define V4L2_PIX_FMT_RGB48 v4l2_fourcc('R', 'G', 'B', '6') /* 48 RGB 16-bit per component */
+ #define V4L2_PIX_FMT_ABGR64_12 v4l2_fourcc('B', '4', '1', '2') /* 64 BGRA 12-bit per component */
+
+ /* RGB formats (6 bytes per pixel) */
diff --git a/target/linux/bcm27xx/patches-6.6/950-1149-media-uapi-Add-Raspberry-Pi-PiSP-Back-End-uAPI.patch b/target/linux/bcm27xx/patches-6.6/950-1149-media-uapi-Add-Raspberry-Pi-PiSP-Back-End-uAPI.patch
new file mode 100644
index 0000000000..a59bcb1e97
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1149-media-uapi-Add-Raspberry-Pi-PiSP-Back-End-uAPI.patch
@@ -0,0 +1,1171 @@
+From be6996ad702fac96b36ea209ae04a71bd1c6e1d4 Mon Sep 17 00:00:00 2001
+From: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+Date: Fri, 24 May 2024 15:18:21 +0200
+Subject: [PATCH 1149/1215] media: uapi: Add Raspberry Pi PiSP Back End uAPI
+
+Add the Raspberry Pi PiSP Back End uAPI header.
+
+The header defines the data type used to configure the PiSP Back End
+ISP.
+
+The detailed description of the types and of the ISP configuration
+procedure is available at
+https://datasheets.raspberrypi.com/camera/raspberry-pi-image-signal-processor-specification.pdf
+
+Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+---
+ MAINTAINERS | 7 +
+ .../linux/media/raspberrypi/pisp_be_config.h | 927 ++++++++++++++++++
+ .../linux/media/raspberrypi/pisp_common.h | 199 ++++
+ 3 files changed, 1133 insertions(+)
+ create mode 100644 include/uapi/linux/media/raspberrypi/pisp_be_config.h
+ create mode 100644 include/uapi/linux/media/raspberrypi/pisp_common.h
+
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -18032,6 +18032,13 @@ L: linux-wireless@vger.kernel.org
+ S: Orphan
+ F: drivers/net/wireless/legacy/ray*
+
++RASPBERRY PI PISP BACK END
++M: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
++L: Raspberry Pi Kernel Maintenance <kernel-list@raspberrypi.com>
++L: linux-media@vger.kernel.org
++S: Maintained
++F: include/uapi/linux/media/raspberrypi/
++
+ RC-CORE / LIRC FRAMEWORK
+ M: Sean Young <sean@mess.org>
+ L: linux-media@vger.kernel.org
+--- /dev/null
++++ b/include/uapi/linux/media/raspberrypi/pisp_be_config.h
+@@ -0,0 +1,927 @@
++/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */
++/*
++ * PiSP Back End configuration definitions.
++ *
++ * Copyright (C) 2021 - Raspberry Pi Ltd
++ *
++ */
++#ifndef _UAPI_PISP_BE_CONFIG_H_
++#define _UAPI_PISP_BE_CONFIG_H_
++
++#include <linux/types.h>
++
++#include "pisp_common.h"
++
++/* byte alignment for inputs */
++#define PISP_BACK_END_INPUT_ALIGN 4u
++/* alignment for compressed inputs */
++#define PISP_BACK_END_COMPRESSED_ALIGN 8u
++/* minimum required byte alignment for outputs */
++#define PISP_BACK_END_OUTPUT_MIN_ALIGN 16u
++/* preferred byte alignment for outputs */
++#define PISP_BACK_END_OUTPUT_MAX_ALIGN 64u
++
++/* minimum allowed tile width anywhere in the pipeline */
++#define PISP_BACK_END_MIN_TILE_WIDTH 16u
++/* minimum allowed tile width anywhere in the pipeline */
++#define PISP_BACK_END_MIN_TILE_HEIGHT 16u
++
++#define PISP_BACK_END_NUM_OUTPUTS 2
++#define PISP_BACK_END_HOG_OUTPUT 1
++
++#define PISP_BACK_END_NUM_TILES 64
++
++enum pisp_be_bayer_enable {
++ PISP_BE_BAYER_ENABLE_INPUT = 0x000001,
++ PISP_BE_BAYER_ENABLE_DECOMPRESS = 0x000002,
++ PISP_BE_BAYER_ENABLE_DPC = 0x000004,
++ PISP_BE_BAYER_ENABLE_GEQ = 0x000008,
++ PISP_BE_BAYER_ENABLE_TDN_INPUT = 0x000010,
++ PISP_BE_BAYER_ENABLE_TDN_DECOMPRESS = 0x000020,
++ PISP_BE_BAYER_ENABLE_TDN = 0x000040,
++ PISP_BE_BAYER_ENABLE_TDN_COMPRESS = 0x000080,
++ PISP_BE_BAYER_ENABLE_TDN_OUTPUT = 0x000100,
++ PISP_BE_BAYER_ENABLE_SDN = 0x000200,
++ PISP_BE_BAYER_ENABLE_BLC = 0x000400,
++ PISP_BE_BAYER_ENABLE_STITCH_INPUT = 0x000800,
++ PISP_BE_BAYER_ENABLE_STITCH_DECOMPRESS = 0x001000,
++ PISP_BE_BAYER_ENABLE_STITCH = 0x002000,
++ PISP_BE_BAYER_ENABLE_STITCH_COMPRESS = 0x004000,
++ PISP_BE_BAYER_ENABLE_STITCH_OUTPUT = 0x008000,
++ PISP_BE_BAYER_ENABLE_WBG = 0x010000,
++ PISP_BE_BAYER_ENABLE_CDN = 0x020000,
++ PISP_BE_BAYER_ENABLE_LSC = 0x040000,
++ PISP_BE_BAYER_ENABLE_TONEMAP = 0x080000,
++ PISP_BE_BAYER_ENABLE_CAC = 0x100000,
++ PISP_BE_BAYER_ENABLE_DEBIN = 0x200000,
++ PISP_BE_BAYER_ENABLE_DEMOSAIC = 0x400000,
++};
++
++enum pisp_be_rgb_enable {
++ PISP_BE_RGB_ENABLE_INPUT = 0x000001,
++ PISP_BE_RGB_ENABLE_CCM = 0x000002,
++ PISP_BE_RGB_ENABLE_SAT_CONTROL = 0x000004,
++ PISP_BE_RGB_ENABLE_YCBCR = 0x000008,
++ PISP_BE_RGB_ENABLE_FALSE_COLOUR = 0x000010,
++ PISP_BE_RGB_ENABLE_SHARPEN = 0x000020,
++ /* Preferred colours would occupy 0x000040 */
++ PISP_BE_RGB_ENABLE_YCBCR_INVERSE = 0x000080,
++ PISP_BE_RGB_ENABLE_GAMMA = 0x000100,
++ PISP_BE_RGB_ENABLE_CSC0 = 0x000200,
++ PISP_BE_RGB_ENABLE_CSC1 = 0x000400,
++ PISP_BE_RGB_ENABLE_DOWNSCALE0 = 0x001000,
++ PISP_BE_RGB_ENABLE_DOWNSCALE1 = 0x002000,
++ PISP_BE_RGB_ENABLE_RESAMPLE0 = 0x008000,
++ PISP_BE_RGB_ENABLE_RESAMPLE1 = 0x010000,
++ PISP_BE_RGB_ENABLE_OUTPUT0 = 0x040000,
++ PISP_BE_RGB_ENABLE_OUTPUT1 = 0x080000,
++ PISP_BE_RGB_ENABLE_HOG = 0x200000
++};
++
++#define PISP_BE_RGB_ENABLE_CSC(i) (PISP_BE_RGB_ENABLE_CSC0 << (i))
++#define PISP_BE_RGB_ENABLE_DOWNSCALE(i) (PISP_BE_RGB_ENABLE_DOWNSCALE0 << (i))
++#define PISP_BE_RGB_ENABLE_RESAMPLE(i) (PISP_BE_RGB_ENABLE_RESAMPLE0 << (i))
++#define PISP_BE_RGB_ENABLE_OUTPUT(i) (PISP_BE_RGB_ENABLE_OUTPUT0 << (i))
++
++/*
++ * We use the enable flags to show when blocks are "dirty", but we need some
++ * extra ones too.
++ */
++enum pisp_be_dirty {
++ PISP_BE_DIRTY_GLOBAL = 0x0001,
++ PISP_BE_DIRTY_SH_FC_COMBINE = 0x0002,
++ PISP_BE_DIRTY_CROP = 0x0004
++};
++
++/**
++ * struct pisp_be_global_config - PiSP global enable bitmaps
++ * @bayer_enables: Bayer input enable flags
++ * @rgb_enables: RGB output enable flags
++ * @bayer_order: Bayer input format ordering
++ * @pad: Padding bytes
++ */
++struct pisp_be_global_config {
++ __u32 bayer_enables;
++ __u32 rgb_enables;
++ __u8 bayer_order;
++ __u8 pad[3];
++} __attribute__((packed));
++
++/**
++ * struct pisp_be_input_buffer_config - PiSP Back End input buffer
++ * @addr: Input buffer address
++ */
++struct pisp_be_input_buffer_config {
++ /* low 32 bits followed by high 32 bits (for each of up to 3 planes) */
++ __u32 addr[3][2];
++} __attribute__((packed));
++
++/**
++ * struct pisp_be_dpc_config - PiSP Back End DPC config
++ *
++ * Defective Pixel Correction configuration
++ *
++ * @coeff_level: Coefficient for the darkest neighbouring pixel value
++ * @coeff_range: Coefficient for the range of pixels for this Bayer channel
++ * @pad: Padding byte
++ * @flags: DPC configuration flags
++ */
++struct pisp_be_dpc_config {
++ __u8 coeff_level;
++ __u8 coeff_range;
++ __u8 pad;
++#define PISP_BE_DPC_FLAG_FOLDBACK 1
++ __u8 flags;
++} __attribute__((packed));
++
++/**
++ * struct pisp_be_geq_config - PiSP Back End GEQ config
++ *
++ * Green Equalisation configuration
++ *
++ * @offset: Offset value for threshold calculation
++ * @slope_sharper: Slope/Sharper configuration
++ * @min: Minimum value the threshold may have
++ * @max: Maximum value the threshold may have
++ */
++struct pisp_be_geq_config {
++ __u16 offset;
++#define PISP_BE_GEQ_SHARPER BIT(15)
++#define PISP_BE_GEQ_SLOPE ((1 << 10) - 1)
++ /* top bit is the "sharper" flag, slope value is bottom 10 bits */
++ __u16 slope_sharper;
++ __u16 min;
++ __u16 max;
++} __attribute__((packed));
++
++/**
++ * struct pisp_be_tdn_input_buffer_config - PiSP Back End TDN input buffer
++ * @addr: TDN input buffer address
++ */
++struct pisp_be_tdn_input_buffer_config {
++ /* low 32 bits followed by high 32 bits */
++ __u32 addr[2];
++} __attribute__((packed));
++
++/**
++ * struct pisp_be_tdn_config - PiSP Back End TDN config
++ *
++ * Temporal Denoise configuration
++ *
++ * @black_level: Black level value subtracted from pixels
++ * @ratio: Multiplier for the LTA input frame
++ * @noise_constant: Constant offset value used in noise estimation
++ * @noise_slope: Noise estimation multiplier
++ * @threshold: Threshold for TDN operations
++ * @reset: Disable TDN operations
++ * @pad: Padding byte
++ */
++struct pisp_be_tdn_config {
++ __u16 black_level;
++ __u16 ratio;
++ __u16 noise_constant;
++ __u16 noise_slope;
++ __u16 threshold;
++ __u8 reset;
++ __u8 pad;
++} __attribute__((packed));
++
++/**
++ * struct pisp_be_tdn_output_buffer_config - PiSP Back End TDN output buffer
++ * @addr: TDN output buffer address
++ */
++struct pisp_be_tdn_output_buffer_config {
++ /* low 32 bits followed by high 32 bits */
++ __u32 addr[2];
++} __attribute__((packed));
++
++/**
++ * struct pisp_be_sdn_config - PiSP Back End SDN config
++ *
++ * Spatial Denoise configuration
++ *
++ * @black_level: Black level subtracted from pixel for noise estimation
++ * @leakage: Proportion of the original undenoised value to mix in
++ * denoised output
++ * @pad: Padding byte
++ * @noise_constant: Noise constant used for noise estimation
++ * @noise_slope: Noise slope value used for noise estimation
++ * @noise_constant2: Second noise constant used for noise estimation
++ * @noise_slope2: Second slope value used for noise estimation
++ */
++struct pisp_be_sdn_config {
++ __u16 black_level;
++ __u8 leakage;
++ __u8 pad;
++ __u16 noise_constant;
++ __u16 noise_slope;
++ __u16 noise_constant2;
++ __u16 noise_slope2;
++} __attribute__((packed));
++
++/**
++ * struct pisp_be_stitch_input_buffer_config - PiSP Back End Stitch input
++ * @addr: Stitch input buffer address
++ */
++struct pisp_be_stitch_input_buffer_config {
++ /* low 32 bits followed by high 32 bits */
++ __u32 addr[2];
++} __attribute__((packed));
++
++#define PISP_BE_STITCH_STREAMING_LONG 0x8000
++#define PISP_BE_STITCH_EXPOSURE_RATIO_MASK 0x7fff
++
++/**
++ * struct pisp_be_stitch_config - PiSP Back End Stitch config
++ *
++ * Stitch block configuration
++ *
++ * @threshold_lo: Low threshold value
++ * @threshold_diff_power: Low and high threshold difference
++ * @pad: Padding bytes
++ * @exposure_ratio: Multiplier to convert long exposure pixels into
++ * short exposure pixels
++ * @motion_threshold_256: Motion threshold above which short exposure
++ * pixels are used
++ * @motion_threshold_recip: Reciprocal of motion_threshold_256 value
++ */
++struct pisp_be_stitch_config {
++ __u16 threshold_lo;
++ __u8 threshold_diff_power;
++ __u8 pad;
++
++ /* top bit indicates whether streaming input is the long exposure */
++ __u16 exposure_ratio;
++
++ __u8 motion_threshold_256;
++ __u8 motion_threshold_recip;
++} __attribute__((packed));
++
++/**
++ * struct pisp_be_stitch_output_buffer_config - PiSP Back End Stitch output
++ * @addr: Stitch input buffer address
++ */
++struct pisp_be_stitch_output_buffer_config {
++ /* low 32 bits followed by high 32 bits */
++ __u32 addr[2];
++} __attribute__((packed));
++
++/**
++ * struct pisp_be_cdn_config - PiSP Back End CDN config
++ *
++ * Colour Denoise configuration
++ *
++ * @thresh: Constant for noise estimation
++ * @iir_strength: Relative strength of the IIR part of the filter
++ * @g_adjust: Proportion of the change assigned to the G channel
++ */
++struct pisp_be_cdn_config {
++ __u16 thresh;
++ __u8 iir_strength;
++ __u8 g_adjust;
++} __attribute__((packed));
++
++#define PISP_BE_LSC_LOG_GRID_SIZE 5
++#define PISP_BE_LSC_GRID_SIZE (1 << PISP_BE_LSC_LOG_GRID_SIZE)
++#define PISP_BE_LSC_STEP_PRECISION 18
++
++/**
++ * struct pisp_be_lsc_config - PiSP Back End LSC config
++ *
++ * Lens Shading Correction configuration
++ *
++ * @grid_step_x: Reciprocal of cell size width
++ * @grid_step_y: Reciprocal of cell size height
++ * @lut_packed: Jointly-coded RGB gains for each LSC grid
++ */
++struct pisp_be_lsc_config {
++ /* (1<<18) / grid_cell_width */
++ __u16 grid_step_x;
++ /* (1<<18) / grid_cell_height */
++ __u16 grid_step_y;
++ /* RGB gains jointly encoded in 32 bits */
++#define PISP_BE_LSC_LUT_SIZE (PISP_BE_LSC_GRID_SIZE + 1)
++ __u32 lut_packed[PISP_BE_LSC_LUT_SIZE][PISP_BE_LSC_LUT_SIZE];
++} __attribute__((packed));
++
++/**
++ * struct pisp_be_lsc_extra - PiSP Back End LSC Extra config
++ * @offset_x: Horizontal offset into the LSC table of this tile
++ * @offset_y: Vertical offset into the LSC table of this tile
++ */
++struct pisp_be_lsc_extra {
++ __u16 offset_x;
++ __u16 offset_y;
++} __attribute__((packed));
++
++#define PISP_BE_CAC_LOG_GRID_SIZE 3
++#define PISP_BE_CAC_GRID_SIZE (1 << PISP_BE_CAC_LOG_GRID_SIZE)
++#define PISP_BE_CAC_STEP_PRECISION 20
++
++/**
++ * struct pisp_be_cac_config - PiSP Back End CAC config
++ *
++ * Chromatic Aberration Correction config
++ *
++ * @grid_step_x: Reciprocal of cell size width
++ * @grid_step_y: Reciprocal of cell size height
++ * @lut: Pixel shift for the CAC grid
++ */
++struct pisp_be_cac_config {
++ /* (1<<20) / grid_cell_width */
++ __u16 grid_step_x;
++ /* (1<<20) / grid_cell_height */
++ __u16 grid_step_y;
++ /* [gridy][gridx][rb][xy] */
++#define PISP_BE_CAC_LUT_SIZE (PISP_BE_CAC_GRID_SIZE + 1)
++ __s8 lut[PISP_BE_CAC_LUT_SIZE][PISP_BE_CAC_LUT_SIZE][2][2];
++} __attribute__((packed));
++
++/**
++ * struct pisp_be_cac_extra - PiSP Back End CAC extra config
++ * @offset_x: Horizontal offset into the CAC table of this tile
++ * @offset_y: Horizontal offset into the CAC table of this tile
++ */
++struct pisp_be_cac_extra {
++ __u16 offset_x;
++ __u16 offset_y;
++} __attribute__((packed));
++
++#define PISP_BE_DEBIN_NUM_COEFFS 4
++
++/**
++ * struct pisp_be_debin_config - PiSP Back End Debin config
++ *
++ * Debinning configuration
++ *
++ * @coeffs: Filter coefficients for debinning
++ * @h_enable: Horizontal debinning enable
++ * @v_enable: Vertical debinning enable
++ * @pad: Padding bytes
++ */
++struct pisp_be_debin_config {
++ __s8 coeffs[PISP_BE_DEBIN_NUM_COEFFS];
++ __s8 h_enable;
++ __s8 v_enable;
++ __s8 pad[2];
++} __attribute__((packed));
++
++#define PISP_BE_TONEMAP_LUT_SIZE 64
++
++/**
++ * struct pisp_be_tonemap_config - PiSP Back End Tonemap config
++ *
++ * Tonemapping configuration
++ *
++ * @detail_constant: Constant value for threshold calculation
++ * @detail_slope: Slope value for threshold calculation
++ * @iir_strength: Relative strength of the IIR fiter
++ * @strength: Strength factor
++ * @lut: Look-up table for tonemap curve
++ */
++struct pisp_be_tonemap_config {
++ __u16 detail_constant;
++ __u16 detail_slope;
++ __u16 iir_strength;
++ __u16 strength;
++ __u32 lut[PISP_BE_TONEMAP_LUT_SIZE];
++} __attribute__((packed));
++
++/**
++ * struct pisp_be_demosaic_config - PiSP Back End Demosaic config
++ *
++ * Demosaic configuration
++ *
++ * @sharper: Use other Bayer channels to increase sharpness
++ * @fc_mode: Built-in false colour suppression mode
++ * @pad: Padding bytes
++ */
++struct pisp_be_demosaic_config {
++ __u8 sharper;
++ __u8 fc_mode;
++ __u8 pad[2];
++} __attribute__((packed));
++
++/**
++ * struct pisp_be_ccm_config - PiSP Back End CCM config
++ *
++ * Colour Correction Matrix configuration
++ *
++ * @coeffs: Matrix coefficients
++ * @pad: Padding bytes
++ * @offsets: Offsets triplet
++ */
++struct pisp_be_ccm_config {
++ __s16 coeffs[9];
++ __u8 pad[2];
++ __s32 offsets[3];
++} __attribute__((packed));
++
++/**
++ * struct pisp_be_sat_control_config - PiSP Back End SAT config
++ *
++ * Saturation Control configuration
++ *
++ * @shift_r: Left shift for Red colour channel
++ * @shift_g: Left shift for Green colour channel
++ * @shift_b: Left shift for Blue colour channel
++ * @pad: Padding byte
++ */
++struct pisp_be_sat_control_config {
++ __u8 shift_r;
++ __u8 shift_g;
++ __u8 shift_b;
++ __u8 pad;
++} __attribute__((packed));
++
++/**
++ * struct pisp_be_false_colour_config - PiSP Back End False Colour config
++ *
++ * False Colour configuration
++ *
++ * @distance: Distance of neighbouring pixels, either 1 or 2
++ * @pad: Padding bytes
++ */
++struct pisp_be_false_colour_config {
++ __u8 distance;
++ __u8 pad[3];
++} __attribute__((packed));
++
++#define PISP_BE_SHARPEN_SIZE 5
++#define PISP_BE_SHARPEN_FUNC_NUM_POINTS 9
++
++/**
++ * struct pisp_be_sharpen_config - PiSP Back End Sharpening config
++ *
++ * Sharpening configuration
++ *
++ * @kernel0: Coefficient for filter 0
++ * @pad0: Padding byte
++ * @kernel1: Coefficient for filter 1
++ * @pad1: Padding byte
++ * @kernel2: Coefficient for filter 2
++ * @pad2: Padding byte
++ * @kernel3: Coefficient for filter 3
++ * @pad3: Padding byte
++ * @kernel4: Coefficient for filter 4
++ * @pad4: Padding byte
++ * @threshold_offset0: Offset for filter 0 response calculation
++ * @threshold_slope0: Slope multiplier for the filter 0 response calculation
++ * @scale0: Scale factor for filter 0 response calculation
++ * @pad5: Padding byte
++ * @threshold_offset1: Offset for filter 0 response calculation
++ * @threshold_slope1: Slope multiplier for the filter 0 response calculation
++ * @scale1: Scale factor for filter 0 response calculation
++ * @pad6: Padding byte
++ * @threshold_offset2: Offset for filter 0 response calculation
++ * @threshold_slope2: Slope multiplier for the filter 0 response calculation
++ * @scale2: Scale factor for filter 0 response calculation
++ * @pad7: Padding byte
++ * @threshold_offset3: Offset for filter 0 response calculation
++ * @threshold_slope3: Slope multiplier for the filter 0 response calculation
++ * @scale3: Scale factor for filter 0 response calculation
++ * @pad8: Padding byte
++ * @threshold_offset4: Offset for filter 0 response calculation
++ * @threshold_slope4: Slope multiplier for the filter 0 response calculation
++ * @scale4: Scale factor for filter 0 response calculation
++ * @pad9: Padding byte
++ * @positive_strength: Factor to scale the positive sharpening strength
++ * @positive_pre_limit: Maximum allowed possible positive sharpening value
++ * @positive_func: Gain factor applied to positive sharpening response
++ * @positive_limit: Final gain factor applied to positive sharpening
++ * @negative_strength: Factor to scale the negative sharpening strength
++ * @negative_pre_limit: Maximum allowed possible negative sharpening value
++ * @negative_func: Gain factor applied to negative sharpening response
++ * @negative_limit: Final gain factor applied to negative sharpening
++ * @enables: Filter enable mask
++ * @white: White output pixel filter mask
++ * @black: Black output pixel filter mask
++ * @grey: Grey output pixel filter mask
++ */
++struct pisp_be_sharpen_config {
++ __s8 kernel0[PISP_BE_SHARPEN_SIZE * PISP_BE_SHARPEN_SIZE];
++ __s8 pad0[3];
++ __s8 kernel1[PISP_BE_SHARPEN_SIZE * PISP_BE_SHARPEN_SIZE];
++ __s8 pad1[3];
++ __s8 kernel2[PISP_BE_SHARPEN_SIZE * PISP_BE_SHARPEN_SIZE];
++ __s8 pad2[3];
++ __s8 kernel3[PISP_BE_SHARPEN_SIZE * PISP_BE_SHARPEN_SIZE];
++ __s8 pad3[3];
++ __s8 kernel4[PISP_BE_SHARPEN_SIZE * PISP_BE_SHARPEN_SIZE];
++ __s8 pad4[3];
++ __u16 threshold_offset0;
++ __u16 threshold_slope0;
++ __u16 scale0;
++ __u16 pad5;
++ __u16 threshold_offset1;
++ __u16 threshold_slope1;
++ __u16 scale1;
++ __u16 pad6;
++ __u16 threshold_offset2;
++ __u16 threshold_slope2;
++ __u16 scale2;
++ __u16 pad7;
++ __u16 threshold_offset3;
++ __u16 threshold_slope3;
++ __u16 scale3;
++ __u16 pad8;
++ __u16 threshold_offset4;
++ __u16 threshold_slope4;
++ __u16 scale4;
++ __u16 pad9;
++ __u16 positive_strength;
++ __u16 positive_pre_limit;
++ __u16 positive_func[PISP_BE_SHARPEN_FUNC_NUM_POINTS];
++ __u16 positive_limit;
++ __u16 negative_strength;
++ __u16 negative_pre_limit;
++ __u16 negative_func[PISP_BE_SHARPEN_FUNC_NUM_POINTS];
++ __u16 negative_limit;
++ __u8 enables;
++ __u8 white;
++ __u8 black;
++ __u8 grey;
++} __attribute__((packed));
++
++/**
++ * struct pisp_be_sh_fc_combine_config - PiSP Back End Sharpening and
++ * False Colour config
++ *
++ * Sharpening and False Colour configuration
++ *
++ * @y_factor: Control amount of desaturation of pixels being darkened
++ * @c1_factor: Control amount of brightening of a pixel for the Cb
++ * channel
++ * @c2_factor: Control amount of brightening of a pixel for the Cr
++ * channel
++ * @pad: Padding byte
++ */
++struct pisp_be_sh_fc_combine_config {
++ __u8 y_factor;
++ __u8 c1_factor;
++ __u8 c2_factor;
++ __u8 pad;
++} __attribute__((packed));
++
++#define PISP_BE_GAMMA_LUT_SIZE 64
++
++/**
++ * struct pisp_be_gamma_config - PiSP Back End Gamma configuration
++ * @lut: Gamma curve look-up table
++ */
++struct pisp_be_gamma_config {
++ __u32 lut[PISP_BE_GAMMA_LUT_SIZE];
++} __attribute__((packed));
++
++/**
++ * struct pisp_be_crop_config - PiSP Back End Crop config
++ *
++ * Crop configuration
++ *
++ * @offset_x: Number of pixels cropped from the left of the tile
++ * @offset_y: Number of pixels cropped from the top of the tile
++ * @width: Width of the cropped tile output
++ * @height: Height of the cropped tile output
++ */
++struct pisp_be_crop_config {
++ __u16 offset_x, offset_y;
++ __u16 width, height;
++} __attribute__((packed));
++
++#define PISP_BE_RESAMPLE_FILTER_SIZE 96
++
++/**
++ * struct pisp_be_resample_config - PiSP Back End Resampling config
++ *
++ * Resample configuration
++ *
++ * @scale_factor_h: Horizontal scale factor
++ * @scale_factor_v: Vertical scale factor
++ * @coef: Resample coefficients
++ */
++struct pisp_be_resample_config {
++ __u16 scale_factor_h, scale_factor_v;
++ __s16 coef[PISP_BE_RESAMPLE_FILTER_SIZE];
++} __attribute__((packed));
++
++/**
++ * struct pisp_be_resample_extra - PiSP Back End Resample config
++ *
++ * Resample configuration
++ *
++ * @scaled_width: Width in pixels of the scaled output
++ * @scaled_height: Height in pixels of the scaled output
++ * @initial_phase_h: Initial horizontal phase
++ * @initial_phase_v: Initial vertical phase
++ */
++struct pisp_be_resample_extra {
++ __u16 scaled_width;
++ __u16 scaled_height;
++ __s16 initial_phase_h[3];
++ __s16 initial_phase_v[3];
++} __attribute__((packed));
++
++/**
++ * struct pisp_be_downscale_config - PiSP Back End Downscale config
++ *
++ * Downscale configuration
++ *
++ * @scale_factor_h: Horizontal scale factor
++ * @scale_factor_v: Vertical scale factor
++ * @scale_recip_h: Horizontal reciprocal factor
++ * @scale_recip_v: Vertical reciprocal factor
++ */
++struct pisp_be_downscale_config {
++ __u16 scale_factor_h;
++ __u16 scale_factor_v;
++ __u16 scale_recip_h;
++ __u16 scale_recip_v;
++} __attribute__((packed));
++
++/**
++ * struct pisp_be_downscale_extra - PiSP Back End Downscale Extra config
++ * @scaled_width: Scaled image width
++ * @scaled_height: Scaled image height
++ */
++struct pisp_be_downscale_extra {
++ __u16 scaled_width;
++ __u16 scaled_height;
++} __attribute__((packed));
++
++/**
++ * struct pisp_be_hog_config - PiSP Back End HOG config
++ *
++ * Histogram of Oriented Gradients configuration
++ *
++ * @compute_signed: Set 0 for unsigned gradients, 1 for signed
++ * @channel_mix: Channels proportions to use
++ * @stride: Stride in bytes between blocks directly below
++ */
++struct pisp_be_hog_config {
++ __u8 compute_signed;
++ __u8 channel_mix[3];
++ __u32 stride;
++} __attribute__((packed));
++
++struct pisp_be_axi_config {
++ __u8 r_qos; /* Read QoS */
++ __u8 r_cache_prot; /* Read { prot[2:0], cache[3:0] } */
++ __u8 w_qos; /* Write QoS */
++ __u8 w_cache_prot; /* Write { prot[2:0], cache[3:0] } */
++} __attribute__((packed));
++
++/**
++ * enum pisp_be_transform - PiSP Back End Transform flags
++ * @PISP_BE_TRANSFORM_NONE: No transform
++ * @PISP_BE_TRANSFORM_HFLIP: Horizontal flip
++ * @PISP_BE_TRANSFORM_VFLIP: Vertical flip
++ * @PISP_BE_TRANSFORM_ROT180: 180 degress rotation
++ */
++enum pisp_be_transform {
++ PISP_BE_TRANSFORM_NONE = 0x0,
++ PISP_BE_TRANSFORM_HFLIP = 0x1,
++ PISP_BE_TRANSFORM_VFLIP = 0x2,
++ PISP_BE_TRANSFORM_ROT180 =
++ (PISP_BE_TRANSFORM_HFLIP | PISP_BE_TRANSFORM_VFLIP)
++};
++
++struct pisp_be_output_format_config {
++ struct pisp_image_format_config image;
++ __u8 transform;
++ __u8 pad[3];
++ __u16 lo;
++ __u16 hi;
++ __u16 lo2;
++ __u16 hi2;
++} __attribute__((packed));
++
++/**
++ * struct pisp_be_output_buffer_config - PiSP Back End Output buffer
++ * @addr: Output buffer address
++ */
++struct pisp_be_output_buffer_config {
++ /* low 32 bits followed by high 32 bits (for each of 3 planes) */
++ __u32 addr[3][2];
++} __attribute__((packed));
++
++/**
++ * struct pisp_be_hog_buffer_config - PiSP Back End HOG buffer
++ * @addr: HOG buffer address
++ */
++struct pisp_be_hog_buffer_config {
++ /* low 32 bits followed by high 32 bits */
++ __u32 addr[2];
++} __attribute__((packed));
++
++/**
++ * struct pisp_be_config - RaspberryPi PiSP Back End Processing configuration
++ *
++ * @global: Global PiSP configuration
++ * @input_format: Input image format
++ * @decompress: Decompress configuration
++ * @dpc: Defective Pixel Correction configuration
++ * @geq: Green Equalisation configuration
++ * @tdn_input_format: Temporal Denoise input format
++ * @tdn_decompress: Temporal Denoise decompress configuration
++ * @tdn: Temporal Denoise configuration
++ * @tdn_compress: Temporal Denoise compress configuration
++ * @tdn_output_format: Temporal Denoise output format
++ * @sdn: Spatial Denoise configuration
++ * @blc: Black Level Correction configuration
++ * @stitch_compress: Stitch compress configuration
++ * @stitch_output_format: Stitch output format
++ * @stitch_input_format: Stitch input format
++ * @stitch_decompress: Stitch decompress configuration
++ * @stitch: Stitch configuration
++ * @lsc: Lens Shading Correction configuration
++ * @wbg: White Balance Gain configuration
++ * @cdn: Colour Denoise configuration
++ * @cac: Colour Aberration Correction configuration
++ * @debin: Debinning configuration
++ * @tonemap: Tonemapping configuration
++ * @demosaic: Demosaicing configuration
++ * @ccm: Colour Correction Matrix configuration
++ * @sat_control: Saturation Control configuration
++ * @ycbcr: YCbCr colour correction configuration
++ * @sharpen: Sharpening configuration
++ * @false_colour: False colour correction
++ * @sh_fc_combine: Sharpening and False Colour correction
++ * @ycbcr_inverse: Inverse YCbCr colour correction
++ * @gamma: Gamma curve configuration
++ * @csc: Color Space Conversion configuration
++ * @downscale: Downscale configuration
++ * @resample: Resampling configuration
++ * @output_format: Output format configuration
++ * @hog: HOG configuration
++ */
++struct pisp_be_config {
++ struct pisp_be_global_config global;
++ struct pisp_image_format_config input_format;
++ struct pisp_decompress_config decompress;
++ struct pisp_be_dpc_config dpc;
++ struct pisp_be_geq_config geq;
++ struct pisp_image_format_config tdn_input_format;
++ struct pisp_decompress_config tdn_decompress;
++ struct pisp_be_tdn_config tdn;
++ struct pisp_compress_config tdn_compress;
++ struct pisp_image_format_config tdn_output_format;
++ struct pisp_be_sdn_config sdn;
++ struct pisp_bla_config blc;
++ struct pisp_compress_config stitch_compress;
++ struct pisp_image_format_config stitch_output_format;
++ struct pisp_image_format_config stitch_input_format;
++ struct pisp_decompress_config stitch_decompress;
++ struct pisp_be_stitch_config stitch;
++ struct pisp_be_lsc_config lsc;
++ struct pisp_wbg_config wbg;
++ struct pisp_be_cdn_config cdn;
++ struct pisp_be_cac_config cac;
++ struct pisp_be_debin_config debin;
++ struct pisp_be_tonemap_config tonemap;
++ struct pisp_be_demosaic_config demosaic;
++ struct pisp_be_ccm_config ccm;
++ struct pisp_be_sat_control_config sat_control;
++ struct pisp_be_ccm_config ycbcr;
++ struct pisp_be_sharpen_config sharpen;
++ struct pisp_be_false_colour_config false_colour;
++ struct pisp_be_sh_fc_combine_config sh_fc_combine;
++ struct pisp_be_ccm_config ycbcr_inverse;
++ struct pisp_be_gamma_config gamma;
++ struct pisp_be_ccm_config csc[PISP_BACK_END_NUM_OUTPUTS];
++ struct pisp_be_downscale_config downscale[PISP_BACK_END_NUM_OUTPUTS];
++ struct pisp_be_resample_config resample[PISP_BACK_END_NUM_OUTPUTS];
++ struct pisp_be_output_format_config
++ output_format[PISP_BACK_END_NUM_OUTPUTS];
++ struct pisp_be_hog_config hog;
++} __attribute__((packed));
++
++/**
++ * enum pisp_tile_edge - PiSP Back End Tile position
++ * @PISP_LEFT_EDGE: Left edge tile
++ * @PISP_RIGHT_EDGE: Right edge tile
++ * @PISP_TOP_EDGE: Top edge tile
++ * @PISP_BOTTOM_EDGE: Bottom edge tile
++ */
++enum pisp_tile_edge {
++ PISP_LEFT_EDGE = (1 << 0),
++ PISP_RIGHT_EDGE = (1 << 1),
++ PISP_TOP_EDGE = (1 << 2),
++ PISP_BOTTOM_EDGE = (1 << 3)
++};
++
++/**
++ * struct pisp_tile - Raspberry Pi PiSP Back End tile configuration
++ *
++ * Tile parameters: each set of tile parameters is a 160-bytes block of data
++ * which contains the tile processing parameters.
++ *
++ * @edge: Edge tile flag
++ * @pad0: Padding bytes
++ * @input_addr_offset: Top-left pixel offset, in bytes
++ * @input_addr_offset2: Top-left pixel offset, in bytes for the second/
++ * third image planes
++ * @input_offset_x: Horizontal offset in pixels of this tile in the
++ * input image
++ * @input_offset_y: Vertical offset in pixels of this tile in the
++ * input image
++ * @input_width: Width in pixels of this tile
++ * @input_height: Height in pixels of the this tile
++ * @tdn_input_addr_offset: TDN input image offset, in bytes
++ * @tdn_output_addr_offset: TDN output image offset, in bytes
++ * @stitch_input_addr_offset: Stitch input image offset, in bytes
++ * @stitch_output_addr_offset: Stitch output image offset, in bytes
++ * @lsc_grid_offset_x: Horizontal offset in the LSC table for this tile
++ * @lsc_grid_offset_y: Vertical offset in the LSC table for this tile
++ * @cac_grid_offset_x: Horizontal offset in the CAC table for this tile
++ * @cac_grid_offset_y: Horizontal offset in the CAC table for this tile
++ * @crop_x_start: Number of pixels cropped from the left of the
++ * tile
++ * @crop_x_end: Number of pixels cropped from the right of the
++ * tile
++ * @crop_y_start: Number of pixels cropped from the top of the
++ * tile
++ * @crop_y_end: Number of pixels cropped from the bottom of the
++ * tile
++ * @downscale_phase_x: Initial horizontal phase in pixels
++ * @downscale_phase_y: Initial vertical phase in pixels
++ * @resample_in_width: Width in pixels of the tile entering the
++ * Resample block
++ * @resample_in_height: Height in pixels of the tile entering the
++ * Resample block
++ * @resample_phase_x: Initial horizontal phase for the Resample block
++ * @resample_phase_y: Initial vertical phase for the Resample block
++ * @output_offset_x: Horizontal offset in pixels where the tile will
++ * be written into the output image
++ * @output_offset_y: Vertical offset in pixels where the tile will be
++ * written into the output image
++ * @output_width: Width in pixels in the output image of this tile
++ * @output_height: Height in pixels in the output image of this tile
++ * @output_addr_offset: Offset in bytes into the output buffer
++ * @output_addr_offset2: Offset in bytes into the output buffer for the
++ * second and third plane
++ * @output_hog_addr_offset: Offset in bytes into the HOG buffer where
++ * results of this tile are to be written
++ */
++struct pisp_tile {
++ __u8 edge; /* enum pisp_tile_edge */
++ __u8 pad0[3];
++ /* 4 bytes */
++ __u32 input_addr_offset;
++ __u32 input_addr_offset2;
++ __u16 input_offset_x;
++ __u16 input_offset_y;
++ __u16 input_width;
++ __u16 input_height;
++ /* 20 bytes */
++ __u32 tdn_input_addr_offset;
++ __u32 tdn_output_addr_offset;
++ __u32 stitch_input_addr_offset;
++ __u32 stitch_output_addr_offset;
++ /* 36 bytes */
++ __u32 lsc_grid_offset_x;
++ __u32 lsc_grid_offset_y;
++ /* 44 bytes */
++ __u32 cac_grid_offset_x;
++ __u32 cac_grid_offset_y;
++ /* 52 bytes */
++ __u16 crop_x_start[PISP_BACK_END_NUM_OUTPUTS];
++ __u16 crop_x_end[PISP_BACK_END_NUM_OUTPUTS];
++ __u16 crop_y_start[PISP_BACK_END_NUM_OUTPUTS];
++ __u16 crop_y_end[PISP_BACK_END_NUM_OUTPUTS];
++ /* 68 bytes */
++ /* Ordering is planes then branches */
++ __u16 downscale_phase_x[3 * PISP_BACK_END_NUM_OUTPUTS];
++ __u16 downscale_phase_y[3 * PISP_BACK_END_NUM_OUTPUTS];
++ /* 92 bytes */
++ __u16 resample_in_width[PISP_BACK_END_NUM_OUTPUTS];
++ __u16 resample_in_height[PISP_BACK_END_NUM_OUTPUTS];
++ /* 100 bytes */
++ /* Ordering is planes then branches */
++ __u16 resample_phase_x[3 * PISP_BACK_END_NUM_OUTPUTS];
++ __u16 resample_phase_y[3 * PISP_BACK_END_NUM_OUTPUTS];
++ /* 124 bytes */
++ __u16 output_offset_x[PISP_BACK_END_NUM_OUTPUTS];
++ __u16 output_offset_y[PISP_BACK_END_NUM_OUTPUTS];
++ __u16 output_width[PISP_BACK_END_NUM_OUTPUTS];
++ __u16 output_height[PISP_BACK_END_NUM_OUTPUTS];
++ /* 140 bytes */
++ __u32 output_addr_offset[PISP_BACK_END_NUM_OUTPUTS];
++ __u32 output_addr_offset2[PISP_BACK_END_NUM_OUTPUTS];
++ /* 156 bytes */
++ __u32 output_hog_addr_offset;
++ /* 160 bytes */
++} __attribute__((packed));
++
++/**
++ * struct pisp_be_tiles_config - Raspberry Pi PiSP Back End configuration
++ * @tiles: Tile descriptors
++ * @num_tiles: Number of tiles
++ * @config: PiSP Back End configuration
++ */
++struct pisp_be_tiles_config {
++ struct pisp_tile tiles[PISP_BACK_END_NUM_TILES];
++ __u32 num_tiles;
++ struct pisp_be_config config;
++} __attribute__((packed));
++
++#endif /* _UAPI_PISP_BE_CONFIG_H_ */
+--- /dev/null
++++ b/include/uapi/linux/media/raspberrypi/pisp_common.h
+@@ -0,0 +1,199 @@
++/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */
++/*
++ * RP1 PiSP common definitions.
++ *
++ * Copyright (C) 2021 - Raspberry Pi Ltd.
++ *
++ */
++#ifndef _UAPI_PISP_COMMON_H_
++#define _UAPI_PISP_COMMON_H_
++
++#include <linux/types.h>
++
++struct pisp_image_format_config {
++ /* size in pixels */
++ __u16 width;
++ __u16 height;
++ /* must match struct pisp_image_format below */
++ __u32 format;
++ __s32 stride;
++ /* some planar image formats will need a second stride */
++ __s32 stride2;
++} __attribute__((packed));
++
++enum pisp_bayer_order {
++ /*
++ * Note how bayer_order&1 tells you if G is on the even pixels of the
++ * checkerboard or not, and bayer_order&2 tells you if R is on the even
++ * rows or is swapped with B. Note that if the top (of the 8) bits is
++ * set, this denotes a monochrome or greyscale image, and the lower bits
++ * should all be ignored.
++ */
++ PISP_BAYER_ORDER_RGGB = 0,
++ PISP_BAYER_ORDER_GBRG = 1,
++ PISP_BAYER_ORDER_BGGR = 2,
++ PISP_BAYER_ORDER_GRBG = 3,
++ PISP_BAYER_ORDER_GREYSCALE = 128
++};
++
++enum pisp_image_format {
++ /*
++ * Precise values are mostly tbd. Generally these will be portmanteau
++ * values comprising bit fields and flags. This format must be shared
++ * throughout the PiSP.
++ */
++ PISP_IMAGE_FORMAT_BPS_8 = 0x00000000,
++ PISP_IMAGE_FORMAT_BPS_10 = 0x00000001,
++ PISP_IMAGE_FORMAT_BPS_12 = 0x00000002,
++ PISP_IMAGE_FORMAT_BPS_16 = 0x00000003,
++ PISP_IMAGE_FORMAT_BPS_MASK = 0x00000003,
++
++ PISP_IMAGE_FORMAT_PLANARITY_INTERLEAVED = 0x00000000,
++ PISP_IMAGE_FORMAT_PLANARITY_SEMI_PLANAR = 0x00000010,
++ PISP_IMAGE_FORMAT_PLANARITY_PLANAR = 0x00000020,
++ PISP_IMAGE_FORMAT_PLANARITY_MASK = 0x00000030,
++
++ PISP_IMAGE_FORMAT_SAMPLING_444 = 0x00000000,
++ PISP_IMAGE_FORMAT_SAMPLING_422 = 0x00000100,
++ PISP_IMAGE_FORMAT_SAMPLING_420 = 0x00000200,
++ PISP_IMAGE_FORMAT_SAMPLING_MASK = 0x00000300,
++
++ PISP_IMAGE_FORMAT_ORDER_NORMAL = 0x00000000,
++ PISP_IMAGE_FORMAT_ORDER_SWAPPED = 0x00001000,
++
++ PISP_IMAGE_FORMAT_SHIFT_0 = 0x00000000,
++ PISP_IMAGE_FORMAT_SHIFT_1 = 0x00010000,
++ PISP_IMAGE_FORMAT_SHIFT_2 = 0x00020000,
++ PISP_IMAGE_FORMAT_SHIFT_3 = 0x00030000,
++ PISP_IMAGE_FORMAT_SHIFT_4 = 0x00040000,
++ PISP_IMAGE_FORMAT_SHIFT_5 = 0x00050000,
++ PISP_IMAGE_FORMAT_SHIFT_6 = 0x00060000,
++ PISP_IMAGE_FORMAT_SHIFT_7 = 0x00070000,
++ PISP_IMAGE_FORMAT_SHIFT_8 = 0x00080000,
++ PISP_IMAGE_FORMAT_SHIFT_MASK = 0x000f0000,
++
++ PISP_IMAGE_FORMAT_UNCOMPRESSED = 0x00000000,
++ PISP_IMAGE_FORMAT_COMPRESSION_MODE_1 = 0x01000000,
++ PISP_IMAGE_FORMAT_COMPRESSION_MODE_2 = 0x02000000,
++ PISP_IMAGE_FORMAT_COMPRESSION_MODE_3 = 0x03000000,
++ PISP_IMAGE_FORMAT_COMPRESSION_MASK = 0x03000000,
++
++ PISP_IMAGE_FORMAT_HOG_SIGNED = 0x04000000,
++ PISP_IMAGE_FORMAT_HOG_UNSIGNED = 0x08000000,
++ PISP_IMAGE_FORMAT_INTEGRAL_IMAGE = 0x10000000,
++ PISP_IMAGE_FORMAT_WALLPAPER_ROLL = 0x20000000,
++ PISP_IMAGE_FORMAT_THREE_CHANNEL = 0x40000000,
++
++ /* Lastly a few specific instantiations of the above. */
++ PISP_IMAGE_FORMAT_SINGLE_16 = PISP_IMAGE_FORMAT_BPS_16,
++ PISP_IMAGE_FORMAT_THREE_16 = PISP_IMAGE_FORMAT_BPS_16 |
++ PISP_IMAGE_FORMAT_THREE_CHANNEL
++};
++
++#define PISP_IMAGE_FORMAT_bps_8(fmt) \
++ (((fmt) & PISP_IMAGE_FORMAT_BPS_MASK) == PISP_IMAGE_FORMAT_BPS_8)
++#define PISP_IMAGE_FORMAT_bps_10(fmt) \
++ (((fmt) & PISP_IMAGE_FORMAT_BPS_MASK) == PISP_IMAGE_FORMAT_BPS_10)
++#define PISP_IMAGE_FORMAT_bps_12(fmt) \
++ (((fmt) & PISP_IMAGE_FORMAT_BPS_MASK) == PISP_IMAGE_FORMAT_BPS_12)
++#define PISP_IMAGE_FORMAT_bps_16(fmt) \
++ (((fmt) & PISP_IMAGE_FORMAT_BPS_MASK) == PISP_IMAGE_FORMAT_BPS_16)
++#define PISP_IMAGE_FORMAT_bps(fmt) \
++ (((fmt) & PISP_IMAGE_FORMAT_BPS_MASK) ? \
++ 8 + (2 << (((fmt) & PISP_IMAGE_FORMAT_BPS_MASK) - 1)) : 8)
++#define PISP_IMAGE_FORMAT_shift(fmt) \
++ (((fmt) & PISP_IMAGE_FORMAT_SHIFT_MASK) / PISP_IMAGE_FORMAT_SHIFT_1)
++#define PISP_IMAGE_FORMAT_three_channel(fmt) \
++ ((fmt) & PISP_IMAGE_FORMAT_THREE_CHANNEL)
++#define PISP_IMAGE_FORMAT_single_channel(fmt) \
++ (!((fmt) & PISP_IMAGE_FORMAT_THREE_CHANNEL))
++#define PISP_IMAGE_FORMAT_compressed(fmt) \
++ (((fmt) & PISP_IMAGE_FORMAT_COMPRESSION_MASK) != \
++ PISP_IMAGE_FORMAT_UNCOMPRESSED)
++#define PISP_IMAGE_FORMAT_sampling_444(fmt) \
++ (((fmt) & PISP_IMAGE_FORMAT_SAMPLING_MASK) == \
++ PISP_IMAGE_FORMAT_SAMPLING_444)
++#define PISP_IMAGE_FORMAT_sampling_422(fmt) \
++ (((fmt) & PISP_IMAGE_FORMAT_SAMPLING_MASK) == \
++ PISP_IMAGE_FORMAT_SAMPLING_422)
++#define PISP_IMAGE_FORMAT_sampling_420(fmt) \
++ (((fmt) & PISP_IMAGE_FORMAT_SAMPLING_MASK) == \
++ PISP_IMAGE_FORMAT_SAMPLING_420)
++#define PISP_IMAGE_FORMAT_order_normal(fmt) \
++ (!((fmt) & PISP_IMAGE_FORMAT_ORDER_SWAPPED))
++#define PISP_IMAGE_FORMAT_order_swapped(fmt) \
++ ((fmt) & PISP_IMAGE_FORMAT_ORDER_SWAPPED)
++#define PISP_IMAGE_FORMAT_interleaved(fmt) \
++ (((fmt) & PISP_IMAGE_FORMAT_PLANARITY_MASK) == \
++ PISP_IMAGE_FORMAT_PLANARITY_INTERLEAVED)
++#define PISP_IMAGE_FORMAT_semiplanar(fmt) \
++ (((fmt) & PISP_IMAGE_FORMAT_PLANARITY_MASK) == \
++ PISP_IMAGE_FORMAT_PLANARITY_SEMI_PLANAR)
++#define PISP_IMAGE_FORMAT_planar(fmt) \
++ (((fmt) & PISP_IMAGE_FORMAT_PLANARITY_MASK) == \
++ PISP_IMAGE_FORMAT_PLANARITY_PLANAR)
++#define PISP_IMAGE_FORMAT_wallpaper(fmt) \
++ ((fmt) & PISP_IMAGE_FORMAT_WALLPAPER_ROLL)
++#define PISP_IMAGE_FORMAT_HOG(fmt) \
++ ((fmt) & \
++ (PISP_IMAGE_FORMAT_HOG_SIGNED | PISP_IMAGE_FORMAT_HOG_UNSIGNED))
++
++#define PISP_WALLPAPER_WIDTH 128 /* in bytes */
++
++struct pisp_bla_config {
++ __u16 black_level_r;
++ __u16 black_level_gr;
++ __u16 black_level_gb;
++ __u16 black_level_b;
++ __u16 output_black_level;
++ __u8 pad[2];
++} __attribute__((packed));
++
++struct pisp_wbg_config {
++ __u16 gain_r;
++ __u16 gain_g;
++ __u16 gain_b;
++ __u8 pad[2];
++} __attribute__((packed));
++
++struct pisp_compress_config {
++ /* value subtracted from incoming data */
++ __u16 offset;
++ __u8 pad;
++ /* 1 => Companding; 2 => Delta (recommended); 3 => Combined (for HDR) */
++ __u8 mode;
++} __attribute__((packed));
++
++struct pisp_decompress_config {
++ /* value added to reconstructed data */
++ __u16 offset;
++ __u8 pad;
++ /* 1 => Companding; 2 => Delta (recommended); 3 => Combined (for HDR) */
++ __u8 mode;
++} __attribute__((packed));
++
++enum pisp_axi_flags {
++ /*
++ * round down bursts to end at a 32-byte boundary, to align following
++ * bursts
++ */
++ PISP_AXI_FLAG_ALIGN = 128,
++ /* for FE writer: force WSTRB high, to pad output to 16-byte boundary */
++ PISP_AXI_FLAG_PAD = 64,
++ /* for FE writer: Use Output FIFO level to trigger "panic" */
++ PISP_AXI_FLAG_PANIC = 32,
++};
++
++struct pisp_axi_config {
++ /*
++ * burst length minus one, which must be in the range 0:15; OR'd with
++ * flags
++ */
++ __u8 maxlen_flags;
++ /* { prot[2:0], cache[3:0] } fields, echoed on AXI bus */
++ __u8 cache_prot;
++ /* QoS field(s) (4x4 bits for FE writer; 4 bits for other masters) */
++ __u16 qos;
++} __attribute__((packed));
++
++#endif /* _UAPI_PISP_COMMON_H_ */
diff --git a/target/linux/bcm27xx/patches-6.6/950-1150-media-uapi-Document-meta-pixel-format-for-PiSP-BE-co.patch b/target/linux/bcm27xx/patches-6.6/950-1150-media-uapi-Document-meta-pixel-format-for-PiSP-BE-co.patch
new file mode 100644
index 0000000000..0ee62a7d33
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1150-media-uapi-Document-meta-pixel-format-for-PiSP-BE-co.patch
@@ -0,0 +1,86 @@
+From 7ca73020a5b26599d539083e413784e79891107e Mon Sep 17 00:00:00 2001
+From: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+Date: Fri, 26 Jan 2024 15:04:59 +0100
+Subject: [PATCH 1150/1215] media: uapi: Document meta pixel format for PiSP BE
+ config
+
+Add format description for the PiSP Back End configuration parameter
+buffer.
+
+Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
+---
+ .../userspace-api/media/v4l/meta-formats.rst | 1 +
+ .../media/v4l/metafmt-pisp-be.rst | 56 +++++++++++++++++++
+ 2 files changed, 57 insertions(+)
+ create mode 100644 Documentation/userspace-api/media/v4l/metafmt-pisp-be.rst
+
+--- a/Documentation/userspace-api/media/v4l/meta-formats.rst
++++ b/Documentation/userspace-api/media/v4l/meta-formats.rst
+@@ -15,6 +15,7 @@ These formats are used for the :ref:`met
+ metafmt-bcm2835-isp-stats
+ metafmt-d4xx
+ metafmt-intel-ipu3
++ metafmt-pisp-be
+ metafmt-rkisp1
+ metafmt-sensor-data
+ metafmt-uvc
+--- /dev/null
++++ b/Documentation/userspace-api/media/v4l/metafmt-pisp-be.rst
+@@ -0,0 +1,56 @@
++.. SPDX-License-Identifier: GPL-2.0
++
++.. _v4l2-meta-fmt-rpi-be-cfg:
++
++************************
++V4L2_META_FMT_RPI_BE_CFG
++************************
++
++Raspberry Pi PiSP Back End configuration format
++===============================================
++
++The Raspberry Pi PiSP Back End memory-to-memory image signal processor is
++configured by userspace by providing a buffer of configuration parameters
++to the `pispbe-config` output video device node using the
++:c:type:`v4l2_meta_format` interface.
++
++The PiSP Back End processes images in tiles, and its configuration requires
++specifying two different sets of parameters by populating the members of
++:c:type:`pisp_be_tiles_config` defined in the ``pisp_be_config.h`` header file.
++
++The `Raspberry Pi PiSP technical specification
++<https://datasheets.raspberrypi.com/camera/raspberry-pi-image-signal-processor-specification.pdf>`_
++provide detailed description of the ISP back end configuration and programming
++model.
++
++Global configuration data
++-------------------------
++
++The global configuration data describe how the pixels in a particular image are
++to be processed and is therefore shared across all the tiles of the image. So
++for example, LSC (Lens Shading Correction) or Denoise parameters would be common
++across all tiles from the same frame.
++
++Global configuration data are passed to the ISP by populating the member of
++:c:type:`pisp_be_config`.
++
++Tile parameters
++---------------
++
++As the ISP processes images in tiles, each set of tiles parameters describe how
++a single tile in an image is going to be processed. A single set of tile
++parameters consist of 160 bytes of data and to process a batch of tiles several
++sets of tiles parameters are required.
++
++Tiles parameters are passed to the ISP by populating the member of
++``pisp_tile`` and the ``num_tiles`` fields of :c:type:`pisp_be_tiles_config`.
++
++Raspberry Pi PiSP Back End uAPI data types
++==========================================
++
++This section describes the data types exposed to userspace by the Raspberry Pi
++PiSP Back End. The section is informative only, for a detailed description of
++each field refer to the `Raspberry Pi PiSP technical specification
++<https://datasheets.raspberrypi.com/camera/raspberry-pi-image-signal-processor-specification.pdf>`_.
++
++.. kernel-doc:: include/uapi/linux/media/raspberrypi/pisp_be_config.h
diff --git a/target/linux/bcm27xx/patches-6.6/950-1151-media-uapi-Document-PiSP-Compressed-RAW-Bayer-format.patch b/target/linux/bcm27xx/patches-6.6/950-1151-media-uapi-Document-PiSP-Compressed-RAW-Bayer-format.patch
new file mode 100644
index 0000000000..aa4b003e5b
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1151-media-uapi-Document-PiSP-Compressed-RAW-Bayer-format.patch
@@ -0,0 +1,106 @@
+From 5d6318f242cce5f9b5677baedde736a2b81061df Mon Sep 17 00:00:00 2001
+From: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+Date: Wed, 17 Jan 2024 11:21:50 +0200
+Subject: [PATCH 1151/1215] media: uapi: Document PiSP Compressed RAW Bayer
+ formats
+
+Document the Raspberry Pi compressed RAW Bayer formats.
+
+The compression algorithm description is provided by Nick Hollinghurst
+<nick.hollinghurst@raspberrypi.com> from Raspberry Pi.
+
+Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
+---
+ .../userspace-api/media/v4l/pixfmt-bayer.rst | 1 +
+ .../media/v4l/pixfmt-srggb8-pisp-comp.rst | 74 +++++++++++++++++++
+ 2 files changed, 75 insertions(+)
+ create mode 100644 Documentation/userspace-api/media/v4l/pixfmt-srggb8-pisp-comp.rst
+
+--- a/Documentation/userspace-api/media/v4l/pixfmt-bayer.rst
++++ b/Documentation/userspace-api/media/v4l/pixfmt-bayer.rst
+@@ -20,6 +20,7 @@ orders. See also `the Wikipedia article
+ :maxdepth: 1
+
+ pixfmt-srggb8
++ pixfmt-srggb8-pisp-comp
+ pixfmt-srggb10
+ pixfmt-srggb10p
+ pixfmt-srggb10alaw8
+--- /dev/null
++++ b/Documentation/userspace-api/media/v4l/pixfmt-srggb8-pisp-comp.rst
+@@ -0,0 +1,74 @@
++.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
++
++.. _v4l2-pix-fmt-pisp-comp1-rggb:
++.. _v4l2-pix-fmt-pisp-comp1-grbg:
++.. _v4l2-pix-fmt-pisp-comp1-gbrg:
++.. _v4l2-pix-fmt-pisp-comp1-bggr:
++.. _v4l2-pix-fmt-pisp-comp1-mono:
++.. _v4l2-pix-fmt-pisp-comp2-rggb:
++.. _v4l2-pix-fmt-pisp-comp2-grbg:
++.. _v4l2-pix-fmt-pisp-comp2-gbrg:
++.. _v4l2-pix-fmt-pisp-comp2-bggr:
++.. _v4l2-pix-fmt-pisp-comp2-mono:
++
++**************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
++V4L2_PIX_FMT_PISP_COMP1_RGGB ('PC1R'), V4L2_PIX_FMT_PISP_COMP1_GRBG ('PC1G'), V4L2_PIX_FMT_PISP_COMP1_GBRG ('PC1g'), V4L2_PIX_FMT_PISP_COMP1_BGGR ('PC1B), V4L2_PIX_FMT_PISP_COMP1_MONO ('PC1M'), V4L2_PIX_FMT_PISP_COMP2_RGGB ('PC2R'), V4L2_PIX_FMT_PISP_COMP2_GRBG ('PC2G'), V4L2_PIX_FMT_PISP_COMP2_GBRG ('PC2g'), V4L2_PIX_FMT_PISP_COMP2_BGGR ('PC2B), V4L2_PIX_FMT_PISP_COMP2_MONO ('PC2M')
++**************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
++
++================================================
++Raspberry Pi PiSP compressed 8-bit Bayer formats
++================================================
++
++Description
++===========
++
++The Raspberry Pi ISP (PiSP) uses a family of three fixed-rate compressed Bayer
++formats. A black-level offset may be subtracted to improve compression
++efficiency; the nominal black level and amount of offset must be signalled out
++of band. Each scanline is padded to a multiple of 8 pixels wide, and each block
++of 8 horizontally-contiguous pixels is coded using 8 bytes.
++
++Mode 1 uses a quantization and delta-based coding scheme which preserves up to
++12 significant bits. Mode 2 is a simple sqrt-like companding scheme with 6 PWL
++chords, preserving up to 12 significant bits. Mode 3 combines both companding
++(with 4 chords) and the delta scheme, preserving up to 14 significant bits.
++
++The remainder of this description applies to Modes 1 and 3.
++
++Each block of 8 pixels is separated into even and odd phases of 4 pixels,
++coded independently by 32-bit words at successive locations in memory.
++The two LS bits of each 32-bit word give its "quantization mode".
++
++In quantization mode 0, the lowest 321 quantization levels are multiples of
++FSD/4096 and the remaining levels are successive multiples of FSD/2048.
++Quantization modes 1 and 2 use linear quantization with step sizes of
++FSD/1024 and FSD/512 respectively. Each of the four pixels is quantized
++independently, with rounding to the nearest level.
++In quantization mode 2 where the middle two samples have quantized values
++(q1,q2) both in the range [384..511], they are coded using 9 bits for q1
++followed by 7 bits for (q2 & 127). Otherwise, for quantization modes
++0, 1 and 2: a 9-bit field encodes MIN(q1,q2) which must be in the range
++[0..511] and a 7-bit field encodes (q2-q1+64) which must be in [0..127].
++
++Each of the outer samples (q0,q3) is encoded using a 7-bit field based
++on its inner neighbour q1 or q2. In quantization mode 2 where the inner
++sample has a quantized value in the range [448..511], the field value is
++(q0-384). Otherwise for quantization modes 0, 1 and 2: The outer sample
++is encoded as (q0-MAX(0,q1-64)). q3 is likewise coded based on q2.
++Each of these values must be in the range [0..127]. All these fields
++of 2, 9, 7, 7, 7 bits respectively are packed in little-endian order
++to give a 32-bit word with LE byte order.
++
++Quantization mode 3 has a "7.5-bit" escape, used when none of the above
++encodings will fit. Each pixel value is quantized to the nearest of 176
++levels, where the lowest 95 levels are multiples of FSD/256 and the
++remaining levels are multiples of FSD/128 (level 175 represents values
++very close to FSD and may require saturating arithmetic to decode).
++
++Each pair of quantized pixels (q0,q1) or (q2,q3) is jointly coded
++by a 15-bit field: 2816*(q0>>4) + 16*q1 + (q0&15).
++Three fields of 2, 15, 15 bits are packed in LE order {15,15,2}.
++
++An implementation of a software decoder of compressed formats is available
++in `Raspberry Pi camera applications code base
++<https://github.com/raspberrypi/rpicam-apps/blob/main/image/dng.cpp>`_.
diff --git a/target/linux/bcm27xx/patches-6.6/950-1152-media-dt-bindings-Add-bindings-for-Raspberry-Pi-PiSP.patch b/target/linux/bcm27xx/patches-6.6/950-1152-media-dt-bindings-Add-bindings-for-Raspberry-Pi-PiSP.patch
new file mode 100644
index 0000000000..30c5cb3506
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1152-media-dt-bindings-Add-bindings-for-Raspberry-Pi-PiSP.patch
@@ -0,0 +1,97 @@
+From c38a898c6877c6722ebfecea99f42e5a84c3e453 Mon Sep 17 00:00:00 2001
+From: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+Date: Thu, 25 Jan 2024 16:42:33 +0100
+Subject: [PATCH 1152/1215] media: dt-bindings: Add bindings for Raspberry Pi
+ PiSP Back End
+
+Add bindings for the Raspberry Pi PiSP Back End memory-to-memory image
+signal processor.
+
+Datasheet:
+https://datasheets.raspberrypi.com/camera/raspberry-pi-image-signal-processor-specification.pdf
+
+Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
+---
+ .../bindings/media/raspberrypi,pispbe.yaml | 63 +++++++++++++++++++
+ MAINTAINERS | 1 +
+ 2 files changed, 64 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/media/raspberrypi,pispbe.yaml
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/media/raspberrypi,pispbe.yaml
+@@ -0,0 +1,63 @@
++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/media/raspberrypi,pispbe.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: Raspberry Pi PiSP Image Signal Processor (ISP) Back End
++
++maintainers:
++ - Raspberry Pi Kernel Maintenance <kernel-list@raspberrypi.com>
++ - Jacopo Mondi <jacopo.mondi@ideasonboard.com>
++
++description: |
++ The Raspberry Pi PiSP Image Signal Processor (ISP) Back End is an image
++ processor that fetches images in Bayer or Grayscale format from DRAM memory
++ in tiles and produces images consumable by applications.
++
++ The full ISP documentation is available at
++ https://datasheets.raspberrypi.com/camera/raspberry-pi-image-signal-processor-specification.pdf
++
++properties:
++ compatible:
++ items:
++ - enum:
++ - brcm,bcm2712-pispbe
++ - const: raspberrypi,pispbe
++
++ reg:
++ maxItems: 1
++
++ interrupts:
++ maxItems: 1
++
++ clocks:
++ maxItems: 1
++
++ iommus:
++ maxItems: 1
++
++required:
++ - compatible
++ - reg
++ - interrupts
++ - clocks
++
++additionalProperties: false
++
++examples:
++ - |
++ #include <dt-bindings/interrupt-controller/arm-gic.h>
++
++ soc {
++ #address-cells = <2>;
++ #size-cells = <2>;
++
++ isp@880000 {
++ compatible = "brcm,bcm2712-pispbe", "raspberrypi,pispbe";
++ reg = <0x10 0x00880000 0x0 0x4000>;
++ interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&firmware_clocks 7>;
++ iommus = <&iommu2>;
++ };
++ };
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -18037,6 +18037,7 @@ M: Jacopo Mondi <jacopo.mondi@ideasonboa
+ L: Raspberry Pi Kernel Maintenance <kernel-list@raspberrypi.com>
+ L: linux-media@vger.kernel.org
+ S: Maintained
++F: Documentation/devicetree/bindings/media/raspberrypi,pispbe.yaml
+ F: include/uapi/linux/media/raspberrypi/
+
+ RC-CORE / LIRC FRAMEWORK
diff --git a/target/linux/bcm27xx/patches-6.6/950-1153-media-admin-guide-Document-the-Raspberry-Pi-PiSP-BE.patch b/target/linux/bcm27xx/patches-6.6/950-1153-media-admin-guide-Document-the-Raspberry-Pi-PiSP-BE.patch
new file mode 100644
index 0000000000..f443cc78c7
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1153-media-admin-guide-Document-the-Raspberry-Pi-PiSP-BE.patch
@@ -0,0 +1,162 @@
+From d68e76260316002869aea1b0edf4be399bb592b8 Mon Sep 17 00:00:00 2001
+From: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+Date: Mon, 29 Jan 2024 17:23:55 +0100
+Subject: [PATCH 1153/1215] media: admin-guide: Document the Raspberry Pi PiSP
+ BE
+
+Add documentation for the PiSP Back End memory-to-memory ISP.
+
+Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+---
+ .../admin-guide/media/raspberrypi-pisp-be.dot | 20 ++++
+ .../admin-guide/media/raspberrypi-pisp-be.rst | 109 ++++++++++++++++++
+ .../admin-guide/media/v4l-drivers.rst | 1 +
+ 3 files changed, 130 insertions(+)
+ create mode 100644 Documentation/admin-guide/media/raspberrypi-pisp-be.dot
+ create mode 100644 Documentation/admin-guide/media/raspberrypi-pisp-be.rst
+
+--- /dev/null
++++ b/Documentation/admin-guide/media/raspberrypi-pisp-be.dot
+@@ -0,0 +1,20 @@
++digraph board {
++ rankdir=TB
++ n00000001 [label="{{<port0> 0 | <port1> 1 | <port2> 2 | <port7> 7} | pispbe\n | {<port3> 3 | <port4> 4 | <port5> 5 | <port6> 6}}", shape=Mrecord, style=filled, fillcolor=green]
++ n00000001:port3 -> n0000001c [style=bold]
++ n00000001:port4 -> n00000022 [style=bold]
++ n00000001:port5 -> n00000028 [style=bold]
++ n00000001:port6 -> n0000002e [style=bold]
++ n0000000a [label="pispbe-input\n/dev/video0", shape=box, style=filled, fillcolor=yellow]
++ n0000000a -> n00000001:port0 [style=bold]
++ n00000010 [label="pispbe-tdn_input\n/dev/video1", shape=box, style=filled, fillcolor=yellow]
++ n00000010 -> n00000001:port1 [style=bold]
++ n00000016 [label="pispbe-stitch_input\n/dev/video2", shape=box, style=filled, fillcolor=yellow]
++ n00000016 -> n00000001:port2 [style=bold]
++ n0000001c [label="pispbe-output0\n/dev/video3", shape=box, style=filled, fillcolor=yellow]
++ n00000022 [label="pispbe-output1\n/dev/video4", shape=box, style=filled, fillcolor=yellow]
++ n00000028 [label="pispbe-tdn_output\n/dev/video5", shape=box, style=filled, fillcolor=yellow]
++ n0000002e [label="pispbe-stitch_output\n/dev/video6", shape=box, style=filled, fillcolor=yellow]
++ n00000034 [label="pispbe-config\n/dev/video7", shape=box, style=filled, fillcolor=yellow]
++ n00000034 -> n00000001:port7 [style=bold]
++}
+--- /dev/null
++++ b/Documentation/admin-guide/media/raspberrypi-pisp-be.rst
+@@ -0,0 +1,109 @@
++.. SPDX-License-Identifier: GPL-2.0
++
++=========================================================
++Raspberry Pi PiSP Back End Memory-to-Memory ISP (pisp-be)
++=========================================================
++
++The PiSP Back End
++=================
++
++The PiSP Back End is a memory-to-memory Image Signal Processor (ISP) which reads
++image data from DRAM memory and performs image processing as specified by the
++application through the parameters in a configuration buffer, before writing
++pixel data back to memory through two distinct output channels.
++
++The ISP registers and programming model are documented in the `Raspberry Pi
++Image Signal Processor (PiSP) Specification document`_
++
++The PiSP Back End ISP processes images in tiles. The handling of image
++tessellation and the computation of low-level configuration parameters is
++realized by a free software library called `libpisp
++<https://github.com/raspberrypi/libpisp>`_.
++
++The full image processing pipeline, which involves capturing RAW Bayer data from
++an image sensor through a MIPI CSI-2 compatible capture interface, storing them
++in DRAM memory and processing them in the PiSP Back End to obtain images usable
++by an application is implemented in `libcamera <https://libcamera.org>`_ as
++part of the Raspberry Pi platform support.
++
++The pisp-be driver
++==================
++
++The Raspberry Pi PiSP Back End (pisp-be) driver is located under
++drivers/media/platform/raspberrypi/pisp-be. It uses the `V4L2 API` to register
++a number of video capture and output devices, the `V4L2 subdev API` to register
++a subdevice for the ISP that connects the video devices in a single media graph
++realized using the `Media Controller (MC) API`.
++
++The media topology registered by the `pisp-be` driver is represented below:
++
++.. _pips-be-topology:
++
++.. kernel-figure:: raspberrypi-pisp-be.dot
++ :alt: Diagram of the default media pipeline topology
++ :align: center
++
++
++The media graph registers the following video device nodes:
++
++- pispbe-input: output device for images to be submitted to the ISP for
++ processing.
++- pispbe-tdn_input: output device for temporal denoise.
++- pispbe-stitch_input: output device for image stitching (HDR).
++- pispbe-output0: first capture device for processed images.
++- pispbe-output1: second capture device for processed images.
++- pispbe-tdn_output: capture device for temporal denoise.
++- pispbe-stitch_output: capture device for image stitching (HDR).
++- pispbe-config: output device for ISP configuration parameters.
++
++pispbe-input
++------------
++
++Images to be processed by the ISP are queued to the `pispbe-input` output device
++node. For a list of image formats supported as input to the ISP refer to the
++`Raspberry Pi Image Signal Processor (PiSP) Specification document`_.
++
++pispbe-tdn_input, pispbe-tdn_output
++-----------------------------------
++
++The `pispbe-tdn_input` output video device receives images to be processed by
++the temporal denoise block which are captured from the `pispbe-tdn_output`
++capture video device. Userspace is responsible for maintaining queues on both
++devices, and ensuring that buffers completed on the output are queued to the
++input.
++
++pispbe-stitch_input, pispbe-stitch_output
++-----------------------------------------
++
++To realize HDR (high dynamic range) image processing the image stitching and
++tonemapping blocks are used. The `pispbe-stitch_output` writes images to memory
++and the `pispbe-stitch_input` receives the previously written frame to process
++it along with the current input image. Userspace is responsible for maintaining
++queues on both devices, and ensuring that buffers completed on the output are
++queued to the input.
++
++pispbe-output0, pispbe-output1
++------------------------------
++
++The two capture devices write to memory the pixel data as processed by the ISP.
++
++pispbe-config
++-------------
++
++The `pispbe-config` output video devices receives a buffer of configuration
++parameters that define the desired image processing to be performed by the ISP.
++
++The format of the ISP configuration parameter is defined by
++:c:type:`pisp_be_tiles_config` C structure and the meaning of each parameter is
++described in the `Raspberry Pi Image Signal Processor (PiSP) Specification
++document`_.
++
++ISP configuration
++=================
++
++The ISP configuration is described solely by the content of the parameters
++buffer. The only parameter that userspace needs to configure using the V4L2 API
++is the image format on the output and capture video devices for validation of
++the content of the parameters buffer.
++
++.. _Raspberry Pi Image Signal Processor (PiSP) Specification document: https://datasheets.raspberrypi.com/camera/raspberry-pi-image-signal-processor-specification.pdf
+--- a/Documentation/admin-guide/media/v4l-drivers.rst
++++ b/Documentation/admin-guide/media/v4l-drivers.rst
+@@ -21,6 +21,7 @@ Video4Linux (V4L) driver-specific docume
+ omap4_camera
+ philips
+ qcom_camss
++ raspberrypi-pisp-be
+ rcar-fdp1
+ rkisp1
+ saa7134
diff --git a/target/linux/bcm27xx/patches-6.6/950-1154-media-pisp-be-Backport-the-mainline-PiSP-BE-driver.patch b/target/linux/bcm27xx/patches-6.6/950-1154-media-pisp-be-Backport-the-mainline-PiSP-BE-driver.patch
new file mode 100644
index 0000000000..a0123995fe
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1154-media-pisp-be-Backport-the-mainline-PiSP-BE-driver.patch
@@ -0,0 +1,2927 @@
+From c75989589bf77530f4013e0bc799169504c69937 Mon Sep 17 00:00:00 2001
+From: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+Date: Thu, 27 Jun 2024 11:41:22 +0200
+Subject: [PATCH 1154/1215] media: pisp-be: Backport the mainline PiSP BE
+ driver
+
+Backport to rpi-6.6.y the mainline version of the PiSP BE driver.
+
+The backported version of the driver corresponds to the one available
+at:
+https://lore.kernel.org/all/20240626181440.195137-1-jacopo.mondi@ideasonboard.com/
+
+Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+---
+ .../platform/raspberrypi/pisp_be/Kconfig | 4 +-
+ .../platform/raspberrypi/pisp_be/pisp_be.c | 1288 +++++++----------
+ .../raspberrypi/pisp_be/pisp_be_config.h | 533 -------
+ .../raspberrypi/pisp_be/pisp_be_formats.h | 44 +-
+ 4 files changed, 572 insertions(+), 1297 deletions(-)
+ delete mode 100644 drivers/media/platform/raspberrypi/pisp_be/pisp_be_config.h
+
+--- a/drivers/media/platform/raspberrypi/pisp_be/Kconfig
++++ b/drivers/media/platform/raspberrypi/pisp_be/Kconfig
+@@ -1,10 +1,10 @@
+ config VIDEO_RASPBERRYPI_PISP_BE
+ tristate "Raspberry Pi PiSP Backend (BE) ISP driver"
+- depends on VIDEO_DEV && PM
++ depends on V4L_PLATFORM_DRIVERS
++ depends on VIDEO_DEV
+ select VIDEO_V4L2_SUBDEV_API
+ select MEDIA_CONTROLLER
+ select VIDEOBUF2_DMA_CONTIG
+- select V4L2_FWNODE
+ help
+ Say Y here to enable support for the PiSP Backend (BE) ISP driver.
+
+--- a/drivers/media/platform/raspberrypi/pisp_be/pisp_be.c
++++ b/drivers/media/platform/raspberrypi/pisp_be/pisp_be.c
+@@ -1,12 +1,14 @@
+ // SPDX-License-Identifier: GPL-2.0
+ /*
+ * PiSP Back End driver.
+- * Copyright (c) 2021-2022 Raspberry Pi Limited.
++ * Copyright (c) 2021-2024 Raspberry Pi Limited.
+ *
+ */
+ #include <linux/clk.h>
+ #include <linux/interrupt.h>
+ #include <linux/io.h>
++#include <linux/kernel.h>
++#include <linux/lockdep.h>
+ #include <linux/module.h>
+ #include <linux/platform_device.h>
+ #include <linux/pm_runtime.h>
+@@ -15,49 +17,39 @@
+ #include <media/videobuf2-dma-contig.h>
+ #include <media/videobuf2-vmalloc.h>
+
+-#include "pisp_be_config.h"
+-#include "pisp_be_formats.h"
+-
+-MODULE_DESCRIPTION("PiSP Back End driver");
+-MODULE_AUTHOR("David Plowman <david.plowman@raspberrypi.com>");
+-MODULE_AUTHOR("Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>");
+-MODULE_LICENSE("GPL v2");
++#include <uapi/linux/media/raspberrypi/pisp_be_config.h>
+
+-/* Offset to use when registering the /dev/videoX node */
+-#define PISPBE_VIDEO_NODE_OFFSET 20
++#include "pisp_be_formats.h"
+
+ /* Maximum number of config buffers possible */
+ #define PISP_BE_NUM_CONFIG_BUFFERS VB2_MAX_FRAME
+
+-/*
+- * We want to support 2 independent instances allowing 2 simultaneous users
+- * of the ISP-BE (of course they share hardware, platform resources and mutex).
+- * Each such instance comprises a group of device nodes representing input
+- * and output queues, and a media controller device node to describe them.
+- */
+-#define PISPBE_NUM_NODE_GROUPS 2
+-
+ #define PISPBE_NAME "pispbe"
+
+ /* Some ISP-BE registers */
+-#define PISP_BE_VERSION_OFFSET (0x0)
+-#define PISP_BE_CONTROL_OFFSET (0x4)
+-#define PISP_BE_TILE_ADDR_LO_OFFSET (0x8)
+-#define PISP_BE_TILE_ADDR_HI_OFFSET (0xc)
+-#define PISP_BE_STATUS_OFFSET (0x10)
+-#define PISP_BE_BATCH_STATUS_OFFSET (0x14)
+-#define PISP_BE_INTERRUPT_EN_OFFSET (0x18)
+-#define PISP_BE_INTERRUPT_STATUS_OFFSET (0x1c)
+-#define PISP_BE_AXI_OFFSET (0x20)
+-#define PISP_BE_CONFIG_BASE_OFFSET (0x40)
+-#define PISP_BE_IO_INPUT_ADDR0_LO_OFFSET (PISP_BE_CONFIG_BASE_OFFSET)
+-#define PISP_BE_GLOBAL_BAYER_ENABLE_OFFSET (PISP_BE_CONFIG_BASE_OFFSET + 0x70)
+-#define PISP_BE_GLOBAL_RGB_ENABLE_OFFSET (PISP_BE_CONFIG_BASE_OFFSET + 0x74)
+-#define N_HW_ADDRESSES 14
+-#define N_HW_ENABLES 2
++#define PISP_BE_VERSION_REG 0x0
++#define PISP_BE_CONTROL_REG 0x4
++#define PISP_BE_CONTROL_COPY_CONFIG BIT(1)
++#define PISP_BE_CONTROL_QUEUE_JOB BIT(0)
++#define PISP_BE_CONTROL_NUM_TILES(n) ((n) << 16)
++#define PISP_BE_TILE_ADDR_LO_REG 0x8
++#define PISP_BE_TILE_ADDR_HI_REG 0xc
++#define PISP_BE_STATUS_REG 0x10
++#define PISP_BE_STATUS_QUEUED BIT(0)
++#define PISP_BE_BATCH_STATUS_REG 0x14
++#define PISP_BE_INTERRUPT_EN_REG 0x18
++#define PISP_BE_INTERRUPT_STATUS_REG 0x1c
++#define PISP_BE_AXI_REG 0x20
++#define PISP_BE_CONFIG_BASE_REG 0x40
++#define PISP_BE_IO_ADDR_LOW(n) (PISP_BE_CONFIG_BASE_REG + 8 * (n))
++#define PISP_BE_IO_ADDR_HIGH(n) (PISP_BE_IO_ADDR_LOW((n)) + 4)
++#define PISP_BE_GLOBAL_BAYER_ENABLE 0xb0
++#define PISP_BE_GLOBAL_RGB_ENABLE 0xb4
++#define N_HW_ADDRESSES 13
++#define N_HW_ENABLES 2
+
+-#define PISP_BE_VERSION_2712C1 0x02252700
+-#define PISP_BE_VERSION_MINOR_BITS 0xF
++#define PISP_BE_VERSION_2712 0x02252700
++#define PISP_BE_VERSION_MINOR_BITS 0xf
+
+ /*
+ * This maps our nodes onto the inputs/outputs of the actual PiSP Back End.
+@@ -65,11 +57,10 @@ MODULE_LICENSE("GPL v2");
+ * context it means an input to the hardware (source image or metadata).
+ * Elsewhere it means an output from the hardware.
+ */
+-enum node_ids {
++enum pispbe_node_ids {
+ MAIN_INPUT_NODE,
+ TDN_INPUT_NODE,
+ STITCH_INPUT_NODE,
+- HOG_OUTPUT_NODE,
+ OUTPUT0_NODE,
+ OUTPUT1_NODE,
+ TDN_OUTPUT_NODE,
+@@ -78,13 +69,13 @@ enum node_ids {
+ PISPBE_NUM_NODES
+ };
+
+-struct node_description {
++struct pispbe_node_description {
+ const char *ent_name;
+ enum v4l2_buf_type buf_type;
+ unsigned int caps;
+ };
+
+-static const struct node_description node_desc[PISPBE_NUM_NODES] = {
++static const struct pispbe_node_description node_desc[PISPBE_NUM_NODES] = {
+ /* MAIN_INPUT_NODE */
+ {
+ .ent_name = PISPBE_NAME "-input",
+@@ -103,12 +94,6 @@ static const struct node_description nod
+ .buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+ .caps = V4L2_CAP_VIDEO_OUTPUT_MPLANE,
+ },
+- /* HOG_OUTPUT_NODE */
+- {
+- .ent_name = PISPBE_NAME "-hog_output",
+- .buf_type = V4L2_BUF_TYPE_META_CAPTURE,
+- .caps = V4L2_CAP_META_CAPTURE,
+- },
+ /* OUTPUT0_NODE */
+ {
+ .ent_name = PISPBE_NAME "-output0",
+@@ -147,14 +132,12 @@ static const struct node_description nod
+ ((desc)->buf_type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE))
+
+ #define NODE_IS_META(node) ( \
+- ((node)->buf_type == V4L2_BUF_TYPE_META_OUTPUT) || \
+- ((node)->buf_type == V4L2_BUF_TYPE_META_CAPTURE))
++ ((node)->buf_type == V4L2_BUF_TYPE_META_OUTPUT))
+ #define NODE_IS_OUTPUT(node) ( \
+ ((node)->buf_type == V4L2_BUF_TYPE_META_OUTPUT) || \
+ ((node)->buf_type == V4L2_BUF_TYPE_VIDEO_OUTPUT) || \
+ ((node)->buf_type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE))
+ #define NODE_IS_CAPTURE(node) ( \
+- ((node)->buf_type == V4L2_BUF_TYPE_META_CAPTURE) || \
+ ((node)->buf_type == V4L2_BUF_TYPE_VIDEO_CAPTURE) || \
+ ((node)->buf_type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE))
+ #define NODE_IS_MPLANE(node) ( \
+@@ -173,9 +156,12 @@ struct pispbe_node {
+ struct media_pad pad;
+ struct media_intf_devnode *intf_devnode;
+ struct media_link *intf_link;
+- struct pispbe_node_group *node_group;
++ struct pispbe_dev *pispbe;
++ /* Video device lock */
+ struct mutex node_lock;
++ /* vb2_queue lock */
+ struct mutex queue_lock;
++ /* Protect pispbe_node->ready_queue and pispbe_buffer->ready_list */
+ spinlock_t ready_lock;
+ struct list_head ready_queue;
+ struct vb2_queue queue;
+@@ -186,29 +172,10 @@ struct pispbe_node {
+ /* For logging only, use the entity name with "pispbe" and separator removed */
+ #define NODE_NAME(node) \
+ (node_desc[(node)->id].ent_name + sizeof(PISPBE_NAME))
+-#define NODE_GET_V4L2(node) ((node)->node_group->v4l2_dev)
+-
+-/*
+- * Node group structure, which comprises all the input and output nodes that a
+- * single PiSP client will need, along with its own v4l2 and media devices.
+- */
+-struct pispbe_node_group {
+- unsigned int id;
+- struct v4l2_device v4l2_dev;
+- struct v4l2_subdev sd;
+- struct pispbe_dev *pispbe;
+- struct media_device mdev;
+- struct pispbe_node node[PISPBE_NUM_NODES];
+- u32 streaming_map; /* bitmap of which nodes are streaming */
+- struct media_pad pad[PISPBE_NUM_NODES]; /* output pads first */
+- struct pisp_be_tiles_config *config;
+- dma_addr_t config_dma_addr;
+- unsigned int sequence;
+-};
+
+ /* Records details of the jobs currently running or queued on the h/w. */
+ struct pispbe_job {
+- struct pispbe_node_group *node_group;
++ bool valid;
+ /*
+ * An array of buffer pointers - remember it's source buffers first,
+ * then captures, then metadata last.
+@@ -216,85 +183,66 @@ struct pispbe_job {
+ struct pispbe_buffer *buf[PISPBE_NUM_NODES];
+ };
+
++struct pispbe_hw_enables {
++ u32 bayer_enables;
++ u32 rgb_enables;
++};
++
++/* Records a job configuration and memory addresses. */
++struct pispbe_job_descriptor {
++ dma_addr_t hw_dma_addrs[N_HW_ADDRESSES];
++ struct pisp_be_tiles_config *config;
++ struct pispbe_hw_enables hw_enables;
++ dma_addr_t tiles;
++};
++
+ /*
+ * Structure representing the entire PiSP Back End device, comprising several
+- * node groups which share platform resources and a mutex for the actual HW.
++ * nodes which share platform resources and a mutex for the actual HW.
+ */
+ struct pispbe_dev {
+ struct device *dev;
+- struct pispbe_node_group node_group[PISPBE_NUM_NODE_GROUPS];
+- int hw_busy; /* non-zero if a job is queued or is being started */
+- struct pispbe_job queued_job, running_job;
++ struct pispbe_dev *pispbe;
++ struct pisp_be_tiles_config *config;
+ void __iomem *be_reg_base;
+ struct clk *clk;
++ struct v4l2_device v4l2_dev;
++ struct v4l2_subdev sd;
++ struct media_device mdev;
++ struct media_pad pad[PISPBE_NUM_NODES]; /* output pads first */
++ struct pispbe_node node[PISPBE_NUM_NODES];
++ dma_addr_t config_dma_addr;
++ unsigned int sequence;
++ u32 streaming_map;
++ struct pispbe_job queued_job, running_job;
++ spinlock_t hw_lock; /* protects "hw_busy" flag and streaming_map */
++ bool hw_busy; /* non-zero if a job is queued or is being started */
+ int irq;
+ u32 hw_version;
+ u8 done, started;
+- spinlock_t hw_lock; /* protects "hw_busy" flag and streaming_map */
+ };
+
+-static inline u32 read_reg(struct pispbe_dev *pispbe, unsigned int offset)
++static u32 pispbe_rd(struct pispbe_dev *pispbe, unsigned int offset)
+ {
+ return readl(pispbe->be_reg_base + offset);
+ }
+
+-static inline void write_reg(struct pispbe_dev *pispbe, unsigned int offset,
+- u32 val)
++static void pispbe_wr(struct pispbe_dev *pispbe, unsigned int offset, u32 val)
+ {
+ writel(val, pispbe->be_reg_base + offset);
+ }
+
+-/* Check and initialize hardware. */
+-static int hw_init(struct pispbe_dev *pispbe)
+-{
+- u32 u;
+-
+- /* Check the HW is present and has a known version */
+- u = read_reg(pispbe, PISP_BE_VERSION_OFFSET);
+- dev_info(pispbe->dev, "pispbe_probe: HW version: 0x%08x", u);
+- pispbe->hw_version = u;
+- if ((u & ~PISP_BE_VERSION_MINOR_BITS) != PISP_BE_VERSION_2712C1)
+- return -ENODEV;
+-
+- /* Clear leftover interrupts */
+- write_reg(pispbe, PISP_BE_INTERRUPT_STATUS_OFFSET, 0xFFFFFFFFu);
+- u = read_reg(pispbe, PISP_BE_BATCH_STATUS_OFFSET);
+- dev_info(pispbe->dev, "pispbe_probe: BatchStatus: 0x%08x", u);
+- pispbe->done = (uint8_t)u;
+- pispbe->started = (uint8_t)(u >> 8);
+- u = read_reg(pispbe, PISP_BE_STATUS_OFFSET);
+- dev_info(pispbe->dev, "pispbe_probe: Status: 0x%08x", u);
+- if (u != 0 || pispbe->done != pispbe->started) {
+- dev_err(pispbe->dev, "pispbe_probe: HW is stuck or busy\n");
+- return -EBUSY;
+- }
+- /*
+- * AXI QOS=0, CACHE=4'b0010, PROT=3'b011
+- * Also set "chicken bits" 22:20 which enable sub-64-byte bursts
+- * and AXI AWID/BID variability (on versions which support this).
+- */
+- write_reg(pispbe, PISP_BE_AXI_OFFSET, 0x32703200u);
+-
+- /* Enable both interrupt flags */
+- write_reg(pispbe, PISP_BE_INTERRUPT_EN_OFFSET, 0x00000003u);
+- return 0;
+-}
+-
+ /*
+ * Queue a job to the h/w. If the h/w is idle it will begin immediately.
+ * Caller must ensure it is "safe to queue", i.e. we don't already have a
+ * queued, unstarted job.
+ */
+-static void hw_queue_job(struct pispbe_dev *pispbe,
+- dma_addr_t hw_dma_addrs[N_HW_ADDRESSES],
+- u32 hw_enables[N_HW_ENABLES],
+- struct pisp_be_config *config, dma_addr_t tiles,
+- unsigned int num_tiles)
++static void pispbe_queue_job(struct pispbe_dev *pispbe,
++ struct pispbe_job_descriptor *job)
+ {
+ unsigned int begin, end;
+- unsigned int u;
+
+- if (read_reg(pispbe, PISP_BE_STATUS_OFFSET) & 1)
++ if (pispbe_rd(pispbe, PISP_BE_STATUS_REG) & PISP_BE_STATUS_QUEUED)
+ dev_err(pispbe->dev, "ERROR: not safe to queue new job!\n");
+
+ /*
+@@ -303,51 +251,49 @@ static void hw_queue_job(struct pispbe_d
+ * and we don't want to modify (or be vulnerable to modifications of)
+ * the mmap'd buffer.
+ */
+- for (u = 0; u < N_HW_ADDRESSES; ++u) {
+- write_reg(pispbe, PISP_BE_IO_INPUT_ADDR0_LO_OFFSET + 8 * u,
+- (u32)(hw_dma_addrs[u]));
+- write_reg(pispbe, PISP_BE_IO_INPUT_ADDR0_LO_OFFSET + 8 * u + 4,
+- (u32)(hw_dma_addrs[u] >> 32));
+- }
+- write_reg(pispbe, PISP_BE_GLOBAL_BAYER_ENABLE_OFFSET, hw_enables[0]);
+- write_reg(pispbe, PISP_BE_GLOBAL_RGB_ENABLE_OFFSET, hw_enables[1]);
++ for (unsigned int u = 0; u < N_HW_ADDRESSES; ++u) {
++ pispbe_wr(pispbe, PISP_BE_IO_ADDR_LOW(u),
++ lower_32_bits(job->hw_dma_addrs[u]));
++ pispbe_wr(pispbe, PISP_BE_IO_ADDR_HIGH(u),
++ upper_32_bits(job->hw_dma_addrs[u]));
++ }
++ pispbe_wr(pispbe, PISP_BE_GLOBAL_BAYER_ENABLE,
++ job->hw_enables.bayer_enables);
++ pispbe_wr(pispbe, PISP_BE_GLOBAL_RGB_ENABLE,
++ job->hw_enables.rgb_enables);
+
+- /*
+- * Everything else is as supplied by the user. XXX Buffer sizes not
+- * checked!
+- */
++ /* Everything else is as supplied by the user. */
+ begin = offsetof(struct pisp_be_config, global.bayer_order) /
+- sizeof(u32);
+- end = offsetof(struct pisp_be_config, axi) / sizeof(u32);
+- for (u = begin; u < end; u++) {
+- unsigned int val = ((u32 *)config)[u];
+-
+- write_reg(pispbe, PISP_BE_CONFIG_BASE_OFFSET + 4 * u, val);
+- }
++ sizeof(u32);
++ end = sizeof(struct pisp_be_config) / sizeof(u32);
++ for (unsigned int u = begin; u < end; u++)
++ pispbe_wr(pispbe, PISP_BE_CONFIG_BASE_REG + sizeof(u32) * u,
++ ((u32 *)job->config)[u]);
+
+ /* Read back the addresses -- an error here could be fatal */
+- for (u = 0; u < N_HW_ADDRESSES; ++u) {
+- unsigned int offset = PISP_BE_IO_INPUT_ADDR0_LO_OFFSET + 8 * u;
+- u64 along = read_reg(pispbe, offset);
+-
+- along += ((u64)read_reg(pispbe, offset + 4)) << 32;
+- if (along != (u64)(hw_dma_addrs[u])) {
+- dev_err(pispbe->dev,
++ for (unsigned int u = 0; u < N_HW_ADDRESSES; ++u) {
++ unsigned int offset = PISP_BE_IO_ADDR_LOW(u);
++ u64 along = pispbe_rd(pispbe, offset);
++
++ along += ((u64)pispbe_rd(pispbe, offset + 4)) << 32;
++ if (along != (u64)(job->hw_dma_addrs[u])) {
++ dev_dbg(pispbe->dev,
+ "ISP BE config error: check if ISP RAMs enabled?\n");
+ return;
+ }
+ }
+
+ /*
+- * Write tile pointer to hardware. XXX Tile offsets and sizes not
+- * checked (and even if checked, the user could subsequently modify
+- * them)!
++ * Write tile pointer to hardware. The IOMMU should prevent
++ * out-of-bounds offsets reaching non-ISP buffers.
+ */
+- write_reg(pispbe, PISP_BE_TILE_ADDR_LO_OFFSET, (u32)tiles);
+- write_reg(pispbe, PISP_BE_TILE_ADDR_HI_OFFSET, (u32)(tiles >> 32));
++ pispbe_wr(pispbe, PISP_BE_TILE_ADDR_LO_REG, lower_32_bits(job->tiles));
++ pispbe_wr(pispbe, PISP_BE_TILE_ADDR_HI_REG, upper_32_bits(job->tiles));
+
+ /* Enqueue the job */
+- write_reg(pispbe, PISP_BE_CONTROL_OFFSET, 3 + 65536 * num_tiles);
++ pispbe_wr(pispbe, PISP_BE_CONTROL_REG,
++ PISP_BE_CONTROL_COPY_CONFIG | PISP_BE_CONTROL_QUEUE_JOB |
++ PISP_BE_CONTROL_NUM_TILES(job->config->num_tiles));
+ }
+
+ struct pispbe_buffer {
+@@ -356,8 +302,8 @@ struct pispbe_buffer {
+ unsigned int config_index;
+ };
+
+-static int get_addr_3(dma_addr_t addr[3], struct pispbe_buffer *buf,
+- struct pispbe_node *node)
++static int pispbe_get_planes_addr(dma_addr_t addr[3], struct pispbe_buffer *buf,
++ struct pispbe_node *node)
+ {
+ unsigned int num_planes = node->format.fmt.pix_mp.num_planes;
+ unsigned int plane_factor = 0;
+@@ -367,22 +313,20 @@ static int get_addr_3(dma_addr_t addr[3]
+ if (!buf || !node->pisp_format)
+ return 0;
+
+- WARN_ON(!NODE_IS_MPLANE(node));
+-
+ /*
+ * Determine the base plane size. This will not be the same
+ * as node->format.fmt.pix_mp.plane_fmt[0].sizeimage for a single
+ * plane buffer in an mplane format.
+ */
+ size = node->format.fmt.pix_mp.plane_fmt[0].bytesperline *
+- node->format.fmt.pix_mp.height;
++ node->format.fmt.pix_mp.height;
+
+- for (p = 0; p < num_planes && p < 3; p++) {
++ for (p = 0; p < num_planes && p < PISPBE_MAX_PLANES; p++) {
+ addr[p] = vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, p);
+ plane_factor += node->pisp_format->plane_factor[p];
+ }
+
+- for (; p < MAX_PLANES && node->pisp_format->plane_factor[p]; p++) {
++ for (; p < PISPBE_MAX_PLANES && node->pisp_format->plane_factor[p]; p++) {
+ /*
+ * Calculate the address offset of this plane as needed
+ * by the hardware. This is specifically for non-mplane
+@@ -396,41 +340,41 @@ static int get_addr_3(dma_addr_t addr[3]
+ return num_planes;
+ }
+
+-static dma_addr_t get_addr(struct pispbe_buffer *buf)
++static dma_addr_t pispbe_get_addr(struct pispbe_buffer *buf)
+ {
+ if (buf)
+ return vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0);
++
+ return 0;
+ }
+
+-static void
+-fixup_addrs_enables(dma_addr_t addrs[N_HW_ADDRESSES],
+- u32 hw_enables[N_HW_ENABLES],
+- struct pisp_be_tiles_config *config,
+- struct pispbe_buffer *buf[PISPBE_NUM_NODES],
+- struct pispbe_node_group *node_group)
+-{
+- int ret, i;
++static void pispbe_xlate_addrs(struct pispbe_dev *pispbe,
++ struct pispbe_job_descriptor *job,
++ struct pispbe_buffer *buf[PISPBE_NUM_NODES])
++{
++ struct pispbe_hw_enables *hw_en = &job->hw_enables;
++ struct pisp_be_tiles_config *config = job->config;
++ dma_addr_t *addrs = job->hw_dma_addrs;
++ int ret;
+
+ /* Take a copy of the "enable" bitmaps so we can modify them. */
+- hw_enables[0] = config->config.global.bayer_enables;
+- hw_enables[1] = config->config.global.rgb_enables;
++ hw_en->bayer_enables = config->config.global.bayer_enables;
++ hw_en->rgb_enables = config->config.global.rgb_enables;
+
+ /*
+ * Main input first. There are 3 address pointers, corresponding to up
+ * to 3 planes.
+ */
+- ret = get_addr_3(addrs, buf[MAIN_INPUT_NODE],
+- &node_group->node[MAIN_INPUT_NODE]);
++ ret = pispbe_get_planes_addr(addrs, buf[MAIN_INPUT_NODE],
++ &pispbe->node[MAIN_INPUT_NODE]);
+ if (ret <= 0) {
+ /*
+ * This shouldn't happen; pispbe_schedule_internal should insist
+ * on an input.
+ */
+- dev_warn(node_group->pispbe->dev,
+- "ISP-BE missing input\n");
+- hw_enables[0] = 0;
+- hw_enables[1] = 0;
++ dev_warn(pispbe->dev, "ISP-BE missing input\n");
++ hw_en->bayer_enables = 0;
++ hw_en->rgb_enables = 0;
+ return;
+ }
+
+@@ -439,118 +383,114 @@ fixup_addrs_enables(dma_addr_t addrs[N_H
+ * used with Bayer input. Input enables must match the requirements
+ * of the processing stages, otherwise the hardware can lock up!
+ */
+- if (hw_enables[0] & PISP_BE_BAYER_ENABLE_INPUT) {
+- addrs[3] = get_addr(buf[TDN_INPUT_NODE]);
++ if (hw_en->bayer_enables & PISP_BE_BAYER_ENABLE_INPUT) {
++ addrs[3] = pispbe_get_addr(buf[TDN_INPUT_NODE]);
+ if (addrs[3] == 0 ||
+- !(hw_enables[0] & PISP_BE_BAYER_ENABLE_TDN_INPUT) ||
+- !(hw_enables[0] & PISP_BE_BAYER_ENABLE_TDN) ||
++ !(hw_en->bayer_enables & PISP_BE_BAYER_ENABLE_TDN_INPUT) ||
++ !(hw_en->bayer_enables & PISP_BE_BAYER_ENABLE_TDN) ||
+ (config->config.tdn.reset & 1)) {
+- hw_enables[0] &= ~(PISP_BE_BAYER_ENABLE_TDN_INPUT |
+- PISP_BE_BAYER_ENABLE_TDN_DECOMPRESS);
++ hw_en->bayer_enables &=
++ ~(PISP_BE_BAYER_ENABLE_TDN_INPUT |
++ PISP_BE_BAYER_ENABLE_TDN_DECOMPRESS);
+ if (!(config->config.tdn.reset & 1))
+- hw_enables[0] &= ~PISP_BE_BAYER_ENABLE_TDN;
++ hw_en->bayer_enables &=
++ ~PISP_BE_BAYER_ENABLE_TDN;
+ }
+
+- addrs[4] = get_addr(buf[STITCH_INPUT_NODE]);
++ addrs[4] = pispbe_get_addr(buf[STITCH_INPUT_NODE]);
+ if (addrs[4] == 0 ||
+- !(hw_enables[0] & PISP_BE_BAYER_ENABLE_STITCH_INPUT) ||
+- !(hw_enables[0] & PISP_BE_BAYER_ENABLE_STITCH)) {
+- hw_enables[0] &=
++ !(hw_en->bayer_enables & PISP_BE_BAYER_ENABLE_STITCH_INPUT) ||
++ !(hw_en->bayer_enables & PISP_BE_BAYER_ENABLE_STITCH)) {
++ hw_en->bayer_enables &=
+ ~(PISP_BE_BAYER_ENABLE_STITCH_INPUT |
+ PISP_BE_BAYER_ENABLE_STITCH_DECOMPRESS |
+ PISP_BE_BAYER_ENABLE_STITCH);
+ }
+
+- addrs[5] = get_addr(buf[TDN_OUTPUT_NODE]);
++ addrs[5] = pispbe_get_addr(buf[TDN_OUTPUT_NODE]);
+ if (addrs[5] == 0)
+- hw_enables[0] &= ~(PISP_BE_BAYER_ENABLE_TDN_COMPRESS |
+- PISP_BE_BAYER_ENABLE_TDN_OUTPUT);
++ hw_en->bayer_enables &=
++ ~(PISP_BE_BAYER_ENABLE_TDN_COMPRESS |
++ PISP_BE_BAYER_ENABLE_TDN_OUTPUT);
+
+- addrs[6] = get_addr(buf[STITCH_OUTPUT_NODE]);
++ addrs[6] = pispbe_get_addr(buf[STITCH_OUTPUT_NODE]);
+ if (addrs[6] == 0)
+- hw_enables[0] &=
++ hw_en->bayer_enables &=
+ ~(PISP_BE_BAYER_ENABLE_STITCH_COMPRESS |
+ PISP_BE_BAYER_ENABLE_STITCH_OUTPUT);
+ } else {
+ /* No Bayer input? Disable entire Bayer pipe (else lockup) */
+- hw_enables[0] = 0;
++ hw_en->bayer_enables = 0;
+ }
+
+ /* Main image output channels. */
+- for (i = 0; i < PISP_BACK_END_NUM_OUTPUTS; i++) {
+- ret = get_addr_3(addrs + 7 + 3 * i, buf[OUTPUT0_NODE + i],
+- &node_group->node[OUTPUT0_NODE + i]);
++ for (unsigned int i = 0; i < PISP_BACK_END_NUM_OUTPUTS; i++) {
++ ret = pispbe_get_planes_addr(addrs + 7 + 3 * i,
++ buf[OUTPUT0_NODE + i],
++ &pispbe->node[OUTPUT0_NODE + i]);
+ if (ret <= 0)
+- hw_enables[1] &= ~(PISP_BE_RGB_ENABLE_OUTPUT0 << i);
++ hw_en->rgb_enables &= ~(PISP_BE_RGB_ENABLE_OUTPUT0 << i);
+ }
+-
+- /* HoG output (always single plane). */
+- addrs[13] = get_addr(buf[HOG_OUTPUT_NODE]);
+- if (addrs[13] == 0)
+- hw_enables[1] &= ~PISP_BE_RGB_ENABLE_HOG;
+ }
+
+ /*
+- * Internal function. Called from pispbe_schedule_one/all. Returns non-zero if
+- * we started a job.
++ * Prepare a job description to be submitted to the HW.
++ *
++ * To schedule a job, we need all streaming nodes (apart from Output0,
++ * Output1, Tdn and Stitch) to have a buffer ready, which must
++ * include at least a config buffer and a main input image.
+ *
+- * Warning: needs to be called with hw_lock taken, and releases it if it
+- * schedules a job.
++ * For Output0, Output1, Tdn and Stitch, a buffer only needs to be
++ * available if the blocks are enabled in the config.
++ *
++ * Needs to be called with hw_lock held.
++ *
++ * Returns 0 if a job has been successfully prepared, < 0 otherwise.
+ */
+-static int pispbe_schedule_internal(struct pispbe_node_group *node_group,
+- unsigned long flags)
++static int pispbe_prepare_job(struct pispbe_dev *pispbe,
++ struct pispbe_job_descriptor *job)
+ {
+- struct pisp_be_tiles_config *config_tiles_buffer;
+- struct pispbe_dev *pispbe = node_group->pispbe;
+- struct pispbe_buffer *buf[PISPBE_NUM_NODES];
+- dma_addr_t hw_dma_addrs[N_HW_ADDRESSES];
+- dma_addr_t tiles;
+- u32 hw_enables[N_HW_ENABLES];
+- struct pispbe_node *node;
+- unsigned long flags1;
++ struct pispbe_buffer *buf[PISPBE_NUM_NODES] = {};
+ unsigned int config_index;
+- int i;
++ struct pispbe_node *node;
++ unsigned long flags;
++
++ lockdep_assert_held(&pispbe->hw_lock);
++
++ memset(job, 0, sizeof(struct pispbe_job_descriptor));
+
+- /*
+- * To schedule a job, we need all streaming nodes (apart from Output0,
+- * Output1, Tdn and Stitch) to have a buffer ready, which must
+- * include at least a config buffer and a main input image.
+- *
+- * For Output0, Output1, Tdn and Stitch, a buffer only needs to be
+- * available if the blocks are enabled in the config.
+- *
+- * (Note that streaming_map is protected by hw_lock, which is held.)
+- */
+ if (((BIT(CONFIG_NODE) | BIT(MAIN_INPUT_NODE)) &
+- node_group->streaming_map) !=
+- (BIT(CONFIG_NODE) | BIT(MAIN_INPUT_NODE))) {
+- dev_dbg(pispbe->dev, "Nothing to do\n");
+- return 0;
+- }
++ pispbe->streaming_map) !=
++ (BIT(CONFIG_NODE) | BIT(MAIN_INPUT_NODE)))
++ return -ENODEV;
+
+- node = &node_group->node[CONFIG_NODE];
+- spin_lock_irqsave(&node->ready_lock, flags1);
+- buf[CONFIG_NODE] =
+- list_first_entry_or_null(&node->ready_queue, struct pispbe_buffer,
+- ready_list);
+- spin_unlock_irqrestore(&node->ready_lock, flags1);
++ node = &pispbe->node[CONFIG_NODE];
++ spin_lock_irqsave(&node->ready_lock, flags);
++ buf[CONFIG_NODE] = list_first_entry_or_null(&node->ready_queue,
++ struct pispbe_buffer,
++ ready_list);
++ if (buf[CONFIG_NODE]) {
++ list_del(&buf[CONFIG_NODE]->ready_list);
++ pispbe->queued_job.buf[CONFIG_NODE] = buf[CONFIG_NODE];
++ }
++ spin_unlock_irqrestore(&node->ready_lock, flags);
+
+ /* Exit early if no config buffer has been queued. */
+ if (!buf[CONFIG_NODE])
+- return 0;
++ return -ENODEV;
+
+ config_index = buf[CONFIG_NODE]->vb.vb2_buf.index;
+- config_tiles_buffer = &node_group->config[config_index];
+- tiles = (dma_addr_t)node_group->config_dma_addr +
+- config_index * sizeof(struct pisp_be_tiles_config) +
+- offsetof(struct pisp_be_tiles_config, tiles);
++ job->config = &pispbe->config[config_index];
++ job->tiles = pispbe->config_dma_addr +
++ config_index * sizeof(struct pisp_be_tiles_config) +
++ offsetof(struct pisp_be_tiles_config, tiles);
+
+ /* remember: srcimages, captures then metadata */
+- for (i = 0; i < PISPBE_NUM_NODES; i++) {
++ for (unsigned int i = 0; i < PISPBE_NUM_NODES; i++) {
+ unsigned int bayer_en =
+- config_tiles_buffer->config.global.bayer_enables;
++ job->config->config.global.bayer_enables;
+ unsigned int rgb_en =
+- config_tiles_buffer->config.global.rgb_enables;
++ job->config->config.global.rgb_enables;
+ bool ignore_buffers = false;
+
+ /* Config node is handled outside the loop above. */
+@@ -558,7 +498,7 @@ static int pispbe_schedule_internal(stru
+ continue;
+
+ buf[i] = NULL;
+- if (!(node_group->streaming_map & BIT(i)))
++ if (!(pispbe->streaming_map & BIT(i)))
+ continue;
+
+ if ((!(rgb_en & PISP_BE_RGB_ENABLE_OUTPUT0) &&
+@@ -578,119 +518,103 @@ static int pispbe_schedule_internal(stru
+ * global enables aren't set for these blocks. If a
+ * buffer has been provided, we dequeue it back to the
+ * user with the other in-use buffers.
+- *
+ */
+ ignore_buffers = true;
+ }
+
+- node = &node_group->node[i];
++ node = &pispbe->node[i];
+
+- spin_lock_irqsave(&node->ready_lock, flags1);
++ /* Pull a buffer from each V4L2 queue to form the queued job */
++ spin_lock_irqsave(&node->ready_lock, flags);
+ buf[i] = list_first_entry_or_null(&node->ready_queue,
+ struct pispbe_buffer,
+ ready_list);
+- spin_unlock_irqrestore(&node->ready_lock, flags1);
+- if (!buf[i] && !ignore_buffers) {
+- dev_dbg(pispbe->dev, "Nothing to do\n");
+- return 0;
+- }
+- }
+-
+- /* Pull a buffer from each V4L2 queue to form the queued job */
+- for (i = 0; i < PISPBE_NUM_NODES; i++) {
+ if (buf[i]) {
+- node = &node_group->node[i];
+-
+- spin_lock_irqsave(&node->ready_lock, flags1);
+ list_del(&buf[i]->ready_list);
+- spin_unlock_irqrestore(&node->ready_lock,
+- flags1);
++ pispbe->queued_job.buf[i] = buf[i];
+ }
+- pispbe->queued_job.buf[i] = buf[i];
++ spin_unlock_irqrestore(&node->ready_lock, flags);
++
++ if (!buf[i] && !ignore_buffers)
++ goto err_return_buffers;
+ }
+
+- pispbe->queued_job.node_group = node_group;
+- pispbe->hw_busy = 1;
+- spin_unlock_irqrestore(&pispbe->hw_lock, flags);
+-
+- /*
+- * We can kick the job off without the hw_lock, as this can
+- * never run again until hw_busy is cleared, which will happen
+- * only when the following job has been queued.
+- */
+- dev_dbg(pispbe->dev, "Have buffers - starting hardware\n");
++ pispbe->queued_job.valid = true;
+
+ /* Convert buffers to DMA addresses for the hardware */
+- fixup_addrs_enables(hw_dma_addrs, hw_enables,
+- config_tiles_buffer, buf, node_group);
+- /*
+- * This could be a spot to fill in the
+- * buf[i]->vb.vb2_buf.planes[j].bytesused fields?
+- */
+- i = config_tiles_buffer->num_tiles;
+- if (i <= 0 || i > PISP_BACK_END_NUM_TILES ||
+- !((hw_enables[0] | hw_enables[1]) &
+- PISP_BE_BAYER_ENABLE_INPUT)) {
+- /*
+- * Bad job. We can't let it proceed as it could lock up
+- * the hardware, or worse!
+- *
+- * XXX How to deal with this most cleanly? For now, just
+- * force num_tiles to 0, which causes the H/W to do
+- * something bizarre but survivable. It increments
+- * (started,done) counters by more than 1, but we seem
+- * to survive...
+- */
+- dev_err(pispbe->dev, "PROBLEM: Bad job");
+- i = 0;
+- }
+- hw_queue_job(pispbe, hw_dma_addrs, hw_enables,
+- &config_tiles_buffer->config, tiles, i);
++ pispbe_xlate_addrs(pispbe, job, buf);
+
+- return 1;
+-}
++ return 0;
+
+-/* Try and schedule a job for just a single node group. */
+-static void pispbe_schedule_one(struct pispbe_node_group *node_group)
+-{
+- struct pispbe_dev *pispbe = node_group->pispbe;
+- unsigned long flags;
+- int ret;
++err_return_buffers:
++ for (unsigned int i = 0; i < PISPBE_NUM_NODES; i++) {
++ struct pispbe_node *n = &pispbe->node[i];
+
+- spin_lock_irqsave(&pispbe->hw_lock, flags);
+- if (pispbe->hw_busy) {
+- spin_unlock_irqrestore(&pispbe->hw_lock, flags);
+- return;
++ if (!buf[i])
++ continue;
++
++ /* Return the buffer to the ready_list queue */
++ spin_lock_irqsave(&n->ready_lock, flags);
++ list_add(&buf[i]->ready_list, &n->ready_queue);
++ spin_unlock_irqrestore(&n->ready_lock, flags);
+ }
+
+- /* A non-zero return means the lock was released. */
+- ret = pispbe_schedule_internal(node_group, flags);
+- if (!ret)
+- spin_unlock_irqrestore(&pispbe->hw_lock, flags);
++ memset(&pispbe->queued_job, 0, sizeof(pispbe->queued_job));
++
++ return -ENODEV;
+ }
+
+-/* Try and schedule a job for any of the node groups. */
+-static void pispbe_schedule_any(struct pispbe_dev *pispbe, int clear_hw_busy)
++static void pispbe_schedule(struct pispbe_dev *pispbe, bool clear_hw_busy)
+ {
++ struct pispbe_job_descriptor job;
+ unsigned long flags;
++ int ret;
+
+ spin_lock_irqsave(&pispbe->hw_lock, flags);
+
+ if (clear_hw_busy)
+- pispbe->hw_busy = 0;
+- if (pispbe->hw_busy == 0) {
+- unsigned int i;
++ pispbe->hw_busy = false;
+
+- for (i = 0; i < PISPBE_NUM_NODE_GROUPS; i++) {
+- /*
+- * A non-zero return from pispbe_schedule_internal means
+- * the lock was released.
+- */
+- if (pispbe_schedule_internal(&pispbe->node_group[i],
+- flags))
+- return;
+- }
++ if (pispbe->hw_busy)
++ goto unlock_and_return;
++
++ ret = pispbe_prepare_job(pispbe, &job);
++ if (ret)
++ goto unlock_and_return;
++
++ /*
++ * We can kick the job off without the hw_lock, as this can
++ * never run again until hw_busy is cleared, which will happen
++ * only when the following job has been queued and an interrupt
++ * is rised.
++ */
++ pispbe->hw_busy = true;
++ spin_unlock_irqrestore(&pispbe->hw_lock, flags);
++
++ if (job.config->num_tiles <= 0 ||
++ job.config->num_tiles > PISP_BACK_END_NUM_TILES ||
++ !((job.hw_enables.bayer_enables | job.hw_enables.rgb_enables) &
++ PISP_BE_BAYER_ENABLE_INPUT)) {
++ /*
++ * Bad job. We can't let it proceed as it could lock up
++ * the hardware, or worse!
++ *
++ * For now, just force num_tiles to 0, which causes the
++ * H/W to do something bizarre but survivable. It
++ * increments (started,done) counters by more than 1,
++ * but we seem to survive...
++ */
++ dev_dbg(pispbe->dev, "Bad job: invalid number of tiles: %u\n",
++ job.config->num_tiles);
++ job.config->num_tiles = 0;
+ }
++
++ pispbe_queue_job(pispbe, &job);
++
++ return;
++
++unlock_and_return:
++ /* No job has been queued, just release the lock and return. */
+ spin_unlock_irqrestore(&pispbe->hw_lock, flags);
+ }
+
+@@ -699,62 +623,53 @@ static void pispbe_isr_jobdone(struct pi
+ {
+ struct pispbe_buffer **buf = job->buf;
+ u64 ts = ktime_get_ns();
+- int i;
+
+- for (i = 0; i < PISPBE_NUM_NODES; i++) {
++ for (unsigned int i = 0; i < PISPBE_NUM_NODES; i++) {
+ if (buf[i]) {
+ buf[i]->vb.vb2_buf.timestamp = ts;
+- buf[i]->vb.sequence = job->node_group->sequence;
++ buf[i]->vb.sequence = pispbe->sequence;
+ vb2_buffer_done(&buf[i]->vb.vb2_buf,
+ VB2_BUF_STATE_DONE);
+ }
+ }
+
+- job->node_group->sequence++;
++ pispbe->sequence++;
+ }
+
+ static irqreturn_t pispbe_isr(int irq, void *dev)
+ {
+ struct pispbe_dev *pispbe = (struct pispbe_dev *)dev;
++ bool can_queue_another = false;
+ u8 started, done;
+- int can_queue_another = 0;
+ u32 u;
+
+- u = read_reg(pispbe, PISP_BE_INTERRUPT_STATUS_OFFSET);
++ u = pispbe_rd(pispbe, PISP_BE_INTERRUPT_STATUS_REG);
+ if (u == 0)
+ return IRQ_NONE;
+
+- write_reg(pispbe, PISP_BE_INTERRUPT_STATUS_OFFSET, u);
+- dev_dbg(pispbe->dev, "Hardware interrupt\n");
+- u = read_reg(pispbe, PISP_BE_BATCH_STATUS_OFFSET);
++ pispbe_wr(pispbe, PISP_BE_INTERRUPT_STATUS_REG, u);
++ u = pispbe_rd(pispbe, PISP_BE_BATCH_STATUS_REG);
+ done = (uint8_t)u;
+ started = (uint8_t)(u >> 8);
+- dev_dbg(pispbe->dev,
+- "H/W started %d done %d, previously started %d done %d\n",
+- (int)started, (int)done, (int)pispbe->started,
+- (int)pispbe->done);
+
+ /*
+ * Be aware that done can go up by 2 and started by 1 when: a job that
+ * we previously saw "start" now finishes, and we then queued a new job
+ * which we see both start and finish "simultaneously".
+ */
+- if (pispbe->running_job.node_group && pispbe->done != done) {
++ if (pispbe->running_job.valid && pispbe->done != done) {
+ pispbe_isr_jobdone(pispbe, &pispbe->running_job);
+ memset(&pispbe->running_job, 0, sizeof(pispbe->running_job));
+ pispbe->done++;
+- dev_dbg(pispbe->dev, "Job done (1)\n");
+ }
+
+ if (pispbe->started != started) {
+ pispbe->started++;
+ can_queue_another = 1;
+- dev_dbg(pispbe->dev, "Job started\n");
+
+- if (pispbe->done != done && pispbe->queued_job.node_group) {
++ if (pispbe->done != done && pispbe->queued_job.valid) {
+ pispbe_isr_jobdone(pispbe, &pispbe->queued_job);
+ pispbe->done++;
+- dev_dbg(pispbe->dev, "Job done (2)\n");
+ } else {
+ pispbe->running_job = pispbe->queued_job;
+ }
+@@ -763,74 +678,81 @@ static irqreturn_t pispbe_isr(int irq, v
+ }
+
+ if (pispbe->done != done || pispbe->started != started) {
+- dev_err(pispbe->dev, "PROBLEM: counters not matching!\n");
++ dev_dbg(pispbe->dev,
++ "Job counters not matching: done = %u, expected %u - started = %u, expected %u\n",
++ pispbe->done, done, pispbe->started, started);
+ pispbe->started = started;
+ pispbe->done = done;
+ }
+
+ /* check if there's more to do before going to sleep */
+- pispbe_schedule_any(pispbe, can_queue_another);
++ pispbe_schedule(pispbe, can_queue_another);
+
+ return IRQ_HANDLED;
+ }
+
+-static int pisp_be_validate_config(struct pispbe_node_group *node_group,
++static int pisp_be_validate_config(struct pispbe_dev *pispbe,
+ struct pisp_be_tiles_config *config)
+ {
+ u32 bayer_enables = config->config.global.bayer_enables;
+ u32 rgb_enables = config->config.global.rgb_enables;
+- struct device *dev = node_group->pispbe->dev;
++ struct device *dev = pispbe->dev;
+ struct v4l2_format *fmt;
+- unsigned int bpl, size, i, j;
++ unsigned int bpl, size;
+
+ if (!(bayer_enables & PISP_BE_BAYER_ENABLE_INPUT) ==
+ !(rgb_enables & PISP_BE_RGB_ENABLE_INPUT)) {
+- dev_err(dev, "%s: Not one input enabled\n", __func__);
++ dev_dbg(dev, "%s: Not one input enabled\n", __func__);
+ return -EIO;
+ }
+
+ /* Ensure output config strides and buffer sizes match the V4L2 formats. */
+- fmt = &node_group->node[TDN_OUTPUT_NODE].format;
++ fmt = &pispbe->node[TDN_OUTPUT_NODE].format;
+ if (bayer_enables & PISP_BE_BAYER_ENABLE_TDN_OUTPUT) {
+ bpl = config->config.tdn_output_format.stride;
+ size = bpl * config->config.tdn_output_format.height;
++
+ if (fmt->fmt.pix_mp.plane_fmt[0].bytesperline < bpl) {
+- dev_err(dev, "%s: bpl mismatch on tdn_output\n",
++ dev_dbg(dev, "%s: bpl mismatch on tdn_output\n",
+ __func__);
+ return -EINVAL;
+ }
++
+ if (fmt->fmt.pix_mp.plane_fmt[0].sizeimage < size) {
+- dev_err(dev, "%s: size mismatch on tdn_output\n",
++ dev_dbg(dev, "%s: size mismatch on tdn_output\n",
+ __func__);
+ return -EINVAL;
+ }
+ }
+
+- fmt = &node_group->node[STITCH_OUTPUT_NODE].format;
++ fmt = &pispbe->node[STITCH_OUTPUT_NODE].format;
+ if (bayer_enables & PISP_BE_BAYER_ENABLE_STITCH_OUTPUT) {
+ bpl = config->config.stitch_output_format.stride;
+ size = bpl * config->config.stitch_output_format.height;
++
+ if (fmt->fmt.pix_mp.plane_fmt[0].bytesperline < bpl) {
+- dev_err(dev, "%s: bpl mismatch on stitch_output\n",
++ dev_dbg(dev, "%s: bpl mismatch on stitch_output\n",
+ __func__);
+ return -EINVAL;
+ }
++
+ if (fmt->fmt.pix_mp.plane_fmt[0].sizeimage < size) {
+- dev_err(dev, "%s: size mismatch on stitch_output\n",
++ dev_dbg(dev, "%s: size mismatch on stitch_output\n",
+ __func__);
+ return -EINVAL;
+ }
+ }
+
+- for (j = 0; j < PISP_BACK_END_NUM_OUTPUTS; j++) {
++ for (unsigned int j = 0; j < PISP_BACK_END_NUM_OUTPUTS; j++) {
+ if (!(rgb_enables & PISP_BE_RGB_ENABLE_OUTPUT(j)))
+ continue;
++
+ if (config->config.output_format[j].image.format &
+ PISP_IMAGE_FORMAT_WALLPAPER_ROLL)
+ continue; /* TODO: Size checks for wallpaper formats */
+
+- fmt = &node_group->node[OUTPUT0_NODE + j].format;
+- for (i = 0; i < fmt->fmt.pix_mp.num_planes; i++) {
++ fmt = &pispbe->node[OUTPUT0_NODE + j].format;
++ for (unsigned int i = 0; i < fmt->fmt.pix_mp.num_planes; i++) {
+ bpl = !i ? config->config.output_format[j].image.stride
+ : config->config.output_format[j].image.stride2;
+ size = bpl * config->config.output_format[j].image.height;
+@@ -838,13 +760,15 @@ static int pisp_be_validate_config(struc
+ if (config->config.output_format[j].image.format &
+ PISP_IMAGE_FORMAT_SAMPLING_420)
+ size >>= 1;
++
+ if (fmt->fmt.pix_mp.plane_fmt[i].bytesperline < bpl) {
+- dev_err(dev, "%s: bpl mismatch on output %d\n",
++ dev_dbg(dev, "%s: bpl mismatch on output %d\n",
+ __func__, j);
+ return -EINVAL;
+ }
++
+ if (fmt->fmt.pix_mp.plane_fmt[i].sizeimage < size) {
+- dev_err(dev, "%s: size mismatch on output\n",
++ dev_dbg(dev, "%s: size mismatch on output\n",
+ __func__);
+ return -EINVAL;
+ }
+@@ -859,32 +783,32 @@ static int pispbe_node_queue_setup(struc
+ struct device *alloc_devs[])
+ {
+ struct pispbe_node *node = vb2_get_drv_priv(q);
+- struct pispbe_dev *pispbe = node->node_group->pispbe;
++ struct pispbe_dev *pispbe = node->pispbe;
++ unsigned int num_planes = NODE_IS_MPLANE(node) ?
++ node->format.fmt.pix_mp.num_planes : 1;
+
+- *nplanes = 1;
+- if (NODE_IS_MPLANE(node)) {
+- unsigned int i;
+-
+- *nplanes = node->format.fmt.pix_mp.num_planes;
+- for (i = 0; i < *nplanes; i++) {
+- unsigned int size =
+- node->format.fmt.pix_mp.plane_fmt[i].sizeimage;
+- if (sizes[i] && sizes[i] < size) {
+- dev_err(pispbe->dev, "%s: size %u < %u\n",
+- __func__, sizes[i], size);
++ if (*nplanes) {
++ if (*nplanes != num_planes)
++ return -EINVAL;
++
++ for (unsigned int i = 0; i < *nplanes; i++) {
++ unsigned int size = NODE_IS_MPLANE(node) ?
++ node->format.fmt.pix_mp.plane_fmt[i].sizeimage :
++ node->format.fmt.meta.buffersize;
++
++ if (sizes[i] < size)
+ return -EINVAL;
+- }
+- sizes[i] = size;
+ }
+- } else if (NODE_IS_META(node)) {
+- sizes[0] = node->format.fmt.meta.buffersize;
+- /*
+- * Limit the config node buffer count to the number of internal
+- * buffers allocated.
+- */
+- if (node->id == CONFIG_NODE)
+- *nbuffers = min_t(unsigned int, *nbuffers,
+- PISP_BE_NUM_CONFIG_BUFFERS);
++
++ return 0;
++ }
++
++ *nplanes = num_planes;
++ for (unsigned int i = 0; i < *nplanes; i++) {
++ unsigned int size = NODE_IS_MPLANE(node) ?
++ node->format.fmt.pix_mp.plane_fmt[i].sizeimage :
++ node->format.fmt.meta.buffersize;
++ sizes[i] = size;
+ }
+
+ dev_dbg(pispbe->dev,
+@@ -897,19 +821,17 @@ static int pispbe_node_queue_setup(struc
+ static int pispbe_node_buffer_prepare(struct vb2_buffer *vb)
+ {
+ struct pispbe_node *node = vb2_get_drv_priv(vb->vb2_queue);
+- struct pispbe_dev *pispbe = node->node_group->pispbe;
+- unsigned long size = 0;
++ struct pispbe_dev *pispbe = node->pispbe;
+ unsigned int num_planes = NODE_IS_MPLANE(node) ?
+- node->format.fmt.pix_mp.num_planes : 1;
+- unsigned int i;
++ node->format.fmt.pix_mp.num_planes : 1;
+
+- for (i = 0; i < num_planes; i++) {
+- size = NODE_IS_MPLANE(node)
+- ? node->format.fmt.pix_mp.plane_fmt[i].sizeimage
+- : node->format.fmt.meta.buffersize;
++ for (unsigned int i = 0; i < num_planes; i++) {
++ unsigned long size = NODE_IS_MPLANE(node) ?
++ node->format.fmt.pix_mp.plane_fmt[i].sizeimage :
++ node->format.fmt.meta.buffersize;
+
+ if (vb2_plane_size(vb, i) < size) {
+- dev_err(pispbe->dev,
++ dev_dbg(pispbe->dev,
+ "data will not fit into plane %d (%lu < %lu)\n",
+ i, vb2_plane_size(vb, i), size);
+ return -EINVAL;
+@@ -919,11 +841,12 @@ static int pispbe_node_buffer_prepare(st
+ }
+
+ if (node->id == CONFIG_NODE) {
+- void *dst = &node->node_group->config[vb->index];
++ void *dst = &node->pispbe->config[vb->index];
+ void *src = vb2_plane_vaddr(vb, 0);
+
+ memcpy(dst, src, sizeof(struct pisp_be_tiles_config));
+- return pisp_be_validate_config(node->node_group, dst);
++
++ return pisp_be_validate_config(pispbe, dst);
+ }
+
+ return 0;
+@@ -936,8 +859,7 @@ static void pispbe_node_buffer_queue(str
+ struct pispbe_buffer *buffer =
+ container_of(vbuf, struct pispbe_buffer, vb);
+ struct pispbe_node *node = vb2_get_drv_priv(buf->vb2_queue);
+- struct pispbe_node_group *node_group = node->node_group;
+- struct pispbe_dev *pispbe = node->node_group->pispbe;
++ struct pispbe_dev *pispbe = node->pispbe;
+ unsigned long flags;
+
+ dev_dbg(pispbe->dev, "%s: for node %s\n", __func__, NODE_NAME(node));
+@@ -947,44 +869,53 @@ static void pispbe_node_buffer_queue(str
+
+ /*
+ * Every time we add a buffer, check if there's now some work for the hw
+- * to do, but only for this client.
++ * to do.
+ */
+- pispbe_schedule_one(node_group);
++ pispbe_schedule(pispbe, false);
+ }
+
+ static int pispbe_node_start_streaming(struct vb2_queue *q, unsigned int count)
+ {
+- unsigned long flags;
+ struct pispbe_node *node = vb2_get_drv_priv(q);
+- struct pispbe_node_group *node_group = node->node_group;
+- struct pispbe_dev *pispbe = node_group->pispbe;
++ struct pispbe_dev *pispbe = node->pispbe;
++ struct pispbe_buffer *buf, *tmp;
++ unsigned long flags;
+ int ret;
+
+ ret = pm_runtime_resume_and_get(pispbe->dev);
+ if (ret < 0)
+- return ret;
++ goto err_return_buffers;
+
+ spin_lock_irqsave(&pispbe->hw_lock, flags);
+- node->node_group->streaming_map |= BIT(node->id);
+- node->node_group->sequence = 0;
++ node->pispbe->streaming_map |= BIT(node->id);
++ node->pispbe->sequence = 0;
+ spin_unlock_irqrestore(&pispbe->hw_lock, flags);
+
+ dev_dbg(pispbe->dev, "%s: for node %s (count %u)\n",
+ __func__, NODE_NAME(node), count);
+- dev_dbg(pispbe->dev, "Nodes streaming for this group now 0x%x\n",
+- node->node_group->streaming_map);
++ dev_dbg(pispbe->dev, "Nodes streaming now 0x%x\n",
++ node->pispbe->streaming_map);
+
+ /* Maybe we're ready to run. */
+- pispbe_schedule_one(node_group);
++ pispbe_schedule(pispbe, false);
+
+ return 0;
++
++err_return_buffers:
++ spin_lock_irqsave(&pispbe->hw_lock, flags);
++ list_for_each_entry_safe(buf, tmp, &node->ready_queue, ready_list) {
++ list_del(&buf->ready_list);
++ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_QUEUED);
++ }
++ spin_unlock_irqrestore(&pispbe->hw_lock, flags);
++
++ return ret;
+ }
+
+ static void pispbe_node_stop_streaming(struct vb2_queue *q)
+ {
+ struct pispbe_node *node = vb2_get_drv_priv(q);
+- struct pispbe_node_group *node_group = node->node_group;
+- struct pispbe_dev *pispbe = node_group->pispbe;
++ struct pispbe_dev *pispbe = node->pispbe;
+ struct pispbe_buffer *buf;
+ unsigned long flags;
+
+@@ -994,7 +925,8 @@ static void pispbe_node_stop_streaming(s
+ * partial set of buffers was queued and cannot be run. For now, just
+ * cancel all buffers stuck in the "ready queue", then wait for any
+ * running job.
+- * XXX This may return buffers out of order.
++ *
++ * This may return buffers out of order.
+ */
+ dev_dbg(pispbe->dev, "%s: for node %s\n", __func__, NODE_NAME(node));
+ spin_lock_irqsave(&pispbe->hw_lock, flags);
+@@ -1016,14 +948,14 @@ static void pispbe_node_stop_streaming(s
+ vb2_wait_for_all_buffers(&node->queue);
+
+ spin_lock_irqsave(&pispbe->hw_lock, flags);
+- node_group->streaming_map &= ~BIT(node->id);
++ pispbe->streaming_map &= ~BIT(node->id);
+ spin_unlock_irqrestore(&pispbe->hw_lock, flags);
+
+ pm_runtime_mark_last_busy(pispbe->dev);
+ pm_runtime_put_autosuspend(pispbe->dev);
+
+- dev_dbg(pispbe->dev, "Nodes streaming for this group now 0x%x\n",
+- node_group->streaming_map);
++ dev_dbg(pispbe->dev, "Nodes streaming now 0x%x\n",
++ pispbe->streaming_map);
+ }
+
+ static const struct vb2_ops pispbe_node_queue_ops = {
+@@ -1047,22 +979,15 @@ static int pispbe_node_querycap(struct f
+ struct v4l2_capability *cap)
+ {
+ struct pispbe_node *node = video_drvdata(file);
+- struct pispbe_dev *pispbe = node->node_group->pispbe;
++ struct pispbe_dev *pispbe = node->pispbe;
+
+ strscpy(cap->driver, PISPBE_NAME, sizeof(cap->driver));
+ strscpy(cap->card, PISPBE_NAME, sizeof(cap->card));
+- snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
+- dev_name(pispbe->dev));
+-
+- cap->capabilities = V4L2_CAP_VIDEO_CAPTURE_MPLANE |
+- V4L2_CAP_VIDEO_OUTPUT_MPLANE |
+- V4L2_CAP_STREAMING | V4L2_CAP_DEVICE_CAPS |
+- V4L2_CAP_META_OUTPUT | V4L2_CAP_META_CAPTURE;
+- cap->device_caps = node->vfd.device_caps;
+
+ dev_dbg(pispbe->dev, "Caps for node %s: %x and %x (dev %x)\n",
+ NODE_NAME(node), cap->capabilities, cap->device_caps,
+ node->vfd.device_caps);
++
+ return 0;
+ }
+
+@@ -1070,17 +995,19 @@ static int pispbe_node_g_fmt_vid_cap(str
+ struct v4l2_format *f)
+ {
+ struct pispbe_node *node = video_drvdata(file);
+- struct pispbe_dev *pispbe = node->node_group->pispbe;
++ struct pispbe_dev *pispbe = node->pispbe;
+
+ if (!NODE_IS_CAPTURE(node) || NODE_IS_META(node)) {
+- dev_err(pispbe->dev,
++ dev_dbg(pispbe->dev,
+ "Cannot get capture fmt for output node %s\n",
+ NODE_NAME(node));
+ return -EINVAL;
+ }
++
+ *f = node->format;
+ dev_dbg(pispbe->dev, "Get capture format for node %s\n",
+ NODE_NAME(node));
++
+ return 0;
+ }
+
+@@ -1088,17 +1015,19 @@ static int pispbe_node_g_fmt_vid_out(str
+ struct v4l2_format *f)
+ {
+ struct pispbe_node *node = video_drvdata(file);
+- struct pispbe_dev *pispbe = node->node_group->pispbe;
++ struct pispbe_dev *pispbe = node->pispbe;
+
+ if (NODE_IS_CAPTURE(node) || NODE_IS_META(node)) {
+- dev_err(pispbe->dev,
++ dev_dbg(pispbe->dev,
+ "Cannot get capture fmt for output node %s\n",
+ NODE_NAME(node));
+ return -EINVAL;
+ }
++
+ *f = node->format;
+ dev_dbg(pispbe->dev, "Get output format for node %s\n",
+ NODE_NAME(node));
++
+ return 0;
+ }
+
+@@ -1106,98 +1035,42 @@ static int pispbe_node_g_fmt_meta_out(st
+ struct v4l2_format *f)
+ {
+ struct pispbe_node *node = video_drvdata(file);
+- struct pispbe_dev *pispbe = node->node_group->pispbe;
++ struct pispbe_dev *pispbe = node->pispbe;
+
+ if (!NODE_IS_META(node) || NODE_IS_CAPTURE(node)) {
+- dev_err(pispbe->dev,
++ dev_dbg(pispbe->dev,
+ "Cannot get capture fmt for meta output node %s\n",
+ NODE_NAME(node));
+ return -EINVAL;
+ }
+- *f = node->format;
+- dev_dbg(pispbe->dev, "Get output format for meta node %s\n",
+- NODE_NAME(node));
+- return 0;
+-}
+
+-static int pispbe_node_g_fmt_meta_cap(struct file *file, void *priv,
+- struct v4l2_format *f)
+-{
+- struct pispbe_node *node = video_drvdata(file);
+- struct pispbe_dev *pispbe = node->node_group->pispbe;
+-
+- if (!NODE_IS_META(node) || NODE_IS_OUTPUT(node)) {
+- dev_err(pispbe->dev,
+- "Cannot get capture fmt for meta output node %s\n",
+- NODE_NAME(node));
+- return -EINVAL;
+- }
+ *f = node->format;
+ dev_dbg(pispbe->dev, "Get output format for meta node %s\n",
+ NODE_NAME(node));
+- return 0;
+-}
+-
+-static int verify_be_pix_format(const struct v4l2_format *f,
+- struct pispbe_node *node)
+-{
+- struct pispbe_dev *pispbe = node->node_group->pispbe;
+- unsigned int nplanes = f->fmt.pix_mp.num_planes;
+- unsigned int i;
+-
+- if (f->fmt.pix_mp.width == 0 || f->fmt.pix_mp.height == 0) {
+- dev_err(pispbe->dev, "Details incorrect for output node %s\n",
+- NODE_NAME(node));
+- return -EINVAL;
+- }
+-
+- if (nplanes == 0 || nplanes > MAX_PLANES) {
+- dev_err(pispbe->dev,
+- "Bad number of planes for output node %s, req =%d\n",
+- NODE_NAME(node), nplanes);
+- return -EINVAL;
+- }
+-
+- for (i = 0; i < nplanes; i++) {
+- const struct v4l2_plane_pix_format *p;
+-
+- p = &f->fmt.pix_mp.plane_fmt[i];
+- if (p->bytesperline == 0 || p->sizeimage == 0) {
+- dev_err(pispbe->dev,
+- "Invalid plane %d for output node %s\n",
+- i, NODE_NAME(node));
+- return -EINVAL;
+- }
+- }
+
+ return 0;
+ }
+
+-static const struct pisp_be_format *find_format(unsigned int fourcc)
++static const struct pisp_be_format *pispbe_find_fmt(unsigned int fourcc)
+ {
+- const struct pisp_be_format *fmt;
+- unsigned int i;
+-
+- for (i = 0; i < ARRAY_SIZE(supported_formats); i++) {
+- fmt = &supported_formats[i];
+- if (fmt->fourcc == fourcc)
+- return fmt;
++ for (unsigned int i = 0; i < ARRAY_SIZE(supported_formats); i++) {
++ if (supported_formats[i].fourcc == fourcc)
++ return &supported_formats[i];
+ }
+
+ return NULL;
+ }
+
+-static void set_plane_params(struct v4l2_format *f,
+- const struct pisp_be_format *fmt)
++static void pispbe_set_plane_params(struct v4l2_format *f,
++ const struct pisp_be_format *fmt)
+ {
+ unsigned int nplanes = f->fmt.pix_mp.num_planes;
+ unsigned int total_plane_factor = 0;
+- unsigned int i;
+
+- for (i = 0; i < MAX_PLANES; i++)
++ for (unsigned int i = 0; i < PISPBE_MAX_PLANES; i++)
+ total_plane_factor += fmt->plane_factor[i];
+
+- for (i = 0; i < nplanes; i++) {
++ for (unsigned int i = 0; i < nplanes; i++) {
+ struct v4l2_plane_pix_format *p = &f->fmt.pix_mp.plane_fmt[i];
+ unsigned int bpl, plane_size;
+
+@@ -1217,28 +1090,25 @@ static void set_plane_params(struct v4l2
+ }
+ }
+
+-static int try_format(struct v4l2_format *f, struct pispbe_node *node)
++static void pispbe_try_format(struct v4l2_format *f, struct pispbe_node *node)
+ {
+- struct pispbe_dev *pispbe = node->node_group->pispbe;
++ struct pispbe_dev *pispbe = node->pispbe;
++ u32 pixfmt = f->fmt.pix_mp.pixelformat;
+ const struct pisp_be_format *fmt;
+- unsigned int i;
+ bool is_rgb;
+- u32 pixfmt = f->fmt.pix_mp.pixelformat;
+
+ dev_dbg(pispbe->dev,
+- "%s: [%s] req %ux%u " V4L2_FOURCC_CONV ", planes %d\n",
++ "%s: [%s] req %ux%u %p4cc, planes %d\n",
+ __func__, NODE_NAME(node), f->fmt.pix_mp.width,
+- f->fmt.pix_mp.height, V4L2_FOURCC_CONV_ARGS(pixfmt),
++ f->fmt.pix_mp.height, &pixfmt,
+ f->fmt.pix_mp.num_planes);
+
+- if (pixfmt == V4L2_PIX_FMT_RPI_BE)
+- return verify_be_pix_format(f, node);
+-
+- fmt = find_format(pixfmt);
++ fmt = pispbe_find_fmt(pixfmt);
+ if (!fmt) {
+- dev_dbg(pispbe->dev, "%s: [%s] Format not found, defaulting to YUV420\n",
++ dev_dbg(pispbe->dev,
++ "%s: [%s] Format not found, defaulting to YUV420\n",
+ __func__, NODE_NAME(node));
+- fmt = find_format(V4L2_PIX_FMT_YUV420);
++ fmt = pispbe_find_fmt(V4L2_PIX_FMT_YUV420);
+ }
+
+ f->fmt.pix_mp.pixelformat = fmt->fourcc;
+@@ -1254,7 +1124,8 @@ static int try_format(struct v4l2_format
+ * not supported. This also catches the case when the "default"
+ * colour space was requested (as that's never in the mask).
+ */
+- if (!(V4L2_COLORSPACE_MASK(f->fmt.pix_mp.colorspace) & fmt->colorspace_mask))
++ if (!(V4L2_COLORSPACE_MASK(f->fmt.pix_mp.colorspace) &
++ fmt->colorspace_mask))
+ f->fmt.pix_mp.colorspace = fmt->colorspace_default;
+
+ /* In all cases, we only support the defaults for these: */
+@@ -1269,9 +1140,9 @@ static int try_format(struct v4l2_format
+ f->fmt.pix_mp.ycbcr_enc);
+
+ /* Set plane size and bytes/line for each plane. */
+- set_plane_params(f, fmt);
++ pispbe_set_plane_params(f, fmt);
+
+- for (i = 0; i < f->fmt.pix_mp.num_planes; i++) {
++ for (unsigned int i = 0; i < f->fmt.pix_mp.num_planes; i++) {
+ dev_dbg(pispbe->dev,
+ "%s: [%s] calc plane %d, %ux%u, depth %u, bpl %u size %u\n",
+ __func__, NODE_NAME(node), i, f->fmt.pix_mp.width,
+@@ -1279,27 +1150,22 @@ static int try_format(struct v4l2_format
+ f->fmt.pix_mp.plane_fmt[i].bytesperline,
+ f->fmt.pix_mp.plane_fmt[i].sizeimage);
+ }
+-
+- return 0;
+ }
+
+ static int pispbe_node_try_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+ {
+ struct pispbe_node *node = video_drvdata(file);
+- struct pispbe_dev *pispbe = node->node_group->pispbe;
+- int ret;
++ struct pispbe_dev *pispbe = node->pispbe;
+
+ if (!NODE_IS_CAPTURE(node) || NODE_IS_META(node)) {
+- dev_err(pispbe->dev,
++ dev_dbg(pispbe->dev,
+ "Cannot set capture fmt for output node %s\n",
+ NODE_NAME(node));
+ return -EINVAL;
+ }
+
+- ret = try_format(f, node);
+- if (ret < 0)
+- return ret;
++ pispbe_try_format(f, node);
+
+ return 0;
+ }
+@@ -1308,19 +1174,16 @@ static int pispbe_node_try_fmt_vid_out(s
+ struct v4l2_format *f)
+ {
+ struct pispbe_node *node = video_drvdata(file);
+- struct pispbe_dev *pispbe = node->node_group->pispbe;
+- int ret;
++ struct pispbe_dev *pispbe = node->pispbe;
+
+ if (!NODE_IS_OUTPUT(node) || NODE_IS_META(node)) {
+- dev_err(pispbe->dev,
++ dev_dbg(pispbe->dev,
+ "Cannot set capture fmt for output node %s\n",
+ NODE_NAME(node));
+ return -EINVAL;
+ }
+
+- ret = try_format(f, node);
+- if (ret < 0)
+- return ret;
++ pispbe_try_format(f, node);
+
+ return 0;
+ }
+@@ -1329,10 +1192,10 @@ static int pispbe_node_try_fmt_meta_out(
+ struct v4l2_format *f)
+ {
+ struct pispbe_node *node = video_drvdata(file);
+- struct pispbe_dev *pispbe = node->node_group->pispbe;
++ struct pispbe_dev *pispbe = node->pispbe;
+
+ if (!NODE_IS_META(node) || NODE_IS_CAPTURE(node)) {
+- dev_err(pispbe->dev,
++ dev_dbg(pispbe->dev,
+ "Cannot set capture fmt for meta output node %s\n",
+ NODE_NAME(node));
+ return -EINVAL;
+@@ -1344,43 +1207,26 @@ static int pispbe_node_try_fmt_meta_out(
+ return 0;
+ }
+
+-static int pispbe_node_try_fmt_meta_cap(struct file *file, void *priv,
+- struct v4l2_format *f)
+-{
+- struct pispbe_node *node = video_drvdata(file);
+- struct pispbe_dev *pispbe = node->node_group->pispbe;
+-
+- if (!NODE_IS_META(node) || NODE_IS_OUTPUT(node)) {
+- dev_err(pispbe->dev,
+- "Cannot set capture fmt for meta output node %s\n",
+- NODE_NAME(node));
+- return -EINVAL;
+- }
+-
+- f->fmt.meta.dataformat = V4L2_PIX_FMT_RPI_BE;
+- if (!f->fmt.meta.buffersize)
+- f->fmt.meta.buffersize = BIT(20);
+-
+- return 0;
+-}
+-
+ static int pispbe_node_s_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+ {
+ struct pispbe_node *node = video_drvdata(file);
+- struct pispbe_dev *pispbe = node->node_group->pispbe;
+- int ret = pispbe_node_try_fmt_vid_cap(file, priv, f);
++ struct pispbe_dev *pispbe = node->pispbe;
++ int ret;
+
++ ret = pispbe_node_try_fmt_vid_cap(file, priv, f);
+ if (ret < 0)
+ return ret;
+
++ if (vb2_is_busy(&node->queue))
++ return -EBUSY;
++
+ node->format = *f;
+- node->pisp_format = find_format(f->fmt.pix_mp.pixelformat);
++ node->pisp_format = pispbe_find_fmt(f->fmt.pix_mp.pixelformat);
++
++ dev_dbg(pispbe->dev, "Set capture format for node %s to %p4cc\n",
++ NODE_NAME(node), &f->fmt.pix_mp.pixelformat);
+
+- dev_dbg(pispbe->dev,
+- "Set capture format for node %s to " V4L2_FOURCC_CONV "\n",
+- NODE_NAME(node),
+- V4L2_FOURCC_CONV_ARGS(f->fmt.pix_mp.pixelformat));
+ return 0;
+ }
+
+@@ -1388,19 +1234,22 @@ static int pispbe_node_s_fmt_vid_out(str
+ struct v4l2_format *f)
+ {
+ struct pispbe_node *node = video_drvdata(file);
+- struct pispbe_dev *pispbe = node->node_group->pispbe;
+- int ret = pispbe_node_try_fmt_vid_out(file, priv, f);
++ struct pispbe_dev *pispbe = node->pispbe;
++ int ret;
+
++ ret = pispbe_node_try_fmt_vid_out(file, priv, f);
+ if (ret < 0)
+ return ret;
+
++ if (vb2_is_busy(&node->queue))
++ return -EBUSY;
++
+ node->format = *f;
+- node->pisp_format = find_format(f->fmt.pix_mp.pixelformat);
++ node->pisp_format = pispbe_find_fmt(f->fmt.pix_mp.pixelformat);
++
++ dev_dbg(pispbe->dev, "Set output format for node %s to %p4cc\n",
++ NODE_NAME(node), &f->fmt.pix_mp.pixelformat);
+
+- dev_dbg(pispbe->dev,
+- "Set output format for node %s to " V4L2_FOURCC_CONV "\n",
+- NODE_NAME(node),
+- V4L2_FOURCC_CONV_ARGS(f->fmt.pix_mp.pixelformat));
+ return 0;
+ }
+
+@@ -1408,39 +1257,22 @@ static int pispbe_node_s_fmt_meta_out(st
+ struct v4l2_format *f)
+ {
+ struct pispbe_node *node = video_drvdata(file);
+- struct pispbe_dev *pispbe = node->node_group->pispbe;
+- int ret = pispbe_node_try_fmt_meta_out(file, priv, f);
++ struct pispbe_dev *pispbe = node->pispbe;
++ int ret;
+
++ ret = pispbe_node_try_fmt_meta_out(file, priv, f);
+ if (ret < 0)
+ return ret;
+
++ if (vb2_is_busy(&node->queue))
++ return -EBUSY;
++
+ node->format = *f;
+ node->pisp_format = &meta_out_supported_formats[0];
+
+- dev_dbg(pispbe->dev,
+- "Set output format for meta node %s to " V4L2_FOURCC_CONV "\n",
+- NODE_NAME(node),
+- V4L2_FOURCC_CONV_ARGS(f->fmt.meta.dataformat));
+- return 0;
+-}
+-
+-static int pispbe_node_s_fmt_meta_cap(struct file *file, void *priv,
+- struct v4l2_format *f)
+-{
+- struct pispbe_node *node = video_drvdata(file);
+- struct pispbe_dev *pispbe = node->node_group->pispbe;
+- int ret = pispbe_node_try_fmt_meta_cap(file, priv, f);
+-
+- if (ret < 0)
+- return ret;
+-
+- node->format = *f;
+- node->pisp_format = find_format(f->fmt.meta.dataformat);
++ dev_dbg(pispbe->dev, "Set output format for meta node %s to %p4cc\n",
++ NODE_NAME(node), &f->fmt.meta.dataformat);
+
+- dev_dbg(pispbe->dev,
+- "Set capture format for meta node %s to " V4L2_FOURCC_CONV "\n",
+- NODE_NAME(node),
+- V4L2_FOURCC_CONV_ARGS(f->fmt.meta.dataformat));
+ return 0;
+ }
+
+@@ -1456,10 +1288,7 @@ static int pispbe_node_enum_fmt(struct f
+ if (f->index)
+ return -EINVAL;
+
+- if (NODE_IS_OUTPUT(node))
+- f->pixelformat = V4L2_META_FMT_RPI_BE_CFG;
+- else
+- f->pixelformat = V4L2_PIX_FMT_RPI_BE;
++ f->pixelformat = V4L2_META_FMT_RPI_BE_CFG;
+ f->flags = 0;
+ return 0;
+ }
+@@ -1477,13 +1306,13 @@ static int pispbe_enum_framesizes(struct
+ struct v4l2_frmsizeenum *fsize)
+ {
+ struct pispbe_node *node = video_drvdata(file);
+- struct pispbe_dev *pispbe = node->node_group->pispbe;
++ struct pispbe_dev *pispbe = node->pispbe;
+
+ if (NODE_IS_META(node) || fsize->index)
+ return -EINVAL;
+
+- if (!find_format(fsize->pixel_format)) {
+- dev_err(pispbe->dev, "Invalid pixel code: %x\n",
++ if (!pispbe_find_fmt(fsize->pixel_format)) {
++ dev_dbg(pispbe->dev, "Invalid pixel code: %x\n",
+ fsize->pixel_format);
+ return -EINVAL;
+ }
+@@ -1500,49 +1329,19 @@ static int pispbe_enum_framesizes(struct
+ return 0;
+ }
+
+-static int pispbe_node_streamon(struct file *file, void *priv,
+- enum v4l2_buf_type type)
+-{
+- struct pispbe_node *node = video_drvdata(file);
+- struct pispbe_dev *pispbe = node->node_group->pispbe;
+-
+- /* Do we need a node->stream_lock mutex? */
+-
+- dev_dbg(pispbe->dev, "Stream on for node %s\n", NODE_NAME(node));
+-
+- /* Do we care about the type? Each node has only one queue. */
+-
+- INIT_LIST_HEAD(&node->ready_queue);
+-
+- /* locking should be handled by the queue->lock? */
+- return vb2_streamon(&node->queue, type);
+-}
+-
+-static int pispbe_node_streamoff(struct file *file, void *priv,
+- enum v4l2_buf_type type)
+-{
+- struct pispbe_node *node = video_drvdata(file);
+-
+- return vb2_streamoff(&node->queue, type);
+-}
+-
+ static const struct v4l2_ioctl_ops pispbe_node_ioctl_ops = {
+ .vidioc_querycap = pispbe_node_querycap,
+ .vidioc_g_fmt_vid_cap_mplane = pispbe_node_g_fmt_vid_cap,
+ .vidioc_g_fmt_vid_out_mplane = pispbe_node_g_fmt_vid_out,
+ .vidioc_g_fmt_meta_out = pispbe_node_g_fmt_meta_out,
+- .vidioc_g_fmt_meta_cap = pispbe_node_g_fmt_meta_cap,
+ .vidioc_try_fmt_vid_cap_mplane = pispbe_node_try_fmt_vid_cap,
+ .vidioc_try_fmt_vid_out_mplane = pispbe_node_try_fmt_vid_out,
+ .vidioc_try_fmt_meta_out = pispbe_node_try_fmt_meta_out,
+- .vidioc_try_fmt_meta_cap = pispbe_node_try_fmt_meta_cap,
+ .vidioc_s_fmt_vid_cap_mplane = pispbe_node_s_fmt_vid_cap,
+ .vidioc_s_fmt_vid_out_mplane = pispbe_node_s_fmt_vid_out,
+ .vidioc_s_fmt_meta_out = pispbe_node_s_fmt_meta_out,
+- .vidioc_s_fmt_meta_cap = pispbe_node_s_fmt_meta_cap,
+ .vidioc_enum_fmt_vid_cap = pispbe_node_enum_fmt,
+ .vidioc_enum_fmt_vid_out = pispbe_node_enum_fmt,
+- .vidioc_enum_fmt_meta_cap = pispbe_node_enum_fmt,
+ .vidioc_enum_fmt_meta_out = pispbe_node_enum_fmt,
+ .vidioc_enum_framesizes = pispbe_enum_framesizes,
+ .vidioc_create_bufs = vb2_ioctl_create_bufs,
+@@ -1552,8 +1351,8 @@ static const struct v4l2_ioctl_ops pispb
+ .vidioc_dqbuf = vb2_ioctl_dqbuf,
+ .vidioc_expbuf = vb2_ioctl_expbuf,
+ .vidioc_reqbufs = vb2_ioctl_reqbufs,
+- .vidioc_streamon = pispbe_node_streamon,
+- .vidioc_streamoff = pispbe_node_streamoff,
++ .vidioc_streamon = vb2_ioctl_streamon,
++ .vidioc_streamoff = vb2_ioctl_streamoff,
+ };
+
+ static const struct video_device pispbe_videodev = {
+@@ -1565,7 +1364,7 @@ static const struct video_device pispbe_
+ .release = video_device_release_empty,
+ };
+
+-static void node_set_default_format(struct pispbe_node *node)
++static void pispbe_node_def_fmt(struct pispbe_node *node)
+ {
+ if (NODE_IS_META(node) && NODE_IS_OUTPUT(node)) {
+ /* Config node */
+@@ -1574,44 +1373,35 @@ static void node_set_default_format(stru
+ f->fmt.meta.dataformat = V4L2_META_FMT_RPI_BE_CFG;
+ f->fmt.meta.buffersize = sizeof(struct pisp_be_tiles_config);
+ f->type = node->buf_type;
+- } else if (NODE_IS_META(node) && NODE_IS_CAPTURE(node)) {
+- /* HOG output node */
+- struct v4l2_format *f = &node->format;
+-
+- f->fmt.meta.dataformat = V4L2_PIX_FMT_RPI_BE;
+- f->fmt.meta.buffersize = BIT(20);
+- f->type = node->buf_type;
+ } else {
+- struct v4l2_format f = {0};
+-
+- f.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_YUV420;
+- f.fmt.pix_mp.width = 1920;
+- f.fmt.pix_mp.height = 1080;
+- f.type = node->buf_type;
+- try_format(&f, node);
++ struct v4l2_format f = {
++ .fmt.pix_mp.pixelformat = V4L2_PIX_FMT_YUV420,
++ .fmt.pix_mp.width = 1920,
++ .fmt.pix_mp.height = 1080,
++ .type = node->buf_type,
++ };
++ pispbe_try_format(&f, node);
+ node->format = f;
+ }
+
+- node->pisp_format = find_format(node->format.fmt.pix_mp.pixelformat);
++ node->pisp_format = pispbe_find_fmt(node->format.fmt.pix_mp.pixelformat);
+ }
+
+ /*
+ * Initialise a struct pispbe_node and register it as /dev/video<N>
+ * to represent one of the PiSP Back End's input or output streams.
+ */
+-static int
+-pispbe_init_node(struct pispbe_node_group *node_group, unsigned int id)
++static int pispbe_init_node(struct pispbe_dev *pispbe, unsigned int id)
+ {
+ bool output = NODE_DESC_IS_OUTPUT(&node_desc[id]);
+- struct pispbe_node *node = &node_group->node[id];
+- struct pispbe_dev *pispbe = node_group->pispbe;
++ struct pispbe_node *node = &pispbe->node[id];
+ struct media_entity *entity = &node->vfd.entity;
+ struct video_device *vdev = &node->vfd;
+ struct vb2_queue *q = &node->queue;
+ int ret;
+
+ node->id = id;
+- node->node_group = node_group;
++ node->pispbe = pispbe;
+ node->buf_type = node_desc[id].buf_type;
+
+ mutex_init(&node->node_lock);
+@@ -1620,7 +1410,7 @@ pispbe_init_node(struct pispbe_node_grou
+ spin_lock_init(&node->ready_lock);
+
+ node->format.type = node->buf_type;
+- node_set_default_format(node);
++ pispbe_node_def_fmt(node);
+
+ q->type = node->buf_type;
+ q->io_modes = VB2_MMAP | VB2_DMABUF;
+@@ -1629,19 +1419,19 @@ pispbe_init_node(struct pispbe_node_grou
+ q->ops = &pispbe_node_queue_ops;
+ q->buf_struct_size = sizeof(struct pispbe_buffer);
+ q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+- q->dev = node->node_group->pispbe->dev;
++ q->dev = pispbe->dev;
+ /* get V4L2 to handle node->queue locking */
+ q->lock = &node->queue_lock;
+
+ ret = vb2_queue_init(q);
+ if (ret < 0) {
+ dev_err(pispbe->dev, "vb2_queue_init failed\n");
+- return ret;
++ goto err_mutex_destroy;
+ }
+
+ *vdev = pispbe_videodev; /* default initialization */
+ strscpy(vdev->name, node_desc[id].ent_name, sizeof(vdev->name));
+- vdev->v4l2_dev = &node_group->v4l2_dev;
++ vdev->v4l2_dev = &pispbe->v4l2_dev;
+ vdev->vfl_dir = output ? VFL_DIR_TX : VFL_DIR_RX;
+ /* get V4L2 to serialise our ioctls */
+ vdev->lock = &node->node_lock;
+@@ -1657,8 +1447,7 @@ pispbe_init_node(struct pispbe_node_grou
+ goto err_unregister_queue;
+ }
+
+- ret = video_register_device(vdev, VFL_TYPE_VIDEO,
+- PISPBE_VIDEO_NODE_OFFSET);
++ ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
+ if (ret) {
+ dev_err(pispbe->dev,
+ "Failed to register video %s device node\n",
+@@ -1668,25 +1457,28 @@ pispbe_init_node(struct pispbe_node_grou
+ video_set_drvdata(vdev, node);
+
+ if (output)
+- ret = media_create_pad_link(entity, 0, &node_group->sd.entity,
++ ret = media_create_pad_link(entity, 0, &pispbe->sd.entity,
+ id, MEDIA_LNK_FL_IMMUTABLE |
+ MEDIA_LNK_FL_ENABLED);
+ else
+- ret = media_create_pad_link(&node_group->sd.entity, id, entity,
++ ret = media_create_pad_link(&pispbe->sd.entity, id, entity,
+ 0, MEDIA_LNK_FL_IMMUTABLE |
+ MEDIA_LNK_FL_ENABLED);
+ if (ret)
+ goto err_unregister_video_dev;
+
+- dev_info(pispbe->dev,
+- "%s device node registered as /dev/video%d\n",
+- NODE_NAME(node), node->vfd.num);
++ dev_dbg(pispbe->dev, "%s device node registered as /dev/video%d\n",
++ NODE_NAME(node), node->vfd.num);
++
+ return 0;
+
+ err_unregister_video_dev:
+ video_unregister_device(&node->vfd);
+ err_unregister_queue:
+ vb2_queue_release(&node->queue);
++err_mutex_destroy:
++ mutex_destroy(&node->node_lock);
++ mutex_destroy(&node->queue_lock);
+ return ret;
+ }
+
+@@ -1698,11 +1490,9 @@ static const struct v4l2_subdev_ops pisp
+ .pad = &pispbe_pad_ops,
+ };
+
+-static int pispbe_init_subdev(struct pispbe_node_group *node_group)
++static int pispbe_init_subdev(struct pispbe_dev *pispbe)
+ {
+- struct pispbe_dev *pispbe = node_group->pispbe;
+- struct v4l2_subdev *sd = &node_group->sd;
+- unsigned int i;
++ struct v4l2_subdev *sd = &pispbe->sd;
+ int ret;
+
+ v4l2_subdev_init(sd, &pispbe_sd_ops);
+@@ -1711,17 +1501,17 @@ static int pispbe_init_subdev(struct pis
+ sd->dev = pispbe->dev;
+ strscpy(sd->name, PISPBE_NAME, sizeof(sd->name));
+
+- for (i = 0; i < PISPBE_NUM_NODES; i++)
+- node_group->pad[i].flags =
++ for (unsigned int i = 0; i < PISPBE_NUM_NODES; i++)
++ pispbe->pad[i].flags =
+ NODE_DESC_IS_OUTPUT(&node_desc[i]) ?
+ MEDIA_PAD_FL_SINK : MEDIA_PAD_FL_SOURCE;
+
+ ret = media_entity_pads_init(&sd->entity, PISPBE_NUM_NODES,
+- node_group->pad);
++ pispbe->pad);
+ if (ret)
+ goto error;
+
+- ret = v4l2_device_register_subdev(&node_group->v4l2_dev, sd);
++ ret = v4l2_device_register_subdev(&pispbe->v4l2_dev, sd);
+ if (ret)
+ goto error;
+
+@@ -1732,45 +1522,36 @@ error:
+ return ret;
+ }
+
+-static int pispbe_init_group(struct pispbe_dev *pispbe, unsigned int id)
++static int pispbe_init_devices(struct pispbe_dev *pispbe)
+ {
+- struct pispbe_node_group *node_group = &pispbe->node_group[id];
+ struct v4l2_device *v4l2_dev;
+ struct media_device *mdev;
+- unsigned int num_registered = 0;
++ unsigned int num_regist;
+ int ret;
+
+- node_group->id = id;
+- node_group->pispbe = pispbe;
+- node_group->streaming_map = 0;
+-
+- dev_info(pispbe->dev, "Register nodes for group %u\n", id);
+-
+ /* Register v4l2_device and media_device */
+- mdev = &node_group->mdev;
+- mdev->hw_revision = node_group->pispbe->hw_version;
+- mdev->dev = node_group->pispbe->dev;
++ mdev = &pispbe->mdev;
++ mdev->hw_revision = pispbe->hw_version;
++ mdev->dev = pispbe->dev;
+ strscpy(mdev->model, PISPBE_NAME, sizeof(mdev->model));
+- snprintf(mdev->bus_info, sizeof(mdev->bus_info),
+- "platform:%s", dev_name(node_group->pispbe->dev));
+ media_device_init(mdev);
+
+- v4l2_dev = &node_group->v4l2_dev;
+- v4l2_dev->mdev = &node_group->mdev;
++ v4l2_dev = &pispbe->v4l2_dev;
++ v4l2_dev->mdev = &pispbe->mdev;
+ strscpy(v4l2_dev->name, PISPBE_NAME, sizeof(v4l2_dev->name));
+
+- ret = v4l2_device_register(pispbe->dev, &node_group->v4l2_dev);
++ ret = v4l2_device_register(pispbe->dev, v4l2_dev);
+ if (ret)
+ goto err_media_dev_cleanup;
+
+ /* Register the PISPBE subdevice. */
+- ret = pispbe_init_subdev(node_group);
++ ret = pispbe_init_subdev(pispbe);
+ if (ret)
+ goto err_unregister_v4l2;
+
+ /* Create device video nodes */
+- for (; num_registered < PISPBE_NUM_NODES; num_registered++) {
+- ret = pispbe_init_node(node_group, num_registered);
++ for (num_regist = 0; num_regist < PISPBE_NUM_NODES; num_regist++) {
++ ret = pispbe_init_node(pispbe, num_regist);
+ if (ret)
+ goto err_unregister_nodes;
+ }
+@@ -1779,12 +1560,12 @@ static int pispbe_init_group(struct pisp
+ if (ret)
+ goto err_unregister_nodes;
+
+- node_group->config =
++ pispbe->config =
+ dma_alloc_coherent(pispbe->dev,
+ sizeof(struct pisp_be_tiles_config) *
+ PISP_BE_NUM_CONFIG_BUFFERS,
+- &node_group->config_dma_addr, GFP_KERNEL);
+- if (!node_group->config) {
++ &pispbe->config_dma_addr, GFP_KERNEL);
++ if (!pispbe->config) {
+ dev_err(pispbe->dev, "Unable to allocate cached config buffers.\n");
+ ret = -ENOMEM;
+ goto err_unregister_mdev;
+@@ -1795,12 +1576,12 @@ static int pispbe_init_group(struct pisp
+ err_unregister_mdev:
+ media_device_unregister(mdev);
+ err_unregister_nodes:
+- while (num_registered-- > 0) {
+- video_unregister_device(&node_group->node[num_registered].vfd);
+- vb2_queue_release(&node_group->node[num_registered].queue);
++ while (num_regist-- > 0) {
++ video_unregister_device(&pispbe->node[num_regist].vfd);
++ vb2_queue_release(&pispbe->node[num_regist].queue);
+ }
+- v4l2_device_unregister_subdev(&node_group->sd);
+- media_entity_cleanup(&node_group->sd.entity);
++ v4l2_device_unregister_subdev(&pispbe->sd);
++ media_entity_cleanup(&pispbe->sd.entity);
+ err_unregister_v4l2:
+ v4l2_device_unregister(v4l2_dev);
+ err_media_dev_cleanup:
+@@ -1808,32 +1589,31 @@ err_media_dev_cleanup:
+ return ret;
+ }
+
+-static void pispbe_destroy_node_group(struct pispbe_node_group *node_group)
++static void pispbe_destroy_devices(struct pispbe_dev *pispbe)
+ {
+- struct pispbe_dev *pispbe = node_group->pispbe;
+- int i;
+-
+- if (node_group->config) {
+- dma_free_coherent(node_group->pispbe->dev,
++ if (pispbe->config) {
++ dma_free_coherent(pispbe->dev,
+ sizeof(struct pisp_be_tiles_config) *
+ PISP_BE_NUM_CONFIG_BUFFERS,
+- node_group->config,
+- node_group->config_dma_addr);
++ pispbe->config,
++ pispbe->config_dma_addr);
+ }
+
+- dev_info(pispbe->dev, "Unregister from media controller\n");
++ dev_dbg(pispbe->dev, "Unregister from media controller\n");
+
+- v4l2_device_unregister_subdev(&node_group->sd);
+- media_entity_cleanup(&node_group->sd.entity);
+- media_device_unregister(&node_group->mdev);
++ v4l2_device_unregister_subdev(&pispbe->sd);
++ media_entity_cleanup(&pispbe->sd.entity);
++ media_device_unregister(&pispbe->mdev);
+
+- for (i = PISPBE_NUM_NODES - 1; i >= 0; i--) {
+- video_unregister_device(&node_group->node[i].vfd);
+- vb2_queue_release(&node_group->node[i].queue);
++ for (int i = PISPBE_NUM_NODES - 1; i >= 0; i--) {
++ video_unregister_device(&pispbe->node[i].vfd);
++ vb2_queue_release(&pispbe->node[i].queue);
++ mutex_destroy(&pispbe->node[i].node_lock);
++ mutex_destroy(&pispbe->node[i].queue_lock);
+ }
+
+- media_device_cleanup(&node_group->mdev);
+- v4l2_device_unregister(&node_group->v4l2_dev);
++ media_device_cleanup(&pispbe->mdev);
++ v4l2_device_unregister(&pispbe->v4l2_dev);
+ }
+
+ static int pispbe_runtime_suspend(struct device *dev)
+@@ -1862,13 +1642,48 @@ static int pispbe_runtime_resume(struct
+ return 0;
+ }
+
+-/*
+- * Probe the ISP-BE hardware block, as a single platform device.
+- * This will instantiate multiple "node groups" each with many device nodes.
+- */
++static int pispbe_hw_init(struct pispbe_dev *pispbe)
++{
++ u32 u;
++
++ /* Check the HW is present and has a known version */
++ u = pispbe_rd(pispbe, PISP_BE_VERSION_REG);
++ dev_dbg(pispbe->dev, "pispbe_probe: HW version: 0x%08x", u);
++ pispbe->hw_version = u;
++ if ((u & ~PISP_BE_VERSION_MINOR_BITS) != PISP_BE_VERSION_2712)
++ return -ENODEV;
++
++ /* Clear leftover interrupts */
++ pispbe_wr(pispbe, PISP_BE_INTERRUPT_STATUS_REG, 0xFFFFFFFFu);
++ u = pispbe_rd(pispbe, PISP_BE_BATCH_STATUS_REG);
++ dev_dbg(pispbe->dev, "pispbe_probe: BatchStatus: 0x%08x", u);
++
++ pispbe->done = (uint8_t)u;
++ pispbe->started = (uint8_t)(u >> 8);
++ u = pispbe_rd(pispbe, PISP_BE_STATUS_REG);
++ dev_dbg(pispbe->dev, "pispbe_probe: Status: 0x%08x", u);
++
++ if (u != 0 || pispbe->done != pispbe->started) {
++ dev_err(pispbe->dev, "pispbe_probe: HW is stuck or busy\n");
++ return -EBUSY;
++ }
++
++ /*
++ * AXI QOS=0, CACHE=4'b0010, PROT=3'b011
++ * Also set "chicken bits" 22:20 which enable sub-64-byte bursts
++ * and AXI AWID/BID variability (on versions which support this).
++ */
++ pispbe_wr(pispbe, PISP_BE_AXI_REG, 0x32703200u);
++
++ /* Enable both interrupt flags */
++ pispbe_wr(pispbe, PISP_BE_INTERRUPT_EN_REG, 0x00000003u);
++
++ return 0;
++}
++
++/* Probe the ISP-BE hardware block, as a single platform device. */
+ static int pispbe_probe(struct platform_device *pdev)
+ {
+- unsigned int num_groups = 0;
+ struct pispbe_dev *pispbe;
+ int ret;
+
+@@ -1913,55 +1728,43 @@ static int pispbe_probe(struct platform_
+ pm_runtime_use_autosuspend(pispbe->dev);
+ pm_runtime_enable(pispbe->dev);
+
+- ret = pm_runtime_resume_and_get(pispbe->dev);
++ ret = pispbe_runtime_resume(pispbe->dev);
+ if (ret)
+ goto pm_runtime_disable_err;
+
+- pispbe->hw_busy = 0;
++ pispbe->hw_busy = false;
+ spin_lock_init(&pispbe->hw_lock);
+- ret = hw_init(pispbe);
++ ret = pispbe_hw_init(pispbe);
+ if (ret)
+- goto pm_runtime_put_err;
++ goto pm_runtime_suspend_err;
+
+- /*
+- * Initialise and register devices for each node_group, including media
+- * device
+- */
+- for (num_groups = 0;
+- num_groups < PISPBE_NUM_NODE_GROUPS;
+- num_groups++) {
+- ret = pispbe_init_group(pispbe, num_groups);
+- if (ret)
+- goto disable_nodes_err;
+- }
++ ret = pispbe_init_devices(pispbe);
++ if (ret)
++ goto disable_devs_err;
+
+ pm_runtime_mark_last_busy(pispbe->dev);
+ pm_runtime_put_autosuspend(pispbe->dev);
+
+ return 0;
+
+-disable_nodes_err:
+- while (num_groups-- > 0)
+- pispbe_destroy_node_group(&pispbe->node_group[num_groups]);
+-pm_runtime_put_err:
+- pm_runtime_put(pispbe->dev);
++disable_devs_err:
++ pispbe_destroy_devices(pispbe);
++pm_runtime_suspend_err:
++ pispbe_runtime_suspend(pispbe->dev);
+ pm_runtime_disable_err:
+ pm_runtime_dont_use_autosuspend(pispbe->dev);
+ pm_runtime_disable(pispbe->dev);
+
+- dev_err(&pdev->dev, "%s: returning %d", __func__, ret);
+-
+ return ret;
+ }
+
+ static int pispbe_remove(struct platform_device *pdev)
+ {
+ struct pispbe_dev *pispbe = platform_get_drvdata(pdev);
+- int i;
+
+- for (i = PISPBE_NUM_NODE_GROUPS - 1; i >= 0; i--)
+- pispbe_destroy_node_group(&pispbe->node_group[i]);
++ pispbe_destroy_devices(pispbe);
+
++ pispbe_runtime_suspend(pispbe->dev);
+ pm_runtime_dont_use_autosuspend(pispbe->dev);
+ pm_runtime_disable(pispbe->dev);
+
+@@ -1991,3 +1794,8 @@ static struct platform_driver pispbe_pdr
+ };
+
+ module_platform_driver(pispbe_pdrv);
++
++MODULE_DESCRIPTION("PiSP Back End driver");
++MODULE_AUTHOR("David Plowman <david.plowman@raspberrypi.com>");
++MODULE_AUTHOR("Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>");
++MODULE_LICENSE("GPL");
+--- a/drivers/media/platform/raspberrypi/pisp_be/pisp_be_config.h
++++ /dev/null
+@@ -1,533 +0,0 @@
+-/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */
+-/*
+- * PiSP Back End configuration definitions.
+- *
+- * Copyright (C) 2021 - Raspberry Pi Ltd
+- *
+- */
+-#ifndef _PISP_BE_CONFIG_H_
+-#define _PISP_BE_CONFIG_H_
+-
+-#include <linux/types.h>
+-
+-#include <media/raspberrypi/pisp_common.h>
+-
+-/* byte alignment for inputs */
+-#define PISP_BACK_END_INPUT_ALIGN 4u
+-/* alignment for compressed inputs */
+-#define PISP_BACK_END_COMPRESSED_ALIGN 8u
+-/* minimum required byte alignment for outputs */
+-#define PISP_BACK_END_OUTPUT_MIN_ALIGN 16u
+-/* preferred byte alignment for outputs */
+-#define PISP_BACK_END_OUTPUT_MAX_ALIGN 64u
+-
+-/* minimum allowed tile width anywhere in the pipeline */
+-#define PISP_BACK_END_MIN_TILE_WIDTH 16u
+-/* minimum allowed tile width anywhere in the pipeline */
+-#define PISP_BACK_END_MIN_TILE_HEIGHT 16u
+-
+-#define PISP_BACK_END_NUM_OUTPUTS 2
+-#define PISP_BACK_END_HOG_OUTPUT 1
+-
+-#define PISP_BACK_END_NUM_TILES 64
+-
+-enum pisp_be_bayer_enable {
+- PISP_BE_BAYER_ENABLE_INPUT = 0x000001,
+- PISP_BE_BAYER_ENABLE_DECOMPRESS = 0x000002,
+- PISP_BE_BAYER_ENABLE_DPC = 0x000004,
+- PISP_BE_BAYER_ENABLE_GEQ = 0x000008,
+- PISP_BE_BAYER_ENABLE_TDN_INPUT = 0x000010,
+- PISP_BE_BAYER_ENABLE_TDN_DECOMPRESS = 0x000020,
+- PISP_BE_BAYER_ENABLE_TDN = 0x000040,
+- PISP_BE_BAYER_ENABLE_TDN_COMPRESS = 0x000080,
+- PISP_BE_BAYER_ENABLE_TDN_OUTPUT = 0x000100,
+- PISP_BE_BAYER_ENABLE_SDN = 0x000200,
+- PISP_BE_BAYER_ENABLE_BLC = 0x000400,
+- PISP_BE_BAYER_ENABLE_STITCH_INPUT = 0x000800,
+- PISP_BE_BAYER_ENABLE_STITCH_DECOMPRESS = 0x001000,
+- PISP_BE_BAYER_ENABLE_STITCH = 0x002000,
+- PISP_BE_BAYER_ENABLE_STITCH_COMPRESS = 0x004000,
+- PISP_BE_BAYER_ENABLE_STITCH_OUTPUT = 0x008000,
+- PISP_BE_BAYER_ENABLE_WBG = 0x010000,
+- PISP_BE_BAYER_ENABLE_CDN = 0x020000,
+- PISP_BE_BAYER_ENABLE_LSC = 0x040000,
+- PISP_BE_BAYER_ENABLE_TONEMAP = 0x080000,
+- PISP_BE_BAYER_ENABLE_CAC = 0x100000,
+- PISP_BE_BAYER_ENABLE_DEBIN = 0x200000,
+- PISP_BE_BAYER_ENABLE_DEMOSAIC = 0x400000,
+-};
+-
+-enum pisp_be_rgb_enable {
+- PISP_BE_RGB_ENABLE_INPUT = 0x000001,
+- PISP_BE_RGB_ENABLE_CCM = 0x000002,
+- PISP_BE_RGB_ENABLE_SAT_CONTROL = 0x000004,
+- PISP_BE_RGB_ENABLE_YCBCR = 0x000008,
+- PISP_BE_RGB_ENABLE_FALSE_COLOUR = 0x000010,
+- PISP_BE_RGB_ENABLE_SHARPEN = 0x000020,
+- /* Preferred colours would occupy 0x000040 */
+- PISP_BE_RGB_ENABLE_YCBCR_INVERSE = 0x000080,
+- PISP_BE_RGB_ENABLE_GAMMA = 0x000100,
+- PISP_BE_RGB_ENABLE_CSC0 = 0x000200,
+- PISP_BE_RGB_ENABLE_CSC1 = 0x000400,
+- PISP_BE_RGB_ENABLE_DOWNSCALE0 = 0x001000,
+- PISP_BE_RGB_ENABLE_DOWNSCALE1 = 0x002000,
+- PISP_BE_RGB_ENABLE_RESAMPLE0 = 0x008000,
+- PISP_BE_RGB_ENABLE_RESAMPLE1 = 0x010000,
+- PISP_BE_RGB_ENABLE_OUTPUT0 = 0x040000,
+- PISP_BE_RGB_ENABLE_OUTPUT1 = 0x080000,
+- PISP_BE_RGB_ENABLE_HOG = 0x200000
+-};
+-
+-#define PISP_BE_RGB_ENABLE_CSC(i) (PISP_BE_RGB_ENABLE_CSC0 << (i))
+-#define PISP_BE_RGB_ENABLE_DOWNSCALE(i) (PISP_BE_RGB_ENABLE_DOWNSCALE0 << (i))
+-#define PISP_BE_RGB_ENABLE_RESAMPLE(i) (PISP_BE_RGB_ENABLE_RESAMPLE0 << (i))
+-#define PISP_BE_RGB_ENABLE_OUTPUT(i) (PISP_BE_RGB_ENABLE_OUTPUT0 << (i))
+-
+-/*
+- * We use the enable flags to show when blocks are "dirty", but we need some
+- * extra ones too.
+- */
+-enum pisp_be_dirty {
+- PISP_BE_DIRTY_GLOBAL = 0x0001,
+- PISP_BE_DIRTY_SH_FC_COMBINE = 0x0002,
+- PISP_BE_DIRTY_CROP = 0x0004
+-};
+-
+-struct pisp_be_global_config {
+- u32 bayer_enables;
+- u32 rgb_enables;
+- u8 bayer_order;
+- u8 pad[3];
+-};
+-
+-struct pisp_be_input_buffer_config {
+- /* low 32 bits followed by high 32 bits (for each of up to 3 planes) */
+- u32 addr[3][2];
+-};
+-
+-struct pisp_be_dpc_config {
+- u8 coeff_level;
+- u8 coeff_range;
+- u8 pad;
+-#define PISP_BE_DPC_FLAG_FOLDBACK 1
+- u8 flags;
+-};
+-
+-struct pisp_be_geq_config {
+- u16 offset;
+-#define PISP_BE_GEQ_SHARPER BIT(15)
+-#define PISP_BE_GEQ_SLOPE ((1 << 10) - 1)
+- /* top bit is the "sharper" flag, slope value is bottom 10 bits */
+- u16 slope_sharper;
+- u16 min;
+- u16 max;
+-};
+-
+-struct pisp_be_tdn_input_buffer_config {
+- /* low 32 bits followed by high 32 bits */
+- u32 addr[2];
+-};
+-
+-struct pisp_be_tdn_config {
+- u16 black_level;
+- u16 ratio;
+- u16 noise_constant;
+- u16 noise_slope;
+- u16 threshold;
+- u8 reset;
+- u8 pad;
+-};
+-
+-struct pisp_be_tdn_output_buffer_config {
+- /* low 32 bits followed by high 32 bits */
+- u32 addr[2];
+-};
+-
+-struct pisp_be_sdn_config {
+- u16 black_level;
+- u8 leakage;
+- u8 pad;
+- u16 noise_constant;
+- u16 noise_slope;
+- u16 noise_constant2;
+- u16 noise_slope2;
+-};
+-
+-struct pisp_be_stitch_input_buffer_config {
+- /* low 32 bits followed by high 32 bits */
+- u32 addr[2];
+-};
+-
+-#define PISP_BE_STITCH_STREAMING_LONG 0x8000
+-#define PISP_BE_STITCH_EXPOSURE_RATIO_MASK 0x7fff
+-
+-struct pisp_be_stitch_config {
+- u16 threshold_lo;
+- u8 threshold_diff_power;
+- u8 pad;
+-
+- /* top bit indicates whether streaming input is the long exposure */
+- u16 exposure_ratio;
+-
+- u8 motion_threshold_256;
+- u8 motion_threshold_recip;
+-};
+-
+-struct pisp_be_stitch_output_buffer_config {
+- /* low 32 bits followed by high 32 bits */
+- u32 addr[2];
+-};
+-
+-struct pisp_be_cdn_config {
+- u16 thresh;
+- u8 iir_strength;
+- u8 g_adjust;
+-};
+-
+-#define PISP_BE_LSC_LOG_GRID_SIZE 5
+-#define PISP_BE_LSC_GRID_SIZE (1 << PISP_BE_LSC_LOG_GRID_SIZE)
+-#define PISP_BE_LSC_STEP_PRECISION 18
+-
+-struct pisp_be_lsc_config {
+- /* (1<<18) / grid_cell_width */
+- u16 grid_step_x;
+- /* (1<<18) / grid_cell_height */
+- u16 grid_step_y;
+- /* RGB gains jointly encoded in 32 bits */
+- u32 lut_packed[PISP_BE_LSC_GRID_SIZE + 1]
+- [PISP_BE_LSC_GRID_SIZE + 1];
+-};
+-
+-struct pisp_be_lsc_extra {
+- u16 offset_x;
+- u16 offset_y;
+-};
+-
+-#define PISP_BE_CAC_LOG_GRID_SIZE 3
+-#define PISP_BE_CAC_GRID_SIZE (1 << PISP_BE_CAC_LOG_GRID_SIZE)
+-#define PISP_BE_CAC_STEP_PRECISION 20
+-
+-struct pisp_be_cac_config {
+- /* (1<<20) / grid_cell_width */
+- u16 grid_step_x;
+- /* (1<<20) / grid_cell_height */
+- u16 grid_step_y;
+- /* [gridy][gridx][rb][xy] */
+- s8 lut[PISP_BE_CAC_GRID_SIZE + 1][PISP_BE_CAC_GRID_SIZE + 1][2][2];
+-};
+-
+-struct pisp_be_cac_extra {
+- u16 offset_x;
+- u16 offset_y;
+-};
+-
+-#define PISP_BE_DEBIN_NUM_COEFFS 4
+-
+-struct pisp_be_debin_config {
+- s8 coeffs[PISP_BE_DEBIN_NUM_COEFFS];
+- s8 h_enable;
+- s8 v_enable;
+- s8 pad[2];
+-};
+-
+-#define PISP_BE_TONEMAP_LUT_SIZE 64
+-
+-struct pisp_be_tonemap_config {
+- u16 detail_constant;
+- u16 detail_slope;
+- u16 iir_strength;
+- u16 strength;
+- u32 lut[PISP_BE_TONEMAP_LUT_SIZE];
+-};
+-
+-struct pisp_be_demosaic_config {
+- u8 sharper;
+- u8 fc_mode;
+- u8 pad[2];
+-};
+-
+-struct pisp_be_ccm_config {
+- s16 coeffs[9];
+- u8 pad[2];
+- s32 offsets[3];
+-};
+-
+-struct pisp_be_sat_control_config {
+- u8 shift_r;
+- u8 shift_g;
+- u8 shift_b;
+- u8 pad;
+-};
+-
+-struct pisp_be_false_colour_config {
+- u8 distance;
+- u8 pad[3];
+-};
+-
+-#define PISP_BE_SHARPEN_SIZE 5
+-#define PISP_BE_SHARPEN_FUNC_NUM_POINTS 9
+-
+-struct pisp_be_sharpen_config {
+- s8 kernel0[PISP_BE_SHARPEN_SIZE * PISP_BE_SHARPEN_SIZE];
+- s8 pad0[3];
+- s8 kernel1[PISP_BE_SHARPEN_SIZE * PISP_BE_SHARPEN_SIZE];
+- s8 pad1[3];
+- s8 kernel2[PISP_BE_SHARPEN_SIZE * PISP_BE_SHARPEN_SIZE];
+- s8 pad2[3];
+- s8 kernel3[PISP_BE_SHARPEN_SIZE * PISP_BE_SHARPEN_SIZE];
+- s8 pad3[3];
+- s8 kernel4[PISP_BE_SHARPEN_SIZE * PISP_BE_SHARPEN_SIZE];
+- s8 pad4[3];
+- u16 threshold_offset0;
+- u16 threshold_slope0;
+- u16 scale0;
+- u16 pad5;
+- u16 threshold_offset1;
+- u16 threshold_slope1;
+- u16 scale1;
+- u16 pad6;
+- u16 threshold_offset2;
+- u16 threshold_slope2;
+- u16 scale2;
+- u16 pad7;
+- u16 threshold_offset3;
+- u16 threshold_slope3;
+- u16 scale3;
+- u16 pad8;
+- u16 threshold_offset4;
+- u16 threshold_slope4;
+- u16 scale4;
+- u16 pad9;
+- u16 positive_strength;
+- u16 positive_pre_limit;
+- u16 positive_func[PISP_BE_SHARPEN_FUNC_NUM_POINTS];
+- u16 positive_limit;
+- u16 negative_strength;
+- u16 negative_pre_limit;
+- u16 negative_func[PISP_BE_SHARPEN_FUNC_NUM_POINTS];
+- u16 negative_limit;
+- u8 enables;
+- u8 white;
+- u8 black;
+- u8 grey;
+-};
+-
+-struct pisp_be_sh_fc_combine_config {
+- u8 y_factor;
+- u8 c1_factor;
+- u8 c2_factor;
+- u8 pad;
+-};
+-
+-#define PISP_BE_GAMMA_LUT_SIZE 64
+-
+-struct pisp_be_gamma_config {
+- u32 lut[PISP_BE_GAMMA_LUT_SIZE];
+-};
+-
+-struct pisp_be_crop_config {
+- u16 offset_x, offset_y;
+- u16 width, height;
+-};
+-
+-#define PISP_BE_RESAMPLE_FILTER_SIZE 96
+-
+-struct pisp_be_resample_config {
+- u16 scale_factor_h, scale_factor_v;
+- s16 coef[PISP_BE_RESAMPLE_FILTER_SIZE];
+-};
+-
+-struct pisp_be_resample_extra {
+- u16 scaled_width;
+- u16 scaled_height;
+- s16 initial_phase_h[3];
+- s16 initial_phase_v[3];
+-};
+-
+-struct pisp_be_downscale_config {
+- u16 scale_factor_h;
+- u16 scale_factor_v;
+- u16 scale_recip_h;
+- u16 scale_recip_v;
+-};
+-
+-struct pisp_be_downscale_extra {
+- u16 scaled_width;
+- u16 scaled_height;
+-};
+-
+-struct pisp_be_hog_config {
+- u8 compute_signed;
+- u8 channel_mix[3];
+- u32 stride;
+-};
+-
+-struct pisp_be_axi_config {
+- u8 r_qos; /* Read QoS */
+- u8 r_cache_prot; /* Read { prot[2:0], cache[3:0] } */
+- u8 w_qos; /* Write QoS */
+- u8 w_cache_prot; /* Write { prot[2:0], cache[3:0] } */
+-};
+-
+-enum pisp_be_transform {
+- PISP_BE_TRANSFORM_NONE = 0x0,
+- PISP_BE_TRANSFORM_HFLIP = 0x1,
+- PISP_BE_TRANSFORM_VFLIP = 0x2,
+- PISP_BE_TRANSFORM_ROT180 =
+- (PISP_BE_TRANSFORM_HFLIP | PISP_BE_TRANSFORM_VFLIP)
+-};
+-
+-struct pisp_be_output_format_config {
+- struct pisp_image_format_config image;
+- u8 transform;
+- u8 pad[3];
+- u16 lo;
+- u16 hi;
+- u16 lo2;
+- u16 hi2;
+-};
+-
+-struct pisp_be_output_buffer_config {
+- /* low 32 bits followed by high 32 bits (for each of 3 planes) */
+- u32 addr[3][2];
+-};
+-
+-struct pisp_be_hog_buffer_config {
+- /* low 32 bits followed by high 32 bits */
+- u32 addr[2];
+-};
+-
+-struct pisp_be_config {
+- /* I/O configuration: */
+- struct pisp_be_input_buffer_config input_buffer;
+- struct pisp_be_tdn_input_buffer_config tdn_input_buffer;
+- struct pisp_be_stitch_input_buffer_config stitch_input_buffer;
+- struct pisp_be_tdn_output_buffer_config tdn_output_buffer;
+- struct pisp_be_stitch_output_buffer_config stitch_output_buffer;
+- struct pisp_be_output_buffer_config
+- output_buffer[PISP_BACK_END_NUM_OUTPUTS];
+- struct pisp_be_hog_buffer_config hog_buffer;
+- /* Processing configuration: */
+- struct pisp_be_global_config global;
+- struct pisp_image_format_config input_format;
+- struct pisp_decompress_config decompress;
+- struct pisp_be_dpc_config dpc;
+- struct pisp_be_geq_config geq;
+- struct pisp_image_format_config tdn_input_format;
+- struct pisp_decompress_config tdn_decompress;
+- struct pisp_be_tdn_config tdn;
+- struct pisp_compress_config tdn_compress;
+- struct pisp_image_format_config tdn_output_format;
+- struct pisp_be_sdn_config sdn;
+- struct pisp_bla_config blc;
+- struct pisp_compress_config stitch_compress;
+- struct pisp_image_format_config stitch_output_format;
+- struct pisp_image_format_config stitch_input_format;
+- struct pisp_decompress_config stitch_decompress;
+- struct pisp_be_stitch_config stitch;
+- struct pisp_be_lsc_config lsc;
+- struct pisp_wbg_config wbg;
+- struct pisp_be_cdn_config cdn;
+- struct pisp_be_cac_config cac;
+- struct pisp_be_debin_config debin;
+- struct pisp_be_tonemap_config tonemap;
+- struct pisp_be_demosaic_config demosaic;
+- struct pisp_be_ccm_config ccm;
+- struct pisp_be_sat_control_config sat_control;
+- struct pisp_be_ccm_config ycbcr;
+- struct pisp_be_sharpen_config sharpen;
+- struct pisp_be_false_colour_config false_colour;
+- struct pisp_be_sh_fc_combine_config sh_fc_combine;
+- struct pisp_be_ccm_config ycbcr_inverse;
+- struct pisp_be_gamma_config gamma;
+- struct pisp_be_ccm_config csc[PISP_BACK_END_NUM_OUTPUTS];
+- struct pisp_be_downscale_config downscale[PISP_BACK_END_NUM_OUTPUTS];
+- struct pisp_be_resample_config resample[PISP_BACK_END_NUM_OUTPUTS];
+- struct pisp_be_output_format_config
+- output_format[PISP_BACK_END_NUM_OUTPUTS];
+- struct pisp_be_hog_config hog;
+- struct pisp_be_axi_config axi;
+- /* Non-register fields: */
+- struct pisp_be_lsc_extra lsc_extra;
+- struct pisp_be_cac_extra cac_extra;
+- struct pisp_be_downscale_extra
+- downscale_extra[PISP_BACK_END_NUM_OUTPUTS];
+- struct pisp_be_resample_extra resample_extra[PISP_BACK_END_NUM_OUTPUTS];
+- struct pisp_be_crop_config crop;
+- struct pisp_image_format_config hog_format;
+- u32 dirty_flags_bayer; /* these use pisp_be_bayer_enable */
+- u32 dirty_flags_rgb; /* use pisp_be_rgb_enable */
+- u32 dirty_flags_extra; /* these use pisp_be_dirty_t */
+-};
+-
+-/*
+- * We also need a tile structure to describe the size of the tiles going
+- * through the pipeline.
+- */
+-
+-enum pisp_tile_edge {
+- PISP_LEFT_EDGE = (1 << 0),
+- PISP_RIGHT_EDGE = (1 << 1),
+- PISP_TOP_EDGE = (1 << 2),
+- PISP_BOTTOM_EDGE = (1 << 3)
+-};
+-
+-struct pisp_tile {
+- u8 edge; // enum pisp_tile_edge
+- u8 pad0[3];
+- // 4 bytes
+- u32 input_addr_offset;
+- u32 input_addr_offset2;
+- u16 input_offset_x;
+- u16 input_offset_y;
+- u16 input_width;
+- u16 input_height;
+- // 20 bytes
+- u32 tdn_input_addr_offset;
+- u32 tdn_output_addr_offset;
+- u32 stitch_input_addr_offset;
+- u32 stitch_output_addr_offset;
+- // 36 bytes
+- u32 lsc_grid_offset_x;
+- u32 lsc_grid_offset_y;
+- // 44 bytes
+- u32 cac_grid_offset_x;
+- u32 cac_grid_offset_y;
+- // 52 bytes
+- u16 crop_x_start[PISP_BACK_END_NUM_OUTPUTS];
+- u16 crop_x_end[PISP_BACK_END_NUM_OUTPUTS];
+- u16 crop_y_start[PISP_BACK_END_NUM_OUTPUTS];
+- u16 crop_y_end[PISP_BACK_END_NUM_OUTPUTS];
+- // 68 bytes
+- /* Ordering is planes then branches */
+- u16 downscale_phase_x[3 * PISP_BACK_END_NUM_OUTPUTS];
+- u16 downscale_phase_y[3 * PISP_BACK_END_NUM_OUTPUTS];
+- // 92 bytes
+- u16 resample_in_width[PISP_BACK_END_NUM_OUTPUTS];
+- u16 resample_in_height[PISP_BACK_END_NUM_OUTPUTS];
+- // 100 bytes
+- /* Ordering is planes then branches */
+- u16 resample_phase_x[3 * PISP_BACK_END_NUM_OUTPUTS];
+- u16 resample_phase_y[3 * PISP_BACK_END_NUM_OUTPUTS];
+- // 124 bytes
+- u16 output_offset_x[PISP_BACK_END_NUM_OUTPUTS];
+- u16 output_offset_y[PISP_BACK_END_NUM_OUTPUTS];
+- u16 output_width[PISP_BACK_END_NUM_OUTPUTS];
+- u16 output_height[PISP_BACK_END_NUM_OUTPUTS];
+- // 140 bytes
+- u32 output_addr_offset[PISP_BACK_END_NUM_OUTPUTS];
+- u32 output_addr_offset2[PISP_BACK_END_NUM_OUTPUTS];
+- // 156 bytes
+- u32 output_hog_addr_offset;
+- // 160 bytes
+-};
+-
+-static_assert(sizeof(struct pisp_tile) == 160);
+-
+-struct pisp_be_tiles_config {
+- struct pisp_be_config config;
+- struct pisp_tile tiles[PISP_BACK_END_NUM_TILES];
+- int num_tiles;
+-};
+-
+-#endif /* _PISP_BE_CONFIG_H_ */
+--- a/drivers/media/platform/raspberrypi/pisp_be/pisp_be_formats.h
++++ b/drivers/media/platform/raspberrypi/pisp_be/pisp_be_formats.h
+@@ -2,7 +2,7 @@
+ /*
+ * PiSP Back End driver image format definitions.
+ *
+- * Copyright (c) 2021 Raspberry Pi Ltd
++ * Copyright (c) 2021-2024 Raspberry Pi Ltd
+ */
+
+ #ifndef _PISP_BE_FORMATS_
+@@ -11,15 +11,15 @@
+ #include <linux/bits.h>
+ #include <linux/videodev2.h>
+
+-#define MAX_PLANES 3
+-#define P3(x) ((x) * 8)
++#define PISPBE_MAX_PLANES 3
++#define P3(x) ((x) * 8)
+
+ struct pisp_be_format {
+ unsigned int fourcc;
+ unsigned int align;
+ unsigned int bit_depth;
+ /* 0P3 factor for plane sizing */
+- unsigned int plane_factor[MAX_PLANES];
++ unsigned int plane_factor[PISPBE_MAX_PLANES];
+ unsigned int num_planes;
+ unsigned int colorspace_mask;
+ enum v4l2_colorspace colorspace_default;
+@@ -27,14 +27,19 @@ struct pisp_be_format {
+
+ #define V4L2_COLORSPACE_MASK(colorspace) BIT(colorspace)
+
+-#define V4L2_COLORSPACE_MASK_JPEG V4L2_COLORSPACE_MASK(V4L2_COLORSPACE_JPEG)
+-#define V4L2_COLORSPACE_MASK_SMPTE170M V4L2_COLORSPACE_MASK(V4L2_COLORSPACE_SMPTE170M)
+-#define V4L2_COLORSPACE_MASK_REC709 V4L2_COLORSPACE_MASK(V4L2_COLORSPACE_REC709)
+-#define V4L2_COLORSPACE_MASK_SRGB V4L2_COLORSPACE_MASK(V4L2_COLORSPACE_SRGB)
+-#define V4L2_COLORSPACE_MASK_RAW V4L2_COLORSPACE_MASK(V4L2_COLORSPACE_RAW)
++#define V4L2_COLORSPACE_MASK_JPEG \
++ V4L2_COLORSPACE_MASK(V4L2_COLORSPACE_JPEG)
++#define V4L2_COLORSPACE_MASK_SMPTE170M \
++ V4L2_COLORSPACE_MASK(V4L2_COLORSPACE_SMPTE170M)
++#define V4L2_COLORSPACE_MASK_REC709 \
++ V4L2_COLORSPACE_MASK(V4L2_COLORSPACE_REC709)
++#define V4L2_COLORSPACE_MASK_SRGB \
++ V4L2_COLORSPACE_MASK(V4L2_COLORSPACE_SRGB)
++#define V4L2_COLORSPACE_MASK_RAW \
++ V4L2_COLORSPACE_MASK(V4L2_COLORSPACE_RAW)
+
+ /*
+- * All three colour spaces JPEG, SMPTE170M and REC709 are fundamentally sRGB
++ * All three colour spaces SRGB, SMPTE170M and REC709 are fundamentally sRGB
+ * underneath (as near as makes no difference to us), just with different YCbCr
+ * encodings. Therefore the ISP can generate sRGB on its main output and any of
+ * the others on its low resolution output. Applications should, when using both
+@@ -43,9 +48,9 @@ struct pisp_be_format {
+ * producing an RGB format. In turn this requires us to allow all these colour
+ * spaces for every YUV/RGB output format.
+ */
+-#define V4L2_COLORSPACE_MASK_ALL_SRGB (V4L2_COLORSPACE_MASK_JPEG | \
+- V4L2_COLORSPACE_MASK_SRGB | \
+- V4L2_COLORSPACE_MASK_SMPTE170M | \
++#define V4L2_COLORSPACE_MASK_ALL_SRGB (V4L2_COLORSPACE_MASK_JPEG | \
++ V4L2_COLORSPACE_MASK_SRGB | \
++ V4L2_COLORSPACE_MASK_SMPTE170M | \
+ V4L2_COLORSPACE_MASK_REC709)
+
+ static const struct pisp_be_format supported_formats[] = {
+@@ -58,7 +63,7 @@ static const struct pisp_be_format suppo
+ .plane_factor = { P3(1), P3(0.25), P3(0.25) },
+ .num_planes = 1,
+ .colorspace_mask = V4L2_COLORSPACE_MASK_ALL_SRGB,
+- .colorspace_default = V4L2_COLORSPACE_JPEG,
++ .colorspace_default = V4L2_COLORSPACE_SMPTE170M,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_YVU420,
+@@ -132,7 +137,7 @@ static const struct pisp_be_format suppo
+ .plane_factor = { P3(1), P3(0.25), P3(0.25) },
+ .num_planes = 3,
+ .colorspace_mask = V4L2_COLORSPACE_MASK_ALL_SRGB,
+- .colorspace_default = V4L2_COLORSPACE_JPEG,
++ .colorspace_default = V4L2_COLORSPACE_SMPTE170M,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_NV12M,
+@@ -168,7 +173,7 @@ static const struct pisp_be_format suppo
+ .plane_factor = { P3(1), P3(0.5), P3(0.5) },
+ .num_planes = 3,
+ .colorspace_mask = V4L2_COLORSPACE_MASK_ALL_SRGB,
+- .colorspace_default = V4L2_COLORSPACE_JPEG,
++ .colorspace_default = V4L2_COLORSPACE_SMPTE170M,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_YVU422M,
+@@ -186,7 +191,7 @@ static const struct pisp_be_format suppo
+ .plane_factor = { P3(1), P3(1), P3(1) },
+ .num_planes = 3,
+ .colorspace_mask = V4L2_COLORSPACE_MASK_ALL_SRGB,
+- .colorspace_default = V4L2_COLORSPACE_JPEG,
++ .colorspace_default = V4L2_COLORSPACE_SMPTE170M,
+ },
+ {
+ .fourcc = V4L2_PIX_FMT_YVU444M,
+@@ -502,11 +507,6 @@ static const struct pisp_be_format suppo
+ .colorspace_mask = V4L2_COLORSPACE_MASK_RAW,
+ .colorspace_default = V4L2_COLORSPACE_RAW,
+ },
+- /* Opaque BE format for HW verification. */
+- {
+- .fourcc = V4L2_PIX_FMT_RPI_BE,
+- .align = 32,
+- },
+ };
+
+ static const struct pisp_be_format meta_out_supported_formats[] = {
diff --git a/target/linux/bcm27xx/patches-6.6/950-1155-media-uapi-pisp_be_config-Drop-BIT-from-uAPI.patch b/target/linux/bcm27xx/patches-6.6/950-1155-media-uapi-pisp_be_config-Drop-BIT-from-uAPI.patch
new file mode 100644
index 0000000000..f59c02c5b1
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1155-media-uapi-pisp_be_config-Drop-BIT-from-uAPI.patch
@@ -0,0 +1,29 @@
+From b58aeea7e2e3afd4fb3b6dcbe5e382b2244b33a4 Mon Sep 17 00:00:00 2001
+From: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+Date: Thu, 27 Jun 2024 13:40:29 +0200
+Subject: [PATCH 1155/1215] media: uapi: pisp_be_config: Drop BIT() from uAPI
+
+The pisp_be_config.h uAPI header file contains a bit-field definition
+that uses the BIT() helper macro.
+
+As the BIT() identifier is not defined in userspace, drop it from the
+uAPI header.
+
+Fixes: c6c49bac8770 ("media: uapi: Add Raspberry Pi PiSP Back End uAPI")
+Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
+---
+ include/uapi/linux/media/raspberrypi/pisp_be_config.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/include/uapi/linux/media/raspberrypi/pisp_be_config.h
++++ b/include/uapi/linux/media/raspberrypi/pisp_be_config.h
+@@ -146,7 +146,7 @@ struct pisp_be_dpc_config {
+ */
+ struct pisp_be_geq_config {
+ __u16 offset;
+-#define PISP_BE_GEQ_SHARPER BIT(15)
++#define PISP_BE_GEQ_SHARPER (1U << 15)
+ #define PISP_BE_GEQ_SLOPE ((1 << 10) - 1)
+ /* top bit is the "sharper" flag, slope value is bottom 10 bits */
+ __u16 slope_sharper;
diff --git a/target/linux/bcm27xx/patches-6.6/950-1156-media-uapi-pisp_common-Add-32-bpp-format-test.patch b/target/linux/bcm27xx/patches-6.6/950-1156-media-uapi-pisp_common-Add-32-bpp-format-test.patch
new file mode 100644
index 0000000000..0cb94fe933
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1156-media-uapi-pisp_common-Add-32-bpp-format-test.patch
@@ -0,0 +1,32 @@
+From 7c36a1feb61d964055bee777efc1db60790aa215 Mon Sep 17 00:00:00 2001
+From: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+Date: Thu, 27 Jun 2024 16:07:43 +0200
+Subject: [PATCH 1156/1215] media: uapi: pisp_common: Add 32 bpp format test
+
+Add definition and test for 32-bits image formats to the pisp_common.h
+uAPI header.
+
+Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+---
+ include/uapi/linux/media/raspberrypi/pisp_common.h | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/include/uapi/linux/media/raspberrypi/pisp_common.h
++++ b/include/uapi/linux/media/raspberrypi/pisp_common.h
+@@ -72,6 +72,8 @@ enum pisp_image_format {
+ PISP_IMAGE_FORMAT_SHIFT_8 = 0x00080000,
+ PISP_IMAGE_FORMAT_SHIFT_MASK = 0x000f0000,
+
++ PISP_IMAGE_FORMAT_BPP_32 = 0x00100000,
++
+ PISP_IMAGE_FORMAT_UNCOMPRESSED = 0x00000000,
+ PISP_IMAGE_FORMAT_COMPRESSION_MODE_1 = 0x01000000,
+ PISP_IMAGE_FORMAT_COMPRESSION_MODE_2 = 0x02000000,
+@@ -134,6 +136,7 @@ enum pisp_image_format {
+ PISP_IMAGE_FORMAT_PLANARITY_PLANAR)
+ #define PISP_IMAGE_FORMAT_wallpaper(fmt) \
+ ((fmt) & PISP_IMAGE_FORMAT_WALLPAPER_ROLL)
++#define PISP_IMAGE_FORMAT_bpp_32(fmt) ((fmt) & PISP_IMAGE_FORMAT_BPP_32)
+ #define PISP_IMAGE_FORMAT_HOG(fmt) \
+ ((fmt) & \
+ (PISP_IMAGE_FORMAT_HOG_SIGNED | PISP_IMAGE_FORMAT_HOG_UNSIGNED))
diff --git a/target/linux/bcm27xx/patches-6.6/950-1157-media-uapi-Capitalize-all-macros.patch b/target/linux/bcm27xx/patches-6.6/950-1157-media-uapi-Capitalize-all-macros.patch
new file mode 100644
index 0000000000..fac2ccf163
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1157-media-uapi-Capitalize-all-macros.patch
@@ -0,0 +1,89 @@
+From 20a3671be178fd98aac08931d809e689eaa7a9d9 Mon Sep 17 00:00:00 2001
+From: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+Date: Fri, 28 Jun 2024 10:10:10 +0200
+Subject: [PATCH 1157/1215] media: uapi: Capitalize all macros
+
+The macro used to inspect an image format characteristic use a mixture
+of capitalized and non-capitalized letters, which is rather unusual for
+the Linux kernel style.
+
+Capitalize all identifiers.
+
+Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+---
+ .../linux/media/raspberrypi/pisp_common.h | 38 +++++++++----------
+ 1 file changed, 19 insertions(+), 19 deletions(-)
+
+--- a/include/uapi/linux/media/raspberrypi/pisp_common.h
++++ b/include/uapi/linux/media/raspberrypi/pisp_common.h
+@@ -92,51 +92,51 @@ enum pisp_image_format {
+ PISP_IMAGE_FORMAT_THREE_CHANNEL
+ };
+
+-#define PISP_IMAGE_FORMAT_bps_8(fmt) \
++#define PISP_IMAGE_FORMAT_BPS_8(fmt) \
+ (((fmt) & PISP_IMAGE_FORMAT_BPS_MASK) == PISP_IMAGE_FORMAT_BPS_8)
+-#define PISP_IMAGE_FORMAT_bps_10(fmt) \
++#define PISP_IMAGE_FORMAT_BPS_10(fmt) \
+ (((fmt) & PISP_IMAGE_FORMAT_BPS_MASK) == PISP_IMAGE_FORMAT_BPS_10)
+-#define PISP_IMAGE_FORMAT_bps_12(fmt) \
++#define PISP_IMAGE_FORMAT_BPS_12(fmt) \
+ (((fmt) & PISP_IMAGE_FORMAT_BPS_MASK) == PISP_IMAGE_FORMAT_BPS_12)
+-#define PISP_IMAGE_FORMAT_bps_16(fmt) \
++#define PISP_IMAGE_FORMAT_BPS_16(fmt) \
+ (((fmt) & PISP_IMAGE_FORMAT_BPS_MASK) == PISP_IMAGE_FORMAT_BPS_16)
+-#define PISP_IMAGE_FORMAT_bps(fmt) \
++#define PISP_IMAGE_FORMAT_BPS(fmt) \
+ (((fmt) & PISP_IMAGE_FORMAT_BPS_MASK) ? \
+ 8 + (2 << (((fmt) & PISP_IMAGE_FORMAT_BPS_MASK) - 1)) : 8)
+-#define PISP_IMAGE_FORMAT_shift(fmt) \
++#define PISP_IMAGE_FORMAT_SHIFT(fmt) \
+ (((fmt) & PISP_IMAGE_FORMAT_SHIFT_MASK) / PISP_IMAGE_FORMAT_SHIFT_1)
+-#define PISP_IMAGE_FORMAT_three_channel(fmt) \
++#define PISP_IMAGE_FORMAT_THREE_CHANNEL(fmt) \
+ ((fmt) & PISP_IMAGE_FORMAT_THREE_CHANNEL)
+-#define PISP_IMAGE_FORMAT_single_channel(fmt) \
++#define PISP_IMAGE_FORMAT_SINGLE_CHANNEL(fmt) \
+ (!((fmt) & PISP_IMAGE_FORMAT_THREE_CHANNEL))
+-#define PISP_IMAGE_FORMAT_compressed(fmt) \
++#define PISP_IMAGE_FORMAT_COMPRESSED(fmt) \
+ (((fmt) & PISP_IMAGE_FORMAT_COMPRESSION_MASK) != \
+ PISP_IMAGE_FORMAT_UNCOMPRESSED)
+-#define PISP_IMAGE_FORMAT_sampling_444(fmt) \
++#define PISP_IMAGE_FORMAT_SAMPLING_444(fmt) \
+ (((fmt) & PISP_IMAGE_FORMAT_SAMPLING_MASK) == \
+ PISP_IMAGE_FORMAT_SAMPLING_444)
+-#define PISP_IMAGE_FORMAT_sampling_422(fmt) \
++#define PISP_IMAGE_FORMAT_SAMPLING_422(fmt) \
+ (((fmt) & PISP_IMAGE_FORMAT_SAMPLING_MASK) == \
+ PISP_IMAGE_FORMAT_SAMPLING_422)
+-#define PISP_IMAGE_FORMAT_sampling_420(fmt) \
++#define PISP_IMAGE_FORMAT_SAMPLING_420(fmt) \
+ (((fmt) & PISP_IMAGE_FORMAT_SAMPLING_MASK) == \
+ PISP_IMAGE_FORMAT_SAMPLING_420)
+-#define PISP_IMAGE_FORMAT_order_normal(fmt) \
++#define PISP_IMAGE_FORMAT_ORDER_NORMAL(fmt) \
+ (!((fmt) & PISP_IMAGE_FORMAT_ORDER_SWAPPED))
+-#define PISP_IMAGE_FORMAT_order_swapped(fmt) \
++#define PISP_IMAGE_FORMAT_ORDER_SWAPPED(fmt) \
+ ((fmt) & PISP_IMAGE_FORMAT_ORDER_SWAPPED)
+-#define PISP_IMAGE_FORMAT_interleaved(fmt) \
++#define PISP_IMAGE_FORMAT_INTERLEAVED(fmt) \
+ (((fmt) & PISP_IMAGE_FORMAT_PLANARITY_MASK) == \
+ PISP_IMAGE_FORMAT_PLANARITY_INTERLEAVED)
+-#define PISP_IMAGE_FORMAT_semiplanar(fmt) \
++#define PISP_IMAGE_FORMAT_SEMIPLANAR(fmt) \
+ (((fmt) & PISP_IMAGE_FORMAT_PLANARITY_MASK) == \
+ PISP_IMAGE_FORMAT_PLANARITY_SEMI_PLANAR)
+-#define PISP_IMAGE_FORMAT_planar(fmt) \
++#define PISP_IMAGE_FORMAT_PLANAR(fmt) \
+ (((fmt) & PISP_IMAGE_FORMAT_PLANARITY_MASK) == \
+ PISP_IMAGE_FORMAT_PLANARITY_PLANAR)
+-#define PISP_IMAGE_FORMAT_wallpaper(fmt) \
++#define PISP_IMAGE_FORMAT_WALLPAPER(fmt) \
+ ((fmt) & PISP_IMAGE_FORMAT_WALLPAPER_ROLL)
+-#define PISP_IMAGE_FORMAT_bpp_32(fmt) ((fmt) & PISP_IMAGE_FORMAT_BPP_32)
++#define PISP_IMAGE_FORMAT_BPP_32(fmt) ((fmt) & PISP_IMAGE_FORMAT_BPP_32)
+ #define PISP_IMAGE_FORMAT_HOG(fmt) \
+ ((fmt) & \
+ (PISP_IMAGE_FORMAT_HOG_SIGNED | PISP_IMAGE_FORMAT_HOG_UNSIGNED))
diff --git a/target/linux/bcm27xx/patches-6.6/950-1158-media-uapi-pisp_be_config-Re-sort-pisp_be_tiles_conf.patch b/target/linux/bcm27xx/patches-6.6/950-1158-media-uapi-pisp_be_config-Re-sort-pisp_be_tiles_conf.patch
new file mode 100644
index 0000000000..49ff9d73ff
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1158-media-uapi-pisp_be_config-Re-sort-pisp_be_tiles_conf.patch
@@ -0,0 +1,30 @@
+From ce89955e44f3ab41262b02d8e1e65c3455d66c4d Mon Sep 17 00:00:00 2001
+From: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+Date: Fri, 28 Jun 2024 13:59:40 +0200
+Subject: [PATCH 1158/1215] media: uapi: pisp_be_config: Re-sort
+ pisp_be_tiles_config
+
+The order of the members of pisp_be_tiles_config is relevant
+as the driver logic assumes 'config' to be at offset 0.
+
+Re-sort the member to match the driver's expectations.
+
+Fixes: c6c49bac8770 ("media: uapi: Add Raspberry Pi PiSP Back End uAPI")
+Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+---
+ include/uapi/linux/media/raspberrypi/pisp_be_config.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/include/uapi/linux/media/raspberrypi/pisp_be_config.h
++++ b/include/uapi/linux/media/raspberrypi/pisp_be_config.h
+@@ -919,9 +919,9 @@ struct pisp_tile {
+ * @config: PiSP Back End configuration
+ */
+ struct pisp_be_tiles_config {
++ struct pisp_be_config config;
+ struct pisp_tile tiles[PISP_BACK_END_NUM_TILES];
+ __u32 num_tiles;
+- struct pisp_be_config config;
+ } __attribute__((packed));
+
+ #endif /* _UAPI_PISP_BE_CONFIG_H_ */
diff --git a/target/linux/bcm27xx/patches-6.6/950-1159-media-uapi-pisp_be_config-Add-extra-config-fields.patch b/target/linux/bcm27xx/patches-6.6/950-1159-media-uapi-pisp_be_config-Add-extra-config-fields.patch
new file mode 100644
index 0000000000..d18d12ec67
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1159-media-uapi-pisp_be_config-Add-extra-config-fields.patch
@@ -0,0 +1,82 @@
+From abf30420f943d03cc28fec38612d2c5f5e6edf1f Mon Sep 17 00:00:00 2001
+From: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+Date: Fri, 28 Jun 2024 14:11:14 +0200
+Subject: [PATCH 1159/1215] media: uapi: pisp_be_config: Add extra config
+ fields
+
+Complete the pisp_be_config strcture by adding fields that even if not
+written to the HW are relevant to complete the uAPI and put it in par
+with the BSP driver.
+
+Fixes: c6c49bac8770 ("media: uapi: Add Raspberry Pi PiSP Back End uAPI")
+Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+---
+ .../linux/media/raspberrypi/pisp_be_config.h | 41 +++++++++++++++++++
+ 1 file changed, 41 insertions(+)
+
+--- a/include/uapi/linux/media/raspberrypi/pisp_be_config.h
++++ b/include/uapi/linux/media/raspberrypi/pisp_be_config.h
+@@ -716,6 +716,13 @@ struct pisp_be_hog_buffer_config {
+ /**
+ * struct pisp_be_config - RaspberryPi PiSP Back End Processing configuration
+ *
++ * @input_buffer: Input buffer addresses
++ * @tdn_input_buffer: TDN input buffer addresses
++ * @stitch_input_buffer: Stitch input buffer addresses
++ * @tdn_output_buffer: TDN output buffer addresses
++ * @stitch_output_buffer: Stitch output buffer addresses
++ * @output_buffer: Output buffers addresses
++ * @hog_buffer: HOG buffer addresses
+ * @global: Global PiSP configuration
+ * @input_format: Input image format
+ * @decompress: Decompress configuration
+@@ -753,8 +760,30 @@ struct pisp_be_hog_buffer_config {
+ * @resample: Resampling configuration
+ * @output_format: Output format configuration
+ * @hog: HOG configuration
++ * @axi: AXI bus configuration
++ * @lsc_extra: LSC extra info
++ * @cac_extra: CAC extra info
++ * @downscale_extra: Downscaler extra info
++ * @resample_extra: Resample extra info
++ * @crop: Crop configuration
++ * @hog_format: HOG format info
++ * @dirty_flags_bayer: Bayer enable dirty flags
++ * (:c:type:`pisp_be_bayer_enable`)
++ * @dirty_flags_rgb: RGB enable dirty flags
++ * (:c:type:`pisp_be_rgb_enable`)
++ * @dirty_flags_extra: Extra dirty flags
+ */
+ struct pisp_be_config {
++ /* I/O configuration: */
++ struct pisp_be_input_buffer_config input_buffer;
++ struct pisp_be_tdn_input_buffer_config tdn_input_buffer;
++ struct pisp_be_stitch_input_buffer_config stitch_input_buffer;
++ struct pisp_be_tdn_output_buffer_config tdn_output_buffer;
++ struct pisp_be_stitch_output_buffer_config stitch_output_buffer;
++ struct pisp_be_output_buffer_config
++ output_buffer[PISP_BACK_END_NUM_OUTPUTS];
++ struct pisp_be_hog_buffer_config hog_buffer;
++ /* Processing configuration: */
+ struct pisp_be_global_config global;
+ struct pisp_image_format_config input_format;
+ struct pisp_decompress_config decompress;
+@@ -793,6 +822,18 @@ struct pisp_be_config {
+ struct pisp_be_output_format_config
+ output_format[PISP_BACK_END_NUM_OUTPUTS];
+ struct pisp_be_hog_config hog;
++ struct pisp_be_axi_config axi;
++ /* Non-register fields: */
++ struct pisp_be_lsc_extra lsc_extra;
++ struct pisp_be_cac_extra cac_extra;
++ struct pisp_be_downscale_extra
++ downscale_extra[PISP_BACK_END_NUM_OUTPUTS];
++ struct pisp_be_resample_extra resample_extra[PISP_BACK_END_NUM_OUTPUTS];
++ struct pisp_be_crop_config crop;
++ struct pisp_image_format_config hog_format;
++ __u32 dirty_flags_bayer; /* these use pisp_be_bayer_enable */
++ __u32 dirty_flags_rgb; /* use pisp_be_rgb_enable */
++ __u32 dirty_flags_extra; /* these use pisp_be_dirty_t */
+ } __attribute__((packed));
+
+ /**
diff --git a/target/linux/bcm27xx/patches-6.6/950-1160-media-pisp_be-Re-introduce-multi-context-support.patch b/target/linux/bcm27xx/patches-6.6/950-1160-media-pisp_be-Re-introduce-multi-context-support.patch
new file mode 100644
index 0000000000..ad667a1e69
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1160-media-pisp_be-Re-introduce-multi-context-support.patch
@@ -0,0 +1,886 @@
+From 033e037013f2c092501a03bb1bf5bbf7b4045aa0 Mon Sep 17 00:00:00 2001
+From: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+Date: Fri, 28 Jun 2024 17:26:26 +0200
+Subject: [PATCH 1160/1215] media: pisp_be: Re-introduce multi-context support
+
+Re-introduce multi-context support that was dropped from the
+mainline driver version.
+
+Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
+---
+ .../platform/raspberrypi/pisp_be/pisp_be.c | 355 ++++++++++--------
+ 1 file changed, 208 insertions(+), 147 deletions(-)
+
+--- a/drivers/media/platform/raspberrypi/pisp_be/pisp_be.c
++++ b/drivers/media/platform/raspberrypi/pisp_be/pisp_be.c
+@@ -24,6 +24,14 @@
+ /* Maximum number of config buffers possible */
+ #define PISP_BE_NUM_CONFIG_BUFFERS VB2_MAX_FRAME
+
++/*
++ * We want to support 2 independent instances allowing 2 simultaneous users
++ * of the ISP-BE (of course they share hardware, platform resources and mutex).
++ * Each such instance comprises a group of device nodes representing input
++ * and output queues, and a media controller device node to describe them.
++ */
++#define PISPBE_NUM_NODE_GROUPS 2
++
+ #define PISPBE_NAME "pispbe"
+
+ /* Some ISP-BE registers */
+@@ -156,7 +164,7 @@ struct pispbe_node {
+ struct media_pad pad;
+ struct media_intf_devnode *intf_devnode;
+ struct media_link *intf_link;
+- struct pispbe_dev *pispbe;
++ struct pispbe_node_group *node_group;
+ /* Video device lock */
+ struct mutex node_lock;
+ /* vb2_queue lock */
+@@ -173,9 +181,27 @@ struct pispbe_node {
+ #define NODE_NAME(node) \
+ (node_desc[(node)->id].ent_name + sizeof(PISPBE_NAME))
+
++/*
++ * Node group structure, which comprises all the input and output nodes that a
++ * single PiSP client will need, along with its own v4l2 and media devices.
++ */
++struct pispbe_node_group {
++ unsigned int id;
++ struct v4l2_device v4l2_dev;
++ struct v4l2_subdev sd;
++ struct pispbe_dev *pispbe;
++ struct media_device mdev;
++ struct pispbe_node node[PISPBE_NUM_NODES];
++ u32 streaming_map; /* bitmap of which nodes are streaming */
++ struct media_pad pad[PISPBE_NUM_NODES]; /* output pads first */
++ struct pisp_be_tiles_config *config;
++ dma_addr_t config_dma_addr;
++ unsigned int sequence;
++};
++
+ /* Records details of the jobs currently running or queued on the h/w. */
+ struct pispbe_job {
+- bool valid;
++ struct pispbe_node_group *node_group;
+ /*
+ * An array of buffer pointers - remember it's source buffers first,
+ * then captures, then metadata last.
+@@ -198,22 +224,13 @@ struct pispbe_job_descriptor {
+
+ /*
+ * Structure representing the entire PiSP Back End device, comprising several
+- * nodes which share platform resources and a mutex for the actual HW.
++ * nodes groups which share platform resources and a mutex for the actual HW.
+ */
+ struct pispbe_dev {
+ struct device *dev;
+- struct pispbe_dev *pispbe;
+- struct pisp_be_tiles_config *config;
+ void __iomem *be_reg_base;
+ struct clk *clk;
+- struct v4l2_device v4l2_dev;
+- struct v4l2_subdev sd;
+- struct media_device mdev;
+- struct media_pad pad[PISPBE_NUM_NODES]; /* output pads first */
+- struct pispbe_node node[PISPBE_NUM_NODES];
+- dma_addr_t config_dma_addr;
+- unsigned int sequence;
+- u32 streaming_map;
++ struct pispbe_node_group node_group[PISPBE_NUM_NODE_GROUPS];
+ struct pispbe_job queued_job, running_job;
+ spinlock_t hw_lock; /* protects "hw_busy" flag and streaming_map */
+ bool hw_busy; /* non-zero if a job is queued or is being started */
+@@ -348,9 +365,9 @@ static dma_addr_t pispbe_get_addr(struct
+ return 0;
+ }
+
+-static void pispbe_xlate_addrs(struct pispbe_dev *pispbe,
+- struct pispbe_job_descriptor *job,
+- struct pispbe_buffer *buf[PISPBE_NUM_NODES])
++static void pispbe_xlate_addrs(struct pispbe_job_descriptor *job,
++ struct pispbe_buffer *buf[PISPBE_NUM_NODES],
++ struct pispbe_node_group *node_group)
+ {
+ struct pispbe_hw_enables *hw_en = &job->hw_enables;
+ struct pisp_be_tiles_config *config = job->config;
+@@ -366,13 +383,13 @@ static void pispbe_xlate_addrs(struct pi
+ * to 3 planes.
+ */
+ ret = pispbe_get_planes_addr(addrs, buf[MAIN_INPUT_NODE],
+- &pispbe->node[MAIN_INPUT_NODE]);
++ &node_group->node[MAIN_INPUT_NODE]);
+ if (ret <= 0) {
+ /*
+ * This shouldn't happen; pispbe_schedule_internal should insist
+ * on an input.
+ */
+- dev_warn(pispbe->dev, "ISP-BE missing input\n");
++ dev_warn(node_group->pispbe->dev, "ISP-BE missing input\n");
+ hw_en->bayer_enables = 0;
+ hw_en->rgb_enables = 0;
+ return;
+@@ -427,7 +444,7 @@ static void pispbe_xlate_addrs(struct pi
+ for (unsigned int i = 0; i < PISP_BACK_END_NUM_OUTPUTS; i++) {
+ ret = pispbe_get_planes_addr(addrs + 7 + 3 * i,
+ buf[OUTPUT0_NODE + i],
+- &pispbe->node[OUTPUT0_NODE + i]);
++ &node_group->node[OUTPUT0_NODE + i]);
+ if (ret <= 0)
+ hw_en->rgb_enables &= ~(PISP_BE_RGB_ENABLE_OUTPUT0 << i);
+ }
+@@ -447,10 +464,11 @@ static void pispbe_xlate_addrs(struct pi
+ *
+ * Returns 0 if a job has been successfully prepared, < 0 otherwise.
+ */
+-static int pispbe_prepare_job(struct pispbe_dev *pispbe,
++static int pispbe_prepare_job(struct pispbe_node_group *node_group,
+ struct pispbe_job_descriptor *job)
+ {
+ struct pispbe_buffer *buf[PISPBE_NUM_NODES] = {};
++ struct pispbe_dev *pispbe = node_group->pispbe;
+ unsigned int config_index;
+ struct pispbe_node *node;
+ unsigned long flags;
+@@ -460,11 +478,11 @@ static int pispbe_prepare_job(struct pis
+ memset(job, 0, sizeof(struct pispbe_job_descriptor));
+
+ if (((BIT(CONFIG_NODE) | BIT(MAIN_INPUT_NODE)) &
+- pispbe->streaming_map) !=
++ node_group->streaming_map) !=
+ (BIT(CONFIG_NODE) | BIT(MAIN_INPUT_NODE)))
+ return -ENODEV;
+
+- node = &pispbe->node[CONFIG_NODE];
++ node = &node_group->node[CONFIG_NODE];
+ spin_lock_irqsave(&node->ready_lock, flags);
+ buf[CONFIG_NODE] = list_first_entry_or_null(&node->ready_queue,
+ struct pispbe_buffer,
+@@ -480,8 +498,8 @@ static int pispbe_prepare_job(struct pis
+ return -ENODEV;
+
+ config_index = buf[CONFIG_NODE]->vb.vb2_buf.index;
+- job->config = &pispbe->config[config_index];
+- job->tiles = pispbe->config_dma_addr +
++ job->config = &node_group->config[config_index];
++ job->tiles = node_group->config_dma_addr +
+ config_index * sizeof(struct pisp_be_tiles_config) +
+ offsetof(struct pisp_be_tiles_config, tiles);
+
+@@ -498,7 +516,7 @@ static int pispbe_prepare_job(struct pis
+ continue;
+
+ buf[i] = NULL;
+- if (!(pispbe->streaming_map & BIT(i)))
++ if (!(node_group->streaming_map & BIT(i)))
+ continue;
+
+ if ((!(rgb_en & PISP_BE_RGB_ENABLE_OUTPUT0) &&
+@@ -522,7 +540,7 @@ static int pispbe_prepare_job(struct pis
+ ignore_buffers = true;
+ }
+
+- node = &pispbe->node[i];
++ node = &node_group->node[i];
+
+ /* Pull a buffer from each V4L2 queue to form the queued job */
+ spin_lock_irqsave(&node->ready_lock, flags);
+@@ -539,16 +557,16 @@ static int pispbe_prepare_job(struct pis
+ goto err_return_buffers;
+ }
+
+- pispbe->queued_job.valid = true;
++ pispbe->queued_job.node_group = node_group;
+
+ /* Convert buffers to DMA addresses for the hardware */
+- pispbe_xlate_addrs(pispbe, job, buf);
++ pispbe_xlate_addrs(job, buf, node_group);
+
+ return 0;
+
+ err_return_buffers:
+ for (unsigned int i = 0; i < PISPBE_NUM_NODES; i++) {
+- struct pispbe_node *n = &pispbe->node[i];
++ struct pispbe_node *n = &node_group->node[i];
+
+ if (!buf[i])
+ continue;
+@@ -564,11 +582,12 @@ err_return_buffers:
+ return -ENODEV;
+ }
+
+-static void pispbe_schedule(struct pispbe_dev *pispbe, bool clear_hw_busy)
++static void pispbe_schedule(struct pispbe_dev *pispbe,
++ struct pispbe_node_group *node_group,
++ bool clear_hw_busy)
+ {
+ struct pispbe_job_descriptor job;
+ unsigned long flags;
+- int ret;
+
+ spin_lock_irqsave(&pispbe->hw_lock, flags);
+
+@@ -578,40 +597,53 @@ static void pispbe_schedule(struct pispb
+ if (pispbe->hw_busy)
+ goto unlock_and_return;
+
+- ret = pispbe_prepare_job(pispbe, &job);
+- if (ret)
+- goto unlock_and_return;
++ for (unsigned int i = 0; i < PISPBE_NUM_NODE_GROUPS; i++) {
++ int ret;
+
+- /*
+- * We can kick the job off without the hw_lock, as this can
+- * never run again until hw_busy is cleared, which will happen
+- * only when the following job has been queued and an interrupt
+- * is rised.
+- */
+- pispbe->hw_busy = true;
+- spin_unlock_irqrestore(&pispbe->hw_lock, flags);
++ /* Schedule jobs only for a specific group. */
++ if (node_group && &pispbe->node_group[i] != node_group)
++ continue;
+
+- if (job.config->num_tiles <= 0 ||
+- job.config->num_tiles > PISP_BACK_END_NUM_TILES ||
+- !((job.hw_enables.bayer_enables | job.hw_enables.rgb_enables) &
+- PISP_BE_BAYER_ENABLE_INPUT)) {
+ /*
+- * Bad job. We can't let it proceed as it could lock up
+- * the hardware, or worse!
+- *
+- * For now, just force num_tiles to 0, which causes the
+- * H/W to do something bizarre but survivable. It
+- * increments (started,done) counters by more than 1,
+- * but we seem to survive...
++ * Prepare a job for this group, if the group is not ready
++ * continue and try with the next one.
+ */
+- dev_dbg(pispbe->dev, "Bad job: invalid number of tiles: %u\n",
+- job.config->num_tiles);
+- job.config->num_tiles = 0;
+- }
++ ret = pispbe_prepare_job(&pispbe->node_group[i], &job);
++ if (ret)
++ continue;
++
++ /*
++ * We can kick the job off without the hw_lock, as this can
++ * never run again until hw_busy is cleared, which will happen
++ * only when the following job has been queued and an interrupt
++ * is rised.
++ */
++ pispbe->hw_busy = true;
++ spin_unlock_irqrestore(&pispbe->hw_lock, flags);
++
++ if (job.config->num_tiles <= 0 ||
++ job.config->num_tiles > PISP_BACK_END_NUM_TILES ||
++ !((job.hw_enables.bayer_enables |
++ job.hw_enables.rgb_enables) &
++ PISP_BE_BAYER_ENABLE_INPUT)) {
++ /*
++ * Bad job. We can't let it proceed as it could lock up
++ * the hardware, or worse!
++ *
++ * For now, just force num_tiles to 0, which causes the
++ * H/W to do something bizarre but survivable. It
++ * increments (started,done) counters by more than 1,
++ * but we seem to survive...
++ */
++ dev_dbg(pispbe->dev, "Bad job: invalid number of tiles: %u\n",
++ job.config->num_tiles);
++ job.config->num_tiles = 0;
++ }
+
+- pispbe_queue_job(pispbe, &job);
++ pispbe_queue_job(pispbe, &job);
+
+- return;
++ return;
++ }
+
+ unlock_and_return:
+ /* No job has been queued, just release the lock and return. */
+@@ -627,13 +659,13 @@ static void pispbe_isr_jobdone(struct pi
+ for (unsigned int i = 0; i < PISPBE_NUM_NODES; i++) {
+ if (buf[i]) {
+ buf[i]->vb.vb2_buf.timestamp = ts;
+- buf[i]->vb.sequence = pispbe->sequence;
++ buf[i]->vb.sequence = job->node_group->sequence;
+ vb2_buffer_done(&buf[i]->vb.vb2_buf,
+ VB2_BUF_STATE_DONE);
+ }
+ }
+
+- pispbe->sequence++;
++ job->node_group->sequence++;
+ }
+
+ static irqreturn_t pispbe_isr(int irq, void *dev)
+@@ -657,7 +689,7 @@ static irqreturn_t pispbe_isr(int irq, v
+ * we previously saw "start" now finishes, and we then queued a new job
+ * which we see both start and finish "simultaneously".
+ */
+- if (pispbe->running_job.valid && pispbe->done != done) {
++ if (pispbe->running_job.node_group && pispbe->done != done) {
+ pispbe_isr_jobdone(pispbe, &pispbe->running_job);
+ memset(&pispbe->running_job, 0, sizeof(pispbe->running_job));
+ pispbe->done++;
+@@ -667,7 +699,7 @@ static irqreturn_t pispbe_isr(int irq, v
+ pispbe->started++;
+ can_queue_another = 1;
+
+- if (pispbe->done != done && pispbe->queued_job.valid) {
++ if (pispbe->done != done && pispbe->queued_job.node_group) {
+ pispbe_isr_jobdone(pispbe, &pispbe->queued_job);
+ pispbe->done++;
+ } else {
+@@ -686,17 +718,17 @@ static irqreturn_t pispbe_isr(int irq, v
+ }
+
+ /* check if there's more to do before going to sleep */
+- pispbe_schedule(pispbe, can_queue_another);
++ pispbe_schedule(pispbe, NULL, can_queue_another);
+
+ return IRQ_HANDLED;
+ }
+
+-static int pisp_be_validate_config(struct pispbe_dev *pispbe,
++static int pisp_be_validate_config(struct pispbe_node_group *node_group,
+ struct pisp_be_tiles_config *config)
+ {
+ u32 bayer_enables = config->config.global.bayer_enables;
+ u32 rgb_enables = config->config.global.rgb_enables;
+- struct device *dev = pispbe->dev;
++ struct device *dev = node_group->pispbe->dev;
+ struct v4l2_format *fmt;
+ unsigned int bpl, size;
+
+@@ -707,7 +739,7 @@ static int pisp_be_validate_config(struc
+ }
+
+ /* Ensure output config strides and buffer sizes match the V4L2 formats. */
+- fmt = &pispbe->node[TDN_OUTPUT_NODE].format;
++ fmt = &node_group->node[TDN_OUTPUT_NODE].format;
+ if (bayer_enables & PISP_BE_BAYER_ENABLE_TDN_OUTPUT) {
+ bpl = config->config.tdn_output_format.stride;
+ size = bpl * config->config.tdn_output_format.height;
+@@ -725,7 +757,7 @@ static int pisp_be_validate_config(struc
+ }
+ }
+
+- fmt = &pispbe->node[STITCH_OUTPUT_NODE].format;
++ fmt = &node_group->node[STITCH_OUTPUT_NODE].format;
+ if (bayer_enables & PISP_BE_BAYER_ENABLE_STITCH_OUTPUT) {
+ bpl = config->config.stitch_output_format.stride;
+ size = bpl * config->config.stitch_output_format.height;
+@@ -751,7 +783,7 @@ static int pisp_be_validate_config(struc
+ PISP_IMAGE_FORMAT_WALLPAPER_ROLL)
+ continue; /* TODO: Size checks for wallpaper formats */
+
+- fmt = &pispbe->node[OUTPUT0_NODE + j].format;
++ fmt = &node_group->node[OUTPUT0_NODE + j].format;
+ for (unsigned int i = 0; i < fmt->fmt.pix_mp.num_planes; i++) {
+ bpl = !i ? config->config.output_format[j].image.stride
+ : config->config.output_format[j].image.stride2;
+@@ -783,7 +815,7 @@ static int pispbe_node_queue_setup(struc
+ struct device *alloc_devs[])
+ {
+ struct pispbe_node *node = vb2_get_drv_priv(q);
+- struct pispbe_dev *pispbe = node->pispbe;
++ struct pispbe_dev *pispbe = node->node_group->pispbe;
+ unsigned int num_planes = NODE_IS_MPLANE(node) ?
+ node->format.fmt.pix_mp.num_planes : 1;
+
+@@ -821,7 +853,7 @@ static int pispbe_node_queue_setup(struc
+ static int pispbe_node_buffer_prepare(struct vb2_buffer *vb)
+ {
+ struct pispbe_node *node = vb2_get_drv_priv(vb->vb2_queue);
+- struct pispbe_dev *pispbe = node->pispbe;
++ struct pispbe_dev *pispbe = node->node_group->pispbe;
+ unsigned int num_planes = NODE_IS_MPLANE(node) ?
+ node->format.fmt.pix_mp.num_planes : 1;
+
+@@ -841,12 +873,12 @@ static int pispbe_node_buffer_prepare(st
+ }
+
+ if (node->id == CONFIG_NODE) {
+- void *dst = &node->pispbe->config[vb->index];
++ void *dst = &node->node_group->config[vb->index];
+ void *src = vb2_plane_vaddr(vb, 0);
+
+ memcpy(dst, src, sizeof(struct pisp_be_tiles_config));
+
+- return pisp_be_validate_config(pispbe, dst);
++ return pisp_be_validate_config(node->node_group, dst);
+ }
+
+ return 0;
+@@ -859,7 +891,8 @@ static void pispbe_node_buffer_queue(str
+ struct pispbe_buffer *buffer =
+ container_of(vbuf, struct pispbe_buffer, vb);
+ struct pispbe_node *node = vb2_get_drv_priv(buf->vb2_queue);
+- struct pispbe_dev *pispbe = node->pispbe;
++ struct pispbe_node_group *node_group = node->node_group;
++ struct pispbe_dev *pispbe = node->node_group->pispbe;
+ unsigned long flags;
+
+ dev_dbg(pispbe->dev, "%s: for node %s\n", __func__, NODE_NAME(node));
+@@ -869,15 +902,16 @@ static void pispbe_node_buffer_queue(str
+
+ /*
+ * Every time we add a buffer, check if there's now some work for the hw
+- * to do.
++ * to do, but only for this client.
+ */
+- pispbe_schedule(pispbe, false);
++ pispbe_schedule(node_group->pispbe, node_group, false);
+ }
+
+ static int pispbe_node_start_streaming(struct vb2_queue *q, unsigned int count)
+ {
+ struct pispbe_node *node = vb2_get_drv_priv(q);
+- struct pispbe_dev *pispbe = node->pispbe;
++ struct pispbe_node_group *node_group = node->node_group;
++ struct pispbe_dev *pispbe = node_group->pispbe;
+ struct pispbe_buffer *buf, *tmp;
+ unsigned long flags;
+ int ret;
+@@ -887,17 +921,17 @@ static int pispbe_node_start_streaming(s
+ goto err_return_buffers;
+
+ spin_lock_irqsave(&pispbe->hw_lock, flags);
+- node->pispbe->streaming_map |= BIT(node->id);
+- node->pispbe->sequence = 0;
++ node->node_group->streaming_map |= BIT(node->id);
++ node->node_group->sequence = 0;
+ spin_unlock_irqrestore(&pispbe->hw_lock, flags);
+
+ dev_dbg(pispbe->dev, "%s: for node %s (count %u)\n",
+ __func__, NODE_NAME(node), count);
+- dev_dbg(pispbe->dev, "Nodes streaming now 0x%x\n",
+- node->pispbe->streaming_map);
++ dev_dbg(pispbe->dev, "Nodes streaming for this group now 0x%x\n",
++ node->node_group->streaming_map);
+
+ /* Maybe we're ready to run. */
+- pispbe_schedule(pispbe, false);
++ pispbe_schedule(node_group->pispbe, node_group, false);
+
+ return 0;
+
+@@ -915,7 +949,8 @@ err_return_buffers:
+ static void pispbe_node_stop_streaming(struct vb2_queue *q)
+ {
+ struct pispbe_node *node = vb2_get_drv_priv(q);
+- struct pispbe_dev *pispbe = node->pispbe;
++ struct pispbe_node_group *node_group = node->node_group;
++ struct pispbe_dev *pispbe = node_group->pispbe;
+ struct pispbe_buffer *buf;
+ unsigned long flags;
+
+@@ -948,14 +983,14 @@ static void pispbe_node_stop_streaming(s
+ vb2_wait_for_all_buffers(&node->queue);
+
+ spin_lock_irqsave(&pispbe->hw_lock, flags);
+- pispbe->streaming_map &= ~BIT(node->id);
++ node_group->streaming_map &= ~BIT(node->id);
+ spin_unlock_irqrestore(&pispbe->hw_lock, flags);
+
+ pm_runtime_mark_last_busy(pispbe->dev);
+ pm_runtime_put_autosuspend(pispbe->dev);
+
+- dev_dbg(pispbe->dev, "Nodes streaming now 0x%x\n",
+- pispbe->streaming_map);
++ dev_dbg(pispbe->dev, "Nodes streaming for this group now 0x%x\n",
++ node_group->streaming_map);
+ }
+
+ static const struct vb2_ops pispbe_node_queue_ops = {
+@@ -979,7 +1014,7 @@ static int pispbe_node_querycap(struct f
+ struct v4l2_capability *cap)
+ {
+ struct pispbe_node *node = video_drvdata(file);
+- struct pispbe_dev *pispbe = node->pispbe;
++ struct pispbe_dev *pispbe = node->node_group->pispbe;
+
+ strscpy(cap->driver, PISPBE_NAME, sizeof(cap->driver));
+ strscpy(cap->card, PISPBE_NAME, sizeof(cap->card));
+@@ -995,7 +1030,7 @@ static int pispbe_node_g_fmt_vid_cap(str
+ struct v4l2_format *f)
+ {
+ struct pispbe_node *node = video_drvdata(file);
+- struct pispbe_dev *pispbe = node->pispbe;
++ struct pispbe_dev *pispbe = node->node_group->pispbe;
+
+ if (!NODE_IS_CAPTURE(node) || NODE_IS_META(node)) {
+ dev_dbg(pispbe->dev,
+@@ -1015,7 +1050,7 @@ static int pispbe_node_g_fmt_vid_out(str
+ struct v4l2_format *f)
+ {
+ struct pispbe_node *node = video_drvdata(file);
+- struct pispbe_dev *pispbe = node->pispbe;
++ struct pispbe_dev *pispbe = node->node_group->pispbe;
+
+ if (NODE_IS_CAPTURE(node) || NODE_IS_META(node)) {
+ dev_dbg(pispbe->dev,
+@@ -1035,7 +1070,7 @@ static int pispbe_node_g_fmt_meta_out(st
+ struct v4l2_format *f)
+ {
+ struct pispbe_node *node = video_drvdata(file);
+- struct pispbe_dev *pispbe = node->pispbe;
++ struct pispbe_dev *pispbe = node->node_group->pispbe;
+
+ if (!NODE_IS_META(node) || NODE_IS_CAPTURE(node)) {
+ dev_dbg(pispbe->dev,
+@@ -1092,7 +1127,7 @@ static void pispbe_set_plane_params(stru
+
+ static void pispbe_try_format(struct v4l2_format *f, struct pispbe_node *node)
+ {
+- struct pispbe_dev *pispbe = node->pispbe;
++ struct pispbe_dev *pispbe = node->node_group->pispbe;
+ u32 pixfmt = f->fmt.pix_mp.pixelformat;
+ const struct pisp_be_format *fmt;
+ bool is_rgb;
+@@ -1156,7 +1191,7 @@ static int pispbe_node_try_fmt_vid_cap(s
+ struct v4l2_format *f)
+ {
+ struct pispbe_node *node = video_drvdata(file);
+- struct pispbe_dev *pispbe = node->pispbe;
++ struct pispbe_dev *pispbe = node->node_group->pispbe;
+
+ if (!NODE_IS_CAPTURE(node) || NODE_IS_META(node)) {
+ dev_dbg(pispbe->dev,
+@@ -1174,7 +1209,7 @@ static int pispbe_node_try_fmt_vid_out(s
+ struct v4l2_format *f)
+ {
+ struct pispbe_node *node = video_drvdata(file);
+- struct pispbe_dev *pispbe = node->pispbe;
++ struct pispbe_dev *pispbe = node->node_group->pispbe;
+
+ if (!NODE_IS_OUTPUT(node) || NODE_IS_META(node)) {
+ dev_dbg(pispbe->dev,
+@@ -1192,7 +1227,7 @@ static int pispbe_node_try_fmt_meta_out(
+ struct v4l2_format *f)
+ {
+ struct pispbe_node *node = video_drvdata(file);
+- struct pispbe_dev *pispbe = node->pispbe;
++ struct pispbe_dev *pispbe = node->node_group->pispbe;
+
+ if (!NODE_IS_META(node) || NODE_IS_CAPTURE(node)) {
+ dev_dbg(pispbe->dev,
+@@ -1211,7 +1246,7 @@ static int pispbe_node_s_fmt_vid_cap(str
+ struct v4l2_format *f)
+ {
+ struct pispbe_node *node = video_drvdata(file);
+- struct pispbe_dev *pispbe = node->pispbe;
++ struct pispbe_dev *pispbe = node->node_group->pispbe;
+ int ret;
+
+ ret = pispbe_node_try_fmt_vid_cap(file, priv, f);
+@@ -1234,7 +1269,7 @@ static int pispbe_node_s_fmt_vid_out(str
+ struct v4l2_format *f)
+ {
+ struct pispbe_node *node = video_drvdata(file);
+- struct pispbe_dev *pispbe = node->pispbe;
++ struct pispbe_dev *pispbe = node->node_group->pispbe;
+ int ret;
+
+ ret = pispbe_node_try_fmt_vid_out(file, priv, f);
+@@ -1257,7 +1292,7 @@ static int pispbe_node_s_fmt_meta_out(st
+ struct v4l2_format *f)
+ {
+ struct pispbe_node *node = video_drvdata(file);
+- struct pispbe_dev *pispbe = node->pispbe;
++ struct pispbe_dev *pispbe = node->node_group->pispbe;
+ int ret;
+
+ ret = pispbe_node_try_fmt_meta_out(file, priv, f);
+@@ -1306,7 +1341,7 @@ static int pispbe_enum_framesizes(struct
+ struct v4l2_frmsizeenum *fsize)
+ {
+ struct pispbe_node *node = video_drvdata(file);
+- struct pispbe_dev *pispbe = node->pispbe;
++ struct pispbe_dev *pispbe = node->node_group->pispbe;
+
+ if (NODE_IS_META(node) || fsize->index)
+ return -EINVAL;
+@@ -1391,17 +1426,19 @@ static void pispbe_node_def_fmt(struct p
+ * Initialise a struct pispbe_node and register it as /dev/video<N>
+ * to represent one of the PiSP Back End's input or output streams.
+ */
+-static int pispbe_init_node(struct pispbe_dev *pispbe, unsigned int id)
++static int pispbe_init_node(struct pispbe_node_group *node_group,
++ unsigned int id)
+ {
+ bool output = NODE_DESC_IS_OUTPUT(&node_desc[id]);
+- struct pispbe_node *node = &pispbe->node[id];
++ struct pispbe_node *node = &node_group->node[id];
+ struct media_entity *entity = &node->vfd.entity;
++ struct pispbe_dev *pispbe = node_group->pispbe;
+ struct video_device *vdev = &node->vfd;
+ struct vb2_queue *q = &node->queue;
+ int ret;
+
+ node->id = id;
+- node->pispbe = pispbe;
++ node->node_group = node_group;
+ node->buf_type = node_desc[id].buf_type;
+
+ mutex_init(&node->node_lock);
+@@ -1419,7 +1456,7 @@ static int pispbe_init_node(struct pispb
+ q->ops = &pispbe_node_queue_ops;
+ q->buf_struct_size = sizeof(struct pispbe_buffer);
+ q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+- q->dev = pispbe->dev;
++ q->dev = node->node_group->pispbe->dev;
+ /* get V4L2 to handle node->queue locking */
+ q->lock = &node->queue_lock;
+
+@@ -1431,7 +1468,7 @@ static int pispbe_init_node(struct pispb
+
+ *vdev = pispbe_videodev; /* default initialization */
+ strscpy(vdev->name, node_desc[id].ent_name, sizeof(vdev->name));
+- vdev->v4l2_dev = &pispbe->v4l2_dev;
++ vdev->v4l2_dev = &node_group->v4l2_dev;
+ vdev->vfl_dir = output ? VFL_DIR_TX : VFL_DIR_RX;
+ /* get V4L2 to serialise our ioctls */
+ vdev->lock = &node->node_lock;
+@@ -1457,11 +1494,11 @@ static int pispbe_init_node(struct pispb
+ video_set_drvdata(vdev, node);
+
+ if (output)
+- ret = media_create_pad_link(entity, 0, &pispbe->sd.entity,
++ ret = media_create_pad_link(entity, 0, &node_group->sd.entity,
+ id, MEDIA_LNK_FL_IMMUTABLE |
+ MEDIA_LNK_FL_ENABLED);
+ else
+- ret = media_create_pad_link(&pispbe->sd.entity, id, entity,
++ ret = media_create_pad_link(&node_group->sd.entity, id, entity,
+ 0, MEDIA_LNK_FL_IMMUTABLE |
+ MEDIA_LNK_FL_ENABLED);
+ if (ret)
+@@ -1490,9 +1527,10 @@ static const struct v4l2_subdev_ops pisp
+ .pad = &pispbe_pad_ops,
+ };
+
+-static int pispbe_init_subdev(struct pispbe_dev *pispbe)
++static int pispbe_init_subdev(struct pispbe_node_group *node_group)
+ {
+- struct v4l2_subdev *sd = &pispbe->sd;
++ struct pispbe_dev *pispbe = node_group->pispbe;
++ struct v4l2_subdev *sd = &node_group->sd;
+ int ret;
+
+ v4l2_subdev_init(sd, &pispbe_sd_ops);
+@@ -1502,16 +1540,16 @@ static int pispbe_init_subdev(struct pis
+ strscpy(sd->name, PISPBE_NAME, sizeof(sd->name));
+
+ for (unsigned int i = 0; i < PISPBE_NUM_NODES; i++)
+- pispbe->pad[i].flags =
++ node_group->pad[i].flags =
+ NODE_DESC_IS_OUTPUT(&node_desc[i]) ?
+ MEDIA_PAD_FL_SINK : MEDIA_PAD_FL_SOURCE;
+
+ ret = media_entity_pads_init(&sd->entity, PISPBE_NUM_NODES,
+- pispbe->pad);
++ node_group->pad);
+ if (ret)
+ goto error;
+
+- ret = v4l2_device_register_subdev(&pispbe->v4l2_dev, sd);
++ ret = v4l2_device_register_subdev(&node_group->v4l2_dev, sd);
+ if (ret)
+ goto error;
+
+@@ -1522,36 +1560,43 @@ error:
+ return ret;
+ }
+
+-static int pispbe_init_devices(struct pispbe_dev *pispbe)
++static int pispbe_init_group(struct pispbe_dev *pispbe, unsigned int id)
+ {
++ struct pispbe_node_group *node_group = &pispbe->node_group[id];
+ struct v4l2_device *v4l2_dev;
+ struct media_device *mdev;
+ unsigned int num_regist;
+ int ret;
+
++ node_group->id = id;
++ node_group->pispbe = pispbe;
++ node_group->streaming_map = 0;
++
++ dev_dbg(pispbe->dev, "Register nodes for group %u\n", id);
++
+ /* Register v4l2_device and media_device */
+- mdev = &pispbe->mdev;
+- mdev->hw_revision = pispbe->hw_version;
+- mdev->dev = pispbe->dev;
++ mdev = &node_group->mdev;
++ mdev->hw_revision = node_group->pispbe->hw_version;
++ mdev->dev = node_group->pispbe->dev;
+ strscpy(mdev->model, PISPBE_NAME, sizeof(mdev->model));
+ media_device_init(mdev);
+
+- v4l2_dev = &pispbe->v4l2_dev;
+- v4l2_dev->mdev = &pispbe->mdev;
++ v4l2_dev = &node_group->v4l2_dev;
++ v4l2_dev->mdev = &node_group->mdev;
+ strscpy(v4l2_dev->name, PISPBE_NAME, sizeof(v4l2_dev->name));
+
+- ret = v4l2_device_register(pispbe->dev, v4l2_dev);
++ ret = v4l2_device_register(pispbe->dev, &node_group->v4l2_dev);
+ if (ret)
+ goto err_media_dev_cleanup;
+
+ /* Register the PISPBE subdevice. */
+- ret = pispbe_init_subdev(pispbe);
++ ret = pispbe_init_subdev(node_group);
+ if (ret)
+ goto err_unregister_v4l2;
+
+ /* Create device video nodes */
+ for (num_regist = 0; num_regist < PISPBE_NUM_NODES; num_regist++) {
+- ret = pispbe_init_node(pispbe, num_regist);
++ ret = pispbe_init_node(node_group, num_regist);
+ if (ret)
+ goto err_unregister_nodes;
+ }
+@@ -1560,12 +1605,12 @@ static int pispbe_init_devices(struct pi
+ if (ret)
+ goto err_unregister_nodes;
+
+- pispbe->config =
++ node_group->config =
+ dma_alloc_coherent(pispbe->dev,
+ sizeof(struct pisp_be_tiles_config) *
+ PISP_BE_NUM_CONFIG_BUFFERS,
+- &pispbe->config_dma_addr, GFP_KERNEL);
+- if (!pispbe->config) {
++ &node_group->config_dma_addr, GFP_KERNEL);
++ if (!node_group->config) {
+ dev_err(pispbe->dev, "Unable to allocate cached config buffers.\n");
+ ret = -ENOMEM;
+ goto err_unregister_mdev;
+@@ -1577,11 +1622,11 @@ err_unregister_mdev:
+ media_device_unregister(mdev);
+ err_unregister_nodes:
+ while (num_regist-- > 0) {
+- video_unregister_device(&pispbe->node[num_regist].vfd);
+- vb2_queue_release(&pispbe->node[num_regist].queue);
++ video_unregister_device(&node_group->node[num_regist].vfd);
++ vb2_queue_release(&node_group->node[num_regist].queue);
+ }
+- v4l2_device_unregister_subdev(&pispbe->sd);
+- media_entity_cleanup(&pispbe->sd.entity);
++ v4l2_device_unregister_subdev(&node_group->sd);
++ media_entity_cleanup(&node_group->sd.entity);
+ err_unregister_v4l2:
+ v4l2_device_unregister(v4l2_dev);
+ err_media_dev_cleanup:
+@@ -1589,31 +1634,33 @@ err_media_dev_cleanup:
+ return ret;
+ }
+
+-static void pispbe_destroy_devices(struct pispbe_dev *pispbe)
++static void pispbe_destroy_node_group(struct pispbe_node_group *node_group)
+ {
+- if (pispbe->config) {
+- dma_free_coherent(pispbe->dev,
++ struct pispbe_dev *pispbe = node_group->pispbe;
++
++ if (node_group->config) {
++ dma_free_coherent(node_group->pispbe->dev,
+ sizeof(struct pisp_be_tiles_config) *
+ PISP_BE_NUM_CONFIG_BUFFERS,
+- pispbe->config,
+- pispbe->config_dma_addr);
++ node_group->config,
++ node_group->config_dma_addr);
+ }
+
+ dev_dbg(pispbe->dev, "Unregister from media controller\n");
+
+- v4l2_device_unregister_subdev(&pispbe->sd);
+- media_entity_cleanup(&pispbe->sd.entity);
+- media_device_unregister(&pispbe->mdev);
++ v4l2_device_unregister_subdev(&node_group->sd);
++ media_entity_cleanup(&node_group->sd.entity);
++ media_device_unregister(&node_group->mdev);
+
+ for (int i = PISPBE_NUM_NODES - 1; i >= 0; i--) {
+- video_unregister_device(&pispbe->node[i].vfd);
+- vb2_queue_release(&pispbe->node[i].queue);
+- mutex_destroy(&pispbe->node[i].node_lock);
+- mutex_destroy(&pispbe->node[i].queue_lock);
++ video_unregister_device(&node_group->node[i].vfd);
++ vb2_queue_release(&node_group->node[i].queue);
++ mutex_destroy(&node_group->node[i].node_lock);
++ mutex_destroy(&node_group->node[i].queue_lock);
+ }
+
+- media_device_cleanup(&pispbe->mdev);
+- v4l2_device_unregister(&pispbe->v4l2_dev);
++ media_device_cleanup(&node_group->mdev);
++ v4l2_device_unregister(&node_group->v4l2_dev);
+ }
+
+ static int pispbe_runtime_suspend(struct device *dev)
+@@ -1681,9 +1728,13 @@ static int pispbe_hw_init(struct pispbe_
+ return 0;
+ }
+
+-/* Probe the ISP-BE hardware block, as a single platform device. */
++/*
++ * Probe the ISP-BE hardware block, as a single platform device.
++ * This will instantiate multiple "node groups" each with many device nodes.
++ */
+ static int pispbe_probe(struct platform_device *pdev)
+ {
++ unsigned int num_groups = 0;
+ struct pispbe_dev *pispbe;
+ int ret;
+
+@@ -1738,17 +1789,26 @@ static int pispbe_probe(struct platform_
+ if (ret)
+ goto pm_runtime_suspend_err;
+
+- ret = pispbe_init_devices(pispbe);
+- if (ret)
+- goto disable_devs_err;
++ /*
++ * Initialise and register devices for each node_group, including media
++ * device
++ */
++ for (num_groups = 0;
++ num_groups < PISPBE_NUM_NODE_GROUPS;
++ num_groups++) {
++ ret = pispbe_init_group(pispbe, num_groups);
++ if (ret)
++ goto disable_nodes_err;
++ }
+
+ pm_runtime_mark_last_busy(pispbe->dev);
+ pm_runtime_put_autosuspend(pispbe->dev);
+
+ return 0;
+
+-disable_devs_err:
+- pispbe_destroy_devices(pispbe);
++disable_nodes_err:
++ while (num_groups-- > 0)
++ pispbe_destroy_node_group(&pispbe->node_group[num_groups]);
+ pm_runtime_suspend_err:
+ pispbe_runtime_suspend(pispbe->dev);
+ pm_runtime_disable_err:
+@@ -1762,7 +1822,8 @@ static int pispbe_remove(struct platform
+ {
+ struct pispbe_dev *pispbe = platform_get_drvdata(pdev);
+
+- pispbe_destroy_devices(pispbe);
++ for (int i = PISPBE_NUM_NODE_GROUPS - 1; i >= 0; i--)
++ pispbe_destroy_node_group(&pispbe->node_group[i]);
+
+ pispbe_runtime_suspend(pispbe->dev);
+ pm_runtime_dont_use_autosuspend(pispbe->dev);
diff --git a/target/linux/bcm27xx/patches-6.6/950-1161-media-pisp_be-Re-introduce-video-node-offset.patch b/target/linux/bcm27xx/patches-6.6/950-1161-media-pisp_be-Re-introduce-video-node-offset.patch
new file mode 100644
index 0000000000..0586f5c620
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1161-media-pisp_be-Re-introduce-video-node-offset.patch
@@ -0,0 +1,36 @@
+From f372f2854279828a33b9b3debc233d366fb4c124 Mon Sep 17 00:00:00 2001
+From: Naushir Patuck <naush@raspberrypi.com>
+Date: Mon, 8 Jul 2024 11:47:49 +0100
+Subject: [PATCH 1161/1215] media: pisp_be: Re-introduce video node offset
+
+Offset the backend dev-nodes starting at /dev/video20
+onwards to maintain backward compatibility with the
+pre-upstreamed kernel driver.
+
+Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
+---
+ drivers/media/platform/raspberrypi/pisp_be/pisp_be.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/drivers/media/platform/raspberrypi/pisp_be/pisp_be.c
++++ b/drivers/media/platform/raspberrypi/pisp_be/pisp_be.c
+@@ -21,6 +21,9 @@
+
+ #include "pisp_be_formats.h"
+
++/* Offset to use when registering the /dev/videoX node */
++#define PISPBE_VIDEO_NODE_OFFSET 20
++
+ /* Maximum number of config buffers possible */
+ #define PISP_BE_NUM_CONFIG_BUFFERS VB2_MAX_FRAME
+
+@@ -1484,7 +1487,8 @@ static int pispbe_init_node(struct pispb
+ goto err_unregister_queue;
+ }
+
+- ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
++ ret = video_register_device(vdev, VFL_TYPE_VIDEO,
++ PISPBE_VIDEO_NODE_OFFSET);
+ if (ret) {
+ dev_err(pispbe->dev,
+ "Failed to register video %s device node\n",
diff --git a/target/linux/bcm27xx/patches-6.6/950-1163-dts-Make-camN_reg-and-camN_reg_gpio-overrides-generi.patch b/target/linux/bcm27xx/patches-6.6/950-1163-dts-Make-camN_reg-and-camN_reg_gpio-overrides-generi.patch
new file mode 100644
index 0000000000..38c1d3b9b6
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1163-dts-Make-camN_reg-and-camN_reg_gpio-overrides-generi.patch
@@ -0,0 +1,158 @@
+From 6e4ad40811170653431fc40a6fdc3f486863b40f Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Thu, 4 Jul 2024 18:15:00 +0100
+Subject: [PATCH 1163/1215] dts: Make camN_reg and camN_reg_gpio overrides
+ generic
+
+The camera regulator GPIO can be used for other purposes,
+so the camN_reg override to allow disabling is potentially
+useful on any platform.
+camN_gpio is less useful, but isn't invalid.
+
+Move these overrides from the CM dt files to bcm270x-rpi.dtsi
+and bcm2712-rpi.dtsi.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ .../arm/boot/dts/broadcom/bcm2708-rpi-cm.dtsi | 4 ----
+ .../arm/boot/dts/broadcom/bcm2709-rpi-cm2.dts | 4 ----
+ arch/arm/boot/dts/broadcom/bcm270x-rpi.dtsi | 7 +++++++
+ .../arm/boot/dts/broadcom/bcm2710-rpi-cm3.dts | 4 ----
+ .../arm/boot/dts/broadcom/bcm2711-rpi-cm4.dts | 7 -------
+ .../boot/dts/broadcom/bcm2711-rpi-cm4s.dts | 5 -----
+ arch/arm/boot/dts/broadcom/bcm2712-rpi.dtsi | 8 ++++++++
+ arch/arm/boot/dts/overlays/README | 20 +++++++++----------
+ 8 files changed, 25 insertions(+), 34 deletions(-)
+
+--- a/arch/arm/boot/dts/broadcom/bcm2708-rpi-cm.dtsi
++++ b/arch/arm/boot/dts/broadcom/bcm2708-rpi-cm.dtsi
+@@ -19,9 +19,5 @@ i2c_vc: &i2c0 {
+ act_led_gpio = <&led_act>,"gpios:4";
+ act_led_activelow = <&led_act>,"gpios:8";
+ act_led_trigger = <&led_act>,"linux,default-trigger";
+- cam0_reg = <&cam0_reg>,"status";
+- cam0_reg_gpio = <&cam0_reg>,"gpio:4";
+- cam1_reg = <&cam1_reg>,"status";
+- cam1_reg_gpio = <&cam1_reg>,"gpio:4";
+ };
+ };
+--- a/arch/arm/boot/dts/broadcom/bcm2709-rpi-cm2.dts
++++ b/arch/arm/boot/dts/broadcom/bcm2709-rpi-cm2.dts
+@@ -211,9 +211,5 @@ i2c_csi_dsi0: &i2c0 {
+ act_led_gpio = <&led_act>,"gpios:4";
+ act_led_activelow = <&led_act>,"gpios:8";
+ act_led_trigger = <&led_act>,"linux,default-trigger";
+- cam0_reg = <&cam0_reg>,"status";
+- cam0_reg_gpio = <&cam0_reg>,"gpio:4";
+- cam1_reg = <&cam1_reg>,"status";
+- cam1_reg_gpio = <&cam1_reg>,"gpio:4";
+ };
+ };
+--- a/arch/arm/boot/dts/broadcom/bcm270x-rpi.dtsi
++++ b/arch/arm/boot/dts/broadcom/bcm270x-rpi.dtsi
+@@ -111,6 +111,13 @@
+ <&csi0>, "sync-gpios:4",
+ <&csi0>, "sync-gpios:8=", <GPIO_ACTIVE_LOW>;
+
++ cam0_reg = <&cam0_reg>,"status";
++ cam0_reg_gpio = <&cam0_reg>,"gpio:4",
++ <&cam0_reg>,"gpio:0=", <&gpio>;
++ cam1_reg = <&cam1_reg>,"status";
++ cam1_reg_gpio = <&cam1_reg>,"gpio:4",
++ <&cam1_reg>,"gpio:0=", <&gpio>;
++
+ strict_gpiod = <&chosen>, "bootargs=pinctrl_bcm2835.persist_gpio_outputs=n";
+ };
+ };
+--- a/arch/arm/boot/dts/broadcom/bcm2710-rpi-cm3.dts
++++ b/arch/arm/boot/dts/broadcom/bcm2710-rpi-cm3.dts
+@@ -211,9 +211,5 @@ i2c_csi_dsi0: &i2c0 {
+ act_led_gpio = <&led_act>,"gpios:4";
+ act_led_activelow = <&led_act>,"gpios:8";
+ act_led_trigger = <&led_act>,"linux,default-trigger";
+- cam0_reg = <&cam0_reg>,"status";
+- cam0_reg_gpio = <&cam0_reg>,"gpio:4";
+- cam1_reg = <&cam1_reg>,"status";
+- cam1_reg_gpio = <&cam1_reg>,"gpio:4";
+ };
+ };
+--- a/arch/arm/boot/dts/broadcom/bcm2711-rpi-cm4.dts
++++ b/arch/arm/boot/dts/broadcom/bcm2711-rpi-cm4.dts
+@@ -498,13 +498,6 @@ i2c_csi_dsi0: &i2c0 {
+ <&ant2>, "output-high?=off",
+ <&ant2>, "output-low?=on";
+
+- cam0_reg = <&cam0_reg>,"status";
+- cam0_reg_gpio = <&cam0_reg>,"gpio:4",
+- <&cam0_reg>,"gpio:0=", <&gpio>;
+- cam1_reg = <&cam1_reg>,"status";
+- cam1_reg_gpio = <&cam1_reg>,"gpio:4",
+- <&cam1_reg>,"gpio:0=", <&gpio>;
+-
+ pcie_tperst_clk_ms = <&pcie0>,"brcm,tperst-clk-ms:0";
+ };
+ };
+--- a/arch/arm/boot/dts/broadcom/bcm2711-rpi-cm4s.dts
++++ b/arch/arm/boot/dts/broadcom/bcm2711-rpi-cm4s.dts
+@@ -289,10 +289,5 @@ i2c_csi_dsi0: &i2c0 {
+ act_led_gpio = <&led_act>,"gpios:4";
+ act_led_activelow = <&led_act>,"gpios:8";
+ act_led_trigger = <&led_act>,"linux,default-trigger";
+-
+- cam0_reg = <&cam0_reg>,"status";
+- cam0_reg_gpio = <&cam0_reg>,"gpio:4";
+- cam1_reg = <&cam1_reg>,"status";
+- cam1_reg_gpio = <&cam1_reg>,"gpio:4";
+ };
+ };
+--- a/arch/arm/boot/dts/broadcom/bcm2712-rpi.dtsi
++++ b/arch/arm/boot/dts/broadcom/bcm2712-rpi.dtsi
+@@ -106,6 +106,14 @@
+ nvmem_priv_rw = <&nvmem_priv>,"rw?";
+ nvmem_mac_rw = <&nvmem_mac>,"rw?";
+ strict_gpiod = <&chosen>, "bootargs=pinctrl_rp1.persist_gpio_outputs=n";
++
++ cam0_reg = <&cam0_reg>,"status";
++ cam0_reg_gpio = <&cam0_reg>,"gpio:4",
++ <&cam0_reg>,"gpio:0=", <&gpio>;
++ cam1_reg = <&cam1_reg>,"status";
++ cam1_reg_gpio = <&cam1_reg>,"gpio:4",
++ <&cam1_reg>,"gpio:0=", <&gpio>;
++
+ };
+ };
+
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -171,21 +171,21 @@ Params:
+ button_debounce Set the debounce delay (in ms) on the power/
+ shutdown button (default 50ms)
+
+- cam0_reg Enables CAM 0 regulator.
+- Only required on CM1 & 3.
++ cam0_reg Controls CAM 0 regulator.
++ Disabled by default on CM1 & 3.
++ Enabled by default on all other boards.
+
+ cam0_reg_gpio Set GPIO for CAM 0 regulator.
+- Default 31 on CM1, 3, and 4S.
+- Default of GPIO expander 5 on CM4, but override
+- switches to normal GPIO.
++ NB override switches to the normal GPIO driver,
++ even if the original was on the GPIO expander.
+
+- cam1_reg Enables CAM 1 regulator.
+- Only required on CM1 & 3.
++ cam1_reg Controls CAM 1 regulator.
++ Disabled by default on CM1 & 3.
++ Enabled by default on all other boards.
+
+ cam1_reg_gpio Set GPIO for CAM 1 regulator.
+- Default 3 on CM1, 3, and 4S.
+- Default of GPIO expander 5 on CM4, but override
+- switches to normal GPIO.
++ NB override switches to the normal GPIO driver,
++ even if the original was on the GPIO expander.
+
+ cam0_sync Enable a GPIO to reflect frame sync from CSI0,
+ going high on frame start, and low on frame end.
diff --git a/target/linux/bcm27xx/patches-6.6/950-1164-spi-dt-bindings-Add-RPI-RP2040-GPIO-Bridge.patch b/target/linux/bcm27xx/patches-6.6/950-1164-spi-dt-bindings-Add-RPI-RP2040-GPIO-Bridge.patch
new file mode 100644
index 0000000000..487e508ea4
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1164-spi-dt-bindings-Add-RPI-RP2040-GPIO-Bridge.patch
@@ -0,0 +1,108 @@
+From afd949f5f64d224cf7a016ef933257842bc170ab Mon Sep 17 00:00:00 2001
+From: Richard Oliver <richard.oliver@raspberrypi.com>
+Date: Fri, 24 May 2024 10:34:45 +0100
+Subject: [PATCH 1164/1215] spi: dt-bindings: Add RPI RP2040 GPIO Bridge
+
+Add YAML device tree bindings for the Raspberry Pi RP2040 GPIO Bridge.
+
+Signed-off-by: Richard Oliver <richard.oliver@raspberrypi.com>
+---
+ .../spi/raspberrypi,rp2040-gpio-bridge.yaml | 77 +++++++++++++++++++
+ MAINTAINERS | 5 ++
+ 2 files changed, 82 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/spi/raspberrypi,rp2040-gpio-bridge.yaml
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/spi/raspberrypi,rp2040-gpio-bridge.yaml
+@@ -0,0 +1,77 @@
++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/spi/raspberrypi,rp2040-gpio-bridge.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: Raspberry Pi RP2040 GPIO Bridge
++
++maintainers:
++ - Raspberry Pi <kernel-list@raspberrypi.com>
++
++description: |-
++ The Raspberry Pi PR2040 GPIO bridge can be used as a GPIO expander and
++ Tx-only SPI master.
++
++properties:
++ reg:
++ description: I2C slave address
++ const: 0x40
++
++ compatible:
++ const: raspberrypi,rp2040-gpio-bridge
++
++ power-supply:
++ description: Phandle to the regulator that powers the RP2040.
++
++ '#address-cells':
++ const: 1
++
++ '#size-cells':
++ const: 0
++
++ '#gpio-cells':
++ const: 2
++
++ gpio-controller: true
++
++ fast_xfer_requires_i2c_lock:
++ description: Set if I2C bus should be locked during fast transfer.
++
++ fast_xfer_recv_gpio_base:
++ description: RP2040 GPIO base for fast transfer pair.
++
++ fast_xfer-gpios:
++ description: RP1 GPIOs to use for fast transfer clock and data.
++
++required:
++ - reg
++ - compatible
++ - power-supply
++ - '#gpio-cells'
++ - gpio-controller
++
++additionalProperties: false
++
++examples:
++ - |
++ i2c {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ spi@40 {
++ reg = <0x40>;
++ compatible = "raspberrypi,rp2040-gpio-bridge";
++ status = "disabled";
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ power-supply = <&cam_dummy_reg>;
++
++ #gpio-cells = <2>;
++ gpio-controller;
++ };
++ };
++
++...
++
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -18027,6 +18027,11 @@ F: drivers/ras/
+ F: include/linux/ras.h
+ F: include/ras/ras_event.h
+
++RASPBERRY PI RP2040 GPIO BRIDGE DRIVER
++M: Raspberry Pi Kernel Maintenance <kernel-list@raspberrypi.com>
++S: Maintained
++F: Documentation/devicetree/bindings/spi/raspberrypi,rp2040-gpio-bridge.yaml
++
+ RAYLINK/WEBGEAR 802.11 WIRELESS LAN DRIVER
+ L: linux-wireless@vger.kernel.org
+ S: Orphan
diff --git a/target/linux/bcm27xx/patches-6.6/950-1165-spi-Add-a-driver-for-the-RPI-RP2040-GPIO-bridge.patch b/target/linux/bcm27xx/patches-6.6/950-1165-spi-Add-a-driver-for-the-RPI-RP2040-GPIO-bridge.patch
new file mode 100644
index 0000000000..68e2ef6007
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1165-spi-Add-a-driver-for-the-RPI-RP2040-GPIO-bridge.patch
@@ -0,0 +1,1288 @@
+From 99ae83f1944f47d4338ef7a6f02536927fc6ce57 Mon Sep 17 00:00:00 2001
+From: Richard Oliver <richard.oliver@raspberrypi.com>
+Date: Tue, 21 May 2024 13:47:23 +0100
+Subject: [PATCH 1165/1215] spi: Add a driver for the RPI RP2040 GPIO bridge
+
+The Raspberry Pi RP2040 GPIO bridge is an I2C-attached device exposing
+both a Tx-only SPI controller, and a GPIO controller.
+
+Due to the relative difference in transfer rates between standard-mode
+I2C and SPI, the GPIO bridge makes use of 12 MiB of non-volatile storage
+to cache repeated transfers. This cache is arranged in ~8 KiB blocks and
+is addressed by the MD5 digest of the data contained therein.
+
+Optionally, this driver is able to take advantage of Raspberry Pi RP1
+GPIOs to achieve faster than I2C data transfer rates.
+
+Signed-off-by: Richard Oliver <richard.oliver@raspberrypi.com>
+---
+ MAINTAINERS | 1 +
+ drivers/spi/Kconfig | 12 +
+ drivers/spi/Makefile | 1 +
+ drivers/spi/spi-rp2040-gpio-bridge.c | 1219 ++++++++++++++++++++++++++
+ 4 files changed, 1233 insertions(+)
+ create mode 100644 drivers/spi/spi-rp2040-gpio-bridge.c
+
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -18031,6 +18031,7 @@ RASPBERRY PI RP2040 GPIO BRIDGE DRIVER
+ M: Raspberry Pi Kernel Maintenance <kernel-list@raspberrypi.com>
+ S: Maintained
+ F: Documentation/devicetree/bindings/spi/raspberrypi,rp2040-gpio-bridge.yaml
++F: drivers/spi/spi-rp2040-gpio-bridge.c
+
+ RAYLINK/WEBGEAR 802.11 WIRELESS LAN DRIVER
+ L: linux-wireless@vger.kernel.org
+--- a/drivers/spi/Kconfig
++++ b/drivers/spi/Kconfig
+@@ -846,6 +846,18 @@ config SPI_RB4XX
+ help
+ SPI controller driver for the Mikrotik RB4xx series boards.
+
++config SPI_RP2040_GPIO_BRIDGE
++ tristate "Raspberry Pi RP2040 GPIO Bridge"
++ depends on I2C && SPI && GPIOLIB
++ help
++ Support for the Raspberry Pi RP2040 GPIO bridge.
++
++ This driver provides support for the Raspberry Pi PR2040 GPIO bridge.
++ It can be used as a GPIO expander and a Tx-only SPI master.
++
++ Optionally, this driver is able to take advantage of Raspberry Pi RP1
++ GPIOs to achieve faster than I2C data transfer rates.
++
+ config SPI_RPCIF
+ tristate "Renesas RPC-IF SPI driver"
+ depends on RENESAS_RPCIF
+--- a/drivers/spi/Makefile
++++ b/drivers/spi/Makefile
+@@ -115,6 +115,7 @@ obj-$(CONFIG_SPI_ROCKCHIP) += spi-rockc
+ obj-$(CONFIG_SPI_ROCKCHIP_SFC) += spi-rockchip-sfc.o
+ obj-$(CONFIG_SPI_RB4XX) += spi-rb4xx.o
+ obj-$(CONFIG_MACH_REALTEK_RTL) += spi-realtek-rtl.o
++obj-$(CONFIG_SPI_RP2040_GPIO_BRIDGE) += spi-rp2040-gpio-bridge.o
+ obj-$(CONFIG_SPI_RPCIF) += spi-rpc-if.o
+ obj-$(CONFIG_SPI_RSPI) += spi-rspi.o
+ obj-$(CONFIG_SPI_RZV2M_CSI) += spi-rzv2m-csi.o
+--- /dev/null
++++ b/drivers/spi/spi-rp2040-gpio-bridge.c
+@@ -0,0 +1,1219 @@
++// SPDX-License-Identifier: GPL-2.0+
++/*
++ * RP2040 GPIO Bridge
++ *
++ * Copyright (C) 2023, 2024, Raspberry Pi Ltd
++ */
++
++#include <crypto/hash.h>
++#include <linux/crypto.h>
++#include <linux/delay.h>
++#include <linux/firmware.h>
++#include <linux/gpio/driver.h>
++#include <linux/i2c.h>
++#include <linux/kernel.h>
++#include <linux/minmax.h>
++#include <linux/of_address.h>
++#include <linux/pm_runtime.h>
++#include <linux/spi/spi.h>
++#include <linux/stddef.h>
++#include <linux/types.h>
++
++#define MODULE_NAME "rp2040-gpio-bridge"
++
++#define I2C_RETRIES 4U
++
++#define ONE_KIB 1024U
++#define MD5_SUFFIX_SIZE 9U
++
++#define RP2040_GBDG_FLASH_BLOCK_SIZE (8U * ONE_KIB)
++#define RP2040_GBDG_BLOCK_SIZE (RP2040_GBDG_FLASH_BLOCK_SIZE - MD5_SUFFIX_SIZE)
++
++/*
++ * 1MiB transfer size is an arbitrary limit
++ * Max value is 4173330 (using a single manifest)
++ */
++#define MAX_TRANSFER_SIZE (1024U * ONE_KIB)
++
++#define HALF_BUFFER (4U * ONE_KIB)
++
++#define STATUS_SIZE 4
++#define MD5_DIGEST_SIZE 16
++#define VERSION_SIZE 4
++#define ID_SIZE 8
++#define TOTAL_RD_HDR_SIZE \
++ (STATUS_SIZE + MD5_DIGEST_SIZE + VERSION_SIZE + ID_SIZE)
++
++struct rp2040_gbdg_device_info {
++ u8 md5[MD5_DIGEST_SIZE];
++ u64 id;
++ u32 version;
++ u32 status;
++};
++
++static_assert(sizeof(struct rp2040_gbdg_device_info) == TOTAL_RD_HDR_SIZE);
++
++#define MANIFEST_UNIT_SIZE 16
++static_assert(MD5_DIGEST_SIZE == MANIFEST_UNIT_SIZE);
++#define MANIFEST_HEADER_UNITS 1
++#define MANIFEST_DATA_UNITS \
++ DIV_ROUND_UP(MAX_TRANSFER_SIZE, RP2040_GBDG_BLOCK_SIZE)
++
++#define STATUS_BUSY 0x01
++
++#define DIRECT_PREFIX 0x00
++#define DIRECT_CMD_CS 0x07
++#define DIRECT_CMD_EMIT 0x08
++
++#define WRITE_DATA_PREFIX 0x80
++#define WRITE_DATA_PREFIX_SIZE 1
++
++#define FIXED_SIZE_CMD_PREFIX 0x81
++
++#define WRITE_DATA_UPPER_PREFIX 0x82
++#define WRITE_DATA_UPPER_PREFIX_SIZE 1
++
++#define NUM_GPIO 24
++
++enum rp2040_gbdg_fixed_size_commands {
++ /* 10-byte commands */
++ CMD_SAVE_CACHE = 0x07,
++ CMD_SEND_RB = 0x08,
++ CMD_GPIO_ST_CL = 0x0b,
++ CMD_GPIO_OE = 0x0c,
++ CMD_DAT_RECV = 0x0d,
++ CMD_DAT_EMIT = 0x0e,
++ /* 18-byte commands */
++ CMD_READ_CSUM = 0x11,
++ CMD_SEND_MANI = 0x13,
++};
++
++struct rp2040_gbdg {
++ struct spi_controller *controller;
++
++ struct i2c_client *client;
++ struct crypto_shash *shash;
++ struct shash_desc *shash_desc;
++
++ struct regulator *regulator;
++
++ struct gpio_chip gc;
++ u32 gpio_requested;
++ u32 gpio_direction;
++
++ bool fast_xfer_requires_i2c_lock;
++ struct gpio_descs *fast_xfer_gpios;
++ u32 fast_xfer_recv_gpio_base;
++ u8 fast_xfer_data_index;
++ u8 fast_xfer_clock_index;
++ void __iomem *gpio_base;
++ void __iomem *rio_base;
++
++ bool bypass_cache;
++
++ u8 buffer[2 + HALF_BUFFER];
++ u8 manifest_prep[(MANIFEST_HEADER_UNITS + MANIFEST_DATA_UNITS) *
++ MANIFEST_UNIT_SIZE];
++};
++
++static int rp2040_gbdg_gpio_dir_in(struct gpio_chip *gc, unsigned int offset);
++static void rp2040_gbdg_gpio_set(struct gpio_chip *gc, unsigned int offset,
++ int value);
++static int rp2040_gbdg_fast_xfer(struct rp2040_gbdg *priv_data, const u8 *data,
++ size_t len);
++
++static int rp2040_gbdg_rp1_calc_offsets(u8 gpio, size_t *bank_offset,
++ u8 *shift_offset)
++{
++ if (!bank_offset || !shift_offset || gpio >= 54)
++ return -EINVAL;
++ if (gpio < 28) {
++ *bank_offset = 0x0000;
++ *shift_offset = gpio;
++ } else if (gpio < 34) {
++ *bank_offset = 0x4000;
++ *shift_offset = gpio - 28;
++ } else {
++ *bank_offset = 0x8000;
++ *shift_offset = gpio - 34;
++ }
++
++ return 0;
++}
++
++static int rp2040_gbdg_calc_mux_offset(u8 gpio, size_t *offset)
++{
++ size_t bank_offset;
++ u8 shift_offset;
++ int ret;
++
++ ret = rp2040_gbdg_rp1_calc_offsets(gpio, &bank_offset, &shift_offset);
++ if (ret)
++ return ret;
++ *offset = bank_offset + shift_offset * 8 + 0x4;
++
++ return 0;
++}
++
++static int rp2040_gbdg_rp1_read_mux(struct rp2040_gbdg *priv_data, u8 gpio,
++ u32 *data)
++{
++ size_t offset;
++ int ret;
++
++ ret = rp2040_gbdg_calc_mux_offset(gpio, &offset);
++ if (ret)
++ return ret;
++
++ *data = readl(priv_data->gpio_base + offset);
++
++ return 0;
++}
++
++static int rp2040_gbdg_rp1_write_mux(struct rp2040_gbdg *priv_data, u8 gpio,
++ u32 val)
++{
++ size_t offset;
++ int ret;
++
++ ret = rp2040_gbdg_calc_mux_offset(gpio, &offset);
++ if (ret)
++ return ret;
++
++ writel(val, priv_data->gpio_base + offset);
++
++ return 0;
++}
++
++static size_t rp2040_gbdg_max_transfer_size(struct spi_device *spi)
++{
++ return MAX_TRANSFER_SIZE;
++}
++
++static int rp2040_gbdg_get_device_info(struct i2c_client *client,
++ struct rp2040_gbdg_device_info *info)
++{
++ u8 buf[TOTAL_RD_HDR_SIZE];
++ u8 retries = I2C_RETRIES;
++ u8 *read_pos = buf;
++ size_t field_size;
++ int ret;
++
++ do {
++ ret = i2c_master_recv(client, buf, sizeof(buf));
++ if (!retries--)
++ break;
++ } while (ret == -ETIMEDOUT);
++
++ if (ret != sizeof(buf))
++ return ret < 0 ? ret : -EIO;
++
++ field_size = sizeof_field(struct rp2040_gbdg_device_info, status);
++ memcpy(&info->status, read_pos, field_size);
++ read_pos += field_size;
++
++ field_size = sizeof_field(struct rp2040_gbdg_device_info, md5);
++ memcpy(&info->md5, read_pos, field_size);
++ read_pos += field_size;
++
++ field_size = sizeof_field(struct rp2040_gbdg_device_info, version);
++ memcpy(&info->version, read_pos, field_size);
++ read_pos += field_size;
++
++ field_size = sizeof_field(struct rp2040_gbdg_device_info, id);
++ memcpy(&info->id, read_pos, field_size);
++
++ return 0;
++}
++
++static int rp2040_gbdg_poll_device_info(struct i2c_client *client,
++ struct rp2040_gbdg_device_info *info)
++{
++ struct rp2040_gbdg_device_info itnl;
++ int ret;
++
++ itnl.status = STATUS_BUSY;
++
++ while (itnl.status & STATUS_BUSY) {
++ ret = rp2040_gbdg_get_device_info(client, &itnl);
++ if (ret)
++ return ret;
++ }
++ memcpy(info, &itnl, sizeof(itnl));
++
++ return 0;
++}
++
++static int rp2040_gbdg_get_buffer_hash(struct i2c_client *client, u8 *md5)
++{
++ struct rp2040_gbdg_device_info info;
++ int ret;
++
++ ret = rp2040_gbdg_poll_device_info(client, &info);
++ if (ret)
++ return ret;
++
++ memcpy(md5, info.md5, MD5_DIGEST_SIZE);
++
++ return 0;
++}
++
++static int rp2040_gbdg_wait_until_free(struct i2c_client *client, u8 *status)
++{
++ struct rp2040_gbdg_device_info info;
++ int ret;
++
++ ret = rp2040_gbdg_poll_device_info(client, &info);
++ if (ret)
++ return ret;
++
++ if (status)
++ *status = info.status;
++
++ return 0;
++}
++
++static int rp2040_gbdg_i2c_send(struct i2c_client *client, const u8 *buf,
++ size_t len)
++{
++ u8 retries = I2C_RETRIES;
++ int ret;
++
++ ret = rp2040_gbdg_wait_until_free(client, NULL);
++ if (ret) {
++ dev_err(&client->dev,
++ "%s() rp2040_gbdg_wait_until_free failed\n", __func__);
++ return ret;
++ }
++
++ do {
++ ret = i2c_master_send(client, buf, len);
++ if (!retries--)
++ break;
++ } while (ret == -ETIMEDOUT);
++
++ if (ret != len) {
++ dev_err(&client->dev, "%s() i2c_master_send returned %d\n",
++ __func__, ret);
++ return ret < 0 ? ret : -EIO;
++ }
++
++ return 0;
++}
++
++static int rp2040_gbdg_10byte_cmd(struct i2c_client *client, u8 cmd, u32 addr,
++ u32 len)
++{
++ u8 buffer[10];
++
++ buffer[0] = FIXED_SIZE_CMD_PREFIX;
++ buffer[1] = cmd;
++ memcpy(&buffer[2], &addr, sizeof(addr));
++ memcpy(&buffer[6], &len, sizeof(len));
++
++ return rp2040_gbdg_i2c_send(client, buffer, sizeof(buffer));
++}
++
++static int rp2040_gbdg_18byte_cmd(struct i2c_client *client, u8 cmd,
++ const u8 *digest)
++{
++ u8 buffer[18];
++
++ buffer[0] = FIXED_SIZE_CMD_PREFIX;
++ buffer[1] = cmd;
++ memcpy(&buffer[2], digest, MD5_DIGEST_SIZE);
++
++ return rp2040_gbdg_i2c_send(client, buffer, sizeof(buffer));
++}
++
++static int rp2040_gbdg_block_hash(struct rp2040_gbdg *priv_data, const u8 *data,
++ size_t len, u8 *out)
++{
++ size_t remaining = RP2040_GBDG_BLOCK_SIZE;
++ size_t pad;
++ int ret;
++
++ static const u8 padding[64] = {
++ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
++ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
++ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
++ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
++ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
++ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
++ 0xFF, 0xFF, 0xFF, 0xFF,
++ };
++
++ if (len > RP2040_GBDG_BLOCK_SIZE) {
++ return -EMSGSIZE;
++ } else if (len == RP2040_GBDG_BLOCK_SIZE) {
++ return crypto_shash_digest(priv_data->shash_desc, data, len,
++ out);
++ } else {
++ ret = crypto_shash_init(priv_data->shash_desc);
++ if (ret)
++ return ret;
++
++ ret = crypto_shash_update(priv_data->shash_desc, data, len);
++ if (ret)
++ return ret;
++ remaining -= len;
++
++ /* Pad up-to a 64-byte boundary, unless that takes us over. */
++ pad = round_up(len, 64);
++ if (pad != len && pad < RP2040_GBDG_BLOCK_SIZE) {
++ ret = crypto_shash_update(priv_data->shash_desc,
++ padding, pad - len);
++ if (ret)
++ return ret;
++ remaining -= (pad - len);
++ }
++
++ /* Pad up-to RP2040_GBDG_BLOCK_SIZE in, preferably, 64-byte chunks */
++ while (remaining) {
++ pad = min_t(size_t, remaining, (size_t)64U);
++ ret = crypto_shash_update(priv_data->shash_desc,
++ padding, pad);
++ if (ret)
++ return ret;
++ remaining -= pad;
++ }
++ return crypto_shash_final(priv_data->shash_desc, out);
++ }
++}
++
++static int rp2040_gbdg_set_remote_buffer_fast(struct rp2040_gbdg *priv_data,
++ const u8 *data, unsigned int len)
++{
++ struct i2c_client *client = priv_data->client;
++ int ret;
++
++ if (len > RP2040_GBDG_BLOCK_SIZE)
++ return -EMSGSIZE;
++ if (!priv_data->fast_xfer_gpios)
++ return -EIO;
++
++ ret = rp2040_gbdg_10byte_cmd(client, CMD_DAT_RECV,
++ priv_data->fast_xfer_recv_gpio_base, len);
++ if (ret) {
++ dev_err(&client->dev, "%s() failed to enter fast data mode\n",
++ __func__);
++ return ret;
++ }
++
++ return rp2040_gbdg_fast_xfer(priv_data, data, len);
++}
++
++static int rp2040_gbdg_set_remote_buffer_i2c(struct rp2040_gbdg *priv_data,
++ const u8 *data, unsigned int len)
++{
++ struct i2c_client *client = priv_data->client;
++ unsigned int write_len;
++ int ret;
++
++ if (len > RP2040_GBDG_BLOCK_SIZE)
++ return -EMSGSIZE;
++
++ priv_data->buffer[0] = WRITE_DATA_PREFIX;
++ write_len = min(len, HALF_BUFFER);
++ memcpy(&priv_data->buffer[1], data, write_len);
++
++ ret = rp2040_gbdg_i2c_send(client, priv_data->buffer, write_len + 1);
++ if (ret)
++ return ret;
++
++ len -= write_len;
++ data += write_len;
++
++ if (!len)
++ return 0;
++
++ priv_data->buffer[0] = WRITE_DATA_UPPER_PREFIX;
++ memcpy(&priv_data->buffer[1], data, len);
++ ret = rp2040_gbdg_i2c_send(client, priv_data->buffer, len + 1);
++
++ return ret;
++}
++
++static int rp2040_gbdg_set_remote_buffer(struct rp2040_gbdg *priv_data,
++ const u8 *data, unsigned int len)
++{
++ if (priv_data->fast_xfer_gpios)
++ return rp2040_gbdg_set_remote_buffer_fast(priv_data, data, len);
++ else
++ return rp2040_gbdg_set_remote_buffer_i2c(priv_data, data, len);
++}
++
++/* Loads data by checksum if available or resorts to sending byte-by-byte */
++static int rp2040_gbdg_load_block_remote(struct rp2040_gbdg *priv_data,
++ const void *data, unsigned int len,
++ u8 *digest, bool persist)
++{
++ u8 ascii_digest[MD5_DIGEST_SIZE * 2 + 1] = { 0 };
++ struct i2c_client *client = priv_data->client;
++ u8 remote_digest[MD5_DIGEST_SIZE];
++ u8 local_digest[MD5_DIGEST_SIZE];
++ int ret;
++
++ if (len > RP2040_GBDG_BLOCK_SIZE)
++ return -EMSGSIZE;
++
++ ret = rp2040_gbdg_block_hash(priv_data, data, len, local_digest);
++ if (ret)
++ return ret;
++
++ if (digest)
++ memcpy(digest, local_digest, MD5_DIGEST_SIZE);
++
++ /* Check if the RP2040 has the data already */
++ ret = rp2040_gbdg_18byte_cmd(client, CMD_READ_CSUM, local_digest);
++ if (ret)
++ return ret;
++
++ ret = rp2040_gbdg_get_buffer_hash(client, remote_digest);
++ if (ret)
++ return ret;
++
++ if (memcmp(local_digest, remote_digest, MD5_DIGEST_SIZE)) {
++ bin2hex(ascii_digest, local_digest, MD5_DIGEST_SIZE);
++ dev_info(&client->dev, "%s() device missing data: %s\n",
++ __func__, ascii_digest);
++ /*
++ * N.B. We're fine to send (the potentially shorter) transfer->len
++ * number of bytes here as the RP2040 will pad with 0xFF up to buffer
++ * size once we stop sending.
++ */
++ ret = rp2040_gbdg_set_remote_buffer(priv_data, data, len);
++ if (ret)
++ return ret;
++
++ /* Make sure the data actually arrived. */
++ ret = rp2040_gbdg_get_buffer_hash(client, remote_digest);
++ if (memcmp(local_digest, remote_digest, MD5_DIGEST_SIZE)) {
++ dev_err(&priv_data->client->dev,
++ "%s() unable to send data to device\n",
++ __func__);
++ return -EREMOTEIO;
++ }
++
++ if (persist) {
++ dev_info(&client->dev,
++ "%s() sent missing data to device, saving\n",
++ __func__);
++ ret = rp2040_gbdg_10byte_cmd(client, CMD_SAVE_CACHE, 0,
++ 0);
++ if (ret)
++ return ret;
++ }
++ }
++
++ return 0;
++}
++
++static int rp2040_gbdg_transfer_block(struct rp2040_gbdg *priv_data,
++ const void *data, unsigned int len)
++{
++ struct i2c_client *client = priv_data->client;
++ int ret;
++
++ if (len > RP2040_GBDG_BLOCK_SIZE)
++ return -EMSGSIZE;
++
++ ret = rp2040_gbdg_load_block_remote(priv_data, data, len, NULL, true);
++ if (ret)
++ return ret;
++
++ /* Remote rambuffer now has correct contents, send it */
++ ret = rp2040_gbdg_10byte_cmd(client, CMD_SEND_RB, 0, len);
++ if (ret)
++ return ret;
++
++ /*
++ * Wait for data to have actually completed sending as we may be de-asserting CS too quickly
++ * otherwise.
++ */
++ ret = rp2040_gbdg_wait_until_free(client, NULL);
++ if (ret)
++ return ret;
++
++ return 0;
++}
++
++static int rp2040_gbdg_transfer_manifest(struct rp2040_gbdg *priv_data,
++ const u8 *data, unsigned int len)
++{
++ struct i2c_client *client = priv_data->client;
++ static const char magic[] = "DATA_MANFST";
++ unsigned int remaining = len;
++ const u32 data_length = len;
++ u8 digest[MD5_DIGEST_SIZE];
++ u8 *digest_write_pos;
++ u8 status;
++ int ret;
++
++ memcpy(priv_data->manifest_prep, magic, sizeof(magic));
++ memcpy(priv_data->manifest_prep + sizeof(magic), &data_length,
++ sizeof(data_length));
++ digest_write_pos =
++ priv_data->manifest_prep + sizeof(magic) + sizeof(data_length);
++
++ while (remaining) {
++ unsigned int size = min(remaining, RP2040_GBDG_BLOCK_SIZE);
++
++ ret = rp2040_gbdg_block_hash(priv_data, data, size,
++ digest_write_pos);
++ if (ret)
++ return ret;
++
++ remaining -= size;
++ data += size;
++ digest_write_pos += MD5_DIGEST_SIZE;
++ }
++
++ ret = rp2040_gbdg_load_block_remote(
++ priv_data, priv_data->manifest_prep,
++ digest_write_pos - priv_data->manifest_prep, digest, true);
++ if (ret)
++ return ret;
++
++ dev_info(&client->dev, "%s() issue CMD_SEND_MANI\n", __func__);
++ ret = rp2040_gbdg_18byte_cmd(client, CMD_SEND_MANI, digest);
++ if (ret)
++ return ret;
++
++ ret = rp2040_gbdg_wait_until_free(client, &status);
++ if (ret)
++ return ret;
++
++ dev_info(&client->dev, "%s() SEND_MANI response: %02x\n", __func__,
++ status);
++
++ return status;
++}
++
++/* Precondition: correctly initialised fast_xfer_*, gpio_base, rio_base */
++static int rp2040_gbdg_fast_xfer(struct rp2040_gbdg *priv_data, const u8 *data,
++ size_t len)
++{
++ struct i2c_client *client = priv_data->client;
++ void __iomem *clock_toggle;
++ void __iomem *data_set;
++ size_t clock_bank;
++ size_t data_bank;
++ u8 clock_offset;
++ u8 data_offset;
++ u32 clock_mux;
++ u32 data_mux;
++
++ if (priv_data->fast_xfer_requires_i2c_lock)
++ i2c_lock_bus(client->adapter, I2C_LOCK_ROOT_ADAPTER);
++
++ rp2040_gbdg_rp1_read_mux(priv_data, priv_data->fast_xfer_data_index,
++ &data_mux);
++ rp2040_gbdg_rp1_read_mux(priv_data, priv_data->fast_xfer_clock_index,
++ &clock_mux);
++
++ gpiod_direction_output(priv_data->fast_xfer_gpios->desc[0], 1);
++ gpiod_direction_output(priv_data->fast_xfer_gpios->desc[1], 0);
++
++ rp2040_gbdg_rp1_calc_offsets(priv_data->fast_xfer_data_index,
++ &data_bank, &data_offset);
++ rp2040_gbdg_rp1_calc_offsets(priv_data->fast_xfer_clock_index,
++ &clock_bank, &clock_offset);
++
++ data_set = priv_data->rio_base + data_bank + 0x2000; /* SET offset */
++ clock_toggle =
++ priv_data->rio_base + clock_bank + 0x1000; /* XOR offset */
++
++ while (len--) {
++ /* MSB first ordering */
++ u32 d = ~(*data++) << 4U;
++ /*
++ * Clock out each bit of data, LSB first
++ * (DDR, achieves approx 5 Mbps)
++ */
++ for (size_t i = 0; i < 8; i++) {
++ /* Branchless set/clr data */
++ writel(1 << data_offset,
++ data_set + ((d <<= 1) & 0x1000) /* CLR offset */
++ );
++
++ /* Toggle the clock */
++ writel(1 << clock_offset, clock_toggle);
++ }
++ }
++
++ rp2040_gbdg_rp1_write_mux(priv_data, priv_data->fast_xfer_data_index,
++ data_mux);
++ rp2040_gbdg_rp1_write_mux(priv_data, priv_data->fast_xfer_clock_index,
++ clock_mux);
++
++ if (priv_data->fast_xfer_requires_i2c_lock)
++ i2c_unlock_bus(client->adapter, I2C_LOCK_ROOT_ADAPTER);
++
++ return 0;
++}
++
++static int rp2040_gbdg_transfer_bypass(struct rp2040_gbdg *priv_data,
++ const u8 *data, unsigned int length)
++{
++ int ret;
++ u8 *buf;
++
++ if (priv_data->fast_xfer_gpios) {
++ ret = rp2040_gbdg_10byte_cmd(
++ priv_data->client, CMD_DAT_EMIT,
++ priv_data->fast_xfer_recv_gpio_base, length);
++ return ret ? ret :
++ rp2040_gbdg_fast_xfer(priv_data, data, length);
++ }
++
++ buf = priv_data->buffer;
++
++ while (length) {
++ unsigned int xfer = min(length, HALF_BUFFER);
++
++ buf[0] = DIRECT_PREFIX;
++ buf[1] = DIRECT_CMD_EMIT;
++ memcpy(&buf[2], data, xfer);
++ ret = rp2040_gbdg_i2c_send(priv_data->client, buf, xfer + 2);
++ if (ret)
++ return ret;
++ length -= xfer;
++ data += xfer;
++ }
++
++ return 0;
++}
++
++static int rp2040_gbdg_transfer_cached(struct rp2040_gbdg *priv_data,
++ const u8 *data, unsigned int length)
++{
++ int ret;
++
++ /*
++ * Caching mechanism divides data into '8KiB - 9' (8183 byte)
++ * 'RP2040_GBDG_BLOCK_SIZE' blocks.
++ *
++ * If there's a large amount of data to send, instead, attempt to make use
++ * of a manifest.
++ */
++ if (length > (2 * RP2040_GBDG_BLOCK_SIZE)) {
++ if (!rp2040_gbdg_transfer_manifest(priv_data, data, length))
++ return 0;
++ }
++
++ while (length) {
++ unsigned int xfer = min(length, RP2040_GBDG_BLOCK_SIZE);
++
++ ret = rp2040_gbdg_transfer_block(priv_data, data, xfer);
++ if (ret)
++ return ret;
++ length -= xfer;
++ data += xfer;
++ }
++
++ return 0;
++}
++
++static int rp2040_gbdg_transfer_one(struct spi_controller *ctlr,
++ struct spi_device *spi,
++ struct spi_transfer *transfer)
++{
++ /* All transfers are performed in a synchronous manner. As such, return '0'
++ * on success or -ve on failure. (Returning +ve indicates async xfer)
++ */
++
++ struct rp2040_gbdg *priv_data = spi_controller_get_devdata(ctlr);
++
++ if (priv_data->bypass_cache) {
++ return rp2040_gbdg_transfer_bypass(priv_data, transfer->tx_buf,
++ transfer->len);
++ } else {
++ return rp2040_gbdg_transfer_cached(priv_data, transfer->tx_buf,
++ transfer->len);
++ }
++}
++
++static void rp2040_gbdg_set_cs(struct spi_device *spi, bool enable)
++{
++ static const char disable_cs[] = { DIRECT_PREFIX, DIRECT_CMD_CS, 0x00 };
++ static const char enable_cs[] = { DIRECT_PREFIX, DIRECT_CMD_CS, 0x10 };
++ struct rp2040_gbdg *p_data;
++
++ p_data = spi_controller_get_devdata(spi->controller);
++
++ /*
++ * 'enable' is inverted and instead describes the logic level of an
++ * active-low CS.
++ */
++ rp2040_gbdg_i2c_send(p_data->client, enable ? disable_cs : enable_cs,
++ 3);
++}
++
++static int rp2040_gbdg_gpio_request(struct gpio_chip *gc, unsigned int offset)
++{
++ struct rp2040_gbdg *priv_data = gpiochip_get_data(gc);
++ u32 pattern;
++ int ret;
++
++ if (offset >= NUM_GPIO)
++ return -EINVAL;
++
++ pattern = (1 << (offset + 8));
++ if (pattern & priv_data->gpio_requested)
++ return -EBUSY;
++
++ /* Resume if previously no gpio requested */
++ if (!priv_data->gpio_requested) {
++ ret = pm_runtime_resume_and_get(&priv_data->client->dev);
++ if (ret) {
++ dev_err(&priv_data->client->dev,
++ "%s(%u) unable to resume\n", __func__, offset);
++ return ret;
++ }
++ }
++
++ priv_data->gpio_requested |= pattern;
++
++ return 0;
++}
++
++static void rp2040_gbdg_gpio_free(struct gpio_chip *gc, unsigned int offset)
++{
++ struct rp2040_gbdg *priv_data = gpiochip_get_data(gc);
++ u32 pattern;
++ int ret;
++
++ if (offset >= NUM_GPIO || !priv_data->gpio_requested)
++ return;
++
++ pattern = (1 << (offset + 8));
++
++ priv_data->gpio_requested &= ~pattern;
++ rp2040_gbdg_gpio_dir_in(gc, offset);
++ rp2040_gbdg_gpio_set(gc, offset, 0);
++
++ if (!priv_data->gpio_requested) {
++ ret = pm_runtime_put_autosuspend(&priv_data->client->dev);
++ if (ret) {
++ dev_err(&priv_data->client->dev,
++ "%s(%u) unable to put_autosuspend\n", __func__,
++ offset);
++ }
++ }
++}
++
++static int rp2040_gbdg_gpio_get_direction(struct gpio_chip *gc,
++ unsigned int offset)
++{
++ struct rp2040_gbdg *priv_data = gpiochip_get_data(gc);
++
++ if (offset >= NUM_GPIO)
++ return -EINVAL;
++
++ return (priv_data->gpio_direction & (1 << (offset + 8))) ?
++ GPIO_LINE_DIRECTION_IN :
++ GPIO_LINE_DIRECTION_OUT;
++}
++
++static int rp2040_gbdg_gpio_dir_in(struct gpio_chip *gc, unsigned int offset)
++{
++ struct rp2040_gbdg *priv_data = gpiochip_get_data(gc);
++ struct i2c_client *client = priv_data->client;
++
++ if (offset >= NUM_GPIO)
++ return -EINVAL;
++
++ priv_data->gpio_direction |= (1 << (offset + 8));
++
++ return rp2040_gbdg_10byte_cmd(client, CMD_GPIO_OE,
++ ~priv_data->gpio_direction,
++ priv_data->gpio_direction);
++}
++
++static int rp2040_gbdg_gpio_dir_out(struct gpio_chip *gc, unsigned int offset,
++ int value)
++{
++ struct rp2040_gbdg *priv_data = gpiochip_get_data(gc);
++ struct i2c_client *client = priv_data->client;
++ u32 pattern;
++ int ret;
++
++ if (offset >= NUM_GPIO)
++ return -EINVAL;
++
++ pattern = (1 << (offset + 8));
++
++ ret = rp2040_gbdg_10byte_cmd(client, CMD_GPIO_ST_CL,
++ value ? pattern : 0, !value ? pattern : 0);
++ if (ret) {
++ dev_err(&client->dev, "%s(%u, %d) could not ST_CL\n", __func__,
++ offset, value);
++ return ret;
++ }
++
++ priv_data->gpio_direction &= ~pattern;
++ ret = rp2040_gbdg_10byte_cmd(client, CMD_GPIO_OE,
++ ~priv_data->gpio_direction,
++ priv_data->gpio_direction);
++
++ return ret;
++}
++
++static int rp2040_gbdg_gpio_get(struct gpio_chip *gc, unsigned int offset)
++{
++ struct rp2040_gbdg *priv_data = gpiochip_get_data(gc);
++ struct i2c_client *client = priv_data->client;
++ struct rp2040_gbdg_device_info info;
++ int ret;
++
++ if (offset >= NUM_GPIO)
++ return -EINVAL;
++
++ ret = rp2040_gbdg_get_device_info(client, &info);
++ if (ret)
++ return ret;
++
++ return info.status & (1 << (offset + 8)) ? 1 : 0;
++}
++
++static void rp2040_gbdg_gpio_set(struct gpio_chip *gc, unsigned int offset,
++ int value)
++{
++ struct rp2040_gbdg *priv_data = gpiochip_get_data(gc);
++ struct i2c_client *client = priv_data->client;
++ u32 pattern;
++
++ if (offset >= NUM_GPIO)
++ return;
++
++ pattern = (1 << (offset + 8));
++ rp2040_gbdg_10byte_cmd(client, CMD_GPIO_ST_CL, value ? pattern : 0,
++ !value ? pattern : 0);
++}
++
++static int rp2040_gbdg_get_regulator(struct device *dev,
++ struct rp2040_gbdg *rp2040_gbdg)
++{
++ struct regulator *reg = devm_regulator_get(dev, "power");
++
++ if (IS_ERR(reg))
++ return PTR_ERR(reg);
++
++ rp2040_gbdg->regulator = reg;
++
++ return 0;
++}
++
++static void rp2040_gbdg_parse_dt(struct rp2040_gbdg *rp2040_gbdg)
++{
++ struct i2c_client *client = rp2040_gbdg->client;
++ struct of_phandle_args of_args[2] = { 0 };
++ struct device *dev = &client->dev;
++ struct device_node *dn;
++
++ rp2040_gbdg->bypass_cache =
++ of_property_read_bool(client->dev.of_node, "bypass-cache");
++
++ /* Optionally configure fast_xfer if RP1 is being used */
++ if (of_parse_phandle_with_args(client->dev.of_node, "fast_xfer-gpios",
++ "#gpio-cells", 0, &of_args[0]) ||
++ of_parse_phandle_with_args(client->dev.of_node, "fast_xfer-gpios",
++ "#gpio-cells", 1, &of_args[1])) {
++ dev_info(dev, "Could not parse fast_xfer-gpios phandles\n");
++ goto node_put;
++ }
++
++ if (of_args[0].np != of_args[1].np) {
++ dev_info(
++ dev,
++ "fast_xfer-gpios are not provided by the same controller\n");
++ goto node_put;
++ }
++ dn = of_args[0].np;
++ if (!of_device_is_compatible(dn, "raspberrypi,rp1-gpio")) {
++ dev_info(dev, "fast_xfer-gpios controller is not an rp1\n");
++ goto node_put;
++ }
++ if (of_args[0].args_count != 2 || of_args[1].args_count != 2) {
++ dev_info(dev, "of_args count is %d\n", of_args[0].args_count);
++ goto node_put;
++ }
++
++ if (of_property_read_u32_index(
++ client->dev.of_node, "fast_xfer_recv_gpio_base", 0,
++ &rp2040_gbdg->fast_xfer_recv_gpio_base)) {
++ dev_info(dev, "Could not read fast_xfer_recv_gpio_base\n");
++ goto node_put;
++ }
++
++ rp2040_gbdg->fast_xfer_gpios =
++ devm_gpiod_get_array_optional(dev, "fast_xfer", GPIOD_ASIS);
++ if (!rp2040_gbdg->fast_xfer_gpios) {
++ dev_info(dev, "Could not acquire fast_xfer-gpios\n");
++ goto node_put;
++ }
++
++ rp2040_gbdg->fast_xfer_data_index = of_args[0].args[0];
++ rp2040_gbdg->fast_xfer_clock_index = of_args[1].args[0];
++ rp2040_gbdg->fast_xfer_requires_i2c_lock = of_property_read_bool(
++ client->dev.of_node, "fast_xfer_requires_i2c_lock");
++
++ rp2040_gbdg->gpio_base = of_iomap(dn, 0);
++ if (IS_ERR_OR_NULL(rp2040_gbdg->gpio_base)) {
++ dev_info(&client->dev, "%s() unable to map gpio_base\n",
++ __func__);
++ rp2040_gbdg->gpio_base = NULL;
++ devm_gpiod_put_array(dev, rp2040_gbdg->fast_xfer_gpios);
++ rp2040_gbdg->fast_xfer_gpios = NULL;
++ goto node_put;
++ }
++
++ rp2040_gbdg->rio_base = of_iomap(dn, 1);
++ if (IS_ERR_OR_NULL(rp2040_gbdg->rio_base)) {
++ dev_info(&client->dev, "%s() unable to map rio_base\n",
++ __func__);
++ rp2040_gbdg->rio_base = NULL;
++ iounmap(rp2040_gbdg->gpio_base);
++ rp2040_gbdg->gpio_base = NULL;
++ devm_gpiod_put_array(dev, rp2040_gbdg->fast_xfer_gpios);
++ rp2040_gbdg->fast_xfer_gpios = NULL;
++ goto node_put;
++ }
++
++node_put:
++ if (of_args[0].np)
++ of_node_put(of_args[0].np);
++ if (of_args[1].np)
++ of_node_put(of_args[1].np);
++}
++
++static int rp2040_gbdg_power_off(struct rp2040_gbdg *rp2040_gbdg)
++{
++ struct device *dev = &rp2040_gbdg->client->dev;
++ int ret;
++
++ ret = regulator_disable(rp2040_gbdg->regulator);
++ if (ret) {
++ dev_err(dev, "%s: Could not disable regulator\n", __func__);
++ return ret;
++ }
++
++ return 0;
++}
++
++static int rp2040_gbdg_power_on(struct rp2040_gbdg *rp2040_gbdg)
++{
++ struct device *dev = &rp2040_gbdg->client->dev;
++ int ret;
++
++ ret = regulator_enable(rp2040_gbdg->regulator);
++ if (ret) {
++ dev_err(dev, "%s: Could not enable regulator\n", __func__);
++ return ret;
++ }
++
++ return 0;
++}
++
++static int rp2040_gbdg_probe(struct i2c_client *client)
++{
++ struct rp2040_gbdg_device_info info;
++ struct spi_controller *controller;
++ struct device *dev = &client->dev;
++ struct rp2040_gbdg *rp2040_gbdg;
++ struct device_node *np;
++ int ret;
++
++ np = dev->of_node;
++
++ controller = devm_spi_alloc_master(dev, sizeof(struct rp2040_gbdg));
++ if (!controller)
++ return dev_err_probe(dev, ENOMEM,
++ "could not alloc spi controller\n");
++
++ rp2040_gbdg = spi_controller_get_devdata(controller);
++ i2c_set_clientdata(client, rp2040_gbdg);
++ rp2040_gbdg->controller = controller;
++ rp2040_gbdg->client = client;
++
++ ret = rp2040_gbdg_get_regulator(dev, rp2040_gbdg);
++ if (ret < 0)
++ return dev_err_probe(dev, ret, "Cannot get regulator\n");
++
++ ret = rp2040_gbdg_power_on(rp2040_gbdg);
++ if (ret)
++ return dev_err_probe(dev, ret, "Could not power on device\n");
++
++ pm_runtime_set_active(dev);
++ pm_runtime_get_noresume(dev);
++ pm_runtime_enable(dev);
++ pm_runtime_set_autosuspend_delay(dev, 1000);
++ pm_runtime_use_autosuspend(dev);
++
++ ret = rp2040_gbdg_get_device_info(client, &info);
++ if (ret) {
++ dev_err(dev, "Could not get device info\n");
++ goto err_pm;
++ }
++
++ dev_info(dev, "%s() found dev ID: %llx, fw ver. %u\n", __func__,
++ info.id, info.version);
++
++ rp2040_gbdg->shash = crypto_alloc_shash("md5", 0, 0);
++ if (IS_ERR(rp2040_gbdg->shash)) {
++ ret = PTR_ERR(rp2040_gbdg->shash);
++ dev_err(dev, "Could not allocate shash\n");
++ goto err_pm;
++ }
++
++ if (crypto_shash_digestsize(rp2040_gbdg->shash) != MD5_DIGEST_SIZE) {
++ ret = -EINVAL;
++ dev_err(dev, "error: Unexpected hash digest size\n");
++ goto err_shash;
++ }
++
++ rp2040_gbdg->shash_desc =
++ devm_kmalloc(dev,
++ sizeof(struct shash_desc) +
++ crypto_shash_descsize(rp2040_gbdg->shash),
++ 0);
++
++ if (!rp2040_gbdg->shash_desc) {
++ ret = -ENOMEM;
++ dev_err(dev,
++ "error: Could not allocate memory for shash_desc\n");
++ goto err_shash;
++ }
++ rp2040_gbdg->shash_desc->tfm = rp2040_gbdg->shash;
++
++ controller->bus_num = -1;
++ controller->num_chipselect = 1;
++ controller->mode_bits = SPI_CPOL | SPI_CPHA;
++ controller->bits_per_word_mask = SPI_BPW_MASK(8);
++ controller->min_speed_hz = 35000000;
++ controller->max_speed_hz = 35000000;
++ controller->max_transfer_size = rp2040_gbdg_max_transfer_size;
++ controller->max_message_size = rp2040_gbdg_max_transfer_size;
++ controller->transfer_one = rp2040_gbdg_transfer_one;
++ controller->set_cs = rp2040_gbdg_set_cs;
++
++ controller->dev.of_node = np;
++ controller->auto_runtime_pm = true;
++
++ ret = devm_spi_register_controller(dev, controller);
++ if (ret) {
++ dev_err(dev, "error: Could not register SPI controller\n");
++ goto err_shash;
++ }
++
++ memset(&rp2040_gbdg->gc, 0, sizeof(struct gpio_chip));
++ rp2040_gbdg->gc.parent = dev;
++ rp2040_gbdg->gc.label = MODULE_NAME;
++ rp2040_gbdg->gc.owner = THIS_MODULE;
++ rp2040_gbdg->gc.base = -1;
++ rp2040_gbdg->gc.ngpio = NUM_GPIO;
++
++ rp2040_gbdg->gc.request = rp2040_gbdg_gpio_request;
++ rp2040_gbdg->gc.free = rp2040_gbdg_gpio_free;
++ rp2040_gbdg->gc.get_direction = rp2040_gbdg_gpio_get_direction;
++ rp2040_gbdg->gc.direction_input = rp2040_gbdg_gpio_dir_in;
++ rp2040_gbdg->gc.direction_output = rp2040_gbdg_gpio_dir_out;
++ rp2040_gbdg->gc.get = rp2040_gbdg_gpio_get;
++ rp2040_gbdg->gc.set = rp2040_gbdg_gpio_set;
++ rp2040_gbdg->gc.can_sleep = true;
++
++ rp2040_gbdg->gpio_requested = 0;
++
++ /* Coming out of reset, all GPIOs are inputs */
++ rp2040_gbdg->gpio_direction = ~0;
++
++ ret = devm_gpiochip_add_data(dev, &rp2040_gbdg->gc, rp2040_gbdg);
++ if (ret) {
++ dev_err(dev, "error: Could not add data to gpiochip\n");
++ goto err_shash;
++ }
++
++ rp2040_gbdg_parse_dt(rp2040_gbdg);
++
++ pm_runtime_mark_last_busy(dev);
++ pm_runtime_put_autosuspend(dev);
++
++ return 0;
++
++err_shash:
++ crypto_free_shash(rp2040_gbdg->shash);
++err_pm:
++ pm_runtime_disable(dev);
++ pm_runtime_put_noidle(dev);
++ rp2040_gbdg_power_off(rp2040_gbdg);
++
++ return ret;
++}
++
++static void rp2040_gbdg_remove(struct i2c_client *client)
++{
++ struct rp2040_gbdg *priv_data = i2c_get_clientdata(client);
++
++ crypto_free_shash(priv_data->shash);
++
++ if (priv_data->gpio_base) {
++ iounmap(priv_data->gpio_base);
++ priv_data->gpio_base = NULL;
++ }
++ if (priv_data->rio_base) {
++ iounmap(priv_data->rio_base);
++ priv_data->rio_base = NULL;
++ }
++
++ pm_runtime_disable(&client->dev);
++ if (!pm_runtime_status_suspended(&client->dev))
++ rp2040_gbdg_power_off(priv_data);
++ pm_runtime_set_suspended(&client->dev);
++}
++
++static const struct i2c_device_id rp2040_gbdg_id[] = {
++ { "rp2040-gpio-bridge", 0 },
++ {},
++};
++MODULE_DEVICE_TABLE(i2c, rp2040_gbdg_id);
++
++static const struct of_device_id rp2040_gbdg_of_match[] = {
++ { .compatible = "raspberrypi,rp2040-gpio-bridge" },
++ {},
++};
++MODULE_DEVICE_TABLE(of, rp2040_gbdg_of_match);
++
++static int rp2040_gbdg_runtime_suspend(struct device *dev)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++
++ return rp2040_gbdg_power_off(i2c_get_clientdata(client));
++}
++
++static int rp2040_gbdg_runtime_resume(struct device *dev)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++
++ return rp2040_gbdg_power_on(i2c_get_clientdata(client));
++}
++
++static const struct dev_pm_ops rp2040_gbdg_pm_ops = { SET_RUNTIME_PM_OPS(
++ rp2040_gbdg_runtime_suspend, rp2040_gbdg_runtime_resume, NULL) };
++
++static struct i2c_driver rp2040_gbdg_driver = {
++ .driver = {
++ .name = MODULE_NAME,
++ .of_match_table = of_match_ptr(rp2040_gbdg_of_match),
++ .pm = &rp2040_gbdg_pm_ops,
++ },
++ .probe = rp2040_gbdg_probe,
++ .remove = rp2040_gbdg_remove,
++ .id_table = rp2040_gbdg_id,
++};
++
++module_i2c_driver(rp2040_gbdg_driver);
++
++MODULE_AUTHOR("Richard Oliver <richard.oliver@raspberrypi.com>");
++MODULE_DESCRIPTION("Raspberry Pi RP2040 GPIO Bridge");
++MODULE_LICENSE("GPL");
diff --git a/target/linux/bcm27xx/patches-6.6/950-1166-dmaengine-dw-axi-dmac-Honour-snps-block-size.patch b/target/linux/bcm27xx/patches-6.6/950-1166-dmaengine-dw-axi-dmac-Honour-snps-block-size.patch
new file mode 100644
index 0000000000..85b1cf6448
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1166-dmaengine-dw-axi-dmac-Honour-snps-block-size.patch
@@ -0,0 +1,52 @@
+From 475cddaba6b02584157e1c128a5a6858770a3d06 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Wed, 10 Jul 2024 14:47:17 +0100
+Subject: [PATCH 1166/1215] dmaengine: dw-axi-dmac: Honour snps,block-size
+
+The snps,block-size DT property declares the maximum block size for each
+channel of the dw-axi-dmac. However, the driver ignores these when
+setting max_seg_size and uses MAX_BLOCK_SIZE (4096) instead.
+
+To take advantage of the efficiencies of larger blocks, calculate the
+minimum block size across all channels and use that instead.
+
+See: https://github.com/raspberrypi/linux/issues/6256
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 15 ++++++++++++++-
+ 1 file changed, 14 insertions(+), 1 deletion(-)
+
+--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
++++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+@@ -1470,6 +1470,7 @@ static int dw_probe(struct platform_devi
+ struct dw_axi_dma *dw;
+ struct dw_axi_dma_hcfg *hdata;
+ struct reset_control *resets;
++ unsigned int max_seg_size;
+ unsigned int flags;
+ u32 i;
+ int ret;
+@@ -1585,9 +1586,21 @@ static int dw_probe(struct platform_devi
+ * Synopsis DesignWare AxiDMA datasheet mentioned Maximum
+ * supported blocks is 1024. Device register width is 4 bytes.
+ * Therefore, set constraint to 1024 * 4.
++ * However, if all channels specify a greater value, use that instead.
+ */
++
+ dw->dma.dev->dma_parms = &dw->dma_parms;
+- dma_set_max_seg_size(&pdev->dev, MAX_BLOCK_SIZE);
++ max_seg_size = UINT_MAX;
++ for (i = 0; i < dw->hdata->nr_channels; i++) {
++ unsigned int block_size = chip->dw->hdata->block_size[i];
++
++ if (!block_size)
++ block_size = MAX_BLOCK_SIZE;
++ max_seg_size = min(block_size, max_seg_size);
++ }
++
++ dma_set_max_seg_size(&pdev->dev, max_seg_size);
++
+ platform_set_drvdata(pdev, chip);
+
+ pm_runtime_enable(chip->dev);
diff --git a/target/linux/bcm27xx/patches-6.6/950-1167-mmc-restrict-posted-write-counts-for-SD-cards-in-CQ-.patch b/target/linux/bcm27xx/patches-6.6/950-1167-mmc-restrict-posted-write-counts-for-SD-cards-in-CQ-.patch
new file mode 100644
index 0000000000..2ba494958e
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1167-mmc-restrict-posted-write-counts-for-SD-cards-in-CQ-.patch
@@ -0,0 +1,157 @@
+From e6c1e862b2b8150a419f4208e5bd7749662b16a1 Mon Sep 17 00:00:00 2001
+From: Jonathan Bell <jonathan@raspberrypi.com>
+Date: Thu, 20 Jun 2024 14:31:20 +0100
+Subject: [PATCH 1167/1215] mmc: restrict posted write counts for SD cards in
+ CQ mode
+
+Command Queueing requires Write Cache and Power off Notification support
+from the card - but using the write cache forms a contract with the host
+whereby the card expects to be told about impending power-down.
+
+The implication is that (for performance) the card can do unsafe things
+with pending write data - including reordering what gets committed to
+nonvolatile storage at what time.
+
+Exposed SD slots and platforms powered by hotpluggable means (i.e.
+Raspberry Pis) can't guarantee that surprise removal won't happen.
+
+To limit the scope for cards to invent new ways to trash filesystems,
+limit pending writes to 1 (equivalent to the non-CQ behaviour).
+
+Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
+---
+ drivers/mmc/core/block.c | 11 +++++++++--
+ drivers/mmc/core/mmc.c | 1 +
+ drivers/mmc/core/queue.c | 9 +++++++++
+ drivers/mmc/core/queue.h | 1 +
+ drivers/mmc/core/sd.c | 8 ++++++++
+ include/linux/mmc/card.h | 2 ++
+ 6 files changed, 30 insertions(+), 2 deletions(-)
+
+--- a/drivers/mmc/core/block.c
++++ b/drivers/mmc/core/block.c
+@@ -1555,6 +1555,8 @@ static void mmc_blk_cqe_complete_rq(stru
+
+ spin_lock_irqsave(&mq->lock, flags);
+
++ if (req_op(req) == REQ_OP_WRITE)
++ mq->pending_writes--;
+ mq->in_flight[issue_type] -= 1;
+
+ put_card = (mmc_tot_in_flight(mq) == 0);
+@@ -2071,6 +2073,8 @@ static void mmc_blk_mq_complete_rq(struc
+ struct mmc_queue_req *mqrq = req_to_mmc_queue_req(req);
+ unsigned int nr_bytes = mqrq->brq.data.bytes_xfered;
+
++ if (req_op(req) == REQ_OP_WRITE)
++ mq->pending_writes--;
+ if (nr_bytes) {
+ if (blk_update_request(req, BLK_STS_OK, nr_bytes))
+ blk_mq_requeue_request(req, true);
+@@ -2165,13 +2169,16 @@ static void mmc_blk_mq_poll_completion(s
+ mmc_blk_urgent_bkops(mq, mqrq);
+ }
+
+-static void mmc_blk_mq_dec_in_flight(struct mmc_queue *mq, enum mmc_issue_type issue_type)
++static void mmc_blk_mq_dec_in_flight(struct mmc_queue *mq, enum mmc_issue_type issue_type,
++ struct request *req)
+ {
+ unsigned long flags;
+ bool put_card;
+
+ spin_lock_irqsave(&mq->lock, flags);
+
++ if (req_op(req) == REQ_OP_WRITE)
++ mq->pending_writes--;
+ mq->in_flight[issue_type] -= 1;
+
+ put_card = (mmc_tot_in_flight(mq) == 0);
+@@ -2205,7 +2212,7 @@ static void mmc_blk_mq_post_req(struct m
+ blk_mq_complete_request(req);
+ }
+
+- mmc_blk_mq_dec_in_flight(mq, issue_type);
++ mmc_blk_mq_dec_in_flight(mq, issue_type, req);
+ }
+
+ void mmc_blk_mq_recovery(struct mmc_queue *mq)
+--- a/drivers/mmc/core/mmc.c
++++ b/drivers/mmc/core/mmc.c
+@@ -1922,6 +1922,7 @@ static int mmc_init_card(struct mmc_host
+ pr_info("%s: Host Software Queue enabled\n",
+ mmc_hostname(host));
+ }
++ card->max_posted_writes = card->ext_csd.cmdq_depth;
+ }
+ }
+
+--- a/drivers/mmc/core/queue.c
++++ b/drivers/mmc/core/queue.c
+@@ -268,6 +268,11 @@ static blk_status_t mmc_mq_queue_rq(stru
+ spin_unlock_irq(&mq->lock);
+ return BLK_STS_RESOURCE;
+ }
++ if (host->cqe_enabled && req_op(req) == REQ_OP_WRITE &&
++ mq->pending_writes >= card->max_posted_writes) {
++ spin_unlock_irq(&mq->lock);
++ return BLK_STS_RESOURCE;
++ }
+ break;
+ default:
+ /*
+@@ -284,6 +289,8 @@ static blk_status_t mmc_mq_queue_rq(stru
+ /* Parallel dispatch of requests is not supported at the moment */
+ mq->busy = true;
+
++ if (req_op(req) == REQ_OP_WRITE)
++ mq->pending_writes++;
+ mq->in_flight[issue_type] += 1;
+ get_card = (mmc_tot_in_flight(mq) == 1);
+ cqe_retune_ok = (mmc_cqe_qcnt(mq) == 1);
+@@ -323,6 +330,8 @@ static blk_status_t mmc_mq_queue_rq(stru
+ bool put_card = false;
+
+ spin_lock_irq(&mq->lock);
++ if (req_op(req) == REQ_OP_WRITE)
++ mq->pending_writes--;
+ mq->in_flight[issue_type] -= 1;
+ if (mmc_tot_in_flight(mq) == 0)
+ put_card = true;
+--- a/drivers/mmc/core/queue.h
++++ b/drivers/mmc/core/queue.h
+@@ -79,6 +79,7 @@ struct mmc_queue {
+ struct request_queue *queue;
+ spinlock_t lock;
+ int in_flight[MMC_ISSUE_MAX];
++ int pending_writes;
+ unsigned int cqe_busy;
+ #define MMC_CQE_DCMD_BUSY BIT(0)
+ bool busy;
+--- a/drivers/mmc/core/sd.c
++++ b/drivers/mmc/core/sd.c
+@@ -1104,6 +1104,14 @@ static int sd_parse_ext_reg_perf(struct
+ pr_debug("%s: Command Queue supported depth %u\n",
+ mmc_hostname(card->host),
+ card->ext_csd.cmdq_depth);
++ /*
++ * If CQ is enabled, there is a contract between host and card such that VDD will
++ * be maintained and removed only if a power off notification is provided.
++ * An SD card in an accessible slot means surprise removal is a possibility.
++ * As a middle ground, limit max posted writes to 1 unless the card is "hardwired".
++ */
++ if (mmc_card_is_removable(card->host))
++ card->max_posted_writes = 1;
+ }
+
+ card->ext_perf.fno = fno;
+--- a/include/linux/mmc/card.h
++++ b/include/linux/mmc/card.h
+@@ -343,6 +343,8 @@ struct mmc_card {
+ unsigned int nr_parts;
+
+ struct workqueue_struct *complete_wq; /* Private workqueue */
++
++ unsigned int max_posted_writes; /* command queue posted write limit */
+ };
+
+ static inline bool mmc_large_sector(struct mmc_card *card)
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
new file mode 100644
index 0000000000..4f1d02c74d
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1168-fixup-mmc-restrict-posted-write-counts-for-SD-cards-.patch
@@ -0,0 +1,70 @@
+From 19682239a60c1b53cad8319eaeb58e71d4213cee Mon Sep 17 00:00:00 2001
+From: Jonathan Bell <jonathan@raspberrypi.com>
+Date: Mon, 15 Jul 2024 13:38:38 +0100
+Subject: [PATCH 1168/1215] fixup: mmc: restrict posted write counts for SD
+ cards in CQ mode
+
+Leaving card->max_posted_writes unintialised was a bad thing to do.
+
+Also, cqe_enable is 1 if hsq is enabled as hsq substitutes the cqhci
+implementation with its own.
+
+Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
+---
+ drivers/mmc/core/mmc.c | 1 +
+ drivers/mmc/core/queue.c | 2 +-
+ drivers/mmc/core/sd.c | 14 ++++++++------
+ 3 files changed, 10 insertions(+), 7 deletions(-)
+
+--- a/drivers/mmc/core/mmc.c
++++ b/drivers/mmc/core/mmc.c
+@@ -1663,6 +1663,7 @@ static int mmc_init_card(struct mmc_host
+ card->ocr = ocr;
+ card->type = MMC_TYPE_MMC;
+ card->rca = 1;
++ card->max_posted_writes = 1;
+ memcpy(card->raw_cid, cid, sizeof(card->raw_cid));
+ }
+
+--- a/drivers/mmc/core/queue.c
++++ b/drivers/mmc/core/queue.c
+@@ -268,7 +268,7 @@ static blk_status_t mmc_mq_queue_rq(stru
+ spin_unlock_irq(&mq->lock);
+ return BLK_STS_RESOURCE;
+ }
+- if (host->cqe_enabled && req_op(req) == REQ_OP_WRITE &&
++ if (!host->hsq_enabled && host->cqe_enabled && req_op(req) == REQ_OP_WRITE &&
+ mq->pending_writes >= card->max_posted_writes) {
+ spin_unlock_irq(&mq->lock);
+ return BLK_STS_RESOURCE;
+--- a/drivers/mmc/core/sd.c
++++ b/drivers/mmc/core/sd.c
+@@ -1105,13 +1105,14 @@ static int sd_parse_ext_reg_perf(struct
+ mmc_hostname(card->host),
+ card->ext_csd.cmdq_depth);
+ /*
+- * If CQ is enabled, there is a contract between host and card such that VDD will
+- * be maintained and removed only if a power off notification is provided.
+- * An SD card in an accessible slot means surprise removal is a possibility.
+- * As a middle ground, limit max posted writes to 1 unless the card is "hardwired".
++ * If CQ is enabled, there is a contract between host and card such that
++ * VDD will be maintained and removed only if a power off notification
++ * is provided. An SD card in an accessible slot means surprise removal
++ * is a possibility. As a middle ground, keep the default maximum of 1
++ * posted write unless the card is "hardwired".
+ */
+- if (mmc_card_is_removable(card->host))
+- card->max_posted_writes = 1;
++ if (!mmc_card_is_removable(card->host))
++ card->max_posted_writes = card->ext_csd.cmdq_depth;
+ }
+
+ card->ext_perf.fno = fno;
+@@ -1383,6 +1384,7 @@ retry:
+
+ card->ocr = ocr;
+ card->type = MMC_TYPE_SD;
++ card->max_posted_writes = 1;
+ memcpy(card->raw_cid, cid, sizeof(card->raw_cid));
+ }
+
diff --git a/target/linux/bcm27xx/patches-6.6/950-1169-mmc-brcmstb-don-t-squash-card-busy-detection-on-bcm2.patch b/target/linux/bcm27xx/patches-6.6/950-1169-mmc-brcmstb-don-t-squash-card-busy-detection-on-bcm2.patch
new file mode 100644
index 0000000000..0d4d6cba19
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1169-mmc-brcmstb-don-t-squash-card-busy-detection-on-bcm2.patch
@@ -0,0 +1,28 @@
+From 1abc413af44652d6a76d5b5c2afe90788595008e Mon Sep 17 00:00:00 2001
+From: Jonathan Bell <jonathan@raspberrypi.com>
+Date: Mon, 15 Jul 2024 13:57:01 +0100
+Subject: [PATCH 1169/1215] mmc: brcmstb: don't squash card-busy detection on
+ bcm2712
+
+Commit 485d9421719b ("mmc: sdhci-brcmstb: check R1_STATUS for
+erase/trim/discard") introduced a new flag and defaulted to disabling
+card busy detection across all platforms with this controller.
+
+This is required for IO voltage switching, as the card drives CMD low
+while the switch is in progress.
+
+Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
+---
+ drivers/mmc/host/sdhci-brcmstb.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/mmc/host/sdhci-brcmstb.c
++++ b/drivers/mmc/host/sdhci-brcmstb.c
+@@ -430,6 +430,7 @@ static const struct brcmstb_match_priv m
+ };
+
+ static const struct brcmstb_match_priv match_priv_2712 = {
++ .flags = BRCMSTB_MATCH_FLAGS_USE_CARD_BUSY,
+ .hs400es = sdhci_brcmstb_hs400es,
+ .cfginit = sdhci_brcmstb_cfginit_2712,
+ .ops = &sdhci_brcmstb_ops_2712,
diff --git a/target/linux/bcm27xx/patches-6.6/950-1172-Revert-Update-DAC8x-to-support-384khz-6187.patch b/target/linux/bcm27xx/patches-6.6/950-1172-Revert-Update-DAC8x-to-support-384khz-6187.patch
new file mode 100644
index 0000000000..1923b7aec0
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1172-Revert-Update-DAC8x-to-support-384khz-6187.patch
@@ -0,0 +1,25 @@
+From 31eb43be8cad2818b4458cf1fd2dfa60031ee5f4 Mon Sep 17 00:00:00 2001
+From: Matthew <sirfragles@gmail.com>
+Date: Tue, 16 Jul 2024 11:20:54 +0200
+Subject: [PATCH 1172/1215] Revert "Update DAC8x to support 384khz (#6187)"
+
+This reverts commit dd7a15472b18d4bce738bb9213443c140473833b.
+---
+ sound/soc/bcm/rpi-simple-soundcard.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/sound/soc/bcm/rpi-simple-soundcard.c
++++ b/sound/soc/bcm/rpi-simple-soundcard.c
+@@ -324,10 +324,10 @@ static int hifiberry_dac8x_init(struct s
+ struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
+
+ /* override the defaults to reflect 4 x PCM5102A on the card
+- * and limit the sample rate to 384ksps
++ * and limit the sample rate to 192ksps
+ */
+ codec_dai->driver->playback.channels_max = 8;
+- codec_dai->driver->playback.rates = SNDRV_PCM_RATE_8000_384000;
++ codec_dai->driver->playback.rates = SNDRV_PCM_RATE_8000_192000;
+
+ return 0;
+ }
diff --git a/target/linux/bcm27xx/patches-6.6/950-1176-dt-bindings-clk-rp1-Add-clocks-representing-MIPI-DSI.patch b/target/linux/bcm27xx/patches-6.6/950-1176-dt-bindings-clk-rp1-Add-clocks-representing-MIPI-DSI.patch
new file mode 100644
index 0000000000..af740bd305
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1176-dt-bindings-clk-rp1-Add-clocks-representing-MIPI-DSI.patch
@@ -0,0 +1,25 @@
+From 3224569a3e279bbeae4e975dfa1a890f3f595239 Mon Sep 17 00:00:00 2001
+From: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>
+Date: Fri, 10 May 2024 15:18:44 +0100
+Subject: [PATCH 1176/1215] dt-bindings: clk: rp1: Add clocks representing MIPI
+ DSI byteclock
+
+Define two new RP1 clocks, representing the MIPI DSI byteclock
+sources for the dividers used to generate MIPI[01] DPI pixel clocks.
+(Previously they were represented by "fake" fixed clocks sources).
+
+Signed-off-by: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>
+---
+ include/dt-bindings/clock/rp1.h | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/include/dt-bindings/clock/rp1.h
++++ b/include/dt-bindings/clock/rp1.h
+@@ -54,3 +54,7 @@
+ /* Extra PLL output channels - RP1B0 only */
+ #define RP1_PLL_VIDEO_PRI_PH 43
+ #define RP1_PLL_AUDIO_TERN 44
++
++/* MIPI clocks managed by the DSI driver */
++#define RP1_CLK_MIPI0_DSI_BYTECLOCK 45
++#define RP1_CLK_MIPI1_DSI_BYTECLOCK 46
diff --git a/target/linux/bcm27xx/patches-6.6/950-1177-clk-clk-rp1-Add-varsrc-clocks-to-represent-MIPI-byte.patch b/target/linux/bcm27xx/patches-6.6/950-1177-clk-clk-rp1-Add-varsrc-clocks-to-represent-MIPI-byte.patch
new file mode 100644
index 0000000000..564ef84c9e
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1177-clk-clk-rp1-Add-varsrc-clocks-to-represent-MIPI-byte.patch
@@ -0,0 +1,132 @@
+From 126560c909f38f00c08dd5f35f50c981d5e25e1f Mon Sep 17 00:00:00 2001
+From: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>
+Date: Fri, 10 May 2024 15:30:44 +0100
+Subject: [PATCH 1177/1215] clk: clk-rp1: Add "varsrc" clocks to represent MIPI
+ byte clocks
+
+Add a new class of clocks to RP1 to represent clock sources whose
+frequency changes at run-time as a side-effect of some other driver.
+Specifically this is for the two MIPI DSI byte-clock sources.
+
+Signed-off-by: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>
+---
+ drivers/clk/clk-rp1.c | 73 +++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 73 insertions(+)
+
+--- a/drivers/clk/clk-rp1.c
++++ b/drivers/clk/clk-rp1.c
+@@ -394,6 +394,11 @@ struct rp1_clock {
+ unsigned long cached_rate;
+ };
+
++struct rp1_varsrc {
++ struct clk_hw hw;
++ struct rp1_clockman *clockman;
++ unsigned long rate;
++};
+
+ struct rp1_clk_change {
+ struct clk_hw *hw;
+@@ -1414,6 +1419,34 @@ static void rp1_clk_debug_init(struct cl
+ rp1_debugfs_regset(clockman, 0, regs, i, dentry);
+ }
+
++static int rp1_varsrc_set_rate(struct clk_hw *hw,
++ unsigned long rate, unsigned long parent_rate)
++{
++ struct rp1_varsrc *varsrc = container_of(hw, struct rp1_varsrc, hw);
++
++ /*
++ * "varsrc" exists purely to let clock dividers know the frequency
++ * of an externally-managed clock source (such as MIPI DSI byte-clock)
++ * which may change at run-time as a side-effect of some other driver.
++ */
++ varsrc->rate = rate;
++ return 0;
++}
++
++static unsigned long rp1_varsrc_recalc_rate(struct clk_hw *hw,
++ unsigned long parent_rate)
++{
++ struct rp1_varsrc *varsrc = container_of(hw, struct rp1_varsrc, hw);
++
++ return varsrc->rate;
++}
++
++static long rp1_varsrc_round_rate(struct clk_hw *hw, unsigned long rate,
++ unsigned long *parent_rate)
++{
++ return rate;
++}
++
+ static const struct clk_ops rp1_pll_core_ops = {
+ .is_prepared = rp1_pll_core_is_on,
+ .prepare = rp1_pll_core_on,
+@@ -1464,6 +1497,12 @@ static const struct clk_ops rp1_clk_ops
+ .debug_init = rp1_clk_debug_init,
+ };
+
++static const struct clk_ops rp1_varsrc_ops = {
++ .set_rate = rp1_varsrc_set_rate,
++ .recalc_rate = rp1_varsrc_recalc_rate,
++ .round_rate = rp1_varsrc_round_rate,
++};
++
+ static bool rp1_clk_is_claimed(const char *name);
+
+ static struct clk_hw *rp1_register_pll_core(struct rp1_clockman *clockman,
+@@ -1647,6 +1686,35 @@ static struct clk_hw *rp1_register_clock
+ return &clock->hw;
+ }
+
++static struct clk_hw *rp1_register_varsrc(struct rp1_clockman *clockman,
++ const void *data)
++{
++ const char *name = *(char const * const *)data;
++ struct rp1_varsrc *clock;
++ struct clk_init_data init;
++ int ret;
++
++ memset(&init, 0, sizeof(init));
++ init.parent_names = &ref_clock;
++ init.num_parents = 1;
++ init.name = name;
++ init.flags = CLK_IGNORE_UNUSED;
++ init.ops = &rp1_varsrc_ops;
++
++ clock = devm_kzalloc(clockman->dev, sizeof(*clock), GFP_KERNEL);
++ if (!clock)
++ return NULL;
++
++ clock->clockman = clockman;
++ clock->hw.init = &init;
++
++ ret = devm_clk_hw_register(clockman->dev, &clock->hw);
++ if (ret)
++ return ERR_PTR(ret);
++
++ return &clock->hw;
++}
++
+ struct rp1_clk_desc {
+ struct clk_hw *(*clk_register)(struct rp1_clockman *clockman,
+ const void *data);
+@@ -1676,6 +1744,8 @@ struct rp1_clk_desc {
+ &(struct rp1_clock_data) \
+ {__VA_ARGS__})
+
++#define REGISTER_VARSRC(n) _REGISTER(&rp1_register_varsrc, &(const char *){n})
++
+ static const struct rp1_clk_desc clk_desc_array[] = {
+ [RP1_PLL_SYS_CORE] = REGISTER_PLL_CORE(
+ .name = "pll_sys_core",
+@@ -2318,6 +2388,9 @@ static const struct rp1_clk_desc clk_des
+ .max_freq = 200 * MHz,
+ .fc0_src = FC_NUM(3, 6),
+ ),
++
++ [RP1_CLK_MIPI0_DSI_BYTECLOCK] = REGISTER_VARSRC("clksrc_mipi0_dsi_byteclk"),
++ [RP1_CLK_MIPI1_DSI_BYTECLOCK] = REGISTER_VARSRC("clksrc_mipi1_dsi_byteclk"),
+ };
+
+ static bool rp1_clk_claimed[ARRAY_SIZE(clk_desc_array)];
diff --git a/target/linux/bcm27xx/patches-6.6/950-1178-dts-rp1-DSI-drivers-to-use-newly-defined-MIPI-byte-s.patch b/target/linux/bcm27xx/patches-6.6/950-1178-dts-rp1-DSI-drivers-to-use-newly-defined-MIPI-byte-s.patch
new file mode 100644
index 0000000000..7e6032dd1f
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1178-dts-rp1-DSI-drivers-to-use-newly-defined-MIPI-byte-s.patch
@@ -0,0 +1,92 @@
+From 9a108c82b6f6526e0aa8a19befa1ed3f31f8fe52 Mon Sep 17 00:00:00 2001
+From: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>
+Date: Fri, 10 May 2024 15:42:29 +0100
+Subject: [PATCH 1178/1215] dts: rp1: DSI drivers to use newly defined MIPI
+ byte source clocks.
+
+Remove the "dummy" 72MHz fixed clock sources and associate DSI driver
+with the new "variable" clock sources now defined in RP1 clocks.
+
+Also add PLLSYS clock to DSI, which it will need as an alternative
+clock source in those cases where DPI pixclock > DSI byteclock.
+
+Signed-off-by: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>
+---
+ arch/arm/boot/dts/broadcom/rp1.dtsi | 50 +++++++++--------------------
+ 1 file changed, 15 insertions(+), 35 deletions(-)
+
+--- a/arch/arm/boot/dts/broadcom/rp1.dtsi
++++ b/arch/arm/boot/dts/broadcom/rp1.dtsi
+@@ -1109,16 +1109,15 @@
+
+ interrupts = <RP1_INT_MIPI0 IRQ_TYPE_LEVEL_HIGH>;
+
+- clocks = <&rp1_clocks RP1_CLK_MIPI0_CFG>, // required, config bus clock
+- <&rp1_clocks RP1_CLK_MIPI0_DPI>, // required, pixel clock
+- <&clksrc_mipi0_dsi_byteclk>, // internal, parent for divide
+- <&clk_xosc>; // hardwired to DSI "refclk"
+- clock-names = "cfgclk", "dpiclk", "byteclk", "refclk";
++ clocks = <&rp1_clocks RP1_CLK_MIPI0_CFG>,
++ <&rp1_clocks RP1_CLK_MIPI0_DPI>,
++ <&rp1_clocks RP1_CLK_MIPI0_DSI_BYTECLOCK>,
++ <&clk_xosc>, // hardwired to DSI "refclk"
++ <&rp1_clocks RP1_PLL_SYS>; // alternate parent for divide
++ clock-names = "cfgclk", "dpiclk", "byteclk", "refclk", "pllsys";
+
+- assigned-clocks = <&rp1_clocks RP1_CLK_MIPI0_CFG>,
+- <&rp1_clocks RP1_CLK_MIPI0_DPI>;
++ assigned-clocks = <&rp1_clocks RP1_CLK_MIPI0_CFG>;
+ assigned-clock-rates = <25000000>;
+- assigned-clock-parents = <0>, <&clksrc_mipi0_dsi_byteclk>;
+ };
+
+ rp1_dsi1: dsi@128000 {
+@@ -1130,16 +1129,15 @@
+
+ interrupts = <RP1_INT_MIPI1 IRQ_TYPE_LEVEL_HIGH>;
+
+- clocks = <&rp1_clocks RP1_CLK_MIPI1_CFG>, // required, config bus clock
+- <&rp1_clocks RP1_CLK_MIPI1_DPI>, // required, pixel clock
+- <&clksrc_mipi1_dsi_byteclk>, // internal, parent for divide
+- <&clk_xosc>; // hardwired to DSI "refclk"
+- clock-names = "cfgclk", "dpiclk", "byteclk", "refclk";
++ clocks = <&rp1_clocks RP1_CLK_MIPI1_CFG>,
++ <&rp1_clocks RP1_CLK_MIPI1_DPI>,
++ <&rp1_clocks RP1_CLK_MIPI1_DSI_BYTECLOCK>,
++ <&clk_xosc>, // hardwired to DSI "refclk"
++ <&rp1_clocks RP1_PLL_SYS>; // alternate parent for divide
++ clock-names = "cfgclk", "dpiclk", "byteclk", "refclk", "pllsys";
+
+- assigned-clocks = <&rp1_clocks RP1_CLK_MIPI1_CFG>,
+- <&rp1_clocks RP1_CLK_MIPI1_DPI>;
++ assigned-clocks = <&rp1_clocks RP1_CLK_MIPI1_CFG>;
+ assigned-clock-rates = <25000000>;
+- assigned-clock-parents = <0>, <&clksrc_mipi1_dsi_byteclk>;
+ };
+
+ /* VEC and DPI both need to control PLL_VIDEO and cannot work together; */
+@@ -1216,24 +1214,6 @@
+ clock-output-names = "core";
+ clock-frequency = <50000000>;
+ };
+- clksrc_mipi0_dsi_byteclk: clksrc_mipi0_dsi_byteclk {
+- // This clock is synthesized by MIPI0 D-PHY, when DSI is running.
+- // Its frequency is not known a priori (until a panel driver attaches)
+- // so assign a made-up frequency of 72MHz so it can be divided for DPI.
+- compatible = "fixed-clock";
+- #clock-cells = <0>;
+- clock-output-names = "clksrc_mipi0_dsi_byteclk";
+- clock-frequency = <72000000>;
+- };
+- clksrc_mipi1_dsi_byteclk: clksrc_mipi1_dsi_byteclk {
+- // This clock is synthesized by MIPI1 D-PHY, when DSI is running.
+- // Its frequency is not known a priori (until a panel driver attaches)
+- // so assign a made-up frequency of 72MHz so it can be divided for DPI.
+- compatible = "fixed-clock";
+- #clock-cells = <0>;
+- clock-output-names = "clksrc_mipi1_dsi_byteclk";
+- clock-frequency = <72000000>;
+- };
+ /* GPIO derived clock sources. Each GPIO with a GPCLK function
+ * can drive its output from the respective GPCLK
+ * generator, and provide a clock source to other internal
diff --git a/target/linux/bcm27xx/patches-6.6/950-1179-drm-rp1-rp1-dsi-Switch-to-PLL_SYS-source-for-DPI-whe.patch b/target/linux/bcm27xx/patches-6.6/950-1179-drm-rp1-rp1-dsi-Switch-to-PLL_SYS-source-for-DPI-whe.patch
new file mode 100644
index 0000000000..a80af9839d
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1179-drm-rp1-rp1-dsi-Switch-to-PLL_SYS-source-for-DPI-whe.patch
@@ -0,0 +1,313 @@
+From f5de8d46da4b40f2180be502c1e547fe8c9b2ac2 Mon Sep 17 00:00:00 2001
+From: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>
+Date: Fri, 10 May 2024 15:48:15 +0100
+Subject: [PATCH 1179/1215] drm: rp1: rp1-dsi: Switch to PLL_SYS source for DPI
+ when 8 * lanes > bpp
+
+To support 4 lanes, re-parent DPI clock source between DSI byteclock
+(using the new "variable sources" defined in clk-rp1) and PLL_SYS.
+This is to cover cases in which byteclock < pixclock <= 200MHz.
+
+Tidying: All frequencies now in Hz (not kHz), where DSI speed is now
+represented by byteclock to simplify arithmetic. Clamp DPI and byte
+clocks to their legal ranges; fix up HSTX timeout to avoid an unsafe
+assumption that it would return to LP state for every scanline.
+
+Because of RP1's clock topology, the ratio between DSI and DPI clocks
+may not be exact with 3 or 4 lanes, leading to slightly irregular
+timings each time DSI switches between HS and LP states. Tweak to
+inhibit LP during Horizontal BP when sync pulses were requested.
+
+Signed-off-by: Nick Hollinghurst <nick.hollinghurst@raspberrypi.com>
+---
+ drivers/gpu/drm/rp1/rp1-dsi/rp1_dsi.c | 3 +-
+ drivers/gpu/drm/rp1/rp1-dsi/rp1_dsi.h | 3 +-
+ drivers/gpu/drm/rp1/rp1-dsi/rp1_dsi_dsi.c | 130 +++++++++++++---------
+ 3 files changed, 80 insertions(+), 56 deletions(-)
+
+--- a/drivers/gpu/drm/rp1/rp1-dsi/rp1_dsi.c
++++ b/drivers/gpu/drm/rp1/rp1-dsi/rp1_dsi.c
+@@ -54,6 +54,7 @@ static void rp1_dsi_bridge_pre_enable(st
+ struct rp1_dsi *dsi = bridge_to_rp1_dsi(bridge);
+
+ rp1dsi_dsi_setup(dsi, &dsi->pipe.crtc.state->adjusted_mode);
++ dsi->dsi_running = true;
+ }
+
+ static void rp1_dsi_bridge_enable(struct drm_bridge *bridge,
+@@ -443,7 +444,7 @@ static int rp1dsi_platform_probe(struct
+ /* Hardware resources */
+ for (i = 0; i < RP1DSI_NUM_CLOCKS; i++) {
+ static const char * const myclocknames[RP1DSI_NUM_CLOCKS] = {
+- "cfgclk", "dpiclk", "byteclk", "refclk"
++ "cfgclk", "dpiclk", "byteclk", "refclk", "pllsys"
+ };
+ dsi->clocks[i] = devm_clk_get(dev, myclocknames[i]);
+ if (IS_ERR(dsi->clocks[i])) {
+--- a/drivers/gpu/drm/rp1/rp1-dsi/rp1_dsi.h
++++ b/drivers/gpu/drm/rp1/rp1-dsi/rp1_dsi.h
+@@ -30,7 +30,8 @@
+ #define RP1DSI_CLOCK_DPI 1
+ #define RP1DSI_CLOCK_BYTE 2
+ #define RP1DSI_CLOCK_REF 3
+-#define RP1DSI_NUM_CLOCKS 4
++#define RP1DSI_CLOCK_PLLSYS 4
++#define RP1DSI_NUM_CLOCKS 5
+
+ /* ---------------------------------------------------------------------- */
+
+--- a/drivers/gpu/drm/rp1/rp1-dsi/rp1_dsi_dsi.c
++++ b/drivers/gpu/drm/rp1/rp1-dsi/rp1_dsi_dsi.c
+@@ -7,6 +7,7 @@
+
+ #include <linux/delay.h>
+ #include <linux/errno.h>
++#include <linux/math64.h>
+ #include <linux/platform_device.h>
+ #include <linux/rp1_platform.h>
+ #include "drm/drm_print.h"
+@@ -1111,7 +1112,7 @@ static void dphy_transaction(struct rp1_
+ DSI_WRITE(DSI_PHY_TST_CTRL0, DPHY_CTRL0_PHY_TESTCLK_BITS);
+ }
+
+-static uint8_t dphy_get_div(u32 refclk_khz, u32 vco_freq_khz, u32 *ptr_m, u32 *ptr_n)
++static u64 dphy_get_div(u32 refclk, u64 vco_freq, u32 *ptr_m, u32 *ptr_n)
+ {
+ /*
+ * See pg 77-78 of dphy databook
+@@ -1124,19 +1125,23 @@ static uint8_t dphy_get_div(u32 refclk_k
+ * In practice, given a 50MHz reference clock, it can produce any
+ * multiple of 10MHz, 11.1111MHz, 12.5MHz, 14.286MHz or 16.667MHz
+ * with < 1% error for all frequencies above 495MHz.
++ *
++ * vco_freq should be set to the lane bit rate (not the MIPI clock
++ * which is half of this). These frequencies are now measured in Hz.
++ * They should fit within u32, but u64 is needed for calculations.
+ */
+
+- static const u32 REF_DIVN_MAX = 40000u;
+- static const u32 REF_DIVN_MIN = 5000u;
+- u32 best_n, best_m, best_err = 0x7fffffff;
+- unsigned int n;
++ static const u32 REF_DIVN_MAX = 40000000;
++ static const u32 REF_DIVN_MIN = 5000000;
++ u32 n, best_n, best_m;
++ u64 best_err = vco_freq;
+
+- for (n = 1 + refclk_khz / REF_DIVN_MAX; n * REF_DIVN_MIN <= refclk_khz && n < 100; ++n) {
+- u32 half_m = (n * vco_freq_khz + refclk_khz) / (2 * refclk_khz);
++ for (n = 1 + refclk / REF_DIVN_MAX; n * REF_DIVN_MIN <= refclk && n < 100; ++n) {
++ u32 half_m = DIV_U64_ROUND_CLOSEST(n * vco_freq, 2 * refclk);
+
+ if (half_m < 150) {
+- u32 f = (2 * half_m * refclk_khz) / n;
+- u32 err = (f > vco_freq_khz) ? f - vco_freq_khz : vco_freq_khz - f;
++ u64 f = div_u64(mul_u32_u32(2 * half_m, refclk), n);
++ u64 err = (f > vco_freq) ? f - vco_freq : vco_freq - f;
+
+ if (err < best_err) {
+ best_n = n;
+@@ -1148,12 +1153,12 @@ static uint8_t dphy_get_div(u32 refclk_k
+ }
+ }
+
+- if (64 * best_err < vco_freq_khz) { /* tolerate small error */
+- *ptr_n = best_n;
+- *ptr_m = best_m;
+- return 1;
+- }
+- return 0;
++ if (64 * best_err >= vco_freq)
++ return 0;
++
++ *ptr_n = best_n;
++ *ptr_m = best_m;
++ return div_u64(mul_u32_u32(best_m, refclk), best_n);
+ }
+
+ struct hsfreq_range {
+@@ -1226,13 +1231,14 @@ static void dphy_set_hsfreqrange(struct
+ hsfreq_table[i].hsfreqrange << 1);
+ }
+
+-static void dphy_configure_pll(struct rp1_dsi *dsi, u32 refclk_khz, u32 vco_freq_khz)
++static u32 dphy_configure_pll(struct rp1_dsi *dsi, u32 refclk, u32 vco_freq)
+ {
+ u32 m = 0;
+ u32 n = 0;
++ u32 actual_vco_freq = dphy_get_div(refclk, vco_freq, &m, &n);
+
+- if (dphy_get_div(refclk_khz, vco_freq_khz, &m, &n)) {
+- dphy_set_hsfreqrange(dsi, vco_freq_khz / 1000);
++ if (actual_vco_freq) {
++ dphy_set_hsfreqrange(dsi, actual_vco_freq / 1000000);
+ /* Program m,n from registers */
+ dphy_transaction(dsi, DPHY_PLL_DIV_CTRL_OFFSET, 0x30);
+ /* N (program N-1) */
+@@ -1242,18 +1248,21 @@ static void dphy_configure_pll(struct rp
+ /* M[4:0] (program M-1) */
+ dphy_transaction(dsi, DPHY_PLL_LOOP_DIV_OFFSET, ((m - 1) & 0x1F));
+ drm_dbg_driver(dsi->drm,
+- "DPHY: vco freq want %dkHz got %dkHz = %d * (%dkHz / %d), hsfreqrange = 0x%02x\r\n",
+- vco_freq_khz, refclk_khz * m / n, m, refclk_khz,
+- n, hsfreq_table[dsi->hsfreq_index].hsfreqrange);
++ "DPHY: vco freq want %uHz got %uHz = %d * (%uHz / %d), hsfreqrange = 0x%02x\n",
++ vco_freq, actual_vco_freq, m, refclk, n,
++ hsfreq_table[dsi->hsfreq_index].hsfreqrange);
+ } else {
+- drm_info(dsi->drm,
+- "rp1dsi: Error configuring DPHY PLL! %dkHz = %d * (%dkHz / %d)\r\n",
+- vco_freq_khz, m, refclk_khz, n);
++ drm_warn(dsi->drm,
++ "rp1dsi: Error configuring DPHY PLL %uHz\n", vco_freq);
+ }
++
++ return actual_vco_freq;
+ }
+
+-static void dphy_init_khz(struct rp1_dsi *dsi, u32 ref_freq, u32 vco_freq)
++static u32 dphy_init(struct rp1_dsi *dsi, u32 ref_freq, u32 vco_freq)
+ {
++ u32 actual_vco_freq;
++
+ /* Reset the PHY */
+ DSI_WRITE(DSI_PHYRSTZ, 0);
+ DSI_WRITE(DSI_PHY_TST_CTRL0, DPHY_CTRL0_PHY_TESTCLK_BITS);
+@@ -1263,13 +1272,15 @@ static void dphy_init_khz(struct rp1_dsi
+ DSI_WRITE(DSI_PHY_TST_CTRL0, DPHY_CTRL0_PHY_TESTCLK_BITS);
+ udelay(1);
+ /* Since we are in DSI (not CSI2) mode here, start the PLL */
+- dphy_configure_pll(dsi, ref_freq, vco_freq);
++ actual_vco_freq = dphy_configure_pll(dsi, ref_freq, vco_freq);
+ udelay(1);
+ /* Unreset */
+ DSI_WRITE(DSI_PHYRSTZ, DSI_PHYRSTZ_SHUTDOWNZ_BITS);
+ udelay(1);
+ DSI_WRITE(DSI_PHYRSTZ, (DSI_PHYRSTZ_SHUTDOWNZ_BITS | DSI_PHYRSTZ_RSTZ_BITS));
+ udelay(1); /* so we can see PLL coming up? */
++
++ return actual_vco_freq;
+ }
+
+ void rp1dsi_mipicfg_setup(struct rp1_dsi *dsi)
+@@ -1290,23 +1301,30 @@ static unsigned long rp1dsi_refclk_freq(
+ return u;
+ }
+
+-static void rp1dsi_dpiclk_start(struct rp1_dsi *dsi, unsigned int bpp, unsigned int lanes)
++static void rp1dsi_dpiclk_start(struct rp1_dsi *dsi, u32 byte_clock,
++ unsigned int bpp, unsigned int lanes)
+ {
+- unsigned long u;
+-
+- if (dsi->clocks[RP1DSI_CLOCK_DPI]) {
+- u = (dsi->clocks[RP1DSI_CLOCK_BYTE]) ?
+- clk_get_rate(dsi->clocks[RP1DSI_CLOCK_BYTE]) : 0;
+- drm_info(dsi->drm,
+- "rp1dsi: Nominal byte clock %lu; scale by %u/%u",
+- u, 4 * lanes, (bpp >> 1));
+- if (u < 1 || u >= (1ul << 28))
+- u = 72000000ul; /* default DUMMY frequency for byteclock */
++ /* Dummy clk_set_rate() to declare the actual DSI byte-clock rate */
++ clk_set_rate(dsi->clocks[RP1DSI_CLOCK_BYTE], byte_clock);
+
++ /*
++ * Prefer the DSI byte-clock source where possible, so that DSI and DPI
++ * clocks will be in an exact ratio and downstream devices can recover
++ * perfect timings. But when DPI clock is faster, fall back on PLL_SYS.
++ * To defeat rounding errors, specify explicitly which source to use.
++ */
++ if (bpp >= 8 * lanes)
+ clk_set_parent(dsi->clocks[RP1DSI_CLOCK_DPI], dsi->clocks[RP1DSI_CLOCK_BYTE]);
+- clk_set_rate(dsi->clocks[RP1DSI_CLOCK_DPI], (4 * lanes * u) / (bpp >> 1));
+- clk_prepare_enable(dsi->clocks[RP1DSI_CLOCK_DPI]);
+- }
++ else if (dsi->clocks[RP1DSI_CLOCK_PLLSYS])
++ clk_set_parent(dsi->clocks[RP1DSI_CLOCK_DPI], dsi->clocks[RP1DSI_CLOCK_PLLSYS]);
++
++ 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)",
++ byte_clock,
++ clk_get_rate(dsi->clocks[RP1DSI_CLOCK_DPI]),
++ clk_get_rate(clk_get_parent(dsi->clocks[RP1DSI_CLOCK_DPI])));
+ }
+
+ static void rp1dsi_dpiclk_stop(struct rp1_dsi *dsi)
+@@ -1336,18 +1354,21 @@ static u32 get_colorcode(enum mipi_dsi_p
+ return 0x005;
+ }
+
+-/* Maximum frequency for LP escape clock (20MHz), and some magic numbers */
+-#define RP1DSI_ESC_CLK_KHZ 20000
+-#define RP1DSI_TO_CLK_DIV 5
+-#define RP1DSI_HSTX_TO_MIN 0x200
+-#define RP1DSI_LPRX_TO_VAL 0x400
++/* Frequency limits for DPI, HS and LP clocks, and some magic numbers */
++#define RP1DSI_DPI_MAX_KHZ 200000
++#define RP1DSI_BYTE_CLK_MIN 10000000
++#define RP1DSI_BYTE_CLK_MAX 187500000
++#define RP1DSI_ESC_CLK_MAX 20000000
++#define RP1DSI_TO_CLK_DIV 0x50
++#define RP1DSI_LPRX_TO_VAL 0x40
+ #define RP1DSI_BTA_TO_VAL 0xd00
+
+ void rp1dsi_dsi_setup(struct rp1_dsi *dsi, struct drm_display_mode const *mode)
+ {
+ u32 timeout, mask, vid_mode_cfg;
+- int lane_kbps;
+ 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);
+
+ DSI_WRITE(DSI_PHY_IF_CFG, dsi->lanes - 1);
+ DSI_WRITE(DSI_DPI_CFG_POL, 0);
+@@ -1360,6 +1381,8 @@ void rp1dsi_dsi_setup(struct rp1_dsi *ds
+ 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 */
+ if (dsi->display_flags & MIPI_DSI_MODE_VIDEO_BURST)
+ vid_mode_cfg |= 0x02;
+ DSI_WRITE(DSI_VID_MODE_CFG, vid_mode_cfg);
+@@ -1369,15 +1392,14 @@ void rp1dsi_dsi_setup(struct rp1_dsi *ds
+ DSI_WRITE(DSI_MODE_CFG, 1);
+
+ /* Set timeouts and clock dividers */
+- DSI_WRITE(DSI_TO_CNT_CFG,
+- (max((bpp * mode->htotal) / (7 * RP1DSI_TO_CLK_DIV * dsi->lanes),
+- RP1DSI_HSTX_TO_MIN) << 16) |
+- RP1DSI_LPRX_TO_VAL);
++ timeout = (bpp * mode->htotal * mode->vdisplay) / (7 * RP1DSI_TO_CLK_DIV * dsi->lanes);
++ if (timeout > 0xFFFFu)
++ timeout = 0;
++ DSI_WRITE(DSI_TO_CNT_CFG, (timeout << 16) | RP1DSI_LPRX_TO_VAL);
+ DSI_WRITE(DSI_BTA_TO_CNT, RP1DSI_BTA_TO_VAL);
+- lane_kbps = (bpp * mode->clock) / dsi->lanes;
+ DSI_WRITE(DSI_CLKMGR_CFG,
+ (RP1DSI_TO_CLK_DIV << 8) |
+- max(2, lane_kbps / (8 * RP1DSI_ESC_CLK_KHZ) + 1));
++ max(2u, 1u + byte_clock / RP1DSI_ESC_CLK_MAX));
+
+ /* Configure video timings */
+ DSI_WRITE(DSI_VID_PKT_SIZE, mode->hdisplay);
+@@ -1394,7 +1416,7 @@ void rp1dsi_dsi_setup(struct rp1_dsi *ds
+ DSI_WRITE(DSI_VID_VACTIVE_LINES, mode->vdisplay);
+
+ /* Init PHY */
+- dphy_init_khz(dsi, rp1dsi_refclk_freq(dsi) / 1000, lane_kbps);
++ byte_clock = dphy_init(dsi, rp1dsi_refclk_freq(dsi), 8 * byte_clock) >> 3;
+
+ DSI_WRITE(DSI_PHY_TMR_LPCLK_CFG,
+ (hsfreq_table[dsi->hsfreq_index].clk_lp2hs << DSI_PHY_TMR_LP2HS_LSB) |
+@@ -1418,7 +1440,7 @@ void rp1dsi_dsi_setup(struct rp1_dsi *ds
+ DSI_WRITE(DSI_PWR_UP, 0x1); /* power up */
+
+ /* Now it should be safe to start the external DPI clock divider */
+- rp1dsi_dpiclk_start(dsi, bpp, dsi->lanes);
++ rp1dsi_dpiclk_start(dsi, byte_clock, bpp, dsi->lanes);
+
+ /* Wait for all lane(s) to be in Stopstate */
+ mask = (1 << 4);
diff --git a/target/linux/bcm27xx/patches-6.6/950-1180-arm64-dts-Move-bcm2712-and-rp1-here.patch b/target/linux/bcm27xx/patches-6.6/950-1180-arm64-dts-Move-bcm2712-and-rp1-here.patch
new file mode 100644
index 0000000000..2856bb5cd8
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1180-arm64-dts-Move-bcm2712-and-rp1-here.patch
@@ -0,0 +1,9749 @@
+From 10c77e119eaaa2677009dea58cf69a8e5383925b Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Wed, 17 Jul 2024 17:27:36 +0100
+Subject: [PATCH 1180/1215] arm64: dts: Move bcm2712 and rp1 here
+
+It is pointless having the bcm2712 family of dts files and rp1.dtsi
+in the arch/arm directory tree, since they then require placeholders
+to include them in arch/arm64 where they are built. The files have
+no dependencies on other files in the arch/arm tree, so simply move
+them here.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ .../arm/boot/dts/broadcom/bcm2712-rpi-5-b.dts | 867 ------------------
+ .../dts/broadcom/bcm2712-rpi-cm5-cm4io.dts | 20 -
+ .../dts/broadcom/bcm2712-rpi-cm5-cm5io.dts | 10 -
+ .../boot/dts/broadcom/bcm2712d0-rpi-5-b.dts | 107 ---
+ .../boot/dts/broadcom/bcm2712-rpi-5-b.dts | 867 +++++++++++++++++-
+ .../dts/broadcom/bcm2712-rpi-cm5-cm4io.dts | 20 +-
+ .../dts/broadcom/bcm2712-rpi-cm5-cm5io.dts | 10 +-
+ .../boot/dts/broadcom/bcm2712-rpi-cm5.dtsi | 10 +-
+ .../boot/dts/broadcom/bcm2712-rpi.dtsi | 0
+ .../boot/dts/broadcom/bcm2712.dtsi | 0
+ .../boot/dts/broadcom/bcm2712d0-rpi-5-b.dts | 107 ++-
+ .../{arm => arm64}/boot/dts/broadcom/rp1.dtsi | 0
+ 12 files changed, 1002 insertions(+), 1016 deletions(-)
+ delete mode 100644 arch/arm/boot/dts/broadcom/bcm2712-rpi-5-b.dts
+ delete mode 100644 arch/arm/boot/dts/broadcom/bcm2712-rpi-cm5-cm4io.dts
+ delete mode 100644 arch/arm/boot/dts/broadcom/bcm2712-rpi-cm5-cm5io.dts
+ delete mode 100644 arch/arm/boot/dts/broadcom/bcm2712d0-rpi-5-b.dts
+ rename arch/{arm => arm64}/boot/dts/broadcom/bcm2712-rpi-cm5.dtsi (98%)
+ rename arch/{arm => arm64}/boot/dts/broadcom/bcm2712-rpi.dtsi (100%)
+ rename arch/{arm => arm64}/boot/dts/broadcom/bcm2712.dtsi (100%)
+ rename arch/{arm => arm64}/boot/dts/broadcom/rp1.dtsi (100%)
+
+--- a/arch/arm/boot/dts/broadcom/bcm2712-rpi-5-b.dts
++++ /dev/null
+@@ -1,867 +0,0 @@
+-// SPDX-License-Identifier: GPL-2.0
+-/dts-v1/;
+-
+-#include <dt-bindings/gpio/gpio.h>
+-#include <dt-bindings/clock/rp1.h>
+-#include <dt-bindings/interrupt-controller/irq.h>
+-#include <dt-bindings/mfd/rp1.h>
+-#include <dt-bindings/pwm/pwm.h>
+-#include <dt-bindings/reset/raspberrypi,firmware-reset.h>
+-
+-#define i2c0 _i2c0
+-#define i2c3 _i2c3
+-#define i2c4 _i2c4
+-#define i2c5 _i2c5
+-#define i2c6 _i2c6
+-#define i2c8 _i2c8
+-#define i2s _i2s
+-#define pwm0 _pwm0
+-#define pwm1 _pwm1
+-#define spi0 _spi0
+-#define spi3 _spi3
+-#define spi4 _spi4
+-#define spi5 _spi5
+-#define spi6 _spi6
+-#define uart0 _uart0
+-#define uart2 _uart2
+-#define uart5 _uart5
+-
+-#include "bcm2712.dtsi"
+-
+-#undef i2c0
+-#undef i2c3
+-#undef i2c4
+-#undef i2c5
+-#undef i2c6
+-#undef i2c8
+-#undef i2s
+-#undef pwm0
+-#undef pwm1
+-#undef spi0
+-#undef spi3
+-#undef spi4
+-#undef spi5
+-#undef spi6
+-#undef uart0
+-#undef uart2
+-#undef uart3
+-#undef uart4
+-#undef uart5
+-
+-/ {
+- compatible = "raspberrypi,5-model-b", "brcm,bcm2712";
+- model = "Raspberry Pi 5";
+-
+- /* Will be filled by the bootloader */
+- memory@0 {
+- device_type = "memory";
+- reg = <0 0 0x28000000>;
+- };
+-
+- leds: leds {
+- compatible = "gpio-leds";
+-
+- led_pwr: led-pwr {
+- label = "PWR";
+- gpios = <&rp1_gpio 44 GPIO_ACTIVE_LOW>;
+- default-state = "off";
+- linux,default-trigger = "none";
+- };
+-
+- led_act: led-act {
+- label = "ACT";
+- gpios = <&gio_aon 9 GPIO_ACTIVE_LOW>;
+- default-state = "off";
+- linux,default-trigger = "mmc0";
+- };
+- };
+-
+- sd_io_1v8_reg: sd_io_1v8_reg {
+- compatible = "regulator-gpio";
+- regulator-name = "vdd-sd-io";
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <3300000>;
+- regulator-boot-on;
+- regulator-always-on;
+- regulator-settling-time-us = <5000>;
+- gpios = <&gio_aon 3 GPIO_ACTIVE_HIGH>;
+- states = <1800000 0x1
+- 3300000 0x0>;
+- status = "okay";
+- };
+-
+- sd_vcc_reg: sd_vcc_reg {
+- compatible = "regulator-fixed";
+- regulator-name = "vcc-sd";
+- regulator-min-microvolt = <3300000>;
+- regulator-max-microvolt = <3300000>;
+- regulator-boot-on;
+- enable-active-high;
+- gpios = <&gio_aon 4 GPIO_ACTIVE_HIGH>;
+- status = "okay";
+- };
+-
+- wl_on_reg: wl_on_reg {
+- compatible = "regulator-fixed";
+- regulator-name = "wl-on-regulator";
+- regulator-min-microvolt = <3300000>;
+- regulator-max-microvolt = <3300000>;
+- pinctrl-0 = <&wl_on_pins>;
+- pinctrl-names = "default";
+-
+- gpio = <&gio 28 GPIO_ACTIVE_HIGH>;
+-
+- startup-delay-us = <150000>;
+- enable-active-high;
+- };
+-
+- clocks: clocks {
+- };
+-
+- cam1_clk: cam1_clk {
+- compatible = "fixed-clock";
+- #clock-cells = <0>;
+- status = "disabled";
+- };
+-
+- cam0_clk: cam0_clk {
+- compatible = "fixed-clock";
+- #clock-cells = <0>;
+- status = "disabled";
+- };
+-
+- cam0_reg: cam0_reg {
+- compatible = "regulator-fixed";
+- regulator-name = "cam0_reg";
+- enable-active-high;
+- status = "okay";
+- gpio = <&rp1_gpio 34 0>; // CD0_IO0_MICCLK, to MIPI 0 connector
+- };
+-
+- cam1_reg: cam1_reg {
+- compatible = "regulator-fixed";
+- regulator-name = "cam1_reg";
+- enable-active-high;
+- status = "okay";
+- gpio = <&rp1_gpio 46 0>; // CD1_IO0_MICCLK, to MIPI 1 connector
+- };
+-
+- cam_dummy_reg: cam_dummy_reg {
+- compatible = "regulator-fixed";
+- regulator-name = "cam-dummy-reg";
+- status = "okay";
+- };
+-
+- dummy: dummy {
+- // A target for unwanted overlay fragments
+- };
+-
+-
+- // A few extra labels to keep overlays happy
+-
+- i2c0if: i2c0if {};
+- i2c0mux: i2c0mux {};
+-};
+-
+-rp1_target: &pcie2 {
+- brcm,enable-mps-rcb;
+- brcm,vdm-qos-map = <0xbbaa9888>;
+- aspm-no-l0s;
+- status = "okay";
+-};
+-
+-&pcie1 {
+- brcm,vdm-qos-map = <0x33333333>;
+-};
+-
+-// Add some labels to 2712 device
+-
+-// The system UART
+-uart10: &_uart0 { status = "okay"; };
+-
+-// The system SPI for the bootloader EEPROM
+-spi10: &_spi0 { status = "okay"; };
+-
+-i2c_rp1boot: &_i2c3 { };
+-
+-#include "rp1.dtsi"
+-
+-&rp1 {
+- // PCIe address space layout:
+- // 00_00000000-00_00xxxxxx = RP1 peripherals
+- // 10_00000000-1x_xxxxxxxx = up to 64GB system RAM
+-
+- // outbound access aimed at PCIe 0_00xxxxxx -> RP1 c0_40xxxxxx
+- // This is the RP1 peripheral space
+- ranges = <0xc0 0x40000000
+- 0x02000000 0x00 0x00000000
+- 0x00 0x00400000>;
+-
+- dma-ranges =
+- // inbound RP1 1x_xxxxxxxx -> PCIe 1x_xxxxxxxx
+- <0x10 0x00000000
+- 0x43000000 0x10 0x00000000
+- 0x10 0x00000000>,
+-
+- // inbound RP1 c0_40xxxxxx -> PCIe 00_00xxxxxx
+- // This allows the RP1 DMA controller to address RP1 hardware
+- <0xc0 0x40000000
+- 0x02000000 0x0 0x00000000
+- 0x0 0x00400000>,
+-
+- // inbound RP1 0x_xxxxxxxx -> PCIe 1x_xxxxxxxx
+- <0x00 0x00000000
+- 0x02000000 0x10 0x00000000
+- 0x10 0x00000000>;
+-};
+-
+-// Expose RP1 nodes as system nodes with labels
+-
+-&rp1_dma {
+- status = "okay";
+-};
+-
+-&rp1_eth {
+- status = "okay";
+- phy-handle = <&phy1>;
+- phy-reset-gpios = <&rp1_gpio 32 GPIO_ACTIVE_LOW>;
+- phy-reset-duration = <5>;
+-
+- phy1: ethernet-phy@1 {
+- reg = <0x1>;
+- brcm,powerdown-enable;
+- };
+-};
+-
+-gpio: &rp1_gpio {
+- status = "okay";
+-};
+-
+-aux: &dummy {};
+-
+-&rp1_usb0 {
+- pinctrl-0 = <&usb_vbus_pins>;
+- pinctrl-names = "default";
+- status = "okay";
+-};
+-
+-&rp1_usb1 {
+- status = "okay";
+-};
+-
+-#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>;
+-};
+-
+-i2c_csi_dsi1: &i2c4 { // Note: This is for MIPI1 connector only
+- pinctrl-0 = <&rp1_i2c4_40_41>;
+- pinctrl-names = "default";
+- clock-frequency = <100000>;
+-};
+-
+-i2c_csi_dsi: &i2c_csi_dsi1 { }; // An alias for compatibility
+-
+-csi0: &rp1_csi0 { };
+-csi1: &rp1_csi1 { };
+-dsi0: &rp1_dsi0 { };
+-dsi1: &rp1_dsi1 { };
+-dpi: &rp1_dpi { };
+-vec: &rp1_vec { };
+-dpi_gpio0: &rp1_dpi_24bit_gpio0 { };
+-dpi_gpio1: &rp1_dpi_24bit_gpio2 { };
+-dpi_18bit_cpadhi_gpio0: &rp1_dpi_18bit_cpadhi_gpio0 { };
+-dpi_18bit_cpadhi_gpio2: &rp1_dpi_18bit_cpadhi_gpio2 { };
+-dpi_18bit_gpio0: &rp1_dpi_18bit_gpio0 { };
+-dpi_18bit_gpio2: &rp1_dpi_18bit_gpio2 { };
+-dpi_16bit_cpadhi_gpio0: &rp1_dpi_16bit_cpadhi_gpio0 { };
+-dpi_16bit_cpadhi_gpio2: &rp1_dpi_16bit_cpadhi_gpio2 { };
+-dpi_16bit_gpio0: &rp1_dpi_16bit_gpio0 { };
+-dpi_16bit_gpio2: &rp1_dpi_16bit_gpio2 { };
+-
+-/* Add the IOMMUs for some RP1 bus masters */
+-
+-&csi0 {
+- iommus = <&iommu5>;
+-};
+-
+-&csi1 {
+- iommus = <&iommu5>;
+-};
+-
+-&dsi0 {
+- iommus = <&iommu5>;
+-};
+-
+-&dsi1 {
+- iommus = <&iommu5>;
+-};
+-
+-&dpi {
+- iommus = <&iommu5>;
+-};
+-
+-&vec {
+- iommus = <&iommu5>;
+-};
+-
+-&ddc0 {
+- status = "disabled";
+-};
+-
+-&ddc1 {
+- status = "disabled";
+-};
+-
+-&hdmi0 {
+- clocks = <&firmware_clocks 13>, <&firmware_clocks 14>, <&dvp 0>, <&clk_27MHz>;
+- clock-names = "hdmi", "bvb", "audio", "cec";
+- status = "disabled";
+-};
+-
+-&hdmi1 {
+- clocks = <&firmware_clocks 13>, <&firmware_clocks 14>, <&dvp 1>, <&clk_27MHz>;
+- clock-names = "hdmi", "bvb", "audio", "cec";
+- status = "disabled";
+-};
+-
+-&hvs {
+- clocks = <&firmware_clocks 4>, <&firmware_clocks 16>;
+- clock-names = "core", "disp";
+-};
+-
+-&mop {
+- status = "disabled";
+-};
+-
+-&moplet {
+- status = "disabled";
+-};
+-
+-&pixelvalve0 {
+- status = "disabled";
+-};
+-
+-&pixelvalve1 {
+- status = "disabled";
+-};
+-
+-&disp_intr {
+- status = "disabled";
+-};
+-
+-/* SDIO1 is used to drive the SD card */
+-&sdio1 {
+- pinctrl-0 = <&emmc_sd_pulls>, <&emmc_aon_cd_pins>;
+- pinctrl-names = "default";
+- vqmmc-supply = <&sd_io_1v8_reg>;
+- vmmc-supply = <&sd_vcc_reg>;
+- bus-width = <4>;
+- sd-uhs-sdr50;
+- sd-uhs-ddr50;
+- sd-uhs-sdr104;
+- cd-gpios = <&gio_aon 5 GPIO_ACTIVE_LOW>;
+- //no-1-8-v;
+- status = "okay";
+-};
+-
+-&pinctrl_aon {
+- emmc_aon_cd_pins: emmc_aon_cd_pins {
+- function = "sd_card_g";
+- pins = "aon_gpio5";
+- bias-pull-up;
+- };
+-
+- /* Slight hack - only one PWM pin (status LED) is usable */
+- aon_pwm_1pin: aon_pwm_1pin {
+- function = "aon_pwm";
+- pins = "aon_gpio9";
+- };
+-};
+-
+-&pinctrl {
+- pwr_button_pins: pwr_button_pins {
+- function = "gpio";
+- pins = "gpio20";
+- bias-pull-up;
+- };
+-
+- wl_on_pins: wl_on_pins {
+- function = "gpio";
+- pins = "gpio28";
+- };
+-
+- bt_shutdown_pins: bt_shutdown_pins {
+- function = "gpio";
+- pins = "gpio29";
+- };
+-
+- emmc_sd_pulls: emmc_sd_pulls {
+- pins = "emmc_cmd", "emmc_dat0", "emmc_dat1", "emmc_dat2", "emmc_dat3";
+- bias-pull-up;
+- };
+-};
+-
+-/* uarta communicates with the BT module */
+-&uarta {
+- uart-has-rtscts;
+- auto-flow-control;
+- status = "okay";
+- clock-frequency = <96000000>;
+- pinctrl-0 = <&uarta_24_pins &bt_shutdown_pins>;
+- pinctrl-names = "default";
+-
+- bluetooth: bluetooth {
+- compatible = "brcm,bcm43438-bt";
+- max-speed = <3000000>;
+- shutdown-gpios = <&gio 29 GPIO_ACTIVE_HIGH>;
+- local-bd-address = [ 00 00 00 00 00 00 ];
+- };
+-};
+-
+-&i2c_rp1boot {
+- clock-frequency = <400000>;
+- pinctrl-0 = <&i2c3_m4_agpio0_pins>;
+- pinctrl-names = "default";
+-};
+-
+-/ {
+- 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";
+- #cooling-cells = <2>;
+- cooling-min-state = <0>;
+- cooling-max-state = <3>;
+- cooling-levels = <0 75 125 175 250>;
+- pwms = <&rp1_pwm1 3 41566 PWM_POLARITY_INVERTED>;
+- rpm-regmap = <&rp1_pwm1>;
+- rpm-offset = <0x3c>;
+- };
+-
+- pwr_button {
+- compatible = "gpio-keys";
+-
+- pinctrl-names = "default";
+- pinctrl-0 = <&pwr_button_pins>;
+- status = "okay";
+-
+- pwr_key: pwr {
+- label = "pwr_button";
+- // linux,code = <205>; // KEY_SUSPEND
+- linux,code = <116>; // KEY_POWER
+- gpios = <&gio 20 GPIO_ACTIVE_LOW>;
+- debounce-interval = <50>; // ms
+- };
+- };
+-};
+-
+-&usb {
+- power-domains = <&power RPI_POWER_DOMAIN_USB>;
+-};
+-
+-/* SDIO2 drives the WLAN interface */
+-&sdio2 {
+- pinctrl-0 = <&sdio2_30_pins>;
+- pinctrl-names = "default";
+- bus-width = <4>;
+- vmmc-supply = <&wl_on_reg>;
+- sd-uhs-ddr50;
+- non-removable;
+- status = "okay";
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- wifi: wifi@1 {
+- reg = <1>;
+- compatible = "brcm,bcm4329-fmac";
+- local-mac-address = [00 00 00 00 00 00];
+- };
+-};
+-
+-&rpivid {
+- status = "okay";
+-};
+-
+-&pinctrl {
+- spi10_gpio2: spi10_gpio2 {
+- function = "vc_spi0";
+- pins = "gpio2", "gpio3", "gpio4";
+- bias-disable;
+- };
+-
+- spi10_cs_gpio1: spi10_cs_gpio1 {
+- function = "gpio";
+- pins = "gpio1";
+- bias-pull-up;
+- };
+-};
+-
+-spi10_pins: &spi10_gpio2 {};
+-spi10_cs_pins: &spi10_cs_gpio1 {};
+-
+-&spi10 {
+- pinctrl-names = "default";
+- cs-gpios = <&gio 1 1>;
+- pinctrl-0 = <&spi10_pins &spi10_cs_pins>;
+-
+- spidev10: spidev@0 {
+- compatible = "spidev";
+- reg = <0>; /* CE0 */
+- #address-cells = <1>;
+- #size-cells = <0>;
+- spi-max-frequency = <20000000>;
+- status = "okay";
+- };
+-};
+-
+-// =============================================
+-// Board specific stuff here
+-
+-&gio_aon {
+- // Don't use GIO_AON as an interrupt controller because it will
+- // clash with the firmware monitoring the PMIC interrupt via the VPU.
+-
+- /delete-property/ interrupt-controller;
+-};
+-
+-&main_aon_irq {
+- // Don't use the MAIN_AON_IRQ interrupt controller because it will
+- // clash with the firmware monitoring the PMIC interrupt via the VPU.
+-
+- status = "disabled";
+-};
+-
+-&rp1_pwm1 {
+- status = "disabled";
+- pinctrl-0 = <&rp1_pwm1_gpio45>;
+- pinctrl-names = "default";
+-};
+-
+-&thermal_trips {
+- cpu_tepid: cpu-tepid {
+- temperature = <50000>;
+- hysteresis = <5000>;
+- type = "active";
+- };
+-
+- cpu_warm: cpu-warm {
+- temperature = <60000>;
+- hysteresis = <5000>;
+- type = "active";
+- };
+-
+- cpu_hot: cpu-hot {
+- temperature = <67500>;
+- hysteresis = <5000>;
+- type = "active";
+- };
+-
+- cpu_vhot: cpu-vhot {
+- temperature = <75000>;
+- hysteresis = <5000>;
+- type = "active";
+- };
+-};
+-
+-&cooling_maps {
+- tepid {
+- trip = <&cpu_tepid>;
+- cooling-device = <&fan 1 1>;
+- };
+-
+- warm {
+- trip = <&cpu_warm>;
+- cooling-device = <&fan 2 2>;
+- };
+-
+- hot {
+- trip = <&cpu_hot>;
+- cooling-device = <&fan 3 3>;
+- };
+-
+- vhot {
+- trip = <&cpu_vhot>;
+- cooling-device = <&fan 4 4>;
+- };
+-
+- melt {
+- trip = <&cpu_crit>;
+- cooling-device = <&fan 4 4>;
+- };
+-};
+-
+-&gio {
+- // The GPIOs above 35 are not used on Pi 5, so shrink the upper bank
+- // to reduce the clutter in gpioinfo/pinctrl
+- brcm,gpio-bank-widths = <32 4>;
+-
+- 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
+- "PCIE_SDA", // GPIO_014
+- "PCIE_SCL", // GPIO_015
+- "-", // GPIO_016
+- "-", // GPIO_017
+- "-", // GPIO_018
+- "-", // GPIO_019
+- "PWR_GPIO", // GPIO_020
+- "2712_G21_FS", // 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_run_hog {
+- gpio-hog;
+- gpios = <2 GPIO_ACTIVE_HIGH>;
+- output-high;
+- line-name = "RP1 RUN pin";
+- };
+-};
+-
+-&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
+- "FAN_TACH", // GPIO29
+- "HOST_SDA", // GPIO30
+- "HOST_SCL", // GPIO31
+- "ETH_RST_N", // GPIO32
+- "-", // GPIO33
+-
+- "CD0_IO0_MICCLK", // GPIO34
+- "CD0_IO0_MICDAT0", // GPIO35
+- "RP1_PCIE_CLKREQ_N", // GPIO36
+- "-", // GPIO37
+- "CD0_SDA", // GPIO38
+- "CD0_SCL", // GPIO39
+- "CD1_SDA", // GPIO40
+- "CD1_SCL", // GPIO41
+- "USB_VBUS_EN", // GPIO42
+- "USB_OC_N", // GPIO43
+- "RP1_STAT_LED", // GPIO44
+- "FAN_PWM", // GPIO45
+- "CD1_IO0_MICCLK", // GPIO46
+- "2712_WAKE", // GPIO47
+- "CD1_IO1_MICDAT1", // GPIO48
+- "EN_MAX_USB_CUR", // GPIO49
+- "-", // GPIO50
+- "-", // GPIO51
+- "-", // GPIO52
+- "-"; // GPIO53
+-
+- usb_vbus_pins: usb_vbus_pins {
+- function = "vbus1";
+- pins = "gpio42", "gpio43";
+- };
+-};
+-
+-/ {
+- aliases: aliases {
+- blconfig = &blconfig;
+- blpubkey = &blpubkey;
+- bluetooth = &bluetooth;
+- console = &uart10;
+- ethernet0 = &rp1_eth;
+- wifi0 = &wifi;
+- fb = &fb;
+- mailbox = &mailbox;
+- mmc0 = &sdio1;
+- uart0 = &uart0;
+- uart1 = &uart1;
+- uart2 = &uart2;
+- uart3 = &uart3;
+- uart4 = &uart4;
+- uart10 = &uart10;
+- serial0 = &uart0;
+- serial1 = &uart1;
+- serial2 = &uart2;
+- serial3 = &uart3;
+- serial4 = &uart4;
+- serial10 = &uart10;
+- i2c = &i2c_arm;
+- i2c0 = &i2c0;
+- i2c1 = &i2c1;
+- i2c2 = &i2c2;
+- i2c3 = &i2c3;
+- i2c4 = &i2c4;
+- i2c5 = &i2c5;
+- i2c6 = &i2c6;
+- i2c10 = &i2c_rp1boot;
+- // Bit-bashed i2c_gpios start at 10
+- spi0 = &spi0;
+- spi1 = &spi1;
+- spi2 = &spi2;
+- spi3 = &spi3;
+- spi4 = &spi4;
+- spi5 = &spi5;
+- spi10 = &spi10;
+- gpio0 = &gpio;
+- gpio1 = &gio;
+- gpio2 = &gio_aon;
+- gpio3 = &pinctrl;
+- gpio4 = &pinctrl_aon;
+- usb0 = &rp1_usb0;
+- usb1 = &rp1_usb1;
+- drm-dsi1 = &dsi0;
+- drm-dsi2 = &dsi1;
+- };
+-
+- __overrides__ {
+- bdaddr = <&bluetooth>, "local-bd-address[";
+- button_debounce = <&pwr_key>, "debounce-interval:0";
+- cooling_fan = <&fan>, "status", <&rp1_pwm1>, "status";
+- uart0_console = <&uart0>,"status", <&aliases>, "console=",&uart0;
+- i2c0 = <&i2c0>, "status";
+- i2c1 = <&i2c1>, "status";
+- i2c = <&i2c1>, "status";
+- i2c_arm = <&i2c_arm>, "status";
+- i2c_vc = <&i2c_vc>, "status";
+- i2c_csi_dsi = <&i2c_csi_dsi>, "status";
+- i2c_csi_dsi0 = <&i2c_csi_dsi0>, "status";
+- i2c_csi_dsi1 = <&i2c_csi_dsi1>, "status";
+- i2c0_baudrate = <&i2c0>, "clock-frequency:0";
+- i2c1_baudrate = <&i2c1>, "clock-frequency:0";
+- i2c_baudrate = <&i2c_arm>, "clock-frequency:0";
+- i2c_arm_baudrate = <&i2c_arm>, "clock-frequency:0";
+- i2c_vc_baudrate = <&i2c_vc>, "clock-frequency:0";
+- krnbt = <&bluetooth>, "status";
+- nvme = <&pciex1>, "status";
+- pciex1 = <&pciex1>, "status";
+- pciex1_gen = <&pciex1> , "max-link-speed:0";
+- pciex1_no_l0s = <&pciex1>, "aspm-no-l0s?";
+- pciex1_tperst_clk_ms = <&pciex1>, "brcm,tperst-clk-ms:0";
+- pcie_tperst_clk_ms = <&pciex1>, "brcm,tperst-clk-ms:0";
+- random = <&random>, "status";
+- rtc = <&rpi_rtc>, "status";
+- rtc_bbat_vchg = <&rpi_rtc>, "trickle-charge-microvolt:0";
+- sd_cqe = <&sdio1>, "supports-cqe?";
+- spi = <&spi0>, "status";
+- suspend = <&pwr_key>, "linux,code:0=205";
+- uart0 = <&uart0>, "status";
+- wifiaddr = <&wifi>, "local-mac-address[";
+-
+- act_led_gpio = <&led_act>,"gpios:4",<&led_act>,"gpios:0=",<&gpio>;
+- act_led_activelow = <&led_act>,"gpios:8";
+- act_led_trigger = <&led_act>, "linux,default-trigger";
+- pwr_led_gpio = <&led_pwr>,"gpios:4";
+- pwr_led_activelow = <&led_pwr>, "gpios:8";
+- pwr_led_trigger = <&led_pwr>, "linux,default-trigger";
+- eth_led0 = <&phy1>,"led-modes:0";
+- eth_led1 = <&phy1>,"led-modes:4";
+- drm_fb0_rp1_dsi0 = <&aliases>, "drm-fb0=",&dsi0;
+- drm_fb0_rp1_dsi1 = <&aliases>, "drm-fb0=",&dsi1;
+- drm_fb0_rp1_dpi = <&aliases>, "drm-fb0=",&dpi;
+- drm_fb0_vc4 = <&aliases>, "drm-fb0=",&vc4;
+- drm_fb1_rp1_dsi0 = <&aliases>, "drm-fb1=",&dsi0;
+- drm_fb1_rp1_dsi1 = <&aliases>, "drm-fb1=",&dsi1;
+- drm_fb1_rp1_dpi = <&aliases>, "drm-fb1=",&dpi;
+- drm_fb1_vc4 = <&aliases>, "drm-fb1=",&vc4;
+- drm_fb2_rp1_dsi0 = <&aliases>, "drm-fb2=",&dsi0;
+- drm_fb2_rp1_dsi1 = <&aliases>, "drm-fb2=",&dsi1;
+- drm_fb2_rp1_dpi = <&aliases>, "drm-fb2=",&dpi;
+- drm_fb2_vc4 = <&aliases>, "drm-fb2=",&vc4;
+-
+- fan_temp0 = <&cpu_tepid>,"temperature:0";
+- fan_temp1 = <&cpu_warm>,"temperature:0";
+- fan_temp2 = <&cpu_hot>,"temperature:0";
+- fan_temp3 = <&cpu_vhot>,"temperature:0";
+- fan_temp0_hyst = <&cpu_tepid>,"hysteresis:0";
+- fan_temp1_hyst = <&cpu_warm>,"hysteresis:0";
+- fan_temp2_hyst = <&cpu_hot>,"hysteresis:0";
+- fan_temp3_hyst = <&cpu_vhot>,"hysteresis:0";
+- fan_temp0_speed = <&fan>, "cooling-levels:4";
+- fan_temp1_speed = <&fan>, "cooling-levels:8";
+- fan_temp2_speed = <&fan>, "cooling-levels:12";
+- fan_temp3_speed = <&fan>, "cooling-levels:16";
+- };
+-};
+--- a/arch/arm/boot/dts/broadcom/bcm2712-rpi-cm5-cm4io.dts
++++ /dev/null
+@@ -1,20 +0,0 @@
+-// SPDX-License-Identifier: GPL-2.0
+-/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";
+- };
+-};
+--- a/arch/arm/boot/dts/broadcom/bcm2712-rpi-cm5-cm5io.dts
++++ /dev/null
+@@ -1,10 +0,0 @@
+-// SPDX-License-Identifier: GPL-2.0
+-/dts-v1/;
+-
+-#include "bcm2712-rpi-cm5.dtsi"
+-
+-/ {
+- __overrides__ {
+- i2c_csi_dsi = <&i2c_csi_dsi>, "status";
+- };
+-};
+--- a/arch/arm/boot/dts/broadcom/bcm2712d0-rpi-5-b.dts
++++ /dev/null
+@@ -1,107 +0,0 @@
+-// SPDX-License-Identifier: GPL-2.0
+-#include "bcm2712-rpi-5-b.dts"
+-
+-&gio {
+- brcm,gpio-bank-widths = <32 4>;
+-
+- 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
+- "PCIE_SDA", // GPIO_014
+- "PCIE_SCL", // GPIO_015
+- "", // GPIO_016
+- "", // GPIO_017
+- "-", // GPIO_018
+- "-", // GPIO_019
+- "PWR_GPIO", // GPIO_020
+- "2712_G21_FS", // 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 {
+- brcm,gpio-bank-widths = <15 6>;
+-
+- 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
+-};
+-
+-&pinctrl {
+- compatible = "brcm,bcm2712d0-pinctrl";
+- reg = <0x7d504100 0x20>;
+-};
+-
+-&pinctrl_aon {
+- compatible = "brcm,bcm2712d0-aon-pinctrl";
+- reg = <0x7d510700 0x1c>;
+-};
+-
+-&vc4 {
+- compatible = "brcm,bcm2712d0-vc6";
+-};
+-
+-&uart10 {
+- interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
+-};
+-
+-&spi10 {
+- dmas = <&dma40 3>, <&dma40 4>;
+-};
+-
+-&hdmi0 {
+- dmas = <&dma40 (12|(1<<30)|(1<<24)|(10<<16)|(15<<20))>;
+-};
+-
+-&hdmi1 {
+- dmas = <&dma40 (13|(1<<30)|(1<<24)|(10<<16)|(15<<20))>;
+-};
+--- a/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts
++++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts
+@@ -1,2 +1,867 @@
+ // SPDX-License-Identifier: GPL-2.0
+-#include "arm/broadcom/bcm2712-rpi-5-b.dts"
++/dts-v1/;
++
++#include <dt-bindings/gpio/gpio.h>
++#include <dt-bindings/clock/rp1.h>
++#include <dt-bindings/interrupt-controller/irq.h>
++#include <dt-bindings/mfd/rp1.h>
++#include <dt-bindings/pwm/pwm.h>
++#include <dt-bindings/reset/raspberrypi,firmware-reset.h>
++
++#define i2c0 _i2c0
++#define i2c3 _i2c3
++#define i2c4 _i2c4
++#define i2c5 _i2c5
++#define i2c6 _i2c6
++#define i2c8 _i2c8
++#define i2s _i2s
++#define pwm0 _pwm0
++#define pwm1 _pwm1
++#define spi0 _spi0
++#define spi3 _spi3
++#define spi4 _spi4
++#define spi5 _spi5
++#define spi6 _spi6
++#define uart0 _uart0
++#define uart2 _uart2
++#define uart5 _uart5
++
++#include "bcm2712.dtsi"
++
++#undef i2c0
++#undef i2c3
++#undef i2c4
++#undef i2c5
++#undef i2c6
++#undef i2c8
++#undef i2s
++#undef pwm0
++#undef pwm1
++#undef spi0
++#undef spi3
++#undef spi4
++#undef spi5
++#undef spi6
++#undef uart0
++#undef uart2
++#undef uart3
++#undef uart4
++#undef uart5
++
++/ {
++ compatible = "raspberrypi,5-model-b", "brcm,bcm2712";
++ model = "Raspberry Pi 5";
++
++ /* Will be filled by the bootloader */
++ memory@0 {
++ device_type = "memory";
++ reg = <0 0 0x28000000>;
++ };
++
++ leds: leds {
++ compatible = "gpio-leds";
++
++ led_pwr: led-pwr {
++ label = "PWR";
++ gpios = <&rp1_gpio 44 GPIO_ACTIVE_LOW>;
++ default-state = "off";
++ linux,default-trigger = "none";
++ };
++
++ led_act: led-act {
++ label = "ACT";
++ gpios = <&gio_aon 9 GPIO_ACTIVE_LOW>;
++ default-state = "off";
++ linux,default-trigger = "mmc0";
++ };
++ };
++
++ sd_io_1v8_reg: sd_io_1v8_reg {
++ compatible = "regulator-gpio";
++ regulator-name = "vdd-sd-io";
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <3300000>;
++ regulator-boot-on;
++ regulator-always-on;
++ regulator-settling-time-us = <5000>;
++ gpios = <&gio_aon 3 GPIO_ACTIVE_HIGH>;
++ states = <1800000 0x1
++ 3300000 0x0>;
++ status = "okay";
++ };
++
++ sd_vcc_reg: sd_vcc_reg {
++ compatible = "regulator-fixed";
++ regulator-name = "vcc-sd";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ regulator-boot-on;
++ enable-active-high;
++ gpios = <&gio_aon 4 GPIO_ACTIVE_HIGH>;
++ status = "okay";
++ };
++
++ wl_on_reg: wl_on_reg {
++ compatible = "regulator-fixed";
++ regulator-name = "wl-on-regulator";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ pinctrl-0 = <&wl_on_pins>;
++ pinctrl-names = "default";
++
++ gpio = <&gio 28 GPIO_ACTIVE_HIGH>;
++
++ startup-delay-us = <150000>;
++ enable-active-high;
++ };
++
++ clocks: clocks {
++ };
++
++ cam1_clk: cam1_clk {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ status = "disabled";
++ };
++
++ cam0_clk: cam0_clk {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ status = "disabled";
++ };
++
++ cam0_reg: cam0_reg {
++ compatible = "regulator-fixed";
++ regulator-name = "cam0_reg";
++ enable-active-high;
++ status = "okay";
++ gpio = <&rp1_gpio 34 0>; // CD0_IO0_MICCLK, to MIPI 0 connector
++ };
++
++ cam1_reg: cam1_reg {
++ compatible = "regulator-fixed";
++ regulator-name = "cam1_reg";
++ enable-active-high;
++ status = "okay";
++ gpio = <&rp1_gpio 46 0>; // CD1_IO0_MICCLK, to MIPI 1 connector
++ };
++
++ cam_dummy_reg: cam_dummy_reg {
++ compatible = "regulator-fixed";
++ regulator-name = "cam-dummy-reg";
++ status = "okay";
++ };
++
++ dummy: dummy {
++ // A target for unwanted overlay fragments
++ };
++
++
++ // A few extra labels to keep overlays happy
++
++ i2c0if: i2c0if {};
++ i2c0mux: i2c0mux {};
++};
++
++rp1_target: &pcie2 {
++ brcm,enable-mps-rcb;
++ brcm,vdm-qos-map = <0xbbaa9888>;
++ aspm-no-l0s;
++ status = "okay";
++};
++
++&pcie1 {
++ brcm,vdm-qos-map = <0x33333333>;
++};
++
++// Add some labels to 2712 device
++
++// The system UART
++uart10: &_uart0 { status = "okay"; };
++
++// The system SPI for the bootloader EEPROM
++spi10: &_spi0 { status = "okay"; };
++
++i2c_rp1boot: &_i2c3 { };
++
++#include "rp1.dtsi"
++
++&rp1 {
++ // PCIe address space layout:
++ // 00_00000000-00_00xxxxxx = RP1 peripherals
++ // 10_00000000-1x_xxxxxxxx = up to 64GB system RAM
++
++ // outbound access aimed at PCIe 0_00xxxxxx -> RP1 c0_40xxxxxx
++ // This is the RP1 peripheral space
++ ranges = <0xc0 0x40000000
++ 0x02000000 0x00 0x00000000
++ 0x00 0x00400000>;
++
++ dma-ranges =
++ // inbound RP1 1x_xxxxxxxx -> PCIe 1x_xxxxxxxx
++ <0x10 0x00000000
++ 0x43000000 0x10 0x00000000
++ 0x10 0x00000000>,
++
++ // inbound RP1 c0_40xxxxxx -> PCIe 00_00xxxxxx
++ // This allows the RP1 DMA controller to address RP1 hardware
++ <0xc0 0x40000000
++ 0x02000000 0x0 0x00000000
++ 0x0 0x00400000>,
++
++ // inbound RP1 0x_xxxxxxxx -> PCIe 1x_xxxxxxxx
++ <0x00 0x00000000
++ 0x02000000 0x10 0x00000000
++ 0x10 0x00000000>;
++};
++
++// Expose RP1 nodes as system nodes with labels
++
++&rp1_dma {
++ status = "okay";
++};
++
++&rp1_eth {
++ status = "okay";
++ phy-handle = <&phy1>;
++ phy-reset-gpios = <&rp1_gpio 32 GPIO_ACTIVE_LOW>;
++ phy-reset-duration = <5>;
++
++ phy1: ethernet-phy@1 {
++ reg = <0x1>;
++ brcm,powerdown-enable;
++ };
++};
++
++gpio: &rp1_gpio {
++ status = "okay";
++};
++
++aux: &dummy {};
++
++&rp1_usb0 {
++ pinctrl-0 = <&usb_vbus_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++};
++
++&rp1_usb1 {
++ status = "okay";
++};
++
++#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>;
++};
++
++i2c_csi_dsi1: &i2c4 { // Note: This is for MIPI1 connector only
++ pinctrl-0 = <&rp1_i2c4_40_41>;
++ pinctrl-names = "default";
++ clock-frequency = <100000>;
++};
++
++i2c_csi_dsi: &i2c_csi_dsi1 { }; // An alias for compatibility
++
++csi0: &rp1_csi0 { };
++csi1: &rp1_csi1 { };
++dsi0: &rp1_dsi0 { };
++dsi1: &rp1_dsi1 { };
++dpi: &rp1_dpi { };
++vec: &rp1_vec { };
++dpi_gpio0: &rp1_dpi_24bit_gpio0 { };
++dpi_gpio1: &rp1_dpi_24bit_gpio2 { };
++dpi_18bit_cpadhi_gpio0: &rp1_dpi_18bit_cpadhi_gpio0 { };
++dpi_18bit_cpadhi_gpio2: &rp1_dpi_18bit_cpadhi_gpio2 { };
++dpi_18bit_gpio0: &rp1_dpi_18bit_gpio0 { };
++dpi_18bit_gpio2: &rp1_dpi_18bit_gpio2 { };
++dpi_16bit_cpadhi_gpio0: &rp1_dpi_16bit_cpadhi_gpio0 { };
++dpi_16bit_cpadhi_gpio2: &rp1_dpi_16bit_cpadhi_gpio2 { };
++dpi_16bit_gpio0: &rp1_dpi_16bit_gpio0 { };
++dpi_16bit_gpio2: &rp1_dpi_16bit_gpio2 { };
++
++/* Add the IOMMUs for some RP1 bus masters */
++
++&csi0 {
++ iommus = <&iommu5>;
++};
++
++&csi1 {
++ iommus = <&iommu5>;
++};
++
++&dsi0 {
++ iommus = <&iommu5>;
++};
++
++&dsi1 {
++ iommus = <&iommu5>;
++};
++
++&dpi {
++ iommus = <&iommu5>;
++};
++
++&vec {
++ iommus = <&iommu5>;
++};
++
++&ddc0 {
++ status = "disabled";
++};
++
++&ddc1 {
++ status = "disabled";
++};
++
++&hdmi0 {
++ clocks = <&firmware_clocks 13>, <&firmware_clocks 14>, <&dvp 0>, <&clk_27MHz>;
++ clock-names = "hdmi", "bvb", "audio", "cec";
++ status = "disabled";
++};
++
++&hdmi1 {
++ clocks = <&firmware_clocks 13>, <&firmware_clocks 14>, <&dvp 1>, <&clk_27MHz>;
++ clock-names = "hdmi", "bvb", "audio", "cec";
++ status = "disabled";
++};
++
++&hvs {
++ clocks = <&firmware_clocks 4>, <&firmware_clocks 16>;
++ clock-names = "core", "disp";
++};
++
++&mop {
++ status = "disabled";
++};
++
++&moplet {
++ status = "disabled";
++};
++
++&pixelvalve0 {
++ status = "disabled";
++};
++
++&pixelvalve1 {
++ status = "disabled";
++};
++
++&disp_intr {
++ status = "disabled";
++};
++
++/* SDIO1 is used to drive the SD card */
++&sdio1 {
++ pinctrl-0 = <&emmc_sd_pulls>, <&emmc_aon_cd_pins>;
++ pinctrl-names = "default";
++ vqmmc-supply = <&sd_io_1v8_reg>;
++ vmmc-supply = <&sd_vcc_reg>;
++ bus-width = <4>;
++ sd-uhs-sdr50;
++ sd-uhs-ddr50;
++ sd-uhs-sdr104;
++ cd-gpios = <&gio_aon 5 GPIO_ACTIVE_LOW>;
++ //no-1-8-v;
++ status = "okay";
++};
++
++&pinctrl_aon {
++ emmc_aon_cd_pins: emmc_aon_cd_pins {
++ function = "sd_card_g";
++ pins = "aon_gpio5";
++ bias-pull-up;
++ };
++
++ /* Slight hack - only one PWM pin (status LED) is usable */
++ aon_pwm_1pin: aon_pwm_1pin {
++ function = "aon_pwm";
++ pins = "aon_gpio9";
++ };
++};
++
++&pinctrl {
++ pwr_button_pins: pwr_button_pins {
++ function = "gpio";
++ pins = "gpio20";
++ bias-pull-up;
++ };
++
++ wl_on_pins: wl_on_pins {
++ function = "gpio";
++ pins = "gpio28";
++ };
++
++ bt_shutdown_pins: bt_shutdown_pins {
++ function = "gpio";
++ pins = "gpio29";
++ };
++
++ emmc_sd_pulls: emmc_sd_pulls {
++ pins = "emmc_cmd", "emmc_dat0", "emmc_dat1", "emmc_dat2", "emmc_dat3";
++ bias-pull-up;
++ };
++};
++
++/* uarta communicates with the BT module */
++&uarta {
++ uart-has-rtscts;
++ auto-flow-control;
++ status = "okay";
++ clock-frequency = <96000000>;
++ pinctrl-0 = <&uarta_24_pins &bt_shutdown_pins>;
++ pinctrl-names = "default";
++
++ bluetooth: bluetooth {
++ compatible = "brcm,bcm43438-bt";
++ max-speed = <3000000>;
++ shutdown-gpios = <&gio 29 GPIO_ACTIVE_HIGH>;
++ local-bd-address = [ 00 00 00 00 00 00 ];
++ };
++};
++
++&i2c_rp1boot {
++ clock-frequency = <400000>;
++ pinctrl-0 = <&i2c3_m4_agpio0_pins>;
++ pinctrl-names = "default";
++};
++
++/ {
++ 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";
++ #cooling-cells = <2>;
++ cooling-min-state = <0>;
++ cooling-max-state = <3>;
++ cooling-levels = <0 75 125 175 250>;
++ pwms = <&rp1_pwm1 3 41566 PWM_POLARITY_INVERTED>;
++ rpm-regmap = <&rp1_pwm1>;
++ rpm-offset = <0x3c>;
++ };
++
++ pwr_button {
++ compatible = "gpio-keys";
++
++ pinctrl-names = "default";
++ pinctrl-0 = <&pwr_button_pins>;
++ status = "okay";
++
++ pwr_key: pwr {
++ label = "pwr_button";
++ // linux,code = <205>; // KEY_SUSPEND
++ linux,code = <116>; // KEY_POWER
++ gpios = <&gio 20 GPIO_ACTIVE_LOW>;
++ debounce-interval = <50>; // ms
++ };
++ };
++};
++
++&usb {
++ power-domains = <&power RPI_POWER_DOMAIN_USB>;
++};
++
++/* SDIO2 drives the WLAN interface */
++&sdio2 {
++ pinctrl-0 = <&sdio2_30_pins>;
++ pinctrl-names = "default";
++ bus-width = <4>;
++ vmmc-supply = <&wl_on_reg>;
++ sd-uhs-ddr50;
++ non-removable;
++ status = "okay";
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ wifi: wifi@1 {
++ reg = <1>;
++ compatible = "brcm,bcm4329-fmac";
++ local-mac-address = [00 00 00 00 00 00];
++ };
++};
++
++&rpivid {
++ status = "okay";
++};
++
++&pinctrl {
++ spi10_gpio2: spi10_gpio2 {
++ function = "vc_spi0";
++ pins = "gpio2", "gpio3", "gpio4";
++ bias-disable;
++ };
++
++ spi10_cs_gpio1: spi10_cs_gpio1 {
++ function = "gpio";
++ pins = "gpio1";
++ bias-pull-up;
++ };
++};
++
++spi10_pins: &spi10_gpio2 {};
++spi10_cs_pins: &spi10_cs_gpio1 {};
++
++&spi10 {
++ pinctrl-names = "default";
++ cs-gpios = <&gio 1 1>;
++ pinctrl-0 = <&spi10_pins &spi10_cs_pins>;
++
++ spidev10: spidev@0 {
++ compatible = "spidev";
++ reg = <0>; /* CE0 */
++ #address-cells = <1>;
++ #size-cells = <0>;
++ spi-max-frequency = <20000000>;
++ status = "okay";
++ };
++};
++
++// =============================================
++// Board specific stuff here
++
++&gio_aon {
++ // Don't use GIO_AON as an interrupt controller because it will
++ // clash with the firmware monitoring the PMIC interrupt via the VPU.
++
++ /delete-property/ interrupt-controller;
++};
++
++&main_aon_irq {
++ // Don't use the MAIN_AON_IRQ interrupt controller because it will
++ // clash with the firmware monitoring the PMIC interrupt via the VPU.
++
++ status = "disabled";
++};
++
++&rp1_pwm1 {
++ status = "disabled";
++ pinctrl-0 = <&rp1_pwm1_gpio45>;
++ pinctrl-names = "default";
++};
++
++&thermal_trips {
++ cpu_tepid: cpu-tepid {
++ temperature = <50000>;
++ hysteresis = <5000>;
++ type = "active";
++ };
++
++ cpu_warm: cpu-warm {
++ temperature = <60000>;
++ hysteresis = <5000>;
++ type = "active";
++ };
++
++ cpu_hot: cpu-hot {
++ temperature = <67500>;
++ hysteresis = <5000>;
++ type = "active";
++ };
++
++ cpu_vhot: cpu-vhot {
++ temperature = <75000>;
++ hysteresis = <5000>;
++ type = "active";
++ };
++};
++
++&cooling_maps {
++ tepid {
++ trip = <&cpu_tepid>;
++ cooling-device = <&fan 1 1>;
++ };
++
++ warm {
++ trip = <&cpu_warm>;
++ cooling-device = <&fan 2 2>;
++ };
++
++ hot {
++ trip = <&cpu_hot>;
++ cooling-device = <&fan 3 3>;
++ };
++
++ vhot {
++ trip = <&cpu_vhot>;
++ cooling-device = <&fan 4 4>;
++ };
++
++ melt {
++ trip = <&cpu_crit>;
++ cooling-device = <&fan 4 4>;
++ };
++};
++
++&gio {
++ // The GPIOs above 35 are not used on Pi 5, so shrink the upper bank
++ // to reduce the clutter in gpioinfo/pinctrl
++ brcm,gpio-bank-widths = <32 4>;
++
++ 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
++ "PCIE_SDA", // GPIO_014
++ "PCIE_SCL", // GPIO_015
++ "-", // GPIO_016
++ "-", // GPIO_017
++ "-", // GPIO_018
++ "-", // GPIO_019
++ "PWR_GPIO", // GPIO_020
++ "2712_G21_FS", // 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_run_hog {
++ gpio-hog;
++ gpios = <2 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "RP1 RUN pin";
++ };
++};
++
++&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
++ "FAN_TACH", // GPIO29
++ "HOST_SDA", // GPIO30
++ "HOST_SCL", // GPIO31
++ "ETH_RST_N", // GPIO32
++ "-", // GPIO33
++
++ "CD0_IO0_MICCLK", // GPIO34
++ "CD0_IO0_MICDAT0", // GPIO35
++ "RP1_PCIE_CLKREQ_N", // GPIO36
++ "-", // GPIO37
++ "CD0_SDA", // GPIO38
++ "CD0_SCL", // GPIO39
++ "CD1_SDA", // GPIO40
++ "CD1_SCL", // GPIO41
++ "USB_VBUS_EN", // GPIO42
++ "USB_OC_N", // GPIO43
++ "RP1_STAT_LED", // GPIO44
++ "FAN_PWM", // GPIO45
++ "CD1_IO0_MICCLK", // GPIO46
++ "2712_WAKE", // GPIO47
++ "CD1_IO1_MICDAT1", // GPIO48
++ "EN_MAX_USB_CUR", // GPIO49
++ "-", // GPIO50
++ "-", // GPIO51
++ "-", // GPIO52
++ "-"; // GPIO53
++
++ usb_vbus_pins: usb_vbus_pins {
++ function = "vbus1";
++ pins = "gpio42", "gpio43";
++ };
++};
++
++/ {
++ aliases: aliases {
++ blconfig = &blconfig;
++ blpubkey = &blpubkey;
++ bluetooth = &bluetooth;
++ console = &uart10;
++ ethernet0 = &rp1_eth;
++ wifi0 = &wifi;
++ fb = &fb;
++ mailbox = &mailbox;
++ mmc0 = &sdio1;
++ uart0 = &uart0;
++ uart1 = &uart1;
++ uart2 = &uart2;
++ uart3 = &uart3;
++ uart4 = &uart4;
++ uart10 = &uart10;
++ serial0 = &uart0;
++ serial1 = &uart1;
++ serial2 = &uart2;
++ serial3 = &uart3;
++ serial4 = &uart4;
++ serial10 = &uart10;
++ i2c = &i2c_arm;
++ i2c0 = &i2c0;
++ i2c1 = &i2c1;
++ i2c2 = &i2c2;
++ i2c3 = &i2c3;
++ i2c4 = &i2c4;
++ i2c5 = &i2c5;
++ i2c6 = &i2c6;
++ i2c10 = &i2c_rp1boot;
++ // Bit-bashed i2c_gpios start at 10
++ spi0 = &spi0;
++ spi1 = &spi1;
++ spi2 = &spi2;
++ spi3 = &spi3;
++ spi4 = &spi4;
++ spi5 = &spi5;
++ spi10 = &spi10;
++ gpio0 = &gpio;
++ gpio1 = &gio;
++ gpio2 = &gio_aon;
++ gpio3 = &pinctrl;
++ gpio4 = &pinctrl_aon;
++ usb0 = &rp1_usb0;
++ usb1 = &rp1_usb1;
++ drm-dsi1 = &dsi0;
++ drm-dsi2 = &dsi1;
++ };
++
++ __overrides__ {
++ bdaddr = <&bluetooth>, "local-bd-address[";
++ button_debounce = <&pwr_key>, "debounce-interval:0";
++ cooling_fan = <&fan>, "status", <&rp1_pwm1>, "status";
++ uart0_console = <&uart0>,"status", <&aliases>, "console=",&uart0;
++ i2c0 = <&i2c0>, "status";
++ i2c1 = <&i2c1>, "status";
++ i2c = <&i2c1>, "status";
++ i2c_arm = <&i2c_arm>, "status";
++ i2c_vc = <&i2c_vc>, "status";
++ i2c_csi_dsi = <&i2c_csi_dsi>, "status";
++ i2c_csi_dsi0 = <&i2c_csi_dsi0>, "status";
++ i2c_csi_dsi1 = <&i2c_csi_dsi1>, "status";
++ i2c0_baudrate = <&i2c0>, "clock-frequency:0";
++ i2c1_baudrate = <&i2c1>, "clock-frequency:0";
++ i2c_baudrate = <&i2c_arm>, "clock-frequency:0";
++ i2c_arm_baudrate = <&i2c_arm>, "clock-frequency:0";
++ i2c_vc_baudrate = <&i2c_vc>, "clock-frequency:0";
++ krnbt = <&bluetooth>, "status";
++ nvme = <&pciex1>, "status";
++ pciex1 = <&pciex1>, "status";
++ pciex1_gen = <&pciex1> , "max-link-speed:0";
++ pciex1_no_l0s = <&pciex1>, "aspm-no-l0s?";
++ pciex1_tperst_clk_ms = <&pciex1>, "brcm,tperst-clk-ms:0";
++ pcie_tperst_clk_ms = <&pciex1>, "brcm,tperst-clk-ms:0";
++ random = <&random>, "status";
++ rtc = <&rpi_rtc>, "status";
++ rtc_bbat_vchg = <&rpi_rtc>, "trickle-charge-microvolt:0";
++ sd_cqe = <&sdio1>, "supports-cqe?";
++ spi = <&spi0>, "status";
++ suspend = <&pwr_key>, "linux,code:0=205";
++ uart0 = <&uart0>, "status";
++ wifiaddr = <&wifi>, "local-mac-address[";
++
++ act_led_gpio = <&led_act>,"gpios:4",<&led_act>,"gpios:0=",<&gpio>;
++ act_led_activelow = <&led_act>,"gpios:8";
++ act_led_trigger = <&led_act>, "linux,default-trigger";
++ pwr_led_gpio = <&led_pwr>,"gpios:4";
++ pwr_led_activelow = <&led_pwr>, "gpios:8";
++ pwr_led_trigger = <&led_pwr>, "linux,default-trigger";
++ eth_led0 = <&phy1>,"led-modes:0";
++ eth_led1 = <&phy1>,"led-modes:4";
++ drm_fb0_rp1_dsi0 = <&aliases>, "drm-fb0=",&dsi0;
++ drm_fb0_rp1_dsi1 = <&aliases>, "drm-fb0=",&dsi1;
++ drm_fb0_rp1_dpi = <&aliases>, "drm-fb0=",&dpi;
++ drm_fb0_vc4 = <&aliases>, "drm-fb0=",&vc4;
++ drm_fb1_rp1_dsi0 = <&aliases>, "drm-fb1=",&dsi0;
++ drm_fb1_rp1_dsi1 = <&aliases>, "drm-fb1=",&dsi1;
++ drm_fb1_rp1_dpi = <&aliases>, "drm-fb1=",&dpi;
++ drm_fb1_vc4 = <&aliases>, "drm-fb1=",&vc4;
++ drm_fb2_rp1_dsi0 = <&aliases>, "drm-fb2=",&dsi0;
++ drm_fb2_rp1_dsi1 = <&aliases>, "drm-fb2=",&dsi1;
++ drm_fb2_rp1_dpi = <&aliases>, "drm-fb2=",&dpi;
++ drm_fb2_vc4 = <&aliases>, "drm-fb2=",&vc4;
++
++ fan_temp0 = <&cpu_tepid>,"temperature:0";
++ fan_temp1 = <&cpu_warm>,"temperature:0";
++ fan_temp2 = <&cpu_hot>,"temperature:0";
++ fan_temp3 = <&cpu_vhot>,"temperature:0";
++ fan_temp0_hyst = <&cpu_tepid>,"hysteresis:0";
++ fan_temp1_hyst = <&cpu_warm>,"hysteresis:0";
++ fan_temp2_hyst = <&cpu_hot>,"hysteresis:0";
++ fan_temp3_hyst = <&cpu_vhot>,"hysteresis:0";
++ fan_temp0_speed = <&fan>, "cooling-levels:4";
++ fan_temp1_speed = <&fan>, "cooling-levels:8";
++ fan_temp2_speed = <&fan>, "cooling-levels:12";
++ fan_temp3_speed = <&fan>, "cooling-levels:16";
++ };
++};
+--- a/arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5-cm4io.dts
++++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5-cm4io.dts
+@@ -1,2 +1,20 @@
+ // SPDX-License-Identifier: GPL-2.0
+-#include "arm/broadcom/bcm2712-rpi-cm5-cm4io.dts"
++/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";
++ };
++};
+--- a/arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5-cm5io.dts
++++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5-cm5io.dts
+@@ -1,2 +1,10 @@
+ // SPDX-License-Identifier: GPL-2.0
+-#include "arm/broadcom/bcm2712-rpi-cm5-cm5io.dts"
++/dts-v1/;
++
++#include "bcm2712-rpi-cm5.dtsi"
++
++/ {
++ __overrides__ {
++ i2c_csi_dsi = <&i2c_csi_dsi>, "status";
++ };
++};
+--- a/arch/arm/boot/dts/broadcom/bcm2712-rpi-cm5.dtsi
++++ /dev/null
+@@ -1,890 +0,0 @@
+-// SPDX-License-Identifier: GPL-2.0
+-
+-#include <dt-bindings/gpio/gpio.h>
+-#include <dt-bindings/clock/rp1.h>
+-#include <dt-bindings/interrupt-controller/irq.h>
+-#include <dt-bindings/mfd/rp1.h>
+-#include <dt-bindings/pwm/pwm.h>
+-#include <dt-bindings/reset/raspberrypi,firmware-reset.h>
+-
+-#define i2c0 _i2c0
+-#define i2c3 _i2c3
+-#define i2c4 _i2c4
+-#define i2c5 _i2c5
+-#define i2c6 _i2c6
+-#define i2c8 _i2c8
+-#define i2s _i2s
+-#define pwm0 _pwm0
+-#define pwm1 _pwm1
+-#define spi0 _spi0
+-#define spi3 _spi3
+-#define spi4 _spi4
+-#define spi5 _spi5
+-#define spi6 _spi6
+-#define uart0 _uart0
+-#define uart2 _uart2
+-#define uart5 _uart5
+-
+-#include "bcm2712.dtsi"
+-
+-#undef i2c0
+-#undef i2c3
+-#undef i2c4
+-#undef i2c5
+-#undef i2c6
+-#undef i2c8
+-#undef i2s
+-#undef pwm0
+-#undef pwm1
+-#undef spi0
+-#undef spi3
+-#undef spi4
+-#undef spi5
+-#undef spi6
+-#undef uart0
+-#undef uart2
+-#undef uart3
+-#undef uart4
+-#undef uart5
+-
+-/ {
+- compatible = "raspberrypi,5-compute-module", "brcm,bcm2712";
+- model = "Raspberry Pi Compute Module 5";
+-
+- /* Will be filled by the bootloader */
+- memory@0 {
+- device_type = "memory";
+- reg = <0 0 0x28000000>;
+- };
+-
+- leds: leds {
+- compatible = "gpio-leds";
+-
+- led_pwr: led-pwr {
+- label = "PWR";
+- gpios = <&rp1_gpio 44 GPIO_ACTIVE_LOW>;
+- default-state = "off";
+- linux,default-trigger = "none";
+- };
+-
+- led_act: led-act {
+- label = "ACT";
+- gpios = <&gio_aon 9 GPIO_ACTIVE_LOW>;
+- default-state = "off";
+- linux,default-trigger = "mmc0";
+- };
+- };
+-
+- sd_io_1v8_reg: sd_io_1v8_reg {
+- compatible = "regulator-gpio";
+- regulator-name = "vdd-sd-io";
+- regulator-min-microvolt = <1800000>;
+- regulator-max-microvolt = <3300000>;
+- regulator-boot-on;
+- regulator-always-on;
+- regulator-settling-time-us = <5000>;
+- gpios = <&gio_aon 3 GPIO_ACTIVE_HIGH>;
+- states = <1800000 0x1
+- 3300000 0x0>;
+- status = "okay";
+- };
+-
+- sd_vcc_reg: sd_vcc_reg {
+- compatible = "regulator-fixed";
+- regulator-name = "vcc-sd";
+- regulator-min-microvolt = <3300000>;
+- regulator-max-microvolt = <3300000>;
+- regulator-boot-on;
+- enable-active-high;
+- gpios = <&gio_aon 4 GPIO_ACTIVE_HIGH>;
+- status = "okay";
+- };
+-
+- wl_on_reg: wl_on_reg {
+- compatible = "regulator-fixed";
+- regulator-name = "wl-on-regulator";
+- regulator-min-microvolt = <3300000>;
+- regulator-max-microvolt = <3300000>;
+- pinctrl-0 = <&wl_on_pins>;
+- pinctrl-names = "default";
+-
+- gpio = <&gio 28 GPIO_ACTIVE_HIGH>;
+-
+- startup-delay-us = <150000>;
+- enable-active-high;
+- };
+-
+- clocks: clocks {
+- };
+-
+- cam1_clk: cam1_clk {
+- compatible = "fixed-clock";
+- #clock-cells = <0>;
+- status = "disabled";
+- };
+-
+- cam0_clk: cam0_clk {
+- compatible = "fixed-clock";
+- #clock-cells = <0>;
+- status = "disabled";
+- };
+-
+- cam0_reg: cam0_reg {
+- compatible = "regulator-fixed";
+- regulator-name = "cam0_reg";
+- enable-active-high;
+- status = "okay";
+- gpio = <&rp1_gpio 34 0>; // CD0_IO0_MICCLK, to CAM_GPIO on connector
+- };
+-
+- cam_dummy_reg: cam_dummy_reg {
+- compatible = "regulator-fixed";
+- regulator-name = "cam-dummy-reg";
+- status = "okay";
+- };
+-
+- dummy: dummy {
+- // A target for unwanted overlay fragments
+- };
+-
+-
+- // A few extra labels to keep overlays happy
+-
+- i2c0if: i2c0if {};
+- i2c0mux: i2c0mux {};
+-};
+-
+-rp1_target: &pcie2 {
+- brcm,enable-mps-rcb;
+- brcm,vdm-qos-map = <0xbbaa9888>;
+- aspm-no-l0s;
+- status = "okay";
+-};
+-
+-// Add some labels to 2712 device
+-
+-// The system UART
+-uart10: &_uart0 { status = "okay"; };
+-
+-// The system SPI for the bootloader EEPROM
+-spi10: &_spi0 { status = "okay"; };
+-
+-i2c_rp1boot: &_i2c3 { };
+-
+-#include "rp1.dtsi"
+-
+-&rp1 {
+- // PCIe address space layout:
+- // 00_00000000-00_00xxxxxx = RP1 peripherals
+- // 10_00000000-1x_xxxxxxxx = up to 64GB system RAM
+-
+- // outbound access aimed at PCIe 0_00xxxxxx -> RP1 c0_40xxxxxx
+- // This is the RP1 peripheral space
+- ranges = <0xc0 0x40000000
+- 0x02000000 0x00 0x00000000
+- 0x00 0x00400000>;
+-
+- dma-ranges =
+- // inbound RP1 1x_xxxxxxxx -> PCIe 1x_xxxxxxxx
+- <0x10 0x00000000
+- 0x43000000 0x10 0x00000000
+- 0x10 0x00000000>,
+-
+- // inbound RP1 c0_40xxxxxx -> PCIe 00_00xxxxxx
+- // This allows the RP1 DMA controller to address RP1 hardware
+- <0xc0 0x40000000
+- 0x02000000 0x0 0x00000000
+- 0x0 0x00400000>,
+-
+- // inbound RP1 0x_xxxxxxxx -> PCIe 1x_xxxxxxxx
+- <0x00 0x00000000
+- 0x02000000 0x10 0x00000000
+- 0x10 0x00000000>;
+-};
+-
+-// Expose RP1 nodes as system nodes with labels
+-
+-&rp1_dma {
+- status = "okay";
+-};
+-
+-&rp1_eth {
+- status = "okay";
+- phy-handle = <&phy1>;
+- phy-reset-gpios = <&rp1_gpio 32 GPIO_ACTIVE_LOW>;
+- phy-reset-duration = <5>;
+-
+- phy1: ethernet-phy@1 {
+- reg = <0x1>;
+- brcm,powerdown-enable;
+- interrupt-parent = <&gpio>;
+- interrupts = <37 IRQ_TYPE_LEVEL_LOW>;
+- };
+-};
+-
+-gpio: &rp1_gpio {
+- status = "okay";
+-};
+-
+-aux: &dummy {};
+-
+-&rp1_usb0 {
+- pinctrl-0 = <&usb_vbus_pins>;
+- pinctrl-names = "default";
+- status = "okay";
+-};
+-
+-&rp1_usb1 {
+- status = "okay";
+-};
+-
+-#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>;
+-};
+-
+-i2c_csi_dsi1: &i2c0 { // Note: This is for MIPI1 connector
+-};
+-
+-i2c_csi_dsi: &i2c_csi_dsi1 { }; // An alias for compatibility
+-
+-cam1_reg: &cam0_reg { // Shares CAM_GPIO with cam0_reg
+-};
+-
+-csi0: &rp1_csi0 { };
+-csi1: &rp1_csi1 { };
+-dsi0: &rp1_dsi0 { };
+-dsi1: &rp1_dsi1 { };
+-dpi: &rp1_dpi { };
+-vec: &rp1_vec { };
+-dpi_gpio0: &rp1_dpi_24bit_gpio0 { };
+-dpi_gpio1: &rp1_dpi_24bit_gpio2 { };
+-dpi_18bit_cpadhi_gpio0: &rp1_dpi_18bit_cpadhi_gpio0 { };
+-dpi_18bit_cpadhi_gpio2: &rp1_dpi_18bit_cpadhi_gpio2 { };
+-dpi_18bit_gpio0: &rp1_dpi_18bit_gpio0 { };
+-dpi_18bit_gpio2: &rp1_dpi_18bit_gpio2 { };
+-dpi_16bit_cpadhi_gpio0: &rp1_dpi_16bit_cpadhi_gpio0 { };
+-dpi_16bit_cpadhi_gpio2: &rp1_dpi_16bit_cpadhi_gpio2 { };
+-dpi_16bit_gpio0: &rp1_dpi_16bit_gpio0 { };
+-dpi_16bit_gpio2: &rp1_dpi_16bit_gpio2 { };
+-
+-/* Add the IOMMUs for some RP1 bus masters */
+-
+-&csi0 {
+- iommus = <&iommu5>;
+-};
+-
+-&csi1 {
+- iommus = <&iommu5>;
+-};
+-
+-&dsi0 {
+- iommus = <&iommu5>;
+-};
+-
+-&dsi1 {
+- iommus = <&iommu5>;
+-};
+-
+-&dpi {
+- iommus = <&iommu5>;
+-};
+-
+-&vec {
+- iommus = <&iommu5>;
+-};
+-
+-&ddc0 {
+- status = "disabled";
+-};
+-
+-&ddc1 {
+- status = "disabled";
+-};
+-
+-&hdmi0 {
+- clocks = <&firmware_clocks 13>, <&firmware_clocks 14>, <&dvp 0>, <&clk_27MHz>;
+- clock-names = "hdmi", "bvb", "audio", "cec";
+- status = "disabled";
+-};
+-
+-&hdmi1 {
+- clocks = <&firmware_clocks 13>, <&firmware_clocks 14>, <&dvp 1>, <&clk_27MHz>;
+- clock-names = "hdmi", "bvb", "audio", "cec";
+- status = "disabled";
+-};
+-
+-&hvs {
+- clocks = <&firmware_clocks 4>, <&firmware_clocks 16>;
+- clock-names = "core", "disp";
+-};
+-
+-&mop {
+- status = "disabled";
+-};
+-
+-&moplet {
+- status = "disabled";
+-};
+-
+-&pixelvalve0 {
+- status = "disabled";
+-};
+-
+-&pixelvalve1 {
+- status = "disabled";
+-};
+-
+-&disp_intr {
+- status = "disabled";
+-};
+-
+-/* SDIO1 is used to drive the eMMC/SD card */
+-&sdio1 {
+- pinctrl-0 = <&emmc_cmddat_pulls>, <&emmc_ds_pull>;
+- pinctrl-names = "default";
+- vqmmc-supply = <&sd_io_1v8_reg>;
+- vmmc-supply = <&sd_vcc_reg>;
+- bus-width = <8>;
+- sd-uhs-sdr50;
+- sd-uhs-ddr50;
+- sd-uhs-sdr104;
+- mmc-hs200-1_8v;
+- mmc-hs400-1_8v;
+- mmc-hs400-enhanced-strobe;
+- broken-cd;
+- supports-cqe;
+- status = "okay";
+-};
+-
+-&pinctrl_aon {
+- ant_pins: ant_pins {
+- function = "gpio";
+- pins = "aon_gpio5", "aon_gpio6";
+- };
+-
+- /* Slight hack - only one PWM pin (status LED) is usable */
+- aon_pwm_1pin: aon_pwm_1pin {
+- function = "aon_pwm";
+- pins = "aon_gpio9";
+- };
+-};
+-
+-&pinctrl {
+- pwr_button_pins: pwr_button_pins {
+- function = "gpio";
+- pins = "gpio20";
+- bias-pull-up;
+- };
+-
+- wl_on_pins: wl_on_pins {
+- function = "gpio";
+- pins = "gpio28";
+- };
+-
+- bt_shutdown_pins: bt_shutdown_pins {
+- function = "gpio";
+- pins = "gpio29";
+- };
+-
+- emmc_ds_pull: emmc_ds_pull {
+- pins = "emmc_ds";
+- bias-pull-down;
+- };
+-
+- emmc_cmddat_pulls: emmc_cmddat_pulls {
+- pins = "emmc_cmd", "emmc_dat0", "emmc_dat1", "emmc_dat2", "emmc_dat3",
+- "emmc_dat4", "emmc_dat5", "emmc_dat6", "emmc_dat7";
+- bias-pull-up;
+- };
+-};
+-
+-/* uarta communicates with the BT module */
+-&uarta {
+- uart-has-rtscts;
+- auto-flow-control;
+- status = "okay";
+- clock-frequency = <96000000>;
+- pinctrl-0 = <&uarta_24_pins &bt_shutdown_pins>;
+- pinctrl-names = "default";
+-
+- bluetooth: bluetooth {
+- compatible = "brcm,bcm43438-bt";
+- max-speed = <3000000>;
+- shutdown-gpios = <&gio 29 GPIO_ACTIVE_HIGH>;
+- local-bd-address = [ 00 00 00 00 00 00 ];
+- };
+-};
+-
+-&i2c_rp1boot {
+- clock-frequency = <400000>;
+- pinctrl-0 = <&i2c3_m4_agpio0_pins>;
+- pinctrl-names = "default";
+-};
+-
+-/ {
+- 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";
+- #cooling-cells = <2>;
+- cooling-min-state = <0>;
+- cooling-max-state = <3>;
+- cooling-levels = <0 75 125 175 250>;
+- pwms = <&rp1_pwm1 3 41566 PWM_POLARITY_INVERTED>;
+- rpm-regmap = <&rp1_pwm1>;
+- rpm-offset = <0x3c>;
+- };
+-
+- pwr_button {
+- compatible = "gpio-keys";
+-
+- pinctrl-names = "default";
+- pinctrl-0 = <&pwr_button_pins>;
+- status = "okay";
+-
+- pwr_key: pwr {
+- label = "pwr_button";
+- // linux,code = <205>; // KEY_SUSPEND
+- linux,code = <116>; // KEY_POWER
+- gpios = <&gio 20 GPIO_ACTIVE_LOW>;
+- debounce-interval = <50>; // ms
+- };
+- };
+-};
+-
+-&usb {
+- power-domains = <&power RPI_POWER_DOMAIN_USB>;
+-};
+-
+-/* SDIO2 drives the WLAN interface */
+-&sdio2 {
+- pinctrl-0 = <&sdio2_30_pins>, <&ant_pins>;
+- pinctrl-names = "default";
+- bus-width = <4>;
+- vmmc-supply = <&wl_on_reg>;
+- sd-uhs-ddr50;
+- non-removable;
+- status = "okay";
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- wifi: wifi@1 {
+- reg = <1>;
+- compatible = "brcm,bcm4329-fmac";
+- local-mac-address = [00 00 00 00 00 00];
+- };
+-};
+-
+-&rpivid {
+- status = "okay";
+-};
+-
+-&pinctrl {
+- spi10_gpio2: spi10_gpio2 {
+- function = "vc_spi0";
+- pins = "gpio2", "gpio3", "gpio4";
+- bias-disable;
+- };
+-
+- spi10_cs_gpio1: spi10_cs_gpio1 {
+- function = "gpio";
+- pins = "gpio1";
+- bias-pull-up;
+- };
+-};
+-
+-spi10_pins: &spi10_gpio2 {};
+-spi10_cs_pins: &spi10_cs_gpio1 {};
+-
+-&spi10 {
+- pinctrl-names = "default";
+- cs-gpios = <&gio 1 1>;
+- pinctrl-0 = <&spi10_pins &spi10_cs_pins>;
+-
+- spidev10: spidev@0 {
+- compatible = "spidev";
+- reg = <0>; /* CE0 */
+- #address-cells = <1>;
+- #size-cells = <0>;
+- spi-max-frequency = <20000000>;
+- status = "okay";
+- };
+-};
+-
+-// =============================================
+-// Board specific stuff here
+-
+-&gio_aon {
+- // Don't use GIO_AON as an interrupt controller because it will
+- // clash with the firmware monitoring the PMIC interrupt via the VPU.
+-
+- /delete-property/ interrupt-controller;
+-};
+-
+-&main_aon_irq {
+- // Don't use the MAIN_AON_IRQ interrupt controller because it will
+- // clash with the firmware monitoring the PMIC interrupt via the VPU.
+-
+- status = "disabled";
+-};
+-
+-&rp1_pwm1 {
+- status = "disabled";
+- pinctrl-0 = <&rp1_pwm1_gpio45>;
+- pinctrl-names = "default";
+-};
+-
+-&thermal_trips {
+- cpu_tepid: cpu-tepid {
+- temperature = <50000>;
+- hysteresis = <5000>;
+- type = "active";
+- };
+-
+- cpu_warm: cpu-warm {
+- temperature = <60000>;
+- hysteresis = <5000>;
+- type = "active";
+- };
+-
+- cpu_hot: cpu-hot {
+- temperature = <67500>;
+- hysteresis = <5000>;
+- type = "active";
+- };
+-
+- cpu_vhot: cpu-vhot {
+- temperature = <75000>;
+- hysteresis = <5000>;
+- type = "active";
+- };
+-};
+-
+-&cooling_maps {
+- tepid {
+- trip = <&cpu_tepid>;
+- cooling-device = <&fan 1 1>;
+- };
+-
+- warm {
+- trip = <&cpu_warm>;
+- cooling-device = <&fan 2 2>;
+- };
+-
+- hot {
+- trip = <&cpu_hot>;
+- cooling-device = <&fan 3 3>;
+- };
+-
+- vhot {
+- trip = <&cpu_vhot>;
+- cooling-device = <&fan 4 4>;
+- };
+-
+- melt {
+- trip = <&cpu_crit>;
+- cooling-device = <&fan 4 4>;
+- };
+-};
+-
+-&gio {
+- // The GPIOs above 35 are not used on Pi 5, so shrink the upper bank
+- // to reduce the clutter in gpioinfo/pinctrl
+- brcm,gpio-bank-widths = <32 4>;
+-
+- 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
+- "-", // GPIO_014
+- "-", // GPIO_015
+- "-", // GPIO_016
+- "-", // GPIO_017
+- "-", // GPIO_018
+- "-", // GPIO_019
+- "PWR_GPIO", // GPIO_020
+- "2712_G21_FS", // 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
+- "ANT1", // AON_GPIO_05
+- "ANT2", // 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_run_hog {
+- gpio-hog;
+- gpios = <2 GPIO_ACTIVE_HIGH>;
+- output-high;
+- line-name = "RP1 RUN pin";
+- };
+-
+- ant1: ant1-hog {
+- gpio-hog;
+- gpios = <5 GPIO_ACTIVE_HIGH>;
+- /* internal antenna enabled */
+- output-high;
+- line-name = "ant1";
+- };
+-
+- ant2: ant2-hog {
+- gpio-hog;
+- gpios = <6 GPIO_ACTIVE_HIGH>;
+- /* external antenna disabled */
+- output-low;
+- line-name = "ant2";
+- };
+-};
+-
+-&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_PWR_EN", // GPIO28
+- "FAN_TACH", // GPIO29
+- "HOST_SDA", // GPIO30
+- "HOST_SCL", // GPIO31
+- "ETH_RST_N", // GPIO32
+- "PCIE_DET_WAKE", // GPIO33
+-
+- "CD0_IO0_MICCLK", // GPIO34
+- "CD0_IO0_MICDAT0", // GPIO35
+- "RP1_PCIE_CLKREQ_N", // GPIO36
+- "ETH_IRQ_N", // GPIO37
+- "SDA0", // GPIO38
+- "SCL0", // GPIO39
+- "-", // GPIO40
+- "-", // GPIO41
+- "USB_VBUS_EN", // GPIO42
+- "USB_OC_N", // GPIO43
+- "RP1_STAT_LED", // GPIO44
+- "FAN_PWM", // GPIO45
+- "-", // GPIO46
+- "2712_WAKE", // GPIO47
+- "-", // GPIO48
+- "-", // GPIO49
+- "-", // GPIO50
+- "-", // GPIO51
+- "-", // GPIO52
+- "-"; // GPIO53
+-
+- usb_vbus_pins: usb_vbus_pins {
+- function = "vbus1";
+- pins = "gpio42", "gpio43";
+- };
+-};
+-
+-/ {
+- aliases: aliases {
+- blconfig = &blconfig;
+- blpubkey = &blpubkey;
+- bluetooth = &bluetooth;
+- console = &uart10;
+- ethernet0 = &rp1_eth;
+- wifi0 = &wifi;
+- fb = &fb;
+- mailbox = &mailbox;
+- mmc0 = &sdio1;
+- uart0 = &uart0;
+- uart1 = &uart1;
+- uart2 = &uart2;
+- uart3 = &uart3;
+- uart4 = &uart4;
+- uart10 = &uart10;
+- serial0 = &uart0;
+- serial1 = &uart1;
+- serial2 = &uart2;
+- serial3 = &uart3;
+- serial4 = &uart4;
+- serial10 = &uart10;
+- i2c = &i2c_arm;
+- i2c0 = &i2c0;
+- i2c1 = &i2c1;
+- i2c2 = &i2c2;
+- i2c3 = &i2c3;
+- i2c4 = &i2c4;
+- i2c5 = &i2c5;
+- i2c6 = &i2c6;
+- i2c10 = &i2c_rp1boot;
+- // Bit-bashed i2c_gpios start at 10
+- spi0 = &spi0;
+- spi1 = &spi1;
+- spi2 = &spi2;
+- spi3 = &spi3;
+- spi4 = &spi4;
+- spi5 = &spi5;
+- spi10 = &spi10;
+- gpio0 = &gpio;
+- gpio1 = &gio;
+- gpio2 = &gio_aon;
+- gpio3 = &pinctrl;
+- gpio4 = &pinctrl_aon;
+- usb0 = &rp1_usb0;
+- usb1 = &rp1_usb1;
+- drm-dsi1 = &dsi0;
+- drm-dsi2 = &dsi1;
+- };
+-
+- __overrides__ {
+- bdaddr = <&bluetooth>, "local-bd-address[";
+- button_debounce = <&pwr_key>, "debounce-interval:0";
+- cooling_fan = <&fan>, "status", <&rp1_pwm1>, "status";
+- uart0_console = <&uart0>,"status", <&aliases>, "console=",&uart0;
+- i2c0 = <&i2c0>, "status";
+- i2c1 = <&i2c1>, "status";
+- i2c = <&i2c1>, "status";
+- i2c_arm = <&i2c_arm>, "status";
+- i2c_vc = <&i2c_vc>, "status";
+- i2c_csi_dsi = <&i2c_csi_dsi>, "status";
+- i2c_csi_dsi0 = <&i2c_csi_dsi0>, "status";
+- i2c_csi_dsi1 = <&i2c_csi_dsi1>, "status";
+- i2c0_baudrate = <&i2c0>, "clock-frequency:0";
+- i2c1_baudrate = <&i2c1>, "clock-frequency:0";
+- i2c_baudrate = <&i2c_arm>, "clock-frequency:0";
+- i2c_arm_baudrate = <&i2c_arm>, "clock-frequency:0";
+- i2c_vc_baudrate = <&i2c_vc>, "clock-frequency:0";
+- krnbt = <&bluetooth>, "status";
+- nvme = <&pciex1>, "status";
+- pciex1 = <&pciex1>, "status";
+- pciex1_gen = <&pciex1> , "max-link-speed:0";
+- pciex1_no_l0s = <&pciex1>, "aspm-no-l0s?";
+- pciex1_tperst_clk_ms = <&pciex1>, "brcm,tperst-clk-ms:0";
+- pcie_tperst_clk_ms = <&pciex1>, "brcm,tperst-clk-ms:0";
+- random = <&random>, "status";
+- rtc = <&rpi_rtc>, "status";
+- rtc_bbat_vchg = <&rpi_rtc>, "trickle-charge-microvolt:0";
+- spi = <&spi0>, "status";
+- suspend = <&pwr_key>, "linux,code:0=205";
+- uart0 = <&uart0>, "status";
+- wifiaddr = <&wifi>, "local-mac-address[";
+-
+- act_led_activelow = <&led_act>, "active-low?";
+- act_led_trigger = <&led_act>, "linux,default-trigger";
+- pwr_led_activelow = <&led_pwr>, "gpios:8";
+- pwr_led_trigger = <&led_pwr>, "linux,default-trigger";
+- eth_led0 = <&phy1>,"led-modes:0";
+- eth_led1 = <&phy1>,"led-modes:4";
+- drm_fb0_rp1_dsi0 = <&aliases>, "drm-fb0=",&dsi0;
+- drm_fb0_rp1_dsi1 = <&aliases>, "drm-fb0=",&dsi1;
+- drm_fb0_rp1_dpi = <&aliases>, "drm-fb0=",&dpi;
+- drm_fb0_vc4 = <&aliases>, "drm-fb0=",&vc4;
+- drm_fb1_rp1_dsi0 = <&aliases>, "drm-fb1=",&dsi0;
+- drm_fb1_rp1_dsi1 = <&aliases>, "drm-fb1=",&dsi1;
+- drm_fb1_rp1_dpi = <&aliases>, "drm-fb1=",&dpi;
+- drm_fb1_vc4 = <&aliases>, "drm-fb1=",&vc4;
+- drm_fb2_rp1_dsi0 = <&aliases>, "drm-fb2=",&dsi0;
+- drm_fb2_rp1_dsi1 = <&aliases>, "drm-fb2=",&dsi1;
+- drm_fb2_rp1_dpi = <&aliases>, "drm-fb2=",&dpi;
+- drm_fb2_vc4 = <&aliases>, "drm-fb2=",&vc4;
+-
+- ant1 = <&ant1>,"output-high?=on",
+- <&ant1>, "output-low?=off",
+- <&ant2>, "output-high?=off",
+- <&ant2>, "output-low?=on";
+- ant2 = <&ant1>,"output-high?=off",
+- <&ant1>, "output-low?=on",
+- <&ant2>, "output-high?=on",
+- <&ant2>, "output-low?=off";
+- noant = <&ant1>,"output-high?=off",
+- <&ant1>, "output-low?=on",
+- <&ant2>, "output-high?=off",
+- <&ant2>, "output-low?=on";
+-
+- fan_temp0 = <&cpu_tepid>,"temperature:0";
+- fan_temp1 = <&cpu_warm>,"temperature:0";
+- fan_temp2 = <&cpu_hot>,"temperature:0";
+- fan_temp3 = <&cpu_vhot>,"temperature:0";
+- fan_temp0_hyst = <&cpu_tepid>,"hysteresis:0";
+- fan_temp1_hyst = <&cpu_warm>,"hysteresis:0";
+- fan_temp2_hyst = <&cpu_hot>,"hysteresis:0";
+- fan_temp3_hyst = <&cpu_vhot>,"hysteresis:0";
+- fan_temp0_speed = <&fan>, "cooling-levels:4";
+- fan_temp1_speed = <&fan>, "cooling-levels:8";
+- fan_temp2_speed = <&fan>, "cooling-levels:12";
+- fan_temp3_speed = <&fan>, "cooling-levels:16";
+- };
+-};
+--- /dev/null
++++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5.dtsi
+@@ -0,0 +1,884 @@
++// SPDX-License-Identifier: GPL-2.0
++
++#include <dt-bindings/gpio/gpio.h>
++#include <dt-bindings/clock/rp1.h>
++#include <dt-bindings/interrupt-controller/irq.h>
++#include <dt-bindings/mfd/rp1.h>
++#include <dt-bindings/pwm/pwm.h>
++#include <dt-bindings/reset/raspberrypi,firmware-reset.h>
++
++#define i2c0 _i2c0
++#define i2c3 _i2c3
++#define i2c4 _i2c4
++#define i2c5 _i2c5
++#define i2c6 _i2c6
++#define i2c8 _i2c8
++#define i2s _i2s
++#define pwm0 _pwm0
++#define pwm1 _pwm1
++#define spi0 _spi0
++#define spi3 _spi3
++#define spi4 _spi4
++#define spi5 _spi5
++#define spi6 _spi6
++#define uart0 _uart0
++#define uart2 _uart2
++#define uart5 _uart5
++
++#include "bcm2712.dtsi"
++
++#undef i2c0
++#undef i2c3
++#undef i2c4
++#undef i2c5
++#undef i2c6
++#undef i2c8
++#undef i2s
++#undef pwm0
++#undef pwm1
++#undef spi0
++#undef spi3
++#undef spi4
++#undef spi5
++#undef spi6
++#undef uart0
++#undef uart2
++#undef uart3
++#undef uart4
++#undef uart5
++
++/ {
++ compatible = "raspberrypi,5-compute-module", "brcm,bcm2712";
++ model = "Raspberry Pi Compute Module 5";
++
++ /* Will be filled by the bootloader */
++ memory@0 {
++ device_type = "memory";
++ reg = <0 0 0x28000000>;
++ };
++
++ leds: leds {
++ compatible = "gpio-leds";
++
++ led_pwr: led-pwr {
++ label = "PWR";
++ gpios = <&rp1_gpio 44 GPIO_ACTIVE_LOW>;
++ default-state = "off";
++ linux,default-trigger = "none";
++ };
++
++ led_act: led-act {
++ label = "ACT";
++ gpios = <&gio_aon 9 GPIO_ACTIVE_LOW>;
++ default-state = "off";
++ linux,default-trigger = "mmc0";
++ };
++ };
++
++ sd_io_1v8_reg: sd_io_1v8_reg {
++ compatible = "regulator-fixed";
++ regulator-name = "vdd-sd-io";
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ regulator-always-on;
++ };
++
++ sd_vcc_reg: sd_vcc_reg {
++ compatible = "regulator-fixed";
++ regulator-name = "vcc-sd";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ regulator-boot-on;
++ enable-active-high;
++ gpios = <&gio_aon 4 GPIO_ACTIVE_HIGH>;
++ status = "okay";
++ };
++
++ wl_on_reg: wl_on_reg {
++ compatible = "regulator-fixed";
++ regulator-name = "wl-on-regulator";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ pinctrl-0 = <&wl_on_pins>;
++ pinctrl-names = "default";
++
++ gpio = <&gio 28 GPIO_ACTIVE_HIGH>;
++
++ startup-delay-us = <150000>;
++ enable-active-high;
++ };
++
++ clocks: clocks {
++ };
++
++ cam1_clk: cam1_clk {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ status = "disabled";
++ };
++
++ cam0_clk: cam0_clk {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ status = "disabled";
++ };
++
++ cam0_reg: cam0_reg {
++ compatible = "regulator-fixed";
++ regulator-name = "cam0_reg";
++ enable-active-high;
++ status = "okay";
++ gpio = <&rp1_gpio 34 0>; // CD0_IO0_MICCLK, to CAM_GPIO on connector
++ };
++
++ cam_dummy_reg: cam_dummy_reg {
++ compatible = "regulator-fixed";
++ regulator-name = "cam-dummy-reg";
++ status = "okay";
++ };
++
++ dummy: dummy {
++ // A target for unwanted overlay fragments
++ };
++
++
++ // A few extra labels to keep overlays happy
++
++ i2c0if: i2c0if {};
++ i2c0mux: i2c0mux {};
++};
++
++rp1_target: &pcie2 {
++ brcm,enable-mps-rcb;
++ brcm,vdm-qos-map = <0xbbaa9888>;
++ aspm-no-l0s;
++ status = "okay";
++};
++
++// Add some labels to 2712 device
++
++// The system UART
++uart10: &_uart0 { status = "okay"; };
++
++// The system SPI for the bootloader EEPROM
++spi10: &_spi0 { status = "okay"; };
++
++i2c_rp1boot: &_i2c3 { };
++
++#include "rp1.dtsi"
++
++&rp1 {
++ // PCIe address space layout:
++ // 00_00000000-00_00xxxxxx = RP1 peripherals
++ // 10_00000000-1x_xxxxxxxx = up to 64GB system RAM
++
++ // outbound access aimed at PCIe 0_00xxxxxx -> RP1 c0_40xxxxxx
++ // This is the RP1 peripheral space
++ ranges = <0xc0 0x40000000
++ 0x02000000 0x00 0x00000000
++ 0x00 0x00400000>;
++
++ dma-ranges =
++ // inbound RP1 1x_xxxxxxxx -> PCIe 1x_xxxxxxxx
++ <0x10 0x00000000
++ 0x43000000 0x10 0x00000000
++ 0x10 0x00000000>,
++
++ // inbound RP1 c0_40xxxxxx -> PCIe 00_00xxxxxx
++ // This allows the RP1 DMA controller to address RP1 hardware
++ <0xc0 0x40000000
++ 0x02000000 0x0 0x00000000
++ 0x0 0x00400000>,
++
++ // inbound RP1 0x_xxxxxxxx -> PCIe 1x_xxxxxxxx
++ <0x00 0x00000000
++ 0x02000000 0x10 0x00000000
++ 0x10 0x00000000>;
++};
++
++// Expose RP1 nodes as system nodes with labels
++
++&rp1_dma {
++ status = "okay";
++};
++
++&rp1_eth {
++ status = "okay";
++ phy-handle = <&phy1>;
++ phy-reset-gpios = <&rp1_gpio 32 GPIO_ACTIVE_LOW>;
++ phy-reset-duration = <5>;
++
++ phy1: ethernet-phy@1 {
++ reg = <0x1>;
++ brcm,powerdown-enable;
++ interrupt-parent = <&gpio>;
++ interrupts = <37 IRQ_TYPE_LEVEL_LOW>;
++ };
++};
++
++gpio: &rp1_gpio {
++ status = "okay";
++};
++
++aux: &dummy {};
++
++&rp1_usb0 {
++ pinctrl-0 = <&usb_vbus_pins>;
++ pinctrl-names = "default";
++ status = "okay";
++};
++
++&rp1_usb1 {
++ status = "okay";
++};
++
++#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>;
++};
++
++i2c_csi_dsi1: &i2c0 { // Note: This is for MIPI1 connector
++};
++
++i2c_csi_dsi: &i2c_csi_dsi1 { }; // An alias for compatibility
++
++cam1_reg: &cam0_reg { // Shares CAM_GPIO with cam0_reg
++};
++
++csi0: &rp1_csi0 { };
++csi1: &rp1_csi1 { };
++dsi0: &rp1_dsi0 { };
++dsi1: &rp1_dsi1 { };
++dpi: &rp1_dpi { };
++vec: &rp1_vec { };
++dpi_gpio0: &rp1_dpi_24bit_gpio0 { };
++dpi_gpio1: &rp1_dpi_24bit_gpio2 { };
++dpi_18bit_cpadhi_gpio0: &rp1_dpi_18bit_cpadhi_gpio0 { };
++dpi_18bit_cpadhi_gpio2: &rp1_dpi_18bit_cpadhi_gpio2 { };
++dpi_18bit_gpio0: &rp1_dpi_18bit_gpio0 { };
++dpi_18bit_gpio2: &rp1_dpi_18bit_gpio2 { };
++dpi_16bit_cpadhi_gpio0: &rp1_dpi_16bit_cpadhi_gpio0 { };
++dpi_16bit_cpadhi_gpio2: &rp1_dpi_16bit_cpadhi_gpio2 { };
++dpi_16bit_gpio0: &rp1_dpi_16bit_gpio0 { };
++dpi_16bit_gpio2: &rp1_dpi_16bit_gpio2 { };
++
++/* Add the IOMMUs for some RP1 bus masters */
++
++&csi0 {
++ iommus = <&iommu5>;
++};
++
++&csi1 {
++ iommus = <&iommu5>;
++};
++
++&dsi0 {
++ iommus = <&iommu5>;
++};
++
++&dsi1 {
++ iommus = <&iommu5>;
++};
++
++&dpi {
++ iommus = <&iommu5>;
++};
++
++&vec {
++ iommus = <&iommu5>;
++};
++
++&ddc0 {
++ status = "disabled";
++};
++
++&ddc1 {
++ status = "disabled";
++};
++
++&hdmi0 {
++ clocks = <&firmware_clocks 13>, <&firmware_clocks 14>, <&dvp 0>, <&clk_27MHz>;
++ clock-names = "hdmi", "bvb", "audio", "cec";
++ status = "disabled";
++};
++
++&hdmi1 {
++ clocks = <&firmware_clocks 13>, <&firmware_clocks 14>, <&dvp 1>, <&clk_27MHz>;
++ clock-names = "hdmi", "bvb", "audio", "cec";
++ status = "disabled";
++};
++
++&hvs {
++ clocks = <&firmware_clocks 4>, <&firmware_clocks 16>;
++ clock-names = "core", "disp";
++};
++
++&mop {
++ status = "disabled";
++};
++
++&moplet {
++ status = "disabled";
++};
++
++&pixelvalve0 {
++ status = "disabled";
++};
++
++&pixelvalve1 {
++ status = "disabled";
++};
++
++&disp_intr {
++ status = "disabled";
++};
++
++/* SDIO1 is used to drive the eMMC/SD card */
++&sdio1 {
++ pinctrl-0 = <&emmc_cmddat_pulls>, <&emmc_ds_pull>;
++ pinctrl-names = "default";
++ vqmmc-supply = <&sd_io_1v8_reg>;
++ vmmc-supply = <&sd_vcc_reg>;
++ bus-width = <8>;
++ sd-uhs-sdr50;
++ sd-uhs-ddr50;
++ sd-uhs-sdr104;
++ mmc-hs200-1_8v;
++ mmc-hs400-1_8v;
++ mmc-hs400-enhanced-strobe;
++ broken-cd;
++ supports-cqe;
++ status = "okay";
++};
++
++&pinctrl_aon {
++ ant_pins: ant_pins {
++ function = "gpio";
++ pins = "aon_gpio5", "aon_gpio6";
++ };
++
++ /* Slight hack - only one PWM pin (status LED) is usable */
++ aon_pwm_1pin: aon_pwm_1pin {
++ function = "aon_pwm";
++ pins = "aon_gpio9";
++ };
++};
++
++&pinctrl {
++ pwr_button_pins: pwr_button_pins {
++ function = "gpio";
++ pins = "gpio20";
++ bias-pull-up;
++ };
++
++ wl_on_pins: wl_on_pins {
++ function = "gpio";
++ pins = "gpio28";
++ };
++
++ bt_shutdown_pins: bt_shutdown_pins {
++ function = "gpio";
++ pins = "gpio29";
++ };
++
++ emmc_ds_pull: emmc_ds_pull {
++ pins = "emmc_ds";
++ bias-pull-down;
++ };
++
++ emmc_cmddat_pulls: emmc_cmddat_pulls {
++ pins = "emmc_cmd", "emmc_dat0", "emmc_dat1", "emmc_dat2", "emmc_dat3",
++ "emmc_dat4", "emmc_dat5", "emmc_dat6", "emmc_dat7";
++ bias-pull-up;
++ };
++};
++
++/* uarta communicates with the BT module */
++&uarta {
++ uart-has-rtscts;
++ auto-flow-control;
++ status = "okay";
++ clock-frequency = <96000000>;
++ pinctrl-0 = <&uarta_24_pins &bt_shutdown_pins>;
++ pinctrl-names = "default";
++
++ bluetooth: bluetooth {
++ compatible = "brcm,bcm43438-bt";
++ max-speed = <3000000>;
++ shutdown-gpios = <&gio 29 GPIO_ACTIVE_HIGH>;
++ local-bd-address = [ 00 00 00 00 00 00 ];
++ };
++};
++
++&i2c_rp1boot {
++ clock-frequency = <400000>;
++ pinctrl-0 = <&i2c3_m4_agpio0_pins>;
++ pinctrl-names = "default";
++};
++
++/ {
++ 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";
++ #cooling-cells = <2>;
++ cooling-min-state = <0>;
++ cooling-max-state = <3>;
++ cooling-levels = <0 75 125 175 250>;
++ pwms = <&rp1_pwm1 3 41566 PWM_POLARITY_INVERTED>;
++ rpm-regmap = <&rp1_pwm1>;
++ rpm-offset = <0x3c>;
++ };
++
++ pwr_button {
++ compatible = "gpio-keys";
++
++ pinctrl-names = "default";
++ pinctrl-0 = <&pwr_button_pins>;
++ status = "okay";
++
++ pwr_key: pwr {
++ label = "pwr_button";
++ // linux,code = <205>; // KEY_SUSPEND
++ linux,code = <116>; // KEY_POWER
++ gpios = <&gio 20 GPIO_ACTIVE_LOW>;
++ debounce-interval = <50>; // ms
++ };
++ };
++};
++
++&usb {
++ power-domains = <&power RPI_POWER_DOMAIN_USB>;
++};
++
++/* SDIO2 drives the WLAN interface */
++&sdio2 {
++ pinctrl-0 = <&sdio2_30_pins>, <&ant_pins>;
++ pinctrl-names = "default";
++ bus-width = <4>;
++ vmmc-supply = <&wl_on_reg>;
++ sd-uhs-ddr50;
++ non-removable;
++ status = "okay";
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ wifi: wifi@1 {
++ reg = <1>;
++ compatible = "brcm,bcm4329-fmac";
++ local-mac-address = [00 00 00 00 00 00];
++ };
++};
++
++&rpivid {
++ status = "okay";
++};
++
++&pinctrl {
++ spi10_gpio2: spi10_gpio2 {
++ function = "vc_spi0";
++ pins = "gpio2", "gpio3", "gpio4";
++ bias-disable;
++ };
++
++ spi10_cs_gpio1: spi10_cs_gpio1 {
++ function = "gpio";
++ pins = "gpio1";
++ bias-pull-up;
++ };
++};
++
++spi10_pins: &spi10_gpio2 {};
++spi10_cs_pins: &spi10_cs_gpio1 {};
++
++&spi10 {
++ pinctrl-names = "default";
++ cs-gpios = <&gio 1 1>;
++ pinctrl-0 = <&spi10_pins &spi10_cs_pins>;
++
++ spidev10: spidev@0 {
++ compatible = "spidev";
++ reg = <0>; /* CE0 */
++ #address-cells = <1>;
++ #size-cells = <0>;
++ spi-max-frequency = <20000000>;
++ status = "okay";
++ };
++};
++
++// =============================================
++// Board specific stuff here
++
++&gio_aon {
++ // Don't use GIO_AON as an interrupt controller because it will
++ // clash with the firmware monitoring the PMIC interrupt via the VPU.
++
++ /delete-property/ interrupt-controller;
++};
++
++&main_aon_irq {
++ // Don't use the MAIN_AON_IRQ interrupt controller because it will
++ // clash with the firmware monitoring the PMIC interrupt via the VPU.
++
++ status = "disabled";
++};
++
++&rp1_pwm1 {
++ status = "disabled";
++ pinctrl-0 = <&rp1_pwm1_gpio45>;
++ pinctrl-names = "default";
++};
++
++&thermal_trips {
++ cpu_tepid: cpu-tepid {
++ temperature = <50000>;
++ hysteresis = <5000>;
++ type = "active";
++ };
++
++ cpu_warm: cpu-warm {
++ temperature = <60000>;
++ hysteresis = <5000>;
++ type = "active";
++ };
++
++ cpu_hot: cpu-hot {
++ temperature = <67500>;
++ hysteresis = <5000>;
++ type = "active";
++ };
++
++ cpu_vhot: cpu-vhot {
++ temperature = <75000>;
++ hysteresis = <5000>;
++ type = "active";
++ };
++};
++
++&cooling_maps {
++ tepid {
++ trip = <&cpu_tepid>;
++ cooling-device = <&fan 1 1>;
++ };
++
++ warm {
++ trip = <&cpu_warm>;
++ cooling-device = <&fan 2 2>;
++ };
++
++ hot {
++ trip = <&cpu_hot>;
++ cooling-device = <&fan 3 3>;
++ };
++
++ vhot {
++ trip = <&cpu_vhot>;
++ cooling-device = <&fan 4 4>;
++ };
++
++ melt {
++ trip = <&cpu_crit>;
++ cooling-device = <&fan 4 4>;
++ };
++};
++
++&gio {
++ // The GPIOs above 35 are not used on Pi 5, so shrink the upper bank
++ // to reduce the clutter in gpioinfo/pinctrl
++ brcm,gpio-bank-widths = <32 4>;
++
++ 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
++ "-", // GPIO_014
++ "-", // GPIO_015
++ "-", // GPIO_016
++ "-", // GPIO_017
++ "-", // GPIO_018
++ "-", // GPIO_019
++ "PWR_GPIO", // GPIO_020
++ "2712_G21_FS", // 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
++ "ANT1", // AON_GPIO_05
++ "ANT2", // 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_run_hog {
++ gpio-hog;
++ gpios = <2 GPIO_ACTIVE_HIGH>;
++ output-high;
++ line-name = "RP1 RUN pin";
++ };
++
++ ant1: ant1-hog {
++ gpio-hog;
++ gpios = <5 GPIO_ACTIVE_HIGH>;
++ /* internal antenna enabled */
++ output-high;
++ line-name = "ant1";
++ };
++
++ ant2: ant2-hog {
++ gpio-hog;
++ gpios = <6 GPIO_ACTIVE_HIGH>;
++ /* external antenna disabled */
++ output-low;
++ line-name = "ant2";
++ };
++};
++
++&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_PWR_EN", // GPIO28
++ "FAN_TACH", // GPIO29
++ "HOST_SDA", // GPIO30
++ "HOST_SCL", // GPIO31
++ "ETH_RST_N", // GPIO32
++ "PCIE_DET_WAKE", // GPIO33
++
++ "CD0_IO0_MICCLK", // GPIO34
++ "CD0_IO0_MICDAT0", // GPIO35
++ "RP1_PCIE_CLKREQ_N", // GPIO36
++ "ETH_IRQ_N", // GPIO37
++ "SDA0", // GPIO38
++ "SCL0", // GPIO39
++ "-", // GPIO40
++ "-", // GPIO41
++ "USB_VBUS_EN", // GPIO42
++ "USB_OC_N", // GPIO43
++ "RP1_STAT_LED", // GPIO44
++ "FAN_PWM", // GPIO45
++ "-", // GPIO46
++ "2712_WAKE", // GPIO47
++ "-", // GPIO48
++ "-", // GPIO49
++ "-", // GPIO50
++ "-", // GPIO51
++ "-", // GPIO52
++ "-"; // GPIO53
++
++ usb_vbus_pins: usb_vbus_pins {
++ function = "vbus1";
++ pins = "gpio42", "gpio43";
++ };
++};
++
++/ {
++ aliases: aliases {
++ blconfig = &blconfig;
++ blpubkey = &blpubkey;
++ bluetooth = &bluetooth;
++ console = &uart10;
++ ethernet0 = &rp1_eth;
++ wifi0 = &wifi;
++ fb = &fb;
++ mailbox = &mailbox;
++ mmc0 = &sdio1;
++ uart0 = &uart0;
++ uart1 = &uart1;
++ uart2 = &uart2;
++ uart3 = &uart3;
++ uart4 = &uart4;
++ uart10 = &uart10;
++ serial0 = &uart0;
++ serial1 = &uart1;
++ serial2 = &uart2;
++ serial3 = &uart3;
++ serial4 = &uart4;
++ serial10 = &uart10;
++ i2c = &i2c_arm;
++ i2c0 = &i2c0;
++ i2c1 = &i2c1;
++ i2c2 = &i2c2;
++ i2c3 = &i2c3;
++ i2c4 = &i2c4;
++ i2c5 = &i2c5;
++ i2c6 = &i2c6;
++ i2c10 = &i2c_rp1boot;
++ // Bit-bashed i2c_gpios start at 10
++ spi0 = &spi0;
++ spi1 = &spi1;
++ spi2 = &spi2;
++ spi3 = &spi3;
++ spi4 = &spi4;
++ spi5 = &spi5;
++ spi10 = &spi10;
++ gpio0 = &gpio;
++ gpio1 = &gio;
++ gpio2 = &gio_aon;
++ gpio3 = &pinctrl;
++ gpio4 = &pinctrl_aon;
++ usb0 = &rp1_usb0;
++ usb1 = &rp1_usb1;
++ drm-dsi1 = &dsi0;
++ drm-dsi2 = &dsi1;
++ };
++
++ __overrides__ {
++ bdaddr = <&bluetooth>, "local-bd-address[";
++ button_debounce = <&pwr_key>, "debounce-interval:0";
++ cooling_fan = <&fan>, "status", <&rp1_pwm1>, "status";
++ uart0_console = <&uart0>,"status", <&aliases>, "console=",&uart0;
++ i2c0 = <&i2c0>, "status";
++ i2c1 = <&i2c1>, "status";
++ i2c = <&i2c1>, "status";
++ i2c_arm = <&i2c_arm>, "status";
++ i2c_vc = <&i2c_vc>, "status";
++ i2c_csi_dsi = <&i2c_csi_dsi>, "status";
++ i2c_csi_dsi0 = <&i2c_csi_dsi0>, "status";
++ i2c_csi_dsi1 = <&i2c_csi_dsi1>, "status";
++ i2c0_baudrate = <&i2c0>, "clock-frequency:0";
++ i2c1_baudrate = <&i2c1>, "clock-frequency:0";
++ i2c_baudrate = <&i2c_arm>, "clock-frequency:0";
++ i2c_arm_baudrate = <&i2c_arm>, "clock-frequency:0";
++ i2c_vc_baudrate = <&i2c_vc>, "clock-frequency:0";
++ krnbt = <&bluetooth>, "status";
++ nvme = <&pciex1>, "status";
++ pciex1 = <&pciex1>, "status";
++ pciex1_gen = <&pciex1> , "max-link-speed:0";
++ pciex1_no_l0s = <&pciex1>, "aspm-no-l0s?";
++ pciex1_tperst_clk_ms = <&pciex1>, "brcm,tperst-clk-ms:0";
++ pcie_tperst_clk_ms = <&pciex1>, "brcm,tperst-clk-ms:0";
++ random = <&random>, "status";
++ rtc = <&rpi_rtc>, "status";
++ rtc_bbat_vchg = <&rpi_rtc>, "trickle-charge-microvolt:0";
++ spi = <&spi0>, "status";
++ suspend = <&pwr_key>, "linux,code:0=205";
++ uart0 = <&uart0>, "status";
++ wifiaddr = <&wifi>, "local-mac-address[";
++
++ act_led_activelow = <&led_act>, "active-low?";
++ act_led_trigger = <&led_act>, "linux,default-trigger";
++ pwr_led_activelow = <&led_pwr>, "gpios:8";
++ pwr_led_trigger = <&led_pwr>, "linux,default-trigger";
++ eth_led0 = <&phy1>,"led-modes:0";
++ eth_led1 = <&phy1>,"led-modes:4";
++ drm_fb0_rp1_dsi0 = <&aliases>, "drm-fb0=",&dsi0;
++ drm_fb0_rp1_dsi1 = <&aliases>, "drm-fb0=",&dsi1;
++ drm_fb0_rp1_dpi = <&aliases>, "drm-fb0=",&dpi;
++ drm_fb0_vc4 = <&aliases>, "drm-fb0=",&vc4;
++ drm_fb1_rp1_dsi0 = <&aliases>, "drm-fb1=",&dsi0;
++ drm_fb1_rp1_dsi1 = <&aliases>, "drm-fb1=",&dsi1;
++ drm_fb1_rp1_dpi = <&aliases>, "drm-fb1=",&dpi;
++ drm_fb1_vc4 = <&aliases>, "drm-fb1=",&vc4;
++ drm_fb2_rp1_dsi0 = <&aliases>, "drm-fb2=",&dsi0;
++ drm_fb2_rp1_dsi1 = <&aliases>, "drm-fb2=",&dsi1;
++ drm_fb2_rp1_dpi = <&aliases>, "drm-fb2=",&dpi;
++ drm_fb2_vc4 = <&aliases>, "drm-fb2=",&vc4;
++
++ ant1 = <&ant1>,"output-high?=on",
++ <&ant1>, "output-low?=off",
++ <&ant2>, "output-high?=off",
++ <&ant2>, "output-low?=on";
++ ant2 = <&ant1>,"output-high?=off",
++ <&ant1>, "output-low?=on",
++ <&ant2>, "output-high?=on",
++ <&ant2>, "output-low?=off";
++ noant = <&ant1>,"output-high?=off",
++ <&ant1>, "output-low?=on",
++ <&ant2>, "output-high?=off",
++ <&ant2>, "output-low?=on";
++
++ fan_temp0 = <&cpu_tepid>,"temperature:0";
++ fan_temp1 = <&cpu_warm>,"temperature:0";
++ fan_temp2 = <&cpu_hot>,"temperature:0";
++ fan_temp3 = <&cpu_vhot>,"temperature:0";
++ fan_temp0_hyst = <&cpu_tepid>,"hysteresis:0";
++ fan_temp1_hyst = <&cpu_warm>,"hysteresis:0";
++ fan_temp2_hyst = <&cpu_hot>,"hysteresis:0";
++ fan_temp3_hyst = <&cpu_vhot>,"hysteresis:0";
++ fan_temp0_speed = <&fan>, "cooling-levels:4";
++ fan_temp1_speed = <&fan>, "cooling-levels:8";
++ fan_temp2_speed = <&fan>, "cooling-levels:12";
++ fan_temp3_speed = <&fan>, "cooling-levels:16";
++ };
++};
+--- a/arch/arm64/boot/dts/broadcom/bcm2712d0-rpi-5-b.dts
++++ b/arch/arm64/boot/dts/broadcom/bcm2712d0-rpi-5-b.dts
+@@ -1,2 +1,107 @@
+ // SPDX-License-Identifier: GPL-2.0
+-#include "../../../../arm/boot/dts/broadcom/bcm2712d0-rpi-5-b.dts"
++#include "bcm2712-rpi-5-b.dts"
++
++&gio {
++ brcm,gpio-bank-widths = <32 4>;
++
++ 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
++ "PCIE_SDA", // GPIO_014
++ "PCIE_SCL", // GPIO_015
++ "", // GPIO_016
++ "", // GPIO_017
++ "-", // GPIO_018
++ "-", // GPIO_019
++ "PWR_GPIO", // GPIO_020
++ "2712_G21_FS", // 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 {
++ brcm,gpio-bank-widths = <15 6>;
++
++ 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
++};
++
++&pinctrl {
++ compatible = "brcm,bcm2712d0-pinctrl";
++ reg = <0x7d504100 0x20>;
++};
++
++&pinctrl_aon {
++ compatible = "brcm,bcm2712d0-aon-pinctrl";
++ reg = <0x7d510700 0x1c>;
++};
++
++&vc4 {
++ compatible = "brcm,bcm2712d0-vc6";
++};
++
++&uart10 {
++ interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
++};
++
++&spi10 {
++ dmas = <&dma40 3>, <&dma40 4>;
++};
++
++&hdmi0 {
++ dmas = <&dma40 (12|(1<<30)|(1<<24)|(10<<16)|(15<<20))>;
++};
++
++&hdmi1 {
++ dmas = <&dma40 (13|(1<<30)|(1<<24)|(10<<16)|(15<<20))>;
++};
+--- a/arch/arm/boot/dts/broadcom/bcm2712-rpi.dtsi
++++ /dev/null
+@@ -1,351 +0,0 @@
+-// SPDX-License-Identifier: GPL-2.0
+-
+-#include <dt-bindings/power/raspberrypi-power.h>
+-
+-&soc {
+- firmware: firmware {
+- compatible = "raspberrypi,bcm2835-firmware", "simple-mfd";
+- #address-cells = <1>;
+- #size-cells = <1>;
+-
+- mboxes = <&mailbox>;
+- dma-ranges;
+-
+- firmware_clocks: clocks {
+- compatible = "raspberrypi,firmware-clocks";
+- #clock-cells = <1>;
+- };
+-
+- reset: reset {
+- compatible = "raspberrypi,firmware-reset";
+- #reset-cells = <1>;
+- };
+-
+- vcio: vcio {
+- compatible = "raspberrypi,vcio";
+- };
+- };
+-
+- power: power {
+- compatible = "raspberrypi,bcm2835-power";
+- firmware = <&firmware>;
+- #power-domain-cells = <1>;
+- };
+-
+- fb: fb {
+- compatible = "brcm,bcm2708-fb";
+- firmware = <&firmware>;
+- status = "okay";
+- };
+-
+- rpi_rtc: rpi_rtc {
+- compatible = "raspberrypi,rpi-rtc";
+- firmware = <&firmware>;
+- status = "okay";
+- trickle-charge-microvolt = <0>;
+- };
+-
+- nvmem {
+- compatible = "simple-bus";
+- #address-cells = <1>;
+- #size-cells = <1>;
+-
+- nvmem_otp: nvmem_otp {
+- compatible = "raspberrypi,rpi-otp";
+- firmware = <&firmware>;
+- reg = <0 192>;
+- status = "okay";
+- };
+-
+- nvmem_cust: nvmem_cust {
+- compatible = "raspberrypi,rpi-otp";
+- firmware = <&firmware>;
+- reg = <1 8>;
+- status = "okay";
+- };
+-
+- nvmem_mac: nvmem_mac {
+- compatible = "raspberrypi,rpi-otp";
+- firmware = <&firmware>;
+- reg = <2 6>;
+- status = "okay";
+- };
+-
+- nvmem_priv: nvmem_priv {
+- compatible = "raspberrypi,rpi-otp";
+- firmware = <&firmware>;
+- reg = <3 16>;
+- status = "okay";
+- };
+- };
+-
+- /* Define these notional regulators for use by overlays, etc. */
+- vdd_3v3_reg: fixedregulator_3v3 {
+- compatible = "regulator-fixed";
+- regulator-always-on;
+- regulator-max-microvolt = <3300000>;
+- regulator-min-microvolt = <3300000>;
+- regulator-name = "3v3";
+- };
+-
+- vdd_5v0_reg: fixedregulator_5v0 {
+- compatible = "regulator-fixed";
+- regulator-always-on;
+- regulator-max-microvolt = <5000000>;
+- regulator-min-microvolt = <5000000>;
+- regulator-name = "5v0";
+- };
+-};
+-
+-/ {
+- __overrides__ {
+- arm_freq;
+- axiperf = <&axiperf>,"status";
+-
+- nvmem_cust_rw = <&nvmem_cust>,"rw?";
+- nvmem_priv_rw = <&nvmem_priv>,"rw?";
+- nvmem_mac_rw = <&nvmem_mac>,"rw?";
+- strict_gpiod = <&chosen>, "bootargs=pinctrl_rp1.persist_gpio_outputs=n";
+-
+- cam0_reg = <&cam0_reg>,"status";
+- cam0_reg_gpio = <&cam0_reg>,"gpio:4",
+- <&cam0_reg>,"gpio:0=", <&gpio>;
+- cam1_reg = <&cam1_reg>,"status";
+- cam1_reg_gpio = <&cam1_reg>,"gpio:4",
+- <&cam1_reg>,"gpio:0=", <&gpio>;
+-
+- };
+-};
+-
+-pciex1: &pcie1 { };
+-pciex4: &pcie2 { };
+-
+-&dma32 {
+- /* The VPU firmware uses DMA channel 11 for VCHIQ */
+- brcm,dma-channel-mask = <0x03f>;
+-};
+-
+-&dma40 {
+- /* The VPU firmware DMA channel 11 for VCHIQ */
+- brcm,dma-channel-mask = <0x07c0>;
+-};
+-
+-&hdmi0 {
+- dmas = <&dma40 (10|(1<<30)|(1<<24)|(10<<16)|(15<<20))>;
+-};
+-
+-&hdmi1 {
+- dmas = <&dma40 (17|(1<<30)|(1<<24)|(10<<16)|(15<<20))>;
+-};
+-
+-&spi10 {
+- dmas = <&dma40 6>, <&dma40 7>;
+- dma-names = "tx", "rx";
+-};
+-
+-&usb {
+- power-domains = <&power RPI_POWER_DOMAIN_USB>;
+-};
+-
+-&rmem {
+- /*
+- * RPi5's co-processor will copy the board's bootloader configuration
+- * into memory for the OS to consume. It'll also update this node with
+- * its placement information.
+- */
+- blconfig: nvram@0 {
+- compatible = "raspberrypi,bootloader-config", "nvmem-rmem";
+- #address-cells = <1>;
+- #size-cells = <1>;
+- reg = <0x0 0x0 0x0>;
+- no-map;
+- status = "disabled";
+- };
+- /*
+- * RPi5 will copy the binary public key blob (if present) from the bootloader
+- * into memory for use by the OS.
+- */
+- blpubkey: nvram@1 {
+- compatible = "raspberrypi,bootloader-public-key", "nvmem-rmem";
+- #address-cells = <1>;
+- #size-cells = <1>;
+- reg = <0x0 0x0 0x0>;
+- no-map;
+- status = "disabled";
+- };
+-};
+-
+-&rp1_adc {
+- status = "okay";
+-};
+-
+-/* Add some gpiomem nodes to make the devices accessible to userspace.
+- * /dev/gpiomem<n> should expose the registers for the interface with DT alias
+- * gpio<n>.
+- */
+-
+-&rp1 {
+- gpiomem@d0000 {
+- /* Export IO_BANKs, RIO_BANKs and PADS_BANKs to userspace */
+- compatible = "raspberrypi,gpiomem";
+- reg = <0xc0 0x400d0000 0x0 0x30000>;
+- chardev-name = "gpiomem0";
+- };
+-};
+-
+-&soc {
+- gpiomem@7d508500 {
+- compatible = "raspberrypi,gpiomem";
+- reg = <0x7d508500 0x40>;
+- chardev-name = "gpiomem1";
+- };
+-
+- gpiomem@7d517c00 {
+- compatible = "raspberrypi,gpiomem";
+- reg = <0x7d517c00 0x40>;
+- chardev-name = "gpiomem2";
+- };
+-
+- gpiomem@7d504100 {
+- compatible = "raspberrypi,gpiomem";
+- reg = <0x7d504100 0x20>;
+- chardev-name = "gpiomem3";
+- };
+-
+- gpiomem@7d510700 {
+- compatible = "raspberrypi,gpiomem";
+- reg = <0x7d510700 0x20>;
+- chardev-name = "gpiomem4";
+- };
+-
+- sound: sound {
+- status = "disabled";
+- };
+-};
+-
+-i2c0: &rp1_i2c0 { };
+-i2c1: &rp1_i2c1 { };
+-i2c2: &rp1_i2c2 { };
+-i2c3: &rp1_i2c3 { };
+-i2c4: &rp1_i2c4 { };
+-i2c5: &rp1_i2c5 { };
+-i2c6: &rp1_i2c6 { };
+-i2s: &rp1_i2s0 { };
+-i2s_clk_producer: &rp1_i2s0 { };
+-i2s_clk_consumer: &rp1_i2s1 { };
+-pwm0: &rp1_pwm0 { };
+-pwm1: &rp1_pwm1 { };
+-pwm: &pwm0 { };
+-spi0: &rp1_spi0 { };
+-spi1: &rp1_spi1 { };
+-spi2: &rp1_spi2 { };
+-spi3: &rp1_spi3 { };
+-spi4: &rp1_spi4 { };
+-spi5: &rp1_spi5 { };
+-
+-uart0_pins: &rp1_uart0_14_15 {};
+-uart0_ctsrts_pins: &rp1_uart0_ctsrts_16_17 {};
+-uart0: &rp1_uart0 {
+- pinctrl-0 = <&uart0_pins>;
+-};
+-
+-uart1_pins: &rp1_uart1_0_1 {};
+-uart1_ctsrts_pins: &rp1_uart1_ctsrts_2_3 {};
+-uart1: &rp1_uart1 { };
+-
+-uart2_pins: &rp1_uart2_4_5 {};
+-uart2_ctsrts_pins: &rp1_uart2_ctsrts_6_7 {};
+-uart2: &rp1_uart2 { };
+-
+-uart3_pins: &rp1_uart3_8_9 {};
+-uart3_ctsrts_pins: &rp1_uart3_ctsrts_10_11 {};
+-uart3: &rp1_uart3 { };
+-
+-uart4_pins: &rp1_uart4_12_13 {};
+-uart4_ctsrts_pins: &rp1_uart4_ctsrts_14_15 {};
+-uart4: &rp1_uart4 { };
+-
+-i2c0_pins: &rp1_i2c0_0_1 {};
+-i2c_vc: &i2c0 { // This is pins 27,28 on the header (not MIPI)
+- pinctrl-0 = <&i2c0_pins>;
+- pinctrl-names = "default";
+- clock-frequency = <100000>;
+-};
+-
+-i2c1_pins: &rp1_i2c1_2_3 {};
+-i2c_arm: &i2c1 {
+- pinctrl-names = "default";
+- pinctrl-0 = <&i2c1_pins>;
+- clock-frequency = <100000>;
+-};
+-
+-i2c2_pins: &rp1_i2c2_4_5 {};
+-&i2c2 {
+- pinctrl-names = "default";
+- pinctrl-0 = <&i2c2_pins>;
+-};
+-
+-i2c3_pins: &rp1_i2c3_6_7 {};
+-&i2c3 {
+- pinctrl-names = "default";
+- pinctrl-0 = <&i2c3_pins>;
+-};
+-
+-&i2s_clk_producer {
+- pinctrl-names = "default";
+- pinctrl-0 = <&rp1_i2s0_18_21>;
+-};
+-
+-&i2s_clk_consumer {
+- pinctrl-names = "default";
+- pinctrl-0 = <&rp1_i2s1_18_21>;
+-};
+-
+-spi0_pins: &rp1_spi0_gpio9 {};
+-spi0_cs_pins: &rp1_spi0_cs_gpio7 {};
+-
+-&spi0 {
+- pinctrl-names = "default";
+- pinctrl-0 = <&spi0_pins &spi0_cs_pins>;
+- cs-gpios = <&gpio 8 1>, <&gpio 7 1>;
+-
+- spidev0: spidev@0 {
+- compatible = "spidev";
+- reg = <0>; /* CE0 */
+- #address-cells = <1>;
+- #size-cells = <0>;
+- spi-max-frequency = <125000000>;
+- };
+-
+- spidev1: spidev@1 {
+- compatible = "spidev";
+- reg = <1>; /* CE1 */
+- #address-cells = <1>;
+- #size-cells = <0>;
+- spi-max-frequency = <125000000>;
+- };
+-};
+-
+-spi2_pins: &rp1_spi2_gpio1 {};
+-&spi2 {
+- pinctrl-names = "default";
+- pinctrl-0 = <&spi2_pins>;
+-};
+-
+-spi3_pins: &rp1_spi3_gpio5 {};
+-&spi3 {
+- pinctrl-names = "default";
+- pinctrl-0 = <&spi3_pins>;
+-};
+-
+-spi4_pins: &rp1_spi4_gpio9 {};
+-&spi4 {
+- pinctrl-names = "default";
+- pinctrl-0 = <&spi4_pins>;
+-};
+-
+-spi5_pins: &rp1_spi5_gpio13 {};
+-&spi5 {
+- pinctrl-names = "default";
+- pinctrl-0 = <&spi5_pins>;
+-};
+--- a/arch/arm/boot/dts/broadcom/bcm2712.dtsi
++++ /dev/null
+@@ -1,1302 +0,0 @@
+-// SPDX-License-Identifier: GPL-2.0
+-#include <dt-bindings/interrupt-controller/arm-gic.h>
+-#include <dt-bindings/soc/bcm2835-pm.h>
+-#include <dt-bindings/phy/phy.h>
+-
+-/ {
+- compatible = "brcm,bcm2712", "brcm,bcm2711";
+- model = "BCM2712";
+-
+- #address-cells = <2>;
+- #size-cells = <1>;
+-
+- interrupt-parent = <&gicv2>;
+-
+- rmem: reserved-memory {
+- #address-cells = <2>;
+- #size-cells = <1>;
+- ranges;
+-
+- atf@0 {
+- reg = <0x0 0x0 0x80000>;
+- no-map;
+- };
+-
+- cma: linux,cma {
+- compatible = "shared-dma-pool";
+- size = <0x4000000>; /* 64MB */
+- reusable;
+- linux,cma-default;
+-
+- /*
+- * arm64 reserves the CMA by default somewhere in
+- * ZONE_DMA32, that's not good enough for the BCM2711
+- * as some devices can only address the lower 1G of
+- * memory (ZONE_DMA).
+- */
+- alloc-ranges = <0x0 0x00000000 0x40000000>;
+- };
+- };
+-
+- thermal-zones {
+- cpu_thermal: cpu-thermal {
+- polling-delay-passive = <2000>;
+- polling-delay = <1000>;
+- coefficients = <(-550) 450000>;
+- thermal-sensors = <&thermal>;
+-
+- thermal_trips: trips {
+- cpu_crit: cpu-crit {
+- temperature = <110000>;
+- hysteresis = <0>;
+- type = "critical";
+- };
+- };
+-
+- cooling_maps: cooling-maps {
+- };
+- };
+- };
+-
+- clk_27MHz: clk-27M {
+- #clock-cells = <0>;
+- compatible = "fixed-clock";
+- clock-frequency = <27000000>;
+- clock-output-names = "27MHz-clock";
+- };
+-
+- clk_108MHz: clk-108M {
+- #clock-cells = <0>;
+- compatible = "fixed-clock";
+- clock-frequency = <108000000>;
+- clock-output-names = "108MHz-clock";
+- };
+-
+- hvs: hvs@107c580000 {
+- compatible = "brcm,bcm2712-hvs";
+- reg = <0x10 0x7c580000 0x1a000>;
+- interrupt-parent = <&disp_intr>;
+- interrupts = <2>, <9>, <16>;
+- interrupt-names = "ch0-eof", "ch1-eof", "ch2-eof";
+- //iommus = <&iommu4>;
+- status = "disabled";
+- };
+-
+- soc: soc {
+- compatible = "simple-bus";
+- #address-cells = <1>;
+- #size-cells = <1>;
+-
+- ranges = <0x7c000000 0x10 0x7c000000 0x04000000>;
+- /* Emulate a contiguous 30-bit address range for DMA */
+- dma-ranges = <0xc0000000 0x00 0x00000000 0x40000000>,
+- <0x7c000000 0x10 0x7c000000 0x04000000>;
+-
+- system_timer: timer@7c003000 {
+- compatible = "brcm,bcm2835-system-timer";
+- reg = <0x7c003000 0x1000>;
+- interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
+- clock-frequency = <1000000>;
+- };
+-
+- firmwarekms: firmwarekms@7d503000 {
+- compatible = "raspberrypi,rpi-firmware-kms-2712";
+- /* SUN_L2 interrupt reg */
+- reg = <0x7d503000 0x18>;
+- interrupt-parent = <&cpu_l2_irq>;
+- interrupts = <19>;
+- brcm,firmware = <&firmware>;
+- status = "disabled";
+- };
+-
+- axiperf: axiperf {
+- compatible = "brcm,bcm2712-axiperf";
+- reg = <0x7c012800 0x100>,
+- <0x7e000000 0x100>;
+- firmware = <&firmware>;
+- status = "disabled";
+- };
+-
+- mailbox: mailbox@7c013880 {
+- compatible = "brcm,bcm2835-mbox";
+- reg = <0x7c013880 0x40>;
+- interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
+- #mbox-cells = <0>;
+- };
+-
+- pixelvalve0: pixelvalve@7c410000 {
+- compatible = "brcm,bcm2712-pixelvalve0";
+- reg = <0x7c410000 0x100>;
+- interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
+- status = "disabled";
+- };
+-
+- pixelvalve1: pixelvalve@7c411000 {
+- compatible = "brcm,bcm2712-pixelvalve1";
+- reg = <0x7c411000 0x100>;
+- interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
+- status = "disabled";
+- };
+-
+- mop: mop@7c500000 {
+- compatible = "brcm,bcm2712-mop";
+- reg = <0x7c500000 0x28>;
+- interrupt-parent = <&disp_intr>;
+- interrupts = <1>;
+- status = "disabled";
+- };
+-
+- moplet: moplet@7c501000 {
+- compatible = "brcm,bcm2712-moplet";
+- reg = <0x7c501000 0x20>;
+- interrupt-parent = <&disp_intr>;
+- interrupts = <0>;
+- status = "disabled";
+- };
+-
+- disp_intr: interrupt-controller@7c502000 {
+- compatible = "brcm,bcm2711-l2-intc", "brcm,l2-intc";
+- reg = <0x7c502000 0x30>;
+- interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
+- interrupt-controller;
+- #interrupt-cells = <1>;
+- status = "disabled";
+- };
+-
+- dvp: clock@7c700000 {
+- compatible = "brcm,brcm2711-dvp";
+- reg = <0x7c700000 0x10>;
+- clocks = <&clk_108MHz>;
+- #clock-cells = <1>;
+- #reset-cells = <1>;
+- };
+-
+- /*
+- * This node is the provider for the enable-method for
+- * bringing up secondary cores.
+- */
+- local_intc: local_intc@7cd00000 {
+- compatible = "brcm,bcm2836-l1-intc";
+- reg = <0x7cd00000 0x100>;
+- };
+-
+- uart0: serial@7d001000 {
+- compatible = "arm,pl011", "arm,primecell";
+- reg = <0x7d001000 0x200>;
+- interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&clk_uart>,
+- <&clk_vpu>;
+- clock-names = "uartclk", "apb_pclk";
+- arm,primecell-periphid = <0x00241011>;
+- status = "disabled";
+- };
+-
+- uart2: serial@7d001400 {
+- compatible = "arm,pl011", "arm,primecell";
+- reg = <0x7d001400 0x200>;
+- interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&clk_uart>,
+- <&clk_vpu>;
+- clock-names = "uartclk", "apb_pclk";
+- arm,primecell-periphid = <0x00241011>;
+- status = "disabled";
+- };
+-
+- uart5: serial@7d001a00 {
+- compatible = "arm,pl011", "arm,primecell";
+- reg = <0x7d001a00 0x200>;
+- interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&clk_uart>,
+- <&clk_vpu>;
+- clock-names = "uartclk", "apb_pclk";
+- arm,primecell-periphid = <0x00241011>;
+- status = "disabled";
+- };
+-
+- sdhost: mmc@7d002000 {
+- compatible = "brcm,bcm2835-sdhost";
+- reg = <0x7d002000 0x100>;
+- //interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&clk_vpu>;
+- status = "disabled";
+- };
+-
+- i2s: i2s@7d003000 {
+- compatible = "brcm,bcm2835-i2s";
+- reg = <0x7d003000 0x24>;
+- //clocks = <&cprman BCM2835_CLOCK_PCM>;
+- status = "disabled";
+- };
+-
+- spi0: spi@7d004000 {
+- compatible = "brcm,bcm2835-spi";
+- reg = <0x7d004000 0x200>;
+- interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&clk_vpu>;
+- num-cs = <1>;
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- spi3: spi@7d004600 {
+- compatible = "brcm,bcm2835-spi";
+- reg = <0x7d004600 0x0200>;
+- interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&clk_vpu>;
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- spi4: spi@7d004800 {
+- compatible = "brcm,bcm2835-spi";
+- reg = <0x7d004800 0x0200>;
+- interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&clk_vpu>;
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- spi5: spi@7d004a00 {
+- compatible = "brcm,bcm2835-spi";
+- reg = <0x7d004a00 0x0200>;
+- interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&clk_vpu>;
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- spi6: spi@7d004c00 {
+- compatible = "brcm,bcm2835-spi";
+- reg = <0x7d004c00 0x0200>;
+- interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&clk_vpu>;
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- i2c0: i2c@7d005000 {
+- compatible = "brcm,bcm2711-i2c", "brcm,bcm2835-i2c";
+- reg = <0x7d005000 0x20>;
+- interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&clk_vpu>;
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- i2c3: i2c@7d005600 {
+- compatible = "brcm,bcm2711-i2c", "brcm,bcm2835-i2c";
+- reg = <0x7d005600 0x20>;
+- interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&clk_vpu>;
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- i2c4: i2c@7d005800 {
+- compatible = "brcm,bcm2711-i2c", "brcm,bcm2835-i2c";
+- reg = <0x7d005800 0x20>;
+- interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&clk_vpu>;
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- i2c5: i2c@7d005a00 {
+- compatible = "brcm,bcm2711-i2c", "brcm,bcm2835-i2c";
+- reg = <0x7d005a00 0x20>;
+- interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&clk_vpu>;
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- i2c6: i2c@7d005c00 {
+- compatible = "brcm,bcm2711-i2c", "brcm,bcm2835-i2c";
+- reg = <0x7d005c00 0x20>;
+- interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&clk_vpu>;
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- i2c8: i2c@7d005e00 {
+- compatible = "brcm,bcm2711-i2c", "brcm,bcm2835-i2c";
+- reg = <0x7d005e00 0x20>;
+- interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&clk_vpu>;
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- pwm0: pwm@7d00c000 {
+- compatible = "brcm,bcm2835-pwm";
+- reg = <0x7d00c000 0x28>;
+- assigned-clock-rates = <50000000>;
+- #pwm-cells = <3>;
+- status = "disabled";
+- };
+-
+- pwm1: pwm@7d00c800 {
+- compatible = "brcm,bcm2835-pwm";
+- reg = <0x7d00c800 0x28>;
+- assigned-clock-rates = <50000000>;
+- #pwm-cells = <3>;
+- status = "disabled";
+- };
+-
+- pm: watchdog@7d200000 {
+- compatible = "brcm,bcm2712-pm";
+- reg = <0x7d200000 0x308>;
+- reg-names = "pm";
+- #power-domain-cells = <1>;
+- #reset-cells = <1>;
+- //clocks = <&cprman BCM2835_CLOCK_V3D>,
+- // <&cprman BCM2835_CLOCK_PERI_IMAGE>,
+- // <&cprman BCM2835_CLOCK_H264>,
+- // <&cprman BCM2835_CLOCK_ISP>;
+- clock-names = "v3d", "peri_image", "h264", "isp";
+- system-power-controller;
+- };
+-
+- cprman: cprman@7d202000 {
+- compatible = "brcm,bcm2711-cprman";
+- reg = <0x7d202000 0x2000>;
+- #clock-cells = <1>;
+-
+- /* CPRMAN derives almost everything from the
+- * platform's oscillator. However, the DSI
+- * pixel clocks come from the DSI analog PHY.
+- */
+- clocks = <&clk_osc>;
+- status = "disabled";
+- };
+-
+- random: rng@7d208000 {
+- compatible = "brcm,bcm2711-rng200";
+- reg = <0x7d208000 0x28>;
+- status = "okay";
+- };
+-
+- cpu_l2_irq: intc@7d503000 {
+- compatible = "brcm,l2-intc";
+- reg = <0x7d503000 0x18>;
+- interrupts = <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>;
+- interrupt-controller;
+- #interrupt-cells = <1>;
+- };
+-
+- pinctrl: pinctrl@7d504100 {
+- compatible = "brcm,bcm2712-pinctrl";
+- reg = <0x7d504100 0x30>;
+-
+- uarta_24_pins: uarta_24_pins {
+- pin_rts {
+- function = "uart0";
+- pins = "gpio24";
+- bias-disable;
+- };
+- pin_cts {
+- function = "uart0";
+- pins = "gpio25";
+- bias-pull-up;
+- };
+- pin_txd {
+- function = "uart0";
+- pins = "gpio26";
+- bias-disable;
+- };
+- pin_rxd {
+- function = "uart0";
+- pins = "gpio27";
+- bias-pull-up;
+- };
+- };
+-
+- sdio2_30_pins: sdio2_30_pins {
+- pin_clk {
+- function = "sd2";
+- pins = "gpio30";
+- bias-disable;
+- };
+- pin_cmd {
+- function = "sd2";
+- pins = "gpio31";
+- bias-pull-up;
+- };
+- pins_dat {
+- function = "sd2";
+- pins = "gpio32", "gpio33", "gpio34", "gpio35";
+- bias-pull-up;
+- };
+- };
+- };
+-
+- ddc0: i2c@7d508200 {
+- compatible = "brcm,brcmstb-i2c";
+- reg = <0x7d508200 0x58>;
+- interrupt-parent = <&bsc_irq>;
+- interrupts = <1>;
+- clock-frequency = <97500>;
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- ddc1: i2c@7d508280 {
+- compatible = "brcm,brcmstb-i2c";
+- reg = <0x7d508280 0x58>;
+- interrupt-parent = <&bsc_irq>;
+- interrupts = <2>;
+- clock-frequency = <97500>;
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- bscd: i2c@7d508300 {
+- compatible = "brcm,brcmstb-i2c";
+- reg = <0x7d508300 0x58>;
+- interrupt-parent = <&bsc_irq>;
+- interrupts = <0>;
+- clock-frequency = <200000>;
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- bsc_irq: intc@7d508380 {
+- compatible = "brcm,bcm7271-l2-intc";
+- reg = <0x7d508380 0x10>;
+- interrupts = <GIC_SPI 242 IRQ_TYPE_LEVEL_HIGH>;
+- interrupt-controller;
+- #interrupt-cells = <1>;
+- };
+-
+- main_irq: intc@7d508400 {
+- compatible = "brcm,bcm7271-l2-intc";
+- reg = <0x7d508400 0x10>;
+- interrupts = <GIC_SPI 244 IRQ_TYPE_LEVEL_HIGH>;
+- interrupt-controller;
+- #interrupt-cells = <1>;
+- };
+-
+- gio: gpio@7d508500 {
+- compatible = "brcm,brcmstb-gpio";
+- reg = <0x7d508500 0x40>;
+- interrupt-parent = <&main_irq>;
+- interrupts = <0>;
+- gpio-controller;
+- #gpio-cells = <2>;
+- interrupt-controller;
+- #interrupt-cells = <2>;
+- brcm,gpio-bank-widths = <32 22>;
+- brcm,gpio-direct;
+- };
+-
+- uarta: serial@7d50c000 {
+- compatible = "brcm,bcm7271-uart";
+- reg = <0x7d50c000 0x20>;
+- reg-names = "uart";
+- reg-shift = <2>;
+- reg-io-width = <4>;
+- interrupts = <GIC_SPI 276 IRQ_TYPE_LEVEL_HIGH>;
+- skip-init;
+- status = "disabled";
+- };
+-
+- uartb: serial@7d50d000 {
+- compatible = "brcm,bcm7271-uart";
+- reg = <0x7d50d000 0x20>;
+- reg-names = "uart";
+- reg-shift = <2>;
+- reg-io-width = <4>;
+- interrupts = <GIC_SPI 277 IRQ_TYPE_LEVEL_HIGH>;
+- skip-init;
+- status = "disabled";
+- };
+-
+- aon_intr: interrupt-controller@7d510600 {
+- compatible = "brcm,bcm2711-l2-intc", "brcm,l2-intc";
+- reg = <0x7d510600 0x30>;
+- interrupts = <GIC_SPI 239 IRQ_TYPE_LEVEL_HIGH>;
+- interrupt-controller;
+- #interrupt-cells = <1>;
+- status = "disabled";
+- };
+-
+- pinctrl_aon: pinctrl@7d510700 {
+- compatible = "brcm,bcm2712-aon-pinctrl";
+- reg = <0x7d510700 0x20>;
+-
+- i2c3_m4_agpio0_pins: i2c3_m4_agpio0_pins {
+- function = "vc_i2c3";
+- pins = "aon_gpio0", "aon_gpio1";
+- bias-pull-up;
+- };
+-
+- bsc_m1_agpio13_pins: bsc_m1_agpio13_pins {
+- function = "bsc_m1";
+- pins = "aon_gpio13", "aon_gpio14";
+- bias-pull-up;
+- };
+-
+- bsc_pmu_sgpio4_pins: bsc_pmu_sgpio4_pins {
+- function = "avs_pmu_bsc";
+- pins = "aon_sgpio4", "aon_sgpio5";
+- };
+-
+- bsc_m2_sgpio4_pins: bsc_m2_sgpio4_pins {
+- function = "bsc_m2";
+- pins = "aon_sgpio4", "aon_sgpio5";
+- };
+-
+- pwm_aon_agpio1_pins: pwm_aon_agpio1_pins {
+- function = "aon_pwm";
+- pins = "aon_gpio1", "aon_gpio2";
+- };
+-
+- pwm_aon_agpio4_pins: pwm_aon_agpio4_pins {
+- function = "vc_pwm0";
+- pins = "aon_gpio4", "aon_gpio5";
+- };
+-
+- pwm_aon_agpio7_pins: pwm_aon_agpio7_pins {
+- function = "aon_pwm";
+- pins = "aon_gpio7", "aon_gpio9";
+- };
+- };
+-
+- intc@7d517000 {
+- compatible = "brcm,bcm7271-l2-intc";
+- reg = <0x7d517000 0x10>;
+- interrupts = <GIC_SPI 247 IRQ_TYPE_LEVEL_HIGH>;
+- interrupt-controller;
+- #interrupt-cells = <1>;
+- status = "disabled";
+- };
+-
+- bscc: i2c@7d517a00 {
+- compatible = "brcm,brcmstb-i2c";
+- reg = <0x7d517a00 0x58>;
+- interrupt-parent = <&bsc_aon_irq>;
+- interrupts = <0>;
+- clock-frequency = <200000>;
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- pwm_aon: pwm@7d517a80 {
+- compatible = "brcm,bcm7038-pwm";
+- reg = <0x7d517a80 0x28>;
+- #pwm-cells = <3>;
+- clocks = <&clk_27MHz>;
+- };
+-
+- main_aon_irq: intc@7d517ac0 {
+- compatible = "brcm,bcm7271-l2-intc";
+- reg = <0x7d517ac0 0x10>;
+- interrupts = <GIC_SPI 245 IRQ_TYPE_LEVEL_HIGH>;
+- interrupt-controller;
+- #interrupt-cells = <1>;
+- };
+-
+- bsc_aon_irq: intc@7d517b00 {
+- compatible = "brcm,bcm7271-l2-intc";
+- reg = <0x7d517b00 0x10>;
+- interrupts = <GIC_SPI 243 IRQ_TYPE_LEVEL_HIGH>;
+- interrupt-controller;
+- #interrupt-cells = <1>;
+- };
+-
+- gio_aon: gpio@7d517c00 {
+- compatible = "brcm,brcmstb-gpio";
+- reg = <0x7d517c00 0x40>;
+- interrupt-parent = <&main_aon_irq>;
+- interrupts = <0>;
+- gpio-controller;
+- #gpio-cells = <2>;
+- interrupt-controller;
+- #interrupt-cells = <2>;
+- brcm,gpio-bank-widths = <17 6>;
+- brcm,gpio-direct;
+- };
+-
+- avs_monitor: avs-monitor@7d542000 {
+- compatible = "brcm,bcm2711-avs-monitor",
+- "syscon", "simple-mfd";
+- reg = <0x7d542000 0xf00>;
+- status = "okay";
+-
+- thermal: thermal {
+- compatible = "brcm,bcm2711-thermal";
+- #thermal-sensor-cells = <0>;
+- };
+- };
+-
+- bsc_pmu: i2c@7d544000 {
+- compatible = "brcm,brcmstb-i2c";
+- reg = <0x7d544000 0x58>;
+- interrupt-parent = <&bsc_aon_irq>;
+- interrupts = <1>;
+- clock-frequency = <200000>;
+- status = "disabled";
+- };
+-
+- hdmi0: hdmi@7ef00700 {
+- compatible = "brcm,bcm2712-hdmi0";
+- reg = <0x7c701400 0x300>,
+- <0x7c701000 0x200>,
+- <0x7c701d00 0x300>,
+- <0x7c702000 0x80>,
+- <0x7c703800 0x200>,
+- <0x7c704000 0x800>,
+- <0x7c700100 0x80>,
+- <0x7d510800 0x100>,
+- <0x7c720000 0x100>;
+- reg-names = "hdmi",
+- "dvp",
+- "phy",
+- "rm",
+- "packet",
+- "metadata",
+- "csc",
+- "cec",
+- "hd";
+- resets = <&dvp 1>;
+- interrupt-parent = <&aon_intr>;
+- interrupts = <1>, <2>, <3>,
+- <7>, <8>;
+- interrupt-names = "cec-tx", "cec-rx", "cec-low",
+- "hpd-connected", "hpd-removed";
+- ddc = <&ddc0>;
+- dmas = <&dma32 10>;
+- dma-names = "audio-rx";
+- status = "disabled";
+- };
+-
+- hdmi1: hdmi@7ef05700 {
+- compatible = "brcm,bcm2712-hdmi1";
+- reg = <0x7c706400 0x300>,
+- <0x7c706000 0x200>,
+- <0x7c706d00 0x300>,
+- <0x7c707000 0x80>,
+- <0x7c708800 0x200>,
+- <0x7c709000 0x800>,
+- <0x7c700180 0x80>,
+- <0x7d511000 0x100>,
+- <0x7c720000 0x100>;
+- reg-names = "hdmi",
+- "dvp",
+- "phy",
+- "rm",
+- "packet",
+- "metadata",
+- "csc",
+- "cec",
+- "hd";
+- ddc = <&ddc1>;
+- resets = <&dvp 2>;
+- interrupt-parent = <&aon_intr>;
+- interrupts = <11>, <12>, <13>,
+- <14>, <15>;
+- interrupt-names = "cec-tx", "cec-rx", "cec-low",
+- "hpd-connected", "hpd-removed";
+- dmas = <&dma32 17>;
+- dma-names = "audio-rx";
+- status = "disabled";
+- };
+- };
+-
+- arm-pmu {
+- compatible = "arm,cortex-a76-pmu";
+- interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+- interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>;
+- };
+-
+- timer {
+- compatible = "arm,armv8-timer";
+- interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) |
+- IRQ_TYPE_LEVEL_LOW)>,
+- <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) |
+- IRQ_TYPE_LEVEL_LOW)>,
+- <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) |
+- IRQ_TYPE_LEVEL_LOW)>,
+- <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) |
+- IRQ_TYPE_LEVEL_LOW)>;
+- /* This only applies to the ARMv7 stub */
+- arm,cpu-registers-not-fw-configured;
+- };
+-
+- cpus: cpus {
+- #address-cells = <1>;
+- #size-cells = <0>;
+- enable-method = "brcm,bcm2836-smp"; // for ARM 32-bit
+-
+- /* Source for d/i cache-line-size, cache-sets, cache-size
+- * https://developer.arm.com/documentation/100798/0401
+- * /L1-memory-system/About-the-L1-memory-system?lang=en
+- */
+- cpu0: cpu@0 {
+- device_type = "cpu";
+- compatible = "arm,cortex-a76";
+- reg = <0x000>;
+- enable-method = "psci";
+- d-cache-size = <0x10000>;
+- d-cache-line-size = <64>;
+- d-cache-sets = <256>; // 64KiB(size)/64(line-size)=1024ways/4-way set
+- i-cache-size = <0x10000>;
+- i-cache-line-size = <64>;
+- i-cache-sets = <256>; // 64KiB(size)/64(line-size)=1024ways/4-way set
+- next-level-cache = <&l2_cache_l0>;
+- };
+-
+- cpu1: cpu@1 {
+- device_type = "cpu";
+- compatible = "arm,cortex-a76";
+- reg = <0x100>;
+- enable-method = "psci";
+- d-cache-size = <0x10000>;
+- d-cache-line-size = <64>;
+- d-cache-sets = <256>; // 64KiB(size)/64(line-size)=1024ways/4-way set
+- i-cache-size = <0x10000>;
+- i-cache-line-size = <64>;
+- i-cache-sets = <256>; // 64KiB(size)/64(line-size)=1024ways/4-way set
+- next-level-cache = <&l2_cache_l1>;
+- };
+-
+- cpu2: cpu@2 {
+- device_type = "cpu";
+- compatible = "arm,cortex-a76";
+- reg = <0x200>;
+- enable-method = "psci";
+- d-cache-size = <0x10000>;
+- d-cache-line-size = <64>;
+- d-cache-sets = <256>; // 64KiB(size)/64(line-size)=1024ways/4-way set
+- i-cache-size = <0x10000>;
+- i-cache-line-size = <64>;
+- i-cache-sets = <256>; // 64KiB(size)/64(line-size)=1024ways/4-way set
+- next-level-cache = <&l2_cache_l2>;
+- };
+-
+- cpu3: cpu@3 {
+- device_type = "cpu";
+- compatible = "arm,cortex-a76";
+- reg = <0x300>;
+- enable-method = "psci";
+- d-cache-size = <0x10000>;
+- d-cache-line-size = <64>;
+- d-cache-sets = <256>; // 64KiB(size)/64(line-size)=1024ways/4-way set
+- i-cache-size = <0x10000>;
+- i-cache-line-size = <64>;
+- i-cache-sets = <256>; // 64KiB(size)/64(line-size)=1024ways/4-way set
+- next-level-cache = <&l2_cache_l3>;
+- };
+-
+- /* Source for cache-line-size and cache-sets:
+- * https://developer.arm.com/documentation/100798/0401
+- * /L2-memory-system/About-the-L2-memory-system?lang=en
+- * and for cache-size:
+- * https://www.raspberrypi.com/documentation/computers
+- * /processors.html#bcm2712
+- */
+- l2_cache_l0: l2-cache-l0 {
+- compatible = "cache";
+- cache-size = <0x80000>;
+- cache-line-size = <128>;
+- cache-sets = <1024>; // 512KiB(size)/64(line-size)=8192ways/8-way set
+- cache-level = <2>;
+- cache-unified;
+- next-level-cache = <&l3_cache>;
+- };
+-
+- l2_cache_l1: l2-cache-l1 {
+- compatible = "cache";
+- cache-size = <0x80000>;
+- cache-line-size = <128>;
+- cache-sets = <1024>; // 512KiB(size)/64(line-size)=8192ways/8-way set
+- cache-level = <2>;
+- cache-unified;
+- next-level-cache = <&l3_cache>;
+- };
+-
+- l2_cache_l2: l2-cache-l2 {
+- compatible = "cache";
+- cache-size = <0x80000>;
+- cache-line-size = <128>;
+- cache-sets = <1024>; // 512KiB(size)/64(line-size)=8192ways/8-way set
+- cache-level = <2>;
+- cache-unified;
+- next-level-cache = <&l3_cache>;
+- };
+-
+- l2_cache_l3: l2-cache-l3 {
+- compatible = "cache";
+- cache-size = <0x80000>;
+- cache-line-size = <128>;
+- cache-sets = <1024>; // 512KiB(size)/64(line-size)=8192ways/8-way set
+- cache-level = <2>;
+- cache-unified;
+- next-level-cache = <&l3_cache>;
+- };
+-
+- /* Source for cache-line-size and cache-sets:
+- * https://developer.arm.com/documentation/100453/0401/L3-cache?lang=en
+- * Source for cache-size:
+- * https://www.raspberrypi.com/documentation/computers/processors.html#bcm2712
+- */
+- l3_cache: l3-cache {
+- compatible = "cache";
+- cache-size = <0x200000>;
+- cache-line-size = <64>;
+- cache-sets = <2048>; // 2MiB(size)/64(line-size)=32768ways/16-way set
+- cache-level = <3>;
+- };
+- };
+-
+- psci {
+- method = "smc";
+- compatible = "arm,psci-1.0", "arm,psci-0.2", "arm,psci";
+- cpu_on = <0xc4000003>;
+- cpu_suspend = <0xc4000001>;
+- cpu_off = <0x84000002>;
+- };
+-
+- axi: axi {
+- compatible = "simple-bus";
+- #address-cells = <2>;
+- #size-cells = <2>;
+-
+- ranges = <0x00 0x00000000 0x00 0x00000000 0x10 0x00000000>,
+- <0x10 0x00000000 0x10 0x00000000 0x01 0x00000000>,
+- <0x14 0x00000000 0x14 0x00000000 0x04 0x00000000>,
+- <0x18 0x00000000 0x18 0x00000000 0x04 0x00000000>,
+- <0x1c 0x00000000 0x1c 0x00000000 0x04 0x00000000>;
+-
+- dma-ranges = <0x00 0x00000000 0x00 0x00000000 0x10 0x00000000>,
+- <0x10 0x00000000 0x10 0x00000000 0x01 0x00000000>,
+- <0x14 0x00000000 0x14 0x00000000 0x04 0x00000000>,
+- <0x18 0x00000000 0x18 0x00000000 0x04 0x00000000>,
+- <0x1c 0x00000000 0x1c 0x00000000 0x04 0x00000000>;
+-
+- vc4: gpu {
+- compatible = "brcm,bcm2712-vc6";
+- };
+-
+- iommu2: iommu@5100 {
+- /* IOMMU2 for PISP-BE, HEVC; and (unused) H264 accelerators */
+- compatible = "brcm,bcm2712-iommu";
+- reg = <0x10 0x5100 0x0 0x80>;
+- cache = <&iommuc>;
+- #iommu-cells = <0>;
+- };
+-
+- iommu4: iommu@5200 {
+- /* IOMMU4 for HVS, MPL/TXP; and (unused) Unicam, PISP-FE, MiniBVN */
+- compatible = "brcm,bcm2712-iommu";
+- reg = <0x10 0x5200 0x0 0x80>;
+- cache = <&iommuc>;
+- #iommu-cells = <0>;
+- #interconnect-cells = <0>;
+- };
+-
+- iommu5: iommu@5280 {
+- /* IOMMU5 for PCIe2 (RP1); and (unused) BSTM */
+- compatible = "brcm,bcm2712-iommu";
+- reg = <0x10 0x5280 0x0 0x80>;
+- cache = <&iommuc>;
+- #iommu-cells = <0>;
+- dma-iova-offset = <0x10 0x00000000>; // HACK for RP1 masters over PCIe
+- };
+-
+- iommuc: iommuc@5b00 {
+- compatible = "brcm,bcm2712-iommuc";
+- reg = <0x10 0x5b00 0x0 0x80>;
+- };
+-
+- dma32: dma@10000 {
+- compatible = "brcm,bcm2712-dma";
+- reg = <0x10 0x00010000 0 0x600>;
+- interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+- interrupt-names = "dma0",
+- "dma1",
+- "dma2",
+- "dma3",
+- "dma4",
+- "dma5";
+- #dma-cells = <1>;
+- brcm,dma-channel-mask = <0x0035>;
+- };
+-
+- dma40: dma@10600 {
+- compatible = "brcm,bcm2712-dma";
+- reg = <0x10 0x00010600 0 0x600>;
+- interrupts =
+- <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>, /* dma4 6 */
+- <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>, /* dma4 7 */
+- <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>, /* dma4 8 */
+- <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>, /* dma4 9 */
+- <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>, /* dma4 10 */
+- <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>; /* dma4 11 */
+- interrupt-names = "dma6",
+- "dma7",
+- "dma8",
+- "dma9",
+- "dma10",
+- "dma11";
+- #dma-cells = <1>;
+- brcm,dma-channel-mask = <0x0fc0>;
+- };
+-
+- // Single-lane Gen3 PCIe
+- // Outbound window at 0x14_000000-0x17_ffffff
+- pcie0: pcie@100000 {
+- compatible = "brcm,bcm2712-pcie";
+- reg = <0x10 0x00100000 0x0 0x9310>;
+- device_type = "pci";
+- max-link-speed = <2>;
+- #address-cells = <3>;
+- #interrupt-cells = <1>;
+- #size-cells = <2>;
+- /*
+- * Unused interrupts:
+- * 208: AER
+- * 215: NMI
+- * 216: PME
+- */
+- interrupt-parent = <&gicv2>;
+- interrupts = <GIC_SPI 213 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 214 IRQ_TYPE_LEVEL_HIGH>;
+- interrupt-names = "pcie", "msi";
+- interrupt-map-mask = <0x0 0x0 0x0 0x7>;
+- interrupt-map = <0 0 0 1 &gicv2 GIC_SPI 209
+- IRQ_TYPE_LEVEL_HIGH>,
+- <0 0 0 2 &gicv2 GIC_SPI 210
+- IRQ_TYPE_LEVEL_HIGH>,
+- <0 0 0 3 &gicv2 GIC_SPI 211
+- IRQ_TYPE_LEVEL_HIGH>,
+- <0 0 0 4 &gicv2 GIC_SPI 212
+- IRQ_TYPE_LEVEL_HIGH>;
+- resets = <&bcm_reset 5>, <&bcm_reset 42>, <&pcie_rescal>;
+- reset-names = "swinit", "bridge", "rescal";
+- msi-controller;
+- msi-parent = <&pcie0>;
+-
+- ranges = <0x02000000 0x00 0x00000000
+- 0x17 0x00000000
+- 0x0 0xfffffffc>,
+- <0x43000000 0x04 0x00000000
+- 0x14 0x00000000
+- 0x3 0x00000000>;
+-
+- dma-ranges = <0x43000000 0x10 0x00000000
+- 0x00 0x00000000
+- 0x10 0x00000000>;
+-
+- status = "disabled";
+- };
+-
+- // Single-lane Gen3 PCIe
+- // Outbound window at 0x18_000000-0x1b_ffffff
+- pcie1: pcie@110000 {
+- compatible = "brcm,bcm2712-pcie";
+- reg = <0x10 0x00110000 0x0 0x9310>;
+- device_type = "pci";
+- max-link-speed = <2>;
+- #address-cells = <3>;
+- #interrupt-cells = <1>;
+- #size-cells = <2>;
+- /*
+- * Unused interrupts:
+- * 218: AER
+- * 225: NMI
+- * 226: PME
+- */
+- interrupt-parent = <&gicv2>;
+- interrupts = <GIC_SPI 223 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>;
+- interrupt-names = "pcie", "msi";
+- interrupt-map-mask = <0x0 0x0 0x0 0x7>;
+- interrupt-map = <0 0 0 1 &gicv2 GIC_SPI 219
+- IRQ_TYPE_LEVEL_HIGH>,
+- <0 0 0 2 &gicv2 GIC_SPI 220
+- IRQ_TYPE_LEVEL_HIGH>,
+- <0 0 0 3 &gicv2 GIC_SPI 221
+- IRQ_TYPE_LEVEL_HIGH>,
+- <0 0 0 4 &gicv2 GIC_SPI 222
+- IRQ_TYPE_LEVEL_HIGH>;
+- resets = <&bcm_reset 7>, <&bcm_reset 43>, <&pcie_rescal>;
+- reset-names = "swinit", "bridge", "rescal";
+- msi-controller;
+- msi-parent = <&mip1>;
+-
+- ranges = <0x02000000 0x00 0x00000000
+- 0x1b 0x00000000
+- 0x00 0xfffffffc>,
+- <0x43000000 0x04 0x00000000
+- 0x18 0x00000000
+- 0x03 0x00000000>;
+-
+- dma-ranges = <0x03000000 0x10 0x00000000
+- 0x00 0x00000000
+- 0x10 0x00000000>;
+-
+- status = "disabled";
+- };
+-
+- pcie_rescal: reset-controller@119500 {
+- compatible = "brcm,bcm7216-pcie-sata-rescal";
+- reg = <0x10 0x00119500 0x0 0x10>;
+- #reset-cells = <0>;
+- };
+-
+- // Quad-lane Gen3 PCIe
+- // Outbound window at 0x1c_000000-0x1f_ffffff
+- pcie2: pcie@120000 {
+- compatible = "brcm,bcm2712-pcie";
+- reg = <0x10 0x00120000 0x0 0x9310>;
+- device_type = "pci";
+- max-link-speed = <2>;
+- #address-cells = <3>;
+- #interrupt-cells = <1>;
+- #size-cells = <2>;
+- /*
+- * Unused interrupts:
+- * 228: AER
+- * 235: NMI
+- * 236: PME
+- */
+- interrupt-parent = <&gicv2>;
+- interrupts = <GIC_SPI 233 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 234 IRQ_TYPE_LEVEL_HIGH>;
+- interrupt-names = "pcie", "msi";
+- interrupt-map-mask = <0x0 0x0 0x0 0x7>;
+- interrupt-map = <0 0 0 1 &gicv2 GIC_SPI 229
+- IRQ_TYPE_LEVEL_HIGH>,
+- <0 0 0 2 &gicv2 GIC_SPI 230
+- IRQ_TYPE_LEVEL_HIGH>,
+- <0 0 0 3 &gicv2 GIC_SPI 231
+- IRQ_TYPE_LEVEL_HIGH>,
+- <0 0 0 4 &gicv2 GIC_SPI 232
+- IRQ_TYPE_LEVEL_HIGH>;
+- resets = <&bcm_reset 32>, <&bcm_reset 44>, <&pcie_rescal>;
+- reset-names = "swinit", "bridge", "rescal";
+- msi-controller;
+- msi-parent = <&mip0>;
+-
+- // ~4GB, 32-bit, not-prefetchable at PCIe 00_00000000
+- ranges = <0x02000000 0x00 0x00000000
+- 0x1f 0x00000000
+- 0x0 0xfffffffc>,
+- // 12GB, 64-bit, prefetchable at PCIe 04_00000000
+- <0x43000000 0x04 0x00000000
+- 0x1c 0x00000000
+- 0x03 0x00000000>;
+-
+- // 64GB system RAM space at PCIe 10_00000000
+- dma-ranges = <0x02000000 0x00 0x00000000
+- 0x1f 0x00000000
+- 0x00 0x00400000>,
+- <0x43000000 0x10 0x00000000
+- 0x00 0x00000000
+- 0x10 0x00000000>;
+-
+- status = "disabled";
+- };
+-
+- mip0: msi-controller@130000 {
+- compatible = "brcm,bcm2712-mip-intc";
+- reg = <0x10 0x00130000 0x0 0xc0>;
+- msi-controller;
+- interrupt-controller;
+- #interrupt-cells = <2>;
+- brcm,msi-base-spi = <128>;
+- brcm,msi-num-spis = <64>;
+- brcm,msi-offset = <0>;
+- brcm,msi-pci-addr = <0xff 0xfffff000>;
+- };
+-
+- mip1: msi-controller@131000 {
+- compatible = "brcm,bcm2712-mip-intc";
+- reg = <0x10 0x00131000 0x0 0xc0>;
+- msi-controller;
+- interrupt-controller;
+- #interrupt-cells = <2>;
+- brcm,msi-base-spi = <247>;
+- /* Actually 20 total, but the others are
+- * both sparse and non-consecutive */
+- brcm,msi-num-spis = <8>;
+- brcm,msi-offset = <8>;
+- brcm,msi-pci-addr = <0xff 0xffffe000>;
+- };
+-
+- syscon_piarbctl: syscon@400018 {
+- compatible = "brcm,syscon-piarbctl", "syscon", "simple-mfd";
+- reg = <0x10 0x00400018 0x0 0x18>;
+- };
+-
+- usb: usb@480000 {
+- compatible = "brcm,bcm2835-usb";
+- reg = <0x10 0x00480000 0x0 0x10000>;
+- interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+- #address-cells = <1>;
+- #size-cells = <0>;
+- clocks = <&clk_usb>;
+- clock-names = "otg";
+- phys = <&usbphy>;
+- phy-names = "usb2-phy";
+- status = "disabled";
+- };
+-
+- rpivid: codec@800000 {
+- compatible = "raspberrypi,rpivid-vid-decoder";
+- reg = <0x10 0x00800000 0x0 0x10000>, /* HEVC */
+- <0x10 0x00840000 0x0 0x1000>; /* INTC */
+- reg-names = "hevc",
+- "intc";
+-
+- interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
+-
+- clocks = <&firmware_clocks 11>;
+- clock-names = "hevc";
+- iommus = <&iommu2>;
+- status = "disabled";
+- };
+-
+- sdio1: mmc@fff000 {
+- compatible = "brcm,bcm2712-sdhci";
+- reg = <0x10 0x00fff000 0x0 0x260>,
+- <0x10 0x00fff400 0x0 0x200>,
+- <0x10 0x015040b0 0x0 0x4>, // Bus isolation control
+- <0x10 0x015200f0 0x0 0x24>; // LCPLL control misc0-8
+- reg-names = "host", "cfg", "busisol", "lcpll";
+- interrupts = <GIC_SPI 273 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&clk_emmc2>;
+- sdhci-caps-mask = <0x0000C000 0x0>;
+- sdhci-caps = <0x0 0x0>;
+- mmc-ddr-3_3v;
+- };
+-
+- sdio2: mmc@1100000 {
+- compatible = "brcm,bcm2712-sdhci";
+- reg = <0x10 0x01100000 0x0 0x260>,
+- <0x10 0x01100400 0x0 0x200>;
+- reg-names = "host", "cfg";
+- interrupts = <GIC_SPI 274 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&clk_emmc2>;
+- sdhci-caps-mask = <0x0000C000 0x0>;
+- sdhci-caps = <0x0 0x0>;
+- supports-cqe;
+- mmc-ddr-3_3v;
+- status = "disabled";
+- };
+-
+- bcm_reset: reset-controller@1504318 {
+- compatible = "brcm,brcmstb-reset";
+- reg = <0x10 0x01504318 0x0 0x30>;
+- #reset-cells = <1>;
+- };
+-
+- v3d: v3d@2000000 {
+- compatible = "brcm,2712-v3d";
+- reg = <0x10 0x02000000 0x0 0x4000>,
+- <0x10 0x02008000 0x0 0x6000>;
+- reg-names = "hub", "core0";
+-
+- power-domains = <&pm BCM2835_POWER_DOMAIN_GRAFX_V3D>;
+- resets = <&pm BCM2835_RESET_V3D>;
+- clocks = <&firmware_clocks 5>;
+- clocks-names = "v3d";
+- interrupts = <GIC_SPI 250 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 249 IRQ_TYPE_LEVEL_HIGH>;
+- status = "disabled";
+- };
+-
+- gicv2: interrupt-controller@7fff9000 {
+- interrupt-controller;
+- #interrupt-cells = <3>;
+- compatible = "arm,gic-400";
+- reg = <0x10 0x7fff9000 0x0 0x1000>,
+- <0x10 0x7fffa000 0x0 0x2000>,
+- <0x10 0x7fffc000 0x0 0x2000>,
+- <0x10 0x7fffe000 0x0 0x2000>;
+- interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) |
+- IRQ_TYPE_LEVEL_HIGH)>;
+- };
+-
+- pisp_be: pisp_be@880000 {
+- compatible = "raspberrypi,pispbe";
+- reg = <0x10 0x00880000 0x0 0x4000>;
+- interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&firmware_clocks 7>;
+- clocks-names = "isp_be";
+- status = "okay";
+- iommus = <&iommu2>;
+- };
+- };
+-
+- clocks {
+- /* The oscillator is the root of the clock tree. */
+- clk_osc: clk-osc {
+- compatible = "fixed-clock";
+- #clock-cells = <0>;
+- clock-output-names = "osc";
+- clock-frequency = <54000000>;
+- };
+-
+- clk_usb: clk-usb {
+- compatible = "fixed-clock";
+- #clock-cells = <0>;
+- clock-output-names = "otg";
+- clock-frequency = <480000000>;
+- };
+-
+- clk_vpu: clk_vpu {
+- #clock-cells = <0>;
+- compatible = "fixed-clock";
+- clock-frequency = <750000000>;
+- clock-output-names = "vpu-clock";
+- };
+-
+- clk_uart: clk_uart {
+- #clock-cells = <0>;
+- compatible = "fixed-clock";
+- clock-frequency = <9216000>;
+- clock-output-names = "uart-clock";
+- };
+-
+- clk_emmc2: clk_emmc2 {
+- #clock-cells = <0>;
+- compatible = "fixed-clock";
+- clock-frequency = <200000000>;
+- clock-output-names = "emmc2-clock";
+- };
+- };
+-
+- usbphy: phy {
+- compatible = "usb-nop-xceiv";
+- #phy-cells = <0>;
+- };
+-};
+--- a/arch/arm/boot/dts/broadcom/rp1.dtsi
++++ /dev/null
+@@ -1,1287 +0,0 @@
+-#include <dt-bindings/clock/rp1.h>
+-#include <dt-bindings/interrupt-controller/irq.h>
+-#include <dt-bindings/mfd/rp1.h>
+-
+-&rp1_target {
+- rp1: rp1 {
+- compatible = "simple-bus";
+- #address-cells = <2>;
+- #size-cells = <2>;
+- #interrupt-cells = <2>;
+- interrupt-controller;
+- interrupt-parent = <&rp1>;
+-
+- // ranges and dma-ranges must be provided by the includer
+-
+- rp1_clocks: clocks@18000 {
+- compatible = "raspberrypi,rp1-clocks";
+- #clock-cells = <1>;
+- reg = <0xc0 0x40018000 0x0 0x10038>;
+- clocks = <&clk_xosc>;
+-
+- assigned-clocks = <&rp1_clocks RP1_PLL_SYS_CORE>,
+- <&rp1_clocks RP1_PLL_AUDIO_CORE>,
+- // RP1_PLL_VIDEO_CORE and dividers are now managed by VEC,DPI drivers
+- <&rp1_clocks RP1_PLL_SYS>,
+- <&rp1_clocks RP1_PLL_SYS_SEC>,
+- <&rp1_clocks RP1_PLL_AUDIO>,
+- <&rp1_clocks RP1_PLL_AUDIO_SEC>,
+- <&rp1_clocks RP1_CLK_SYS>,
+- <&rp1_clocks RP1_PLL_SYS_PRI_PH>,
+- // RP1_CLK_SLOW_SYS is used for the frequency counter (FC0)
+- <&rp1_clocks RP1_CLK_SLOW_SYS>,
+- <&rp1_clocks RP1_CLK_SDIO_TIMER>,
+- <&rp1_clocks RP1_CLK_SDIO_ALT_SRC>,
+- <&rp1_clocks RP1_CLK_ETH_TSU>;
+-
+- assigned-clock-rates = <1000000000>, // RP1_PLL_SYS_CORE
+- <1536000000>, // RP1_PLL_AUDIO_CORE
+- <200000000>, // RP1_PLL_SYS
+- <125000000>, // RP1_PLL_SYS_SEC
+- <61440000>, // RP1_PLL_AUDIO
+- <192000000>, // RP1_PLL_AUDIO_SEC
+- <200000000>, // RP1_CLK_SYS
+- <100000000>, // RP1_PLL_SYS_PRI_PH
+- // Must match the XOSC frequency
+- <50000000>, // RP1_CLK_SLOW_SYS
+- <1000000>, // RP1_CLK_SDIO_TIMER
+- <200000000>, // RP1_CLK_SDIO_ALT_SRC
+- <50000000>; // RP1_CLK_ETH_TSU
+- };
+-
+- rp1_uart0: serial@30000 {
+- compatible = "arm,pl011-axi";
+- reg = <0xc0 0x40030000 0x0 0x100>;
+- interrupts = <RP1_INT_UART0 IRQ_TYPE_LEVEL_HIGH>;
+- 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";
+- pinctrl-names = "default";
+- arm,primecell-periphid = <0x00541011>;
+- uart-has-rtscts;
+- cts-event-workaround;
+- skip-init;
+- status = "disabled";
+- };
+-
+- rp1_uart1: serial@34000 {
+- compatible = "arm,pl011-axi";
+- reg = <0xc0 0x40034000 0x0 0x100>;
+- interrupts = <RP1_INT_UART1 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&rp1_clocks RP1_CLK_UART &rp1_clocks RP1_PLL_SYS_PRI_PH>;
+- clock-names = "uartclk", "apb_pclk";
+- // dmas = <&rp1_dma RP1_DMA_UART1_TX>,
+- // <&rp1_dma RP1_DMA_UART1_RX>;
+- // dma-names = "tx", "rx";
+- pinctrl-names = "default";
+- arm,primecell-periphid = <0x00541011>;
+- uart-has-rtscts;
+- cts-event-workaround;
+- skip-init;
+- status = "disabled";
+- };
+-
+- rp1_uart2: serial@38000 {
+- compatible = "arm,pl011-axi";
+- reg = <0xc0 0x40038000 0x0 0x100>;
+- interrupts = <RP1_INT_UART2 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&rp1_clocks RP1_CLK_UART &rp1_clocks RP1_PLL_SYS_PRI_PH>;
+- clock-names = "uartclk", "apb_pclk";
+- // dmas = <&rp1_dma RP1_DMA_UART2_TX>,
+- // <&rp1_dma RP1_DMA_UART2_RX>;
+- // dma-names = "tx", "rx";
+- pinctrl-names = "default";
+- arm,primecell-periphid = <0x00541011>;
+- uart-has-rtscts;
+- cts-event-workaround;
+- skip-init;
+- status = "disabled";
+- };
+-
+- rp1_uart3: serial@3c000 {
+- compatible = "arm,pl011-axi";
+- reg = <0xc0 0x4003c000 0x0 0x100>;
+- interrupts = <RP1_INT_UART3 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&rp1_clocks RP1_CLK_UART &rp1_clocks RP1_PLL_SYS_PRI_PH>;
+- clock-names = "uartclk", "apb_pclk";
+- // dmas = <&rp1_dma RP1_DMA_UART3_TX>,
+- // <&rp1_dma RP1_DMA_UART3_RX>;
+- // dma-names = "tx", "rx";
+- pinctrl-names = "default";
+- arm,primecell-periphid = <0x00541011>;
+- uart-has-rtscts;
+- cts-event-workaround;
+- skip-init;
+- status = "disabled";
+- };
+-
+- rp1_uart4: serial@40000 {
+- compatible = "arm,pl011-axi";
+- reg = <0xc0 0x40040000 0x0 0x100>;
+- interrupts = <RP1_INT_UART4 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&rp1_clocks RP1_CLK_UART &rp1_clocks RP1_PLL_SYS_PRI_PH>;
+- clock-names = "uartclk", "apb_pclk";
+- // dmas = <&rp1_dma RP1_DMA_UART4_TX>,
+- // <&rp1_dma RP1_DMA_UART4_RX>;
+- // dma-names = "tx", "rx";
+- pinctrl-names = "default";
+- arm,primecell-periphid = <0x00541011>;
+- uart-has-rtscts;
+- cts-event-workaround;
+- skip-init;
+- status = "disabled";
+- };
+-
+- rp1_uart5: serial@44000 {
+- compatible = "arm,pl011-axi";
+- reg = <0xc0 0x40044000 0x0 0x100>;
+- interrupts = <RP1_INT_UART5 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&rp1_clocks RP1_CLK_UART &rp1_clocks RP1_PLL_SYS_PRI_PH>;
+- clock-names = "uartclk", "apb_pclk";
+- // dmas = <&rp1_dma RP1_DMA_UART5_TX>,
+- // <&rp1_dma RP1_DMA_UART5_RX>;
+- // dma-names = "tx", "rx";
+- pinctrl-names = "default";
+- arm,primecell-periphid = <0x00541011>;
+- uart-has-rtscts;
+- cts-event-workaround;
+- skip-init;
+- status = "disabled";
+- };
+-
+- rp1_spi8: spi@4c000 {
+- reg = <0xc0 0x4004c000 0x0 0x130>;
+- compatible = "snps,dw-apb-ssi";
+- interrupts = <RP1_INT_SPI8 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&rp1_clocks RP1_CLK_SYS>;
+- clock-names = "ssi_clk";
+- #address-cells = <1>;
+- #size-cells = <0>;
+- num-cs = <2>;
+- dmas = <&rp1_dma RP1_DMA_SPI8_TX>,
+- <&rp1_dma RP1_DMA_SPI8_RX>;
+- dma-names = "tx", "rx";
+- status = "disabled";
+- };
+-
+- rp1_spi0: spi@50000 {
+- reg = <0xc0 0x40050000 0x0 0x130>;
+- compatible = "snps,dw-apb-ssi";
+- interrupts = <RP1_INT_SPI0 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&rp1_clocks RP1_CLK_SYS>;
+- clock-names = "ssi_clk";
+- #address-cells = <1>;
+- #size-cells = <0>;
+- num-cs = <2>;
+- dmas = <&rp1_dma RP1_DMA_SPI0_TX>,
+- <&rp1_dma RP1_DMA_SPI0_RX>;
+- dma-names = "tx", "rx";
+- status = "disabled";
+- };
+-
+- rp1_spi1: spi@54000 {
+- reg = <0xc0 0x40054000 0x0 0x130>;
+- compatible = "snps,dw-apb-ssi";
+- interrupts = <RP1_INT_SPI1 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&rp1_clocks RP1_CLK_SYS>;
+- clock-names = "ssi_clk";
+- #address-cells = <1>;
+- #size-cells = <0>;
+- num-cs = <2>;
+- dmas = <&rp1_dma RP1_DMA_SPI1_TX>,
+- <&rp1_dma RP1_DMA_SPI1_RX>;
+- dma-names = "tx", "rx";
+- status = "disabled";
+- };
+-
+- rp1_spi2: spi@58000 {
+- reg = <0xc0 0x40058000 0x0 0x130>;
+- compatible = "snps,dw-apb-ssi";
+- interrupts = <RP1_INT_SPI2 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&rp1_clocks RP1_CLK_SYS>;
+- clock-names = "ssi_clk";
+- #address-cells = <1>;
+- #size-cells = <0>;
+- num-cs = <2>;
+- dmas = <&rp1_dma RP1_DMA_SPI2_TX>,
+- <&rp1_dma RP1_DMA_SPI2_RX>;
+- dma-names = "tx", "rx";
+- status = "disabled";
+- };
+-
+- rp1_spi3: spi@5c000 {
+- reg = <0xc0 0x4005c000 0x0 0x130>;
+- compatible = "snps,dw-apb-ssi";
+- interrupts = <RP1_INT_SPI3 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&rp1_clocks RP1_CLK_SYS>;
+- clock-names = "ssi_clk";
+- #address-cells = <1>;
+- #size-cells = <0>;
+- num-cs = <2>;
+- dmas = <&rp1_dma RP1_DMA_SPI3_TX>,
+- <&rp1_dma RP1_DMA_SPI3_RX>;
+- dma-names = "tx", "rx";
+- status = "disabled";
+- };
+-
+- // SPI4 is a target/slave interface
+- rp1_spi4: spi@60000 {
+- reg = <0xc0 0x40060000 0x0 0x130>;
+- compatible = "snps,dw-apb-ssi";
+- interrupts = <RP1_INT_SPI4 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&rp1_clocks RP1_CLK_SYS>;
+- clock-names = "ssi_clk";
+- #address-cells = <0>;
+- #size-cells = <0>;
+- num-cs = <1>;
+- spi-slave;
+- dmas = <&rp1_dma RP1_DMA_SPI4_TX>,
+- <&rp1_dma RP1_DMA_SPI4_RX>;
+- dma-names = "tx", "rx";
+- status = "disabled";
+-
+- slave {
+- compatible = "spidev";
+- spi-max-frequency = <1000000>;
+- };
+- };
+-
+- rp1_spi5: spi@64000 {
+- reg = <0xc0 0x40064000 0x0 0x130>;
+- compatible = "snps,dw-apb-ssi";
+- interrupts = <RP1_INT_SPI5 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&rp1_clocks RP1_CLK_SYS>;
+- clock-names = "ssi_clk";
+- #address-cells = <1>;
+- #size-cells = <0>;
+- num-cs = <2>;
+- dmas = <&rp1_dma RP1_DMA_SPI5_TX>,
+- <&rp1_dma RP1_DMA_SPI5_RX>;
+- dma-names = "tx", "rx";
+- status = "disabled";
+- };
+-
+- rp1_spi6: spi@68000 {
+- reg = <0xc0 0x40068000 0x0 0x130>;
+- compatible = "snps,dw-apb-ssi";
+- interrupts = <RP1_INT_SPI6 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&rp1_clocks RP1_CLK_SYS>;
+- clock-names = "ssi_clk";
+- #address-cells = <1>;
+- #size-cells = <0>;
+- num-cs = <2>;
+- dmas = <&rp1_dma RP1_DMA_SPI6_TX>,
+- <&rp1_dma RP1_DMA_SPI6_RX>;
+- dma-names = "tx", "rx";
+- status = "disabled";
+- };
+-
+- // SPI7 is a target/slave interface
+- rp1_spi7: spi@6c000 {
+- reg = <0xc0 0x4006c000 0x0 0x130>;
+- compatible = "snps,dw-apb-ssi";
+- interrupts = <RP1_INT_SPI7 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&rp1_clocks RP1_CLK_SYS>;
+- clock-names = "ssi_clk";
+- #address-cells = <0>;
+- #size-cells = <0>;
+- num-cs = <1>;
+- spi-slave;
+- dmas = <&rp1_dma RP1_DMA_SPI7_TX>,
+- <&rp1_dma RP1_DMA_SPI7_RX>;
+- dma-names = "tx", "rx";
+- status = "disabled";
+-
+- slave {
+- compatible = "spidev";
+- spi-max-frequency = <1000000>;
+- };
+- };
+-
+- rp1_i2c0: i2c@70000 {
+- reg = <0xc0 0x40070000 0x0 0x1000>;
+- compatible = "snps,designware-i2c";
+- interrupts = <RP1_INT_I2C0 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&rp1_clocks RP1_CLK_SYS>;
+- i2c-scl-rising-time-ns = <65>;
+- i2c-scl-falling-time-ns = <100>;
+- status = "disabled";
+- };
+-
+- rp1_i2c1: i2c@74000 {
+- reg = <0xc0 0x40074000 0x0 0x1000>;
+- compatible = "snps,designware-i2c";
+- interrupts = <RP1_INT_I2C1 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&rp1_clocks RP1_CLK_SYS>;
+- i2c-scl-rising-time-ns = <65>;
+- i2c-scl-falling-time-ns = <100>;
+- status = "disabled";
+- };
+-
+- rp1_i2c2: i2c@78000 {
+- reg = <0xc0 0x40078000 0x0 0x1000>;
+- compatible = "snps,designware-i2c";
+- interrupts = <RP1_INT_I2C2 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&rp1_clocks RP1_CLK_SYS>;
+- i2c-scl-rising-time-ns = <65>;
+- i2c-scl-falling-time-ns = <100>;
+- status = "disabled";
+- };
+-
+- rp1_i2c3: i2c@7c000 {
+- reg = <0xc0 0x4007c000 0x0 0x1000>;
+- compatible = "snps,designware-i2c";
+- interrupts = <RP1_INT_I2C3 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&rp1_clocks RP1_CLK_SYS>;
+- i2c-scl-rising-time-ns = <65>;
+- i2c-scl-falling-time-ns = <100>;
+- status = "disabled";
+- };
+-
+- rp1_i2c4: i2c@80000 {
+- reg = <0xc0 0x40080000 0x0 0x1000>;
+- compatible = "snps,designware-i2c";
+- interrupts = <RP1_INT_I2C4 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&rp1_clocks RP1_CLK_SYS>;
+- i2c-scl-rising-time-ns = <65>;
+- i2c-scl-falling-time-ns = <100>;
+- status = "disabled";
+- };
+-
+- rp1_i2c5: i2c@84000 {
+- reg = <0xc0 0x40084000 0x0 0x1000>;
+- compatible = "snps,designware-i2c";
+- interrupts = <RP1_INT_I2C5 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&rp1_clocks RP1_CLK_SYS>;
+- i2c-scl-rising-time-ns = <65>;
+- i2c-scl-falling-time-ns = <100>;
+- status = "disabled";
+- };
+-
+- rp1_i2c6: i2c@88000 {
+- reg = <0xc0 0x40088000 0x0 0x1000>;
+- compatible = "snps,designware-i2c";
+- interrupts = <RP1_INT_I2C6 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&rp1_clocks RP1_CLK_SYS>;
+- i2c-scl-rising-time-ns = <65>;
+- i2c-scl-falling-time-ns = <100>;
+- status = "disabled";
+- };
+-
+- rp1_pwm0: pwm@98000 {
+- compatible = "raspberrypi,rp1-pwm";
+- reg = <0xc0 0x40098000 0x0 0x100>;
+- #pwm-cells = <3>;
+- clocks = <&rp1_clocks RP1_CLK_PWM0>;
+- assigned-clocks = <&rp1_clocks RP1_CLK_PWM0>;
+- assigned-clock-rates = <50000000>;
+- status = "disabled";
+- };
+-
+- rp1_pwm1: pwm@9c000 {
+- compatible = "raspberrypi,rp1-pwm";
+- reg = <0xc0 0x4009c000 0x0 0x100>;
+- #pwm-cells = <3>;
+- clocks = <&rp1_clocks RP1_CLK_PWM1>;
+- assigned-clocks = <&rp1_clocks RP1_CLK_PWM1>;
+- assigned-clock-rates = <50000000>;
+- status = "disabled";
+- };
+-
+- rp1_i2s0: i2s@a0000 {
+- reg = <0xc0 0x400a0000 0x0 0x1000>;
+- compatible = "snps,designware-i2s";
+- // Providing an interrupt disables DMA
+- // interrupts = <RP1_INT_I2S0 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&rp1_clocks RP1_CLK_I2S>;
+- clock-names = "i2sclk";
+- #sound-dai-cells = <0>;
+- dmas = <&rp1_dma RP1_DMA_I2S0_TX>,<&rp1_dma RP1_DMA_I2S0_RX>;
+- dma-names = "tx", "rx";
+- status = "disabled";
+- };
+-
+- rp1_i2s1: i2s@a4000 {
+- reg = <0xc0 0x400a4000 0x0 0x1000>;
+- compatible = "snps,designware-i2s";
+- // Providing an interrupt disables DMA
+- // interrupts = <RP1_INT_I2S1 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&rp1_clocks RP1_CLK_I2S>;
+- clock-names = "i2sclk";
+- #sound-dai-cells = <0>;
+- dmas = <&rp1_dma RP1_DMA_I2S1_TX>,<&rp1_dma RP1_DMA_I2S1_RX>;
+- dma-names = "tx", "rx";
+- status = "disabled";
+- };
+-
+- rp1_i2s2: i2s@a8000 {
+- reg = <0xc0 0x400a8000 0x0 0x1000>;
+- compatible = "snps,designware-i2s";
+- // Providing an interrupt disables DMA
+- // interrupts = <RP1_INT_I2S2 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&rp1_clocks RP1_CLK_I2S>;
+- status = "disabled";
+- };
+-
+- rp1_sdio_clk0: sdio_clk0@b0004 {
+- compatible = "raspberrypi,rp1-sdio-clk";
+- reg = <0xc0 0x400b0004 0x0 0x1c>;
+- clocks = <&sdio_src &sdhci_core>;
+- clock-names = "src", "base";
+- #clock-cells = <0>;
+- status = "disabled";
+- };
+-
+- rp1_sdio_clk1: sdio_clk1@b4004 {
+- compatible = "raspberrypi,rp1-sdio-clk";
+- reg = <0xc0 0x400b4004 0x0 0x1c>;
+- clocks = <&sdio_src &sdhci_core>;
+- clock-names = "src", "base";
+- #clock-cells = <0>;
+- status = "disabled";
+- };
+-
+- rp1_adc: adc@c8000 {
+- compatible = "raspberrypi,rp1-adc";
+- reg = <0xc0 0x400c8000 0x0 0x4000>;
+- clocks = <&rp1_clocks RP1_CLK_ADC>;
+- clock-names = "adcclk";
+- #clock-cells = <0>;
+- vref-supply = <&rp1_vdd_3v3>;
+- status = "disabled";
+- };
+-
+- rp1_gpio: gpio@d0000 {
+- reg = <0xc0 0x400d0000 0x0 0xc000>,
+- <0xc0 0x400e0000 0x0 0xc000>,
+- <0xc0 0x400f0000 0x0 0xc000>;
+- compatible = "raspberrypi,rp1-gpio";
+- interrupts = <RP1_INT_IO_BANK0 IRQ_TYPE_LEVEL_HIGH>,
+- <RP1_INT_IO_BANK1 IRQ_TYPE_LEVEL_HIGH>,
+- <RP1_INT_IO_BANK2 IRQ_TYPE_LEVEL_HIGH>;
+- gpio-controller;
+- #gpio-cells = <2>;
+- interrupt-controller;
+- #interrupt-cells = <2>;
+- gpio-ranges = <&rp1_gpio 0 0 54>;
+-
+- rp1_uart0_14_15: rp1_uart0_14_15 {
+- pin_txd {
+- function = "uart0";
+- pins = "gpio14";
+- bias-disable;
+- };
+- pin_rxd {
+- function = "uart0";
+- pins = "gpio15";
+- bias-pull-up;
+- };
+- };
+- rp1_uart0_ctsrts_16_17: rp1_uart0_ctsrts_16_17 {
+- pin_cts {
+- function = "uart0";
+- pins = "gpio16";
+- bias-pull-up;
+- };
+- pin_rts {
+- function = "uart0";
+- pins = "gpio17";
+- bias-disable;
+- };
+- };
+- rp1_uart1_0_1: rp1_uart1_0_1 {
+- pin_txd {
+- function = "uart1";
+- pins = "gpio0";
+- bias-disable;
+- };
+- pin_rxd {
+- function = "uart1";
+- pins = "gpio1";
+- bias-pull-up;
+- };
+- };
+- rp1_uart1_ctsrts_2_3: rp1_uart1_ctsrts_2_3 {
+- pin_cts {
+- function = "uart1";
+- pins = "gpio2";
+- bias-pull-up;
+- };
+- pin_rts {
+- function = "uart1";
+- pins = "gpio3";
+- bias-disable;
+- };
+- };
+- rp1_uart2_4_5: rp1_uart2_4_5 {
+- pin_txd {
+- function = "uart2";
+- pins = "gpio4";
+- bias-disable;
+- };
+- pin_rxd {
+- function = "uart2";
+- pins = "gpio5";
+- bias-pull-up;
+- };
+- };
+- rp1_uart2_ctsrts_6_7: rp1_uart2_ctsrts_6_7 {
+- pin_cts {
+- function = "uart2";
+- pins = "gpio6";
+- bias-pull-up;
+- };
+- pin_rts {
+- function = "uart2";
+- pins = "gpio7";
+- bias-disable;
+- };
+- };
+- rp1_uart3_8_9: rp1_uart3_8_9 {
+- pin_txd {
+- function = "uart3";
+- pins = "gpio8";
+- bias-disable;
+- };
+- pin_rxd {
+- function = "uart3";
+- pins = "gpio9";
+- bias-pull-up;
+- };
+- };
+- rp1_uart3_ctsrts_10_11: rp1_uart3_ctsrts_10_11 {
+- pin_cts {
+- function = "uart3";
+- pins = "gpio10";
+- bias-pull-up;
+- };
+- pin_rts {
+- function = "uart3";
+- pins = "gpio11";
+- bias-disable;
+- };
+- };
+- rp1_uart4_12_13: rp1_uart4_12_13 {
+- pin_txd {
+- function = "uart4";
+- pins = "gpio12";
+- bias-disable;
+- };
+- pin_rxd {
+- function = "uart4";
+- pins = "gpio13";
+- bias-pull-up;
+- };
+- };
+- rp1_uart4_ctsrts_14_15: rp1_uart4_ctsrts_14_15 {
+- pin_cts {
+- function = "uart4";
+- pins = "gpio14";
+- bias-pull-up;
+- };
+- pin_rts {
+- function = "uart4";
+- pins = "gpio15";
+- bias-disable;
+- };
+- };
+-
+- rp1_sdio0_22_27: rp1_sdio0_22_27 {
+- pin_clk {
+- function = "sd0";
+- pins = "gpio22";
+- bias-disable;
+- drive-strength = <12>;
+- slew-rate = <1>;
+- };
+- pin_cmd {
+- function = "sd0";
+- pins = "gpio23";
+- bias-pull-up;
+- drive-strength = <12>;
+- slew-rate = <1>;
+- };
+- pins_dat {
+- function = "sd0";
+- pins = "gpio24", "gpio25", "gpio26", "gpio27";
+- bias-pull-up;
+- drive-strength = <12>;
+- slew-rate = <1>;
+- };
+- };
+-
+- rp1_sdio1_28_33: rp1_sdio1_28_33 {
+- pin_clk {
+- function = "sd1";
+- pins = "gpio28";
+- bias-disable;
+- drive-strength = <12>;
+- slew-rate = <1>;
+- };
+- pin_cmd {
+- function = "sd1";
+- pins = "gpio29";
+- bias-pull-up;
+- drive-strength = <12>;
+- slew-rate = <1>;
+- };
+- pins_dat {
+- function = "sd1";
+- pins = "gpio30", "gpio31", "gpio32", "gpio33";
+- bias-pull-up;
+- drive-strength = <12>;
+- slew-rate = <1>;
+- };
+- };
+-
+- rp1_i2s0_18_21: rp1_i2s0_18_21 {
+- function = "i2s0";
+- pins = "gpio18", "gpio19", "gpio20", "gpio21";
+- bias-disable;
+- };
+-
+- rp1_i2s1_18_21: rp1_i2s1_18_21 {
+- function = "i2s1";
+- pins = "gpio18", "gpio19", "gpio20", "gpio21";
+- bias-disable;
+- };
+-
+- rp1_i2c4_34_35: rp1_i2c4_34_35 {
+- function = "i2c4";
+- pins = "gpio34", "gpio35";
+- drive-strength = <12>;
+- bias-pull-up;
+- };
+- rp1_i2c6_38_39: rp1_i2c6_38_39 {
+- function = "i2c6";
+- pins = "gpio38", "gpio39";
+- drive-strength = <12>;
+- bias-pull-up;
+- };
+- rp1_i2c4_40_41: rp1_i2c4_40_41 {
+- function = "i2c4";
+- pins = "gpio40", "gpio41";
+- drive-strength = <12>;
+- bias-pull-up;
+- };
+- rp1_i2c5_44_45: rp1_i2c5_44_45 {
+- function = "i2c5";
+- pins = "gpio44", "gpio45";
+- drive-strength = <12>;
+- bias-pull-up;
+- };
+- rp1_i2c0_0_1: rp1_i2c0_0_1 {
+- function = "i2c0";
+- pins = "gpio0", "gpio1";
+- drive-strength = <12>;
+- bias-pull-up;
+- };
+- rp1_i2c0_8_9: rp1_i2c0_8_9 {
+- function = "i2c0";
+- pins = "gpio8", "gpio9";
+- drive-strength = <12>;
+- bias-pull-up;
+- };
+- rp1_i2c1_2_3: rp1_i2c1_2_3 {
+- function = "i2c1";
+- pins = "gpio2", "gpio3";
+- drive-strength = <12>;
+- bias-pull-up;
+- };
+- rp1_i2c1_10_11: rp1_i2c1_10_11 {
+- function = "i2c1";
+- pins = "gpio10", "gpio11";
+- drive-strength = <12>;
+- bias-pull-up;
+- };
+- rp1_i2c2_4_5: rp1_i2c2_4_5 {
+- function = "i2c2";
+- pins = "gpio4", "gpio5";
+- drive-strength = <12>;
+- bias-pull-up;
+- };
+- rp1_i2c2_12_13: rp1_i2c2_12_13 {
+- function = "i2c2";
+- pins = "gpio12", "gpio13";
+- drive-strength = <12>;
+- bias-pull-up;
+- };
+- rp1_i2c3_6_7: rp1_i2c3_6_7 {
+- function = "i2c3";
+- pins = "gpio6", "gpio7";
+- drive-strength = <12>;
+- bias-pull-up;
+- };
+- rp1_i2c3_14_15: rp1_i2c3_14_15 {
+- function = "i2c3";
+- pins = "gpio14", "gpio15";
+- drive-strength = <12>;
+- bias-pull-up;
+- };
+- rp1_i2c3_22_23: rp1_i2c3_22_23 {
+- function = "i2c3";
+- pins = "gpio22", "gpio23";
+- drive-strength = <12>;
+- bias-pull-up;
+- };
+-
+- // DPI mappings with HSYNC,VSYNC but without PIXCLK,DE
+- rp1_dpi_16bit_gpio2: rp1_dpi_16bit_gpio2 { /* Mode 2, not fully supported by RP1 */
+- function = "dpi";
+- pins = "gpio2", "gpio3", "gpio4", "gpio5",
+- "gpio6", "gpio7", "gpio8", "gpio9",
+- "gpio10", "gpio11", "gpio12", "gpio13",
+- "gpio14", "gpio15", "gpio16", "gpio17",
+- "gpio18", "gpio19";
+- bias-disable;
+- };
+- rp1_dpi_16bit_cpadhi_gpio2: rp1_dpi_16bit_cpadhi_gpio2 { /* Mode 3 */
+- function = "dpi";
+- pins = "gpio2", "gpio3", "gpio4", "gpio5",
+- "gpio6", "gpio7", "gpio8",
+- "gpio12", "gpio13", "gpio14", "gpio15",
+- "gpio16", "gpio17",
+- "gpio20", "gpio21", "gpio22", "gpio23",
+- "gpio24";
+- bias-disable;
+- };
+- rp1_dpi_16bit_pad666_gpio2: rp1_dpi_16bit_pad666_gpio2 { /* Mode 4 */
+- function = "dpi";
+- pins = "gpio2", "gpio3",
+- "gpio5", "gpio6", "gpio7", "gpio8",
+- "gpio9",
+- "gpio12", "gpio13", "gpio14", "gpio15",
+- "gpio16", "gpio17",
+- "gpio21", "gpio22", "gpio23", "gpio24",
+- "gpio25";
+- bias-disable;
+- };
+- rp1_dpi_18bit_gpio2: rp1_dpi_18bit_gpio2 { /* Mode 5, not fully supported by RP1 */
+- function = "dpi";
+- pins = "gpio2", "gpio3", "gpio4", "gpio5",
+- "gpio6", "gpio7", "gpio8", "gpio9",
+- "gpio10", "gpio11", "gpio12", "gpio13",
+- "gpio14", "gpio15", "gpio16", "gpio17",
+- "gpio18", "gpio19", "gpio20", "gpio21";
+- bias-disable;
+- };
+- rp1_dpi_18bit_cpadhi_gpio2: rp1_dpi_18bit_cpadhi_gpio2 { /* Mode 6 */
+- function = "dpi";
+- pins = "gpio2", "gpio3", "gpio4", "gpio5",
+- "gpio6", "gpio7", "gpio8", "gpio9",
+- "gpio12", "gpio13", "gpio14", "gpio15",
+- "gpio16", "gpio17",
+- "gpio20", "gpio21", "gpio22", "gpio23",
+- "gpio24", "gpio25";
+- bias-disable;
+- };
+- rp1_dpi_24bit_gpio2: rp1_dpi_24bit_gpio2 { /* Mode 7 */
+- function = "dpi";
+- pins = "gpio2", "gpio3", "gpio4", "gpio5",
+- "gpio6", "gpio7", "gpio8", "gpio9",
+- "gpio10", "gpio11", "gpio12", "gpio13",
+- "gpio14", "gpio15", "gpio16", "gpio17",
+- "gpio18", "gpio19", "gpio20", "gpio21",
+- "gpio22", "gpio23", "gpio24", "gpio25",
+- "gpio26", "gpio27";
+- bias-disable;
+- };
+- rp1_dpi_hvsync: rp1_dpi_hvsync { /* Sync only, for use with int VDAC */
+- function = "dpi";
+- pins = "gpio2", "gpio3";
+- bias-disable;
+- };
+-
+- // More DPI mappings, including PIXCLK,DE on GPIOs 0,1
+- rp1_dpi_16bit_gpio0: rp1_dpi_16bit_gpio0 { /* Mode 2, not fully supported by RP1 */
+- function = "dpi";
+- pins = "gpio0", "gpio1", "gpio2", "gpio3",
+- "gpio4", "gpio5", "gpio6", "gpio7",
+- "gpio8", "gpio9", "gpio10", "gpio11",
+- "gpio12", "gpio13", "gpio14", "gpio15",
+- "gpio16", "gpio17", "gpio18", "gpio19";
+- bias-disable;
+- };
+- rp1_dpi_16bit_cpadhi_gpio0: rp1_dpi_16bit_cpadhi_gpio0 { /* Mode 3 */
+- function = "dpi";
+- pins = "gpio0", "gpio1", "gpio2", "gpio3",
+- "gpio4", "gpio5", "gpio6", "gpio7",
+- "gpio8",
+- "gpio12", "gpio13", "gpio14", "gpio15",
+- "gpio16", "gpio17",
+- "gpio20", "gpio21", "gpio22", "gpio23",
+- "gpio24";
+- bias-disable;
+- };
+- rp1_dpi_16bit_pad666_gpio0: rp1_dpi_16bit_pad666_gpio0 { /* Mode 4 */
+- function = "dpi";
+- pins = "gpio0", "gpio1", "gpio2", "gpio3",
+- "gpio5", "gpio6", "gpio7", "gpio8",
+- "gpio9",
+- "gpio12", "gpio13", "gpio14", "gpio15",
+- "gpio16", "gpio17",
+- "gpio21", "gpio22", "gpio23", "gpio24",
+- "gpio25";
+- bias-disable;
+- };
+- rp1_dpi_18bit_gpio0: rp1_dpi_18bit_gpio0 { /* Mode 5, not fully supported by RP1 */
+- function = "dpi";
+- pins = "gpio0", "gpio1", "gpio2", "gpio3",
+- "gpio4", "gpio5", "gpio6", "gpio7",
+- "gpio8", "gpio9", "gpio10", "gpio11",
+- "gpio12", "gpio13", "gpio14", "gpio15",
+- "gpio16", "gpio17", "gpio18", "gpio19",
+- "gpio20", "gpio21";
+- bias-disable;
+- };
+- rp1_dpi_18bit_cpadhi_gpio0: rp1_dpi_18bit_cpadhi_gpio0 { /* Mode 6 */
+- function = "dpi";
+- pins = "gpio0", "gpio1", "gpio2", "gpio3",
+- "gpio4", "gpio5", "gpio6", "gpio7",
+- "gpio8", "gpio9",
+- "gpio12", "gpio13", "gpio14", "gpio15",
+- "gpio16", "gpio17",
+- "gpio20", "gpio21", "gpio22", "gpio23",
+- "gpio24", "gpio25";
+- bias-disable;
+- };
+- rp1_dpi_24bit_gpio0: rp1_dpi_24bit_gpio0 { /* Mode 7 -- All GPIOs used! */
+- function = "dpi";
+- pins = "gpio0", "gpio1", "gpio2", "gpio3",
+- "gpio4", "gpio5", "gpio6", "gpio7",
+- "gpio8", "gpio9", "gpio10", "gpio11",
+- "gpio12", "gpio13", "gpio14", "gpio15",
+- "gpio16", "gpio17", "gpio18", "gpio19",
+- "gpio20", "gpio21", "gpio22", "gpio23",
+- "gpio24", "gpio25", "gpio26", "gpio27";
+- bias-disable;
+- };
+-
+- rp1_gpclksrc0_gpio4: rp1_gpclksrc0_gpio4 {
+- function = "gpclk0";
+- pins = "gpio4";
+- bias-disable;
+- };
+-
+- rp1_gpclksrc0_gpio20: rp1_gpclksrc0_gpio20 {
+- function = "gpclk0";
+- pins = "gpio20";
+- bias-disable;
+- };
+-
+- rp1_gpclksrc1_gpio5: rp1_gpclksrc1_gpio5 {
+- function = "gpclk1";
+- pins = "gpio5";
+- bias-disable;
+- };
+-
+- rp1_gpclksrc1_gpio18: rp1_gpclksrc1_gpio18 {
+- function = "gpclk1";
+- pins = "gpio18";
+- bias-disable;
+- };
+-
+- rp1_gpclksrc1_gpio21: rp1_gpclksrc1_gpio21 {
+- function = "gpclk1";
+- pins = "gpio21";
+- bias-disable;
+- };
+-
+- rp1_pwm1_gpio45: rp1_pwm1_gpio45 {
+- function = "pwm1";
+- pins = "gpio45";
+- bias-pull-down;
+- };
+-
+- rp1_spi0_gpio9: rp1_spi0_gpio9 {
+- function = "spi0";
+- pins = "gpio9", "gpio10", "gpio11";
+- bias-disable;
+- drive-strength = <12>;
+- slew-rate = <1>;
+- };
+-
+- rp1_spi0_cs_gpio7: rp1_spi0_cs_gpio7 {
+- function = "spi0";
+- pins = "gpio7", "gpio8";
+- bias-pull-up;
+- };
+-
+- rp1_spi1_gpio19: rp1_spi1_gpio19 {
+- function = "spi1";
+- pins = "gpio19", "gpio20", "gpio21";
+- bias-disable;
+- drive-strength = <12>;
+- slew-rate = <1>;
+- };
+-
+- rp1_spi2_gpio1: rp1_spi2_gpio1 {
+- function = "spi2";
+- pins = "gpio1", "gpio2", "gpio3";
+- bias-disable;
+- drive-strength = <12>;
+- slew-rate = <1>;
+- };
+-
+- rp1_spi3_gpio5: rp1_spi3_gpio5 {
+- function = "spi3";
+- pins = "gpio5", "gpio6", "gpio7";
+- bias-disable;
+- drive-strength = <12>;
+- slew-rate = <1>;
+- };
+-
+- rp1_spi4_gpio9: rp1_spi4_gpio9 {
+- function = "spi4";
+- pins = "gpio9", "gpio10", "gpio11";
+- bias-disable;
+- drive-strength = <12>;
+- slew-rate = <1>;
+- };
+-
+- rp1_spi5_gpio13: rp1_spi5_gpio13 {
+- function = "spi5";
+- pins = "gpio13", "gpio14", "gpio15";
+- bias-disable;
+- drive-strength = <12>;
+- slew-rate = <1>;
+- };
+-
+- rp1_spi8_gpio49: rp1_spi8_gpio49 {
+- function = "spi8";
+- pins = "gpio49", "gpio50", "gpio51";
+- bias-disable;
+- drive-strength = <12>;
+- slew-rate = <1>;
+- };
+-
+- rp1_spi8_cs_gpio52: rp1_spi8_cs_gpio52 {
+- function = "spi0";
+- pins = "gpio52", "gpio53";
+- bias-pull-up;
+- };
+- };
+-
+- rp1_eth: ethernet@100000 {
+- reg = <0xc0 0x40100000 0x0 0x4000>;
+- compatible = "cdns,macb";
+- #address-cells = <1>;
+- #size-cells = <0>;
+- interrupts = <RP1_INT_ETH IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&macb_pclk &macb_hclk &rp1_clocks RP1_CLK_ETH_TSU>;
+- clock-names = "pclk", "hclk", "tsu_clk";
+- phy-mode = "rgmii-id";
+- cdns,aw2w-max-pipe = /bits/ 8 <8>;
+- cdns,ar2r-max-pipe = /bits/ 8 <8>;
+- cdns,use-aw2b-fill;
+- local-mac-address = [00 00 00 00 00 00];
+- status = "disabled";
+- };
+-
+- rp1_csi0: csi@110000 {
+- compatible = "raspberrypi,rp1-cfe";
+- reg = <0xc0 0x40110000 0x0 0x100>, // CSI2 DMA address
+- <0xc0 0x40114000 0x0 0x100>, // PHY/CSI Host address
+- <0xc0 0x40120000 0x0 0x100>, // MIPI CFG address
+- <0xc0 0x40124000 0x0 0x1000>; // PiSP FE address
+-
+- // interrupts must match rp1_pisp_fe setup
+- interrupts = <RP1_INT_MIPI0 IRQ_TYPE_LEVEL_HIGH>;
+-
+- clocks = <&rp1_clocks RP1_CLK_MIPI0_CFG>;
+- assigned-clocks = <&rp1_clocks RP1_CLK_MIPI0_CFG>;
+- assigned-clock-rates = <25000000>;
+-
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- rp1_csi1: csi@128000 {
+- compatible = "raspberrypi,rp1-cfe";
+- reg = <0xc0 0x40128000 0x0 0x100>, // CSI2 DMA address
+- <0xc0 0x4012c000 0x0 0x100>, // PHY/CSI Host address
+- <0xc0 0x40138000 0x0 0x100>, // MIPI CFG address
+- <0xc0 0x4013c000 0x0 0x1000>; // PiSP FE address
+-
+- // interrupts must match rp1_pisp_fe setup
+- interrupts = <RP1_INT_MIPI1 IRQ_TYPE_LEVEL_HIGH>;
+-
+- clocks = <&rp1_clocks RP1_CLK_MIPI1_CFG>;
+- assigned-clocks = <&rp1_clocks RP1_CLK_MIPI1_CFG>;
+- assigned-clock-rates = <25000000>;
+-
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- rp1_mmc0: mmc@180000 {
+- reg = <0xc0 0x40180000 0x0 0x100>;
+- compatible = "raspberrypi,rp1-dwcmshc";
+- interrupts = <RP1_INT_SDIO0 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&rp1_clocks RP1_CLK_SYS &sdhci_core
+- &rp1_clocks RP1_CLK_SDIO_TIMER
+- &rp1_sdio_clk0>;
+- clock-names = "bus", "core", "timeout", "sdio";
+- /* Bank 0 VDDIO is fixed */
+- no-1-8-v;
+- bus-width = <4>;
+- vmmc-supply = <&rp1_vdd_3v3>;
+- broken-cd;
+- status = "disabled";
+- };
+-
+- rp1_mmc1: mmc@184000 {
+- reg = <0xc0 0x40184000 0x0 0x100>;
+- compatible = "raspberrypi,rp1-dwcmshc";
+- interrupts = <RP1_INT_SDIO1 IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&rp1_clocks RP1_CLK_SYS &sdhci_core
+- &rp1_clocks RP1_CLK_SDIO_TIMER
+- &rp1_sdio_clk1>;
+- clock-names = "bus", "core", "timeout", "sdio";
+- bus-width = <4>;
+- vmmc-supply = <&rp1_vdd_3v3>;
+- /* Nerf SDR speeds */
+- sdhci-caps-mask = <0x3 0x0>;
+- broken-cd;
+- status = "disabled";
+- };
+-
+- rp1_dma: dma@188000 {
+- reg = <0xc0 0x40188000 0x0 0x1000>;
+- compatible = "snps,axi-dma-1.01a";
+- interrupts = <RP1_INT_DMA IRQ_TYPE_LEVEL_HIGH>;
+- clocks = <&sdhci_core &rp1_clocks RP1_CLK_SYS>;
+- clock-names = "core-clk", "cfgr-clk";
+-
+- #dma-cells = <1>;
+- dma-channels = <8>;
+- snps,dma-masters = <1>;
+- snps,dma-targets = <64>;
+- snps,data-width = <4>; // (8 << 4) == 128 bits
+- snps,block-size = <0x40000 0x40000 0x40000 0x40000 0x40000 0x40000 0x40000 0x40000>;
+- snps,priority = <0 1 2 3 4 5 6 7>;
+- snps,axi-max-burst-len = <8>;
+- status = "disabled";
+- };
+-
+- rp1_usb0: usb@200000 {
+- reg = <0xc0 0x40200000 0x0 0x100000>;
+- compatible = "snps,dwc3";
+- dr_mode = "host";
+- usb3-lpm-capable;
+- snps,axi-pipe-limit = /bits/ 8 <8>;
+- snps,dis_rxdet_inp3_quirk;
+- snps,parkmode-disable-ss-quirk;
+- snps,parkmode-disable-hs-quirk;
+- snps,parkmode-disable-fsls-quirk;
+- snps,tx-max-burst = /bits/ 8 <8>;
+- snps,tx-thr-num-pkt = /bits/ 8 <2>;
+- interrupts = <RP1_INT_USBHOST0_0 IRQ_TYPE_EDGE_RISING>;
+- status = "disabled";
+- };
+-
+- rp1_usb1: usb@300000 {
+- reg = <0xc0 0x40300000 0x0 0x100000>;
+- compatible = "snps,dwc3";
+- dr_mode = "host";
+- usb3-lpm-capable;
+- snps,axi-pipe-limit = /bits/ 8 <8>;
+- snps,dis_rxdet_inp3_quirk;
+- snps,parkmode-disable-ss-quirk;
+- snps,parkmode-disable-hs-quirk;
+- snps,parkmode-disable-fsls-quirk;
+- snps,tx-max-burst = /bits/ 8 <8>;
+- snps,tx-thr-num-pkt = /bits/ 8 <2>;
+- interrupts = <RP1_INT_USBHOST1_0 IRQ_TYPE_EDGE_RISING>;
+- status = "disabled";
+- };
+-
+- rp1_dsi0: dsi@110000 {
+- compatible = "raspberrypi,rp1dsi";
+- status = "disabled";
+- reg = <0xc0 0x40118000 0x0 0x1000>, // MIPI0 DSI DMA (ArgonDPI)
+- <0xc0 0x4011c000 0x0 0x1000>, // MIPI0 DSI Host (SNPS)
+- <0xc0 0x40120000 0x0 0x1000>; // MIPI0 CFG
+-
+- interrupts = <RP1_INT_MIPI0 IRQ_TYPE_LEVEL_HIGH>;
+-
+- clocks = <&rp1_clocks RP1_CLK_MIPI0_CFG>,
+- <&rp1_clocks RP1_CLK_MIPI0_DPI>,
+- <&rp1_clocks RP1_CLK_MIPI0_DSI_BYTECLOCK>,
+- <&clk_xosc>, // hardwired to DSI "refclk"
+- <&rp1_clocks RP1_PLL_SYS>; // alternate parent for divide
+- clock-names = "cfgclk", "dpiclk", "byteclk", "refclk", "pllsys";
+-
+- assigned-clocks = <&rp1_clocks RP1_CLK_MIPI0_CFG>;
+- assigned-clock-rates = <25000000>;
+- };
+-
+- rp1_dsi1: dsi@128000 {
+- compatible = "raspberrypi,rp1dsi";
+- status = "disabled";
+- reg = <0xc0 0x40130000 0x0 0x1000>, // MIPI1 DSI DMA (ArgonDPI)
+- <0xc0 0x40134000 0x0 0x1000>, // MIPI1 DSI Host (SNPS)
+- <0xc0 0x40138000 0x0 0x1000>; // MIPI1 CFG
+-
+- interrupts = <RP1_INT_MIPI1 IRQ_TYPE_LEVEL_HIGH>;
+-
+- clocks = <&rp1_clocks RP1_CLK_MIPI1_CFG>,
+- <&rp1_clocks RP1_CLK_MIPI1_DPI>,
+- <&rp1_clocks RP1_CLK_MIPI1_DSI_BYTECLOCK>,
+- <&clk_xosc>, // hardwired to DSI "refclk"
+- <&rp1_clocks RP1_PLL_SYS>; // alternate parent for divide
+- clock-names = "cfgclk", "dpiclk", "byteclk", "refclk", "pllsys";
+-
+- assigned-clocks = <&rp1_clocks RP1_CLK_MIPI1_CFG>;
+- assigned-clock-rates = <25000000>;
+- };
+-
+- /* VEC and DPI both need to control PLL_VIDEO and cannot work together; */
+- /* config.txt should enable one or other using dtparam=vec or an overlay. */
+- rp1_vec: vec@144000 {
+- compatible = "raspberrypi,rp1vec";
+- status = "disabled";
+- reg = <0xc0 0x40144000 0x0 0x1000>, // VIDEO_OUT_VEC
+- <0xc0 0x40140000 0x0 0x1000>; // VIDEO_OUT_CFG
+-
+- interrupts = <RP1_INT_VIDEO_OUT IRQ_TYPE_LEVEL_HIGH>;
+-
+- clocks = <&rp1_clocks RP1_CLK_VEC>;
+-
+- assigned-clocks = <&rp1_clocks RP1_PLL_VIDEO_CORE>,
+- <&rp1_clocks RP1_PLL_VIDEO_SEC>,
+- <&rp1_clocks RP1_CLK_VEC>;
+- assigned-clock-rates = <1188000000>,
+- <108000000>,
+- <108000000>;
+- assigned-clock-parents = <0>,
+- <&rp1_clocks RP1_PLL_VIDEO_CORE>,
+- <&rp1_clocks RP1_PLL_VIDEO_SEC>;
+- };
+-
+- rp1_dpi: dpi@148000 {
+- compatible = "raspberrypi,rp1dpi";
+- status = "disabled";
+- reg = <0xc0 0x40148000 0x0 0x1000>, // VIDEO_OUT DPI
+- <0xc0 0x40140000 0x0 0x1000>; // VIDEO_OUT_CFG
+-
+- interrupts = <RP1_INT_VIDEO_OUT IRQ_TYPE_LEVEL_HIGH>;
+-
+- clocks = <&rp1_clocks RP1_CLK_DPI>, // DPI pixel clock
+- <&rp1_clocks RP1_PLL_VIDEO>, // PLL primary divider, and
+- <&rp1_clocks RP1_PLL_VIDEO_CORE>; // VCO, which we also control
+- clock-names = "dpiclk", "plldiv", "pllcore";
+-
+- assigned-clocks = <&rp1_clocks RP1_CLK_DPI>;
+- assigned-clock-parents = <&rp1_clocks RP1_PLL_VIDEO>;
+- };
+- };
+-};
+-
+-&clocks {
+- clk_xosc: clk_xosc {
+- compatible = "fixed-clock";
+- #clock-cells = <0>;
+- clock-output-names = "xosc";
+- clock-frequency = <50000000>;
+- };
+- macb_pclk: macb_pclk {
+- compatible = "fixed-clock";
+- #clock-cells = <0>;
+- clock-output-names = "pclk";
+- clock-frequency = <200000000>;
+- };
+- macb_hclk: macb_hclk {
+- compatible = "fixed-clock";
+- #clock-cells = <0>;
+- clock-output-names = "hclk";
+- clock-frequency = <200000000>;
+- };
+- sdio_src: sdio_src {
+- // 400 MHz on FPGA. PLL sys VCO on asic
+- compatible = "fixed-clock";
+- #clock-cells = <0>;
+- clock-output-names = "src";
+- clock-frequency = <1000000000>;
+- };
+- sdhci_core: sdhci_core {
+- compatible = "fixed-clock";
+- #clock-cells = <0>;
+- clock-output-names = "core";
+- clock-frequency = <50000000>;
+- };
+- /* GPIO derived clock sources. Each GPIO with a GPCLK function
+- * can drive its output from the respective GPCLK
+- * generator, and provide a clock source to other internal
+- * dividers. Add dummy sources here so that they can be overridden
+- * with overlays.
+- */
+- clksrc_gp0: clksrc_gp0 {
+- status = "disabled";
+- compatible = "fixed-factor-clock";
+- #clock-cells = <0>;
+- clock-div = <1>;
+- clock-mult = <1>;
+- clocks = <&rp1_clocks RP1_CLK_GP0>;
+- clock-output-names = "clksrc_gp0";
+- };
+- clksrc_gp1: clksrc_gp1 {
+- status = "disabled";
+- compatible = "fixed-factor-clock";
+- #clock-cells = <0>;
+- clock-div = <1>;
+- clock-mult = <1>;
+- clocks = <&rp1_clocks RP1_CLK_GP1>;
+- clock-output-names = "clksrc_gp1";
+- };
+- clksrc_gp2: clksrc_gp2 {
+- status = "disabled";
+- compatible = "fixed-factor-clock";
+- clock-div = <1>;
+- clock-mult = <1>;
+- #clock-cells = <0>;
+- clocks = <&rp1_clocks RP1_CLK_GP2>;
+- clock-output-names = "clksrc_gp2";
+- };
+- clksrc_gp3: clksrc_gp3 {
+- status = "disabled";
+- compatible = "fixed-factor-clock";
+- clock-div = <1>;
+- clock-mult = <1>;
+- #clock-cells = <0>;
+- clocks = <&rp1_clocks RP1_CLK_GP3>;
+- clock-output-names = "clksrc_gp3";
+- };
+- clksrc_gp4: clksrc_gp4 {
+- status = "disabled";
+- compatible = "fixed-factor-clock";
+- #clock-cells = <0>;
+- clock-div = <1>;
+- clock-mult = <1>;
+- clocks = <&rp1_clocks RP1_CLK_GP4>;
+- clock-output-names = "clksrc_gp4";
+- };
+- clksrc_gp5: clksrc_gp5 {
+- status = "disabled";
+- compatible = "fixed-factor-clock";
+- #clock-cells = <0>;
+- clock-div = <1>;
+- clock-mult = <1>;
+- clocks = <&rp1_clocks RP1_CLK_GP5>;
+- clock-output-names = "clksrc_gp5";
+- };
+-};
+-
+-/ {
+- rp1_vdd_3v3: rp1_vdd_3v3 {
+- compatible = "regulator-fixed";
+- regulator-name = "vdd-3v3";
+- regulator-min-microvolt = <3300000>;
+- regulator-max-microvolt = <3300000>;
+- regulator-always-on;
+- };
+-};
+--- /dev/null
++++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi.dtsi
+@@ -0,0 +1,351 @@
++// SPDX-License-Identifier: GPL-2.0
++
++#include <dt-bindings/power/raspberrypi-power.h>
++
++&soc {
++ firmware: firmware {
++ compatible = "raspberrypi,bcm2835-firmware", "simple-mfd";
++ #address-cells = <1>;
++ #size-cells = <1>;
++
++ mboxes = <&mailbox>;
++ dma-ranges;
++
++ firmware_clocks: clocks {
++ compatible = "raspberrypi,firmware-clocks";
++ #clock-cells = <1>;
++ };
++
++ reset: reset {
++ compatible = "raspberrypi,firmware-reset";
++ #reset-cells = <1>;
++ };
++
++ vcio: vcio {
++ compatible = "raspberrypi,vcio";
++ };
++ };
++
++ power: power {
++ compatible = "raspberrypi,bcm2835-power";
++ firmware = <&firmware>;
++ #power-domain-cells = <1>;
++ };
++
++ fb: fb {
++ compatible = "brcm,bcm2708-fb";
++ firmware = <&firmware>;
++ status = "okay";
++ };
++
++ rpi_rtc: rpi_rtc {
++ compatible = "raspberrypi,rpi-rtc";
++ firmware = <&firmware>;
++ status = "okay";
++ trickle-charge-microvolt = <0>;
++ };
++
++ nvmem {
++ compatible = "simple-bus";
++ #address-cells = <1>;
++ #size-cells = <1>;
++
++ nvmem_otp: nvmem_otp {
++ compatible = "raspberrypi,rpi-otp";
++ firmware = <&firmware>;
++ reg = <0 192>;
++ status = "okay";
++ };
++
++ nvmem_cust: nvmem_cust {
++ compatible = "raspberrypi,rpi-otp";
++ firmware = <&firmware>;
++ reg = <1 8>;
++ status = "okay";
++ };
++
++ nvmem_mac: nvmem_mac {
++ compatible = "raspberrypi,rpi-otp";
++ firmware = <&firmware>;
++ reg = <2 6>;
++ status = "okay";
++ };
++
++ nvmem_priv: nvmem_priv {
++ compatible = "raspberrypi,rpi-otp";
++ firmware = <&firmware>;
++ reg = <3 16>;
++ status = "okay";
++ };
++ };
++
++ /* Define these notional regulators for use by overlays, etc. */
++ vdd_3v3_reg: fixedregulator_3v3 {
++ compatible = "regulator-fixed";
++ regulator-always-on;
++ regulator-max-microvolt = <3300000>;
++ regulator-min-microvolt = <3300000>;
++ regulator-name = "3v3";
++ };
++
++ vdd_5v0_reg: fixedregulator_5v0 {
++ compatible = "regulator-fixed";
++ regulator-always-on;
++ regulator-max-microvolt = <5000000>;
++ regulator-min-microvolt = <5000000>;
++ regulator-name = "5v0";
++ };
++};
++
++/ {
++ __overrides__ {
++ arm_freq;
++ axiperf = <&axiperf>,"status";
++
++ nvmem_cust_rw = <&nvmem_cust>,"rw?";
++ nvmem_priv_rw = <&nvmem_priv>,"rw?";
++ nvmem_mac_rw = <&nvmem_mac>,"rw?";
++ strict_gpiod = <&chosen>, "bootargs=pinctrl_rp1.persist_gpio_outputs=n";
++
++ cam0_reg = <&cam0_reg>,"status";
++ cam0_reg_gpio = <&cam0_reg>,"gpio:4",
++ <&cam0_reg>,"gpio:0=", <&gpio>;
++ cam1_reg = <&cam1_reg>,"status";
++ cam1_reg_gpio = <&cam1_reg>,"gpio:4",
++ <&cam1_reg>,"gpio:0=", <&gpio>;
++
++ };
++};
++
++pciex1: &pcie1 { };
++pciex4: &pcie2 { };
++
++&dma32 {
++ /* The VPU firmware uses DMA channel 11 for VCHIQ */
++ brcm,dma-channel-mask = <0x03f>;
++};
++
++&dma40 {
++ /* The VPU firmware DMA channel 11 for VCHIQ */
++ brcm,dma-channel-mask = <0x07c0>;
++};
++
++&hdmi0 {
++ dmas = <&dma40 (10|(1<<30)|(1<<24)|(10<<16)|(15<<20))>;
++};
++
++&hdmi1 {
++ dmas = <&dma40 (17|(1<<30)|(1<<24)|(10<<16)|(15<<20))>;
++};
++
++&spi10 {
++ dmas = <&dma40 6>, <&dma40 7>;
++ dma-names = "tx", "rx";
++};
++
++&usb {
++ power-domains = <&power RPI_POWER_DOMAIN_USB>;
++};
++
++&rmem {
++ /*
++ * RPi5's co-processor will copy the board's bootloader configuration
++ * into memory for the OS to consume. It'll also update this node with
++ * its placement information.
++ */
++ blconfig: nvram@0 {
++ compatible = "raspberrypi,bootloader-config", "nvmem-rmem";
++ #address-cells = <1>;
++ #size-cells = <1>;
++ reg = <0x0 0x0 0x0>;
++ no-map;
++ status = "disabled";
++ };
++ /*
++ * RPi5 will copy the binary public key blob (if present) from the bootloader
++ * into memory for use by the OS.
++ */
++ blpubkey: nvram@1 {
++ compatible = "raspberrypi,bootloader-public-key", "nvmem-rmem";
++ #address-cells = <1>;
++ #size-cells = <1>;
++ reg = <0x0 0x0 0x0>;
++ no-map;
++ status = "disabled";
++ };
++};
++
++&rp1_adc {
++ status = "okay";
++};
++
++/* Add some gpiomem nodes to make the devices accessible to userspace.
++ * /dev/gpiomem<n> should expose the registers for the interface with DT alias
++ * gpio<n>.
++ */
++
++&rp1 {
++ gpiomem@d0000 {
++ /* Export IO_BANKs, RIO_BANKs and PADS_BANKs to userspace */
++ compatible = "raspberrypi,gpiomem";
++ reg = <0xc0 0x400d0000 0x0 0x30000>;
++ chardev-name = "gpiomem0";
++ };
++};
++
++&soc {
++ gpiomem@7d508500 {
++ compatible = "raspberrypi,gpiomem";
++ reg = <0x7d508500 0x40>;
++ chardev-name = "gpiomem1";
++ };
++
++ gpiomem@7d517c00 {
++ compatible = "raspberrypi,gpiomem";
++ reg = <0x7d517c00 0x40>;
++ chardev-name = "gpiomem2";
++ };
++
++ gpiomem@7d504100 {
++ compatible = "raspberrypi,gpiomem";
++ reg = <0x7d504100 0x20>;
++ chardev-name = "gpiomem3";
++ };
++
++ gpiomem@7d510700 {
++ compatible = "raspberrypi,gpiomem";
++ reg = <0x7d510700 0x20>;
++ chardev-name = "gpiomem4";
++ };
++
++ sound: sound {
++ status = "disabled";
++ };
++};
++
++i2c0: &rp1_i2c0 { };
++i2c1: &rp1_i2c1 { };
++i2c2: &rp1_i2c2 { };
++i2c3: &rp1_i2c3 { };
++i2c4: &rp1_i2c4 { };
++i2c5: &rp1_i2c5 { };
++i2c6: &rp1_i2c6 { };
++i2s: &rp1_i2s0 { };
++i2s_clk_producer: &rp1_i2s0 { };
++i2s_clk_consumer: &rp1_i2s1 { };
++pwm0: &rp1_pwm0 { };
++pwm1: &rp1_pwm1 { };
++pwm: &pwm0 { };
++spi0: &rp1_spi0 { };
++spi1: &rp1_spi1 { };
++spi2: &rp1_spi2 { };
++spi3: &rp1_spi3 { };
++spi4: &rp1_spi4 { };
++spi5: &rp1_spi5 { };
++
++uart0_pins: &rp1_uart0_14_15 {};
++uart0_ctsrts_pins: &rp1_uart0_ctsrts_16_17 {};
++uart0: &rp1_uart0 {
++ pinctrl-0 = <&uart0_pins>;
++};
++
++uart1_pins: &rp1_uart1_0_1 {};
++uart1_ctsrts_pins: &rp1_uart1_ctsrts_2_3 {};
++uart1: &rp1_uart1 { };
++
++uart2_pins: &rp1_uart2_4_5 {};
++uart2_ctsrts_pins: &rp1_uart2_ctsrts_6_7 {};
++uart2: &rp1_uart2 { };
++
++uart3_pins: &rp1_uart3_8_9 {};
++uart3_ctsrts_pins: &rp1_uart3_ctsrts_10_11 {};
++uart3: &rp1_uart3 { };
++
++uart4_pins: &rp1_uart4_12_13 {};
++uart4_ctsrts_pins: &rp1_uart4_ctsrts_14_15 {};
++uart4: &rp1_uart4 { };
++
++i2c0_pins: &rp1_i2c0_0_1 {};
++i2c_vc: &i2c0 { // This is pins 27,28 on the header (not MIPI)
++ pinctrl-0 = <&i2c0_pins>;
++ pinctrl-names = "default";
++ clock-frequency = <100000>;
++};
++
++i2c1_pins: &rp1_i2c1_2_3 {};
++i2c_arm: &i2c1 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2c1_pins>;
++ clock-frequency = <100000>;
++};
++
++i2c2_pins: &rp1_i2c2_4_5 {};
++&i2c2 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2c2_pins>;
++};
++
++i2c3_pins: &rp1_i2c3_6_7 {};
++&i2c3 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2c3_pins>;
++};
++
++&i2s_clk_producer {
++ pinctrl-names = "default";
++ pinctrl-0 = <&rp1_i2s0_18_21>;
++};
++
++&i2s_clk_consumer {
++ pinctrl-names = "default";
++ pinctrl-0 = <&rp1_i2s1_18_21>;
++};
++
++spi0_pins: &rp1_spi0_gpio9 {};
++spi0_cs_pins: &rp1_spi0_cs_gpio7 {};
++
++&spi0 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&spi0_pins &spi0_cs_pins>;
++ cs-gpios = <&gpio 8 1>, <&gpio 7 1>;
++
++ spidev0: spidev@0 {
++ compatible = "spidev";
++ reg = <0>; /* CE0 */
++ #address-cells = <1>;
++ #size-cells = <0>;
++ spi-max-frequency = <125000000>;
++ };
++
++ spidev1: spidev@1 {
++ compatible = "spidev";
++ reg = <1>; /* CE1 */
++ #address-cells = <1>;
++ #size-cells = <0>;
++ spi-max-frequency = <125000000>;
++ };
++};
++
++spi2_pins: &rp1_spi2_gpio1 {};
++&spi2 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&spi2_pins>;
++};
++
++spi3_pins: &rp1_spi3_gpio5 {};
++&spi3 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&spi3_pins>;
++};
++
++spi4_pins: &rp1_spi4_gpio9 {};
++&spi4 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&spi4_pins>;
++};
++
++spi5_pins: &rp1_spi5_gpio13 {};
++&spi5 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&spi5_pins>;
++};
+--- /dev/null
++++ b/arch/arm64/boot/dts/broadcom/bcm2712.dtsi
+@@ -0,0 +1,1302 @@
++// SPDX-License-Identifier: GPL-2.0
++#include <dt-bindings/interrupt-controller/arm-gic.h>
++#include <dt-bindings/soc/bcm2835-pm.h>
++#include <dt-bindings/phy/phy.h>
++
++/ {
++ compatible = "brcm,bcm2712", "brcm,bcm2711";
++ model = "BCM2712";
++
++ #address-cells = <2>;
++ #size-cells = <1>;
++
++ interrupt-parent = <&gicv2>;
++
++ rmem: reserved-memory {
++ #address-cells = <2>;
++ #size-cells = <1>;
++ ranges;
++
++ atf@0 {
++ reg = <0x0 0x0 0x80000>;
++ no-map;
++ };
++
++ cma: linux,cma {
++ compatible = "shared-dma-pool";
++ size = <0x4000000>; /* 64MB */
++ reusable;
++ linux,cma-default;
++
++ /*
++ * arm64 reserves the CMA by default somewhere in
++ * ZONE_DMA32, that's not good enough for the BCM2711
++ * as some devices can only address the lower 1G of
++ * memory (ZONE_DMA).
++ */
++ alloc-ranges = <0x0 0x00000000 0x40000000>;
++ };
++ };
++
++ thermal-zones {
++ cpu_thermal: cpu-thermal {
++ polling-delay-passive = <2000>;
++ polling-delay = <1000>;
++ coefficients = <(-550) 450000>;
++ thermal-sensors = <&thermal>;
++
++ thermal_trips: trips {
++ cpu_crit: cpu-crit {
++ temperature = <110000>;
++ hysteresis = <0>;
++ type = "critical";
++ };
++ };
++
++ cooling_maps: cooling-maps {
++ };
++ };
++ };
++
++ clk_27MHz: clk-27M {
++ #clock-cells = <0>;
++ compatible = "fixed-clock";
++ clock-frequency = <27000000>;
++ clock-output-names = "27MHz-clock";
++ };
++
++ clk_108MHz: clk-108M {
++ #clock-cells = <0>;
++ compatible = "fixed-clock";
++ clock-frequency = <108000000>;
++ clock-output-names = "108MHz-clock";
++ };
++
++ hvs: hvs@107c580000 {
++ compatible = "brcm,bcm2712-hvs";
++ reg = <0x10 0x7c580000 0x1a000>;
++ interrupt-parent = <&disp_intr>;
++ interrupts = <2>, <9>, <16>;
++ interrupt-names = "ch0-eof", "ch1-eof", "ch2-eof";
++ //iommus = <&iommu4>;
++ status = "disabled";
++ };
++
++ soc: soc {
++ compatible = "simple-bus";
++ #address-cells = <1>;
++ #size-cells = <1>;
++
++ ranges = <0x7c000000 0x10 0x7c000000 0x04000000>;
++ /* Emulate a contiguous 30-bit address range for DMA */
++ dma-ranges = <0xc0000000 0x00 0x00000000 0x40000000>,
++ <0x7c000000 0x10 0x7c000000 0x04000000>;
++
++ system_timer: timer@7c003000 {
++ compatible = "brcm,bcm2835-system-timer";
++ reg = <0x7c003000 0x1000>;
++ interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
++ clock-frequency = <1000000>;
++ };
++
++ firmwarekms: firmwarekms@7d503000 {
++ compatible = "raspberrypi,rpi-firmware-kms-2712";
++ /* SUN_L2 interrupt reg */
++ reg = <0x7d503000 0x18>;
++ interrupt-parent = <&cpu_l2_irq>;
++ interrupts = <19>;
++ brcm,firmware = <&firmware>;
++ status = "disabled";
++ };
++
++ axiperf: axiperf {
++ compatible = "brcm,bcm2712-axiperf";
++ reg = <0x7c012800 0x100>,
++ <0x7e000000 0x100>;
++ firmware = <&firmware>;
++ status = "disabled";
++ };
++
++ mailbox: mailbox@7c013880 {
++ compatible = "brcm,bcm2835-mbox";
++ reg = <0x7c013880 0x40>;
++ interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
++ #mbox-cells = <0>;
++ };
++
++ pixelvalve0: pixelvalve@7c410000 {
++ compatible = "brcm,bcm2712-pixelvalve0";
++ reg = <0x7c410000 0x100>;
++ interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
++ status = "disabled";
++ };
++
++ pixelvalve1: pixelvalve@7c411000 {
++ compatible = "brcm,bcm2712-pixelvalve1";
++ reg = <0x7c411000 0x100>;
++ interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
++ status = "disabled";
++ };
++
++ mop: mop@7c500000 {
++ compatible = "brcm,bcm2712-mop";
++ reg = <0x7c500000 0x28>;
++ interrupt-parent = <&disp_intr>;
++ interrupts = <1>;
++ status = "disabled";
++ };
++
++ moplet: moplet@7c501000 {
++ compatible = "brcm,bcm2712-moplet";
++ reg = <0x7c501000 0x20>;
++ interrupt-parent = <&disp_intr>;
++ interrupts = <0>;
++ status = "disabled";
++ };
++
++ disp_intr: interrupt-controller@7c502000 {
++ compatible = "brcm,bcm2711-l2-intc", "brcm,l2-intc";
++ reg = <0x7c502000 0x30>;
++ interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
++ interrupt-controller;
++ #interrupt-cells = <1>;
++ status = "disabled";
++ };
++
++ dvp: clock@7c700000 {
++ compatible = "brcm,brcm2711-dvp";
++ reg = <0x7c700000 0x10>;
++ clocks = <&clk_108MHz>;
++ #clock-cells = <1>;
++ #reset-cells = <1>;
++ };
++
++ /*
++ * This node is the provider for the enable-method for
++ * bringing up secondary cores.
++ */
++ local_intc: local_intc@7cd00000 {
++ compatible = "brcm,bcm2836-l1-intc";
++ reg = <0x7cd00000 0x100>;
++ };
++
++ uart0: serial@7d001000 {
++ compatible = "arm,pl011", "arm,primecell";
++ reg = <0x7d001000 0x200>;
++ interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&clk_uart>,
++ <&clk_vpu>;
++ clock-names = "uartclk", "apb_pclk";
++ arm,primecell-periphid = <0x00241011>;
++ status = "disabled";
++ };
++
++ uart2: serial@7d001400 {
++ compatible = "arm,pl011", "arm,primecell";
++ reg = <0x7d001400 0x200>;
++ interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&clk_uart>,
++ <&clk_vpu>;
++ clock-names = "uartclk", "apb_pclk";
++ arm,primecell-periphid = <0x00241011>;
++ status = "disabled";
++ };
++
++ uart5: serial@7d001a00 {
++ compatible = "arm,pl011", "arm,primecell";
++ reg = <0x7d001a00 0x200>;
++ interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&clk_uart>,
++ <&clk_vpu>;
++ clock-names = "uartclk", "apb_pclk";
++ arm,primecell-periphid = <0x00241011>;
++ status = "disabled";
++ };
++
++ sdhost: mmc@7d002000 {
++ compatible = "brcm,bcm2835-sdhost";
++ reg = <0x7d002000 0x100>;
++ //interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&clk_vpu>;
++ status = "disabled";
++ };
++
++ i2s: i2s@7d003000 {
++ compatible = "brcm,bcm2835-i2s";
++ reg = <0x7d003000 0x24>;
++ //clocks = <&cprman BCM2835_CLOCK_PCM>;
++ status = "disabled";
++ };
++
++ spi0: spi@7d004000 {
++ compatible = "brcm,bcm2835-spi";
++ reg = <0x7d004000 0x200>;
++ interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&clk_vpu>;
++ num-cs = <1>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ spi3: spi@7d004600 {
++ compatible = "brcm,bcm2835-spi";
++ reg = <0x7d004600 0x0200>;
++ interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&clk_vpu>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ spi4: spi@7d004800 {
++ compatible = "brcm,bcm2835-spi";
++ reg = <0x7d004800 0x0200>;
++ interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&clk_vpu>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ spi5: spi@7d004a00 {
++ compatible = "brcm,bcm2835-spi";
++ reg = <0x7d004a00 0x0200>;
++ interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&clk_vpu>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ spi6: spi@7d004c00 {
++ compatible = "brcm,bcm2835-spi";
++ reg = <0x7d004c00 0x0200>;
++ interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&clk_vpu>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ i2c0: i2c@7d005000 {
++ compatible = "brcm,bcm2711-i2c", "brcm,bcm2835-i2c";
++ reg = <0x7d005000 0x20>;
++ interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&clk_vpu>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ i2c3: i2c@7d005600 {
++ compatible = "brcm,bcm2711-i2c", "brcm,bcm2835-i2c";
++ reg = <0x7d005600 0x20>;
++ interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&clk_vpu>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ i2c4: i2c@7d005800 {
++ compatible = "brcm,bcm2711-i2c", "brcm,bcm2835-i2c";
++ reg = <0x7d005800 0x20>;
++ interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&clk_vpu>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ i2c5: i2c@7d005a00 {
++ compatible = "brcm,bcm2711-i2c", "brcm,bcm2835-i2c";
++ reg = <0x7d005a00 0x20>;
++ interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&clk_vpu>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ i2c6: i2c@7d005c00 {
++ compatible = "brcm,bcm2711-i2c", "brcm,bcm2835-i2c";
++ reg = <0x7d005c00 0x20>;
++ interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&clk_vpu>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ i2c8: i2c@7d005e00 {
++ compatible = "brcm,bcm2711-i2c", "brcm,bcm2835-i2c";
++ reg = <0x7d005e00 0x20>;
++ interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&clk_vpu>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ pwm0: pwm@7d00c000 {
++ compatible = "brcm,bcm2835-pwm";
++ reg = <0x7d00c000 0x28>;
++ assigned-clock-rates = <50000000>;
++ #pwm-cells = <3>;
++ status = "disabled";
++ };
++
++ pwm1: pwm@7d00c800 {
++ compatible = "brcm,bcm2835-pwm";
++ reg = <0x7d00c800 0x28>;
++ assigned-clock-rates = <50000000>;
++ #pwm-cells = <3>;
++ status = "disabled";
++ };
++
++ pm: watchdog@7d200000 {
++ compatible = "brcm,bcm2712-pm";
++ reg = <0x7d200000 0x308>;
++ reg-names = "pm";
++ #power-domain-cells = <1>;
++ #reset-cells = <1>;
++ //clocks = <&cprman BCM2835_CLOCK_V3D>,
++ // <&cprman BCM2835_CLOCK_PERI_IMAGE>,
++ // <&cprman BCM2835_CLOCK_H264>,
++ // <&cprman BCM2835_CLOCK_ISP>;
++ clock-names = "v3d", "peri_image", "h264", "isp";
++ system-power-controller;
++ };
++
++ cprman: cprman@7d202000 {
++ compatible = "brcm,bcm2711-cprman";
++ reg = <0x7d202000 0x2000>;
++ #clock-cells = <1>;
++
++ /* CPRMAN derives almost everything from the
++ * platform's oscillator. However, the DSI
++ * pixel clocks come from the DSI analog PHY.
++ */
++ clocks = <&clk_osc>;
++ status = "disabled";
++ };
++
++ random: rng@7d208000 {
++ compatible = "brcm,bcm2711-rng200";
++ reg = <0x7d208000 0x28>;
++ status = "okay";
++ };
++
++ cpu_l2_irq: intc@7d503000 {
++ compatible = "brcm,l2-intc";
++ reg = <0x7d503000 0x18>;
++ interrupts = <GIC_SPI 238 IRQ_TYPE_LEVEL_HIGH>;
++ interrupt-controller;
++ #interrupt-cells = <1>;
++ };
++
++ pinctrl: pinctrl@7d504100 {
++ compatible = "brcm,bcm2712-pinctrl";
++ reg = <0x7d504100 0x30>;
++
++ uarta_24_pins: uarta_24_pins {
++ pin_rts {
++ function = "uart0";
++ pins = "gpio24";
++ bias-disable;
++ };
++ pin_cts {
++ function = "uart0";
++ pins = "gpio25";
++ bias-pull-up;
++ };
++ pin_txd {
++ function = "uart0";
++ pins = "gpio26";
++ bias-disable;
++ };
++ pin_rxd {
++ function = "uart0";
++ pins = "gpio27";
++ bias-pull-up;
++ };
++ };
++
++ sdio2_30_pins: sdio2_30_pins {
++ pin_clk {
++ function = "sd2";
++ pins = "gpio30";
++ bias-disable;
++ };
++ pin_cmd {
++ function = "sd2";
++ pins = "gpio31";
++ bias-pull-up;
++ };
++ pins_dat {
++ function = "sd2";
++ pins = "gpio32", "gpio33", "gpio34", "gpio35";
++ bias-pull-up;
++ };
++ };
++ };
++
++ ddc0: i2c@7d508200 {
++ compatible = "brcm,brcmstb-i2c";
++ reg = <0x7d508200 0x58>;
++ interrupt-parent = <&bsc_irq>;
++ interrupts = <1>;
++ clock-frequency = <97500>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ ddc1: i2c@7d508280 {
++ compatible = "brcm,brcmstb-i2c";
++ reg = <0x7d508280 0x58>;
++ interrupt-parent = <&bsc_irq>;
++ interrupts = <2>;
++ clock-frequency = <97500>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ bscd: i2c@7d508300 {
++ compatible = "brcm,brcmstb-i2c";
++ reg = <0x7d508300 0x58>;
++ interrupt-parent = <&bsc_irq>;
++ interrupts = <0>;
++ clock-frequency = <200000>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ bsc_irq: intc@7d508380 {
++ compatible = "brcm,bcm7271-l2-intc";
++ reg = <0x7d508380 0x10>;
++ interrupts = <GIC_SPI 242 IRQ_TYPE_LEVEL_HIGH>;
++ interrupt-controller;
++ #interrupt-cells = <1>;
++ };
++
++ main_irq: intc@7d508400 {
++ compatible = "brcm,bcm7271-l2-intc";
++ reg = <0x7d508400 0x10>;
++ interrupts = <GIC_SPI 244 IRQ_TYPE_LEVEL_HIGH>;
++ interrupt-controller;
++ #interrupt-cells = <1>;
++ };
++
++ gio: gpio@7d508500 {
++ compatible = "brcm,brcmstb-gpio";
++ reg = <0x7d508500 0x40>;
++ interrupt-parent = <&main_irq>;
++ interrupts = <0>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ interrupt-controller;
++ #interrupt-cells = <2>;
++ brcm,gpio-bank-widths = <32 22>;
++ brcm,gpio-direct;
++ };
++
++ uarta: serial@7d50c000 {
++ compatible = "brcm,bcm7271-uart";
++ reg = <0x7d50c000 0x20>;
++ reg-names = "uart";
++ reg-shift = <2>;
++ reg-io-width = <4>;
++ interrupts = <GIC_SPI 276 IRQ_TYPE_LEVEL_HIGH>;
++ skip-init;
++ status = "disabled";
++ };
++
++ uartb: serial@7d50d000 {
++ compatible = "brcm,bcm7271-uart";
++ reg = <0x7d50d000 0x20>;
++ reg-names = "uart";
++ reg-shift = <2>;
++ reg-io-width = <4>;
++ interrupts = <GIC_SPI 277 IRQ_TYPE_LEVEL_HIGH>;
++ skip-init;
++ status = "disabled";
++ };
++
++ aon_intr: interrupt-controller@7d510600 {
++ compatible = "brcm,bcm2711-l2-intc", "brcm,l2-intc";
++ reg = <0x7d510600 0x30>;
++ interrupts = <GIC_SPI 239 IRQ_TYPE_LEVEL_HIGH>;
++ interrupt-controller;
++ #interrupt-cells = <1>;
++ status = "disabled";
++ };
++
++ pinctrl_aon: pinctrl@7d510700 {
++ compatible = "brcm,bcm2712-aon-pinctrl";
++ reg = <0x7d510700 0x20>;
++
++ i2c3_m4_agpio0_pins: i2c3_m4_agpio0_pins {
++ function = "vc_i2c3";
++ pins = "aon_gpio0", "aon_gpio1";
++ bias-pull-up;
++ };
++
++ bsc_m1_agpio13_pins: bsc_m1_agpio13_pins {
++ function = "bsc_m1";
++ pins = "aon_gpio13", "aon_gpio14";
++ bias-pull-up;
++ };
++
++ bsc_pmu_sgpio4_pins: bsc_pmu_sgpio4_pins {
++ function = "avs_pmu_bsc";
++ pins = "aon_sgpio4", "aon_sgpio5";
++ };
++
++ bsc_m2_sgpio4_pins: bsc_m2_sgpio4_pins {
++ function = "bsc_m2";
++ pins = "aon_sgpio4", "aon_sgpio5";
++ };
++
++ pwm_aon_agpio1_pins: pwm_aon_agpio1_pins {
++ function = "aon_pwm";
++ pins = "aon_gpio1", "aon_gpio2";
++ };
++
++ pwm_aon_agpio4_pins: pwm_aon_agpio4_pins {
++ function = "vc_pwm0";
++ pins = "aon_gpio4", "aon_gpio5";
++ };
++
++ pwm_aon_agpio7_pins: pwm_aon_agpio7_pins {
++ function = "aon_pwm";
++ pins = "aon_gpio7", "aon_gpio9";
++ };
++ };
++
++ intc@7d517000 {
++ compatible = "brcm,bcm7271-l2-intc";
++ reg = <0x7d517000 0x10>;
++ interrupts = <GIC_SPI 247 IRQ_TYPE_LEVEL_HIGH>;
++ interrupt-controller;
++ #interrupt-cells = <1>;
++ status = "disabled";
++ };
++
++ bscc: i2c@7d517a00 {
++ compatible = "brcm,brcmstb-i2c";
++ reg = <0x7d517a00 0x58>;
++ interrupt-parent = <&bsc_aon_irq>;
++ interrupts = <0>;
++ clock-frequency = <200000>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ pwm_aon: pwm@7d517a80 {
++ compatible = "brcm,bcm7038-pwm";
++ reg = <0x7d517a80 0x28>;
++ #pwm-cells = <3>;
++ clocks = <&clk_27MHz>;
++ };
++
++ main_aon_irq: intc@7d517ac0 {
++ compatible = "brcm,bcm7271-l2-intc";
++ reg = <0x7d517ac0 0x10>;
++ interrupts = <GIC_SPI 245 IRQ_TYPE_LEVEL_HIGH>;
++ interrupt-controller;
++ #interrupt-cells = <1>;
++ };
++
++ bsc_aon_irq: intc@7d517b00 {
++ compatible = "brcm,bcm7271-l2-intc";
++ reg = <0x7d517b00 0x10>;
++ interrupts = <GIC_SPI 243 IRQ_TYPE_LEVEL_HIGH>;
++ interrupt-controller;
++ #interrupt-cells = <1>;
++ };
++
++ gio_aon: gpio@7d517c00 {
++ compatible = "brcm,brcmstb-gpio";
++ reg = <0x7d517c00 0x40>;
++ interrupt-parent = <&main_aon_irq>;
++ interrupts = <0>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ interrupt-controller;
++ #interrupt-cells = <2>;
++ brcm,gpio-bank-widths = <17 6>;
++ brcm,gpio-direct;
++ };
++
++ avs_monitor: avs-monitor@7d542000 {
++ compatible = "brcm,bcm2711-avs-monitor",
++ "syscon", "simple-mfd";
++ reg = <0x7d542000 0xf00>;
++ status = "okay";
++
++ thermal: thermal {
++ compatible = "brcm,bcm2711-thermal";
++ #thermal-sensor-cells = <0>;
++ };
++ };
++
++ bsc_pmu: i2c@7d544000 {
++ compatible = "brcm,brcmstb-i2c";
++ reg = <0x7d544000 0x58>;
++ interrupt-parent = <&bsc_aon_irq>;
++ interrupts = <1>;
++ clock-frequency = <200000>;
++ status = "disabled";
++ };
++
++ hdmi0: hdmi@7ef00700 {
++ compatible = "brcm,bcm2712-hdmi0";
++ reg = <0x7c701400 0x300>,
++ <0x7c701000 0x200>,
++ <0x7c701d00 0x300>,
++ <0x7c702000 0x80>,
++ <0x7c703800 0x200>,
++ <0x7c704000 0x800>,
++ <0x7c700100 0x80>,
++ <0x7d510800 0x100>,
++ <0x7c720000 0x100>;
++ reg-names = "hdmi",
++ "dvp",
++ "phy",
++ "rm",
++ "packet",
++ "metadata",
++ "csc",
++ "cec",
++ "hd";
++ resets = <&dvp 1>;
++ interrupt-parent = <&aon_intr>;
++ interrupts = <1>, <2>, <3>,
++ <7>, <8>;
++ interrupt-names = "cec-tx", "cec-rx", "cec-low",
++ "hpd-connected", "hpd-removed";
++ ddc = <&ddc0>;
++ dmas = <&dma32 10>;
++ dma-names = "audio-rx";
++ status = "disabled";
++ };
++
++ hdmi1: hdmi@7ef05700 {
++ compatible = "brcm,bcm2712-hdmi1";
++ reg = <0x7c706400 0x300>,
++ <0x7c706000 0x200>,
++ <0x7c706d00 0x300>,
++ <0x7c707000 0x80>,
++ <0x7c708800 0x200>,
++ <0x7c709000 0x800>,
++ <0x7c700180 0x80>,
++ <0x7d511000 0x100>,
++ <0x7c720000 0x100>;
++ reg-names = "hdmi",
++ "dvp",
++ "phy",
++ "rm",
++ "packet",
++ "metadata",
++ "csc",
++ "cec",
++ "hd";
++ ddc = <&ddc1>;
++ resets = <&dvp 2>;
++ interrupt-parent = <&aon_intr>;
++ interrupts = <11>, <12>, <13>,
++ <14>, <15>;
++ interrupt-names = "cec-tx", "cec-rx", "cec-low",
++ "hpd-connected", "hpd-removed";
++ dmas = <&dma32 17>;
++ dma-names = "audio-rx";
++ status = "disabled";
++ };
++ };
++
++ arm-pmu {
++ compatible = "arm,cortex-a76-pmu";
++ interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
++ interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>;
++ };
++
++ timer {
++ compatible = "arm,armv8-timer";
++ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) |
++ IRQ_TYPE_LEVEL_LOW)>,
++ <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) |
++ IRQ_TYPE_LEVEL_LOW)>,
++ <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) |
++ IRQ_TYPE_LEVEL_LOW)>,
++ <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) |
++ IRQ_TYPE_LEVEL_LOW)>;
++ /* This only applies to the ARMv7 stub */
++ arm,cpu-registers-not-fw-configured;
++ };
++
++ cpus: cpus {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ enable-method = "brcm,bcm2836-smp"; // for ARM 32-bit
++
++ /* Source for d/i cache-line-size, cache-sets, cache-size
++ * https://developer.arm.com/documentation/100798/0401
++ * /L1-memory-system/About-the-L1-memory-system?lang=en
++ */
++ cpu0: cpu@0 {
++ device_type = "cpu";
++ compatible = "arm,cortex-a76";
++ reg = <0x000>;
++ enable-method = "psci";
++ d-cache-size = <0x10000>;
++ d-cache-line-size = <64>;
++ d-cache-sets = <256>; // 64KiB(size)/64(line-size)=1024ways/4-way set
++ i-cache-size = <0x10000>;
++ i-cache-line-size = <64>;
++ i-cache-sets = <256>; // 64KiB(size)/64(line-size)=1024ways/4-way set
++ next-level-cache = <&l2_cache_l0>;
++ };
++
++ cpu1: cpu@1 {
++ device_type = "cpu";
++ compatible = "arm,cortex-a76";
++ reg = <0x100>;
++ enable-method = "psci";
++ d-cache-size = <0x10000>;
++ d-cache-line-size = <64>;
++ d-cache-sets = <256>; // 64KiB(size)/64(line-size)=1024ways/4-way set
++ i-cache-size = <0x10000>;
++ i-cache-line-size = <64>;
++ i-cache-sets = <256>; // 64KiB(size)/64(line-size)=1024ways/4-way set
++ next-level-cache = <&l2_cache_l1>;
++ };
++
++ cpu2: cpu@2 {
++ device_type = "cpu";
++ compatible = "arm,cortex-a76";
++ reg = <0x200>;
++ enable-method = "psci";
++ d-cache-size = <0x10000>;
++ d-cache-line-size = <64>;
++ d-cache-sets = <256>; // 64KiB(size)/64(line-size)=1024ways/4-way set
++ i-cache-size = <0x10000>;
++ i-cache-line-size = <64>;
++ i-cache-sets = <256>; // 64KiB(size)/64(line-size)=1024ways/4-way set
++ next-level-cache = <&l2_cache_l2>;
++ };
++
++ cpu3: cpu@3 {
++ device_type = "cpu";
++ compatible = "arm,cortex-a76";
++ reg = <0x300>;
++ enable-method = "psci";
++ d-cache-size = <0x10000>;
++ d-cache-line-size = <64>;
++ d-cache-sets = <256>; // 64KiB(size)/64(line-size)=1024ways/4-way set
++ i-cache-size = <0x10000>;
++ i-cache-line-size = <64>;
++ i-cache-sets = <256>; // 64KiB(size)/64(line-size)=1024ways/4-way set
++ next-level-cache = <&l2_cache_l3>;
++ };
++
++ /* Source for cache-line-size and cache-sets:
++ * https://developer.arm.com/documentation/100798/0401
++ * /L2-memory-system/About-the-L2-memory-system?lang=en
++ * and for cache-size:
++ * https://www.raspberrypi.com/documentation/computers
++ * /processors.html#bcm2712
++ */
++ l2_cache_l0: l2-cache-l0 {
++ compatible = "cache";
++ cache-size = <0x80000>;
++ cache-line-size = <128>;
++ cache-sets = <1024>; // 512KiB(size)/64(line-size)=8192ways/8-way set
++ cache-level = <2>;
++ cache-unified;
++ next-level-cache = <&l3_cache>;
++ };
++
++ l2_cache_l1: l2-cache-l1 {
++ compatible = "cache";
++ cache-size = <0x80000>;
++ cache-line-size = <128>;
++ cache-sets = <1024>; // 512KiB(size)/64(line-size)=8192ways/8-way set
++ cache-level = <2>;
++ cache-unified;
++ next-level-cache = <&l3_cache>;
++ };
++
++ l2_cache_l2: l2-cache-l2 {
++ compatible = "cache";
++ cache-size = <0x80000>;
++ cache-line-size = <128>;
++ cache-sets = <1024>; // 512KiB(size)/64(line-size)=8192ways/8-way set
++ cache-level = <2>;
++ cache-unified;
++ next-level-cache = <&l3_cache>;
++ };
++
++ l2_cache_l3: l2-cache-l3 {
++ compatible = "cache";
++ cache-size = <0x80000>;
++ cache-line-size = <128>;
++ cache-sets = <1024>; // 512KiB(size)/64(line-size)=8192ways/8-way set
++ cache-level = <2>;
++ cache-unified;
++ next-level-cache = <&l3_cache>;
++ };
++
++ /* Source for cache-line-size and cache-sets:
++ * https://developer.arm.com/documentation/100453/0401/L3-cache?lang=en
++ * Source for cache-size:
++ * https://www.raspberrypi.com/documentation/computers/processors.html#bcm2712
++ */
++ l3_cache: l3-cache {
++ compatible = "cache";
++ cache-size = <0x200000>;
++ cache-line-size = <64>;
++ cache-sets = <2048>; // 2MiB(size)/64(line-size)=32768ways/16-way set
++ cache-level = <3>;
++ };
++ };
++
++ psci {
++ method = "smc";
++ compatible = "arm,psci-1.0", "arm,psci-0.2", "arm,psci";
++ cpu_on = <0xc4000003>;
++ cpu_suspend = <0xc4000001>;
++ cpu_off = <0x84000002>;
++ };
++
++ axi: axi {
++ compatible = "simple-bus";
++ #address-cells = <2>;
++ #size-cells = <2>;
++
++ ranges = <0x00 0x00000000 0x00 0x00000000 0x10 0x00000000>,
++ <0x10 0x00000000 0x10 0x00000000 0x01 0x00000000>,
++ <0x14 0x00000000 0x14 0x00000000 0x04 0x00000000>,
++ <0x18 0x00000000 0x18 0x00000000 0x04 0x00000000>,
++ <0x1c 0x00000000 0x1c 0x00000000 0x04 0x00000000>;
++
++ dma-ranges = <0x00 0x00000000 0x00 0x00000000 0x10 0x00000000>,
++ <0x10 0x00000000 0x10 0x00000000 0x01 0x00000000>,
++ <0x14 0x00000000 0x14 0x00000000 0x04 0x00000000>,
++ <0x18 0x00000000 0x18 0x00000000 0x04 0x00000000>,
++ <0x1c 0x00000000 0x1c 0x00000000 0x04 0x00000000>;
++
++ vc4: gpu {
++ compatible = "brcm,bcm2712-vc6";
++ };
++
++ iommu2: iommu@5100 {
++ /* IOMMU2 for PISP-BE, HEVC; and (unused) H264 accelerators */
++ compatible = "brcm,bcm2712-iommu";
++ reg = <0x10 0x5100 0x0 0x80>;
++ cache = <&iommuc>;
++ #iommu-cells = <0>;
++ };
++
++ iommu4: iommu@5200 {
++ /* IOMMU4 for HVS, MPL/TXP; and (unused) Unicam, PISP-FE, MiniBVN */
++ compatible = "brcm,bcm2712-iommu";
++ reg = <0x10 0x5200 0x0 0x80>;
++ cache = <&iommuc>;
++ #iommu-cells = <0>;
++ #interconnect-cells = <0>;
++ };
++
++ iommu5: iommu@5280 {
++ /* IOMMU5 for PCIe2 (RP1); and (unused) BSTM */
++ compatible = "brcm,bcm2712-iommu";
++ reg = <0x10 0x5280 0x0 0x80>;
++ cache = <&iommuc>;
++ #iommu-cells = <0>;
++ dma-iova-offset = <0x10 0x00000000>; // HACK for RP1 masters over PCIe
++ };
++
++ iommuc: iommuc@5b00 {
++ compatible = "brcm,bcm2712-iommuc";
++ reg = <0x10 0x5b00 0x0 0x80>;
++ };
++
++ dma32: dma@10000 {
++ compatible = "brcm,bcm2712-dma";
++ reg = <0x10 0x00010000 0 0x600>;
++ interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
++ interrupt-names = "dma0",
++ "dma1",
++ "dma2",
++ "dma3",
++ "dma4",
++ "dma5";
++ #dma-cells = <1>;
++ brcm,dma-channel-mask = <0x0035>;
++ };
++
++ dma40: dma@10600 {
++ compatible = "brcm,bcm2712-dma";
++ reg = <0x10 0x00010600 0 0x600>;
++ interrupts =
++ <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>, /* dma4 6 */
++ <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>, /* dma4 7 */
++ <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>, /* dma4 8 */
++ <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>, /* dma4 9 */
++ <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>, /* dma4 10 */
++ <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>; /* dma4 11 */
++ interrupt-names = "dma6",
++ "dma7",
++ "dma8",
++ "dma9",
++ "dma10",
++ "dma11";
++ #dma-cells = <1>;
++ brcm,dma-channel-mask = <0x0fc0>;
++ };
++
++ // Single-lane Gen3 PCIe
++ // Outbound window at 0x14_000000-0x17_ffffff
++ pcie0: pcie@100000 {
++ compatible = "brcm,bcm2712-pcie";
++ reg = <0x10 0x00100000 0x0 0x9310>;
++ device_type = "pci";
++ max-link-speed = <2>;
++ #address-cells = <3>;
++ #interrupt-cells = <1>;
++ #size-cells = <2>;
++ /*
++ * Unused interrupts:
++ * 208: AER
++ * 215: NMI
++ * 216: PME
++ */
++ interrupt-parent = <&gicv2>;
++ interrupts = <GIC_SPI 213 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 214 IRQ_TYPE_LEVEL_HIGH>;
++ interrupt-names = "pcie", "msi";
++ interrupt-map-mask = <0x0 0x0 0x0 0x7>;
++ interrupt-map = <0 0 0 1 &gicv2 GIC_SPI 209
++ IRQ_TYPE_LEVEL_HIGH>,
++ <0 0 0 2 &gicv2 GIC_SPI 210
++ IRQ_TYPE_LEVEL_HIGH>,
++ <0 0 0 3 &gicv2 GIC_SPI 211
++ IRQ_TYPE_LEVEL_HIGH>,
++ <0 0 0 4 &gicv2 GIC_SPI 212
++ IRQ_TYPE_LEVEL_HIGH>;
++ resets = <&bcm_reset 5>, <&bcm_reset 42>, <&pcie_rescal>;
++ reset-names = "swinit", "bridge", "rescal";
++ msi-controller;
++ msi-parent = <&pcie0>;
++
++ ranges = <0x02000000 0x00 0x00000000
++ 0x17 0x00000000
++ 0x0 0xfffffffc>,
++ <0x43000000 0x04 0x00000000
++ 0x14 0x00000000
++ 0x3 0x00000000>;
++
++ dma-ranges = <0x43000000 0x10 0x00000000
++ 0x00 0x00000000
++ 0x10 0x00000000>;
++
++ status = "disabled";
++ };
++
++ // Single-lane Gen3 PCIe
++ // Outbound window at 0x18_000000-0x1b_ffffff
++ pcie1: pcie@110000 {
++ compatible = "brcm,bcm2712-pcie";
++ reg = <0x10 0x00110000 0x0 0x9310>;
++ device_type = "pci";
++ max-link-speed = <2>;
++ #address-cells = <3>;
++ #interrupt-cells = <1>;
++ #size-cells = <2>;
++ /*
++ * Unused interrupts:
++ * 218: AER
++ * 225: NMI
++ * 226: PME
++ */
++ interrupt-parent = <&gicv2>;
++ interrupts = <GIC_SPI 223 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>;
++ interrupt-names = "pcie", "msi";
++ interrupt-map-mask = <0x0 0x0 0x0 0x7>;
++ interrupt-map = <0 0 0 1 &gicv2 GIC_SPI 219
++ IRQ_TYPE_LEVEL_HIGH>,
++ <0 0 0 2 &gicv2 GIC_SPI 220
++ IRQ_TYPE_LEVEL_HIGH>,
++ <0 0 0 3 &gicv2 GIC_SPI 221
++ IRQ_TYPE_LEVEL_HIGH>,
++ <0 0 0 4 &gicv2 GIC_SPI 222
++ IRQ_TYPE_LEVEL_HIGH>;
++ resets = <&bcm_reset 7>, <&bcm_reset 43>, <&pcie_rescal>;
++ reset-names = "swinit", "bridge", "rescal";
++ msi-controller;
++ msi-parent = <&mip1>;
++
++ ranges = <0x02000000 0x00 0x00000000
++ 0x1b 0x00000000
++ 0x00 0xfffffffc>,
++ <0x43000000 0x04 0x00000000
++ 0x18 0x00000000
++ 0x03 0x00000000>;
++
++ dma-ranges = <0x03000000 0x10 0x00000000
++ 0x00 0x00000000
++ 0x10 0x00000000>;
++
++ status = "disabled";
++ };
++
++ pcie_rescal: reset-controller@119500 {
++ compatible = "brcm,bcm7216-pcie-sata-rescal";
++ reg = <0x10 0x00119500 0x0 0x10>;
++ #reset-cells = <0>;
++ };
++
++ // Quad-lane Gen3 PCIe
++ // Outbound window at 0x1c_000000-0x1f_ffffff
++ pcie2: pcie@120000 {
++ compatible = "brcm,bcm2712-pcie";
++ reg = <0x10 0x00120000 0x0 0x9310>;
++ device_type = "pci";
++ max-link-speed = <2>;
++ #address-cells = <3>;
++ #interrupt-cells = <1>;
++ #size-cells = <2>;
++ /*
++ * Unused interrupts:
++ * 228: AER
++ * 235: NMI
++ * 236: PME
++ */
++ interrupt-parent = <&gicv2>;
++ interrupts = <GIC_SPI 233 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 234 IRQ_TYPE_LEVEL_HIGH>;
++ interrupt-names = "pcie", "msi";
++ interrupt-map-mask = <0x0 0x0 0x0 0x7>;
++ interrupt-map = <0 0 0 1 &gicv2 GIC_SPI 229
++ IRQ_TYPE_LEVEL_HIGH>,
++ <0 0 0 2 &gicv2 GIC_SPI 230
++ IRQ_TYPE_LEVEL_HIGH>,
++ <0 0 0 3 &gicv2 GIC_SPI 231
++ IRQ_TYPE_LEVEL_HIGH>,
++ <0 0 0 4 &gicv2 GIC_SPI 232
++ IRQ_TYPE_LEVEL_HIGH>;
++ resets = <&bcm_reset 32>, <&bcm_reset 44>, <&pcie_rescal>;
++ reset-names = "swinit", "bridge", "rescal";
++ msi-controller;
++ msi-parent = <&mip0>;
++
++ // ~4GB, 32-bit, not-prefetchable at PCIe 00_00000000
++ ranges = <0x02000000 0x00 0x00000000
++ 0x1f 0x00000000
++ 0x0 0xfffffffc>,
++ // 12GB, 64-bit, prefetchable at PCIe 04_00000000
++ <0x43000000 0x04 0x00000000
++ 0x1c 0x00000000
++ 0x03 0x00000000>;
++
++ // 64GB system RAM space at PCIe 10_00000000
++ dma-ranges = <0x02000000 0x00 0x00000000
++ 0x1f 0x00000000
++ 0x00 0x00400000>,
++ <0x43000000 0x10 0x00000000
++ 0x00 0x00000000
++ 0x10 0x00000000>;
++
++ status = "disabled";
++ };
++
++ mip0: msi-controller@130000 {
++ compatible = "brcm,bcm2712-mip-intc";
++ reg = <0x10 0x00130000 0x0 0xc0>;
++ msi-controller;
++ interrupt-controller;
++ #interrupt-cells = <2>;
++ brcm,msi-base-spi = <128>;
++ brcm,msi-num-spis = <64>;
++ brcm,msi-offset = <0>;
++ brcm,msi-pci-addr = <0xff 0xfffff000>;
++ };
++
++ mip1: msi-controller@131000 {
++ compatible = "brcm,bcm2712-mip-intc";
++ reg = <0x10 0x00131000 0x0 0xc0>;
++ msi-controller;
++ interrupt-controller;
++ #interrupt-cells = <2>;
++ brcm,msi-base-spi = <247>;
++ /* Actually 20 total, but the others are
++ * both sparse and non-consecutive */
++ brcm,msi-num-spis = <8>;
++ brcm,msi-offset = <8>;
++ brcm,msi-pci-addr = <0xff 0xffffe000>;
++ };
++
++ syscon_piarbctl: syscon@400018 {
++ compatible = "brcm,syscon-piarbctl", "syscon", "simple-mfd";
++ reg = <0x10 0x00400018 0x0 0x18>;
++ };
++
++ usb: usb@480000 {
++ compatible = "brcm,bcm2835-usb";
++ reg = <0x10 0x00480000 0x0 0x10000>;
++ interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ clocks = <&clk_usb>;
++ clock-names = "otg";
++ phys = <&usbphy>;
++ phy-names = "usb2-phy";
++ status = "disabled";
++ };
++
++ rpivid: codec@800000 {
++ compatible = "raspberrypi,rpivid-vid-decoder";
++ reg = <0x10 0x00800000 0x0 0x10000>, /* HEVC */
++ <0x10 0x00840000 0x0 0x1000>; /* INTC */
++ reg-names = "hevc",
++ "intc";
++
++ interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
++
++ clocks = <&firmware_clocks 11>;
++ clock-names = "hevc";
++ iommus = <&iommu2>;
++ status = "disabled";
++ };
++
++ sdio1: mmc@fff000 {
++ compatible = "brcm,bcm2712-sdhci";
++ reg = <0x10 0x00fff000 0x0 0x260>,
++ <0x10 0x00fff400 0x0 0x200>,
++ <0x10 0x015040b0 0x0 0x4>, // Bus isolation control
++ <0x10 0x015200f0 0x0 0x24>; // LCPLL control misc0-8
++ reg-names = "host", "cfg", "busisol", "lcpll";
++ interrupts = <GIC_SPI 273 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&clk_emmc2>;
++ sdhci-caps-mask = <0x0000C000 0x0>;
++ sdhci-caps = <0x0 0x0>;
++ mmc-ddr-3_3v;
++ };
++
++ sdio2: mmc@1100000 {
++ compatible = "brcm,bcm2712-sdhci";
++ reg = <0x10 0x01100000 0x0 0x260>,
++ <0x10 0x01100400 0x0 0x200>;
++ reg-names = "host", "cfg";
++ interrupts = <GIC_SPI 274 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&clk_emmc2>;
++ sdhci-caps-mask = <0x0000C000 0x0>;
++ sdhci-caps = <0x0 0x0>;
++ supports-cqe;
++ mmc-ddr-3_3v;
++ status = "disabled";
++ };
++
++ bcm_reset: reset-controller@1504318 {
++ compatible = "brcm,brcmstb-reset";
++ reg = <0x10 0x01504318 0x0 0x30>;
++ #reset-cells = <1>;
++ };
++
++ v3d: v3d@2000000 {
++ compatible = "brcm,2712-v3d";
++ reg = <0x10 0x02000000 0x0 0x4000>,
++ <0x10 0x02008000 0x0 0x6000>;
++ reg-names = "hub", "core0";
++
++ power-domains = <&pm BCM2835_POWER_DOMAIN_GRAFX_V3D>;
++ resets = <&pm BCM2835_RESET_V3D>;
++ clocks = <&firmware_clocks 5>;
++ clocks-names = "v3d";
++ interrupts = <GIC_SPI 250 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 249 IRQ_TYPE_LEVEL_HIGH>;
++ status = "disabled";
++ };
++
++ gicv2: interrupt-controller@7fff9000 {
++ interrupt-controller;
++ #interrupt-cells = <3>;
++ compatible = "arm,gic-400";
++ reg = <0x10 0x7fff9000 0x0 0x1000>,
++ <0x10 0x7fffa000 0x0 0x2000>,
++ <0x10 0x7fffc000 0x0 0x2000>,
++ <0x10 0x7fffe000 0x0 0x2000>;
++ interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) |
++ IRQ_TYPE_LEVEL_HIGH)>;
++ };
++
++ pisp_be: pisp_be@880000 {
++ compatible = "raspberrypi,pispbe";
++ reg = <0x10 0x00880000 0x0 0x4000>;
++ interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&firmware_clocks 7>;
++ clocks-names = "isp_be";
++ status = "okay";
++ iommus = <&iommu2>;
++ };
++ };
++
++ clocks {
++ /* The oscillator is the root of the clock tree. */
++ clk_osc: clk-osc {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-output-names = "osc";
++ clock-frequency = <54000000>;
++ };
++
++ clk_usb: clk-usb {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-output-names = "otg";
++ clock-frequency = <480000000>;
++ };
++
++ clk_vpu: clk_vpu {
++ #clock-cells = <0>;
++ compatible = "fixed-clock";
++ clock-frequency = <750000000>;
++ clock-output-names = "vpu-clock";
++ };
++
++ clk_uart: clk_uart {
++ #clock-cells = <0>;
++ compatible = "fixed-clock";
++ clock-frequency = <9216000>;
++ clock-output-names = "uart-clock";
++ };
++
++ clk_emmc2: clk_emmc2 {
++ #clock-cells = <0>;
++ compatible = "fixed-clock";
++ clock-frequency = <200000000>;
++ clock-output-names = "emmc2-clock";
++ };
++ };
++
++ usbphy: phy {
++ compatible = "usb-nop-xceiv";
++ #phy-cells = <0>;
++ };
++};
+--- /dev/null
++++ b/arch/arm64/boot/dts/broadcom/rp1.dtsi
+@@ -0,0 +1,1287 @@
++#include <dt-bindings/clock/rp1.h>
++#include <dt-bindings/interrupt-controller/irq.h>
++#include <dt-bindings/mfd/rp1.h>
++
++&rp1_target {
++ rp1: rp1 {
++ compatible = "simple-bus";
++ #address-cells = <2>;
++ #size-cells = <2>;
++ #interrupt-cells = <2>;
++ interrupt-controller;
++ interrupt-parent = <&rp1>;
++
++ // ranges and dma-ranges must be provided by the includer
++
++ rp1_clocks: clocks@18000 {
++ compatible = "raspberrypi,rp1-clocks";
++ #clock-cells = <1>;
++ reg = <0xc0 0x40018000 0x0 0x10038>;
++ clocks = <&clk_xosc>;
++
++ assigned-clocks = <&rp1_clocks RP1_PLL_SYS_CORE>,
++ <&rp1_clocks RP1_PLL_AUDIO_CORE>,
++ // RP1_PLL_VIDEO_CORE and dividers are now managed by VEC,DPI drivers
++ <&rp1_clocks RP1_PLL_SYS>,
++ <&rp1_clocks RP1_PLL_SYS_SEC>,
++ <&rp1_clocks RP1_PLL_AUDIO>,
++ <&rp1_clocks RP1_PLL_AUDIO_SEC>,
++ <&rp1_clocks RP1_CLK_SYS>,
++ <&rp1_clocks RP1_PLL_SYS_PRI_PH>,
++ // RP1_CLK_SLOW_SYS is used for the frequency counter (FC0)
++ <&rp1_clocks RP1_CLK_SLOW_SYS>,
++ <&rp1_clocks RP1_CLK_SDIO_TIMER>,
++ <&rp1_clocks RP1_CLK_SDIO_ALT_SRC>,
++ <&rp1_clocks RP1_CLK_ETH_TSU>;
++
++ assigned-clock-rates = <1000000000>, // RP1_PLL_SYS_CORE
++ <1536000000>, // RP1_PLL_AUDIO_CORE
++ <200000000>, // RP1_PLL_SYS
++ <125000000>, // RP1_PLL_SYS_SEC
++ <61440000>, // RP1_PLL_AUDIO
++ <192000000>, // RP1_PLL_AUDIO_SEC
++ <200000000>, // RP1_CLK_SYS
++ <100000000>, // RP1_PLL_SYS_PRI_PH
++ // Must match the XOSC frequency
++ <50000000>, // RP1_CLK_SLOW_SYS
++ <1000000>, // RP1_CLK_SDIO_TIMER
++ <200000000>, // RP1_CLK_SDIO_ALT_SRC
++ <50000000>; // RP1_CLK_ETH_TSU
++ };
++
++ rp1_uart0: serial@30000 {
++ compatible = "arm,pl011-axi";
++ reg = <0xc0 0x40030000 0x0 0x100>;
++ interrupts = <RP1_INT_UART0 IRQ_TYPE_LEVEL_HIGH>;
++ 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";
++ pinctrl-names = "default";
++ arm,primecell-periphid = <0x00541011>;
++ uart-has-rtscts;
++ cts-event-workaround;
++ skip-init;
++ status = "disabled";
++ };
++
++ rp1_uart1: serial@34000 {
++ compatible = "arm,pl011-axi";
++ reg = <0xc0 0x40034000 0x0 0x100>;
++ interrupts = <RP1_INT_UART1 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&rp1_clocks RP1_CLK_UART &rp1_clocks RP1_PLL_SYS_PRI_PH>;
++ clock-names = "uartclk", "apb_pclk";
++ // dmas = <&rp1_dma RP1_DMA_UART1_TX>,
++ // <&rp1_dma RP1_DMA_UART1_RX>;
++ // dma-names = "tx", "rx";
++ pinctrl-names = "default";
++ arm,primecell-periphid = <0x00541011>;
++ uart-has-rtscts;
++ cts-event-workaround;
++ skip-init;
++ status = "disabled";
++ };
++
++ rp1_uart2: serial@38000 {
++ compatible = "arm,pl011-axi";
++ reg = <0xc0 0x40038000 0x0 0x100>;
++ interrupts = <RP1_INT_UART2 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&rp1_clocks RP1_CLK_UART &rp1_clocks RP1_PLL_SYS_PRI_PH>;
++ clock-names = "uartclk", "apb_pclk";
++ // dmas = <&rp1_dma RP1_DMA_UART2_TX>,
++ // <&rp1_dma RP1_DMA_UART2_RX>;
++ // dma-names = "tx", "rx";
++ pinctrl-names = "default";
++ arm,primecell-periphid = <0x00541011>;
++ uart-has-rtscts;
++ cts-event-workaround;
++ skip-init;
++ status = "disabled";
++ };
++
++ rp1_uart3: serial@3c000 {
++ compatible = "arm,pl011-axi";
++ reg = <0xc0 0x4003c000 0x0 0x100>;
++ interrupts = <RP1_INT_UART3 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&rp1_clocks RP1_CLK_UART &rp1_clocks RP1_PLL_SYS_PRI_PH>;
++ clock-names = "uartclk", "apb_pclk";
++ // dmas = <&rp1_dma RP1_DMA_UART3_TX>,
++ // <&rp1_dma RP1_DMA_UART3_RX>;
++ // dma-names = "tx", "rx";
++ pinctrl-names = "default";
++ arm,primecell-periphid = <0x00541011>;
++ uart-has-rtscts;
++ cts-event-workaround;
++ skip-init;
++ status = "disabled";
++ };
++
++ rp1_uart4: serial@40000 {
++ compatible = "arm,pl011-axi";
++ reg = <0xc0 0x40040000 0x0 0x100>;
++ interrupts = <RP1_INT_UART4 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&rp1_clocks RP1_CLK_UART &rp1_clocks RP1_PLL_SYS_PRI_PH>;
++ clock-names = "uartclk", "apb_pclk";
++ // dmas = <&rp1_dma RP1_DMA_UART4_TX>,
++ // <&rp1_dma RP1_DMA_UART4_RX>;
++ // dma-names = "tx", "rx";
++ pinctrl-names = "default";
++ arm,primecell-periphid = <0x00541011>;
++ uart-has-rtscts;
++ cts-event-workaround;
++ skip-init;
++ status = "disabled";
++ };
++
++ rp1_uart5: serial@44000 {
++ compatible = "arm,pl011-axi";
++ reg = <0xc0 0x40044000 0x0 0x100>;
++ interrupts = <RP1_INT_UART5 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&rp1_clocks RP1_CLK_UART &rp1_clocks RP1_PLL_SYS_PRI_PH>;
++ clock-names = "uartclk", "apb_pclk";
++ // dmas = <&rp1_dma RP1_DMA_UART5_TX>,
++ // <&rp1_dma RP1_DMA_UART5_RX>;
++ // dma-names = "tx", "rx";
++ pinctrl-names = "default";
++ arm,primecell-periphid = <0x00541011>;
++ uart-has-rtscts;
++ cts-event-workaround;
++ skip-init;
++ status = "disabled";
++ };
++
++ rp1_spi8: spi@4c000 {
++ reg = <0xc0 0x4004c000 0x0 0x130>;
++ compatible = "snps,dw-apb-ssi";
++ interrupts = <RP1_INT_SPI8 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&rp1_clocks RP1_CLK_SYS>;
++ clock-names = "ssi_clk";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ num-cs = <2>;
++ dmas = <&rp1_dma RP1_DMA_SPI8_TX>,
++ <&rp1_dma RP1_DMA_SPI8_RX>;
++ dma-names = "tx", "rx";
++ status = "disabled";
++ };
++
++ rp1_spi0: spi@50000 {
++ reg = <0xc0 0x40050000 0x0 0x130>;
++ compatible = "snps,dw-apb-ssi";
++ interrupts = <RP1_INT_SPI0 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&rp1_clocks RP1_CLK_SYS>;
++ clock-names = "ssi_clk";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ num-cs = <2>;
++ dmas = <&rp1_dma RP1_DMA_SPI0_TX>,
++ <&rp1_dma RP1_DMA_SPI0_RX>;
++ dma-names = "tx", "rx";
++ status = "disabled";
++ };
++
++ rp1_spi1: spi@54000 {
++ reg = <0xc0 0x40054000 0x0 0x130>;
++ compatible = "snps,dw-apb-ssi";
++ interrupts = <RP1_INT_SPI1 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&rp1_clocks RP1_CLK_SYS>;
++ clock-names = "ssi_clk";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ num-cs = <2>;
++ dmas = <&rp1_dma RP1_DMA_SPI1_TX>,
++ <&rp1_dma RP1_DMA_SPI1_RX>;
++ dma-names = "tx", "rx";
++ status = "disabled";
++ };
++
++ rp1_spi2: spi@58000 {
++ reg = <0xc0 0x40058000 0x0 0x130>;
++ compatible = "snps,dw-apb-ssi";
++ interrupts = <RP1_INT_SPI2 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&rp1_clocks RP1_CLK_SYS>;
++ clock-names = "ssi_clk";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ num-cs = <2>;
++ dmas = <&rp1_dma RP1_DMA_SPI2_TX>,
++ <&rp1_dma RP1_DMA_SPI2_RX>;
++ dma-names = "tx", "rx";
++ status = "disabled";
++ };
++
++ rp1_spi3: spi@5c000 {
++ reg = <0xc0 0x4005c000 0x0 0x130>;
++ compatible = "snps,dw-apb-ssi";
++ interrupts = <RP1_INT_SPI3 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&rp1_clocks RP1_CLK_SYS>;
++ clock-names = "ssi_clk";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ num-cs = <2>;
++ dmas = <&rp1_dma RP1_DMA_SPI3_TX>,
++ <&rp1_dma RP1_DMA_SPI3_RX>;
++ dma-names = "tx", "rx";
++ status = "disabled";
++ };
++
++ // SPI4 is a target/slave interface
++ rp1_spi4: spi@60000 {
++ reg = <0xc0 0x40060000 0x0 0x130>;
++ compatible = "snps,dw-apb-ssi";
++ interrupts = <RP1_INT_SPI4 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&rp1_clocks RP1_CLK_SYS>;
++ clock-names = "ssi_clk";
++ #address-cells = <0>;
++ #size-cells = <0>;
++ num-cs = <1>;
++ spi-slave;
++ dmas = <&rp1_dma RP1_DMA_SPI4_TX>,
++ <&rp1_dma RP1_DMA_SPI4_RX>;
++ dma-names = "tx", "rx";
++ status = "disabled";
++
++ slave {
++ compatible = "spidev";
++ spi-max-frequency = <1000000>;
++ };
++ };
++
++ rp1_spi5: spi@64000 {
++ reg = <0xc0 0x40064000 0x0 0x130>;
++ compatible = "snps,dw-apb-ssi";
++ interrupts = <RP1_INT_SPI5 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&rp1_clocks RP1_CLK_SYS>;
++ clock-names = "ssi_clk";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ num-cs = <2>;
++ dmas = <&rp1_dma RP1_DMA_SPI5_TX>,
++ <&rp1_dma RP1_DMA_SPI5_RX>;
++ dma-names = "tx", "rx";
++ status = "disabled";
++ };
++
++ rp1_spi6: spi@68000 {
++ reg = <0xc0 0x40068000 0x0 0x130>;
++ compatible = "snps,dw-apb-ssi";
++ interrupts = <RP1_INT_SPI6 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&rp1_clocks RP1_CLK_SYS>;
++ clock-names = "ssi_clk";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ num-cs = <2>;
++ dmas = <&rp1_dma RP1_DMA_SPI6_TX>,
++ <&rp1_dma RP1_DMA_SPI6_RX>;
++ dma-names = "tx", "rx";
++ status = "disabled";
++ };
++
++ // SPI7 is a target/slave interface
++ rp1_spi7: spi@6c000 {
++ reg = <0xc0 0x4006c000 0x0 0x130>;
++ compatible = "snps,dw-apb-ssi";
++ interrupts = <RP1_INT_SPI7 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&rp1_clocks RP1_CLK_SYS>;
++ clock-names = "ssi_clk";
++ #address-cells = <0>;
++ #size-cells = <0>;
++ num-cs = <1>;
++ spi-slave;
++ dmas = <&rp1_dma RP1_DMA_SPI7_TX>,
++ <&rp1_dma RP1_DMA_SPI7_RX>;
++ dma-names = "tx", "rx";
++ status = "disabled";
++
++ slave {
++ compatible = "spidev";
++ spi-max-frequency = <1000000>;
++ };
++ };
++
++ rp1_i2c0: i2c@70000 {
++ reg = <0xc0 0x40070000 0x0 0x1000>;
++ compatible = "snps,designware-i2c";
++ interrupts = <RP1_INT_I2C0 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&rp1_clocks RP1_CLK_SYS>;
++ i2c-scl-rising-time-ns = <65>;
++ i2c-scl-falling-time-ns = <100>;
++ status = "disabled";
++ };
++
++ rp1_i2c1: i2c@74000 {
++ reg = <0xc0 0x40074000 0x0 0x1000>;
++ compatible = "snps,designware-i2c";
++ interrupts = <RP1_INT_I2C1 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&rp1_clocks RP1_CLK_SYS>;
++ i2c-scl-rising-time-ns = <65>;
++ i2c-scl-falling-time-ns = <100>;
++ status = "disabled";
++ };
++
++ rp1_i2c2: i2c@78000 {
++ reg = <0xc0 0x40078000 0x0 0x1000>;
++ compatible = "snps,designware-i2c";
++ interrupts = <RP1_INT_I2C2 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&rp1_clocks RP1_CLK_SYS>;
++ i2c-scl-rising-time-ns = <65>;
++ i2c-scl-falling-time-ns = <100>;
++ status = "disabled";
++ };
++
++ rp1_i2c3: i2c@7c000 {
++ reg = <0xc0 0x4007c000 0x0 0x1000>;
++ compatible = "snps,designware-i2c";
++ interrupts = <RP1_INT_I2C3 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&rp1_clocks RP1_CLK_SYS>;
++ i2c-scl-rising-time-ns = <65>;
++ i2c-scl-falling-time-ns = <100>;
++ status = "disabled";
++ };
++
++ rp1_i2c4: i2c@80000 {
++ reg = <0xc0 0x40080000 0x0 0x1000>;
++ compatible = "snps,designware-i2c";
++ interrupts = <RP1_INT_I2C4 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&rp1_clocks RP1_CLK_SYS>;
++ i2c-scl-rising-time-ns = <65>;
++ i2c-scl-falling-time-ns = <100>;
++ status = "disabled";
++ };
++
++ rp1_i2c5: i2c@84000 {
++ reg = <0xc0 0x40084000 0x0 0x1000>;
++ compatible = "snps,designware-i2c";
++ interrupts = <RP1_INT_I2C5 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&rp1_clocks RP1_CLK_SYS>;
++ i2c-scl-rising-time-ns = <65>;
++ i2c-scl-falling-time-ns = <100>;
++ status = "disabled";
++ };
++
++ rp1_i2c6: i2c@88000 {
++ reg = <0xc0 0x40088000 0x0 0x1000>;
++ compatible = "snps,designware-i2c";
++ interrupts = <RP1_INT_I2C6 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&rp1_clocks RP1_CLK_SYS>;
++ i2c-scl-rising-time-ns = <65>;
++ i2c-scl-falling-time-ns = <100>;
++ status = "disabled";
++ };
++
++ rp1_pwm0: pwm@98000 {
++ compatible = "raspberrypi,rp1-pwm";
++ reg = <0xc0 0x40098000 0x0 0x100>;
++ #pwm-cells = <3>;
++ clocks = <&rp1_clocks RP1_CLK_PWM0>;
++ assigned-clocks = <&rp1_clocks RP1_CLK_PWM0>;
++ assigned-clock-rates = <50000000>;
++ status = "disabled";
++ };
++
++ rp1_pwm1: pwm@9c000 {
++ compatible = "raspberrypi,rp1-pwm";
++ reg = <0xc0 0x4009c000 0x0 0x100>;
++ #pwm-cells = <3>;
++ clocks = <&rp1_clocks RP1_CLK_PWM1>;
++ assigned-clocks = <&rp1_clocks RP1_CLK_PWM1>;
++ assigned-clock-rates = <50000000>;
++ status = "disabled";
++ };
++
++ rp1_i2s0: i2s@a0000 {
++ reg = <0xc0 0x400a0000 0x0 0x1000>;
++ compatible = "snps,designware-i2s";
++ // Providing an interrupt disables DMA
++ // interrupts = <RP1_INT_I2S0 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&rp1_clocks RP1_CLK_I2S>;
++ clock-names = "i2sclk";
++ #sound-dai-cells = <0>;
++ dmas = <&rp1_dma RP1_DMA_I2S0_TX>,<&rp1_dma RP1_DMA_I2S0_RX>;
++ dma-names = "tx", "rx";
++ status = "disabled";
++ };
++
++ rp1_i2s1: i2s@a4000 {
++ reg = <0xc0 0x400a4000 0x0 0x1000>;
++ compatible = "snps,designware-i2s";
++ // Providing an interrupt disables DMA
++ // interrupts = <RP1_INT_I2S1 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&rp1_clocks RP1_CLK_I2S>;
++ clock-names = "i2sclk";
++ #sound-dai-cells = <0>;
++ dmas = <&rp1_dma RP1_DMA_I2S1_TX>,<&rp1_dma RP1_DMA_I2S1_RX>;
++ dma-names = "tx", "rx";
++ status = "disabled";
++ };
++
++ rp1_i2s2: i2s@a8000 {
++ reg = <0xc0 0x400a8000 0x0 0x1000>;
++ compatible = "snps,designware-i2s";
++ // Providing an interrupt disables DMA
++ // interrupts = <RP1_INT_I2S2 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&rp1_clocks RP1_CLK_I2S>;
++ status = "disabled";
++ };
++
++ rp1_sdio_clk0: sdio_clk0@b0004 {
++ compatible = "raspberrypi,rp1-sdio-clk";
++ reg = <0xc0 0x400b0004 0x0 0x1c>;
++ clocks = <&sdio_src &sdhci_core>;
++ clock-names = "src", "base";
++ #clock-cells = <0>;
++ status = "disabled";
++ };
++
++ rp1_sdio_clk1: sdio_clk1@b4004 {
++ compatible = "raspberrypi,rp1-sdio-clk";
++ reg = <0xc0 0x400b4004 0x0 0x1c>;
++ clocks = <&sdio_src &sdhci_core>;
++ clock-names = "src", "base";
++ #clock-cells = <0>;
++ status = "disabled";
++ };
++
++ rp1_adc: adc@c8000 {
++ compatible = "raspberrypi,rp1-adc";
++ reg = <0xc0 0x400c8000 0x0 0x4000>;
++ clocks = <&rp1_clocks RP1_CLK_ADC>;
++ clock-names = "adcclk";
++ #clock-cells = <0>;
++ vref-supply = <&rp1_vdd_3v3>;
++ status = "disabled";
++ };
++
++ rp1_gpio: gpio@d0000 {
++ reg = <0xc0 0x400d0000 0x0 0xc000>,
++ <0xc0 0x400e0000 0x0 0xc000>,
++ <0xc0 0x400f0000 0x0 0xc000>;
++ compatible = "raspberrypi,rp1-gpio";
++ interrupts = <RP1_INT_IO_BANK0 IRQ_TYPE_LEVEL_HIGH>,
++ <RP1_INT_IO_BANK1 IRQ_TYPE_LEVEL_HIGH>,
++ <RP1_INT_IO_BANK2 IRQ_TYPE_LEVEL_HIGH>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ interrupt-controller;
++ #interrupt-cells = <2>;
++ gpio-ranges = <&rp1_gpio 0 0 54>;
++
++ rp1_uart0_14_15: rp1_uart0_14_15 {
++ pin_txd {
++ function = "uart0";
++ pins = "gpio14";
++ bias-disable;
++ };
++ pin_rxd {
++ function = "uart0";
++ pins = "gpio15";
++ bias-pull-up;
++ };
++ };
++ rp1_uart0_ctsrts_16_17: rp1_uart0_ctsrts_16_17 {
++ pin_cts {
++ function = "uart0";
++ pins = "gpio16";
++ bias-pull-up;
++ };
++ pin_rts {
++ function = "uart0";
++ pins = "gpio17";
++ bias-disable;
++ };
++ };
++ rp1_uart1_0_1: rp1_uart1_0_1 {
++ pin_txd {
++ function = "uart1";
++ pins = "gpio0";
++ bias-disable;
++ };
++ pin_rxd {
++ function = "uart1";
++ pins = "gpio1";
++ bias-pull-up;
++ };
++ };
++ rp1_uart1_ctsrts_2_3: rp1_uart1_ctsrts_2_3 {
++ pin_cts {
++ function = "uart1";
++ pins = "gpio2";
++ bias-pull-up;
++ };
++ pin_rts {
++ function = "uart1";
++ pins = "gpio3";
++ bias-disable;
++ };
++ };
++ rp1_uart2_4_5: rp1_uart2_4_5 {
++ pin_txd {
++ function = "uart2";
++ pins = "gpio4";
++ bias-disable;
++ };
++ pin_rxd {
++ function = "uart2";
++ pins = "gpio5";
++ bias-pull-up;
++ };
++ };
++ rp1_uart2_ctsrts_6_7: rp1_uart2_ctsrts_6_7 {
++ pin_cts {
++ function = "uart2";
++ pins = "gpio6";
++ bias-pull-up;
++ };
++ pin_rts {
++ function = "uart2";
++ pins = "gpio7";
++ bias-disable;
++ };
++ };
++ rp1_uart3_8_9: rp1_uart3_8_9 {
++ pin_txd {
++ function = "uart3";
++ pins = "gpio8";
++ bias-disable;
++ };
++ pin_rxd {
++ function = "uart3";
++ pins = "gpio9";
++ bias-pull-up;
++ };
++ };
++ rp1_uart3_ctsrts_10_11: rp1_uart3_ctsrts_10_11 {
++ pin_cts {
++ function = "uart3";
++ pins = "gpio10";
++ bias-pull-up;
++ };
++ pin_rts {
++ function = "uart3";
++ pins = "gpio11";
++ bias-disable;
++ };
++ };
++ rp1_uart4_12_13: rp1_uart4_12_13 {
++ pin_txd {
++ function = "uart4";
++ pins = "gpio12";
++ bias-disable;
++ };
++ pin_rxd {
++ function = "uart4";
++ pins = "gpio13";
++ bias-pull-up;
++ };
++ };
++ rp1_uart4_ctsrts_14_15: rp1_uart4_ctsrts_14_15 {
++ pin_cts {
++ function = "uart4";
++ pins = "gpio14";
++ bias-pull-up;
++ };
++ pin_rts {
++ function = "uart4";
++ pins = "gpio15";
++ bias-disable;
++ };
++ };
++
++ rp1_sdio0_22_27: rp1_sdio0_22_27 {
++ pin_clk {
++ function = "sd0";
++ pins = "gpio22";
++ bias-disable;
++ drive-strength = <12>;
++ slew-rate = <1>;
++ };
++ pin_cmd {
++ function = "sd0";
++ pins = "gpio23";
++ bias-pull-up;
++ drive-strength = <12>;
++ slew-rate = <1>;
++ };
++ pins_dat {
++ function = "sd0";
++ pins = "gpio24", "gpio25", "gpio26", "gpio27";
++ bias-pull-up;
++ drive-strength = <12>;
++ slew-rate = <1>;
++ };
++ };
++
++ rp1_sdio1_28_33: rp1_sdio1_28_33 {
++ pin_clk {
++ function = "sd1";
++ pins = "gpio28";
++ bias-disable;
++ drive-strength = <12>;
++ slew-rate = <1>;
++ };
++ pin_cmd {
++ function = "sd1";
++ pins = "gpio29";
++ bias-pull-up;
++ drive-strength = <12>;
++ slew-rate = <1>;
++ };
++ pins_dat {
++ function = "sd1";
++ pins = "gpio30", "gpio31", "gpio32", "gpio33";
++ bias-pull-up;
++ drive-strength = <12>;
++ slew-rate = <1>;
++ };
++ };
++
++ rp1_i2s0_18_21: rp1_i2s0_18_21 {
++ function = "i2s0";
++ pins = "gpio18", "gpio19", "gpio20", "gpio21";
++ bias-disable;
++ };
++
++ rp1_i2s1_18_21: rp1_i2s1_18_21 {
++ function = "i2s1";
++ pins = "gpio18", "gpio19", "gpio20", "gpio21";
++ bias-disable;
++ };
++
++ rp1_i2c4_34_35: rp1_i2c4_34_35 {
++ function = "i2c4";
++ pins = "gpio34", "gpio35";
++ drive-strength = <12>;
++ bias-pull-up;
++ };
++ rp1_i2c6_38_39: rp1_i2c6_38_39 {
++ function = "i2c6";
++ pins = "gpio38", "gpio39";
++ drive-strength = <12>;
++ bias-pull-up;
++ };
++ rp1_i2c4_40_41: rp1_i2c4_40_41 {
++ function = "i2c4";
++ pins = "gpio40", "gpio41";
++ drive-strength = <12>;
++ bias-pull-up;
++ };
++ rp1_i2c5_44_45: rp1_i2c5_44_45 {
++ function = "i2c5";
++ pins = "gpio44", "gpio45";
++ drive-strength = <12>;
++ bias-pull-up;
++ };
++ rp1_i2c0_0_1: rp1_i2c0_0_1 {
++ function = "i2c0";
++ pins = "gpio0", "gpio1";
++ drive-strength = <12>;
++ bias-pull-up;
++ };
++ rp1_i2c0_8_9: rp1_i2c0_8_9 {
++ function = "i2c0";
++ pins = "gpio8", "gpio9";
++ drive-strength = <12>;
++ bias-pull-up;
++ };
++ rp1_i2c1_2_3: rp1_i2c1_2_3 {
++ function = "i2c1";
++ pins = "gpio2", "gpio3";
++ drive-strength = <12>;
++ bias-pull-up;
++ };
++ rp1_i2c1_10_11: rp1_i2c1_10_11 {
++ function = "i2c1";
++ pins = "gpio10", "gpio11";
++ drive-strength = <12>;
++ bias-pull-up;
++ };
++ rp1_i2c2_4_5: rp1_i2c2_4_5 {
++ function = "i2c2";
++ pins = "gpio4", "gpio5";
++ drive-strength = <12>;
++ bias-pull-up;
++ };
++ rp1_i2c2_12_13: rp1_i2c2_12_13 {
++ function = "i2c2";
++ pins = "gpio12", "gpio13";
++ drive-strength = <12>;
++ bias-pull-up;
++ };
++ rp1_i2c3_6_7: rp1_i2c3_6_7 {
++ function = "i2c3";
++ pins = "gpio6", "gpio7";
++ drive-strength = <12>;
++ bias-pull-up;
++ };
++ rp1_i2c3_14_15: rp1_i2c3_14_15 {
++ function = "i2c3";
++ pins = "gpio14", "gpio15";
++ drive-strength = <12>;
++ bias-pull-up;
++ };
++ rp1_i2c3_22_23: rp1_i2c3_22_23 {
++ function = "i2c3";
++ pins = "gpio22", "gpio23";
++ drive-strength = <12>;
++ bias-pull-up;
++ };
++
++ // DPI mappings with HSYNC,VSYNC but without PIXCLK,DE
++ rp1_dpi_16bit_gpio2: rp1_dpi_16bit_gpio2 { /* Mode 2, not fully supported by RP1 */
++ function = "dpi";
++ pins = "gpio2", "gpio3", "gpio4", "gpio5",
++ "gpio6", "gpio7", "gpio8", "gpio9",
++ "gpio10", "gpio11", "gpio12", "gpio13",
++ "gpio14", "gpio15", "gpio16", "gpio17",
++ "gpio18", "gpio19";
++ bias-disable;
++ };
++ rp1_dpi_16bit_cpadhi_gpio2: rp1_dpi_16bit_cpadhi_gpio2 { /* Mode 3 */
++ function = "dpi";
++ pins = "gpio2", "gpio3", "gpio4", "gpio5",
++ "gpio6", "gpio7", "gpio8",
++ "gpio12", "gpio13", "gpio14", "gpio15",
++ "gpio16", "gpio17",
++ "gpio20", "gpio21", "gpio22", "gpio23",
++ "gpio24";
++ bias-disable;
++ };
++ rp1_dpi_16bit_pad666_gpio2: rp1_dpi_16bit_pad666_gpio2 { /* Mode 4 */
++ function = "dpi";
++ pins = "gpio2", "gpio3",
++ "gpio5", "gpio6", "gpio7", "gpio8",
++ "gpio9",
++ "gpio12", "gpio13", "gpio14", "gpio15",
++ "gpio16", "gpio17",
++ "gpio21", "gpio22", "gpio23", "gpio24",
++ "gpio25";
++ bias-disable;
++ };
++ rp1_dpi_18bit_gpio2: rp1_dpi_18bit_gpio2 { /* Mode 5, not fully supported by RP1 */
++ function = "dpi";
++ pins = "gpio2", "gpio3", "gpio4", "gpio5",
++ "gpio6", "gpio7", "gpio8", "gpio9",
++ "gpio10", "gpio11", "gpio12", "gpio13",
++ "gpio14", "gpio15", "gpio16", "gpio17",
++ "gpio18", "gpio19", "gpio20", "gpio21";
++ bias-disable;
++ };
++ rp1_dpi_18bit_cpadhi_gpio2: rp1_dpi_18bit_cpadhi_gpio2 { /* Mode 6 */
++ function = "dpi";
++ pins = "gpio2", "gpio3", "gpio4", "gpio5",
++ "gpio6", "gpio7", "gpio8", "gpio9",
++ "gpio12", "gpio13", "gpio14", "gpio15",
++ "gpio16", "gpio17",
++ "gpio20", "gpio21", "gpio22", "gpio23",
++ "gpio24", "gpio25";
++ bias-disable;
++ };
++ rp1_dpi_24bit_gpio2: rp1_dpi_24bit_gpio2 { /* Mode 7 */
++ function = "dpi";
++ pins = "gpio2", "gpio3", "gpio4", "gpio5",
++ "gpio6", "gpio7", "gpio8", "gpio9",
++ "gpio10", "gpio11", "gpio12", "gpio13",
++ "gpio14", "gpio15", "gpio16", "gpio17",
++ "gpio18", "gpio19", "gpio20", "gpio21",
++ "gpio22", "gpio23", "gpio24", "gpio25",
++ "gpio26", "gpio27";
++ bias-disable;
++ };
++ rp1_dpi_hvsync: rp1_dpi_hvsync { /* Sync only, for use with int VDAC */
++ function = "dpi";
++ pins = "gpio2", "gpio3";
++ bias-disable;
++ };
++
++ // More DPI mappings, including PIXCLK,DE on GPIOs 0,1
++ rp1_dpi_16bit_gpio0: rp1_dpi_16bit_gpio0 { /* Mode 2, not fully supported by RP1 */
++ function = "dpi";
++ pins = "gpio0", "gpio1", "gpio2", "gpio3",
++ "gpio4", "gpio5", "gpio6", "gpio7",
++ "gpio8", "gpio9", "gpio10", "gpio11",
++ "gpio12", "gpio13", "gpio14", "gpio15",
++ "gpio16", "gpio17", "gpio18", "gpio19";
++ bias-disable;
++ };
++ rp1_dpi_16bit_cpadhi_gpio0: rp1_dpi_16bit_cpadhi_gpio0 { /* Mode 3 */
++ function = "dpi";
++ pins = "gpio0", "gpio1", "gpio2", "gpio3",
++ "gpio4", "gpio5", "gpio6", "gpio7",
++ "gpio8",
++ "gpio12", "gpio13", "gpio14", "gpio15",
++ "gpio16", "gpio17",
++ "gpio20", "gpio21", "gpio22", "gpio23",
++ "gpio24";
++ bias-disable;
++ };
++ rp1_dpi_16bit_pad666_gpio0: rp1_dpi_16bit_pad666_gpio0 { /* Mode 4 */
++ function = "dpi";
++ pins = "gpio0", "gpio1", "gpio2", "gpio3",
++ "gpio5", "gpio6", "gpio7", "gpio8",
++ "gpio9",
++ "gpio12", "gpio13", "gpio14", "gpio15",
++ "gpio16", "gpio17",
++ "gpio21", "gpio22", "gpio23", "gpio24",
++ "gpio25";
++ bias-disable;
++ };
++ rp1_dpi_18bit_gpio0: rp1_dpi_18bit_gpio0 { /* Mode 5, not fully supported by RP1 */
++ function = "dpi";
++ pins = "gpio0", "gpio1", "gpio2", "gpio3",
++ "gpio4", "gpio5", "gpio6", "gpio7",
++ "gpio8", "gpio9", "gpio10", "gpio11",
++ "gpio12", "gpio13", "gpio14", "gpio15",
++ "gpio16", "gpio17", "gpio18", "gpio19",
++ "gpio20", "gpio21";
++ bias-disable;
++ };
++ rp1_dpi_18bit_cpadhi_gpio0: rp1_dpi_18bit_cpadhi_gpio0 { /* Mode 6 */
++ function = "dpi";
++ pins = "gpio0", "gpio1", "gpio2", "gpio3",
++ "gpio4", "gpio5", "gpio6", "gpio7",
++ "gpio8", "gpio9",
++ "gpio12", "gpio13", "gpio14", "gpio15",
++ "gpio16", "gpio17",
++ "gpio20", "gpio21", "gpio22", "gpio23",
++ "gpio24", "gpio25";
++ bias-disable;
++ };
++ rp1_dpi_24bit_gpio0: rp1_dpi_24bit_gpio0 { /* Mode 7 -- All GPIOs used! */
++ function = "dpi";
++ pins = "gpio0", "gpio1", "gpio2", "gpio3",
++ "gpio4", "gpio5", "gpio6", "gpio7",
++ "gpio8", "gpio9", "gpio10", "gpio11",
++ "gpio12", "gpio13", "gpio14", "gpio15",
++ "gpio16", "gpio17", "gpio18", "gpio19",
++ "gpio20", "gpio21", "gpio22", "gpio23",
++ "gpio24", "gpio25", "gpio26", "gpio27";
++ bias-disable;
++ };
++
++ rp1_gpclksrc0_gpio4: rp1_gpclksrc0_gpio4 {
++ function = "gpclk0";
++ pins = "gpio4";
++ bias-disable;
++ };
++
++ rp1_gpclksrc0_gpio20: rp1_gpclksrc0_gpio20 {
++ function = "gpclk0";
++ pins = "gpio20";
++ bias-disable;
++ };
++
++ rp1_gpclksrc1_gpio5: rp1_gpclksrc1_gpio5 {
++ function = "gpclk1";
++ pins = "gpio5";
++ bias-disable;
++ };
++
++ rp1_gpclksrc1_gpio18: rp1_gpclksrc1_gpio18 {
++ function = "gpclk1";
++ pins = "gpio18";
++ bias-disable;
++ };
++
++ rp1_gpclksrc1_gpio21: rp1_gpclksrc1_gpio21 {
++ function = "gpclk1";
++ pins = "gpio21";
++ bias-disable;
++ };
++
++ rp1_pwm1_gpio45: rp1_pwm1_gpio45 {
++ function = "pwm1";
++ pins = "gpio45";
++ bias-pull-down;
++ };
++
++ rp1_spi0_gpio9: rp1_spi0_gpio9 {
++ function = "spi0";
++ pins = "gpio9", "gpio10", "gpio11";
++ bias-disable;
++ drive-strength = <12>;
++ slew-rate = <1>;
++ };
++
++ rp1_spi0_cs_gpio7: rp1_spi0_cs_gpio7 {
++ function = "spi0";
++ pins = "gpio7", "gpio8";
++ bias-pull-up;
++ };
++
++ rp1_spi1_gpio19: rp1_spi1_gpio19 {
++ function = "spi1";
++ pins = "gpio19", "gpio20", "gpio21";
++ bias-disable;
++ drive-strength = <12>;
++ slew-rate = <1>;
++ };
++
++ rp1_spi2_gpio1: rp1_spi2_gpio1 {
++ function = "spi2";
++ pins = "gpio1", "gpio2", "gpio3";
++ bias-disable;
++ drive-strength = <12>;
++ slew-rate = <1>;
++ };
++
++ rp1_spi3_gpio5: rp1_spi3_gpio5 {
++ function = "spi3";
++ pins = "gpio5", "gpio6", "gpio7";
++ bias-disable;
++ drive-strength = <12>;
++ slew-rate = <1>;
++ };
++
++ rp1_spi4_gpio9: rp1_spi4_gpio9 {
++ function = "spi4";
++ pins = "gpio9", "gpio10", "gpio11";
++ bias-disable;
++ drive-strength = <12>;
++ slew-rate = <1>;
++ };
++
++ rp1_spi5_gpio13: rp1_spi5_gpio13 {
++ function = "spi5";
++ pins = "gpio13", "gpio14", "gpio15";
++ bias-disable;
++ drive-strength = <12>;
++ slew-rate = <1>;
++ };
++
++ rp1_spi8_gpio49: rp1_spi8_gpio49 {
++ function = "spi8";
++ pins = "gpio49", "gpio50", "gpio51";
++ bias-disable;
++ drive-strength = <12>;
++ slew-rate = <1>;
++ };
++
++ rp1_spi8_cs_gpio52: rp1_spi8_cs_gpio52 {
++ function = "spi0";
++ pins = "gpio52", "gpio53";
++ bias-pull-up;
++ };
++ };
++
++ rp1_eth: ethernet@100000 {
++ reg = <0xc0 0x40100000 0x0 0x4000>;
++ compatible = "cdns,macb";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ interrupts = <RP1_INT_ETH IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&macb_pclk &macb_hclk &rp1_clocks RP1_CLK_ETH_TSU>;
++ clock-names = "pclk", "hclk", "tsu_clk";
++ phy-mode = "rgmii-id";
++ cdns,aw2w-max-pipe = /bits/ 8 <8>;
++ cdns,ar2r-max-pipe = /bits/ 8 <8>;
++ cdns,use-aw2b-fill;
++ local-mac-address = [00 00 00 00 00 00];
++ status = "disabled";
++ };
++
++ rp1_csi0: csi@110000 {
++ compatible = "raspberrypi,rp1-cfe";
++ reg = <0xc0 0x40110000 0x0 0x100>, // CSI2 DMA address
++ <0xc0 0x40114000 0x0 0x100>, // PHY/CSI Host address
++ <0xc0 0x40120000 0x0 0x100>, // MIPI CFG address
++ <0xc0 0x40124000 0x0 0x1000>; // PiSP FE address
++
++ // interrupts must match rp1_pisp_fe setup
++ interrupts = <RP1_INT_MIPI0 IRQ_TYPE_LEVEL_HIGH>;
++
++ clocks = <&rp1_clocks RP1_CLK_MIPI0_CFG>;
++ assigned-clocks = <&rp1_clocks RP1_CLK_MIPI0_CFG>;
++ assigned-clock-rates = <25000000>;
++
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ rp1_csi1: csi@128000 {
++ compatible = "raspberrypi,rp1-cfe";
++ reg = <0xc0 0x40128000 0x0 0x100>, // CSI2 DMA address
++ <0xc0 0x4012c000 0x0 0x100>, // PHY/CSI Host address
++ <0xc0 0x40138000 0x0 0x100>, // MIPI CFG address
++ <0xc0 0x4013c000 0x0 0x1000>; // PiSP FE address
++
++ // interrupts must match rp1_pisp_fe setup
++ interrupts = <RP1_INT_MIPI1 IRQ_TYPE_LEVEL_HIGH>;
++
++ clocks = <&rp1_clocks RP1_CLK_MIPI1_CFG>;
++ assigned-clocks = <&rp1_clocks RP1_CLK_MIPI1_CFG>;
++ assigned-clock-rates = <25000000>;
++
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ rp1_mmc0: mmc@180000 {
++ reg = <0xc0 0x40180000 0x0 0x100>;
++ compatible = "raspberrypi,rp1-dwcmshc";
++ interrupts = <RP1_INT_SDIO0 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&rp1_clocks RP1_CLK_SYS &sdhci_core
++ &rp1_clocks RP1_CLK_SDIO_TIMER
++ &rp1_sdio_clk0>;
++ clock-names = "bus", "core", "timeout", "sdio";
++ /* Bank 0 VDDIO is fixed */
++ no-1-8-v;
++ bus-width = <4>;
++ vmmc-supply = <&rp1_vdd_3v3>;
++ broken-cd;
++ status = "disabled";
++ };
++
++ rp1_mmc1: mmc@184000 {
++ reg = <0xc0 0x40184000 0x0 0x100>;
++ compatible = "raspberrypi,rp1-dwcmshc";
++ interrupts = <RP1_INT_SDIO1 IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&rp1_clocks RP1_CLK_SYS &sdhci_core
++ &rp1_clocks RP1_CLK_SDIO_TIMER
++ &rp1_sdio_clk1>;
++ clock-names = "bus", "core", "timeout", "sdio";
++ bus-width = <4>;
++ vmmc-supply = <&rp1_vdd_3v3>;
++ /* Nerf SDR speeds */
++ sdhci-caps-mask = <0x3 0x0>;
++ broken-cd;
++ status = "disabled";
++ };
++
++ rp1_dma: dma@188000 {
++ reg = <0xc0 0x40188000 0x0 0x1000>;
++ compatible = "snps,axi-dma-1.01a";
++ interrupts = <RP1_INT_DMA IRQ_TYPE_LEVEL_HIGH>;
++ clocks = <&sdhci_core &rp1_clocks RP1_CLK_SYS>;
++ clock-names = "core-clk", "cfgr-clk";
++
++ #dma-cells = <1>;
++ dma-channels = <8>;
++ snps,dma-masters = <1>;
++ snps,dma-targets = <64>;
++ snps,data-width = <4>; // (8 << 4) == 128 bits
++ snps,block-size = <0x40000 0x40000 0x40000 0x40000 0x40000 0x40000 0x40000 0x40000>;
++ snps,priority = <0 1 2 3 4 5 6 7>;
++ snps,axi-max-burst-len = <8>;
++ status = "disabled";
++ };
++
++ rp1_usb0: usb@200000 {
++ reg = <0xc0 0x40200000 0x0 0x100000>;
++ compatible = "snps,dwc3";
++ dr_mode = "host";
++ usb3-lpm-capable;
++ snps,axi-pipe-limit = /bits/ 8 <8>;
++ snps,dis_rxdet_inp3_quirk;
++ snps,parkmode-disable-ss-quirk;
++ snps,parkmode-disable-hs-quirk;
++ snps,parkmode-disable-fsls-quirk;
++ snps,tx-max-burst = /bits/ 8 <8>;
++ snps,tx-thr-num-pkt = /bits/ 8 <2>;
++ interrupts = <RP1_INT_USBHOST0_0 IRQ_TYPE_EDGE_RISING>;
++ status = "disabled";
++ };
++
++ rp1_usb1: usb@300000 {
++ reg = <0xc0 0x40300000 0x0 0x100000>;
++ compatible = "snps,dwc3";
++ dr_mode = "host";
++ usb3-lpm-capable;
++ snps,axi-pipe-limit = /bits/ 8 <8>;
++ snps,dis_rxdet_inp3_quirk;
++ snps,parkmode-disable-ss-quirk;
++ snps,parkmode-disable-hs-quirk;
++ snps,parkmode-disable-fsls-quirk;
++ snps,tx-max-burst = /bits/ 8 <8>;
++ snps,tx-thr-num-pkt = /bits/ 8 <2>;
++ interrupts = <RP1_INT_USBHOST1_0 IRQ_TYPE_EDGE_RISING>;
++ status = "disabled";
++ };
++
++ rp1_dsi0: dsi@110000 {
++ compatible = "raspberrypi,rp1dsi";
++ status = "disabled";
++ reg = <0xc0 0x40118000 0x0 0x1000>, // MIPI0 DSI DMA (ArgonDPI)
++ <0xc0 0x4011c000 0x0 0x1000>, // MIPI0 DSI Host (SNPS)
++ <0xc0 0x40120000 0x0 0x1000>; // MIPI0 CFG
++
++ interrupts = <RP1_INT_MIPI0 IRQ_TYPE_LEVEL_HIGH>;
++
++ clocks = <&rp1_clocks RP1_CLK_MIPI0_CFG>,
++ <&rp1_clocks RP1_CLK_MIPI0_DPI>,
++ <&rp1_clocks RP1_CLK_MIPI0_DSI_BYTECLOCK>,
++ <&clk_xosc>, // hardwired to DSI "refclk"
++ <&rp1_clocks RP1_PLL_SYS>; // alternate parent for divide
++ clock-names = "cfgclk", "dpiclk", "byteclk", "refclk", "pllsys";
++
++ assigned-clocks = <&rp1_clocks RP1_CLK_MIPI0_CFG>;
++ assigned-clock-rates = <25000000>;
++ };
++
++ rp1_dsi1: dsi@128000 {
++ compatible = "raspberrypi,rp1dsi";
++ status = "disabled";
++ reg = <0xc0 0x40130000 0x0 0x1000>, // MIPI1 DSI DMA (ArgonDPI)
++ <0xc0 0x40134000 0x0 0x1000>, // MIPI1 DSI Host (SNPS)
++ <0xc0 0x40138000 0x0 0x1000>; // MIPI1 CFG
++
++ interrupts = <RP1_INT_MIPI1 IRQ_TYPE_LEVEL_HIGH>;
++
++ clocks = <&rp1_clocks RP1_CLK_MIPI1_CFG>,
++ <&rp1_clocks RP1_CLK_MIPI1_DPI>,
++ <&rp1_clocks RP1_CLK_MIPI1_DSI_BYTECLOCK>,
++ <&clk_xosc>, // hardwired to DSI "refclk"
++ <&rp1_clocks RP1_PLL_SYS>; // alternate parent for divide
++ clock-names = "cfgclk", "dpiclk", "byteclk", "refclk", "pllsys";
++
++ assigned-clocks = <&rp1_clocks RP1_CLK_MIPI1_CFG>;
++ assigned-clock-rates = <25000000>;
++ };
++
++ /* VEC and DPI both need to control PLL_VIDEO and cannot work together; */
++ /* config.txt should enable one or other using dtparam=vec or an overlay. */
++ rp1_vec: vec@144000 {
++ compatible = "raspberrypi,rp1vec";
++ status = "disabled";
++ reg = <0xc0 0x40144000 0x0 0x1000>, // VIDEO_OUT_VEC
++ <0xc0 0x40140000 0x0 0x1000>; // VIDEO_OUT_CFG
++
++ interrupts = <RP1_INT_VIDEO_OUT IRQ_TYPE_LEVEL_HIGH>;
++
++ clocks = <&rp1_clocks RP1_CLK_VEC>;
++
++ assigned-clocks = <&rp1_clocks RP1_PLL_VIDEO_CORE>,
++ <&rp1_clocks RP1_PLL_VIDEO_SEC>,
++ <&rp1_clocks RP1_CLK_VEC>;
++ assigned-clock-rates = <1188000000>,
++ <108000000>,
++ <108000000>;
++ assigned-clock-parents = <0>,
++ <&rp1_clocks RP1_PLL_VIDEO_CORE>,
++ <&rp1_clocks RP1_PLL_VIDEO_SEC>;
++ };
++
++ rp1_dpi: dpi@148000 {
++ compatible = "raspberrypi,rp1dpi";
++ status = "disabled";
++ reg = <0xc0 0x40148000 0x0 0x1000>, // VIDEO_OUT DPI
++ <0xc0 0x40140000 0x0 0x1000>; // VIDEO_OUT_CFG
++
++ interrupts = <RP1_INT_VIDEO_OUT IRQ_TYPE_LEVEL_HIGH>;
++
++ clocks = <&rp1_clocks RP1_CLK_DPI>, // DPI pixel clock
++ <&rp1_clocks RP1_PLL_VIDEO>, // PLL primary divider, and
++ <&rp1_clocks RP1_PLL_VIDEO_CORE>; // VCO, which we also control
++ clock-names = "dpiclk", "plldiv", "pllcore";
++
++ assigned-clocks = <&rp1_clocks RP1_CLK_DPI>;
++ assigned-clock-parents = <&rp1_clocks RP1_PLL_VIDEO>;
++ };
++ };
++};
++
++&clocks {
++ clk_xosc: clk_xosc {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-output-names = "xosc";
++ clock-frequency = <50000000>;
++ };
++ macb_pclk: macb_pclk {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-output-names = "pclk";
++ clock-frequency = <200000000>;
++ };
++ macb_hclk: macb_hclk {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-output-names = "hclk";
++ clock-frequency = <200000000>;
++ };
++ sdio_src: sdio_src {
++ // 400 MHz on FPGA. PLL sys VCO on asic
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-output-names = "src";
++ clock-frequency = <1000000000>;
++ };
++ sdhci_core: sdhci_core {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-output-names = "core";
++ clock-frequency = <50000000>;
++ };
++ /* GPIO derived clock sources. Each GPIO with a GPCLK function
++ * can drive its output from the respective GPCLK
++ * generator, and provide a clock source to other internal
++ * dividers. Add dummy sources here so that they can be overridden
++ * with overlays.
++ */
++ clksrc_gp0: clksrc_gp0 {
++ status = "disabled";
++ compatible = "fixed-factor-clock";
++ #clock-cells = <0>;
++ clock-div = <1>;
++ clock-mult = <1>;
++ clocks = <&rp1_clocks RP1_CLK_GP0>;
++ clock-output-names = "clksrc_gp0";
++ };
++ clksrc_gp1: clksrc_gp1 {
++ status = "disabled";
++ compatible = "fixed-factor-clock";
++ #clock-cells = <0>;
++ clock-div = <1>;
++ clock-mult = <1>;
++ clocks = <&rp1_clocks RP1_CLK_GP1>;
++ clock-output-names = "clksrc_gp1";
++ };
++ clksrc_gp2: clksrc_gp2 {
++ status = "disabled";
++ compatible = "fixed-factor-clock";
++ clock-div = <1>;
++ clock-mult = <1>;
++ #clock-cells = <0>;
++ clocks = <&rp1_clocks RP1_CLK_GP2>;
++ clock-output-names = "clksrc_gp2";
++ };
++ clksrc_gp3: clksrc_gp3 {
++ status = "disabled";
++ compatible = "fixed-factor-clock";
++ clock-div = <1>;
++ clock-mult = <1>;
++ #clock-cells = <0>;
++ clocks = <&rp1_clocks RP1_CLK_GP3>;
++ clock-output-names = "clksrc_gp3";
++ };
++ clksrc_gp4: clksrc_gp4 {
++ status = "disabled";
++ compatible = "fixed-factor-clock";
++ #clock-cells = <0>;
++ clock-div = <1>;
++ clock-mult = <1>;
++ clocks = <&rp1_clocks RP1_CLK_GP4>;
++ clock-output-names = "clksrc_gp4";
++ };
++ clksrc_gp5: clksrc_gp5 {
++ status = "disabled";
++ compatible = "fixed-factor-clock";
++ #clock-cells = <0>;
++ clock-div = <1>;
++ clock-mult = <1>;
++ clocks = <&rp1_clocks RP1_CLK_GP5>;
++ clock-output-names = "clksrc_gp5";
++ };
++};
++
++/ {
++ rp1_vdd_3v3: rp1_vdd_3v3 {
++ compatible = "regulator-fixed";
++ regulator-name = "vdd-3v3";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ regulator-always-on;
++ };
++};
diff --git a/target/linux/bcm27xx/patches-6.6/950-1181-arm64-dts-Add-cm5l-files.patch b/target/linux/bcm27xx/patches-6.6/950-1181-arm64-dts-Add-cm5l-files.patch
new file mode 100644
index 0000000000..4f0544386a
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1181-arm64-dts-Add-cm5l-files.patch
@@ -0,0 +1,92 @@
+From 4de4f56af7d803fa7dd9ffe42d4719b428d73e6c Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Wed, 17 Jul 2024 17:31:58 +0100
+Subject: [PATCH 1181/1215] arm64: dts: Add cm5l files
+
+CM5 Lite DTBs require minor changes compared to the "heavy" variants.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm64/boot/dts/broadcom/Makefile | 2 ++
+ .../dts/broadcom/bcm2712-rpi-cm5l-cm4io.dts | 20 ++++++++++++++++
+ .../dts/broadcom/bcm2712-rpi-cm5l-cm5io.dts | 10 ++++++++
+ .../boot/dts/broadcom/bcm2712-rpi-cm5l.dtsi | 24 +++++++++++++++++++
+ 4 files changed, 56 insertions(+)
+ create mode 100644 arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5l-cm4io.dts
+ create mode 100644 arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5l-cm5io.dts
+ create mode 100644 arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5l.dtsi
+
+--- a/arch/arm64/boot/dts/broadcom/Makefile
++++ b/arch/arm64/boot/dts/broadcom/Makefile
+@@ -24,6 +24,8 @@ dtb-$(CONFIG_ARCH_BCM2835) += bcm2712-rp
+ dtb-$(CONFIG_ARCH_BCM2835) += bcm2712d0-rpi-5-b.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
++dtb-$(CONFIG_ARCH_BCM2835) += bcm2712-rpi-cm5l-cm4io.dtb
+
+ subdir-y += bcmbca
+ subdir-y += northstar2
+--- /dev/null
++++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5l-cm4io.dts
+@@ -0,0 +1,20 @@
++// SPDX-License-Identifier: GPL-2.0
++/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";
++ };
++};
+--- /dev/null
++++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5l-cm5io.dts
+@@ -0,0 +1,10 @@
++// SPDX-License-Identifier: GPL-2.0
++/dts-v1/;
++
++#include "bcm2712-rpi-cm5l.dtsi"
++
++/ {
++ __overrides__ {
++ i2c_csi_dsi = <&i2c_csi_dsi>, "status";
++ };
++};
+--- /dev/null
++++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5l.dtsi
+@@ -0,0 +1,24 @@
++// SPDX-License-Identifier: GPL-2.0
++/dts-v1/;
++
++#include "bcm2712-rpi-cm5.dtsi"
++
++/ {
++ __overrides__ {
++ i2c_csi_dsi = <&i2c_csi_dsi>, "status";
++ };
++};
++
++&sd_io_1v8_reg {
++ compatible = "regulator-gpio";
++ regulator-max-microvolt = <3300000>;
++ regulator-settling-time-us = <5000>;
++ gpios = <&gio_aon 3 GPIO_ACTIVE_HIGH>;
++ states = <1800000 0x1
++ 3300000 0x0>;
++};
++
++&sdio1 {
++ /delete-property/ mmc-hs400-1_8v;
++ /delete-property/ mmc-hs400-enhanced-strobe;
++};
diff --git a/target/linux/bcm27xx/patches-6.6/950-1182-dts-bcm2712-Dedup-the-aliases-and-overrides.patch b/target/linux/bcm27xx/patches-6.6/950-1182-dts-bcm2712-Dedup-the-aliases-and-overrides.patch
new file mode 100644
index 0000000000..6cffbdd9be
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1182-dts-bcm2712-Dedup-the-aliases-and-overrides.patch
@@ -0,0 +1,408 @@
+From e1c56acf3355cd539447511fdc1b886e5eb5cca3 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Thu, 2 May 2024 16:57:31 +0100
+Subject: [PATCH 1182/1215] dts: bcm2712: Dedup the aliases and overrides
+
+Move the aliases and overrrides shared by Pi 5 and CM5 into
+bcm2712-rpi.dtsi.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ .../boot/dts/broadcom/bcm2712-rpi-5-b.dts | 115 -----------------
+ .../boot/dts/broadcom/bcm2712-rpi-cm5.dtsi | 114 -----------------
+ arch/arm64/boot/dts/broadcom/bcm2712-rpi.dtsi | 117 +++++++++++++++++-
+ 3 files changed, 113 insertions(+), 233 deletions(-)
+
+--- a/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts
++++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts
+@@ -746,122 +746,7 @@ spi10_cs_pins: &spi10_cs_gpio1 {};
+ };
+
+ / {
+- aliases: aliases {
+- blconfig = &blconfig;
+- blpubkey = &blpubkey;
+- bluetooth = &bluetooth;
+- console = &uart10;
+- ethernet0 = &rp1_eth;
+- wifi0 = &wifi;
+- fb = &fb;
+- mailbox = &mailbox;
+- mmc0 = &sdio1;
+- uart0 = &uart0;
+- uart1 = &uart1;
+- uart2 = &uart2;
+- uart3 = &uart3;
+- uart4 = &uart4;
+- uart10 = &uart10;
+- serial0 = &uart0;
+- serial1 = &uart1;
+- serial2 = &uart2;
+- serial3 = &uart3;
+- serial4 = &uart4;
+- serial10 = &uart10;
+- i2c = &i2c_arm;
+- i2c0 = &i2c0;
+- i2c1 = &i2c1;
+- i2c2 = &i2c2;
+- i2c3 = &i2c3;
+- i2c4 = &i2c4;
+- i2c5 = &i2c5;
+- i2c6 = &i2c6;
+- i2c10 = &i2c_rp1boot;
+- // Bit-bashed i2c_gpios start at 10
+- spi0 = &spi0;
+- spi1 = &spi1;
+- spi2 = &spi2;
+- spi3 = &spi3;
+- spi4 = &spi4;
+- spi5 = &spi5;
+- spi10 = &spi10;
+- gpio0 = &gpio;
+- gpio1 = &gio;
+- gpio2 = &gio_aon;
+- gpio3 = &pinctrl;
+- gpio4 = &pinctrl_aon;
+- usb0 = &rp1_usb0;
+- usb1 = &rp1_usb1;
+- drm-dsi1 = &dsi0;
+- drm-dsi2 = &dsi1;
+- };
+-
+ __overrides__ {
+- bdaddr = <&bluetooth>, "local-bd-address[";
+- button_debounce = <&pwr_key>, "debounce-interval:0";
+- cooling_fan = <&fan>, "status", <&rp1_pwm1>, "status";
+- uart0_console = <&uart0>,"status", <&aliases>, "console=",&uart0;
+- i2c0 = <&i2c0>, "status";
+- i2c1 = <&i2c1>, "status";
+- i2c = <&i2c1>, "status";
+- i2c_arm = <&i2c_arm>, "status";
+- i2c_vc = <&i2c_vc>, "status";
+- i2c_csi_dsi = <&i2c_csi_dsi>, "status";
+- i2c_csi_dsi0 = <&i2c_csi_dsi0>, "status";
+- i2c_csi_dsi1 = <&i2c_csi_dsi1>, "status";
+- i2c0_baudrate = <&i2c0>, "clock-frequency:0";
+- i2c1_baudrate = <&i2c1>, "clock-frequency:0";
+- i2c_baudrate = <&i2c_arm>, "clock-frequency:0";
+- i2c_arm_baudrate = <&i2c_arm>, "clock-frequency:0";
+- i2c_vc_baudrate = <&i2c_vc>, "clock-frequency:0";
+- krnbt = <&bluetooth>, "status";
+- nvme = <&pciex1>, "status";
+- pciex1 = <&pciex1>, "status";
+- pciex1_gen = <&pciex1> , "max-link-speed:0";
+- pciex1_no_l0s = <&pciex1>, "aspm-no-l0s?";
+- pciex1_tperst_clk_ms = <&pciex1>, "brcm,tperst-clk-ms:0";
+- pcie_tperst_clk_ms = <&pciex1>, "brcm,tperst-clk-ms:0";
+- random = <&random>, "status";
+- rtc = <&rpi_rtc>, "status";
+- rtc_bbat_vchg = <&rpi_rtc>, "trickle-charge-microvolt:0";
+ sd_cqe = <&sdio1>, "supports-cqe?";
+- spi = <&spi0>, "status";
+- suspend = <&pwr_key>, "linux,code:0=205";
+- uart0 = <&uart0>, "status";
+- wifiaddr = <&wifi>, "local-mac-address[";
+-
+- act_led_gpio = <&led_act>,"gpios:4",<&led_act>,"gpios:0=",<&gpio>;
+- act_led_activelow = <&led_act>,"gpios:8";
+- act_led_trigger = <&led_act>, "linux,default-trigger";
+- pwr_led_gpio = <&led_pwr>,"gpios:4";
+- pwr_led_activelow = <&led_pwr>, "gpios:8";
+- pwr_led_trigger = <&led_pwr>, "linux,default-trigger";
+- eth_led0 = <&phy1>,"led-modes:0";
+- eth_led1 = <&phy1>,"led-modes:4";
+- drm_fb0_rp1_dsi0 = <&aliases>, "drm-fb0=",&dsi0;
+- drm_fb0_rp1_dsi1 = <&aliases>, "drm-fb0=",&dsi1;
+- drm_fb0_rp1_dpi = <&aliases>, "drm-fb0=",&dpi;
+- drm_fb0_vc4 = <&aliases>, "drm-fb0=",&vc4;
+- drm_fb1_rp1_dsi0 = <&aliases>, "drm-fb1=",&dsi0;
+- drm_fb1_rp1_dsi1 = <&aliases>, "drm-fb1=",&dsi1;
+- drm_fb1_rp1_dpi = <&aliases>, "drm-fb1=",&dpi;
+- drm_fb1_vc4 = <&aliases>, "drm-fb1=",&vc4;
+- drm_fb2_rp1_dsi0 = <&aliases>, "drm-fb2=",&dsi0;
+- drm_fb2_rp1_dsi1 = <&aliases>, "drm-fb2=",&dsi1;
+- drm_fb2_rp1_dpi = <&aliases>, "drm-fb2=",&dpi;
+- drm_fb2_vc4 = <&aliases>, "drm-fb2=",&vc4;
+-
+- fan_temp0 = <&cpu_tepid>,"temperature:0";
+- fan_temp1 = <&cpu_warm>,"temperature:0";
+- fan_temp2 = <&cpu_hot>,"temperature:0";
+- fan_temp3 = <&cpu_vhot>,"temperature:0";
+- fan_temp0_hyst = <&cpu_tepid>,"hysteresis:0";
+- fan_temp1_hyst = <&cpu_warm>,"hysteresis:0";
+- fan_temp2_hyst = <&cpu_hot>,"hysteresis:0";
+- fan_temp3_hyst = <&cpu_vhot>,"hysteresis:0";
+- fan_temp0_speed = <&fan>, "cooling-levels:4";
+- fan_temp1_speed = <&fan>, "cooling-levels:8";
+- fan_temp2_speed = <&fan>, "cooling-levels:12";
+- fan_temp3_speed = <&fan>, "cooling-levels:16";
+ };
+ };
+--- a/arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5.dtsi
++++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5.dtsi
+@@ -753,108 +753,7 @@ spi10_cs_pins: &spi10_cs_gpio1 {};
+ };
+
+ / {
+- aliases: aliases {
+- blconfig = &blconfig;
+- blpubkey = &blpubkey;
+- bluetooth = &bluetooth;
+- console = &uart10;
+- ethernet0 = &rp1_eth;
+- wifi0 = &wifi;
+- fb = &fb;
+- mailbox = &mailbox;
+- mmc0 = &sdio1;
+- uart0 = &uart0;
+- uart1 = &uart1;
+- uart2 = &uart2;
+- uart3 = &uart3;
+- uart4 = &uart4;
+- uart10 = &uart10;
+- serial0 = &uart0;
+- serial1 = &uart1;
+- serial2 = &uart2;
+- serial3 = &uart3;
+- serial4 = &uart4;
+- serial10 = &uart10;
+- i2c = &i2c_arm;
+- i2c0 = &i2c0;
+- i2c1 = &i2c1;
+- i2c2 = &i2c2;
+- i2c3 = &i2c3;
+- i2c4 = &i2c4;
+- i2c5 = &i2c5;
+- i2c6 = &i2c6;
+- i2c10 = &i2c_rp1boot;
+- // Bit-bashed i2c_gpios start at 10
+- spi0 = &spi0;
+- spi1 = &spi1;
+- spi2 = &spi2;
+- spi3 = &spi3;
+- spi4 = &spi4;
+- spi5 = &spi5;
+- spi10 = &spi10;
+- gpio0 = &gpio;
+- gpio1 = &gio;
+- gpio2 = &gio_aon;
+- gpio3 = &pinctrl;
+- gpio4 = &pinctrl_aon;
+- usb0 = &rp1_usb0;
+- usb1 = &rp1_usb1;
+- drm-dsi1 = &dsi0;
+- drm-dsi2 = &dsi1;
+- };
+-
+ __overrides__ {
+- bdaddr = <&bluetooth>, "local-bd-address[";
+- button_debounce = <&pwr_key>, "debounce-interval:0";
+- cooling_fan = <&fan>, "status", <&rp1_pwm1>, "status";
+- uart0_console = <&uart0>,"status", <&aliases>, "console=",&uart0;
+- i2c0 = <&i2c0>, "status";
+- i2c1 = <&i2c1>, "status";
+- i2c = <&i2c1>, "status";
+- i2c_arm = <&i2c_arm>, "status";
+- i2c_vc = <&i2c_vc>, "status";
+- i2c_csi_dsi = <&i2c_csi_dsi>, "status";
+- i2c_csi_dsi0 = <&i2c_csi_dsi0>, "status";
+- i2c_csi_dsi1 = <&i2c_csi_dsi1>, "status";
+- i2c0_baudrate = <&i2c0>, "clock-frequency:0";
+- i2c1_baudrate = <&i2c1>, "clock-frequency:0";
+- i2c_baudrate = <&i2c_arm>, "clock-frequency:0";
+- i2c_arm_baudrate = <&i2c_arm>, "clock-frequency:0";
+- i2c_vc_baudrate = <&i2c_vc>, "clock-frequency:0";
+- krnbt = <&bluetooth>, "status";
+- nvme = <&pciex1>, "status";
+- pciex1 = <&pciex1>, "status";
+- pciex1_gen = <&pciex1> , "max-link-speed:0";
+- pciex1_no_l0s = <&pciex1>, "aspm-no-l0s?";
+- pciex1_tperst_clk_ms = <&pciex1>, "brcm,tperst-clk-ms:0";
+- pcie_tperst_clk_ms = <&pciex1>, "brcm,tperst-clk-ms:0";
+- random = <&random>, "status";
+- rtc = <&rpi_rtc>, "status";
+- rtc_bbat_vchg = <&rpi_rtc>, "trickle-charge-microvolt:0";
+- spi = <&spi0>, "status";
+- suspend = <&pwr_key>, "linux,code:0=205";
+- uart0 = <&uart0>, "status";
+- wifiaddr = <&wifi>, "local-mac-address[";
+-
+- act_led_activelow = <&led_act>, "active-low?";
+- act_led_trigger = <&led_act>, "linux,default-trigger";
+- pwr_led_activelow = <&led_pwr>, "gpios:8";
+- pwr_led_trigger = <&led_pwr>, "linux,default-trigger";
+- eth_led0 = <&phy1>,"led-modes:0";
+- eth_led1 = <&phy1>,"led-modes:4";
+- drm_fb0_rp1_dsi0 = <&aliases>, "drm-fb0=",&dsi0;
+- drm_fb0_rp1_dsi1 = <&aliases>, "drm-fb0=",&dsi1;
+- drm_fb0_rp1_dpi = <&aliases>, "drm-fb0=",&dpi;
+- drm_fb0_vc4 = <&aliases>, "drm-fb0=",&vc4;
+- drm_fb1_rp1_dsi0 = <&aliases>, "drm-fb1=",&dsi0;
+- drm_fb1_rp1_dsi1 = <&aliases>, "drm-fb1=",&dsi1;
+- drm_fb1_rp1_dpi = <&aliases>, "drm-fb1=",&dpi;
+- drm_fb1_vc4 = <&aliases>, "drm-fb1=",&vc4;
+- drm_fb2_rp1_dsi0 = <&aliases>, "drm-fb2=",&dsi0;
+- drm_fb2_rp1_dsi1 = <&aliases>, "drm-fb2=",&dsi1;
+- drm_fb2_rp1_dpi = <&aliases>, "drm-fb2=",&dpi;
+- drm_fb2_vc4 = <&aliases>, "drm-fb2=",&vc4;
+-
+ ant1 = <&ant1>,"output-high?=on",
+ <&ant1>, "output-low?=off",
+ <&ant2>, "output-high?=off",
+@@ -867,18 +766,5 @@ spi10_cs_pins: &spi10_cs_gpio1 {};
+ <&ant1>, "output-low?=on",
+ <&ant2>, "output-high?=off",
+ <&ant2>, "output-low?=on";
+-
+- fan_temp0 = <&cpu_tepid>,"temperature:0";
+- fan_temp1 = <&cpu_warm>,"temperature:0";
+- fan_temp2 = <&cpu_hot>,"temperature:0";
+- fan_temp3 = <&cpu_vhot>,"temperature:0";
+- fan_temp0_hyst = <&cpu_tepid>,"hysteresis:0";
+- fan_temp1_hyst = <&cpu_warm>,"hysteresis:0";
+- fan_temp2_hyst = <&cpu_hot>,"hysteresis:0";
+- fan_temp3_hyst = <&cpu_vhot>,"hysteresis:0";
+- fan_temp0_speed = <&fan>, "cooling-levels:4";
+- fan_temp1_speed = <&fan>, "cooling-levels:8";
+- fan_temp2_speed = <&fan>, "cooling-levels:12";
+- fan_temp3_speed = <&fan>, "cooling-levels:16";
+ };
+ };
+--- a/arch/arm64/boot/dts/broadcom/bcm2712-rpi.dtsi
++++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi.dtsi
+@@ -98,14 +98,124 @@
+ };
+
+ / {
++ aliases: aliases {
++ blconfig = &blconfig;
++ blpubkey = &blpubkey;
++ bluetooth = &bluetooth;
++ console = &uart10;
++ drm-dsi1 = &dsi0;
++ drm-dsi2 = &dsi1;
++ ethernet0 = &rp1_eth;
++ fb = &fb;
++ gpio0 = &gpio;
++ gpio1 = &gio;
++ gpio2 = &gio_aon;
++ gpio3 = &pinctrl;
++ gpio4 = &pinctrl_aon;
++ i2c = &i2c_arm;
++ i2c0 = &i2c0;
++ i2c1 = &i2c1;
++ i2c10 = &i2c_rp1boot;
++ i2c2 = &i2c2;
++ i2c3 = &i2c3;
++ i2c4 = &i2c4;
++ i2c5 = &i2c5;
++ i2c6 = &i2c6;
++ mailbox = &mailbox;
++ mmc0 = &sdio1;
++ serial0 = &uart0;
++ serial1 = &uart1;
++ serial10 = &uart10;
++ serial2 = &uart2;
++ serial3 = &uart3;
++ serial4 = &uart4;
++ spi0 = &spi0;
++ spi1 = &spi1;
++ spi10 = &spi10;
++ spi2 = &spi2;
++ spi3 = &spi3;
++ spi4 = &spi4;
++ spi5 = &spi5;
++ uart0 = &uart0;
++ uart1 = &uart1;
++ uart10 = &uart10;
++ uart2 = &uart2;
++ uart3 = &uart3;
++ uart4 = &uart4;
++ usb0 = &rp1_usb0;
++ usb1 = &rp1_usb1;
++ wifi0 = &wifi;
++ };
++
+ __overrides__ {
+- arm_freq;
++ act_led_gpio = <&led_act>,"gpios:4",<&led_act>,"gpios:0=",<&gpio>;
++ act_led_activelow = <&led_act>, "gpios:8";
++ act_led_trigger = <&led_act>, "linux,default-trigger";
+ axiperf = <&axiperf>,"status";
+-
++ bdaddr = <&bluetooth>, "local-bd-address[";
++ button_debounce = <&pwr_key>, "debounce-interval:0";
++ cooling_fan = <&fan>, "status", <&rp1_pwm1>, "status";
++ drm_fb0_rp1_dpi = <&aliases>, "drm-fb0=",&dpi;
++ drm_fb0_rp1_dsi0 = <&aliases>, "drm-fb0=",&dsi0;
++ drm_fb0_rp1_dsi1 = <&aliases>, "drm-fb0=",&dsi1;
++ drm_fb0_vc4 = <&aliases>, "drm-fb0=",&vc4;
++ drm_fb1_rp1_dpi = <&aliases>, "drm-fb1=",&dpi;
++ drm_fb1_rp1_dsi0 = <&aliases>, "drm-fb1=",&dsi0;
++ drm_fb1_rp1_dsi1 = <&aliases>, "drm-fb1=",&dsi1;
++ drm_fb1_vc4 = <&aliases>, "drm-fb1=",&vc4;
++ drm_fb2_rp1_dpi = <&aliases>, "drm-fb2=",&dpi;
++ drm_fb2_rp1_dsi0 = <&aliases>, "drm-fb2=",&dsi0;
++ drm_fb2_rp1_dsi1 = <&aliases>, "drm-fb2=",&dsi1;
++ drm_fb2_vc4 = <&aliases>, "drm-fb2=",&vc4;
++ eth_led0 = <&phy1>,"led-modes:0";
++ eth_led1 = <&phy1>,"led-modes:4";
++ fan_temp0 = <&cpu_tepid>,"temperature:0";
++ fan_temp0_hyst = <&cpu_tepid>,"hysteresis:0";
++ fan_temp0_speed = <&fan>, "cooling-levels:4";
++ fan_temp1 = <&cpu_warm>,"temperature:0";
++ fan_temp1_hyst = <&cpu_warm>,"hysteresis:0";
++ fan_temp1_speed = <&fan>, "cooling-levels:8";
++ fan_temp2 = <&cpu_hot>,"temperature:0";
++ fan_temp2_hyst = <&cpu_hot>,"hysteresis:0";
++ fan_temp2_speed = <&fan>, "cooling-levels:12";
++ fan_temp3 = <&cpu_vhot>,"temperature:0";
++ fan_temp3_hyst = <&cpu_vhot>,"hysteresis:0";
++ fan_temp3_speed = <&fan>, "cooling-levels:16";
++ i2c = <&i2c1>, "status";
++ i2c_arm = <&i2c_arm>, "status";
++ i2c_arm_baudrate = <&i2c_arm>, "clock-frequency:0";
++ i2c_baudrate = <&i2c_arm>, "clock-frequency:0";
++ i2c_csi_dsi = <&i2c_csi_dsi>, "status";
++ i2c_csi_dsi0 = <&i2c_csi_dsi0>, "status";
++ i2c_csi_dsi1 = <&i2c_csi_dsi1>, "status";
++ i2c_vc = <&i2c_vc>, "status";
++ i2c_vc_baudrate = <&i2c_vc>, "clock-frequency:0";
++ i2c0 = <&i2c0>, "status";
++ i2c0_baudrate = <&i2c0>, "clock-frequency:0";
++ i2c1 = <&i2c1>, "status";
++ i2c1_baudrate = <&i2c1>, "clock-frequency:0";
++ krnbt = <&bluetooth>, "status";
++ nvme = <&pciex1>, "status";
+ nvmem_cust_rw = <&nvmem_cust>,"rw?";
+- nvmem_priv_rw = <&nvmem_priv>,"rw?";
+ nvmem_mac_rw = <&nvmem_mac>,"rw?";
++ nvmem_priv_rw = <&nvmem_priv>,"rw?";
++ pcie_tperst_clk_ms = <&pciex1>, "brcm,tperst-clk-ms:0";
++ pciex1 = <&pciex1>, "status";
++ pciex1_gen = <&pciex1> , "max-link-speed:0";
++ pciex1_no_l0s = <&pciex1>, "aspm-no-l0s?";
++ pciex1_tperst_clk_ms = <&pciex1>, "brcm,tperst-clk-ms:0";
++ pwr_led_gpio = <&led_pwr>, "gpios:4";
++ pwr_led_activelow = <&led_pwr>, "gpios:8";
++ pwr_led_trigger = <&led_pwr>, "linux,default-trigger";
++ random = <&random>, "status";
++ rtc = <&rpi_rtc>, "status";
++ rtc_bbat_vchg = <&rpi_rtc>, "trickle-charge-microvolt:0";
++ spi = <&spi0>, "status";
+ strict_gpiod = <&chosen>, "bootargs=pinctrl_rp1.persist_gpio_outputs=n";
++ suspend = <&pwr_key>, "linux,code:0=205";
++ uart0 = <&uart0>, "status";
++ uart0_console = <&uart0>,"status", <&aliases>, "console=",&uart0;
++ wifiaddr = <&wifi>, "local-mac-address[";
+
+ cam0_reg = <&cam0_reg>,"status";
+ cam0_reg_gpio = <&cam0_reg>,"gpio:4",
+@@ -113,7 +223,6 @@
+ cam1_reg = <&cam1_reg>,"status";
+ cam1_reg_gpio = <&cam1_reg>,"gpio:4",
+ <&cam1_reg>,"gpio:0=", <&gpio>;
+-
+ };
+ };
+
diff --git a/target/linux/bcm27xx/patches-6.6/950-1183-arm64-dts-Give-cm5l-its-own-model-name.patch b/target/linux/bcm27xx/patches-6.6/950-1183-arm64-dts-Give-cm5l-its-own-model-name.patch
new file mode 100644
index 0000000000..72279e130c
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1183-arm64-dts-Give-cm5l-its-own-model-name.patch
@@ -0,0 +1,24 @@
+From ad110e5ff36de6096e1b9d7e0fe125326f45ed7d Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Fri, 19 Jul 2024 13:18:47 +0100
+Subject: [PATCH 1183/1215] arm64: dts: Give cm5l its own model name
+
+The bootloader patches the DT with the correct model string, but it
+is better not to rely on that by setting it from the start.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5l.dtsi | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5l.dtsi
++++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-cm5l.dtsi
+@@ -4,6 +4,8 @@
+ #include "bcm2712-rpi-cm5.dtsi"
+
+ / {
++ model = "Raspberry Pi Compute Module 5 Lite";
++
+ __overrides__ {
+ i2c_csi_dsi = <&i2c_csi_dsi>, "status";
+ };
diff --git a/target/linux/bcm27xx/patches-6.6/950-1185-pinctrl-rp1-jump-through-hoops-to-avoid-PCIe-latency.patch b/target/linux/bcm27xx/patches-6.6/950-1185-pinctrl-rp1-jump-through-hoops-to-avoid-PCIe-latency.patch
new file mode 100644
index 0000000000..fecfb7a200
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1185-pinctrl-rp1-jump-through-hoops-to-avoid-PCIe-latency.patch
@@ -0,0 +1,288 @@
+From d24229dcef58e0162780ceffa02eb5f6a01b9a4d Mon Sep 17 00:00:00 2001
+From: Jonathan Bell <jonathan@raspberrypi.com>
+Date: Tue, 16 Jul 2024 16:47:08 +0100
+Subject: [PATCH 1185/1215] pinctrl: rp1: jump through hoops to avoid PCIe
+ latency issues
+
+Automatic link power saving plus the ability of a root complex to buffer
+pending posted write transfers (and consider them complete before being
+transmitted on the wire) causes compression of updates to GPIO state.
+
+The large bandwidth of a Gen 2 x4 link means the writes toggle state
+inside RP1 as fast as it can go (~20MHz), which is bad for applications
+wanting bitbash with at least a few microseconds of delay between
+updates.
+
+By tailoring IO access patterns to a special Root Complex register,
+writes to GPIOs can be stalled until the link wakes - meaning all writes
+end up with a reasonably consistent minimum pacing (~200ns).
+
+Additionally, write barriers have no effect other than to arbitrarily
+delay some writes by a small, variable amount - so remove the vast
+majority of these in areas that could be hot-paths.
+
+Although the IO memory is mapped with Device strongly-ordered semantics,
+this doesn't prevent the splitter inside BCM2712 from letting an MMIO
+read request to a GPIO register get ahead of the pacing writes to the
+Root Complex register. So each pin state read must flush writes out to
+the Outer-Shareable domain.
+
+Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
+---
+ drivers/pinctrl/pinctrl-rp1.c | 120 +++++++++++++++++++++++++++++-----
+ 1 file changed, 105 insertions(+), 15 deletions(-)
+
+--- a/drivers/pinctrl/pinctrl-rp1.c
++++ b/drivers/pinctrl/pinctrl-rp1.c
+@@ -197,6 +197,7 @@ struct rp1_pin_info {
+ void __iomem *inte;
+ void __iomem *ints;
+ void __iomem *pad;
++ void __iomem *dummy;
+ };
+
+ enum funcs {
+@@ -276,6 +277,7 @@ struct rp1_pinctrl {
+ void __iomem *gpio_base;
+ void __iomem *rio_base;
+ void __iomem *pads_base;
++ void __iomem *dummy_base;
+ int irq[RP1_NUM_BANKS];
+ struct rp1_pin_info pins[RP1_NUM_GPIOS];
+
+@@ -577,6 +579,42 @@ static bool persist_gpio_outputs = true;
+ module_param(persist_gpio_outputs, bool, 0644);
+ MODULE_PARM_DESC(persist_gpio_outputs, "Enable GPIO_OUT persistence when pin is freed");
+
++static bool pace_pin_updates = true;
++module_param(pace_pin_updates, bool, 0644);
++MODULE_PARM_DESC(pace_pin_updates, "Update pin states with guaranteed monotonicity if PCIe ASPM is enabled");
++
++static inline void rp1_pin_writel(u32 val, void __iomem *dummy, void __iomem *reg)
++{
++ unsigned long flags;
++
++ local_irq_save(flags);
++ /*
++ * Issuing 6 pipelined writes to the RC's Slot Control register will stall the
++ * peripheral bus inside 2712 if the link is in L1. This acts as a lightweight
++ * "fence" operation preventing back-to-back writes arriving at RP1 on a wake.
++ */
++ if (dummy) {
++ writel_relaxed(0, dummy);
++ writel_relaxed(0, dummy);
++ writel_relaxed(0, dummy);
++ writel_relaxed(0, dummy);
++ writel_relaxed(0, dummy);
++ writel_relaxed(0, dummy);
++ }
++ writel_relaxed(val, reg);
++ local_irq_restore(flags);
++}
++
++static inline u32 rp1_pin_readl(const void __iomem *ioaddr)
++{
++ /*
++ * Prior posted writes may not yet have been emitted by the CPU - do a store-flush
++ * before reading GPIO state, as this will serialise writes versus the next issued read.
++ */
++ __dma_wmb();
++ return readl(ioaddr);
++}
++
+ static int rp1_pinconf_set(struct pinctrl_dev *pctldev,
+ unsigned int offset, unsigned long *configs,
+ unsigned int num_configs);
+@@ -603,12 +641,12 @@ static struct rp1_pin_info *rp1_get_pin_
+
+ static void rp1_pad_update(struct rp1_pin_info *pin, u32 clr, u32 set)
+ {
+- u32 padctrl = readl(pin->pad);
++ u32 padctrl = rp1_pin_readl(pin->pad);
+
+ padctrl &= ~clr;
+ padctrl |= set;
+
+- writel(padctrl, pin->pad);
++ rp1_pin_writel(padctrl, pin->dummy, pin->pad);
+ }
+
+ static void rp1_input_enable(struct rp1_pin_info *pin, int value)
+@@ -625,7 +663,7 @@ static void rp1_output_enable(struct rp1
+
+ static u32 rp1_get_fsel(struct rp1_pin_info *pin)
+ {
+- u32 ctrl = readl(pin->gpio + RP1_GPIO_CTRL);
++ u32 ctrl = rp1_pin_readl(pin->gpio + RP1_GPIO_CTRL);
+ u32 oeover = FLD_GET(ctrl, RP1_GPIO_CTRL_OEOVER);
+ u32 fsel = FLD_GET(ctrl, RP1_GPIO_CTRL_FUNCSEL);
+
+@@ -637,7 +675,7 @@ static u32 rp1_get_fsel(struct rp1_pin_i
+
+ static void rp1_set_fsel(struct rp1_pin_info *pin, u32 fsel)
+ {
+- u32 ctrl = readl(pin->gpio + RP1_GPIO_CTRL);
++ u32 ctrl = rp1_pin_readl(pin->gpio + RP1_GPIO_CTRL);
+
+ if (fsel >= RP1_FSEL_COUNT)
+ fsel = RP1_FSEL_NONE_HW;
+@@ -652,12 +690,12 @@ static void rp1_set_fsel(struct rp1_pin_
+ FLD_SET(ctrl, RP1_GPIO_CTRL_OEOVER, RP1_OEOVER_PERI);
+ }
+ FLD_SET(ctrl, RP1_GPIO_CTRL_FUNCSEL, fsel);
+- writel(ctrl, pin->gpio + RP1_GPIO_CTRL);
++ rp1_pin_writel(ctrl, pin->dummy, pin->gpio + RP1_GPIO_CTRL);
+ }
+
+ static int rp1_get_dir(struct rp1_pin_info *pin)
+ {
+- return !(readl(pin->rio + RP1_RIO_OE) & (1 << pin->offset)) ?
++ return !(rp1_pin_readl(pin->rio + RP1_RIO_OE) & (1 << pin->offset)) ?
+ RP1_DIR_INPUT : RP1_DIR_OUTPUT;
+ }
+
+@@ -665,19 +703,19 @@ static void rp1_set_dir(struct rp1_pin_i
+ {
+ int offset = is_input ? RP1_CLR_OFFSET : RP1_SET_OFFSET;
+
+- writel(1 << pin->offset, pin->rio + RP1_RIO_OE + offset);
++ rp1_pin_writel(1 << pin->offset, pin->dummy, pin->rio + RP1_RIO_OE + offset);
+ }
+
+ static int rp1_get_value(struct rp1_pin_info *pin)
+ {
+- return !!(readl(pin->rio + RP1_RIO_IN) & (1 << pin->offset));
++ return !!(rp1_pin_readl(pin->rio + RP1_RIO_IN) & (1 << pin->offset));
+ }
+
+ static void rp1_set_value(struct rp1_pin_info *pin, int value)
+ {
+ /* Assume the pin is already an output */
+- writel(1 << pin->offset,
+- pin->rio + RP1_RIO_OUT + (value ? RP1_SET_OFFSET : RP1_CLR_OFFSET));
++ rp1_pin_writel(1 << pin->offset, pin->dummy,
++ pin->rio + RP1_RIO_OUT + (value ? RP1_SET_OFFSET : RP1_CLR_OFFSET));
+ }
+
+ static int rp1_gpio_get(struct gpio_chip *chip, unsigned offset)
+@@ -1298,7 +1336,7 @@ static const struct pinmux_ops rp1_pmx_o
+
+ static void rp1_pull_config_set(struct rp1_pin_info *pin, unsigned int arg)
+ {
+- u32 padctrl = readl(pin->pad);
++ u32 padctrl = rp1_pin_readl(pin->pad);
+
+ FLD_SET(padctrl, RP1_PAD_PULL, arg & 0x3);
+
+@@ -1398,7 +1436,7 @@ static int rp1_pinconf_get(struct pinctr
+ if (!pin)
+ return -EINVAL;
+
+- padctrl = readl(pin->pad);
++ padctrl = rp1_pin_readl(pin->pad);
+
+ switch (param) {
+ case PIN_CONFIG_INPUT_ENABLE:
+@@ -1493,6 +1531,7 @@ static int rp1_pinctrl_probe(struct plat
+ {
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
++ struct device_node *rp1_node = NULL;
+ struct rp1_pinctrl *pc;
+ struct gpio_irq_chip *girq;
+ int err, i;
+@@ -1528,6 +1567,40 @@ static int rp1_pinctrl_probe(struct plat
+ pc->gpio_chip = rp1_gpio_chip;
+ pc->gpio_chip.parent = dev;
+
++ /*
++ * Workaround for the vagaries of PCIe on BCM2712
++ *
++ * If the link to RP1 is in L1, then the BRCMSTB RC will buffer many
++ * outbound writes - and generate write responses for them, despite the
++ * fact that the link is not yet active. This has the effect of compressing
++ * multiple writes to GPIOs together, destroying any pacing that an application
++ * may require in the 1-10us range.
++ *
++ * The RC Slot Control configuration register is special. It emits a
++ * MsgD for every write to it, will stall further writes until the message
++ * goes out on the wire. This can be (ab)used to force CPU stalls when the
++ * link is inactive, at the cost of a small amount of downstream bandwidth
++ * and some 200ns of added latency for each write.
++ *
++ * Several back-to-back configuration writes are necessary to "fill the pipe",
++ * otherwise the outbound MAC can consume a pending MMIO write and reorder
++ * it with respect to the config writes - undoing the intent.
++ *
++ * of_iomap() is used directly here as the address overlaps with the RC driver's
++ * usage.
++ */
++ rp1_node = of_find_node_by_name(NULL, "rp1");
++ if (!rp1_node)
++ dev_err(&pdev->dev, "failed to find RP1 DT node\n");
++ else if (pace_pin_updates &&
++ of_device_is_compatible(rp1_node->parent, "brcm,bcm2712-pcie")) {
++ pc->dummy_base = of_iomap(rp1_node->parent, 0);
++ if (IS_ERR(pc->dummy_base)) {
++ dev_warn(&pdev->dev, "could not map bcm2712 root complex registers\n");
++ pc->dummy_base = NULL;
++ }
++ }
++
+ for (i = 0; i < RP1_NUM_BANKS; i++) {
+ const struct rp1_iobank_desc *bank = &rp1_iobanks[i];
+ int j;
+@@ -1547,14 +1620,17 @@ static int rp1_pinctrl_probe(struct plat
+ pin->rio = pc->rio_base + bank->rio_offset;
+ pin->pad = pc->pads_base + bank->pads_offset +
+ j * sizeof(u32);
++ pin->dummy = pc->dummy_base ? pc->dummy_base + 0xc0 : NULL;
+ }
+
+ raw_spin_lock_init(&pc->irq_lock[i]);
+ }
+
+ pc->pctl_dev = devm_pinctrl_register(dev, &rp1_pinctrl_desc, pc);
+- if (IS_ERR(pc->pctl_dev))
+- return PTR_ERR(pc->pctl_dev);
++ if (IS_ERR(pc->pctl_dev)) {
++ err = PTR_ERR(pc->pctl_dev);
++ goto out_iounmap;
++ }
+
+ girq = &pc->gpio_chip.irq;
+ girq->chip = &rp1_gpio_irq_chip;
+@@ -1583,7 +1659,7 @@ static int rp1_pinctrl_probe(struct plat
+ err = devm_gpiochip_add_data(dev, &pc->gpio_chip, pc);
+ if (err) {
+ dev_err(dev, "could not add GPIO chip\n");
+- return err;
++ goto out_iounmap;
+ }
+
+ pc->gpio_range = rp1_pinctrl_gpio_range;
+@@ -1592,10 +1668,24 @@ static int rp1_pinctrl_probe(struct plat
+ pinctrl_add_gpio_range(pc->pctl_dev, &pc->gpio_range);
+
+ return 0;
++
++out_iounmap:
++ if (pc->dummy_base)
++ iounmap(pc->dummy_base);
++ return err;
++}
++
++static void rp1_pinctrl_remove(struct platform_device *pdev)
++{
++ struct rp1_pinctrl *pc = platform_get_drvdata(pdev);
++
++ if (pc->dummy_base)
++ iounmap(pc->dummy_base);
+ }
+
+ static struct platform_driver rp1_pinctrl_driver = {
+ .probe = rp1_pinctrl_probe,
++ .remove_new = rp1_pinctrl_remove,
+ .driver = {
+ .name = MODULE_NAME,
+ .of_match_table = rp1_pinctrl_match,
diff --git a/target/linux/bcm27xx/patches-6.6/950-1186-staging-bcm2835-codec-Disable-HEADER_ON_OPEN-for-vid.patch b/target/linux/bcm27xx/patches-6.6/950-1186-staging-bcm2835-codec-Disable-HEADER_ON_OPEN-for-vid.patch
new file mode 100644
index 0000000000..a8fbeaf062
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1186-staging-bcm2835-codec-Disable-HEADER_ON_OPEN-for-vid.patch
@@ -0,0 +1,36 @@
+From 43fa967811484afde0bbbee182ff8f29dc0550c2 Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Fri, 5 Jul 2024 15:57:25 +0100
+Subject: [PATCH 1186/1215] staging: bcm2835-codec: Disable HEADER_ON_OPEN for
+ video encode
+
+Video encode can defer generating the header until the first
+frame is presented, which allows it to take the colourspace
+information from the frame rather than just the format.
+
+Enable that for the V4L2 driver now that the firmware populates
+all the parameters.
+
+https://github.com/raspberrypi/firmware/issues/1885
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ .../vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c
++++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c
+@@ -2731,6 +2731,13 @@ static int bcm2835_codec_create_componen
+ &params,
+ sizeof(params));
+
++ } else if (dev->role == ENCODE) {
++ enable = 0;
++ vchiq_mmal_port_parameter_set(dev->instance,
++ &ctx->component->control,
++ MMAL_PARAMETER_VIDEO_ENCODE_HEADER_ON_OPEN,
++ &enable,
++ sizeof(enable));
+ } else if (dev->role == ENCODE_IMAGE) {
+ enable = 0;
+ vchiq_mmal_port_parameter_set(dev->instance,
diff --git a/target/linux/bcm27xx/patches-6.6/950-1188-staging-bcm2835-codec-Add-support-for-H264-level-5.0.patch b/target/linux/bcm27xx/patches-6.6/950-1188-staging-bcm2835-codec-Add-support-for-H264-level-5.0.patch
new file mode 100644
index 0000000000..f3c53adf50
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1188-staging-bcm2835-codec-Add-support-for-H264-level-5.0.patch
@@ -0,0 +1,36 @@
+From 31b9871b8895d7931ee88d7cda7861f829b21d63 Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Wed, 17 Jul 2024 16:59:08 +0100
+Subject: [PATCH 1188/1215] staging: bcm2835-codec: Add support for H264 level
+ 5.0 and 5.1
+
+We do NOT claim to support decoding in real-time for these levels,
+but can transcode some content, and handle 1920x1200.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ .../vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c | 6 ++++--
+ 1 file changed, 4 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
+@@ -3273,7 +3273,7 @@ static void dec_add_profile_ctrls(struct
+ case V4L2_PIX_FMT_H264:
+ ctrl = v4l2_ctrl_new_std_menu(hdl, &bcm2835_codec_ctrl_ops,
+ V4L2_CID_MPEG_VIDEO_H264_LEVEL,
+- V4L2_MPEG_VIDEO_H264_LEVEL_4_2,
++ V4L2_MPEG_VIDEO_H264_LEVEL_5_1,
+ ~(BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_0) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1B) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_1) |
+@@ -3287,7 +3287,9 @@ static void dec_add_profile_ctrls(struct
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_2) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_0) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_1) |
+- BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_2)),
++ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_2) |
++ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_0) |
++ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_1)),
+ V4L2_MPEG_VIDEO_H264_LEVEL_4_0);
+ ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+ ctrl = v4l2_ctrl_new_std_menu(hdl, &bcm2835_codec_ctrl_ops,
diff --git a/target/linux/bcm27xx/patches-6.6/950-1189-spi-dw-Save-bandwidth-with-the-TMOD_TO-feature.patch b/target/linux/bcm27xx/patches-6.6/950-1189-spi-dw-Save-bandwidth-with-the-TMOD_TO-feature.patch
new file mode 100644
index 0000000000..66ff22eb7f
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1189-spi-dw-Save-bandwidth-with-the-TMOD_TO-feature.patch
@@ -0,0 +1,66 @@
+From 6014649de765a8a1f95c146ca72214ff0ba4ba89 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Mon, 1 Jul 2024 15:49:14 +0100
+Subject: [PATCH 1189/1215] spi: dw: Save bandwidth with the TMOD_TO feature
+
+TMOD_TO is the transmit-only mode that doesn't put data into the receive
+FIFO. Using TMOD_TO when the user doesn't want the received data saves
+CPU time and memory bandwidth.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ drivers/spi/spi-dw-core.c | 27 +++++++++++++++++----------
+ 1 file changed, 17 insertions(+), 10 deletions(-)
+
+--- a/drivers/spi/spi-dw-core.c
++++ b/drivers/spi/spi-dw-core.c
+@@ -225,12 +225,17 @@ static irqreturn_t dw_spi_transfer_handl
+ * final stage of the transfer. By doing so we'll get the next IRQ
+ * right when the leftover incoming data is received.
+ */
+- dw_reader(dws);
+- if (!dws->rx_len) {
+- dw_spi_mask_intr(dws, 0xff);
++ if (dws->rx_len) {
++ dw_reader(dws);
++ if (!dws->rx_len) {
++ dw_spi_mask_intr(dws, 0xff);
++ spi_finalize_current_transfer(dws->host);
++ } else if (dws->rx_len <= dw_readl(dws, DW_SPI_RXFTLR)) {
++ dw_writel(dws, DW_SPI_RXFTLR, dws->rx_len - 1);
++ }
++ } else if (!dws->tx_len) {
++ dw_spi_mask_intr(dws, DW_SPI_INT_TXEI);
+ spi_finalize_current_transfer(dws->host);
+- } else if (dws->rx_len <= dw_readl(dws, DW_SPI_RXFTLR)) {
+- dw_writel(dws, DW_SPI_RXFTLR, dws->rx_len - 1);
+ }
+
+ /*
+@@ -239,12 +244,9 @@ static irqreturn_t dw_spi_transfer_handl
+ * have the TXE IRQ flood at the final stage of the transfer.
+ */
+ if (irq_status & DW_SPI_INT_TXEI) {
+- dw_writer(dws);
+- if (!dws->tx_len) {
++ if (!dws->tx_len)
+ dw_spi_mask_intr(dws, DW_SPI_INT_TXEI);
+- if (!dws->rx_len)
+- spi_finalize_current_transfer(dws->host);
+- }
++ dw_writer(dws);
+ }
+
+ return IRQ_HANDLED;
+@@ -437,6 +439,11 @@ static int dw_spi_transfer_one(struct sp
+ dws->rx = transfer->rx_buf;
+ dws->rx_len = dws->tx_len;
+
++ if (!dws->rx) {
++ dws->rx_len = 0;
++ cfg.tmode = DW_SPI_CTRLR0_TMOD_TO;
++ }
++
+ /* Ensure the data above is visible for all CPUs */
+ smp_mb();
+
diff --git a/target/linux/bcm27xx/patches-6.6/950-1190-spi-dw-Save-bandwidth-with-the-TMOD_RO-feature.patch b/target/linux/bcm27xx/patches-6.6/950-1190-spi-dw-Save-bandwidth-with-the-TMOD_RO-feature.patch
new file mode 100644
index 0000000000..7791b99b6d
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1190-spi-dw-Save-bandwidth-with-the-TMOD_RO-feature.patch
@@ -0,0 +1,186 @@
+From cd9084ceb606a2f06c3429c2d3beae2d7c3ebd23 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Mon, 1 Jul 2024 16:41:04 +0100
+Subject: [PATCH 1190/1215] spi: dw: Save bandwidth with the TMOD_RO feature
+
+TMOD_RO is the receive-only mode that doesn't require data in the
+transmit FIFO in order to generate clock cycles. Using TMOD_RO when the
+device doesn't care about the data sent to it saves CPU time and memory
+bandwidth.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ drivers/spi/spi-dw-core.c | 31 +++++++++++++++++++++-------
+ drivers/spi/spi-dw-dma.c | 43 +++++++++++++++++++++++++--------------
+ 2 files changed, 52 insertions(+), 22 deletions(-)
+
+--- a/drivers/spi/spi-dw-core.c
++++ b/drivers/spi/spi-dw-core.c
+@@ -367,18 +367,18 @@ static void dw_spi_irq_setup(struct dw_s
+ * will be adjusted at the final stage of the IRQ-based SPI transfer
+ * execution so not to lose the leftover of the incoming data.
+ */
+- level = min_t(unsigned int, dws->fifo_len / 2, dws->tx_len);
++ level = min_t(unsigned int, dws->fifo_len / 2, dws->tx_len ? dws->tx_len : dws->rx_len);
+ dw_writel(dws, DW_SPI_TXFTLR, level);
+ dw_writel(dws, DW_SPI_RXFTLR, level - 1);
+
+ dws->transfer_handler = dw_spi_transfer_handler;
+
+- imask = 0;
+- if (dws->tx_len)
+- imask |= DW_SPI_INT_TXEI | DW_SPI_INT_TXOI;
++ imask = DW_SPI_INT_TXEI | DW_SPI_INT_TXOI;
+ if (dws->rx_len)
+ imask |= DW_SPI_INT_RXUI | DW_SPI_INT_RXOI | DW_SPI_INT_RXFI;
+ dw_spi_umask_intr(dws, imask);
++ if (!dws->tx_len)
++ dw_writel(dws, DW_SPI_DR, 0);
+ }
+
+ /*
+@@ -401,13 +401,18 @@ static int dw_spi_poll_transfer(struct d
+ delay.unit = SPI_DELAY_UNIT_SCK;
+ nbits = dws->n_bytes * BITS_PER_BYTE;
+
++ if (!dws->tx_len)
++ dw_writel(dws, DW_SPI_DR, 0);
++
+ do {
+- dw_writer(dws);
++ if (dws->tx_len)
++ dw_writer(dws);
+
+ delay.value = nbits * (dws->rx_len - dws->tx_len);
+ spi_delay_exec(&delay, transfer);
+
+- dw_reader(dws);
++ if (dws->rx_len)
++ dw_reader(dws);
+
+ ret = dw_spi_check_status(dws, true);
+ if (ret)
+@@ -427,6 +432,7 @@ static int dw_spi_transfer_one(struct sp
+ .dfs = transfer->bits_per_word,
+ .freq = transfer->speed_hz,
+ };
++ int buswidth;
+ int ret;
+
+ dws->dma_mapped = 0;
+@@ -444,6 +450,18 @@ static int dw_spi_transfer_one(struct sp
+ cfg.tmode = DW_SPI_CTRLR0_TMOD_TO;
+ }
+
++ if (!dws->rx) {
++ dws->rx_len = 0;
++ cfg.tmode = DW_SPI_CTRLR0_TMOD_TO;
++ }
++ if (!dws->tx) {
++ dws->tx_len = 0;
++ cfg.tmode = DW_SPI_CTRLR0_TMOD_RO;
++ cfg.ndf = dws->rx_len;
++ }
++ buswidth = transfer->rx_buf ? transfer->rx_nbits :
++ (transfer->tx_buf ? transfer->tx_nbits : 1);
++
+ /* Ensure the data above is visible for all CPUs */
+ smp_mb();
+
+@@ -961,7 +979,6 @@ int dw_spi_add_host(struct device *dev,
+ dev_warn(dev, "DMA init failed\n");
+ } else {
+ host->can_dma = dws->dma_ops->can_dma;
+- host->flags |= SPI_CONTROLLER_MUST_TX;
+ }
+ }
+
+--- a/drivers/spi/spi-dw-dma.c
++++ b/drivers/spi/spi-dw-dma.c
+@@ -6,6 +6,7 @@
+ */
+
+ #include <linux/completion.h>
++#include <linux/delay.h>
+ #include <linux/dma-mapping.h>
+ #include <linux/dmaengine.h>
+ #include <linux/irqreturn.h>
+@@ -470,13 +471,12 @@ static int dw_spi_dma_setup(struct dw_sp
+ u16 imr, dma_ctrl;
+ int ret;
+
+- if (!xfer->tx_buf)
+- return -EINVAL;
+-
+ /* Setup DMA channels */
+- ret = dw_spi_dma_config_tx(dws);
+- if (ret)
+- return ret;
++ if (xfer->tx_buf) {
++ ret = dw_spi_dma_config_tx(dws);
++ if (ret)
++ return ret;
++ }
+
+ if (xfer->rx_buf) {
+ ret = dw_spi_dma_config_rx(dws);
+@@ -485,13 +485,17 @@ static int dw_spi_dma_setup(struct dw_sp
+ }
+
+ /* Set the DMA handshaking interface */
+- dma_ctrl = DW_SPI_DMACR_TDMAE;
++ dma_ctrl = 0;
++ if (xfer->tx_buf)
++ dma_ctrl |= DW_SPI_DMACR_TDMAE;
+ if (xfer->rx_buf)
+ dma_ctrl |= DW_SPI_DMACR_RDMAE;
+ dw_writel(dws, DW_SPI_DMACR, dma_ctrl);
+
+ /* Set the interrupt mask */
+- imr = DW_SPI_INT_TXOI;
++ imr = 0;
++ if (xfer->tx_buf)
++ imr |= DW_SPI_INT_TXOI;
+ if (xfer->rx_buf)
+ imr |= DW_SPI_INT_RXUI | DW_SPI_INT_RXOI;
+ dw_spi_umask_intr(dws, imr);
+@@ -508,15 +512,16 @@ static int dw_spi_dma_transfer_all(struc
+ {
+ int ret;
+
+- /* Submit the DMA Tx transfer */
+- ret = dw_spi_dma_submit_tx(dws, xfer->tx_sg.sgl, xfer->tx_sg.nents);
+- if (ret)
+- goto err_clear_dmac;
++ /* Submit the DMA Tx transfer if required */
++ if (xfer->tx_buf) {
++ ret = dw_spi_dma_submit_tx(dws, xfer->tx_sg.sgl, xfer->tx_sg.nents);
++ if (ret)
++ goto err_clear_dmac;
++ }
+
+ /* Submit the DMA Rx transfer if required */
+ if (xfer->rx_buf) {
+- ret = dw_spi_dma_submit_rx(dws, xfer->rx_sg.sgl,
+- xfer->rx_sg.nents);
++ ret = dw_spi_dma_submit_rx(dws, xfer->rx_sg.sgl, xfer->rx_sg.nents);
+ if (ret)
+ goto err_clear_dmac;
+
+@@ -524,7 +529,15 @@ static int dw_spi_dma_transfer_all(struc
+ dma_async_issue_pending(dws->rxchan);
+ }
+
+- dma_async_issue_pending(dws->txchan);
++ if (xfer->tx_buf) {
++ dma_async_issue_pending(dws->txchan);
++ } else {
++ /* Pause to allow DMA channel to fetch RX descriptor */
++ usleep_range(5, 10);
++
++ /* Write something to the TX FIFO to start the transfer */
++ dw_writel(dws, DW_SPI_DR, 0);
++ }
+
+ ret = dw_spi_dma_wait(dws, xfer->len, xfer->effective_speed_hz);
+
diff --git a/target/linux/bcm27xx/patches-6.6/950-1191-spi-dw-don-t-immediately-kill-DMA-transfers-if-an-er.patch b/target/linux/bcm27xx/patches-6.6/950-1191-spi-dw-don-t-immediately-kill-DMA-transfers-if-an-er.patch
new file mode 100644
index 0000000000..45400204c4
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1191-spi-dw-don-t-immediately-kill-DMA-transfers-if-an-er.patch
@@ -0,0 +1,41 @@
+From 3af7822df36e36b5a74d877df7654695c0e0d34a Mon Sep 17 00:00:00 2001
+From: Jonathan Bell <jonathan@raspberrypi.com>
+Date: Mon, 22 Jul 2024 15:27:51 +0100
+Subject: [PATCH 1191/1215] spi: dw: don't immediately kill DMA transfers if an
+ error occurs
+
+Disabling the peripheral resets controller state which has a dangerous
+side-effect of disabling the DMA handshake interface while it is active.
+This can cause DMA channels to hang.
+
+The error recovery pathway will wait for DMA to stop and reset the chip
+anyway, so mask further FIFO interrupts and let the transfer finish
+gracefully.
+
+Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
+---
+ drivers/spi/spi-dw-core.c | 13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+--- a/drivers/spi/spi-dw-core.c
++++ b/drivers/spi/spi-dw-core.c
+@@ -200,7 +200,18 @@ int dw_spi_check_status(struct dw_spi *d
+
+ /* Generically handle the erroneous situation */
+ if (ret) {
+- dw_spi_reset_chip(dws);
++ /*
++ * Forcibly halting the controller can cause DMA to hang.
++ * Defer to dw_spi_handle_err outside of interrupt context
++ * and mask further interrupts for the current transfer.
++ */
++ if (dws->dma_mapped) {
++ dw_spi_mask_intr(dws, 0xff);
++ dw_readl(dws, DW_SPI_ICR);
++ } else {
++ dw_spi_reset_chip(dws);
++ }
++
+ if (dws->host->cur_msg)
+ dws->host->cur_msg->status = ret;
+ }
diff --git a/target/linux/bcm27xx/patches-6.6/950-1192-dts-rp1-hobble-DMA-AXI-burst-lengths.patch b/target/linux/bcm27xx/patches-6.6/950-1192-dts-rp1-hobble-DMA-AXI-burst-lengths.patch
new file mode 100644
index 0000000000..9cfdefec7d
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1192-dts-rp1-hobble-DMA-AXI-burst-lengths.patch
@@ -0,0 +1,35 @@
+From 4c1a665b465fa0e9d3369a467fc563ec812a47ce Mon Sep 17 00:00:00 2001
+From: Jonathan Bell <jonathan@raspberrypi.com>
+Date: Fri, 19 Jul 2024 13:07:59 +0100
+Subject: [PATCH 1192/1215] dts: rp1: hobble DMA AXI burst lengths
+
+Channels 1-2 have a statically configured maximum MSIZE of 8, and
+channels 3-8 have MSIZE set to 4. The DMAC "helpfully" silently
+truncates bursts to the hardware supported maximum, so any FIFO read
+operation with an oversized burst threshold will leave a residue of
+threshold minus MSIZE rows.
+
+As channel allocation is dynamic, this means every client needs to use a
+maximum of 4 for burst length.
+
+AXI AWLEN/ARLEN constraints aren't strictly related to MSIZE, except
+that bursts won't be issued that are longer than MSIZE beats. Therefore,
+it's a useful proxy to tell clients of the DMAC the hardware
+limitations.
+
+Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
+---
+ arch/arm64/boot/dts/broadcom/rp1.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/arm64/boot/dts/broadcom/rp1.dtsi
++++ b/arch/arm64/boot/dts/broadcom/rp1.dtsi
+@@ -1064,7 +1064,7 @@
+ snps,data-width = <4>; // (8 << 4) == 128 bits
+ snps,block-size = <0x40000 0x40000 0x40000 0x40000 0x40000 0x40000 0x40000 0x40000>;
+ snps,priority = <0 1 2 3 4 5 6 7>;
+- snps,axi-max-burst-len = <8>;
++ snps,axi-max-burst-len = <4>;
+ status = "disabled";
+ };
+
diff --git a/target/linux/bcm27xx/patches-6.6/950-1193-drivers-dw-axi-dmac-make-more-sensible-choices-about.patch b/target/linux/bcm27xx/patches-6.6/950-1193-drivers-dw-axi-dmac-make-more-sensible-choices-about.patch
new file mode 100644
index 0000000000..d336532f46
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1193-drivers-dw-axi-dmac-make-more-sensible-choices-about.patch
@@ -0,0 +1,124 @@
+From ce56098eb4dc2985f27f30ad7b7f5aed6bcf7fb1 Mon Sep 17 00:00:00 2001
+From: Jonathan Bell <jonathan@raspberrypi.com>
+Date: Fri, 19 Jul 2024 15:55:56 +0100
+Subject: [PATCH 1193/1215] drivers: dw-axi-dmac: make more sensible choices
+ about memory accesses
+
+There's no real need to constrain MEM access widths to 32-bit (or
+narrower), as the DMAC is intelligent enough to size memory accesses
+appropriately. Wider accesses are more efficient.
+
+Similarly, MEM burst lengths don't need to be a function of DEV burst
+lengths - the DMAC packs/unpacks data into/from its internal channel
+FIFOs appropriately. Longer accesses are more efficient.
+
+However, the DMAC doesn't have complete support for unaligned accesses,
+and blocks are always defined in integer multiples of SRC_WIDTH, so odd
+source lengths or buffer alignments will prevent wide accesses being
+used, as before.
+
+There is an implicit requirement to limit requested DEV read burst
+lengths to less than the hardware's maximum configured MSIZE - otherwise
+RX data will be left over at the end of a block. There is no config
+register that reports this value, so the AXI burst length parameter is
+used to produce a facsimile of it. Warn if such a request arrives that
+doesn't respect this.
+
+Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
+---
+ .../dma/dw-axi-dmac/dw-axi-dmac-platform.c | 38 ++++++++++++-------
+ 1 file changed, 25 insertions(+), 13 deletions(-)
+
+--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
++++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+@@ -261,6 +261,15 @@ static u32 axi_chan_get_xfer_width(struc
+ return __ffs(src | dst | len | BIT(max_width));
+ }
+
++static u32 axi_dma_encode_msize(u32 max_burst)
++{
++ if (max_burst <= 1)
++ return DWAXIDMAC_BURST_TRANS_LEN_1;
++ if (max_burst > 1024)
++ return DWAXIDMAC_BURST_TRANS_LEN_1024;
++ return fls(max_burst) - 2;
++}
++
+ static inline const char *axi_chan_name(struct axi_dma_chan *chan)
+ {
+ return dma_chan_name(&chan->vc.chan);
+@@ -685,41 +694,41 @@ static int dw_axi_dma_set_hw_desc(struct
+ size_t axi_block_ts;
+ size_t block_ts;
+ u32 ctllo, ctlhi;
+- u32 burst_len;
++ u32 burst_len = 0, mem_burst_msize, reg_burst_msize;
+
+ axi_block_ts = chan->chip->dw->hdata->block_size[chan->id];
+
+ mem_width = __ffs(data_width | mem_addr | len);
+- if (mem_width > DWAXIDMAC_TRANS_WIDTH_32)
+- mem_width = DWAXIDMAC_TRANS_WIDTH_32;
+
+ if (!IS_ALIGNED(mem_addr, 4)) {
+ dev_err(chan->chip->dev, "invalid buffer alignment\n");
+ return -EINVAL;
+ }
+
++ /* Use a reasonable upper limit otherwise residue reporting granularity grows large */
++ mem_burst_msize = axi_dma_encode_msize(16);
++
+ switch (chan->direction) {
+ case DMA_MEM_TO_DEV:
++ reg_burst_msize = axi_dma_encode_msize(chan->config.dst_maxburst);
+ reg_width = __ffs(chan->config.dst_addr_width);
+ device_addr = phys_to_dma(chan->chip->dev, chan->config.dst_addr);
+ ctllo = reg_width << CH_CTL_L_DST_WIDTH_POS |
+ mem_width << CH_CTL_L_SRC_WIDTH_POS |
+- DWAXIDMAC_BURST_TRANS_LEN_1 << CH_CTL_L_DST_MSIZE_POS |
+- DWAXIDMAC_BURST_TRANS_LEN_4 << CH_CTL_L_SRC_MSIZE_POS |
++ reg_burst_msize << CH_CTL_L_DST_MSIZE_POS |
++ mem_burst_msize << CH_CTL_L_SRC_MSIZE_POS |
+ DWAXIDMAC_CH_CTL_L_NOINC << CH_CTL_L_DST_INC_POS |
+ DWAXIDMAC_CH_CTL_L_INC << CH_CTL_L_SRC_INC_POS;
+ block_ts = len >> mem_width;
+ break;
+ case DMA_DEV_TO_MEM:
++ reg_burst_msize = axi_dma_encode_msize(chan->config.src_maxburst);
+ reg_width = __ffs(chan->config.src_addr_width);
+- /* Prevent partial access units getting lost */
+- if (mem_width > reg_width)
+- mem_width = reg_width;
+ device_addr = phys_to_dma(chan->chip->dev, chan->config.src_addr);
+ ctllo = reg_width << CH_CTL_L_SRC_WIDTH_POS |
+ mem_width << CH_CTL_L_DST_WIDTH_POS |
+- DWAXIDMAC_BURST_TRANS_LEN_4 << CH_CTL_L_DST_MSIZE_POS |
+- DWAXIDMAC_BURST_TRANS_LEN_1 << CH_CTL_L_SRC_MSIZE_POS |
++ mem_burst_msize << CH_CTL_L_DST_MSIZE_POS |
++ reg_burst_msize << CH_CTL_L_SRC_MSIZE_POS |
+ DWAXIDMAC_CH_CTL_L_INC << CH_CTL_L_DST_INC_POS |
+ DWAXIDMAC_CH_CTL_L_NOINC << CH_CTL_L_SRC_INC_POS;
+ block_ts = len >> reg_width;
+@@ -760,6 +769,12 @@ static int dw_axi_dma_set_hw_desc(struct
+ set_desc_src_master(hw_desc);
+
+ hw_desc->len = len;
++
++ if (burst_len && (chan->config.src_maxburst > burst_len))
++ dev_warn_ratelimited(chan2dev(chan),
++ "%s: requested source burst length %u exceeds supported burst length %u - data may be lost\n",
++ axi_chan_name(chan), chan->config.src_maxburst, burst_len);
++
+ return 0;
+ }
+
+@@ -776,9 +791,6 @@ static size_t calculate_block_len(struct
+ case DMA_MEM_TO_DEV:
+ data_width = BIT(chan->chip->dw->hdata->m_data_width);
+ mem_width = __ffs(data_width | dma_addr | buf_len);
+- if (mem_width > DWAXIDMAC_TRANS_WIDTH_32)
+- mem_width = DWAXIDMAC_TRANS_WIDTH_32;
+-
+ block_len = axi_block_ts << mem_width;
+ break;
+ case DMA_DEV_TO_MEM:
diff --git a/target/linux/bcm27xx/patches-6.6/950-1195-tty-serial-pl011-restrict-RX-burst-FIFO-threshold.patch b/target/linux/bcm27xx/patches-6.6/950-1195-tty-serial-pl011-restrict-RX-burst-FIFO-threshold.patch
new file mode 100644
index 0000000000..62731aeb34
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1195-tty-serial-pl011-restrict-RX-burst-FIFO-threshold.patch
@@ -0,0 +1,30 @@
+From f3cb675102a2a5a330038c4e748f02b02cec989e Mon Sep 17 00:00:00 2001
+From: Jonathan Bell <jonathan@raspberrypi.com>
+Date: Mon, 22 Jul 2024 09:30:54 +0100
+Subject: [PATCH 1195/1215] tty/serial: pl011: restrict RX burst FIFO threshold
+
+If the associated DMA controller has lower burst length support than the
+level the FIFO is set to, then bytes will be left in the RX FIFO at the
+end of a DMA block - requiring a round-trip through the timeout interrupt
+handler rather than an end-of-block DMA interrupt.
+
+Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
+---
+ drivers/tty/serial/amba-pl011.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/tty/serial/amba-pl011.c
++++ b/drivers/tty/serial/amba-pl011.c
+@@ -487,6 +487,12 @@ static void pl011_dma_probe(struct uart_
+ "RX DMA disabled - no residue processing\n");
+ return;
+ }
++ /*
++ * DMA controllers with smaller burst capabilities than 1/4
++ * the FIFO depth will leave more bytes than expected in the
++ * RX FIFO if mismatched.
++ */
++ rx_conf.src_maxburst = min(caps.max_burst, rx_conf.src_maxburst);
+ }
+ dmaengine_slave_config(chan, &rx_conf);
+ uap->dmarx.chan = chan;
diff --git a/target/linux/bcm27xx/patches-6.6/950-1196-DT-bindings-add-a-dma-maxburst-property-to-snps-desi.patch b/target/linux/bcm27xx/patches-6.6/950-1196-DT-bindings-add-a-dma-maxburst-property-to-snps-desi.patch
new file mode 100644
index 0000000000..0d0afc2f9c
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1196-DT-bindings-add-a-dma-maxburst-property-to-snps-desi.patch
@@ -0,0 +1,27 @@
+From 5112fd8cce4f1dc9bf43f0f90d35e273e1a0f555 Mon Sep 17 00:00:00 2001
+From: Jonathan Bell <jonathan@raspberrypi.com>
+Date: Mon, 22 Jul 2024 14:32:32 +0100
+Subject: [PATCH 1196/1215] DT: bindings: add a dma-maxburst property to
+ snps,designware-i2s
+
+Do an end-run around ASoC in lieu of not being able to easily find the
+associated DMA controller capabilities.
+
+Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
+---
+ .../devicetree/bindings/sound/snps,designware-i2s.yaml | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/Documentation/devicetree/bindings/sound/snps,designware-i2s.yaml
++++ b/Documentation/devicetree/bindings/sound/snps,designware-i2s.yaml
+@@ -69,6 +69,10 @@ properties:
+ - description: RX DMA Channel
+ minItems: 1
+
++ dma-maxburst:
++ description: FIFO DMA burst threshold limit
++ maxItems: 1
++
+ dma-names:
+ items:
+ - const: tx
diff --git a/target/linux/bcm27xx/patches-6.6/950-1197-sound-soc-dwc-i2s-choose-FIFO-thresholds-based-on-DM.patch b/target/linux/bcm27xx/patches-6.6/950-1197-sound-soc-dwc-i2s-choose-FIFO-thresholds-based-on-DM.patch
new file mode 100644
index 0000000000..d0e3bc1fab
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1197-sound-soc-dwc-i2s-choose-FIFO-thresholds-based-on-DM.patch
@@ -0,0 +1,99 @@
+From b6b4260fa546d1dc7421c7cfed059052dae04227 Mon Sep 17 00:00:00 2001
+From: Jonathan Bell <jonathan@raspberrypi.com>
+Date: Thu, 18 Jul 2024 09:40:03 +0100
+Subject: [PATCH 1197/1215] sound/soc: dwc-i2s: choose FIFO thresholds based on
+ DMA burst constraints
+
+Valid ranges for the I2S peripheral's FIFO configuration include a depth
+of 16 - unconditionally setting the burst length to 16 with a fifo
+threshold of size/2 will cause under/overflows.
+
+For DMA engines with restricted capabilities the requested burst length
+and FIFO thresholds need to be adjusted downward accordingly.
+
+Both the RX and TX FIFOs operate on "less-than" thresholds. Setting the
+TX threshold to fifo_size minus burst means the FIFO is kept nearly-full.
+
+Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
+---
+ sound/soc/dwc/dwc-i2s.c | 21 ++++++++++++++++-----
+ sound/soc/dwc/local.h | 1 +
+ 2 files changed, 17 insertions(+), 5 deletions(-)
+
+--- a/sound/soc/dwc/dwc-i2s.c
++++ b/sound/soc/dwc/dwc-i2s.c
+@@ -236,6 +236,8 @@ static void dw_i2s_config(struct dw_i2s_
+ u32 ch_reg;
+ struct i2s_clk_config_data *config = &dev->config;
+ u32 dmacr;
++ u32 comp1 = i2s_read_reg(dev->i2s_base, dev->i2s_reg_comp1);
++ u32 fifo_depth = 1 << (1 + COMP1_FIFO_DEPTH_GLOBAL(comp1));
+
+ i2s_disable_channels(dev, stream);
+
+@@ -251,7 +253,7 @@ static void dw_i2s_config(struct dw_i2s_
+ i2s_write_reg(dev->i2s_base, TCR(ch_reg),
+ dev->xfer_resolution);
+ i2s_write_reg(dev->i2s_base, TFCR(ch_reg),
+- dev->fifo_th - 1);
++ fifo_depth - dev->fifo_th - 1);
+ i2s_write_reg(dev->i2s_base, TER(ch_reg), TER_TXCHEN |
+ dev->tdm_mask << TER_TXSLOT_SHIFT);
+ dmacr |= (DMACR_DMAEN_TXCH0 << ch_reg);
+@@ -783,8 +785,8 @@ static int dw_configure_dai_by_pd(struct
+ dev->capture_dma_data.pd.data = pdata->capture_dma_data;
+ dev->play_dma_data.pd.addr = res->start + I2S_TXDMA;
+ dev->capture_dma_data.pd.addr = res->start + I2S_RXDMA;
+- dev->play_dma_data.pd.max_burst = 16;
+- dev->capture_dma_data.pd.max_burst = 16;
++ dev->play_dma_data.pd.max_burst = dev->fifo_th;
++ dev->capture_dma_data.pd.max_burst = dev->fifo_th;
+ dev->play_dma_data.pd.addr_width = bus_widths[idx];
+ dev->capture_dma_data.pd.addr_width = bus_widths[idx];
+ dev->play_dma_data.pd.filter = pdata->filter;
+@@ -815,7 +817,10 @@ static int dw_configure_dai_by_dt(struct
+ dev->play_dma_data.dt.addr = res->start + I2S_TXDMA;
+ dev->play_dma_data.dt.fifo_size = fifo_depth *
+ (fifo_width[idx2]) >> 8;
+- dev->play_dma_data.dt.maxburst = 16;
++ if (dev->max_dma_burst)
++ dev->play_dma_data.dt.maxburst = dev->max_dma_burst;
++ else
++ dev->play_dma_data.dt.maxburst = fifo_depth / 2;
+ }
+ if (COMP1_RX_ENABLED(comp1)) {
+ idx2 = COMP2_RX_WORDSIZE_0(comp2);
+@@ -824,9 +829,14 @@ static int dw_configure_dai_by_dt(struct
+ dev->capture_dma_data.dt.addr = res->start + I2S_RXDMA;
+ dev->capture_dma_data.dt.fifo_size = fifo_depth *
+ (fifo_width[idx2] >> 8);
+- dev->capture_dma_data.dt.maxburst = 16;
++ if (dev->max_dma_burst)
++ dev->capture_dma_data.dt.maxburst = dev->max_dma_burst;
++ else
++ dev->capture_dma_data.dt.maxburst = fifo_depth / 2;
+ }
+
++ if (dev->max_dma_burst)
++ dev->fifo_th = min(dev->max_dma_burst, dev->fifo_th);
+ return 0;
+
+ }
+@@ -1070,6 +1080,7 @@ static int dw_i2s_probe(struct platform_
+ }
+ }
+
++ of_property_read_u32(pdev->dev.of_node, "dma-maxburst", &dev->max_dma_burst);
+ dev->bclk_ratio = 0;
+ dev->i2s_reg_comp1 = I2S_COMP_PARAM_1;
+ dev->i2s_reg_comp2 = I2S_COMP_PARAM_2;
+--- a/sound/soc/dwc/local.h
++++ b/sound/soc/dwc/local.h
+@@ -133,6 +133,7 @@ struct dw_i2s_dev {
+ u32 ccr;
+ u32 xfer_resolution;
+ u32 fifo_th;
++ u32 max_dma_burst;
+ u32 l_reg;
+ u32 r_reg;
+ bool is_jh7110; /* Flag for StarFive JH7110 SoC */
diff --git a/target/linux/bcm27xx/patches-6.6/950-1198-dts-rp1-restrict-i2s-burst-lengths-to-4.patch b/target/linux/bcm27xx/patches-6.6/950-1198-dts-rp1-restrict-i2s-burst-lengths-to-4.patch
new file mode 100644
index 0000000000..30b8a9f9b8
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1198-dts-rp1-restrict-i2s-burst-lengths-to-4.patch
@@ -0,0 +1,30 @@
+From 062434ab3be76d4fa5973bb199ccfd5b68c11720 Mon Sep 17 00:00:00 2001
+From: Jonathan Bell <jonathan@raspberrypi.com>
+Date: Tue, 23 Jul 2024 11:21:47 +0100
+Subject: [PATCH 1198/1215] dts: rp1: restrict i2s burst lengths to 4
+
+The associated DMAC has channels that do not support longer bursts.
+
+Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
+---
+ arch/arm64/boot/dts/broadcom/rp1.dtsi | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/arch/arm64/boot/dts/broadcom/rp1.dtsi
++++ b/arch/arm64/boot/dts/broadcom/rp1.dtsi
+@@ -400,6 +400,7 @@
+ #sound-dai-cells = <0>;
+ dmas = <&rp1_dma RP1_DMA_I2S0_TX>,<&rp1_dma RP1_DMA_I2S0_RX>;
+ dma-names = "tx", "rx";
++ dma-maxburst = <4>;
+ status = "disabled";
+ };
+
+@@ -413,6 +414,7 @@
+ #sound-dai-cells = <0>;
+ dmas = <&rp1_dma RP1_DMA_I2S1_TX>,<&rp1_dma RP1_DMA_I2S1_RX>;
+ dma-names = "tx", "rx";
++ dma-maxburst = <4>;
+ status = "disabled";
+ };
+
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
new file mode 100644
index 0000000000..4c429e284d
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1199-drm-vc4-Disable-the-2pixel-clock-odd-timings-workaro.patch
@@ -0,0 +1,204 @@
+From 485d11cfa7df2d2deb39c9b3455cebcb1a85cea2 Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Thu, 25 Jul 2024 14:36:32 +0100
+Subject: [PATCH 1199/1215] drm/vc4: Disable the 2pixel/clock odd timings
+ workaround for interlaced
+
+Whilst BCM2712 does fix using odd horizontal timings, it doesn't
+work with interlaced modes.
+
+Drop the workaround for interlaced modes and revert to the same
+behaviour as BCM2711.
+
+https://github.com/raspberrypi/linux/issues/6281
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ drivers/gpu/drm/vc4/vc4_crtc.c | 20 +++++++++++++++++---
+ drivers/gpu/drm/vc4/vc4_drv.h | 2 ++
+ drivers/gpu/drm/vc4/vc4_hdmi.c | 8 +++++++-
+ drivers/gpu/drm/vc4/vc4_hdmi.h | 4 ++++
+ 4 files changed, 30 insertions(+), 4 deletions(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_crtc.c
++++ b/drivers/gpu/drm/vc4/vc4_crtc.c
+@@ -378,7 +378,9 @@ static void vc4_crtc_config_pv(struct dr
+ bool is_dsi1 = vc4_encoder->type == VC4_ENCODER_TYPE_DSI1;
+ bool is_vec = vc4_encoder->type == VC4_ENCODER_TYPE_VEC;
+ u32 format = is_dsi1 ? PV_CONTROL_FORMAT_DSIV_24 : PV_CONTROL_FORMAT_24;
+- u8 ppc = pv_data->pixels_per_clock;
++ u8 ppc = (mode->flags & DRM_MODE_FLAG_INTERLACE) ?
++ pv_data->pixels_per_clock_int :
++ pv_data->pixels_per_clock;
+
+ u16 vert_bp = mode->crtc_vtotal - mode->crtc_vsync_end;
+ u16 vert_sync = mode->crtc_vsync_end - mode->crtc_vsync_start;
+@@ -443,7 +445,8 @@ static void vc4_crtc_config_pv(struct dr
+ */
+ CRTC_WRITE(PV_V_CONTROL,
+ PV_VCONTROL_CONTINUOUS |
+- (vc4->gen >= VC4_GEN_6 ? PV_VCONTROL_ODD_TIMING : 0) |
++ (vc4->gen >= VC4_GEN_6 && ppc == 1 ?
++ PV_VCONTROL_ODD_TIMING : 0) |
+ (is_dsi ? PV_VCONTROL_DSI : 0) |
+ PV_VCONTROL_INTERLACE |
+ (odd_field_first
+@@ -455,7 +458,8 @@ static void vc4_crtc_config_pv(struct dr
+ } else {
+ CRTC_WRITE(PV_V_CONTROL,
+ PV_VCONTROL_CONTINUOUS |
+- (vc4->gen >= VC4_GEN_6 ? PV_VCONTROL_ODD_TIMING : 0) |
++ (vc4->gen >= VC4_GEN_6 && ppc == 1 ?
++ PV_VCONTROL_ODD_TIMING : 0) |
+ (is_dsi ? PV_VCONTROL_DSI : 0));
+ CRTC_WRITE(PV_VSYNCD_EVEN, 0);
+ }
+@@ -1223,6 +1227,7 @@ const struct vc4_pv_data bcm2835_pv0_dat
+ },
+ .fifo_depth = 64,
+ .pixels_per_clock = 1,
++ .pixels_per_clock_int = 1,
+ .encoder_types = {
+ [PV_CONTROL_CLK_SELECT_DSI] = VC4_ENCODER_TYPE_DSI0,
+ [PV_CONTROL_CLK_SELECT_DPI_SMI_HDMI] = VC4_ENCODER_TYPE_DPI,
+@@ -1238,6 +1243,7 @@ const struct vc4_pv_data bcm2835_pv1_dat
+ },
+ .fifo_depth = 64,
+ .pixels_per_clock = 1,
++ .pixels_per_clock_int = 1,
+ .encoder_types = {
+ [PV_CONTROL_CLK_SELECT_DSI] = VC4_ENCODER_TYPE_DSI1,
+ [PV_CONTROL_CLK_SELECT_DPI_SMI_HDMI] = VC4_ENCODER_TYPE_SMI,
+@@ -1253,6 +1259,7 @@ const struct vc4_pv_data bcm2835_pv2_dat
+ },
+ .fifo_depth = 64,
+ .pixels_per_clock = 1,
++ .pixels_per_clock_int = 1,
+ .encoder_types = {
+ [PV_CONTROL_CLK_SELECT_DPI_SMI_HDMI] = VC4_ENCODER_TYPE_HDMI0,
+ [PV_CONTROL_CLK_SELECT_VEC] = VC4_ENCODER_TYPE_VEC,
+@@ -1268,6 +1275,7 @@ const struct vc4_pv_data bcm2711_pv0_dat
+ },
+ .fifo_depth = 64,
+ .pixels_per_clock = 1,
++ .pixels_per_clock_int = 1,
+ .encoder_types = {
+ [0] = VC4_ENCODER_TYPE_DSI0,
+ [1] = VC4_ENCODER_TYPE_DPI,
+@@ -1283,6 +1291,7 @@ const struct vc4_pv_data bcm2711_pv1_dat
+ },
+ .fifo_depth = 64,
+ .pixels_per_clock = 1,
++ .pixels_per_clock_int = 1,
+ .encoder_types = {
+ [0] = VC4_ENCODER_TYPE_DSI1,
+ [1] = VC4_ENCODER_TYPE_SMI,
+@@ -1298,6 +1307,7 @@ const struct vc4_pv_data bcm2711_pv2_dat
+ },
+ .fifo_depth = 256,
+ .pixels_per_clock = 2,
++ .pixels_per_clock_int = 2,
+ .encoder_types = {
+ [0] = VC4_ENCODER_TYPE_HDMI0,
+ },
+@@ -1312,6 +1322,7 @@ const struct vc4_pv_data bcm2711_pv3_dat
+ },
+ .fifo_depth = 64,
+ .pixels_per_clock = 1,
++ .pixels_per_clock_int = 1,
+ .encoder_types = {
+ [PV_CONTROL_CLK_SELECT_VEC] = VC4_ENCODER_TYPE_VEC,
+ },
+@@ -1326,6 +1337,7 @@ const struct vc4_pv_data bcm2711_pv4_dat
+ },
+ .fifo_depth = 64,
+ .pixels_per_clock = 2,
++ .pixels_per_clock_int = 2,
+ .encoder_types = {
+ [0] = VC4_ENCODER_TYPE_HDMI1,
+ },
+@@ -1339,6 +1351,7 @@ const struct vc4_pv_data bcm2712_pv0_dat
+ },
+ .fifo_depth = 64,
+ .pixels_per_clock = 1,
++ .pixels_per_clock_int = 2,
+ .encoder_types = {
+ [0] = VC4_ENCODER_TYPE_HDMI0,
+ },
+@@ -1352,6 +1365,7 @@ const struct vc4_pv_data bcm2712_pv1_dat
+ },
+ .fifo_depth = 64,
+ .pixels_per_clock = 1,
++ .pixels_per_clock_int = 2,
+ .encoder_types = {
+ [0] = VC4_ENCODER_TYPE_HDMI1,
+ },
+--- a/drivers/gpu/drm/vc4/vc4_drv.h
++++ b/drivers/gpu/drm/vc4/vc4_drv.h
+@@ -569,6 +569,8 @@ struct vc4_pv_data {
+
+ /* Number of pixels output per clock period */
+ u8 pixels_per_clock;
++ /* Number of pixels output per clock period when in an interlaced mode */
++ u8 pixels_per_clock_int;
+
+ enum vc4_encoder_type encoder_types[4];
+ };
+--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
+@@ -2263,7 +2263,9 @@ static int vc4_hdmi_encoder_atomic_check
+ unsigned long long tmds_bit_rate;
+ int ret;
+
+- if (vc4_hdmi->variant->unsupported_odd_h_timings) {
++ if (vc4_hdmi->variant->unsupported_odd_h_timings ||
++ (vc4_hdmi->variant->unsupported_int_odd_h_timings &&
++ (mode->flags & DRM_MODE_FLAG_INTERLACE))) {
+ if (mode->flags & DRM_MODE_FLAG_DBLCLK) {
+ /* Only try to fixup DBLCLK modes to get 480i and 576i
+ * working.
+@@ -3974,6 +3976,7 @@ static const struct vc4_hdmi_variant bcm
+ PHY_LANE_CK,
+ },
+ .unsupported_odd_h_timings = true,
++ .unsupported_int_odd_h_timings = true,
+ .external_irq_controller = true,
+
+ .init_resources = vc5_hdmi_init_resources,
+@@ -4003,6 +4006,7 @@ static const struct vc4_hdmi_variant bcm
+ PHY_LANE_2,
+ },
+ .unsupported_odd_h_timings = true,
++ .unsupported_int_odd_h_timings = true,
+ .external_irq_controller = true,
+
+ .init_resources = vc5_hdmi_init_resources,
+@@ -4032,6 +4036,7 @@ static const struct vc4_hdmi_variant bcm
+ PHY_LANE_CK,
+ },
+ .unsupported_odd_h_timings = false,
++ .unsupported_int_odd_h_timings = true,
+ .external_irq_controller = true,
+
+ .init_resources = vc5_hdmi_init_resources,
+@@ -4059,6 +4064,7 @@ static const struct vc4_hdmi_variant bcm
+ PHY_LANE_CK,
+ },
+ .unsupported_odd_h_timings = false,
++ .unsupported_int_odd_h_timings = true,
+ .external_irq_controller = true,
+
+ .init_resources = vc5_hdmi_init_resources,
+--- a/drivers/gpu/drm/vc4/vc4_hdmi.h
++++ b/drivers/gpu/drm/vc4/vc4_hdmi.h
+@@ -49,6 +49,10 @@ struct vc4_hdmi_variant {
+
+ /* The BCM2711 cannot deal with odd horizontal pixel timings */
+ bool unsupported_odd_h_timings;
++ /* The BCM2712 can handle odd horizontal pixel timings, but not in
++ * interlaced modes
++ */
++ bool unsupported_int_odd_h_timings;
+
+ /*
+ * The BCM2711 CEC/hotplug IRQ controller is shared between the
diff --git a/target/linux/bcm27xx/patches-6.6/950-1200-ARM-dts-bcm2712-Fix-invalid-polling-delay-passive-se.patch b/target/linux/bcm27xx/patches-6.6/950-1200-ARM-dts-bcm2712-Fix-invalid-polling-delay-passive-se.patch
new file mode 100644
index 0000000000..8a7d86d745
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1200-ARM-dts-bcm2712-Fix-invalid-polling-delay-passive-se.patch
@@ -0,0 +1,26 @@
+From 70636ad110715b5e1ec6b08e24f0ddaf5df7186d Mon Sep 17 00:00:00 2001
+From: Dom Cobley <popcornmix@gmail.com>
+Date: Tue, 30 Jul 2024 19:00:03 +0100
+Subject: [PATCH 1200/1215] ARM: dts: bcm2712: Fix invalid
+ polling-delay-passive setting
+
+This produces a hard fail on later (6.11) kernels.
+
+See: https://lore.kernel.org/all/5802156.DvuYhMxLoT@rjwysocki.net/
+
+Signed-off-by: Dom Cobley <popcornmix@gmail.com>
+---
+ arch/arm64/boot/dts/broadcom/bcm2712.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/arm64/boot/dts/broadcom/bcm2712.dtsi
++++ b/arch/arm64/boot/dts/broadcom/bcm2712.dtsi
+@@ -40,7 +40,7 @@
+
+ thermal-zones {
+ cpu_thermal: cpu-thermal {
+- polling-delay-passive = <2000>;
++ polling-delay-passive = <1000>;
+ polling-delay = <1000>;
+ coefficients = <(-550) 450000>;
+ thermal-sensors = <&thermal>;
diff --git a/target/linux/bcm27xx/patches-6.6/950-1201-spi-dw-Fix-non-DMA-transmit-only-transfers.patch b/target/linux/bcm27xx/patches-6.6/950-1201-spi-dw-Fix-non-DMA-transmit-only-transfers.patch
new file mode 100644
index 0000000000..6545c09186
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1201-spi-dw-Fix-non-DMA-transmit-only-transfers.patch
@@ -0,0 +1,143 @@
+From 199e611183de09ad91fe01fc79da78cc9d11ccb6 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Mon, 29 Jul 2024 11:12:38 +0100
+Subject: [PATCH 1201/1215] spi: dw: Fix non-DMA transmit-only transfers
+
+Ensure the transmit FIFO has emptied before ending the transfer by
+dropping the TX threshold to 0 when the last byte has been pushed into
+the FIFO. Include a similar fix for the non-IRQ paths.
+
+See: https://github.com/raspberrypi/linux/issues/6285
+Fixes: 6014649de765 ("spi: dw: Save bandwidth with the TMOD_TO feature")
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ drivers/spi/spi-dw-core.c | 62 +++++++++++++++++++++++++++++++++------
+ drivers/spi/spi-dw.h | 3 ++
+ 2 files changed, 56 insertions(+), 9 deletions(-)
+
+--- a/drivers/spi/spi-dw-core.c
++++ b/drivers/spi/spi-dw-core.c
+@@ -220,6 +220,32 @@ int dw_spi_check_status(struct dw_spi *d
+ }
+ EXPORT_SYMBOL_NS_GPL(dw_spi_check_status, SPI_DW_CORE);
+
++static inline bool dw_spi_ctlr_busy(struct dw_spi *dws)
++{
++ return dw_readl(dws, DW_SPI_SR) & DW_SPI_SR_BUSY;
++}
++
++static enum hrtimer_restart dw_spi_hrtimer_handler(struct hrtimer *hr)
++{
++ struct dw_spi *dws = container_of(hr, struct dw_spi, hrtimer);
++
++ if (!dw_spi_ctlr_busy(dws)) {
++ spi_finalize_current_transfer(dws->host);
++ return HRTIMER_NORESTART;
++ }
++
++ if (!dws->idle_wait_retries) {
++ dev_err(&dws->host->dev, "controller stuck at busy\n");
++ spi_finalize_current_transfer(dws->host);
++ return HRTIMER_NORESTART;
++ }
++
++ dws->idle_wait_retries--;
++ hrtimer_forward_now(hr, dws->idle_wait_interval);
++
++ return HRTIMER_RESTART;
++}
++
+ static irqreturn_t dw_spi_transfer_handler(struct dw_spi *dws)
+ {
+ u16 irq_status = dw_readl(dws, DW_SPI_ISR);
+@@ -246,7 +272,22 @@ static irqreturn_t dw_spi_transfer_handl
+ }
+ } else if (!dws->tx_len) {
+ dw_spi_mask_intr(dws, DW_SPI_INT_TXEI);
+- spi_finalize_current_transfer(dws->host);
++ if (dw_spi_ctlr_busy(dws)) {
++ ktime_t period = ns_to_ktime(DIV_ROUND_UP(NSEC_PER_SEC, dws->current_freq));
++
++ /*
++ * Make the initial wait an underestimate of how long the transfer
++ * should take, then poll rapidly to reduce the delay
++ */
++ hrtimer_start(&dws->hrtimer,
++ period * (8 * dws->n_bytes - 1),
++ HRTIMER_MODE_REL);
++ dws->idle_wait_retries = 10;
++ dws->idle_wait_interval = period;
++ } else {
++ spi_finalize_current_transfer(dws->host);
++ }
++ return IRQ_HANDLED;
+ }
+
+ /*
+@@ -255,9 +296,13 @@ static irqreturn_t dw_spi_transfer_handl
+ * have the TXE IRQ flood at the final stage of the transfer.
+ */
+ if (irq_status & DW_SPI_INT_TXEI) {
+- if (!dws->tx_len)
+- dw_spi_mask_intr(dws, DW_SPI_INT_TXEI);
+ dw_writer(dws);
++ if (!dws->tx_len) {
++ if (dws->rx_len)
++ dw_spi_mask_intr(dws, DW_SPI_INT_TXEI);
++ else
++ dw_writel(dws, DW_SPI_TXFTLR, 0);
++ }
+ }
+
+ return IRQ_HANDLED;
+@@ -428,7 +473,7 @@ static int dw_spi_poll_transfer(struct d
+ ret = dw_spi_check_status(dws, true);
+ if (ret)
+ return ret;
+- } while (dws->rx_len);
++ } while (dws->rx_len || dws->tx_len || dw_spi_ctlr_busy(dws));
+
+ return 0;
+ }
+@@ -652,11 +697,6 @@ static int dw_spi_write_then_read(struct
+ return 0;
+ }
+
+-static inline bool dw_spi_ctlr_busy(struct dw_spi *dws)
+-{
+- return dw_readl(dws, DW_SPI_SR) & DW_SPI_SR_BUSY;
+-}
+-
+ static int dw_spi_wait_mem_op_done(struct dw_spi *dws)
+ {
+ int retry = DW_SPI_WAIT_RETRIES;
+@@ -993,6 +1033,9 @@ int dw_spi_add_host(struct device *dev,
+ }
+ }
+
++ hrtimer_init(&dws->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
++ dws->hrtimer.function = dw_spi_hrtimer_handler;
++
+ ret = spi_register_controller(host);
+ if (ret) {
+ dev_err_probe(dev, ret, "problem registering spi host\n");
+@@ -1018,6 +1061,7 @@ void dw_spi_remove_host(struct dw_spi *d
+ {
+ dw_spi_debugfs_remove(dws);
+
++ hrtimer_cancel(&dws->hrtimer);
+ spi_unregister_controller(dws->host);
+
+ if (dws->dma_ops && dws->dma_ops->dma_exit)
+--- a/drivers/spi/spi-dw.h
++++ b/drivers/spi/spi-dw.h
+@@ -180,6 +180,9 @@ struct dw_spi {
+ u32 current_freq; /* frequency in hz */
+ u32 cur_rx_sample_dly;
+ u32 def_rx_sample_dly_ns;
++ struct hrtimer hrtimer;
++ ktime_t idle_wait_interval;
++ int idle_wait_retries;
+
+ /* Custom memory operations */
+ struct spi_controller_mem_ops mem_ops;
diff --git a/target/linux/bcm27xx/patches-6.6/950-1202-spi-dw-Clamp-the-minimum-clock-speed.patch b/target/linux/bcm27xx/patches-6.6/950-1202-spi-dw-Clamp-the-minimum-clock-speed.patch
new file mode 100644
index 0000000000..585173aa44
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1202-spi-dw-Clamp-the-minimum-clock-speed.patch
@@ -0,0 +1,26 @@
+From e9294823cf02068189a0e901223ed4991923c689 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Wed, 31 Jul 2024 10:55:19 +0100
+Subject: [PATCH 1202/1215] spi: dw: Clamp the minimum clock speed
+
+The DW SPI interface has a 16-bit clock divider, where the bottom bit
+of the divisor must be 0. Limit how low the clock speed can go to
+prevent the clock divider from being truncated, as that could lead to
+a much higher clock rate than requested.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ drivers/spi/spi-dw-core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/spi/spi-dw-core.c
++++ b/drivers/spi/spi-dw-core.c
+@@ -397,7 +397,7 @@ void dw_spi_update_config(struct dw_spi
+ dw_writel(dws, DW_SPI_CTRLR1, cfg->ndf ? cfg->ndf - 1 : 0);
+
+ /* Note DW APB SSI clock divider doesn't support odd numbers */
+- clk_div = (DIV_ROUND_UP(dws->max_freq, cfg->freq) + 1) & 0xfffe;
++ clk_div = min(DIV_ROUND_UP(dws->max_freq, cfg->freq) + 1, 0xfffe) & 0xfffe;
+ speed_hz = dws->max_freq / clk_div;
+
+ if (dws->current_freq != speed_hz) {
diff --git a/target/linux/bcm27xx/patches-6.6/950-1203-overlays-i2c-rtc-Correct-bq32000-property-name.patch b/target/linux/bcm27xx/patches-6.6/950-1203-overlays-i2c-rtc-Correct-bq32000-property-name.patch
new file mode 100644
index 0000000000..afd6c415ba
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1203-overlays-i2c-rtc-Correct-bq32000-property-name.patch
@@ -0,0 +1,26 @@
+From 05e3687c6c973c30bf35f3b7f4a7589b5030a830 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Wed, 31 Jul 2024 13:19:26 +0100
+Subject: [PATCH 1203/1215] overlays: i2c-rtc: Correct bq32000 property name
+
+The DT property for the BQ32000 controlled by trickle-resistor-ohms
+parameter should be "trickle-resistor-ohms", not "abracon,tc-resistor".
+
+See: https://github.com/raspberrypi/linux/issues/6291
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm/boot/dts/overlays/i2c-rtc-common.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/arm/boot/dts/overlays/i2c-rtc-common.dtsi
++++ b/arch/arm/boot/dts/overlays/i2c-rtc-common.dtsi
+@@ -354,7 +354,7 @@
+ <&rv3028>,"trickle-resistor-ohms:0",
+ <&rv3032>,"trickle-resistor-ohms:0",
+ <&rv1805>,"abracon,tc-resistor:0",
+- <&bq32000>,"abracon,tc-resistor:0";
++ <&bq32000>,"trickle-resistor-ohms:0";
+ trickle-voltage-mv = <&rv3032>,"trickle-voltage-millivolts:0";
+ backup-switchover-mode = <&rv3028>,"backup-switchover-mode:0";
+ wakeup-source = <&ds1339>,"wakeup-source?",
diff --git a/target/linux/bcm27xx/patches-6.6/950-1204-hwmon-adt7410-Add-DT-compatible-strings.patch b/target/linux/bcm27xx/patches-6.6/950-1204-hwmon-adt7410-Add-DT-compatible-strings.patch
new file mode 100644
index 0000000000..cc54c62b91
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1204-hwmon-adt7410-Add-DT-compatible-strings.patch
@@ -0,0 +1,31 @@
+From 16d0ee22d2c0b32cc67db73ce03263b740bba2a7 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Wed, 31 Jul 2024 15:02:47 +0100
+Subject: [PATCH 1204/1215] hwmon: (adt7410) Add DT compatible strings
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ drivers/hwmon/adt7410.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/drivers/hwmon/adt7410.c
++++ b/drivers/hwmon/adt7410.c
+@@ -94,10 +94,18 @@ static const struct i2c_device_id adt741
+ };
+ MODULE_DEVICE_TABLE(i2c, adt7410_ids);
+
++static const struct of_device_id adt7410_of_ids[] = {
++ { .compatible = "adi,adt7410" },
++ { .compatible = "adi,adt7420" },
++ {}
++};
++MODULE_DEVICE_TABLE(of, adt7410_of_ids);
++
+ static struct i2c_driver adt7410_driver = {
+ .class = I2C_CLASS_HWMON,
+ .driver = {
+ .name = "adt7410",
++ .of_match_table = adt7410_of_ids,
+ .pm = pm_sleep_ptr(&adt7x10_dev_pm_ops),
+ },
+ .probe = adt7410_i2c_probe,
diff --git a/target/linux/bcm27xx/patches-6.6/950-1205-fixup-pinctrl-bcm2712-pinctrl-pinconf-driver.patch b/target/linux/bcm27xx/patches-6.6/950-1205-fixup-pinctrl-bcm2712-pinctrl-pinconf-driver.patch
new file mode 100644
index 0000000000..fb786e172e
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1205-fixup-pinctrl-bcm2712-pinctrl-pinconf-driver.patch
@@ -0,0 +1,23 @@
+From a4bf61fad9fe102514243ed263c458b053c87681 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Fri, 2 Aug 2024 11:29:03 +0100
+Subject: [PATCH 1205/1215] fixup! pinctrl: bcm2712 pinctrl/pinconf driver
+
+Fix cut-and-paste error spotted during upstreaming process.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ drivers/pinctrl/bcm/pinctrl-bcm2712.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/pinctrl/bcm/pinctrl-bcm2712.c
++++ b/drivers/pinctrl/bcm/pinctrl-bcm2712.c
+@@ -1029,7 +1029,7 @@ static int bcm2712_pinconf_get(struct pi
+
+ *config = pinconf_to_config_packed(param, arg);
+
+- return -ENOTSUPP;
++ return 0;
+ }
+
+ static int bcm2712_pinconf_set(struct pinctrl_dev *pctldev,
diff --git a/target/linux/bcm27xx/patches-6.6/950-1206-dtoverlays-Add-overlay-for-HD44780-via-I2C-PCF8574-b.patch b/target/linux/bcm27xx/patches-6.6/950-1206-dtoverlays-Add-overlay-for-HD44780-via-I2C-PCF8574-b.patch
new file mode 100644
index 0000000000..db5f472ff0
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1206-dtoverlays-Add-overlay-for-HD44780-via-I2C-PCF8574-b.patch
@@ -0,0 +1,125 @@
+From e94e761305fa2281718adcf625d78f3cf662e12d Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Thu, 1 Aug 2024 18:12:50 +0100
+Subject: [PATCH 1206/1215] dtoverlays: Add overlay for HD44780 via I2C PCF8574
+ backpack
+
+Many HD44780 LCD displays are connected via very common I2C
+GPIO expander.
+We have an overlay for connecting the displays directly to GPIOs,
+but not one for it connected via a backpack. Add such an overlay.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ arch/arm/boot/dts/overlays/Makefile | 1 +
+ arch/arm/boot/dts/overlays/README | 27 +++++++++
+ .../dts/overlays/hd44780-i2c-lcd-overlay.dts | 57 +++++++++++++++++++
+ 3 files changed, 85 insertions(+)
+ create mode 100644 arch/arm/boot/dts/overlays/hd44780-i2c-lcd-overlay.dts
+
+--- a/arch/arm/boot/dts/overlays/Makefile
++++ b/arch/arm/boot/dts/overlays/Makefile
+@@ -82,6 +82,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \
+ gpio-no-irq.dtbo \
+ gpio-poweroff.dtbo \
+ gpio-shutdown.dtbo \
++ hd44780-i2c-lcd.dtbo \
+ hd44780-lcd.dtbo \
+ hdmi-backlight-hwhack-gpio.dtbo \
+ hifiberry-amp.dtbo \
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -1705,6 +1705,33 @@ Params: gpio_pin GPIO pin
+ (default 100)
+
+
++Name: hd44780-i2c-lcd
++Info: Configures an HD44780 compatible LCD display connected via a PCF8574 as
++ is often found as a backpack interface for these displays.
++Load: dtoverlay=hd44780-i2c-lcd,<param>=<val>
++Params: addr I2C address of PCF8574
++ pin_d4 GPIO pin for data pin D4 (default 4)
++
++ pin_d5 GPIO pin for data pin D5 (default 5)
++
++ pin_d6 GPIO pin for data pin D6 (default 6)
++
++ pin_d7 GPIO pin for data pin D7 (default 7)
++
++ pin_en GPIO pin for "Enable" (default 2)
++
++ pin_rs GPIO pin for "Register Select" (default 0)
++
++ pin_rw GPIO pin for R/W select (default 1)
++
++ pin_bl GPIO pin for enabling/disabling the display
++ backlight. (default 3)
++
++ display_height Height of the display in characters (default 2)
++
++ display_width Width of the display in characters (default 16)
++
++
+ Name: hd44780-lcd
+ Info: Configures an HD44780 compatible LCD display. Uses 4 gpio pins for
+ data, 2 gpio pins for enable and register select and 1 optional pin
+--- /dev/null
++++ b/arch/arm/boot/dts/overlays/hd44780-i2c-lcd-overlay.dts
+@@ -0,0 +1,57 @@
++/dts-v1/;
++/plugin/;
++
++/ {
++ compatible = "brcm,bcm2835";
++
++ fragment@0 {
++ target = <&i2c_arm>;
++ __overlay__ {
++ status = "okay";
++
++ pcf857x: pcf857x@27 {
++ compatible = "nxp,pcf8574";
++ reg = <0x27>;
++ gpio-controller;
++ #gpio-cells = <2>;
++ status = "okay";
++ };
++ };
++ };
++
++ fragment@1 {
++ target-path = "/";
++ __overlay__ {
++ lcd_screen: auxdisplay {
++ compatible = "hit,hd44780";
++
++ data-gpios = <&pcf857x 4 0>,
++ <&pcf857x 5 0>,
++ <&pcf857x 6 0>,
++ <&pcf857x 7 0>;
++ enable-gpios = <&pcf857x 2 0>;
++ rs-gpios = <&pcf857x 0 0>;
++ rw-gpios = <&pcf857x 1 0>;
++ backlight-gpios = <&pcf857x 3 0>;
++
++ display-width-chars = <16>;
++ display-height-chars = <2>;
++ };
++ };
++ };
++
++ __overrides__ {
++ pin_d4 = <&lcd_screen>,"data-gpios:4";
++ pin_d5 = <&lcd_screen>,"data-gpios:16";
++ pin_d6 = <&lcd_screen>,"data-gpios:28";
++ pin_d7 = <&lcd_screen>,"data-gpios:40";
++ pin_en = <&lcd_screen>,"enable-gpios:4";
++ pin_rs = <&lcd_screen>,"rs-gpios:4";
++ pin_rw = <&lcd_screen>,"rw-gpios:4";
++ pin_bl = <&lcd_screen>,"backlight-gpios:4";
++ display_height = <&lcd_screen>,"display-height-chars:0";
++ display_width = <&lcd_screen>,"display-width-chars:0";
++ addr = <&pcf857x>,"reg:0";
++ };
++
++};
diff --git a/target/linux/bcm27xx/patches-6.6/950-1207-dtoverlays-Document-display_-width-height-on-hd44780.patch b/target/linux/bcm27xx/patches-6.6/950-1207-dtoverlays-Document-display_-width-height-on-hd44780.patch
new file mode 100644
index 0000000000..793cd49310
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1207-dtoverlays-Document-display_-width-height-on-hd44780.patch
@@ -0,0 +1,28 @@
+From 3c319a466a1c718f66c471a9d5ec60de6de44612 Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Fri, 2 Aug 2024 10:41:28 +0100
+Subject: [PATCH 1207/1215] dtoverlays: Document display_[width|height] on
+ hd44780-lcd overlay
+
+The default values defining a 16x2 display weren't documented,
+so add them.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ arch/arm/boot/dts/overlays/README | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -1752,9 +1752,9 @@ Params: pin_d4 GPIO pin
+ pin_bl Optional pin for enabling/disabling the
+ display backlight. (default disabled)
+
+- display_height Height of the display in characters
++ display_height Height of the display in characters (default 2)
+
+- display_width Width of the display in characters
++ display_width Width of the display in characters (default 16)
+
+
+ Name: hdmi-backlight-hwhack-gpio
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-1208-DTS-bcm2712-enable-SD-slot-CQE-by-default-on-Pi-5.patch
new file mode 100644
index 0000000000..16e7603498
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1208-DTS-bcm2712-enable-SD-slot-CQE-by-default-on-Pi-5.patch
@@ -0,0 +1,39 @@
+From 216df57950849f905c398904e7d6cbdf278b5717 Mon Sep 17 00:00:00 2001
+From: Jonathan Bell <jonathan@raspberrypi.com>
+Date: Mon, 5 Aug 2024 11:28:36 +0100
+Subject: [PATCH 1208/1215] DTS: bcm2712: 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.
+
+Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
+---
+ arch/arm/boot/dts/overlays/README | 6 +++---
+ arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts | 1 +
+ 2 files changed, 4 insertions(+), 3 deletions(-)
+
+--- a/arch/arm/boot/dts/overlays/README
++++ b/arch/arm/boot/dts/overlays/README
+@@ -378,9 +378,9 @@ Params:
+ non-lite SKU of CM4).
+ (default "on")
+
+- sd_cqe Use to enable Command Queueing on the SD
+- interface for faster Class A2 card performance
+- (Pi 5 only, default "off")
++ sd_cqe Set to "off" to disable Command Queueing if you
++ have an incompatible Class A2 SD card
++ (Pi 5 only, default "on")
+
+ sd_overclock Clock (in MHz) to use when the MMC framework
+ 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
+ sd-uhs-sdr50;
+ sd-uhs-ddr50;
+ sd-uhs-sdr104;
++ supports-cqe;
+ cd-gpios = <&gio_aon 5 GPIO_ACTIVE_LOW>;
+ //no-1-8-v;
+ status = "okay";
diff --git a/target/linux/bcm27xx/patches-6.6/950-1211-gpiolib-Override-gpiochip-numbers-with-DT-aliases.patch b/target/linux/bcm27xx/patches-6.6/950-1211-gpiolib-Override-gpiochip-numbers-with-DT-aliases.patch
new file mode 100644
index 0000000000..d909c6f9a2
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1211-gpiolib-Override-gpiochip-numbers-with-DT-aliases.patch
@@ -0,0 +1,50 @@
+From 53b9d9bbb57e292c6b332a2fb9899003586e17ca Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Thu, 2 May 2024 16:17:02 +0100
+Subject: [PATCH 1211/1215] gpiolib: Override gpiochip numbers with DT aliases
+
+In the same way that other subsystems support the setting of device
+id numbers from Device Tree aliases, allow gpiochip numbers to be
+derived from "gpiochip<n>" aliases.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ drivers/gpio/gpiolib.c | 13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpio/gpiolib.c
++++ b/drivers/gpio/gpiolib.c
+@@ -111,6 +111,7 @@ static int gpiochip_irqchip_init_valid_m
+ static void gpiochip_irqchip_free_valid_mask(struct gpio_chip *gc);
+
+ static bool gpiolib_initialized;
++static int first_dynamic_gpiochip_num = -1;
+
+ static inline void desc_set_label(struct gpio_desc *d, const char *label)
+ {
+@@ -746,6 +747,7 @@ int gpiochip_add_data_with_key(struct gp
+ unsigned int i;
+ int base = 0;
+ int ret = 0;
++ int id;
+
+ /*
+ * First: allocate and populate the internal stat container, and
+@@ -770,7 +772,16 @@ int gpiochip_add_data_with_key(struct gp
+ else if (gc->parent)
+ device_set_node(&gdev->dev, dev_fwnode(gc->parent));
+
+- gdev->id = ida_alloc(&gpio_ida, GFP_KERNEL);
++ if (first_dynamic_gpiochip_num < 0) {
++ id = of_alias_get_highest_id("gpiochip");
++ first_dynamic_gpiochip_num = (id >= 0) ? (id + 1) : 0;
++ }
++
++ id = of_alias_get_id(gdev->dev.of_node, "gpiochip");
++ if (id < 0)
++ id = first_dynamic_gpiochip_num;
++
++ gdev->id = ida_alloc_range(&gpio_ida, id, ~0, GFP_KERNEL);
+ if (gdev->id < 0) {
+ ret = gdev->id;
+ goto err_free_gdev;
diff --git a/target/linux/bcm27xx/patches-6.6/950-1212-dts-bcm2712-rpi-Add-gpiochip0-alias.patch b/target/linux/bcm27xx/patches-6.6/950-1212-dts-bcm2712-rpi-Add-gpiochip0-alias.patch
new file mode 100644
index 0000000000..21913760a7
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1212-dts-bcm2712-rpi-Add-gpiochip0-alias.patch
@@ -0,0 +1,23 @@
+From 1162316fd26eeb4193b23fcc1bb332f42938aa70 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Thu, 2 May 2024 16:58:59 +0100
+Subject: [PATCH 1212/1215] dts: bcm2712-rpi: Add gpiochip0 alias
+
+Add a gpiochip0 aliase pointing to the rp1 GPIO node, making it appear
+as gpiochip0.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm64/boot/dts/broadcom/bcm2712-rpi.dtsi | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/arch/arm64/boot/dts/broadcom/bcm2712-rpi.dtsi
++++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi.dtsi
+@@ -112,6 +112,7 @@
+ gpio2 = &gio_aon;
+ gpio3 = &pinctrl;
+ gpio4 = &pinctrl_aon;
++ gpiochip0 = &gpio;
+ i2c = &i2c_arm;
+ i2c0 = &i2c0;
+ i2c1 = &i2c1;
diff --git a/target/linux/bcm27xx/patches-6.6/950-1213-dts-bcm2712-rpi-The-SoC-gpiochips-start-at-10.patch b/target/linux/bcm27xx/patches-6.6/950-1213-dts-bcm2712-rpi-The-SoC-gpiochips-start-at-10.patch
new file mode 100644
index 0000000000..5bf54c3fb0
--- /dev/null
+++ b/target/linux/bcm27xx/patches-6.6/950-1213-dts-bcm2712-rpi-The-SoC-gpiochips-start-at-10.patch
@@ -0,0 +1,24 @@
+From 70c640ce992234aacba5a717f3fb47319f451431 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.com>
+Date: Thu, 2 May 2024 17:40:25 +0100
+Subject: [PATCH 1213/1215] dts: bcm2712-rpi: The SoC gpiochips start at 10
+
+Make the BCM2712's onboard GPIOs start at gpiochip10, marking them out
+as system resources and preventing accidental use by existing Pi 5
+code.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+---
+ arch/arm64/boot/dts/broadcom/bcm2712-rpi.dtsi | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/arch/arm64/boot/dts/broadcom/bcm2712-rpi.dtsi
++++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi.dtsi
+@@ -113,6 +113,7 @@
+ gpio3 = &pinctrl;
+ gpio4 = &pinctrl_aon;
+ gpiochip0 = &gpio;
++ gpiochip10 = &gio;
+ i2c = &i2c_arm;
+ i2c0 = &i2c0;
+ i2c1 = &i2c1;
diff --git a/target/linux/bcm47xx/patches-6.6/830-huawei_e970_support.patch b/target/linux/bcm47xx/patches-6.6/830-huawei_e970_support.patch
index 21ab40206f..08813da1ba 100644
--- a/target/linux/bcm47xx/patches-6.6/830-huawei_e970_support.patch
+++ b/target/linux/bcm47xx/patches-6.6/830-huawei_e970_support.patch
@@ -1,14 +1,14 @@
--- a/arch/mips/bcm47xx/setup.c
+++ b/arch/mips/bcm47xx/setup.c
-@@ -37,6 +37,7 @@
- #include <linux/ssb/ssb.h>
+@@ -38,6 +38,7 @@
#include <linux/ssb/ssb_embedded.h>
#include <linux/bcma/bcma_soc.h>
+ #include <asm/bmips.h>
+#include <linux/old_gpio_wdt.h>
#include <asm/bootinfo.h>
#include <asm/idle.h>
#include <asm/prom.h>
-@@ -254,6 +255,33 @@ static struct fixed_phy_status bcm47xx_f
+@@ -262,6 +263,33 @@ static struct fixed_phy_status bcm47xx_f
.duplex = DUPLEX_FULL,
};
@@ -42,7 +42,7 @@
static int __init bcm47xx_register_bus_complete(void)
{
switch (bcm47xx_bus_type) {
-@@ -275,6 +303,7 @@ static int __init bcm47xx_register_bus_c
+@@ -283,6 +311,7 @@ static int __init bcm47xx_register_bus_c
bcm47xx_workarounds();
fixed_phy_add(PHY_POLL, 0, &bcm47xx_fixed_phy_status);
diff --git a/target/linux/bcm4908/Makefile b/target/linux/bcm4908/Makefile
index b4d238eff6..2d12bd7815 100644
--- a/target/linux/bcm4908/Makefile
+++ b/target/linux/bcm4908/Makefile
@@ -9,8 +9,7 @@ FEATURES:=squashfs nand usb gpio
CPU_TYPE:=cortex-a53
SUBTARGETS:=generic
-KERNEL_PATCHVER:=6.1
-KERNEL_TESTING_PATCHVER:=6.6
+KERNEL_PATCHVER:=6.6
define Target/Description
Build firmware images for Broadcom BCM4908 SoC family routers.
diff --git a/target/linux/bcm4908/config-6.1 b/target/linux/bcm4908/config-6.1
deleted file mode 100644
index 086d387bc7..0000000000
--- a/target/linux/bcm4908/config-6.1
+++ /dev/null
@@ -1,245 +0,0 @@
-CONFIG_64BIT=y
-CONFIG_ARCH_BCM=y
-CONFIG_ARCH_BCMBCA=y
-CONFIG_ARCH_DMA_ADDR_T_64BIT=y
-CONFIG_ARCH_KEEP_MEMBLOCK=y
-CONFIG_ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE=y
-CONFIG_ARCH_MMAP_RND_BITS=18
-CONFIG_ARCH_MMAP_RND_BITS_MAX=24
-CONFIG_ARCH_MMAP_RND_BITS_MIN=18
-CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11
-CONFIG_ARCH_PROC_KCORE_TEXT=y
-CONFIG_ARCH_SPARSEMEM_ENABLE=y
-CONFIG_ARCH_STACKWALK=y
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
-CONFIG_ARCH_WANTS_NO_INSTR=y
-CONFIG_ARM64=y
-CONFIG_ARM64_4K_PAGES=y
-CONFIG_ARM64_CRYPTO=y
-CONFIG_ARM64_LD_HAS_FIX_ERRATUM_843419=y
-CONFIG_ARM64_PAGE_SHIFT=12
-CONFIG_ARM64_PA_BITS=48
-CONFIG_ARM64_PA_BITS_48=y
-CONFIG_ARM64_PTR_AUTH=y
-CONFIG_ARM64_PTR_AUTH_KERNEL=y
-CONFIG_ARM64_SVE=y
-CONFIG_ARM64_TAGGED_ADDR_ABI=y
-CONFIG_ARM64_VA_BITS=39
-CONFIG_ARM64_VA_BITS_39=y
-CONFIG_ARM_AMBA=y
-CONFIG_ARM_ARCH_TIMER=y
-CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y
-CONFIG_ARM_GIC=y
-CONFIG_ARM_GIC_V3=y
-CONFIG_ARM_GIC_V3_ITS=y
-CONFIG_ARM_PSCI_FW=y
-CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y
-CONFIG_B53=y
-CONFIG_BCM4908_ENET=y
-CONFIG_BCM7038_WDT=y
-CONFIG_BCM7XXX_PHY=y
-CONFIG_BCM_NET_PHYLIB=y
-CONFIG_BCM_PMB=y
-# CONFIG_BLK_DEV_INITRD is not set
-CONFIG_BLK_PM=y
-CONFIG_CC_HAVE_STACKPROTECTOR_SYSREG=y
-CONFIG_CLK_BCM_63XX=y
-CONFIG_CLONE_BACKWARDS=y
-CONFIG_CMDLINE="earlycon=bcm63xx_uart,0xff800640 console=ttyS0,115200"
-CONFIG_CMDLINE_FROM_BOOTLOADER=y
-CONFIG_COMMON_CLK=y
-# CONFIG_COMPAT_32BIT_TIME is not set
-CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_CPU_RMAP=y
-CONFIG_CRC16=y
-CONFIG_CRYPTO_AES_ARM64=y
-CONFIG_CRYPTO_AES_ARM64_CE=y
-CONFIG_CRYPTO_AES_ARM64_CE_BLK=y
-CONFIG_CRYPTO_AES_ARM64_CE_CCM=y
-CONFIG_CRYPTO_CRYPTD=y
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_GHASH_ARM64_CE=y
-CONFIG_CRYPTO_HASH_INFO=y
-CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
-CONFIG_CRYPTO_LZO=y
-CONFIG_CRYPTO_RNG2=y
-CONFIG_CRYPTO_SIMD=y
-CONFIG_CRYPTO_ZSTD=y
-CONFIG_DCACHE_WORD_ACCESS=y
-CONFIG_DMA_DIRECT_REMAP=y
-CONFIG_DMA_REMAP=y
-CONFIG_DTC=y
-CONFIG_EDAC_SUPPORT=y
-CONFIG_FIXED_PHY=y
-CONFIG_FIX_EARLYCON_MEM=y
-CONFIG_FRAME_POINTER=y
-CONFIG_FWNODE_MDIO=y
-CONFIG_FW_LOADER_PAGED_BUF=y
-CONFIG_GENERIC_ALLOCATOR=y
-CONFIG_GENERIC_ARCH_TOPOLOGY=y
-CONFIG_GENERIC_BUG=y
-CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
-CONFIG_GENERIC_CPU_AUTOPROBE=y
-CONFIG_GENERIC_CPU_VULNERABILITIES=y
-CONFIG_GENERIC_CSUM=y
-CONFIG_GENERIC_EARLY_IOREMAP=y
-CONFIG_GENERIC_FIND_FIRST_BIT=y
-CONFIG_GENERIC_GETTIMEOFDAY=y
-CONFIG_GENERIC_IDLE_POLL_SETUP=y
-CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
-CONFIG_GENERIC_IRQ_SHOW=y
-CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
-CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y
-CONFIG_GENERIC_MSI_IRQ=y
-CONFIG_GENERIC_MSI_IRQ_DOMAIN=y
-CONFIG_GENERIC_PCI_IOMAP=y
-CONFIG_GENERIC_PHY=y
-CONFIG_GENERIC_PINCONF=y
-CONFIG_GENERIC_PINCTRL_GROUPS=y
-CONFIG_GENERIC_PINMUX_FUNCTIONS=y
-CONFIG_GENERIC_SCHED_CLOCK=y
-CONFIG_GENERIC_SMP_IDLE_THREAD=y
-CONFIG_GENERIC_STRNCPY_FROM_USER=y
-CONFIG_GENERIC_STRNLEN_USER=y
-CONFIG_GENERIC_TIME_VSYSCALL=y
-CONFIG_GPIO_CDEV=y
-CONFIG_GPIO_GENERIC=y
-CONFIG_GPIO_GENERIC_PLATFORM=y
-CONFIG_GRO_CELLS=y
-CONFIG_HANDLE_DOMAIN_IRQ=y
-CONFIG_HARDIRQS_SW_RESEND=y
-CONFIG_HAS_DMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HZ_PERIODIC=y
-CONFIG_I2C=y
-CONFIG_I2C_BOARDINFO=y
-CONFIG_I2C_BRCMSTB=y
-CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000
-CONFIG_IRQCHIP=y
-CONFIG_IRQ_DOMAIN=y
-CONFIG_IRQ_DOMAIN_HIERARCHY=y
-CONFIG_IRQ_FORCED_THREADING=y
-CONFIG_IRQ_WORK=y
-CONFIG_LEDS_BCM63138=y
-CONFIG_LEDS_GPIO=y
-CONFIG_LIBFDT=y
-CONFIG_LOCK_DEBUGGING_SUPPORT=y
-CONFIG_LOCK_SPIN_ON_OWNER=y
-CONFIG_LZO_COMPRESS=y
-CONFIG_LZO_DECOMPRESS=y
-CONFIG_MDIO_BCM_UNIMAC=y
-CONFIG_MDIO_BUS=y
-CONFIG_MDIO_DEVICE=y
-CONFIG_MDIO_DEVRES=y
-CONFIG_MEMFD_CREATE=y
-CONFIG_MFD_SYSCON=y
-CONFIG_MIGRATION=y
-# CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY is not set
-CONFIG_MODULES_USE_ELF_RELA=y
-CONFIG_MTD_BRCM_U_BOOT=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_NAND_BRCMNAND=y
-CONFIG_MTD_NAND_BRCMNAND_BCMBCA=y
-CONFIG_MTD_NAND_CORE=y
-CONFIG_MTD_NAND_ECC=y
-CONFIG_MTD_NAND_ECC_SW_HAMMING=y
-CONFIG_MTD_OF_PARTS_BCM4908=y
-# CONFIG_MTD_OF_PARTS_LINKSYS_NS is not set
-CONFIG_MTD_RAW_NAND=y
-CONFIG_MTD_SPLIT_CFE_BOOTFS=y
-# CONFIG_MTD_SPLIT_SQUASHFS_ROOT is not set
-CONFIG_MTD_UBI=y
-CONFIG_MTD_UBI_BEB_LIMIT=20
-CONFIG_MTD_UBI_BLOCK=y
-CONFIG_MTD_UBI_WL_THRESHOLD=4096
-CONFIG_MUTEX_SPIN_ON_OWNER=y
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NEED_SG_DMA_LENGTH=y
-CONFIG_NET_DEVLINK=y
-CONFIG_NET_DSA=y
-CONFIG_NET_DSA_BCM_SF2=y
-CONFIG_NET_DSA_TAG_BRCM=y
-CONFIG_NET_DSA_TAG_BRCM_COMMON=y
-CONFIG_NET_DSA_TAG_BRCM_LEGACY=y
-CONFIG_NET_DSA_TAG_BRCM_PREPEND=y
-CONFIG_NET_FLOW_LIMIT=y
-CONFIG_NET_SELFTESTS=y
-CONFIG_NET_SWITCHDEV=y
-CONFIG_NO_IOPORT_MAP=y
-CONFIG_NR_CPUS=4
-CONFIG_NVMEM=y
-CONFIG_NVMEM_SYSFS=y
-CONFIG_NVMEM_U_BOOT_ENV=y
-CONFIG_OF=y
-CONFIG_OF_ADDRESS=y
-CONFIG_OF_EARLY_FLATTREE=y
-CONFIG_OF_FLATTREE=y
-CONFIG_OF_GPIO=y
-CONFIG_OF_IRQ=y
-CONFIG_OF_KOBJ=y
-CONFIG_OF_MDIO=y
-CONFIG_PADATA=y
-CONFIG_PARTITION_PERCPU=y
-CONFIG_PGTABLE_LEVELS=3
-CONFIG_PHYLIB=y
-CONFIG_PHYLINK=y
-CONFIG_PHYS_ADDR_T_64BIT=y
-# CONFIG_PHY_BRCM_SATA is not set
-CONFIG_PHY_BRCM_USB=y
-CONFIG_PINCTRL=y
-CONFIG_PINCTRL_BCM4908=y
-# CONFIG_PINCTRL_SINGLE is not set
-CONFIG_PM=y
-CONFIG_PM_CLK=y
-CONFIG_PM_GENERIC_DOMAINS=y
-CONFIG_PM_GENERIC_DOMAINS_OF=y
-CONFIG_POWER_RESET=y
-CONFIG_POWER_RESET_SYSCON=y
-CONFIG_POWER_SUPPLY=y
-CONFIG_PTP_1588_CLOCK_OPTIONAL=y
-CONFIG_QUEUED_RWLOCKS=y
-CONFIG_QUEUED_SPINLOCKS=y
-CONFIG_RATIONAL=y
-CONFIG_REGMAP=y
-CONFIG_REGMAP_MMIO=y
-CONFIG_RELOCATABLE=y
-CONFIG_RFS_ACCEL=y
-CONFIG_RODATA_FULL_DEFAULT_ENABLED=y
-CONFIG_RPS=y
-CONFIG_RWSEM_SPIN_ON_OWNER=y
-# CONFIG_SERIAL_8250 is not set
-CONFIG_SERIAL_BCM63XX=y
-CONFIG_SERIAL_BCM63XX_CONSOLE=y
-CONFIG_SGL_ALLOC=y
-CONFIG_SMP=y
-CONFIG_SOCK_RX_QUEUE_MAPPING=y
-CONFIG_SPARSEMEM=y
-CONFIG_SPARSEMEM_EXTREME=y
-CONFIG_SPARSEMEM_VMEMMAP=y
-CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
-CONFIG_SPARSE_IRQ=y
-CONFIG_SRCU=y
-CONFIG_SWIOTLB=y
-CONFIG_SWPHY=y
-CONFIG_SYSCTL_EXCEPTION_TRACE=y
-CONFIG_THREAD_INFO_IN_TASK=y
-CONFIG_TICK_CPU_ACCOUNTING=y
-CONFIG_TIMER_OF=y
-CONFIG_TIMER_PROBE=y
-CONFIG_TRACE_IRQFLAGS_NMI_SUPPORT=y
-CONFIG_TREE_RCU=y
-CONFIG_TREE_SRCU=y
-CONFIG_UBIFS_FS=y
-CONFIG_UNMAP_KERNEL_AT_EL0=y
-CONFIG_USB_SUPPORT=y
-CONFIG_VMAP_STACK=y
-CONFIG_WATCHDOG_CORE=y
-CONFIG_XPS=y
-CONFIG_XXHASH=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZONE_DMA32=y
-CONFIG_ZSTD_COMPRESS=y
-CONFIG_ZSTD_DECOMPRESS=y
diff --git a/target/linux/bcm4908/patches-6.1/035-v6.2-0001-arm64-dts-broadcom-bcmbca-bcm4908-add-TWD-block-time.patch b/target/linux/bcm4908/patches-6.1/035-v6.2-0001-arm64-dts-broadcom-bcmbca-bcm4908-add-TWD-block-time.patch
deleted file mode 100644
index e175f27891..0000000000
--- a/target/linux/bcm4908/patches-6.1/035-v6.2-0001-arm64-dts-broadcom-bcmbca-bcm4908-add-TWD-block-time.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From 68064196cffea33f090bd2e8d81cd5e20107ecf1 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Thu, 3 Nov 2022 11:53:16 +0100
-Subject: [PATCH] arm64: dts: broadcom: bcmbca: bcm4908: add TWD block timer
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-BCM4908 TWD contains block with 4 timers. Add binding for it.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20221103105316.21294-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi | 5 +++++
- 1 file changed, 5 insertions(+)
-
---- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi
-+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi
-@@ -280,6 +280,11 @@
- #address-cells = <1>;
- #size-cells = <1>;
-
-+ timer@0 {
-+ compatible = "brcm,bcm63138-timer";
-+ reg = <0x0 0x28>;
-+ };
-+
- watchdog@28 {
- compatible = "brcm,bcm6345-wdt";
- reg = <0x28 0x8>;
diff --git a/target/linux/bcm4908/patches-6.1/035-v6.2-0002-arm64-dts-broadcom-bcmbca-bcm6858-add-TWD-block.patch b/target/linux/bcm4908/patches-6.1/035-v6.2-0002-arm64-dts-broadcom-bcmbca-bcm6858-add-TWD-block.patch
deleted file mode 100644
index e8e81ae544..0000000000
--- a/target/linux/bcm4908/patches-6.1/035-v6.2-0002-arm64-dts-broadcom-bcmbca-bcm6858-add-TWD-block.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-From 4f9fb09175e87a233787a2dee1e5dabb14deb022 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Thu, 3 Nov 2022 12:00:15 +0100
-Subject: [PATCH] arm64: dts: broadcom: bcmbca: bcm6858: add TWD block
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-BCM6858 contains TWD block with timers, watchdog, and reset subblocks.
-Describe it.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20221103110015.21761-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- .../boot/dts/broadcom/bcmbca/bcm6858.dtsi | 19 +++++++++++++++++++
- 1 file changed, 19 insertions(+)
-
---- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm6858.dtsi
-+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm6858.dtsi
-@@ -109,6 +109,25 @@
- #size-cells = <1>;
- ranges = <0x0 0x0 0xff800000 0x62000>;
-
-+ twd: timer-mfd@400 {
-+ compatible = "brcm,bcm4908-twd", "simple-mfd", "syscon";
-+ reg = <0x400 0x4c>;
-+ ranges = <0x0 0x400 0x4c>;
-+
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ timer@0 {
-+ compatible = "brcm,bcm63138-timer";
-+ reg = <0x0 0x28>;
-+ };
-+
-+ watchdog@28 {
-+ compatible = "brcm,bcm6345-wdt";
-+ reg = <0x28 0x8>;
-+ };
-+ };
-+
- uart0: serial@640 {
- compatible = "brcm,bcm6345-uart";
- reg = <0x640 0x18>;
diff --git a/target/linux/bcm4908/patches-6.1/035-v6.2-0003-arm64-dts-Update-cache-properties-for-broadcom.patch b/target/linux/bcm4908/patches-6.1/035-v6.2-0003-arm64-dts-Update-cache-properties-for-broadcom.patch
deleted file mode 100644
index a19ab8cf8f..0000000000
--- a/target/linux/bcm4908/patches-6.1/035-v6.2-0003-arm64-dts-Update-cache-properties-for-broadcom.patch
+++ /dev/null
@@ -1,134 +0,0 @@
-From e567e58d6819adc002c57b81e16b88da24d3b4aa Mon Sep 17 00:00:00 2001
-From: Pierre Gondois <pierre.gondois@arm.com>
-Date: Tue, 22 Nov 2022 17:32:07 +0100
-Subject: [PATCH] arm64: dts: Update cache properties for broadcom
-
-The DeviceTree Specification v0.3 specifies that the cache node
-'compatible' and 'cache-level' properties are 'required'. Cf.
-s3.8 Multi-level and Shared Cache Nodes
-The 'cache-unified' property should be present if one of the
-properties for unified cache is present ('cache-size', ...).
-
-Update the Device Trees accordingly.
-
-Acked-by: William Zhang <william.zhang@broadcom.com>
-Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
-Link: https://lore.kernel.org/r/20221122163208.3810985-3-pierre.gondois@arm.com
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi | 1 +
- arch/arm64/boot/dts/broadcom/bcmbca/bcm4912.dtsi | 1 +
- arch/arm64/boot/dts/broadcom/bcmbca/bcm63146.dtsi | 1 +
- arch/arm64/boot/dts/broadcom/bcmbca/bcm63158.dtsi | 1 +
- arch/arm64/boot/dts/broadcom/bcmbca/bcm6813.dtsi | 1 +
- arch/arm64/boot/dts/broadcom/bcmbca/bcm6856.dtsi | 1 +
- arch/arm64/boot/dts/broadcom/bcmbca/bcm6858.dtsi | 1 +
- arch/arm64/boot/dts/broadcom/northstar2/ns2.dtsi | 1 +
- arch/arm64/boot/dts/broadcom/stingray/stingray.dtsi | 4 ++++
- 9 files changed, 12 insertions(+)
-
---- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi
-+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi
-@@ -63,6 +63,7 @@
-
- l2: l2-cache0 {
- compatible = "cache";
-+ cache-level = <2>;
- };
- };
-
---- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4912.dtsi
-+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4912.dtsi
-@@ -51,6 +51,7 @@
-
- L2_0: l2-cache0 {
- compatible = "cache";
-+ cache-level = <2>;
- };
- };
-
---- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm63146.dtsi
-+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm63146.dtsi
-@@ -35,6 +35,7 @@
-
- L2_0: l2-cache0 {
- compatible = "cache";
-+ cache-level = <2>;
- };
- };
-
---- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm63158.dtsi
-+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm63158.dtsi
-@@ -51,6 +51,7 @@
-
- L2_0: l2-cache0 {
- compatible = "cache";
-+ cache-level = <2>;
- };
- };
-
---- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm6813.dtsi
-+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm6813.dtsi
-@@ -51,6 +51,7 @@
-
- L2_0: l2-cache0 {
- compatible = "cache";
-+ cache-level = <2>;
- };
- };
-
---- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm6856.dtsi
-+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm6856.dtsi
-@@ -35,6 +35,7 @@
-
- L2_0: l2-cache0 {
- compatible = "cache";
-+ cache-level = <2>;
- };
- };
-
---- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm6858.dtsi
-+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm6858.dtsi
-@@ -50,6 +50,7 @@
- };
- L2_0: l2-cache0 {
- compatible = "cache";
-+ cache-level = <2>;
- };
- };
-
---- a/arch/arm64/boot/dts/broadcom/northstar2/ns2.dtsi
-+++ b/arch/arm64/boot/dts/broadcom/northstar2/ns2.dtsi
-@@ -79,6 +79,7 @@
-
- CLUSTER0_L2: l2-cache@0 {
- compatible = "cache";
-+ cache-level = <2>;
- };
- };
-
---- a/arch/arm64/boot/dts/broadcom/stingray/stingray.dtsi
-+++ b/arch/arm64/boot/dts/broadcom/stingray/stingray.dtsi
-@@ -108,18 +108,22 @@
-
- CLUSTER0_L2: l2-cache@0 {
- compatible = "cache";
-+ cache-level = <2>;
- };
-
- CLUSTER1_L2: l2-cache@100 {
- compatible = "cache";
-+ cache-level = <2>;
- };
-
- CLUSTER2_L2: l2-cache@200 {
- compatible = "cache";
-+ cache-level = <2>;
- };
-
- CLUSTER3_L2: l2-cache@300 {
- compatible = "cache";
-+ cache-level = <2>;
- };
- };
-
diff --git a/target/linux/bcm4908/patches-6.1/036-v6.4-0001-arm64-dts-broadcom-bcmbca-Add-spi-controller-node.patch b/target/linux/bcm4908/patches-6.1/036-v6.4-0001-arm64-dts-broadcom-bcmbca-Add-spi-controller-node.patch
deleted file mode 100644
index 7476aed05b..0000000000
--- a/target/linux/bcm4908/patches-6.1/036-v6.4-0001-arm64-dts-broadcom-bcmbca-Add-spi-controller-node.patch
+++ /dev/null
@@ -1,367 +0,0 @@
-From f5d83b714e304d5f3229da434af2eeea033c4f5d Mon Sep 17 00:00:00 2001
-From: William Zhang <william.zhang@broadcom.com>
-Date: Mon, 6 Feb 2023 22:58:15 -0800
-Subject: [PATCH] arm64: dts: broadcom: bcmbca: Add spi controller node
-
-Add support for HSSPI controller in ARMv8 chip dts files.
-
-Signed-off-by: William Zhang <william.zhang@broadcom.com>
-Link: https://lore.kernel.org/r/20230207065826.285013-5-william.zhang@broadcom.com
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- .../boot/dts/broadcom/bcmbca/bcm4908.dtsi | 18 +++++++++++++++++
- .../boot/dts/broadcom/bcmbca/bcm4912.dtsi | 20 +++++++++++++++++++
- .../boot/dts/broadcom/bcmbca/bcm63146.dtsi | 19 ++++++++++++++++++
- .../boot/dts/broadcom/bcmbca/bcm63158.dtsi | 19 ++++++++++++++++++
- .../boot/dts/broadcom/bcmbca/bcm6813.dtsi | 20 +++++++++++++++++++
- .../boot/dts/broadcom/bcmbca/bcm6856.dtsi | 18 +++++++++++++++++
- .../boot/dts/broadcom/bcmbca/bcm6858.dtsi | 18 +++++++++++++++++
- .../boot/dts/broadcom/bcmbca/bcm94908.dts | 4 ++++
- .../boot/dts/broadcom/bcmbca/bcm94912.dts | 4 ++++
- .../boot/dts/broadcom/bcmbca/bcm963146.dts | 4 ++++
- .../boot/dts/broadcom/bcmbca/bcm963158.dts | 4 ++++
- .../boot/dts/broadcom/bcmbca/bcm96813.dts | 4 ++++
- .../boot/dts/broadcom/bcmbca/bcm96856.dts | 4 ++++
- .../boot/dts/broadcom/bcmbca/bcm96858.dts | 4 ++++
- 14 files changed, 160 insertions(+)
-
---- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi
-+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi
-@@ -107,6 +107,12 @@
- clock-frequency = <50000000>;
- clock-output-names = "periph";
- };
-+
-+ hsspi_pll: hsspi-pll {
-+ compatible = "fixed-clock";
-+ #clock-cells = <0>;
-+ clock-frequency = <400000000>;
-+ };
- };
-
- soc {
-@@ -528,6 +534,18 @@
- #size-cells = <0>;
- };
-
-+ hsspi: spi@1000{
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ compatible = "brcm,bcm4908-hsspi", "brcm,bcmbca-hsspi-v1.0";
-+ reg = <0x1000 0x600>;
-+ interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
-+ clocks = <&hsspi_pll &hsspi_pll>;
-+ clock-names = "hsspi", "pll";
-+ num-cs = <8>;
-+ status = "disabled";
-+ };
-+
- nand-controller@1800 {
- #address-cells = <1>;
- #size-cells = <0>;
---- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4912.dtsi
-+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4912.dtsi
-@@ -79,6 +79,7 @@
- #clock-cells = <0>;
- clock-frequency = <200000000>;
- };
-+
- uart_clk: uart-clk {
- compatible = "fixed-factor-clock";
- #clock-cells = <0>;
-@@ -86,6 +87,12 @@
- clock-div = <4>;
- clock-mult = <1>;
- };
-+
-+ hsspi_pll: hsspi-pll {
-+ compatible = "fixed-clock";
-+ #clock-cells = <0>;
-+ clock-frequency = <200000000>;
-+ };
- };
-
- psci {
-@@ -117,6 +124,19 @@
- #size-cells = <1>;
- ranges = <0x0 0x0 0xff800000 0x800000>;
-
-+ hsspi: spi@1000 {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ compatible = "brcm,bcm4912-hsspi", "brcm,bcmbca-hsspi-v1.1";
-+ reg = <0x1000 0x600>, <0x2610 0x4>;
-+ reg-names = "hsspi", "spim-ctrl";
-+ interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
-+ clocks = <&hsspi_pll &hsspi_pll>;
-+ clock-names = "hsspi", "pll";
-+ num-cs = <8>;
-+ status = "disabled";
-+ };
-+
- uart0: serial@12000 {
- compatible = "arm,pl011", "arm,primecell";
- reg = <0x12000 0x1000>;
---- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm63146.dtsi
-+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm63146.dtsi
-@@ -60,6 +60,7 @@
- #clock-cells = <0>;
- clock-frequency = <200000000>;
- };
-+
- uart_clk: uart-clk {
- compatible = "fixed-factor-clock";
- #clock-cells = <0>;
-@@ -67,6 +68,12 @@
- clock-div = <4>;
- clock-mult = <1>;
- };
-+
-+ hsspi_pll: hsspi-pll {
-+ compatible = "fixed-clock";
-+ #clock-cells = <0>;
-+ clock-frequency = <200000000>;
-+ };
- };
-
- psci {
-@@ -99,6 +106,18 @@
- #size-cells = <1>;
- ranges = <0x0 0x0 0xff800000 0x800000>;
-
-+ hsspi: spi@1000 {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ compatible = "brcm,bcm63146-hsspi", "brcm,bcmbca-hsspi-v1.0";
-+ reg = <0x1000 0x600>;
-+ interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
-+ clocks = <&hsspi_pll &hsspi_pll>;
-+ clock-names = "hsspi", "pll";
-+ num-cs = <8>;
-+ status = "disabled";
-+ };
-+
- uart0: serial@12000 {
- compatible = "arm,pl011", "arm,primecell";
- reg = <0x12000 0x1000>;
---- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm63158.dtsi
-+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm63158.dtsi
-@@ -79,6 +79,7 @@
- #clock-cells = <0>;
- clock-frequency = <200000000>;
- };
-+
- uart_clk: uart-clk {
- compatible = "fixed-factor-clock";
- #clock-cells = <0>;
-@@ -86,6 +87,12 @@
- clock-div = <4>;
- clock-mult = <1>;
- };
-+
-+ hsspi_pll: hsspi-pll {
-+ compatible = "fixed-clock";
-+ #clock-cells = <0>;
-+ clock-frequency = <400000000>;
-+ };
- };
-
- psci {
-@@ -117,6 +124,18 @@
- #size-cells = <1>;
- ranges = <0x0 0x0 0xff800000 0x800000>;
-
-+ hsspi: spi@1000 {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ compatible = "brcm,bcm63158-hsspi", "brcm,bcmbca-hsspi-v1.0";
-+ reg = <0x1000 0x600>;
-+ interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
-+ clocks = <&hsspi_pll &hsspi_pll>;
-+ clock-names = "hsspi", "pll";
-+ num-cs = <8>;
-+ status = "disabled";
-+ };
-+
- uart0: serial@12000 {
- compatible = "arm,pl011", "arm,primecell";
- reg = <0x12000 0x1000>;
---- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm6813.dtsi
-+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm6813.dtsi
-@@ -79,6 +79,7 @@
- #clock-cells = <0>;
- clock-frequency = <200000000>;
- };
-+
- uart_clk: uart-clk {
- compatible = "fixed-factor-clock";
- #clock-cells = <0>;
-@@ -86,6 +87,12 @@
- clock-div = <4>;
- clock-mult = <1>;
- };
-+
-+ hsspi_pll: hsspi-pll {
-+ compatible = "fixed-clock";
-+ #clock-cells = <0>;
-+ clock-frequency = <200000000>;
-+ };
- };
-
- psci {
-@@ -117,6 +124,19 @@
- #size-cells = <1>;
- ranges = <0x0 0x0 0xff800000 0x800000>;
-
-+ hsspi: spi@1000 {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ compatible = "brcm,bcm6813-hsspi", "brcm,bcmbca-hsspi-v1.1";
-+ reg = <0x1000 0x600>, <0x2610 0x4>;
-+ reg-names = "hsspi", "spim-ctrl";
-+ interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
-+ clocks = <&hsspi_pll &hsspi_pll>;
-+ clock-names = "hsspi", "pll";
-+ num-cs = <8>;
-+ status = "disabled";
-+ };
-+
- uart0: serial@12000 {
- compatible = "arm,pl011", "arm,primecell";
- reg = <0x12000 0x1000>;
---- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm6856.dtsi
-+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm6856.dtsi
-@@ -60,6 +60,12 @@
- #clock-cells = <0>;
- clock-frequency = <200000000>;
- };
-+
-+ hsspi_pll: hsspi-pll {
-+ compatible = "fixed-clock";
-+ #clock-cells = <0>;
-+ clock-frequency = <400000000>;
-+ };
- };
-
- psci {
-@@ -100,5 +106,17 @@
- clock-names = "refclk";
- status = "disabled";
- };
-+
-+ hsspi: spi@1000 {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ compatible = "brcm,bcm6856-hsspi", "brcm,bcmbca-hsspi-v1.0";
-+ reg = <0x1000 0x600>;
-+ interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
-+ clocks = <&hsspi_pll &hsspi_pll>;
-+ clock-names = "hsspi", "pll";
-+ num-cs = <8>;
-+ status = "disabled";
-+ };
- };
- };
---- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm6858.dtsi
-+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm6858.dtsi
-@@ -78,6 +78,12 @@
- #clock-cells = <0>;
- clock-frequency = <200000000>;
- };
-+
-+ hsspi_pll: hsspi-pll {
-+ compatible = "fixed-clock";
-+ #clock-cells = <0>;
-+ clock-frequency = <400000000>;
-+ };
- };
-
- psci {
-@@ -137,5 +143,17 @@
- clock-names = "refclk";
- status = "disabled";
- };
-+
-+ hsspi: spi@1000 {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ compatible = "brcm,bcm6858-hsspi", "brcm,bcmbca-hsspi-v1.0";
-+ reg = <0x1000 0x600>;
-+ interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
-+ clocks = <&hsspi_pll &hsspi_pll>;
-+ clock-names = "hsspi", "pll";
-+ num-cs = <8>;
-+ status = "disabled";
-+ };
- };
- };
---- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm94908.dts
-+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm94908.dts
-@@ -28,3 +28,7 @@
- &uart0 {
- status = "okay";
- };
-+
-+&hsspi {
-+ status = "okay";
-+};
---- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm94912.dts
-+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm94912.dts
-@@ -28,3 +28,7 @@
- &uart0 {
- status = "okay";
- };
-+
-+&hsspi {
-+ status = "okay";
-+};
---- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm963146.dts
-+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm963146.dts
-@@ -28,3 +28,7 @@
- &uart0 {
- status = "okay";
- };
-+
-+&hsspi {
-+ status = "okay";
-+};
---- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm963158.dts
-+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm963158.dts
-@@ -28,3 +28,7 @@
- &uart0 {
- status = "okay";
- };
-+
-+&hsspi {
-+ status = "okay";
-+};
---- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm96813.dts
-+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm96813.dts
-@@ -28,3 +28,7 @@
- &uart0 {
- status = "okay";
- };
-+
-+&hsspi {
-+ status = "okay";
-+};
---- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm96856.dts
-+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm96856.dts
-@@ -28,3 +28,7 @@
- &uart0 {
- status = "okay";
- };
-+
-+&hsspi {
-+ status = "okay";
-+};
---- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm96858.dts
-+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm96858.dts
-@@ -28,3 +28,7 @@
- &uart0 {
- status = "okay";
- };
-+
-+&hsspi {
-+ status = "okay";
-+};
diff --git a/target/linux/bcm4908/patches-6.1/036-v6.4-0005-arm64-dts-broadcom-bcmbca-bcm4908-add-on-SoC-USB-por.patch b/target/linux/bcm4908/patches-6.1/036-v6.4-0005-arm64-dts-broadcom-bcmbca-bcm4908-add-on-SoC-USB-por.patch
deleted file mode 100644
index 47b2455ae6..0000000000
--- a/target/linux/bcm4908/patches-6.1/036-v6.4-0005-arm64-dts-broadcom-bcmbca-bcm4908-add-on-SoC-USB-por.patch
+++ /dev/null
@@ -1,81 +0,0 @@
-From 477cad715de1dfc256a20da3ed83b62f3cb2944d Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Tue, 28 Feb 2023 15:45:18 +0100
-Subject: [PATCH] arm64: dts: broadcom: bcmbca: bcm4908: add on-SoC USB ports
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-BCM4908 has 3 USB controllers each with 2 USB ports. Home routers often
-have LEDs indicating state of selected USB ports. Describe those SoC USB
-ports to allow using them as LED trigger sources.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/all/20230228144520.21816-1-zajec5@gmail.com/
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- .../boot/dts/broadcom/bcmbca/bcm4908.dtsi | 39 +++++++++++++++++++
- 1 file changed, 39 insertions(+)
-
---- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi
-+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi
-@@ -148,6 +148,19 @@
- interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
- phys = <&usb_phy PHY_TYPE_USB2>;
- status = "disabled";
-+
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ ehci_port1: port@1 {
-+ reg = <1>;
-+ #trigger-source-cells = <0>;
-+ };
-+
-+ ehci_port2: port@2 {
-+ reg = <2>;
-+ #trigger-source-cells = <0>;
-+ };
- };
-
- ohci: usb@c400 {
-@@ -156,6 +169,19 @@
- interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
- phys = <&usb_phy PHY_TYPE_USB2>;
- status = "disabled";
-+
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ ohci_port1: port@1 {
-+ reg = <1>;
-+ #trigger-source-cells = <0>;
-+ };
-+
-+ ohci_port2: port@2 {
-+ reg = <2>;
-+ #trigger-source-cells = <0>;
-+ };
- };
-
- xhci: usb@d000 {
-@@ -164,6 +190,19 @@
- interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
- phys = <&usb_phy PHY_TYPE_USB3>;
- status = "disabled";
-+
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ xhci_port1: port@1 {
-+ reg = <1>;
-+ #trigger-source-cells = <0>;
-+ };
-+
-+ xhci_port2: port@2 {
-+ reg = <2>;
-+ #trigger-source-cells = <0>;
-+ };
- };
-
- bus@80000 {
diff --git a/target/linux/bcm4908/patches-6.1/036-v6.4-0006-arm64-dts-broadcom-bcmbca-bcm4908-add-Netgear-R8000P.patch b/target/linux/bcm4908/patches-6.1/036-v6.4-0006-arm64-dts-broadcom-bcmbca-bcm4908-add-Netgear-R8000P.patch
deleted file mode 100644
index 3e210d68e1..0000000000
--- a/target/linux/bcm4908/patches-6.1/036-v6.4-0006-arm64-dts-broadcom-bcmbca-bcm4908-add-Netgear-R8000P.patch
+++ /dev/null
@@ -1,38 +0,0 @@
-From 889e53ccccc29ff4bf8d4c89cca34e8768845747 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Tue, 28 Feb 2023 15:45:19 +0100
-Subject: [PATCH] arm64: dts: broadcom: bcmbca: bcm4908: add Netgear R8000P USB
- LED triggers
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This device has 2 USB LEDs meant to be triggered by devices in relevant
-USB ports.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/all/20230228144520.21816-2-zajec5@gmail.com/
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- .../arm64/boot/dts/broadcom/bcmbca/bcm4906-netgear-r8000p.dts | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4906-netgear-r8000p.dts
-+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4906-netgear-r8000p.dts
-@@ -58,12 +58,16 @@
- function = "usb2";
- color = <LED_COLOR_ID_WHITE>;
- gpios = <&gpio0 17 GPIO_ACTIVE_LOW>;
-+ trigger-sources = <&ohci_port1>, <&ehci_port1>;
-+ linux,default-trigger = "usbport";
- };
-
- led-usb3 {
- function = "usb3";
- color = <LED_COLOR_ID_WHITE>;
- gpios = <&gpio0 18 GPIO_ACTIVE_LOW>;
-+ trigger-sources = <&ohci_port2>, <&ehci_port2>, <&xhci_port2>;
-+ linux,default-trigger = "usbport";
- };
-
- led-wifi {
diff --git a/target/linux/bcm4908/patches-6.1/036-v6.4-0007-arm64-dts-broadcom-bcmbca-bcm4908-add-TP-Link-C2300-.patch b/target/linux/bcm4908/patches-6.1/036-v6.4-0007-arm64-dts-broadcom-bcmbca-bcm4908-add-TP-Link-C2300-.patch
deleted file mode 100644
index 959ccd4fa3..0000000000
--- a/target/linux/bcm4908/patches-6.1/036-v6.4-0007-arm64-dts-broadcom-bcmbca-bcm4908-add-TP-Link-C2300-.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From e6d356b146b75f1f77621aab7950a1eb550859f9 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Tue, 28 Feb 2023 15:45:20 +0100
-Subject: [PATCH] arm64: dts: broadcom: bcmbca: bcm4908: add TP-Link C2300 USB
- LED triggers
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This device has 2 USB LEDs meant to be triggered by devices in relevant
-USB ports.
-
-While at it fix typo in USB LED name.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/all/20230228144520.21816-3-zajec5@gmail.com/
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- .../dts/broadcom/bcmbca/bcm4906-tplink-archer-c2300-v1.dts | 6 +++++-
- 1 file changed, 5 insertions(+), 1 deletion(-)
-
---- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4906-tplink-archer-c2300-v1.dts
-+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4906-tplink-archer-c2300-v1.dts
-@@ -64,12 +64,16 @@
- function = "usb2";
- color = <LED_COLOR_ID_BLUE>;
- gpios = <&gpio0 15 GPIO_ACTIVE_LOW>;
-+ trigger-sources = <&ohci_port1>, <&ehci_port1>;
-+ linux,default-trigger = "usbport";
- };
-
- led-usb3 {
-- function = "usbd3";
-+ function = "usb3";
- color = <LED_COLOR_ID_BLUE>;
- gpios = <&gpio0 17 GPIO_ACTIVE_LOW>;
-+ trigger-sources = <&ohci_port2>, <&ehci_port2>, <&xhci_port2>;
-+ linux,default-trigger = "usbport";
- };
-
- led-brightness {
diff --git a/target/linux/bcm4908/patches-6.1/072-v6.2-0001-net-broadcom-bcm4908_enet-use-build_skb.patch b/target/linux/bcm4908/patches-6.1/072-v6.2-0001-net-broadcom-bcm4908_enet-use-build_skb.patch
deleted file mode 100644
index 1b4cc9e24c..0000000000
--- a/target/linux/bcm4908/patches-6.1/072-v6.2-0001-net-broadcom-bcm4908_enet-use-build_skb.patch
+++ /dev/null
@@ -1,152 +0,0 @@
-From 3a1cc23a75abcd9cea585eb84846507363d58397 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Tue, 25 Oct 2022 15:22:45 +0200
-Subject: [PATCH] net: broadcom: bcm4908_enet: use build_skb()
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-RX code can be more efficient with the build_skb(). Allocating actual
-SKB around eth packet buffer - right before passing it up - results in
-a better cache usage.
-
-Without RPS (echo 0 > rps_cpus) BCM4908 NAT masq performance "jumps"
-between two speeds: ~900 Mbps and 940 Mbps (it's a 4 CPUs SoC). This
-change bumps the lower speed from 905 Mb/s to 918 Mb/s (tested using
-single stream iperf 2.0.5 traffic).
-
-There are more optimizations to consider. One obvious to try is GRO
-however as BCM4908 doesn't do hw csum is may actually lower performance.
-Sometimes. Some early testing:
-
-┌─────────────────────────────────┬─────────────────────┬────────────────────┐
-│ │ netif_receive_skb() │ napi_gro_receive() │
-├─────────────────────────────────┼─────────────────────┼────────────────────┤
-│ netdev_alloc_skb() │ 905 Mb/s │ 892 Mb/s │
-│ napi_alloc_frag() + build_skb() │ 918 Mb/s │ 917 Mb/s │
-└─────────────────────────────────┴─────────────────────┴────────────────────┘
-
-Another ideas:
-1. napi_build_skb()
-2. skb_copy_from_linear_data() for small packets
-
-Those need proper testing first though. That can be done later.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20221025132245.22871-1-zajec5@gmail.com
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- drivers/net/ethernet/broadcom/bcm4908_enet.c | 53 +++++++++++++-------
- 1 file changed, 36 insertions(+), 17 deletions(-)
-
---- a/drivers/net/ethernet/broadcom/bcm4908_enet.c
-+++ b/drivers/net/ethernet/broadcom/bcm4908_enet.c
-@@ -36,13 +36,24 @@
- #define ENET_MAX_ETH_OVERHEAD (ETH_HLEN + BRCM_MAX_TAG_LEN + VLAN_HLEN + \
- ETH_FCS_LEN + 4) /* 32 */
-
-+#define ENET_RX_SKB_BUF_SIZE (NET_SKB_PAD + NET_IP_ALIGN + \
-+ ETH_HLEN + BRCM_MAX_TAG_LEN + VLAN_HLEN + \
-+ ENET_MTU_MAX + ETH_FCS_LEN + 4)
-+#define ENET_RX_SKB_BUF_ALLOC_SIZE (SKB_DATA_ALIGN(ENET_RX_SKB_BUF_SIZE) + \
-+ SKB_DATA_ALIGN(sizeof(struct skb_shared_info)))
-+#define ENET_RX_BUF_DMA_OFFSET (NET_SKB_PAD + NET_IP_ALIGN)
-+#define ENET_RX_BUF_DMA_SIZE (ENET_RX_SKB_BUF_SIZE - ENET_RX_BUF_DMA_OFFSET)
-+
- struct bcm4908_enet_dma_ring_bd {
- __le32 ctl;
- __le32 addr;
- } __packed;
-
- struct bcm4908_enet_dma_ring_slot {
-- struct sk_buff *skb;
-+ union {
-+ void *buf; /* RX */
-+ struct sk_buff *skb; /* TX */
-+ };
- unsigned int len;
- dma_addr_t dma_addr;
- };
-@@ -260,22 +271,21 @@ static int bcm4908_enet_dma_alloc_rx_buf
- u32 tmp;
- int err;
-
-- slot->len = ENET_MTU_MAX + ENET_MAX_ETH_OVERHEAD;
--
-- slot->skb = netdev_alloc_skb(enet->netdev, slot->len);
-- if (!slot->skb)
-+ slot->buf = napi_alloc_frag(ENET_RX_SKB_BUF_ALLOC_SIZE);
-+ if (!slot->buf)
- return -ENOMEM;
-
-- slot->dma_addr = dma_map_single(dev, slot->skb->data, slot->len, DMA_FROM_DEVICE);
-+ slot->dma_addr = dma_map_single(dev, slot->buf + ENET_RX_BUF_DMA_OFFSET,
-+ ENET_RX_BUF_DMA_SIZE, DMA_FROM_DEVICE);
- err = dma_mapping_error(dev, slot->dma_addr);
- if (err) {
- dev_err(dev, "Failed to map DMA buffer: %d\n", err);
-- kfree_skb(slot->skb);
-- slot->skb = NULL;
-+ skb_free_frag(slot->buf);
-+ slot->buf = NULL;
- return err;
- }
-
-- tmp = slot->len << DMA_CTL_LEN_DESC_BUFLENGTH_SHIFT;
-+ tmp = ENET_RX_BUF_DMA_SIZE << DMA_CTL_LEN_DESC_BUFLENGTH_SHIFT;
- tmp |= DMA_CTL_STATUS_OWN;
- if (idx == enet->rx_ring.length - 1)
- tmp |= DMA_CTL_STATUS_WRAP;
-@@ -315,11 +325,11 @@ static void bcm4908_enet_dma_uninit(stru
-
- for (i = rx_ring->length - 1; i >= 0; i--) {
- slot = &rx_ring->slots[i];
-- if (!slot->skb)
-+ if (!slot->buf)
- continue;
- dma_unmap_single(dev, slot->dma_addr, slot->len, DMA_FROM_DEVICE);
-- kfree_skb(slot->skb);
-- slot->skb = NULL;
-+ skb_free_frag(slot->buf);
-+ slot->buf = NULL;
- }
- }
-
-@@ -575,6 +585,7 @@ static int bcm4908_enet_poll_rx(struct n
- while (handled < weight) {
- struct bcm4908_enet_dma_ring_bd *buf_desc;
- struct bcm4908_enet_dma_ring_slot slot;
-+ struct sk_buff *skb;
- u32 ctl;
- int len;
- int err;
-@@ -598,16 +609,24 @@ static int bcm4908_enet_poll_rx(struct n
-
- if (len < ETH_ZLEN ||
- (ctl & (DMA_CTL_STATUS_SOP | DMA_CTL_STATUS_EOP)) != (DMA_CTL_STATUS_SOP | DMA_CTL_STATUS_EOP)) {
-- kfree_skb(slot.skb);
-+ skb_free_frag(slot.buf);
- enet->netdev->stats.rx_dropped++;
- break;
- }
-
-- dma_unmap_single(dev, slot.dma_addr, slot.len, DMA_FROM_DEVICE);
-+ dma_unmap_single(dev, slot.dma_addr, ENET_RX_BUF_DMA_SIZE, DMA_FROM_DEVICE);
-+
-+ skb = build_skb(slot.buf, ENET_RX_SKB_BUF_ALLOC_SIZE);
-+ if (unlikely(!skb)) {
-+ skb_free_frag(slot.buf);
-+ enet->netdev->stats.rx_dropped++;
-+ break;
-+ }
-+ skb_reserve(skb, ENET_RX_BUF_DMA_OFFSET);
-+ skb_put(skb, len - ETH_FCS_LEN);
-+ skb->protocol = eth_type_trans(skb, enet->netdev);
-
-- skb_put(slot.skb, len - ETH_FCS_LEN);
-- slot.skb->protocol = eth_type_trans(slot.skb, enet->netdev);
-- netif_receive_skb(slot.skb);
-+ netif_receive_skb(skb);
-
- enet->netdev->stats.rx_packets++;
- enet->netdev->stats.rx_bytes += len;
diff --git a/target/linux/bcm4908/patches-6.1/072-v6.2-0002-net-broadcom-bcm4908_enet-report-queued-and-transmit.patch b/target/linux/bcm4908/patches-6.1/072-v6.2-0002-net-broadcom-bcm4908_enet-report-queued-and-transmit.patch
deleted file mode 100644
index 544f899070..0000000000
--- a/target/linux/bcm4908/patches-6.1/072-v6.2-0002-net-broadcom-bcm4908_enet-report-queued-and-transmit.patch
+++ /dev/null
@@ -1,45 +0,0 @@
-From 471ef777ec79baadc5cd9773d08f95f49cf5e2b1 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Mon, 31 Oct 2022 11:48:56 +0100
-Subject: [PATCH] net: broadcom: bcm4908_enet: report queued and transmitted
- bytes
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This allows BQL to operate avoiding buffer bloat and reducing latency.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20221031104856.32388-1-zajec5@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/broadcom/bcm4908_enet.c | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- a/drivers/net/ethernet/broadcom/bcm4908_enet.c
-+++ b/drivers/net/ethernet/broadcom/bcm4908_enet.c
-@@ -505,6 +505,7 @@ static int bcm4908_enet_stop(struct net_
- netif_carrier_off(netdev);
- napi_disable(&rx_ring->napi);
- napi_disable(&tx_ring->napi);
-+ netdev_reset_queue(netdev);
-
- bcm4908_enet_dma_rx_ring_disable(enet, &enet->rx_ring);
- bcm4908_enet_dma_tx_ring_disable(enet, &enet->tx_ring);
-@@ -564,6 +565,8 @@ static netdev_tx_t bcm4908_enet_start_xm
- if (ring->write_idx + 1 == ring->length - 1)
- tmp |= DMA_CTL_STATUS_WRAP;
-
-+ netdev_sent_queue(enet->netdev, skb->len);
-+
- buf_desc->addr = cpu_to_le32((uint32_t)slot->dma_addr);
- buf_desc->ctl = cpu_to_le32(tmp);
-
-@@ -671,6 +674,7 @@ static int bcm4908_enet_poll_tx(struct n
- tx_ring->read_idx = 0;
- }
-
-+ netdev_completed_queue(enet->netdev, handled, bytes);
- enet->netdev->stats.tx_packets += handled;
- enet->netdev->stats.tx_bytes += bytes;
-
diff --git a/target/linux/bcm4908/patches-6.1/130-arm64-dts-broadcom-bcmbca-bcm4908-set-brcm-wp-not-co.patch b/target/linux/bcm4908/patches-6.1/130-arm64-dts-broadcom-bcmbca-bcm4908-set-brcm-wp-not-co.patch
deleted file mode 100644
index 46d632e95d..0000000000
--- a/target/linux/bcm4908/patches-6.1/130-arm64-dts-broadcom-bcmbca-bcm4908-set-brcm-wp-not-co.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Thu, 28 Mar 2024 10:24:34 +0100
-Subject: [PATCH] arm64: dts: broadcom: bcmbca: bcm4908: set
- brcm,wp-not-connected
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Every described BCM4908 board has WP pin not connected. This caused
-problems for drivers since day 0 but there was no property to describe
-that properly. Projects like OpenWrt were modifying Linux driver to deal
-with it.
-
-It's not clear if that is hardware limitation or just reference design
-being copied over and over but this applies to all known / supported
-BCM4908 boards. Handle it by marking WP as not connected by default.
-
-Fixes: 2961f69f151c ("arm64: dts: broadcom: add BCM4908 and Asus GT-AC5300 early DTS files")
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
----
-
---- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi
-+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi
-@@ -593,6 +593,7 @@
- reg-names = "nand", "nand-int-base";
- interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
- interrupt-names = "nand_ctlrdy";
-+ brcm,wp-not-connected;
- status = "okay";
-
- nandcs: nand@0 {
diff --git a/target/linux/bcm4908/patches-6.1/180-leds-bcm63138-rename-dependency-symbol-ARCH_BCM4908-.patch b/target/linux/bcm4908/patches-6.1/180-leds-bcm63138-rename-dependency-symbol-ARCH_BCM4908-.patch
deleted file mode 100644
index d3375a74c7..0000000000
--- a/target/linux/bcm4908/patches-6.1/180-leds-bcm63138-rename-dependency-symbol-ARCH_BCM4908-.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 14 Jul 2023 08:28:41 +0200
-Subject: [PATCH] leds: bcm63138: rename dependency symbol ARCH_BCM4908 to
- ARCH_BCMBCA
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Symbol ARCH_BCM4908 has been merged/removed without updating leds
-Kconfig.
-
-Fixes: dd5c672d7ca9 ("arm64: bcmbca: Merge ARCH_BCM4908 to ARCH_BCMBCA")
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
----
- drivers/leds/blink/Kconfig | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/leds/blink/Kconfig
-+++ b/drivers/leds/blink/Kconfig
-@@ -1,10 +1,10 @@
- config LEDS_BCM63138
- tristate "LED Support for Broadcom BCM63138 SoC"
- depends on LEDS_CLASS
-- depends on ARCH_BCM4908 || ARCH_BCM_5301X || BCM63XX || COMPILE_TEST
-+ depends on ARCH_BCMBCA || ARCH_BCM_5301X || BCM63XX || COMPILE_TEST
- depends on HAS_IOMEM
- depends on OF
-- default ARCH_BCM4908
-+ default ARCH_BCMBCA
- help
- This option enables support for LED controller that is part of
- BCM63138 SoC. The same hardware block is known to be also used
diff --git a/target/linux/bcm4908/patches-6.1/300-arm64-dts-broadcom-bcmbca-bcm4908-limit-amount-of-GP.patch b/target/linux/bcm4908/patches-6.1/300-arm64-dts-broadcom-bcmbca-bcm4908-limit-amount-of-GP.patch
deleted file mode 100644
index 4adeef8319..0000000000
--- a/target/linux/bcm4908/patches-6.1/300-arm64-dts-broadcom-bcmbca-bcm4908-limit-amount-of-GP.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Mon, 15 Feb 2021 22:01:03 +0100
-Subject: [PATCH] arm64: dts: broadcom: bcmbca: bcm4908: limit amount of GPIOs
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Linux driver can't handle more than 64 GPIOs
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
----
-
---- a/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi
-+++ b/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi
-@@ -340,7 +340,7 @@
- gpio0: gpio-controller@500 {
- compatible = "brcm,bcm6345-gpio";
- reg-names = "dirout", "dat";
-- reg = <0x500 0x28>, <0x528 0x28>;
-+ reg = <0x500 0x8>, <0x528 0x8>;
-
- #gpio-cells = <2>;
- gpio-controller;
diff --git a/target/linux/bcm4908/patches-6.1/301-arm64-don-t-issue-HVC-on-boot.patch b/target/linux/bcm4908/patches-6.1/301-arm64-don-t-issue-HVC-on-boot.patch
deleted file mode 100644
index 8c71301c21..0000000000
--- a/target/linux/bcm4908/patches-6.1/301-arm64-don-t-issue-HVC-on-boot.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Thu, 12 Aug 2021 11:52:42 +0200
-Subject: [PATCH] arm64: don't issue HVC on boot
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Broadcom's CFE loader seems to miss setting SCR_EL3.HCE which results in
-generating an UNDEF and kernel panic on the first HVC.
-
-HVC gets issued by kernels 5.12+ while booting, by kexec and KVM. Until
-someone finds a workaround we have to avoid all above.
-
-Workarounds: 0c93df9622d4 ("arm64: Initialise as nVHE before switching to VHE")
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
----
- arch/arm64/kernel/hyp-stub.S | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/arch/arm64/kernel/hyp-stub.S
-+++ b/arch/arm64/kernel/hyp-stub.S
-@@ -301,7 +301,7 @@ SYM_FUNC_START(finalise_el2)
- b.ne 1f
-
- mov x0, #HVC_FINALISE_EL2
-- hvc #0
-+// hvc #0
- 1:
- ret
- SYM_FUNC_END(finalise_el2)
diff --git a/target/linux/bcm4908/patches-6.1/700-net-dsa-bcm_sf2-enable-GPHY-for-switch-probing.patch b/target/linux/bcm4908/patches-6.1/700-net-dsa-bcm_sf2-enable-GPHY-for-switch-probing.patch
deleted file mode 100644
index cf089fec61..0000000000
--- a/target/linux/bcm4908/patches-6.1/700-net-dsa-bcm_sf2-enable-GPHY-for-switch-probing.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Mon, 15 Feb 2021 23:59:26 +0100
-Subject: [PATCH] net: dsa: bcm_sf2: enable GPHY for switch probing
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-GPHY needs to be enabled to succesfully probe & setup switch port
-connected to it. Otherwise hardcoding PHY OUI would be required.
-
-Before:
-brcm-sf2 80080000.switch lan4 (uninitialized): PHY [800c05c0.mdio--1:08] driver [Generic PHY] (irq=POLL)
-brcm-sf2 80080000.switch lan3 (uninitialized): PHY [800c05c0.mdio--1:09] driver [Generic PHY] (irq=POLL)
-brcm-sf2 80080000.switch lan2 (uninitialized): PHY [800c05c0.mdio--1:0a] driver [Generic PHY] (irq=POLL)
-brcm-sf2 80080000.switch lan1 (uninitialized): PHY [800c05c0.mdio--1:0b] driver [Generic PHY] (irq=POLL)
-brcm-sf2 80080000.switch wan (uninitialized): error -5 setting up PHY for tree 0, switch 0, port 7
-
-After:
-brcm-sf2 80080000.switch lan4 (uninitialized): PHY [800c05c0.mdio--1:08] driver [Generic PHY] (irq=POLL)
-brcm-sf2 80080000.switch lan3 (uninitialized): PHY [800c05c0.mdio--1:09] driver [Generic PHY] (irq=POLL)
-brcm-sf2 80080000.switch lan2 (uninitialized): PHY [800c05c0.mdio--1:0a] driver [Generic PHY] (irq=POLL)
-brcm-sf2 80080000.switch lan1 (uninitialized): PHY [800c05c0.mdio--1:0b] driver [Generic PHY] (irq=POLL)
-brcm-sf2 80080000.switch wan (uninitialized): PHY [800c05c0.mdio--1:0c] driver [Generic PHY] (irq=POLL)
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
----
- drivers/net/dsa/bcm_sf2.c | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- a/drivers/net/dsa/bcm_sf2.c
-+++ b/drivers/net/dsa/bcm_sf2.c
-@@ -1522,10 +1522,14 @@ static int bcm_sf2_sw_probe(struct platf
- rev = reg_readl(priv, REG_PHY_REVISION);
- priv->hw_params.gphy_rev = rev & PHY_REVISION_MASK;
-
-+ bcm_sf2_gphy_enable_set(priv->dev->ds, true);
-+
- ret = b53_switch_register(dev);
- if (ret)
- goto out_mdio;
-
-+ bcm_sf2_gphy_enable_set(priv->dev->ds, false);
-+
- dev_info(&pdev->dev,
- "Starfighter 2 top: %x.%02x, core: %x.%02x, IRQs: %d, %d\n",
- priv->hw_params.top_rev >> 8, priv->hw_params.top_rev & 0xff,
diff --git a/target/linux/bcm4908/patches-6.1/701-net-dsa-bcm_sf2-keep-GPHY-enabled-on-the-BCM4908.patch b/target/linux/bcm4908/patches-6.1/701-net-dsa-bcm_sf2-keep-GPHY-enabled-on-the-BCM4908.patch
deleted file mode 100644
index 865eac729a..0000000000
--- a/target/linux/bcm4908/patches-6.1/701-net-dsa-bcm_sf2-keep-GPHY-enabled-on-the-BCM4908.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Tue, 16 Feb 2021 00:06:35 +0100
-Subject: [PATCH] net: dsa: bcm_sf2: keep GPHY enabled on the BCM4908
-
-Trying to access disabled PHY results in MDIO_READ_FAIL and:
-[ 11.962886] brcm-sf2 80080000.switch wan: configuring for phy/internal link mode
-[ 11.972500] 8021q: adding VLAN 0 to HW filter on device wan
-[ 11.980205] ------------[ cut here ]------------
-[ 11.984885] WARNING: CPU: 0 PID: 7 at phy_error+0x10/0x58
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
----
- drivers/net/dsa/bcm_sf2.c | 6 ++++++
- 1 file changed, 6 insertions(+)
-
---- a/drivers/net/dsa/bcm_sf2.c
-+++ b/drivers/net/dsa/bcm_sf2.c
-@@ -1536,6 +1536,12 @@ static int bcm_sf2_sw_probe(struct platf
- priv->hw_params.core_rev >> 8, priv->hw_params.core_rev & 0xff,
- priv->irq0, priv->irq1);
-
-+ /* BCM4908 has 5 GPHYs which means bcm_sf2_port_setup() will not enable
-+ * GPHY when needed. Leave it enabled here.
-+ */
-+ if (priv->type == BCM4908_DEVICE_ID)
-+ bcm_sf2_gphy_enable_set(priv->dev->ds, true);
-+
- return 0;
-
- out_mdio:
diff --git a/target/linux/bcm4908/patches-6.6/700-net-dsa-bcm_sf2-enable-GPHY-for-switch-probing.patch b/target/linux/bcm4908/patches-6.6/700-net-dsa-bcm_sf2-enable-GPHY-for-switch-probing.patch
index cf089fec61..8961bb298c 100644
--- a/target/linux/bcm4908/patches-6.6/700-net-dsa-bcm_sf2-enable-GPHY-for-switch-probing.patch
+++ b/target/linux/bcm4908/patches-6.6/700-net-dsa-bcm_sf2-enable-GPHY-for-switch-probing.patch
@@ -29,7 +29,7 @@ Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
--- a/drivers/net/dsa/bcm_sf2.c
+++ b/drivers/net/dsa/bcm_sf2.c
-@@ -1522,10 +1522,14 @@ static int bcm_sf2_sw_probe(struct platf
+@@ -1524,10 +1524,14 @@ static int bcm_sf2_sw_probe(struct platf
rev = reg_readl(priv, REG_PHY_REVISION);
priv->hw_params.gphy_rev = rev & PHY_REVISION_MASK;
diff --git a/target/linux/bcm4908/patches-6.6/701-net-dsa-bcm_sf2-keep-GPHY-enabled-on-the-BCM4908.patch b/target/linux/bcm4908/patches-6.6/701-net-dsa-bcm_sf2-keep-GPHY-enabled-on-the-BCM4908.patch
index 865eac729a..ff3f44910b 100644
--- a/target/linux/bcm4908/patches-6.6/701-net-dsa-bcm_sf2-keep-GPHY-enabled-on-the-BCM4908.patch
+++ b/target/linux/bcm4908/patches-6.6/701-net-dsa-bcm_sf2-keep-GPHY-enabled-on-the-BCM4908.patch
@@ -15,7 +15,7 @@ Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
--- a/drivers/net/dsa/bcm_sf2.c
+++ b/drivers/net/dsa/bcm_sf2.c
-@@ -1536,6 +1536,12 @@ static int bcm_sf2_sw_probe(struct platf
+@@ -1538,6 +1538,12 @@ static int bcm_sf2_sw_probe(struct platf
priv->hw_params.core_rev >> 8, priv->hw_params.core_rev & 0xff,
priv->irq0, priv->irq1);
diff --git a/target/linux/bcm53xx/Makefile b/target/linux/bcm53xx/Makefile
index 5b778454fa..b858d2fdbb 100644
--- a/target/linux/bcm53xx/Makefile
+++ b/target/linux/bcm53xx/Makefile
@@ -11,8 +11,7 @@ FEATURES:=squashfs nand usb pci pcie gpio pwm
CPU_TYPE:=cortex-a9
SUBTARGETS:=generic
-KERNEL_PATCHVER:=6.1
-KERNEL_TESTING_PATCHVER:=6.6
+KERNEL_PATCHVER:=6.6
define Target/Description
Build firmware images for Broadcom based BCM47xx/53xx routers with ARM CPU, *not* MIPS.
diff --git a/target/linux/bcm53xx/config-5.15 b/target/linux/bcm53xx/config-5.15
deleted file mode 100644
index 9cd1f079d1..0000000000
--- a/target/linux/bcm53xx/config-5.15
+++ /dev/null
@@ -1,317 +0,0 @@
-CONFIG_ALIGNMENT_TRAP=y
-CONFIG_ARCH_32BIT_OFF_T=y
-CONFIG_ARCH_BCM=y
-CONFIG_ARCH_BCM_5301X=y
-CONFIG_ARCH_BCM_53573=y
-# CONFIG_ARCH_BCM_HR2 is not set
-CONFIG_ARCH_BCM_IPROC=y
-CONFIG_ARCH_HIBERNATION_POSSIBLE=y
-CONFIG_ARCH_KEEP_MEMBLOCK=y
-CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
-CONFIG_ARCH_MULTIPLATFORM=y
-CONFIG_ARCH_MULTI_V6_V7=y
-CONFIG_ARCH_MULTI_V7=y
-CONFIG_ARCH_NR_GPIO=0
-CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y
-CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y
-CONFIG_ARCH_SELECT_MEMORY_MODEL=y
-CONFIG_ARCH_SPARSEMEM_ENABLE=y
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
-CONFIG_ARM=y
-CONFIG_ARM_AMBA=y
-CONFIG_ARM_APPENDED_DTB=y
-CONFIG_ARM_ARCH_TIMER=y
-CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y
-# CONFIG_ARM_ATAG_DTB_COMPAT is not set
-CONFIG_ARM_CRYPTO=y
-CONFIG_ARM_ERRATA_754322=y
-CONFIG_ARM_ERRATA_764369=y
-CONFIG_ARM_ERRATA_775420=y
-CONFIG_ARM_GIC=y
-CONFIG_ARM_GLOBAL_TIMER=y
-CONFIG_ARM_GT_INITIAL_PRESCALER_VAL=1
-CONFIG_ARM_HAS_SG_CHAIN=y
-CONFIG_ARM_HEAVY_MB=y
-CONFIG_ARM_L1_CACHE_SHIFT=6
-CONFIG_ARM_L1_CACHE_SHIFT_6=y
-CONFIG_ARM_PATCH_IDIV=y
-CONFIG_ARM_PATCH_PHYS_VIRT=y
-CONFIG_ARM_THUMB=y
-CONFIG_ARM_UNWIND=y
-CONFIG_ARM_VIRT_EXT=y
-CONFIG_ATAGS=y
-CONFIG_AUTO_ZRELADDR=y
-CONFIG_B53=y
-CONFIG_B53_MDIO_DRIVER=y
-CONFIG_B53_SRAB_DRIVER=y
-CONFIG_BCM47XX_NVRAM=y
-CONFIG_BCM47XX_SPROM=y
-CONFIG_BCM47XX_WDT=y
-CONFIG_BCMA=y
-CONFIG_BCMA_BLOCKIO=y
-CONFIG_BCMA_DEBUG=y
-CONFIG_BCMA_DRIVER_GMAC_CMN=y
-CONFIG_BCMA_DRIVER_GPIO=y
-CONFIG_BCMA_DRIVER_PCI=y
-CONFIG_BCMA_FALLBACK_SPROM=y
-CONFIG_BCMA_HOST_PCI=y
-CONFIG_BCMA_HOST_PCI_POSSIBLE=y
-CONFIG_BCMA_HOST_SOC=y
-CONFIG_BCMA_SFLASH=y
-# CONFIG_BCM_CYGNUS_PHY is not set
-CONFIG_BCM_NET_PHYLIB=y
-CONFIG_BCM_NS_THERMAL=y
-CONFIG_BCM_SR_THERMAL=y
-CONFIG_BGMAC=y
-CONFIG_BGMAC_BCMA=y
-# CONFIG_BGMAC_PLATFORM is not set
-CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y
-CONFIG_BLK_MQ_PCI=y
-CONFIG_BOUNCE=y
-CONFIG_BROADCOM_PHY=y
-CONFIG_CACHE_L2X0=y
-CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK=y
-CONFIG_CLKSRC_MMIO=y
-# CONFIG_CLK_BCM_NS2 is not set
-CONFIG_CLK_BCM_NSP=y
-# CONFIG_CLK_BCM_SR is not set
-CONFIG_CLONE_BACKWARDS=y
-CONFIG_COMMON_CLK=y
-CONFIG_COMMON_CLK_IPROC=y
-CONFIG_COMPAT_32BIT_TIME=y
-CONFIG_CPU_32v6K=y
-CONFIG_CPU_32v7=y
-CONFIG_CPU_ABRT_EV7=y
-CONFIG_CPU_CACHE_V7=y
-CONFIG_CPU_CACHE_VIPT=y
-CONFIG_CPU_COPY_V6=y
-CONFIG_CPU_CP15=y
-CONFIG_CPU_CP15_MMU=y
-CONFIG_CPU_HAS_ASID=y
-CONFIG_CPU_PABRT_V7=y
-CONFIG_CPU_RMAP=y
-CONFIG_CPU_SPECTRE=y
-CONFIG_CPU_THUMB_CAPABLE=y
-CONFIG_CPU_TLB_V7=y
-CONFIG_CPU_V7=y
-CONFIG_CRC16=y
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_HASH_INFO=y
-CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
-CONFIG_CRYPTO_LZO=y
-CONFIG_CRYPTO_RNG2=y
-CONFIG_CRYPTO_ZSTD=y
-CONFIG_DCACHE_WORD_ACCESS=y
-CONFIG_DEBUG_BCM_5301X=y
-CONFIG_DEBUG_LL=y
-CONFIG_DEBUG_LL_INCLUDE="debug/8250.S"
-CONFIG_DEBUG_MISC=y
-CONFIG_DEBUG_UART_8250=y
-CONFIG_DEBUG_UART_8250_SHIFT=0
-CONFIG_DEBUG_UART_PHYS=0x18000300
-CONFIG_DEBUG_UART_VIRT=0xf1000300
-CONFIG_DEBUG_UNCOMPRESS=y
-CONFIG_DEBUG_USER=y
-CONFIG_DMA_OPS=y
-CONFIG_DMA_REMAP=y
-CONFIG_DTC=y
-CONFIG_EARLY_PRINTK=y
-CONFIG_EDAC_ATOMIC_SCRUB=y
-CONFIG_EDAC_SUPPORT=y
-CONFIG_EXTCON=y
-CONFIG_FIXED_PHY=y
-CONFIG_FIX_EARLYCON_MEM=y
-CONFIG_FWNODE_MDIO=y
-CONFIG_FW_LOADER_PAGED_BUF=y
-# CONFIG_FW_LOADER_USER_HELPER_FALLBACK is not set
-CONFIG_GENERIC_ALLOCATOR=y
-CONFIG_GENERIC_ARCH_TOPOLOGY=y
-CONFIG_GENERIC_BUG=y
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
-CONFIG_GENERIC_CPU_AUTOPROBE=y
-CONFIG_GENERIC_CPU_VULNERABILITIES=y
-CONFIG_GENERIC_EARLY_IOREMAP=y
-CONFIG_GENERIC_GETTIMEOFDAY=y
-CONFIG_GENERIC_IDLE_POLL_SETUP=y
-CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
-CONFIG_GENERIC_IRQ_MULTI_HANDLER=y
-CONFIG_GENERIC_IRQ_SHOW=y
-CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
-CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y
-CONFIG_GENERIC_PCI_IOMAP=y
-CONFIG_GENERIC_PHY=y
-CONFIG_GENERIC_PINCONF=y
-CONFIG_GENERIC_PINCTRL_GROUPS=y
-CONFIG_GENERIC_PINMUX_FUNCTIONS=y
-CONFIG_GENERIC_SCHED_CLOCK=y
-CONFIG_GENERIC_SMP_IDLE_THREAD=y
-CONFIG_GENERIC_STRNCPY_FROM_USER=y
-CONFIG_GENERIC_STRNLEN_USER=y
-CONFIG_GENERIC_TIME_VSYSCALL=y
-CONFIG_GENERIC_VDSO_32=y
-CONFIG_GPIOLIB_IRQCHIP=y
-CONFIG_GPIO_74X164=y
-CONFIG_GPIO_BCM_XGS_IPROC=y
-CONFIG_GPIO_CDEV=y
-CONFIG_GPIO_GENERIC=y
-CONFIG_GRO_CELLS=y
-CONFIG_HANDLE_DOMAIN_IRQ=y
-CONFIG_HARDEN_BRANCH_PREDICTOR=y
-CONFIG_HARDIRQS_SW_RESEND=y
-CONFIG_HAS_DMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT_MAP=y
-CONFIG_HAVE_SMP=y
-CONFIG_HIGHMEM=y
-CONFIG_HIGHPTE=y
-CONFIG_HW_RANDOM=y
-CONFIG_HW_RANDOM_BCM2835=y
-CONFIG_HZ_FIXED=0
-CONFIG_HZ_PERIODIC=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_IRQCHIP=y
-CONFIG_IRQ_DOMAIN=y
-CONFIG_IRQ_DOMAIN_HIERARCHY=y
-CONFIG_IRQ_FORCED_THREADING=y
-CONFIG_IRQ_WORK=y
-CONFIG_KMAP_LOCAL=y
-CONFIG_KMAP_LOCAL_NON_LINEAR_PTE_ARRAY=y
-# CONFIG_LEDS_BCM63138 is not set
-CONFIG_LIBFDT=y
-CONFIG_LOCK_DEBUGGING_SUPPORT=y
-CONFIG_LOCK_SPIN_ON_OWNER=y
-CONFIG_LZO_COMPRESS=y
-CONFIG_LZO_DECOMPRESS=y
-CONFIG_MDIO_BCM_IPROC=y
-CONFIG_MDIO_BUS=y
-CONFIG_MDIO_BUS_MUX=y
-# CONFIG_MDIO_BUS_MUX_BCM_IPROC is not set
-CONFIG_MDIO_BUS_MUX_MMIOREG=y
-CONFIG_MDIO_DEVICE=y
-CONFIG_MDIO_DEVRES=y
-CONFIG_MEMFD_CREATE=y
-CONFIG_MFD_SYSCON=y
-CONFIG_MIGHT_HAVE_CACHE_L2X0=y
-CONFIG_MIGRATION=y
-CONFIG_MODULES_USE_ELF_REL=y
-CONFIG_MTD_BCM47XXSFLASH=y
-CONFIG_MTD_BCM47XX_PARTS=y
-CONFIG_MTD_NAND_BRCMNAND=y
-CONFIG_MTD_NAND_CORE=y
-CONFIG_MTD_NAND_ECC=y
-CONFIG_MTD_NAND_ECC_SW_HAMMING=y
-CONFIG_MTD_OF_PARTS_LINKSYS_NS=y
-CONFIG_MTD_PARSER_TPLINK_SAFELOADER=y
-CONFIG_MTD_PARSER_TRX=y
-CONFIG_MTD_RAW_NAND=y
-CONFIG_MTD_SPI_NOR=y
-CONFIG_MTD_SPLIT_SEAMA_FW=y
-CONFIG_MTD_UBI=y
-CONFIG_MTD_UBI_BEB_LIMIT=20
-CONFIG_MTD_UBI_BLOCK=y
-CONFIG_MTD_UBI_WL_THRESHOLD=4096
-CONFIG_MUTEX_SPIN_ON_OWNER=y
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NET_DEVLINK=y
-CONFIG_NET_DSA=y
-CONFIG_NET_DSA_TAG_BRCM=y
-CONFIG_NET_DSA_TAG_BRCM_COMMON=y
-CONFIG_NET_DSA_TAG_BRCM_LEGACY=y
-CONFIG_NET_DSA_TAG_BRCM_PREPEND=y
-CONFIG_NET_FLOW_LIMIT=y
-CONFIG_NET_SELFTESTS=y
-CONFIG_NET_SWITCHDEV=y
-CONFIG_NR_CPUS=2
-CONFIG_NVMEM=y
-CONFIG_NVMEM_BRCM_NVRAM=y
-CONFIG_NVMEM_SYSFS=y
-CONFIG_OF=y
-CONFIG_OF_ADDRESS=y
-CONFIG_OF_EARLY_FLATTREE=y
-CONFIG_OF_FLATTREE=y
-CONFIG_OF_GPIO=y
-CONFIG_OF_IRQ=y
-CONFIG_OF_KOBJ=y
-CONFIG_OF_MDIO=y
-CONFIG_OLD_SIGACTION=y
-CONFIG_OLD_SIGSUSPEND3=y
-CONFIG_OUTER_CACHE=y
-CONFIG_OUTER_CACHE_SYNC=y
-CONFIG_PADATA=y
-CONFIG_PAGE_OFFSET=0xC0000000
-CONFIG_PCI=y
-CONFIG_PCIE_IPROC=y
-CONFIG_PCIE_IPROC_BCMA=y
-# CONFIG_PCIE_IPROC_PLATFORM is not set
-CONFIG_PCI_DOMAINS=y
-CONFIG_PCI_DOMAINS_GENERIC=y
-CONFIG_PERF_USE_VMALLOC=y
-CONFIG_PGTABLE_LEVELS=2
-CONFIG_PHYLIB=y
-CONFIG_PHYLINK=y
-# CONFIG_PHY_BCM_NS_USB2 is not set
-# CONFIG_PHY_BCM_NS_USB3 is not set
-# CONFIG_PHY_BCM_SR_PCIE is not set
-CONFIG_PHY_BCM_SR_USB=y
-# CONFIG_PHY_BRCM_SATA is not set
-# CONFIG_PHY_NS2_USB_DRD is not set
-CONFIG_PINCTRL=y
-# CONFIG_PINCTRL_IPROC_GPIO is not set
-CONFIG_PINCTRL_NS=y
-# CONFIG_PINCTRL_NS2_MUX is not set
-CONFIG_PTP_1588_CLOCK_OPTIONAL=y
-CONFIG_PWM=y
-CONFIG_PWM_BCM_IPROC=y
-CONFIG_PWM_SYSFS=y
-CONFIG_RATIONAL=y
-CONFIG_REGMAP=y
-CONFIG_REGMAP_MMIO=y
-CONFIG_RFS_ACCEL=y
-CONFIG_RPS=y
-CONFIG_RWSEM_SPIN_ON_OWNER=y
-CONFIG_SERIAL_8250_FSL=y
-CONFIG_SERIAL_MCTRL_GPIO=y
-CONFIG_SERIAL_OF_PLATFORM=y
-CONFIG_SGL_ALLOC=y
-CONFIG_SMP=y
-CONFIG_SMP_ON_UP=y
-CONFIG_SOCK_RX_QUEUE_MAPPING=y
-CONFIG_SPARSE_IRQ=y
-CONFIG_SPI=y
-CONFIG_SPI_BCM_QSPI=y
-CONFIG_SPI_BITBANG=y
-CONFIG_SPI_GPIO=y
-CONFIG_SPI_MASTER=y
-CONFIG_SPI_MEM=y
-CONFIG_SRCU=y
-CONFIG_SWPHY=y
-CONFIG_SWP_EMULATE=y
-CONFIG_SYS_SUPPORTS_APM_EMULATION=y
-CONFIG_THERMAL=y
-CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
-CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
-CONFIG_THERMAL_GOV_STEP_WISE=y
-CONFIG_THERMAL_OF=y
-CONFIG_TICK_CPU_ACCOUNTING=y
-CONFIG_TIMER_OF=y
-CONFIG_TIMER_PROBE=y
-CONFIG_TREE_RCU=y
-CONFIG_TREE_SRCU=y
-CONFIG_UBIFS_FS=y
-CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
-CONFIG_UNWINDER_ARM=y
-CONFIG_USB_SUPPORT=y
-CONFIG_USE_OF=y
-# CONFIG_VFP is not set
-CONFIG_WATCHDOG_CORE=y
-CONFIG_XPS=y
-CONFIG_XXHASH=y
-CONFIG_XZ_DEC_ARM=y
-CONFIG_XZ_DEC_BCJ=y
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZSTD_COMPRESS=y
-CONFIG_ZSTD_DECOMPRESS=y
diff --git a/target/linux/bcm53xx/config-6.1 b/target/linux/bcm53xx/config-6.1
deleted file mode 100644
index 259c6559a6..0000000000
--- a/target/linux/bcm53xx/config-6.1
+++ /dev/null
@@ -1,339 +0,0 @@
-CONFIG_ALIGNMENT_TRAP=y
-CONFIG_ARCH_32BIT_OFF_T=y
-CONFIG_ARCH_BCM=y
-CONFIG_ARCH_BCM_5301X=y
-CONFIG_ARCH_BCM_53573=y
-CONFIG_ARCH_BCM_IPROC=y
-CONFIG_ARCH_HIBERNATION_POSSIBLE=y
-CONFIG_ARCH_KEEP_MEMBLOCK=y
-CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
-CONFIG_ARCH_MULTIPLATFORM=y
-CONFIG_ARCH_MULTI_V6_V7=y
-CONFIG_ARCH_MULTI_V7=y
-CONFIG_ARCH_NR_GPIO=0
-CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y
-CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y
-CONFIG_ARCH_SELECT_MEMORY_MODEL=y
-CONFIG_ARCH_SPARSEMEM_ENABLE=y
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
-CONFIG_ARM=y
-CONFIG_ARM_AMBA=y
-CONFIG_ARM_APPENDED_DTB=y
-CONFIG_ARM_ARCH_TIMER=y
-CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y
-# CONFIG_ARM_ATAG_DTB_COMPAT is not set
-CONFIG_ARM_ERRATA_754322=y
-CONFIG_ARM_ERRATA_764369=y
-CONFIG_ARM_ERRATA_775420=y
-CONFIG_ARM_GIC=y
-CONFIG_ARM_GLOBAL_TIMER=y
-CONFIG_ARM_GT_INITIAL_PRESCALER_VAL=1
-CONFIG_ARM_HAS_GROUP_RELOCS=y
-CONFIG_ARM_HEAVY_MB=y
-CONFIG_ARM_L1_CACHE_SHIFT=6
-CONFIG_ARM_L1_CACHE_SHIFT_6=y
-CONFIG_ARM_PATCH_IDIV=y
-CONFIG_ARM_PATCH_PHYS_VIRT=y
-CONFIG_ARM_THUMB=y
-CONFIG_ARM_UNWIND=y
-CONFIG_ARM_VIRT_EXT=y
-CONFIG_ATAGS=y
-CONFIG_AUTO_ZRELADDR=y
-CONFIG_B53=y
-CONFIG_B53_MDIO_DRIVER=y
-CONFIG_B53_SRAB_DRIVER=y
-CONFIG_BCM47XX_NVRAM=y
-CONFIG_BCM47XX_SPROM=y
-CONFIG_BCM47XX_WDT=y
-CONFIG_BCMA=y
-CONFIG_BCMA_BLOCKIO=y
-CONFIG_BCMA_DEBUG=y
-CONFIG_BCMA_DRIVER_GMAC_CMN=y
-CONFIG_BCMA_DRIVER_GPIO=y
-CONFIG_BCMA_DRIVER_PCI=y
-CONFIG_BCMA_FALLBACK_SPROM=y
-CONFIG_BCMA_HOST_PCI=y
-CONFIG_BCMA_HOST_PCI_POSSIBLE=y
-CONFIG_BCMA_HOST_SOC=y
-CONFIG_BCMA_SFLASH=y
-# CONFIG_BCM_CYGNUS_PHY is not set
-CONFIG_BCM_NET_PHYLIB=y
-CONFIG_BCM_NS_THERMAL=y
-CONFIG_BCM_SR_THERMAL=y
-CONFIG_BGMAC=y
-CONFIG_BGMAC_BCMA=y
-# CONFIG_BGMAC_PLATFORM is not set
-CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y
-CONFIG_BLK_MQ_PCI=y
-CONFIG_BOUNCE=y
-CONFIG_BROADCOM_PHY=y
-CONFIG_CACHE_L2X0=y
-CONFIG_CC_HAVE_STACKPROTECTOR_TLS=y
-CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
-CONFIG_CC_NO_ARRAY_BOUNDS=y
-CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK=y
-CONFIG_CLKSRC_MMIO=y
-# CONFIG_CLK_BCM_NS2 is not set
-CONFIG_CLK_BCM_NSP=y
-# CONFIG_CLK_BCM_SR is not set
-CONFIG_CLONE_BACKWARDS=y
-CONFIG_COMMON_CLK=y
-CONFIG_COMMON_CLK_IPROC=y
-CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
-CONFIG_COMPAT_32BIT_TIME=y
-CONFIG_CONTEXT_TRACKING=y
-CONFIG_CONTEXT_TRACKING_IDLE=y
-CONFIG_CPU_32v6K=y
-CONFIG_CPU_32v7=y
-CONFIG_CPU_ABRT_EV7=y
-CONFIG_CPU_CACHE_V7=y
-CONFIG_CPU_CACHE_VIPT=y
-CONFIG_CPU_COPY_V6=y
-CONFIG_CPU_CP15=y
-CONFIG_CPU_CP15_MMU=y
-CONFIG_CPU_HAS_ASID=y
-CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_CPU_PABRT_V7=y
-CONFIG_CPU_RMAP=y
-CONFIG_CPU_SPECTRE=y
-CONFIG_CPU_THUMB_CAPABLE=y
-CONFIG_CPU_TLB_V7=y
-CONFIG_CPU_V7=y
-CONFIG_CRC16=y
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_HASH_INFO=y
-CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
-CONFIG_CRYPTO_LIB_SHA1=y
-CONFIG_CRYPTO_LIB_UTILS=y
-CONFIG_CRYPTO_LZO=y
-CONFIG_CRYPTO_RNG2=y
-CONFIG_CRYPTO_ZSTD=y
-CONFIG_CURRENT_POINTER_IN_TPIDRURO=y
-CONFIG_DCACHE_WORD_ACCESS=y
-CONFIG_DEBUG_BCM_5301X=y
-CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_LL=y
-CONFIG_DEBUG_LL_INCLUDE="debug/8250.S"
-CONFIG_DEBUG_MISC=y
-CONFIG_DEBUG_UART_8250=y
-CONFIG_DEBUG_UART_8250_SHIFT=0
-CONFIG_DEBUG_UART_PHYS=0x18000300
-CONFIG_DEBUG_UART_VIRT=0xf1000300
-CONFIG_DEBUG_USER=y
-CONFIG_DMA_OPS=y
-CONFIG_DTC=y
-CONFIG_EARLY_PRINTK=y
-CONFIG_EDAC_ATOMIC_SCRUB=y
-CONFIG_EDAC_SUPPORT=y
-CONFIG_EXCLUSIVE_SYSTEM_RAM=y
-CONFIG_EXTCON=y
-CONFIG_FIXED_PHY=y
-CONFIG_FIX_EARLYCON_MEM=y
-CONFIG_FWNODE_MDIO=y
-CONFIG_FW_LOADER_PAGED_BUF=y
-CONFIG_FW_LOADER_SYSFS=y
-# CONFIG_FW_LOADER_USER_HELPER_FALLBACK is not set
-CONFIG_GCC11_NO_ARRAY_BOUNDS=y
-CONFIG_GCC_ASM_GOTO_OUTPUT_WORKAROUND=y
-CONFIG_GENERIC_ALLOCATOR=y
-CONFIG_GENERIC_ARCH_TOPOLOGY=y
-CONFIG_GENERIC_BUG=y
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
-CONFIG_GENERIC_CPU_AUTOPROBE=y
-CONFIG_GENERIC_CPU_VULNERABILITIES=y
-CONFIG_GENERIC_EARLY_IOREMAP=y
-CONFIG_GENERIC_GETTIMEOFDAY=y
-CONFIG_GENERIC_IDLE_POLL_SETUP=y
-CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
-CONFIG_GENERIC_IRQ_MULTI_HANDLER=y
-CONFIG_GENERIC_IRQ_SHOW=y
-CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
-CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y
-CONFIG_GENERIC_PCI_IOMAP=y
-CONFIG_GENERIC_PHY=y
-CONFIG_GENERIC_PINCONF=y
-CONFIG_GENERIC_PINCTRL_GROUPS=y
-CONFIG_GENERIC_PINMUX_FUNCTIONS=y
-CONFIG_GENERIC_SCHED_CLOCK=y
-CONFIG_GENERIC_SMP_IDLE_THREAD=y
-CONFIG_GENERIC_STRNCPY_FROM_USER=y
-CONFIG_GENERIC_STRNLEN_USER=y
-CONFIG_GENERIC_TIME_VSYSCALL=y
-CONFIG_GENERIC_VDSO_32=y
-CONFIG_GPIOLIB_IRQCHIP=y
-CONFIG_GPIO_74X164=y
-CONFIG_GPIO_BCM_XGS_IPROC=y
-CONFIG_GPIO_CDEV=y
-CONFIG_GPIO_GENERIC=y
-CONFIG_GRO_CELLS=y
-CONFIG_HARDEN_BRANCH_PREDICTOR=y
-CONFIG_HARDIRQS_SW_RESEND=y
-CONFIG_HAS_DMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT_MAP=y
-CONFIG_HAVE_SMP=y
-CONFIG_HIGHMEM=y
-CONFIG_HIGHPTE=y
-CONFIG_HW_RANDOM=y
-CONFIG_HW_RANDOM_BCM2835=y
-CONFIG_HZ_FIXED=0
-CONFIG_HZ_PERIODIC=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_IRQCHIP=y
-CONFIG_IRQSTACKS=y
-CONFIG_IRQ_DOMAIN=y
-CONFIG_IRQ_DOMAIN_HIERARCHY=y
-CONFIG_IRQ_FORCED_THREADING=y
-CONFIG_IRQ_WORK=y
-CONFIG_KMAP_LOCAL=y
-CONFIG_KMAP_LOCAL_NON_LINEAR_PTE_ARRAY=y
-# CONFIG_LEDS_BCM63138 is not set
-CONFIG_LIBFDT=y
-CONFIG_LOCK_DEBUGGING_SUPPORT=y
-CONFIG_LOCK_SPIN_ON_OWNER=y
-CONFIG_LZO_COMPRESS=y
-CONFIG_LZO_DECOMPRESS=y
-CONFIG_MDIO_BCM_IPROC=y
-CONFIG_MDIO_BUS=y
-CONFIG_MDIO_BUS_MUX=y
-# CONFIG_MDIO_BUS_MUX_BCM_IPROC is not set
-CONFIG_MDIO_BUS_MUX_MMIOREG=y
-CONFIG_MDIO_DEVICE=y
-CONFIG_MDIO_DEVRES=y
-CONFIG_MEMFD_CREATE=y
-CONFIG_MFD_SYSCON=y
-CONFIG_MIGHT_HAVE_CACHE_L2X0=y
-CONFIG_MIGRATION=y
-CONFIG_MODULES_USE_ELF_REL=y
-CONFIG_MTD_BCM47XXSFLASH=y
-CONFIG_MTD_BCM47XX_PARTS=y
-CONFIG_MTD_NAND_BRCMNAND=y
-CONFIG_MTD_NAND_BRCMNAND_IPROC=y
-CONFIG_MTD_NAND_CORE=y
-CONFIG_MTD_NAND_ECC=y
-CONFIG_MTD_NAND_ECC_SW_HAMMING=y
-CONFIG_MTD_OF_PARTS_LINKSYS_NS=y
-CONFIG_MTD_PARSER_TPLINK_SAFELOADER=y
-CONFIG_MTD_PARSER_TRX=y
-CONFIG_MTD_RAW_NAND=y
-CONFIG_MTD_SPI_NOR=y
-CONFIG_MTD_SPLIT_SEAMA_FW=y
-CONFIG_MTD_UBI=y
-CONFIG_MTD_UBI_BEB_LIMIT=20
-CONFIG_MTD_UBI_BLOCK=y
-CONFIG_MTD_UBI_WL_THRESHOLD=4096
-CONFIG_MUTEX_SPIN_ON_OWNER=y
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NET_DEVLINK=y
-CONFIG_NET_DSA=y
-CONFIG_NET_DSA_TAG_BRCM=y
-CONFIG_NET_DSA_TAG_BRCM_COMMON=y
-CONFIG_NET_DSA_TAG_BRCM_LEGACY=y
-CONFIG_NET_DSA_TAG_BRCM_PREPEND=y
-CONFIG_NET_FLOW_LIMIT=y
-CONFIG_NET_SELFTESTS=y
-CONFIG_NET_SWITCHDEV=y
-CONFIG_NR_CPUS=2
-CONFIG_NVMEM=y
-CONFIG_NVMEM_BRCM_NVRAM=y
-CONFIG_NVMEM_LAYOUTS=y
-CONFIG_NVMEM_SYSFS=y
-CONFIG_OF=y
-CONFIG_OF_ADDRESS=y
-CONFIG_OF_EARLY_FLATTREE=y
-CONFIG_OF_FLATTREE=y
-CONFIG_OF_GPIO=y
-CONFIG_OF_IRQ=y
-CONFIG_OF_KOBJ=y
-CONFIG_OF_MDIO=y
-CONFIG_OLD_SIGACTION=y
-CONFIG_OLD_SIGSUSPEND3=y
-CONFIG_OUTER_CACHE=y
-CONFIG_OUTER_CACHE_SYNC=y
-CONFIG_PADATA=y
-CONFIG_PAGE_OFFSET=0xC0000000
-CONFIG_PAGE_POOL=y
-CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
-CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
-CONFIG_PCI=y
-CONFIG_PCIE_IPROC=y
-CONFIG_PCIE_IPROC_BCMA=y
-# CONFIG_PCIE_IPROC_PLATFORM is not set
-CONFIG_PCI_DOMAINS=y
-CONFIG_PCI_DOMAINS_GENERIC=y
-CONFIG_PERF_USE_VMALLOC=y
-CONFIG_PGTABLE_LEVELS=2
-CONFIG_PHYLIB=y
-CONFIG_PHYLIB_LEDS=y
-CONFIG_PHYLINK=y
-# CONFIG_PHY_BCM_NS_USB2 is not set
-# CONFIG_PHY_BCM_NS_USB3 is not set
-# CONFIG_PHY_BCM_SR_PCIE is not set
-CONFIG_PHY_BCM_SR_USB=y
-# CONFIG_PHY_BRCM_SATA is not set
-# CONFIG_PHY_NS2_USB_DRD is not set
-CONFIG_PINCTRL=y
-# CONFIG_PINCTRL_IPROC_GPIO is not set
-CONFIG_PINCTRL_NS=y
-# CONFIG_PINCTRL_NS2_MUX is not set
-CONFIG_PREEMPT_NONE_BUILD=y
-CONFIG_PTP_1588_CLOCK_OPTIONAL=y
-CONFIG_PWM=y
-CONFIG_PWM_BCM_IPROC=y
-CONFIG_PWM_SYSFS=y
-CONFIG_RANDSTRUCT_NONE=y
-CONFIG_RATIONAL=y
-CONFIG_REGMAP=y
-CONFIG_REGMAP_MMIO=y
-CONFIG_RFS_ACCEL=y
-CONFIG_RPS=y
-CONFIG_RWSEM_SPIN_ON_OWNER=y
-CONFIG_SERIAL_8250_FSL=y
-CONFIG_SERIAL_MCTRL_GPIO=y
-CONFIG_SERIAL_OF_PLATFORM=y
-CONFIG_SGL_ALLOC=y
-CONFIG_SMP=y
-CONFIG_SMP_ON_UP=y
-CONFIG_SOCK_RX_QUEUE_MAPPING=y
-CONFIG_SOFTIRQ_ON_OWN_STACK=y
-CONFIG_SPARSE_IRQ=y
-CONFIG_SPI=y
-CONFIG_SPI_BCM_QSPI=y
-CONFIG_SPI_BITBANG=y
-CONFIG_SPI_GPIO=y
-CONFIG_SPI_MASTER=y
-CONFIG_SPI_MEM=y
-CONFIG_SRCU=y
-CONFIG_SWPHY=y
-CONFIG_SWP_EMULATE=y
-CONFIG_SYS_SUPPORTS_APM_EMULATION=y
-CONFIG_THERMAL=y
-CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
-CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
-CONFIG_THERMAL_GOV_STEP_WISE=y
-CONFIG_THERMAL_OF=y
-CONFIG_THREAD_INFO_IN_TASK=y
-CONFIG_TICK_CPU_ACCOUNTING=y
-CONFIG_TIMER_OF=y
-CONFIG_TIMER_PROBE=y
-CONFIG_TREE_RCU=y
-CONFIG_TREE_SRCU=y
-CONFIG_UBIFS_FS=y
-CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
-CONFIG_UNWINDER_ARM=y
-CONFIG_USB_SUPPORT=y
-CONFIG_USE_OF=y
-# CONFIG_VFP is not set
-CONFIG_WATCHDOG_CORE=y
-CONFIG_XPS=y
-CONFIG_XXHASH=y
-CONFIG_XZ_DEC_ARM=y
-CONFIG_XZ_DEC_BCJ=y
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZSTD_COMMON=y
-CONFIG_ZSTD_COMPRESS=y
-CONFIG_ZSTD_DECOMPRESS=y
diff --git a/target/linux/bcm53xx/image/Makefile b/target/linux/bcm53xx/image/Makefile
index 88590c3755..e02eba387c 100644
--- a/target/linux/bcm53xx/image/Makefile
+++ b/target/linux/bcm53xx/image/Makefile
@@ -127,11 +127,7 @@ define Build/dwl8610ap-image
mv $@.new $@
endef
-ifneq ($(KERNEL),5.15)
-ifneq ($(KERNEL),6.1)
DTS_DIR := $(DTS_DIR)/broadcom
-endif
-endif
DEVICE_VARS += ASUS_PRODUCTID
DEVICE_VARS += BUFFALO_TAG_PLATFORM BUFFALO_TAG_VERSION BUFFALO_TAG_MINOR
diff --git a/target/linux/bcm53xx/patches-5.15/030-v5.15-0001-ARM-dts-NSP-add-device-names-to-compatible.patch b/target/linux/bcm53xx/patches-5.15/030-v5.15-0001-ARM-dts-NSP-add-device-names-to-compatible.patch
deleted file mode 100644
index c994953d4d..0000000000
--- a/target/linux/bcm53xx/patches-5.15/030-v5.15-0001-ARM-dts-NSP-add-device-names-to-compatible.patch
+++ /dev/null
@@ -1,97 +0,0 @@
-From 465078bfdf5271601f098450ae2fc974865c59fd Mon Sep 17 00:00:00 2001
-From: Matthew Hagan <mnhagan88@gmail.com>
-Date: Thu, 10 Jun 2021 21:35:10 +0100
-Subject: [PATCH] ARM: dts: NSP: add device names to compatible
-
-Currently only the SoC type and platform are specified for all NSP
-devices. This patch adds the device names.
-
-Signed-off-by: Matthew Hagan <mnhagan88@gmail.com>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm958522er.dts | 2 +-
- arch/arm/boot/dts/bcm958525er.dts | 2 +-
- arch/arm/boot/dts/bcm958525xmc.dts | 2 +-
- arch/arm/boot/dts/bcm958622hr.dts | 2 +-
- arch/arm/boot/dts/bcm958625hr.dts | 2 +-
- arch/arm/boot/dts/bcm958625k.dts | 2 +-
- arch/arm/boot/dts/bcm988312hr.dts | 2 +-
- 7 files changed, 7 insertions(+), 7 deletions(-)
-
---- a/arch/arm/boot/dts/bcm958522er.dts
-+++ b/arch/arm/boot/dts/bcm958522er.dts
-@@ -37,7 +37,7 @@
-
- / {
- model = "NorthStar Plus SVK (BCM958522ER)";
-- compatible = "brcm,bcm58522", "brcm,nsp";
-+ compatible = "brcm,bcm958522er", "brcm,bcm58522", "brcm,nsp";
-
- chosen {
- stdout-path = "serial0:115200n8";
---- a/arch/arm/boot/dts/bcm958525er.dts
-+++ b/arch/arm/boot/dts/bcm958525er.dts
-@@ -37,7 +37,7 @@
-
- / {
- model = "NorthStar Plus SVK (BCM958525ER)";
-- compatible = "brcm,bcm58525", "brcm,nsp";
-+ compatible = "brcm,bcm958525er", "brcm,bcm58525", "brcm,nsp";
-
- chosen {
- stdout-path = "serial0:115200n8";
---- a/arch/arm/boot/dts/bcm958525xmc.dts
-+++ b/arch/arm/boot/dts/bcm958525xmc.dts
-@@ -37,7 +37,7 @@
-
- / {
- model = "NorthStar Plus XMC (BCM958525xmc)";
-- compatible = "brcm,bcm58525", "brcm,nsp";
-+ compatible = "brcm,bcm958525xmc", "brcm,bcm58525", "brcm,nsp";
-
- chosen {
- stdout-path = "serial0:115200n8";
---- a/arch/arm/boot/dts/bcm958622hr.dts
-+++ b/arch/arm/boot/dts/bcm958622hr.dts
-@@ -37,7 +37,7 @@
-
- / {
- model = "NorthStar Plus SVK (BCM958622HR)";
-- compatible = "brcm,bcm58622", "brcm,nsp";
-+ compatible = "brcm,bcm958622hr", "brcm,bcm58622", "brcm,nsp";
-
- chosen {
- stdout-path = "serial0:115200n8";
---- a/arch/arm/boot/dts/bcm958625hr.dts
-+++ b/arch/arm/boot/dts/bcm958625hr.dts
-@@ -37,7 +37,7 @@
-
- / {
- model = "NorthStar Plus SVK (BCM958625HR)";
-- compatible = "brcm,bcm58625", "brcm,nsp";
-+ compatible = "brcm,bcm958625hr", "brcm,bcm58625", "brcm,nsp";
-
- chosen {
- stdout-path = "serial0:115200n8";
---- a/arch/arm/boot/dts/bcm958625k.dts
-+++ b/arch/arm/boot/dts/bcm958625k.dts
-@@ -36,7 +36,7 @@
-
- / {
- model = "NorthStar Plus SVK (BCM958625K)";
-- compatible = "brcm,bcm58625", "brcm,nsp";
-+ compatible = "brcm,bcm958625k", "brcm,bcm58625", "brcm,nsp";
-
- chosen {
- stdout-path = "serial0:115200n8";
---- a/arch/arm/boot/dts/bcm988312hr.dts
-+++ b/arch/arm/boot/dts/bcm988312hr.dts
-@@ -37,7 +37,7 @@
-
- / {
- model = "NorthStar Plus SVK (BCM988312HR)";
-- compatible = "brcm,bcm88312", "brcm,nsp";
-+ compatible = "brcm,bcm988312hr", "brcm,bcm88312", "brcm,nsp";
-
- chosen {
- stdout-path = "serial0:115200n8";
diff --git a/target/linux/bcm53xx/patches-5.15/030-v5.15-0002-ARM-dts-NSP-enable-DMA-on-bcm988312hr.patch b/target/linux/bcm53xx/patches-5.15/030-v5.15-0002-ARM-dts-NSP-enable-DMA-on-bcm988312hr.patch
deleted file mode 100644
index d84124d2dd..0000000000
--- a/target/linux/bcm53xx/patches-5.15/030-v5.15-0002-ARM-dts-NSP-enable-DMA-on-bcm988312hr.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From 1b90dde4278a7b459979706b572785bc3a10bbb5 Mon Sep 17 00:00:00 2001
-From: Matthew Hagan <mnhagan88@gmail.com>
-Date: Thu, 10 Jun 2021 21:35:12 +0100
-Subject: [PATCH] ARM: dts: NSP: enable DMA on bcm988312hr
-
-The previous patch "ARM: dts: NSP: Disable PL330 by default, add
-dma-coherent property" set the DMAC to disabled by default, requiring it
-to be manually enabled on each device. The bcm988312hr was mistakenly
-omitted. This patch adds it back.
-
-Signed-off-by: Matthew Hagan <mnhagan88@gmail.com>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm988312hr.dts | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- a/arch/arm/boot/dts/bcm988312hr.dts
-+++ b/arch/arm/boot/dts/bcm988312hr.dts
-@@ -58,6 +58,10 @@
-
- /* USB 3 support needed to be complete */
-
-+&dma {
-+ status = "okay";
-+};
-+
- &amac0 {
- status = "okay";
- };
diff --git a/target/linux/bcm53xx/patches-5.15/030-v5.15-0003-ARM-dts-NSP-disable-qspi-node-by-default.patch b/target/linux/bcm53xx/patches-5.15/030-v5.15-0003-ARM-dts-NSP-disable-qspi-node-by-default.patch
deleted file mode 100644
index e540245b0f..0000000000
--- a/target/linux/bcm53xx/patches-5.15/030-v5.15-0003-ARM-dts-NSP-disable-qspi-node-by-default.patch
+++ /dev/null
@@ -1,113 +0,0 @@
-From 091a12b1814142eac16a115dab206f735b5476a9 Mon Sep 17 00:00:00 2001
-From: Matthew Hagan <mnhagan88@gmail.com>
-Date: Sun, 13 Jun 2021 10:46:34 +0100
-Subject: [PATCH] ARM: dts: NSP: disable qspi node by default
-
-The QSPI bus is enabled by default, however this may not used on all
-devices. This patch disables by default, requiring it to be explicitly
-enabled where required.
-
-Signed-off-by: Matthew Hagan <mnhagan88@gmail.com>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm-nsp.dtsi | 1 +
- arch/arm/boot/dts/bcm958522er.dts | 1 +
- arch/arm/boot/dts/bcm958525er.dts | 1 +
- arch/arm/boot/dts/bcm958525xmc.dts | 1 +
- arch/arm/boot/dts/bcm958622hr.dts | 1 +
- arch/arm/boot/dts/bcm958623hr.dts | 1 +
- arch/arm/boot/dts/bcm958625hr.dts | 1 +
- arch/arm/boot/dts/bcm958625k.dts | 1 +
- arch/arm/boot/dts/bcm988312hr.dts | 1 +
- 9 files changed, 9 insertions(+)
-
---- a/arch/arm/boot/dts/bcm-nsp.dtsi
-+++ b/arch/arm/boot/dts/bcm-nsp.dtsi
-@@ -310,6 +310,7 @@
- num-cs = <2>;
- #address-cells = <1>;
- #size-cells = <0>;
-+ status = "disabled";
- };
-
- xhci: usb@29000 {
---- a/arch/arm/boot/dts/bcm958522er.dts
-+++ b/arch/arm/boot/dts/bcm958522er.dts
-@@ -134,6 +134,7 @@
- };
-
- &qspi {
-+ status = "okay";
- bspi-sel = <0>;
- flash: m25p80@0 {
- #address-cells = <1>;
---- a/arch/arm/boot/dts/bcm958525er.dts
-+++ b/arch/arm/boot/dts/bcm958525er.dts
-@@ -134,6 +134,7 @@
- };
-
- &qspi {
-+ status = "okay";
- bspi-sel = <0>;
- flash: m25p80@0 {
- #address-cells = <1>;
---- a/arch/arm/boot/dts/bcm958525xmc.dts
-+++ b/arch/arm/boot/dts/bcm958525xmc.dts
-@@ -150,6 +150,7 @@
- };
-
- &qspi {
-+ status = "okay";
- bspi-sel = <0>;
- flash: m25p80@0 {
- #address-cells = <1>;
---- a/arch/arm/boot/dts/bcm958622hr.dts
-+++ b/arch/arm/boot/dts/bcm958622hr.dts
-@@ -138,6 +138,7 @@
- };
-
- &qspi {
-+ status = "okay";
- bspi-sel = <0>;
- flash: m25p80@0 {
- #address-cells = <1>;
---- a/arch/arm/boot/dts/bcm958623hr.dts
-+++ b/arch/arm/boot/dts/bcm958623hr.dts
-@@ -142,6 +142,7 @@
- };
-
- &qspi {
-+ status = "okay";
- bspi-sel = <0>;
- flash: m25p80@0 {
- #address-cells = <1>;
---- a/arch/arm/boot/dts/bcm958625hr.dts
-+++ b/arch/arm/boot/dts/bcm958625hr.dts
-@@ -149,6 +149,7 @@
- };
-
- &qspi {
-+ status = "okay";
- bspi-sel = <0>;
- flash: m25p80@0 {
- #address-cells = <1>;
---- a/arch/arm/boot/dts/bcm958625k.dts
-+++ b/arch/arm/boot/dts/bcm958625k.dts
-@@ -153,6 +153,7 @@
- };
-
- &qspi {
-+ status = "okay";
- bspi-sel = <0>;
- flash: m25p80@0 {
- #address-cells = <1>;
---- a/arch/arm/boot/dts/bcm988312hr.dts
-+++ b/arch/arm/boot/dts/bcm988312hr.dts
-@@ -138,6 +138,7 @@
- };
-
- &qspi {
-+ status = "okay";
- bspi-sel = <0>;
- flash: m25p80@0 {
- #address-cells = <1>;
diff --git a/target/linux/bcm53xx/patches-5.15/030-v5.15-0004-ARM-dts-NSP-add-MDIO-bus-controller-node.patch b/target/linux/bcm53xx/patches-5.15/030-v5.15-0004-ARM-dts-NSP-add-MDIO-bus-controller-node.patch
deleted file mode 100644
index 6164a22c76..0000000000
--- a/target/linux/bcm53xx/patches-5.15/030-v5.15-0004-ARM-dts-NSP-add-MDIO-bus-controller-node.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 236b31b1d84eb0e4f10c5f113a2675529456f919 Mon Sep 17 00:00:00 2001
-From: Matthew Hagan <mnhagan88@gmail.com>
-Date: Sun, 13 Jun 2021 10:46:36 +0100
-Subject: [PATCH] ARM: dts: NSP: add MDIO bus controller node
-
-This patch adds the node for the MDIO bus controller, present on the NSP
-SoC.
-
-Signed-off-by: Matthew Hagan <mnhagan88@gmail.com>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm-nsp.dtsi | 7 +++++++
- 1 file changed, 7 insertions(+)
-
---- a/arch/arm/boot/dts/bcm-nsp.dtsi
-+++ b/arch/arm/boot/dts/bcm-nsp.dtsi
-@@ -363,6 +363,13 @@
- status = "disabled";
- };
-
-+ mdio: mdio@32000 {
-+ compatible = "brcm,iproc-mdio";
-+ reg = <0x32000 0x8>;
-+ #size-cells = <0>;
-+ #address-cells = <1>;
-+ };
-+
- rng: rng@33000 {
- compatible = "brcm,bcm-nsp-rng";
- reg = <0x33000 0x14>;
diff --git a/target/linux/bcm53xx/patches-5.15/030-v5.15-0005-ARM-dts-NSP-Move-USB3-PHY-to-internal-MDIO-bus.patch b/target/linux/bcm53xx/patches-5.15/030-v5.15-0005-ARM-dts-NSP-Move-USB3-PHY-to-internal-MDIO-bus.patch
deleted file mode 100644
index b760e0fcf2..0000000000
--- a/target/linux/bcm53xx/patches-5.15/030-v5.15-0005-ARM-dts-NSP-Move-USB3-PHY-to-internal-MDIO-bus.patch
+++ /dev/null
@@ -1,85 +0,0 @@
-From 1c615401bddb1be21e1d375aaa071680f40f1ae2 Mon Sep 17 00:00:00 2001
-From: Matthew Hagan <mnhagan88@gmail.com>
-Date: Sun, 13 Jun 2021 10:46:37 +0100
-Subject: [PATCH] ARM: dts: NSP: Move USB3 PHY to internal MDIO bus
-
-This patch largely replicates Vivek Unune's patch "ARM: dts:
-BCM5301X:Make usb3 phy use mdio phy driver"[1] for the NSP platform,
-whereby we need to create an mdio-mux to facilitate switches
-configured via external MDIO, in this case on the Meraki MX65.
-
-However in doing so, we are creating an overlap with usb3_phy's
-ccb-mii range. To resolve this, usb3_phy should be moved to a child
-node of the internal MDIO bus. The result is heavily based upon Vivek's
-patch. This has also been cross-referenced with Yendapally Reddy's
-earlier work which utilised the subsequently dropped brcm,nsp-usb3-phy
-driver: "[PATCH v2 4/4] arm: dts: nsp: Add USB nodes to device tree"
-[2]. Finally, this change provides conformance to the bcm-ns-usb3-phy
-documentation, utilising the required usb3-dmp-syscon property. Note
-that support for the deprecated ccb-mii bindings has been dropped as of
-"phy: phy-bcm-ns-usb3: drop support for deprecated DT binding"[3].
-
-[1] https://lore.kernel.org/patchwork/patch/933971/
-[2] https://www.spinics.net/lists/arm-kernel/msg555132.html
-[3] https://lore.kernel.org/linux-devicetree/20201113113423.9466-1-zajec5@gmail.com/
-
-Signed-off-by: Matthew Hagan <mnhagan88@gmail.com>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm-nsp.dtsi | 38 +++++++++++++++++++++++++++-------
- 1 file changed, 31 insertions(+), 7 deletions(-)
-
---- a/arch/arm/boot/dts/bcm-nsp.dtsi
-+++ b/arch/arm/boot/dts/bcm-nsp.dtsi
-@@ -370,6 +370,35 @@
- #address-cells = <1>;
- };
-
-+ mdio-mux@32000 {
-+ compatible = "mdio-mux-mmioreg";
-+ reg = <0x32000 0x4>;
-+ mux-mask = <0x200>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ mdio-parent-bus = <&mdio>;
-+
-+ mdio_int: mdio@0 {
-+ reg = <0x0>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ usb3_phy: usb3-phy@10 {
-+ compatible = "brcm,ns-bx-usb3-phy";
-+ reg = <0x10>;
-+ usb3-dmp-syscon = <&usb3_dmp>;
-+ #phy-cells = <0>;
-+ status = "disabled";
-+ };
-+ };
-+
-+ mdio_ext: mdio@200 {
-+ reg = <0x200>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ };
-+ };
-+
- rng: rng@33000 {
- compatible = "brcm,bcm-nsp-rng";
- reg = <0x33000 0x14>;
-@@ -528,13 +557,8 @@
- };
- };
-
-- usb3_phy: usb3-phy@104000 {
-- compatible = "brcm,ns-bx-usb3-phy";
-- reg = <0x104000 0x1000>,
-- <0x032000 0x1000>;
-- reg-names = "dmp", "ccb-mii";
-- #phy-cells = <0>;
-- status = "disabled";
-+ usb3_dmp: syscon@104000 {
-+ reg = <0x104000 0x1000>;
- };
- };
-
diff --git a/target/linux/bcm53xx/patches-5.15/030-v5.15-0006-ARM-dts-NSP-Add-common-bindings-for-MX64-MX65.patch b/target/linux/bcm53xx/patches-5.15/030-v5.15-0006-ARM-dts-NSP-Add-common-bindings-for-MX64-MX65.patch
deleted file mode 100644
index aebf62af9b..0000000000
--- a/target/linux/bcm53xx/patches-5.15/030-v5.15-0006-ARM-dts-NSP-Add-common-bindings-for-MX64-MX65.patch
+++ /dev/null
@@ -1,148 +0,0 @@
-From f111016a8293b968f05450fec83020c94d0f88c2 Mon Sep 17 00:00:00 2001
-From: Matthew Hagan <mnhagan88@gmail.com>
-Date: Fri, 6 Aug 2021 21:44:32 +0100
-Subject: [PATCH] ARM: dts: NSP: Add common bindings for MX64/MX65
-
-These bindings are required for all Meraki MX64/MX65 devices. These
-common bindings include memory (2GB), PWM LEDs, AMAC, I2C (AT24), NAND
-partitions, EHCI, OHCI and pinctrl.
-
-Signed-off-by: Matthew Hagan <mnhagan88@gmail.com>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- .../dts/bcm958625-meraki-mx6x-common.dtsi | 129 ++++++++++++++++++
- 1 file changed, 129 insertions(+)
- create mode 100644 arch/arm/boot/dts/bcm958625-meraki-mx6x-common.dtsi
-
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm958625-meraki-mx6x-common.dtsi
-@@ -0,0 +1,129 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-+/*
-+ * Common Bindings for Cisco Meraki MX64 (Kingpin) and MX65 (Alamo) devices.
-+ *
-+ * Copyright (C) 2020-2021 Matthew Hagan <mnhagan88@gmail.com>
-+ */
-+
-+#include "bcm-nsp.dtsi"
-+#include <dt-bindings/gpio/gpio.h>
-+#include <dt-bindings/input/input.h>
-+#include <dt-bindings/leds/common.h>
-+
-+/ {
-+ pwm-leds {
-+ compatible = "pwm-leds";
-+
-+ led-1 {
-+ function = LED_FUNCTION_INDICATOR;
-+ color = <LED_COLOR_ID_RED>;
-+ pwms = <&pwm 1 50000>;
-+ max-brightness = <255>;
-+ };
-+
-+ led-2 {
-+ function = LED_FUNCTION_INDICATOR;
-+ color = <LED_COLOR_ID_GREEN>;
-+ pwms = <&pwm 2 50000>;
-+ max-brightness = <255>;
-+ };
-+
-+ led-3 {
-+ function = LED_FUNCTION_INDICATOR;
-+ color = <LED_COLOR_ID_BLUE>;
-+ pwms = <&pwm 3 50000>;
-+ max-brightness = <255>;
-+ };
-+ };
-+};
-+
-+&amac2 {
-+ status = "okay";
-+};
-+
-+&ehci0 {
-+ status = "okay";
-+};
-+
-+&i2c0 {
-+ status = "okay";
-+
-+ at24@50 {
-+ compatible = "atmel,24c64";
-+ reg = <0x50>;
-+ pagesize = <32>;
-+ read-only;
-+ };
-+};
-+
-+&nand_controller {
-+ nand@0 {
-+ compatible = "brcm,nandcs";
-+ reg = <0>;
-+ nand-on-flash-bbt;
-+
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ nand-ecc-strength = <24>;
-+ nand-ecc-step-size = <1024>;
-+
-+ brcm,nand-oob-sector-size = <27>;
-+
-+ partition@0 {
-+ label = "u-boot";
-+ reg = <0x0 0x80000>;
-+ read-only;
-+ };
-+
-+ partition@80000 {
-+ label = "shmoo";
-+ reg = <0x80000 0x80000>;
-+ read-only;
-+ };
-+
-+ partition@100000 {
-+ label = "bootkernel1";
-+ reg = <0x100000 0x300000>;
-+ };
-+
-+ partition@400000 {
-+ label = "nvram";
-+ reg = <0x400000 0x100000>;
-+ };
-+
-+ partition@500000 {
-+ label = "bootkernel2";
-+ reg = <0x500000 0x300000>;
-+ };
-+
-+ partition@800000 {
-+ label = "ubi";
-+ reg = <0x800000 0x3f700000>;
-+ };
-+ };
-+};
-+
-+&ohci0 {
-+ status = "okay";
-+};
-+
-+&pinctrl {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&pwm_leds>;
-+
-+ pwm_leds: pwm_leds {
-+ function = "pwm";
-+ groups = "pwm1_grp", "pwm2_grp", "pwm3_grp";
-+ };
-+};
-+
-+&pwm {
-+ status = "okay";
-+ #pwm-cells = <2>;
-+};
-+
-+&uart0 {
-+ clock-frequency = <62500000>;
-+ status = "okay";
-+};
diff --git a/target/linux/bcm53xx/patches-5.15/030-v5.15-0007-ARM-dts-NSP-Add-Ax-stepping-modifications.patch b/target/linux/bcm53xx/patches-5.15/030-v5.15-0007-ARM-dts-NSP-Add-Ax-stepping-modifications.patch
deleted file mode 100644
index 39a69bd9a8..0000000000
--- a/target/linux/bcm53xx/patches-5.15/030-v5.15-0007-ARM-dts-NSP-Add-Ax-stepping-modifications.patch
+++ /dev/null
@@ -1,90 +0,0 @@
-From 2addf9266a1d0f4ba59c9868b3effcd50de441a4 Mon Sep 17 00:00:00 2001
-From: Matthew Hagan <mnhagan88@gmail.com>
-Date: Fri, 6 Aug 2021 21:44:33 +0100
-Subject: [PATCH] ARM: dts: NSP: Add Ax stepping modifications
-
-While uncommon, some Ax NSP SoCs exist in the wild. This stepping
-requires a modified secondary CPU boot-reg and removal of DMA coherency
-properties. Without these modifications, the secondary CPU will be
-inactive and many peripherals will exhibit undefined behaviour.
-
-Signed-off-by: Matthew Hagan <mnhagan88@gmail.com>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm-nsp-ax.dtsi | 70 +++++++++++++++++++++++++++++++
- 1 file changed, 70 insertions(+)
- create mode 100644 arch/arm/boot/dts/bcm-nsp-ax.dtsi
-
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm-nsp-ax.dtsi
-@@ -0,0 +1,70 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-+/*
-+ * Broadcom Northstar Plus Ax stepping-specific bindings.
-+ * Notable differences from B0+ are the secondary-boot-reg and
-+ * lack of DMA coherency.
-+ */
-+
-+&cpu1 {
-+ secondary-boot-reg = <0xffff042c>;
-+};
-+
-+&dma {
-+ /delete-property/ dma-coherent;
-+};
-+
-+&sdio {
-+ /delete-property/ dma-coherent;
-+};
-+
-+&amac0 {
-+ /delete-property/ dma-coherent;
-+};
-+
-+&amac1 {
-+ /delete-property/ dma-coherent;
-+};
-+
-+&amac2 {
-+ /delete-property/ dma-coherent;
-+};
-+
-+&ehci0 {
-+ /delete-property/ dma-coherent;
-+};
-+
-+&mailbox {
-+ /delete-property/ dma-coherent;
-+};
-+
-+&xhci {
-+ /delete-property/ dma-coherent;
-+};
-+
-+&ehci0 {
-+ /delete-property/ dma-coherent;
-+};
-+
-+&ohci0 {
-+ /delete-property/ dma-coherent;
-+};
-+
-+&i2c0 {
-+ /delete-property/ dma-coherent;
-+};
-+
-+&sata {
-+ /delete-property/ dma-coherent;
-+};
-+
-+&pcie0 {
-+ /delete-property/ dma-coherent;
-+};
-+
-+&pcie1 {
-+ /delete-property/ dma-coherent;
-+};
-+
-+&pcie2 {
-+ /delete-property/ dma-coherent;
-+};
diff --git a/target/linux/bcm53xx/patches-5.15/030-v5.15-0008-ARM-dts-NSP-Add-DT-files-for-Meraki-MX64-series.patch b/target/linux/bcm53xx/patches-5.15/030-v5.15-0008-ARM-dts-NSP-Add-DT-files-for-Meraki-MX64-series.patch
deleted file mode 100644
index ffdd64fb59..0000000000
--- a/target/linux/bcm53xx/patches-5.15/030-v5.15-0008-ARM-dts-NSP-Add-DT-files-for-Meraki-MX64-series.patch
+++ /dev/null
@@ -1,340 +0,0 @@
-From 3f902645280baf0d7dab57c227cc14f43edb45ef Mon Sep 17 00:00:00 2001
-From: Matthew Hagan <mnhagan88@gmail.com>
-Date: Fri, 6 Aug 2021 21:44:34 +0100
-Subject: [PATCH] ARM: dts: NSP: Add DT files for Meraki MX64 series
-
-MX64 & MX64W Hardware info:
- - CPU: Broadcom BCM58625 Cortex A9 @ 1200Mhz
- - RAM: 2 GB (4 x 4Gb SK Hynix H5TC4G83CFR)
- - Storage: 1 GB (Micron MT29F8G08ABACA)
- - Networking: BCM58625 internal switch (5x 1GbE ports)
- - USB: 1x USB2.0
- - Serial: Internal header
- - WLAN(MX64W only): 2x Broadcom BCM43520KMLG on the PCI bus
-
-This patch adds the Meraki MX64 series-specific bindings. Since some
-devices make use of the older A0 SoC, changes need to be made to
-accommodate this case, including removal of coherency options and
-modification to the secondary-boot-reg.
-
-Signed-off-by: Matthew Hagan <mnhagan88@gmail.com>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/Makefile | 4 +
- .../boot/dts/bcm958625-meraki-kingpin.dtsi | 163 ++++++++++++++++++
- .../arm/boot/dts/bcm958625-meraki-mx64-a0.dts | 25 +++
- arch/arm/boot/dts/bcm958625-meraki-mx64.dts | 24 +++
- .../boot/dts/bcm958625-meraki-mx64w-a0.dts | 33 ++++
- arch/arm/boot/dts/bcm958625-meraki-mx64w.dts | 32 ++++
- 6 files changed, 281 insertions(+)
- create mode 100644 arch/arm/boot/dts/bcm958625-meraki-kingpin.dtsi
- create mode 100644 arch/arm/boot/dts/bcm958625-meraki-mx64-a0.dts
- create mode 100644 arch/arm/boot/dts/bcm958625-meraki-mx64.dts
- create mode 100644 arch/arm/boot/dts/bcm958625-meraki-mx64w-a0.dts
- create mode 100644 arch/arm/boot/dts/bcm958625-meraki-mx64w.dts
-
---- a/arch/arm/boot/dts/Makefile
-+++ b/arch/arm/boot/dts/Makefile
-@@ -158,6 +158,10 @@ dtb-$(CONFIG_ARCH_BCM_NSP) += \
- bcm958525xmc.dtb \
- bcm958622hr.dtb \
- bcm958623hr.dtb \
-+ bcm958625-meraki-mx64.dtb \
-+ bcm958625-meraki-mx64-a0.dtb \
-+ bcm958625-meraki-mx64w.dtb \
-+ bcm958625-meraki-mx64w-a0.dtb \
- bcm958625hr.dtb \
- bcm988312hr.dtb \
- bcm958625k.dtb
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm958625-meraki-kingpin.dtsi
-@@ -0,0 +1,163 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-+/*
-+ * Device Tree Bindings for Cisco Meraki MX64 series (Kingpin).
-+ *
-+ * Copyright (C) 2020-2021 Matthew Hagan <mnhagan88@gmail.com>
-+ */
-+
-+#include "bcm958625-meraki-mx6x-common.dtsi"
-+
-+/ {
-+
-+ keys {
-+ compatible = "gpio-keys-polled";
-+ autorepeat;
-+ poll-interval = <20>;
-+
-+ reset {
-+ label = "reset";
-+ linux,code = <KEY_RESTART>;
-+ gpios = <&gpioa 6 GPIO_ACTIVE_LOW>;
-+ };
-+ };
-+
-+ leds {
-+ compatible = "gpio-leds";
-+
-+ led-0 {
-+ /* green:lan1-left */
-+ function = LED_FUNCTION_ACTIVITY;
-+ function-enumerator = <0>;
-+ color = <LED_COLOR_ID_GREEN>;
-+ gpios = <&gpioa 19 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ led-1 {
-+ /* green:lan1-right */
-+ function = LED_FUNCTION_ACTIVITY;
-+ function-enumerator = <1>;
-+ color = <LED_COLOR_ID_GREEN>;
-+ gpios = <&gpioa 18 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ led-2 {
-+ /* green:lan2-left */
-+ function = LED_FUNCTION_ACTIVITY;
-+ function-enumerator = <2>;
-+ color = <LED_COLOR_ID_GREEN>;
-+ gpios = <&gpioa 24 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ led-3 {
-+ /* green:lan2-right */
-+ function = LED_FUNCTION_ACTIVITY;
-+ function-enumerator = <3>;
-+ color = <LED_COLOR_ID_GREEN>;
-+ gpios = <&gpioa 20 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ led-4 {
-+ /* green:lan3-left */
-+ function = LED_FUNCTION_ACTIVITY;
-+ function-enumerator = <4>;
-+ color = <LED_COLOR_ID_GREEN>;
-+ gpios = <&gpioa 26 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ led-5 {
-+ /* green:lan3-right */
-+ function = LED_FUNCTION_ACTIVITY;
-+ function-enumerator = <5>;
-+ color = <LED_COLOR_ID_GREEN>;
-+ gpios = <&gpioa 25 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ led-6 {
-+ /* green:lan4-left */
-+ function = LED_FUNCTION_ACTIVITY;
-+ function-enumerator = <6>;
-+ color = <LED_COLOR_ID_GREEN>;
-+ gpios = <&gpioa 28 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ led-7 {
-+ /* green:lan4-right */
-+ function = LED_FUNCTION_ACTIVITY;
-+ function-enumerator = <7>;
-+ color = <LED_COLOR_ID_GREEN>;
-+ gpios = <&gpioa 27 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ led-8 {
-+ /* green:wan-left */
-+ function = LED_FUNCTION_ACTIVITY;
-+ function-enumerator = <8>;
-+ color = <LED_COLOR_ID_GREEN>;
-+ gpios = <&gpioa 30 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ led-9 {
-+ /* green:wan-right */
-+ function = LED_FUNCTION_ACTIVITY;
-+ function-enumerator = <9>;
-+ color = <LED_COLOR_ID_GREEN>;
-+ gpios = <&gpioa 29 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ led-a {
-+ /* amber:power */
-+ function = LED_FUNCTION_POWER;
-+ color = <LED_COLOR_ID_AMBER>;
-+ gpios = <&gpioa 0 GPIO_ACTIVE_LOW>;
-+ default-state = "on";
-+ };
-+
-+ led-b {
-+ /* white:status */
-+ function = LED_FUNCTION_STATUS;
-+ color = <LED_COLOR_ID_WHITE>;
-+ gpios = <&gpioa 31 GPIO_ACTIVE_HIGH>;
-+ };
-+ };
-+};
-+
-+&srab {
-+ compatible = "brcm,bcm58625-srab", "brcm,nsp-srab";
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "lan1";
-+ reg = <0>;
-+ };
-+
-+ port@1 {
-+ label = "lan2";
-+ reg = <1>;
-+ };
-+
-+ port@2 {
-+ label = "lan3";
-+ reg = <2>;
-+ };
-+
-+ port@3 {
-+ label = "lan4";
-+ reg = <3>;
-+ };
-+
-+ port@4 {
-+ label = "wan";
-+ reg = <4>;
-+ };
-+
-+ port@8 {
-+ ethernet = <&amac2>;
-+ reg = <8>;
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
-+ };
-+ };
-+};
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm958625-meraki-mx64-a0.dts
-@@ -0,0 +1,25 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-+/*
-+ * Device Tree Bindings for Cisco Meraki MX64 with A0 SoC.
-+ *
-+ * Copyright (C) 2020-2021 Matthew Hagan <mnhagan88@gmail.com>
-+ */
-+
-+/dts-v1/;
-+
-+#include "bcm958625-meraki-kingpin.dtsi"
-+#include "bcm-nsp-ax.dtsi"
-+
-+/ {
-+ model = "Cisco Meraki MX64(A0)";
-+ compatible = "meraki,mx64-a0", "brcm,bcm58625", "brcm,nsp";
-+
-+ chosen {
-+ stdout-path = "serial0:115200n8";
-+ };
-+
-+ memory@60000000 {
-+ device_type = "memory";
-+ reg = <0x60000000 0x80000000>;
-+ };
-+};
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm958625-meraki-mx64.dts
-@@ -0,0 +1,24 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-+/*
-+ * Device Tree Bindings for Cisco Meraki MX64 with B0+ SoC.
-+ *
-+ * Copyright (C) 2020-2021 Matthew Hagan <mnhagan88@gmail.com>
-+ */
-+
-+/dts-v1/;
-+
-+#include "bcm958625-meraki-kingpin.dtsi"
-+
-+/ {
-+ model = "Cisco Meraki MX64";
-+ compatible = "meraki,mx64", "brcm,bcm58625", "brcm,nsp";
-+
-+ chosen {
-+ stdout-path = "serial0:115200n8";
-+ };
-+
-+ memory@60000000 {
-+ device_type = "memory";
-+ reg = <0x60000000 0x80000000>;
-+ };
-+};
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm958625-meraki-mx64w-a0.dts
-@@ -0,0 +1,33 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-+/*
-+ * Device Tree Bindings for Cisco Meraki MX64W with A0 SoC.
-+ *
-+ * Copyright (C) 2020-2021 Matthew Hagan <mnhagan88@gmail.com>
-+ */
-+
-+/dts-v1/;
-+
-+#include "bcm958625-meraki-kingpin.dtsi"
-+#include "bcm-nsp-ax.dtsi"
-+
-+/ {
-+ model = "Cisco Meraki MX64W(A0)";
-+ compatible = "meraki,mx64w-a0", "brcm,bcm58625", "brcm,nsp";
-+
-+ chosen {
-+ stdout-path = "serial0:115200n8";
-+ };
-+
-+ memory@60000000 {
-+ device_type = "memory";
-+ reg = <0x60000000 0x80000000>;
-+ };
-+};
-+
-+&pcie0 {
-+ status = "okay";
-+};
-+
-+&pcie1 {
-+ status = "okay";
-+};
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm958625-meraki-mx64w.dts
-@@ -0,0 +1,32 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-+/*
-+ * Device Tree Bindings for Cisco Meraki MX64W with B0+ SoC.
-+ *
-+ * Copyright (C) 2020-2021 Matthew Hagan <mnhagan88@gmail.com>
-+ */
-+
-+/dts-v1/;
-+
-+#include "bcm958625-meraki-kingpin.dtsi"
-+
-+/ {
-+ model = "Cisco Meraki MX64W";
-+ compatible = "meraki,mx64w", "brcm,bcm58625", "brcm,nsp";
-+
-+ chosen {
-+ stdout-path = "serial0:115200n8";
-+ };
-+
-+ memory@60000000 {
-+ device_type = "memory";
-+ reg = <0x60000000 0x80000000>;
-+ };
-+};
-+
-+&pcie0 {
-+ status = "okay";
-+};
-+
-+&pcie1 {
-+ status = "okay";
-+};
diff --git a/target/linux/bcm53xx/patches-5.15/030-v5.15-0009-ARM-dts-NSP-Add-DT-files-for-Meraki-MX65-series.patch b/target/linux/bcm53xx/patches-5.15/030-v5.15-0009-ARM-dts-NSP-Add-DT-files-for-Meraki-MX65-series.patch
deleted file mode 100644
index 29f8b5d0fe..0000000000
--- a/target/linux/bcm53xx/patches-5.15/030-v5.15-0009-ARM-dts-NSP-Add-DT-files-for-Meraki-MX65-series.patch
+++ /dev/null
@@ -1,386 +0,0 @@
-From 702a8f4744ed5b480f2b2411858184afdb10f9fd Mon Sep 17 00:00:00 2001
-From: Matthew Hagan <mnhagan88@gmail.com>
-Date: Fri, 6 Aug 2021 21:44:35 +0100
-Subject: [PATCH] ARM: dts: NSP: Add DT files for Meraki MX65 series
-
-MX65 & MX65W Hardware info:
- - CPU: Broadcom BCM58625 Cortex A9 @ 1200Mhz
- - RAM: 2 GB (4 x 4Gb SK Hynix H5TC4G83CFR)
- - Storage: 1 GB (Micron MT29F8G08ABACA)
- - Networking: BCM58625 switch (2x 1GbE ports)
- 2x Qualcomm QCA8337 switches (10x 1GbE ports total)
- - PSE: Broadcom BCM59111KMLG connected to LAN ports 11 & 12
- - USB: 1x USB2.0
- - Serial: Internal header
- - WLAN(MX65W Only): 2x Broadcom BCM43520KMLG on the PCI bus.
-
-Note that a driver and firmware image for the BCM59111 PSE has been
-released under GPL, but this is not present in the kernel.
-
-Signed-off-by: Matthew Hagan <mnhagan88@gmail.com>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/Makefile | 2 +
- arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi | 279 ++++++++++++++++++
- arch/arm/boot/dts/bcm958625-meraki-mx65.dts | 24 ++
- arch/arm/boot/dts/bcm958625-meraki-mx65w.dts | 32 ++
- 4 files changed, 337 insertions(+)
- create mode 100644 arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi
- create mode 100644 arch/arm/boot/dts/bcm958625-meraki-mx65.dts
- create mode 100644 arch/arm/boot/dts/bcm958625-meraki-mx65w.dts
-
---- a/arch/arm/boot/dts/Makefile
-+++ b/arch/arm/boot/dts/Makefile
-@@ -162,6 +162,8 @@ dtb-$(CONFIG_ARCH_BCM_NSP) += \
- bcm958625-meraki-mx64-a0.dtb \
- bcm958625-meraki-mx64w.dtb \
- bcm958625-meraki-mx64w-a0.dtb \
-+ bcm958625-meraki-mx65.dtb \
-+ bcm958625-meraki-mx65w.dtb \
- bcm958625hr.dtb \
- bcm988312hr.dtb \
- bcm958625k.dtb
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi
-@@ -0,0 +1,279 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-+/*
-+ * Device Tree Bindings for Cisco Meraki MX65 series (Alamo).
-+ *
-+ * Copyright (C) 2020-2021 Matthew Hagan <mnhagan88@gmail.com>
-+ */
-+
-+#include "bcm958625-meraki-mx6x-common.dtsi"
-+
-+/ {
-+ keys {
-+ compatible = "gpio-keys-polled";
-+ autorepeat;
-+ poll-interval = <20>;
-+
-+ reset {
-+ label = "reset";
-+ linux,code = <KEY_RESTART>;
-+ gpios = <&gpioa 8 GPIO_ACTIVE_LOW>;
-+ };
-+ };
-+
-+ leds {
-+ compatible = "gpio-leds";
-+
-+ led-0 {
-+ /* green:wan1-left */
-+ function = LED_FUNCTION_ACTIVITY;
-+ function-enumerator = <0>;
-+ color = <LED_COLOR_ID_GREEN>;
-+ gpios = <&gpioa 25 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ led-1 {
-+ /* green:wan1-right */
-+ function = LED_FUNCTION_ACTIVITY;
-+ function-enumerator = <1>;
-+ color = <LED_COLOR_ID_GREEN>;
-+ gpios = <&gpioa 24 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ led-2 {
-+ /* green:wan2-left */
-+ function = LED_FUNCTION_ACTIVITY;
-+ function-enumerator = <2>;
-+ color = <LED_COLOR_ID_GREEN>;
-+ gpios = <&gpioa 27 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ led-3 {
-+ /* green:wan2-right */
-+ function = LED_FUNCTION_ACTIVITY;
-+ function-enumerator = <3>;
-+ color = <LED_COLOR_ID_GREEN>;
-+ gpios = <&gpioa 26 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ led-4 {
-+ /* amber:power */
-+ function = LED_FUNCTION_POWER;
-+ color = <LED_COLOR_ID_AMBER>;
-+ gpios = <&gpioa 3 GPIO_ACTIVE_HIGH>;
-+ default-state = "on";
-+ };
-+
-+ led-5 {
-+ /* white:status */
-+ function = LED_FUNCTION_STATUS;
-+ color = <LED_COLOR_ID_WHITE>;
-+ gpios = <&gpioa 31 GPIO_ACTIVE_HIGH>;
-+ };
-+ };
-+
-+ mdio-mii-mux {
-+ compatible = "mdio-mux-mmioreg";
-+ reg = <0x1803f1c0 0x4>;
-+ mux-mask = <0x2000>;
-+ mdio-parent-bus = <&mdio_ext>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ mdio@0 {
-+ reg = <0x0>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ phy_port6: phy@0 {
-+ reg = <0>;
-+ };
-+
-+ phy_port7: phy@1 {
-+ reg = <1>;
-+ };
-+
-+ phy_port8: phy@2 {
-+ reg = <2>;
-+ };
-+
-+ phy_port9: phy@3 {
-+ reg = <3>;
-+ };
-+
-+ phy_port10: phy@4 {
-+ reg = <4>;
-+ };
-+
-+ switch@10 {
-+ compatible = "qca,qca8337";
-+ reg = <0x10>;
-+ dsa,member = <1 0>;
-+
-+ ports {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ port@0 {
-+ reg = <0>;
-+ ethernet = <&sgmii1>;
-+ phy-mode = "sgmii";
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
-+ };
-+
-+ port@1 {
-+ reg = <1>;
-+ label = "lan8";
-+ phy-handle = <&phy_port6>;
-+ };
-+
-+ port@2 {
-+ reg = <2>;
-+ label = "lan9";
-+ phy-handle = <&phy_port7>;
-+ };
-+
-+ port@3 {
-+ reg = <3>;
-+ label = "lan10";
-+ phy-handle = <&phy_port8>;
-+ };
-+
-+ port@4 {
-+ reg = <4>;
-+ label = "lan11";
-+ phy-handle = <&phy_port9>;
-+ };
-+
-+ port@5 {
-+ reg = <5>;
-+ label = "lan12";
-+ phy-handle = <&phy_port10>;
-+ };
-+ };
-+ };
-+ };
-+
-+ mdio-mii@2000 {
-+ reg = <0x2000>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ phy_port1: phy@0 {
-+ reg = <0>;
-+ };
-+
-+ phy_port2: phy@1 {
-+ reg = <1>;
-+ };
-+
-+ phy_port3: phy@2 {
-+ reg = <2>;
-+ };
-+
-+ phy_port4: phy@3 {
-+ reg = <3>;
-+ };
-+
-+ phy_port5: phy@4 {
-+ reg = <4>;
-+ };
-+
-+ switch@10 {
-+ compatible = "qca,qca8337";
-+ reg = <0x10>;
-+ dsa,member = <2 0>;
-+
-+ ports {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ port@0 {
-+ reg = <0>;
-+ ethernet = <&sgmii0>;
-+ phy-mode = "sgmii";
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
-+ };
-+
-+ port@1 {
-+ reg = <1>;
-+ label = "lan3";
-+ phy-handle = <&phy_port1>;
-+ };
-+
-+ port@2 {
-+ reg = <2>;
-+ label = "lan4";
-+ phy-handle = <&phy_port2>;
-+ };
-+
-+ port@3 {
-+ reg = <3>;
-+ label = "lan5";
-+ phy-handle = <&phy_port3>;
-+ };
-+
-+ port@4 {
-+ reg = <4>;
-+ label = "lan6";
-+ phy-handle = <&phy_port4>;
-+ };
-+
-+ port@5 {
-+ reg = <5>;
-+ label = "lan7";
-+ phy-handle = <&phy_port5>;
-+ };
-+ };
-+ };
-+ };
-+ };
-+};
-+
-+&srab {
-+ compatible = "brcm,bcm58625-srab", "brcm,nsp-srab";
-+ status = "okay";
-+ dsa,member = <0 0>;
-+
-+ ports {
-+ port@0 {
-+ label = "wan1";
-+ reg = <0>;
-+ };
-+
-+ port@1 {
-+ label = "wan2";
-+ reg = <1>;
-+ };
-+
-+ sgmii0: port@4 {
-+ label = "sw0";
-+ reg = <4>;
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
-+ };
-+
-+ sgmii1: port@5 {
-+ label = "sw1";
-+ reg = <5>;
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
-+ };
-+
-+ port@8 {
-+ ethernet = <&amac2>;
-+ reg = <8>;
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
-+ };
-+ };
-+};
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm958625-meraki-mx65.dts
-@@ -0,0 +1,24 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-+/*
-+ * Device Tree Bindings for Cisco Meraki MX65.
-+ *
-+ * Copyright (C) 2020-2021 Matthew Hagan <mnhagan88@gmail.com>
-+ */
-+
-+/dts-v1/;
-+
-+#include "bcm958625-meraki-alamo.dtsi"
-+
-+/ {
-+ model = "Cisco Meraki MX65";
-+ compatible = "meraki,mx65", "brcm,bcm58625", "brcm,nsp";
-+
-+ chosen {
-+ stdout-path = "serial0:115200n8";
-+ };
-+
-+ memory@60000000 {
-+ device_type = "memory";
-+ reg = <0x60000000 0x80000000>;
-+ };
-+};
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm958625-meraki-mx65w.dts
-@@ -0,0 +1,32 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-+/*
-+ * Device Tree Bindings for Cisco Meraki MX65W.
-+ *
-+ * Copyright (C) 2020-2021 Matthew Hagan <mnhagan88@gmail.com>
-+ */
-+
-+/dts-v1/;
-+
-+#include "bcm958625-meraki-alamo.dtsi"
-+
-+/ {
-+ model = "Cisco Meraki MX65W";
-+ compatible = "meraki,mx65w", "brcm,bcm58625", "brcm,nsp";
-+
-+ chosen {
-+ stdout-path = "serial0:115200n8";
-+ };
-+
-+ memory@60000000 {
-+ device_type = "memory";
-+ reg = <0x60000000 0x80000000>;
-+ };
-+};
-+
-+&pcie0 {
-+ status = "okay";
-+};
-+
-+&pcie1 {
-+ status = "okay";
-+};
diff --git a/target/linux/bcm53xx/patches-5.15/030-v5.16-0013-ARM-dts-NSP-Add-bcm958623hr-board-name-to-dts.patch b/target/linux/bcm53xx/patches-5.15/030-v5.16-0013-ARM-dts-NSP-Add-bcm958623hr-board-name-to-dts.patch
deleted file mode 100644
index c5f28474e3..0000000000
--- a/target/linux/bcm53xx/patches-5.15/030-v5.16-0013-ARM-dts-NSP-Add-bcm958623hr-board-name-to-dts.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From 695717eb4c61173d05a277e37132b5e2c6531bf1 Mon Sep 17 00:00:00 2001
-From: Matthew Hagan <mnhagan88@gmail.com>
-Date: Sun, 29 Aug 2021 22:37:47 +0000
-Subject: [PATCH] ARM: dts: NSP: Add bcm958623hr board name to dts
-
-This board was previously added to
-Documentation/devicetree/bindings/arm/bcm/brcm,nsp.yaml
-however the dts file was not updated to reflect this change. This patch
-corrects bcm958623hr.dts by adding the board name to the compatible.
-
-Signed-off-by: Matthew Hagan <mnhagan88@gmail.com>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm958623hr.dts | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/arch/arm/boot/dts/bcm958623hr.dts
-+++ b/arch/arm/boot/dts/bcm958623hr.dts
-@@ -37,7 +37,7 @@
-
- / {
- model = "NorthStar Plus SVK (BCM958623HR)";
-- compatible = "brcm,bcm58623", "brcm,nsp";
-+ compatible = "brcm,bcm958623hr", "brcm,bcm58623", "brcm,nsp";
-
- chosen {
- stdout-path = "serial0:115200n8";
diff --git a/target/linux/bcm53xx/patches-5.15/030-v5.16-0015-ARM-dts-NSP-Fix-MDIO-mux-node-names.patch b/target/linux/bcm53xx/patches-5.15/030-v5.16-0015-ARM-dts-NSP-Fix-MDIO-mux-node-names.patch
deleted file mode 100644
index a7c0f16719..0000000000
--- a/target/linux/bcm53xx/patches-5.15/030-v5.16-0015-ARM-dts-NSP-Fix-MDIO-mux-node-names.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From 38f8111369f318a538e9d4d89d8e48030c22fb40 Mon Sep 17 00:00:00 2001
-From: Matthew Hagan <mnhagan88@gmail.com>
-Date: Sun, 29 Aug 2021 22:37:49 +0000
-Subject: [PATCH] ARM: dts: NSP: Fix MDIO mux node names
-
-While functional, the mdio-mux-mmioreg binding does not conform to
-Documentation/devicetree/bindings/net/mdio-mux-mmioreg.yaml in that an
-mdio-mux compatible is also required. Without this the following output
-is observed when running dtbs_check:
-
-mdio-mux@32000: compatible: ['mdio-mux-mmioreg'] is too short
-
-This change brings conformance to this requirement and corresponds
-likewise to Rafal Milecki's change to the BCM5301x platform[1].
-
-[1] https://lore.kernel.org/linux-arm-kernel/20210822191256.3715003-1-f.fainelli@gmail.com/T/
-
-Signed-off-by: Matthew Hagan <mnhagan88@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm-nsp.dtsi | 2 +-
- arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi | 2 +-
- 2 files changed, 2 insertions(+), 2 deletions(-)
-
---- a/arch/arm/boot/dts/bcm-nsp.dtsi
-+++ b/arch/arm/boot/dts/bcm-nsp.dtsi
-@@ -371,7 +371,7 @@
- };
-
- mdio-mux@32000 {
-- compatible = "mdio-mux-mmioreg";
-+ compatible = "mdio-mux-mmioreg", "mdio-mux";
- reg = <0x32000 0x4>;
- mux-mask = <0x200>;
- #address-cells = <1>;
---- a/arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi
-+++ b/arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi
-@@ -72,7 +72,7 @@
- };
-
- mdio-mii-mux {
-- compatible = "mdio-mux-mmioreg";
-+ compatible = "mdio-mux-mmioreg", "mdio-mux";
- reg = <0x1803f1c0 0x4>;
- mux-mask = <0x2000>;
- mdio-parent-bus = <&mdio_ext>;
diff --git a/target/linux/bcm53xx/patches-5.15/030-v5.16-0016-ARM-dts-NSP-Fix-MX64-MX65-eeprom-node-name.patch b/target/linux/bcm53xx/patches-5.15/030-v5.16-0016-ARM-dts-NSP-Fix-MX64-MX65-eeprom-node-name.patch
deleted file mode 100644
index 4cffad1f4e..0000000000
--- a/target/linux/bcm53xx/patches-5.15/030-v5.16-0016-ARM-dts-NSP-Fix-MX64-MX65-eeprom-node-name.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From 56e4e548427240d85fd220460d0ab5987e1dec00 Mon Sep 17 00:00:00 2001
-From: Matthew Hagan <mnhagan88@gmail.com>
-Date: Sun, 29 Aug 2021 22:37:50 +0000
-Subject: [PATCH] ARM: dts: NSP: Fix MX64/MX65 eeprom node name
-
-Running dtbs_check yields the following message when checking the
-MX64/MX65 devicetree:
-at24@50: $nodename:0: 'at24@50' does not match '^eeprom@[0-9a-f]{1,2}$'
-
-This patch fixes the issue by renaming the at24 node appropriately.
-
-Signed-off-by: Matthew Hagan <mnhagan88@gmail.com>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm958625-meraki-mx6x-common.dtsi | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/arch/arm/boot/dts/bcm958625-meraki-mx6x-common.dtsi
-+++ b/arch/arm/boot/dts/bcm958625-meraki-mx6x-common.dtsi
-@@ -48,7 +48,7 @@
- &i2c0 {
- status = "okay";
-
-- at24@50 {
-+ eeprom@50 {
- compatible = "atmel,24c64";
- reg = <0x50>;
- pagesize = <32>;
diff --git a/target/linux/bcm53xx/patches-5.15/030-v5.16-0017-ARM-dts-NSP-Fix-MX65-MDIO-mux-warnings.patch b/target/linux/bcm53xx/patches-5.15/030-v5.16-0017-ARM-dts-NSP-Fix-MX65-MDIO-mux-warnings.patch
deleted file mode 100644
index cad7388685..0000000000
--- a/target/linux/bcm53xx/patches-5.15/030-v5.16-0017-ARM-dts-NSP-Fix-MX65-MDIO-mux-warnings.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From f5fc9044e5d45a4d97b5240c8723f4677f647c9f Mon Sep 17 00:00:00 2001
-From: Matthew Hagan <mnhagan88@gmail.com>
-Date: Sun, 29 Aug 2021 22:37:51 +0000
-Subject: [PATCH] ARM: dts: NSP: Fix MX65 MDIO mux warnings
-
-The naming of this node is based upon that of the initial EA9500 dts[1].
-However this does not conform with the mdio-mux format, yielding the
-following message when running dtbs_check:
-mdio-mii-mux: $nodename:0: 'mdio-mii-mux' does not match '^mdio-mux[\\-@]?'
-
-Secondly, this node should be moved to within the axi node and given the
-appropriate unit address. This also requires exposing the axi node via a
-label in bcm-nsp.dtsi. This fixes the following warning:
-Warning (unit_address_vs_reg): /mdio-mii-mux: node has a reg or ranges property, but no unit name
-
-[1]https://patchwork.ozlabs.org/project/linux-imx/patch/20180618174159.86150-1-npcomplete13@gmail.com/#1941353
-
-Signed-off-by: Matthew Hagan <mnhagan88@gmail.com>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm-nsp.dtsi | 2 +-
- arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi | 6 ++++--
- 2 files changed, 5 insertions(+), 3 deletions(-)
-
---- a/arch/arm/boot/dts/bcm-nsp.dtsi
-+++ b/arch/arm/boot/dts/bcm-nsp.dtsi
-@@ -166,7 +166,7 @@
- };
- };
-
-- axi@18000000 {
-+ axi: axi@18000000 {
- compatible = "simple-bus";
- ranges = <0x00000000 0x18000000 0x0011c40c>;
- #address-cells = <1>;
---- a/arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi
-+++ b/arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi
-@@ -70,10 +70,12 @@
- gpios = <&gpioa 31 GPIO_ACTIVE_HIGH>;
- };
- };
-+};
-
-- mdio-mii-mux {
-+&axi {
-+ mdio-mux@3f1c0 {
- compatible = "mdio-mux-mmioreg", "mdio-mux";
-- reg = <0x1803f1c0 0x4>;
-+ reg = <0x3f1c0 0x4>;
- mux-mask = <0x2000>;
- mdio-parent-bus = <&mdio_ext>;
- #address-cells = <1>;
diff --git a/target/linux/bcm53xx/patches-5.15/030-v5.16-0018-ARM-dts-BCM5301X-Specify-switch-ports-for-more-devic.patch b/target/linux/bcm53xx/patches-5.15/030-v5.16-0018-ARM-dts-BCM5301X-Specify-switch-ports-for-more-devic.patch
deleted file mode 100644
index b309771369..0000000000
--- a/target/linux/bcm53xx/patches-5.15/030-v5.16-0018-ARM-dts-BCM5301X-Specify-switch-ports-for-more-devic.patch
+++ /dev/null
@@ -1,290 +0,0 @@
-From 225ffaf3d0e00daa2d0c7b68e8fd731ebbde3c03 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Tue, 7 Sep 2021 08:00:48 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Specify switch ports for more devices
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Those are remaining models I have that didn't have ports yet. All
-tested.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm4708-netgear-r6250.dts | 37 ++++++++++++++++
- .../boot/dts/bcm47081-buffalo-wzr-600dhp2.dts | 37 ++++++++++++++++
- arch/arm/boot/dts/bcm4709-netgear-r8000.dts | 42 +++++++++++++++++++
- arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts | 42 +++++++++++++++++++
- arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts | 37 ++++++++++++++++
- arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts | 37 ++++++++++++++++
- 6 files changed, 232 insertions(+)
-
---- a/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
-+++ b/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
-@@ -94,3 +94,40 @@
- &usb3_phy {
- status = "okay";
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ reg = <0>;
-+ label = "lan4";
-+ };
-+
-+ port@1 {
-+ reg = <1>;
-+ label = "lan3";
-+ };
-+
-+ port@2 {
-+ reg = <2>;
-+ label = "lan2";
-+ };
-+
-+ port@3 {
-+ reg = <3>;
-+ label = "lan1";
-+ };
-+
-+ port@4 {
-+ reg = <4>;
-+ label = "wan";
-+ };
-+
-+ port@5 {
-+ reg = <5>;
-+ label = "cpu";
-+ ethernet = <&gmac0>;
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
-+++ b/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
-@@ -117,3 +117,40 @@
- };
- };
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ reg = <0>;
-+ label = "lan1";
-+ };
-+
-+ port@1 {
-+ reg = <1>;
-+ label = "lan2";
-+ };
-+
-+ port@2 {
-+ reg = <2>;
-+ label = "lan3";
-+ };
-+
-+ port@3 {
-+ reg = <3>;
-+ label = "lan4";
-+ };
-+
-+ port@4 {
-+ reg = <4>;
-+ label = "wan";
-+ };
-+
-+ port@5 {
-+ reg = <5>;
-+ label = "cpu";
-+ ethernet = <&gmac0>;
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
-+++ b/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
-@@ -187,3 +187,45 @@
- &usb3_phy {
- status = "okay";
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ reg = <0>;
-+ label = "lan1";
-+ };
-+
-+ port@1 {
-+ reg = <1>;
-+ label = "lan2";
-+ };
-+
-+ port@2 {
-+ reg = <2>;
-+ label = "lan3";
-+ };
-+
-+ port@3 {
-+ reg = <3>;
-+ label = "lan4";
-+ };
-+
-+ port@4 {
-+ reg = <4>;
-+ label = "wan";
-+ };
-+
-+ port@8 {
-+ reg = <8>;
-+ label = "cpu";
-+ ethernet = <&gmac2>;
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts
-+++ b/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts
-@@ -118,3 +118,45 @@
- &usb3_phy {
- status = "okay";
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ reg = <0>;
-+ label = "lan4";
-+ };
-+
-+ port@1 {
-+ reg = <1>;
-+ label = "lan3";
-+ };
-+
-+ port@2 {
-+ reg = <2>;
-+ label = "lan2";
-+ };
-+
-+ port@3 {
-+ reg = <3>;
-+ label = "lan1";
-+ };
-+
-+ port@4 {
-+ reg = <4>;
-+ label = "wan";
-+ };
-+
-+ port@8 {
-+ reg = <8>;
-+ label = "cpu";
-+ ethernet = <&gmac2>;
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts
-@@ -68,3 +68,40 @@
- &usb3_phy {
- status = "okay";
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ reg = <0>;
-+ label = "wan";
-+ };
-+
-+ port@1 {
-+ reg = <1>;
-+ label = "lan4";
-+ };
-+
-+ port@2 {
-+ reg = <2>;
-+ label = "lan3";
-+ };
-+
-+ port@3 {
-+ reg = <3>;
-+ label = "lan2";
-+ };
-+
-+ port@4 {
-+ reg = <4>;
-+ label = "lan1";
-+ };
-+
-+ port@5 {
-+ reg = <5>;
-+ label = "cpu";
-+ ethernet = <&gmac0>;
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts
-@@ -68,3 +68,40 @@
- &usb3_phy {
- status = "okay";
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ reg = <0>;
-+ label = "wan";
-+ };
-+
-+ port@1 {
-+ reg = <1>;
-+ label = "lan4";
-+ };
-+
-+ port@2 {
-+ reg = <2>;
-+ label = "lan3";
-+ };
-+
-+ port@3 {
-+ reg = <3>;
-+ label = "lan2";
-+ };
-+
-+ port@4 {
-+ reg = <4>;
-+ label = "lan1";
-+ };
-+
-+ port@5 {
-+ reg = <5>;
-+ label = "cpu";
-+ ethernet = <&gmac0>;
-+ };
-+ };
-+};
diff --git a/target/linux/bcm53xx/patches-5.15/030-v5.16-0020-ARM-dts-BCM53573-Add-Tenda-AC9-switch-ports.patch b/target/linux/bcm53xx/patches-5.15/030-v5.16-0020-ARM-dts-BCM53573-Add-Tenda-AC9-switch-ports.patch
deleted file mode 100644
index c6d995723c..0000000000
--- a/target/linux/bcm53xx/patches-5.15/030-v5.16-0020-ARM-dts-BCM53573-Add-Tenda-AC9-switch-ports.patch
+++ /dev/null
@@ -1,59 +0,0 @@
-From 64612828628cca6e3992e421f45c242dc6625647 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Mon, 20 Sep 2021 16:10:24 +0200
-Subject: [PATCH] ARM: dts: BCM53573: Add Tenda AC9 switch ports
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This router has 1 WAN and 4 LAN ports.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm47189-tenda-ac9.dts | 37 ++++++++++++++++++++++++
- 1 file changed, 37 insertions(+)
-
---- a/arch/arm/boot/dts/bcm47189-tenda-ac9.dts
-+++ b/arch/arm/boot/dts/bcm47189-tenda-ac9.dts
-@@ -105,3 +105,40 @@
- };
- };
- };
-+
-+&switch {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ reg = <0>;
-+ label = "wan";
-+ };
-+
-+ port@1 {
-+ reg = <1>;
-+ label = "lan1";
-+ };
-+
-+ port@2 {
-+ reg = <2>;
-+ label = "lan2";
-+ };
-+
-+ port@3 {
-+ reg = <3>;
-+ label = "lan3";
-+ };
-+
-+ port@4 {
-+ reg = <4>;
-+ label = "lan4";
-+ };
-+
-+ port@5 {
-+ reg = <5>;
-+ label = "cpu";
-+ ethernet = <&gmac0>;
-+ };
-+ };
-+};
diff --git a/target/linux/bcm53xx/patches-5.15/030-v5.16-0021-ARM-BCM53016-Specify-switch-ports-for-Meraki-MR32.patch b/target/linux/bcm53xx/patches-5.15/030-v5.16-0021-ARM-BCM53016-Specify-switch-ports-for-Meraki-MR32.patch
deleted file mode 100644
index 35f697c66f..0000000000
--- a/target/linux/bcm53xx/patches-5.15/030-v5.16-0021-ARM-BCM53016-Specify-switch-ports-for-Meraki-MR32.patch
+++ /dev/null
@@ -1,57 +0,0 @@
-From 6abc4ca5a28070945e0d68cb4160b309bfbf4b8b Mon Sep 17 00:00:00 2001
-From: Christian Lamparter <chunkeey@gmail.com>
-Date: Sat, 18 Sep 2021 19:29:30 +0200
-Subject: [PATCH] ARM: BCM53016: Specify switch ports for Meraki MR32
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-the switch identifies itself as a BCM53012 (rev 5)...
-This patch has been tested & verified on OpenWrt's
-snapshot with Linux 5.10 (didn't test any older kernels).
-The MR32 is able to "talk to the network" as before with
-OpenWrt's SWITCHDEV b53 driver.
-
-| b53-srab-switch 18007000.ethernet-switch: found switch: BCM53012, rev 5
-| libphy: dsa slave smi: probed
-| b53-srab-switch 18007000.ethernet-switch poe (uninitialized):
-| PHY [dsa-0.0:00] driver [Generic PHY] (irq=POLL)
-| b53-srab-switch 18007000.ethernet-switch: Using legacy PHYLIB callbacks.
-| Please migrate to PHYLINK!
-| DSA: tree 0 setup
-
-Reported-by: Rafał Miłecki <zajec5@gmail.com>
-Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm53016-meraki-mr32.dts | 22 ++++++++++++++++++++++
- 1 file changed, 22 insertions(+)
-
---- a/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-+++ b/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-@@ -217,3 +217,25 @@
- };
- };
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ reg = <0>;
-+ label = "poe";
-+ };
-+
-+ port@5 {
-+ reg = <5>;
-+ label = "cpu";
-+ ethernet = <&gmac0>;
-+
-+ fixed-link {
-+ speed = <1000>;
-+ duplex-full;
-+ };
-+ };
-+ };
-+};
diff --git a/target/linux/bcm53xx/patches-5.15/030-v5.16-0022-ARM-BCM53016-MR32-get-mac-address-from-nvmem.patch b/target/linux/bcm53xx/patches-5.15/030-v5.16-0022-ARM-BCM53016-MR32-get-mac-address-from-nvmem.patch
deleted file mode 100644
index 70a18822a9..0000000000
--- a/target/linux/bcm53xx/patches-5.15/030-v5.16-0022-ARM-BCM53016-MR32-get-mac-address-from-nvmem.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From 477ffdbdf389cc91294d66e251cc6f856da5820c Mon Sep 17 00:00:00 2001
-From: Christian Lamparter <chunkeey@gmail.com>
-Date: Sat, 18 Sep 2021 19:29:31 +0200
-Subject: [PATCH] ARM: BCM53016: MR32: get mac-address from nvmem
-
-The MAC-Address of the MR32's sole ethernet port is
-located in offset 0x66 of the attached AT24C64 eeprom.
-
-Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm53016-meraki-mr32.dts | 11 +++++++++++
- 1 file changed, 11 insertions(+)
-
---- a/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-+++ b/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-@@ -110,6 +110,12 @@
- reg = <0x50>;
- pagesize = <32>;
- read-only;
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ mac_address: mac-address@66 {
-+ reg = <0x66 0x6>;
-+ };
- };
- };
- };
-@@ -133,6 +139,11 @@
- */
- };
-
-+&gmac0 {
-+ nvmem-cell-names = "mac-address";
-+ nvmem-cells = <&mac_address>;
-+};
-+
- &gmac1 {
- status = "disabled";
- };
diff --git a/target/linux/bcm53xx/patches-5.15/030-v5.16-0023-ARM-dts-BCM5301X-Add-DT-for-Asus-RT-AC88U.patch b/target/linux/bcm53xx/patches-5.15/030-v5.16-0023-ARM-dts-BCM5301X-Add-DT-for-Asus-RT-AC88U.patch
deleted file mode 100644
index 667ccea0a9..0000000000
--- a/target/linux/bcm53xx/patches-5.15/030-v5.16-0023-ARM-dts-BCM5301X-Add-DT-for-Asus-RT-AC88U.patch
+++ /dev/null
@@ -1,242 +0,0 @@
-From beff77b93452cd2057c859694709dd34a181488f Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Tue, 21 Sep 2021 20:19:01 +0800
-Subject: [PATCH] ARM: dts: BCM5301X: Add DT for Asus RT-AC88U
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Hardware Info
--------------
-
-Processor - Broadcom BCM4709C0KFEBG dual-core @ 1.4 GHz
-Switch - BCM53012 in BCM4709C0KFEBG & external RTL8365MB
-DDR3 RAM - 512 MB
-Flash - 128 MB (ESMT F59L1G81LA-25T)
-2.4GHz - BCM4366 4×4 2.4/5G single chip 802.11ac SoC
-5GHz - BCM4366 4×4 2.4/5G single chip 802.11ac SoC
-Ports - 8 Ports, 1 WAN Ports
-
-Tested on OpenWrt on kernel 5.10 built with DSA driver.
-
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/Makefile | 1 +
- arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts | 200 +++++++++++++++++++
- 2 files changed, 201 insertions(+)
- create mode 100644 arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-
---- a/arch/arm/boot/dts/Makefile
-+++ b/arch/arm/boot/dts/Makefile
-@@ -117,6 +117,7 @@ dtb-$(CONFIG_ARCH_BCM_5301X) += \
- bcm4709-netgear-r7000.dtb \
- bcm4709-netgear-r8000.dtb \
- bcm4709-tplink-archer-c9-v1.dtb \
-+ bcm47094-asus-rt-ac88u.dtb \
- bcm47094-dlink-dir-885l.dtb \
- bcm47094-linksys-panamera.dtb \
- bcm47094-luxul-abr-4500.dtb \
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-@@ -0,0 +1,200 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-+/*
-+ * Copyright (C) 2021 Arınç ÜNAL <arinc.unal@arinc9.com>
-+ */
-+
-+/dts-v1/;
-+
-+#include "bcm47094.dtsi"
-+#include "bcm5301x-nand-cs0-bch8.dtsi"
-+
-+/ {
-+ compatible = "asus,rt-ac88u", "brcm,bcm47094", "brcm,bcm4708";
-+ model = "Asus RT-AC88U";
-+
-+ chosen {
-+ bootargs = "earlycon";
-+ };
-+
-+ memory@0 {
-+ device_type = "memory";
-+ reg = <0x00000000 0x08000000>,
-+ <0x88000000 0x18000000>;
-+ };
-+
-+ nvram@1c080000 {
-+ compatible = "brcm,nvram";
-+ reg = <0x1c080000 0x00180000>;
-+ };
-+
-+ leds {
-+ compatible = "gpio-leds";
-+
-+ power {
-+ label = "white:power";
-+ gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
-+ linux,default-trigger = "default-on";
-+ };
-+
-+ wan-red {
-+ label = "red:wan";
-+ gpios = <&chipcommon 5 GPIO_ACTIVE_HIGH>;
-+ };
-+
-+ lan {
-+ label = "white:lan";
-+ gpios = <&chipcommon 21 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ usb2 {
-+ label = "white:usb2";
-+ gpios = <&chipcommon 16 GPIO_ACTIVE_LOW>;
-+ trigger-sources = <&ehci_port2>;
-+ linux,default-trigger = "usbport";
-+ };
-+
-+ usb3 {
-+ label = "white:usb3";
-+ gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>;
-+ trigger-sources = <&ehci_port1>, <&xhci_port1>;
-+ linux,default-trigger = "usbport";
-+ };
-+
-+ wps {
-+ label = "white:wps";
-+ gpios = <&chipcommon 19 GPIO_ACTIVE_LOW>;
-+ };
-+ };
-+
-+ gpio-keys {
-+ compatible = "gpio-keys";
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ wps {
-+ label = "WPS";
-+ linux,code = <KEY_WPS_BUTTON>;
-+ gpios = <&chipcommon 20 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ reset {
-+ label = "Reset";
-+ linux,code = <KEY_RESTART>;
-+ gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ wifi {
-+ label = "Wi-Fi";
-+ linux,code = <KEY_RFKILL>;
-+ gpios = <&chipcommon 18 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ led {
-+ label = "Backlight";
-+ linux,code = <KEY_BRIGHTNESS_ZERO>;
-+ gpios = <&chipcommon 4 GPIO_ACTIVE_LOW>;
-+ };
-+ };
-+};
-+
-+&srab {
-+ compatible = "brcm,bcm53012-srab", "brcm,bcm5301x-srab";
-+ status = "okay";
-+ dsa,member = <0 0>;
-+
-+ ports {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ port@0 {
-+ reg = <0>;
-+ label = "lan4";
-+ };
-+
-+ port@1 {
-+ reg = <1>;
-+ label = "lan3";
-+ };
-+
-+ port@2 {
-+ reg = <2>;
-+ label = "lan2";
-+ };
-+
-+ port@3 {
-+ reg = <3>;
-+ label = "lan1";
-+ };
-+
-+ port@4 {
-+ reg = <4>;
-+ label = "wan";
-+ };
-+
-+ sw0_p5: port@5 {
-+ reg = <5>;
-+ label = "extsw";
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
-+ };
-+
-+ port@7 {
-+ reg = <7>;
-+ ethernet = <&gmac1>;
-+ label = "cpu";
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
-+ };
-+
-+ port@8 {
-+ reg = <8>;
-+ ethernet = <&gmac2>;
-+ label = "cpu";
-+ status = "disabled";
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
-+ };
-+ };
-+};
-+
-+&usb2 {
-+ vcc-gpio = <&chipcommon 9 GPIO_ACTIVE_HIGH>;
-+};
-+
-+&usb3_phy {
-+ status = "okay";
-+};
-+
-+&nandcs {
-+ partitions {
-+ compatible = "fixed-partitions";
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ partition@0 {
-+ label = "boot";
-+ reg = <0x00000000 0x00080000>;
-+ read-only;
-+ };
-+
-+ partition@80000 {
-+ label = "nvram";
-+ reg = <0x00080000 0x00180000>;
-+ };
-+
-+ partition@200000 {
-+ label = "firmware";
-+ reg = <0x00200000 0x07e00000>;
-+ compatible = "brcm,trx";
-+ };
-+ };
-+};
diff --git a/target/linux/bcm53xx/patches-5.15/031-v5.17-0001-ARM-dts-NSP-MX65-add-qca8k-falling-edge-PLL-properti.patch b/target/linux/bcm53xx/patches-5.15/031-v5.17-0001-ARM-dts-NSP-MX65-add-qca8k-falling-edge-PLL-properti.patch
deleted file mode 100644
index a0be1eda4d..0000000000
--- a/target/linux/bcm53xx/patches-5.15/031-v5.17-0001-ARM-dts-NSP-MX65-add-qca8k-falling-edge-PLL-properti.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-From 58d3d07985c1adab31a3ed76360d016bb1c5b358 Mon Sep 17 00:00:00 2001
-From: Matthew Hagan <mnhagan88@gmail.com>
-Date: Fri, 15 Oct 2021 23:50:22 +0100
-Subject: [PATCH] ARM: dts: NSP: MX65: add qca8k falling-edge, PLL properties
-
-This patch enables two properties for the QCA8337 switches on the MX65.
-
-Set the SGMII transmit clock to falling edge
-"qca,sgmii-txclk-falling-edge" to conform to the OEM configuration [1].
-
-The new explicit PLL enable option "qca,sgmii-enable-pll" is required
-[2].
-
-[1] https://git.kernel.org/netdev/net-next/c/6c43809bf1be
-[2] https://git.kernel.org/netdev/net-next/c/bbc4799e8bb6
-
-Signed-off-by: Matthew Hagan <mnhagan88@gmail.com>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- a/arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi
-+++ b/arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi
-@@ -118,6 +118,8 @@
- reg = <0>;
- ethernet = <&sgmii1>;
- phy-mode = "sgmii";
-+ qca,sgmii-enable-pll;
-+ qca,sgmii-txclk-falling-edge;
- fixed-link {
- speed = <1000>;
- full-duplex;
-@@ -194,6 +196,8 @@
- reg = <0>;
- ethernet = <&sgmii0>;
- phy-mode = "sgmii";
-+ qca,sgmii-enable-pll;
-+ qca,sgmii-txclk-falling-edge;
- fixed-link {
- speed = <1000>;
- full-duplex;
diff --git a/target/linux/bcm53xx/patches-5.15/031-v5.17-0002-ARM-dts-BCM5301X-remove-unnecessary-address-size-cel.patch b/target/linux/bcm53xx/patches-5.15/031-v5.17-0002-ARM-dts-BCM5301X-remove-unnecessary-address-size-cel.patch
deleted file mode 100644
index 3c3725adec..0000000000
--- a/target/linux/bcm53xx/patches-5.15/031-v5.17-0002-ARM-dts-BCM5301X-remove-unnecessary-address-size-cel.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From 835992e7eca4b29a87c204cefff2f7863fd087f3 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Wed, 27 Oct 2021 00:57:03 +0800
-Subject: [PATCH] ARM: dts: BCM5301X: remove unnecessary address & size cells
- from Asus RT-AC88U
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Remove the unnecessary #address-cells & #size-cells in the gpio-keys node
-from the device tree of Asus RT-AC88U.
-
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts | 2 --
- 1 file changed, 2 deletions(-)
-
---- a/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-+++ b/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-@@ -68,8 +68,6 @@
-
- gpio-keys {
- compatible = "gpio-keys";
-- #address-cells = <1>;
-- #size-cells = <0>;
-
- wps {
- label = "WPS";
diff --git a/target/linux/bcm53xx/patches-5.15/031-v5.17-0003-ARM-dts-BCM5301X-define-RTL8365MB-switch-on-Asus-RT-.patch b/target/linux/bcm53xx/patches-5.15/031-v5.17-0003-ARM-dts-BCM5301X-define-RTL8365MB-switch-on-Asus-RT-.patch
deleted file mode 100644
index 562d5a22c7..0000000000
--- a/target/linux/bcm53xx/patches-5.15/031-v5.17-0003-ARM-dts-BCM5301X-define-RTL8365MB-switch-on-Asus-RT-.patch
+++ /dev/null
@@ -1,104 +0,0 @@
-From b6c99228c8edc5e67d8229ba1c5f76cce210ddfc Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Wed, 27 Oct 2021 00:57:06 +0800
-Subject: [PATCH] ARM: dts: BCM5301X: define RTL8365MB switch on Asus RT-AC88U
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Define the Realtek RTL8365MB switch without interrupt support on the device
-tree of Asus RT-AC88U.
-
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Acked-by: Alvin Šipraga <alsi@bang-olufsen.dk>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts | 77 ++++++++++++++++++++
- 1 file changed, 77 insertions(+)
-
---- a/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-+++ b/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-@@ -93,6 +93,83 @@
- gpios = <&chipcommon 4 GPIO_ACTIVE_LOW>;
- };
- };
-+
-+ switch {
-+ compatible = "realtek,rtl8365mb";
-+ /* 7 = MDIO (has input reads), 6 = MDC (clock, output only) */
-+ mdc-gpios = <&chipcommon 6 GPIO_ACTIVE_HIGH>;
-+ mdio-gpios = <&chipcommon 7 GPIO_ACTIVE_HIGH>;
-+ reset-gpios = <&chipcommon 10 GPIO_ACTIVE_LOW>;
-+ realtek,disable-leds;
-+ dsa,member = <1 0>;
-+
-+ ports {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ reg = <0>;
-+
-+ port@0 {
-+ reg = <0>;
-+ label = "lan5";
-+ phy-handle = <&ethphy0>;
-+ };
-+
-+ port@1 {
-+ reg = <1>;
-+ label = "lan6";
-+ phy-handle = <&ethphy1>;
-+ };
-+
-+ port@2 {
-+ reg = <2>;
-+ label = "lan7";
-+ phy-handle = <&ethphy2>;
-+ };
-+
-+ port@3 {
-+ reg = <3>;
-+ label = "lan8";
-+ phy-handle = <&ethphy3>;
-+ };
-+
-+ port@6 {
-+ reg = <6>;
-+ label = "cpu";
-+ ethernet = <&sw0_p5>;
-+ phy-mode = "rgmii";
-+ tx-internal-delay-ps = <2000>;
-+ rx-internal-delay-ps = <2000>;
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ pause;
-+ };
-+ };
-+ };
-+
-+ mdio {
-+ compatible = "realtek,smi-mdio";
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ ethphy0: ethernet-phy@0 {
-+ reg = <0>;
-+ };
-+
-+ ethphy1: ethernet-phy@1 {
-+ reg = <1>;
-+ };
-+
-+ ethphy2: ethernet-phy@2 {
-+ reg = <2>;
-+ };
-+
-+ ethphy3: ethernet-phy@3 {
-+ reg = <3>;
-+ };
-+ };
-+ };
- };
-
- &srab {
diff --git a/target/linux/bcm53xx/patches-5.15/031-v5.17-0004-ARM-BCM53016-MR32-convert-to-Broadcom-iProc-I2C-Driv.patch b/target/linux/bcm53xx/patches-5.15/031-v5.17-0004-ARM-BCM53016-MR32-convert-to-Broadcom-iProc-I2C-Driv.patch
deleted file mode 100644
index 6118e98cc5..0000000000
--- a/target/linux/bcm53xx/patches-5.15/031-v5.17-0004-ARM-BCM53016-MR32-convert-to-Broadcom-iProc-I2C-Driv.patch
+++ /dev/null
@@ -1,104 +0,0 @@
-From de7880016665afe7fa7d40e1fafa859260d53ba1 Mon Sep 17 00:00:00 2001
-From: Christian Lamparter <chunkeey@gmail.com>
-Date: Thu, 28 Oct 2021 09:03:44 +0200
-Subject: [PATCH] ARM: BCM53016: MR32: convert to Broadcom iProc I2C Driver
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-replaces the bit-banged i2c-gpio provided i2c functionality
-with the hardware in the SoC.
-
-During review of the MR32, Florian Fainelli pointed out that the
-SoC has a real I2C-controller. Furthermore, the connected pins
-(SDA and SCL) would line up perfectly for use. Back then I couldn't
-get it working though and I left it with i2c-gpio (which worked).
-
-Now we know the reason: the interrupt was incorrectly specified.
-(Hence, this patch depends on Florian Fainelli's
-"ARM: dts: BCM5301X: Fix I2C controller interrupt" patch).
-
-Cc: Florian Fainelli <f.fainelli@gmail.com>
-Cc: Rafał Miłecki <zajec5@gmail.com>
-Cc: Matthew Hagan <mnhagan88@gmail.com>
-Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm53016-meraki-mr32.dts | 62 ++++++++++------------
- 1 file changed, 28 insertions(+), 34 deletions(-)
-
---- a/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-+++ b/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-@@ -84,40 +84,6 @@
- max-brightness = <255>;
- };
- };
--
-- i2c {
-- /*
-- * The platform provided I2C does not budge.
-- * This is a replacement until I can figure
-- * out what are the missing bits...
-- */
--
-- compatible = "i2c-gpio";
-- sda-gpios = <&chipcommon 5 GPIO_ACTIVE_HIGH>;
-- scl-gpios = <&chipcommon 4 GPIO_ACTIVE_HIGH>;
-- i2c-gpio,delay-us = <10>; /* close to 100 kHz */
-- #address-cells = <1>;
-- #size-cells = <0>;
--
-- current_sense: ina219@45 {
-- compatible = "ti,ina219";
-- reg = <0x45>;
-- shunt-resistor = <60000>; /* = 60 mOhms */
-- };
--
-- eeprom: eeprom@50 {
-- compatible = "atmel,24c64";
-- reg = <0x50>;
-- pagesize = <32>;
-- read-only;
-- #address-cells = <1>;
-- #size-cells = <1>;
--
-- mac_address: mac-address@66 {
-- reg = <0x66 0x6>;
-- };
-- };
-- };
- };
-
- &uart0 {
-@@ -250,3 +216,31 @@
- };
- };
- };
-+
-+&i2c0 {
-+ status = "okay";
-+
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&pinmux_i2c>;
-+
-+ clock-frequency = <100000>;
-+
-+ current_sense: ina219@45 {
-+ compatible = "ti,ina219";
-+ reg = <0x45>;
-+ shunt-resistor = <60000>; /* = 60 mOhms */
-+ };
-+
-+ eeprom: eeprom@50 {
-+ compatible = "atmel,24c64";
-+ reg = <0x50>;
-+ pagesize = <32>;
-+ read-only;
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ mac_address: mac-address@66 {
-+ reg = <0x66 0x6>;
-+ };
-+ };
-+};
diff --git a/target/linux/bcm53xx/patches-5.15/031-v5.17-0006-ARM-dts-BCM5301X-use-non-deprecated-USB-2.0-PHY-bind.patch b/target/linux/bcm53xx/patches-5.15/031-v5.17-0006-ARM-dts-BCM5301X-use-non-deprecated-USB-2.0-PHY-bind.patch
deleted file mode 100644
index e01927bedf..0000000000
--- a/target/linux/bcm53xx/patches-5.15/031-v5.17-0006-ARM-dts-BCM5301X-use-non-deprecated-USB-2.0-PHY-bind.patch
+++ /dev/null
@@ -1,54 +0,0 @@
-From 1a46061a2a4130a08841941ce6dcaa32be2ce312 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Tue, 23 Nov 2021 10:03:33 +0100
-Subject: [PATCH] ARM: dts: BCM5301X: use non-deprecated USB 2.0 PHY binding
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-The new binding covers a single reg and uses syscon to reference shared
-register.
-
-References: 55b9b741712d ("dt-bindings: phy: brcm,ns-usb2-phy: bind just a PHY block")
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm5301x.dtsi | 20 ++++++++++----------
- 1 file changed, 10 insertions(+), 10 deletions(-)
-
---- a/arch/arm/boot/dts/bcm5301x.dtsi
-+++ b/arch/arm/boot/dts/bcm5301x.dtsi
-@@ -148,15 +148,6 @@
- };
- };
-
-- usb2_phy: usb2-phy@1800c000 {
-- compatible = "brcm,ns-usb2-phy";
-- reg = <0x1800c000 0x1000>;
-- reg-names = "dmu";
-- #phy-cells = <0>;
-- clocks = <&genpll BCM_NSP_GENPLL_USB_PHY_REF_CLK>;
-- clock-names = "phy-ref-clk";
-- };
--
- axi@18000000 {
- compatible = "brcm,bus-axi";
- reg = <0x18000000 0x1000>;
-@@ -450,7 +441,16 @@
- "sata1", "sata2";
- };
-
-- syscon@180 {
-+ usb2_phy: phy@164 {
-+ compatible = "brcm,ns-usb2-phy";
-+ reg = <0x164 0x4>;
-+ brcm,syscon-clkset = <&cru_clkset>;
-+ clocks = <&genpll BCM_NSP_GENPLL_USB_PHY_REF_CLK>;
-+ clock-names = "phy-ref-clk";
-+ #phy-cells = <0>;
-+ };
-+
-+ cru_clkset: syscon@180 {
- compatible = "brcm,cru-clkset", "syscon";
- reg = <0x180 0x4>;
- };
diff --git a/target/linux/bcm53xx/patches-5.15/031-v5.17-0007-ARM-dts-NSP-Fixed-iProc-PCIe-MSI-sub-node.patch b/target/linux/bcm53xx/patches-5.15/031-v5.17-0007-ARM-dts-NSP-Fixed-iProc-PCIe-MSI-sub-node.patch
deleted file mode 100644
index 730b989808..0000000000
--- a/target/linux/bcm53xx/patches-5.15/031-v5.17-0007-ARM-dts-NSP-Fixed-iProc-PCIe-MSI-sub-node.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-From 69c4e53bdd055ecc27761f6971a50c631ff9072e Mon Sep 17 00:00:00 2001
-From: Florian Fainelli <f.fainelli@gmail.com>
-Date: Thu, 2 Dec 2021 15:16:27 -0800
-Subject: [PATCH] ARM: dts: NSP: Fixed iProc PCIe MSI sub-node
-
-Rename the msi controller unit name to 'msi' to avoid collisions with
-the 'msi-controller' boolean property.
-
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm-nsp.dtsi | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
-
---- a/arch/arm/boot/dts/bcm-nsp.dtsi
-+++ b/arch/arm/boot/dts/bcm-nsp.dtsi
-@@ -587,7 +587,7 @@
- status = "disabled";
-
- msi-parent = <&msi0>;
-- msi0: msi-controller {
-+ msi0: msi {
- compatible = "brcm,iproc-msi";
- msi-controller;
- interrupt-parent = <&gic>;
-@@ -624,7 +624,7 @@
- status = "disabled";
-
- msi-parent = <&msi1>;
-- msi1: msi-controller {
-+ msi1: msi {
- compatible = "brcm,iproc-msi";
- msi-controller;
- interrupt-parent = <&gic>;
-@@ -661,7 +661,7 @@
- status = "disabled";
-
- msi-parent = <&msi2>;
-- msi2: msi-controller {
-+ msi2: msi {
- compatible = "brcm,iproc-msi";
- msi-controller;
- interrupt-parent = <&gic>;
diff --git a/target/linux/bcm53xx/patches-5.15/031-v5.17-0008-ARM-dts-NSP-Rename-SATA-unit-name.patch b/target/linux/bcm53xx/patches-5.15/031-v5.17-0008-ARM-dts-NSP-Rename-SATA-unit-name.patch
deleted file mode 100644
index fd90fbf1f6..0000000000
--- a/target/linux/bcm53xx/patches-5.15/031-v5.17-0008-ARM-dts-NSP-Rename-SATA-unit-name.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From 9a68c53f875e88edd3403c001ad85f4ac0ed3486 Mon Sep 17 00:00:00 2001
-From: Florian Fainelli <f.fainelli@gmail.com>
-Date: Tue, 7 Dec 2021 10:19:09 -0800
-Subject: [PATCH] ARM: dts: NSP: Rename SATA unit name
-
-Rename the SATA controller unit name from ahci to sata in preparation
-for adding the Broadcom SATA3 controller YAML binding which will bring
-validation.
-
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm-nsp.dtsi | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/arch/arm/boot/dts/bcm-nsp.dtsi
-+++ b/arch/arm/boot/dts/bcm-nsp.dtsi
-@@ -534,7 +534,7 @@
- };
- };
-
-- sata: ahci@41000 {
-+ sata: sata@41000 {
- compatible = "brcm,bcm-nsp-ahci";
- reg-names = "ahci", "top-ctrl";
- reg = <0x41000 0x1000>, <0x40020 0x1c>;
diff --git a/target/linux/bcm53xx/patches-5.15/031-v5.17-0009-ARM-dts-BCM5301X-correct-RX-delay-and-enable-flow-co.patch b/target/linux/bcm53xx/patches-5.15/031-v5.17-0009-ARM-dts-BCM5301X-correct-RX-delay-and-enable-flow-co.patch
deleted file mode 100644
index e81ec169b9..0000000000
--- a/target/linux/bcm53xx/patches-5.15/031-v5.17-0009-ARM-dts-BCM5301X-correct-RX-delay-and-enable-flow-co.patch
+++ /dev/null
@@ -1,45 +0,0 @@
-From 5e33f1c4a7cb914a003a304ab8eef705b17aabb7 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Fri, 17 Dec 2021 00:03:19 +0800
-Subject: [PATCH] ARM: dts: BCM5301X: correct RX delay and enable flow control
- on Asus RT-AC88U
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-The current 'rx-internal-delay-ps' property value on the Realtek switch
-node, 2000, will be divided by 300, resulting in 6.66, which will be
-rounded to the closest step value, 7. Change it to 2100 to be accurate.
-See ef136837aaf6 ("net: dsa: rtl8365mb: set RGMII RX delay in steps of
-0.3 ns") for reference.
-
-Flow control needs to be enabled on both sides of the internal and
-external switch. It is already enabled on the CPU port of the Realtek
-switch so we also enable it on the external switch port of the Broadcom
-switch as well.
-
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
---- a/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-+++ b/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-@@ -138,7 +138,7 @@
- ethernet = <&sw0_p5>;
- phy-mode = "rgmii";
- tx-internal-delay-ps = <2000>;
-- rx-internal-delay-ps = <2000>;
-+ rx-internal-delay-ps = <2100>;
-
- fixed-link {
- speed = <1000>;
-@@ -213,6 +213,7 @@
- fixed-link {
- speed = <1000>;
- full-duplex;
-+ pause;
- };
- };
-
diff --git a/target/linux/bcm53xx/patches-5.15/031-v5.17-0010-Revert-ARM-dts-BCM5301X-define-RTL8365MB-switch-on-A.patch b/target/linux/bcm53xx/patches-5.15/031-v5.17-0010-Revert-ARM-dts-BCM5301X-define-RTL8365MB-switch-on-A.patch
deleted file mode 100644
index 3d814b1252..0000000000
--- a/target/linux/bcm53xx/patches-5.15/031-v5.17-0010-Revert-ARM-dts-BCM5301X-define-RTL8365MB-switch-on-A.patch
+++ /dev/null
@@ -1,109 +0,0 @@
-From 8b0c59c622dc4dab970ec63264fb5b152944ac80 Mon Sep 17 00:00:00 2001
-From: Arnd Bergmann <arnd@arndb.de>
-Date: Thu, 23 Dec 2021 00:17:17 +0100
-Subject: [PATCH] Revert "ARM: dts: BCM5301X: define RTL8365MB switch on Asus
- RT-AC88U"
-
-This reverts commit 3d2d52a0d1835b56f6bd67d268f6c39df0e41692, it caused
-a build regression:
-
-arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts:109.4-14: Warning (reg_format): /switch/ports:reg: property has invalid length (4 bytes) (#address-cells == 2, #size-cells == 1)
-arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dtb: Warning (pci_device_reg): Failed prerequisite 'reg_format'
-arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dtb: Warning (pci_device_bus_num): Failed prerequisite 'reg_format'
-arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dtb: Warning (i2c_bus_reg): Failed prerequisite 'reg_format'
-arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dtb: Warning (spi_bus_reg): Failed prerequisite 'reg_format'
-arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts:106.9-149.5: Warning (avoid_default_addr_size): /switch/ports: Relying on default #address-cells value
-arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts:106.9-149.5: Warning (avoid_default_addr_size): /switch/ports: Relying on default #size-cells value
-
-Reported-by: Stephen Rothwell <sfr@canb.auug.org.au>
-Signed-off-by: Arnd Bergmann <arnd@arndb.de>
----
- arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts | 77 --------------------
- 1 file changed, 77 deletions(-)
-
---- a/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-+++ b/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-@@ -93,83 +93,6 @@
- gpios = <&chipcommon 4 GPIO_ACTIVE_LOW>;
- };
- };
--
-- switch {
-- compatible = "realtek,rtl8365mb";
-- /* 7 = MDIO (has input reads), 6 = MDC (clock, output only) */
-- mdc-gpios = <&chipcommon 6 GPIO_ACTIVE_HIGH>;
-- mdio-gpios = <&chipcommon 7 GPIO_ACTIVE_HIGH>;
-- reset-gpios = <&chipcommon 10 GPIO_ACTIVE_LOW>;
-- realtek,disable-leds;
-- dsa,member = <1 0>;
--
-- ports {
-- #address-cells = <1>;
-- #size-cells = <0>;
-- reg = <0>;
--
-- port@0 {
-- reg = <0>;
-- label = "lan5";
-- phy-handle = <&ethphy0>;
-- };
--
-- port@1 {
-- reg = <1>;
-- label = "lan6";
-- phy-handle = <&ethphy1>;
-- };
--
-- port@2 {
-- reg = <2>;
-- label = "lan7";
-- phy-handle = <&ethphy2>;
-- };
--
-- port@3 {
-- reg = <3>;
-- label = "lan8";
-- phy-handle = <&ethphy3>;
-- };
--
-- port@6 {
-- reg = <6>;
-- label = "cpu";
-- ethernet = <&sw0_p5>;
-- phy-mode = "rgmii";
-- tx-internal-delay-ps = <2000>;
-- rx-internal-delay-ps = <2100>;
--
-- fixed-link {
-- speed = <1000>;
-- full-duplex;
-- pause;
-- };
-- };
-- };
--
-- mdio {
-- compatible = "realtek,smi-mdio";
-- #address-cells = <1>;
-- #size-cells = <0>;
--
-- ethphy0: ethernet-phy@0 {
-- reg = <0>;
-- };
--
-- ethphy1: ethernet-phy@1 {
-- reg = <1>;
-- };
--
-- ethphy2: ethernet-phy@2 {
-- reg = <2>;
-- };
--
-- ethphy3: ethernet-phy@3 {
-- reg = <3>;
-- };
-- };
-- };
- };
-
- &srab {
diff --git a/target/linux/bcm53xx/patches-5.15/032-v5.18-0001-ARM-dts-BCM5301X-define-RTL8365MB-switch-on-Asus-RT-.patch b/target/linux/bcm53xx/patches-5.15/032-v5.18-0001-ARM-dts-BCM5301X-define-RTL8365MB-switch-on-Asus-RT-.patch
deleted file mode 100644
index 77d3420ff8..0000000000
--- a/target/linux/bcm53xx/patches-5.15/032-v5.18-0001-ARM-dts-BCM5301X-define-RTL8365MB-switch-on-Asus-RT-.patch
+++ /dev/null
@@ -1,103 +0,0 @@
-From 441d531ec9b766f49e01c107a3043235daa4493f Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Sun, 2 Jan 2022 23:33:04 +0300
-Subject: [PATCH] ARM: dts: BCM5301X: define RTL8365MB switch on Asus RT-AC88U
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Define the Realtek RTL8365MB switch without interrupt support on the device
-tree of Asus RT-AC88U.
-
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Acked-by: Alvin Šipraga <alsi@bang-olufsen.dk>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts | 76 ++++++++++++++++++++
- 1 file changed, 76 insertions(+)
-
---- a/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-+++ b/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-@@ -93,6 +93,82 @@
- gpios = <&chipcommon 4 GPIO_ACTIVE_LOW>;
- };
- };
-+
-+ switch {
-+ compatible = "realtek,rtl8365mb";
-+ /* 7 = MDIO (has input reads), 6 = MDC (clock, output only) */
-+ mdc-gpios = <&chipcommon 6 GPIO_ACTIVE_HIGH>;
-+ mdio-gpios = <&chipcommon 7 GPIO_ACTIVE_HIGH>;
-+ reset-gpios = <&chipcommon 10 GPIO_ACTIVE_LOW>;
-+ realtek,disable-leds;
-+ dsa,member = <1 0>;
-+
-+ ports {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ port@0 {
-+ reg = <0>;
-+ label = "lan5";
-+ phy-handle = <&ethphy0>;
-+ };
-+
-+ port@1 {
-+ reg = <1>;
-+ label = "lan6";
-+ phy-handle = <&ethphy1>;
-+ };
-+
-+ port@2 {
-+ reg = <2>;
-+ label = "lan7";
-+ phy-handle = <&ethphy2>;
-+ };
-+
-+ port@3 {
-+ reg = <3>;
-+ label = "lan8";
-+ phy-handle = <&ethphy3>;
-+ };
-+
-+ port@6 {
-+ reg = <6>;
-+ label = "cpu";
-+ ethernet = <&sw0_p5>;
-+ phy-mode = "rgmii";
-+ tx-internal-delay-ps = <2000>;
-+ rx-internal-delay-ps = <2100>;
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ pause;
-+ };
-+ };
-+ };
-+
-+ mdio {
-+ compatible = "realtek,smi-mdio";
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ ethphy0: ethernet-phy@0 {
-+ reg = <0>;
-+ };
-+
-+ ethphy1: ethernet-phy@1 {
-+ reg = <1>;
-+ };
-+
-+ ethphy2: ethernet-phy@2 {
-+ reg = <2>;
-+ };
-+
-+ ethphy3: ethernet-phy@3 {
-+ reg = <3>;
-+ };
-+ };
-+ };
- };
-
- &srab {
diff --git a/target/linux/bcm53xx/patches-5.15/032-v5.18-0002-ARM-dts-NSP-MX6X-get-mac-address-from-eeprom.patch b/target/linux/bcm53xx/patches-5.15/032-v5.18-0002-ARM-dts-NSP-MX6X-get-mac-address-from-eeprom.patch
deleted file mode 100644
index 19cf1fe952..0000000000
--- a/target/linux/bcm53xx/patches-5.15/032-v5.18-0002-ARM-dts-NSP-MX6X-get-mac-address-from-eeprom.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From 66848aff05f669e95795b5f3a163f4762781333e Mon Sep 17 00:00:00 2001
-From: Matthew Hagan <mnhagan88@gmail.com>
-Date: Wed, 23 Feb 2022 23:50:39 +0000
-Subject: [PATCH] ARM: dts: NSP: MX6X: get mac-address from eeprom
-
-The MAC address on the MX64/MX65 series is located on the AT24 EEPROM.
-This is the same as other Meraki devices such as the MR32 [1].
-
-[1] https://lore.kernel.org/linux-arm-kernel/fa8271d02ef74a687f365cebe5c55ec846963ab7.1631986106.git.chunkeey@gmail.com/
-
-Signed-off-by: Matthew Hagan <mnhagan88@gmail.com>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm958625-meraki-mx6x-common.dtsi | 8 ++++++++
- 1 file changed, 8 insertions(+)
-
---- a/arch/arm/boot/dts/bcm958625-meraki-mx6x-common.dtsi
-+++ b/arch/arm/boot/dts/bcm958625-meraki-mx6x-common.dtsi
-@@ -39,6 +39,8 @@
-
- &amac2 {
- status = "okay";
-+ nvmem-cells = <&mac_address>;
-+ nvmem-cell-names = "mac-address";
- };
-
- &ehci0 {
-@@ -53,6 +55,12 @@
- reg = <0x50>;
- pagesize = <32>;
- read-only;
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ mac_address: mac-address@66 {
-+ reg = <0x66 0x6>;
-+ };
- };
- };
-
diff --git a/target/linux/bcm53xx/patches-5.15/032-v5.18-0003-ARM-dts-NSP-MX6X-correct-LED-function-types.patch b/target/linux/bcm53xx/patches-5.15/032-v5.18-0003-ARM-dts-NSP-MX6X-correct-LED-function-types.patch
deleted file mode 100644
index 2da45ff9da..0000000000
--- a/target/linux/bcm53xx/patches-5.15/032-v5.18-0003-ARM-dts-NSP-MX6X-correct-LED-function-types.patch
+++ /dev/null
@@ -1,62 +0,0 @@
-From 482c85c7fc95c572d368b2214b9e9d2c4a2e5789 Mon Sep 17 00:00:00 2001
-From: Matthew Hagan <mnhagan88@gmail.com>
-Date: Wed, 23 Feb 2022 23:50:40 +0000
-Subject: [PATCH] ARM: dts: NSP: MX6X: correct LED function types
-
-Currently, the amber LED will remain always on. This is due to a
-misinterpretation of the LED sub-node properties, where-by "default-state"
-was used to indicate the initial state when powering on the device. When in
-use, however, this resulted in the amber LED always being on. Instead change
-this to only indicate a fault state.
-
-Assign LED_FUNCTION_POWER to the green PWM LED.
-
-These changes bring the MX64/65 in line with the MR32's devicetree.
-
-Signed-off-by: Matthew Hagan <mnhagan88@gmail.com>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi | 3 +--
- arch/arm/boot/dts/bcm958625-meraki-kingpin.dtsi | 3 +--
- arch/arm/boot/dts/bcm958625-meraki-mx6x-common.dtsi | 2 +-
- 3 files changed, 3 insertions(+), 5 deletions(-)
-
---- a/arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi
-+++ b/arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi
-@@ -57,10 +57,9 @@
-
- led-4 {
- /* amber:power */
-- function = LED_FUNCTION_POWER;
-+ function = LED_FUNCTION_FAULT;
- color = <LED_COLOR_ID_AMBER>;
- gpios = <&gpioa 3 GPIO_ACTIVE_HIGH>;
-- default-state = "on";
- };
-
- led-5 {
---- a/arch/arm/boot/dts/bcm958625-meraki-kingpin.dtsi
-+++ b/arch/arm/boot/dts/bcm958625-meraki-kingpin.dtsi
-@@ -106,10 +106,9 @@
-
- led-a {
- /* amber:power */
-- function = LED_FUNCTION_POWER;
-+ function = LED_FUNCTION_FAULT;
- color = <LED_COLOR_ID_AMBER>;
- gpios = <&gpioa 0 GPIO_ACTIVE_LOW>;
-- default-state = "on";
- };
-
- led-b {
---- a/arch/arm/boot/dts/bcm958625-meraki-mx6x-common.dtsi
-+++ b/arch/arm/boot/dts/bcm958625-meraki-mx6x-common.dtsi
-@@ -22,7 +22,7 @@
- };
-
- led-2 {
-- function = LED_FUNCTION_INDICATOR;
-+ function = LED_FUNCTION_POWER;
- color = <LED_COLOR_ID_GREEN>;
- pwms = <&pwm 2 50000>;
- max-brightness = <255>;
diff --git a/target/linux/bcm53xx/patches-5.15/032-v5.18-0004-ARM-dts-BCM5301X-Add-Ethernet-MAC-address-to-Luxul-X.patch b/target/linux/bcm53xx/patches-5.15/032-v5.18-0004-ARM-dts-BCM5301X-Add-Ethernet-MAC-address-to-Luxul-X.patch
deleted file mode 100644
index c70fbc398b..0000000000
--- a/target/linux/bcm53xx/patches-5.15/032-v5.18-0004-ARM-dts-BCM5301X-Add-Ethernet-MAC-address-to-Luxul-X.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-From c8442f0fb09ca3d842b9b23d1d0650f649fd10f8 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Mon, 28 Feb 2022 10:52:07 +0100
-Subject: [PATCH] ARM: dts: BCM5301X: Add Ethernet MAC address to Luxul
- XWR-3150
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Luxul XWR-3150 stores MAC as NVRAM variable. Add NVMEM cell for it and
-reference it in the Ethernet interface node.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts | 8 ++++++++
- 1 file changed, 8 insertions(+)
-
---- a/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
-@@ -25,6 +25,9 @@
- nvram@1eff0000 {
- compatible = "brcm,nvram";
- reg = <0x1eff0000 0x10000>;
-+
-+ et0macaddr: et0macaddr {
-+ };
- };
-
- leds {
-@@ -72,6 +75,11 @@
- };
- };
-
-+&gmac0 {
-+ nvmem-cells = <&et0macaddr>;
-+ nvmem-cell-names = "mac-address";
-+};
-+
- &usb3 {
- vcc-gpio = <&chipcommon 18 GPIO_ACTIVE_HIGH>;
- };
diff --git a/target/linux/bcm53xx/patches-5.15/033-v5.19-0002-ARM-dts-BCM5301X-Fix-DTC-warning-for-NAND-node.patch b/target/linux/bcm53xx/patches-5.15/033-v5.19-0002-ARM-dts-BCM5301X-Fix-DTC-warning-for-NAND-node.patch
deleted file mode 100644
index e61fef8aab..0000000000
--- a/target/linux/bcm53xx/patches-5.15/033-v5.19-0002-ARM-dts-BCM5301X-Fix-DTC-warning-for-NAND-node.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From 90103611d573c5c238350f9b1d7cb682c62f5681 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Fri, 1 Apr 2022 13:19:58 +0300
-Subject: [PATCH] ARM: dts: BCM5301X: Fix DTC warning for NAND node
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Remove the unnecessary #address-cells and #size-cells properties on the
-nand@0 node to fix the warning below.
-
-Warning (avoid_unnecessary_addr_size): /nand-controller@18028000/nand@0: unnecessary #address-cells/#size-cells without "ranges" or child "reg" property
-
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Acked-by: Rafał Miłecki <rafal@milecki.pl>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm5301x-nand-cs0.dtsi | 2 --
- 1 file changed, 2 deletions(-)
-
---- a/arch/arm/boot/dts/bcm5301x-nand-cs0.dtsi
-+++ b/arch/arm/boot/dts/bcm5301x-nand-cs0.dtsi
-@@ -10,8 +10,6 @@
- nandcs: nand@0 {
- compatible = "brcm,nandcs";
- reg = <0>;
-- #address-cells = <1>;
-- #size-cells = <1>;
-
- partitions {
- compatible = "brcm,bcm947xx-cfe-partitions";
diff --git a/target/linux/bcm53xx/patches-5.15/033-v5.19-0003-ARM-dts-BCM5301X-Remove-cell-properties-from-srab-po.patch b/target/linux/bcm53xx/patches-5.15/033-v5.19-0003-ARM-dts-BCM5301X-Remove-cell-properties-from-srab-po.patch
deleted file mode 100644
index 6ef8720b1d..0000000000
--- a/target/linux/bcm53xx/patches-5.15/033-v5.19-0003-ARM-dts-BCM5301X-Remove-cell-properties-from-srab-po.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From e5ff0a7aab3ef5dd8ec7636b936c95179aa5ddfa Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Fri, 1 Apr 2022 13:19:59 +0300
-Subject: [PATCH] ARM: dts: BCM5301X: Remove cell properties from srab ports on
- Asus RT-AC88U
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Remove #address-cells and #size-cells properties from the ports node of
-&srab. They are already defined on bcm5301x.dtsi, there's no need to define
-them again.
-
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Acked-by: Rafał Miłecki <rafal@milecki.pl>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts | 5 +----
- 1 file changed, 1 insertion(+), 4 deletions(-)
-
---- a/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-+++ b/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-@@ -1,6 +1,6 @@
- // SPDX-License-Identifier: GPL-2.0-or-later OR MIT
- /*
-- * Copyright (C) 2021 Arınç ÜNAL <arinc.unal@arinc9.com>
-+ * Copyright (C) 2021-2022 Arınç ÜNAL <arinc.unal@arinc9.com>
- */
-
- /dts-v1/;
-@@ -177,9 +177,6 @@
- dsa,member = <0 0>;
-
- ports {
-- #address-cells = <1>;
-- #size-cells = <0>;
--
- port@0 {
- reg = <0>;
- label = "lan4";
diff --git a/target/linux/bcm53xx/patches-5.15/033-v5.19-0004-ARM-dts-BCM5301X-Add-rgmii-to-port-5-of-Broadcom-swi.patch b/target/linux/bcm53xx/patches-5.15/033-v5.19-0004-ARM-dts-BCM5301X-Add-rgmii-to-port-5-of-Broadcom-swi.patch
deleted file mode 100644
index aa192b3a11..0000000000
--- a/target/linux/bcm53xx/patches-5.15/033-v5.19-0004-ARM-dts-BCM5301X-Add-rgmii-to-port-5-of-Broadcom-swi.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From 4b7a67420a34ebd8fbf0111221a8bfd8001d418d Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Fri, 1 Apr 2022 13:20:00 +0300
-Subject: [PATCH] ARM: dts: BCM5301X: Add rgmii to port@5 of Broadcom switch on
- Asus RT-AC88U
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Define phy-mode of the Broadcom switch's port@5 as rgmii. This doesn't seem
-to matter but let's explicitly define it since phy-mode as rgmii is defined
-on the other side which is port@6 of the Realtek switch.
-
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-+++ b/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-@@ -205,6 +205,7 @@
- sw0_p5: port@5 {
- reg = <5>;
- label = "extsw";
-+ phy-mode = "rgmii";
-
- fixed-link {
- speed = <1000>;
diff --git a/target/linux/bcm53xx/patches-5.15/033-v5.19-0005-ARM-dts-BCM5301X-Retrieve-gmac1-MAC-address-from-NVR.patch b/target/linux/bcm53xx/patches-5.15/033-v5.19-0005-ARM-dts-BCM5301X-Retrieve-gmac1-MAC-address-from-NVR.patch
deleted file mode 100644
index 4c0858be0a..0000000000
--- a/target/linux/bcm53xx/patches-5.15/033-v5.19-0005-ARM-dts-BCM5301X-Retrieve-gmac1-MAC-address-from-NVR.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-From 7f7f8c7b9f3cbae1355fb3b0ce4ea9d6f1552521 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Fri, 1 Apr 2022 13:20:01 +0300
-Subject: [PATCH] ARM: dts: BCM5301X: Retrieve gmac1 MAC address from NVRAM on
- Asus RT-AC88U
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-The et1macaddr NVRAM variable contains a MAC address for gmac1 on Asus
-RT-AC88U. Add NVMEM cell for it and reference it in the gmac1 node.
-
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Acked-by: Rafał Miłecki <rafal@milecki.pl>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts | 8 ++++++++
- 1 file changed, 8 insertions(+)
-
---- a/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-+++ b/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-@@ -25,6 +25,9 @@
- nvram@1c080000 {
- compatible = "brcm,nvram";
- reg = <0x1c080000 0x00180000>;
-+
-+ et1macaddr: et1macaddr {
-+ };
- };
-
- leds {
-@@ -239,6 +242,11 @@
- };
- };
-
-+&gmac1 {
-+ nvmem-cells = <&et1macaddr>;
-+ nvmem-cell-names = "mac-address";
-+};
-+
- &usb2 {
- vcc-gpio = <&chipcommon 9 GPIO_ACTIVE_HIGH>;
- };
diff --git a/target/linux/bcm53xx/patches-5.15/033-v5.19-0006-ARM-dts-BCM5301X-Fix-compatible-strings-for-BCM53012.patch b/target/linux/bcm53xx/patches-5.15/033-v5.19-0006-ARM-dts-BCM5301X-Fix-compatible-strings-for-BCM53012.patch
deleted file mode 100644
index 59e99dae62..0000000000
--- a/target/linux/bcm53xx/patches-5.15/033-v5.19-0006-ARM-dts-BCM5301X-Fix-compatible-strings-for-BCM53012.patch
+++ /dev/null
@@ -1,65 +0,0 @@
-From 69bb5c6f3f41fe6baa86a775c8a3e69dd27f85d6 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Sat, 2 Apr 2022 23:46:21 +0300
-Subject: [PATCH] ARM: dts: BCM5301X: Fix compatible strings for BCM53012 and
- BCM53016 SoC
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Fix compatible strings for devicetrees using the BCM53012 and BCM53016 SoC.
-
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm53016-meraki-mr32.dts | 2 +-
- arch/arm/boot/dts/bcm953012er.dts | 2 +-
- arch/arm/boot/dts/bcm953012hr.dts | 2 +-
- arch/arm/boot/dts/bcm953012k.dts | 2 +-
- 4 files changed, 4 insertions(+), 4 deletions(-)
-
---- a/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-+++ b/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-@@ -13,7 +13,7 @@
- #include <dt-bindings/leds/common.h>
-
- / {
-- compatible = "meraki,mr32", "brcm,brcm53016", "brcm,bcm4708";
-+ compatible = "meraki,mr32", "brcm,bcm53016", "brcm,bcm4708";
- model = "Meraki MR32";
-
- chosen {
---- a/arch/arm/boot/dts/bcm953012er.dts
-+++ b/arch/arm/boot/dts/bcm953012er.dts
-@@ -37,7 +37,7 @@
-
- / {
- model = "NorthStar Enterprise Router (BCM953012ER)";
-- compatible = "brcm,bcm953012er", "brcm,brcm53012", "brcm,bcm4708";
-+ compatible = "brcm,bcm953012er", "brcm,bcm53012", "brcm,bcm4708";
-
- memory@0 {
- device_type = "memory";
---- a/arch/arm/boot/dts/bcm953012hr.dts
-+++ b/arch/arm/boot/dts/bcm953012hr.dts
-@@ -37,7 +37,7 @@
-
- / {
- model = "NorthStar HR (BCM953012HR)";
-- compatible = "brcm,bcm953012hr", "brcm,brcm53012", "brcm,bcm4708";
-+ compatible = "brcm,bcm953012hr", "brcm,bcm53012", "brcm,bcm4708";
-
- aliases {
- ethernet0 = &gmac0;
---- a/arch/arm/boot/dts/bcm953012k.dts
-+++ b/arch/arm/boot/dts/bcm953012k.dts
-@@ -36,7 +36,7 @@
-
- / {
- model = "NorthStar SVK (BCM953012K)";
-- compatible = "brcm,bcm953012k", "brcm,brcm53012", "brcm,bcm4708";
-+ compatible = "brcm,bcm953012k", "brcm,bcm53012", "brcm,bcm4708";
-
- aliases {
- serial0 = &uart0;
diff --git a/target/linux/bcm53xx/patches-5.15/033-v5.19-0007-ARM-dts-BCM5301X-Disable-gmac0-and-enable-port-8-on-.patch b/target/linux/bcm53xx/patches-5.15/033-v5.19-0007-ARM-dts-BCM5301X-Disable-gmac0-and-enable-port-8-on-.patch
deleted file mode 100644
index f75a53777f..0000000000
--- a/target/linux/bcm53xx/patches-5.15/033-v5.19-0007-ARM-dts-BCM5301X-Disable-gmac0-and-enable-port-8-on-.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-From b9cff8783439ff1803709128af3a0e04c5f5f047 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Sun, 10 Apr 2022 12:44:55 +0300
-Subject: [PATCH] ARM: dts: BCM5301X: Disable gmac0 and enable port@8 on Asus
- RT-AC88U
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Disable gmac0 which is not connected to any switch MAC. Enable port@8 of
-the Broadcom switch which is connected to gmac2.
-
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts | 5 ++++-
- 1 file changed, 4 insertions(+), 1 deletion(-)
-
---- a/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-+++ b/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-@@ -232,7 +232,6 @@
- reg = <8>;
- ethernet = <&gmac2>;
- label = "cpu";
-- status = "disabled";
-
- fixed-link {
- speed = <1000>;
-@@ -242,6 +241,10 @@
- };
- };
-
-+&gmac0 {
-+ status = "disabled";
-+};
-+
- &gmac1 {
- nvmem-cells = <&et1macaddr>;
- nvmem-cell-names = "mac-address";
diff --git a/target/linux/bcm53xx/patches-5.15/033-v5.19-0008-ARM-dts-BCM5301X-Add-DT-for-WZR-1166DHP-DHP2.patch b/target/linux/bcm53xx/patches-5.15/033-v5.19-0008-ARM-dts-BCM5301X-Add-DT-for-WZR-1166DHP-DHP2.patch
deleted file mode 100644
index c6f1cbd5e2..0000000000
--- a/target/linux/bcm53xx/patches-5.15/033-v5.19-0008-ARM-dts-BCM5301X-Add-DT-for-WZR-1166DHP-DHP2.patch
+++ /dev/null
@@ -1,300 +0,0 @@
-From 417aea4436bb658d8c5c4dcd0e3c255931d0ee96 Mon Sep 17 00:00:00 2001
-From: SHIMAMOTO Takayoshi <takayoshi.shimamoto.360@gmail.com>
-Date: Fri, 22 Apr 2022 00:10:54 +0900
-Subject: [PATCH] ARM: dts: BCM5301X: Add DT for WZR-1166DHP,DHP2
-
-Buffalo WZR-1166DHP/WZR-1166DHP2 wireless router with
-
- - BCM4708A0
- - 128MiB NAND flash
- - 2T2R 11ac/a/b/g/n Wi-Fi
- - 4x 10/100/1000M ethernet switch
- - 1x USB 3.0 port
-
- WZR-1166DHP and WZR-1166DHP2 have different memory capacity.
-
- WZR-1166DHP
- - 512 MiB DDR2 SDRAM
-
- WZR-1166DHP2
- - 256 MiB DDR2 SDRAM
-
- These hardware components are very similar to the WZR-1750DHP
- except for the number of antennas.
-
-Signed-off-by: SHIMAMOTO Takayoshi <takayoshi.shimamoto.360@gmail.com>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/Makefile | 2 +
- .../bcm4708-buffalo-wzr-1166dhp-common.dtsi | 192 ++++++++++++++++++
- .../boot/dts/bcm4708-buffalo-wzr-1166dhp.dts | 26 +++
- .../boot/dts/bcm4708-buffalo-wzr-1166dhp2.dts | 26 +++
- 4 files changed, 246 insertions(+)
- create mode 100644 arch/arm/boot/dts/bcm4708-buffalo-wzr-1166dhp-common.dtsi
- create mode 100644 arch/arm/boot/dts/bcm4708-buffalo-wzr-1166dhp.dts
- create mode 100644 arch/arm/boot/dts/bcm4708-buffalo-wzr-1166dhp2.dts
-
---- a/arch/arm/boot/dts/Makefile
-+++ b/arch/arm/boot/dts/Makefile
-@@ -98,6 +98,8 @@ dtb-$(CONFIG_ARCH_BCM_5301X) += \
- bcm4708-asus-rt-ac56u.dtb \
- bcm4708-asus-rt-ac68u.dtb \
- bcm4708-buffalo-wzr-1750dhp.dtb \
-+ bcm4708-buffalo-wzr-1166dhp.dtb \
-+ bcm4708-buffalo-wzr-1166dhp2.dtb \
- bcm4708-linksys-ea6300-v1.dtb \
- bcm4708-linksys-ea6500-v2.dtb \
- bcm4708-luxul-xap-1510.dtb \
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1166dhp-common.dtsi
-@@ -0,0 +1,192 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-+/*
-+ * Broadcom BCM470X / BCM5301X ARM platform code.
-+ * DTS for Buffalo WZR-1166DHP and WZR-1166DHP2
-+ *
-+ * Copyright (C) 2014 Rafał Miłecki <zajec5@gmail.com>
-+ * Copyright (C) 2022 SHIMAMOTO Takayoshi <takayoshi.shimamoto.360@gmail.com>
-+ */
-+
-+
-+#include "bcm4708.dtsi"
-+#include "bcm5301x-nand-cs0-bch8.dtsi"
-+#include <dt-bindings/leds/common.h>
-+
-+/ {
-+ spi {
-+ compatible = "spi-gpio";
-+ num-chipselects = <1>;
-+ gpio-sck = <&chipcommon 7 0>;
-+ gpio-mosi = <&chipcommon 4 0>;
-+ cs-gpios = <&chipcommon 6 0>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ hc595: gpio_spi@0 {
-+ compatible = "fairchild,74hc595";
-+ reg = <0>;
-+ registers-number = <1>;
-+ spi-max-frequency = <100000>;
-+
-+ gpio-controller;
-+ #gpio-cells = <2>;
-+
-+ };
-+ };
-+
-+ leds {
-+ compatible = "gpio-leds";
-+
-+ usb {
-+ /* label = "bcm53xx:blue:usb"; */
-+ function = LED_FUNCTION_USB;
-+ color = <LED_COLOR_ID_BLUE>;
-+ gpios = <&hc595 0 GPIO_ACTIVE_HIGH>;
-+ trigger-sources = <&ohci_port1>, <&ehci_port1>,
-+ <&xhci_port1>, <&ohci_port2>,
-+ <&ehci_port2>;
-+ linux,default-trigger = "usbport";
-+ };
-+
-+ power0 {
-+ /* label = "bcm53xx:red:power"; */
-+ function = LED_FUNCTION_FAULT;
-+ color = <LED_COLOR_ID_RED>;
-+ gpios = <&hc595 1 GPIO_ACTIVE_HIGH>;
-+ };
-+
-+ power1 {
-+ /* label = "bcm53xx:white:power"; */
-+ function = LED_FUNCTION_POWER;
-+ color = <LED_COLOR_ID_WHITE>;
-+ gpios = <&hc595 2 GPIO_ACTIVE_HIGH>;
-+ linux,default-trigger = "default-on";
-+ };
-+
-+ router0 {
-+ /* label = "bcm53xx:blue:router"; */
-+ function = LED_FUNCTION_STATUS;
-+ color = <LED_COLOR_ID_BLUE>;
-+ gpios = <&hc595 3 GPIO_ACTIVE_HIGH>;
-+ linux,default-trigger = "default-on";
-+ };
-+
-+ router1 {
-+ /* label = "bcm53xx:amber:router"; */
-+ function = LED_FUNCTION_STATUS;
-+ color = <LED_COLOR_ID_AMBER>;
-+ gpios = <&hc595 4 GPIO_ACTIVE_HIGH>;
-+ };
-+
-+ wan {
-+ /* label = "bcm53xx:blue:wan"; */
-+ function = LED_FUNCTION_WAN;
-+ color = <LED_COLOR_ID_BLUE>;
-+ gpios = <&hc595 5 GPIO_ACTIVE_HIGH>;
-+ linux,default-trigger = "default-on";
-+ };
-+
-+ wireless0 {
-+ /* label = "bcm53xx:blue:wireless"; */
-+ function = LED_FUNCTION_WLAN;
-+ color = <LED_COLOR_ID_BLUE>;
-+ gpios = <&hc595 6 GPIO_ACTIVE_HIGH>;
-+ };
-+
-+ wireless1 {
-+ /* label = "bcm53xx:amber:wireless"; */
-+ function = LED_FUNCTION_WLAN;
-+ color = <LED_COLOR_ID_AMBER>;
-+ gpios = <&hc595 7 GPIO_ACTIVE_HIGH>;
-+ };
-+ };
-+
-+ gpio-keys {
-+ compatible = "gpio-keys";
-+
-+ restart {
-+ label = "Reset";
-+ linux,code = <KEY_RESTART>;
-+ gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ aoss {
-+ label = "AOSS";
-+ linux,code = <KEY_WPS_BUTTON>;
-+ gpios = <&chipcommon 12 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ /* Commit mode set by switch? */
-+ mode {
-+ label = "Mode";
-+ linux,code = <KEY_SETUP>;
-+ gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ /* Switch: AP mode */
-+ sw_ap {
-+ label = "AP";
-+ linux,code = <BTN_0>;
-+ gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ eject {
-+ label = "USB eject";
-+ linux,code = <KEY_EJECTCD>;
-+ gpios = <&chipcommon 15 GPIO_ACTIVE_LOW>;
-+ };
-+ };
-+};
-+
-+&usb2 {
-+ vcc-gpio = <&chipcommon 9 GPIO_ACTIVE_HIGH>;
-+};
-+
-+&usb3 {
-+ vcc-gpio = <&chipcommon 10 GPIO_ACTIVE_LOW>;
-+};
-+
-+&spi_nor {
-+ status = "okay";
-+};
-+
-+&usb3_phy {
-+ status = "okay";
-+};
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ reg = <0>;
-+ label = "lan1";
-+ };
-+
-+ port@1 {
-+ reg = <1>;
-+ label = "lan2";
-+ };
-+
-+ port@2 {
-+ reg = <2>;
-+ label = "lan3";
-+ };
-+
-+ port@3 {
-+ reg = <3>;
-+ label = "lan4";
-+ };
-+
-+ port@4 {
-+ reg = <4>;
-+ label = "wan";
-+ };
-+
-+ port@5 {
-+ reg = <5>;
-+ label = "cpu";
-+ ethernet = <&gmac0>;
-+ };
-+ };
-+};
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1166dhp.dts
-@@ -0,0 +1,26 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-+/*
-+ * Device Tree Bindigs for Buffalo WZR-1166DHP
-+ *
-+ * Copyright (C) 2022 SHIMAMOTO Takayoshi <takayoshi.shimamoto.360@gmail.com>
-+ */
-+
-+/dts-v1/;
-+
-+#include "bcm4708-buffalo-wzr-1166dhp-common.dtsi"
-+
-+/ {
-+ compatible = "buffalo,wzr-1166dhp", "brcm,bcm4708";
-+ model = "Buffalo WZR-1166DHP";
-+
-+ chosen {
-+ bootargs = "console=ttyS0,115200";
-+ };
-+
-+ memory@0 {
-+ device_type = "memory";
-+ reg = <0x00000000 0x08000000>,
-+ <0x88000000 0x18000000>;
-+ };
-+
-+};
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1166dhp2.dts
-@@ -0,0 +1,26 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-+/*
-+ * Device Tree Bindigs for Buffalo WZR-1166DHP2
-+ *
-+ * Copyright (C) 2022 SHIMAMOTO Takayoshi <takayoshi.shimamoto.360@gmail.com>
-+ */
-+
-+/dts-v1/;
-+
-+#include "bcm4708-buffalo-wzr-1166dhp-common.dtsi"
-+
-+/ {
-+ compatible = "buffalo,wzr-1166dhp2", "brcm,bcm4708";
-+ model = "Buffalo WZR-1166DHP2";
-+
-+ chosen {
-+ bootargs = "console=ttyS0,115200";
-+ };
-+
-+ memory@0 {
-+ device_type = "memory";
-+ reg = <0x00000000 0x08000000>,
-+ <0x88000000 0x08000000>;
-+ };
-+
-+};
diff --git a/target/linux/bcm53xx/patches-5.15/033-v5.19-0009-Revert-ARM-dts-BCM5301X-Fix-DTC-warning-for-NAND-nod.patch b/target/linux/bcm53xx/patches-5.15/033-v5.19-0009-Revert-ARM-dts-BCM5301X-Fix-DTC-warning-for-NAND-nod.patch
deleted file mode 100644
index cc7e9741a7..0000000000
--- a/target/linux/bcm53xx/patches-5.15/033-v5.19-0009-Revert-ARM-dts-BCM5301X-Fix-DTC-warning-for-NAND-nod.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From 18176b9d82eebaf4408dc0440f54d57a8cbced83 Mon Sep 17 00:00:00 2001
-From: Arnd Bergmann <arnd@arndb.de>
-Date: Fri, 13 May 2022 11:11:07 +0200
-Subject: [PATCH] Revert "ARM: dts: BCM5301X: Fix DTC warning for NAND node"
-
-This reverts commit 90103611d573, which caused a new DTC warning
-
-arch/arm/boot/dts/bcm953012hr.dts:57.3-33: Warning (reg_format): /nand-controller@18028000/nand@0/partition@0:reg: property has invalid length (8 bytes) (#address-cells == 2, #size-cells == 1)
-arch/arm/boot/dts/bcm953012hr.dts:62.3-33: Warning (reg_format): /nand-controller@18028000/nand@0/partition@200000:reg: property has invalid length (8 bytes) (#address-cells == 2, #size-cells == 1)
-arch/arm/boot/dts/bcm953012hr.dts:66.3-33: Warning (reg_format): /nand-controller@18028000/nand@0/partition@600000:reg: property has invalid length (8 bytes) (#address-cells == 2, #size-cells == 1)
-arch/arm/boot/dts/bcm953012hr.dts:70.3-33: Warning (reg_format): /nand-controller@18028000/nand@0/partition@1000000:reg: property has invalid length (8 bytes) (#address-cells == 2, #size-cells == 1)
-arch/arm/boot/dts/bcm953012hr.dtb: Warning (pci_device_reg): Failed prerequisite 'reg_format'
-arch/arm/boot/dts/bcm953012hr.dtb: Warning (pci_device_bus_num): Failed prerequisite 'reg_format'
-arch/arm/boot/dts/bcm953012hr.dtb: Warning (i2c_bus_reg): Failed prerequisite 'reg_format'
-arch/arm/boot/dts/bcm953012hr.dtb: Warning (spi_bus_reg): Failed prerequisite 'reg_format'
-
-Signed-off-by: Arnd Bergmann <arnd@arndb.de>
----
- arch/arm/boot/dts/bcm5301x-nand-cs0.dtsi | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/arch/arm/boot/dts/bcm5301x-nand-cs0.dtsi
-+++ b/arch/arm/boot/dts/bcm5301x-nand-cs0.dtsi
-@@ -10,6 +10,8 @@
- nandcs: nand@0 {
- compatible = "brcm,nandcs";
- reg = <0>;
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-
- partitions {
- compatible = "brcm,bcm947xx-cfe-partitions";
diff --git a/target/linux/bcm53xx/patches-5.15/034-v6.0-0001-ARM-dts-broadcom-align-gpio-key-node-names-with-dtsc.patch b/target/linux/bcm53xx/patches-5.15/034-v6.0-0001-ARM-dts-broadcom-align-gpio-key-node-names-with-dtsc.patch
deleted file mode 100644
index 1c0708a5f0..0000000000
--- a/target/linux/bcm53xx/patches-5.15/034-v6.0-0001-ARM-dts-broadcom-align-gpio-key-node-names-with-dtsc.patch
+++ /dev/null
@@ -1,912 +0,0 @@
-From c5aec5611aec8fb1ca68f68e41acaefccfc93c16 Mon Sep 17 00:00:00 2001
-From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Date: Thu, 9 Jun 2022 13:39:30 +0200
-Subject: [PATCH] ARM: dts: broadcom: align gpio-key node names with dtschema
-
-The node names should be generic and DT schema expects certain pattern
-(e.g. with key/button/switch).
-
-Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dts | 6 +++---
- arch/arm/boot/dts/bcm4708-asus-rt-ac68u.dts | 8 ++++----
- .../boot/dts/bcm4708-buffalo-wzr-1166dhp-common.dtsi | 10 +++++-----
- arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts | 10 +++++-----
- arch/arm/boot/dts/bcm4708-linksys-ea6300-v1.dts | 4 ++--
- arch/arm/boot/dts/bcm4708-linksys-ea6500-v2.dts | 4 ++--
- arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts | 2 +-
- arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts | 2 +-
- arch/arm/boot/dts/bcm4708-netgear-r6250.dts | 6 +++---
- arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts | 6 +++---
- arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts | 6 +++---
- arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts | 4 ++--
- arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts | 8 ++++----
- arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts | 2 +-
- arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts | 2 +-
- arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts | 2 +-
- arch/arm/boot/dts/bcm47081-tplink-archer-c5-v2.dts | 4 ++--
- arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts | 4 ++--
- arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts | 12 ++++++------
- arch/arm/boot/dts/bcm4709-linksys-ea9200.dts | 4 ++--
- arch/arm/boot/dts/bcm4709-netgear-r7000.dts | 6 +++---
- arch/arm/boot/dts/bcm4709-netgear-r8000.dts | 8 ++++----
- arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts | 4 ++--
- arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts | 8 ++++----
- arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts | 6 +++---
- arch/arm/boot/dts/bcm47094-linksys-panamera.dts | 6 +++---
- arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts | 2 +-
- arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts | 2 +-
- arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts | 2 +-
- arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts | 2 +-
- arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts | 2 +-
- arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts | 2 +-
- arch/arm/boot/dts/bcm47094-netgear-r8500.dts | 8 ++++----
- arch/arm/boot/dts/bcm47094-phicomm-k3.dts | 2 +-
- arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts | 2 +-
- arch/arm/boot/dts/bcm47189-luxul-xap-810.dts | 2 +-
- arch/arm/boot/dts/bcm47189-tenda-ac9.dts | 6 +++---
- arch/arm/boot/dts/bcm53016-meraki-mr32.dts | 2 +-
- arch/arm/boot/dts/bcm911360_entphn.dts | 4 ++--
- arch/arm/boot/dts/bcm947189acdbmr.dts | 4 ++--
- arch/arm/boot/dts/bcm953012er.dts | 4 ++--
- arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi | 2 +-
- arch/arm/boot/dts/bcm958625-meraki-kingpin.dtsi | 2 +-
- 43 files changed, 97 insertions(+), 97 deletions(-)
-
---- a/arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dts
-+++ b/arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dts
-@@ -70,19 +70,19 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- rfkill {
-+ button-rfkill {
- label = "WiFi";
- linux,code = <KEY_RFKILL>;
- gpios = <&chipcommon 7 GPIO_ACTIVE_LOW>;
- };
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
- };
-
-- wps {
-+ button-wps {
- label = "WPS";
- linux,code = <KEY_WPS_BUTTON>;
- gpios = <&chipcommon 15 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm4708-asus-rt-ac68u.dts
-+++ b/arch/arm/boot/dts/bcm4708-asus-rt-ac68u.dts
-@@ -54,25 +54,25 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- brightness {
-+ button-brightness {
- label = "Backlight";
- linux,code = <KEY_BRIGHTNESS_ZERO>;
- gpios = <&chipcommon 5 GPIO_ACTIVE_LOW>;
- };
-
-- wps {
-+ button-wps {
- label = "WPS";
- linux,code = <KEY_WPS_BUTTON>;
- gpios = <&chipcommon 7 GPIO_ACTIVE_LOW>;
- };
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
- };
-
-- rfkill {
-+ button-rfkill {
- label = "WiFi";
- linux,code = <KEY_RFKILL>;
- gpios = <&chipcommon 15 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm4708-buffalo-wzr-1166dhp-common.dtsi
-+++ b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1166dhp-common.dtsi
-@@ -104,33 +104,33 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
- };
-
-- aoss {
-+ button-aoss {
- label = "AOSS";
- linux,code = <KEY_WPS_BUTTON>;
- gpios = <&chipcommon 12 GPIO_ACTIVE_LOW>;
- };
-
- /* Commit mode set by switch? */
-- mode {
-+ button-mode {
- label = "Mode";
- linux,code = <KEY_SETUP>;
- gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
- };
-
- /* Switch: AP mode */
-- sw_ap {
-+ button-sw-ap {
- label = "AP";
- linux,code = <BTN_0>;
- gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
- };
-
-- eject {
-+ button-eject {
- label = "USB eject";
- linux,code = <KEY_EJECTCD>;
- gpios = <&chipcommon 15 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts
-+++ b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts
-@@ -100,33 +100,33 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
- };
-
-- aoss {
-+ button-aoss {
- label = "AOSS";
- linux,code = <KEY_WPS_BUTTON>;
- gpios = <&chipcommon 12 GPIO_ACTIVE_LOW>;
- };
-
- /* Commit mode set by switch? */
-- mode {
-+ button-mode {
- label = "Mode";
- linux,code = <KEY_SETUP>;
- gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
- };
-
- /* Switch: AP mode */
-- sw_ap {
-+ button-sw-ap {
- label = "AP";
- linux,code = <BTN_0>;
- gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
- };
-
-- eject {
-+ button-eject {
- label = "USB eject";
- linux,code = <KEY_EJECTCD>;
- gpios = <&chipcommon 15 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm4708-linksys-ea6300-v1.dts
-+++ b/arch/arm/boot/dts/bcm4708-linksys-ea6300-v1.dts
-@@ -29,13 +29,13 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- wps {
-+ button-wps {
- label = "WPS";
- linux,code = <KEY_WPS_BUTTON>;
- gpios = <&chipcommon 7 GPIO_ACTIVE_LOW>;
- };
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm4708-linksys-ea6500-v2.dts
-+++ b/arch/arm/boot/dts/bcm4708-linksys-ea6500-v2.dts
-@@ -26,13 +26,13 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- wps {
-+ button-wps {
- label = "WPS";
- linux,code = <KEY_WPS_BUTTON>;
- gpios = <&chipcommon 7 GPIO_ACTIVE_LOW>;
- };
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts
-+++ b/arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts
-@@ -45,7 +45,7 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts
-+++ b/arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts
-@@ -52,7 +52,7 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 7 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
-+++ b/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
-@@ -63,19 +63,19 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- wps {
-+ button-wps {
- label = "WPS";
- linux,code = <KEY_WPS_BUTTON>;
- gpios = <&chipcommon 4 GPIO_ACTIVE_LOW>;
- };
-
-- rfkill {
-+ button-rfkill {
- label = "WiFi";
- linux,code = <KEY_RFKILL>;
- gpios = <&chipcommon 5 GPIO_ACTIVE_LOW>;
- };
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 6 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts
-+++ b/arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts
-@@ -59,19 +59,19 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- wps {
-+ button-wps {
- label = "WPS";
- linux,code = <KEY_WPS_BUTTON>;
- gpios = <&chipcommon 4 GPIO_ACTIVE_LOW>;
- };
-
-- rfkill {
-+ button-rfkill {
- label = "WiFi";
- linux,code = <KEY_RFKILL>;
- gpios = <&chipcommon 5 GPIO_ACTIVE_LOW>;
- };
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 6 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts
-+++ b/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts
-@@ -94,19 +94,19 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- rfkill {
-+ button-rfkill {
- label = "WiFi";
- linux,code = <KEY_RFKILL>;
- gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
- };
-
-- wps {
-+ button-wps {
- label = "WPS";
- linux,code = <KEY_WPS_BUTTON>;
- gpios = <&chipcommon 7 GPIO_ACTIVE_LOW>;
- };
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts
-+++ b/arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts
-@@ -60,13 +60,13 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 7 GPIO_ACTIVE_LOW>;
- };
-
-- wps {
-+ button-wps {
- label = "WPS";
- linux,code = <KEY_WPS_BUTTON>;
- gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
-+++ b/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
-@@ -91,26 +91,26 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- aoss {
-+ button-aoss {
- label = "AOSS";
- linux,code = <KEY_WPS_BUTTON>;
- gpios = <&chipcommon 9 GPIO_ACTIVE_LOW>;
- };
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
- };
-
- /* Switch device mode? */
-- mode {
-+ button-mode {
- label = "Mode";
- linux,code = <KEY_SETUP>;
- gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
- };
-
-- eject {
-+ button-eject {
- label = "USB eject";
- linux,code = <KEY_EJECTCD>;
- gpios = <&chipcommon 15 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts
-+++ b/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts
-@@ -96,7 +96,7 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts
-+++ b/arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts
-@@ -45,7 +45,7 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts
-+++ b/arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts
-@@ -94,7 +94,7 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm47081-tplink-archer-c5-v2.dts
-+++ b/arch/arm/boot/dts/bcm47081-tplink-archer-c5-v2.dts
-@@ -77,13 +77,13 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- rfkill {
-+ button-rfkill {
- label = "WiFi";
- linux,code = <KEY_RFKILL>;
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- };
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 7 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts
-+++ b/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts
-@@ -50,13 +50,13 @@
- #address-cells = <1>;
- #size-cells = <0>;
-
-- wps {
-+ button-wps {
- label = "WPS";
- linux,code = <KEY_WPS_BUTTON>;
- gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>;
- };
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts
-+++ b/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts
-@@ -80,39 +80,39 @@
- #address-cells = <1>;
- #size-cells = <0>;
-
-- power {
-+ button-power {
- label = "Power";
- linux,code = <KEY_POWER>;
- gpios = <&chipcommon 1 GPIO_ACTIVE_LOW>;
- };
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 15 GPIO_ACTIVE_LOW>;
- };
-
-- aoss {
-+ button-aoss {
- label = "AOSS";
- linux,code = <KEY_WPS_BUTTON>;
- gpios = <&chipcommon 16 GPIO_ACTIVE_LOW>;
- };
-
- /* Commit mode set by switch? */
-- mode {
-+ button-mode {
- label = "Mode";
- linux,code = <KEY_SETUP>;
- gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>;
- };
-
- /* Switch: AP mode */
-- sw_ap {
-+ button-sw-ap {
- label = "AP";
- linux,code = <BTN_0>;
- gpios = <&chipcommon 18 GPIO_ACTIVE_LOW>;
- };
-
-- eject {
-+ button-eject {
- label = "USB eject";
- linux,code = <KEY_EJECTCD>;
- gpios = <&chipcommon 20 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm4709-linksys-ea9200.dts
-+++ b/arch/arm/boot/dts/bcm4709-linksys-ea9200.dts
-@@ -32,13 +32,13 @@
- #address-cells = <1>;
- #size-cells = <0>;
-
-- wps {
-+ button-wps {
- label = "WPS";
- linux,code = <KEY_WPS_BUTTON>;
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- };
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm4709-netgear-r7000.dts
-+++ b/arch/arm/boot/dts/bcm4709-netgear-r7000.dts
-@@ -75,19 +75,19 @@
- #address-cells = <1>;
- #size-cells = <0>;
-
-- wps {
-+ button-wps {
- label = "WPS";
- linux,code = <KEY_WPS_BUTTON>;
- gpios = <&chipcommon 4 GPIO_ACTIVE_LOW>;
- };
-
-- rfkill {
-+ button-rfkill {
- label = "WiFi";
- linux,code = <KEY_RFKILL>;
- gpios = <&chipcommon 5 GPIO_ACTIVE_LOW>;
- };
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 6 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
-+++ b/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
-@@ -102,25 +102,25 @@
- #address-cells = <1>;
- #size-cells = <0>;
-
-- rfkill {
-+ button-rfkill {
- label = "WiFi";
- linux,code = <KEY_RFKILL>;
- gpios = <&chipcommon 4 GPIO_ACTIVE_LOW>;
- };
-
-- wps {
-+ button-wps {
- label = "WPS";
- linux,code = <KEY_WPS_BUTTON>;
- gpios = <&chipcommon 5 GPIO_ACTIVE_LOW>;
- };
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 6 GPIO_ACTIVE_LOW>;
- };
-
-- brightness {
-+ button-brightness {
- label = "Backlight";
- linux,code = <KEY_BRIGHTNESS_ZERO>;
- gpios = <&chipcommon 19 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts
-+++ b/arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts
-@@ -80,13 +80,13 @@
- #address-cells = <1>;
- #size-cells = <0>;
-
-- wps {
-+ button-wps {
- label = "WPS";
- linux,code = <KEY_WPS_BUTTON>;
- gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
- };
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-+++ b/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-@@ -72,25 +72,25 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- wps {
-+ button-wps {
- label = "WPS";
- linux,code = <KEY_WPS_BUTTON>;
- gpios = <&chipcommon 20 GPIO_ACTIVE_LOW>;
- };
-
-- reset {
-+ button-reset {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
- };
-
-- wifi {
-+ button-wifi {
- label = "Wi-Fi";
- linux,code = <KEY_RFKILL>;
- gpios = <&chipcommon 18 GPIO_ACTIVE_LOW>;
- };
-
-- led {
-+ button-led {
- label = "Backlight";
- linux,code = <KEY_BRIGHTNESS_ZERO>;
- gpios = <&chipcommon 4 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts
-+++ b/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts
-@@ -86,20 +86,20 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- wps {
-+ button-wps {
- label = "WPS";
- linux,code = <KEY_WPS_BUTTON>;
- gpios = <&chipcommon 7 GPIO_ACTIVE_LOW>;
- };
-
- /* Switch: router / extender */
-- extender {
-+ button-extender {
- label = "Extender";
- linux,code = <BTN_0>;
- gpios = <&chipcommon 10 GPIO_ACTIVE_LOW>;
- };
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm47094-linksys-panamera.dts
-+++ b/arch/arm/boot/dts/bcm47094-linksys-panamera.dts
-@@ -30,19 +30,19 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- wps {
-+ button-wps {
- label = "WPS";
- linux,code = <KEY_WPS_BUTTON>;
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- };
-
-- rfkill {
-+ button-rfkill {
- label = "WiFi";
- linux,code = <KEY_RFKILL>;
- gpios = <&chipcommon 16 GPIO_ACTIVE_LOW>;
- };
-
-- reset {
-+ button-reset {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts
-@@ -49,7 +49,7 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts
-@@ -43,7 +43,7 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts
-@@ -49,7 +49,7 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts
-@@ -37,7 +37,7 @@
- #address-cells = <1>;
- #size-cells = <0>;
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 19 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts
-@@ -89,7 +89,7 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
-@@ -67,7 +67,7 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm47094-netgear-r8500.dts
-+++ b/arch/arm/boot/dts/bcm47094-netgear-r8500.dts
-@@ -65,25 +65,25 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- brightness {
-+ button-brightness {
- label = "Backlight";
- linux,code = <KEY_BRIGHTNESS_ZERO>;
- gpios = <&chipcommon 1 GPIO_ACTIVE_LOW>;
- };
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 10 GPIO_ACTIVE_LOW>;
- };
-
-- wps {
-+ button-wps {
- label = "WPS";
- linux,code = <KEY_WPS_BUTTON>;
- gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
- };
-
-- rfkill {
-+ button-rfkill {
- label = "WiFi";
- linux,code = <KEY_RFKILL>;
- gpios = <&chipcommon 20 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm47094-phicomm-k3.dts
-+++ b/arch/arm/boot/dts/bcm47094-phicomm-k3.dts
-@@ -22,7 +22,7 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts
-+++ b/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts
-@@ -38,7 +38,7 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 7 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts
-+++ b/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts
-@@ -47,7 +47,7 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 7 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm47189-tenda-ac9.dts
-+++ b/arch/arm/boot/dts/bcm47189-tenda-ac9.dts
-@@ -59,19 +59,19 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- rfkill {
-+ button-rfkill {
- label = "WiFi";
- linux,code = <KEY_RFKILL>;
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- };
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 7 GPIO_ACTIVE_LOW>;
- };
-
-- wps {
-+ button-wps {
- label = "WPS";
- linux,code = <KEY_WPS_BUTTON>;
- gpios = <&chipcommon 9 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-+++ b/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-@@ -50,7 +50,7 @@
- #address-cells = <1>;
- #size-cells = <0>;
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 21 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm911360_entphn.dts
-+++ b/arch/arm/boot/dts/bcm911360_entphn.dts
-@@ -47,10 +47,10 @@
- stdout-path = "serial0:115200n8";
- };
-
-- gpio_keys {
-+ gpio-keys {
- compatible = "gpio-keys";
-
-- hook {
-+ button-hook {
- label = "HOOK";
- linux,code = <KEY_O>;
- gpios = <&gpio_asiu 48 0>;
---- a/arch/arm/boot/dts/bcm947189acdbmr.dts
-+++ b/arch/arm/boot/dts/bcm947189acdbmr.dts
-@@ -44,13 +44,13 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 7 GPIO_ACTIVE_HIGH>;
- };
-
-- wps {
-+ button-wps {
- label = "WPS";
- linux,code = <KEY_WPS_BUTTON>;
- gpios = <&chipcommon 9 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm953012er.dts
-+++ b/arch/arm/boot/dts/bcm953012er.dts
-@@ -47,13 +47,13 @@
- gpio-keys {
- compatible = "gpio-keys";
-
-- wps {
-+ button-wps {
- label = "WPS";
- linux,code = <KEY_WPS_BUTTON>;
- gpios = <&chipcommon 6 GPIO_ACTIVE_LOW>;
- };
-
-- restart {
-+ button-restart {
- label = "Reset";
- linux,code = <KEY_RESTART>;
- gpios = <&chipcommon 15 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi
-+++ b/arch/arm/boot/dts/bcm958625-meraki-alamo.dtsi
-@@ -13,7 +13,7 @@
- autorepeat;
- poll-interval = <20>;
-
-- reset {
-+ button-reset {
- label = "reset";
- linux,code = <KEY_RESTART>;
- gpios = <&gpioa 8 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm958625-meraki-kingpin.dtsi
-+++ b/arch/arm/boot/dts/bcm958625-meraki-kingpin.dtsi
-@@ -14,7 +14,7 @@
- autorepeat;
- poll-interval = <20>;
-
-- reset {
-+ button-reset {
- label = "reset";
- linux,code = <KEY_RESTART>;
- gpios = <&gpioa 6 GPIO_ACTIVE_LOW>;
diff --git a/target/linux/bcm53xx/patches-5.15/034-v6.0-0002-ARM-dts-broadcom-correct-gpio-keys-properties.patch b/target/linux/bcm53xx/patches-5.15/034-v6.0-0002-ARM-dts-broadcom-correct-gpio-keys-properties.patch
deleted file mode 100644
index 7bded431b0..0000000000
--- a/target/linux/bcm53xx/patches-5.15/034-v6.0-0002-ARM-dts-broadcom-correct-gpio-keys-properties.patch
+++ /dev/null
@@ -1,108 +0,0 @@
-From d634a6969c03803a945fdc2bccbe7d813420e569 Mon Sep 17 00:00:00 2001
-From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Date: Thu, 9 Jun 2022 13:39:31 +0200
-Subject: [PATCH] ARM: dts: broadcom: correct gpio-keys properties
-
-gpio-keys children do not use unit addresses.
-
-Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts | 2 --
- arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts | 2 --
- arch/arm/boot/dts/bcm4709-linksys-ea9200.dts | 2 --
- arch/arm/boot/dts/bcm4709-netgear-r7000.dts | 2 --
- arch/arm/boot/dts/bcm4709-netgear-r8000.dts | 2 --
- arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts | 2 --
- arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts | 2 --
- arch/arm/boot/dts/bcm53016-meraki-mr32.dts | 2 --
- 8 files changed, 16 deletions(-)
-
---- a/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts
-+++ b/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts
-@@ -47,8 +47,6 @@
-
- gpio-keys {
- compatible = "gpio-keys";
-- #address-cells = <1>;
-- #size-cells = <0>;
-
- button-wps {
- label = "WPS";
---- a/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts
-+++ b/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts
-@@ -77,8 +77,6 @@
-
- gpio-keys {
- compatible = "gpio-keys";
-- #address-cells = <1>;
-- #size-cells = <0>;
-
- button-power {
- label = "Power";
---- a/arch/arm/boot/dts/bcm4709-linksys-ea9200.dts
-+++ b/arch/arm/boot/dts/bcm4709-linksys-ea9200.dts
-@@ -29,8 +29,6 @@
-
- gpio-keys {
- compatible = "gpio-keys";
-- #address-cells = <1>;
-- #size-cells = <0>;
-
- button-wps {
- label = "WPS";
---- a/arch/arm/boot/dts/bcm4709-netgear-r7000.dts
-+++ b/arch/arm/boot/dts/bcm4709-netgear-r7000.dts
-@@ -72,8 +72,6 @@
-
- gpio-keys {
- compatible = "gpio-keys";
-- #address-cells = <1>;
-- #size-cells = <0>;
-
- button-wps {
- label = "WPS";
---- a/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
-+++ b/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
-@@ -99,8 +99,6 @@
-
- gpio-keys {
- compatible = "gpio-keys";
-- #address-cells = <1>;
-- #size-cells = <0>;
-
- button-rfkill {
- label = "WiFi";
---- a/arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts
-+++ b/arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts
-@@ -77,8 +77,6 @@
-
- gpio-keys {
- compatible = "gpio-keys";
-- #address-cells = <1>;
-- #size-cells = <0>;
-
- button-wps {
- label = "WPS";
---- a/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts
-@@ -34,8 +34,6 @@
-
- gpio-keys {
- compatible = "gpio-keys";
-- #address-cells = <1>;
-- #size-cells = <0>;
-
- button-restart {
- label = "Reset";
---- a/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-+++ b/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-@@ -47,8 +47,6 @@
-
- keys {
- compatible = "gpio-keys";
-- #address-cells = <1>;
-- #size-cells = <0>;
-
- button-restart {
- label = "Reset";
diff --git a/target/linux/bcm53xx/patches-5.15/035-v6.2-0001-ARM-dts-bcm53016-Add-devicetree-for-D-Link-DWL-8610A.patch b/target/linux/bcm53xx/patches-5.15/035-v6.2-0001-ARM-dts-bcm53016-Add-devicetree-for-D-Link-DWL-8610A.patch
deleted file mode 100644
index 206726f5f6..0000000000
--- a/target/linux/bcm53xx/patches-5.15/035-v6.2-0001-ARM-dts-bcm53016-Add-devicetree-for-D-Link-DWL-8610A.patch
+++ /dev/null
@@ -1,165 +0,0 @@
-From 9f66e1dd82e3186aee95282657512ca2aef1afe0 Mon Sep 17 00:00:00 2001
-From: Linus Walleij <linus.walleij@linaro.org>
-Date: Wed, 19 Oct 2022 21:34:49 +0200
-Subject: [PATCH] ARM: dts: bcm53016: Add devicetree for D-Link DWL-8610AP
-
-This adds a device tree for the BCM53016-based D-Link DWL-8610AP
-access point wireless router.
-
-The TRX-format partitions had to be named "firmware" due to
-an OpenWrt patch that only accepts parting such nodes if they
-are named "firmware".
-
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-Link: https://lore.kernel.org/r/20221019193449.3036010-2-linus.walleij@linaro.org
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/Makefile | 1 +
- .../boot/dts/bcm53016-dlink-dwl-8610ap.dts | 131 ++++++++++++++++++
- 2 files changed, 132 insertions(+)
- create mode 100644 arch/arm/boot/dts/bcm53016-dlink-dwl-8610ap.dts
-
---- a/arch/arm/boot/dts/Makefile
-+++ b/arch/arm/boot/dts/Makefile
-@@ -131,6 +131,7 @@ dtb-$(CONFIG_ARCH_BCM_5301X) += \
- bcm47094-netgear-r8500.dtb \
- bcm47094-phicomm-k3.dtb \
- bcm53015-meraki-mr26.dtb \
-+ bcm53016-dlink-dwl-8610ap.dtb \
- bcm53016-meraki-mr32.dtb \
- bcm94708.dtb \
- bcm94709.dtb \
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm53016-dlink-dwl-8610ap.dts
-@@ -0,0 +1,131 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-+/dts-v1/;
-+
-+#include "bcm4709.dtsi"
-+#include "bcm5301x-nand-cs0-bch8.dtsi"
-+#include <dt-bindings/leds/common.h>
-+#include <dt-bindings/input/input.h>
-+
-+/ {
-+ model = "D-Link DWL-8610AP";
-+ compatible = "dlink,dwl-8610ap", "brcm,bcm53016", "brcm,bcm4708";
-+
-+ memory@0 {
-+ device_type = "memory";
-+ /* 512 MB RAM in 2 x Macronix D9PSH chips */
-+ reg = <0x00000000 0x08000000>,
-+ <0x88000000 0x08000000>;
-+ };
-+
-+ leds {
-+ compatible = "gpio-leds";
-+
-+ power {
-+ function = LED_FUNCTION_POWER;
-+ color = <LED_COLOR_ID_GREEN>;
-+ gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
-+ default-state = "on";
-+ };
-+
-+ diag {
-+ /* Actually "diag" unclear what this means */
-+ function = LED_FUNCTION_INDICATOR;
-+ color = <LED_COLOR_ID_RED>;
-+ gpios = <&chipcommon 1 GPIO_ACTIVE_LOW>;
-+ default-state = "on";
-+ linux,default-trigger = "heartbeat";
-+ };
-+
-+ wlan-2g {
-+ function = LED_FUNCTION_WLAN;
-+ color = <LED_COLOR_ID_GREEN>;
-+ gpios = <&chipcommon 5 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ wlan-5g {
-+ function = LED_FUNCTION_WLAN;
-+ color = <LED_COLOR_ID_GREEN>;
-+ gpios = <&chipcommon 8 GPIO_ACTIVE_LOW>;
-+ };
-+ };
-+
-+ gpio_keys {
-+ compatible = "gpio-keys";
-+
-+ button-reset {
-+ debounce-interval = <100>;
-+ wakeup-source;
-+ linux,code = <KEY_RESTART>;
-+ label = "reset";
-+ /* This GPIO is actually stored in NVRAM, but it's not gonna change */
-+ gpios = <&chipcommon 4 GPIO_ACTIVE_LOW>;
-+ };
-+ };
-+
-+ /*
-+ * Flash memory at 0x1e000000-0x1fffffff
-+ * Macronix 32 64KB blocks; total size 2MB, same that can be
-+ * found attached to the spi_nor SPI controller.
-+ */
-+ nvram@1e080000 {
-+ compatible = "brcm,nvram";
-+ reg = <0x1e080000 0x00020000>;
-+
-+ et0macaddr: et0macaddr {
-+ };
-+
-+ et1macaddr: et1macaddr {
-+ };
-+ };
-+};
-+
-+&gmac0 {
-+ nvmem-cells = <&et0macaddr>;
-+ nvmem-cell-names = "mac-address";
-+};
-+
-+&gmac1 {
-+ nvmem-cells = <&et1macaddr>;
-+ nvmem-cell-names = "mac-address";
-+};
-+
-+&spi_nor {
-+ /* Serial SPI NOR Flash MX 25L1606E */
-+ status = "okay";
-+};
-+
-+&nandcs {
-+ /*
-+ * Spansion S34ML01G100TFI00 128 MB NAND Flash memory
-+ *
-+ * This ECC is a bit unorthodox but it is what the stock firmware
-+ * is using, so to be able to mount the original partitions
-+ * this is necessary.
-+ */
-+ nand-ecc-strength = <5>;
-+ partitions {
-+ compatible = "fixed-partitions";
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ /* This is named nflash1.trx in CFE */
-+ trx@0 {
-+ label = "firmware";
-+ reg = <0x00000000 0x02800000>;
-+ compatible = "brcm,trx";
-+ };
-+
-+ /* This is named nflash1.trx2 in CFE */
-+ trx2@2800000 {
-+ label = "firmware2";
-+ reg = <0x02800000 0x02800000>;
-+ compatible = "brcm,trx";
-+ };
-+
-+ /* This is named nflash1.rwfs in CFE */
-+ free@5000000 {
-+ label = "free";
-+ reg = <0x05000000 0x03000000>;
-+ };
-+ };
-+};
diff --git a/target/linux/bcm53xx/patches-5.15/035-v6.2-0002-ARM-dts-bcm47094-Add-devicetree-for-D-Link-DIR-890L.patch b/target/linux/bcm53xx/patches-5.15/035-v6.2-0002-ARM-dts-bcm47094-Add-devicetree-for-D-Link-DIR-890L.patch
deleted file mode 100644
index 4842e16649..0000000000
--- a/target/linux/bcm53xx/patches-5.15/035-v6.2-0002-ARM-dts-bcm47094-Add-devicetree-for-D-Link-DIR-890L.patch
+++ /dev/null
@@ -1,242 +0,0 @@
-From b1ba87897ceda8e49a47aa92832dd7bff8583e21 Mon Sep 17 00:00:00 2001
-From: Linus Walleij <linus.walleij@linaro.org>
-Date: Mon, 7 Nov 2022 14:41:04 +0100
-Subject: [PATCH] ARM: dts: bcm47094: Add devicetree for D-Link DIR-890L
-
-This adds a device tree for the D-Link DIR-890L. This device
-is very similar to D-Link DIR-885L, the differences are detailed
-as a comment in the DTS file.
-
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-Link: https://lore.kernel.org/r/20221107134104.1422169-2-linus.walleij@linaro.org
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/Makefile | 1 +
- arch/arm/boot/dts/bcm47094-dlink-dir-890l.dts | 211 ++++++++++++++++++
- 2 files changed, 212 insertions(+)
- create mode 100644 arch/arm/boot/dts/bcm47094-dlink-dir-890l.dts
-
---- a/arch/arm/boot/dts/Makefile
-+++ b/arch/arm/boot/dts/Makefile
-@@ -121,6 +121,7 @@ dtb-$(CONFIG_ARCH_BCM_5301X) += \
- bcm4709-tplink-archer-c9-v1.dtb \
- bcm47094-asus-rt-ac88u.dtb \
- bcm47094-dlink-dir-885l.dtb \
-+ bcm47094-dlink-dir-890l.dtb \
- bcm47094-linksys-panamera.dtb \
- bcm47094-luxul-abr-4500.dtb \
- bcm47094-luxul-xap-1610.dtb \
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm47094-dlink-dir-890l.dts
-@@ -0,0 +1,211 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-+/*
-+ * Device tree for D-Link DIR-890L
-+ * D-Link calls this board "WRGAC36"
-+ * this router has the same looks and form factor as D-Link DIR-885L.
-+ *
-+ * Some differences from DIR-885L include a separate USB2 port, separate LEDs
-+ * for USB2 and USB3, a separate VCC supply for the USB2 slot and no
-+ * router/extender switch is mounted (there is an empty mount point on the
-+ * PCB) so this device is a pure router. Also the LAN ports are in the right
-+ * order.
-+ *
-+ * Based on the device tree for DIR-885L
-+ * Copyright (C) 2016 Rafał Miłecki <zajec5@gmail.com>
-+ * Copyright (C) 2022 Linus Walleij
-+ */
-+
-+/dts-v1/;
-+
-+#include "bcm47094.dtsi"
-+#include "bcm5301x-nand-cs0-bch1.dtsi"
-+
-+/ {
-+ compatible = "dlink,dir-890l", "brcm,bcm47094", "brcm,bcm4708";
-+ model = "D-Link DIR-890L";
-+
-+ chosen {
-+ bootargs = "console=ttyS0,115200 earlycon";
-+ };
-+
-+ memory@0 {
-+ device_type = "memory";
-+ reg = <0x00000000 0x08000000>,
-+ <0x88000000 0x08000000>;
-+ };
-+
-+ leds {
-+ /*
-+ * LED information is derived from the boot log which
-+ * conveniently lists all the LEDs.
-+ */
-+ compatible = "gpio-leds";
-+
-+ power-white {
-+ label = "bcm53xx:white:power";
-+ gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
-+ linux,default-trigger = "default-on";
-+ };
-+
-+ wan-white {
-+ label = "bcm53xx:white:wan";
-+ gpios = <&chipcommon 1 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ power-amber {
-+ label = "bcm53xx:amber:power";
-+ gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ wan-amber {
-+ label = "bcm53xx:amber:wan";
-+ gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ usb3-white {
-+ label = "bcm53xx:white:usb3";
-+ gpios = <&chipcommon 8 GPIO_ACTIVE_LOW>;
-+ trigger-sources = <&xhci_port1>;
-+ linux,default-trigger = "usbport";
-+ };
-+
-+ usb2-white {
-+ label = "bcm53xx:white:usb2";
-+ gpios = <&chipcommon 15 GPIO_ACTIVE_LOW>;
-+ trigger-sources = <&ohci_port1>, <&ehci_port1>;
-+ linux,default-trigger = "usbport";
-+ };
-+
-+ 2ghz {
-+ label = "bcm53xx:white:2ghz";
-+ gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ 5ghz {
-+ label = "bcm53xx:white:5ghz";
-+ gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
-+ };
-+ };
-+
-+ gpio-keys {
-+ compatible = "gpio-keys";
-+
-+ button-wps {
-+ label = "WPS";
-+ linux,code = <KEY_WPS_BUTTON>;
-+ gpios = <&chipcommon 7 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ /* Called "factory reset" in the vendor dmesg */
-+ button-restart {
-+ label = "Reset";
-+ linux,code = <KEY_RESTART>;
-+ gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>;
-+ };
-+ };
-+
-+ /*
-+ * The flash memory is memory mapped at 0x1e000000-0x1fffffff
-+ * 64KB blocks; total size 2MB, same that can be
-+ * found attached to the spi_nor SPI controller.
-+ */
-+ nvram@1e1f0000 {
-+ compatible = "brcm,nvram";
-+ reg = <0x1e1f0000 0x00010000>;
-+
-+ et0macaddr: et0macaddr {
-+ };
-+ };
-+};
-+
-+&gmac2 {
-+ /*
-+ * The NVRAM curiously does not contain a MAC address
-+ * for et2 so since that is the only ethernet interface
-+ * actually in use on the platform, we use this et0 MAC
-+ * address for et2.
-+ */
-+ nvmem-cells = <&et0macaddr>;
-+ nvmem-cell-names = "mac-address";
-+};
-+
-+&spi_nor {
-+ status = "okay";
-+};
-+
-+&nandcs {
-+ /* Spansion S34ML01G2, 128MB with 128KB erase blocks */
-+ partitions {
-+ compatible = "fixed-partitions";
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ /*
-+ * This is called "nflash" in the vendor kernel with
-+ * "upgrade" and "rootfs" (probably using OpenWrt
-+ * splitpart). We call it "firmware" like standard tools
-+ * assume. The CFE loader contains incorrect information
-+ * about TRX partitions, ignore this, there are no TRX
-+ * partitions: this device uses SEAMA.
-+ */
-+ firmware@0 {
-+ label = "firmware";
-+ reg = <0x00000000 0x08000000>;
-+ };
-+ };
-+};
-+
-+&usb2 {
-+ vcc-gpios = <&chipcommon 21 GPIO_ACTIVE_HIGH>;
-+};
-+
-+&usb3 {
-+ vcc-gpios = <&chipcommon 18 GPIO_ACTIVE_HIGH>;
-+};
-+
-+&usb3_phy {
-+ status = "okay";
-+};
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ reg = <0>;
-+ label = "lan1";
-+ };
-+
-+ port@1 {
-+ reg = <1>;
-+ label = "lan2";
-+ };
-+
-+ port@2 {
-+ reg = <2>;
-+ label = "lan3";
-+ };
-+
-+ port@3 {
-+ reg = <3>;
-+ label = "lan4";
-+ };
-+
-+ port@4 {
-+ reg = <4>;
-+ label = "wan";
-+ };
-+
-+ port@8 {
-+ reg = <8>;
-+ label = "cpu";
-+ ethernet = <&gmac2>;
-+ phy-mode = "rgmii";
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
-+ };
-+ };
-+};
diff --git a/target/linux/bcm53xx/patches-5.15/035-v6.2-0003-ARM-dts-BCM5301X-Correct-description-of-TP-Link-part.patch b/target/linux/bcm53xx/patches-5.15/035-v6.2-0003-ARM-dts-BCM5301X-Correct-description-of-TP-Link-part.patch
deleted file mode 100644
index 4c4ed036b9..0000000000
--- a/target/linux/bcm53xx/patches-5.15/035-v6.2-0003-ARM-dts-BCM5301X-Correct-description-of-TP-Link-part.patch
+++ /dev/null
@@ -1,99 +0,0 @@
-From c8ee9f119bfb4244f76c9971c341ec06b49332cd Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Tue, 8 Nov 2022 12:07:08 +0100
-Subject: [PATCH] ARM: dts: BCM5301X: Correct description of TP-Link partitions
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-TP-Link routers have flash space partitioned according to the partitions
-table. It may look like fixed partitioning but those partitions can be
-actually reorganized. New can be added (or some removed), offsets and
-sizes may change.
-
-Fix DT to use binding for the TP-Link SafeLoader partitioning method.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20221108110708.13693-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- .../boot/dts/bcm47081-tplink-archer-c5-v2.dts | 25 ++++---------------
- .../boot/dts/bcm4709-tplink-archer-c9-v1.dts | 25 ++++---------------
- 2 files changed, 10 insertions(+), 40 deletions(-)
-
---- a/arch/arm/boot/dts/bcm47081-tplink-archer-c5-v2.dts
-+++ b/arch/arm/boot/dts/bcm47081-tplink-archer-c5-v2.dts
-@@ -95,30 +95,15 @@
- status = "okay";
-
- partitions {
-- compatible = "fixed-partitions";
-- #address-cells = <1>;
-- #size-cells = <1>;
-+ compatible = "tplink,safeloader-partitions";
-+ partitions-table-offset = <0xe50000>;
-
-- boot@0 {
-- label = "boot";
-- reg = <0x000000 0x040000>;
-- read-only;
-- };
--
-- os-image@100000 {
-- label = "os-image";
-- reg = <0x040000 0x200000>;
-+ partition-os-image {
- compatible = "brcm,trx";
- };
-
-- rootfs@240000 {
-- label = "rootfs";
-- reg = <0x240000 0xc00000>;
-- };
--
-- nvram@ff0000 {
-- label = "nvram";
-- reg = <0xff0000 0x010000>;
-+ partition-file-system {
-+ linux,rootfs;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts
-+++ b/arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts
-@@ -104,30 +104,15 @@
- status = "okay";
-
- partitions {
-- compatible = "fixed-partitions";
-- #address-cells = <1>;
-- #size-cells = <1>;
-+ compatible = "tplink,safeloader-partitions";
-+ partitions-table-offset = <0xe50000>;
-
-- boot@0 {
-- label = "boot";
-- reg = <0x000000 0x040000>;
-- read-only;
-- };
--
-- os-image@100000 {
-- label = "os-image";
-- reg = <0x040000 0x200000>;
-+ partition-os-image {
- compatible = "brcm,trx";
- };
-
-- rootfs@240000 {
-- label = "rootfs";
-- reg = <0x240000 0xc00000>;
-- };
--
-- nvram@ff0000 {
-- label = "nvram";
-- reg = <0xff0000 0x010000>;
-+ partition-file-system {
-+ linux,rootfs;
- };
- };
- };
diff --git a/target/linux/bcm53xx/patches-5.15/035-v6.2-0004-ARM-dts-broadcom-align-LED-node-names-with-dtschema.patch b/target/linux/bcm53xx/patches-5.15/035-v6.2-0004-ARM-dts-broadcom-align-LED-node-names-with-dtschema.patch
deleted file mode 100644
index a53070a506..0000000000
--- a/target/linux/bcm53xx/patches-5.15/035-v6.2-0004-ARM-dts-broadcom-align-LED-node-names-with-dtschema.patch
+++ /dev/null
@@ -1,1698 +0,0 @@
-From af84101e3f2258a303fa2461ebec0878ce23ea10 Mon Sep 17 00:00:00 2001
-From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Date: Fri, 25 Nov 2022 15:41:27 +0100
-Subject: [PATCH] ARM: dts: broadcom: align LED node names with dtschema
-
-The node names should be generic and DT schema expects certain pattern:
-
- bcm4708-asus-rt-ac68u.dtb: leds: 'logo', 'power', 'usb2', 'usb3' do not match any of the regexes: '(^led-[0-9a-f]$|led)', 'pinctrl-[0-9]+'
-
-Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Link: https://lore.kernel.org/r/20221125144128.477059-1-krzysztof.kozlowski@linaro.org
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dts | 15 +++++-----
- arch/arm/boot/dts/bcm4708-asus-rt-ac68u.dts | 8 +++---
- .../bcm4708-buffalo-wzr-1166dhp-common.dtsi | 16 +++++------
- .../boot/dts/bcm4708-buffalo-wzr-1750dhp.dts | 16 +++++------
- arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts | 6 ++--
- arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts | 2 +-
- arch/arm/boot/dts/bcm4708-netgear-r6250.dts | 10 +++----
- .../arm/boot/dts/bcm4708-netgear-r6300-v2.dts | 10 +++----
- arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts | 22 +++++++--------
- arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts | 10 +++----
- .../boot/dts/bcm47081-buffalo-wzr-600dhp2.dts | 14 +++++-----
- .../boot/dts/bcm47081-buffalo-wzr-900dhp.dts | 16 +++++------
- arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts | 6 ++--
- arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts | 20 ++++++-------
- .../boot/dts/bcm47081-tplink-archer-c5-v2.dts | 18 ++++++------
- arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts | 6 ++--
- .../boot/dts/bcm4709-buffalo-wxr-1900dhp.dts | 18 ++++++------
- arch/arm/boot/dts/bcm4709-netgear-r7000.dts | 16 +++++------
- arch/arm/boot/dts/bcm4709-netgear-r8000.dts | 22 +++++++--------
- .../boot/dts/bcm4709-tplink-archer-c9-v1.dts | 18 ++++++------
- arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts | 12 ++++----
- arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts | 14 +++++-----
- arch/arm/boot/dts/bcm47094-dlink-dir-890l.dts | 16 +++++------
- .../boot/dts/bcm47094-linksys-panamera.dts | 28 +++++++++----------
- arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts | 4 +--
- arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts | 6 ++--
- arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts | 4 +--
- arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts | 2 +-
- arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts | 20 ++++++-------
- .../boot/dts/bcm47094-luxul-xwr-3150-v1.dts | 10 +++----
- arch/arm/boot/dts/bcm47094-netgear-r8500.dts | 14 +++++-----
- arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts | 4 +--
- arch/arm/boot/dts/bcm47189-luxul-xap-810.dts | 10 +++----
- arch/arm/boot/dts/bcm47189-tenda-ac9.dts | 14 +++++-----
- .../boot/dts/bcm53016-dlink-dwl-8610ap.dts | 8 +++---
- arch/arm/boot/dts/bcm53016-meraki-mr32.dts | 6 ++--
- arch/arm/boot/dts/bcm947189acdbmr.dts | 6 ++--
- 37 files changed, 223 insertions(+), 224 deletions(-)
-
---- a/arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dts
-+++ b/arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dts
-@@ -28,40 +28,39 @@
- leds {
- compatible = "gpio-leds";
-
-- usb3 {
-+ led-usb3 {
- label = "bcm53xx:blue:usb3";
- gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
- };
-
-- wan {
-+ led-wan {
- label = "bcm53xx:blue:wan";
- gpios = <&chipcommon 1 GPIO_ACTIVE_LOW>;
- };
-
-- lan {
-+ led-lan {
- label = "bcm53xx:blue:lan";
- gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>;
- };
-
-- power {
-+ led-power {
- label = "bcm53xx:blue:power";
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- all {
-+ led-all {
- label = "bcm53xx:blue:all";
- gpios = <&chipcommon 4 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:blue:2ghz";
- gpios = <&chipcommon 6 GPIO_ACTIVE_LOW>;
- };
-
--
-- usb2 {
-+ led-usb2 {
- label = "bcm53xx:blue:usb2";
- gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
- };
---- a/arch/arm/boot/dts/bcm4708-asus-rt-ac68u.dts
-+++ b/arch/arm/boot/dts/bcm4708-asus-rt-ac68u.dts
-@@ -28,24 +28,24 @@
- leds {
- compatible = "gpio-leds";
-
-- usb2 {
-+ led-usb2 {
- label = "bcm53xx:blue:usb2";
- gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
- };
-
-- power {
-+ led-power {
- label = "bcm53xx:blue:power";
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- logo {
-+ led-logo {
- label = "bcm53xx:white:logo";
- gpios = <&chipcommon 4 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- usb3 {
-+ led-usb3 {
- label = "bcm53xx:blue:usb3";
- gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
- };
---- a/arch/arm/boot/dts/bcm4708-buffalo-wzr-1166dhp-common.dtsi
-+++ b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1166dhp-common.dtsi
-@@ -37,7 +37,7 @@
- leds {
- compatible = "gpio-leds";
-
-- usb {
-+ led-usb {
- /* label = "bcm53xx:blue:usb"; */
- function = LED_FUNCTION_USB;
- color = <LED_COLOR_ID_BLUE>;
-@@ -48,14 +48,14 @@
- linux,default-trigger = "usbport";
- };
-
-- power0 {
-+ led-power0 {
- /* label = "bcm53xx:red:power"; */
- function = LED_FUNCTION_FAULT;
- color = <LED_COLOR_ID_RED>;
- gpios = <&hc595 1 GPIO_ACTIVE_HIGH>;
- };
-
-- power1 {
-+ led-power1 {
- /* label = "bcm53xx:white:power"; */
- function = LED_FUNCTION_POWER;
- color = <LED_COLOR_ID_WHITE>;
-@@ -63,7 +63,7 @@
- linux,default-trigger = "default-on";
- };
-
-- router0 {
-+ led-router0 {
- /* label = "bcm53xx:blue:router"; */
- function = LED_FUNCTION_STATUS;
- color = <LED_COLOR_ID_BLUE>;
-@@ -71,14 +71,14 @@
- linux,default-trigger = "default-on";
- };
-
-- router1 {
-+ led-router1 {
- /* label = "bcm53xx:amber:router"; */
- function = LED_FUNCTION_STATUS;
- color = <LED_COLOR_ID_AMBER>;
- gpios = <&hc595 4 GPIO_ACTIVE_HIGH>;
- };
-
-- wan {
-+ led-wan {
- /* label = "bcm53xx:blue:wan"; */
- function = LED_FUNCTION_WAN;
- color = <LED_COLOR_ID_BLUE>;
-@@ -86,14 +86,14 @@
- linux,default-trigger = "default-on";
- };
-
-- wireless0 {
-+ led-wireless0 {
- /* label = "bcm53xx:blue:wireless"; */
- function = LED_FUNCTION_WLAN;
- color = <LED_COLOR_ID_BLUE>;
- gpios = <&hc595 6 GPIO_ACTIVE_HIGH>;
- };
-
-- wireless1 {
-+ led-wireless1 {
- /* label = "bcm53xx:amber:wireless"; */
- function = LED_FUNCTION_WLAN;
- color = <LED_COLOR_ID_AMBER>;
---- a/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts
-+++ b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts
-@@ -49,7 +49,7 @@
- leds {
- compatible = "gpio-leds";
-
-- usb {
-+ led-usb {
- label = "bcm53xx:blue:usb";
- gpios = <&hc595 0 GPIO_ACTIVE_HIGH>;
- trigger-sources = <&ohci_port1>, <&ehci_port1>,
-@@ -58,40 +58,40 @@
- linux,default-trigger = "usbport";
- };
-
-- power0 {
-+ led-power0 {
- label = "bcm53xx:red:power";
- gpios = <&hc595 1 GPIO_ACTIVE_HIGH>;
- };
-
-- power1 {
-+ led-power1 {
- label = "bcm53xx:white:power";
- gpios = <&hc595 2 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- router0 {
-+ led-router0 {
- label = "bcm53xx:blue:router";
- gpios = <&hc595 3 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- router1 {
-+ led-router1 {
- label = "bcm53xx:amber:router";
- gpios = <&hc595 4 GPIO_ACTIVE_HIGH>;
- };
-
-- wan {
-+ led-wan {
- label = "bcm53xx:blue:wan";
- gpios = <&hc595 5 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- wireless0 {
-+ led-wireless0 {
- label = "bcm53xx:blue:wireless";
- gpios = <&hc595 6 GPIO_ACTIVE_HIGH>;
- };
-
-- wireless1 {
-+ led-wireless1 {
- label = "bcm53xx:amber:wireless";
- gpios = <&hc595 7 GPIO_ACTIVE_HIGH>;
- };
---- a/arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts
-+++ b/arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts
-@@ -23,19 +23,19 @@
- leds {
- compatible = "gpio-leds";
-
-- 5ghz {
-+ led-5ghz {
- label = "bcm53xx:blue:5ghz";
- gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "none";
- };
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:blue:2ghz";
- gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "none";
- };
-
-- status {
-+ led-status {
- label = "bcm53xx:green:status";
- gpios = <&chipcommon 15 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "timer";
---- a/arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts
-+++ b/arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts
-@@ -42,7 +42,7 @@
- leds {
- compatible = "gpio-leds";
-
-- status {
-+ led-status {
- label = "bcm53xx:green:status";
- gpios = <&chipcommon 0 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "timer";
---- a/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
-+++ b/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
-@@ -29,24 +29,24 @@
- leds {
- compatible = "gpio-leds";
-
-- logo {
-+ led-logo {
- label = "bcm53xx:white:logo";
- gpios = <&chipcommon 1 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- power0 {
-+ led-power0 {
- label = "bcm53xx:green:power";
- gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- power1 {
-+ led-power1 {
- label = "bcm53xx:amber:power";
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- };
-
-- usb {
-+ led-usb {
- label = "bcm53xx:blue:usb";
- gpios = <&chipcommon 8 GPIO_ACTIVE_LOW>;
- trigger-sources = <&ohci_port1>, <&ehci_port1>,
-@@ -54,7 +54,7 @@
- linux,default-trigger = "usbport";
- };
-
-- wireless {
-+ led-wireless {
- label = "bcm53xx:blue:wireless";
- gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
- };
---- a/arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts
-+++ b/arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts
-@@ -28,29 +28,29 @@
- leds {
- compatible = "gpio-leds";
-
-- logo {
-+ led-logo {
- label = "bcm53xx:white:logo";
- gpios = <&chipcommon 1 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- power0 {
-+ led-power0 {
- label = "bcm53xx:green:power";
- gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>;
- };
-
-- power1 {
-+ led-power1 {
- label = "bcm53xx:amber:power";
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- usb {
-+ led-usb {
- label = "bcm53xx:blue:usb";
- gpios = <&chipcommon 8 GPIO_ACTIVE_LOW>;
- };
-
-- wireless {
-+ led-wireless {
- label = "bcm53xx:blue:wireless";
- gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
- };
---- a/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts
-+++ b/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts
-@@ -28,64 +28,64 @@
- leds {
- compatible = "gpio-leds";
-
-- power-white {
-+ led-power-white {
- label = "bcm53xx:white:power";
- gpios = <&chipcommon 1 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- power-amber {
-+ led-power-amber {
- label = "bcm53xx:amber:power";
- gpios = <&chipcommon 2 GPIO_ACTIVE_HIGH>;
- };
-
-- usb2 {
-+ led-usb2 {
- label = "bcm53xx:white:usb2";
- gpios = <&chipcommon 3 GPIO_ACTIVE_HIGH>;
- trigger-sources = <&ohci_port2>, <&ehci_port2>;
- linux,default-trigger = "usbport";
- };
-
-- usb3-white {
-+ led-usb3-white {
- label = "bcm53xx:white:usb3";
- gpios = <&chipcommon 4 GPIO_ACTIVE_HIGH>;
- trigger-sources = <&xhci_port1>;
- linux,default-trigger = "usbport";
- };
-
-- usb3-green {
-+ led-usb3-green {
- label = "bcm53xx:green:usb3";
- gpios = <&chipcommon 5 GPIO_ACTIVE_HIGH>;
- trigger-sources = <&ohci_port1>, <&ehci_port1>;
- linux,default-trigger = "usbport";
- };
-
-- wps {
-+ led-wps {
- label = "bcm53xx:white:wps";
- gpios = <&chipcommon 6 GPIO_ACTIVE_HIGH>;
- };
-
-- status-red {
-+ led-status-red {
- label = "bcm53xx:red:status";
- gpios = <&chipcommon 8 GPIO_ACTIVE_HIGH>;
- };
-
-- status-green {
-+ led-status-green {
- label = "bcm53xx:green:status";
- gpios = <&chipcommon 9 GPIO_ACTIVE_HIGH>;
- };
-
-- status-blue {
-+ led-status-blue {
- label = "bcm53xx:blue:status";
- gpios = <&chipcommon 10 GPIO_ACTIVE_HIGH>;
- };
-
-- wan-white {
-+ led-wan-white {
- label = "bcm53xx:white:wan";
- gpios = <&chipcommon 12 GPIO_ACTIVE_HIGH>;
- };
-
-- wan-red {
-+ led-wan-red {
- label = "bcm53xx:red:wan";
- gpios = <&chipcommon 13 GPIO_ACTIVE_HIGH>;
- };
---- a/arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts
-+++ b/arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts
-@@ -28,30 +28,30 @@
- leds {
- compatible = "gpio-leds";
-
-- power {
-+ led-power {
- label = "bcm53xx:blue:power";
- gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- usb2 {
-+ led-usb2 {
- label = "bcm53xx:blue:usb2";
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- };
-
-- wan {
-+ led-wan {
- label = "bcm53xx:blue:wan";
- gpios = <&chipcommon 6 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- lan {
-+ led-lan {
- label = "bcm53xx:blue:lan";
- gpios = <&chipcommon 9 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- usb3 {
-+ led-usb3 {
- label = "bcm53xx:blue:usb3";
- gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
- };
---- a/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
-+++ b/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
-@@ -49,40 +49,40 @@
- leds {
- compatible = "gpio-leds";
-
-- power0 {
-+ led-power0 {
- label = "bcm53xx:green:power";
- gpios = <&hc595 1 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- power1 {
-+ led-power1 {
- label = "bcm53xx:red:power";
- gpios = <&hc595 2 GPIO_ACTIVE_HIGH>;
- };
-
-- router0 {
-+ led-router0 {
- label = "bcm53xx:green:router";
- gpios = <&hc595 3 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- router1 {
-+ led-router1 {
- label = "bcm53xx:amber:router";
- gpios = <&hc595 4 GPIO_ACTIVE_HIGH>;
- };
-
-- wan {
-+ led-wan {
- label = "bcm53xx:green:wan";
- gpios = <&hc595 5 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- wireless0 {
-+ led-wireless0 {
- label = "bcm53xx:green:wireless";
- gpios = <&hc595 6 GPIO_ACTIVE_HIGH>;
- };
-
-- wireless1 {
-+ led-wireless1 {
- label = "bcm53xx:amber:wireless";
- gpios = <&hc595 7 GPIO_ACTIVE_HIGH>;
- };
---- a/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts
-+++ b/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts
-@@ -49,45 +49,45 @@
- leds {
- compatible = "gpio-leds";
-
-- usb {
-+ led-usb {
- label = "bcm53xx:green:usb";
- gpios = <&hc595 0 GPIO_ACTIVE_HIGH>;
- };
-
-- power0 {
-+ led-power0 {
- label = "bcm53xx:green:power";
- gpios = <&hc595 1 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- power1 {
-+ led-power1 {
- label = "bcm53xx:red:power";
- gpios = <&hc595 2 GPIO_ACTIVE_HIGH>;
- };
-
-- router0 {
-+ led-router0 {
- label = "bcm53xx:green:router";
- gpios = <&hc595 3 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- router1 {
-+ led-router1 {
- label = "bcm53xx:amber:router";
- gpios = <&hc595 4 GPIO_ACTIVE_HIGH>;
- };
-
-- wan {
-+ led-wan {
- label = "bcm53xx:green:wan";
- gpios = <&hc595 5 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- wireless0 {
-+ led-wireless0 {
- label = "bcm53xx:green:wireless";
- gpios = <&hc595 6 GPIO_ACTIVE_HIGH>;
- };
-
-- wireless1 {
-+ led-wireless1 {
- label = "bcm53xx:amber:wireless";
- gpios = <&hc595 7 GPIO_ACTIVE_HIGH>;
- };
---- a/arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts
-+++ b/arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts
-@@ -23,19 +23,19 @@
- leds {
- compatible = "gpio-leds";
-
-- 5ghz {
-+ led-5ghz {
- label = "bcm53xx:blue:5ghz";
- gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "none";
- };
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:blue:2ghz";
- gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "none";
- };
-
-- status {
-+ led-status {
- label = "bcm53xx:green:status";
- gpios = <&chipcommon 15 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "timer";
---- a/arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts
-+++ b/arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts
-@@ -29,62 +29,62 @@
- leds {
- compatible = "gpio-leds";
-
-- power {
-+ led-power {
- label = "bcm53xx:green:power";
- gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- lan3 {
-+ led-lan3 {
- label = "bcm53xx:green:lan3";
- gpios = <&chipcommon 1 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "none";
- };
-
-- lan4 {
-+ led-lan4 {
- label = "bcm53xx:green:lan4";
- gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "none";
- };
-
-- wan {
-+ led-wan {
- label = "bcm53xx:green:wan";
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "none";
- };
-
-- lan2 {
-+ led-lan2 {
- label = "bcm53xx:green:lan2";
- gpios = <&chipcommon 6 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "none";
- };
-
-- usb {
-+ led-usb {
- label = "bcm53xx:green:usb";
- gpios = <&chipcommon 8 GPIO_ACTIVE_LOW>;
- trigger-sources = <&ohci_port2>, <&ehci_port2>;
- linux,default-trigger = "usbport";
- };
-
-- status {
-+ led-status {
- label = "bcm53xx:green:status";
- gpios = <&chipcommon 10 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "timer";
- };
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:green:2ghz";
- gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "none";
- };
-
-- 5ghz {
-+ led-5ghz {
- label = "bcm53xx:green:5ghz";
- gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "none";
- };
-
-- lan1 {
-+ led-lan1 {
- label = "bcm53xx:green:lan1";
- gpios = <&chipcommon 15 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "none";
---- a/arch/arm/boot/dts/bcm47081-tplink-archer-c5-v2.dts
-+++ b/arch/arm/boot/dts/bcm47081-tplink-archer-c5-v2.dts
-@@ -23,50 +23,50 @@
- leds {
- compatible = "gpio-leds";
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:green:2ghz";
- gpios = <&chipcommon 0 GPIO_ACTIVE_HIGH>;
- };
-
-- lan {
-+ led-lan {
- label = "bcm53xx:green:lan";
- gpios = <&chipcommon 1 GPIO_ACTIVE_HIGH>;
- };
-
-- usb2-port1 {
-+ led-usb2-port1 {
- label = "bcm53xx:green:usb2-port1";
- gpios = <&chipcommon 2 GPIO_ACTIVE_HIGH>;
- trigger-sources = <&ohci_port1>, <&ehci_port1>;
- linux,default-trigger = "usbport";
- };
-
-- power {
-+ led-power {
- label = "bcm53xx:green:power";
- gpios = <&chipcommon 4 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- wan-green {
-+ led-wan-green {
- label = "bcm53xx:green:wan";
- gpios = <&chipcommon 5 GPIO_ACTIVE_HIGH>;
- };
-
-- wps {
-+ led-wps {
- label = "bcm53xx:green:wps";
- gpios = <&chipcommon 6 GPIO_ACTIVE_HIGH>;
- };
-
-- wan-amber {
-+ led-wan-amber {
- label = "bcm53xx:amber:wan";
- gpios = <&chipcommon 8 GPIO_ACTIVE_HIGH>;
- };
-
-- 5ghz {
-+ led-5ghz {
- label = "bcm53xx:green:5ghz";
- gpios = <&chipcommon 12 GPIO_ACTIVE_HIGH>;
- };
-
-- usb2-port2 {
-+ led-usb2-port2 {
- label = "bcm53xx:green:usb2-port2";
- gpios = <&chipcommon 13 GPIO_ACTIVE_HIGH>;
- trigger-sources = <&ohci_port2>, <&ehci_port2>;
---- a/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts
-+++ b/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts
-@@ -28,18 +28,18 @@
- leds {
- compatible = "gpio-leds";
-
-- wps {
-+ led-wps {
- label = "bcm53xx:blue:wps";
- gpios = <&chipcommon 1 GPIO_ACTIVE_LOW>;
- };
-
-- power {
-+ led-power {
- label = "bcm53xx:blue:power";
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- wan {
-+ led-wan {
- label = "bcm53xx:red:wan";
- gpios = <&chipcommon 5 GPIO_ACTIVE_LOW>;
- };
---- a/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts
-+++ b/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts
-@@ -28,48 +28,48 @@
- leds {
- compatible = "gpio-leds";
-
-- usb {
-+ led-usb {
- label = "bcm53xx:green:usb";
- gpios = <&chipcommon 4 GPIO_ACTIVE_HIGH>;
- };
-
-- power-amber {
-+ led-power-amber {
- label = "bcm53xx:amber:power";
- gpios = <&chipcommon 5 GPIO_ACTIVE_HIGH>;
- };
-
-- power-white {
-+ led-power-white {
- label = "bcm53xx:white:power";
- gpios = <&chipcommon 6 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- router-amber {
-+ led-router-amber {
- label = "bcm53xx:amber:router";
- gpios = <&chipcommon 7 GPIO_ACTIVE_HIGH>;
- };
-
-- router-white {
-+ led-router-white {
- label = "bcm53xx:white:router";
- gpios = <&chipcommon 8 GPIO_ACTIVE_HIGH>;
- };
-
-- wan-amber {
-+ led-wan-amber {
- label = "bcm53xx:amber:wan";
- gpios = <&chipcommon 9 GPIO_ACTIVE_HIGH>;
- };
-
-- wan-white {
-+ led-wan-white {
- label = "bcm53xx:white:wan";
- gpios = <&chipcommon 10 GPIO_ACTIVE_HIGH>;
- };
-
-- wireless-amber {
-+ led-wireless-amber {
- label = "bcm53xx:amber:wireless";
- gpios = <&chipcommon 11 GPIO_ACTIVE_HIGH>;
- };
-
-- wireless-white {
-+ led-wireless-white {
- label = "bcm53xx:white:wireless";
- gpios = <&chipcommon 12 GPIO_ACTIVE_HIGH>;
- };
---- a/arch/arm/boot/dts/bcm4709-netgear-r7000.dts
-+++ b/arch/arm/boot/dts/bcm4709-netgear-r7000.dts
-@@ -28,43 +28,43 @@
- leds {
- compatible = "gpio-leds";
-
-- power-white {
-+ led-power-white {
- label = "bcm53xx:white:power";
- gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- power-amber {
-+ led-power-amber {
- label = "bcm53xx:amber:power";
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- };
-
-- 5ghz {
-+ led-5ghz {
- label = "bcm53xx:white:5ghz";
- gpios = <&chipcommon 12 GPIO_ACTIVE_LOW>;
- };
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:white:2ghz";
- gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
- };
-
-- wps {
-+ led-wps {
- label = "bcm53xx:white:wps";
- gpios = <&chipcommon 14 GPIO_ACTIVE_HIGH>;
- };
-
-- wireless {
-+ led-wireless {
- label = "bcm53xx:white:wireless";
- gpios = <&chipcommon 15 GPIO_ACTIVE_HIGH>;
- };
-
-- usb3 {
-+ led-usb3 {
- label = "bcm53xx:white:usb3";
- gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>;
- };
-
-- usb2 {
-+ led-usb2 {
- label = "bcm53xx:white:usb2";
- gpios = <&chipcommon 18 GPIO_ACTIVE_LOW>;
- };
---- a/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
-+++ b/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
-@@ -39,59 +39,59 @@
- leds {
- compatible = "gpio-leds";
-
-- power-white {
-+ led-power-white {
- label = "bcm53xx:white:power";
- gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- power-amber {
-+ led-power-amber {
- label = "bcm53xx:amber:power";
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- };
-
-- wan-white {
-+ led-wan-white {
- label = "bcm53xx:white:wan";
- gpios = <&chipcommon 8 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- wan-amber {
-+ led-wan-amber {
- label = "bcm53xx:amber:wan";
- gpios = <&chipcommon 9 GPIO_ACTIVE_HIGH>;
- };
-
-- 5ghz-1 {
-+ led-5ghz-1 {
- label = "bcm53xx:white:5ghz-1";
- gpios = <&chipcommon 12 GPIO_ACTIVE_LOW>;
- };
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:white:2ghz";
- gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
- };
-
-- wireless {
-+ led-wireless {
- label = "bcm53xx:white:wireless";
- gpios = <&chipcommon 14 GPIO_ACTIVE_HIGH>;
- };
-
-- wps {
-+ led-wps {
- label = "bcm53xx:white:wps";
- gpios = <&chipcommon 15 GPIO_ACTIVE_HIGH>;
- };
-
-- 5ghz-2 {
-+ led-5ghz-2 {
- label = "bcm53xx:white:5ghz-2";
- gpios = <&chipcommon 16 GPIO_ACTIVE_LOW>;
- };
-
-- usb3 {
-+ led-usb3 {
- label = "bcm53xx:white:usb3";
- gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>;
- };
-
-- usb2 {
-+ led-usb2 {
- label = "bcm53xx:white:usb2";
- gpios = <&chipcommon 18 GPIO_ACTIVE_LOW>;
- };
---- a/arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts
-+++ b/arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts
-@@ -23,27 +23,27 @@
- leds {
- compatible = "gpio-leds";
-
-- lan {
-+ led-lan {
- label = "bcm53xx:blue:lan";
- gpios = <&chipcommon 1 GPIO_ACTIVE_HIGH>;
- };
-
-- wps {
-+ led-wps {
- label = "bcm53xx:blue:wps";
- gpios = <&chipcommon 2 GPIO_ACTIVE_HIGH>;
- };
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:blue:2ghz";
- gpios = <&chipcommon 4 GPIO_ACTIVE_HIGH>;
- };
-
-- 5ghz {
-+ led-5ghz {
- label = "bcm53xx:blue:5ghz";
- gpios = <&chipcommon 5 GPIO_ACTIVE_HIGH>;
- };
-
-- usb3 {
-+ led-usb3 {
- label = "bcm53xx:blue:usb3";
- gpios = <&chipcommon 6 GPIO_ACTIVE_HIGH>;
- trigger-sources = <&ohci_port1>, <&ehci_port1>,
-@@ -51,24 +51,24 @@
- linux,default-trigger = "usbport";
- };
-
-- usb2 {
-+ led-usb2 {
- label = "bcm53xx:blue:usb2";
- gpios = <&chipcommon 7 GPIO_ACTIVE_HIGH>;
- trigger-sources = <&ohci_port2>, <&ehci_port2>;
- linux,default-trigger = "usbport";
- };
-
-- wan-blue {
-+ led-wan-blue {
- label = "bcm53xx:blue:wan";
- gpios = <&chipcommon 14 GPIO_ACTIVE_HIGH>;
- };
-
-- wan-amber {
-+ led-wan-amber {
- label = "bcm53xx:amber:wan";
- gpios = <&chipcommon 15 GPIO_ACTIVE_HIGH>;
- };
-
-- power {
-+ led-power {
- label = "bcm53xx:blue:power";
- gpios = <&chipcommon 18 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
---- a/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-+++ b/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-@@ -33,37 +33,37 @@
- leds {
- compatible = "gpio-leds";
-
-- power {
-+ led-power {
- label = "white:power";
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- wan-red {
-+ led-wan-red {
- label = "red:wan";
- gpios = <&chipcommon 5 GPIO_ACTIVE_HIGH>;
- };
-
-- lan {
-+ led-lan {
- label = "white:lan";
- gpios = <&chipcommon 21 GPIO_ACTIVE_LOW>;
- };
-
-- usb2 {
-+ led-usb2 {
- label = "white:usb2";
- gpios = <&chipcommon 16 GPIO_ACTIVE_LOW>;
- trigger-sources = <&ehci_port2>;
- linux,default-trigger = "usbport";
- };
-
-- usb3 {
-+ led-usb3 {
- label = "white:usb3";
- gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>;
- trigger-sources = <&ehci_port1>, <&xhci_port1>;
- linux,default-trigger = "usbport";
- };
-
-- wps {
-+ led-wps {
- label = "white:wps";
- gpios = <&chipcommon 19 GPIO_ACTIVE_LOW>;
- };
---- a/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts
-+++ b/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts
-@@ -43,28 +43,28 @@
- leds {
- compatible = "gpio-leds";
-
-- power-white {
-+ led-power-white {
- label = "bcm53xx:white:power";
- gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- wan-white {
-+ led-wan-white {
- label = "bcm53xx:white:wan";
- gpios = <&chipcommon 1 GPIO_ACTIVE_LOW>;
- };
-
-- power-amber {
-+ led-power-amber {
- label = "bcm53xx:amber:power";
- gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>;
- };
-
-- wan-amber {
-+ led-wan-amber {
- label = "bcm53xx:amber:wan";
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- };
-
-- usb3-white {
-+ led-usb3-white {
- label = "bcm53xx:white:usb3";
- gpios = <&chipcommon 8 GPIO_ACTIVE_LOW>;
- trigger-sources = <&ohci_port1>, <&ehci_port1>,
-@@ -72,12 +72,12 @@
- linux,default-trigger = "usbport";
- };
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:white:2ghz";
- gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
- };
-
-- 5ghz {
-+ led-5ghz {
- label = "bcm53xx:white:5ghz";
- gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
- };
---- a/arch/arm/boot/dts/bcm47094-dlink-dir-890l.dts
-+++ b/arch/arm/boot/dts/bcm47094-dlink-dir-890l.dts
-@@ -41,47 +41,47 @@
- */
- compatible = "gpio-leds";
-
-- power-white {
-+ led-power-white {
- label = "bcm53xx:white:power";
- gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- wan-white {
-+ led-wan-white {
- label = "bcm53xx:white:wan";
- gpios = <&chipcommon 1 GPIO_ACTIVE_LOW>;
- };
-
-- power-amber {
-+ led-power-amber {
- label = "bcm53xx:amber:power";
- gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>;
- };
-
-- wan-amber {
-+ led-wan-amber {
- label = "bcm53xx:amber:wan";
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- };
-
-- usb3-white {
-+ led-usb3-white {
- label = "bcm53xx:white:usb3";
- gpios = <&chipcommon 8 GPIO_ACTIVE_LOW>;
- trigger-sources = <&xhci_port1>;
- linux,default-trigger = "usbport";
- };
-
-- usb2-white {
-+ led-usb2-white {
- label = "bcm53xx:white:usb2";
- gpios = <&chipcommon 15 GPIO_ACTIVE_LOW>;
- trigger-sources = <&ohci_port1>, <&ehci_port1>;
- linux,default-trigger = "usbport";
- };
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:white:2ghz";
- gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
- };
-
-- 5ghz {
-+ led-5ghz {
- label = "bcm53xx:white:5ghz";
- gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
- };
---- a/arch/arm/boot/dts/bcm47094-linksys-panamera.dts
-+++ b/arch/arm/boot/dts/bcm47094-linksys-panamera.dts
-@@ -52,19 +52,19 @@
- leds {
- compatible = "gpio-leds";
-
-- wps {
-+ led-wps {
- label = "bcm53xx:white:wps";
- gpios = <&chipcommon 22 GPIO_ACTIVE_LOW>;
- };
-
-- usb2 {
-+ led-usb2 {
- label = "bcm53xx:green:usb2";
- gpios = <&chipcommon 1 GPIO_ACTIVE_LOW>;
- trigger-sources = <&ohci_port2>, <&ehci_port2>;
- linux,default-trigger = "usbport";
- };
-
-- usb3 {
-+ led-usb3 {
- label = "bcm53xx:green:usb3";
- gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>;
- trigger-sources = <&ohci_port1>, <&ehci_port1>,
-@@ -72,58 +72,58 @@
- linux,default-trigger = "usbport";
- };
-
-- power {
-+ led-power {
- label = "bcm53xx:white:power";
- gpios = <&chipcommon 4 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- wifi-disabled {
-+ led-wifi-disabled {
- label = "bcm53xx:amber:wifi-disabled";
- gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
- };
-
-- wifi-enabled {
-+ led-wifi-enabled {
- label = "bcm53xx:white:wifi-enabled";
- gpios = <&chipcommon 5 GPIO_ACTIVE_HIGH>;
- };
-
-- bluebar1 {
-+ led-bluebar1 {
- label = "bcm53xx:white:bluebar1";
- gpios = <&chipcommon 11 GPIO_ACTIVE_HIGH>;
- };
-
-- bluebar2 {
-+ led-bluebar2 {
- label = "bcm53xx:white:bluebar2";
- gpios = <&chipcommon 12 GPIO_ACTIVE_HIGH>;
- };
-
-- bluebar3 {
-+ led-bluebar3 {
- label = "bcm53xx:white:bluebar3";
- gpios = <&chipcommon 15 GPIO_ACTIVE_LOW>;
- };
-
-- bluebar4 {
-+ led-bluebar4 {
- label = "bcm53xx:white:bluebar4";
- gpios = <&chipcommon 18 GPIO_ACTIVE_HIGH>;
- };
-
-- bluebar5 {
-+ led-bluebar5 {
- label = "bcm53xx:white:bluebar5";
- gpios = <&chipcommon 19 GPIO_ACTIVE_HIGH>;
- };
-
-- bluebar6 {
-+ led-bluebar6 {
- label = "bcm53xx:white:bluebar6";
- gpios = <&chipcommon 20 GPIO_ACTIVE_HIGH>;
- };
-
-- bluebar7 {
-+ led-bluebar7 {
- label = "bcm53xx:white:bluebar7";
- gpios = <&chipcommon 21 GPIO_ACTIVE_HIGH>;
- };
-
-- bluebar8 {
-+ led-bluebar8 {
- label = "bcm53xx:white:bluebar8";
- gpios = <&chipcommon 8 GPIO_ACTIVE_HIGH>;
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts
-@@ -30,13 +30,13 @@
- leds {
- compatible = "gpio-leds";
-
-- status {
-+ led-status {
- label = "bcm53xx:green:status";
- gpios = <&chipcommon 20 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "timer";
- };
-
-- usb3 {
-+ led-usb3 {
- label = "bcm53xx:green:usb3";
- gpios = <&chipcommon 19 GPIO_ACTIVE_LOW>;
- trigger-sources = <&ohci_port1>, <&ehci_port1>,
---- a/arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts
-@@ -23,18 +23,18 @@
- leds {
- compatible = "gpio-leds";
-
-- status {
-+ led-status {
- label = "bcm53xx:green:status";
- gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "timer";
- };
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:blue:2ghz";
- gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
- };
-
-- 5ghz {
-+ led-5ghz {
- label = "bcm53xx:blue:5ghz";
- gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts
-@@ -30,13 +30,13 @@
- leds {
- compatible = "gpio-leds";
-
-- status {
-+ led-status {
- label = "bcm53xx:green:status";
- gpios = <&chipcommon 20 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "timer";
- };
-
-- usb3 {
-+ led-usb3 {
- label = "bcm53xx:green:usb3";
- gpios = <&chipcommon 19 GPIO_ACTIVE_HIGH>;
- trigger-sources = <&ohci_port1>, <&ehci_port1>,
---- a/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts
-@@ -25,7 +25,7 @@
- leds {
- compatible = "gpio-leds";
-
-- status {
-+ led-status {
- label = "bcm53xx:green:status";
- gpios = <&chipcommon 18 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "timer";
---- a/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts
-@@ -30,38 +30,38 @@
- leds {
- compatible = "gpio-leds";
-
-- power {
-+ led-power {
- label = "bcm53xx:green:power";
- gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- lan3 {
-+ led-lan3 {
- label = "bcm53xx:green:lan3";
- gpios = <&chipcommon 1 GPIO_ACTIVE_LOW>;
- };
-
-- lan4 {
-+ led-lan4 {
- label = "bcm53xx:green:lan4";
- gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>;
- };
-
-- wan {
-+ led-wan {
- label = "bcm53xx:green:wan";
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- };
-
-- lan1 {
-+ led-lan1 {
- label = "bcm53xx:green:lan1";
- gpios = <&chipcommon 4 GPIO_ACTIVE_LOW>;
- };
-
-- lan2 {
-+ led-lan2 {
- label = "bcm53xx:green:lan2";
- gpios = <&chipcommon 6 GPIO_ACTIVE_LOW>;
- };
-
-- usb3 {
-+ led-usb3 {
- label = "bcm53xx:green:usb3";
- gpios = <&chipcommon 8 GPIO_ACTIVE_LOW>;
- trigger-sources = <&ohci_port1>, <&ehci_port1>,
-@@ -69,18 +69,18 @@
- linux,default-trigger = "usbport";
- };
-
-- status {
-+ led-status {
- label = "bcm53xx:green:status";
- gpios = <&chipcommon 10 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "timer";
- };
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:green:2ghz";
- gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
- };
-
-- 5ghz {
-+ led-5ghz {
- label = "bcm53xx:green:5ghz";
- gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
-@@ -33,13 +33,13 @@
- leds {
- compatible = "gpio-leds";
-
-- power {
-+ led-power {
- label = "bcm53xx:green:power";
- gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- usb3 {
-+ led-usb3 {
- label = "bcm53xx:green:usb3";
- gpios = <&chipcommon 8 GPIO_ACTIVE_LOW>;
- trigger-sources = <&ohci_port1>, <&ehci_port1>,
-@@ -47,18 +47,18 @@
- linux,default-trigger = "usbport";
- };
-
-- status {
-+ led-status {
- label = "bcm53xx:green:status";
- gpios = <&chipcommon 10 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "timer";
- };
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:green:2ghz";
- gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
- };
-
-- 5ghz {
-+ led-5ghz {
- label = "bcm53xx:green:5ghz";
- gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
- };
---- a/arch/arm/boot/dts/bcm47094-netgear-r8500.dts
-+++ b/arch/arm/boot/dts/bcm47094-netgear-r8500.dts
-@@ -25,38 +25,38 @@
- leds {
- compatible = "gpio-leds";
-
-- power0 {
-+ led-power0 {
- label = "bcm53xx:white:power";
- gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- power1 {
-+ led-power1 {
- label = "bcm53xx:amber:power";
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- };
-
-- 5ghz-1 {
-+ led-5ghz-1 {
- label = "bcm53xx:white:5ghz-1";
- gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
- };
-
-- 5ghz-2 {
-+ led-5ghz-2 {
- label = "bcm53xx:white:5ghz-2";
- gpios = <&chipcommon 12 GPIO_ACTIVE_LOW>;
- };
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:white:2ghz";
- gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
- };
-
-- usb2 {
-+ led-usb2 {
- label = "bcm53xx:white:usb2";
- gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>;
- };
-
-- usb3 {
-+ led-usb3 {
- label = "bcm53xx:white:usb3";
- gpios = <&chipcommon 18 GPIO_ACTIVE_LOW>;
- };
---- a/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts
-+++ b/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts
-@@ -23,12 +23,12 @@
- leds {
- compatible = "gpio-leds";
-
-- wlan {
-+ led-wlan {
- label = "bcm53xx:blue:wlan";
- gpios = <&chipcommon 10 GPIO_ACTIVE_LOW>;
- };
-
-- system {
-+ led-system {
- label = "bcm53xx:green:system";
- gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "timer";
---- a/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts
-+++ b/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts
-@@ -20,25 +20,25 @@
- reg = <0x00000000 0x08000000>;
- };
-
-- leds {
-+ leds-0 {
- compatible = "gpio-leds";
-
-- 5ghz {
-+ led-5ghz {
- label = "bcm53xx:blue:5ghz";
- gpios = <&chipcommon 11 GPIO_ACTIVE_HIGH>;
- };
-
-- system {
-+ led-system {
- label = "bcm53xx:green:system";
- gpios = <&chipcommon 15 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "timer";
- };
- };
-
-- pcie0_leds {
-+ leds-1 {
- compatible = "gpio-leds";
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:blue:2ghz";
- gpios = <&pcie0_chipcommon 3 GPIO_ACTIVE_HIGH>;
- };
---- a/arch/arm/boot/dts/bcm47189-tenda-ac9.dts
-+++ b/arch/arm/boot/dts/bcm47189-tenda-ac9.dts
-@@ -20,37 +20,37 @@
- reg = <0x00000000 0x08000000>;
- };
-
-- leds {
-+ leds-0 {
- compatible = "gpio-leds";
-
-- usb {
-+ led-usb {
- label = "bcm53xx:blue:usb";
- gpios = <&chipcommon 1 GPIO_ACTIVE_HIGH>;
- trigger-sources = <&ohci_port1>, <&ehci_port1>;
- linux,default-trigger = "usbport";
- };
-
-- wps {
-+ led-wps {
- label = "bcm53xx:blue:wps";
- gpios = <&chipcommon 10 GPIO_ACTIVE_HIGH>;
- };
-
-- 5ghz {
-+ led-5ghz {
- label = "bcm53xx:blue:5ghz";
- gpios = <&chipcommon 11 GPIO_ACTIVE_HIGH>;
- };
-
-- system {
-+ led-system {
- label = "bcm53xx:blue:system";
- gpios = <&chipcommon 15 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "timer";
- };
- };
-
-- pcie0_leds {
-+ leds-1 {
- compatible = "gpio-leds";
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:blue:2ghz";
- gpios = <&pcie0_chipcommon 3 GPIO_ACTIVE_HIGH>;
- };
---- a/arch/arm/boot/dts/bcm53016-dlink-dwl-8610ap.dts
-+++ b/arch/arm/boot/dts/bcm53016-dlink-dwl-8610ap.dts
-@@ -20,14 +20,14 @@
- leds {
- compatible = "gpio-leds";
-
-- power {
-+ led-power {
- function = LED_FUNCTION_POWER;
- color = <LED_COLOR_ID_GREEN>;
- gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
- default-state = "on";
- };
-
-- diag {
-+ led-diag {
- /* Actually "diag" unclear what this means */
- function = LED_FUNCTION_INDICATOR;
- color = <LED_COLOR_ID_RED>;
-@@ -36,13 +36,13 @@
- linux,default-trigger = "heartbeat";
- };
-
-- wlan-2g {
-+ led-wlan-2g {
- function = LED_FUNCTION_WLAN;
- color = <LED_COLOR_ID_GREEN>;
- gpios = <&chipcommon 5 GPIO_ACTIVE_LOW>;
- };
-
-- wlan-5g {
-+ led-wlan-5g {
- function = LED_FUNCTION_WLAN;
- color = <LED_COLOR_ID_GREEN>;
- gpios = <&chipcommon 8 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-+++ b/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-@@ -58,7 +58,7 @@
- pwm-leds {
- compatible = "pwm-leds";
-
-- red {
-+ led-0 {
- /* SYS-LED 1 - Tricolor */
- function = LED_FUNCTION_INDICATOR;
- color = <LED_COLOR_ID_RED>;
-@@ -66,7 +66,7 @@
- max-brightness = <255>;
- };
-
-- green {
-+ led-1 {
- /* SYS-LED 1 - Tricolor */
- function = LED_FUNCTION_POWER;
- color = <LED_COLOR_ID_GREEN>;
-@@ -74,7 +74,7 @@
- max-brightness = <255>;
- };
-
-- blue {
-+ led-2 {
- /* SYS-LED 1 - Tricolor */
- function = LED_FUNCTION_INDICATOR;
- color = <LED_COLOR_ID_BLUE>;
---- a/arch/arm/boot/dts/bcm947189acdbmr.dts
-+++ b/arch/arm/boot/dts/bcm947189acdbmr.dts
-@@ -25,17 +25,17 @@
- leds {
- compatible = "gpio-leds";
-
-- wps {
-+ led-wps {
- label = "bcm53xx:blue:wps";
- gpios = <&chipcommon 10 GPIO_ACTIVE_HIGH>;
- };
-
-- 5ghz {
-+ led-5ghz {
- label = "bcm53xx:blue:5ghz";
- gpios = <&chipcommon 11 GPIO_ACTIVE_HIGH>;
- };
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:blue:2ghz";
- gpios = <&chipcommon 12 GPIO_ACTIVE_HIGH>;
- };
diff --git a/target/linux/bcm53xx/patches-5.15/036-v6.5-0001-ARM-dts-BCM5301X-Relicense-Rafa-s-code-to-the-GPL-2..patch b/target/linux/bcm53xx/patches-5.15/036-v6.5-0001-ARM-dts-BCM5301X-Relicense-Rafa-s-code-to-the-GPL-2..patch
deleted file mode 100644
index 3bb39dfd50..0000000000
--- a/target/linux/bcm53xx/patches-5.15/036-v6.5-0001-ARM-dts-BCM5301X-Relicense-Rafa-s-code-to-the-GPL-2..patch
+++ /dev/null
@@ -1,487 +0,0 @@
-From 915fac07f053418d0ab9075af64da2872ca8a7f8 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Wed, 3 May 2023 14:16:10 +0200
-Subject: [PATCH] =?UTF-8?q?ARM:=20dts:=20BCM5301X:=20Relicense=20Rafa?=
- =?UTF-8?q?=C5=82's=20code=20to=20the=20GPL=202.0+=20/=20MIT?=
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-All BCM5301X device DTS files use dual licensing. Try the same for SoC.
-Introduce a new .dtsi file with a proper SPDX tag.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230503121611.1629-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- MAINTAINERS | 1 +
- arch/arm/boot/dts/bcm-ns.dtsi | 202 ++++++++++++++++++++++++++++++++
- arch/arm/boot/dts/bcm5301x.dtsi | 192 +-----------------------------
- 3 files changed, 205 insertions(+), 190 deletions(-)
- create mode 100644 arch/arm/boot/dts/bcm-ns.dtsi
-
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -3579,6 +3579,7 @@ M: Rafał Miłecki <zajec5@gmail.com>
- M: bcm-kernel-feedback-list@broadcom.com
- L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
- S: Maintained
-+F: arch/arm/boot/dts/bcm-ns.dtsi
- F: arch/arm/boot/dts/bcm470*
- F: arch/arm/boot/dts/bcm5301*
- F: arch/arm/boot/dts/bcm953012*
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm-ns.dtsi
-@@ -0,0 +1,202 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-+
-+#include <dt-bindings/clock/bcm-nsp.h>
-+#include <dt-bindings/gpio/gpio.h>
-+#include <dt-bindings/input/input.h>
-+#include <dt-bindings/interrupt-controller/irq.h>
-+#include <dt-bindings/interrupt-controller/arm-gic.h>
-+
-+/ {
-+ axi@18000000 {
-+ compatible = "brcm,bus-axi";
-+ reg = <0x18000000 0x1000>;
-+ ranges = <0x00000000 0x18000000 0x00100000>;
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ chipcommon: chipcommon@0 {
-+ reg = <0x00000000 0x1000>;
-+
-+ gpio-controller;
-+ #gpio-cells = <2>;
-+ };
-+
-+ pcie0: pcie@12000 {
-+ reg = <0x00012000 0x1000>;
-+ };
-+
-+ pcie1: pcie@13000 {
-+ reg = <0x00013000 0x1000>;
-+ };
-+
-+ usb2: usb2@21000 {
-+ reg = <0x00021000 0x1000>;
-+
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+ ranges;
-+
-+ interrupt-parent = <&gic>;
-+
-+ ehci: usb@21000 {
-+ #usb-cells = <0>;
-+
-+ compatible = "generic-ehci";
-+ reg = <0x00021000 0x1000>;
-+ interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
-+ phys = <&usb2_phy>;
-+
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ ehci_port1: port@1 {
-+ reg = <1>;
-+ #trigger-source-cells = <0>;
-+ };
-+
-+ ehci_port2: port@2 {
-+ reg = <2>;
-+ #trigger-source-cells = <0>;
-+ };
-+ };
-+
-+ ohci: usb@22000 {
-+ #usb-cells = <0>;
-+
-+ compatible = "generic-ohci";
-+ reg = <0x00022000 0x1000>;
-+ interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
-+
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ ohci_port1: port@1 {
-+ reg = <1>;
-+ #trigger-source-cells = <0>;
-+ };
-+
-+ ohci_port2: port@2 {
-+ reg = <2>;
-+ #trigger-source-cells = <0>;
-+ };
-+ };
-+ };
-+
-+ usb3: usb3@23000 {
-+ reg = <0x00023000 0x1000>;
-+
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+ ranges;
-+
-+ interrupt-parent = <&gic>;
-+
-+ xhci: usb@23000 {
-+ #usb-cells = <0>;
-+
-+ compatible = "generic-xhci";
-+ reg = <0x00023000 0x1000>;
-+ interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
-+ phys = <&usb3_phy>;
-+ phy-names = "usb";
-+
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ xhci_port1: port@1 {
-+ reg = <1>;
-+ #trigger-source-cells = <0>;
-+ };
-+ };
-+ };
-+ };
-+
-+ mdio: mdio@18003000 {
-+ compatible = "brcm,iproc-mdio";
-+ reg = <0x18003000 0x8>;
-+ #size-cells = <0>;
-+ #address-cells = <1>;
-+ };
-+
-+ dmu-bus@1800c000 {
-+ compatible = "simple-bus";
-+ ranges = <0 0x1800c000 0x1000>;
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ cru-bus@100 {
-+ compatible = "brcm,ns-cru", "simple-mfd";
-+ reg = <0x100 0x1a4>;
-+ ranges;
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ usb2_phy: phy@164 {
-+ compatible = "brcm,ns-usb2-phy";
-+ reg = <0x164 0x4>;
-+ brcm,syscon-clkset = <&cru_clkset>;
-+ clocks = <&genpll BCM_NSP_GENPLL_USB_PHY_REF_CLK>;
-+ clock-names = "phy-ref-clk";
-+ #phy-cells = <0>;
-+ };
-+
-+ cru_clkset: syscon@180 {
-+ compatible = "brcm,cru-clkset", "syscon";
-+ reg = <0x180 0x4>;
-+ };
-+
-+ pinctrl: pinctrl@1c0 {
-+ compatible = "brcm,bcm4708-pinmux";
-+ reg = <0x1c0 0x24>;
-+ reg-names = "cru_gpio_control";
-+
-+ spi-pins {
-+ groups = "spi_grp";
-+ function = "spi";
-+ };
-+
-+ pinmux_i2c: i2c-pins {
-+ groups = "i2c_grp";
-+ function = "i2c";
-+ };
-+
-+ pinmux_pwm: pwm-pins {
-+ groups = "pwm0_grp", "pwm1_grp",
-+ "pwm2_grp", "pwm3_grp";
-+ function = "pwm";
-+ };
-+
-+ pinmux_uart1: uart1-pins {
-+ groups = "uart1_grp";
-+ function = "uart1";
-+ };
-+ };
-+
-+ thermal: thermal@2c0 {
-+ compatible = "brcm,ns-thermal";
-+ reg = <0x2c0 0x10>;
-+ #thermal-sensor-cells = <0>;
-+ };
-+ };
-+ };
-+
-+ thermal-zones {
-+ cpu_thermal: cpu-thermal {
-+ polling-delay-passive = <0>;
-+ polling-delay = <1000>;
-+ coefficients = <(-556) 418000>;
-+ thermal-sensors = <&thermal>;
-+
-+ trips {
-+ cpu-crit {
-+ temperature = <125000>;
-+ hysteresis = <0>;
-+ type = "critical";
-+ };
-+ };
-+
-+ cooling-maps {
-+ };
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm5301x.dtsi
-+++ b/arch/arm/boot/dts/bcm5301x.dtsi
-@@ -8,11 +8,7 @@
- * Licensed under the GNU/GPL. See COPYING for details.
- */
-
--#include <dt-bindings/clock/bcm-nsp.h>
--#include <dt-bindings/gpio/gpio.h>
--#include <dt-bindings/input/input.h>
--#include <dt-bindings/interrupt-controller/irq.h>
--#include <dt-bindings/interrupt-controller/arm-gic.h>
-+#include "bcm-ns.dtsi"
-
- / {
- #address-cells = <1>;
-@@ -149,12 +145,6 @@
- };
-
- axi@18000000 {
-- compatible = "brcm,bus-axi";
-- reg = <0x18000000 0x1000>;
-- ranges = <0x00000000 0x18000000 0x00100000>;
-- #address-cells = <1>;
-- #size-cells = <1>;
--
- #interrupt-cells = <1>;
- interrupt-map-mask = <0x000fffff 0xffff>;
- interrupt-map =
-@@ -228,108 +218,15 @@
- <0x00028000 6 &gic GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>,
- <0x00028000 7 &gic GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
-
-- chipcommon: chipcommon@0 {
-- reg = <0x00000000 0x1000>;
--
-- gpio-controller;
-- #gpio-cells = <2>;
-+ chipcommon@0 {
- interrupt-controller;
- #interrupt-cells = <2>;
- };
-
-- pcie0: pcie@12000 {
-- reg = <0x00012000 0x1000>;
-- };
--
-- pcie1: pcie@13000 {
-- reg = <0x00013000 0x1000>;
-- };
--
- pcie2: pcie@14000 {
- reg = <0x00014000 0x1000>;
- };
-
-- usb2: usb2@21000 {
-- reg = <0x00021000 0x1000>;
--
-- #address-cells = <1>;
-- #size-cells = <1>;
-- ranges;
--
-- interrupt-parent = <&gic>;
--
-- ehci: usb@21000 {
-- #usb-cells = <0>;
--
-- compatible = "generic-ehci";
-- reg = <0x00021000 0x1000>;
-- interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
-- phys = <&usb2_phy>;
--
-- #address-cells = <1>;
-- #size-cells = <0>;
--
-- ehci_port1: port@1 {
-- reg = <1>;
-- #trigger-source-cells = <0>;
-- };
--
-- ehci_port2: port@2 {
-- reg = <2>;
-- #trigger-source-cells = <0>;
-- };
-- };
--
-- ohci: usb@22000 {
-- #usb-cells = <0>;
--
-- compatible = "generic-ohci";
-- reg = <0x00022000 0x1000>;
-- interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
--
-- #address-cells = <1>;
-- #size-cells = <0>;
--
-- ohci_port1: port@1 {
-- reg = <1>;
-- #trigger-source-cells = <0>;
-- };
--
-- ohci_port2: port@2 {
-- reg = <2>;
-- #trigger-source-cells = <0>;
-- };
-- };
-- };
--
-- usb3: usb3@23000 {
-- reg = <0x00023000 0x1000>;
--
-- #address-cells = <1>;
-- #size-cells = <1>;
-- ranges;
--
-- interrupt-parent = <&gic>;
--
-- xhci: usb@23000 {
-- #usb-cells = <0>;
--
-- compatible = "generic-xhci";
-- reg = <0x00023000 0x1000>;
-- interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
-- phys = <&usb3_phy>;
-- phy-names = "usb";
--
-- #address-cells = <1>;
-- #size-cells = <0>;
--
-- xhci_port1: port@1 {
-- reg = <1>;
-- #trigger-source-cells = <0>;
-- };
-- };
-- };
--
- gmac0: ethernet@24000 {
- reg = <0x24000 0x800>;
- };
-@@ -355,13 +252,6 @@
- status = "disabled";
- };
-
-- mdio: mdio@18003000 {
-- compatible = "brcm,iproc-mdio";
-- reg = <0x18003000 0x8>;
-- #size-cells = <0>;
-- #address-cells = <1>;
-- };
--
- mdio-mux@18003000 {
- compatible = "mdio-mux-mmioreg", "mdio-mux";
- mdio-parent-bus = <&mdio>;
-@@ -409,18 +299,7 @@
- };
-
- dmu-bus@1800c000 {
-- compatible = "simple-bus";
-- ranges = <0 0x1800c000 0x1000>;
-- #address-cells = <1>;
-- #size-cells = <1>;
--
- cru-bus@100 {
-- compatible = "brcm,ns-cru", "simple-mfd";
-- reg = <0x100 0x1a4>;
-- ranges;
-- #address-cells = <1>;
-- #size-cells = <1>;
--
- lcpll0: clock-controller@100 {
- #clock-cells = <1>;
- compatible = "brcm,nsp-lcpll0";
-@@ -440,53 +319,6 @@
- "usbclk", "iprocfast",
- "sata1", "sata2";
- };
--
-- usb2_phy: phy@164 {
-- compatible = "brcm,ns-usb2-phy";
-- reg = <0x164 0x4>;
-- brcm,syscon-clkset = <&cru_clkset>;
-- clocks = <&genpll BCM_NSP_GENPLL_USB_PHY_REF_CLK>;
-- clock-names = "phy-ref-clk";
-- #phy-cells = <0>;
-- };
--
-- cru_clkset: syscon@180 {
-- compatible = "brcm,cru-clkset", "syscon";
-- reg = <0x180 0x4>;
-- };
--
-- pinctrl: pinctrl@1c0 {
-- compatible = "brcm,bcm4708-pinmux";
-- reg = <0x1c0 0x24>;
-- reg-names = "cru_gpio_control";
--
-- spi-pins {
-- groups = "spi_grp";
-- function = "spi";
-- };
--
-- pinmux_i2c: i2c-pins {
-- groups = "i2c_grp";
-- function = "i2c";
-- };
--
-- pinmux_pwm: pwm-pins {
-- groups = "pwm0_grp", "pwm1_grp",
-- "pwm2_grp", "pwm3_grp";
-- function = "pwm";
-- };
--
-- pinmux_uart1: uart1-pins {
-- groups = "uart1_grp";
-- function = "uart1";
-- };
-- };
--
-- thermal: thermal@2c0 {
-- compatible = "brcm,ns-thermal";
-- reg = <0x2c0 0x10>;
-- #thermal-sensor-cells = <0>;
-- };
- };
- };
-
-@@ -557,24 +389,4 @@
- };
- };
- };
--
-- thermal-zones {
-- cpu_thermal: cpu-thermal {
-- polling-delay-passive = <0>;
-- polling-delay = <1000>;
-- coefficients = <(-556) 418000>;
-- thermal-sensors = <&thermal>;
--
-- trips {
-- cpu-crit {
-- temperature = <125000>;
-- hysteresis = <0>;
-- type = "critical";
-- };
-- };
--
-- cooling-maps {
-- };
-- };
-- };
- };
diff --git a/target/linux/bcm53xx/patches-5.15/036-v6.5-0002-ARM-dts-BCM5301X-Relicense-Florian-s-code-to-the-GPL.patch b/target/linux/bcm53xx/patches-5.15/036-v6.5-0002-ARM-dts-BCM5301X-Relicense-Florian-s-code-to-the-GPL.patch
deleted file mode 100644
index b98f2daa67..0000000000
--- a/target/linux/bcm53xx/patches-5.15/036-v6.5-0002-ARM-dts-BCM5301X-Relicense-Florian-s-code-to-the-GPL.patch
+++ /dev/null
@@ -1,136 +0,0 @@
-From 916553449561c4f0b61c71b751b7bb583f5dddd4 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Wed, 3 May 2023 14:16:11 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Relicense Florian's code to the GPL 2.0+
- / MIT
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-All BCM5301X device DTS files use dual licensing. Try the same for SoC.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230503121611.1629-2-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm-ns.dtsi | 36 ++++++++++++++++++++++++++++++
- arch/arm/boot/dts/bcm5301x.dtsi | 39 ---------------------------------
- 2 files changed, 36 insertions(+), 39 deletions(-)
-
---- a/arch/arm/boot/dts/bcm-ns.dtsi
-+++ b/arch/arm/boot/dts/bcm-ns.dtsi
-@@ -19,6 +19,8 @@
-
- gpio-controller;
- #gpio-cells = <2>;
-+ interrupt-controller;
-+ #interrupt-cells = <2>;
- };
-
- pcie0: pcie@12000 {
-@@ -109,6 +111,22 @@
- };
- };
- };
-+
-+ gmac0: ethernet@24000 {
-+ reg = <0x24000 0x800>;
-+ };
-+
-+ gmac1: ethernet@25000 {
-+ reg = <0x25000 0x800>;
-+ };
-+
-+ gmac2: ethernet@26000 {
-+ reg = <0x26000 0x800>;
-+ };
-+
-+ gmac3: ethernet@27000 {
-+ reg = <0x27000 0x800>;
-+ };
- };
-
- mdio: mdio@18003000 {
-@@ -118,6 +136,24 @@
- #address-cells = <1>;
- };
-
-+ rng: rng@18004000 {
-+ compatible = "brcm,bcm5301x-rng";
-+ reg = <0x18004000 0x14>;
-+ };
-+
-+ srab: ethernet-switch@18007000 {
-+ compatible = "brcm,bcm53011-srab", "brcm,bcm5301x-srab";
-+ reg = <0x18007000 0x1000>;
-+
-+ status = "disabled";
-+
-+ /* ports are defined in board DTS */
-+ ports {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ };
-+ };
-+
- dmu-bus@1800c000 {
- compatible = "simple-bus";
- ranges = <0 0x1800c000 0x1000>;
---- a/arch/arm/boot/dts/bcm5301x.dtsi
-+++ b/arch/arm/boot/dts/bcm5301x.dtsi
-@@ -218,30 +218,9 @@
- <0x00028000 6 &gic GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>,
- <0x00028000 7 &gic GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
-
-- chipcommon@0 {
-- interrupt-controller;
-- #interrupt-cells = <2>;
-- };
--
- pcie2: pcie@14000 {
- reg = <0x00014000 0x1000>;
- };
--
-- gmac0: ethernet@24000 {
-- reg = <0x24000 0x800>;
-- };
--
-- gmac1: ethernet@25000 {
-- reg = <0x25000 0x800>;
-- };
--
-- gmac2: ethernet@26000 {
-- reg = <0x26000 0x800>;
-- };
--
-- gmac3: ethernet@27000 {
-- reg = <0x27000 0x800>;
-- };
- };
-
- pwm: pwm@18002000 {
-@@ -322,24 +301,6 @@
- };
- };
-
-- srab: ethernet-switch@18007000 {
-- compatible = "brcm,bcm53011-srab", "brcm,bcm5301x-srab";
-- reg = <0x18007000 0x1000>;
--
-- status = "disabled";
--
-- /* ports are defined in board DTS */
-- ports {
-- #address-cells = <1>;
-- #size-cells = <0>;
-- };
-- };
--
-- rng: rng@18004000 {
-- compatible = "brcm,bcm5301x-rng";
-- reg = <0x18004000 0x14>;
-- };
--
- nand_controller: nand-controller@18028000 {
- compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1", "brcm,brcmnand";
- reg = <0x18028000 0x600>, <0x1811a408 0x600>, <0x18028f00 0x20>;
diff --git a/target/linux/bcm53xx/patches-5.15/036-v6.5-0004-ARM-dts-BCM5301X-Relicense-Hauke-s-code-to-the-GPL-2.patch b/target/linux/bcm53xx/patches-5.15/036-v6.5-0004-ARM-dts-BCM5301X-Relicense-Hauke-s-code-to-the-GPL-2.patch
deleted file mode 100644
index 328748c8e0..0000000000
--- a/target/linux/bcm53xx/patches-5.15/036-v6.5-0004-ARM-dts-BCM5301X-Relicense-Hauke-s-code-to-the-GPL-2.patch
+++ /dev/null
@@ -1,249 +0,0 @@
-From b3b3cd885ed39cb4b38319a1c4fa4e41db6fee72 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Mon, 15 May 2023 17:19:20 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Relicense Hauke's code to the GPL 2.0+ /
- MIT
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Move code added by Hauke to the bcm-ns.dtsi which uses dual licensing.
-That syncs more Northstar code to be based on the same licensing schema.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Cc: Hauke Mehrtens <hauke@hauke-m.de>
-Acked-by: Hauke Mehrtens <hauke@hauke-m.de>
-Link: https://lore.kernel.org/r/20230515151921.25021-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/bcm-ns.dtsi | 90 +++++++++++++++++++++++++++++++++
- arch/arm/boot/dts/bcm5301x.dtsi | 85 -------------------------------
- 2 files changed, 90 insertions(+), 85 deletions(-)
-
---- a/arch/arm/boot/dts/bcm-ns.dtsi
-+++ b/arch/arm/boot/dts/bcm-ns.dtsi
-@@ -1,4 +1,7 @@
- // SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-+/*
-+ * Copyright 2013-2014 Hauke Mehrtens <hauke@hauke-m.de>
-+ */
-
- #include <dt-bindings/clock/bcm-nsp.h>
- #include <dt-bindings/gpio/gpio.h>
-@@ -7,6 +10,81 @@
- #include <dt-bindings/interrupt-controller/arm-gic.h>
-
- / {
-+ interrupt-parent = <&gic>;
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ chipcommon-a-bus@18000000 {
-+ compatible = "simple-bus";
-+ ranges = <0x00000000 0x18000000 0x00001000>;
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ uart0: serial@300 {
-+ compatible = "ns16550";
-+ reg = <0x0300 0x100>;
-+ interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
-+ clocks = <&iprocslow>;
-+ status = "disabled";
-+ };
-+
-+ uart1: serial@400 {
-+ compatible = "ns16550";
-+ reg = <0x0400 0x100>;
-+ interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
-+ clocks = <&iprocslow>;
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&pinmux_uart1>;
-+ status = "disabled";
-+ };
-+ };
-+
-+ mpcore-bus@19000000 {
-+ compatible = "simple-bus";
-+ ranges = <0x00000000 0x19000000 0x00023000>;
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ scu@20000 {
-+ compatible = "arm,cortex-a9-scu";
-+ reg = <0x20000 0x100>;
-+ };
-+
-+ timer@20200 {
-+ compatible = "arm,cortex-a9-global-timer";
-+ reg = <0x20200 0x100>;
-+ interrupts = <GIC_PPI 11 IRQ_TYPE_EDGE_RISING>;
-+ clocks = <&periph_clk>;
-+ };
-+
-+ timer@20600 {
-+ compatible = "arm,cortex-a9-twd-timer";
-+ reg = <0x20600 0x20>;
-+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) |
-+ IRQ_TYPE_EDGE_RISING)>;
-+ clocks = <&periph_clk>;
-+ };
-+
-+ gic: interrupt-controller@21000 {
-+ compatible = "arm,cortex-a9-gic";
-+ #interrupt-cells = <3>;
-+ #address-cells = <0>;
-+ interrupt-controller;
-+ reg = <0x21000 0x1000>,
-+ <0x20100 0x100>;
-+ };
-+
-+ L2: cache-controller@22000 {
-+ compatible = "arm,pl310-cache";
-+ reg = <0x22000 0x1000>;
-+ cache-unified;
-+ arm,shared-override;
-+ prefetch-data = <1>;
-+ prefetch-instr = <1>;
-+ cache-level = <2>;
-+ };
-+ };
-+
- axi@18000000 {
- compatible = "brcm,bus-axi";
- reg = <0x18000000 0x1000>;
-@@ -216,6 +294,18 @@
- };
- };
-
-+ nand_controller: nand-controller@18028000 {
-+ compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1", "brcm,brcmnand";
-+ reg = <0x18028000 0x600>, <0x1811a408 0x600>, <0x18028f00 0x20>;
-+ reg-names = "nand", "iproc-idm", "iproc-ext";
-+ interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
-+
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ brcm,nand-has-wp;
-+ };
-+
- thermal-zones {
- cpu_thermal: cpu-thermal {
- polling-delay-passive = <0>;
---- a/arch/arm/boot/dts/bcm5301x.dtsi
-+++ b/arch/arm/boot/dts/bcm5301x.dtsi
-@@ -11,41 +11,7 @@
- #include "bcm-ns.dtsi"
-
- / {
-- #address-cells = <1>;
-- #size-cells = <1>;
-- interrupt-parent = <&gic>;
--
-- chipcommon-a-bus@18000000 {
-- compatible = "simple-bus";
-- ranges = <0x00000000 0x18000000 0x00001000>;
-- #address-cells = <1>;
-- #size-cells = <1>;
--
-- uart0: serial@300 {
-- compatible = "ns16550";
-- reg = <0x0300 0x100>;
-- interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
-- clocks = <&iprocslow>;
-- status = "disabled";
-- };
--
-- uart1: serial@400 {
-- compatible = "ns16550";
-- reg = <0x0400 0x100>;
-- interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
-- clocks = <&iprocslow>;
-- pinctrl-names = "default";
-- pinctrl-0 = <&pinmux_uart1>;
-- status = "disabled";
-- };
-- };
--
- mpcore-bus@19000000 {
-- compatible = "simple-bus";
-- ranges = <0x00000000 0x19000000 0x00023000>;
-- #address-cells = <1>;
-- #size-cells = <1>;
--
- a9pll: arm_clk@0 {
- #clock-cells = <0>;
- compatible = "brcm,nsp-armpll";
-@@ -53,26 +19,6 @@
- reg = <0x00000 0x1000>;
- };
-
-- scu@20000 {
-- compatible = "arm,cortex-a9-scu";
-- reg = <0x20000 0x100>;
-- };
--
-- timer@20200 {
-- compatible = "arm,cortex-a9-global-timer";
-- reg = <0x20200 0x100>;
-- interrupts = <GIC_PPI 11 IRQ_TYPE_EDGE_RISING>;
-- clocks = <&periph_clk>;
-- };
--
-- timer@20600 {
-- compatible = "arm,cortex-a9-twd-timer";
-- reg = <0x20600 0x20>;
-- interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) |
-- IRQ_TYPE_EDGE_RISING)>;
-- clocks = <&periph_clk>;
-- };
--
- watchdog@20620 {
- compatible = "arm,cortex-a9-twd-wdt";
- reg = <0x20620 0x20>;
-@@ -80,25 +26,6 @@
- IRQ_TYPE_EDGE_RISING)>;
- clocks = <&periph_clk>;
- };
--
-- gic: interrupt-controller@21000 {
-- compatible = "arm,cortex-a9-gic";
-- #interrupt-cells = <3>;
-- #address-cells = <0>;
-- interrupt-controller;
-- reg = <0x21000 0x1000>,
-- <0x20100 0x100>;
-- };
--
-- L2: cache-controller@22000 {
-- compatible = "arm,pl310-cache";
-- reg = <0x22000 0x1000>;
-- cache-unified;
-- arm,shared-override;
-- prefetch-data = <1>;
-- prefetch-instr = <1>;
-- cache-level = <2>;
-- };
- };
-
- pmu {
-@@ -301,18 +228,6 @@
- };
- };
-
-- nand_controller: nand-controller@18028000 {
-- compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1", "brcm,brcmnand";
-- reg = <0x18028000 0x600>, <0x1811a408 0x600>, <0x18028f00 0x20>;
-- reg-names = "nand", "iproc-idm", "iproc-ext";
-- interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
--
-- #address-cells = <1>;
-- #size-cells = <0>;
--
-- brcm,nand-has-wp;
-- };
--
- spi@18029200 {
- compatible = "brcm,spi-nsp-qspi", "brcm,spi-bcm-qspi";
- reg = <0x18029200 0x184>,
diff --git a/target/linux/bcm53xx/patches-5.15/036-v6.5-0005-ARM-dts-BCM5301X-Relicense-AXI-interrupts-code-to-th.patch b/target/linux/bcm53xx/patches-5.15/036-v6.5-0005-ARM-dts-BCM5301X-Relicense-AXI-interrupts-code-to-th.patch
deleted file mode 100644
index ef29266d0b..0000000000
--- a/target/linux/bcm53xx/patches-5.15/036-v6.5-0005-ARM-dts-BCM5301X-Relicense-AXI-interrupts-code-to-th.patch
+++ /dev/null
@@ -1,203 +0,0 @@
-From 3b3e35b279bee5e51580c648399e20323467f58c Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Mon, 15 May 2023 17:19:21 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Relicense AXI interrupts code to the GPL
- 2.0+ / MIT
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Those entries were added by:
-1. Hauke in commits dec378827c4a ("ARM: BCM5301X: Add IRQs to Broadcom's
- bus-axi in DTS file") and 1f80de6863ca ("ARM: BCM5301X: add IRQ
- numbers for PCIe controller")
-2. Florian in the commit 2cd0c0202f13 ("ARM: dts: BCM5301X: Add SRAB
- interrupts")
-
-Move them to the bcm-ns.dtsi which uses dual licensing. That syncs more
-Northstar code to be based on the same licensing schema.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Cc: Hauke Mehrtens <hauke@hauke-m.de>
-Cc: Florian Fainelli <f.fainelli@gmail.com>
-Acked-by: Hauke Mehrtens <hauke@hauke-m.de>
-Link: https://lore.kernel.org/r/20230515151921.25021-2-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/bcm-ns.dtsi | 73 ++++++++++++++++++++++++++++++++
- arch/arm/boot/dts/bcm5301x.dtsi | 75 ---------------------------------
- 2 files changed, 73 insertions(+), 75 deletions(-)
-
---- a/arch/arm/boot/dts/bcm-ns.dtsi
-+++ b/arch/arm/boot/dts/bcm-ns.dtsi
-@@ -92,6 +92,79 @@
- #address-cells = <1>;
- #size-cells = <1>;
-
-+ #interrupt-cells = <1>;
-+ interrupt-map-mask = <0x000fffff 0xffff>;
-+ interrupt-map =
-+ /* ChipCommon */
-+ <0x00000000 0 &gic GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>,
-+
-+ /* Switch Register Access Block */
-+ <0x00007000 0 &gic GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00007000 1 &gic GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00007000 2 &gic GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00007000 3 &gic GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00007000 4 &gic GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00007000 5 &gic GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00007000 6 &gic GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00007000 7 &gic GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00007000 8 &gic GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00007000 9 &gic GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00007000 10 &gic GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00007000 11 &gic GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00007000 12 &gic GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>,
-+
-+ /* PCIe Controller 0 */
-+ <0x00012000 0 &gic GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00012000 1 &gic GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00012000 2 &gic GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00012000 3 &gic GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00012000 4 &gic GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00012000 5 &gic GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
-+
-+ /* PCIe Controller 1 */
-+ <0x00013000 0 &gic GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00013000 1 &gic GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00013000 2 &gic GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00013000 3 &gic GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00013000 4 &gic GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00013000 5 &gic GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
-+
-+ /* PCIe Controller 2 */
-+ <0x00014000 0 &gic GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00014000 1 &gic GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00014000 2 &gic GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00014000 3 &gic GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00014000 4 &gic GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00014000 5 &gic GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>,
-+
-+ /* USB 2.0 Controller */
-+ <0x00021000 0 &gic GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>,
-+
-+ /* USB 3.0 Controller */
-+ <0x00023000 0 &gic GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>,
-+
-+ /* Ethernet Controller 0 */
-+ <0x00024000 0 &gic GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>,
-+
-+ /* Ethernet Controller 1 */
-+ <0x00025000 0 &gic GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>,
-+
-+ /* Ethernet Controller 2 */
-+ <0x00026000 0 &gic GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>,
-+
-+ /* Ethernet Controller 3 */
-+ <0x00027000 0 &gic GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>,
-+
-+ /* NAND Controller */
-+ <0x00028000 0 &gic GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00028000 1 &gic GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00028000 2 &gic GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00028000 3 &gic GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00028000 4 &gic GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00028000 5 &gic GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00028000 6 &gic GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00028000 7 &gic GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
-+
- chipcommon: chipcommon@0 {
- reg = <0x00000000 0x1000>;
-
---- a/arch/arm/boot/dts/bcm5301x.dtsi
-+++ b/arch/arm/boot/dts/bcm5301x.dtsi
-@@ -3,8 +3,6 @@
- * Generic DTS part for all BCM53010, BCM53011, BCM53012, BCM53014, BCM53015,
- * BCM53016, BCM53017, BCM53018, BCM4707, BCM4708 and BCM4709 SoCs
- *
-- * Copyright 2013-2014 Hauke Mehrtens <hauke@hauke-m.de>
-- *
- * Licensed under the GNU/GPL. See COPYING for details.
- */
-
-@@ -72,79 +70,6 @@
- };
-
- axi@18000000 {
-- #interrupt-cells = <1>;
-- interrupt-map-mask = <0x000fffff 0xffff>;
-- interrupt-map =
-- /* ChipCommon */
-- <0x00000000 0 &gic GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>,
--
-- /* Switch Register Access Block */
-- <0x00007000 0 &gic GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00007000 1 &gic GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00007000 2 &gic GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00007000 3 &gic GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00007000 4 &gic GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00007000 5 &gic GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00007000 6 &gic GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00007000 7 &gic GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00007000 8 &gic GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00007000 9 &gic GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00007000 10 &gic GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00007000 11 &gic GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00007000 12 &gic GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>,
--
-- /* PCIe Controller 0 */
-- <0x00012000 0 &gic GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00012000 1 &gic GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00012000 2 &gic GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00012000 3 &gic GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00012000 4 &gic GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00012000 5 &gic GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
--
-- /* PCIe Controller 1 */
-- <0x00013000 0 &gic GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00013000 1 &gic GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00013000 2 &gic GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00013000 3 &gic GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00013000 4 &gic GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00013000 5 &gic GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
--
-- /* PCIe Controller 2 */
-- <0x00014000 0 &gic GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00014000 1 &gic GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00014000 2 &gic GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00014000 3 &gic GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00014000 4 &gic GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00014000 5 &gic GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>,
--
-- /* USB 2.0 Controller */
-- <0x00021000 0 &gic GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>,
--
-- /* USB 3.0 Controller */
-- <0x00023000 0 &gic GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>,
--
-- /* Ethernet Controller 0 */
-- <0x00024000 0 &gic GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>,
--
-- /* Ethernet Controller 1 */
-- <0x00025000 0 &gic GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>,
--
-- /* Ethernet Controller 2 */
-- <0x00026000 0 &gic GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>,
--
-- /* Ethernet Controller 3 */
-- <0x00027000 0 &gic GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>,
--
-- /* NAND Controller */
-- <0x00028000 0 &gic GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00028000 1 &gic GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00028000 2 &gic GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00028000 3 &gic GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00028000 4 &gic GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00028000 5 &gic GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00028000 6 &gic GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00028000 7 &gic GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
--
- pcie2: pcie@14000 {
- reg = <0x00014000 0x1000>;
- };
diff --git a/target/linux/bcm53xx/patches-5.15/036-v6.5-0006-ARM-dts-BCM5301X-Specify-MAC-addresses-on-Luxul-devi.patch b/target/linux/bcm53xx/patches-5.15/036-v6.5-0006-ARM-dts-BCM5301X-Specify-MAC-addresses-on-Luxul-devi.patch
deleted file mode 100644
index 7d9b297191..0000000000
--- a/target/linux/bcm53xx/patches-5.15/036-v6.5-0006-ARM-dts-BCM5301X-Specify-MAC-addresses-on-Luxul-devi.patch
+++ /dev/null
@@ -1,336 +0,0 @@
-From dfa6570eb5ce2f24059caadbe2ed70034b5337bc Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Mon, 15 May 2023 10:33:08 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Specify MAC addresses on Luxul devices
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Use NRAM (NVMEM device) and its "et0macaddr" variable (NVMEM cell) to
-point Ethernet devices to their MAC addresses.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230515083308.7612-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts | 13 +++++++++++++
- arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts | 13 +++++++++++++
- arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts | 13 +++++++++++++
- arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts | 11 +++++++++++
- arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts | 11 +++++++++++
- arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts | 13 +++++++++++++
- arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts | 11 +++++++++++
- arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts | 13 +++++++++++++
- arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts | 11 +++++++++++
- arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts | 5 ++++-
- 10 files changed, 113 insertions(+), 1 deletion(-)
-
---- a/arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts
-+++ b/arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts
-@@ -20,6 +20,14 @@
- reg = <0x00000000 0x08000000>;
- };
-
-+ nvram@1eff0000 {
-+ compatible = "brcm,nvram";
-+ reg = <0x1eff0000 0x10000>;
-+
-+ et0macaddr: et0macaddr {
-+ };
-+ };
-+
- leds {
- compatible = "gpio-leds";
-
-@@ -53,6 +61,11 @@
- };
- };
-
-+&gmac0 {
-+ nvmem-cells = <&et0macaddr>;
-+ nvmem-cell-names = "mac-address";
-+};
-+
- &spi_nor {
- status = "okay";
- };
---- a/arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts
-+++ b/arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts
-@@ -24,6 +24,14 @@
- reg = <0x00000000 0x08000000>;
- };
-
-+ nvram@1eff0000 {
-+ compatible = "brcm,nvram";
-+ reg = <0x1eff0000 0x10000>;
-+
-+ et0macaddr: et0macaddr {
-+ };
-+ };
-+
- nand_controller: nand-controller@18028000 {
- nand@0 {
- partitions {
-@@ -60,6 +68,11 @@
- };
- };
-
-+&gmac0 {
-+ nvmem-cells = <&et0macaddr>;
-+ nvmem-cell-names = "mac-address";
-+};
-+
- &spi_nor {
- status = "okay";
- };
---- a/arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts
-+++ b/arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts
-@@ -20,6 +20,14 @@
- reg = <0x00000000 0x08000000>;
- };
-
-+ nvram@1eff0000 {
-+ compatible = "brcm,nvram";
-+ reg = <0x1eff0000 0x10000>;
-+
-+ et0macaddr: et0macaddr {
-+ };
-+ };
-+
- leds {
- compatible = "gpio-leds";
-
-@@ -53,6 +61,11 @@
- };
- };
-
-+&gmac0 {
-+ nvmem-cells = <&et0macaddr>;
-+ nvmem-cell-names = "mac-address";
-+};
-+
- &spi_nor {
- status = "okay";
- };
---- a/arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts
-+++ b/arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts
-@@ -24,6 +24,10 @@
- nvram@1eff0000 {
- compatible = "brcm,nvram";
- reg = <0x1eff0000 0x10000>;
-+
-+ et0macaddr: et0macaddr {
-+ #nvmem-cell-cells = <1>;
-+ };
- };
-
- leds {
-@@ -106,6 +110,11 @@
- vcc-gpio = <&chipcommon 9 GPIO_ACTIVE_HIGH>;
- };
-
-+&gmac0 {
-+ nvmem-cells = <&et0macaddr 0>;
-+ nvmem-cell-names = "mac-address";
-+};
-+
- &spi_nor {
- status = "okay";
- };
-@@ -137,6 +146,8 @@
- port@4 {
- reg = <4>;
- label = "wan";
-+ nvmem-cells = <&et0macaddr 5>;
-+ nvmem-cell-names = "mac-address";
- };
-
- port@5 {
---- a/arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts
-@@ -25,6 +25,10 @@
- nvram@1eff0000 {
- compatible = "brcm,nvram";
- reg = <0x1eff0000 0x10000>;
-+
-+ et0macaddr: et0macaddr {
-+ #nvmem-cell-cells = <1>;
-+ };
- };
-
- leds {
-@@ -61,6 +65,11 @@
- vcc-gpio = <&chipcommon 18 GPIO_ACTIVE_HIGH>;
- };
-
-+&gmac0 {
-+ nvmem-cells = <&et0macaddr 0>;
-+ nvmem-cell-names = "mac-address";
-+};
-+
- &spi_nor {
- status = "okay";
- };
-@@ -76,6 +85,8 @@
- port@0 {
- reg = <0>;
- label = "wan";
-+ nvmem-cells = <&et0macaddr 1>;
-+ nvmem-cell-names = "mac-address";
- };
-
- port@1 {
---- a/arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts
-@@ -20,6 +20,14 @@
- reg = <0x00000000 0x08000000>;
- };
-
-+ nvram@1eff0000 {
-+ compatible = "brcm,nvram";
-+ reg = <0x1eff0000 0x10000>;
-+
-+ et0macaddr: et0macaddr {
-+ };
-+ };
-+
- leds {
- compatible = "gpio-leds";
-
-@@ -51,6 +59,11 @@
- };
- };
-
-+&gmac0 {
-+ nvmem-cells = <&et0macaddr>;
-+ nvmem-cell-names = "mac-address";
-+};
-+
- &spi_nor {
- status = "okay";
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts
-@@ -25,6 +25,10 @@
- nvram@1eff0000 {
- compatible = "brcm,nvram";
- reg = <0x1eff0000 0x10000>;
-+
-+ et0macaddr: et0macaddr {
-+ #nvmem-cell-cells = <1>;
-+ };
- };
-
- leds {
-@@ -61,6 +65,11 @@
- vcc-gpio = <&chipcommon 18 GPIO_ACTIVE_HIGH>;
- };
-
-+&gmac0 {
-+ nvmem-cells = <&et0macaddr 0>;
-+ nvmem-cell-names = "mac-address";
-+};
-+
- &spi_nor {
- status = "okay";
- };
-@@ -76,6 +85,8 @@
- port@0 {
- reg = <0>;
- label = "wan";
-+ nvmem-cells = <&et0macaddr 1>;
-+ nvmem-cell-names = "mac-address";
- };
-
- port@1 {
---- a/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts
-@@ -22,6 +22,14 @@
- <0x88000000 0x18000000>;
- };
-
-+ nvram@1eff0000 {
-+ compatible = "brcm,nvram";
-+ reg = <0x1eff0000 0x10000>;
-+
-+ et0macaddr: et0macaddr {
-+ };
-+ };
-+
- leds {
- compatible = "gpio-leds";
-
-@@ -47,6 +55,11 @@
- status = "okay";
- };
-
-+&gmac0 {
-+ nvmem-cells = <&et0macaddr>;
-+ nvmem-cell-names = "mac-address";
-+};
-+
- &spi_nor {
- status = "okay";
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts
-@@ -25,6 +25,10 @@
- nvram@1eff0000 {
- compatible = "brcm,nvram";
- reg = <0x1eff0000 0x10000>;
-+
-+ et0macaddr: et0macaddr {
-+ #nvmem-cell-cells = <1>;
-+ };
- };
-
- leds {
-@@ -101,6 +105,11 @@
- vcc-gpio = <&chipcommon 18 GPIO_ACTIVE_HIGH>;
- };
-
-+&gmac0 {
-+ nvmem-cells = <&et0macaddr 0>;
-+ nvmem-cell-names = "mac-address";
-+};
-+
- &spi_nor {
- status = "okay";
- };
-@@ -136,6 +145,8 @@
- port@4 {
- reg = <4>;
- label = "wan";
-+ nvmem-cells = <&et0macaddr 5>;
-+ nvmem-cell-names = "mac-address";
- };
-
- port@5 {
---- a/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
-@@ -27,6 +27,7 @@
- reg = <0x1eff0000 0x10000>;
-
- et0macaddr: et0macaddr {
-+ #nvmem-cell-cells = <1>;
- };
- };
-
-@@ -76,7 +77,7 @@
- };
-
- &gmac0 {
-- nvmem-cells = <&et0macaddr>;
-+ nvmem-cells = <&et0macaddr 0>;
- nvmem-cell-names = "mac-address";
- };
-
-@@ -119,6 +120,8 @@
- port@4 {
- reg = <4>;
- label = "wan";
-+ nvmem-cells = <&et0macaddr 5>;
-+ nvmem-cell-names = "mac-address";
- };
-
- port@5 {
diff --git a/target/linux/bcm53xx/patches-5.15/036-v6.5-0007-ARM-dts-BCM5301X-Use-updated-device-compatible-strin.patch b/target/linux/bcm53xx/patches-5.15/036-v6.5-0007-ARM-dts-BCM5301X-Use-updated-device-compatible-strin.patch
deleted file mode 100644
index 5f5890e291..0000000000
--- a/target/linux/bcm53xx/patches-5.15/036-v6.5-0007-ARM-dts-BCM5301X-Use-updated-device-compatible-strin.patch
+++ /dev/null
@@ -1,90 +0,0 @@
-From 9d7121f1d2faa0b50bf5b462adcd2dd91970c45e Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Sat, 20 May 2023 13:26:01 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Use updated device "compatible" strings
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Northstar binding was updated to use minus/hyphen char between model and
-version for all devices.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
-Link: https://lore.kernel.org/r/20230520112601.11821-2-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts | 2 +-
- arch/arm/boot/dts/bcm4708-netgear-r6250.dts | 2 +-
- arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts | 2 +-
- arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts | 2 +-
- arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts | 2 +-
- arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts | 2 +-
- 6 files changed, 6 insertions(+), 6 deletions(-)
-
---- a/arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts
-+++ b/arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts
-@@ -8,7 +8,7 @@
- #include "bcm4708.dtsi"
-
- / {
-- compatible = "luxul,xap-1510v1", "brcm,bcm4708";
-+ compatible = "luxul,xap-1510-v1", "brcm,bcm4708";
- model = "Luxul XAP-1510 V1";
-
- chosen {
---- a/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
-+++ b/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
-@@ -13,7 +13,7 @@
- #include "bcm5301x-nand-cs0-bch8.dtsi"
-
- / {
-- compatible = "netgear,r6250v1", "brcm,bcm4708";
-+ compatible = "netgear,r6250-v1", "brcm,bcm4708";
- model = "Netgear R6250 V1 (BCM4708)";
-
- chosen {
---- a/arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts
-+++ b/arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts
-@@ -12,7 +12,7 @@
- #include "bcm5301x-nand-cs0-bch8.dtsi"
-
- / {
-- compatible = "netgear,r6300v2", "brcm,bcm4708";
-+ compatible = "netgear,r6300-v2", "brcm,bcm4708";
- model = "Netgear R6300 V2 (BCM4708)";
-
- chosen {
---- a/arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts
-+++ b/arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts
-@@ -8,7 +8,7 @@
- #include "bcm47081.dtsi"
-
- / {
-- compatible = "luxul,xap-1410v1", "brcm,bcm47081", "brcm,bcm4708";
-+ compatible = "luxul,xap-1410-v1", "brcm,bcm47081", "brcm,bcm4708";
- model = "Luxul XAP-1410 V1";
-
- chosen {
---- a/arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts
-+++ b/arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts
-@@ -9,7 +9,7 @@
- #include "bcm5301x-nand-cs0-bch4.dtsi"
-
- / {
-- compatible = "luxul,xwr-1200v1", "brcm,bcm47081", "brcm,bcm4708";
-+ compatible = "luxul,xwr-1200-v1", "brcm,bcm47081", "brcm,bcm4708";
- model = "Luxul XWR-1200 V1";
-
- chosen {
---- a/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts
-@@ -9,7 +9,7 @@
- #include "bcm5301x-nand-cs0-bch4.dtsi"
-
- / {
-- compatible = "luxul,xwr-3100v1", "brcm,bcm47094", "brcm,bcm4708";
-+ compatible = "luxul,xwr-3100-v1", "brcm,bcm47094", "brcm,bcm4708";
- model = "Luxul XWR-3100 V1";
-
- chosen {
diff --git a/target/linux/bcm53xx/patches-5.15/036-v6.5-0008-ARM-dts-BCM5301X-Use-updated-spi-gpio-binding-proper.patch b/target/linux/bcm53xx/patches-5.15/036-v6.5-0008-ARM-dts-BCM5301X-Use-updated-spi-gpio-binding-proper.patch
deleted file mode 100644
index c16587f684..0000000000
--- a/target/linux/bcm53xx/patches-5.15/036-v6.5-0008-ARM-dts-BCM5301X-Use-updated-spi-gpio-binding-proper.patch
+++ /dev/null
@@ -1,82 +0,0 @@
-From 04afb51c1dce90051487d3c7b70a1b1b246ce29a Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 2 Jun 2023 17:10:23 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Use updated "spi-gpio" binding properties
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Switch away from deprecated properties.
-
-This fixes:
-arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dtb: spi: gpio-sck: False schema does not allow [[6, 7, 0]]
- From schema: Documentation/devicetree/bindings/spi/spi-gpio.yaml
-arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dtb: spi: gpio-mosi: False schema does not allow [[6, 4, 0]]
- From schema: Documentation/devicetree/bindings/spi/spi-gpio.yaml
-arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dtb: spi: 'sck-gpios' is a required property
- From schema: Documentation/devicetree/bindings/spi/spi-gpio.yaml
-arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dtb: spi: Unevaluated properties are not allowed ('gpio-mosi', 'gpio-sck' were unexpected)
- From schema: Documentation/devicetree/bindings/spi/spi-gpio.yaml
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230602151023.8607-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/bcm4708-buffalo-wzr-1166dhp-common.dtsi | 4 ++--
- arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts | 4 ++--
- arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts | 4 ++--
- arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts | 4 ++--
- 4 files changed, 8 insertions(+), 8 deletions(-)
-
---- a/arch/arm/boot/dts/bcm4708-buffalo-wzr-1166dhp-common.dtsi
-+++ b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1166dhp-common.dtsi
-@@ -16,8 +16,8 @@
- spi {
- compatible = "spi-gpio";
- num-chipselects = <1>;
-- gpio-sck = <&chipcommon 7 0>;
-- gpio-mosi = <&chipcommon 4 0>;
-+ sck-gpios = <&chipcommon 7 0>;
-+ mosi-gpios = <&chipcommon 4 0>;
- cs-gpios = <&chipcommon 6 0>;
- #address-cells = <1>;
- #size-cells = <0>;
---- a/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts
-+++ b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts
-@@ -28,8 +28,8 @@
- spi {
- compatible = "spi-gpio";
- num-chipselects = <1>;
-- gpio-sck = <&chipcommon 7 0>;
-- gpio-mosi = <&chipcommon 4 0>;
-+ sck-gpios = <&chipcommon 7 0>;
-+ mosi-gpios = <&chipcommon 4 0>;
- cs-gpios = <&chipcommon 6 0>;
- #address-cells = <1>;
- #size-cells = <0>;
---- a/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
-+++ b/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
-@@ -28,8 +28,8 @@
- spi {
- compatible = "spi-gpio";
- num-chipselects = <1>;
-- gpio-sck = <&chipcommon 7 0>;
-- gpio-mosi = <&chipcommon 4 0>;
-+ sck-gpios = <&chipcommon 7 0>;
-+ mosi-gpios = <&chipcommon 4 0>;
- cs-gpios = <&chipcommon 6 0>;
- #address-cells = <1>;
- #size-cells = <0>;
---- a/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts
-+++ b/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts
-@@ -28,8 +28,8 @@
- spi {
- compatible = "spi-gpio";
- num-chipselects = <1>;
-- gpio-sck = <&chipcommon 7 0>;
-- gpio-mosi = <&chipcommon 4 0>;
-+ sck-gpios = <&chipcommon 7 0>;
-+ mosi-gpios = <&chipcommon 4 0>;
- cs-gpios = <&chipcommon 6 0>;
- #address-cells = <1>;
- #size-cells = <0>;
diff --git a/target/linux/bcm53xx/patches-5.15/036-v6.5-0009-ARM-dts-BCM5301X-Drop-invalid-usb-cells.patch b/target/linux/bcm53xx/patches-5.15/036-v6.5-0009-ARM-dts-BCM5301X-Drop-invalid-usb-cells.patch
deleted file mode 100644
index 59fa457aee..0000000000
--- a/target/linux/bcm53xx/patches-5.15/036-v6.5-0009-ARM-dts-BCM5301X-Drop-invalid-usb-cells.patch
+++ /dev/null
@@ -1,54 +0,0 @@
-From c3acdd4901192bc69dc577012663d5abae21661e Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 2 Jun 2023 15:34:54 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Drop invalid #usb-cells
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Such property simply doesn't exist (is not documented or used anywhere).
-
-This fixes:
-arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dtb: usb@21000: Unevaluated properties are not allowed ('#usb-cells' was unexpected)
- From schema: Documentation/devicetree/bindings/usb/generic-ehci.yaml
-arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dtb: usb@22000: Unevaluated properties are not allowed ('#usb-cells' was unexpected)
- From schema: Documentation/devicetree/bindings/usb/generic-ohci.yaml
-arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dtb: usb@23000: Unevaluated properties are not allowed ('#usb-cells' was unexpected)
- From schema: Documentation/devicetree/bindings/usb/generic-xhci.yaml
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230602133455.7441-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/bcm-ns.dtsi | 6 ------
- 1 file changed, 6 deletions(-)
-
---- a/arch/arm/boot/dts/bcm-ns.dtsi
-+++ b/arch/arm/boot/dts/bcm-ns.dtsi
-@@ -192,8 +192,6 @@
- interrupt-parent = <&gic>;
-
- ehci: usb@21000 {
-- #usb-cells = <0>;
--
- compatible = "generic-ehci";
- reg = <0x00021000 0x1000>;
- interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
-@@ -214,8 +212,6 @@
- };
-
- ohci: usb@22000 {
-- #usb-cells = <0>;
--
- compatible = "generic-ohci";
- reg = <0x00022000 0x1000>;
- interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
-@@ -245,8 +241,6 @@
- interrupt-parent = <&gic>;
-
- xhci: usb@23000 {
-- #usb-cells = <0>;
--
- compatible = "generic-xhci";
- reg = <0x00023000 0x1000>;
- interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/target/linux/bcm53xx/patches-5.15/036-v6.5-0010-ARM-dts-BCM5301X-Drop-invalid-properties-from-Meraki.patch b/target/linux/bcm53xx/patches-5.15/036-v6.5-0010-ARM-dts-BCM5301X-Drop-invalid-properties-from-Meraki.patch
deleted file mode 100644
index b8411fc719..0000000000
--- a/target/linux/bcm53xx/patches-5.15/036-v6.5-0010-ARM-dts-BCM5301X-Drop-invalid-properties-from-Meraki.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From 676bf7d062c14191c3fc12f1e36e1f3809041483 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 2 Jun 2023 15:34:55 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Drop invalid properties from Meraki MR32
- keys
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This fixes:
-arch/arm/boot/dts/bcm53015-meraki-mr26.dtb: keys: '#address-cells', '#size-cells' do not match any of the regexes: '^(button|event|key|switch|(button|event|key|switch)-[a-z0-9-]+|[a-z0-9-]+-(button|event|key|switch))$', 'pinctrl-[0-9]+'
- From schema: Documentation/devicetree/bindings/input/gpio-keys.yaml
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230602133455.7441-2-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/bcm53015-meraki-mr26.dts | 2 --
- 1 file changed, 2 deletions(-)
-
---- a/arch/arm/boot/dts/bcm53015-meraki-mr26.dts
-+++ b/arch/arm/boot/dts/bcm53015-meraki-mr26.dts
-@@ -39,8 +39,6 @@
-
- keys {
- compatible = "gpio-keys";
-- #address-cells = <1>;
-- #size-cells = <0>;
-
- key-restart {
- label = "Reset";
diff --git a/target/linux/bcm53xx/patches-5.15/036-v6.5-0011-ARM-dts-BCM5301X-Relicense-Christian-s-code-to-the-G.patch b/target/linux/bcm53xx/patches-5.15/036-v6.5-0011-ARM-dts-BCM5301X-Relicense-Christian-s-code-to-the-G.patch
deleted file mode 100644
index 7496321269..0000000000
--- a/target/linux/bcm53xx/patches-5.15/036-v6.5-0011-ARM-dts-BCM5301X-Relicense-Christian-s-code-to-the-G.patch
+++ /dev/null
@@ -1,106 +0,0 @@
-From 1d5682ccc7d6088179b6cfd50a3e3bb6d2b0527e Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Mon, 5 Jun 2023 08:10:49 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Relicense Christian's code to the GPL
- 2.0+ / MIT
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Move code added by Christian to the bcm-ns.dtsi which uses dual
-licensing. That syncs more Northstar code to be based on the same
-licensing schema.
-
-Cc: Christian Lamparter <chunkeey@gmail.com>
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Acked-by: Christian Lamparter <chunkeey@gmail.com>
-Link: https://lore.kernel.org/r/20230605061049.16136-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/bcm-ns.dtsi | 21 +++++++++++++++++++++
- arch/arm/boot/dts/bcm5301x.dtsi | 23 -----------------------
- 2 files changed, 21 insertions(+), 23 deletions(-)
-
---- a/arch/arm/boot/dts/bcm-ns.dtsi
-+++ b/arch/arm/boot/dts/bcm-ns.dtsi
-@@ -182,6 +182,10 @@
- reg = <0x00013000 0x1000>;
- };
-
-+ pcie2: pcie@14000 {
-+ reg = <0x00014000 0x1000>;
-+ };
-+
- usb2: usb2@21000 {
- reg = <0x00021000 0x1000>;
-
-@@ -274,6 +278,14 @@
- };
- };
-
-+ pwm: pwm@18002000 {
-+ compatible = "brcm,iproc-pwm";
-+ reg = <0x18002000 0x28>;
-+ clocks = <&osc>;
-+ #pwm-cells = <3>;
-+ status = "disabled";
-+ };
-+
- mdio: mdio@18003000 {
- compatible = "brcm,iproc-mdio";
- reg = <0x18003000 0x8>;
-@@ -299,6 +311,15 @@
- };
- };
-
-+ uart2: serial@18008000 {
-+ compatible = "ns16550a";
-+ reg = <0x18008000 0x20>;
-+ clocks = <&iprocslow>;
-+ interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
-+ reg-shift = <2>;
-+ status = "disabled";
-+ };
-+
- dmu-bus@1800c000 {
- compatible = "simple-bus";
- ranges = <0 0x1800c000 0x1000>;
---- a/arch/arm/boot/dts/bcm5301x.dtsi
-+++ b/arch/arm/boot/dts/bcm5301x.dtsi
-@@ -69,20 +69,6 @@
- };
- };
-
-- axi@18000000 {
-- pcie2: pcie@14000 {
-- reg = <0x00014000 0x1000>;
-- };
-- };
--
-- pwm: pwm@18002000 {
-- compatible = "brcm,iproc-pwm";
-- reg = <0x18002000 0x28>;
-- clocks = <&osc>;
-- #pwm-cells = <3>;
-- status = "disabled";
-- };
--
- mdio-mux@18003000 {
- compatible = "mdio-mux-mmioreg", "mdio-mux";
- mdio-parent-bus = <&mdio>;
-@@ -110,15 +96,6 @@
- reg = <0x18105000 0x1000>;
- };
-
-- uart2: serial@18008000 {
-- compatible = "ns16550a";
-- reg = <0x18008000 0x20>;
-- clocks = <&iprocslow>;
-- interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
-- reg-shift = <2>;
-- status = "disabled";
-- };
--
- i2c0: i2c@18009000 {
- compatible = "brcm,iproc-i2c";
- reg = <0x18009000 0x50>;
diff --git a/target/linux/bcm53xx/patches-5.15/036-v6.5-0012-ARM-dts-BCM5301X-Describe-switch-ports-in-the-main-D.patch b/target/linux/bcm53xx/patches-5.15/036-v6.5-0012-ARM-dts-BCM5301X-Describe-switch-ports-in-the-main-D.patch
deleted file mode 100644
index fa2f21af53..0000000000
--- a/target/linux/bcm53xx/patches-5.15/036-v6.5-0012-ARM-dts-BCM5301X-Describe-switch-ports-in-the-main-D.patch
+++ /dev/null
@@ -1,838 +0,0 @@
-From ba4aebce23b2affb810b8a60eae853674d2cded2 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Mon, 5 Jun 2023 15:21:09 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Describe switch ports in the main DTS
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-All Northstar SoCs have BCM5301x switches (BCM53011, BCM53012) with 8
-ports (0-8 without 6). By design 3 switch ports (5, 7 and 8) are
-hardwired to 3 on-SoC Ethernet interfaces. Switch port 8 requires
-forcing link state.
-
-It seems that global Northstar .dtsi file is the best place to describe
-those hw details. Only device specific bits (like labels) should go to
-device .dts files.
-
-This seems to fit well with a tiny exception of Asus RT-AC88U which
-somehow was designed to have switch 5 connected to an extra switch. This
-case was simply handled with a /delete-property/.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Reviewed-by: Christian Lamparter <chunkeey@gmail.com> (MR32+MR26)
-Link: https://lore.kernel.org/r/20230605132109.7933-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/bcm-ns.dtsi | 41 ++++++++++++++++++-
- .../bcm4708-buffalo-wzr-1166dhp-common.dtsi | 7 ----
- arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts | 4 --
- arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts | 3 --
- arch/arm/boot/dts/bcm4708-netgear-r6250.dts | 7 ----
- arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts | 7 ----
- .../boot/dts/bcm47081-buffalo-wzr-600dhp2.dts | 7 ----
- arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts | 3 --
- arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts | 7 ----
- arch/arm/boot/dts/bcm4709-netgear-r8000.dts | 12 ------
- arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts | 17 +-------
- arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts | 12 ------
- arch/arm/boot/dts/bcm47094-dlink-dir-890l.dts | 12 ------
- .../boot/dts/bcm47094-linksys-panamera.dts | 34 ++++-----------
- arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts | 7 ----
- arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts | 4 --
- arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts | 7 ----
- arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts | 3 --
- arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts | 7 ----
- .../boot/dts/bcm47094-luxul-xwr-3150-v1.dts | 7 ----
- arch/arm/boot/dts/bcm53015-meraki-mr26.dts | 3 --
- arch/arm/boot/dts/bcm53016-meraki-mr32.dts | 3 --
- 22 files changed, 51 insertions(+), 163 deletions(-)
-
---- a/arch/arm/boot/dts/bcm-ns.dtsi
-+++ b/arch/arm/boot/dts/bcm-ns.dtsi
-@@ -304,10 +304,49 @@
-
- status = "disabled";
-
-- /* ports are defined in board DTS */
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-+
-+ port@0 {
-+ reg = <0>;
-+ };
-+
-+ port@1 {
-+ reg = <1>;
-+ };
-+
-+ port@2 {
-+ reg = <2>;
-+ };
-+
-+ port@3 {
-+ reg = <3>;
-+ };
-+
-+ port@4 {
-+ reg = <4>;
-+ };
-+
-+ port@5 {
-+ reg = <5>;
-+ ethernet = <&gmac0>;
-+ };
-+
-+ port@7 {
-+ reg = <7>;
-+ ethernet = <&gmac1>;
-+ };
-+
-+ port@8 {
-+ reg = <8>;
-+ ethernet = <&gmac2>;
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
-+ };
- };
- };
-
---- a/arch/arm/boot/dts/bcm4708-buffalo-wzr-1166dhp-common.dtsi
-+++ b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1166dhp-common.dtsi
-@@ -159,34 +159,27 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "lan1";
- };
-
- port@1 {
-- reg = <1>;
- label = "lan2";
- };
-
- port@2 {
-- reg = <2>;
- label = "lan3";
- };
-
- port@3 {
-- reg = <3>;
- label = "lan4";
- };
-
- port@4 {
-- reg = <4>;
- label = "wan";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts
-+++ b/arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts
-@@ -75,19 +75,15 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "poe";
- };
-
- port@4 {
-- reg = <4>;
- label = "lan";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts
-+++ b/arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts
-@@ -82,14 +82,11 @@
-
- ports {
- port@4 {
-- reg = <4>;
- label = "lan";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
-+++ b/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
-@@ -100,34 +100,27 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "lan4";
- };
-
- port@1 {
-- reg = <1>;
- label = "lan3";
- };
-
- port@2 {
-- reg = <2>;
- label = "lan2";
- };
-
- port@3 {
-- reg = <3>;
- label = "lan1";
- };
-
- port@4 {
-- reg = <4>;
- label = "wan";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts
-+++ b/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts
-@@ -123,34 +123,27 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "lan4";
- };
-
- port@1 {
-- reg = <1>;
- label = "lan3";
- };
-
- port@2 {
-- reg = <2>;
- label = "lan2";
- };
-
- port@3 {
-- reg = <3>;
- label = "lan1";
- };
-
- port@4 {
-- reg = <4>;
- label = "wan";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
-+++ b/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
-@@ -123,34 +123,27 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "lan1";
- };
-
- port@1 {
-- reg = <1>;
- label = "lan2";
- };
-
- port@2 {
-- reg = <2>;
- label = "lan3";
- };
-
- port@3 {
-- reg = <3>;
- label = "lan4";
- };
-
- port@4 {
-- reg = <4>;
- label = "wan";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts
-+++ b/arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts
-@@ -75,14 +75,11 @@
-
- ports {
- port@4 {
-- reg = <4>;
- label = "poe";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts
-+++ b/arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts
-@@ -124,36 +124,29 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "lan4";
- };
-
- port@1 {
-- reg = <1>;
- label = "lan3";
- };
-
- port@2 {
-- reg = <2>;
- label = "lan2";
- };
-
- port@3 {
-- reg = <3>;
- label = "lan1";
- };
-
- port@4 {
-- reg = <4>;
- label = "wan";
- nvmem-cells = <&et0macaddr 5>;
- nvmem-cell-names = "mac-address";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
-+++ b/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
-@@ -191,39 +191,27 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "lan1";
- };
-
- port@1 {
-- reg = <1>;
- label = "lan2";
- };
-
- port@2 {
-- reg = <2>;
- label = "lan3";
- };
-
- port@3 {
-- reg = <3>;
- label = "lan4";
- };
-
- port@4 {
-- reg = <4>;
- label = "wan";
- };
-
- port@8 {
-- reg = <8>;
- label = "cpu";
-- ethernet = <&gmac2>;
--
-- fixed-link {
-- speed = <1000>;
-- full-duplex;
-- };
- };
- };
- };
---- a/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-+++ b/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-@@ -181,32 +181,28 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "lan4";
- };
-
- port@1 {
-- reg = <1>;
- label = "lan3";
- };
-
- port@2 {
-- reg = <2>;
- label = "lan2";
- };
-
- port@3 {
-- reg = <3>;
- label = "lan1";
- };
-
- port@4 {
-- reg = <4>;
- label = "wan";
- };
-
- sw0_p5: port@5 {
-- reg = <5>;
-+ /delete-property/ethernet;
-+
- label = "extsw";
- phy-mode = "rgmii";
-
-@@ -218,8 +214,6 @@
- };
-
- port@7 {
-- reg = <7>;
-- ethernet = <&gmac1>;
- label = "cpu";
-
- fixed-link {
-@@ -229,14 +223,7 @@
- };
-
- port@8 {
-- reg = <8>;
-- ethernet = <&gmac2>;
- label = "cpu";
--
-- fixed-link {
-- speed = <1000>;
-- full-duplex;
-- };
- };
- };
- };
---- a/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts
-+++ b/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts
-@@ -124,39 +124,27 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "lan4";
- };
-
- port@1 {
-- reg = <1>;
- label = "lan3";
- };
-
- port@2 {
-- reg = <2>;
- label = "lan2";
- };
-
- port@3 {
-- reg = <3>;
- label = "lan1";
- };
-
- port@4 {
-- reg = <4>;
- label = "wan";
- };
-
- port@8 {
-- reg = <8>;
- label = "cpu";
-- ethernet = <&gmac2>;
--
-- fixed-link {
-- speed = <1000>;
-- full-duplex;
-- };
- };
- };
- };
---- a/arch/arm/boot/dts/bcm47094-dlink-dir-890l.dts
-+++ b/arch/arm/boot/dts/bcm47094-dlink-dir-890l.dts
-@@ -172,40 +172,28 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "lan1";
- };
-
- port@1 {
-- reg = <1>;
- label = "lan2";
- };
-
- port@2 {
-- reg = <2>;
- label = "lan3";
- };
-
- port@3 {
-- reg = <3>;
- label = "lan4";
- };
-
- port@4 {
-- reg = <4>;
- label = "wan";
- };
-
- port@8 {
-- reg = <8>;
- label = "cpu";
-- ethernet = <&gmac2>;
- phy-mode = "rgmii";
--
-- fixed-link {
-- speed = <1000>;
-- full-duplex;
-- };
- };
- };
- };
---- a/arch/arm/boot/dts/bcm47094-linksys-panamera.dts
-+++ b/arch/arm/boot/dts/bcm47094-linksys-panamera.dts
-@@ -207,29 +207,32 @@
- dsa,member = <0 0>;
-
- ports {
-+ sw0_p0: port@0 {
-+ label = "extsw";
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
-+ };
-+
- port@1 {
-- reg = <1>;
- label = "lan7";
- };
-
- port@2 {
-- reg = <2>;
- label = "lan4";
- };
-
- port@3 {
-- reg = <3>;
- label = "lan8";
- };
-
- port@4 {
-- reg = <4>;
- label = "wan";
- };
-
- port@5 {
-- reg = <5>;
-- ethernet = <&gmac0>;
- label = "cpu";
- status = "disabled";
-
-@@ -240,8 +243,6 @@
- };
-
- port@7 {
-- reg = <7>;
-- ethernet = <&gmac1>;
- label = "cpu";
- status = "disabled";
-
-@@ -252,24 +253,7 @@
- };
-
- port@8 {
-- reg = <8>;
-- ethernet = <&gmac2>;
- label = "cpu";
--
-- fixed-link {
-- speed = <1000>;
-- full-duplex;
-- };
-- };
--
-- sw0_p0: port@0 {
-- reg = <0>;
-- label = "extsw";
--
-- fixed-link {
-- speed = <1000>;
-- full-duplex;
-- };
- };
- };
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts
-@@ -83,36 +83,29 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "wan";
- nvmem-cells = <&et0macaddr 1>;
- nvmem-cell-names = "mac-address";
- };
-
- port@1 {
-- reg = <1>;
- label = "lan4";
- };
-
- port@2 {
-- reg = <2>;
- label = "lan3";
- };
-
- port@3 {
-- reg = <3>;
- label = "lan2";
- };
-
- port@4 {
-- reg = <4>;
- label = "lan1";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts
-@@ -73,19 +73,15 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "poe";
- };
-
- port@1 {
-- reg = <1>;
- label = "lan";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts
-@@ -83,36 +83,29 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "wan";
- nvmem-cells = <&et0macaddr 1>;
- nvmem-cell-names = "mac-address";
- };
-
- port@1 {
-- reg = <1>;
- label = "lan4";
- };
-
- port@2 {
-- reg = <2>;
- label = "lan3";
- };
-
- port@3 {
-- reg = <3>;
- label = "lan2";
- };
-
- port@4 {
-- reg = <4>;
- label = "lan1";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts
-@@ -69,14 +69,11 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "lan";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts
-@@ -123,36 +123,29 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "lan4";
- };
-
- port@1 {
-- reg = <1>;
- label = "lan3";
- };
-
- port@2 {
-- reg = <2>;
- label = "lan2";
- };
-
- port@3 {
-- reg = <3>;
- label = "lan1";
- };
-
- port@4 {
-- reg = <4>;
- label = "wan";
- nvmem-cells = <&et0macaddr 5>;
- nvmem-cell-names = "mac-address";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
-@@ -98,36 +98,29 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "lan4";
- };
-
- port@1 {
-- reg = <1>;
- label = "lan3";
- };
-
- port@2 {
-- reg = <2>;
- label = "lan2";
- };
-
- port@3 {
-- reg = <3>;
- label = "lan1";
- };
-
- port@4 {
-- reg = <4>;
- label = "wan";
- nvmem-cells = <&et0macaddr 5>;
- nvmem-cell-names = "mac-address";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm53015-meraki-mr26.dts
-+++ b/arch/arm/boot/dts/bcm53015-meraki-mr26.dts
-@@ -115,14 +115,11 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "poe";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
-
- fixed-link {
- speed = <1000>;
---- a/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-+++ b/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-@@ -176,14 +176,11 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "poe";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
-
- fixed-link {
- speed = <1000>;
diff --git a/target/linux/bcm53xx/patches-5.15/036-v6.5-0013-ARM-dts-BCM5301X-MR26-MR32-remove-bogus-nand-ecc-alg.patch b/target/linux/bcm53xx/patches-5.15/036-v6.5-0013-ARM-dts-BCM5301X-MR26-MR32-remove-bogus-nand-ecc-alg.patch
deleted file mode 100644
index ea571f459a..0000000000
--- a/target/linux/bcm53xx/patches-5.15/036-v6.5-0013-ARM-dts-BCM5301X-MR26-MR32-remove-bogus-nand-ecc-alg.patch
+++ /dev/null
@@ -1,63 +0,0 @@
-From a6a1a156f5debaebf9f61850d111b966e9be9ee9 Mon Sep 17 00:00:00 2001
-From: Christian Lamparter <chunkeey@gmail.com>
-Date: Thu, 8 Jun 2023 17:36:27 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: MR26: MR32: remove bogus nand-ecc-algo
- property
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-| bcm53015-meraki-mr26.dtb: nand-controller@18028000:
-| nand@0:nand-ecc-algo:0: 'hw' is not one of ['hamming', 'bch', 'rs']
-| From schema: Documentation/[...]/nand-controller.yaml
-| bcm53016-meraki-mr32.dtb: nand-controller@18028000:
-| nand@0:nand-ecc-algo:0: 'hw' is not one of ['hamming', 'bch', 'rs']
-| From schema: Documentation/[...]/nand-controller.yaml
-
-original ECC values for these old Merakis are sadly not
-provided by the vendor. It looks like Meraki just stuck
-with what Broadcom's SDK was doing... which left this
-up to the proprietary nand driver.
-
-Note: The invalid setting was and is handled by brcmnand. It
-falls back to "bch" in brcmnand_setup_dev() when ecc.algo is
-set to NAND_ECC_ALGO_UNKNOWN (since "hw" is not in the list
-above).
-
-A correct nand-ecc-algo = "bch"; is already specified in the
-included "bcm5301x-nand-cs0-bch8.dtsi". So this line can be
-dropped.
-
-Reported-by: Rafał Miłecki <zajec5@gmail.com> (per Mail)
-Fixes: 935327a73553 ("ARM: dts: BCM5301X: Add DT for Meraki MR26")
-Fixes: ec88a9c344d9 ("ARM: BCM5301X: Add DT for Meraki MR32")
-Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
-Link: https://lore.kernel.org/r/2c4d00dd40124c2ddc0b139cbce7531b108f9052.1686238550.git.chunkeey@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/bcm53015-meraki-mr26.dts | 2 --
- arch/arm/boot/dts/bcm53016-meraki-mr32.dts | 2 --
- 2 files changed, 4 deletions(-)
-
---- a/arch/arm/boot/dts/bcm53015-meraki-mr26.dts
-+++ b/arch/arm/boot/dts/bcm53015-meraki-mr26.dts
-@@ -72,8 +72,6 @@
- };
-
- &nandcs {
-- nand-ecc-algo = "hw";
--
- partitions {
- compatible = "fixed-partitions";
- #address-cells = <0x1>;
---- a/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-+++ b/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-@@ -125,8 +125,6 @@
- };
-
- &nandcs {
-- nand-ecc-algo = "hw";
--
- partitions {
- /*
- * The partition autodetection does not work for this device.
diff --git a/target/linux/bcm53xx/patches-5.15/036-v6.5-0014-ARM-dts-BCM5301X-MR32-remove-partition-index-numbers.patch b/target/linux/bcm53xx/patches-5.15/036-v6.5-0014-ARM-dts-BCM5301X-MR32-remove-partition-index-numbers.patch
deleted file mode 100644
index 8eb5442d17..0000000000
--- a/target/linux/bcm53xx/patches-5.15/036-v6.5-0014-ARM-dts-BCM5301X-MR32-remove-partition-index-numbers.patch
+++ /dev/null
@@ -1,54 +0,0 @@
-From d68b2f7d7d06872450d4f39d84d5926d7e7ae88c Mon Sep 17 00:00:00 2001
-From: Christian Lamparter <chunkeey@gmail.com>
-Date: Thu, 8 Jun 2023 17:36:28 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: MR32: remove partition index numbers
-
-removes the partition indexes in the node names under.
-This brings the device tree source in line with others.
-
-Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
-Link: https://lore.kernel.org/r/627f57d568030a56499361790524b4d4f3381619.1686238550.git.chunkeey@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/bcm53016-meraki-mr32.dts | 10 +++++-----
- 1 file changed, 5 insertions(+), 5 deletions(-)
-
---- a/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-+++ b/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-@@ -138,31 +138,31 @@
- #address-cells = <0x1>;
- #size-cells = <0x1>;
-
-- partition0@0 {
-+ partition@0 {
- label = "u-boot";
- reg = <0x0 0x100000>;
- read-only;
- };
-
-- partition1@100000 {
-+ partition@100000 {
- label = "bootkernel1";
- reg = <0x100000 0x300000>;
- read-only;
- };
-
-- partition2@400000 {
-+ partition@400000 {
- label = "nvram";
- reg = <0x400000 0x100000>;
- read-only;
- };
-
-- partition3@500000 {
-+ partition@500000 {
- label = "bootkernel2";
- reg = <0x500000 0x300000>;
- read-only;
- };
-
-- partition4@800000 {
-+ partition@800000 {
- label = "ubi";
- reg = <0x800000 0x7780000>;
- };
diff --git a/target/linux/bcm53xx/patches-5.15/036-v6.5-0016-ARM-dts-BCM5301X-Add-Netgear-R8000-WiFi-regulator-ma.patch b/target/linux/bcm53xx/patches-5.15/036-v6.5-0016-ARM-dts-BCM5301X-Add-Netgear-R8000-WiFi-regulator-ma.patch
deleted file mode 100644
index 3ffe0b2f17..0000000000
--- a/target/linux/bcm53xx/patches-5.15/036-v6.5-0016-ARM-dts-BCM5301X-Add-Netgear-R8000-WiFi-regulator-ma.patch
+++ /dev/null
@@ -1,61 +0,0 @@
-From 752a63b8dbe6cc6900efd1035bea427a778a4b55 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 2 Jun 2023 15:59:25 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Add Netgear R8000 WiFi regulator mappings
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This allows setting FullMAC firmware regulatory domain.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230602135925.14143-3-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/bcm4709-netgear-r8000.dts | 17 +++++++++++++++++
- 1 file changed, 17 insertions(+)
-
---- a/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
-+++ b/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
-@@ -137,8 +137,10 @@
- #size-cells = <2>;
-
- wifi@0,1,0 {
-+ compatible = "brcm,bcm4366-fmac", "brcm,bcm4329-fmac";
- reg = <0x0000 0 0 0 0>;
- ieee80211-freq-limit = <5735000 5835000>;
-+ brcm,ccode-map = "JP-JP-78", "US-Q2-86";
- };
- };
- };
-@@ -159,6 +161,19 @@
- #address-cells = <3>;
- #size-cells = <2>;
-
-+ bridge@1,0 {
-+ reg = <0x800 0 0 0 0>;
-+
-+ #address-cells = <3>;
-+ #size-cells = <2>;
-+
-+ wifi@0,0 {
-+ compatible = "brcm,bcm4366-fmac", "brcm,bcm4329-fmac";
-+ reg = <0x0000 0 0 0 0>;
-+ brcm,ccode-map = "JP-JP-78", "US-Q2-86";
-+ };
-+ };
-+
- bridge@1,2,2 {
- reg = <0x1000 0 0 0 0>;
-
-@@ -166,8 +181,10 @@
- #size-cells = <2>;
-
- wifi@1,4,0 {
-+ compatible = "brcm,bcm4366-fmac", "brcm,bcm4329-fmac";
- reg = <0x0000 0 0 0 0>;
- ieee80211-freq-limit = <5170000 5730000>;
-+ brcm,ccode-map = "JP-JP-78", "US-Q2-86";
- };
- };
- };
diff --git a/target/linux/bcm53xx/patches-5.15/036-v6.5-0017-ARM-dts-BCM5301X-Add-cells-sizes-to-PCIe-nodes.patch b/target/linux/bcm53xx/patches-5.15/036-v6.5-0017-ARM-dts-BCM5301X-Add-cells-sizes-to-PCIe-nodes.patch
deleted file mode 100644
index 454ce4c278..0000000000
--- a/target/linux/bcm53xx/patches-5.15/036-v6.5-0017-ARM-dts-BCM5301X-Add-cells-sizes-to-PCIe-nodes.patch
+++ /dev/null
@@ -1,59 +0,0 @@
-From b67cad33176e472df6d16a24ee7624299bdcd5d5 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 16 Jun 2023 12:58:27 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Add cells sizes to PCIe nodes
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This fixes:
-arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dtb: pcie@12000: '#address-cells' is a required property
- From schema: /lib/python3.10/site-packages/dtschema/schemas/pci/pci-bus.yaml
-arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dtb: pcie@12000: '#size-cells' is a required property
- From schema: /lib/python3.10/site-packages/dtschema/schemas/pci/pci-bus.yaml
-arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dtb: pcie@13000: '#address-cells' is a required property
- From schema: /lib/python3.10/site-packages/dtschema/schemas/pci/pci-bus.yaml
-arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dtb: pcie@13000: '#size-cells' is a required property
- From schema: /lib/python3.10/site-packages/dtschema/schemas/pci/pci-bus.yaml
-arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dtb: pcie@14000: '#address-cells' is a required property
- From schema: /lib/python3.10/site-packages/dtschema/schemas/pci/pci-bus.yaml
-arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dtb: pcie@14000: '#size-cells' is a required property
- From schema: /lib/python3.10/site-packages/dtschema/schemas/pci/pci-bus.yaml
-
-Two properties that need to be added later are "device_type" and
-"ranges". Adding "device_type" on its own causes a new warning and the
-value of "ranges" needs to be determined yet.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230616105827.21656-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/bcm-ns.dtsi | 9 +++++++++
- 1 file changed, 9 insertions(+)
-
---- a/arch/arm/boot/dts/bcm-ns.dtsi
-+++ b/arch/arm/boot/dts/bcm-ns.dtsi
-@@ -176,14 +176,23 @@
-
- pcie0: pcie@12000 {
- reg = <0x00012000 0x1000>;
-+
-+ #address-cells = <3>;
-+ #size-cells = <2>;
- };
-
- pcie1: pcie@13000 {
- reg = <0x00013000 0x1000>;
-+
-+ #address-cells = <3>;
-+ #size-cells = <2>;
- };
-
- pcie2: pcie@14000 {
- reg = <0x00014000 0x1000>;
-+
-+ #address-cells = <3>;
-+ #size-cells = <2>;
- };
-
- usb2: usb2@21000 {
diff --git a/target/linux/bcm53xx/patches-5.15/037-v6.6-0001-ARM-dts-broadcom-add-missing-space-before.patch b/target/linux/bcm53xx/patches-5.15/037-v6.6-0001-ARM-dts-broadcom-add-missing-space-before.patch
deleted file mode 100644
index 9811757ee2..0000000000
--- a/target/linux/bcm53xx/patches-5.15/037-v6.6-0001-ARM-dts-broadcom-add-missing-space-before.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From 4b8e16de053fc88eac406ad63da2693dd8279043 Mon Sep 17 00:00:00 2001
-From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Date: Wed, 5 Jul 2023 17:01:07 +0200
-Subject: [PATCH] ARM: dts: broadcom: add missing space before {
-
-Add missing whitespace between node name/label and opening {.
-
-Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Link: https://lore.kernel.org/r/20230705150108.293999-1-krzysztof.kozlowski@linaro.org
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/broadcom/bcm47094-linksys-panamera.dts | 2 +-
- arch/arm/boot/dts/broadcom/bcm47094-phicomm-k3.dts | 2 +-
- 2 files changed, 2 insertions(+), 2 deletions(-)
-
---- a/arch/arm/boot/dts/bcm47094-linksys-panamera.dts
-+++ b/arch/arm/boot/dts/bcm47094-linksys-panamera.dts
-@@ -279,7 +279,7 @@
- reg = <0x080000 0x0100000>;
- };
-
-- partition@180000{
-+ partition@180000 {
- label = "devinfo";
- reg = <0x0180000 0x080000>;
- };
---- a/arch/arm/boot/dts/bcm47094-phicomm-k3.dts
-+++ b/arch/arm/boot/dts/bcm47094-phicomm-k3.dts
-@@ -55,7 +55,7 @@
- reg = <0x0080000 0x0100000>;
- };
-
-- partition@180000{
-+ partition@180000 {
- label = "phicomm";
- reg = <0x0180000 0x0280000>;
- read-only;
diff --git a/target/linux/bcm53xx/patches-5.15/037-v6.6-0002-ARM-dts-BCM5301X-Add-Wi-Fi-regulatory-mappings-for-L.patch b/target/linux/bcm53xx/patches-5.15/037-v6.6-0002-ARM-dts-BCM5301X-Add-Wi-Fi-regulatory-mappings-for-L.patch
deleted file mode 100644
index e5143abf58..0000000000
--- a/target/linux/bcm53xx/patches-5.15/037-v6.6-0002-ARM-dts-BCM5301X-Add-Wi-Fi-regulatory-mappings-for-L.patch
+++ /dev/null
@@ -1,107 +0,0 @@
-From 8960f095de3b80beb3639075f0c8161b6ea98c61 Mon Sep 17 00:00:00 2001
-From: Dan Haab <dan.haab@luxul.com>
-Date: Wed, 5 Jul 2023 09:32:51 -0600
-Subject: [PATCH] ARM: dts: BCM5301X: Add Wi-Fi regulatory mappings for Luxul
- devices
-
-This allows setting FullMAC firmware regulatory domain.
-
-Signed-off-by: Dan Haab <dan.haab@luxul.com>
-Link: https://lore.kernel.org/r/20230705153251.739236-1-riproute@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- .../dts/broadcom/bcm47094-luxul-xap-1610.dts | 37 +++++++++++++++++++
- .../broadcom/bcm47094-luxul-xwr-3150-v1.dts | 36 ++++++++++++++++++
- 2 files changed, 73 insertions(+)
-
---- a/arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts
-@@ -64,6 +64,43 @@
- nvmem-cell-names = "mac-address";
- };
-
-+
-+&pcie0 {
-+ #address-cells = <3>;
-+ #size-cells = <2>;
-+
-+ bridge@0,0 {
-+ reg = <0x0000 0 0 0 0>;
-+
-+ #address-cells = <3>;
-+ #size-cells = <2>;
-+
-+ wifi@0,0 {
-+ compatible = "brcm,bcm4366-fmac", "brcm,bcm4329-fmac";
-+ reg = <0x0000 0 0 0 0>;
-+ brcm,ccode-map = "AU-AU-920", "CA-CA-892", "GB-DE-964", "NZ-AU-920", "US-US-825";
-+ };
-+ };
-+};
-+
-+&pcie1 {
-+ #address-cells = <3>;
-+ #size-cells = <2>;
-+
-+ bridge@0,0 {
-+ reg = <0x0000 0 0 0 0>;
-+
-+ #address-cells = <3>;
-+ #size-cells = <2>;
-+
-+ wifi@0,0 {
-+ compatible = "brcm,bcm4366-fmac", "brcm,bcm4329-fmac";
-+ reg = <0x0000 0 0 0 0>;
-+ brcm,ccode-map = "AU-AU-920", "CA-CA-892", "GB-DE-964", "NZ-AU-920", "US-US-825";
-+ };
-+ };
-+};
-+
- &spi_nor {
- status = "okay";
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
-@@ -81,6 +81,42 @@
- nvmem-cell-names = "mac-address";
- };
-
-+&pcie0 {
-+ #address-cells = <3>;
-+ #size-cells = <2>;
-+
-+ bridge@0,0 {
-+ reg = <0x0000 0 0 0 0>;
-+
-+ #address-cells = <3>;
-+ #size-cells = <2>;
-+
-+ wifi@0,0 {
-+ compatible = "brcm,bcm4366-fmac", "brcm,bcm4329-fmac";
-+ reg = <0x0000 0 0 0 0>;
-+ brcm,ccode-map = "AU-AU-953", "CA-CA-946", "GB-E0-846", "NZ-AU-953", "US-Q2-930";
-+ };
-+ };
-+};
-+
-+&pcie1 {
-+ #address-cells = <3>;
-+ #size-cells = <2>;
-+
-+ bridge@0,0 {
-+ reg = <0x0000 0 0 0 0>;
-+
-+ #address-cells = <3>;
-+ #size-cells = <2>;
-+
-+ wifi@0,0 {
-+ compatible = "brcm,bcm4366-fmac", "brcm,bcm4329-fmac";
-+ reg = <0x0000 0 0 0 0>;
-+ brcm,ccode-map = "AU-AU-953", "CA-CA-946", "GB-E0-846", "NZ-AU-953", "US-Q2-930";
-+ };
-+ };
-+};
-+
- &usb3 {
- vcc-gpio = <&chipcommon 18 GPIO_ACTIVE_HIGH>;
- };
diff --git a/target/linux/bcm53xx/patches-5.15/037-v6.6-0003-ARM-dts-BCM5301X-Add-Ethernet-interfaces-links.patch b/target/linux/bcm53xx/patches-5.15/037-v6.6-0003-ARM-dts-BCM5301X-Add-Ethernet-interfaces-links.patch
deleted file mode 100644
index 4b2e608ec2..0000000000
--- a/target/linux/bcm53xx/patches-5.15/037-v6.6-0003-ARM-dts-BCM5301X-Add-Ethernet-interfaces-links.patch
+++ /dev/null
@@ -1,53 +0,0 @@
-From 2ce61fa62183cf994666fcc911da34075c7183b5 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 7 Jul 2023 11:15:19 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Add Ethernet interfaces links
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Northstar SoCs have 3 usable Ethernet interfaces each connected to one
-of switch ports. They all use fixed links.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230707091519.21673-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/broadcom/bcm-ns.dtsi | 18 ++++++++++++++++++
- 1 file changed, 18 insertions(+)
-
---- a/arch/arm/boot/dts/bcm-ns.dtsi
-+++ b/arch/arm/boot/dts/bcm-ns.dtsi
-@@ -272,14 +272,32 @@
-
- gmac0: ethernet@24000 {
- reg = <0x24000 0x800>;
-+ phy-mode = "internal";
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
- };
-
- gmac1: ethernet@25000 {
- reg = <0x25000 0x800>;
-+ phy-mode = "internal";
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
- };
-
- gmac2: ethernet@26000 {
- reg = <0x26000 0x800>;
-+ phy-mode = "internal";
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
- };
-
- gmac3: ethernet@27000 {
diff --git a/target/linux/bcm53xx/patches-5.15/037-v6.6-0009-ARM-dts-BCM53573-Fix-Ethernet-info-for-Luxul-devices.patch b/target/linux/bcm53xx/patches-5.15/037-v6.6-0009-ARM-dts-BCM53573-Fix-Ethernet-info-for-Luxul-devices.patch
deleted file mode 100644
index 7930c52b16..0000000000
--- a/target/linux/bcm53xx/patches-5.15/037-v6.6-0009-ARM-dts-BCM53573-Fix-Ethernet-info-for-Luxul-devices.patch
+++ /dev/null
@@ -1,75 +0,0 @@
-From 44ad8207806973f4e4f7d870fff36cc01f494250 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Thu, 13 Jul 2023 13:11:45 +0200
-Subject: [PATCH] ARM: dts: BCM53573: Fix Ethernet info for Luxul devices
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Both Luxul's XAP devices (XAP-810 and XAP-1440) are access points that
-use a non-default design. They don't include switch but have a single
-Ethernet port and BCM54210E PHY connected to the Ethernet controller's
-MDIO bus.
-
-Support for those devices regressed due to two changes:
-
-1. Describing MDIO bus with switch
-After commit 9fb90ae6cae7 ("ARM: dts: BCM53573: Describe on-SoC BCM53125
-rev 4 switch") Linux stopped probing for MDIO devices.
-
-2. Dropping hardcoded BCM54210E delays
-In commit fea7fda7f50a ("net: phy: broadcom: Fix RGMII delays
-configuration for BCM54210E") support for other PHY modes was added but
-that requires a proper "phy-mode" value in DT.
-
-Both above changes are correct (they don't need to be reverted or
-anything) but they need this fix for DT data to be correct and for Linux
-to work properly.
-
-Fixes: 9fb90ae6cae7 ("ARM: dts: BCM53573: Describe on-SoC BCM53125 rev 4 switch")
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230713111145.14864-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- .../boot/dts/broadcom/bcm47189-luxul-xap-1440.dts | 13 +++++++++++++
- .../boot/dts/broadcom/bcm47189-luxul-xap-810.dts | 13 +++++++++++++
- 2 files changed, 26 insertions(+)
-
---- a/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts
-+++ b/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts
-@@ -58,3 +58,16 @@
- };
- };
- };
-+
-+&gmac0 {
-+ phy-mode = "rgmii";
-+ phy-handle = <&bcm54210e>;
-+
-+ mdio {
-+ /delete-node/ switch@1e;
-+
-+ bcm54210e: ethernet-phy@0 {
-+ reg = <0>;
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts
-+++ b/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts
-@@ -94,3 +94,16 @@
- };
- };
- };
-+
-+&gmac0 {
-+ phy-mode = "rgmii";
-+ phy-handle = <&bcm54210e>;
-+
-+ mdio {
-+ /delete-node/ switch@1e;
-+
-+ bcm54210e: ethernet-phy@0 {
-+ reg = <0>;
-+ };
-+ };
-+};
diff --git a/target/linux/bcm53xx/patches-5.15/037-v6.6-0010-ARM-dts-bcm5301x-Add-SEAMA-compatibles.patch b/target/linux/bcm53xx/patches-5.15/037-v6.6-0010-ARM-dts-bcm5301x-Add-SEAMA-compatibles.patch
deleted file mode 100644
index f23873e111..0000000000
--- a/target/linux/bcm53xx/patches-5.15/037-v6.6-0010-ARM-dts-bcm5301x-Add-SEAMA-compatibles.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From 72ec77d74d28be7359ef77971cdee38b60af9e49 Mon Sep 17 00:00:00 2001
-From: Linus Walleij <linus.walleij@linaro.org>
-Date: Thu, 13 Jul 2023 00:16:42 +0200
-Subject: [PATCH] ARM: dts: bcm5301x: Add SEAMA compatibles
-
-This adds SEAMA compatibles to the firmware partition of these
-two D-Link devices.
-
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-Link: https://lore.kernel.org/r/20230713-seama-partitions-v4-2-69e577453d40@linaro.org
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/broadcom/bcm47094-dlink-dir-885l.dts | 1 +
- arch/arm/boot/dts/broadcom/bcm47094-dlink-dir-890l.dts | 1 +
- 2 files changed, 2 insertions(+)
-
---- a/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts
-+++ b/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts
-@@ -33,6 +33,7 @@
- #size-cells = <1>;
-
- partition@0 {
-+ compatible = "seama";
- label = "firmware";
- reg = <0x00000000 0x08000000>;
- };
---- a/arch/arm/boot/dts/bcm47094-dlink-dir-890l.dts
-+++ b/arch/arm/boot/dts/bcm47094-dlink-dir-890l.dts
-@@ -149,6 +149,7 @@
- * partitions: this device uses SEAMA.
- */
- firmware@0 {
-+ compatible = "seama";
- label = "firmware";
- reg = <0x00000000 0x08000000>;
- };
diff --git a/target/linux/bcm53xx/patches-5.15/037-v6.6-0011-ARM-dts-BCM53573-Fix-Tenda-AC9-switch-CPU-port.patch b/target/linux/bcm53xx/patches-5.15/037-v6.6-0011-ARM-dts-BCM53573-Fix-Tenda-AC9-switch-CPU-port.patch
deleted file mode 100644
index d5cb817e8e..0000000000
--- a/target/linux/bcm53xx/patches-5.15/037-v6.6-0011-ARM-dts-BCM53573-Fix-Tenda-AC9-switch-CPU-port.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From 7141209db9c335ab261a17933809a3e660ebdc12 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Sun, 23 Jul 2023 21:54:14 +0200
-Subject: [PATCH] ARM: dts: BCM53573: Fix Tenda AC9 switch CPU port
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Primary Ethernet interface is connected to the port 8 (not 5).
-
-Fixes: 64612828628c ("ARM: dts: BCM53573: Add Tenda AC9 switch ports")
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230723195416.7831-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/broadcom/bcm47189-tenda-ac9.dts | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/arch/arm/boot/dts/bcm47189-tenda-ac9.dts
-+++ b/arch/arm/boot/dts/bcm47189-tenda-ac9.dts
-@@ -135,8 +135,8 @@
- label = "lan4";
- };
-
-- port@5 {
-- reg = <5>;
-+ port@8 {
-+ reg = <8>;
- label = "cpu";
- ethernet = <&gmac0>;
- };
diff --git a/target/linux/bcm53xx/patches-5.15/037-v6.6-0012-ARM-dts-BCM53573-Describe-BCM53125-switch-ports-in-t.patch b/target/linux/bcm53xx/patches-5.15/037-v6.6-0012-ARM-dts-BCM53573-Describe-BCM53125-switch-ports-in-t.patch
deleted file mode 100644
index ab27495078..0000000000
--- a/target/linux/bcm53xx/patches-5.15/037-v6.6-0012-ARM-dts-BCM53573-Describe-BCM53125-switch-ports-in-t.patch
+++ /dev/null
@@ -1,97 +0,0 @@
-From 8d6b61ecad2f1c939813c5c4517d53e04672dc48 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Sun, 23 Jul 2023 21:54:15 +0200
-Subject: [PATCH] ARM: dts: BCM53573: Describe BCM53125 switch ports in the
- main DTS
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-BCM53125 always has 5 ports with GPHYs (for LAN/WAN ports) and 2 IMP
-ports. It seems the best place to describe that in the main .dtsi.
-Device specific bits can go to device .dts files. This will help
-avoiding some code duplication.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230723195416.7831-2-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- .../boot/dts/broadcom/bcm47189-tenda-ac9.dts | 7 -----
- arch/arm/boot/dts/broadcom/bcm53573.dtsi | 26 ++++++++++++++++++-
- 2 files changed, 25 insertions(+), 8 deletions(-)
-
---- a/arch/arm/boot/dts/bcm47189-tenda-ac9.dts
-+++ b/arch/arm/boot/dts/bcm47189-tenda-ac9.dts
-@@ -111,34 +111,27 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "wan";
- };
-
- port@1 {
-- reg = <1>;
- label = "lan1";
- };
-
- port@2 {
-- reg = <2>;
- label = "lan2";
- };
-
- port@3 {
-- reg = <3>;
- label = "lan3";
- };
-
- port@4 {
-- reg = <4>;
- label = "lan4";
- };
-
- port@8 {
-- reg = <8>;
- label = "cpu";
-- ethernet = <&gmac0>;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm53573.dtsi
-+++ b/arch/arm/boot/dts/bcm53573.dtsi
-@@ -192,10 +192,34 @@
-
- status = "disabled";
-
-- /* ports are defined in board DTS */
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-+
-+ port@0 {
-+ reg = <0>;
-+ };
-+
-+ port@1 {
-+ reg = <1>;
-+ };
-+
-+ port@2 {
-+ reg = <2>;
-+ };
-+
-+ port@3 {
-+ reg = <3>;
-+ };
-+
-+ port@4 {
-+ reg = <4>;
-+ };
-+
-+ port@8 {
-+ reg = <8>;
-+ ethernet = <&gmac0>;
-+ };
- };
- };
- };
diff --git a/target/linux/bcm53xx/patches-5.15/037-v6.6-0013-ARM-dts-BCM53573-Add-BCM53125-switch-port-5.patch b/target/linux/bcm53xx/patches-5.15/037-v6.6-0013-ARM-dts-BCM53573-Add-BCM53125-switch-port-5.patch
deleted file mode 100644
index cc9e86ac75..0000000000
--- a/target/linux/bcm53xx/patches-5.15/037-v6.6-0013-ARM-dts-BCM53573-Add-BCM53125-switch-port-5.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From d95b1caeea194962220db1778ce7fe71cdba788b Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Sun, 23 Jul 2023 21:54:16 +0200
-Subject: [PATCH] ARM: dts: BCM53573: Add BCM53125 switch port 5
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-It's connected to the extra Ethernet interface.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230723195416.7831-3-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/broadcom/bcm53573.dtsi | 10 ++++++++++
- 1 file changed, 10 insertions(+)
-
---- a/arch/arm/boot/dts/bcm53573.dtsi
-+++ b/arch/arm/boot/dts/bcm53573.dtsi
-@@ -216,6 +216,16 @@
- reg = <4>;
- };
-
-+ port@5 {
-+ reg = <5>;
-+ ethernet = <&gmac1>;
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
-+ };
-+
- port@8 {
- reg = <8>;
- ethernet = <&gmac0>;
diff --git a/target/linux/bcm53xx/patches-5.15/037-v6.6-0014-ARM-dts-BCM53573-Add-Ethernet-interfaces-links.patch b/target/linux/bcm53xx/patches-5.15/037-v6.6-0014-ARM-dts-BCM53573-Add-Ethernet-interfaces-links.patch
deleted file mode 100644
index f97d4edd75..0000000000
--- a/target/linux/bcm53xx/patches-5.15/037-v6.6-0014-ARM-dts-BCM53573-Add-Ethernet-interfaces-links.patch
+++ /dev/null
@@ -1,73 +0,0 @@
-From e0ae343a2c1b782a346d9b844ea65e1d49c428b2 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Mon, 24 Jul 2023 12:12:27 +0200
-Subject: [PATCH] ARM: dts: BCM53573: Add Ethernet interfaces links
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-BCM53573 has 2 Ethernet interfaces each connected to one of switch ports
-in the default design. They both use fixed links.
-
-An exception are Luxul XAP devices that have switch replaced by a single
-PHY.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230724101227.5420-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- .../boot/dts/broadcom/bcm47189-luxul-xap-1440.dts | 2 ++
- .../arm/boot/dts/broadcom/bcm47189-luxul-xap-810.dts | 2 ++
- arch/arm/boot/dts/broadcom/bcm53573.dtsi | 12 ++++++++++++
- 3 files changed, 16 insertions(+)
-
---- a/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts
-+++ b/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts
-@@ -50,6 +50,8 @@
- phy-mode = "rgmii";
- phy-handle = <&bcm54210e>;
-
-+ /delete-node/ fixed-link;
-+
- mdio {
- /delete-node/ switch@1e;
-
---- a/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts
-+++ b/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts
-@@ -86,6 +86,8 @@
- phy-mode = "rgmii";
- phy-handle = <&bcm54210e>;
-
-+ /delete-node/ fixed-link;
-+
- mdio {
- /delete-node/ switch@1e;
-
---- a/arch/arm/boot/dts/bcm53573.dtsi
-+++ b/arch/arm/boot/dts/bcm53573.dtsi
-@@ -181,6 +181,12 @@
-
- gmac0: ethernet@5000 {
- reg = <0x5000 0x1000>;
-+ phy-mode = "internal";
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
-
- mdio {
- #address-cells = <1>;
-@@ -237,6 +243,12 @@
-
- gmac1: ethernet@b000 {
- reg = <0xb000 0x1000>;
-+ phy-mode = "internal";
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
- };
-
- pmu@12000 {
diff --git a/target/linux/bcm53xx/patches-5.15/037-v6.6-0015-ARM-dts-BCM53573-Disable-second-Ethernet-on-Luxul-de.patch b/target/linux/bcm53xx/patches-5.15/037-v6.6-0015-ARM-dts-BCM53573-Disable-second-Ethernet-on-Luxul-de.patch
deleted file mode 100644
index e9e347075d..0000000000
--- a/target/linux/bcm53xx/patches-5.15/037-v6.6-0015-ARM-dts-BCM53573-Disable-second-Ethernet-on-Luxul-de.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-From d8835601e3c306fda78f8736f1aef688e99e892d Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Mon, 24 Jul 2023 12:11:59 +0200
-Subject: [PATCH] ARM: dts: BCM53573: Disable second Ethernet on Luxul devices
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-XAP-810 and XAP-1440 both have a single Ethernet port and BCM54210E PHY.
-Their second Ethernet interface is not connected to anything.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230724101159.5289-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/broadcom/bcm47189-luxul-xap-1440.dts | 4 ++++
- arch/arm/boot/dts/broadcom/bcm47189-luxul-xap-810.dts | 4 ++++
- 2 files changed, 8 insertions(+)
-
---- a/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts
-+++ b/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts
-@@ -73,3 +73,7 @@
- };
- };
- };
-+
-+&gmac1 {
-+ status = "disabled";
-+};
---- a/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts
-+++ b/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts
-@@ -109,3 +109,7 @@
- };
- };
- };
-+
-+&gmac1 {
-+ status = "disabled";
-+};
diff --git a/target/linux/bcm53xx/patches-5.15/037-v6.6-0016-ARM-dts-BCM5301X-Add-DT-for-Asus-RT-AC3100.patch b/target/linux/bcm53xx/patches-5.15/037-v6.6-0016-ARM-dts-BCM5301X-Add-DT-for-Asus-RT-AC3100.patch
deleted file mode 100644
index 6c2af02589..0000000000
--- a/target/linux/bcm53xx/patches-5.15/037-v6.6-0016-ARM-dts-BCM5301X-Add-DT-for-Asus-RT-AC3100.patch
+++ /dev/null
@@ -1,431 +0,0 @@
-From 2900083269f7c0f0ff430bffc6ced2038aed9b6b Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Thu, 3 Aug 2023 10:14:54 +0300
-Subject: [PATCH] ARM: dts: BCM5301X: Add DT for ASUS RT-AC3100
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-ASUS RT-AC3100 is ASUS RT-AC88U without the external switch. Move the
-shared bindings to bcm47094-asus-rt-ac3100.dtsi.
-
-Remove the fixed-link node on port@7 as commit ba4aebce23b2 ("ARM: dts:
-BCM5301X: Describe switch ports in the main DTS") states it's not
-necessary.
-
-Replace the copyright notice with an author notice.
-
-Rename the model name from Asus to ASUS on bcm47094-asus-rt-ac88u.dts.
-
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
-Link: https://lore.kernel.org/r/20230803071454.5902-2-arinc.unal@arinc9.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/Makefile | 1 +
- .../dts/bcm47094-asus-rt-ac3100.dts | 23 +++
- .../dts/bcm47094-asus-rt-ac3100.dtsi | 163 ++++++++++++++++++
- .../dts/bcm47094-asus-rt-ac88u.dts | 155 +----------------
- 4 files changed, 190 insertions(+), 152 deletions(-)
- create mode 100644 arch/arm/boot/dts/bcm47094-asus-rt-ac3100.dts
- create mode 100644 arch/arm/boot/dts/bcm47094-asus-rt-ac3100.dtsi
-
---- a/arch/arm/boot/dts/Makefile
-+++ b/arch/arm/boot/dts/Makefile
-@@ -119,6 +119,7 @@ dtb-$(CONFIG_ARCH_BCM_5301X) += \
- bcm4709-netgear-r7000.dtb \
- bcm4709-netgear-r8000.dtb \
- bcm4709-tplink-archer-c9-v1.dtb \
-+ bcm47094-asus-rt-ac3100.dtb \
- bcm47094-asus-rt-ac88u.dtb \
- bcm47094-dlink-dir-885l.dtb \
- bcm47094-dlink-dir-890l.dtb \
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm47094-asus-rt-ac3100.dts
-@@ -0,0 +1,23 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-+/*
-+ * Author: Arınç ÜNAL <arinc.unal@arinc9.com>
-+ */
-+
-+/dts-v1/;
-+
-+#include "bcm47094-asus-rt-ac3100.dtsi"
-+
-+/ {
-+ compatible = "asus,rt-ac3100", "brcm,bcm47094", "brcm,bcm4708";
-+ model = "ASUS RT-AC3100";
-+
-+ nvram@1c080000 {
-+ et0macaddr: et0macaddr {
-+ };
-+ };
-+};
-+
-+&gmac0 {
-+ nvmem-cells = <&et0macaddr>;
-+ nvmem-cell-names = "mac-address";
-+};
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm47094-asus-rt-ac3100.dtsi
-@@ -0,0 +1,163 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-+/*
-+ * Author: Arınç ÜNAL <arinc.unal@arinc9.com>
-+ */
-+
-+#include "bcm47094.dtsi"
-+#include "bcm5301x-nand-cs0-bch8.dtsi"
-+
-+/ {
-+ chosen {
-+ bootargs = "earlycon";
-+ };
-+
-+ memory@0 {
-+ device_type = "memory";
-+ reg = <0x00000000 0x08000000>,
-+ <0x88000000 0x18000000>;
-+ };
-+
-+ nvram@1c080000 {
-+ compatible = "brcm,nvram";
-+ reg = <0x1c080000 0x00180000>;
-+ };
-+
-+ leds {
-+ compatible = "gpio-leds";
-+
-+ led-power {
-+ label = "white:power";
-+ gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
-+ linux,default-trigger = "default-on";
-+ };
-+
-+ led-wan-red {
-+ label = "red:wan";
-+ gpios = <&chipcommon 5 GPIO_ACTIVE_HIGH>;
-+ };
-+
-+ led-lan {
-+ label = "white:lan";
-+ gpios = <&chipcommon 21 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ led-usb2 {
-+ label = "white:usb2";
-+ gpios = <&chipcommon 16 GPIO_ACTIVE_LOW>;
-+ trigger-sources = <&ehci_port2>;
-+ linux,default-trigger = "usbport";
-+ };
-+
-+ led-usb3 {
-+ label = "white:usb3";
-+ gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>;
-+ trigger-sources = <&ehci_port1>, <&xhci_port1>;
-+ linux,default-trigger = "usbport";
-+ };
-+
-+ led-wps {
-+ label = "white:wps";
-+ gpios = <&chipcommon 19 GPIO_ACTIVE_LOW>;
-+ };
-+ };
-+
-+ gpio-keys {
-+ compatible = "gpio-keys";
-+
-+ button-wps {
-+ label = "WPS";
-+ linux,code = <KEY_WPS_BUTTON>;
-+ gpios = <&chipcommon 20 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ button-reset {
-+ label = "Reset";
-+ linux,code = <KEY_RESTART>;
-+ gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ button-wifi {
-+ label = "Wi-Fi";
-+ linux,code = <KEY_RFKILL>;
-+ gpios = <&chipcommon 18 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ button-led {
-+ label = "Backlight";
-+ linux,code = <KEY_BRIGHTNESS_ZERO>;
-+ gpios = <&chipcommon 4 GPIO_ACTIVE_LOW>;
-+ };
-+ };
-+};
-+
-+&srab {
-+ compatible = "brcm,bcm53012-srab", "brcm,bcm5301x-srab";
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "lan4";
-+ };
-+
-+ port@1 {
-+ label = "lan3";
-+ };
-+
-+ port@2 {
-+ label = "lan2";
-+ };
-+
-+ port@3 {
-+ label = "lan1";
-+ };
-+
-+ port@4 {
-+ label = "wan";
-+ };
-+
-+ port@5 {
-+ label = "cpu";
-+ };
-+
-+ port@7 {
-+ label = "cpu";
-+ };
-+
-+ port@8 {
-+ label = "cpu";
-+ };
-+ };
-+};
-+
-+&usb2 {
-+ vcc-gpio = <&chipcommon 9 GPIO_ACTIVE_HIGH>;
-+};
-+
-+&usb3_phy {
-+ status = "okay";
-+};
-+
-+&nandcs {
-+ partitions {
-+ compatible = "fixed-partitions";
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ partition@0 {
-+ label = "boot";
-+ reg = <0x00000000 0x00080000>;
-+ read-only;
-+ };
-+
-+ partition@80000 {
-+ label = "nvram";
-+ reg = <0x00080000 0x00180000>;
-+ };
-+
-+ partition@200000 {
-+ label = "firmware";
-+ reg = <0x00200000 0x07e00000>;
-+ compatible = "brcm,trx";
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-+++ b/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-@@ -1,102 +1,21 @@
- // SPDX-License-Identifier: GPL-2.0-or-later OR MIT
- /*
-- * Copyright (C) 2021-2022 Arınç ÜNAL <arinc.unal@arinc9.com>
-+ * Author: Arınç ÜNAL <arinc.unal@arinc9.com>
- */
-
- /dts-v1/;
-
--#include "bcm47094.dtsi"
--#include "bcm5301x-nand-cs0-bch8.dtsi"
-+#include "bcm47094-asus-rt-ac3100.dtsi"
-
- / {
- compatible = "asus,rt-ac88u", "brcm,bcm47094", "brcm,bcm4708";
-- model = "Asus RT-AC88U";
--
-- chosen {
-- bootargs = "earlycon";
-- };
--
-- memory@0 {
-- device_type = "memory";
-- reg = <0x00000000 0x08000000>,
-- <0x88000000 0x18000000>;
-- };
-+ model = "ASUS RT-AC88U";
-
- nvram@1c080000 {
-- compatible = "brcm,nvram";
-- reg = <0x1c080000 0x00180000>;
--
- et1macaddr: et1macaddr {
- };
- };
-
-- leds {
-- compatible = "gpio-leds";
--
-- led-power {
-- label = "white:power";
-- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
-- linux,default-trigger = "default-on";
-- };
--
-- led-wan-red {
-- label = "red:wan";
-- gpios = <&chipcommon 5 GPIO_ACTIVE_HIGH>;
-- };
--
-- led-lan {
-- label = "white:lan";
-- gpios = <&chipcommon 21 GPIO_ACTIVE_LOW>;
-- };
--
-- led-usb2 {
-- label = "white:usb2";
-- gpios = <&chipcommon 16 GPIO_ACTIVE_LOW>;
-- trigger-sources = <&ehci_port2>;
-- linux,default-trigger = "usbport";
-- };
--
-- led-usb3 {
-- label = "white:usb3";
-- gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>;
-- trigger-sources = <&ehci_port1>, <&xhci_port1>;
-- linux,default-trigger = "usbport";
-- };
--
-- led-wps {
-- label = "white:wps";
-- gpios = <&chipcommon 19 GPIO_ACTIVE_LOW>;
-- };
-- };
--
-- gpio-keys {
-- compatible = "gpio-keys";
--
-- button-wps {
-- label = "WPS";
-- linux,code = <KEY_WPS_BUTTON>;
-- gpios = <&chipcommon 20 GPIO_ACTIVE_LOW>;
-- };
--
-- button-reset {
-- label = "Reset";
-- linux,code = <KEY_RESTART>;
-- gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
-- };
--
-- button-wifi {
-- label = "Wi-Fi";
-- linux,code = <KEY_RFKILL>;
-- gpios = <&chipcommon 18 GPIO_ACTIVE_LOW>;
-- };
--
-- button-led {
-- label = "Backlight";
-- linux,code = <KEY_BRIGHTNESS_ZERO>;
-- gpios = <&chipcommon 4 GPIO_ACTIVE_LOW>;
-- };
-- };
--
- switch {
- compatible = "realtek,rtl8365mb";
- /* 7 = MDIO (has input reads), 6 = MDC (clock, output only) */
-@@ -175,31 +94,9 @@
- };
-
- &srab {
-- compatible = "brcm,bcm53012-srab", "brcm,bcm5301x-srab";
-- status = "okay";
- dsa,member = <0 0>;
-
- ports {
-- port@0 {
-- label = "lan4";
-- };
--
-- port@1 {
-- label = "lan3";
-- };
--
-- port@2 {
-- label = "lan2";
-- };
--
-- port@3 {
-- label = "lan1";
-- };
--
-- port@4 {
-- label = "wan";
-- };
--
- sw0_p5: port@5 {
- /delete-property/ethernet;
-
-@@ -212,19 +109,6 @@
- pause;
- };
- };
--
-- port@7 {
-- label = "cpu";
--
-- fixed-link {
-- speed = <1000>;
-- full-duplex;
-- };
-- };
--
-- port@8 {
-- label = "cpu";
-- };
- };
- };
-
-@@ -236,36 +120,3 @@
- nvmem-cells = <&et1macaddr>;
- nvmem-cell-names = "mac-address";
- };
--
--&usb2 {
-- vcc-gpio = <&chipcommon 9 GPIO_ACTIVE_HIGH>;
--};
--
--&usb3_phy {
-- status = "okay";
--};
--
--&nandcs {
-- partitions {
-- compatible = "fixed-partitions";
-- #address-cells = <1>;
-- #size-cells = <1>;
--
-- partition@0 {
-- label = "boot";
-- reg = <0x00000000 0x00080000>;
-- read-only;
-- };
--
-- partition@80000 {
-- label = "nvram";
-- reg = <0x00080000 0x00180000>;
-- };
--
-- partition@200000 {
-- label = "firmware";
-- reg = <0x00200000 0x07e00000>;
-- compatible = "brcm,trx";
-- };
-- };
--};
diff --git a/target/linux/bcm53xx/patches-5.15/038-v6.7-0001-ARM-dts-BCM5301X-Set-MACs-for-D-Link-DIR-885L.patch b/target/linux/bcm53xx/patches-5.15/038-v6.7-0001-ARM-dts-BCM5301X-Set-MACs-for-D-Link-DIR-885L.patch
deleted file mode 100644
index 78b8975f1f..0000000000
--- a/target/linux/bcm53xx/patches-5.15/038-v6.7-0001-ARM-dts-BCM5301X-Set-MACs-for-D-Link-DIR-885L.patch
+++ /dev/null
@@ -1,56 +0,0 @@
-From 5cbee5828219c4f7b33e96b5d8ce5e467b2857c8 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 1 Sep 2023 12:55:49 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Set MACs for D-Link DIR-885L
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Specify NVRAM access and use its "et2macaddr" NVMEM cell.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230901105549.7076-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- .../dts/broadcom/bcm47094-dlink-dir-885l.dts | 16 ++++++++++++++++
- 1 file changed, 16 insertions(+)
-
---- a/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts
-+++ b/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts
-@@ -25,6 +25,15 @@
- <0x88000000 0x08000000>;
- };
-
-+ nvram@1e3f0000 {
-+ compatible = "brcm,nvram";
-+ reg = <0x1e3f0000 0x10000>;
-+
-+ et2macaddr: et2macaddr {
-+ #nvmem-cell-cells = <1>;
-+ };
-+ };
-+
- nand_controller: nand-controller@18028000 {
- nand@0 {
- partitions {
-@@ -112,6 +121,11 @@
- vcc-gpio = <&chipcommon 18 GPIO_ACTIVE_HIGH>;
- };
-
-+&gmac0 {
-+ nvmem-cells = <&et2macaddr 0>;
-+ nvmem-cell-names = "mac-address";
-+};
-+
- &spi_nor {
- status = "okay";
- };
-@@ -142,6 +156,8 @@
-
- port@4 {
- label = "wan";
-+ nvmem-cells = <&et2macaddr 3>;
-+ nvmem-cell-names = "mac-address";
- };
-
- port@8 {
diff --git a/target/linux/bcm53xx/patches-5.15/038-v6.7-0002-ARM-dts-BCM5301X-Set-MAC-address-for-Asus-RT-AC87U.patch b/target/linux/bcm53xx/patches-5.15/038-v6.7-0002-ARM-dts-BCM5301X-Set-MAC-address-for-Asus-RT-AC87U.patch
deleted file mode 100644
index 11ce7acb53..0000000000
--- a/target/linux/bcm53xx/patches-5.15/038-v6.7-0002-ARM-dts-BCM5301X-Set-MAC-address-for-Asus-RT-AC87U.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-From a9e79863b62aaaefcdf469fc331bf482ae00db0d Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 1 Sep 2023 14:43:11 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Set MAC address for Asus RT-AC87U
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Specify NVRAM access and use its "et1macaddr" NVMEM cell.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230901124311.31156-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/broadcom/bcm4709-asus-rt-ac87u.dts | 11 +++++++++++
- 1 file changed, 11 insertions(+)
-
---- a/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts
-+++ b/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts
-@@ -25,6 +25,12 @@
- <0x88000000 0x08000000>;
- };
-
-+ nvram@1c080000 {
-+ et1macaddr: et1macaddr {
-+ #nvmem-cell-cells = <1>;
-+ };
-+ };
-+
- leds {
- compatible = "gpio-leds";
-
-@@ -62,6 +68,11 @@
- };
- };
-
-+&gmac0 {
-+ nvmem-cells = <&et1macaddr 0>;
-+ nvmem-cell-names = "mac-address";
-+};
-+
- &usb3_phy {
- status = "okay";
- };
diff --git a/target/linux/bcm53xx/patches-5.15/038-v6.7-0003-ARM-dts-BCM5301X-Relicense-Felix-s-code-to-the-GPL-2.patch b/target/linux/bcm53xx/patches-5.15/038-v6.7-0003-ARM-dts-BCM5301X-Relicense-Felix-s-code-to-the-GPL-2.patch
deleted file mode 100644
index 6df1e555e9..0000000000
--- a/target/linux/bcm53xx/patches-5.15/038-v6.7-0003-ARM-dts-BCM5301X-Relicense-Felix-s-code-to-the-GPL-2.patch
+++ /dev/null
@@ -1,57 +0,0 @@
-From 81ea360a16978a4df61df9db56b171909bd659c0 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Sat, 16 Sep 2023 10:30:57 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Relicense Felix's code to the GPL 2.0+ /
- MIT
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Move code added by Felix to the bcm-ns.dtsi which uses dual licensing.
-That syncs more Northstar code to be based on the same licensing schema.
-
-This code was added in the commit 1ff80363524c ("ARM: BCM5301X: Add
-profiling support").
-
-Cc: Felix Fietkau <nbd@nbd.name>
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Acked-by: Felix Fietkau <nbd@nbd.name>
-Link: https://lore.kernel.org/r/20230916083057.10458-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/broadcom/bcm-ns.dtsi | 7 +++++++
- arch/arm/boot/dts/broadcom/bcm5301x.dtsi | 7 -------
- 2 files changed, 7 insertions(+), 7 deletions(-)
-
---- a/arch/arm/boot/dts/bcm-ns.dtsi
-+++ b/arch/arm/boot/dts/bcm-ns.dtsi
-@@ -14,6 +14,13 @@
- #address-cells = <1>;
- #size-cells = <1>;
-
-+ pmu {
-+ compatible = "arm,cortex-a9-pmu";
-+ interrupts =
-+ <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
-+ <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
-+ };
-+
- chipcommon-a-bus@18000000 {
- compatible = "simple-bus";
- ranges = <0x00000000 0x18000000 0x00001000>;
---- a/arch/arm/boot/dts/bcm5301x.dtsi
-+++ b/arch/arm/boot/dts/bcm5301x.dtsi
-@@ -26,13 +26,6 @@
- };
- };
-
-- pmu {
-- compatible = "arm,cortex-a9-pmu";
-- interrupts =
-- <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
-- <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
-- };
--
- clocks {
- #address-cells = <1>;
- #size-cells = <1>;
diff --git a/target/linux/bcm53xx/patches-5.15/038-v6.7-0004-ARM-dts-BCM5301X-Relicense-Vivek-s-code-to-the-GPL-2.patch b/target/linux/bcm53xx/patches-5.15/038-v6.7-0004-ARM-dts-BCM5301X-Relicense-Vivek-s-code-to-the-GPL-2.patch
deleted file mode 100644
index 66db4a291f..0000000000
--- a/target/linux/bcm53xx/patches-5.15/038-v6.7-0004-ARM-dts-BCM5301X-Relicense-Vivek-s-code-to-the-GPL-2.patch
+++ /dev/null
@@ -1,104 +0,0 @@
-From b8d4f7c1be04d66c37c119c501c87bccc4197694 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Sat, 16 Sep 2023 10:58:55 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Relicense Vivek's code to the GPL 2.0+ /
- MIT
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Move code added by Vivek to the bcm-ns.dtsi which uses dual licensing.
-That syncs more Northstar code to be based on the same licensing schema.
-
-This code was added in the commit 37f6130ec39f ("ARM: dts: BCM5301X:
-Make USB 3.0 PHY use MDIO PHY driver").
-
-Cc: Vivek Unune <npcomplete13@gmail.com>
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Acked-by: Vivek Unune <npcomplete13@gmail.com>
-Link: https://lore.kernel.org/r/20230916085855.28375-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/broadcom/bcm-ns.dtsi | 27 ++++++++++++++++++++++++
- arch/arm/boot/dts/broadcom/bcm5301x.dtsi | 27 ------------------------
- 2 files changed, 27 insertions(+), 27 deletions(-)
-
---- a/arch/arm/boot/dts/bcm-ns.dtsi
-+++ b/arch/arm/boot/dts/bcm-ns.dtsi
-@@ -327,6 +327,29 @@
- #address-cells = <1>;
- };
-
-+ mdio-mux@18003000 {
-+ compatible = "mdio-mux-mmioreg", "mdio-mux";
-+ mdio-parent-bus = <&mdio>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ reg = <0x18003000 0x4>;
-+ mux-mask = <0x200>;
-+
-+ mdio@0 {
-+ reg = <0x0>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ usb3_phy: usb3-phy@10 {
-+ compatible = "brcm,ns-ax-usb3-phy";
-+ reg = <0x10>;
-+ usb3-dmp-syscon = <&usb3_dmp>;
-+ #phy-cells = <0>;
-+ status = "disabled";
-+ };
-+ };
-+ };
-+
- rng: rng@18004000 {
- compatible = "brcm,bcm5301x-rng";
- reg = <0x18004000 0x14>;
-@@ -467,6 +490,10 @@
- brcm,nand-has-wp;
- };
-
-+ usb3_dmp: syscon@18105000 {
-+ reg = <0x18105000 0x1000>;
-+ };
-+
- thermal-zones {
- cpu_thermal: cpu-thermal {
- polling-delay-passive = <0>;
---- a/arch/arm/boot/dts/bcm5301x.dtsi
-+++ b/arch/arm/boot/dts/bcm5301x.dtsi
-@@ -62,33 +62,6 @@
- };
- };
-
-- mdio-mux@18003000 {
-- compatible = "mdio-mux-mmioreg", "mdio-mux";
-- mdio-parent-bus = <&mdio>;
-- #address-cells = <1>;
-- #size-cells = <0>;
-- reg = <0x18003000 0x4>;
-- mux-mask = <0x200>;
--
-- mdio@0 {
-- reg = <0x0>;
-- #address-cells = <1>;
-- #size-cells = <0>;
--
-- usb3_phy: usb3-phy@10 {
-- compatible = "brcm,ns-ax-usb3-phy";
-- reg = <0x10>;
-- usb3-dmp-syscon = <&usb3_dmp>;
-- #phy-cells = <0>;
-- status = "disabled";
-- };
-- };
-- };
--
-- usb3_dmp: syscon@18105000 {
-- reg = <0x18105000 0x1000>;
-- };
--
- i2c0: i2c@18009000 {
- compatible = "brcm,iproc-i2c";
- reg = <0x18009000 0x50>;
diff --git a/target/linux/bcm53xx/patches-5.15/038-v6.7-0005-ARM-dts-BCM5301X-Explicitly-disable-unused-switch-CP.patch b/target/linux/bcm53xx/patches-5.15/038-v6.7-0005-ARM-dts-BCM5301X-Explicitly-disable-unused-switch-CP.patch
deleted file mode 100644
index 72e5c6b061..0000000000
--- a/target/linux/bcm53xx/patches-5.15/038-v6.7-0005-ARM-dts-BCM5301X-Explicitly-disable-unused-switch-CP.patch
+++ /dev/null
@@ -1,377 +0,0 @@
-From 473baeab929444295b0530f8766e4becb6a08973 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 13 Oct 2023 12:33:13 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Explicitly disable unused switch CPU
- ports
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-When redescribing ports I assumed that missing "label" (like "cpu")
-means switch port isn't used. That was incorrect and I realized my
-change made Linux always use the first (5) CPU port (there are 3 of
-them).
-
-While above should technically be possible it often isn't correct:
-1. Non-default switch ports are often connected to Ethernet interfaces
- not fully covered by vendor setup (they may miss MACs)
-2. On some devices non-default ports require specifying fixed link
-
-This fixes network connectivity for some devices. It was reported &
-tested for Netgear R8000. It also affects Linksys EA9200 with its
-downstream DTS.
-
-Fixes: ba4aebce23b2 ("ARM: dts: BCM5301X: Describe switch ports in the main DTS")
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20231013103314.10306-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- .../dts/broadcom/bcm4708-buffalo-wzr-1166dhp-common.dtsi | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm4708-luxul-xap-1510.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm4708-luxul-xwc-1000.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm4708-netgear-r6250.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm4708-smartrg-sr400ac.dts | 8 ++++++++
- .../boot/dts/broadcom/bcm47081-buffalo-wzr-600dhp2.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm47081-luxul-xap-1410.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm47081-luxul-xwr-1200.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm4709-netgear-r8000.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm47094-dlink-dir-885l.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm47094-dlink-dir-890l.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm47094-luxul-abr-4500.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm47094-luxul-xap-1610.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm47094-luxul-xbr-4500.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm47094-luxul-xwc-2000.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm47094-luxul-xwr-3100.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm47094-luxul-xwr-3150-v1.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm53015-meraki-mr26.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm53016-meraki-mr32.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm953012er.dts | 8 ++++++++
- 20 files changed, 160 insertions(+)
-
---- a/arch/arm/boot/dts/bcm4708-buffalo-wzr-1166dhp-common.dtsi
-+++ b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1166dhp-common.dtsi
-@@ -181,5 +181,13 @@
- port@5 {
- label = "cpu";
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
---- a/arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts
-+++ b/arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts
-@@ -85,5 +85,13 @@
- port@5 {
- label = "cpu";
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
---- a/arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts
-+++ b/arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts
-@@ -88,5 +88,13 @@
- port@5 {
- label = "cpu";
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
---- a/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
-+++ b/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
-@@ -122,5 +122,13 @@
- port@5 {
- label = "cpu";
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
---- a/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts
-+++ b/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts
-@@ -145,6 +145,14 @@
- port@5 {
- label = "cpu";
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
-
---- a/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
-+++ b/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
-@@ -145,5 +145,13 @@
- port@5 {
- label = "cpu";
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
---- a/arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts
-+++ b/arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts
-@@ -81,5 +81,13 @@
- port@5 {
- label = "cpu";
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
---- a/arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts
-+++ b/arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts
-@@ -148,5 +148,13 @@
- port@5 {
- label = "cpu";
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
---- a/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
-+++ b/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
-@@ -227,6 +227,14 @@
- label = "wan";
- };
-
-+ port@5 {
-+ status = "disabled";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
- port@8 {
- label = "cpu";
- };
---- a/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts
-+++ b/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts
-@@ -160,6 +160,14 @@
- nvmem-cell-names = "mac-address";
- };
-
-+ port@5 {
-+ status = "disabled";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
- port@8 {
- label = "cpu";
- };
---- a/arch/arm/boot/dts/bcm47094-dlink-dir-890l.dts
-+++ b/arch/arm/boot/dts/bcm47094-dlink-dir-890l.dts
-@@ -192,6 +192,14 @@
- label = "wan";
- };
-
-+ port@5 {
-+ status = "disabled";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
- port@8 {
- label = "cpu";
- phy-mode = "rgmii";
---- a/arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts
-@@ -107,5 +107,13 @@
- port@5 {
- label = "cpu";
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts
-@@ -120,5 +120,13 @@
- port@5 {
- label = "cpu";
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts
-@@ -107,5 +107,13 @@
- port@5 {
- label = "cpu";
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts
-@@ -75,5 +75,13 @@
- port@5 {
- label = "cpu";
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts
-@@ -147,5 +147,13 @@
- port@5 {
- label = "cpu";
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
-@@ -158,5 +158,13 @@
- port@5 {
- label = "cpu";
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
---- a/arch/arm/boot/dts/bcm53015-meraki-mr26.dts
-+++ b/arch/arm/boot/dts/bcm53015-meraki-mr26.dts
-@@ -124,6 +124,14 @@
- full-duplex;
- };
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
-
---- a/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-+++ b/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-@@ -185,6 +185,14 @@
- full-duplex;
- };
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
-
---- a/arch/arm/boot/dts/bcm953012er.dts
-+++ b/arch/arm/boot/dts/bcm953012er.dts
-@@ -84,6 +84,14 @@
- label = "cpu";
- ethernet = <&gmac0>;
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
-
diff --git a/target/linux/bcm53xx/patches-5.15/038-v6.7-0006-ARM-dts-BCM5301X-Set-fixed-link-for-extra-Netgear-R8.patch b/target/linux/bcm53xx/patches-5.15/038-v6.7-0006-ARM-dts-BCM5301X-Set-fixed-link-for-extra-Netgear-R8.patch
deleted file mode 100644
index 0b2b7b36a3..0000000000
--- a/target/linux/bcm53xx/patches-5.15/038-v6.7-0006-ARM-dts-BCM5301X-Set-fixed-link-for-extra-Netgear-R8.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From d313b0e9070a7100ca55e64fe3b081d176d8806d Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 13 Oct 2023 12:33:14 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Set fixed-link for extra Netgear R8000
- CPU ports
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Ports 5 and 7 are disabled by default because the standard use case is
-for port 8 to manage all CPU directed traffic. For experimentation
-purposes however it is desirable to provide adequate properties such
-that people can experiment with using different ports without having to
-figure out their configuration. Some of the use cases include but are
-not limited to doubling or tripling the bandwidth by leveraging the
-additional ports/Ethernet MAC combinations.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20231013103314.10306-2-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/broadcom/bcm4709-netgear-r8000.dts | 10 ++++++++++
- 1 file changed, 10 insertions(+)
-
---- a/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
-+++ b/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
-@@ -229,10 +229,20 @@
-
- port@5 {
- status = "disabled";
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
- };
-
- port@7 {
- status = "disabled";
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
- };
-
- port@8 {
diff --git a/target/linux/bcm53xx/patches-5.15/038-v6.7-0007-ARM-dts-BCM5301X-Set-switch-ports-for-Linksys-EA9200.patch b/target/linux/bcm53xx/patches-5.15/038-v6.7-0007-ARM-dts-BCM5301X-Set-switch-ports-for-Linksys-EA9200.patch
deleted file mode 100644
index 4528c95a5a..0000000000
--- a/target/linux/bcm53xx/patches-5.15/038-v6.7-0007-ARM-dts-BCM5301X-Set-switch-ports-for-Linksys-EA9200.patch
+++ /dev/null
@@ -1,63 +0,0 @@
-From 253358f373492608348136e569366d73cb969f6a Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Tue, 24 Oct 2023 09:26:05 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Set switch ports for Linksys EA9200
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This patch was developed as OpenWrt downstream change and was recently
-confirmed to work as expected.
-
-Tested-by: Rani Hod <rani.hod@gmail.com>
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20231024072605.32517-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- .../dts/broadcom/bcm4709-linksys-ea9200.dts | 38 +++++++++++++++++++
- 1 file changed, 38 insertions(+)
-
---- a/arch/arm/boot/dts/bcm4709-linksys-ea9200.dts
-+++ b/arch/arm/boot/dts/bcm4709-linksys-ea9200.dts
-@@ -47,3 +47,41 @@
- &usb3_phy {
- status = "okay";
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "lan1";
-+ };
-+
-+ port@1 {
-+ label = "lan2";
-+ };
-+
-+ port@2 {
-+ label = "lan3";
-+ };
-+
-+ port@3 {
-+ label = "lan4";
-+ };
-+
-+ port@4 {
-+ label = "wan";
-+ };
-+
-+ port@5 {
-+ status = "disabled";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ label = "cpu";
-+ };
-+ };
-+};
diff --git a/target/linux/bcm53xx/patches-5.15/070-v5.17-phy-bcm-ns-usb2-support-updated-DT-binding-with-PHY-.patch b/target/linux/bcm53xx/patches-5.15/070-v5.17-phy-bcm-ns-usb2-support-updated-DT-binding-with-PHY-.patch
deleted file mode 100644
index e4a0f314dc..0000000000
--- a/target/linux/bcm53xx/patches-5.15/070-v5.17-phy-bcm-ns-usb2-support-updated-DT-binding-with-PHY-.patch
+++ /dev/null
@@ -1,129 +0,0 @@
-From d3bc6269e21fc474763708e79c7a118740befb94 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Tue, 26 Oct 2021 11:37:16 +0200
-Subject: [PATCH] phy: bcm-ns-usb2: support updated DT binding with PHY reg
- space
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Updated DT binding maps just a PHY's register space instead of the whole
-DMU block. Accessing a common CRU reg is handled using syscon &
-regmap.
-
-The old binding has been deprecated and remains supported as a fallback
-method.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20211026093716.5567-1-zajec5@gmail.com
-Signed-off-by: Vinod Koul <vkoul@kernel.org>
----
- drivers/phy/broadcom/phy-bcm-ns-usb2.c | 52 +++++++++++++++++++++-----
- 1 file changed, 43 insertions(+), 9 deletions(-)
-
---- a/drivers/phy/broadcom/phy-bcm-ns-usb2.c
-+++ b/drivers/phy/broadcom/phy-bcm-ns-usb2.c
-@@ -9,17 +9,23 @@
- #include <linux/clk.h>
- #include <linux/delay.h>
- #include <linux/err.h>
-+#include <linux/mfd/syscon.h>
- #include <linux/module.h>
- #include <linux/of_address.h>
- #include <linux/of_platform.h>
- #include <linux/phy/phy.h>
- #include <linux/platform_device.h>
-+#include <linux/regmap.h>
- #include <linux/slab.h>
-
- struct bcm_ns_usb2 {
- struct device *dev;
- struct clk *ref_clk;
- struct phy *phy;
-+ struct regmap *clkset;
-+ void __iomem *base;
-+
-+ /* Deprecated binding */
- void __iomem *dmu;
- };
-
-@@ -27,7 +33,6 @@ static int bcm_ns_usb2_phy_init(struct p
- {
- struct bcm_ns_usb2 *usb2 = phy_get_drvdata(phy);
- struct device *dev = usb2->dev;
-- void __iomem *dmu = usb2->dmu;
- u32 ref_clk_rate, usb2ctl, usb_pll_ndiv, usb_pll_pdiv;
- int err = 0;
-
-@@ -44,7 +49,10 @@ static int bcm_ns_usb2_phy_init(struct p
- goto err_clk_off;
- }
-
-- usb2ctl = readl(dmu + BCMA_DMU_CRU_USB2_CONTROL);
-+ if (usb2->base)
-+ usb2ctl = readl(usb2->base);
-+ else
-+ usb2ctl = readl(usb2->dmu + BCMA_DMU_CRU_USB2_CONTROL);
-
- if (usb2ctl & BCMA_DMU_CRU_USB2_CONTROL_USB_PLL_PDIV_MASK) {
- usb_pll_pdiv = usb2ctl;
-@@ -58,15 +66,24 @@ static int bcm_ns_usb2_phy_init(struct p
- usb_pll_ndiv = (1920000000 * usb_pll_pdiv) / ref_clk_rate;
-
- /* Unlock DMU PLL settings with some magic value */
-- writel(0x0000ea68, dmu + BCMA_DMU_CRU_CLKSET_KEY);
-+ if (usb2->clkset)
-+ regmap_write(usb2->clkset, 0, 0x0000ea68);
-+ else
-+ writel(0x0000ea68, usb2->dmu + BCMA_DMU_CRU_CLKSET_KEY);
-
- /* Write USB 2.0 PLL control setting */
- usb2ctl &= ~BCMA_DMU_CRU_USB2_CONTROL_USB_PLL_NDIV_MASK;
- usb2ctl |= usb_pll_ndiv << BCMA_DMU_CRU_USB2_CONTROL_USB_PLL_NDIV_SHIFT;
-- writel(usb2ctl, dmu + BCMA_DMU_CRU_USB2_CONTROL);
-+ if (usb2->base)
-+ writel(usb2ctl, usb2->base);
-+ else
-+ writel(usb2ctl, usb2->dmu + BCMA_DMU_CRU_USB2_CONTROL);
-
- /* Lock DMU PLL settings */
-- writel(0x00000000, dmu + BCMA_DMU_CRU_CLKSET_KEY);
-+ if (usb2->clkset)
-+ regmap_write(usb2->clkset, 0, 0x00000000);
-+ else
-+ writel(0x00000000, usb2->dmu + BCMA_DMU_CRU_CLKSET_KEY);
-
- err_clk_off:
- clk_disable_unprepare(usb2->ref_clk);
-@@ -90,10 +107,27 @@ static int bcm_ns_usb2_probe(struct plat
- return -ENOMEM;
- usb2->dev = dev;
-
-- usb2->dmu = devm_platform_ioremap_resource_byname(pdev, "dmu");
-- if (IS_ERR(usb2->dmu)) {
-- dev_err(dev, "Failed to map DMU regs\n");
-- return PTR_ERR(usb2->dmu);
-+ if (of_find_property(dev->of_node, "brcm,syscon-clkset", NULL)) {
-+ usb2->base = devm_platform_ioremap_resource(pdev, 0);
-+ if (IS_ERR(usb2->base)) {
-+ dev_err(dev, "Failed to map control reg\n");
-+ return PTR_ERR(usb2->base);
-+ }
-+
-+ usb2->clkset = syscon_regmap_lookup_by_phandle(dev->of_node,
-+ "brcm,syscon-clkset");
-+ if (IS_ERR(usb2->clkset)) {
-+ dev_err(dev, "Failed to lookup clkset regmap\n");
-+ return PTR_ERR(usb2->clkset);
-+ }
-+ } else {
-+ usb2->dmu = devm_platform_ioremap_resource_byname(pdev, "dmu");
-+ if (IS_ERR(usb2->dmu)) {
-+ dev_err(dev, "Failed to map DMU regs\n");
-+ return PTR_ERR(usb2->dmu);
-+ }
-+
-+ dev_warn(dev, "using deprecated DT binding\n");
- }
-
- usb2->ref_clk = devm_clk_get(dev, "phy-ref-clk");
diff --git a/target/linux/bcm53xx/patches-5.15/080-v6.2-bcma-support-SPROM-rev-11.patch b/target/linux/bcm53xx/patches-5.15/080-v6.2-bcma-support-SPROM-rev-11.patch
deleted file mode 100644
index 5ebc78ca20..0000000000
--- a/target/linux/bcm53xx/patches-5.15/080-v6.2-bcma-support-SPROM-rev-11.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From b9457a04eb89645049fdf427c13e6a18d5501895 Mon Sep 17 00:00:00 2001
-From: Linus Walleij <linus.walleij@linaro.org>
-Date: Tue, 11 Oct 2022 14:24:40 +0200
-Subject: [PATCH] bcma: support SPROM rev 11
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Rev 11 works fine for me to set the MAC address of gmac0 and
-gmac1 in the D-Link DWL-8610AP.
-
-Cc: Rafał Miłecki <zajec5@gmail.com>
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
----
- drivers/bcma/sprom.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/bcma/sprom.c
-+++ b/drivers/bcma/sprom.c
-@@ -170,7 +170,7 @@ static int bcma_sprom_valid(struct bcma_
- return err;
-
- revision = sprom[words - 1] & SSB_SPROM_REVISION_REV;
-- if (revision != 8 && revision != 9 && revision != 10) {
-+ if (revision < 8 || revision > 11) {
- pr_err("Unsupported SPROM revision: %d\n", revision);
- return -ENOENT;
- }
diff --git a/target/linux/bcm53xx/patches-5.15/140-mtd-parsers-trx-parse-firmware-MTD-partitions-only.patch b/target/linux/bcm53xx/patches-5.15/140-mtd-parsers-trx-parse-firmware-MTD-partitions-only.patch
deleted file mode 100644
index e1933e75c7..0000000000
--- a/target/linux/bcm53xx/patches-5.15/140-mtd-parsers-trx-parse-firmware-MTD-partitions-only.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Tue, 13 Apr 2021 18:25:20 +0200
-Subject: [PATCH] mtd: parsers: trx: parse "firmware" MTD partitions only
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Parsing every partition with "compatible" set to "brcm,trx" results in
-parsing both: firmware partition and failsafe partition on devices that
-implement failsafe booting. This affects e.g. Linksys EA9500 which has:
-
-partition@200000 {
- reg = <0x0200000 0x01d00000>;
- compatible = "linksys,ns-firmware", "brcm,trx";
-};
-
-partition@1f00000 {
- reg = <0x01f00000 0x01d00000>;
- compatible = "linksys,ns-firmware", "brcm,trx";
-};
-
-Check for MTD partition name "firmware" before parsing. Recently added
-ofpart_linksys_ns.c creates "firmware" and "failsafe" depending on
-bootloader setup.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
----
- drivers/mtd/parsers/parser_trx.c | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- a/drivers/mtd/parsers/parser_trx.c
-+++ b/drivers/mtd/parsers/parser_trx.c
-@@ -92,6 +92,10 @@ static int parser_trx_parse(struct mtd_i
- if (err != 0 && err != -EINVAL)
- pr_err("failed to parse \"brcm,trx-magic\" DT attribute, using default: %d\n", err);
-
-+ /* Don't parse any failsafe / backup partitions */
-+ if (strcmp(mtd->name, "firmware"))
-+ return -EINVAL;
-+
- parts = kcalloc(TRX_PARSER_MAX_PARTS, sizeof(struct mtd_partition),
- GFP_KERNEL);
- if (!parts)
diff --git a/target/linux/bcm53xx/patches-5.15/180-usb-xhci-add-support-for-performing-fake-doorbell.patch b/target/linux/bcm53xx/patches-5.15/180-usb-xhci-add-support-for-performing-fake-doorbell.patch
deleted file mode 100644
index 49277ab251..0000000000
--- a/target/linux/bcm53xx/patches-5.15/180-usb-xhci-add-support-for-performing-fake-doorbell.patch
+++ /dev/null
@@ -1,119 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Sat, 1 Oct 2016 22:54:48 +0200
-Subject: [PATCH] usb: xhci: add support for performing fake doorbell
-
-Broadcom's Northstar XHCI controllers seem to need a special start
-procedure to work correctly. There isn't any official documentation of
-this, the problem is that controller doesn't detect any connected
-devices with default setup. Moreover connecting USB device to controller
-that doesn't run properly can cause SoC's watchdog issues.
-
-A workaround that was successfully tested on multiple devices is to
-perform a fake doorbell. This patch adds code for doing this and enables
-it on BCM4708 family.
----
- drivers/usb/host/xhci-plat.c | 6 +++++
- drivers/usb/host/xhci.c | 63 +++++++++++++++++++++++++++++++++++++++++---
- drivers/usb/host/xhci.h | 1 +
- 3 files changed, 67 insertions(+), 3 deletions(-)
-
---- a/drivers/usb/host/xhci-plat.c
-+++ b/drivers/usb/host/xhci-plat.c
-@@ -77,6 +77,8 @@ static int xhci_priv_resume_quirk(struct
- static void xhci_plat_quirks(struct device *dev, struct xhci_hcd *xhci)
- {
- struct xhci_plat_priv *priv = xhci_to_priv(xhci);
-+ struct platform_device*pdev = to_platform_device(dev);
-+ struct device_node *node = pdev->dev.of_node;
-
- /*
- * As of now platform drivers don't provide MSI support so we ensure
-@@ -84,6 +86,9 @@ static void xhci_plat_quirks(struct devi
- * dev struct in order to setup MSI
- */
- xhci->quirks |= XHCI_PLAT | priv->quirks;
-+
-+ if (node && of_machine_is_compatible("brcm,bcm4708"))
-+ xhci->quirks |= XHCI_FAKE_DOORBELL;
- }
-
- /* called during probe() after chip reset completes */
---- a/drivers/usb/host/xhci.c
-+++ b/drivers/usb/host/xhci.c
-@@ -158,6 +158,49 @@ int xhci_start(struct xhci_hcd *xhci)
- return ret;
- }
-
-+/**
-+ * xhci_fake_doorbell - Perform a fake doorbell on a specified slot
-+ *
-+ * Some controllers require a fake doorbell to start correctly. Without that
-+ * they simply don't detect any devices.
-+ */
-+static int xhci_fake_doorbell(struct xhci_hcd *xhci, int slot_id)
-+{
-+ u32 temp;
-+
-+ /* Alloc a virt device for that slot */
-+ if (!xhci_alloc_virt_device(xhci, slot_id, NULL, GFP_NOIO)) {
-+ xhci_warn(xhci, "Could not allocate xHCI USB device data structures\n");
-+ return -ENOMEM;
-+ }
-+
-+ /* Ring fake doorbell for slot_id ep 0 */
-+ xhci_ring_ep_doorbell(xhci, slot_id, 0, 0);
-+ usleep_range(1000, 1500);
-+
-+ /* Read the status to check if HSE is set or not */
-+ temp = readl(&xhci->op_regs->status);
-+
-+ /* Clear HSE if set */
-+ if (temp & STS_FATAL) {
-+ xhci_dbg(xhci, "HSE problem detected, status: 0x%08x\n", temp);
-+ temp &= ~0x1fff;
-+ temp |= STS_FATAL;
-+ writel(temp, &xhci->op_regs->status);
-+ usleep_range(1000, 1500);
-+ readl(&xhci->op_regs->status);
-+ }
-+
-+ /* Free virt device */
-+ xhci_free_virt_device(xhci, slot_id);
-+
-+ /* We're done if controller is already running */
-+ if (readl(&xhci->op_regs->command) & CMD_RUN)
-+ return 0;
-+
-+ return xhci_start(xhci);
-+}
-+
- /*
- * Reset a halted HC.
- *
-@@ -634,6 +677,16 @@ static int xhci_run_finished(struct xhci
- spin_unlock_irqrestore(&xhci->lock, flags);
- return -ENODEV;
- }
-+
-+ if (xhci->quirks & XHCI_FAKE_DOORBELL) {
-+ int err = xhci_fake_doorbell(xhci, 1);
-+ if (err) {
-+ xhci_halt(xhci);
-+ spin_unlock_irqrestore(&xhci->lock, flags);
-+ return err;
-+ }
-+ }
-+
- xhci->shared_hcd->state = HC_STATE_RUNNING;
- xhci->cmd_ring_state = CMD_RING_STATE_RUNNING;
-
---- a/drivers/usb/host/xhci.h
-+++ b/drivers/usb/host/xhci.h
-@@ -1908,6 +1908,7 @@ struct xhci_hcd {
- #define XHCI_RESET_TO_DEFAULT BIT_ULL(44)
- #define XHCI_ZHAOXIN_TRB_FETCH BIT_ULL(45)
- #define XHCI_ZHAOXIN_HOST BIT_ULL(46)
-+#define XHCI_FAKE_DOORBELL BIT_ULL(47)
-
- unsigned int num_active_eps;
- unsigned int limit_active_eps;
diff --git a/target/linux/bcm53xx/patches-5.15/300-ARM-BCM5301X-Disable-MMU-and-Dcache-during-decompres.patch b/target/linux/bcm53xx/patches-5.15/300-ARM-BCM5301X-Disable-MMU-and-Dcache-during-decompres.patch
deleted file mode 100644
index 0247a66ccc..0000000000
--- a/target/linux/bcm53xx/patches-5.15/300-ARM-BCM5301X-Disable-MMU-and-Dcache-during-decompres.patch
+++ /dev/null
@@ -1,101 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Wed, 24 Sep 2014 22:14:07 +0200
-Subject: [PATCH] ARM: BCM5301X: Disable MMU and Dcache during decompression
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Broadcom devices have broken CFE (bootloader) that leaves hardware in an
-invalid state. It causes problems with booting Linux. On Northstar
-devices kernel was randomly hanging in ~25% of tries during early init.
-Hangs used to happen at random places in the start_kernel. On BCM53573
-kernel doesn't even seem to start booting.
-
-To workaround this problem we need to do following very early:
-1) Clear 2 following bits in the SCTLR register:
-#define CR_M (1 << 0) /* MMU enable */
-#define CR_C (1 << 2) /* Dcache enable */
-2) Flush the whole D-cache
-3) Disable L2 cache
-
-Unfortunately this patch is not upstreamable as it does above things
-unconditionally. We can't check if we are running on Broadcom platform
-in any safe way and doing such hacks with ARCH_MULTI_V7 is unacceptable
-as it could break other devices support.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
----
-
---- a/arch/arm/boot/compressed/Makefile
-+++ b/arch/arm/boot/compressed/Makefile
-@@ -36,6 +36,11 @@ ifeq ($(CONFIG_ARCH_ACORN),y)
- OBJS += ll_char_wr.o font.o
- endif
-
-+ifeq ($(CONFIG_ARCH_BCM_5301X),y)
-+OBJS += head-bcm_5301x-mpcore.o
-+OBJS += cache-v7-min.o
-+endif
-+
- ifeq ($(CONFIG_ARCH_SA1100),y)
- OBJS += head-sa1100.o
- endif
---- /dev/null
-+++ b/arch/arm/boot/compressed/head-bcm_5301x-mpcore.S
-@@ -0,0 +1,37 @@
-+/*
-+ *
-+ * Platform specific tweaks. This is merged into head.S by the linker.
-+ *
-+ */
-+
-+#include <linux/linkage.h>
-+#include <asm/assembler.h>
-+#include <asm/cp15.h>
-+
-+ .section ".start", "ax"
-+
-+/*
-+ * This code section is spliced into the head code by the linker
-+ */
-+
-+__plat_uncompress_start:
-+
-+ @ Preserve r8/r7 i.e. kernel entry values
-+ mov r12, r8
-+
-+ @ Clear MMU enable and Dcache enable bits
-+ mrc p15, 0, r0, c1, c0, 0 @ Read SCTLR
-+ bic r0, #CR_C|CR_M
-+ mcr p15, 0, r0, c1, c0, 0 @ Write SCTLR
-+ nop
-+
-+ @ Call the cache invalidation routine
-+ bl v7_flush_dcache_all
-+ nop
-+ mov r0,#0
-+ ldr r3, =0x19022000 @ L2 cache controller, control reg
-+ str r0, [r3, #0x100] @ Disable L2 cache
-+ nop
-+
-+ @ Restore
-+ mov r8, r12
---- a/arch/arm/boot/compressed/cache-v7-min.S
-+++ b/arch/arm/boot/compressed/cache-v7-min.S
-@@ -12,6 +12,7 @@
-
- #include <linux/linkage.h>
- #include <linux/init.h>
-+#include <asm/assembler.h>
-
- __INIT
-
-@@ -63,7 +64,7 @@ loop2:
- ARM( orr r11, r11, r9, lsl r2 ) @ factor index number into r11
- THUMB( lsl r6, r9, r2 )
- THUMB( orr r11, r11, r6 ) @ factor index number into r11
-- mcr p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way
-+ mcr p15, 0, r11, c7, c6, 2 @ clean & invalidate by set/way
- subs r9, r9, #1 @ decrement the index
- bge loop2
- subs r4, r4, #1 @ decrement the way
diff --git a/target/linux/bcm53xx/patches-5.15/304-ARM-dts-BCM5301X-Specify-switch-ports-for-remaining-.patch b/target/linux/bcm53xx/patches-5.15/304-ARM-dts-BCM5301X-Specify-switch-ports-for-remaining-.patch
deleted file mode 100644
index 8039831a78..0000000000
--- a/target/linux/bcm53xx/patches-5.15/304-ARM-dts-BCM5301X-Specify-switch-ports-for-remaining-.patch
+++ /dev/null
@@ -1,675 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Subject: [PATCH] ARM: dts: BCM5301X: Specify switch ports for remaining
- devices
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
----
-
---- a/arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dts
-+++ b/arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dts
-@@ -92,3 +92,41 @@
- &usb3_phy {
- status = "okay";
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "lan1";
-+ };
-+
-+ port@1 {
-+ label = "lan2";
-+ };
-+
-+ port@2 {
-+ label = "lan3";
-+ };
-+
-+ port@3 {
-+ label = "lan4";
-+ };
-+
-+ port@4 {
-+ label = "wan";
-+ };
-+
-+ port@5 {
-+ label = "cpu";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm4708-asus-rt-ac68u.dts
-+++ b/arch/arm/boot/dts/bcm4708-asus-rt-ac68u.dts
-@@ -83,3 +83,41 @@
- &usb3_phy {
- status = "okay";
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "wan";
-+ };
-+
-+ port@1 {
-+ label = "lan1";
-+ };
-+
-+ port@2 {
-+ label = "lan2";
-+ };
-+
-+ port@3 {
-+ label = "lan3";
-+ };
-+
-+ port@4 {
-+ label = "lan4";
-+ };
-+
-+ port@5 {
-+ label = "cpu";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts
-+++ b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts
-@@ -149,3 +149,41 @@
- &usb3_phy {
- status = "okay";
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "lan1";
-+ };
-+
-+ port@1 {
-+ label = "lan2";
-+ };
-+
-+ port@2 {
-+ label = "lan3";
-+ };
-+
-+ port@3 {
-+ label = "lan4";
-+ };
-+
-+ port@4 {
-+ label = "wan";
-+ };
-+
-+ port@5 {
-+ label = "cpu";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm4708-linksys-ea6300-v1.dts
-+++ b/arch/arm/boot/dts/bcm4708-linksys-ea6300-v1.dts
-@@ -46,3 +46,41 @@
- &usb3_phy {
- status = "okay";
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "lan1";
-+ };
-+
-+ port@1 {
-+ label = "lan2";
-+ };
-+
-+ port@2 {
-+ label = "lan3";
-+ };
-+
-+ port@3 {
-+ label = "lan4";
-+ };
-+
-+ port@4 {
-+ label = "wan";
-+ };
-+
-+ port@5 {
-+ label = "cpu";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm4708-linksys-ea6500-v2.dts
-+++ b/arch/arm/boot/dts/bcm4708-linksys-ea6500-v2.dts
-@@ -43,3 +43,41 @@
- &usb3_phy {
- status = "okay";
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "lan1";
-+ };
-+
-+ port@1 {
-+ label = "lan2";
-+ };
-+
-+ port@2 {
-+ label = "lan3";
-+ };
-+
-+ port@3 {
-+ label = "lan4";
-+ };
-+
-+ port@4 {
-+ label = "wan";
-+ };
-+
-+ port@5 {
-+ label = "cpu";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts
-+++ b/arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts
-@@ -86,3 +86,41 @@
- &usb3_phy {
- status = "okay";
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "lan1";
-+ };
-+
-+ port@1 {
-+ label = "lan2";
-+ };
-+
-+ port@2 {
-+ label = "lan3";
-+ };
-+
-+ port@3 {
-+ label = "lan4";
-+ };
-+
-+ port@4 {
-+ label = "wan";
-+ };
-+
-+ port@5 {
-+ label = "cpu";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts
-+++ b/arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts
-@@ -77,3 +77,41 @@
- &usb3_phy {
- status = "okay";
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "wan";
-+ };
-+
-+ port@1 {
-+ label = "lan1";
-+ };
-+
-+ port@2 {
-+ label = "lan2";
-+ };
-+
-+ port@3 {
-+ label = "lan3";
-+ };
-+
-+ port@4 {
-+ label = "lan4";
-+ };
-+
-+ port@5 {
-+ label = "cpu";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts
-+++ b/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts
-@@ -77,6 +77,40 @@
- status = "okay";
- };
-
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "wan";
-+ };
-+
-+ port@1 {
-+ label = "lan1";
-+ };
-+
-+ port@2 {
-+ label = "lan2";
-+ };
-+
-+ port@3 {
-+ label = "lan3";
-+ };
-+
-+ port@5 {
-+ status = "disabled";
-+ };
-+
-+ port@7 {
-+ label = "cpu";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
-+ };
-+};
-+
- &nandcs {
- partitions {
- compatible = "fixed-partitions";
---- a/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts
-+++ b/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts
-@@ -130,3 +130,41 @@
- &usb3_phy {
- status = "okay";
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "lan1";
-+ };
-+
-+ port@1 {
-+ label = "lan2";
-+ };
-+
-+ port@2 {
-+ label = "lan3";
-+ };
-+
-+ port@3 {
-+ label = "lan4";
-+ };
-+
-+ port@4 {
-+ label = "wan";
-+ };
-+
-+ port@5 {
-+ label = "cpu";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm4709-netgear-r7000.dts
-+++ b/arch/arm/boot/dts/bcm4709-netgear-r7000.dts
-@@ -104,3 +104,41 @@
- &usb3_phy {
- status = "okay";
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "wan";
-+ };
-+
-+ port@1 {
-+ label = "lan1";
-+ };
-+
-+ port@2 {
-+ label = "lan2";
-+ };
-+
-+ port@3 {
-+ label = "lan3";
-+ };
-+
-+ port@4 {
-+ label = "lan4";
-+ };
-+
-+ port@5 {
-+ label = "cpu";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm47094-netgear-r8500.dts
-+++ b/arch/arm/boot/dts/bcm47094-netgear-r8500.dts
-@@ -94,3 +94,41 @@
- &usb3_phy {
- status = "okay";
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "wan";
-+ };
-+
-+ port@1 {
-+ label = "lan1";
-+ };
-+
-+ port@2 {
-+ label = "lan2";
-+ };
-+
-+ port@3 {
-+ label = "lan3";
-+ };
-+
-+ port@4 {
-+ label = "lan4";
-+ };
-+
-+ port@5 {
-+ status = "disabled";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ label = "cpu";
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm47094-phicomm-k3.dts
-+++ b/arch/arm/boot/dts/bcm47094-phicomm-k3.dts
-@@ -38,6 +38,40 @@
- status = "okay";
- };
-
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "lan1";
-+ };
-+
-+ port@1 {
-+ label = "lan2";
-+ };
-+
-+ port@2 {
-+ label = "lan3";
-+ };
-+
-+ port@3 {
-+ label = "wan";
-+ };
-+
-+ port@5 {
-+ label = "cpu";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
-+ };
-+};
-+
- &nandcs {
- partitions {
- compatible = "fixed-partitions";
---- a/arch/arm/boot/dts/bcm47081-tplink-archer-c5-v2.dts
-+++ b/arch/arm/boot/dts/bcm47081-tplink-archer-c5-v2.dts
-@@ -91,6 +91,44 @@
- };
- };
-
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "wan";
-+ };
-+
-+ port@1 {
-+ label = "lan1";
-+ };
-+
-+ port@2 {
-+ label = "lan2";
-+ };
-+
-+ port@3 {
-+ label = "lan3";
-+ };
-+
-+ port@4 {
-+ label = "lan4";
-+ };
-+
-+ port@5 {
-+ label = "cpu";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
-+ };
-+};
-+
- &spi_nor {
- status = "okay";
-
---- a/arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts
-+++ b/arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts
-@@ -100,6 +100,44 @@
- vcc-gpio = <&chipcommon 12 GPIO_ACTIVE_HIGH>;
- };
-
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "wan";
-+ };
-+
-+ port@1 {
-+ label = "lan1";
-+ };
-+
-+ port@2 {
-+ label = "lan2";
-+ };
-+
-+ port@3 {
-+ label = "lan3";
-+ };
-+
-+ port@4 {
-+ label = "lan4";
-+ };
-+
-+ port@5 {
-+ label = "cpu";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
-+ };
-+};
-+
- &spi_nor {
- status = "okay";
-
---- a/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts
-+++ b/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts
-@@ -107,3 +107,42 @@
- &usb3_phy {
- status = "okay";
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "lan1";
-+ };
-+
-+ port@1 {
-+ label = "lan2";
-+ };
-+
-+ port@2 {
-+ label = "lan3";
-+ };
-+
-+ port@3 {
-+ label = "lan4";
-+ };
-+
-+ port@4 {
-+ label = "wan";
-+ };
-+
-+ port@5 {
-+ label = "cpu";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
-+ };
-+};
-+
diff --git a/target/linux/bcm53xx/patches-5.15/310-ARM-BCM5301X-Add-DT-for-Netgear-R7900.patch b/target/linux/bcm53xx/patches-5.15/310-ARM-BCM5301X-Add-DT-for-Netgear-R7900.patch
deleted file mode 100644
index bc04cbd2d6..0000000000
--- a/target/linux/bcm53xx/patches-5.15/310-ARM-BCM5301X-Add-DT-for-Netgear-R7900.patch
+++ /dev/null
@@ -1,64 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
-Subject: [PATCH] ARM: BCM5301X: Add DT for Netgear R7900
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
----
-
---- a/arch/arm/boot/dts/Makefile
-+++ b/arch/arm/boot/dts/Makefile
-@@ -117,6 +117,7 @@ dtb-$(CONFIG_ARCH_BCM_5301X) += \
- bcm4709-buffalo-wxr-1900dhp.dtb \
- bcm4709-linksys-ea9200.dtb \
- bcm4709-netgear-r7000.dtb \
-+ bcm4709-netgear-r7900.dtb \
- bcm4709-netgear-r8000.dtb \
- bcm4709-tplink-archer-c9-v1.dtb \
- bcm47094-asus-rt-ac3100.dtb \
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm4709-netgear-r7900.dts
-@@ -0,0 +1,42 @@
-+/*
-+ * Broadcom BCM470X / BCM5301X ARM platform code.
-+ * DTS for Netgear R7900
-+ *
-+ * Copyright (C) 2016 Rafał Miłecki <zajec5@gmail.com>
-+ *
-+ * Licensed under the GNU/GPL. See COPYING for details.
-+ */
-+
-+/dts-v1/;
-+
-+#include "bcm4709.dtsi"
-+#include "bcm5301x-nand-cs0-bch8.dtsi"
-+
-+/ {
-+ compatible = "netgear,r7900", "brcm,bcm4709", "brcm,bcm4708";
-+ model = "Netgear R7900";
-+
-+ chosen {
-+ bootargs = "console=ttyS0,115200";
-+ };
-+
-+ memory {
-+ reg = <0x00000000 0x08000000
-+ 0x88000000 0x08000000>;
-+ };
-+
-+ axi@18000000 {
-+ usb3@23000 {
-+ reg = <0x00023000 0x1000>;
-+
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ vcc-gpio = <&chipcommon 0 GPIO_ACTIVE_HIGH>;
-+ };
-+ };
-+};
-+
-+&uart0 {
-+ status = "okay";
-+};
diff --git a/target/linux/bcm53xx/patches-5.15/500-UBI-Detect-EOF-mark-and-erase-all-remaining-blocks.patch b/target/linux/bcm53xx/patches-5.15/500-UBI-Detect-EOF-mark-and-erase-all-remaining-blocks.patch
deleted file mode 100644
index 209c57ca0b..0000000000
--- a/target/linux/bcm53xx/patches-5.15/500-UBI-Detect-EOF-mark-and-erase-all-remaining-blocks.patch
+++ /dev/null
@@ -1,59 +0,0 @@
-From 2a2af518266a29323cf30c3f9ba9ef2ceb1dd84b Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
-Date: Thu, 16 Oct 2014 20:52:16 +0200
-Subject: [PATCH] UBI: Detect EOF mark and erase all remaining blocks
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
----
- drivers/mtd/ubi/attach.c | 5 +++++
- drivers/mtd/ubi/io.c | 4 ++++
- drivers/mtd/ubi/ubi.h | 1 +
- 3 files changed, 10 insertions(+)
-
---- a/drivers/mtd/ubi/attach.c
-+++ b/drivers/mtd/ubi/attach.c
-@@ -82,6 +82,9 @@ static int self_check_ai(struct ubi_devi
- #define AV_ADD BIT(1)
- #define AV_FIND_OR_ADD (AV_FIND | AV_ADD)
-
-+/* Set on finding block with 0xdeadc0de, indicates erasing all blocks behind */
-+bool erase_all_next;
-+
- /**
- * find_or_add_av - internal function to find a volume, add a volume or do
- * both (find and add if missing).
-@@ -1580,6 +1583,8 @@ int ubi_attach(struct ubi_device *ubi, i
- if (!ai)
- return -ENOMEM;
-
-+ erase_all_next = false;
-+
- #ifdef CONFIG_MTD_UBI_FASTMAP
- /* On small flash devices we disable fastmap in any case. */
- if ((int)mtd_div_by_eb(ubi->mtd->size, ubi->mtd) <= UBI_FM_MAX_START) {
---- a/drivers/mtd/ubi/io.c
-+++ b/drivers/mtd/ubi/io.c
-@@ -717,6 +717,10 @@ int ubi_io_read_ec_hdr(struct ubi_device
- }
-
- magic = be32_to_cpu(ec_hdr->magic);
-+ if (magic == 0xdeadc0de)
-+ erase_all_next = true;
-+ if (erase_all_next)
-+ return read_err ? UBI_IO_FF_BITFLIPS : UBI_IO_FF;
- if (magic != UBI_EC_HDR_MAGIC) {
- if (mtd_is_eccerr(read_err))
- return UBI_IO_BAD_HDR_EBADMSG;
---- a/drivers/mtd/ubi/ubi.h
-+++ b/drivers/mtd/ubi/ubi.h
-@@ -820,6 +820,7 @@ extern struct mutex ubi_devices_mutex;
- extern struct blocking_notifier_head ubi_notifiers;
-
- /* attach.c */
-+extern bool erase_all_next;
- struct ubi_ainf_peb *ubi_alloc_aeb(struct ubi_attach_info *ai, int pnum,
- int ec);
- void ubi_free_aeb(struct ubi_attach_info *ai, struct ubi_ainf_peb *aeb);
diff --git a/target/linux/bcm53xx/patches-5.15/600-net-disable-GRO-by-default.patch b/target/linux/bcm53xx/patches-5.15/600-net-disable-GRO-by-default.patch
deleted file mode 100644
index 9f6343c791..0000000000
--- a/target/linux/bcm53xx/patches-5.15/600-net-disable-GRO-by-default.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Mon, 20 Jun 2022 10:01:18 +0200
-Subject: [PATCH] net: disable GRO by default
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-In many cases GRO improves network performance however it comes at a
-cost of chacksums calculations. In case of slow CPU and missing hardware
-csum calculation support GRO can actually decrease network speed.
-
-On BCM4708 *disabling* GRO results in following NAT masquarade speed
-changes:
-1. 364 Mb/s → 396 Mb/s (packet steering disabled)
-2. 341 Mb/s → 566 Mb/s (packet steering enabled)
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
----
- include/linux/netdev_features.h | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/include/linux/netdev_features.h
-+++ b/include/linux/netdev_features.h
-@@ -242,10 +242,10 @@ static inline int find_next_netdev_featu
- #define NETIF_F_UPPER_DISABLES NETIF_F_LRO
-
- /* changeable features with no special hardware requirements */
--#define NETIF_F_SOFT_FEATURES (NETIF_F_GSO | NETIF_F_GRO)
-+#define NETIF_F_SOFT_FEATURES (NETIF_F_GSO)
-
- /* Changeable features with no special hardware requirements that defaults to off. */
--#define NETIF_F_SOFT_FEATURES_OFF (NETIF_F_GRO_FRAGLIST | NETIF_F_GRO_UDP_FWD)
-+#define NETIF_F_SOFT_FEATURES_OFF (NETIF_F_GRO_FRAGLIST | NETIF_F_GRO_UDP_FWD | NETIF_F_GRO)
-
- #define NETIF_F_VLAN_FEATURES (NETIF_F_HW_VLAN_CTAG_FILTER | \
- NETIF_F_HW_VLAN_CTAG_RX | \
diff --git a/target/linux/bcm53xx/patches-5.15/700-bgmac-reduce-max-frame-size-to-support-just-MTU-1500.patch b/target/linux/bcm53xx/patches-5.15/700-bgmac-reduce-max-frame-size-to-support-just-MTU-1500.patch
deleted file mode 100644
index 3a2f4b06ed..0000000000
--- a/target/linux/bcm53xx/patches-5.15/700-bgmac-reduce-max-frame-size-to-support-just-MTU-1500.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 10 Jun 2022 13:10:47 +0200
-Subject: [PATCH] bgmac: reduce max frame size to support just MTU 1500
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-bgmac allocates new replacement buffer before handling each received
-frame. Allocating & DMA-preparing 9724 B each time consumes a lot of CPU
-time. Ideally bgmac should just respect currently set MTU but it isn't
-the case right now. For now just revert back to the old limited frame
-size.
-
-This change bumps NAT masquarade speed by ~95%.
-
-Ref: 8c7da63978f1 ("bgmac: configure MTU and add support for frames beyond 8192 byte size")
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
----
- drivers/net/ethernet/broadcom/bgmac.h | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
---- a/drivers/net/ethernet/broadcom/bgmac.h
-+++ b/drivers/net/ethernet/broadcom/bgmac.h
-@@ -328,8 +328,7 @@
- #define BGMAC_RX_FRAME_OFFSET 30 /* There are 2 unused bytes between header and real data */
- #define BGMAC_RX_BUF_OFFSET (NET_SKB_PAD + NET_IP_ALIGN - \
- BGMAC_RX_FRAME_OFFSET)
--/* Jumbo frame size with FCS */
--#define BGMAC_RX_MAX_FRAME_SIZE 9724
-+#define BGMAC_RX_MAX_FRAME_SIZE 1536
- #define BGMAC_RX_BUF_SIZE (BGMAC_RX_FRAME_OFFSET + BGMAC_RX_MAX_FRAME_SIZE)
- #define BGMAC_RX_ALLOC_SIZE (SKB_DATA_ALIGN(BGMAC_RX_BUF_SIZE + BGMAC_RX_BUF_OFFSET) + \
- SKB_DATA_ALIGN(sizeof(struct skb_shared_info)))
diff --git a/target/linux/bcm53xx/patches-5.15/905-BCM53573-minor-hacks.patch b/target/linux/bcm53xx/patches-5.15/905-BCM53573-minor-hacks.patch
deleted file mode 100644
index e063f02aa9..0000000000
--- a/target/linux/bcm53xx/patches-5.15/905-BCM53573-minor-hacks.patch
+++ /dev/null
@@ -1,80 +0,0 @@
-From 6f1c62440eb6846cb8045d7a5480ec7bbe47c96f Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Mon, 15 Aug 2016 10:30:41 +0200
-Subject: [PATCH] BCM53573 minor hacks
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
----
-
---- a/arch/arm/boot/dts/bcm53573.dtsi
-+++ b/arch/arm/boot/dts/bcm53573.dtsi
-@@ -54,6 +54,7 @@
- <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
- <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
- <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
-+ clocks = <&ilp>;
- };
-
- clocks {
---- a/drivers/bcma/main.c
-+++ b/drivers/bcma/main.c
-@@ -330,14 +330,6 @@ static int bcma_register_devices(struct
- }
- #endif
-
--#ifdef CONFIG_BCMA_SFLASH
-- if (bus->drv_cc.sflash.present) {
-- err = platform_device_register(&bcma_sflash_dev);
-- if (err)
-- bcma_err(bus, "Error registering serial flash\n");
-- }
--#endif
--
- #ifdef CONFIG_BCMA_NFLASH
- if (bus->drv_cc.nflash.present) {
- err = platform_device_register(&bcma_nflash_dev);
-@@ -415,6 +407,14 @@ int bcma_bus_register(struct bcma_bus *b
- bcma_register_core(bus, core);
- }
-
-+#ifdef CONFIG_BCMA_SFLASH
-+ if (bus->drv_cc.sflash.present) {
-+ err = platform_device_register(&bcma_sflash_dev);
-+ if (err)
-+ bcma_err(bus, "Error registering serial flash\n");
-+ }
-+#endif
-+
- /* Try to get SPROM */
- err = bcma_sprom_get(bus);
- if (err == -ENOENT) {
---- a/drivers/clocksource/arm_arch_timer.c
-+++ b/drivers/clocksource/arm_arch_timer.c
-@@ -14,6 +14,7 @@
- #include <linux/smp.h>
- #include <linux/cpu.h>
- #include <linux/cpu_pm.h>
-+#include <linux/clk.h>
- #include <linux/clockchips.h>
- #include <linux/clocksource.h>
- #include <linux/clocksource_ids.h>
-@@ -946,6 +947,16 @@ static void __init arch_timer_of_configu
- if (of_property_read_u32(np, "clock-frequency", &arch_timer_rate))
- arch_timer_rate = rate;
-
-+ /* Get clk rate through clk driver if present */
-+ if (!arch_timer_rate) {
-+ struct clk *clk = of_clk_get(np, 0);
-+
-+ if (!IS_ERR(clk)) {
-+ if (!clk_prepare_enable(clk))
-+ arch_timer_rate = clk_get_rate(clk);
-+ }
-+ }
-+
- /* Check the timer frequency. */
- if (validate_timer_rate())
- pr_warn("frequency not available\n");
diff --git a/target/linux/bcm53xx/patches-6.1/030-v6.2-0001-ARM-dts-bcm53016-Add-devicetree-for-D-Link-DWL-8610A.patch b/target/linux/bcm53xx/patches-6.1/030-v6.2-0001-ARM-dts-bcm53016-Add-devicetree-for-D-Link-DWL-8610A.patch
deleted file mode 100644
index 0439e38991..0000000000
--- a/target/linux/bcm53xx/patches-6.1/030-v6.2-0001-ARM-dts-bcm53016-Add-devicetree-for-D-Link-DWL-8610A.patch
+++ /dev/null
@@ -1,165 +0,0 @@
-From 9f66e1dd82e3186aee95282657512ca2aef1afe0 Mon Sep 17 00:00:00 2001
-From: Linus Walleij <linus.walleij@linaro.org>
-Date: Wed, 19 Oct 2022 21:34:49 +0200
-Subject: [PATCH] ARM: dts: bcm53016: Add devicetree for D-Link DWL-8610AP
-
-This adds a device tree for the BCM53016-based D-Link DWL-8610AP
-access point wireless router.
-
-The TRX-format partitions had to be named "firmware" due to
-an OpenWrt patch that only accepts parting such nodes if they
-are named "firmware".
-
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-Link: https://lore.kernel.org/r/20221019193449.3036010-2-linus.walleij@linaro.org
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/Makefile | 1 +
- .../boot/dts/bcm53016-dlink-dwl-8610ap.dts | 131 ++++++++++++++++++
- 2 files changed, 132 insertions(+)
- create mode 100644 arch/arm/boot/dts/bcm53016-dlink-dwl-8610ap.dts
-
---- a/arch/arm/boot/dts/Makefile
-+++ b/arch/arm/boot/dts/Makefile
-@@ -139,6 +139,7 @@ dtb-$(CONFIG_ARCH_BCM_5301X) += \
- bcm47094-netgear-r8500.dtb \
- bcm47094-phicomm-k3.dtb \
- bcm53015-meraki-mr26.dtb \
-+ bcm53016-dlink-dwl-8610ap.dtb \
- bcm53016-meraki-mr32.dtb \
- bcm94708.dtb \
- bcm94709.dtb \
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm53016-dlink-dwl-8610ap.dts
-@@ -0,0 +1,131 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-+/dts-v1/;
-+
-+#include "bcm4709.dtsi"
-+#include "bcm5301x-nand-cs0-bch8.dtsi"
-+#include <dt-bindings/leds/common.h>
-+#include <dt-bindings/input/input.h>
-+
-+/ {
-+ model = "D-Link DWL-8610AP";
-+ compatible = "dlink,dwl-8610ap", "brcm,bcm53016", "brcm,bcm4708";
-+
-+ memory@0 {
-+ device_type = "memory";
-+ /* 512 MB RAM in 2 x Macronix D9PSH chips */
-+ reg = <0x00000000 0x08000000>,
-+ <0x88000000 0x08000000>;
-+ };
-+
-+ leds {
-+ compatible = "gpio-leds";
-+
-+ power {
-+ function = LED_FUNCTION_POWER;
-+ color = <LED_COLOR_ID_GREEN>;
-+ gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
-+ default-state = "on";
-+ };
-+
-+ diag {
-+ /* Actually "diag" unclear what this means */
-+ function = LED_FUNCTION_INDICATOR;
-+ color = <LED_COLOR_ID_RED>;
-+ gpios = <&chipcommon 1 GPIO_ACTIVE_LOW>;
-+ default-state = "on";
-+ linux,default-trigger = "heartbeat";
-+ };
-+
-+ wlan-2g {
-+ function = LED_FUNCTION_WLAN;
-+ color = <LED_COLOR_ID_GREEN>;
-+ gpios = <&chipcommon 5 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ wlan-5g {
-+ function = LED_FUNCTION_WLAN;
-+ color = <LED_COLOR_ID_GREEN>;
-+ gpios = <&chipcommon 8 GPIO_ACTIVE_LOW>;
-+ };
-+ };
-+
-+ gpio_keys {
-+ compatible = "gpio-keys";
-+
-+ button-reset {
-+ debounce-interval = <100>;
-+ wakeup-source;
-+ linux,code = <KEY_RESTART>;
-+ label = "reset";
-+ /* This GPIO is actually stored in NVRAM, but it's not gonna change */
-+ gpios = <&chipcommon 4 GPIO_ACTIVE_LOW>;
-+ };
-+ };
-+
-+ /*
-+ * Flash memory at 0x1e000000-0x1fffffff
-+ * Macronix 32 64KB blocks; total size 2MB, same that can be
-+ * found attached to the spi_nor SPI controller.
-+ */
-+ nvram@1e080000 {
-+ compatible = "brcm,nvram";
-+ reg = <0x1e080000 0x00020000>;
-+
-+ et0macaddr: et0macaddr {
-+ };
-+
-+ et1macaddr: et1macaddr {
-+ };
-+ };
-+};
-+
-+&gmac0 {
-+ nvmem-cells = <&et0macaddr>;
-+ nvmem-cell-names = "mac-address";
-+};
-+
-+&gmac1 {
-+ nvmem-cells = <&et1macaddr>;
-+ nvmem-cell-names = "mac-address";
-+};
-+
-+&spi_nor {
-+ /* Serial SPI NOR Flash MX 25L1606E */
-+ status = "okay";
-+};
-+
-+&nandcs {
-+ /*
-+ * Spansion S34ML01G100TFI00 128 MB NAND Flash memory
-+ *
-+ * This ECC is a bit unorthodox but it is what the stock firmware
-+ * is using, so to be able to mount the original partitions
-+ * this is necessary.
-+ */
-+ nand-ecc-strength = <5>;
-+ partitions {
-+ compatible = "fixed-partitions";
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ /* This is named nflash1.trx in CFE */
-+ trx@0 {
-+ label = "firmware";
-+ reg = <0x00000000 0x02800000>;
-+ compatible = "brcm,trx";
-+ };
-+
-+ /* This is named nflash1.trx2 in CFE */
-+ trx2@2800000 {
-+ label = "firmware2";
-+ reg = <0x02800000 0x02800000>;
-+ compatible = "brcm,trx";
-+ };
-+
-+ /* This is named nflash1.rwfs in CFE */
-+ free@5000000 {
-+ label = "free";
-+ reg = <0x05000000 0x03000000>;
-+ };
-+ };
-+};
diff --git a/target/linux/bcm53xx/patches-6.1/030-v6.2-0002-ARM-dts-bcm47094-Add-devicetree-for-D-Link-DIR-890L.patch b/target/linux/bcm53xx/patches-6.1/030-v6.2-0002-ARM-dts-bcm47094-Add-devicetree-for-D-Link-DIR-890L.patch
deleted file mode 100644
index 21bb94fcc3..0000000000
--- a/target/linux/bcm53xx/patches-6.1/030-v6.2-0002-ARM-dts-bcm47094-Add-devicetree-for-D-Link-DIR-890L.patch
+++ /dev/null
@@ -1,242 +0,0 @@
-From b1ba87897ceda8e49a47aa92832dd7bff8583e21 Mon Sep 17 00:00:00 2001
-From: Linus Walleij <linus.walleij@linaro.org>
-Date: Mon, 7 Nov 2022 14:41:04 +0100
-Subject: [PATCH] ARM: dts: bcm47094: Add devicetree for D-Link DIR-890L
-
-This adds a device tree for the D-Link DIR-890L. This device
-is very similar to D-Link DIR-885L, the differences are detailed
-as a comment in the DTS file.
-
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-Link: https://lore.kernel.org/r/20221107134104.1422169-2-linus.walleij@linaro.org
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/Makefile | 1 +
- arch/arm/boot/dts/bcm47094-dlink-dir-890l.dts | 211 ++++++++++++++++++
- 2 files changed, 212 insertions(+)
- create mode 100644 arch/arm/boot/dts/bcm47094-dlink-dir-890l.dts
-
---- a/arch/arm/boot/dts/Makefile
-+++ b/arch/arm/boot/dts/Makefile
-@@ -129,6 +129,7 @@ dtb-$(CONFIG_ARCH_BCM_5301X) += \
- bcm4709-tplink-archer-c9-v1.dtb \
- bcm47094-asus-rt-ac88u.dtb \
- bcm47094-dlink-dir-885l.dtb \
-+ bcm47094-dlink-dir-890l.dtb \
- bcm47094-linksys-panamera.dtb \
- bcm47094-luxul-abr-4500.dtb \
- bcm47094-luxul-xap-1610.dtb \
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm47094-dlink-dir-890l.dts
-@@ -0,0 +1,211 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-+/*
-+ * Device tree for D-Link DIR-890L
-+ * D-Link calls this board "WRGAC36"
-+ * this router has the same looks and form factor as D-Link DIR-885L.
-+ *
-+ * Some differences from DIR-885L include a separate USB2 port, separate LEDs
-+ * for USB2 and USB3, a separate VCC supply for the USB2 slot and no
-+ * router/extender switch is mounted (there is an empty mount point on the
-+ * PCB) so this device is a pure router. Also the LAN ports are in the right
-+ * order.
-+ *
-+ * Based on the device tree for DIR-885L
-+ * Copyright (C) 2016 Rafał Miłecki <zajec5@gmail.com>
-+ * Copyright (C) 2022 Linus Walleij
-+ */
-+
-+/dts-v1/;
-+
-+#include "bcm47094.dtsi"
-+#include "bcm5301x-nand-cs0-bch1.dtsi"
-+
-+/ {
-+ compatible = "dlink,dir-890l", "brcm,bcm47094", "brcm,bcm4708";
-+ model = "D-Link DIR-890L";
-+
-+ chosen {
-+ bootargs = "console=ttyS0,115200 earlycon";
-+ };
-+
-+ memory@0 {
-+ device_type = "memory";
-+ reg = <0x00000000 0x08000000>,
-+ <0x88000000 0x08000000>;
-+ };
-+
-+ leds {
-+ /*
-+ * LED information is derived from the boot log which
-+ * conveniently lists all the LEDs.
-+ */
-+ compatible = "gpio-leds";
-+
-+ power-white {
-+ label = "bcm53xx:white:power";
-+ gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
-+ linux,default-trigger = "default-on";
-+ };
-+
-+ wan-white {
-+ label = "bcm53xx:white:wan";
-+ gpios = <&chipcommon 1 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ power-amber {
-+ label = "bcm53xx:amber:power";
-+ gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ wan-amber {
-+ label = "bcm53xx:amber:wan";
-+ gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ usb3-white {
-+ label = "bcm53xx:white:usb3";
-+ gpios = <&chipcommon 8 GPIO_ACTIVE_LOW>;
-+ trigger-sources = <&xhci_port1>;
-+ linux,default-trigger = "usbport";
-+ };
-+
-+ usb2-white {
-+ label = "bcm53xx:white:usb2";
-+ gpios = <&chipcommon 15 GPIO_ACTIVE_LOW>;
-+ trigger-sources = <&ohci_port1>, <&ehci_port1>;
-+ linux,default-trigger = "usbport";
-+ };
-+
-+ 2ghz {
-+ label = "bcm53xx:white:2ghz";
-+ gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ 5ghz {
-+ label = "bcm53xx:white:5ghz";
-+ gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
-+ };
-+ };
-+
-+ gpio-keys {
-+ compatible = "gpio-keys";
-+
-+ button-wps {
-+ label = "WPS";
-+ linux,code = <KEY_WPS_BUTTON>;
-+ gpios = <&chipcommon 7 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ /* Called "factory reset" in the vendor dmesg */
-+ button-restart {
-+ label = "Reset";
-+ linux,code = <KEY_RESTART>;
-+ gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>;
-+ };
-+ };
-+
-+ /*
-+ * The flash memory is memory mapped at 0x1e000000-0x1fffffff
-+ * 64KB blocks; total size 2MB, same that can be
-+ * found attached to the spi_nor SPI controller.
-+ */
-+ nvram@1e1f0000 {
-+ compatible = "brcm,nvram";
-+ reg = <0x1e1f0000 0x00010000>;
-+
-+ et0macaddr: et0macaddr {
-+ };
-+ };
-+};
-+
-+&gmac2 {
-+ /*
-+ * The NVRAM curiously does not contain a MAC address
-+ * for et2 so since that is the only ethernet interface
-+ * actually in use on the platform, we use this et0 MAC
-+ * address for et2.
-+ */
-+ nvmem-cells = <&et0macaddr>;
-+ nvmem-cell-names = "mac-address";
-+};
-+
-+&spi_nor {
-+ status = "okay";
-+};
-+
-+&nandcs {
-+ /* Spansion S34ML01G2, 128MB with 128KB erase blocks */
-+ partitions {
-+ compatible = "fixed-partitions";
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ /*
-+ * This is called "nflash" in the vendor kernel with
-+ * "upgrade" and "rootfs" (probably using OpenWrt
-+ * splitpart). We call it "firmware" like standard tools
-+ * assume. The CFE loader contains incorrect information
-+ * about TRX partitions, ignore this, there are no TRX
-+ * partitions: this device uses SEAMA.
-+ */
-+ firmware@0 {
-+ label = "firmware";
-+ reg = <0x00000000 0x08000000>;
-+ };
-+ };
-+};
-+
-+&usb2 {
-+ vcc-gpios = <&chipcommon 21 GPIO_ACTIVE_HIGH>;
-+};
-+
-+&usb3 {
-+ vcc-gpios = <&chipcommon 18 GPIO_ACTIVE_HIGH>;
-+};
-+
-+&usb3_phy {
-+ status = "okay";
-+};
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ reg = <0>;
-+ label = "lan1";
-+ };
-+
-+ port@1 {
-+ reg = <1>;
-+ label = "lan2";
-+ };
-+
-+ port@2 {
-+ reg = <2>;
-+ label = "lan3";
-+ };
-+
-+ port@3 {
-+ reg = <3>;
-+ label = "lan4";
-+ };
-+
-+ port@4 {
-+ reg = <4>;
-+ label = "wan";
-+ };
-+
-+ port@8 {
-+ reg = <8>;
-+ label = "cpu";
-+ ethernet = <&gmac2>;
-+ phy-mode = "rgmii";
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
-+ };
-+ };
-+};
diff --git a/target/linux/bcm53xx/patches-6.1/030-v6.2-0003-ARM-dts-BCM5301X-Correct-description-of-TP-Link-part.patch b/target/linux/bcm53xx/patches-6.1/030-v6.2-0003-ARM-dts-BCM5301X-Correct-description-of-TP-Link-part.patch
deleted file mode 100644
index 4c4ed036b9..0000000000
--- a/target/linux/bcm53xx/patches-6.1/030-v6.2-0003-ARM-dts-BCM5301X-Correct-description-of-TP-Link-part.patch
+++ /dev/null
@@ -1,99 +0,0 @@
-From c8ee9f119bfb4244f76c9971c341ec06b49332cd Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Tue, 8 Nov 2022 12:07:08 +0100
-Subject: [PATCH] ARM: dts: BCM5301X: Correct description of TP-Link partitions
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-TP-Link routers have flash space partitioned according to the partitions
-table. It may look like fixed partitioning but those partitions can be
-actually reorganized. New can be added (or some removed), offsets and
-sizes may change.
-
-Fix DT to use binding for the TP-Link SafeLoader partitioning method.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20221108110708.13693-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- .../boot/dts/bcm47081-tplink-archer-c5-v2.dts | 25 ++++---------------
- .../boot/dts/bcm4709-tplink-archer-c9-v1.dts | 25 ++++---------------
- 2 files changed, 10 insertions(+), 40 deletions(-)
-
---- a/arch/arm/boot/dts/bcm47081-tplink-archer-c5-v2.dts
-+++ b/arch/arm/boot/dts/bcm47081-tplink-archer-c5-v2.dts
-@@ -95,30 +95,15 @@
- status = "okay";
-
- partitions {
-- compatible = "fixed-partitions";
-- #address-cells = <1>;
-- #size-cells = <1>;
-+ compatible = "tplink,safeloader-partitions";
-+ partitions-table-offset = <0xe50000>;
-
-- boot@0 {
-- label = "boot";
-- reg = <0x000000 0x040000>;
-- read-only;
-- };
--
-- os-image@100000 {
-- label = "os-image";
-- reg = <0x040000 0x200000>;
-+ partition-os-image {
- compatible = "brcm,trx";
- };
-
-- rootfs@240000 {
-- label = "rootfs";
-- reg = <0x240000 0xc00000>;
-- };
--
-- nvram@ff0000 {
-- label = "nvram";
-- reg = <0xff0000 0x010000>;
-+ partition-file-system {
-+ linux,rootfs;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts
-+++ b/arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts
-@@ -104,30 +104,15 @@
- status = "okay";
-
- partitions {
-- compatible = "fixed-partitions";
-- #address-cells = <1>;
-- #size-cells = <1>;
-+ compatible = "tplink,safeloader-partitions";
-+ partitions-table-offset = <0xe50000>;
-
-- boot@0 {
-- label = "boot";
-- reg = <0x000000 0x040000>;
-- read-only;
-- };
--
-- os-image@100000 {
-- label = "os-image";
-- reg = <0x040000 0x200000>;
-+ partition-os-image {
- compatible = "brcm,trx";
- };
-
-- rootfs@240000 {
-- label = "rootfs";
-- reg = <0x240000 0xc00000>;
-- };
--
-- nvram@ff0000 {
-- label = "nvram";
-- reg = <0xff0000 0x010000>;
-+ partition-file-system {
-+ linux,rootfs;
- };
- };
- };
diff --git a/target/linux/bcm53xx/patches-6.1/030-v6.2-0004-ARM-dts-broadcom-align-LED-node-names-with-dtschema.patch b/target/linux/bcm53xx/patches-6.1/030-v6.2-0004-ARM-dts-broadcom-align-LED-node-names-with-dtschema.patch
deleted file mode 100644
index d6bf49d0cd..0000000000
--- a/target/linux/bcm53xx/patches-6.1/030-v6.2-0004-ARM-dts-broadcom-align-LED-node-names-with-dtschema.patch
+++ /dev/null
@@ -1,1700 +0,0 @@
-From af84101e3f2258a303fa2461ebec0878ce23ea10 Mon Sep 17 00:00:00 2001
-From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Date: Fri, 25 Nov 2022 15:41:27 +0100
-Subject: [PATCH] ARM: dts: broadcom: align LED node names with dtschema
-
-The node names should be generic and DT schema expects certain pattern:
-
- bcm4708-asus-rt-ac68u.dtb: leds: 'logo', 'power', 'usb2', 'usb3' do not match any of the regexes: '(^led-[0-9a-f]$|led)', 'pinctrl-[0-9]+'
-
-Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Link: https://lore.kernel.org/r/20221125144128.477059-1-krzysztof.kozlowski@linaro.org
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dts | 15 +++++-----
- arch/arm/boot/dts/bcm4708-asus-rt-ac68u.dts | 8 +++---
- .../bcm4708-buffalo-wzr-1166dhp-common.dtsi | 16 +++++------
- .../boot/dts/bcm4708-buffalo-wzr-1750dhp.dts | 16 +++++------
- arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts | 6 ++--
- arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts | 2 +-
- arch/arm/boot/dts/bcm4708-netgear-r6250.dts | 10 +++----
- .../arm/boot/dts/bcm4708-netgear-r6300-v2.dts | 10 +++----
- arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts | 22 +++++++--------
- arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts | 10 +++----
- .../boot/dts/bcm47081-buffalo-wzr-600dhp2.dts | 14 +++++-----
- .../boot/dts/bcm47081-buffalo-wzr-900dhp.dts | 16 +++++------
- arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts | 6 ++--
- arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts | 20 ++++++-------
- .../boot/dts/bcm47081-tplink-archer-c5-v2.dts | 18 ++++++------
- arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts | 6 ++--
- .../boot/dts/bcm4709-buffalo-wxr-1900dhp.dts | 18 ++++++------
- arch/arm/boot/dts/bcm4709-netgear-r7000.dts | 16 +++++------
- arch/arm/boot/dts/bcm4709-netgear-r8000.dts | 22 +++++++--------
- .../boot/dts/bcm4709-tplink-archer-c9-v1.dts | 18 ++++++------
- arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts | 12 ++++----
- arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts | 14 +++++-----
- arch/arm/boot/dts/bcm47094-dlink-dir-890l.dts | 16 +++++------
- .../boot/dts/bcm47094-linksys-panamera.dts | 28 +++++++++----------
- arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts | 4 +--
- arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts | 6 ++--
- arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts | 4 +--
- arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts | 2 +-
- arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts | 20 ++++++-------
- .../boot/dts/bcm47094-luxul-xwr-3150-v1.dts | 10 +++----
- arch/arm/boot/dts/bcm47094-netgear-r8500.dts | 14 +++++-----
- arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts | 4 +--
- arch/arm/boot/dts/bcm47189-luxul-xap-810.dts | 10 +++----
- arch/arm/boot/dts/bcm47189-tenda-ac9.dts | 14 +++++-----
- .../boot/dts/bcm53016-dlink-dwl-8610ap.dts | 8 +++---
- arch/arm/boot/dts/bcm53016-meraki-mr32.dts | 6 ++--
- arch/arm/boot/dts/bcm947189acdbmr.dts | 6 ++--
- 37 files changed, 223 insertions(+), 224 deletions(-)
-
---- a/arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dts
-+++ b/arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dts
-@@ -28,40 +28,39 @@
- leds {
- compatible = "gpio-leds";
-
-- usb3 {
-+ led-usb3 {
- label = "bcm53xx:blue:usb3";
- gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
- };
-
-- wan {
-+ led-wan {
- label = "bcm53xx:blue:wan";
- gpios = <&chipcommon 1 GPIO_ACTIVE_LOW>;
- };
-
-- lan {
-+ led-lan {
- label = "bcm53xx:blue:lan";
- gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>;
- };
-
-- power {
-+ led-power {
- label = "bcm53xx:blue:power";
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- all {
-+ led-all {
- label = "bcm53xx:blue:all";
- gpios = <&chipcommon 4 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:blue:2ghz";
- gpios = <&chipcommon 6 GPIO_ACTIVE_LOW>;
- };
-
--
-- usb2 {
-+ led-usb2 {
- label = "bcm53xx:blue:usb2";
- gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
- };
---- a/arch/arm/boot/dts/bcm4708-asus-rt-ac68u.dts
-+++ b/arch/arm/boot/dts/bcm4708-asus-rt-ac68u.dts
-@@ -28,24 +28,24 @@
- leds {
- compatible = "gpio-leds";
-
-- usb2 {
-+ led-usb2 {
- label = "bcm53xx:blue:usb2";
- gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
- };
-
-- power {
-+ led-power {
- label = "bcm53xx:blue:power";
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- logo {
-+ led-logo {
- label = "bcm53xx:white:logo";
- gpios = <&chipcommon 4 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- usb3 {
-+ led-usb3 {
- label = "bcm53xx:blue:usb3";
- gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
- };
---- a/arch/arm/boot/dts/bcm4708-buffalo-wzr-1166dhp-common.dtsi
-+++ b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1166dhp-common.dtsi
-@@ -37,7 +37,7 @@
- leds {
- compatible = "gpio-leds";
-
-- usb {
-+ led-usb {
- /* label = "bcm53xx:blue:usb"; */
- function = LED_FUNCTION_USB;
- color = <LED_COLOR_ID_BLUE>;
-@@ -48,14 +48,14 @@
- linux,default-trigger = "usbport";
- };
-
-- power0 {
-+ led-power0 {
- /* label = "bcm53xx:red:power"; */
- function = LED_FUNCTION_FAULT;
- color = <LED_COLOR_ID_RED>;
- gpios = <&hc595 1 GPIO_ACTIVE_HIGH>;
- };
-
-- power1 {
-+ led-power1 {
- /* label = "bcm53xx:white:power"; */
- function = LED_FUNCTION_POWER;
- color = <LED_COLOR_ID_WHITE>;
-@@ -63,7 +63,7 @@
- linux,default-trigger = "default-on";
- };
-
-- router0 {
-+ led-router0 {
- /* label = "bcm53xx:blue:router"; */
- function = LED_FUNCTION_STATUS;
- color = <LED_COLOR_ID_BLUE>;
-@@ -71,14 +71,14 @@
- linux,default-trigger = "default-on";
- };
-
-- router1 {
-+ led-router1 {
- /* label = "bcm53xx:amber:router"; */
- function = LED_FUNCTION_STATUS;
- color = <LED_COLOR_ID_AMBER>;
- gpios = <&hc595 4 GPIO_ACTIVE_HIGH>;
- };
-
-- wan {
-+ led-wan {
- /* label = "bcm53xx:blue:wan"; */
- function = LED_FUNCTION_WAN;
- color = <LED_COLOR_ID_BLUE>;
-@@ -86,14 +86,14 @@
- linux,default-trigger = "default-on";
- };
-
-- wireless0 {
-+ led-wireless0 {
- /* label = "bcm53xx:blue:wireless"; */
- function = LED_FUNCTION_WLAN;
- color = <LED_COLOR_ID_BLUE>;
- gpios = <&hc595 6 GPIO_ACTIVE_HIGH>;
- };
-
-- wireless1 {
-+ led-wireless1 {
- /* label = "bcm53xx:amber:wireless"; */
- function = LED_FUNCTION_WLAN;
- color = <LED_COLOR_ID_AMBER>;
---- a/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts
-+++ b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts
-@@ -49,7 +49,7 @@
- leds {
- compatible = "gpio-leds";
-
-- usb {
-+ led-usb {
- label = "bcm53xx:blue:usb";
- gpios = <&hc595 0 GPIO_ACTIVE_HIGH>;
- trigger-sources = <&ohci_port1>, <&ehci_port1>,
-@@ -58,40 +58,40 @@
- linux,default-trigger = "usbport";
- };
-
-- power0 {
-+ led-power0 {
- label = "bcm53xx:red:power";
- gpios = <&hc595 1 GPIO_ACTIVE_HIGH>;
- };
-
-- power1 {
-+ led-power1 {
- label = "bcm53xx:white:power";
- gpios = <&hc595 2 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- router0 {
-+ led-router0 {
- label = "bcm53xx:blue:router";
- gpios = <&hc595 3 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- router1 {
-+ led-router1 {
- label = "bcm53xx:amber:router";
- gpios = <&hc595 4 GPIO_ACTIVE_HIGH>;
- };
-
-- wan {
-+ led-wan {
- label = "bcm53xx:blue:wan";
- gpios = <&hc595 5 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- wireless0 {
-+ led-wireless0 {
- label = "bcm53xx:blue:wireless";
- gpios = <&hc595 6 GPIO_ACTIVE_HIGH>;
- };
-
-- wireless1 {
-+ led-wireless1 {
- label = "bcm53xx:amber:wireless";
- gpios = <&hc595 7 GPIO_ACTIVE_HIGH>;
- };
---- a/arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts
-+++ b/arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts
-@@ -23,19 +23,19 @@
- leds {
- compatible = "gpio-leds";
-
-- 5ghz {
-+ led-5ghz {
- label = "bcm53xx:blue:5ghz";
- gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "none";
- };
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:blue:2ghz";
- gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "none";
- };
-
-- status {
-+ led-status {
- label = "bcm53xx:green:status";
- gpios = <&chipcommon 15 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "timer";
---- a/arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts
-+++ b/arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts
-@@ -42,7 +42,7 @@
- leds {
- compatible = "gpio-leds";
-
-- status {
-+ led-status {
- label = "bcm53xx:green:status";
- gpios = <&chipcommon 0 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "timer";
---- a/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
-+++ b/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
-@@ -29,24 +29,24 @@
- leds {
- compatible = "gpio-leds";
-
-- logo {
-+ led-logo {
- label = "bcm53xx:white:logo";
- gpios = <&chipcommon 1 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- power0 {
-+ led-power0 {
- label = "bcm53xx:green:power";
- gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- power1 {
-+ led-power1 {
- label = "bcm53xx:amber:power";
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- };
-
-- usb {
-+ led-usb {
- label = "bcm53xx:blue:usb";
- gpios = <&chipcommon 8 GPIO_ACTIVE_LOW>;
- trigger-sources = <&ohci_port1>, <&ehci_port1>,
-@@ -54,7 +54,7 @@
- linux,default-trigger = "usbport";
- };
-
-- wireless {
-+ led-wireless {
- label = "bcm53xx:blue:wireless";
- gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
- };
---- a/arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts
-+++ b/arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts
-@@ -28,29 +28,29 @@
- leds {
- compatible = "gpio-leds";
-
-- logo {
-+ led-logo {
- label = "bcm53xx:white:logo";
- gpios = <&chipcommon 1 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- power0 {
-+ led-power0 {
- label = "bcm53xx:green:power";
- gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>;
- };
-
-- power1 {
-+ led-power1 {
- label = "bcm53xx:amber:power";
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- usb {
-+ led-usb {
- label = "bcm53xx:blue:usb";
- gpios = <&chipcommon 8 GPIO_ACTIVE_LOW>;
- };
-
-- wireless {
-+ led-wireless {
- label = "bcm53xx:blue:wireless";
- gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
- };
---- a/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts
-+++ b/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts
-@@ -28,64 +28,64 @@
- leds {
- compatible = "gpio-leds";
-
-- power-white {
-+ led-power-white {
- label = "bcm53xx:white:power";
- gpios = <&chipcommon 1 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- power-amber {
-+ led-power-amber {
- label = "bcm53xx:amber:power";
- gpios = <&chipcommon 2 GPIO_ACTIVE_HIGH>;
- };
-
-- usb2 {
-+ led-usb2 {
- label = "bcm53xx:white:usb2";
- gpios = <&chipcommon 3 GPIO_ACTIVE_HIGH>;
- trigger-sources = <&ohci_port2>, <&ehci_port2>;
- linux,default-trigger = "usbport";
- };
-
-- usb3-white {
-+ led-usb3-white {
- label = "bcm53xx:white:usb3";
- gpios = <&chipcommon 4 GPIO_ACTIVE_HIGH>;
- trigger-sources = <&xhci_port1>;
- linux,default-trigger = "usbport";
- };
-
-- usb3-green {
-+ led-usb3-green {
- label = "bcm53xx:green:usb3";
- gpios = <&chipcommon 5 GPIO_ACTIVE_HIGH>;
- trigger-sources = <&ohci_port1>, <&ehci_port1>;
- linux,default-trigger = "usbport";
- };
-
-- wps {
-+ led-wps {
- label = "bcm53xx:white:wps";
- gpios = <&chipcommon 6 GPIO_ACTIVE_HIGH>;
- };
-
-- status-red {
-+ led-status-red {
- label = "bcm53xx:red:status";
- gpios = <&chipcommon 8 GPIO_ACTIVE_HIGH>;
- };
-
-- status-green {
-+ led-status-green {
- label = "bcm53xx:green:status";
- gpios = <&chipcommon 9 GPIO_ACTIVE_HIGH>;
- };
-
-- status-blue {
-+ led-status-blue {
- label = "bcm53xx:blue:status";
- gpios = <&chipcommon 10 GPIO_ACTIVE_HIGH>;
- };
-
-- wan-white {
-+ led-wan-white {
- label = "bcm53xx:white:wan";
- gpios = <&chipcommon 12 GPIO_ACTIVE_HIGH>;
- };
-
-- wan-red {
-+ led-wan-red {
- label = "bcm53xx:red:wan";
- gpios = <&chipcommon 13 GPIO_ACTIVE_HIGH>;
- };
---- a/arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts
-+++ b/arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts
-@@ -28,30 +28,30 @@
- leds {
- compatible = "gpio-leds";
-
-- power {
-+ led-power {
- label = "bcm53xx:blue:power";
- gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- usb2 {
-+ led-usb2 {
- label = "bcm53xx:blue:usb2";
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- };
-
-- wan {
-+ led-wan {
- label = "bcm53xx:blue:wan";
- gpios = <&chipcommon 6 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- lan {
-+ led-lan {
- label = "bcm53xx:blue:lan";
- gpios = <&chipcommon 9 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- usb3 {
-+ led-usb3 {
- label = "bcm53xx:blue:usb3";
- gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
- };
---- a/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
-+++ b/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
-@@ -49,40 +49,40 @@
- leds {
- compatible = "gpio-leds";
-
-- power0 {
-+ led-power0 {
- label = "bcm53xx:green:power";
- gpios = <&hc595 1 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- power1 {
-+ led-power1 {
- label = "bcm53xx:red:power";
- gpios = <&hc595 2 GPIO_ACTIVE_HIGH>;
- };
-
-- router0 {
-+ led-router0 {
- label = "bcm53xx:green:router";
- gpios = <&hc595 3 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- router1 {
-+ led-router1 {
- label = "bcm53xx:amber:router";
- gpios = <&hc595 4 GPIO_ACTIVE_HIGH>;
- };
-
-- wan {
-+ led-wan {
- label = "bcm53xx:green:wan";
- gpios = <&hc595 5 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- wireless0 {
-+ led-wireless0 {
- label = "bcm53xx:green:wireless";
- gpios = <&hc595 6 GPIO_ACTIVE_HIGH>;
- };
-
-- wireless1 {
-+ led-wireless1 {
- label = "bcm53xx:amber:wireless";
- gpios = <&hc595 7 GPIO_ACTIVE_HIGH>;
- };
---- a/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts
-+++ b/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts
-@@ -49,45 +49,45 @@
- leds {
- compatible = "gpio-leds";
-
-- usb {
-+ led-usb {
- label = "bcm53xx:green:usb";
- gpios = <&hc595 0 GPIO_ACTIVE_HIGH>;
- };
-
-- power0 {
-+ led-power0 {
- label = "bcm53xx:green:power";
- gpios = <&hc595 1 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- power1 {
-+ led-power1 {
- label = "bcm53xx:red:power";
- gpios = <&hc595 2 GPIO_ACTIVE_HIGH>;
- };
-
-- router0 {
-+ led-router0 {
- label = "bcm53xx:green:router";
- gpios = <&hc595 3 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- router1 {
-+ led-router1 {
- label = "bcm53xx:amber:router";
- gpios = <&hc595 4 GPIO_ACTIVE_HIGH>;
- };
-
-- wan {
-+ led-wan {
- label = "bcm53xx:green:wan";
- gpios = <&hc595 5 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- wireless0 {
-+ led-wireless0 {
- label = "bcm53xx:green:wireless";
- gpios = <&hc595 6 GPIO_ACTIVE_HIGH>;
- };
-
-- wireless1 {
-+ led-wireless1 {
- label = "bcm53xx:amber:wireless";
- gpios = <&hc595 7 GPIO_ACTIVE_HIGH>;
- };
---- a/arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts
-+++ b/arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts
-@@ -23,19 +23,19 @@
- leds {
- compatible = "gpio-leds";
-
-- 5ghz {
-+ led-5ghz {
- label = "bcm53xx:blue:5ghz";
- gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "none";
- };
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:blue:2ghz";
- gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "none";
- };
-
-- status {
-+ led-status {
- label = "bcm53xx:green:status";
- gpios = <&chipcommon 15 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "timer";
---- a/arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts
-+++ b/arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts
-@@ -29,62 +29,62 @@
- leds {
- compatible = "gpio-leds";
-
-- power {
-+ led-power {
- label = "bcm53xx:green:power";
- gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- lan3 {
-+ led-lan3 {
- label = "bcm53xx:green:lan3";
- gpios = <&chipcommon 1 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "none";
- };
-
-- lan4 {
-+ led-lan4 {
- label = "bcm53xx:green:lan4";
- gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "none";
- };
-
-- wan {
-+ led-wan {
- label = "bcm53xx:green:wan";
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "none";
- };
-
-- lan2 {
-+ led-lan2 {
- label = "bcm53xx:green:lan2";
- gpios = <&chipcommon 6 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "none";
- };
-
-- usb {
-+ led-usb {
- label = "bcm53xx:green:usb";
- gpios = <&chipcommon 8 GPIO_ACTIVE_LOW>;
- trigger-sources = <&ohci_port2>, <&ehci_port2>;
- linux,default-trigger = "usbport";
- };
-
-- status {
-+ led-status {
- label = "bcm53xx:green:status";
- gpios = <&chipcommon 10 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "timer";
- };
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:green:2ghz";
- gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "none";
- };
-
-- 5ghz {
-+ led-5ghz {
- label = "bcm53xx:green:5ghz";
- gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "none";
- };
-
-- lan1 {
-+ led-lan1 {
- label = "bcm53xx:green:lan1";
- gpios = <&chipcommon 15 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "none";
---- a/arch/arm/boot/dts/bcm47081-tplink-archer-c5-v2.dts
-+++ b/arch/arm/boot/dts/bcm47081-tplink-archer-c5-v2.dts
-@@ -23,50 +23,50 @@
- leds {
- compatible = "gpio-leds";
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:green:2ghz";
- gpios = <&chipcommon 0 GPIO_ACTIVE_HIGH>;
- };
-
-- lan {
-+ led-lan {
- label = "bcm53xx:green:lan";
- gpios = <&chipcommon 1 GPIO_ACTIVE_HIGH>;
- };
-
-- usb2-port1 {
-+ led-usb2-port1 {
- label = "bcm53xx:green:usb2-port1";
- gpios = <&chipcommon 2 GPIO_ACTIVE_HIGH>;
- trigger-sources = <&ohci_port1>, <&ehci_port1>;
- linux,default-trigger = "usbport";
- };
-
-- power {
-+ led-power {
- label = "bcm53xx:green:power";
- gpios = <&chipcommon 4 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- wan-green {
-+ led-wan-green {
- label = "bcm53xx:green:wan";
- gpios = <&chipcommon 5 GPIO_ACTIVE_HIGH>;
- };
-
-- wps {
-+ led-wps {
- label = "bcm53xx:green:wps";
- gpios = <&chipcommon 6 GPIO_ACTIVE_HIGH>;
- };
-
-- wan-amber {
-+ led-wan-amber {
- label = "bcm53xx:amber:wan";
- gpios = <&chipcommon 8 GPIO_ACTIVE_HIGH>;
- };
-
-- 5ghz {
-+ led-5ghz {
- label = "bcm53xx:green:5ghz";
- gpios = <&chipcommon 12 GPIO_ACTIVE_HIGH>;
- };
-
-- usb2-port2 {
-+ led-usb2-port2 {
- label = "bcm53xx:green:usb2-port2";
- gpios = <&chipcommon 13 GPIO_ACTIVE_HIGH>;
- trigger-sources = <&ohci_port2>, <&ehci_port2>;
---- a/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts
-+++ b/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts
-@@ -28,18 +28,18 @@
- leds {
- compatible = "gpio-leds";
-
-- wps {
-+ led-wps {
- label = "bcm53xx:blue:wps";
- gpios = <&chipcommon 1 GPIO_ACTIVE_LOW>;
- };
-
-- power {
-+ led-power {
- label = "bcm53xx:blue:power";
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- wan {
-+ led-wan {
- label = "bcm53xx:red:wan";
- gpios = <&chipcommon 5 GPIO_ACTIVE_LOW>;
- };
---- a/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts
-+++ b/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts
-@@ -28,48 +28,48 @@
- leds {
- compatible = "gpio-leds";
-
-- usb {
-+ led-usb {
- label = "bcm53xx:green:usb";
- gpios = <&chipcommon 4 GPIO_ACTIVE_HIGH>;
- };
-
-- power-amber {
-+ led-power-amber {
- label = "bcm53xx:amber:power";
- gpios = <&chipcommon 5 GPIO_ACTIVE_HIGH>;
- };
-
-- power-white {
-+ led-power-white {
- label = "bcm53xx:white:power";
- gpios = <&chipcommon 6 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- router-amber {
-+ led-router-amber {
- label = "bcm53xx:amber:router";
- gpios = <&chipcommon 7 GPIO_ACTIVE_HIGH>;
- };
-
-- router-white {
-+ led-router-white {
- label = "bcm53xx:white:router";
- gpios = <&chipcommon 8 GPIO_ACTIVE_HIGH>;
- };
-
-- wan-amber {
-+ led-wan-amber {
- label = "bcm53xx:amber:wan";
- gpios = <&chipcommon 9 GPIO_ACTIVE_HIGH>;
- };
-
-- wan-white {
-+ led-wan-white {
- label = "bcm53xx:white:wan";
- gpios = <&chipcommon 10 GPIO_ACTIVE_HIGH>;
- };
-
-- wireless-amber {
-+ led-wireless-amber {
- label = "bcm53xx:amber:wireless";
- gpios = <&chipcommon 11 GPIO_ACTIVE_HIGH>;
- };
-
-- wireless-white {
-+ led-wireless-white {
- label = "bcm53xx:white:wireless";
- gpios = <&chipcommon 12 GPIO_ACTIVE_HIGH>;
- };
---- a/arch/arm/boot/dts/bcm4709-netgear-r7000.dts
-+++ b/arch/arm/boot/dts/bcm4709-netgear-r7000.dts
-@@ -28,43 +28,43 @@
- leds {
- compatible = "gpio-leds";
-
-- power-white {
-+ led-power-white {
- label = "bcm53xx:white:power";
- gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- power-amber {
-+ led-power-amber {
- label = "bcm53xx:amber:power";
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- };
-
-- 5ghz {
-+ led-5ghz {
- label = "bcm53xx:white:5ghz";
- gpios = <&chipcommon 12 GPIO_ACTIVE_LOW>;
- };
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:white:2ghz";
- gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
- };
-
-- wps {
-+ led-wps {
- label = "bcm53xx:white:wps";
- gpios = <&chipcommon 14 GPIO_ACTIVE_HIGH>;
- };
-
-- wireless {
-+ led-wireless {
- label = "bcm53xx:white:wireless";
- gpios = <&chipcommon 15 GPIO_ACTIVE_HIGH>;
- };
-
-- usb3 {
-+ led-usb3 {
- label = "bcm53xx:white:usb3";
- gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>;
- };
-
-- usb2 {
-+ led-usb2 {
- label = "bcm53xx:white:usb2";
- gpios = <&chipcommon 18 GPIO_ACTIVE_LOW>;
- };
---- a/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
-+++ b/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
-@@ -39,59 +39,59 @@
- leds {
- compatible = "gpio-leds";
-
-- power-white {
-+ led-power-white {
- label = "bcm53xx:white:power";
- gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- power-amber {
-+ led-power-amber {
- label = "bcm53xx:amber:power";
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- };
-
-- wan-white {
-+ led-wan-white {
- label = "bcm53xx:white:wan";
- gpios = <&chipcommon 8 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- wan-amber {
-+ led-wan-amber {
- label = "bcm53xx:amber:wan";
- gpios = <&chipcommon 9 GPIO_ACTIVE_HIGH>;
- };
-
-- 5ghz-1 {
-+ led-5ghz-1 {
- label = "bcm53xx:white:5ghz-1";
- gpios = <&chipcommon 12 GPIO_ACTIVE_LOW>;
- };
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:white:2ghz";
- gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
- };
-
-- wireless {
-+ led-wireless {
- label = "bcm53xx:white:wireless";
- gpios = <&chipcommon 14 GPIO_ACTIVE_HIGH>;
- };
-
-- wps {
-+ led-wps {
- label = "bcm53xx:white:wps";
- gpios = <&chipcommon 15 GPIO_ACTIVE_HIGH>;
- };
-
-- 5ghz-2 {
-+ led-5ghz-2 {
- label = "bcm53xx:white:5ghz-2";
- gpios = <&chipcommon 16 GPIO_ACTIVE_LOW>;
- };
-
-- usb3 {
-+ led-usb3 {
- label = "bcm53xx:white:usb3";
- gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>;
- };
-
-- usb2 {
-+ led-usb2 {
- label = "bcm53xx:white:usb2";
- gpios = <&chipcommon 18 GPIO_ACTIVE_LOW>;
- };
---- a/arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts
-+++ b/arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts
-@@ -23,27 +23,27 @@
- leds {
- compatible = "gpio-leds";
-
-- lan {
-+ led-lan {
- label = "bcm53xx:blue:lan";
- gpios = <&chipcommon 1 GPIO_ACTIVE_HIGH>;
- };
-
-- wps {
-+ led-wps {
- label = "bcm53xx:blue:wps";
- gpios = <&chipcommon 2 GPIO_ACTIVE_HIGH>;
- };
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:blue:2ghz";
- gpios = <&chipcommon 4 GPIO_ACTIVE_HIGH>;
- };
-
-- 5ghz {
-+ led-5ghz {
- label = "bcm53xx:blue:5ghz";
- gpios = <&chipcommon 5 GPIO_ACTIVE_HIGH>;
- };
-
-- usb3 {
-+ led-usb3 {
- label = "bcm53xx:blue:usb3";
- gpios = <&chipcommon 6 GPIO_ACTIVE_HIGH>;
- trigger-sources = <&ohci_port1>, <&ehci_port1>,
-@@ -51,24 +51,24 @@
- linux,default-trigger = "usbport";
- };
-
-- usb2 {
-+ led-usb2 {
- label = "bcm53xx:blue:usb2";
- gpios = <&chipcommon 7 GPIO_ACTIVE_HIGH>;
- trigger-sources = <&ohci_port2>, <&ehci_port2>;
- linux,default-trigger = "usbport";
- };
-
-- wan-blue {
-+ led-wan-blue {
- label = "bcm53xx:blue:wan";
- gpios = <&chipcommon 14 GPIO_ACTIVE_HIGH>;
- };
-
-- wan-amber {
-+ led-wan-amber {
- label = "bcm53xx:amber:wan";
- gpios = <&chipcommon 15 GPIO_ACTIVE_HIGH>;
- };
-
-- power {
-+ led-power {
- label = "bcm53xx:blue:power";
- gpios = <&chipcommon 18 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
---- a/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-+++ b/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-@@ -33,37 +33,37 @@
- leds {
- compatible = "gpio-leds";
-
-- power {
-+ led-power {
- label = "white:power";
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- wan-red {
-+ led-wan-red {
- label = "red:wan";
- gpios = <&chipcommon 5 GPIO_ACTIVE_HIGH>;
- };
-
-- lan {
-+ led-lan {
- label = "white:lan";
- gpios = <&chipcommon 21 GPIO_ACTIVE_LOW>;
- };
-
-- usb2 {
-+ led-usb2 {
- label = "white:usb2";
- gpios = <&chipcommon 16 GPIO_ACTIVE_LOW>;
- trigger-sources = <&ehci_port2>;
- linux,default-trigger = "usbport";
- };
-
-- usb3 {
-+ led-usb3 {
- label = "white:usb3";
- gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>;
- trigger-sources = <&ehci_port1>, <&xhci_port1>;
- linux,default-trigger = "usbport";
- };
-
-- wps {
-+ led-wps {
- label = "white:wps";
- gpios = <&chipcommon 19 GPIO_ACTIVE_LOW>;
- };
---- a/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts
-+++ b/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts
-@@ -43,28 +43,28 @@
- leds {
- compatible = "gpio-leds";
-
-- power-white {
-+ led-power-white {
- label = "bcm53xx:white:power";
- gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- wan-white {
-+ led-wan-white {
- label = "bcm53xx:white:wan";
- gpios = <&chipcommon 1 GPIO_ACTIVE_LOW>;
- };
-
-- power-amber {
-+ led-power-amber {
- label = "bcm53xx:amber:power";
- gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>;
- };
-
-- wan-amber {
-+ led-wan-amber {
- label = "bcm53xx:amber:wan";
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- };
-
-- usb3-white {
-+ led-usb3-white {
- label = "bcm53xx:white:usb3";
- gpios = <&chipcommon 8 GPIO_ACTIVE_LOW>;
- trigger-sources = <&ohci_port1>, <&ehci_port1>,
-@@ -72,12 +72,12 @@
- linux,default-trigger = "usbport";
- };
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:white:2ghz";
- gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
- };
-
-- 5ghz {
-+ led-5ghz {
- label = "bcm53xx:white:5ghz";
- gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
- };
---- a/arch/arm/boot/dts/bcm47094-dlink-dir-890l.dts
-+++ b/arch/arm/boot/dts/bcm47094-dlink-dir-890l.dts
-@@ -41,47 +41,47 @@
- */
- compatible = "gpio-leds";
-
-- power-white {
-+ led-power-white {
- label = "bcm53xx:white:power";
- gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- wan-white {
-+ led-wan-white {
- label = "bcm53xx:white:wan";
- gpios = <&chipcommon 1 GPIO_ACTIVE_LOW>;
- };
-
-- power-amber {
-+ led-power-amber {
- label = "bcm53xx:amber:power";
- gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>;
- };
-
-- wan-amber {
-+ led-wan-amber {
- label = "bcm53xx:amber:wan";
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- };
-
-- usb3-white {
-+ led-usb3-white {
- label = "bcm53xx:white:usb3";
- gpios = <&chipcommon 8 GPIO_ACTIVE_LOW>;
- trigger-sources = <&xhci_port1>;
- linux,default-trigger = "usbport";
- };
-
-- usb2-white {
-+ led-usb2-white {
- label = "bcm53xx:white:usb2";
- gpios = <&chipcommon 15 GPIO_ACTIVE_LOW>;
- trigger-sources = <&ohci_port1>, <&ehci_port1>;
- linux,default-trigger = "usbport";
- };
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:white:2ghz";
- gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
- };
-
-- 5ghz {
-+ led-5ghz {
- label = "bcm53xx:white:5ghz";
- gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
- };
---- a/arch/arm/boot/dts/bcm47094-linksys-panamera.dts
-+++ b/arch/arm/boot/dts/bcm47094-linksys-panamera.dts
-@@ -52,19 +52,19 @@
- leds {
- compatible = "gpio-leds";
-
-- wps {
-+ led-wps {
- label = "bcm53xx:white:wps";
- gpios = <&chipcommon 22 GPIO_ACTIVE_LOW>;
- };
-
-- usb2 {
-+ led-usb2 {
- label = "bcm53xx:green:usb2";
- gpios = <&chipcommon 1 GPIO_ACTIVE_LOW>;
- trigger-sources = <&ohci_port2>, <&ehci_port2>;
- linux,default-trigger = "usbport";
- };
-
-- usb3 {
-+ led-usb3 {
- label = "bcm53xx:green:usb3";
- gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>;
- trigger-sources = <&ohci_port1>, <&ehci_port1>,
-@@ -72,58 +72,58 @@
- linux,default-trigger = "usbport";
- };
-
-- power {
-+ led-power {
- label = "bcm53xx:white:power";
- gpios = <&chipcommon 4 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- wifi-disabled {
-+ led-wifi-disabled {
- label = "bcm53xx:amber:wifi-disabled";
- gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
- };
-
-- wifi-enabled {
-+ led-wifi-enabled {
- label = "bcm53xx:white:wifi-enabled";
- gpios = <&chipcommon 5 GPIO_ACTIVE_HIGH>;
- };
-
-- bluebar1 {
-+ led-bluebar1 {
- label = "bcm53xx:white:bluebar1";
- gpios = <&chipcommon 11 GPIO_ACTIVE_HIGH>;
- };
-
-- bluebar2 {
-+ led-bluebar2 {
- label = "bcm53xx:white:bluebar2";
- gpios = <&chipcommon 12 GPIO_ACTIVE_HIGH>;
- };
-
-- bluebar3 {
-+ led-bluebar3 {
- label = "bcm53xx:white:bluebar3";
- gpios = <&chipcommon 15 GPIO_ACTIVE_LOW>;
- };
-
-- bluebar4 {
-+ led-bluebar4 {
- label = "bcm53xx:white:bluebar4";
- gpios = <&chipcommon 18 GPIO_ACTIVE_HIGH>;
- };
-
-- bluebar5 {
-+ led-bluebar5 {
- label = "bcm53xx:white:bluebar5";
- gpios = <&chipcommon 19 GPIO_ACTIVE_HIGH>;
- };
-
-- bluebar6 {
-+ led-bluebar6 {
- label = "bcm53xx:white:bluebar6";
- gpios = <&chipcommon 20 GPIO_ACTIVE_HIGH>;
- };
-
-- bluebar7 {
-+ led-bluebar7 {
- label = "bcm53xx:white:bluebar7";
- gpios = <&chipcommon 21 GPIO_ACTIVE_HIGH>;
- };
-
-- bluebar8 {
-+ led-bluebar8 {
- label = "bcm53xx:white:bluebar8";
- gpios = <&chipcommon 8 GPIO_ACTIVE_HIGH>;
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts
-@@ -30,13 +30,13 @@
- leds {
- compatible = "gpio-leds";
-
-- status {
-+ led-status {
- label = "bcm53xx:green:status";
- gpios = <&chipcommon 20 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "timer";
- };
-
-- usb3 {
-+ led-usb3 {
- label = "bcm53xx:green:usb3";
- gpios = <&chipcommon 19 GPIO_ACTIVE_LOW>;
- trigger-sources = <&ohci_port1>, <&ehci_port1>,
---- a/arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts
-@@ -23,18 +23,18 @@
- leds {
- compatible = "gpio-leds";
-
-- status {
-+ led-status {
- label = "bcm53xx:green:status";
- gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "timer";
- };
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:blue:2ghz";
- gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
- };
-
-- 5ghz {
-+ led-5ghz {
- label = "bcm53xx:blue:5ghz";
- gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts
-@@ -30,13 +30,13 @@
- leds {
- compatible = "gpio-leds";
-
-- status {
-+ led-status {
- label = "bcm53xx:green:status";
- gpios = <&chipcommon 20 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "timer";
- };
-
-- usb3 {
-+ led-usb3 {
- label = "bcm53xx:green:usb3";
- gpios = <&chipcommon 19 GPIO_ACTIVE_HIGH>;
- trigger-sources = <&ohci_port1>, <&ehci_port1>,
---- a/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts
-@@ -25,7 +25,7 @@
- leds {
- compatible = "gpio-leds";
-
-- status {
-+ led-status {
- label = "bcm53xx:green:status";
- gpios = <&chipcommon 18 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "timer";
---- a/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts
-@@ -30,38 +30,38 @@
- leds {
- compatible = "gpio-leds";
-
-- power {
-+ led-power {
- label = "bcm53xx:green:power";
- gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- lan3 {
-+ led-lan3 {
- label = "bcm53xx:green:lan3";
- gpios = <&chipcommon 1 GPIO_ACTIVE_LOW>;
- };
-
-- lan4 {
-+ led-lan4 {
- label = "bcm53xx:green:lan4";
- gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>;
- };
-
-- wan {
-+ led-wan {
- label = "bcm53xx:green:wan";
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- };
-
-- lan1 {
-+ led-lan1 {
- label = "bcm53xx:green:lan1";
- gpios = <&chipcommon 4 GPIO_ACTIVE_LOW>;
- };
-
-- lan2 {
-+ led-lan2 {
- label = "bcm53xx:green:lan2";
- gpios = <&chipcommon 6 GPIO_ACTIVE_LOW>;
- };
-
-- usb3 {
-+ led-usb3 {
- label = "bcm53xx:green:usb3";
- gpios = <&chipcommon 8 GPIO_ACTIVE_LOW>;
- trigger-sources = <&ohci_port1>, <&ehci_port1>,
-@@ -69,18 +69,18 @@
- linux,default-trigger = "usbport";
- };
-
-- status {
-+ led-status {
- label = "bcm53xx:green:status";
- gpios = <&chipcommon 10 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "timer";
- };
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:green:2ghz";
- gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
- };
-
-- 5ghz {
-+ led-5ghz {
- label = "bcm53xx:green:5ghz";
- gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
-@@ -33,13 +33,13 @@
- leds {
- compatible = "gpio-leds";
-
-- power {
-+ led-power {
- label = "bcm53xx:green:power";
- gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- usb3 {
-+ led-usb3 {
- label = "bcm53xx:green:usb3";
- gpios = <&chipcommon 8 GPIO_ACTIVE_LOW>;
- trigger-sources = <&ohci_port1>, <&ehci_port1>,
-@@ -47,18 +47,18 @@
- linux,default-trigger = "usbport";
- };
-
-- status {
-+ led-status {
- label = "bcm53xx:green:status";
- gpios = <&chipcommon 10 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "timer";
- };
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:green:2ghz";
- gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
- };
-
-- 5ghz {
-+ led-5ghz {
- label = "bcm53xx:green:5ghz";
- gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
- };
---- a/arch/arm/boot/dts/bcm47094-netgear-r8500.dts
-+++ b/arch/arm/boot/dts/bcm47094-netgear-r8500.dts
-@@ -25,38 +25,38 @@
- leds {
- compatible = "gpio-leds";
-
-- power0 {
-+ led-power0 {
- label = "bcm53xx:white:power";
- gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-on";
- };
-
-- power1 {
-+ led-power1 {
- label = "bcm53xx:amber:power";
- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
- };
-
-- 5ghz-1 {
-+ led-5ghz-1 {
- label = "bcm53xx:white:5ghz-1";
- gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
- };
-
-- 5ghz-2 {
-+ led-5ghz-2 {
- label = "bcm53xx:white:5ghz-2";
- gpios = <&chipcommon 12 GPIO_ACTIVE_LOW>;
- };
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:white:2ghz";
- gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
- };
-
-- usb2 {
-+ led-usb2 {
- label = "bcm53xx:white:usb2";
- gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>;
- };
-
-- usb3 {
-+ led-usb3 {
- label = "bcm53xx:white:usb3";
- gpios = <&chipcommon 18 GPIO_ACTIVE_LOW>;
- };
---- a/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts
-+++ b/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts
-@@ -23,13 +23,13 @@
- leds {
- compatible = "gpio-leds";
-
-- wlan {
-+ led-wlan {
- label = "bcm53xx:blue:wlan";
- gpios = <&chipcommon 10 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "default-off";
- };
-
-- system {
-+ led-system {
- label = "bcm53xx:green:system";
- gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
- linux,default-trigger = "timer";
---- a/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts
-+++ b/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts
-@@ -20,26 +20,26 @@
- reg = <0x00000000 0x08000000>;
- };
-
-- leds {
-+ leds-0 {
- compatible = "gpio-leds";
-
-- 5ghz {
-+ led-5ghz {
- label = "bcm53xx:blue:5ghz";
- gpios = <&chipcommon 11 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-off";
- };
-
-- system {
-+ led-system {
- label = "bcm53xx:green:system";
- gpios = <&chipcommon 15 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "timer";
- };
- };
-
-- pcie0_leds {
-+ leds-1 {
- compatible = "gpio-leds";
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:blue:2ghz";
- gpios = <&pcie0_chipcommon 3 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-off";
---- a/arch/arm/boot/dts/bcm47189-tenda-ac9.dts
-+++ b/arch/arm/boot/dts/bcm47189-tenda-ac9.dts
-@@ -20,37 +20,37 @@
- reg = <0x00000000 0x08000000>;
- };
-
-- leds {
-+ leds-0 {
- compatible = "gpio-leds";
-
-- usb {
-+ led-usb {
- label = "bcm53xx:blue:usb";
- gpios = <&chipcommon 1 GPIO_ACTIVE_HIGH>;
- trigger-sources = <&ohci_port1>, <&ehci_port1>;
- linux,default-trigger = "usbport";
- };
-
-- wps {
-+ led-wps {
- label = "bcm53xx:blue:wps";
- gpios = <&chipcommon 10 GPIO_ACTIVE_HIGH>;
- };
-
-- 5ghz {
-+ led-5ghz {
- label = "bcm53xx:blue:5ghz";
- gpios = <&chipcommon 11 GPIO_ACTIVE_HIGH>;
- };
-
-- system {
-+ led-system {
- label = "bcm53xx:blue:system";
- gpios = <&chipcommon 15 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "timer";
- };
- };
-
-- pcie0_leds {
-+ leds-1 {
- compatible = "gpio-leds";
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:blue:2ghz";
- gpios = <&pcie0_chipcommon 3 GPIO_ACTIVE_HIGH>;
- };
---- a/arch/arm/boot/dts/bcm53016-dlink-dwl-8610ap.dts
-+++ b/arch/arm/boot/dts/bcm53016-dlink-dwl-8610ap.dts
-@@ -20,14 +20,14 @@
- leds {
- compatible = "gpio-leds";
-
-- power {
-+ led-power {
- function = LED_FUNCTION_POWER;
- color = <LED_COLOR_ID_GREEN>;
- gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>;
- default-state = "on";
- };
-
-- diag {
-+ led-diag {
- /* Actually "diag" unclear what this means */
- function = LED_FUNCTION_INDICATOR;
- color = <LED_COLOR_ID_RED>;
-@@ -36,13 +36,13 @@
- linux,default-trigger = "heartbeat";
- };
-
-- wlan-2g {
-+ led-wlan-2g {
- function = LED_FUNCTION_WLAN;
- color = <LED_COLOR_ID_GREEN>;
- gpios = <&chipcommon 5 GPIO_ACTIVE_LOW>;
- };
-
-- wlan-5g {
-+ led-wlan-5g {
- function = LED_FUNCTION_WLAN;
- color = <LED_COLOR_ID_GREEN>;
- gpios = <&chipcommon 8 GPIO_ACTIVE_LOW>;
---- a/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-+++ b/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-@@ -58,7 +58,7 @@
- pwm-leds {
- compatible = "pwm-leds";
-
-- red {
-+ led-0 {
- /* SYS-LED 1 - Tricolor */
- function = LED_FUNCTION_INDICATOR;
- color = <LED_COLOR_ID_RED>;
-@@ -66,7 +66,7 @@
- max-brightness = <255>;
- };
-
-- green {
-+ led-1 {
- /* SYS-LED 1 - Tricolor */
- function = LED_FUNCTION_POWER;
- color = <LED_COLOR_ID_GREEN>;
-@@ -74,7 +74,7 @@
- max-brightness = <255>;
- };
-
-- blue {
-+ led-2 {
- /* SYS-LED 1 - Tricolor */
- function = LED_FUNCTION_INDICATOR;
- color = <LED_COLOR_ID_BLUE>;
---- a/arch/arm/boot/dts/bcm947189acdbmr.dts
-+++ b/arch/arm/boot/dts/bcm947189acdbmr.dts
-@@ -25,17 +25,17 @@
- leds {
- compatible = "gpio-leds";
-
-- wps {
-+ led-wps {
- label = "bcm53xx:blue:wps";
- gpios = <&chipcommon 10 GPIO_ACTIVE_HIGH>;
- };
-
-- 5ghz {
-+ led-5ghz {
- label = "bcm53xx:blue:5ghz";
- gpios = <&chipcommon 11 GPIO_ACTIVE_HIGH>;
- };
-
-- 2ghz {
-+ led-2ghz {
- label = "bcm53xx:blue:2ghz";
- gpios = <&chipcommon 12 GPIO_ACTIVE_HIGH>;
- };
diff --git a/target/linux/bcm53xx/patches-6.1/031-v6.5-0001-ARM-dts-BCM5301X-Relicense-Rafa-s-code-to-the-GPL-2..patch b/target/linux/bcm53xx/patches-6.1/031-v6.5-0001-ARM-dts-BCM5301X-Relicense-Rafa-s-code-to-the-GPL-2..patch
deleted file mode 100644
index 4744e6d5b1..0000000000
--- a/target/linux/bcm53xx/patches-6.1/031-v6.5-0001-ARM-dts-BCM5301X-Relicense-Rafa-s-code-to-the-GPL-2..patch
+++ /dev/null
@@ -1,487 +0,0 @@
-From 915fac07f053418d0ab9075af64da2872ca8a7f8 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Wed, 3 May 2023 14:16:10 +0200
-Subject: [PATCH] =?UTF-8?q?ARM:=20dts:=20BCM5301X:=20Relicense=20Rafa?=
- =?UTF-8?q?=C5=82's=20code=20to=20the=20GPL=202.0+=20/=20MIT?=
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-All BCM5301X device DTS files use dual licensing. Try the same for SoC.
-Introduce a new .dtsi file with a proper SPDX tag.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230503121611.1629-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- MAINTAINERS | 1 +
- arch/arm/boot/dts/bcm-ns.dtsi | 202 ++++++++++++++++++++++++++++++++
- arch/arm/boot/dts/bcm5301x.dtsi | 192 +-----------------------------
- 3 files changed, 205 insertions(+), 190 deletions(-)
- create mode 100644 arch/arm/boot/dts/bcm-ns.dtsi
-
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -4063,6 +4063,7 @@ M: Rafał Miłecki <zajec5@gmail.com>
- R: Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com>
- L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
- S: Maintained
-+F: arch/arm/boot/dts/bcm-ns.dtsi
- F: arch/arm/boot/dts/bcm470*
- F: arch/arm/boot/dts/bcm5301*
- F: arch/arm/boot/dts/bcm953012*
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm-ns.dtsi
-@@ -0,0 +1,202 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-+
-+#include <dt-bindings/clock/bcm-nsp.h>
-+#include <dt-bindings/gpio/gpio.h>
-+#include <dt-bindings/input/input.h>
-+#include <dt-bindings/interrupt-controller/irq.h>
-+#include <dt-bindings/interrupt-controller/arm-gic.h>
-+
-+/ {
-+ axi@18000000 {
-+ compatible = "brcm,bus-axi";
-+ reg = <0x18000000 0x1000>;
-+ ranges = <0x00000000 0x18000000 0x00100000>;
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ chipcommon: chipcommon@0 {
-+ reg = <0x00000000 0x1000>;
-+
-+ gpio-controller;
-+ #gpio-cells = <2>;
-+ };
-+
-+ pcie0: pcie@12000 {
-+ reg = <0x00012000 0x1000>;
-+ };
-+
-+ pcie1: pcie@13000 {
-+ reg = <0x00013000 0x1000>;
-+ };
-+
-+ usb2: usb2@21000 {
-+ reg = <0x00021000 0x1000>;
-+
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+ ranges;
-+
-+ interrupt-parent = <&gic>;
-+
-+ ehci: usb@21000 {
-+ #usb-cells = <0>;
-+
-+ compatible = "generic-ehci";
-+ reg = <0x00021000 0x1000>;
-+ interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
-+ phys = <&usb2_phy>;
-+
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ ehci_port1: port@1 {
-+ reg = <1>;
-+ #trigger-source-cells = <0>;
-+ };
-+
-+ ehci_port2: port@2 {
-+ reg = <2>;
-+ #trigger-source-cells = <0>;
-+ };
-+ };
-+
-+ ohci: usb@22000 {
-+ #usb-cells = <0>;
-+
-+ compatible = "generic-ohci";
-+ reg = <0x00022000 0x1000>;
-+ interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
-+
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ ohci_port1: port@1 {
-+ reg = <1>;
-+ #trigger-source-cells = <0>;
-+ };
-+
-+ ohci_port2: port@2 {
-+ reg = <2>;
-+ #trigger-source-cells = <0>;
-+ };
-+ };
-+ };
-+
-+ usb3: usb3@23000 {
-+ reg = <0x00023000 0x1000>;
-+
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+ ranges;
-+
-+ interrupt-parent = <&gic>;
-+
-+ xhci: usb@23000 {
-+ #usb-cells = <0>;
-+
-+ compatible = "generic-xhci";
-+ reg = <0x00023000 0x1000>;
-+ interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
-+ phys = <&usb3_phy>;
-+ phy-names = "usb";
-+
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ xhci_port1: port@1 {
-+ reg = <1>;
-+ #trigger-source-cells = <0>;
-+ };
-+ };
-+ };
-+ };
-+
-+ mdio: mdio@18003000 {
-+ compatible = "brcm,iproc-mdio";
-+ reg = <0x18003000 0x8>;
-+ #size-cells = <0>;
-+ #address-cells = <1>;
-+ };
-+
-+ dmu-bus@1800c000 {
-+ compatible = "simple-bus";
-+ ranges = <0 0x1800c000 0x1000>;
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ cru-bus@100 {
-+ compatible = "brcm,ns-cru", "simple-mfd";
-+ reg = <0x100 0x1a4>;
-+ ranges;
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ usb2_phy: phy@164 {
-+ compatible = "brcm,ns-usb2-phy";
-+ reg = <0x164 0x4>;
-+ brcm,syscon-clkset = <&cru_clkset>;
-+ clocks = <&genpll BCM_NSP_GENPLL_USB_PHY_REF_CLK>;
-+ clock-names = "phy-ref-clk";
-+ #phy-cells = <0>;
-+ };
-+
-+ cru_clkset: syscon@180 {
-+ compatible = "brcm,cru-clkset", "syscon";
-+ reg = <0x180 0x4>;
-+ };
-+
-+ pinctrl: pinctrl@1c0 {
-+ compatible = "brcm,bcm4708-pinmux";
-+ reg = <0x1c0 0x24>;
-+ reg-names = "cru_gpio_control";
-+
-+ spi-pins {
-+ groups = "spi_grp";
-+ function = "spi";
-+ };
-+
-+ pinmux_i2c: i2c-pins {
-+ groups = "i2c_grp";
-+ function = "i2c";
-+ };
-+
-+ pinmux_pwm: pwm-pins {
-+ groups = "pwm0_grp", "pwm1_grp",
-+ "pwm2_grp", "pwm3_grp";
-+ function = "pwm";
-+ };
-+
-+ pinmux_uart1: uart1-pins {
-+ groups = "uart1_grp";
-+ function = "uart1";
-+ };
-+ };
-+
-+ thermal: thermal@2c0 {
-+ compatible = "brcm,ns-thermal";
-+ reg = <0x2c0 0x10>;
-+ #thermal-sensor-cells = <0>;
-+ };
-+ };
-+ };
-+
-+ thermal-zones {
-+ cpu_thermal: cpu-thermal {
-+ polling-delay-passive = <0>;
-+ polling-delay = <1000>;
-+ coefficients = <(-556) 418000>;
-+ thermal-sensors = <&thermal>;
-+
-+ trips {
-+ cpu-crit {
-+ temperature = <125000>;
-+ hysteresis = <0>;
-+ type = "critical";
-+ };
-+ };
-+
-+ cooling-maps {
-+ };
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm5301x.dtsi
-+++ b/arch/arm/boot/dts/bcm5301x.dtsi
-@@ -8,11 +8,7 @@
- * Licensed under the GNU/GPL. See COPYING for details.
- */
-
--#include <dt-bindings/clock/bcm-nsp.h>
--#include <dt-bindings/gpio/gpio.h>
--#include <dt-bindings/input/input.h>
--#include <dt-bindings/interrupt-controller/irq.h>
--#include <dt-bindings/interrupt-controller/arm-gic.h>
-+#include "bcm-ns.dtsi"
-
- / {
- #address-cells = <1>;
-@@ -149,12 +145,6 @@
- };
-
- axi@18000000 {
-- compatible = "brcm,bus-axi";
-- reg = <0x18000000 0x1000>;
-- ranges = <0x00000000 0x18000000 0x00100000>;
-- #address-cells = <1>;
-- #size-cells = <1>;
--
- #interrupt-cells = <1>;
- interrupt-map-mask = <0x000fffff 0xffff>;
- interrupt-map =
-@@ -228,108 +218,15 @@
- <0x00028000 6 &gic GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>,
- <0x00028000 7 &gic GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
-
-- chipcommon: chipcommon@0 {
-- reg = <0x00000000 0x1000>;
--
-- gpio-controller;
-- #gpio-cells = <2>;
-+ chipcommon@0 {
- interrupt-controller;
- #interrupt-cells = <2>;
- };
-
-- pcie0: pcie@12000 {
-- reg = <0x00012000 0x1000>;
-- };
--
-- pcie1: pcie@13000 {
-- reg = <0x00013000 0x1000>;
-- };
--
- pcie2: pcie@14000 {
- reg = <0x00014000 0x1000>;
- };
-
-- usb2: usb2@21000 {
-- reg = <0x00021000 0x1000>;
--
-- #address-cells = <1>;
-- #size-cells = <1>;
-- ranges;
--
-- interrupt-parent = <&gic>;
--
-- ehci: usb@21000 {
-- #usb-cells = <0>;
--
-- compatible = "generic-ehci";
-- reg = <0x00021000 0x1000>;
-- interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
-- phys = <&usb2_phy>;
--
-- #address-cells = <1>;
-- #size-cells = <0>;
--
-- ehci_port1: port@1 {
-- reg = <1>;
-- #trigger-source-cells = <0>;
-- };
--
-- ehci_port2: port@2 {
-- reg = <2>;
-- #trigger-source-cells = <0>;
-- };
-- };
--
-- ohci: usb@22000 {
-- #usb-cells = <0>;
--
-- compatible = "generic-ohci";
-- reg = <0x00022000 0x1000>;
-- interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
--
-- #address-cells = <1>;
-- #size-cells = <0>;
--
-- ohci_port1: port@1 {
-- reg = <1>;
-- #trigger-source-cells = <0>;
-- };
--
-- ohci_port2: port@2 {
-- reg = <2>;
-- #trigger-source-cells = <0>;
-- };
-- };
-- };
--
-- usb3: usb3@23000 {
-- reg = <0x00023000 0x1000>;
--
-- #address-cells = <1>;
-- #size-cells = <1>;
-- ranges;
--
-- interrupt-parent = <&gic>;
--
-- xhci: usb@23000 {
-- #usb-cells = <0>;
--
-- compatible = "generic-xhci";
-- reg = <0x00023000 0x1000>;
-- interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
-- phys = <&usb3_phy>;
-- phy-names = "usb";
--
-- #address-cells = <1>;
-- #size-cells = <0>;
--
-- xhci_port1: port@1 {
-- reg = <1>;
-- #trigger-source-cells = <0>;
-- };
-- };
-- };
--
- gmac0: ethernet@24000 {
- reg = <0x24000 0x800>;
- };
-@@ -355,13 +252,6 @@
- status = "disabled";
- };
-
-- mdio: mdio@18003000 {
-- compatible = "brcm,iproc-mdio";
-- reg = <0x18003000 0x8>;
-- #size-cells = <0>;
-- #address-cells = <1>;
-- };
--
- mdio-mux@18003000 {
- compatible = "mdio-mux-mmioreg", "mdio-mux";
- mdio-parent-bus = <&mdio>;
-@@ -409,18 +299,7 @@
- };
-
- dmu-bus@1800c000 {
-- compatible = "simple-bus";
-- ranges = <0 0x1800c000 0x1000>;
-- #address-cells = <1>;
-- #size-cells = <1>;
--
- cru-bus@100 {
-- compatible = "brcm,ns-cru", "simple-mfd";
-- reg = <0x100 0x1a4>;
-- ranges;
-- #address-cells = <1>;
-- #size-cells = <1>;
--
- lcpll0: clock-controller@100 {
- #clock-cells = <1>;
- compatible = "brcm,nsp-lcpll0";
-@@ -440,53 +319,6 @@
- "usbclk", "iprocfast",
- "sata1", "sata2";
- };
--
-- usb2_phy: phy@164 {
-- compatible = "brcm,ns-usb2-phy";
-- reg = <0x164 0x4>;
-- brcm,syscon-clkset = <&cru_clkset>;
-- clocks = <&genpll BCM_NSP_GENPLL_USB_PHY_REF_CLK>;
-- clock-names = "phy-ref-clk";
-- #phy-cells = <0>;
-- };
--
-- cru_clkset: syscon@180 {
-- compatible = "brcm,cru-clkset", "syscon";
-- reg = <0x180 0x4>;
-- };
--
-- pinctrl: pinctrl@1c0 {
-- compatible = "brcm,bcm4708-pinmux";
-- reg = <0x1c0 0x24>;
-- reg-names = "cru_gpio_control";
--
-- spi-pins {
-- groups = "spi_grp";
-- function = "spi";
-- };
--
-- pinmux_i2c: i2c-pins {
-- groups = "i2c_grp";
-- function = "i2c";
-- };
--
-- pinmux_pwm: pwm-pins {
-- groups = "pwm0_grp", "pwm1_grp",
-- "pwm2_grp", "pwm3_grp";
-- function = "pwm";
-- };
--
-- pinmux_uart1: uart1-pins {
-- groups = "uart1_grp";
-- function = "uart1";
-- };
-- };
--
-- thermal: thermal@2c0 {
-- compatible = "brcm,ns-thermal";
-- reg = <0x2c0 0x10>;
-- #thermal-sensor-cells = <0>;
-- };
- };
- };
-
-@@ -557,24 +389,4 @@
- };
- };
- };
--
-- thermal-zones {
-- cpu_thermal: cpu-thermal {
-- polling-delay-passive = <0>;
-- polling-delay = <1000>;
-- coefficients = <(-556) 418000>;
-- thermal-sensors = <&thermal>;
--
-- trips {
-- cpu-crit {
-- temperature = <125000>;
-- hysteresis = <0>;
-- type = "critical";
-- };
-- };
--
-- cooling-maps {
-- };
-- };
-- };
- };
diff --git a/target/linux/bcm53xx/patches-6.1/031-v6.5-0002-ARM-dts-BCM5301X-Relicense-Florian-s-code-to-the-GPL.patch b/target/linux/bcm53xx/patches-6.1/031-v6.5-0002-ARM-dts-BCM5301X-Relicense-Florian-s-code-to-the-GPL.patch
deleted file mode 100644
index b98f2daa67..0000000000
--- a/target/linux/bcm53xx/patches-6.1/031-v6.5-0002-ARM-dts-BCM5301X-Relicense-Florian-s-code-to-the-GPL.patch
+++ /dev/null
@@ -1,136 +0,0 @@
-From 916553449561c4f0b61c71b751b7bb583f5dddd4 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Wed, 3 May 2023 14:16:11 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Relicense Florian's code to the GPL 2.0+
- / MIT
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-All BCM5301X device DTS files use dual licensing. Try the same for SoC.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230503121611.1629-2-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
----
- arch/arm/boot/dts/bcm-ns.dtsi | 36 ++++++++++++++++++++++++++++++
- arch/arm/boot/dts/bcm5301x.dtsi | 39 ---------------------------------
- 2 files changed, 36 insertions(+), 39 deletions(-)
-
---- a/arch/arm/boot/dts/bcm-ns.dtsi
-+++ b/arch/arm/boot/dts/bcm-ns.dtsi
-@@ -19,6 +19,8 @@
-
- gpio-controller;
- #gpio-cells = <2>;
-+ interrupt-controller;
-+ #interrupt-cells = <2>;
- };
-
- pcie0: pcie@12000 {
-@@ -109,6 +111,22 @@
- };
- };
- };
-+
-+ gmac0: ethernet@24000 {
-+ reg = <0x24000 0x800>;
-+ };
-+
-+ gmac1: ethernet@25000 {
-+ reg = <0x25000 0x800>;
-+ };
-+
-+ gmac2: ethernet@26000 {
-+ reg = <0x26000 0x800>;
-+ };
-+
-+ gmac3: ethernet@27000 {
-+ reg = <0x27000 0x800>;
-+ };
- };
-
- mdio: mdio@18003000 {
-@@ -118,6 +136,24 @@
- #address-cells = <1>;
- };
-
-+ rng: rng@18004000 {
-+ compatible = "brcm,bcm5301x-rng";
-+ reg = <0x18004000 0x14>;
-+ };
-+
-+ srab: ethernet-switch@18007000 {
-+ compatible = "brcm,bcm53011-srab", "brcm,bcm5301x-srab";
-+ reg = <0x18007000 0x1000>;
-+
-+ status = "disabled";
-+
-+ /* ports are defined in board DTS */
-+ ports {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ };
-+ };
-+
- dmu-bus@1800c000 {
- compatible = "simple-bus";
- ranges = <0 0x1800c000 0x1000>;
---- a/arch/arm/boot/dts/bcm5301x.dtsi
-+++ b/arch/arm/boot/dts/bcm5301x.dtsi
-@@ -218,30 +218,9 @@
- <0x00028000 6 &gic GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>,
- <0x00028000 7 &gic GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
-
-- chipcommon@0 {
-- interrupt-controller;
-- #interrupt-cells = <2>;
-- };
--
- pcie2: pcie@14000 {
- reg = <0x00014000 0x1000>;
- };
--
-- gmac0: ethernet@24000 {
-- reg = <0x24000 0x800>;
-- };
--
-- gmac1: ethernet@25000 {
-- reg = <0x25000 0x800>;
-- };
--
-- gmac2: ethernet@26000 {
-- reg = <0x26000 0x800>;
-- };
--
-- gmac3: ethernet@27000 {
-- reg = <0x27000 0x800>;
-- };
- };
-
- pwm: pwm@18002000 {
-@@ -322,24 +301,6 @@
- };
- };
-
-- srab: ethernet-switch@18007000 {
-- compatible = "brcm,bcm53011-srab", "brcm,bcm5301x-srab";
-- reg = <0x18007000 0x1000>;
--
-- status = "disabled";
--
-- /* ports are defined in board DTS */
-- ports {
-- #address-cells = <1>;
-- #size-cells = <0>;
-- };
-- };
--
-- rng: rng@18004000 {
-- compatible = "brcm,bcm5301x-rng";
-- reg = <0x18004000 0x14>;
-- };
--
- nand_controller: nand-controller@18028000 {
- compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1", "brcm,brcmnand";
- reg = <0x18028000 0x600>, <0x1811a408 0x600>, <0x18028f00 0x20>;
diff --git a/target/linux/bcm53xx/patches-6.1/031-v6.5-0004-ARM-dts-BCM5301X-Relicense-Hauke-s-code-to-the-GPL-2.patch b/target/linux/bcm53xx/patches-6.1/031-v6.5-0004-ARM-dts-BCM5301X-Relicense-Hauke-s-code-to-the-GPL-2.patch
deleted file mode 100644
index 328748c8e0..0000000000
--- a/target/linux/bcm53xx/patches-6.1/031-v6.5-0004-ARM-dts-BCM5301X-Relicense-Hauke-s-code-to-the-GPL-2.patch
+++ /dev/null
@@ -1,249 +0,0 @@
-From b3b3cd885ed39cb4b38319a1c4fa4e41db6fee72 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Mon, 15 May 2023 17:19:20 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Relicense Hauke's code to the GPL 2.0+ /
- MIT
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Move code added by Hauke to the bcm-ns.dtsi which uses dual licensing.
-That syncs more Northstar code to be based on the same licensing schema.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Cc: Hauke Mehrtens <hauke@hauke-m.de>
-Acked-by: Hauke Mehrtens <hauke@hauke-m.de>
-Link: https://lore.kernel.org/r/20230515151921.25021-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/bcm-ns.dtsi | 90 +++++++++++++++++++++++++++++++++
- arch/arm/boot/dts/bcm5301x.dtsi | 85 -------------------------------
- 2 files changed, 90 insertions(+), 85 deletions(-)
-
---- a/arch/arm/boot/dts/bcm-ns.dtsi
-+++ b/arch/arm/boot/dts/bcm-ns.dtsi
-@@ -1,4 +1,7 @@
- // SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-+/*
-+ * Copyright 2013-2014 Hauke Mehrtens <hauke@hauke-m.de>
-+ */
-
- #include <dt-bindings/clock/bcm-nsp.h>
- #include <dt-bindings/gpio/gpio.h>
-@@ -7,6 +10,81 @@
- #include <dt-bindings/interrupt-controller/arm-gic.h>
-
- / {
-+ interrupt-parent = <&gic>;
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ chipcommon-a-bus@18000000 {
-+ compatible = "simple-bus";
-+ ranges = <0x00000000 0x18000000 0x00001000>;
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ uart0: serial@300 {
-+ compatible = "ns16550";
-+ reg = <0x0300 0x100>;
-+ interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
-+ clocks = <&iprocslow>;
-+ status = "disabled";
-+ };
-+
-+ uart1: serial@400 {
-+ compatible = "ns16550";
-+ reg = <0x0400 0x100>;
-+ interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
-+ clocks = <&iprocslow>;
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&pinmux_uart1>;
-+ status = "disabled";
-+ };
-+ };
-+
-+ mpcore-bus@19000000 {
-+ compatible = "simple-bus";
-+ ranges = <0x00000000 0x19000000 0x00023000>;
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ scu@20000 {
-+ compatible = "arm,cortex-a9-scu";
-+ reg = <0x20000 0x100>;
-+ };
-+
-+ timer@20200 {
-+ compatible = "arm,cortex-a9-global-timer";
-+ reg = <0x20200 0x100>;
-+ interrupts = <GIC_PPI 11 IRQ_TYPE_EDGE_RISING>;
-+ clocks = <&periph_clk>;
-+ };
-+
-+ timer@20600 {
-+ compatible = "arm,cortex-a9-twd-timer";
-+ reg = <0x20600 0x20>;
-+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) |
-+ IRQ_TYPE_EDGE_RISING)>;
-+ clocks = <&periph_clk>;
-+ };
-+
-+ gic: interrupt-controller@21000 {
-+ compatible = "arm,cortex-a9-gic";
-+ #interrupt-cells = <3>;
-+ #address-cells = <0>;
-+ interrupt-controller;
-+ reg = <0x21000 0x1000>,
-+ <0x20100 0x100>;
-+ };
-+
-+ L2: cache-controller@22000 {
-+ compatible = "arm,pl310-cache";
-+ reg = <0x22000 0x1000>;
-+ cache-unified;
-+ arm,shared-override;
-+ prefetch-data = <1>;
-+ prefetch-instr = <1>;
-+ cache-level = <2>;
-+ };
-+ };
-+
- axi@18000000 {
- compatible = "brcm,bus-axi";
- reg = <0x18000000 0x1000>;
-@@ -216,6 +294,18 @@
- };
- };
-
-+ nand_controller: nand-controller@18028000 {
-+ compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1", "brcm,brcmnand";
-+ reg = <0x18028000 0x600>, <0x1811a408 0x600>, <0x18028f00 0x20>;
-+ reg-names = "nand", "iproc-idm", "iproc-ext";
-+ interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
-+
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ brcm,nand-has-wp;
-+ };
-+
- thermal-zones {
- cpu_thermal: cpu-thermal {
- polling-delay-passive = <0>;
---- a/arch/arm/boot/dts/bcm5301x.dtsi
-+++ b/arch/arm/boot/dts/bcm5301x.dtsi
-@@ -11,41 +11,7 @@
- #include "bcm-ns.dtsi"
-
- / {
-- #address-cells = <1>;
-- #size-cells = <1>;
-- interrupt-parent = <&gic>;
--
-- chipcommon-a-bus@18000000 {
-- compatible = "simple-bus";
-- ranges = <0x00000000 0x18000000 0x00001000>;
-- #address-cells = <1>;
-- #size-cells = <1>;
--
-- uart0: serial@300 {
-- compatible = "ns16550";
-- reg = <0x0300 0x100>;
-- interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
-- clocks = <&iprocslow>;
-- status = "disabled";
-- };
--
-- uart1: serial@400 {
-- compatible = "ns16550";
-- reg = <0x0400 0x100>;
-- interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
-- clocks = <&iprocslow>;
-- pinctrl-names = "default";
-- pinctrl-0 = <&pinmux_uart1>;
-- status = "disabled";
-- };
-- };
--
- mpcore-bus@19000000 {
-- compatible = "simple-bus";
-- ranges = <0x00000000 0x19000000 0x00023000>;
-- #address-cells = <1>;
-- #size-cells = <1>;
--
- a9pll: arm_clk@0 {
- #clock-cells = <0>;
- compatible = "brcm,nsp-armpll";
-@@ -53,26 +19,6 @@
- reg = <0x00000 0x1000>;
- };
-
-- scu@20000 {
-- compatible = "arm,cortex-a9-scu";
-- reg = <0x20000 0x100>;
-- };
--
-- timer@20200 {
-- compatible = "arm,cortex-a9-global-timer";
-- reg = <0x20200 0x100>;
-- interrupts = <GIC_PPI 11 IRQ_TYPE_EDGE_RISING>;
-- clocks = <&periph_clk>;
-- };
--
-- timer@20600 {
-- compatible = "arm,cortex-a9-twd-timer";
-- reg = <0x20600 0x20>;
-- interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) |
-- IRQ_TYPE_EDGE_RISING)>;
-- clocks = <&periph_clk>;
-- };
--
- watchdog@20620 {
- compatible = "arm,cortex-a9-twd-wdt";
- reg = <0x20620 0x20>;
-@@ -80,25 +26,6 @@
- IRQ_TYPE_EDGE_RISING)>;
- clocks = <&periph_clk>;
- };
--
-- gic: interrupt-controller@21000 {
-- compatible = "arm,cortex-a9-gic";
-- #interrupt-cells = <3>;
-- #address-cells = <0>;
-- interrupt-controller;
-- reg = <0x21000 0x1000>,
-- <0x20100 0x100>;
-- };
--
-- L2: cache-controller@22000 {
-- compatible = "arm,pl310-cache";
-- reg = <0x22000 0x1000>;
-- cache-unified;
-- arm,shared-override;
-- prefetch-data = <1>;
-- prefetch-instr = <1>;
-- cache-level = <2>;
-- };
- };
-
- pmu {
-@@ -301,18 +228,6 @@
- };
- };
-
-- nand_controller: nand-controller@18028000 {
-- compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1", "brcm,brcmnand";
-- reg = <0x18028000 0x600>, <0x1811a408 0x600>, <0x18028f00 0x20>;
-- reg-names = "nand", "iproc-idm", "iproc-ext";
-- interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
--
-- #address-cells = <1>;
-- #size-cells = <0>;
--
-- brcm,nand-has-wp;
-- };
--
- spi@18029200 {
- compatible = "brcm,spi-nsp-qspi", "brcm,spi-bcm-qspi";
- reg = <0x18029200 0x184>,
diff --git a/target/linux/bcm53xx/patches-6.1/031-v6.5-0005-ARM-dts-BCM5301X-Relicense-AXI-interrupts-code-to-th.patch b/target/linux/bcm53xx/patches-6.1/031-v6.5-0005-ARM-dts-BCM5301X-Relicense-AXI-interrupts-code-to-th.patch
deleted file mode 100644
index ef29266d0b..0000000000
--- a/target/linux/bcm53xx/patches-6.1/031-v6.5-0005-ARM-dts-BCM5301X-Relicense-AXI-interrupts-code-to-th.patch
+++ /dev/null
@@ -1,203 +0,0 @@
-From 3b3e35b279bee5e51580c648399e20323467f58c Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Mon, 15 May 2023 17:19:21 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Relicense AXI interrupts code to the GPL
- 2.0+ / MIT
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Those entries were added by:
-1. Hauke in commits dec378827c4a ("ARM: BCM5301X: Add IRQs to Broadcom's
- bus-axi in DTS file") and 1f80de6863ca ("ARM: BCM5301X: add IRQ
- numbers for PCIe controller")
-2. Florian in the commit 2cd0c0202f13 ("ARM: dts: BCM5301X: Add SRAB
- interrupts")
-
-Move them to the bcm-ns.dtsi which uses dual licensing. That syncs more
-Northstar code to be based on the same licensing schema.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Cc: Hauke Mehrtens <hauke@hauke-m.de>
-Cc: Florian Fainelli <f.fainelli@gmail.com>
-Acked-by: Hauke Mehrtens <hauke@hauke-m.de>
-Link: https://lore.kernel.org/r/20230515151921.25021-2-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/bcm-ns.dtsi | 73 ++++++++++++++++++++++++++++++++
- arch/arm/boot/dts/bcm5301x.dtsi | 75 ---------------------------------
- 2 files changed, 73 insertions(+), 75 deletions(-)
-
---- a/arch/arm/boot/dts/bcm-ns.dtsi
-+++ b/arch/arm/boot/dts/bcm-ns.dtsi
-@@ -92,6 +92,79 @@
- #address-cells = <1>;
- #size-cells = <1>;
-
-+ #interrupt-cells = <1>;
-+ interrupt-map-mask = <0x000fffff 0xffff>;
-+ interrupt-map =
-+ /* ChipCommon */
-+ <0x00000000 0 &gic GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>,
-+
-+ /* Switch Register Access Block */
-+ <0x00007000 0 &gic GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00007000 1 &gic GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00007000 2 &gic GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00007000 3 &gic GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00007000 4 &gic GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00007000 5 &gic GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00007000 6 &gic GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00007000 7 &gic GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00007000 8 &gic GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00007000 9 &gic GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00007000 10 &gic GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00007000 11 &gic GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00007000 12 &gic GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>,
-+
-+ /* PCIe Controller 0 */
-+ <0x00012000 0 &gic GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00012000 1 &gic GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00012000 2 &gic GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00012000 3 &gic GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00012000 4 &gic GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00012000 5 &gic GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
-+
-+ /* PCIe Controller 1 */
-+ <0x00013000 0 &gic GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00013000 1 &gic GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00013000 2 &gic GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00013000 3 &gic GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00013000 4 &gic GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00013000 5 &gic GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
-+
-+ /* PCIe Controller 2 */
-+ <0x00014000 0 &gic GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00014000 1 &gic GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00014000 2 &gic GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00014000 3 &gic GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00014000 4 &gic GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00014000 5 &gic GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>,
-+
-+ /* USB 2.0 Controller */
-+ <0x00021000 0 &gic GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>,
-+
-+ /* USB 3.0 Controller */
-+ <0x00023000 0 &gic GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>,
-+
-+ /* Ethernet Controller 0 */
-+ <0x00024000 0 &gic GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>,
-+
-+ /* Ethernet Controller 1 */
-+ <0x00025000 0 &gic GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>,
-+
-+ /* Ethernet Controller 2 */
-+ <0x00026000 0 &gic GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>,
-+
-+ /* Ethernet Controller 3 */
-+ <0x00027000 0 &gic GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>,
-+
-+ /* NAND Controller */
-+ <0x00028000 0 &gic GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00028000 1 &gic GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00028000 2 &gic GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00028000 3 &gic GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00028000 4 &gic GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00028000 5 &gic GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00028000 6 &gic GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>,
-+ <0x00028000 7 &gic GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
-+
- chipcommon: chipcommon@0 {
- reg = <0x00000000 0x1000>;
-
---- a/arch/arm/boot/dts/bcm5301x.dtsi
-+++ b/arch/arm/boot/dts/bcm5301x.dtsi
-@@ -3,8 +3,6 @@
- * Generic DTS part for all BCM53010, BCM53011, BCM53012, BCM53014, BCM53015,
- * BCM53016, BCM53017, BCM53018, BCM4707, BCM4708 and BCM4709 SoCs
- *
-- * Copyright 2013-2014 Hauke Mehrtens <hauke@hauke-m.de>
-- *
- * Licensed under the GNU/GPL. See COPYING for details.
- */
-
-@@ -72,79 +70,6 @@
- };
-
- axi@18000000 {
-- #interrupt-cells = <1>;
-- interrupt-map-mask = <0x000fffff 0xffff>;
-- interrupt-map =
-- /* ChipCommon */
-- <0x00000000 0 &gic GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>,
--
-- /* Switch Register Access Block */
-- <0x00007000 0 &gic GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00007000 1 &gic GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00007000 2 &gic GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00007000 3 &gic GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00007000 4 &gic GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00007000 5 &gic GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00007000 6 &gic GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00007000 7 &gic GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00007000 8 &gic GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00007000 9 &gic GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00007000 10 &gic GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00007000 11 &gic GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00007000 12 &gic GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>,
--
-- /* PCIe Controller 0 */
-- <0x00012000 0 &gic GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00012000 1 &gic GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00012000 2 &gic GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00012000 3 &gic GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00012000 4 &gic GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00012000 5 &gic GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
--
-- /* PCIe Controller 1 */
-- <0x00013000 0 &gic GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00013000 1 &gic GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00013000 2 &gic GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00013000 3 &gic GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00013000 4 &gic GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00013000 5 &gic GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
--
-- /* PCIe Controller 2 */
-- <0x00014000 0 &gic GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00014000 1 &gic GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00014000 2 &gic GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00014000 3 &gic GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00014000 4 &gic GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00014000 5 &gic GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>,
--
-- /* USB 2.0 Controller */
-- <0x00021000 0 &gic GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>,
--
-- /* USB 3.0 Controller */
-- <0x00023000 0 &gic GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>,
--
-- /* Ethernet Controller 0 */
-- <0x00024000 0 &gic GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>,
--
-- /* Ethernet Controller 1 */
-- <0x00025000 0 &gic GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>,
--
-- /* Ethernet Controller 2 */
-- <0x00026000 0 &gic GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>,
--
-- /* Ethernet Controller 3 */
-- <0x00027000 0 &gic GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>,
--
-- /* NAND Controller */
-- <0x00028000 0 &gic GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00028000 1 &gic GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00028000 2 &gic GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00028000 3 &gic GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00028000 4 &gic GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00028000 5 &gic GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00028000 6 &gic GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>,
-- <0x00028000 7 &gic GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
--
- pcie2: pcie@14000 {
- reg = <0x00014000 0x1000>;
- };
diff --git a/target/linux/bcm53xx/patches-6.1/031-v6.5-0006-ARM-dts-BCM5301X-Specify-MAC-addresses-on-Luxul-devi.patch b/target/linux/bcm53xx/patches-6.1/031-v6.5-0006-ARM-dts-BCM5301X-Specify-MAC-addresses-on-Luxul-devi.patch
deleted file mode 100644
index 7d9b297191..0000000000
--- a/target/linux/bcm53xx/patches-6.1/031-v6.5-0006-ARM-dts-BCM5301X-Specify-MAC-addresses-on-Luxul-devi.patch
+++ /dev/null
@@ -1,336 +0,0 @@
-From dfa6570eb5ce2f24059caadbe2ed70034b5337bc Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Mon, 15 May 2023 10:33:08 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Specify MAC addresses on Luxul devices
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Use NRAM (NVMEM device) and its "et0macaddr" variable (NVMEM cell) to
-point Ethernet devices to their MAC addresses.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230515083308.7612-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts | 13 +++++++++++++
- arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts | 13 +++++++++++++
- arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts | 13 +++++++++++++
- arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts | 11 +++++++++++
- arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts | 11 +++++++++++
- arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts | 13 +++++++++++++
- arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts | 11 +++++++++++
- arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts | 13 +++++++++++++
- arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts | 11 +++++++++++
- arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts | 5 ++++-
- 10 files changed, 113 insertions(+), 1 deletion(-)
-
---- a/arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts
-+++ b/arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts
-@@ -20,6 +20,14 @@
- reg = <0x00000000 0x08000000>;
- };
-
-+ nvram@1eff0000 {
-+ compatible = "brcm,nvram";
-+ reg = <0x1eff0000 0x10000>;
-+
-+ et0macaddr: et0macaddr {
-+ };
-+ };
-+
- leds {
- compatible = "gpio-leds";
-
-@@ -53,6 +61,11 @@
- };
- };
-
-+&gmac0 {
-+ nvmem-cells = <&et0macaddr>;
-+ nvmem-cell-names = "mac-address";
-+};
-+
- &spi_nor {
- status = "okay";
- };
---- a/arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts
-+++ b/arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts
-@@ -24,6 +24,14 @@
- reg = <0x00000000 0x08000000>;
- };
-
-+ nvram@1eff0000 {
-+ compatible = "brcm,nvram";
-+ reg = <0x1eff0000 0x10000>;
-+
-+ et0macaddr: et0macaddr {
-+ };
-+ };
-+
- nand_controller: nand-controller@18028000 {
- nand@0 {
- partitions {
-@@ -60,6 +68,11 @@
- };
- };
-
-+&gmac0 {
-+ nvmem-cells = <&et0macaddr>;
-+ nvmem-cell-names = "mac-address";
-+};
-+
- &spi_nor {
- status = "okay";
- };
---- a/arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts
-+++ b/arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts
-@@ -20,6 +20,14 @@
- reg = <0x00000000 0x08000000>;
- };
-
-+ nvram@1eff0000 {
-+ compatible = "brcm,nvram";
-+ reg = <0x1eff0000 0x10000>;
-+
-+ et0macaddr: et0macaddr {
-+ };
-+ };
-+
- leds {
- compatible = "gpio-leds";
-
-@@ -53,6 +61,11 @@
- };
- };
-
-+&gmac0 {
-+ nvmem-cells = <&et0macaddr>;
-+ nvmem-cell-names = "mac-address";
-+};
-+
- &spi_nor {
- status = "okay";
- };
---- a/arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts
-+++ b/arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts
-@@ -24,6 +24,10 @@
- nvram@1eff0000 {
- compatible = "brcm,nvram";
- reg = <0x1eff0000 0x10000>;
-+
-+ et0macaddr: et0macaddr {
-+ #nvmem-cell-cells = <1>;
-+ };
- };
-
- leds {
-@@ -106,6 +110,11 @@
- vcc-gpio = <&chipcommon 9 GPIO_ACTIVE_HIGH>;
- };
-
-+&gmac0 {
-+ nvmem-cells = <&et0macaddr 0>;
-+ nvmem-cell-names = "mac-address";
-+};
-+
- &spi_nor {
- status = "okay";
- };
-@@ -137,6 +146,8 @@
- port@4 {
- reg = <4>;
- label = "wan";
-+ nvmem-cells = <&et0macaddr 5>;
-+ nvmem-cell-names = "mac-address";
- };
-
- port@5 {
---- a/arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts
-@@ -25,6 +25,10 @@
- nvram@1eff0000 {
- compatible = "brcm,nvram";
- reg = <0x1eff0000 0x10000>;
-+
-+ et0macaddr: et0macaddr {
-+ #nvmem-cell-cells = <1>;
-+ };
- };
-
- leds {
-@@ -61,6 +65,11 @@
- vcc-gpio = <&chipcommon 18 GPIO_ACTIVE_HIGH>;
- };
-
-+&gmac0 {
-+ nvmem-cells = <&et0macaddr 0>;
-+ nvmem-cell-names = "mac-address";
-+};
-+
- &spi_nor {
- status = "okay";
- };
-@@ -76,6 +85,8 @@
- port@0 {
- reg = <0>;
- label = "wan";
-+ nvmem-cells = <&et0macaddr 1>;
-+ nvmem-cell-names = "mac-address";
- };
-
- port@1 {
---- a/arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts
-@@ -20,6 +20,14 @@
- reg = <0x00000000 0x08000000>;
- };
-
-+ nvram@1eff0000 {
-+ compatible = "brcm,nvram";
-+ reg = <0x1eff0000 0x10000>;
-+
-+ et0macaddr: et0macaddr {
-+ };
-+ };
-+
- leds {
- compatible = "gpio-leds";
-
-@@ -51,6 +59,11 @@
- };
- };
-
-+&gmac0 {
-+ nvmem-cells = <&et0macaddr>;
-+ nvmem-cell-names = "mac-address";
-+};
-+
- &spi_nor {
- status = "okay";
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts
-@@ -25,6 +25,10 @@
- nvram@1eff0000 {
- compatible = "brcm,nvram";
- reg = <0x1eff0000 0x10000>;
-+
-+ et0macaddr: et0macaddr {
-+ #nvmem-cell-cells = <1>;
-+ };
- };
-
- leds {
-@@ -61,6 +65,11 @@
- vcc-gpio = <&chipcommon 18 GPIO_ACTIVE_HIGH>;
- };
-
-+&gmac0 {
-+ nvmem-cells = <&et0macaddr 0>;
-+ nvmem-cell-names = "mac-address";
-+};
-+
- &spi_nor {
- status = "okay";
- };
-@@ -76,6 +85,8 @@
- port@0 {
- reg = <0>;
- label = "wan";
-+ nvmem-cells = <&et0macaddr 1>;
-+ nvmem-cell-names = "mac-address";
- };
-
- port@1 {
---- a/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts
-@@ -22,6 +22,14 @@
- <0x88000000 0x18000000>;
- };
-
-+ nvram@1eff0000 {
-+ compatible = "brcm,nvram";
-+ reg = <0x1eff0000 0x10000>;
-+
-+ et0macaddr: et0macaddr {
-+ };
-+ };
-+
- leds {
- compatible = "gpio-leds";
-
-@@ -47,6 +55,11 @@
- status = "okay";
- };
-
-+&gmac0 {
-+ nvmem-cells = <&et0macaddr>;
-+ nvmem-cell-names = "mac-address";
-+};
-+
- &spi_nor {
- status = "okay";
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts
-@@ -25,6 +25,10 @@
- nvram@1eff0000 {
- compatible = "brcm,nvram";
- reg = <0x1eff0000 0x10000>;
-+
-+ et0macaddr: et0macaddr {
-+ #nvmem-cell-cells = <1>;
-+ };
- };
-
- leds {
-@@ -101,6 +105,11 @@
- vcc-gpio = <&chipcommon 18 GPIO_ACTIVE_HIGH>;
- };
-
-+&gmac0 {
-+ nvmem-cells = <&et0macaddr 0>;
-+ nvmem-cell-names = "mac-address";
-+};
-+
- &spi_nor {
- status = "okay";
- };
-@@ -136,6 +145,8 @@
- port@4 {
- reg = <4>;
- label = "wan";
-+ nvmem-cells = <&et0macaddr 5>;
-+ nvmem-cell-names = "mac-address";
- };
-
- port@5 {
---- a/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
-@@ -27,6 +27,7 @@
- reg = <0x1eff0000 0x10000>;
-
- et0macaddr: et0macaddr {
-+ #nvmem-cell-cells = <1>;
- };
- };
-
-@@ -76,7 +77,7 @@
- };
-
- &gmac0 {
-- nvmem-cells = <&et0macaddr>;
-+ nvmem-cells = <&et0macaddr 0>;
- nvmem-cell-names = "mac-address";
- };
-
-@@ -119,6 +120,8 @@
- port@4 {
- reg = <4>;
- label = "wan";
-+ nvmem-cells = <&et0macaddr 5>;
-+ nvmem-cell-names = "mac-address";
- };
-
- port@5 {
diff --git a/target/linux/bcm53xx/patches-6.1/031-v6.5-0007-ARM-dts-BCM5301X-Use-updated-device-compatible-strin.patch b/target/linux/bcm53xx/patches-6.1/031-v6.5-0007-ARM-dts-BCM5301X-Use-updated-device-compatible-strin.patch
deleted file mode 100644
index 5f5890e291..0000000000
--- a/target/linux/bcm53xx/patches-6.1/031-v6.5-0007-ARM-dts-BCM5301X-Use-updated-device-compatible-strin.patch
+++ /dev/null
@@ -1,90 +0,0 @@
-From 9d7121f1d2faa0b50bf5b462adcd2dd91970c45e Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Sat, 20 May 2023 13:26:01 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Use updated device "compatible" strings
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Northstar binding was updated to use minus/hyphen char between model and
-version for all devices.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
-Link: https://lore.kernel.org/r/20230520112601.11821-2-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts | 2 +-
- arch/arm/boot/dts/bcm4708-netgear-r6250.dts | 2 +-
- arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts | 2 +-
- arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts | 2 +-
- arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts | 2 +-
- arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts | 2 +-
- 6 files changed, 6 insertions(+), 6 deletions(-)
-
---- a/arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts
-+++ b/arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts
-@@ -8,7 +8,7 @@
- #include "bcm4708.dtsi"
-
- / {
-- compatible = "luxul,xap-1510v1", "brcm,bcm4708";
-+ compatible = "luxul,xap-1510-v1", "brcm,bcm4708";
- model = "Luxul XAP-1510 V1";
-
- chosen {
---- a/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
-+++ b/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
-@@ -13,7 +13,7 @@
- #include "bcm5301x-nand-cs0-bch8.dtsi"
-
- / {
-- compatible = "netgear,r6250v1", "brcm,bcm4708";
-+ compatible = "netgear,r6250-v1", "brcm,bcm4708";
- model = "Netgear R6250 V1 (BCM4708)";
-
- chosen {
---- a/arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts
-+++ b/arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts
-@@ -12,7 +12,7 @@
- #include "bcm5301x-nand-cs0-bch8.dtsi"
-
- / {
-- compatible = "netgear,r6300v2", "brcm,bcm4708";
-+ compatible = "netgear,r6300-v2", "brcm,bcm4708";
- model = "Netgear R6300 V2 (BCM4708)";
-
- chosen {
---- a/arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts
-+++ b/arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts
-@@ -8,7 +8,7 @@
- #include "bcm47081.dtsi"
-
- / {
-- compatible = "luxul,xap-1410v1", "brcm,bcm47081", "brcm,bcm4708";
-+ compatible = "luxul,xap-1410-v1", "brcm,bcm47081", "brcm,bcm4708";
- model = "Luxul XAP-1410 V1";
-
- chosen {
---- a/arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts
-+++ b/arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts
-@@ -9,7 +9,7 @@
- #include "bcm5301x-nand-cs0-bch4.dtsi"
-
- / {
-- compatible = "luxul,xwr-1200v1", "brcm,bcm47081", "brcm,bcm4708";
-+ compatible = "luxul,xwr-1200-v1", "brcm,bcm47081", "brcm,bcm4708";
- model = "Luxul XWR-1200 V1";
-
- chosen {
---- a/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts
-@@ -9,7 +9,7 @@
- #include "bcm5301x-nand-cs0-bch4.dtsi"
-
- / {
-- compatible = "luxul,xwr-3100v1", "brcm,bcm47094", "brcm,bcm4708";
-+ compatible = "luxul,xwr-3100-v1", "brcm,bcm47094", "brcm,bcm4708";
- model = "Luxul XWR-3100 V1";
-
- chosen {
diff --git a/target/linux/bcm53xx/patches-6.1/031-v6.5-0008-ARM-dts-BCM5301X-Use-updated-spi-gpio-binding-proper.patch b/target/linux/bcm53xx/patches-6.1/031-v6.5-0008-ARM-dts-BCM5301X-Use-updated-spi-gpio-binding-proper.patch
deleted file mode 100644
index c16587f684..0000000000
--- a/target/linux/bcm53xx/patches-6.1/031-v6.5-0008-ARM-dts-BCM5301X-Use-updated-spi-gpio-binding-proper.patch
+++ /dev/null
@@ -1,82 +0,0 @@
-From 04afb51c1dce90051487d3c7b70a1b1b246ce29a Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 2 Jun 2023 17:10:23 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Use updated "spi-gpio" binding properties
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Switch away from deprecated properties.
-
-This fixes:
-arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dtb: spi: gpio-sck: False schema does not allow [[6, 7, 0]]
- From schema: Documentation/devicetree/bindings/spi/spi-gpio.yaml
-arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dtb: spi: gpio-mosi: False schema does not allow [[6, 4, 0]]
- From schema: Documentation/devicetree/bindings/spi/spi-gpio.yaml
-arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dtb: spi: 'sck-gpios' is a required property
- From schema: Documentation/devicetree/bindings/spi/spi-gpio.yaml
-arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dtb: spi: Unevaluated properties are not allowed ('gpio-mosi', 'gpio-sck' were unexpected)
- From schema: Documentation/devicetree/bindings/spi/spi-gpio.yaml
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230602151023.8607-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/bcm4708-buffalo-wzr-1166dhp-common.dtsi | 4 ++--
- arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts | 4 ++--
- arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts | 4 ++--
- arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts | 4 ++--
- 4 files changed, 8 insertions(+), 8 deletions(-)
-
---- a/arch/arm/boot/dts/bcm4708-buffalo-wzr-1166dhp-common.dtsi
-+++ b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1166dhp-common.dtsi
-@@ -16,8 +16,8 @@
- spi {
- compatible = "spi-gpio";
- num-chipselects = <1>;
-- gpio-sck = <&chipcommon 7 0>;
-- gpio-mosi = <&chipcommon 4 0>;
-+ sck-gpios = <&chipcommon 7 0>;
-+ mosi-gpios = <&chipcommon 4 0>;
- cs-gpios = <&chipcommon 6 0>;
- #address-cells = <1>;
- #size-cells = <0>;
---- a/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts
-+++ b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts
-@@ -28,8 +28,8 @@
- spi {
- compatible = "spi-gpio";
- num-chipselects = <1>;
-- gpio-sck = <&chipcommon 7 0>;
-- gpio-mosi = <&chipcommon 4 0>;
-+ sck-gpios = <&chipcommon 7 0>;
-+ mosi-gpios = <&chipcommon 4 0>;
- cs-gpios = <&chipcommon 6 0>;
- #address-cells = <1>;
- #size-cells = <0>;
---- a/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
-+++ b/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
-@@ -28,8 +28,8 @@
- spi {
- compatible = "spi-gpio";
- num-chipselects = <1>;
-- gpio-sck = <&chipcommon 7 0>;
-- gpio-mosi = <&chipcommon 4 0>;
-+ sck-gpios = <&chipcommon 7 0>;
-+ mosi-gpios = <&chipcommon 4 0>;
- cs-gpios = <&chipcommon 6 0>;
- #address-cells = <1>;
- #size-cells = <0>;
---- a/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts
-+++ b/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts
-@@ -28,8 +28,8 @@
- spi {
- compatible = "spi-gpio";
- num-chipselects = <1>;
-- gpio-sck = <&chipcommon 7 0>;
-- gpio-mosi = <&chipcommon 4 0>;
-+ sck-gpios = <&chipcommon 7 0>;
-+ mosi-gpios = <&chipcommon 4 0>;
- cs-gpios = <&chipcommon 6 0>;
- #address-cells = <1>;
- #size-cells = <0>;
diff --git a/target/linux/bcm53xx/patches-6.1/031-v6.5-0009-ARM-dts-BCM5301X-Drop-invalid-usb-cells.patch b/target/linux/bcm53xx/patches-6.1/031-v6.5-0009-ARM-dts-BCM5301X-Drop-invalid-usb-cells.patch
deleted file mode 100644
index 59fa457aee..0000000000
--- a/target/linux/bcm53xx/patches-6.1/031-v6.5-0009-ARM-dts-BCM5301X-Drop-invalid-usb-cells.patch
+++ /dev/null
@@ -1,54 +0,0 @@
-From c3acdd4901192bc69dc577012663d5abae21661e Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 2 Jun 2023 15:34:54 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Drop invalid #usb-cells
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Such property simply doesn't exist (is not documented or used anywhere).
-
-This fixes:
-arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dtb: usb@21000: Unevaluated properties are not allowed ('#usb-cells' was unexpected)
- From schema: Documentation/devicetree/bindings/usb/generic-ehci.yaml
-arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dtb: usb@22000: Unevaluated properties are not allowed ('#usb-cells' was unexpected)
- From schema: Documentation/devicetree/bindings/usb/generic-ohci.yaml
-arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dtb: usb@23000: Unevaluated properties are not allowed ('#usb-cells' was unexpected)
- From schema: Documentation/devicetree/bindings/usb/generic-xhci.yaml
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230602133455.7441-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/bcm-ns.dtsi | 6 ------
- 1 file changed, 6 deletions(-)
-
---- a/arch/arm/boot/dts/bcm-ns.dtsi
-+++ b/arch/arm/boot/dts/bcm-ns.dtsi
-@@ -192,8 +192,6 @@
- interrupt-parent = <&gic>;
-
- ehci: usb@21000 {
-- #usb-cells = <0>;
--
- compatible = "generic-ehci";
- reg = <0x00021000 0x1000>;
- interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
-@@ -214,8 +212,6 @@
- };
-
- ohci: usb@22000 {
-- #usb-cells = <0>;
--
- compatible = "generic-ohci";
- reg = <0x00022000 0x1000>;
- interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
-@@ -245,8 +241,6 @@
- interrupt-parent = <&gic>;
-
- xhci: usb@23000 {
-- #usb-cells = <0>;
--
- compatible = "generic-xhci";
- reg = <0x00023000 0x1000>;
- interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/target/linux/bcm53xx/patches-6.1/031-v6.5-0010-ARM-dts-BCM5301X-Drop-invalid-properties-from-Meraki.patch b/target/linux/bcm53xx/patches-6.1/031-v6.5-0010-ARM-dts-BCM5301X-Drop-invalid-properties-from-Meraki.patch
deleted file mode 100644
index b8411fc719..0000000000
--- a/target/linux/bcm53xx/patches-6.1/031-v6.5-0010-ARM-dts-BCM5301X-Drop-invalid-properties-from-Meraki.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From 676bf7d062c14191c3fc12f1e36e1f3809041483 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 2 Jun 2023 15:34:55 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Drop invalid properties from Meraki MR32
- keys
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This fixes:
-arch/arm/boot/dts/bcm53015-meraki-mr26.dtb: keys: '#address-cells', '#size-cells' do not match any of the regexes: '^(button|event|key|switch|(button|event|key|switch)-[a-z0-9-]+|[a-z0-9-]+-(button|event|key|switch))$', 'pinctrl-[0-9]+'
- From schema: Documentation/devicetree/bindings/input/gpio-keys.yaml
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230602133455.7441-2-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/bcm53015-meraki-mr26.dts | 2 --
- 1 file changed, 2 deletions(-)
-
---- a/arch/arm/boot/dts/bcm53015-meraki-mr26.dts
-+++ b/arch/arm/boot/dts/bcm53015-meraki-mr26.dts
-@@ -39,8 +39,6 @@
-
- keys {
- compatible = "gpio-keys";
-- #address-cells = <1>;
-- #size-cells = <0>;
-
- key-restart {
- label = "Reset";
diff --git a/target/linux/bcm53xx/patches-6.1/031-v6.5-0011-ARM-dts-BCM5301X-Relicense-Christian-s-code-to-the-G.patch b/target/linux/bcm53xx/patches-6.1/031-v6.5-0011-ARM-dts-BCM5301X-Relicense-Christian-s-code-to-the-G.patch
deleted file mode 100644
index 7496321269..0000000000
--- a/target/linux/bcm53xx/patches-6.1/031-v6.5-0011-ARM-dts-BCM5301X-Relicense-Christian-s-code-to-the-G.patch
+++ /dev/null
@@ -1,106 +0,0 @@
-From 1d5682ccc7d6088179b6cfd50a3e3bb6d2b0527e Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Mon, 5 Jun 2023 08:10:49 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Relicense Christian's code to the GPL
- 2.0+ / MIT
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Move code added by Christian to the bcm-ns.dtsi which uses dual
-licensing. That syncs more Northstar code to be based on the same
-licensing schema.
-
-Cc: Christian Lamparter <chunkeey@gmail.com>
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Acked-by: Christian Lamparter <chunkeey@gmail.com>
-Link: https://lore.kernel.org/r/20230605061049.16136-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/bcm-ns.dtsi | 21 +++++++++++++++++++++
- arch/arm/boot/dts/bcm5301x.dtsi | 23 -----------------------
- 2 files changed, 21 insertions(+), 23 deletions(-)
-
---- a/arch/arm/boot/dts/bcm-ns.dtsi
-+++ b/arch/arm/boot/dts/bcm-ns.dtsi
-@@ -182,6 +182,10 @@
- reg = <0x00013000 0x1000>;
- };
-
-+ pcie2: pcie@14000 {
-+ reg = <0x00014000 0x1000>;
-+ };
-+
- usb2: usb2@21000 {
- reg = <0x00021000 0x1000>;
-
-@@ -274,6 +278,14 @@
- };
- };
-
-+ pwm: pwm@18002000 {
-+ compatible = "brcm,iproc-pwm";
-+ reg = <0x18002000 0x28>;
-+ clocks = <&osc>;
-+ #pwm-cells = <3>;
-+ status = "disabled";
-+ };
-+
- mdio: mdio@18003000 {
- compatible = "brcm,iproc-mdio";
- reg = <0x18003000 0x8>;
-@@ -299,6 +311,15 @@
- };
- };
-
-+ uart2: serial@18008000 {
-+ compatible = "ns16550a";
-+ reg = <0x18008000 0x20>;
-+ clocks = <&iprocslow>;
-+ interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
-+ reg-shift = <2>;
-+ status = "disabled";
-+ };
-+
- dmu-bus@1800c000 {
- compatible = "simple-bus";
- ranges = <0 0x1800c000 0x1000>;
---- a/arch/arm/boot/dts/bcm5301x.dtsi
-+++ b/arch/arm/boot/dts/bcm5301x.dtsi
-@@ -69,20 +69,6 @@
- };
- };
-
-- axi@18000000 {
-- pcie2: pcie@14000 {
-- reg = <0x00014000 0x1000>;
-- };
-- };
--
-- pwm: pwm@18002000 {
-- compatible = "brcm,iproc-pwm";
-- reg = <0x18002000 0x28>;
-- clocks = <&osc>;
-- #pwm-cells = <3>;
-- status = "disabled";
-- };
--
- mdio-mux@18003000 {
- compatible = "mdio-mux-mmioreg", "mdio-mux";
- mdio-parent-bus = <&mdio>;
-@@ -110,15 +96,6 @@
- reg = <0x18105000 0x1000>;
- };
-
-- uart2: serial@18008000 {
-- compatible = "ns16550a";
-- reg = <0x18008000 0x20>;
-- clocks = <&iprocslow>;
-- interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
-- reg-shift = <2>;
-- status = "disabled";
-- };
--
- i2c0: i2c@18009000 {
- compatible = "brcm,iproc-i2c";
- reg = <0x18009000 0x50>;
diff --git a/target/linux/bcm53xx/patches-6.1/031-v6.5-0012-ARM-dts-BCM5301X-Describe-switch-ports-in-the-main-D.patch b/target/linux/bcm53xx/patches-6.1/031-v6.5-0012-ARM-dts-BCM5301X-Describe-switch-ports-in-the-main-D.patch
deleted file mode 100644
index fa2f21af53..0000000000
--- a/target/linux/bcm53xx/patches-6.1/031-v6.5-0012-ARM-dts-BCM5301X-Describe-switch-ports-in-the-main-D.patch
+++ /dev/null
@@ -1,838 +0,0 @@
-From ba4aebce23b2affb810b8a60eae853674d2cded2 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Mon, 5 Jun 2023 15:21:09 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Describe switch ports in the main DTS
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-All Northstar SoCs have BCM5301x switches (BCM53011, BCM53012) with 8
-ports (0-8 without 6). By design 3 switch ports (5, 7 and 8) are
-hardwired to 3 on-SoC Ethernet interfaces. Switch port 8 requires
-forcing link state.
-
-It seems that global Northstar .dtsi file is the best place to describe
-those hw details. Only device specific bits (like labels) should go to
-device .dts files.
-
-This seems to fit well with a tiny exception of Asus RT-AC88U which
-somehow was designed to have switch 5 connected to an extra switch. This
-case was simply handled with a /delete-property/.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Reviewed-by: Christian Lamparter <chunkeey@gmail.com> (MR32+MR26)
-Link: https://lore.kernel.org/r/20230605132109.7933-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/bcm-ns.dtsi | 41 ++++++++++++++++++-
- .../bcm4708-buffalo-wzr-1166dhp-common.dtsi | 7 ----
- arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts | 4 --
- arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts | 3 --
- arch/arm/boot/dts/bcm4708-netgear-r6250.dts | 7 ----
- arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts | 7 ----
- .../boot/dts/bcm47081-buffalo-wzr-600dhp2.dts | 7 ----
- arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts | 3 --
- arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts | 7 ----
- arch/arm/boot/dts/bcm4709-netgear-r8000.dts | 12 ------
- arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts | 17 +-------
- arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts | 12 ------
- arch/arm/boot/dts/bcm47094-dlink-dir-890l.dts | 12 ------
- .../boot/dts/bcm47094-linksys-panamera.dts | 34 ++++-----------
- arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts | 7 ----
- arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts | 4 --
- arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts | 7 ----
- arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts | 3 --
- arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts | 7 ----
- .../boot/dts/bcm47094-luxul-xwr-3150-v1.dts | 7 ----
- arch/arm/boot/dts/bcm53015-meraki-mr26.dts | 3 --
- arch/arm/boot/dts/bcm53016-meraki-mr32.dts | 3 --
- 22 files changed, 51 insertions(+), 163 deletions(-)
-
---- a/arch/arm/boot/dts/bcm-ns.dtsi
-+++ b/arch/arm/boot/dts/bcm-ns.dtsi
-@@ -304,10 +304,49 @@
-
- status = "disabled";
-
-- /* ports are defined in board DTS */
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-+
-+ port@0 {
-+ reg = <0>;
-+ };
-+
-+ port@1 {
-+ reg = <1>;
-+ };
-+
-+ port@2 {
-+ reg = <2>;
-+ };
-+
-+ port@3 {
-+ reg = <3>;
-+ };
-+
-+ port@4 {
-+ reg = <4>;
-+ };
-+
-+ port@5 {
-+ reg = <5>;
-+ ethernet = <&gmac0>;
-+ };
-+
-+ port@7 {
-+ reg = <7>;
-+ ethernet = <&gmac1>;
-+ };
-+
-+ port@8 {
-+ reg = <8>;
-+ ethernet = <&gmac2>;
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
-+ };
- };
- };
-
---- a/arch/arm/boot/dts/bcm4708-buffalo-wzr-1166dhp-common.dtsi
-+++ b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1166dhp-common.dtsi
-@@ -159,34 +159,27 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "lan1";
- };
-
- port@1 {
-- reg = <1>;
- label = "lan2";
- };
-
- port@2 {
-- reg = <2>;
- label = "lan3";
- };
-
- port@3 {
-- reg = <3>;
- label = "lan4";
- };
-
- port@4 {
-- reg = <4>;
- label = "wan";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts
-+++ b/arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts
-@@ -75,19 +75,15 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "poe";
- };
-
- port@4 {
-- reg = <4>;
- label = "lan";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts
-+++ b/arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts
-@@ -82,14 +82,11 @@
-
- ports {
- port@4 {
-- reg = <4>;
- label = "lan";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
-+++ b/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
-@@ -100,34 +100,27 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "lan4";
- };
-
- port@1 {
-- reg = <1>;
- label = "lan3";
- };
-
- port@2 {
-- reg = <2>;
- label = "lan2";
- };
-
- port@3 {
-- reg = <3>;
- label = "lan1";
- };
-
- port@4 {
-- reg = <4>;
- label = "wan";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts
-+++ b/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts
-@@ -123,34 +123,27 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "lan4";
- };
-
- port@1 {
-- reg = <1>;
- label = "lan3";
- };
-
- port@2 {
-- reg = <2>;
- label = "lan2";
- };
-
- port@3 {
-- reg = <3>;
- label = "lan1";
- };
-
- port@4 {
-- reg = <4>;
- label = "wan";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
-+++ b/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
-@@ -123,34 +123,27 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "lan1";
- };
-
- port@1 {
-- reg = <1>;
- label = "lan2";
- };
-
- port@2 {
-- reg = <2>;
- label = "lan3";
- };
-
- port@3 {
-- reg = <3>;
- label = "lan4";
- };
-
- port@4 {
-- reg = <4>;
- label = "wan";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts
-+++ b/arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts
-@@ -75,14 +75,11 @@
-
- ports {
- port@4 {
-- reg = <4>;
- label = "poe";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts
-+++ b/arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts
-@@ -124,36 +124,29 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "lan4";
- };
-
- port@1 {
-- reg = <1>;
- label = "lan3";
- };
-
- port@2 {
-- reg = <2>;
- label = "lan2";
- };
-
- port@3 {
-- reg = <3>;
- label = "lan1";
- };
-
- port@4 {
-- reg = <4>;
- label = "wan";
- nvmem-cells = <&et0macaddr 5>;
- nvmem-cell-names = "mac-address";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
-+++ b/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
-@@ -191,39 +191,27 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "lan1";
- };
-
- port@1 {
-- reg = <1>;
- label = "lan2";
- };
-
- port@2 {
-- reg = <2>;
- label = "lan3";
- };
-
- port@3 {
-- reg = <3>;
- label = "lan4";
- };
-
- port@4 {
-- reg = <4>;
- label = "wan";
- };
-
- port@8 {
-- reg = <8>;
- label = "cpu";
-- ethernet = <&gmac2>;
--
-- fixed-link {
-- speed = <1000>;
-- full-duplex;
-- };
- };
- };
- };
---- a/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-+++ b/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-@@ -181,32 +181,28 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "lan4";
- };
-
- port@1 {
-- reg = <1>;
- label = "lan3";
- };
-
- port@2 {
-- reg = <2>;
- label = "lan2";
- };
-
- port@3 {
-- reg = <3>;
- label = "lan1";
- };
-
- port@4 {
-- reg = <4>;
- label = "wan";
- };
-
- sw0_p5: port@5 {
-- reg = <5>;
-+ /delete-property/ethernet;
-+
- label = "extsw";
- phy-mode = "rgmii";
-
-@@ -218,8 +214,6 @@
- };
-
- port@7 {
-- reg = <7>;
-- ethernet = <&gmac1>;
- label = "cpu";
-
- fixed-link {
-@@ -229,14 +223,7 @@
- };
-
- port@8 {
-- reg = <8>;
-- ethernet = <&gmac2>;
- label = "cpu";
--
-- fixed-link {
-- speed = <1000>;
-- full-duplex;
-- };
- };
- };
- };
---- a/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts
-+++ b/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts
-@@ -124,39 +124,27 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "lan4";
- };
-
- port@1 {
-- reg = <1>;
- label = "lan3";
- };
-
- port@2 {
-- reg = <2>;
- label = "lan2";
- };
-
- port@3 {
-- reg = <3>;
- label = "lan1";
- };
-
- port@4 {
-- reg = <4>;
- label = "wan";
- };
-
- port@8 {
-- reg = <8>;
- label = "cpu";
-- ethernet = <&gmac2>;
--
-- fixed-link {
-- speed = <1000>;
-- full-duplex;
-- };
- };
- };
- };
---- a/arch/arm/boot/dts/bcm47094-dlink-dir-890l.dts
-+++ b/arch/arm/boot/dts/bcm47094-dlink-dir-890l.dts
-@@ -172,40 +172,28 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "lan1";
- };
-
- port@1 {
-- reg = <1>;
- label = "lan2";
- };
-
- port@2 {
-- reg = <2>;
- label = "lan3";
- };
-
- port@3 {
-- reg = <3>;
- label = "lan4";
- };
-
- port@4 {
-- reg = <4>;
- label = "wan";
- };
-
- port@8 {
-- reg = <8>;
- label = "cpu";
-- ethernet = <&gmac2>;
- phy-mode = "rgmii";
--
-- fixed-link {
-- speed = <1000>;
-- full-duplex;
-- };
- };
- };
- };
---- a/arch/arm/boot/dts/bcm47094-linksys-panamera.dts
-+++ b/arch/arm/boot/dts/bcm47094-linksys-panamera.dts
-@@ -207,29 +207,32 @@
- dsa,member = <0 0>;
-
- ports {
-+ sw0_p0: port@0 {
-+ label = "extsw";
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
-+ };
-+
- port@1 {
-- reg = <1>;
- label = "lan7";
- };
-
- port@2 {
-- reg = <2>;
- label = "lan4";
- };
-
- port@3 {
-- reg = <3>;
- label = "lan8";
- };
-
- port@4 {
-- reg = <4>;
- label = "wan";
- };
-
- port@5 {
-- reg = <5>;
-- ethernet = <&gmac0>;
- label = "cpu";
- status = "disabled";
-
-@@ -240,8 +243,6 @@
- };
-
- port@7 {
-- reg = <7>;
-- ethernet = <&gmac1>;
- label = "cpu";
- status = "disabled";
-
-@@ -252,24 +253,7 @@
- };
-
- port@8 {
-- reg = <8>;
-- ethernet = <&gmac2>;
- label = "cpu";
--
-- fixed-link {
-- speed = <1000>;
-- full-duplex;
-- };
-- };
--
-- sw0_p0: port@0 {
-- reg = <0>;
-- label = "extsw";
--
-- fixed-link {
-- speed = <1000>;
-- full-duplex;
-- };
- };
- };
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts
-@@ -83,36 +83,29 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "wan";
- nvmem-cells = <&et0macaddr 1>;
- nvmem-cell-names = "mac-address";
- };
-
- port@1 {
-- reg = <1>;
- label = "lan4";
- };
-
- port@2 {
-- reg = <2>;
- label = "lan3";
- };
-
- port@3 {
-- reg = <3>;
- label = "lan2";
- };
-
- port@4 {
-- reg = <4>;
- label = "lan1";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts
-@@ -73,19 +73,15 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "poe";
- };
-
- port@1 {
-- reg = <1>;
- label = "lan";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts
-@@ -83,36 +83,29 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "wan";
- nvmem-cells = <&et0macaddr 1>;
- nvmem-cell-names = "mac-address";
- };
-
- port@1 {
-- reg = <1>;
- label = "lan4";
- };
-
- port@2 {
-- reg = <2>;
- label = "lan3";
- };
-
- port@3 {
-- reg = <3>;
- label = "lan2";
- };
-
- port@4 {
-- reg = <4>;
- label = "lan1";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts
-@@ -69,14 +69,11 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "lan";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts
-@@ -123,36 +123,29 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "lan4";
- };
-
- port@1 {
-- reg = <1>;
- label = "lan3";
- };
-
- port@2 {
-- reg = <2>;
- label = "lan2";
- };
-
- port@3 {
-- reg = <3>;
- label = "lan1";
- };
-
- port@4 {
-- reg = <4>;
- label = "wan";
- nvmem-cells = <&et0macaddr 5>;
- nvmem-cell-names = "mac-address";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
-@@ -98,36 +98,29 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "lan4";
- };
-
- port@1 {
-- reg = <1>;
- label = "lan3";
- };
-
- port@2 {
-- reg = <2>;
- label = "lan2";
- };
-
- port@3 {
-- reg = <3>;
- label = "lan1";
- };
-
- port@4 {
-- reg = <4>;
- label = "wan";
- nvmem-cells = <&et0macaddr 5>;
- nvmem-cell-names = "mac-address";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm53015-meraki-mr26.dts
-+++ b/arch/arm/boot/dts/bcm53015-meraki-mr26.dts
-@@ -115,14 +115,11 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "poe";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
-
- fixed-link {
- speed = <1000>;
---- a/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-+++ b/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-@@ -176,14 +176,11 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "poe";
- };
-
- port@5 {
-- reg = <5>;
- label = "cpu";
-- ethernet = <&gmac0>;
-
- fixed-link {
- speed = <1000>;
diff --git a/target/linux/bcm53xx/patches-6.1/031-v6.5-0013-ARM-dts-BCM5301X-MR26-MR32-remove-bogus-nand-ecc-alg.patch b/target/linux/bcm53xx/patches-6.1/031-v6.5-0013-ARM-dts-BCM5301X-MR26-MR32-remove-bogus-nand-ecc-alg.patch
deleted file mode 100644
index ea571f459a..0000000000
--- a/target/linux/bcm53xx/patches-6.1/031-v6.5-0013-ARM-dts-BCM5301X-MR26-MR32-remove-bogus-nand-ecc-alg.patch
+++ /dev/null
@@ -1,63 +0,0 @@
-From a6a1a156f5debaebf9f61850d111b966e9be9ee9 Mon Sep 17 00:00:00 2001
-From: Christian Lamparter <chunkeey@gmail.com>
-Date: Thu, 8 Jun 2023 17:36:27 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: MR26: MR32: remove bogus nand-ecc-algo
- property
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-| bcm53015-meraki-mr26.dtb: nand-controller@18028000:
-| nand@0:nand-ecc-algo:0: 'hw' is not one of ['hamming', 'bch', 'rs']
-| From schema: Documentation/[...]/nand-controller.yaml
-| bcm53016-meraki-mr32.dtb: nand-controller@18028000:
-| nand@0:nand-ecc-algo:0: 'hw' is not one of ['hamming', 'bch', 'rs']
-| From schema: Documentation/[...]/nand-controller.yaml
-
-original ECC values for these old Merakis are sadly not
-provided by the vendor. It looks like Meraki just stuck
-with what Broadcom's SDK was doing... which left this
-up to the proprietary nand driver.
-
-Note: The invalid setting was and is handled by brcmnand. It
-falls back to "bch" in brcmnand_setup_dev() when ecc.algo is
-set to NAND_ECC_ALGO_UNKNOWN (since "hw" is not in the list
-above).
-
-A correct nand-ecc-algo = "bch"; is already specified in the
-included "bcm5301x-nand-cs0-bch8.dtsi". So this line can be
-dropped.
-
-Reported-by: Rafał Miłecki <zajec5@gmail.com> (per Mail)
-Fixes: 935327a73553 ("ARM: dts: BCM5301X: Add DT for Meraki MR26")
-Fixes: ec88a9c344d9 ("ARM: BCM5301X: Add DT for Meraki MR32")
-Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
-Link: https://lore.kernel.org/r/2c4d00dd40124c2ddc0b139cbce7531b108f9052.1686238550.git.chunkeey@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/bcm53015-meraki-mr26.dts | 2 --
- arch/arm/boot/dts/bcm53016-meraki-mr32.dts | 2 --
- 2 files changed, 4 deletions(-)
-
---- a/arch/arm/boot/dts/bcm53015-meraki-mr26.dts
-+++ b/arch/arm/boot/dts/bcm53015-meraki-mr26.dts
-@@ -72,8 +72,6 @@
- };
-
- &nandcs {
-- nand-ecc-algo = "hw";
--
- partitions {
- compatible = "fixed-partitions";
- #address-cells = <0x1>;
---- a/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-+++ b/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-@@ -125,8 +125,6 @@
- };
-
- &nandcs {
-- nand-ecc-algo = "hw";
--
- partitions {
- /*
- * The partition autodetection does not work for this device.
diff --git a/target/linux/bcm53xx/patches-6.1/031-v6.5-0014-ARM-dts-BCM5301X-MR32-remove-partition-index-numbers.patch b/target/linux/bcm53xx/patches-6.1/031-v6.5-0014-ARM-dts-BCM5301X-MR32-remove-partition-index-numbers.patch
deleted file mode 100644
index 8eb5442d17..0000000000
--- a/target/linux/bcm53xx/patches-6.1/031-v6.5-0014-ARM-dts-BCM5301X-MR32-remove-partition-index-numbers.patch
+++ /dev/null
@@ -1,54 +0,0 @@
-From d68b2f7d7d06872450d4f39d84d5926d7e7ae88c Mon Sep 17 00:00:00 2001
-From: Christian Lamparter <chunkeey@gmail.com>
-Date: Thu, 8 Jun 2023 17:36:28 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: MR32: remove partition index numbers
-
-removes the partition indexes in the node names under.
-This brings the device tree source in line with others.
-
-Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
-Link: https://lore.kernel.org/r/627f57d568030a56499361790524b4d4f3381619.1686238550.git.chunkeey@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/bcm53016-meraki-mr32.dts | 10 +++++-----
- 1 file changed, 5 insertions(+), 5 deletions(-)
-
---- a/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-+++ b/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-@@ -138,31 +138,31 @@
- #address-cells = <0x1>;
- #size-cells = <0x1>;
-
-- partition0@0 {
-+ partition@0 {
- label = "u-boot";
- reg = <0x0 0x100000>;
- read-only;
- };
-
-- partition1@100000 {
-+ partition@100000 {
- label = "bootkernel1";
- reg = <0x100000 0x300000>;
- read-only;
- };
-
-- partition2@400000 {
-+ partition@400000 {
- label = "nvram";
- reg = <0x400000 0x100000>;
- read-only;
- };
-
-- partition3@500000 {
-+ partition@500000 {
- label = "bootkernel2";
- reg = <0x500000 0x300000>;
- read-only;
- };
-
-- partition4@800000 {
-+ partition@800000 {
- label = "ubi";
- reg = <0x800000 0x7780000>;
- };
diff --git a/target/linux/bcm53xx/patches-6.1/031-v6.5-0016-ARM-dts-BCM5301X-Add-Netgear-R8000-WiFi-regulator-ma.patch b/target/linux/bcm53xx/patches-6.1/031-v6.5-0016-ARM-dts-BCM5301X-Add-Netgear-R8000-WiFi-regulator-ma.patch
deleted file mode 100644
index 3ffe0b2f17..0000000000
--- a/target/linux/bcm53xx/patches-6.1/031-v6.5-0016-ARM-dts-BCM5301X-Add-Netgear-R8000-WiFi-regulator-ma.patch
+++ /dev/null
@@ -1,61 +0,0 @@
-From 752a63b8dbe6cc6900efd1035bea427a778a4b55 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 2 Jun 2023 15:59:25 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Add Netgear R8000 WiFi regulator mappings
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This allows setting FullMAC firmware regulatory domain.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230602135925.14143-3-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/bcm4709-netgear-r8000.dts | 17 +++++++++++++++++
- 1 file changed, 17 insertions(+)
-
---- a/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
-+++ b/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
-@@ -137,8 +137,10 @@
- #size-cells = <2>;
-
- wifi@0,1,0 {
-+ compatible = "brcm,bcm4366-fmac", "brcm,bcm4329-fmac";
- reg = <0x0000 0 0 0 0>;
- ieee80211-freq-limit = <5735000 5835000>;
-+ brcm,ccode-map = "JP-JP-78", "US-Q2-86";
- };
- };
- };
-@@ -159,6 +161,19 @@
- #address-cells = <3>;
- #size-cells = <2>;
-
-+ bridge@1,0 {
-+ reg = <0x800 0 0 0 0>;
-+
-+ #address-cells = <3>;
-+ #size-cells = <2>;
-+
-+ wifi@0,0 {
-+ compatible = "brcm,bcm4366-fmac", "brcm,bcm4329-fmac";
-+ reg = <0x0000 0 0 0 0>;
-+ brcm,ccode-map = "JP-JP-78", "US-Q2-86";
-+ };
-+ };
-+
- bridge@1,2,2 {
- reg = <0x1000 0 0 0 0>;
-
-@@ -166,8 +181,10 @@
- #size-cells = <2>;
-
- wifi@1,4,0 {
-+ compatible = "brcm,bcm4366-fmac", "brcm,bcm4329-fmac";
- reg = <0x0000 0 0 0 0>;
- ieee80211-freq-limit = <5170000 5730000>;
-+ brcm,ccode-map = "JP-JP-78", "US-Q2-86";
- };
- };
- };
diff --git a/target/linux/bcm53xx/patches-6.1/031-v6.5-0017-ARM-dts-BCM5301X-Add-cells-sizes-to-PCIe-nodes.patch b/target/linux/bcm53xx/patches-6.1/031-v6.5-0017-ARM-dts-BCM5301X-Add-cells-sizes-to-PCIe-nodes.patch
deleted file mode 100644
index 454ce4c278..0000000000
--- a/target/linux/bcm53xx/patches-6.1/031-v6.5-0017-ARM-dts-BCM5301X-Add-cells-sizes-to-PCIe-nodes.patch
+++ /dev/null
@@ -1,59 +0,0 @@
-From b67cad33176e472df6d16a24ee7624299bdcd5d5 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 16 Jun 2023 12:58:27 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Add cells sizes to PCIe nodes
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This fixes:
-arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dtb: pcie@12000: '#address-cells' is a required property
- From schema: /lib/python3.10/site-packages/dtschema/schemas/pci/pci-bus.yaml
-arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dtb: pcie@12000: '#size-cells' is a required property
- From schema: /lib/python3.10/site-packages/dtschema/schemas/pci/pci-bus.yaml
-arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dtb: pcie@13000: '#address-cells' is a required property
- From schema: /lib/python3.10/site-packages/dtschema/schemas/pci/pci-bus.yaml
-arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dtb: pcie@13000: '#size-cells' is a required property
- From schema: /lib/python3.10/site-packages/dtschema/schemas/pci/pci-bus.yaml
-arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dtb: pcie@14000: '#address-cells' is a required property
- From schema: /lib/python3.10/site-packages/dtschema/schemas/pci/pci-bus.yaml
-arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dtb: pcie@14000: '#size-cells' is a required property
- From schema: /lib/python3.10/site-packages/dtschema/schemas/pci/pci-bus.yaml
-
-Two properties that need to be added later are "device_type" and
-"ranges". Adding "device_type" on its own causes a new warning and the
-value of "ranges" needs to be determined yet.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230616105827.21656-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/bcm-ns.dtsi | 9 +++++++++
- 1 file changed, 9 insertions(+)
-
---- a/arch/arm/boot/dts/bcm-ns.dtsi
-+++ b/arch/arm/boot/dts/bcm-ns.dtsi
-@@ -176,14 +176,23 @@
-
- pcie0: pcie@12000 {
- reg = <0x00012000 0x1000>;
-+
-+ #address-cells = <3>;
-+ #size-cells = <2>;
- };
-
- pcie1: pcie@13000 {
- reg = <0x00013000 0x1000>;
-+
-+ #address-cells = <3>;
-+ #size-cells = <2>;
- };
-
- pcie2: pcie@14000 {
- reg = <0x00014000 0x1000>;
-+
-+ #address-cells = <3>;
-+ #size-cells = <2>;
- };
-
- usb2: usb2@21000 {
diff --git a/target/linux/bcm53xx/patches-6.1/032-v6.6-0001-ARM-dts-broadcom-add-missing-space-before.patch b/target/linux/bcm53xx/patches-6.1/032-v6.6-0001-ARM-dts-broadcom-add-missing-space-before.patch
deleted file mode 100644
index 9811757ee2..0000000000
--- a/target/linux/bcm53xx/patches-6.1/032-v6.6-0001-ARM-dts-broadcom-add-missing-space-before.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From 4b8e16de053fc88eac406ad63da2693dd8279043 Mon Sep 17 00:00:00 2001
-From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Date: Wed, 5 Jul 2023 17:01:07 +0200
-Subject: [PATCH] ARM: dts: broadcom: add missing space before {
-
-Add missing whitespace between node name/label and opening {.
-
-Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Link: https://lore.kernel.org/r/20230705150108.293999-1-krzysztof.kozlowski@linaro.org
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/broadcom/bcm47094-linksys-panamera.dts | 2 +-
- arch/arm/boot/dts/broadcom/bcm47094-phicomm-k3.dts | 2 +-
- 2 files changed, 2 insertions(+), 2 deletions(-)
-
---- a/arch/arm/boot/dts/bcm47094-linksys-panamera.dts
-+++ b/arch/arm/boot/dts/bcm47094-linksys-panamera.dts
-@@ -279,7 +279,7 @@
- reg = <0x080000 0x0100000>;
- };
-
-- partition@180000{
-+ partition@180000 {
- label = "devinfo";
- reg = <0x0180000 0x080000>;
- };
---- a/arch/arm/boot/dts/bcm47094-phicomm-k3.dts
-+++ b/arch/arm/boot/dts/bcm47094-phicomm-k3.dts
-@@ -55,7 +55,7 @@
- reg = <0x0080000 0x0100000>;
- };
-
-- partition@180000{
-+ partition@180000 {
- label = "phicomm";
- reg = <0x0180000 0x0280000>;
- read-only;
diff --git a/target/linux/bcm53xx/patches-6.1/032-v6.6-0002-ARM-dts-BCM5301X-Add-Wi-Fi-regulatory-mappings-for-L.patch b/target/linux/bcm53xx/patches-6.1/032-v6.6-0002-ARM-dts-BCM5301X-Add-Wi-Fi-regulatory-mappings-for-L.patch
deleted file mode 100644
index e5143abf58..0000000000
--- a/target/linux/bcm53xx/patches-6.1/032-v6.6-0002-ARM-dts-BCM5301X-Add-Wi-Fi-regulatory-mappings-for-L.patch
+++ /dev/null
@@ -1,107 +0,0 @@
-From 8960f095de3b80beb3639075f0c8161b6ea98c61 Mon Sep 17 00:00:00 2001
-From: Dan Haab <dan.haab@luxul.com>
-Date: Wed, 5 Jul 2023 09:32:51 -0600
-Subject: [PATCH] ARM: dts: BCM5301X: Add Wi-Fi regulatory mappings for Luxul
- devices
-
-This allows setting FullMAC firmware regulatory domain.
-
-Signed-off-by: Dan Haab <dan.haab@luxul.com>
-Link: https://lore.kernel.org/r/20230705153251.739236-1-riproute@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- .../dts/broadcom/bcm47094-luxul-xap-1610.dts | 37 +++++++++++++++++++
- .../broadcom/bcm47094-luxul-xwr-3150-v1.dts | 36 ++++++++++++++++++
- 2 files changed, 73 insertions(+)
-
---- a/arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts
-@@ -64,6 +64,43 @@
- nvmem-cell-names = "mac-address";
- };
-
-+
-+&pcie0 {
-+ #address-cells = <3>;
-+ #size-cells = <2>;
-+
-+ bridge@0,0 {
-+ reg = <0x0000 0 0 0 0>;
-+
-+ #address-cells = <3>;
-+ #size-cells = <2>;
-+
-+ wifi@0,0 {
-+ compatible = "brcm,bcm4366-fmac", "brcm,bcm4329-fmac";
-+ reg = <0x0000 0 0 0 0>;
-+ brcm,ccode-map = "AU-AU-920", "CA-CA-892", "GB-DE-964", "NZ-AU-920", "US-US-825";
-+ };
-+ };
-+};
-+
-+&pcie1 {
-+ #address-cells = <3>;
-+ #size-cells = <2>;
-+
-+ bridge@0,0 {
-+ reg = <0x0000 0 0 0 0>;
-+
-+ #address-cells = <3>;
-+ #size-cells = <2>;
-+
-+ wifi@0,0 {
-+ compatible = "brcm,bcm4366-fmac", "brcm,bcm4329-fmac";
-+ reg = <0x0000 0 0 0 0>;
-+ brcm,ccode-map = "AU-AU-920", "CA-CA-892", "GB-DE-964", "NZ-AU-920", "US-US-825";
-+ };
-+ };
-+};
-+
- &spi_nor {
- status = "okay";
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
-@@ -81,6 +81,42 @@
- nvmem-cell-names = "mac-address";
- };
-
-+&pcie0 {
-+ #address-cells = <3>;
-+ #size-cells = <2>;
-+
-+ bridge@0,0 {
-+ reg = <0x0000 0 0 0 0>;
-+
-+ #address-cells = <3>;
-+ #size-cells = <2>;
-+
-+ wifi@0,0 {
-+ compatible = "brcm,bcm4366-fmac", "brcm,bcm4329-fmac";
-+ reg = <0x0000 0 0 0 0>;
-+ brcm,ccode-map = "AU-AU-953", "CA-CA-946", "GB-E0-846", "NZ-AU-953", "US-Q2-930";
-+ };
-+ };
-+};
-+
-+&pcie1 {
-+ #address-cells = <3>;
-+ #size-cells = <2>;
-+
-+ bridge@0,0 {
-+ reg = <0x0000 0 0 0 0>;
-+
-+ #address-cells = <3>;
-+ #size-cells = <2>;
-+
-+ wifi@0,0 {
-+ compatible = "brcm,bcm4366-fmac", "brcm,bcm4329-fmac";
-+ reg = <0x0000 0 0 0 0>;
-+ brcm,ccode-map = "AU-AU-953", "CA-CA-946", "GB-E0-846", "NZ-AU-953", "US-Q2-930";
-+ };
-+ };
-+};
-+
- &usb3 {
- vcc-gpio = <&chipcommon 18 GPIO_ACTIVE_HIGH>;
- };
diff --git a/target/linux/bcm53xx/patches-6.1/032-v6.6-0003-ARM-dts-BCM5301X-Add-Ethernet-interfaces-links.patch b/target/linux/bcm53xx/patches-6.1/032-v6.6-0003-ARM-dts-BCM5301X-Add-Ethernet-interfaces-links.patch
deleted file mode 100644
index 4b2e608ec2..0000000000
--- a/target/linux/bcm53xx/patches-6.1/032-v6.6-0003-ARM-dts-BCM5301X-Add-Ethernet-interfaces-links.patch
+++ /dev/null
@@ -1,53 +0,0 @@
-From 2ce61fa62183cf994666fcc911da34075c7183b5 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 7 Jul 2023 11:15:19 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Add Ethernet interfaces links
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Northstar SoCs have 3 usable Ethernet interfaces each connected to one
-of switch ports. They all use fixed links.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230707091519.21673-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/broadcom/bcm-ns.dtsi | 18 ++++++++++++++++++
- 1 file changed, 18 insertions(+)
-
---- a/arch/arm/boot/dts/bcm-ns.dtsi
-+++ b/arch/arm/boot/dts/bcm-ns.dtsi
-@@ -272,14 +272,32 @@
-
- gmac0: ethernet@24000 {
- reg = <0x24000 0x800>;
-+ phy-mode = "internal";
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
- };
-
- gmac1: ethernet@25000 {
- reg = <0x25000 0x800>;
-+ phy-mode = "internal";
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
- };
-
- gmac2: ethernet@26000 {
- reg = <0x26000 0x800>;
-+ phy-mode = "internal";
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
- };
-
- gmac3: ethernet@27000 {
diff --git a/target/linux/bcm53xx/patches-6.1/032-v6.6-0004-ARM-dts-BCM53573-Drop-nonexistent-default-off-LED-tr.patch b/target/linux/bcm53xx/patches-6.1/032-v6.6-0004-ARM-dts-BCM53573-Drop-nonexistent-default-off-LED-tr.patch
deleted file mode 100644
index 8bad76edca..0000000000
--- a/target/linux/bcm53xx/patches-6.1/032-v6.6-0004-ARM-dts-BCM53573-Drop-nonexistent-default-off-LED-tr.patch
+++ /dev/null
@@ -1,57 +0,0 @@
-From be7e1e5b0f67c58ec4be0a54db23b6a4fa6e2116 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 7 Jul 2023 13:40:01 +0200
-Subject: [PATCH] ARM: dts: BCM53573: Drop nonexistent "default-off" LED
- trigger
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-There is no such trigger documented or implemented in Linux. It was a
-copy & paste mistake.
-
-This fixes:
-arch/arm/boot/dts/broadcom/bcm47189-luxul-xap-1440.dtb: leds: led-wlan:linux,default-trigger: 'oneOf' conditional failed, one must be fixed:
- 'default-off' is not one of ['backlight', 'default-on', 'heartbeat', 'disk-activity', 'disk-read', 'disk-write', 'timer', 'pattern', 'audio-micmute', 'audio-mute', 'bluetooth-power', 'flash', 'kbd-capslock', 'mtd', 'nand-disk', 'none', 'torch', 'usb-gadget', 'usb-host', 'usbport']
- 'default-off' does not match '^cpu[0-9]*$'
- 'default-off' does not match '^hci[0-9]+-power$'
- 'default-off' does not match '^mmc[0-9]+$'
- 'default-off' does not match '^phy[0-9]+tx$'
- From schema: Documentation/devicetree/bindings/leds/leds-gpio.yaml
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230707114004.2740-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/broadcom/bcm47189-luxul-xap-1440.dts | 1 -
- arch/arm/boot/dts/broadcom/bcm47189-luxul-xap-810.dts | 2 --
- 2 files changed, 3 deletions(-)
-
---- a/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts
-+++ b/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts
-@@ -26,7 +26,6 @@
- led-wlan {
- label = "bcm53xx:blue:wlan";
- gpios = <&chipcommon 10 GPIO_ACTIVE_LOW>;
-- linux,default-trigger = "default-off";
- };
-
- led-system {
---- a/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts
-+++ b/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts
-@@ -26,7 +26,6 @@
- led-5ghz {
- label = "bcm53xx:blue:5ghz";
- gpios = <&chipcommon 11 GPIO_ACTIVE_HIGH>;
-- linux,default-trigger = "default-off";
- };
-
- led-system {
-@@ -42,7 +41,6 @@
- led-2ghz {
- label = "bcm53xx:blue:2ghz";
- gpios = <&pcie0_chipcommon 3 GPIO_ACTIVE_HIGH>;
-- linux,default-trigger = "default-off";
- };
- };
-
diff --git a/target/linux/bcm53xx/patches-6.1/032-v6.6-0009-ARM-dts-BCM53573-Fix-Ethernet-info-for-Luxul-devices.patch b/target/linux/bcm53xx/patches-6.1/032-v6.6-0009-ARM-dts-BCM53573-Fix-Ethernet-info-for-Luxul-devices.patch
deleted file mode 100644
index 7930c52b16..0000000000
--- a/target/linux/bcm53xx/patches-6.1/032-v6.6-0009-ARM-dts-BCM53573-Fix-Ethernet-info-for-Luxul-devices.patch
+++ /dev/null
@@ -1,75 +0,0 @@
-From 44ad8207806973f4e4f7d870fff36cc01f494250 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Thu, 13 Jul 2023 13:11:45 +0200
-Subject: [PATCH] ARM: dts: BCM53573: Fix Ethernet info for Luxul devices
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Both Luxul's XAP devices (XAP-810 and XAP-1440) are access points that
-use a non-default design. They don't include switch but have a single
-Ethernet port and BCM54210E PHY connected to the Ethernet controller's
-MDIO bus.
-
-Support for those devices regressed due to two changes:
-
-1. Describing MDIO bus with switch
-After commit 9fb90ae6cae7 ("ARM: dts: BCM53573: Describe on-SoC BCM53125
-rev 4 switch") Linux stopped probing for MDIO devices.
-
-2. Dropping hardcoded BCM54210E delays
-In commit fea7fda7f50a ("net: phy: broadcom: Fix RGMII delays
-configuration for BCM54210E") support for other PHY modes was added but
-that requires a proper "phy-mode" value in DT.
-
-Both above changes are correct (they don't need to be reverted or
-anything) but they need this fix for DT data to be correct and for Linux
-to work properly.
-
-Fixes: 9fb90ae6cae7 ("ARM: dts: BCM53573: Describe on-SoC BCM53125 rev 4 switch")
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230713111145.14864-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- .../boot/dts/broadcom/bcm47189-luxul-xap-1440.dts | 13 +++++++++++++
- .../boot/dts/broadcom/bcm47189-luxul-xap-810.dts | 13 +++++++++++++
- 2 files changed, 26 insertions(+)
-
---- a/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts
-+++ b/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts
-@@ -58,3 +58,16 @@
- };
- };
- };
-+
-+&gmac0 {
-+ phy-mode = "rgmii";
-+ phy-handle = <&bcm54210e>;
-+
-+ mdio {
-+ /delete-node/ switch@1e;
-+
-+ bcm54210e: ethernet-phy@0 {
-+ reg = <0>;
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts
-+++ b/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts
-@@ -94,3 +94,16 @@
- };
- };
- };
-+
-+&gmac0 {
-+ phy-mode = "rgmii";
-+ phy-handle = <&bcm54210e>;
-+
-+ mdio {
-+ /delete-node/ switch@1e;
-+
-+ bcm54210e: ethernet-phy@0 {
-+ reg = <0>;
-+ };
-+ };
-+};
diff --git a/target/linux/bcm53xx/patches-6.1/032-v6.6-0010-ARM-dts-bcm5301x-Add-SEAMA-compatibles.patch b/target/linux/bcm53xx/patches-6.1/032-v6.6-0010-ARM-dts-bcm5301x-Add-SEAMA-compatibles.patch
deleted file mode 100644
index f23873e111..0000000000
--- a/target/linux/bcm53xx/patches-6.1/032-v6.6-0010-ARM-dts-bcm5301x-Add-SEAMA-compatibles.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From 72ec77d74d28be7359ef77971cdee38b60af9e49 Mon Sep 17 00:00:00 2001
-From: Linus Walleij <linus.walleij@linaro.org>
-Date: Thu, 13 Jul 2023 00:16:42 +0200
-Subject: [PATCH] ARM: dts: bcm5301x: Add SEAMA compatibles
-
-This adds SEAMA compatibles to the firmware partition of these
-two D-Link devices.
-
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-Link: https://lore.kernel.org/r/20230713-seama-partitions-v4-2-69e577453d40@linaro.org
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/broadcom/bcm47094-dlink-dir-885l.dts | 1 +
- arch/arm/boot/dts/broadcom/bcm47094-dlink-dir-890l.dts | 1 +
- 2 files changed, 2 insertions(+)
-
---- a/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts
-+++ b/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts
-@@ -33,6 +33,7 @@
- #size-cells = <1>;
-
- partition@0 {
-+ compatible = "seama";
- label = "firmware";
- reg = <0x00000000 0x08000000>;
- };
---- a/arch/arm/boot/dts/bcm47094-dlink-dir-890l.dts
-+++ b/arch/arm/boot/dts/bcm47094-dlink-dir-890l.dts
-@@ -149,6 +149,7 @@
- * partitions: this device uses SEAMA.
- */
- firmware@0 {
-+ compatible = "seama";
- label = "firmware";
- reg = <0x00000000 0x08000000>;
- };
diff --git a/target/linux/bcm53xx/patches-6.1/032-v6.6-0012-ARM-dts-BCM53573-Describe-BCM53125-switch-ports-in-t.patch b/target/linux/bcm53xx/patches-6.1/032-v6.6-0012-ARM-dts-BCM53573-Describe-BCM53125-switch-ports-in-t.patch
deleted file mode 100644
index ab27495078..0000000000
--- a/target/linux/bcm53xx/patches-6.1/032-v6.6-0012-ARM-dts-BCM53573-Describe-BCM53125-switch-ports-in-t.patch
+++ /dev/null
@@ -1,97 +0,0 @@
-From 8d6b61ecad2f1c939813c5c4517d53e04672dc48 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Sun, 23 Jul 2023 21:54:15 +0200
-Subject: [PATCH] ARM: dts: BCM53573: Describe BCM53125 switch ports in the
- main DTS
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-BCM53125 always has 5 ports with GPHYs (for LAN/WAN ports) and 2 IMP
-ports. It seems the best place to describe that in the main .dtsi.
-Device specific bits can go to device .dts files. This will help
-avoiding some code duplication.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230723195416.7831-2-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- .../boot/dts/broadcom/bcm47189-tenda-ac9.dts | 7 -----
- arch/arm/boot/dts/broadcom/bcm53573.dtsi | 26 ++++++++++++++++++-
- 2 files changed, 25 insertions(+), 8 deletions(-)
-
---- a/arch/arm/boot/dts/bcm47189-tenda-ac9.dts
-+++ b/arch/arm/boot/dts/bcm47189-tenda-ac9.dts
-@@ -111,34 +111,27 @@
-
- ports {
- port@0 {
-- reg = <0>;
- label = "wan";
- };
-
- port@1 {
-- reg = <1>;
- label = "lan1";
- };
-
- port@2 {
-- reg = <2>;
- label = "lan2";
- };
-
- port@3 {
-- reg = <3>;
- label = "lan3";
- };
-
- port@4 {
-- reg = <4>;
- label = "lan4";
- };
-
- port@8 {
-- reg = <8>;
- label = "cpu";
-- ethernet = <&gmac0>;
- };
- };
- };
---- a/arch/arm/boot/dts/bcm53573.dtsi
-+++ b/arch/arm/boot/dts/bcm53573.dtsi
-@@ -192,10 +192,34 @@
-
- status = "disabled";
-
-- /* ports are defined in board DTS */
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-+
-+ port@0 {
-+ reg = <0>;
-+ };
-+
-+ port@1 {
-+ reg = <1>;
-+ };
-+
-+ port@2 {
-+ reg = <2>;
-+ };
-+
-+ port@3 {
-+ reg = <3>;
-+ };
-+
-+ port@4 {
-+ reg = <4>;
-+ };
-+
-+ port@8 {
-+ reg = <8>;
-+ ethernet = <&gmac0>;
-+ };
- };
- };
- };
diff --git a/target/linux/bcm53xx/patches-6.1/032-v6.6-0013-ARM-dts-BCM53573-Add-BCM53125-switch-port-5.patch b/target/linux/bcm53xx/patches-6.1/032-v6.6-0013-ARM-dts-BCM53573-Add-BCM53125-switch-port-5.patch
deleted file mode 100644
index cc9e86ac75..0000000000
--- a/target/linux/bcm53xx/patches-6.1/032-v6.6-0013-ARM-dts-BCM53573-Add-BCM53125-switch-port-5.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From d95b1caeea194962220db1778ce7fe71cdba788b Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Sun, 23 Jul 2023 21:54:16 +0200
-Subject: [PATCH] ARM: dts: BCM53573: Add BCM53125 switch port 5
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-It's connected to the extra Ethernet interface.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230723195416.7831-3-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/broadcom/bcm53573.dtsi | 10 ++++++++++
- 1 file changed, 10 insertions(+)
-
---- a/arch/arm/boot/dts/bcm53573.dtsi
-+++ b/arch/arm/boot/dts/bcm53573.dtsi
-@@ -216,6 +216,16 @@
- reg = <4>;
- };
-
-+ port@5 {
-+ reg = <5>;
-+ ethernet = <&gmac1>;
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
-+ };
-+
- port@8 {
- reg = <8>;
- ethernet = <&gmac0>;
diff --git a/target/linux/bcm53xx/patches-6.1/032-v6.6-0014-ARM-dts-BCM53573-Add-Ethernet-interfaces-links.patch b/target/linux/bcm53xx/patches-6.1/032-v6.6-0014-ARM-dts-BCM53573-Add-Ethernet-interfaces-links.patch
deleted file mode 100644
index f97d4edd75..0000000000
--- a/target/linux/bcm53xx/patches-6.1/032-v6.6-0014-ARM-dts-BCM53573-Add-Ethernet-interfaces-links.patch
+++ /dev/null
@@ -1,73 +0,0 @@
-From e0ae343a2c1b782a346d9b844ea65e1d49c428b2 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Mon, 24 Jul 2023 12:12:27 +0200
-Subject: [PATCH] ARM: dts: BCM53573: Add Ethernet interfaces links
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-BCM53573 has 2 Ethernet interfaces each connected to one of switch ports
-in the default design. They both use fixed links.
-
-An exception are Luxul XAP devices that have switch replaced by a single
-PHY.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230724101227.5420-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- .../boot/dts/broadcom/bcm47189-luxul-xap-1440.dts | 2 ++
- .../arm/boot/dts/broadcom/bcm47189-luxul-xap-810.dts | 2 ++
- arch/arm/boot/dts/broadcom/bcm53573.dtsi | 12 ++++++++++++
- 3 files changed, 16 insertions(+)
-
---- a/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts
-+++ b/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts
-@@ -50,6 +50,8 @@
- phy-mode = "rgmii";
- phy-handle = <&bcm54210e>;
-
-+ /delete-node/ fixed-link;
-+
- mdio {
- /delete-node/ switch@1e;
-
---- a/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts
-+++ b/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts
-@@ -86,6 +86,8 @@
- phy-mode = "rgmii";
- phy-handle = <&bcm54210e>;
-
-+ /delete-node/ fixed-link;
-+
- mdio {
- /delete-node/ switch@1e;
-
---- a/arch/arm/boot/dts/bcm53573.dtsi
-+++ b/arch/arm/boot/dts/bcm53573.dtsi
-@@ -181,6 +181,12 @@
-
- gmac0: ethernet@5000 {
- reg = <0x5000 0x1000>;
-+ phy-mode = "internal";
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
-
- mdio {
- #address-cells = <1>;
-@@ -237,6 +243,12 @@
-
- gmac1: ethernet@b000 {
- reg = <0xb000 0x1000>;
-+ phy-mode = "internal";
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
- };
-
- pmu@12000 {
diff --git a/target/linux/bcm53xx/patches-6.1/032-v6.6-0015-ARM-dts-BCM53573-Disable-second-Ethernet-on-Luxul-de.patch b/target/linux/bcm53xx/patches-6.1/032-v6.6-0015-ARM-dts-BCM53573-Disable-second-Ethernet-on-Luxul-de.patch
deleted file mode 100644
index e9e347075d..0000000000
--- a/target/linux/bcm53xx/patches-6.1/032-v6.6-0015-ARM-dts-BCM53573-Disable-second-Ethernet-on-Luxul-de.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-From d8835601e3c306fda78f8736f1aef688e99e892d Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Mon, 24 Jul 2023 12:11:59 +0200
-Subject: [PATCH] ARM: dts: BCM53573: Disable second Ethernet on Luxul devices
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-XAP-810 and XAP-1440 both have a single Ethernet port and BCM54210E PHY.
-Their second Ethernet interface is not connected to anything.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230724101159.5289-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/broadcom/bcm47189-luxul-xap-1440.dts | 4 ++++
- arch/arm/boot/dts/broadcom/bcm47189-luxul-xap-810.dts | 4 ++++
- 2 files changed, 8 insertions(+)
-
---- a/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts
-+++ b/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts
-@@ -73,3 +73,7 @@
- };
- };
- };
-+
-+&gmac1 {
-+ status = "disabled";
-+};
---- a/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts
-+++ b/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts
-@@ -109,3 +109,7 @@
- };
- };
- };
-+
-+&gmac1 {
-+ status = "disabled";
-+};
diff --git a/target/linux/bcm53xx/patches-6.1/032-v6.6-0016-ARM-dts-BCM5301X-Add-DT-for-Asus-RT-AC3100.patch b/target/linux/bcm53xx/patches-6.1/032-v6.6-0016-ARM-dts-BCM5301X-Add-DT-for-Asus-RT-AC3100.patch
deleted file mode 100644
index 47d5b10839..0000000000
--- a/target/linux/bcm53xx/patches-6.1/032-v6.6-0016-ARM-dts-BCM5301X-Add-DT-for-Asus-RT-AC3100.patch
+++ /dev/null
@@ -1,431 +0,0 @@
-From 2900083269f7c0f0ff430bffc6ced2038aed9b6b Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
-Date: Thu, 3 Aug 2023 10:14:54 +0300
-Subject: [PATCH] ARM: dts: BCM5301X: Add DT for ASUS RT-AC3100
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-ASUS RT-AC3100 is ASUS RT-AC88U without the external switch. Move the
-shared bindings to bcm47094-asus-rt-ac3100.dtsi.
-
-Remove the fixed-link node on port@7 as commit ba4aebce23b2 ("ARM: dts:
-BCM5301X: Describe switch ports in the main DTS") states it's not
-necessary.
-
-Replace the copyright notice with an author notice.
-
-Rename the model name from Asus to ASUS on bcm47094-asus-rt-ac88u.dts.
-
-Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
-Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
-Link: https://lore.kernel.org/r/20230803071454.5902-2-arinc.unal@arinc9.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/Makefile | 1 +
- .../dts/bcm47094-asus-rt-ac3100.dts | 23 +++
- .../dts/bcm47094-asus-rt-ac3100.dtsi | 163 ++++++++++++++++++
- .../dts/bcm47094-asus-rt-ac88u.dts | 155 +----------------
- 4 files changed, 190 insertions(+), 152 deletions(-)
- create mode 100644 arch/arm/boot/dts/bcm47094-asus-rt-ac3100.dts
- create mode 100644 arch/arm/boot/dts/bcm47094-asus-rt-ac3100.dtsi
-
---- a/arch/arm/boot/dts/Makefile
-+++ b/arch/arm/boot/dts/Makefile
-@@ -127,6 +127,7 @@ dtb-$(CONFIG_ARCH_BCM_5301X) += \
- bcm4709-netgear-r7000.dtb \
- bcm4709-netgear-r8000.dtb \
- bcm4709-tplink-archer-c9-v1.dtb \
-+ bcm47094-asus-rt-ac3100.dtb \
- bcm47094-asus-rt-ac88u.dtb \
- bcm47094-dlink-dir-885l.dtb \
- bcm47094-dlink-dir-890l.dtb \
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm47094-asus-rt-ac3100.dts
-@@ -0,0 +1,23 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-+/*
-+ * Author: Arınç ÜNAL <arinc.unal@arinc9.com>
-+ */
-+
-+/dts-v1/;
-+
-+#include "bcm47094-asus-rt-ac3100.dtsi"
-+
-+/ {
-+ compatible = "asus,rt-ac3100", "brcm,bcm47094", "brcm,bcm4708";
-+ model = "ASUS RT-AC3100";
-+
-+ nvram@1c080000 {
-+ et0macaddr: et0macaddr {
-+ };
-+ };
-+};
-+
-+&gmac0 {
-+ nvmem-cells = <&et0macaddr>;
-+ nvmem-cell-names = "mac-address";
-+};
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm47094-asus-rt-ac3100.dtsi
-@@ -0,0 +1,163 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-+/*
-+ * Author: Arınç ÜNAL <arinc.unal@arinc9.com>
-+ */
-+
-+#include "bcm47094.dtsi"
-+#include "bcm5301x-nand-cs0-bch8.dtsi"
-+
-+/ {
-+ chosen {
-+ bootargs = "earlycon";
-+ };
-+
-+ memory@0 {
-+ device_type = "memory";
-+ reg = <0x00000000 0x08000000>,
-+ <0x88000000 0x18000000>;
-+ };
-+
-+ nvram@1c080000 {
-+ compatible = "brcm,nvram";
-+ reg = <0x1c080000 0x00180000>;
-+ };
-+
-+ leds {
-+ compatible = "gpio-leds";
-+
-+ led-power {
-+ label = "white:power";
-+ gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
-+ linux,default-trigger = "default-on";
-+ };
-+
-+ led-wan-red {
-+ label = "red:wan";
-+ gpios = <&chipcommon 5 GPIO_ACTIVE_HIGH>;
-+ };
-+
-+ led-lan {
-+ label = "white:lan";
-+ gpios = <&chipcommon 21 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ led-usb2 {
-+ label = "white:usb2";
-+ gpios = <&chipcommon 16 GPIO_ACTIVE_LOW>;
-+ trigger-sources = <&ehci_port2>;
-+ linux,default-trigger = "usbport";
-+ };
-+
-+ led-usb3 {
-+ label = "white:usb3";
-+ gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>;
-+ trigger-sources = <&ehci_port1>, <&xhci_port1>;
-+ linux,default-trigger = "usbport";
-+ };
-+
-+ led-wps {
-+ label = "white:wps";
-+ gpios = <&chipcommon 19 GPIO_ACTIVE_LOW>;
-+ };
-+ };
-+
-+ gpio-keys {
-+ compatible = "gpio-keys";
-+
-+ button-wps {
-+ label = "WPS";
-+ linux,code = <KEY_WPS_BUTTON>;
-+ gpios = <&chipcommon 20 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ button-reset {
-+ label = "Reset";
-+ linux,code = <KEY_RESTART>;
-+ gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ button-wifi {
-+ label = "Wi-Fi";
-+ linux,code = <KEY_RFKILL>;
-+ gpios = <&chipcommon 18 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ button-led {
-+ label = "Backlight";
-+ linux,code = <KEY_BRIGHTNESS_ZERO>;
-+ gpios = <&chipcommon 4 GPIO_ACTIVE_LOW>;
-+ };
-+ };
-+};
-+
-+&srab {
-+ compatible = "brcm,bcm53012-srab", "brcm,bcm5301x-srab";
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "lan4";
-+ };
-+
-+ port@1 {
-+ label = "lan3";
-+ };
-+
-+ port@2 {
-+ label = "lan2";
-+ };
-+
-+ port@3 {
-+ label = "lan1";
-+ };
-+
-+ port@4 {
-+ label = "wan";
-+ };
-+
-+ port@5 {
-+ label = "cpu";
-+ };
-+
-+ port@7 {
-+ label = "cpu";
-+ };
-+
-+ port@8 {
-+ label = "cpu";
-+ };
-+ };
-+};
-+
-+&usb2 {
-+ vcc-gpio = <&chipcommon 9 GPIO_ACTIVE_HIGH>;
-+};
-+
-+&usb3_phy {
-+ status = "okay";
-+};
-+
-+&nandcs {
-+ partitions {
-+ compatible = "fixed-partitions";
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ partition@0 {
-+ label = "boot";
-+ reg = <0x00000000 0x00080000>;
-+ read-only;
-+ };
-+
-+ partition@80000 {
-+ label = "nvram";
-+ reg = <0x00080000 0x00180000>;
-+ };
-+
-+ partition@200000 {
-+ label = "firmware";
-+ reg = <0x00200000 0x07e00000>;
-+ compatible = "brcm,trx";
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-+++ b/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
-@@ -1,102 +1,21 @@
- // SPDX-License-Identifier: GPL-2.0-or-later OR MIT
- /*
-- * Copyright (C) 2021-2022 Arınç ÜNAL <arinc.unal@arinc9.com>
-+ * Author: Arınç ÜNAL <arinc.unal@arinc9.com>
- */
-
- /dts-v1/;
-
--#include "bcm47094.dtsi"
--#include "bcm5301x-nand-cs0-bch8.dtsi"
-+#include "bcm47094-asus-rt-ac3100.dtsi"
-
- / {
- compatible = "asus,rt-ac88u", "brcm,bcm47094", "brcm,bcm4708";
-- model = "Asus RT-AC88U";
--
-- chosen {
-- bootargs = "earlycon";
-- };
--
-- memory@0 {
-- device_type = "memory";
-- reg = <0x00000000 0x08000000>,
-- <0x88000000 0x18000000>;
-- };
-+ model = "ASUS RT-AC88U";
-
- nvram@1c080000 {
-- compatible = "brcm,nvram";
-- reg = <0x1c080000 0x00180000>;
--
- et1macaddr: et1macaddr {
- };
- };
-
-- leds {
-- compatible = "gpio-leds";
--
-- led-power {
-- label = "white:power";
-- gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
-- linux,default-trigger = "default-on";
-- };
--
-- led-wan-red {
-- label = "red:wan";
-- gpios = <&chipcommon 5 GPIO_ACTIVE_HIGH>;
-- };
--
-- led-lan {
-- label = "white:lan";
-- gpios = <&chipcommon 21 GPIO_ACTIVE_LOW>;
-- };
--
-- led-usb2 {
-- label = "white:usb2";
-- gpios = <&chipcommon 16 GPIO_ACTIVE_LOW>;
-- trigger-sources = <&ehci_port2>;
-- linux,default-trigger = "usbport";
-- };
--
-- led-usb3 {
-- label = "white:usb3";
-- gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>;
-- trigger-sources = <&ehci_port1>, <&xhci_port1>;
-- linux,default-trigger = "usbport";
-- };
--
-- led-wps {
-- label = "white:wps";
-- gpios = <&chipcommon 19 GPIO_ACTIVE_LOW>;
-- };
-- };
--
-- gpio-keys {
-- compatible = "gpio-keys";
--
-- button-wps {
-- label = "WPS";
-- linux,code = <KEY_WPS_BUTTON>;
-- gpios = <&chipcommon 20 GPIO_ACTIVE_LOW>;
-- };
--
-- button-reset {
-- label = "Reset";
-- linux,code = <KEY_RESTART>;
-- gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
-- };
--
-- button-wifi {
-- label = "Wi-Fi";
-- linux,code = <KEY_RFKILL>;
-- gpios = <&chipcommon 18 GPIO_ACTIVE_LOW>;
-- };
--
-- button-led {
-- label = "Backlight";
-- linux,code = <KEY_BRIGHTNESS_ZERO>;
-- gpios = <&chipcommon 4 GPIO_ACTIVE_LOW>;
-- };
-- };
--
- switch {
- compatible = "realtek,rtl8365mb";
- /* 7 = MDIO (has input reads), 6 = MDC (clock, output only) */
-@@ -175,31 +94,9 @@
- };
-
- &srab {
-- compatible = "brcm,bcm53012-srab", "brcm,bcm5301x-srab";
-- status = "okay";
- dsa,member = <0 0>;
-
- ports {
-- port@0 {
-- label = "lan4";
-- };
--
-- port@1 {
-- label = "lan3";
-- };
--
-- port@2 {
-- label = "lan2";
-- };
--
-- port@3 {
-- label = "lan1";
-- };
--
-- port@4 {
-- label = "wan";
-- };
--
- sw0_p5: port@5 {
- /delete-property/ethernet;
-
-@@ -212,19 +109,6 @@
- pause;
- };
- };
--
-- port@7 {
-- label = "cpu";
--
-- fixed-link {
-- speed = <1000>;
-- full-duplex;
-- };
-- };
--
-- port@8 {
-- label = "cpu";
-- };
- };
- };
-
-@@ -236,36 +120,3 @@
- nvmem-cells = <&et1macaddr>;
- nvmem-cell-names = "mac-address";
- };
--
--&usb2 {
-- vcc-gpio = <&chipcommon 9 GPIO_ACTIVE_HIGH>;
--};
--
--&usb3_phy {
-- status = "okay";
--};
--
--&nandcs {
-- partitions {
-- compatible = "fixed-partitions";
-- #address-cells = <1>;
-- #size-cells = <1>;
--
-- partition@0 {
-- label = "boot";
-- reg = <0x00000000 0x00080000>;
-- read-only;
-- };
--
-- partition@80000 {
-- label = "nvram";
-- reg = <0x00080000 0x00180000>;
-- };
--
-- partition@200000 {
-- label = "firmware";
-- reg = <0x00200000 0x07e00000>;
-- compatible = "brcm,trx";
-- };
-- };
--};
diff --git a/target/linux/bcm53xx/patches-6.1/033-v6.7-0001-ARM-dts-BCM5301X-Set-MACs-for-D-Link-DIR-885L.patch b/target/linux/bcm53xx/patches-6.1/033-v6.7-0001-ARM-dts-BCM5301X-Set-MACs-for-D-Link-DIR-885L.patch
deleted file mode 100644
index 78b8975f1f..0000000000
--- a/target/linux/bcm53xx/patches-6.1/033-v6.7-0001-ARM-dts-BCM5301X-Set-MACs-for-D-Link-DIR-885L.patch
+++ /dev/null
@@ -1,56 +0,0 @@
-From 5cbee5828219c4f7b33e96b5d8ce5e467b2857c8 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 1 Sep 2023 12:55:49 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Set MACs for D-Link DIR-885L
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Specify NVRAM access and use its "et2macaddr" NVMEM cell.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230901105549.7076-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- .../dts/broadcom/bcm47094-dlink-dir-885l.dts | 16 ++++++++++++++++
- 1 file changed, 16 insertions(+)
-
---- a/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts
-+++ b/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts
-@@ -25,6 +25,15 @@
- <0x88000000 0x08000000>;
- };
-
-+ nvram@1e3f0000 {
-+ compatible = "brcm,nvram";
-+ reg = <0x1e3f0000 0x10000>;
-+
-+ et2macaddr: et2macaddr {
-+ #nvmem-cell-cells = <1>;
-+ };
-+ };
-+
- nand_controller: nand-controller@18028000 {
- nand@0 {
- partitions {
-@@ -112,6 +121,11 @@
- vcc-gpio = <&chipcommon 18 GPIO_ACTIVE_HIGH>;
- };
-
-+&gmac0 {
-+ nvmem-cells = <&et2macaddr 0>;
-+ nvmem-cell-names = "mac-address";
-+};
-+
- &spi_nor {
- status = "okay";
- };
-@@ -142,6 +156,8 @@
-
- port@4 {
- label = "wan";
-+ nvmem-cells = <&et2macaddr 3>;
-+ nvmem-cell-names = "mac-address";
- };
-
- port@8 {
diff --git a/target/linux/bcm53xx/patches-6.1/033-v6.7-0002-ARM-dts-BCM5301X-Set-MAC-address-for-Asus-RT-AC87U.patch b/target/linux/bcm53xx/patches-6.1/033-v6.7-0002-ARM-dts-BCM5301X-Set-MAC-address-for-Asus-RT-AC87U.patch
deleted file mode 100644
index 11ce7acb53..0000000000
--- a/target/linux/bcm53xx/patches-6.1/033-v6.7-0002-ARM-dts-BCM5301X-Set-MAC-address-for-Asus-RT-AC87U.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-From a9e79863b62aaaefcdf469fc331bf482ae00db0d Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 1 Sep 2023 14:43:11 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Set MAC address for Asus RT-AC87U
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Specify NVRAM access and use its "et1macaddr" NVMEM cell.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20230901124311.31156-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/broadcom/bcm4709-asus-rt-ac87u.dts | 11 +++++++++++
- 1 file changed, 11 insertions(+)
-
---- a/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts
-+++ b/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts
-@@ -25,6 +25,12 @@
- <0x88000000 0x08000000>;
- };
-
-+ nvram@1c080000 {
-+ et1macaddr: et1macaddr {
-+ #nvmem-cell-cells = <1>;
-+ };
-+ };
-+
- leds {
- compatible = "gpio-leds";
-
-@@ -62,6 +68,11 @@
- };
- };
-
-+&gmac0 {
-+ nvmem-cells = <&et1macaddr 0>;
-+ nvmem-cell-names = "mac-address";
-+};
-+
- &usb3_phy {
- status = "okay";
- };
diff --git a/target/linux/bcm53xx/patches-6.1/033-v6.7-0003-ARM-dts-BCM5301X-Relicense-Felix-s-code-to-the-GPL-2.patch b/target/linux/bcm53xx/patches-6.1/033-v6.7-0003-ARM-dts-BCM5301X-Relicense-Felix-s-code-to-the-GPL-2.patch
deleted file mode 100644
index 6df1e555e9..0000000000
--- a/target/linux/bcm53xx/patches-6.1/033-v6.7-0003-ARM-dts-BCM5301X-Relicense-Felix-s-code-to-the-GPL-2.patch
+++ /dev/null
@@ -1,57 +0,0 @@
-From 81ea360a16978a4df61df9db56b171909bd659c0 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Sat, 16 Sep 2023 10:30:57 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Relicense Felix's code to the GPL 2.0+ /
- MIT
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Move code added by Felix to the bcm-ns.dtsi which uses dual licensing.
-That syncs more Northstar code to be based on the same licensing schema.
-
-This code was added in the commit 1ff80363524c ("ARM: BCM5301X: Add
-profiling support").
-
-Cc: Felix Fietkau <nbd@nbd.name>
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Acked-by: Felix Fietkau <nbd@nbd.name>
-Link: https://lore.kernel.org/r/20230916083057.10458-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/broadcom/bcm-ns.dtsi | 7 +++++++
- arch/arm/boot/dts/broadcom/bcm5301x.dtsi | 7 -------
- 2 files changed, 7 insertions(+), 7 deletions(-)
-
---- a/arch/arm/boot/dts/bcm-ns.dtsi
-+++ b/arch/arm/boot/dts/bcm-ns.dtsi
-@@ -14,6 +14,13 @@
- #address-cells = <1>;
- #size-cells = <1>;
-
-+ pmu {
-+ compatible = "arm,cortex-a9-pmu";
-+ interrupts =
-+ <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
-+ <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
-+ };
-+
- chipcommon-a-bus@18000000 {
- compatible = "simple-bus";
- ranges = <0x00000000 0x18000000 0x00001000>;
---- a/arch/arm/boot/dts/bcm5301x.dtsi
-+++ b/arch/arm/boot/dts/bcm5301x.dtsi
-@@ -26,13 +26,6 @@
- };
- };
-
-- pmu {
-- compatible = "arm,cortex-a9-pmu";
-- interrupts =
-- <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
-- <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
-- };
--
- clocks {
- #address-cells = <1>;
- #size-cells = <1>;
diff --git a/target/linux/bcm53xx/patches-6.1/033-v6.7-0004-ARM-dts-BCM5301X-Relicense-Vivek-s-code-to-the-GPL-2.patch b/target/linux/bcm53xx/patches-6.1/033-v6.7-0004-ARM-dts-BCM5301X-Relicense-Vivek-s-code-to-the-GPL-2.patch
deleted file mode 100644
index 66db4a291f..0000000000
--- a/target/linux/bcm53xx/patches-6.1/033-v6.7-0004-ARM-dts-BCM5301X-Relicense-Vivek-s-code-to-the-GPL-2.patch
+++ /dev/null
@@ -1,104 +0,0 @@
-From b8d4f7c1be04d66c37c119c501c87bccc4197694 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Sat, 16 Sep 2023 10:58:55 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Relicense Vivek's code to the GPL 2.0+ /
- MIT
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Move code added by Vivek to the bcm-ns.dtsi which uses dual licensing.
-That syncs more Northstar code to be based on the same licensing schema.
-
-This code was added in the commit 37f6130ec39f ("ARM: dts: BCM5301X:
-Make USB 3.0 PHY use MDIO PHY driver").
-
-Cc: Vivek Unune <npcomplete13@gmail.com>
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Acked-by: Vivek Unune <npcomplete13@gmail.com>
-Link: https://lore.kernel.org/r/20230916085855.28375-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/broadcom/bcm-ns.dtsi | 27 ++++++++++++++++++++++++
- arch/arm/boot/dts/broadcom/bcm5301x.dtsi | 27 ------------------------
- 2 files changed, 27 insertions(+), 27 deletions(-)
-
---- a/arch/arm/boot/dts/bcm-ns.dtsi
-+++ b/arch/arm/boot/dts/bcm-ns.dtsi
-@@ -327,6 +327,29 @@
- #address-cells = <1>;
- };
-
-+ mdio-mux@18003000 {
-+ compatible = "mdio-mux-mmioreg", "mdio-mux";
-+ mdio-parent-bus = <&mdio>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ reg = <0x18003000 0x4>;
-+ mux-mask = <0x200>;
-+
-+ mdio@0 {
-+ reg = <0x0>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ usb3_phy: usb3-phy@10 {
-+ compatible = "brcm,ns-ax-usb3-phy";
-+ reg = <0x10>;
-+ usb3-dmp-syscon = <&usb3_dmp>;
-+ #phy-cells = <0>;
-+ status = "disabled";
-+ };
-+ };
-+ };
-+
- rng: rng@18004000 {
- compatible = "brcm,bcm5301x-rng";
- reg = <0x18004000 0x14>;
-@@ -467,6 +490,10 @@
- brcm,nand-has-wp;
- };
-
-+ usb3_dmp: syscon@18105000 {
-+ reg = <0x18105000 0x1000>;
-+ };
-+
- thermal-zones {
- cpu_thermal: cpu-thermal {
- polling-delay-passive = <0>;
---- a/arch/arm/boot/dts/bcm5301x.dtsi
-+++ b/arch/arm/boot/dts/bcm5301x.dtsi
-@@ -62,33 +62,6 @@
- };
- };
-
-- mdio-mux@18003000 {
-- compatible = "mdio-mux-mmioreg", "mdio-mux";
-- mdio-parent-bus = <&mdio>;
-- #address-cells = <1>;
-- #size-cells = <0>;
-- reg = <0x18003000 0x4>;
-- mux-mask = <0x200>;
--
-- mdio@0 {
-- reg = <0x0>;
-- #address-cells = <1>;
-- #size-cells = <0>;
--
-- usb3_phy: usb3-phy@10 {
-- compatible = "brcm,ns-ax-usb3-phy";
-- reg = <0x10>;
-- usb3-dmp-syscon = <&usb3_dmp>;
-- #phy-cells = <0>;
-- status = "disabled";
-- };
-- };
-- };
--
-- usb3_dmp: syscon@18105000 {
-- reg = <0x18105000 0x1000>;
-- };
--
- i2c0: i2c@18009000 {
- compatible = "brcm,iproc-i2c";
- reg = <0x18009000 0x50>;
diff --git a/target/linux/bcm53xx/patches-6.1/033-v6.7-0005-ARM-dts-BCM5301X-Explicitly-disable-unused-switch-CP.patch b/target/linux/bcm53xx/patches-6.1/033-v6.7-0005-ARM-dts-BCM5301X-Explicitly-disable-unused-switch-CP.patch
deleted file mode 100644
index 72e5c6b061..0000000000
--- a/target/linux/bcm53xx/patches-6.1/033-v6.7-0005-ARM-dts-BCM5301X-Explicitly-disable-unused-switch-CP.patch
+++ /dev/null
@@ -1,377 +0,0 @@
-From 473baeab929444295b0530f8766e4becb6a08973 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 13 Oct 2023 12:33:13 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Explicitly disable unused switch CPU
- ports
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-When redescribing ports I assumed that missing "label" (like "cpu")
-means switch port isn't used. That was incorrect and I realized my
-change made Linux always use the first (5) CPU port (there are 3 of
-them).
-
-While above should technically be possible it often isn't correct:
-1. Non-default switch ports are often connected to Ethernet interfaces
- not fully covered by vendor setup (they may miss MACs)
-2. On some devices non-default ports require specifying fixed link
-
-This fixes network connectivity for some devices. It was reported &
-tested for Netgear R8000. It also affects Linksys EA9200 with its
-downstream DTS.
-
-Fixes: ba4aebce23b2 ("ARM: dts: BCM5301X: Describe switch ports in the main DTS")
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20231013103314.10306-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- .../dts/broadcom/bcm4708-buffalo-wzr-1166dhp-common.dtsi | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm4708-luxul-xap-1510.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm4708-luxul-xwc-1000.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm4708-netgear-r6250.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm4708-smartrg-sr400ac.dts | 8 ++++++++
- .../boot/dts/broadcom/bcm47081-buffalo-wzr-600dhp2.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm47081-luxul-xap-1410.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm47081-luxul-xwr-1200.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm4709-netgear-r8000.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm47094-dlink-dir-885l.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm47094-dlink-dir-890l.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm47094-luxul-abr-4500.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm47094-luxul-xap-1610.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm47094-luxul-xbr-4500.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm47094-luxul-xwc-2000.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm47094-luxul-xwr-3100.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm47094-luxul-xwr-3150-v1.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm53015-meraki-mr26.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm53016-meraki-mr32.dts | 8 ++++++++
- arch/arm/boot/dts/broadcom/bcm953012er.dts | 8 ++++++++
- 20 files changed, 160 insertions(+)
-
---- a/arch/arm/boot/dts/bcm4708-buffalo-wzr-1166dhp-common.dtsi
-+++ b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1166dhp-common.dtsi
-@@ -181,5 +181,13 @@
- port@5 {
- label = "cpu";
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
---- a/arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts
-+++ b/arch/arm/boot/dts/bcm4708-luxul-xap-1510.dts
-@@ -85,5 +85,13 @@
- port@5 {
- label = "cpu";
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
---- a/arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts
-+++ b/arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts
-@@ -88,5 +88,13 @@
- port@5 {
- label = "cpu";
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
---- a/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
-+++ b/arch/arm/boot/dts/bcm4708-netgear-r6250.dts
-@@ -122,5 +122,13 @@
- port@5 {
- label = "cpu";
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
---- a/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts
-+++ b/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts
-@@ -145,6 +145,14 @@
- port@5 {
- label = "cpu";
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
-
---- a/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
-+++ b/arch/arm/boot/dts/bcm47081-buffalo-wzr-600dhp2.dts
-@@ -145,5 +145,13 @@
- port@5 {
- label = "cpu";
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
---- a/arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts
-+++ b/arch/arm/boot/dts/bcm47081-luxul-xap-1410.dts
-@@ -81,5 +81,13 @@
- port@5 {
- label = "cpu";
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
---- a/arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts
-+++ b/arch/arm/boot/dts/bcm47081-luxul-xwr-1200.dts
-@@ -148,5 +148,13 @@
- port@5 {
- label = "cpu";
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
---- a/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
-+++ b/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
-@@ -227,6 +227,14 @@
- label = "wan";
- };
-
-+ port@5 {
-+ status = "disabled";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
- port@8 {
- label = "cpu";
- };
---- a/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts
-+++ b/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts
-@@ -160,6 +160,14 @@
- nvmem-cell-names = "mac-address";
- };
-
-+ port@5 {
-+ status = "disabled";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
- port@8 {
- label = "cpu";
- };
---- a/arch/arm/boot/dts/bcm47094-dlink-dir-890l.dts
-+++ b/arch/arm/boot/dts/bcm47094-dlink-dir-890l.dts
-@@ -192,6 +192,14 @@
- label = "wan";
- };
-
-+ port@5 {
-+ status = "disabled";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
- port@8 {
- label = "cpu";
- phy-mode = "rgmii";
---- a/arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-abr-4500.dts
-@@ -107,5 +107,13 @@
- port@5 {
- label = "cpu";
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xap-1610.dts
-@@ -120,5 +120,13 @@
- port@5 {
- label = "cpu";
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xbr-4500.dts
-@@ -107,5 +107,13 @@
- port@5 {
- label = "cpu";
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts
-@@ -75,5 +75,13 @@
- port@5 {
- label = "cpu";
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts
-@@ -147,5 +147,13 @@
- port@5 {
- label = "cpu";
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
---- a/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
-+++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
-@@ -158,5 +158,13 @@
- port@5 {
- label = "cpu";
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
---- a/arch/arm/boot/dts/bcm53015-meraki-mr26.dts
-+++ b/arch/arm/boot/dts/bcm53015-meraki-mr26.dts
-@@ -124,6 +124,14 @@
- full-duplex;
- };
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
-
---- a/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-+++ b/arch/arm/boot/dts/bcm53016-meraki-mr32.dts
-@@ -185,6 +185,14 @@
- full-duplex;
- };
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
-
---- a/arch/arm/boot/dts/bcm953012er.dts
-+++ b/arch/arm/boot/dts/bcm953012er.dts
-@@ -84,6 +84,14 @@
- label = "cpu";
- ethernet = <&gmac0>;
- };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
- };
- };
-
diff --git a/target/linux/bcm53xx/patches-6.1/033-v6.7-0006-ARM-dts-BCM5301X-Set-fixed-link-for-extra-Netgear-R8.patch b/target/linux/bcm53xx/patches-6.1/033-v6.7-0006-ARM-dts-BCM5301X-Set-fixed-link-for-extra-Netgear-R8.patch
deleted file mode 100644
index 0b2b7b36a3..0000000000
--- a/target/linux/bcm53xx/patches-6.1/033-v6.7-0006-ARM-dts-BCM5301X-Set-fixed-link-for-extra-Netgear-R8.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From d313b0e9070a7100ca55e64fe3b081d176d8806d Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 13 Oct 2023 12:33:14 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Set fixed-link for extra Netgear R8000
- CPU ports
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Ports 5 and 7 are disabled by default because the standard use case is
-for port 8 to manage all CPU directed traffic. For experimentation
-purposes however it is desirable to provide adequate properties such
-that people can experiment with using different ports without having to
-figure out their configuration. Some of the use cases include but are
-not limited to doubling or tripling the bandwidth by leveraging the
-additional ports/Ethernet MAC combinations.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20231013103314.10306-2-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- arch/arm/boot/dts/broadcom/bcm4709-netgear-r8000.dts | 10 ++++++++++
- 1 file changed, 10 insertions(+)
-
---- a/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
-+++ b/arch/arm/boot/dts/bcm4709-netgear-r8000.dts
-@@ -229,10 +229,20 @@
-
- port@5 {
- status = "disabled";
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
- };
-
- port@7 {
- status = "disabled";
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
- };
-
- port@8 {
diff --git a/target/linux/bcm53xx/patches-6.1/033-v6.7-0007-ARM-dts-BCM5301X-Set-switch-ports-for-Linksys-EA9200.patch b/target/linux/bcm53xx/patches-6.1/033-v6.7-0007-ARM-dts-BCM5301X-Set-switch-ports-for-Linksys-EA9200.patch
deleted file mode 100644
index 4528c95a5a..0000000000
--- a/target/linux/bcm53xx/patches-6.1/033-v6.7-0007-ARM-dts-BCM5301X-Set-switch-ports-for-Linksys-EA9200.patch
+++ /dev/null
@@ -1,63 +0,0 @@
-From 253358f373492608348136e569366d73cb969f6a Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Tue, 24 Oct 2023 09:26:05 +0200
-Subject: [PATCH] ARM: dts: BCM5301X: Set switch ports for Linksys EA9200
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This patch was developed as OpenWrt downstream change and was recently
-confirmed to work as expected.
-
-Tested-by: Rani Hod <rani.hod@gmail.com>
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
-Link: https://lore.kernel.org/r/20231024072605.32517-1-zajec5@gmail.com
-Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
----
- .../dts/broadcom/bcm4709-linksys-ea9200.dts | 38 +++++++++++++++++++
- 1 file changed, 38 insertions(+)
-
---- a/arch/arm/boot/dts/bcm4709-linksys-ea9200.dts
-+++ b/arch/arm/boot/dts/bcm4709-linksys-ea9200.dts
-@@ -47,3 +47,41 @@
- &usb3_phy {
- status = "okay";
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "lan1";
-+ };
-+
-+ port@1 {
-+ label = "lan2";
-+ };
-+
-+ port@2 {
-+ label = "lan3";
-+ };
-+
-+ port@3 {
-+ label = "lan4";
-+ };
-+
-+ port@4 {
-+ label = "wan";
-+ };
-+
-+ port@5 {
-+ status = "disabled";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ label = "cpu";
-+ };
-+ };
-+};
diff --git a/target/linux/bcm53xx/patches-6.1/080-v6.2-bcma-support-SPROM-rev-11.patch b/target/linux/bcm53xx/patches-6.1/080-v6.2-bcma-support-SPROM-rev-11.patch
deleted file mode 100644
index 5ebc78ca20..0000000000
--- a/target/linux/bcm53xx/patches-6.1/080-v6.2-bcma-support-SPROM-rev-11.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From b9457a04eb89645049fdf427c13e6a18d5501895 Mon Sep 17 00:00:00 2001
-From: Linus Walleij <linus.walleij@linaro.org>
-Date: Tue, 11 Oct 2022 14:24:40 +0200
-Subject: [PATCH] bcma: support SPROM rev 11
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Rev 11 works fine for me to set the MAC address of gmac0 and
-gmac1 in the D-Link DWL-8610AP.
-
-Cc: Rafał Miłecki <zajec5@gmail.com>
-Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
----
- drivers/bcma/sprom.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/bcma/sprom.c
-+++ b/drivers/bcma/sprom.c
-@@ -170,7 +170,7 @@ static int bcma_sprom_valid(struct bcma_
- return err;
-
- revision = sprom[words - 1] & SSB_SPROM_REVISION_REV;
-- if (revision != 8 && revision != 9 && revision != 10) {
-+ if (revision < 8 || revision > 11) {
- pr_err("Unsupported SPROM revision: %d\n", revision);
- return -ENOENT;
- }
diff --git a/target/linux/bcm53xx/patches-6.1/140-mtd-parsers-trx-parse-firmware-MTD-partitions-only.patch b/target/linux/bcm53xx/patches-6.1/140-mtd-parsers-trx-parse-firmware-MTD-partitions-only.patch
deleted file mode 100644
index e1933e75c7..0000000000
--- a/target/linux/bcm53xx/patches-6.1/140-mtd-parsers-trx-parse-firmware-MTD-partitions-only.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Tue, 13 Apr 2021 18:25:20 +0200
-Subject: [PATCH] mtd: parsers: trx: parse "firmware" MTD partitions only
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Parsing every partition with "compatible" set to "brcm,trx" results in
-parsing both: firmware partition and failsafe partition on devices that
-implement failsafe booting. This affects e.g. Linksys EA9500 which has:
-
-partition@200000 {
- reg = <0x0200000 0x01d00000>;
- compatible = "linksys,ns-firmware", "brcm,trx";
-};
-
-partition@1f00000 {
- reg = <0x01f00000 0x01d00000>;
- compatible = "linksys,ns-firmware", "brcm,trx";
-};
-
-Check for MTD partition name "firmware" before parsing. Recently added
-ofpart_linksys_ns.c creates "firmware" and "failsafe" depending on
-bootloader setup.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
----
- drivers/mtd/parsers/parser_trx.c | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- a/drivers/mtd/parsers/parser_trx.c
-+++ b/drivers/mtd/parsers/parser_trx.c
-@@ -92,6 +92,10 @@ static int parser_trx_parse(struct mtd_i
- if (err != 0 && err != -EINVAL)
- pr_err("failed to parse \"brcm,trx-magic\" DT attribute, using default: %d\n", err);
-
-+ /* Don't parse any failsafe / backup partitions */
-+ if (strcmp(mtd->name, "firmware"))
-+ return -EINVAL;
-+
- parts = kcalloc(TRX_PARSER_MAX_PARTS, sizeof(struct mtd_partition),
- GFP_KERNEL);
- if (!parts)
diff --git a/target/linux/bcm53xx/patches-6.1/180-usb-xhci-add-support-for-performing-fake-doorbell.patch b/target/linux/bcm53xx/patches-6.1/180-usb-xhci-add-support-for-performing-fake-doorbell.patch
deleted file mode 100644
index ac5a48283d..0000000000
--- a/target/linux/bcm53xx/patches-6.1/180-usb-xhci-add-support-for-performing-fake-doorbell.patch
+++ /dev/null
@@ -1,118 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Sat, 1 Oct 2016 22:54:48 +0200
-Subject: [PATCH] usb: xhci: add support for performing fake doorbell
-
-Broadcom's Northstar XHCI controllers seem to need a special start
-procedure to work correctly. There isn't any official documentation of
-this, the problem is that controller doesn't detect any connected
-devices with default setup. Moreover connecting USB device to controller
-that doesn't run properly can cause SoC's watchdog issues.
-
-A workaround that was successfully tested on multiple devices is to
-perform a fake doorbell. This patch adds code for doing this and enables
-it on BCM4708 family.
----
- drivers/usb/host/xhci-plat.c | 6 +++++
- drivers/usb/host/xhci.c | 63 +++++++++++++++++++++++++++++++++++++++++---
- drivers/usb/host/xhci.h | 1 +
- 3 files changed, 67 insertions(+), 3 deletions(-)
-
---- a/drivers/usb/host/xhci-plat.c
-+++ b/drivers/usb/host/xhci-plat.c
-@@ -77,6 +77,8 @@ static int xhci_priv_resume_quirk(struct
- static void xhci_plat_quirks(struct device *dev, struct xhci_hcd *xhci)
- {
- struct xhci_plat_priv *priv = xhci_to_priv(xhci);
-+ struct platform_device*pdev = to_platform_device(dev);
-+ struct device_node *node = pdev->dev.of_node;
-
- /*
- * As of now platform drivers don't provide MSI support so we ensure
-@@ -84,6 +86,9 @@ static void xhci_plat_quirks(struct devi
- * dev struct in order to setup MSI
- */
- xhci->quirks |= XHCI_PLAT | priv->quirks;
-+
-+ if (node && of_machine_is_compatible("brcm,bcm4708"))
-+ xhci->quirks |= XHCI_FAKE_DOORBELL;
- }
-
- /* called during probe() after chip reset completes */
---- a/drivers/usb/host/xhci.c
-+++ b/drivers/usb/host/xhci.c
-@@ -161,6 +161,49 @@ int xhci_start(struct xhci_hcd *xhci)
- return ret;
- }
-
-+/**
-+ * xhci_fake_doorbell - Perform a fake doorbell on a specified slot
-+ *
-+ * Some controllers require a fake doorbell to start correctly. Without that
-+ * they simply don't detect any devices.
-+ */
-+static int xhci_fake_doorbell(struct xhci_hcd *xhci, int slot_id)
-+{
-+ u32 temp;
-+
-+ /* Alloc a virt device for that slot */
-+ if (!xhci_alloc_virt_device(xhci, slot_id, NULL, GFP_NOIO)) {
-+ xhci_warn(xhci, "Could not allocate xHCI USB device data structures\n");
-+ return -ENOMEM;
-+ }
-+
-+ /* Ring fake doorbell for slot_id ep 0 */
-+ xhci_ring_ep_doorbell(xhci, slot_id, 0, 0);
-+ usleep_range(1000, 1500);
-+
-+ /* Read the status to check if HSE is set or not */
-+ temp = readl(&xhci->op_regs->status);
-+
-+ /* Clear HSE if set */
-+ if (temp & STS_FATAL) {
-+ xhci_dbg(xhci, "HSE problem detected, status: 0x%08x\n", temp);
-+ temp &= ~0x1fff;
-+ temp |= STS_FATAL;
-+ writel(temp, &xhci->op_regs->status);
-+ usleep_range(1000, 1500);
-+ readl(&xhci->op_regs->status);
-+ }
-+
-+ /* Free virt device */
-+ xhci_free_virt_device(xhci, slot_id);
-+
-+ /* We're done if controller is already running */
-+ if (readl(&xhci->op_regs->command) & CMD_RUN)
-+ return 0;
-+
-+ return xhci_start(xhci);
-+}
-+
- /*
- * Reset a halted HC.
- *
-@@ -641,6 +684,15 @@ static int xhci_run_finished(struct xhci
- return -ENODEV;
- }
-
-+ if (xhci->quirks & XHCI_FAKE_DOORBELL) {
-+ int err = xhci_fake_doorbell(xhci, 1);
-+ if (err) {
-+ xhci_halt(xhci);
-+ spin_unlock_irqrestore(&xhci->lock, flags);
-+ return err;
-+ }
-+ }
-+
- xhci->cmd_ring_state = CMD_RING_STATE_RUNNING;
-
- if (xhci->quirks & XHCI_NEC_HOST)
---- a/drivers/usb/host/xhci.h
-+++ b/drivers/usb/host/xhci.h
-@@ -1908,6 +1908,7 @@ struct xhci_hcd {
- #define XHCI_RESET_TO_DEFAULT BIT_ULL(44)
- #define XHCI_ZHAOXIN_TRB_FETCH BIT_ULL(45)
- #define XHCI_ZHAOXIN_HOST BIT_ULL(46)
-+#define XHCI_FAKE_DOORBELL BIT_ULL(47)
-
- unsigned int num_active_eps;
- unsigned int limit_active_eps;
diff --git a/target/linux/bcm53xx/patches-6.1/300-ARM-BCM5301X-Disable-MMU-and-Dcache-during-decompres.patch b/target/linux/bcm53xx/patches-6.1/300-ARM-BCM5301X-Disable-MMU-and-Dcache-during-decompres.patch
deleted file mode 100644
index 034d5b52fc..0000000000
--- a/target/linux/bcm53xx/patches-6.1/300-ARM-BCM5301X-Disable-MMU-and-Dcache-during-decompres.patch
+++ /dev/null
@@ -1,101 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Wed, 24 Sep 2014 22:14:07 +0200
-Subject: [PATCH] ARM: BCM5301X: Disable MMU and Dcache during decompression
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Broadcom devices have broken CFE (bootloader) that leaves hardware in an
-invalid state. It causes problems with booting Linux. On Northstar
-devices kernel was randomly hanging in ~25% of tries during early init.
-Hangs used to happen at random places in the start_kernel. On BCM53573
-kernel doesn't even seem to start booting.
-
-To workaround this problem we need to do following very early:
-1) Clear 2 following bits in the SCTLR register:
-#define CR_M (1 << 0) /* MMU enable */
-#define CR_C (1 << 2) /* Dcache enable */
-2) Flush the whole D-cache
-3) Disable L2 cache
-
-Unfortunately this patch is not upstreamable as it does above things
-unconditionally. We can't check if we are running on Broadcom platform
-in any safe way and doing such hacks with ARCH_MULTI_V7 is unacceptable
-as it could break other devices support.
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
----
-
---- a/arch/arm/boot/compressed/Makefile
-+++ b/arch/arm/boot/compressed/Makefile
-@@ -35,6 +35,11 @@ ifeq ($(CONFIG_ARCH_ACORN),y)
- OBJS += ll_char_wr.o font.o
- endif
-
-+ifeq ($(CONFIG_ARCH_BCM_5301X),y)
-+OBJS += head-bcm_5301x-mpcore.o
-+OBJS += cache-v7-min.o
-+endif
-+
- ifeq ($(CONFIG_ARCH_SA1100),y)
- OBJS += head-sa1100.o
- endif
---- /dev/null
-+++ b/arch/arm/boot/compressed/head-bcm_5301x-mpcore.S
-@@ -0,0 +1,37 @@
-+/*
-+ *
-+ * Platform specific tweaks. This is merged into head.S by the linker.
-+ *
-+ */
-+
-+#include <linux/linkage.h>
-+#include <asm/assembler.h>
-+#include <asm/cp15.h>
-+
-+ .section ".start", "ax"
-+
-+/*
-+ * This code section is spliced into the head code by the linker
-+ */
-+
-+__plat_uncompress_start:
-+
-+ @ Preserve r8/r7 i.e. kernel entry values
-+ mov r12, r8
-+
-+ @ Clear MMU enable and Dcache enable bits
-+ mrc p15, 0, r0, c1, c0, 0 @ Read SCTLR
-+ bic r0, #CR_C|CR_M
-+ mcr p15, 0, r0, c1, c0, 0 @ Write SCTLR
-+ nop
-+
-+ @ Call the cache invalidation routine
-+ bl v7_flush_dcache_all
-+ nop
-+ mov r0,#0
-+ ldr r3, =0x19022000 @ L2 cache controller, control reg
-+ str r0, [r3, #0x100] @ Disable L2 cache
-+ nop
-+
-+ @ Restore
-+ mov r8, r12
---- a/arch/arm/boot/compressed/cache-v7-min.S
-+++ b/arch/arm/boot/compressed/cache-v7-min.S
-@@ -12,6 +12,7 @@
-
- #include <linux/linkage.h>
- #include <linux/init.h>
-+#include <asm/assembler.h>
-
- __INIT
-
-@@ -63,7 +64,7 @@ loop2:
- ARM( orr r11, r11, r9, lsl r2 ) @ factor index number into r11
- THUMB( lsl r6, r9, r2 )
- THUMB( orr r11, r11, r6 ) @ factor index number into r11
-- mcr p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way
-+ mcr p15, 0, r11, c7, c6, 2 @ clean & invalidate by set/way
- subs r9, r9, #1 @ decrement the index
- bge loop2
- subs r4, r4, #1 @ decrement the way
diff --git a/target/linux/bcm53xx/patches-6.1/304-ARM-dts-BCM5301X-Specify-switch-ports-for-remaining-.patch b/target/linux/bcm53xx/patches-6.1/304-ARM-dts-BCM5301X-Specify-switch-ports-for-remaining-.patch
deleted file mode 100644
index 8039831a78..0000000000
--- a/target/linux/bcm53xx/patches-6.1/304-ARM-dts-BCM5301X-Specify-switch-ports-for-remaining-.patch
+++ /dev/null
@@ -1,675 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Subject: [PATCH] ARM: dts: BCM5301X: Specify switch ports for remaining
- devices
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
----
-
---- a/arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dts
-+++ b/arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dts
-@@ -92,3 +92,41 @@
- &usb3_phy {
- status = "okay";
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "lan1";
-+ };
-+
-+ port@1 {
-+ label = "lan2";
-+ };
-+
-+ port@2 {
-+ label = "lan3";
-+ };
-+
-+ port@3 {
-+ label = "lan4";
-+ };
-+
-+ port@4 {
-+ label = "wan";
-+ };
-+
-+ port@5 {
-+ label = "cpu";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm4708-asus-rt-ac68u.dts
-+++ b/arch/arm/boot/dts/bcm4708-asus-rt-ac68u.dts
-@@ -83,3 +83,41 @@
- &usb3_phy {
- status = "okay";
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "wan";
-+ };
-+
-+ port@1 {
-+ label = "lan1";
-+ };
-+
-+ port@2 {
-+ label = "lan2";
-+ };
-+
-+ port@3 {
-+ label = "lan3";
-+ };
-+
-+ port@4 {
-+ label = "lan4";
-+ };
-+
-+ port@5 {
-+ label = "cpu";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts
-+++ b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts
-@@ -149,3 +149,41 @@
- &usb3_phy {
- status = "okay";
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "lan1";
-+ };
-+
-+ port@1 {
-+ label = "lan2";
-+ };
-+
-+ port@2 {
-+ label = "lan3";
-+ };
-+
-+ port@3 {
-+ label = "lan4";
-+ };
-+
-+ port@4 {
-+ label = "wan";
-+ };
-+
-+ port@5 {
-+ label = "cpu";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm4708-linksys-ea6300-v1.dts
-+++ b/arch/arm/boot/dts/bcm4708-linksys-ea6300-v1.dts
-@@ -46,3 +46,41 @@
- &usb3_phy {
- status = "okay";
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "lan1";
-+ };
-+
-+ port@1 {
-+ label = "lan2";
-+ };
-+
-+ port@2 {
-+ label = "lan3";
-+ };
-+
-+ port@3 {
-+ label = "lan4";
-+ };
-+
-+ port@4 {
-+ label = "wan";
-+ };
-+
-+ port@5 {
-+ label = "cpu";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm4708-linksys-ea6500-v2.dts
-+++ b/arch/arm/boot/dts/bcm4708-linksys-ea6500-v2.dts
-@@ -43,3 +43,41 @@
- &usb3_phy {
- status = "okay";
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "lan1";
-+ };
-+
-+ port@1 {
-+ label = "lan2";
-+ };
-+
-+ port@2 {
-+ label = "lan3";
-+ };
-+
-+ port@3 {
-+ label = "lan4";
-+ };
-+
-+ port@4 {
-+ label = "wan";
-+ };
-+
-+ port@5 {
-+ label = "cpu";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts
-+++ b/arch/arm/boot/dts/bcm4708-netgear-r6300-v2.dts
-@@ -86,3 +86,41 @@
- &usb3_phy {
- status = "okay";
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "lan1";
-+ };
-+
-+ port@1 {
-+ label = "lan2";
-+ };
-+
-+ port@2 {
-+ label = "lan3";
-+ };
-+
-+ port@3 {
-+ label = "lan4";
-+ };
-+
-+ port@4 {
-+ label = "wan";
-+ };
-+
-+ port@5 {
-+ label = "cpu";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts
-+++ b/arch/arm/boot/dts/bcm47081-asus-rt-n18u.dts
-@@ -77,3 +77,41 @@
- &usb3_phy {
- status = "okay";
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "wan";
-+ };
-+
-+ port@1 {
-+ label = "lan1";
-+ };
-+
-+ port@2 {
-+ label = "lan2";
-+ };
-+
-+ port@3 {
-+ label = "lan3";
-+ };
-+
-+ port@4 {
-+ label = "lan4";
-+ };
-+
-+ port@5 {
-+ label = "cpu";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts
-+++ b/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts
-@@ -77,6 +77,40 @@
- status = "okay";
- };
-
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "wan";
-+ };
-+
-+ port@1 {
-+ label = "lan1";
-+ };
-+
-+ port@2 {
-+ label = "lan2";
-+ };
-+
-+ port@3 {
-+ label = "lan3";
-+ };
-+
-+ port@5 {
-+ status = "disabled";
-+ };
-+
-+ port@7 {
-+ label = "cpu";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
-+ };
-+};
-+
- &nandcs {
- partitions {
- compatible = "fixed-partitions";
---- a/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts
-+++ b/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts
-@@ -130,3 +130,41 @@
- &usb3_phy {
- status = "okay";
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "lan1";
-+ };
-+
-+ port@1 {
-+ label = "lan2";
-+ };
-+
-+ port@2 {
-+ label = "lan3";
-+ };
-+
-+ port@3 {
-+ label = "lan4";
-+ };
-+
-+ port@4 {
-+ label = "wan";
-+ };
-+
-+ port@5 {
-+ label = "cpu";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm4709-netgear-r7000.dts
-+++ b/arch/arm/boot/dts/bcm4709-netgear-r7000.dts
-@@ -104,3 +104,41 @@
- &usb3_phy {
- status = "okay";
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "wan";
-+ };
-+
-+ port@1 {
-+ label = "lan1";
-+ };
-+
-+ port@2 {
-+ label = "lan2";
-+ };
-+
-+ port@3 {
-+ label = "lan3";
-+ };
-+
-+ port@4 {
-+ label = "lan4";
-+ };
-+
-+ port@5 {
-+ label = "cpu";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm47094-netgear-r8500.dts
-+++ b/arch/arm/boot/dts/bcm47094-netgear-r8500.dts
-@@ -94,3 +94,41 @@
- &usb3_phy {
- status = "okay";
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "wan";
-+ };
-+
-+ port@1 {
-+ label = "lan1";
-+ };
-+
-+ port@2 {
-+ label = "lan2";
-+ };
-+
-+ port@3 {
-+ label = "lan3";
-+ };
-+
-+ port@4 {
-+ label = "lan4";
-+ };
-+
-+ port@5 {
-+ status = "disabled";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ label = "cpu";
-+ };
-+ };
-+};
---- a/arch/arm/boot/dts/bcm47094-phicomm-k3.dts
-+++ b/arch/arm/boot/dts/bcm47094-phicomm-k3.dts
-@@ -38,6 +38,40 @@
- status = "okay";
- };
-
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "lan1";
-+ };
-+
-+ port@1 {
-+ label = "lan2";
-+ };
-+
-+ port@2 {
-+ label = "lan3";
-+ };
-+
-+ port@3 {
-+ label = "wan";
-+ };
-+
-+ port@5 {
-+ label = "cpu";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
-+ };
-+};
-+
- &nandcs {
- partitions {
- compatible = "fixed-partitions";
---- a/arch/arm/boot/dts/bcm47081-tplink-archer-c5-v2.dts
-+++ b/arch/arm/boot/dts/bcm47081-tplink-archer-c5-v2.dts
-@@ -91,6 +91,44 @@
- };
- };
-
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "wan";
-+ };
-+
-+ port@1 {
-+ label = "lan1";
-+ };
-+
-+ port@2 {
-+ label = "lan2";
-+ };
-+
-+ port@3 {
-+ label = "lan3";
-+ };
-+
-+ port@4 {
-+ label = "lan4";
-+ };
-+
-+ port@5 {
-+ label = "cpu";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
-+ };
-+};
-+
- &spi_nor {
- status = "okay";
-
---- a/arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts
-+++ b/arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts
-@@ -100,6 +100,44 @@
- vcc-gpio = <&chipcommon 12 GPIO_ACTIVE_HIGH>;
- };
-
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "wan";
-+ };
-+
-+ port@1 {
-+ label = "lan1";
-+ };
-+
-+ port@2 {
-+ label = "lan2";
-+ };
-+
-+ port@3 {
-+ label = "lan3";
-+ };
-+
-+ port@4 {
-+ label = "lan4";
-+ };
-+
-+ port@5 {
-+ label = "cpu";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
-+ };
-+};
-+
- &spi_nor {
- status = "okay";
-
---- a/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts
-+++ b/arch/arm/boot/dts/bcm47081-buffalo-wzr-900dhp.dts
-@@ -107,3 +107,42 @@
- &usb3_phy {
- status = "okay";
- };
-+
-+&srab {
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ label = "lan1";
-+ };
-+
-+ port@1 {
-+ label = "lan2";
-+ };
-+
-+ port@2 {
-+ label = "lan3";
-+ };
-+
-+ port@3 {
-+ label = "lan4";
-+ };
-+
-+ port@4 {
-+ label = "wan";
-+ };
-+
-+ port@5 {
-+ label = "cpu";
-+ };
-+
-+ port@7 {
-+ status = "disabled";
-+ };
-+
-+ port@8 {
-+ status = "disabled";
-+ };
-+ };
-+};
-+
diff --git a/target/linux/bcm53xx/patches-6.1/310-ARM-BCM5301X-Add-DT-for-Netgear-R7900.patch b/target/linux/bcm53xx/patches-6.1/310-ARM-BCM5301X-Add-DT-for-Netgear-R7900.patch
deleted file mode 100644
index 773c3e9be6..0000000000
--- a/target/linux/bcm53xx/patches-6.1/310-ARM-BCM5301X-Add-DT-for-Netgear-R7900.patch
+++ /dev/null
@@ -1,64 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
-Subject: [PATCH] ARM: BCM5301X: Add DT for Netgear R7900
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
----
-
---- a/arch/arm/boot/dts/Makefile
-+++ b/arch/arm/boot/dts/Makefile
-@@ -125,6 +125,7 @@ dtb-$(CONFIG_ARCH_BCM_5301X) += \
- bcm4709-buffalo-wxr-1900dhp.dtb \
- bcm4709-linksys-ea9200.dtb \
- bcm4709-netgear-r7000.dtb \
-+ bcm4709-netgear-r7900.dtb \
- bcm4709-netgear-r8000.dtb \
- bcm4709-tplink-archer-c9-v1.dtb \
- bcm47094-asus-rt-ac3100.dtb \
---- /dev/null
-+++ b/arch/arm/boot/dts/bcm4709-netgear-r7900.dts
-@@ -0,0 +1,42 @@
-+/*
-+ * Broadcom BCM470X / BCM5301X ARM platform code.
-+ * DTS for Netgear R7900
-+ *
-+ * Copyright (C) 2016 Rafał Miłecki <zajec5@gmail.com>
-+ *
-+ * Licensed under the GNU/GPL. See COPYING for details.
-+ */
-+
-+/dts-v1/;
-+
-+#include "bcm4709.dtsi"
-+#include "bcm5301x-nand-cs0-bch8.dtsi"
-+
-+/ {
-+ compatible = "netgear,r7900", "brcm,bcm4709", "brcm,bcm4708";
-+ model = "Netgear R7900";
-+
-+ chosen {
-+ bootargs = "console=ttyS0,115200";
-+ };
-+
-+ memory {
-+ reg = <0x00000000 0x08000000
-+ 0x88000000 0x08000000>;
-+ };
-+
-+ axi@18000000 {
-+ usb3@23000 {
-+ reg = <0x00023000 0x1000>;
-+
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ vcc-gpio = <&chipcommon 0 GPIO_ACTIVE_HIGH>;
-+ };
-+ };
-+};
-+
-+&uart0 {
-+ status = "okay";
-+};
diff --git a/target/linux/bcm53xx/patches-6.1/500-UBI-Detect-EOF-mark-and-erase-all-remaining-blocks.patch b/target/linux/bcm53xx/patches-6.1/500-UBI-Detect-EOF-mark-and-erase-all-remaining-blocks.patch
deleted file mode 100644
index e6140d9a70..0000000000
--- a/target/linux/bcm53xx/patches-6.1/500-UBI-Detect-EOF-mark-and-erase-all-remaining-blocks.patch
+++ /dev/null
@@ -1,59 +0,0 @@
-From 2a2af518266a29323cf30c3f9ba9ef2ceb1dd84b Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
-Date: Thu, 16 Oct 2014 20:52:16 +0200
-Subject: [PATCH] UBI: Detect EOF mark and erase all remaining blocks
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
----
- drivers/mtd/ubi/attach.c | 5 +++++
- drivers/mtd/ubi/io.c | 4 ++++
- drivers/mtd/ubi/ubi.h | 1 +
- 3 files changed, 10 insertions(+)
-
---- a/drivers/mtd/ubi/attach.c
-+++ b/drivers/mtd/ubi/attach.c
-@@ -82,6 +82,9 @@ static int self_check_ai(struct ubi_devi
- #define AV_ADD BIT(1)
- #define AV_FIND_OR_ADD (AV_FIND | AV_ADD)
-
-+/* Set on finding block with 0xdeadc0de, indicates erasing all blocks behind */
-+bool erase_all_next;
-+
- /**
- * find_or_add_av - internal function to find a volume, add a volume or do
- * both (find and add if missing).
-@@ -1580,6 +1583,8 @@ int ubi_attach(struct ubi_device *ubi, i
- if (!ai)
- return -ENOMEM;
-
-+ erase_all_next = false;
-+
- #ifdef CONFIG_MTD_UBI_FASTMAP
- /* On small flash devices we disable fastmap in any case. */
- if ((int)mtd_div_by_eb(ubi->mtd->size, ubi->mtd) <= UBI_FM_MAX_START) {
---- a/drivers/mtd/ubi/io.c
-+++ b/drivers/mtd/ubi/io.c
-@@ -717,6 +717,10 @@ int ubi_io_read_ec_hdr(struct ubi_device
- }
-
- magic = be32_to_cpu(ec_hdr->magic);
-+ if (magic == 0xdeadc0de)
-+ erase_all_next = true;
-+ if (erase_all_next)
-+ return read_err ? UBI_IO_FF_BITFLIPS : UBI_IO_FF;
- if (magic != UBI_EC_HDR_MAGIC) {
- if (mtd_is_eccerr(read_err))
- return UBI_IO_BAD_HDR_EBADMSG;
---- a/drivers/mtd/ubi/ubi.h
-+++ b/drivers/mtd/ubi/ubi.h
-@@ -822,6 +822,7 @@ extern struct mutex ubi_devices_mutex;
- extern struct blocking_notifier_head ubi_notifiers;
-
- /* attach.c */
-+extern bool erase_all_next;
- struct ubi_ainf_peb *ubi_alloc_aeb(struct ubi_attach_info *ai, int pnum,
- int ec);
- void ubi_free_aeb(struct ubi_attach_info *ai, struct ubi_ainf_peb *aeb);
diff --git a/target/linux/bcm53xx/patches-6.1/600-net-disable-GRO-by-default.patch b/target/linux/bcm53xx/patches-6.1/600-net-disable-GRO-by-default.patch
deleted file mode 100644
index 9fa41a4b7e..0000000000
--- a/target/linux/bcm53xx/patches-6.1/600-net-disable-GRO-by-default.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Mon, 20 Jun 2022 10:01:18 +0200
-Subject: [PATCH] net: disable GRO by default
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-In many cases GRO improves network performance however it comes at a
-cost of chacksums calculations. In case of slow CPU and missing hardware
-csum calculation support GRO can actually decrease network speed.
-
-On BCM4708 *disabling* GRO results in following NAT masquarade speed
-changes:
-1. 364 Mb/s → 396 Mb/s (packet steering disabled)
-2. 341 Mb/s → 566 Mb/s (packet steering enabled)
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
----
- include/linux/netdev_features.h | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/include/linux/netdev_features.h
-+++ b/include/linux/netdev_features.h
-@@ -242,10 +242,10 @@ static inline int find_next_netdev_featu
- #define NETIF_F_UPPER_DISABLES NETIF_F_LRO
-
- /* changeable features with no special hardware requirements */
--#define NETIF_F_SOFT_FEATURES (NETIF_F_GSO | NETIF_F_GRO | NETIF_F_GRO_FRAGLIST)
-+#define NETIF_F_SOFT_FEATURES (NETIF_F_GSO)
-
- /* Changeable features with no special hardware requirements that defaults to off. */
--#define NETIF_F_SOFT_FEATURES_OFF (NETIF_F_GRO_UDP_FWD)
-+#define NETIF_F_SOFT_FEATURES_OFF (NETIF_F_GRO_UDP_FWD | NETIF_F_GRO | NETIF_F_GRO_FRAGLIST)
-
- #define NETIF_F_VLAN_FEATURES (NETIF_F_HW_VLAN_CTAG_FILTER | \
- NETIF_F_HW_VLAN_CTAG_RX | \
diff --git a/target/linux/bcm53xx/patches-6.1/700-bgmac-reduce-max-frame-size-to-support-just-MTU-1500.patch b/target/linux/bcm53xx/patches-6.1/700-bgmac-reduce-max-frame-size-to-support-just-MTU-1500.patch
deleted file mode 100644
index 3a2f4b06ed..0000000000
--- a/target/linux/bcm53xx/patches-6.1/700-bgmac-reduce-max-frame-size-to-support-just-MTU-1500.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Fri, 10 Jun 2022 13:10:47 +0200
-Subject: [PATCH] bgmac: reduce max frame size to support just MTU 1500
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-bgmac allocates new replacement buffer before handling each received
-frame. Allocating & DMA-preparing 9724 B each time consumes a lot of CPU
-time. Ideally bgmac should just respect currently set MTU but it isn't
-the case right now. For now just revert back to the old limited frame
-size.
-
-This change bumps NAT masquarade speed by ~95%.
-
-Ref: 8c7da63978f1 ("bgmac: configure MTU and add support for frames beyond 8192 byte size")
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
----
- drivers/net/ethernet/broadcom/bgmac.h | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
---- a/drivers/net/ethernet/broadcom/bgmac.h
-+++ b/drivers/net/ethernet/broadcom/bgmac.h
-@@ -328,8 +328,7 @@
- #define BGMAC_RX_FRAME_OFFSET 30 /* There are 2 unused bytes between header and real data */
- #define BGMAC_RX_BUF_OFFSET (NET_SKB_PAD + NET_IP_ALIGN - \
- BGMAC_RX_FRAME_OFFSET)
--/* Jumbo frame size with FCS */
--#define BGMAC_RX_MAX_FRAME_SIZE 9724
-+#define BGMAC_RX_MAX_FRAME_SIZE 1536
- #define BGMAC_RX_BUF_SIZE (BGMAC_RX_FRAME_OFFSET + BGMAC_RX_MAX_FRAME_SIZE)
- #define BGMAC_RX_ALLOC_SIZE (SKB_DATA_ALIGN(BGMAC_RX_BUF_SIZE + BGMAC_RX_BUF_OFFSET) + \
- SKB_DATA_ALIGN(sizeof(struct skb_shared_info)))
diff --git a/target/linux/bcm53xx/patches-6.1/905-BCM53573-minor-hacks.patch b/target/linux/bcm53xx/patches-6.1/905-BCM53573-minor-hacks.patch
deleted file mode 100644
index 0a52ca98ee..0000000000
--- a/target/linux/bcm53xx/patches-6.1/905-BCM53573-minor-hacks.patch
+++ /dev/null
@@ -1,80 +0,0 @@
-From 6f1c62440eb6846cb8045d7a5480ec7bbe47c96f Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
-Date: Mon, 15 Aug 2016 10:30:41 +0200
-Subject: [PATCH] BCM53573 minor hacks
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
----
-
---- a/arch/arm/boot/dts/bcm53573.dtsi
-+++ b/arch/arm/boot/dts/bcm53573.dtsi
-@@ -54,6 +54,7 @@
- <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
- <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
- <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
-+ clocks = <&ilp>;
- };
-
- clocks {
---- a/drivers/bcma/main.c
-+++ b/drivers/bcma/main.c
-@@ -330,14 +330,6 @@ static int bcma_register_devices(struct
- }
- #endif
-
--#ifdef CONFIG_BCMA_SFLASH
-- if (bus->drv_cc.sflash.present) {
-- err = platform_device_register(&bcma_sflash_dev);
-- if (err)
-- bcma_err(bus, "Error registering serial flash\n");
-- }
--#endif
--
- #ifdef CONFIG_BCMA_NFLASH
- if (bus->drv_cc.nflash.present) {
- err = platform_device_register(&bcma_nflash_dev);
-@@ -415,6 +407,14 @@ int bcma_bus_register(struct bcma_bus *b
- bcma_register_core(bus, core);
- }
-
-+#ifdef CONFIG_BCMA_SFLASH
-+ if (bus->drv_cc.sflash.present) {
-+ err = platform_device_register(&bcma_sflash_dev);
-+ if (err)
-+ bcma_err(bus, "Error registering serial flash\n");
-+ }
-+#endif
-+
- /* Try to get SPROM */
- err = bcma_sprom_get(bus);
- if (err == -ENOENT) {
---- a/drivers/clocksource/arm_arch_timer.c
-+++ b/drivers/clocksource/arm_arch_timer.c
-@@ -14,6 +14,7 @@
- #include <linux/smp.h>
- #include <linux/cpu.h>
- #include <linux/cpu_pm.h>
-+#include <linux/clk.h>
- #include <linux/clockchips.h>
- #include <linux/clocksource.h>
- #include <linux/clocksource_ids.h>
-@@ -1029,6 +1030,16 @@ static void __init arch_timer_of_configu
- if (of_property_read_u32(np, "clock-frequency", &arch_timer_rate))
- arch_timer_rate = rate;
-
-+ /* Get clk rate through clk driver if present */
-+ if (!arch_timer_rate) {
-+ struct clk *clk = of_clk_get(np, 0);
-+
-+ if (!IS_ERR(clk)) {
-+ if (!clk_prepare_enable(clk))
-+ arch_timer_rate = clk_get_rate(clk);
-+ }
-+ }
-+
- /* Check the timer frequency. */
- if (validate_timer_rate())
- pr_warn("frequency not available\n");
diff --git a/target/linux/bcm53xx/patches-6.6/600-net-disable-GRO-by-default.patch b/target/linux/bcm53xx/patches-6.6/600-net-disable-GRO-by-default.patch
index 9fa41a4b7e..fd41824383 100644
--- a/target/linux/bcm53xx/patches-6.6/600-net-disable-GRO-by-default.patch
+++ b/target/linux/bcm53xx/patches-6.6/600-net-disable-GRO-by-default.patch
@@ -21,7 +21,7 @@ Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
--- a/include/linux/netdev_features.h
+++ b/include/linux/netdev_features.h
-@@ -242,10 +242,10 @@ static inline int find_next_netdev_featu
+@@ -243,10 +243,10 @@ static inline int find_next_netdev_featu
#define NETIF_F_UPPER_DISABLES NETIF_F_LRO
/* changeable features with no special hardware requirements */
diff --git a/target/linux/bmips/bcm6318/base-files/etc/board.d/01_leds b/target/linux/bmips/bcm6318/base-files/etc/board.d/01_leds
index 98355460a0..059a4f415a 100644
--- a/target/linux/bmips/bcm6318/base-files/etc/board.d/01_leds
+++ b/target/linux/bmips/bcm6318/base-files/etc/board.d/01_leds
@@ -6,7 +6,8 @@
board_config_update
case "$(board_name)" in
-comtrend,ar-5315u)
+comtrend,ar-5315u |\
+tp-link,td-w8968-v3)
ucidef_set_led_usbport "usb" "USB" "green:usb" "usb1-port1" "usb2-port1"
;;
esac
diff --git a/target/linux/bmips/bcm6318/base-files/etc/board.d/02_network b/target/linux/bmips/bcm6318/base-files/etc/board.d/02_network
index 92b2e8f4d4..b821f6a545 100644
--- a/target/linux/bmips/bcm6318/base-files/etc/board.d/02_network
+++ b/target/linux/bmips/bcm6318/base-files/etc/board.d/02_network
@@ -5,7 +5,8 @@
board_config_update
case "$(board_name)" in
-comtrend,ar-5315u)
+comtrend,ar-5315u |\
+tp-link,td-w8968-v3)
ucidef_set_bridge_device switch
ucidef_set_interface_lan "lan1 lan2 lan3 lan4"
;;
diff --git a/target/linux/bmips/bcm6318/base-files/etc/uci-defaults/09_fix_crc b/target/linux/bmips/bcm6318/base-files/etc/uci-defaults/09_fix_crc
index a52f0ecc40..df09e1d249 100644
--- a/target/linux/bmips/bcm6318/base-files/etc/uci-defaults/09_fix_crc
+++ b/target/linux/bmips/bcm6318/base-files/etc/uci-defaults/09_fix_crc
@@ -3,7 +3,8 @@
. /lib/functions.sh
case "$(board_name)" in
-comtrend,ar-5315u)
+comtrend,ar-5315u) |\
+tp-link,td-w8968-v3)
mtd fixtrx firmware
;;
esac
diff --git a/target/linux/bmips/bcm6328/base-files/etc/board.d/01_leds b/target/linux/bmips/bcm6328/base-files/etc/board.d/01_leds
index b2ccc9a60e..3b9033a4d4 100644
--- a/target/linux/bmips/bcm6328/base-files/etc/board.d/01_leds
+++ b/target/linux/bmips/bcm6328/base-files/etc/board.d/01_leds
@@ -10,6 +10,7 @@ arcadyan,ar7516)
ucidef_set_led_netdev "wan" "WAN" "green:wan" "wan"
ucidef_set_led_netdev "wlan0" "WiFi" "green:wifi" "phy0-ap0"
;;
+inteno,xg6846 |\
nucom,r5010unv2 |\
sercomm,ad1018)
ucidef_set_led_usbport "usb" "USB" "green:usb" "usb1-port1" "usb2-port1"
diff --git a/target/linux/bmips/bcm6328/base-files/etc/board.d/02_network b/target/linux/bmips/bcm6328/base-files/etc/board.d/02_network
index 78c0794f23..e846182a9a 100644
--- a/target/linux/bmips/bcm6328/base-files/etc/board.d/02_network
+++ b/target/linux/bmips/bcm6328/base-files/etc/board.d/02_network
@@ -14,6 +14,7 @@ inteno,xg6846)
;;
comtrend,ar-5381u |\
comtrend,ar-5387un |\
+dlink,dsl-2750b-b1 |\
innacomm,w3400v6 |\
nucom,r5010unv2)
ucidef_set_bridge_device switch
diff --git a/target/linux/bmips/bcm6328/base-files/etc/uci-defaults/09_fix_crc b/target/linux/bmips/bcm6328/base-files/etc/uci-defaults/09_fix_crc
index e521af36ba..e442fa662c 100644
--- a/target/linux/bmips/bcm6328/base-files/etc/uci-defaults/09_fix_crc
+++ b/target/linux/bmips/bcm6328/base-files/etc/uci-defaults/09_fix_crc
@@ -6,6 +6,7 @@ case "$(board_name)" in
arcadyan,ar7516 |\
comtrend,ar-5381u |\
comtrend,ar-5387un |\
+dlink,dsl-2750b-b1 |\
nucom,r5010unv2)
mtd fixtrx firmware
;;
diff --git a/target/linux/bmips/dts/bcm6318-tp-link-td-w8968-v3.dts b/target/linux/bmips/dts/bcm6318-tp-link-td-w8968-v3.dts
new file mode 100644
index 0000000000..59b209daed
--- /dev/null
+++ b/target/linux/bmips/dts/bcm6318-tp-link-td-w8968-v3.dts
@@ -0,0 +1,253 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "bcm6318.dtsi"
+
+/ {
+ model = "TP-Link TD-W8968 V3";
+ compatible = "tp-link,td-w8968-v3", "brcm,bcm6318";
+
+ aliases {
+ led-boot = &led_power_green;
+ led-failsafe = &led_power_green;
+ led-running = &led_power_green;
+ led-upgrade = &led_power_green;
+ };
+
+ keys {
+ compatible = "gpio-keys-polled";
+ poll-interval = <100>;
+
+ wlan {
+ label = "wlan";
+ gpios = <&gpio 9 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_WLAN>;
+ debounce-interval = <60>;
+ };
+
+ wps {
+ label = "wps";
+ gpios = <&gpio 33 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_WPS_BUTTON>;
+ debounce-interval = <60>;
+ };
+
+ reset {
+ label = "reset";
+ gpios = <&gpio 34 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_RESTART>;
+ debounce-interval = <60>;
+ };
+ };
+
+ bcm43217-sprom {
+ compatible = "brcm,bcma-sprom";
+
+ pci-bus = <1>;
+ pci-dev = <0>;
+
+ nvmem-cells = <&macaddr_cfe_6a0 1>;
+ nvmem-cell-names = "mac-address";
+
+ brcm,sprom = "brcm/bcm43217-sprom.bin";
+ };
+};
+
+&ehci {
+ status = "okay";
+};
+
+&ethernet {
+ status = "okay";
+
+ nvmem-cells = <&macaddr_cfe_6a0 0>;
+ nvmem-cell-names = "mac-address";
+};
+
+&hsspi {
+ status = "okay";
+
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ spi-max-frequency = <62500000>;
+ spi-tx-bus-width = <2>;
+ spi-rx-bus-width = <2>;
+ reg = <0>;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ reg = <0x000000 0x010000>;
+ label = "cfe";
+ read-only;
+
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ macaddr_cfe_6a0: macaddr@6a0 {
+ compatible = "mac-base";
+ reg = <0x6a0 0x6>;
+ #nvmem-cell-cells = <1>;
+ };
+ };
+ };
+
+ partition@10000 {
+ compatible = "brcm,bcm963xx-imagetag";
+ reg = <0x010000 0x7e0000>;
+ label = "firmware";
+ };
+
+ partition@7f0000 {
+ reg = <0x7f0000 0x010000>;
+ label = "nvram";
+ };
+ };
+ };
+};
+
+&leds {
+ status = "okay";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_leds
+ &pinctrl_ephy0_act_led &pinctrl_ephy1_act_led
+ &pinctrl_ephy2_act_led &pinctrl_ephy3_act_led>;
+
+ led@2 {
+ reg = <2>;
+ active-low;
+ function = LED_FUNCTION_WPS;
+ color = <LED_COLOR_ID_GREEN>;
+ };
+
+ led_power_green: led@3 {
+ reg = <3>;
+ active-high;
+ function = LED_FUNCTION_POWER;
+ color = <LED_COLOR_ID_GREEN>;
+ };
+
+ led@4 {
+ /* EPHY0 Act */
+ reg = <4>;
+ brcm,hardware-controlled;
+ brcm,link-signal-sources = <4>;
+ };
+
+ led@5 {
+ /* EPHY1 Act */
+ reg = <5>;
+ brcm,hardware-controlled;
+ brcm,link-signal-sources = <5>;
+ };
+
+ led@6 {
+ /* EPHY2 Act */
+ reg = <6>;
+ brcm,hardware-controlled;
+ brcm,link-signal-sources = <6>;
+ };
+
+ led@7 {
+ /* EPHY3 Act */
+ reg = <7>;
+ brcm,hardware-controlled;
+ brcm,link-signal-sources = <7>;
+ };
+
+ led@8 {
+ reg = <8>;
+ active-low;
+ function = LED_FUNCTION_WAN_ONLINE;
+ color = <LED_COLOR_ID_GREEN>;
+ };
+
+ led@10 {
+ reg = <10>;
+ active-low;
+ label = "green:dsl";
+ };
+
+ led@13 {
+ reg = <13>;
+ active-low;
+ function = LED_FUNCTION_USB;
+ color = <LED_COLOR_ID_GREEN>;
+ };
+
+ led@16 {
+ reg = <16>;
+ active-low;
+ function = LED_FUNCTION_WLAN;
+ color = <LED_COLOR_ID_GREEN>;
+ };
+};
+
+&ohci {
+ status = "okay";
+};
+
+&pcie {
+ status = "okay";
+};
+
+&pinctrl {
+ pinctrl_leds: leds {
+ function = "led";
+ pins = "gpio2", "gpio3",
+ "gpio8", "gpio10",
+ "gpio13", "gpio16";
+ };
+};
+
+&switch0 {
+ ports {
+ port@0 {
+ reg = <0>;
+ label = "lan4";
+
+ phy-handle = <&phy1>;
+ phy-mode = "mii";
+ };
+
+ port@1 {
+ reg = <1>;
+ label = "lan3";
+
+ phy-handle = <&phy2>;
+ phy-mode = "mii";
+ };
+
+ port@2 {
+ reg = <2>;
+ label = "lan2";
+
+ phy-handle = <&phy3>;
+ phy-mode = "mii";
+ };
+
+ port@3 {
+ reg = <3>;
+ label = "lan1";
+
+ phy-handle = <&phy4>;
+ phy-mode = "mii";
+ };
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&usbh {
+ status = "okay";
+};
diff --git a/target/linux/bmips/dts/bcm6328-dlink-dsl-2750b-b1.dts b/target/linux/bmips/dts/bcm6328-dlink-dsl-2750b-b1.dts
new file mode 100644
index 0000000000..e4806c0a9a
--- /dev/null
+++ b/target/linux/bmips/dts/bcm6328-dlink-dsl-2750b-b1.dts
@@ -0,0 +1,273 @@
+#include "bcm6328.dtsi"
+
+/ {
+ model = "D-Link DSL-2750B rev B1/DSL-2740B rev F1/DSL-2741B rev F1";
+ compatible = "dlink,dsl-2750b-b1", "brcm,bcm6328";
+
+ aliases {
+ led-boot = &led_power_green;
+ led-failsafe = &led_power_red;
+ led-running = &led_power_green;
+ led-upgrade = &led_power_green;
+ };
+
+ keys {
+ compatible = "gpio-keys-polled";
+ poll-interval = <100>;
+
+ wifi {
+ label = "wifi";
+ gpios = <&gpio 10 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_WLAN>;
+ debounce-interval = <60>;
+ };
+
+ reset {
+ label = "reset";
+ gpios = <&gpio 23 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_RESTART>;
+ debounce-interval = <60>;
+ };
+
+ wps {
+ label = "wps";
+ gpios = <&gpio 24 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_WPS_BUTTON>;
+ debounce-interval = <60>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led-31 {
+ function = LED_FUNCTION_USB;
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&gpio 31 GPIO_ACTIVE_LOW>;
+ trigger-sources = <&ehci_port1>;
+ linux,default-trigger = "usbport";
+ };
+ };
+
+ ath9k-leds {
+ compatible = "gpio-leds";
+
+ led-8 {
+ function = LED_FUNCTION_WLAN;
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&ath9k 8 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "phy0tpt";
+ };
+ };
+};
+
+&leds {
+ status = "okay";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_leds>;
+
+ led@2 {
+ reg = <2>;
+ active-low;
+ label = "red:internet";
+ };
+
+ led@3 {
+ reg = <3>;
+ active-low;
+ label = "green:dsl";
+ };
+
+ led_power_green: led@4 {
+ reg = <4>;
+ active-low;
+ function = LED_FUNCTION_POWER;
+ color = <LED_COLOR_ID_GREEN>;
+ };
+
+ led_power_red: led@8 {
+ reg = <8>;
+ active-low;
+ function = LED_FUNCTION_POWER;
+ color = <LED_COLOR_ID_RED>;
+ panic-indicator;
+ };
+
+ led@9 {
+ reg = <9>;
+ active-low;
+ function = LED_FUNCTION_WPS;
+ color = <LED_COLOR_ID_BLUE>;
+ };
+
+ led@11 {
+ reg = <11>;
+ active-low;
+ label = "green:internet";
+ };
+};
+
+&ehci {
+ status = "okay";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ehci_port1: port@1 {
+ reg = <1>;
+ #trigger-source-cells = <0>;
+ };
+};
+
+&ethernet {
+ status = "okay";
+
+ nvmem-cells = <&macaddr_cfe_6a0 0>;
+ nvmem-cell-names = "mac-address";
+};
+
+&hsspi {
+ status = "okay";
+
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ spi-max-frequency = <16666667>;
+ spi-tx-bus-width = <2>;
+ spi-rx-bus-width = <2>;
+ reg = <0>;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ reg = <0x000000 0x010000>;
+ label = "cfe";
+ read-only;
+
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ macaddr_cfe_6a0: macaddr@6a0 {
+ compatible = "mac-base";
+ reg = <0x6a0 0x6>;
+ #nvmem-cell-cells = <1>;
+ };
+ };
+ };
+
+ partition@10000 {
+ reg = <0x010000 0x7c0000>;
+ label = "linux";
+ compatible = "brcm,bcm963xx-imagetag";
+ };
+
+ partition@7d0000 {
+ reg = <0x7d0000 0x010000>;
+ label = "cal_data";
+ read-only;
+
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ cal_data_1000: calibration@1000 {
+ reg = <0x1000 0x440>;
+ };
+ };
+ };
+
+ partition@7e0000 {
+ reg = <0x7e0000 0x020000>;
+ label = "nvram";
+ };
+ };
+ };
+};
+
+&ohci {
+ status = "okay";
+};
+
+&pcie {
+ status = "okay";
+
+ pcie@0 {
+ reg = <0 0 0 0 0>;
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+
+ ath9k: wifi@168c,002e {
+ compatible = "pci168c,002e";
+ reg = <0 0 0 0 0>;
+
+ nvmem-cells = <&macaddr_cfe_6a0 1>, <&cal_data_1000>;
+ nvmem-cell-names = "mac-address", "calibration";
+
+ #gpio-cells = <2>;
+ gpio-controller;
+ };
+ };
+};
+
+&pinctrl {
+ pinctrl_leds: leds {
+ function = "led";
+ pins = "gpio2", "gpio3", "gpio4",
+ "gpio8", "gpio9", "gpio11";
+ };
+};
+
+&switch0 {
+ ports {
+ port@0 {
+ reg = <0>;
+ label = "lan1";
+
+ phy-handle = <&phy1>;
+ phy-mode = "mii";
+ };
+
+ port@1 {
+ reg = <1>;
+ label = "lan2";
+
+ phy-handle = <&phy2>;
+ phy-mode = "mii";
+ };
+
+ port@2 {
+ reg = <2>;
+ label = "lan3";
+
+ phy-handle = <&phy3>;
+ phy-mode = "mii";
+ };
+
+ port@3 {
+ reg = <3>;
+ label = "lan4";
+
+ phy-handle = <&phy4>;
+ phy-mode = "mii";
+ };
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&usbh {
+ status = "okay";
+};
diff --git a/target/linux/bmips/dts/bcm6328-inteno-xg6846.dts b/target/linux/bmips/dts/bcm6328-inteno-xg6846.dts
index 72f85a53ca..91b771a2bd 100644
--- a/target/linux/bmips/dts/bcm6328-inteno-xg6846.dts
+++ b/target/linux/bmips/dts/bcm6328-inteno-xg6846.dts
@@ -1,5 +1,4 @@
// SPDX-License-Identifier: GPL-2.0
-/dts-v1/;
/*
* Devicetree for the Inteno XG6846 router, mostly used as a
@@ -16,26 +15,18 @@
* Some devices have a USB type A host receptacle mounted,
* some do not.
*/
+
#include "bcm6328.dtsi"
-#include <dt-bindings/input/input.h>
-#include <dt-bindings/gpio/gpio.h>
/ {
model = "Inteno XG6846";
compatible = "inteno,xg6846", "brcm,bcm6328";
- /* OpenWrt-specific aliases */
aliases {
- led-boot = &led_pwr_red;
- led-failsafe = &led_pwr_red;
- led-running = &led_pwr_green;
- led-upgrade = &led_pwr_red;
- led-usb = &led_usb_green;
- };
-
- chosen {
- bootargs = "rootfstype=squashfs,jffs2 noinitrd console=ttyS0,115200";
- stdout-path = "serial0:115200n8";
+ led-boot = &led_power_red;
+ led-failsafe = &led_power_red;
+ led-running = &led_power_green;
+ led-upgrade = &led_power_red;
};
/*
@@ -49,6 +40,12 @@
scl-gpios = <&gpio 19 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
#address-cells = <1>;
#size-cells = <0>;
+
+ sfp_eeprom: eeprom@50 {
+ compatible = "atmel,24c02";
+ reg = <0x50>;
+ read-only;
+ };
};
/* This I2C bus is used for the external CATV connector (usually unused) */
@@ -60,17 +57,9 @@
#size-cells = <0>;
};
- sfp0: sfp0 {
- compatible = "sff,sfp";
- i2c-bus = <&i2c0>;
- los-gpios = <&gpio 29 GPIO_ACTIVE_HIGH>;
- };
-
keys {
compatible = "gpio-keys-polled";
- #address-cells = <1>;
- #size-cells = <0>;
- poll-interval = <20>;
+ poll-interval = <100>;
reset {
label = "reset";
@@ -79,6 +68,12 @@
debounce-interval = <60>;
};
};
+
+ sfp0: sfp0 {
+ compatible = "sff,sfp";
+ i2c-bus = <&i2c0>;
+ los-gpios = <&gpio 29 GPIO_ACTIVE_HIGH>;
+ };
};
&hsspi {
@@ -110,10 +105,20 @@
#address-cells = <1>;
#size-cells = <1>;
- cfe: partition@0 {
+ partition@0 {
label = "cfe";
reg = <0x0000000 0x0010000>;
read-only;
+
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ macaddr_cfe_6a0: macaddr@6a0 {
+ reg = <0x6a0 0x6>;
+ };
+ };
};
partition@10000 {
@@ -131,14 +136,8 @@
};
};
-&cfe {
- compatible = "nvmem-cells";
- #address-cells = <1>;
- #size-cells = <1>;
-
- macaddr_cfe_6a0: macaddr@6a0 {
- reg = <0x6a0 0x6>;
- };
+&ehci {
+ status = "okay";
};
&ethernet {
@@ -148,20 +147,33 @@
nvmem-cell-names = "mac-address";
};
-&switch0 {
- dsa,member = <0 0>;
+&leds {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_leds>,
+ <&pinctrl_ephy1_spd_led>,
+ <&pinctrl_ephy3_spd_led>;
- ports {
- switch0port4: port@4 {
- reg = <4>;
- label = "extsw";
+ led@16 {
+ reg = <16>;
+ active-low;
+ function = LED_FUNCTION_USB;
+ color = <LED_COLOR_ID_GREEN>;
+ };
- phy-mode = "rgmii";
- fixed-link {
- speed = <1000>;
- full-duplex;
- };
- };
+ led_power_red: led@18 {
+ reg = <18>;
+ active-low;
+ function = LED_FUNCTION_POWER;
+ color = <LED_COLOR_ID_RED>;
+ panic-indicator;
+ };
+
+ led_power_green: led@20 {
+ reg = <20>;
+ active-low;
+ function = LED_FUNCTION_POWER;
+ color = <LED_COLOR_ID_GREEN>;
};
};
@@ -172,8 +184,10 @@
#address-cells = <1>;
#size-cells = <0>;
reg = <0>;
+
interrupt-controller;
#interrupt-cells = <2>;
+
dsa,member = <1 0>;
ports {
@@ -183,49 +197,165 @@
port@0 {
reg = <0>;
label = "lan1";
+
phy-handle = <&lan1phy>;
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@0 {
+ reg = <0>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_LAN;
+ default-state = "keep";
+ };
+
+ led@1 {
+ reg = <1>;
+ color = <LED_COLOR_ID_AMBER>;
+ function = LED_FUNCTION_LAN;
+ };
+ };
};
port@1 {
reg = <1>;
label = "lan2";
+
phy-handle = <&lan2phy>;
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@0 {
+ reg = <0>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_LAN;
+ default-state = "keep";
+ };
+
+ led@1 {
+ reg = <1>;
+ color = <LED_COLOR_ID_AMBER>;
+ function = LED_FUNCTION_LAN;
+ };
+ };
};
port@2 {
reg = <2>;
label = "lan3";
+
phy-handle = <&lan3phy>;
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@0 {
+ reg = <0>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_LAN;
+ default-state = "keep";
+ };
+
+ led@1 {
+ reg = <1>;
+ color = <LED_COLOR_ID_AMBER>;
+ function = LED_FUNCTION_LAN;
+ };
+ };
};
port@3 {
reg = <3>;
label = "lan4";
+
phy-handle = <&lan4phy>;
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@0 {
+ reg = <0>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_LAN;
+ default-state = "keep";
+ };
+
+ led@1 {
+ reg = <1>;
+ color = <LED_COLOR_ID_AMBER>;
+ function = LED_FUNCTION_LAN;
+ };
+ };
};
port@4 {
reg = <4>;
label = "ext1";
+
phy-handle = <&ext1phy>;
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@0 {
+ reg = <0>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_WAN;
+ default-state = "keep";
+ };
+
+ led@1 {
+ reg = <1>;
+ color = <LED_COLOR_ID_AMBER>;
+ function = LED_FUNCTION_WAN;
+ };
+ };
};
port@5 {
reg = <5>;
- phy-mode = "rgmii-id";
label = "wan";
+
+ phy-mode = "rgmii-id";
sfp = <&sfp0>;
+
fixed-link {
speed = <1000>;
full-duplex;
};
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@0 {
+ reg = <0>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_WAN;
+ default-state = "keep";
+ };
+
+ led@1 {
+ reg = <1>;
+ color = <LED_COLOR_ID_AMBER>;
+ function = LED_FUNCTION_WAN;
+ };
+ };
};
port@6 {
reg = <6>;
+
phy-mode = "rgmii-id";
- label = "cpu";
ethernet = <&switch0port4>;
+
fixed-link {
speed = <1000>;
full-duplex;
@@ -242,21 +372,25 @@
interrupt-parent = <&switch1>;
interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
};
+
lan2phy: ethernet-phy@1 {
reg = <1>;
interrupt-parent = <&switch1>;
interrupts = <1 IRQ_TYPE_LEVEL_HIGH>;
};
+
lan3phy: ethernet-phy@2 {
reg = <2>;
interrupt-parent = <&switch1>;
interrupts = <2 IRQ_TYPE_LEVEL_HIGH>;
};
+
lan4phy: ethernet-phy@3 {
reg = <3>;
interrupt-parent = <&switch1>;
interrupts = <3 IRQ_TYPE_LEVEL_HIGH>;
};
+
ext1phy: ethernet-phy@4 {
reg = <4>;
interrupt-parent = <&switch1>;
@@ -266,48 +400,39 @@
};
};
-&uart0 {
+&ohci {
status = "okay";
};
&pinctrl {
- pinctrl_xg6846_usb_spd_led: xg6846_usb_spd_led-pins {
+ pinctrl_leds: leds {
function = "led";
- pins = "gpio17";
+ pins = "gpio16", "gpio18", "gpio20";
};
};
-&leds {
- status = "okay";
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_xg6846_usb_spd_led>, /* GPIO16 LED USB */
- <&pinctrl_ephy1_spd_led>, /* GPIO18 LED PWR red */
- <&pinctrl_ephy3_spd_led>; /* GPIO20 LED PWR green */
+&switch0 {
+ dsa,member = <0 0>;
- /* On board variants without USB this LED is not mounted */
- led_usb_green: led@16 {
- reg = <16>;
- active-low;
- label = "green:usb";
- default-state = "off";
- };
+ ports {
+ switch0port4: port@4 {
+ reg = <4>;
+ label = "extsw";
- /*
- * LED 18 and 20 drive the same physical LED, the PWR
- * LED that can be both red and green.
- */
- led_pwr_red: led@18 {
- reg = <18>;
- active-low;
- label = "red:pwr";
- default-state = "off";
- };
+ phy-mode = "rgmii";
- led_pwr_green: led@20 {
- reg = <20>;
- active-low;
- label = "green:pwr";
- default-state = "off";
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ };
+ };
};
+};
+
+&uart0 {
+ status = "okay";
+};
+&usbh {
+ status = "okay";
};
diff --git a/target/linux/bmips/dts/bcm6358-huawei-hg556a-b.dts b/target/linux/bmips/dts/bcm6358-huawei-hg556a-b.dts
index 6500d54e36..999f162fe4 100644
--- a/target/linux/bmips/dts/bcm6358-huawei-hg556a-b.dts
+++ b/target/linux/bmips/dts/bcm6358-huawei-hg556a-b.dts
@@ -49,69 +49,69 @@
leds {
compatible = "gpio-leds";
- led@0 {
+ led-0 {
label = "red:message";
gpios = <&gpio 0 GPIO_ACTIVE_LOW>;
};
- led@1 {
+ led-1 {
label = "red:hspa";
gpios = <&gpio 1 GPIO_ACTIVE_LOW>;
};
- led@2 {
+ led-2 {
label = "red:dsl";
gpios = <&gpio 2 GPIO_ACTIVE_LOW>;
};
- led_power_red: led@3 {
+ led_power_red: led-3 {
function = LED_FUNCTION_POWER;
color = <LED_COLOR_ID_RED>;
gpios = <&gpio 3 GPIO_ACTIVE_LOW>;
};
- led@6 {
+ led-6 {
label = "all";
gpios = <&gpio 6 GPIO_ACTIVE_LOW>;
default-state = "on";
};
- led@12 {
+ led-12 {
label = "green:lan1";
gpios = <&gpio 12 GPIO_ACTIVE_LOW>;
};
- led@13 {
+ led-13 {
label = "red:lan1";
gpios = <&gpio 13 GPIO_ACTIVE_LOW>;
};
- led@15 {
+ led-15 {
label = "green:lan2";
gpios = <&gpio 15 GPIO_ACTIVE_LOW>;
};
- led@22 {
+ led-22 {
label = "red:lan2";
gpios = <&gpio 22 GPIO_ACTIVE_LOW>;
};
- led@23 {
+ led-23 {
label = "green:lan3";
gpios = <&gpio 23 GPIO_ACTIVE_LOW>;
};
- led@26 {
+ led-26 {
label = "red:lan3";
gpios = <&gpio 26 GPIO_ACTIVE_LOW>;
};
- led@27 {
+ led-27 {
label = "green:lan4";
gpios = <&gpio 27 GPIO_ACTIVE_LOW>;
};
- led@28 {
+ led-28 {
label = "red:lan4";
gpios = <&gpio 28 GPIO_ACTIVE_LOW>;
};
@@ -120,7 +120,7 @@
ath9k-leds {
compatible = "gpio-leds";
- wlan {
+ led-2 {
function = LED_FUNCTION_WLAN;
color = <LED_COLOR_ID_RED>;
gpios = <&ath9k 2 GPIO_ACTIVE_HIGH>;
diff --git a/target/linux/bmips/dts/bcm6362-huawei-hg253s-v2.dts b/target/linux/bmips/dts/bcm6362-huawei-hg253s-v2.dts
index a7498815e3..596ccf998f 100644
--- a/target/linux/bmips/dts/bcm6362-huawei-hg253s-v2.dts
+++ b/target/linux/bmips/dts/bcm6362-huawei-hg253s-v2.dts
@@ -41,12 +41,12 @@
leds {
compatible = "gpio-leds";
- led_phone_green: led@28 {
+ led_phone_green: led-28 {
label = "green:phone";
gpios = <&gpio 28 GPIO_ACTIVE_LOW>;
};
- led@30 {
+ led-30 {
function = LED_FUNCTION_USB;
color = <LED_COLOR_ID_GREEN>;
gpios = <&gpio 30 GPIO_ACTIVE_LOW>;
diff --git a/target/linux/bmips/dts/bcm6362-netgear-dgnd3700-v2.dts b/target/linux/bmips/dts/bcm6362-netgear-dgnd3700-v2.dts
index 0259fdba6c..7c1fde3132 100644
--- a/target/linux/bmips/dts/bcm6362-netgear-dgnd3700-v2.dts
+++ b/target/linux/bmips/dts/bcm6362-netgear-dgnd3700-v2.dts
@@ -42,12 +42,12 @@
leds {
compatible = "gpio-leds";
- led@28 {
+ led-28 {
label = "green:dsl";
gpios = <&gpio 28 GPIO_ACTIVE_LOW>;
};
- led_power_red: led@34 {
+ led_power_red: led-34 {
function = LED_FUNCTION_POWER;
color = <LED_COLOR_ID_RED>;
gpios = <&gpio 34 GPIO_ACTIVE_LOW>;
diff --git a/target/linux/bmips/dts/bcm6368-actiontec-r1000h.dts b/target/linux/bmips/dts/bcm6368-actiontec-r1000h.dts
index 5951ad854c..7f4a725e9a 100644
--- a/target/linux/bmips/dts/bcm6368-actiontec-r1000h.dts
+++ b/target/linux/bmips/dts/bcm6368-actiontec-r1000h.dts
@@ -35,44 +35,44 @@
leds {
compatible = "gpio-leds";
- led@5 {
+ led-5 {
function = LED_FUNCTION_WAN;
color = <LED_COLOR_ID_GREEN>;
gpios = <&gpio 5 GPIO_ACTIVE_HIGH>;
};
- led@21 {
+ led-21 {
function = LED_FUNCTION_USB;
color = <LED_COLOR_ID_GREEN>;
gpios = <&gpio 21 GPIO_ACTIVE_LOW>;
};
- led_power_green: led@22 {
+ led_power_green: led-22 {
function = LED_FUNCTION_POWER;
color = <LED_COLOR_ID_GREEN>;
gpios = <&gpio 22 GPIO_ACTIVE_HIGH>;
};
- led@23 {
+ led-23 {
function = LED_FUNCTION_WPS;
color = <LED_COLOR_ID_GREEN>;
gpios = <&gpio 23 GPIO_ACTIVE_LOW>;
};
- led_power_red: led@24 {
+ led_power_red: led-24 {
function = LED_FUNCTION_POWER;
color = <LED_COLOR_ID_RED>;
gpios = <&gpio 24 GPIO_ACTIVE_HIGH>;
panic-indicator;
};
- led@30 {
+ led-30 {
function = LED_FUNCTION_WPS;
color = <LED_COLOR_ID_RED>;
gpios = <&gpio 30 GPIO_ACTIVE_LOW>;
};
- led@31 {
+ led-31 {
function = LED_FUNCTION_WAN;
color = <LED_COLOR_ID_RED>;
gpios = <&gpio 31 GPIO_ACTIVE_HIGH>;
diff --git a/target/linux/bmips/dts/bcm6368-comtrend-vr-3025u.dts b/target/linux/bmips/dts/bcm6368-comtrend-vr-3025u.dts
index 647db7afaa..0ebe26716c 100644
--- a/target/linux/bmips/dts/bcm6368-comtrend-vr-3025u.dts
+++ b/target/linux/bmips/dts/bcm6368-comtrend-vr-3025u.dts
@@ -28,30 +28,30 @@
leds {
compatible = "gpio-leds";
- led@2 {
+ led-2 {
label = "green:dsl";
gpios = <&gpio 2 GPIO_ACTIVE_LOW>;
};
- led@5 {
+ led-5 {
label = "green:internet";
gpios = <&gpio 5 GPIO_ACTIVE_HIGH>;
};
- led_power_green: led@22 {
+ led_power_green: led-22 {
function = LED_FUNCTION_POWER;
color = <LED_COLOR_ID_GREEN>;
gpios = <&gpio 22 GPIO_ACTIVE_HIGH>;
};
- led_power_red: led@24 {
+ led_power_red: led-24 {
function = LED_FUNCTION_POWER;
color = <LED_COLOR_ID_RED>;
gpios = <&gpio 24 GPIO_ACTIVE_HIGH>;
panic-indicator;
};
- led@31 {
+ led-31 {
label = "red:internet";
gpios = <&gpio 31 GPIO_ACTIVE_HIGH>;
};
diff --git a/target/linux/bmips/dts/bcm6368-comtrend-vr-3025un.dts b/target/linux/bmips/dts/bcm6368-comtrend-vr-3025un.dts
index ba75cb3e5c..8935dfe903 100644
--- a/target/linux/bmips/dts/bcm6368-comtrend-vr-3025un.dts
+++ b/target/linux/bmips/dts/bcm6368-comtrend-vr-3025un.dts
@@ -28,30 +28,30 @@
leds {
compatible = "gpio-leds";
- led@2 {
+ led-2 {
label = "green:dsl";
gpios = <&gpio 2 GPIO_ACTIVE_LOW>;
};
- led@5 {
+ led-5 {
label = "green:internet";
gpios = <&gpio 5 GPIO_ACTIVE_HIGH>;
};
- led_power_green: led@22 {
+ led_power_green: led-22 {
function = LED_FUNCTION_POWER;
color = <LED_COLOR_ID_GREEN>;
gpios = <&gpio 22 GPIO_ACTIVE_HIGH>;
};
- led_power_red: led@24 {
+ led_power_red: led-24 {
function = LED_FUNCTION_POWER;
color = <LED_COLOR_ID_RED>;
gpios = <&gpio 24 GPIO_ACTIVE_HIGH>;
panic-indicator;
};
- led@31 {
+ led-31 {
label = "red:internet";
gpios = <&gpio 31 GPIO_ACTIVE_HIGH>;
};
diff --git a/target/linux/bmips/dts/bcm6368-netgear-dgnd3700.dtsi b/target/linux/bmips/dts/bcm6368-netgear-dgnd3700.dtsi
index 49c546692a..43225cdd52 100644
--- a/target/linux/bmips/dts/bcm6368-netgear-dgnd3700.dtsi
+++ b/target/linux/bmips/dts/bcm6368-netgear-dgnd3700.dtsi
@@ -41,66 +41,66 @@
leds {
compatible = "gpio-leds";
- led@2 {
+ led-2 {
label = "green:dsl";
gpios = <&gpio 2 GPIO_ACTIVE_LOW>;
};
- led@4 {
+ led-4 {
function = LED_FUNCTION_WAN;
color = <LED_COLOR_ID_RED>;
gpios = <&gpio 4 GPIO_ACTIVE_LOW>;
};
- led@5 {
+ led-5 {
function = LED_FUNCTION_WAN;
color = <LED_COLOR_ID_GREEN>;
gpios = <&gpio 5 GPIO_ACTIVE_LOW>;
};
- led@11 {
+ led-11 {
function = LED_FUNCTION_WPS;
color = <LED_COLOR_ID_GREEN>;
gpios = <&gpio 11 GPIO_ACTIVE_LOW>;
};
- led@13 {
+ led-13 {
/* Front USB port */
label = "green:usb2";
gpios = <&gpio 13 GPIO_ACTIVE_LOW>;
};
- led@14 {
+ led-14 {
/* Back USB port */
label = "green:usb1";
gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
};
- led_power_red: led@22 {
+ led_power_red: led-22 {
function = LED_FUNCTION_POWER;
color = <LED_COLOR_ID_RED>;
gpios = <&gpio 22 GPIO_ACTIVE_LOW>;
panic-indicator;
};
- led@23 {
+ led-23 {
function = LED_FUNCTION_LAN;
color = <LED_COLOR_ID_GREEN>;
gpios = <&gpio 23 GPIO_ACTIVE_LOW>;
};
- led_power_green: led@24 {
+ led_power_green: led-24 {
function = LED_FUNCTION_POWER;
color = <LED_COLOR_ID_GREEN>;
gpios = <&gpio 24 GPIO_ACTIVE_LOW>;
};
- led@26 {
+ led-26 {
label = "green:wifi2g";
gpios = <&gpio 26 GPIO_ACTIVE_LOW>;
};
- led@27 {
+ led-27 {
label = "blue:wifi5g";
gpios = <&gpio 27 GPIO_ACTIVE_LOW>;
};
diff --git a/target/linux/bmips/dts/bcm6368-observa-vh4032n.dts b/target/linux/bmips/dts/bcm6368-observa-vh4032n.dts
index 3268ff146f..a0c2f321af 100644
--- a/target/linux/bmips/dts/bcm6368-observa-vh4032n.dts
+++ b/target/linux/bmips/dts/bcm6368-observa-vh4032n.dts
@@ -35,45 +35,45 @@
leds {
compatible = "gpio-leds";
- led@2 {
+ led-2 {
label = "blue:dsl";
gpios = <&gpio 2 GPIO_ACTIVE_LOW>;
};
- led@5 {
+ led-5 {
label = "red:dsl";
gpios = <&gpio 5 GPIO_ACTIVE_LOW>;
};
- led@11 {
+ led-11 {
label = "blue:hspa";
gpios = <&gpio 11 GPIO_ACTIVE_LOW>;
};
- led@12 {
+ led-12 {
label = "red:hspa";
gpios = <&gpio 12 GPIO_ACTIVE_LOW>;
};
- led_power_blue: led@22 {
+ led_power_blue: led-22 {
function = LED_FUNCTION_POWER;
color = <LED_COLOR_ID_BLUE>;
gpios = <&gpio 22 GPIO_ACTIVE_HIGH>;
};
- led_power_red: led@24 {
+ led_power_red: led-24 {
function = LED_FUNCTION_POWER;
color = <LED_COLOR_ID_RED>;
gpios = <&gpio 24 GPIO_ACTIVE_HIGH>;
panic-indicator;
};
- led@25 {
+ led-25 {
label = "blue:voice";
gpios = <&gpio 25 GPIO_ACTIVE_LOW>;
};
- led@26 {
+ led-26 {
label = "red:voice";
gpios = <&gpio 26 GPIO_ACTIVE_LOW>;
};
diff --git a/target/linux/bmips/dts/bcm6369-comtrend-wap-5813n.dts b/target/linux/bmips/dts/bcm6369-comtrend-wap-5813n.dts
index 263a10bf61..5fa511816b 100644
--- a/target/linux/bmips/dts/bcm6369-comtrend-wap-5813n.dts
+++ b/target/linux/bmips/dts/bcm6369-comtrend-wap-5813n.dts
@@ -42,37 +42,37 @@
leds {
compatible = "gpio-leds";
- led@5 {
+ led-5 {
label = "green:internet";
gpios = <&gpio 5 GPIO_ACTIVE_HIGH>;
};
- led@14 {
+ led-14 {
function = LED_FUNCTION_USB;
color = <LED_COLOR_ID_GREEN>;
gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
};
- led_power_green: led@22 {
+ led_power_green: led-22 {
function = LED_FUNCTION_POWER;
color = <LED_COLOR_ID_GREEN>;
gpios = <&gpio 22 GPIO_ACTIVE_HIGH>;
};
- led@23 {
+ led-23 {
function = LED_FUNCTION_WPS;
color = <LED_COLOR_ID_GREEN>;
gpios = <&gpio 23 GPIO_ACTIVE_LOW>;
};
- led_power_red: led@24 {
+ led_power_red: led-24 {
function = LED_FUNCTION_POWER;
color = <LED_COLOR_ID_RED>;
gpios = <&gpio 24 GPIO_ACTIVE_HIGH>;
panic-indicator;
};
- led@31 {
+ led-31 {
label = "red:internet";
gpios = <&gpio 31 GPIO_ACTIVE_HIGH>;
};
diff --git a/target/linux/bmips/dts/bcm6369-netgear-evg2000.dts b/target/linux/bmips/dts/bcm6369-netgear-evg2000.dts
index 376f5b6865..cf91c0ad23 100644
--- a/target/linux/bmips/dts/bcm6369-netgear-evg2000.dts
+++ b/target/linux/bmips/dts/bcm6369-netgear-evg2000.dts
@@ -35,52 +35,52 @@
leds {
compatible = "gpio-leds";
- led@2 {
+ led-2 {
label = "green:voip2";
gpios = <&gpio 2 GPIO_ACTIVE_LOW>;
};
- led@4 {
+ led-4 {
label = "red:internet";
gpios = <&gpio 4 GPIO_ACTIVE_LOW>;
};
- led@5 {
+ led-5 {
label = "green:internet";
gpios = <&gpio 5 GPIO_ACTIVE_LOW>;
};
- led@14 {
+ led-14 {
label = "green:voip1";
gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
};
- led@15 {
+ led-15 {
function = LED_FUNCTION_USB;
color = <LED_COLOR_ID_GREEN>;
gpios = <&gpio 15 GPIO_ACTIVE_LOW>;
};
- led_power_green: led@22 {
+ led_power_green: led-22 {
function = LED_FUNCTION_POWER;
color = <LED_COLOR_ID_GREEN>;
gpios = <&gpio 22 GPIO_ACTIVE_LOW>;
};
- led_power_red: led@23 {
+ led_power_red: led-23 {
function = LED_FUNCTION_POWER;
color = <LED_COLOR_ID_RED>;
gpios = <&gpio 23 GPIO_ACTIVE_LOW>;
panic-indicator;
};
- led@24 {
+ led-24 {
function = LED_FUNCTION_LAN;
color = <LED_COLOR_ID_GREEN>;
gpios = <&gpio 24 GPIO_ACTIVE_LOW>;
};
- led@27 {
+ led-27 {
function = LED_FUNCTION_WAN;
color = <LED_COLOR_ID_GREEN>;
gpios = <&gpio 27 GPIO_ACTIVE_LOW>;
diff --git a/target/linux/bmips/image/bcm6318.mk b/target/linux/bmips/image/bcm6318.mk
index bfd75cc077..286a30c2f4 100644
--- a/target/linux/bmips/image/bcm6318.mk
+++ b/target/linux/bmips/image/bcm6318.mk
@@ -12,3 +12,23 @@ define Device/comtrend_ar-5315u
kmod-leds-bcm6328
endef
TARGET_DEVICES += comtrend_ar-5315u
+
+define Device/tp-link_td-w8968-v3
+ $(Device/bcm63xx-cfe)
+ DEVICE_VENDOR := TP-Link
+ DEVICE_MODEL := TD-W8968
+ DEVICE_VARIANT := V3
+ DEVICE_ALT0_VENDOR := TP-Link
+ DEVICE_ALT0_MODEL := TD-W8968
+ DEVICE_ALT0_VARIANT := V4
+ DEVICE_ALT1_VENDOR := TP-Link
+ DEVICE_ALT1_MODEL := TD-W8960N
+ DEVICE_ALT1_VARIANT := V5
+ CHIP_ID := 6318
+ CFE_BOARD_ID := 96318REF
+ FLASH_MB := 8
+ DEVICE_PACKAGES += $(USB2_PACKAGES) \
+ $(B43_PACKAGES) broadcom-43217-sprom \
+ kmod-leds-bcm6328
+endef
+TARGET_DEVICES += tp-link_td-w8968-v3
diff --git a/target/linux/bmips/image/bcm6328.mk b/target/linux/bmips/image/bcm6328.mk
index b85b6ac7a8..0ba17cef4f 100644
--- a/target/linux/bmips/image/bcm6328.mk
+++ b/target/linux/bmips/image/bcm6328.mk
@@ -39,6 +39,27 @@ define Device/comtrend_ar-5387un
endef
TARGET_DEVICES += comtrend_ar-5387un
+define Device/dlink_dsl-2750b-b1
+ $(Device/bcm63xx-cfe)
+ DEVICE_VENDOR := D-Link
+ DEVICE_MODEL := DSL-2750B
+ DEVICE_VARIANT := B1
+ DEVICE_ALT0_VENDOR := D-Link
+ DEVICE_ALT0_MODEL := DSL-2740B
+ DEVICE_ALT0_VARIANT := F1
+ DEVICE_ALT1_VENDOR := D-Link
+ DEVICE_ALT1_MODEL := DSL-2741B
+ DEVICE_ALT1_VARIANT := F1
+ CFE_BOARD_ID := AW4339U
+ CHIP_ID := 6328
+ IMAGES := cfe-EU.bin cfe-AU.bin
+ IMAGE/cfe-AU.bin := cfe-bin --signature2 "4.06.01.AUF1" --pad 4
+ IMAGE/cfe-EU.bin := cfe-bin --signature2 "4.06.01.EUF1" --pad 4
+ DEVICE_PACKAGES += $(USB2_PACKAGES) $(ATH9K_PACKAGES) \
+ kmod-leds-gpio kmod-leds-bcm6328
+endef
+TARGET_DEVICES += dlink_dsl-2750b-b1
+
define Device/innacomm_w3400v6
$(Device/bcm63xx-cfe)
DEVICE_VENDOR := Innacomm
diff --git a/target/linux/gemini/config-6.6 b/target/linux/gemini/config-6.6
index 87174d292f..a93297a423 100644
--- a/target/linux/gemini/config-6.6
+++ b/target/linux/gemini/config-6.6
@@ -180,7 +180,6 @@ CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
CONFIG_FS_IOMAP=y
CONFIG_FS_MBCACHE=y
-CONFIG_FS_POSIX_ACL=y
CONFIG_FTTMR010_TIMER=y
CONFIG_FTWDT010_WATCHDOG=y
CONFIG_FUNCTION_ALIGNMENT=0
@@ -431,7 +430,6 @@ CONFIG_THREAD_INFO_IN_TASK=y
CONFIG_TICK_CPU_ACCOUNTING=y
CONFIG_TIMER_OF=y
CONFIG_TIMER_PROBE=y
-CONFIG_TMPFS_POSIX_ACL=y
CONFIG_TREE_RCU=y
CONFIG_TREE_SRCU=y
CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
diff --git a/target/linux/generic/backport-5.15/836-v6.9-0002-nvmem-mtk-efuse-Register-MediaTek-socinfo-driver-fro.patch b/target/linux/generic/backport-5.15/836-v6.9-0002-nvmem-mtk-efuse-Register-MediaTek-socinfo-driver-fro.patch
new file mode 100644
index 0000000000..8e7c8233e2
--- /dev/null
+++ b/target/linux/generic/backport-5.15/836-v6.9-0002-nvmem-mtk-efuse-Register-MediaTek-socinfo-driver-fro.patch
@@ -0,0 +1,69 @@
+From 998f0633773b3432829fe45d2cd2ffb842f3c78e Mon Sep 17 00:00:00 2001
+From: William-tw Lin <william-tw.lin@mediatek.com>
+Date: Sat, 24 Feb 2024 11:45:07 +0000
+Subject: [PATCH] nvmem: mtk-efuse: Register MediaTek socinfo driver from efuse
+
+The socinfo driver reads chip information from eFuses and does not need
+any devicetree node. Register it from mtk-efuse.
+
+While at it, also add the name for this driver's nvmem_config.
+
+Signed-off-by: William-tw Lin <william-tw.lin@mediatek.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240224114516.86365-3-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/mtk-efuse.c | 21 ++++++++++++++++++++-
+ 1 file changed, 20 insertions(+), 1 deletion(-)
+
+--- a/drivers/nvmem/mtk-efuse.c
++++ b/drivers/nvmem/mtk-efuse.c
+@@ -68,6 +68,7 @@ static int mtk_efuse_probe(struct platfo
+ struct nvmem_config econfig = {};
+ struct mtk_efuse_priv *priv;
+ const struct mtk_efuse_pdata *pdata;
++ struct platform_device *socinfo;
+
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+@@ -85,11 +86,20 @@ static int mtk_efuse_probe(struct platfo
+ econfig.size = resource_size(res);
+ econfig.priv = priv;
+ econfig.dev = dev;
++ econfig.name = "mtk-efuse";
+ if (pdata->uses_post_processing)
+ econfig.fixup_dt_cell_info = &mtk_efuse_fixup_dt_cell_info;
+ nvmem = devm_nvmem_register(dev, &econfig);
++ if (IS_ERR(nvmem))
++ return PTR_ERR(nvmem);
+
+- return PTR_ERR_OR_ZERO(nvmem);
++ socinfo = platform_device_register_data(&pdev->dev, "mtk-socinfo",
++ PLATFORM_DEVID_AUTO, NULL, 0);
++ if (IS_ERR(socinfo))
++ dev_info(dev, "MediaTek SoC Information will be unavailable\n");
++
++ platform_set_drvdata(pdev, socinfo);
++ return 0;
+ }
+
+ static const struct mtk_efuse_pdata mtk_mt8186_efuse_pdata = {
+@@ -108,8 +118,17 @@ static const struct of_device_id mtk_efu
+ };
+ MODULE_DEVICE_TABLE(of, mtk_efuse_of_match);
+
++static void mtk_efuse_remove(struct platform_device *pdev)
++{
++ struct platform_device *socinfo = platform_get_drvdata(pdev);
++
++ if (!IS_ERR_OR_NULL(socinfo))
++ platform_device_unregister(socinfo);
++}
++
+ static struct platform_driver mtk_efuse_driver = {
+ .probe = mtk_efuse_probe,
++ .remove_new = mtk_efuse_remove,
+ .driver = {
+ .name = "mediatek,efuse",
+ .of_match_table = mtk_efuse_of_match,
diff --git a/target/linux/generic/backport-5.15/836-v6.9-0003-nvmem-zynqmp_nvmem-zynqmp_nvmem_probe-cleanup.patch b/target/linux/generic/backport-5.15/836-v6.9-0003-nvmem-zynqmp_nvmem-zynqmp_nvmem_probe-cleanup.patch
new file mode 100644
index 0000000000..0f90e548a2
--- /dev/null
+++ b/target/linux/generic/backport-5.15/836-v6.9-0003-nvmem-zynqmp_nvmem-zynqmp_nvmem_probe-cleanup.patch
@@ -0,0 +1,97 @@
+From 29be47fcd6a06ea2e79eeeca6e69ad1e23254a69 Mon Sep 17 00:00:00 2001
+From: Praveen Teja Kundanala <praveen.teja.kundanala@amd.com>
+Date: Sat, 24 Feb 2024 11:45:11 +0000
+Subject: [PATCH] nvmem: zynqmp_nvmem: zynqmp_nvmem_probe cleanup
+
+- Remove static nvmem_config declaration
+- Remove zynqmp_nvmem_data
+
+Signed-off-by: Praveen Teja Kundanala <praveen.teja.kundanala@amd.com>
+Acked-by: Kalyani Akula <Kalyani.akula@amd.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240224114516.86365-7-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/zynqmp_nvmem.c | 37 ++++++++++++------------------------
+ 1 file changed, 12 insertions(+), 25 deletions(-)
+
+--- a/drivers/nvmem/zynqmp_nvmem.c
++++ b/drivers/nvmem/zynqmp_nvmem.c
+@@ -1,6 +1,7 @@
+ // SPDX-License-Identifier: GPL-2.0+
+ /*
+ * Copyright (C) 2019 Xilinx, Inc.
++ * Copyright (C) 2022 - 2023, Advanced Micro Devices, Inc.
+ */
+
+ #include <linux/module.h>
+@@ -11,36 +12,25 @@
+
+ #define SILICON_REVISION_MASK 0xF
+
+-struct zynqmp_nvmem_data {
+- struct device *dev;
+- struct nvmem_device *nvmem;
+-};
+
+ static int zynqmp_nvmem_read(void *context, unsigned int offset,
+ void *val, size_t bytes)
+ {
++ struct device *dev = context;
+ int ret;
+- int idcode, version;
+- struct zynqmp_nvmem_data *priv = context;
++ int idcode;
++ int version;
+
+ ret = zynqmp_pm_get_chipid(&idcode, &version);
+ if (ret < 0)
+ return ret;
+
+- dev_dbg(priv->dev, "Read chipid val %x %x\n", idcode, version);
++ dev_dbg(dev, "Read chipid val %x %x\n", idcode, version);
+ *(int *)val = version & SILICON_REVISION_MASK;
+
+ return 0;
+ }
+
+-static struct nvmem_config econfig = {
+- .name = "zynqmp-nvmem",
+- .owner = THIS_MODULE,
+- .word_size = 1,
+- .size = 1,
+- .read_only = true,
+-};
+-
+ static const struct of_device_id zynqmp_nvmem_match[] = {
+ { .compatible = "xlnx,zynqmp-nvmem-fw", },
+ { /* sentinel */ },
+@@ -50,21 +40,18 @@ MODULE_DEVICE_TABLE(of, zynqmp_nvmem_mat
+ static int zynqmp_nvmem_probe(struct platform_device *pdev)
+ {
+ struct device *dev = &pdev->dev;
+- struct zynqmp_nvmem_data *priv;
++ struct nvmem_config econfig = {};
+
+- priv = devm_kzalloc(dev, sizeof(struct zynqmp_nvmem_data), GFP_KERNEL);
+- if (!priv)
+- return -ENOMEM;
+-
+- priv->dev = dev;
++ econfig.name = "zynqmp-nvmem";
++ econfig.owner = THIS_MODULE;
++ econfig.word_size = 1;
++ econfig.size = 1;
+ econfig.dev = dev;
+ econfig.add_legacy_fixed_of_cells = true;
++ econfig.read_only = true;
+ econfig.reg_read = zynqmp_nvmem_read;
+- econfig.priv = priv;
+-
+- priv->nvmem = devm_nvmem_register(dev, &econfig);
+
+- return PTR_ERR_OR_ZERO(priv->nvmem);
++ return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &econfig));
+ }
+
+ static struct platform_driver zynqmp_nvmem_driver = {
diff --git a/target/linux/generic/backport-5.15/836-v6.9-0004-nvmem-zynqmp_nvmem-Add-support-to-access-efuse.patch b/target/linux/generic/backport-5.15/836-v6.9-0004-nvmem-zynqmp_nvmem-Add-support-to-access-efuse.patch
new file mode 100644
index 0000000000..39c2f17835
--- /dev/null
+++ b/target/linux/generic/backport-5.15/836-v6.9-0004-nvmem-zynqmp_nvmem-Add-support-to-access-efuse.patch
@@ -0,0 +1,243 @@
+From 737c0c8d07b5f671c0a33cec95965fcb2d2ea893 Mon Sep 17 00:00:00 2001
+From: Praveen Teja Kundanala <praveen.teja.kundanala@amd.com>
+Date: Sat, 24 Feb 2024 11:45:12 +0000
+Subject: [PATCH] nvmem: zynqmp_nvmem: Add support to access efuse
+
+Add support to read/write efuse memory map of ZynqMP.
+Below are the offsets of ZynqMP efuse memory map
+ 0 - SOC version(read only)
+ 0xC - 0xFC -ZynqMP specific purpose efuses
+ 0x100 - 0x17F - Physical Unclonable Function(PUF)
+ efuses repurposed as user efuses
+
+Signed-off-by: Praveen Teja Kundanala <praveen.teja.kundanala@amd.com>
+Acked-by: Kalyani Akula <Kalyani.akula@amd.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240224114516.86365-8-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/zynqmp_nvmem.c | 186 +++++++++++++++++++++++++++++++++--
+ 1 file changed, 176 insertions(+), 10 deletions(-)
+
+--- a/drivers/nvmem/zynqmp_nvmem.c
++++ b/drivers/nvmem/zynqmp_nvmem.c
+@@ -4,6 +4,7 @@
+ * Copyright (C) 2022 - 2023, Advanced Micro Devices, Inc.
+ */
+
++#include <linux/dma-mapping.h>
+ #include <linux/module.h>
+ #include <linux/nvmem-provider.h>
+ #include <linux/of.h>
+@@ -11,24 +12,189 @@
+ #include <linux/firmware/xlnx-zynqmp.h>
+
+ #define SILICON_REVISION_MASK 0xF
++#define P_USER_0_64_UPPER_MASK GENMASK(31, 16)
++#define P_USER_127_LOWER_4_BIT_MASK GENMASK(3, 0)
++#define WORD_INBYTES 4
++#define SOC_VER_SIZE 0x4
++#define EFUSE_MEMORY_SIZE 0x177
++#define UNUSED_SPACE 0x8
++#define ZYNQMP_NVMEM_SIZE (SOC_VER_SIZE + UNUSED_SPACE + \
++ EFUSE_MEMORY_SIZE)
++#define SOC_VERSION_OFFSET 0x0
++#define EFUSE_START_OFFSET 0xC
++#define EFUSE_END_OFFSET 0xFC
++#define EFUSE_PUF_START_OFFSET 0x100
++#define EFUSE_PUF_MID_OFFSET 0x140
++#define EFUSE_PUF_END_OFFSET 0x17F
++#define EFUSE_NOT_ENABLED 29
+
++/*
++ * efuse access type
++ */
++enum efuse_access {
++ EFUSE_READ = 0,
++ EFUSE_WRITE
++};
++
++/**
++ * struct xilinx_efuse - the basic structure
++ * @src: address of the buffer to store the data to be write/read
++ * @size: read/write word count
++ * @offset: read/write offset
++ * @flag: 0 - represents efuse read and 1- represents efuse write
++ * @pufuserfuse:0 - represents non-puf efuses, offset is used for read/write
++ * 1 - represents puf user fuse row number.
++ *
++ * this structure stores all the required details to
++ * read/write efuse memory.
++ */
++struct xilinx_efuse {
++ u64 src;
++ u32 size;
++ u32 offset;
++ enum efuse_access flag;
++ u32 pufuserfuse;
++};
++
++static int zynqmp_efuse_access(void *context, unsigned int offset,
++ void *val, size_t bytes, enum efuse_access flag,
++ unsigned int pufflag)
++{
++ struct device *dev = context;
++ struct xilinx_efuse *efuse;
++ dma_addr_t dma_addr;
++ dma_addr_t dma_buf;
++ size_t words = bytes / WORD_INBYTES;
++ int ret;
++ int value;
++ char *data;
+
+-static int zynqmp_nvmem_read(void *context, unsigned int offset,
+- void *val, size_t bytes)
++ if (bytes % WORD_INBYTES != 0) {
++ dev_err(dev, "Bytes requested should be word aligned\n");
++ return -EOPNOTSUPP;
++ }
++
++ if (pufflag == 0 && offset % WORD_INBYTES) {
++ dev_err(dev, "Offset requested should be word aligned\n");
++ return -EOPNOTSUPP;
++ }
++
++ if (pufflag == 1 && flag == EFUSE_WRITE) {
++ memcpy(&value, val, bytes);
++ if ((offset == EFUSE_PUF_START_OFFSET ||
++ offset == EFUSE_PUF_MID_OFFSET) &&
++ value & P_USER_0_64_UPPER_MASK) {
++ dev_err(dev, "Only lower 4 bytes are allowed to be programmed in P_USER_0 & P_USER_64\n");
++ return -EOPNOTSUPP;
++ }
++
++ if (offset == EFUSE_PUF_END_OFFSET &&
++ (value & P_USER_127_LOWER_4_BIT_MASK)) {
++ dev_err(dev, "Only MSB 28 bits are allowed to be programmed for P_USER_127\n");
++ return -EOPNOTSUPP;
++ }
++ }
++
++ efuse = dma_alloc_coherent(dev, sizeof(struct xilinx_efuse),
++ &dma_addr, GFP_KERNEL);
++ if (!efuse)
++ return -ENOMEM;
++
++ data = dma_alloc_coherent(dev, sizeof(bytes),
++ &dma_buf, GFP_KERNEL);
++ if (!data) {
++ ret = -ENOMEM;
++ goto efuse_data_fail;
++ }
++
++ if (flag == EFUSE_WRITE) {
++ memcpy(data, val, bytes);
++ efuse->flag = EFUSE_WRITE;
++ } else {
++ efuse->flag = EFUSE_READ;
++ }
++
++ efuse->src = dma_buf;
++ efuse->size = words;
++ efuse->offset = offset;
++ efuse->pufuserfuse = pufflag;
++
++ zynqmp_pm_efuse_access(dma_addr, (u32 *)&ret);
++ if (ret != 0) {
++ if (ret == EFUSE_NOT_ENABLED) {
++ dev_err(dev, "efuse access is not enabled\n");
++ ret = -EOPNOTSUPP;
++ } else {
++ dev_err(dev, "Error in efuse read %x\n", ret);
++ ret = -EPERM;
++ }
++ goto efuse_access_err;
++ }
++
++ if (flag == EFUSE_READ)
++ memcpy(val, data, bytes);
++efuse_access_err:
++ dma_free_coherent(dev, sizeof(bytes),
++ data, dma_buf);
++efuse_data_fail:
++ dma_free_coherent(dev, sizeof(struct xilinx_efuse),
++ efuse, dma_addr);
++
++ return ret;
++}
++
++static int zynqmp_nvmem_read(void *context, unsigned int offset, void *val, size_t bytes)
+ {
+ struct device *dev = context;
+ int ret;
++ int pufflag = 0;
+ int idcode;
+ int version;
+
+- ret = zynqmp_pm_get_chipid(&idcode, &version);
+- if (ret < 0)
+- return ret;
++ if (offset >= EFUSE_PUF_START_OFFSET && offset <= EFUSE_PUF_END_OFFSET)
++ pufflag = 1;
++
++ switch (offset) {
++ /* Soc version offset is zero */
++ case SOC_VERSION_OFFSET:
++ if (bytes != SOC_VER_SIZE)
++ return -EOPNOTSUPP;
++
++ ret = zynqmp_pm_get_chipid((u32 *)&idcode, (u32 *)&version);
++ if (ret < 0)
++ return ret;
++
++ dev_dbg(dev, "Read chipid val %x %x\n", idcode, version);
++ *(int *)val = version & SILICON_REVISION_MASK;
++ break;
++ /* Efuse offset starts from 0xc */
++ case EFUSE_START_OFFSET ... EFUSE_END_OFFSET:
++ case EFUSE_PUF_START_OFFSET ... EFUSE_PUF_END_OFFSET:
++ ret = zynqmp_efuse_access(context, offset, val,
++ bytes, EFUSE_READ, pufflag);
++ break;
++ default:
++ *(u32 *)val = 0xDEADBEEF;
++ ret = 0;
++ break;
++ }
++
++ return ret;
++}
++
++static int zynqmp_nvmem_write(void *context,
++ unsigned int offset, void *val, size_t bytes)
++{
++ int pufflag = 0;
++
++ if (offset < EFUSE_START_OFFSET || offset > EFUSE_PUF_END_OFFSET)
++ return -EOPNOTSUPP;
+
+- dev_dbg(dev, "Read chipid val %x %x\n", idcode, version);
+- *(int *)val = version & SILICON_REVISION_MASK;
++ if (offset >= EFUSE_PUF_START_OFFSET && offset <= EFUSE_PUF_END_OFFSET)
++ pufflag = 1;
+
+- return 0;
++ return zynqmp_efuse_access(context, offset,
++ val, bytes, EFUSE_WRITE, pufflag);
+ }
+
+ static const struct of_device_id zynqmp_nvmem_match[] = {
+@@ -45,11 +211,11 @@ static int zynqmp_nvmem_probe(struct pla
+ econfig.name = "zynqmp-nvmem";
+ econfig.owner = THIS_MODULE;
+ econfig.word_size = 1;
+- econfig.size = 1;
++ econfig.size = ZYNQMP_NVMEM_SIZE;
+ econfig.dev = dev;
+ econfig.add_legacy_fixed_of_cells = true;
+- econfig.read_only = true;
+ econfig.reg_read = zynqmp_nvmem_read;
++ econfig.reg_write = zynqmp_nvmem_write;
+
+ return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &econfig));
+ }
diff --git a/target/linux/generic/backport-5.15/836-v6.9-0005-nvmem-mtk-efuse-Drop-NVMEM-device-name.patch b/target/linux/generic/backport-5.15/836-v6.9-0005-nvmem-mtk-efuse-Drop-NVMEM-device-name.patch
new file mode 100644
index 0000000000..c67399cb13
--- /dev/null
+++ b/target/linux/generic/backport-5.15/836-v6.9-0005-nvmem-mtk-efuse-Drop-NVMEM-device-name.patch
@@ -0,0 +1,35 @@
+From 76c345edef754b16cab81ad9452cc49c09e67066 Mon Sep 17 00:00:00 2001
+From: Chen-Yu Tsai <wenst@chromium.org>
+Date: Sat, 24 Feb 2024 11:45:14 +0000
+Subject: [PATCH] nvmem: mtk-efuse: Drop NVMEM device name
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The MT8183 has not one but two efuse devices. The static name and ID
+causes the second efuse device to fail to probe, due to duplicate sysfs
+entries.
+
+With the rework of the mtk-socinfo driver, lookup by name is no longer
+necessary. The custom name can simply be dropped.
+
+Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Tested-by: "Nícolas F. R. A. Prado" <nfraprado@collabora.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240224114516.86365-10-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/mtk-efuse.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/drivers/nvmem/mtk-efuse.c
++++ b/drivers/nvmem/mtk-efuse.c
+@@ -86,7 +86,6 @@ static int mtk_efuse_probe(struct platfo
+ econfig.size = resource_size(res);
+ econfig.priv = priv;
+ econfig.dev = dev;
+- econfig.name = "mtk-efuse";
+ if (pdata->uses_post_processing)
+ econfig.fixup_dt_cell_info = &mtk_efuse_fixup_dt_cell_info;
+ nvmem = devm_nvmem_register(dev, &econfig);
diff --git a/target/linux/generic/backport-5.15/836-v6.9-0007-nvmem-core-Print-error-on-wrong-bits-DT-property.patch b/target/linux/generic/backport-5.15/836-v6.9-0007-nvmem-core-Print-error-on-wrong-bits-DT-property.patch
new file mode 100644
index 0000000000..47787d9ad2
--- /dev/null
+++ b/target/linux/generic/backport-5.15/836-v6.9-0007-nvmem-core-Print-error-on-wrong-bits-DT-property.patch
@@ -0,0 +1,32 @@
+From def3173d4f17b37cecbd74d7c269a080b0b01598 Mon Sep 17 00:00:00 2001
+From: Markus Schneider-Pargmann <msp@baylibre.com>
+Date: Sat, 24 Feb 2024 11:45:16 +0000
+Subject: [PATCH] nvmem: core: Print error on wrong bits DT property
+
+The algorithms in nvmem core are built with the constraint that
+bit_offset < 8. If bit_offset is greater the results are wrong. Print an
+error if the devicetree 'bits' property is outside of the valid range
+and abort parsing.
+
+Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240224114516.86365-12-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/core.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/nvmem/core.c
++++ b/drivers/nvmem/core.c
+@@ -807,6 +807,11 @@ static int nvmem_add_cells_from_dt(struc
+ if (addr && len == (2 * sizeof(u32))) {
+ info.bit_offset = be32_to_cpup(addr++);
+ info.nbits = be32_to_cpup(addr);
++ if (info.bit_offset >= BITS_PER_BYTE || info.nbits < 1) {
++ dev_err(dev, "nvmem: invalid bits on %pOF\n", child);
++ of_node_put(child);
++ return -EINVAL;
++ }
+ }
+
+ info.np = of_node_get(child);
diff --git a/target/linux/generic/backport-5.15/837-v6.10-0001-nvmem-layouts-store-owner-from-modules-with-nvmem_la.patch b/target/linux/generic/backport-5.15/837-v6.10-0001-nvmem-layouts-store-owner-from-modules-with-nvmem_la.patch
new file mode 100644
index 0000000000..c15b4b2265
--- /dev/null
+++ b/target/linux/generic/backport-5.15/837-v6.10-0001-nvmem-layouts-store-owner-from-modules-with-nvmem_la.patch
@@ -0,0 +1,61 @@
+From 6d0ca4a2a7e25f9ad07c1f335f20b4d9e048cdd5 Mon Sep 17 00:00:00 2001
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Date: Tue, 30 Apr 2024 09:49:11 +0100
+Subject: [PATCH] nvmem: layouts: store owner from modules with
+ nvmem_layout_driver_register()
+
+Modules registering driver with nvmem_layout_driver_register() might
+forget to set .owner field. The field is used by some of other kernel
+parts for reference counting (try_module_get()), so it is expected that
+drivers will set it.
+
+Solve the problem by moving this task away from the drivers to the core
+code, just like we did for platform_driver in
+commit 9447057eaff8 ("platform_device: use a macro instead of
+platform_driver_register").
+
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Michael Walle <mwalle@kernel.org>
+Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240430084921.33387-2-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/layouts.c | 6 ++++--
+ include/linux/nvmem-provider.h | 5 ++++-
+ 2 files changed, 8 insertions(+), 3 deletions(-)
+
+--- a/drivers/nvmem/layouts.c
++++ b/drivers/nvmem/layouts.c
+@@ -52,13 +52,15 @@ static struct bus_type nvmem_layout_bus_
+ .remove = nvmem_layout_bus_remove,
+ };
+
+-int nvmem_layout_driver_register(struct nvmem_layout_driver *drv)
++int __nvmem_layout_driver_register(struct nvmem_layout_driver *drv,
++ struct module *owner)
+ {
+ drv->driver.bus = &nvmem_layout_bus_type;
++ drv->driver.owner = owner;
+
+ return driver_register(&drv->driver);
+ }
+-EXPORT_SYMBOL_GPL(nvmem_layout_driver_register);
++EXPORT_SYMBOL_GPL(__nvmem_layout_driver_register);
+
+ void nvmem_layout_driver_unregister(struct nvmem_layout_driver *drv)
+ {
+--- a/include/linux/nvmem-provider.h
++++ b/include/linux/nvmem-provider.h
+@@ -199,7 +199,10 @@ int nvmem_add_one_cell(struct nvmem_devi
+ int nvmem_layout_register(struct nvmem_layout *layout);
+ void nvmem_layout_unregister(struct nvmem_layout *layout);
+
+-int nvmem_layout_driver_register(struct nvmem_layout_driver *drv);
++#define nvmem_layout_driver_register(drv) \
++ __nvmem_layout_driver_register(drv, THIS_MODULE)
++int __nvmem_layout_driver_register(struct nvmem_layout_driver *drv,
++ struct module *owner);
+ void nvmem_layout_driver_unregister(struct nvmem_layout_driver *drv);
+ #define module_nvmem_layout_driver(__nvmem_layout_driver) \
+ module_driver(__nvmem_layout_driver, nvmem_layout_driver_register, \
diff --git a/target/linux/generic/backport-5.15/837-v6.10-0002-nvmem-layouts-onie-tlv-drop-driver-owner-initializat.patch b/target/linux/generic/backport-5.15/837-v6.10-0002-nvmem-layouts-onie-tlv-drop-driver-owner-initializat.patch
new file mode 100644
index 0000000000..b483dd243b
--- /dev/null
+++ b/target/linux/generic/backport-5.15/837-v6.10-0002-nvmem-layouts-onie-tlv-drop-driver-owner-initializat.patch
@@ -0,0 +1,28 @@
+From 21833338eccb91194fec6ba7548d9c454824eca0 Mon Sep 17 00:00:00 2001
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Date: Tue, 30 Apr 2024 09:49:12 +0100
+Subject: [PATCH] nvmem: layouts: onie-tlv: drop driver owner initialization
+
+Core in nvmem_layout_driver_register() already sets the .owner, so
+driver does not need to.
+
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Michael Walle <mwalle@kernel.org>
+Acked-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240430084921.33387-3-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/layouts/onie-tlv.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/drivers/nvmem/layouts/onie-tlv.c
++++ b/drivers/nvmem/layouts/onie-tlv.c
+@@ -247,7 +247,6 @@ MODULE_DEVICE_TABLE(of, onie_tlv_of_matc
+
+ static struct nvmem_layout_driver onie_tlv_layout = {
+ .driver = {
+- .owner = THIS_MODULE,
+ .name = "onie-tlv-layout",
+ .of_match_table = onie_tlv_of_match_table,
+ },
diff --git a/target/linux/generic/backport-5.15/837-v6.10-0003-nvmem-layouts-sl28vpd-drop-driver-owner-initializati.patch b/target/linux/generic/backport-5.15/837-v6.10-0003-nvmem-layouts-sl28vpd-drop-driver-owner-initializati.patch
new file mode 100644
index 0000000000..472a65feca
--- /dev/null
+++ b/target/linux/generic/backport-5.15/837-v6.10-0003-nvmem-layouts-sl28vpd-drop-driver-owner-initializati.patch
@@ -0,0 +1,28 @@
+From 23fd602f21953c03c0714257d36685cd6b486f04 Mon Sep 17 00:00:00 2001
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Date: Tue, 30 Apr 2024 09:49:13 +0100
+Subject: [PATCH] nvmem: layouts: sl28vpd: drop driver owner initialization
+
+Core in nvmem_layout_driver_register() already sets the .owner, so
+driver does not need to.
+
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Michael Walle <mwalle@kernel.org>
+Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240430084921.33387-4-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/layouts/sl28vpd.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/drivers/nvmem/layouts/sl28vpd.c
++++ b/drivers/nvmem/layouts/sl28vpd.c
+@@ -156,7 +156,6 @@ MODULE_DEVICE_TABLE(of, sl28vpd_of_match
+
+ static struct nvmem_layout_driver sl28vpd_layout = {
+ .driver = {
+- .owner = THIS_MODULE,
+ .name = "kontron-sl28vpd-layout",
+ .of_match_table = sl28vpd_of_match_table,
+ },
diff --git a/target/linux/generic/backport-5.15/837-v6.10-0004-nvmem-sc27xx-fix-module-autoloading.patch b/target/linux/generic/backport-5.15/837-v6.10-0004-nvmem-sc27xx-fix-module-autoloading.patch
new file mode 100644
index 0000000000..2aa13a5c64
--- /dev/null
+++ b/target/linux/generic/backport-5.15/837-v6.10-0004-nvmem-sc27xx-fix-module-autoloading.patch
@@ -0,0 +1,26 @@
+From dc3d88ade857ba3dca34f008e0b0aed3ef79cb15 Mon Sep 17 00:00:00 2001
+From: Krzysztof Kozlowski <krzk@kernel.org>
+Date: Tue, 30 Apr 2024 09:49:14 +0100
+Subject: [PATCH] nvmem: sc27xx: fix module autoloading
+
+Add MODULE_DEVICE_TABLE(), so the module could be properly autoloaded
+based on the alias from of_device_id table.
+
+Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240430084921.33387-5-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/sc27xx-efuse.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/nvmem/sc27xx-efuse.c
++++ b/drivers/nvmem/sc27xx-efuse.c
+@@ -263,6 +263,7 @@ static const struct of_device_id sc27xx_
+ { .compatible = "sprd,sc2730-efuse", .data = &sc2730_edata},
+ { }
+ };
++MODULE_DEVICE_TABLE(of, sc27xx_efuse_of_match);
+
+ static struct platform_driver sc27xx_efuse_driver = {
+ .probe = sc27xx_efuse_probe,
diff --git a/target/linux/generic/backport-5.15/837-v6.10-0005-nvmem-sprd-fix-module-autoloading.patch b/target/linux/generic/backport-5.15/837-v6.10-0005-nvmem-sprd-fix-module-autoloading.patch
new file mode 100644
index 0000000000..0953c92340
--- /dev/null
+++ b/target/linux/generic/backport-5.15/837-v6.10-0005-nvmem-sprd-fix-module-autoloading.patch
@@ -0,0 +1,26 @@
+From 154c1ec943e34f3188c9305b0c91d5e7dc1373b8 Mon Sep 17 00:00:00 2001
+From: Krzysztof Kozlowski <krzk@kernel.org>
+Date: Tue, 30 Apr 2024 09:49:15 +0100
+Subject: [PATCH] nvmem: sprd: fix module autoloading
+
+Add MODULE_DEVICE_TABLE(), so the module could be properly autoloaded
+based on the alias from of_device_id table.
+
+Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240430084921.33387-6-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/sprd-efuse.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/nvmem/sprd-efuse.c
++++ b/drivers/nvmem/sprd-efuse.c
+@@ -426,6 +426,7 @@ static const struct of_device_id sprd_ef
+ { .compatible = "sprd,ums312-efuse", .data = &ums312_data },
+ { }
+ };
++MODULE_DEVICE_TABLE(of, sprd_efuse_of_match);
+
+ static struct platform_driver sprd_efuse_driver = {
+ .probe = sprd_efuse_probe,
diff --git a/target/linux/generic/backport-5.15/837-v6.10-0006-nvmem-core-switch-to-use-device_add_groups.patch b/target/linux/generic/backport-5.15/837-v6.10-0006-nvmem-core-switch-to-use-device_add_groups.patch
new file mode 100644
index 0000000000..07eb082296
--- /dev/null
+++ b/target/linux/generic/backport-5.15/837-v6.10-0006-nvmem-core-switch-to-use-device_add_groups.patch
@@ -0,0 +1,32 @@
+From 8d8fc146dd7a0d6a6b37695747a524310dfb9d57 Mon Sep 17 00:00:00 2001
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Date: Tue, 30 Apr 2024 09:49:16 +0100
+Subject: [PATCH] nvmem: core: switch to use device_add_groups()
+
+devm_device_add_groups() is being removed from the kernel, so move the
+nvmem driver to use device_add_groups() instead. The logic is
+identical, when the device is removed the driver core will properly
+clean up and remove the groups, and the memory used by the attribute
+groups will be freed because it was created with dev_* calls, so this is
+functionally identical overall.
+
+Cc: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Link: https://lore.kernel.org/r/20240430084921.33387-7-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/nvmem/core.c
++++ b/drivers/nvmem/core.c
+@@ -478,7 +478,7 @@ static int nvmem_populate_sysfs_cells(st
+
+ nvmem_cells_group.bin_attrs = cells_attrs;
+
+- ret = devm_device_add_groups(&nvmem->dev, nvmem_cells_groups);
++ ret = device_add_groups(&nvmem->dev, nvmem_cells_groups);
+ if (ret)
+ goto unlock_mutex;
+
diff --git a/target/linux/generic/backport-5.15/837-v6.10-0007-nvmem-lpc18xx_eeprom-Convert-to-platform-remove-call.patch b/target/linux/generic/backport-5.15/837-v6.10-0007-nvmem-lpc18xx_eeprom-Convert-to-platform-remove-call.patch
new file mode 100644
index 0000000000..27d9270d31
--- /dev/null
+++ b/target/linux/generic/backport-5.15/837-v6.10-0007-nvmem-lpc18xx_eeprom-Convert-to-platform-remove-call.patch
@@ -0,0 +1,57 @@
+From 693d2f629962628ddefc88f4b6b453edda5ac32e Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= <u.kleine-koenig@pengutronix.de>
+Date: Tue, 30 Apr 2024 09:49:17 +0100
+Subject: [PATCH] nvmem: lpc18xx_eeprom: Convert to platform remove callback
+ returning void
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The .remove() callback for a platform driver returns an int which makes
+many driver authors wrongly assume it's possible to do error handling by
+returning an error code. However the value returned is ignored (apart
+from emitting a warning) and this typically results in resource leaks.
+
+To improve here there is a quest to make the remove callback return
+void. In the first step of this quest all drivers are converted to
+.remove_new(), which already returns void. Eventually after all drivers
+are converted, .remove_new() will be renamed to .remove().
+
+Trivially convert this driver from always returning zero in the remove
+callback to the void returning variant.
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Acked-by: Vladimir Zapolskiy <vz@mleia.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240430084921.33387-8-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/lpc18xx_eeprom.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+--- a/drivers/nvmem/lpc18xx_eeprom.c
++++ b/drivers/nvmem/lpc18xx_eeprom.c
+@@ -249,13 +249,11 @@ err_clk:
+ return ret;
+ }
+
+-static int lpc18xx_eeprom_remove(struct platform_device *pdev)
++static void lpc18xx_eeprom_remove(struct platform_device *pdev)
+ {
+ struct lpc18xx_eeprom_dev *eeprom = platform_get_drvdata(pdev);
+
+ clk_disable_unprepare(eeprom->clk);
+-
+- return 0;
+ }
+
+ static const struct of_device_id lpc18xx_eeprom_of_match[] = {
+@@ -266,7 +264,7 @@ MODULE_DEVICE_TABLE(of, lpc18xx_eeprom_o
+
+ static struct platform_driver lpc18xx_eeprom_driver = {
+ .probe = lpc18xx_eeprom_probe,
+- .remove = lpc18xx_eeprom_remove,
++ .remove_new = lpc18xx_eeprom_remove,
+ .driver = {
+ .name = "lpc18xx-eeprom",
+ .of_match_table = lpc18xx_eeprom_of_match,
diff --git a/target/linux/generic/backport-5.15/837-v6.10-0008-nvmem-meson-mx-efuse-Remove-nvmem_device-from-efuse-.patch b/target/linux/generic/backport-5.15/837-v6.10-0008-nvmem-meson-mx-efuse-Remove-nvmem_device-from-efuse-.patch
new file mode 100644
index 0000000000..7770052d97
--- /dev/null
+++ b/target/linux/generic/backport-5.15/837-v6.10-0008-nvmem-meson-mx-efuse-Remove-nvmem_device-from-efuse-.patch
@@ -0,0 +1,50 @@
+From 2a1ad6b75292d38aa2f6ded7335979e0632521da Mon Sep 17 00:00:00 2001
+From: Mukesh Ojha <quic_mojha@quicinc.com>
+Date: Tue, 30 Apr 2024 09:49:21 +0100
+Subject: [PATCH] nvmem: meson-mx-efuse: Remove nvmem_device from efuse struct
+
+nvmem_device is used at one place while registering nvmem
+device and it is not required to be present in efuse struct
+for just this purpose.
+
+Drop nvmem_device and manage with nvmem device stack variable.
+
+Signed-off-by: Mukesh Ojha <quic_mojha@quicinc.com>
+Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240430084921.33387-12-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/meson-mx-efuse.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/nvmem/meson-mx-efuse.c
++++ b/drivers/nvmem/meson-mx-efuse.c
+@@ -44,7 +44,6 @@ struct meson_mx_efuse_platform_data {
+ struct meson_mx_efuse {
+ void __iomem *base;
+ struct clk *core_clk;
+- struct nvmem_device *nvmem;
+ struct nvmem_config config;
+ };
+
+@@ -194,6 +193,7 @@ static int meson_mx_efuse_probe(struct p
+ {
+ const struct meson_mx_efuse_platform_data *drvdata;
+ struct meson_mx_efuse *efuse;
++ struct nvmem_device *nvmem;
+
+ drvdata = of_device_get_match_data(&pdev->dev);
+ if (!drvdata)
+@@ -224,9 +224,9 @@ static int meson_mx_efuse_probe(struct p
+ return PTR_ERR(efuse->core_clk);
+ }
+
+- efuse->nvmem = devm_nvmem_register(&pdev->dev, &efuse->config);
++ nvmem = devm_nvmem_register(&pdev->dev, &efuse->config);
+
+- return PTR_ERR_OR_ZERO(efuse->nvmem);
++ return PTR_ERR_OR_ZERO(nvmem);
+ }
+
+ static struct platform_driver meson_mx_efuse_driver = {
diff --git a/target/linux/generic/backport-5.15/837-v6.10-0009-nvmem-rmem-Fix-return-value-of-rmem_read.patch b/target/linux/generic/backport-5.15/837-v6.10-0009-nvmem-rmem-Fix-return-value-of-rmem_read.patch
new file mode 100644
index 0000000000..0f0f68b4d7
--- /dev/null
+++ b/target/linux/generic/backport-5.15/837-v6.10-0009-nvmem-rmem-Fix-return-value-of-rmem_read.patch
@@ -0,0 +1,42 @@
+From 28b008751aa295612318a0fbb2f22dd4f6a83139 Mon Sep 17 00:00:00 2001
+From: Joy Chakraborty <joychakr@google.com>
+Date: Fri, 28 Jun 2024 12:37:01 +0100
+Subject: [PATCH] nvmem: rmem: Fix return value of rmem_read()
+
+reg_read() callback registered with nvmem core expects 0 on success and
+a negative value on error but rmem_read() returns the number of bytes
+read which is treated as an error at the nvmem core.
+
+This does not break when rmem is accessed using sysfs via
+bin_attr_nvmem_read()/write() but causes an error when accessed from
+places like nvmem_access_with_keepouts(), etc.
+
+Change to return 0 on success and error in case
+memory_read_from_buffer() returns an error or -EIO if bytes read do not
+match what was requested.
+
+Fixes: 5a3fa75a4d9c ("nvmem: Add driver to expose reserved memory as nvmem")
+Cc: stable@vger.kernel.org
+Signed-off-by: Joy Chakraborty <joychakr@google.com>
+Reviewed-by: Dan Carpenter <dan.carpenter@linaro.org>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240628113704.13742-2-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/rmem.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/drivers/nvmem/rmem.c
++++ b/drivers/nvmem/rmem.c
+@@ -46,7 +46,10 @@ static int rmem_read(void *context, unsi
+
+ memunmap(addr);
+
+- return count;
++ if (count < 0)
++ return count;
++
++ return count == bytes ? 0 : -EIO;
+ }
+
+ static int rmem_probe(struct platform_device *pdev)
diff --git a/target/linux/generic/backport-5.15/837-v6.10-0010-nvmem-meson-efuse-Fix-return-value-of-nvmem-callback.patch b/target/linux/generic/backport-5.15/837-v6.10-0010-nvmem-meson-efuse-Fix-return-value-of-nvmem-callback.patch
new file mode 100644
index 0000000000..9e5d6198b7
--- /dev/null
+++ b/target/linux/generic/backport-5.15/837-v6.10-0010-nvmem-meson-efuse-Fix-return-value-of-nvmem-callback.patch
@@ -0,0 +1,59 @@
+From 7a0a6d0a7c805f9380381f4deedffdf87b93f408 Mon Sep 17 00:00:00 2001
+From: Joy Chakraborty <joychakr@google.com>
+Date: Fri, 28 Jun 2024 12:37:02 +0100
+Subject: [PATCH] nvmem: meson-efuse: Fix return value of nvmem callbacks
+
+Read/write callbacks registered with nvmem core expect 0 to be returned
+on success and a negative value to be returned on failure.
+
+meson_efuse_read() and meson_efuse_write() call into
+meson_sm_call_read() and meson_sm_call_write() respectively which return
+the number of bytes read or written on success as per their api
+description.
+
+Fix to return error if meson_sm_call_read()/meson_sm_call_write()
+returns an error else return 0.
+
+Fixes: a29a63bdaf6f ("nvmem: meson-efuse: simplify read callback")
+Cc: stable@vger.kernel.org
+Signed-off-by: Joy Chakraborty <joychakr@google.com>
+Reviewed-by: Dan Carpenter <dan.carpenter@linaro.org>
+Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240628113704.13742-3-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/meson-efuse.c | 14 ++++++++++----
+ 1 file changed, 10 insertions(+), 4 deletions(-)
+
+--- a/drivers/nvmem/meson-efuse.c
++++ b/drivers/nvmem/meson-efuse.c
+@@ -18,18 +18,24 @@ static int meson_efuse_read(void *contex
+ void *val, size_t bytes)
+ {
+ struct meson_sm_firmware *fw = context;
++ int ret;
+
+- return meson_sm_call_read(fw, (u8 *)val, bytes, SM_EFUSE_READ, offset,
+- bytes, 0, 0, 0);
++ ret = meson_sm_call_read(fw, (u8 *)val, bytes, SM_EFUSE_READ, offset,
++ bytes, 0, 0, 0);
++
++ return ret < 0 ? ret : 0;
+ }
+
+ static int meson_efuse_write(void *context, unsigned int offset,
+ void *val, size_t bytes)
+ {
+ struct meson_sm_firmware *fw = context;
++ int ret;
++
++ ret = meson_sm_call_write(fw, (u8 *)val, bytes, SM_EFUSE_WRITE, offset,
++ bytes, 0, 0, 0);
+
+- return meson_sm_call_write(fw, (u8 *)val, bytes, SM_EFUSE_WRITE, offset,
+- bytes, 0, 0, 0);
++ return ret < 0 ? ret : 0;
+ }
+
+ static const struct of_device_id meson_efuse_match[] = {
diff --git a/target/linux/generic/backport-5.15/837-v6.10-0011-nvmem-core-only-change-name-to-fram-for-current-attr.patch b/target/linux/generic/backport-5.15/837-v6.10-0011-nvmem-core-only-change-name-to-fram-for-current-attr.patch
new file mode 100644
index 0000000000..064a44999b
--- /dev/null
+++ b/target/linux/generic/backport-5.15/837-v6.10-0011-nvmem-core-only-change-name-to-fram-for-current-attr.patch
@@ -0,0 +1,39 @@
+From 0ba424c934fd43dccf0d597e1ae8851f07cb2edf Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= <linux@weissschuh.net>
+Date: Fri, 28 Jun 2024 12:37:03 +0100
+Subject: [PATCH] nvmem: core: only change name to fram for current attribute
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+bin_attr_nvmem_eeprom_compat is the template from which all future
+compat attributes are created.
+Changing it means to change all subsquent compat attributes, too.
+
+Instead only use the "fram" name for the currently registered attribute.
+
+Fixes: fd307a4ad332 ("nvmem: prepare basics for FRAM support")
+Cc: stable@vger.kernel.org
+Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240628113704.13742-4-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/core.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+--- a/drivers/nvmem/core.c
++++ b/drivers/nvmem/core.c
+@@ -397,10 +397,9 @@ static int nvmem_sysfs_setup_compat(stru
+ if (!config->base_dev)
+ return -EINVAL;
+
+- if (config->type == NVMEM_TYPE_FRAM)
+- bin_attr_nvmem_eeprom_compat.attr.name = "fram";
+-
+ nvmem->eeprom = bin_attr_nvmem_eeprom_compat;
++ if (config->type == NVMEM_TYPE_FRAM)
++ nvmem->eeprom.attr.name = "fram";
+ nvmem->eeprom.attr.mode = nvmem_bin_attr_get_umode(nvmem);
+ nvmem->eeprom.size = nvmem->size;
+ #ifdef CONFIG_DEBUG_LOCK_ALLOC
diff --git a/target/linux/generic/backport-5.15/837-v6.10-0012-nvmem-core-limit-cell-sysfs-permissions-to-main-attr.patch b/target/linux/generic/backport-5.15/837-v6.10-0012-nvmem-core-limit-cell-sysfs-permissions-to-main-attr.patch
new file mode 100644
index 0000000000..88453e83cc
--- /dev/null
+++ b/target/linux/generic/backport-5.15/837-v6.10-0012-nvmem-core-limit-cell-sysfs-permissions-to-main-attr.patch
@@ -0,0 +1,37 @@
+From 6bef98bafd82903a8d461463f9594f19f1fd6a85 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= <linux@weissschuh.net>
+Date: Fri, 28 Jun 2024 12:37:04 +0100
+Subject: [PATCH] nvmem: core: limit cell sysfs permissions to main attribute
+ ones
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The cell sysfs attribute should not provide more access to the nvmem
+data than the main attribute itself.
+For example if nvme_config::root_only was set, the cell attribute
+would still provide read access to everybody.
+
+Mask out permissions not available on the main attribute.
+
+Fixes: 0331c611949f ("nvmem: core: Expose cells through sysfs")
+Cc: stable@vger.kernel.org
+Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240628113704.13742-5-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/nvmem/core.c
++++ b/drivers/nvmem/core.c
+@@ -462,7 +462,7 @@ static int nvmem_populate_sysfs_cells(st
+ attrs[i].attr.name = devm_kasprintf(&nvmem->dev, GFP_KERNEL,
+ "%s@%x", entry->name,
+ entry->offset);
+- attrs[i].attr.mode = 0444;
++ attrs[i].attr.mode = 0444 & nvmem_bin_attr_get_umode(nvmem);
+ attrs[i].size = entry->bytes;
+ attrs[i].read = &nvmem_cell_attr_read;
+ attrs[i].private = entry;
diff --git a/target/linux/generic/backport-5.15/838-v6.11-0001-nvmem-add-missing-MODULE_DESCRIPTION-macros.patch b/target/linux/generic/backport-5.15/838-v6.11-0001-nvmem-add-missing-MODULE_DESCRIPTION-macros.patch
new file mode 100644
index 0000000000..a8ce832408
--- /dev/null
+++ b/target/linux/generic/backport-5.15/838-v6.11-0001-nvmem-add-missing-MODULE_DESCRIPTION-macros.patch
@@ -0,0 +1,48 @@
+From c553bad4c5fc5ae44bd2fcaa73e1d6bedfb1c35c Mon Sep 17 00:00:00 2001
+From: Jeff Johnson <quic_jjohnson@quicinc.com>
+Date: Fri, 5 Jul 2024 08:48:38 +0100
+Subject: [PATCH] nvmem: add missing MODULE_DESCRIPTION() macros
+
+make allmodconfig && make W=1 C=1 reports:
+WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/nvmem/nvmem-apple-efuses.o
+WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/nvmem/nvmem_brcm_nvram.o
+WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/nvmem/nvmem_u-boot-env.o
+
+Add the missing invocations of the MODULE_DESCRIPTION() macro.
+
+Signed-off-by: Jeff Johnson <quic_jjohnson@quicinc.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240705074852.423202-2-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/apple-efuses.c | 1 +
+ drivers/nvmem/brcm_nvram.c | 1 +
+ drivers/nvmem/u-boot-env.c | 1 +
+ 3 files changed, 3 insertions(+)
+
+--- a/drivers/nvmem/apple-efuses.c
++++ b/drivers/nvmem/apple-efuses.c
+@@ -78,4 +78,5 @@ static struct platform_driver apple_efus
+ module_platform_driver(apple_efuses_driver);
+
+ MODULE_AUTHOR("Sven Peter <sven@svenpeter.dev>");
++MODULE_DESCRIPTION("Apple SoC eFuse driver");
+ MODULE_LICENSE("GPL");
+--- a/drivers/nvmem/brcm_nvram.c
++++ b/drivers/nvmem/brcm_nvram.c
+@@ -253,5 +253,6 @@ static int __init brcm_nvram_init(void)
+ subsys_initcall_sync(brcm_nvram_init);
+
+ MODULE_AUTHOR("Rafał Miłecki");
++MODULE_DESCRIPTION("Broadcom I/O-mapped NVRAM support driver");
+ MODULE_LICENSE("GPL");
+ MODULE_DEVICE_TABLE(of, brcm_nvram_of_match_table);
+--- a/drivers/nvmem/u-boot-env.c
++++ b/drivers/nvmem/u-boot-env.c
+@@ -249,5 +249,6 @@ static struct platform_driver u_boot_env
+ module_platform_driver(u_boot_env_driver);
+
+ MODULE_AUTHOR("Rafał Miłecki");
++MODULE_DESCRIPTION("U-Boot environment variables support module");
+ MODULE_LICENSE("GPL");
+ MODULE_DEVICE_TABLE(of, u_boot_env_of_match_table);
diff --git a/target/linux/generic/backport-5.15/838-v6.11-0002-nvmem-meson-efuse-Replacing-the-use-of-of_node_put-t.patch b/target/linux/generic/backport-5.15/838-v6.11-0002-nvmem-meson-efuse-Replacing-the-use-of-of_node_put-t.patch
new file mode 100644
index 0000000000..05c82dbf6f
--- /dev/null
+++ b/target/linux/generic/backport-5.15/838-v6.11-0002-nvmem-meson-efuse-Replacing-the-use-of-of_node_put-t.patch
@@ -0,0 +1,48 @@
+From 5fecb932607d83d37a703c731268e9d9051457f5 Mon Sep 17 00:00:00 2001
+From: MarileneGarcia <marilene.agarcia@gmail.com>
+Date: Fri, 5 Jul 2024 08:48:40 +0100
+Subject: [PATCH] nvmem: meson-efuse: Replacing the use of of_node_put to
+ __free
+
+Use __free for device_node values, and thus drop calls to
+of_node_put.
+
+The goal is to reduce memory management issues by using this
+scope-based of_node_put() cleanup to simplify function exit
+handling. When using __free a resource is allocated within a
+block, it is automatically freed at the end of the block.
+
+Suggested-by: Julia Lawall <julia.lawall@inria.fr>
+Signed-off-by: MarileneGarcia <marilene.agarcia@gmail.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240705074852.423202-4-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/meson-efuse.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+--- a/drivers/nvmem/meson-efuse.c
++++ b/drivers/nvmem/meson-efuse.c
+@@ -48,20 +48,19 @@ static int meson_efuse_probe(struct plat
+ {
+ struct device *dev = &pdev->dev;
+ struct meson_sm_firmware *fw;
+- struct device_node *sm_np;
+ struct nvmem_device *nvmem;
+ struct nvmem_config *econfig;
+ struct clk *clk;
+ unsigned int size;
++ struct device_node *sm_np __free(device_node) =
++ of_parse_phandle(pdev->dev.of_node, "secure-monitor", 0);
+
+- sm_np = of_parse_phandle(pdev->dev.of_node, "secure-monitor", 0);
+ if (!sm_np) {
+ dev_err(&pdev->dev, "no secure-monitor node\n");
+ return -ENODEV;
+ }
+
+ fw = meson_sm_get(sm_np);
+- of_node_put(sm_np);
+ if (!fw)
+ return -EPROBE_DEFER;
+
diff --git a/target/linux/generic/backport-5.15/838-v6.11-0003-nvmem-rockchip-otp-set-add_legacy_fixed_of_cells-con.patch b/target/linux/generic/backport-5.15/838-v6.11-0003-nvmem-rockchip-otp-set-add_legacy_fixed_of_cells-con.patch
new file mode 100644
index 0000000000..a8a30fc810
--- /dev/null
+++ b/target/linux/generic/backport-5.15/838-v6.11-0003-nvmem-rockchip-otp-set-add_legacy_fixed_of_cells-con.patch
@@ -0,0 +1,28 @@
+From 2933e79db3c00a8cdc56f6bb050a857fec1875ad Mon Sep 17 00:00:00 2001
+From: Heiko Stuebner <heiko.stuebner@cherry.de>
+Date: Fri, 5 Jul 2024 08:48:41 +0100
+Subject: [PATCH] nvmem: rockchip-otp: set add_legacy_fixed_of_cells config
+ option
+
+The Rockchip OTP describes its layout via devicetree subnodes,
+so set the appropriate property.
+
+Fixes: 2cc3b37f5b6d ("nvmem: add explicit config option to read old syntax fixed OF cells")
+Signed-off-by: Heiko Stuebner <heiko.stuebner@cherry.de>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240705074852.423202-5-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/rockchip-otp.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/nvmem/rockchip-otp.c
++++ b/drivers/nvmem/rockchip-otp.c
+@@ -255,6 +255,7 @@ static int rockchip_otp_read(void *conte
+ static struct nvmem_config otp_config = {
+ .name = "rockchip-otp",
+ .owner = THIS_MODULE,
++ .add_legacy_fixed_of_cells = true,
+ .read_only = true,
+ .stride = 1,
+ .word_size = 1,
diff --git a/target/linux/generic/backport-5.15/838-v6.11-0004-nvmem-rockchip-otp-Set-type-to-OTP.patch b/target/linux/generic/backport-5.15/838-v6.11-0004-nvmem-rockchip-otp-Set-type-to-OTP.patch
new file mode 100644
index 0000000000..8491eb3c9c
--- /dev/null
+++ b/target/linux/generic/backport-5.15/838-v6.11-0004-nvmem-rockchip-otp-Set-type-to-OTP.patch
@@ -0,0 +1,25 @@
+From 39f95600d8c53355b212a117e91a6ba15e0cac47 Mon Sep 17 00:00:00 2001
+From: Heiko Stuebner <heiko.stuebner@cherry.de>
+Date: Fri, 5 Jul 2024 08:48:42 +0100
+Subject: [PATCH] nvmem: rockchip-otp: Set type to OTP
+
+The Rockchip OTP is obviously an OTP memory, so document this fact.
+
+Signed-off-by: Heiko Stuebner <heiko.stuebner@cherry.de>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240705074852.423202-6-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/rockchip-otp.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/nvmem/rockchip-otp.c
++++ b/drivers/nvmem/rockchip-otp.c
+@@ -256,6 +256,7 @@ static struct nvmem_config otp_config =
+ .name = "rockchip-otp",
+ .owner = THIS_MODULE,
+ .add_legacy_fixed_of_cells = true,
++ .type = NVMEM_TYPE_OTP,
+ .read_only = true,
+ .stride = 1,
+ .word_size = 1,
diff --git a/target/linux/generic/backport-5.15/838-v6.11-0005-nvmem-rockchip-efuse-set-type-to-OTP.patch b/target/linux/generic/backport-5.15/838-v6.11-0005-nvmem-rockchip-efuse-set-type-to-OTP.patch
new file mode 100644
index 0000000000..260b03eb03
--- /dev/null
+++ b/target/linux/generic/backport-5.15/838-v6.11-0005-nvmem-rockchip-efuse-set-type-to-OTP.patch
@@ -0,0 +1,26 @@
+From ba64a04474d2989f397982c48e405cfd785e2dd5 Mon Sep 17 00:00:00 2001
+From: Heiko Stuebner <heiko.stuebner@cherry.de>
+Date: Fri, 5 Jul 2024 08:48:43 +0100
+Subject: [PATCH] nvmem: rockchip-efuse: set type to OTP
+
+This device currently reports an "Unknown" type in sysfs.
+Since it is an eFuse hardware device, set its type to OTP.
+
+Signed-off-by: Heiko Stuebner <heiko.stuebner@cherry.de>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240705074852.423202-7-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/rockchip-efuse.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/nvmem/rockchip-efuse.c
++++ b/drivers/nvmem/rockchip-efuse.c
+@@ -206,6 +206,7 @@ static int rockchip_rk3399_efuse_read(vo
+ static struct nvmem_config econfig = {
+ .name = "rockchip-efuse",
+ .add_legacy_fixed_of_cells = true,
++ .type = NVMEM_TYPE_OTP,
+ .stride = 1,
+ .word_size = 1,
+ .read_only = true,
diff --git a/target/linux/generic/backport-5.15/838-v6.11-0006-nvmem-core-add-single-sysfs-group.patch b/target/linux/generic/backport-5.15/838-v6.11-0006-nvmem-core-add-single-sysfs-group.patch
new file mode 100644
index 0000000000..4fb2afd2fa
--- /dev/null
+++ b/target/linux/generic/backport-5.15/838-v6.11-0006-nvmem-core-add-single-sysfs-group.patch
@@ -0,0 +1,42 @@
+From 6188f233161c6a5b2d1c396a221dfafc77dc9eec Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= <linux@weissschuh.net>
+Date: Fri, 5 Jul 2024 08:48:46 +0100
+Subject: [PATCH] nvmem: core: add single sysfs group
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The sysfs core provides a function to easily register a single group.
+Use it and remove the now unnecessary nvmem_cells_groups array.
+
+Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240705074852.423202-10-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/core.c | 7 +------
+ 1 file changed, 1 insertion(+), 6 deletions(-)
+
+--- a/drivers/nvmem/core.c
++++ b/drivers/nvmem/core.c
+@@ -368,11 +368,6 @@ static const struct attribute_group *nvm
+ NULL,
+ };
+
+-static const struct attribute_group *nvmem_cells_groups[] = {
+- &nvmem_cells_group,
+- NULL,
+-};
+-
+ static struct bin_attribute bin_attr_nvmem_eeprom_compat = {
+ .attr = {
+ .name = "eeprom",
+@@ -477,7 +472,7 @@ static int nvmem_populate_sysfs_cells(st
+
+ nvmem_cells_group.bin_attrs = cells_attrs;
+
+- ret = device_add_groups(&nvmem->dev, nvmem_cells_groups);
++ ret = device_add_group(&nvmem->dev, &nvmem_cells_group);
+ if (ret)
+ goto unlock_mutex;
+
diff --git a/target/linux/generic/backport-5.15/838-v6.11-0007-nvmem-core-remove-global-nvmem_cells_group.patch b/target/linux/generic/backport-5.15/838-v6.11-0007-nvmem-core-remove-global-nvmem_cells_group.patch
new file mode 100644
index 0000000000..ef626d37a0
--- /dev/null
+++ b/target/linux/generic/backport-5.15/838-v6.11-0007-nvmem-core-remove-global-nvmem_cells_group.patch
@@ -0,0 +1,83 @@
+From 6839fed062b7898665983368c88269a6fb1fc10f Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= <linux@weissschuh.net>
+Date: Fri, 5 Jul 2024 08:48:47 +0100
+Subject: [PATCH] nvmem: core: remove global nvmem_cells_group
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+nvmem_cells_groups is a global variable that is also mutated.
+This is complicated and error-prone.
+
+Instead use a normal stack variable.
+
+Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240705074852.423202-11-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/core.c | 26 ++++++++++----------------
+ 1 file changed, 10 insertions(+), 16 deletions(-)
+
+--- a/drivers/nvmem/core.c
++++ b/drivers/nvmem/core.c
+@@ -358,11 +358,6 @@ static const struct attribute_group nvme
+ .is_bin_visible = nvmem_bin_attr_is_visible,
+ };
+
+-/* Cell attributes will be dynamically allocated */
+-static struct attribute_group nvmem_cells_group = {
+- .name = "cells",
+-};
+-
+ static const struct attribute_group *nvmem_dev_groups[] = {
+ &nvmem_bin_group,
+ NULL,
+@@ -424,23 +419,24 @@ static void nvmem_sysfs_remove_compat(st
+
+ static int nvmem_populate_sysfs_cells(struct nvmem_device *nvmem)
+ {
+- struct bin_attribute **cells_attrs, *attrs;
++ struct attribute_group group = {
++ .name = "cells",
++ };
+ struct nvmem_cell_entry *entry;
++ struct bin_attribute *attrs;
+ unsigned int ncells = 0, i = 0;
+ int ret = 0;
+
+ mutex_lock(&nvmem_mutex);
+
+- if (list_empty(&nvmem->cells) || nvmem->sysfs_cells_populated) {
+- nvmem_cells_group.bin_attrs = NULL;
++ if (list_empty(&nvmem->cells) || nvmem->sysfs_cells_populated)
+ goto unlock_mutex;
+- }
+
+ /* Allocate an array of attributes with a sentinel */
+ ncells = list_count_nodes(&nvmem->cells);
+- cells_attrs = devm_kcalloc(&nvmem->dev, ncells + 1,
+- sizeof(struct bin_attribute *), GFP_KERNEL);
+- if (!cells_attrs) {
++ group.bin_attrs = devm_kcalloc(&nvmem->dev, ncells + 1,
++ sizeof(struct bin_attribute *), GFP_KERNEL);
++ if (!group.bin_attrs) {
+ ret = -ENOMEM;
+ goto unlock_mutex;
+ }
+@@ -466,13 +462,11 @@ static int nvmem_populate_sysfs_cells(st
+ goto unlock_mutex;
+ }
+
+- cells_attrs[i] = &attrs[i];
++ group.bin_attrs[i] = &attrs[i];
+ i++;
+ }
+
+- nvmem_cells_group.bin_attrs = cells_attrs;
+-
+- ret = device_add_group(&nvmem->dev, &nvmem_cells_group);
++ ret = device_add_group(&nvmem->dev, &group);
+ if (ret)
+ goto unlock_mutex;
+
diff --git a/target/linux/generic/backport-5.15/838-v6.11-0008-nvmem-core-drop-unnecessary-range-checks-in-sysfs-ca.patch b/target/linux/generic/backport-5.15/838-v6.11-0008-nvmem-core-drop-unnecessary-range-checks-in-sysfs-ca.patch
new file mode 100644
index 0000000000..9b6251b919
--- /dev/null
+++ b/target/linux/generic/backport-5.15/838-v6.11-0008-nvmem-core-drop-unnecessary-range-checks-in-sysfs-ca.patch
@@ -0,0 +1,61 @@
+From 588773802c386d38f9c4e91acd47369e89d95a30 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= <linux@weissschuh.net>
+Date: Fri, 5 Jul 2024 08:48:48 +0100
+Subject: [PATCH] nvmem: core: drop unnecessary range checks in sysfs callbacks
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The same checks have already been done in sysfs_kf_bin_write() and
+sysfs_kf_bin_read() just before the callbacks are invoked.
+
+Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240705074852.423202-12-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/core.c | 14 --------------
+ 1 file changed, 14 deletions(-)
+
+--- a/drivers/nvmem/core.c
++++ b/drivers/nvmem/core.c
+@@ -204,19 +204,12 @@ static ssize_t bin_attr_nvmem_read(struc
+ dev = kobj_to_dev(kobj);
+ nvmem = to_nvmem_device(dev);
+
+- /* Stop the user from reading */
+- if (pos >= nvmem->size)
+- return 0;
+-
+ if (!IS_ALIGNED(pos, nvmem->stride))
+ return -EINVAL;
+
+ if (count < nvmem->word_size)
+ return -EINVAL;
+
+- if (pos + count > nvmem->size)
+- count = nvmem->size - pos;
+-
+ count = round_down(count, nvmem->word_size);
+
+ if (!nvmem->reg_read)
+@@ -244,19 +237,12 @@ static ssize_t bin_attr_nvmem_write(stru
+ dev = kobj_to_dev(kobj);
+ nvmem = to_nvmem_device(dev);
+
+- /* Stop the user from writing */
+- if (pos >= nvmem->size)
+- return -EFBIG;
+-
+ if (!IS_ALIGNED(pos, nvmem->stride))
+ return -EINVAL;
+
+ if (count < nvmem->word_size)
+ return -EINVAL;
+
+- if (pos + count > nvmem->size)
+- count = nvmem->size - pos;
+-
+ count = round_down(count, nvmem->word_size);
+
+ if (!nvmem->reg_write)
diff --git a/target/linux/generic/backport-5.15/838-v6.11-0009-nvmem-Use-sysfs_emit-for-type-attribute.patch b/target/linux/generic/backport-5.15/838-v6.11-0009-nvmem-Use-sysfs_emit-for-type-attribute.patch
new file mode 100644
index 0000000000..3da1febaf1
--- /dev/null
+++ b/target/linux/generic/backport-5.15/838-v6.11-0009-nvmem-Use-sysfs_emit-for-type-attribute.patch
@@ -0,0 +1,30 @@
+From 08c367e45b6d322956878774f0b88bf5e52c6d54 Mon Sep 17 00:00:00 2001
+From: Marek Vasut <marex@denx.de>
+Date: Fri, 5 Jul 2024 08:48:51 +0100
+Subject: [PATCH] nvmem: Use sysfs_emit() for type attribute
+
+Use sysfs_emit() instead of sprintf() to follow best practice per
+Documentation/filesystems/sysfs.rst
+"
+show() should only use sysfs_emit()...
+"
+
+Signed-off-by: Marek Vasut <marex@denx.de>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240705074852.423202-15-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/nvmem/core.c
++++ b/drivers/nvmem/core.c
+@@ -180,7 +180,7 @@ static ssize_t type_show(struct device *
+ {
+ struct nvmem_device *nvmem = to_nvmem_device(dev);
+
+- return sprintf(buf, "%s\n", nvmem_type_str[nvmem->type]);
++ return sysfs_emit(buf, "%s\n", nvmem_type_str[nvmem->type]);
+ }
+
+ static DEVICE_ATTR_RO(type);
diff --git a/target/linux/generic/backport-5.15/838-v6.11-0010-nvmem-core-Implement-force_ro-sysfs-attribute.patch b/target/linux/generic/backport-5.15/838-v6.11-0010-nvmem-core-Implement-force_ro-sysfs-attribute.patch
new file mode 100644
index 0000000000..ac7dda1bdf
--- /dev/null
+++ b/target/linux/generic/backport-5.15/838-v6.11-0010-nvmem-core-Implement-force_ro-sysfs-attribute.patch
@@ -0,0 +1,122 @@
+From 9d7eb234ac7a56b88aea8a52ed81553a730fe25c Mon Sep 17 00:00:00 2001
+From: Marek Vasut <marex@denx.de>
+Date: Fri, 5 Jul 2024 08:48:52 +0100
+Subject: [PATCH] nvmem: core: Implement force_ro sysfs attribute
+
+Implement "force_ro" sysfs attribute to allow users to set read-write
+devices as read-only and back to read-write from userspace. The choice
+of the name is based on MMC core 'force_ro' attribute.
+
+This solves a situation where an AT24 I2C EEPROM with GPIO based nWP
+signal may have to be occasionally updated. Such I2C EEPROM device is
+usually set as read-only during most of the regular system operation,
+but in case it has to be updated in a controlled manner, it could be
+unlocked using this new "force_ro" sysfs attribute and then re-locked
+again.
+
+The "read-only" DT property and config->read_only configuration is
+respected and is used to set default state of the device, read-only
+or read-write, for devices which do implement .reg_write function.
+For devices which do not implement .reg_write function, the device
+is unconditionally read-only and the "force_ro" attribute is not
+visible.
+
+Signed-off-by: Marek Vasut <marex@denx.de>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240705074852.423202-16-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ Documentation/ABI/stable/sysfs-bus-nvmem | 17 ++++++++++
+ drivers/nvmem/core.c | 43 ++++++++++++++++++++++++
+ 2 files changed, 60 insertions(+)
+
+--- a/Documentation/ABI/stable/sysfs-bus-nvmem
++++ b/Documentation/ABI/stable/sysfs-bus-nvmem
+@@ -1,3 +1,20 @@
++What: /sys/bus/nvmem/devices/.../force_ro
++Date: June 2024
++KernelVersion: 6.11
++Contact: Marek Vasut <marex@denx.de>
++Description:
++ This read/write attribute allows users to set read-write
++ devices as read-only and back to read-write from userspace.
++ This can be used to unlock and relock write-protection of
++ devices which are generally locked, except during sporadic
++ programming operation.
++ Read returns '0' or '1' for read-write or read-only modes
++ respectively.
++ Write parses one of 'YyTt1NnFf0', or [oO][NnFf] for "on"
++ and "off", i.e. what kstrbool() supports.
++ Note: This file is only present if CONFIG_NVMEM_SYSFS
++ is enabled.
++
+ What: /sys/bus/nvmem/devices/.../nvmem
+ Date: July 2015
+ KernelVersion: 4.2
+--- a/drivers/nvmem/core.c
++++ b/drivers/nvmem/core.c
+@@ -185,7 +185,30 @@ static ssize_t type_show(struct device *
+
+ static DEVICE_ATTR_RO(type);
+
++static ssize_t force_ro_show(struct device *dev, struct device_attribute *attr,
++ char *buf)
++{
++ struct nvmem_device *nvmem = to_nvmem_device(dev);
++
++ return sysfs_emit(buf, "%d\n", nvmem->read_only);
++}
++
++static ssize_t force_ro_store(struct device *dev, struct device_attribute *attr,
++ const char *buf, size_t count)
++{
++ struct nvmem_device *nvmem = to_nvmem_device(dev);
++ int ret = kstrtobool(buf, &nvmem->read_only);
++
++ if (ret < 0)
++ return ret;
++
++ return count;
++}
++
++static DEVICE_ATTR_RW(force_ro);
++
+ static struct attribute *nvmem_attrs[] = {
++ &dev_attr_force_ro.attr,
+ &dev_attr_type.attr,
+ NULL,
+ };
+@@ -286,6 +309,25 @@ static umode_t nvmem_bin_attr_is_visible
+ return nvmem_bin_attr_get_umode(nvmem);
+ }
+
++static umode_t nvmem_attr_is_visible(struct kobject *kobj,
++ struct attribute *attr, int i)
++{
++ struct device *dev = kobj_to_dev(kobj);
++ struct nvmem_device *nvmem = to_nvmem_device(dev);
++
++ /*
++ * If the device has no .reg_write operation, do not allow
++ * configuration as read-write.
++ * If the device is set as read-only by configuration, it
++ * can be forced into read-write mode using the 'force_ro'
++ * attribute.
++ */
++ if (attr == &dev_attr_force_ro.attr && !nvmem->reg_write)
++ return 0; /* Attribute not visible */
++
++ return attr->mode;
++}
++
+ static struct nvmem_cell *nvmem_create_cell(struct nvmem_cell_entry *entry,
+ const char *id, int index);
+
+@@ -342,6 +384,7 @@ static const struct attribute_group nvme
+ .bin_attrs = nvmem_bin_attributes,
+ .attrs = nvmem_attrs,
+ .is_bin_visible = nvmem_bin_attr_is_visible,
++ .is_visible = nvmem_attr_is_visible,
+ };
+
+ static const struct attribute_group *nvmem_dev_groups[] = {
diff --git a/target/linux/generic/backport-5.15/838-v6.11-0011-nvmem-u-boot-env-error-if-NVMEM-device-is-too-small.patch b/target/linux/generic/backport-5.15/838-v6.11-0011-nvmem-u-boot-env-error-if-NVMEM-device-is-too-small.patch
new file mode 100644
index 0000000000..70d420f205
--- /dev/null
+++ b/target/linux/generic/backport-5.15/838-v6.11-0011-nvmem-u-boot-env-error-if-NVMEM-device-is-too-small.patch
@@ -0,0 +1,40 @@
+From 8679e8b4a1ebdb40c4429e49368d29353e07b601 Mon Sep 17 00:00:00 2001
+From: John Thomson <git@johnthomson.fastmail.com.au>
+Date: Mon, 2 Sep 2024 15:25:08 +0100
+Subject: [PATCH] nvmem: u-boot-env: error if NVMEM device is too small
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Verify data size before trying to parse it to avoid reading out of
+buffer. This could happen in case of problems at MTD level or invalid DT
+bindings.
+
+Signed-off-by: John Thomson <git@johnthomson.fastmail.com.au>
+Cc: stable <stable@kernel.org>
+Fixes: d5542923f200 ("nvmem: add driver handling U-Boot environment variables")
+[rmilecki: simplify commit description & rebase]
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240902142510.71096-2-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/u-boot-env.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/drivers/nvmem/u-boot-env.c
++++ b/drivers/nvmem/u-boot-env.c
+@@ -176,6 +176,13 @@ static int u_boot_env_parse(struct u_boo
+ data_offset = offsetof(struct u_boot_env_image_broadcom, data);
+ break;
+ }
++
++ if (dev_size < data_offset) {
++ dev_err(dev, "Device too small for u-boot-env\n");
++ err = -EIO;
++ goto err_kfree;
++ }
++
+ crc32_addr = (__le32 *)(buf + crc32_offset);
+ crc32 = le32_to_cpu(*crc32_addr);
+ crc32_data_len = dev_size - crc32_data_offset;
diff --git a/target/linux/generic/backport-5.15/838-v6.11-0012-nvmem-Fix-return-type-of-devm_nvmem_device_get-in-ke.patch b/target/linux/generic/backport-5.15/838-v6.11-0012-nvmem-Fix-return-type-of-devm_nvmem_device_get-in-ke.patch
new file mode 100644
index 0000000000..08f6278849
--- /dev/null
+++ b/target/linux/generic/backport-5.15/838-v6.11-0012-nvmem-Fix-return-type-of-devm_nvmem_device_get-in-ke.patch
@@ -0,0 +1,37 @@
+From c69f37f6559a8948d70badd2b179db7714dedd62 Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+Date: Mon, 2 Sep 2024 15:25:09 +0100
+Subject: [PATCH] nvmem: Fix return type of devm_nvmem_device_get() in
+ kerneldoc
+
+devm_nvmem_device_get() returns an nvmem device, not an nvmem cell.
+
+Fixes: e2a5402ec7c6d044 ("nvmem: Add nvmem_device based consumer apis.")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240902142510.71096-3-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/core.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/nvmem/core.c
++++ b/drivers/nvmem/core.c
+@@ -1276,13 +1276,13 @@ void nvmem_device_put(struct nvmem_devic
+ EXPORT_SYMBOL_GPL(nvmem_device_put);
+
+ /**
+- * devm_nvmem_device_get() - Get nvmem cell of device form a given id
++ * devm_nvmem_device_get() - Get nvmem device of device form a given id
+ *
+ * @dev: Device that requests the nvmem device.
+ * @id: name id for the requested nvmem device.
+ *
+- * Return: ERR_PTR() on error or a valid pointer to a struct nvmem_cell
+- * on success. The nvmem_cell will be freed by the automatically once the
++ * Return: ERR_PTR() on error or a valid pointer to a struct nvmem_device
++ * on success. The nvmem_device will be freed by the automatically once the
+ * device is freed.
+ */
+ struct nvmem_device *devm_nvmem_device_get(struct device *dev, const char *id)
diff --git a/target/linux/generic/backport-5.15/839-v6.12-0001-nvmem-imx-ocotp-ele-support-i.MX95.patch b/target/linux/generic/backport-5.15/839-v6.12-0001-nvmem-imx-ocotp-ele-support-i.MX95.patch
new file mode 100644
index 0000000000..c19931b3fa
--- /dev/null
+++ b/target/linux/generic/backport-5.15/839-v6.12-0001-nvmem-imx-ocotp-ele-support-i.MX95.patch
@@ -0,0 +1,73 @@
+From c3f9b7b4e5f9de319d00784577cda42036ff243a Mon Sep 17 00:00:00 2001
+From: Peng Fan <peng.fan@nxp.com>
+Date: Mon, 2 Sep 2024 15:29:45 +0100
+Subject: [PATCH] nvmem: imx-ocotp-ele: support i.MX95
+
+i.MX95 OCOTP has same accessing method, so add an entry for i.MX95, but
+some fuse has ECC feature, so only read out the lower 16bits for ECC fuses.
+
+Signed-off-by: Peng Fan <peng.fan@nxp.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240902142952.71639-3-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/imx-ocotp-ele.c | 32 +++++++++++++++++++++++++++++---
+ 1 file changed, 29 insertions(+), 3 deletions(-)
+
+--- a/drivers/nvmem/imx-ocotp-ele.c
++++ b/drivers/nvmem/imx-ocotp-ele.c
+@@ -14,8 +14,9 @@
+ #include <linux/slab.h>
+
+ enum fuse_type {
+- FUSE_FSB = 1,
+- FUSE_ELE = 2,
++ FUSE_FSB = BIT(0),
++ FUSE_ELE = BIT(1),
++ FUSE_ECC = BIT(2),
+ FUSE_INVALID = -1
+ };
+
+@@ -93,7 +94,10 @@ static int imx_ocotp_reg_read(void *cont
+ continue;
+ }
+
+- *buf++ = readl_relaxed(reg + (i << 2));
++ if (type & FUSE_ECC)
++ *buf++ = readl_relaxed(reg + (i << 2)) & GENMASK(15, 0);
++ else
++ *buf++ = readl_relaxed(reg + (i << 2));
+ }
+
+ memcpy(val, (u8 *)p, bytes);
+@@ -155,8 +159,30 @@ static const struct ocotp_devtype_data i
+ },
+ };
+
++static const struct ocotp_devtype_data imx95_ocotp_data = {
++ .reg_off = 0x8000,
++ .reg_read = imx_ocotp_reg_read,
++ .size = 2048,
++ .num_entry = 12,
++ .entry = {
++ { 0, 1, FUSE_FSB | FUSE_ECC },
++ { 7, 1, FUSE_FSB | FUSE_ECC },
++ { 9, 3, FUSE_FSB | FUSE_ECC },
++ { 12, 24, FUSE_FSB },
++ { 36, 2, FUSE_FSB | FUSE_ECC },
++ { 38, 14, FUSE_FSB },
++ { 63, 1, FUSE_ELE },
++ { 128, 16, FUSE_ELE },
++ { 188, 1, FUSE_ELE },
++ { 317, 2, FUSE_FSB | FUSE_ECC },
++ { 320, 7, FUSE_FSB },
++ { 328, 184, FUSE_FSB }
++ },
++};
++
+ static const struct of_device_id imx_ele_ocotp_dt_ids[] = {
+ { .compatible = "fsl,imx93-ocotp", .data = &imx93_ocotp_data, },
++ { .compatible = "fsl,imx95-ocotp", .data = &imx95_ocotp_data, },
+ {},
+ };
+ MODULE_DEVICE_TABLE(of, imx_ele_ocotp_dt_ids);
diff --git a/target/linux/generic/backport-5.15/839-v6.12-0002-nvmem-sunplus-ocotp-Use-devm_platform_ioremap_resour.patch b/target/linux/generic/backport-5.15/839-v6.12-0002-nvmem-sunplus-ocotp-Use-devm_platform_ioremap_resour.patch
new file mode 100644
index 0000000000..13ef50b157
--- /dev/null
+++ b/target/linux/generic/backport-5.15/839-v6.12-0002-nvmem-sunplus-ocotp-Use-devm_platform_ioremap_resour.patch
@@ -0,0 +1,44 @@
+From 98ee46391baf35987227236d0c3bb30ab6e758c8 Mon Sep 17 00:00:00 2001
+From: Zhang Zekun <zhangzekun11@huawei.com>
+Date: Mon, 2 Sep 2024 15:29:50 +0100
+Subject: [PATCH] nvmem: sunplus-ocotp: Use
+ devm_platform_ioremap_resource_byname() helper function
+
+platform_get_resource_byname() and devm_ioremap_resource() can be
+replaced by devm_platform_ioremap_resource_byname(), which can
+simplify the code logic a bit, No functional change here.
+
+Signed-off-by: Zhang Zekun <zhangzekun11@huawei.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240902142952.71639-8-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/sunplus-ocotp.c | 7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+--- a/drivers/nvmem/sunplus-ocotp.c
++++ b/drivers/nvmem/sunplus-ocotp.c
+@@ -159,7 +159,6 @@ static int sp_ocotp_probe(struct platfor
+ struct device *dev = &pdev->dev;
+ struct nvmem_device *nvmem;
+ struct sp_ocotp_priv *otp;
+- struct resource *res;
+ int ret;
+
+ otp = devm_kzalloc(dev, sizeof(*otp), GFP_KERNEL);
+@@ -168,13 +167,11 @@ static int sp_ocotp_probe(struct platfor
+
+ otp->dev = dev;
+
+- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hb_gpio");
+- otp->base[HB_GPIO] = devm_ioremap_resource(dev, res);
++ otp->base[HB_GPIO] = devm_platform_ioremap_resource_byname(pdev, "hb_gpio");
+ if (IS_ERR(otp->base[HB_GPIO]))
+ return PTR_ERR(otp->base[HB_GPIO]);
+
+- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "otprx");
+- otp->base[OTPRX] = devm_ioremap_resource(dev, res);
++ otp->base[OTPRX] = devm_platform_ioremap_resource_byname(pdev, "otprx");
+ if (IS_ERR(otp->base[OTPRX]))
+ return PTR_ERR(otp->base[OTPRX]);
+
diff --git a/target/linux/generic/backport-5.15/839-v6.12-0003-nvmem-layouts-add-U-Boot-env-layout.patch b/target/linux/generic/backport-5.15/839-v6.12-0003-nvmem-layouts-add-U-Boot-env-layout.patch
new file mode 100644
index 0000000000..138e602a54
--- /dev/null
+++ b/target/linux/generic/backport-5.15/839-v6.12-0003-nvmem-layouts-add-U-Boot-env-layout.patch
@@ -0,0 +1,515 @@
+From 5f15811286aff4664bf275a7ede64e1b8858151b Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
+Date: Mon, 2 Sep 2024 15:29:47 +0100
+Subject: [PATCH] nvmem: layouts: add U-Boot env layout
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+U-Boot environment variables are stored in a specific format. Actual
+data can be placed in various storage sources (MTD, UBI volume, EEPROM,
+NVRAM, etc.).
+
+Move all generic (NVMEM device independent) code from NVMEM device
+driver to an NVMEM layout driver. Then add a simple NVMEM layout code on
+top of it.
+
+This allows using NVMEM layout for parsing U-Boot env data stored in any
+kind of NVMEM device.
+
+The old NVMEM glue driver stays in place for handling bindings in the
+MTD context. To avoid code duplication it uses exported layout parsing
+function. Please note that handling MTD & NVMEM layout bindings may be
+refactored in the future.
+
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240902142952.71639-5-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ MAINTAINERS | 1 +
+ drivers/nvmem/Kconfig | 3 +-
+ drivers/nvmem/layouts/Kconfig | 11 ++
+ drivers/nvmem/layouts/Makefile | 1 +
+ drivers/nvmem/layouts/u-boot-env.c | 211 +++++++++++++++++++++++++++++
+ drivers/nvmem/layouts/u-boot-env.h | 15 ++
+ drivers/nvmem/u-boot-env.c | 165 +---------------------
+ 7 files changed, 242 insertions(+), 165 deletions(-)
+ create mode 100644 drivers/nvmem/layouts/u-boot-env.c
+ create mode 100644 drivers/nvmem/layouts/u-boot-env.h
+
+--- a/drivers/nvmem/Kconfig
++++ b/drivers/nvmem/Kconfig
+@@ -363,8 +363,7 @@ config NVMEM_SUNXI_SID
+ config NVMEM_U_BOOT_ENV
+ tristate "U-Boot environment variables support"
+ depends on OF && MTD
+- select CRC32
+- select GENERIC_NET_UTILS
++ select NVMEM_LAYOUT_U_BOOT_ENV
+ help
+ U-Boot stores its setup as environment variables. This driver adds
+ support for verifying & exporting such data. It also exposes variables
+--- a/drivers/nvmem/layouts/Kconfig
++++ b/drivers/nvmem/layouts/Kconfig
+@@ -26,6 +26,17 @@ config NVMEM_LAYOUT_ONIE_TLV
+
+ If unsure, say N.
+
++config NVMEM_LAYOUT_U_BOOT_ENV
++ tristate "U-Boot environment variables layout"
++ select CRC32
++ select GENERIC_NET_UTILS
++ help
++ U-Boot stores its setup as environment variables. This driver adds
++ support for verifying & exporting such data. It also exposes variables
++ as NVMEM cells so they can be referenced by other drivers.
++
++ If unsure, say N.
++
+ endmenu
+
+ endif
+--- a/drivers/nvmem/layouts/Makefile
++++ b/drivers/nvmem/layouts/Makefile
+@@ -5,3 +5,4 @@
+
+ obj-$(CONFIG_NVMEM_LAYOUT_SL28_VPD) += sl28vpd.o
+ obj-$(CONFIG_NVMEM_LAYOUT_ONIE_TLV) += onie-tlv.o
++obj-$(CONFIG_NVMEM_LAYOUT_U_BOOT_ENV) += u-boot-env.o
+--- /dev/null
++++ b/drivers/nvmem/layouts/u-boot-env.c
+@@ -0,0 +1,211 @@
++// SPDX-License-Identifier: GPL-2.0-only
++/*
++ * Copyright (C) 2022 - 2023 Rafał Miłecki <rafal@milecki.pl>
++ */
++
++#include <linux/crc32.h>
++#include <linux/etherdevice.h>
++#include <linux/export.h>
++#include <linux/if_ether.h>
++#include <linux/nvmem-consumer.h>
++#include <linux/nvmem-provider.h>
++#include <linux/of.h>
++#include <linux/slab.h>
++
++#include "u-boot-env.h"
++
++struct u_boot_env_image_single {
++ __le32 crc32;
++ uint8_t data[];
++} __packed;
++
++struct u_boot_env_image_redundant {
++ __le32 crc32;
++ u8 mark;
++ uint8_t data[];
++} __packed;
++
++struct u_boot_env_image_broadcom {
++ __le32 magic;
++ __le32 len;
++ __le32 crc32;
++ DECLARE_FLEX_ARRAY(uint8_t, data);
++} __packed;
++
++static int u_boot_env_read_post_process_ethaddr(void *context, const char *id, int index,
++ unsigned int offset, void *buf, size_t bytes)
++{
++ u8 mac[ETH_ALEN];
++
++ if (bytes != 3 * ETH_ALEN - 1)
++ return -EINVAL;
++
++ if (!mac_pton(buf, mac))
++ return -EINVAL;
++
++ if (index)
++ eth_addr_add(mac, index);
++
++ ether_addr_copy(buf, mac);
++
++ return 0;
++}
++
++static int u_boot_env_parse_cells(struct device *dev, struct nvmem_device *nvmem, uint8_t *buf,
++ size_t data_offset, size_t data_len)
++{
++ char *data = buf + data_offset;
++ char *var, *value, *eq;
++
++ for (var = data;
++ var < data + data_len && *var;
++ var = value + strlen(value) + 1) {
++ struct nvmem_cell_info info = {};
++
++ eq = strchr(var, '=');
++ if (!eq)
++ break;
++ *eq = '\0';
++ value = eq + 1;
++
++ info.name = devm_kstrdup(dev, var, GFP_KERNEL);
++ if (!info.name)
++ return -ENOMEM;
++ info.offset = data_offset + value - data;
++ info.bytes = strlen(value);
++ info.np = of_get_child_by_name(dev->of_node, info.name);
++ if (!strcmp(var, "ethaddr")) {
++ info.raw_len = strlen(value);
++ info.bytes = ETH_ALEN;
++ info.read_post_process = u_boot_env_read_post_process_ethaddr;
++ }
++
++ nvmem_add_one_cell(nvmem, &info);
++ }
++
++ return 0;
++}
++
++int u_boot_env_parse(struct device *dev, struct nvmem_device *nvmem,
++ enum u_boot_env_format format)
++{
++ size_t crc32_data_offset;
++ size_t crc32_data_len;
++ size_t crc32_offset;
++ __le32 *crc32_addr;
++ size_t data_offset;
++ size_t data_len;
++ size_t dev_size;
++ uint32_t crc32;
++ uint32_t calc;
++ uint8_t *buf;
++ int bytes;
++ int err;
++
++ dev_size = nvmem_dev_size(nvmem);
++
++ buf = kzalloc(dev_size, GFP_KERNEL);
++ if (!buf) {
++ err = -ENOMEM;
++ goto err_out;
++ }
++
++ bytes = nvmem_device_read(nvmem, 0, dev_size, buf);
++ if (bytes < 0) {
++ err = bytes;
++ goto err_kfree;
++ } else if (bytes != dev_size) {
++ err = -EIO;
++ goto err_kfree;
++ }
++
++ switch (format) {
++ case U_BOOT_FORMAT_SINGLE:
++ crc32_offset = offsetof(struct u_boot_env_image_single, crc32);
++ crc32_data_offset = offsetof(struct u_boot_env_image_single, data);
++ data_offset = offsetof(struct u_boot_env_image_single, data);
++ break;
++ case U_BOOT_FORMAT_REDUNDANT:
++ crc32_offset = offsetof(struct u_boot_env_image_redundant, crc32);
++ crc32_data_offset = offsetof(struct u_boot_env_image_redundant, data);
++ data_offset = offsetof(struct u_boot_env_image_redundant, data);
++ break;
++ case U_BOOT_FORMAT_BROADCOM:
++ crc32_offset = offsetof(struct u_boot_env_image_broadcom, crc32);
++ crc32_data_offset = offsetof(struct u_boot_env_image_broadcom, data);
++ data_offset = offsetof(struct u_boot_env_image_broadcom, data);
++ break;
++ }
++
++ if (dev_size < data_offset) {
++ dev_err(dev, "Device too small for u-boot-env\n");
++ err = -EIO;
++ goto err_kfree;
++ }
++
++ crc32_addr = (__le32 *)(buf + crc32_offset);
++ crc32 = le32_to_cpu(*crc32_addr);
++ crc32_data_len = dev_size - crc32_data_offset;
++ data_len = dev_size - data_offset;
++
++ calc = crc32(~0, buf + crc32_data_offset, crc32_data_len) ^ ~0L;
++ if (calc != crc32) {
++ dev_err(dev, "Invalid calculated CRC32: 0x%08x (expected: 0x%08x)\n", calc, crc32);
++ err = -EINVAL;
++ goto err_kfree;
++ }
++
++ buf[dev_size - 1] = '\0';
++ err = u_boot_env_parse_cells(dev, nvmem, buf, data_offset, data_len);
++
++err_kfree:
++ kfree(buf);
++err_out:
++ return err;
++}
++EXPORT_SYMBOL_GPL(u_boot_env_parse);
++
++static int u_boot_env_add_cells(struct nvmem_layout *layout)
++{
++ struct device *dev = &layout->dev;
++ enum u_boot_env_format format;
++
++ format = (uintptr_t)device_get_match_data(dev);
++
++ return u_boot_env_parse(dev, layout->nvmem, format);
++}
++
++static int u_boot_env_probe(struct nvmem_layout *layout)
++{
++ layout->add_cells = u_boot_env_add_cells;
++
++ return nvmem_layout_register(layout);
++}
++
++static void u_boot_env_remove(struct nvmem_layout *layout)
++{
++ nvmem_layout_unregister(layout);
++}
++
++static const struct of_device_id u_boot_env_of_match_table[] = {
++ { .compatible = "u-boot,env", .data = (void *)U_BOOT_FORMAT_SINGLE, },
++ { .compatible = "u-boot,env-redundant-bool", .data = (void *)U_BOOT_FORMAT_REDUNDANT, },
++ { .compatible = "u-boot,env-redundant-count", .data = (void *)U_BOOT_FORMAT_REDUNDANT, },
++ { .compatible = "brcm,env", .data = (void *)U_BOOT_FORMAT_BROADCOM, },
++ {},
++};
++
++static struct nvmem_layout_driver u_boot_env_layout = {
++ .driver = {
++ .name = "u-boot-env-layout",
++ .of_match_table = u_boot_env_of_match_table,
++ },
++ .probe = u_boot_env_probe,
++ .remove = u_boot_env_remove,
++};
++module_nvmem_layout_driver(u_boot_env_layout);
++
++MODULE_AUTHOR("Rafał Miłecki");
++MODULE_LICENSE("GPL");
++MODULE_DEVICE_TABLE(of, u_boot_env_of_match_table);
++MODULE_DESCRIPTION("NVMEM layout driver for U-Boot environment variables");
+--- /dev/null
++++ b/drivers/nvmem/layouts/u-boot-env.h
+@@ -0,0 +1,15 @@
++/* SPDX-License-Identifier: GPL-2.0-only */
++
++#ifndef _LINUX_NVMEM_LAYOUTS_U_BOOT_ENV_H
++#define _LINUX_NVMEM_LAYOUTS_U_BOOT_ENV_H
++
++enum u_boot_env_format {
++ U_BOOT_FORMAT_SINGLE,
++ U_BOOT_FORMAT_REDUNDANT,
++ U_BOOT_FORMAT_BROADCOM,
++};
++
++int u_boot_env_parse(struct device *dev, struct nvmem_device *nvmem,
++ enum u_boot_env_format format);
++
++#endif /* ifndef _LINUX_NVMEM_LAYOUTS_U_BOOT_ENV_H */
+--- a/drivers/nvmem/u-boot-env.c
++++ b/drivers/nvmem/u-boot-env.c
+@@ -3,23 +3,15 @@
+ * Copyright (C) 2022 Rafał Miłecki <rafal@milecki.pl>
+ */
+
+-#include <linux/crc32.h>
+-#include <linux/etherdevice.h>
+-#include <linux/if_ether.h>
+ #include <linux/mod_devicetable.h>
+ #include <linux/module.h>
+ #include <linux/mtd/mtd.h>
+-#include <linux/nvmem-consumer.h>
+ #include <linux/nvmem-provider.h>
+ #include <linux/of_device.h>
+ #include <linux/platform_device.h>
+ #include <linux/slab.h>
+
+-enum u_boot_env_format {
+- U_BOOT_FORMAT_SINGLE,
+- U_BOOT_FORMAT_REDUNDANT,
+- U_BOOT_FORMAT_BROADCOM,
+-};
++#include "layouts/u-boot-env.h"
+
+ struct u_boot_env {
+ struct device *dev;
+@@ -29,24 +21,6 @@ struct u_boot_env {
+ struct mtd_info *mtd;
+ };
+
+-struct u_boot_env_image_single {
+- __le32 crc32;
+- uint8_t data[];
+-} __packed;
+-
+-struct u_boot_env_image_redundant {
+- __le32 crc32;
+- u8 mark;
+- uint8_t data[];
+-} __packed;
+-
+-struct u_boot_env_image_broadcom {
+- __le32 magic;
+- __le32 len;
+- __le32 crc32;
+- DECLARE_FLEX_ARRAY(uint8_t, data);
+-} __packed;
+-
+ static int u_boot_env_read(void *context, unsigned int offset, void *val,
+ size_t bytes)
+ {
+@@ -69,141 +43,6 @@ static int u_boot_env_read(void *context
+ return 0;
+ }
+
+-static int u_boot_env_read_post_process_ethaddr(void *context, const char *id, int index,
+- unsigned int offset, void *buf, size_t bytes)
+-{
+- u8 mac[ETH_ALEN];
+-
+- if (bytes != 3 * ETH_ALEN - 1)
+- return -EINVAL;
+-
+- if (!mac_pton(buf, mac))
+- return -EINVAL;
+-
+- if (index)
+- eth_addr_add(mac, index);
+-
+- ether_addr_copy(buf, mac);
+-
+- return 0;
+-}
+-
+-static int u_boot_env_add_cells(struct u_boot_env *priv, uint8_t *buf,
+- size_t data_offset, size_t data_len)
+-{
+- struct nvmem_device *nvmem = priv->nvmem;
+- struct device *dev = priv->dev;
+- char *data = buf + data_offset;
+- char *var, *value, *eq;
+-
+- for (var = data;
+- var < data + data_len && *var;
+- var = value + strlen(value) + 1) {
+- struct nvmem_cell_info info = {};
+-
+- eq = strchr(var, '=');
+- if (!eq)
+- break;
+- *eq = '\0';
+- value = eq + 1;
+-
+- info.name = devm_kstrdup(dev, var, GFP_KERNEL);
+- if (!info.name)
+- return -ENOMEM;
+- info.offset = data_offset + value - data;
+- info.bytes = strlen(value);
+- info.np = of_get_child_by_name(dev->of_node, info.name);
+- if (!strcmp(var, "ethaddr")) {
+- info.raw_len = strlen(value);
+- info.bytes = ETH_ALEN;
+- info.read_post_process = u_boot_env_read_post_process_ethaddr;
+- }
+-
+- nvmem_add_one_cell(nvmem, &info);
+- }
+-
+- return 0;
+-}
+-
+-static int u_boot_env_parse(struct u_boot_env *priv)
+-{
+- struct nvmem_device *nvmem = priv->nvmem;
+- struct device *dev = priv->dev;
+- size_t crc32_data_offset;
+- size_t crc32_data_len;
+- size_t crc32_offset;
+- __le32 *crc32_addr;
+- size_t data_offset;
+- size_t data_len;
+- size_t dev_size;
+- uint32_t crc32;
+- uint32_t calc;
+- uint8_t *buf;
+- int bytes;
+- int err;
+-
+- dev_size = nvmem_dev_size(nvmem);
+-
+- buf = kzalloc(dev_size, GFP_KERNEL);
+- if (!buf) {
+- err = -ENOMEM;
+- goto err_out;
+- }
+-
+- bytes = nvmem_device_read(nvmem, 0, dev_size, buf);
+- if (bytes < 0) {
+- err = bytes;
+- goto err_kfree;
+- } else if (bytes != dev_size) {
+- err = -EIO;
+- goto err_kfree;
+- }
+-
+- switch (priv->format) {
+- case U_BOOT_FORMAT_SINGLE:
+- crc32_offset = offsetof(struct u_boot_env_image_single, crc32);
+- crc32_data_offset = offsetof(struct u_boot_env_image_single, data);
+- data_offset = offsetof(struct u_boot_env_image_single, data);
+- break;
+- case U_BOOT_FORMAT_REDUNDANT:
+- crc32_offset = offsetof(struct u_boot_env_image_redundant, crc32);
+- crc32_data_offset = offsetof(struct u_boot_env_image_redundant, data);
+- data_offset = offsetof(struct u_boot_env_image_redundant, data);
+- break;
+- case U_BOOT_FORMAT_BROADCOM:
+- crc32_offset = offsetof(struct u_boot_env_image_broadcom, crc32);
+- crc32_data_offset = offsetof(struct u_boot_env_image_broadcom, data);
+- data_offset = offsetof(struct u_boot_env_image_broadcom, data);
+- break;
+- }
+-
+- if (dev_size < data_offset) {
+- dev_err(dev, "Device too small for u-boot-env\n");
+- err = -EIO;
+- goto err_kfree;
+- }
+-
+- crc32_addr = (__le32 *)(buf + crc32_offset);
+- crc32 = le32_to_cpu(*crc32_addr);
+- crc32_data_len = dev_size - crc32_data_offset;
+- data_len = dev_size - data_offset;
+-
+- calc = crc32(~0, buf + crc32_data_offset, crc32_data_len) ^ ~0L;
+- if (calc != crc32) {
+- dev_err(dev, "Invalid calculated CRC32: 0x%08x (expected: 0x%08x)\n", calc, crc32);
+- err = -EINVAL;
+- goto err_kfree;
+- }
+-
+- buf[dev_size - 1] = '\0';
+- err = u_boot_env_add_cells(priv, buf, data_offset, data_len);
+-
+-err_kfree:
+- kfree(buf);
+-err_out:
+- return err;
+-}
+-
+ static int u_boot_env_probe(struct platform_device *pdev)
+ {
+ struct nvmem_config config = {
+@@ -235,7 +74,7 @@ static int u_boot_env_probe(struct platf
+ if (IS_ERR(priv->nvmem))
+ return PTR_ERR(priv->nvmem);
+
+- return u_boot_env_parse(priv);
++ return u_boot_env_parse(dev, priv->nvmem, priv->format);
+ }
+
+ static const struct of_device_id u_boot_env_of_match_table[] = {
diff --git a/target/linux/generic/backport-6.1/020-v6.3-01-UPSTREAM-mm-multi-gen-LRU-rename-lru_gen_struct-to-l.patch b/target/linux/generic/backport-6.1/020-v6.3-01-UPSTREAM-mm-multi-gen-LRU-rename-lru_gen_struct-to-l.patch
index fe32acc985..2428bdcb72 100644
--- a/target/linux/generic/backport-6.1/020-v6.3-01-UPSTREAM-mm-multi-gen-LRU-rename-lru_gen_struct-to-l.patch
+++ b/target/linux/generic/backport-6.1/020-v6.3-01-UPSTREAM-mm-multi-gen-LRU-rename-lru_gen_struct-to-l.patch
@@ -294,7 +294,7 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
struct mem_cgroup *memcg = lruvec_memcg(lruvec);
VM_WARN_ON_ONCE(!list_empty(list));
-@@ -5249,7 +5249,7 @@ done:
+@@ -5248,7 +5248,7 @@ done:
static bool __maybe_unused state_is_valid(struct lruvec *lruvec)
{
@@ -303,7 +303,7 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
if (lrugen->enabled) {
enum lru_list lru;
-@@ -5531,7 +5531,7 @@ static void lru_gen_seq_show_full(struct
+@@ -5530,7 +5530,7 @@ static void lru_gen_seq_show_full(struct
int i;
int type, tier;
int hist = lru_hist_from_seq(seq);
@@ -312,7 +312,7 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
for (tier = 0; tier < MAX_NR_TIERS; tier++) {
seq_printf(m, " %10d", tier);
-@@ -5581,7 +5581,7 @@ static int lru_gen_seq_show(struct seq_f
+@@ -5580,7 +5580,7 @@ static int lru_gen_seq_show(struct seq_f
unsigned long seq;
bool full = !debugfs_real_fops(m->file)->write;
struct lruvec *lruvec = v;
@@ -321,7 +321,7 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
int nid = lruvec_pgdat(lruvec)->node_id;
struct mem_cgroup *memcg = lruvec_memcg(lruvec);
DEFINE_MAX_SEQ(lruvec);
-@@ -5835,7 +5835,7 @@ void lru_gen_init_lruvec(struct lruvec *
+@@ -5834,7 +5834,7 @@ void lru_gen_init_lruvec(struct lruvec *
{
int i;
int gen, type, zone;
diff --git a/target/linux/generic/backport-6.1/020-v6.3-03-UPSTREAM-mm-multi-gen-LRU-remove-eviction-fairness-s.patch b/target/linux/generic/backport-6.1/020-v6.3-03-UPSTREAM-mm-multi-gen-LRU-remove-eviction-fairness-s.patch
index e5ad78b61d..3a27bbcae0 100644
--- a/target/linux/generic/backport-6.1/020-v6.3-03-UPSTREAM-mm-multi-gen-LRU-remove-eviction-fairness-s.patch
+++ b/target/linux/generic/backport-6.1/020-v6.3-03-UPSTREAM-mm-multi-gen-LRU-remove-eviction-fairness-s.patch
@@ -76,7 +76,7 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
{
int type;
int scanned;
-@@ -5095,9 +5104,6 @@ retry:
+@@ -5094,9 +5103,6 @@ retry:
goto retry;
}
@@ -86,7 +86,7 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
return scanned;
}
-@@ -5136,67 +5142,26 @@ done:
+@@ -5135,67 +5141,26 @@ done:
return min_seq[!can_swap] + MIN_NR_GENS <= max_seq ? nr_to_scan : 0;
}
@@ -163,7 +163,7 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
lru_add_drain();
-@@ -5220,7 +5185,7 @@ static void lru_gen_shrink_lruvec(struct
+@@ -5219,7 +5184,7 @@ static void lru_gen_shrink_lruvec(struct
if (!nr_to_scan)
goto done;
@@ -172,7 +172,7 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
if (!delta)
goto done;
-@@ -5228,7 +5193,7 @@ static void lru_gen_shrink_lruvec(struct
+@@ -5227,7 +5192,7 @@ static void lru_gen_shrink_lruvec(struct
if (scanned >= nr_to_scan)
break;
@@ -181,7 +181,7 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
break;
cond_resched();
-@@ -5678,7 +5643,7 @@ static int run_eviction(struct lruvec *l
+@@ -5677,7 +5642,7 @@ static int run_eviction(struct lruvec *l
if (sc->nr_reclaimed >= nr_to_reclaim)
return 0;
diff --git a/target/linux/generic/backport-6.1/020-v6.3-04-BACKPORT-mm-multi-gen-LRU-remove-aging-fairness-safe.patch b/target/linux/generic/backport-6.1/020-v6.3-04-BACKPORT-mm-multi-gen-LRU-remove-aging-fairness-safe.patch
index cb349abcdb..8295889554 100644
--- a/target/linux/generic/backport-6.1/020-v6.3-04-BACKPORT-mm-multi-gen-LRU-remove-aging-fairness-safe.patch
+++ b/target/linux/generic/backport-6.1/020-v6.3-04-BACKPORT-mm-multi-gen-LRU-remove-aging-fairness-safe.patch
@@ -214,7 +214,7 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
*/
if (mutex_trylock(&oom_lock)) {
struct oom_control oc = {
-@@ -5113,33 +5117,27 @@ retry:
+@@ -5112,33 +5116,27 @@ retry:
* reclaim.
*/
static unsigned long get_nr_to_scan(struct lruvec *lruvec, struct scan_control *sc,
@@ -254,7 +254,7 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
}
static unsigned long get_nr_to_reclaim(struct scan_control *sc)
-@@ -5158,9 +5156,7 @@ static unsigned long get_nr_to_reclaim(s
+@@ -5157,9 +5155,7 @@ static unsigned long get_nr_to_reclaim(s
static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
{
struct blk_plug plug;
@@ -264,7 +264,7 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
unsigned long nr_to_reclaim = get_nr_to_reclaim(sc);
lru_add_drain();
-@@ -5181,13 +5177,13 @@ static void lru_gen_shrink_lruvec(struct
+@@ -5180,13 +5176,13 @@ static void lru_gen_shrink_lruvec(struct
else
swappiness = 0;
@@ -281,7 +281,7 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
scanned += delta;
if (scanned >= nr_to_scan)
-@@ -5199,10 +5195,6 @@ static void lru_gen_shrink_lruvec(struct
+@@ -5198,10 +5194,6 @@ static void lru_gen_shrink_lruvec(struct
cond_resched();
}
diff --git a/target/linux/generic/backport-6.1/020-v6.3-05-UPSTREAM-mm-multi-gen-LRU-shuffle-should_run_aging.patch b/target/linux/generic/backport-6.1/020-v6.3-05-UPSTREAM-mm-multi-gen-LRU-shuffle-should_run_aging.patch
index 42caab7c37..6374b425cd 100644
--- a/target/linux/generic/backport-6.1/020-v6.3-05-UPSTREAM-mm-multi-gen-LRU-shuffle-should_run_aging.patch
+++ b/target/linux/generic/backport-6.1/020-v6.3-05-UPSTREAM-mm-multi-gen-LRU-shuffle-should_run_aging.patch
@@ -95,7 +95,7 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
static bool lruvec_is_sizable(struct lruvec *lruvec, struct scan_control *sc)
{
int gen, type, zone;
-@@ -5111,6 +5049,68 @@ retry:
+@@ -5110,6 +5048,68 @@ retry:
return scanned;
}
diff --git a/target/linux/generic/backport-6.1/020-v6.3-06-BACKPORT-mm-multi-gen-LRU-per-node-lru_gen_folio-lis.patch b/target/linux/generic/backport-6.1/020-v6.3-06-BACKPORT-mm-multi-gen-LRU-per-node-lru_gen_folio-lis.patch
index 7756d19d9b..50ceaf13ed 100644
--- a/target/linux/generic/backport-6.1/020-v6.3-06-BACKPORT-mm-multi-gen-LRU-per-node-lru_gen_folio-lis.patch
+++ b/target/linux/generic/backport-6.1/020-v6.3-06-BACKPORT-mm-multi-gen-LRU-per-node-lru_gen_folio-lis.patch
@@ -335,7 +335,7 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
if (order > 0)
return 0;
-@@ -5387,6 +5400,7 @@ static int mem_cgroup_css_online(struct
+@@ -5390,6 +5403,7 @@ static int mem_cgroup_css_online(struct
if (unlikely(mem_cgroup_is_root(memcg)))
queue_delayed_work(system_unbound_wq, &stats_flush_dwork,
2UL*HZ);
@@ -343,7 +343,7 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
return 0;
offline_kmem:
memcg_offline_kmem(memcg);
-@@ -5418,6 +5432,7 @@ static void mem_cgroup_css_offline(struc
+@@ -5421,6 +5435,7 @@ static void mem_cgroup_css_offline(struc
memcg_offline_kmem(memcg);
reparent_shrinker_deferred(memcg);
wb_memcg_offline(memcg);
@@ -351,7 +351,7 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
drain_all_stock(memcg);
-@@ -5429,6 +5444,7 @@ static void mem_cgroup_css_released(stru
+@@ -5432,6 +5447,7 @@ static void mem_cgroup_css_released(stru
struct mem_cgroup *memcg = mem_cgroup_from_css(css);
invalidate_reclaim_iterators(memcg);
@@ -361,7 +361,7 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
static void mem_cgroup_css_free(struct cgroup_subsys_state *css)
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
-@@ -7949,6 +7949,7 @@ static void __init free_area_init_node(i
+@@ -7956,6 +7956,7 @@ static void __init free_area_init_node(i
pgdat_set_deferred_range(pgdat);
free_area_init_core(pgdat);
@@ -421,7 +421,7 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
/* check the order to exclude compaction-induced reclaim */
if (!min_ttl || sc->order || sc->priority == DEF_PRIORITY)
return;
-@@ -5116,8 +5113,7 @@ static bool should_run_aging(struct lruv
+@@ -5115,8 +5112,7 @@ static bool should_run_aging(struct lruv
* 1. Defer try_to_inc_max_seq() to workqueues to reduce latency for memcg
* reclaim.
*/
@@ -431,7 +431,7 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
{
unsigned long nr_to_scan;
struct mem_cgroup *memcg = lruvec_memcg(lruvec);
-@@ -5134,10 +5130,8 @@ static unsigned long get_nr_to_scan(stru
+@@ -5133,10 +5129,8 @@ static unsigned long get_nr_to_scan(stru
if (sc->priority == DEF_PRIORITY)
return nr_to_scan;
@@ -443,7 +443,7 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
}
static unsigned long get_nr_to_reclaim(struct scan_control *sc)
-@@ -5146,29 +5140,18 @@ static unsigned long get_nr_to_reclaim(s
+@@ -5145,29 +5139,18 @@ static unsigned long get_nr_to_reclaim(s
if (!global_reclaim(sc))
return -1;
@@ -475,7 +475,7 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
if (sc->may_swap)
swappiness = get_swappiness(lruvec, sc);
-@@ -5178,7 +5161,7 @@ static void lru_gen_shrink_lruvec(struct
+@@ -5177,7 +5160,7 @@ static void lru_gen_shrink_lruvec(struct
swappiness = 0;
nr_to_scan = get_nr_to_scan(lruvec, sc, swappiness);
@@ -484,7 +484,7 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
break;
delta = evict_folios(lruvec, sc, swappiness);
-@@ -5195,10 +5178,251 @@ static void lru_gen_shrink_lruvec(struct
+@@ -5194,10 +5177,251 @@ static void lru_gen_shrink_lruvec(struct
cond_resched();
}
@@ -736,7 +736,7 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
/******************************************************************************
* state change
-@@ -5656,11 +5880,11 @@ static int run_cmd(char cmd, int memcg_i
+@@ -5655,11 +5879,11 @@ static int run_cmd(char cmd, int memcg_i
if (!mem_cgroup_disabled()) {
rcu_read_lock();
@@ -751,7 +751,7 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
rcu_read_unlock();
if (!memcg)
-@@ -5808,6 +6032,19 @@ void lru_gen_init_lruvec(struct lruvec *
+@@ -5807,6 +6031,19 @@ void lru_gen_init_lruvec(struct lruvec *
}
#ifdef CONFIG_MEMCG
@@ -771,7 +771,7 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
void lru_gen_init_memcg(struct mem_cgroup *memcg)
{
INIT_LIST_HEAD(&memcg->mm_list.fifo);
-@@ -5831,7 +6068,69 @@ void lru_gen_exit_memcg(struct mem_cgrou
+@@ -5830,7 +6067,69 @@ void lru_gen_exit_memcg(struct mem_cgrou
}
}
}
@@ -842,7 +842,7 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
static int __init init_lru_gen(void)
{
-@@ -5858,6 +6157,10 @@ static void lru_gen_shrink_lruvec(struct
+@@ -5857,6 +6156,10 @@ static void lru_gen_shrink_lruvec(struct
{
}
@@ -853,7 +853,7 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
#endif /* CONFIG_LRU_GEN */
static void shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
-@@ -5871,7 +6174,7 @@ static void shrink_lruvec(struct lruvec
+@@ -5870,7 +6173,7 @@ static void shrink_lruvec(struct lruvec
bool proportional_reclaim;
struct blk_plug plug;
@@ -862,7 +862,7 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
lru_gen_shrink_lruvec(lruvec, sc);
return;
}
-@@ -6114,6 +6417,11 @@ static void shrink_node(pg_data_t *pgdat
+@@ -6113,6 +6416,11 @@ static void shrink_node(pg_data_t *pgdat
struct lruvec *target_lruvec;
bool reclaimable = false;
diff --git a/target/linux/generic/backport-6.1/020-v6.3-07-BACKPORT-mm-multi-gen-LRU-clarify-scan_control-flags.patch b/target/linux/generic/backport-6.1/020-v6.3-07-BACKPORT-mm-multi-gen-LRU-clarify-scan_control-flags.patch
index d60ddb9dcc..079f4fd202 100644
--- a/target/linux/generic/backport-6.1/020-v6.3-07-BACKPORT-mm-multi-gen-LRU-clarify-scan_control-flags.patch
+++ b/target/linux/generic/backport-6.1/020-v6.3-07-BACKPORT-mm-multi-gen-LRU-clarify-scan_control-flags.patch
@@ -113,7 +113,7 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
*/
return isolated || !remaining ? scanned : 0;
}
-@@ -5119,8 +5115,7 @@ static long get_nr_to_scan(struct lruvec
+@@ -5118,8 +5114,7 @@ static long get_nr_to_scan(struct lruvec
struct mem_cgroup *memcg = lruvec_memcg(lruvec);
DEFINE_MAX_SEQ(lruvec);
@@ -123,7 +123,7 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
return 0;
if (!should_run_aging(lruvec, max_seq, sc, can_swap, &nr_to_scan))
-@@ -5148,17 +5143,14 @@ static bool try_to_shrink_lruvec(struct
+@@ -5147,17 +5142,14 @@ static bool try_to_shrink_lruvec(struct
long nr_to_scan;
unsigned long scanned = 0;
unsigned long nr_to_reclaim = get_nr_to_reclaim(sc);
@@ -146,7 +146,7 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
nr_to_scan = get_nr_to_scan(lruvec, sc, swappiness);
if (nr_to_scan <= 0)
-@@ -5289,12 +5281,13 @@ static void lru_gen_shrink_lruvec(struct
+@@ -5288,12 +5280,13 @@ static void lru_gen_shrink_lruvec(struct
struct blk_plug plug;
VM_WARN_ON_ONCE(global_reclaim(sc));
@@ -161,7 +161,7 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
if (try_to_shrink_lruvec(lruvec, sc))
lru_gen_rotate_memcg(lruvec, MEMCG_LRU_YOUNG);
-@@ -5350,11 +5343,19 @@ static void lru_gen_shrink_node(struct p
+@@ -5349,11 +5342,19 @@ static void lru_gen_shrink_node(struct p
VM_WARN_ON_ONCE(!global_reclaim(sc));
@@ -182,7 +182,7 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
set_initial_priority(pgdat, sc);
-@@ -5372,7 +5373,7 @@ static void lru_gen_shrink_node(struct p
+@@ -5371,7 +5372,7 @@ static void lru_gen_shrink_node(struct p
clear_mm_walk();
blk_finish_plug(&plug);
@@ -191,7 +191,7 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
/* kswapd should never fail */
pgdat->kswapd_failures = 0;
}
-@@ -5944,7 +5945,7 @@ static ssize_t lru_gen_seq_write(struct
+@@ -5943,7 +5944,7 @@ static ssize_t lru_gen_seq_write(struct
set_task_reclaim_state(current, &sc.reclaim_state);
flags = memalloc_noreclaim_save();
blk_start_plug(&plug);
diff --git a/target/linux/generic/backport-6.1/020-v6.3-09-UPSTREAM-mm-multi-gen-LRU-avoid-futile-retries.patch b/target/linux/generic/backport-6.1/020-v6.3-09-UPSTREAM-mm-multi-gen-LRU-avoid-futile-retries.patch
index c1ad1c538e..2ed3f07bbf 100644
--- a/target/linux/generic/backport-6.1/020-v6.3-09-UPSTREAM-mm-multi-gen-LRU-avoid-futile-retries.patch
+++ b/target/linux/generic/backport-6.1/020-v6.3-09-UPSTREAM-mm-multi-gen-LRU-avoid-futile-retries.patch
@@ -29,7 +29,7 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
-@@ -5218,18 +5218,20 @@ static int shrink_one(struct lruvec *lru
+@@ -5217,18 +5217,20 @@ static int shrink_one(struct lruvec *lru
static void shrink_many(struct pglist_data *pgdat, struct scan_control *sc)
{
@@ -52,7 +52,7 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
gen = get_memcg_gen(READ_ONCE(pgdat->memcg_lru.seq));
rcu_read_lock();
-@@ -5253,14 +5255,22 @@ restart:
+@@ -5252,14 +5254,22 @@ restart:
op = shrink_one(lruvec, sc);
@@ -78,7 +78,7 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
/* restart if raced with lru_gen_rotate_memcg() */
if (gen != get_nulls_value(pos))
goto restart;
-@@ -5269,11 +5279,6 @@ restart:
+@@ -5268,11 +5278,6 @@ restart:
bin = get_memcg_bin(bin + 1);
if (bin != first_bin)
goto restart;
diff --git a/target/linux/generic/backport-6.1/020-v6.3-10-UPSTREAM-mm-add-vma_has_recency.patch b/target/linux/generic/backport-6.1/020-v6.3-10-UPSTREAM-mm-add-vma_has_recency.patch
index 67fe4f96ec..19d6e0a207 100644
--- a/target/linux/generic/backport-6.1/020-v6.3-10-UPSTREAM-mm-add-vma_has_recency.patch
+++ b/target/linux/generic/backport-6.1/020-v6.3-10-UPSTREAM-mm-add-vma_has_recency.patch
@@ -87,7 +87,7 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
mark_page_accessed(page);
}
rss[mm_counter(page)]--;
-@@ -5219,8 +5218,8 @@ static inline void mm_account_fault(stru
+@@ -5218,8 +5217,8 @@ static inline void mm_account_fault(stru
#ifdef CONFIG_LRU_GEN
static void lru_gen_enter_fault(struct vm_area_struct *vma)
{
diff --git a/target/linux/generic/backport-6.1/020-v6.3-15-UPSTREAM-mm-multi-gen-LRU-section-for-memcg-LRU.patch b/target/linux/generic/backport-6.1/020-v6.3-15-UPSTREAM-mm-multi-gen-LRU-section-for-memcg-LRU.patch
index 101a0a3757..11c1b43db9 100644
--- a/target/linux/generic/backport-6.1/020-v6.3-15-UPSTREAM-mm-multi-gen-LRU-section-for-memcg-LRU.patch
+++ b/target/linux/generic/backport-6.1/020-v6.3-15-UPSTREAM-mm-multi-gen-LRU-section-for-memcg-LRU.patch
@@ -303,7 +303,7 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
* the eviction
******************************************************************************/
-@@ -5398,53 +5540,6 @@ done:
+@@ -5397,53 +5539,6 @@ done:
pgdat->kswapd_failures = 0;
}
@@ -357,7 +357,7 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
/******************************************************************************
* state change
******************************************************************************/
-@@ -6090,67 +6185,6 @@ void lru_gen_exit_memcg(struct mem_cgrou
+@@ -6089,67 +6184,6 @@ void lru_gen_exit_memcg(struct mem_cgrou
}
}
diff --git a/target/linux/generic/backport-6.1/020-v6.3-16-UPSTREAM-mm-multi-gen-LRU-improve-lru_gen_exit_memcg.patch b/target/linux/generic/backport-6.1/020-v6.3-16-UPSTREAM-mm-multi-gen-LRU-improve-lru_gen_exit_memcg.patch
index 1ee766f861..fcb9708d8a 100644
--- a/target/linux/generic/backport-6.1/020-v6.3-16-UPSTREAM-mm-multi-gen-LRU-improve-lru_gen_exit_memcg.patch
+++ b/target/linux/generic/backport-6.1/020-v6.3-16-UPSTREAM-mm-multi-gen-LRU-improve-lru_gen_exit_memcg.patch
@@ -20,7 +20,7 @@ Signed-off-by: T.J. Mercier <tjmercier@google.com>
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
-@@ -6172,12 +6172,17 @@ void lru_gen_exit_memcg(struct mem_cgrou
+@@ -6171,12 +6171,17 @@ void lru_gen_exit_memcg(struct mem_cgrou
int i;
int nid;
diff --git a/target/linux/generic/backport-6.1/020-v6.4-19-mm-Multi-gen-LRU-remove-wait_event_killable.patch b/target/linux/generic/backport-6.1/020-v6.4-19-mm-Multi-gen-LRU-remove-wait_event_killable.patch
index 1b0459cdb9..958d459686 100644
--- a/target/linux/generic/backport-6.1/020-v6.4-19-mm-Multi-gen-LRU-remove-wait_event_killable.patch
+++ b/target/linux/generic/backport-6.1/020-v6.4-19-mm-Multi-gen-LRU-remove-wait_event_killable.patch
@@ -255,7 +255,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
}
/******************************************************************************
-@@ -6117,7 +6087,6 @@ void lru_gen_init_lruvec(struct lruvec *
+@@ -6116,7 +6086,6 @@ void lru_gen_init_lruvec(struct lruvec *
INIT_LIST_HEAD(&lrugen->folios[gen][type][zone]);
lruvec->mm_state.seq = MIN_NR_GENS;
@@ -263,7 +263,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
}
#ifdef CONFIG_MEMCG
-@@ -6150,7 +6119,6 @@ void lru_gen_exit_memcg(struct mem_cgrou
+@@ -6149,7 +6118,6 @@ void lru_gen_exit_memcg(struct mem_cgrou
for_each_node(nid) {
struct lruvec *lruvec = get_lruvec(memcg, nid);
diff --git a/target/linux/generic/backport-6.1/412-v6.3-01-spidev-Add-Silicon-Labs-EM3581-device-compatible.patch b/target/linux/generic/backport-6.1/412-v6.3-01-spidev-Add-Silicon-Labs-EM3581-device-compatible.patch
deleted file mode 100644
index cc05fa6b75..0000000000
--- a/target/linux/generic/backport-6.1/412-v6.3-01-spidev-Add-Silicon-Labs-EM3581-device-compatible.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From c67d90e058550403a3e6f9b05bfcdcfa12b1815c Mon Sep 17 00:00:00 2001
-From: Vincent Tremblay <vincent@vtremblay.dev>
-Date: Mon, 26 Dec 2022 21:35:48 -0500
-Subject: [PATCH] spidev: Add Silicon Labs EM3581 device compatible
-
-Add compatible string for Silicon Labs EM3581 device.
-
-Signed-off-by: Vincent Tremblay <vincent@vtremblay.dev>
-Link: https://lore.kernel.org/r/20221227023550.569547-2-vincent@vtremblay.dev
-Signed-off-by: Mark Brown <broonie@kernel.org>
----
- drivers/spi/spidev.c | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/drivers/spi/spidev.c
-+++ b/drivers/spi/spidev.c
-@@ -700,6 +700,7 @@ static const struct spi_device_id spidev
- { .name = "m53cpld" },
- { .name = "spi-petra" },
- { .name = "spi-authenta" },
-+ { .name = "em3581" },
- {},
- };
- MODULE_DEVICE_TABLE(spi, spidev_spi_ids);
-@@ -726,6 +727,7 @@ static const struct of_device_id spidev_
- { .compatible = "menlo,m53cpld", .data = &spidev_of_check },
- { .compatible = "cisco,spi-petra", .data = &spidev_of_check },
- { .compatible = "micron,spi-authenta", .data = &spidev_of_check },
-+ { .compatible = "silabs,em3581", .data = &spidev_of_check },
- {},
- };
- MODULE_DEVICE_TABLE(of, spidev_dt_ids);
diff --git a/target/linux/generic/backport-6.1/412-v6.3-02-spidev-Add-Silicon-Labs-SI3210-device-compatible.patch b/target/linux/generic/backport-6.1/412-v6.3-02-spidev-Add-Silicon-Labs-SI3210-device-compatible.patch
index 59d025e087..1f8501dc1c 100644
--- a/target/linux/generic/backport-6.1/412-v6.3-02-spidev-Add-Silicon-Labs-SI3210-device-compatible.patch
+++ b/target/linux/generic/backport-6.1/412-v6.3-02-spidev-Add-Silicon-Labs-SI3210-device-compatible.patch
@@ -14,7 +14,7 @@ Signed-off-by: Mark Brown <broonie@kernel.org>
--- a/drivers/spi/spidev.c
+++ b/drivers/spi/spidev.c
-@@ -701,6 +701,7 @@ static const struct spi_device_id spidev
+@@ -702,6 +702,7 @@ static const struct spi_device_id spidev
{ .name = "spi-petra" },
{ .name = "spi-authenta" },
{ .name = "em3581" },
@@ -22,9 +22,9 @@ Signed-off-by: Mark Brown <broonie@kernel.org>
{},
};
MODULE_DEVICE_TABLE(spi, spidev_spi_ids);
-@@ -728,6 +729,7 @@ static const struct of_device_id spidev_
- { .compatible = "cisco,spi-petra", .data = &spidev_of_check },
- { .compatible = "micron,spi-authenta", .data = &spidev_of_check },
+@@ -730,6 +731,7 @@ static const struct of_device_id spidev_
+ { .compatible = "rohm,dh2228fv", .data = &spidev_of_check },
+ { .compatible = "semtech,sx1301", .data = &spidev_of_check },
{ .compatible = "silabs,em3581", .data = &spidev_of_check },
+ { .compatible = "silabs,si3210", .data = &spidev_of_check },
{},
diff --git a/target/linux/generic/backport-6.1/715-07-v6.2-net-remove-explicit-phylink_generic_validate-referen.patch b/target/linux/generic/backport-6.1/715-07-v6.2-net-remove-explicit-phylink_generic_validate-referen.patch
index 31fde5f18e..90a29ccc36 100644
--- a/target/linux/generic/backport-6.1/715-07-v6.2-net-remove-explicit-phylink_generic_validate-referen.patch
+++ b/target/linux/generic/backport-6.1/715-07-v6.2-net-remove-explicit-phylink_generic_validate-referen.patch
@@ -202,7 +202,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
.mac_link_up = am65_cpsw_nuss_mac_link_up,
--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
-@@ -1736,7 +1736,6 @@ static void axienet_mac_link_up(struct p
+@@ -1737,7 +1737,6 @@ static void axienet_mac_link_up(struct p
}
static const struct phylink_mac_ops axienet_phylink_ops = {
diff --git a/target/linux/generic/backport-6.1/715-26-v6.5-net-phylink-pass-neg_mode-into-phylink_mii_c22_pcs_c.patch b/target/linux/generic/backport-6.1/715-26-v6.5-net-phylink-pass-neg_mode-into-phylink_mii_c22_pcs_c.patch
index 5572850e95..07e879098a 100644
--- a/target/linux/generic/backport-6.1/715-26-v6.5-net-phylink-pass-neg_mode-into-phylink_mii_c22_pcs_c.patch
+++ b/target/linux/generic/backport-6.1/715-26-v6.5-net-phylink-pass-neg_mode-into-phylink_mii_c22_pcs_c.patch
@@ -53,7 +53,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
supported = mac_dev->phylink_config.supported_interfaces;
--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
-@@ -1631,7 +1631,7 @@ static void axienet_pcs_an_restart(struc
+@@ -1632,7 +1632,7 @@ static void axienet_pcs_an_restart(struc
phylink_mii_c22_pcs_an_restart(pcs_phy);
}
@@ -62,7 +62,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
phy_interface_t interface,
const unsigned long *advertising,
bool permit_pause_to_mac)
-@@ -1653,7 +1653,8 @@ static int axienet_pcs_config(struct phy
+@@ -1654,7 +1654,8 @@ static int axienet_pcs_config(struct phy
}
}
@@ -72,7 +72,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
if (ret < 0)
netdev_warn(ndev, "Failed to configure PCS: %d\n", ret);
-@@ -2129,6 +2130,7 @@ static int axienet_probe(struct platform
+@@ -2130,6 +2131,7 @@ static int axienet_probe(struct platform
}
of_node_put(np);
lp->pcs.ops = &axienet_pcs_ops;
diff --git a/target/linux/generic/backport-6.1/797-6.7-net-dsa-mv88e6xxx-fix-marvell-6350-switch-probing.patch b/target/linux/generic/backport-6.1/797-6.7-net-dsa-mv88e6xxx-fix-marvell-6350-switch-probing.patch
index 36083bbaf5..0afc69fa44 100644
--- a/target/linux/generic/backport-6.1/797-6.7-net-dsa-mv88e6xxx-fix-marvell-6350-switch-probing.patch
+++ b/target/linux/generic/backport-6.1/797-6.7-net-dsa-mv88e6xxx-fix-marvell-6350-switch-probing.patch
@@ -51,7 +51,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
static int mv88e6352_get_port4_serdes_cmode(struct mv88e6xxx_chip *chip)
{
u16 reg, val;
-@@ -4501,7 +4513,7 @@ static const struct mv88e6xxx_ops mv88e6
+@@ -4502,7 +4514,7 @@ static const struct mv88e6xxx_ops mv88e6
.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
.stu_getnext = mv88e6352_g1_stu_getnext,
.stu_loadpurge = mv88e6352_g1_stu_loadpurge,
@@ -60,7 +60,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
};
static const struct mv88e6xxx_ops mv88e6172_ops = {
-@@ -4604,7 +4616,7 @@ static const struct mv88e6xxx_ops mv88e6
+@@ -4605,7 +4617,7 @@ static const struct mv88e6xxx_ops mv88e6
.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
.stu_getnext = mv88e6352_g1_stu_getnext,
.stu_loadpurge = mv88e6352_g1_stu_loadpurge,
@@ -69,7 +69,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
};
static const struct mv88e6xxx_ops mv88e6176_ops = {
-@@ -5281,7 +5293,7 @@ static const struct mv88e6xxx_ops mv88e6
+@@ -5282,7 +5294,7 @@ static const struct mv88e6xxx_ops mv88e6
.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
.stu_getnext = mv88e6352_g1_stu_getnext,
.stu_loadpurge = mv88e6352_g1_stu_loadpurge,
@@ -78,7 +78,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
};
static const struct mv88e6xxx_ops mv88e6351_ops = {
-@@ -5327,7 +5339,7 @@ static const struct mv88e6xxx_ops mv88e6
+@@ -5328,7 +5340,7 @@ static const struct mv88e6xxx_ops mv88e6
.stu_loadpurge = mv88e6352_g1_stu_loadpurge,
.avb_ops = &mv88e6352_avb_ops,
.ptp_ops = &mv88e6352_ptp_ops,
diff --git a/target/linux/generic/backport-6.1/804-v6.5-11-leds-trigger-netdev-expose-netdev-trigger-modes-in-l.patch b/target/linux/generic/backport-6.1/804-v6.5-11-leds-trigger-netdev-expose-netdev-trigger-modes-in-l.patch
index 70aed850d1..f23504b1d0 100644
--- a/target/linux/generic/backport-6.1/804-v6.5-11-leds-trigger-netdev-expose-netdev-trigger-modes-in-l.patch
+++ b/target/linux/generic/backport-6.1/804-v6.5-11-leds-trigger-netdev-expose-netdev-trigger-modes-in-l.patch
@@ -35,7 +35,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
int current_brightness;
--- a/include/linux/leds.h
+++ b/include/linux/leds.h
-@@ -527,6 +527,16 @@ static inline void *led_get_trigger_data
+@@ -525,6 +525,16 @@ led_trigger_get_brightness(const struct
#endif /* CONFIG_LEDS_TRIGGERS */
diff --git a/target/linux/generic/backport-6.1/805-v6.5-01-leds-trigger-netdev-add-additional-specific-link-spe.patch b/target/linux/generic/backport-6.1/805-v6.5-01-leds-trigger-netdev-add-additional-specific-link-spe.patch
index 1c564b3897..38989a2a63 100644
--- a/target/linux/generic/backport-6.1/805-v6.5-01-leds-trigger-netdev-add-additional-specific-link-spe.patch
+++ b/target/linux/generic/backport-6.1/805-v6.5-01-leds-trigger-netdev-add-additional-specific-link-spe.patch
@@ -230,7 +230,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
/* base state is ON (link present) */
--- a/include/linux/leds.h
+++ b/include/linux/leds.h
-@@ -530,6 +530,9 @@ static inline void *led_get_trigger_data
+@@ -528,6 +528,9 @@ led_trigger_get_brightness(const struct
/* Trigger specific enum */
enum led_trigger_netdev_modes {
TRIGGER_NETDEV_LINK = 0,
diff --git a/target/linux/generic/backport-6.1/805-v6.5-02-leds-trigger-netdev-add-additional-specific-link-dup.patch b/target/linux/generic/backport-6.1/805-v6.5-02-leds-trigger-netdev-add-additional-specific-link-dup.patch
index a5ab461828..9021326991 100644
--- a/target/linux/generic/backport-6.1/805-v6.5-02-leds-trigger-netdev-add-additional-specific-link-dup.patch
+++ b/target/linux/generic/backport-6.1/805-v6.5-02-leds-trigger-netdev-add-additional-specific-link-dup.patch
@@ -127,7 +127,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
/* base state is ON (link present) */
--- a/include/linux/leds.h
+++ b/include/linux/leds.h
-@@ -533,6 +533,8 @@ enum led_trigger_netdev_modes {
+@@ -531,6 +531,8 @@ enum led_trigger_netdev_modes {
TRIGGER_NETDEV_LINK_10,
TRIGGER_NETDEV_LINK_100,
TRIGGER_NETDEV_LINK_1000,
diff --git a/target/linux/generic/backport-6.1/807-v6.5-04-net-dsa-mv88e6xxx-fix-88E6393X-family-internal-phys-.patch b/target/linux/generic/backport-6.1/807-v6.5-04-net-dsa-mv88e6xxx-fix-88E6393X-family-internal-phys-.patch
index cadc70fd73..428b7c9b79 100644
--- a/target/linux/generic/backport-6.1/807-v6.5-04-net-dsa-mv88e6xxx-fix-88E6393X-family-internal-phys-.patch
+++ b/target/linux/generic/backport-6.1/807-v6.5-04-net-dsa-mv88e6xxx-fix-88E6393X-family-internal-phys-.patch
@@ -20,7 +20,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
-@@ -5998,7 +5998,8 @@ static const struct mv88e6xxx_info mv88e
+@@ -5999,7 +5999,8 @@ static const struct mv88e6xxx_info mv88e
.name = "Marvell 88E6191X",
.num_databases = 4096,
.num_ports = 11, /* 10 + Z80 */
@@ -30,7 +30,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
.max_vid = 8191,
.max_sid = 63,
.port_base_addr = 0x0,
-@@ -6021,7 +6022,8 @@ static const struct mv88e6xxx_info mv88e
+@@ -6022,7 +6023,8 @@ static const struct mv88e6xxx_info mv88e
.name = "Marvell 88E6193X",
.num_databases = 4096,
.num_ports = 11, /* 10 + Z80 */
@@ -40,7 +40,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
.max_vid = 8191,
.max_sid = 63,
.port_base_addr = 0x0,
-@@ -6340,7 +6342,8 @@ static const struct mv88e6xxx_info mv88e
+@@ -6341,7 +6343,8 @@ static const struct mv88e6xxx_info mv88e
.name = "Marvell 88E6393X",
.num_databases = 4096,
.num_ports = 11, /* 10 + Z80 */
diff --git a/target/linux/generic/backport-6.1/807-v6.5-06-net-dsa-mv88e6xxx-enable-support-for-88E6361-switch.patch b/target/linux/generic/backport-6.1/807-v6.5-06-net-dsa-mv88e6xxx-enable-support-for-88E6361-switch.patch
index 471e6a3903..9a294b59fc 100644
--- a/target/linux/generic/backport-6.1/807-v6.5-06-net-dsa-mv88e6xxx-enable-support-for-88E6361-switch.patch
+++ b/target/linux/generic/backport-6.1/807-v6.5-06-net-dsa-mv88e6xxx-enable-support-for-88E6361-switch.patch
@@ -58,7 +58,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
}
}
-@@ -6285,6 +6291,32 @@ static const struct mv88e6xxx_info mv88e
+@@ -6286,6 +6292,32 @@ static const struct mv88e6xxx_info mv88e
.ptp_support = true,
.ops = &mv88e6352_ops,
},
diff --git a/target/linux/generic/backport-6.1/809-v6.3-0001-nvmem-core-remove-spurious-white-space.patch b/target/linux/generic/backport-6.1/809-v6.3-0001-nvmem-core-remove-spurious-white-space.patch
index 01400fd490..9eec0bc48f 100644
--- a/target/linux/generic/backport-6.1/809-v6.3-0001-nvmem-core-remove-spurious-white-space.patch
+++ b/target/linux/generic/backport-6.1/809-v6.3-0001-nvmem-core-remove-spurious-white-space.patch
@@ -15,7 +15,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
-@@ -764,7 +764,7 @@ struct nvmem_device *nvmem_register(cons
+@@ -763,7 +763,7 @@ struct nvmem_device *nvmem_register(cons
if (!nvmem)
return ERR_PTR(-ENOMEM);
diff --git a/target/linux/generic/backport-6.1/809-v6.3-0002-nvmem-core-add-an-index-parameter-to-the-cell.patch b/target/linux/generic/backport-6.1/809-v6.3-0002-nvmem-core-add-an-index-parameter-to-the-cell.patch
index 454d3bf0ed..84ee69b815 100644
--- a/target/linux/generic/backport-6.1/809-v6.3-0002-nvmem-core-add-an-index-parameter-to-the-cell.patch
+++ b/target/linux/generic/backport-6.1/809-v6.3-0002-nvmem-core-add-an-index-parameter-to-the-cell.patch
@@ -47,7 +47,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
};
static DEFINE_MUTEX(nvmem_mutex);
-@@ -1122,7 +1123,8 @@ struct nvmem_device *devm_nvmem_device_g
+@@ -1121,7 +1122,8 @@ struct nvmem_device *devm_nvmem_device_g
}
EXPORT_SYMBOL_GPL(devm_nvmem_device_get);
@@ -57,7 +57,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
{
struct nvmem_cell *cell;
const char *name = NULL;
-@@ -1141,6 +1143,7 @@ static struct nvmem_cell *nvmem_create_c
+@@ -1140,6 +1142,7 @@ static struct nvmem_cell *nvmem_create_c
cell->id = name;
cell->entry = entry;
@@ -65,7 +65,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
return cell;
}
-@@ -1179,7 +1182,7 @@ nvmem_cell_get_from_lookup(struct device
+@@ -1178,7 +1181,7 @@ nvmem_cell_get_from_lookup(struct device
__nvmem_device_put(nvmem);
cell = ERR_PTR(-ENOENT);
} else {
@@ -74,7 +74,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
if (IS_ERR(cell))
__nvmem_device_put(nvmem);
}
-@@ -1227,15 +1230,27 @@ struct nvmem_cell *of_nvmem_cell_get(str
+@@ -1226,15 +1229,27 @@ struct nvmem_cell *of_nvmem_cell_get(str
struct nvmem_device *nvmem;
struct nvmem_cell_entry *cell_entry;
struct nvmem_cell *cell;
@@ -105,7 +105,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
nvmem_np = of_get_parent(cell_np);
if (!nvmem_np) {
-@@ -1257,7 +1272,7 @@ struct nvmem_cell *of_nvmem_cell_get(str
+@@ -1256,7 +1271,7 @@ struct nvmem_cell *of_nvmem_cell_get(str
return ERR_PTR(-ENOENT);
}
@@ -114,7 +114,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
if (IS_ERR(cell))
__nvmem_device_put(nvmem);
-@@ -1410,8 +1425,8 @@ static void nvmem_shift_read_buffer_in_p
+@@ -1409,8 +1424,8 @@ static void nvmem_shift_read_buffer_in_p
}
static int __nvmem_cell_read(struct nvmem_device *nvmem,
@@ -125,7 +125,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
{
int rc;
-@@ -1425,7 +1440,7 @@ static int __nvmem_cell_read(struct nvme
+@@ -1424,7 +1439,7 @@ static int __nvmem_cell_read(struct nvme
nvmem_shift_read_buffer_in_place(cell, buf);
if (nvmem->cell_post_process) {
@@ -134,7 +134,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
cell->offset, buf, cell->bytes);
if (rc)
return rc;
-@@ -1460,7 +1475,7 @@ void *nvmem_cell_read(struct nvmem_cell
+@@ -1459,7 +1474,7 @@ void *nvmem_cell_read(struct nvmem_cell
if (!buf)
return ERR_PTR(-ENOMEM);
@@ -143,7 +143,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
if (rc) {
kfree(buf);
return ERR_PTR(rc);
-@@ -1773,7 +1788,7 @@ ssize_t nvmem_device_cell_read(struct nv
+@@ -1772,7 +1787,7 @@ ssize_t nvmem_device_cell_read(struct nv
if (rc)
return rc;
diff --git a/target/linux/generic/backport-6.1/809-v6.3-0004-nvmem-core-drop-the-removal-of-the-cells-in-nvmem_ad.patch b/target/linux/generic/backport-6.1/809-v6.3-0004-nvmem-core-drop-the-removal-of-the-cells-in-nvmem_ad.patch
index 8f996eab34..b20c500e7c 100644
--- a/target/linux/generic/backport-6.1/809-v6.3-0004-nvmem-core-drop-the-removal-of-the-cells-in-nvmem_ad.patch
+++ b/target/linux/generic/backport-6.1/809-v6.3-0004-nvmem-core-drop-the-removal-of-the-cells-in-nvmem_ad.patch
@@ -22,7 +22,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
-@@ -515,7 +515,7 @@ static int nvmem_add_cells(struct nvmem_
+@@ -514,7 +514,7 @@ static int nvmem_add_cells(struct nvmem_
int ncells)
{
struct nvmem_cell_entry **cells;
@@ -31,7 +31,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
cells = kcalloc(ncells, sizeof(*cells), GFP_KERNEL);
if (!cells)
-@@ -525,28 +525,22 @@ static int nvmem_add_cells(struct nvmem_
+@@ -524,28 +524,22 @@ static int nvmem_add_cells(struct nvmem_
cells[i] = kzalloc(sizeof(**cells), GFP_KERNEL);
if (!cells[i]) {
rval = -ENOMEM;
diff --git a/target/linux/generic/backport-6.1/809-v6.3-0005-nvmem-core-add-nvmem_add_one_cell.patch b/target/linux/generic/backport-6.1/809-v6.3-0005-nvmem-core-add-nvmem_add_one_cell.patch
index 711ce229b2..df4a02b8c5 100644
--- a/target/linux/generic/backport-6.1/809-v6.3-0005-nvmem-core-add-nvmem_add_one_cell.patch
+++ b/target/linux/generic/backport-6.1/809-v6.3-0005-nvmem-core-add-nvmem_add_one_cell.patch
@@ -19,7 +19,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
-@@ -502,6 +502,36 @@ static int nvmem_cell_info_to_nvmem_cell
+@@ -501,6 +501,36 @@ static int nvmem_cell_info_to_nvmem_cell
}
/**
@@ -56,7 +56,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* nvmem_add_cells() - Add cell information to an nvmem device
*
* @nvmem: nvmem device to add cells to.
-@@ -514,34 +544,15 @@ static int nvmem_add_cells(struct nvmem_
+@@ -513,34 +543,15 @@ static int nvmem_add_cells(struct nvmem_
const struct nvmem_cell_info *info,
int ncells)
{
diff --git a/target/linux/generic/backport-6.1/809-v6.3-0006-nvmem-core-use-nvmem_add_one_cell-in-nvmem_add_cells.patch b/target/linux/generic/backport-6.1/809-v6.3-0006-nvmem-core-use-nvmem_add_one_cell-in-nvmem_add_cells.patch
index e1791e5c83..1b4a3f3ef3 100644
--- a/target/linux/generic/backport-6.1/809-v6.3-0006-nvmem-core-use-nvmem_add_one_cell-in-nvmem_add_cells.patch
+++ b/target/linux/generic/backport-6.1/809-v6.3-0006-nvmem-core-use-nvmem_add_one_cell-in-nvmem_add_cells.patch
@@ -19,7 +19,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
-@@ -688,15 +688,14 @@ static int nvmem_validate_keepouts(struc
+@@ -687,15 +687,14 @@ static int nvmem_validate_keepouts(struc
static int nvmem_add_cells_from_of(struct nvmem_device *nvmem)
{
@@ -39,7 +39,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
addr = of_get_property(child, "reg", &len);
if (!addr)
continue;
-@@ -706,40 +705,24 @@ static int nvmem_add_cells_from_of(struc
+@@ -705,40 +704,24 @@ static int nvmem_add_cells_from_of(struc
return -EINVAL;
}
diff --git a/target/linux/generic/backport-6.1/810-v6.3-i915-Move-list_count-to-list.h-as-list_count_nodes-f.patch b/target/linux/generic/backport-6.1/810-v6.3-i915-Move-list_count-to-list.h-as-list_count_nodes-f.patch
index 5c4206da14..998e453443 100644
--- a/target/linux/generic/backport-6.1/810-v6.3-i915-Move-list_count-to-list.h-as-list_count_nodes-f.patch
+++ b/target/linux/generic/backport-6.1/810-v6.3-i915-Move-list_count-to-list.h-as-list_count_nodes-f.patch
@@ -20,7 +20,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
--- a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
+++ b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
-@@ -4157,17 +4157,6 @@ void intel_execlists_show_requests(struc
+@@ -4153,17 +4153,6 @@ void intel_execlists_show_requests(struc
spin_unlock_irqrestore(&sched_engine->lock, flags);
}
@@ -38,7 +38,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
void intel_execlists_dump_active_requests(struct intel_engine_cs *engine,
struct i915_request *hung_rq,
struct drm_printer *m)
-@@ -4178,8 +4167,8 @@ void intel_execlists_dump_active_request
+@@ -4174,8 +4163,8 @@ void intel_execlists_dump_active_request
intel_engine_dump_active_requests(&engine->sched_engine->requests, hung_rq, m);
diff --git a/target/linux/generic/backport-6.1/811-v6.4-0002-nvmem-core-introduce-NVMEM-layouts.patch b/target/linux/generic/backport-6.1/811-v6.4-0002-nvmem-core-introduce-NVMEM-layouts.patch
index 94cd23c18a..77d2af7269 100644
--- a/target/linux/generic/backport-6.1/811-v6.4-0002-nvmem-core-introduce-NVMEM-layouts.patch
+++ b/target/linux/generic/backport-6.1/811-v6.4-0002-nvmem-core-introduce-NVMEM-layouts.patch
@@ -103,7 +103,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
static int __nvmem_reg_read(struct nvmem_device *nvmem, unsigned int offset,
void *val, size_t bytes)
{
-@@ -728,6 +732,101 @@ static int nvmem_add_cells_from_of(struc
+@@ -727,6 +731,101 @@ static int nvmem_add_cells_from_of(struc
return 0;
}
@@ -205,7 +205,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
/**
* nvmem_register() - Register a nvmem device for given nvmem_config.
* Also creates a binary entry in /sys/bus/nvmem/devices/dev-name/nvmem
-@@ -834,6 +933,12 @@ struct nvmem_device *nvmem_register(cons
+@@ -833,6 +932,12 @@ struct nvmem_device *nvmem_register(cons
goto err_put_device;
}
@@ -218,7 +218,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
if (config->cells) {
rval = nvmem_add_cells(nvmem, config->cells, config->ncells);
if (rval)
-@@ -854,12 +959,17 @@ struct nvmem_device *nvmem_register(cons
+@@ -853,12 +958,17 @@ struct nvmem_device *nvmem_register(cons
if (rval)
goto err_remove_cells;
@@ -236,7 +236,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
if (config->compat)
nvmem_sysfs_remove_compat(nvmem, config);
err_put_device:
-@@ -881,6 +991,7 @@ static void nvmem_device_release(struct
+@@ -880,6 +990,7 @@ static void nvmem_device_release(struct
device_remove_bin_file(nvmem->base_dev, &nvmem->eeprom);
nvmem_device_remove_all_cells(nvmem);
@@ -244,7 +244,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
device_unregister(&nvmem->dev);
}
-@@ -1246,6 +1357,15 @@ struct nvmem_cell *of_nvmem_cell_get(str
+@@ -1245,6 +1356,15 @@ struct nvmem_cell *of_nvmem_cell_get(str
return ERR_PTR(-EINVAL);
}
diff --git a/target/linux/generic/backport-6.1/811-v6.4-0003-nvmem-core-handle-the-absence-of-expected-layouts.patch b/target/linux/generic/backport-6.1/811-v6.4-0003-nvmem-core-handle-the-absence-of-expected-layouts.patch
index 6fa7b6382d..40ce320b6e 100644
--- a/target/linux/generic/backport-6.1/811-v6.4-0003-nvmem-core-handle-the-absence-of-expected-layouts.patch
+++ b/target/linux/generic/backport-6.1/811-v6.4-0003-nvmem-core-handle-the-absence-of-expected-layouts.patch
@@ -28,7 +28,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
-@@ -755,7 +755,7 @@ EXPORT_SYMBOL_GPL(nvmem_layout_unregiste
+@@ -754,7 +754,7 @@ EXPORT_SYMBOL_GPL(nvmem_layout_unregiste
static struct nvmem_layout *nvmem_layout_get(struct nvmem_device *nvmem)
{
struct device_node *layout_np, *np = nvmem->dev.of_node;
@@ -37,7 +37,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
layout_np = of_get_child_by_name(np, "nvmem-layout");
if (!layout_np)
-@@ -938,6 +938,13 @@ struct nvmem_device *nvmem_register(cons
+@@ -937,6 +937,13 @@ struct nvmem_device *nvmem_register(cons
* pointer will be NULL and nvmem_layout_put() will be a noop.
*/
nvmem->layout = config->layout ?: nvmem_layout_get(nvmem);
@@ -51,7 +51,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
if (config->cells) {
rval = nvmem_add_cells(nvmem, config->cells, config->ncells);
-@@ -970,6 +977,7 @@ struct nvmem_device *nvmem_register(cons
+@@ -969,6 +976,7 @@ struct nvmem_device *nvmem_register(cons
err_remove_cells:
nvmem_device_remove_all_cells(nvmem);
nvmem_layout_put(nvmem->layout);
diff --git a/target/linux/generic/backport-6.1/811-v6.4-0004-nvmem-core-request-layout-modules-loading.patch b/target/linux/generic/backport-6.1/811-v6.4-0004-nvmem-core-request-layout-modules-loading.patch
index b9341666f9..13712d76c6 100644
--- a/target/linux/generic/backport-6.1/811-v6.4-0004-nvmem-core-request-layout-modules-loading.patch
+++ b/target/linux/generic/backport-6.1/811-v6.4-0004-nvmem-core-request-layout-modules-loading.patch
@@ -36,7 +36,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
#include <linux/slab.h>
struct nvmem_device {
-@@ -761,6 +762,13 @@ static struct nvmem_layout *nvmem_layout
+@@ -760,6 +761,13 @@ static struct nvmem_layout *nvmem_layout
if (!layout_np)
return NULL;
diff --git a/target/linux/generic/backport-6.1/811-v6.4-0005-nvmem-core-add-per-cell-post-processing.patch b/target/linux/generic/backport-6.1/811-v6.4-0005-nvmem-core-add-per-cell-post-processing.patch
index 53628cd4e4..50f3504132 100644
--- a/target/linux/generic/backport-6.1/811-v6.4-0005-nvmem-core-add-per-cell-post-processing.patch
+++ b/target/linux/generic/backport-6.1/811-v6.4-0005-nvmem-core-add-per-cell-post-processing.patch
@@ -28,7 +28,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
struct device_node *np;
struct nvmem_device *nvmem;
struct list_head node;
-@@ -470,6 +471,7 @@ static int nvmem_cell_info_to_nvmem_cell
+@@ -469,6 +470,7 @@ static int nvmem_cell_info_to_nvmem_cell
cell->offset = info->offset;
cell->bytes = info->bytes;
cell->name = info->name;
@@ -36,7 +36,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
cell->bit_offset = info->bit_offset;
cell->nbits = info->nbits;
-@@ -1563,6 +1565,13 @@ static int __nvmem_cell_read(struct nvme
+@@ -1562,6 +1564,13 @@ static int __nvmem_cell_read(struct nvme
if (cell->bit_offset || cell->nbits)
nvmem_shift_read_buffer_in_place(cell, buf);
@@ -50,7 +50,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
if (nvmem->cell_post_process) {
rc = nvmem->cell_post_process(nvmem->priv, id, index,
cell->offset, buf, cell->bytes);
-@@ -1671,6 +1680,14 @@ static int __nvmem_cell_entry_write(stru
+@@ -1670,6 +1679,14 @@ static int __nvmem_cell_entry_write(stru
(cell->bit_offset == 0 && len != cell->bytes))
return -EINVAL;
diff --git a/target/linux/generic/backport-6.1/811-v6.4-0006-nvmem-core-allow-to-modify-a-cell-before-adding-it.patch b/target/linux/generic/backport-6.1/811-v6.4-0006-nvmem-core-allow-to-modify-a-cell-before-adding-it.patch
index 32990148c8..1b77992a2b 100644
--- a/target/linux/generic/backport-6.1/811-v6.4-0006-nvmem-core-allow-to-modify-a-cell-before-adding-it.patch
+++ b/target/linux/generic/backport-6.1/811-v6.4-0006-nvmem-core-allow-to-modify-a-cell-before-adding-it.patch
@@ -18,7 +18,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
-@@ -695,6 +695,7 @@ static int nvmem_validate_keepouts(struc
+@@ -694,6 +694,7 @@ static int nvmem_validate_keepouts(struc
static int nvmem_add_cells_from_of(struct nvmem_device *nvmem)
{
@@ -26,7 +26,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
struct device *dev = &nvmem->dev;
struct device_node *child;
const __be32 *addr;
-@@ -724,6 +725,9 @@ static int nvmem_add_cells_from_of(struc
+@@ -723,6 +724,9 @@ static int nvmem_add_cells_from_of(struc
info.np = of_node_get(child);
diff --git a/target/linux/generic/backport-6.1/811-v6.4-0008-nvmem-cell-drop-global-cell_post_process.patch b/target/linux/generic/backport-6.1/811-v6.4-0008-nvmem-cell-drop-global-cell_post_process.patch
index eac202b882..e6f4be261c 100644
--- a/target/linux/generic/backport-6.1/811-v6.4-0008-nvmem-cell-drop-global-cell_post_process.patch
+++ b/target/linux/generic/backport-6.1/811-v6.4-0008-nvmem-cell-drop-global-cell_post_process.patch
@@ -26,7 +26,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
struct gpio_desc *wp_gpio;
struct nvmem_layout *layout;
void *priv;
-@@ -903,7 +902,6 @@ struct nvmem_device *nvmem_register(cons
+@@ -902,7 +901,6 @@ struct nvmem_device *nvmem_register(cons
nvmem->type = config->type;
nvmem->reg_read = config->reg_read;
nvmem->reg_write = config->reg_write;
@@ -34,7 +34,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
nvmem->keepout = config->keepout;
nvmem->nkeepout = config->nkeepout;
if (config->of_node)
-@@ -1575,13 +1573,6 @@ static int __nvmem_cell_read(struct nvme
+@@ -1574,13 +1572,6 @@ static int __nvmem_cell_read(struct nvme
if (rc)
return rc;
}
diff --git a/target/linux/generic/backport-6.1/811-v6.4-0009-nvmem-core-provide-own-priv-pointer-in-post-process-.patch b/target/linux/generic/backport-6.1/811-v6.4-0009-nvmem-core-provide-own-priv-pointer-in-post-process-.patch
index 46b30a2ed9..b39626f6e7 100644
--- a/target/linux/generic/backport-6.1/811-v6.4-0009-nvmem-core-provide-own-priv-pointer-in-post-process-.patch
+++ b/target/linux/generic/backport-6.1/811-v6.4-0009-nvmem-core-provide-own-priv-pointer-in-post-process-.patch
@@ -29,7 +29,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
struct device_node *np;
struct nvmem_device *nvmem;
struct list_head node;
-@@ -471,6 +472,7 @@ static int nvmem_cell_info_to_nvmem_cell
+@@ -470,6 +471,7 @@ static int nvmem_cell_info_to_nvmem_cell
cell->bytes = info->bytes;
cell->name = info->name;
cell->read_post_process = info->read_post_process;
@@ -37,7 +37,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
cell->bit_offset = info->bit_offset;
cell->nbits = info->nbits;
-@@ -1568,7 +1570,7 @@ static int __nvmem_cell_read(struct nvme
+@@ -1567,7 +1569,7 @@ static int __nvmem_cell_read(struct nvme
nvmem_shift_read_buffer_in_place(cell, buf);
if (cell->read_post_process) {
diff --git a/target/linux/generic/backport-6.1/811-v6.4-0017-nvmem-core-support-specifying-both-cell-raw-data-pos.patch b/target/linux/generic/backport-6.1/811-v6.4-0017-nvmem-core-support-specifying-both-cell-raw-data-pos.patch
index eeb407e9bb..a1ebd53d07 100644
--- a/target/linux/generic/backport-6.1/811-v6.4-0017-nvmem-core-support-specifying-both-cell-raw-data-pos.patch
+++ b/target/linux/generic/backport-6.1/811-v6.4-0017-nvmem-core-support-specifying-both-cell-raw-data-pos.patch
@@ -51,7 +51,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
int bytes;
int bit_offset;
int nbits;
-@@ -469,6 +470,7 @@ static int nvmem_cell_info_to_nvmem_cell
+@@ -468,6 +469,7 @@ static int nvmem_cell_info_to_nvmem_cell
{
cell->nvmem = nvmem;
cell->offset = info->offset;
@@ -59,7 +59,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
cell->bytes = info->bytes;
cell->name = info->name;
cell->read_post_process = info->read_post_process;
-@@ -1560,7 +1562,7 @@ static int __nvmem_cell_read(struct nvme
+@@ -1559,7 +1561,7 @@ static int __nvmem_cell_read(struct nvme
{
int rc;
@@ -68,7 +68,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
if (rc)
return rc;
-@@ -1571,7 +1573,7 @@ static int __nvmem_cell_read(struct nvme
+@@ -1570,7 +1572,7 @@ static int __nvmem_cell_read(struct nvme
if (cell->read_post_process) {
rc = cell->read_post_process(cell->priv, id, index,
@@ -77,7 +77,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
if (rc)
return rc;
}
-@@ -1594,14 +1596,15 @@ static int __nvmem_cell_read(struct nvme
+@@ -1593,14 +1595,15 @@ static int __nvmem_cell_read(struct nvme
*/
void *nvmem_cell_read(struct nvmem_cell *cell, size_t *len)
{
diff --git a/target/linux/generic/backport-6.1/813-v6.5-0011-nvmem-core-add-support-for-fixed-cells-layout.patch b/target/linux/generic/backport-6.1/813-v6.5-0011-nvmem-core-add-support-for-fixed-cells-layout.patch
index 59b2f9fa2c..3b4654822a 100644
--- a/target/linux/generic/backport-6.1/813-v6.5-0011-nvmem-core-add-support-for-fixed-cells-layout.patch
+++ b/target/linux/generic/backport-6.1/813-v6.5-0011-nvmem-core-add-support-for-fixed-cells-layout.patch
@@ -27,7 +27,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
-@@ -696,7 +696,7 @@ static int nvmem_validate_keepouts(struc
+@@ -695,7 +695,7 @@ static int nvmem_validate_keepouts(struc
return 0;
}
@@ -36,7 +36,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
{
struct nvmem_layout *layout = nvmem->layout;
struct device *dev = &nvmem->dev;
-@@ -704,7 +704,7 @@ static int nvmem_add_cells_from_of(struc
+@@ -703,7 +703,7 @@ static int nvmem_add_cells_from_of(struc
const __be32 *addr;
int len, ret;
@@ -45,7 +45,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
struct nvmem_cell_info info = {0};
addr = of_get_property(child, "reg", &len);
-@@ -742,6 +742,28 @@ static int nvmem_add_cells_from_of(struc
+@@ -741,6 +741,28 @@ static int nvmem_add_cells_from_of(struc
return 0;
}
@@ -74,7 +74,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
int __nvmem_layout_register(struct nvmem_layout *layout, struct module *owner)
{
layout->owner = owner;
-@@ -972,7 +994,7 @@ struct nvmem_device *nvmem_register(cons
+@@ -971,7 +993,7 @@ struct nvmem_device *nvmem_register(cons
if (rval)
goto err_remove_cells;
@@ -83,7 +83,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
if (rval)
goto err_remove_cells;
-@@ -982,6 +1004,10 @@ struct nvmem_device *nvmem_register(cons
+@@ -981,6 +1003,10 @@ struct nvmem_device *nvmem_register(cons
if (rval)
goto err_remove_cells;
diff --git a/target/linux/generic/backport-6.1/814-v6.6-0014-nvmem-core-Create-all-cells-before-adding-the-nvmem-.patch b/target/linux/generic/backport-6.1/814-v6.6-0014-nvmem-core-Create-all-cells-before-adding-the-nvmem-.patch
index f9532f39c3..990ce8ecf1 100644
--- a/target/linux/generic/backport-6.1/814-v6.6-0014-nvmem-core-Create-all-cells-before-adding-the-nvmem-.patch
+++ b/target/linux/generic/backport-6.1/814-v6.6-0014-nvmem-core-Create-all-cells-before-adding-the-nvmem-.patch
@@ -15,7 +15,7 @@ Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
-@@ -998,17 +998,17 @@ struct nvmem_device *nvmem_register(cons
+@@ -997,17 +997,17 @@ struct nvmem_device *nvmem_register(cons
if (rval)
goto err_remove_cells;
diff --git a/target/linux/generic/backport-6.1/814-v6.6-0016-nvmem-core-Do-not-open-code-existing-functions.patch b/target/linux/generic/backport-6.1/814-v6.6-0016-nvmem-core-Do-not-open-code-existing-functions.patch
index 28d8bba194..4ebf229695 100644
--- a/target/linux/generic/backport-6.1/814-v6.6-0016-nvmem-core-Do-not-open-code-existing-functions.patch
+++ b/target/linux/generic/backport-6.1/814-v6.6-0016-nvmem-core-Do-not-open-code-existing-functions.patch
@@ -14,7 +14,7 @@ Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
-@@ -786,10 +786,10 @@ EXPORT_SYMBOL_GPL(nvmem_layout_unregiste
+@@ -785,10 +785,10 @@ EXPORT_SYMBOL_GPL(nvmem_layout_unregiste
static struct nvmem_layout *nvmem_layout_get(struct nvmem_device *nvmem)
{
diff --git a/target/linux/generic/backport-6.1/814-v6.6-0017-nvmem-core-Notify-when-a-new-layout-is-registered.patch b/target/linux/generic/backport-6.1/814-v6.6-0017-nvmem-core-Notify-when-a-new-layout-is-registered.patch
index b62a0e18da..6803397d60 100644
--- a/target/linux/generic/backport-6.1/814-v6.6-0017-nvmem-core-Notify-when-a-new-layout-is-registered.patch
+++ b/target/linux/generic/backport-6.1/814-v6.6-0017-nvmem-core-Notify-when-a-new-layout-is-registered.patch
@@ -14,7 +14,7 @@ Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
-@@ -772,12 +772,16 @@ int __nvmem_layout_register(struct nvmem
+@@ -771,12 +771,16 @@ int __nvmem_layout_register(struct nvmem
list_add(&layout->node, &nvmem_layouts);
spin_unlock(&nvmem_layout_lock);
diff --git a/target/linux/generic/backport-6.1/816-v6.7-0002-nvmem-add-explicit-config-option-to-read-old-syntax-.patch b/target/linux/generic/backport-6.1/816-v6.7-0002-nvmem-add-explicit-config-option-to-read-old-syntax-.patch
index be293e6f2a..547122ae48 100644
--- a/target/linux/generic/backport-6.1/816-v6.7-0002-nvmem-add-explicit-config-option-to-read-old-syntax-.patch
+++ b/target/linux/generic/backport-6.1/816-v6.7-0002-nvmem-add-explicit-config-option-to-read-old-syntax-.patch
@@ -95,7 +95,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
.stride = sizeof(u32),
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
-@@ -998,9 +998,11 @@ struct nvmem_device *nvmem_register(cons
+@@ -997,9 +997,11 @@ struct nvmem_device *nvmem_register(cons
if (rval)
goto err_remove_cells;
@@ -132,7 +132,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
imx_ocotp_nvmem_config.priv = priv;
--- a/drivers/nvmem/meson-efuse.c
+++ b/drivers/nvmem/meson-efuse.c
-@@ -74,6 +74,7 @@ static int meson_efuse_probe(struct plat
+@@ -80,6 +80,7 @@ static int meson_efuse_probe(struct plat
econfig->dev = dev;
econfig->name = dev_name(dev);
diff --git a/target/linux/generic/backport-6.1/816-v6.7-0004-Revert-nvmem-add-new-config-option.patch b/target/linux/generic/backport-6.1/816-v6.7-0004-Revert-nvmem-add-new-config-option.patch
index 7d80ad37f1..1ed7c43332 100644
--- a/target/linux/generic/backport-6.1/816-v6.7-0004-Revert-nvmem-add-new-config-option.patch
+++ b/target/linux/generic/backport-6.1/816-v6.7-0004-Revert-nvmem-add-new-config-option.patch
@@ -48,7 +48,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
mtd->nvmem = nvmem_register(&config);
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
-@@ -936,7 +936,7 @@ struct nvmem_device *nvmem_register(cons
+@@ -935,7 +935,7 @@ struct nvmem_device *nvmem_register(cons
nvmem->nkeepout = config->nkeepout;
if (config->of_node)
nvmem->dev.of_node = config->of_node;
diff --git a/target/linux/generic/backport-6.1/816-v6.7-0005-nvmem-Do-not-expect-fixed-layouts-to-grab-a-layout-d.patch b/target/linux/generic/backport-6.1/816-v6.7-0005-nvmem-Do-not-expect-fixed-layouts-to-grab-a-layout-d.patch
index bd5ceaabf7..65b8878310 100644
--- a/target/linux/generic/backport-6.1/816-v6.7-0005-nvmem-Do-not-expect-fixed-layouts-to-grab-a-layout-d.patch
+++ b/target/linux/generic/backport-6.1/816-v6.7-0005-nvmem-Do-not-expect-fixed-layouts-to-grab-a-layout-d.patch
@@ -30,7 +30,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
-@@ -797,6 +797,12 @@ static struct nvmem_layout *nvmem_layout
+@@ -796,6 +796,12 @@ static struct nvmem_layout *nvmem_layout
if (!layout_np)
return NULL;
diff --git a/target/linux/generic/backport-6.1/819-v6.8-0001-nvmem-Move-of_nvmem_layout_get_container-in-another-.patch b/target/linux/generic/backport-6.1/819-v6.8-0001-nvmem-Move-of_nvmem_layout_get_container-in-another-.patch
index 2093fac8a1..59175c8051 100644
--- a/target/linux/generic/backport-6.1/819-v6.8-0001-nvmem-Move-of_nvmem_layout_get_container-in-another-.patch
+++ b/target/linux/generic/backport-6.1/819-v6.8-0001-nvmem-Move-of_nvmem_layout_get_container-in-another-.patch
@@ -25,7 +25,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
-@@ -848,14 +848,6 @@ static int nvmem_add_cells_from_layout(s
+@@ -847,14 +847,6 @@ static int nvmem_add_cells_from_layout(s
}
#if IS_ENABLED(CONFIG_OF)
diff --git a/target/linux/generic/backport-6.1/819-v6.8-0003-nvmem-Simplify-the-add_cells-hook.patch b/target/linux/generic/backport-6.1/819-v6.8-0003-nvmem-Simplify-the-add_cells-hook.patch
index db2d8c1b46..1f39dfea2f 100644
--- a/target/linux/generic/backport-6.1/819-v6.8-0003-nvmem-Simplify-the-add_cells-hook.patch
+++ b/target/linux/generic/backport-6.1/819-v6.8-0003-nvmem-Simplify-the-add_cells-hook.patch
@@ -20,7 +20,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
-@@ -817,7 +817,7 @@ static int nvmem_add_cells_from_layout(s
+@@ -816,7 +816,7 @@ static int nvmem_add_cells_from_layout(s
int ret;
if (layout && layout->add_cells) {
diff --git a/target/linux/generic/backport-6.1/819-v6.8-0004-nvmem-Move-and-rename-fixup_cell_info.patch b/target/linux/generic/backport-6.1/819-v6.8-0004-nvmem-Move-and-rename-fixup_cell_info.patch
index 65aa37f834..c2968f2c67 100644
--- a/target/linux/generic/backport-6.1/819-v6.8-0004-nvmem-Move-and-rename-fixup_cell_info.patch
+++ b/target/linux/generic/backport-6.1/819-v6.8-0004-nvmem-Move-and-rename-fixup_cell_info.patch
@@ -25,7 +25,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
-@@ -676,7 +676,6 @@ static int nvmem_validate_keepouts(struc
+@@ -675,7 +675,6 @@ static int nvmem_validate_keepouts(struc
static int nvmem_add_cells_from_dt(struct nvmem_device *nvmem, struct device_node *np)
{
@@ -33,7 +33,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
struct device *dev = &nvmem->dev;
struct device_node *child;
const __be32 *addr;
-@@ -706,8 +705,8 @@ static int nvmem_add_cells_from_dt(struc
+@@ -705,8 +704,8 @@ static int nvmem_add_cells_from_dt(struc
info.np = of_node_get(child);
@@ -44,7 +44,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
ret = nvmem_add_one_cell(nvmem, &info);
kfree(info.name);
-@@ -896,6 +895,7 @@ struct nvmem_device *nvmem_register(cons
+@@ -895,6 +894,7 @@ struct nvmem_device *nvmem_register(cons
kref_init(&nvmem->refcnt);
INIT_LIST_HEAD(&nvmem->cells);
diff --git a/target/linux/generic/backport-6.1/819-v6.8-0005-nvmem-core-Rework-layouts-to-become-regular-devices.patch b/target/linux/generic/backport-6.1/819-v6.8-0005-nvmem-core-Rework-layouts-to-become-regular-devices.patch
index 1881332340..9a19dc4452 100644
--- a/target/linux/generic/backport-6.1/819-v6.8-0005-nvmem-core-Rework-layouts-to-become-regular-devices.patch
+++ b/target/linux/generic/backport-6.1/819-v6.8-0005-nvmem-core-Rework-layouts-to-become-regular-devices.patch
@@ -84,7 +84,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
static int __nvmem_reg_read(struct nvmem_device *nvmem, unsigned int offset,
void *val, size_t bytes)
{
-@@ -741,97 +738,22 @@ static int nvmem_add_cells_from_fixed_la
+@@ -740,97 +737,22 @@ static int nvmem_add_cells_from_fixed_la
return err;
}
@@ -189,7 +189,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
const void *nvmem_layout_get_match_data(struct nvmem_device *nvmem,
struct nvmem_layout *layout)
{
-@@ -839,7 +761,7 @@ const void *nvmem_layout_get_match_data(
+@@ -838,7 +760,7 @@ const void *nvmem_layout_get_match_data(
const struct of_device_id *match;
layout_np = of_nvmem_layout_get_container(nvmem);
@@ -198,7 +198,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
return match ? match->data : NULL;
}
-@@ -951,19 +873,6 @@ struct nvmem_device *nvmem_register(cons
+@@ -950,19 +872,6 @@ struct nvmem_device *nvmem_register(cons
goto err_put_device;
}
@@ -218,7 +218,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
if (config->cells) {
rval = nvmem_add_cells(nvmem, config->cells, config->ncells);
if (rval)
-@@ -984,24 +893,24 @@ struct nvmem_device *nvmem_register(cons
+@@ -983,24 +892,24 @@ struct nvmem_device *nvmem_register(cons
if (rval)
goto err_remove_cells;
@@ -249,7 +249,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
if (config->compat)
nvmem_sysfs_remove_compat(nvmem, config);
err_put_device:
-@@ -1023,7 +932,7 @@ static void nvmem_device_release(struct
+@@ -1022,7 +931,7 @@ static void nvmem_device_release(struct
device_remove_bin_file(nvmem->base_dev, &nvmem->eeprom);
nvmem_device_remove_all_cells(nvmem);
@@ -258,7 +258,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
device_unregister(&nvmem->dev);
}
-@@ -1325,6 +1234,12 @@ nvmem_cell_get_from_lookup(struct device
+@@ -1324,6 +1233,12 @@ nvmem_cell_get_from_lookup(struct device
return cell;
}
@@ -271,7 +271,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
#if IS_ENABLED(CONFIG_OF)
static struct nvmem_cell_entry *
nvmem_find_cell_entry_by_node(struct nvmem_device *nvmem, struct device_node *np)
-@@ -1343,6 +1258,18 @@ nvmem_find_cell_entry_by_node(struct nvm
+@@ -1342,6 +1257,18 @@ nvmem_find_cell_entry_by_node(struct nvm
return cell;
}
@@ -290,7 +290,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
/**
* of_nvmem_cell_get() - Get a nvmem cell from given device node and cell id
*
-@@ -1405,16 +1332,29 @@ struct nvmem_cell *of_nvmem_cell_get(str
+@@ -1404,16 +1331,29 @@ struct nvmem_cell *of_nvmem_cell_get(str
return ERR_CAST(nvmem);
}
@@ -322,7 +322,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
return cell;
}
-@@ -1528,6 +1468,7 @@ void nvmem_cell_put(struct nvmem_cell *c
+@@ -1527,6 +1467,7 @@ void nvmem_cell_put(struct nvmem_cell *c
kfree(cell);
__nvmem_device_put(nvmem);
@@ -330,7 +330,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
}
EXPORT_SYMBOL_GPL(nvmem_cell_put);
-@@ -2105,11 +2046,22 @@ EXPORT_SYMBOL_GPL(nvmem_dev_name);
+@@ -2104,11 +2045,22 @@ EXPORT_SYMBOL_GPL(nvmem_dev_name);
static int __init nvmem_init(void)
{
diff --git a/target/linux/generic/backport-6.1/819-v6.8-0006-nvmem-core-Expose-cells-through-sysfs.patch b/target/linux/generic/backport-6.1/819-v6.8-0006-nvmem-core-Expose-cells-through-sysfs.patch
index 89872bec2e..07e44d7b21 100644
--- a/target/linux/generic/backport-6.1/819-v6.8-0006-nvmem-core-Expose-cells-through-sysfs.patch
+++ b/target/linux/generic/backport-6.1/819-v6.8-0006-nvmem-core-Expose-cells-through-sysfs.patch
@@ -111,7 +111,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
static struct bin_attribute bin_attr_nvmem_eeprom_compat = {
.attr = {
.name = "eeprom",
-@@ -381,6 +428,68 @@ static void nvmem_sysfs_remove_compat(st
+@@ -380,6 +427,68 @@ static void nvmem_sysfs_remove_compat(st
device_remove_bin_file(nvmem->base_dev, &nvmem->eeprom);
}
@@ -180,7 +180,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
#else /* CONFIG_NVMEM_SYSFS */
static int nvmem_sysfs_setup_compat(struct nvmem_device *nvmem,
-@@ -740,11 +849,25 @@ static int nvmem_add_cells_from_fixed_la
+@@ -739,11 +848,25 @@ static int nvmem_add_cells_from_fixed_la
int nvmem_layout_register(struct nvmem_layout *layout)
{
@@ -207,7 +207,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
}
EXPORT_SYMBOL_GPL(nvmem_layout_register);
-@@ -903,10 +1026,20 @@ struct nvmem_device *nvmem_register(cons
+@@ -902,10 +1025,20 @@ struct nvmem_device *nvmem_register(cons
if (rval)
goto err_remove_dev;
diff --git a/target/linux/generic/backport-6.1/819-v6.8-0008-nvmem-layouts-refactor-.add_cells-callback-arguments.patch b/target/linux/generic/backport-6.1/819-v6.8-0008-nvmem-layouts-refactor-.add_cells-callback-arguments.patch
index 1bf3ba35b6..400004c617 100644
--- a/target/linux/generic/backport-6.1/819-v6.8-0008-nvmem-layouts-refactor-.add_cells-callback-arguments.patch
+++ b/target/linux/generic/backport-6.1/819-v6.8-0008-nvmem-layouts-refactor-.add_cells-callback-arguments.patch
@@ -44,7 +44,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
-@@ -855,7 +855,7 @@ int nvmem_layout_register(struct nvmem_l
+@@ -854,7 +854,7 @@ int nvmem_layout_register(struct nvmem_l
return -EINVAL;
/* Populate the cells */
diff --git a/target/linux/generic/backport-6.1/819-v6.8-0009-nvmem-drop-nvmem_layout_get_match_data.patch b/target/linux/generic/backport-6.1/819-v6.8-0009-nvmem-drop-nvmem_layout_get_match_data.patch
index 514b5f2de5..510f3dd841 100644
--- a/target/linux/generic/backport-6.1/819-v6.8-0009-nvmem-drop-nvmem_layout_get_match_data.patch
+++ b/target/linux/generic/backport-6.1/819-v6.8-0009-nvmem-drop-nvmem_layout_get_match_data.patch
@@ -24,7 +24,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
-@@ -877,19 +877,6 @@ void nvmem_layout_unregister(struct nvme
+@@ -876,19 +876,6 @@ void nvmem_layout_unregister(struct nvme
}
EXPORT_SYMBOL_GPL(nvmem_layout_unregister);
diff --git a/target/linux/generic/backport-6.1/819-v6.8-0010-nvmem-core-add-nvmem_dev_size-helper.patch b/target/linux/generic/backport-6.1/819-v6.8-0010-nvmem-core-add-nvmem_dev_size-helper.patch
index aa0bbaa0c5..ccdcc09736 100644
--- a/target/linux/generic/backport-6.1/819-v6.8-0010-nvmem-core-add-nvmem_dev_size-helper.patch
+++ b/target/linux/generic/backport-6.1/819-v6.8-0010-nvmem-core-add-nvmem_dev_size-helper.patch
@@ -21,7 +21,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
-@@ -2164,6 +2164,19 @@ const char *nvmem_dev_name(struct nvmem_
+@@ -2163,6 +2163,19 @@ const char *nvmem_dev_name(struct nvmem_
}
EXPORT_SYMBOL_GPL(nvmem_dev_name);
diff --git a/target/linux/generic/backport-6.1/823-v6.9-0002-nvmem-mtk-efuse-Register-MediaTek-socinfo-driver-fro.patch b/target/linux/generic/backport-6.1/823-v6.9-0002-nvmem-mtk-efuse-Register-MediaTek-socinfo-driver-fro.patch
new file mode 100644
index 0000000000..8e7c8233e2
--- /dev/null
+++ b/target/linux/generic/backport-6.1/823-v6.9-0002-nvmem-mtk-efuse-Register-MediaTek-socinfo-driver-fro.patch
@@ -0,0 +1,69 @@
+From 998f0633773b3432829fe45d2cd2ffb842f3c78e Mon Sep 17 00:00:00 2001
+From: William-tw Lin <william-tw.lin@mediatek.com>
+Date: Sat, 24 Feb 2024 11:45:07 +0000
+Subject: [PATCH] nvmem: mtk-efuse: Register MediaTek socinfo driver from efuse
+
+The socinfo driver reads chip information from eFuses and does not need
+any devicetree node. Register it from mtk-efuse.
+
+While at it, also add the name for this driver's nvmem_config.
+
+Signed-off-by: William-tw Lin <william-tw.lin@mediatek.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240224114516.86365-3-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/mtk-efuse.c | 21 ++++++++++++++++++++-
+ 1 file changed, 20 insertions(+), 1 deletion(-)
+
+--- a/drivers/nvmem/mtk-efuse.c
++++ b/drivers/nvmem/mtk-efuse.c
+@@ -68,6 +68,7 @@ static int mtk_efuse_probe(struct platfo
+ struct nvmem_config econfig = {};
+ struct mtk_efuse_priv *priv;
+ const struct mtk_efuse_pdata *pdata;
++ struct platform_device *socinfo;
+
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+@@ -85,11 +86,20 @@ static int mtk_efuse_probe(struct platfo
+ econfig.size = resource_size(res);
+ econfig.priv = priv;
+ econfig.dev = dev;
++ econfig.name = "mtk-efuse";
+ if (pdata->uses_post_processing)
+ econfig.fixup_dt_cell_info = &mtk_efuse_fixup_dt_cell_info;
+ nvmem = devm_nvmem_register(dev, &econfig);
++ if (IS_ERR(nvmem))
++ return PTR_ERR(nvmem);
+
+- return PTR_ERR_OR_ZERO(nvmem);
++ socinfo = platform_device_register_data(&pdev->dev, "mtk-socinfo",
++ PLATFORM_DEVID_AUTO, NULL, 0);
++ if (IS_ERR(socinfo))
++ dev_info(dev, "MediaTek SoC Information will be unavailable\n");
++
++ platform_set_drvdata(pdev, socinfo);
++ return 0;
+ }
+
+ static const struct mtk_efuse_pdata mtk_mt8186_efuse_pdata = {
+@@ -108,8 +118,17 @@ static const struct of_device_id mtk_efu
+ };
+ MODULE_DEVICE_TABLE(of, mtk_efuse_of_match);
+
++static void mtk_efuse_remove(struct platform_device *pdev)
++{
++ struct platform_device *socinfo = platform_get_drvdata(pdev);
++
++ if (!IS_ERR_OR_NULL(socinfo))
++ platform_device_unregister(socinfo);
++}
++
+ static struct platform_driver mtk_efuse_driver = {
+ .probe = mtk_efuse_probe,
++ .remove_new = mtk_efuse_remove,
+ .driver = {
+ .name = "mediatek,efuse",
+ .of_match_table = mtk_efuse_of_match,
diff --git a/target/linux/generic/backport-6.1/823-v6.9-0003-nvmem-zynqmp_nvmem-zynqmp_nvmem_probe-cleanup.patch b/target/linux/generic/backport-6.1/823-v6.9-0003-nvmem-zynqmp_nvmem-zynqmp_nvmem_probe-cleanup.patch
new file mode 100644
index 0000000000..0f90e548a2
--- /dev/null
+++ b/target/linux/generic/backport-6.1/823-v6.9-0003-nvmem-zynqmp_nvmem-zynqmp_nvmem_probe-cleanup.patch
@@ -0,0 +1,97 @@
+From 29be47fcd6a06ea2e79eeeca6e69ad1e23254a69 Mon Sep 17 00:00:00 2001
+From: Praveen Teja Kundanala <praveen.teja.kundanala@amd.com>
+Date: Sat, 24 Feb 2024 11:45:11 +0000
+Subject: [PATCH] nvmem: zynqmp_nvmem: zynqmp_nvmem_probe cleanup
+
+- Remove static nvmem_config declaration
+- Remove zynqmp_nvmem_data
+
+Signed-off-by: Praveen Teja Kundanala <praveen.teja.kundanala@amd.com>
+Acked-by: Kalyani Akula <Kalyani.akula@amd.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240224114516.86365-7-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/zynqmp_nvmem.c | 37 ++++++++++++------------------------
+ 1 file changed, 12 insertions(+), 25 deletions(-)
+
+--- a/drivers/nvmem/zynqmp_nvmem.c
++++ b/drivers/nvmem/zynqmp_nvmem.c
+@@ -1,6 +1,7 @@
+ // SPDX-License-Identifier: GPL-2.0+
+ /*
+ * Copyright (C) 2019 Xilinx, Inc.
++ * Copyright (C) 2022 - 2023, Advanced Micro Devices, Inc.
+ */
+
+ #include <linux/module.h>
+@@ -11,36 +12,25 @@
+
+ #define SILICON_REVISION_MASK 0xF
+
+-struct zynqmp_nvmem_data {
+- struct device *dev;
+- struct nvmem_device *nvmem;
+-};
+
+ static int zynqmp_nvmem_read(void *context, unsigned int offset,
+ void *val, size_t bytes)
+ {
++ struct device *dev = context;
+ int ret;
+- int idcode, version;
+- struct zynqmp_nvmem_data *priv = context;
++ int idcode;
++ int version;
+
+ ret = zynqmp_pm_get_chipid(&idcode, &version);
+ if (ret < 0)
+ return ret;
+
+- dev_dbg(priv->dev, "Read chipid val %x %x\n", idcode, version);
++ dev_dbg(dev, "Read chipid val %x %x\n", idcode, version);
+ *(int *)val = version & SILICON_REVISION_MASK;
+
+ return 0;
+ }
+
+-static struct nvmem_config econfig = {
+- .name = "zynqmp-nvmem",
+- .owner = THIS_MODULE,
+- .word_size = 1,
+- .size = 1,
+- .read_only = true,
+-};
+-
+ static const struct of_device_id zynqmp_nvmem_match[] = {
+ { .compatible = "xlnx,zynqmp-nvmem-fw", },
+ { /* sentinel */ },
+@@ -50,21 +40,18 @@ MODULE_DEVICE_TABLE(of, zynqmp_nvmem_mat
+ static int zynqmp_nvmem_probe(struct platform_device *pdev)
+ {
+ struct device *dev = &pdev->dev;
+- struct zynqmp_nvmem_data *priv;
++ struct nvmem_config econfig = {};
+
+- priv = devm_kzalloc(dev, sizeof(struct zynqmp_nvmem_data), GFP_KERNEL);
+- if (!priv)
+- return -ENOMEM;
+-
+- priv->dev = dev;
++ econfig.name = "zynqmp-nvmem";
++ econfig.owner = THIS_MODULE;
++ econfig.word_size = 1;
++ econfig.size = 1;
+ econfig.dev = dev;
+ econfig.add_legacy_fixed_of_cells = true;
++ econfig.read_only = true;
+ econfig.reg_read = zynqmp_nvmem_read;
+- econfig.priv = priv;
+-
+- priv->nvmem = devm_nvmem_register(dev, &econfig);
+
+- return PTR_ERR_OR_ZERO(priv->nvmem);
++ return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &econfig));
+ }
+
+ static struct platform_driver zynqmp_nvmem_driver = {
diff --git a/target/linux/generic/backport-6.1/823-v6.9-0004-nvmem-zynqmp_nvmem-Add-support-to-access-efuse.patch b/target/linux/generic/backport-6.1/823-v6.9-0004-nvmem-zynqmp_nvmem-Add-support-to-access-efuse.patch
new file mode 100644
index 0000000000..39c2f17835
--- /dev/null
+++ b/target/linux/generic/backport-6.1/823-v6.9-0004-nvmem-zynqmp_nvmem-Add-support-to-access-efuse.patch
@@ -0,0 +1,243 @@
+From 737c0c8d07b5f671c0a33cec95965fcb2d2ea893 Mon Sep 17 00:00:00 2001
+From: Praveen Teja Kundanala <praveen.teja.kundanala@amd.com>
+Date: Sat, 24 Feb 2024 11:45:12 +0000
+Subject: [PATCH] nvmem: zynqmp_nvmem: Add support to access efuse
+
+Add support to read/write efuse memory map of ZynqMP.
+Below are the offsets of ZynqMP efuse memory map
+ 0 - SOC version(read only)
+ 0xC - 0xFC -ZynqMP specific purpose efuses
+ 0x100 - 0x17F - Physical Unclonable Function(PUF)
+ efuses repurposed as user efuses
+
+Signed-off-by: Praveen Teja Kundanala <praveen.teja.kundanala@amd.com>
+Acked-by: Kalyani Akula <Kalyani.akula@amd.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240224114516.86365-8-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/zynqmp_nvmem.c | 186 +++++++++++++++++++++++++++++++++--
+ 1 file changed, 176 insertions(+), 10 deletions(-)
+
+--- a/drivers/nvmem/zynqmp_nvmem.c
++++ b/drivers/nvmem/zynqmp_nvmem.c
+@@ -4,6 +4,7 @@
+ * Copyright (C) 2022 - 2023, Advanced Micro Devices, Inc.
+ */
+
++#include <linux/dma-mapping.h>
+ #include <linux/module.h>
+ #include <linux/nvmem-provider.h>
+ #include <linux/of.h>
+@@ -11,24 +12,189 @@
+ #include <linux/firmware/xlnx-zynqmp.h>
+
+ #define SILICON_REVISION_MASK 0xF
++#define P_USER_0_64_UPPER_MASK GENMASK(31, 16)
++#define P_USER_127_LOWER_4_BIT_MASK GENMASK(3, 0)
++#define WORD_INBYTES 4
++#define SOC_VER_SIZE 0x4
++#define EFUSE_MEMORY_SIZE 0x177
++#define UNUSED_SPACE 0x8
++#define ZYNQMP_NVMEM_SIZE (SOC_VER_SIZE + UNUSED_SPACE + \
++ EFUSE_MEMORY_SIZE)
++#define SOC_VERSION_OFFSET 0x0
++#define EFUSE_START_OFFSET 0xC
++#define EFUSE_END_OFFSET 0xFC
++#define EFUSE_PUF_START_OFFSET 0x100
++#define EFUSE_PUF_MID_OFFSET 0x140
++#define EFUSE_PUF_END_OFFSET 0x17F
++#define EFUSE_NOT_ENABLED 29
+
++/*
++ * efuse access type
++ */
++enum efuse_access {
++ EFUSE_READ = 0,
++ EFUSE_WRITE
++};
++
++/**
++ * struct xilinx_efuse - the basic structure
++ * @src: address of the buffer to store the data to be write/read
++ * @size: read/write word count
++ * @offset: read/write offset
++ * @flag: 0 - represents efuse read and 1- represents efuse write
++ * @pufuserfuse:0 - represents non-puf efuses, offset is used for read/write
++ * 1 - represents puf user fuse row number.
++ *
++ * this structure stores all the required details to
++ * read/write efuse memory.
++ */
++struct xilinx_efuse {
++ u64 src;
++ u32 size;
++ u32 offset;
++ enum efuse_access flag;
++ u32 pufuserfuse;
++};
++
++static int zynqmp_efuse_access(void *context, unsigned int offset,
++ void *val, size_t bytes, enum efuse_access flag,
++ unsigned int pufflag)
++{
++ struct device *dev = context;
++ struct xilinx_efuse *efuse;
++ dma_addr_t dma_addr;
++ dma_addr_t dma_buf;
++ size_t words = bytes / WORD_INBYTES;
++ int ret;
++ int value;
++ char *data;
+
+-static int zynqmp_nvmem_read(void *context, unsigned int offset,
+- void *val, size_t bytes)
++ if (bytes % WORD_INBYTES != 0) {
++ dev_err(dev, "Bytes requested should be word aligned\n");
++ return -EOPNOTSUPP;
++ }
++
++ if (pufflag == 0 && offset % WORD_INBYTES) {
++ dev_err(dev, "Offset requested should be word aligned\n");
++ return -EOPNOTSUPP;
++ }
++
++ if (pufflag == 1 && flag == EFUSE_WRITE) {
++ memcpy(&value, val, bytes);
++ if ((offset == EFUSE_PUF_START_OFFSET ||
++ offset == EFUSE_PUF_MID_OFFSET) &&
++ value & P_USER_0_64_UPPER_MASK) {
++ dev_err(dev, "Only lower 4 bytes are allowed to be programmed in P_USER_0 & P_USER_64\n");
++ return -EOPNOTSUPP;
++ }
++
++ if (offset == EFUSE_PUF_END_OFFSET &&
++ (value & P_USER_127_LOWER_4_BIT_MASK)) {
++ dev_err(dev, "Only MSB 28 bits are allowed to be programmed for P_USER_127\n");
++ return -EOPNOTSUPP;
++ }
++ }
++
++ efuse = dma_alloc_coherent(dev, sizeof(struct xilinx_efuse),
++ &dma_addr, GFP_KERNEL);
++ if (!efuse)
++ return -ENOMEM;
++
++ data = dma_alloc_coherent(dev, sizeof(bytes),
++ &dma_buf, GFP_KERNEL);
++ if (!data) {
++ ret = -ENOMEM;
++ goto efuse_data_fail;
++ }
++
++ if (flag == EFUSE_WRITE) {
++ memcpy(data, val, bytes);
++ efuse->flag = EFUSE_WRITE;
++ } else {
++ efuse->flag = EFUSE_READ;
++ }
++
++ efuse->src = dma_buf;
++ efuse->size = words;
++ efuse->offset = offset;
++ efuse->pufuserfuse = pufflag;
++
++ zynqmp_pm_efuse_access(dma_addr, (u32 *)&ret);
++ if (ret != 0) {
++ if (ret == EFUSE_NOT_ENABLED) {
++ dev_err(dev, "efuse access is not enabled\n");
++ ret = -EOPNOTSUPP;
++ } else {
++ dev_err(dev, "Error in efuse read %x\n", ret);
++ ret = -EPERM;
++ }
++ goto efuse_access_err;
++ }
++
++ if (flag == EFUSE_READ)
++ memcpy(val, data, bytes);
++efuse_access_err:
++ dma_free_coherent(dev, sizeof(bytes),
++ data, dma_buf);
++efuse_data_fail:
++ dma_free_coherent(dev, sizeof(struct xilinx_efuse),
++ efuse, dma_addr);
++
++ return ret;
++}
++
++static int zynqmp_nvmem_read(void *context, unsigned int offset, void *val, size_t bytes)
+ {
+ struct device *dev = context;
+ int ret;
++ int pufflag = 0;
+ int idcode;
+ int version;
+
+- ret = zynqmp_pm_get_chipid(&idcode, &version);
+- if (ret < 0)
+- return ret;
++ if (offset >= EFUSE_PUF_START_OFFSET && offset <= EFUSE_PUF_END_OFFSET)
++ pufflag = 1;
++
++ switch (offset) {
++ /* Soc version offset is zero */
++ case SOC_VERSION_OFFSET:
++ if (bytes != SOC_VER_SIZE)
++ return -EOPNOTSUPP;
++
++ ret = zynqmp_pm_get_chipid((u32 *)&idcode, (u32 *)&version);
++ if (ret < 0)
++ return ret;
++
++ dev_dbg(dev, "Read chipid val %x %x\n", idcode, version);
++ *(int *)val = version & SILICON_REVISION_MASK;
++ break;
++ /* Efuse offset starts from 0xc */
++ case EFUSE_START_OFFSET ... EFUSE_END_OFFSET:
++ case EFUSE_PUF_START_OFFSET ... EFUSE_PUF_END_OFFSET:
++ ret = zynqmp_efuse_access(context, offset, val,
++ bytes, EFUSE_READ, pufflag);
++ break;
++ default:
++ *(u32 *)val = 0xDEADBEEF;
++ ret = 0;
++ break;
++ }
++
++ return ret;
++}
++
++static int zynqmp_nvmem_write(void *context,
++ unsigned int offset, void *val, size_t bytes)
++{
++ int pufflag = 0;
++
++ if (offset < EFUSE_START_OFFSET || offset > EFUSE_PUF_END_OFFSET)
++ return -EOPNOTSUPP;
+
+- dev_dbg(dev, "Read chipid val %x %x\n", idcode, version);
+- *(int *)val = version & SILICON_REVISION_MASK;
++ if (offset >= EFUSE_PUF_START_OFFSET && offset <= EFUSE_PUF_END_OFFSET)
++ pufflag = 1;
+
+- return 0;
++ return zynqmp_efuse_access(context, offset,
++ val, bytes, EFUSE_WRITE, pufflag);
+ }
+
+ static const struct of_device_id zynqmp_nvmem_match[] = {
+@@ -45,11 +211,11 @@ static int zynqmp_nvmem_probe(struct pla
+ econfig.name = "zynqmp-nvmem";
+ econfig.owner = THIS_MODULE;
+ econfig.word_size = 1;
+- econfig.size = 1;
++ econfig.size = ZYNQMP_NVMEM_SIZE;
+ econfig.dev = dev;
+ econfig.add_legacy_fixed_of_cells = true;
+- econfig.read_only = true;
+ econfig.reg_read = zynqmp_nvmem_read;
++ econfig.reg_write = zynqmp_nvmem_write;
+
+ return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &econfig));
+ }
diff --git a/target/linux/generic/backport-6.1/823-v6.9-0005-nvmem-mtk-efuse-Drop-NVMEM-device-name.patch b/target/linux/generic/backport-6.1/823-v6.9-0005-nvmem-mtk-efuse-Drop-NVMEM-device-name.patch
new file mode 100644
index 0000000000..c67399cb13
--- /dev/null
+++ b/target/linux/generic/backport-6.1/823-v6.9-0005-nvmem-mtk-efuse-Drop-NVMEM-device-name.patch
@@ -0,0 +1,35 @@
+From 76c345edef754b16cab81ad9452cc49c09e67066 Mon Sep 17 00:00:00 2001
+From: Chen-Yu Tsai <wenst@chromium.org>
+Date: Sat, 24 Feb 2024 11:45:14 +0000
+Subject: [PATCH] nvmem: mtk-efuse: Drop NVMEM device name
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The MT8183 has not one but two efuse devices. The static name and ID
+causes the second efuse device to fail to probe, due to duplicate sysfs
+entries.
+
+With the rework of the mtk-socinfo driver, lookup by name is no longer
+necessary. The custom name can simply be dropped.
+
+Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Tested-by: "Nícolas F. R. A. Prado" <nfraprado@collabora.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240224114516.86365-10-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/mtk-efuse.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/drivers/nvmem/mtk-efuse.c
++++ b/drivers/nvmem/mtk-efuse.c
+@@ -86,7 +86,6 @@ static int mtk_efuse_probe(struct platfo
+ econfig.size = resource_size(res);
+ econfig.priv = priv;
+ econfig.dev = dev;
+- econfig.name = "mtk-efuse";
+ if (pdata->uses_post_processing)
+ econfig.fixup_dt_cell_info = &mtk_efuse_fixup_dt_cell_info;
+ nvmem = devm_nvmem_register(dev, &econfig);
diff --git a/target/linux/generic/backport-6.1/823-v6.9-0007-nvmem-core-Print-error-on-wrong-bits-DT-property.patch b/target/linux/generic/backport-6.1/823-v6.9-0007-nvmem-core-Print-error-on-wrong-bits-DT-property.patch
new file mode 100644
index 0000000000..17bab24802
--- /dev/null
+++ b/target/linux/generic/backport-6.1/823-v6.9-0007-nvmem-core-Print-error-on-wrong-bits-DT-property.patch
@@ -0,0 +1,32 @@
+From def3173d4f17b37cecbd74d7c269a080b0b01598 Mon Sep 17 00:00:00 2001
+From: Markus Schneider-Pargmann <msp@baylibre.com>
+Date: Sat, 24 Feb 2024 11:45:16 +0000
+Subject: [PATCH] nvmem: core: Print error on wrong bits DT property
+
+The algorithms in nvmem core are built with the constraint that
+bit_offset < 8. If bit_offset is greater the results are wrong. Print an
+error if the devicetree 'bits' property is outside of the valid range
+and abort parsing.
+
+Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240224114516.86365-12-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/core.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/nvmem/core.c
++++ b/drivers/nvmem/core.c
+@@ -806,6 +806,11 @@ static int nvmem_add_cells_from_dt(struc
+ if (addr && len == (2 * sizeof(u32))) {
+ info.bit_offset = be32_to_cpup(addr++);
+ info.nbits = be32_to_cpup(addr);
++ if (info.bit_offset >= BITS_PER_BYTE || info.nbits < 1) {
++ dev_err(dev, "nvmem: invalid bits on %pOF\n", child);
++ of_node_put(child);
++ return -EINVAL;
++ }
+ }
+
+ info.np = of_node_get(child);
diff --git a/target/linux/generic/backport-6.1/827-v6.3-0001-of-base-add-of_parse_phandle_with_optional_args.patch b/target/linux/generic/backport-6.1/827-v6.3-0001-of-base-add-of_parse_phandle_with_optional_args.patch
index f568c3f6ce..b4cb96d248 100644
--- a/target/linux/generic/backport-6.1/827-v6.3-0001-of-base-add-of_parse_phandle_with_optional_args.patch
+++ b/target/linux/generic/backport-6.1/827-v6.3-0001-of-base-add-of_parse_phandle_with_optional_args.patch
@@ -24,7 +24,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
--- a/include/linux/of.h
+++ b/include/linux/of.h
-@@ -1009,6 +1009,31 @@ static inline int of_parse_phandle_with_
+@@ -1011,6 +1011,31 @@ static inline int of_parse_phandle_with_
}
/**
diff --git a/target/linux/generic/backport-6.1/828-v6.4-0003-of-Rename-of_modalias_node.patch b/target/linux/generic/backport-6.1/828-v6.4-0003-of-Rename-of_modalias_node.patch
index c11ccc6c3e..69d316b8fa 100644
--- a/target/linux/generic/backport-6.1/828-v6.4-0003-of-Rename-of_modalias_node.patch
+++ b/target/linux/generic/backport-6.1/828-v6.4-0003-of-Rename-of_modalias_node.patch
@@ -161,7 +161,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
goto err_out;
--- a/include/linux/of.h
+++ b/include/linux/of.h
-@@ -362,7 +362,8 @@ extern int of_n_addr_cells(struct device
+@@ -364,7 +364,8 @@ extern int of_n_addr_cells(struct device
extern int of_n_size_cells(struct device_node *np);
extern const struct of_device_id *of_match_node(
const struct of_device_id *matches, const struct device_node *node);
diff --git a/target/linux/generic/backport-6.1/828-v6.4-0004-of-Move-of_modalias-to-module.c.patch b/target/linux/generic/backport-6.1/828-v6.4-0004-of-Move-of_modalias-to-module.c.patch
index 39a84161a2..16baed1187 100644
--- a/target/linux/generic/backport-6.1/828-v6.4-0004-of-Move-of_modalias-to-module.c.patch
+++ b/target/linux/generic/backport-6.1/828-v6.4-0004-of-Move-of_modalias-to-module.c.patch
@@ -135,7 +135,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+}
--- a/include/linux/of.h
+++ b/include/linux/of.h
-@@ -374,6 +374,9 @@ extern int of_parse_phandle_with_args_ma
+@@ -376,6 +376,9 @@ extern int of_parse_phandle_with_args_ma
extern int of_count_phandle_with_args(const struct device_node *np,
const char *list_name, const char *cells_name);
@@ -145,7 +145,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
/* phandle iterator functions */
extern int of_phandle_iterator_init(struct of_phandle_iterator *it,
const struct device_node *np,
-@@ -731,6 +734,12 @@ static inline int of_count_phandle_with_
+@@ -733,6 +736,12 @@ static inline int of_count_phandle_with_
return -ENOSYS;
}
diff --git a/target/linux/generic/backport-6.1/828-v6.4-0005-of-Move-the-request-module-helper-logic-to-module.c.patch b/target/linux/generic/backport-6.1/828-v6.4-0005-of-Move-the-request-module-helper-logic-to-module.c.patch
index 046c1df561..67dcea0d19 100644
--- a/target/linux/generic/backport-6.1/828-v6.4-0005-of-Move-the-request-module-helper-logic-to-module.c.patch
+++ b/target/linux/generic/backport-6.1/828-v6.4-0005-of-Move-the-request-module-helper-logic-to-module.c.patch
@@ -109,7 +109,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+EXPORT_SYMBOL_GPL(of_request_module);
--- a/include/linux/of.h
+++ b/include/linux/of.h
-@@ -376,6 +376,7 @@ extern int of_count_phandle_with_args(co
+@@ -378,6 +378,7 @@ extern int of_count_phandle_with_args(co
/* module functions */
extern ssize_t of_modalias(const struct device_node *np, char *str, ssize_t len);
@@ -117,7 +117,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
/* phandle iterator functions */
extern int of_phandle_iterator_init(struct of_phandle_iterator *it,
-@@ -739,6 +740,11 @@ static inline ssize_t of_modalias(const
+@@ -741,6 +742,11 @@ static inline ssize_t of_modalias(const
{
return -ENODEV;
}
diff --git a/target/linux/generic/backport-6.1/829-v6.10-0001-nvmem-layouts-store-owner-from-modules-with-nvmem_la.patch b/target/linux/generic/backport-6.1/829-v6.10-0001-nvmem-layouts-store-owner-from-modules-with-nvmem_la.patch
new file mode 100644
index 0000000000..c15b4b2265
--- /dev/null
+++ b/target/linux/generic/backport-6.1/829-v6.10-0001-nvmem-layouts-store-owner-from-modules-with-nvmem_la.patch
@@ -0,0 +1,61 @@
+From 6d0ca4a2a7e25f9ad07c1f335f20b4d9e048cdd5 Mon Sep 17 00:00:00 2001
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Date: Tue, 30 Apr 2024 09:49:11 +0100
+Subject: [PATCH] nvmem: layouts: store owner from modules with
+ nvmem_layout_driver_register()
+
+Modules registering driver with nvmem_layout_driver_register() might
+forget to set .owner field. The field is used by some of other kernel
+parts for reference counting (try_module_get()), so it is expected that
+drivers will set it.
+
+Solve the problem by moving this task away from the drivers to the core
+code, just like we did for platform_driver in
+commit 9447057eaff8 ("platform_device: use a macro instead of
+platform_driver_register").
+
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Michael Walle <mwalle@kernel.org>
+Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240430084921.33387-2-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/layouts.c | 6 ++++--
+ include/linux/nvmem-provider.h | 5 ++++-
+ 2 files changed, 8 insertions(+), 3 deletions(-)
+
+--- a/drivers/nvmem/layouts.c
++++ b/drivers/nvmem/layouts.c
+@@ -52,13 +52,15 @@ static struct bus_type nvmem_layout_bus_
+ .remove = nvmem_layout_bus_remove,
+ };
+
+-int nvmem_layout_driver_register(struct nvmem_layout_driver *drv)
++int __nvmem_layout_driver_register(struct nvmem_layout_driver *drv,
++ struct module *owner)
+ {
+ drv->driver.bus = &nvmem_layout_bus_type;
++ drv->driver.owner = owner;
+
+ return driver_register(&drv->driver);
+ }
+-EXPORT_SYMBOL_GPL(nvmem_layout_driver_register);
++EXPORT_SYMBOL_GPL(__nvmem_layout_driver_register);
+
+ void nvmem_layout_driver_unregister(struct nvmem_layout_driver *drv)
+ {
+--- a/include/linux/nvmem-provider.h
++++ b/include/linux/nvmem-provider.h
+@@ -199,7 +199,10 @@ int nvmem_add_one_cell(struct nvmem_devi
+ int nvmem_layout_register(struct nvmem_layout *layout);
+ void nvmem_layout_unregister(struct nvmem_layout *layout);
+
+-int nvmem_layout_driver_register(struct nvmem_layout_driver *drv);
++#define nvmem_layout_driver_register(drv) \
++ __nvmem_layout_driver_register(drv, THIS_MODULE)
++int __nvmem_layout_driver_register(struct nvmem_layout_driver *drv,
++ struct module *owner);
+ void nvmem_layout_driver_unregister(struct nvmem_layout_driver *drv);
+ #define module_nvmem_layout_driver(__nvmem_layout_driver) \
+ module_driver(__nvmem_layout_driver, nvmem_layout_driver_register, \
diff --git a/target/linux/generic/backport-6.1/829-v6.10-0002-nvmem-layouts-onie-tlv-drop-driver-owner-initializat.patch b/target/linux/generic/backport-6.1/829-v6.10-0002-nvmem-layouts-onie-tlv-drop-driver-owner-initializat.patch
new file mode 100644
index 0000000000..b483dd243b
--- /dev/null
+++ b/target/linux/generic/backport-6.1/829-v6.10-0002-nvmem-layouts-onie-tlv-drop-driver-owner-initializat.patch
@@ -0,0 +1,28 @@
+From 21833338eccb91194fec6ba7548d9c454824eca0 Mon Sep 17 00:00:00 2001
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Date: Tue, 30 Apr 2024 09:49:12 +0100
+Subject: [PATCH] nvmem: layouts: onie-tlv: drop driver owner initialization
+
+Core in nvmem_layout_driver_register() already sets the .owner, so
+driver does not need to.
+
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Michael Walle <mwalle@kernel.org>
+Acked-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240430084921.33387-3-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/layouts/onie-tlv.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/drivers/nvmem/layouts/onie-tlv.c
++++ b/drivers/nvmem/layouts/onie-tlv.c
+@@ -247,7 +247,6 @@ MODULE_DEVICE_TABLE(of, onie_tlv_of_matc
+
+ static struct nvmem_layout_driver onie_tlv_layout = {
+ .driver = {
+- .owner = THIS_MODULE,
+ .name = "onie-tlv-layout",
+ .of_match_table = onie_tlv_of_match_table,
+ },
diff --git a/target/linux/generic/backport-6.1/829-v6.10-0003-nvmem-layouts-sl28vpd-drop-driver-owner-initializati.patch b/target/linux/generic/backport-6.1/829-v6.10-0003-nvmem-layouts-sl28vpd-drop-driver-owner-initializati.patch
new file mode 100644
index 0000000000..472a65feca
--- /dev/null
+++ b/target/linux/generic/backport-6.1/829-v6.10-0003-nvmem-layouts-sl28vpd-drop-driver-owner-initializati.patch
@@ -0,0 +1,28 @@
+From 23fd602f21953c03c0714257d36685cd6b486f04 Mon Sep 17 00:00:00 2001
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Date: Tue, 30 Apr 2024 09:49:13 +0100
+Subject: [PATCH] nvmem: layouts: sl28vpd: drop driver owner initialization
+
+Core in nvmem_layout_driver_register() already sets the .owner, so
+driver does not need to.
+
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Michael Walle <mwalle@kernel.org>
+Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240430084921.33387-4-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/layouts/sl28vpd.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/drivers/nvmem/layouts/sl28vpd.c
++++ b/drivers/nvmem/layouts/sl28vpd.c
+@@ -156,7 +156,6 @@ MODULE_DEVICE_TABLE(of, sl28vpd_of_match
+
+ static struct nvmem_layout_driver sl28vpd_layout = {
+ .driver = {
+- .owner = THIS_MODULE,
+ .name = "kontron-sl28vpd-layout",
+ .of_match_table = sl28vpd_of_match_table,
+ },
diff --git a/target/linux/generic/backport-6.1/829-v6.10-0004-nvmem-sc27xx-fix-module-autoloading.patch b/target/linux/generic/backport-6.1/829-v6.10-0004-nvmem-sc27xx-fix-module-autoloading.patch
new file mode 100644
index 0000000000..2aa13a5c64
--- /dev/null
+++ b/target/linux/generic/backport-6.1/829-v6.10-0004-nvmem-sc27xx-fix-module-autoloading.patch
@@ -0,0 +1,26 @@
+From dc3d88ade857ba3dca34f008e0b0aed3ef79cb15 Mon Sep 17 00:00:00 2001
+From: Krzysztof Kozlowski <krzk@kernel.org>
+Date: Tue, 30 Apr 2024 09:49:14 +0100
+Subject: [PATCH] nvmem: sc27xx: fix module autoloading
+
+Add MODULE_DEVICE_TABLE(), so the module could be properly autoloaded
+based on the alias from of_device_id table.
+
+Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240430084921.33387-5-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/sc27xx-efuse.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/nvmem/sc27xx-efuse.c
++++ b/drivers/nvmem/sc27xx-efuse.c
+@@ -263,6 +263,7 @@ static const struct of_device_id sc27xx_
+ { .compatible = "sprd,sc2730-efuse", .data = &sc2730_edata},
+ { }
+ };
++MODULE_DEVICE_TABLE(of, sc27xx_efuse_of_match);
+
+ static struct platform_driver sc27xx_efuse_driver = {
+ .probe = sc27xx_efuse_probe,
diff --git a/target/linux/generic/backport-6.1/829-v6.10-0005-nvmem-sprd-fix-module-autoloading.patch b/target/linux/generic/backport-6.1/829-v6.10-0005-nvmem-sprd-fix-module-autoloading.patch
new file mode 100644
index 0000000000..0953c92340
--- /dev/null
+++ b/target/linux/generic/backport-6.1/829-v6.10-0005-nvmem-sprd-fix-module-autoloading.patch
@@ -0,0 +1,26 @@
+From 154c1ec943e34f3188c9305b0c91d5e7dc1373b8 Mon Sep 17 00:00:00 2001
+From: Krzysztof Kozlowski <krzk@kernel.org>
+Date: Tue, 30 Apr 2024 09:49:15 +0100
+Subject: [PATCH] nvmem: sprd: fix module autoloading
+
+Add MODULE_DEVICE_TABLE(), so the module could be properly autoloaded
+based on the alias from of_device_id table.
+
+Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240430084921.33387-6-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/sprd-efuse.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/nvmem/sprd-efuse.c
++++ b/drivers/nvmem/sprd-efuse.c
+@@ -426,6 +426,7 @@ static const struct of_device_id sprd_ef
+ { .compatible = "sprd,ums312-efuse", .data = &ums312_data },
+ { }
+ };
++MODULE_DEVICE_TABLE(of, sprd_efuse_of_match);
+
+ static struct platform_driver sprd_efuse_driver = {
+ .probe = sprd_efuse_probe,
diff --git a/target/linux/generic/backport-6.1/829-v6.10-0006-nvmem-core-switch-to-use-device_add_groups.patch b/target/linux/generic/backport-6.1/829-v6.10-0006-nvmem-core-switch-to-use-device_add_groups.patch
new file mode 100644
index 0000000000..4de97af6ac
--- /dev/null
+++ b/target/linux/generic/backport-6.1/829-v6.10-0006-nvmem-core-switch-to-use-device_add_groups.patch
@@ -0,0 +1,32 @@
+From 8d8fc146dd7a0d6a6b37695747a524310dfb9d57 Mon Sep 17 00:00:00 2001
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Date: Tue, 30 Apr 2024 09:49:16 +0100
+Subject: [PATCH] nvmem: core: switch to use device_add_groups()
+
+devm_device_add_groups() is being removed from the kernel, so move the
+nvmem driver to use device_add_groups() instead. The logic is
+identical, when the device is removed the driver core will properly
+clean up and remove the groups, and the memory used by the attribute
+groups will be freed because it was created with dev_* calls, so this is
+functionally identical overall.
+
+Cc: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Link: https://lore.kernel.org/r/20240430084921.33387-7-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/nvmem/core.c
++++ b/drivers/nvmem/core.c
+@@ -477,7 +477,7 @@ static int nvmem_populate_sysfs_cells(st
+
+ nvmem_cells_group.bin_attrs = cells_attrs;
+
+- ret = devm_device_add_groups(&nvmem->dev, nvmem_cells_groups);
++ ret = device_add_groups(&nvmem->dev, nvmem_cells_groups);
+ if (ret)
+ goto unlock_mutex;
+
diff --git a/target/linux/generic/backport-6.1/829-v6.10-0007-nvmem-lpc18xx_eeprom-Convert-to-platform-remove-call.patch b/target/linux/generic/backport-6.1/829-v6.10-0007-nvmem-lpc18xx_eeprom-Convert-to-platform-remove-call.patch
new file mode 100644
index 0000000000..27d9270d31
--- /dev/null
+++ b/target/linux/generic/backport-6.1/829-v6.10-0007-nvmem-lpc18xx_eeprom-Convert-to-platform-remove-call.patch
@@ -0,0 +1,57 @@
+From 693d2f629962628ddefc88f4b6b453edda5ac32e Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= <u.kleine-koenig@pengutronix.de>
+Date: Tue, 30 Apr 2024 09:49:17 +0100
+Subject: [PATCH] nvmem: lpc18xx_eeprom: Convert to platform remove callback
+ returning void
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The .remove() callback for a platform driver returns an int which makes
+many driver authors wrongly assume it's possible to do error handling by
+returning an error code. However the value returned is ignored (apart
+from emitting a warning) and this typically results in resource leaks.
+
+To improve here there is a quest to make the remove callback return
+void. In the first step of this quest all drivers are converted to
+.remove_new(), which already returns void. Eventually after all drivers
+are converted, .remove_new() will be renamed to .remove().
+
+Trivially convert this driver from always returning zero in the remove
+callback to the void returning variant.
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Acked-by: Vladimir Zapolskiy <vz@mleia.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240430084921.33387-8-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/lpc18xx_eeprom.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+--- a/drivers/nvmem/lpc18xx_eeprom.c
++++ b/drivers/nvmem/lpc18xx_eeprom.c
+@@ -249,13 +249,11 @@ err_clk:
+ return ret;
+ }
+
+-static int lpc18xx_eeprom_remove(struct platform_device *pdev)
++static void lpc18xx_eeprom_remove(struct platform_device *pdev)
+ {
+ struct lpc18xx_eeprom_dev *eeprom = platform_get_drvdata(pdev);
+
+ clk_disable_unprepare(eeprom->clk);
+-
+- return 0;
+ }
+
+ static const struct of_device_id lpc18xx_eeprom_of_match[] = {
+@@ -266,7 +264,7 @@ MODULE_DEVICE_TABLE(of, lpc18xx_eeprom_o
+
+ static struct platform_driver lpc18xx_eeprom_driver = {
+ .probe = lpc18xx_eeprom_probe,
+- .remove = lpc18xx_eeprom_remove,
++ .remove_new = lpc18xx_eeprom_remove,
+ .driver = {
+ .name = "lpc18xx-eeprom",
+ .of_match_table = lpc18xx_eeprom_of_match,
diff --git a/target/linux/generic/backport-6.1/829-v6.10-0008-nvmem-meson-mx-efuse-Remove-nvmem_device-from-efuse-.patch b/target/linux/generic/backport-6.1/829-v6.10-0008-nvmem-meson-mx-efuse-Remove-nvmem_device-from-efuse-.patch
new file mode 100644
index 0000000000..7770052d97
--- /dev/null
+++ b/target/linux/generic/backport-6.1/829-v6.10-0008-nvmem-meson-mx-efuse-Remove-nvmem_device-from-efuse-.patch
@@ -0,0 +1,50 @@
+From 2a1ad6b75292d38aa2f6ded7335979e0632521da Mon Sep 17 00:00:00 2001
+From: Mukesh Ojha <quic_mojha@quicinc.com>
+Date: Tue, 30 Apr 2024 09:49:21 +0100
+Subject: [PATCH] nvmem: meson-mx-efuse: Remove nvmem_device from efuse struct
+
+nvmem_device is used at one place while registering nvmem
+device and it is not required to be present in efuse struct
+for just this purpose.
+
+Drop nvmem_device and manage with nvmem device stack variable.
+
+Signed-off-by: Mukesh Ojha <quic_mojha@quicinc.com>
+Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240430084921.33387-12-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/meson-mx-efuse.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/nvmem/meson-mx-efuse.c
++++ b/drivers/nvmem/meson-mx-efuse.c
+@@ -44,7 +44,6 @@ struct meson_mx_efuse_platform_data {
+ struct meson_mx_efuse {
+ void __iomem *base;
+ struct clk *core_clk;
+- struct nvmem_device *nvmem;
+ struct nvmem_config config;
+ };
+
+@@ -194,6 +193,7 @@ static int meson_mx_efuse_probe(struct p
+ {
+ const struct meson_mx_efuse_platform_data *drvdata;
+ struct meson_mx_efuse *efuse;
++ struct nvmem_device *nvmem;
+
+ drvdata = of_device_get_match_data(&pdev->dev);
+ if (!drvdata)
+@@ -224,9 +224,9 @@ static int meson_mx_efuse_probe(struct p
+ return PTR_ERR(efuse->core_clk);
+ }
+
+- efuse->nvmem = devm_nvmem_register(&pdev->dev, &efuse->config);
++ nvmem = devm_nvmem_register(&pdev->dev, &efuse->config);
+
+- return PTR_ERR_OR_ZERO(efuse->nvmem);
++ return PTR_ERR_OR_ZERO(nvmem);
+ }
+
+ static struct platform_driver meson_mx_efuse_driver = {
diff --git a/target/linux/generic/backport-6.1/830-04-v6.5-cpufreq-qcom-nvmem-use-SoC-ID-s-from-bindings.patch b/target/linux/generic/backport-6.1/830-04-v6.5-cpufreq-qcom-nvmem-use-SoC-ID-s-from-bindings.patch
index e0f10f7642..25a718bd7e 100644
--- a/target/linux/generic/backport-6.1/830-04-v6.5-cpufreq-qcom-nvmem-use-SoC-ID-s-from-bindings.patch
+++ b/target/linux/generic/backport-6.1/830-04-v6.5-cpufreq-qcom-nvmem-use-SoC-ID-s-from-bindings.patch
@@ -32,7 +32,7 @@ Link: https://lore.kernel.org/r/20230526204802.3081168-4-robimarko@gmail.com
enum _msm8996_version {
MSM8996_V3,
-@@ -153,12 +148,12 @@ static enum _msm8996_version qcom_cpufre
+@@ -157,12 +152,12 @@ static enum _msm8996_version qcom_cpufre
msm_id++;
switch ((enum _msm_id)*msm_id) {
diff --git a/target/linux/generic/backport-6.1/830-05-v6.5-cpufreq-qcom-nvmem-use-helper-to-get-SMEM-SoC-ID.patch b/target/linux/generic/backport-6.1/830-05-v6.5-cpufreq-qcom-nvmem-use-helper-to-get-SMEM-SoC-ID.patch
index 93e776f62c..49d222662c 100644
--- a/target/linux/generic/backport-6.1/830-05-v6.5-cpufreq-qcom-nvmem-use-helper-to-get-SMEM-SoC-ID.patch
+++ b/target/linux/generic/backport-6.1/830-05-v6.5-cpufreq-qcom-nvmem-use-helper-to-get-SMEM-SoC-ID.patch
@@ -36,7 +36,7 @@ Link: https://lore.kernel.org/r/20230526204802.3081168-5-robimarko@gmail.com
struct qcom_cpufreq_drv;
struct qcom_cpufreq_match_data {
-@@ -134,60 +126,32 @@ static void get_krait_bin_format_b(struc
+@@ -138,60 +130,32 @@ static void get_krait_bin_format_b(struc
dev_dbg(cpu_dev, "PVS version: %d\n", *pvs_ver);
}
diff --git a/target/linux/generic/backport-6.1/834-v6.8-leds-trigger-netdev-Extend-speeds-up-to-10G.patch b/target/linux/generic/backport-6.1/834-v6.8-leds-trigger-netdev-Extend-speeds-up-to-10G.patch
index 1c8e014a1a..9d5a928f5f 100644
--- a/target/linux/generic/backport-6.1/834-v6.8-leds-trigger-netdev-Extend-speeds-up-to-10G.patch
+++ b/target/linux/generic/backport-6.1/834-v6.8-leds-trigger-netdev-Extend-speeds-up-to-10G.patch
@@ -99,7 +99,7 @@ Signed-off-by: Lee Jones <lee@kernel.org>
interval = jiffies_to_msecs(
--- a/include/linux/leds.h
+++ b/include/linux/leds.h
-@@ -533,6 +533,9 @@ enum led_trigger_netdev_modes {
+@@ -531,6 +531,9 @@ enum led_trigger_netdev_modes {
TRIGGER_NETDEV_LINK_10,
TRIGGER_NETDEV_LINK_100,
TRIGGER_NETDEV_LINK_1000,
diff --git a/target/linux/generic/backport-6.1/840-v6.11-0001-nvmem-add-missing-MODULE_DESCRIPTION-macros.patch b/target/linux/generic/backport-6.1/840-v6.11-0001-nvmem-add-missing-MODULE_DESCRIPTION-macros.patch
new file mode 100644
index 0000000000..a8ce832408
--- /dev/null
+++ b/target/linux/generic/backport-6.1/840-v6.11-0001-nvmem-add-missing-MODULE_DESCRIPTION-macros.patch
@@ -0,0 +1,48 @@
+From c553bad4c5fc5ae44bd2fcaa73e1d6bedfb1c35c Mon Sep 17 00:00:00 2001
+From: Jeff Johnson <quic_jjohnson@quicinc.com>
+Date: Fri, 5 Jul 2024 08:48:38 +0100
+Subject: [PATCH] nvmem: add missing MODULE_DESCRIPTION() macros
+
+make allmodconfig && make W=1 C=1 reports:
+WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/nvmem/nvmem-apple-efuses.o
+WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/nvmem/nvmem_brcm_nvram.o
+WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/nvmem/nvmem_u-boot-env.o
+
+Add the missing invocations of the MODULE_DESCRIPTION() macro.
+
+Signed-off-by: Jeff Johnson <quic_jjohnson@quicinc.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240705074852.423202-2-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/apple-efuses.c | 1 +
+ drivers/nvmem/brcm_nvram.c | 1 +
+ drivers/nvmem/u-boot-env.c | 1 +
+ 3 files changed, 3 insertions(+)
+
+--- a/drivers/nvmem/apple-efuses.c
++++ b/drivers/nvmem/apple-efuses.c
+@@ -78,4 +78,5 @@ static struct platform_driver apple_efus
+ module_platform_driver(apple_efuses_driver);
+
+ MODULE_AUTHOR("Sven Peter <sven@svenpeter.dev>");
++MODULE_DESCRIPTION("Apple SoC eFuse driver");
+ MODULE_LICENSE("GPL");
+--- a/drivers/nvmem/brcm_nvram.c
++++ b/drivers/nvmem/brcm_nvram.c
+@@ -253,5 +253,6 @@ static int __init brcm_nvram_init(void)
+ subsys_initcall_sync(brcm_nvram_init);
+
+ MODULE_AUTHOR("Rafał Miłecki");
++MODULE_DESCRIPTION("Broadcom I/O-mapped NVRAM support driver");
+ MODULE_LICENSE("GPL");
+ MODULE_DEVICE_TABLE(of, brcm_nvram_of_match_table);
+--- a/drivers/nvmem/u-boot-env.c
++++ b/drivers/nvmem/u-boot-env.c
+@@ -249,5 +249,6 @@ static struct platform_driver u_boot_env
+ module_platform_driver(u_boot_env_driver);
+
+ MODULE_AUTHOR("Rafał Miłecki");
++MODULE_DESCRIPTION("U-Boot environment variables support module");
+ MODULE_LICENSE("GPL");
+ MODULE_DEVICE_TABLE(of, u_boot_env_of_match_table);
diff --git a/target/linux/generic/backport-6.1/840-v6.11-0002-nvmem-meson-efuse-Replacing-the-use-of-of_node_put-t.patch b/target/linux/generic/backport-6.1/840-v6.11-0002-nvmem-meson-efuse-Replacing-the-use-of-of_node_put-t.patch
new file mode 100644
index 0000000000..05c82dbf6f
--- /dev/null
+++ b/target/linux/generic/backport-6.1/840-v6.11-0002-nvmem-meson-efuse-Replacing-the-use-of-of_node_put-t.patch
@@ -0,0 +1,48 @@
+From 5fecb932607d83d37a703c731268e9d9051457f5 Mon Sep 17 00:00:00 2001
+From: MarileneGarcia <marilene.agarcia@gmail.com>
+Date: Fri, 5 Jul 2024 08:48:40 +0100
+Subject: [PATCH] nvmem: meson-efuse: Replacing the use of of_node_put to
+ __free
+
+Use __free for device_node values, and thus drop calls to
+of_node_put.
+
+The goal is to reduce memory management issues by using this
+scope-based of_node_put() cleanup to simplify function exit
+handling. When using __free a resource is allocated within a
+block, it is automatically freed at the end of the block.
+
+Suggested-by: Julia Lawall <julia.lawall@inria.fr>
+Signed-off-by: MarileneGarcia <marilene.agarcia@gmail.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240705074852.423202-4-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/meson-efuse.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+--- a/drivers/nvmem/meson-efuse.c
++++ b/drivers/nvmem/meson-efuse.c
+@@ -48,20 +48,19 @@ static int meson_efuse_probe(struct plat
+ {
+ struct device *dev = &pdev->dev;
+ struct meson_sm_firmware *fw;
+- struct device_node *sm_np;
+ struct nvmem_device *nvmem;
+ struct nvmem_config *econfig;
+ struct clk *clk;
+ unsigned int size;
++ struct device_node *sm_np __free(device_node) =
++ of_parse_phandle(pdev->dev.of_node, "secure-monitor", 0);
+
+- sm_np = of_parse_phandle(pdev->dev.of_node, "secure-monitor", 0);
+ if (!sm_np) {
+ dev_err(&pdev->dev, "no secure-monitor node\n");
+ return -ENODEV;
+ }
+
+ fw = meson_sm_get(sm_np);
+- of_node_put(sm_np);
+ if (!fw)
+ return -EPROBE_DEFER;
+
diff --git a/target/linux/generic/backport-6.1/840-v6.11-0003-nvmem-rockchip-otp-set-add_legacy_fixed_of_cells-con.patch b/target/linux/generic/backport-6.1/840-v6.11-0003-nvmem-rockchip-otp-set-add_legacy_fixed_of_cells-con.patch
new file mode 100644
index 0000000000..a8a30fc810
--- /dev/null
+++ b/target/linux/generic/backport-6.1/840-v6.11-0003-nvmem-rockchip-otp-set-add_legacy_fixed_of_cells-con.patch
@@ -0,0 +1,28 @@
+From 2933e79db3c00a8cdc56f6bb050a857fec1875ad Mon Sep 17 00:00:00 2001
+From: Heiko Stuebner <heiko.stuebner@cherry.de>
+Date: Fri, 5 Jul 2024 08:48:41 +0100
+Subject: [PATCH] nvmem: rockchip-otp: set add_legacy_fixed_of_cells config
+ option
+
+The Rockchip OTP describes its layout via devicetree subnodes,
+so set the appropriate property.
+
+Fixes: 2cc3b37f5b6d ("nvmem: add explicit config option to read old syntax fixed OF cells")
+Signed-off-by: Heiko Stuebner <heiko.stuebner@cherry.de>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240705074852.423202-5-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/rockchip-otp.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/nvmem/rockchip-otp.c
++++ b/drivers/nvmem/rockchip-otp.c
+@@ -255,6 +255,7 @@ static int rockchip_otp_read(void *conte
+ static struct nvmem_config otp_config = {
+ .name = "rockchip-otp",
+ .owner = THIS_MODULE,
++ .add_legacy_fixed_of_cells = true,
+ .read_only = true,
+ .stride = 1,
+ .word_size = 1,
diff --git a/target/linux/generic/backport-6.1/840-v6.11-0004-nvmem-rockchip-otp-Set-type-to-OTP.patch b/target/linux/generic/backport-6.1/840-v6.11-0004-nvmem-rockchip-otp-Set-type-to-OTP.patch
new file mode 100644
index 0000000000..8491eb3c9c
--- /dev/null
+++ b/target/linux/generic/backport-6.1/840-v6.11-0004-nvmem-rockchip-otp-Set-type-to-OTP.patch
@@ -0,0 +1,25 @@
+From 39f95600d8c53355b212a117e91a6ba15e0cac47 Mon Sep 17 00:00:00 2001
+From: Heiko Stuebner <heiko.stuebner@cherry.de>
+Date: Fri, 5 Jul 2024 08:48:42 +0100
+Subject: [PATCH] nvmem: rockchip-otp: Set type to OTP
+
+The Rockchip OTP is obviously an OTP memory, so document this fact.
+
+Signed-off-by: Heiko Stuebner <heiko.stuebner@cherry.de>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240705074852.423202-6-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/rockchip-otp.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/nvmem/rockchip-otp.c
++++ b/drivers/nvmem/rockchip-otp.c
+@@ -256,6 +256,7 @@ static struct nvmem_config otp_config =
+ .name = "rockchip-otp",
+ .owner = THIS_MODULE,
+ .add_legacy_fixed_of_cells = true,
++ .type = NVMEM_TYPE_OTP,
+ .read_only = true,
+ .stride = 1,
+ .word_size = 1,
diff --git a/target/linux/generic/backport-6.1/840-v6.11-0005-nvmem-rockchip-efuse-set-type-to-OTP.patch b/target/linux/generic/backport-6.1/840-v6.11-0005-nvmem-rockchip-efuse-set-type-to-OTP.patch
new file mode 100644
index 0000000000..260b03eb03
--- /dev/null
+++ b/target/linux/generic/backport-6.1/840-v6.11-0005-nvmem-rockchip-efuse-set-type-to-OTP.patch
@@ -0,0 +1,26 @@
+From ba64a04474d2989f397982c48e405cfd785e2dd5 Mon Sep 17 00:00:00 2001
+From: Heiko Stuebner <heiko.stuebner@cherry.de>
+Date: Fri, 5 Jul 2024 08:48:43 +0100
+Subject: [PATCH] nvmem: rockchip-efuse: set type to OTP
+
+This device currently reports an "Unknown" type in sysfs.
+Since it is an eFuse hardware device, set its type to OTP.
+
+Signed-off-by: Heiko Stuebner <heiko.stuebner@cherry.de>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240705074852.423202-7-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/rockchip-efuse.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/nvmem/rockchip-efuse.c
++++ b/drivers/nvmem/rockchip-efuse.c
+@@ -206,6 +206,7 @@ static int rockchip_rk3399_efuse_read(vo
+ static struct nvmem_config econfig = {
+ .name = "rockchip-efuse",
+ .add_legacy_fixed_of_cells = true,
++ .type = NVMEM_TYPE_OTP,
+ .stride = 1,
+ .word_size = 1,
+ .read_only = true,
diff --git a/target/linux/generic/backport-6.1/840-v6.11-0006-nvmem-core-add-single-sysfs-group.patch b/target/linux/generic/backport-6.1/840-v6.11-0006-nvmem-core-add-single-sysfs-group.patch
new file mode 100644
index 0000000000..4fb2afd2fa
--- /dev/null
+++ b/target/linux/generic/backport-6.1/840-v6.11-0006-nvmem-core-add-single-sysfs-group.patch
@@ -0,0 +1,42 @@
+From 6188f233161c6a5b2d1c396a221dfafc77dc9eec Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= <linux@weissschuh.net>
+Date: Fri, 5 Jul 2024 08:48:46 +0100
+Subject: [PATCH] nvmem: core: add single sysfs group
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The sysfs core provides a function to easily register a single group.
+Use it and remove the now unnecessary nvmem_cells_groups array.
+
+Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240705074852.423202-10-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/core.c | 7 +------
+ 1 file changed, 1 insertion(+), 6 deletions(-)
+
+--- a/drivers/nvmem/core.c
++++ b/drivers/nvmem/core.c
+@@ -368,11 +368,6 @@ static const struct attribute_group *nvm
+ NULL,
+ };
+
+-static const struct attribute_group *nvmem_cells_groups[] = {
+- &nvmem_cells_group,
+- NULL,
+-};
+-
+ static struct bin_attribute bin_attr_nvmem_eeprom_compat = {
+ .attr = {
+ .name = "eeprom",
+@@ -477,7 +472,7 @@ static int nvmem_populate_sysfs_cells(st
+
+ nvmem_cells_group.bin_attrs = cells_attrs;
+
+- ret = device_add_groups(&nvmem->dev, nvmem_cells_groups);
++ ret = device_add_group(&nvmem->dev, &nvmem_cells_group);
+ if (ret)
+ goto unlock_mutex;
+
diff --git a/target/linux/generic/backport-6.1/840-v6.11-0007-nvmem-core-remove-global-nvmem_cells_group.patch b/target/linux/generic/backport-6.1/840-v6.11-0007-nvmem-core-remove-global-nvmem_cells_group.patch
new file mode 100644
index 0000000000..ef626d37a0
--- /dev/null
+++ b/target/linux/generic/backport-6.1/840-v6.11-0007-nvmem-core-remove-global-nvmem_cells_group.patch
@@ -0,0 +1,83 @@
+From 6839fed062b7898665983368c88269a6fb1fc10f Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= <linux@weissschuh.net>
+Date: Fri, 5 Jul 2024 08:48:47 +0100
+Subject: [PATCH] nvmem: core: remove global nvmem_cells_group
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+nvmem_cells_groups is a global variable that is also mutated.
+This is complicated and error-prone.
+
+Instead use a normal stack variable.
+
+Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240705074852.423202-11-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/core.c | 26 ++++++++++----------------
+ 1 file changed, 10 insertions(+), 16 deletions(-)
+
+--- a/drivers/nvmem/core.c
++++ b/drivers/nvmem/core.c
+@@ -358,11 +358,6 @@ static const struct attribute_group nvme
+ .is_bin_visible = nvmem_bin_attr_is_visible,
+ };
+
+-/* Cell attributes will be dynamically allocated */
+-static struct attribute_group nvmem_cells_group = {
+- .name = "cells",
+-};
+-
+ static const struct attribute_group *nvmem_dev_groups[] = {
+ &nvmem_bin_group,
+ NULL,
+@@ -424,23 +419,24 @@ static void nvmem_sysfs_remove_compat(st
+
+ static int nvmem_populate_sysfs_cells(struct nvmem_device *nvmem)
+ {
+- struct bin_attribute **cells_attrs, *attrs;
++ struct attribute_group group = {
++ .name = "cells",
++ };
+ struct nvmem_cell_entry *entry;
++ struct bin_attribute *attrs;
+ unsigned int ncells = 0, i = 0;
+ int ret = 0;
+
+ mutex_lock(&nvmem_mutex);
+
+- if (list_empty(&nvmem->cells) || nvmem->sysfs_cells_populated) {
+- nvmem_cells_group.bin_attrs = NULL;
++ if (list_empty(&nvmem->cells) || nvmem->sysfs_cells_populated)
+ goto unlock_mutex;
+- }
+
+ /* Allocate an array of attributes with a sentinel */
+ ncells = list_count_nodes(&nvmem->cells);
+- cells_attrs = devm_kcalloc(&nvmem->dev, ncells + 1,
+- sizeof(struct bin_attribute *), GFP_KERNEL);
+- if (!cells_attrs) {
++ group.bin_attrs = devm_kcalloc(&nvmem->dev, ncells + 1,
++ sizeof(struct bin_attribute *), GFP_KERNEL);
++ if (!group.bin_attrs) {
+ ret = -ENOMEM;
+ goto unlock_mutex;
+ }
+@@ -466,13 +462,11 @@ static int nvmem_populate_sysfs_cells(st
+ goto unlock_mutex;
+ }
+
+- cells_attrs[i] = &attrs[i];
++ group.bin_attrs[i] = &attrs[i];
+ i++;
+ }
+
+- nvmem_cells_group.bin_attrs = cells_attrs;
+-
+- ret = device_add_group(&nvmem->dev, &nvmem_cells_group);
++ ret = device_add_group(&nvmem->dev, &group);
+ if (ret)
+ goto unlock_mutex;
+
diff --git a/target/linux/generic/backport-6.1/840-v6.11-0008-nvmem-core-drop-unnecessary-range-checks-in-sysfs-ca.patch b/target/linux/generic/backport-6.1/840-v6.11-0008-nvmem-core-drop-unnecessary-range-checks-in-sysfs-ca.patch
new file mode 100644
index 0000000000..9b6251b919
--- /dev/null
+++ b/target/linux/generic/backport-6.1/840-v6.11-0008-nvmem-core-drop-unnecessary-range-checks-in-sysfs-ca.patch
@@ -0,0 +1,61 @@
+From 588773802c386d38f9c4e91acd47369e89d95a30 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= <linux@weissschuh.net>
+Date: Fri, 5 Jul 2024 08:48:48 +0100
+Subject: [PATCH] nvmem: core: drop unnecessary range checks in sysfs callbacks
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The same checks have already been done in sysfs_kf_bin_write() and
+sysfs_kf_bin_read() just before the callbacks are invoked.
+
+Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240705074852.423202-12-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/core.c | 14 --------------
+ 1 file changed, 14 deletions(-)
+
+--- a/drivers/nvmem/core.c
++++ b/drivers/nvmem/core.c
+@@ -204,19 +204,12 @@ static ssize_t bin_attr_nvmem_read(struc
+ dev = kobj_to_dev(kobj);
+ nvmem = to_nvmem_device(dev);
+
+- /* Stop the user from reading */
+- if (pos >= nvmem->size)
+- return 0;
+-
+ if (!IS_ALIGNED(pos, nvmem->stride))
+ return -EINVAL;
+
+ if (count < nvmem->word_size)
+ return -EINVAL;
+
+- if (pos + count > nvmem->size)
+- count = nvmem->size - pos;
+-
+ count = round_down(count, nvmem->word_size);
+
+ if (!nvmem->reg_read)
+@@ -244,19 +237,12 @@ static ssize_t bin_attr_nvmem_write(stru
+ dev = kobj_to_dev(kobj);
+ nvmem = to_nvmem_device(dev);
+
+- /* Stop the user from writing */
+- if (pos >= nvmem->size)
+- return -EFBIG;
+-
+ if (!IS_ALIGNED(pos, nvmem->stride))
+ return -EINVAL;
+
+ if (count < nvmem->word_size)
+ return -EINVAL;
+
+- if (pos + count > nvmem->size)
+- count = nvmem->size - pos;
+-
+ count = round_down(count, nvmem->word_size);
+
+ if (!nvmem->reg_write)
diff --git a/target/linux/generic/backport-6.1/840-v6.11-0009-nvmem-Use-sysfs_emit-for-type-attribute.patch b/target/linux/generic/backport-6.1/840-v6.11-0009-nvmem-Use-sysfs_emit-for-type-attribute.patch
new file mode 100644
index 0000000000..3da1febaf1
--- /dev/null
+++ b/target/linux/generic/backport-6.1/840-v6.11-0009-nvmem-Use-sysfs_emit-for-type-attribute.patch
@@ -0,0 +1,30 @@
+From 08c367e45b6d322956878774f0b88bf5e52c6d54 Mon Sep 17 00:00:00 2001
+From: Marek Vasut <marex@denx.de>
+Date: Fri, 5 Jul 2024 08:48:51 +0100
+Subject: [PATCH] nvmem: Use sysfs_emit() for type attribute
+
+Use sysfs_emit() instead of sprintf() to follow best practice per
+Documentation/filesystems/sysfs.rst
+"
+show() should only use sysfs_emit()...
+"
+
+Signed-off-by: Marek Vasut <marex@denx.de>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240705074852.423202-15-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/nvmem/core.c
++++ b/drivers/nvmem/core.c
+@@ -180,7 +180,7 @@ static ssize_t type_show(struct device *
+ {
+ struct nvmem_device *nvmem = to_nvmem_device(dev);
+
+- return sprintf(buf, "%s\n", nvmem_type_str[nvmem->type]);
++ return sysfs_emit(buf, "%s\n", nvmem_type_str[nvmem->type]);
+ }
+
+ static DEVICE_ATTR_RO(type);
diff --git a/target/linux/generic/backport-6.1/840-v6.11-0010-nvmem-core-Implement-force_ro-sysfs-attribute.patch b/target/linux/generic/backport-6.1/840-v6.11-0010-nvmem-core-Implement-force_ro-sysfs-attribute.patch
new file mode 100644
index 0000000000..ac7dda1bdf
--- /dev/null
+++ b/target/linux/generic/backport-6.1/840-v6.11-0010-nvmem-core-Implement-force_ro-sysfs-attribute.patch
@@ -0,0 +1,122 @@
+From 9d7eb234ac7a56b88aea8a52ed81553a730fe25c Mon Sep 17 00:00:00 2001
+From: Marek Vasut <marex@denx.de>
+Date: Fri, 5 Jul 2024 08:48:52 +0100
+Subject: [PATCH] nvmem: core: Implement force_ro sysfs attribute
+
+Implement "force_ro" sysfs attribute to allow users to set read-write
+devices as read-only and back to read-write from userspace. The choice
+of the name is based on MMC core 'force_ro' attribute.
+
+This solves a situation where an AT24 I2C EEPROM with GPIO based nWP
+signal may have to be occasionally updated. Such I2C EEPROM device is
+usually set as read-only during most of the regular system operation,
+but in case it has to be updated in a controlled manner, it could be
+unlocked using this new "force_ro" sysfs attribute and then re-locked
+again.
+
+The "read-only" DT property and config->read_only configuration is
+respected and is used to set default state of the device, read-only
+or read-write, for devices which do implement .reg_write function.
+For devices which do not implement .reg_write function, the device
+is unconditionally read-only and the "force_ro" attribute is not
+visible.
+
+Signed-off-by: Marek Vasut <marex@denx.de>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240705074852.423202-16-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ Documentation/ABI/stable/sysfs-bus-nvmem | 17 ++++++++++
+ drivers/nvmem/core.c | 43 ++++++++++++++++++++++++
+ 2 files changed, 60 insertions(+)
+
+--- a/Documentation/ABI/stable/sysfs-bus-nvmem
++++ b/Documentation/ABI/stable/sysfs-bus-nvmem
+@@ -1,3 +1,20 @@
++What: /sys/bus/nvmem/devices/.../force_ro
++Date: June 2024
++KernelVersion: 6.11
++Contact: Marek Vasut <marex@denx.de>
++Description:
++ This read/write attribute allows users to set read-write
++ devices as read-only and back to read-write from userspace.
++ This can be used to unlock and relock write-protection of
++ devices which are generally locked, except during sporadic
++ programming operation.
++ Read returns '0' or '1' for read-write or read-only modes
++ respectively.
++ Write parses one of 'YyTt1NnFf0', or [oO][NnFf] for "on"
++ and "off", i.e. what kstrbool() supports.
++ Note: This file is only present if CONFIG_NVMEM_SYSFS
++ is enabled.
++
+ What: /sys/bus/nvmem/devices/.../nvmem
+ Date: July 2015
+ KernelVersion: 4.2
+--- a/drivers/nvmem/core.c
++++ b/drivers/nvmem/core.c
+@@ -185,7 +185,30 @@ static ssize_t type_show(struct device *
+
+ static DEVICE_ATTR_RO(type);
+
++static ssize_t force_ro_show(struct device *dev, struct device_attribute *attr,
++ char *buf)
++{
++ struct nvmem_device *nvmem = to_nvmem_device(dev);
++
++ return sysfs_emit(buf, "%d\n", nvmem->read_only);
++}
++
++static ssize_t force_ro_store(struct device *dev, struct device_attribute *attr,
++ const char *buf, size_t count)
++{
++ struct nvmem_device *nvmem = to_nvmem_device(dev);
++ int ret = kstrtobool(buf, &nvmem->read_only);
++
++ if (ret < 0)
++ return ret;
++
++ return count;
++}
++
++static DEVICE_ATTR_RW(force_ro);
++
+ static struct attribute *nvmem_attrs[] = {
++ &dev_attr_force_ro.attr,
+ &dev_attr_type.attr,
+ NULL,
+ };
+@@ -286,6 +309,25 @@ static umode_t nvmem_bin_attr_is_visible
+ return nvmem_bin_attr_get_umode(nvmem);
+ }
+
++static umode_t nvmem_attr_is_visible(struct kobject *kobj,
++ struct attribute *attr, int i)
++{
++ struct device *dev = kobj_to_dev(kobj);
++ struct nvmem_device *nvmem = to_nvmem_device(dev);
++
++ /*
++ * If the device has no .reg_write operation, do not allow
++ * configuration as read-write.
++ * If the device is set as read-only by configuration, it
++ * can be forced into read-write mode using the 'force_ro'
++ * attribute.
++ */
++ if (attr == &dev_attr_force_ro.attr && !nvmem->reg_write)
++ return 0; /* Attribute not visible */
++
++ return attr->mode;
++}
++
+ static struct nvmem_cell *nvmem_create_cell(struct nvmem_cell_entry *entry,
+ const char *id, int index);
+
+@@ -342,6 +384,7 @@ static const struct attribute_group nvme
+ .bin_attrs = nvmem_bin_attributes,
+ .attrs = nvmem_attrs,
+ .is_bin_visible = nvmem_bin_attr_is_visible,
++ .is_visible = nvmem_attr_is_visible,
+ };
+
+ static const struct attribute_group *nvmem_dev_groups[] = {
diff --git a/target/linux/generic/backport-6.1/840-v6.11-0011-nvmem-u-boot-env-error-if-NVMEM-device-is-too-small.patch b/target/linux/generic/backport-6.1/840-v6.11-0011-nvmem-u-boot-env-error-if-NVMEM-device-is-too-small.patch
new file mode 100644
index 0000000000..70d420f205
--- /dev/null
+++ b/target/linux/generic/backport-6.1/840-v6.11-0011-nvmem-u-boot-env-error-if-NVMEM-device-is-too-small.patch
@@ -0,0 +1,40 @@
+From 8679e8b4a1ebdb40c4429e49368d29353e07b601 Mon Sep 17 00:00:00 2001
+From: John Thomson <git@johnthomson.fastmail.com.au>
+Date: Mon, 2 Sep 2024 15:25:08 +0100
+Subject: [PATCH] nvmem: u-boot-env: error if NVMEM device is too small
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Verify data size before trying to parse it to avoid reading out of
+buffer. This could happen in case of problems at MTD level or invalid DT
+bindings.
+
+Signed-off-by: John Thomson <git@johnthomson.fastmail.com.au>
+Cc: stable <stable@kernel.org>
+Fixes: d5542923f200 ("nvmem: add driver handling U-Boot environment variables")
+[rmilecki: simplify commit description & rebase]
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240902142510.71096-2-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/u-boot-env.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/drivers/nvmem/u-boot-env.c
++++ b/drivers/nvmem/u-boot-env.c
+@@ -176,6 +176,13 @@ static int u_boot_env_parse(struct u_boo
+ data_offset = offsetof(struct u_boot_env_image_broadcom, data);
+ break;
+ }
++
++ if (dev_size < data_offset) {
++ dev_err(dev, "Device too small for u-boot-env\n");
++ err = -EIO;
++ goto err_kfree;
++ }
++
+ crc32_addr = (__le32 *)(buf + crc32_offset);
+ crc32 = le32_to_cpu(*crc32_addr);
+ crc32_data_len = dev_size - crc32_data_offset;
diff --git a/target/linux/generic/backport-6.1/840-v6.11-0012-nvmem-Fix-return-type-of-devm_nvmem_device_get-in-ke.patch b/target/linux/generic/backport-6.1/840-v6.11-0012-nvmem-Fix-return-type-of-devm_nvmem_device_get-in-ke.patch
new file mode 100644
index 0000000000..08f6278849
--- /dev/null
+++ b/target/linux/generic/backport-6.1/840-v6.11-0012-nvmem-Fix-return-type-of-devm_nvmem_device_get-in-ke.patch
@@ -0,0 +1,37 @@
+From c69f37f6559a8948d70badd2b179db7714dedd62 Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+Date: Mon, 2 Sep 2024 15:25:09 +0100
+Subject: [PATCH] nvmem: Fix return type of devm_nvmem_device_get() in
+ kerneldoc
+
+devm_nvmem_device_get() returns an nvmem device, not an nvmem cell.
+
+Fixes: e2a5402ec7c6d044 ("nvmem: Add nvmem_device based consumer apis.")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240902142510.71096-3-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/core.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/nvmem/core.c
++++ b/drivers/nvmem/core.c
+@@ -1276,13 +1276,13 @@ void nvmem_device_put(struct nvmem_devic
+ EXPORT_SYMBOL_GPL(nvmem_device_put);
+
+ /**
+- * devm_nvmem_device_get() - Get nvmem cell of device form a given id
++ * devm_nvmem_device_get() - Get nvmem device of device form a given id
+ *
+ * @dev: Device that requests the nvmem device.
+ * @id: name id for the requested nvmem device.
+ *
+- * Return: ERR_PTR() on error or a valid pointer to a struct nvmem_cell
+- * on success. The nvmem_cell will be freed by the automatically once the
++ * Return: ERR_PTR() on error or a valid pointer to a struct nvmem_device
++ * on success. The nvmem_device will be freed by the automatically once the
+ * device is freed.
+ */
+ struct nvmem_device *devm_nvmem_device_get(struct device *dev, const char *id)
diff --git a/target/linux/generic/backport-6.1/841-v6.12-0001-nvmem-imx-ocotp-ele-support-i.MX95.patch b/target/linux/generic/backport-6.1/841-v6.12-0001-nvmem-imx-ocotp-ele-support-i.MX95.patch
new file mode 100644
index 0000000000..c19931b3fa
--- /dev/null
+++ b/target/linux/generic/backport-6.1/841-v6.12-0001-nvmem-imx-ocotp-ele-support-i.MX95.patch
@@ -0,0 +1,73 @@
+From c3f9b7b4e5f9de319d00784577cda42036ff243a Mon Sep 17 00:00:00 2001
+From: Peng Fan <peng.fan@nxp.com>
+Date: Mon, 2 Sep 2024 15:29:45 +0100
+Subject: [PATCH] nvmem: imx-ocotp-ele: support i.MX95
+
+i.MX95 OCOTP has same accessing method, so add an entry for i.MX95, but
+some fuse has ECC feature, so only read out the lower 16bits for ECC fuses.
+
+Signed-off-by: Peng Fan <peng.fan@nxp.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240902142952.71639-3-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/imx-ocotp-ele.c | 32 +++++++++++++++++++++++++++++---
+ 1 file changed, 29 insertions(+), 3 deletions(-)
+
+--- a/drivers/nvmem/imx-ocotp-ele.c
++++ b/drivers/nvmem/imx-ocotp-ele.c
+@@ -14,8 +14,9 @@
+ #include <linux/slab.h>
+
+ enum fuse_type {
+- FUSE_FSB = 1,
+- FUSE_ELE = 2,
++ FUSE_FSB = BIT(0),
++ FUSE_ELE = BIT(1),
++ FUSE_ECC = BIT(2),
+ FUSE_INVALID = -1
+ };
+
+@@ -93,7 +94,10 @@ static int imx_ocotp_reg_read(void *cont
+ continue;
+ }
+
+- *buf++ = readl_relaxed(reg + (i << 2));
++ if (type & FUSE_ECC)
++ *buf++ = readl_relaxed(reg + (i << 2)) & GENMASK(15, 0);
++ else
++ *buf++ = readl_relaxed(reg + (i << 2));
+ }
+
+ memcpy(val, (u8 *)p, bytes);
+@@ -155,8 +159,30 @@ static const struct ocotp_devtype_data i
+ },
+ };
+
++static const struct ocotp_devtype_data imx95_ocotp_data = {
++ .reg_off = 0x8000,
++ .reg_read = imx_ocotp_reg_read,
++ .size = 2048,
++ .num_entry = 12,
++ .entry = {
++ { 0, 1, FUSE_FSB | FUSE_ECC },
++ { 7, 1, FUSE_FSB | FUSE_ECC },
++ { 9, 3, FUSE_FSB | FUSE_ECC },
++ { 12, 24, FUSE_FSB },
++ { 36, 2, FUSE_FSB | FUSE_ECC },
++ { 38, 14, FUSE_FSB },
++ { 63, 1, FUSE_ELE },
++ { 128, 16, FUSE_ELE },
++ { 188, 1, FUSE_ELE },
++ { 317, 2, FUSE_FSB | FUSE_ECC },
++ { 320, 7, FUSE_FSB },
++ { 328, 184, FUSE_FSB }
++ },
++};
++
+ static const struct of_device_id imx_ele_ocotp_dt_ids[] = {
+ { .compatible = "fsl,imx93-ocotp", .data = &imx93_ocotp_data, },
++ { .compatible = "fsl,imx95-ocotp", .data = &imx95_ocotp_data, },
+ {},
+ };
+ MODULE_DEVICE_TABLE(of, imx_ele_ocotp_dt_ids);
diff --git a/target/linux/generic/backport-6.1/841-v6.12-0002-nvmem-sunplus-ocotp-Use-devm_platform_ioremap_resour.patch b/target/linux/generic/backport-6.1/841-v6.12-0002-nvmem-sunplus-ocotp-Use-devm_platform_ioremap_resour.patch
new file mode 100644
index 0000000000..13ef50b157
--- /dev/null
+++ b/target/linux/generic/backport-6.1/841-v6.12-0002-nvmem-sunplus-ocotp-Use-devm_platform_ioremap_resour.patch
@@ -0,0 +1,44 @@
+From 98ee46391baf35987227236d0c3bb30ab6e758c8 Mon Sep 17 00:00:00 2001
+From: Zhang Zekun <zhangzekun11@huawei.com>
+Date: Mon, 2 Sep 2024 15:29:50 +0100
+Subject: [PATCH] nvmem: sunplus-ocotp: Use
+ devm_platform_ioremap_resource_byname() helper function
+
+platform_get_resource_byname() and devm_ioremap_resource() can be
+replaced by devm_platform_ioremap_resource_byname(), which can
+simplify the code logic a bit, No functional change here.
+
+Signed-off-by: Zhang Zekun <zhangzekun11@huawei.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240902142952.71639-8-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/sunplus-ocotp.c | 7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+--- a/drivers/nvmem/sunplus-ocotp.c
++++ b/drivers/nvmem/sunplus-ocotp.c
+@@ -159,7 +159,6 @@ static int sp_ocotp_probe(struct platfor
+ struct device *dev = &pdev->dev;
+ struct nvmem_device *nvmem;
+ struct sp_ocotp_priv *otp;
+- struct resource *res;
+ int ret;
+
+ otp = devm_kzalloc(dev, sizeof(*otp), GFP_KERNEL);
+@@ -168,13 +167,11 @@ static int sp_ocotp_probe(struct platfor
+
+ otp->dev = dev;
+
+- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hb_gpio");
+- otp->base[HB_GPIO] = devm_ioremap_resource(dev, res);
++ otp->base[HB_GPIO] = devm_platform_ioremap_resource_byname(pdev, "hb_gpio");
+ if (IS_ERR(otp->base[HB_GPIO]))
+ return PTR_ERR(otp->base[HB_GPIO]);
+
+- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "otprx");
+- otp->base[OTPRX] = devm_ioremap_resource(dev, res);
++ otp->base[OTPRX] = devm_platform_ioremap_resource_byname(pdev, "otprx");
+ if (IS_ERR(otp->base[OTPRX]))
+ return PTR_ERR(otp->base[OTPRX]);
+
diff --git a/target/linux/generic/backport-6.1/841-v6.12-0003-nvmem-layouts-add-U-Boot-env-layout.patch b/target/linux/generic/backport-6.1/841-v6.12-0003-nvmem-layouts-add-U-Boot-env-layout.patch
new file mode 100644
index 0000000000..e711c84c8d
--- /dev/null
+++ b/target/linux/generic/backport-6.1/841-v6.12-0003-nvmem-layouts-add-U-Boot-env-layout.patch
@@ -0,0 +1,525 @@
+From 5f15811286aff4664bf275a7ede64e1b8858151b Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
+Date: Mon, 2 Sep 2024 15:29:47 +0100
+Subject: [PATCH] nvmem: layouts: add U-Boot env layout
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+U-Boot environment variables are stored in a specific format. Actual
+data can be placed in various storage sources (MTD, UBI volume, EEPROM,
+NVRAM, etc.).
+
+Move all generic (NVMEM device independent) code from NVMEM device
+driver to an NVMEM layout driver. Then add a simple NVMEM layout code on
+top of it.
+
+This allows using NVMEM layout for parsing U-Boot env data stored in any
+kind of NVMEM device.
+
+The old NVMEM glue driver stays in place for handling bindings in the
+MTD context. To avoid code duplication it uses exported layout parsing
+function. Please note that handling MTD & NVMEM layout bindings may be
+refactored in the future.
+
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240902142952.71639-5-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ MAINTAINERS | 1 +
+ drivers/nvmem/Kconfig | 3 +-
+ drivers/nvmem/layouts/Kconfig | 11 ++
+ drivers/nvmem/layouts/Makefile | 1 +
+ drivers/nvmem/layouts/u-boot-env.c | 211 +++++++++++++++++++++++++++++
+ drivers/nvmem/layouts/u-boot-env.h | 15 ++
+ drivers/nvmem/u-boot-env.c | 165 +---------------------
+ 7 files changed, 242 insertions(+), 165 deletions(-)
+ create mode 100644 drivers/nvmem/layouts/u-boot-env.c
+ create mode 100644 drivers/nvmem/layouts/u-boot-env.h
+
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -21033,6 +21033,7 @@ U-BOOT ENVIRONMENT VARIABLES
+ M: Rafał Miłecki <rafal@milecki.pl>
+ S: Maintained
+ F: Documentation/devicetree/bindings/nvmem/u-boot,env.yaml
++F: drivers/nvmem/layouts/u-boot-env.c
+ F: drivers/nvmem/u-boot-env.c
+
+ UACCE ACCELERATOR FRAMEWORK
+--- a/drivers/nvmem/Kconfig
++++ b/drivers/nvmem/Kconfig
+@@ -363,8 +363,7 @@ config NVMEM_SUNXI_SID
+ config NVMEM_U_BOOT_ENV
+ tristate "U-Boot environment variables support"
+ depends on OF && MTD
+- select CRC32
+- select GENERIC_NET_UTILS
++ select NVMEM_LAYOUT_U_BOOT_ENV
+ help
+ U-Boot stores its setup as environment variables. This driver adds
+ support for verifying & exporting such data. It also exposes variables
+--- a/drivers/nvmem/layouts/Kconfig
++++ b/drivers/nvmem/layouts/Kconfig
+@@ -26,6 +26,17 @@ config NVMEM_LAYOUT_ONIE_TLV
+
+ If unsure, say N.
+
++config NVMEM_LAYOUT_U_BOOT_ENV
++ tristate "U-Boot environment variables layout"
++ select CRC32
++ select GENERIC_NET_UTILS
++ help
++ U-Boot stores its setup as environment variables. This driver adds
++ support for verifying & exporting such data. It also exposes variables
++ as NVMEM cells so they can be referenced by other drivers.
++
++ If unsure, say N.
++
+ endmenu
+
+ endif
+--- a/drivers/nvmem/layouts/Makefile
++++ b/drivers/nvmem/layouts/Makefile
+@@ -5,3 +5,4 @@
+
+ obj-$(CONFIG_NVMEM_LAYOUT_SL28_VPD) += sl28vpd.o
+ obj-$(CONFIG_NVMEM_LAYOUT_ONIE_TLV) += onie-tlv.o
++obj-$(CONFIG_NVMEM_LAYOUT_U_BOOT_ENV) += u-boot-env.o
+--- /dev/null
++++ b/drivers/nvmem/layouts/u-boot-env.c
+@@ -0,0 +1,211 @@
++// SPDX-License-Identifier: GPL-2.0-only
++/*
++ * Copyright (C) 2022 - 2023 Rafał Miłecki <rafal@milecki.pl>
++ */
++
++#include <linux/crc32.h>
++#include <linux/etherdevice.h>
++#include <linux/export.h>
++#include <linux/if_ether.h>
++#include <linux/nvmem-consumer.h>
++#include <linux/nvmem-provider.h>
++#include <linux/of.h>
++#include <linux/slab.h>
++
++#include "u-boot-env.h"
++
++struct u_boot_env_image_single {
++ __le32 crc32;
++ uint8_t data[];
++} __packed;
++
++struct u_boot_env_image_redundant {
++ __le32 crc32;
++ u8 mark;
++ uint8_t data[];
++} __packed;
++
++struct u_boot_env_image_broadcom {
++ __le32 magic;
++ __le32 len;
++ __le32 crc32;
++ DECLARE_FLEX_ARRAY(uint8_t, data);
++} __packed;
++
++static int u_boot_env_read_post_process_ethaddr(void *context, const char *id, int index,
++ unsigned int offset, void *buf, size_t bytes)
++{
++ u8 mac[ETH_ALEN];
++
++ if (bytes != 3 * ETH_ALEN - 1)
++ return -EINVAL;
++
++ if (!mac_pton(buf, mac))
++ return -EINVAL;
++
++ if (index)
++ eth_addr_add(mac, index);
++
++ ether_addr_copy(buf, mac);
++
++ return 0;
++}
++
++static int u_boot_env_parse_cells(struct device *dev, struct nvmem_device *nvmem, uint8_t *buf,
++ size_t data_offset, size_t data_len)
++{
++ char *data = buf + data_offset;
++ char *var, *value, *eq;
++
++ for (var = data;
++ var < data + data_len && *var;
++ var = value + strlen(value) + 1) {
++ struct nvmem_cell_info info = {};
++
++ eq = strchr(var, '=');
++ if (!eq)
++ break;
++ *eq = '\0';
++ value = eq + 1;
++
++ info.name = devm_kstrdup(dev, var, GFP_KERNEL);
++ if (!info.name)
++ return -ENOMEM;
++ info.offset = data_offset + value - data;
++ info.bytes = strlen(value);
++ info.np = of_get_child_by_name(dev->of_node, info.name);
++ if (!strcmp(var, "ethaddr")) {
++ info.raw_len = strlen(value);
++ info.bytes = ETH_ALEN;
++ info.read_post_process = u_boot_env_read_post_process_ethaddr;
++ }
++
++ nvmem_add_one_cell(nvmem, &info);
++ }
++
++ return 0;
++}
++
++int u_boot_env_parse(struct device *dev, struct nvmem_device *nvmem,
++ enum u_boot_env_format format)
++{
++ size_t crc32_data_offset;
++ size_t crc32_data_len;
++ size_t crc32_offset;
++ __le32 *crc32_addr;
++ size_t data_offset;
++ size_t data_len;
++ size_t dev_size;
++ uint32_t crc32;
++ uint32_t calc;
++ uint8_t *buf;
++ int bytes;
++ int err;
++
++ dev_size = nvmem_dev_size(nvmem);
++
++ buf = kzalloc(dev_size, GFP_KERNEL);
++ if (!buf) {
++ err = -ENOMEM;
++ goto err_out;
++ }
++
++ bytes = nvmem_device_read(nvmem, 0, dev_size, buf);
++ if (bytes < 0) {
++ err = bytes;
++ goto err_kfree;
++ } else if (bytes != dev_size) {
++ err = -EIO;
++ goto err_kfree;
++ }
++
++ switch (format) {
++ case U_BOOT_FORMAT_SINGLE:
++ crc32_offset = offsetof(struct u_boot_env_image_single, crc32);
++ crc32_data_offset = offsetof(struct u_boot_env_image_single, data);
++ data_offset = offsetof(struct u_boot_env_image_single, data);
++ break;
++ case U_BOOT_FORMAT_REDUNDANT:
++ crc32_offset = offsetof(struct u_boot_env_image_redundant, crc32);
++ crc32_data_offset = offsetof(struct u_boot_env_image_redundant, data);
++ data_offset = offsetof(struct u_boot_env_image_redundant, data);
++ break;
++ case U_BOOT_FORMAT_BROADCOM:
++ crc32_offset = offsetof(struct u_boot_env_image_broadcom, crc32);
++ crc32_data_offset = offsetof(struct u_boot_env_image_broadcom, data);
++ data_offset = offsetof(struct u_boot_env_image_broadcom, data);
++ break;
++ }
++
++ if (dev_size < data_offset) {
++ dev_err(dev, "Device too small for u-boot-env\n");
++ err = -EIO;
++ goto err_kfree;
++ }
++
++ crc32_addr = (__le32 *)(buf + crc32_offset);
++ crc32 = le32_to_cpu(*crc32_addr);
++ crc32_data_len = dev_size - crc32_data_offset;
++ data_len = dev_size - data_offset;
++
++ calc = crc32(~0, buf + crc32_data_offset, crc32_data_len) ^ ~0L;
++ if (calc != crc32) {
++ dev_err(dev, "Invalid calculated CRC32: 0x%08x (expected: 0x%08x)\n", calc, crc32);
++ err = -EINVAL;
++ goto err_kfree;
++ }
++
++ buf[dev_size - 1] = '\0';
++ err = u_boot_env_parse_cells(dev, nvmem, buf, data_offset, data_len);
++
++err_kfree:
++ kfree(buf);
++err_out:
++ return err;
++}
++EXPORT_SYMBOL_GPL(u_boot_env_parse);
++
++static int u_boot_env_add_cells(struct nvmem_layout *layout)
++{
++ struct device *dev = &layout->dev;
++ enum u_boot_env_format format;
++
++ format = (uintptr_t)device_get_match_data(dev);
++
++ return u_boot_env_parse(dev, layout->nvmem, format);
++}
++
++static int u_boot_env_probe(struct nvmem_layout *layout)
++{
++ layout->add_cells = u_boot_env_add_cells;
++
++ return nvmem_layout_register(layout);
++}
++
++static void u_boot_env_remove(struct nvmem_layout *layout)
++{
++ nvmem_layout_unregister(layout);
++}
++
++static const struct of_device_id u_boot_env_of_match_table[] = {
++ { .compatible = "u-boot,env", .data = (void *)U_BOOT_FORMAT_SINGLE, },
++ { .compatible = "u-boot,env-redundant-bool", .data = (void *)U_BOOT_FORMAT_REDUNDANT, },
++ { .compatible = "u-boot,env-redundant-count", .data = (void *)U_BOOT_FORMAT_REDUNDANT, },
++ { .compatible = "brcm,env", .data = (void *)U_BOOT_FORMAT_BROADCOM, },
++ {},
++};
++
++static struct nvmem_layout_driver u_boot_env_layout = {
++ .driver = {
++ .name = "u-boot-env-layout",
++ .of_match_table = u_boot_env_of_match_table,
++ },
++ .probe = u_boot_env_probe,
++ .remove = u_boot_env_remove,
++};
++module_nvmem_layout_driver(u_boot_env_layout);
++
++MODULE_AUTHOR("Rafał Miłecki");
++MODULE_LICENSE("GPL");
++MODULE_DEVICE_TABLE(of, u_boot_env_of_match_table);
++MODULE_DESCRIPTION("NVMEM layout driver for U-Boot environment variables");
+--- /dev/null
++++ b/drivers/nvmem/layouts/u-boot-env.h
+@@ -0,0 +1,15 @@
++/* SPDX-License-Identifier: GPL-2.0-only */
++
++#ifndef _LINUX_NVMEM_LAYOUTS_U_BOOT_ENV_H
++#define _LINUX_NVMEM_LAYOUTS_U_BOOT_ENV_H
++
++enum u_boot_env_format {
++ U_BOOT_FORMAT_SINGLE,
++ U_BOOT_FORMAT_REDUNDANT,
++ U_BOOT_FORMAT_BROADCOM,
++};
++
++int u_boot_env_parse(struct device *dev, struct nvmem_device *nvmem,
++ enum u_boot_env_format format);
++
++#endif /* ifndef _LINUX_NVMEM_LAYOUTS_U_BOOT_ENV_H */
+--- a/drivers/nvmem/u-boot-env.c
++++ b/drivers/nvmem/u-boot-env.c
+@@ -3,23 +3,15 @@
+ * Copyright (C) 2022 Rafał Miłecki <rafal@milecki.pl>
+ */
+
+-#include <linux/crc32.h>
+-#include <linux/etherdevice.h>
+-#include <linux/if_ether.h>
+ #include <linux/mod_devicetable.h>
+ #include <linux/module.h>
+ #include <linux/mtd/mtd.h>
+-#include <linux/nvmem-consumer.h>
+ #include <linux/nvmem-provider.h>
+ #include <linux/of_device.h>
+ #include <linux/platform_device.h>
+ #include <linux/slab.h>
+
+-enum u_boot_env_format {
+- U_BOOT_FORMAT_SINGLE,
+- U_BOOT_FORMAT_REDUNDANT,
+- U_BOOT_FORMAT_BROADCOM,
+-};
++#include "layouts/u-boot-env.h"
+
+ struct u_boot_env {
+ struct device *dev;
+@@ -29,24 +21,6 @@ struct u_boot_env {
+ struct mtd_info *mtd;
+ };
+
+-struct u_boot_env_image_single {
+- __le32 crc32;
+- uint8_t data[];
+-} __packed;
+-
+-struct u_boot_env_image_redundant {
+- __le32 crc32;
+- u8 mark;
+- uint8_t data[];
+-} __packed;
+-
+-struct u_boot_env_image_broadcom {
+- __le32 magic;
+- __le32 len;
+- __le32 crc32;
+- DECLARE_FLEX_ARRAY(uint8_t, data);
+-} __packed;
+-
+ static int u_boot_env_read(void *context, unsigned int offset, void *val,
+ size_t bytes)
+ {
+@@ -69,141 +43,6 @@ static int u_boot_env_read(void *context
+ return 0;
+ }
+
+-static int u_boot_env_read_post_process_ethaddr(void *context, const char *id, int index,
+- unsigned int offset, void *buf, size_t bytes)
+-{
+- u8 mac[ETH_ALEN];
+-
+- if (bytes != 3 * ETH_ALEN - 1)
+- return -EINVAL;
+-
+- if (!mac_pton(buf, mac))
+- return -EINVAL;
+-
+- if (index)
+- eth_addr_add(mac, index);
+-
+- ether_addr_copy(buf, mac);
+-
+- return 0;
+-}
+-
+-static int u_boot_env_add_cells(struct u_boot_env *priv, uint8_t *buf,
+- size_t data_offset, size_t data_len)
+-{
+- struct nvmem_device *nvmem = priv->nvmem;
+- struct device *dev = priv->dev;
+- char *data = buf + data_offset;
+- char *var, *value, *eq;
+-
+- for (var = data;
+- var < data + data_len && *var;
+- var = value + strlen(value) + 1) {
+- struct nvmem_cell_info info = {};
+-
+- eq = strchr(var, '=');
+- if (!eq)
+- break;
+- *eq = '\0';
+- value = eq + 1;
+-
+- info.name = devm_kstrdup(dev, var, GFP_KERNEL);
+- if (!info.name)
+- return -ENOMEM;
+- info.offset = data_offset + value - data;
+- info.bytes = strlen(value);
+- info.np = of_get_child_by_name(dev->of_node, info.name);
+- if (!strcmp(var, "ethaddr")) {
+- info.raw_len = strlen(value);
+- info.bytes = ETH_ALEN;
+- info.read_post_process = u_boot_env_read_post_process_ethaddr;
+- }
+-
+- nvmem_add_one_cell(nvmem, &info);
+- }
+-
+- return 0;
+-}
+-
+-static int u_boot_env_parse(struct u_boot_env *priv)
+-{
+- struct nvmem_device *nvmem = priv->nvmem;
+- struct device *dev = priv->dev;
+- size_t crc32_data_offset;
+- size_t crc32_data_len;
+- size_t crc32_offset;
+- __le32 *crc32_addr;
+- size_t data_offset;
+- size_t data_len;
+- size_t dev_size;
+- uint32_t crc32;
+- uint32_t calc;
+- uint8_t *buf;
+- int bytes;
+- int err;
+-
+- dev_size = nvmem_dev_size(nvmem);
+-
+- buf = kzalloc(dev_size, GFP_KERNEL);
+- if (!buf) {
+- err = -ENOMEM;
+- goto err_out;
+- }
+-
+- bytes = nvmem_device_read(nvmem, 0, dev_size, buf);
+- if (bytes < 0) {
+- err = bytes;
+- goto err_kfree;
+- } else if (bytes != dev_size) {
+- err = -EIO;
+- goto err_kfree;
+- }
+-
+- switch (priv->format) {
+- case U_BOOT_FORMAT_SINGLE:
+- crc32_offset = offsetof(struct u_boot_env_image_single, crc32);
+- crc32_data_offset = offsetof(struct u_boot_env_image_single, data);
+- data_offset = offsetof(struct u_boot_env_image_single, data);
+- break;
+- case U_BOOT_FORMAT_REDUNDANT:
+- crc32_offset = offsetof(struct u_boot_env_image_redundant, crc32);
+- crc32_data_offset = offsetof(struct u_boot_env_image_redundant, data);
+- data_offset = offsetof(struct u_boot_env_image_redundant, data);
+- break;
+- case U_BOOT_FORMAT_BROADCOM:
+- crc32_offset = offsetof(struct u_boot_env_image_broadcom, crc32);
+- crc32_data_offset = offsetof(struct u_boot_env_image_broadcom, data);
+- data_offset = offsetof(struct u_boot_env_image_broadcom, data);
+- break;
+- }
+-
+- if (dev_size < data_offset) {
+- dev_err(dev, "Device too small for u-boot-env\n");
+- err = -EIO;
+- goto err_kfree;
+- }
+-
+- crc32_addr = (__le32 *)(buf + crc32_offset);
+- crc32 = le32_to_cpu(*crc32_addr);
+- crc32_data_len = dev_size - crc32_data_offset;
+- data_len = dev_size - data_offset;
+-
+- calc = crc32(~0, buf + crc32_data_offset, crc32_data_len) ^ ~0L;
+- if (calc != crc32) {
+- dev_err(dev, "Invalid calculated CRC32: 0x%08x (expected: 0x%08x)\n", calc, crc32);
+- err = -EINVAL;
+- goto err_kfree;
+- }
+-
+- buf[dev_size - 1] = '\0';
+- err = u_boot_env_add_cells(priv, buf, data_offset, data_len);
+-
+-err_kfree:
+- kfree(buf);
+-err_out:
+- return err;
+-}
+-
+ static int u_boot_env_probe(struct platform_device *pdev)
+ {
+ struct nvmem_config config = {
+@@ -235,7 +74,7 @@ static int u_boot_env_probe(struct platf
+ if (IS_ERR(priv->nvmem))
+ return PTR_ERR(priv->nvmem);
+
+- return u_boot_env_parse(priv);
++ return u_boot_env_parse(dev, priv->nvmem, priv->format);
+ }
+
+ static const struct of_device_id u_boot_env_of_match_table[] = {
diff --git a/target/linux/generic/backport-6.1/851-v6.2-bus-mhi-host-pci_generic-Add-HP-variant-of-T99W175.patch b/target/linux/generic/backport-6.1/851-v6.2-bus-mhi-host-pci_generic-Add-HP-variant-of-T99W175.patch
index 0dabc48bfa..6f9fc71a71 100644
--- a/target/linux/generic/backport-6.1/851-v6.2-bus-mhi-host-pci_generic-Add-HP-variant-of-T99W175.patch
+++ b/target/linux/generic/backport-6.1/851-v6.2-bus-mhi-host-pci_generic-Add-HP-variant-of-T99W175.patch
@@ -22,7 +22,7 @@ Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
--- a/drivers/bus/mhi/host/pci_generic.c
+++ b/drivers/bus/mhi/host/pci_generic.c
-@@ -596,6 +596,9 @@ static const struct pci_device_id mhi_pc
+@@ -599,6 +599,9 @@ static const struct pci_device_id mhi_pc
/* MV32-WB (Cinterion) */
{ PCI_DEVICE(0x1269, 0x00bb),
.driver_data = (kernel_ulong_t) &mhi_mv32_info },
diff --git a/target/linux/generic/backport-6.1/852-v6.2-bus-mhi-host-pci_generic-Add-definition-for-some-VID.patch b/target/linux/generic/backport-6.1/852-v6.2-bus-mhi-host-pci_generic-Add-definition-for-some-VID.patch
index fbf6c8a501..12419fbe39 100644
--- a/target/linux/generic/backport-6.1/852-v6.2-bus-mhi-host-pci_generic-Add-definition-for-some-VID.patch
+++ b/target/linux/generic/backport-6.1/852-v6.2-bus-mhi-host-pci_generic-Add-definition-for-some-VID.patch
@@ -28,7 +28,7 @@ Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
/**
* struct mhi_pci_dev_info - MHI PCI device specific information
* @config: MHI controller configuration
-@@ -557,11 +561,11 @@ static const struct pci_device_id mhi_pc
+@@ -560,11 +564,11 @@ static const struct pci_device_id mhi_pc
.driver_data = (kernel_ulong_t) &mhi_telit_fn990_info },
{ PCI_DEVICE(PCI_VENDOR_ID_QCOM, 0x0308),
.driver_data = (kernel_ulong_t) &mhi_qcom_sdx65_info },
@@ -43,7 +43,7 @@ Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
.driver_data = (kernel_ulong_t) &mhi_quectel_em1xx_info },
/* T99W175 (sdx55), Both for eSIM and Non-eSIM */
{ PCI_DEVICE(PCI_VENDOR_ID_FOXCONN, 0xe0ab),
-@@ -585,16 +589,16 @@ static const struct pci_device_id mhi_pc
+@@ -588,16 +592,16 @@ static const struct pci_device_id mhi_pc
{ PCI_DEVICE(PCI_VENDOR_ID_FOXCONN, 0xe0d9),
.driver_data = (kernel_ulong_t) &mhi_foxconn_sdx65_info },
/* MV31-W (Cinterion) */
diff --git a/target/linux/generic/backport-6.1/853-v6.2-bus-mhi-host-pci_generic-Drop-redundant-pci_enable_p.patch b/target/linux/generic/backport-6.1/853-v6.2-bus-mhi-host-pci_generic-Drop-redundant-pci_enable_p.patch
index 2f5a0ac11d..943227d2a8 100644
--- a/target/linux/generic/backport-6.1/853-v6.2-bus-mhi-host-pci_generic-Drop-redundant-pci_enable_p.patch
+++ b/target/linux/generic/backport-6.1/853-v6.2-bus-mhi-host-pci_generic-Drop-redundant-pci_enable_p.patch
@@ -36,7 +36,7 @@ Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/mhi.h>
-@@ -901,11 +900,9 @@ static int mhi_pci_probe(struct pci_dev
+@@ -904,11 +903,9 @@ static int mhi_pci_probe(struct pci_dev
mhi_pdev->pci_state = pci_store_saved_state(pdev);
pci_load_saved_state(pdev, NULL);
@@ -49,7 +49,7 @@ Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
/* MHI bus does not power up the controller by default */
err = mhi_prepare_for_power_up(mhi_cntrl);
-@@ -939,8 +936,6 @@ err_unprepare:
+@@ -942,8 +939,6 @@ err_unprepare:
mhi_unprepare_after_power_down(mhi_cntrl);
err_unregister:
mhi_unregister_controller(mhi_cntrl);
@@ -58,7 +58,7 @@ Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
return err;
}
-@@ -963,7 +958,6 @@ static void mhi_pci_remove(struct pci_de
+@@ -966,7 +961,6 @@ static void mhi_pci_remove(struct pci_de
pm_runtime_get_noresume(&pdev->dev);
mhi_unregister_controller(mhi_cntrl);
diff --git a/target/linux/generic/backport-6.1/854-v6.4-bus-mhi-pci_generic-Add-Foxconn-T99W510.patch b/target/linux/generic/backport-6.1/854-v6.4-bus-mhi-pci_generic-Add-Foxconn-T99W510.patch
index f757ca28e5..8ec6f3e76f 100644
--- a/target/linux/generic/backport-6.1/854-v6.4-bus-mhi-pci_generic-Add-Foxconn-T99W510.patch
+++ b/target/linux/generic/backport-6.1/854-v6.4-bus-mhi-pci_generic-Add-Foxconn-T99W510.patch
@@ -31,7 +31,7 @@ Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
static const struct mhi_pci_dev_info mhi_foxconn_sdx55_info = {
.name = "foxconn-sdx55",
.fw = "qcom/sdx55m/sbl1.mbn",
-@@ -587,6 +596,15 @@ static const struct pci_device_id mhi_pc
+@@ -590,6 +599,15 @@ static const struct pci_device_id mhi_pc
/* T99W373 (sdx62) */
{ PCI_DEVICE(PCI_VENDOR_ID_FOXCONN, 0xe0d9),
.driver_data = (kernel_ulong_t) &mhi_foxconn_sdx65_info },
diff --git a/target/linux/generic/backport-6.1/856-v6.6-bus-mhi-host-pci_generic-Add-support-for-Quectel-EM1.patch b/target/linux/generic/backport-6.1/856-v6.6-bus-mhi-host-pci_generic-Add-support-for-Quectel-EM1.patch
index 5c15eec712..2e01d4fd65 100644
--- a/target/linux/generic/backport-6.1/856-v6.6-bus-mhi-host-pci_generic-Add-support-for-Quectel-EM1.patch
+++ b/target/linux/generic/backport-6.1/856-v6.6-bus-mhi-host-pci_generic-Add-support-for-Quectel-EM1.patch
@@ -23,7 +23,7 @@ Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
--- a/drivers/bus/mhi/host/pci_generic.c
+++ b/drivers/bus/mhi/host/pci_generic.c
-@@ -591,6 +591,8 @@ static const struct pci_device_id mhi_pc
+@@ -594,6 +594,8 @@ static const struct pci_device_id mhi_pc
.driver_data = (kernel_ulong_t) &mhi_quectel_em1xx_info },
{ PCI_DEVICE(PCI_VENDOR_ID_QUECTEL, 0x1002), /* EM160R-GL (sdx24) */
.driver_data = (kernel_ulong_t) &mhi_quectel_em1xx_info },
diff --git a/target/linux/generic/backport-6.1/857-v6.6-bus-mhi-host-pci_generic-Add-support-for-Quectel-RM5.patch b/target/linux/generic/backport-6.1/857-v6.6-bus-mhi-host-pci_generic-Add-support-for-Quectel-RM5.patch
index 5922207e29..f547eb972f 100644
--- a/target/linux/generic/backport-6.1/857-v6.6-bus-mhi-host-pci_generic-Add-support-for-Quectel-RM5.patch
+++ b/target/linux/generic/backport-6.1/857-v6.6-bus-mhi-host-pci_generic-Add-support-for-Quectel-RM5.patch
@@ -37,7 +37,7 @@ Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
static const struct mhi_channel_config mhi_foxconn_sdx55_channels[] = {
MHI_CHANNEL_CONFIG_UL(0, "LOOPBACK", 32, 0),
MHI_CHANNEL_CONFIG_DL(1, "LOOPBACK", 32, 0),
-@@ -591,6 +601,9 @@ static const struct pci_device_id mhi_pc
+@@ -594,6 +604,9 @@ static const struct pci_device_id mhi_pc
.driver_data = (kernel_ulong_t) &mhi_quectel_em1xx_info },
{ PCI_DEVICE(PCI_VENDOR_ID_QUECTEL, 0x1002), /* EM160R-GL (sdx24) */
.driver_data = (kernel_ulong_t) &mhi_quectel_em1xx_info },
diff --git a/target/linux/generic/backport-6.1/858-v6.6-bus-mhi-host-pci_generic-Add-support-for-Dell-DW5932.patch b/target/linux/generic/backport-6.1/858-v6.6-bus-mhi-host-pci_generic-Add-support-for-Dell-DW5932.patch
index bb7b3c3ffc..ba0e156a8c 100644
--- a/target/linux/generic/backport-6.1/858-v6.6-bus-mhi-host-pci_generic-Add-support-for-Dell-DW5932.patch
+++ b/target/linux/generic/backport-6.1/858-v6.6-bus-mhi-host-pci_generic-Add-support-for-Dell-DW5932.patch
@@ -19,7 +19,7 @@ Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
--- a/drivers/bus/mhi/host/pci_generic.c
+++ b/drivers/bus/mhi/host/pci_generic.c
-@@ -638,6 +638,12 @@ static const struct pci_device_id mhi_pc
+@@ -641,6 +641,12 @@ static const struct pci_device_id mhi_pc
/* T99W510 (sdx24), variant 3 */
{ PCI_DEVICE(PCI_VENDOR_ID_FOXCONN, 0xe0f2),
.driver_data = (kernel_ulong_t) &mhi_foxconn_sdx24_info },
diff --git a/target/linux/generic/backport-6.1/859-v6.6-bus-mhi-host-pci_generic-Add-support-for-Quectel-RM5.patch b/target/linux/generic/backport-6.1/859-v6.6-bus-mhi-host-pci_generic-Add-support-for-Quectel-RM5.patch
index c0dfe01e32..a09ae6fa47 100644
--- a/target/linux/generic/backport-6.1/859-v6.6-bus-mhi-host-pci_generic-Add-support-for-Quectel-RM5.patch
+++ b/target/linux/generic/backport-6.1/859-v6.6-bus-mhi-host-pci_generic-Add-support-for-Quectel-RM5.patch
@@ -24,7 +24,7 @@ Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
--- a/drivers/bus/mhi/host/pci_generic.c
+++ b/drivers/bus/mhi/host/pci_generic.c
-@@ -604,6 +604,9 @@ static const struct pci_device_id mhi_pc
+@@ -607,6 +607,9 @@ static const struct pci_device_id mhi_pc
/* RM520N-GL (sdx6x), eSIM */
{ PCI_DEVICE(PCI_VENDOR_ID_QUECTEL, 0x1004),
.driver_data = (kernel_ulong_t) &mhi_quectel_rm5xx_info },
diff --git a/target/linux/generic/backport-6.1/860-v6.6-bus-mhi-host-pci_generic-add-support-for-Telit-FE990.patch b/target/linux/generic/backport-6.1/860-v6.6-bus-mhi-host-pci_generic-add-support-for-Telit-FE990.patch
deleted file mode 100644
index 40fdfc613b..0000000000
--- a/target/linux/generic/backport-6.1/860-v6.6-bus-mhi-host-pci_generic-add-support-for-Telit-FE990.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From 30001cf3a19a2f676a0e23c2c3a511c4a8903284 Mon Sep 17 00:00:00 2001
-From: Daniele Palmas <dnlplm@gmail.com>
-Date: Fri, 4 Aug 2023 11:40:39 +0200
-Subject: [PATCH 11/13] bus: mhi: host: pci_generic: add support for Telit
- FE990 modem
-
-Add support for Telit FE990 that has the same configuration as FN990:
-
-$ lspci -vv
-04:00.0 Unassigned class [ff00]: Qualcomm Device 0308
- Subsystem: Device 1c5d:2015
-
-Signed-off-by: Daniele Palmas <dnlplm@gmail.com>
-Reviewed-by: Manivannan Sadhasivam <mani@kernel.org>
-Link: https://lore.kernel.org/r/20230804094039.365102-1-dnlplm@gmail.com
-[mani: minor update to commit subject and adjusted comment]
-Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
----
- drivers/bus/mhi/host/pci_generic.c | 3 +++
- 1 file changed, 3 insertions(+)
-
---- a/drivers/bus/mhi/host/pci_generic.c
-+++ b/drivers/bus/mhi/host/pci_generic.c
-@@ -595,6 +595,9 @@ static const struct pci_device_id mhi_pc
- /* Telit FN990 */
- { PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0308, 0x1c5d, 0x2010),
- .driver_data = (kernel_ulong_t) &mhi_telit_fn990_info },
-+ /* Telit FE990 */
-+ { PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0308, 0x1c5d, 0x2015),
-+ .driver_data = (kernel_ulong_t) &mhi_telit_fn990_info },
- { PCI_DEVICE(PCI_VENDOR_ID_QCOM, 0x0308),
- .driver_data = (kernel_ulong_t) &mhi_qcom_sdx65_info },
- { PCI_DEVICE(PCI_VENDOR_ID_QUECTEL, 0x1001), /* EM120R-GL (sdx24) */
diff --git a/target/linux/generic/backport-6.1/894-v6.8-net-ethtool-implement-ethtool_puts.patch b/target/linux/generic/backport-6.1/894-v6.8-net-ethtool-implement-ethtool_puts.patch
index 5094a6d774..379a4fc7c0 100644
--- a/target/linux/generic/backport-6.1/894-v6.8-net-ethtool-implement-ethtool_puts.patch
+++ b/target/linux/generic/backport-6.1/894-v6.8-net-ethtool-implement-ethtool_puts.patch
@@ -123,7 +123,7 @@ Signed-off-by: Justin Stitt <justinstitt@google.com>
#endif /* _LINUX_ETHTOOL_H */
--- a/net/ethtool/ioctl.c
+++ b/net/ethtool/ioctl.c
-@@ -1974,6 +1974,13 @@ __printf(2, 3) void ethtool_sprintf(u8 *
+@@ -1977,6 +1977,13 @@ __printf(2, 3) void ethtool_sprintf(u8 *
}
EXPORT_SYMBOL(ethtool_sprintf);
diff --git a/target/linux/generic/backport-6.6/200-regmap-maple-work-around-false-positive-warning.patch b/target/linux/generic/backport-6.6/200-regmap-maple-work-around-false-positive-warning.patch
new file mode 100644
index 0000000000..de5c813804
--- /dev/null
+++ b/target/linux/generic/backport-6.6/200-regmap-maple-work-around-false-positive-warning.patch
@@ -0,0 +1,47 @@
+From 542440fd7b30983cae23e32bd22f69a076ec7ef4 Mon Sep 17 00:00:00 2001
+From: Arnd Bergmann <arnd@arndb.de>
+Date: Fri, 19 Jul 2024 12:40:24 +0200
+Subject: regmap: maple: work around gcc-14.1 false-positive warning
+
+With gcc-14.1, there is a false-postive -Wuninitialized warning in
+regcache_maple_drop:
+
+drivers/base/regmap/regcache-maple.c: In function 'regcache_maple_drop':
+drivers/base/regmap/regcache-maple.c:113:23: error: 'lower_index' is used uninitialized [-Werror=uninitialized]
+ 113 | unsigned long lower_index, lower_last;
+ | ^~~~~~~~~~~
+drivers/base/regmap/regcache-maple.c:113:36: error: 'lower_last' is used uninitialized [-Werror=uninitialized]
+ 113 | unsigned long lower_index, lower_last;
+ | ^~~~~~~~~~
+
+I've created a reduced test case to see if this needs to be reported
+as a gcc, but it appears that the gcc-14.x branch already has a change
+that turns this into a more sensible -Wmaybe-uninitialized warning, so
+I ended up not reporting it so far.
+
+The reduced test case also produces a warning for gcc-13 and gcc-12
+but I don't see that with the version in the kernel.
+
+Link: https://godbolt.org/z/oKbohKqd3
+Link: https://lore.kernel.org/all/CAMuHMdWj=FLmkazPbYKPevDrcym2_HDb_U7Mb9YE9ovrP0jJfA@mail.gmail.com/
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Link: https://patch.msgid.link/20240719104030.1382465-1-arnd@kernel.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+---
+ drivers/base/regmap/regcache-maple.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+(limited to 'drivers/base/regmap/regcache-maple.c')
+
+--- a/drivers/base/regmap/regcache-maple.c
++++ b/drivers/base/regmap/regcache-maple.c
+@@ -110,7 +110,8 @@ static int regcache_maple_drop(struct re
+ struct maple_tree *mt = map->cache;
+ MA_STATE(mas, mt, min, max);
+ unsigned long *entry, *lower, *upper;
+- unsigned long lower_index, lower_last;
++ /* initialized to work around false-positive -Wuninitialized warning */
++ unsigned long lower_index = 0, lower_last = 0;
+ unsigned long upper_index, upper_last;
+ int ret = 0;
+
diff --git a/target/linux/generic/backport-6.6/310-v6.7-mips-kexec-fix-the-incorrect-ifdeffery-and-dependenc.patch b/target/linux/generic/backport-6.6/310-v6.7-mips-kexec-fix-the-incorrect-ifdeffery-and-dependenc.patch
index 99a6bfe638..6d3c7d04fe 100644
--- a/target/linux/generic/backport-6.6/310-v6.7-mips-kexec-fix-the-incorrect-ifdeffery-and-dependenc.patch
+++ b/target/linux/generic/backport-6.6/310-v6.7-mips-kexec-fix-the-incorrect-ifdeffery-and-dependenc.patch
@@ -134,7 +134,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
};
--- a/arch/mips/kernel/smp-cps.c
+++ b/arch/mips/kernel/smp-cps.c
-@@ -392,7 +392,7 @@ static void cps_smp_finish(void)
+@@ -395,7 +395,7 @@ static void cps_smp_finish(void)
local_irq_enable();
}
@@ -143,7 +143,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
enum cpu_death {
CPU_DEATH_HALT,
-@@ -429,7 +429,7 @@ static void cps_shutdown_this_cpu(enum c
+@@ -432,7 +432,7 @@ static void cps_shutdown_this_cpu(enum c
}
}
@@ -152,7 +152,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
static void cps_kexec_nonboot_cpu(void)
{
-@@ -439,9 +439,9 @@ static void cps_kexec_nonboot_cpu(void)
+@@ -442,9 +442,9 @@ static void cps_kexec_nonboot_cpu(void)
cps_shutdown_this_cpu(CPU_DEATH_POWER);
}
@@ -164,7 +164,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
#ifdef CONFIG_HOTPLUG_CPU
-@@ -610,7 +610,7 @@ static const struct plat_smp_ops cps_smp
+@@ -613,7 +613,7 @@ static const struct plat_smp_ops cps_smp
.cpu_die = cps_cpu_die,
.cleanup_dead_cpu = cps_cleanup_dead_cpu,
#endif
@@ -175,8 +175,8 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
};
--- a/arch/mips/loongson64/reset.c
+++ b/arch/mips/loongson64/reset.c
-@@ -53,7 +53,7 @@ static void loongson_halt(void)
- }
+@@ -39,7 +39,7 @@ static int firmware_poweroff(struct sys_
+ return NOTIFY_DONE;
}
-#ifdef CONFIG_KEXEC
@@ -184,9 +184,9 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
/* 0X80000000~0X80200000 is safe */
#define MAX_ARGS 64
-@@ -158,7 +158,7 @@ static int __init mips_reboot_setup(void
- _machine_halt = loongson_halt;
- pm_power_off = loongson_poweroff;
+@@ -152,7 +152,7 @@ static int __init mips_reboot_setup(void
+ firmware_poweroff, NULL);
+ }
-#ifdef CONFIG_KEXEC
+#ifdef CONFIG_KEXEC_CORE
@@ -195,7 +195,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
return -ENOMEM;
--- a/arch/mips/loongson64/smp.c
+++ b/arch/mips/loongson64/smp.c
-@@ -864,7 +864,7 @@ const struct plat_smp_ops loongson3_smp_
+@@ -883,7 +883,7 @@ const struct plat_smp_ops loongson3_smp_
.cpu_disable = loongson3_cpu_disable,
.cpu_die = loongson3_cpu_die,
#endif
diff --git a/target/linux/bmips/patches-6.6/020-v6.11-mips-bmips-rework-and-cache-CBR-addr-handling.patch b/target/linux/generic/backport-6.6/320-v6.11-mips-bmips-rework-and-cache-CBR-addr-handling.patch
index 21eaa3d6cb..21eaa3d6cb 100644
--- a/target/linux/bmips/patches-6.6/020-v6.11-mips-bmips-rework-and-cache-CBR-addr-handling.patch
+++ b/target/linux/generic/backport-6.6/320-v6.11-mips-bmips-rework-and-cache-CBR-addr-handling.patch
diff --git a/target/linux/bmips/patches-6.6/021-v6.11-mips-bmips-setup-make-CBR-address-configurable.patch b/target/linux/generic/backport-6.6/321-v6.11-mips-bmips-setup-make-CBR-address-configurable.patch
index 10a710a31d..10a710a31d 100644
--- a/target/linux/bmips/patches-6.6/021-v6.11-mips-bmips-setup-make-CBR-address-configurable.patch
+++ b/target/linux/generic/backport-6.6/321-v6.11-mips-bmips-setup-make-CBR-address-configurable.patch
diff --git a/target/linux/bmips/patches-6.6/022-v6.11-mips-bmips-enable-RAC-on-BMIPS4350.patch b/target/linux/generic/backport-6.6/322-v6.11-mips-bmips-enable-RAC-on-BMIPS4350.patch
index 2af45df259..2af45df259 100644
--- a/target/linux/bmips/patches-6.6/022-v6.11-mips-bmips-enable-RAC-on-BMIPS4350.patch
+++ b/target/linux/generic/backport-6.6/322-v6.11-mips-bmips-enable-RAC-on-BMIPS4350.patch
diff --git a/target/linux/generic/backport-6.6/610-v6.9-net-mdio-add-2.5g-and-5g-related-PMA-speed-constants.patch b/target/linux/generic/backport-6.6/610-v6.9-net-mdio-add-2.5g-and-5g-related-PMA-speed-constants.patch
new file mode 100644
index 0000000000..9a40ea4b90
--- /dev/null
+++ b/target/linux/generic/backport-6.6/610-v6.9-net-mdio-add-2.5g-and-5g-related-PMA-speed-constants.patch
@@ -0,0 +1,30 @@
+From 6c06c88fa838fcc1b7e5380facd086f57fd9d1c4 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
+Date: Sun, 4 Feb 2024 15:16:46 +0100
+Subject: [PATCH] net: mdio: add 2.5g and 5g related PMA speed constants
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add constants indicating 2.5g and 5g ability in the MMD PMA speed
+register.
+
+Signed-off-by: Marek Behún <kabel@kernel.org>
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Link: https://lore.kernel.org/r/98e15038-d96c-442f-93e4-410100d27866@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ include/uapi/linux/mdio.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/include/uapi/linux/mdio.h
++++ b/include/uapi/linux/mdio.h
+@@ -138,6 +138,8 @@
+ #define MDIO_PMA_SPEED_1000 0x0010 /* 1000M capable */
+ #define MDIO_PMA_SPEED_100 0x0020 /* 100M capable */
+ #define MDIO_PMA_SPEED_10 0x0040 /* 10M capable */
++#define MDIO_PMA_SPEED_2_5G 0x2000 /* 2.5G capable */
++#define MDIO_PMA_SPEED_5G 0x4000 /* 5G capable */
+ #define MDIO_PCS_SPEED_10P2B 0x0002 /* 10PASS-TS/2BASE-TL capable */
+ #define MDIO_PCS_SPEED_2_5G 0x0040 /* 2.5G capable */
+ #define MDIO_PCS_SPEED_5G 0x0080 /* 5G capable */
diff --git a/target/linux/generic/backport-6.6/611-01-v6.11-udp-Allow-GSO-transmit-from-devices-with-no-checksum.patch b/target/linux/generic/backport-6.6/611-01-v6.11-udp-Allow-GSO-transmit-from-devices-with-no-checksum.patch
new file mode 100644
index 0000000000..4a71d1203a
--- /dev/null
+++ b/target/linux/generic/backport-6.6/611-01-v6.11-udp-Allow-GSO-transmit-from-devices-with-no-checksum.patch
@@ -0,0 +1,94 @@
+From: Jakub Sitnicki <jakub@cloudflare.com>
+Date: Wed, 26 Jun 2024 19:51:26 +0200
+Subject: [PATCH] udp: Allow GSO transmit from devices with no checksum offload
+
+Today sending a UDP GSO packet from a TUN device results in an EIO error:
+
+ import fcntl, os, struct
+ from socket import *
+
+ TUNSETIFF = 0x400454CA
+ IFF_TUN = 0x0001
+ IFF_NO_PI = 0x1000
+ UDP_SEGMENT = 103
+
+ tun_fd = os.open("/dev/net/tun", os.O_RDWR)
+ ifr = struct.pack("16sH", b"tun0", IFF_TUN | IFF_NO_PI)
+ fcntl.ioctl(tun_fd, TUNSETIFF, ifr)
+
+ os.system("ip addr add 192.0.2.1/24 dev tun0")
+ os.system("ip link set dev tun0 up")
+
+ s = socket(AF_INET, SOCK_DGRAM)
+ s.setsockopt(SOL_UDP, UDP_SEGMENT, 1200)
+ s.sendto(b"x" * 3000, ("192.0.2.2", 9)) # EIO
+
+This is due to a check in the udp stack if the egress device offers
+checksum offload. While TUN/TAP devices, by default, don't advertise this
+capability because it requires support from the TUN/TAP reader.
+
+However, the GSO stack has a software fallback for checksum calculation,
+which we can use. This way we don't force UDP_SEGMENT users to handle the
+EIO error and implement a segmentation fallback.
+
+Lift the restriction so that UDP_SEGMENT can be used with any egress
+device. We also need to adjust the UDP GSO code to match the GSO stack
+expectation about ip_summed field, as set in commit 8d63bee643f1 ("net:
+avoid skb_warn_bad_offload false positives on UFO"). Otherwise we will hit
+the bad offload check.
+
+Users should, however, expect a potential performance impact when
+batch-sending packets with UDP_SEGMENT without checksum offload on the
+egress device. In such case the packet payload is read twice: first during
+the sendmsg syscall when copying data from user memory, and then in the GSO
+stack for checksum computation. This double memory read can be less
+efficient than a regular sendmsg where the checksum is calculated during
+the initial data copy from user memory.
+
+Signed-off-by: Jakub Sitnicki <jakub@cloudflare.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Link: https://patch.msgid.link/20240626-linux-udpgso-v2-1-422dfcbd6b48@cloudflare.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+
+--- a/net/ipv4/udp.c
++++ b/net/ipv4/udp.c
+@@ -942,8 +942,7 @@ static int udp_send_skb(struct sk_buff *
+ kfree_skb(skb);
+ return -EINVAL;
+ }
+- if (skb->ip_summed != CHECKSUM_PARTIAL || is_udplite ||
+- dst_xfrm(skb_dst(skb))) {
++ if (is_udplite || dst_xfrm(skb_dst(skb))) {
+ kfree_skb(skb);
+ return -EIO;
+ }
+--- a/net/ipv4/udp_offload.c
++++ b/net/ipv4/udp_offload.c
+@@ -362,6 +362,14 @@ struct sk_buff *__udp_gso_segment(struct
+ else
+ uh->check = gso_make_checksum(seg, ~check) ? : CSUM_MANGLED_0;
+
++ /* On the TX path, CHECKSUM_NONE and CHECKSUM_UNNECESSARY have the same
++ * meaning. However, check for bad offloads in the GSO stack expects the
++ * latter, if the checksum was calculated in software. To vouch for the
++ * segment skbs we actually need to set it on the gso_skb.
++ */
++ if (gso_skb->ip_summed == CHECKSUM_NONE)
++ gso_skb->ip_summed = CHECKSUM_UNNECESSARY;
++
+ /* update refcount for the packet */
+ if (copy_dtor) {
+ int delta = sum_truesize - gso_skb->truesize;
+--- a/net/ipv6/udp.c
++++ b/net/ipv6/udp.c
+@@ -1261,8 +1261,7 @@ static int udp_v6_send_skb(struct sk_buf
+ kfree_skb(skb);
+ return -EINVAL;
+ }
+- if (skb->ip_summed != CHECKSUM_PARTIAL || is_udplite ||
+- dst_xfrm(skb_dst(skb))) {
++ if (is_udplite || dst_xfrm(skb_dst(skb))) {
+ kfree_skb(skb);
+ return -EIO;
+ }
diff --git a/target/linux/generic/backport-6.6/611-02-v6.11-net-Make-USO-depend-on-CSUM-offload.patch b/target/linux/generic/backport-6.6/611-02-v6.11-net-Make-USO-depend-on-CSUM-offload.patch
new file mode 100644
index 0000000000..8eecb06304
--- /dev/null
+++ b/target/linux/generic/backport-6.6/611-02-v6.11-net-Make-USO-depend-on-CSUM-offload.patch
@@ -0,0 +1,69 @@
+From: Jakub Sitnicki <jakub@cloudflare.com>
+Date: Thu, 8 Aug 2024 11:56:21 +0200
+Subject: [PATCH] net: Make USO depend on CSUM offload
+
+UDP segmentation offload inherently depends on checksum offload. It should
+not be possible to disable checksum offload while leaving USO enabled.
+Enforce this dependency in code.
+
+There is a single tx-udp-segmentation feature flag to indicate support for
+both IPv4/6, hence the devices wishing to support USO must offer checksum
+offload for both IP versions.
+
+Fixes: 10154dbded6d ("udp: Allow GSO transmit from devices with no checksum offload")
+Suggested-by: Willem de Bruijn <willemdebruijn.kernel@gmail.com>
+Signed-off-by: Jakub Sitnicki <jakub@cloudflare.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Link: https://patch.msgid.link/20240808-udp-gso-egress-from-tunnel-v4-1-f5c5b4149ab9@cloudflare.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -9751,6 +9751,15 @@ static void netdev_sync_lower_features(s
+ }
+ }
+
++static bool netdev_has_ip_or_hw_csum(netdev_features_t features)
++{
++ netdev_features_t ip_csum_mask = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
++ bool ip_csum = (features & ip_csum_mask) == ip_csum_mask;
++ bool hw_csum = features & NETIF_F_HW_CSUM;
++
++ return ip_csum || hw_csum;
++}
++
+ static netdev_features_t netdev_fix_features(struct net_device *dev,
+ netdev_features_t features)
+ {
+@@ -9832,15 +9841,9 @@ static netdev_features_t netdev_fix_feat
+ features &= ~NETIF_F_LRO;
+ }
+
+- if (features & NETIF_F_HW_TLS_TX) {
+- bool ip_csum = (features & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM)) ==
+- (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
+- bool hw_csum = features & NETIF_F_HW_CSUM;
+-
+- if (!ip_csum && !hw_csum) {
+- netdev_dbg(dev, "Dropping TLS TX HW offload feature since no CSUM feature.\n");
+- features &= ~NETIF_F_HW_TLS_TX;
+- }
++ if ((features & NETIF_F_HW_TLS_TX) && !netdev_has_ip_or_hw_csum(features)) {
++ netdev_dbg(dev, "Dropping TLS TX HW offload feature since no CSUM feature.\n");
++ features &= ~NETIF_F_HW_TLS_TX;
+ }
+
+ if ((features & NETIF_F_HW_TLS_RX) && !(features & NETIF_F_RXCSUM)) {
+@@ -9848,6 +9851,11 @@ static netdev_features_t netdev_fix_feat
+ features &= ~NETIF_F_HW_TLS_RX;
+ }
+
++ if ((features & NETIF_F_GSO_UDP_L4) && !netdev_has_ip_or_hw_csum(features)) {
++ netdev_dbg(dev, "Dropping USO feature since no CSUM feature.\n");
++ features &= ~NETIF_F_GSO_UDP_L4;
++ }
++
+ return features;
+ }
+
diff --git a/target/linux/generic/backport-6.6/611-03-v6.11-udp-Fall-back-to-software-USO-if-IPv6-extension-head.patch b/target/linux/generic/backport-6.6/611-03-v6.11-udp-Fall-back-to-software-USO-if-IPv6-extension-head.patch
new file mode 100644
index 0000000000..e8eceb880c
--- /dev/null
+++ b/target/linux/generic/backport-6.6/611-03-v6.11-udp-Fall-back-to-software-USO-if-IPv6-extension-head.patch
@@ -0,0 +1,86 @@
+From: Jakub Sitnicki <jakub@cloudflare.com>
+Date: Thu, 8 Aug 2024 11:56:22 +0200
+Subject: [PATCH] udp: Fall back to software USO if IPv6 extension headers are
+ present
+
+In commit 10154dbded6d ("udp: Allow GSO transmit from devices with no
+checksum offload") we have intentionally allowed UDP GSO packets marked
+CHECKSUM_NONE to pass to the GSO stack, so that they can be segmented and
+checksummed by a software fallback when the egress device lacks these
+features.
+
+What was not taken into consideration is that a CHECKSUM_NONE skb can be
+handed over to the GSO stack also when the egress device advertises the
+tx-udp-segmentation / NETIF_F_GSO_UDP_L4 feature.
+
+This will happen when there are IPv6 extension headers present, which we
+check for in __ip6_append_data(). Syzbot has discovered this scenario,
+producing a warning as below:
+
+ ip6tnl0: caps=(0x00000006401d7869, 0x00000006401d7869)
+ WARNING: CPU: 0 PID: 5112 at net/core/dev.c:3293 skb_warn_bad_offload+0x166/0x1a0 net/core/dev.c:3291
+ Modules linked in:
+ CPU: 0 PID: 5112 Comm: syz-executor391 Not tainted 6.10.0-rc7-syzkaller-01603-g80ab5445da62 #0
+ Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 06/07/2024
+ RIP: 0010:skb_warn_bad_offload+0x166/0x1a0 net/core/dev.c:3291
+ [...]
+ Call Trace:
+ <TASK>
+ __skb_gso_segment+0x3be/0x4c0 net/core/gso.c:127
+ skb_gso_segment include/net/gso.h:83 [inline]
+ validate_xmit_skb+0x585/0x1120 net/core/dev.c:3661
+ __dev_queue_xmit+0x17a4/0x3e90 net/core/dev.c:4415
+ neigh_output include/net/neighbour.h:542 [inline]
+ ip6_finish_output2+0xffa/0x1680 net/ipv6/ip6_output.c:137
+ ip6_finish_output+0x41e/0x810 net/ipv6/ip6_output.c:222
+ ip6_send_skb+0x112/0x230 net/ipv6/ip6_output.c:1958
+ udp_v6_send_skb+0xbf5/0x1870 net/ipv6/udp.c:1292
+ udpv6_sendmsg+0x23b3/0x3270 net/ipv6/udp.c:1588
+ sock_sendmsg_nosec net/socket.c:730 [inline]
+ __sock_sendmsg+0xef/0x270 net/socket.c:745
+ ____sys_sendmsg+0x525/0x7d0 net/socket.c:2585
+ ___sys_sendmsg net/socket.c:2639 [inline]
+ __sys_sendmmsg+0x3b2/0x740 net/socket.c:2725
+ __do_sys_sendmmsg net/socket.c:2754 [inline]
+ __se_sys_sendmmsg net/socket.c:2751 [inline]
+ __x64_sys_sendmmsg+0xa0/0xb0 net/socket.c:2751
+ do_syscall_x64 arch/x86/entry/common.c:52 [inline]
+ do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+ [...]
+ </TASK>
+
+We are hitting the bad offload warning because when an egress device is
+capable of handling segmentation offload requested by
+skb_shinfo(skb)->gso_type, the chain of gso_segment callbacks won't produce
+any segment skbs and return NULL. See the skb_gso_ok() branch in
+{__udp,tcp,sctp}_gso_segment helpers.
+
+To fix it, force a fallback to software USO when processing a packet with
+IPv6 extension headers, since we don't know if these can checksummed by
+all devices which offer USO.
+
+Fixes: 10154dbded6d ("udp: Allow GSO transmit from devices with no checksum offload")
+Reported-by: syzbot+e15b7e15b8a751a91d9a@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/all/000000000000e1609a061d5330ce@google.com/
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Signed-off-by: Jakub Sitnicki <jakub@cloudflare.com>
+Link: https://patch.msgid.link/20240808-udp-gso-egress-from-tunnel-v4-2-f5c5b4149ab9@cloudflare.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+
+--- a/net/ipv4/udp_offload.c
++++ b/net/ipv4/udp_offload.c
+@@ -283,6 +283,12 @@ struct sk_buff *__udp_gso_segment(struct
+ !(skb_shinfo(gso_skb)->gso_type & SKB_GSO_FRAGLIST)))
+ return ERR_PTR(-EINVAL);
+
++ /* We don't know if egress device can segment and checksum the packet
++ * when IPv6 extension headers are present. Fall back to software GSO.
++ */
++ if (gso_skb->ip_summed != CHECKSUM_PARTIAL)
++ features &= ~(NETIF_F_GSO_UDP_L4 | NETIF_F_CSUM_MASK);
++
+ if (skb_gso_ok(gso_skb, features | NETIF_F_GSO_ROBUST)) {
+ /* Packet is from an untrusted source, reset gso_segs. */
+ skb_shinfo(gso_skb)->gso_segs = DIV_ROUND_UP(gso_skb->len - sizeof(*uh),
diff --git a/target/linux/generic/backport-6.6/752-04-v6.6-net-ethernet-mtk_wed-check-update_wo_rx_stats-in-mtk.patch b/target/linux/generic/backport-6.6/752-04-v6.6-net-ethernet-mtk_wed-check-update_wo_rx_stats-in-mtk.patch
deleted file mode 100644
index c99e1334d4..0000000000
--- a/target/linux/generic/backport-6.6/752-04-v6.6-net-ethernet-mtk_wed-check-update_wo_rx_stats-in-mtk.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Tue, 12 Sep 2023 10:28:00 +0200
-Subject: [PATCH] net: ethernet: mtk_wed: check update_wo_rx_stats in
- mtk_wed_update_rx_stats()
-
-Check if update_wo_rx_stats function pointer is properly set in
-mtk_wed_update_rx_stats routine before accessing it.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Reviewed-by: Simon Horman <horms@kernel.org>
-Link: https://lore.kernel.org/r/b0d233386e059bccb59f18f69afb79a7806e5ded.1694507226.git.lorenzo@kernel.org
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
-@@ -68,6 +68,9 @@ mtk_wed_update_rx_stats(struct mtk_wed_d
- struct mtk_wed_wo_rx_stats *stats;
- int i;
-
-+ if (!wed->wlan.update_wo_rx_stats)
-+ return;
-+
- if (count * sizeof(*stats) > skb->len - sizeof(u32))
- return;
-
diff --git a/target/linux/generic/backport-6.6/752-06-v6.7-net-ethernet-mtk_wed-introduce-versioning-utility-ro.patch b/target/linux/generic/backport-6.6/752-06-v6.7-net-ethernet-mtk_wed-introduce-versioning-utility-ro.patch
index 6d1d9a4069..323bc14c3e 100644
--- a/target/linux/generic/backport-6.6/752-06-v6.7-net-ethernet-mtk_wed-introduce-versioning-utility-ro.patch
+++ b/target/linux/generic/backport-6.6/752-06-v6.7-net-ethernet-mtk_wed-introduce-versioning-utility-ro.patch
@@ -168,7 +168,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
ext_mask |= MTK_WED_EXT_INT_STATUS_TX_DRV_R_RESP_ERR;
else
ext_mask |= MTK_WED_EXT_INT_STATUS_RX_FBUF_LO_TH |
-@@ -1840,7 +1840,7 @@ mtk_wed_setup_tc(struct mtk_wed_device *
+@@ -1842,7 +1842,7 @@ mtk_wed_setup_tc(struct mtk_wed_device *
{
struct mtk_wed_hw *hw = wed->hw;
@@ -177,7 +177,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
return -EOPNOTSUPP;
switch (type) {
-@@ -1914,9 +1914,9 @@ void mtk_wed_add_hw(struct device_node *
+@@ -1916,9 +1916,9 @@ void mtk_wed_add_hw(struct device_node *
hw->wdma = wdma;
hw->index = index;
hw->irq = irq;
diff --git a/target/linux/generic/backport-6.6/752-13-v6.7-net-ethernet-mtk_wed-add-mtk_wed_soc_data-structure.patch b/target/linux/generic/backport-6.6/752-13-v6.7-net-ethernet-mtk_wed-add-mtk_wed_soc_data-structure.patch
index 3e750ec1d4..6e2f8b1920 100644
--- a/target/linux/generic/backport-6.6/752-13-v6.7-net-ethernet-mtk_wed-add-mtk_wed_soc_data-structure.patch
+++ b/target/linux/generic/backport-6.6/752-13-v6.7-net-ethernet-mtk_wed-add-mtk_wed_soc_data-structure.patch
@@ -142,7 +142,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
return -ENOMEM;
wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_BASE,
-@@ -1928,7 +1935,12 @@ void mtk_wed_add_hw(struct device_node *
+@@ -1930,7 +1937,12 @@ void mtk_wed_add_hw(struct device_node *
hw->irq = irq;
hw->version = eth->soc->version;
@@ -156,7 +156,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
hw->mirror = syscon_regmap_lookup_by_phandle(eth_np,
"mediatek,pcie-mirror");
hw->hifsys = syscon_regmap_lookup_by_phandle(eth_np,
-@@ -1942,6 +1954,8 @@ void mtk_wed_add_hw(struct device_node *
+@@ -1944,6 +1956,8 @@ void mtk_wed_add_hw(struct device_node *
regmap_write(hw->mirror, 0, 0);
regmap_write(hw->mirror, 4, 0);
}
diff --git a/target/linux/generic/backport-6.6/752-14-v6.7-net-ethernet-mtk_wed-introduce-WED-support-for-MT798.patch b/target/linux/generic/backport-6.6/752-14-v6.7-net-ethernet-mtk_wed-introduce-WED-support-for-MT798.patch
index 5a271a5628..f565b7631f 100644
--- a/target/linux/generic/backport-6.6/752-14-v6.7-net-ethernet-mtk_wed-introduce-WED-support-for-MT798.patch
+++ b/target/linux/generic/backport-6.6/752-14-v6.7-net-ethernet-mtk_wed-introduce-WED-support-for-MT798.patch
@@ -759,7 +759,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
val = wed_r32(dev, MTK_WED_EXT_INT_STATUS);
wed_w32(dev, MTK_WED_EXT_INT_STATUS, val);
-@@ -1939,6 +2130,9 @@ void mtk_wed_add_hw(struct device_node *
+@@ -1941,6 +2132,9 @@ void mtk_wed_add_hw(struct device_node *
case 2:
hw->soc = &mt7986_data;
break;
diff --git a/target/linux/generic/backport-6.6/752-17-v6.7-net-ethernet-mtk_wed-introduce-hw_rro-support-for-MT.patch b/target/linux/generic/backport-6.6/752-17-v6.7-net-ethernet-mtk_wed-introduce-hw_rro-support-for-MT.patch
index f035f8fc06..20befcc620 100644
--- a/target/linux/generic/backport-6.6/752-17-v6.7-net-ethernet-mtk_wed-introduce-hw_rro-support-for-MT.patch
+++ b/target/linux/generic/backport-6.6/752-17-v6.7-net-ethernet-mtk_wed-introduce-hw_rro-support-for-MT.patch
@@ -364,7 +364,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
mtk_wed_start(struct mtk_wed_device *dev, u32 irq_mask)
{
int i;
-@@ -2212,6 +2503,10 @@ void mtk_wed_add_hw(struct device_node *
+@@ -2214,6 +2505,10 @@ void mtk_wed_add_hw(struct device_node *
.detach = mtk_wed_detach,
.ppe_check = mtk_wed_ppe_check,
.setup_tc = mtk_wed_setup_tc,
diff --git a/target/linux/generic/backport-6.6/780-01-v6.8-r8169-add-support-for-LED-s-on-RTL8168-RTL8101.patch b/target/linux/generic/backport-6.6/780-01-v6.8-r8169-add-support-for-LED-s-on-RTL8168-RTL8101.patch
deleted file mode 100644
index 3345ebf6c6..0000000000
--- a/target/linux/generic/backport-6.6/780-01-v6.8-r8169-add-support-for-LED-s-on-RTL8168-RTL8101.patch
+++ /dev/null
@@ -1,319 +0,0 @@
-From 18764b883e157e28126b54e7d4ba9dd487d5bf54 Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Sat, 16 Dec 2023 20:58:10 +0100
-Subject: [PATCH] r8169: add support for LED's on RTL8168/RTL8101
-
-This adds support for the LED's on most chip versions. Excluded are
-the old non-PCIe versions and RTL8125. RTL8125 has a different LED
-register layout, support for it will follow later.
-
-LED's can be controlled from userspace using the netdev LED trigger.
-
-Tested on RTL8168h.
-
-Note: The driver can't know which LED's are actually physically
-wired. Therefore not every LED device may represent a physically
-available LED.
-
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/realtek/Makefile | 3 +
- drivers/net/ethernet/realtek/r8169.h | 7 +
- drivers/net/ethernet/realtek/r8169_leds.c | 157 ++++++++++++++++++++++
- drivers/net/ethernet/realtek/r8169_main.c | 65 +++++++++
- 4 files changed, 232 insertions(+)
- create mode 100644 drivers/net/ethernet/realtek/r8169_leds.c
-
---- a/drivers/net/ethernet/realtek/Makefile
-+++ b/drivers/net/ethernet/realtek/Makefile
-@@ -7,4 +7,7 @@ obj-$(CONFIG_8139CP) += 8139cp.o
- obj-$(CONFIG_8139TOO) += 8139too.o
- obj-$(CONFIG_ATP) += atp.o
- r8169-objs += r8169_main.o r8169_firmware.o r8169_phy_config.o
-+ifdef CONFIG_LEDS_TRIGGER_NETDEV
-+r8169-objs += r8169_leds.o
-+endif
- obj-$(CONFIG_R8169) += r8169.o
---- a/drivers/net/ethernet/realtek/r8169.h
-+++ b/drivers/net/ethernet/realtek/r8169.h
-@@ -8,6 +8,7 @@
- * See MAINTAINERS file for support contact information.
- */
-
-+#include <linux/netdevice.h>
- #include <linux/types.h>
- #include <linux/phy.h>
-
-@@ -77,3 +78,9 @@ u16 rtl8168h_2_get_adc_bias_ioffset(stru
- u8 rtl8168d_efuse_read(struct rtl8169_private *tp, int reg_addr);
- void r8169_hw_phy_config(struct rtl8169_private *tp, struct phy_device *phydev,
- enum mac_version ver);
-+
-+void r8169_get_led_name(struct rtl8169_private *tp, int idx,
-+ char *buf, int buf_len);
-+int rtl8168_get_led_mode(struct rtl8169_private *tp);
-+int rtl8168_led_mod_ctrl(struct rtl8169_private *tp, u16 mask, u16 val);
-+void rtl8168_init_leds(struct net_device *ndev);
---- /dev/null
-+++ b/drivers/net/ethernet/realtek/r8169_leds.c
-@@ -0,0 +1,157 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/* r8169_leds.c: Realtek 8169/8168/8101/8125 ethernet driver.
-+ *
-+ * Copyright (c) 2023 Heiner Kallweit <hkallweit1@gmail.com>
-+ *
-+ * See MAINTAINERS file for support contact information.
-+ */
-+
-+#include <linux/leds.h>
-+#include <linux/netdevice.h>
-+#include <uapi/linux/uleds.h>
-+
-+#include "r8169.h"
-+
-+#define RTL8168_LED_CTRL_OPTION2 BIT(15)
-+#define RTL8168_LED_CTRL_ACT BIT(3)
-+#define RTL8168_LED_CTRL_LINK_1000 BIT(2)
-+#define RTL8168_LED_CTRL_LINK_100 BIT(1)
-+#define RTL8168_LED_CTRL_LINK_10 BIT(0)
-+
-+#define RTL8168_NUM_LEDS 3
-+
-+#define RTL8168_SUPPORTED_MODES \
-+ (BIT(TRIGGER_NETDEV_LINK_1000) | BIT(TRIGGER_NETDEV_LINK_100) | \
-+ BIT(TRIGGER_NETDEV_LINK_10) | BIT(TRIGGER_NETDEV_RX) | \
-+ BIT(TRIGGER_NETDEV_TX))
-+
-+struct r8169_led_classdev {
-+ struct led_classdev led;
-+ struct net_device *ndev;
-+ int index;
-+};
-+
-+#define lcdev_to_r8169_ldev(lcdev) container_of(lcdev, struct r8169_led_classdev, led)
-+
-+static int rtl8168_led_hw_control_is_supported(struct led_classdev *led_cdev,
-+ unsigned long flags)
-+{
-+ struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev);
-+ struct rtl8169_private *tp = netdev_priv(ldev->ndev);
-+ int shift = ldev->index * 4;
-+ bool rx, tx;
-+
-+ if (flags & ~RTL8168_SUPPORTED_MODES)
-+ goto nosupp;
-+
-+ rx = flags & BIT(TRIGGER_NETDEV_RX);
-+ tx = flags & BIT(TRIGGER_NETDEV_TX);
-+ if (rx != tx)
-+ goto nosupp;
-+
-+ return 0;
-+
-+nosupp:
-+ /* Switch LED off to indicate that mode isn't supported */
-+ rtl8168_led_mod_ctrl(tp, 0x000f << shift, 0);
-+ return -EOPNOTSUPP;
-+}
-+
-+static int rtl8168_led_hw_control_set(struct led_classdev *led_cdev,
-+ unsigned long flags)
-+{
-+ struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev);
-+ struct rtl8169_private *tp = netdev_priv(ldev->ndev);
-+ int shift = ldev->index * 4;
-+ u16 mode = 0;
-+
-+ if (flags & BIT(TRIGGER_NETDEV_LINK_10))
-+ mode |= RTL8168_LED_CTRL_LINK_10;
-+ if (flags & BIT(TRIGGER_NETDEV_LINK_100))
-+ mode |= RTL8168_LED_CTRL_LINK_100;
-+ if (flags & BIT(TRIGGER_NETDEV_LINK_1000))
-+ mode |= RTL8168_LED_CTRL_LINK_1000;
-+ if (flags & BIT(TRIGGER_NETDEV_TX))
-+ mode |= RTL8168_LED_CTRL_ACT;
-+
-+ return rtl8168_led_mod_ctrl(tp, 0x000f << shift, mode << shift);
-+}
-+
-+static int rtl8168_led_hw_control_get(struct led_classdev *led_cdev,
-+ unsigned long *flags)
-+{
-+ struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev);
-+ struct rtl8169_private *tp = netdev_priv(ldev->ndev);
-+ int shift = ldev->index * 4;
-+ int mode;
-+
-+ mode = rtl8168_get_led_mode(tp);
-+ if (mode < 0)
-+ return mode;
-+
-+ if (mode & RTL8168_LED_CTRL_OPTION2) {
-+ rtl8168_led_mod_ctrl(tp, RTL8168_LED_CTRL_OPTION2, 0);
-+ netdev_notice(ldev->ndev, "Deactivating unsupported Option2 LED mode\n");
-+ }
-+
-+ mode = (mode >> shift) & 0x000f;
-+
-+ if (mode & RTL8168_LED_CTRL_ACT)
-+ *flags |= BIT(TRIGGER_NETDEV_TX) | BIT(TRIGGER_NETDEV_RX);
-+
-+ if (mode & RTL8168_LED_CTRL_LINK_10)
-+ *flags |= BIT(TRIGGER_NETDEV_LINK_10);
-+ if (mode & RTL8168_LED_CTRL_LINK_100)
-+ *flags |= BIT(TRIGGER_NETDEV_LINK_100);
-+ if (mode & RTL8168_LED_CTRL_LINK_1000)
-+ *flags |= BIT(TRIGGER_NETDEV_LINK_1000);
-+
-+ return 0;
-+}
-+
-+static struct device *
-+ r8169_led_hw_control_get_device(struct led_classdev *led_cdev)
-+{
-+ struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev);
-+
-+ return &ldev->ndev->dev;
-+}
-+
-+static void rtl8168_setup_ldev(struct r8169_led_classdev *ldev,
-+ struct net_device *ndev, int index)
-+{
-+ struct rtl8169_private *tp = netdev_priv(ndev);
-+ struct led_classdev *led_cdev = &ldev->led;
-+ char led_name[LED_MAX_NAME_SIZE];
-+
-+ ldev->ndev = ndev;
-+ ldev->index = index;
-+
-+ r8169_get_led_name(tp, index, led_name, LED_MAX_NAME_SIZE);
-+ led_cdev->name = led_name;
-+ led_cdev->default_trigger = "netdev";
-+ led_cdev->hw_control_trigger = "netdev";
-+ led_cdev->flags |= LED_RETAIN_AT_SHUTDOWN;
-+ led_cdev->hw_control_is_supported = rtl8168_led_hw_control_is_supported;
-+ led_cdev->hw_control_set = rtl8168_led_hw_control_set;
-+ led_cdev->hw_control_get = rtl8168_led_hw_control_get;
-+ led_cdev->hw_control_get_device = r8169_led_hw_control_get_device;
-+
-+ /* ignore errors */
-+ devm_led_classdev_register(&ndev->dev, led_cdev);
-+}
-+
-+void rtl8168_init_leds(struct net_device *ndev)
-+{
-+ /* bind resource mgmt to netdev */
-+ struct device *dev = &ndev->dev;
-+ struct r8169_led_classdev *leds;
-+ int i;
-+
-+ leds = devm_kcalloc(dev, RTL8168_NUM_LEDS, sizeof(*leds), GFP_KERNEL);
-+ if (!leds)
-+ return;
-+
-+ for (i = 0; i < RTL8168_NUM_LEDS; i++)
-+ rtl8168_setup_ldev(leds + i, ndev, i);
-+}
---- a/drivers/net/ethernet/realtek/r8169_main.c
-+++ b/drivers/net/ethernet/realtek/r8169_main.c
-@@ -289,6 +289,7 @@ enum rtl8168_8101_registers {
- };
-
- enum rtl8168_registers {
-+ LED_CTRL = 0x18,
- LED_FREQ = 0x1a,
- EEE_LED = 0x1b,
- ERIDR = 0x70,
-@@ -620,6 +621,7 @@ struct rtl8169_private {
-
- raw_spinlock_t config25_lock;
- raw_spinlock_t mac_ocp_lock;
-+ struct mutex led_lock; /* serialize LED ctrl RMW access */
-
- raw_spinlock_t cfg9346_usage_lock;
- int cfg9346_usage_count;
-@@ -792,6 +794,62 @@ static const struct rtl_cond name = {
- \
- static bool name ## _check(struct rtl8169_private *tp)
-
-+int rtl8168_led_mod_ctrl(struct rtl8169_private *tp, u16 mask, u16 val)
-+{
-+ struct device *dev = tp_to_dev(tp);
-+ int ret;
-+
-+ ret = pm_runtime_resume_and_get(dev);
-+ if (ret < 0)
-+ return ret;
-+
-+ mutex_lock(&tp->led_lock);
-+ RTL_W16(tp, LED_CTRL, (RTL_R16(tp, LED_CTRL) & ~mask) | val);
-+ mutex_unlock(&tp->led_lock);
-+
-+ pm_runtime_put_sync(dev);
-+
-+ return 0;
-+}
-+
-+int rtl8168_get_led_mode(struct rtl8169_private *tp)
-+{
-+ struct device *dev = tp_to_dev(tp);
-+ int ret;
-+
-+ ret = pm_runtime_resume_and_get(dev);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = RTL_R16(tp, LED_CTRL);
-+
-+ pm_runtime_put_sync(dev);
-+
-+ return ret;
-+}
-+
-+void r8169_get_led_name(struct rtl8169_private *tp, int idx,
-+ char *buf, int buf_len)
-+{
-+ struct pci_dev *pdev = tp->pci_dev;
-+ char pdom[8], pfun[8];
-+ int domain;
-+
-+ domain = pci_domain_nr(pdev->bus);
-+ if (domain)
-+ snprintf(pdom, sizeof(pdom), "P%d", domain);
-+ else
-+ pdom[0] = '\0';
-+
-+ if (pdev->multifunction)
-+ snprintf(pfun, sizeof(pfun), "f%d", PCI_FUNC(pdev->devfn));
-+ else
-+ pfun[0] = '\0';
-+
-+ snprintf(buf, buf_len, "en%sp%ds%d%s-%d::lan", pdom, pdev->bus->number,
-+ PCI_SLOT(pdev->devfn), pfun, idx);
-+}
-+
- static void r8168fp_adjust_ocp_cmd(struct rtl8169_private *tp, u32 *cmd, int type)
- {
- /* based on RTL8168FP_OOBMAC_BASE in vendor driver */
-@@ -5258,6 +5316,7 @@ static int rtl_init_one(struct pci_dev *
- raw_spin_lock_init(&tp->cfg9346_usage_lock);
- raw_spin_lock_init(&tp->config25_lock);
- raw_spin_lock_init(&tp->mac_ocp_lock);
-+ mutex_init(&tp->led_lock);
-
- dev->tstats = devm_netdev_alloc_pcpu_stats(&pdev->dev,
- struct pcpu_sw_netstats);
-@@ -5414,6 +5473,12 @@ static int rtl_init_one(struct pci_dev *
- if (rc)
- return rc;
-
-+#if IS_REACHABLE(CONFIG_LEDS_CLASS) && IS_ENABLED(CONFIG_LEDS_TRIGGER_NETDEV)
-+ if (tp->mac_version > RTL_GIGA_MAC_VER_06 &&
-+ tp->mac_version < RTL_GIGA_MAC_VER_61)
-+ rtl8168_init_leds(dev);
-+#endif
-+
- netdev_info(dev, "%s, %pM, XID %03x, IRQ %d\n",
- rtl_chip_infos[chipset].name, dev->dev_addr, xid, tp->irq);
-
diff --git a/target/linux/generic/backport-6.6/780-01-v6.8-r8169-improve-RTL8411b-phy-down-fixup.patch b/target/linux/generic/backport-6.6/780-01-v6.8-r8169-improve-RTL8411b-phy-down-fixup.patch
new file mode 100644
index 0000000000..9a17fe4f78
--- /dev/null
+++ b/target/linux/generic/backport-6.6/780-01-v6.8-r8169-improve-RTL8411b-phy-down-fixup.patch
@@ -0,0 +1,173 @@
+From 055dd7511f675d26fa283b35bb3dadfc7f77ed97 Mon Sep 17 00:00:00 2001
+From: Heiner Kallweit <hkallweit1@gmail.com>
+Date: Mon, 13 Nov 2023 20:13:26 +0100
+Subject: [PATCH] r8169: improve RTL8411b phy-down fixup
+
+Mirsad proposed a patch to reduce the number of spinlock lock/unlock
+operations and the function code size. This can be further improved
+because the function sets a consecutive register block.
+
+Suggested-by: Mirsad Todorovac <mirsad.todorovac@alu.unizg.hr>
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Reviewed-by: Mirsad Todorovac <mirsad.todorovac@alu.unizg.hr>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/realtek/r8169_main.c | 139 +++++-----------------
+ 1 file changed, 28 insertions(+), 111 deletions(-)
+
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -3129,6 +3129,33 @@ static void rtl_hw_start_8168g_2(struct
+ rtl_ephy_init(tp, e_info_8168g_2);
+ }
+
++static void rtl8411b_fix_phy_down(struct rtl8169_private *tp)
++{
++ static const u16 fix_data[] = {
++/* 0xf800 */ 0xe008, 0xe00a, 0xe00c, 0xe00e, 0xe027, 0xe04f, 0xe05e, 0xe065,
++/* 0xf810 */ 0xc602, 0xbe00, 0x0000, 0xc502, 0xbd00, 0x074c, 0xc302, 0xbb00,
++/* 0xf820 */ 0x080a, 0x6420, 0x48c2, 0x8c20, 0xc516, 0x64a4, 0x49c0, 0xf009,
++/* 0xf830 */ 0x74a2, 0x8ca5, 0x74a0, 0xc50e, 0x9ca2, 0x1c11, 0x9ca0, 0xe006,
++/* 0xf840 */ 0x74f8, 0x48c4, 0x8cf8, 0xc404, 0xbc00, 0xc403, 0xbc00, 0x0bf2,
++/* 0xf850 */ 0x0c0a, 0xe434, 0xd3c0, 0x49d9, 0xf01f, 0xc526, 0x64a5, 0x1400,
++/* 0xf860 */ 0xf007, 0x0c01, 0x8ca5, 0x1c15, 0xc51b, 0x9ca0, 0xe013, 0xc519,
++/* 0xf870 */ 0x74a0, 0x48c4, 0x8ca0, 0xc516, 0x74a4, 0x48c8, 0x48ca, 0x9ca4,
++/* 0xf880 */ 0xc512, 0x1b00, 0x9ba0, 0x1b1c, 0x483f, 0x9ba2, 0x1b04, 0xc508,
++/* 0xf890 */ 0x9ba0, 0xc505, 0xbd00, 0xc502, 0xbd00, 0x0300, 0x051e, 0xe434,
++/* 0xf8a0 */ 0xe018, 0xe092, 0xde20, 0xd3c0, 0xc50f, 0x76a4, 0x49e3, 0xf007,
++/* 0xf8b0 */ 0x49c0, 0xf103, 0xc607, 0xbe00, 0xc606, 0xbe00, 0xc602, 0xbe00,
++/* 0xf8c0 */ 0x0c4c, 0x0c28, 0x0c2c, 0xdc00, 0xc707, 0x1d00, 0x8de2, 0x48c1,
++/* 0xf8d0 */ 0xc502, 0xbd00, 0x00aa, 0xe0c0, 0xc502, 0xbd00, 0x0132
++ };
++ unsigned long flags;
++ int i;
++
++ raw_spin_lock_irqsave(&tp->mac_ocp_lock, flags);
++ for (i = 0; i < ARRAY_SIZE(fix_data); i++)
++ __r8168_mac_ocp_write(tp, 0xf800 + 2 * i, fix_data[i]);
++ raw_spin_unlock_irqrestore(&tp->mac_ocp_lock, flags);
++}
++
+ static void rtl_hw_start_8411_2(struct rtl8169_private *tp)
+ {
+ static const struct ephy_info e_info_8411_2[] = {
+@@ -3162,117 +3189,7 @@ static void rtl_hw_start_8411_2(struct r
+ mdelay(3);
+ r8168_mac_ocp_write(tp, 0xFC26, 0x0000);
+
+- r8168_mac_ocp_write(tp, 0xF800, 0xE008);
+- r8168_mac_ocp_write(tp, 0xF802, 0xE00A);
+- r8168_mac_ocp_write(tp, 0xF804, 0xE00C);
+- r8168_mac_ocp_write(tp, 0xF806, 0xE00E);
+- r8168_mac_ocp_write(tp, 0xF808, 0xE027);
+- r8168_mac_ocp_write(tp, 0xF80A, 0xE04F);
+- r8168_mac_ocp_write(tp, 0xF80C, 0xE05E);
+- r8168_mac_ocp_write(tp, 0xF80E, 0xE065);
+- r8168_mac_ocp_write(tp, 0xF810, 0xC602);
+- r8168_mac_ocp_write(tp, 0xF812, 0xBE00);
+- r8168_mac_ocp_write(tp, 0xF814, 0x0000);
+- r8168_mac_ocp_write(tp, 0xF816, 0xC502);
+- r8168_mac_ocp_write(tp, 0xF818, 0xBD00);
+- r8168_mac_ocp_write(tp, 0xF81A, 0x074C);
+- r8168_mac_ocp_write(tp, 0xF81C, 0xC302);
+- r8168_mac_ocp_write(tp, 0xF81E, 0xBB00);
+- r8168_mac_ocp_write(tp, 0xF820, 0x080A);
+- r8168_mac_ocp_write(tp, 0xF822, 0x6420);
+- r8168_mac_ocp_write(tp, 0xF824, 0x48C2);
+- r8168_mac_ocp_write(tp, 0xF826, 0x8C20);
+- r8168_mac_ocp_write(tp, 0xF828, 0xC516);
+- r8168_mac_ocp_write(tp, 0xF82A, 0x64A4);
+- r8168_mac_ocp_write(tp, 0xF82C, 0x49C0);
+- r8168_mac_ocp_write(tp, 0xF82E, 0xF009);
+- r8168_mac_ocp_write(tp, 0xF830, 0x74A2);
+- r8168_mac_ocp_write(tp, 0xF832, 0x8CA5);
+- r8168_mac_ocp_write(tp, 0xF834, 0x74A0);
+- r8168_mac_ocp_write(tp, 0xF836, 0xC50E);
+- r8168_mac_ocp_write(tp, 0xF838, 0x9CA2);
+- r8168_mac_ocp_write(tp, 0xF83A, 0x1C11);
+- r8168_mac_ocp_write(tp, 0xF83C, 0x9CA0);
+- r8168_mac_ocp_write(tp, 0xF83E, 0xE006);
+- r8168_mac_ocp_write(tp, 0xF840, 0x74F8);
+- r8168_mac_ocp_write(tp, 0xF842, 0x48C4);
+- r8168_mac_ocp_write(tp, 0xF844, 0x8CF8);
+- r8168_mac_ocp_write(tp, 0xF846, 0xC404);
+- r8168_mac_ocp_write(tp, 0xF848, 0xBC00);
+- r8168_mac_ocp_write(tp, 0xF84A, 0xC403);
+- r8168_mac_ocp_write(tp, 0xF84C, 0xBC00);
+- r8168_mac_ocp_write(tp, 0xF84E, 0x0BF2);
+- r8168_mac_ocp_write(tp, 0xF850, 0x0C0A);
+- r8168_mac_ocp_write(tp, 0xF852, 0xE434);
+- r8168_mac_ocp_write(tp, 0xF854, 0xD3C0);
+- r8168_mac_ocp_write(tp, 0xF856, 0x49D9);
+- r8168_mac_ocp_write(tp, 0xF858, 0xF01F);
+- r8168_mac_ocp_write(tp, 0xF85A, 0xC526);
+- r8168_mac_ocp_write(tp, 0xF85C, 0x64A5);
+- r8168_mac_ocp_write(tp, 0xF85E, 0x1400);
+- r8168_mac_ocp_write(tp, 0xF860, 0xF007);
+- r8168_mac_ocp_write(tp, 0xF862, 0x0C01);
+- r8168_mac_ocp_write(tp, 0xF864, 0x8CA5);
+- r8168_mac_ocp_write(tp, 0xF866, 0x1C15);
+- r8168_mac_ocp_write(tp, 0xF868, 0xC51B);
+- r8168_mac_ocp_write(tp, 0xF86A, 0x9CA0);
+- r8168_mac_ocp_write(tp, 0xF86C, 0xE013);
+- r8168_mac_ocp_write(tp, 0xF86E, 0xC519);
+- r8168_mac_ocp_write(tp, 0xF870, 0x74A0);
+- r8168_mac_ocp_write(tp, 0xF872, 0x48C4);
+- r8168_mac_ocp_write(tp, 0xF874, 0x8CA0);
+- r8168_mac_ocp_write(tp, 0xF876, 0xC516);
+- r8168_mac_ocp_write(tp, 0xF878, 0x74A4);
+- r8168_mac_ocp_write(tp, 0xF87A, 0x48C8);
+- r8168_mac_ocp_write(tp, 0xF87C, 0x48CA);
+- r8168_mac_ocp_write(tp, 0xF87E, 0x9CA4);
+- r8168_mac_ocp_write(tp, 0xF880, 0xC512);
+- r8168_mac_ocp_write(tp, 0xF882, 0x1B00);
+- r8168_mac_ocp_write(tp, 0xF884, 0x9BA0);
+- r8168_mac_ocp_write(tp, 0xF886, 0x1B1C);
+- r8168_mac_ocp_write(tp, 0xF888, 0x483F);
+- r8168_mac_ocp_write(tp, 0xF88A, 0x9BA2);
+- r8168_mac_ocp_write(tp, 0xF88C, 0x1B04);
+- r8168_mac_ocp_write(tp, 0xF88E, 0xC508);
+- r8168_mac_ocp_write(tp, 0xF890, 0x9BA0);
+- r8168_mac_ocp_write(tp, 0xF892, 0xC505);
+- r8168_mac_ocp_write(tp, 0xF894, 0xBD00);
+- r8168_mac_ocp_write(tp, 0xF896, 0xC502);
+- r8168_mac_ocp_write(tp, 0xF898, 0xBD00);
+- r8168_mac_ocp_write(tp, 0xF89A, 0x0300);
+- r8168_mac_ocp_write(tp, 0xF89C, 0x051E);
+- r8168_mac_ocp_write(tp, 0xF89E, 0xE434);
+- r8168_mac_ocp_write(tp, 0xF8A0, 0xE018);
+- r8168_mac_ocp_write(tp, 0xF8A2, 0xE092);
+- r8168_mac_ocp_write(tp, 0xF8A4, 0xDE20);
+- r8168_mac_ocp_write(tp, 0xF8A6, 0xD3C0);
+- r8168_mac_ocp_write(tp, 0xF8A8, 0xC50F);
+- r8168_mac_ocp_write(tp, 0xF8AA, 0x76A4);
+- r8168_mac_ocp_write(tp, 0xF8AC, 0x49E3);
+- r8168_mac_ocp_write(tp, 0xF8AE, 0xF007);
+- r8168_mac_ocp_write(tp, 0xF8B0, 0x49C0);
+- r8168_mac_ocp_write(tp, 0xF8B2, 0xF103);
+- r8168_mac_ocp_write(tp, 0xF8B4, 0xC607);
+- r8168_mac_ocp_write(tp, 0xF8B6, 0xBE00);
+- r8168_mac_ocp_write(tp, 0xF8B8, 0xC606);
+- r8168_mac_ocp_write(tp, 0xF8BA, 0xBE00);
+- r8168_mac_ocp_write(tp, 0xF8BC, 0xC602);
+- r8168_mac_ocp_write(tp, 0xF8BE, 0xBE00);
+- r8168_mac_ocp_write(tp, 0xF8C0, 0x0C4C);
+- r8168_mac_ocp_write(tp, 0xF8C2, 0x0C28);
+- r8168_mac_ocp_write(tp, 0xF8C4, 0x0C2C);
+- r8168_mac_ocp_write(tp, 0xF8C6, 0xDC00);
+- r8168_mac_ocp_write(tp, 0xF8C8, 0xC707);
+- r8168_mac_ocp_write(tp, 0xF8CA, 0x1D00);
+- r8168_mac_ocp_write(tp, 0xF8CC, 0x8DE2);
+- r8168_mac_ocp_write(tp, 0xF8CE, 0x48C1);
+- r8168_mac_ocp_write(tp, 0xF8D0, 0xC502);
+- r8168_mac_ocp_write(tp, 0xF8D2, 0xBD00);
+- r8168_mac_ocp_write(tp, 0xF8D4, 0x00AA);
+- r8168_mac_ocp_write(tp, 0xF8D6, 0xE0C0);
+- r8168_mac_ocp_write(tp, 0xF8D8, 0xC502);
+- r8168_mac_ocp_write(tp, 0xF8DA, 0xBD00);
+- r8168_mac_ocp_write(tp, 0xF8DC, 0x0132);
++ rtl8411b_fix_phy_down(tp);
+
+ r8168_mac_ocp_write(tp, 0xFC26, 0x8000);
+
diff --git a/target/linux/generic/backport-6.6/780-02-v6.8-r8169-fix-building-with-CONFIG_LEDS_CLASS-m.patch b/target/linux/generic/backport-6.6/780-02-v6.8-r8169-fix-building-with-CONFIG_LEDS_CLASS-m.patch
deleted file mode 100644
index cea88c042a..0000000000
--- a/target/linux/generic/backport-6.6/780-02-v6.8-r8169-fix-building-with-CONFIG_LEDS_CLASS-m.patch
+++ /dev/null
@@ -1,75 +0,0 @@
-From a2634a5ffcafc31c343c6153ae487eb184c433a6 Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Wed, 3 Jan 2024 16:52:04 +0100
-Subject: [PATCH] r8169: fix building with CONFIG_LEDS_CLASS=m
-
-When r8169 is built-in but LED support is a loadable module, the new
-code to drive the LED causes a link failure:
-
-ld: drivers/net/ethernet/realtek/r8169_leds.o: in function `rtl8168_init_leds':
-r8169_leds.c:(.text+0x36c): undefined reference to `devm_led_classdev_register_ext'
-
-LED support is an optional feature, so fix this issue by adding a Kconfig
-symbol R8169_LEDS that is guaranteed to be false if r8169 is built-in
-and LED core support is a module. As a positive side effect of this change
-r8169_leds.o no longer is built under this configuration.
-
-Fixes: 18764b883e15 ("r8169: add support for LED's on RTL8168/RTL8101")
-Reported-by: kernel test robot <lkp@intel.com>
-Closes: https://lore.kernel.org/oe-kbuild-all/202312281159.9TPeXbNd-lkp@intel.com/
-Suggested-by: Arnd Bergmann <arnd@arndb.de>
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Reviewed-by: Simon Horman <horms@kernel.org>
-Tested-by: Simon Horman <horms@kernel.org> # build-tested
-Tested-by: Arnd Bergmann <arnd@arndb.de>
-Link: https://lore.kernel.org/r/d055aeb5-fe5c-4ccf-987f-5af93a17537b@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/realtek/Kconfig | 7 +++++++
- drivers/net/ethernet/realtek/Makefile | 6 ++----
- drivers/net/ethernet/realtek/r8169_main.c | 5 ++---
- 3 files changed, 11 insertions(+), 7 deletions(-)
-
---- a/drivers/net/ethernet/realtek/Kconfig
-+++ b/drivers/net/ethernet/realtek/Kconfig
-@@ -113,4 +113,11 @@ config R8169
- To compile this driver as a module, choose M here: the module
- will be called r8169. This is recommended.
-
-+config R8169_LEDS
-+ def_bool R8169 && LEDS_TRIGGER_NETDEV
-+ depends on !(R8169=y && LEDS_CLASS=m)
-+ help
-+ Optional support for controlling the NIC LED's with the netdev
-+ LED trigger.
-+
- endif # NET_VENDOR_REALTEK
---- a/drivers/net/ethernet/realtek/Makefile
-+++ b/drivers/net/ethernet/realtek/Makefile
-@@ -6,8 +6,6 @@
- obj-$(CONFIG_8139CP) += 8139cp.o
- obj-$(CONFIG_8139TOO) += 8139too.o
- obj-$(CONFIG_ATP) += atp.o
--r8169-objs += r8169_main.o r8169_firmware.o r8169_phy_config.o
--ifdef CONFIG_LEDS_TRIGGER_NETDEV
--r8169-objs += r8169_leds.o
--endif
-+r8169-y += r8169_main.o r8169_firmware.o r8169_phy_config.o
-+r8169-$(CONFIG_R8169_LEDS) += r8169_leds.o
- obj-$(CONFIG_R8169) += r8169.o
---- a/drivers/net/ethernet/realtek/r8169_main.c
-+++ b/drivers/net/ethernet/realtek/r8169_main.c
-@@ -5473,11 +5473,10 @@ static int rtl_init_one(struct pci_dev *
- if (rc)
- return rc;
-
--#if IS_REACHABLE(CONFIG_LEDS_CLASS) && IS_ENABLED(CONFIG_LEDS_TRIGGER_NETDEV)
-- if (tp->mac_version > RTL_GIGA_MAC_VER_06 &&
-+ if (IS_ENABLED(CONFIG_R8169_LEDS) &&
-+ tp->mac_version > RTL_GIGA_MAC_VER_06 &&
- tp->mac_version < RTL_GIGA_MAC_VER_61)
- rtl8168_init_leds(dev);
--#endif
-
- netdev_info(dev, "%s, %pM, XID %03x, IRQ %d\n",
- rtl_chip_infos[chipset].name, dev->dev_addr, xid, tp->irq);
diff --git a/target/linux/generic/backport-6.6/780-02-v6.8-r8169-remove-not-needed-check-in-rtl_fw_write_firmwa.patch b/target/linux/generic/backport-6.6/780-02-v6.8-r8169-remove-not-needed-check-in-rtl_fw_write_firmwa.patch
new file mode 100644
index 0000000000..de10d30e83
--- /dev/null
+++ b/target/linux/generic/backport-6.6/780-02-v6.8-r8169-remove-not-needed-check-in-rtl_fw_write_firmwa.patch
@@ -0,0 +1,27 @@
+From 3a767b482cacd9bfeac786837fcac419af315995 Mon Sep 17 00:00:00 2001
+From: Heiner Kallweit <hkallweit1@gmail.com>
+Date: Thu, 23 Nov 2023 10:53:26 +0100
+Subject: [PATCH] r8169: remove not needed check in rtl_fw_write_firmware
+
+This check can never be true for a firmware file with a correct format.
+Existing checks in rtl_fw_data_ok() are sufficient, no problems with
+invalid firmware files are known.
+
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/realtek/r8169_firmware.c | 3 ---
+ 1 file changed, 3 deletions(-)
+
+--- a/drivers/net/ethernet/realtek/r8169_firmware.c
++++ b/drivers/net/ethernet/realtek/r8169_firmware.c
+@@ -151,9 +151,6 @@ void rtl_fw_write_firmware(struct rtl816
+ u32 regno = (action & 0x0fff0000) >> 16;
+ enum rtl_fw_opcode opcode = action >> 28;
+
+- if (!action)
+- break;
+-
+ switch (opcode) {
+ case PHY_READ:
+ predata = fw_read(tp, regno);
diff --git a/target/linux/generic/backport-6.6/780-03-v6.8-r8169-remove-multicast-filter-limit.patch b/target/linux/generic/backport-6.6/780-03-v6.8-r8169-remove-multicast-filter-limit.patch
new file mode 100644
index 0000000000..4186e14e17
--- /dev/null
+++ b/target/linux/generic/backport-6.6/780-03-v6.8-r8169-remove-multicast-filter-limit.patch
@@ -0,0 +1,47 @@
+From cd04b44bf055c4cd6bcee2ebfa6932fb20ef369d Mon Sep 17 00:00:00 2001
+From: Heiner Kallweit <hkallweit1@gmail.com>
+Date: Mon, 27 Nov 2023 21:16:10 +0100
+Subject: [PATCH] r8169: remove multicast filter limit
+
+Once upon a time, when r8169 was new, the multicast filter limit code
+was copied from RTL8139 driver. There the filter limit is even
+user-configurable.
+The filtering is hash-based and we don't have perfect filtering.
+Actually the mc filtering on RTL8125 still seems to be the same
+as used on 8390/NE2000. So it's not clear to me which benefit it
+should bring when switching to all-multi mode once a certain number
+of filter bits is set. More the opposite: Filtering out at least
+some unwanted mc traffic is better than no filtering.
+Also the available chip documentation doesn't mention any restriction.
+Therefore remove the filter limit.
+
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Link: https://lore.kernel.org/r/57076c05-3730-40d1-ab9a-5334b263e41a@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/realtek/r8169_main.c | 7 +------
+ 1 file changed, 1 insertion(+), 6 deletions(-)
+
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -56,10 +56,6 @@
+ #define FIRMWARE_8125A_3 "rtl_nic/rtl8125a-3.fw"
+ #define FIRMWARE_8125B_2 "rtl_nic/rtl8125b-2.fw"
+
+-/* Maximum number of multicast addresses to filter (vs. Rx-all-multicast).
+- The RTL chips use a 64 element hash table based on the Ethernet CRC. */
+-#define MC_FILTER_LIMIT 32
+-
+ #define TX_DMA_BURST 7 /* Maximum PCI burst, '7' is unlimited */
+ #define InterFrameGap 0x03 /* 3 means InterFrameGap = the shortest one */
+
+@@ -2626,8 +2622,7 @@ static void rtl_set_rx_mode(struct net_d
+ rx_mode |= AcceptAllPhys;
+ } else if (!(dev->flags & IFF_MULTICAST)) {
+ rx_mode &= ~AcceptMulticast;
+- } else if (netdev_mc_count(dev) > MC_FILTER_LIMIT ||
+- dev->flags & IFF_ALLMULTI ||
++ } else if (dev->flags & IFF_ALLMULTI ||
+ tp->mac_version == RTL_GIGA_MAC_VER_35) {
+ /* accept all multicasts */
+ } else if (netdev_mc_empty(dev)) {
diff --git a/target/linux/generic/backport-6.6/780-03-v6.9-r8169-add-support-for-RTL8126A.patch b/target/linux/generic/backport-6.6/780-03-v6.9-r8169-add-support-for-RTL8126A.patch
deleted file mode 100644
index 5ab160855a..0000000000
--- a/target/linux/generic/backport-6.6/780-03-v6.9-r8169-add-support-for-RTL8126A.patch
+++ /dev/null
@@ -1,355 +0,0 @@
-From 3907f1ffc0ecf466d5c04aadc44c4b9203f3ec9a Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Thu, 1 Feb 2024 22:38:01 +0100
-Subject: [PATCH] r8169: add support for RTL8126A
-
-This adds support for the RTL8126A found on Asus z790 Maximus Formula.
-It was successfully tested w/o the firmware at 1000Mbps. Firmware file
-has been provided by Realtek and submitted to linux-firmware.
-2.5G and 5G modes are untested.
-
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/realtek/r8169.h | 1 +
- drivers/net/ethernet/realtek/r8169_main.c | 105 ++++++++++++++----
- .../net/ethernet/realtek/r8169_phy_config.c | 7 ++
- 3 files changed, 89 insertions(+), 24 deletions(-)
-
---- a/drivers/net/ethernet/realtek/r8169.h
-+++ b/drivers/net/ethernet/realtek/r8169.h
-@@ -68,6 +68,7 @@ enum mac_version {
- /* support for RTL_GIGA_MAC_VER_60 has been removed */
- RTL_GIGA_MAC_VER_61,
- RTL_GIGA_MAC_VER_63,
-+ RTL_GIGA_MAC_VER_65,
- RTL_GIGA_MAC_NONE
- };
-
---- a/drivers/net/ethernet/realtek/r8169_main.c
-+++ b/drivers/net/ethernet/realtek/r8169_main.c
-@@ -55,6 +55,7 @@
- #define FIRMWARE_8107E_2 "rtl_nic/rtl8107e-2.fw"
- #define FIRMWARE_8125A_3 "rtl_nic/rtl8125a-3.fw"
- #define FIRMWARE_8125B_2 "rtl_nic/rtl8125b-2.fw"
-+#define FIRMWARE_8126A_2 "rtl_nic/rtl8126a-2.fw"
-
- /* Maximum number of multicast addresses to filter (vs. Rx-all-multicast).
- The RTL chips use a 64 element hash table based on the Ethernet CRC. */
-@@ -140,6 +141,7 @@ static const struct {
- [RTL_GIGA_MAC_VER_61] = {"RTL8125A", FIRMWARE_8125A_3},
- /* reserve 62 for CFG_METHOD_4 in the vendor driver */
- [RTL_GIGA_MAC_VER_63] = {"RTL8125B", FIRMWARE_8125B_2},
-+ [RTL_GIGA_MAC_VER_65] = {"RTL8126A", FIRMWARE_8126A_2},
- };
-
- static const struct pci_device_id rtl8169_pci_tbl[] = {
-@@ -162,6 +164,7 @@ static const struct pci_device_id rtl816
- { PCI_VENDOR_ID_LINKSYS, 0x1032, PCI_ANY_ID, 0x0024 },
- { 0x0001, 0x8168, PCI_ANY_ID, 0x2410 },
- { PCI_VDEVICE(REALTEK, 0x8125) },
-+ { PCI_VDEVICE(REALTEK, 0x8126) },
- { PCI_VDEVICE(REALTEK, 0x3000) },
- {}
- };
-@@ -331,8 +334,12 @@ enum rtl8168_registers {
- };
-
- enum rtl8125_registers {
-+ INT_CFG0_8125 = 0x34,
-+#define INT_CFG0_ENABLE_8125 BIT(0)
-+#define INT_CFG0_CLKREQEN BIT(3)
- IntrMask_8125 = 0x38,
- IntrStatus_8125 = 0x3c,
-+ INT_CFG1_8125 = 0x7a,
- TxPoll_8125 = 0x90,
- MAC0_BKP = 0x19e0,
- EEE_TXIDLE_TIMER_8125 = 0x6048,
-@@ -1144,7 +1151,7 @@ static void rtl_writephy(struct rtl8169_
- case RTL_GIGA_MAC_VER_31:
- r8168dp_2_mdio_write(tp, location, val);
- break;
-- case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_63:
-+ case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_65:
- r8168g_mdio_write(tp, location, val);
- break;
- default:
-@@ -1159,7 +1166,7 @@ static int rtl_readphy(struct rtl8169_pr
- case RTL_GIGA_MAC_VER_28:
- case RTL_GIGA_MAC_VER_31:
- return r8168dp_2_mdio_read(tp, location);
-- case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_63:
-+ case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_65:
- return r8168g_mdio_read(tp, location);
- default:
- return r8169_mdio_read(tp, location);
-@@ -1368,7 +1375,7 @@ static void rtl_set_d3_pll_down(struct r
- case RTL_GIGA_MAC_VER_25 ... RTL_GIGA_MAC_VER_26:
- case RTL_GIGA_MAC_VER_29 ... RTL_GIGA_MAC_VER_30:
- case RTL_GIGA_MAC_VER_32 ... RTL_GIGA_MAC_VER_37:
-- case RTL_GIGA_MAC_VER_39 ... RTL_GIGA_MAC_VER_63:
-+ case RTL_GIGA_MAC_VER_39 ... RTL_GIGA_MAC_VER_65:
- if (enable)
- RTL_W8(tp, PMCH, RTL_R8(tp, PMCH) & ~D3_NO_PLL_DOWN);
- else
-@@ -1535,7 +1542,7 @@ static void __rtl8169_set_wol(struct rtl
- break;
- case RTL_GIGA_MAC_VER_34:
- case RTL_GIGA_MAC_VER_37:
-- case RTL_GIGA_MAC_VER_39 ... RTL_GIGA_MAC_VER_63:
-+ case RTL_GIGA_MAC_VER_39 ... RTL_GIGA_MAC_VER_65:
- if (wolopts)
- rtl_mod_config2(tp, 0, PME_SIGNAL);
- else
-@@ -2122,6 +2129,9 @@ static enum mac_version rtl8169_get_mac_
- u16 val;
- enum mac_version ver;
- } mac_info[] = {
-+ /* 8126A family. */
-+ { 0x7cf, 0x649, RTL_GIGA_MAC_VER_65 },
-+
- /* 8125B family. */
- { 0x7cf, 0x641, RTL_GIGA_MAC_VER_63 },
-
-@@ -2392,6 +2402,7 @@ static void rtl_init_rxcfg(struct rtl816
- RTL_W32(tp, RxConfig, RX_FETCH_DFLT_8125 | RX_DMA_BURST);
- break;
- case RTL_GIGA_MAC_VER_63:
-+ case RTL_GIGA_MAC_VER_65:
- RTL_W32(tp, RxConfig, RX_FETCH_DFLT_8125 | RX_DMA_BURST |
- RX_PAUSE_SLOT_ON);
- break;
-@@ -2578,7 +2589,7 @@ static void rtl_wait_txrx_fifo_empty(str
- case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_61:
- rtl_loop_wait_high(tp, &rtl_rxtx_empty_cond, 100, 42);
- break;
-- case RTL_GIGA_MAC_VER_63:
-+ case RTL_GIGA_MAC_VER_63 ... RTL_GIGA_MAC_VER_65:
- RTL_W8(tp, ChipCmd, RTL_R8(tp, ChipCmd) | StopReq);
- rtl_loop_wait_high(tp, &rtl_rxtx_empty_cond, 100, 42);
- rtl_loop_wait_high(tp, &rtl_rxtx_empty_cond_2, 100, 42);
-@@ -2822,7 +2833,7 @@ static void rtl_enable_exit_l1(struct rt
- case RTL_GIGA_MAC_VER_37 ... RTL_GIGA_MAC_VER_38:
- rtl_eri_set_bits(tp, 0xd4, 0x0c00);
- break;
-- case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_63:
-+ case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_65:
- r8168_mac_ocp_modify(tp, 0xc0ac, 0, 0x1f80);
- break;
- default:
-@@ -2836,7 +2847,7 @@ static void rtl_disable_exit_l1(struct r
- case RTL_GIGA_MAC_VER_34 ... RTL_GIGA_MAC_VER_38:
- rtl_eri_clear_bits(tp, 0xd4, 0x1f00);
- break;
-- case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_63:
-+ case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_65:
- r8168_mac_ocp_modify(tp, 0xc0ac, 0x1f80, 0);
- break;
- default:
-@@ -2846,6 +2857,8 @@ static void rtl_disable_exit_l1(struct r
-
- static void rtl_hw_aspm_clkreq_enable(struct rtl8169_private *tp, bool enable)
- {
-+ u8 val8;
-+
- if (tp->mac_version < RTL_GIGA_MAC_VER_32)
- return;
-
-@@ -2859,11 +2872,19 @@ static void rtl_hw_aspm_clkreq_enable(st
- return;
-
- rtl_mod_config5(tp, 0, ASPM_en);
-- rtl_mod_config2(tp, 0, ClkReqEn);
-+ switch (tp->mac_version) {
-+ case RTL_GIGA_MAC_VER_65:
-+ val8 = RTL_R8(tp, INT_CFG0_8125) | INT_CFG0_CLKREQEN;
-+ RTL_W8(tp, INT_CFG0_8125, val8);
-+ break;
-+ default:
-+ rtl_mod_config2(tp, 0, ClkReqEn);
-+ break;
-+ }
-
- switch (tp->mac_version) {
- case RTL_GIGA_MAC_VER_46 ... RTL_GIGA_MAC_VER_48:
-- case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_63:
-+ case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_65:
- /* reset ephy tx/rx disable timer */
- r8168_mac_ocp_modify(tp, 0xe094, 0xff00, 0);
- /* chip can trigger L1.2 */
-@@ -2875,14 +2896,22 @@ static void rtl_hw_aspm_clkreq_enable(st
- } else {
- switch (tp->mac_version) {
- case RTL_GIGA_MAC_VER_46 ... RTL_GIGA_MAC_VER_48:
-- case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_63:
-+ case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_65:
- r8168_mac_ocp_modify(tp, 0xe092, 0x00ff, 0);
- break;
- default:
- break;
- }
-
-- rtl_mod_config2(tp, ClkReqEn, 0);
-+ switch (tp->mac_version) {
-+ case RTL_GIGA_MAC_VER_65:
-+ val8 = RTL_R8(tp, INT_CFG0_8125) & ~INT_CFG0_CLKREQEN;
-+ RTL_W8(tp, INT_CFG0_8125, val8);
-+ break;
-+ default:
-+ rtl_mod_config2(tp, ClkReqEn, 0);
-+ break;
-+ }
- rtl_mod_config5(tp, ASPM_en, 0);
- }
- }
-@@ -3678,10 +3707,15 @@ static void rtl_hw_start_8125_common(str
- /* disable new tx descriptor format */
- r8168_mac_ocp_modify(tp, 0xeb58, 0x0001, 0x0000);
-
-- if (tp->mac_version == RTL_GIGA_MAC_VER_63)
-+ if (tp->mac_version == RTL_GIGA_MAC_VER_65)
-+ RTL_W8(tp, 0xD8, RTL_R8(tp, 0xD8) & ~0x02);
-+
-+ if (tp->mac_version == RTL_GIGA_MAC_VER_65)
-+ r8168_mac_ocp_modify(tp, 0xe614, 0x0700, 0x0400);
-+ else if (tp->mac_version == RTL_GIGA_MAC_VER_63)
- r8168_mac_ocp_modify(tp, 0xe614, 0x0700, 0x0200);
- else
-- r8168_mac_ocp_modify(tp, 0xe614, 0x0700, 0x0400);
-+ r8168_mac_ocp_modify(tp, 0xe614, 0x0700, 0x0300);
-
- if (tp->mac_version == RTL_GIGA_MAC_VER_63)
- r8168_mac_ocp_modify(tp, 0xe63e, 0x0c30, 0x0000);
-@@ -3694,6 +3728,10 @@ static void rtl_hw_start_8125_common(str
- r8168_mac_ocp_modify(tp, 0xe056, 0x00f0, 0x0030);
- r8168_mac_ocp_modify(tp, 0xe040, 0x1000, 0x0000);
- r8168_mac_ocp_modify(tp, 0xea1c, 0x0003, 0x0001);
-+ if (tp->mac_version == RTL_GIGA_MAC_VER_65)
-+ r8168_mac_ocp_modify(tp, 0xea1c, 0x0300, 0x0000);
-+ else
-+ r8168_mac_ocp_modify(tp, 0xea1c, 0x0004, 0x0000);
- r8168_mac_ocp_modify(tp, 0xe0c0, 0x4f0f, 0x4403);
- r8168_mac_ocp_modify(tp, 0xe052, 0x0080, 0x0068);
- r8168_mac_ocp_modify(tp, 0xd430, 0x0fff, 0x047f);
-@@ -3708,10 +3746,10 @@ static void rtl_hw_start_8125_common(str
-
- rtl_loop_wait_low(tp, &rtl_mac_ocp_e00e_cond, 1000, 10);
-
-- if (tp->mac_version == RTL_GIGA_MAC_VER_63)
-- rtl8125b_config_eee_mac(tp);
-- else
-+ if (tp->mac_version == RTL_GIGA_MAC_VER_61)
- rtl8125a_config_eee_mac(tp);
-+ else
-+ rtl8125b_config_eee_mac(tp);
-
- rtl_disable_rxdvgate(tp);
- }
-@@ -3755,6 +3793,12 @@ static void rtl_hw_start_8125b(struct rt
- rtl_hw_start_8125_common(tp);
- }
-
-+static void rtl_hw_start_8126a(struct rtl8169_private *tp)
-+{
-+ rtl_set_def_aspm_entry_latency(tp);
-+ rtl_hw_start_8125_common(tp);
-+}
-+
- static void rtl_hw_config(struct rtl8169_private *tp)
- {
- static const rtl_generic_fct hw_configs[] = {
-@@ -3797,6 +3841,7 @@ static void rtl_hw_config(struct rtl8169
- [RTL_GIGA_MAC_VER_53] = rtl_hw_start_8117,
- [RTL_GIGA_MAC_VER_61] = rtl_hw_start_8125a_2,
- [RTL_GIGA_MAC_VER_63] = rtl_hw_start_8125b,
-+ [RTL_GIGA_MAC_VER_65] = rtl_hw_start_8126a,
- };
-
- if (hw_configs[tp->mac_version])
-@@ -3807,9 +3852,23 @@ static void rtl_hw_start_8125(struct rtl
- {
- int i;
-
-+ RTL_W8(tp, INT_CFG0_8125, 0x00);
-+
- /* disable interrupt coalescing */
-- for (i = 0xa00; i < 0xb00; i += 4)
-- RTL_W32(tp, i, 0);
-+ switch (tp->mac_version) {
-+ case RTL_GIGA_MAC_VER_61:
-+ for (i = 0xa00; i < 0xb00; i += 4)
-+ RTL_W32(tp, i, 0);
-+ break;
-+ case RTL_GIGA_MAC_VER_63:
-+ case RTL_GIGA_MAC_VER_65:
-+ for (i = 0xa00; i < 0xa80; i += 4)
-+ RTL_W32(tp, i, 0);
-+ RTL_W16(tp, INT_CFG1_8125, 0x0000);
-+ break;
-+ default:
-+ break;
-+ }
-
- rtl_hw_config(tp);
- }
-@@ -3887,8 +3946,7 @@ static int rtl8169_change_mtu(struct net
- rtl_jumbo_config(tp);
-
- switch (tp->mac_version) {
-- case RTL_GIGA_MAC_VER_61:
-- case RTL_GIGA_MAC_VER_63:
-+ case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_65:
- rtl8125_set_eee_txidle_timer(tp);
- break;
- default:
-@@ -4037,7 +4095,7 @@ static void rtl8169_cleanup(struct rtl81
- RTL_W8(tp, ChipCmd, RTL_R8(tp, ChipCmd) | StopReq);
- rtl_loop_wait_high(tp, &rtl_txcfg_empty_cond, 100, 666);
- break;
-- case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_63:
-+ case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_65:
- rtl_enable_rxdvgate(tp);
- fsleep(2000);
- break;
-@@ -4188,8 +4246,7 @@ static unsigned int rtl_quirk_packet_pad
-
- switch (tp->mac_version) {
- case RTL_GIGA_MAC_VER_34:
-- case RTL_GIGA_MAC_VER_61:
-- case RTL_GIGA_MAC_VER_63:
-+ case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_65:
- padto = max_t(unsigned int, padto, ETH_ZLEN);
- break;
- default:
-@@ -5225,7 +5282,7 @@ static void rtl_hw_initialize(struct rtl
- case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_48:
- rtl_hw_init_8168g(tp);
- break;
-- case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_63:
-+ case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_65:
- rtl_hw_init_8125(tp);
- break;
- default:
---- a/drivers/net/ethernet/realtek/r8169_phy_config.c
-+++ b/drivers/net/ethernet/realtek/r8169_phy_config.c
-@@ -1102,6 +1102,12 @@ static void rtl8125b_hw_phy_config(struc
- rtl8125b_config_eee_phy(phydev);
- }
-
-+static void rtl8126a_hw_phy_config(struct rtl8169_private *tp,
-+ struct phy_device *phydev)
-+{
-+ r8169_apply_firmware(tp);
-+}
-+
- void r8169_hw_phy_config(struct rtl8169_private *tp, struct phy_device *phydev,
- enum mac_version ver)
- {
-@@ -1152,6 +1158,7 @@ void r8169_hw_phy_config(struct rtl8169_
- [RTL_GIGA_MAC_VER_53] = rtl8117_hw_phy_config,
- [RTL_GIGA_MAC_VER_61] = rtl8125a_2_hw_phy_config,
- [RTL_GIGA_MAC_VER_63] = rtl8125b_hw_phy_config,
-+ [RTL_GIGA_MAC_VER_65] = rtl8126a_hw_phy_config,
- };
-
- if (phy_configs[ver])
diff --git a/target/linux/generic/backport-6.6/780-04-v6.8-r8169-improve-handling-task-scheduling.patch b/target/linux/generic/backport-6.6/780-04-v6.8-r8169-improve-handling-task-scheduling.patch
new file mode 100644
index 0000000000..a809e8213a
--- /dev/null
+++ b/target/linux/generic/backport-6.6/780-04-v6.8-r8169-improve-handling-task-scheduling.patch
@@ -0,0 +1,41 @@
+From 127532cd0f060ebc3c4cbca81b6438728ad5896e Mon Sep 17 00:00:00 2001
+From: Heiner Kallweit <hkallweit1@gmail.com>
+Date: Mon, 27 Nov 2023 18:20:11 +0100
+Subject: [PATCH] r8169: improve handling task scheduling
+
+If we know that the task is going to be a no-op, don't even schedule it.
+And remove the check for netif_running() in the worker function, the
+check for flag RTL_FLAG_TASK_ENABLED is sufficient. Note that we can't
+remove the check for flag RTL_FLAG_TASK_ENABLED in the worker function
+because we have no guarantee when it will be executed.
+
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
+Link: https://lore.kernel.org/r/c65873a3-7394-4107-99a7-83f20030779c@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/realtek/r8169_main.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -2252,6 +2252,9 @@ u16 rtl8168h_2_get_adc_bias_ioffset(stru
+
+ static void rtl_schedule_task(struct rtl8169_private *tp, enum rtl_flag flag)
+ {
++ if (!test_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags))
++ return;
++
+ set_bit(flag, tp->wk.flags);
+ schedule_work(&tp->wk.work);
+ }
+@@ -4491,8 +4494,7 @@ static void rtl_task(struct work_struct
+
+ rtnl_lock();
+
+- if (!netif_running(tp->dev) ||
+- !test_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags))
++ if (!test_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags))
+ goto out_unlock;
+
+ if (test_and_clear_bit(RTL_FLAG_TASK_TX_TIMEOUT, tp->wk.flags)) {
diff --git a/target/linux/generic/backport-6.6/780-05-v6.8-r8169-add-support-for-LED-s-on-RTL8168-RTL8101.patch b/target/linux/generic/backport-6.6/780-05-v6.8-r8169-add-support-for-LED-s-on-RTL8168-RTL8101.patch
new file mode 100644
index 0000000000..7a5d5a66a1
--- /dev/null
+++ b/target/linux/generic/backport-6.6/780-05-v6.8-r8169-add-support-for-LED-s-on-RTL8168-RTL8101.patch
@@ -0,0 +1,319 @@
+From 18764b883e157e28126b54e7d4ba9dd487d5bf54 Mon Sep 17 00:00:00 2001
+From: Heiner Kallweit <hkallweit1@gmail.com>
+Date: Sat, 16 Dec 2023 20:58:10 +0100
+Subject: [PATCH] r8169: add support for LED's on RTL8168/RTL8101
+
+This adds support for the LED's on most chip versions. Excluded are
+the old non-PCIe versions and RTL8125. RTL8125 has a different LED
+register layout, support for it will follow later.
+
+LED's can be controlled from userspace using the netdev LED trigger.
+
+Tested on RTL8168h.
+
+Note: The driver can't know which LED's are actually physically
+wired. Therefore not every LED device may represent a physically
+available LED.
+
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/realtek/Makefile | 3 +
+ drivers/net/ethernet/realtek/r8169.h | 7 +
+ drivers/net/ethernet/realtek/r8169_leds.c | 157 ++++++++++++++++++++++
+ drivers/net/ethernet/realtek/r8169_main.c | 65 +++++++++
+ 4 files changed, 232 insertions(+)
+ create mode 100644 drivers/net/ethernet/realtek/r8169_leds.c
+
+--- a/drivers/net/ethernet/realtek/Makefile
++++ b/drivers/net/ethernet/realtek/Makefile
+@@ -7,4 +7,7 @@ obj-$(CONFIG_8139CP) += 8139cp.o
+ obj-$(CONFIG_8139TOO) += 8139too.o
+ obj-$(CONFIG_ATP) += atp.o
+ r8169-objs += r8169_main.o r8169_firmware.o r8169_phy_config.o
++ifdef CONFIG_LEDS_TRIGGER_NETDEV
++r8169-objs += r8169_leds.o
++endif
+ obj-$(CONFIG_R8169) += r8169.o
+--- a/drivers/net/ethernet/realtek/r8169.h
++++ b/drivers/net/ethernet/realtek/r8169.h
+@@ -8,6 +8,7 @@
+ * See MAINTAINERS file for support contact information.
+ */
+
++#include <linux/netdevice.h>
+ #include <linux/types.h>
+ #include <linux/phy.h>
+
+@@ -77,3 +78,9 @@ u16 rtl8168h_2_get_adc_bias_ioffset(stru
+ u8 rtl8168d_efuse_read(struct rtl8169_private *tp, int reg_addr);
+ void r8169_hw_phy_config(struct rtl8169_private *tp, struct phy_device *phydev,
+ enum mac_version ver);
++
++void r8169_get_led_name(struct rtl8169_private *tp, int idx,
++ char *buf, int buf_len);
++int rtl8168_get_led_mode(struct rtl8169_private *tp);
++int rtl8168_led_mod_ctrl(struct rtl8169_private *tp, u16 mask, u16 val);
++void rtl8168_init_leds(struct net_device *ndev);
+--- /dev/null
++++ b/drivers/net/ethernet/realtek/r8169_leds.c
+@@ -0,0 +1,157 @@
++// SPDX-License-Identifier: GPL-2.0-only
++/* r8169_leds.c: Realtek 8169/8168/8101/8125 ethernet driver.
++ *
++ * Copyright (c) 2023 Heiner Kallweit <hkallweit1@gmail.com>
++ *
++ * See MAINTAINERS file for support contact information.
++ */
++
++#include <linux/leds.h>
++#include <linux/netdevice.h>
++#include <uapi/linux/uleds.h>
++
++#include "r8169.h"
++
++#define RTL8168_LED_CTRL_OPTION2 BIT(15)
++#define RTL8168_LED_CTRL_ACT BIT(3)
++#define RTL8168_LED_CTRL_LINK_1000 BIT(2)
++#define RTL8168_LED_CTRL_LINK_100 BIT(1)
++#define RTL8168_LED_CTRL_LINK_10 BIT(0)
++
++#define RTL8168_NUM_LEDS 3
++
++#define RTL8168_SUPPORTED_MODES \
++ (BIT(TRIGGER_NETDEV_LINK_1000) | BIT(TRIGGER_NETDEV_LINK_100) | \
++ BIT(TRIGGER_NETDEV_LINK_10) | BIT(TRIGGER_NETDEV_RX) | \
++ BIT(TRIGGER_NETDEV_TX))
++
++struct r8169_led_classdev {
++ struct led_classdev led;
++ struct net_device *ndev;
++ int index;
++};
++
++#define lcdev_to_r8169_ldev(lcdev) container_of(lcdev, struct r8169_led_classdev, led)
++
++static int rtl8168_led_hw_control_is_supported(struct led_classdev *led_cdev,
++ unsigned long flags)
++{
++ struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev);
++ struct rtl8169_private *tp = netdev_priv(ldev->ndev);
++ int shift = ldev->index * 4;
++ bool rx, tx;
++
++ if (flags & ~RTL8168_SUPPORTED_MODES)
++ goto nosupp;
++
++ rx = flags & BIT(TRIGGER_NETDEV_RX);
++ tx = flags & BIT(TRIGGER_NETDEV_TX);
++ if (rx != tx)
++ goto nosupp;
++
++ return 0;
++
++nosupp:
++ /* Switch LED off to indicate that mode isn't supported */
++ rtl8168_led_mod_ctrl(tp, 0x000f << shift, 0);
++ return -EOPNOTSUPP;
++}
++
++static int rtl8168_led_hw_control_set(struct led_classdev *led_cdev,
++ unsigned long flags)
++{
++ struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev);
++ struct rtl8169_private *tp = netdev_priv(ldev->ndev);
++ int shift = ldev->index * 4;
++ u16 mode = 0;
++
++ if (flags & BIT(TRIGGER_NETDEV_LINK_10))
++ mode |= RTL8168_LED_CTRL_LINK_10;
++ if (flags & BIT(TRIGGER_NETDEV_LINK_100))
++ mode |= RTL8168_LED_CTRL_LINK_100;
++ if (flags & BIT(TRIGGER_NETDEV_LINK_1000))
++ mode |= RTL8168_LED_CTRL_LINK_1000;
++ if (flags & BIT(TRIGGER_NETDEV_TX))
++ mode |= RTL8168_LED_CTRL_ACT;
++
++ return rtl8168_led_mod_ctrl(tp, 0x000f << shift, mode << shift);
++}
++
++static int rtl8168_led_hw_control_get(struct led_classdev *led_cdev,
++ unsigned long *flags)
++{
++ struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev);
++ struct rtl8169_private *tp = netdev_priv(ldev->ndev);
++ int shift = ldev->index * 4;
++ int mode;
++
++ mode = rtl8168_get_led_mode(tp);
++ if (mode < 0)
++ return mode;
++
++ if (mode & RTL8168_LED_CTRL_OPTION2) {
++ rtl8168_led_mod_ctrl(tp, RTL8168_LED_CTRL_OPTION2, 0);
++ netdev_notice(ldev->ndev, "Deactivating unsupported Option2 LED mode\n");
++ }
++
++ mode = (mode >> shift) & 0x000f;
++
++ if (mode & RTL8168_LED_CTRL_ACT)
++ *flags |= BIT(TRIGGER_NETDEV_TX) | BIT(TRIGGER_NETDEV_RX);
++
++ if (mode & RTL8168_LED_CTRL_LINK_10)
++ *flags |= BIT(TRIGGER_NETDEV_LINK_10);
++ if (mode & RTL8168_LED_CTRL_LINK_100)
++ *flags |= BIT(TRIGGER_NETDEV_LINK_100);
++ if (mode & RTL8168_LED_CTRL_LINK_1000)
++ *flags |= BIT(TRIGGER_NETDEV_LINK_1000);
++
++ return 0;
++}
++
++static struct device *
++ r8169_led_hw_control_get_device(struct led_classdev *led_cdev)
++{
++ struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev);
++
++ return &ldev->ndev->dev;
++}
++
++static void rtl8168_setup_ldev(struct r8169_led_classdev *ldev,
++ struct net_device *ndev, int index)
++{
++ struct rtl8169_private *tp = netdev_priv(ndev);
++ struct led_classdev *led_cdev = &ldev->led;
++ char led_name[LED_MAX_NAME_SIZE];
++
++ ldev->ndev = ndev;
++ ldev->index = index;
++
++ r8169_get_led_name(tp, index, led_name, LED_MAX_NAME_SIZE);
++ led_cdev->name = led_name;
++ led_cdev->default_trigger = "netdev";
++ led_cdev->hw_control_trigger = "netdev";
++ led_cdev->flags |= LED_RETAIN_AT_SHUTDOWN;
++ led_cdev->hw_control_is_supported = rtl8168_led_hw_control_is_supported;
++ led_cdev->hw_control_set = rtl8168_led_hw_control_set;
++ led_cdev->hw_control_get = rtl8168_led_hw_control_get;
++ led_cdev->hw_control_get_device = r8169_led_hw_control_get_device;
++
++ /* ignore errors */
++ devm_led_classdev_register(&ndev->dev, led_cdev);
++}
++
++void rtl8168_init_leds(struct net_device *ndev)
++{
++ /* bind resource mgmt to netdev */
++ struct device *dev = &ndev->dev;
++ struct r8169_led_classdev *leds;
++ int i;
++
++ leds = devm_kcalloc(dev, RTL8168_NUM_LEDS, sizeof(*leds), GFP_KERNEL);
++ if (!leds)
++ return;
++
++ for (i = 0; i < RTL8168_NUM_LEDS; i++)
++ rtl8168_setup_ldev(leds + i, ndev, i);
++}
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -285,6 +285,7 @@ enum rtl8168_8101_registers {
+ };
+
+ enum rtl8168_registers {
++ LED_CTRL = 0x18,
+ LED_FREQ = 0x1a,
+ EEE_LED = 0x1b,
+ ERIDR = 0x70,
+@@ -616,6 +617,7 @@ struct rtl8169_private {
+
+ raw_spinlock_t config25_lock;
+ raw_spinlock_t mac_ocp_lock;
++ struct mutex led_lock; /* serialize LED ctrl RMW access */
+
+ raw_spinlock_t cfg9346_usage_lock;
+ int cfg9346_usage_count;
+@@ -788,6 +790,62 @@ static const struct rtl_cond name = {
+ \
+ static bool name ## _check(struct rtl8169_private *tp)
+
++int rtl8168_led_mod_ctrl(struct rtl8169_private *tp, u16 mask, u16 val)
++{
++ struct device *dev = tp_to_dev(tp);
++ int ret;
++
++ ret = pm_runtime_resume_and_get(dev);
++ if (ret < 0)
++ return ret;
++
++ mutex_lock(&tp->led_lock);
++ RTL_W16(tp, LED_CTRL, (RTL_R16(tp, LED_CTRL) & ~mask) | val);
++ mutex_unlock(&tp->led_lock);
++
++ pm_runtime_put_sync(dev);
++
++ return 0;
++}
++
++int rtl8168_get_led_mode(struct rtl8169_private *tp)
++{
++ struct device *dev = tp_to_dev(tp);
++ int ret;
++
++ ret = pm_runtime_resume_and_get(dev);
++ if (ret < 0)
++ return ret;
++
++ ret = RTL_R16(tp, LED_CTRL);
++
++ pm_runtime_put_sync(dev);
++
++ return ret;
++}
++
++void r8169_get_led_name(struct rtl8169_private *tp, int idx,
++ char *buf, int buf_len)
++{
++ struct pci_dev *pdev = tp->pci_dev;
++ char pdom[8], pfun[8];
++ int domain;
++
++ domain = pci_domain_nr(pdev->bus);
++ if (domain)
++ snprintf(pdom, sizeof(pdom), "P%d", domain);
++ else
++ pdom[0] = '\0';
++
++ if (pdev->multifunction)
++ snprintf(pfun, sizeof(pfun), "f%d", PCI_FUNC(pdev->devfn));
++ else
++ pfun[0] = '\0';
++
++ snprintf(buf, buf_len, "en%sp%ds%d%s-%d::lan", pdom, pdev->bus->number,
++ PCI_SLOT(pdev->devfn), pfun, idx);
++}
++
+ static void r8168fp_adjust_ocp_cmd(struct rtl8169_private *tp, u32 *cmd, int type)
+ {
+ /* based on RTL8168FP_OOBMAC_BASE in vendor driver */
+@@ -5168,6 +5226,7 @@ static int rtl_init_one(struct pci_dev *
+ raw_spin_lock_init(&tp->cfg9346_usage_lock);
+ raw_spin_lock_init(&tp->config25_lock);
+ raw_spin_lock_init(&tp->mac_ocp_lock);
++ mutex_init(&tp->led_lock);
+
+ dev->tstats = devm_netdev_alloc_pcpu_stats(&pdev->dev,
+ struct pcpu_sw_netstats);
+@@ -5324,6 +5383,12 @@ static int rtl_init_one(struct pci_dev *
+ if (rc)
+ return rc;
+
++#if IS_REACHABLE(CONFIG_LEDS_CLASS) && IS_ENABLED(CONFIG_LEDS_TRIGGER_NETDEV)
++ if (tp->mac_version > RTL_GIGA_MAC_VER_06 &&
++ tp->mac_version < RTL_GIGA_MAC_VER_61)
++ rtl8168_init_leds(dev);
++#endif
++
+ netdev_info(dev, "%s, %pM, XID %03x, IRQ %d\n",
+ rtl_chip_infos[chipset].name, dev->dev_addr, xid, tp->irq);
+
diff --git a/target/linux/generic/backport-6.6/780-05-v6.9-r8169-add-LED-support-for-RTL8125-RTL8126.patch b/target/linux/generic/backport-6.6/780-05-v6.9-r8169-add-LED-support-for-RTL8125-RTL8126.patch
deleted file mode 100644
index 742ee578b2..0000000000
--- a/target/linux/generic/backport-6.6/780-05-v6.9-r8169-add-LED-support-for-RTL8125-RTL8126.patch
+++ /dev/null
@@ -1,244 +0,0 @@
-From be51ed104ba9929c741afb718ef7198dbcecef94 Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Mon, 12 Feb 2024 19:44:11 +0100
-Subject: [PATCH] r8169: add LED support for RTL8125/RTL8126
-
-This adds LED support for RTL8125/RTL8126.
-
-Note: Due to missing datasheets changing the 5Gbps link mode isn't
-supported for RTL8126.
-
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Link: https://lore.kernel.org/r/f982602c-9de3-4ca6-85a3-2c1d118dcb15@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/realtek/r8169.h | 3 +
- drivers/net/ethernet/realtek/r8169_leds.c | 106 ++++++++++++++++++++++
- drivers/net/ethernet/realtek/r8169_main.c | 61 ++++++++++++-
- 3 files changed, 166 insertions(+), 4 deletions(-)
-
---- a/drivers/net/ethernet/realtek/r8169.h
-+++ b/drivers/net/ethernet/realtek/r8169.h
-@@ -85,3 +85,6 @@ void r8169_get_led_name(struct rtl8169_p
- int rtl8168_get_led_mode(struct rtl8169_private *tp);
- int rtl8168_led_mod_ctrl(struct rtl8169_private *tp, u16 mask, u16 val);
- void rtl8168_init_leds(struct net_device *ndev);
-+int rtl8125_get_led_mode(struct rtl8169_private *tp, int index);
-+int rtl8125_set_led_mode(struct rtl8169_private *tp, int index, u16 mode);
-+void rtl8125_init_leds(struct net_device *ndev);
---- a/drivers/net/ethernet/realtek/r8169_leds.c
-+++ b/drivers/net/ethernet/realtek/r8169_leds.c
-@@ -18,7 +18,14 @@
- #define RTL8168_LED_CTRL_LINK_100 BIT(1)
- #define RTL8168_LED_CTRL_LINK_10 BIT(0)
-
-+#define RTL8125_LED_CTRL_ACT BIT(9)
-+#define RTL8125_LED_CTRL_LINK_2500 BIT(5)
-+#define RTL8125_LED_CTRL_LINK_1000 BIT(3)
-+#define RTL8125_LED_CTRL_LINK_100 BIT(1)
-+#define RTL8125_LED_CTRL_LINK_10 BIT(0)
-+
- #define RTL8168_NUM_LEDS 3
-+#define RTL8125_NUM_LEDS 4
-
- struct r8169_led_classdev {
- struct led_classdev led;
-@@ -157,3 +164,102 @@ void rtl8168_init_leds(struct net_device
- for (i = 0; i < RTL8168_NUM_LEDS; i++)
- rtl8168_setup_ldev(leds + i, ndev, i);
- }
-+
-+static int rtl8125_led_hw_control_is_supported(struct led_classdev *led_cdev,
-+ unsigned long flags)
-+{
-+ struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev);
-+ struct rtl8169_private *tp = netdev_priv(ldev->ndev);
-+
-+ if (!r8169_trigger_mode_is_valid(flags)) {
-+ /* Switch LED off to indicate that mode isn't supported */
-+ rtl8125_set_led_mode(tp, ldev->index, 0);
-+ return -EOPNOTSUPP;
-+ }
-+
-+ return 0;
-+}
-+
-+static int rtl8125_led_hw_control_set(struct led_classdev *led_cdev,
-+ unsigned long flags)
-+{
-+ struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev);
-+ struct rtl8169_private *tp = netdev_priv(ldev->ndev);
-+ u16 mode = 0;
-+
-+ if (flags & BIT(TRIGGER_NETDEV_LINK_10))
-+ mode |= RTL8125_LED_CTRL_LINK_10;
-+ if (flags & BIT(TRIGGER_NETDEV_LINK_100))
-+ mode |= RTL8125_LED_CTRL_LINK_100;
-+ if (flags & BIT(TRIGGER_NETDEV_LINK_1000))
-+ mode |= RTL8125_LED_CTRL_LINK_1000;
-+ if (flags & BIT(TRIGGER_NETDEV_LINK_2500))
-+ mode |= RTL8125_LED_CTRL_LINK_2500;
-+ if (flags & (BIT(TRIGGER_NETDEV_TX) | BIT(TRIGGER_NETDEV_RX)))
-+ mode |= RTL8125_LED_CTRL_ACT;
-+
-+ return rtl8125_set_led_mode(tp, ldev->index, mode);
-+}
-+
-+static int rtl8125_led_hw_control_get(struct led_classdev *led_cdev,
-+ unsigned long *flags)
-+{
-+ struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev);
-+ struct rtl8169_private *tp = netdev_priv(ldev->ndev);
-+ int mode;
-+
-+ mode = rtl8125_get_led_mode(tp, ldev->index);
-+ if (mode < 0)
-+ return mode;
-+
-+ if (mode & RTL8125_LED_CTRL_LINK_10)
-+ *flags |= BIT(TRIGGER_NETDEV_LINK_10);
-+ if (mode & RTL8125_LED_CTRL_LINK_100)
-+ *flags |= BIT(TRIGGER_NETDEV_LINK_100);
-+ if (mode & RTL8125_LED_CTRL_LINK_1000)
-+ *flags |= BIT(TRIGGER_NETDEV_LINK_1000);
-+ if (mode & RTL8125_LED_CTRL_LINK_2500)
-+ *flags |= BIT(TRIGGER_NETDEV_LINK_2500);
-+ if (mode & RTL8125_LED_CTRL_ACT)
-+ *flags |= BIT(TRIGGER_NETDEV_TX) | BIT(TRIGGER_NETDEV_RX);
-+
-+ return 0;
-+}
-+
-+static void rtl8125_setup_led_ldev(struct r8169_led_classdev *ldev,
-+ struct net_device *ndev, int index)
-+{
-+ struct rtl8169_private *tp = netdev_priv(ndev);
-+ struct led_classdev *led_cdev = &ldev->led;
-+ char led_name[LED_MAX_NAME_SIZE];
-+
-+ ldev->ndev = ndev;
-+ ldev->index = index;
-+
-+ r8169_get_led_name(tp, index, led_name, LED_MAX_NAME_SIZE);
-+ led_cdev->name = led_name;
-+ led_cdev->hw_control_trigger = "netdev";
-+ led_cdev->flags |= LED_RETAIN_AT_SHUTDOWN;
-+ led_cdev->hw_control_is_supported = rtl8125_led_hw_control_is_supported;
-+ led_cdev->hw_control_set = rtl8125_led_hw_control_set;
-+ led_cdev->hw_control_get = rtl8125_led_hw_control_get;
-+ led_cdev->hw_control_get_device = r8169_led_hw_control_get_device;
-+
-+ /* ignore errors */
-+ devm_led_classdev_register(&ndev->dev, led_cdev);
-+}
-+
-+void rtl8125_init_leds(struct net_device *ndev)
-+{
-+ /* bind resource mgmt to netdev */
-+ struct device *dev = &ndev->dev;
-+ struct r8169_led_classdev *leds;
-+ int i;
-+
-+ leds = devm_kcalloc(dev, RTL8125_NUM_LEDS, sizeof(*leds), GFP_KERNEL);
-+ if (!leds)
-+ return;
-+
-+ for (i = 0; i < RTL8125_NUM_LEDS; i++)
-+ rtl8125_setup_led_ldev(leds + i, ndev, i);
-+}
---- a/drivers/net/ethernet/realtek/r8169_main.c
-+++ b/drivers/net/ethernet/realtek/r8169_main.c
-@@ -334,17 +334,23 @@ enum rtl8168_registers {
- };
-
- enum rtl8125_registers {
-+ LEDSEL0 = 0x18,
- INT_CFG0_8125 = 0x34,
- #define INT_CFG0_ENABLE_8125 BIT(0)
- #define INT_CFG0_CLKREQEN BIT(3)
- IntrMask_8125 = 0x38,
- IntrStatus_8125 = 0x3c,
- INT_CFG1_8125 = 0x7a,
-+ LEDSEL2 = 0x84,
-+ LEDSEL1 = 0x86,
- TxPoll_8125 = 0x90,
-+ LEDSEL3 = 0x96,
- MAC0_BKP = 0x19e0,
- EEE_TXIDLE_TIMER_8125 = 0x6048,
- };
-
-+#define LEDSEL_MASK_8125 0x23f
-+
- #define RX_VLAN_INNER_8125 BIT(22)
- #define RX_VLAN_OUTER_8125 BIT(23)
- #define RX_VLAN_8125 (RX_VLAN_INNER_8125 | RX_VLAN_OUTER_8125)
-@@ -835,6 +841,51 @@ int rtl8168_get_led_mode(struct rtl8169_
- return ret;
- }
-
-+static int rtl8125_get_led_reg(int index)
-+{
-+ static const int led_regs[] = { LEDSEL0, LEDSEL1, LEDSEL2, LEDSEL3 };
-+
-+ return led_regs[index];
-+}
-+
-+int rtl8125_set_led_mode(struct rtl8169_private *tp, int index, u16 mode)
-+{
-+ int reg = rtl8125_get_led_reg(index);
-+ struct device *dev = tp_to_dev(tp);
-+ int ret;
-+ u16 val;
-+
-+ ret = pm_runtime_resume_and_get(dev);
-+ if (ret < 0)
-+ return ret;
-+
-+ mutex_lock(&tp->led_lock);
-+ val = RTL_R16(tp, reg) & ~LEDSEL_MASK_8125;
-+ RTL_W16(tp, reg, val | mode);
-+ mutex_unlock(&tp->led_lock);
-+
-+ pm_runtime_put_sync(dev);
-+
-+ return 0;
-+}
-+
-+int rtl8125_get_led_mode(struct rtl8169_private *tp, int index)
-+{
-+ int reg = rtl8125_get_led_reg(index);
-+ struct device *dev = tp_to_dev(tp);
-+ int ret;
-+
-+ ret = pm_runtime_resume_and_get(dev);
-+ if (ret < 0)
-+ return ret;
-+
-+ ret = RTL_R16(tp, reg);
-+
-+ pm_runtime_put_sync(dev);
-+
-+ return ret;
-+}
-+
- void r8169_get_led_name(struct rtl8169_private *tp, int idx,
- char *buf, int buf_len)
- {
-@@ -5530,10 +5581,12 @@ static int rtl_init_one(struct pci_dev *
- if (rc)
- return rc;
-
-- if (IS_ENABLED(CONFIG_R8169_LEDS) &&
-- tp->mac_version > RTL_GIGA_MAC_VER_06 &&
-- tp->mac_version < RTL_GIGA_MAC_VER_61)
-- rtl8168_init_leds(dev);
-+ if (IS_ENABLED(CONFIG_R8169_LEDS)) {
-+ if (rtl_is_8125(tp))
-+ rtl8125_init_leds(dev);
-+ else if (tp->mac_version > RTL_GIGA_MAC_VER_06)
-+ rtl8168_init_leds(dev);
-+ }
-
- netdev_info(dev, "%s, %pM, XID %03x, IRQ %d\n",
- rtl_chip_infos[chipset].name, dev->dev_addr, xid, tp->irq);
diff --git a/target/linux/generic/backport-6.6/780-06-v6.8-r8169-fix-building-with-CONFIG_LEDS_CLASS-m.patch b/target/linux/generic/backport-6.6/780-06-v6.8-r8169-fix-building-with-CONFIG_LEDS_CLASS-m.patch
new file mode 100644
index 0000000000..67f215cadf
--- /dev/null
+++ b/target/linux/generic/backport-6.6/780-06-v6.8-r8169-fix-building-with-CONFIG_LEDS_CLASS-m.patch
@@ -0,0 +1,75 @@
+From a2634a5ffcafc31c343c6153ae487eb184c433a6 Mon Sep 17 00:00:00 2001
+From: Heiner Kallweit <hkallweit1@gmail.com>
+Date: Wed, 3 Jan 2024 16:52:04 +0100
+Subject: [PATCH] r8169: fix building with CONFIG_LEDS_CLASS=m
+
+When r8169 is built-in but LED support is a loadable module, the new
+code to drive the LED causes a link failure:
+
+ld: drivers/net/ethernet/realtek/r8169_leds.o: in function `rtl8168_init_leds':
+r8169_leds.c:(.text+0x36c): undefined reference to `devm_led_classdev_register_ext'
+
+LED support is an optional feature, so fix this issue by adding a Kconfig
+symbol R8169_LEDS that is guaranteed to be false if r8169 is built-in
+and LED core support is a module. As a positive side effect of this change
+r8169_leds.o no longer is built under this configuration.
+
+Fixes: 18764b883e15 ("r8169: add support for LED's on RTL8168/RTL8101")
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202312281159.9TPeXbNd-lkp@intel.com/
+Suggested-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Tested-by: Simon Horman <horms@kernel.org> # build-tested
+Tested-by: Arnd Bergmann <arnd@arndb.de>
+Link: https://lore.kernel.org/r/d055aeb5-fe5c-4ccf-987f-5af93a17537b@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/realtek/Kconfig | 7 +++++++
+ drivers/net/ethernet/realtek/Makefile | 6 ++----
+ drivers/net/ethernet/realtek/r8169_main.c | 5 ++---
+ 3 files changed, 11 insertions(+), 7 deletions(-)
+
+--- a/drivers/net/ethernet/realtek/Kconfig
++++ b/drivers/net/ethernet/realtek/Kconfig
+@@ -113,4 +113,11 @@ config R8169
+ To compile this driver as a module, choose M here: the module
+ will be called r8169. This is recommended.
+
++config R8169_LEDS
++ def_bool R8169 && LEDS_TRIGGER_NETDEV
++ depends on !(R8169=y && LEDS_CLASS=m)
++ help
++ Optional support for controlling the NIC LED's with the netdev
++ LED trigger.
++
+ endif # NET_VENDOR_REALTEK
+--- a/drivers/net/ethernet/realtek/Makefile
++++ b/drivers/net/ethernet/realtek/Makefile
+@@ -6,8 +6,6 @@
+ obj-$(CONFIG_8139CP) += 8139cp.o
+ obj-$(CONFIG_8139TOO) += 8139too.o
+ obj-$(CONFIG_ATP) += atp.o
+-r8169-objs += r8169_main.o r8169_firmware.o r8169_phy_config.o
+-ifdef CONFIG_LEDS_TRIGGER_NETDEV
+-r8169-objs += r8169_leds.o
+-endif
++r8169-y += r8169_main.o r8169_firmware.o r8169_phy_config.o
++r8169-$(CONFIG_R8169_LEDS) += r8169_leds.o
+ obj-$(CONFIG_R8169) += r8169.o
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -5383,11 +5383,10 @@ static int rtl_init_one(struct pci_dev *
+ if (rc)
+ return rc;
+
+-#if IS_REACHABLE(CONFIG_LEDS_CLASS) && IS_ENABLED(CONFIG_LEDS_TRIGGER_NETDEV)
+- if (tp->mac_version > RTL_GIGA_MAC_VER_06 &&
++ if (IS_ENABLED(CONFIG_R8169_LEDS) &&
++ tp->mac_version > RTL_GIGA_MAC_VER_06 &&
+ tp->mac_version < RTL_GIGA_MAC_VER_61)
+ rtl8168_init_leds(dev);
+-#endif
+
+ netdev_info(dev, "%s, %pM, XID %03x, IRQ %d\n",
+ rtl_chip_infos[chipset].name, dev->dev_addr, xid, tp->irq);
diff --git a/target/linux/generic/backport-6.6/780-06-v6.9-r8169-add-MODULE_FIRMWARE-entry-for-RTL8126A.patch b/target/linux/generic/backport-6.6/780-06-v6.9-r8169-add-MODULE_FIRMWARE-entry-for-RTL8126A.patch
deleted file mode 100644
index a6175c824e..0000000000
--- a/target/linux/generic/backport-6.6/780-06-v6.9-r8169-add-MODULE_FIRMWARE-entry-for-RTL8126A.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From f4d3e595c0000ce39dec7e4799ea42ce42ab6867 Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Sat, 17 Feb 2024 15:48:23 +0100
-Subject: [PATCH] r8169: add MODULE_FIRMWARE entry for RTL8126A
-
-Add the missing MODULE_FIRMWARE entry for RTL8126A.
-
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Reviewed-by: Simon Horman <horms@kernel.org>
-Link: https://lore.kernel.org/r/47ef79d2-59c4-4d44-9595-366c70c4ad87@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/realtek/r8169_main.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/drivers/net/ethernet/realtek/r8169_main.c
-+++ b/drivers/net/ethernet/realtek/r8169_main.c
-@@ -680,6 +680,7 @@ MODULE_FIRMWARE(FIRMWARE_8168FP_3);
- MODULE_FIRMWARE(FIRMWARE_8107E_2);
- MODULE_FIRMWARE(FIRMWARE_8125A_3);
- MODULE_FIRMWARE(FIRMWARE_8125B_2);
-+MODULE_FIRMWARE(FIRMWARE_8126A_2);
-
- static inline struct device *tp_to_dev(struct rtl8169_private *tp)
- {
diff --git a/target/linux/generic/backport-6.6/780-07-v6.10-r8169-add-support-for-RTL8168M.patch b/target/linux/generic/backport-6.6/780-07-v6.10-r8169-add-support-for-RTL8168M.patch
deleted file mode 100644
index 557b8b1491..0000000000
--- a/target/linux/generic/backport-6.6/780-07-v6.10-r8169-add-support-for-RTL8168M.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 39f59c72ad3a1eaab9a60f0671bc94d2bc826d21 Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Sun, 7 Apr 2024 23:19:25 +0200
-Subject: [PATCH] r8169: add support for RTL8168M
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-A user reported an unknown chip version. According to the r8168 vendor
-driver it's called RTL8168M, but handling is identical to RTL8168H.
-So let's simply treat it as RTL8168H.
-
-Tested-by: Евгений <octobergun@gmail.com>
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/realtek/r8169_main.c | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/drivers/net/ethernet/realtek/r8169_main.c
-+++ b/drivers/net/ethernet/realtek/r8169_main.c
-@@ -2212,6 +2212,8 @@ static enum mac_version rtl8169_get_mac_
- * the wild. Let's disable detection.
- * { 0x7cf, 0x540, RTL_GIGA_MAC_VER_45 },
- */
-+ /* Realtek calls it RTL8168M, but it's handled like RTL8168H */
-+ { 0x7cf, 0x6c0, RTL_GIGA_MAC_VER_46 },
-
- /* 8168G family. */
- { 0x7cf, 0x5c8, RTL_GIGA_MAC_VER_44 },
diff --git a/target/linux/generic/backport-6.6/780-07-v6.9-r8169-simplify-EEE-handling.patch b/target/linux/generic/backport-6.6/780-07-v6.9-r8169-simplify-EEE-handling.patch
new file mode 100644
index 0000000000..bdd3330580
--- /dev/null
+++ b/target/linux/generic/backport-6.6/780-07-v6.9-r8169-simplify-EEE-handling.patch
@@ -0,0 +1,96 @@
+From f5d59230ec26aa5e8b59e9f4a4d288703a737479 Mon Sep 17 00:00:00 2001
+From: Heiner Kallweit <hkallweit1@gmail.com>
+Date: Wed, 31 Jan 2024 21:31:01 +0100
+Subject: [PATCH] r8169: simplify EEE handling
+
+We don't have to store the EEE modes to be advertised in the driver,
+phylib does this for us and stores it in phydev->advertising_eee.
+phylib also takes care of properly handling the EEE advertisement.
+
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Link: https://lore.kernel.org/r/27c336a8-ea47-483d-815b-02c45ae41da2@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/realtek/r8169_main.c | 32 +++--------------------
+ 1 file changed, 4 insertions(+), 28 deletions(-)
+
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -629,7 +629,6 @@ struct rtl8169_private {
+ struct rtl8169_counters *counters;
+ struct rtl8169_tc_offsets tc_offset;
+ u32 saved_wolopts;
+- int eee_adv;
+
+ const char *fw_name;
+ struct rtl_fw *rtl_fw;
+@@ -2010,17 +2009,11 @@ static int rtl8169_get_eee(struct net_de
+ static int rtl8169_set_eee(struct net_device *dev, struct ethtool_eee *data)
+ {
+ struct rtl8169_private *tp = netdev_priv(dev);
+- int ret;
+
+ if (!rtl_supports_eee(tp))
+ return -EOPNOTSUPP;
+
+- ret = phy_ethtool_set_eee(tp->phydev, data);
+-
+- if (!ret)
+- tp->eee_adv = phy_read_mmd(dev->phydev, MDIO_MMD_AN,
+- MDIO_AN_EEE_ADV);
+- return ret;
++ return phy_ethtool_set_eee(tp->phydev, data);
+ }
+
+ static void rtl8169_get_ringparam(struct net_device *dev,
+@@ -2085,21 +2078,6 @@ static const struct ethtool_ops rtl8169_
+ .set_pauseparam = rtl8169_set_pauseparam,
+ };
+
+-static void rtl_enable_eee(struct rtl8169_private *tp)
+-{
+- struct phy_device *phydev = tp->phydev;
+- int adv;
+-
+- /* respect EEE advertisement the user may have set */
+- if (tp->eee_adv >= 0)
+- adv = tp->eee_adv;
+- else
+- adv = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_PCS_EEE_ABLE);
+-
+- if (adv >= 0)
+- phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, adv);
+-}
+-
+ static enum mac_version rtl8169_get_mac_version(u16 xid, bool gmii)
+ {
+ /*
+@@ -2336,9 +2314,6 @@ static void rtl8169_init_phy(struct rtl8
+ /* We may have called phy_speed_down before */
+ phy_speed_up(tp->phydev);
+
+- if (rtl_supports_eee(tp))
+- rtl_enable_eee(tp);
+-
+ genphy_soft_reset(tp->phydev);
+ }
+
+@@ -5085,7 +5060,9 @@ static int r8169_mdio_register(struct rt
+ }
+
+ tp->phydev->mac_managed_pm = true;
+-
++ if (rtl_supports_eee(tp))
++ linkmode_copy(tp->phydev->advertising_eee,
++ tp->phydev->supported_eee);
+ phy_support_asym_pause(tp->phydev);
+
+ /* PHY will be woken up in rtl_open() */
+@@ -5220,7 +5197,6 @@ static int rtl_init_one(struct pci_dev *
+ tp->dev = dev;
+ tp->pci_dev = pdev;
+ tp->supports_gmii = ent->driver_data == RTL_CFG_NO_GBIT ? 0 : 1;
+- tp->eee_adv = -1;
+ tp->ocp_base = OCP_STD_PHY_BASE;
+
+ raw_spin_lock_init(&tp->cfg9346_usage_lock);
diff --git a/target/linux/generic/backport-6.6/780-08-v6.10-r8169-fix-LED-related-deadlock-on-module-removal.patch b/target/linux/generic/backport-6.6/780-08-v6.10-r8169-fix-LED-related-deadlock-on-module-removal.patch
deleted file mode 100644
index 52019869a8..0000000000
--- a/target/linux/generic/backport-6.6/780-08-v6.10-r8169-fix-LED-related-deadlock-on-module-removal.patch
+++ /dev/null
@@ -1,147 +0,0 @@
-From 19fa4f2a85d777a8052e869c1b892a2f7556569d Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Mon, 8 Apr 2024 20:47:40 +0200
-Subject: [PATCH] r8169: fix LED-related deadlock on module removal
-
-Binding devm_led_classdev_register() to the netdev is problematic
-because on module removal we get a RTNL-related deadlock. Fix this
-by avoiding the device-managed LED functions.
-
-Note: We can safely call led_classdev_unregister() for a LED even
-if registering it failed, because led_classdev_unregister() detects
-this and is a no-op in this case.
-
-Fixes: 18764b883e15 ("r8169: add support for LED's on RTL8168/RTL8101")
-Cc: stable@vger.kernel.org
-Reported-by: Lukas Wunner <lukas@wunner.de>
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/realtek/r8169.h | 6 ++--
- drivers/net/ethernet/realtek/r8169_leds.c | 35 +++++++++++++++--------
- drivers/net/ethernet/realtek/r8169_main.c | 8 ++++--
- 3 files changed, 33 insertions(+), 16 deletions(-)
-
---- a/drivers/net/ethernet/realtek/r8169.h
-+++ b/drivers/net/ethernet/realtek/r8169.h
-@@ -73,6 +73,7 @@ enum mac_version {
- };
-
- struct rtl8169_private;
-+struct r8169_led_classdev;
-
- void r8169_apply_firmware(struct rtl8169_private *tp);
- u16 rtl8168h_2_get_adc_bias_ioffset(struct rtl8169_private *tp);
-@@ -84,7 +85,8 @@ void r8169_get_led_name(struct rtl8169_p
- char *buf, int buf_len);
- int rtl8168_get_led_mode(struct rtl8169_private *tp);
- int rtl8168_led_mod_ctrl(struct rtl8169_private *tp, u16 mask, u16 val);
--void rtl8168_init_leds(struct net_device *ndev);
-+struct r8169_led_classdev *rtl8168_init_leds(struct net_device *ndev);
- int rtl8125_get_led_mode(struct rtl8169_private *tp, int index);
- int rtl8125_set_led_mode(struct rtl8169_private *tp, int index, u16 mode);
--void rtl8125_init_leds(struct net_device *ndev);
-+struct r8169_led_classdev *rtl8125_init_leds(struct net_device *ndev);
-+void r8169_remove_leds(struct r8169_led_classdev *leds);
---- a/drivers/net/ethernet/realtek/r8169_leds.c
-+++ b/drivers/net/ethernet/realtek/r8169_leds.c
-@@ -147,22 +147,22 @@ static void rtl8168_setup_ldev(struct r8
- led_cdev->hw_control_get_device = r8169_led_hw_control_get_device;
-
- /* ignore errors */
-- devm_led_classdev_register(&ndev->dev, led_cdev);
-+ led_classdev_register(&ndev->dev, led_cdev);
- }
-
--void rtl8168_init_leds(struct net_device *ndev)
-+struct r8169_led_classdev *rtl8168_init_leds(struct net_device *ndev)
- {
-- /* bind resource mgmt to netdev */
-- struct device *dev = &ndev->dev;
- struct r8169_led_classdev *leds;
- int i;
-
-- leds = devm_kcalloc(dev, RTL8168_NUM_LEDS, sizeof(*leds), GFP_KERNEL);
-+ leds = kcalloc(RTL8168_NUM_LEDS + 1, sizeof(*leds), GFP_KERNEL);
- if (!leds)
-- return;
-+ return NULL;
-
- for (i = 0; i < RTL8168_NUM_LEDS; i++)
- rtl8168_setup_ldev(leds + i, ndev, i);
-+
-+ return leds;
- }
-
- static int rtl8125_led_hw_control_is_supported(struct led_classdev *led_cdev,
-@@ -246,20 +246,31 @@ static void rtl8125_setup_led_ldev(struc
- led_cdev->hw_control_get_device = r8169_led_hw_control_get_device;
-
- /* ignore errors */
-- devm_led_classdev_register(&ndev->dev, led_cdev);
-+ led_classdev_register(&ndev->dev, led_cdev);
- }
-
--void rtl8125_init_leds(struct net_device *ndev)
-+struct r8169_led_classdev *rtl8125_init_leds(struct net_device *ndev)
- {
-- /* bind resource mgmt to netdev */
-- struct device *dev = &ndev->dev;
- struct r8169_led_classdev *leds;
- int i;
-
-- leds = devm_kcalloc(dev, RTL8125_NUM_LEDS, sizeof(*leds), GFP_KERNEL);
-+ leds = kcalloc(RTL8125_NUM_LEDS + 1, sizeof(*leds), GFP_KERNEL);
- if (!leds)
-- return;
-+ return NULL;
-
- for (i = 0; i < RTL8125_NUM_LEDS; i++)
- rtl8125_setup_led_ldev(leds + i, ndev, i);
-+
-+ return leds;
-+}
-+
-+void r8169_remove_leds(struct r8169_led_classdev *leds)
-+{
-+ if (!leds)
-+ return;
-+
-+ for (struct r8169_led_classdev *l = leds; l->ndev; l++)
-+ led_classdev_unregister(&l->led);
-+
-+ kfree(leds);
- }
---- a/drivers/net/ethernet/realtek/r8169_main.c
-+++ b/drivers/net/ethernet/realtek/r8169_main.c
-@@ -651,6 +651,8 @@ struct rtl8169_private {
- const char *fw_name;
- struct rtl_fw *rtl_fw;
-
-+ struct r8169_led_classdev *leds;
-+
- u32 ocp_base;
- };
-
-@@ -5126,6 +5128,8 @@ static void rtl_remove_one(struct pci_de
-
- cancel_work_sync(&tp->wk.work);
-
-+ r8169_remove_leds(tp->leds);
-+
- unregister_netdev(tp->dev);
-
- if (tp->dash_type != RTL_DASH_NONE)
-@@ -5586,9 +5590,9 @@ static int rtl_init_one(struct pci_dev *
-
- if (IS_ENABLED(CONFIG_R8169_LEDS)) {
- if (rtl_is_8125(tp))
-- rtl8125_init_leds(dev);
-+ tp->leds = rtl8125_init_leds(dev);
- else if (tp->mac_version > RTL_GIGA_MAC_VER_06)
-- rtl8168_init_leds(dev);
-+ tp->leds = rtl8168_init_leds(dev);
- }
-
- netdev_info(dev, "%s, %pM, XID %03x, IRQ %d\n",
diff --git a/target/linux/generic/backport-6.6/780-08-v6.9-r8169-add-support-for-RTL8126A.patch b/target/linux/generic/backport-6.6/780-08-v6.9-r8169-add-support-for-RTL8126A.patch
new file mode 100644
index 0000000000..65aa5449ec
--- /dev/null
+++ b/target/linux/generic/backport-6.6/780-08-v6.9-r8169-add-support-for-RTL8126A.patch
@@ -0,0 +1,355 @@
+From 3907f1ffc0ecf466d5c04aadc44c4b9203f3ec9a Mon Sep 17 00:00:00 2001
+From: Heiner Kallweit <hkallweit1@gmail.com>
+Date: Thu, 1 Feb 2024 22:38:01 +0100
+Subject: [PATCH] r8169: add support for RTL8126A
+
+This adds support for the RTL8126A found on Asus z790 Maximus Formula.
+It was successfully tested w/o the firmware at 1000Mbps. Firmware file
+has been provided by Realtek and submitted to linux-firmware.
+2.5G and 5G modes are untested.
+
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/realtek/r8169.h | 1 +
+ drivers/net/ethernet/realtek/r8169_main.c | 105 ++++++++++++++----
+ .../net/ethernet/realtek/r8169_phy_config.c | 7 ++
+ 3 files changed, 89 insertions(+), 24 deletions(-)
+
+--- a/drivers/net/ethernet/realtek/r8169.h
++++ b/drivers/net/ethernet/realtek/r8169.h
+@@ -68,6 +68,7 @@ enum mac_version {
+ /* support for RTL_GIGA_MAC_VER_60 has been removed */
+ RTL_GIGA_MAC_VER_61,
+ RTL_GIGA_MAC_VER_63,
++ RTL_GIGA_MAC_VER_65,
+ RTL_GIGA_MAC_NONE
+ };
+
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -55,6 +55,7 @@
+ #define FIRMWARE_8107E_2 "rtl_nic/rtl8107e-2.fw"
+ #define FIRMWARE_8125A_3 "rtl_nic/rtl8125a-3.fw"
+ #define FIRMWARE_8125B_2 "rtl_nic/rtl8125b-2.fw"
++#define FIRMWARE_8126A_2 "rtl_nic/rtl8126a-2.fw"
+
+ #define TX_DMA_BURST 7 /* Maximum PCI burst, '7' is unlimited */
+ #define InterFrameGap 0x03 /* 3 means InterFrameGap = the shortest one */
+@@ -136,6 +137,7 @@ static const struct {
+ [RTL_GIGA_MAC_VER_61] = {"RTL8125A", FIRMWARE_8125A_3},
+ /* reserve 62 for CFG_METHOD_4 in the vendor driver */
+ [RTL_GIGA_MAC_VER_63] = {"RTL8125B", FIRMWARE_8125B_2},
++ [RTL_GIGA_MAC_VER_65] = {"RTL8126A", FIRMWARE_8126A_2},
+ };
+
+ static const struct pci_device_id rtl8169_pci_tbl[] = {
+@@ -158,6 +160,7 @@ static const struct pci_device_id rtl816
+ { PCI_VENDOR_ID_LINKSYS, 0x1032, PCI_ANY_ID, 0x0024 },
+ { 0x0001, 0x8168, PCI_ANY_ID, 0x2410 },
+ { PCI_VDEVICE(REALTEK, 0x8125) },
++ { PCI_VDEVICE(REALTEK, 0x8126) },
+ { PCI_VDEVICE(REALTEK, 0x3000) },
+ {}
+ };
+@@ -327,8 +330,12 @@ enum rtl8168_registers {
+ };
+
+ enum rtl8125_registers {
++ INT_CFG0_8125 = 0x34,
++#define INT_CFG0_ENABLE_8125 BIT(0)
++#define INT_CFG0_CLKREQEN BIT(3)
+ IntrMask_8125 = 0x38,
+ IntrStatus_8125 = 0x3c,
++ INT_CFG1_8125 = 0x7a,
+ TxPoll_8125 = 0x90,
+ MAC0_BKP = 0x19e0,
+ EEE_TXIDLE_TIMER_8125 = 0x6048,
+@@ -1139,7 +1146,7 @@ static void rtl_writephy(struct rtl8169_
+ case RTL_GIGA_MAC_VER_31:
+ r8168dp_2_mdio_write(tp, location, val);
+ break;
+- case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_63:
++ case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_65:
+ r8168g_mdio_write(tp, location, val);
+ break;
+ default:
+@@ -1154,7 +1161,7 @@ static int rtl_readphy(struct rtl8169_pr
+ case RTL_GIGA_MAC_VER_28:
+ case RTL_GIGA_MAC_VER_31:
+ return r8168dp_2_mdio_read(tp, location);
+- case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_63:
++ case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_65:
+ return r8168g_mdio_read(tp, location);
+ default:
+ return r8169_mdio_read(tp, location);
+@@ -1363,7 +1370,7 @@ static void rtl_set_d3_pll_down(struct r
+ case RTL_GIGA_MAC_VER_25 ... RTL_GIGA_MAC_VER_26:
+ case RTL_GIGA_MAC_VER_29 ... RTL_GIGA_MAC_VER_30:
+ case RTL_GIGA_MAC_VER_32 ... RTL_GIGA_MAC_VER_37:
+- case RTL_GIGA_MAC_VER_39 ... RTL_GIGA_MAC_VER_63:
++ case RTL_GIGA_MAC_VER_39 ... RTL_GIGA_MAC_VER_65:
+ if (enable)
+ RTL_W8(tp, PMCH, RTL_R8(tp, PMCH) & ~D3_NO_PLL_DOWN);
+ else
+@@ -1530,7 +1537,7 @@ static void __rtl8169_set_wol(struct rtl
+ break;
+ case RTL_GIGA_MAC_VER_34:
+ case RTL_GIGA_MAC_VER_37:
+- case RTL_GIGA_MAC_VER_39 ... RTL_GIGA_MAC_VER_63:
++ case RTL_GIGA_MAC_VER_39 ... RTL_GIGA_MAC_VER_65:
+ if (wolopts)
+ rtl_mod_config2(tp, 0, PME_SIGNAL);
+ else
+@@ -2096,6 +2103,9 @@ static enum mac_version rtl8169_get_mac_
+ u16 val;
+ enum mac_version ver;
+ } mac_info[] = {
++ /* 8126A family. */
++ { 0x7cf, 0x649, RTL_GIGA_MAC_VER_65 },
++
+ /* 8125B family. */
+ { 0x7cf, 0x641, RTL_GIGA_MAC_VER_63 },
+
+@@ -2366,6 +2376,7 @@ static void rtl_init_rxcfg(struct rtl816
+ RTL_W32(tp, RxConfig, RX_FETCH_DFLT_8125 | RX_DMA_BURST);
+ break;
+ case RTL_GIGA_MAC_VER_63:
++ case RTL_GIGA_MAC_VER_65:
+ RTL_W32(tp, RxConfig, RX_FETCH_DFLT_8125 | RX_DMA_BURST |
+ RX_PAUSE_SLOT_ON);
+ break;
+@@ -2552,7 +2563,7 @@ static void rtl_wait_txrx_fifo_empty(str
+ case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_61:
+ rtl_loop_wait_high(tp, &rtl_rxtx_empty_cond, 100, 42);
+ break;
+- case RTL_GIGA_MAC_VER_63:
++ case RTL_GIGA_MAC_VER_63 ... RTL_GIGA_MAC_VER_65:
+ RTL_W8(tp, ChipCmd, RTL_R8(tp, ChipCmd) | StopReq);
+ rtl_loop_wait_high(tp, &rtl_rxtx_empty_cond, 100, 42);
+ rtl_loop_wait_high(tp, &rtl_rxtx_empty_cond_2, 100, 42);
+@@ -2795,7 +2806,7 @@ static void rtl_enable_exit_l1(struct rt
+ case RTL_GIGA_MAC_VER_37 ... RTL_GIGA_MAC_VER_38:
+ rtl_eri_set_bits(tp, 0xd4, 0x0c00);
+ break;
+- case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_63:
++ case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_65:
+ r8168_mac_ocp_modify(tp, 0xc0ac, 0, 0x1f80);
+ break;
+ default:
+@@ -2809,7 +2820,7 @@ static void rtl_disable_exit_l1(struct r
+ case RTL_GIGA_MAC_VER_34 ... RTL_GIGA_MAC_VER_38:
+ rtl_eri_clear_bits(tp, 0xd4, 0x1f00);
+ break;
+- case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_63:
++ case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_65:
+ r8168_mac_ocp_modify(tp, 0xc0ac, 0x1f80, 0);
+ break;
+ default:
+@@ -2819,6 +2830,8 @@ static void rtl_disable_exit_l1(struct r
+
+ static void rtl_hw_aspm_clkreq_enable(struct rtl8169_private *tp, bool enable)
+ {
++ u8 val8;
++
+ if (tp->mac_version < RTL_GIGA_MAC_VER_32)
+ return;
+
+@@ -2832,11 +2845,19 @@ static void rtl_hw_aspm_clkreq_enable(st
+ return;
+
+ rtl_mod_config5(tp, 0, ASPM_en);
+- rtl_mod_config2(tp, 0, ClkReqEn);
++ switch (tp->mac_version) {
++ case RTL_GIGA_MAC_VER_65:
++ val8 = RTL_R8(tp, INT_CFG0_8125) | INT_CFG0_CLKREQEN;
++ RTL_W8(tp, INT_CFG0_8125, val8);
++ break;
++ default:
++ rtl_mod_config2(tp, 0, ClkReqEn);
++ break;
++ }
+
+ switch (tp->mac_version) {
+ case RTL_GIGA_MAC_VER_46 ... RTL_GIGA_MAC_VER_48:
+- case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_63:
++ case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_65:
+ /* reset ephy tx/rx disable timer */
+ r8168_mac_ocp_modify(tp, 0xe094, 0xff00, 0);
+ /* chip can trigger L1.2 */
+@@ -2848,14 +2869,22 @@ static void rtl_hw_aspm_clkreq_enable(st
+ } else {
+ switch (tp->mac_version) {
+ case RTL_GIGA_MAC_VER_46 ... RTL_GIGA_MAC_VER_48:
+- case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_63:
++ case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_65:
+ r8168_mac_ocp_modify(tp, 0xe092, 0x00ff, 0);
+ break;
+ default:
+ break;
+ }
+
+- rtl_mod_config2(tp, ClkReqEn, 0);
++ switch (tp->mac_version) {
++ case RTL_GIGA_MAC_VER_65:
++ val8 = RTL_R8(tp, INT_CFG0_8125) & ~INT_CFG0_CLKREQEN;
++ RTL_W8(tp, INT_CFG0_8125, val8);
++ break;
++ default:
++ rtl_mod_config2(tp, ClkReqEn, 0);
++ break;
++ }
+ rtl_mod_config5(tp, ASPM_en, 0);
+ }
+ }
+@@ -3568,10 +3597,15 @@ static void rtl_hw_start_8125_common(str
+ /* disable new tx descriptor format */
+ r8168_mac_ocp_modify(tp, 0xeb58, 0x0001, 0x0000);
+
+- if (tp->mac_version == RTL_GIGA_MAC_VER_63)
++ if (tp->mac_version == RTL_GIGA_MAC_VER_65)
++ RTL_W8(tp, 0xD8, RTL_R8(tp, 0xD8) & ~0x02);
++
++ if (tp->mac_version == RTL_GIGA_MAC_VER_65)
++ r8168_mac_ocp_modify(tp, 0xe614, 0x0700, 0x0400);
++ else if (tp->mac_version == RTL_GIGA_MAC_VER_63)
+ r8168_mac_ocp_modify(tp, 0xe614, 0x0700, 0x0200);
+ else
+- r8168_mac_ocp_modify(tp, 0xe614, 0x0700, 0x0400);
++ r8168_mac_ocp_modify(tp, 0xe614, 0x0700, 0x0300);
+
+ if (tp->mac_version == RTL_GIGA_MAC_VER_63)
+ r8168_mac_ocp_modify(tp, 0xe63e, 0x0c30, 0x0000);
+@@ -3584,6 +3618,10 @@ static void rtl_hw_start_8125_common(str
+ r8168_mac_ocp_modify(tp, 0xe056, 0x00f0, 0x0030);
+ r8168_mac_ocp_modify(tp, 0xe040, 0x1000, 0x0000);
+ r8168_mac_ocp_modify(tp, 0xea1c, 0x0003, 0x0001);
++ if (tp->mac_version == RTL_GIGA_MAC_VER_65)
++ r8168_mac_ocp_modify(tp, 0xea1c, 0x0300, 0x0000);
++ else
++ r8168_mac_ocp_modify(tp, 0xea1c, 0x0004, 0x0000);
+ r8168_mac_ocp_modify(tp, 0xe0c0, 0x4f0f, 0x4403);
+ r8168_mac_ocp_modify(tp, 0xe052, 0x0080, 0x0068);
+ r8168_mac_ocp_modify(tp, 0xd430, 0x0fff, 0x047f);
+@@ -3598,10 +3636,10 @@ static void rtl_hw_start_8125_common(str
+
+ rtl_loop_wait_low(tp, &rtl_mac_ocp_e00e_cond, 1000, 10);
+
+- if (tp->mac_version == RTL_GIGA_MAC_VER_63)
+- rtl8125b_config_eee_mac(tp);
+- else
++ if (tp->mac_version == RTL_GIGA_MAC_VER_61)
+ rtl8125a_config_eee_mac(tp);
++ else
++ rtl8125b_config_eee_mac(tp);
+
+ rtl_disable_rxdvgate(tp);
+ }
+@@ -3645,6 +3683,12 @@ static void rtl_hw_start_8125b(struct rt
+ rtl_hw_start_8125_common(tp);
+ }
+
++static void rtl_hw_start_8126a(struct rtl8169_private *tp)
++{
++ rtl_set_def_aspm_entry_latency(tp);
++ rtl_hw_start_8125_common(tp);
++}
++
+ static void rtl_hw_config(struct rtl8169_private *tp)
+ {
+ static const rtl_generic_fct hw_configs[] = {
+@@ -3687,6 +3731,7 @@ static void rtl_hw_config(struct rtl8169
+ [RTL_GIGA_MAC_VER_53] = rtl_hw_start_8117,
+ [RTL_GIGA_MAC_VER_61] = rtl_hw_start_8125a_2,
+ [RTL_GIGA_MAC_VER_63] = rtl_hw_start_8125b,
++ [RTL_GIGA_MAC_VER_65] = rtl_hw_start_8126a,
+ };
+
+ if (hw_configs[tp->mac_version])
+@@ -3697,9 +3742,23 @@ static void rtl_hw_start_8125(struct rtl
+ {
+ int i;
+
++ RTL_W8(tp, INT_CFG0_8125, 0x00);
++
+ /* disable interrupt coalescing */
+- for (i = 0xa00; i < 0xb00; i += 4)
+- RTL_W32(tp, i, 0);
++ switch (tp->mac_version) {
++ case RTL_GIGA_MAC_VER_61:
++ for (i = 0xa00; i < 0xb00; i += 4)
++ RTL_W32(tp, i, 0);
++ break;
++ case RTL_GIGA_MAC_VER_63:
++ case RTL_GIGA_MAC_VER_65:
++ for (i = 0xa00; i < 0xa80; i += 4)
++ RTL_W32(tp, i, 0);
++ RTL_W16(tp, INT_CFG1_8125, 0x0000);
++ break;
++ default:
++ break;
++ }
+
+ rtl_hw_config(tp);
+ }
+@@ -3777,8 +3836,7 @@ static int rtl8169_change_mtu(struct net
+ rtl_jumbo_config(tp);
+
+ switch (tp->mac_version) {
+- case RTL_GIGA_MAC_VER_61:
+- case RTL_GIGA_MAC_VER_63:
++ case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_65:
+ rtl8125_set_eee_txidle_timer(tp);
+ break;
+ default:
+@@ -3927,7 +3985,7 @@ static void rtl8169_cleanup(struct rtl81
+ RTL_W8(tp, ChipCmd, RTL_R8(tp, ChipCmd) | StopReq);
+ rtl_loop_wait_high(tp, &rtl_txcfg_empty_cond, 100, 666);
+ break;
+- case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_63:
++ case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_65:
+ rtl_enable_rxdvgate(tp);
+ fsleep(2000);
+ break;
+@@ -4078,8 +4136,7 @@ static unsigned int rtl_quirk_packet_pad
+
+ switch (tp->mac_version) {
+ case RTL_GIGA_MAC_VER_34:
+- case RTL_GIGA_MAC_VER_61:
+- case RTL_GIGA_MAC_VER_63:
++ case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_65:
+ padto = max_t(unsigned int, padto, ETH_ZLEN);
+ break;
+ default:
+@@ -5112,7 +5169,7 @@ static void rtl_hw_initialize(struct rtl
+ case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_48:
+ rtl_hw_init_8168g(tp);
+ break;
+- case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_63:
++ case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_65:
+ rtl_hw_init_8125(tp);
+ break;
+ default:
+--- a/drivers/net/ethernet/realtek/r8169_phy_config.c
++++ b/drivers/net/ethernet/realtek/r8169_phy_config.c
+@@ -1102,6 +1102,12 @@ static void rtl8125b_hw_phy_config(struc
+ rtl8125b_config_eee_phy(phydev);
+ }
+
++static void rtl8126a_hw_phy_config(struct rtl8169_private *tp,
++ struct phy_device *phydev)
++{
++ r8169_apply_firmware(tp);
++}
++
+ void r8169_hw_phy_config(struct rtl8169_private *tp, struct phy_device *phydev,
+ enum mac_version ver)
+ {
+@@ -1152,6 +1158,7 @@ void r8169_hw_phy_config(struct rtl8169_
+ [RTL_GIGA_MAC_VER_53] = rtl8117_hw_phy_config,
+ [RTL_GIGA_MAC_VER_61] = rtl8125a_2_hw_phy_config,
+ [RTL_GIGA_MAC_VER_63] = rtl8125b_hw_phy_config,
++ [RTL_GIGA_MAC_VER_65] = rtl8126a_hw_phy_config,
+ };
+
+ if (phy_configs[ver])
diff --git a/target/linux/generic/backport-6.6/780-09-v6.10-r8169-add-missing-conditional-compiling-for-call-to-.patch b/target/linux/generic/backport-6.6/780-09-v6.10-r8169-add-missing-conditional-compiling-for-call-to-.patch
deleted file mode 100644
index cfe552046e..0000000000
--- a/target/linux/generic/backport-6.6/780-09-v6.10-r8169-add-missing-conditional-compiling-for-call-to-.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From 97e176fcbbf3c0f2bd410c9b241177c051f57176 Mon Sep 17 00:00:00 2001
-From: Heiner Kallweit <hkallweit1@gmail.com>
-Date: Wed, 10 Apr 2024 15:11:28 +0200
-Subject: [PATCH] r8169: add missing conditional compiling for call to
- r8169_remove_leds
-
-Add missing dependency on CONFIG_R8169_LEDS. As-is a link error occurs
-if config option CONFIG_R8169_LEDS isn't enabled.
-
-Fixes: 19fa4f2a85d7 ("r8169: fix LED-related deadlock on module removal")
-Reported-by: Venkat Rao Bagalkote <venkat88@linux.vnet.ibm.com>
-Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
-Tested-By: Venkat Rao Bagalkote <venkat88@linux.vnet.ibm.com>
-Link: https://lore.kernel.org/r/d080038c-eb6b-45ac-9237-b8c1cdd7870f@gmail.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/realtek/r8169_main.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/realtek/r8169_main.c
-+++ b/drivers/net/ethernet/realtek/r8169_main.c
-@@ -5128,7 +5128,8 @@ static void rtl_remove_one(struct pci_de
-
- cancel_work_sync(&tp->wk.work);
-
-- r8169_remove_leds(tp->leds);
-+ if (IS_ENABLED(CONFIG_R8169_LEDS))
-+ r8169_remove_leds(tp->leds);
-
- unregister_netdev(tp->dev);
-
diff --git a/target/linux/generic/backport-6.6/780-04-v6.9-r8169-improve-checking-for-valid-LED-modes.patch b/target/linux/generic/backport-6.6/780-09-v6.9-r8169-improve-checking-for-valid-LED-modes.patch
index ae0c821267..ae0c821267 100644
--- a/target/linux/generic/backport-6.6/780-04-v6.9-r8169-improve-checking-for-valid-LED-modes.patch
+++ b/target/linux/generic/backport-6.6/780-09-v6.9-r8169-improve-checking-for-valid-LED-modes.patch
diff --git a/target/linux/generic/backport-6.6/780-10-v6.9-r8169-simplify-code-by-using-core-provided-pcpu-stat.patch b/target/linux/generic/backport-6.6/780-10-v6.9-r8169-simplify-code-by-using-core-provided-pcpu-stat.patch
new file mode 100644
index 0000000000..510123767a
--- /dev/null
+++ b/target/linux/generic/backport-6.6/780-10-v6.9-r8169-simplify-code-by-using-core-provided-pcpu-stat.patch
@@ -0,0 +1,39 @@
+From 400909df6e6543cb5cce3db9bbcd413d59125327 Mon Sep 17 00:00:00 2001
+From: Heiner Kallweit <hkallweit1@gmail.com>
+Date: Sat, 10 Feb 2024 17:58:29 +0100
+Subject: [PATCH] r8169: simplify code by using core-provided pcpu stats
+ allocation
+
+Use core-provided pcpu stats allocation instead of open-coding it in
+the driver.
+
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Link: https://lore.kernel.org/r/03f5bb3b-d7f4-48be-ae8a-54862ec4566c@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+---
+ drivers/net/ethernet/realtek/r8169_main.c | 7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -5261,11 +5261,6 @@ static int rtl_init_one(struct pci_dev *
+ raw_spin_lock_init(&tp->mac_ocp_lock);
+ mutex_init(&tp->led_lock);
+
+- dev->tstats = devm_netdev_alloc_pcpu_stats(&pdev->dev,
+- struct pcpu_sw_netstats);
+- if (!dev->tstats)
+- return -ENOMEM;
+-
+ /* Get the *optional* external "ether_clk" used on some boards */
+ tp->clk = devm_clk_get_optional_enabled(&pdev->dev, "ether_clk");
+ if (IS_ERR(tp->clk))
+@@ -5380,6 +5375,8 @@ static int rtl_init_one(struct pci_dev *
+ dev->hw_features |= NETIF_F_RXALL;
+ dev->hw_features |= NETIF_F_RXFCS;
+
++ dev->pcpu_stat_type = NETDEV_PCPU_STAT_TSTATS;
++
+ netdev_sw_irq_coalesce_default_on(dev);
+
+ /* configure chip for default features */
diff --git a/target/linux/generic/backport-6.6/780-11-v6.9-r8169-add-LED-support-for-RTL8125-RTL8126.patch b/target/linux/generic/backport-6.6/780-11-v6.9-r8169-add-LED-support-for-RTL8125-RTL8126.patch
new file mode 100644
index 0000000000..2059551b50
--- /dev/null
+++ b/target/linux/generic/backport-6.6/780-11-v6.9-r8169-add-LED-support-for-RTL8125-RTL8126.patch
@@ -0,0 +1,244 @@
+From be51ed104ba9929c741afb718ef7198dbcecef94 Mon Sep 17 00:00:00 2001
+From: Heiner Kallweit <hkallweit1@gmail.com>
+Date: Mon, 12 Feb 2024 19:44:11 +0100
+Subject: [PATCH] r8169: add LED support for RTL8125/RTL8126
+
+This adds LED support for RTL8125/RTL8126.
+
+Note: Due to missing datasheets changing the 5Gbps link mode isn't
+supported for RTL8126.
+
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://lore.kernel.org/r/f982602c-9de3-4ca6-85a3-2c1d118dcb15@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/realtek/r8169.h | 3 +
+ drivers/net/ethernet/realtek/r8169_leds.c | 106 ++++++++++++++++++++++
+ drivers/net/ethernet/realtek/r8169_main.c | 61 ++++++++++++-
+ 3 files changed, 166 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/ethernet/realtek/r8169.h
++++ b/drivers/net/ethernet/realtek/r8169.h
+@@ -85,3 +85,6 @@ void r8169_get_led_name(struct rtl8169_p
+ int rtl8168_get_led_mode(struct rtl8169_private *tp);
+ int rtl8168_led_mod_ctrl(struct rtl8169_private *tp, u16 mask, u16 val);
+ void rtl8168_init_leds(struct net_device *ndev);
++int rtl8125_get_led_mode(struct rtl8169_private *tp, int index);
++int rtl8125_set_led_mode(struct rtl8169_private *tp, int index, u16 mode);
++void rtl8125_init_leds(struct net_device *ndev);
+--- a/drivers/net/ethernet/realtek/r8169_leds.c
++++ b/drivers/net/ethernet/realtek/r8169_leds.c
+@@ -18,7 +18,14 @@
+ #define RTL8168_LED_CTRL_LINK_100 BIT(1)
+ #define RTL8168_LED_CTRL_LINK_10 BIT(0)
+
++#define RTL8125_LED_CTRL_ACT BIT(9)
++#define RTL8125_LED_CTRL_LINK_2500 BIT(5)
++#define RTL8125_LED_CTRL_LINK_1000 BIT(3)
++#define RTL8125_LED_CTRL_LINK_100 BIT(1)
++#define RTL8125_LED_CTRL_LINK_10 BIT(0)
++
+ #define RTL8168_NUM_LEDS 3
++#define RTL8125_NUM_LEDS 4
+
+ struct r8169_led_classdev {
+ struct led_classdev led;
+@@ -157,3 +164,102 @@ void rtl8168_init_leds(struct net_device
+ for (i = 0; i < RTL8168_NUM_LEDS; i++)
+ rtl8168_setup_ldev(leds + i, ndev, i);
+ }
++
++static int rtl8125_led_hw_control_is_supported(struct led_classdev *led_cdev,
++ unsigned long flags)
++{
++ struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev);
++ struct rtl8169_private *tp = netdev_priv(ldev->ndev);
++
++ if (!r8169_trigger_mode_is_valid(flags)) {
++ /* Switch LED off to indicate that mode isn't supported */
++ rtl8125_set_led_mode(tp, ldev->index, 0);
++ return -EOPNOTSUPP;
++ }
++
++ return 0;
++}
++
++static int rtl8125_led_hw_control_set(struct led_classdev *led_cdev,
++ unsigned long flags)
++{
++ struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev);
++ struct rtl8169_private *tp = netdev_priv(ldev->ndev);
++ u16 mode = 0;
++
++ if (flags & BIT(TRIGGER_NETDEV_LINK_10))
++ mode |= RTL8125_LED_CTRL_LINK_10;
++ if (flags & BIT(TRIGGER_NETDEV_LINK_100))
++ mode |= RTL8125_LED_CTRL_LINK_100;
++ if (flags & BIT(TRIGGER_NETDEV_LINK_1000))
++ mode |= RTL8125_LED_CTRL_LINK_1000;
++ if (flags & BIT(TRIGGER_NETDEV_LINK_2500))
++ mode |= RTL8125_LED_CTRL_LINK_2500;
++ if (flags & (BIT(TRIGGER_NETDEV_TX) | BIT(TRIGGER_NETDEV_RX)))
++ mode |= RTL8125_LED_CTRL_ACT;
++
++ return rtl8125_set_led_mode(tp, ldev->index, mode);
++}
++
++static int rtl8125_led_hw_control_get(struct led_classdev *led_cdev,
++ unsigned long *flags)
++{
++ struct r8169_led_classdev *ldev = lcdev_to_r8169_ldev(led_cdev);
++ struct rtl8169_private *tp = netdev_priv(ldev->ndev);
++ int mode;
++
++ mode = rtl8125_get_led_mode(tp, ldev->index);
++ if (mode < 0)
++ return mode;
++
++ if (mode & RTL8125_LED_CTRL_LINK_10)
++ *flags |= BIT(TRIGGER_NETDEV_LINK_10);
++ if (mode & RTL8125_LED_CTRL_LINK_100)
++ *flags |= BIT(TRIGGER_NETDEV_LINK_100);
++ if (mode & RTL8125_LED_CTRL_LINK_1000)
++ *flags |= BIT(TRIGGER_NETDEV_LINK_1000);
++ if (mode & RTL8125_LED_CTRL_LINK_2500)
++ *flags |= BIT(TRIGGER_NETDEV_LINK_2500);
++ if (mode & RTL8125_LED_CTRL_ACT)
++ *flags |= BIT(TRIGGER_NETDEV_TX) | BIT(TRIGGER_NETDEV_RX);
++
++ return 0;
++}
++
++static void rtl8125_setup_led_ldev(struct r8169_led_classdev *ldev,
++ struct net_device *ndev, int index)
++{
++ struct rtl8169_private *tp = netdev_priv(ndev);
++ struct led_classdev *led_cdev = &ldev->led;
++ char led_name[LED_MAX_NAME_SIZE];
++
++ ldev->ndev = ndev;
++ ldev->index = index;
++
++ r8169_get_led_name(tp, index, led_name, LED_MAX_NAME_SIZE);
++ led_cdev->name = led_name;
++ led_cdev->hw_control_trigger = "netdev";
++ led_cdev->flags |= LED_RETAIN_AT_SHUTDOWN;
++ led_cdev->hw_control_is_supported = rtl8125_led_hw_control_is_supported;
++ led_cdev->hw_control_set = rtl8125_led_hw_control_set;
++ led_cdev->hw_control_get = rtl8125_led_hw_control_get;
++ led_cdev->hw_control_get_device = r8169_led_hw_control_get_device;
++
++ /* ignore errors */
++ devm_led_classdev_register(&ndev->dev, led_cdev);
++}
++
++void rtl8125_init_leds(struct net_device *ndev)
++{
++ /* bind resource mgmt to netdev */
++ struct device *dev = &ndev->dev;
++ struct r8169_led_classdev *leds;
++ int i;
++
++ leds = devm_kcalloc(dev, RTL8125_NUM_LEDS, sizeof(*leds), GFP_KERNEL);
++ if (!leds)
++ return;
++
++ for (i = 0; i < RTL8125_NUM_LEDS; i++)
++ rtl8125_setup_led_ldev(leds + i, ndev, i);
++}
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -330,17 +330,23 @@ enum rtl8168_registers {
+ };
+
+ enum rtl8125_registers {
++ LEDSEL0 = 0x18,
+ INT_CFG0_8125 = 0x34,
+ #define INT_CFG0_ENABLE_8125 BIT(0)
+ #define INT_CFG0_CLKREQEN BIT(3)
+ IntrMask_8125 = 0x38,
+ IntrStatus_8125 = 0x3c,
+ INT_CFG1_8125 = 0x7a,
++ LEDSEL2 = 0x84,
++ LEDSEL1 = 0x86,
+ TxPoll_8125 = 0x90,
++ LEDSEL3 = 0x96,
+ MAC0_BKP = 0x19e0,
+ EEE_TXIDLE_TIMER_8125 = 0x6048,
+ };
+
++#define LEDSEL_MASK_8125 0x23f
++
+ #define RX_VLAN_INNER_8125 BIT(22)
+ #define RX_VLAN_OUTER_8125 BIT(23)
+ #define RX_VLAN_8125 (RX_VLAN_INNER_8125 | RX_VLAN_OUTER_8125)
+@@ -830,6 +836,51 @@ int rtl8168_get_led_mode(struct rtl8169_
+ return ret;
+ }
+
++static int rtl8125_get_led_reg(int index)
++{
++ static const int led_regs[] = { LEDSEL0, LEDSEL1, LEDSEL2, LEDSEL3 };
++
++ return led_regs[index];
++}
++
++int rtl8125_set_led_mode(struct rtl8169_private *tp, int index, u16 mode)
++{
++ int reg = rtl8125_get_led_reg(index);
++ struct device *dev = tp_to_dev(tp);
++ int ret;
++ u16 val;
++
++ ret = pm_runtime_resume_and_get(dev);
++ if (ret < 0)
++ return ret;
++
++ mutex_lock(&tp->led_lock);
++ val = RTL_R16(tp, reg) & ~LEDSEL_MASK_8125;
++ RTL_W16(tp, reg, val | mode);
++ mutex_unlock(&tp->led_lock);
++
++ pm_runtime_put_sync(dev);
++
++ return 0;
++}
++
++int rtl8125_get_led_mode(struct rtl8169_private *tp, int index)
++{
++ int reg = rtl8125_get_led_reg(index);
++ struct device *dev = tp_to_dev(tp);
++ int ret;
++
++ ret = pm_runtime_resume_and_get(dev);
++ if (ret < 0)
++ return ret;
++
++ ret = RTL_R16(tp, reg);
++
++ pm_runtime_put_sync(dev);
++
++ return ret;
++}
++
+ void r8169_get_led_name(struct rtl8169_private *tp, int idx,
+ char *buf, int buf_len)
+ {
+@@ -5413,10 +5464,12 @@ static int rtl_init_one(struct pci_dev *
+ if (rc)
+ return rc;
+
+- if (IS_ENABLED(CONFIG_R8169_LEDS) &&
+- tp->mac_version > RTL_GIGA_MAC_VER_06 &&
+- tp->mac_version < RTL_GIGA_MAC_VER_61)
+- rtl8168_init_leds(dev);
++ if (IS_ENABLED(CONFIG_R8169_LEDS)) {
++ if (rtl_is_8125(tp))
++ rtl8125_init_leds(dev);
++ else if (tp->mac_version > RTL_GIGA_MAC_VER_06)
++ rtl8168_init_leds(dev);
++ }
+
+ netdev_info(dev, "%s, %pM, XID %03x, IRQ %d\n",
+ rtl_chip_infos[chipset].name, dev->dev_addr, xid, tp->irq);
diff --git a/target/linux/generic/backport-6.6/780-12-v6.9-r8169-add-generic-rtl_set_eee_txidle_timer-function.patch b/target/linux/generic/backport-6.6/780-12-v6.9-r8169-add-generic-rtl_set_eee_txidle_timer-function.patch
new file mode 100644
index 0000000000..1a7eed191f
--- /dev/null
+++ b/target/linux/generic/backport-6.6/780-12-v6.9-r8169-add-generic-rtl_set_eee_txidle_timer-function.patch
@@ -0,0 +1,91 @@
+From 2ce30993831041b9dcd31eb12896be6611e8b7e2 Mon Sep 17 00:00:00 2001
+From: Heiner Kallweit <hkallweit1@gmail.com>
+Date: Mon, 12 Feb 2024 19:57:46 +0100
+Subject: [PATCH] r8169: add generic rtl_set_eee_txidle_timer function
+
+Add a generic setter for the EEE tx idle timer and use it with all
+RTL8125/RTL8126 chip versions, in line with the vendor driver.
+This prepares for adding EEE tx idle timer support for additional
+chip versions.
+
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://lore.kernel.org/r/39beed72-0dc4-4c45-8899-b72c43ab62a7@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/realtek/r8169_main.c | 34 +++++++++++++----------
+ 1 file changed, 20 insertions(+), 14 deletions(-)
+
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -619,6 +619,7 @@ struct rtl8169_private {
+ struct page *Rx_databuff[NUM_RX_DESC]; /* Rx data buffers */
+ struct ring_info tx_skb[NUM_TX_DESC]; /* Tx data buffers */
+ u16 cp_cmd;
++ u16 tx_lpi_timer;
+ u32 irq_mask;
+ int irq;
+ struct clk *clk;
+@@ -2054,6 +2055,22 @@ static int rtl_set_coalesce(struct net_d
+ return 0;
+ }
+
++static void rtl_set_eee_txidle_timer(struct rtl8169_private *tp)
++{
++ unsigned int timer_val = READ_ONCE(tp->dev->mtu) + ETH_HLEN + 0x20;
++
++ switch (tp->mac_version) {
++ case RTL_GIGA_MAC_VER_61:
++ case RTL_GIGA_MAC_VER_63:
++ case RTL_GIGA_MAC_VER_65:
++ tp->tx_lpi_timer = timer_val;
++ RTL_W16(tp, EEE_TXIDLE_TIMER_8125, timer_val);
++ break;
++ default:
++ break;
++ }
++}
++
+ static int rtl8169_get_eee(struct net_device *dev, struct ethtool_eee *data)
+ {
+ struct rtl8169_private *tp = netdev_priv(dev);
+@@ -2312,14 +2329,8 @@ static void rtl8125a_config_eee_mac(stru
+ r8168_mac_ocp_modify(tp, 0xeb62, 0, BIT(2) | BIT(1));
+ }
+
+-static void rtl8125_set_eee_txidle_timer(struct rtl8169_private *tp)
+-{
+- RTL_W16(tp, EEE_TXIDLE_TIMER_8125, tp->dev->mtu + ETH_HLEN + 0x20);
+-}
+-
+ static void rtl8125b_config_eee_mac(struct rtl8169_private *tp)
+ {
+- rtl8125_set_eee_txidle_timer(tp);
+ r8168_mac_ocp_modify(tp, 0xe040, 0, BIT(1) | BIT(0));
+ }
+
+@@ -3852,6 +3863,8 @@ static void rtl_hw_start(struct rtl8169
+ rtl_hw_aspm_clkreq_enable(tp, false);
+ RTL_W16(tp, CPlusCmd, tp->cp_cmd);
+
++ rtl_set_eee_txidle_timer(tp);
++
+ if (tp->mac_version <= RTL_GIGA_MAC_VER_06)
+ rtl_hw_start_8169(tp);
+ else if (rtl_is_8125(tp))
+@@ -3885,14 +3898,7 @@ static int rtl8169_change_mtu(struct net
+ dev->mtu = new_mtu;
+ netdev_update_features(dev);
+ rtl_jumbo_config(tp);
+-
+- switch (tp->mac_version) {
+- case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_65:
+- rtl8125_set_eee_txidle_timer(tp);
+- break;
+- default:
+- break;
+- }
++ rtl_set_eee_txidle_timer(tp);
+
+ return 0;
+ }
diff --git a/target/linux/generic/backport-6.6/780-13-v6.9-r8169-support-setting-the-EEE-tx-idle-timer-on-RTL81.patch b/target/linux/generic/backport-6.6/780-13-v6.9-r8169-support-setting-the-EEE-tx-idle-timer-on-RTL81.patch
new file mode 100644
index 0000000000..917c7c194f
--- /dev/null
+++ b/target/linux/generic/backport-6.6/780-13-v6.9-r8169-support-setting-the-EEE-tx-idle-timer-on-RTL81.patch
@@ -0,0 +1,30 @@
+From 57d2d2c8f132c830565058a5cdd8138350e068ec Mon Sep 17 00:00:00 2001
+From: Heiner Kallweit <hkallweit1@gmail.com>
+Date: Mon, 12 Feb 2024 19:58:47 +0100
+Subject: [PATCH] r8169: support setting the EEE tx idle timer on
+ RTL8168h
+
+Support setting the EEE tx idle timer also on RTL8168h.
+
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://lore.kernel.org/r/cfb69ec9-24c4-4aad-9909-fdae3088add4@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/realtek/r8169_main.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -2060,6 +2060,11 @@ static void rtl_set_eee_txidle_timer(str
+ unsigned int timer_val = READ_ONCE(tp->dev->mtu) + ETH_HLEN + 0x20;
+
+ switch (tp->mac_version) {
++ case RTL_GIGA_MAC_VER_46:
++ case RTL_GIGA_MAC_VER_48:
++ tp->tx_lpi_timer = timer_val;
++ r8168_mac_ocp_write(tp, 0xe048, timer_val);
++ break;
+ case RTL_GIGA_MAC_VER_61:
+ case RTL_GIGA_MAC_VER_63:
+ case RTL_GIGA_MAC_VER_65:
diff --git a/target/linux/generic/backport-6.6/780-14-v6.9-r8169-add-support-for-returning-tx_lpi_timer-in-etht.patch b/target/linux/generic/backport-6.6/780-14-v6.9-r8169-add-support-for-returning-tx_lpi_timer-in-etht.patch
new file mode 100644
index 0000000000..51477d0142
--- /dev/null
+++ b/target/linux/generic/backport-6.6/780-14-v6.9-r8169-add-support-for-returning-tx_lpi_timer-in-etht.patch
@@ -0,0 +1,55 @@
+From 9c50139727265c088f936e496777bf588850e9f1 Mon Sep 17 00:00:00 2001
+From: Heiner Kallweit <hkallweit1@gmail.com>
+Date: Mon, 12 Feb 2024 19:59:26 +0100
+Subject: [PATCH] r8169: add support for returning tx_lpi_timer in
+ ethtool get_eee
+
+Add support for returning the tx_lpi_timer value to userspace.
+This is supported by few chip versions only: RTL8168h/RTL8125/RTL8126
+
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://lore.kernel.org/r/4eee9c34-c5d6-4c96-9b05-455896dea59a@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/realtek/r8169_main.c | 22 +++++++++++++++++++++-
+ 1 file changed, 21 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -2076,14 +2076,34 @@ static void rtl_set_eee_txidle_timer(str
+ }
+ }
+
++static unsigned int r8169_get_tx_lpi_timer_us(struct rtl8169_private *tp)
++{
++ unsigned int speed = tp->phydev->speed;
++ unsigned int timer = tp->tx_lpi_timer;
++
++ if (!timer || speed == SPEED_UNKNOWN)
++ return 0;
++
++ /* tx_lpi_timer value is in bytes */
++ return DIV_ROUND_CLOSEST(timer * BITS_PER_BYTE, speed);
++}
++
+ static int rtl8169_get_eee(struct net_device *dev, struct ethtool_eee *data)
+ {
+ struct rtl8169_private *tp = netdev_priv(dev);
++ int ret;
+
+ if (!rtl_supports_eee(tp))
+ return -EOPNOTSUPP;
+
+- return phy_ethtool_get_eee(tp->phydev, data);
++ ret = phy_ethtool_get_eee(tp->phydev, data);
++ if (ret)
++ return ret;
++
++ data->tx_lpi_timer = r8169_get_tx_lpi_timer_us(tp);
++ data->tx_lpi_enabled = data->tx_lpi_timer ? data->eee_enabled : false;
++
++ return 0;
+ }
+
+ static int rtl8169_set_eee(struct net_device *dev, struct ethtool_eee *data)
diff --git a/target/linux/generic/backport-6.6/780-15-v6.9-r8169-add-MODULE_FIRMWARE-entry-for-RTL8126A.patch b/target/linux/generic/backport-6.6/780-15-v6.9-r8169-add-MODULE_FIRMWARE-entry-for-RTL8126A.patch
new file mode 100644
index 0000000000..6a7ebc885b
--- /dev/null
+++ b/target/linux/generic/backport-6.6/780-15-v6.9-r8169-add-MODULE_FIRMWARE-entry-for-RTL8126A.patch
@@ -0,0 +1,25 @@
+From f4d3e595c0000ce39dec7e4799ea42ce42ab6867 Mon Sep 17 00:00:00 2001
+From: Heiner Kallweit <hkallweit1@gmail.com>
+Date: Sat, 17 Feb 2024 15:48:23 +0100
+Subject: [PATCH] r8169: add MODULE_FIRMWARE entry for RTL8126A
+
+Add the missing MODULE_FIRMWARE entry for RTL8126A.
+
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://lore.kernel.org/r/47ef79d2-59c4-4d44-9595-366c70c4ad87@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/realtek/r8169_main.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -676,6 +676,7 @@ MODULE_FIRMWARE(FIRMWARE_8168FP_3);
+ MODULE_FIRMWARE(FIRMWARE_8107E_2);
+ MODULE_FIRMWARE(FIRMWARE_8125A_3);
+ MODULE_FIRMWARE(FIRMWARE_8125B_2);
++MODULE_FIRMWARE(FIRMWARE_8126A_2);
+
+ static inline struct device *tp_to_dev(struct rtl8169_private *tp)
+ {
diff --git a/target/linux/generic/backport-6.6/780-16-v6.9-r8169-fix-LED-related-deadlock-on-module-removal.patch b/target/linux/generic/backport-6.6/780-16-v6.9-r8169-fix-LED-related-deadlock-on-module-removal.patch
new file mode 100644
index 0000000000..d8e4a4f6ff
--- /dev/null
+++ b/target/linux/generic/backport-6.6/780-16-v6.9-r8169-fix-LED-related-deadlock-on-module-removal.patch
@@ -0,0 +1,147 @@
+From 19fa4f2a85d777a8052e869c1b892a2f7556569d Mon Sep 17 00:00:00 2001
+From: Heiner Kallweit <hkallweit1@gmail.com>
+Date: Mon, 8 Apr 2024 20:47:40 +0200
+Subject: [PATCH] r8169: fix LED-related deadlock on module removal
+
+Binding devm_led_classdev_register() to the netdev is problematic
+because on module removal we get a RTNL-related deadlock. Fix this
+by avoiding the device-managed LED functions.
+
+Note: We can safely call led_classdev_unregister() for a LED even
+if registering it failed, because led_classdev_unregister() detects
+this and is a no-op in this case.
+
+Fixes: 18764b883e15 ("r8169: add support for LED's on RTL8168/RTL8101")
+Cc: stable@vger.kernel.org
+Reported-by: Lukas Wunner <lukas@wunner.de>
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/realtek/r8169.h | 6 ++--
+ drivers/net/ethernet/realtek/r8169_leds.c | 35 +++++++++++++++--------
+ drivers/net/ethernet/realtek/r8169_main.c | 8 ++++--
+ 3 files changed, 33 insertions(+), 16 deletions(-)
+
+--- a/drivers/net/ethernet/realtek/r8169.h
++++ b/drivers/net/ethernet/realtek/r8169.h
+@@ -73,6 +73,7 @@ enum mac_version {
+ };
+
+ struct rtl8169_private;
++struct r8169_led_classdev;
+
+ void r8169_apply_firmware(struct rtl8169_private *tp);
+ u16 rtl8168h_2_get_adc_bias_ioffset(struct rtl8169_private *tp);
+@@ -84,7 +85,8 @@ void r8169_get_led_name(struct rtl8169_p
+ char *buf, int buf_len);
+ int rtl8168_get_led_mode(struct rtl8169_private *tp);
+ int rtl8168_led_mod_ctrl(struct rtl8169_private *tp, u16 mask, u16 val);
+-void rtl8168_init_leds(struct net_device *ndev);
++struct r8169_led_classdev *rtl8168_init_leds(struct net_device *ndev);
+ int rtl8125_get_led_mode(struct rtl8169_private *tp, int index);
+ int rtl8125_set_led_mode(struct rtl8169_private *tp, int index, u16 mode);
+-void rtl8125_init_leds(struct net_device *ndev);
++struct r8169_led_classdev *rtl8125_init_leds(struct net_device *ndev);
++void r8169_remove_leds(struct r8169_led_classdev *leds);
+--- a/drivers/net/ethernet/realtek/r8169_leds.c
++++ b/drivers/net/ethernet/realtek/r8169_leds.c
+@@ -147,22 +147,22 @@ static void rtl8168_setup_ldev(struct r8
+ led_cdev->hw_control_get_device = r8169_led_hw_control_get_device;
+
+ /* ignore errors */
+- devm_led_classdev_register(&ndev->dev, led_cdev);
++ led_classdev_register(&ndev->dev, led_cdev);
+ }
+
+-void rtl8168_init_leds(struct net_device *ndev)
++struct r8169_led_classdev *rtl8168_init_leds(struct net_device *ndev)
+ {
+- /* bind resource mgmt to netdev */
+- struct device *dev = &ndev->dev;
+ struct r8169_led_classdev *leds;
+ int i;
+
+- leds = devm_kcalloc(dev, RTL8168_NUM_LEDS, sizeof(*leds), GFP_KERNEL);
++ leds = kcalloc(RTL8168_NUM_LEDS + 1, sizeof(*leds), GFP_KERNEL);
+ if (!leds)
+- return;
++ return NULL;
+
+ for (i = 0; i < RTL8168_NUM_LEDS; i++)
+ rtl8168_setup_ldev(leds + i, ndev, i);
++
++ return leds;
+ }
+
+ static int rtl8125_led_hw_control_is_supported(struct led_classdev *led_cdev,
+@@ -246,20 +246,31 @@ static void rtl8125_setup_led_ldev(struc
+ led_cdev->hw_control_get_device = r8169_led_hw_control_get_device;
+
+ /* ignore errors */
+- devm_led_classdev_register(&ndev->dev, led_cdev);
++ led_classdev_register(&ndev->dev, led_cdev);
+ }
+
+-void rtl8125_init_leds(struct net_device *ndev)
++struct r8169_led_classdev *rtl8125_init_leds(struct net_device *ndev)
+ {
+- /* bind resource mgmt to netdev */
+- struct device *dev = &ndev->dev;
+ struct r8169_led_classdev *leds;
+ int i;
+
+- leds = devm_kcalloc(dev, RTL8125_NUM_LEDS, sizeof(*leds), GFP_KERNEL);
++ leds = kcalloc(RTL8125_NUM_LEDS + 1, sizeof(*leds), GFP_KERNEL);
+ if (!leds)
+- return;
++ return NULL;
+
+ for (i = 0; i < RTL8125_NUM_LEDS; i++)
+ rtl8125_setup_led_ldev(leds + i, ndev, i);
++
++ return leds;
++}
++
++void r8169_remove_leds(struct r8169_led_classdev *leds)
++{
++ if (!leds)
++ return;
++
++ for (struct r8169_led_classdev *l = leds; l->ndev; l++)
++ led_classdev_unregister(&l->led);
++
++ kfree(leds);
+ }
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -647,6 +647,8 @@ struct rtl8169_private {
+ const char *fw_name;
+ struct rtl_fw *rtl_fw;
+
++ struct r8169_led_classdev *leds;
++
+ u32 ocp_base;
+ };
+
+@@ -5040,6 +5042,8 @@ static void rtl_remove_one(struct pci_de
+
+ cancel_work_sync(&tp->wk.work);
+
++ r8169_remove_leds(tp->leds);
++
+ unregister_netdev(tp->dev);
+
+ if (tp->dash_type != RTL_DASH_NONE)
+@@ -5498,9 +5502,9 @@ static int rtl_init_one(struct pci_dev *
+
+ if (IS_ENABLED(CONFIG_R8169_LEDS)) {
+ if (rtl_is_8125(tp))
+- rtl8125_init_leds(dev);
++ tp->leds = rtl8125_init_leds(dev);
+ else if (tp->mac_version > RTL_GIGA_MAC_VER_06)
+- rtl8168_init_leds(dev);
++ tp->leds = rtl8168_init_leds(dev);
+ }
+
+ netdev_info(dev, "%s, %pM, XID %03x, IRQ %d\n",
diff --git a/target/linux/generic/backport-6.6/780-17-v6.9-r8169-add-missing-conditional-compiling-for-call-to-.patch b/target/linux/generic/backport-6.6/780-17-v6.9-r8169-add-missing-conditional-compiling-for-call-to-.patch
new file mode 100644
index 0000000000..366ae803f9
--- /dev/null
+++ b/target/linux/generic/backport-6.6/780-17-v6.9-r8169-add-missing-conditional-compiling-for-call-to-.patch
@@ -0,0 +1,31 @@
+From 97e176fcbbf3c0f2bd410c9b241177c051f57176 Mon Sep 17 00:00:00 2001
+From: Heiner Kallweit <hkallweit1@gmail.com>
+Date: Wed, 10 Apr 2024 15:11:28 +0200
+Subject: [PATCH] r8169: add missing conditional compiling for call to
+ r8169_remove_leds
+
+Add missing dependency on CONFIG_R8169_LEDS. As-is a link error occurs
+if config option CONFIG_R8169_LEDS isn't enabled.
+
+Fixes: 19fa4f2a85d7 ("r8169: fix LED-related deadlock on module removal")
+Reported-by: Venkat Rao Bagalkote <venkat88@linux.vnet.ibm.com>
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Tested-By: Venkat Rao Bagalkote <venkat88@linux.vnet.ibm.com>
+Link: https://lore.kernel.org/r/d080038c-eb6b-45ac-9237-b8c1cdd7870f@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/realtek/r8169_main.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -5042,7 +5042,8 @@ static void rtl_remove_one(struct pci_de
+
+ cancel_work_sync(&tp->wk.work);
+
+- r8169_remove_leds(tp->leds);
++ if (IS_ENABLED(CONFIG_R8169_LEDS))
++ r8169_remove_leds(tp->leds);
+
+ unregister_netdev(tp->dev);
+
diff --git a/target/linux/generic/backport-6.6/780-18-v6.10-r8169-add-support-for-RTL8168M.patch b/target/linux/generic/backport-6.6/780-18-v6.10-r8169-add-support-for-RTL8168M.patch
new file mode 100644
index 0000000000..2abbe2ccf1
--- /dev/null
+++ b/target/linux/generic/backport-6.6/780-18-v6.10-r8169-add-support-for-RTL8168M.patch
@@ -0,0 +1,30 @@
+From 39f59c72ad3a1eaab9a60f0671bc94d2bc826d21 Mon Sep 17 00:00:00 2001
+From: Heiner Kallweit <hkallweit1@gmail.com>
+Date: Sun, 7 Apr 2024 23:19:25 +0200
+Subject: [PATCH] r8169: add support for RTL8168M
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+A user reported an unknown chip version. According to the r8168 vendor
+driver it's called RTL8168M, but handling is identical to RTL8168H.
+So let's simply treat it as RTL8168H.
+
+Tested-by: Евгений <octobergun@gmail.com>
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/realtek/r8169_main.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -2230,6 +2230,8 @@ static enum mac_version rtl8169_get_mac_
+ * the wild. Let's disable detection.
+ * { 0x7cf, 0x540, RTL_GIGA_MAC_VER_45 },
+ */
++ /* Realtek calls it RTL8168M, but it's handled like RTL8168H */
++ { 0x7cf, 0x6c0, RTL_GIGA_MAC_VER_46 },
+
+ /* 8168G family. */
+ { 0x7cf, 0x5c8, RTL_GIGA_MAC_VER_44 },
diff --git a/target/linux/generic/backport-6.6/780-19-v6.10-net-annotate-writes-on-dev-mtu-from-ndo_change_mtu.patch b/target/linux/generic/backport-6.6/780-19-v6.10-net-annotate-writes-on-dev-mtu-from-ndo_change_mtu.patch
new file mode 100644
index 0000000000..cad1210e4d
--- /dev/null
+++ b/target/linux/generic/backport-6.6/780-19-v6.10-net-annotate-writes-on-dev-mtu-from-ndo_change_mtu.patch
@@ -0,0 +1,60 @@
+From 1eb2cded45b35816085c1f962933c187d970f9dc Mon Sep 17 00:00:00 2001
+From: Eric Dumazet <edumazet@google.com>
+Date: Mon, 6 May 2024 10:28:12 +0000
+Subject: [PATCH] net: annotate writes on dev->mtu from ndo_change_mtu()
+
+Simon reported that ndo_change_mtu() methods were never
+updated to use WRITE_ONCE(dev->mtu, new_mtu) as hinted
+in commit 501a90c94510 ("inet: protect against too small
+mtu values.")
+
+We read dev->mtu without holding RTNL in many places,
+with READ_ONCE() annotations.
+
+It is time to take care of ndo_change_mtu() methods
+to use corresponding WRITE_ONCE()
+
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reported-by: Simon Horman <horms@kernel.org>
+Closes: https://lore.kernel.org/netdev/20240505144608.GB67882@kernel.org/
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Reviewed-by: Sabrina Dubroca <sd@queasysnail.net>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Acked-by: Shannon Nelson <shannon.nelson@amd.com>
+Link: https://lore.kernel.org/r/20240506102812.3025432-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/realtek/8139cp.c | 4 ++--
+ drivers/net/ethernet/realtek/r8169_main.c | 2 +-
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/ethernet/realtek/8139cp.c
++++ b/drivers/net/ethernet/realtek/8139cp.c
+@@ -1277,14 +1277,14 @@ static int cp_change_mtu(struct net_devi
+
+ /* if network interface not up, no need for complexity */
+ if (!netif_running(dev)) {
+- dev->mtu = new_mtu;
++ WRITE_ONCE(dev->mtu, new_mtu);
+ cp_set_rxbufsize(cp); /* set new rx buf size */
+ return 0;
+ }
+
+ /* network IS up, close it, reset MTU, and come up again. */
+ cp_close(dev);
+- dev->mtu = new_mtu;
++ WRITE_ONCE(dev->mtu, new_mtu);
+ cp_set_rxbufsize(cp);
+ return cp_open(dev);
+ }
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -3925,7 +3925,7 @@ static int rtl8169_change_mtu(struct net
+ {
+ struct rtl8169_private *tp = netdev_priv(dev);
+
+- dev->mtu = new_mtu;
++ WRITE_ONCE(dev->mtu, new_mtu);
+ netdev_update_features(dev);
+ rtl_jumbo_config(tp);
+ rtl_set_eee_txidle_timer(tp);
diff --git a/target/linux/generic/backport-6.6/780-20-v6.11-r8169-disable-interrupt-source-RxOverflow.patch b/target/linux/generic/backport-6.6/780-20-v6.11-r8169-disable-interrupt-source-RxOverflow.patch
new file mode 100644
index 0000000000..cef5d95252
--- /dev/null
+++ b/target/linux/generic/backport-6.6/780-20-v6.11-r8169-disable-interrupt-source-RxOverflow.patch
@@ -0,0 +1,34 @@
+From 6994520a332887f1688464f250c9ec8002a89a8e Mon Sep 17 00:00:00 2001
+From: Heiner Kallweit <hkallweit1@gmail.com>
+Date: Mon, 27 May 2024 21:16:56 +0200
+Subject: [PATCH] r8169: disable interrupt source RxOverflow
+
+Vendor driver calls this bit RxDescUnavail. All we do in the interrupt
+handler in this case is scheduling NAPI. If we should be out of
+RX descriptors, then NAPI is scheduled anyway. Therefore remove this
+interrupt source. Tested on RTL8168h.
+
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Reviewed-by: Sunil Goutham <sgoutham@marvell.com>
+Link: https://lore.kernel.org/r/9b2054b2-0548-4f48-bf91-b646572093b4@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/realtek/r8169_main.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -5083,12 +5083,10 @@ static void rtl_set_irq_mask(struct rtl8
+ tp->irq_mask = RxOK | RxErr | TxOK | TxErr | LinkChg;
+
+ if (tp->mac_version <= RTL_GIGA_MAC_VER_06)
+- tp->irq_mask |= SYSErr | RxOverflow | RxFIFOOver;
++ tp->irq_mask |= SYSErr | RxFIFOOver;
+ else if (tp->mac_version == RTL_GIGA_MAC_VER_11)
+ /* special workaround needed */
+ tp->irq_mask |= RxFIFOOver;
+- else
+- tp->irq_mask |= RxOverflow;
+ }
+
+ static int rtl_alloc_irq(struct rtl8169_private *tp)
diff --git a/target/linux/generic/backport-6.6/780-21-v6.11-r8169-remove-detection-of-chip-version-11-early-RTL8.patch b/target/linux/generic/backport-6.6/780-21-v6.11-r8169-remove-detection-of-chip-version-11-early-RTL8.patch
new file mode 100644
index 0000000000..7f0f23fccb
--- /dev/null
+++ b/target/linux/generic/backport-6.6/780-21-v6.11-r8169-remove-detection-of-chip-version-11-early-RTL8.patch
@@ -0,0 +1,32 @@
+From 982300c115d229565d7af8e8b38aa1ee7bb1f5bd Mon Sep 17 00:00:00 2001
+From: Heiner Kallweit <hkallweit1@gmail.com>
+Date: Mon, 27 May 2024 21:20:16 +0200
+Subject: [PATCH] r8169: remove detection of chip version 11 (early
+ RTL8168b)
+
+This early RTL8168b version was the first PCIe chip version, and it's
+quite quirky. Last sign of life is from more than 15 yrs ago.
+Let's remove detection of this chip version, we'll see whether anybody
+complains. If not, support for this chip version can be removed a few
+kernel versions later.
+
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Link: https://lore.kernel.org/r/875cdcf4-843c-420a-ad5d-417447b68572@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/realtek/r8169_main.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -2275,7 +2275,9 @@ static enum mac_version rtl8169_get_mac_
+
+ /* 8168B family. */
+ { 0x7c8, 0x380, RTL_GIGA_MAC_VER_17 },
+- { 0x7c8, 0x300, RTL_GIGA_MAC_VER_11 },
++ /* This one is very old and rare, let's see if anybody complains.
++ * { 0x7c8, 0x300, RTL_GIGA_MAC_VER_11 },
++ */
+
+ /* 8101 family. */
+ { 0x7c8, 0x448, RTL_GIGA_MAC_VER_39 },
diff --git a/target/linux/generic/backport-6.6/781-01-v6.9-net-phy-realtek-add-support-for-RTL8126A-integrated-.patch b/target/linux/generic/backport-6.6/781-01-v6.9-net-phy-realtek-add-support-for-RTL8126A-integrated-.patch
new file mode 100644
index 0000000000..723742e7fa
--- /dev/null
+++ b/target/linux/generic/backport-6.6/781-01-v6.9-net-phy-realtek-add-support-for-RTL8126A-integrated-.patch
@@ -0,0 +1,40 @@
+From 5befa3728b855e9f75b29bb0069a1ca7f5bab2f7 Mon Sep 17 00:00:00 2001
+From: Heiner Kallweit <hkallweit1@gmail.com>
+Date: Wed, 31 Jan 2024 21:24:29 +0100
+Subject: [PATCH] net: phy: realtek: add support for RTL8126A-integrated 5Gbps
+ PHY
+
+A user reported that first consumer mainboards show up with a RTL8126A
+5Gbps MAC/PHY. This adds support for the integrated PHY, which is also
+available stand-alone. From a PHY driver perspective it's treated the
+same as the 2.5Gbps PHY's, we just have to support the new PHY ID.
+
+Reported-by: Joe Salmeri <jmscdba@gmail.com>
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Tested-by: Joe Salmeri <jmscdba@gmail.com>
+Link: https://lore.kernel.org/r/0c8e67ea-6505-43d1-bd51-94e7ecd6e222@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/phy/realtek.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+--- a/drivers/net/phy/realtek.c
++++ b/drivers/net/phy/realtek.c
+@@ -1050,6 +1050,16 @@ static struct phy_driver realtek_drvs[]
+ .read_page = rtl821x_read_page,
+ .write_page = rtl821x_write_page,
+ }, {
++ PHY_ID_MATCH_EXACT(0x001cc862),
++ .name = "RTL8251B 5Gbps PHY",
++ .get_features = rtl822x_get_features,
++ .config_aneg = rtl822x_config_aneg,
++ .read_status = rtl822x_read_status,
++ .suspend = genphy_suspend,
++ .resume = rtlgen_resume,
++ .read_page = rtl821x_read_page,
++ .write_page = rtl821x_write_page,
++ }, {
+ PHY_ID_MATCH_EXACT(0x001cc961),
+ .name = "RTL8366RB Gigabit Ethernet",
+ .config_init = &rtl8366rb_config_init,
diff --git a/target/linux/generic/backport-6.6/781-02-v6.9-net-phy-realtek-use-generic-MDIO-constants.patch b/target/linux/generic/backport-6.6/781-02-v6.9-net-phy-realtek-use-generic-MDIO-constants.patch
new file mode 100644
index 0000000000..6672aca9b8
--- /dev/null
+++ b/target/linux/generic/backport-6.6/781-02-v6.9-net-phy-realtek-use-generic-MDIO-constants.patch
@@ -0,0 +1,93 @@
+From 2b9ec5dfb8255656ca731ab9d9bf59d94566d377 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
+Date: Sun, 4 Feb 2024 15:17:53 +0100
+Subject: [PATCH] net: phy: realtek: use generic MDIO constants
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Drop the ad-hoc MDIO constants used in the driver and use generic
+constants instead.
+
+Signed-off-by: Marek Behún <kabel@kernel.org>
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://lore.kernel.org/r/732a70d6-4191-4aae-8862-3716b062aa9e@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/phy/realtek.c | 30 +++++++++++++-----------------
+ 1 file changed, 13 insertions(+), 17 deletions(-)
+
+--- a/drivers/net/phy/realtek.c
++++ b/drivers/net/phy/realtek.c
+@@ -57,14 +57,6 @@
+ #define RTL8366RB_POWER_SAVE 0x15
+ #define RTL8366RB_POWER_SAVE_ON BIT(12)
+
+-#define RTL_SUPPORTS_5000FULL BIT(14)
+-#define RTL_SUPPORTS_2500FULL BIT(13)
+-#define RTL_SUPPORTS_10000FULL BIT(0)
+-#define RTL_ADV_2500FULL BIT(7)
+-#define RTL_LPADV_10000FULL BIT(11)
+-#define RTL_LPADV_5000FULL BIT(6)
+-#define RTL_LPADV_2500FULL BIT(5)
+-
+ #define RTL9000A_GINMR 0x14
+ #define RTL9000A_GINMR_LINK_STATUS BIT(4)
+
+@@ -676,11 +668,11 @@ static int rtl822x_get_features(struct p
+ return val;
+
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
+- phydev->supported, val & RTL_SUPPORTS_2500FULL);
++ phydev->supported, val & MDIO_PMA_SPEED_2_5G);
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
+- phydev->supported, val & RTL_SUPPORTS_5000FULL);
++ phydev->supported, val & MDIO_PMA_SPEED_5G);
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
+- phydev->supported, val & RTL_SUPPORTS_10000FULL);
++ phydev->supported, val & MDIO_SPEED_10G);
+
+ return genphy_read_abilities(phydev);
+ }
+@@ -694,10 +686,11 @@ static int rtl822x_config_aneg(struct ph
+
+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
+ phydev->advertising))
+- adv2500 = RTL_ADV_2500FULL;
++ adv2500 = MDIO_AN_10GBT_CTRL_ADV2_5G;
+
+ ret = phy_modify_paged_changed(phydev, 0xa5d, 0x12,
+- RTL_ADV_2500FULL, adv2500);
++ MDIO_AN_10GBT_CTRL_ADV2_5G,
++ adv2500);
+ if (ret < 0)
+ return ret;
+ }
+@@ -716,11 +709,14 @@ static int rtl822x_read_status(struct ph
+ return lpadv;
+
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
+- phydev->lp_advertising, lpadv & RTL_LPADV_10000FULL);
++ phydev->lp_advertising,
++ lpadv & MDIO_AN_10GBT_STAT_LP10G);
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
+- phydev->lp_advertising, lpadv & RTL_LPADV_5000FULL);
++ phydev->lp_advertising,
++ lpadv & MDIO_AN_10GBT_STAT_LP5G);
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
+- phydev->lp_advertising, lpadv & RTL_LPADV_2500FULL);
++ phydev->lp_advertising,
++ lpadv & MDIO_AN_10GBT_STAT_LP2_5G);
+ }
+
+ ret = genphy_read_status(phydev);
+@@ -738,7 +734,7 @@ static bool rtlgen_supports_2_5gbps(stru
+ val = phy_read(phydev, 0x13);
+ phy_write(phydev, RTL821x_PAGE_SELECT, 0);
+
+- return val >= 0 && val & RTL_SUPPORTS_2500FULL;
++ return val >= 0 && val & MDIO_PMA_SPEED_2_5G;
+ }
+
+ static int rtlgen_match_phy_device(struct phy_device *phydev)
diff --git a/target/linux/generic/backport-6.6/781-03-v6.9-net-phy-realtek-add-5Gbps-support-to-rtl822x_config_.patch b/target/linux/generic/backport-6.6/781-03-v6.9-net-phy-realtek-add-5Gbps-support-to-rtl822x_config_.patch
new file mode 100644
index 0000000000..4b99a0eae6
--- /dev/null
+++ b/target/linux/generic/backport-6.6/781-03-v6.9-net-phy-realtek-add-5Gbps-support-to-rtl822x_config_.patch
@@ -0,0 +1,42 @@
+From db1bb7741ff29bf2cefcbc0ca567644e9ed1caa9 Mon Sep 17 00:00:00 2001
+From: Heiner Kallweit <hkallweit1@gmail.com>
+Date: Sun, 4 Feb 2024 15:18:50 +0100
+Subject: [PATCH] net: phy: realtek: add 5Gbps support to rtl822x_config_aneg()
+
+RTL8126 as an evolution of RTL8125 supports 5Gbps. rtl822x_config_aneg()
+is used by the PHY driver for the integrated PHY, therefore add 5Gbps
+support to it.
+
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Link: https://lore.kernel.org/r/5644ab50-e3e9-477c-96db-05cd5bdc2563@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/phy/realtek.c | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/phy/realtek.c
++++ b/drivers/net/phy/realtek.c
+@@ -682,15 +682,19 @@ static int rtl822x_config_aneg(struct ph
+ int ret = 0;
+
+ if (phydev->autoneg == AUTONEG_ENABLE) {
+- u16 adv2500 = 0;
++ u16 adv = 0;
+
+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
+ phydev->advertising))
+- adv2500 = MDIO_AN_10GBT_CTRL_ADV2_5G;
++ adv |= MDIO_AN_10GBT_CTRL_ADV2_5G;
++ if (linkmode_test_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
++ phydev->advertising))
++ adv |= MDIO_AN_10GBT_CTRL_ADV5G;
+
+ ret = phy_modify_paged_changed(phydev, 0xa5d, 0x12,
+- MDIO_AN_10GBT_CTRL_ADV2_5G,
+- adv2500);
++ MDIO_AN_10GBT_CTRL_ADV2_5G |
++ MDIO_AN_10GBT_CTRL_ADV5G,
++ adv);
+ if (ret < 0)
+ return ret;
+ }
diff --git a/target/linux/generic/backport-6.6/781-04-v6.9-net-phy-realtek-use-generic-MDIO-helpers-to-simplify.patch b/target/linux/generic/backport-6.6/781-04-v6.9-net-phy-realtek-use-generic-MDIO-helpers-to-simplify.patch
new file mode 100644
index 0000000000..86db2df76b
--- /dev/null
+++ b/target/linux/generic/backport-6.6/781-04-v6.9-net-phy-realtek-use-generic-MDIO-helpers-to-simplify.patch
@@ -0,0 +1,52 @@
+From b63cc73341e076961d564a74cc3d29b2fd444079 Mon Sep 17 00:00:00 2001
+From: Heiner Kallweit <hkallweit1@gmail.com>
+Date: Thu, 8 Feb 2024 07:59:18 +0100
+Subject: [PATCH] net: phy: realtek: use generic MDIO helpers to simplify the
+ code
+
+Use generic MDIO helpers to simplify the code.
+
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://lore.kernel.org/r/422ae70f-7305-45fd-ab3e-0dd604b9fd6c@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/phy/realtek.c | 20 +++-----------------
+ 1 file changed, 3 insertions(+), 17 deletions(-)
+
+--- a/drivers/net/phy/realtek.c
++++ b/drivers/net/phy/realtek.c
+@@ -682,14 +682,7 @@ static int rtl822x_config_aneg(struct ph
+ int ret = 0;
+
+ if (phydev->autoneg == AUTONEG_ENABLE) {
+- u16 adv = 0;
+-
+- if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
+- phydev->advertising))
+- adv |= MDIO_AN_10GBT_CTRL_ADV2_5G;
+- if (linkmode_test_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
+- phydev->advertising))
+- adv |= MDIO_AN_10GBT_CTRL_ADV5G;
++ u16 adv = linkmode_adv_to_mii_10gbt_adv_t(phydev->advertising);
+
+ ret = phy_modify_paged_changed(phydev, 0xa5d, 0x12,
+ MDIO_AN_10GBT_CTRL_ADV2_5G |
+@@ -712,15 +705,8 @@ static int rtl822x_read_status(struct ph
+ if (lpadv < 0)
+ return lpadv;
+
+- linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
+- phydev->lp_advertising,
+- lpadv & MDIO_AN_10GBT_STAT_LP10G);
+- linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
+- phydev->lp_advertising,
+- lpadv & MDIO_AN_10GBT_STAT_LP5G);
+- linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
+- phydev->lp_advertising,
+- lpadv & MDIO_AN_10GBT_STAT_LP2_5G);
++ mii_10gbt_stat_mod_linkmode_lpa_t(phydev->lp_advertising,
++ lpadv);
+ }
+
+ ret = genphy_read_status(phydev);
diff --git a/target/linux/generic/backport-6.6/781-05-v6.10-net-phy-realtek-configure-SerDes-mode-for-rtl822xb-P.patch b/target/linux/generic/backport-6.6/781-05-v6.10-net-phy-realtek-configure-SerDes-mode-for-rtl822xb-P.patch
new file mode 100644
index 0000000000..ba24ca3a16
--- /dev/null
+++ b/target/linux/generic/backport-6.6/781-05-v6.10-net-phy-realtek-configure-SerDes-mode-for-rtl822xb-P.patch
@@ -0,0 +1,209 @@
+From deb8af5243504e379878ae3f9a091b21422d65b2 Mon Sep 17 00:00:00 2001
+From: Alexander Couzens <lynxis@fe80.eu>
+Date: Tue, 9 Apr 2024 09:30:11 +0200
+Subject: [PATCH] net: phy: realtek: configure SerDes mode for rtl822xb PHYs
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The rtl8221b and rtl8226b series support switching SerDes mode between
+2500base-x and sgmii based on the negotiated copper speed.
+
+Configure this switching mode according to SerDes modes supported by
+host.
+
+There is an additional datasheet for RTL8226B/RTL8221B called
+"SERDES MODE SETTING FLOW APPLICATION NOTE" where a sequence is
+described to setup interface and rate adapter mode.
+
+However, there is no documentation about the meaning of registers
+and bits, it's literally just magic numbers and pseudo-code.
+
+Signed-off-by: Alexander Couzens <lynxis@fe80.eu>
+[ refactored, dropped HiSGMII mode and changed commit message ]
+Signed-off-by: Marek Behún <kabel@kernel.org>
+[ changed rtl822x_update_interface() to use vendor register ]
+[ always fill in possible interfaces ]
+[ only apply to rtl8221b and rtl8226b phy's ]
+[ set phydev->rate_matching in .config_init() ]
+Signed-off-by: Eric Woudstra <ericwouds@gmail.com>
+
+Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Reviewed-by: should come before them, without any blank lines. As the
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/phy/realtek.c | 114 ++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 110 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/phy/realtek.c
++++ b/drivers/net/phy/realtek.c
+@@ -54,6 +54,16 @@
+ RTL8201F_ISR_LINK)
+ #define RTL8201F_IER 0x13
+
++#define RTL822X_VND1_SERDES_OPTION 0x697a
++#define RTL822X_VND1_SERDES_OPTION_MODE_MASK GENMASK(5, 0)
++#define RTL822X_VND1_SERDES_OPTION_MODE_2500BASEX_SGMII 0
++#define RTL822X_VND1_SERDES_OPTION_MODE_2500BASEX 2
++
++#define RTL822X_VND1_SERDES_CTRL3 0x7580
++#define RTL822X_VND1_SERDES_CTRL3_MODE_MASK GENMASK(5, 0)
++#define RTL822X_VND1_SERDES_CTRL3_MODE_SGMII 0x02
++#define RTL822X_VND1_SERDES_CTRL3_MODE_2500BASEX 0x16
++
+ #define RTL8366RB_POWER_SAVE 0x15
+ #define RTL8366RB_POWER_SAVE_ON BIT(12)
+
+@@ -659,6 +669,63 @@ static int rtl822x_write_mmd(struct phy_
+ return ret;
+ }
+
++static int rtl822xb_config_init(struct phy_device *phydev)
++{
++ bool has_2500, has_sgmii;
++ u16 mode;
++ int ret;
++
++ has_2500 = test_bit(PHY_INTERFACE_MODE_2500BASEX,
++ phydev->host_interfaces) ||
++ phydev->interface == PHY_INTERFACE_MODE_2500BASEX;
++
++ has_sgmii = test_bit(PHY_INTERFACE_MODE_SGMII,
++ phydev->host_interfaces) ||
++ phydev->interface == PHY_INTERFACE_MODE_SGMII;
++
++ /* fill in possible interfaces */
++ __assign_bit(PHY_INTERFACE_MODE_2500BASEX, phydev->possible_interfaces,
++ has_2500);
++ __assign_bit(PHY_INTERFACE_MODE_SGMII, phydev->possible_interfaces,
++ has_sgmii);
++
++ if (!has_2500 && !has_sgmii)
++ return 0;
++
++ /* determine SerDes option mode */
++ if (has_2500 && !has_sgmii) {
++ mode = RTL822X_VND1_SERDES_OPTION_MODE_2500BASEX;
++ phydev->rate_matching = RATE_MATCH_PAUSE;
++ } else {
++ mode = RTL822X_VND1_SERDES_OPTION_MODE_2500BASEX_SGMII;
++ phydev->rate_matching = RATE_MATCH_NONE;
++ }
++
++ /* the following sequence with magic numbers sets up the SerDes
++ * option mode
++ */
++ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x75f3, 0);
++ if (ret < 0)
++ return ret;
++
++ ret = phy_modify_mmd_changed(phydev, MDIO_MMD_VEND1,
++ RTL822X_VND1_SERDES_OPTION,
++ RTL822X_VND1_SERDES_OPTION_MODE_MASK,
++ mode);
++ if (ret < 0)
++ return ret;
++
++ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x6a04, 0x0503);
++ if (ret < 0)
++ return ret;
++
++ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x6f10, 0xd455);
++ if (ret < 0)
++ return ret;
++
++ return phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x6f11, 0x8020);
++}
++
+ static int rtl822x_get_features(struct phy_device *phydev)
+ {
+ int val;
+@@ -695,6 +762,28 @@ static int rtl822x_config_aneg(struct ph
+ return __genphy_config_aneg(phydev, ret);
+ }
+
++static void rtl822xb_update_interface(struct phy_device *phydev)
++{
++ int val;
++
++ if (!phydev->link)
++ return;
++
++ /* Change interface according to serdes mode */
++ val = phy_read_mmd(phydev, MDIO_MMD_VEND1, RTL822X_VND1_SERDES_CTRL3);
++ if (val < 0)
++ return;
++
++ switch (val & RTL822X_VND1_SERDES_CTRL3_MODE_MASK) {
++ case RTL822X_VND1_SERDES_CTRL3_MODE_2500BASEX:
++ phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
++ break;
++ case RTL822X_VND1_SERDES_CTRL3_MODE_SGMII:
++ phydev->interface = PHY_INTERFACE_MODE_SGMII;
++ break;
++ }
++}
++
+ static int rtl822x_read_status(struct phy_device *phydev)
+ {
+ int ret;
+@@ -716,6 +805,19 @@ static int rtl822x_read_status(struct ph
+ return rtlgen_get_speed(phydev);
+ }
+
++static int rtl822xb_read_status(struct phy_device *phydev)
++{
++ int ret;
++
++ ret = rtl822x_read_status(phydev);
++ if (ret < 0)
++ return ret;
++
++ rtl822xb_update_interface(phydev);
++
++ return 0;
++}
++
+ static bool rtlgen_supports_2_5gbps(struct phy_device *phydev)
+ {
+ int val;
+@@ -988,7 +1090,8 @@ static struct phy_driver realtek_drvs[]
+ .name = "RTL8226B_RTL8221B 2.5Gbps PHY",
+ .get_features = rtl822x_get_features,
+ .config_aneg = rtl822x_config_aneg,
+- .read_status = rtl822x_read_status,
++ .config_init = rtl822xb_config_init,
++ .read_status = rtl822xb_read_status,
+ .suspend = genphy_suspend,
+ .resume = rtlgen_resume,
+ .read_page = rtl821x_read_page,
+@@ -1010,7 +1113,8 @@ static struct phy_driver realtek_drvs[]
+ .name = "RTL8226B-CG_RTL8221B-CG 2.5Gbps PHY",
+ .get_features = rtl822x_get_features,
+ .config_aneg = rtl822x_config_aneg,
+- .read_status = rtl822x_read_status,
++ .config_init = rtl822xb_config_init,
++ .read_status = rtl822xb_read_status,
+ .suspend = genphy_suspend,
+ .resume = rtlgen_resume,
+ .read_page = rtl821x_read_page,
+@@ -1020,7 +1124,8 @@ static struct phy_driver realtek_drvs[]
+ .name = "RTL8221B-VB-CG 2.5Gbps PHY",
+ .get_features = rtl822x_get_features,
+ .config_aneg = rtl822x_config_aneg,
+- .read_status = rtl822x_read_status,
++ .config_init = rtl822xb_config_init,
++ .read_status = rtl822xb_read_status,
+ .suspend = genphy_suspend,
+ .resume = rtlgen_resume,
+ .read_page = rtl821x_read_page,
+@@ -1030,7 +1135,8 @@ static struct phy_driver realtek_drvs[]
+ .name = "RTL8221B-VM-CG 2.5Gbps PHY",
+ .get_features = rtl822x_get_features,
+ .config_aneg = rtl822x_config_aneg,
+- .read_status = rtl822x_read_status,
++ .config_init = rtl822xb_config_init,
++ .read_status = rtl822xb_read_status,
+ .suspend = genphy_suspend,
+ .resume = rtlgen_resume,
+ .read_page = rtl821x_read_page,
diff --git a/target/linux/generic/backport-6.6/781-06-v6.10-net-phy-realtek-add-get_rate_matching-for-rtl822xb-P.patch b/target/linux/generic/backport-6.6/781-06-v6.10-net-phy-realtek-add-get_rate_matching-for-rtl822xb-P.patch
new file mode 100644
index 0000000000..609ae1a028
--- /dev/null
+++ b/target/linux/generic/backport-6.6/781-06-v6.10-net-phy-realtek-add-get_rate_matching-for-rtl822xb-P.patch
@@ -0,0 +1,77 @@
+From c189dbd738243be6775bb6878366bf63e27bfd05 Mon Sep 17 00:00:00 2001
+From: Eric Woudstra <ericwouds@gmail.com>
+Date: Tue, 9 Apr 2024 09:30:12 +0200
+Subject: [PATCH] net: phy: realtek: add get_rate_matching() for rtl822xb PHYs
+
+Uses vendor register to determine if SerDes is setup in rate-matching mode.
+
+Rate-matching only supported when SerDes is set to 2500base-x.
+
+Signed-off-by: Eric Woudstra <ericwouds@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/phy/realtek.c | 25 +++++++++++++++++++++++++
+ 1 file changed, 25 insertions(+)
+
+--- a/drivers/net/phy/realtek.c
++++ b/drivers/net/phy/realtek.c
+@@ -726,6 +726,27 @@ static int rtl822xb_config_init(struct p
+ return phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x6f11, 0x8020);
+ }
+
++static int rtl822xb_get_rate_matching(struct phy_device *phydev,
++ phy_interface_t iface)
++{
++ int val;
++
++ /* Only rate matching at 2500base-x */
++ if (iface != PHY_INTERFACE_MODE_2500BASEX)
++ return RATE_MATCH_NONE;
++
++ val = phy_read_mmd(phydev, MDIO_MMD_VEND1, RTL822X_VND1_SERDES_OPTION);
++ if (val < 0)
++ return val;
++
++ if ((val & RTL822X_VND1_SERDES_OPTION_MODE_MASK) ==
++ RTL822X_VND1_SERDES_OPTION_MODE_2500BASEX)
++ return RATE_MATCH_PAUSE;
++
++ /* RTL822X_VND1_SERDES_OPTION_MODE_2500BASEX_SGMII */
++ return RATE_MATCH_NONE;
++}
++
+ static int rtl822x_get_features(struct phy_device *phydev)
+ {
+ int val;
+@@ -1091,6 +1112,7 @@ static struct phy_driver realtek_drvs[]
+ .get_features = rtl822x_get_features,
+ .config_aneg = rtl822x_config_aneg,
+ .config_init = rtl822xb_config_init,
++ .get_rate_matching = rtl822xb_get_rate_matching,
+ .read_status = rtl822xb_read_status,
+ .suspend = genphy_suspend,
+ .resume = rtlgen_resume,
+@@ -1114,6 +1136,7 @@ static struct phy_driver realtek_drvs[]
+ .get_features = rtl822x_get_features,
+ .config_aneg = rtl822x_config_aneg,
+ .config_init = rtl822xb_config_init,
++ .get_rate_matching = rtl822xb_get_rate_matching,
+ .read_status = rtl822xb_read_status,
+ .suspend = genphy_suspend,
+ .resume = rtlgen_resume,
+@@ -1125,6 +1148,7 @@ static struct phy_driver realtek_drvs[]
+ .get_features = rtl822x_get_features,
+ .config_aneg = rtl822x_config_aneg,
+ .config_init = rtl822xb_config_init,
++ .get_rate_matching = rtl822xb_get_rate_matching,
+ .read_status = rtl822xb_read_status,
+ .suspend = genphy_suspend,
+ .resume = rtlgen_resume,
+@@ -1136,6 +1160,7 @@ static struct phy_driver realtek_drvs[]
+ .get_features = rtl822x_get_features,
+ .config_aneg = rtl822x_config_aneg,
+ .config_init = rtl822xb_config_init,
++ .get_rate_matching = rtl822xb_get_rate_matching,
+ .read_status = rtl822xb_read_status,
+ .suspend = genphy_suspend,
+ .resume = rtlgen_resume,
diff --git a/target/linux/generic/backport-6.6/781-07-v6.10-net-phy-realtek-Add-driver-instances-for-rtl8221b-vi.patch b/target/linux/generic/backport-6.6/781-07-v6.10-net-phy-realtek-Add-driver-instances-for-rtl8221b-vi.patch
new file mode 100644
index 0000000000..5366c72f9c
--- /dev/null
+++ b/target/linux/generic/backport-6.6/781-07-v6.10-net-phy-realtek-Add-driver-instances-for-rtl8221b-vi.patch
@@ -0,0 +1,218 @@
+From ad5ce743a6b0329f642d80be50ef7b534e908fba Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
+Date: Tue, 9 Apr 2024 09:30:13 +0200
+Subject: [PATCH] net: phy: realtek: Add driver instances for rtl8221b via
+ Clause 45
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Collected from several commits in [PATCH net-next]
+"Realtek RTL822x PHY rework to c45 and SerDes interface switching"
+
+The instances are used by Clause 45 only accessible PHY's on several sfp
+modules, which are using RollBall protocol.
+
+Signed-off-by: Marek Behún <kabel@kernel.org>
+[ Added matching functions to differentiate C45 instances ]
+Signed-off-by: Eric Woudstra <ericwouds@gmail.com>
+
+Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/phy/realtek.c | 135 ++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 131 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/phy/realtek.c
++++ b/drivers/net/phy/realtek.c
+@@ -64,6 +64,13 @@
+ #define RTL822X_VND1_SERDES_CTRL3_MODE_SGMII 0x02
+ #define RTL822X_VND1_SERDES_CTRL3_MODE_2500BASEX 0x16
+
++/* RTL822X_VND2_XXXXX registers are only accessible when phydev->is_c45
++ * is set, they cannot be accessed by C45-over-C22.
++ */
++#define RTL822X_VND2_GBCR 0xa412
++
++#define RTL822X_VND2_GANLPAR 0xa414
++
+ #define RTL8366RB_POWER_SAVE 0x15
+ #define RTL8366RB_POWER_SAVE_ON BIT(12)
+
+@@ -74,6 +81,9 @@
+
+ #define RTL_GENERIC_PHYID 0x001cc800
+ #define RTL_8211FVD_PHYID 0x001cc878
++#define RTL_8221B_VB_CG 0x001cc849
++#define RTL_8221B_VN_CG 0x001cc84a
++#define RTL_8251B 0x001cc862
+
+ MODULE_DESCRIPTION("Realtek PHY driver");
+ MODULE_AUTHOR("Johnson Leung");
+@@ -839,6 +849,67 @@ static int rtl822xb_read_status(struct p
+ return 0;
+ }
+
++static int rtl822x_c45_config_aneg(struct phy_device *phydev)
++{
++ bool changed = false;
++ int ret, val;
++
++ 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;
++
++ val = linkmode_adv_to_mii_ctrl1000_t(phydev->advertising);
++
++ /* Vendor register as C45 has no standardized support for 1000BaseT */
++ ret = phy_modify_mmd_changed(phydev, MDIO_MMD_VEND2, RTL822X_VND2_GBCR,
++ ADVERTISE_1000FULL, val);
++ if (ret < 0)
++ return ret;
++ if (ret > 0)
++ changed = true;
++
++ return genphy_c45_check_and_restart_aneg(phydev, changed);
++}
++
++static int rtl822x_c45_read_status(struct phy_device *phydev)
++{
++ int ret, val;
++
++ ret = genphy_c45_read_status(phydev);
++ if (ret < 0)
++ return ret;
++
++ /* Vendor register as C45 has no standardized support for 1000BaseT */
++ if (phydev->autoneg == AUTONEG_ENABLE) {
++ val = phy_read_mmd(phydev, MDIO_MMD_VEND2,
++ RTL822X_VND2_GANLPAR);
++ if (val < 0)
++ return val;
++
++ mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, val);
++ }
++
++ return 0;
++}
++
++static int rtl822xb_c45_read_status(struct phy_device *phydev)
++{
++ int ret;
++
++ ret = rtl822x_c45_read_status(phydev);
++ if (ret < 0)
++ return ret;
++
++ rtl822xb_update_interface(phydev);
++
++ return 0;
++}
++
+ static bool rtlgen_supports_2_5gbps(struct phy_device *phydev)
+ {
+ int val;
+@@ -862,6 +933,35 @@ static int rtl8226_match_phy_device(stru
+ rtlgen_supports_2_5gbps(phydev);
+ }
+
++static int rtlgen_is_c45_match(struct phy_device *phydev, unsigned int id,
++ bool is_c45)
++{
++ if (phydev->is_c45)
++ return is_c45 && (id == phydev->c45_ids.device_ids[1]);
++ else
++ return !is_c45 && (id == phydev->phy_id);
++}
++
++static int rtl8221b_vb_cg_c22_match_phy_device(struct phy_device *phydev)
++{
++ return rtlgen_is_c45_match(phydev, RTL_8221B_VB_CG, false);
++}
++
++static int rtl8221b_vb_cg_c45_match_phy_device(struct phy_device *phydev)
++{
++ return rtlgen_is_c45_match(phydev, RTL_8221B_VB_CG, true);
++}
++
++static int rtl8221b_vn_cg_c22_match_phy_device(struct phy_device *phydev)
++{
++ return rtlgen_is_c45_match(phydev, RTL_8221B_VN_CG, false);
++}
++
++static int rtl8221b_vn_cg_c45_match_phy_device(struct phy_device *phydev)
++{
++ return rtlgen_is_c45_match(phydev, RTL_8221B_VN_CG, true);
++}
++
+ static int rtlgen_resume(struct phy_device *phydev)
+ {
+ int ret = genphy_resume(phydev);
+@@ -872,6 +972,15 @@ static int rtlgen_resume(struct phy_devi
+ return ret;
+ }
+
++static int rtlgen_c45_resume(struct phy_device *phydev)
++{
++ int ret = genphy_c45_pma_resume(phydev);
++
++ msleep(20);
++
++ return ret;
++}
++
+ static int rtl9000a_config_init(struct phy_device *phydev)
+ {
+ phydev->autoneg = AUTONEG_DISABLE;
+@@ -1143,8 +1252,8 @@ static struct phy_driver realtek_drvs[]
+ .read_page = rtl821x_read_page,
+ .write_page = rtl821x_write_page,
+ }, {
+- PHY_ID_MATCH_EXACT(0x001cc849),
+- .name = "RTL8221B-VB-CG 2.5Gbps PHY",
++ .match_phy_device = rtl8221b_vb_cg_c22_match_phy_device,
++ .name = "RTL8221B-VB-CG 2.5Gbps PHY (C22)",
+ .get_features = rtl822x_get_features,
+ .config_aneg = rtl822x_config_aneg,
+ .config_init = rtl822xb_config_init,
+@@ -1155,8 +1264,17 @@ static struct phy_driver realtek_drvs[]
+ .read_page = rtl821x_read_page,
+ .write_page = rtl821x_write_page,
+ }, {
+- PHY_ID_MATCH_EXACT(0x001cc84a),
+- .name = "RTL8221B-VM-CG 2.5Gbps PHY",
++ .match_phy_device = rtl8221b_vb_cg_c45_match_phy_device,
++ .name = "RTL8221B-VB-CG 2.5Gbps PHY (C45)",
++ .config_init = rtl822xb_config_init,
++ .get_rate_matching = rtl822xb_get_rate_matching,
++ .config_aneg = rtl822x_c45_config_aneg,
++ .read_status = rtl822xb_c45_read_status,
++ .suspend = genphy_c45_pma_suspend,
++ .resume = rtlgen_c45_resume,
++ }, {
++ .match_phy_device = rtl8221b_vn_cg_c22_match_phy_device,
++ .name = "RTL8221B-VM-CG 2.5Gbps PHY (C22)",
+ .get_features = rtl822x_get_features,
+ .config_aneg = rtl822x_config_aneg,
+ .config_init = rtl822xb_config_init,
+@@ -1167,6 +1285,15 @@ static struct phy_driver realtek_drvs[]
+ .read_page = rtl821x_read_page,
+ .write_page = rtl821x_write_page,
+ }, {
++ .match_phy_device = rtl8221b_vn_cg_c45_match_phy_device,
++ .name = "RTL8221B-VN-CG 2.5Gbps PHY (C45)",
++ .config_init = rtl822xb_config_init,
++ .get_rate_matching = rtl822xb_get_rate_matching,
++ .config_aneg = rtl822x_c45_config_aneg,
++ .read_status = rtl822xb_c45_read_status,
++ .suspend = genphy_c45_pma_suspend,
++ .resume = rtlgen_c45_resume,
++ }, {
+ PHY_ID_MATCH_EXACT(0x001cc862),
+ .name = "RTL8251B 5Gbps PHY",
+ .get_features = rtl822x_get_features,
diff --git a/target/linux/generic/backport-6.6/781-08-v6.10-net-phy-realtek-Change-rtlgen_get_speed-to-rtlgen_de.patch b/target/linux/generic/backport-6.6/781-08-v6.10-net-phy-realtek-Change-rtlgen_get_speed-to-rtlgen_de.patch
new file mode 100644
index 0000000000..5c7130d2e0
--- /dev/null
+++ b/target/linux/generic/backport-6.6/781-08-v6.10-net-phy-realtek-Change-rtlgen_get_speed-to-rtlgen_de.patch
@@ -0,0 +1,125 @@
+From 2e4ea707c7e04eb83e58c43e0e744bbdf6b23ff2 Mon Sep 17 00:00:00 2001
+From: Eric Woudstra <ericwouds@gmail.com>
+Date: Tue, 9 Apr 2024 09:30:14 +0200
+Subject: [PATCH] net: phy: realtek: Change rtlgen_get_speed() to
+ rtlgen_decode_speed()
+
+The value of the register to determine the speed, is retrieved
+differently when using Clause 45 only. To use the rtlgen_get_speed()
+function in this case, pass the value of the register as argument to
+rtlgen_get_speed(). The function would then always return 0, so change it
+to void. A better name for this function now is rtlgen_decode_speed().
+
+Replace a call to genphy_read_status() followed by rtlgen_get_speed()
+with a call to rtlgen_read_status() in rtl822x_read_status().
+
+Add reading speed to rtl822x_c45_read_status().
+
+Signed-off-by: Eric Woudstra <ericwouds@gmail.com>
+
+Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/phy/realtek.c | 46 +++++++++++++++++++++------------------
+ 1 file changed, 25 insertions(+), 21 deletions(-)
+
+--- a/drivers/net/phy/realtek.c
++++ b/drivers/net/phy/realtek.c
+@@ -71,6 +71,8 @@
+
+ #define RTL822X_VND2_GANLPAR 0xa414
+
++#define RTL822X_VND2_PHYSR 0xa434
++
+ #define RTL8366RB_POWER_SAVE 0x15
+ #define RTL8366RB_POWER_SAVE_ON BIT(12)
+
+@@ -551,17 +553,8 @@ static int rtl8366rb_config_init(struct
+ }
+
+ /* get actual speed to cover the downshift case */
+-static int rtlgen_get_speed(struct phy_device *phydev)
++static void rtlgen_decode_speed(struct phy_device *phydev, int val)
+ {
+- int val;
+-
+- if (!phydev->link)
+- return 0;
+-
+- val = phy_read_paged(phydev, 0xa43, 0x12);
+- if (val < 0)
+- return val;
+-
+ switch (val & RTLGEN_SPEED_MASK) {
+ case 0x0000:
+ phydev->speed = SPEED_10;
+@@ -584,19 +577,26 @@ static int rtlgen_get_speed(struct phy_d
+ default:
+ break;
+ }
+-
+- return 0;
+ }
+
+ static int rtlgen_read_status(struct phy_device *phydev)
+ {
+- int ret;
++ int ret, val;
+
+ ret = genphy_read_status(phydev);
+ if (ret < 0)
+ return ret;
+
+- return rtlgen_get_speed(phydev);
++ if (!phydev->link)
++ return 0;
++
++ val = phy_read_paged(phydev, 0xa43, 0x12);
++ if (val < 0)
++ return val;
++
++ rtlgen_decode_speed(phydev, val);
++
++ return 0;
+ }
+
+ static int rtlgen_read_mmd(struct phy_device *phydev, int devnum, u16 regnum)
+@@ -817,8 +817,6 @@ static void rtl822xb_update_interface(st
+
+ static int rtl822x_read_status(struct phy_device *phydev)
+ {
+- int ret;
+-
+ if (phydev->autoneg == AUTONEG_ENABLE) {
+ int lpadv = phy_read_paged(phydev, 0xa5d, 0x13);
+
+@@ -829,11 +827,7 @@ static int rtl822x_read_status(struct ph
+ lpadv);
+ }
+
+- ret = genphy_read_status(phydev);
+- if (ret < 0)
+- return ret;
+-
+- return rtlgen_get_speed(phydev);
++ return rtlgen_read_status(phydev);
+ }
+
+ static int rtl822xb_read_status(struct phy_device *phydev)
+@@ -894,6 +888,16 @@ static int rtl822x_c45_read_status(struc
+ mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, val);
+ }
+
++ if (!phydev->link)
++ return 0;
++
++ /* Read actual speed from vendor register. */
++ val = phy_read_mmd(phydev, MDIO_MMD_VEND2, RTL822X_VND2_PHYSR);
++ if (val < 0)
++ return val;
++
++ rtlgen_decode_speed(phydev, val);
++
+ return 0;
+ }
+
diff --git a/target/linux/generic/backport-6.6/781-09-v6.10-net-phy-realtek-add-rtl822x_c45_get_features-to-set-.patch b/target/linux/generic/backport-6.6/781-09-v6.10-net-phy-realtek-add-rtl822x_c45_get_features-to-set-.patch
new file mode 100644
index 0000000000..ed29dcd3e6
--- /dev/null
+++ b/target/linux/generic/backport-6.6/781-09-v6.10-net-phy-realtek-add-rtl822x_c45_get_features-to-set-.patch
@@ -0,0 +1,48 @@
+From 2d9ce64862705b33397d54dafecc5f51d8b1bb06 Mon Sep 17 00:00:00 2001
+From: Eric Woudstra <ericwouds@gmail.com>
+Date: Tue, 9 Apr 2024 09:30:15 +0200
+Subject: [PATCH] net: phy: realtek: add rtl822x_c45_get_features() to set
+ supported port
+
+Sets ETHTOOL_LINK_MODE_TP_BIT in phydev->supported.
+
+Signed-off-by: Eric Woudstra <ericwouds@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/phy/realtek.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+--- a/drivers/net/phy/realtek.c
++++ b/drivers/net/phy/realtek.c
+@@ -843,6 +843,14 @@ static int rtl822xb_read_status(struct p
+ return 0;
+ }
+
++static int rtl822x_c45_get_features(struct phy_device *phydev)
++{
++ linkmode_set_bit(ETHTOOL_LINK_MODE_TP_BIT,
++ phydev->supported);
++
++ return genphy_c45_pma_read_abilities(phydev);
++}
++
+ static int rtl822x_c45_config_aneg(struct phy_device *phydev)
+ {
+ bool changed = false;
+@@ -1272,6 +1280,7 @@ static struct phy_driver realtek_drvs[]
+ .name = "RTL8221B-VB-CG 2.5Gbps PHY (C45)",
+ .config_init = rtl822xb_config_init,
+ .get_rate_matching = rtl822xb_get_rate_matching,
++ .get_features = rtl822x_c45_get_features,
+ .config_aneg = rtl822x_c45_config_aneg,
+ .read_status = rtl822xb_c45_read_status,
+ .suspend = genphy_c45_pma_suspend,
+@@ -1293,6 +1302,7 @@ static struct phy_driver realtek_drvs[]
+ .name = "RTL8221B-VN-CG 2.5Gbps PHY (C45)",
+ .config_init = rtl822xb_config_init,
+ .get_rate_matching = rtl822xb_get_rate_matching,
++ .get_features = rtl822x_c45_get_features,
+ .config_aneg = rtl822x_c45_config_aneg,
+ .read_status = rtl822xb_c45_read_status,
+ .suspend = genphy_c45_pma_suspend,
diff --git a/target/linux/generic/backport-6.6/781-10-v6.11-net-phy-realtek-add-support-for-rtl8224-2.5Gbps-PHY.patch b/target/linux/generic/backport-6.6/781-10-v6.11-net-phy-realtek-add-support-for-rtl8224-2.5Gbps-PHY.patch
new file mode 100644
index 0000000000..13e1d883a3
--- /dev/null
+++ b/target/linux/generic/backport-6.6/781-10-v6.11-net-phy-realtek-add-support-for-rtl8224-2.5Gbps-PHY.patch
@@ -0,0 +1,33 @@
+From 9e42a2ea7f6703e2092c39171c2bf1fd7eec0bd3 Mon Sep 17 00:00:00 2001
+From: Chris Packham <chris.packham@alliedtelesis.co.nz>
+Date: Tue, 11 Jun 2024 17:34:14 +1200
+Subject: [PATCH] net: phy: realtek: add support for rtl8224 2.5Gbps PHY
+
+The Realtek RTL8224 PHY is a 2.5Gbps capable PHY. It only uses the
+clause 45 MDIO interface and can leverage the support that has already
+been added for the other 822x PHYs.
+
+Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
+Link: https://lore.kernel.org/r/20240611053415.2111723-1-chris.packham@alliedtelesis.co.nz
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/phy/realtek.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/drivers/net/phy/realtek.c
++++ b/drivers/net/phy/realtek.c
+@@ -1318,6 +1318,14 @@ static struct phy_driver realtek_drvs[]
+ .read_page = rtl821x_read_page,
+ .write_page = rtl821x_write_page,
+ }, {
++ PHY_ID_MATCH_EXACT(0x001ccad0),
++ .name = "RTL8224 2.5Gbps PHY",
++ .get_features = rtl822x_c45_get_features,
++ .config_aneg = rtl822x_c45_config_aneg,
++ .read_status = rtl822x_c45_read_status,
++ .suspend = genphy_c45_pma_suspend,
++ .resume = rtlgen_c45_resume,
++ }, {
+ PHY_ID_MATCH_EXACT(0x001cc961),
+ .name = "RTL8366RB Gigabit Ethernet",
+ .config_init = &rtl8366rb_config_init,
diff --git a/target/linux/generic/backport-6.6/781-11-v6.11-net-phy-realtek-Add-support-for-PHY-LEDs-on-RTL8211F.patch b/target/linux/generic/backport-6.6/781-11-v6.11-net-phy-realtek-Add-support-for-PHY-LEDs-on-RTL8211F.patch
new file mode 100644
index 0000000000..12c8ae66b5
--- /dev/null
+++ b/target/linux/generic/backport-6.6/781-11-v6.11-net-phy-realtek-Add-support-for-PHY-LEDs-on-RTL8211F.patch
@@ -0,0 +1,151 @@
+From 17784801d888238571a0c4101b9ac4401fffeaa0 Mon Sep 17 00:00:00 2001
+From: Marek Vasut <marex@denx.de>
+Date: Tue, 25 Jun 2024 22:42:17 +0200
+Subject: [PATCH] net: phy: realtek: Add support for PHY LEDs on RTL8211F
+
+Realtek RTL8211F Ethernet PHY supports 3 LED pins which are used to
+indicate link status and activity. Add minimal LED controller driver
+supporting the most common uses with the 'netdev' trigger.
+
+Signed-off-by: Marek Vasut <marex@denx.de>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/phy/realtek.c | 106 ++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 106 insertions(+)
+
+--- a/drivers/net/phy/realtek.c
++++ b/drivers/net/phy/realtek.c
+@@ -32,6 +32,15 @@
+ #define RTL8211F_PHYCR2 0x19
+ #define RTL8211F_INSR 0x1d
+
++#define RTL8211F_LEDCR 0x10
++#define RTL8211F_LEDCR_MODE BIT(15)
++#define RTL8211F_LEDCR_ACT_TXRX BIT(4)
++#define RTL8211F_LEDCR_LINK_1000 BIT(3)
++#define RTL8211F_LEDCR_LINK_100 BIT(1)
++#define RTL8211F_LEDCR_LINK_10 BIT(0)
++#define RTL8211F_LEDCR_MASK GENMASK(4, 0)
++#define RTL8211F_LEDCR_SHIFT 5
++
+ #define RTL8211F_TX_DELAY BIT(8)
+ #define RTL8211F_RX_DELAY BIT(3)
+
+@@ -87,6 +96,8 @@
+ #define RTL_8221B_VN_CG 0x001cc84a
+ #define RTL_8251B 0x001cc862
+
++#define RTL8211F_LED_COUNT 3
++
+ MODULE_DESCRIPTION("Realtek PHY driver");
+ MODULE_AUTHOR("Johnson Leung");
+ MODULE_LICENSE("GPL");
+@@ -476,6 +487,98 @@ static int rtl821x_resume(struct phy_dev
+ return 0;
+ }
+
++static int rtl8211f_led_hw_is_supported(struct phy_device *phydev, u8 index,
++ unsigned long rules)
++{
++ const unsigned long mask = BIT(TRIGGER_NETDEV_LINK_10) |
++ BIT(TRIGGER_NETDEV_LINK_100) |
++ BIT(TRIGGER_NETDEV_LINK_1000) |
++ BIT(TRIGGER_NETDEV_RX) |
++ BIT(TRIGGER_NETDEV_TX);
++
++ /* The RTL8211F PHY supports these LED settings on up to three LEDs:
++ * - Link: Configurable subset of 10/100/1000 link rates
++ * - Active: Blink on activity, RX or TX is not differentiated
++ * The Active option has two modes, A and B:
++ * - A: Link and Active indication at configurable, but matching,
++ * subset of 10/100/1000 link rates
++ * - B: Link indication at configurable subset of 10/100/1000 link
++ * rates and Active indication always at all three 10+100+1000
++ * link rates.
++ * This code currently uses mode B only.
++ */
++
++ if (index >= RTL8211F_LED_COUNT)
++ return -EINVAL;
++
++ /* Filter out any other unsupported triggers. */
++ if (rules & ~mask)
++ return -EOPNOTSUPP;
++
++ /* RX and TX are not differentiated, either both are set or not set. */
++ if (!(rules & BIT(TRIGGER_NETDEV_RX)) ^ !(rules & BIT(TRIGGER_NETDEV_TX)))
++ return -EOPNOTSUPP;
++
++ return 0;
++}
++
++static int rtl8211f_led_hw_control_get(struct phy_device *phydev, u8 index,
++ unsigned long *rules)
++{
++ int val;
++
++ val = phy_read_paged(phydev, 0xd04, RTL8211F_LEDCR);
++ if (val < 0)
++ return val;
++
++ val >>= RTL8211F_LEDCR_SHIFT * index;
++ val &= RTL8211F_LEDCR_MASK;
++
++ if (val & RTL8211F_LEDCR_LINK_10)
++ set_bit(TRIGGER_NETDEV_LINK_10, rules);
++
++ if (val & RTL8211F_LEDCR_LINK_100)
++ set_bit(TRIGGER_NETDEV_LINK_100, rules);
++
++ if (val & RTL8211F_LEDCR_LINK_1000)
++ set_bit(TRIGGER_NETDEV_LINK_1000, rules);
++
++ if (val & RTL8211F_LEDCR_ACT_TXRX) {
++ set_bit(TRIGGER_NETDEV_RX, rules);
++ set_bit(TRIGGER_NETDEV_TX, rules);
++ }
++
++ return 0;
++}
++
++static int rtl8211f_led_hw_control_set(struct phy_device *phydev, u8 index,
++ unsigned long rules)
++{
++ const u16 mask = RTL8211F_LEDCR_MASK << (RTL8211F_LEDCR_SHIFT * index);
++ u16 reg = RTL8211F_LEDCR_MODE; /* Mode B */
++
++ if (index >= RTL8211F_LED_COUNT)
++ return -EINVAL;
++
++ if (test_bit(TRIGGER_NETDEV_LINK_10, &rules))
++ reg |= RTL8211F_LEDCR_LINK_10;
++
++ if (test_bit(TRIGGER_NETDEV_LINK_100, &rules))
++ reg |= RTL8211F_LEDCR_LINK_100;
++
++ if (test_bit(TRIGGER_NETDEV_LINK_1000, &rules))
++ reg |= RTL8211F_LEDCR_LINK_1000;
++
++ if (test_bit(TRIGGER_NETDEV_RX, &rules) ||
++ test_bit(TRIGGER_NETDEV_TX, &rules)) {
++ reg |= RTL8211F_LEDCR_ACT_TXRX;
++ }
++
++ reg <<= RTL8211F_LEDCR_SHIFT * index;
++
++ return phy_modify_paged(phydev, 0xd04, RTL8211F_LEDCR, mask, reg);
++}
++
+ static int rtl8211e_config_init(struct phy_device *phydev)
+ {
+ int ret = 0, oldpage;
+@@ -1192,6 +1295,9 @@ static struct phy_driver realtek_drvs[]
+ .read_page = rtl821x_read_page,
+ .write_page = rtl821x_write_page,
+ .flags = PHY_ALWAYS_CALL_SUSPEND,
++ .led_hw_is_supported = rtl8211f_led_hw_is_supported,
++ .led_hw_control_get = rtl8211f_led_hw_control_get,
++ .led_hw_control_set = rtl8211f_led_hw_control_set,
+ }, {
+ PHY_ID_MATCH_EXACT(RTL_8211FVD_PHYID),
+ .name = "RTL8211F-VD Gigabit Ethernet",
diff --git a/target/linux/generic/backport-6.6/781-12-v6.11-net-phy-realtek-Fix-setting-of-PHY-LEDs-Mode-B-bit-o.patch b/target/linux/generic/backport-6.6/781-12-v6.11-net-phy-realtek-Fix-setting-of-PHY-LEDs-Mode-B-bit-o.patch
new file mode 100644
index 0000000000..5958fc929c
--- /dev/null
+++ b/target/linux/generic/backport-6.6/781-12-v6.11-net-phy-realtek-Fix-setting-of-PHY-LEDs-Mode-B-bit-o.patch
@@ -0,0 +1,42 @@
+From a2f5c505b4378cd6fc7c4a44ff3665ccef2037db Mon Sep 17 00:00:00 2001
+From: Sava Jakovljev <savaj@meyersound.com>
+Date: Wed, 21 Aug 2024 04:16:57 +0200
+Subject: [PATCH] net: phy: realtek: Fix setting of PHY LEDs Mode B bit on
+ RTL8211F
+
+The current implementation incorrectly sets the mode bit of the PHY chip.
+Bit 15 (RTL8211F_LEDCR_MODE) should not be shifted together with the
+configuration nibble of a LED- it should be set independently of the
+index of the LED being configured.
+As a consequence, the RTL8211F LED control is actually operating in Mode A.
+Fix the error by or-ing final register value to write with a const-value of
+RTL8211F_LEDCR_MODE, thus setting Mode bit explicitly.
+
+Fixes: 17784801d888 ("net: phy: realtek: Add support for PHY LEDs on RTL8211F")
+Signed-off-by: Sava Jakovljev <savaj@meyersound.com>
+Reviewed-by: Marek Vasut <marex@denx.de>
+Link: https://patch.msgid.link/PAWP192MB21287372F30C4E55B6DF6158C38E2@PAWP192MB2128.EURP192.PROD.OUTLOOK.COM
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+---
+ drivers/net/phy/realtek.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/phy/realtek.c
++++ b/drivers/net/phy/realtek.c
+@@ -555,7 +555,7 @@ static int rtl8211f_led_hw_control_set(s
+ unsigned long rules)
+ {
+ const u16 mask = RTL8211F_LEDCR_MASK << (RTL8211F_LEDCR_SHIFT * index);
+- u16 reg = RTL8211F_LEDCR_MODE; /* Mode B */
++ u16 reg = 0;
+
+ if (index >= RTL8211F_LED_COUNT)
+ return -EINVAL;
+@@ -575,6 +575,7 @@ static int rtl8211f_led_hw_control_set(s
+ }
+
+ reg <<= RTL8211F_LEDCR_SHIFT * index;
++ reg |= RTL8211F_LEDCR_MODE; /* Mode B */
+
+ return phy_modify_paged(phydev, 0xd04, RTL8211F_LEDCR, mask, reg);
+ }
diff --git a/target/linux/generic/backport-6.6/816-v6.7-0004-Revert-nvmem-add-new-config-option.patch b/target/linux/generic/backport-6.6/816-v6.7-0004-Revert-nvmem-add-new-config-option.patch
index 39be82d4bf..36d15248b8 100644
--- a/target/linux/generic/backport-6.6/816-v6.7-0004-Revert-nvmem-add-new-config-option.patch
+++ b/target/linux/generic/backport-6.6/816-v6.7-0004-Revert-nvmem-add-new-config-option.patch
@@ -48,7 +48,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
mtd->nvmem = nvmem_register(&config);
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
-@@ -941,7 +941,7 @@ struct nvmem_device *nvmem_register(cons
+@@ -940,7 +940,7 @@ struct nvmem_device *nvmem_register(cons
nvmem->nkeepout = config->nkeepout;
if (config->of_node)
nvmem->dev.of_node = config->of_node;
diff --git a/target/linux/generic/backport-6.6/819-v6.8-0001-nvmem-Move-of_nvmem_layout_get_container-in-another-.patch b/target/linux/generic/backport-6.6/819-v6.8-0001-nvmem-Move-of_nvmem_layout_get_container-in-another-.patch
index 59175c8051..7ca426e87a 100644
--- a/target/linux/generic/backport-6.6/819-v6.8-0001-nvmem-Move-of_nvmem_layout_get_container-in-another-.patch
+++ b/target/linux/generic/backport-6.6/819-v6.8-0001-nvmem-Move-of_nvmem_layout_get_container-in-another-.patch
@@ -25,7 +25,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
-@@ -847,14 +847,6 @@ static int nvmem_add_cells_from_layout(s
+@@ -846,14 +846,6 @@ static int nvmem_add_cells_from_layout(s
}
#if IS_ENABLED(CONFIG_OF)
diff --git a/target/linux/generic/backport-6.6/819-v6.8-0003-nvmem-Simplify-the-add_cells-hook.patch b/target/linux/generic/backport-6.6/819-v6.8-0003-nvmem-Simplify-the-add_cells-hook.patch
index 1f39dfea2f..dac691e117 100644
--- a/target/linux/generic/backport-6.6/819-v6.8-0003-nvmem-Simplify-the-add_cells-hook.patch
+++ b/target/linux/generic/backport-6.6/819-v6.8-0003-nvmem-Simplify-the-add_cells-hook.patch
@@ -20,7 +20,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
-@@ -816,7 +816,7 @@ static int nvmem_add_cells_from_layout(s
+@@ -815,7 +815,7 @@ static int nvmem_add_cells_from_layout(s
int ret;
if (layout && layout->add_cells) {
diff --git a/target/linux/generic/backport-6.6/819-v6.8-0004-nvmem-Move-and-rename-fixup_cell_info.patch b/target/linux/generic/backport-6.6/819-v6.8-0004-nvmem-Move-and-rename-fixup_cell_info.patch
index d2c274033e..0a614fc13d 100644
--- a/target/linux/generic/backport-6.6/819-v6.8-0004-nvmem-Move-and-rename-fixup_cell_info.patch
+++ b/target/linux/generic/backport-6.6/819-v6.8-0004-nvmem-Move-and-rename-fixup_cell_info.patch
@@ -25,7 +25,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
-@@ -675,7 +675,6 @@ static int nvmem_validate_keepouts(struc
+@@ -674,7 +674,6 @@ static int nvmem_validate_keepouts(struc
static int nvmem_add_cells_from_dt(struct nvmem_device *nvmem, struct device_node *np)
{
@@ -33,7 +33,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
struct device *dev = &nvmem->dev;
struct device_node *child;
const __be32 *addr;
-@@ -705,8 +704,8 @@ static int nvmem_add_cells_from_dt(struc
+@@ -704,8 +703,8 @@ static int nvmem_add_cells_from_dt(struc
info.np = of_node_get(child);
@@ -44,7 +44,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
ret = nvmem_add_one_cell(nvmem, &info);
kfree(info.name);
-@@ -895,6 +894,7 @@ struct nvmem_device *nvmem_register(cons
+@@ -894,6 +893,7 @@ struct nvmem_device *nvmem_register(cons
kref_init(&nvmem->refcnt);
INIT_LIST_HEAD(&nvmem->cells);
diff --git a/target/linux/generic/backport-6.6/819-v6.8-0005-nvmem-core-Rework-layouts-to-become-regular-devices.patch b/target/linux/generic/backport-6.6/819-v6.8-0005-nvmem-core-Rework-layouts-to-become-regular-devices.patch
index ce33b52328..1a41050d08 100644
--- a/target/linux/generic/backport-6.6/819-v6.8-0005-nvmem-core-Rework-layouts-to-become-regular-devices.patch
+++ b/target/linux/generic/backport-6.6/819-v6.8-0005-nvmem-core-Rework-layouts-to-become-regular-devices.patch
@@ -84,7 +84,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
static int __nvmem_reg_read(struct nvmem_device *nvmem, unsigned int offset,
void *val, size_t bytes)
{
-@@ -740,97 +737,22 @@ static int nvmem_add_cells_from_fixed_la
+@@ -739,97 +736,22 @@ static int nvmem_add_cells_from_fixed_la
return err;
}
@@ -189,7 +189,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
const void *nvmem_layout_get_match_data(struct nvmem_device *nvmem,
struct nvmem_layout *layout)
{
-@@ -838,7 +760,7 @@ const void *nvmem_layout_get_match_data(
+@@ -837,7 +759,7 @@ const void *nvmem_layout_get_match_data(
const struct of_device_id *match;
layout_np = of_nvmem_layout_get_container(nvmem);
@@ -198,7 +198,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
return match ? match->data : NULL;
}
-@@ -950,19 +872,6 @@ struct nvmem_device *nvmem_register(cons
+@@ -949,19 +871,6 @@ struct nvmem_device *nvmem_register(cons
goto err_put_device;
}
@@ -218,7 +218,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
if (config->cells) {
rval = nvmem_add_cells(nvmem, config->cells, config->ncells);
if (rval)
-@@ -983,24 +892,24 @@ struct nvmem_device *nvmem_register(cons
+@@ -982,24 +891,24 @@ struct nvmem_device *nvmem_register(cons
if (rval)
goto err_remove_cells;
@@ -249,7 +249,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
if (config->compat)
nvmem_sysfs_remove_compat(nvmem, config);
err_put_device:
-@@ -1022,7 +931,7 @@ static void nvmem_device_release(struct
+@@ -1021,7 +930,7 @@ static void nvmem_device_release(struct
device_remove_bin_file(nvmem->base_dev, &nvmem->eeprom);
nvmem_device_remove_all_cells(nvmem);
@@ -258,7 +258,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
device_unregister(&nvmem->dev);
}
-@@ -1324,6 +1233,12 @@ nvmem_cell_get_from_lookup(struct device
+@@ -1323,6 +1232,12 @@ nvmem_cell_get_from_lookup(struct device
return cell;
}
@@ -271,7 +271,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
#if IS_ENABLED(CONFIG_OF)
static struct nvmem_cell_entry *
nvmem_find_cell_entry_by_node(struct nvmem_device *nvmem, struct device_node *np)
-@@ -1342,6 +1257,18 @@ nvmem_find_cell_entry_by_node(struct nvm
+@@ -1341,6 +1256,18 @@ nvmem_find_cell_entry_by_node(struct nvm
return cell;
}
@@ -290,7 +290,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
/**
* of_nvmem_cell_get() - Get a nvmem cell from given device node and cell id
*
-@@ -1404,16 +1331,29 @@ struct nvmem_cell *of_nvmem_cell_get(str
+@@ -1403,16 +1330,29 @@ struct nvmem_cell *of_nvmem_cell_get(str
return ERR_CAST(nvmem);
}
@@ -322,7 +322,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
return cell;
}
-@@ -1527,6 +1467,7 @@ void nvmem_cell_put(struct nvmem_cell *c
+@@ -1526,6 +1466,7 @@ void nvmem_cell_put(struct nvmem_cell *c
kfree(cell);
__nvmem_device_put(nvmem);
@@ -330,7 +330,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
}
EXPORT_SYMBOL_GPL(nvmem_cell_put);
-@@ -2104,11 +2045,22 @@ EXPORT_SYMBOL_GPL(nvmem_dev_name);
+@@ -2103,11 +2044,22 @@ EXPORT_SYMBOL_GPL(nvmem_dev_name);
static int __init nvmem_init(void)
{
diff --git a/target/linux/generic/backport-6.6/819-v6.8-0006-nvmem-core-Expose-cells-through-sysfs.patch b/target/linux/generic/backport-6.6/819-v6.8-0006-nvmem-core-Expose-cells-through-sysfs.patch
index 4a1f9aefc8..8442636b09 100644
--- a/target/linux/generic/backport-6.6/819-v6.8-0006-nvmem-core-Expose-cells-through-sysfs.patch
+++ b/target/linux/generic/backport-6.6/819-v6.8-0006-nvmem-core-Expose-cells-through-sysfs.patch
@@ -111,7 +111,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
static struct bin_attribute bin_attr_nvmem_eeprom_compat = {
.attr = {
.name = "eeprom",
-@@ -380,6 +427,68 @@ static void nvmem_sysfs_remove_compat(st
+@@ -379,6 +426,68 @@ static void nvmem_sysfs_remove_compat(st
device_remove_bin_file(nvmem->base_dev, &nvmem->eeprom);
}
@@ -180,7 +180,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
#else /* CONFIG_NVMEM_SYSFS */
static int nvmem_sysfs_setup_compat(struct nvmem_device *nvmem,
-@@ -739,11 +848,25 @@ static int nvmem_add_cells_from_fixed_la
+@@ -738,11 +847,25 @@ static int nvmem_add_cells_from_fixed_la
int nvmem_layout_register(struct nvmem_layout *layout)
{
@@ -207,7 +207,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
}
EXPORT_SYMBOL_GPL(nvmem_layout_register);
-@@ -902,10 +1025,20 @@ struct nvmem_device *nvmem_register(cons
+@@ -901,10 +1024,20 @@ struct nvmem_device *nvmem_register(cons
if (rval)
goto err_remove_dev;
diff --git a/target/linux/generic/backport-6.6/819-v6.8-0008-nvmem-layouts-refactor-.add_cells-callback-arguments.patch b/target/linux/generic/backport-6.6/819-v6.8-0008-nvmem-layouts-refactor-.add_cells-callback-arguments.patch
index 400004c617..a95770a059 100644
--- a/target/linux/generic/backport-6.6/819-v6.8-0008-nvmem-layouts-refactor-.add_cells-callback-arguments.patch
+++ b/target/linux/generic/backport-6.6/819-v6.8-0008-nvmem-layouts-refactor-.add_cells-callback-arguments.patch
@@ -44,7 +44,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
-@@ -854,7 +854,7 @@ int nvmem_layout_register(struct nvmem_l
+@@ -853,7 +853,7 @@ int nvmem_layout_register(struct nvmem_l
return -EINVAL;
/* Populate the cells */
diff --git a/target/linux/generic/backport-6.6/819-v6.8-0009-nvmem-drop-nvmem_layout_get_match_data.patch b/target/linux/generic/backport-6.6/819-v6.8-0009-nvmem-drop-nvmem_layout_get_match_data.patch
index 510f3dd841..291854bcb5 100644
--- a/target/linux/generic/backport-6.6/819-v6.8-0009-nvmem-drop-nvmem_layout_get_match_data.patch
+++ b/target/linux/generic/backport-6.6/819-v6.8-0009-nvmem-drop-nvmem_layout_get_match_data.patch
@@ -24,7 +24,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
-@@ -876,19 +876,6 @@ void nvmem_layout_unregister(struct nvme
+@@ -875,19 +875,6 @@ void nvmem_layout_unregister(struct nvme
}
EXPORT_SYMBOL_GPL(nvmem_layout_unregister);
diff --git a/target/linux/generic/backport-6.6/819-v6.8-0010-nvmem-core-add-nvmem_dev_size-helper.patch b/target/linux/generic/backport-6.6/819-v6.8-0010-nvmem-core-add-nvmem_dev_size-helper.patch
index ccdcc09736..93fd1ce6ad 100644
--- a/target/linux/generic/backport-6.6/819-v6.8-0010-nvmem-core-add-nvmem_dev_size-helper.patch
+++ b/target/linux/generic/backport-6.6/819-v6.8-0010-nvmem-core-add-nvmem_dev_size-helper.patch
@@ -21,7 +21,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
-@@ -2163,6 +2163,19 @@ const char *nvmem_dev_name(struct nvmem_
+@@ -2162,6 +2162,19 @@ const char *nvmem_dev_name(struct nvmem_
}
EXPORT_SYMBOL_GPL(nvmem_dev_name);
diff --git a/target/linux/generic/backport-6.6/820-v6.9-0002-nvmem-mtk-efuse-Register-MediaTek-socinfo-driver-fro.patch b/target/linux/generic/backport-6.6/820-v6.9-0002-nvmem-mtk-efuse-Register-MediaTek-socinfo-driver-fro.patch
new file mode 100644
index 0000000000..8e7c8233e2
--- /dev/null
+++ b/target/linux/generic/backport-6.6/820-v6.9-0002-nvmem-mtk-efuse-Register-MediaTek-socinfo-driver-fro.patch
@@ -0,0 +1,69 @@
+From 998f0633773b3432829fe45d2cd2ffb842f3c78e Mon Sep 17 00:00:00 2001
+From: William-tw Lin <william-tw.lin@mediatek.com>
+Date: Sat, 24 Feb 2024 11:45:07 +0000
+Subject: [PATCH] nvmem: mtk-efuse: Register MediaTek socinfo driver from efuse
+
+The socinfo driver reads chip information from eFuses and does not need
+any devicetree node. Register it from mtk-efuse.
+
+While at it, also add the name for this driver's nvmem_config.
+
+Signed-off-by: William-tw Lin <william-tw.lin@mediatek.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240224114516.86365-3-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/mtk-efuse.c | 21 ++++++++++++++++++++-
+ 1 file changed, 20 insertions(+), 1 deletion(-)
+
+--- a/drivers/nvmem/mtk-efuse.c
++++ b/drivers/nvmem/mtk-efuse.c
+@@ -68,6 +68,7 @@ static int mtk_efuse_probe(struct platfo
+ struct nvmem_config econfig = {};
+ struct mtk_efuse_priv *priv;
+ const struct mtk_efuse_pdata *pdata;
++ struct platform_device *socinfo;
+
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+@@ -85,11 +86,20 @@ static int mtk_efuse_probe(struct platfo
+ econfig.size = resource_size(res);
+ econfig.priv = priv;
+ econfig.dev = dev;
++ econfig.name = "mtk-efuse";
+ if (pdata->uses_post_processing)
+ econfig.fixup_dt_cell_info = &mtk_efuse_fixup_dt_cell_info;
+ nvmem = devm_nvmem_register(dev, &econfig);
++ if (IS_ERR(nvmem))
++ return PTR_ERR(nvmem);
+
+- return PTR_ERR_OR_ZERO(nvmem);
++ socinfo = platform_device_register_data(&pdev->dev, "mtk-socinfo",
++ PLATFORM_DEVID_AUTO, NULL, 0);
++ if (IS_ERR(socinfo))
++ dev_info(dev, "MediaTek SoC Information will be unavailable\n");
++
++ platform_set_drvdata(pdev, socinfo);
++ return 0;
+ }
+
+ static const struct mtk_efuse_pdata mtk_mt8186_efuse_pdata = {
+@@ -108,8 +118,17 @@ static const struct of_device_id mtk_efu
+ };
+ MODULE_DEVICE_TABLE(of, mtk_efuse_of_match);
+
++static void mtk_efuse_remove(struct platform_device *pdev)
++{
++ struct platform_device *socinfo = platform_get_drvdata(pdev);
++
++ if (!IS_ERR_OR_NULL(socinfo))
++ platform_device_unregister(socinfo);
++}
++
+ static struct platform_driver mtk_efuse_driver = {
+ .probe = mtk_efuse_probe,
++ .remove_new = mtk_efuse_remove,
+ .driver = {
+ .name = "mediatek,efuse",
+ .of_match_table = mtk_efuse_of_match,
diff --git a/target/linux/generic/backport-6.6/820-v6.9-0003-nvmem-zynqmp_nvmem-zynqmp_nvmem_probe-cleanup.patch b/target/linux/generic/backport-6.6/820-v6.9-0003-nvmem-zynqmp_nvmem-zynqmp_nvmem_probe-cleanup.patch
new file mode 100644
index 0000000000..0f90e548a2
--- /dev/null
+++ b/target/linux/generic/backport-6.6/820-v6.9-0003-nvmem-zynqmp_nvmem-zynqmp_nvmem_probe-cleanup.patch
@@ -0,0 +1,97 @@
+From 29be47fcd6a06ea2e79eeeca6e69ad1e23254a69 Mon Sep 17 00:00:00 2001
+From: Praveen Teja Kundanala <praveen.teja.kundanala@amd.com>
+Date: Sat, 24 Feb 2024 11:45:11 +0000
+Subject: [PATCH] nvmem: zynqmp_nvmem: zynqmp_nvmem_probe cleanup
+
+- Remove static nvmem_config declaration
+- Remove zynqmp_nvmem_data
+
+Signed-off-by: Praveen Teja Kundanala <praveen.teja.kundanala@amd.com>
+Acked-by: Kalyani Akula <Kalyani.akula@amd.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240224114516.86365-7-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/zynqmp_nvmem.c | 37 ++++++++++++------------------------
+ 1 file changed, 12 insertions(+), 25 deletions(-)
+
+--- a/drivers/nvmem/zynqmp_nvmem.c
++++ b/drivers/nvmem/zynqmp_nvmem.c
+@@ -1,6 +1,7 @@
+ // SPDX-License-Identifier: GPL-2.0+
+ /*
+ * Copyright (C) 2019 Xilinx, Inc.
++ * Copyright (C) 2022 - 2023, Advanced Micro Devices, Inc.
+ */
+
+ #include <linux/module.h>
+@@ -11,36 +12,25 @@
+
+ #define SILICON_REVISION_MASK 0xF
+
+-struct zynqmp_nvmem_data {
+- struct device *dev;
+- struct nvmem_device *nvmem;
+-};
+
+ static int zynqmp_nvmem_read(void *context, unsigned int offset,
+ void *val, size_t bytes)
+ {
++ struct device *dev = context;
+ int ret;
+- int idcode, version;
+- struct zynqmp_nvmem_data *priv = context;
++ int idcode;
++ int version;
+
+ ret = zynqmp_pm_get_chipid(&idcode, &version);
+ if (ret < 0)
+ return ret;
+
+- dev_dbg(priv->dev, "Read chipid val %x %x\n", idcode, version);
++ dev_dbg(dev, "Read chipid val %x %x\n", idcode, version);
+ *(int *)val = version & SILICON_REVISION_MASK;
+
+ return 0;
+ }
+
+-static struct nvmem_config econfig = {
+- .name = "zynqmp-nvmem",
+- .owner = THIS_MODULE,
+- .word_size = 1,
+- .size = 1,
+- .read_only = true,
+-};
+-
+ static const struct of_device_id zynqmp_nvmem_match[] = {
+ { .compatible = "xlnx,zynqmp-nvmem-fw", },
+ { /* sentinel */ },
+@@ -50,21 +40,18 @@ MODULE_DEVICE_TABLE(of, zynqmp_nvmem_mat
+ static int zynqmp_nvmem_probe(struct platform_device *pdev)
+ {
+ struct device *dev = &pdev->dev;
+- struct zynqmp_nvmem_data *priv;
++ struct nvmem_config econfig = {};
+
+- priv = devm_kzalloc(dev, sizeof(struct zynqmp_nvmem_data), GFP_KERNEL);
+- if (!priv)
+- return -ENOMEM;
+-
+- priv->dev = dev;
++ econfig.name = "zynqmp-nvmem";
++ econfig.owner = THIS_MODULE;
++ econfig.word_size = 1;
++ econfig.size = 1;
+ econfig.dev = dev;
+ econfig.add_legacy_fixed_of_cells = true;
++ econfig.read_only = true;
+ econfig.reg_read = zynqmp_nvmem_read;
+- econfig.priv = priv;
+-
+- priv->nvmem = devm_nvmem_register(dev, &econfig);
+
+- return PTR_ERR_OR_ZERO(priv->nvmem);
++ return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &econfig));
+ }
+
+ static struct platform_driver zynqmp_nvmem_driver = {
diff --git a/target/linux/generic/backport-6.6/820-v6.9-0004-nvmem-zynqmp_nvmem-Add-support-to-access-efuse.patch b/target/linux/generic/backport-6.6/820-v6.9-0004-nvmem-zynqmp_nvmem-Add-support-to-access-efuse.patch
new file mode 100644
index 0000000000..39c2f17835
--- /dev/null
+++ b/target/linux/generic/backport-6.6/820-v6.9-0004-nvmem-zynqmp_nvmem-Add-support-to-access-efuse.patch
@@ -0,0 +1,243 @@
+From 737c0c8d07b5f671c0a33cec95965fcb2d2ea893 Mon Sep 17 00:00:00 2001
+From: Praveen Teja Kundanala <praveen.teja.kundanala@amd.com>
+Date: Sat, 24 Feb 2024 11:45:12 +0000
+Subject: [PATCH] nvmem: zynqmp_nvmem: Add support to access efuse
+
+Add support to read/write efuse memory map of ZynqMP.
+Below are the offsets of ZynqMP efuse memory map
+ 0 - SOC version(read only)
+ 0xC - 0xFC -ZynqMP specific purpose efuses
+ 0x100 - 0x17F - Physical Unclonable Function(PUF)
+ efuses repurposed as user efuses
+
+Signed-off-by: Praveen Teja Kundanala <praveen.teja.kundanala@amd.com>
+Acked-by: Kalyani Akula <Kalyani.akula@amd.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240224114516.86365-8-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/zynqmp_nvmem.c | 186 +++++++++++++++++++++++++++++++++--
+ 1 file changed, 176 insertions(+), 10 deletions(-)
+
+--- a/drivers/nvmem/zynqmp_nvmem.c
++++ b/drivers/nvmem/zynqmp_nvmem.c
+@@ -4,6 +4,7 @@
+ * Copyright (C) 2022 - 2023, Advanced Micro Devices, Inc.
+ */
+
++#include <linux/dma-mapping.h>
+ #include <linux/module.h>
+ #include <linux/nvmem-provider.h>
+ #include <linux/of.h>
+@@ -11,24 +12,189 @@
+ #include <linux/firmware/xlnx-zynqmp.h>
+
+ #define SILICON_REVISION_MASK 0xF
++#define P_USER_0_64_UPPER_MASK GENMASK(31, 16)
++#define P_USER_127_LOWER_4_BIT_MASK GENMASK(3, 0)
++#define WORD_INBYTES 4
++#define SOC_VER_SIZE 0x4
++#define EFUSE_MEMORY_SIZE 0x177
++#define UNUSED_SPACE 0x8
++#define ZYNQMP_NVMEM_SIZE (SOC_VER_SIZE + UNUSED_SPACE + \
++ EFUSE_MEMORY_SIZE)
++#define SOC_VERSION_OFFSET 0x0
++#define EFUSE_START_OFFSET 0xC
++#define EFUSE_END_OFFSET 0xFC
++#define EFUSE_PUF_START_OFFSET 0x100
++#define EFUSE_PUF_MID_OFFSET 0x140
++#define EFUSE_PUF_END_OFFSET 0x17F
++#define EFUSE_NOT_ENABLED 29
+
++/*
++ * efuse access type
++ */
++enum efuse_access {
++ EFUSE_READ = 0,
++ EFUSE_WRITE
++};
++
++/**
++ * struct xilinx_efuse - the basic structure
++ * @src: address of the buffer to store the data to be write/read
++ * @size: read/write word count
++ * @offset: read/write offset
++ * @flag: 0 - represents efuse read and 1- represents efuse write
++ * @pufuserfuse:0 - represents non-puf efuses, offset is used for read/write
++ * 1 - represents puf user fuse row number.
++ *
++ * this structure stores all the required details to
++ * read/write efuse memory.
++ */
++struct xilinx_efuse {
++ u64 src;
++ u32 size;
++ u32 offset;
++ enum efuse_access flag;
++ u32 pufuserfuse;
++};
++
++static int zynqmp_efuse_access(void *context, unsigned int offset,
++ void *val, size_t bytes, enum efuse_access flag,
++ unsigned int pufflag)
++{
++ struct device *dev = context;
++ struct xilinx_efuse *efuse;
++ dma_addr_t dma_addr;
++ dma_addr_t dma_buf;
++ size_t words = bytes / WORD_INBYTES;
++ int ret;
++ int value;
++ char *data;
+
+-static int zynqmp_nvmem_read(void *context, unsigned int offset,
+- void *val, size_t bytes)
++ if (bytes % WORD_INBYTES != 0) {
++ dev_err(dev, "Bytes requested should be word aligned\n");
++ return -EOPNOTSUPP;
++ }
++
++ if (pufflag == 0 && offset % WORD_INBYTES) {
++ dev_err(dev, "Offset requested should be word aligned\n");
++ return -EOPNOTSUPP;
++ }
++
++ if (pufflag == 1 && flag == EFUSE_WRITE) {
++ memcpy(&value, val, bytes);
++ if ((offset == EFUSE_PUF_START_OFFSET ||
++ offset == EFUSE_PUF_MID_OFFSET) &&
++ value & P_USER_0_64_UPPER_MASK) {
++ dev_err(dev, "Only lower 4 bytes are allowed to be programmed in P_USER_0 & P_USER_64\n");
++ return -EOPNOTSUPP;
++ }
++
++ if (offset == EFUSE_PUF_END_OFFSET &&
++ (value & P_USER_127_LOWER_4_BIT_MASK)) {
++ dev_err(dev, "Only MSB 28 bits are allowed to be programmed for P_USER_127\n");
++ return -EOPNOTSUPP;
++ }
++ }
++
++ efuse = dma_alloc_coherent(dev, sizeof(struct xilinx_efuse),
++ &dma_addr, GFP_KERNEL);
++ if (!efuse)
++ return -ENOMEM;
++
++ data = dma_alloc_coherent(dev, sizeof(bytes),
++ &dma_buf, GFP_KERNEL);
++ if (!data) {
++ ret = -ENOMEM;
++ goto efuse_data_fail;
++ }
++
++ if (flag == EFUSE_WRITE) {
++ memcpy(data, val, bytes);
++ efuse->flag = EFUSE_WRITE;
++ } else {
++ efuse->flag = EFUSE_READ;
++ }
++
++ efuse->src = dma_buf;
++ efuse->size = words;
++ efuse->offset = offset;
++ efuse->pufuserfuse = pufflag;
++
++ zynqmp_pm_efuse_access(dma_addr, (u32 *)&ret);
++ if (ret != 0) {
++ if (ret == EFUSE_NOT_ENABLED) {
++ dev_err(dev, "efuse access is not enabled\n");
++ ret = -EOPNOTSUPP;
++ } else {
++ dev_err(dev, "Error in efuse read %x\n", ret);
++ ret = -EPERM;
++ }
++ goto efuse_access_err;
++ }
++
++ if (flag == EFUSE_READ)
++ memcpy(val, data, bytes);
++efuse_access_err:
++ dma_free_coherent(dev, sizeof(bytes),
++ data, dma_buf);
++efuse_data_fail:
++ dma_free_coherent(dev, sizeof(struct xilinx_efuse),
++ efuse, dma_addr);
++
++ return ret;
++}
++
++static int zynqmp_nvmem_read(void *context, unsigned int offset, void *val, size_t bytes)
+ {
+ struct device *dev = context;
+ int ret;
++ int pufflag = 0;
+ int idcode;
+ int version;
+
+- ret = zynqmp_pm_get_chipid(&idcode, &version);
+- if (ret < 0)
+- return ret;
++ if (offset >= EFUSE_PUF_START_OFFSET && offset <= EFUSE_PUF_END_OFFSET)
++ pufflag = 1;
++
++ switch (offset) {
++ /* Soc version offset is zero */
++ case SOC_VERSION_OFFSET:
++ if (bytes != SOC_VER_SIZE)
++ return -EOPNOTSUPP;
++
++ ret = zynqmp_pm_get_chipid((u32 *)&idcode, (u32 *)&version);
++ if (ret < 0)
++ return ret;
++
++ dev_dbg(dev, "Read chipid val %x %x\n", idcode, version);
++ *(int *)val = version & SILICON_REVISION_MASK;
++ break;
++ /* Efuse offset starts from 0xc */
++ case EFUSE_START_OFFSET ... EFUSE_END_OFFSET:
++ case EFUSE_PUF_START_OFFSET ... EFUSE_PUF_END_OFFSET:
++ ret = zynqmp_efuse_access(context, offset, val,
++ bytes, EFUSE_READ, pufflag);
++ break;
++ default:
++ *(u32 *)val = 0xDEADBEEF;
++ ret = 0;
++ break;
++ }
++
++ return ret;
++}
++
++static int zynqmp_nvmem_write(void *context,
++ unsigned int offset, void *val, size_t bytes)
++{
++ int pufflag = 0;
++
++ if (offset < EFUSE_START_OFFSET || offset > EFUSE_PUF_END_OFFSET)
++ return -EOPNOTSUPP;
+
+- dev_dbg(dev, "Read chipid val %x %x\n", idcode, version);
+- *(int *)val = version & SILICON_REVISION_MASK;
++ if (offset >= EFUSE_PUF_START_OFFSET && offset <= EFUSE_PUF_END_OFFSET)
++ pufflag = 1;
+
+- return 0;
++ return zynqmp_efuse_access(context, offset,
++ val, bytes, EFUSE_WRITE, pufflag);
+ }
+
+ static const struct of_device_id zynqmp_nvmem_match[] = {
+@@ -45,11 +211,11 @@ static int zynqmp_nvmem_probe(struct pla
+ econfig.name = "zynqmp-nvmem";
+ econfig.owner = THIS_MODULE;
+ econfig.word_size = 1;
+- econfig.size = 1;
++ econfig.size = ZYNQMP_NVMEM_SIZE;
+ econfig.dev = dev;
+ econfig.add_legacy_fixed_of_cells = true;
+- econfig.read_only = true;
+ econfig.reg_read = zynqmp_nvmem_read;
++ econfig.reg_write = zynqmp_nvmem_write;
+
+ return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &econfig));
+ }
diff --git a/target/linux/generic/backport-6.6/820-v6.9-0005-nvmem-mtk-efuse-Drop-NVMEM-device-name.patch b/target/linux/generic/backport-6.6/820-v6.9-0005-nvmem-mtk-efuse-Drop-NVMEM-device-name.patch
new file mode 100644
index 0000000000..c67399cb13
--- /dev/null
+++ b/target/linux/generic/backport-6.6/820-v6.9-0005-nvmem-mtk-efuse-Drop-NVMEM-device-name.patch
@@ -0,0 +1,35 @@
+From 76c345edef754b16cab81ad9452cc49c09e67066 Mon Sep 17 00:00:00 2001
+From: Chen-Yu Tsai <wenst@chromium.org>
+Date: Sat, 24 Feb 2024 11:45:14 +0000
+Subject: [PATCH] nvmem: mtk-efuse: Drop NVMEM device name
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The MT8183 has not one but two efuse devices. The static name and ID
+causes the second efuse device to fail to probe, due to duplicate sysfs
+entries.
+
+With the rework of the mtk-socinfo driver, lookup by name is no longer
+necessary. The custom name can simply be dropped.
+
+Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Tested-by: "Nícolas F. R. A. Prado" <nfraprado@collabora.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240224114516.86365-10-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/mtk-efuse.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/drivers/nvmem/mtk-efuse.c
++++ b/drivers/nvmem/mtk-efuse.c
+@@ -86,7 +86,6 @@ static int mtk_efuse_probe(struct platfo
+ econfig.size = resource_size(res);
+ econfig.priv = priv;
+ econfig.dev = dev;
+- econfig.name = "mtk-efuse";
+ if (pdata->uses_post_processing)
+ econfig.fixup_dt_cell_info = &mtk_efuse_fixup_dt_cell_info;
+ nvmem = devm_nvmem_register(dev, &econfig);
diff --git a/target/linux/generic/backport-6.6/820-v6.9-0006-nvmem-core-make-nvmem_layout_bus_type-const.patch b/target/linux/generic/backport-6.6/820-v6.9-0006-nvmem-core-make-nvmem_layout_bus_type-const.patch
new file mode 100644
index 0000000000..506092e359
--- /dev/null
+++ b/target/linux/generic/backport-6.6/820-v6.9-0006-nvmem-core-make-nvmem_layout_bus_type-const.patch
@@ -0,0 +1,33 @@
+From 8ec0faf2572216b4e25d6829cd41cf3ee2dab979 Mon Sep 17 00:00:00 2001
+From: "Ricardo B. Marliere" <ricardo@marliere.net>
+Date: Sat, 24 Feb 2024 11:45:15 +0000
+Subject: [PATCH] nvmem: core: make nvmem_layout_bus_type const
+
+Since commit d492cc2573a0 ("driver core: device.h: make struct bus_type
+a const *"), the driver core can properly handle constant struct
+bus_type, move the nvmem_layout_bus_type variable to be a constant
+structure as well, placing it into read-only memory which can not be
+modified at runtime.
+
+Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Suggested-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: "Ricardo B. Marliere" <ricardo@marliere.net>
+Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240224114516.86365-11-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/layouts.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/nvmem/layouts.c
++++ b/drivers/nvmem/layouts.c
+@@ -45,7 +45,7 @@ static void nvmem_layout_bus_remove(stru
+ return drv->remove(layout);
+ }
+
+-static struct bus_type nvmem_layout_bus_type = {
++static const struct bus_type nvmem_layout_bus_type = {
+ .name = "nvmem-layout",
+ .match = nvmem_layout_bus_match,
+ .probe = nvmem_layout_bus_probe,
diff --git a/target/linux/generic/backport-6.6/820-v6.9-0007-nvmem-core-Print-error-on-wrong-bits-DT-property.patch b/target/linux/generic/backport-6.6/820-v6.9-0007-nvmem-core-Print-error-on-wrong-bits-DT-property.patch
new file mode 100644
index 0000000000..aa4e0ab04a
--- /dev/null
+++ b/target/linux/generic/backport-6.6/820-v6.9-0007-nvmem-core-Print-error-on-wrong-bits-DT-property.patch
@@ -0,0 +1,32 @@
+From def3173d4f17b37cecbd74d7c269a080b0b01598 Mon Sep 17 00:00:00 2001
+From: Markus Schneider-Pargmann <msp@baylibre.com>
+Date: Sat, 24 Feb 2024 11:45:16 +0000
+Subject: [PATCH] nvmem: core: Print error on wrong bits DT property
+
+The algorithms in nvmem core are built with the constraint that
+bit_offset < 8. If bit_offset is greater the results are wrong. Print an
+error if the devicetree 'bits' property is outside of the valid range
+and abort parsing.
+
+Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240224114516.86365-12-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/core.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/nvmem/core.c
++++ b/drivers/nvmem/core.c
+@@ -805,6 +805,11 @@ static int nvmem_add_cells_from_dt(struc
+ if (addr && len == (2 * sizeof(u32))) {
+ info.bit_offset = be32_to_cpup(addr++);
+ info.nbits = be32_to_cpup(addr);
++ if (info.bit_offset >= BITS_PER_BYTE || info.nbits < 1) {
++ dev_err(dev, "nvmem: invalid bits on %pOF\n", child);
++ of_node_put(child);
++ return -EINVAL;
++ }
+ }
+
+ info.np = of_node_get(child);
diff --git a/target/linux/generic/backport-6.6/821-v6.10-0001-nvmem-layouts-store-owner-from-modules-with-nvmem_la.patch b/target/linux/generic/backport-6.6/821-v6.10-0001-nvmem-layouts-store-owner-from-modules-with-nvmem_la.patch
new file mode 100644
index 0000000000..418d2c82b2
--- /dev/null
+++ b/target/linux/generic/backport-6.6/821-v6.10-0001-nvmem-layouts-store-owner-from-modules-with-nvmem_la.patch
@@ -0,0 +1,61 @@
+From 6d0ca4a2a7e25f9ad07c1f335f20b4d9e048cdd5 Mon Sep 17 00:00:00 2001
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Date: Tue, 30 Apr 2024 09:49:11 +0100
+Subject: [PATCH] nvmem: layouts: store owner from modules with
+ nvmem_layout_driver_register()
+
+Modules registering driver with nvmem_layout_driver_register() might
+forget to set .owner field. The field is used by some of other kernel
+parts for reference counting (try_module_get()), so it is expected that
+drivers will set it.
+
+Solve the problem by moving this task away from the drivers to the core
+code, just like we did for platform_driver in
+commit 9447057eaff8 ("platform_device: use a macro instead of
+platform_driver_register").
+
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Michael Walle <mwalle@kernel.org>
+Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240430084921.33387-2-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/layouts.c | 6 ++++--
+ include/linux/nvmem-provider.h | 5 ++++-
+ 2 files changed, 8 insertions(+), 3 deletions(-)
+
+--- a/drivers/nvmem/layouts.c
++++ b/drivers/nvmem/layouts.c
+@@ -52,13 +52,15 @@ static const struct bus_type nvmem_layou
+ .remove = nvmem_layout_bus_remove,
+ };
+
+-int nvmem_layout_driver_register(struct nvmem_layout_driver *drv)
++int __nvmem_layout_driver_register(struct nvmem_layout_driver *drv,
++ struct module *owner)
+ {
+ drv->driver.bus = &nvmem_layout_bus_type;
++ drv->driver.owner = owner;
+
+ return driver_register(&drv->driver);
+ }
+-EXPORT_SYMBOL_GPL(nvmem_layout_driver_register);
++EXPORT_SYMBOL_GPL(__nvmem_layout_driver_register);
+
+ void nvmem_layout_driver_unregister(struct nvmem_layout_driver *drv)
+ {
+--- a/include/linux/nvmem-provider.h
++++ b/include/linux/nvmem-provider.h
+@@ -199,7 +199,10 @@ int nvmem_add_one_cell(struct nvmem_devi
+ int nvmem_layout_register(struct nvmem_layout *layout);
+ void nvmem_layout_unregister(struct nvmem_layout *layout);
+
+-int nvmem_layout_driver_register(struct nvmem_layout_driver *drv);
++#define nvmem_layout_driver_register(drv) \
++ __nvmem_layout_driver_register(drv, THIS_MODULE)
++int __nvmem_layout_driver_register(struct nvmem_layout_driver *drv,
++ struct module *owner);
+ void nvmem_layout_driver_unregister(struct nvmem_layout_driver *drv);
+ #define module_nvmem_layout_driver(__nvmem_layout_driver) \
+ module_driver(__nvmem_layout_driver, nvmem_layout_driver_register, \
diff --git a/target/linux/generic/backport-6.6/821-v6.10-0002-nvmem-layouts-onie-tlv-drop-driver-owner-initializat.patch b/target/linux/generic/backport-6.6/821-v6.10-0002-nvmem-layouts-onie-tlv-drop-driver-owner-initializat.patch
new file mode 100644
index 0000000000..b483dd243b
--- /dev/null
+++ b/target/linux/generic/backport-6.6/821-v6.10-0002-nvmem-layouts-onie-tlv-drop-driver-owner-initializat.patch
@@ -0,0 +1,28 @@
+From 21833338eccb91194fec6ba7548d9c454824eca0 Mon Sep 17 00:00:00 2001
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Date: Tue, 30 Apr 2024 09:49:12 +0100
+Subject: [PATCH] nvmem: layouts: onie-tlv: drop driver owner initialization
+
+Core in nvmem_layout_driver_register() already sets the .owner, so
+driver does not need to.
+
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Michael Walle <mwalle@kernel.org>
+Acked-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240430084921.33387-3-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/layouts/onie-tlv.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/drivers/nvmem/layouts/onie-tlv.c
++++ b/drivers/nvmem/layouts/onie-tlv.c
+@@ -247,7 +247,6 @@ MODULE_DEVICE_TABLE(of, onie_tlv_of_matc
+
+ static struct nvmem_layout_driver onie_tlv_layout = {
+ .driver = {
+- .owner = THIS_MODULE,
+ .name = "onie-tlv-layout",
+ .of_match_table = onie_tlv_of_match_table,
+ },
diff --git a/target/linux/generic/backport-6.6/821-v6.10-0003-nvmem-layouts-sl28vpd-drop-driver-owner-initializati.patch b/target/linux/generic/backport-6.6/821-v6.10-0003-nvmem-layouts-sl28vpd-drop-driver-owner-initializati.patch
new file mode 100644
index 0000000000..472a65feca
--- /dev/null
+++ b/target/linux/generic/backport-6.6/821-v6.10-0003-nvmem-layouts-sl28vpd-drop-driver-owner-initializati.patch
@@ -0,0 +1,28 @@
+From 23fd602f21953c03c0714257d36685cd6b486f04 Mon Sep 17 00:00:00 2001
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Date: Tue, 30 Apr 2024 09:49:13 +0100
+Subject: [PATCH] nvmem: layouts: sl28vpd: drop driver owner initialization
+
+Core in nvmem_layout_driver_register() already sets the .owner, so
+driver does not need to.
+
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Michael Walle <mwalle@kernel.org>
+Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240430084921.33387-4-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/layouts/sl28vpd.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/drivers/nvmem/layouts/sl28vpd.c
++++ b/drivers/nvmem/layouts/sl28vpd.c
+@@ -156,7 +156,6 @@ MODULE_DEVICE_TABLE(of, sl28vpd_of_match
+
+ static struct nvmem_layout_driver sl28vpd_layout = {
+ .driver = {
+- .owner = THIS_MODULE,
+ .name = "kontron-sl28vpd-layout",
+ .of_match_table = sl28vpd_of_match_table,
+ },
diff --git a/target/linux/generic/backport-6.6/821-v6.10-0004-nvmem-sc27xx-fix-module-autoloading.patch b/target/linux/generic/backport-6.6/821-v6.10-0004-nvmem-sc27xx-fix-module-autoloading.patch
new file mode 100644
index 0000000000..8f33f2ab61
--- /dev/null
+++ b/target/linux/generic/backport-6.6/821-v6.10-0004-nvmem-sc27xx-fix-module-autoloading.patch
@@ -0,0 +1,26 @@
+From dc3d88ade857ba3dca34f008e0b0aed3ef79cb15 Mon Sep 17 00:00:00 2001
+From: Krzysztof Kozlowski <krzk@kernel.org>
+Date: Tue, 30 Apr 2024 09:49:14 +0100
+Subject: [PATCH] nvmem: sc27xx: fix module autoloading
+
+Add MODULE_DEVICE_TABLE(), so the module could be properly autoloaded
+based on the alias from of_device_id table.
+
+Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240430084921.33387-5-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/sc27xx-efuse.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/nvmem/sc27xx-efuse.c
++++ b/drivers/nvmem/sc27xx-efuse.c
+@@ -262,6 +262,7 @@ static const struct of_device_id sc27xx_
+ { .compatible = "sprd,sc2730-efuse", .data = &sc2730_edata},
+ { }
+ };
++MODULE_DEVICE_TABLE(of, sc27xx_efuse_of_match);
+
+ static struct platform_driver sc27xx_efuse_driver = {
+ .probe = sc27xx_efuse_probe,
diff --git a/target/linux/generic/backport-6.6/821-v6.10-0005-nvmem-sprd-fix-module-autoloading.patch b/target/linux/generic/backport-6.6/821-v6.10-0005-nvmem-sprd-fix-module-autoloading.patch
new file mode 100644
index 0000000000..0953c92340
--- /dev/null
+++ b/target/linux/generic/backport-6.6/821-v6.10-0005-nvmem-sprd-fix-module-autoloading.patch
@@ -0,0 +1,26 @@
+From 154c1ec943e34f3188c9305b0c91d5e7dc1373b8 Mon Sep 17 00:00:00 2001
+From: Krzysztof Kozlowski <krzk@kernel.org>
+Date: Tue, 30 Apr 2024 09:49:15 +0100
+Subject: [PATCH] nvmem: sprd: fix module autoloading
+
+Add MODULE_DEVICE_TABLE(), so the module could be properly autoloaded
+based on the alias from of_device_id table.
+
+Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240430084921.33387-6-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/sprd-efuse.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/nvmem/sprd-efuse.c
++++ b/drivers/nvmem/sprd-efuse.c
+@@ -426,6 +426,7 @@ static const struct of_device_id sprd_ef
+ { .compatible = "sprd,ums312-efuse", .data = &ums312_data },
+ { }
+ };
++MODULE_DEVICE_TABLE(of, sprd_efuse_of_match);
+
+ static struct platform_driver sprd_efuse_driver = {
+ .probe = sprd_efuse_probe,
diff --git a/target/linux/generic/backport-6.6/821-v6.10-0006-nvmem-core-switch-to-use-device_add_groups.patch b/target/linux/generic/backport-6.6/821-v6.10-0006-nvmem-core-switch-to-use-device_add_groups.patch
new file mode 100644
index 0000000000..14baafc6b8
--- /dev/null
+++ b/target/linux/generic/backport-6.6/821-v6.10-0006-nvmem-core-switch-to-use-device_add_groups.patch
@@ -0,0 +1,32 @@
+From 8d8fc146dd7a0d6a6b37695747a524310dfb9d57 Mon Sep 17 00:00:00 2001
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Date: Tue, 30 Apr 2024 09:49:16 +0100
+Subject: [PATCH] nvmem: core: switch to use device_add_groups()
+
+devm_device_add_groups() is being removed from the kernel, so move the
+nvmem driver to use device_add_groups() instead. The logic is
+identical, when the device is removed the driver core will properly
+clean up and remove the groups, and the memory used by the attribute
+groups will be freed because it was created with dev_* calls, so this is
+functionally identical overall.
+
+Cc: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Link: https://lore.kernel.org/r/20240430084921.33387-7-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/nvmem/core.c
++++ b/drivers/nvmem/core.c
+@@ -476,7 +476,7 @@ static int nvmem_populate_sysfs_cells(st
+
+ nvmem_cells_group.bin_attrs = cells_attrs;
+
+- ret = devm_device_add_groups(&nvmem->dev, nvmem_cells_groups);
++ ret = device_add_groups(&nvmem->dev, nvmem_cells_groups);
+ if (ret)
+ goto unlock_mutex;
+
diff --git a/target/linux/generic/backport-6.6/821-v6.10-0007-nvmem-lpc18xx_eeprom-Convert-to-platform-remove-call.patch b/target/linux/generic/backport-6.6/821-v6.10-0007-nvmem-lpc18xx_eeprom-Convert-to-platform-remove-call.patch
new file mode 100644
index 0000000000..27d9270d31
--- /dev/null
+++ b/target/linux/generic/backport-6.6/821-v6.10-0007-nvmem-lpc18xx_eeprom-Convert-to-platform-remove-call.patch
@@ -0,0 +1,57 @@
+From 693d2f629962628ddefc88f4b6b453edda5ac32e Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= <u.kleine-koenig@pengutronix.de>
+Date: Tue, 30 Apr 2024 09:49:17 +0100
+Subject: [PATCH] nvmem: lpc18xx_eeprom: Convert to platform remove callback
+ returning void
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The .remove() callback for a platform driver returns an int which makes
+many driver authors wrongly assume it's possible to do error handling by
+returning an error code. However the value returned is ignored (apart
+from emitting a warning) and this typically results in resource leaks.
+
+To improve here there is a quest to make the remove callback return
+void. In the first step of this quest all drivers are converted to
+.remove_new(), which already returns void. Eventually after all drivers
+are converted, .remove_new() will be renamed to .remove().
+
+Trivially convert this driver from always returning zero in the remove
+callback to the void returning variant.
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Acked-by: Vladimir Zapolskiy <vz@mleia.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240430084921.33387-8-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/lpc18xx_eeprom.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+--- a/drivers/nvmem/lpc18xx_eeprom.c
++++ b/drivers/nvmem/lpc18xx_eeprom.c
+@@ -249,13 +249,11 @@ err_clk:
+ return ret;
+ }
+
+-static int lpc18xx_eeprom_remove(struct platform_device *pdev)
++static void lpc18xx_eeprom_remove(struct platform_device *pdev)
+ {
+ struct lpc18xx_eeprom_dev *eeprom = platform_get_drvdata(pdev);
+
+ clk_disable_unprepare(eeprom->clk);
+-
+- return 0;
+ }
+
+ static const struct of_device_id lpc18xx_eeprom_of_match[] = {
+@@ -266,7 +264,7 @@ MODULE_DEVICE_TABLE(of, lpc18xx_eeprom_o
+
+ static struct platform_driver lpc18xx_eeprom_driver = {
+ .probe = lpc18xx_eeprom_probe,
+- .remove = lpc18xx_eeprom_remove,
++ .remove_new = lpc18xx_eeprom_remove,
+ .driver = {
+ .name = "lpc18xx-eeprom",
+ .of_match_table = lpc18xx_eeprom_of_match,
diff --git a/target/linux/generic/backport-6.6/821-v6.10-0008-nvmem-meson-mx-efuse-Remove-nvmem_device-from-efuse-.patch b/target/linux/generic/backport-6.6/821-v6.10-0008-nvmem-meson-mx-efuse-Remove-nvmem_device-from-efuse-.patch
new file mode 100644
index 0000000000..0b56ccc785
--- /dev/null
+++ b/target/linux/generic/backport-6.6/821-v6.10-0008-nvmem-meson-mx-efuse-Remove-nvmem_device-from-efuse-.patch
@@ -0,0 +1,50 @@
+From 2a1ad6b75292d38aa2f6ded7335979e0632521da Mon Sep 17 00:00:00 2001
+From: Mukesh Ojha <quic_mojha@quicinc.com>
+Date: Tue, 30 Apr 2024 09:49:21 +0100
+Subject: [PATCH] nvmem: meson-mx-efuse: Remove nvmem_device from efuse struct
+
+nvmem_device is used at one place while registering nvmem
+device and it is not required to be present in efuse struct
+for just this purpose.
+
+Drop nvmem_device and manage with nvmem device stack variable.
+
+Signed-off-by: Mukesh Ojha <quic_mojha@quicinc.com>
+Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240430084921.33387-12-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/meson-mx-efuse.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/nvmem/meson-mx-efuse.c
++++ b/drivers/nvmem/meson-mx-efuse.c
+@@ -43,7 +43,6 @@ struct meson_mx_efuse_platform_data {
+ struct meson_mx_efuse {
+ void __iomem *base;
+ struct clk *core_clk;
+- struct nvmem_device *nvmem;
+ struct nvmem_config config;
+ };
+
+@@ -193,6 +192,7 @@ static int meson_mx_efuse_probe(struct p
+ {
+ const struct meson_mx_efuse_platform_data *drvdata;
+ struct meson_mx_efuse *efuse;
++ struct nvmem_device *nvmem;
+
+ drvdata = of_device_get_match_data(&pdev->dev);
+ if (!drvdata)
+@@ -223,9 +223,9 @@ static int meson_mx_efuse_probe(struct p
+ return PTR_ERR(efuse->core_clk);
+ }
+
+- efuse->nvmem = devm_nvmem_register(&pdev->dev, &efuse->config);
++ nvmem = devm_nvmem_register(&pdev->dev, &efuse->config);
+
+- return PTR_ERR_OR_ZERO(efuse->nvmem);
++ return PTR_ERR_OR_ZERO(nvmem);
+ }
+
+ static struct platform_driver meson_mx_efuse_driver = {
diff --git a/target/linux/generic/backport-6.6/822-v6.11-0001-nvmem-add-missing-MODULE_DESCRIPTION-macros.patch b/target/linux/generic/backport-6.6/822-v6.11-0001-nvmem-add-missing-MODULE_DESCRIPTION-macros.patch
new file mode 100644
index 0000000000..a8ce832408
--- /dev/null
+++ b/target/linux/generic/backport-6.6/822-v6.11-0001-nvmem-add-missing-MODULE_DESCRIPTION-macros.patch
@@ -0,0 +1,48 @@
+From c553bad4c5fc5ae44bd2fcaa73e1d6bedfb1c35c Mon Sep 17 00:00:00 2001
+From: Jeff Johnson <quic_jjohnson@quicinc.com>
+Date: Fri, 5 Jul 2024 08:48:38 +0100
+Subject: [PATCH] nvmem: add missing MODULE_DESCRIPTION() macros
+
+make allmodconfig && make W=1 C=1 reports:
+WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/nvmem/nvmem-apple-efuses.o
+WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/nvmem/nvmem_brcm_nvram.o
+WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/nvmem/nvmem_u-boot-env.o
+
+Add the missing invocations of the MODULE_DESCRIPTION() macro.
+
+Signed-off-by: Jeff Johnson <quic_jjohnson@quicinc.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240705074852.423202-2-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/apple-efuses.c | 1 +
+ drivers/nvmem/brcm_nvram.c | 1 +
+ drivers/nvmem/u-boot-env.c | 1 +
+ 3 files changed, 3 insertions(+)
+
+--- a/drivers/nvmem/apple-efuses.c
++++ b/drivers/nvmem/apple-efuses.c
+@@ -78,4 +78,5 @@ static struct platform_driver apple_efus
+ module_platform_driver(apple_efuses_driver);
+
+ MODULE_AUTHOR("Sven Peter <sven@svenpeter.dev>");
++MODULE_DESCRIPTION("Apple SoC eFuse driver");
+ MODULE_LICENSE("GPL");
+--- a/drivers/nvmem/brcm_nvram.c
++++ b/drivers/nvmem/brcm_nvram.c
+@@ -253,5 +253,6 @@ static int __init brcm_nvram_init(void)
+ subsys_initcall_sync(brcm_nvram_init);
+
+ MODULE_AUTHOR("Rafał Miłecki");
++MODULE_DESCRIPTION("Broadcom I/O-mapped NVRAM support driver");
+ MODULE_LICENSE("GPL");
+ MODULE_DEVICE_TABLE(of, brcm_nvram_of_match_table);
+--- a/drivers/nvmem/u-boot-env.c
++++ b/drivers/nvmem/u-boot-env.c
+@@ -249,5 +249,6 @@ static struct platform_driver u_boot_env
+ module_platform_driver(u_boot_env_driver);
+
+ MODULE_AUTHOR("Rafał Miłecki");
++MODULE_DESCRIPTION("U-Boot environment variables support module");
+ MODULE_LICENSE("GPL");
+ MODULE_DEVICE_TABLE(of, u_boot_env_of_match_table);
diff --git a/target/linux/generic/backport-6.6/822-v6.11-0002-nvmem-meson-efuse-Replacing-the-use-of-of_node_put-t.patch b/target/linux/generic/backport-6.6/822-v6.11-0002-nvmem-meson-efuse-Replacing-the-use-of-of_node_put-t.patch
new file mode 100644
index 0000000000..05c82dbf6f
--- /dev/null
+++ b/target/linux/generic/backport-6.6/822-v6.11-0002-nvmem-meson-efuse-Replacing-the-use-of-of_node_put-t.patch
@@ -0,0 +1,48 @@
+From 5fecb932607d83d37a703c731268e9d9051457f5 Mon Sep 17 00:00:00 2001
+From: MarileneGarcia <marilene.agarcia@gmail.com>
+Date: Fri, 5 Jul 2024 08:48:40 +0100
+Subject: [PATCH] nvmem: meson-efuse: Replacing the use of of_node_put to
+ __free
+
+Use __free for device_node values, and thus drop calls to
+of_node_put.
+
+The goal is to reduce memory management issues by using this
+scope-based of_node_put() cleanup to simplify function exit
+handling. When using __free a resource is allocated within a
+block, it is automatically freed at the end of the block.
+
+Suggested-by: Julia Lawall <julia.lawall@inria.fr>
+Signed-off-by: MarileneGarcia <marilene.agarcia@gmail.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240705074852.423202-4-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/meson-efuse.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+--- a/drivers/nvmem/meson-efuse.c
++++ b/drivers/nvmem/meson-efuse.c
+@@ -48,20 +48,19 @@ static int meson_efuse_probe(struct plat
+ {
+ struct device *dev = &pdev->dev;
+ struct meson_sm_firmware *fw;
+- struct device_node *sm_np;
+ struct nvmem_device *nvmem;
+ struct nvmem_config *econfig;
+ struct clk *clk;
+ unsigned int size;
++ struct device_node *sm_np __free(device_node) =
++ of_parse_phandle(pdev->dev.of_node, "secure-monitor", 0);
+
+- sm_np = of_parse_phandle(pdev->dev.of_node, "secure-monitor", 0);
+ if (!sm_np) {
+ dev_err(&pdev->dev, "no secure-monitor node\n");
+ return -ENODEV;
+ }
+
+ fw = meson_sm_get(sm_np);
+- of_node_put(sm_np);
+ if (!fw)
+ return -EPROBE_DEFER;
+
diff --git a/target/linux/generic/backport-6.6/822-v6.11-0004-nvmem-rockchip-otp-Set-type-to-OTP.patch b/target/linux/generic/backport-6.6/822-v6.11-0004-nvmem-rockchip-otp-Set-type-to-OTP.patch
new file mode 100644
index 0000000000..8491eb3c9c
--- /dev/null
+++ b/target/linux/generic/backport-6.6/822-v6.11-0004-nvmem-rockchip-otp-Set-type-to-OTP.patch
@@ -0,0 +1,25 @@
+From 39f95600d8c53355b212a117e91a6ba15e0cac47 Mon Sep 17 00:00:00 2001
+From: Heiko Stuebner <heiko.stuebner@cherry.de>
+Date: Fri, 5 Jul 2024 08:48:42 +0100
+Subject: [PATCH] nvmem: rockchip-otp: Set type to OTP
+
+The Rockchip OTP is obviously an OTP memory, so document this fact.
+
+Signed-off-by: Heiko Stuebner <heiko.stuebner@cherry.de>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240705074852.423202-6-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/rockchip-otp.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/nvmem/rockchip-otp.c
++++ b/drivers/nvmem/rockchip-otp.c
+@@ -256,6 +256,7 @@ static struct nvmem_config otp_config =
+ .name = "rockchip-otp",
+ .owner = THIS_MODULE,
+ .add_legacy_fixed_of_cells = true,
++ .type = NVMEM_TYPE_OTP,
+ .read_only = true,
+ .stride = 1,
+ .word_size = 1,
diff --git a/target/linux/generic/backport-6.6/822-v6.11-0005-nvmem-rockchip-efuse-set-type-to-OTP.patch b/target/linux/generic/backport-6.6/822-v6.11-0005-nvmem-rockchip-efuse-set-type-to-OTP.patch
new file mode 100644
index 0000000000..260b03eb03
--- /dev/null
+++ b/target/linux/generic/backport-6.6/822-v6.11-0005-nvmem-rockchip-efuse-set-type-to-OTP.patch
@@ -0,0 +1,26 @@
+From ba64a04474d2989f397982c48e405cfd785e2dd5 Mon Sep 17 00:00:00 2001
+From: Heiko Stuebner <heiko.stuebner@cherry.de>
+Date: Fri, 5 Jul 2024 08:48:43 +0100
+Subject: [PATCH] nvmem: rockchip-efuse: set type to OTP
+
+This device currently reports an "Unknown" type in sysfs.
+Since it is an eFuse hardware device, set its type to OTP.
+
+Signed-off-by: Heiko Stuebner <heiko.stuebner@cherry.de>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240705074852.423202-7-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/rockchip-efuse.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/nvmem/rockchip-efuse.c
++++ b/drivers/nvmem/rockchip-efuse.c
+@@ -206,6 +206,7 @@ static int rockchip_rk3399_efuse_read(vo
+ static struct nvmem_config econfig = {
+ .name = "rockchip-efuse",
+ .add_legacy_fixed_of_cells = true,
++ .type = NVMEM_TYPE_OTP,
+ .stride = 1,
+ .word_size = 1,
+ .read_only = true,
diff --git a/target/linux/generic/backport-6.6/822-v6.11-0006-nvmem-core-add-single-sysfs-group.patch b/target/linux/generic/backport-6.6/822-v6.11-0006-nvmem-core-add-single-sysfs-group.patch
new file mode 100644
index 0000000000..eae06b2404
--- /dev/null
+++ b/target/linux/generic/backport-6.6/822-v6.11-0006-nvmem-core-add-single-sysfs-group.patch
@@ -0,0 +1,42 @@
+From 6188f233161c6a5b2d1c396a221dfafc77dc9eec Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= <linux@weissschuh.net>
+Date: Fri, 5 Jul 2024 08:48:46 +0100
+Subject: [PATCH] nvmem: core: add single sysfs group
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The sysfs core provides a function to easily register a single group.
+Use it and remove the now unnecessary nvmem_cells_groups array.
+
+Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240705074852.423202-10-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/core.c | 7 +------
+ 1 file changed, 1 insertion(+), 6 deletions(-)
+
+--- a/drivers/nvmem/core.c
++++ b/drivers/nvmem/core.c
+@@ -367,11 +367,6 @@ static const struct attribute_group *nvm
+ NULL,
+ };
+
+-static const struct attribute_group *nvmem_cells_groups[] = {
+- &nvmem_cells_group,
+- NULL,
+-};
+-
+ static struct bin_attribute bin_attr_nvmem_eeprom_compat = {
+ .attr = {
+ .name = "eeprom",
+@@ -476,7 +471,7 @@ static int nvmem_populate_sysfs_cells(st
+
+ nvmem_cells_group.bin_attrs = cells_attrs;
+
+- ret = device_add_groups(&nvmem->dev, nvmem_cells_groups);
++ ret = device_add_group(&nvmem->dev, &nvmem_cells_group);
+ if (ret)
+ goto unlock_mutex;
+
diff --git a/target/linux/generic/backport-6.6/822-v6.11-0007-nvmem-core-remove-global-nvmem_cells_group.patch b/target/linux/generic/backport-6.6/822-v6.11-0007-nvmem-core-remove-global-nvmem_cells_group.patch
new file mode 100644
index 0000000000..9ec523c3b0
--- /dev/null
+++ b/target/linux/generic/backport-6.6/822-v6.11-0007-nvmem-core-remove-global-nvmem_cells_group.patch
@@ -0,0 +1,83 @@
+From 6839fed062b7898665983368c88269a6fb1fc10f Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= <linux@weissschuh.net>
+Date: Fri, 5 Jul 2024 08:48:47 +0100
+Subject: [PATCH] nvmem: core: remove global nvmem_cells_group
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+nvmem_cells_groups is a global variable that is also mutated.
+This is complicated and error-prone.
+
+Instead use a normal stack variable.
+
+Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240705074852.423202-11-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/core.c | 26 ++++++++++----------------
+ 1 file changed, 10 insertions(+), 16 deletions(-)
+
+--- a/drivers/nvmem/core.c
++++ b/drivers/nvmem/core.c
+@@ -357,11 +357,6 @@ static const struct attribute_group nvme
+ .is_bin_visible = nvmem_bin_attr_is_visible,
+ };
+
+-/* Cell attributes will be dynamically allocated */
+-static struct attribute_group nvmem_cells_group = {
+- .name = "cells",
+-};
+-
+ static const struct attribute_group *nvmem_dev_groups[] = {
+ &nvmem_bin_group,
+ NULL,
+@@ -423,23 +418,24 @@ static void nvmem_sysfs_remove_compat(st
+
+ static int nvmem_populate_sysfs_cells(struct nvmem_device *nvmem)
+ {
+- struct bin_attribute **cells_attrs, *attrs;
++ struct attribute_group group = {
++ .name = "cells",
++ };
+ struct nvmem_cell_entry *entry;
++ struct bin_attribute *attrs;
+ unsigned int ncells = 0, i = 0;
+ int ret = 0;
+
+ mutex_lock(&nvmem_mutex);
+
+- if (list_empty(&nvmem->cells) || nvmem->sysfs_cells_populated) {
+- nvmem_cells_group.bin_attrs = NULL;
++ if (list_empty(&nvmem->cells) || nvmem->sysfs_cells_populated)
+ goto unlock_mutex;
+- }
+
+ /* Allocate an array of attributes with a sentinel */
+ ncells = list_count_nodes(&nvmem->cells);
+- cells_attrs = devm_kcalloc(&nvmem->dev, ncells + 1,
+- sizeof(struct bin_attribute *), GFP_KERNEL);
+- if (!cells_attrs) {
++ group.bin_attrs = devm_kcalloc(&nvmem->dev, ncells + 1,
++ sizeof(struct bin_attribute *), GFP_KERNEL);
++ if (!group.bin_attrs) {
+ ret = -ENOMEM;
+ goto unlock_mutex;
+ }
+@@ -465,13 +461,11 @@ static int nvmem_populate_sysfs_cells(st
+ goto unlock_mutex;
+ }
+
+- cells_attrs[i] = &attrs[i];
++ group.bin_attrs[i] = &attrs[i];
+ i++;
+ }
+
+- nvmem_cells_group.bin_attrs = cells_attrs;
+-
+- ret = device_add_group(&nvmem->dev, &nvmem_cells_group);
++ ret = device_add_group(&nvmem->dev, &group);
+ if (ret)
+ goto unlock_mutex;
+
diff --git a/target/linux/generic/backport-6.6/822-v6.11-0008-nvmem-core-drop-unnecessary-range-checks-in-sysfs-ca.patch b/target/linux/generic/backport-6.6/822-v6.11-0008-nvmem-core-drop-unnecessary-range-checks-in-sysfs-ca.patch
new file mode 100644
index 0000000000..22408e5295
--- /dev/null
+++ b/target/linux/generic/backport-6.6/822-v6.11-0008-nvmem-core-drop-unnecessary-range-checks-in-sysfs-ca.patch
@@ -0,0 +1,61 @@
+From 588773802c386d38f9c4e91acd47369e89d95a30 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= <linux@weissschuh.net>
+Date: Fri, 5 Jul 2024 08:48:48 +0100
+Subject: [PATCH] nvmem: core: drop unnecessary range checks in sysfs callbacks
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The same checks have already been done in sysfs_kf_bin_write() and
+sysfs_kf_bin_read() just before the callbacks are invoked.
+
+Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240705074852.423202-12-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/core.c | 14 --------------
+ 1 file changed, 14 deletions(-)
+
+--- a/drivers/nvmem/core.c
++++ b/drivers/nvmem/core.c
+@@ -203,19 +203,12 @@ static ssize_t bin_attr_nvmem_read(struc
+ dev = kobj_to_dev(kobj);
+ nvmem = to_nvmem_device(dev);
+
+- /* Stop the user from reading */
+- if (pos >= nvmem->size)
+- return 0;
+-
+ if (!IS_ALIGNED(pos, nvmem->stride))
+ return -EINVAL;
+
+ if (count < nvmem->word_size)
+ return -EINVAL;
+
+- if (pos + count > nvmem->size)
+- count = nvmem->size - pos;
+-
+ count = round_down(count, nvmem->word_size);
+
+ if (!nvmem->reg_read)
+@@ -243,19 +236,12 @@ static ssize_t bin_attr_nvmem_write(stru
+ dev = kobj_to_dev(kobj);
+ nvmem = to_nvmem_device(dev);
+
+- /* Stop the user from writing */
+- if (pos >= nvmem->size)
+- return -EFBIG;
+-
+ if (!IS_ALIGNED(pos, nvmem->stride))
+ return -EINVAL;
+
+ if (count < nvmem->word_size)
+ return -EINVAL;
+
+- if (pos + count > nvmem->size)
+- count = nvmem->size - pos;
+-
+ count = round_down(count, nvmem->word_size);
+
+ if (!nvmem->reg_write)
diff --git a/target/linux/generic/backport-6.6/822-v6.11-0009-nvmem-Use-sysfs_emit-for-type-attribute.patch b/target/linux/generic/backport-6.6/822-v6.11-0009-nvmem-Use-sysfs_emit-for-type-attribute.patch
new file mode 100644
index 0000000000..3159efbbe7
--- /dev/null
+++ b/target/linux/generic/backport-6.6/822-v6.11-0009-nvmem-Use-sysfs_emit-for-type-attribute.patch
@@ -0,0 +1,30 @@
+From 08c367e45b6d322956878774f0b88bf5e52c6d54 Mon Sep 17 00:00:00 2001
+From: Marek Vasut <marex@denx.de>
+Date: Fri, 5 Jul 2024 08:48:51 +0100
+Subject: [PATCH] nvmem: Use sysfs_emit() for type attribute
+
+Use sysfs_emit() instead of sprintf() to follow best practice per
+Documentation/filesystems/sysfs.rst
+"
+show() should only use sysfs_emit()...
+"
+
+Signed-off-by: Marek Vasut <marex@denx.de>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240705074852.423202-15-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/nvmem/core.c
++++ b/drivers/nvmem/core.c
+@@ -179,7 +179,7 @@ static ssize_t type_show(struct device *
+ {
+ struct nvmem_device *nvmem = to_nvmem_device(dev);
+
+- return sprintf(buf, "%s\n", nvmem_type_str[nvmem->type]);
++ return sysfs_emit(buf, "%s\n", nvmem_type_str[nvmem->type]);
+ }
+
+ static DEVICE_ATTR_RO(type);
diff --git a/target/linux/generic/backport-6.6/822-v6.11-0010-nvmem-core-Implement-force_ro-sysfs-attribute.patch b/target/linux/generic/backport-6.6/822-v6.11-0010-nvmem-core-Implement-force_ro-sysfs-attribute.patch
new file mode 100644
index 0000000000..28fb544a04
--- /dev/null
+++ b/target/linux/generic/backport-6.6/822-v6.11-0010-nvmem-core-Implement-force_ro-sysfs-attribute.patch
@@ -0,0 +1,122 @@
+From 9d7eb234ac7a56b88aea8a52ed81553a730fe25c Mon Sep 17 00:00:00 2001
+From: Marek Vasut <marex@denx.de>
+Date: Fri, 5 Jul 2024 08:48:52 +0100
+Subject: [PATCH] nvmem: core: Implement force_ro sysfs attribute
+
+Implement "force_ro" sysfs attribute to allow users to set read-write
+devices as read-only and back to read-write from userspace. The choice
+of the name is based on MMC core 'force_ro' attribute.
+
+This solves a situation where an AT24 I2C EEPROM with GPIO based nWP
+signal may have to be occasionally updated. Such I2C EEPROM device is
+usually set as read-only during most of the regular system operation,
+but in case it has to be updated in a controlled manner, it could be
+unlocked using this new "force_ro" sysfs attribute and then re-locked
+again.
+
+The "read-only" DT property and config->read_only configuration is
+respected and is used to set default state of the device, read-only
+or read-write, for devices which do implement .reg_write function.
+For devices which do not implement .reg_write function, the device
+is unconditionally read-only and the "force_ro" attribute is not
+visible.
+
+Signed-off-by: Marek Vasut <marex@denx.de>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240705074852.423202-16-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ Documentation/ABI/stable/sysfs-bus-nvmem | 17 ++++++++++
+ drivers/nvmem/core.c | 43 ++++++++++++++++++++++++
+ 2 files changed, 60 insertions(+)
+
+--- a/Documentation/ABI/stable/sysfs-bus-nvmem
++++ b/Documentation/ABI/stable/sysfs-bus-nvmem
+@@ -1,3 +1,20 @@
++What: /sys/bus/nvmem/devices/.../force_ro
++Date: June 2024
++KernelVersion: 6.11
++Contact: Marek Vasut <marex@denx.de>
++Description:
++ This read/write attribute allows users to set read-write
++ devices as read-only and back to read-write from userspace.
++ This can be used to unlock and relock write-protection of
++ devices which are generally locked, except during sporadic
++ programming operation.
++ Read returns '0' or '1' for read-write or read-only modes
++ respectively.
++ Write parses one of 'YyTt1NnFf0', or [oO][NnFf] for "on"
++ and "off", i.e. what kstrbool() supports.
++ Note: This file is only present if CONFIG_NVMEM_SYSFS
++ is enabled.
++
+ What: /sys/bus/nvmem/devices/.../nvmem
+ Date: July 2015
+ KernelVersion: 4.2
+--- a/drivers/nvmem/core.c
++++ b/drivers/nvmem/core.c
+@@ -184,7 +184,30 @@ static ssize_t type_show(struct device *
+
+ static DEVICE_ATTR_RO(type);
+
++static ssize_t force_ro_show(struct device *dev, struct device_attribute *attr,
++ char *buf)
++{
++ struct nvmem_device *nvmem = to_nvmem_device(dev);
++
++ return sysfs_emit(buf, "%d\n", nvmem->read_only);
++}
++
++static ssize_t force_ro_store(struct device *dev, struct device_attribute *attr,
++ const char *buf, size_t count)
++{
++ struct nvmem_device *nvmem = to_nvmem_device(dev);
++ int ret = kstrtobool(buf, &nvmem->read_only);
++
++ if (ret < 0)
++ return ret;
++
++ return count;
++}
++
++static DEVICE_ATTR_RW(force_ro);
++
+ static struct attribute *nvmem_attrs[] = {
++ &dev_attr_force_ro.attr,
+ &dev_attr_type.attr,
+ NULL,
+ };
+@@ -285,6 +308,25 @@ static umode_t nvmem_bin_attr_is_visible
+ return nvmem_bin_attr_get_umode(nvmem);
+ }
+
++static umode_t nvmem_attr_is_visible(struct kobject *kobj,
++ struct attribute *attr, int i)
++{
++ struct device *dev = kobj_to_dev(kobj);
++ struct nvmem_device *nvmem = to_nvmem_device(dev);
++
++ /*
++ * If the device has no .reg_write operation, do not allow
++ * configuration as read-write.
++ * If the device is set as read-only by configuration, it
++ * can be forced into read-write mode using the 'force_ro'
++ * attribute.
++ */
++ if (attr == &dev_attr_force_ro.attr && !nvmem->reg_write)
++ return 0; /* Attribute not visible */
++
++ return attr->mode;
++}
++
+ static struct nvmem_cell *nvmem_create_cell(struct nvmem_cell_entry *entry,
+ const char *id, int index);
+
+@@ -341,6 +383,7 @@ static const struct attribute_group nvme
+ .bin_attrs = nvmem_bin_attributes,
+ .attrs = nvmem_attrs,
+ .is_bin_visible = nvmem_bin_attr_is_visible,
++ .is_visible = nvmem_attr_is_visible,
+ };
+
+ static const struct attribute_group *nvmem_dev_groups[] = {
diff --git a/target/linux/generic/backport-6.6/822-v6.11-0011-nvmem-u-boot-env-error-if-NVMEM-device-is-too-small.patch b/target/linux/generic/backport-6.6/822-v6.11-0011-nvmem-u-boot-env-error-if-NVMEM-device-is-too-small.patch
new file mode 100644
index 0000000000..70d420f205
--- /dev/null
+++ b/target/linux/generic/backport-6.6/822-v6.11-0011-nvmem-u-boot-env-error-if-NVMEM-device-is-too-small.patch
@@ -0,0 +1,40 @@
+From 8679e8b4a1ebdb40c4429e49368d29353e07b601 Mon Sep 17 00:00:00 2001
+From: John Thomson <git@johnthomson.fastmail.com.au>
+Date: Mon, 2 Sep 2024 15:25:08 +0100
+Subject: [PATCH] nvmem: u-boot-env: error if NVMEM device is too small
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Verify data size before trying to parse it to avoid reading out of
+buffer. This could happen in case of problems at MTD level or invalid DT
+bindings.
+
+Signed-off-by: John Thomson <git@johnthomson.fastmail.com.au>
+Cc: stable <stable@kernel.org>
+Fixes: d5542923f200 ("nvmem: add driver handling U-Boot environment variables")
+[rmilecki: simplify commit description & rebase]
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240902142510.71096-2-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/u-boot-env.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/drivers/nvmem/u-boot-env.c
++++ b/drivers/nvmem/u-boot-env.c
+@@ -176,6 +176,13 @@ static int u_boot_env_parse(struct u_boo
+ data_offset = offsetof(struct u_boot_env_image_broadcom, data);
+ break;
+ }
++
++ if (dev_size < data_offset) {
++ dev_err(dev, "Device too small for u-boot-env\n");
++ err = -EIO;
++ goto err_kfree;
++ }
++
+ crc32_addr = (__le32 *)(buf + crc32_offset);
+ crc32 = le32_to_cpu(*crc32_addr);
+ crc32_data_len = dev_size - crc32_data_offset;
diff --git a/target/linux/generic/backport-6.6/822-v6.11-0012-nvmem-Fix-return-type-of-devm_nvmem_device_get-in-ke.patch b/target/linux/generic/backport-6.6/822-v6.11-0012-nvmem-Fix-return-type-of-devm_nvmem_device_get-in-ke.patch
new file mode 100644
index 0000000000..6d49a253a4
--- /dev/null
+++ b/target/linux/generic/backport-6.6/822-v6.11-0012-nvmem-Fix-return-type-of-devm_nvmem_device_get-in-ke.patch
@@ -0,0 +1,37 @@
+From c69f37f6559a8948d70badd2b179db7714dedd62 Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert+renesas@glider.be>
+Date: Mon, 2 Sep 2024 15:25:09 +0100
+Subject: [PATCH] nvmem: Fix return type of devm_nvmem_device_get() in
+ kerneldoc
+
+devm_nvmem_device_get() returns an nvmem device, not an nvmem cell.
+
+Fixes: e2a5402ec7c6d044 ("nvmem: Add nvmem_device based consumer apis.")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240902142510.71096-3-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/core.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/nvmem/core.c
++++ b/drivers/nvmem/core.c
+@@ -1275,13 +1275,13 @@ void nvmem_device_put(struct nvmem_devic
+ EXPORT_SYMBOL_GPL(nvmem_device_put);
+
+ /**
+- * devm_nvmem_device_get() - Get nvmem cell of device form a given id
++ * devm_nvmem_device_get() - Get nvmem device of device form a given id
+ *
+ * @dev: Device that requests the nvmem device.
+ * @id: name id for the requested nvmem device.
+ *
+- * Return: ERR_PTR() on error or a valid pointer to a struct nvmem_cell
+- * on success. The nvmem_cell will be freed by the automatically once the
++ * Return: ERR_PTR() on error or a valid pointer to a struct nvmem_device
++ * on success. The nvmem_device will be freed by the automatically once the
+ * device is freed.
+ */
+ struct nvmem_device *devm_nvmem_device_get(struct device *dev, const char *id)
diff --git a/target/linux/generic/backport-6.6/823-v6.12-0001-nvmem-imx-ocotp-ele-support-i.MX95.patch b/target/linux/generic/backport-6.6/823-v6.12-0001-nvmem-imx-ocotp-ele-support-i.MX95.patch
new file mode 100644
index 0000000000..c19931b3fa
--- /dev/null
+++ b/target/linux/generic/backport-6.6/823-v6.12-0001-nvmem-imx-ocotp-ele-support-i.MX95.patch
@@ -0,0 +1,73 @@
+From c3f9b7b4e5f9de319d00784577cda42036ff243a Mon Sep 17 00:00:00 2001
+From: Peng Fan <peng.fan@nxp.com>
+Date: Mon, 2 Sep 2024 15:29:45 +0100
+Subject: [PATCH] nvmem: imx-ocotp-ele: support i.MX95
+
+i.MX95 OCOTP has same accessing method, so add an entry for i.MX95, but
+some fuse has ECC feature, so only read out the lower 16bits for ECC fuses.
+
+Signed-off-by: Peng Fan <peng.fan@nxp.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240902142952.71639-3-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/imx-ocotp-ele.c | 32 +++++++++++++++++++++++++++++---
+ 1 file changed, 29 insertions(+), 3 deletions(-)
+
+--- a/drivers/nvmem/imx-ocotp-ele.c
++++ b/drivers/nvmem/imx-ocotp-ele.c
+@@ -14,8 +14,9 @@
+ #include <linux/slab.h>
+
+ enum fuse_type {
+- FUSE_FSB = 1,
+- FUSE_ELE = 2,
++ FUSE_FSB = BIT(0),
++ FUSE_ELE = BIT(1),
++ FUSE_ECC = BIT(2),
+ FUSE_INVALID = -1
+ };
+
+@@ -93,7 +94,10 @@ static int imx_ocotp_reg_read(void *cont
+ continue;
+ }
+
+- *buf++ = readl_relaxed(reg + (i << 2));
++ if (type & FUSE_ECC)
++ *buf++ = readl_relaxed(reg + (i << 2)) & GENMASK(15, 0);
++ else
++ *buf++ = readl_relaxed(reg + (i << 2));
+ }
+
+ memcpy(val, (u8 *)p, bytes);
+@@ -155,8 +159,30 @@ static const struct ocotp_devtype_data i
+ },
+ };
+
++static const struct ocotp_devtype_data imx95_ocotp_data = {
++ .reg_off = 0x8000,
++ .reg_read = imx_ocotp_reg_read,
++ .size = 2048,
++ .num_entry = 12,
++ .entry = {
++ { 0, 1, FUSE_FSB | FUSE_ECC },
++ { 7, 1, FUSE_FSB | FUSE_ECC },
++ { 9, 3, FUSE_FSB | FUSE_ECC },
++ { 12, 24, FUSE_FSB },
++ { 36, 2, FUSE_FSB | FUSE_ECC },
++ { 38, 14, FUSE_FSB },
++ { 63, 1, FUSE_ELE },
++ { 128, 16, FUSE_ELE },
++ { 188, 1, FUSE_ELE },
++ { 317, 2, FUSE_FSB | FUSE_ECC },
++ { 320, 7, FUSE_FSB },
++ { 328, 184, FUSE_FSB }
++ },
++};
++
+ static const struct of_device_id imx_ele_ocotp_dt_ids[] = {
+ { .compatible = "fsl,imx93-ocotp", .data = &imx93_ocotp_data, },
++ { .compatible = "fsl,imx95-ocotp", .data = &imx95_ocotp_data, },
+ {},
+ };
+ MODULE_DEVICE_TABLE(of, imx_ele_ocotp_dt_ids);
diff --git a/target/linux/generic/backport-6.6/823-v6.12-0002-nvmem-sunplus-ocotp-Use-devm_platform_ioremap_resour.patch b/target/linux/generic/backport-6.6/823-v6.12-0002-nvmem-sunplus-ocotp-Use-devm_platform_ioremap_resour.patch
new file mode 100644
index 0000000000..13ef50b157
--- /dev/null
+++ b/target/linux/generic/backport-6.6/823-v6.12-0002-nvmem-sunplus-ocotp-Use-devm_platform_ioremap_resour.patch
@@ -0,0 +1,44 @@
+From 98ee46391baf35987227236d0c3bb30ab6e758c8 Mon Sep 17 00:00:00 2001
+From: Zhang Zekun <zhangzekun11@huawei.com>
+Date: Mon, 2 Sep 2024 15:29:50 +0100
+Subject: [PATCH] nvmem: sunplus-ocotp: Use
+ devm_platform_ioremap_resource_byname() helper function
+
+platform_get_resource_byname() and devm_ioremap_resource() can be
+replaced by devm_platform_ioremap_resource_byname(), which can
+simplify the code logic a bit, No functional change here.
+
+Signed-off-by: Zhang Zekun <zhangzekun11@huawei.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240902142952.71639-8-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/sunplus-ocotp.c | 7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+--- a/drivers/nvmem/sunplus-ocotp.c
++++ b/drivers/nvmem/sunplus-ocotp.c
+@@ -159,7 +159,6 @@ static int sp_ocotp_probe(struct platfor
+ struct device *dev = &pdev->dev;
+ struct nvmem_device *nvmem;
+ struct sp_ocotp_priv *otp;
+- struct resource *res;
+ int ret;
+
+ otp = devm_kzalloc(dev, sizeof(*otp), GFP_KERNEL);
+@@ -168,13 +167,11 @@ static int sp_ocotp_probe(struct platfor
+
+ otp->dev = dev;
+
+- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hb_gpio");
+- otp->base[HB_GPIO] = devm_ioremap_resource(dev, res);
++ otp->base[HB_GPIO] = devm_platform_ioremap_resource_byname(pdev, "hb_gpio");
+ if (IS_ERR(otp->base[HB_GPIO]))
+ return PTR_ERR(otp->base[HB_GPIO]);
+
+- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "otprx");
+- otp->base[OTPRX] = devm_ioremap_resource(dev, res);
++ otp->base[OTPRX] = devm_platform_ioremap_resource_byname(pdev, "otprx");
+ if (IS_ERR(otp->base[OTPRX]))
+ return PTR_ERR(otp->base[OTPRX]);
+
diff --git a/target/linux/generic/backport-6.6/823-v6.12-0003-nvmem-layouts-add-U-Boot-env-layout.patch b/target/linux/generic/backport-6.6/823-v6.12-0003-nvmem-layouts-add-U-Boot-env-layout.patch
new file mode 100644
index 0000000000..15a0f77bb3
--- /dev/null
+++ b/target/linux/generic/backport-6.6/823-v6.12-0003-nvmem-layouts-add-U-Boot-env-layout.patch
@@ -0,0 +1,525 @@
+From 5f15811286aff4664bf275a7ede64e1b8858151b Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
+Date: Mon, 2 Sep 2024 15:29:47 +0100
+Subject: [PATCH] nvmem: layouts: add U-Boot env layout
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+U-Boot environment variables are stored in a specific format. Actual
+data can be placed in various storage sources (MTD, UBI volume, EEPROM,
+NVRAM, etc.).
+
+Move all generic (NVMEM device independent) code from NVMEM device
+driver to an NVMEM layout driver. Then add a simple NVMEM layout code on
+top of it.
+
+This allows using NVMEM layout for parsing U-Boot env data stored in any
+kind of NVMEM device.
+
+The old NVMEM glue driver stays in place for handling bindings in the
+MTD context. To avoid code duplication it uses exported layout parsing
+function. Please note that handling MTD & NVMEM layout bindings may be
+refactored in the future.
+
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20240902142952.71639-5-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ MAINTAINERS | 1 +
+ drivers/nvmem/Kconfig | 3 +-
+ drivers/nvmem/layouts/Kconfig | 11 ++
+ drivers/nvmem/layouts/Makefile | 1 +
+ drivers/nvmem/layouts/u-boot-env.c | 211 +++++++++++++++++++++++++++++
+ drivers/nvmem/layouts/u-boot-env.h | 15 ++
+ drivers/nvmem/u-boot-env.c | 165 +---------------------
+ 7 files changed, 242 insertions(+), 165 deletions(-)
+ create mode 100644 drivers/nvmem/layouts/u-boot-env.c
+ create mode 100644 drivers/nvmem/layouts/u-boot-env.h
+
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -21988,6 +21988,7 @@ U-BOOT ENVIRONMENT VARIABLES
+ M: Rafał Miłecki <rafal@milecki.pl>
+ S: Maintained
+ F: Documentation/devicetree/bindings/nvmem/u-boot,env.yaml
++F: drivers/nvmem/layouts/u-boot-env.c
+ F: drivers/nvmem/u-boot-env.c
+
+ UACCE ACCELERATOR FRAMEWORK
+--- a/drivers/nvmem/Kconfig
++++ b/drivers/nvmem/Kconfig
+@@ -363,8 +363,7 @@ config NVMEM_SUNXI_SID
+ config NVMEM_U_BOOT_ENV
+ tristate "U-Boot environment variables support"
+ depends on OF && MTD
+- select CRC32
+- select GENERIC_NET_UTILS
++ select NVMEM_LAYOUT_U_BOOT_ENV
+ help
+ U-Boot stores its setup as environment variables. This driver adds
+ support for verifying & exporting such data. It also exposes variables
+--- a/drivers/nvmem/layouts/Kconfig
++++ b/drivers/nvmem/layouts/Kconfig
+@@ -26,6 +26,17 @@ config NVMEM_LAYOUT_ONIE_TLV
+
+ If unsure, say N.
+
++config NVMEM_LAYOUT_U_BOOT_ENV
++ tristate "U-Boot environment variables layout"
++ select CRC32
++ select GENERIC_NET_UTILS
++ help
++ U-Boot stores its setup as environment variables. This driver adds
++ support for verifying & exporting such data. It also exposes variables
++ as NVMEM cells so they can be referenced by other drivers.
++
++ If unsure, say N.
++
+ endmenu
+
+ endif
+--- a/drivers/nvmem/layouts/Makefile
++++ b/drivers/nvmem/layouts/Makefile
+@@ -5,3 +5,4 @@
+
+ obj-$(CONFIG_NVMEM_LAYOUT_SL28_VPD) += sl28vpd.o
+ obj-$(CONFIG_NVMEM_LAYOUT_ONIE_TLV) += onie-tlv.o
++obj-$(CONFIG_NVMEM_LAYOUT_U_BOOT_ENV) += u-boot-env.o
+--- /dev/null
++++ b/drivers/nvmem/layouts/u-boot-env.c
+@@ -0,0 +1,211 @@
++// SPDX-License-Identifier: GPL-2.0-only
++/*
++ * Copyright (C) 2022 - 2023 Rafał Miłecki <rafal@milecki.pl>
++ */
++
++#include <linux/crc32.h>
++#include <linux/etherdevice.h>
++#include <linux/export.h>
++#include <linux/if_ether.h>
++#include <linux/nvmem-consumer.h>
++#include <linux/nvmem-provider.h>
++#include <linux/of.h>
++#include <linux/slab.h>
++
++#include "u-boot-env.h"
++
++struct u_boot_env_image_single {
++ __le32 crc32;
++ uint8_t data[];
++} __packed;
++
++struct u_boot_env_image_redundant {
++ __le32 crc32;
++ u8 mark;
++ uint8_t data[];
++} __packed;
++
++struct u_boot_env_image_broadcom {
++ __le32 magic;
++ __le32 len;
++ __le32 crc32;
++ DECLARE_FLEX_ARRAY(uint8_t, data);
++} __packed;
++
++static int u_boot_env_read_post_process_ethaddr(void *context, const char *id, int index,
++ unsigned int offset, void *buf, size_t bytes)
++{
++ u8 mac[ETH_ALEN];
++
++ if (bytes != 3 * ETH_ALEN - 1)
++ return -EINVAL;
++
++ if (!mac_pton(buf, mac))
++ return -EINVAL;
++
++ if (index)
++ eth_addr_add(mac, index);
++
++ ether_addr_copy(buf, mac);
++
++ return 0;
++}
++
++static int u_boot_env_parse_cells(struct device *dev, struct nvmem_device *nvmem, uint8_t *buf,
++ size_t data_offset, size_t data_len)
++{
++ char *data = buf + data_offset;
++ char *var, *value, *eq;
++
++ for (var = data;
++ var < data + data_len && *var;
++ var = value + strlen(value) + 1) {
++ struct nvmem_cell_info info = {};
++
++ eq = strchr(var, '=');
++ if (!eq)
++ break;
++ *eq = '\0';
++ value = eq + 1;
++
++ info.name = devm_kstrdup(dev, var, GFP_KERNEL);
++ if (!info.name)
++ return -ENOMEM;
++ info.offset = data_offset + value - data;
++ info.bytes = strlen(value);
++ info.np = of_get_child_by_name(dev->of_node, info.name);
++ if (!strcmp(var, "ethaddr")) {
++ info.raw_len = strlen(value);
++ info.bytes = ETH_ALEN;
++ info.read_post_process = u_boot_env_read_post_process_ethaddr;
++ }
++
++ nvmem_add_one_cell(nvmem, &info);
++ }
++
++ return 0;
++}
++
++int u_boot_env_parse(struct device *dev, struct nvmem_device *nvmem,
++ enum u_boot_env_format format)
++{
++ size_t crc32_data_offset;
++ size_t crc32_data_len;
++ size_t crc32_offset;
++ __le32 *crc32_addr;
++ size_t data_offset;
++ size_t data_len;
++ size_t dev_size;
++ uint32_t crc32;
++ uint32_t calc;
++ uint8_t *buf;
++ int bytes;
++ int err;
++
++ dev_size = nvmem_dev_size(nvmem);
++
++ buf = kzalloc(dev_size, GFP_KERNEL);
++ if (!buf) {
++ err = -ENOMEM;
++ goto err_out;
++ }
++
++ bytes = nvmem_device_read(nvmem, 0, dev_size, buf);
++ if (bytes < 0) {
++ err = bytes;
++ goto err_kfree;
++ } else if (bytes != dev_size) {
++ err = -EIO;
++ goto err_kfree;
++ }
++
++ switch (format) {
++ case U_BOOT_FORMAT_SINGLE:
++ crc32_offset = offsetof(struct u_boot_env_image_single, crc32);
++ crc32_data_offset = offsetof(struct u_boot_env_image_single, data);
++ data_offset = offsetof(struct u_boot_env_image_single, data);
++ break;
++ case U_BOOT_FORMAT_REDUNDANT:
++ crc32_offset = offsetof(struct u_boot_env_image_redundant, crc32);
++ crc32_data_offset = offsetof(struct u_boot_env_image_redundant, data);
++ data_offset = offsetof(struct u_boot_env_image_redundant, data);
++ break;
++ case U_BOOT_FORMAT_BROADCOM:
++ crc32_offset = offsetof(struct u_boot_env_image_broadcom, crc32);
++ crc32_data_offset = offsetof(struct u_boot_env_image_broadcom, data);
++ data_offset = offsetof(struct u_boot_env_image_broadcom, data);
++ break;
++ }
++
++ if (dev_size < data_offset) {
++ dev_err(dev, "Device too small for u-boot-env\n");
++ err = -EIO;
++ goto err_kfree;
++ }
++
++ crc32_addr = (__le32 *)(buf + crc32_offset);
++ crc32 = le32_to_cpu(*crc32_addr);
++ crc32_data_len = dev_size - crc32_data_offset;
++ data_len = dev_size - data_offset;
++
++ calc = crc32(~0, buf + crc32_data_offset, crc32_data_len) ^ ~0L;
++ if (calc != crc32) {
++ dev_err(dev, "Invalid calculated CRC32: 0x%08x (expected: 0x%08x)\n", calc, crc32);
++ err = -EINVAL;
++ goto err_kfree;
++ }
++
++ buf[dev_size - 1] = '\0';
++ err = u_boot_env_parse_cells(dev, nvmem, buf, data_offset, data_len);
++
++err_kfree:
++ kfree(buf);
++err_out:
++ return err;
++}
++EXPORT_SYMBOL_GPL(u_boot_env_parse);
++
++static int u_boot_env_add_cells(struct nvmem_layout *layout)
++{
++ struct device *dev = &layout->dev;
++ enum u_boot_env_format format;
++
++ format = (uintptr_t)device_get_match_data(dev);
++
++ return u_boot_env_parse(dev, layout->nvmem, format);
++}
++
++static int u_boot_env_probe(struct nvmem_layout *layout)
++{
++ layout->add_cells = u_boot_env_add_cells;
++
++ return nvmem_layout_register(layout);
++}
++
++static void u_boot_env_remove(struct nvmem_layout *layout)
++{
++ nvmem_layout_unregister(layout);
++}
++
++static const struct of_device_id u_boot_env_of_match_table[] = {
++ { .compatible = "u-boot,env", .data = (void *)U_BOOT_FORMAT_SINGLE, },
++ { .compatible = "u-boot,env-redundant-bool", .data = (void *)U_BOOT_FORMAT_REDUNDANT, },
++ { .compatible = "u-boot,env-redundant-count", .data = (void *)U_BOOT_FORMAT_REDUNDANT, },
++ { .compatible = "brcm,env", .data = (void *)U_BOOT_FORMAT_BROADCOM, },
++ {},
++};
++
++static struct nvmem_layout_driver u_boot_env_layout = {
++ .driver = {
++ .name = "u-boot-env-layout",
++ .of_match_table = u_boot_env_of_match_table,
++ },
++ .probe = u_boot_env_probe,
++ .remove = u_boot_env_remove,
++};
++module_nvmem_layout_driver(u_boot_env_layout);
++
++MODULE_AUTHOR("Rafał Miłecki");
++MODULE_LICENSE("GPL");
++MODULE_DEVICE_TABLE(of, u_boot_env_of_match_table);
++MODULE_DESCRIPTION("NVMEM layout driver for U-Boot environment variables");
+--- /dev/null
++++ b/drivers/nvmem/layouts/u-boot-env.h
+@@ -0,0 +1,15 @@
++/* SPDX-License-Identifier: GPL-2.0-only */
++
++#ifndef _LINUX_NVMEM_LAYOUTS_U_BOOT_ENV_H
++#define _LINUX_NVMEM_LAYOUTS_U_BOOT_ENV_H
++
++enum u_boot_env_format {
++ U_BOOT_FORMAT_SINGLE,
++ U_BOOT_FORMAT_REDUNDANT,
++ U_BOOT_FORMAT_BROADCOM,
++};
++
++int u_boot_env_parse(struct device *dev, struct nvmem_device *nvmem,
++ enum u_boot_env_format format);
++
++#endif /* ifndef _LINUX_NVMEM_LAYOUTS_U_BOOT_ENV_H */
+--- a/drivers/nvmem/u-boot-env.c
++++ b/drivers/nvmem/u-boot-env.c
+@@ -3,23 +3,15 @@
+ * Copyright (C) 2022 Rafał Miłecki <rafal@milecki.pl>
+ */
+
+-#include <linux/crc32.h>
+-#include <linux/etherdevice.h>
+-#include <linux/if_ether.h>
+ #include <linux/mod_devicetable.h>
+ #include <linux/module.h>
+ #include <linux/mtd/mtd.h>
+-#include <linux/nvmem-consumer.h>
+ #include <linux/nvmem-provider.h>
+ #include <linux/of.h>
+ #include <linux/platform_device.h>
+ #include <linux/slab.h>
+
+-enum u_boot_env_format {
+- U_BOOT_FORMAT_SINGLE,
+- U_BOOT_FORMAT_REDUNDANT,
+- U_BOOT_FORMAT_BROADCOM,
+-};
++#include "layouts/u-boot-env.h"
+
+ struct u_boot_env {
+ struct device *dev;
+@@ -29,24 +21,6 @@ struct u_boot_env {
+ struct mtd_info *mtd;
+ };
+
+-struct u_boot_env_image_single {
+- __le32 crc32;
+- uint8_t data[];
+-} __packed;
+-
+-struct u_boot_env_image_redundant {
+- __le32 crc32;
+- u8 mark;
+- uint8_t data[];
+-} __packed;
+-
+-struct u_boot_env_image_broadcom {
+- __le32 magic;
+- __le32 len;
+- __le32 crc32;
+- DECLARE_FLEX_ARRAY(uint8_t, data);
+-} __packed;
+-
+ static int u_boot_env_read(void *context, unsigned int offset, void *val,
+ size_t bytes)
+ {
+@@ -69,141 +43,6 @@ static int u_boot_env_read(void *context
+ return 0;
+ }
+
+-static int u_boot_env_read_post_process_ethaddr(void *context, const char *id, int index,
+- unsigned int offset, void *buf, size_t bytes)
+-{
+- u8 mac[ETH_ALEN];
+-
+- if (bytes != 3 * ETH_ALEN - 1)
+- return -EINVAL;
+-
+- if (!mac_pton(buf, mac))
+- return -EINVAL;
+-
+- if (index)
+- eth_addr_add(mac, index);
+-
+- ether_addr_copy(buf, mac);
+-
+- return 0;
+-}
+-
+-static int u_boot_env_add_cells(struct u_boot_env *priv, uint8_t *buf,
+- size_t data_offset, size_t data_len)
+-{
+- struct nvmem_device *nvmem = priv->nvmem;
+- struct device *dev = priv->dev;
+- char *data = buf + data_offset;
+- char *var, *value, *eq;
+-
+- for (var = data;
+- var < data + data_len && *var;
+- var = value + strlen(value) + 1) {
+- struct nvmem_cell_info info = {};
+-
+- eq = strchr(var, '=');
+- if (!eq)
+- break;
+- *eq = '\0';
+- value = eq + 1;
+-
+- info.name = devm_kstrdup(dev, var, GFP_KERNEL);
+- if (!info.name)
+- return -ENOMEM;
+- info.offset = data_offset + value - data;
+- info.bytes = strlen(value);
+- info.np = of_get_child_by_name(dev->of_node, info.name);
+- if (!strcmp(var, "ethaddr")) {
+- info.raw_len = strlen(value);
+- info.bytes = ETH_ALEN;
+- info.read_post_process = u_boot_env_read_post_process_ethaddr;
+- }
+-
+- nvmem_add_one_cell(nvmem, &info);
+- }
+-
+- return 0;
+-}
+-
+-static int u_boot_env_parse(struct u_boot_env *priv)
+-{
+- struct nvmem_device *nvmem = priv->nvmem;
+- struct device *dev = priv->dev;
+- size_t crc32_data_offset;
+- size_t crc32_data_len;
+- size_t crc32_offset;
+- __le32 *crc32_addr;
+- size_t data_offset;
+- size_t data_len;
+- size_t dev_size;
+- uint32_t crc32;
+- uint32_t calc;
+- uint8_t *buf;
+- int bytes;
+- int err;
+-
+- dev_size = nvmem_dev_size(nvmem);
+-
+- buf = kzalloc(dev_size, GFP_KERNEL);
+- if (!buf) {
+- err = -ENOMEM;
+- goto err_out;
+- }
+-
+- bytes = nvmem_device_read(nvmem, 0, dev_size, buf);
+- if (bytes < 0) {
+- err = bytes;
+- goto err_kfree;
+- } else if (bytes != dev_size) {
+- err = -EIO;
+- goto err_kfree;
+- }
+-
+- switch (priv->format) {
+- case U_BOOT_FORMAT_SINGLE:
+- crc32_offset = offsetof(struct u_boot_env_image_single, crc32);
+- crc32_data_offset = offsetof(struct u_boot_env_image_single, data);
+- data_offset = offsetof(struct u_boot_env_image_single, data);
+- break;
+- case U_BOOT_FORMAT_REDUNDANT:
+- crc32_offset = offsetof(struct u_boot_env_image_redundant, crc32);
+- crc32_data_offset = offsetof(struct u_boot_env_image_redundant, data);
+- data_offset = offsetof(struct u_boot_env_image_redundant, data);
+- break;
+- case U_BOOT_FORMAT_BROADCOM:
+- crc32_offset = offsetof(struct u_boot_env_image_broadcom, crc32);
+- crc32_data_offset = offsetof(struct u_boot_env_image_broadcom, data);
+- data_offset = offsetof(struct u_boot_env_image_broadcom, data);
+- break;
+- }
+-
+- if (dev_size < data_offset) {
+- dev_err(dev, "Device too small for u-boot-env\n");
+- err = -EIO;
+- goto err_kfree;
+- }
+-
+- crc32_addr = (__le32 *)(buf + crc32_offset);
+- crc32 = le32_to_cpu(*crc32_addr);
+- crc32_data_len = dev_size - crc32_data_offset;
+- data_len = dev_size - data_offset;
+-
+- calc = crc32(~0, buf + crc32_data_offset, crc32_data_len) ^ ~0L;
+- if (calc != crc32) {
+- dev_err(dev, "Invalid calculated CRC32: 0x%08x (expected: 0x%08x)\n", calc, crc32);
+- err = -EINVAL;
+- goto err_kfree;
+- }
+-
+- buf[dev_size - 1] = '\0';
+- err = u_boot_env_add_cells(priv, buf, data_offset, data_len);
+-
+-err_kfree:
+- kfree(buf);
+-err_out:
+- return err;
+-}
+-
+ static int u_boot_env_probe(struct platform_device *pdev)
+ {
+ struct nvmem_config config = {
+@@ -235,7 +74,7 @@ static int u_boot_env_probe(struct platf
+ if (IS_ERR(priv->nvmem))
+ return PTR_ERR(priv->nvmem);
+
+- return u_boot_env_parse(priv);
++ return u_boot_env_parse(dev, priv->nvmem, priv->format);
+ }
+
+ static const struct of_device_id u_boot_env_of_match_table[] = {
diff --git a/target/linux/generic/backport-6.6/834-v6.8-leds-trigger-netdev-Extend-speeds-up-to-10G.patch b/target/linux/generic/backport-6.6/834-v6.8-leds-trigger-netdev-Extend-speeds-up-to-10G.patch
index 2ae209f9e1..4571d7d2bf 100644
--- a/target/linux/generic/backport-6.6/834-v6.8-leds-trigger-netdev-Extend-speeds-up-to-10G.patch
+++ b/target/linux/generic/backport-6.6/834-v6.8-leds-trigger-netdev-Extend-speeds-up-to-10G.patch
@@ -99,7 +99,7 @@ Signed-off-by: Lee Jones <lee@kernel.org>
interval = jiffies_to_msecs(
--- a/include/linux/leds.h
+++ b/include/linux/leds.h
-@@ -588,6 +588,9 @@ enum led_trigger_netdev_modes {
+@@ -586,6 +586,9 @@ enum led_trigger_netdev_modes {
TRIGGER_NETDEV_LINK_10,
TRIGGER_NETDEV_LINK_100,
TRIGGER_NETDEV_LINK_1000,
diff --git a/target/linux/generic/backport-6.6/894-v6.8-net-ethtool-implement-ethtool_puts.patch b/target/linux/generic/backport-6.6/894-v6.8-net-ethtool-implement-ethtool_puts.patch
index 9c61ff27ab..8e57193ef1 100644
--- a/target/linux/generic/backport-6.6/894-v6.8-net-ethtool-implement-ethtool_puts.patch
+++ b/target/linux/generic/backport-6.6/894-v6.8-net-ethtool-implement-ethtool_puts.patch
@@ -123,7 +123,7 @@ Signed-off-by: Justin Stitt <justinstitt@google.com>
#endif /* _LINUX_ETHTOOL_H */
--- a/net/ethtool/ioctl.c
+++ b/net/ethtool/ioctl.c
-@@ -1991,6 +1991,13 @@ __printf(2, 3) void ethtool_sprintf(u8 *
+@@ -1994,6 +1994,13 @@ __printf(2, 3) void ethtool_sprintf(u8 *
}
EXPORT_SYMBOL(ethtool_sprintf);
diff --git a/target/linux/generic/backport-6.6/896-01-v6.9-net-dsa-mv88e6xxx-rename-mv88e6xxx_g2_scratch_gpio_s.patch b/target/linux/generic/backport-6.6/896-01-v6.9-net-dsa-mv88e6xxx-rename-mv88e6xxx_g2_scratch_gpio_s.patch
index d9265cad10..48dd6ffb67 100644
--- a/target/linux/generic/backport-6.6/896-01-v6.9-net-dsa-mv88e6xxx-rename-mv88e6xxx_g2_scratch_gpio_s.patch
+++ b/target/linux/generic/backport-6.6/896-01-v6.9-net-dsa-mv88e6xxx-rename-mv88e6xxx_g2_scratch_gpio_s.patch
@@ -19,7 +19,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
-@@ -3668,7 +3668,7 @@ static int mv88e6xxx_mdio_register(struc
+@@ -3669,7 +3669,7 @@ static int mv88e6xxx_mdio_register(struc
if (external) {
mv88e6xxx_reg_lock(chip);
diff --git a/target/linux/generic/backport-6.6/896-02-v6.9-net-dsa-mv88e6xxx-add-Amethyst-specific-SMI-GPIO-fun.patch b/target/linux/generic/backport-6.6/896-02-v6.9-net-dsa-mv88e6xxx-add-Amethyst-specific-SMI-GPIO-fun.patch
index 5661d50adb..e5931573f7 100644
--- a/target/linux/generic/backport-6.6/896-02-v6.9-net-dsa-mv88e6xxx-add-Amethyst-specific-SMI-GPIO-fun.patch
+++ b/target/linux/generic/backport-6.6/896-02-v6.9-net-dsa-mv88e6xxx-add-Amethyst-specific-SMI-GPIO-fun.patch
@@ -27,7 +27,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
-@@ -3668,7 +3668,10 @@ static int mv88e6xxx_mdio_register(struc
+@@ -3669,7 +3669,10 @@ static int mv88e6xxx_mdio_register(struc
if (external) {
mv88e6xxx_reg_lock(chip);
diff --git a/target/linux/generic/config-5.15 b/target/linux/generic/config-5.15
index cba00711ca..a34ba551be 100644
--- a/target/linux/generic/config-5.15
+++ b/target/linux/generic/config-5.15
@@ -318,8 +318,10 @@ CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=8
# CONFIG_ARM64_64K_PAGES is not set
# CONFIG_ARM64_AMU_EXTN is not set
# CONFIG_ARM64_BTI is not set
+CONFIG_ARM64_CNP=y
# CONFIG_ARM64_CRYPTO is not set
# CONFIG_ARM64_E0PD is not set
+# CONFIG_ARM64_EPAN is not set
# CONFIG_ARM64_ERRATUM_1024718 is not set
# CONFIG_ARM64_ERRATUM_1165522 is not set
# CONFIG_ARM64_ERRATUM_1286807 is not set
@@ -349,7 +351,7 @@ CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=8
# CONFIG_ARM64_LSE_ATOMICS is not set
CONFIG_ARM64_MODULE_PLTS=y
# CONFIG_ARM64_MTE is not set
-# CONFIG_ARM64_PAN is not set
+CONFIG_ARM64_PAN=y
# CONFIG_ARM64_PMEM is not set
# CONFIG_ARM64_PSEUDO_NMI is not set
# CONFIG_ARM64_PTDUMP_DEBUGFS is not set
@@ -774,6 +776,7 @@ CONFIG_BROKEN_ON_SMP=y
# CONFIG_BTRFS_ASSERT is not set
# CONFIG_BTRFS_DEBUG is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_BTRFS_FS_CHECK_INTEGRITY is not set
# CONFIG_BTRFS_FS_POSIX_ACL is not set
# CONFIG_BTRFS_FS_REF_VERIFY is not set
# CONFIG_BTRFS_FS_RUN_SANITY_TESTS is not set
@@ -1043,10 +1046,10 @@ CONFIG_CRAMFS_BLOCKDEV=y
# CONFIG_CRC16 is not set
CONFIG_CRC32=y
# CONFIG_CRC32_BIT is not set
-CONFIG_CRC32_SARWATE=y
+# CONFIG_CRC32_SARWATE is not set
# CONFIG_CRC32_SELFTEST is not set
# CONFIG_CRC32_SLICEBY4 is not set
-# CONFIG_CRC32_SLICEBY8 is not set
+CONFIG_CRC32_SLICEBY8=y
# CONFIG_CRC4 is not set
# CONFIG_CRC64 is not set
# CONFIG_CRC7 is not set
@@ -4450,6 +4453,7 @@ CONFIG_NMI_LOG_BUF_SHIFT=13
# CONFIG_NVMEM_IMX_OCOTP is not set
# CONFIG_NVMEM_LAYOUT_ONIE_TLV is not set
# CONFIG_NVMEM_LAYOUT_SL28_VPD is not set
+# CONFIG_NVMEM_LAYOUT_U_BOOT_ENV is not set
# CONFIG_NVMEM_REBOOT_MODE is not set
# CONFIG_NVMEM_RMEM is not set
# CONFIG_NVMEM_SYSFS is not set
diff --git a/target/linux/generic/config-6.1 b/target/linux/generic/config-6.1
index 70e87665b7..ef61717d78 100644
--- a/target/linux/generic/config-6.1
+++ b/target/linux/generic/config-6.1
@@ -348,8 +348,10 @@ CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=8
# CONFIG_ARM64_64K_PAGES is not set
# CONFIG_ARM64_AMU_EXTN is not set
# CONFIG_ARM64_BTI is not set
+CONFIG_ARM64_CNP=y
# CONFIG_ARM64_CRYPTO is not set
# CONFIG_ARM64_E0PD is not set
+# CONFIG_ARM64_EPAN is not set
# CONFIG_ARM64_ERRATUM_1024718 is not set
# CONFIG_ARM64_ERRATUM_1165522 is not set
# CONFIG_ARM64_ERRATUM_1286807 is not set
@@ -368,6 +370,8 @@ CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=8
# CONFIG_ARM64_ERRATUM_2441009 is not set
# CONFIG_ARM64_ERRATUM_2658417 is not set
# CONFIG_ARM64_ERRATUM_2966298 is not set
+# CONFIG_ARM64_ERRATUM_3194386 is not set
+# CONFIG_ARM64_ERRATUM_3312417 is not set
# CONFIG_ARM64_ERRATUM_819472 is not set
# CONFIG_ARM64_ERRATUM_824069 is not set
# CONFIG_ARM64_ERRATUM_826319 is not set
@@ -381,7 +385,7 @@ CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=8
# CONFIG_ARM64_LSE_ATOMICS is not set
CONFIG_ARM64_MODULE_PLTS=y
# CONFIG_ARM64_MTE is not set
-# CONFIG_ARM64_PAN is not set
+CONFIG_ARM64_PAN=y
# CONFIG_ARM64_PMEM is not set
# CONFIG_ARM64_PSEUDO_NMI is not set
# CONFIG_ARM64_PTDUMP_DEBUGFS is not set
@@ -820,6 +824,7 @@ CONFIG_BROKEN_ON_SMP=y
# CONFIG_BTRFS_ASSERT is not set
# CONFIG_BTRFS_DEBUG is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_BTRFS_FS_CHECK_INTEGRITY is not set
# CONFIG_BTRFS_FS_POSIX_ACL is not set
# CONFIG_BTRFS_FS_REF_VERIFY is not set
# CONFIG_BTRFS_FS_RUN_SANITY_TESTS is not set
@@ -1102,10 +1107,10 @@ CONFIG_CRAMFS_BLOCKDEV=y
# CONFIG_CRC16 is not set
CONFIG_CRC32=y
# CONFIG_CRC32_BIT is not set
-CONFIG_CRC32_SARWATE=y
+# CONFIG_CRC32_SARWATE is not set
# CONFIG_CRC32_SELFTEST is not set
# CONFIG_CRC32_SLICEBY4 is not set
-# CONFIG_CRC32_SLICEBY8 is not set
+CONFIG_CRC32_SLICEBY8=y
# CONFIG_CRC4 is not set
# CONFIG_CRC64 is not set
# CONFIG_CRC64_ROCKSOFT is not set
@@ -4619,6 +4624,7 @@ CONFIG_NMI_LOG_BUF_SHIFT=13
# CONFIG_NVMEM_IMX_OCOTP is not set
# CONFIG_NVMEM_LAYOUT_ONIE_TLV is not set
# CONFIG_NVMEM_LAYOUT_SL28_VPD is not set
+# CONFIG_NVMEM_LAYOUT_U_BOOT_ENV is not set
# CONFIG_NVMEM_REBOOT_MODE is not set
# CONFIG_NVMEM_RMEM is not set
# CONFIG_NVMEM_SYSFS is not set
@@ -4838,6 +4844,7 @@ CONFIG_PCI_SYSCALL=y
# CONFIG_PCMCIA_XIRC2PS is not set
# CONFIG_PCMCIA_XIRCOM is not set
# CONFIG_PCNET32 is not set
+CONFIG_PCP_BATCH_SCALE_MAX=5
# CONFIG_PCPU_DEV_REFCNT is not set
# CONFIG_PCSPKR_PLATFORM is not set
# CONFIG_PCS_MTK_USXGMII is not set
diff --git a/target/linux/generic/config-6.6 b/target/linux/generic/config-6.6
index 20fe98099f..71fdf59d33 100644
--- a/target/linux/generic/config-6.6
+++ b/target/linux/generic/config-6.6
@@ -179,6 +179,7 @@ CONFIG_ALLOW_DEV_COREDUMP=y
# CONFIG_AMD_MEM_ENCRYPT is not set
# CONFIG_AMD_PHY is not set
# CONFIG_AMD_XGBE is not set
+# CONFIG_AMD_XGBE_DCB is not set
# CONFIG_AMD_XGBE_HAVE_ECC is not set
# CONFIG_AMIGA_PARTITION is not set
# CONFIG_AMILO_RFKILL is not set
@@ -324,7 +325,9 @@ CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=8
# CONFIG_ARM64_64K_PAGES is not set
# CONFIG_ARM64_AMU_EXTN is not set
# CONFIG_ARM64_BTI is not set
+CONFIG_ARM64_CNP=y
# CONFIG_ARM64_E0PD is not set
+# CONFIG_ARM64_EPAN is not set
# CONFIG_ARM64_ERRATUM_1024718 is not set
# CONFIG_ARM64_ERRATUM_1165522 is not set
# CONFIG_ARM64_ERRATUM_1286807 is not set
@@ -345,6 +348,7 @@ CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=8
# CONFIG_ARM64_ERRATUM_2658417 is not set
# CONFIG_ARM64_ERRATUM_2966298 is not set
# CONFIG_ARM64_ERRATUM_3117295 is not set
+# CONFIG_ARM64_ERRATUM_3194386 is not set
# CONFIG_ARM64_ERRATUM_819472 is not set
# CONFIG_ARM64_ERRATUM_824069 is not set
# CONFIG_ARM64_ERRATUM_826319 is not set
@@ -357,7 +361,7 @@ CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=8
# CONFIG_ARM64_HW_AFDBM is not set
# CONFIG_ARM64_LSE_ATOMICS is not set
# CONFIG_ARM64_MTE is not set
-# CONFIG_ARM64_PAN is not set
+CONFIG_ARM64_PAN=y
# CONFIG_ARM64_PMEM is not set
# CONFIG_ARM64_PSEUDO_NMI is not set
# CONFIG_ARM64_PTR_AUTH is not set
@@ -635,11 +639,11 @@ CONFIG_BLK_DEV_LOOP_MIN_COUNT=8
# CONFIG_BLK_DEV_UBLK is not set
# CONFIG_BLK_DEV_ZONED is not set
# CONFIG_BLK_INLINE_ENCRYPTION is not set
-# CONFIG_BLOCK_NOTIFIERS is not set
# CONFIG_BLK_SED_OPAL is not set
# CONFIG_BLK_WBT is not set
CONFIG_BLOCK=y
# CONFIG_BLOCK_LEGACY_AUTOLOAD is not set
+# CONFIG_BLOCK_NOTIFIERS is not set
# CONFIG_BMA180 is not set
# CONFIG_BMA220 is not set
# CONFIG_BMA400 is not set
@@ -725,6 +729,7 @@ CONFIG_BROKEN_ON_SMP=y
# CONFIG_BTRFS_ASSERT is not set
# CONFIG_BTRFS_DEBUG is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_BTRFS_FS_CHECK_INTEGRITY is not set
# CONFIG_BTRFS_FS_POSIX_ACL is not set
# CONFIG_BTRFS_FS_REF_VERIFY is not set
# CONFIG_BTRFS_FS_RUN_SANITY_TESTS is not set
@@ -875,6 +880,7 @@ CONFIG_CFG80211_HEADERS=y
# CONFIG_CHELSIO_T4 is not set
# CONFIG_CHELSIO_T4VF is not set
# CONFIG_CHROME_PLATFORMS is not set
+# CONFIG_CZNIC_PLATFORMS is not set
# CONFIG_CHR_DEV_SCH is not set
# CONFIG_CHR_DEV_SG is not set
# CONFIG_CHR_DEV_ST is not set
@@ -1003,10 +1009,10 @@ CONFIG_CRAMFS_BLOCKDEV=y
# CONFIG_CRC16 is not set
CONFIG_CRC32=y
# CONFIG_CRC32_BIT is not set
-CONFIG_CRC32_SARWATE=y
+# CONFIG_CRC32_SARWATE is not set
# CONFIG_CRC32_SELFTEST is not set
# CONFIG_CRC32_SLICEBY4 is not set
-# CONFIG_CRC32_SLICEBY8 is not set
+CONFIG_CRC32_SLICEBY8=y
# CONFIG_CRC4 is not set
# CONFIG_CRC64 is not set
# CONFIG_CRC64_ROCKSOFT is not set
@@ -1015,8 +1021,8 @@ CONFIG_CRC32_SARWATE=y
# CONFIG_CRC_CCITT is not set
# CONFIG_CRC_ITU_T is not set
# CONFIG_CRC_T10DIF is not set
-# CONFIG_CROS_HPS_I2C is not set
# CONFIG_CROSS_MEMORY_ATTACH is not set
+# CONFIG_CROS_HPS_I2C is not set
CONFIG_CRYPTO=y
# CONFIG_CRYPTO_842 is not set
CONFIG_CRYPTO_ACOMP2=y
@@ -1527,8 +1533,8 @@ CONFIG_DQL=y
# CONFIG_DRM_PANEL_MANTIX_MLAF057WE51 is not set
# CONFIG_DRM_PANEL_MIPI_DBI is not set
# CONFIG_DRM_PANEL_NEC_NL8048HL11 is not set
-# CONFIG_DRM_PANEL_NEWVISION_NV3052C is not set
# CONFIG_DRM_PANEL_NEWVISION_NV3051D is not set
+# CONFIG_DRM_PANEL_NEWVISION_NV3052C is not set
# CONFIG_DRM_PANEL_NOVATEK_NT35510 is not set
# CONFIG_DRM_PANEL_NOVATEK_NT35560 is not set
# CONFIG_DRM_PANEL_NOVATEK_NT35950 is not set
@@ -2521,6 +2527,7 @@ CONFIG_HZ_100=y
# CONFIG_I3C is not set
# CONFIG_I40E is not set
# CONFIG_I40EVF is not set
+# CONFIG_I40E_DCB is not set
# CONFIG_I6300ESB_WDT is not set
# CONFIG_I82092 is not set
# CONFIG_I82365 is not set
@@ -2869,6 +2876,7 @@ CONFIG_ISDN=y
# CONFIG_IWLWIFI is not set
# CONFIG_IXGBE is not set
# CONFIG_IXGBEVF is not set
+# CONFIG_IXGBE_DCB is not set
# CONFIG_JAILHOUSE_GUEST is not set
# CONFIG_JBD2_DEBUG is not set
# CONFIG_JFFS2_CMODE_FAVOURLZO is not set
@@ -3111,7 +3119,7 @@ CONFIG_LINEAR_RANGES=y
# CONFIG_LIQUIDIO is not set
# CONFIG_LIQUIDIO_VF is not set
# CONFIG_LIRC is not set
-# CONFIG_LIST_HARDENED is not set
+CONFIG_LIST_HARDENED=y
# CONFIG_LITEX_LITEETH is not set
# CONFIG_LITEX_SOC_CONTROLLER is not set
# CONFIG_LIVEPATCH is not set
@@ -4327,6 +4335,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
# CONFIG_NVMEM_IMX_OCOTP is not set
# CONFIG_NVMEM_LAYOUT_ONIE_TLV is not set
# CONFIG_NVMEM_LAYOUT_SL28_VPD is not set
+# CONFIG_NVMEM_LAYOUT_U_BOOT_ENV is not set
# CONFIG_NVMEM_REBOOT_MODE is not set
# CONFIG_NVMEM_RMEM is not set
# CONFIG_NVMEM_SYSFS is not set
@@ -4545,6 +4554,7 @@ CONFIG_PCI_SYSCALL=y
# CONFIG_PCMCIA_XIRCOM is not set
# CONFIG_PCNET32 is not set
# CONFIG_PCPU_DEV_REFCNT is not set
+CONFIG_PCP_BATCH_SCALE_MAX=5
# CONFIG_PCSPKR_PLATFORM is not set
# CONFIG_PCS_MTK_USXGMII is not set
# CONFIG_PCS_XPCS is not set
@@ -4797,6 +4807,7 @@ CONFIG_PWRSEQ_SIMPLE=y
# CONFIG_QFMT_V1 is not set
# CONFIG_QLA3XXX is not set
# CONFIG_QLCNIC is not set
+# CONFIG_QLCNIC_DCB is not set
# CONFIG_QLGE is not set
# CONFIG_QNX4FS_FS is not set
# CONFIG_QNX6FS_FS is not set
@@ -6182,8 +6193,8 @@ CONFIG_SND_X86=y
# CONFIG_SPI_AXI_SPI_ENGINE is not set
# CONFIG_SPI_BCM2835 is not set
# CONFIG_SPI_BCM63XX_HSSPI is not set
-# CONFIG_SPI_BCM_QSPI is not set
# CONFIG_SPI_BCMBCA_HSSPI is not set
+# CONFIG_SPI_BCM_QSPI is not set
# CONFIG_SPI_BITBANG is not set
# CONFIG_SPI_BUTTERFLY is not set
# CONFIG_SPI_CADENCE is not set
@@ -6760,8 +6771,8 @@ CONFIG_USB_BELKIN=y
# CONFIG_USB_CDNS3 is not set
# CONFIG_USB_CDNS3_IMX is not set
# CONFIG_USB_CDNS3_PCI_WRAP is not set
-# CONFIG_USB_CDNS_SUPPORT is not set
# CONFIG_USB_CDNSP_PCI is not set
+# CONFIG_USB_CDNS_SUPPORT is not set
# CONFIG_USB_CHAOSKEY is not set
# CONFIG_USB_CHIPIDEA is not set
# CONFIG_USB_CHIPIDEA_GENERIC is not set
@@ -6787,6 +6798,7 @@ CONFIG_USB_DEFAULT_PERSIST=y
# CONFIG_USB_DWC3_EXYNOS is not set
# CONFIG_USB_DWC3_HAPS is not set
# CONFIG_USB_DWC3_KEYSTONE is not set
+# CONFIG_USB_DWC3_OCTEON is not set
# CONFIG_USB_DWC3_OF_SIMPLE is not set
# CONFIG_USB_DWC3_PCI is not set
# CONFIG_USB_DWC3_QCOM is not set
diff --git a/target/linux/generic/files/drivers/net/phy/rtl8366_smi.h b/target/linux/generic/files/drivers/net/phy/rtl8366_smi.h
index 3fcae81fa4..2608240bb0 100644
--- a/target/linux/generic/files/drivers/net/phy/rtl8366_smi.h
+++ b/target/linux/generic/files/drivers/net/phy/rtl8366_smi.h
@@ -23,6 +23,18 @@ struct dentry;
struct inode;
struct file;
+typedef enum rtl8367b_chip_e {
+ RTL8367B_CHIP_UNKNOWN,
+ /* Family B */
+ RTL8367B_CHIP_RTL8367RB,
+ RTL8367B_CHIP_RTL8367R_VB, /* chip with exception in extif assignment */
+/* Family C */
+ RTL8367B_CHIP_RTL8367RB_VB,
+ RTL8367B_CHIP_RTL8367S,
+/* Family D */
+ RTL8367B_CHIP_RTL8367S_VB /* chip with exception in extif assignment */
+} rtl8367b_chip_t;
+
struct rtl8366_mib_counter {
unsigned base;
unsigned offset;
@@ -64,7 +76,9 @@ struct rtl8366_smi {
u8 dbg_vlan_4k_page;
#endif
u32 phy_id;
+ rtl8367b_chip_t rtl8367b_chip;
struct mii_bus *ext_mbus;
+ struct rtl8366_vlan_mc *emu_vlanmc;
};
struct rtl8366_vlan_mc {
diff --git a/target/linux/generic/files/drivers/net/phy/rtl8367.c b/target/linux/generic/files/drivers/net/phy/rtl8367.c
index b14b63e036..0acfeb54bb 100644
--- a/target/linux/generic/files/drivers/net/phy/rtl8367.c
+++ b/target/linux/generic/files/drivers/net/phy/rtl8367.c
@@ -1077,21 +1077,37 @@ static int rtl8367_led_blinkrate_set(struct rtl8366_smi *smi, unsigned int rate)
}
#ifdef CONFIG_OF
-static int rtl8367_extif_init_of(struct rtl8366_smi *smi, int id,
+static int rtl8367_extif_init_of(struct rtl8366_smi *smi,
const char *name)
{
struct rtl8367_extif_config *cfg;
const __be32 *prop;
int size;
int err;
+ unsigned cpu_port;
+ unsigned id = UINT_MAX;
prop = of_get_property(smi->parent->of_node, name, &size);
- if (!prop)
- return rtl8367_extif_init(smi, id, NULL);
+ if (!prop || (size != (10 * sizeof(*prop)))) {
+ dev_err(smi->parent, "%s property is not defined or invalid\n", name);
+ err = -EINVAL;
+ goto err_init;
+ }
- if (size != (9 * sizeof(*prop))) {
- dev_err(smi->parent, "%s property is invalid\n", name);
- return -EINVAL;
+ cpu_port = be32_to_cpup(prop++);
+ switch (cpu_port) {
+ case RTL8367_CPU_PORT_NUM - 1:
+ case RTL8367_CPU_PORT_NUM:
+ id = RTL8367_CPU_PORT_NUM - cpu_port;
+ if (smi->cpu_port == UINT_MAX) {
+ dev_info(smi->parent, "cpu_port:%u, assigned to extif%u\n", cpu_port, id);
+ smi->cpu_port = cpu_port;
+ }
+ break;
+ default:
+ dev_err(smi->parent, "wrong cpu_port %u in %s property\n", cpu_port, name);
+ err = -EINVAL;
+ goto err_init;
}
cfg = kzalloc(sizeof(struct rtl8367_extif_config), GFP_KERNEL);
@@ -1111,10 +1127,14 @@ static int rtl8367_extif_init_of(struct rtl8366_smi *smi, int id,
err = rtl8367_extif_init(smi, id, cfg);
kfree(cfg);
+err_init:
+ if (id != 0) rtl8367_extif_init(smi, 0, NULL);
+ if (id != 1) rtl8367_extif_init(smi, 1, NULL);
+
return err;
}
#else
-static int rtl8367_extif_init_of(struct rtl8366_smi *smi, int id,
+static int rtl8367_extif_init_of(struct rtl8366_smi *smi,
const char *name)
{
return -EINVAL;
@@ -1135,11 +1155,7 @@ static int rtl8367_setup(struct rtl8366_smi *smi)
/* initialize external interfaces */
if (smi->parent->of_node) {
- err = rtl8367_extif_init_of(smi, 0, "realtek,extif0");
- if (err)
- return err;
-
- err = rtl8367_extif_init_of(smi, 1, "realtek,extif1");
+ err = rtl8367_extif_init_of(smi, "realtek,extif");
if (err)
return err;
} else {
@@ -1722,11 +1738,6 @@ static int rtl8367_detect(struct rtl8366_smi *smi)
dev_info(smi->parent, "RTL%s ver. %u chip found\n",
chip_name, rtl_ver & RTL8367_RTL_VER_MASK);
- if (of_property_present(smi->parent->of_node, "realtek,extif1"))
- smi->cpu_port = RTL8367_CPU_PORT_NUM - 1;
-
- dev_info(smi->parent, "CPU port: %u\n", smi->cpu_port);
-
return 0;
}
@@ -1764,7 +1775,7 @@ static int rtl8367_probe(struct platform_device *pdev)
smi->cmd_read = 0xb9;
smi->cmd_write = 0xb8;
smi->ops = &rtl8367_smi_ops;
- smi->cpu_port = RTL8367_CPU_PORT_NUM;
+ smi->cpu_port = UINT_MAX; /* not defined yet */
smi->num_ports = RTL8367_NUM_PORTS;
smi->num_vlan_mc = RTL8367_NUM_VLANS;
smi->mib_counters = rtl8367_mib_counters;
diff --git a/target/linux/generic/files/drivers/net/phy/rtl8367b.c b/target/linux/generic/files/drivers/net/phy/rtl8367b.c
index 04c790e924..4236912dd5 100644
--- a/target/linux/generic/files/drivers/net/phy/rtl8367b.c
+++ b/target/linux/generic/files/drivers/net/phy/rtl8367b.c
@@ -1,5 +1,7 @@
/*
- * Platform driver for the Realtek RTL8367R-VB ethernet switches
+ * Platform driver for Realtek RTL8367B family chips, i.e. RTL8367RB and RTL8367R-VB
+ * extended with support for RTL8367C family chips, i.e. RTL8367RB-VB and RTL8367S
+ * extended with support for RTL8367D family chips, i.e. RTL8367S-VB
*
* Copyright (C) 2012 Gabor Juhos <juhosg@openwrt.org>
*
@@ -266,6 +268,37 @@ struct rtl8367b_initval {
#define RTL8367B_MIB_RXB_ID 0 /* IfInOctets */
#define RTL8367B_MIB_TXB_ID 28 /* IfOutOctets */
+#define RTL8367D_PORT_STATUS_REG(_p) (0x12d0 + (_p))
+
+#define RTL8367D_PORT_STATUS_SPEED1_MASK 0x3000
+#define RTL8367D_PORT_STATUS_SPEED1_SHIFT 10 /*12-2*/
+
+#define RTL8367D_REG_MAC0_FORCE_SELECT 0x12c0
+#define RTL8367D_REG_MAC0_FORCE_SELECT_EN 0x12c8
+
+#define RTL8367D_VLAN_PVID_CTRL_REG(_p) (0x0700 + (_p))
+#define RTL8367D_VLAN_PVID_CTRL_MASK 0xfff
+#define RTL8367D_VLAN_PVID_CTRL_SHIFT(_p) 0
+
+#define RTL8367D_FIDMAX 3
+#define RTL8367D_FID_MASK 3
+#define RTL8367D_TA_VLAN1_FID_SHIFT 0
+#define RTL8367D_TA_VLAN1_FID_MASK RTL8367D_FID_MASK
+
+#define RTL8367D_VID_MASK 0xfff
+#define RTL8367D_TA_VLAN_VID_MASK RTL8367D_VID_MASK
+
+#define RTL8367D_REG_EXT_TXC_DLY 0x13f9
+#define RTL8367D_EXT1_RGMII_TX_DLY_MASK 0x38
+
+#define RTL8367D_REG_TOP_CON0 0x1d70
+#define RTL8367D_MAC7_SEL_EXT1_MASK 0x2000
+#define RTL8367D_MAC4_SEL_EXT1_MASK 0x1000
+
+#define RTL8367D_REG_SDS1_MISC0 0x1d78
+#define RTL8367D_SDS1_MODE_MASK 0x1f
+#define RTL8367D_PORT_SDS_MODE_DISABLE 0x1f
+
static struct rtl8366_mib_counter
rtl8367b_mib_counters[RTL8367B_NUM_MIB_COUNTERS] = {
{0, 0, 4, "ifInOctets" },
@@ -351,220 +384,7 @@ rtl8367b_mib_counters[RTL8367B_NUM_MIB_COUNTERS] = {
return err; \
} while (0)
-static const struct rtl8367b_initval rtl8367r_vb_initvals_0[] = {
- {0x1B03, 0x0876}, {0x1200, 0x7FC4}, {0x0301, 0x0026}, {0x1722, 0x0E14},
- {0x205F, 0x0002}, {0x2059, 0x1A00}, {0x205F, 0x0000}, {0x207F, 0x0002},
- {0x2077, 0x0000}, {0x2078, 0x0000}, {0x2079, 0x0000}, {0x207A, 0x0000},
- {0x207B, 0x0000}, {0x207F, 0x0000}, {0x205F, 0x0002}, {0x2053, 0x0000},
- {0x2054, 0x0000}, {0x2055, 0x0000}, {0x2056, 0x0000}, {0x2057, 0x0000},
- {0x205F, 0x0000}, {0x12A4, 0x110A}, {0x12A6, 0x150A}, {0x13F1, 0x0013},
- {0x13F4, 0x0010}, {0x13F5, 0x0000}, {0x0018, 0x0F00}, {0x0038, 0x0F00},
- {0x0058, 0x0F00}, {0x0078, 0x0F00}, {0x0098, 0x0F00}, {0x12B6, 0x0C02},
- {0x12B7, 0x030F}, {0x12B8, 0x11FF}, {0x12BC, 0x0004}, {0x1362, 0x0115},
- {0x1363, 0x0002}, {0x1363, 0x0000}, {0x133F, 0x0030}, {0x133E, 0x000E},
- {0x221F, 0x0007}, {0x221E, 0x002D}, {0x2218, 0xF030}, {0x221F, 0x0007},
- {0x221E, 0x0023}, {0x2216, 0x0005}, {0x2215, 0x00B9}, {0x2219, 0x0044},
- {0x2215, 0x00BA}, {0x2219, 0x0020}, {0x2215, 0x00BB}, {0x2219, 0x00C1},
- {0x2215, 0x0148}, {0x2219, 0x0096}, {0x2215, 0x016E}, {0x2219, 0x0026},
- {0x2216, 0x0000}, {0x2216, 0x0000}, {0x221E, 0x002D}, {0x2218, 0xF010},
- {0x221F, 0x0007}, {0x221E, 0x0020}, {0x2215, 0x0D00}, {0x221F, 0x0000},
- {0x221F, 0x0000}, {0x2217, 0x2160}, {0x221F, 0x0001}, {0x2210, 0xF25E},
- {0x221F, 0x0007}, {0x221E, 0x0042}, {0x2215, 0x0F00}, {0x2215, 0x0F00},
- {0x2216, 0x7408}, {0x2215, 0x0E00}, {0x2215, 0x0F00}, {0x2215, 0x0F01},
- {0x2216, 0x4000}, {0x2215, 0x0E01}, {0x2215, 0x0F01}, {0x2215, 0x0F02},
- {0x2216, 0x9400}, {0x2215, 0x0E02}, {0x2215, 0x0F02}, {0x2215, 0x0F03},
- {0x2216, 0x7408}, {0x2215, 0x0E03}, {0x2215, 0x0F03}, {0x2215, 0x0F04},
- {0x2216, 0x4008}, {0x2215, 0x0E04}, {0x2215, 0x0F04}, {0x2215, 0x0F05},
- {0x2216, 0x9400}, {0x2215, 0x0E05}, {0x2215, 0x0F05}, {0x2215, 0x0F06},
- {0x2216, 0x0803}, {0x2215, 0x0E06}, {0x2215, 0x0F06}, {0x2215, 0x0D00},
- {0x2215, 0x0100}, {0x221F, 0x0001}, {0x2210, 0xF05E}, {0x221F, 0x0000},
- {0x2217, 0x2100}, {0x221F, 0x0000}, {0x220D, 0x0003}, {0x220E, 0x0015},
- {0x220D, 0x4003}, {0x220E, 0x0006}, {0x221F, 0x0000}, {0x2200, 0x1340},
- {0x133F, 0x0010}, {0x12A0, 0x0058}, {0x12A1, 0x0058}, {0x133E, 0x000E},
- {0x133F, 0x0030}, {0x221F, 0x0000}, {0x2210, 0x0166}, {0x221F, 0x0000},
- {0x133E, 0x000E}, {0x133F, 0x0010}, {0x133F, 0x0030}, {0x133E, 0x000E},
- {0x221F, 0x0005}, {0x2205, 0xFFF6}, {0x2206, 0x0080}, {0x2205, 0x8B6E},
- {0x2206, 0x0000}, {0x220F, 0x0100}, {0x2205, 0x8000}, {0x2206, 0x0280},
- {0x2206, 0x28F7}, {0x2206, 0x00E0}, {0x2206, 0xFFF7}, {0x2206, 0xA080},
- {0x2206, 0x02AE}, {0x2206, 0xF602}, {0x2206, 0x0153}, {0x2206, 0x0201},
- {0x2206, 0x6602}, {0x2206, 0x80B9}, {0x2206, 0xE08B}, {0x2206, 0x8CE1},
- {0x2206, 0x8B8D}, {0x2206, 0x1E01}, {0x2206, 0xE18B}, {0x2206, 0x8E1E},
- {0x2206, 0x01A0}, {0x2206, 0x00E7}, {0x2206, 0xAEDB}, {0x2206, 0xEEE0},
- {0x2206, 0x120E}, {0x2206, 0xEEE0}, {0x2206, 0x1300}, {0x2206, 0xEEE0},
- {0x2206, 0x2001}, {0x2206, 0xEEE0}, {0x2206, 0x2166}, {0x2206, 0xEEE0},
- {0x2206, 0xC463}, {0x2206, 0xEEE0}, {0x2206, 0xC5E8}, {0x2206, 0xEEE0},
- {0x2206, 0xC699}, {0x2206, 0xEEE0}, {0x2206, 0xC7C2}, {0x2206, 0xEEE0},
- {0x2206, 0xC801}, {0x2206, 0xEEE0}, {0x2206, 0xC913}, {0x2206, 0xEEE0},
- {0x2206, 0xCA30}, {0x2206, 0xEEE0}, {0x2206, 0xCB3E}, {0x2206, 0xEEE0},
- {0x2206, 0xDCE1}, {0x2206, 0xEEE0}, {0x2206, 0xDD00}, {0x2206, 0xEEE2},
- {0x2206, 0x0001}, {0x2206, 0xEEE2}, {0x2206, 0x0100}, {0x2206, 0xEEE4},
- {0x2206, 0x8860}, {0x2206, 0xEEE4}, {0x2206, 0x8902}, {0x2206, 0xEEE4},
- {0x2206, 0x8C00}, {0x2206, 0xEEE4}, {0x2206, 0x8D30}, {0x2206, 0xEEEA},
- {0x2206, 0x1480}, {0x2206, 0xEEEA}, {0x2206, 0x1503}, {0x2206, 0xEEEA},
- {0x2206, 0xC600}, {0x2206, 0xEEEA}, {0x2206, 0xC706}, {0x2206, 0xEE85},
- {0x2206, 0xEE00}, {0x2206, 0xEE85}, {0x2206, 0xEF00}, {0x2206, 0xEE8B},
- {0x2206, 0x6750}, {0x2206, 0xEE8B}, {0x2206, 0x6632}, {0x2206, 0xEE8A},
- {0x2206, 0xD448}, {0x2206, 0xEE8A}, {0x2206, 0xD548}, {0x2206, 0xEE8A},
- {0x2206, 0xD649}, {0x2206, 0xEE8A}, {0x2206, 0xD7F8}, {0x2206, 0xEE8B},
- {0x2206, 0x85E2}, {0x2206, 0xEE8B}, {0x2206, 0x8700}, {0x2206, 0xEEFF},
- {0x2206, 0xF600}, {0x2206, 0xEEFF}, {0x2206, 0xF7FC}, {0x2206, 0x04F8},
- {0x2206, 0xE08B}, {0x2206, 0x8EAD}, {0x2206, 0x2023}, {0x2206, 0xF620},
- {0x2206, 0xE48B}, {0x2206, 0x8E02}, {0x2206, 0x2877}, {0x2206, 0x0225},
- {0x2206, 0xC702}, {0x2206, 0x26A1}, {0x2206, 0x0281}, {0x2206, 0xB302},
- {0x2206, 0x8496}, {0x2206, 0x0202}, {0x2206, 0xA102}, {0x2206, 0x27F1},
- {0x2206, 0x0228}, {0x2206, 0xF902}, {0x2206, 0x2AA0}, {0x2206, 0x0282},
- {0x2206, 0xB8E0}, {0x2206, 0x8B8E}, {0x2206, 0xAD21}, {0x2206, 0x08F6},
- {0x2206, 0x21E4}, {0x2206, 0x8B8E}, {0x2206, 0x0202}, {0x2206, 0x80E0},
- {0x2206, 0x8B8E}, {0x2206, 0xAD22}, {0x2206, 0x05F6}, {0x2206, 0x22E4},
- {0x2206, 0x8B8E}, {0x2206, 0xE08B}, {0x2206, 0x8EAD}, {0x2206, 0x2305},
- {0x2206, 0xF623}, {0x2206, 0xE48B}, {0x2206, 0x8EE0}, {0x2206, 0x8B8E},
- {0x2206, 0xAD24}, {0x2206, 0x08F6}, {0x2206, 0x24E4}, {0x2206, 0x8B8E},
- {0x2206, 0x0227}, {0x2206, 0x6AE0}, {0x2206, 0x8B8E}, {0x2206, 0xAD25},
- {0x2206, 0x05F6}, {0x2206, 0x25E4}, {0x2206, 0x8B8E}, {0x2206, 0xE08B},
- {0x2206, 0x8EAD}, {0x2206, 0x260B}, {0x2206, 0xF626}, {0x2206, 0xE48B},
- {0x2206, 0x8E02}, {0x2206, 0x830D}, {0x2206, 0x021D}, {0x2206, 0x6BE0},
- {0x2206, 0x8B8E}, {0x2206, 0xAD27}, {0x2206, 0x05F6}, {0x2206, 0x27E4},
- {0x2206, 0x8B8E}, {0x2206, 0x0281}, {0x2206, 0x4402}, {0x2206, 0x045C},
- {0x2206, 0xFC04}, {0x2206, 0xF8E0}, {0x2206, 0x8B83}, {0x2206, 0xAD23},
- {0x2206, 0x30E0}, {0x2206, 0xE022}, {0x2206, 0xE1E0}, {0x2206, 0x2359},
- {0x2206, 0x02E0}, {0x2206, 0x85EF}, {0x2206, 0xE585}, {0x2206, 0xEFAC},
- {0x2206, 0x2907}, {0x2206, 0x1F01}, {0x2206, 0x9E51}, {0x2206, 0xAD29},
- {0x2206, 0x20E0}, {0x2206, 0x8B83}, {0x2206, 0xAD21}, {0x2206, 0x06E1},
- {0x2206, 0x8B84}, {0x2206, 0xAD28}, {0x2206, 0x42E0}, {0x2206, 0x8B85},
- {0x2206, 0xAD21}, {0x2206, 0x06E1}, {0x2206, 0x8B84}, {0x2206, 0xAD29},
- {0x2206, 0x36BF}, {0x2206, 0x34BF}, {0x2206, 0x022C}, {0x2206, 0x31AE},
- {0x2206, 0x2EE0}, {0x2206, 0x8B83}, {0x2206, 0xAD21}, {0x2206, 0x10E0},
- {0x2206, 0x8B84}, {0x2206, 0xF620}, {0x2206, 0xE48B}, {0x2206, 0x84EE},
- {0x2206, 0x8ADA}, {0x2206, 0x00EE}, {0x2206, 0x8ADB}, {0x2206, 0x00E0},
- {0x2206, 0x8B85}, {0x2206, 0xAD21}, {0x2206, 0x0CE0}, {0x2206, 0x8B84},
- {0x2206, 0xF621}, {0x2206, 0xE48B}, {0x2206, 0x84EE}, {0x2206, 0x8B72},
- {0x2206, 0xFFBF}, {0x2206, 0x34C2}, {0x2206, 0x022C}, {0x2206, 0x31FC},
- {0x2206, 0x04F8}, {0x2206, 0xFAEF}, {0x2206, 0x69E0}, {0x2206, 0x8B85},
- {0x2206, 0xAD21}, {0x2206, 0x42E0}, {0x2206, 0xE022}, {0x2206, 0xE1E0},
- {0x2206, 0x2358}, {0x2206, 0xC059}, {0x2206, 0x021E}, {0x2206, 0x01E1},
- {0x2206, 0x8B72}, {0x2206, 0x1F10}, {0x2206, 0x9E2F}, {0x2206, 0xE48B},
- {0x2206, 0x72AD}, {0x2206, 0x2123}, {0x2206, 0xE18B}, {0x2206, 0x84F7},
- {0x2206, 0x29E5}, {0x2206, 0x8B84}, {0x2206, 0xAC27}, {0x2206, 0x10AC},
- {0x2206, 0x2605}, {0x2206, 0x0205}, {0x2206, 0x23AE}, {0x2206, 0x1602},
- {0x2206, 0x0535}, {0x2206, 0x0282}, {0x2206, 0x30AE}, {0x2206, 0x0E02},
- {0x2206, 0x056A}, {0x2206, 0x0282}, {0x2206, 0x75AE}, {0x2206, 0x0602},
- {0x2206, 0x04DC}, {0x2206, 0x0282}, {0x2206, 0x04EF}, {0x2206, 0x96FE},
- {0x2206, 0xFC04}, {0x2206, 0xF8F9}, {0x2206, 0xE08B}, {0x2206, 0x87AD},
- {0x2206, 0x2321}, {0x2206, 0xE0EA}, {0x2206, 0x14E1}, {0x2206, 0xEA15},
- {0x2206, 0xAD26}, {0x2206, 0x18F6}, {0x2206, 0x27E4}, {0x2206, 0xEA14},
- {0x2206, 0xE5EA}, {0x2206, 0x15F6}, {0x2206, 0x26E4}, {0x2206, 0xEA14},
- {0x2206, 0xE5EA}, {0x2206, 0x15F7}, {0x2206, 0x27E4}, {0x2206, 0xEA14},
- {0x2206, 0xE5EA}, {0x2206, 0x15FD}, {0x2206, 0xFC04}, {0x2206, 0xF8F9},
- {0x2206, 0xE08B}, {0x2206, 0x87AD}, {0x2206, 0x233A}, {0x2206, 0xAD22},
- {0x2206, 0x37E0}, {0x2206, 0xE020}, {0x2206, 0xE1E0}, {0x2206, 0x21AC},
- {0x2206, 0x212E}, {0x2206, 0xE0EA}, {0x2206, 0x14E1}, {0x2206, 0xEA15},
- {0x2206, 0xF627}, {0x2206, 0xE4EA}, {0x2206, 0x14E5}, {0x2206, 0xEA15},
- {0x2206, 0xE2EA}, {0x2206, 0x12E3}, {0x2206, 0xEA13}, {0x2206, 0x5A8F},
- {0x2206, 0x6A20}, {0x2206, 0xE6EA}, {0x2206, 0x12E7}, {0x2206, 0xEA13},
- {0x2206, 0xF726}, {0x2206, 0xE4EA}, {0x2206, 0x14E5}, {0x2206, 0xEA15},
- {0x2206, 0xF727}, {0x2206, 0xE4EA}, {0x2206, 0x14E5}, {0x2206, 0xEA15},
- {0x2206, 0xFDFC}, {0x2206, 0x04F8}, {0x2206, 0xF9E0}, {0x2206, 0x8B87},
- {0x2206, 0xAD23}, {0x2206, 0x38AD}, {0x2206, 0x2135}, {0x2206, 0xE0E0},
- {0x2206, 0x20E1}, {0x2206, 0xE021}, {0x2206, 0xAC21}, {0x2206, 0x2CE0},
- {0x2206, 0xEA14}, {0x2206, 0xE1EA}, {0x2206, 0x15F6}, {0x2206, 0x27E4},
- {0x2206, 0xEA14}, {0x2206, 0xE5EA}, {0x2206, 0x15E2}, {0x2206, 0xEA12},
- {0x2206, 0xE3EA}, {0x2206, 0x135A}, {0x2206, 0x8FE6}, {0x2206, 0xEA12},
- {0x2206, 0xE7EA}, {0x2206, 0x13F7}, {0x2206, 0x26E4}, {0x2206, 0xEA14},
- {0x2206, 0xE5EA}, {0x2206, 0x15F7}, {0x2206, 0x27E4}, {0x2206, 0xEA14},
- {0x2206, 0xE5EA}, {0x2206, 0x15FD}, {0x2206, 0xFC04}, {0x2206, 0xF8FA},
- {0x2206, 0xEF69}, {0x2206, 0xE08B}, {0x2206, 0x86AD}, {0x2206, 0x2146},
- {0x2206, 0xE0E0}, {0x2206, 0x22E1}, {0x2206, 0xE023}, {0x2206, 0x58C0},
- {0x2206, 0x5902}, {0x2206, 0x1E01}, {0x2206, 0xE18B}, {0x2206, 0x651F},
- {0x2206, 0x109E}, {0x2206, 0x33E4}, {0x2206, 0x8B65}, {0x2206, 0xAD21},
- {0x2206, 0x22AD}, {0x2206, 0x272A}, {0x2206, 0xD400}, {0x2206, 0x01BF},
- {0x2206, 0x34F2}, {0x2206, 0x022C}, {0x2206, 0xA2BF}, {0x2206, 0x34F5},
- {0x2206, 0x022C}, {0x2206, 0xE0E0}, {0x2206, 0x8B67}, {0x2206, 0x1B10},
- {0x2206, 0xAA14}, {0x2206, 0xE18B}, {0x2206, 0x660D}, {0x2206, 0x1459},
- {0x2206, 0x0FAE}, {0x2206, 0x05E1}, {0x2206, 0x8B66}, {0x2206, 0x590F},
- {0x2206, 0xBF85}, {0x2206, 0x6102}, {0x2206, 0x2CA2}, {0x2206, 0xEF96},
- {0x2206, 0xFEFC}, {0x2206, 0x04F8}, {0x2206, 0xF9FA}, {0x2206, 0xFBEF},
- {0x2206, 0x79E2}, {0x2206, 0x8AD2}, {0x2206, 0xAC19}, {0x2206, 0x2DE0},
- {0x2206, 0xE036}, {0x2206, 0xE1E0}, {0x2206, 0x37EF}, {0x2206, 0x311F},
- {0x2206, 0x325B}, {0x2206, 0x019E}, {0x2206, 0x1F7A}, {0x2206, 0x0159},
- {0x2206, 0x019F}, {0x2206, 0x0ABF}, {0x2206, 0x348E}, {0x2206, 0x022C},
- {0x2206, 0x31F6}, {0x2206, 0x06AE}, {0x2206, 0x0FF6}, {0x2206, 0x0302},
- {0x2206, 0x0470}, {0x2206, 0xF703}, {0x2206, 0xF706}, {0x2206, 0xBF34},
- {0x2206, 0x9302}, {0x2206, 0x2C31}, {0x2206, 0xAC1A}, {0x2206, 0x25E0},
- {0x2206, 0xE022}, {0x2206, 0xE1E0}, {0x2206, 0x23EF}, {0x2206, 0x300D},
- {0x2206, 0x311F}, {0x2206, 0x325B}, {0x2206, 0x029E}, {0x2206, 0x157A},
- {0x2206, 0x0258}, {0x2206, 0xC4A0}, {0x2206, 0x0408}, {0x2206, 0xBF34},
- {0x2206, 0x9E02}, {0x2206, 0x2C31}, {0x2206, 0xAE06}, {0x2206, 0xBF34},
- {0x2206, 0x9C02}, {0x2206, 0x2C31}, {0x2206, 0xAC1B}, {0x2206, 0x4AE0},
- {0x2206, 0xE012}, {0x2206, 0xE1E0}, {0x2206, 0x13EF}, {0x2206, 0x300D},
- {0x2206, 0x331F}, {0x2206, 0x325B}, {0x2206, 0x1C9E}, {0x2206, 0x3AEF},
- {0x2206, 0x325B}, {0x2206, 0x1C9F}, {0x2206, 0x09BF}, {0x2206, 0x3498},
- {0x2206, 0x022C}, {0x2206, 0x3102}, {0x2206, 0x83C5}, {0x2206, 0x5A03},
- {0x2206, 0x0D03}, {0x2206, 0x581C}, {0x2206, 0x1E20}, {0x2206, 0x0207},
- {0x2206, 0xA0A0}, {0x2206, 0x000E}, {0x2206, 0x0284}, {0x2206, 0x17AD},
- {0x2206, 0x1817}, {0x2206, 0xBF34}, {0x2206, 0x9A02}, {0x2206, 0x2C31},
- {0x2206, 0xAE0F}, {0x2206, 0xBF34}, {0x2206, 0xC802}, {0x2206, 0x2C31},
- {0x2206, 0xBF34}, {0x2206, 0xC502}, {0x2206, 0x2C31}, {0x2206, 0x0284},
- {0x2206, 0x52E6}, {0x2206, 0x8AD2}, {0x2206, 0xEF97}, {0x2206, 0xFFFE},
- {0x2206, 0xFDFC}, {0x2206, 0x04F8}, {0x2206, 0xBF34}, {0x2206, 0xDA02},
- {0x2206, 0x2CE0}, {0x2206, 0xE58A}, {0x2206, 0xD3BF}, {0x2206, 0x34D4},
- {0x2206, 0x022C}, {0x2206, 0xE00C}, {0x2206, 0x1159}, {0x2206, 0x02E0},
- {0x2206, 0x8AD3}, {0x2206, 0x1E01}, {0x2206, 0xE48A}, {0x2206, 0xD3D1},
- {0x2206, 0x00BF}, {0x2206, 0x34DA}, {0x2206, 0x022C}, {0x2206, 0xA2D1},
- {0x2206, 0x01BF}, {0x2206, 0x34D4}, {0x2206, 0x022C}, {0x2206, 0xA2BF},
- {0x2206, 0x34CB}, {0x2206, 0x022C}, {0x2206, 0xE0E5}, {0x2206, 0x8ACE},
- {0x2206, 0xBF85}, {0x2206, 0x6702}, {0x2206, 0x2CE0}, {0x2206, 0xE58A},
- {0x2206, 0xCFBF}, {0x2206, 0x8564}, {0x2206, 0x022C}, {0x2206, 0xE0E5},
- {0x2206, 0x8AD0}, {0x2206, 0xBF85}, {0x2206, 0x6A02}, {0x2206, 0x2CE0},
- {0x2206, 0xE58A}, {0x2206, 0xD1FC}, {0x2206, 0x04F8}, {0x2206, 0xE18A},
- {0x2206, 0xD1BF}, {0x2206, 0x856A}, {0x2206, 0x022C}, {0x2206, 0xA2E1},
- {0x2206, 0x8AD0}, {0x2206, 0xBF85}, {0x2206, 0x6402}, {0x2206, 0x2CA2},
- {0x2206, 0xE18A}, {0x2206, 0xCFBF}, {0x2206, 0x8567}, {0x2206, 0x022C},
- {0x2206, 0xA2E1}, {0x2206, 0x8ACE}, {0x2206, 0xBF34}, {0x2206, 0xCB02},
- {0x2206, 0x2CA2}, {0x2206, 0xE18A}, {0x2206, 0xD3BF}, {0x2206, 0x34DA},
- {0x2206, 0x022C}, {0x2206, 0xA2E1}, {0x2206, 0x8AD3}, {0x2206, 0x0D11},
- {0x2206, 0xBF34}, {0x2206, 0xD402}, {0x2206, 0x2CA2}, {0x2206, 0xFC04},
- {0x2206, 0xF9A0}, {0x2206, 0x0405}, {0x2206, 0xE38A}, {0x2206, 0xD4AE},
- {0x2206, 0x13A0}, {0x2206, 0x0805}, {0x2206, 0xE38A}, {0x2206, 0xD5AE},
- {0x2206, 0x0BA0}, {0x2206, 0x0C05}, {0x2206, 0xE38A}, {0x2206, 0xD6AE},
- {0x2206, 0x03E3}, {0x2206, 0x8AD7}, {0x2206, 0xEF13}, {0x2206, 0xBF34},
- {0x2206, 0xCB02}, {0x2206, 0x2CA2}, {0x2206, 0xEF13}, {0x2206, 0x0D11},
- {0x2206, 0xBF85}, {0x2206, 0x6702}, {0x2206, 0x2CA2}, {0x2206, 0xEF13},
- {0x2206, 0x0D14}, {0x2206, 0xBF85}, {0x2206, 0x6402}, {0x2206, 0x2CA2},
- {0x2206, 0xEF13}, {0x2206, 0x0D17}, {0x2206, 0xBF85}, {0x2206, 0x6A02},
- {0x2206, 0x2CA2}, {0x2206, 0xFD04}, {0x2206, 0xF8E0}, {0x2206, 0x8B85},
- {0x2206, 0xAD27}, {0x2206, 0x2DE0}, {0x2206, 0xE036}, {0x2206, 0xE1E0},
- {0x2206, 0x37E1}, {0x2206, 0x8B73}, {0x2206, 0x1F10}, {0x2206, 0x9E20},
- {0x2206, 0xE48B}, {0x2206, 0x73AC}, {0x2206, 0x200B}, {0x2206, 0xAC21},
- {0x2206, 0x0DAC}, {0x2206, 0x250F}, {0x2206, 0xAC27}, {0x2206, 0x0EAE},
- {0x2206, 0x0F02}, {0x2206, 0x84CC}, {0x2206, 0xAE0A}, {0x2206, 0x0284},
- {0x2206, 0xD1AE}, {0x2206, 0x05AE}, {0x2206, 0x0302}, {0x2206, 0x84D8},
- {0x2206, 0xFC04}, {0x2206, 0xEE8B}, {0x2206, 0x6800}, {0x2206, 0x0402},
- {0x2206, 0x84E5}, {0x2206, 0x0285}, {0x2206, 0x2804}, {0x2206, 0x0285},
- {0x2206, 0x4904}, {0x2206, 0xEE8B}, {0x2206, 0x6800}, {0x2206, 0xEE8B},
- {0x2206, 0x6902}, {0x2206, 0x04F8}, {0x2206, 0xF9E0}, {0x2206, 0x8B85},
- {0x2206, 0xAD26}, {0x2206, 0x38D0}, {0x2206, 0x0B02}, {0x2206, 0x2B4D},
- {0x2206, 0x5882}, {0x2206, 0x7882}, {0x2206, 0x9F2D}, {0x2206, 0xE08B},
- {0x2206, 0x68E1}, {0x2206, 0x8B69}, {0x2206, 0x1F10}, {0x2206, 0x9EC8},
- {0x2206, 0x10E4}, {0x2206, 0x8B68}, {0x2206, 0xE0E0}, {0x2206, 0x00E1},
- {0x2206, 0xE001}, {0x2206, 0xF727}, {0x2206, 0xE4E0}, {0x2206, 0x00E5},
- {0x2206, 0xE001}, {0x2206, 0xE2E0}, {0x2206, 0x20E3}, {0x2206, 0xE021},
- {0x2206, 0xAD30}, {0x2206, 0xF7F6}, {0x2206, 0x27E4}, {0x2206, 0xE000},
- {0x2206, 0xE5E0}, {0x2206, 0x01FD}, {0x2206, 0xFC04}, {0x2206, 0xF8FA},
- {0x2206, 0xEF69}, {0x2206, 0xE08B}, {0x2206, 0x86AD}, {0x2206, 0x2212},
- {0x2206, 0xE0E0}, {0x2206, 0x14E1}, {0x2206, 0xE015}, {0x2206, 0xAD26},
- {0x2206, 0x9CE1}, {0x2206, 0x85E0}, {0x2206, 0xBF85}, {0x2206, 0x6D02},
- {0x2206, 0x2CA2}, {0x2206, 0xEF96}, {0x2206, 0xFEFC}, {0x2206, 0x04F8},
- {0x2206, 0xFAEF}, {0x2206, 0x69E0}, {0x2206, 0x8B86}, {0x2206, 0xAD22},
- {0x2206, 0x09E1}, {0x2206, 0x85E1}, {0x2206, 0xBF85}, {0x2206, 0x6D02},
- {0x2206, 0x2CA2}, {0x2206, 0xEF96}, {0x2206, 0xFEFC}, {0x2206, 0x0464},
- {0x2206, 0xE48C}, {0x2206, 0xFDE4}, {0x2206, 0x80CA}, {0x2206, 0xE480},
- {0x2206, 0x66E0}, {0x2206, 0x8E70}, {0x2206, 0xE076}, {0x2205, 0xE142},
- {0x2206, 0x0701}, {0x2205, 0xE140}, {0x2206, 0x0405}, {0x220F, 0x0000},
- {0x221F, 0x0000}, {0x2200, 0x1340}, {0x133E, 0x000E}, {0x133F, 0x0010},
- {0x13EB, 0x11BB}
-};
-
-static const struct rtl8367b_initval rtl8367r_vb_initvals_1[] = {
+static const struct rtl8367b_initval rtl8367b_initvals[] = {
{0x1B03, 0x0876}, {0x1200, 0x7FC4}, {0x1305, 0xC000}, {0x121E, 0x03CA},
{0x1233, 0x0352}, {0x1234, 0x0064}, {0x1237, 0x0096}, {0x1238, 0x0078},
{0x1239, 0x0084}, {0x123A, 0x0030}, {0x205F, 0x0002}, {0x2059, 0x1A00},
@@ -730,39 +550,28 @@ static int rtl8367b_write_phy_reg(struct rtl8366_smi *smi,
static int rtl8367b_init_regs(struct rtl8366_smi *smi)
{
const struct rtl8367b_initval *initvals;
- u32 chip_num;
- u32 chip_ver;
- u32 rlvid;
int count;
- int err;
- REG_WR(smi, RTL8367B_RTL_MAGIC_ID_REG, RTL8367B_RTL_MAGIC_ID_VAL);
- REG_RD(smi, RTL8367B_CHIP_NUMBER_REG, &chip_num);
- REG_RD(smi, RTL8367B_CHIP_VER_REG, &chip_ver);
-
- if ((chip_ver == 0x0020 || chip_ver == 0x00A0) && chip_num == 0x6367) {
+ switch (smi->rtl8367b_chip) {
+ case RTL8367B_CHIP_RTL8367RB:
+ case RTL8367B_CHIP_RTL8367R_VB:
+ initvals = rtl8367b_initvals;
+ count = ARRAY_SIZE(rtl8367b_initvals);
+ break;
+ case RTL8367B_CHIP_RTL8367RB_VB:
+ case RTL8367B_CHIP_RTL8367S:
+ case RTL8367B_CHIP_RTL8367S_VB:
initvals = rtl8367c_initvals;
count = ARRAY_SIZE(rtl8367c_initvals);
- } else {
- rlvid = (chip_ver >> RTL8367B_CHIP_VER_RLVID_SHIFT) &
- RTL8367B_CHIP_VER_RLVID_MASK;
- switch (rlvid) {
- case 0:
- initvals = rtl8367r_vb_initvals_0;
- count = ARRAY_SIZE(rtl8367r_vb_initvals_0);
- break;
- case 1:
- initvals = rtl8367r_vb_initvals_1;
- count = ARRAY_SIZE(rtl8367r_vb_initvals_1);
- break;
- default:
- dev_err(smi->parent, "unknow rlvid %u\n", rlvid);
- return -ENODEV;
+ if ((smi->rtl8367b_chip == RTL8367B_CHIP_RTL8367S_VB) && (smi->emu_vlanmc == NULL)) {
+ smi->emu_vlanmc = kzalloc(sizeof(struct rtl8366_vlan_mc) * smi->num_vlan_mc, GFP_KERNEL);
+ dev_info(smi->parent, "alloc vlan mc emulator");
}
+ break;
+ default:
+ return -ENODEV;
}
- /* TODO: disable RLTP */
-
return rtl8367b_write_initvals(smi, initvals, count);
}
@@ -795,6 +604,7 @@ static int rtl8367b_extif_set_mode(struct rtl8366_smi *smi, int id,
enum rtl8367_extif_mode mode)
{
int err;
+ u32 data;
/* set port mode */
switch (mode) {
@@ -814,6 +624,15 @@ static int rtl8367b_extif_set_mode(struct rtl8366_smi *smi, int id,
RTL8367B_DEBUG1_DP_MASK(id),
(7 << RTL8367B_DEBUG1_DN_SHIFT(id)) |
(7 << RTL8367B_DEBUG1_DP_SHIFT(id)));
+ if ((smi->rtl8367b_chip == RTL8367B_CHIP_RTL8367S_VB) && (id == 1)) {
+ REG_RMW(smi, RTL8367D_REG_EXT_TXC_DLY, RTL8367D_EXT1_RGMII_TX_DLY_MASK, 0);
+ /* Configure RGMII/MII mux to port 7 if UTP_PORT4 is not RGMII mode */
+ REG_RD(smi, RTL8367D_REG_TOP_CON0, &data);
+ data &= RTL8367D_MAC4_SEL_EXT1_MASK;
+ if (data == 0)
+ REG_RMW(smi, RTL8367D_REG_TOP_CON0, RTL8367D_MAC7_SEL_EXT1_MASK, RTL8367D_MAC7_SEL_EXT1_MASK);
+ REG_RMW(smi, RTL8367D_REG_SDS1_MISC0, RTL8367D_SDS1_MODE_MASK, RTL8367D_PORT_SDS_MODE_DISABLE);
+ }
} else {
REG_RMW(smi, RTL8367B_CHIP_DEBUG2_REG,
RTL8367B_DEBUG2_DRI_EXT2 |
@@ -872,23 +691,31 @@ static int rtl8367b_extif_set_force(struct rtl8366_smi *smi, int id,
u32 val;
int err;
- mask = (RTL8367B_DI_FORCE_MODE |
- RTL8367B_DI_FORCE_NWAY |
- RTL8367B_DI_FORCE_TXPAUSE |
- RTL8367B_DI_FORCE_RXPAUSE |
- RTL8367B_DI_FORCE_LINK |
- RTL8367B_DI_FORCE_DUPLEX |
- RTL8367B_DI_FORCE_SPEED_MASK);
-
- val = pa->speed;
- val |= pa->force_mode ? RTL8367B_DI_FORCE_MODE : 0;
+ val = pa->speed & RTL8367B_DI_FORCE_SPEED_MASK;
val |= pa->nway ? RTL8367B_DI_FORCE_NWAY : 0;
val |= pa->txpause ? RTL8367B_DI_FORCE_TXPAUSE : 0;
val |= pa->rxpause ? RTL8367B_DI_FORCE_RXPAUSE : 0;
val |= pa->link ? RTL8367B_DI_FORCE_LINK : 0;
val |= pa->duplex ? RTL8367B_DI_FORCE_DUPLEX : 0;
- REG_RMW(smi, RTL8367B_DI_FORCE_REG(id), mask, val);
+ if (smi->rtl8367b_chip >= RTL8367B_CHIP_RTL8367S_VB) { /* Family D */
+ val |= (pa->speed << RTL8367D_PORT_STATUS_SPEED1_SHIFT) & RTL8367D_PORT_STATUS_SPEED1_MASK;
+ if (smi->cpu_port != UINT_MAX) {
+ REG_WR(smi, RTL8367D_REG_MAC0_FORCE_SELECT + smi->cpu_port, val);
+ REG_WR(smi, RTL8367D_REG_MAC0_FORCE_SELECT_EN + smi->cpu_port, pa->force_mode ? 0xffff : 0x0000);
+ }
+ } else {
+ val |= pa->force_mode ? RTL8367B_DI_FORCE_MODE : 0;
+ mask = (RTL8367B_DI_FORCE_MODE |
+ RTL8367B_DI_FORCE_NWAY |
+ RTL8367B_DI_FORCE_TXPAUSE |
+ RTL8367B_DI_FORCE_RXPAUSE |
+ RTL8367B_DI_FORCE_LINK |
+ RTL8367B_DI_FORCE_DUPLEX |
+ RTL8367B_DI_FORCE_SPEED_MASK);
+
+ REG_RMW(smi, RTL8367B_DI_FORCE_REG(id), mask, val);
+ }
return 0;
}
@@ -939,21 +766,56 @@ static int rtl8367b_extif_init(struct rtl8366_smi *smi, int id,
}
#ifdef CONFIG_OF
-static int rtl8367b_extif_init_of(struct rtl8366_smi *smi, int id,
+static int rtl8367b_extif_init_of(struct rtl8366_smi *smi,
const char *name)
{
struct rtl8367_extif_config *cfg;
const __be32 *prop;
int size;
int err;
+ unsigned cpu_port;
+ unsigned id = UINT_MAX;
prop = of_get_property(smi->parent->of_node, name, &size);
- if (!prop)
- return rtl8367b_extif_init(smi, id, NULL);
+ if (!prop || (size != (10 * sizeof(*prop)))) {
+ dev_err(smi->parent, "%s property is not defined or invalid\n", name);
+ err = -EINVAL;
+ goto err_init;
+ }
- if (size != (9 * sizeof(*prop))) {
- dev_err(smi->parent, "%s property is invalid\n", name);
- return -EINVAL;
+ cpu_port = be32_to_cpup(prop++);
+ switch (cpu_port) {
+ case RTL8367B_CPU_PORT_NUM:
+ case RTL8367B_CPU_PORT_NUM + 1:
+ case RTL8367B_CPU_PORT_NUM + 2:
+ if (smi->rtl8367b_chip == RTL8367B_CHIP_RTL8367R_VB) { /* for the RTL8367R-VB chip, cpu_port 5 corresponds to extif1 */
+ if (cpu_port == RTL8367B_CPU_PORT_NUM)
+ id = 1;
+ else {
+ dev_err(smi->parent, "wrong cpu_port %u in %s property\n", cpu_port, name);
+ err = -EINVAL;
+ goto err_init;
+ }
+ } else if (smi->rtl8367b_chip == RTL8367B_CHIP_RTL8367S_VB) { /* for the RTL8367S-VB chip, cpu_port 7 corresponds to extif1, cpu_port 6 corresponds to extif0 */
+ if (cpu_port != RTL8367B_CPU_PORT_NUM) {
+ id = cpu_port - RTL8367B_CPU_PORT_NUM - 1;
+ } else {
+ dev_err(smi->parent, "wrong cpu_port %u in %s property\n", cpu_port, name);
+ err = -EINVAL;
+ goto err_init;
+ }
+ } else {
+ id = cpu_port - RTL8367B_CPU_PORT_NUM;
+ }
+ if (smi->cpu_port == UINT_MAX) {
+ dev_info(smi->parent, "cpu_port:%u, assigned to extif%u\n", cpu_port, id);
+ smi->cpu_port = cpu_port;
+ }
+ break;
+ default:
+ dev_err(smi->parent, "wrong cpu_port %u in %s property\n", cpu_port, name);
+ err = -EINVAL;
+ goto err_init;
}
cfg = kzalloc(sizeof(struct rtl8367_extif_config), GFP_KERNEL);
@@ -973,10 +835,15 @@ static int rtl8367b_extif_init_of(struct rtl8366_smi *smi, int id,
err = rtl8367b_extif_init(smi, id, cfg);
kfree(cfg);
+err_init:
+ if (id != 0) rtl8367b_extif_init(smi, 0, NULL);
+ if (id != 1) rtl8367b_extif_init(smi, 1, NULL);
+ if (id != 2) rtl8367b_extif_init(smi, 2, NULL);
+
return err;
}
#else
-static int rtl8367b_extif_init_of(struct rtl8366_smi *smi, int id,
+static int rtl8367b_extif_init_of(struct rtl8366_smi *smi,
const char *name)
{
return -EINVAL;
@@ -997,15 +864,7 @@ static int rtl8367b_setup(struct rtl8366_smi *smi)
/* initialize external interfaces */
if (smi->parent->of_node) {
- err = rtl8367b_extif_init_of(smi, 0, "realtek,extif0");
- if (err)
- return err;
-
- err = rtl8367b_extif_init_of(smi, 1, "realtek,extif1");
- if (err)
- return err;
-
- err = rtl8367b_extif_init_of(smi, 2, "realtek,extif2");
+ err = rtl8367b_extif_init_of(smi, "realtek,extif");
if (err)
return err;
} else {
@@ -1115,8 +974,12 @@ static int rtl8367b_get_vlan_4k(struct rtl8366_smi *smi, u32 vid,
RTL8367B_TA_VLAN0_MEMBER_MASK;
vlan4k->untag = (data[0] >> RTL8367B_TA_VLAN0_UNTAG_SHIFT) &
RTL8367B_TA_VLAN0_UNTAG_MASK;
- vlan4k->fid = (data[1] >> RTL8367B_TA_VLAN1_FID_SHIFT) &
- RTL8367B_TA_VLAN1_FID_MASK;
+ if (smi->rtl8367b_chip >= RTL8367B_CHIP_RTL8367S_VB) /* Family D */
+ vlan4k->fid = (data[1] >> RTL8367D_TA_VLAN1_FID_SHIFT) &
+ RTL8367D_TA_VLAN1_FID_MASK;
+ else
+ vlan4k->fid = (data[1] >> RTL8367B_TA_VLAN1_FID_SHIFT) &
+ RTL8367B_TA_VLAN1_FID_MASK;
return 0;
}
@@ -1131,7 +994,7 @@ static int rtl8367b_set_vlan_4k(struct rtl8366_smi *smi,
if (vlan4k->vid >= RTL8367B_NUM_VIDS ||
vlan4k->member > RTL8367B_TA_VLAN0_MEMBER_MASK ||
vlan4k->untag > RTL8367B_UNTAG_MASK ||
- vlan4k->fid > RTL8367B_FIDMAX)
+ vlan4k->fid > ((smi->rtl8367b_chip >= RTL8367B_CHIP_RTL8367S_VB) ? RTL8367D_FIDMAX : RTL8367B_FIDMAX))
return -EINVAL;
memset(data, 0, sizeof(data));
@@ -1140,15 +1003,24 @@ static int rtl8367b_set_vlan_4k(struct rtl8366_smi *smi,
RTL8367B_TA_VLAN0_MEMBER_SHIFT;
data[0] |= (vlan4k->untag & RTL8367B_TA_VLAN0_UNTAG_MASK) <<
RTL8367B_TA_VLAN0_UNTAG_SHIFT;
- data[1] = (vlan4k->fid & RTL8367B_TA_VLAN1_FID_MASK) <<
- RTL8367B_TA_VLAN1_FID_SHIFT;
+
+ if (smi->rtl8367b_chip >= RTL8367B_CHIP_RTL8367S_VB) /* Family D */
+ data[1] = ((vlan4k->fid & RTL8367D_TA_VLAN1_FID_MASK) <<
+ RTL8367D_TA_VLAN1_FID_SHIFT) | 12; /* ivl_svl - BIT(3), svlan_chek_ivl_svl - BIT(2) */
+ else
+ data[1] = (vlan4k->fid & RTL8367B_TA_VLAN1_FID_MASK) <<
+ RTL8367B_TA_VLAN1_FID_SHIFT;
for (i = 0; i < ARRAY_SIZE(data); i++)
REG_WR(smi, RTL8367B_TA_WRDATA_REG(i), data[i]);
/* write VID */
- REG_WR(smi, RTL8367B_TA_ADDR_REG,
- vlan4k->vid & RTL8367B_TA_VLAN_VID_MASK);
+ if (smi->rtl8367b_chip >= RTL8367B_CHIP_RTL8367S_VB) /* Family D */
+ REG_WR(smi, RTL8367B_TA_ADDR_REG,
+ vlan4k->vid & RTL8367D_TA_VLAN_VID_MASK);
+ else
+ REG_WR(smi, RTL8367B_TA_ADDR_REG,
+ vlan4k->vid & RTL8367B_TA_VLAN_VID_MASK);
/* write table access control word */
REG_WR(smi, RTL8367B_TA_CTRL_REG, RTL8367B_TA_CTRL_CVLAN_WRITE);
@@ -1168,6 +1040,14 @@ static int rtl8367b_get_vlan_mc(struct rtl8366_smi *smi, u32 index,
if (index >= RTL8367B_NUM_VLANS)
return -EINVAL;
+ if (smi->emu_vlanmc) { /* use vlan mc emulation */
+ vlanmc->vid = smi->emu_vlanmc[index].vid;
+ vlanmc->member = smi->emu_vlanmc[index].member;
+ vlanmc->fid = smi->emu_vlanmc[index].fid;
+ vlanmc->untag = smi->emu_vlanmc[index].untag;
+ return 0;
+ }
+
for (i = 0; i < ARRAY_SIZE(data); i++)
REG_RD(smi, RTL8367B_VLAN_MC_BASE(index) + i, &data[i]);
@@ -1193,9 +1073,17 @@ static int rtl8367b_set_vlan_mc(struct rtl8366_smi *smi, u32 index,
vlanmc->priority > RTL8367B_PRIORITYMAX ||
vlanmc->member > RTL8367B_VLAN_MC0_MEMBER_MASK ||
vlanmc->untag > RTL8367B_UNTAG_MASK ||
- vlanmc->fid > RTL8367B_FIDMAX)
+ vlanmc->fid > ((smi->rtl8367b_chip >= RTL8367B_CHIP_RTL8367S_VB) ? RTL8367D_FIDMAX : RTL8367B_FIDMAX))
return -EINVAL;
+ if (smi->emu_vlanmc) { /* use vlanmc emulation */
+ smi->emu_vlanmc[index].vid = vlanmc->vid;
+ smi->emu_vlanmc[index].member = vlanmc->member;
+ smi->emu_vlanmc[index].fid = vlanmc->fid;
+ smi->emu_vlanmc[index].untag = vlanmc->untag;
+ return 0;
+ }
+
data[0] = (vlanmc->member & RTL8367B_VLAN_MC0_MEMBER_MASK) <<
RTL8367B_VLAN_MC0_MEMBER_SHIFT;
data[1] = (vlanmc->fid & RTL8367B_VLAN_MC1_FID_MASK) <<
@@ -1218,10 +1106,41 @@ static int rtl8367b_get_mc_index(struct rtl8366_smi *smi, int port, int *val)
if (port >= RTL8367B_NUM_PORTS)
return -EINVAL;
- REG_RD(smi, RTL8367B_VLAN_PVID_CTRL_REG(port), &data);
+ if (smi->rtl8367b_chip >= RTL8367B_CHIP_RTL8367S_VB) { /* Family D */
+ int i;
+ struct rtl8366_vlan_mc vlanmc;
- *val = (data >> RTL8367B_VLAN_PVID_CTRL_SHIFT(port)) &
- RTL8367B_VLAN_PVID_CTRL_MASK;
+ err = rtl8366_smi_read_reg(smi, RTL8367D_VLAN_PVID_CTRL_REG(port), &data);
+
+ if (err) {
+ dev_err(smi->parent, "read pvid register 0x%04x fail", RTL8367D_VLAN_PVID_CTRL_REG(port));
+ return err;
+ }
+
+ data &= RTL8367D_VLAN_PVID_CTRL_MASK;
+ for (i = 0; i < smi->num_vlan_mc; i++) {
+ err = rtl8367b_get_vlan_mc(smi, i, &vlanmc);
+
+ if (err) {
+ dev_err(smi->parent, "get vlan mc index %d fail", i);
+ return err;
+ }
+
+ if (data == vlanmc.vid) break;
+ }
+
+ if (i < smi->num_vlan_mc) {
+ *val = i;
+ } else {
+ dev_err(smi->parent, "vlan mc index for pvid %d not found", data);
+ return -EINVAL;
+ }
+ } else {
+ REG_RD(smi, RTL8367B_VLAN_PVID_CTRL_REG(port), &data);
+
+ *val = (data >> RTL8367B_VLAN_PVID_CTRL_SHIFT(port)) &
+ RTL8367B_VLAN_PVID_CTRL_MASK;
+ }
return 0;
}
@@ -1231,7 +1150,28 @@ static int rtl8367b_set_mc_index(struct rtl8366_smi *smi, int port, int index)
if (port >= RTL8367B_NUM_PORTS || index >= RTL8367B_NUM_VLANS)
return -EINVAL;
- return rtl8366_smi_rmwr(smi, RTL8367B_VLAN_PVID_CTRL_REG(port),
+ if (smi->rtl8367b_chip >= RTL8367B_CHIP_RTL8367S_VB) { /* Family D */
+ int pvid, err;
+ struct rtl8366_vlan_mc vlanmc;
+
+ err = rtl8367b_get_vlan_mc(smi, index, &vlanmc);
+
+ if (err) {
+ dev_err(smi->parent, "get vlan mc index %d fail", index);
+ return err;
+ }
+
+ pvid = vlanmc.vid & RTL8367D_VLAN_PVID_CTRL_MASK;
+ err = rtl8366_smi_write_reg(smi, RTL8367D_VLAN_PVID_CTRL_REG(port), pvid);
+
+ if (err) {
+ dev_err(smi->parent, "set port %d pvid %d fail", port, pvid);
+ return err;
+ }
+
+ return 0;
+ } else
+ return rtl8366_smi_rmwr(smi, RTL8367B_VLAN_PVID_CTRL_REG(port),
RTL8367B_VLAN_PVID_CTRL_MASK <<
RTL8367B_VLAN_PVID_CTRL_SHIFT(port),
(index & RTL8367B_VLAN_PVID_CTRL_MASK) <<
@@ -1294,7 +1234,10 @@ static int rtl8367b_sw_get_port_link(struct switch_dev *dev,
if (port >= RTL8367B_NUM_PORTS)
return -EINVAL;
- rtl8366_smi_read_reg(smi, RTL8367B_PORT_STATUS_REG(port), &data);
+ if (smi->rtl8367b_chip >= RTL8367B_CHIP_RTL8367S_VB) /* Family D */
+ rtl8366_smi_read_reg(smi, RTL8367D_PORT_STATUS_REG(port), &data);
+ else
+ rtl8366_smi_read_reg(smi, RTL8367B_PORT_STATUS_REG(port), &data);
link->link = !!(data & RTL8367B_PORT_STATUS_LINK);
if (!link->link)
@@ -1305,15 +1248,18 @@ static int rtl8367b_sw_get_port_link(struct switch_dev *dev,
link->tx_flow = !!(data & RTL8367B_PORT_STATUS_TXPAUSE);
link->aneg = !!(data & RTL8367B_PORT_STATUS_NWAY);
- speed = (data & RTL8367B_PORT_STATUS_SPEED_MASK);
+ if (smi->rtl8367b_chip >= RTL8367B_CHIP_RTL8367S_VB) /* Family D */
+ speed = (data & RTL8367B_PORT_STATUS_SPEED_MASK) | ((data & RTL8367D_PORT_STATUS_SPEED1_MASK) >> RTL8367D_PORT_STATUS_SPEED1_SHIFT);
+ else
+ speed = (data & RTL8367B_PORT_STATUS_SPEED_MASK);
switch (speed) {
- case 0:
+ case RTL8367B_PORT_STATUS_SPEED_10:
link->speed = SWITCH_PORT_SPEED_10;
break;
- case 1:
+ case RTL8367B_PORT_STATUS_SPEED_100:
link->speed = SWITCH_PORT_SPEED_100;
break;
- case 2:
+ case RTL8367B_PORT_STATUS_SPEED_1000:
link->speed = SWITCH_PORT_SPEED_1000;
break;
default:
@@ -1530,10 +1476,11 @@ static int rtl8367b_detect(struct rtl8366_smi *smi)
const char *chip_name = NULL;
u32 chip_num;
u32 chip_ver;
- u32 chip_mode;
int ret;
- /* TODO: improve chip detection */
+ smi->emu_vlanmc = NULL;
+ smi->rtl8367b_chip = RTL8367B_CHIP_UNKNOWN;
+
rtl8366_smi_write_reg(smi, RTL8367B_RTL_MAGIC_ID_REG,
RTL8367B_RTL_MAGIC_ID_VAL);
@@ -1551,44 +1498,42 @@ static int rtl8367b_detect(struct rtl8366_smi *smi)
return ret;
}
- ret = rtl8366_smi_read_reg(smi, RTL8367B_CHIP_MODE_REG, &chip_mode);
- if (ret) {
- dev_err(smi->parent, "unable to read %s register\n",
- "chip mode");
- return ret;
- }
-
switch (chip_ver) {
+ case 0x0010:
+ if (chip_num == 0x6642) {
+ chip_name = "8367S-VB";
+ smi->rtl8367b_chip = RTL8367B_CHIP_RTL8367S_VB;
+ }
+ break;
case 0x0020:
- if (chip_num == 0x6367)
+ if (chip_num == 0x6367) {
chip_name = "8367RB-VB";
+ smi->rtl8367b_chip = RTL8367B_CHIP_RTL8367RB_VB;
+ }
break;
case 0x00A0:
- if (chip_num == 0x6367)
+ if (chip_num == 0x6367) {
chip_name = "8367S";
+ smi->rtl8367b_chip = RTL8367B_CHIP_RTL8367S;
+ }
break;
case 0x1000:
chip_name = "8367RB";
+ smi->rtl8367b_chip = RTL8367B_CHIP_RTL8367RB;
break;
case 0x1010:
chip_name = "8367R-VB";
+ smi->rtl8367b_chip = RTL8367B_CHIP_RTL8367R_VB;
}
if (!chip_name) {
dev_err(smi->parent,
- "unknown chip num:%04x ver:%04x, mode:%04x\n",
- chip_num, chip_ver, chip_mode);
+ "unknown chip (num:%04x ver:%04x)\n",
+ chip_num, chip_ver);
return -ENODEV;
}
- dev_info(smi->parent, "RTL%s chip found\n", chip_name);
-
- if (of_property_present(smi->parent->of_node, "realtek,extif2"))
- smi->cpu_port = RTL8367B_CPU_PORT_NUM + 2;
- else if (of_property_present(smi->parent->of_node, "realtek,extif1") && (chip_ver != 0x1010)) /* for the RTL8367R-VB chip, extif1 corresponds to cpu_port 5 */
- smi->cpu_port = RTL8367B_CPU_PORT_NUM + 1;
-
- dev_info(smi->parent, "CPU port: %u\n", smi->cpu_port);
+ dev_info(smi->parent, "RTL%s chip found (num:%04x ver:%04x)\n", chip_name, chip_num, chip_ver);
return 0;
}
@@ -1628,7 +1573,7 @@ static int rtl8367b_probe(struct platform_device *pdev)
smi->cmd_write = 0xb8;
smi->ops = &rtl8367b_smi_ops;
smi->num_ports = RTL8367B_NUM_PORTS;
- smi->cpu_port = RTL8367B_CPU_PORT_NUM;
+ smi->cpu_port = UINT_MAX; /* not defined yet */
smi->num_vlan_mc = RTL8367B_NUM_VLANS;
smi->mib_counters = rtl8367b_mib_counters;
smi->num_mib_counters = ARRAY_SIZE(rtl8367b_mib_counters);
@@ -1649,6 +1594,8 @@ static int rtl8367b_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, NULL);
rtl8366_smi_cleanup(smi);
err_free_smi:
+ if (smi->emu_vlanmc)
+ kfree(smi->emu_vlanmc);
kfree(smi);
return err;
}
diff --git a/target/linux/generic/hack-5.15/911-kobject_add_broadcast_uevent.patch b/target/linux/generic/hack-5.15/911-kobject_add_broadcast_uevent.patch
index a487d55193..dd93e0be42 100644
--- a/target/linux/generic/hack-5.15/911-kobject_add_broadcast_uevent.patch
+++ b/target/linux/generic/hack-5.15/911-kobject_add_broadcast_uevent.patch
@@ -1,7 +1,7 @@
From 0d37e6edc09c99e683dd91ca0e83bbc0df8477b3 Mon Sep 17 00:00:00 2001
From: Felix Fietkau <nbd@nbd.name>
Date: Sun, 16 Jul 2017 16:56:10 +0200
-Subject: lib: add uevent_next_seqnum()
+Subject: lib: add broadcast_uevent()
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
diff --git a/target/linux/generic/hack-6.1/230-openwrt_lzma_options.patch b/target/linux/generic/hack-6.1/230-openwrt_lzma_options.patch
index 55530c5c7e..ddf7f5e0c0 100644
--- a/target/linux/generic/hack-6.1/230-openwrt_lzma_options.patch
+++ b/target/linux/generic/hack-6.1/230-openwrt_lzma_options.patch
@@ -23,7 +23,7 @@ Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
{ {0x02, 0x21}, "lz4", unlz4 },
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
-@@ -443,10 +443,10 @@ quiet_cmd_bzip2_with_size = BZIP2 $@
+@@ -447,10 +447,10 @@ quiet_cmd_bzip2_with_size = BZIP2 $@
# ---------------------------------------------------------------------------
quiet_cmd_lzma = LZMA $@
diff --git a/target/linux/generic/hack-6.1/253-ksmbd-config.patch b/target/linux/generic/hack-6.1/253-ksmbd-config.patch
index a57c914180..c968daf081 100644
--- a/target/linux/generic/hack-6.1/253-ksmbd-config.patch
+++ b/target/linux/generic/hack-6.1/253-ksmbd-config.patch
@@ -10,7 +10,7 @@ Subject: [PATCH] Kconfig: add tristate for OID and ASNI string
--- a/init/Kconfig
+++ b/init/Kconfig
-@@ -2013,7 +2013,7 @@ config PADATA
+@@ -2017,7 +2017,7 @@ config PADATA
bool
config ASN1
diff --git a/target/linux/generic/hack-6.1/780-usb-net-MeigLink_modem_support.patch b/target/linux/generic/hack-6.1/780-usb-net-MeigLink_modem_support.patch
index 2729a0ec38..6e318a6e9a 100644
--- a/target/linux/generic/hack-6.1/780-usb-net-MeigLink_modem_support.patch
+++ b/target/linux/generic/hack-6.1/780-usb-net-MeigLink_modem_support.patch
@@ -10,7 +10,7 @@ Subject: [PATCH] net/usb/qmi_wwan: add MeigLink modem support
--- a/drivers/net/usb/qmi_wwan.c
+++ b/drivers/net/usb/qmi_wwan.c
-@@ -1082,12 +1082,18 @@ static const struct usb_device_id produc
+@@ -1083,12 +1083,18 @@ static const struct usb_device_id produc
USB_DEVICE_AND_INTERFACE_INFO(0x03f0, 0x581d, USB_CLASS_VENDOR_SPEC, 1, 7),
.driver_info = (unsigned long)&qmi_wwan_info,
},
@@ -43,7 +43,7 @@ Subject: [PATCH] net/usb/qmi_wwan: add MeigLink modem support
#define QUECTEL_VENDOR_ID 0x2c7c
/* These Quectel products use Quectel's vendor ID */
-@@ -1156,6 +1161,11 @@ static const struct usb_device_id option
+@@ -1158,6 +1163,11 @@ static const struct usb_device_id option
{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x0023)}, /* ONYX 3G device */
{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9000), /* SIMCom SIM5218 */
.driver_info = NCTRL(0) | NCTRL(1) | NCTRL(2) | NCTRL(3) | RSVD(4) },
@@ -55,7 +55,7 @@ Subject: [PATCH] net/usb/qmi_wwan: add MeigLink modem support
/* Quectel products using Qualcomm vendor ID */
{ USB_DEVICE(QUALCOMM_VENDOR_ID, QUECTEL_PRODUCT_UC15)},
{ USB_DEVICE(QUALCOMM_VENDOR_ID, QUECTEL_PRODUCT_UC20),
-@@ -1197,6 +1207,11 @@ static const struct usb_device_id option
+@@ -1199,6 +1209,11 @@ static const struct usb_device_id option
.driver_info = ZLP },
{ USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_BG96),
.driver_info = RSVD(4) },
diff --git a/target/linux/generic/hack-6.1/902-debloat_proc.patch b/target/linux/generic/hack-6.1/902-debloat_proc.patch
index ee3caa9f47..2bc86fa1e2 100644
--- a/target/linux/generic/hack-6.1/902-debloat_proc.patch
+++ b/target/linux/generic/hack-6.1/902-debloat_proc.patch
@@ -29,7 +29,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/fs/locks.c
+++ b/fs/locks.c
-@@ -2909,6 +2909,8 @@ static const struct seq_operations locks
+@@ -2907,6 +2907,8 @@ static const struct seq_operations locks
static int __init proc_locks_init(void)
{
@@ -235,7 +235,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
if (!pe)
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
-@@ -4222,6 +4222,8 @@ static const struct seq_operations vmall
+@@ -4215,6 +4215,8 @@ static const struct seq_operations vmall
static int __init proc_vmalloc_init(void)
{
@@ -341,7 +341,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
-@@ -3036,11 +3036,13 @@ static const struct seq_operations fib_r
+@@ -3037,11 +3037,13 @@ static const struct seq_operations fib_r
int __net_init fib_proc_init(struct net *net)
{
@@ -357,7 +357,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
fib_triestat_seq_show, NULL))
goto out2;
-@@ -3051,17 +3053,21 @@ int __net_init fib_proc_init(struct net
+@@ -3052,17 +3054,21 @@ int __net_init fib_proc_init(struct net
return 0;
out3:
diff --git a/target/linux/generic/hack-6.1/904-debloat_dma_buf.patch b/target/linux/generic/hack-6.1/904-debloat_dma_buf.patch
index 105eb3da4b..8b6bd6a786 100644
--- a/target/linux/generic/hack-6.1/904-debloat_dma_buf.patch
+++ b/target/linux/generic/hack-6.1/904-debloat_dma_buf.patch
@@ -73,7 +73,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
+MODULE_LICENSE("GPL");
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
-@@ -4367,6 +4367,7 @@ int wake_up_state(struct task_struct *p,
+@@ -4363,6 +4363,7 @@ int wake_up_state(struct task_struct *p,
{
return try_to_wake_up(p, state, 0);
}
diff --git a/target/linux/generic/hack-6.1/911-kobject_add_broadcast_uevent.patch b/target/linux/generic/hack-6.1/911-kobject_add_broadcast_uevent.patch
index 9854585d25..99e95ce352 100644
--- a/target/linux/generic/hack-6.1/911-kobject_add_broadcast_uevent.patch
+++ b/target/linux/generic/hack-6.1/911-kobject_add_broadcast_uevent.patch
@@ -1,7 +1,7 @@
From 0d37e6edc09c99e683dd91ca0e83bbc0df8477b3 Mon Sep 17 00:00:00 2001
From: Felix Fietkau <nbd@nbd.name>
Date: Sun, 16 Jul 2017 16:56:10 +0200
-Subject: lib: add uevent_next_seqnum()
+Subject: lib: add broadcast_uevent()
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
@@ -30,7 +30,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
#endif /* _KOBJECT_H_ */
--- a/lib/kobject_uevent.c
+++ b/lib/kobject_uevent.c
-@@ -691,6 +691,43 @@ int add_uevent_var(struct kobj_uevent_en
+@@ -706,6 +706,43 @@ int add_uevent_var(struct kobj_uevent_en
EXPORT_SYMBOL_GPL(add_uevent_var);
#if defined(CONFIG_NET)
diff --git a/target/linux/generic/hack-6.1/930-Revert-Revert-Revert-driver-core-Set-fw_devlink-on-b.patch b/target/linux/generic/hack-6.1/930-Revert-Revert-Revert-driver-core-Set-fw_devlink-on-b.patch
index f2ae028aa1..3476aa6edb 100644
--- a/target/linux/generic/hack-6.1/930-Revert-Revert-Revert-driver-core-Set-fw_devlink-on-b.patch
+++ b/target/linux/generic/hack-6.1/930-Revert-Revert-Revert-driver-core-Set-fw_devlink-on-b.patch
@@ -19,7 +19,7 @@ Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
-@@ -1717,7 +1717,7 @@ static void device_links_purge(struct de
+@@ -1718,7 +1718,7 @@ static void device_links_purge(struct de
#define FW_DEVLINK_FLAGS_RPM (FW_DEVLINK_FLAGS_ON | \
DL_FLAG_PM_RUNTIME)
diff --git a/target/linux/generic/hack-6.6/230-openwrt_lzma_options.patch b/target/linux/generic/hack-6.6/230-openwrt_lzma_options.patch
index a22acafea1..ca70da7e31 100644
--- a/target/linux/generic/hack-6.6/230-openwrt_lzma_options.patch
+++ b/target/linux/generic/hack-6.6/230-openwrt_lzma_options.patch
@@ -23,7 +23,7 @@ Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
{ {0x02, 0x21}, "lz4", unlz4 },
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
-@@ -456,10 +456,10 @@ quiet_cmd_bzip2_with_size = BZIP2 $@
+@@ -460,10 +460,10 @@ quiet_cmd_bzip2_with_size = BZIP2 $@
# ---------------------------------------------------------------------------
quiet_cmd_lzma = LZMA $@
diff --git a/target/linux/generic/hack-6.6/253-ksmbd-config.patch b/target/linux/generic/hack-6.6/253-ksmbd-config.patch
index 298a0787b7..9079c66d42 100644
--- a/target/linux/generic/hack-6.6/253-ksmbd-config.patch
+++ b/target/linux/generic/hack-6.6/253-ksmbd-config.patch
@@ -10,7 +10,7 @@ Subject: [PATCH] Kconfig: add tristate for OID and ASNI string
--- a/init/Kconfig
+++ b/init/Kconfig
-@@ -1989,7 +1989,7 @@ config PADATA
+@@ -1993,7 +1993,7 @@ config PADATA
bool
config ASN1
@@ -21,7 +21,7 @@ Subject: [PATCH] Kconfig: add tristate for OID and ASNI string
that can be interpreted by the ASN.1 stream decoder and used to
--- a/lib/Kconfig
+++ b/lib/Kconfig
-@@ -647,7 +647,7 @@ config LIBFDT
+@@ -641,7 +641,7 @@ config LIBFDT
bool
config OID_REGISTRY
diff --git a/target/linux/generic/hack-6.6/600-net-enable-fraglist-GRO-by-default.patch b/target/linux/generic/hack-6.6/600-net-enable-fraglist-GRO-by-default.patch
index 51f990039c..9633525bc4 100644
--- a/target/linux/generic/hack-6.6/600-net-enable-fraglist-GRO-by-default.patch
+++ b/target/linux/generic/hack-6.6/600-net-enable-fraglist-GRO-by-default.patch
@@ -9,7 +9,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/include/linux/netdev_features.h
+++ b/include/linux/netdev_features.h
-@@ -242,10 +242,10 @@ static inline int find_next_netdev_featu
+@@ -243,10 +243,10 @@ static inline int find_next_netdev_featu
#define NETIF_F_UPPER_DISABLES NETIF_F_LRO
/* changeable features with no special hardware requirements */
diff --git a/target/linux/generic/hack-6.6/780-usb-net-MeigLink_modem_support.patch b/target/linux/generic/hack-6.6/780-usb-net-MeigLink_modem_support.patch
index d010231e49..73a27ef6e2 100644
--- a/target/linux/generic/hack-6.6/780-usb-net-MeigLink_modem_support.patch
+++ b/target/linux/generic/hack-6.6/780-usb-net-MeigLink_modem_support.patch
@@ -10,7 +10,7 @@ Subject: [PATCH] net/usb/qmi_wwan: add MeigLink modem support
--- a/drivers/net/usb/qmi_wwan.c
+++ b/drivers/net/usb/qmi_wwan.c
-@@ -1083,12 +1083,18 @@ static const struct usb_device_id produc
+@@ -1084,12 +1084,18 @@ static const struct usb_device_id produc
USB_DEVICE_AND_INTERFACE_INFO(0x03f0, 0x581d, USB_CLASS_VENDOR_SPEC, 1, 7),
.driver_info = (unsigned long)&qmi_wwan_info,
},
@@ -43,7 +43,7 @@ Subject: [PATCH] net/usb/qmi_wwan: add MeigLink modem support
#define QUECTEL_VENDOR_ID 0x2c7c
/* These Quectel products use Quectel's vendor ID */
-@@ -1156,6 +1161,11 @@ static const struct usb_device_id option
+@@ -1158,6 +1163,11 @@ static const struct usb_device_id option
{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x0023)}, /* ONYX 3G device */
{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9000), /* SIMCom SIM5218 */
.driver_info = NCTRL(0) | NCTRL(1) | NCTRL(2) | NCTRL(3) | RSVD(4) },
@@ -55,7 +55,7 @@ Subject: [PATCH] net/usb/qmi_wwan: add MeigLink modem support
/* Quectel products using Qualcomm vendor ID */
{ USB_DEVICE(QUALCOMM_VENDOR_ID, QUECTEL_PRODUCT_UC15)},
{ USB_DEVICE(QUALCOMM_VENDOR_ID, QUECTEL_PRODUCT_UC20),
-@@ -1197,6 +1207,11 @@ static const struct usb_device_id option
+@@ -1199,6 +1209,11 @@ static const struct usb_device_id option
.driver_info = ZLP },
{ USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_BG96),
.driver_info = RSVD(4) },
diff --git a/target/linux/generic/hack-6.6/800-GPIO-add-named-gpio-exports.patch b/target/linux/generic/hack-6.6/800-GPIO-add-named-gpio-exports.patch
index cb03f760df..a1d787191c 100644
--- a/target/linux/generic/hack-6.6/800-GPIO-add-named-gpio-exports.patch
+++ b/target/linux/generic/hack-6.6/800-GPIO-add-named-gpio-exports.patch
@@ -131,7 +131,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
struct gpio_desc *desc)
--- a/drivers/gpio/gpiolib-sysfs.c
+++ b/drivers/gpio/gpiolib-sysfs.c
-@@ -557,7 +557,7 @@ static struct class gpio_class = {
+@@ -558,7 +558,7 @@ static struct class gpio_class = {
*
* Returns zero on success, else an error.
*/
@@ -140,7 +140,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
{
struct gpio_chip *chip;
struct gpio_device *gdev;
-@@ -619,6 +619,8 @@ int gpiod_export(struct gpio_desc *desc,
+@@ -620,6 +620,8 @@ int gpiod_export(struct gpio_desc *desc,
offset = gpio_chip_hwgpio(desc);
if (chip->names && chip->names[offset])
ioname = chip->names[offset];
@@ -149,7 +149,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
dev = device_create_with_groups(&gpio_class, &gdev->dev,
MKDEV(0, 0), data, gpio_groups,
-@@ -640,8 +642,21 @@ err_unlock:
+@@ -641,8 +643,21 @@ err_unlock:
gpiod_dbg(desc, "%s: status %d\n", __func__, status);
return status;
}
diff --git a/target/linux/generic/hack-6.6/902-debloat_proc.patch b/target/linux/generic/hack-6.6/902-debloat_proc.patch
index eda0f45b72..442daf6a0a 100644
--- a/target/linux/generic/hack-6.6/902-debloat_proc.patch
+++ b/target/linux/generic/hack-6.6/902-debloat_proc.patch
@@ -29,7 +29,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/fs/locks.c
+++ b/fs/locks.c
-@@ -2897,6 +2897,8 @@ static const struct seq_operations locks
+@@ -2895,6 +2895,8 @@ static const struct seq_operations locks
static int __init proc_locks_init(void)
{
@@ -235,7 +235,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
if (!pe)
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
-@@ -4447,6 +4447,8 @@ static const struct seq_operations vmall
+@@ -4448,6 +4448,8 @@ static const struct seq_operations vmall
static int __init proc_vmalloc_init(void)
{
@@ -341,7 +341,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
-@@ -3036,11 +3036,13 @@ static const struct seq_operations fib_r
+@@ -3037,11 +3037,13 @@ static const struct seq_operations fib_r
int __net_init fib_proc_init(struct net *net)
{
@@ -357,7 +357,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
fib_triestat_seq_show, NULL))
goto out2;
-@@ -3051,17 +3053,21 @@ int __net_init fib_proc_init(struct net
+@@ -3052,17 +3054,21 @@ int __net_init fib_proc_init(struct net
return 0;
out3:
diff --git a/target/linux/generic/hack-6.6/904-debloat_dma_buf.patch b/target/linux/generic/hack-6.6/904-debloat_dma_buf.patch
index 8fdaab5ad6..355bd0d70c 100644
--- a/target/linux/generic/hack-6.6/904-debloat_dma_buf.patch
+++ b/target/linux/generic/hack-6.6/904-debloat_dma_buf.patch
@@ -73,7 +73,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
+MODULE_LICENSE("GPL");
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
-@@ -4487,6 +4487,7 @@ int wake_up_state(struct task_struct *p,
+@@ -4483,6 +4483,7 @@ int wake_up_state(struct task_struct *p,
{
return try_to_wake_up(p, state, 0);
}
diff --git a/target/linux/generic/hack-6.6/911-kobject_add_broadcast_uevent.patch b/target/linux/generic/hack-6.6/911-kobject_add_broadcast_uevent.patch
index 7a21e73dae..372ac6fa7d 100644
--- a/target/linux/generic/hack-6.6/911-kobject_add_broadcast_uevent.patch
+++ b/target/linux/generic/hack-6.6/911-kobject_add_broadcast_uevent.patch
@@ -1,7 +1,7 @@
From 0d37e6edc09c99e683dd91ca0e83bbc0df8477b3 Mon Sep 17 00:00:00 2001
From: Felix Fietkau <nbd@nbd.name>
Date: Sun, 16 Jul 2017 16:56:10 +0200
-Subject: lib: add uevent_next_seqnum()
+Subject: lib: add broadcast_uevent()
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
@@ -30,7 +30,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
#endif /* _KOBJECT_H_ */
--- a/lib/kobject_uevent.c
+++ b/lib/kobject_uevent.c
-@@ -691,6 +691,43 @@ int add_uevent_var(struct kobj_uevent_en
+@@ -706,6 +706,43 @@ int add_uevent_var(struct kobj_uevent_en
EXPORT_SYMBOL_GPL(add_uevent_var);
#if defined(CONFIG_NET)
diff --git a/target/linux/generic/hack-6.6/930-Revert-Revert-Revert-driver-core-Set-fw_devlink-on-b.patch b/target/linux/generic/hack-6.6/930-Revert-Revert-Revert-driver-core-Set-fw_devlink-on-b.patch
index 1c5fb11ff5..85a19027fd 100644
--- a/target/linux/generic/hack-6.6/930-Revert-Revert-Revert-driver-core-Set-fw_devlink-on-b.patch
+++ b/target/linux/generic/hack-6.6/930-Revert-Revert-Revert-driver-core-Set-fw_devlink-on-b.patch
@@ -19,7 +19,7 @@ Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
-@@ -1657,7 +1657,7 @@ static void device_links_purge(struct de
+@@ -1658,7 +1658,7 @@ static void device_links_purge(struct de
#define FW_DEVLINK_FLAGS_RPM (FW_DEVLINK_FLAGS_ON | \
DL_FLAG_PM_RUNTIME)
diff --git a/target/linux/generic/pending-5.15/491-ubi-auto-create-ubiblock-device-for-rootfs.patch b/target/linux/generic/pending-5.15/491-ubi-auto-create-ubiblock-device-for-rootfs.patch
index ae53770c11..4ddd27add9 100644
--- a/target/linux/generic/pending-5.15/491-ubi-auto-create-ubiblock-device-for-rootfs.patch
+++ b/target/linux/generic/pending-5.15/491-ubi-auto-create-ubiblock-device-for-rootfs.patch
@@ -24,7 +24,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+ return magic == UBIFS_NODE_MAGIC;
+}
+
-+static void __init ubiblock_create_auto_rootfs(void)
++static void ubiblock_create_auto_rootfs(void)
+{
+ int ubi_num, ret, is_ubifs;
+ struct ubi_volume_desc *desc;
diff --git a/target/linux/generic/pending-5.15/802-nvmem-u-boot-env-align-endianness-of-crc32-values.patch b/target/linux/generic/pending-5.15/802-nvmem-u-boot-env-align-endianness-of-crc32-values.patch
index d07447bcba..29fe668f8d 100644
--- a/target/linux/generic/pending-5.15/802-nvmem-u-boot-env-align-endianness-of-crc32-values.patch
+++ b/target/linux/generic/pending-5.15/802-nvmem-u-boot-env-align-endianness-of-crc32-values.patch
@@ -1,7 +1,7 @@
From 0e71cac033bb7689c4dfa2e6814191337ef770f5 Mon Sep 17 00:00:00 2001
From: INAGAKI Hiroshi <musashino.open@gmail.com>
Date: Thu, 13 Oct 2022 00:51:33 +0900
-Subject: [PATCH] nvmem: u-boot-env: align endianness of crc32 values
+Subject: [PATCH] nvmem: layouts: u-boot-env: align endianness of crc32 values
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
@@ -31,12 +31,10 @@ Acked-by: Rafał Miłecki <rafal@milecki.pl>
Tested-by: Christian Lamparter <chunkeey@gmail.com>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
---
- drivers/nvmem/u-boot-env.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
---- a/drivers/nvmem/u-boot-env.c
-+++ b/drivers/nvmem/u-boot-env.c
-@@ -181,7 +181,7 @@ static int u_boot_env_parse(struct u_boo
+--- a/drivers/nvmem/layouts/u-boot-env.c
++++ b/drivers/nvmem/layouts/u-boot-env.c
+@@ -148,7 +148,7 @@ int u_boot_env_parse(struct device *dev,
crc32_data_len = dev_size - crc32_data_offset;
data_len = dev_size - data_offset;
diff --git a/target/linux/generic/pending-5.15/804-nvmem-core-support-mac-base-fixed-layout-cells.patch b/target/linux/generic/pending-5.15/804-nvmem-core-support-mac-base-fixed-layout-cells.patch
index 9bb94a28b5..29cda1824e 100644
--- a/target/linux/generic/pending-5.15/804-nvmem-core-support-mac-base-fixed-layout-cells.patch
+++ b/target/linux/generic/pending-5.15/804-nvmem-core-support-mac-base-fixed-layout-cells.patch
@@ -33,7 +33,7 @@ string.
#include <linux/init.h>
#include <linux/kref.h>
#include <linux/module.h>
-@@ -780,6 +783,62 @@ static int nvmem_validate_keepouts(struc
+@@ -797,6 +800,62 @@ static int nvmem_validate_keepouts(struc
return 0;
}
@@ -96,7 +96,7 @@ string.
static int nvmem_add_cells_from_dt(struct nvmem_device *nvmem, struct device_node *np)
{
struct device *dev = &nvmem->dev;
-@@ -814,6 +873,25 @@ static int nvmem_add_cells_from_dt(struc
+@@ -836,6 +895,25 @@ static int nvmem_add_cells_from_dt(struc
if (nvmem->fixup_dt_cell_info)
nvmem->fixup_dt_cell_info(nvmem, &info);
diff --git a/target/linux/generic/pending-6.1/120-Fix-alloc_node_mem_map-with-ARCH_PFN_OFFSET-calcu.patch b/target/linux/generic/pending-6.1/120-Fix-alloc_node_mem_map-with-ARCH_PFN_OFFSET-calcu.patch
index edee0e46a5..8fea984a33 100644
--- a/target/linux/generic/pending-6.1/120-Fix-alloc_node_mem_map-with-ARCH_PFN_OFFSET-calcu.patch
+++ b/target/linux/generic/pending-6.1/120-Fix-alloc_node_mem_map-with-ARCH_PFN_OFFSET-calcu.patch
@@ -71,7 +71,7 @@ Signed-off-by: Tobias Wolf <dev-NTEO@vplace.de>
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
-@@ -7903,7 +7903,7 @@ static void __init alloc_node_mem_map(st
+@@ -7910,7 +7910,7 @@ static void __init alloc_node_mem_map(st
if (pgdat == NODE_DATA(0)) {
mem_map = NODE_DATA(0)->node_mem_map;
if (page_to_pfn(mem_map) != pgdat->node_start_pfn)
diff --git a/target/linux/generic/pending-6.1/491-ubi-auto-create-ubiblock-device-for-rootfs.patch b/target/linux/generic/pending-6.1/491-ubi-auto-create-ubiblock-device-for-rootfs.patch
index a43da2a572..f0ea8e8cb5 100644
--- a/target/linux/generic/pending-6.1/491-ubi-auto-create-ubiblock-device-for-rootfs.patch
+++ b/target/linux/generic/pending-6.1/491-ubi-auto-create-ubiblock-device-for-rootfs.patch
@@ -24,7 +24,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+ return magic == UBIFS_NODE_MAGIC;
+}
+
-+static void __init ubiblock_create_auto_rootfs(struct ubi_volume_info *vi)
++static void ubiblock_create_auto_rootfs(struct ubi_volume_info *vi)
+{
+ int ret, is_ubifs;
+ struct ubi_volume_desc *desc;
diff --git a/target/linux/generic/pending-6.1/510-block-add-uImage.FIT-subimage-block-driver.patch b/target/linux/generic/pending-6.1/510-block-add-uImage.FIT-subimage-block-driver.patch
index 700eda1c8e..befc505dbc 100644
--- a/target/linux/generic/pending-6.1/510-block-add-uImage.FIT-subimage-block-driver.patch
+++ b/target/linux/generic/pending-6.1/510-block-add-uImage.FIT-subimage-block-driver.patch
@@ -36,7 +36,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
--- a/MAINTAINERS
+++ b/MAINTAINERS
-@@ -21059,6 +21059,12 @@ F: Documentation/filesystems/ubifs-authe
+@@ -21060,6 +21060,12 @@ F: Documentation/filesystems/ubifs-authe
F: Documentation/filesystems/ubifs.rst
F: fs/ubifs/
diff --git a/target/linux/generic/pending-6.1/630-packet_socket_type.patch b/target/linux/generic/pending-6.1/630-packet_socket_type.patch
index 359d002b0e..5553fba94b 100644
--- a/target/linux/generic/pending-6.1/630-packet_socket_type.patch
+++ b/target/linux/generic/pending-6.1/630-packet_socket_type.patch
@@ -30,7 +30,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
#define PACKET_FANOUT_LB 1
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
-@@ -1866,6 +1866,7 @@ static int packet_rcv_spkt(struct sk_buf
+@@ -1927,6 +1927,7 @@ static int packet_rcv_spkt(struct sk_buf
{
struct sock *sk;
struct sockaddr_pkt *spkt;
@@ -38,7 +38,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
/*
* When we registered the protocol we saved the socket in the data
-@@ -1873,6 +1874,7 @@ static int packet_rcv_spkt(struct sk_buf
+@@ -1934,6 +1935,7 @@ static int packet_rcv_spkt(struct sk_buf
*/
sk = pt->af_packet_priv;
@@ -46,7 +46,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
/*
* Yank back the headers [hope the device set this
-@@ -1885,7 +1887,7 @@ static int packet_rcv_spkt(struct sk_buf
+@@ -1946,7 +1948,7 @@ static int packet_rcv_spkt(struct sk_buf
* so that this procedure is noop.
*/
@@ -55,7 +55,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
goto out;
if (!net_eq(dev_net(dev), sock_net(sk)))
-@@ -2131,12 +2133,12 @@ static int packet_rcv(struct sk_buff *sk
+@@ -2192,12 +2194,12 @@ static int packet_rcv(struct sk_buff *sk
unsigned int snaplen, res;
bool is_drop_n_account = false;
@@ -71,7 +71,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
if (!net_eq(dev_net(dev), sock_net(sk)))
goto drop;
-@@ -2263,12 +2265,12 @@ static int tpacket_rcv(struct sk_buff *s
+@@ -2324,12 +2326,12 @@ static int tpacket_rcv(struct sk_buff *s
BUILD_BUG_ON(TPACKET_ALIGN(sizeof(*h.h2)) != 32);
BUILD_BUG_ON(TPACKET_ALIGN(sizeof(*h.h3)) != 48);
@@ -87,7 +87,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
if (!net_eq(dev_net(dev), sock_net(sk)))
goto drop;
-@@ -3377,6 +3379,7 @@ static int packet_create(struct net *net
+@@ -3443,6 +3445,7 @@ static int packet_create(struct net *net
mutex_init(&po->pg_vec_lock);
po->rollover = NULL;
po->prot_hook.func = packet_rcv;
@@ -95,7 +95,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
if (sock->type == SOCK_PACKET)
po->prot_hook.func = packet_rcv_spkt;
-@@ -4014,6 +4017,16 @@ packet_setsockopt(struct socket *sock, i
+@@ -4096,6 +4099,16 @@ packet_setsockopt(struct socket *sock, i
WRITE_ONCE(po->xmit, val ? packet_direct_xmit : dev_queue_xmit);
return 0;
}
@@ -112,7 +112,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
default:
return -ENOPROTOOPT;
}
-@@ -4070,6 +4083,13 @@ static int packet_getsockopt(struct sock
+@@ -4152,6 +4165,13 @@ static int packet_getsockopt(struct sock
case PACKET_VNET_HDR:
val = po->has_vnet_hdr;
break;
diff --git a/target/linux/generic/pending-6.1/666-Add-support-for-MAP-E-FMRs-mesh-mode.patch b/target/linux/generic/pending-6.1/666-Add-support-for-MAP-E-FMRs-mesh-mode.patch
index b799c6fc9c..a2f88d79e6 100644
--- a/target/linux/generic/pending-6.1/666-Add-support-for-MAP-E-FMRs-mesh-mode.patch
+++ b/target/linux/generic/pending-6.1/666-Add-support-for-MAP-E-FMRs-mesh-mode.patch
@@ -338,7 +338,7 @@ Signed-off-by: Steven Barth <cyrus@openwrt.org>
if (iptunnel_handle_offloads(skb, SKB_GSO_IPXIP6))
return -1;
-@@ -1545,6 +1706,14 @@ ip6_tnl_change(struct ip6_tnl *t, const
+@@ -1546,6 +1707,14 @@ ip6_tnl_change(struct ip6_tnl *t, const
t->parms.link = p->link;
t->parms.proto = p->proto;
t->parms.fwmark = p->fwmark;
@@ -353,7 +353,7 @@ Signed-off-by: Steven Barth <cyrus@openwrt.org>
dst_cache_reset(&t->dst_cache);
ip6_tnl_link_config(t);
}
-@@ -1579,6 +1748,7 @@ ip6_tnl_parm_from_user(struct __ip6_tnl_
+@@ -1580,6 +1749,7 @@ ip6_tnl_parm_from_user(struct __ip6_tnl_
p->flowinfo = u->flowinfo;
p->link = u->link;
p->proto = u->proto;
@@ -361,7 +361,7 @@ Signed-off-by: Steven Barth <cyrus@openwrt.org>
memcpy(p->name, u->name, sizeof(u->name));
}
-@@ -1965,6 +2135,15 @@ static int ip6_tnl_validate(struct nlatt
+@@ -1967,6 +2137,15 @@ static int ip6_tnl_validate(struct nlatt
return 0;
}
@@ -377,7 +377,7 @@ Signed-off-by: Steven Barth <cyrus@openwrt.org>
static void ip6_tnl_netlink_parms(struct nlattr *data[],
struct __ip6_tnl_parm *parms)
{
-@@ -2002,6 +2181,46 @@ static void ip6_tnl_netlink_parms(struct
+@@ -2004,6 +2183,46 @@ static void ip6_tnl_netlink_parms(struct
if (data[IFLA_IPTUN_FWMARK])
parms->fwmark = nla_get_u32(data[IFLA_IPTUN_FWMARK]);
@@ -424,7 +424,7 @@ Signed-off-by: Steven Barth <cyrus@openwrt.org>
}
static int ip6_tnl_newlink(struct net *src_net, struct net_device *dev,
-@@ -2085,6 +2304,12 @@ static void ip6_tnl_dellink(struct net_d
+@@ -2087,6 +2306,12 @@ static void ip6_tnl_dellink(struct net_d
static size_t ip6_tnl_get_size(const struct net_device *dev)
{
@@ -437,7 +437,7 @@ Signed-off-by: Steven Barth <cyrus@openwrt.org>
return
/* IFLA_IPTUN_LINK */
nla_total_size(4) +
-@@ -2114,6 +2339,24 @@ static size_t ip6_tnl_get_size(const str
+@@ -2116,6 +2341,24 @@ static size_t ip6_tnl_get_size(const str
nla_total_size(0) +
/* IFLA_IPTUN_FWMARK */
nla_total_size(4) +
@@ -462,7 +462,7 @@ Signed-off-by: Steven Barth <cyrus@openwrt.org>
0;
}
-@@ -2121,6 +2364,9 @@ static int ip6_tnl_fill_info(struct sk_b
+@@ -2123,6 +2366,9 @@ static int ip6_tnl_fill_info(struct sk_b
{
struct ip6_tnl *tunnel = netdev_priv(dev);
struct __ip6_tnl_parm *parm = &tunnel->parms;
@@ -472,7 +472,7 @@ Signed-off-by: Steven Barth <cyrus@openwrt.org>
if (nla_put_u32(skb, IFLA_IPTUN_LINK, parm->link) ||
nla_put_in6_addr(skb, IFLA_IPTUN_LOCAL, &parm->laddr) ||
-@@ -2130,9 +2376,27 @@ static int ip6_tnl_fill_info(struct sk_b
+@@ -2132,9 +2378,27 @@ static int ip6_tnl_fill_info(struct sk_b
nla_put_be32(skb, IFLA_IPTUN_FLOWINFO, parm->flowinfo) ||
nla_put_u32(skb, IFLA_IPTUN_FLAGS, parm->flags) ||
nla_put_u8(skb, IFLA_IPTUN_PROTO, parm->proto) ||
@@ -501,7 +501,7 @@ Signed-off-by: Steven Barth <cyrus@openwrt.org>
if (nla_put_u16(skb, IFLA_IPTUN_ENCAP_TYPE, tunnel->encap.type) ||
nla_put_be16(skb, IFLA_IPTUN_ENCAP_SPORT, tunnel->encap.sport) ||
nla_put_be16(skb, IFLA_IPTUN_ENCAP_DPORT, tunnel->encap.dport) ||
-@@ -2172,6 +2436,7 @@ static const struct nla_policy ip6_tnl_p
+@@ -2174,6 +2438,7 @@ static const struct nla_policy ip6_tnl_p
[IFLA_IPTUN_ENCAP_DPORT] = { .type = NLA_U16 },
[IFLA_IPTUN_COLLECT_METADATA] = { .type = NLA_FLAG },
[IFLA_IPTUN_FWMARK] = { .type = NLA_U32 },
diff --git a/target/linux/generic/pending-6.1/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch b/target/linux/generic/pending-6.1/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch
index 43d49f07d1..1d16b81543 100644
--- a/target/linux/generic/pending-6.1/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch
+++ b/target/linux/generic/pending-6.1/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch
@@ -66,7 +66,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
static void rt_fibinfo_free(struct rtable __rcu **rtp)
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
-@@ -2783,6 +2783,7 @@ static const char *const rtn_type_names[
+@@ -2784,6 +2784,7 @@ static const char *const rtn_type_names[
[RTN_THROW] = "THROW",
[RTN_NAT] = "NAT",
[RTN_XRESOLVE] = "XRESOLVE",
diff --git a/target/linux/generic/pending-6.1/680-net-add-TCP-fraglist-GRO-support.patch b/target/linux/generic/pending-6.1/680-net-add-TCP-fraglist-GRO-support.patch
index f52233fe90..012d6b87ba 100644
--- a/target/linux/generic/pending-6.1/680-net-add-TCP-fraglist-GRO-support.patch
+++ b/target/linux/generic/pending-6.1/680-net-add-TCP-fraglist-GRO-support.patch
@@ -80,7 +80,7 @@ Signe-off-by: Felix Fietkau <nbd@nbd.name>
#endif /* _NET_IPV6_GRO_H */
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
-@@ -2057,7 +2057,10 @@ void tcp_v4_destroy_sock(struct sock *sk
+@@ -2058,7 +2058,10 @@ void tcp_v4_destroy_sock(struct sock *sk
struct sk_buff *tcp_gso_segment(struct sk_buff *skb,
netdev_features_t features);
@@ -211,7 +211,7 @@ Signe-off-by: Felix Fietkau <nbd@nbd.name>
if (unlikely(skb->ip_summed != CHECKSUM_PARTIAL)) {
const struct iphdr *iph = ip_hdr(skb);
struct tcphdr *th = tcp_hdr(skb);
-@@ -177,61 +244,76 @@ out:
+@@ -180,61 +247,76 @@ out:
return segs;
}
@@ -318,7 +318,7 @@ Signe-off-by: Felix Fietkau <nbd@nbd.name>
flush = NAPI_GRO_CB(p)->flush;
flush |= (__force int)(flags & TCP_FLAG_CWR);
flush |= (__force int)((flags ^ tcp_flag_word(th2)) &
-@@ -268,6 +350,19 @@ found:
+@@ -271,6 +353,19 @@ found:
flush |= p->decrypted ^ skb->decrypted;
#endif
@@ -338,7 +338,7 @@ Signe-off-by: Felix Fietkau <nbd@nbd.name>
if (flush || skb_gro_receive(p, skb)) {
mss = 1;
goto out_check_final;
-@@ -289,7 +384,6 @@ out_check_final:
+@@ -292,7 +387,6 @@ out_check_final:
if (p && (!NAPI_GRO_CB(skb)->same_flow || flush))
pp = p;
@@ -346,7 +346,7 @@ Signe-off-by: Felix Fietkau <nbd@nbd.name>
NAPI_GRO_CB(skb)->flush |= (flush != 0);
return pp;
-@@ -315,18 +409,58 @@ int tcp_gro_complete(struct sk_buff *skb
+@@ -318,18 +412,58 @@ int tcp_gro_complete(struct sk_buff *skb
}
EXPORT_SYMBOL(tcp_gro_complete);
@@ -410,7 +410,7 @@ Signe-off-by: Felix Fietkau <nbd@nbd.name>
}
INDIRECT_CALLABLE_SCOPE int tcp4_gro_complete(struct sk_buff *skb, int thoff)
-@@ -334,6 +468,15 @@ INDIRECT_CALLABLE_SCOPE int tcp4_gro_com
+@@ -337,6 +471,15 @@ INDIRECT_CALLABLE_SCOPE int tcp4_gro_com
const struct iphdr *iph = ip_hdr(skb);
struct tcphdr *th = tcp_hdr(skb);
@@ -428,7 +428,7 @@ Signe-off-by: Felix Fietkau <nbd@nbd.name>
skb_shinfo(skb)->gso_type |= SKB_GSO_TCPV4;
--- a/net/ipv4/udp_offload.c
+++ b/net/ipv4/udp_offload.c
-@@ -425,33 +425,6 @@ out:
+@@ -437,33 +437,6 @@ out:
return segs;
}
diff --git a/target/linux/generic/pending-6.1/701-netfilter-nf_tables-ignore-EOPNOTSUPP-on-flowtable-d.patch b/target/linux/generic/pending-6.1/701-netfilter-nf_tables-ignore-EOPNOTSUPP-on-flowtable-d.patch
index 916b6bc6a0..99ea09ae8f 100644
--- a/target/linux/generic/pending-6.1/701-netfilter-nf_tables-ignore-EOPNOTSUPP-on-flowtable-d.patch
+++ b/target/linux/generic/pending-6.1/701-netfilter-nf_tables-ignore-EOPNOTSUPP-on-flowtable-d.patch
@@ -18,7 +18,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
-@@ -7958,7 +7958,7 @@ static int nft_register_flowtable_net_ho
+@@ -8012,7 +8012,7 @@ static int nft_register_flowtable_net_ho
err = flowtable->data.type->setup(&flowtable->data,
hook->ops.dev,
FLOW_BLOCK_BIND);
diff --git a/target/linux/generic/pending-6.1/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch b/target/linux/generic/pending-6.1/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch
index 13a4d190ee..6fa33ee1a8 100644
--- a/target/linux/generic/pending-6.1/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch
+++ b/target/linux/generic/pending-6.1/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch
@@ -17,7 +17,7 @@ Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
-@@ -7079,6 +7079,7 @@ static int mv88e6xxx_register_switch(str
+@@ -7080,6 +7080,7 @@ static int mv88e6xxx_register_switch(str
ds->ops = &mv88e6xxx_switch_ops;
ds->ageing_time_min = chip->info->age_time_coeff;
ds->ageing_time_max = chip->info->age_time_coeff * U8_MAX;
diff --git a/target/linux/generic/pending-6.1/774-net-dsa-b53-mmap-allow-passing-a-chip-ID.patch b/target/linux/generic/pending-6.1/774-net-dsa-b53-mmap-allow-passing-a-chip-ID.patch
index de237374af..bb632b5eff 100644
--- a/target/linux/generic/pending-6.1/774-net-dsa-b53-mmap-allow-passing-a-chip-ID.patch
+++ b/target/linux/generic/pending-6.1/774-net-dsa-b53-mmap-allow-passing-a-chip-ID.patch
@@ -100,7 +100,7 @@ Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
--- a/drivers/net/dsa/b53/b53_common.c
+++ b/drivers/net/dsa/b53/b53_common.c
-@@ -2466,6 +2466,19 @@ static const struct b53_chip_data b53_sw
+@@ -2469,6 +2469,19 @@ static const struct b53_chip_data b53_sw
.jumbo_size_reg = B53_JUMBO_MAX_SIZE_63XX,
},
{
diff --git a/target/linux/generic/pending-6.1/777-net-dsa-b53-mdio-add-support-for-BCM53134.patch b/target/linux/generic/pending-6.1/777-net-dsa-b53-mdio-add-support-for-BCM53134.patch
index f0ae2defce..7bed8c22a4 100644
--- a/target/linux/generic/pending-6.1/777-net-dsa-b53-mdio-add-support-for-BCM53134.patch
+++ b/target/linux/generic/pending-6.1/777-net-dsa-b53-mdio-add-support-for-BCM53134.patch
@@ -100,7 +100,7 @@ Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
--- a/drivers/net/dsa/b53/b53_common.c
+++ b/drivers/net/dsa/b53/b53_common.c
-@@ -2613,6 +2613,20 @@ static const struct b53_chip_data b53_sw
+@@ -2616,6 +2616,20 @@ static const struct b53_chip_data b53_sw
.jumbo_pm_reg = B53_JUMBO_PORT_MASK,
.jumbo_size_reg = B53_JUMBO_MAX_SIZE,
},
@@ -121,7 +121,7 @@ Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
};
static int b53_switch_init(struct b53_device *dev)
-@@ -2790,6 +2804,7 @@ int b53_switch_detect(struct b53_device
+@@ -2793,6 +2807,7 @@ int b53_switch_detect(struct b53_device
case BCM53012_DEVICE_ID:
case BCM53018_DEVICE_ID:
case BCM53019_DEVICE_ID:
diff --git a/target/linux/generic/pending-6.1/802-nvmem-u-boot-env-align-endianness-of-crc32-values.patch b/target/linux/generic/pending-6.1/802-nvmem-u-boot-env-align-endianness-of-crc32-values.patch
index d07447bcba..29fe668f8d 100644
--- a/target/linux/generic/pending-6.1/802-nvmem-u-boot-env-align-endianness-of-crc32-values.patch
+++ b/target/linux/generic/pending-6.1/802-nvmem-u-boot-env-align-endianness-of-crc32-values.patch
@@ -1,7 +1,7 @@
From 0e71cac033bb7689c4dfa2e6814191337ef770f5 Mon Sep 17 00:00:00 2001
From: INAGAKI Hiroshi <musashino.open@gmail.com>
Date: Thu, 13 Oct 2022 00:51:33 +0900
-Subject: [PATCH] nvmem: u-boot-env: align endianness of crc32 values
+Subject: [PATCH] nvmem: layouts: u-boot-env: align endianness of crc32 values
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
@@ -31,12 +31,10 @@ Acked-by: Rafał Miłecki <rafal@milecki.pl>
Tested-by: Christian Lamparter <chunkeey@gmail.com>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
---
- drivers/nvmem/u-boot-env.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
---- a/drivers/nvmem/u-boot-env.c
-+++ b/drivers/nvmem/u-boot-env.c
-@@ -181,7 +181,7 @@ static int u_boot_env_parse(struct u_boo
+--- a/drivers/nvmem/layouts/u-boot-env.c
++++ b/drivers/nvmem/layouts/u-boot-env.c
+@@ -148,7 +148,7 @@ int u_boot_env_parse(struct device *dev,
crc32_data_len = dev_size - crc32_data_offset;
data_len = dev_size - data_offset;
diff --git a/target/linux/generic/pending-6.1/804-nvmem-core-support-mac-base-fixed-layout-cells.patch b/target/linux/generic/pending-6.1/804-nvmem-core-support-mac-base-fixed-layout-cells.patch
index 9bb94a28b5..29cda1824e 100644
--- a/target/linux/generic/pending-6.1/804-nvmem-core-support-mac-base-fixed-layout-cells.patch
+++ b/target/linux/generic/pending-6.1/804-nvmem-core-support-mac-base-fixed-layout-cells.patch
@@ -33,7 +33,7 @@ string.
#include <linux/init.h>
#include <linux/kref.h>
#include <linux/module.h>
-@@ -780,6 +783,62 @@ static int nvmem_validate_keepouts(struc
+@@ -797,6 +800,62 @@ static int nvmem_validate_keepouts(struc
return 0;
}
@@ -96,7 +96,7 @@ string.
static int nvmem_add_cells_from_dt(struct nvmem_device *nvmem, struct device_node *np)
{
struct device *dev = &nvmem->dev;
-@@ -814,6 +873,25 @@ static int nvmem_add_cells_from_dt(struc
+@@ -836,6 +895,25 @@ static int nvmem_add_cells_from_dt(struc
if (nvmem->fixup_dt_cell_info)
nvmem->fixup_dt_cell_info(nvmem, &info);
diff --git a/target/linux/generic/pending-6.1/834-ledtrig-libata.patch b/target/linux/generic/pending-6.1/834-ledtrig-libata.patch
index 39960bc090..7ca586c676 100644
--- a/target/linux/generic/pending-6.1/834-ledtrig-libata.patch
+++ b/target/linux/generic/pending-6.1/834-ledtrig-libata.patch
@@ -85,7 +85,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
ata_sff_port_init(ap);
return ap;
-@@ -5473,6 +5492,12 @@ static void ata_host_release(struct kref
+@@ -5476,6 +5495,12 @@ static void ata_host_release(struct kref
kfree(ap->pmp_link);
kfree(ap->slave_link);
@@ -98,7 +98,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
kfree(ap);
host->ports[i] = NULL;
}
-@@ -5875,7 +5900,23 @@ int ata_host_register(struct ata_host *h
+@@ -5878,7 +5903,23 @@ int ata_host_register(struct ata_host *h
host->ports[i]->print_id = atomic_inc_return(&ata_print_id);
host->ports[i]->local_port_no = i + 1;
}
diff --git a/target/linux/generic/pending-6.6/410-mtd-spinand-set-bitflip_threshold-to-75-of-ECC-strength.patch b/target/linux/generic/pending-6.6/410-mtd-spinand-set-bitflip_threshold-to-75-of-ECC-strength.patch
new file mode 100644
index 0000000000..aeac79c023
--- /dev/null
+++ b/target/linux/generic/pending-6.6/410-mtd-spinand-set-bitflip_threshold-to-75-of-ECC-strength.patch
@@ -0,0 +1,63 @@
+From patchwork Mon Aug 12 01:56:41 2024
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org>
+X-Patchwork-Id: 1971406
+Return-Path:
+ <linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org>
+X-Original-To: incoming@patchwork.ozlabs.org
+Delivered-To: patchwork-incoming@legolas.ozlabs.org
+Date: Mon, 12 Aug 2024 02:56:41 +0100
+From: Daniel Golle <daniel@makrotopia.org>
+To: Miquel Raynal <miquel.raynal@bootlin.com>,
+ Richard Weinberger <richard@nod.at>,
+ Vignesh Raghavendra <vigneshr@ti.com>,
+ Tudor Ambarus <tudor.ambarus@linaro.org>,
+ Daniel Golle <daniel@makrotopia.org>,
+ Mika Westerberg <mika.westerberg@linux.intel.com>,
+ Chia-Lin Kao <acelan.kao@canonical.com>,
+ Martin Kurbanov <mmkurbanov@salutedevices.com>,
+ linux-mtd@lists.infradead.org, linux-kernel@vger.kernel.org
+Subject: [PATCH] mtd: spinand: set bitflip_threshold to 75% of ECC strength
+Message-ID:
+ <2117e387260b0a96f95b8e1652ff79e0e2d71d53.1723427450.git.daniel@makrotopia.org>
+MIME-Version: 1.0
+Content-Disposition: inline
+X-BeenThere: linux-mtd@lists.infradead.org
+X-Mailman-Version: 2.1.34
+Precedence: list
+List-Id: Linux MTD discussion mailing list <linux-mtd.lists.infradead.org>
+List-Unsubscribe: <http://lists.infradead.org/mailman/options/linux-mtd>,
+ <mailto:linux-mtd-request@lists.infradead.org?subject=unsubscribe>
+List-Archive: <http://lists.infradead.org/pipermail/linux-mtd/>
+List-Post: <mailto:linux-mtd@lists.infradead.org>
+List-Help: <mailto:linux-mtd-request@lists.infradead.org?subject=help>
+List-Subscribe: <http://lists.infradead.org/mailman/listinfo/linux-mtd>,
+ <mailto:linux-mtd-request@lists.infradead.org?subject=subscribe>
+Sender: "linux-mtd" <linux-mtd-bounces@lists.infradead.org>
+Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org
+
+Reporting an unclean read from SPI-NAND only when the maximum number
+of correctable bitflip errors has been hit seems a bit late.
+UBI LEB scrubbing, which depends on the lower MTD device reporting
+correctable bitflips, then only kicks in when it's almost too late.
+
+Set bitflip_threshold to 75% of the ECC strength, which is also the
+default for raw NAND.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ drivers/mtd/nand/spi/core.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/mtd/nand/spi/core.c
++++ b/drivers/mtd/nand/spi/core.c
+@@ -1286,6 +1286,7 @@ static int spinand_init(struct spinand_d
+ /* Propagate ECC information to mtd_info */
+ mtd->ecc_strength = nanddev_get_ecc_conf(nand)->strength;
+ mtd->ecc_step_size = nanddev_get_ecc_conf(nand)->step_size;
++ mtd->bitflip_threshold = DIV_ROUND_UP(mtd->ecc_strength * 3, 4);
+
+ ret = spinand_create_dirmaps(spinand);
+ if (ret) {
diff --git a/target/linux/generic/pending-6.6/451-block-partitions-populate-fwnode.patch b/target/linux/generic/pending-6.6/451-block-partitions-populate-fwnode.patch
index 2aef22879d..e279b71173 100644
--- a/target/linux/generic/pending-6.6/451-block-partitions-populate-fwnode.patch
+++ b/target/linux/generic/pending-6.6/451-block-partitions-populate-fwnode.patch
@@ -1,15 +1,42 @@
-From 7f4c9c534aabe1315669e076d3fe0af0fd374cda Mon Sep 17 00:00:00 2001
+From patchwork Tue Jul 30 19:25:59 2024
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org>
+X-Patchwork-Id: 13747816
+Date: Tue, 30 Jul 2024 20:25:59 +0100
From: Daniel Golle <daniel@makrotopia.org>
-Date: Thu, 30 May 2024 03:13:19 +0100
-Subject: [PATCH 2/9] block: partitions: populate fwnode
+To: Rob Herring <robh@kernel.org>, Krzysztof Kozlowski <krzk+dt@kernel.org>,
+ Conor Dooley <conor+dt@kernel.org>, Jens Axboe <axboe@kernel.dk>,
+ Daniel Golle <daniel@makrotopia.org>, Christian Brauner <brauner@kernel.org>,
+ Al Viro <viro@zeniv.linux.org.uk>, Li Lingfeng <lilingfeng3@huawei.com>,
+ Ming Lei <ming.lei@redhat.com>, Christian Heusel <christian@heusel.eu>,
+ =?utf-8?b?UmFmYcWCIE1pxYJlY2tp?= <rafal@milecki.pl>,
+ Felix Fietkau <nbd@nbd.name>, John Crispin <john@phrozen.org>,
+ Chad Monroe <chad.monroe@adtran.com>, Yangyu Chen <cyy@cyyself.name>,
+ Tianling Shen <cnsztl@immortalwrt.org>, Chuanhong Guo <gch981213@gmail.com>,
+ Chen Minqiang <ptpt52@gmail.com>, devicetree@vger.kernel.org,
+ linux-kernel@vger.kernel.org, linux-block@vger.kernel.org
+Subject: [PATCH v5 2/4] block: partitions: populate fwnode
+Message-ID:
+ <3051ac090ad3b3e2f5adb6b67c923261ead729a5.1722365899.git.daniel@makrotopia.org>
+References: <cover.1722365899.git.daniel@makrotopia.org>
+Precedence: bulk
+X-Mailing-List: linux-block@vger.kernel.org
+List-Id: <linux-block.vger.kernel.org>
+List-Subscribe: <mailto:linux-block+subscribe@vger.kernel.org>
+List-Unsubscribe: <mailto:linux-block+unsubscribe@vger.kernel.org>
+MIME-Version: 1.0
+Content-Disposition: inline
+In-Reply-To: <cover.1722365899.git.daniel@makrotopia.org>
-Let block partitions to be represented by a firmware node and hence
-allow them to being referenced e.g. for use with blk-nvmem.
+Assign matching firmware nodes to block partitions in order to allow
+them to be referenced e.g. as NVMEM providers.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
- block/partitions/core.c | 41 +++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 41 insertions(+)
+ block/partitions/core.c | 72 +++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 72 insertions(+)
--- a/block/partitions/core.c
+++ b/block/partitions/core.c
@@ -22,36 +49,70 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
#include "check.h"
static int (*const check_part[])(struct parsed_partitions *) = {
-@@ -292,6 +294,40 @@ static ssize_t whole_disk_show(struct de
+@@ -292,6 +294,74 @@ static ssize_t whole_disk_show(struct de
}
static const DEVICE_ATTR(whole_disk, 0444, whole_disk_show, NULL);
++static bool part_meta_match(const char *attr, const char *member, size_t length)
++{
++ /* check if length of attr exceeds specified maximum length */
++ if (strnlen(attr, length) == length)
++ return false;
++
++ /* return true if strings match */
++ return !strncmp(attr, member, length);
++}
++
+static struct fwnode_handle *find_partition_fwnode(struct block_device *bdev)
+{
+ struct fwnode_handle *fw_parts, *fw_part;
+ struct device *ddev = disk_to_dev(bdev->bd_disk);
+ const char *partname, *uuid;
+ u32 partno;
++ bool got_uuid, got_partname, got_partno;
+
+ fw_parts = device_get_named_child_node(ddev, "partitions");
+ if (!fw_parts)
+ return NULL;
+
+ fwnode_for_each_child_node(fw_parts, fw_part) {
-+ if (!fwnode_property_read_string(fw_part, "uuid", &uuid) &&
-+ (!bdev->bd_meta_info || strncmp(uuid,
-+ bdev->bd_meta_info->uuid,
-+ PARTITION_META_INFO_UUIDLTH)))
++ got_uuid = false;
++ got_partname = false;
++ got_partno = false;
++ /*
++ * In case 'uuid' is defined in the partitions firmware node
++ * require partition meta info being present and the specified
++ * uuid to match.
++ */
++ got_uuid = !fwnode_property_read_string(fw_part, "uuid", &uuid);
++ if (got_uuid && (!bdev->bd_meta_info ||
++ !part_meta_match(uuid, bdev->bd_meta_info->uuid,
++ PARTITION_META_INFO_UUIDLTH)))
++ continue;
++
++ /*
++ * In case 'partname' is defined in the partitions firmware node
++ * require partition meta info being present and the specified
++ * volname to match.
++ */
++ got_partname = !fwnode_property_read_string(fw_part, "partname",
++ &partname);
++ if (got_partname && (!bdev->bd_meta_info ||
++ !part_meta_match(partname,
++ bdev->bd_meta_info->volname,
++ PARTITION_META_INFO_VOLNAMELTH)))
+ continue;
+
-+ if (!fwnode_property_read_string(fw_part, "partname", &partname) &&
-+ (!bdev->bd_meta_info || strncmp(partname,
-+ bdev->bd_meta_info->volname,
-+ PARTITION_META_INFO_VOLNAMELTH)))
++ /*
++ * In case 'partno' is defined in the partitions firmware node
++ * the specified partno needs to match.
++ */
++ got_partno = !fwnode_property_read_u32(fw_part, "partno", &partno);
++ if (got_partno && bdev->bd_partno != partno)
+ continue;
+
-+ if (!fwnode_property_read_u32(fw_part, "partno", &partno) &&
-+ bdev->bd_partno != partno)
++ /* Skip if no matching criteria is present in firmware node */
++ if (!got_uuid && !got_partname && !got_partno)
+ continue;
+
+ return fw_part;
@@ -63,7 +124,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
/*
* Must be called either with open_mutex held, before a disk can be opened or
* after all disk users are gone.
-@@ -374,6 +410,8 @@ static struct block_device *add_partitio
+@@ -374,6 +444,8 @@ static struct block_device *add_partitio
goto out_put;
}
diff --git a/target/linux/generic/pending-6.6/452-block-add-support-for-notifications.patch b/target/linux/generic/pending-6.6/452-block-add-support-for-notifications.patch
index c5a3391e45..cad3fbfa90 100644
--- a/target/linux/generic/pending-6.6/452-block-add-support-for-notifications.patch
+++ b/target/linux/generic/pending-6.6/452-block-add-support-for-notifications.patch
@@ -1,7 +1,34 @@
-From e07ace307ce598847074a096f408bec0e3a392ed Mon Sep 17 00:00:00 2001
+From patchwork Tue Jul 30 19:26:42 2024
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org>
+X-Patchwork-Id: 13747817
+Date: Tue, 30 Jul 2024 20:26:42 +0100
From: Daniel Golle <daniel@makrotopia.org>
-Date: Thu, 30 May 2024 03:14:34 +0100
-Subject: [PATCH 3/9] block: add support for notifications
+To: Rob Herring <robh@kernel.org>, Krzysztof Kozlowski <krzk+dt@kernel.org>,
+ Conor Dooley <conor+dt@kernel.org>, Jens Axboe <axboe@kernel.dk>,
+ Daniel Golle <daniel@makrotopia.org>, Christian Brauner <brauner@kernel.org>,
+ Al Viro <viro@zeniv.linux.org.uk>, Li Lingfeng <lilingfeng3@huawei.com>,
+ Ming Lei <ming.lei@redhat.com>, Christian Heusel <christian@heusel.eu>,
+ =?utf-8?b?UmFmYcWCIE1pxYJlY2tp?= <rafal@milecki.pl>,
+ Felix Fietkau <nbd@nbd.name>, John Crispin <john@phrozen.org>,
+ Chad Monroe <chad.monroe@adtran.com>, Yangyu Chen <cyy@cyyself.name>,
+ Tianling Shen <cnsztl@immortalwrt.org>, Chuanhong Guo <gch981213@gmail.com>,
+ Chen Minqiang <ptpt52@gmail.com>, devicetree@vger.kernel.org,
+ linux-kernel@vger.kernel.org, linux-block@vger.kernel.org
+Subject: [PATCH v5 3/4] block: add support for notifications
+Message-ID:
+ <ca0022886e8f211a323a716653a1396a3bc91653.1722365899.git.daniel@makrotopia.org>
+References: <cover.1722365899.git.daniel@makrotopia.org>
+Precedence: bulk
+X-Mailing-List: linux-block@vger.kernel.org
+List-Id: <linux-block.vger.kernel.org>
+List-Subscribe: <mailto:linux-block+subscribe@vger.kernel.org>
+List-Unsubscribe: <mailto:linux-block+unsubscribe@vger.kernel.org>
+MIME-Version: 1.0
+Content-Disposition: inline
+In-Reply-To: <cover.1722365899.git.daniel@makrotopia.org>
Add notifier block to notify other subsystems about the addition or
removal of block devices.
@@ -10,9 +37,9 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
block/Kconfig | 6 +++
block/Makefile | 1 +
- block/blk-notify.c | 88 ++++++++++++++++++++++++++++++++++++++++++
- include/linux/blkdev.h | 8 ++++
- 4 files changed, 103 insertions(+)
+ block/blk-notify.c | 87 ++++++++++++++++++++++++++++++++++++++++++
+ include/linux/blkdev.h | 11 ++++++
+ 4 files changed, 105 insertions(+)
create mode 100644 block/blk-notify.c
--- a/block/Kconfig
@@ -39,7 +66,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+obj-$(CONFIG_BLOCK_NOTIFIERS) += blk-notify.o
--- /dev/null
+++ b/block/blk-notify.c
-@@ -0,0 +1,88 @@
+@@ -0,0 +1,87 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Notifiers for addition and removal of block devices
@@ -97,7 +124,6 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+ list_add_tail(&new_blkdev->list, &blk_devices);
+ raw_notifier_call_chain(&blk_notifier_list, BLK_DEVICE_ADD, dev);
+ mutex_unlock(&blk_notifier_lock);
-+
+ return 0;
+}
+
@@ -130,16 +156,19 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+device_initcall(blk_notifications_init);
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
-@@ -1564,4 +1564,12 @@ struct io_comp_batch {
+@@ -1564,4 +1564,15 @@ struct io_comp_batch {
#define DEFINE_IO_COMP_BATCH(name) struct io_comp_batch name = { }
+
-+#ifdef CONFIG_BLOCK_NOTIFIERS
+#define BLK_DEVICE_ADD 1
+#define BLK_DEVICE_REMOVE 2
++#if defined(CONFIG_BLOCK_NOTIFIERS)
+void blk_register_notify(struct notifier_block *nb);
+void blk_unregister_notify(struct notifier_block *nb);
++#else
++static inline void blk_register_notify(struct notifier_block *nb) { };
++static inline void blk_unregister_notify(struct notifier_block *nb) { };
+#endif
+
#endif /* _LINUX_BLKDEV_H */
diff --git a/target/linux/generic/pending-6.6/453-block-add-new-genhd-flag-GENHD_FL_NVMEM.patch b/target/linux/generic/pending-6.6/453-block-add-new-genhd-flag-GENHD_FL_NVMEM.patch
index 5997680e47..79abcd0e6b 100644
--- a/target/linux/generic/pending-6.6/453-block-add-new-genhd-flag-GENHD_FL_NVMEM.patch
+++ b/target/linux/generic/pending-6.6/453-block-add-new-genhd-flag-GENHD_FL_NVMEM.patch
@@ -1,7 +1,34 @@
-From f4487fa1cb7e55b3c17a33f41b9c9d66f4f853b7 Mon Sep 17 00:00:00 2001
+From patchwork Tue Jul 30 19:27:07 2024
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org>
+X-Patchwork-Id: 13747818
+Date: Tue, 30 Jul 2024 20:27:07 +0100
From: Daniel Golle <daniel@makrotopia.org>
-Date: Thu, 30 May 2024 03:14:49 +0100
-Subject: [PATCH 4/9] block: add new genhd flag GENHD_FL_NVMEM
+To: Rob Herring <robh@kernel.org>, Krzysztof Kozlowski <krzk+dt@kernel.org>,
+ Conor Dooley <conor+dt@kernel.org>, Jens Axboe <axboe@kernel.dk>,
+ Daniel Golle <daniel@makrotopia.org>, Christian Brauner <brauner@kernel.org>,
+ Al Viro <viro@zeniv.linux.org.uk>, Li Lingfeng <lilingfeng3@huawei.com>,
+ Ming Lei <ming.lei@redhat.com>, Christian Heusel <christian@heusel.eu>,
+ =?utf-8?b?UmFmYcWCIE1pxYJlY2tp?= <rafal@milecki.pl>,
+ Felix Fietkau <nbd@nbd.name>, John Crispin <john@phrozen.org>,
+ Chad Monroe <chad.monroe@adtran.com>, Yangyu Chen <cyy@cyyself.name>,
+ Tianling Shen <cnsztl@immortalwrt.org>, Chuanhong Guo <gch981213@gmail.com>,
+ Chen Minqiang <ptpt52@gmail.com>, devicetree@vger.kernel.org,
+ linux-kernel@vger.kernel.org, linux-block@vger.kernel.org
+Subject: [PATCH v5 4/4] block: add new genhd flag GENHD_FL_NVMEM
+Message-ID:
+ <311ea569c23ce14e2896cd3b069dc494c58c49c2.1722365899.git.daniel@makrotopia.org>
+References: <cover.1722365899.git.daniel@makrotopia.org>
+Precedence: bulk
+X-Mailing-List: linux-block@vger.kernel.org
+List-Id: <linux-block.vger.kernel.org>
+List-Subscribe: <mailto:linux-block+subscribe@vger.kernel.org>
+List-Unsubscribe: <mailto:linux-block+unsubscribe@vger.kernel.org>
+MIME-Version: 1.0
+Content-Disposition: inline
+In-Reply-To: <cover.1722365899.git.daniel@makrotopia.org>
Add new flag to destinguish block devices which may act as an NVMEM
provider.
diff --git a/target/linux/generic/pending-6.6/489-mtd-spinand-winbond-add-support-for-W25N01KV.patch b/target/linux/generic/pending-6.6/489-mtd-spinand-winbond-add-support-for-W25N01KV.patch
new file mode 100644
index 0000000000..78498af1ce
--- /dev/null
+++ b/target/linux/generic/pending-6.6/489-mtd-spinand-winbond-add-support-for-W25N01KV.patch
@@ -0,0 +1,63 @@
+From 446daf20b0a6790751459cdde0ff9fc8813e54d1 Mon Sep 17 00:00:00 2001
+From: Robert Marko <robimarko@gmail.com>
+Date: Mon, 29 Jul 2024 14:09:16 +0200
+Subject: [PATCH] mtd: spinand: winbond: add support for W25N01KV
+
+Add support for Winbond W25N01KV 1Gbit SPI-NAND.
+
+It has 4-bit on-die ECC.
+
+Signed-off-by: Robert Marko <robimarko@gmail.com>
+---
+ drivers/mtd/nand/spi/winbond.c | 26 ++++++++++++++++++++++++++
+ 1 file changed, 26 insertions(+)
+
+--- a/drivers/mtd/nand/spi/winbond.c
++++ b/drivers/mtd/nand/spi/winbond.c
+@@ -74,6 +74,18 @@ static int w25m02gv_select_target(struct
+ return spi_mem_exec_op(spinand->spimem, &op);
+ }
+
++static int w25n01kv_ooblayout_ecc(struct mtd_info *mtd, int section,
++ struct mtd_oob_region *region)
++{
++ if (section > 3)
++ return -ERANGE;
++
++ region->offset = 64 + (8 * section);
++ region->length = 7;
++
++ return 0;
++}
++
+ static int w25n02kv_ooblayout_ecc(struct mtd_info *mtd, int section,
+ struct mtd_oob_region *region)
+ {
+@@ -98,6 +110,11 @@ static int w25n02kv_ooblayout_free(struc
+ return 0;
+ }
+
++static const struct mtd_ooblayout_ops w25n01kv_ooblayout = {
++ .ecc = w25n01kv_ooblayout_ecc,
++ .free = w25n02kv_ooblayout_free,
++};
++
+ static const struct mtd_ooblayout_ops w25n02kv_ooblayout = {
+ .ecc = w25n02kv_ooblayout_ecc,
+ .free = w25n02kv_ooblayout_free,
+@@ -160,6 +177,15 @@ static const struct spinand_info winbond
+ &update_cache_variants),
+ 0,
+ SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL)),
++ SPINAND_INFO("W25N01KV",
++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xae, 0x21),
++ NAND_MEMORG(1, 2048, 96, 64, 1024, 20, 1, 1, 1),
++ NAND_ECCREQ(4, 512),
++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
++ &write_cache_variants,
++ &update_cache_variants),
++ 0,
++ SPINAND_ECCINFO(&w25n01kv_ooblayout, w25n02kv_ecc_get_status)),
+ SPINAND_INFO("W25N02KV",
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa, 0x22),
+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
diff --git a/target/linux/generic/pending-6.6/491-ubi-auto-create-ubiblock-device-for-rootfs.patch b/target/linux/generic/pending-6.6/491-ubi-auto-create-ubiblock-device-for-rootfs.patch
index 6081d1d9e5..0b607faa5e 100644
--- a/target/linux/generic/pending-6.6/491-ubi-auto-create-ubiblock-device-for-rootfs.patch
+++ b/target/linux/generic/pending-6.6/491-ubi-auto-create-ubiblock-device-for-rootfs.patch
@@ -24,7 +24,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+ return magic == UBIFS_NODE_MAGIC;
+}
+
-+static void __init ubiblock_create_auto_rootfs(struct ubi_volume_info *vi)
++static void ubiblock_create_auto_rootfs(struct ubi_volume_info *vi)
+{
+ int ret, is_ubifs;
+ struct ubi_volume_desc *desc;
diff --git a/target/linux/generic/pending-6.6/510-block-add-uImage.FIT-subimage-block-driver.patch b/target/linux/generic/pending-6.6/510-block-add-uImage.FIT-subimage-block-driver.patch
index 5cc85083d2..ff38964ece 100644
--- a/target/linux/generic/pending-6.6/510-block-add-uImage.FIT-subimage-block-driver.patch
+++ b/target/linux/generic/pending-6.6/510-block-add-uImage.FIT-subimage-block-driver.patch
@@ -36,7 +36,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
--- a/MAINTAINERS
+++ b/MAINTAINERS
-@@ -22014,6 +22014,12 @@ F: Documentation/filesystems/ubifs-authe
+@@ -22015,6 +22015,12 @@ F: Documentation/filesystems/ubifs-authe
F: Documentation/filesystems/ubifs.rst
F: fs/ubifs/
diff --git a/target/linux/generic/pending-6.6/630-packet_socket_type.patch b/target/linux/generic/pending-6.6/630-packet_socket_type.patch
index fd00e1e052..2b753efa67 100644
--- a/target/linux/generic/pending-6.6/630-packet_socket_type.patch
+++ b/target/linux/generic/pending-6.6/630-packet_socket_type.patch
@@ -30,7 +30,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
#define PACKET_FANOUT_LB 1
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
-@@ -1864,6 +1864,7 @@ static int packet_rcv_spkt(struct sk_buf
+@@ -1925,6 +1925,7 @@ static int packet_rcv_spkt(struct sk_buf
{
struct sock *sk;
struct sockaddr_pkt *spkt;
@@ -38,7 +38,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
/*
* When we registered the protocol we saved the socket in the data
-@@ -1871,6 +1872,7 @@ static int packet_rcv_spkt(struct sk_buf
+@@ -1932,6 +1933,7 @@ static int packet_rcv_spkt(struct sk_buf
*/
sk = pt->af_packet_priv;
@@ -46,7 +46,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
/*
* Yank back the headers [hope the device set this
-@@ -1883,7 +1885,7 @@ static int packet_rcv_spkt(struct sk_buf
+@@ -1944,7 +1946,7 @@ static int packet_rcv_spkt(struct sk_buf
* so that this procedure is noop.
*/
@@ -55,7 +55,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
goto out;
if (!net_eq(dev_net(dev), sock_net(sk)))
-@@ -2129,12 +2131,12 @@ static int packet_rcv(struct sk_buff *sk
+@@ -2190,12 +2192,12 @@ static int packet_rcv(struct sk_buff *sk
unsigned int snaplen, res;
bool is_drop_n_account = false;
@@ -71,7 +71,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
if (!net_eq(dev_net(dev), sock_net(sk)))
goto drop;
-@@ -2261,12 +2263,12 @@ static int tpacket_rcv(struct sk_buff *s
+@@ -2322,12 +2324,12 @@ static int tpacket_rcv(struct sk_buff *s
BUILD_BUG_ON(TPACKET_ALIGN(sizeof(*h.h2)) != 32);
BUILD_BUG_ON(TPACKET_ALIGN(sizeof(*h.h3)) != 48);
@@ -87,7 +87,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
if (!net_eq(dev_net(dev), sock_net(sk)))
goto drop;
-@@ -3385,6 +3387,7 @@ static int packet_create(struct net *net
+@@ -3451,6 +3453,7 @@ static int packet_create(struct net *net
mutex_init(&po->pg_vec_lock);
po->rollover = NULL;
po->prot_hook.func = packet_rcv;
@@ -95,7 +95,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
if (sock->type == SOCK_PACKET)
po->prot_hook.func = packet_rcv_spkt;
-@@ -4036,6 +4039,16 @@ packet_setsockopt(struct socket *sock, i
+@@ -4118,6 +4121,16 @@ packet_setsockopt(struct socket *sock, i
packet_sock_flag_set(po, PACKET_SOCK_QDISC_BYPASS, val);
return 0;
}
@@ -112,7 +112,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
default:
return -ENOPROTOOPT;
}
-@@ -4095,6 +4108,13 @@ static int packet_getsockopt(struct sock
+@@ -4177,6 +4190,13 @@ static int packet_getsockopt(struct sock
case PACKET_VNET_HDR_SZ:
val = READ_ONCE(po->vnet_hdr_sz);
break;
diff --git a/target/linux/generic/pending-6.6/640-net-bridge-fix-switchdev-host-mdb-entry-updates.patch b/target/linux/generic/pending-6.6/640-net-bridge-fix-switchdev-host-mdb-entry-updates.patch
new file mode 100644
index 0000000000..cf55c6a3fb
--- /dev/null
+++ b/target/linux/generic/pending-6.6/640-net-bridge-fix-switchdev-host-mdb-entry-updates.patch
@@ -0,0 +1,42 @@
+From: Felix Fietkau <nbd@nbd.name>
+Date: Thu, 22 Aug 2024 18:02:17 +0200
+Subject: [PATCH] net: bridge: fix switchdev host mdb entry updates
+
+When a mdb entry is removed, the bridge switchdev code can issue a
+switchdev_port_obj_del call for a port that was not offloaded.
+
+This leads to an imbalance in switchdev_port_obj_add/del calls, since
+br_switchdev_mdb_replay has not been called for the port before.
+
+This can lead to potential multicast forwarding issues and messages such as:
+mt7915e 0000:01:00.0 wl1-ap0: Failed to del Host Multicast Database entry
+ (object id=3) with error: -ENOENT (-2).
+
+Fix this issue by checking the port offload status when iterating over
+lower devs.
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/net/bridge/br_switchdev.c
++++ b/net/bridge/br_switchdev.c
+@@ -568,10 +568,18 @@ static void br_switchdev_host_mdb(struct
+ struct net_bridge_mdb_entry *mp, int type)
+ {
+ struct net_device *lower_dev;
++ struct net_bridge_port *port;
+ struct list_head *iter;
+
+- netdev_for_each_lower_dev(dev, lower_dev, iter)
++ rcu_read_lock();
++ netdev_for_each_lower_dev(dev, lower_dev, iter) {
++ port = br_port_get_rcu(lower_dev);
++ if (!port || !port->offload_count)
++ continue;
++
+ br_switchdev_host_mdb_one(dev, lower_dev, mp, type);
++ }
++ rcu_read_unlock();
+ }
+
+ static int
diff --git a/target/linux/generic/pending-6.6/666-Add-support-for-MAP-E-FMRs-mesh-mode.patch b/target/linux/generic/pending-6.6/666-Add-support-for-MAP-E-FMRs-mesh-mode.patch
index 0d65fa7272..863372ea87 100644
--- a/target/linux/generic/pending-6.6/666-Add-support-for-MAP-E-FMRs-mesh-mode.patch
+++ b/target/linux/generic/pending-6.6/666-Add-support-for-MAP-E-FMRs-mesh-mode.patch
@@ -338,7 +338,7 @@ Signed-off-by: Steven Barth <cyrus@openwrt.org>
if (iptunnel_handle_offloads(skb, SKB_GSO_IPXIP6))
return -1;
-@@ -1543,6 +1704,14 @@ ip6_tnl_change(struct ip6_tnl *t, const
+@@ -1544,6 +1705,14 @@ ip6_tnl_change(struct ip6_tnl *t, const
t->parms.link = p->link;
t->parms.proto = p->proto;
t->parms.fwmark = p->fwmark;
@@ -353,7 +353,7 @@ Signed-off-by: Steven Barth <cyrus@openwrt.org>
dst_cache_reset(&t->dst_cache);
ip6_tnl_link_config(t);
}
-@@ -1577,6 +1746,7 @@ ip6_tnl_parm_from_user(struct __ip6_tnl_
+@@ -1578,6 +1747,7 @@ ip6_tnl_parm_from_user(struct __ip6_tnl_
p->flowinfo = u->flowinfo;
p->link = u->link;
p->proto = u->proto;
@@ -361,7 +361,7 @@ Signed-off-by: Steven Barth <cyrus@openwrt.org>
memcpy(p->name, u->name, sizeof(u->name));
}
-@@ -1964,6 +2134,15 @@ static int ip6_tnl_validate(struct nlatt
+@@ -1966,6 +2136,15 @@ static int ip6_tnl_validate(struct nlatt
return 0;
}
@@ -377,7 +377,7 @@ Signed-off-by: Steven Barth <cyrus@openwrt.org>
static void ip6_tnl_netlink_parms(struct nlattr *data[],
struct __ip6_tnl_parm *parms)
{
-@@ -2001,6 +2180,46 @@ static void ip6_tnl_netlink_parms(struct
+@@ -2003,6 +2182,46 @@ static void ip6_tnl_netlink_parms(struct
if (data[IFLA_IPTUN_FWMARK])
parms->fwmark = nla_get_u32(data[IFLA_IPTUN_FWMARK]);
@@ -424,7 +424,7 @@ Signed-off-by: Steven Barth <cyrus@openwrt.org>
}
static int ip6_tnl_newlink(struct net *src_net, struct net_device *dev,
-@@ -2084,6 +2303,12 @@ static void ip6_tnl_dellink(struct net_d
+@@ -2086,6 +2305,12 @@ static void ip6_tnl_dellink(struct net_d
static size_t ip6_tnl_get_size(const struct net_device *dev)
{
@@ -437,7 +437,7 @@ Signed-off-by: Steven Barth <cyrus@openwrt.org>
return
/* IFLA_IPTUN_LINK */
nla_total_size(4) +
-@@ -2113,6 +2338,24 @@ static size_t ip6_tnl_get_size(const str
+@@ -2115,6 +2340,24 @@ static size_t ip6_tnl_get_size(const str
nla_total_size(0) +
/* IFLA_IPTUN_FWMARK */
nla_total_size(4) +
@@ -462,7 +462,7 @@ Signed-off-by: Steven Barth <cyrus@openwrt.org>
0;
}
-@@ -2120,6 +2363,9 @@ static int ip6_tnl_fill_info(struct sk_b
+@@ -2122,6 +2365,9 @@ static int ip6_tnl_fill_info(struct sk_b
{
struct ip6_tnl *tunnel = netdev_priv(dev);
struct __ip6_tnl_parm *parm = &tunnel->parms;
@@ -472,7 +472,7 @@ Signed-off-by: Steven Barth <cyrus@openwrt.org>
if (nla_put_u32(skb, IFLA_IPTUN_LINK, parm->link) ||
nla_put_in6_addr(skb, IFLA_IPTUN_LOCAL, &parm->laddr) ||
-@@ -2129,9 +2375,27 @@ static int ip6_tnl_fill_info(struct sk_b
+@@ -2131,9 +2377,27 @@ static int ip6_tnl_fill_info(struct sk_b
nla_put_be32(skb, IFLA_IPTUN_FLOWINFO, parm->flowinfo) ||
nla_put_u32(skb, IFLA_IPTUN_FLAGS, parm->flags) ||
nla_put_u8(skb, IFLA_IPTUN_PROTO, parm->proto) ||
@@ -501,7 +501,7 @@ Signed-off-by: Steven Barth <cyrus@openwrt.org>
if (nla_put_u16(skb, IFLA_IPTUN_ENCAP_TYPE, tunnel->encap.type) ||
nla_put_be16(skb, IFLA_IPTUN_ENCAP_SPORT, tunnel->encap.sport) ||
nla_put_be16(skb, IFLA_IPTUN_ENCAP_DPORT, tunnel->encap.dport) ||
-@@ -2171,6 +2435,7 @@ static const struct nla_policy ip6_tnl_p
+@@ -2173,6 +2437,7 @@ static const struct nla_policy ip6_tnl_p
[IFLA_IPTUN_ENCAP_DPORT] = { .type = NLA_U16 },
[IFLA_IPTUN_COLLECT_METADATA] = { .type = NLA_FLAG },
[IFLA_IPTUN_FWMARK] = { .type = NLA_U32 },
diff --git a/target/linux/generic/pending-6.6/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch b/target/linux/generic/pending-6.6/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch
index cc92e20f63..f754705dc6 100644
--- a/target/linux/generic/pending-6.6/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch
+++ b/target/linux/generic/pending-6.6/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch
@@ -66,7 +66,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
static void rt_fibinfo_free(struct rtable __rcu **rtp)
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
-@@ -2783,6 +2783,7 @@ static const char *const rtn_type_names[
+@@ -2784,6 +2784,7 @@ static const char *const rtn_type_names[
[RTN_THROW] = "THROW",
[RTN_NAT] = "NAT",
[RTN_XRESOLVE] = "XRESOLVE",
diff --git a/target/linux/generic/pending-6.6/680-net-add-TCP-fraglist-GRO-support.patch b/target/linux/generic/pending-6.6/680-net-add-TCP-fraglist-GRO-support.patch
index 7672f46d20..68ebf4e68a 100644
--- a/target/linux/generic/pending-6.6/680-net-add-TCP-fraglist-GRO-support.patch
+++ b/target/linux/generic/pending-6.6/680-net-add-TCP-fraglist-GRO-support.patch
@@ -31,7 +31,7 @@ Signe-off-by: Felix Fietkau <nbd@nbd.name>
static inline void gro_normal_list(struct napi_struct *napi)
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
-@@ -2083,7 +2083,10 @@ void tcp_v4_destroy_sock(struct sock *sk
+@@ -2084,7 +2084,10 @@ void tcp_v4_destroy_sock(struct sock *sk
struct sk_buff *tcp_gso_segment(struct sk_buff *skb,
netdev_features_t features);
@@ -162,7 +162,7 @@ Signe-off-by: Felix Fietkau <nbd@nbd.name>
if (unlikely(skb->ip_summed != CHECKSUM_PARTIAL)) {
const struct iphdr *iph = ip_hdr(skb);
struct tcphdr *th = tcp_hdr(skb);
-@@ -178,61 +245,76 @@ out:
+@@ -181,61 +248,76 @@ out:
return segs;
}
@@ -269,7 +269,7 @@ Signe-off-by: Felix Fietkau <nbd@nbd.name>
flush = NAPI_GRO_CB(p)->flush;
flush |= (__force int)(flags & TCP_FLAG_CWR);
flush |= (__force int)((flags ^ tcp_flag_word(th2)) &
-@@ -269,6 +351,19 @@ found:
+@@ -272,6 +354,19 @@ found:
flush |= p->decrypted ^ skb->decrypted;
#endif
@@ -289,7 +289,7 @@ Signe-off-by: Felix Fietkau <nbd@nbd.name>
if (flush || skb_gro_receive(p, skb)) {
mss = 1;
goto out_check_final;
-@@ -290,7 +385,6 @@ out_check_final:
+@@ -293,7 +388,6 @@ out_check_final:
if (p && (!NAPI_GRO_CB(skb)->same_flow || flush))
pp = p;
@@ -297,7 +297,7 @@ Signe-off-by: Felix Fietkau <nbd@nbd.name>
NAPI_GRO_CB(skb)->flush |= (flush != 0);
return pp;
-@@ -314,18 +408,58 @@ void tcp_gro_complete(struct sk_buff *sk
+@@ -317,18 +411,58 @@ void tcp_gro_complete(struct sk_buff *sk
}
EXPORT_SYMBOL(tcp_gro_complete);
@@ -361,7 +361,7 @@ Signe-off-by: Felix Fietkau <nbd@nbd.name>
}
INDIRECT_CALLABLE_SCOPE int tcp4_gro_complete(struct sk_buff *skb, int thoff)
-@@ -333,6 +467,15 @@ INDIRECT_CALLABLE_SCOPE int tcp4_gro_com
+@@ -336,6 +470,15 @@ INDIRECT_CALLABLE_SCOPE int tcp4_gro_com
const struct iphdr *iph = ip_hdr(skb);
struct tcphdr *th = tcp_hdr(skb);
@@ -379,7 +379,7 @@ Signe-off-by: Felix Fietkau <nbd@nbd.name>
skb_shinfo(skb)->gso_type |= SKB_GSO_TCPV4;
--- a/net/ipv4/udp_offload.c
+++ b/net/ipv4/udp_offload.c
-@@ -433,33 +433,6 @@ out:
+@@ -452,33 +452,6 @@ out:
return segs;
}
diff --git a/target/linux/generic/pending-6.6/681-net-remove-NETIF_F_GSO_FRAGLIST-from-NETIF_F_GSO_SOF.patch b/target/linux/generic/pending-6.6/681-net-remove-NETIF_F_GSO_FRAGLIST-from-NETIF_F_GSO_SOF.patch
new file mode 100644
index 0000000000..85d2ac21b1
--- /dev/null
+++ b/target/linux/generic/pending-6.6/681-net-remove-NETIF_F_GSO_FRAGLIST-from-NETIF_F_GSO_SOF.patch
@@ -0,0 +1,129 @@
+From: Felix Fietkau <nbd@nbd.name>
+Date: Thu, 15 Aug 2024 21:15:13 +0200
+Subject: [PATCH] net: remove NETIF_F_GSO_FRAGLIST from NETIF_F_GSO_SOFTWARE
+
+Several drivers set NETIF_F_GSO_SOFTWARE, but mangle fraglist GRO packets
+in a way that they can't be properly segmented anymore.
+In order to properly deal with this, remove fraglist GSO from
+NETIF_F_GSO_SOFTWARE and switch to NETIF_F_GSO_SOFTWARE_ALL (which includes
+fraglist GSO) in places where it's safe to add.
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/drivers/net/dummy.c
++++ b/drivers/net/dummy.c
+@@ -118,7 +118,7 @@ static void dummy_setup(struct net_devic
+ dev->flags &= ~IFF_MULTICAST;
+ dev->priv_flags |= IFF_LIVE_ADDR_CHANGE | IFF_NO_QUEUE;
+ dev->features |= NETIF_F_SG | NETIF_F_FRAGLIST;
+- dev->features |= NETIF_F_GSO_SOFTWARE;
++ dev->features |= NETIF_F_GSO_SOFTWARE_ALL;
+ dev->features |= NETIF_F_HW_CSUM | NETIF_F_HIGHDMA | NETIF_F_LLTX;
+ dev->features |= NETIF_F_GSO_ENCAP_ALL;
+ dev->hw_features |= dev->features;
+--- a/drivers/net/loopback.c
++++ b/drivers/net/loopback.c
+@@ -176,7 +176,7 @@ static void gen_lo_setup(struct net_devi
+ dev->flags = IFF_LOOPBACK;
+ dev->priv_flags |= IFF_LIVE_ADDR_CHANGE | IFF_NO_QUEUE;
+ netif_keep_dst(dev);
+- dev->hw_features = NETIF_F_GSO_SOFTWARE;
++ dev->hw_features = NETIF_F_GSO_SOFTWARE_ALL;
+ dev->features = NETIF_F_SG | NETIF_F_FRAGLIST
+ | NETIF_F_GSO_SOFTWARE
+ | NETIF_F_HW_CSUM
+--- a/drivers/net/macvlan.c
++++ b/drivers/net/macvlan.c
+@@ -896,7 +896,7 @@ static int macvlan_hwtstamp_set(struct n
+ static struct lock_class_key macvlan_netdev_addr_lock_key;
+
+ #define ALWAYS_ON_OFFLOADS \
+- (NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_GSO_SOFTWARE | \
++ (NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_GSO_SOFTWARE_ALL | \
+ NETIF_F_GSO_ROBUST | NETIF_F_GSO_ENCAP_ALL)
+
+ #define ALWAYS_ON_FEATURES (ALWAYS_ON_OFFLOADS | NETIF_F_LLTX)
+--- a/include/linux/netdev_features.h
++++ b/include/linux/netdev_features.h
+@@ -219,13 +219,14 @@ static inline int find_next_netdev_featu
+
+ /* List of features with software fallbacks. */
+ #define NETIF_F_GSO_SOFTWARE (NETIF_F_ALL_TSO | NETIF_F_GSO_SCTP | \
+- NETIF_F_GSO_UDP_L4 | NETIF_F_GSO_FRAGLIST)
++ NETIF_F_GSO_UDP_L4)
++#define NETIF_F_GSO_SOFTWARE_ALL (NETIF_F_GSO_SOFTWARE | NETIF_F_GSO_FRAGLIST)
+
+ /*
+ * If one device supports one of these features, then enable them
+ * for all in netdev_increment_features.
+ */
+-#define NETIF_F_ONE_FOR_ALL (NETIF_F_GSO_SOFTWARE | NETIF_F_GSO_ROBUST | \
++#define NETIF_F_ONE_FOR_ALL (NETIF_F_GSO_SOFTWARE_ALL | NETIF_F_GSO_ROBUST | \
+ NETIF_F_SG | NETIF_F_HIGHDMA | \
+ NETIF_F_FRAGLIST | NETIF_F_VLAN_CHALLENGED)
+
+--- a/net/8021q/vlan.h
++++ b/net/8021q/vlan.h
+@@ -108,7 +108,7 @@ static inline netdev_features_t vlan_tnl
+ netdev_features_t ret;
+
+ ret = real_dev->hw_enc_features &
+- (NETIF_F_CSUM_MASK | NETIF_F_GSO_SOFTWARE |
++ (NETIF_F_CSUM_MASK | NETIF_F_GSO_SOFTWARE_ALL |
+ NETIF_F_GSO_ENCAP_ALL);
+
+ if ((ret & NETIF_F_GSO_ENCAP_ALL) && (ret & NETIF_F_CSUM_MASK))
+--- a/net/8021q/vlan_dev.c
++++ b/net/8021q/vlan_dev.c
+@@ -583,7 +583,7 @@ static int vlan_dev_init(struct net_devi
+ dev->state |= (1 << __LINK_STATE_NOCARRIER);
+
+ dev->hw_features = NETIF_F_HW_CSUM | NETIF_F_SG |
+- NETIF_F_FRAGLIST | NETIF_F_GSO_SOFTWARE |
++ NETIF_F_FRAGLIST | NETIF_F_GSO_SOFTWARE_ALL |
+ NETIF_F_GSO_ENCAP_ALL |
+ NETIF_F_HIGHDMA | NETIF_F_SCTP_CRC |
+ NETIF_F_ALL_FCOE;
+@@ -676,7 +676,7 @@ static netdev_features_t vlan_dev_fix_fe
+ if (lower_features & (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM))
+ lower_features |= NETIF_F_HW_CSUM;
+ features = netdev_intersect_features(features, lower_features);
+- features |= old_features & (NETIF_F_SOFT_FEATURES | NETIF_F_GSO_SOFTWARE);
++ features |= old_features & (NETIF_F_SOFT_FEATURES | NETIF_F_GSO_SOFTWARE_ALL);
+ features |= NETIF_F_LLTX;
+
+ return features;
+--- a/net/core/sock.c
++++ b/net/core/sock.c
+@@ -2449,7 +2449,7 @@ void sk_setup_caps(struct sock *sk, stru
+ if (sk_is_tcp(sk))
+ sk->sk_route_caps |= NETIF_F_GSO;
+ if (sk->sk_route_caps & NETIF_F_GSO)
+- sk->sk_route_caps |= NETIF_F_GSO_SOFTWARE;
++ sk->sk_route_caps |= NETIF_F_GSO_SOFTWARE_ALL;
+ if (unlikely(sk->sk_gso_disabled))
+ sk->sk_route_caps &= ~NETIF_F_GSO_MASK;
+ if (sk_can_gso(sk)) {
+--- a/net/mac80211/ieee80211_i.h
++++ b/net/mac80211/ieee80211_i.h
+@@ -1996,7 +1996,7 @@ void ieee80211_color_collision_detection
+ /* interface handling */
+ #define MAC80211_SUPPORTED_FEATURES_TX (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | \
+ NETIF_F_HW_CSUM | NETIF_F_SG | \
+- NETIF_F_HIGHDMA | NETIF_F_GSO_SOFTWARE | \
++ NETIF_F_HIGHDMA | NETIF_F_GSO_SOFTWARE_ALL | \
+ NETIF_F_HW_TC)
+ #define MAC80211_SUPPORTED_FEATURES_RX (NETIF_F_RXCSUM)
+ #define MAC80211_SUPPORTED_FEATURES (MAC80211_SUPPORTED_FEATURES_TX | \
+--- a/net/openvswitch/vport-internal_dev.c
++++ b/net/openvswitch/vport-internal_dev.c
+@@ -110,7 +110,7 @@ static void do_setup(struct net_device *
+
+ netdev->features = NETIF_F_LLTX | NETIF_F_SG | NETIF_F_FRAGLIST |
+ NETIF_F_HIGHDMA | NETIF_F_HW_CSUM |
+- NETIF_F_GSO_SOFTWARE | NETIF_F_GSO_ENCAP_ALL;
++ NETIF_F_GSO_SOFTWARE_ALL | NETIF_F_GSO_ENCAP_ALL;
+
+ netdev->vlan_features = netdev->features;
+ netdev->hw_enc_features = netdev->features;
diff --git a/target/linux/generic/pending-6.6/701-netfilter-nf_tables-ignore-EOPNOTSUPP-on-flowtable-d.patch b/target/linux/generic/pending-6.6/701-netfilter-nf_tables-ignore-EOPNOTSUPP-on-flowtable-d.patch
index ca4620ef0c..827ceff18b 100644
--- a/target/linux/generic/pending-6.6/701-netfilter-nf_tables-ignore-EOPNOTSUPP-on-flowtable-d.patch
+++ b/target/linux/generic/pending-6.6/701-netfilter-nf_tables-ignore-EOPNOTSUPP-on-flowtable-d.patch
@@ -18,7 +18,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
-@@ -8267,7 +8267,7 @@ static int nft_register_flowtable_net_ho
+@@ -8322,7 +8322,7 @@ static int nft_register_flowtable_net_ho
err = flowtable->data.type->setup(&flowtable->data,
hook->ops.dev,
FLOW_BLOCK_BIND);
diff --git a/target/linux/generic/pending-6.6/720-01-net-phy-realtek-use-genphy_soft_reset-for-2.5G-PHYs.patch b/target/linux/generic/pending-6.6/720-01-net-phy-realtek-use-genphy_soft_reset-for-2.5G-PHYs.patch
new file mode 100644
index 0000000000..fe8ee7b5fa
--- /dev/null
+++ b/target/linux/generic/pending-6.6/720-01-net-phy-realtek-use-genphy_soft_reset-for-2.5G-PHYs.patch
@@ -0,0 +1,81 @@
+From 85cd45580f5e3b26068cccb7d6173f200e754dc0 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Sun, 2 Apr 2023 23:56:16 +0100
+Subject: [PATCH 1/2] net: phy: realtek: use genphy_soft_reset for 2.5G PHYs
+
+Some vendor bootloaders do weird things with those PHYs which result in
+link modes being reported wrongly. Start from a clean sheet by resetting
+the PHY.
+
+Reported-by: Yevhen Kolomeiko <jarvis2709@gmail.com>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ drivers/net/phy/realtek.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/net/phy/realtek.c
++++ b/drivers/net/phy/realtek.c
+@@ -1325,6 +1325,7 @@ static struct phy_driver realtek_drvs[]
+ }, {
+ .name = "RTL8226 2.5Gbps PHY",
+ .match_phy_device = rtl8226_match_phy_device,
++ .soft_reset = genphy_soft_reset,
+ .get_features = rtl822x_get_features,
+ .config_aneg = rtl822x_config_aneg,
+ .read_status = rtl822x_read_status,
+@@ -1337,6 +1338,7 @@ static struct phy_driver realtek_drvs[]
+ }, {
+ PHY_ID_MATCH_EXACT(0x001cc840),
+ .name = "RTL8226B_RTL8221B 2.5Gbps PHY",
++ .soft_reset = genphy_soft_reset,
+ .get_features = rtl822x_get_features,
+ .config_aneg = rtl822x_config_aneg,
+ .config_init = rtl822xb_config_init,
+@@ -1351,6 +1353,7 @@ static struct phy_driver realtek_drvs[]
+ }, {
+ PHY_ID_MATCH_EXACT(0x001cc838),
+ .name = "RTL8226-CG 2.5Gbps PHY",
++ .soft_reset = genphy_soft_reset,
+ .get_features = rtl822x_get_features,
+ .config_aneg = rtl822x_config_aneg,
+ .read_status = rtl822x_read_status,
+@@ -1361,6 +1364,7 @@ static struct phy_driver realtek_drvs[]
+ }, {
+ PHY_ID_MATCH_EXACT(0x001cc848),
+ .name = "RTL8226B-CG_RTL8221B-CG 2.5Gbps PHY",
++ .soft_reset = genphy_soft_reset,
+ .get_features = rtl822x_get_features,
+ .config_aneg = rtl822x_config_aneg,
+ .config_init = rtl822xb_config_init,
+@@ -1373,6 +1377,7 @@ static struct phy_driver realtek_drvs[]
+ }, {
+ .match_phy_device = rtl8221b_vb_cg_c22_match_phy_device,
+ .name = "RTL8221B-VB-CG 2.5Gbps PHY (C22)",
++ .soft_reset = genphy_soft_reset,
+ .get_features = rtl822x_get_features,
+ .config_aneg = rtl822x_config_aneg,
+ .config_init = rtl822xb_config_init,
+@@ -1385,6 +1390,7 @@ static struct phy_driver realtek_drvs[]
+ }, {
+ .match_phy_device = rtl8221b_vb_cg_c45_match_phy_device,
+ .name = "RTL8221B-VB-CG 2.5Gbps PHY (C45)",
++ .soft_reset = genphy_soft_reset,
+ .config_init = rtl822xb_config_init,
+ .get_rate_matching = rtl822xb_get_rate_matching,
+ .get_features = rtl822x_c45_get_features,
+@@ -1395,6 +1401,7 @@ static struct phy_driver realtek_drvs[]
+ }, {
+ .match_phy_device = rtl8221b_vn_cg_c22_match_phy_device,
+ .name = "RTL8221B-VM-CG 2.5Gbps PHY (C22)",
++ .soft_reset = genphy_soft_reset,
+ .get_features = rtl822x_get_features,
+ .config_aneg = rtl822x_config_aneg,
+ .config_init = rtl822xb_config_init,
+@@ -1407,6 +1414,7 @@ static struct phy_driver realtek_drvs[]
+ }, {
+ .match_phy_device = rtl8221b_vn_cg_c45_match_phy_device,
+ .name = "RTL8221B-VN-CG 2.5Gbps PHY (C45)",
++ .soft_reset = genphy_soft_reset,
+ .config_init = rtl822xb_config_init,
+ .get_rate_matching = rtl822xb_get_rate_matching,
+ .get_features = rtl822x_c45_get_features,
diff --git a/target/linux/generic/pending-6.6/720-02-net-phy-realtek-disable-SGMII-in-band-AN-for-2-5G-PHYs.patch b/target/linux/generic/pending-6.6/720-02-net-phy-realtek-disable-SGMII-in-band-AN-for-2-5G-PHYs.patch
new file mode 100644
index 0000000000..0c729acb7f
--- /dev/null
+++ b/target/linux/generic/pending-6.6/720-02-net-phy-realtek-disable-SGMII-in-band-AN-for-2-5G-PHYs.patch
@@ -0,0 +1,63 @@
+From d54ef6aea00e7a6ace439baade6ad0aa38ee4b04 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Mon, 3 Apr 2023 01:21:57 +0300
+Subject: [PATCH 287/326] net: phy: realtek: disable SGMII in-band AN for 2.5G
+ PHYs
+
+MAC drivers don't use SGMII in-band autonegotiation unless told to do so
+in device tree using 'managed = "in-band-status"'. When using MDIO to
+access a PHY, in-band-status is unneeded as we have link-status via
+MDIO. Switch off SGMII in-band autonegotiation using magic values.
+
+Reported-by: Chen Minqiang <ptpt52@gmail.com>
+Reported-by: Chukun Pan <amadeus@jmu.edu.cn>
+Reported-by: Yevhen Kolomeiko <jarvis2709@gmail.com>
+Tested-by: Yevhen Kolomeiko <jarvis2709@gmail.com>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ drivers/net/phy/realtek.c | 27 +++++++++++++++++++++++++--
+ 1 file changed, 25 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/phy/realtek.c
++++ b/drivers/net/phy/realtek.c
+@@ -786,8 +786,8 @@ static int rtl822x_write_mmd(struct phy_
+ static int rtl822xb_config_init(struct phy_device *phydev)
+ {
+ bool has_2500, has_sgmii;
++ int ret, val;
+ u16 mode;
+- int ret;
+
+ has_2500 = test_bit(PHY_INTERFACE_MODE_2500BASEX,
+ phydev->host_interfaces) ||
+@@ -837,7 +837,29 @@ static int rtl822xb_config_init(struct p
+ if (ret < 0)
+ return ret;
+
+- return phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x6f11, 0x8020);
++ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x6f11, 0x8020);
++ if (ret < 0)
++ return ret;
++
++ /* Disable SGMII AN */
++ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x7588, 0x2);
++ if (ret < 0)
++ return ret;
++
++ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x7589, 0x71d0);
++ if (ret < 0)
++ return ret;
++
++ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x7587, 0x3);
++ if (ret < 0)
++ return ret;
++
++ ret = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1, 0x7587,
++ val, !(val & BIT(0)), 500, 100000, false);
++ if (ret < 0)
++ return ret;
++
++ return 0;
+ }
+
+ static int rtl822xb_get_rate_matching(struct phy_device *phydev,
diff --git a/target/linux/generic/pending-6.6/720-03-net-phy-realtek-make-sure-paged-read-is-protected-by.patch b/target/linux/generic/pending-6.6/720-03-net-phy-realtek-make-sure-paged-read-is-protected-by.patch
new file mode 100644
index 0000000000..8b8dca8f27
--- /dev/null
+++ b/target/linux/generic/pending-6.6/720-03-net-phy-realtek-make-sure-paged-read-is-protected-by.patch
@@ -0,0 +1,35 @@
+From 4dd2cc9b91ecb25f278a2c55e07e6455e9000e6b Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Sat, 22 Apr 2023 01:21:14 +0100
+Subject: [PATCH] net: phy: realtek: make sure paged read is protected by mutex
+
+As we cannot rely on phy_read_paged function before the PHY is
+identified, the paged read in rtlgen_supports_2_5gbps needs to be open
+coded as it is being called by the match_phy_device function, ie. before
+.read_page and .write_page have been populated.
+
+Make sure it is also protected by the MDIO bus mutex and use
+rtl821x_write_page instead of 3 individually locked MDIO bus operations.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ drivers/net/phy/realtek.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/phy/realtek.c
++++ b/drivers/net/phy/realtek.c
+@@ -1052,9 +1052,11 @@ static bool rtlgen_supports_2_5gbps(stru
+ {
+ int val;
+
+- phy_write(phydev, RTL821x_PAGE_SELECT, 0xa61);
+- val = phy_read(phydev, 0x13);
+- phy_write(phydev, RTL821x_PAGE_SELECT, 0);
++ mutex_lock(&phydev->mdio.bus->mdio_lock);
++ rtl821x_write_page(phydev, 0xa61);
++ val = __phy_read(phydev, 0x13);
++ rtl821x_write_page(phydev, 0);
++ mutex_unlock(&phydev->mdio.bus->mdio_lock);
+
+ return val >= 0 && val & MDIO_PMA_SPEED_2_5G;
+ }
diff --git a/target/linux/generic/pending-6.6/720-04-net-phy-realtek-use-inline-functions-for-10GbE-adver.patch b/target/linux/generic/pending-6.6/720-04-net-phy-realtek-use-inline-functions-for-10GbE-adver.patch
new file mode 100644
index 0000000000..8b20451979
--- /dev/null
+++ b/target/linux/generic/pending-6.6/720-04-net-phy-realtek-use-inline-functions-for-10GbE-adver.patch
@@ -0,0 +1,26 @@
+From 92c8b9d558160d94b981dd8a2b9c47657627ffdc Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Sat, 22 Apr 2023 01:23:08 +0100
+Subject: [PATCH 2/3] net: phy: realtek: use inline functions for 10GbE
+ advertisement
+
+Use existing generic inline functions to encode local advertisement
+of 10GbE link modes as well as to decode link-partner advertisement.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ drivers/net/phy/realtek.c | 22 +++++-----------------
+ 1 file changed, 5 insertions(+), 17 deletions(-)
+
+--- a/drivers/net/phy/realtek.c
++++ b/drivers/net/phy/realtek.c
+@@ -910,7 +910,8 @@ static int rtl822x_config_aneg(struct ph
+
+ ret = phy_modify_paged_changed(phydev, 0xa5d, 0x12,
+ MDIO_AN_10GBT_CTRL_ADV2_5G |
+- MDIO_AN_10GBT_CTRL_ADV5G,
++ MDIO_AN_10GBT_CTRL_ADV5G |
++ MDIO_AN_10GBT_CTRL_ADV10G,
+ adv);
+ if (ret < 0)
+ return ret;
diff --git a/target/linux/generic/pending-6.6/720-05-net-phy-realtek-check-validity-of-10GbE-link-partner.patch b/target/linux/generic/pending-6.6/720-05-net-phy-realtek-check-validity-of-10GbE-link-partner.patch
new file mode 100644
index 0000000000..1ba3353f19
--- /dev/null
+++ b/target/linux/generic/pending-6.6/720-05-net-phy-realtek-check-validity-of-10GbE-link-partner.patch
@@ -0,0 +1,28 @@
+From 929bb4d3cfbc7878326c0771a01a636d49c54b40 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Sat, 22 Apr 2023 01:25:39 +0100
+Subject: [PATCH 3/3] net: phy: realtek: check validity of 10GbE link-partner
+ advertisement
+
+Only use link-partner advertisement bits for 10GbE modes if they are
+actually valid. Check LOCALOK and REMOTEOK bits and clear 10GbE modes
+unless both of them are set.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ drivers/net/phy/realtek.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/net/phy/realtek.c
++++ b/drivers/net/phy/realtek.c
+@@ -950,6 +950,10 @@ static int rtl822x_read_status(struct ph
+ if (lpadv < 0)
+ return lpadv;
+
++ if (!(lpadv & MDIO_AN_10GBT_STAT_REMOK) ||
++ !(lpadv & MDIO_AN_10GBT_STAT_LOCOK))
++ lpadv = 0;
++
+ mii_10gbt_stat_mod_linkmode_lpa_t(phydev->lp_advertising,
+ lpadv);
+ }
diff --git a/target/linux/generic/pending-6.6/720-06-net-phy-realtek-introduce-rtl822x_probe.patch b/target/linux/generic/pending-6.6/720-06-net-phy-realtek-introduce-rtl822x_probe.patch
new file mode 100644
index 0000000000..ee4de599ab
--- /dev/null
+++ b/target/linux/generic/pending-6.6/720-06-net-phy-realtek-introduce-rtl822x_probe.patch
@@ -0,0 +1,100 @@
+From 9155098547fb1172d4fa536f3f6bc9d42f59d08c Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Sat, 22 Apr 2023 03:26:01 +0100
+Subject: [PATCH] net: phy: realtek: setup ALDPS on RTL822x
+
+Setup Link Down Power Saving Mode according the DTS property
+just like for RTL821x 1GE PHYs.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ drivers/net/phy/realtek.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+--- a/drivers/net/phy/realtek.c
++++ b/drivers/net/phy/realtek.c
+@@ -82,6 +82,10 @@
+
+ #define RTL822X_VND2_PHYSR 0xa434
+
++#define RTL8221B_PHYCR1 0xa430
++#define RTL8221B_PHYCR1_ALDPS_EN BIT(2)
++#define RTL8221B_PHYCR1_ALDPS_XTAL_OFF_EN BIT(12)
++
+ #define RTL8366RB_POWER_SAVE 0x15
+ #define RTL8366RB_POWER_SAVE_ON BIT(12)
+
+@@ -1107,6 +1111,25 @@ static int rtl8221b_vn_cg_c45_match_phy_
+ return rtlgen_is_c45_match(phydev, RTL_8221B_VN_CG, true);
+ }
+
++static int rtl822x_probe(struct phy_device *phydev)
++{
++ struct device *dev = &phydev->mdio.dev;
++ int val;
++
++ val = phy_read_mmd(phydev, MDIO_MMD_VEND1, RTL8221B_PHYCR1);
++ if (val < 0)
++ return val;
++
++ if (of_property_read_bool(dev->of_node, "realtek,aldps-enable"))
++ val |= RTL8221B_PHYCR1_ALDPS_EN | RTL8221B_PHYCR1_ALDPS_XTAL_OFF_EN;
++ else
++ val &= ~(RTL8221B_PHYCR1_ALDPS_EN | RTL8221B_PHYCR1_ALDPS_XTAL_OFF_EN);
++
++ phy_write_mmd(phydev, MDIO_MMD_VEND1, RTL8221B_PHYCR1, val);
++
++ return 0;
++}
++
+ static int rtlgen_resume(struct phy_device *phydev)
+ {
+ int ret = genphy_resume(phydev);
+@@ -1382,6 +1405,7 @@ static struct phy_driver realtek_drvs[]
+ }, {
+ PHY_ID_MATCH_EXACT(0x001cc838),
+ .name = "RTL8226-CG 2.5Gbps PHY",
++ .probe = rtl822x_probe,
+ .soft_reset = genphy_soft_reset,
+ .get_features = rtl822x_get_features,
+ .config_aneg = rtl822x_config_aneg,
+@@ -1393,6 +1417,7 @@ static struct phy_driver realtek_drvs[]
+ }, {
+ PHY_ID_MATCH_EXACT(0x001cc848),
+ .name = "RTL8226B-CG_RTL8221B-CG 2.5Gbps PHY",
++ .probe = rtl822x_probe,
+ .soft_reset = genphy_soft_reset,
+ .get_features = rtl822x_get_features,
+ .config_aneg = rtl822x_config_aneg,
+@@ -1406,6 +1431,7 @@ static struct phy_driver realtek_drvs[]
+ }, {
+ .match_phy_device = rtl8221b_vb_cg_c22_match_phy_device,
+ .name = "RTL8221B-VB-CG 2.5Gbps PHY (C22)",
++ .probe = rtl822x_probe,
+ .soft_reset = genphy_soft_reset,
+ .get_features = rtl822x_get_features,
+ .config_aneg = rtl822x_config_aneg,
+@@ -1419,6 +1445,7 @@ static struct phy_driver realtek_drvs[]
+ }, {
+ .match_phy_device = rtl8221b_vb_cg_c45_match_phy_device,
+ .name = "RTL8221B-VB-CG 2.5Gbps PHY (C45)",
++ .probe = rtl822x_probe,
+ .soft_reset = genphy_soft_reset,
+ .config_init = rtl822xb_config_init,
+ .get_rate_matching = rtl822xb_get_rate_matching,
+@@ -1430,6 +1457,7 @@ static struct phy_driver realtek_drvs[]
+ }, {
+ .match_phy_device = rtl8221b_vn_cg_c22_match_phy_device,
+ .name = "RTL8221B-VM-CG 2.5Gbps PHY (C22)",
++ .probe = rtl822x_probe,
+ .soft_reset = genphy_soft_reset,
+ .get_features = rtl822x_get_features,
+ .config_aneg = rtl822x_config_aneg,
+@@ -1443,6 +1471,7 @@ static struct phy_driver realtek_drvs[]
+ }, {
+ .match_phy_device = rtl8221b_vn_cg_c45_match_phy_device,
+ .name = "RTL8221B-VN-CG 2.5Gbps PHY (C45)",
++ .probe = rtl822x_probe,
+ .soft_reset = genphy_soft_reset,
+ .config_init = rtl822xb_config_init,
+ .get_rate_matching = rtl822xb_get_rate_matching,
diff --git a/target/linux/generic/pending-6.6/720-07-net-phy-realtek-detect-early-version-of-RTL8221B.patch b/target/linux/generic/pending-6.6/720-07-net-phy-realtek-detect-early-version-of-RTL8221B.patch
new file mode 100644
index 0000000000..cca5da0e13
--- /dev/null
+++ b/target/linux/generic/pending-6.6/720-07-net-phy-realtek-detect-early-version-of-RTL8221B.patch
@@ -0,0 +1,52 @@
+From 0de82310d2b32e78ff79d42c08b1122a6ede3778 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Sun, 30 Apr 2023 00:15:41 +0100
+Subject: [PATCH] net: phy: realtek: detect early version of RTL8221B
+
+Early versions (?) of the RTL8221B PHY cannot be identified in a regular
+Clause-45 bus scan as the PHY doesn't report the implemented MMDs
+correctly but returns 0 instead.
+Implement custom identify function using the PKGID instead of iterating
+over the implemented MMDs.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+[forward-port by @namiltd]
+Signed-off-by: Mieczyslaw Nalewaj <namiltd@yahoo.com>
+--- a/drivers/net/phy/realtek.c
++++ b/drivers/net/phy/realtek.c
+@@ -1085,10 +1085,32 @@ static int rtl8226_match_phy_device(stru
+ static int rtlgen_is_c45_match(struct phy_device *phydev, unsigned int id,
+ bool is_c45)
+ {
+- if (phydev->is_c45)
+- return is_c45 && (id == phydev->c45_ids.device_ids[1]);
+- else
++ if (phydev->is_c45) {
++ u32 rid;
++
++ if (!is_c45)
++ return 0;
++
++ rid = phydev->c45_ids.device_ids[1];
++ if ((rid == 0xffffffff) && phydev->mdio.bus->read_c45) {
++ int val;
++
++ val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PKGID1);
++ if (val < 0)
++ return 0;
++
++ rid = val << 16;
++ val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PKGID2);
++ if (val < 0)
++ return 0;
++
++ rid |= val;
++ }
++
++ return (id == rid);
++ } else {
+ return !is_c45 && (id == phydev->phy_id);
++ }
+ }
+
+ static int rtl8221b_vb_cg_c22_match_phy_device(struct phy_device *phydev)
diff --git a/target/linux/generic/pending-6.6/720-08-net-phy-realtek-support-interrupt-of-RTL8221B.patch b/target/linux/generic/pending-6.6/720-08-net-phy-realtek-support-interrupt-of-RTL8221B.patch
new file mode 100644
index 0000000000..ee28bfbcfc
--- /dev/null
+++ b/target/linux/generic/pending-6.6/720-08-net-phy-realtek-support-interrupt-of-RTL8221B.patch
@@ -0,0 +1,102 @@
+From d7943c31d57c11e1a517aa3ce2006fca44866870 Mon Sep 17 00:00:00 2001
+From: Jianhui Zhao <zhaojh329@gmail.com>
+Date: Sun, 24 Sep 2023 22:15:00 +0800
+Subject: [PATCH] net: phy: realtek: add interrupt support for RTL8221B
+
+This commit introduces interrupt support for RTL8221B.
+
+Signed-off-by: Jianhui Zhao <zhaojh329@gmail.com>
+---
+ drivers/net/phy/realtek.c | 47 +++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 47 insertions(+)
+
+--- a/drivers/net/phy/realtek.c
++++ b/drivers/net/phy/realtek.c
+@@ -1287,6 +1287,51 @@ static irqreturn_t rtl9000a_handle_inter
+ return IRQ_HANDLED;
+ }
+
++static int rtl8221b_ack_interrupt(struct phy_device *phydev)
++{
++ int err;
++
++ err = phy_read_mmd(phydev, MDIO_MMD_VEND2, 0xa4d4);
++
++ return (err < 0) ? err : 0;
++}
++
++static int rtl8221b_config_intr(struct phy_device *phydev)
++{
++ int err;
++
++ if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
++ err = rtl8221b_ack_interrupt(phydev);
++ if (err)
++ return err;
++
++ err = phy_write_mmd(phydev, MDIO_MMD_VEND2, 0xa4d2, 0x7ff);
++ } else {
++ err = phy_write_mmd(phydev, MDIO_MMD_VEND2, 0xa4d2, 0x0);
++ if (err)
++ return err;
++
++ err = rtl8221b_ack_interrupt(phydev);
++ }
++
++ return err;
++}
++
++static irqreturn_t rtl8221b_handle_interrupt(struct phy_device *phydev)
++{
++ int err;
++
++ err = rtl8221b_ack_interrupt(phydev);
++ if (err) {
++ phy_error(phydev);
++ return IRQ_NONE;
++ }
++
++ phy_trigger_machine(phydev);
++
++ return IRQ_HANDLED;
++}
++
+ static struct phy_driver realtek_drvs[] = {
+ {
+ PHY_ID_MATCH_EXACT(0x00008201),
+@@ -1453,6 +1498,8 @@ static struct phy_driver realtek_drvs[]
+ }, {
+ .match_phy_device = rtl8221b_vb_cg_c22_match_phy_device,
+ .name = "RTL8221B-VB-CG 2.5Gbps PHY (C22)",
++ .config_intr = rtl8221b_config_intr,
++ .handle_interrupt = rtl8221b_handle_interrupt,
+ .probe = rtl822x_probe,
+ .soft_reset = genphy_soft_reset,
+ .get_features = rtl822x_get_features,
+@@ -1467,6 +1514,8 @@ static struct phy_driver realtek_drvs[]
+ }, {
+ .match_phy_device = rtl8221b_vb_cg_c45_match_phy_device,
+ .name = "RTL8221B-VB-CG 2.5Gbps PHY (C45)",
++ .config_intr = rtl8221b_config_intr,
++ .handle_interrupt = rtl8221b_handle_interrupt,
+ .probe = rtl822x_probe,
+ .soft_reset = genphy_soft_reset,
+ .config_init = rtl822xb_config_init,
+@@ -1479,6 +1528,8 @@ static struct phy_driver realtek_drvs[]
+ }, {
+ .match_phy_device = rtl8221b_vn_cg_c22_match_phy_device,
+ .name = "RTL8221B-VM-CG 2.5Gbps PHY (C22)",
++ .config_intr = rtl8221b_config_intr,
++ .handle_interrupt = rtl8221b_handle_interrupt,
+ .probe = rtl822x_probe,
+ .soft_reset = genphy_soft_reset,
+ .get_features = rtl822x_get_features,
+@@ -1493,6 +1544,8 @@ static struct phy_driver realtek_drvs[]
+ }, {
+ .match_phy_device = rtl8221b_vn_cg_c45_match_phy_device,
+ .name = "RTL8221B-VN-CG 2.5Gbps PHY (C45)",
++ .config_intr = rtl8221b_config_intr,
++ .handle_interrupt = rtl8221b_handle_interrupt,
+ .probe = rtl822x_probe,
+ .soft_reset = genphy_soft_reset,
+ .config_init = rtl822xb_config_init,
diff --git a/target/linux/generic/pending-6.6/721-net-phy-realtek-rtl8221-allow-to-configure-SERDES-mo.patch b/target/linux/generic/pending-6.6/721-net-phy-realtek-rtl8221-allow-to-configure-SERDES-mo.patch
deleted file mode 100644
index 7e9b3660d5..0000000000
--- a/target/linux/generic/pending-6.6/721-net-phy-realtek-rtl8221-allow-to-configure-SERDES-mo.patch
+++ /dev/null
@@ -1,106 +0,0 @@
-From ace6abaa0f9203083fe4c0a6a74da2d96410b625 Mon Sep 17 00:00:00 2001
-From: Alexander Couzens <lynxis@fe80.eu>
-Date: Sat, 13 Aug 2022 12:49:33 +0200
-Subject: [PATCH 01/10] net: phy: realtek: rtl8221: allow to configure SERDES
- mode
-
-The rtl8221 supports multiple SERDES modes:
-- SGMII
-- 2500base-x
-- HiSGMII
-
-Further it supports rate adaption on SERDES links to allow
-slow ethernet speeds (10/100/1000mbit) to work on 2500base-x/HiSGMII
-links without reducing the SERDES speed.
-
-When operating without rate adapters the SERDES link will follow the
-ethernet speed.
-
-Signed-off-by: Alexander Couzens <lynxis@fe80.eu>
----
- drivers/net/phy/realtek.c | 48 +++++++++++++++++++++++++++++++++++++++
- 1 file changed, 48 insertions(+)
-
---- a/drivers/net/phy/realtek.c
-+++ b/drivers/net/phy/realtek.c
-@@ -54,6 +54,15 @@
- RTL8201F_ISR_LINK)
- #define RTL8201F_IER 0x13
-
-+#define RTL8221B_MMD_SERDES_CTRL MDIO_MMD_VEND1
-+#define RTL8221B_MMD_PHY_CTRL MDIO_MMD_VEND2
-+#define RTL8221B_SERDES_OPTION 0x697a
-+#define RTL8221B_SERDES_OPTION_MODE_MASK GENMASK(5, 0)
-+#define RTL8221B_SERDES_OPTION_MODE_2500BASEX_SGMII 0
-+#define RTL8221B_SERDES_OPTION_MODE_HISGMII_SGMII 1
-+#define RTL8221B_SERDES_OPTION_MODE_2500BASEX 2
-+#define RTL8221B_SERDES_OPTION_MODE_HISGMII 3
-+
- #define RTL8366RB_POWER_SAVE 0x15
- #define RTL8366RB_POWER_SAVE_ON BIT(12)
-
-@@ -879,6 +888,48 @@ static irqreturn_t rtl9000a_handle_inter
- return IRQ_HANDLED;
- }
-
-+static int rtl8221b_config_init(struct phy_device *phydev)
-+{
-+ u16 option_mode;
-+
-+ switch (phydev->interface) {
-+ case PHY_INTERFACE_MODE_2500BASEX:
-+ if (!phydev->is_c45) {
-+ option_mode = RTL8221B_SERDES_OPTION_MODE_2500BASEX;
-+ break;
-+ }
-+ fallthrough;
-+ case PHY_INTERFACE_MODE_SGMII:
-+ option_mode = RTL8221B_SERDES_OPTION_MODE_2500BASEX_SGMII;
-+ break;
-+ default:
-+ return 0;
-+ }
-+
-+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL,
-+ 0x75f3, 0);
-+
-+ phy_modify_mmd_changed(phydev, RTL8221B_MMD_SERDES_CTRL,
-+ RTL8221B_SERDES_OPTION,
-+ RTL8221B_SERDES_OPTION_MODE_MASK, option_mode);
-+ switch (option_mode) {
-+ case RTL8221B_SERDES_OPTION_MODE_2500BASEX_SGMII:
-+ case RTL8221B_SERDES_OPTION_MODE_2500BASEX:
-+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6a04, 0x0503);
-+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6f10, 0xd455);
-+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6f11, 0x8020);
-+ break;
-+ case RTL8221B_SERDES_OPTION_MODE_HISGMII_SGMII:
-+ case RTL8221B_SERDES_OPTION_MODE_HISGMII:
-+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6a04, 0x0503);
-+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6f10, 0xd433);
-+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6f11, 0x8020);
-+ break;
-+ }
-+
-+ return 0;
-+}
-+
- static struct phy_driver realtek_drvs[] = {
- {
- PHY_ID_MATCH_EXACT(0x00008201),
-@@ -1033,6 +1084,7 @@ static struct phy_driver realtek_drvs[]
- PHY_ID_MATCH_EXACT(0x001cc849),
- .name = "RTL8221B-VB-CG 2.5Gbps PHY",
- .get_features = rtl822x_get_features,
-+ .config_init = rtl8221b_config_init,
- .config_aneg = rtl822x_config_aneg,
- .read_status = rtl822x_read_status,
- .suspend = genphy_suspend,
-@@ -1044,6 +1096,7 @@ static struct phy_driver realtek_drvs[]
- .name = "RTL8221B-VM-CG 2.5Gbps PHY",
- .get_features = rtl822x_get_features,
- .config_aneg = rtl822x_config_aneg,
-+ .config_init = rtl8221b_config_init,
- .read_status = rtl822x_read_status,
- .suspend = genphy_suspend,
- .resume = rtlgen_resume,
diff --git a/target/linux/generic/pending-6.6/722-net-phy-realtek-support-switching-between-SGMII-and-.patch b/target/linux/generic/pending-6.6/722-net-phy-realtek-support-switching-between-SGMII-and-.patch
deleted file mode 100644
index 58bd259198..0000000000
--- a/target/linux/generic/pending-6.6/722-net-phy-realtek-support-switching-between-SGMII-and-.patch
+++ /dev/null
@@ -1,61 +0,0 @@
-From 312753d0aadba0f58841ae513b80fdbabc887523 Mon Sep 17 00:00:00 2001
-From: Chukun Pan <amadeus@jmu.edu.cn>
-Date: Wed, 8 Feb 2023 16:32:18 +0800
-Subject: [PATCH] net: phy: realtek: support switching between SGMII and
- 2500BASE-X for RTL822x series
-
-After commit ace6aba ("net: phy: realtek: rtl8221: allow to configure
-SERDES mode"), the rtl8221 phy can work in SGMII and 2500base-x modes
-respectively. So add interface automatic switching for rtl8221 phy to
-match various wire speeds.
-
-Signed-off-by: Chukun Pan <amadeus@jmu.edu.cn>
----
- drivers/net/phy/realtek.c | 26 ++++++++++++++++++++++++--
- 1 file changed, 24 insertions(+), 2 deletions(-)
-
---- a/drivers/net/phy/realtek.c
-+++ b/drivers/net/phy/realtek.c
-@@ -714,6 +714,25 @@ static int rtl822x_config_aneg(struct ph
- return __genphy_config_aneg(phydev, ret);
- }
-
-+static void rtl822x_update_interface(struct phy_device *phydev)
-+{
-+ /* Automatically switch SERDES interface between
-+ * SGMII and 2500-BaseX according to speed.
-+ */
-+ switch (phydev->speed) {
-+ case SPEED_2500:
-+ phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
-+ break;
-+ case SPEED_1000:
-+ case SPEED_100:
-+ case SPEED_10:
-+ phydev->interface = PHY_INTERFACE_MODE_SGMII;
-+ break;
-+ default:
-+ break;
-+ }
-+}
-+
- static int rtl822x_read_status(struct phy_device *phydev)
- {
- int ret;
-@@ -732,11 +751,14 @@ static int rtl822x_read_status(struct ph
- phydev->lp_advertising, lpadv & RTL_LPADV_2500FULL);
- }
-
-- ret = genphy_read_status(phydev);
-+ ret = rtlgen_read_status(phydev);
- if (ret < 0)
- return ret;
-
-- return rtlgen_get_speed(phydev);
-+ if (phydev->is_c45 && phydev->link)
-+ rtl822x_update_interface(phydev);
-+
-+ return 0;
- }
-
- static bool rtlgen_supports_2_5gbps(struct phy_device *phydev)
diff --git a/target/linux/generic/pending-6.6/724-net-phy-realtek-use-genphy_soft_reset-for-2.5G-PHYs.patch b/target/linux/generic/pending-6.6/724-net-phy-realtek-use-genphy_soft_reset-for-2.5G-PHYs.patch
deleted file mode 100644
index 8efedd3a11..0000000000
--- a/target/linux/generic/pending-6.6/724-net-phy-realtek-use-genphy_soft_reset-for-2.5G-PHYs.patch
+++ /dev/null
@@ -1,65 +0,0 @@
-From 85cd45580f5e3b26068cccb7d6173f200e754dc0 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Sun, 2 Apr 2023 23:56:16 +0100
-Subject: [PATCH 1/2] net: phy: realtek: use genphy_soft_reset for 2.5G PHYs
-
-Some vendor bootloaders do weird things with those PHYs which result in
-link modes being reported wrongly. Start from a clean sheet by resetting
-the PHY.
-
-Reported-by: Yevhen Kolomeiko <jarvis2709@gmail.com>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/phy/realtek.c | 6 ++++++
- 1 file changed, 6 insertions(+)
-
---- a/drivers/net/phy/realtek.c
-+++ b/drivers/net/phy/realtek.c
-@@ -1070,6 +1070,7 @@ static struct phy_driver realtek_drvs[]
- .write_page = rtl821x_write_page,
- .read_mmd = rtl822x_read_mmd,
- .write_mmd = rtl822x_write_mmd,
-+ .soft_reset = genphy_soft_reset,
- }, {
- PHY_ID_MATCH_EXACT(0x001cc840),
- .name = "RTL8226B_RTL8221B 2.5Gbps PHY",
-@@ -1082,6 +1083,7 @@ static struct phy_driver realtek_drvs[]
- .write_page = rtl821x_write_page,
- .read_mmd = rtl822x_read_mmd,
- .write_mmd = rtl822x_write_mmd,
-+ .soft_reset = genphy_soft_reset,
- }, {
- PHY_ID_MATCH_EXACT(0x001cc838),
- .name = "RTL8226-CG 2.5Gbps PHY",
-@@ -1092,6 +1094,7 @@ static struct phy_driver realtek_drvs[]
- .resume = rtlgen_resume,
- .read_page = rtl821x_read_page,
- .write_page = rtl821x_write_page,
-+ .soft_reset = genphy_soft_reset,
- }, {
- PHY_ID_MATCH_EXACT(0x001cc848),
- .name = "RTL8226B-CG_RTL8221B-CG 2.5Gbps PHY",
-@@ -1102,6 +1105,7 @@ static struct phy_driver realtek_drvs[]
- .resume = rtlgen_resume,
- .read_page = rtl821x_read_page,
- .write_page = rtl821x_write_page,
-+ .soft_reset = genphy_soft_reset,
- }, {
- PHY_ID_MATCH_EXACT(0x001cc849),
- .name = "RTL8221B-VB-CG 2.5Gbps PHY",
-@@ -1113,6 +1117,7 @@ static struct phy_driver realtek_drvs[]
- .resume = rtlgen_resume,
- .read_page = rtl821x_read_page,
- .write_page = rtl821x_write_page,
-+ .soft_reset = genphy_soft_reset,
- }, {
- PHY_ID_MATCH_EXACT(0x001cc84a),
- .name = "RTL8221B-VM-CG 2.5Gbps PHY",
-@@ -1124,6 +1129,7 @@ static struct phy_driver realtek_drvs[]
- .resume = rtlgen_resume,
- .read_page = rtl821x_read_page,
- .write_page = rtl821x_write_page,
-+ .soft_reset = genphy_soft_reset,
- }, {
- PHY_ID_MATCH_EXACT(0x001cc961),
- .name = "RTL8366RB Gigabit Ethernet",
diff --git a/target/linux/generic/pending-6.6/725-net-phy-realtek-disable-SGMII-in-band-AN-for-2-5G-PHYs.patch b/target/linux/generic/pending-6.6/725-net-phy-realtek-disable-SGMII-in-band-AN-for-2-5G-PHYs.patch
deleted file mode 100644
index 43cf35ab77..0000000000
--- a/target/linux/generic/pending-6.6/725-net-phy-realtek-disable-SGMII-in-band-AN-for-2-5G-PHYs.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-From 2b1b8c4c215af7988136401c902338d091d408a1 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Mon, 3 Apr 2023 01:21:57 +0300
-Subject: [PATCH 2/2] net: phy: realtek: disable SGMII in-band AN for 2.5G PHYs
-
-MAC drivers don't use SGMII in-band autonegotiation unless told to do so
-in device tree using 'managed = "in-band-status"'. When using MDIO to
-access a PHY, in-band-status is unneeded as we have link-status via
-MDIO. Switch off SGMII in-band autonegotiation using magic values.
-
-Reported-by: Chen Minqiang <ptpt52@gmail.com>
-Reported-by: Chukun Pan <amadeus@jmu.edu.cn>
-Reported-by: Yevhen Kolomeiko <jarvis2709@gmail.com>
-Tested-by: Yevhen Kolomeiko <jarvis2709@gmail.com>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/phy/realtek.c | 8 ++++++++
- 1 file changed, 8 insertions(+)
-
---- a/drivers/net/phy/realtek.c
-+++ b/drivers/net/phy/realtek.c
-@@ -913,6 +913,7 @@ static irqreturn_t rtl9000a_handle_inter
- static int rtl8221b_config_init(struct phy_device *phydev)
- {
- u16 option_mode;
-+ int val;
-
- switch (phydev->interface) {
- case PHY_INTERFACE_MODE_2500BASEX:
-@@ -949,6 +950,13 @@ static int rtl8221b_config_init(struct p
- break;
- }
-
-+ /* Disable SGMII AN */
-+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x7588, 0x2);
-+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x7589, 0x71d0);
-+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x7587, 0x3);
-+ phy_read_mmd_poll_timeout(phydev, RTL8221B_MMD_SERDES_CTRL, 0x7587,
-+ val, !(val & BIT(0)), 500, 100000, false);
-+
- return 0;
- }
-
diff --git a/target/linux/generic/pending-6.6/726-net-phy-realtek-make-sure-paged-read-is-protected-by.patch b/target/linux/generic/pending-6.6/726-net-phy-realtek-make-sure-paged-read-is-protected-by.patch
deleted file mode 100644
index be86a774ea..0000000000
--- a/target/linux/generic/pending-6.6/726-net-phy-realtek-make-sure-paged-read-is-protected-by.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From 4dd2cc9b91ecb25f278a2c55e07e6455e9000e6b Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Sat, 22 Apr 2023 01:21:14 +0100
-Subject: [PATCH] net: phy: realtek: make sure paged read is protected by mutex
-
-As we cannot rely on phy_read_paged function before the PHY is
-identified, the paged read in rtlgen_supports_2_5gbps needs to be open
-coded as it is being called by the match_phy_device function, ie. before
-.read_page and .write_page have been populated.
-
-Make sure it is also protected by the MDIO bus mutex and use
-rtl821x_write_page instead of 3 individually locked MDIO bus operations.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/phy/realtek.c | 8 +++++---
- 1 file changed, 5 insertions(+), 3 deletions(-)
-
---- a/drivers/net/phy/realtek.c
-+++ b/drivers/net/phy/realtek.c
-@@ -765,9 +765,11 @@ static bool rtlgen_supports_2_5gbps(stru
- {
- int val;
-
-- phy_write(phydev, RTL821x_PAGE_SELECT, 0xa61);
-- val = phy_read(phydev, 0x13);
-- phy_write(phydev, RTL821x_PAGE_SELECT, 0);
-+ mutex_lock(&phydev->mdio.bus->mdio_lock);
-+ rtl821x_write_page(phydev, 0xa61);
-+ val = __phy_read(phydev, 0x13);
-+ rtl821x_write_page(phydev, 0);
-+ mutex_unlock(&phydev->mdio.bus->mdio_lock);
-
- return val >= 0 && val & RTL_SUPPORTS_2500FULL;
- }
diff --git a/target/linux/generic/pending-6.6/727-net-phy-realtek-use-inline-functions-for-10GbE-adver.patch b/target/linux/generic/pending-6.6/727-net-phy-realtek-use-inline-functions-for-10GbE-adver.patch
deleted file mode 100644
index e6cbfbe649..0000000000
--- a/target/linux/generic/pending-6.6/727-net-phy-realtek-use-inline-functions-for-10GbE-adver.patch
+++ /dev/null
@@ -1,60 +0,0 @@
-From 92c8b9d558160d94b981dd8a2b9c47657627ffdc Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Sat, 22 Apr 2023 01:23:08 +0100
-Subject: [PATCH 2/3] net: phy: realtek: use inline functions for 10GbE
- advertisement
-
-Use existing generic inline functions to encode local advertisement
-of 10GbE link modes as well as to decode link-partner advertisement.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/phy/realtek.c | 22 +++++-----------------
- 1 file changed, 5 insertions(+), 17 deletions(-)
-
---- a/drivers/net/phy/realtek.c
-+++ b/drivers/net/phy/realtek.c
-@@ -69,10 +69,6 @@
- #define RTL_SUPPORTS_5000FULL BIT(14)
- #define RTL_SUPPORTS_2500FULL BIT(13)
- #define RTL_SUPPORTS_10000FULL BIT(0)
--#define RTL_ADV_2500FULL BIT(7)
--#define RTL_LPADV_10000FULL BIT(11)
--#define RTL_LPADV_5000FULL BIT(6)
--#define RTL_LPADV_2500FULL BIT(5)
-
- #define RTL9000A_GINMR 0x14
- #define RTL9000A_GINMR_LINK_STATUS BIT(4)
-@@ -699,14 +695,11 @@ static int rtl822x_config_aneg(struct ph
- int ret = 0;
-
- if (phydev->autoneg == AUTONEG_ENABLE) {
-- u16 adv2500 = 0;
--
-- if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
-- phydev->advertising))
-- adv2500 = RTL_ADV_2500FULL;
--
- ret = phy_modify_paged_changed(phydev, 0xa5d, 0x12,
-- RTL_ADV_2500FULL, adv2500);
-+ MDIO_AN_10GBT_CTRL_ADV10G |
-+ MDIO_AN_10GBT_CTRL_ADV5G |
-+ MDIO_AN_10GBT_CTRL_ADV2_5G,
-+ linkmode_adv_to_mii_10gbt_adv_t(phydev->advertising));
- if (ret < 0)
- return ret;
- }
-@@ -743,12 +736,7 @@ static int rtl822x_read_status(struct ph
- if (lpadv < 0)
- return lpadv;
-
-- linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
-- phydev->lp_advertising, lpadv & RTL_LPADV_10000FULL);
-- linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
-- phydev->lp_advertising, lpadv & RTL_LPADV_5000FULL);
-- linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
-- phydev->lp_advertising, lpadv & RTL_LPADV_2500FULL);
-+ mii_10gbt_stat_mod_linkmode_lpa_t(phydev->lp_advertising, lpadv);
- }
-
- ret = rtlgen_read_status(phydev);
diff --git a/target/linux/generic/pending-6.6/728-net-phy-realtek-check-validity-of-10GbE-link-partner.patch b/target/linux/generic/pending-6.6/728-net-phy-realtek-check-validity-of-10GbE-link-partner.patch
deleted file mode 100644
index 329415bab5..0000000000
--- a/target/linux/generic/pending-6.6/728-net-phy-realtek-check-validity-of-10GbE-link-partner.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From 929bb4d3cfbc7878326c0771a01a636d49c54b40 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Sat, 22 Apr 2023 01:25:39 +0100
-Subject: [PATCH 3/3] net: phy: realtek: check validity of 10GbE link-partner
- advertisement
-
-Only use link-partner advertisement bits for 10GbE modes if they are
-actually valid. Check LOCALOK and REMOTEOK bits and clear 10GbE modes
-unless both of them are set.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/phy/realtek.c | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- a/drivers/net/phy/realtek.c
-+++ b/drivers/net/phy/realtek.c
-@@ -736,6 +736,10 @@ static int rtl822x_read_status(struct ph
- if (lpadv < 0)
- return lpadv;
-
-+ if (!(lpadv & MDIO_AN_10GBT_STAT_REMOK) ||
-+ !(lpadv & MDIO_AN_10GBT_STAT_LOCOK))
-+ lpadv = 0;
-+
- mii_10gbt_stat_mod_linkmode_lpa_t(phydev->lp_advertising, lpadv);
- }
-
diff --git a/target/linux/generic/pending-6.6/729-net-phy-realtek-introduce-rtl822x_probe.patch b/target/linux/generic/pending-6.6/729-net-phy-realtek-introduce-rtl822x_probe.patch
deleted file mode 100644
index 7098fa6b28..0000000000
--- a/target/linux/generic/pending-6.6/729-net-phy-realtek-introduce-rtl822x_probe.patch
+++ /dev/null
@@ -1,84 +0,0 @@
-From 9155098547fb1172d4fa536f3f6bc9d42f59d08c Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Sat, 22 Apr 2023 03:26:01 +0100
-Subject: [PATCH] net: phy: realtek: setup ALDPS on RTL822x
-
-Setup Link Down Power Saving Mode according the DTS property
-just like for RTL821x 1GE PHYs.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/phy/realtek.c | 11 +++++++++++
- 1 file changed, 11 insertions(+)
-
---- a/drivers/net/phy/realtek.c
-+++ b/drivers/net/phy/realtek.c
-@@ -63,6 +63,10 @@
- #define RTL8221B_SERDES_OPTION_MODE_2500BASEX 2
- #define RTL8221B_SERDES_OPTION_MODE_HISGMII 3
-
-+#define RTL8221B_PHYCR1 0xa430
-+#define RTL8221B_PHYCR1_ALDPS_EN BIT(2)
-+#define RTL8221B_PHYCR1_ALDPS_XTAL_OFF_EN BIT(12)
-+
- #define RTL8366RB_POWER_SAVE 0x15
- #define RTL8366RB_POWER_SAVE_ON BIT(12)
-
-@@ -778,6 +782,25 @@ static int rtl8226_match_phy_device(stru
- rtlgen_supports_2_5gbps(phydev);
- }
-
-+static int rtl822x_probe(struct phy_device *phydev)
-+{
-+ struct device *dev = &phydev->mdio.dev;
-+ int val;
-+
-+ val = phy_read_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, RTL8221B_PHYCR1);
-+ if (val < 0)
-+ return val;
-+
-+ if (of_property_read_bool(dev->of_node, "realtek,aldps-enable"))
-+ val |= RTL8221B_PHYCR1_ALDPS_EN | RTL8221B_PHYCR1_ALDPS_XTAL_OFF_EN;
-+ else
-+ val &= ~(RTL8221B_PHYCR1_ALDPS_EN | RTL8221B_PHYCR1_ALDPS_XTAL_OFF_EN);
-+
-+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, RTL8221B_PHYCR1, val);
-+
-+ return 0;
-+}
-+
- static int rtlgen_resume(struct phy_device *phydev)
- {
- int ret = genphy_resume(phydev);
-@@ -1091,6 +1114,7 @@ static struct phy_driver realtek_drvs[]
- .name = "RTL8226-CG 2.5Gbps PHY",
- .get_features = rtl822x_get_features,
- .config_aneg = rtl822x_config_aneg,
-+ .probe = rtl822x_probe,
- .read_status = rtl822x_read_status,
- .suspend = genphy_suspend,
- .resume = rtlgen_resume,
-@@ -1102,6 +1126,7 @@ static struct phy_driver realtek_drvs[]
- .name = "RTL8226B-CG_RTL8221B-CG 2.5Gbps PHY",
- .get_features = rtl822x_get_features,
- .config_aneg = rtl822x_config_aneg,
-+ .probe = rtl822x_probe,
- .read_status = rtl822x_read_status,
- .suspend = genphy_suspend,
- .resume = rtlgen_resume,
-@@ -1114,6 +1139,7 @@ static struct phy_driver realtek_drvs[]
- .get_features = rtl822x_get_features,
- .config_init = rtl8221b_config_init,
- .config_aneg = rtl822x_config_aneg,
-+ .probe = rtl822x_probe,
- .read_status = rtl822x_read_status,
- .suspend = genphy_suspend,
- .resume = rtlgen_resume,
-@@ -1126,6 +1152,7 @@ static struct phy_driver realtek_drvs[]
- .get_features = rtl822x_get_features,
- .config_aneg = rtl822x_config_aneg,
- .config_init = rtl8221b_config_init,
-+ .probe = rtl822x_probe,
- .read_status = rtl822x_read_status,
- .suspend = genphy_suspend,
- .resume = rtlgen_resume,
diff --git a/target/linux/generic/pending-6.6/730-net-phy-realtek-detect-early-version-of-RTL8221B.patch b/target/linux/generic/pending-6.6/730-net-phy-realtek-detect-early-version-of-RTL8221B.patch
deleted file mode 100644
index 0e9affd16a..0000000000
--- a/target/linux/generic/pending-6.6/730-net-phy-realtek-detect-early-version-of-RTL8221B.patch
+++ /dev/null
@@ -1,71 +0,0 @@
-From 0de82310d2b32e78ff79d42c08b1122a6ede3778 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Sun, 30 Apr 2023 00:15:41 +0100
-Subject: [PATCH] net: phy: realtek: detect early version of RTL8221B
-
-Early versions (?) of the RTL8221B PHY cannot be identified in a regular
-Clause-45 bus scan as the PHY doesn't report the implemented MMDs
-correctly but returns 0 instead.
-Implement custom identify function using the PKGID instead of iterating
-over the implemented MMDs.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-
---- a/drivers/net/phy/realtek.c
-+++ b/drivers/net/phy/realtek.c
-@@ -81,6 +81,7 @@
-
- #define RTL_GENERIC_PHYID 0x001cc800
- #define RTL_8211FVD_PHYID 0x001cc878
-+#define RTL_8221B_VB_CG_PHYID 0x001cc849
-
- MODULE_DESCRIPTION("Realtek PHY driver");
- MODULE_AUTHOR("Johnson Leung");
-@@ -782,6 +783,38 @@ static int rtl8226_match_phy_device(stru
- rtlgen_supports_2_5gbps(phydev);
- }
-
-+static int rtl8221b_vb_cg_match_phy_device(struct phy_device *phydev)
-+{
-+ int val;
-+ u32 id;
-+
-+ if (phydev->mdio.bus->read_c45) {
-+ val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PKGID1);
-+ if (val < 0)
-+ return 0;
-+
-+ id = val << 16;
-+ val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PKGID2);
-+ if (val < 0)
-+ return 0;
-+
-+ id |= val;
-+ } else {
-+ val = phy_read(phydev, MII_PHYSID1);
-+ if (val < 0)
-+ return 0;
-+
-+ id = val << 16;
-+ val = phy_read(phydev, MII_PHYSID2);
-+ if (val < 0)
-+ return 0;
-+
-+ id |= val;
-+ }
-+
-+ return (id == RTL_8221B_VB_CG_PHYID);
-+}
-+
- static int rtl822x_probe(struct phy_device *phydev)
- {
- struct device *dev = &phydev->mdio.dev;
-@@ -1134,7 +1167,7 @@ static struct phy_driver realtek_drvs[]
- .write_page = rtl821x_write_page,
- .soft_reset = genphy_soft_reset,
- }, {
-- PHY_ID_MATCH_EXACT(0x001cc849),
-+ .match_phy_device = rtl8221b_vb_cg_match_phy_device,
- .name = "RTL8221B-VB-CG 2.5Gbps PHY",
- .get_features = rtl822x_get_features,
- .config_init = rtl8221b_config_init,
diff --git a/target/linux/generic/pending-6.6/741-net-phy-realtek-support-interrupt-of-RTL8221B.patch b/target/linux/generic/pending-6.6/741-net-phy-realtek-support-interrupt-of-RTL8221B.patch
deleted file mode 100644
index 726f66cf64..0000000000
--- a/target/linux/generic/pending-6.6/741-net-phy-realtek-support-interrupt-of-RTL8221B.patch
+++ /dev/null
@@ -1,75 +0,0 @@
-From d7943c31d57c11e1a517aa3ce2006fca44866870 Mon Sep 17 00:00:00 2001
-From: Jianhui Zhao <zhaojh329@gmail.com>
-Date: Sun, 24 Sep 2023 22:15:00 +0800
-Subject: [PATCH] net: phy: realtek: add interrupt support for RTL8221B
-
-This commit introduces interrupt support for RTL8221B.
-
-Signed-off-by: Jianhui Zhao <zhaojh329@gmail.com>
----
- drivers/net/phy/realtek.c | 47 +++++++++++++++++++++++++++++++++++++++
- 1 file changed, 47 insertions(+)
-
---- a/drivers/net/phy/realtek.c
-+++ b/drivers/net/phy/realtek.c
-@@ -1010,6 +1010,51 @@ static int rtl8221b_config_init(struct p
- return 0;
- }
-
-+static int rtl8221b_ack_interrupt(struct phy_device *phydev)
-+{
-+ int err;
-+
-+ err = phy_read_mmd(phydev, RTL8221B_MMD_PHY_CTRL, 0xa4d4);
-+
-+ return (err < 0) ? err : 0;
-+}
-+
-+static int rtl8221b_config_intr(struct phy_device *phydev)
-+{
-+ int err;
-+
-+ if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
-+ err = rtl8221b_ack_interrupt(phydev);
-+ if (err)
-+ return err;
-+
-+ err = phy_write_mmd(phydev, RTL8221B_MMD_PHY_CTRL, 0xa4d2, 0x7ff);
-+ } else {
-+ err = phy_write_mmd(phydev, RTL8221B_MMD_PHY_CTRL, 0xa4d2, 0x0);
-+ if (err)
-+ return err;
-+
-+ err = rtl8221b_ack_interrupt(phydev);
-+ }
-+
-+ return err;
-+}
-+
-+static irqreturn_t rtl8221b_handle_interrupt(struct phy_device *phydev)
-+{
-+ int err;
-+
-+ err = rtl8221b_ack_interrupt(phydev);
-+ if (err) {
-+ phy_error(phydev);
-+ return IRQ_NONE;
-+ }
-+
-+ phy_trigger_machine(phydev);
-+
-+ return IRQ_HANDLED;
-+}
-+
- static struct phy_driver realtek_drvs[] = {
- {
- PHY_ID_MATCH_EXACT(0x00008201),
-@@ -1172,6 +1217,8 @@ static struct phy_driver realtek_drvs[]
- .get_features = rtl822x_get_features,
- .config_init = rtl8221b_config_init,
- .config_aneg = rtl822x_config_aneg,
-+ .config_intr = rtl8221b_config_intr,
-+ .handle_interrupt = rtl8221b_handle_interrupt,
- .probe = rtl822x_probe,
- .read_status = rtl822x_read_status,
- .suspend = genphy_suspend,
diff --git a/target/linux/generic/pending-6.6/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch b/target/linux/generic/pending-6.6/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch
index 15d385c5fd..3f3d7572e0 100644
--- a/target/linux/generic/pending-6.6/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch
+++ b/target/linux/generic/pending-6.6/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch
@@ -17,7 +17,7 @@ Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
-@@ -6992,6 +6992,7 @@ static int mv88e6xxx_register_switch(str
+@@ -6993,6 +6993,7 @@ static int mv88e6xxx_register_switch(str
ds->ops = &mv88e6xxx_switch_ops;
ds->ageing_time_min = chip->info->age_time_coeff;
ds->ageing_time_max = chip->info->age_time_coeff * U8_MAX;
diff --git a/target/linux/generic/pending-6.6/802-nvmem-u-boot-env-align-endianness-of-crc32-values.patch b/target/linux/generic/pending-6.6/802-nvmem-u-boot-env-align-endianness-of-crc32-values.patch
index d07447bcba..29fe668f8d 100644
--- a/target/linux/generic/pending-6.6/802-nvmem-u-boot-env-align-endianness-of-crc32-values.patch
+++ b/target/linux/generic/pending-6.6/802-nvmem-u-boot-env-align-endianness-of-crc32-values.patch
@@ -1,7 +1,7 @@
From 0e71cac033bb7689c4dfa2e6814191337ef770f5 Mon Sep 17 00:00:00 2001
From: INAGAKI Hiroshi <musashino.open@gmail.com>
Date: Thu, 13 Oct 2022 00:51:33 +0900
-Subject: [PATCH] nvmem: u-boot-env: align endianness of crc32 values
+Subject: [PATCH] nvmem: layouts: u-boot-env: align endianness of crc32 values
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
@@ -31,12 +31,10 @@ Acked-by: Rafał Miłecki <rafal@milecki.pl>
Tested-by: Christian Lamparter <chunkeey@gmail.com>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
---
- drivers/nvmem/u-boot-env.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
---- a/drivers/nvmem/u-boot-env.c
-+++ b/drivers/nvmem/u-boot-env.c
-@@ -181,7 +181,7 @@ static int u_boot_env_parse(struct u_boo
+--- a/drivers/nvmem/layouts/u-boot-env.c
++++ b/drivers/nvmem/layouts/u-boot-env.c
+@@ -148,7 +148,7 @@ int u_boot_env_parse(struct device *dev,
crc32_data_len = dev_size - crc32_data_offset;
data_len = dev_size - data_offset;
diff --git a/target/linux/generic/pending-6.6/804-nvmem-core-support-mac-base-fixed-layout-cells.patch b/target/linux/generic/pending-6.6/804-nvmem-core-support-mac-base-fixed-layout-cells.patch
index d08ed63eaa..241ff77a7b 100644
--- a/target/linux/generic/pending-6.6/804-nvmem-core-support-mac-base-fixed-layout-cells.patch
+++ b/target/linux/generic/pending-6.6/804-nvmem-core-support-mac-base-fixed-layout-cells.patch
@@ -33,7 +33,7 @@ string.
#include <linux/init.h>
#include <linux/kref.h>
#include <linux/module.h>
-@@ -779,6 +782,62 @@ static int nvmem_validate_keepouts(struc
+@@ -796,6 +799,62 @@ static int nvmem_validate_keepouts(struc
return 0;
}
@@ -96,7 +96,7 @@ string.
static int nvmem_add_cells_from_dt(struct nvmem_device *nvmem, struct device_node *np)
{
struct device *dev = &nvmem->dev;
-@@ -813,6 +872,25 @@ static int nvmem_add_cells_from_dt(struc
+@@ -835,6 +894,25 @@ static int nvmem_add_cells_from_dt(struc
if (nvmem->fixup_dt_cell_info)
nvmem->fixup_dt_cell_info(nvmem, &info);
diff --git a/target/linux/imx/Makefile b/target/linux/imx/Makefile
index 2d3f35e4b4..2eb12943c3 100644
--- a/target/linux/imx/Makefile
+++ b/target/linux/imx/Makefile
@@ -9,8 +9,7 @@ BOARDNAME:=NXP i.MX
FEATURES:=audio display fpu gpio pcie rtc usb usbgadget squashfs targz nand ubifs boot-part rootfs-part
SUBTARGETS:=cortexa7 cortexa9 cortexa53
-KERNEL_PATCHVER:=6.1
-KERNEL_TESTING_PATCHVER:=6.6
+KERNEL_PATCHVER:=6.6
include $(INCLUDE_DIR)/target.mk
diff --git a/target/linux/imx/config-6.1 b/target/linux/imx/config-6.1
deleted file mode 100644
index 837bab909a..0000000000
--- a/target/linux/imx/config-6.1
+++ /dev/null
@@ -1,486 +0,0 @@
-CONFIG_ALIGNMENT_TRAP=y
-CONFIG_ARCH_32BIT_OFF_T=y
-CONFIG_ARCH_HIBERNATION_POSSIBLE=y
-CONFIG_ARCH_KEEP_MEMBLOCK=y
-CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
-CONFIG_ARCH_MMAP_RND_BITS_MAX=15
-CONFIG_ARCH_MULTIPLATFORM=y
-CONFIG_ARCH_MULTI_V6_V7=y
-CONFIG_ARCH_MULTI_V7=y
-CONFIG_ARCH_MXC=y
-CONFIG_ARCH_NR_GPIO=0
-CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y
-CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y
-CONFIG_ARCH_SELECT_MEMORY_MODEL=y
-CONFIG_ARCH_SPARSEMEM_ENABLE=y
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
-CONFIG_ARM=y
-CONFIG_ARM_ARCH_TIMER=y
-CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y
-CONFIG_ARM_ERRATA_754322=y
-CONFIG_ARM_ERRATA_764369=y
-CONFIG_ARM_ERRATA_775420=y
-CONFIG_ARM_ERRATA_814220=y
-CONFIG_ARM_HAS_GROUP_RELOCS=y
-CONFIG_ARM_HEAVY_MB=y
-# CONFIG_ARM_IMX6Q_CPUFREQ is not set
-# CONFIG_ARM_IMX_CPUFREQ_DT is not set
-CONFIG_ARM_L1_CACHE_SHIFT=6
-CONFIG_ARM_L1_CACHE_SHIFT_6=y
-CONFIG_ARM_PATCH_IDIV=y
-CONFIG_ARM_PATCH_PHYS_VIRT=y
-CONFIG_ARM_THUMB=y
-CONFIG_ARM_UNWIND=y
-CONFIG_ARM_VIRT_EXT=y
-CONFIG_ASN1=y
-CONFIG_ASSOCIATIVE_ARRAY=y
-CONFIG_ATA=y
-CONFIG_ATAGS=y
-# CONFIG_ATA_SFF is not set
-CONFIG_AUTO_ZRELADDR=y
-CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_BLK_PM=y
-CONFIG_CACHE_L2X0=y
-CONFIG_CC_HAVE_STACKPROTECTOR_TLS=y
-CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
-CONFIG_CC_NO_ARRAY_BOUNDS=y
-CONFIG_CLKSRC_IMX_GPT=y
-CONFIG_CLKSRC_MMIO=y
-# CONFIG_CLK_IMX8MM is not set
-# CONFIG_CLK_IMX8MN is not set
-# CONFIG_CLK_IMX8MP is not set
-# CONFIG_CLK_IMX8MQ is not set
-# CONFIG_CLK_IMX8ULP is not set
-# CONFIG_CLK_IMX93 is not set
-CONFIG_CLONE_BACKWARDS=y
-CONFIG_CLZ_TAB=y
-CONFIG_COMMON_CLK=y
-CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
-CONFIG_COMPAT_32BIT_TIME=y
-CONFIG_CONTEXT_TRACKING=y
-CONFIG_CONTEXT_TRACKING_IDLE=y
-CONFIG_CPUFREQ_DT=y
-CONFIG_CPUFREQ_DT_PLATDEV=y
-CONFIG_CPU_32v6K=y
-CONFIG_CPU_32v7=y
-CONFIG_CPU_ABRT_EV7=y
-CONFIG_CPU_CACHE_V7=y
-CONFIG_CPU_CACHE_VIPT=y
-CONFIG_CPU_COPY_V6=y
-CONFIG_CPU_CP15=y
-CONFIG_CPU_CP15_MMU=y
-CONFIG_CPU_FREQ=y
-CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
-CONFIG_CPU_FREQ_GOV_ATTR_SET=y
-CONFIG_CPU_FREQ_GOV_COMMON=y
-CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
-CONFIG_CPU_FREQ_GOV_ONDEMAND=y
-CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
-CONFIG_CPU_FREQ_GOV_POWERSAVE=y
-CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
-CONFIG_CPU_FREQ_GOV_USERSPACE=y
-CONFIG_CPU_FREQ_STAT=y
-CONFIG_CPU_FREQ_THERMAL=y
-CONFIG_CPU_HAS_ASID=y
-CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_CPU_PABRT_V7=y
-CONFIG_CPU_RMAP=y
-CONFIG_CPU_SPECTRE=y
-CONFIG_CPU_THERMAL=y
-CONFIG_CPU_THUMB_CAPABLE=y
-CONFIG_CPU_TLB_V7=y
-CONFIG_CPU_V7=y
-CONFIG_CRC16=y
-CONFIG_CRYPTO_AES_ARM=y
-CONFIG_CRYPTO_AES_ARM_BS=y
-CONFIG_CRYPTO_ARCH_HAVE_LIB_BLAKE2S=y
-CONFIG_CRYPTO_ARCH_HAVE_LIB_CHACHA=y
-CONFIG_CRYPTO_AUTHENC=y
-CONFIG_CRYPTO_BLAKE2S_ARM=y
-CONFIG_CRYPTO_CBC=y
-CONFIG_CRYPTO_CHACHA20=y
-CONFIG_CRYPTO_CHACHA20_NEON=y
-CONFIG_CRYPTO_CRC32=y
-CONFIG_CRYPTO_CRC32C=y
-CONFIG_CRYPTO_CRC32_ARM_CE=y
-CONFIG_CRYPTO_CRYPTD=y
-CONFIG_CRYPTO_CTS=y
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_DEV_FSL_CAAM=y
-CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API=y
-CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API_DESC=y
-CONFIG_CRYPTO_DEV_FSL_CAAM_COMMON=y
-CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API=y
-CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_DESC=y
-# CONFIG_CRYPTO_DEV_FSL_CAAM_DEBUG is not set
-# CONFIG_CRYPTO_DEV_FSL_CAAM_INTC is not set
-CONFIG_CRYPTO_DEV_FSL_CAAM_JR=y
-CONFIG_CRYPTO_DEV_FSL_CAAM_PKC_API=y
-CONFIG_CRYPTO_DEV_FSL_CAAM_PRNG_API=y
-CONFIG_CRYPTO_DEV_FSL_CAAM_RINGSIZE=9
-CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_API=y
-CONFIG_CRYPTO_DRBG=y
-CONFIG_CRYPTO_DRBG_HMAC=y
-CONFIG_CRYPTO_DRBG_MENU=y
-CONFIG_CRYPTO_ECB=y
-CONFIG_CRYPTO_ENGINE=y
-CONFIG_CRYPTO_HASH_INFO=y
-CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_HW=y
-CONFIG_CRYPTO_JITTERENTROPY=y
-CONFIG_CRYPTO_LIB_CHACHA_GENERIC=y
-CONFIG_CRYPTO_LIB_DES=y
-CONFIG_CRYPTO_LIB_SHA1=y
-CONFIG_CRYPTO_LIB_SHA256=y
-CONFIG_CRYPTO_LIB_UTILS=y
-CONFIG_CRYPTO_LZO=y
-CONFIG_CRYPTO_RNG=y
-CONFIG_CRYPTO_RNG2=y
-CONFIG_CRYPTO_RNG_DEFAULT=y
-CONFIG_CRYPTO_RSA=y
-CONFIG_CRYPTO_SEQIV=y
-CONFIG_CRYPTO_SHA1=y
-CONFIG_CRYPTO_SHA1_ARM=y
-CONFIG_CRYPTO_SHA1_ARM_NEON=y
-CONFIG_CRYPTO_SHA256=y
-CONFIG_CRYPTO_SHA256_ARM=y
-CONFIG_CRYPTO_SHA512=y
-CONFIG_CRYPTO_SHA512_ARM=y
-CONFIG_CRYPTO_SIMD=y
-CONFIG_CRYPTO_XTS=y
-CONFIG_CRYPTO_ZSTD=y
-CONFIG_CURRENT_POINTER_IN_TPIDRURO=y
-CONFIG_DCACHE_WORD_ACCESS=y
-CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
-CONFIG_DEBUG_MISC=y
-CONFIG_DECOMPRESS_BZIP2=y
-CONFIG_DECOMPRESS_GZIP=y
-CONFIG_DECOMPRESS_LZO=y
-CONFIG_DECOMPRESS_XZ=y
-CONFIG_DMADEVICES=y
-CONFIG_DMA_ENGINE=y
-CONFIG_DMA_OF=y
-CONFIG_DMA_OPS=y
-CONFIG_DMA_VIRTUAL_CHANNELS=y
-# CONFIG_DRM_FSL_LDB is not set
-# CONFIG_DRM_IMX8QM_LDB is not set
-# CONFIG_DRM_IMX8QXP_LDB is not set
-# CONFIG_DRM_IMX8QXP_PIXEL_COMBINER is not set
-# CONFIG_DRM_IMX8QXP_PIXEL_LINK_TO_DPI is not set
-# CONFIG_DRM_DW_HDMI_GP_AUDIO is not set
-# CONFIG_VIDEO_IMX_MIPI_CSIS is not set
-# CONFIG_VIDEO_DW100 is not set
-# CONFIG_VIDEO_ROCKCHIP_ISP1 is not set
-# CONFIG_VIDEO_HANTRO is not set
-CONFIG_DTC=y
-CONFIG_EDAC_ATOMIC_SCRUB=y
-CONFIG_EDAC_SUPPORT=y
-CONFIG_ENCRYPTED_KEYS=y
-CONFIG_EXCLUSIVE_SYSTEM_RAM=y
-CONFIG_EXT4_FS=y
-CONFIG_EXT4_FS_POSIX_ACL=y
-CONFIG_EXT4_FS_SECURITY=y
-CONFIG_EXTCON=y
-CONFIG_F2FS_FS=y
-CONFIG_FEC=y
-CONFIG_FIXED_PHY=y
-CONFIG_FIX_EARLYCON_MEM=y
-# CONFIG_FSL_DPAA2_SWITCH is not set
-CONFIG_FSL_GUTS=y
-CONFIG_FS_ENCRYPTION=y
-CONFIG_FS_ENCRYPTION_ALGS=y
-CONFIG_FS_IOMAP=y
-CONFIG_FS_MBCACHE=y
-CONFIG_FS_POSIX_ACL=y
-CONFIG_FWNODE_MDIO=y
-CONFIG_FW_LOADER_PAGED_BUF=y
-CONFIG_FW_LOADER_SYSFS=y
-CONFIG_GCC11_NO_ARRAY_BOUNDS=y
-CONFIG_GENERIC_ALLOCATOR=y
-CONFIG_GENERIC_ARCH_TOPOLOGY=y
-CONFIG_GENERIC_BUG=y
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
-CONFIG_GENERIC_CPU_AUTOPROBE=y
-CONFIG_GENERIC_CPU_VULNERABILITIES=y
-CONFIG_GENERIC_EARLY_IOREMAP=y
-CONFIG_GENERIC_GETTIMEOFDAY=y
-CONFIG_GENERIC_IDLE_POLL_SETUP=y
-CONFIG_GENERIC_IRQ_CHIP=y
-CONFIG_GENERIC_IRQ_MULTI_HANDLER=y
-CONFIG_GENERIC_IRQ_SHOW=y
-CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
-CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y
-CONFIG_GENERIC_MSI_IRQ=y
-CONFIG_GENERIC_MSI_IRQ_DOMAIN=y
-CONFIG_GENERIC_PCI_IOMAP=y
-CONFIG_GENERIC_PINCONF=y
-CONFIG_GENERIC_PINCTRL_GROUPS=y
-CONFIG_GENERIC_PINMUX_FUNCTIONS=y
-CONFIG_GENERIC_SCHED_CLOCK=y
-CONFIG_GENERIC_SMP_IDLE_THREAD=y
-CONFIG_GENERIC_STRNCPY_FROM_USER=y
-CONFIG_GENERIC_STRNLEN_USER=y
-CONFIG_GENERIC_TIME_VSYSCALL=y
-CONFIG_GENERIC_VDSO_32=y
-# CONFIG_GIANFAR is not set
-CONFIG_GLOB=y
-CONFIG_GPIOLIB_IRQCHIP=y
-CONFIG_GPIO_CDEV=y
-CONFIG_GPIO_GENERIC=y
-CONFIG_GPIO_MXC=y
-CONFIG_GPIO_VF610=y
-CONFIG_GRO_CELLS=y
-CONFIG_HARDEN_BRANCH_PREDICTOR=y
-CONFIG_HARDIRQS_SW_RESEND=y
-CONFIG_HAS_DMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT_MAP=y
-CONFIG_HAVE_SMP=y
-CONFIG_HWMON=y
-CONFIG_HW_RANDOM=y
-CONFIG_HZ_FIXED=0
-CONFIG_HZ_PERIODIC=y
-CONFIG_I2C=y
-CONFIG_I2C_BOARDINFO=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_IMX=y
-# CONFIG_I2C_IMX_LPI2C is not set
-CONFIG_I2C_SLAVE=y
-# CONFIG_I2C_SLAVE_TESTUNIT is not set
-CONFIG_IMX2_WDT=y
-# CONFIG_IMX7ULP_WDT is not set
-# CONFIG_IMX8MM_THERMAL is not set
-CONFIG_IMX_DMA=y
-# CONFIG_IMX_GPCV2_PM_DOMAINS is not set
-CONFIG_IMX_INTMUX=y
-CONFIG_IMX_IRQSTEER=y
-CONFIG_IMX_MU_MSI=m
-CONFIG_IMX_SDMA=y
-CONFIG_IMX_THERMAL=y
-# CONFIG_IMX_WEIM is not set
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_IRQCHIP=y
-CONFIG_IRQSTACKS=y
-CONFIG_IRQ_DOMAIN=y
-CONFIG_IRQ_DOMAIN_HIERARCHY=y
-CONFIG_IRQ_FORCED_THREADING=y
-CONFIG_IRQ_WORK=y
-CONFIG_JBD2=y
-# CONFIG_JFFS2_FS is not set
-CONFIG_KEYS=y
-CONFIG_LIBFDT=y
-CONFIG_LOCK_DEBUGGING_SUPPORT=y
-CONFIG_LOCK_SPIN_ON_OWNER=y
-CONFIG_LZO_COMPRESS=y
-CONFIG_LZO_DECOMPRESS=y
-CONFIG_MDIO_BUS=y
-CONFIG_MDIO_DEVICE=y
-CONFIG_MDIO_DEVRES=y
-CONFIG_MEMFD_CREATE=y
-CONFIG_MFD_SYSCON=y
-CONFIG_MIGHT_HAVE_CACHE_L2X0=y
-CONFIG_MIGRATION=y
-CONFIG_MMC=y
-CONFIG_MMC_BLOCK=y
-CONFIG_MMC_CQHCI=y
-# CONFIG_MMC_MXC is not set
-CONFIG_MMC_SDHCI=y
-CONFIG_MMC_SDHCI_ESDHC_IMX=y
-CONFIG_MMC_SDHCI_IO_ACCESSORS=y
-CONFIG_MMC_SDHCI_OF_ESDHC=y
-CONFIG_MMC_SDHCI_PLTFM=y
-CONFIG_MODULES_USE_ELF_REL=y
-CONFIG_MPILIB=y
-CONFIG_MTD_NAND_CORE=y
-CONFIG_MTD_NAND_ECC=y
-CONFIG_MTD_NAND_ECC_SW_HAMMING=y
-CONFIG_MTD_NAND_GPMI_NAND=y
-CONFIG_MTD_RAW_NAND=y
-CONFIG_MTD_UBI=y
-CONFIG_MTD_UBI_BEB_LIMIT=20
-CONFIG_MTD_UBI_BLOCK=y
-CONFIG_MTD_UBI_WL_THRESHOLD=4096
-CONFIG_MUTEX_SPIN_ON_OWNER=y
-# CONFIG_MX3_IPU is not set
-CONFIG_MXC_CLK=y
-CONFIG_MXS_DMA=y
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NEON=y
-CONFIG_NET_DEVLINK=y
-CONFIG_NET_DSA=y
-CONFIG_NET_DSA_TAG_DSA=y
-CONFIG_NET_DSA_TAG_DSA_COMMON=y
-CONFIG_NET_DSA_TAG_EDSA=y
-CONFIG_NET_FLOW_LIMIT=y
-CONFIG_NET_PTP_CLASSIFY=y
-CONFIG_NET_SELFTESTS=y
-CONFIG_NET_SWITCHDEV=y
-CONFIG_NLS=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NR_CPUS=4
-CONFIG_NVMEM=y
-# CONFIG_NVMEM_IMX_IIM is not set
-CONFIG_NVMEM_IMX_OCOTP=y
-# CONFIG_NVMEM_IMX_OCOTP_ELE is not set
-CONFIG_NVMEM_LAYOUTS=y
-# CONFIG_NVMEM_SNVS_LPGPR is not set
-CONFIG_NVMEM_SYSFS=y
-CONFIG_OF=y
-CONFIG_OF_ADDRESS=y
-CONFIG_OF_EARLY_FLATTREE=y
-CONFIG_OF_FLATTREE=y
-CONFIG_OF_GPIO=y
-CONFIG_OF_IRQ=y
-CONFIG_OF_KOBJ=y
-CONFIG_OF_MDIO=y
-CONFIG_OLD_SIGACTION=y
-CONFIG_OLD_SIGSUSPEND3=y
-CONFIG_OUTER_CACHE=y
-CONFIG_OUTER_CACHE_SYNC=y
-CONFIG_PADATA=y
-CONFIG_PAGE_OFFSET=0x80000000
-CONFIG_PAGE_POOL=y
-CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
-CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
-CONFIG_PERF_USE_VMALLOC=y
-CONFIG_PGTABLE_LEVELS=2
-CONFIG_PHYLIB=y
-CONFIG_PHYLINK=y
-CONFIG_PINCTRL=y
-# CONFIG_PINCTRL_IMX8ULP is not set
-# CONFIG_PINCTRL_IMX93 is not set
-# CONFIG_PINCTRL_IMXRT1050 is not set
-# CONFIG_PINCTRL_IMXRT1170 is not set
-CONFIG_PL310_ERRATA_769419=y
-CONFIG_PM=y
-CONFIG_PM_CLK=y
-CONFIG_PM_OPP=y
-CONFIG_PPS=y
-CONFIG_PREEMPT_NONE_BUILD=y
-CONFIG_PTP_1588_CLOCK=y
-CONFIG_PTP_1588_CLOCK_OPTIONAL=y
-CONFIG_PWM=y
-# CONFIG_PWM_IMX1 is not set
-CONFIG_PWM_IMX27=y
-# CONFIG_PWM_IMX_TPM is not set
-CONFIG_PWM_SYSFS=y
-CONFIG_RANDSTRUCT_NONE=y
-CONFIG_RAS=y
-CONFIG_RATIONAL=y
-CONFIG_RD_BZIP2=y
-CONFIG_RD_GZIP=y
-CONFIG_RD_LZO=y
-CONFIG_RD_XZ=y
-CONFIG_REGMAP=y
-CONFIG_REGMAP_I2C=y
-CONFIG_REGMAP_MMIO=y
-CONFIG_REGULATOR=y
-CONFIG_REGULATOR_ANATOP=y
-CONFIG_REGULATOR_FIXED_VOLTAGE=y
-CONFIG_REGULATOR_PFUZE100=y
-CONFIG_RESET_CONTROLLER=y
-CONFIG_RFS_ACCEL=y
-CONFIG_RPS=y
-CONFIG_RTC_CLASS=y
-# CONFIG_RTC_DRV_CMOS is not set
-# CONFIG_RTC_DRV_IMXDI is not set
-# CONFIG_RTC_DRV_MXC is not set
-# CONFIG_RTC_DRV_MXC_V2 is not set
-CONFIG_RTC_I2C_AND_SPI=y
-CONFIG_RWSEM_SPIN_ON_OWNER=y
-CONFIG_SCHED_THERMAL_PRESSURE=y
-CONFIG_SCSI=y
-CONFIG_SCSI_COMMON=y
-CONFIG_SERIAL_8250_FSL=y
-CONFIG_SERIAL_IMX=y
-CONFIG_SERIAL_IMX_CONSOLE=y
-CONFIG_SERIAL_IMX_EARLYCON=y
-CONFIG_SERIAL_MCTRL_GPIO=y
-CONFIG_SGL_ALLOC=y
-CONFIG_SG_POOL=y
-CONFIG_SMP=y
-CONFIG_SMP_ON_UP=y
-CONFIG_SOCK_RX_QUEUE_MAPPING=y
-CONFIG_SOC_BUS=y
-# CONFIG_SOC_IMX50 is not set
-# CONFIG_SOC_IMX51 is not set
-# CONFIG_SOC_IMX53 is not set
-# CONFIG_SOC_IMX6Q is not set
-# CONFIG_SOC_IMX6SL is not set
-# CONFIG_SOC_IMX6SLL is not set
-# CONFIG_SOC_IMX6SX is not set
-# CONFIG_SOC_IMX6UL is not set
-# CONFIG_SOC_IMX7D is not set
-# CONFIG_SOC_IMX7ULP is not set
-# CONFIG_SOC_IMX8M is not set
-# CONFIG_SOC_IMX9 is not set
-# CONFIG_SOC_LS1021A is not set
-# CONFIG_SOC_VF610 is not set
-CONFIG_SOFTIRQ_ON_OWN_STACK=y
-CONFIG_SPARSE_IRQ=y
-CONFIG_SPI=y
-CONFIG_SPI_BITBANG=y
-# CONFIG_SPI_FSL_LPSPI is not set
-# CONFIG_SPI_FSL_QUADSPI is not set
-CONFIG_SPI_IMX=y
-CONFIG_SPI_MASTER=y
-CONFIG_SRAM=y
-CONFIG_SRAM_EXEC=y
-CONFIG_SRCU=y
-CONFIG_STMP_DEVICE=y
-CONFIG_SWPHY=y
-CONFIG_SWP_EMULATE=y
-CONFIG_SYS_SUPPORTS_APM_EMULATION=y
-CONFIG_THERMAL=y
-CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
-CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
-CONFIG_THERMAL_GOV_STEP_WISE=y
-CONFIG_THERMAL_OF=y
-CONFIG_THREAD_INFO_IN_TASK=y
-CONFIG_TICK_CPU_ACCOUNTING=y
-CONFIG_TIMER_OF=y
-CONFIG_TIMER_PROBE=y
-CONFIG_TREE_RCU=y
-CONFIG_TREE_SRCU=y
-CONFIG_UBIFS_FS=y
-# CONFIG_UCLAMP_TASK is not set
-CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
-CONFIG_UNWINDER_ARM=y
-CONFIG_USB=y
-CONFIG_USB_CHIPIDEA=y
-CONFIG_USB_CHIPIDEA_HOST=y
-CONFIG_USB_CHIPIDEA_IMX=y
-CONFIG_USB_CHIPIDEA_UDC=y
-CONFIG_USB_COMMON=y
-CONFIG_USB_EHCI_HCD=y
-# CONFIG_USB_EHCI_HCD_PLATFORM is not set
-CONFIG_USB_GADGET=y
-CONFIG_USB_MXS_PHY=y
-CONFIG_USB_OTG=y
-CONFIG_USB_PHY=y
-CONFIG_USB_ROLE_SWITCH=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_SUPPORT=y
-CONFIG_USB_ULPI_BUS=y
-CONFIG_USE_OF=y
-CONFIG_VFP=y
-CONFIG_VFPv3=y
-CONFIG_VMSPLIT_2G=y
-# CONFIG_VMSPLIT_3G is not set
-CONFIG_WATCHDOG_CORE=y
-CONFIG_XPS=y
-CONFIG_XXHASH=y
-CONFIG_XZ_DEC_ARM=y
-CONFIG_XZ_DEC_ARMTHUMB=y
-CONFIG_XZ_DEC_BCJ=y
-CONFIG_ZBOOT_ROM_BSS=0
-CONFIG_ZBOOT_ROM_TEXT=0
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZSTD_COMMON=y
-CONFIG_ZSTD_COMPRESS=y
-CONFIG_ZSTD_DECOMPRESS=y
diff --git a/target/linux/imx/config-6.6 b/target/linux/imx/config-6.6
index 6edc3560b4..6cb1d8a8f6 100644
--- a/target/linux/imx/config-6.6
+++ b/target/linux/imx/config-6.6
@@ -186,8 +186,6 @@ CONFIG_EDAC_SUPPORT=y
CONFIG_ENCRYPTED_KEYS=y
CONFIG_EXCLUSIVE_SYSTEM_RAM=y
CONFIG_EXT4_FS=y
-CONFIG_EXT4_FS_POSIX_ACL=y
-CONFIG_EXT4_FS_SECURITY=y
CONFIG_EXTCON=y
CONFIG_F2FS_FS=y
CONFIG_FEC=y
@@ -199,7 +197,6 @@ CONFIG_FS_ENCRYPTION=y
CONFIG_FS_ENCRYPTION_ALGS=y
CONFIG_FS_IOMAP=y
CONFIG_FS_MBCACHE=y
-CONFIG_FS_POSIX_ACL=y
CONFIG_FWNODE_MDIO=y
CONFIG_FW_LOADER_PAGED_BUF=y
CONFIG_FW_LOADER_SYSFS=y
diff --git a/target/linux/imx/image/cortexa7.mk b/target/linux/imx/image/cortexa7.mk
index 3f89a99a83..6d2d0ab778 100644
--- a/target/linux/imx/image/cortexa7.mk
+++ b/target/linux/imx/image/cortexa7.mk
@@ -10,9 +10,7 @@ define Device/Default
KERNEL_NAME := zImage
KERNEL := kernel-bin | uImage none
KERNEL_LOADADDR := 0x80008000
-ifdef CONFIG_LINUX_6_6
DTS_DIR := $(DTS_DIR)/nxp/imx
-endif
IMAGES :=
endef
diff --git a/target/linux/imx/image/cortexa9.mk b/target/linux/imx/image/cortexa9.mk
index 1ff5bcb8a7..5f087c83ed 100644
--- a/target/linux/imx/image/cortexa9.mk
+++ b/target/linux/imx/image/cortexa9.mk
@@ -84,9 +84,7 @@ define Device/Default
KERNEL_NAME := zImage
KERNEL := kernel-bin | uImage none
KERNEL_LOADADDR := 0x10008000
-ifdef CONFIG_LINUX_6_6
DTS_DIR := $(DTS_DIR)/nxp/imx
-endif
IMAGES :=
endef
diff --git a/target/linux/imx/patches-6.1/001-6.2-phy-freescale-imx8m-pcie-Refine-register-definitions.patch b/target/linux/imx/patches-6.1/001-6.2-phy-freescale-imx8m-pcie-Refine-register-definitions.patch
deleted file mode 100644
index 01731755df..0000000000
--- a/target/linux/imx/patches-6.1/001-6.2-phy-freescale-imx8m-pcie-Refine-register-definitions.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-From ffcbb4ccd357eeb649036e379a34bf5fb8d4f47c Mon Sep 17 00:00:00 2001
-From: Richard Zhu <hongxing.zhu@nxp.com>
-Date: Thu, 13 Oct 2022 09:47:00 +0800
-Subject: [PATCH 1/3] phy: freescale: imx8m-pcie: Refine register definitions
-
-No function changes, refine PHY register definitions.
-- Keep align with other CMN PHY registers, refine the definitions of
- PHY_CMN_REG75.
-- Remove two BIT definitions that are not used at all.
-
-Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
-Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
-Tested-by: Marek Vasut <marex@denx.de>
-Tested-by: Richard Leitner <richard.leitner@skidata.com>
-Tested-by: Alexander Stein <alexander.stein@ew.tq-group.com>
-Reviewed-by: Lucas Stach <l.stach@pengutronix.de>
----
- drivers/phy/freescale/phy-fsl-imx8m-pcie.c | 11 ++++-------
- 1 file changed, 4 insertions(+), 7 deletions(-)
-
---- a/drivers/phy/freescale/phy-fsl-imx8m-pcie.c
-+++ b/drivers/phy/freescale/phy-fsl-imx8m-pcie.c
-@@ -32,12 +32,10 @@
- #define IMX8MM_PCIE_PHY_CMN_REG065 0x194
- #define ANA_AUX_RX_TERM (BIT(7) | BIT(4))
- #define ANA_AUX_TX_LVL GENMASK(3, 0)
--#define IMX8MM_PCIE_PHY_CMN_REG75 0x1D4
--#define PCIE_PHY_CMN_REG75_PLL_DONE 0x3
-+#define IMX8MM_PCIE_PHY_CMN_REG075 0x1D4
-+#define ANA_PLL_DONE 0x3
- #define PCIE_PHY_TRSV_REG5 0x414
--#define PCIE_PHY_TRSV_REG5_GEN1_DEEMP 0x2D
- #define PCIE_PHY_TRSV_REG6 0x418
--#define PCIE_PHY_TRSV_REG6_GEN2_DEEMP 0xF
-
- #define IMX8MM_GPR_PCIE_REF_CLK_SEL GENMASK(25, 24)
- #define IMX8MM_GPR_PCIE_REF_CLK_PLL FIELD_PREP(IMX8MM_GPR_PCIE_REF_CLK_SEL, 0x3)
-@@ -152,9 +150,8 @@ static int imx8_pcie_phy_power_on(struct
- }
-
- /* Polling to check the phy is ready or not. */
-- ret = readl_poll_timeout(imx8_phy->base + IMX8MM_PCIE_PHY_CMN_REG75,
-- val, val == PCIE_PHY_CMN_REG75_PLL_DONE,
-- 10, 20000);
-+ ret = readl_poll_timeout(imx8_phy->base + IMX8MM_PCIE_PHY_CMN_REG075,
-+ val, val == ANA_PLL_DONE, 10, 20000);
- return ret;
- }
-
diff --git a/target/linux/imx/patches-6.1/003-6.3-phy-freescale-imx8m-pcie-Add-i.MX8MP-PCIe-PHY-suppor.patch b/target/linux/imx/patches-6.1/003-6.3-phy-freescale-imx8m-pcie-Add-i.MX8MP-PCIe-PHY-suppor.patch
deleted file mode 100644
index dbcfd40e57..0000000000
--- a/target/linux/imx/patches-6.1/003-6.3-phy-freescale-imx8m-pcie-Add-i.MX8MP-PCIe-PHY-suppor.patch
+++ /dev/null
@@ -1,99 +0,0 @@
-From bf03b9281b119bcdc167b2dd6ac98294587eb5ff Mon Sep 17 00:00:00 2001
-From: Richard Zhu <hongxing.zhu@nxp.com>
-Date: Thu, 13 Oct 2022 09:47:02 +0800
-Subject: [PATCH 3/3] phy: freescale: imx8m-pcie: Add i.MX8MP PCIe PHY support
-
-Add i.MX8MP PCIe PHY support.
-
-Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
-Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
-Tested-by: Marek Vasut <marex@denx.de>
-Tested-by: Richard Leitner <richard.leitner@skidata.com>
-Tested-by: Alexander Stein <alexander.stein@ew.tq-group.com>
-Reviewed-by: Lucas Stach <l.stach@pengutronix.de>
-Reviewed-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
----
- drivers/phy/freescale/phy-fsl-imx8m-pcie.c | 25 ++++++++++++++++++++--
- 1 file changed, 23 insertions(+), 2 deletions(-)
-
---- a/drivers/phy/freescale/phy-fsl-imx8m-pcie.c
-+++ b/drivers/phy/freescale/phy-fsl-imx8m-pcie.c
-@@ -48,6 +48,7 @@
-
- enum imx8_pcie_phy_type {
- IMX8MM,
-+ IMX8MP,
- };
-
- struct imx8_pcie_phy_drvdata {
-@@ -60,6 +61,7 @@ struct imx8_pcie_phy {
- struct clk *clk;
- struct phy *phy;
- struct regmap *iomuxc_gpr;
-+ struct reset_control *perst;
- struct reset_control *reset;
- u32 refclk_pad_mode;
- u32 tx_deemph_gen1;
-@@ -74,11 +76,11 @@ static int imx8_pcie_phy_power_on(struct
- u32 val, pad_mode;
- struct imx8_pcie_phy *imx8_phy = phy_get_drvdata(phy);
-
-- reset_control_assert(imx8_phy->reset);
--
- pad_mode = imx8_phy->refclk_pad_mode;
- switch (imx8_phy->drvdata->variant) {
- case IMX8MM:
-+ reset_control_assert(imx8_phy->reset);
-+
- /* Tune PHY de-emphasis setting to pass PCIe compliance. */
- if (imx8_phy->tx_deemph_gen1)
- writel(imx8_phy->tx_deemph_gen1,
-@@ -87,6 +89,8 @@ static int imx8_pcie_phy_power_on(struct
- writel(imx8_phy->tx_deemph_gen2,
- imx8_phy->base + PCIE_PHY_TRSV_REG6);
- break;
-+ case IMX8MP: /* Do nothing. */
-+ break;
- }
-
- if (pad_mode == IMX8_PCIE_REFCLK_PAD_INPUT ||
-@@ -143,6 +147,9 @@ static int imx8_pcie_phy_power_on(struct
- IMX8MM_GPR_PCIE_CMN_RST);
-
- switch (imx8_phy->drvdata->variant) {
-+ case IMX8MP:
-+ reset_control_deassert(imx8_phy->perst);
-+ fallthrough;
- case IMX8MM:
- reset_control_deassert(imx8_phy->reset);
- usleep_range(200, 500);
-@@ -183,8 +190,14 @@ static const struct imx8_pcie_phy_drvdat
- .variant = IMX8MM,
- };
-
-+static const struct imx8_pcie_phy_drvdata imx8mp_drvdata = {
-+ .gpr = "fsl,imx8mp-iomuxc-gpr",
-+ .variant = IMX8MP,
-+};
-+
- static const struct of_device_id imx8_pcie_phy_of_match[] = {
- {.compatible = "fsl,imx8mm-pcie-phy", .data = &imx8mm_drvdata, },
-+ {.compatible = "fsl,imx8mp-pcie-phy", .data = &imx8mp_drvdata, },
- { },
- };
- MODULE_DEVICE_TABLE(of, imx8_pcie_phy_of_match);
-@@ -240,6 +253,14 @@ static int imx8_pcie_phy_probe(struct pl
- return PTR_ERR(imx8_phy->reset);
- }
-
-+ if (imx8_phy->drvdata->variant == IMX8MP) {
-+ imx8_phy->perst =
-+ devm_reset_control_get_exclusive(dev, "perst");
-+ if (IS_ERR(imx8_phy->perst))
-+ dev_err_probe(dev, PTR_ERR(imx8_phy->perst),
-+ "Failed to get PCIE PHY PERST control\n");
-+ }
-+
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- imx8_phy->base = devm_ioremap_resource(dev, res);
- if (IS_ERR(imx8_phy->base))
diff --git a/target/linux/imx/patches-6.1/100-bootargs.patch b/target/linux/imx/patches-6.1/100-bootargs.patch
deleted file mode 100644
index cf63a3bdb1..0000000000
--- a/target/linux/imx/patches-6.1/100-bootargs.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/arch/arm/boot/dts/imx6dl-wandboard.dts
-+++ b/arch/arm/boot/dts/imx6dl-wandboard.dts
-@@ -16,4 +16,8 @@
- device_type = "memory";
- reg = <0x10000000 0x40000000>;
- };
-+
-+ chosen {
-+ bootargs = "console=ttymxc0,115200";
-+ };
- };
diff --git a/target/linux/imx/patches-6.1/300-ARM-dts-imx6q-apalis-ixora-add-status-LEDs-aliases.patch b/target/linux/imx/patches-6.1/300-ARM-dts-imx6q-apalis-ixora-add-status-LEDs-aliases.patch
deleted file mode 100644
index 9db7098aaf..0000000000
--- a/target/linux/imx/patches-6.1/300-ARM-dts-imx6q-apalis-ixora-add-status-LEDs-aliases.patch
+++ /dev/null
@@ -1,96 +0,0 @@
-From 68604e89335ccb3e893b5a05b2c0d5cd2eaaf6ec Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Petr=20=C5=A0tetiar?= <ynezz@true.cz>
-Date: Tue, 3 Mar 2020 15:14:40 +0100
-Subject: [PATCH] ARM: dts: imx6q-apalis: ixora: add status LEDs aliases
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Signed-off-by: Petr Štetiar <ynezz@true.cz>
----
- arch/arm/boot/dts/imx6q-apalis-ixora-v1.1.dts | 16 ++++++++++------
- arch/arm/boot/dts/imx6q-apalis-ixora.dts | 12 ++++++++----
- 2 files changed, 18 insertions(+), 10 deletions(-)
-
---- a/arch/arm/boot/dts/imx6q-apalis-ixora.dts
-+++ b/arch/arm/boot/dts/imx6q-apalis-ixora.dts
-@@ -24,6 +24,10 @@
- i2c2 = &i2c2;
- rtc0 = &rtc_i2c;
- rtc1 = &snvs_rtc;
-+ led-boot = &led_boot;
-+ led-failsafe = &led_failsafe;
-+ led-running = &led_running;
-+ led-upgrade = &led_upgrade;
- };
-
- chosen {
-@@ -35,22 +39,22 @@
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_leds_ixora>;
-
-- led4-green {
-+ led_running: led4-green {
- gpios = <&gpio1 17 GPIO_ACTIVE_HIGH>;
- label = "LED_4_GREEN";
- };
-
-- led4-red {
-+ led_upgrade: led4-red {
- gpios = <&gpio1 21 GPIO_ACTIVE_HIGH>;
- label = "LED_4_RED";
- };
-
-- led5-green {
-+ led_boot: led5-green {
- gpios = <&gpio2 1 GPIO_ACTIVE_HIGH>;
- label = "LED_5_GREEN";
- };
-
-- led5-red {
-+ led_failsafe: led5-red {
- gpios = <&gpio2 2 GPIO_ACTIVE_HIGH>;
- label = "LED_5_RED";
- };
---- a/arch/arm/boot/dts/imx6q-apalis-ixora-v1.2.dts
-+++ b/arch/arm/boot/dts/imx6q-apalis-ixora-v1.2.dts
-@@ -24,6 +24,10 @@
- i2c2 = &i2c2;
- rtc0 = &rtc_i2c;
- rtc1 = &snvs_rtc;
-+ led-boot = &led_boot;
-+ led-failsafe = &led_failsafe;
-+ led-running = &led_running;
-+ led-upgrade = &led_upgrade;
- };
-
- chosen {
-@@ -36,22 +40,22 @@
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_leds_ixora>;
-
-- led4-green {
-- gpios = <&gpio1 14 GPIO_ACTIVE_HIGH>;
-+ led_running: led4-green {
-+ gpios = <&gpio1 17 GPIO_ACTIVE_HIGH>;
- label = "LED_4_GREEN";
- };
-
-- led4-red {
-- gpios = <&gpio1 12 GPIO_ACTIVE_HIGH>;
-+ led_upgrade: led4-red {
-+ gpios = <&gpio1 21 GPIO_ACTIVE_HIGH>;
- label = "LED_4_RED";
- };
-
-- led5-green {
-+ led_boot: led5-green {
- gpios = <&gpio2 1 GPIO_ACTIVE_HIGH>;
- label = "LED_5_GREEN";
- };
-
-- led5-red {
-+ led_failsafe: led5-red {
- gpios = <&gpio2 2 GPIO_ACTIVE_HIGH>;
- label = "LED_5_RED";
- };
diff --git a/target/linux/imx/patches-6.1/301-ARM-dts-imx6q-apalis-ixora-make-switch3-reset-button.patch b/target/linux/imx/patches-6.1/301-ARM-dts-imx6q-apalis-ixora-make-switch3-reset-button.patch
deleted file mode 100644
index 95f572f35e..0000000000
--- a/target/linux/imx/patches-6.1/301-ARM-dts-imx6q-apalis-ixora-make-switch3-reset-button.patch
+++ /dev/null
@@ -1,78 +0,0 @@
-From b6764bb27c819cdcf854371db485a43d71f579f3 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Petr=20=C5=A0tetiar?= <ynezz@true.cz>
-Date: Tue, 3 Mar 2020 15:15:57 +0100
-Subject: [PATCH] ARM: dts: imx6q-apalis: ixora: make switch3 reset button
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Signed-off-by: Petr Štetiar <ynezz@true.cz>
----
- arch/arm/boot/dts/imx6q-apalis-ixora-v1.1.dts | 15 ++++++++++++++-
- arch/arm/boot/dts/imx6q-apalis-ixora.dts | 15 ++++++++++++++-
- 2 files changed, 28 insertions(+), 2 deletions(-)
-
---- a/arch/arm/boot/dts/imx6q-apalis-ixora.dts
-+++ b/arch/arm/boot/dts/imx6q-apalis-ixora.dts
-@@ -59,6 +59,17 @@
- label = "LED_5_RED";
- };
- };
-+
-+ gpio-keys {
-+ pinctrl-0 = <&pinctrl_gpio_keys &pinctrl_switch3_ixora>;
-+
-+ reset {
-+ label = "reset";
-+ gpios = <&gpio1 16 GPIO_ACTIVE_LOW>;
-+ linux,code = <KEY_RESTART>;
-+ debounce-interval = <10>;
-+ };
-+ };
- };
-
- &can1 {
-@@ -181,4 +192,10 @@
- MX6QDL_PAD_NANDF_D2__GPIO2_IO02 0x1b0b0
- >;
- };
-+
-+ pinctrl_switch3_ixora: switch3ixora {
-+ fsl,pins = <
-+ MX6QDL_PAD_SD1_DAT0__GPIO1_IO16 0x1b0b0
-+ >;
-+ };
- };
---- a/arch/arm/boot/dts/imx6q-apalis-ixora-v1.2.dts
-+++ b/arch/arm/boot/dts/imx6q-apalis-ixora-v1.2.dts
-@@ -61,6 +61,17 @@
- };
- };
-
-+ gpio-keys {
-+ pinctrl-0 = <&pinctrl_gpio_keys &pinctrl_switch3_ixora>;
-+
-+ reset {
-+ label = "reset";
-+ gpios = <&gpio1 16 GPIO_ACTIVE_LOW>;
-+ linux,code = <KEY_RESTART>;
-+ debounce-interval = <10>;
-+ };
-+ };
-+
- reg_3v3_vmmc: regulator-3v3-vmmc {
- compatible = "regulator-fixed";
- enable-active-high;
-@@ -262,6 +273,12 @@
- >;
- };
-
-+ pinctrl_switch3_ixora: switch3ixora {
-+ fsl,pins = <
-+ MX6QDL_PAD_SD1_DAT0__GPIO1_IO16 0x1b0b0
-+ >;
-+ };
-+
- pinctrl_mmc_cd_sleep: mmccdslpgrp {
- fsl,pins = <
- /* MMC1 CD */
diff --git a/target/linux/imx/patches-6.1/310-ARM-dts-imx7d-pico-pi-set-aliases.patch b/target/linux/imx/patches-6.1/310-ARM-dts-imx7d-pico-pi-set-aliases.patch
deleted file mode 100644
index f50199cdfc..0000000000
--- a/target/linux/imx/patches-6.1/310-ARM-dts-imx7d-pico-pi-set-aliases.patch
+++ /dev/null
@@ -1,24 +0,0 @@
---- a/arch/arm/boot/dts/imx7d-pico-pi.dts
-+++ b/arch/arm/boot/dts/imx7d-pico-pi.dts
-@@ -8,12 +8,20 @@
- model = "TechNexion PICO-IMX7D Board and PI baseboard";
- compatible = "technexion,imx7d-pico-pi", "fsl,imx7d";
-
-+ aliases {
-+ led-boot = &led_system;
-+ led-failsafe = &led_system;
-+ led-running = &led_system;
-+ led-upgrade = &led_system;
-+ label-mac-device = &fec1;
-+ };
-+
- leds {
- compatible = "gpio-leds";
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_gpio_leds>;
-
-- led {
-+ led_system: led {
- label = "gpio-led";
- gpios = <&gpio2 6 GPIO_ACTIVE_HIGH>;
- };
diff --git a/target/linux/imx/patches-6.1/311-ARM-imx7d-pico-pi.dts-add-default-stdout-path.patch b/target/linux/imx/patches-6.1/311-ARM-imx7d-pico-pi.dts-add-default-stdout-path.patch
deleted file mode 100644
index 5248e8c74c..0000000000
--- a/target/linux/imx/patches-6.1/311-ARM-imx7d-pico-pi.dts-add-default-stdout-path.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-From 6e8e5ccfbee7a531b035ffce3f95f3901946fa9d Mon Sep 17 00:00:00 2001
-From: Robert Nelson <robertcnelson@gmail.com>
-Date: Wed, 9 Jan 2019 14:33:24 -0600
-Subject: [PATCH] ARM: imx7d-pico-pi.dts: add default stdout-path
-
-Signed-off-by: Robert Nelson <robertcnelson@gmail.com>
----
- arch/arm/boot/dts/imx7d-pico-pi.dts | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- a/arch/arm/boot/dts/imx7d-pico-pi.dts
-+++ b/arch/arm/boot/dts/imx7d-pico-pi.dts
-@@ -16,6 +16,10 @@
- label-mac-device = &fec1;
- };
-
-+ chosen {
-+ stdout-path = "serial4:115200n8";
-+ };
-+
- leds {
- compatible = "gpio-leds";
- pinctrl-names = "default";
diff --git a/target/linux/ipq40xx/Makefile b/target/linux/ipq40xx/Makefile
index 30091e5d29..68a47c9082 100644
--- a/target/linux/ipq40xx/Makefile
+++ b/target/linux/ipq40xx/Makefile
@@ -3,7 +3,7 @@ include $(TOPDIR)/rules.mk
ARCH:=arm
BOARD:=ipq40xx
BOARDNAME:=Qualcomm Atheros IPQ40XX
-FEATURES:=squashfs fpu ramdisk nand
+FEATURES:=squashfs fpu ramdisk
CPU_TYPE:=cortex-a7
CPU_SUBTYPE:=neon-vfpv4
SUBTARGETS:=generic chromium mikrotik
diff --git a/target/linux/ipq40xx/config-6.6 b/target/linux/ipq40xx/config-6.6
index 3049efc3d6..683463628f 100644
--- a/target/linux/ipq40xx/config-6.6
+++ b/target/linux/ipq40xx/config-6.6
@@ -306,11 +306,6 @@ CONFIG_MTD_SPI_NOR=y
CONFIG_MTD_SPLIT_FIRMWARE=y
CONFIG_MTD_SPLIT_FIT_FW=y
CONFIG_MTD_SPLIT_WRGG_FW=y
-CONFIG_MTD_UBI=y
-CONFIG_MTD_UBI_BEB_LIMIT=20
-CONFIG_MTD_UBI_BLOCK=y
-CONFIG_MTD_UBI_NVMEM=y
-CONFIG_MTD_UBI_WL_THRESHOLD=4096
CONFIG_MUTEX_SPIN_ON_OWNER=y
CONFIG_NEED_DMA_MAP_STATE=y
CONFIG_NEON=y
@@ -532,7 +527,6 @@ CONFIG_TIMER_OF=y
CONFIG_TIMER_PROBE=y
CONFIG_TREE_RCU=y
CONFIG_TREE_SRCU=y
-CONFIG_UBIFS_FS=y
CONFIG_UEVENT_HELPER_PATH=""
CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
CONFIG_UNWINDER_ARM=y
diff --git a/target/linux/ipq40xx/files-6.6/arch/arm/boot/dts/qcom/qcom-ipq4018-nbg6617.dts b/target/linux/ipq40xx/files-6.6/arch/arm/boot/dts/qcom/qcom-ipq4018-nbg6617.dts
index f8e24ca53d..957ccb306c 100644
--- a/target/linux/ipq40xx/files-6.6/arch/arm/boot/dts/qcom/qcom-ipq4018-nbg6617.dts
+++ b/target/linux/ipq40xx/files-6.6/arch/arm/boot/dts/qcom/qcom-ipq4018-nbg6617.dts
@@ -8,7 +8,7 @@
#include <dt-bindings/soc/qcom,tcsr.h>
/ {
- model = "ZyXEL NBG6617";
+ model = "Zyxel NBG6617";
compatible = "zyxel,nbg6617";
chosen {
@@ -239,7 +239,7 @@
partition12@6a0000 {
label = "not_root_data";
/*
- * for some strange reason, someone at ZyXEL
+ * for some strange reason, someone at Zyxel
* had the "great" idea to put the rootfs_data
* in front of rootfs... Don't do that!
* As a result this one, full MebiByte remains
diff --git a/target/linux/ipq40xx/files-6.6/arch/arm/boot/dts/qcom/qcom-ipq4018-wre6606.dts b/target/linux/ipq40xx/files-6.6/arch/arm/boot/dts/qcom/qcom-ipq4018-wre6606.dts
index d59c41fab1..83ae05c626 100644
--- a/target/linux/ipq40xx/files-6.6/arch/arm/boot/dts/qcom/qcom-ipq4018-wre6606.dts
+++ b/target/linux/ipq40xx/files-6.6/arch/arm/boot/dts/qcom/qcom-ipq4018-wre6606.dts
@@ -22,7 +22,7 @@
#include <dt-bindings/soc/qcom,tcsr.h>
/ {
- model = "ZyXEL WRE6606";
+ model = "Zyxel WRE6606";
compatible = "zyxel,wre6606";
aliases {
diff --git a/target/linux/ipq40xx/generic/config-default b/target/linux/ipq40xx/generic/config-default
new file mode 100644
index 0000000000..bd9876a0b6
--- /dev/null
+++ b/target/linux/ipq40xx/generic/config-default
@@ -0,0 +1,6 @@
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_BEB_LIMIT=20
+CONFIG_MTD_UBI_BLOCK=y
+CONFIG_MTD_UBI_NVMEM=y
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+CONFIG_UBIFS_FS=y
diff --git a/target/linux/ipq40xx/generic/target.mk b/target/linux/ipq40xx/generic/target.mk
index 90c1b762af..4ff40dea2b 100644
--- a/target/linux/ipq40xx/generic/target.mk
+++ b/target/linux/ipq40xx/generic/target.mk
@@ -1,3 +1,3 @@
BOARDNAME:=Generic
-FEATURES+=emmc
+FEATURES+=emmc nand
DEFAULT_PACKAGES += ath10k-board-qca4019
diff --git a/target/linux/ipq40xx/image/generic.mk b/target/linux/ipq40xx/image/generic.mk
index 929cff72ea..a2931ff01e 100644
--- a/target/linux/ipq40xx/image/generic.mk
+++ b/target/linux/ipq40xx/image/generic.mk
@@ -179,12 +179,14 @@ endef
define Device/aruba_ap-303
$(call Device/aruba_glenmorangie)
DEVICE_MODEL := AP-303
+ DEVICE_DTS_CONFIG := Glenmorangie@1
endef
TARGET_DEVICES += aruba_ap-303
define Device/aruba_ap-303h
$(call Device/aruba_glenmorangie)
DEVICE_MODEL := AP-303H
+ DEVICE_DTS_CONFIG := Aberlour@1
endef
TARGET_DEVICES += aruba_ap-303h
@@ -192,6 +194,7 @@ define Device/aruba_ap-365
$(call Device/aruba_glenmorangie)
DEVICE_MODEL := AP-365
DEVICE_PACKAGES := kmod-hwmon-ad7418
+ DEVICE_DTS_CONFIG := Bunker@1
endef
TARGET_DEVICES += aruba_ap-365
@@ -1279,7 +1282,7 @@ TARGET_DEVICES += zte_mf289f
define Device/zyxel_nbg6617
$(call Device/FitImageLzma)
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
DEVICE_MODEL := NBG6617
SOC := qcom-ipq4018
KERNEL_SIZE := 4096k
@@ -1289,7 +1292,7 @@ define Device/zyxel_nbg6617
RAS_VERSION := "$(VERSION_DIST) $(REVISION)"
IMAGE/sysupgrade.bin := append-kernel | append-rootfs | pad-rootfs | append-metadata
IMAGES += factory.bin
-# The ZyXEL firmware allows flashing thru the web-gui only when the rootfs is
+# The Zyxel firmware allows flashing thru the web-gui only when the rootfs is
# at least as large as the one of the initial firmware image (not the current
# one on the device). This only applies to the Web-UI, the bootlaoder ignores
# this minimum-size. However, the larger image can be flashed both ways.
@@ -1301,7 +1304,7 @@ TARGET_DEVICES += zyxel_nbg6617
define Device/zyxel_wre6606
$(call Device/FitImage)
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
DEVICE_MODEL := WRE6606
DEVICE_DTS_CONFIG := config@4
SOC := qcom-ipq4018
diff --git a/target/linux/ipq40xx/mikrotik/config-default b/target/linux/ipq40xx/mikrotik/config-default
index ab470ecb41..805e6db23b 100644
--- a/target/linux/ipq40xx/mikrotik/config-default
+++ b/target/linux/ipq40xx/mikrotik/config-default
@@ -4,3 +4,9 @@ CONFIG_MTD_ROUTERBOOT_PARTS=y
CONFIG_MTD_SPI_NOR_USE_VARIABLE_ERASE=y
CONFIG_MTD_SPLIT_MINOR_FW=y
# CONFIG_NVMEM_LAYOUT_MIKROTIK is not set
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_BEB_LIMIT=20
+CONFIG_MTD_UBI_BLOCK=y
+CONFIG_MTD_UBI_NVMEM=y
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+CONFIG_UBIFS_FS=y
diff --git a/target/linux/ipq40xx/mikrotik/target.mk b/target/linux/ipq40xx/mikrotik/target.mk
index 4530a90985..12bf8a4cd3 100644
--- a/target/linux/ipq40xx/mikrotik/target.mk
+++ b/target/linux/ipq40xx/mikrotik/target.mk
@@ -1,4 +1,4 @@
BOARDNAME:=MikroTik
-FEATURES += minor
+FEATURES += minor nand
KERNEL_IMAGES:=vmlinux
IMAGES_DIR:=compressed
diff --git a/target/linux/ipq40xx/patches-6.6/700-net-ipqess-introduce-the-Qualcomm-IPQESS-driver.patch b/target/linux/ipq40xx/patches-6.6/700-net-ipqess-introduce-the-Qualcomm-IPQESS-driver.patch
index 4910307c88..d9ecf4b640 100644
--- a/target/linux/ipq40xx/patches-6.6/700-net-ipqess-introduce-the-Qualcomm-IPQESS-driver.patch
+++ b/target/linux/ipq40xx/patches-6.6/700-net-ipqess-introduce-the-Qualcomm-IPQESS-driver.patch
@@ -996,7 +996,7 @@ Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+ .ndo_uninit = ipqess_uninit,
+ .ndo_open = ipqess_open,
+ .ndo_stop = ipqess_stop,
-+ .ndo_do_ioctl = ipqess_do_ioctl,
++ .ndo_eth_ioctl = ipqess_do_ioctl,
+ .ndo_start_xmit = ipqess_xmit,
+ .ndo_get_stats = ipqess_get_stats,
+ .ndo_set_mac_address = ipqess_set_mac_address,
diff --git a/target/linux/ipq40xx/patches-6.6/999-atm-mpoa-intel-dsl-phy-support.patch b/target/linux/ipq40xx/patches-6.6/999-atm-mpoa-intel-dsl-phy-support.patch
index 3d5b7afe8c..eab26ccb11 100644
--- a/target/linux/ipq40xx/patches-6.6/999-atm-mpoa-intel-dsl-phy-support.patch
+++ b/target/linux/ipq40xx/patches-6.6/999-atm-mpoa-intel-dsl-phy-support.patch
@@ -4,7 +4,7 @@ Subject: [PATCH] UGW_SW-29163: ATM oam support
--- a/drivers/net/ppp/ppp_generic.c
+++ b/drivers/net/ppp/ppp_generic.c
-@@ -2953,6 +2953,22 @@ char *ppp_dev_name(struct ppp_channel *c
+@@ -2968,6 +2968,22 @@ char *ppp_dev_name(struct ppp_channel *c
return name;
}
@@ -27,7 +27,7 @@ Subject: [PATCH] UGW_SW-29163: ATM oam support
/*
* Disconnect a channel from the generic layer.
-@@ -3599,6 +3615,7 @@ EXPORT_SYMBOL(ppp_unregister_channel);
+@@ -3614,6 +3630,7 @@ EXPORT_SYMBOL(ppp_unregister_channel);
EXPORT_SYMBOL(ppp_channel_index);
EXPORT_SYMBOL(ppp_unit_number);
EXPORT_SYMBOL(ppp_dev_name);
diff --git a/target/linux/ipq806x/files-6.6/arch/arm/boot/dts/qcom/qcom-ipq8065-nbg6817.dts b/target/linux/ipq806x/files-6.6/arch/arm/boot/dts/qcom/qcom-ipq8065-nbg6817.dts
index 7d22b4f541..9a9251e9b9 100644
--- a/target/linux/ipq806x/files-6.6/arch/arm/boot/dts/qcom/qcom-ipq8065-nbg6817.dts
+++ b/target/linux/ipq806x/files-6.6/arch/arm/boot/dts/qcom/qcom-ipq8065-nbg6817.dts
@@ -4,7 +4,7 @@
#include <dt-bindings/leds/common.h>
/ {
- model = "ZyXEL NBG6817";
+ model = "Zyxel NBG6817";
compatible = "zyxel,nbg6817", "qcom,ipq8065", "qcom,ipq8064";
memory@0 {
diff --git a/target/linux/ipq806x/image/generic.mk b/target/linux/ipq806x/image/generic.mk
index b5bf8898ab..112793d5fd 100644
--- a/target/linux/ipq806x/image/generic.mk
+++ b/target/linux/ipq806x/image/generic.mk
@@ -74,7 +74,7 @@ define Device/TpSafeImage
tplink-safeloader sysupgrade | append-metadata
endef
-define Device/ZyXELImage
+define Device/ZyxelImage
KERNEL_SUFFIX := -uImage
KERNEL = kernel-bin | append-dtb | uImage none | \
pad-to $$(KERNEL_SIZE)
@@ -578,7 +578,7 @@ TARGET_DEVICES += ubnt_unifi-ac-hd
define Device/zyxel_nbg6817
$(Device/dsa-migration)
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
DEVICE_MODEL := NBG6817
SOC := qcom-ipq8065
KERNEL_SIZE := 4096k
@@ -590,6 +590,6 @@ define Device/zyxel_nbg6817
SUPPORTED_DEVICES += nbg6817
DEVICE_PACKAGES := ath10k-firmware-qca9984-ct e2fsprogs \
kmod-fs-ext4 losetup
- $(call Device/ZyXELImage)
+ $(call Device/ZyxelImage)
endef
TARGET_DEVICES += zyxel_nbg6817
diff --git a/target/linux/kirkwood/Makefile b/target/linux/kirkwood/Makefile
index 44eaf925a1..2010f9a812 100644
--- a/target/linux/kirkwood/Makefile
+++ b/target/linux/kirkwood/Makefile
@@ -11,8 +11,7 @@ FEATURES:=rtc usb nand squashfs ramdisk
CPU_TYPE:=xscale
SUBTARGETS:=generic
-KERNEL_PATCHVER:=6.1
-KERNEL_TESTING_PATCHVER:=6.6
+KERNEL_PATCHVER:=6.6
include $(INCLUDE_DIR)/target.mk
diff --git a/target/linux/kirkwood/config-6.1 b/target/linux/kirkwood/config-6.1
deleted file mode 100644
index 6d21143e96..0000000000
--- a/target/linux/kirkwood/config-6.1
+++ /dev/null
@@ -1,309 +0,0 @@
-CONFIG_ALIGNMENT_TRAP=y
-CONFIG_ARCH_32BIT_OFF_T=y
-CONFIG_ARCH_HIBERNATION_POSSIBLE=y
-CONFIG_ARCH_KEEP_MEMBLOCK=y
-CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
-CONFIG_ARCH_MULTIPLATFORM=y
-CONFIG_ARCH_MULTI_CPU_AUTO=y
-# CONFIG_ARCH_MULTI_V4 is not set
-# CONFIG_ARCH_MULTI_V4T is not set
-CONFIG_ARCH_MULTI_V4_V5=y
-CONFIG_ARCH_MULTI_V5=y
-CONFIG_ARCH_MVEBU=y
-CONFIG_ARCH_NR_GPIO=0
-CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y
-CONFIG_ARCH_SELECT_MEMORY_MODEL=y
-CONFIG_ARCH_SPARSEMEM_ENABLE=y
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
-CONFIG_ARM=y
-# CONFIG_ARMADA_37XX_WATCHDOG is not set
-# CONFIG_ARMADA_THERMAL is not set
-CONFIG_ARM_APPENDED_DTB=y
-CONFIG_ARM_ATAG_DTB_COMPAT=y
-CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER=y
-CONFIG_ARM_HAS_GROUP_RELOCS=y
-# CONFIG_ARM_KIRKWOOD_CPUIDLE is not set
-CONFIG_ARM_L1_CACHE_SHIFT=5
-# CONFIG_ARM_MVEBU_V7_CPUIDLE is not set
-CONFIG_ARM_PATCH_PHYS_VIRT=y
-# CONFIG_ARM_THUMB is not set
-CONFIG_ARM_UNWIND=y
-CONFIG_ATA=y
-CONFIG_ATAGS=y
-CONFIG_ATA_LEDS=y
-CONFIG_AUTO_ZRELADDR=y
-CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_BLK_MQ_PCI=y
-CONFIG_CACHE_FEROCEON_L2=y
-# CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH is not set
-CONFIG_CC_HAVE_STACKPROTECTOR_TLS=y
-CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
-CONFIG_CC_NO_ARRAY_BOUNDS=y
-CONFIG_CLKSRC_MMIO=y
-CONFIG_CLONE_BACKWARDS=y
-CONFIG_COMMON_CLK=y
-CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
-CONFIG_COMPAT_32BIT_TIME=y
-CONFIG_CPU_32v5=y
-CONFIG_CPU_ABRT_EV5T=y
-CONFIG_CPU_CACHE_VIVT=y
-CONFIG_CPU_COPY_FEROCEON=y
-CONFIG_CPU_CP15=y
-CONFIG_CPU_CP15_MMU=y
-CONFIG_CPU_FEROCEON=y
-# CONFIG_CPU_FEROCEON_OLD_ID is not set
-CONFIG_CPU_IDLE=y
-CONFIG_CPU_IDLE_GOV_LADDER=y
-CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_CPU_PABRT_LEGACY=y
-CONFIG_CPU_PM=y
-CONFIG_CPU_THERMAL=y
-CONFIG_CPU_THUMB_CAPABLE=y
-CONFIG_CPU_TLB_FEROCEON=y
-CONFIG_CPU_USE_DOMAINS=y
-CONFIG_CRC16=y
-# CONFIG_CRC32_SARWATE is not set
-CONFIG_CRC32_SLICEBY8=y
-CONFIG_CRYPTO_CRC32C=y
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_DES=y
-CONFIG_CRYPTO_DEV_MARVELL=y
-CONFIG_CRYPTO_DEV_MARVELL_CESA=y
-CONFIG_CRYPTO_HASH_INFO=y
-CONFIG_CRYPTO_HW=y
-CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
-CONFIG_CRYPTO_LIB_DES=y
-CONFIG_CRYPTO_LIB_SHA1=y
-CONFIG_CRYPTO_LIB_UTILS=y
-CONFIG_CRYPTO_LZO=y
-CONFIG_CRYPTO_RNG2=y
-CONFIG_CRYPTO_ZSTD=y
-CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_LL=y
-CONFIG_DEBUG_LL_INCLUDE="debug/8250.S"
-CONFIG_DEBUG_MVEBU_UART0_ALTERNATE=y
-# CONFIG_DEBUG_MVEBU_UART1_ALTERNATE is not set
-CONFIG_DEBUG_UART_8250=y
-CONFIG_DEBUG_UART_8250_SHIFT=2
-CONFIG_DEBUG_UART_PHYS=0xf1012000
-CONFIG_DEBUG_UART_VIRT=0xfed12000
-CONFIG_DMA_OPS=y
-CONFIG_DNOTIFY=y
-CONFIG_DTC=y
-# CONFIG_EARLY_PRINTK is not set
-CONFIG_EDAC_ATOMIC_SCRUB=y
-CONFIG_EDAC_SUPPORT=y
-CONFIG_EXCLUSIVE_SYSTEM_RAM=y
-CONFIG_FIXED_PHY=y
-CONFIG_FIX_EARLYCON_MEM=y
-CONFIG_FORCE_PCI=y
-CONFIG_FWNODE_MDIO=y
-CONFIG_FW_LOADER_PAGED_BUF=y
-CONFIG_FW_LOADER_SYSFS=y
-CONFIG_GCC11_NO_ARRAY_BOUNDS=y
-CONFIG_GENERIC_ALLOCATOR=y
-CONFIG_GENERIC_ATOMIC64=y
-CONFIG_GENERIC_BUG=y
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_GENERIC_CPU_AUTOPROBE=y
-CONFIG_GENERIC_EARLY_IOREMAP=y
-CONFIG_GENERIC_IDLE_POLL_SETUP=y
-CONFIG_GENERIC_IRQ_CHIP=y
-CONFIG_GENERIC_IRQ_MULTI_HANDLER=y
-CONFIG_GENERIC_IRQ_SHOW=y
-CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
-CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y
-CONFIG_GENERIC_PCI_IOMAP=y
-CONFIG_GENERIC_PHY=y
-CONFIG_GENERIC_PINCONF=y
-CONFIG_GENERIC_SCHED_CLOCK=y
-CONFIG_GENERIC_SMP_IDLE_THREAD=y
-CONFIG_GENERIC_STRNCPY_FROM_USER=y
-CONFIG_GENERIC_STRNLEN_USER=y
-CONFIG_GLOB=y
-CONFIG_GPIOLIB_IRQCHIP=y
-CONFIG_GPIO_CDEV=y
-CONFIG_GPIO_MVEBU=y
-CONFIG_GRO_CELLS=y
-CONFIG_HARDIRQS_SW_RESEND=y
-CONFIG_HAS_DMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT_MAP=y
-CONFIG_HWMON=y
-CONFIG_HW_RANDOM=y
-CONFIG_HW_RANDOM_OMAP=y
-CONFIG_HZ_FIXED=0
-CONFIG_HZ_PERIODIC=y
-CONFIG_I2C=y
-CONFIG_I2C_BOARDINFO=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_MV64XXX=y
-# CONFIG_I2C_PXA is not set
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_IRQCHIP=y
-CONFIG_IRQSTACKS=y
-CONFIG_IRQ_DOMAIN=y
-CONFIG_IRQ_FORCED_THREADING=y
-CONFIG_IRQ_WORK=y
-CONFIG_KIRKWOOD_CLK=y
-CONFIG_KIRKWOOD_THERMAL=y
-CONFIG_LEDS_GPIO=y
-CONFIG_LEDS_NETXBIG=y
-CONFIG_LEDS_NS2=y
-CONFIG_LIBFDT=y
-CONFIG_LOCK_DEBUGGING_SUPPORT=y
-CONFIG_LZO_COMPRESS=y
-CONFIG_LZO_DECOMPRESS=y
-CONFIG_MACH_KIRKWOOD=y
-CONFIG_MACH_MVEBU_ANY=y
-CONFIG_MANGLE_BOOTARGS=y
-CONFIG_MARVELL_PHY=y
-CONFIG_MDIO_BUS=y
-CONFIG_MDIO_DEVICE=y
-CONFIG_MDIO_DEVRES=y
-CONFIG_MEMFD_CREATE=y
-CONFIG_MIGRATION=y
-CONFIG_MODULES_USE_ELF_REL=y
-# CONFIG_MTD_CFI is not set
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_NAND_CORE=y
-CONFIG_MTD_NAND_ECC=y
-CONFIG_MTD_NAND_ECC_SW_HAMMING=y
-# CONFIG_MTD_NAND_MARVELL is not set
-CONFIG_MTD_NAND_ORION=y
-CONFIG_MTD_RAW_NAND=y
-CONFIG_MTD_SPI_NOR=y
-CONFIG_MTD_SPLIT_FIRMWARE=y
-CONFIG_MTD_SPLIT_UIMAGE_FW=y
-CONFIG_MTD_UBI=y
-CONFIG_MTD_UBI_BEB_LIMIT=20
-CONFIG_MTD_UBI_BLOCK=y
-CONFIG_MTD_UBI_WL_THRESHOLD=4096
-CONFIG_MV643XX_ETH=y
-CONFIG_MVEBU_CLK_COMMON=y
-CONFIG_MVEBU_MBUS=y
-CONFIG_MVMDIO=y
-# CONFIG_MVNETA is not set
-# CONFIG_MVPP2 is not set
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NEED_KUSER_HELPERS=y
-CONFIG_NEED_PER_CPU_KM=y
-CONFIG_NET_DEVLINK=y
-CONFIG_NET_DSA=y
-CONFIG_NET_DSA_MV88E6XXX=y
-CONFIG_NET_DSA_TAG_DSA=y
-CONFIG_NET_DSA_TAG_DSA_COMMON=y
-CONFIG_NET_DSA_TAG_EDSA=y
-CONFIG_NET_SELFTESTS=y
-CONFIG_NET_SWITCHDEV=y
-CONFIG_NLS=y
-CONFIG_NVMEM=y
-CONFIG_OF=y
-CONFIG_OF_ADDRESS=y
-CONFIG_OF_EARLY_FLATTREE=y
-CONFIG_OF_FLATTREE=y
-CONFIG_OF_GPIO=y
-CONFIG_OF_IRQ=y
-CONFIG_OF_KOBJ=y
-CONFIG_OF_MDIO=y
-CONFIG_OLD_SIGACTION=y
-CONFIG_OLD_SIGSUSPEND3=y
-CONFIG_ORION_IRQCHIP=y
-CONFIG_ORION_TIMER=y
-CONFIG_ORION_WATCHDOG=y
-CONFIG_OUTER_CACHE=y
-CONFIG_PAGE_OFFSET=0xC0000000
-CONFIG_PAGE_POOL=y
-CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
-CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
-CONFIG_PCI=y
-CONFIG_PCI_BRIDGE_EMUL=y
-CONFIG_PCI_DOMAINS=y
-CONFIG_PCI_DOMAINS_GENERIC=y
-CONFIG_PCI_MVEBU=y
-CONFIG_PERF_USE_VMALLOC=y
-CONFIG_PGTABLE_LEVELS=2
-CONFIG_PHYLIB=y
-CONFIG_PHYLINK=y
-# CONFIG_PHY_MVEBU_A3700_UTMI is not set
-# CONFIG_PHY_MVEBU_A38X_COMPHY is not set
-CONFIG_PHY_MVEBU_SATA=y
-CONFIG_PINCTRL=y
-CONFIG_PINCTRL_KIRKWOOD=y
-CONFIG_PINCTRL_MVEBU=y
-# CONFIG_PINCTRL_SINGLE is not set
-CONFIG_PINCTRL_SX150X=y
-CONFIG_PLAT_ORION=y
-CONFIG_POWER_RESET=y
-CONFIG_POWER_RESET_GPIO=y
-CONFIG_POWER_RESET_LINKSTATION=y
-CONFIG_POWER_SUPPLY=y
-CONFIG_PREEMPT_NONE_BUILD=y
-CONFIG_PTP_1588_CLOCK_OPTIONAL=y
-CONFIG_RANDSTRUCT_NONE=y
-CONFIG_RATIONAL=y
-CONFIG_REGMAP=y
-CONFIG_REGMAP_MMIO=y
-CONFIG_REGULATOR=y
-CONFIG_REGULATOR_FIXED_VOLTAGE=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_MV=y
-CONFIG_RTC_I2C_AND_SPI=y
-CONFIG_RTC_MC146818_LIB=y
-CONFIG_SCSI=y
-CONFIG_SCSI_COMMON=y
-CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y
-CONFIG_SERIAL_8250_FSL=y
-CONFIG_SERIAL_MCTRL_GPIO=y
-# CONFIG_SERIAL_MVEBU_UART is not set
-CONFIG_SERIAL_OF_PLATFORM=y
-CONFIG_SGL_ALLOC=y
-CONFIG_SG_POOL=y
-CONFIG_SOC_BUS=y
-CONFIG_SOFTIRQ_ON_OWN_STACK=y
-CONFIG_SPARSE_IRQ=y
-CONFIG_SPI=y
-# CONFIG_SPI_ARMADA_3700 is not set
-CONFIG_SPI_MASTER=y
-CONFIG_SPI_MEM=y
-CONFIG_SPI_ORION=y
-CONFIG_SPLIT_PTLOCK_CPUS=999999
-CONFIG_SRAM=y
-CONFIG_SRAM_EXEC=y
-CONFIG_SRCU=y
-CONFIG_SWPHY=y
-CONFIG_SYS_SUPPORTS_APM_EMULATION=y
-CONFIG_THERMAL=y
-CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
-CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
-CONFIG_THERMAL_GOV_STEP_WISE=y
-CONFIG_THERMAL_HWMON=y
-CONFIG_THERMAL_OF=y
-CONFIG_THREAD_INFO_IN_TASK=y
-CONFIG_TICK_CPU_ACCOUNTING=y
-CONFIG_TIMER_OF=y
-CONFIG_TIMER_PROBE=y
-CONFIG_TINY_SRCU=y
-CONFIG_UBIFS_FS=y
-CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
-CONFIG_UNWINDER_ARM=y
-CONFIG_USB=y
-CONFIG_USB_COMMON=y
-CONFIG_USB_LED_TRIG=y
-CONFIG_USB_SUPPORT=y
-CONFIG_USE_OF=y
-# CONFIG_VFP is not set
-CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_WAN=y
-CONFIG_WATCHDOG_CORE=y
-CONFIG_XXHASH=y
-CONFIG_XZ_DEC_ARM=y
-CONFIG_XZ_DEC_BCJ=y
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZSTD_COMMON=y
-CONFIG_ZSTD_COMPRESS=y
-CONFIG_ZSTD_DECOMPRESS=y
diff --git a/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-nsa310b.dts b/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-nsa310b.dts
index 12e51d6656..594be97929 100644
--- a/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-nsa310b.dts
+++ b/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-nsa310b.dts
@@ -8,7 +8,7 @@
*/
/ {
- model = "ZyXEL NSA310b";
+ model = "Zyxel NSA310b";
compatible = "zyxel,nsa310b", "zyxel,nsa310", "marvell,kirkwood-88f6281", "marvell,kirkwood";
aliases {
diff --git a/target/linux/kirkwood/files-6.6/arch/arm/boot/dts/marvell/kirkwood-nsa310b.dts b/target/linux/kirkwood/files-6.6/arch/arm/boot/dts/marvell/kirkwood-nsa310b.dts
index 12e51d6656..594be97929 100644
--- a/target/linux/kirkwood/files-6.6/arch/arm/boot/dts/marvell/kirkwood-nsa310b.dts
+++ b/target/linux/kirkwood/files-6.6/arch/arm/boot/dts/marvell/kirkwood-nsa310b.dts
@@ -8,7 +8,7 @@
*/
/ {
- model = "ZyXEL NSA310b";
+ model = "Zyxel NSA310b";
compatible = "zyxel,nsa310b", "zyxel,nsa310", "marvell,kirkwood-88f6281", "marvell,kirkwood";
aliases {
diff --git a/target/linux/kirkwood/image/Makefile b/target/linux/kirkwood/image/Makefile
index 2bd2f64159..eaced92657 100644
--- a/target/linux/kirkwood/image/Makefile
+++ b/target/linux/kirkwood/image/Makefile
@@ -112,9 +112,7 @@ endef
define Device/Default
PROFILES := Default
-ifdef CONFIG_LINUX_6_6
DEVICE_DTS_DIR := $(DTS_DIR)/marvell
-endif
DEVICE_DTS = kirkwood-$(lastword $(subst _, ,$(1)))
KERNEL_DEPENDS = $$(wildcard $(DTS_DIR)/$$(DEVICE_DTS).dts)
KERNEL := kernel-bin | append-dtb | uImage none
@@ -375,7 +373,7 @@ endef
TARGET_DEVICES += seagate_goflexhome
define Device/zyxel_nsa310b
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
DEVICE_MODEL := NSA310b
DEVICE_PACKAGES := kmod-ata-marvell-sata kmod-r8169 kmod-fs-ext4 \
kmod-gpio-button-hotplug kmod-hwmon-lm85 kmod-rtc-mv
@@ -384,7 +382,7 @@ endef
TARGET_DEVICES += zyxel_nsa310b
define Device/zyxel_nsa310s
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
DEVICE_MODEL := NSA310S
DEVICE_PACKAGES := kmod-ata-marvell-sata kmod-fs-ext4 \
kmod-gpio-button-hotplug kmod-rtc-mv
@@ -392,7 +390,7 @@ endef
TARGET_DEVICES += zyxel_nsa310s
define Device/zyxel_nsa325
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
DEVICE_MODEL := NSA325
DEVICE_VARIANT := v1/v2
DEVICE_PACKAGES := kmod-ata-marvell-sata kmod-fs-ext4 \
diff --git a/target/linux/kirkwood/image/generic.mk b/target/linux/kirkwood/image/generic.mk
deleted file mode 100644
index fff46be172..0000000000
--- a/target/linux/kirkwood/image/generic.mk
+++ /dev/null
@@ -1,177 +0,0 @@
-define Device/checkpoint_l-50
- DEVICE_VENDOR := Check Point
- DEVICE_MODEL := L-50
- DEVICE_PACKAGES := kmod-ath9k kmod-gpio-button-hotplug kmod-mvsdio \
- kmod-rtc-s35390a kmod-usb-ledtrig-usbport wpad-basic-mbedtls
- IMAGES := sysupgrade.bin
-endef
-TARGET_DEVICES += checkpoint_l-50
-
-define Device/cisco_on100
- DEVICE_VENDOR := Cisco Systems
- DEVICE_MODEL := ON100
- KERNEL_SIZE := 5376k
- KERNEL_IN_UBI :=
- UBINIZE_OPTS := -E 5
- IMAGE/factory.bin := append-kernel | pad-to $$$$(KERNEL_SIZE) | append-ubi
- DEVICE_PACKAGES := kmod-mvsdio kmod-rtc-mv
- SUPPORTED_DEVICES += on100
-endef
-TARGET_DEVICES += cisco_on100
-
-define Device/cloudengines_pogoe02
- DEVICE_VENDOR := Cloud Engines
- DEVICE_MODEL := Pogoplug E02
- DEVICE_DTS := kirkwood-pogo_e02
- DEVICE_PACKAGES := kmod-rtc-mv
- SUPPORTED_DEVICES += pogo_e02
-endef
-TARGET_DEVICES += cloudengines_pogoe02
-
-define Device/cloudengines_pogoplugv4
- DEVICE_VENDOR := Cloud Engines
- DEVICE_MODEL := Pogoplug V4
- DEVICE_DTS := kirkwood-pogoplug-series-4
- DEVICE_PACKAGES := kmod-ata-marvell-sata kmod-fs-ext4 kmod-mvsdio kmod-usb3 \
- kmod-gpio-button-hotplug kmod-rtc-mv
-endef
-TARGET_DEVICES += cloudengines_pogoplugv4
-
-define Device/ctera_c200-v1
- DEVICE_VENDOR := Ctera
- DEVICE_MODEL := C200
- DEVICE_VARIANT := V1
- DEVICE_PACKAGES := kmod-ata-marvell-sata kmod-gpio-button-hotplug \
- kmod-hwmon-lm63 kmod-rtc-s35390a kmod-usb-ledtrig-usbport
- KERNEL := kernel-bin | append-dtb | uImage none | ctera-firmware
- KERNEL_IN_UBI :=
- KERNEL_SUFFIX := -factory.firm
- IMAGES := sysupgrade.bin
-endef
-TARGET_DEVICES += ctera_c200-v1
-
-define Device/endian_4i-edge-200
- DEVICE_VENDOR := Endian
- DEVICE_MODEL := 4i Edge 200
- DEVICE_ALT0_VENDOR := Endian
- DEVICE_ALT0_MODEL := UTM Mini Firewall
- DEVICE_PACKAGES := kmod-ath9k kmod-mvsdio wpad-basic-mbedtls kmod-rtc-mv
- KERNEL_SIZE := 4096k
- IMAGES := sysupgrade.bin
-endef
-TARGET_DEVICES += endian_4i-edge-200
-
-define Device/globalscale_sheevaplug
- DEVICE_VENDOR := Globalscale
- DEVICE_MODEL := Sheevaplug
- DEVICE_PACKAGES := kmod-mvsdio kmod-rtc-mv
-endef
-TARGET_DEVICES += globalscale_sheevaplug
-
-define Device/iom_iconnect-1.1
- DEVICE_VENDOR := Iomega
- DEVICE_MODEL := Iconnect
- DEVICE_PACKAGES := kmod-rtc-mv
- DEVICE_DTS := kirkwood-iconnect
- SUPPORTED_DEVICES += iconnect
-endef
-TARGET_DEVICES += iom_iconnect-1.1
-
-define Device/iptime_nas1
- DEVICE_VENDOR := ipTIME
- DEVICE_MODEL := NAS1
- DEVICE_PACKAGES := kmod-ata-marvell-sata kmod-fs-ext4 \
- kmod-gpio-button-hotplug kmod-gpio-pca953x kmod-hwmon-drivetemp \
- kmod-hwmon-gpiofan kmod-usb-ledtrig-usbport kmod-rtc-mv kmod-thermal \
- -uboot-envtools
- KERNEL := $$(KERNEL) | iptime-naspkg nas1
- BLOCKSIZE := 256k
- IMAGE_SIZE := 15872k
- IMAGES := sysupgrade.bin
- IMAGE/sysupgrade.bin := append-kernel | append-rootfs | pad-rootfs | \
- check-size | append-metadata
-endef
-TARGET_DEVICES += iptime_nas1
-
-define Device/netgear_readynas-duo-v2
- DEVICE_VENDOR := NETGEAR
- DEVICE_MODEL := ReadyNAS Duo
- DEVICE_VARIANT := v2
- DEVICE_DTS := kirkwood-netgear_readynas_duo_v2
- KERNEL_IN_UBI :=
- IMAGES := sysupgrade.bin
- DEVICE_PACKAGES := kmod-ata-marvell-sata kmod-fs-ext4 \
- kmod-gpio-button-hotplug kmod-hwmon-g762 kmod-rtc-rs5c372a kmod-usb3
-endef
-TARGET_DEVICES += netgear_readynas-duo-v2
-
-define Device/raidsonic_ib-nas62x0
- DEVICE_VENDOR := RaidSonic
- DEVICE_MODEL := ICY BOX IB-NAS62x0
- DEVICE_DTS := kirkwood-ib62x0
- DEVICE_PACKAGES := kmod-ata-marvell-sata kmod-fs-ext4 kmod-rtc-mv
- SUPPORTED_DEVICES += ib62x0
-endef
-TARGET_DEVICES += raidsonic_ib-nas62x0
-
-define Device/seagate_blackarmor-nas220
- DEVICE_VENDOR := Seagate
- DEVICE_MODEL := Blackarmor NAS220
- DEVICE_PACKAGES := kmod-hwmon-adt7475 kmod-fs-ext4 kmod-ata-marvell-sata \
- mdadm kmod-gpio-button-hotplug kmod-rtc-mv
- PAGESIZE := 512
- SUBPAGESIZE := 256
- BLOCKSIZE := 16k
- UBINIZE_OPTS := -e 1
-endef
-TARGET_DEVICES += seagate_blackarmor-nas220
-
-define Device/seagate_dockstar
- DEVICE_VENDOR := Seagate
- DEVICE_MODEL := FreeAgent Dockstar
- DEVICE_PACKAGES := kmod-rtc-mv
- SUPPORTED_DEVICES += dockstar
-endef
-TARGET_DEVICES += seagate_dockstar
-
-define Device/seagate_goflexnet
- DEVICE_VENDOR := Seagate
- DEVICE_MODEL := GoFlexNet
- DEVICE_PACKAGES := kmod-ata-marvell-sata kmod-fs-ext4 kmod-rtc-mv
- SUPPORTED_DEVICES += goflexnet
-endef
-TARGET_DEVICES += seagate_goflexnet
-
-define Device/seagate_goflexhome
- DEVICE_VENDOR := Seagate
- DEVICE_MODEL := GoFlexHome
- DEVICE_PACKAGES := kmod-ata-marvell-sata kmod-fs-ext4 kmod-rtc-mv
- SUPPORTED_DEVICES += goflexhome
-endef
-TARGET_DEVICES += seagate_goflexhome
-
-define Device/zyxel_nsa310b
- DEVICE_VENDOR := ZyXEL
- DEVICE_MODEL := NSA310b
- DEVICE_PACKAGES := kmod-ata-marvell-sata kmod-r8169 kmod-fs-ext4 \
- kmod-gpio-button-hotplug kmod-hwmon-lm85 kmod-rtc-mv
- SUPPORTED_DEVICES += nsa310b
-endef
-TARGET_DEVICES += zyxel_nsa310b
-
-define Device/zyxel_nsa310s
- DEVICE_VENDOR := ZyXEL
- DEVICE_MODEL := NSA310S
- DEVICE_PACKAGES := kmod-ata-marvell-sata kmod-fs-ext4 kmod-gpio-button-hotplug
-endef
-TARGET_DEVICES += zyxel_nsa310s
-
-define Device/zyxel_nsa325
- DEVICE_VENDOR := ZyXEL
- DEVICE_MODEL := NSA325
- DEVICE_VARIANT := v1/v2
- DEVICE_PACKAGES := kmod-ata-marvell-sata kmod-fs-ext4 \
- kmod-gpio-button-hotplug kmod-rtc-pcf8563 kmod-usb3
- SUPPORTED_DEVICES += nsa325
-endef
-TARGET_DEVICES += zyxel_nsa325
diff --git a/target/linux/kirkwood/patches-6.1/002-6.2-ARM-dts-kirkwood-Add-Zyxel-NSA310S-board.patch b/target/linux/kirkwood/patches-6.1/002-6.2-ARM-dts-kirkwood-Add-Zyxel-NSA310S-board.patch
deleted file mode 100644
index 6a8e8e8c9b..0000000000
--- a/target/linux/kirkwood/patches-6.1/002-6.2-ARM-dts-kirkwood-Add-Zyxel-NSA310S-board.patch
+++ /dev/null
@@ -1,301 +0,0 @@
-From e977a103840c57d72b52cbc8c17f87f86ef9aa8d Mon Sep 17 00:00:00 2001
-From: Pawel Dembicki <paweldembicki@gmail.com>
-Date: Sat, 29 Oct 2022 22:57:38 +0200
-Subject: [PATCH] ARM: dts: kirkwood: Add Zyxel NSA310S board
-
-Zyxel NSA310S is a NAS based on Marvell kirkwood SoC.
-
-Specification:
- - Processor Marvell 88F6702 1 GHz
- - 256MB RAM
- - 128MB NAND
- - 1x GBE LAN port (PHY: Marvell 88E1318)
- - 2x USB 2.0
- - 1x SATA
- - 3x button
- - 7x leds
- - serial on J1 connector (115200 8N1) (GND-NOPIN-RX-TX-VCC)
-
-Tested-by: Tony Dinh <mibodhi@gmail.com>
-Signed-off-by: Pawel Dembicki <paweldembicki@gmail.com>
-Acked-by: Adam Baker <linux@baker-net.org.uk>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Gregory CLEMENT <gregory.clement@bootlin.com>
----
- arch/arm/boot/dts/Makefile | 1 +
- arch/arm/boot/dts/kirkwood-nsa310s.dts | 259 +++++++++++++++++++++++++
- 2 files changed, 260 insertions(+)
- create mode 100644 arch/arm/boot/dts/kirkwood-nsa310s.dts
-
---- a/arch/arm/boot/dts/Makefile
-+++ b/arch/arm/boot/dts/Makefile
-@@ -356,6 +356,7 @@ dtb-$(CONFIG_MACH_KIRKWOOD) += \
- kirkwood-ns2mini.dtb \
- kirkwood-nsa310.dtb \
- kirkwood-nsa310a.dtb \
-+ kirkwood-nsa310s.dtb \
- kirkwood-nsa320.dtb \
- kirkwood-nsa325.dtb \
- kirkwood-openblocks_a6.dtb \
---- /dev/null
-+++ b/arch/arm/boot/dts/kirkwood-nsa310s.dts
-@@ -0,0 +1,259 @@
-+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
-+/*
-+ * ZyXEL NSA310S Board Description
-+ * Copyright 2020-2022 Pawel Dembicki <paweldembicki@gmail.com>
-+ * Copyright (c) 2015-2021, Tony Dinh <mibodhi@gmail.com>
-+ * Copyright (c) 2014, Adam Baker <linux@baker-net.org.uk>
-+ * Based upon the board setup file created by Peter Schildmann
-+ */
-+/dts-v1/;
-+
-+#include "kirkwood.dtsi"
-+#include "kirkwood-6281.dtsi"
-+#include <dt-bindings/leds/common.h>
-+
-+/ {
-+ model = "ZyXEL NSA310S";
-+ compatible = "zyxel,nsa310s", "marvell,kirkwood-88f6702", "marvell,kirkwood";
-+
-+ memory {
-+ device_type = "memory";
-+ reg = <0x00000000 0x10000000>;
-+ };
-+
-+ chosen {
-+ bootargs = "console=ttyS0,115200n8 earlyprintk";
-+ stdout-path = &uart0;
-+ };
-+
-+ gpio_poweroff {
-+ compatible = "gpio-poweroff";
-+ pinctrl-0 = <&pmx_pwr_off>;
-+ pinctrl-names = "default";
-+ gpios = <&gpio0 27 GPIO_ACTIVE_HIGH>;
-+ };
-+
-+ keys {
-+ compatible = "gpio-keys";
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ pinctrl-0 = <&pmx_buttons>;
-+ pinctrl-names = "default";
-+
-+ power {
-+ label = "Power Button";
-+ linux,code = <KEY_POWER>;
-+ gpios = <&gpio0 26 GPIO_ACTIVE_HIGH>;
-+ };
-+
-+ copy {
-+ label = "Copy Button";
-+ linux,code = <KEY_COPY>;
-+ gpios = <&gpio0 25 GPIO_ACTIVE_LOW>;
-+ };
-+
-+ reset {
-+ label = "Reset Button";
-+ linux,code = <KEY_RESTART>;
-+ gpios = <&gpio0 24 GPIO_ACTIVE_LOW>;
-+ };
-+ };
-+
-+ leds {
-+ compatible = "gpio-leds";
-+ pinctrl-0 = <&pmx_leds>;
-+ pinctrl-names = "default";
-+
-+ led-1 {
-+ function = LED_FUNCTION_DISK_ERR;
-+ color = <LED_COLOR_ID_RED>;
-+ gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>;
-+ };
-+
-+ led-2 {
-+ function = LED_FUNCTION_USB;
-+ color = <LED_COLOR_ID_GREEN>;
-+ gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>;
-+ linux,default-trigger = "usb-host";
-+ };
-+
-+ led-3 {
-+ function = LED_FUNCTION_DISK;
-+ color = <LED_COLOR_ID_GREEN>;
-+ gpios = <&gpio0 16 GPIO_ACTIVE_HIGH>;
-+ linux,default-trigger = "ata1";
-+ };
-+
-+ led-4 {
-+ function = LED_FUNCTION_INDICATOR;
-+ color = <LED_COLOR_ID_GREEN>;
-+ gpios = <&gpio0 22 GPIO_ACTIVE_HIGH>;
-+ };
-+
-+ led-5 {
-+ function = LED_FUNCTION_INDICATOR;
-+ color = <LED_COLOR_ID_RED>;
-+ gpios = <&gpio0 23 GPIO_ACTIVE_HIGH>;
-+ };
-+
-+ led-6 {
-+ function = LED_FUNCTION_STATUS;
-+ color = <LED_COLOR_ID_GREEN>;
-+ gpios = <&gpio0 28 GPIO_ACTIVE_HIGH>;
-+ linux,default-trigger = "default-on";
-+ };
-+
-+ led-7 {
-+ function = LED_FUNCTION_STATUS;
-+ color = <LED_COLOR_ID_RED>;
-+ gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>;
-+ };
-+ };
-+
-+ usb0_power: regulator@1 {
-+ compatible = "regulator-fixed";
-+ regulator-name = "USB Power";
-+
-+ regulator-min-microvolt = <5000000>;
-+ regulator-max-microvolt = <5000000>;
-+ regulator-always-on;
-+ regulator-boot-on;
-+ gpios = <&gpio0 21 GPIO_ACTIVE_HIGH>;
-+ };
-+
-+ sata1_power: regulator@2 {
-+ compatible = "regulator-fixed";
-+ regulator-name = "SATA1 Power";
-+
-+ regulator-min-microvolt = <5000000>;
-+ regulator-max-microvolt = <5000000>;
-+ regulator-always-on;
-+ regulator-boot-on;
-+ gpios = <&gpio1 1 GPIO_ACTIVE_HIGH>;
-+ };
-+
-+ thermal-zones {
-+ disk-thermal {
-+ polling-delay = <20000>;
-+ polling-delay-passive = <2000>;
-+
-+ thermal-sensors = <&hdd_temp>;
-+
-+ trips {
-+ disk_alert: disk-alert {
-+ temperature = <40000>;
-+ hysteresis = <5000>;
-+ type = "active";
-+ };
-+ disk_crit: disk-crit {
-+ temperature = <60000>;
-+ hysteresis = <2000>;
-+ type = "critical";
-+ };
-+ };
-+ };
-+ };
-+};
-+
-+
-+&eth0 {
-+ status = "okay";
-+
-+ ethernet0-port@0 {
-+ phy-handle = <&ethphy0>;
-+ };
-+};
-+
-+&i2c0 {
-+ status = "okay";
-+
-+ rtc@68 {
-+ compatible = "htk,ht1382";
-+ reg = <0x68>;
-+ };
-+};
-+
-+&mdio {
-+ status = "okay";
-+
-+ ethphy0: ethernet-phy@1 {
-+ reg = <1>;
-+ phy-mode = "rgmii-id";
-+ marvell,reg-init = <0x1 0x16 0x0 0x3>,
-+ <0x1 0x10 0x0 0x1017>,
-+ <0x1 0x11 0x0 0x4408>,
-+ <0x1 0x16 0x0 0x0>;
-+ };
-+};
-+
-+&nand {
-+ status = "okay";
-+ chip-delay = <35>;
-+
-+ partition@0 {
-+ label = "uboot";
-+ reg = <0x0000000 0x00c0000>;
-+ read-only;
-+ };
-+ partition@c0000 {
-+ label = "uboot_env";
-+ reg = <0x00c0000 0x0080000>;
-+ };
-+ partition@140000 {
-+ label = "ubi";
-+ reg = <0x0140000 0x7ec0000>;
-+ };
-+};
-+
-+&pciec {
-+ status = "okay";
-+};
-+
-+&pcie0 {
-+ status = "okay";
-+};
-+
-+&pinctrl {
-+ pinctrl-names = "default";
-+
-+ pmx_buttons: pmx-buttons {
-+ marvell,pins = "mpp24", "mpp25", "mpp26";
-+ marvell,function = "gpio";
-+ };
-+
-+ pmx_leds: pmx-leds {
-+ marvell,pins = "mpp13", "mpp15", "mpp16", "mpp22", "mpp23",
-+ "mpp28", "mpp29";
-+ marvell,function = "gpio";
-+ };
-+
-+ pmx_power: pmx-power {
-+ marvell,pins = "mpp21", "mpp33";
-+ marvell,function = "gpio";
-+ };
-+
-+ pmx_pwr_off: pmx-pwr-off {
-+ marvell,pins = "mpp27";
-+ marvell,function = "gpio";
-+ };
-+};
-+
-+&rtc {
-+ status = "disabled";
-+};
-+
-+&sata {
-+ status = "okay";
-+ nr-ports = <1>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ hdd_temp: sata-port@0 {
-+ reg = <0>;
-+ #thermal-sensor-cells = <0>;
-+ };
-+};
-+
-+&uart0 {
-+ status = "okay";
-+};
diff --git a/target/linux/kirkwood/patches-6.1/003-6.5-ARM-dts-kirkwood-Add-Endian-4i-Edge-200-board.patch b/target/linux/kirkwood/patches-6.1/003-6.5-ARM-dts-kirkwood-Add-Endian-4i-Edge-200-board.patch
deleted file mode 100644
index cde281526b..0000000000
--- a/target/linux/kirkwood/patches-6.1/003-6.5-ARM-dts-kirkwood-Add-Endian-4i-Edge-200-board.patch
+++ /dev/null
@@ -1,249 +0,0 @@
-From 5668d088ee4ea05db9daaae0645d1d1f579b20f9 Mon Sep 17 00:00:00 2001
-From: Pawel Dembicki <paweldembicki@gmail.com>
-Date: Mon, 3 Oct 2022 09:34:43 +0200
-Subject: ARM: dts: kirkwood: Add Endian 4i Edge 200 board
-
-Add Endian 4i Edge 200 is 5-port firewall.
-It have also clone: Endian UTM Mini (The same hardware, with added WLAN
-card).
-
-Hardware:
- - SoC: Marvell 88F6281-A1 ARMv5TE Processor 1.2GHz
- - Ram: 512MB (4x Nanya NT5TU128M8GE-AC)
- - NAND Flash: 512MB (Micron 29F4G08AAC)
- - Lan 1-4: 4x GBE (Marvell 88E6171R-TFJ2)
- - Lan 5: 1x GBE (Marvell 88E1116R-NNC1)
- - Storage: MicroSD Slot
- - MCPIE: MiniPCIe Slot present [fitted with SparkLan WPEA-110N/E
- (Atheros AR9280 chipset) in Endian UTM Mini WLAN only]
- - USB: 1x USB 2.0 port
- - Console: RJ-45 port
- - LEDs: 3x GPIO controlled
-
-Signed-off-by: Pawel Dembicki <paweldembicki@gmail.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Gregory CLEMENT <gregory.clement@bootlin.com>
----
- arch/arm/boot/dts/Makefile | 1 +
- arch/arm/boot/dts/kirkwood-4i-edge-200.dts | 205 +++++++++++++++++++++++++++++
- 2 files changed, 206 insertions(+)
- create mode 100644 arch/arm/boot/dts/kirkwood-4i-edge-200.dts
-
---- a/arch/arm/boot/dts/Makefile
-+++ b/arch/arm/boot/dts/Makefile
-@@ -300,6 +300,7 @@ dtb-$(CONFIG_ARCH_KEYSTONE) += \
- keystone-k2g-evm.dtb \
- keystone-k2g-ice.dtb
- dtb-$(CONFIG_MACH_KIRKWOOD) += \
-+ kirkwood-4i-edge-200.dtb \
- kirkwood-b3.dtb \
- kirkwood-blackarmor-nas220.dtb \
- kirkwood-c200-v1.dtb \
---- /dev/null
-+++ b/arch/arm/boot/dts/kirkwood-4i-edge-200.dts
-@@ -0,0 +1,205 @@
-+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
-+/*
-+ * Endian 4i Edge 200 Board Description
-+ * Note: Endian UTM Mini is hardware clone of Endian Edge 200
-+ * Copyright 2021-2022 Pawel Dembicki <paweldembicki@gmail.com>
-+ */
-+
-+/dts-v1/;
-+
-+#include "kirkwood.dtsi"
-+#include "kirkwood-6281.dtsi"
-+#include <dt-bindings/leds/common.h>
-+
-+/ {
-+ model = "Endian 4i Edge 200";
-+ compatible = "endian,4i-edge-200", "marvell,kirkwood-88f6281", "marvell,kirkwood";
-+
-+ memory {
-+ device_type = "memory";
-+ reg = <0x00000000 0x20000000>;
-+ };
-+
-+ chosen {
-+ bootargs = "console=ttyS0,115200n8";
-+ stdout-path = &uart0;
-+ };
-+
-+ leds {
-+ compatible = "gpio-leds";
-+ pinctrl-0 = <&pmx_led>;
-+ pinctrl-names = "default";
-+
-+ led-1 {
-+ function = LED_FUNCTION_SD;
-+ color = <LED_COLOR_ID_AMBER>;
-+ gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>;
-+ linux,default-trigger = "mmc0";
-+ };
-+
-+ led-2 {
-+ function = LED_FUNCTION_STATUS;
-+ color = <LED_COLOR_ID_AMBER>;
-+ gpios = <&gpio1 3 GPIO_ACTIVE_HIGH>;
-+ };
-+
-+ led-3 {
-+ function = LED_FUNCTION_STATUS;
-+ color = <LED_COLOR_ID_GREEN>;
-+ gpios = <&gpio1 17 GPIO_ACTIVE_HIGH>;
-+ };
-+ };
-+};
-+
-+&eth0 {
-+ status = "okay";
-+};
-+
-+&eth0port {
-+ speed = <1000>;
-+ duplex = <1>;
-+};
-+
-+&eth1 {
-+ status = "okay";
-+};
-+
-+&eth1port {
-+ phy-handle = <&ethphyb>;
-+};
-+
-+&mdio {
-+ status = "okay";
-+
-+ ethphyb: ethernet-phy@b {
-+ reg = <0x0b>;
-+
-+ marvell,reg-init =
-+ /* link-activity, bi-color mode 4 */
-+ <3 0x10 0xfff0 0xf>; /* Reg 3,16 <- 0xzzzf */
-+ };
-+
-+ switch0: switch@11 {
-+ compatible = "marvell,mv88e6085";
-+ reg = <0x11>;
-+
-+ ports {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ port@0 {
-+ reg = <0>;
-+ label = "port1";
-+ };
-+
-+ port@1 {
-+ reg = <1>;
-+ label = "port2";
-+ };
-+
-+ port@2 {
-+ reg = <2>;
-+ label = "port3";
-+ };
-+
-+ port@3 {
-+ reg = <3>;
-+ label = "port4";
-+ };
-+
-+ port@5 {
-+ reg = <5>;
-+ phy-mode = "rgmii-id";
-+ ethernet = <&eth0port>;
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
-+ };
-+ };
-+ };
-+};
-+
-+&nand {
-+ status = "okay";
-+ pinctrl-0 = <&pmx_nand>;
-+ pinctrl-names = "default";
-+
-+ partition@0 {
-+ label = "u-boot";
-+ reg = <0x00000000 0x000a0000>;
-+ read-only;
-+ };
-+
-+ partition@a0000 {
-+ label = "u-boot-env";
-+ reg = <0x000a0000 0x00060000>;
-+ read-only;
-+ };
-+
-+ partition@100000 {
-+ label = "kernel";
-+ reg = <0x00100000 0x00400000>;
-+ };
-+
-+ partition@500000 {
-+ label = "ubi";
-+ reg = <0x00500000 0x1fb00000>;
-+ };
-+};
-+
-+&pciec {
-+ status = "okay";
-+};
-+
-+&pcie0 {
-+ status = "okay";
-+};
-+
-+&pinctrl {
-+ pinctrl-0 = <&pmx_sysrst>;
-+ pinctrl-names = "default";
-+
-+ pmx_sysrst: pmx-sysrst {
-+ marvell,pins = "mpp6";
-+ marvell,function = "sysrst";
-+ };
-+
-+ pmx_sdio_cd: pmx-sdio-cd {
-+ marvell,pins = "mpp28";
-+ marvell,function = "gpio";
-+ };
-+
-+ pmx_led: pmx-led {
-+ marvell,pins = "mpp34", "mpp35", "mpp49";
-+ marvell,function = "gpio";
-+ };
-+};
-+
-+&rtc {
-+ status = "okay";
-+};
-+
-+&sata_phy0 {
-+ status = "disabled";
-+};
-+
-+&sata_phy1 {
-+ status = "disabled";
-+};
-+
-+&sdio {
-+ pinctrl-0 = <&pmx_sdio_cd>;
-+ pinctrl-names = "default";
-+ status = "okay";
-+ cd-gpios = <&gpio0 28 9>;
-+};
-+
-+&uart0 {
-+ status = "okay";
-+};
-+
-+&usb0 {
-+ status = "okay";
-+};
diff --git a/target/linux/kirkwood/patches-6.1/004-6.4-ARM-dts-kirkwood-Add-missing-phy-mode-and-fixed-link.patch b/target/linux/kirkwood/patches-6.1/004-6.4-ARM-dts-kirkwood-Add-missing-phy-mode-and-fixed-link.patch
deleted file mode 100644
index fd7adc3584..0000000000
--- a/target/linux/kirkwood/patches-6.1/004-6.4-ARM-dts-kirkwood-Add-missing-phy-mode-and-fixed-link.patch
+++ /dev/null
@@ -1,108 +0,0 @@
-From 8aea8659a5f3ae8dc63c9f632ce1f676a1483556 Mon Sep 17 00:00:00 2001
-From: Andrew Lunn <andrew@lunn.ch>
-Date: Fri, 7 Apr 2023 17:17:20 +0200
-Subject: [PATCH] ARM: dts: kirkwood: Add missing phy-mode and fixed links
-
-The DSA framework has got more picky about always having a phy-mode
-for the CPU port. The Kirkwood Ethernet is an RGMII port. Set the
-switch to impose the RGMII delays.
-
-Additionally, the cpu label has never actually been used in the
-binding, so remove it.
-
-Signed-off-by: Andrew Lunn <andrew@lunn.ch>
-Signed-off-by: Gregory CLEMENT <gregory.clement@bootlin.com>
----
- arch/arm/boot/dts/kirkwood-dir665.dts | 3 ++-
- arch/arm/boot/dts/kirkwood-l-50.dts | 2 +-
- arch/arm/boot/dts/kirkwood-linksys-viper.dts | 3 ++-
- arch/arm/boot/dts/kirkwood-mv88f6281gtw-ge.dts | 3 ++-
- arch/arm/boot/dts/kirkwood-rd88f6281.dtsi | 2 +-
- 5 files changed, 8 insertions(+), 5 deletions(-)
-
---- a/arch/arm/boot/dts/kirkwood-dir665.dts
-+++ b/arch/arm/boot/dts/kirkwood-dir665.dts
-@@ -232,7 +232,7 @@
-
- port@6 {
- reg = <6>;
-- label = "cpu";
-+ phy-mode = "rgmii-id";
- ethernet = <&eth0port>;
- fixed-link {
- speed = <1000>;
-@@ -251,6 +251,7 @@
- ethernet0-port@0 {
- speed = <1000>;
- duplex = <1>;
-+ phy-mode = "rgmii";
- };
- };
-
---- a/arch/arm/boot/dts/kirkwood-l-50.dts
-+++ b/arch/arm/boot/dts/kirkwood-l-50.dts
-@@ -254,7 +254,6 @@
-
- port@6 {
- reg = <6>;
-- label = "cpu";
- phy-mode = "rgmii-id";
- ethernet = <&eth1port>;
- fixed-link {
-@@ -330,6 +329,7 @@
- ethernet1-port@0 {
- speed = <1000>;
- duplex = <1>;
-+ phy-mode = "rgmii";
- };
- };
-
---- a/arch/arm/boot/dts/kirkwood-linksys-viper.dts
-+++ b/arch/arm/boot/dts/kirkwood-linksys-viper.dts
-@@ -198,7 +198,7 @@
-
- port@5 {
- reg = <5>;
-- label = "cpu";
-+ phy-mode = "rgmii-id";
- ethernet = <&eth0port>;
- fixed-link {
- speed = <1000>;
-@@ -221,6 +221,7 @@
- ethernet0-port@0 {
- speed = <1000>;
- duplex = <1>;
-+ phy-mode = "rgmii";
- };
- };
-
---- a/arch/arm/boot/dts/kirkwood-mv88f6281gtw-ge.dts
-+++ b/arch/arm/boot/dts/kirkwood-mv88f6281gtw-ge.dts
-@@ -149,7 +149,7 @@
-
- port@5 {
- reg = <5>;
-- label = "cpu";
-+ phy-mode = "rgmii-id";
- ethernet = <&eth0port>;
- fixed-link {
- speed = <1000>;
-@@ -166,6 +166,7 @@
- ethernet0-port@0 {
- speed = <1000>;
- duplex = <1>;
-+ phy-mode = "rgmii";
- };
- };
-
---- a/arch/arm/boot/dts/kirkwood-rd88f6281.dtsi
-+++ b/arch/arm/boot/dts/kirkwood-rd88f6281.dtsi
-@@ -105,7 +105,7 @@
-
- port@5 {
- reg = <5>;
-- label = "cpu";
-+ phy-mode = "rgmii-id";
- ethernet = <&eth0port>;
- fixed-link {
- speed = <1000>;
diff --git a/target/linux/kirkwood/patches-6.1/100-ib62x0.patch b/target/linux/kirkwood/patches-6.1/100-ib62x0.patch
deleted file mode 100644
index 0637c24b63..0000000000
--- a/target/linux/kirkwood/patches-6.1/100-ib62x0.patch
+++ /dev/null
@@ -1,53 +0,0 @@
---- a/arch/arm/boot/dts/kirkwood-ib62x0.dts
-+++ b/arch/arm/boot/dts/kirkwood-ib62x0.dts
-@@ -6,7 +6,14 @@
-
- / {
- model = "RaidSonic ICY BOX IB-NAS62x0 (Rev B)";
-- compatible = "raidsonic,ib-nas6210-b", "raidsonic,ib-nas6220-b", "raidsonic,ib-nas6210", "raidsonic,ib-nas6220", "raidsonic,ib-nas62x0", "marvell,kirkwood-88f6281", "marvell,kirkwood";
-+ compatible = "raidsonic,ib-nas62x0", "marvell,kirkwood-88f6281", "marvell,kirkwood";
-+
-+ aliases {
-+ led-boot = &led_green_os;
-+ led-failsafe = &led_red_os;
-+ led-running = &led_green_os;
-+ led-upgrade = &led_red_os;
-+ };
-
- memory {
- device_type = "memory";
-@@ -81,12 +88,12 @@
- &pmx_led_usb_transfer>;
- pinctrl-names = "default";
-
-- green-os {
-+ led_green_os: green-os {
- label = "ib62x0:green:os";
- gpios = <&gpio0 25 GPIO_ACTIVE_HIGH>;
-- default-state = "keep";
-+ default-state = "on";
- };
-- red-os {
-+ led_red_os: red-os {
- label = "ib62x0:red:os";
- gpios = <&gpio0 22 GPIO_ACTIVE_HIGH>;
- };
-@@ -118,13 +125,13 @@
- };
-
- partition@100000 {
-- label = "uImage";
-- reg = <0x0100000 0x600000>;
-+ label = "second stage u-boot";
-+ reg = <0x100000 0x200000>;
- };
-
-- partition@700000 {
-- label = "root";
-- reg = <0x0700000 0xf900000>;
-+ partition@200000 {
-+ label = "ubi";
-+ reg = <0x200000 0xfe00000>;
- };
-
- };
diff --git a/target/linux/kirkwood/patches-6.1/101-iconnect.patch b/target/linux/kirkwood/patches-6.1/101-iconnect.patch
deleted file mode 100644
index 935e2dfcf5..0000000000
--- a/target/linux/kirkwood/patches-6.1/101-iconnect.patch
+++ /dev/null
@@ -1,80 +0,0 @@
---- a/arch/arm/boot/dts/kirkwood-iconnect.dts
-+++ b/arch/arm/boot/dts/kirkwood-iconnect.dts
-@@ -8,6 +8,13 @@
- model = "Iomega Iconnect";
- compatible = "iom,iconnect-1.1", "iom,iconnect", "marvell,kirkwood-88f6281", "marvell,kirkwood";
-
-+ aliases {
-+ led-boot = &led_power_blue;
-+ led-failsafe = &led_power_red;
-+ led-running = &led_power_blue;
-+ led-upgrade = &led_power_red;
-+ };
-+
- memory {
- device_type = "memory";
- reg = <0x00000000 0x10000000>;
-@@ -16,8 +23,6 @@
- chosen {
- bootargs = "console=ttyS0,115200n8 earlyprintk";
- stdout-path = &uart0;
-- linux,initrd-start = <0x4500040>;
-- linux,initrd-end = <0x4800000>;
- };
-
- ocp@f1000000 {
-@@ -89,12 +94,12 @@
- gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>;
- default-state = "on";
- };
-- power-blue {
-+ led_power_blue: power-blue {
- label = "power:blue";
- gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>;
-- default-state = "keep";
-+ default-state = "on";
- };
-- power-red {
-+ led_power_red: power-red {
- label = "power:red";
- gpios = <&gpio1 11 GPIO_ACTIVE_HIGH>;
- };
-@@ -146,28 +151,23 @@
- status = "okay";
-
- partition@0 {
-- label = "uboot";
-- reg = <0x0000000 0xc0000>;
-+ label = "u-boot";
-+ reg = <0x0000000 0xe0000>;
- };
-
-- partition@a0000 {
-- label = "env";
-- reg = <0xa0000 0x20000>;
-+ partition@e0000 {
-+ label = "u-boot environment";
-+ reg = <0xe0000 0x100000>;
- };
-
- partition@100000 {
-- label = "zImage";
-- reg = <0x100000 0x300000>;
-- };
--
-- partition@540000 {
-- label = "initrd";
-- reg = <0x540000 0x300000>;
-+ label = "second stage u-boot";
-+ reg = <0x100000 0x200000>;
- };
-
-- partition@980000 {
-- label = "boot";
-- reg = <0x980000 0x1f400000>;
-+ partition@200000 {
-+ label = "ubi";
-+ reg = <0x200000 0x1fe00000>;
- };
- };
-
diff --git a/target/linux/kirkwood/patches-6.1/102-dockstar.patch b/target/linux/kirkwood/patches-6.1/102-dockstar.patch
deleted file mode 100644
index 127f84962c..0000000000
--- a/target/linux/kirkwood/patches-6.1/102-dockstar.patch
+++ /dev/null
@@ -1,62 +0,0 @@
---- a/arch/arm/boot/dts/kirkwood-dockstar.dts
-+++ b/arch/arm/boot/dts/kirkwood-dockstar.dts
-@@ -8,6 +8,13 @@
- model = "Seagate FreeAgent Dockstar";
- compatible = "seagate,dockstar", "marvell,kirkwood-88f6281", "marvell,kirkwood";
-
-+ aliases {
-+ led-boot = &led_health;
-+ led-failsafe = &led_fault;
-+ led-running = &led_health;
-+ led-upgrade = &led_fault;
-+ };
-+
- memory {
- device_type = "memory";
- reg = <0x00000000 0x8000000>;
-@@ -42,12 +49,12 @@
- pinctrl-0 = <&pmx_led_green &pmx_led_orange>;
- pinctrl-names = "default";
-
-- health {
-+ led_health: health {
- label = "status:green:health";
- gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
-- default-state = "keep";
-+ default-state = "on";
- };
-- fault {
-+ led_fault: fault {
- label = "status:orange:fault";
- gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
- };
-@@ -78,18 +85,22 @@
-
- partition@0 {
- label = "u-boot";
-- reg = <0x0000000 0x100000>;
-- read-only;
-+ reg = <0x0000000 0xe0000>;
-+ };
-+
-+ partition@e0000 {
-+ label = "u-boot environment";
-+ reg = <0xe0000 0x100000>;
- };
-
- partition@100000 {
-- label = "uImage";
-- reg = <0x0100000 0x400000>;
-+ label = "second stage u-boot";
-+ reg = <0x100000 0x200000>;
- };
-
-- partition@500000 {
-- label = "data";
-- reg = <0x0500000 0xfb00000>;
-+ partition@200000 {
-+ label = "ubi";
-+ reg = <0x200000 0xfe00000>;
- };
- };
-
diff --git a/target/linux/kirkwood/patches-6.1/103-iomega-ix2-200.patch b/target/linux/kirkwood/patches-6.1/103-iomega-ix2-200.patch
deleted file mode 100644
index db04c09f76..0000000000
--- a/target/linux/kirkwood/patches-6.1/103-iomega-ix2-200.patch
+++ /dev/null
@@ -1,71 +0,0 @@
---- a/arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts
-+++ b/arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts
-@@ -8,6 +8,13 @@
- model = "Iomega StorCenter ix2-200";
- compatible = "iom,ix2-200", "marvell,kirkwood-88f6281", "marvell,kirkwood";
-
-+ aliases {
-+ led-boot = &led_power;
-+ led-failsafe = &led_health;
-+ led-running = &led_power;
-+ led-upgrade = &led_health;
-+ };
-+
- memory {
- device_type = "memory";
- reg = <0x00000000 0x10000000>;
-@@ -127,16 +134,16 @@
- &pmx_led_rebuild &pmx_led_health >;
- pinctrl-names = "default";
-
-- power_led {
-+ led_power: power_led {
- label = "status:white:power_led";
- gpios = <&gpio0 16 GPIO_ACTIVE_HIGH>;
-- default-state = "keep";
-+ default-state = "on";
- };
- rebuild_led {
- label = "status:white:rebuild_led";
- gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
- };
-- health_led {
-+ led_health: health_led {
- label = "status:red:health_led";
- gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>;
- };
-@@ -186,19 +193,19 @@
- };
-
- partition@a0000 {
-- label = "env";
-+ label = "u-boot environment";
- reg = <0xa0000 0x20000>;
- read-only;
- };
-
- partition@100000 {
-- label = "uImage";
-- reg = <0x100000 0x300000>;
-+ label = "kernel";
-+ reg = <0x100000 0x400000>;
- };
-
-- partition@400000 {
-- label = "rootfs";
-- reg = <0x400000 0x1C00000>;
-+ partition@500000 {
-+ label = "ubi";
-+ reg = <0x500000 0x1C00000>;
- };
- };
-
-@@ -211,7 +218,7 @@
- };
-
- &eth0 {
-- status = "okay";
-+ status = "disabled";
- ethernet0-port@0 {
- speed = <1000>;
- duplex = <1>;
diff --git a/target/linux/kirkwood/patches-6.1/105-linksys-viper-dts.patch b/target/linux/kirkwood/patches-6.1/105-linksys-viper-dts.patch
deleted file mode 100644
index b1604ec92c..0000000000
--- a/target/linux/kirkwood/patches-6.1/105-linksys-viper-dts.patch
+++ /dev/null
@@ -1,59 +0,0 @@
---- a/arch/arm/boot/dts/kirkwood-linksys-viper.dts
-+++ b/arch/arm/boot/dts/kirkwood-linksys-viper.dts
-@@ -24,6 +24,10 @@
- };
-
- aliases {
-+ led-boot = &led_white_health;
-+ led-failsafe = &led_white_health;
-+ led-running = &led_white_health;
-+ led-upgrade = &led_white_health;
- serial0 = &uart0;
- };
-
-@@ -56,9 +60,10 @@
- pinctrl-0 = < &pmx_led_white_health &pmx_led_white_pulse >;
- pinctrl-names = "default";
-
-- white-health {
-+ led_white_health: white-health {
- label = "viper:white:health";
- gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>;
-+ default-state = "on";
- };
-
- white-pulse {
-@@ -114,23 +119,23 @@
- };
-
- partition@200000 {
-- label = "kernel";
-- reg = <0x200000 0x2A0000>;
-+ label = "kernel1";
-+ reg = <0x200000 0x1A00000>;
- };
-
-- partition@4a0000 {
-- label = "rootfs";
-- reg = <0x4A0000 0x1760000>;
-+ partition@600000 {
-+ label = "rootfs1";
-+ reg = <0x600000 0x1600000>;
- };
-
- partition@1c00000 {
-- label = "alt_kernel";
-- reg = <0x1C00000 0x2A0000>;
-+ label = "kernel2";
-+ reg = <0x1C00000 0x1A00000>;
- };
-
-- partition@1ea0000 {
-- label = "alt_rootfs";
-- reg = <0x1EA0000 0x1760000>;
-+ partition@2000000 {
-+ label = "rootfs2";
-+ reg = <0x2000000 0x1600000>;
- };
-
- partition@3600000 {
diff --git a/target/linux/kirkwood/patches-6.1/106-goflexnet.patch b/target/linux/kirkwood/patches-6.1/106-goflexnet.patch
deleted file mode 100644
index 82cf90841e..0000000000
--- a/target/linux/kirkwood/patches-6.1/106-goflexnet.patch
+++ /dev/null
@@ -1,53 +0,0 @@
---- a/arch/arm/boot/dts/kirkwood-goflexnet.dts
-+++ b/arch/arm/boot/dts/kirkwood-goflexnet.dts
-@@ -8,6 +8,13 @@
- model = "Seagate GoFlex Net";
- compatible = "seagate,goflexnet", "marvell,kirkwood-88f6281", "marvell,kirkwood";
-
-+ aliases {
-+ led-boot = &led_health;
-+ led-failsafe = &led_fault;
-+ led-running = &led_health;
-+ led-upgrade = &led_fault;
-+ };
-+
- memory {
- device_type = "memory";
- reg = <0x00000000 0x8000000>;
-@@ -85,12 +92,12 @@
- >;
- pinctrl-names = "default";
-
-- health {
-+ led_health: health {
- label = "status:green:health";
- gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
-- default-state = "keep";
-+ default-state = "on";
- };
-- fault {
-+ led_fault: fault {
- label = "status:orange:fault";
- gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
- };
-@@ -159,18 +166,8 @@
- };
-
- partition@100000 {
-- label = "uImage";
-- reg = <0x0100000 0x400000>;
-- };
--
-- partition@500000 {
-- label = "pogoplug";
-- reg = <0x0500000 0x2000000>;
-- };
--
-- partition@2500000 {
-- label = "root";
-- reg = <0x02500000 0xd800000>;
-+ label = "ubi";
-+ reg = <0x0100000 0x0ff00000>;
- };
- };
-
diff --git a/target/linux/kirkwood/patches-6.1/107-01-zyxel-nsa3x0-common-nand-partitions.patch b/target/linux/kirkwood/patches-6.1/107-01-zyxel-nsa3x0-common-nand-partitions.patch
deleted file mode 100644
index df654033fd..0000000000
--- a/target/linux/kirkwood/patches-6.1/107-01-zyxel-nsa3x0-common-nand-partitions.patch
+++ /dev/null
@@ -1,48 +0,0 @@
---- a/arch/arm/boot/dts/kirkwood-nsa3x0-common.dtsi
-+++ b/arch/arm/boot/dts/kirkwood-nsa3x0-common.dtsi
-@@ -112,40 +112,16 @@
-
- partition@0 {
- label = "uboot";
-- reg = <0x0000000 0x0100000>;
-+ reg = <0x0000000 0x00c0000>;
- read-only;
- };
- partition@100000 {
- label = "uboot_env";
-- reg = <0x0100000 0x0080000>;
-+ reg = <0x00c0000 0x0080000>;
- };
-- partition@180000 {
-- label = "key_store";
-- reg = <0x0180000 0x0080000>;
-- };
-- partition@200000 {
-- label = "info";
-- reg = <0x0200000 0x0080000>;
-- };
-- partition@280000 {
-- label = "etc";
-- reg = <0x0280000 0x0a00000>;
-- };
-- partition@c80000 {
-- label = "kernel_1";
-- reg = <0x0c80000 0x0a00000>;
-- };
-- partition@1680000 {
-- label = "rootfs1";
-- reg = <0x1680000 0x2fc0000>;
-- };
-- partition@4640000 {
-- label = "kernel_2";
-- reg = <0x4640000 0x0a00000>;
-- };
-- partition@5040000 {
-- label = "rootfs2";
-- reg = <0x5040000 0x2fc0000>;
-+ partition@140000 {
-+ label = "ubi";
-+ reg = <0x0140000 0x7ec0000>;
- };
- };
-
diff --git a/target/linux/kirkwood/patches-6.1/107-03-nsa325.patch b/target/linux/kirkwood/patches-6.1/107-03-nsa325.patch
deleted file mode 100644
index 374c0895a9..0000000000
--- a/target/linux/kirkwood/patches-6.1/107-03-nsa325.patch
+++ /dev/null
@@ -1,54 +0,0 @@
---- a/arch/arm/boot/dts/kirkwood-nsa325.dts
-+++ b/arch/arm/boot/dts/kirkwood-nsa325.dts
-@@ -15,6 +15,13 @@
- model = "ZyXEL NSA325";
- compatible = "zyxel,nsa325", "marvell,kirkwood-88f6282", "marvell,kirkwood";
-
-+ aliases {
-+ led-boot = &led_green_sys;
-+ led-failsafe = &led_orange_sys;
-+ led-running = &led_green_sys;
-+ led-upgrade = &led_orange_sys;
-+ };
-+
- memory {
- device_type = "memory";
- reg = <0x00000000 0x20000000>;
-@@ -162,17 +169,19 @@
- &pmx_led_hdd1_green &pmx_led_hdd1_red>;
- pinctrl-names = "default";
-
-- green-sys {
-+ led_green_sys: green-sys {
- label = "nsa325:green:sys";
- gpios = <&gpio0 28 GPIO_ACTIVE_HIGH>;
-+ default-state = "on";
- };
-- orange-sys {
-+ led_orange_sys: orange-sys {
- label = "nsa325:orange:sys";
- gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>;
- };
- green-hdd1 {
- label = "nsa325:green:hdd1";
- gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>;
-+ linux,default-trigger = "ata1";
- };
- red-hdd1 {
- label = "nsa325:red:hdd1";
-@@ -181,6 +190,7 @@
- green-hdd2 {
- label = "nsa325:green:hdd2";
- gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
-+ linux,default-trigger = "ata2";
- };
- red-hdd2 {
- label = "nsa325:red:hdd2";
-@@ -189,6 +199,7 @@
- green-usb {
- label = "nsa325:green:usb";
- gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>;
-+ linux,default-trigger = "usb-host";
- };
- green-copy {
- label = "nsa325:green:copy";
diff --git a/target/linux/kirkwood/patches-6.1/109-pogoplug_v4.patch b/target/linux/kirkwood/patches-6.1/109-pogoplug_v4.patch
deleted file mode 100644
index 4273eb9af1..0000000000
--- a/target/linux/kirkwood/patches-6.1/109-pogoplug_v4.patch
+++ /dev/null
@@ -1,87 +0,0 @@
---- a/arch/arm/boot/dts/kirkwood-pogoplug-series-4.dts
-+++ b/arch/arm/boot/dts/kirkwood-pogoplug-series-4.dts
-@@ -18,12 +18,20 @@
- compatible = "cloudengines,pogoplugv4", "marvell,kirkwood-88f6192",
- "marvell,kirkwood";
-
-+ aliases {
-+ led-boot = &led_health;
-+ led-failsafe = &led_fault;
-+ led-running = &led_health;
-+ led-upgrade = &led_fault;
-+ };
-+
- memory {
- device_type = "memory";
- reg = <0x00000000 0x08000000>;
- };
-
- chosen {
-+ bootargs = "console=ttyS0,115200";
- stdout-path = "uart0:115200n8";
- };
-
-@@ -37,8 +45,8 @@
- eject {
- debounce-interval = <50>;
- wakeup-source;
-- linux,code = <KEY_EJECTCD>;
-- label = "Eject Button";
-+ linux,code = <KEY_RESTART>;
-+ label = "Reset";
- gpios = <&gpio0 29 GPIO_ACTIVE_LOW>;
- };
- };
-@@ -48,12 +56,12 @@
- pinctrl-0 = <&pmx_led_green &pmx_led_red>;
- pinctrl-names = "default";
-
-- health {
-+ led_health: health {
- label = "pogoplugv4:green:health";
- gpios = <&gpio0 22 GPIO_ACTIVE_LOW>;
- default-state = "on";
- };
-- fault {
-+ led_fault: fault {
- label = "pogoplugv4:red:fault";
- gpios = <&gpio0 24 GPIO_ACTIVE_LOW>;
- };
-@@ -137,29 +145,19 @@
- #size-cells = <1>;
-
- partition@0 {
-- label = "u-boot";
-- reg = <0x00000000 0x200000>;
-+ label = "uboot";
-+ reg = <0x00000000 0x1c0000>;
- read-only;
- };
-
-- partition@200000 {
-- label = "uImage";
-- reg = <0x00200000 0x300000>;
-- };
--
-- partition@500000 {
-- label = "uImage2";
-- reg = <0x00500000 0x300000>;
-- };
--
-- partition@800000 {
-- label = "failsafe";
-- reg = <0x00800000 0x800000>;
-+ partition@1c0000 {
-+ label = "uboot_env";
-+ reg = <0x001c0000 0x40000>;
- };
-
-- partition@1000000 {
-- label = "root";
-- reg = <0x01000000 0x7000000>;
-+ partition@200000 {
-+ label = "ubi";
-+ reg = <0x00200000 0x7e00000>;
- };
- };
- };
diff --git a/target/linux/kirkwood/patches-6.1/110-pogo_e02.patch b/target/linux/kirkwood/patches-6.1/110-pogo_e02.patch
deleted file mode 100644
index fc384d3521..0000000000
--- a/target/linux/kirkwood/patches-6.1/110-pogo_e02.patch
+++ /dev/null
@@ -1,68 +0,0 @@
---- a/arch/arm/boot/dts/kirkwood-pogo_e02.dts
-+++ b/arch/arm/boot/dts/kirkwood-pogo_e02.dts
-@@ -20,6 +20,13 @@
- compatible = "cloudengines,pogoe02", "marvell,kirkwood-88f6281",
- "marvell,kirkwood";
-
-+ aliases {
-+ led-boot = &led_health;
-+ led-failsafe = &led_fault;
-+ led-running = &led_health;
-+ led-upgrade = &led_fault;
-+ };
-+
- memory {
- device_type = "memory";
- reg = <0x00000000 0x10000000>;
-@@ -33,12 +40,12 @@
- gpio-leds {
- compatible = "gpio-leds";
-
-- health {
-+ led_health: health {
- label = "pogo_e02:green:health";
- gpios = <&gpio1 16 GPIO_ACTIVE_LOW>;
-- default-state = "keep";
-+ default-state = "on";
- };
-- fault {
-+ led_fault: fault {
- label = "pogo_e02:orange:fault";
- gpios = <&gpio1 17 GPIO_ACTIVE_LOW>;
- };
-@@ -95,24 +102,24 @@
- status = "okay";
-
- partition@0 {
-- label = "u-boot";
-- reg = <0x0000000 0x100000>;
-+ label = "uboot";
-+ reg = <0x0 0xe0000>;
- read-only;
- };
-
-- partition@100000 {
-- label = "uImage";
-- reg = <0x0100000 0x400000>;
-+ partition@e0000 {
-+ label = "uboot_env";
-+ reg = <0xe0000 0x20000>;
- };
-
-- partition@500000 {
-- label = "pogoplug";
-- reg = <0x0500000 0x2000000>;
-+ partition@100000 {
-+ label = "second_stage_uboot";
-+ reg = <0x100000 0x100000>;
- };
-
-- partition@2500000 {
-- label = "root";
-- reg = <0x02500000 0x5b00000>;
-+ partition@200000 {
-+ label = "ubi";
-+ reg = <0x200000 0x7e00000>;
- };
- };
-
diff --git a/target/linux/kirkwood/patches-6.1/111-l-50.patch b/target/linux/kirkwood/patches-6.1/111-l-50.patch
deleted file mode 100644
index bc933cb610..0000000000
--- a/target/linux/kirkwood/patches-6.1/111-l-50.patch
+++ /dev/null
@@ -1,47 +0,0 @@
---- a/arch/arm/boot/dts/kirkwood-l-50.dts
-+++ b/arch/arm/boot/dts/kirkwood-l-50.dts
-@@ -18,6 +18,13 @@
- reg = <0x00000000 0x20000000>;
- };
-
-+ aliases {
-+ led-boot = &led_status_green;
-+ led-failsafe = &led_status_red;
-+ led-running = &led_status_green;
-+ led-upgrade = &led_status_red;
-+ };
-+
- chosen {
- bootargs = "console=ttyS0,115200n8";
- stdout-path = &uart0;
-@@ -95,12 +102,12 @@
- leds {
- compatible = "gpio-leds";
-
-- status_green {
-+ led_status_green: status_green {
- label = "l-50:green:status";
- gpios = <&gpio1 6 GPIO_ACTIVE_LOW>;
- };
-
-- status_red {
-+ led_status_red: status_red {
- label = "l-50:red:status";
- gpios = <&gpio3 2 GPIO_ACTIVE_LOW>;
- };
-@@ -349,13 +356,8 @@
- };
-
- partition@100000 {
-- label = "kernel-1";
-- reg = <0x00100000 0x00800000>;
-- };
--
-- partition@900000 {
-- label = "rootfs-1";
-- reg = <0x00900000 0x07100000>;
-+ label = "ubi";
-+ reg = <0x00100000 0x07900000>;
- };
-
- partition@7a00000 {
diff --git a/target/linux/kirkwood/patches-6.1/112-sheevaplug.patch b/target/linux/kirkwood/patches-6.1/112-sheevaplug.patch
deleted file mode 100644
index d1ff9884a0..0000000000
--- a/target/linux/kirkwood/patches-6.1/112-sheevaplug.patch
+++ /dev/null
@@ -1,47 +0,0 @@
---- a/arch/arm/boot/dts/kirkwood-sheevaplug-common.dtsi
-+++ b/arch/arm/boot/dts/kirkwood-sheevaplug-common.dtsi
-@@ -78,13 +78,8 @@
- };
-
- partition@100000 {
-- label = "uImage";
-- reg = <0x0100000 0x400000>;
-- };
--
-- partition@500000 {
-- label = "root";
-- reg = <0x0500000 0x1fb00000>;
-+ label = "ubi";
-+ reg = <0x0100000 0x1ff00000>;
- };
- };
-
---- a/arch/arm/boot/dts/kirkwood-sheevaplug.dts
-+++ b/arch/arm/boot/dts/kirkwood-sheevaplug.dts
-@@ -13,6 +13,13 @@
- model = "Globalscale Technologies SheevaPlug";
- compatible = "globalscale,sheevaplug", "marvell,kirkwood-88f6281", "marvell,kirkwood";
-
-+ aliases {
-+ led-boot = &led_health;
-+ led-failsafe = &led_health;
-+ led-running = &led_health;
-+ led-upgrade = &led_health;
-+ };
-+
- ocp@f1000000 {
- mvsdio@90000 {
- pinctrl-0 = <&pmx_sdio>;
-@@ -28,10 +35,10 @@
- pinctrl-0 = <&pmx_led_blue &pmx_led_red>;
- pinctrl-names = "default";
-
-- health {
-+ led_health: health {
- label = "sheevaplug:blue:health";
- gpios = <&gpio1 17 GPIO_ACTIVE_LOW>;
-- default-state = "keep";
-+ default-state = "on";
- };
-
- misc {
diff --git a/target/linux/kirkwood/patches-6.1/113-readynas_duo_v2.patch b/target/linux/kirkwood/patches-6.1/113-readynas_duo_v2.patch
deleted file mode 100644
index c6452c55a3..0000000000
--- a/target/linux/kirkwood/patches-6.1/113-readynas_duo_v2.patch
+++ /dev/null
@@ -1,76 +0,0 @@
---- a/arch/arm/boot/dts/kirkwood-netgear_readynas_duo_v2.dts
-+++ b/arch/arm/boot/dts/kirkwood-netgear_readynas_duo_v2.dts
-@@ -19,6 +19,13 @@
- reg = <0x00000000 0x10000000>;
- };
-
-+ aliases {
-+ led-boot = &led_power;
-+ led-failsafe = &led_power;
-+ led-running = &led_power;
-+ led-upgrade = &led_power;
-+ };
-+
- chosen {
- bootargs = "console=ttyS0,115200n8 earlyprintk";
- stdout-path = &uart0;
-@@ -115,7 +122,7 @@
- &pmx_led_blue_backup >;
- pinctrl-names = "default";
-
-- power_led {
-+ led_power: power_led {
- label = "status:blue:power_led";
- gpios = <&gpio0 31 GPIO_ACTIVE_LOW>;
- default-state = "keep";
-@@ -129,11 +136,13 @@
- disk1_led {
- label = "status:blue:disk1_led";
- gpios = <&gpio0 23 GPIO_ACTIVE_LOW>;
-+ linux,default-trigger = "ata1";
- };
-
- disk2_led {
- label = "status:blue:disk2_led";
- gpios = <&gpio0 22 GPIO_ACTIVE_LOW>;
-+ linux,default-trigger = "ata2";
- };
-
- backup_led {
-@@ -150,7 +159,13 @@
-
- power-button {
- label = "Power Button";
-- linux,code = <KEY_POWER>;
-+ /* Power button and INT pin from PHY are both connected
-+ * to this GPIO. Every network restart causes PHY restart
-+ * and button is pressed. It's difficult to use it as
-+ * KEY_POWER without changes in kernel (or netifd) so
-+ * the button is configured as regular one.
-+ */
-+ linux,code = <BTN_1>;
- gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
- };
-
-@@ -208,18 +223,13 @@
- };
-
- partition@200000 {
-- label = "uImage";
-+ label = "kernel";
- reg = <0x0200000 0x600000>;
- };
-
- partition@800000 {
-- label = "minirootfs";
-- reg = <0x0800000 0x1000000>;
-- };
--
-- partition@1800000 {
-- label = "jffs2";
-- reg = <0x1800000 0x6800000>;
-+ label = "ubi";
-+ reg = <0x0800000 0x7800000>;
- };
- };
-
diff --git a/target/linux/kirkwood/patches-6.1/114-ctera-c-200-v1.patch b/target/linux/kirkwood/patches-6.1/114-ctera-c-200-v1.patch
deleted file mode 100644
index eb62e1a5ed..0000000000
--- a/target/linux/kirkwood/patches-6.1/114-ctera-c-200-v1.patch
+++ /dev/null
@@ -1,58 +0,0 @@
---- a/arch/arm/boot/dts/kirkwood-c200-v1.dts
-+++ b/arch/arm/boot/dts/kirkwood-c200-v1.dts
-@@ -14,6 +14,14 @@
- model = "Ctera C200 V1";
- compatible = "ctera,c200-v1", "marvell,kirkwood-88f6281", "marvell,kirkwood";
-
-+
-+ aliases {
-+ led-boot = &led_status_green;
-+ led-failsafe = &led_status_red;
-+ led-running = &led_status_green;
-+ led-upgrade = &led_status_red;
-+ };
-+
- chosen {
- bootargs = "console=ttyS0,115200";
- stdout-path = &uart0;
-@@ -78,6 +86,7 @@
- function-enumerator = <1>;
- color = <LED_COLOR_ID_GREEN>;
- gpios = <&gpio0 15 GPIO_ACTIVE_LOW>;
-+ linux,default-trigger = "ata1";
- };
-
- led-2 {
-@@ -85,6 +94,7 @@
- function-enumerator = <2>;
- color = <LED_COLOR_ID_GREEN>;
- gpios = <&gpio0 16 GPIO_ACTIVE_LOW>;
-+ linux,default-trigger = "ata2";
- };
-
- led-3 {
-@@ -94,13 +104,13 @@
- gpios = <&gpio0 17 GPIO_ACTIVE_LOW>;
- };
-
-- led-4 {
-+ led_status_red: led-4 {
- function = LED_FUNCTION_STATUS;
- color = <LED_COLOR_ID_RED>;
- gpios = <&gpio1 6 GPIO_ACTIVE_LOW>;
- };
-
-- led-5 {
-+ led_status_green: led-5 {
- function = LED_FUNCTION_STATUS;
- color = <LED_COLOR_ID_GREEN>;
- gpios = <&gpio1 7 GPIO_ACTIVE_LOW>;
-@@ -240,7 +250,7 @@
- };
-
- partition@7a00000 {
-- label = "rootfs";
-+ label = "ubi";
- reg = <0x7a00000 0x8600000>;
- };
- };
diff --git a/target/linux/kirkwood/patches-6.1/115-nsa310s.patch b/target/linux/kirkwood/patches-6.1/115-nsa310s.patch
deleted file mode 100644
index 4c6e08f49c..0000000000
--- a/target/linux/kirkwood/patches-6.1/115-nsa310s.patch
+++ /dev/null
@@ -1,35 +0,0 @@
---- a/arch/arm/boot/dts/kirkwood-nsa310s.dts
-+++ b/arch/arm/boot/dts/kirkwood-nsa310s.dts
-@@ -16,6 +16,13 @@
- model = "ZyXEL NSA310S";
- compatible = "zyxel,nsa310s", "marvell,kirkwood-88f6702", "marvell,kirkwood";
-
-+ aliases {
-+ led-boot = &led_green_sys;
-+ led-failsafe = &led_red_sys;
-+ led-running = &led_green_sys;
-+ led-upgrade = &led_red_sys;
-+ };
-+
- memory {
- device_type = "memory";
- reg = <0x00000000 0x10000000>;
-@@ -96,14 +103,16 @@
- gpios = <&gpio0 23 GPIO_ACTIVE_HIGH>;
- };
-
-- led-6 {
-+ led_green_sys: led-6 {
-+ label = "nsa310s:green:sys";
- function = LED_FUNCTION_STATUS;
- color = <LED_COLOR_ID_GREEN>;
- gpios = <&gpio0 28 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-
-- led-7 {
-+ led_red_sys: led-7 {
-+ label = "nsa310s:red:sys";
- function = LED_FUNCTION_STATUS;
- color = <LED_COLOR_ID_RED>;
- gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>;
diff --git a/target/linux/kirkwood/patches-6.1/116-4i-edge-200.patch b/target/linux/kirkwood/patches-6.1/116-4i-edge-200.patch
deleted file mode 100644
index ffc46c29dc..0000000000
--- a/target/linux/kirkwood/patches-6.1/116-4i-edge-200.patch
+++ /dev/null
@@ -1,34 +0,0 @@
---- a/arch/arm/boot/dts/kirkwood-4i-edge-200.dts
-+++ b/arch/arm/boot/dts/kirkwood-4i-edge-200.dts
-@@ -20,6 +20,13 @@
- reg = <0x00000000 0x20000000>;
- };
-
-+ aliases {
-+ led-boot = &led_status_green;
-+ led-failsafe = &led_status_orange;
-+ led-running = &led_status_green;
-+ led-upgrade = &led_status_orange;
-+ };
-+
- chosen {
- bootargs = "console=ttyS0,115200n8";
- stdout-path = &uart0;
-@@ -37,13 +44,15 @@
- linux,default-trigger = "mmc0";
- };
-
-- led-2 {
-+ led_status_orange: led-2 {
-+ label = "orange:status";
- function = LED_FUNCTION_STATUS;
- color = <LED_COLOR_ID_AMBER>;
- gpios = <&gpio1 3 GPIO_ACTIVE_HIGH>;
- };
-
-- led-3 {
-+ led_status_green: led-3 {
-+ label = "green:status";
- function = LED_FUNCTION_STATUS;
- color = <LED_COLOR_ID_GREEN>;
- gpios = <&gpio1 17 GPIO_ACTIVE_HIGH>;
diff --git a/target/linux/kirkwood/patches-6.1/117-netgear_stora.patch b/target/linux/kirkwood/patches-6.1/117-netgear_stora.patch
deleted file mode 100644
index c7518933b2..0000000000
--- a/target/linux/kirkwood/patches-6.1/117-netgear_stora.patch
+++ /dev/null
@@ -1,10 +0,0 @@
---- a/arch/arm/boot/dts/Makefile
-+++ b/arch/arm/boot/dts/Makefile
-@@ -375,6 +375,7 @@ dtb-$(CONFIG_MACH_KIRKWOOD) += \
- kirkwood-rs411.dtb \
- kirkwood-sheevaplug.dtb \
- kirkwood-sheevaplug-esata.dtb \
-+ kirkwood-stora.dtb \
- kirkwood-t5325.dtb \
- kirkwood-topkick.dtb \
- kirkwood-ts219-6281.dtb \
diff --git a/target/linux/kirkwood/patches-6.1/118-dns-320l.patch b/target/linux/kirkwood/patches-6.1/118-dns-320l.patch
deleted file mode 100644
index d6c84e2c59..0000000000
--- a/target/linux/kirkwood/patches-6.1/118-dns-320l.patch
+++ /dev/null
@@ -1,35 +0,0 @@
---- a/arch/arm/boot/dts/Makefile
-+++ b/arch/arm/boot/dts/Makefile
-@@ -310,6 +310,7 @@ dtb-$(CONFIG_MACH_KIRKWOOD) += \
- kirkwood-db-88f6282.dtb \
- kirkwood-dir665.dtb \
- kirkwood-dns320.dtb \
-+ kirkwood-dns320l.dtb \
- kirkwood-dns325.dtb \
- kirkwood-dockstar.dtb \
- kirkwood-dreamplug.dtb \
---- a/arch/arm/boot/dts/kirkwood-dns320l.dts
-+++ b/arch/arm/boot/dts/kirkwood-dns320l.dts
-@@ -32,6 +32,13 @@
- reg = <0x00000000 0x10000000>;
- };
-
-+ aliases {
-+ led-boot = &led_orange_usb;
-+ led-failsafe = &led_orange_usb;
-+ led-running = &led_orange_usb;
-+ led-upgrade = &led_orange_usb;
-+ };
-+
- chosen {
- bootargs = "console=ttyS0,115200n8 earlyprintk";
- stdout-path = &uart0;
-@@ -68,7 +75,7 @@
- linux,default-trigger = "usbport";
- };
-
-- orange-usb {
-+ led_orange_usb: orange-usb {
- label = "dns320l:usb:orange";
- gpios = <&gpio0 26 GPIO_ACTIVE_HIGH>;
- };
diff --git a/target/linux/kirkwood/patches-6.1/201-enable-sata-port-specific-led-triggers.patch b/target/linux/kirkwood/patches-6.1/201-enable-sata-port-specific-led-triggers.patch
deleted file mode 100644
index 3db362de9f..0000000000
--- a/target/linux/kirkwood/patches-6.1/201-enable-sata-port-specific-led-triggers.patch
+++ /dev/null
@@ -1,10 +0,0 @@
---- a/arch/arm/mach-mvebu/Kconfig
-+++ b/arch/arm/mach-mvebu/Kconfig
-@@ -115,6 +115,7 @@ config MACH_DOVE
- config MACH_KIRKWOOD
- bool "Marvell Kirkwood boards"
- depends on ARCH_MULTI_V5
-+ select ARCH_WANT_LIBATA_LEDS
- select CPU_FEROCEON
- select GPIOLIB
- select KIRKWOOD_CLK
diff --git a/target/linux/kirkwood/patches-6.1/202-linksys-find-active-root.patch b/target/linux/kirkwood/patches-6.1/202-linksys-find-active-root.patch
deleted file mode 100644
index 5029b1791c..0000000000
--- a/target/linux/kirkwood/patches-6.1/202-linksys-find-active-root.patch
+++ /dev/null
@@ -1,62 +0,0 @@
-The WRT1900AC among other Linksys routers uses a dual-firmware layout.
-Dynamically rename the active partition to "ubi".
-
-Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
----
---- a/drivers/mtd/parsers/ofpart_core.c
-+++ b/drivers/mtd/parsers/ofpart_core.c
-@@ -38,6 +38,8 @@ static bool node_has_compatible(struct d
- return of_get_property(pp, "compatible", NULL);
- }
-
-+static int mangled_rootblock;
-+
- static int parse_fixed_partitions(struct mtd_info *master,
- const struct mtd_partition **pparts,
- struct mtd_part_parser_data *data)
-@@ -47,6 +49,7 @@ static int parse_fixed_partitions(struct
- struct mtd_partition *parts;
- struct device_node *mtd_node;
- struct device_node *ofpart_node;
-+ const char *owrtpart = "ubi";
- const char *partname;
- struct device_node *pp;
- int nr_parts, i, ret = 0;
-@@ -152,9 +155,15 @@ static int parse_fixed_partitions(struct
- parts[i].size = of_read_number(reg + a_cells, s_cells);
- parts[i].of_node = pp;
-
-- partname = of_get_property(pp, "label", &len);
-- if (!partname)
-- partname = of_get_property(pp, "name", &len);
-+ if (mangled_rootblock && (i == mangled_rootblock)) {
-+ partname = owrtpart;
-+ } else {
-+ partname = of_get_property(pp, "label", &len);
-+
-+ if (!partname)
-+ partname = of_get_property(pp, "name", &len);
-+ }
-+
- parts[i].name = partname;
-
- if (of_get_property(pp, "read-only", &len))
-@@ -271,6 +280,18 @@ static int __init ofpart_parser_init(voi
- return 0;
- }
-
-+static int __init active_root(char *str)
-+{
-+ get_option(&str, &mangled_rootblock);
-+
-+ if (!mangled_rootblock)
-+ return 1;
-+
-+ return 1;
-+}
-+
-+__setup("mangled_rootblock=", active_root);
-+
- static void __exit ofpart_parser_exit(void)
- {
- deregister_mtd_parser(&ofpart_parser);
diff --git a/target/linux/kirkwood/patches-6.1/203-blackarmor-nas220.patch b/target/linux/kirkwood/patches-6.1/203-blackarmor-nas220.patch
deleted file mode 100644
index e04a28206a..0000000000
--- a/target/linux/kirkwood/patches-6.1/203-blackarmor-nas220.patch
+++ /dev/null
@@ -1,99 +0,0 @@
---- a/arch/arm/boot/dts/kirkwood-blackarmor-nas220.dts
-+++ b/arch/arm/boot/dts/kirkwood-blackarmor-nas220.dts
-@@ -17,6 +17,13 @@
- compatible = "seagate,blackarmor-nas220","marvell,kirkwood-88f6192",
- "marvell,kirkwood";
-
-+ aliases {
-+ led-boot = &led_status_amber;
-+ led-failsafe = &led_status_amber;
-+ led-running = &led_status_blue;
-+ led-upgrade = &led_status_amber;
-+ };
-+
- memory { /* 128 MB */
- device_type = "memory";
- reg = <0x00000000 0x8000000>;
-@@ -36,14 +43,14 @@
- compatible = "gpio-keys";
-
- reset {
-- label = "Reset";
-- linux,code = <KEY_POWER>;
-+ label = "Reset Button";
-+ linux,code = <KEY_RESTART>;
- gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>;
- };
-
-- button {
-- label = "Power";
-- linux,code = <KEY_SLEEP>;
-+ power {
-+ label = "Power Button";
-+ linux,code = <KEY_POWER>;
- gpios = <&gpio0 26 GPIO_ACTIVE_LOW>;
- };
- };
-@@ -51,11 +58,27 @@
- gpio-leds {
- compatible = "gpio-leds";
-
-- blue-power {
-+ led_power_blue: power_blue {
- label = "nas220:blue:power";
- gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
- linux,default-trigger = "default-on";
- };
-+
-+ disk_blue {
-+ label = "nas220:blue:disk";
-+ gpios = <&gpio0 16 GPIO_ACTIVE_LOW>;
-+ linux,default-trigger = "disk-activity";
-+ };
-+
-+ led_status_blue: status_blue {
-+ label = "nas220:blue:status";
-+ gpios = <&gpio0 23 GPIO_ACTIVE_HIGH>;
-+ };
-+
-+ led_status_amber: status_amber {
-+ label = "nas220:amber:status";
-+ gpios = <&gpio0 22 GPIO_ACTIVE_HIGH>;
-+ };
- };
-
- regulators {
-@@ -153,6 +176,33 @@
-
- &nand {
- status = "okay";
-+
-+ partitions {
-+ compatible = "fixed-partitions";
-+
-+ partition@0 {
-+ label = "uboot";
-+ reg = <0x0 0xa0000>;
-+ read-only;
-+ };
-+
-+ partition@a0000 {
-+ label = "uboot-env";
-+ reg = <0xa0000 0x10000>;
-+ read-only;
-+ };
-+
-+ partition@b0000 {
-+ label = "reserved";
-+ reg = <0xb0000 0x10000>;
-+ read-only;
-+ };
-+
-+ partition@c0000 {
-+ label = "ubi";
-+ reg = <0xc0000 0x1e80000>;
-+ };
-+ };
- };
-
- &mdio {
diff --git a/target/linux/lantiq/files/arch/mips/boot/dts/lantiq/ar9_zyxel_p-2601hn.dts b/target/linux/lantiq/files/arch/mips/boot/dts/lantiq/ar9_zyxel_p-2601hn.dts
index 760bced2d2..cf850ad5d9 100644
--- a/target/linux/lantiq/files/arch/mips/boot/dts/lantiq/ar9_zyxel_p-2601hn.dts
+++ b/target/linux/lantiq/files/arch/mips/boot/dts/lantiq/ar9_zyxel_p-2601hn.dts
@@ -5,7 +5,7 @@
/ {
compatible = "zyxel,p-2601hn", "lantiq,xway", "lantiq,ar9";
- model = "ZyXEL P-2601HN-Fx";
+ model = "Zyxel P-2601HN-Fx";
chosen {
bootargs = "console=ttyLTQ0,115200";
diff --git a/target/linux/lantiq/files/arch/mips/boot/dts/lantiq/danube_arcadyan_arv7525pw.dts b/target/linux/lantiq/files/arch/mips/boot/dts/lantiq/danube_arcadyan_arv7525pw.dts
index 890eac972d..5315f3723e 100644
--- a/target/linux/lantiq/files/arch/mips/boot/dts/lantiq/danube_arcadyan_arv7525pw.dts
+++ b/target/linux/lantiq/files/arch/mips/boot/dts/lantiq/danube_arcadyan_arv7525pw.dts
@@ -135,6 +135,10 @@
macaddr_boardconfig_16: macaddr@16 {
reg = <0x16 0x6>;
};
+
+ eeprom_boardconfig_410: eeprom@410 {
+ reg = <0x410 0x200>;
+ };
};
};
};
@@ -152,7 +156,8 @@
wifi@0,0 {
compatible = "pci0,0";
reg = <0x7000 0 0 0 0>;
- ralink,mtd-eeprom = <&boardconfig 0x410>;
+ nvmem-cells = <&eeprom_boardconfig_410>;
+ nvmem-cell-names = "eeprom";
};
};
diff --git a/target/linux/lantiq/files/arch/mips/boot/dts/lantiq/vr9_arcadyan_vgv7510kw22.dtsi b/target/linux/lantiq/files/arch/mips/boot/dts/lantiq/vr9_arcadyan_vgv7510kw22.dtsi
index daf115088b..5ef6a4cc9e 100644
--- a/target/linux/lantiq/files/arch/mips/boot/dts/lantiq/vr9_arcadyan_vgv7510kw22.dtsi
+++ b/target/linux/lantiq/files/arch/mips/boot/dts/lantiq/vr9_arcadyan_vgv7510kw22.dtsi
@@ -169,6 +169,9 @@
label = "wan";
phy-mode = "mii";
phy-handle = <&phy1>;
+
+ nvmem-cells = <&macaddr_boardconfig_16 2>;
+ nvmem-cell-names = "mac-address";
};
port@2 {
reg = <2>;
diff --git a/target/linux/lantiq/files/arch/mips/boot/dts/lantiq/vr9_zyxel_p-2812hnu-f1.dts b/target/linux/lantiq/files/arch/mips/boot/dts/lantiq/vr9_zyxel_p-2812hnu-f1.dts
index 4a7f63b177..247b811b4f 100644
--- a/target/linux/lantiq/files/arch/mips/boot/dts/lantiq/vr9_zyxel_p-2812hnu-f1.dts
+++ b/target/linux/lantiq/files/arch/mips/boot/dts/lantiq/vr9_zyxel_p-2812hnu-f1.dts
@@ -2,7 +2,7 @@
/ {
compatible = "zyxel,p-2812hnu-f1", "zyxel,p-2812hnu", "lantiq,xway", "lantiq,vr9";
- model = "ZyXEL P-2812HNU-F1";
+ model = "Zyxel P-2812HNU-F1";
leds {
usb1 {
diff --git a/target/linux/lantiq/files/arch/mips/boot/dts/lantiq/vr9_zyxel_p-2812hnu-f3.dts b/target/linux/lantiq/files/arch/mips/boot/dts/lantiq/vr9_zyxel_p-2812hnu-f3.dts
index 376cdaeb61..a7fd3d3ec8 100644
--- a/target/linux/lantiq/files/arch/mips/boot/dts/lantiq/vr9_zyxel_p-2812hnu-f3.dts
+++ b/target/linux/lantiq/files/arch/mips/boot/dts/lantiq/vr9_zyxel_p-2812hnu-f3.dts
@@ -2,7 +2,7 @@
/ {
compatible = "zyxel,p-2812hnu-f3", "zyxel,p-2812hnu", "lantiq,xway", "lantiq,vr9";
- model = "ZyXEL P-2812HNU-F3";
+ model = "Zyxel P-2812HNU-F3";
};
&pci0 {
diff --git a/target/linux/lantiq/image/ar9.mk b/target/linux/lantiq/image/ar9.mk
index 3a301f3655..f4a15cfb3e 100644
--- a/target/linux/lantiq/image/ar9.mk
+++ b/target/linux/lantiq/image/ar9.mk
@@ -159,7 +159,7 @@ endef
TARGET_DEVICES += zte_h201l
define Device/zyxel_p-2601hn
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
DEVICE_MODEL := P-2601HN
DEVICE_VARIANT := F1/F3
IMAGE_SIZE := 15616k
diff --git a/target/linux/lantiq/image/vr9.mk b/target/linux/lantiq/image/vr9.mk
index dc307e1ee4..d4bded9cae 100644
--- a/target/linux/lantiq/image/vr9.mk
+++ b/target/linux/lantiq/image/vr9.mk
@@ -370,7 +370,7 @@ TARGET_DEVICES += netgear_dm200
define Device/zyxel_p-2812hnu-f1
$(Device/dsa-migration)
$(Device/NAND)
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
DEVICE_MODEL := P-2812HNU
DEVICE_VARIANT := F1
BOARD_NAME := P2812HNUF1
@@ -384,7 +384,7 @@ TARGET_DEVICES += zyxel_p-2812hnu-f1
define Device/zyxel_p-2812hnu-f3
$(Device/dsa-migration)
$(Device/NAND)
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
DEVICE_MODEL := P-2812HNU
DEVICE_VARIANT := F3
BOARD_NAME := P2812HNUF3
diff --git a/target/linux/lantiq/patches-6.6/0001-MIPS-lantiq-add-pcie-driver.patch b/target/linux/lantiq/patches-6.6/0001-MIPS-lantiq-add-pcie-driver.patch
index 3e23c0f23d..b796de9c11 100644
--- a/target/linux/lantiq/patches-6.6/0001-MIPS-lantiq-add-pcie-driver.patch
+++ b/target/linux/lantiq/patches-6.6/0001-MIPS-lantiq-add-pcie-driver.patch
@@ -5524,7 +5524,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
(transaction layer end-to-end CRC checking).
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
-@@ -1599,6 +1599,8 @@ void pci_walk_bus_locked(struct pci_bus
+@@ -1602,6 +1602,8 @@ void pci_walk_bus_locked(struct pci_bus
void *userdata);
int pci_cfg_space_size(struct pci_dev *dev);
unsigned char pci_bus_max_busnr(struct pci_bus *bus);
diff --git a/target/linux/lantiq/patches-6.6/0027-v6.11-net-ethernet-lantiq_etop-remove-redundant-device-nam.patch b/target/linux/lantiq/patches-6.6/0027-v6.11-net-ethernet-lantiq_etop-remove-redundant-device-nam.patch
new file mode 100644
index 0000000000..abaef6c3a8
--- /dev/null
+++ b/target/linux/lantiq/patches-6.6/0027-v6.11-net-ethernet-lantiq_etop-remove-redundant-device-nam.patch
@@ -0,0 +1,31 @@
+From 9283477e28913c1e7625c0a8d6959745e2431533 Mon Sep 17 00:00:00 2001
+From: Aleksander Jan Bajkowski <olek2@wp.pl>
+Date: Sat, 13 Jul 2024 19:09:20 +0200
+Subject: [PATCH] net: ethernet: lantiq_etop: remove redundant device name
+ setup
+
+The same name is set when allocating the netdevice structure in the
+alloc_etherdev_mq()->alloc_etherrdev_mqs() function. Therefore, there
+is no need to manually set it.
+
+This fixes CheckPatch warnings:
+WARNING: Prefer strscpy over strcpy - see: https://github.com/KSPP/linux/issues/88
+ strcpy(dev->name, "eth%d");
+
+Signed-off-by: Aleksander Jan Bajkowski <olek2@wp.pl>
+Link: https://patch.msgid.link/20240713170920.863171-1-olek2@wp.pl
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/lantiq_etop.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/drivers/net/ethernet/lantiq_etop.c
++++ b/drivers/net/ethernet/lantiq_etop.c
+@@ -675,7 +675,6 @@ ltq_etop_probe(struct platform_device *p
+ err = -ENOMEM;
+ goto err_out;
+ }
+- strcpy(dev->name, "eth%d");
+ dev->netdev_ops = &ltq_eth_netdev_ops;
+ dev->ethtool_ops = &ltq_etop_ethtool_ops;
+ priv = netdev_priv(dev);
diff --git a/target/linux/lantiq/patches-6.6/0028-NET-lantiq-various-etop-fixes.patch b/target/linux/lantiq/patches-6.6/0028-NET-lantiq-various-etop-fixes.patch
index 8ac1097267..788a34d61a 100644
--- a/target/linux/lantiq/patches-6.6/0028-NET-lantiq-various-etop-fixes.patch
+++ b/target/linux/lantiq/patches-6.6/0028-NET-lantiq-various-etop-fixes.patch
@@ -5,8 +5,8 @@ Subject: [PATCH 28/36] NET: lantiq: various etop fixes
Signed-off-by: John Crispin <blogic@openwrt.org>
---
- drivers/net/ethernet/lantiq_etop.c | 555 +++++++++++++++++++++++++-----------
- 1 file changed, 389 insertions(+), 166 deletions(-)
+ drivers/net/ethernet/lantiq_etop.c | 530 ++++++++++++++++++++---------
+ 1 file changed, 375 insertions(+), 155 deletions(-)
--- a/drivers/net/ethernet/lantiq_etop.c
+++ b/drivers/net/ethernet/lantiq_etop.c
@@ -66,10 +66,10 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
-#define LTQ_ETOP_IGPLEN 0x16080
+
+#define MAC_CFG_MASK 0xfff
-+#define MAC_CFG_CGEN (1 << 11)
-+#define MAC_CFG_DUPLEX (1 << 2)
-+#define MAC_CFG_SPEED (1 << 1)
-+#define MAC_CFG_LINK (1 << 0)
++#define MAC_CFG_CGEN BIT(11)
++#define MAC_CFG_DUPLEX BIT(2)
++#define MAC_CFG_SPEED BIT(1)
++#define MAC_CFG_LINK BIT(0)
#define MAX_DMA_CHAN 0x8
#define MAX_DMA_CRC_LEN 0x4
@@ -89,11 +89,11 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
-#define IS_TX(x) ((x) == LTQ_ETOP_TX_CHANNEL)
-#define IS_RX(x) ((x) == LTQ_ETOP_RX_CHANNEL)
+#define ETOP_CFG_MASK 0xfff
-+#define ETOP_CFG_FEN0 (1 << 8)
-+#define ETOP_CFG_SEN0 (1 << 6)
-+#define ETOP_CFG_OFF1 (1 << 3)
-+#define ETOP_CFG_REMII0 (1 << 1)
-+#define ETOP_CFG_OFF0 (1 << 0)
++#define ETOP_CFG_FEN0 BIT(8)
++#define ETOP_CFG_SEN0 BIT(6)
++#define ETOP_CFG_OFF1 BIT(3)
++#define ETOP_CFG_REMII0 BIT(1)
++#define ETOP_CFG_OFF0 BIT(0)
+
+#define LTQ_GBIT_MDIO_CTL 0xCC
+#define LTQ_GBIT_MDIO_DATA 0xd0
@@ -103,8 +103,8 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
+#define LTQ_GBIT_PMAC_RX_IPG 0xa8
+#define LTQ_GBIT_RGMII_CTL 0x78
+
-+#define PMAC_HD_CTL_AS (1 << 19)
-+#define PMAC_HD_CTL_RXSH (1 << 22)
++#define PMAC_HD_CTL_AS BIT(19)
++#define PMAC_HD_CTL_RXSH BIT(22)
+
+/* Switch Enable (0=disable, 1=enable) */
+#define GCTL0_SE 0x80000000
@@ -170,14 +170,13 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
int tx_burst_len;
int rx_burst_len;
-- spinlock_t lock;
+ int tx_irq;
+ int rx_irq;
+
+ unsigned char mac[6];
+ phy_interface_t mii_mode;
-+
-+ spinlock_t lock;
++
+ spinlock_t lock;
+
+ struct clk *clk_ppe;
+ struct clk *clk_switch;
@@ -186,7 +185,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
};
+static int ltq_etop_mdio_wr(struct mii_bus *bus, int phy_addr,
-+ int phy_reg, u16 phy_data);
++ int phy_reg, u16 phy_data);
+
static int
ltq_etop_alloc_skb(struct ltq_etop_chan *ch)
@@ -256,12 +255,12 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
return 1;
}
-@@ -202,9 +278,10 @@ static irqreturn_t
+@@ -202,9 +278,11 @@ static irqreturn_t
ltq_etop_dma_irq(int irq, void *_priv)
{
struct ltq_etop_priv *priv = _priv;
- int ch = irq - LTQ_DMA_CH0_INT;
--
+
- napi_schedule(&priv->ch[ch].napi);
+ if (irq == priv->txch.dma.irq)
+ napi_schedule(&priv->txch.napi);
@@ -270,16 +269,16 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
return IRQ_HANDLED;
}
-@@ -216,7 +293,7 @@ ltq_etop_free_channel(struct net_device
+@@ -216,7 +294,7 @@ ltq_etop_free_channel(struct net_device
ltq_dma_free(&ch->dma);
if (ch->dma.irq)
free_irq(ch->dma.irq, priv);
- if (IS_RX(ch->idx)) {
-+ if (ch == &priv->txch) {
- int desc;
++ if (ch == &priv->rxch) {
+ struct ltq_dma_channel *dma = &ch->dma;
- for (desc = 0; desc < LTQ_DESC_NUM; desc++)
-@@ -228,80 +305,135 @@ static void
+ for (dma->desc = 0; dma->desc < LTQ_DESC_NUM; dma->desc++)
+@@ -228,80 +306,137 @@ static void
ltq_etop_hw_exit(struct net_device *dev)
{
struct ltq_etop_priv *priv = netdev_priv(dev);
@@ -320,13 +319,14 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
+ ltq_gbit_w32_mask(0x300, 0, LTQ_GBIT_GCTL0);
+ /* disable pmac & dmac headers */
+ ltq_gbit_w32_mask(PMAC_HD_CTL_AS | PMAC_HD_CTL_RXSH, 0,
-+ LTQ_GBIT_PMAC_HD_CTL);
++ LTQ_GBIT_PMAC_HD_CTL);
+ /* Due to traffic halt when burst length 8,
-+ replace default IPG value with 0x3B */
++ *replace default IPG value with 0x3B
++ */
+ ltq_gbit_w32(0x3B, LTQ_GBIT_PMAC_RX_IPG);
+ /* set mdc clock to 2.5 MHz */
+ ltq_gbit_w32_mask(MDC_CLOCK_MASK, 4 << MDC_CLOCK_OFFSET,
-+ LTQ_GBIT_RGMII_CTL);
++ LTQ_GBIT_RGMII_CTL);
}
static int
@@ -336,11 +336,10 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
- int i;
- int err;
+ phy_interface_t mii_mode = priv->mii_mode;
-
-- ltq_pmu_enable(PMU_PPE);
++
+ clk_enable(priv->clk_ppe);
-- switch (priv->pldata->mii_mode) {
+- ltq_pmu_enable(PMU_PPE);
+ if (of_machine_is_compatible("lantiq,ar9")) {
+ ltq_etop_gbit_init(dev);
+ /* force the etops link to the gbit to MII */
@@ -349,7 +348,8 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
+ ltq_etop_w32_mask(MDIO_CFG_MASK, 0, LTQ_ETOP_MDIO_CFG);
+ ltq_etop_w32_mask(MAC_CFG_MASK, MAC_CFG_CGEN | MAC_CFG_DUPLEX |
+ MAC_CFG_SPEED | MAC_CFG_LINK, LTQ_ETOP_MAC_CFG);
-+
+
+- switch (priv->pldata->mii_mode) {
+ switch (mii_mode) {
case PHY_INTERFACE_MODE_RMII:
- ltq_etop_w32_mask(ETOP_MII_MASK, ETOP_MII_REVERSE,
@@ -373,7 +373,8 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
+ /* enable clock for internal PHY */
+ clk_enable(priv->clk_ephycgu);
+ /* we need to write this magic to the internal phy to
-+ make it work */
++ * make it work
++ */
+ ltq_etop_mdio_wr(NULL, 0x8, 0x12, 0xC020);
+ pr_info("Selected EPHY mode\n");
+ break;
@@ -464,12 +465,12 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
}
static void
-@@ -320,6 +452,39 @@ static const struct ethtool_ops ltq_etop
+@@ -320,6 +455,39 @@ static const struct ethtool_ops ltq_etop
};
static int
+ltq_etop_mdio_wr_xr9(struct mii_bus *bus, int phy_addr,
-+ int phy_reg, u16 phy_data)
++ int phy_reg, u16 phy_data)
+{
+ u32 val = MDIO_XR9_REQUEST | MDIO_XR9_WRITE |
+ (phy_data << MDIO_XR9_WR_OFFSET) |
@@ -504,7 +505,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
ltq_etop_mdio_wr(struct mii_bus *bus, int phy_addr, int phy_reg, u16 phy_data)
{
u32 val = MDIO_REQUEST |
-@@ -327,9 +492,9 @@ ltq_etop_mdio_wr(struct mii_bus *bus, in
+@@ -327,9 +495,9 @@ ltq_etop_mdio_wr(struct mii_bus *bus, in
((phy_reg & MDIO_REG_MASK) << MDIO_REG_OFFSET) |
phy_data;
@@ -516,7 +517,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
return 0;
}
-@@ -340,12 +505,12 @@ ltq_etop_mdio_rd(struct mii_bus *bus, in
+@@ -340,12 +508,12 @@ ltq_etop_mdio_rd(struct mii_bus *bus, in
((phy_addr & MDIO_ADDR_MASK) << MDIO_ADDR_OFFSET) |
((phy_reg & MDIO_REG_MASK) << MDIO_REG_OFFSET);
@@ -533,7 +534,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
return val;
}
-@@ -361,7 +526,10 @@ ltq_etop_mdio_probe(struct net_device *d
+@@ -361,7 +529,10 @@ ltq_etop_mdio_probe(struct net_device *d
struct ltq_etop_priv *priv = netdev_priv(dev);
struct phy_device *phydev;
@@ -545,7 +546,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
if (!phydev) {
netdev_err(dev, "no PHY found\n");
-@@ -369,14 +537,17 @@ ltq_etop_mdio_probe(struct net_device *d
+@@ -369,14 +540,17 @@ ltq_etop_mdio_probe(struct net_device *d
}
phydev = phy_connect(dev, phydev_name(phydev),
@@ -565,7 +566,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
phy_attached_info(phydev);
-@@ -397,8 +568,13 @@ ltq_etop_mdio_init(struct net_device *de
+@@ -397,8 +571,13 @@ ltq_etop_mdio_init(struct net_device *de
}
priv->mii_bus->priv = dev;
@@ -581,7 +582,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
priv->mii_bus->name = "ltq_mii";
snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
priv->pdev->name, priv->pdev->id);
-@@ -435,18 +611,21 @@ static int
+@@ -435,18 +614,21 @@ static int
ltq_etop_open(struct net_device *dev)
{
struct ltq_etop_priv *priv = netdev_priv(dev);
@@ -613,7 +614,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
netif_tx_start_all_queues(dev);
return 0;
}
-@@ -455,18 +634,19 @@ static int
+@@ -455,18 +637,19 @@ static int
ltq_etop_stop(struct net_device *dev)
{
struct ltq_etop_priv *priv = netdev_priv(dev);
@@ -643,7 +644,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
return 0;
}
-@@ -476,15 +656,16 @@ ltq_etop_tx(struct sk_buff *skb, struct
+@@ -476,15 +659,16 @@ ltq_etop_tx(struct sk_buff *skb, struct
int queue = skb_get_queue_mapping(skb);
struct netdev_queue *txq = netdev_get_tx_queue(dev, queue);
struct ltq_etop_priv *priv = netdev_priv(dev);
@@ -660,11 +661,11 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
- if ((desc->ctl & (LTQ_DMA_OWN | LTQ_DMA_C)) || ch->skb[ch->dma.desc]) {
+ if ((desc->ctl & (LTQ_DMA_OWN | LTQ_DMA_C)) ||
-+ priv->txch.skb[priv->txch.dma.desc]) {
++ priv->txch.skb[priv->txch.dma.desc]) {
netdev_err(dev, "tx ring full\n");
netif_tx_stop_queue(txq);
return NETDEV_TX_BUSY;
-@@ -492,7 +673,7 @@ ltq_etop_tx(struct sk_buff *skb, struct
+@@ -492,7 +676,7 @@ ltq_etop_tx(struct sk_buff *skb, struct
/* dma needs to start on a burst length value aligned address */
byte_offset = CPHYSADDR(skb->data) % (priv->tx_burst_len * 4);
@@ -673,7 +674,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
netif_trans_update(dev);
-@@ -503,11 +684,11 @@ ltq_etop_tx(struct sk_buff *skb, struct
+@@ -503,11 +687,11 @@ ltq_etop_tx(struct sk_buff *skb, struct
wmb();
desc->ctl = LTQ_DMA_OWN | LTQ_DMA_SOP | LTQ_DMA_EOP |
LTQ_DMA_TX_OFFSET(byte_offset) | (len & LTQ_DMA_SIZE_MASK);
@@ -688,7 +689,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
netif_tx_stop_queue(txq);
return NETDEV_TX_OK;
-@@ -518,11 +699,14 @@ ltq_etop_change_mtu(struct net_device *d
+@@ -518,11 +702,14 @@ ltq_etop_change_mtu(struct net_device *d
{
struct ltq_etop_priv *priv = netdev_priv(dev);
unsigned long flags;
@@ -704,7 +705,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
spin_unlock_irqrestore(&priv->lock, flags);
return 0;
-@@ -575,6 +759,9 @@ ltq_etop_init(struct net_device *dev)
+@@ -575,6 +762,9 @@ ltq_etop_init(struct net_device *dev)
if (err)
goto err_hw;
ltq_etop_change_mtu(dev, 1500);
@@ -714,7 +715,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
memcpy(&mac, &priv->pldata->mac, sizeof(struct sockaddr));
if (!is_valid_ether_addr(mac.sa_data)) {
-@@ -592,9 +779,10 @@ ltq_etop_init(struct net_device *dev)
+@@ -592,9 +782,10 @@ ltq_etop_init(struct net_device *dev)
dev->addr_assign_type = NET_ADDR_RANDOM;
ltq_etop_set_multicast_list(dev);
@@ -724,11 +725,11 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
+ if (!ltq_etop_mdio_init(dev))
+ dev->ethtool_ops = &ltq_etop_ethtool_ops;
+ else
-+ pr_warn("etop: mdio probe failed\n");;
++ pr_warn("etop: mdio probe failed\n");
return 0;
err_netdev:
-@@ -614,6 +802,9 @@ ltq_etop_tx_timeout(struct net_device *d
+@@ -614,6 +805,9 @@ ltq_etop_tx_timeout(struct net_device *d
err = ltq_etop_hw_init(dev);
if (err)
goto err_hw;
@@ -738,7 +739,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
netif_trans_update(dev);
netif_wake_queue(dev);
return;
-@@ -637,14 +828,18 @@ static const struct net_device_ops ltq_e
+@@ -637,14 +831,18 @@ static const struct net_device_ops ltq_e
.ndo_tx_timeout = ltq_etop_tx_timeout,
};
@@ -761,7 +762,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
-@@ -670,19 +865,55 @@ ltq_etop_probe(struct platform_device *p
+@@ -670,18 +868,54 @@ ltq_etop_probe(struct platform_device *p
goto err_out;
}
@@ -777,7 +778,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
+ goto err_out;
+ }
+ ltq_gbit_membase = devm_ioremap(&pdev->dev,
-+ gbit_res->start, resource_size(gbit_res));
++ gbit_res->start, resource_size(gbit_res));
+ if (!ltq_gbit_membase) {
+ dev_err(&pdev->dev, "failed to remap gigabit switch %d\n",
+ pdev->id);
@@ -787,7 +788,6 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
}
+
+ dev = alloc_etherdev_mq(sizeof(struct ltq_etop_priv), 4);
- strcpy(dev->name, "eth%d");
dev->netdev_ops = &ltq_eth_netdev_ops;
- dev->ethtool_ops = &ltq_etop_ethtool_ops;
priv = netdev_priv(dev);
@@ -823,7 +823,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
spin_lock_init(&priv->lock);
SET_NETDEV_DEV(dev, &pdev->dev);
-@@ -698,15 +929,10 @@ ltq_etop_probe(struct platform_device *p
+@@ -697,15 +931,10 @@ ltq_etop_probe(struct platform_device *p
goto err_free;
}
@@ -843,7 +843,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
err = register_netdev(dev);
if (err)
-@@ -735,31 +961,22 @@ ltq_etop_remove(struct platform_device *
+@@ -734,31 +963,22 @@ ltq_etop_remove(struct platform_device *
return 0;
}
diff --git a/target/linux/lantiq/patches-6.6/0035-owrt-lantiq-wifi-and-ethernet-eeprom-handling.patch b/target/linux/lantiq/patches-6.6/0035-owrt-lantiq-wifi-and-ethernet-eeprom-handling.patch
index b06c5ab47c..3e349d4c32 100644
--- a/target/linux/lantiq/patches-6.6/0035-owrt-lantiq-wifi-and-ethernet-eeprom-handling.patch
+++ b/target/linux/lantiq/patches-6.6/0035-owrt-lantiq-wifi-and-ethernet-eeprom-handling.patch
@@ -203,7 +203,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
+early_param("ethaddr", setup_ethaddr);
--- a/drivers/net/ethernet/lantiq_etop.c
+++ b/drivers/net/ethernet/lantiq_etop.c
-@@ -763,7 +763,11 @@ ltq_etop_init(struct net_device *dev)
+@@ -766,7 +766,11 @@ ltq_etop_init(struct net_device *dev)
if (err)
goto err_hw;
diff --git a/target/linux/lantiq/patches-6.6/0701-NET-lantiq-etop-of-mido.patch b/target/linux/lantiq/patches-6.6/0701-NET-lantiq-etop-of-mido.patch
index 19c027b9f8..d80cdb0872 100644
--- a/target/linux/lantiq/patches-6.6/0701-NET-lantiq-etop-of-mido.patch
+++ b/target/linux/lantiq/patches-6.6/0701-NET-lantiq-etop-of-mido.patch
@@ -18,7 +18,7 @@ Signed-off-by: Johann Neuhauser <johann@it-neuhauser.de>
#include <asm/checksum.h>
-@@ -558,7 +559,8 @@ static int
+@@ -561,7 +562,8 @@ static int
ltq_etop_mdio_init(struct net_device *dev)
{
struct ltq_etop_priv *priv = netdev_priv(dev);
@@ -28,7 +28,7 @@ Signed-off-by: Johann Neuhauser <johann@it-neuhauser.de>
priv->mii_bus = mdiobus_alloc();
if (!priv->mii_bus) {
-@@ -578,7 +580,15 @@ ltq_etop_mdio_init(struct net_device *de
+@@ -581,7 +583,15 @@ ltq_etop_mdio_init(struct net_device *de
priv->mii_bus->name = "ltq_mii";
snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
priv->pdev->name, priv->pdev->id);
diff --git a/target/linux/lantiq/xrx200/base-files/etc/board.d/02_network b/target/linux/lantiq/xrx200/base-files/etc/board.d/02_network
index 2208752c14..27a3c75edc 100644
--- a/target/linux/lantiq/xrx200/base-files/etc/board.d/02_network
+++ b/target/linux/lantiq/xrx200/base-files/etc/board.d/02_network
@@ -110,10 +110,6 @@ lantiq_setup_macs()
lan_mac=$(mtd_get_mac_ascii u-boot-env ethaddr)
wan_mac=$(macaddr_add "$lan_mac" 1)
;;
- arcadyan,vgv7510kw22-brn|\
- arcadyan,vgv7510kw22-nor)
- wan_mac=$(macaddr_add "$(mtd_get_mac_binary board_config 0x16)" 2)
- ;;
arcadyan,vgv7519-brn|\
arcadyan,vgv7519-nor|\
arcadyan,vrv9510kwac23)
diff --git a/target/linux/layerscape/Makefile b/target/linux/layerscape/Makefile
index 30b9fb8f73..e0bc544f43 100644
--- a/target/linux/layerscape/Makefile
+++ b/target/linux/layerscape/Makefile
@@ -7,8 +7,7 @@ include $(TOPDIR)/rules.mk
BOARD:=layerscape
BOARDNAME:=NXP Layerscape
-KERNEL_PATCHVER:=6.1
-KERNEL_TESTING_PATCHVER:=6.6
+KERNEL_PATCHVER:=6.6
FEATURES:=squashfs nand usb pcie gpio fpu ubifs ext4 rootfs-part boot-part
SUBTARGETS:=armv8_64b armv7
diff --git a/target/linux/layerscape/armv7/config-6.1 b/target/linux/layerscape/armv7/config-6.1
index d60e5824db..6606d53e95 100644
--- a/target/linux/layerscape/armv7/config-6.1
+++ b/target/linux/layerscape/armv7/config-6.1
@@ -205,8 +205,6 @@ CONFIG_ELF_CORE=y
# CONFIG_ENABLE_DEFAULT_TRACERS is not set
CONFIG_EXCLUSIVE_SYSTEM_RAM=y
CONFIG_EXT4_FS=y
-CONFIG_EXT4_FS_POSIX_ACL=y
-CONFIG_EXT4_FS_SECURITY=y
CONFIG_F2FS_FS=y
CONFIG_FAILOVER=y
CONFIG_FAT_FS=y
@@ -225,7 +223,6 @@ CONFIG_FSL_RCPM=y
CONFIG_FSL_XGMAC_MDIO=y
CONFIG_FS_IOMAP=y
CONFIG_FS_MBCACHE=y
-CONFIG_FS_POSIX_ACL=y
CONFIG_FTRACE=y
# CONFIG_FTRACE_SYSCALLS is not set
CONFIG_FUSE_FS=y
@@ -645,7 +642,6 @@ CONFIG_THREAD_INFO_IN_TASK=y
CONFIG_TICK_CPU_ACCOUNTING=y
CONFIG_TIMER_OF=y
CONFIG_TIMER_PROBE=y
-CONFIG_TMPFS_POSIX_ACL=y
CONFIG_TREE_RCU=y
CONFIG_TREE_SRCU=y
CONFIG_UBIFS_FS=y
diff --git a/target/linux/layerscape/armv7/config-6.6 b/target/linux/layerscape/armv7/config-6.6
index 63c49df174..ee397fc7c6 100644
--- a/target/linux/layerscape/armv7/config-6.6
+++ b/target/linux/layerscape/armv7/config-6.6
@@ -206,8 +206,6 @@ CONFIG_ELF_CORE=y
# CONFIG_ENABLE_DEFAULT_TRACERS is not set
CONFIG_EXCLUSIVE_SYSTEM_RAM=y
CONFIG_EXT4_FS=y
-CONFIG_EXT4_FS_POSIX_ACL=y
-CONFIG_EXT4_FS_SECURITY=y
CONFIG_F2FS_FS=y
CONFIG_FAILOVER=y
CONFIG_FAT_FS=y
@@ -225,7 +223,6 @@ CONFIG_FSL_RCPM=y
CONFIG_FSL_XGMAC_MDIO=y
CONFIG_FS_IOMAP=y
CONFIG_FS_MBCACHE=y
-CONFIG_FS_POSIX_ACL=y
CONFIG_FTRACE=y
# CONFIG_FTRACE_SYSCALLS is not set
CONFIG_FUNCTION_ALIGNMENT=0
@@ -652,7 +649,6 @@ CONFIG_THREAD_INFO_IN_TASK=y
CONFIG_TICK_CPU_ACCOUNTING=y
CONFIG_TIMER_OF=y
CONFIG_TIMER_PROBE=y
-CONFIG_TMPFS_POSIX_ACL=y
CONFIG_TREE_RCU=y
CONFIG_TREE_SRCU=y
CONFIG_UBIFS_FS=y
diff --git a/target/linux/layerscape/armv8_64b/config-6.1 b/target/linux/layerscape/armv8_64b/config-6.1
index a2a4a633af..d0b71a91f1 100644
--- a/target/linux/layerscape/armv8_64b/config-6.1
+++ b/target/linux/layerscape/armv8_64b/config-6.1
@@ -22,8 +22,6 @@ CONFIG_ARCH_WANTS_NO_INSTR=y
CONFIG_ARCH_WANTS_THP_SWAP=y
CONFIG_ARM64=y
CONFIG_ARM64_4K_PAGES=y
-CONFIG_ARM64_CNP=y
-CONFIG_ARM64_EPAN=y
CONFIG_ARM64_ERRATUM_1165522=y
CONFIG_ARM64_ERRATUM_1286807=y
CONFIG_ARM64_ERRATUM_2051678=y
@@ -40,7 +38,6 @@ CONFIG_ARM64_ERRATUM_843419=y
CONFIG_ARM64_HW_AFDBM=y
CONFIG_ARM64_LD_HAS_FIX_ERRATUM_843419=y
CONFIG_ARM64_PAGE_SHIFT=12
-CONFIG_ARM64_PAN=y
CONFIG_ARM64_PA_BITS=48
CONFIG_ARM64_PA_BITS_48=y
CONFIG_ARM64_PTR_AUTH=y
@@ -104,9 +101,6 @@ CONFIG_BLK_MQ_VIRTIO=y
CONFIG_BLK_PM=y
CONFIG_BSD_PROCESS_ACCT=y
CONFIG_BSD_PROCESS_ACCT_V3=y
-CONFIG_BTRFS_FS=y
-# CONFIG_BTRFS_FS_CHECK_INTEGRITY is not set
-CONFIG_BTRFS_FS_POSIX_ACL=y
CONFIG_CAVIUM_ERRATUM_22375=y
CONFIG_CAVIUM_ERRATUM_23144=y
CONFIG_CAVIUM_ERRATUM_23154=y
@@ -261,8 +255,6 @@ CONFIG_ELF_CORE=y
# CONFIG_EMBEDDED is not set
CONFIG_EXCLUSIVE_SYSTEM_RAM=y
CONFIG_EXT4_FS=y
-CONFIG_EXT4_FS_POSIX_ACL=y
-CONFIG_EXT4_FS_SECURITY=y
CONFIG_EXTCON=y
CONFIG_EXTCON_USB_GPIO=y
CONFIG_F2FS_FS=y
@@ -319,7 +311,6 @@ CONFIG_FSL_RCPM=y
CONFIG_FSL_XGMAC_MDIO=y
CONFIG_FS_IOMAP=y
CONFIG_FS_MBCACHE=y
-CONFIG_FS_POSIX_ACL=y
CONFIG_FUSE_FS=y
CONFIG_FWNODE_MDIO=y
CONFIG_FW_CACHE=y
@@ -794,7 +785,6 @@ CONFIG_THREAD_INFO_IN_TASK=y
CONFIG_TICK_CPU_ACCOUNTING=y
CONFIG_TIMER_OF=y
CONFIG_TIMER_PROBE=y
-CONFIG_TMPFS_POSIX_ACL=y
CONFIG_TRACE_IRQFLAGS_NMI_SUPPORT=y
CONFIG_TRANSPARENT_HUGEPAGE=y
CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y
@@ -885,7 +875,6 @@ CONFIG_XEN_SYS_HYPERVISOR=y
# CONFIG_XEN_WDT is not set
CONFIG_XEN_XENBUS_FRONTEND=y
CONFIG_XFS_FS=y
-CONFIG_XFS_POSIX_ACL=y
CONFIG_XFS_RT=y
CONFIG_XOR_BLOCKS=y
CONFIG_XPS=y
diff --git a/target/linux/layerscape/armv8_64b/config-6.6 b/target/linux/layerscape/armv8_64b/config-6.6
index f95b4603be..3c052edb7d 100644
--- a/target/linux/layerscape/armv8_64b/config-6.6
+++ b/target/linux/layerscape/armv8_64b/config-6.6
@@ -23,8 +23,6 @@ CONFIG_ARCH_WANTS_NO_INSTR=y
CONFIG_ARCH_WANTS_THP_SWAP=y
CONFIG_ARM64=y
CONFIG_ARM64_4K_PAGES=y
-CONFIG_ARM64_CNP=y
-CONFIG_ARM64_EPAN=y
CONFIG_ARM64_ERRATUM_1165522=y
CONFIG_ARM64_ERRATUM_1286807=y
CONFIG_ARM64_ERRATUM_2051678=y
@@ -41,7 +39,6 @@ CONFIG_ARM64_ERRATUM_843419=y
CONFIG_ARM64_HW_AFDBM=y
CONFIG_ARM64_LD_HAS_FIX_ERRATUM_843419=y
CONFIG_ARM64_PAGE_SHIFT=12
-CONFIG_ARM64_PAN=y
CONFIG_ARM64_PA_BITS=48
CONFIG_ARM64_PA_BITS_48=y
CONFIG_ARM64_PTR_AUTH=y
@@ -105,9 +102,6 @@ CONFIG_BLK_MQ_VIRTIO=y
CONFIG_BLK_PM=y
CONFIG_BSD_PROCESS_ACCT=y
CONFIG_BSD_PROCESS_ACCT_V3=y
-CONFIG_BTRFS_FS=y
-# CONFIG_BTRFS_FS_CHECK_INTEGRITY is not set
-CONFIG_BTRFS_FS_POSIX_ACL=y
CONFIG_BUFFER_HEAD=y
CONFIG_BUILTIN_RETURN_ADDRESS_STRIPS_PAC=y
CONFIG_CAVIUM_ERRATUM_22375=y
@@ -268,8 +262,6 @@ CONFIG_EEPROM_AT24=y
CONFIG_ELF_CORE=y
CONFIG_EXCLUSIVE_SYSTEM_RAM=y
CONFIG_EXT4_FS=y
-CONFIG_EXT4_FS_POSIX_ACL=y
-CONFIG_EXT4_FS_SECURITY=y
CONFIG_EXTCON=y
CONFIG_EXTCON_USB_GPIO=y
CONFIG_F2FS_FS=y
@@ -329,7 +321,6 @@ CONFIG_FSL_RCPM=y
CONFIG_FSL_XGMAC_MDIO=y
CONFIG_FS_IOMAP=y
CONFIG_FS_MBCACHE=y
-CONFIG_FS_POSIX_ACL=y
CONFIG_FUNCTION_ALIGNMENT=4
CONFIG_FUNCTION_ALIGNMENT_4B=y
CONFIG_FUSE_FS=y
@@ -802,7 +793,6 @@ CONFIG_THREAD_INFO_IN_TASK=y
CONFIG_TICK_CPU_ACCOUNTING=y
CONFIG_TIMER_OF=y
CONFIG_TIMER_PROBE=y
-CONFIG_TMPFS_POSIX_ACL=y
CONFIG_TRACE_IRQFLAGS_NMI_SUPPORT=y
CONFIG_TRANSPARENT_HUGEPAGE=y
CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y
@@ -895,7 +885,6 @@ CONFIG_XEN_SYS_HYPERVISOR=y
# CONFIG_XEN_WDT is not set
CONFIG_XEN_XENBUS_FRONTEND=y
CONFIG_XFS_FS=y
-CONFIG_XFS_POSIX_ACL=y
CONFIG_XFS_RT=y
CONFIG_XOR_BLOCKS=y
CONFIG_XPS=y
diff --git a/target/linux/layerscape/armv8_64b/target.mk b/target/linux/layerscape/armv8_64b/target.mk
index c9a61701a9..d880afa7a3 100644
--- a/target/linux/layerscape/armv8_64b/target.mk
+++ b/target/linux/layerscape/armv8_64b/target.mk
@@ -5,6 +5,7 @@
ARCH:=aarch64
BOARDNAME:=ARMv8 64-bit based boards
KERNELNAME:=Image dtbs
+DEPENDS:=+@KERNEL_BTRFS_FS +@KERNEL_BTRFS_FS_POSIX_ACL
define Target/Description
Build firmware images for NXP Layerscape ARMv8 64-bit based boards.
diff --git a/target/linux/layerscape/image/armv7.mk b/target/linux/layerscape/image/armv7.mk
index 916f92eacf..6812d94e1f 100644
--- a/target/linux/layerscape/image/armv7.mk
+++ b/target/linux/layerscape/image/armv7.mk
@@ -6,11 +6,7 @@ define Device/Default
PROFILES := Default
FILESYSTEMS := squashfs
IMAGES := firmware.bin sysupgrade.bin
-ifdef CONFIG_LINUX_6_1
- DEVICE_DTS_DIR := $(DTS_DIR)
-else
DEVICE_DTS_DIR := $(DTS_DIR)/nxp/ls
-endif
KERNEL := kernel-bin | uImage none
KERNEL_INITRAMFS = kernel-bin | gzip | fit gzip $$(DEVICE_DTS_DIR)/$$(DEVICE_DTS).dtb
KERNEL_NAME := zImage
diff --git a/target/linux/layerscape/patches-6.1/302-arm64-dts-ls1012a-update-with-ppfe-support.patch b/target/linux/layerscape/patches-6.1/302-arm64-dts-ls1012a-update-with-ppfe-support.patch
deleted file mode 100644
index 70e624a2a9..0000000000
--- a/target/linux/layerscape/patches-6.1/302-arm64-dts-ls1012a-update-with-ppfe-support.patch
+++ /dev/null
@@ -1,288 +0,0 @@
-From 1bb35ff4ce33e65601c8d9c736be52e4aabd6252 Mon Sep 17 00:00:00 2001
-From: Calvin Johnson <calvin.johnson@nxp.com>
-Date: Sat, 16 Sep 2017 14:20:23 +0530
-Subject: [PATCH] arm64: dts: freescale: ls1012a: update with ppfe support
-
-Update ls1012a dtsi and platform dts files with support for ppfe.
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-Signed-off-by: Anjaneyulu Jagarlmudi <anji.jagarlmudi@nxp.com>
----
- .../boot/dts/freescale/fsl-ls1012a-frdm.dts | 43 +++++++++++++++++
- .../boot/dts/freescale/fsl-ls1012a-frwy.dts | 43 +++++++++++++++++
- .../boot/dts/freescale/fsl-ls1012a-qds.dts | 43 +++++++++++++++++
- .../boot/dts/freescale/fsl-ls1012a-rdb.dts | 47 +++++++++++++++++++
- .../arm64/boot/dts/freescale/fsl-ls1012a.dtsi | 29 ++++++++++++
- 5 files changed, 205 insertions(+)
-
---- a/arch/arm64/boot/dts/freescale/fsl-ls1012a-frdm.dts
-+++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a-frdm.dts
-@@ -14,6 +14,11 @@
- model = "LS1012A Freedom Board";
- compatible = "fsl,ls1012a-frdm", "fsl,ls1012a";
-
-+ aliases {
-+ ethernet0 = &pfe_mac0;
-+ ethernet1 = &pfe_mac1;
-+ };
-+
- sys_mclk: clock-mclk {
- compatible = "fixed-clock";
- #clock-cells = <0>;
-@@ -95,6 +100,44 @@
- };
- };
-
-+&pfe {
-+ status = "okay";
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ pfe_mac0: ethernet@0 {
-+ compatible = "fsl,pfe-gemac-port";
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ reg = <0x0>; /* GEM_ID */
-+ fsl,gemac-bus-id = <0x0>; /* BUS_ID */
-+ fsl,gemac-phy-id = <0x2>; /* PHY_ID */
-+ fsl,mdio-mux-val = <0x0>;
-+ phy-mode = "sgmii";
-+ fsl,pfe-phy-if-flags = <0x0>;
-+
-+ mdio@0 {
-+ reg = <0x1>; /* enabled/disabled */
-+ };
-+ };
-+
-+ pfe_mac1: ethernet@1 {
-+ compatible = "fsl,pfe-gemac-port";
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ reg = <0x1>; /* GEM_ID */
-+ fsl,gemac-bus-id = <0x1>; /* BUS_ID */
-+ fsl,gemac-phy-id = <0x1>; /* PHY_ID */
-+ fsl,mdio-mux-val = <0x0>;
-+ phy-mode = "sgmii";
-+ fsl,pfe-phy-if-flags = <0x0>;
-+
-+ mdio@0 {
-+ reg = <0x0>; /* enabled/disabled */
-+ };
-+ };
-+};
-+
- &qspi {
- status = "okay";
-
---- a/arch/arm64/boot/dts/freescale/fsl-ls1012a-frwy.dts
-+++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a-frwy.dts
-@@ -14,6 +14,11 @@
- / {
- model = "LS1012A FRWY Board";
- compatible = "fsl,ls1012a-frwy", "fsl,ls1012a";
-+
-+ aliases {
-+ ethernet0 = &pfe_mac0;
-+ ethernet1 = &pfe_mac1;
-+ };
- };
-
- &duart0 {
-@@ -28,6 +33,44 @@
- status = "okay";
- };
-
-+&pfe {
-+ status = "okay";
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ pfe_mac0: ethernet@0 {
-+ compatible = "fsl,pfe-gemac-port";
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ reg = <0x0>; /* GEM_ID */
-+ fsl,gemac-bus-id = <0x0>; /* BUS_ID */
-+ fsl,gemac-phy-id = <0x2>; /* PHY_ID */
-+ fsl,mdio-mux-val = <0x0>;
-+ phy-mode = "sgmii";
-+ fsl,pfe-phy-if-flags = <0x0>;
-+
-+ mdio@0 {
-+ reg = <0x1>; /* enabled/disabled */
-+ };
-+ };
-+
-+ pfe_mac1: ethernet@1 {
-+ compatible = "fsl,pfe-gemac-port";
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ reg = <0x1>; /* GEM_ID */
-+ fsl,gemac-bus-id = <0x1>; /* BUS_ID */
-+ fsl,gemac-phy-id = <0x1>; /* PHY_ID */
-+ fsl,mdio-mux-val = <0x0>;
-+ phy-mode = "sgmii";
-+ fsl,pfe-phy-if-flags = <0x0>;
-+
-+ mdio@0 {
-+ reg = <0x0>; /* enabled/disabled */
-+ };
-+ };
-+};
-+
- &qspi {
- status = "okay";
-
---- a/arch/arm64/boot/dts/freescale/fsl-ls1012a-qds.dts
-+++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a-qds.dts
-@@ -18,6 +18,11 @@
- mmc1 = &esdhc1;
- };
-
-+ aliases {
-+ ethernet0 = &pfe_mac0;
-+ ethernet1 = &pfe_mac1;
-+ };
-+
- sys_mclk: clock-mclk {
- compatible = "fixed-clock";
- #clock-cells = <0>;
-@@ -132,6 +137,44 @@
- };
- };
- };
-+
-+&pfe {
-+ status = "okay";
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ pfe_mac0: ethernet@0 {
-+ compatible = "fsl,pfe-gemac-port";
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ reg = <0x0>; /* GEM_ID */
-+ fsl,gemac-bus-id = <0x0>; /* BUS_ID */
-+ fsl,gemac-phy-id = <0x1>; /* PHY_ID */
-+ fsl,mdio-mux-val = <0x2>;
-+ phy-mode = "sgmii-2500";
-+ fsl,pfe-phy-if-flags = <0x0>;
-+
-+ mdio@0 {
-+ reg = <0x1>; /* enabled/disabled */
-+ };
-+ };
-+
-+ pfe_mac1: ethernet@1 {
-+ compatible = "fsl,pfe-gemac-port";
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ reg = <0x1>; /* GEM_ID */
-+ fsl,gemac-bus-id = <0x1>; /* BUS_ID */
-+ fsl,gemac-phy-id = <0x2>; /* PHY_ID */
-+ fsl,mdio-mux-val = <0x3>;
-+ phy-mode = "sgmii-2500";
-+ fsl,pfe-phy-if-flags = <0x0>;
-+
-+ mdio@0 {
-+ reg = <0x0>; /* enabled/disabled */
-+ };
-+ };
-+};
-
- &qspi {
- status = "okay";
---- a/arch/arm64/boot/dts/freescale/fsl-ls1012a-rdb.dts
-+++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a-rdb.dts
-@@ -16,6 +16,8 @@
-
- aliases {
- serial0 = &duart0;
-+ ethernet0 = &pfe_mac0;
-+ ethernet1 = &pfe_mac1;
- mmc0 = &esdhc0;
- mmc1 = &esdhc1;
- };
-@@ -86,6 +88,44 @@
- };
- };
-
-+&pfe {
-+ status = "okay";
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ pfe_mac0: ethernet@0 {
-+ compatible = "fsl,pfe-gemac-port";
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ reg = <0x0>; /* GEM_ID */
-+ fsl,gemac-bus-id = <0x0>; /* BUS_ID */
-+ fsl,gemac-phy-id = <0x2>; /* PHY_ID */
-+ fsl,mdio-mux-val = <0x0>;
-+ phy-mode = "sgmii";
-+ fsl,pfe-phy-if-flags = <0x0>;
-+
-+ mdio@0 {
-+ reg = <0x1>; /* enabled/disabled */
-+ };
-+ };
-+
-+ pfe_mac1: ethernet@1 {
-+ compatible = "fsl,pfe-gemac-port";
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ reg = <0x1>; /* GEM_ID */
-+ fsl,gemac-bus-id = < 0x1 >; /* BUS_ID */
-+ fsl,gemac-phy-id = < 0x1 >; /* PHY_ID */
-+ fsl,mdio-mux-val = <0x0>;
-+ phy-mode = "rgmii-txid";
-+ fsl,pfe-phy-if-flags = <0x0>;
-+
-+ mdio@0 {
-+ reg = <0x0>; /* enabled/disabled */
-+ };
-+ };
-+};
-+
- &qspi {
- status = "okay";
-
---- a/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi
-+++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi
-@@ -568,6 +568,35 @@
- };
- };
-
-+ reserved-memory {
-+ #address-cells = <2>;
-+ #size-cells = <2>;
-+ ranges;
-+
-+ pfe_reserved: packetbuffer@83400000 {
-+ reg = <0 0x83400000 0 0xc00000>;
-+ };
-+ };
-+
-+ pfe: pfe@04000000 {
-+ compatible = "fsl,pfe";
-+ reg = <0x0 0x04000000 0x0 0xc00000>, /* AXI 16M */
-+ <0x0 0x83400000 0x0 0xc00000>; /* PFE DDR 12M */
-+ reg-names = "pfe", "pfe-ddr";
-+ fsl,pfe-num-interfaces = <0x2>;
-+ interrupts = <0 172 0x4>, /* HIF interrupt */
-+ <0 173 0x4>, /*HIF_NOCPY interrupt */
-+ <0 174 0x4>; /* WoL interrupt */
-+ interrupt-names = "pfe_hif", "pfe_hif_nocpy", "pfe_wol";
-+ memory-region = <&pfe_reserved>;
-+ fsl,pfe-scfg = <&scfg 0>;
-+ fsl,rcpm-wakeup = <&rcpm 0xf0000020>;
-+ clocks = <&clockgen 4 0>;
-+ clock-names = "pfe";
-+
-+ status = "okay";
-+ };
-+
- firmware {
- optee {
- compatible = "linaro,optee-tz";
diff --git a/target/linux/layerscape/patches-6.1/303-arm64-dts-ls1012a-frdm-workaround-by-updating-qspi-f.patch b/target/linux/layerscape/patches-6.1/303-arm64-dts-ls1012a-frdm-workaround-by-updating-qspi-f.patch
deleted file mode 100644
index 5d19cb92dc..0000000000
--- a/target/linux/layerscape/patches-6.1/303-arm64-dts-ls1012a-frdm-workaround-by-updating-qspi-f.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From 9c5c18dbf8e1845d349ef7020f8af5bc9b56ed1f Mon Sep 17 00:00:00 2001
-From: Pawel Dembicki <paweldembicki@gmail.com>
-Date: Fri, 28 Sep 2022 17:14:32 +0200
-Subject: [PATCH] arm64: dts: ls1012a-frdm/qds: workaround by updating qspi flash to
- single mode
-
-Update rx and tx bus-width to 1 to use single mode to workaround ubifs
-issue found with double mode. (The same method as RDB board)
-
-Signed-off-by: Pawel Dembicki <paweldembicki@gmail.com>
----
- arch/arm64/boot/dts/freescale/fsl-ls1012a-frdm.dts | 4 ++--
- arch/arm64/boot/dts/freescale/fsl-ls1012a-qds.dts | 4 ++--
- 2 file changed, 4 insertions(+), 4 deletions(-)
-
---- a/arch/arm64/boot/dts/freescale/fsl-ls1012a-frdm.dts
-+++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a-frdm.dts
-@@ -148,8 +148,8 @@
- spi-max-frequency = <50000000>;
- m25p,fast-read;
- reg = <0>;
-- spi-rx-bus-width = <2>;
-- spi-tx-bus-width = <2>;
-+ spi-rx-bus-width = <1>;
-+ spi-tx-bus-width = <1>;
- };
- };
-
---- a/arch/arm64/boot/dts/freescale/fsl-ls1012a-qds.dts
-+++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a-qds.dts
-@@ -186,8 +186,8 @@
- spi-max-frequency = <50000000>;
- m25p,fast-read;
- reg = <0>;
-- spi-rx-bus-width = <2>;
-- spi-tx-bus-width = <2>;
-+ spi-rx-bus-width = <1>;
-+ spi-tx-bus-width = <1>;
- };
- };
-
diff --git a/target/linux/layerscape/patches-6.1/304-arm64-dts-ls1012a-rdb-workaround-by-updating-qspi-fl.patch b/target/linux/layerscape/patches-6.1/304-arm64-dts-ls1012a-rdb-workaround-by-updating-qspi-fl.patch
deleted file mode 100644
index 53cfd193b7..0000000000
--- a/target/linux/layerscape/patches-6.1/304-arm64-dts-ls1012a-rdb-workaround-by-updating-qspi-fl.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From 9c5c18dbf8e1845d349ef7020f8af5bc9b56ed1f Mon Sep 17 00:00:00 2001
-From: Kuldeep Singh <kuldeep.singh@nxp.com>
-Date: Tue, 7 Jan 2020 17:14:32 +0530
-Subject: [PATCH] arm64: dts: ls1012a-rdb: workaround by updating qspi flash to
- single mode
-
-Update rx and tx bus-width to 1 to use single mode to workaround ubifs
-issue found with double mode.
-
-[ Leo: Local workaround ]
-
-Signed-off-by: Kuldeep Singh <kuldeep.singh@nxp.com>
----
- arch/arm64/boot/dts/freescale/fsl-ls1012a-rdb.dts | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/arch/arm64/boot/dts/freescale/fsl-ls1012a-rdb.dts
-+++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a-rdb.dts
-@@ -136,8 +136,8 @@
- spi-max-frequency = <50000000>;
- m25p,fast-read;
- reg = <0>;
-- spi-rx-bus-width = <2>;
-- spi-tx-bus-width = <2>;
-+ spi-rx-bus-width = <1>;
-+ spi-tx-bus-width = <1>;
- };
- };
-
diff --git a/target/linux/layerscape/patches-6.1/305-arm64-dts-ls1046a-rdb-Update-qspi-spi-rx-bus-width-t.patch b/target/linux/layerscape/patches-6.1/305-arm64-dts-ls1046a-rdb-Update-qspi-spi-rx-bus-width-t.patch
deleted file mode 100644
index 9bc4e2b520..0000000000
--- a/target/linux/layerscape/patches-6.1/305-arm64-dts-ls1046a-rdb-Update-qspi-spi-rx-bus-width-t.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From 38093ebbf25eb60a1aa863f46118a68a0300c56e Mon Sep 17 00:00:00 2001
-From: Kuldeep Singh <kuldeep.singh@nxp.com>
-Date: Fri, 3 Jan 2020 14:49:07 +0530
-Subject: [PATCH] arm64: dts: ls1046a-rdb: Update qspi spi-rx-bus-width to 1
-
-Update rx width from quad mode to single mode as a workaround.
-
-[Leo: Local workaround ]
-
-Signed-off-by: Kuldeep Singh <kuldeep.singh@nxp.com>
----
- arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts
-+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts
-@@ -104,7 +104,7 @@
- #address-cells = <1>;
- #size-cells = <1>;
- spi-max-frequency = <50000000>;
-- spi-rx-bus-width = <4>;
-+ spi-rx-bus-width = <1>;
- spi-tx-bus-width = <1>;
- reg = <0>;
- };
-@@ -114,7 +114,7 @@
- #address-cells = <1>;
- #size-cells = <1>;
- spi-max-frequency = <50000000>;
-- spi-rx-bus-width = <4>;
-+ spi-rx-bus-width = <1>;
- spi-tx-bus-width = <1>;
- reg = <1>;
- };
diff --git a/target/linux/layerscape/patches-6.1/400-LF-20-3-mtd-spi-nor-Use-1-bit-mode-of-spansion-s25fs.patch b/target/linux/layerscape/patches-6.1/400-LF-20-3-mtd-spi-nor-Use-1-bit-mode-of-spansion-s25fs.patch
deleted file mode 100644
index b06c0f8133..0000000000
--- a/target/linux/layerscape/patches-6.1/400-LF-20-3-mtd-spi-nor-Use-1-bit-mode-of-spansion-s25fs.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From 20b1193c8c1d81a8d44ae36e579f70e6fbab45b9 Mon Sep 17 00:00:00 2001
-From: Han Xu <han.xu@nxp.com>
-Date: Tue, 14 Apr 2020 11:58:44 -0500
-Subject: [PATCH] LF-20-3 mtd: spi-nor: Use 1 bit mode of spansion(s25fs512s)
- flash
-
-This is a workaround patch which uses only single bit mode of s25fs512s
-flash
-
-Signed-off-by: Han Xu <han.xu@nxp.com>
-Signed-off-by: Kuldeep Singh <kuldeep.singh@nxp.com>
----
- drivers/mtd/spi-nor/spansion.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/mtd/spi-nor/spansion.c
-+++ b/drivers/mtd/spi-nor/spansion.c
-@@ -398,8 +398,8 @@ static const struct flash_info spansion_
- MFR_FLAGS(USE_CLSR)
- },
- { "s25fs512s", INFO6(0x010220, 0x4d0081, 256 * 1024, 256)
-- NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
- MFR_FLAGS(USE_CLSR)
-+ FIXUP_FLAGS(SPI_NOR_4B_OPCODES)
- .fixups = &s25fs_s_nor_fixups, },
- { "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024, 64) },
- { "s25sl12801", INFO(0x012018, 0x0301, 64 * 1024, 256) },
diff --git a/target/linux/layerscape/patches-6.1/701-staging-add-fsl_ppfe-driver.patch b/target/linux/layerscape/patches-6.1/701-staging-add-fsl_ppfe-driver.patch
deleted file mode 100644
index a52ac6201f..0000000000
--- a/target/linux/layerscape/patches-6.1/701-staging-add-fsl_ppfe-driver.patch
+++ /dev/null
@@ -1,11808 +0,0 @@
-From 4bb50554937246443767e89d32e54df7a12396ca Mon Sep 17 00:00:00 2001
-From: Calvin Johnson <calvin.johnson@nxp.com>
-Date: Sat, 16 Sep 2017 07:05:49 +0530
-Subject: [PATCH] staging: add fsl_ppfe driver
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This is squash of all commits with ppfe driver taken from NXP 6.1 tree:
-https://github.com/nxp-qoriq/linux/tree/lf-6.1.y
-
-List of original commits:
-
-net: fsl_ppfe: dts binding for ppfe
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-Signed-off-by: Anjaneyulu Jagarlmudi <anji.jagarlmudi@nxp.com>
-
-staging: fsl_ppfe/eth: header files for pfe driver
-
-This patch has all pfe header files.
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-Signed-off-by: Anjaneyulu Jagarlmudi <anji.jagarlmudi@nxp.com>
-
-staging: fsl_ppfe/eth: introduce pfe driver
-
- This patch introduces Linux support for NXP's LS1012A Packet
-Forwarding Engine (pfe_eth). LS1012A uses hardware packet forwarding
-engine to provide high performance Ethernet interfaces. The device
-includes two Ethernet ports.
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-Signed-off-by: Anjaneyulu Jagarlmudi <anji.jagarlmudi@nxp.com>
-
-staging: fsl_ppfe/eth: fix RGMII tx delay issue
-
-Recently logic to enable RGMII tx delay was changed by
-below patch.
-
-https://patchwork.kernel.org/patch/9447581/
-
-Based on the patch, appropriate change is made in PFE driver.
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-Signed-off-by: Anjaneyulu Jagarlmudi <anji.jagarlmudi@nxp.com>
-
-staging: fsl_ppfe/eth: remove unused functions
-
-Remove unused functions hif_xmit_pkt & hif_lib_xmit_pkt.
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-
-staging: fsl_ppfe/eth: fix read/write/ack idx issue
-
-While fixing checkpatch errors some of the index increments
-were commented out. They are enabled.
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-
-staging: fsl_ppfe/eth: Make phy_ethtool_ksettings_get return void
-
-Make return value void since function never return meaningful value
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-
-staging: fsl_ppfe/eth: add function to update tmu credits
-
-__hif_lib_update_credit function is used to update the tmu credits.
-If tx_qos is set, tmu credit is updated based on the number of packets
-transmitted by tmu.
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-Signed-off-by: Anjaneyulu Jagarlmudi <anji.jagarlmudi@nxp.com>
-
-staging: fsl_ppfe/eth: Avoid packet drop at TMU queues
-
-Added flow control between TMU queues and PFE Linux driver,
-based on TMU credits availability.
-Added tx_qos module parameter to control this behavior.
-Use queue-0 as default queue to transmit packets.
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-Signed-off-by: Akhila Kavi <akhila.kavi@nxp.com>
-Signed-off-by: Anjaneyulu Jagarlmudi <anji.jagarlmudi@nxp.com>
-
-staging: fsl_ppfe/eth: Enable PFE in clause 45 mode
-
-when we opearate in clause 45 mode, we need to call
-the function get_phy_device() with its 3rd argument as
-"true" and then the resultant phy device needs to be
-register with phy layer via phy_device_register()
-
-Signed-off-by: Bhaskar Upadhaya <Bhaskar.Upadhaya@nxp.com>
-
-staging: fsl_ppfe/eth: Disable autonegotiation for 2.5G SGMII
-
-PCS initialization sequence for 2.5G SGMII interface governs
-auto negotiation to be in disabled mode
-
-Signed-off-by: Bhaskar Upadhaya <Bhaskar.Upadhaya@nxp.com>
-
-staging: fsl_ppfe/eth: calculate PFE_PKT_SIZE with SKB_DATA_ALIGN
-
-pfe packet size was calculated without considering skb data alignment
-and this resulted in jumbo frames crashing kernel when the
-cacheline size increased from 64 to 128 bytes with
-commit 97303480753e ("arm64: Increase the max granular size").
-
-Modify pfe packet size caclulation to include skb data alignment of
-sizeof(struct skb_shared_info).
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-
-staging: fsl_ppfe/eth: support for userspace networking
-
-This patch adds the userspace mode support to fsl_ppfe network driver.
-In the new mode, basic hardware initialization is performed in kernel, while
-the datapath and HIF handling is the responsibility of the userspace.
-
-The new command line parameter is added to initialize the ppfe module
-in userspace mode. By default the module remains in kernelspace networking
-mode.
-To enable userspace mode, use "insmod pfe.ko us=1"
-
-Signed-off-by: Akhil Goyal <akhil.goyal@nxp.com>
-Signed-off-by: Gagandeep Singh <g.singh@nxp.com>
-
-staging: fsl_ppfe/eth: unregister netdev after pfe_phy_exit
-
-rmmod pfe.ko throws below warning:
-
-kernfs: can not remove 'phydev', no directory
-------------[ cut here ]------------
-WARNING: CPU: 0 PID: 2230 at fs/kernfs/dir.c:1481
-kernfs_remove_by_name_ns+0x90/0xa0
-
-This is caused when the unregistered netdev structure is accessed to
-disconnect phy.
-
-Resolve the issue by unregistering netdev after disconnecting phy.
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-
-staging: fsl_ppfe/eth: HW parse results for DPDK
-
-HW Parse results are included in the packet headroom.
-Length and Offset calculation now accommodates parse info size.
-
-Signed-off-by: Archana Madhavan <archana.madhavan@nxp.com>
-
-staging: fsl_ppfe/eth: reorganize pfe_netdev_ops
-
-Reorganize members of struct pfe_netdev_ops to match with the order
-of members in struct net_device_ops defined in include/linux/netdevice.h
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-
-staging: fsl_ppfe/eth: use mask for rx max frame len
-
-Define and use PFE_RCR_MAX_FL_MASK to properly set Rx max frame
-length of MAC Receive Control Register.
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-
-staging: fsl_ppfe/eth: define pfe ndo_change_mtu function
-
-Define ndo_change_mtu function for pfe. This sets the max Rx frame
-length to the new mtu.
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-
-staging: fsl_ppfe/eth: remove jumbo frame enable from gemac init
-
-MAC Receive Control Register was configured to allow jumbo frames.
-This is removed as jumbo frames can be supported anytime by changing
-mtu which will in turn modify MAX_FL field of MAC RCR.
-Jumbo frames caused pfe to hang on LS1012A rev 1.0 Silicon due to
-erratum A-010897.
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-
-staging: fsl_ppfe/eth: disable CRC removal
-
-Disable CRC removal from the packet, so that packets are forwarded
-as is to Linux.
-CRC configuration in MAC will be reflected in the packet received
-to Linux.
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-
-staging: fsl_ppfe/eth: handle ls1012a errata_a010897
-
-On LS1012A rev 1.0, Jumbo frames are not supported as it causes
-the PFE controller to hang. A reset of the entire chip is required
-to resume normal operation.
-
-To handle this errata, frames with length > 1900 are truncated for
-rev 1.0 of LS1012A.
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-
-staging: fsl_ppfe/eth: replace magic numbers
-
-Replace magic numbers and some cosmetic changes.
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-
-staging: fsl_ppfe/eth: resolve indentation warning
-
-Resolve the following indentation warning:
-
-drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c:
-In function ‘pfe_get_gemac_if_proprties’:
-drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c:96:2:
-warning: this ‘else’ clause does not guard...
-[-Wmisleading-indentation]
- else
- ^~~~
-drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c:98:3:
-note: ...this statement, but the latter is misleadingly indented as
-if it were guarded by the ‘else’
- pdata->ls1012a_eth_pdata[port].mdio_muxval = phy_id;
- ^~~~~
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-
-staging: fsl_ppfe/eth: add fixed-link support
-
-In cases where MAC is not connected to a normal MDIO-managed PHY
-device, and instead to a switch, it is configured as a "fixed-link".
-Code to handle this scenario is added here.
-
-phy_node in the dtb is checked to identify a fixed-link.
-On identification of a fixed-link, it is registered and connected.
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-
-staging: fsl_ppfe: add support for a char dev for link status
-
-Read and IOCTL support is added. Application would need to open,
-read/ioctl the /dev/pfe_us_cdev device.
-select is pending as it requires a wait_queue.
-
-Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-
-staging: fsl_ppfe: enable hif event from userspace
-
-HIF interrupts are enabled using ioctl from user space,
-and epoll wait from user space wakes up when there is an HIF
-interrupt.
-
-Signed-off-by: Akhil Goyal <akhil.goyal@nxp.com>
-
-staging: fsl_ppfe: performance tuning for user space
-
-interrupt coalescing of 100 usec is added.
-
-Signed-off-by: Akhil Goyal <akhil.goyal@nxp.com>
-Signed-off-by: Sachin Saxena <sachin.saxena@nxp.com>
-
-staging: fsl_ppfe/eth: Update to use SPDX identifiers
-
-Replace license text with corresponding SPDX identifiers and update the
-format of existing SPDX identifiers to follow the new guideline
-Documentation/process/license-rules.rst.
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-
-staging: fsl_ppfe/eth: misc clean up
-
-- remove redundant hwfeature init
-- remove unused vars from ls1012a_eth_platform_data
-- To handle ls1012a errata_a010897, PPFE driver requires GUTS driver
-to be compiled in. Select FSL_GUTS when PPFE driver is compiled.
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-
-staging: fsl_ppfe/eth: reorganize platform phy parameters
-
-- Use "phy-handle" and of_* functions to get phy node and fixed-link
-parameters
-
-- Reorganize phy parameters and initialize them only if phy-handle
-or fixed-link is defined in the dtb.
-
-- correct typo pfe_get_gemac_if_proprties to pfe_get_gemac_if_properties
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-
-staging: fsl_ppfe/eth: support single interface initialization
-
-- arrange members of struct mii_bus in sequence matching phy.h
-- if mdio node is defined, use of_mdiobus_register to register
- child nodes (phy devices) available on the mdio bus.
-- remove of_phy_register_fixed_link from pfe_phy_init as it is being
- handled in pfe_get_gemac_if_properties
-- remove mdio enabled check
-- skip phy init, if no PHY or fixed-link
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-
-net: fsl_ppfe: update dts properties for phy
-
-Use commonly used phy-handle property and mdio subnode to handle
-phy properties.
-
-Deprecate bindings fsl,gemac-phy-id & fsl,pfe-phy-if-flags.
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-
-staging: fsl_ppfe/eth: remove unused code
-
-- remove gemac-bus-id related code that is unused.
-- remove unused prototype gemac_set_mdc_div.
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-
-staging: fsl_ppfe/eth: separate mdio init from mac init
-
-- separate mdio initialization from mac initialization
-- Define pfe_mdio_priv_s structure to hold mii_bus structure and other
- related data.
-- Modify functions to work with the separted mdio init model.
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-
-staging: fsl_ppfe/eth: adapt to link mode based phydev changes
-
-Setting link mode bits have changed with the integration of
-commit (3c1bcc8 net: ethernet: Convert phydev advertize and
-supported from u32 to link mode). Adapt to the new method of
-setting and clearing the link mode bits.
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-
-staging: fsl_ppfe/eth: use generic soc_device infra instead of fsl_guts_get_svr()
-
-Commit ("soc: fsl: guts: make fsl_guts_get_svr() static") has
-made fsl_guts_get_svr() static and hence use generic soc_device
-infrastructure to check SoC revision.
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-
-staging: fsl_ppfe/eth: use memremap() to map RAM area used by PFE
-
-RAM area used by PFE should be mapped using memremap() instead of
-directly traslating physical addr to virtual. This will ensure proper
-checks are done before the area is used.
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-
-staging: fsl_ppfe/eth: remove 'fallback' argument from dev->ndo_select_queue()
-
-To be consistent with upstream API change.
-
-Signed-off-by: Li Yang <leoyang.li@nxp.com>
-
-staging: fsl_ppfe/eth: prefix header search paths with $(srctree)/
-
-Currently, the rules for configuring search paths in Kbuild have
-changed: https://lkml.org/lkml/2019/5/13/37
-
-This will lead the below error:
-
-fatal error: pfe/pfe.h: No such file or directory
-
-Fix it by adding $(srctree)/ prefix to the search paths.
-
-Signed-off-by: Ting Liu <ting.liu@nxp.com>
-
-staging: fsl_ppfe/eth: add pfe support to Kconfig and Makefile
-
-Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
-[ Aisheng: fix minor conflict due to removed VBOXSF_FS ]
-Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
-
-staging: fsl_ppfe/eth: Disable termination of CRC fwd.
-
-LS1012A MAC PCS block has an erratum that is seen with specific PHY AR803x.
-The issue is triggered by the (spec-compliant) operation of the AR803x PHY
-on the LS1012A-FRWY board.Due to this, good FCS packet is reported as error
-packet by MAC, so for these error packets FCS should be validated and
-discard only real error packets in PFE Rx packet path.
-
-Signed-off-by: Nagesh Koneti <koneti.nagesh@nxp.com>
-Signed-off-by: Nagesh Koneti <“koneti.nagesh@nxp.com”>
-
-net: ppfe: Cope with of_get_phy_mode() API change
-
-Signed-off-by: Li Yang <leoyang.li@nxp.com>
-
-staging: fsl_ppfe/eth: Enhance error checking in platform probe
-
-Fix the kernel crash when MAC addr is not passed in dtb.
-
-Signed-off-by: Anji Jagarlmudi <anji.jagarlmudi@nxp.com>
-
-staging: fsl_ppfe/eth: reject unsupported coalescing params
-
-Set ethtool_ops->supported_coalesce_params to let
-the core reject unsupported coalescing parameters.
-
-Signed-off-by: Anji Jagarlmudi <anji.jagarlmudi@nxp.com>
-
-staging: fsl_ppfe/eth:check "reg" property before pfe_get_gemac_if_properties()
-
-It has been observed that the function pfe_get_gemac_if_properties() is
-been called blindly for the next two child nodes. There might be some
-cases where it may go wrong and that lead to missing interfaces.
-with these changes it is ensured thats not the case.
-
-Signed-off-by: Chaitanya Sakinam <chaitanya.sakinam@nxp.com>
-Signed-off-by: Anji J <anji.jagarlmudi@nxp.com>
-
-staging: fsl_ppfe/eth: "struct firmware" dereference is reduced in many functions
-
-firmware structure's data variable is the actual elf data. It has been
-dereferenced in multiple functions and this has been reduced.
-
-Signed-off-by: Chaitanya Sakinam <chaitanya.sakinam@nxp.com>
-Signed-off-by: Anji J <anji.jagarlmudi@nxp.com>
-
-staging: fsl_ppfe/eth: LF-27 load pfe binaries from FDT
-
-FDT prepared in uboot now has pfe firmware part of it.
-These changes will read the firmware by default from it and tries to load
-the elf into the PFE PEs. This help build the pfe driver pasrt of kernel.
-
-Signed-off-by: Chaitanya Sakinam <chaitanya.sakinam@nxp.com>
-Signed-off-by: Anji J <anji.jagarlmudi@nxp.com>
-
-staging: fsl_ppfe/eth: proper handling for RGMII delay mode
-
-The correct setting for the RGMII ports on LS1012ARDB is to
-enable delay on both Tx and Rx. So the phy mode to be matched
-is PHY_INTERFACE_MODE_RGMII_ID.
-
-Signed-off-by: Chaitanya Sakinam <chaitanya.sakinam@nxp.com>
-Signed-off-by: Anji Jagarlmudi <anji.jagarlmudi@nxp.com>
-
-LF-1762-2 staging: fsl_ppfe: replace '---help---' in Kconfig files with 'help'
-
-Update Kconfig to cope with upstream change
-commit 84af7a6194e4 ("checkpatch: kconfig: prefer 'help' over
-'---help---'").
-
-Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
-
-staging: fsl_ppfe/eth: Nesting level does not match indentation
-
-corrected nesting level
-LF-1661 and Coverity CID: 8879316
-
-Signed-off-by: Chaitanya Sakinam <chaitanya.sakinam@nxp.com>
-
-staging: fsl_ppfe/eth: Initialized scalar variable
-
-Proper initialization of scalar variable
-LF-1657 and Coverity CID: 3335133
-
-Signed-off-by: Chaitanya Sakinam <chaitanya.sakinam@nxp.com>
-
-staging: fsl_ppfe/eth: misspelt variable name
-
-variable name corrected
-LF-1656 and Coverity CID: 3335119
-
-Signed-off-by: Chaitanya Sakinam <chaitanya.sakinam@nxp.com>
-
-staging: fsl_ppfe/eth: Avoiding out-of-bound writes
-
-avoid out-of-bound writes with proper error handling
-LF-1654, LF-1652 and Coverity CID: 3335106, 3335090
-
-Signed-off-by: Chaitanya Sakinam <chaitanya.sakinam@nxp.com>
-
-staging: fsl_ppfe/eth: Initializing scalar variable
-
-proper initialization of scalar variable.
-LF-1653 and Coverity CID: 3335101
-
-Signed-off-by: Chaitanya Sakinam <chaitanya.sakinam@nxp.com>
-
-staging: fsl_ppfe/eth: checking return value
-
-proper checks added and handled for return value.
-LF-1644 and Coverity CID: 241888
-
-Signed-off-by: Chaitanya Sakinam <chaitanya.sakinam@nxp.com>
-
-staging: fsl_ppfe/eth: Avoid out-of-bound access
-
-proper handling to avoid out-of-bound access
-LF-1642, LF-1641 and Coverity CID: 240910, 240891
-
-Signed-off-by: Chaitanya Sakinam <chaitanya.sakinam@nxp.com>
-
-staging: fsl_ppfe/eth: Avoiding out-of-bound writes
-
-avoid out-of-bound writes with proper error handling
-LF-1654, LF-1652 and Coverity CID: 3335106, 3335090
-
-Signed-off-by: Chaitanya Sakinam <chaitanya.sakinam@nxp.com>
-
-staging: fsl_ppfe/eth: return value init in error case
-
-proper err return in error case.
-LF-1806 and Coverity CID: 10468592
-
-Signed-off-by: Chaitanya Sakinam <chaitanya.sakinam@nxp.com>
-
-staging: fsl_ppfe/eth: Avoid recursion in header inclusion
-
-Avoiding header inclusions that are not necessary and also that are
-causing header inclusion recursion.
-
-LF-2102 and Coverity CID: 240838
-
-Signed-off-by: Chaitanya Sakinam <chaitanya.sakinam@nxp.com>
-
-staging: fsl_ppfe/eth: Avoiding return value overwrite
-
-avoid return value overwrite at the end of function.
-LF-2136, LF-2137 and Coverity CID: 8879341, 8879364
-
-Signed-off-by: Chaitanya Sakinam <chaitanya.sakinam@nxp.com>
-
-staging: fsl_ppfe/eth: LF-27 enabling PFE firmware load from FDT
-
-The macro, "LOAD_PFEFIRMWARE_FROM_FILESYSTEM" is been disabled to load
-the firmware from FDT by default. Enabling the macro will load the
-firmware from filesystem.
-
-Also, the Makefile is now tuned to build pfe as per the config option
-
-Signed-off-by: Chaitanya Sakinam <chaitanya.sakinam@nxp.com>
-
-staging: fsl_ppfe/eth: Ethtool stats correction for IEEE_rx_drop counter
-
-Due to carrier extended bug the phy counter IEEE_rx_drop counter is
-incremented some times and phy reports the packet has crc error.
-Because of this PFE revalidates all the packets that are marked crc
-error by phy. Now, the counter phy reports is till bogus and this
-patch decrements the counter by pfe revalidated (and are crc ok)
-counter amount.
-
-Signed-off-by: Chaitanya Sakinam <chaitanya.sakinam@nxp.com>
-
-staging: fsl_ppfe/eth: PFE firmware load enhancements
-
-PFE driver enhancements to load the PE firmware from filesystem
-when the firmware is not found in FDT.
-
-Signed-off-by: Chaitanya Sakinam <chaitanya.sakinam@nxp.com>
-
-staging: fsl_ppfe: deal with upstream API change of of_get_mac_address()
-
-Uptream commit 83216e398 changed the of_get_mac_address() API, update
-the user accordingly.
-
-Signed-off-by: Li Yang <leoyang.li@nxp.com>
-
-staging: fsl_ppfe: update coalesce setting uAPI usage
-
-API changed since:
-f3ccfda19319 ("ethtool: extend coalesce setting uAPI with CQE mode")
-
-Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
-
-staging: fsl_ppfe: Addressed build warnings
-
-Signed-off-by: Chaitanya Sakinam <chaitanya.sakinam@nxp.com>
-
-staging: fsl_ppfe: Addressed build warnings
-
-Signed-off-by: Chaitanya Sakinam <chaitanya.sakinam@nxp.com>
-
-Signed-off-by: Pawel Dembicki <paweldembicki@gmail.com>
----
- .../devicetree/bindings/net/fsl_ppfe/pfe.txt | 199 ++
- MAINTAINERS | 8 +
- drivers/staging/Kconfig | 2 +
- drivers/staging/Makefile | 1 +
- drivers/staging/fsl_ppfe/Kconfig | 21 +
- drivers/staging/fsl_ppfe/Makefile | 20 +
- drivers/staging/fsl_ppfe/TODO | 2 +
- drivers/staging/fsl_ppfe/include/pfe/cbus.h | 78 +
- .../staging/fsl_ppfe/include/pfe/cbus/bmu.h | 55 +
- .../fsl_ppfe/include/pfe/cbus/class_csr.h | 289 ++
- .../fsl_ppfe/include/pfe/cbus/emac_mtip.h | 242 ++
- .../staging/fsl_ppfe/include/pfe/cbus/gpi.h | 86 +
- .../staging/fsl_ppfe/include/pfe/cbus/hif.h | 100 +
- .../fsl_ppfe/include/pfe/cbus/hif_nocpy.h | 50 +
- .../fsl_ppfe/include/pfe/cbus/tmu_csr.h | 168 ++
- .../fsl_ppfe/include/pfe/cbus/util_csr.h | 61 +
- drivers/staging/fsl_ppfe/include/pfe/pfe.h | 372 +++
- drivers/staging/fsl_ppfe/pfe_cdev.c | 258 ++
- drivers/staging/fsl_ppfe/pfe_cdev.h | 41 +
- drivers/staging/fsl_ppfe/pfe_ctrl.c | 226 ++
- drivers/staging/fsl_ppfe/pfe_ctrl.h | 100 +
- drivers/staging/fsl_ppfe/pfe_debugfs.c | 99 +
- drivers/staging/fsl_ppfe/pfe_debugfs.h | 13 +
- drivers/staging/fsl_ppfe/pfe_eth.c | 2588 +++++++++++++++++
- drivers/staging/fsl_ppfe/pfe_eth.h | 175 ++
- drivers/staging/fsl_ppfe/pfe_firmware.c | 398 +++
- drivers/staging/fsl_ppfe/pfe_firmware.h | 21 +
- drivers/staging/fsl_ppfe/pfe_hal.c | 1517 ++++++++++
- drivers/staging/fsl_ppfe/pfe_hif.c | 1063 +++++++
- drivers/staging/fsl_ppfe/pfe_hif.h | 199 ++
- drivers/staging/fsl_ppfe/pfe_hif_lib.c | 628 ++++
- drivers/staging/fsl_ppfe/pfe_hif_lib.h | 229 ++
- drivers/staging/fsl_ppfe/pfe_hw.c | 164 ++
- drivers/staging/fsl_ppfe/pfe_hw.h | 15 +
- .../staging/fsl_ppfe/pfe_ls1012a_platform.c | 383 +++
- drivers/staging/fsl_ppfe/pfe_mod.c | 158 +
- drivers/staging/fsl_ppfe/pfe_mod.h | 103 +
- drivers/staging/fsl_ppfe/pfe_perfmon.h | 26 +
- drivers/staging/fsl_ppfe/pfe_sysfs.c | 840 ++++++
- drivers/staging/fsl_ppfe/pfe_sysfs.h | 17 +
- 40 files changed, 11015 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/net/fsl_ppfe/pfe.txt
- create mode 100644 drivers/staging/fsl_ppfe/Kconfig
- create mode 100644 drivers/staging/fsl_ppfe/Makefile
- create mode 100644 drivers/staging/fsl_ppfe/TODO
- create mode 100644 drivers/staging/fsl_ppfe/include/pfe/cbus.h
- create mode 100644 drivers/staging/fsl_ppfe/include/pfe/cbus/bmu.h
- create mode 100644 drivers/staging/fsl_ppfe/include/pfe/cbus/class_csr.h
- create mode 100644 drivers/staging/fsl_ppfe/include/pfe/cbus/emac_mtip.h
- create mode 100644 drivers/staging/fsl_ppfe/include/pfe/cbus/gpi.h
- create mode 100644 drivers/staging/fsl_ppfe/include/pfe/cbus/hif.h
- create mode 100644 drivers/staging/fsl_ppfe/include/pfe/cbus/hif_nocpy.h
- create mode 100644 drivers/staging/fsl_ppfe/include/pfe/cbus/tmu_csr.h
- create mode 100644 drivers/staging/fsl_ppfe/include/pfe/cbus/util_csr.h
- create mode 100644 drivers/staging/fsl_ppfe/include/pfe/pfe.h
- create mode 100644 drivers/staging/fsl_ppfe/pfe_cdev.c
- create mode 100644 drivers/staging/fsl_ppfe/pfe_cdev.h
- create mode 100644 drivers/staging/fsl_ppfe/pfe_ctrl.c
- create mode 100644 drivers/staging/fsl_ppfe/pfe_ctrl.h
- create mode 100644 drivers/staging/fsl_ppfe/pfe_debugfs.c
- create mode 100644 drivers/staging/fsl_ppfe/pfe_debugfs.h
- create mode 100644 drivers/staging/fsl_ppfe/pfe_eth.c
- create mode 100644 drivers/staging/fsl_ppfe/pfe_eth.h
- create mode 100644 drivers/staging/fsl_ppfe/pfe_firmware.c
- create mode 100644 drivers/staging/fsl_ppfe/pfe_firmware.h
- create mode 100644 drivers/staging/fsl_ppfe/pfe_hal.c
- create mode 100644 drivers/staging/fsl_ppfe/pfe_hif.c
- create mode 100644 drivers/staging/fsl_ppfe/pfe_hif.h
- create mode 100644 drivers/staging/fsl_ppfe/pfe_hif_lib.c
- create mode 100644 drivers/staging/fsl_ppfe/pfe_hif_lib.h
- create mode 100644 drivers/staging/fsl_ppfe/pfe_hw.c
- create mode 100644 drivers/staging/fsl_ppfe/pfe_hw.h
- create mode 100644 drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c
- create mode 100644 drivers/staging/fsl_ppfe/pfe_mod.c
- create mode 100644 drivers/staging/fsl_ppfe/pfe_mod.h
- create mode 100644 drivers/staging/fsl_ppfe/pfe_perfmon.h
- create mode 100644 drivers/staging/fsl_ppfe/pfe_sysfs.c
- create mode 100644 drivers/staging/fsl_ppfe/pfe_sysfs.h
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/net/fsl_ppfe/pfe.txt
-@@ -0,0 +1,199 @@
-+=============================================================================
-+NXP Programmable Packet Forwarding Engine Device Bindings
-+
-+CONTENTS
-+ - PFE Node
-+ - Ethernet Node
-+
-+=============================================================================
-+PFE Node
-+
-+DESCRIPTION
-+
-+PFE Node has all the properties associated with Packet Forwarding Engine block.
-+
-+PROPERTIES
-+
-+- compatible
-+ Usage: required
-+ Value type: <stringlist>
-+ Definition: Must include "fsl,pfe"
-+
-+- reg
-+ Usage: required
-+ Value type: <prop-encoded-array>
-+ Definition: A standard property.
-+ Specifies the offset of the following registers:
-+ - PFE configuration registers
-+ - DDR memory used by PFE
-+
-+- fsl,pfe-num-interfaces
-+ Usage: required
-+ Value type: <u32>
-+ Definition: Must be present. Value can be either one or two.
-+
-+- interrupts
-+ Usage: required
-+ Value type: <prop-encoded-array>
-+ Definition: Three interrupts are specified in this property.
-+ - HIF interrupt
-+ - HIF NO COPY interrupt
-+ - Wake On LAN interrupt
-+
-+- interrupt-names
-+ Usage: required
-+ Value type: <stringlist>
-+ Definition: Following strings are defined for the 3 interrupts.
-+ "pfe_hif" - HIF interrupt
-+ "pfe_hif_nocpy" - HIF NO COPY interrupt
-+ "pfe_wol" - Wake On LAN interrupt
-+
-+- memory-region
-+ Usage: required
-+ Value type: <phandle>
-+ Definition: phandle to a node describing reserved memory used by pfe.
-+ Refer:- Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
-+
-+- fsl,pfe-scfg
-+ Usage: required
-+ Value type: <phandle>
-+ Definition: phandle for scfg.
-+
-+- fsl,rcpm-wakeup
-+ Usage: required
-+ Value type: <phandle>
-+ Definition: phandle for rcpm.
-+
-+- clocks
-+ Usage: required
-+ Value type: <phandle>
-+ Definition: phandle for clockgen.
-+
-+- clock-names
-+ Usage: required
-+ Value type: <string>
-+ Definition: phandle for clock name.
-+
-+EXAMPLE
-+
-+pfe: pfe@04000000 {
-+ compatible = "fsl,pfe";
-+ reg = <0x0 0x04000000 0x0 0xc00000>, /* AXI 16M */
-+ <0x0 0x83400000 0x0 0xc00000>; /* PFE DDR 12M */
-+ reg-names = "pfe", "pfe-ddr";
-+ fsl,pfe-num-interfaces = <0x2>;
-+ interrupts = <0 172 0x4>, /* HIF interrupt */
-+ <0 173 0x4>, /*HIF_NOCPY interrupt */
-+ <0 174 0x4>; /* WoL interrupt */
-+ interrupt-names = "pfe_hif", "pfe_hif_nocpy", "pfe_wol";
-+ memory-region = <&pfe_reserved>;
-+ fsl,pfe-scfg = <&scfg 0>;
-+ fsl,rcpm-wakeup = <&rcpm 0xf0000020>;
-+ clocks = <&clockgen 4 0>;
-+ clock-names = "pfe";
-+
-+ status = "okay";
-+ pfe_mac0: ethernet@0 {
-+ };
-+
-+ pfe_mac1: ethernet@1 {
-+ };
-+};
-+
-+=============================================================================
-+Ethernet Node
-+
-+DESCRIPTION
-+
-+Ethernet Node has all the properties associated with PFE used by platforms to
-+connect to PHY:
-+
-+PROPERTIES
-+
-+- compatible
-+ Usage: required
-+ Value type: <stringlist>
-+ Definition: Must include "fsl,pfe-gemac-port"
-+
-+- reg
-+ Usage: required
-+ Value type: <prop-encoded-array>
-+ Definition: A standard property.
-+ Specifies the gemacid of the interface.
-+
-+- fsl,gemac-bus-id
-+ Usage: required
-+ Value type: <u32>
-+ Definition: Must be present. Value should be the id of the bus
-+ connected to gemac.
-+
-+- fsl,gemac-phy-id (deprecated binding)
-+ Usage: required
-+ Value type: <u32>
-+ Definition: This binding shouldn't be used with new platforms.
-+ Must be present. Value should be the id of the phy
-+ connected to gemac.
-+
-+- fsl,mdio-mux-val
-+ Usage: required
-+ Value type: <u32>
-+ Definition: Must be present. Value can be either 0 or 2 or 3.
-+ This value is used to configure the mux to enable mdio.
-+
-+- phy-mode
-+ Usage: required
-+ Value type: <string>
-+ Definition: Must include "sgmii"
-+
-+- fsl,pfe-phy-if-flags (deprecated binding)
-+ Usage: required
-+ Value type: <u32>
-+ Definition: This binding shouldn't be used with new platforms.
-+ Must be present. Value should be 0 by default.
-+ If there is not phy connected, this need to be 1.
-+
-+- phy-handle
-+ Usage: optional
-+ Value type: <phandle>
-+ Definition: phandle to the PHY device connected to this device.
-+
-+- mdio : A required subnode which specifies the mdio bus in the PFE and used as
-+a container for phy nodes according to ../phy.txt.
-+
-+EXAMPLE
-+
-+ethernet@0 {
-+ compatible = "fsl,pfe-gemac-port";
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ reg = <0x0>; /* GEM_ID */
-+ fsl,gemac-bus-id = <0x0>; /* BUS_ID */
-+ fsl,mdio-mux-val = <0x0>;
-+ phy-mode = "sgmii";
-+ phy-handle = <&sgmii_phy1>;
-+};
-+
-+
-+ethernet@1 {
-+ compatible = "fsl,pfe-gemac-port";
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ reg = <0x1>; /* GEM_ID */
-+ fsl,gemac-bus-id = <0x1>; /* BUS_ID */
-+ fsl,mdio-mux-val = <0x0>;
-+ phy-mode = "sgmii";
-+ phy-handle = <&sgmii_phy2>;
-+};
-+
-+mdio@0 {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ sgmii_phy1: ethernet-phy@2 {
-+ reg = <0x2>;
-+ };
-+
-+ sgmii_phy2: ethernet-phy@1 {
-+ reg = <0x1>;
-+ };
-+};
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -8255,6 +8255,14 @@ F: drivers/ptp/ptp_qoriq.c
- F: drivers/ptp/ptp_qoriq_debugfs.c
- F: include/linux/fsl/ptp_qoriq.h
-
-+FREESCALE QORIQ PPFE ETHERNET DRIVER
-+M: Anji Jagarlmudi <anji.jagarlmudi@nxp.com>
-+M: Calvin Johnson <calvin.johnson@nxp.com>
-+L: netdev@vger.kernel.org
-+S: Maintained
-+F: drivers/staging/fsl_ppfe
-+F: Documentation/devicetree/bindings/net/fsl_ppfe/pfe.txt
-+
- FREESCALE QUAD SPI DRIVER
- M: Han Xu <han.xu@nxp.com>
- L: linux-spi@vger.kernel.org
---- a/drivers/staging/Kconfig
-+++ b/drivers/staging/Kconfig
-@@ -80,4 +80,6 @@ source "drivers/staging/qlge/Kconfig"
-
- source "drivers/staging/vme_user/Kconfig"
-
-+source "drivers/staging/fsl_ppfe/Kconfig"
-+
- endif # STAGING
---- a/drivers/staging/Makefile
-+++ b/drivers/staging/Makefile
-@@ -29,3 +29,4 @@ obj-$(CONFIG_PI433) += pi433/
- obj-$(CONFIG_XIL_AXIS_FIFO) += axis-fifo/
- obj-$(CONFIG_FIELDBUS_DEV) += fieldbus/
- obj-$(CONFIG_QLGE) += qlge/
-+obj-$(CONFIG_FSL_PPFE) += fsl_ppfe/
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/Kconfig
-@@ -0,0 +1,21 @@
-+#
-+# Freescale Programmable Packet Forwarding Engine driver
-+#
-+config FSL_PPFE
-+ tristate "Freescale PPFE Driver"
-+ select FSL_GUTS
-+ default n
-+ help
-+ Freescale LS1012A SoC has a Programmable Packet Forwarding Engine.
-+ It provides two high performance ethernet interfaces.
-+ This driver initializes, programs and controls the PPFE.
-+ Use this driver to enable network connectivity on LS1012A platforms.
-+
-+if FSL_PPFE
-+
-+config FSL_PPFE_UTIL_DISABLED
-+ bool "Disable PPFE UTIL Processor Engine"
-+ help
-+ UTIL PE has to be enabled only if required.
-+
-+endif # FSL_PPFE
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/Makefile
-@@ -0,0 +1,20 @@
-+#
-+# Makefile for Freesecale PPFE driver
-+#
-+
-+ccflags-y += -I $(srctree)/$(src)/include -I $(srctree)/$(src)
-+
-+obj-$(CONFIG_FSL_PPFE) += pfe.o
-+
-+pfe-y += pfe_mod.o \
-+ pfe_hw.o \
-+ pfe_firmware.o \
-+ pfe_ctrl.o \
-+ pfe_hif.o \
-+ pfe_hif_lib.o\
-+ pfe_eth.o \
-+ pfe_sysfs.o \
-+ pfe_debugfs.o \
-+ pfe_ls1012a_platform.o \
-+ pfe_hal.o \
-+ pfe_cdev.o
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/TODO
-@@ -0,0 +1,2 @@
-+TODO:
-+ - provide pfe pe monitoring support
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/include/pfe/cbus.h
-@@ -0,0 +1,78 @@
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ *
-+ * 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 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.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
-+ */
-+
-+#ifndef _CBUS_H_
-+#define _CBUS_H_
-+
-+#define EMAC1_BASE_ADDR (CBUS_BASE_ADDR + 0x200000)
-+#define EGPI1_BASE_ADDR (CBUS_BASE_ADDR + 0x210000)
-+#define EMAC2_BASE_ADDR (CBUS_BASE_ADDR + 0x220000)
-+#define EGPI2_BASE_ADDR (CBUS_BASE_ADDR + 0x230000)
-+#define BMU1_BASE_ADDR (CBUS_BASE_ADDR + 0x240000)
-+#define BMU2_BASE_ADDR (CBUS_BASE_ADDR + 0x250000)
-+#define ARB_BASE_ADDR (CBUS_BASE_ADDR + 0x260000)
-+#define DDR_CONFIG_BASE_ADDR (CBUS_BASE_ADDR + 0x270000)
-+#define HIF_BASE_ADDR (CBUS_BASE_ADDR + 0x280000)
-+#define HGPI_BASE_ADDR (CBUS_BASE_ADDR + 0x290000)
-+#define LMEM_BASE_ADDR (CBUS_BASE_ADDR + 0x300000)
-+#define LMEM_SIZE 0x10000
-+#define LMEM_END (LMEM_BASE_ADDR + LMEM_SIZE)
-+#define TMU_CSR_BASE_ADDR (CBUS_BASE_ADDR + 0x310000)
-+#define CLASS_CSR_BASE_ADDR (CBUS_BASE_ADDR + 0x320000)
-+#define HIF_NOCPY_BASE_ADDR (CBUS_BASE_ADDR + 0x350000)
-+#define UTIL_CSR_BASE_ADDR (CBUS_BASE_ADDR + 0x360000)
-+#define CBUS_GPT_BASE_ADDR (CBUS_BASE_ADDR + 0x370000)
-+
-+/*
-+ * defgroup XXX_MEM_ACCESS_ADDR PE memory access through CSR
-+ * XXX_MEM_ACCESS_ADDR register bit definitions.
-+ */
-+#define PE_MEM_ACCESS_WRITE BIT(31) /* Internal Memory Write. */
-+#define PE_MEM_ACCESS_IMEM BIT(15)
-+#define PE_MEM_ACCESS_DMEM BIT(16)
-+
-+/* Byte Enables of the Internal memory access. These are interpred in BE */
-+#define PE_MEM_ACCESS_BYTE_ENABLE(offset, size) \
-+ ({ typeof(size) size_ = (size); \
-+ (((BIT(size_) - 1) << (4 - (offset) - (size_))) & 0xf) << 24; })
-+
-+#include "cbus/emac_mtip.h"
-+#include "cbus/gpi.h"
-+#include "cbus/bmu.h"
-+#include "cbus/hif.h"
-+#include "cbus/tmu_csr.h"
-+#include "cbus/class_csr.h"
-+#include "cbus/hif_nocpy.h"
-+#include "cbus/util_csr.h"
-+
-+/* PFE cores states */
-+#define CORE_DISABLE 0x00000000
-+#define CORE_ENABLE 0x00000001
-+#define CORE_SW_RESET 0x00000002
-+
-+/* LMEM defines */
-+#define LMEM_HDR_SIZE 0x0010
-+#define LMEM_BUF_SIZE_LN2 0x7
-+#define LMEM_BUF_SIZE BIT(LMEM_BUF_SIZE_LN2)
-+
-+/* DDR defines */
-+#define DDR_HDR_SIZE 0x0100
-+#define DDR_BUF_SIZE_LN2 0xb
-+#define DDR_BUF_SIZE BIT(DDR_BUF_SIZE_LN2)
-+
-+#endif /* _CBUS_H_ */
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/include/pfe/cbus/bmu.h
-@@ -0,0 +1,55 @@
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ *
-+ * 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 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.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
-+ */
-+
-+#ifndef _BMU_H_
-+#define _BMU_H_
-+
-+#define BMU_VERSION 0x000
-+#define BMU_CTRL 0x004
-+#define BMU_UCAST_CONFIG 0x008
-+#define BMU_UCAST_BASE_ADDR 0x00c
-+#define BMU_BUF_SIZE 0x010
-+#define BMU_BUF_CNT 0x014
-+#define BMU_THRES 0x018
-+#define BMU_INT_SRC 0x020
-+#define BMU_INT_ENABLE 0x024
-+#define BMU_ALLOC_CTRL 0x030
-+#define BMU_FREE_CTRL 0x034
-+#define BMU_FREE_ERR_ADDR 0x038
-+#define BMU_CURR_BUF_CNT 0x03c
-+#define BMU_MCAST_CNT 0x040
-+#define BMU_MCAST_ALLOC_CTRL 0x044
-+#define BMU_REM_BUF_CNT 0x048
-+#define BMU_LOW_WATERMARK 0x050
-+#define BMU_HIGH_WATERMARK 0x054
-+#define BMU_INT_MEM_ACCESS 0x100
-+
-+struct BMU_CFG {
-+ unsigned long baseaddr;
-+ u32 count;
-+ u32 size;
-+ u32 low_watermark;
-+ u32 high_watermark;
-+};
-+
-+#define BMU1_BUF_SIZE LMEM_BUF_SIZE_LN2
-+#define BMU2_BUF_SIZE DDR_BUF_SIZE_LN2
-+
-+#define BMU2_MCAST_ALLOC_CTRL (BMU2_BASE_ADDR + BMU_MCAST_ALLOC_CTRL)
-+
-+#endif /* _BMU_H_ */
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/include/pfe/cbus/class_csr.h
-@@ -0,0 +1,289 @@
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ *
-+ * 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 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.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
-+ */
-+
-+#ifndef _CLASS_CSR_H_
-+#define _CLASS_CSR_H_
-+
-+/* @file class_csr.h.
-+ * class_csr - block containing all the classifier control and status register.
-+ * Mapped on CBUS and accessible from all PE's and ARM.
-+ */
-+#define CLASS_VERSION (CLASS_CSR_BASE_ADDR + 0x000)
-+#define CLASS_TX_CTRL (CLASS_CSR_BASE_ADDR + 0x004)
-+#define CLASS_INQ_PKTPTR (CLASS_CSR_BASE_ADDR + 0x010)
-+
-+/* (ddr_hdr_size[24:16], lmem_hdr_size[5:0]) */
-+#define CLASS_HDR_SIZE (CLASS_CSR_BASE_ADDR + 0x014)
-+
-+/* LMEM header size for the Classifier block.\ Data in the LMEM
-+ * is written from this offset.
-+ */
-+#define CLASS_HDR_SIZE_LMEM(off) ((off) & 0x3f)
-+
-+/* DDR header size for the Classifier block.\ Data in the DDR
-+ * is written from this offset.
-+ */
-+#define CLASS_HDR_SIZE_DDR(off) (((off) & 0x1ff) << 16)
-+
-+#define CLASS_PE0_QB_DM_ADDR0 (CLASS_CSR_BASE_ADDR + 0x020)
-+
-+/* DMEM address of first [15:0] and second [31:16] buffers on QB side. */
-+#define CLASS_PE0_QB_DM_ADDR1 (CLASS_CSR_BASE_ADDR + 0x024)
-+
-+/* DMEM address of third [15:0] and fourth [31:16] buffers on QB side. */
-+#define CLASS_PE0_RO_DM_ADDR0 (CLASS_CSR_BASE_ADDR + 0x060)
-+
-+/* DMEM address of first [15:0] and second [31:16] buffers on RO side. */
-+#define CLASS_PE0_RO_DM_ADDR1 (CLASS_CSR_BASE_ADDR + 0x064)
-+
-+/* DMEM address of third [15:0] and fourth [31:16] buffers on RO side. */
-+
-+/* @name Class PE memory access. Allows external PE's and HOST to
-+ * read/write PMEM/DMEM memory ranges for each classifier PE.
-+ */
-+/* {sr_pe_mem_cmd[31], csr_pe_mem_wren[27:24], csr_pe_mem_addr[23:0]},
-+ * See \ref XXX_MEM_ACCESS_ADDR for details.
-+ */
-+#define CLASS_MEM_ACCESS_ADDR (CLASS_CSR_BASE_ADDR + 0x100)
-+
-+/* Internal Memory Access Write Data [31:0] */
-+#define CLASS_MEM_ACCESS_WDATA (CLASS_CSR_BASE_ADDR + 0x104)
-+
-+/* Internal Memory Access Read Data [31:0] */
-+#define CLASS_MEM_ACCESS_RDATA (CLASS_CSR_BASE_ADDR + 0x108)
-+#define CLASS_TM_INQ_ADDR (CLASS_CSR_BASE_ADDR + 0x114)
-+#define CLASS_PE_STATUS (CLASS_CSR_BASE_ADDR + 0x118)
-+
-+#define CLASS_PHY1_RX_PKTS (CLASS_CSR_BASE_ADDR + 0x11c)
-+#define CLASS_PHY1_TX_PKTS (CLASS_CSR_BASE_ADDR + 0x120)
-+#define CLASS_PHY1_LP_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x124)
-+#define CLASS_PHY1_INTF_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x128)
-+#define CLASS_PHY1_INTF_MATCH_PKTS (CLASS_CSR_BASE_ADDR + 0x12c)
-+#define CLASS_PHY1_L3_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x130)
-+#define CLASS_PHY1_V4_PKTS (CLASS_CSR_BASE_ADDR + 0x134)
-+#define CLASS_PHY1_V6_PKTS (CLASS_CSR_BASE_ADDR + 0x138)
-+#define CLASS_PHY1_CHKSUM_ERR_PKTS (CLASS_CSR_BASE_ADDR + 0x13c)
-+#define CLASS_PHY1_TTL_ERR_PKTS (CLASS_CSR_BASE_ADDR + 0x140)
-+#define CLASS_PHY2_RX_PKTS (CLASS_CSR_BASE_ADDR + 0x144)
-+#define CLASS_PHY2_TX_PKTS (CLASS_CSR_BASE_ADDR + 0x148)
-+#define CLASS_PHY2_LP_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x14c)
-+#define CLASS_PHY2_INTF_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x150)
-+#define CLASS_PHY2_INTF_MATCH_PKTS (CLASS_CSR_BASE_ADDR + 0x154)
-+#define CLASS_PHY2_L3_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x158)
-+#define CLASS_PHY2_V4_PKTS (CLASS_CSR_BASE_ADDR + 0x15c)
-+#define CLASS_PHY2_V6_PKTS (CLASS_CSR_BASE_ADDR + 0x160)
-+#define CLASS_PHY2_CHKSUM_ERR_PKTS (CLASS_CSR_BASE_ADDR + 0x164)
-+#define CLASS_PHY2_TTL_ERR_PKTS (CLASS_CSR_BASE_ADDR + 0x168)
-+#define CLASS_PHY3_RX_PKTS (CLASS_CSR_BASE_ADDR + 0x16c)
-+#define CLASS_PHY3_TX_PKTS (CLASS_CSR_BASE_ADDR + 0x170)
-+#define CLASS_PHY3_LP_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x174)
-+#define CLASS_PHY3_INTF_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x178)
-+#define CLASS_PHY3_INTF_MATCH_PKTS (CLASS_CSR_BASE_ADDR + 0x17c)
-+#define CLASS_PHY3_L3_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x180)
-+#define CLASS_PHY3_V4_PKTS (CLASS_CSR_BASE_ADDR + 0x184)
-+#define CLASS_PHY3_V6_PKTS (CLASS_CSR_BASE_ADDR + 0x188)
-+#define CLASS_PHY3_CHKSUM_ERR_PKTS (CLASS_CSR_BASE_ADDR + 0x18c)
-+#define CLASS_PHY3_TTL_ERR_PKTS (CLASS_CSR_BASE_ADDR + 0x190)
-+#define CLASS_PHY1_ICMP_PKTS (CLASS_CSR_BASE_ADDR + 0x194)
-+#define CLASS_PHY1_IGMP_PKTS (CLASS_CSR_BASE_ADDR + 0x198)
-+#define CLASS_PHY1_TCP_PKTS (CLASS_CSR_BASE_ADDR + 0x19c)
-+#define CLASS_PHY1_UDP_PKTS (CLASS_CSR_BASE_ADDR + 0x1a0)
-+#define CLASS_PHY2_ICMP_PKTS (CLASS_CSR_BASE_ADDR + 0x1a4)
-+#define CLASS_PHY2_IGMP_PKTS (CLASS_CSR_BASE_ADDR + 0x1a8)
-+#define CLASS_PHY2_TCP_PKTS (CLASS_CSR_BASE_ADDR + 0x1ac)
-+#define CLASS_PHY2_UDP_PKTS (CLASS_CSR_BASE_ADDR + 0x1b0)
-+#define CLASS_PHY3_ICMP_PKTS (CLASS_CSR_BASE_ADDR + 0x1b4)
-+#define CLASS_PHY3_IGMP_PKTS (CLASS_CSR_BASE_ADDR + 0x1b8)
-+#define CLASS_PHY3_TCP_PKTS (CLASS_CSR_BASE_ADDR + 0x1bc)
-+#define CLASS_PHY3_UDP_PKTS (CLASS_CSR_BASE_ADDR + 0x1c0)
-+#define CLASS_PHY4_ICMP_PKTS (CLASS_CSR_BASE_ADDR + 0x1c4)
-+#define CLASS_PHY4_IGMP_PKTS (CLASS_CSR_BASE_ADDR + 0x1c8)
-+#define CLASS_PHY4_TCP_PKTS (CLASS_CSR_BASE_ADDR + 0x1cc)
-+#define CLASS_PHY4_UDP_PKTS (CLASS_CSR_BASE_ADDR + 0x1d0)
-+#define CLASS_PHY4_RX_PKTS (CLASS_CSR_BASE_ADDR + 0x1d4)
-+#define CLASS_PHY4_TX_PKTS (CLASS_CSR_BASE_ADDR + 0x1d8)
-+#define CLASS_PHY4_LP_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x1dc)
-+#define CLASS_PHY4_INTF_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x1e0)
-+#define CLASS_PHY4_INTF_MATCH_PKTS (CLASS_CSR_BASE_ADDR + 0x1e4)
-+#define CLASS_PHY4_L3_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x1e8)
-+#define CLASS_PHY4_V4_PKTS (CLASS_CSR_BASE_ADDR + 0x1ec)
-+#define CLASS_PHY4_V6_PKTS (CLASS_CSR_BASE_ADDR + 0x1f0)
-+#define CLASS_PHY4_CHKSUM_ERR_PKTS (CLASS_CSR_BASE_ADDR + 0x1f4)
-+#define CLASS_PHY4_TTL_ERR_PKTS (CLASS_CSR_BASE_ADDR + 0x1f8)
-+
-+#define CLASS_PE_SYS_CLK_RATIO (CLASS_CSR_BASE_ADDR + 0x200)
-+#define CLASS_AFULL_THRES (CLASS_CSR_BASE_ADDR + 0x204)
-+#define CLASS_GAP_BETWEEN_READS (CLASS_CSR_BASE_ADDR + 0x208)
-+#define CLASS_MAX_BUF_CNT (CLASS_CSR_BASE_ADDR + 0x20c)
-+#define CLASS_TSQ_FIFO_THRES (CLASS_CSR_BASE_ADDR + 0x210)
-+#define CLASS_TSQ_MAX_CNT (CLASS_CSR_BASE_ADDR + 0x214)
-+#define CLASS_IRAM_DATA_0 (CLASS_CSR_BASE_ADDR + 0x218)
-+#define CLASS_IRAM_DATA_1 (CLASS_CSR_BASE_ADDR + 0x21c)
-+#define CLASS_IRAM_DATA_2 (CLASS_CSR_BASE_ADDR + 0x220)
-+#define CLASS_IRAM_DATA_3 (CLASS_CSR_BASE_ADDR + 0x224)
-+
-+#define CLASS_BUS_ACCESS_ADDR (CLASS_CSR_BASE_ADDR + 0x228)
-+
-+#define CLASS_BUS_ACCESS_WDATA (CLASS_CSR_BASE_ADDR + 0x22c)
-+#define CLASS_BUS_ACCESS_RDATA (CLASS_CSR_BASE_ADDR + 0x230)
-+
-+/* (route_entry_size[9:0], route_hash_size[23:16]
-+ * (this is actually ln2(size)))
-+ */
-+#define CLASS_ROUTE_HASH_ENTRY_SIZE (CLASS_CSR_BASE_ADDR + 0x234)
-+
-+#define CLASS_ROUTE_ENTRY_SIZE(size) ((size) & 0x1ff)
-+#define CLASS_ROUTE_HASH_SIZE(hash_bits) (((hash_bits) & 0xff) << 16)
-+
-+#define CLASS_ROUTE_TABLE_BASE (CLASS_CSR_BASE_ADDR + 0x238)
-+
-+#define CLASS_ROUTE_MULTI (CLASS_CSR_BASE_ADDR + 0x23c)
-+#define CLASS_SMEM_OFFSET (CLASS_CSR_BASE_ADDR + 0x240)
-+#define CLASS_LMEM_BUF_SIZE (CLASS_CSR_BASE_ADDR + 0x244)
-+#define CLASS_VLAN_ID (CLASS_CSR_BASE_ADDR + 0x248)
-+#define CLASS_BMU1_BUF_FREE (CLASS_CSR_BASE_ADDR + 0x24c)
-+#define CLASS_USE_TMU_INQ (CLASS_CSR_BASE_ADDR + 0x250)
-+#define CLASS_VLAN_ID1 (CLASS_CSR_BASE_ADDR + 0x254)
-+
-+#define CLASS_BUS_ACCESS_BASE (CLASS_CSR_BASE_ADDR + 0x258)
-+#define CLASS_BUS_ACCESS_BASE_MASK (0xFF000000)
-+/* bit 31:24 of PE peripheral address are stored in CLASS_BUS_ACCESS_BASE */
-+
-+#define CLASS_HIF_PARSE (CLASS_CSR_BASE_ADDR + 0x25c)
-+
-+#define CLASS_HOST_PE0_GP (CLASS_CSR_BASE_ADDR + 0x260)
-+#define CLASS_PE0_GP (CLASS_CSR_BASE_ADDR + 0x264)
-+#define CLASS_HOST_PE1_GP (CLASS_CSR_BASE_ADDR + 0x268)
-+#define CLASS_PE1_GP (CLASS_CSR_BASE_ADDR + 0x26c)
-+#define CLASS_HOST_PE2_GP (CLASS_CSR_BASE_ADDR + 0x270)
-+#define CLASS_PE2_GP (CLASS_CSR_BASE_ADDR + 0x274)
-+#define CLASS_HOST_PE3_GP (CLASS_CSR_BASE_ADDR + 0x278)
-+#define CLASS_PE3_GP (CLASS_CSR_BASE_ADDR + 0x27c)
-+#define CLASS_HOST_PE4_GP (CLASS_CSR_BASE_ADDR + 0x280)
-+#define CLASS_PE4_GP (CLASS_CSR_BASE_ADDR + 0x284)
-+#define CLASS_HOST_PE5_GP (CLASS_CSR_BASE_ADDR + 0x288)
-+#define CLASS_PE5_GP (CLASS_CSR_BASE_ADDR + 0x28c)
-+
-+#define CLASS_PE_INT_SRC (CLASS_CSR_BASE_ADDR + 0x290)
-+#define CLASS_PE_INT_ENABLE (CLASS_CSR_BASE_ADDR + 0x294)
-+
-+#define CLASS_TPID0_TPID1 (CLASS_CSR_BASE_ADDR + 0x298)
-+#define CLASS_TPID2 (CLASS_CSR_BASE_ADDR + 0x29c)
-+
-+#define CLASS_L4_CHKSUM_ADDR (CLASS_CSR_BASE_ADDR + 0x2a0)
-+
-+#define CLASS_PE0_DEBUG (CLASS_CSR_BASE_ADDR + 0x2a4)
-+#define CLASS_PE1_DEBUG (CLASS_CSR_BASE_ADDR + 0x2a8)
-+#define CLASS_PE2_DEBUG (CLASS_CSR_BASE_ADDR + 0x2ac)
-+#define CLASS_PE3_DEBUG (CLASS_CSR_BASE_ADDR + 0x2b0)
-+#define CLASS_PE4_DEBUG (CLASS_CSR_BASE_ADDR + 0x2b4)
-+#define CLASS_PE5_DEBUG (CLASS_CSR_BASE_ADDR + 0x2b8)
-+
-+#define CLASS_STATE (CLASS_CSR_BASE_ADDR + 0x2bc)
-+
-+/* CLASS defines */
-+#define CLASS_PBUF_SIZE 0x100 /* Fixed by hardware */
-+#define CLASS_PBUF_HEADER_OFFSET 0x80 /* Can be configured */
-+
-+/* Can be configured */
-+#define CLASS_PBUF0_BASE_ADDR 0x000
-+/* Can be configured */
-+#define CLASS_PBUF1_BASE_ADDR (CLASS_PBUF0_BASE_ADDR + CLASS_PBUF_SIZE)
-+/* Can be configured */
-+#define CLASS_PBUF2_BASE_ADDR (CLASS_PBUF1_BASE_ADDR + CLASS_PBUF_SIZE)
-+/* Can be configured */
-+#define CLASS_PBUF3_BASE_ADDR (CLASS_PBUF2_BASE_ADDR + CLASS_PBUF_SIZE)
-+
-+#define CLASS_PBUF0_HEADER_BASE_ADDR (CLASS_PBUF0_BASE_ADDR + \
-+ CLASS_PBUF_HEADER_OFFSET)
-+#define CLASS_PBUF1_HEADER_BASE_ADDR (CLASS_PBUF1_BASE_ADDR + \
-+ CLASS_PBUF_HEADER_OFFSET)
-+#define CLASS_PBUF2_HEADER_BASE_ADDR (CLASS_PBUF2_BASE_ADDR + \
-+ CLASS_PBUF_HEADER_OFFSET)
-+#define CLASS_PBUF3_HEADER_BASE_ADDR (CLASS_PBUF3_BASE_ADDR + \
-+ CLASS_PBUF_HEADER_OFFSET)
-+
-+#define CLASS_PE0_RO_DM_ADDR0_VAL ((CLASS_PBUF1_BASE_ADDR << 16) | \
-+ CLASS_PBUF0_BASE_ADDR)
-+#define CLASS_PE0_RO_DM_ADDR1_VAL ((CLASS_PBUF3_BASE_ADDR << 16) | \
-+ CLASS_PBUF2_BASE_ADDR)
-+
-+#define CLASS_PE0_QB_DM_ADDR0_VAL ((CLASS_PBUF1_HEADER_BASE_ADDR << 16) |\
-+ CLASS_PBUF0_HEADER_BASE_ADDR)
-+#define CLASS_PE0_QB_DM_ADDR1_VAL ((CLASS_PBUF3_HEADER_BASE_ADDR << 16) |\
-+ CLASS_PBUF2_HEADER_BASE_ADDR)
-+
-+#define CLASS_ROUTE_SIZE 128
-+#define CLASS_MAX_ROUTE_SIZE 256
-+#define CLASS_ROUTE_HASH_BITS 20
-+#define CLASS_ROUTE_HASH_MASK (BIT(CLASS_ROUTE_HASH_BITS) - 1)
-+
-+/* Can be configured */
-+#define CLASS_ROUTE0_BASE_ADDR 0x400
-+/* Can be configured */
-+#define CLASS_ROUTE1_BASE_ADDR (CLASS_ROUTE0_BASE_ADDR + CLASS_ROUTE_SIZE)
-+/* Can be configured */
-+#define CLASS_ROUTE2_BASE_ADDR (CLASS_ROUTE1_BASE_ADDR + CLASS_ROUTE_SIZE)
-+/* Can be configured */
-+#define CLASS_ROUTE3_BASE_ADDR (CLASS_ROUTE2_BASE_ADDR + CLASS_ROUTE_SIZE)
-+
-+#define CLASS_SA_SIZE 128
-+#define CLASS_IPSEC_SA0_BASE_ADDR 0x600
-+/* not used */
-+#define CLASS_IPSEC_SA1_BASE_ADDR (CLASS_IPSEC_SA0_BASE_ADDR + CLASS_SA_SIZE)
-+/* not used */
-+#define CLASS_IPSEC_SA2_BASE_ADDR (CLASS_IPSEC_SA1_BASE_ADDR + CLASS_SA_SIZE)
-+/* not used */
-+#define CLASS_IPSEC_SA3_BASE_ADDR (CLASS_IPSEC_SA2_BASE_ADDR + CLASS_SA_SIZE)
-+
-+/* generic purpose free dmem buffer, last portion of 2K dmem pbuf */
-+#define CLASS_GP_DMEM_BUF_SIZE (2048 - (CLASS_PBUF_SIZE * 4) - \
-+ (CLASS_ROUTE_SIZE * 4) - (CLASS_SA_SIZE))
-+#define CLASS_GP_DMEM_BUF ((void *)(CLASS_IPSEC_SA0_BASE_ADDR + \
-+ CLASS_SA_SIZE))
-+
-+#define TWO_LEVEL_ROUTE BIT(0)
-+#define PHYNO_IN_HASH BIT(1)
-+#define HW_ROUTE_FETCH BIT(3)
-+#define HW_BRIDGE_FETCH BIT(5)
-+#define IP_ALIGNED BIT(6)
-+#define ARC_HIT_CHECK_EN BIT(7)
-+#define CLASS_TOE BIT(11)
-+#define HASH_NORMAL (0 << 12)
-+#define HASH_CRC_PORT BIT(12)
-+#define HASH_CRC_IP (2 << 12)
-+#define HASH_CRC_PORT_IP (3 << 12)
-+#define QB2BUS_LE BIT(15)
-+
-+#define TCP_CHKSUM_DROP BIT(0)
-+#define UDP_CHKSUM_DROP BIT(1)
-+#define IPV4_CHKSUM_DROP BIT(9)
-+
-+/*CLASS_HIF_PARSE bits*/
-+#define HIF_PKT_CLASS_EN BIT(0)
-+#define HIF_PKT_OFFSET(ofst) (((ofst) & 0xF) << 1)
-+
-+struct class_cfg {
-+ u32 toe_mode;
-+ unsigned long route_table_baseaddr;
-+ u32 route_table_hash_bits;
-+ u32 pe_sys_clk_ratio;
-+ u32 resume;
-+};
-+
-+#endif /* _CLASS_CSR_H_ */
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/include/pfe/cbus/emac_mtip.h
-@@ -0,0 +1,242 @@
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ *
-+ * 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 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.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
-+ */
-+
-+#ifndef _EMAC_H_
-+#define _EMAC_H_
-+
-+#include <linux/ethtool.h>
-+
-+#define EMAC_IEVENT_REG 0x004
-+#define EMAC_IMASK_REG 0x008
-+#define EMAC_R_DES_ACTIVE_REG 0x010
-+#define EMAC_X_DES_ACTIVE_REG 0x014
-+#define EMAC_ECNTRL_REG 0x024
-+#define EMAC_MII_DATA_REG 0x040
-+#define EMAC_MII_CTRL_REG 0x044
-+#define EMAC_MIB_CTRL_STS_REG 0x064
-+#define EMAC_RCNTRL_REG 0x084
-+#define EMAC_TCNTRL_REG 0x0C4
-+#define EMAC_PHY_ADDR_LOW 0x0E4
-+#define EMAC_PHY_ADDR_HIGH 0x0E8
-+#define EMAC_GAUR 0x120
-+#define EMAC_GALR 0x124
-+#define EMAC_TFWR_STR_FWD 0x144
-+#define EMAC_RX_SECTION_FULL 0x190
-+#define EMAC_RX_SECTION_EMPTY 0x194
-+#define EMAC_TX_SECTION_EMPTY 0x1A0
-+#define EMAC_TRUNC_FL 0x1B0
-+
-+#define RMON_T_DROP 0x200 /* Count of frames not cntd correctly */
-+#define RMON_T_PACKETS 0x204 /* RMON TX packet count */
-+#define RMON_T_BC_PKT 0x208 /* RMON TX broadcast pkts */
-+#define RMON_T_MC_PKT 0x20c /* RMON TX multicast pkts */
-+#define RMON_T_CRC_ALIGN 0x210 /* RMON TX pkts with CRC align err */
-+#define RMON_T_UNDERSIZE 0x214 /* RMON TX pkts < 64 bytes, good CRC */
-+#define RMON_T_OVERSIZE 0x218 /* RMON TX pkts > MAX_FL bytes good CRC */
-+#define RMON_T_FRAG 0x21c /* RMON TX pkts < 64 bytes, bad CRC */
-+#define RMON_T_JAB 0x220 /* RMON TX pkts > MAX_FL bytes, bad CRC */
-+#define RMON_T_COL 0x224 /* RMON TX collision count */
-+#define RMON_T_P64 0x228 /* RMON TX 64 byte pkts */
-+#define RMON_T_P65TO127 0x22c /* RMON TX 65 to 127 byte pkts */
-+#define RMON_T_P128TO255 0x230 /* RMON TX 128 to 255 byte pkts */
-+#define RMON_T_P256TO511 0x234 /* RMON TX 256 to 511 byte pkts */
-+#define RMON_T_P512TO1023 0x238 /* RMON TX 512 to 1023 byte pkts */
-+#define RMON_T_P1024TO2047 0x23c /* RMON TX 1024 to 2047 byte pkts */
-+#define RMON_T_P_GTE2048 0x240 /* RMON TX pkts > 2048 bytes */
-+#define RMON_T_OCTETS 0x244 /* RMON TX octets */
-+#define IEEE_T_DROP 0x248 /* Count of frames not counted crtly */
-+#define IEEE_T_FRAME_OK 0x24c /* Frames tx'd OK */
-+#define IEEE_T_1COL 0x250 /* Frames tx'd with single collision */
-+#define IEEE_T_MCOL 0x254 /* Frames tx'd with multiple collision */
-+#define IEEE_T_DEF 0x258 /* Frames tx'd after deferral delay */
-+#define IEEE_T_LCOL 0x25c /* Frames tx'd with late collision */
-+#define IEEE_T_EXCOL 0x260 /* Frames tx'd with excesv collisions */
-+#define IEEE_T_MACERR 0x264 /* Frames tx'd with TX FIFO underrun */
-+#define IEEE_T_CSERR 0x268 /* Frames tx'd with carrier sense err */
-+#define IEEE_T_SQE 0x26c /* Frames tx'd with SQE err */
-+#define IEEE_T_FDXFC 0x270 /* Flow control pause frames tx'd */
-+#define IEEE_T_OCTETS_OK 0x274 /* Octet count for frames tx'd w/o err */
-+#define RMON_R_PACKETS 0x284 /* RMON RX packet count */
-+#define RMON_R_BC_PKT 0x288 /* RMON RX broadcast pkts */
-+#define RMON_R_MC_PKT 0x28c /* RMON RX multicast pkts */
-+#define RMON_R_CRC_ALIGN 0x290 /* RMON RX pkts with CRC alignment err */
-+#define RMON_R_UNDERSIZE 0x294 /* RMON RX pkts < 64 bytes, good CRC */
-+#define RMON_R_OVERSIZE 0x298 /* RMON RX pkts > MAX_FL bytes good CRC */
-+#define RMON_R_FRAG 0x29c /* RMON RX pkts < 64 bytes, bad CRC */
-+#define RMON_R_JAB 0x2a0 /* RMON RX pkts > MAX_FL bytes, bad CRC */
-+#define RMON_R_RESVD_O 0x2a4 /* Reserved */
-+#define RMON_R_P64 0x2a8 /* RMON RX 64 byte pkts */
-+#define RMON_R_P65TO127 0x2ac /* RMON RX 65 to 127 byte pkts */
-+#define RMON_R_P128TO255 0x2b0 /* RMON RX 128 to 255 byte pkts */
-+#define RMON_R_P256TO511 0x2b4 /* RMON RX 256 to 511 byte pkts */
-+#define RMON_R_P512TO1023 0x2b8 /* RMON RX 512 to 1023 byte pkts */
-+#define RMON_R_P1024TO2047 0x2bc /* RMON RX 1024 to 2047 byte pkts */
-+#define RMON_R_P_GTE2048 0x2c0 /* RMON RX pkts > 2048 bytes */
-+#define RMON_R_OCTETS 0x2c4 /* RMON RX octets */
-+#define IEEE_R_DROP 0x2c8 /* Count frames not counted correctly */
-+#define IEEE_R_FRAME_OK 0x2cc /* Frames rx'd OK */
-+#define IEEE_R_CRC 0x2d0 /* Frames rx'd with CRC err */
-+#define IEEE_R_ALIGN 0x2d4 /* Frames rx'd with alignment err */
-+#define IEEE_R_MACERR 0x2d8 /* Receive FIFO overflow count */
-+#define IEEE_R_FDXFC 0x2dc /* Flow control pause frames rx'd */
-+#define IEEE_R_OCTETS_OK 0x2e0 /* Octet cnt for frames rx'd w/o err */
-+
-+#define EMAC_SMAC_0_0 0x500 /*Supplemental MAC Address 0 (RW).*/
-+#define EMAC_SMAC_0_1 0x504 /*Supplemental MAC Address 0 (RW).*/
-+
-+/* GEMAC definitions and settings */
-+
-+#define EMAC_PORT_0 0
-+#define EMAC_PORT_1 1
-+
-+/* GEMAC Bit definitions */
-+#define EMAC_IEVENT_HBERR 0x80000000
-+#define EMAC_IEVENT_BABR 0x40000000
-+#define EMAC_IEVENT_BABT 0x20000000
-+#define EMAC_IEVENT_GRA 0x10000000
-+#define EMAC_IEVENT_TXF 0x08000000
-+#define EMAC_IEVENT_TXB 0x04000000
-+#define EMAC_IEVENT_RXF 0x02000000
-+#define EMAC_IEVENT_RXB 0x01000000
-+#define EMAC_IEVENT_MII 0x00800000
-+#define EMAC_IEVENT_EBERR 0x00400000
-+#define EMAC_IEVENT_LC 0x00200000
-+#define EMAC_IEVENT_RL 0x00100000
-+#define EMAC_IEVENT_UN 0x00080000
-+
-+#define EMAC_IMASK_HBERR 0x80000000
-+#define EMAC_IMASK_BABR 0x40000000
-+#define EMAC_IMASKT_BABT 0x20000000
-+#define EMAC_IMASK_GRA 0x10000000
-+#define EMAC_IMASKT_TXF 0x08000000
-+#define EMAC_IMASK_TXB 0x04000000
-+#define EMAC_IMASKT_RXF 0x02000000
-+#define EMAC_IMASK_RXB 0x01000000
-+#define EMAC_IMASK_MII 0x00800000
-+#define EMAC_IMASK_EBERR 0x00400000
-+#define EMAC_IMASK_LC 0x00200000
-+#define EMAC_IMASKT_RL 0x00100000
-+#define EMAC_IMASK_UN 0x00080000
-+
-+#define EMAC_RCNTRL_MAX_FL_SHIFT 16
-+#define EMAC_RCNTRL_LOOP 0x00000001
-+#define EMAC_RCNTRL_DRT 0x00000002
-+#define EMAC_RCNTRL_MII_MODE 0x00000004
-+#define EMAC_RCNTRL_PROM 0x00000008
-+#define EMAC_RCNTRL_BC_REJ 0x00000010
-+#define EMAC_RCNTRL_FCE 0x00000020
-+#define EMAC_RCNTRL_RGMII 0x00000040
-+#define EMAC_RCNTRL_SGMII 0x00000080
-+#define EMAC_RCNTRL_RMII 0x00000100
-+#define EMAC_RCNTRL_RMII_10T 0x00000200
-+#define EMAC_RCNTRL_CRC_FWD 0x00004000
-+
-+#define EMAC_TCNTRL_GTS 0x00000001
-+#define EMAC_TCNTRL_HBC 0x00000002
-+#define EMAC_TCNTRL_FDEN 0x00000004
-+#define EMAC_TCNTRL_TFC_PAUSE 0x00000008
-+#define EMAC_TCNTRL_RFC_PAUSE 0x00000010
-+
-+#define EMAC_ECNTRL_RESET 0x00000001 /* reset the EMAC */
-+#define EMAC_ECNTRL_ETHER_EN 0x00000002 /* enable the EMAC */
-+#define EMAC_ECNTRL_MAGIC_ENA 0x00000004
-+#define EMAC_ECNTRL_SLEEP 0x00000008
-+#define EMAC_ECNTRL_SPEED 0x00000020
-+#define EMAC_ECNTRL_DBSWAP 0x00000100
-+
-+#define EMAC_X_WMRK_STRFWD 0x00000100
-+
-+#define EMAC_X_DES_ACTIVE_TDAR 0x01000000
-+#define EMAC_R_DES_ACTIVE_RDAR 0x01000000
-+
-+#define EMAC_RX_SECTION_EMPTY_V 0x00010006
-+/*
-+ * The possible operating speeds of the MAC, currently supporting 10, 100 and
-+ * 1000Mb modes.
-+ */
-+enum mac_speed {SPEED_10M, SPEED_100M, SPEED_1000M, SPEED_1000M_PCS};
-+
-+/* MII-related definitios */
-+#define EMAC_MII_DATA_ST 0x40000000 /* Start of frame delimiter */
-+#define EMAC_MII_DATA_OP_RD 0x20000000 /* Perform a read operation */
-+#define EMAC_MII_DATA_OP_CL45_RD 0x30000000 /* Perform a read operation */
-+#define EMAC_MII_DATA_OP_WR 0x10000000 /* Perform a write operation */
-+#define EMAC_MII_DATA_OP_CL45_WR 0x10000000 /* Perform a write operation */
-+#define EMAC_MII_DATA_PA_MSK 0x0f800000 /* PHY Address field mask */
-+#define EMAC_MII_DATA_RA_MSK 0x007c0000 /* PHY Register field mask */
-+#define EMAC_MII_DATA_TA 0x00020000 /* Turnaround */
-+#define EMAC_MII_DATA_DATAMSK 0x0000ffff /* PHY data field */
-+
-+#define EMAC_MII_DATA_RA_SHIFT 18 /* MII Register address bits */
-+#define EMAC_MII_DATA_RA_MASK 0x1F /* MII Register address mask */
-+#define EMAC_MII_DATA_PA_SHIFT 23 /* MII PHY address bits */
-+#define EMAC_MII_DATA_PA_MASK 0x1F /* MII PHY address mask */
-+
-+#define EMAC_MII_DATA_RA(v) (((v) & EMAC_MII_DATA_RA_MASK) << \
-+ EMAC_MII_DATA_RA_SHIFT)
-+#define EMAC_MII_DATA_PA(v) (((v) & EMAC_MII_DATA_RA_MASK) << \
-+ EMAC_MII_DATA_PA_SHIFT)
-+#define EMAC_MII_DATA(v) ((v) & 0xffff)
-+
-+#define EMAC_MII_SPEED_SHIFT 1
-+#define EMAC_HOLDTIME_SHIFT 8
-+#define EMAC_HOLDTIME_MASK 0x7
-+#define EMAC_HOLDTIME(v) (((v) & EMAC_HOLDTIME_MASK) << \
-+ EMAC_HOLDTIME_SHIFT)
-+
-+/*
-+ * The Address organisation for the MAC device. All addresses are split into
-+ * two 32-bit register fields. The first one (bottom) is the lower 32-bits of
-+ * the address and the other field are the high order bits - this may be 16-bits
-+ * in the case of MAC addresses, or 32-bits for the hash address.
-+ * In terms of memory storage, the first item (bottom) is assumed to be at a
-+ * lower address location than 'top'. i.e. top should be at address location of
-+ * 'bottom' + 4 bytes.
-+ */
-+struct pfe_mac_addr {
-+ u32 bottom; /* Lower 32-bits of address. */
-+ u32 top; /* Upper 32-bits of address. */
-+};
-+
-+/*
-+ * The following is the organisation of the address filters section of the MAC
-+ * registers. The Cadence MAC contains four possible specific address match
-+ * addresses, if an incoming frame corresponds to any one of these four
-+ * addresses then the frame will be copied to memory.
-+ * It is not necessary for all four of the address match registers to be
-+ * programmed, this is application dependent.
-+ */
-+struct spec_addr {
-+ struct pfe_mac_addr one; /* Specific address register 1. */
-+ struct pfe_mac_addr two; /* Specific address register 2. */
-+ struct pfe_mac_addr three; /* Specific address register 3. */
-+ struct pfe_mac_addr four; /* Specific address register 4. */
-+};
-+
-+struct gemac_cfg {
-+ u32 mode;
-+ u32 speed;
-+ u32 duplex;
-+};
-+
-+/* EMAC Hash size */
-+#define EMAC_HASH_REG_BITS 64
-+
-+#define EMAC_SPEC_ADDR_MAX 4
-+
-+#endif /* _EMAC_H_ */
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/include/pfe/cbus/gpi.h
-@@ -0,0 +1,86 @@
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ *
-+ * 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 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.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
-+ */
-+
-+#ifndef _GPI_H_
-+#define _GPI_H_
-+
-+#define GPI_VERSION 0x00
-+#define GPI_CTRL 0x04
-+#define GPI_RX_CONFIG 0x08
-+#define GPI_HDR_SIZE 0x0c
-+#define GPI_BUF_SIZE 0x10
-+#define GPI_LMEM_ALLOC_ADDR 0x14
-+#define GPI_LMEM_FREE_ADDR 0x18
-+#define GPI_DDR_ALLOC_ADDR 0x1c
-+#define GPI_DDR_FREE_ADDR 0x20
-+#define GPI_CLASS_ADDR 0x24
-+#define GPI_DRX_FIFO 0x28
-+#define GPI_TRX_FIFO 0x2c
-+#define GPI_INQ_PKTPTR 0x30
-+#define GPI_DDR_DATA_OFFSET 0x34
-+#define GPI_LMEM_DATA_OFFSET 0x38
-+#define GPI_TMLF_TX 0x4c
-+#define GPI_DTX_ASEQ 0x50
-+#define GPI_FIFO_STATUS 0x54
-+#define GPI_FIFO_DEBUG 0x58
-+#define GPI_TX_PAUSE_TIME 0x5c
-+#define GPI_LMEM_SEC_BUF_DATA_OFFSET 0x60
-+#define GPI_DDR_SEC_BUF_DATA_OFFSET 0x64
-+#define GPI_TOE_CHKSUM_EN 0x68
-+#define GPI_OVERRUN_DROPCNT 0x6c
-+#define GPI_CSR_MTIP_PAUSE_REG 0x74
-+#define GPI_CSR_MTIP_PAUSE_QUANTUM 0x78
-+#define GPI_CSR_RX_CNT 0x7c
-+#define GPI_CSR_TX_CNT 0x80
-+#define GPI_CSR_DEBUG1 0x84
-+#define GPI_CSR_DEBUG2 0x88
-+
-+struct gpi_cfg {
-+ u32 lmem_rtry_cnt;
-+ u32 tmlf_txthres;
-+ u32 aseq_len;
-+ u32 mtip_pause_reg;
-+};
-+
-+/* GPI commons defines */
-+#define GPI_LMEM_BUF_EN 0x1
-+#define GPI_DDR_BUF_EN 0x1
-+
-+/* EGPI 1 defines */
-+#define EGPI1_LMEM_RTRY_CNT 0x40
-+#define EGPI1_TMLF_TXTHRES 0xBC
-+#define EGPI1_ASEQ_LEN 0x50
-+
-+/* EGPI 2 defines */
-+#define EGPI2_LMEM_RTRY_CNT 0x40
-+#define EGPI2_TMLF_TXTHRES 0xBC
-+#define EGPI2_ASEQ_LEN 0x40
-+
-+/* EGPI 3 defines */
-+#define EGPI3_LMEM_RTRY_CNT 0x40
-+#define EGPI3_TMLF_TXTHRES 0xBC
-+#define EGPI3_ASEQ_LEN 0x40
-+
-+/* HGPI defines */
-+#define HGPI_LMEM_RTRY_CNT 0x40
-+#define HGPI_TMLF_TXTHRES 0xBC
-+#define HGPI_ASEQ_LEN 0x40
-+
-+#define EGPI_PAUSE_TIME 0x000007D0
-+#define EGPI_PAUSE_ENABLE 0x40000000
-+#endif /* _GPI_H_ */
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/include/pfe/cbus/hif.h
-@@ -0,0 +1,100 @@
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ *
-+ * 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 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.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
-+ */
-+
-+#ifndef _HIF_H_
-+#define _HIF_H_
-+
-+/* @file hif.h.
-+ * hif - PFE hif block control and status register.
-+ * Mapped on CBUS and accessible from all PE's and ARM.
-+ */
-+#define HIF_VERSION (HIF_BASE_ADDR + 0x00)
-+#define HIF_TX_CTRL (HIF_BASE_ADDR + 0x04)
-+#define HIF_TX_CURR_BD_ADDR (HIF_BASE_ADDR + 0x08)
-+#define HIF_TX_ALLOC (HIF_BASE_ADDR + 0x0c)
-+#define HIF_TX_BDP_ADDR (HIF_BASE_ADDR + 0x10)
-+#define HIF_TX_STATUS (HIF_BASE_ADDR + 0x14)
-+#define HIF_RX_CTRL (HIF_BASE_ADDR + 0x20)
-+#define HIF_RX_BDP_ADDR (HIF_BASE_ADDR + 0x24)
-+#define HIF_RX_STATUS (HIF_BASE_ADDR + 0x30)
-+#define HIF_INT_SRC (HIF_BASE_ADDR + 0x34)
-+#define HIF_INT_ENABLE (HIF_BASE_ADDR + 0x38)
-+#define HIF_POLL_CTRL (HIF_BASE_ADDR + 0x3c)
-+#define HIF_RX_CURR_BD_ADDR (HIF_BASE_ADDR + 0x40)
-+#define HIF_RX_ALLOC (HIF_BASE_ADDR + 0x44)
-+#define HIF_TX_DMA_STATUS (HIF_BASE_ADDR + 0x48)
-+#define HIF_RX_DMA_STATUS (HIF_BASE_ADDR + 0x4c)
-+#define HIF_INT_COAL (HIF_BASE_ADDR + 0x50)
-+
-+/* HIF_INT_SRC/ HIF_INT_ENABLE control bits */
-+#define HIF_INT BIT(0)
-+#define HIF_RXBD_INT BIT(1)
-+#define HIF_RXPKT_INT BIT(2)
-+#define HIF_TXBD_INT BIT(3)
-+#define HIF_TXPKT_INT BIT(4)
-+
-+/* HIF_TX_CTRL bits */
-+#define HIF_CTRL_DMA_EN BIT(0)
-+#define HIF_CTRL_BDP_POLL_CTRL_EN BIT(1)
-+#define HIF_CTRL_BDP_CH_START_WSTB BIT(2)
-+
-+/* HIF_RX_STATUS bits */
-+#define BDP_CSR_RX_DMA_ACTV BIT(16)
-+
-+/* HIF_INT_ENABLE bits */
-+#define HIF_INT_EN BIT(0)
-+#define HIF_RXBD_INT_EN BIT(1)
-+#define HIF_RXPKT_INT_EN BIT(2)
-+#define HIF_TXBD_INT_EN BIT(3)
-+#define HIF_TXPKT_INT_EN BIT(4)
-+
-+/* HIF_POLL_CTRL bits*/
-+#define HIF_RX_POLL_CTRL_CYCLE 0x0400
-+#define HIF_TX_POLL_CTRL_CYCLE 0x0400
-+
-+/* HIF_INT_COAL bits*/
-+#define HIF_INT_COAL_ENABLE BIT(31)
-+
-+/* Buffer descriptor control bits */
-+#define BD_CTRL_BUFLEN_MASK 0x3fff
-+#define BD_BUF_LEN(x) ((x) & BD_CTRL_BUFLEN_MASK)
-+#define BD_CTRL_CBD_INT_EN BIT(16)
-+#define BD_CTRL_PKT_INT_EN BIT(17)
-+#define BD_CTRL_LIFM BIT(18)
-+#define BD_CTRL_LAST_BD BIT(19)
-+#define BD_CTRL_DIR BIT(20)
-+#define BD_CTRL_LMEM_CPY BIT(21) /* Valid only for HIF_NOCPY */
-+#define BD_CTRL_PKT_XFER BIT(24)
-+#define BD_CTRL_DESC_EN BIT(31)
-+#define BD_CTRL_PARSE_DISABLE BIT(25)
-+#define BD_CTRL_BRFETCH_DISABLE BIT(26)
-+#define BD_CTRL_RTFETCH_DISABLE BIT(27)
-+
-+/* Buffer descriptor status bits*/
-+#define BD_STATUS_CONN_ID(x) ((x) & 0xffff)
-+#define BD_STATUS_DIR_PROC_ID BIT(16)
-+#define BD_STATUS_CONN_ID_EN BIT(17)
-+#define BD_STATUS_PE2PROC_ID(x) (((x) & 7) << 18)
-+#define BD_STATUS_LE_DATA BIT(21)
-+#define BD_STATUS_CHKSUM_EN BIT(22)
-+
-+/* HIF Buffer descriptor status bits */
-+#define DIR_PROC_ID BIT(16)
-+#define PROC_ID(id) ((id) << 18)
-+
-+#endif /* _HIF_H_ */
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/include/pfe/cbus/hif_nocpy.h
-@@ -0,0 +1,50 @@
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ *
-+ * 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 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.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
-+ */
-+
-+#ifndef _HIF_NOCPY_H_
-+#define _HIF_NOCPY_H_
-+
-+#define HIF_NOCPY_VERSION (HIF_NOCPY_BASE_ADDR + 0x00)
-+#define HIF_NOCPY_TX_CTRL (HIF_NOCPY_BASE_ADDR + 0x04)
-+#define HIF_NOCPY_TX_CURR_BD_ADDR (HIF_NOCPY_BASE_ADDR + 0x08)
-+#define HIF_NOCPY_TX_ALLOC (HIF_NOCPY_BASE_ADDR + 0x0c)
-+#define HIF_NOCPY_TX_BDP_ADDR (HIF_NOCPY_BASE_ADDR + 0x10)
-+#define HIF_NOCPY_TX_STATUS (HIF_NOCPY_BASE_ADDR + 0x14)
-+#define HIF_NOCPY_RX_CTRL (HIF_NOCPY_BASE_ADDR + 0x20)
-+#define HIF_NOCPY_RX_BDP_ADDR (HIF_NOCPY_BASE_ADDR + 0x24)
-+#define HIF_NOCPY_RX_STATUS (HIF_NOCPY_BASE_ADDR + 0x30)
-+#define HIF_NOCPY_INT_SRC (HIF_NOCPY_BASE_ADDR + 0x34)
-+#define HIF_NOCPY_INT_ENABLE (HIF_NOCPY_BASE_ADDR + 0x38)
-+#define HIF_NOCPY_POLL_CTRL (HIF_NOCPY_BASE_ADDR + 0x3c)
-+#define HIF_NOCPY_RX_CURR_BD_ADDR (HIF_NOCPY_BASE_ADDR + 0x40)
-+#define HIF_NOCPY_RX_ALLOC (HIF_NOCPY_BASE_ADDR + 0x44)
-+#define HIF_NOCPY_TX_DMA_STATUS (HIF_NOCPY_BASE_ADDR + 0x48)
-+#define HIF_NOCPY_RX_DMA_STATUS (HIF_NOCPY_BASE_ADDR + 0x4c)
-+#define HIF_NOCPY_RX_INQ0_PKTPTR (HIF_NOCPY_BASE_ADDR + 0x50)
-+#define HIF_NOCPY_RX_INQ1_PKTPTR (HIF_NOCPY_BASE_ADDR + 0x54)
-+#define HIF_NOCPY_TX_PORT_NO (HIF_NOCPY_BASE_ADDR + 0x60)
-+#define HIF_NOCPY_LMEM_ALLOC_ADDR (HIF_NOCPY_BASE_ADDR + 0x64)
-+#define HIF_NOCPY_CLASS_ADDR (HIF_NOCPY_BASE_ADDR + 0x68)
-+#define HIF_NOCPY_TMU_PORT0_ADDR (HIF_NOCPY_BASE_ADDR + 0x70)
-+#define HIF_NOCPY_TMU_PORT1_ADDR (HIF_NOCPY_BASE_ADDR + 0x74)
-+#define HIF_NOCPY_TMU_PORT2_ADDR (HIF_NOCPY_BASE_ADDR + 0x7c)
-+#define HIF_NOCPY_TMU_PORT3_ADDR (HIF_NOCPY_BASE_ADDR + 0x80)
-+#define HIF_NOCPY_TMU_PORT4_ADDR (HIF_NOCPY_BASE_ADDR + 0x84)
-+#define HIF_NOCPY_INT_COAL (HIF_NOCPY_BASE_ADDR + 0x90)
-+
-+#endif /* _HIF_NOCPY_H_ */
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/include/pfe/cbus/tmu_csr.h
-@@ -0,0 +1,168 @@
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ *
-+ * 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 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.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
-+ */
-+
-+#ifndef _TMU_CSR_H_
-+#define _TMU_CSR_H_
-+
-+#define TMU_VERSION (TMU_CSR_BASE_ADDR + 0x000)
-+#define TMU_INQ_WATERMARK (TMU_CSR_BASE_ADDR + 0x004)
-+#define TMU_PHY_INQ_PKTPTR (TMU_CSR_BASE_ADDR + 0x008)
-+#define TMU_PHY_INQ_PKTINFO (TMU_CSR_BASE_ADDR + 0x00c)
-+#define TMU_PHY_INQ_FIFO_CNT (TMU_CSR_BASE_ADDR + 0x010)
-+#define TMU_SYS_GENERIC_CONTROL (TMU_CSR_BASE_ADDR + 0x014)
-+#define TMU_SYS_GENERIC_STATUS (TMU_CSR_BASE_ADDR + 0x018)
-+#define TMU_SYS_GEN_CON0 (TMU_CSR_BASE_ADDR + 0x01c)
-+#define TMU_SYS_GEN_CON1 (TMU_CSR_BASE_ADDR + 0x020)
-+#define TMU_SYS_GEN_CON2 (TMU_CSR_BASE_ADDR + 0x024)
-+#define TMU_SYS_GEN_CON3 (TMU_CSR_BASE_ADDR + 0x028)
-+#define TMU_SYS_GEN_CON4 (TMU_CSR_BASE_ADDR + 0x02c)
-+#define TMU_TEQ_DISABLE_DROPCHK (TMU_CSR_BASE_ADDR + 0x030)
-+#define TMU_TEQ_CTRL (TMU_CSR_BASE_ADDR + 0x034)
-+#define TMU_TEQ_QCFG (TMU_CSR_BASE_ADDR + 0x038)
-+#define TMU_TEQ_DROP_STAT (TMU_CSR_BASE_ADDR + 0x03c)
-+#define TMU_TEQ_QAVG (TMU_CSR_BASE_ADDR + 0x040)
-+#define TMU_TEQ_WREG_PROB (TMU_CSR_BASE_ADDR + 0x044)
-+#define TMU_TEQ_TRANS_STAT (TMU_CSR_BASE_ADDR + 0x048)
-+#define TMU_TEQ_HW_PROB_CFG0 (TMU_CSR_BASE_ADDR + 0x04c)
-+#define TMU_TEQ_HW_PROB_CFG1 (TMU_CSR_BASE_ADDR + 0x050)
-+#define TMU_TEQ_HW_PROB_CFG2 (TMU_CSR_BASE_ADDR + 0x054)
-+#define TMU_TEQ_HW_PROB_CFG3 (TMU_CSR_BASE_ADDR + 0x058)
-+#define TMU_TEQ_HW_PROB_CFG4 (TMU_CSR_BASE_ADDR + 0x05c)
-+#define TMU_TEQ_HW_PROB_CFG5 (TMU_CSR_BASE_ADDR + 0x060)
-+#define TMU_TEQ_HW_PROB_CFG6 (TMU_CSR_BASE_ADDR + 0x064)
-+#define TMU_TEQ_HW_PROB_CFG7 (TMU_CSR_BASE_ADDR + 0x068)
-+#define TMU_TEQ_HW_PROB_CFG8 (TMU_CSR_BASE_ADDR + 0x06c)
-+#define TMU_TEQ_HW_PROB_CFG9 (TMU_CSR_BASE_ADDR + 0x070)
-+#define TMU_TEQ_HW_PROB_CFG10 (TMU_CSR_BASE_ADDR + 0x074)
-+#define TMU_TEQ_HW_PROB_CFG11 (TMU_CSR_BASE_ADDR + 0x078)
-+#define TMU_TEQ_HW_PROB_CFG12 (TMU_CSR_BASE_ADDR + 0x07c)
-+#define TMU_TEQ_HW_PROB_CFG13 (TMU_CSR_BASE_ADDR + 0x080)
-+#define TMU_TEQ_HW_PROB_CFG14 (TMU_CSR_BASE_ADDR + 0x084)
-+#define TMU_TEQ_HW_PROB_CFG15 (TMU_CSR_BASE_ADDR + 0x088)
-+#define TMU_TEQ_HW_PROB_CFG16 (TMU_CSR_BASE_ADDR + 0x08c)
-+#define TMU_TEQ_HW_PROB_CFG17 (TMU_CSR_BASE_ADDR + 0x090)
-+#define TMU_TEQ_HW_PROB_CFG18 (TMU_CSR_BASE_ADDR + 0x094)
-+#define TMU_TEQ_HW_PROB_CFG19 (TMU_CSR_BASE_ADDR + 0x098)
-+#define TMU_TEQ_HW_PROB_CFG20 (TMU_CSR_BASE_ADDR + 0x09c)
-+#define TMU_TEQ_HW_PROB_CFG21 (TMU_CSR_BASE_ADDR + 0x0a0)
-+#define TMU_TEQ_HW_PROB_CFG22 (TMU_CSR_BASE_ADDR + 0x0a4)
-+#define TMU_TEQ_HW_PROB_CFG23 (TMU_CSR_BASE_ADDR + 0x0a8)
-+#define TMU_TEQ_HW_PROB_CFG24 (TMU_CSR_BASE_ADDR + 0x0ac)
-+#define TMU_TEQ_HW_PROB_CFG25 (TMU_CSR_BASE_ADDR + 0x0b0)
-+#define TMU_TDQ_IIFG_CFG (TMU_CSR_BASE_ADDR + 0x0b4)
-+/* [9:0] Scheduler Enable for each of the scheduler in the TDQ.
-+ * This is a global Enable for all schedulers in PHY0
-+ */
-+#define TMU_TDQ0_SCH_CTRL (TMU_CSR_BASE_ADDR + 0x0b8)
-+
-+#define TMU_LLM_CTRL (TMU_CSR_BASE_ADDR + 0x0bc)
-+#define TMU_LLM_BASE_ADDR (TMU_CSR_BASE_ADDR + 0x0c0)
-+#define TMU_LLM_QUE_LEN (TMU_CSR_BASE_ADDR + 0x0c4)
-+#define TMU_LLM_QUE_HEADPTR (TMU_CSR_BASE_ADDR + 0x0c8)
-+#define TMU_LLM_QUE_TAILPTR (TMU_CSR_BASE_ADDR + 0x0cc)
-+#define TMU_LLM_QUE_DROPCNT (TMU_CSR_BASE_ADDR + 0x0d0)
-+#define TMU_INT_EN (TMU_CSR_BASE_ADDR + 0x0d4)
-+#define TMU_INT_SRC (TMU_CSR_BASE_ADDR + 0x0d8)
-+#define TMU_INQ_STAT (TMU_CSR_BASE_ADDR + 0x0dc)
-+#define TMU_CTRL (TMU_CSR_BASE_ADDR + 0x0e0)
-+
-+/* [31] Mem Access Command. 0 = Internal Memory Read, 1 = Internal memory
-+ * Write [27:24] Byte Enables of the Internal memory access [23:0] Address of
-+ * the internal memory. This address is used to access both the PM and DM of
-+ * all the PE's
-+ */
-+#define TMU_MEM_ACCESS_ADDR (TMU_CSR_BASE_ADDR + 0x0e4)
-+
-+/* Internal Memory Access Write Data */
-+#define TMU_MEM_ACCESS_WDATA (TMU_CSR_BASE_ADDR + 0x0e8)
-+/* Internal Memory Access Read Data. The commands are blocked
-+ * at the mem_access only
-+ */
-+#define TMU_MEM_ACCESS_RDATA (TMU_CSR_BASE_ADDR + 0x0ec)
-+
-+/* [31:0] PHY0 in queue address (must be initialized with one of the
-+ * xxx_INQ_PKTPTR cbus addresses)
-+ */
-+#define TMU_PHY0_INQ_ADDR (TMU_CSR_BASE_ADDR + 0x0f0)
-+/* [31:0] PHY1 in queue address (must be initialized with one of the
-+ * xxx_INQ_PKTPTR cbus addresses)
-+ */
-+#define TMU_PHY1_INQ_ADDR (TMU_CSR_BASE_ADDR + 0x0f4)
-+/* [31:0] PHY2 in queue address (must be initialized with one of the
-+ * xxx_INQ_PKTPTR cbus addresses)
-+ */
-+#define TMU_PHY2_INQ_ADDR (TMU_CSR_BASE_ADDR + 0x0f8)
-+/* [31:0] PHY3 in queue address (must be initialized with one of the
-+ * xxx_INQ_PKTPTR cbus addresses)
-+ */
-+#define TMU_PHY3_INQ_ADDR (TMU_CSR_BASE_ADDR + 0x0fc)
-+#define TMU_BMU_INQ_ADDR (TMU_CSR_BASE_ADDR + 0x100)
-+#define TMU_TX_CTRL (TMU_CSR_BASE_ADDR + 0x104)
-+
-+#define TMU_BUS_ACCESS_WDATA (TMU_CSR_BASE_ADDR + 0x108)
-+#define TMU_BUS_ACCESS (TMU_CSR_BASE_ADDR + 0x10c)
-+#define TMU_BUS_ACCESS_RDATA (TMU_CSR_BASE_ADDR + 0x110)
-+
-+#define TMU_PE_SYS_CLK_RATIO (TMU_CSR_BASE_ADDR + 0x114)
-+#define TMU_PE_STATUS (TMU_CSR_BASE_ADDR + 0x118)
-+#define TMU_TEQ_MAX_THRESHOLD (TMU_CSR_BASE_ADDR + 0x11c)
-+/* [31:0] PHY4 in queue address (must be initialized with one of the
-+ * xxx_INQ_PKTPTR cbus addresses)
-+ */
-+#define TMU_PHY4_INQ_ADDR (TMU_CSR_BASE_ADDR + 0x134)
-+/* [9:0] Scheduler Enable for each of the scheduler in the TDQ.
-+ * This is a global Enable for all schedulers in PHY1
-+ */
-+#define TMU_TDQ1_SCH_CTRL (TMU_CSR_BASE_ADDR + 0x138)
-+/* [9:0] Scheduler Enable for each of the scheduler in the TDQ.
-+ * This is a global Enable for all schedulers in PHY2
-+ */
-+#define TMU_TDQ2_SCH_CTRL (TMU_CSR_BASE_ADDR + 0x13c)
-+/* [9:0] Scheduler Enable for each of the scheduler in the TDQ.
-+ * This is a global Enable for all schedulers in PHY3
-+ */
-+#define TMU_TDQ3_SCH_CTRL (TMU_CSR_BASE_ADDR + 0x140)
-+#define TMU_BMU_BUF_SIZE (TMU_CSR_BASE_ADDR + 0x144)
-+/* [31:0] PHY5 in queue address (must be initialized with one of the
-+ * xxx_INQ_PKTPTR cbus addresses)
-+ */
-+#define TMU_PHY5_INQ_ADDR (TMU_CSR_BASE_ADDR + 0x148)
-+
-+#define SW_RESET BIT(0) /* Global software reset */
-+#define INQ_RESET BIT(2)
-+#define TEQ_RESET BIT(3)
-+#define TDQ_RESET BIT(4)
-+#define PE_RESET BIT(5)
-+#define MEM_INIT BIT(6)
-+#define MEM_INIT_DONE BIT(7)
-+#define LLM_INIT BIT(8)
-+#define LLM_INIT_DONE BIT(9)
-+#define ECC_MEM_INIT_DONE BIT(10)
-+
-+struct tmu_cfg {
-+ u32 pe_sys_clk_ratio;
-+ unsigned long llm_base_addr;
-+ u32 llm_queue_len;
-+};
-+
-+/* Not HW related for pfe_ctrl / pfe common defines */
-+#define DEFAULT_MAX_QDEPTH 80
-+#define DEFAULT_Q0_QDEPTH 511 /*We keep one large queue for host tx qos */
-+#define DEFAULT_TMU3_QDEPTH 127
-+
-+#endif /* _TMU_CSR_H_ */
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/include/pfe/cbus/util_csr.h
-@@ -0,0 +1,61 @@
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ *
-+ * 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 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.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
-+ */
-+
-+#ifndef _UTIL_CSR_H_
-+#define _UTIL_CSR_H_
-+
-+#define UTIL_VERSION (UTIL_CSR_BASE_ADDR + 0x000)
-+#define UTIL_TX_CTRL (UTIL_CSR_BASE_ADDR + 0x004)
-+#define UTIL_INQ_PKTPTR (UTIL_CSR_BASE_ADDR + 0x010)
-+
-+#define UTIL_HDR_SIZE (UTIL_CSR_BASE_ADDR + 0x014)
-+
-+#define UTIL_PE0_QB_DM_ADDR0 (UTIL_CSR_BASE_ADDR + 0x020)
-+#define UTIL_PE0_QB_DM_ADDR1 (UTIL_CSR_BASE_ADDR + 0x024)
-+#define UTIL_PE0_RO_DM_ADDR0 (UTIL_CSR_BASE_ADDR + 0x060)
-+#define UTIL_PE0_RO_DM_ADDR1 (UTIL_CSR_BASE_ADDR + 0x064)
-+
-+#define UTIL_MEM_ACCESS_ADDR (UTIL_CSR_BASE_ADDR + 0x100)
-+#define UTIL_MEM_ACCESS_WDATA (UTIL_CSR_BASE_ADDR + 0x104)
-+#define UTIL_MEM_ACCESS_RDATA (UTIL_CSR_BASE_ADDR + 0x108)
-+
-+#define UTIL_TM_INQ_ADDR (UTIL_CSR_BASE_ADDR + 0x114)
-+#define UTIL_PE_STATUS (UTIL_CSR_BASE_ADDR + 0x118)
-+
-+#define UTIL_PE_SYS_CLK_RATIO (UTIL_CSR_BASE_ADDR + 0x200)
-+#define UTIL_AFULL_THRES (UTIL_CSR_BASE_ADDR + 0x204)
-+#define UTIL_GAP_BETWEEN_READS (UTIL_CSR_BASE_ADDR + 0x208)
-+#define UTIL_MAX_BUF_CNT (UTIL_CSR_BASE_ADDR + 0x20c)
-+#define UTIL_TSQ_FIFO_THRES (UTIL_CSR_BASE_ADDR + 0x210)
-+#define UTIL_TSQ_MAX_CNT (UTIL_CSR_BASE_ADDR + 0x214)
-+#define UTIL_IRAM_DATA_0 (UTIL_CSR_BASE_ADDR + 0x218)
-+#define UTIL_IRAM_DATA_1 (UTIL_CSR_BASE_ADDR + 0x21c)
-+#define UTIL_IRAM_DATA_2 (UTIL_CSR_BASE_ADDR + 0x220)
-+#define UTIL_IRAM_DATA_3 (UTIL_CSR_BASE_ADDR + 0x224)
-+
-+#define UTIL_BUS_ACCESS_ADDR (UTIL_CSR_BASE_ADDR + 0x228)
-+#define UTIL_BUS_ACCESS_WDATA (UTIL_CSR_BASE_ADDR + 0x22c)
-+#define UTIL_BUS_ACCESS_RDATA (UTIL_CSR_BASE_ADDR + 0x230)
-+
-+#define UTIL_INQ_AFULL_THRES (UTIL_CSR_BASE_ADDR + 0x234)
-+
-+struct util_cfg {
-+ u32 pe_sys_clk_ratio;
-+};
-+
-+#endif /* _UTIL_CSR_H_ */
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/include/pfe/pfe.h
-@@ -0,0 +1,372 @@
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ *
-+ * 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 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.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
-+ */
-+
-+#ifndef _PFE_H_
-+#define _PFE_H_
-+
-+#include "cbus.h"
-+
-+#define CLASS_DMEM_BASE_ADDR(i) (0x00000000 | ((i) << 20))
-+/*
-+ * Only valid for mem access register interface
-+ */
-+#define CLASS_IMEM_BASE_ADDR(i) (0x00000000 | ((i) << 20))
-+#define CLASS_DMEM_SIZE 0x00002000
-+#define CLASS_IMEM_SIZE 0x00008000
-+
-+#define TMU_DMEM_BASE_ADDR(i) (0x00000000 + ((i) << 20))
-+/*
-+ * Only valid for mem access register interface
-+ */
-+#define TMU_IMEM_BASE_ADDR(i) (0x00000000 + ((i) << 20))
-+#define TMU_DMEM_SIZE 0x00000800
-+#define TMU_IMEM_SIZE 0x00002000
-+
-+#define UTIL_DMEM_BASE_ADDR 0x00000000
-+#define UTIL_DMEM_SIZE 0x00002000
-+
-+#define PE_LMEM_BASE_ADDR 0xc3010000
-+#define PE_LMEM_SIZE 0x8000
-+#define PE_LMEM_END (PE_LMEM_BASE_ADDR + PE_LMEM_SIZE)
-+
-+#define DMEM_BASE_ADDR 0x00000000
-+#define DMEM_SIZE 0x2000 /* TMU has less... */
-+#define DMEM_END (DMEM_BASE_ADDR + DMEM_SIZE)
-+
-+#define PMEM_BASE_ADDR 0x00010000
-+#define PMEM_SIZE 0x8000 /* TMU has less... */
-+#define PMEM_END (PMEM_BASE_ADDR + PMEM_SIZE)
-+
-+/* These check memory ranges from PE point of view/memory map */
-+#define IS_DMEM(addr, len) \
-+ ({ typeof(addr) addr_ = (addr); \
-+ ((unsigned long)(addr_) >= DMEM_BASE_ADDR) && \
-+ (((unsigned long)(addr_) + (len)) <= DMEM_END); })
-+
-+#define IS_PMEM(addr, len) \
-+ ({ typeof(addr) addr_ = (addr); \
-+ ((unsigned long)(addr_) >= PMEM_BASE_ADDR) && \
-+ (((unsigned long)(addr_) + (len)) <= PMEM_END); })
-+
-+#define IS_PE_LMEM(addr, len) \
-+ ({ typeof(addr) addr_ = (addr); \
-+ ((unsigned long)(addr_) >= \
-+ PE_LMEM_BASE_ADDR) && \
-+ (((unsigned long)(addr_) + \
-+ (len)) <= PE_LMEM_END); })
-+
-+#define IS_PFE_LMEM(addr, len) \
-+ ({ typeof(addr) addr_ = (addr); \
-+ ((unsigned long)(addr_) >= \
-+ CBUS_VIRT_TO_PFE(LMEM_BASE_ADDR)) && \
-+ (((unsigned long)(addr_) + (len)) <= \
-+ CBUS_VIRT_TO_PFE(LMEM_END)); })
-+
-+#define __IS_PHYS_DDR(addr, len) \
-+ ({ typeof(addr) addr_ = (addr); \
-+ ((unsigned long)(addr_) >= \
-+ DDR_PHYS_BASE_ADDR) && \
-+ (((unsigned long)(addr_) + (len)) <= \
-+ DDR_PHYS_END); })
-+
-+#define IS_PHYS_DDR(addr, len) __IS_PHYS_DDR(DDR_PFE_TO_PHYS(addr), len)
-+
-+/*
-+ * If using a run-time virtual address for the cbus base address use this code
-+ */
-+extern void *cbus_base_addr;
-+extern void *ddr_base_addr;
-+extern unsigned long ddr_phys_base_addr;
-+extern unsigned int ddr_size;
-+
-+#define CBUS_BASE_ADDR cbus_base_addr
-+#define DDR_PHYS_BASE_ADDR ddr_phys_base_addr
-+#define DDR_BASE_ADDR ddr_base_addr
-+#define DDR_SIZE ddr_size
-+
-+#define DDR_PHYS_END (DDR_PHYS_BASE_ADDR + DDR_SIZE)
-+
-+#define LS1012A_PFE_RESET_WA /*
-+ * PFE doesn't have global reset and re-init
-+ * should takecare few things to make PFE
-+ * functional after reset
-+ */
-+#define PFE_CBUS_PHYS_BASE_ADDR 0xc0000000 /* CBUS physical base address
-+ * as seen by PE's.
-+ */
-+/* CBUS physical base address as seen by PE's. */
-+#define PFE_CBUS_PHYS_BASE_ADDR_FROM_PFE 0xc0000000
-+
-+#define DDR_PHYS_TO_PFE(p) (((unsigned long int)(p)) & 0x7FFFFFFF)
-+#define DDR_PFE_TO_PHYS(p) (((unsigned long int)(p)) | 0x80000000)
-+#define CBUS_PHYS_TO_PFE(p) (((p) - PFE_CBUS_PHYS_BASE_ADDR) + \
-+ PFE_CBUS_PHYS_BASE_ADDR_FROM_PFE)
-+/* Translates to PFE address map */
-+
-+#define DDR_PHYS_TO_VIRT(p) (((p) - DDR_PHYS_BASE_ADDR) + DDR_BASE_ADDR)
-+#define DDR_VIRT_TO_PHYS(v) (((v) - DDR_BASE_ADDR) + DDR_PHYS_BASE_ADDR)
-+#define DDR_VIRT_TO_PFE(p) (DDR_PHYS_TO_PFE(DDR_VIRT_TO_PHYS(p)))
-+
-+#define CBUS_VIRT_TO_PFE(v) (((v) - CBUS_BASE_ADDR) + \
-+ PFE_CBUS_PHYS_BASE_ADDR)
-+#define CBUS_PFE_TO_VIRT(p) (((unsigned long int)(p) - \
-+ PFE_CBUS_PHYS_BASE_ADDR) + CBUS_BASE_ADDR)
-+
-+/* The below part of the code is used in QOS control driver from host */
-+#define TMU_APB_BASE_ADDR 0xc1000000 /* TMU base address seen by
-+ * pe's
-+ */
-+
-+enum {
-+ CLASS0_ID = 0,
-+ CLASS1_ID,
-+ CLASS2_ID,
-+ CLASS3_ID,
-+ CLASS4_ID,
-+ CLASS5_ID,
-+ TMU0_ID,
-+ TMU1_ID,
-+ TMU2_ID,
-+ TMU3_ID,
-+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
-+ UTIL_ID,
-+#endif
-+ MAX_PE
-+};
-+
-+#define CLASS_MASK (BIT(CLASS0_ID) | BIT(CLASS1_ID) |\
-+ BIT(CLASS2_ID) | BIT(CLASS3_ID) |\
-+ BIT(CLASS4_ID) | BIT(CLASS5_ID))
-+#define CLASS_MAX_ID CLASS5_ID
-+
-+#define TMU_MASK (BIT(TMU0_ID) | BIT(TMU1_ID) |\
-+ BIT(TMU3_ID))
-+
-+#define TMU_MAX_ID TMU3_ID
-+
-+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
-+#define UTIL_MASK BIT(UTIL_ID)
-+#endif
-+
-+struct pe_status {
-+ u32 cpu_state;
-+ u32 activity_counter;
-+ u32 rx;
-+ union {
-+ u32 tx;
-+ u32 tmu_qstatus;
-+ };
-+ u32 drop;
-+#if defined(CFG_PE_DEBUG)
-+ u32 debug_indicator;
-+ u32 debug[16];
-+#endif
-+} __aligned(16);
-+
-+struct pe_sync_mailbox {
-+ u32 stop;
-+ u32 stopped;
-+};
-+
-+/* Drop counter definitions */
-+
-+#define CLASS_NUM_DROP_COUNTERS 13
-+#define UTIL_NUM_DROP_COUNTERS 8
-+
-+/* PE information.
-+ * Structure containing PE's specific information. It is used to create
-+ * generic C functions common to all PE's.
-+ * Before using the library functions this structure needs to be initialized
-+ * with the different registers virtual addresses
-+ * (according to the ARM MMU mmaping). The default initialization supports a
-+ * virtual == physical mapping.
-+ */
-+struct pe_info {
-+ u32 dmem_base_addr; /* PE's dmem base address */
-+ u32 pmem_base_addr; /* PE's pmem base address */
-+ u32 pmem_size; /* PE's pmem size */
-+
-+ void *mem_access_wdata; /* PE's _MEM_ACCESS_WDATA register
-+ * address
-+ */
-+ void *mem_access_addr; /* PE's _MEM_ACCESS_ADDR register
-+ * address
-+ */
-+ void *mem_access_rdata; /* PE's _MEM_ACCESS_RDATA register
-+ * address
-+ */
-+};
-+
-+void pe_lmem_read(u32 *dst, u32 len, u32 offset);
-+void pe_lmem_write(u32 *src, u32 len, u32 offset);
-+
-+void pe_dmem_memcpy_to32(int id, u32 dst, const void *src, unsigned int len);
-+void pe_pmem_memcpy_to32(int id, u32 dst, const void *src, unsigned int len);
-+
-+u32 pe_pmem_read(int id, u32 addr, u8 size);
-+
-+void pe_dmem_write(int id, u32 val, u32 addr, u8 size);
-+u32 pe_dmem_read(int id, u32 addr, u8 size);
-+void class_pe_lmem_memcpy_to32(u32 dst, const void *src, unsigned int len);
-+void class_pe_lmem_memset(u32 dst, int val, unsigned int len);
-+void class_bus_write(u32 val, u32 addr, u8 size);
-+u32 class_bus_read(u32 addr, u8 size);
-+
-+#define class_bus_readl(addr) class_bus_read(addr, 4)
-+#define class_bus_readw(addr) class_bus_read(addr, 2)
-+#define class_bus_readb(addr) class_bus_read(addr, 1)
-+
-+#define class_bus_writel(val, addr) class_bus_write(val, addr, 4)
-+#define class_bus_writew(val, addr) class_bus_write(val, addr, 2)
-+#define class_bus_writeb(val, addr) class_bus_write(val, addr, 1)
-+
-+#define pe_dmem_readl(id, addr) pe_dmem_read(id, addr, 4)
-+#define pe_dmem_readw(id, addr) pe_dmem_read(id, addr, 2)
-+#define pe_dmem_readb(id, addr) pe_dmem_read(id, addr, 1)
-+
-+#define pe_dmem_writel(id, val, addr) pe_dmem_write(id, val, addr, 4)
-+#define pe_dmem_writew(id, val, addr) pe_dmem_write(id, val, addr, 2)
-+#define pe_dmem_writeb(id, val, addr) pe_dmem_write(id, val, addr, 1)
-+
-+/*int pe_load_elf_section(int id, const void *data, elf32_shdr *shdr); */
-+int pe_load_elf_section(int id, const void *data, struct elf32_shdr *shdr,
-+ struct device *dev);
-+
-+void pfe_lib_init(void *cbus_base, void *ddr_base, unsigned long ddr_phys_base,
-+ unsigned int ddr_size);
-+void bmu_init(void *base, struct BMU_CFG *cfg);
-+void bmu_reset(void *base);
-+void bmu_enable(void *base);
-+void bmu_disable(void *base);
-+void bmu_set_config(void *base, struct BMU_CFG *cfg);
-+
-+/*
-+ * An enumerated type for loopback values. This can be one of three values, no
-+ * loopback -normal operation, local loopback with internal loopback module of
-+ * MAC or PHY loopback which is through the external PHY.
-+ */
-+#ifndef __MAC_LOOP_ENUM__
-+#define __MAC_LOOP_ENUM__
-+enum mac_loop {LB_NONE, LB_EXT, LB_LOCAL};
-+#endif
-+
-+void gemac_init(void *base, void *config);
-+void gemac_disable_rx_checksum_offload(void *base);
-+void gemac_enable_rx_checksum_offload(void *base);
-+void gemac_set_speed(void *base, enum mac_speed gem_speed);
-+void gemac_set_duplex(void *base, int duplex);
-+void gemac_set_mode(void *base, int mode);
-+void gemac_enable(void *base);
-+void gemac_tx_disable(void *base);
-+void gemac_tx_enable(void *base);
-+void gemac_disable(void *base);
-+void gemac_reset(void *base);
-+void gemac_set_address(void *base, struct spec_addr *addr);
-+struct spec_addr gemac_get_address(void *base);
-+void gemac_set_loop(void *base, enum mac_loop gem_loop);
-+void gemac_set_laddr1(void *base, struct pfe_mac_addr *address);
-+void gemac_set_laddr2(void *base, struct pfe_mac_addr *address);
-+void gemac_set_laddr3(void *base, struct pfe_mac_addr *address);
-+void gemac_set_laddr4(void *base, struct pfe_mac_addr *address);
-+void gemac_set_laddrN(void *base, struct pfe_mac_addr *address,
-+ unsigned int entry_index);
-+void gemac_clear_laddr1(void *base);
-+void gemac_clear_laddr2(void *base);
-+void gemac_clear_laddr3(void *base);
-+void gemac_clear_laddr4(void *base);
-+void gemac_clear_laddrN(void *base, unsigned int entry_index);
-+struct pfe_mac_addr gemac_get_hash(void *base);
-+void gemac_set_hash(void *base, struct pfe_mac_addr *hash);
-+struct pfe_mac_addr gem_get_laddr1(void *base);
-+struct pfe_mac_addr gem_get_laddr2(void *base);
-+struct pfe_mac_addr gem_get_laddr3(void *base);
-+struct pfe_mac_addr gem_get_laddr4(void *base);
-+struct pfe_mac_addr gem_get_laddrN(void *base, unsigned int entry_index);
-+void gemac_set_config(void *base, struct gemac_cfg *cfg);
-+void gemac_allow_broadcast(void *base);
-+void gemac_no_broadcast(void *base);
-+void gemac_enable_1536_rx(void *base);
-+void gemac_disable_1536_rx(void *base);
-+void gemac_set_rx_max_fl(void *base, int mtu);
-+void gemac_enable_rx_jmb(void *base);
-+void gemac_disable_rx_jmb(void *base);
-+void gemac_enable_stacked_vlan(void *base);
-+void gemac_disable_stacked_vlan(void *base);
-+void gemac_enable_pause_rx(void *base);
-+void gemac_disable_pause_rx(void *base);
-+void gemac_enable_copy_all(void *base);
-+void gemac_disable_copy_all(void *base);
-+void gemac_set_bus_width(void *base, int width);
-+void gemac_set_wol(void *base, u32 wol_conf);
-+
-+void gpi_init(void *base, struct gpi_cfg *cfg);
-+void gpi_reset(void *base);
-+void gpi_enable(void *base);
-+void gpi_disable(void *base);
-+void gpi_set_config(void *base, struct gpi_cfg *cfg);
-+
-+void class_init(struct class_cfg *cfg);
-+void class_reset(void);
-+void class_enable(void);
-+void class_disable(void);
-+void class_set_config(struct class_cfg *cfg);
-+
-+void tmu_reset(void);
-+void tmu_init(struct tmu_cfg *cfg);
-+void tmu_enable(u32 pe_mask);
-+void tmu_disable(u32 pe_mask);
-+u32 tmu_qstatus(u32 if_id);
-+u32 tmu_pkts_processed(u32 if_id);
-+
-+void util_init(struct util_cfg *cfg);
-+void util_reset(void);
-+void util_enable(void);
-+void util_disable(void);
-+
-+void hif_init(void);
-+void hif_tx_enable(void);
-+void hif_tx_disable(void);
-+void hif_rx_enable(void);
-+void hif_rx_disable(void);
-+
-+/* Get Chip Revision level
-+ *
-+ */
-+static inline unsigned int CHIP_REVISION(void)
-+{
-+ /*For LS1012A return always 1 */
-+ return 1;
-+}
-+
-+/* Start HIF rx DMA
-+ *
-+ */
-+static inline void hif_rx_dma_start(void)
-+{
-+ writel(HIF_CTRL_DMA_EN | HIF_CTRL_BDP_CH_START_WSTB, HIF_RX_CTRL);
-+}
-+
-+/* Start HIF tx DMA
-+ *
-+ */
-+static inline void hif_tx_dma_start(void)
-+{
-+ writel(HIF_CTRL_DMA_EN | HIF_CTRL_BDP_CH_START_WSTB, HIF_TX_CTRL);
-+}
-+
-+#endif /* _PFE_H_ */
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/pfe_cdev.c
-@@ -0,0 +1,258 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+/*
-+ * Copyright 2018 NXP
-+ */
-+
-+/* @pfe_cdev.c.
-+ * Dummy device representing the PFE US in userspace.
-+ * - used for interacting with the kernel layer for link status
-+ */
-+
-+#include <linux/eventfd.h>
-+#include <linux/irqreturn.h>
-+#include <linux/io.h>
-+#include <asm/irq.h>
-+
-+#include "pfe_cdev.h"
-+#include "pfe_mod.h"
-+
-+static int pfe_majno;
-+static struct class *pfe_char_class;
-+static struct device *pfe_char_dev;
-+struct eventfd_ctx *g_trigger;
-+
-+struct pfe_shared_info link_states[PFE_CDEV_ETH_COUNT];
-+
-+static int pfe_cdev_open(struct inode *inp, struct file *fp)
-+{
-+ pr_debug("PFE CDEV device opened.\n");
-+ return 0;
-+}
-+
-+static ssize_t pfe_cdev_read(struct file *fp, char *buf,
-+ size_t len, loff_t *off)
-+{
-+ int ret = 0;
-+
-+ pr_info("PFE CDEV attempt copying (%lu) size of user.\n",
-+ sizeof(link_states));
-+
-+ pr_debug("Dump link_state on screen before copy_to_user\n");
-+ for (; ret < PFE_CDEV_ETH_COUNT; ret++) {
-+ pr_debug("%u %u", link_states[ret].phy_id,
-+ link_states[ret].state);
-+ pr_debug("\n");
-+ }
-+
-+ /* Copy to user the value in buffer sized len */
-+ ret = copy_to_user(buf, &link_states, sizeof(link_states));
-+ if (ret != 0) {
-+ pr_err("Failed to send (%d)bytes of (%lu) requested.\n",
-+ ret, len);
-+ return -EFAULT;
-+ }
-+
-+ /* offset set back to 0 as there is contextual reading offset */
-+ *off = 0;
-+ pr_debug("Read of (%lu) bytes performed.\n", sizeof(link_states));
-+
-+ return sizeof(link_states);
-+}
-+
-+/**
-+ * This function is for getting some commands from user through non-IOCTL
-+ * channel. It can used to configure the device.
-+ * TODO: To be filled in future, if require duplex communication with user
-+ * space.
-+ */
-+static ssize_t pfe_cdev_write(struct file *fp, const char *buf,
-+ size_t len, loff_t *off)
-+{
-+ pr_info("PFE CDEV Write operation not supported!\n");
-+
-+ return -EFAULT;
-+}
-+
-+static int pfe_cdev_release(struct inode *inp, struct file *fp)
-+{
-+ if (g_trigger) {
-+ free_irq(pfe->hif_irq, g_trigger);
-+ eventfd_ctx_put(g_trigger);
-+ g_trigger = NULL;
-+ }
-+
-+ pr_info("PFE_CDEV: Device successfully closed\n");
-+ return 0;
-+}
-+
-+/*
-+ * hif_us_isr-
-+ * This ISR routine processes Rx/Tx done interrupts from the HIF hardware block
-+ */
-+static irqreturn_t hif_us_isr(int irq, void *arg)
-+{
-+ struct eventfd_ctx *trigger = (struct eventfd_ctx *)arg;
-+ int int_status;
-+ int int_enable_mask;
-+
-+ /*Read hif interrupt source register */
-+ int_status = readl_relaxed(HIF_INT_SRC);
-+ int_enable_mask = readl_relaxed(HIF_INT_ENABLE);
-+
-+ if ((int_status & HIF_INT) == 0)
-+ return IRQ_NONE;
-+
-+ if (int_status & HIF_RXPKT_INT) {
-+ int_enable_mask &= ~(HIF_RXPKT_INT);
-+ /* Disable interrupts, they will be enabled after
-+ * they are serviced
-+ */
-+ writel_relaxed(int_enable_mask, HIF_INT_ENABLE);
-+
-+ eventfd_signal(trigger, 1);
-+ }
-+
-+ return IRQ_HANDLED;
-+}
-+
-+#define PFE_INTR_COAL_USECS 100
-+static long pfe_cdev_ioctl(struct file *fp, unsigned int cmd,
-+ unsigned long arg)
-+{
-+ int ret = -EFAULT;
-+ int __user *argp = (int __user *)arg;
-+
-+ pr_debug("PFE CDEV IOCTL Called with cmd=(%u)\n", cmd);
-+
-+ switch (cmd) {
-+ case PFE_CDEV_ETH0_STATE_GET:
-+ /* Return an unsigned int (link state) for ETH0 */
-+ *argp = link_states[0].state;
-+ pr_debug("Returning state=%d for ETH0\n", *argp);
-+ ret = 0;
-+ break;
-+ case PFE_CDEV_ETH1_STATE_GET:
-+ /* Return an unsigned int (link state) for ETH0 */
-+ *argp = link_states[1].state;
-+ pr_debug("Returning state=%d for ETH1\n", *argp);
-+ ret = 0;
-+ break;
-+ case PFE_CDEV_HIF_INTR_EN:
-+ /* Return success/failure */
-+ g_trigger = eventfd_ctx_fdget(*argp);
-+ if (IS_ERR(g_trigger))
-+ return PTR_ERR(g_trigger);
-+ ret = request_irq(pfe->hif_irq, hif_us_isr, 0, "pfe_hif",
-+ g_trigger);
-+ if (ret) {
-+ pr_err("%s: failed to get the hif IRQ = %d\n",
-+ __func__, pfe->hif_irq);
-+ eventfd_ctx_put(g_trigger);
-+ g_trigger = NULL;
-+ }
-+ writel((PFE_INTR_COAL_USECS * (pfe->ctrl.sys_clk / 1000)) |
-+ HIF_INT_COAL_ENABLE, HIF_INT_COAL);
-+
-+ pr_debug("request_irq for hif interrupt: %d\n", pfe->hif_irq);
-+ ret = 0;
-+ break;
-+ default:
-+ pr_info("Unsupport cmd (%d) for PFE CDEV.\n", cmd);
-+ break;
-+ };
-+
-+ return ret;
-+}
-+
-+static unsigned int pfe_cdev_poll(struct file *fp,
-+ struct poll_table_struct *wait)
-+{
-+ pr_info("PFE CDEV poll method not supported\n");
-+ return 0;
-+}
-+
-+static const struct file_operations pfe_cdev_fops = {
-+ .open = pfe_cdev_open,
-+ .read = pfe_cdev_read,
-+ .write = pfe_cdev_write,
-+ .release = pfe_cdev_release,
-+ .unlocked_ioctl = pfe_cdev_ioctl,
-+ .poll = pfe_cdev_poll,
-+};
-+
-+int pfe_cdev_init(void)
-+{
-+ int ret;
-+
-+ pr_debug("PFE CDEV initialization begin\n");
-+
-+ /* Register the major number for the device */
-+ pfe_majno = register_chrdev(0, PFE_CDEV_NAME, &pfe_cdev_fops);
-+ if (pfe_majno < 0) {
-+ pr_err("Unable to register PFE CDEV. PFE CDEV not available\n");
-+ ret = pfe_majno;
-+ goto cleanup;
-+ }
-+
-+ pr_debug("PFE CDEV assigned major number: %d\n", pfe_majno);
-+
-+ /* Register the class for the device */
-+ pfe_char_class = class_create(THIS_MODULE, PFE_CLASS_NAME);
-+ if (IS_ERR(pfe_char_class)) {
-+ pr_err(
-+ "Failed to init class for PFE CDEV. PFE CDEV not available.\n");
-+ ret = PTR_ERR(pfe_char_class);
-+ goto cleanup;
-+ }
-+
-+ pr_debug("PFE CDEV Class created successfully.\n");
-+
-+ /* Create the device without any parent and without any callback data */
-+ pfe_char_dev = device_create(pfe_char_class, NULL,
-+ MKDEV(pfe_majno, 0), NULL,
-+ PFE_CDEV_NAME);
-+ if (IS_ERR(pfe_char_dev)) {
-+ pr_err("Unable to PFE CDEV device. PFE CDEV not available.\n");
-+ ret = PTR_ERR(pfe_char_dev);
-+ goto cleanup;
-+ }
-+
-+ /* Information structure being shared with the userspace */
-+ memset(link_states, 0, sizeof(struct pfe_shared_info) *
-+ PFE_CDEV_ETH_COUNT);
-+
-+ pr_info("PFE CDEV created: %s\n", PFE_CDEV_NAME);
-+
-+ ret = 0;
-+ return ret;
-+
-+cleanup:
-+ if (!IS_ERR(pfe_char_class))
-+ class_destroy(pfe_char_class);
-+
-+ if (pfe_majno > 0)
-+ unregister_chrdev(pfe_majno, PFE_CDEV_NAME);
-+
-+ return ret;
-+}
-+
-+void pfe_cdev_exit(void)
-+{
-+ if (!IS_ERR(pfe_char_dev))
-+ device_destroy(pfe_char_class, MKDEV(pfe_majno, 0));
-+
-+ if (!IS_ERR(pfe_char_class)) {
-+ class_unregister(pfe_char_class);
-+ class_destroy(pfe_char_class);
-+ }
-+
-+ if (pfe_majno > 0)
-+ unregister_chrdev(pfe_majno, PFE_CDEV_NAME);
-+
-+ /* reset the variables */
-+ pfe_majno = 0;
-+ pfe_char_class = NULL;
-+ pfe_char_dev = NULL;
-+
-+ pr_info("PFE CDEV Removed.\n");
-+}
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/pfe_cdev.h
-@@ -0,0 +1,41 @@
-+/* SPDX-License-Identifier: GPL-2.0+ */
-+/*
-+ * Copyright 2018 NXP
-+ */
-+
-+#ifndef _PFE_CDEV_H_
-+#define _PFE_CDEV_H_
-+
-+#include <linux/init.h>
-+#include <linux/device.h>
-+#include <linux/err.h>
-+#include <linux/kernel.h>
-+#include <linux/fs.h>
-+#include <linux/uaccess.h>
-+#include <linux/poll.h>
-+
-+#define PFE_CDEV_NAME "pfe_us_cdev"
-+#define PFE_CLASS_NAME "ppfe_us"
-+
-+/* Extracted from ls1012a_pfe_platform_data, there are 3 interfaces which are
-+ * supported by PFE driver. Should be updated if number of eth devices are
-+ * changed.
-+ */
-+#define PFE_CDEV_ETH_COUNT 3
-+
-+struct pfe_shared_info {
-+ uint32_t phy_id; /* Link phy ID */
-+ uint8_t state; /* Has either 0 or 1 */
-+};
-+
-+extern struct pfe_shared_info link_states[PFE_CDEV_ETH_COUNT];
-+
-+/* IOCTL Commands */
-+#define PFE_CDEV_ETH0_STATE_GET _IOR('R', 0, int)
-+#define PFE_CDEV_ETH1_STATE_GET _IOR('R', 1, int)
-+#define PFE_CDEV_HIF_INTR_EN _IOWR('R', 2, int)
-+
-+int pfe_cdev_init(void);
-+void pfe_cdev_exit(void);
-+
-+#endif /* _PFE_CDEV_H_ */
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/pfe_ctrl.c
-@@ -0,0 +1,226 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <linux/module.h>
-+#include <linux/list.h>
-+#include <linux/kthread.h>
-+
-+#include "pfe_mod.h"
-+#include "pfe_ctrl.h"
-+
-+#define TIMEOUT_MS 1000
-+
-+int relax(unsigned long end)
-+{
-+ if (time_after(jiffies, end)) {
-+ if (time_after(jiffies, end + (TIMEOUT_MS * HZ) / 1000))
-+ return -1;
-+
-+ if (need_resched())
-+ schedule();
-+ }
-+
-+ return 0;
-+}
-+
-+void pfe_ctrl_suspend(struct pfe_ctrl *ctrl)
-+{
-+ int id;
-+
-+ mutex_lock(&ctrl->mutex);
-+
-+ for (id = CLASS0_ID; id <= CLASS_MAX_ID; id++)
-+ pe_dmem_write(id, cpu_to_be32(0x1), CLASS_DM_RESUME, 4);
-+
-+ for (id = TMU0_ID; id <= TMU_MAX_ID; id++) {
-+ if (id == TMU2_ID)
-+ continue;
-+ pe_dmem_write(id, cpu_to_be32(0x1), TMU_DM_RESUME, 4);
-+ }
-+
-+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
-+ pe_dmem_write(UTIL_ID, cpu_to_be32(0x1), UTIL_DM_RESUME, 4);
-+#endif
-+ mutex_unlock(&ctrl->mutex);
-+}
-+
-+void pfe_ctrl_resume(struct pfe_ctrl *ctrl)
-+{
-+ int pe_mask = CLASS_MASK | TMU_MASK;
-+
-+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
-+ pe_mask |= UTIL_MASK;
-+#endif
-+ mutex_lock(&ctrl->mutex);
-+ pe_start(&pfe->ctrl, pe_mask);
-+ mutex_unlock(&ctrl->mutex);
-+}
-+
-+/* PE sync stop.
-+ * Stops packet processing for a list of PE's (specified using a bitmask).
-+ * The caller must hold ctrl->mutex.
-+ *
-+ * @param ctrl Control context
-+ * @param pe_mask Mask of PE id's to stop
-+ *
-+ */
-+int pe_sync_stop(struct pfe_ctrl *ctrl, int pe_mask)
-+{
-+ struct pe_sync_mailbox *mbox;
-+ int pe_stopped = 0;
-+ unsigned long end = jiffies + 2;
-+ int i;
-+
-+ pe_mask &= 0x2FF; /*Exclude Util + TMU2 */
-+
-+ for (i = 0; i < MAX_PE; i++)
-+ if (pe_mask & (1 << i)) {
-+ mbox = (void *)ctrl->sync_mailbox_baseaddr[i];
-+
-+ pe_dmem_write(i, cpu_to_be32(0x1), (unsigned
-+ long)&mbox->stop, 4);
-+ }
-+
-+ while (pe_stopped != pe_mask) {
-+ for (i = 0; i < MAX_PE; i++)
-+ if ((pe_mask & (1 << i)) && !(pe_stopped & (1 << i))) {
-+ mbox = (void *)ctrl->sync_mailbox_baseaddr[i];
-+
-+ if (pe_dmem_read(i, (unsigned
-+ long)&mbox->stopped, 4) &
-+ cpu_to_be32(0x1))
-+ pe_stopped |= (1 << i);
-+ }
-+
-+ if (relax(end) < 0)
-+ goto err;
-+ }
-+
-+ return 0;
-+
-+err:
-+ pr_err("%s: timeout, %x %x\n", __func__, pe_mask, pe_stopped);
-+
-+ for (i = 0; i < MAX_PE; i++)
-+ if (pe_mask & (1 << i)) {
-+ mbox = (void *)ctrl->sync_mailbox_baseaddr[i];
-+
-+ pe_dmem_write(i, cpu_to_be32(0x0), (unsigned
-+ long)&mbox->stop, 4);
-+ }
-+
-+ return -EIO;
-+}
-+
-+/* PE start.
-+ * Starts packet processing for a list of PE's (specified using a bitmask).
-+ * The caller must hold ctrl->mutex.
-+ *
-+ * @param ctrl Control context
-+ * @param pe_mask Mask of PE id's to start
-+ *
-+ */
-+void pe_start(struct pfe_ctrl *ctrl, int pe_mask)
-+{
-+ struct pe_sync_mailbox *mbox;
-+ int i;
-+
-+ for (i = 0; i < MAX_PE; i++)
-+ if (pe_mask & (1 << i)) {
-+ mbox = (void *)ctrl->sync_mailbox_baseaddr[i];
-+
-+ pe_dmem_write(i, cpu_to_be32(0x0), (unsigned
-+ long)&mbox->stop, 4);
-+ }
-+}
-+
-+/* This function will ensure all PEs are put in to idle state */
-+int pe_reset_all(struct pfe_ctrl *ctrl)
-+{
-+ struct pe_sync_mailbox *mbox;
-+ int pe_stopped = 0;
-+ unsigned long end = jiffies + 2;
-+ int i;
-+ int pe_mask = CLASS_MASK | TMU_MASK;
-+
-+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
-+ pe_mask |= UTIL_MASK;
-+#endif
-+
-+ for (i = 0; i < MAX_PE; i++)
-+ if (pe_mask & (1 << i)) {
-+ mbox = (void *)ctrl->sync_mailbox_baseaddr[i];
-+
-+ pe_dmem_write(i, cpu_to_be32(0x2), (unsigned
-+ long)&mbox->stop, 4);
-+ }
-+
-+ while (pe_stopped != pe_mask) {
-+ for (i = 0; i < MAX_PE; i++)
-+ if ((pe_mask & (1 << i)) && !(pe_stopped & (1 << i))) {
-+ mbox = (void *)ctrl->sync_mailbox_baseaddr[i];
-+
-+ if (pe_dmem_read(i, (unsigned long)
-+ &mbox->stopped, 4) &
-+ cpu_to_be32(0x1))
-+ pe_stopped |= (1 << i);
-+ }
-+
-+ if (relax(end) < 0)
-+ goto err;
-+ }
-+
-+ return 0;
-+
-+err:
-+ pr_err("%s: timeout, %x %x\n", __func__, pe_mask, pe_stopped);
-+ return -EIO;
-+}
-+
-+int pfe_ctrl_init(struct pfe *pfe)
-+{
-+ struct pfe_ctrl *ctrl = &pfe->ctrl;
-+ int id;
-+
-+ pr_info("%s\n", __func__);
-+
-+ mutex_init(&ctrl->mutex);
-+ spin_lock_init(&ctrl->lock);
-+
-+ for (id = CLASS0_ID; id <= CLASS_MAX_ID; id++) {
-+ ctrl->sync_mailbox_baseaddr[id] = CLASS_DM_SYNC_MBOX;
-+ ctrl->msg_mailbox_baseaddr[id] = CLASS_DM_MSG_MBOX;
-+ }
-+
-+ for (id = TMU0_ID; id <= TMU_MAX_ID; id++) {
-+ if (id == TMU2_ID)
-+ continue;
-+ ctrl->sync_mailbox_baseaddr[id] = TMU_DM_SYNC_MBOX;
-+ ctrl->msg_mailbox_baseaddr[id] = TMU_DM_MSG_MBOX;
-+ }
-+
-+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
-+ ctrl->sync_mailbox_baseaddr[UTIL_ID] = UTIL_DM_SYNC_MBOX;
-+ ctrl->msg_mailbox_baseaddr[UTIL_ID] = UTIL_DM_MSG_MBOX;
-+#endif
-+
-+ ctrl->hash_array_baseaddr = pfe->ddr_baseaddr + ROUTE_TABLE_BASEADDR;
-+ ctrl->hash_array_phys_baseaddr = pfe->ddr_phys_baseaddr +
-+ ROUTE_TABLE_BASEADDR;
-+
-+ ctrl->dev = pfe->dev;
-+
-+ pr_info("%s finished\n", __func__);
-+
-+ return 0;
-+}
-+
-+void pfe_ctrl_exit(struct pfe *pfe)
-+{
-+ pr_info("%s\n", __func__);
-+}
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/pfe_ctrl.h
-@@ -0,0 +1,100 @@
-+/* SPDX-License-Identifier: GPL-2.0+ */
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ */
-+
-+#ifndef _PFE_CTRL_H_
-+#define _PFE_CTRL_H_
-+
-+#include <linux/dmapool.h>
-+
-+#include "pfe/pfe.h"
-+
-+#define DMA_BUF_SIZE_128 0x80 /* enough for 1 conntracks */
-+#define DMA_BUF_SIZE_256 0x100
-+/* enough for 2 conntracks, 1 bridge entry or 1 multicast entry */
-+#define DMA_BUF_SIZE_512 0x200
-+/* 512bytes dma allocated buffers used by rtp relay feature */
-+#define DMA_BUF_MIN_ALIGNMENT 8
-+#define DMA_BUF_BOUNDARY (4 * 1024)
-+/* bursts can not cross 4k boundary */
-+
-+#define CMD_TX_ENABLE 0x0501
-+#define CMD_TX_DISABLE 0x0502
-+
-+#define CMD_RX_LRO 0x0011
-+#define CMD_PKTCAP_ENABLE 0x0d01
-+#define CMD_QM_EXPT_RATE 0x020c
-+
-+#define CLASS_DM_SH_STATIC (0x800)
-+#define CLASS_DM_CPU_TICKS (CLASS_DM_SH_STATIC)
-+#define CLASS_DM_SYNC_MBOX (0x808)
-+#define CLASS_DM_MSG_MBOX (0x810)
-+#define CLASS_DM_DROP_CNTR (0x820)
-+#define CLASS_DM_RESUME (0x854)
-+#define CLASS_DM_PESTATUS (0x860)
-+#define CLASS_DM_CRC_VALIDATED (0x14b0)
-+
-+#define TMU_DM_SH_STATIC (0x80)
-+#define TMU_DM_CPU_TICKS (TMU_DM_SH_STATIC)
-+#define TMU_DM_SYNC_MBOX (0x88)
-+#define TMU_DM_MSG_MBOX (0x90)
-+#define TMU_DM_RESUME (0xA0)
-+#define TMU_DM_PESTATUS (0xB0)
-+#define TMU_DM_CONTEXT (0x300)
-+#define TMU_DM_TX_TRANS (0x480)
-+
-+#define UTIL_DM_SH_STATIC (0x0)
-+#define UTIL_DM_CPU_TICKS (UTIL_DM_SH_STATIC)
-+#define UTIL_DM_SYNC_MBOX (0x8)
-+#define UTIL_DM_MSG_MBOX (0x10)
-+#define UTIL_DM_DROP_CNTR (0x20)
-+#define UTIL_DM_RESUME (0x40)
-+#define UTIL_DM_PESTATUS (0x50)
-+
-+struct pfe_ctrl {
-+ struct mutex mutex; /* to serialize pfe control access */
-+ spinlock_t lock;
-+
-+ void *dma_pool;
-+ void *dma_pool_512;
-+ void *dma_pool_128;
-+
-+ struct device *dev;
-+
-+ void *hash_array_baseaddr; /*
-+ * Virtual base address of
-+ * the conntrack hash array
-+ */
-+ unsigned long hash_array_phys_baseaddr; /*
-+ * Physical base address of
-+ * the conntrack hash array
-+ */
-+
-+ int (*event_cb)(u16, u16, u16*);
-+
-+ unsigned long sync_mailbox_baseaddr[MAX_PE]; /*
-+ * Sync mailbox PFE
-+ * internal address,
-+ * initialized
-+ * when parsing elf images
-+ */
-+ unsigned long msg_mailbox_baseaddr[MAX_PE]; /*
-+ * Msg mailbox PFE internal
-+ * address, initialized
-+ * when parsing elf images
-+ */
-+ unsigned int sys_clk; /* AXI clock value, in KHz */
-+};
-+
-+int pfe_ctrl_init(struct pfe *pfe);
-+void pfe_ctrl_exit(struct pfe *pfe);
-+int pe_sync_stop(struct pfe_ctrl *ctrl, int pe_mask);
-+void pe_start(struct pfe_ctrl *ctrl, int pe_mask);
-+int pe_reset_all(struct pfe_ctrl *ctrl);
-+void pfe_ctrl_suspend(struct pfe_ctrl *ctrl);
-+void pfe_ctrl_resume(struct pfe_ctrl *ctrl);
-+int relax(unsigned long end);
-+
-+#endif /* _PFE_CTRL_H_ */
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/pfe_debugfs.c
-@@ -0,0 +1,99 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/debugfs.h>
-+#include <linux/platform_device.h>
-+
-+#include "pfe_mod.h"
-+
-+static int dmem_show(struct seq_file *s, void *unused)
-+{
-+ u32 dmem_addr, val;
-+ int id = (long int)s->private;
-+ int i;
-+
-+ for (dmem_addr = 0; dmem_addr < CLASS_DMEM_SIZE; dmem_addr += 8 * 4) {
-+ seq_printf(s, "%04x:", dmem_addr);
-+
-+ for (i = 0; i < 8; i++) {
-+ val = pe_dmem_read(id, dmem_addr + i * 4, 4);
-+ seq_printf(s, " %02x %02x %02x %02x", val & 0xff,
-+ (val >> 8) & 0xff, (val >> 16) & 0xff,
-+ (val >> 24) & 0xff);
-+ }
-+
-+ seq_puts(s, "\n");
-+ }
-+
-+ return 0;
-+}
-+
-+static int dmem_open(struct inode *inode, struct file *file)
-+{
-+ return single_open(file, dmem_show, inode->i_private);
-+}
-+
-+static const struct file_operations dmem_fops = {
-+ .open = dmem_open,
-+ .read = seq_read,
-+ .llseek = seq_lseek,
-+ .release = single_release,
-+};
-+
-+int pfe_debugfs_init(struct pfe *pfe)
-+{
-+ struct dentry *d;
-+
-+ pr_info("%s\n", __func__);
-+
-+ pfe->dentry = debugfs_create_dir("pfe", NULL);
-+ if (IS_ERR_OR_NULL(pfe->dentry))
-+ goto err_dir;
-+
-+ d = debugfs_create_file("pe0_dmem", 0444, pfe->dentry, (void *)0,
-+ &dmem_fops);
-+ if (IS_ERR_OR_NULL(d))
-+ goto err_pe;
-+
-+ d = debugfs_create_file("pe1_dmem", 0444, pfe->dentry, (void *)1,
-+ &dmem_fops);
-+ if (IS_ERR_OR_NULL(d))
-+ goto err_pe;
-+
-+ d = debugfs_create_file("pe2_dmem", 0444, pfe->dentry, (void *)2,
-+ &dmem_fops);
-+ if (IS_ERR_OR_NULL(d))
-+ goto err_pe;
-+
-+ d = debugfs_create_file("pe3_dmem", 0444, pfe->dentry, (void *)3,
-+ &dmem_fops);
-+ if (IS_ERR_OR_NULL(d))
-+ goto err_pe;
-+
-+ d = debugfs_create_file("pe4_dmem", 0444, pfe->dentry, (void *)4,
-+ &dmem_fops);
-+ if (IS_ERR_OR_NULL(d))
-+ goto err_pe;
-+
-+ d = debugfs_create_file("pe5_dmem", 0444, pfe->dentry, (void *)5,
-+ &dmem_fops);
-+ if (IS_ERR_OR_NULL(d))
-+ goto err_pe;
-+
-+ return 0;
-+
-+err_pe:
-+ debugfs_remove_recursive(pfe->dentry);
-+
-+err_dir:
-+ return -1;
-+}
-+
-+void pfe_debugfs_exit(struct pfe *pfe)
-+{
-+ debugfs_remove_recursive(pfe->dentry);
-+}
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/pfe_debugfs.h
-@@ -0,0 +1,13 @@
-+/* SPDX-License-Identifier: GPL-2.0+ */
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ */
-+
-+#ifndef _PFE_DEBUGFS_H_
-+#define _PFE_DEBUGFS_H_
-+
-+int pfe_debugfs_init(struct pfe *pfe);
-+void pfe_debugfs_exit(struct pfe *pfe);
-+
-+#endif /* _PFE_DEBUGFS_H_ */
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/pfe_eth.c
-@@ -0,0 +1,2588 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ */
-+
-+/* @pfe_eth.c.
-+ * Ethernet driver for to handle exception path for PFE.
-+ * - uses HIF functions to send/receive packets.
-+ * - uses ctrl function to start/stop interfaces.
-+ * - uses direct register accesses to control phy operation.
-+ */
-+#include <linux/version.h>
-+#include <linux/kernel.h>
-+#include <linux/interrupt.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/dmapool.h>
-+#include <linux/netdevice.h>
-+#include <linux/etherdevice.h>
-+#include <linux/ethtool.h>
-+#include <linux/mii.h>
-+#include <linux/phy.h>
-+#include <linux/timer.h>
-+#include <linux/hrtimer.h>
-+#include <linux/platform_device.h>
-+
-+#include <net/ip.h>
-+#include <net/sock.h>
-+
-+#include <linux/of.h>
-+#include <linux/of_mdio.h>
-+
-+#include <linux/io.h>
-+#include <asm/irq.h>
-+#include <linux/delay.h>
-+#include <linux/regmap.h>
-+#include <linux/i2c.h>
-+#include <linux/sys_soc.h>
-+
-+#if defined(CONFIG_NF_CONNTRACK_MARK)
-+#include <net/netfilter/nf_conntrack.h>
-+#endif
-+
-+#include "pfe_mod.h"
-+#include "pfe_eth.h"
-+#include "pfe_cdev.h"
-+
-+#define LS1012A_REV_1_0 0x87040010
-+
-+bool pfe_use_old_dts_phy;
-+bool pfe_errata_a010897;
-+
-+static void *cbus_emac_base[3];
-+static void *cbus_gpi_base[3];
-+
-+/* Forward Declaration */
-+static void pfe_eth_exit_one(struct pfe_eth_priv_s *priv);
-+static void pfe_eth_flush_tx(struct pfe_eth_priv_s *priv);
-+static void pfe_eth_flush_txQ(struct pfe_eth_priv_s *priv, int tx_q_num, int
-+ from_tx, int n_desc);
-+
-+/* MDIO registers */
-+#define MDIO_SGMII_CR 0x00
-+#define MDIO_SGMII_SR 0x01
-+#define MDIO_SGMII_DEV_ABIL_SGMII 0x04
-+#define MDIO_SGMII_LINK_TMR_L 0x12
-+#define MDIO_SGMII_LINK_TMR_H 0x13
-+#define MDIO_SGMII_IF_MODE 0x14
-+
-+/* SGMII Control defines */
-+#define SGMII_CR_RST 0x8000
-+#define SGMII_CR_AN_EN 0x1000
-+#define SGMII_CR_RESTART_AN 0x0200
-+#define SGMII_CR_FD 0x0100
-+#define SGMII_CR_SPEED_SEL1_1G 0x0040
-+#define SGMII_CR_DEF_VAL (SGMII_CR_AN_EN | SGMII_CR_FD | \
-+ SGMII_CR_SPEED_SEL1_1G)
-+
-+/* SGMII IF Mode */
-+#define SGMII_DUPLEX_HALF 0x10
-+#define SGMII_SPEED_10MBPS 0x00
-+#define SGMII_SPEED_100MBPS 0x04
-+#define SGMII_SPEED_1GBPS 0x08
-+#define SGMII_USE_SGMII_AN 0x02
-+#define SGMII_EN 0x01
-+
-+/* SGMII Device Ability for SGMII */
-+#define SGMII_DEV_ABIL_ACK 0x4000
-+#define SGMII_DEV_ABIL_EEE_CLK_STP_EN 0x0100
-+#define SGMII_DEV_ABIL_SGMII 0x0001
-+
-+unsigned int gemac_regs[] = {
-+ 0x0004, /* Interrupt event */
-+ 0x0008, /* Interrupt mask */
-+ 0x0024, /* Ethernet control */
-+ 0x0064, /* MIB Control/Status */
-+ 0x0084, /* Receive control/status */
-+ 0x00C4, /* Transmit control */
-+ 0x00E4, /* Physical address low */
-+ 0x00E8, /* Physical address high */
-+ 0x0144, /* Transmit FIFO Watermark and Store and Forward Control*/
-+ 0x0190, /* Receive FIFO Section Full Threshold */
-+ 0x01A0, /* Transmit FIFO Section Empty Threshold */
-+ 0x01B0, /* Frame Truncation Length */
-+};
-+
-+const struct soc_device_attribute ls1012a_rev1_soc_attr[] = {
-+ { .family = "QorIQ LS1012A",
-+ .soc_id = "svr:0x87040010",
-+ .revision = "1.0",
-+ .data = NULL },
-+ { },
-+};
-+
-+/********************************************************************/
-+/* SYSFS INTERFACE */
-+/********************************************************************/
-+
-+#ifdef PFE_ETH_NAPI_STATS
-+/*
-+ * pfe_eth_show_napi_stats
-+ */
-+static ssize_t pfe_eth_show_napi_stats(struct device *dev,
-+ struct device_attribute *attr,
-+ char *buf)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(to_net_dev(dev));
-+ ssize_t len = 0;
-+
-+ len += sprintf(buf + len, "sched: %u\n",
-+ priv->napi_counters[NAPI_SCHED_COUNT]);
-+ len += sprintf(buf + len, "poll: %u\n",
-+ priv->napi_counters[NAPI_POLL_COUNT]);
-+ len += sprintf(buf + len, "packet: %u\n",
-+ priv->napi_counters[NAPI_PACKET_COUNT]);
-+ len += sprintf(buf + len, "budget: %u\n",
-+ priv->napi_counters[NAPI_FULL_BUDGET_COUNT]);
-+ len += sprintf(buf + len, "desc: %u\n",
-+ priv->napi_counters[NAPI_DESC_COUNT]);
-+
-+ return len;
-+}
-+
-+/*
-+ * pfe_eth_set_napi_stats
-+ */
-+static ssize_t pfe_eth_set_napi_stats(struct device *dev,
-+ struct device_attribute *attr,
-+ const char *buf, size_t count)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(to_net_dev(dev));
-+
-+ memset(priv->napi_counters, 0, sizeof(priv->napi_counters));
-+
-+ return count;
-+}
-+#endif
-+#ifdef PFE_ETH_TX_STATS
-+/* pfe_eth_show_tx_stats
-+ *
-+ */
-+static ssize_t pfe_eth_show_tx_stats(struct device *dev,
-+ struct device_attribute *attr,
-+ char *buf)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(to_net_dev(dev));
-+ ssize_t len = 0;
-+ int i;
-+
-+ len += sprintf(buf + len, "TX queues stats:\n");
-+
-+ for (i = 0; i < emac_txq_cnt; i++) {
-+ struct netdev_queue *tx_queue = netdev_get_tx_queue(priv->ndev,
-+ i);
-+
-+ len += sprintf(buf + len, "\n");
-+ __netif_tx_lock_bh(tx_queue);
-+
-+ hif_tx_lock(&pfe->hif);
-+ len += sprintf(buf + len,
-+ "Queue %2d : credits = %10d\n"
-+ , i, hif_lib_tx_credit_avail(pfe, priv->id, i));
-+ len += sprintf(buf + len,
-+ " tx packets = %10d\n"
-+ , pfe->tmu_credit.tx_packets[priv->id][i]);
-+ hif_tx_unlock(&pfe->hif);
-+
-+ /* Don't output additionnal stats if queue never used */
-+ if (!pfe->tmu_credit.tx_packets[priv->id][i])
-+ goto skip;
-+
-+ len += sprintf(buf + len,
-+ " clean_fail = %10d\n"
-+ , priv->clean_fail[i]);
-+ len += sprintf(buf + len,
-+ " stop_queue = %10d\n"
-+ , priv->stop_queue_total[i]);
-+ len += sprintf(buf + len,
-+ " stop_queue_hif = %10d\n"
-+ , priv->stop_queue_hif[i]);
-+ len += sprintf(buf + len,
-+ " stop_queue_hif_client = %10d\n"
-+ , priv->stop_queue_hif_client[i]);
-+ len += sprintf(buf + len,
-+ " stop_queue_credit = %10d\n"
-+ , priv->stop_queue_credit[i]);
-+skip:
-+ __netif_tx_unlock_bh(tx_queue);
-+ }
-+ return len;
-+}
-+
-+/* pfe_eth_set_tx_stats
-+ *
-+ */
-+static ssize_t pfe_eth_set_tx_stats(struct device *dev,
-+ struct device_attribute *attr,
-+ const char *buf, size_t count)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(to_net_dev(dev));
-+ int i;
-+
-+ for (i = 0; i < emac_txq_cnt; i++) {
-+ struct netdev_queue *tx_queue = netdev_get_tx_queue(priv->ndev,
-+ i);
-+
-+ __netif_tx_lock_bh(tx_queue);
-+ priv->clean_fail[i] = 0;
-+ priv->stop_queue_total[i] = 0;
-+ priv->stop_queue_hif[i] = 0;
-+ priv->stop_queue_hif_client[i] = 0;
-+ priv->stop_queue_credit[i] = 0;
-+ __netif_tx_unlock_bh(tx_queue);
-+ }
-+
-+ return count;
-+}
-+#endif
-+/* pfe_eth_show_txavail
-+ *
-+ */
-+static ssize_t pfe_eth_show_txavail(struct device *dev,
-+ struct device_attribute *attr,
-+ char *buf)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(to_net_dev(dev));
-+ ssize_t len = 0;
-+ int i;
-+
-+ for (i = 0; i < emac_txq_cnt; i++) {
-+ struct netdev_queue *tx_queue = netdev_get_tx_queue(priv->ndev,
-+ i);
-+
-+ __netif_tx_lock_bh(tx_queue);
-+
-+ len += sprintf(buf + len, "%d",
-+ hif_lib_tx_avail(&priv->client, i));
-+
-+ __netif_tx_unlock_bh(tx_queue);
-+
-+ if (i == (emac_txq_cnt - 1))
-+ len += sprintf(buf + len, "\n");
-+ else
-+ len += sprintf(buf + len, " ");
-+ }
-+
-+ return len;
-+}
-+
-+/* pfe_eth_show_default_priority
-+ *
-+ */
-+static ssize_t pfe_eth_show_default_priority(struct device *dev,
-+ struct device_attribute *attr,
-+ char *buf)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(to_net_dev(dev));
-+ unsigned long flags;
-+ int rc;
-+
-+ spin_lock_irqsave(&priv->lock, flags);
-+ rc = sprintf(buf, "%d\n", priv->default_priority);
-+ spin_unlock_irqrestore(&priv->lock, flags);
-+
-+ return rc;
-+}
-+
-+/* pfe_eth_set_default_priority
-+ *
-+ */
-+
-+static ssize_t pfe_eth_set_default_priority(struct device *dev,
-+ struct device_attribute *attr,
-+ const char *buf, size_t count)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(to_net_dev(dev));
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&priv->lock, flags);
-+ priv->default_priority = kstrtoul(buf, 0, 0);
-+ spin_unlock_irqrestore(&priv->lock, flags);
-+
-+ return count;
-+}
-+
-+static DEVICE_ATTR(txavail, 0444, pfe_eth_show_txavail, NULL);
-+static DEVICE_ATTR(default_priority, 0644, pfe_eth_show_default_priority,
-+ pfe_eth_set_default_priority);
-+
-+#ifdef PFE_ETH_NAPI_STATS
-+static DEVICE_ATTR(napi_stats, 0644, pfe_eth_show_napi_stats,
-+ pfe_eth_set_napi_stats);
-+#endif
-+
-+#ifdef PFE_ETH_TX_STATS
-+static DEVICE_ATTR(tx_stats, 0644, pfe_eth_show_tx_stats,
-+ pfe_eth_set_tx_stats);
-+#endif
-+
-+/*
-+ * pfe_eth_sysfs_init
-+ *
-+ */
-+static int pfe_eth_sysfs_init(struct net_device *ndev)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(ndev);
-+ int err;
-+
-+ /* Initialize the default values */
-+
-+ /*
-+ * By default, packets without conntrack will use this default low
-+ * priority queue
-+ */
-+ priv->default_priority = 0;
-+
-+ /* Create our sysfs files */
-+ err = device_create_file(&ndev->dev, &dev_attr_default_priority);
-+ if (err) {
-+ netdev_err(ndev,
-+ "failed to create default_priority sysfs files\n");
-+ goto err_priority;
-+ }
-+
-+ err = device_create_file(&ndev->dev, &dev_attr_txavail);
-+ if (err) {
-+ netdev_err(ndev,
-+ "failed to create default_priority sysfs files\n");
-+ goto err_txavail;
-+ }
-+
-+#ifdef PFE_ETH_NAPI_STATS
-+ err = device_create_file(&ndev->dev, &dev_attr_napi_stats);
-+ if (err) {
-+ netdev_err(ndev, "failed to create napi stats sysfs files\n");
-+ goto err_napi;
-+ }
-+#endif
-+
-+#ifdef PFE_ETH_TX_STATS
-+ err = device_create_file(&ndev->dev, &dev_attr_tx_stats);
-+ if (err) {
-+ netdev_err(ndev, "failed to create tx stats sysfs files\n");
-+ goto err_tx;
-+ }
-+#endif
-+
-+ return 0;
-+
-+#ifdef PFE_ETH_TX_STATS
-+err_tx:
-+#endif
-+#ifdef PFE_ETH_NAPI_STATS
-+ device_remove_file(&ndev->dev, &dev_attr_napi_stats);
-+
-+err_napi:
-+#endif
-+ device_remove_file(&ndev->dev, &dev_attr_txavail);
-+
-+err_txavail:
-+ device_remove_file(&ndev->dev, &dev_attr_default_priority);
-+
-+err_priority:
-+ return -1;
-+}
-+
-+/* pfe_eth_sysfs_exit
-+ *
-+ */
-+void pfe_eth_sysfs_exit(struct net_device *ndev)
-+{
-+#ifdef PFE_ETH_TX_STATS
-+ device_remove_file(&ndev->dev, &dev_attr_tx_stats);
-+#endif
-+
-+#ifdef PFE_ETH_NAPI_STATS
-+ device_remove_file(&ndev->dev, &dev_attr_napi_stats);
-+#endif
-+ device_remove_file(&ndev->dev, &dev_attr_txavail);
-+ device_remove_file(&ndev->dev, &dev_attr_default_priority);
-+}
-+
-+/*************************************************************************/
-+/* ETHTOOL INTERCAE */
-+/*************************************************************************/
-+
-+/*MTIP GEMAC */
-+static const struct fec_stat {
-+ char name[ETH_GSTRING_LEN];
-+ u16 offset;
-+} fec_stats[] = {
-+ /* RMON TX */
-+ { "tx_dropped", RMON_T_DROP },
-+ { "tx_packets", RMON_T_PACKETS },
-+ { "tx_broadcast", RMON_T_BC_PKT },
-+ { "tx_multicast", RMON_T_MC_PKT },
-+ { "tx_crc_errors", RMON_T_CRC_ALIGN },
-+ { "tx_undersize", RMON_T_UNDERSIZE },
-+ { "tx_oversize", RMON_T_OVERSIZE },
-+ { "tx_fragment", RMON_T_FRAG },
-+ { "tx_jabber", RMON_T_JAB },
-+ { "tx_collision", RMON_T_COL },
-+ { "tx_64byte", RMON_T_P64 },
-+ { "tx_65to127byte", RMON_T_P65TO127 },
-+ { "tx_128to255byte", RMON_T_P128TO255 },
-+ { "tx_256to511byte", RMON_T_P256TO511 },
-+ { "tx_512to1023byte", RMON_T_P512TO1023 },
-+ { "tx_1024to2047byte", RMON_T_P1024TO2047 },
-+ { "tx_GTE2048byte", RMON_T_P_GTE2048 },
-+ { "tx_octets", RMON_T_OCTETS },
-+
-+ /* IEEE TX */
-+ { "IEEE_tx_drop", IEEE_T_DROP },
-+ { "IEEE_tx_frame_ok", IEEE_T_FRAME_OK },
-+ { "IEEE_tx_1col", IEEE_T_1COL },
-+ { "IEEE_tx_mcol", IEEE_T_MCOL },
-+ { "IEEE_tx_def", IEEE_T_DEF },
-+ { "IEEE_tx_lcol", IEEE_T_LCOL },
-+ { "IEEE_tx_excol", IEEE_T_EXCOL },
-+ { "IEEE_tx_macerr", IEEE_T_MACERR },
-+ { "IEEE_tx_cserr", IEEE_T_CSERR },
-+ { "IEEE_tx_sqe", IEEE_T_SQE },
-+ { "IEEE_tx_fdxfc", IEEE_T_FDXFC },
-+ { "IEEE_tx_octets_ok", IEEE_T_OCTETS_OK },
-+
-+ /* RMON RX */
-+ { "rx_packets", RMON_R_PACKETS },
-+ { "rx_broadcast", RMON_R_BC_PKT },
-+ { "rx_multicast", RMON_R_MC_PKT },
-+ { "rx_crc_errors", RMON_R_CRC_ALIGN },
-+ { "rx_undersize", RMON_R_UNDERSIZE },
-+ { "rx_oversize", RMON_R_OVERSIZE },
-+ { "rx_fragment", RMON_R_FRAG },
-+ { "rx_jabber", RMON_R_JAB },
-+ { "rx_64byte", RMON_R_P64 },
-+ { "rx_65to127byte", RMON_R_P65TO127 },
-+ { "rx_128to255byte", RMON_R_P128TO255 },
-+ { "rx_256to511byte", RMON_R_P256TO511 },
-+ { "rx_512to1023byte", RMON_R_P512TO1023 },
-+ { "rx_1024to2047byte", RMON_R_P1024TO2047 },
-+ { "rx_GTE2048byte", RMON_R_P_GTE2048 },
-+ { "rx_octets", RMON_R_OCTETS },
-+
-+ /* IEEE RX */
-+ { "IEEE_rx_drop", IEEE_R_DROP },
-+ { "IEEE_rx_frame_ok", IEEE_R_FRAME_OK },
-+ { "IEEE_rx_crc", IEEE_R_CRC },
-+ { "IEEE_rx_align", IEEE_R_ALIGN },
-+ { "IEEE_rx_macerr", IEEE_R_MACERR },
-+ { "IEEE_rx_fdxfc", IEEE_R_FDXFC },
-+ { "IEEE_rx_octets_ok", IEEE_R_OCTETS_OK },
-+};
-+
-+static void pfe_eth_fill_stats(struct net_device *ndev, struct ethtool_stats
-+ *stats, u64 *data)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(ndev);
-+ int i;
-+ u64 pfe_crc_validated = 0;
-+ int id;
-+
-+ for (id = CLASS0_ID; id <= CLASS_MAX_ID; id++) {
-+ pfe_crc_validated += be32_to_cpu(pe_dmem_read(id,
-+ CLASS_DM_CRC_VALIDATED + (priv->id * 4), 4));
-+ }
-+
-+ for (i = 0; i < ARRAY_SIZE(fec_stats); i++) {
-+ data[i] = readl(priv->EMAC_baseaddr + fec_stats[i].offset);
-+
-+ if (fec_stats[i].offset == IEEE_R_DROP)
-+ data[i] -= pfe_crc_validated;
-+ }
-+}
-+
-+static void pfe_eth_gstrings(struct net_device *netdev,
-+ u32 stringset, u8 *data)
-+{
-+ int i;
-+
-+ switch (stringset) {
-+ case ETH_SS_STATS:
-+ for (i = 0; i < ARRAY_SIZE(fec_stats); i++)
-+ memcpy(data + i * ETH_GSTRING_LEN,
-+ fec_stats[i].name, ETH_GSTRING_LEN);
-+ break;
-+ }
-+}
-+
-+static int pfe_eth_stats_count(struct net_device *ndev, int sset)
-+{
-+ switch (sset) {
-+ case ETH_SS_STATS:
-+ return ARRAY_SIZE(fec_stats);
-+ default:
-+ return -EOPNOTSUPP;
-+ }
-+}
-+
-+/*
-+ * pfe_eth_gemac_reglen - Return the length of the register structure.
-+ *
-+ */
-+static int pfe_eth_gemac_reglen(struct net_device *ndev)
-+{
-+ pr_info("%s()\n", __func__);
-+ return (sizeof(gemac_regs) / sizeof(u32));
-+}
-+
-+/*
-+ * pfe_eth_gemac_get_regs - Return the gemac register structure.
-+ *
-+ */
-+static void pfe_eth_gemac_get_regs(struct net_device *ndev, struct ethtool_regs
-+ *regs, void *regbuf)
-+{
-+ int i;
-+
-+ struct pfe_eth_priv_s *priv = netdev_priv(ndev);
-+ u32 *buf = (u32 *)regbuf;
-+
-+ pr_info("%s()\n", __func__);
-+ for (i = 0; i < sizeof(gemac_regs) / sizeof(u32); i++)
-+ buf[i] = readl(priv->EMAC_baseaddr + gemac_regs[i]);
-+}
-+
-+/*
-+ * pfe_eth_set_wol - Set the magic packet option, in WoL register.
-+ *
-+ */
-+static int pfe_eth_set_wol(struct net_device *ndev, struct ethtool_wolinfo *wol)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(ndev);
-+
-+ if (wol->wolopts & ~WAKE_MAGIC)
-+ return -EOPNOTSUPP;
-+
-+ /* for MTIP we store wol->wolopts */
-+ priv->wol = wol->wolopts;
-+
-+ device_set_wakeup_enable(&ndev->dev, wol->wolopts & WAKE_MAGIC);
-+
-+ return 0;
-+}
-+
-+/*
-+ *
-+ * pfe_eth_get_wol - Get the WoL options.
-+ *
-+ */
-+static void pfe_eth_get_wol(struct net_device *ndev, struct ethtool_wolinfo
-+ *wol)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(ndev);
-+
-+ wol->supported = WAKE_MAGIC;
-+ wol->wolopts = 0;
-+
-+ if (priv->wol & WAKE_MAGIC)
-+ wol->wolopts = WAKE_MAGIC;
-+
-+ memset(&wol->sopass, 0, sizeof(wol->sopass));
-+}
-+
-+/*
-+ * pfe_eth_get_drvinfo - Fills in the drvinfo structure with some basic info
-+ *
-+ */
-+static void pfe_eth_get_drvinfo(struct net_device *ndev, struct ethtool_drvinfo
-+ *drvinfo)
-+{
-+ strlcpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver));
-+ strlcpy(drvinfo->version, DRV_VERSION, sizeof(drvinfo->version));
-+ strlcpy(drvinfo->fw_version, "N/A", sizeof(drvinfo->fw_version));
-+ strlcpy(drvinfo->bus_info, "N/A", sizeof(drvinfo->bus_info));
-+}
-+
-+/*
-+ * pfe_eth_set_settings - Used to send commands to PHY.
-+ *
-+ */
-+static int pfe_eth_set_settings(struct net_device *ndev,
-+ const struct ethtool_link_ksettings *cmd)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(ndev);
-+ struct phy_device *phydev = priv->phydev;
-+
-+ if (!phydev)
-+ return -ENODEV;
-+
-+ return phy_ethtool_ksettings_set(phydev, cmd);
-+}
-+
-+/*
-+ * pfe_eth_getsettings - Return the current settings in the ethtool_cmd
-+ * structure.
-+ *
-+ */
-+static int pfe_eth_get_settings(struct net_device *ndev,
-+ struct ethtool_link_ksettings *cmd)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(ndev);
-+ struct phy_device *phydev = priv->phydev;
-+
-+ if (!phydev)
-+ return -ENODEV;
-+
-+ phy_ethtool_ksettings_get(phydev, cmd);
-+
-+ return 0;
-+}
-+
-+/*
-+ * pfe_eth_get_msglevel - Gets the debug message mask.
-+ *
-+ */
-+static uint32_t pfe_eth_get_msglevel(struct net_device *ndev)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(ndev);
-+
-+ return priv->msg_enable;
-+}
-+
-+/*
-+ * pfe_eth_set_msglevel - Sets the debug message mask.
-+ *
-+ */
-+static void pfe_eth_set_msglevel(struct net_device *ndev, uint32_t data)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(ndev);
-+
-+ priv->msg_enable = data;
-+}
-+
-+#define HIF_RX_COAL_MAX_CLKS (~(1 << 31))
-+#define HIF_RX_COAL_CLKS_PER_USEC (pfe->ctrl.sys_clk / 1000)
-+#define HIF_RX_COAL_MAX_USECS (HIF_RX_COAL_MAX_CLKS / \
-+ HIF_RX_COAL_CLKS_PER_USEC)
-+
-+/*
-+ * pfe_eth_set_coalesce - Sets rx interrupt coalescing timer.
-+ *
-+ */
-+static int pfe_eth_set_coalesce(struct net_device *ndev,
-+ struct ethtool_coalesce *ec,
-+ struct kernel_ethtool_coalesce *kernel_coal,
-+ struct netlink_ext_ack *extack)
-+{
-+ if (ec->rx_coalesce_usecs > HIF_RX_COAL_MAX_USECS)
-+ return -EINVAL;
-+
-+ if (!ec->rx_coalesce_usecs) {
-+ writel(0, HIF_INT_COAL);
-+ return 0;
-+ }
-+
-+ writel((ec->rx_coalesce_usecs * HIF_RX_COAL_CLKS_PER_USEC) |
-+ HIF_INT_COAL_ENABLE, HIF_INT_COAL);
-+
-+ return 0;
-+}
-+
-+/*
-+ * pfe_eth_get_coalesce - Gets rx interrupt coalescing timer value.
-+ *
-+ */
-+static int pfe_eth_get_coalesce(struct net_device *ndev,
-+ struct ethtool_coalesce *ec,
-+ struct kernel_ethtool_coalesce *kernel_coal,
-+ struct netlink_ext_ack *extack)
-+{
-+ int reg_val = readl(HIF_INT_COAL);
-+
-+ if (reg_val & HIF_INT_COAL_ENABLE)
-+ ec->rx_coalesce_usecs = (reg_val & HIF_RX_COAL_MAX_CLKS) /
-+ HIF_RX_COAL_CLKS_PER_USEC;
-+ else
-+ ec->rx_coalesce_usecs = 0;
-+
-+ return 0;
-+}
-+
-+/*
-+ * pfe_eth_set_pauseparam - Sets pause parameters
-+ *
-+ */
-+static int pfe_eth_set_pauseparam(struct net_device *ndev,
-+ struct ethtool_pauseparam *epause)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(ndev);
-+
-+ if (epause->tx_pause != epause->rx_pause) {
-+ netdev_info(ndev,
-+ "hardware only support enable/disable both tx and rx\n");
-+ return -EINVAL;
-+ }
-+
-+ priv->pause_flag = 0;
-+ priv->pause_flag |= epause->rx_pause ? PFE_PAUSE_FLAG_ENABLE : 0;
-+ priv->pause_flag |= epause->autoneg ? PFE_PAUSE_FLAG_AUTONEG : 0;
-+
-+ if (epause->rx_pause || epause->autoneg) {
-+ gemac_enable_pause_rx(priv->EMAC_baseaddr);
-+ writel((readl(priv->GPI_baseaddr + GPI_TX_PAUSE_TIME) |
-+ EGPI_PAUSE_ENABLE),
-+ priv->GPI_baseaddr + GPI_TX_PAUSE_TIME);
-+ if (priv->phydev) {
-+ linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT,
-+ priv->phydev->supported);
-+ linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
-+ priv->phydev->supported);
-+ linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT,
-+ priv->phydev->advertising);
-+ linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
-+ priv->phydev->advertising);
-+ }
-+ } else {
-+ gemac_disable_pause_rx(priv->EMAC_baseaddr);
-+ writel((readl(priv->GPI_baseaddr + GPI_TX_PAUSE_TIME) &
-+ ~EGPI_PAUSE_ENABLE),
-+ priv->GPI_baseaddr + GPI_TX_PAUSE_TIME);
-+ if (priv->phydev) {
-+ linkmode_clear_bit(ETHTOOL_LINK_MODE_Pause_BIT,
-+ priv->phydev->supported);
-+ linkmode_clear_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
-+ priv->phydev->supported);
-+ linkmode_clear_bit(ETHTOOL_LINK_MODE_Pause_BIT,
-+ priv->phydev->advertising);
-+ linkmode_clear_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
-+ priv->phydev->advertising);
-+ }
-+ }
-+
-+ return 0;
-+}
-+
-+/*
-+ * pfe_eth_get_pauseparam - Gets pause parameters
-+ *
-+ */
-+static void pfe_eth_get_pauseparam(struct net_device *ndev,
-+ struct ethtool_pauseparam *epause)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(ndev);
-+
-+ epause->autoneg = (priv->pause_flag & PFE_PAUSE_FLAG_AUTONEG) != 0;
-+ epause->tx_pause = (priv->pause_flag & PFE_PAUSE_FLAG_ENABLE) != 0;
-+ epause->rx_pause = epause->tx_pause;
-+}
-+
-+/*
-+ * pfe_eth_get_hash
-+ */
-+#define PFE_HASH_BITS 6 /* #bits in hash */
-+#define CRC32_POLY 0xEDB88320
-+
-+static int pfe_eth_get_hash(u8 *addr)
-+{
-+ unsigned int i, bit, data, crc, hash;
-+
-+ /* calculate crc32 value of mac address */
-+ crc = 0xffffffff;
-+
-+ for (i = 0; i < 6; i++) {
-+ data = addr[i];
-+ for (bit = 0; bit < 8; bit++, data >>= 1) {
-+ crc = (crc >> 1) ^
-+ (((crc ^ data) & 1) ? CRC32_POLY : 0);
-+ }
-+ }
-+
-+ /*
-+ * only upper 6 bits (PFE_HASH_BITS) are used
-+ * which point to specific bit in the hash registers
-+ */
-+ hash = (crc >> (32 - PFE_HASH_BITS)) & 0x3f;
-+
-+ return hash;
-+}
-+
-+const struct ethtool_ops pfe_ethtool_ops = {
-+ .supported_coalesce_params = ETHTOOL_COALESCE_RX_USECS,
-+ .get_drvinfo = pfe_eth_get_drvinfo,
-+ .get_regs_len = pfe_eth_gemac_reglen,
-+ .get_regs = pfe_eth_gemac_get_regs,
-+ .get_link = ethtool_op_get_link,
-+ .get_wol = pfe_eth_get_wol,
-+ .set_wol = pfe_eth_set_wol,
-+ .set_pauseparam = pfe_eth_set_pauseparam,
-+ .get_pauseparam = pfe_eth_get_pauseparam,
-+ .get_strings = pfe_eth_gstrings,
-+ .get_sset_count = pfe_eth_stats_count,
-+ .get_ethtool_stats = pfe_eth_fill_stats,
-+ .get_msglevel = pfe_eth_get_msglevel,
-+ .set_msglevel = pfe_eth_set_msglevel,
-+ .set_coalesce = pfe_eth_set_coalesce,
-+ .get_coalesce = pfe_eth_get_coalesce,
-+ .get_link_ksettings = pfe_eth_get_settings,
-+ .set_link_ksettings = pfe_eth_set_settings,
-+};
-+
-+/* pfe_eth_mdio_reset
-+ */
-+int pfe_eth_mdio_reset(struct mii_bus *bus)
-+{
-+ struct pfe_mdio_priv_s *priv = (struct pfe_mdio_priv_s *)bus->priv;
-+ u32 phy_speed;
-+
-+
-+ mutex_lock(&bus->mdio_lock);
-+
-+ /*
-+ * Set MII speed to 2.5 MHz (= clk_get_rate() / 2 * phy_speed)
-+ *
-+ * The formula for FEC MDC is 'ref_freq / (MII_SPEED x 2)' while
-+ * for ENET-MAC is 'ref_freq / ((MII_SPEED + 1) x 2)'.
-+ */
-+ phy_speed = (DIV_ROUND_UP((pfe->ctrl.sys_clk * 1000), 4000000)
-+ << EMAC_MII_SPEED_SHIFT);
-+ phy_speed |= EMAC_HOLDTIME(0x5);
-+ __raw_writel(phy_speed, priv->mdio_base + EMAC_MII_CTRL_REG);
-+
-+ mutex_unlock(&bus->mdio_lock);
-+
-+ return 0;
-+}
-+
-+/* pfe_eth_mdio_timeout
-+ *
-+ */
-+static int pfe_eth_mdio_timeout(struct pfe_mdio_priv_s *priv, int timeout)
-+{
-+ while (!(__raw_readl(priv->mdio_base + EMAC_IEVENT_REG) &
-+ EMAC_IEVENT_MII)) {
-+ if (timeout-- <= 0)
-+ return -1;
-+ usleep_range(10, 20);
-+ }
-+ __raw_writel(EMAC_IEVENT_MII, priv->mdio_base + EMAC_IEVENT_REG);
-+ return 0;
-+}
-+
-+static int pfe_eth_mdio_mux(u8 muxval)
-+{
-+ struct i2c_adapter *a;
-+ struct i2c_msg msg;
-+ unsigned char buf[2];
-+ int ret;
-+
-+ a = i2c_get_adapter(0);
-+ if (!a)
-+ return -ENODEV;
-+
-+ /* set bit 1 (the second bit) of chip at 0x09, register 0x13 */
-+ buf[0] = 0x54; /* reg number */
-+ buf[1] = (muxval << 6) | 0x3; /* data */
-+ msg.addr = 0x66;
-+ msg.buf = buf;
-+ msg.len = 2;
-+ msg.flags = 0;
-+ ret = i2c_transfer(a, &msg, 1);
-+ i2c_put_adapter(a);
-+ if (ret != 1)
-+ return -ENODEV;
-+ return 0;
-+}
-+
-+static int pfe_eth_mdio_write_addr(struct mii_bus *bus, int mii_id,
-+ int dev_addr, int regnum)
-+{
-+ struct pfe_mdio_priv_s *priv = (struct pfe_mdio_priv_s *)bus->priv;
-+
-+ __raw_writel(EMAC_MII_DATA_PA(mii_id) |
-+ EMAC_MII_DATA_RA(dev_addr) |
-+ EMAC_MII_DATA_TA | EMAC_MII_DATA(regnum),
-+ priv->mdio_base + EMAC_MII_DATA_REG);
-+
-+ if (pfe_eth_mdio_timeout(priv, EMAC_MDIO_TIMEOUT)) {
-+ dev_err(&bus->dev, "phy MDIO address write timeout\n");
-+ return -1;
-+ }
-+
-+ return 0;
-+}
-+
-+static int pfe_eth_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
-+ u16 value)
-+{
-+ struct pfe_mdio_priv_s *priv = (struct pfe_mdio_priv_s *)bus->priv;
-+
-+ /*To access external PHYs on QDS board mux needs to be configured*/
-+ if ((mii_id) && (pfe->mdio_muxval[mii_id]))
-+ pfe_eth_mdio_mux(pfe->mdio_muxval[mii_id]);
-+
-+ if (regnum & MII_ADDR_C45) {
-+ pfe_eth_mdio_write_addr(bus, mii_id, (regnum >> 16) & 0x1f,
-+ regnum & 0xffff);
-+ __raw_writel(EMAC_MII_DATA_OP_CL45_WR |
-+ EMAC_MII_DATA_PA(mii_id) |
-+ EMAC_MII_DATA_RA((regnum >> 16) & 0x1f) |
-+ EMAC_MII_DATA_TA | EMAC_MII_DATA(value),
-+ priv->mdio_base + EMAC_MII_DATA_REG);
-+ } else {
-+ /* start a write op */
-+ __raw_writel(EMAC_MII_DATA_ST | EMAC_MII_DATA_OP_WR |
-+ EMAC_MII_DATA_PA(mii_id) |
-+ EMAC_MII_DATA_RA(regnum) |
-+ EMAC_MII_DATA_TA | EMAC_MII_DATA(value),
-+ priv->mdio_base + EMAC_MII_DATA_REG);
-+ }
-+
-+ if (pfe_eth_mdio_timeout(priv, EMAC_MDIO_TIMEOUT)) {
-+ dev_err(&bus->dev, "%s: phy MDIO write timeout\n", __func__);
-+ return -1;
-+ }
-+ return 0;
-+}
-+
-+static int pfe_eth_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
-+{
-+ struct pfe_mdio_priv_s *priv = (struct pfe_mdio_priv_s *)bus->priv;
-+ u16 value = 0;
-+
-+ /*To access external PHYs on QDS board mux needs to be configured*/
-+ if ((mii_id) && (pfe->mdio_muxval[mii_id]))
-+ pfe_eth_mdio_mux(pfe->mdio_muxval[mii_id]);
-+
-+ if (regnum & MII_ADDR_C45) {
-+ pfe_eth_mdio_write_addr(bus, mii_id, (regnum >> 16) & 0x1f,
-+ regnum & 0xffff);
-+ __raw_writel(EMAC_MII_DATA_OP_CL45_RD |
-+ EMAC_MII_DATA_PA(mii_id) |
-+ EMAC_MII_DATA_RA((regnum >> 16) & 0x1f) |
-+ EMAC_MII_DATA_TA,
-+ priv->mdio_base + EMAC_MII_DATA_REG);
-+ } else {
-+ /* start a read op */
-+ __raw_writel(EMAC_MII_DATA_ST | EMAC_MII_DATA_OP_RD |
-+ EMAC_MII_DATA_PA(mii_id) |
-+ EMAC_MII_DATA_RA(regnum) |
-+ EMAC_MII_DATA_TA, priv->mdio_base +
-+ EMAC_MII_DATA_REG);
-+ }
-+
-+ if (pfe_eth_mdio_timeout(priv, EMAC_MDIO_TIMEOUT)) {
-+ dev_err(&bus->dev, "%s: phy MDIO read timeout\n", __func__);
-+ return -1;
-+ }
-+
-+ value = EMAC_MII_DATA(__raw_readl(priv->mdio_base +
-+ EMAC_MII_DATA_REG));
-+ return value;
-+}
-+
-+static int pfe_eth_mdio_init(struct pfe *pfe,
-+ struct ls1012a_pfe_platform_data *pfe_info,
-+ int ii)
-+{
-+ struct pfe_mdio_priv_s *priv = NULL;
-+ struct ls1012a_mdio_platform_data *mdio_info;
-+ struct mii_bus *bus;
-+ struct device_node *mdio_node;
-+ int rc = 0;
-+
-+ mdio_info = (struct ls1012a_mdio_platform_data *)
-+ pfe_info->ls1012a_mdio_pdata;
-+ mdio_info->id = ii;
-+
-+ bus = mdiobus_alloc_size(sizeof(struct pfe_mdio_priv_s));
-+ if (!bus) {
-+ pr_err("mdiobus_alloc() failed\n");
-+ rc = -ENOMEM;
-+ goto err_mdioalloc;
-+ }
-+
-+ bus->name = "ls1012a MDIO Bus";
-+ snprintf(bus->id, MII_BUS_ID_SIZE, "ls1012a-%x", mdio_info->id);
-+
-+ bus->read = &pfe_eth_mdio_read;
-+ bus->write = &pfe_eth_mdio_write;
-+ bus->reset = &pfe_eth_mdio_reset;
-+ bus->parent = pfe->dev;
-+ bus->phy_mask = mdio_info->phy_mask;
-+ bus->irq[0] = mdio_info->irq[0];
-+ priv = bus->priv;
-+ priv->mdio_base = cbus_emac_base[ii];
-+
-+ priv->mdc_div = mdio_info->mdc_div;
-+ if (!priv->mdc_div)
-+ priv->mdc_div = 64;
-+
-+ dev_info(bus->parent, "%s: mdc_div: %d, phy_mask: %x\n",
-+ __func__, priv->mdc_div, bus->phy_mask);
-+ mdio_node = of_get_child_by_name(pfe->dev->of_node, "mdio");
-+ if ((mdio_info->id == 0) && mdio_node) {
-+ rc = of_mdiobus_register(bus, mdio_node);
-+ of_node_put(mdio_node);
-+ } else {
-+ rc = mdiobus_register(bus);
-+ }
-+
-+ if (rc) {
-+ dev_err(bus->parent, "mdiobus_register(%s) failed\n",
-+ bus->name);
-+ goto err_mdioregister;
-+ }
-+
-+ priv->mii_bus = bus;
-+ pfe->mdio.mdio_priv[ii] = priv;
-+
-+ pfe_eth_mdio_reset(bus);
-+
-+ return 0;
-+
-+err_mdioregister:
-+ mdiobus_free(bus);
-+err_mdioalloc:
-+ return rc;
-+}
-+
-+/* pfe_eth_mdio_exit
-+ */
-+static void pfe_eth_mdio_exit(struct pfe *pfe,
-+ int ii)
-+{
-+ struct pfe_mdio_priv_s *mdio_priv = pfe->mdio.mdio_priv[ii];
-+ struct mii_bus *bus = mdio_priv->mii_bus;
-+
-+ if (!bus)
-+ return;
-+ mdiobus_unregister(bus);
-+ mdiobus_free(bus);
-+}
-+
-+/* pfe_get_phydev_speed
-+ */
-+static int pfe_get_phydev_speed(struct phy_device *phydev)
-+{
-+ switch (phydev->speed) {
-+ case 10:
-+ return SPEED_10M;
-+ case 100:
-+ return SPEED_100M;
-+ case 1000:
-+ default:
-+ return SPEED_1000M;
-+ }
-+}
-+
-+/* pfe_set_rgmii_speed
-+ */
-+#define RGMIIPCR 0x434
-+/* RGMIIPCR bit definitions*/
-+#define SCFG_RGMIIPCR_EN_AUTO (0x00000008)
-+#define SCFG_RGMIIPCR_SETSP_1000M (0x00000004)
-+#define SCFG_RGMIIPCR_SETSP_100M (0x00000000)
-+#define SCFG_RGMIIPCR_SETSP_10M (0x00000002)
-+#define SCFG_RGMIIPCR_SETFD (0x00000001)
-+
-+#define MDIOSELCR 0x484
-+#define MDIOSEL_SERDES 0x0
-+#define MDIOSEL_EXTPHY 0x80000000
-+
-+static void pfe_set_rgmii_speed(struct phy_device *phydev)
-+{
-+ u32 rgmii_pcr;
-+
-+ regmap_read(pfe->scfg, RGMIIPCR, &rgmii_pcr);
-+ rgmii_pcr &= ~(SCFG_RGMIIPCR_SETSP_1000M | SCFG_RGMIIPCR_SETSP_10M);
-+
-+ switch (phydev->speed) {
-+ case 10:
-+ rgmii_pcr |= SCFG_RGMIIPCR_SETSP_10M;
-+ break;
-+ case 1000:
-+ rgmii_pcr |= SCFG_RGMIIPCR_SETSP_1000M;
-+ break;
-+ case 100:
-+ default:
-+ /* Default is 100M */
-+ break;
-+ }
-+ regmap_write(pfe->scfg, RGMIIPCR, rgmii_pcr);
-+}
-+
-+/* pfe_get_phydev_duplex
-+ */
-+static int pfe_get_phydev_duplex(struct phy_device *phydev)
-+{
-+ /*return (phydev->duplex == DUPLEX_HALF) ? DUP_HALF:DUP_FULL ; */
-+ return DUPLEX_FULL;
-+}
-+
-+/* pfe_eth_adjust_link
-+ */
-+static void pfe_eth_adjust_link(struct net_device *ndev)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(ndev);
-+ unsigned long flags;
-+ struct phy_device *phydev = priv->phydev;
-+ int new_state = 0;
-+
-+ netif_info(priv, drv, ndev, "%s\n", __func__);
-+
-+ spin_lock_irqsave(&priv->lock, flags);
-+
-+ if (phydev->link) {
-+ /*
-+ * Now we make sure that we can be in full duplex mode.
-+ * If not, we operate in half-duplex mode.
-+ */
-+ if (phydev->duplex != priv->oldduplex) {
-+ new_state = 1;
-+ gemac_set_duplex(priv->EMAC_baseaddr,
-+ pfe_get_phydev_duplex(phydev));
-+ priv->oldduplex = phydev->duplex;
-+ }
-+
-+ if (phydev->speed != priv->oldspeed) {
-+ new_state = 1;
-+ gemac_set_speed(priv->EMAC_baseaddr,
-+ pfe_get_phydev_speed(phydev));
-+ if (priv->einfo->mii_config ==
-+ PHY_INTERFACE_MODE_RGMII_ID)
-+ pfe_set_rgmii_speed(phydev);
-+ priv->oldspeed = phydev->speed;
-+ }
-+
-+ if (!priv->oldlink) {
-+ new_state = 1;
-+ priv->oldlink = 1;
-+ }
-+
-+ } else if (priv->oldlink) {
-+ new_state = 1;
-+ priv->oldlink = 0;
-+ priv->oldspeed = 0;
-+ priv->oldduplex = -1;
-+ }
-+
-+ if (new_state && netif_msg_link(priv))
-+ phy_print_status(phydev);
-+
-+ spin_unlock_irqrestore(&priv->lock, flags);
-+
-+ /* Now, dump the details to the cdev.
-+ * XXX: Locking would be required? (uniprocess arch)
-+ * Or, maybe move it in spinlock above
-+ */
-+ if (us && priv->einfo->gem_id < PFE_CDEV_ETH_COUNT) {
-+ pr_debug("Changing link state from (%u) to (%u) for ID=(%u)\n",
-+ link_states[priv->einfo->gem_id].state,
-+ phydev->link,
-+ priv->einfo->gem_id);
-+ link_states[priv->einfo->gem_id].phy_id = priv->einfo->gem_id;
-+ link_states[priv->einfo->gem_id].state = phydev->link;
-+ }
-+}
-+
-+/* pfe_phy_exit
-+ */
-+static void pfe_phy_exit(struct net_device *ndev)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(ndev);
-+
-+ netif_info(priv, drv, ndev, "%s\n", __func__);
-+
-+ phy_disconnect(priv->phydev);
-+ priv->phydev = NULL;
-+}
-+
-+/* pfe_eth_stop
-+ */
-+static void pfe_eth_stop(struct net_device *ndev, int wake)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(ndev);
-+
-+ netif_info(priv, drv, ndev, "%s\n", __func__);
-+
-+ if (wake) {
-+ gemac_tx_disable(priv->EMAC_baseaddr);
-+ } else {
-+ gemac_disable(priv->EMAC_baseaddr);
-+ gpi_disable(priv->GPI_baseaddr);
-+
-+ if (priv->phydev)
-+ phy_stop(priv->phydev);
-+ }
-+}
-+
-+/* pfe_eth_start
-+ */
-+static int pfe_eth_start(struct pfe_eth_priv_s *priv)
-+{
-+ netif_info(priv, drv, priv->ndev, "%s\n", __func__);
-+
-+ if (priv->phydev)
-+ phy_start(priv->phydev);
-+
-+ gpi_enable(priv->GPI_baseaddr);
-+ gemac_enable(priv->EMAC_baseaddr);
-+
-+ return 0;
-+}
-+
-+/*
-+ * Configure on chip serdes through mdio
-+ */
-+static void ls1012a_configure_serdes(struct net_device *ndev)
-+{
-+ struct pfe_eth_priv_s *eth_priv = netdev_priv(ndev);
-+ struct pfe_mdio_priv_s *mdio_priv = pfe->mdio.mdio_priv[eth_priv->id];
-+ int sgmii_2500 = 0;
-+ struct mii_bus *bus = mdio_priv->mii_bus;
-+ u16 value = 0;
-+
-+ if (eth_priv->einfo->mii_config == PHY_INTERFACE_MODE_2500SGMII)
-+ sgmii_2500 = 1;
-+
-+ netif_info(eth_priv, drv, ndev, "%s\n", __func__);
-+ /* PCS configuration done with corresponding GEMAC */
-+
-+ pfe_eth_mdio_read(bus, 0, MDIO_SGMII_CR);
-+ pfe_eth_mdio_read(bus, 0, MDIO_SGMII_SR);
-+
-+ pfe_eth_mdio_write(bus, 0, MDIO_SGMII_CR, SGMII_CR_RST);
-+
-+ if (sgmii_2500) {
-+ pfe_eth_mdio_write(bus, 0, MDIO_SGMII_IF_MODE, SGMII_SPEED_1GBPS
-+ | SGMII_EN);
-+ pfe_eth_mdio_write(bus, 0, MDIO_SGMII_DEV_ABIL_SGMII,
-+ SGMII_DEV_ABIL_ACK | SGMII_DEV_ABIL_SGMII);
-+ pfe_eth_mdio_write(bus, 0, MDIO_SGMII_LINK_TMR_L, 0xa120);
-+ pfe_eth_mdio_write(bus, 0, MDIO_SGMII_LINK_TMR_H, 0x7);
-+ /* Autonegotiation need to be disabled for 2.5G SGMII mode*/
-+ value = SGMII_CR_FD | SGMII_CR_SPEED_SEL1_1G;
-+ pfe_eth_mdio_write(bus, 0, MDIO_SGMII_CR, value);
-+ } else {
-+ pfe_eth_mdio_write(bus, 0, MDIO_SGMII_IF_MODE,
-+ SGMII_SPEED_1GBPS
-+ | SGMII_USE_SGMII_AN
-+ | SGMII_EN);
-+ pfe_eth_mdio_write(bus, 0, MDIO_SGMII_DEV_ABIL_SGMII,
-+ SGMII_DEV_ABIL_EEE_CLK_STP_EN
-+ | 0xa0
-+ | SGMII_DEV_ABIL_SGMII);
-+ pfe_eth_mdio_write(bus, 0, MDIO_SGMII_LINK_TMR_L, 0x400);
-+ pfe_eth_mdio_write(bus, 0, MDIO_SGMII_LINK_TMR_H, 0x0);
-+ value = SGMII_CR_AN_EN | SGMII_CR_FD | SGMII_CR_SPEED_SEL1_1G;
-+ pfe_eth_mdio_write(bus, 0, MDIO_SGMII_CR, value);
-+ }
-+}
-+
-+/*
-+ * pfe_phy_init
-+ *
-+ */
-+static int pfe_phy_init(struct net_device *ndev)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(ndev);
-+ struct phy_device *phydev;
-+ char phy_id[MII_BUS_ID_SIZE + 3];
-+ char bus_id[MII_BUS_ID_SIZE];
-+ phy_interface_t interface;
-+
-+ priv->oldlink = 0;
-+ priv->oldspeed = 0;
-+ priv->oldduplex = -1;
-+
-+ snprintf(bus_id, MII_BUS_ID_SIZE, "ls1012a-%d", 0);
-+ snprintf(phy_id, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id,
-+ priv->einfo->phy_id);
-+ netif_info(priv, drv, ndev, "%s: %s\n", __func__, phy_id);
-+ interface = priv->einfo->mii_config;
-+ if ((interface == PHY_INTERFACE_MODE_SGMII) ||
-+ (interface == PHY_INTERFACE_MODE_2500SGMII)) {
-+ /*Configure SGMII PCS */
-+ if (pfe->scfg) {
-+ /* Config MDIO from serdes */
-+ regmap_write(pfe->scfg, MDIOSELCR, MDIOSEL_SERDES);
-+ }
-+ ls1012a_configure_serdes(ndev);
-+ }
-+
-+ if (pfe->scfg) {
-+ /*Config MDIO from PAD */
-+ regmap_write(pfe->scfg, MDIOSELCR, MDIOSEL_EXTPHY);
-+ }
-+
-+ priv->oldlink = 0;
-+ priv->oldspeed = 0;
-+ priv->oldduplex = -1;
-+ pr_info("%s interface %x\n", __func__, interface);
-+
-+ if (priv->phy_node) {
-+ phydev = of_phy_connect(ndev, priv->phy_node,
-+ pfe_eth_adjust_link, 0,
-+ priv->einfo->mii_config);
-+ if (!(phydev)) {
-+ netdev_err(ndev, "Unable to connect to phy\n");
-+ return -ENODEV;
-+ }
-+
-+ } else {
-+ phydev = phy_connect(ndev, phy_id,
-+ &pfe_eth_adjust_link, interface);
-+ if (IS_ERR(phydev)) {
-+ netdev_err(ndev, "Unable to connect to phy\n");
-+ return PTR_ERR(phydev);
-+ }
-+ }
-+
-+ priv->phydev = phydev;
-+ phydev->irq = PHY_POLL;
-+
-+ return 0;
-+}
-+
-+/* pfe_gemac_init
-+ */
-+static int pfe_gemac_init(struct pfe_eth_priv_s *priv)
-+{
-+ struct gemac_cfg cfg;
-+
-+ netif_info(priv, ifup, priv->ndev, "%s\n", __func__);
-+
-+ cfg.mode = 0;
-+ cfg.speed = SPEED_1000M;
-+ cfg.duplex = DUPLEX_FULL;
-+
-+ gemac_set_config(priv->EMAC_baseaddr, &cfg);
-+ gemac_allow_broadcast(priv->EMAC_baseaddr);
-+ gemac_enable_1536_rx(priv->EMAC_baseaddr);
-+ gemac_enable_stacked_vlan(priv->EMAC_baseaddr);
-+ gemac_enable_pause_rx(priv->EMAC_baseaddr);
-+ gemac_set_bus_width(priv->EMAC_baseaddr, 64);
-+
-+ /*GEM will perform checksum verifications*/
-+ if (priv->ndev->features & NETIF_F_RXCSUM)
-+ gemac_enable_rx_checksum_offload(priv->EMAC_baseaddr);
-+ else
-+ gemac_disable_rx_checksum_offload(priv->EMAC_baseaddr);
-+
-+ return 0;
-+}
-+
-+/* pfe_eth_event_handler
-+ */
-+static int pfe_eth_event_handler(void *data, int event, int qno)
-+{
-+ struct pfe_eth_priv_s *priv = data;
-+
-+ switch (event) {
-+ case EVENT_RX_PKT_IND:
-+
-+ if (qno == 0) {
-+ if (napi_schedule_prep(&priv->high_napi)) {
-+ netif_info(priv, intr, priv->ndev,
-+ "%s: schedule high prio poll\n"
-+ , __func__);
-+
-+#ifdef PFE_ETH_NAPI_STATS
-+ priv->napi_counters[NAPI_SCHED_COUNT]++;
-+#endif
-+
-+ __napi_schedule(&priv->high_napi);
-+ }
-+ } else if (qno == 1) {
-+ if (napi_schedule_prep(&priv->low_napi)) {
-+ netif_info(priv, intr, priv->ndev,
-+ "%s: schedule low prio poll\n"
-+ , __func__);
-+
-+#ifdef PFE_ETH_NAPI_STATS
-+ priv->napi_counters[NAPI_SCHED_COUNT]++;
-+#endif
-+ __napi_schedule(&priv->low_napi);
-+ }
-+ } else if (qno == 2) {
-+ if (napi_schedule_prep(&priv->lro_napi)) {
-+ netif_info(priv, intr, priv->ndev,
-+ "%s: schedule lro prio poll\n"
-+ , __func__);
-+
-+#ifdef PFE_ETH_NAPI_STATS
-+ priv->napi_counters[NAPI_SCHED_COUNT]++;
-+#endif
-+ __napi_schedule(&priv->lro_napi);
-+ }
-+ }
-+
-+ break;
-+
-+ case EVENT_TXDONE_IND:
-+ pfe_eth_flush_tx(priv);
-+ hif_lib_event_handler_start(&priv->client, EVENT_TXDONE_IND, 0);
-+ break;
-+ case EVENT_HIGH_RX_WM:
-+ default:
-+ break;
-+ }
-+
-+ return 0;
-+}
-+
-+static int pfe_eth_change_mtu(struct net_device *ndev, int new_mtu)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(ndev);
-+
-+ ndev->mtu = new_mtu;
-+ new_mtu += ETH_HLEN + ETH_FCS_LEN;
-+ gemac_set_rx_max_fl(priv->EMAC_baseaddr, new_mtu);
-+
-+ return 0;
-+}
-+
-+/* pfe_eth_open
-+ */
-+static int pfe_eth_open(struct net_device *ndev)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(ndev);
-+ struct hif_client_s *client;
-+ int rc;
-+
-+ netif_info(priv, ifup, ndev, "%s\n", __func__);
-+
-+ /* Register client driver with HIF */
-+ client = &priv->client;
-+ memset(client, 0, sizeof(*client));
-+ client->id = PFE_CL_GEM0 + priv->id;
-+ client->tx_qn = emac_txq_cnt;
-+ client->rx_qn = EMAC_RXQ_CNT;
-+ client->priv = priv;
-+ client->pfe = priv->pfe;
-+ client->event_handler = pfe_eth_event_handler;
-+
-+ client->tx_qsize = EMAC_TXQ_DEPTH;
-+ client->rx_qsize = EMAC_RXQ_DEPTH;
-+
-+ rc = hif_lib_client_register(client);
-+ if (rc) {
-+ netdev_err(ndev, "%s: hif_lib_client_register(%d) failed\n",
-+ __func__, client->id);
-+ goto err0;
-+ }
-+
-+ netif_info(priv, drv, ndev, "%s: registered client: %p\n", __func__,
-+ client);
-+
-+ pfe_gemac_init(priv);
-+
-+ if (!is_valid_ether_addr(ndev->dev_addr)) {
-+ netdev_err(ndev, "%s: invalid MAC address\n", __func__);
-+ rc = -EADDRNOTAVAIL;
-+ goto err1;
-+ }
-+
-+ gemac_set_laddrN(priv->EMAC_baseaddr,
-+ (struct pfe_mac_addr *)ndev->dev_addr, 1);
-+
-+ napi_enable(&priv->high_napi);
-+ napi_enable(&priv->low_napi);
-+ napi_enable(&priv->lro_napi);
-+
-+ rc = pfe_eth_start(priv);
-+
-+ netif_tx_wake_all_queues(ndev);
-+
-+ return rc;
-+
-+err1:
-+ hif_lib_client_unregister(&priv->client);
-+
-+err0:
-+ return rc;
-+}
-+
-+/*
-+ * pfe_eth_shutdown
-+ */
-+int pfe_eth_shutdown(struct net_device *ndev, int wake)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(ndev);
-+ int i, qstatus, id;
-+ unsigned long next_poll = jiffies + 1, end = jiffies +
-+ (TX_POLL_TIMEOUT_MS * HZ) / 1000;
-+ int tx_pkts, prv_tx_pkts;
-+
-+ netif_info(priv, ifdown, ndev, "%s\n", __func__);
-+
-+ for (i = 0; i < emac_txq_cnt; i++)
-+ hrtimer_cancel(&priv->fast_tx_timeout[i].timer);
-+
-+ netif_tx_stop_all_queues(ndev);
-+
-+ do {
-+ tx_pkts = 0;
-+ pfe_eth_flush_tx(priv);
-+
-+ for (i = 0; i < emac_txq_cnt; i++)
-+ tx_pkts += hif_lib_tx_pending(&priv->client, i);
-+
-+ if (tx_pkts) {
-+ /*Don't wait forever, break if we cross max timeout */
-+ if (time_after(jiffies, end)) {
-+ pr_err(
-+ "(%s)Tx is not complete after %dmsec\n",
-+ ndev->name, TX_POLL_TIMEOUT_MS);
-+ break;
-+ }
-+
-+ pr_info("%s : (%s) Waiting for tx packets to free. Pending tx pkts = %d.\n"
-+ , __func__, ndev->name, tx_pkts);
-+ if (need_resched())
-+ schedule();
-+ }
-+
-+ } while (tx_pkts);
-+
-+ end = jiffies + (TX_POLL_TIMEOUT_MS * HZ) / 1000;
-+
-+ prv_tx_pkts = tmu_pkts_processed(priv->id);
-+ /*
-+ * Wait till TMU transmits all pending packets
-+ * poll tmu_qstatus and pkts processed by TMU for every 10ms
-+ * Consider TMU is busy, If we see TMU qeueu pending or any packets
-+ * processed by TMU
-+ */
-+ while (1) {
-+ if (time_after(jiffies, next_poll)) {
-+ tx_pkts = tmu_pkts_processed(priv->id);
-+ qstatus = tmu_qstatus(priv->id) & 0x7ffff;
-+
-+ if (!qstatus && (tx_pkts == prv_tx_pkts))
-+ break;
-+ /* Don't wait forever, break if we cross max
-+ * timeout(TX_POLL_TIMEOUT_MS)
-+ */
-+ if (time_after(jiffies, end)) {
-+ pr_err("TMU%d is busy after %dmsec\n",
-+ priv->id, TX_POLL_TIMEOUT_MS);
-+ break;
-+ }
-+ prv_tx_pkts = tx_pkts;
-+ next_poll++;
-+ }
-+ if (need_resched())
-+ schedule();
-+ }
-+ /* Wait for some more time to complete transmitting packet if any */
-+ next_poll = jiffies + 1;
-+ while (1) {
-+ if (time_after(jiffies, next_poll))
-+ break;
-+ if (need_resched())
-+ schedule();
-+ }
-+
-+ pfe_eth_stop(ndev, wake);
-+
-+ napi_disable(&priv->lro_napi);
-+ napi_disable(&priv->low_napi);
-+ napi_disable(&priv->high_napi);
-+
-+ for (id = CLASS0_ID; id <= CLASS_MAX_ID; id++) {
-+ pe_dmem_write(id, 0, CLASS_DM_CRC_VALIDATED
-+ + (priv->id * 4), 4);
-+ }
-+
-+ hif_lib_client_unregister(&priv->client);
-+
-+ return 0;
-+}
-+
-+/* pfe_eth_close
-+ *
-+ */
-+static int pfe_eth_close(struct net_device *ndev)
-+{
-+ pfe_eth_shutdown(ndev, 0);
-+
-+ return 0;
-+}
-+
-+/* pfe_eth_suspend
-+ *
-+ * return value : 1 if netdevice is configured to wakeup system
-+ * 0 otherwise
-+ */
-+int pfe_eth_suspend(struct net_device *ndev)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(ndev);
-+ int retval = 0;
-+
-+ if (priv->wol) {
-+ gemac_set_wol(priv->EMAC_baseaddr, priv->wol);
-+ retval = 1;
-+ }
-+ pfe_eth_shutdown(ndev, priv->wol);
-+
-+ return retval;
-+}
-+
-+/* pfe_eth_resume
-+ *
-+ */
-+int pfe_eth_resume(struct net_device *ndev)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(ndev);
-+
-+ if (priv->wol)
-+ gemac_set_wol(priv->EMAC_baseaddr, 0);
-+ gemac_tx_enable(priv->EMAC_baseaddr);
-+
-+ return pfe_eth_open(ndev);
-+}
-+
-+/* pfe_eth_get_queuenum
-+ */
-+static int pfe_eth_get_queuenum(struct pfe_eth_priv_s *priv, struct sk_buff
-+ *skb)
-+{
-+ int queuenum = 0;
-+ unsigned long flags;
-+
-+ /* Get the Fast Path queue number */
-+ /*
-+ * Use conntrack mark (if conntrack exists), then packet mark (if any),
-+ * then fallback to default
-+ */
-+#if defined(CONFIG_IP_NF_CONNTRACK_MARK) || defined(CONFIG_NF_CONNTRACK_MARK)
-+ if (skb->_nfct) {
-+ enum ip_conntrack_info cinfo;
-+ struct nf_conn *ct;
-+
-+ ct = nf_ct_get(skb, &cinfo);
-+
-+ if (ct) {
-+ u32 connmark;
-+
-+ connmark = ct->mark;
-+
-+ if ((connmark & 0x80000000) && priv->id != 0)
-+ connmark >>= 16;
-+
-+ queuenum = connmark & EMAC_QUEUENUM_MASK;
-+ }
-+ } else {/* continued after #endif ... */
-+#endif
-+ if (skb->mark) {
-+ queuenum = skb->mark & EMAC_QUEUENUM_MASK;
-+ } else {
-+ spin_lock_irqsave(&priv->lock, flags);
-+ queuenum = priv->default_priority & EMAC_QUEUENUM_MASK;
-+ spin_unlock_irqrestore(&priv->lock, flags);
-+ }
-+#if defined(CONFIG_IP_NF_CONNTRACK_MARK) || defined(CONFIG_NF_CONNTRACK_MARK)
-+ }
-+#endif
-+ return queuenum;
-+}
-+
-+/* pfe_eth_might_stop_tx
-+ *
-+ */
-+static int pfe_eth_might_stop_tx(struct pfe_eth_priv_s *priv, int queuenum,
-+ struct netdev_queue *tx_queue,
-+ unsigned int n_desc,
-+ unsigned int n_segs)
-+{
-+ ktime_t kt;
-+ int tried = 0;
-+
-+try_again:
-+ if (unlikely((__hif_tx_avail(&pfe->hif) < n_desc) ||
-+ (hif_lib_tx_avail(&priv->client, queuenum) < n_desc) ||
-+ (hif_lib_tx_credit_avail(pfe, priv->id, queuenum) < n_segs))) {
-+ if (!tried) {
-+ __hif_lib_update_credit(&priv->client, queuenum);
-+ tried = 1;
-+ goto try_again;
-+ }
-+#ifdef PFE_ETH_TX_STATS
-+ if (__hif_tx_avail(&pfe->hif) < n_desc) {
-+ priv->stop_queue_hif[queuenum]++;
-+ } else if (hif_lib_tx_avail(&priv->client, queuenum) < n_desc) {
-+ priv->stop_queue_hif_client[queuenum]++;
-+ } else if (hif_lib_tx_credit_avail(pfe, priv->id, queuenum) <
-+ n_segs) {
-+ priv->stop_queue_credit[queuenum]++;
-+ }
-+ priv->stop_queue_total[queuenum]++;
-+#endif
-+ netif_tx_stop_queue(tx_queue);
-+
-+ kt = ktime_set(0, LS1012A_TX_FAST_RECOVERY_TIMEOUT_MS *
-+ NSEC_PER_MSEC);
-+ hrtimer_start(&priv->fast_tx_timeout[queuenum].timer, kt,
-+ HRTIMER_MODE_REL);
-+ return -1;
-+ } else {
-+ return 0;
-+ }
-+}
-+
-+#define SA_MAX_OP 2
-+/* pfe_hif_send_packet
-+ *
-+ * At this level if TX fails we drop the packet
-+ */
-+static void pfe_hif_send_packet(struct sk_buff *skb, struct pfe_eth_priv_s
-+ *priv, int queuenum)
-+{
-+ struct skb_shared_info *sh = skb_shinfo(skb);
-+ unsigned int nr_frags;
-+ u32 ctrl = 0;
-+
-+ netif_info(priv, tx_queued, priv->ndev, "%s\n", __func__);
-+
-+ if (skb_is_gso(skb)) {
-+ priv->stats.tx_dropped++;
-+ return;
-+ }
-+
-+ if (skb->ip_summed == CHECKSUM_PARTIAL)
-+ ctrl = HIF_CTRL_TX_CHECKSUM;
-+
-+ nr_frags = sh->nr_frags;
-+
-+ if (nr_frags) {
-+ skb_frag_t *f;
-+ int i;
-+
-+ __hif_lib_xmit_pkt(&priv->client, queuenum, skb->data,
-+ skb_headlen(skb), ctrl, HIF_FIRST_BUFFER,
-+ skb);
-+
-+ for (i = 0; i < nr_frags - 1; i++) {
-+ f = &sh->frags[i];
-+ __hif_lib_xmit_pkt(&priv->client, queuenum,
-+ skb_frag_address(f),
-+ skb_frag_size(f),
-+ 0x0, 0x0, skb);
-+ }
-+
-+ f = &sh->frags[i];
-+
-+ __hif_lib_xmit_pkt(&priv->client, queuenum,
-+ skb_frag_address(f), skb_frag_size(f),
-+ 0x0, HIF_LAST_BUFFER | HIF_DATA_VALID,
-+ skb);
-+
-+ netif_info(priv, tx_queued, priv->ndev,
-+ "%s: pkt sent successfully skb:%p nr_frags:%d len:%d\n",
-+ __func__, skb, nr_frags, skb->len);
-+ } else {
-+ __hif_lib_xmit_pkt(&priv->client, queuenum, skb->data,
-+ skb->len, ctrl, HIF_FIRST_BUFFER |
-+ HIF_LAST_BUFFER | HIF_DATA_VALID,
-+ skb);
-+ netif_info(priv, tx_queued, priv->ndev,
-+ "%s: pkt sent successfully skb:%p len:%d\n",
-+ __func__, skb, skb->len);
-+ }
-+ hif_tx_dma_start();
-+ priv->stats.tx_packets++;
-+ priv->stats.tx_bytes += skb->len;
-+ hif_lib_tx_credit_use(pfe, priv->id, queuenum, 1);
-+}
-+
-+/* pfe_eth_flush_txQ
-+ */
-+static void pfe_eth_flush_txQ(struct pfe_eth_priv_s *priv, int tx_q_num, int
-+ from_tx, int n_desc)
-+{
-+ struct sk_buff *skb;
-+ struct netdev_queue *tx_queue = netdev_get_tx_queue(priv->ndev,
-+ tx_q_num);
-+ unsigned int flags;
-+
-+ netif_info(priv, tx_done, priv->ndev, "%s\n", __func__);
-+
-+ if (!from_tx)
-+ __netif_tx_lock_bh(tx_queue);
-+
-+ /* Clean HIF and client queue */
-+ while ((skb = hif_lib_tx_get_next_complete(&priv->client,
-+ tx_q_num, &flags,
-+ HIF_TX_DESC_NT))) {
-+ if (flags & HIF_DATA_VALID)
-+ dev_kfree_skb_any(skb);
-+ }
-+ if (!from_tx)
-+ __netif_tx_unlock_bh(tx_queue);
-+}
-+
-+/* pfe_eth_flush_tx
-+ */
-+static void pfe_eth_flush_tx(struct pfe_eth_priv_s *priv)
-+{
-+ int ii;
-+
-+ netif_info(priv, tx_done, priv->ndev, "%s\n", __func__);
-+
-+ for (ii = 0; ii < emac_txq_cnt; ii++) {
-+ pfe_eth_flush_txQ(priv, ii, 0, 0);
-+ __hif_lib_update_credit(&priv->client, ii);
-+ }
-+}
-+
-+void pfe_tx_get_req_desc(struct sk_buff *skb, unsigned int *n_desc, unsigned int
-+ *n_segs)
-+{
-+ struct skb_shared_info *sh = skb_shinfo(skb);
-+
-+ /* Scattered data */
-+ if (sh->nr_frags) {
-+ *n_desc = sh->nr_frags + 1;
-+ *n_segs = 1;
-+ /* Regular case */
-+ } else {
-+ *n_desc = 1;
-+ *n_segs = 1;
-+ }
-+}
-+
-+/* pfe_eth_send_packet
-+ */
-+static int pfe_eth_send_packet(struct sk_buff *skb, struct net_device *ndev)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(ndev);
-+ int tx_q_num = skb_get_queue_mapping(skb);
-+ int n_desc, n_segs;
-+ struct netdev_queue *tx_queue = netdev_get_tx_queue(priv->ndev,
-+ tx_q_num);
-+
-+ netif_info(priv, tx_queued, ndev, "%s\n", __func__);
-+
-+ if ((!skb_is_gso(skb)) && (skb_headroom(skb) < (PFE_PKT_HEADER_SZ +
-+ sizeof(unsigned long)))) {
-+ netif_warn(priv, tx_err, priv->ndev, "%s: copying skb\n",
-+ __func__);
-+
-+ if (pskb_expand_head(skb, (PFE_PKT_HEADER_SZ + sizeof(unsigned
-+ long)), 0, GFP_ATOMIC)) {
-+ /* No need to re-transmit, no way to recover*/
-+ kfree_skb(skb);
-+ priv->stats.tx_dropped++;
-+ return NETDEV_TX_OK;
-+ }
-+ }
-+
-+ pfe_tx_get_req_desc(skb, &n_desc, &n_segs);
-+
-+ hif_tx_lock(&pfe->hif);
-+ if (unlikely(pfe_eth_might_stop_tx(priv, tx_q_num, tx_queue, n_desc,
-+ n_segs))) {
-+#ifdef PFE_ETH_TX_STATS
-+ if (priv->was_stopped[tx_q_num]) {
-+ priv->clean_fail[tx_q_num]++;
-+ priv->was_stopped[tx_q_num] = 0;
-+ }
-+#endif
-+ hif_tx_unlock(&pfe->hif);
-+ return NETDEV_TX_BUSY;
-+ }
-+
-+ pfe_hif_send_packet(skb, priv, tx_q_num);
-+
-+ hif_tx_unlock(&pfe->hif);
-+
-+ tx_queue->trans_start = jiffies;
-+
-+#ifdef PFE_ETH_TX_STATS
-+ priv->was_stopped[tx_q_num] = 0;
-+#endif
-+
-+ return NETDEV_TX_OK;
-+}
-+
-+/* pfe_eth_select_queue
-+ *
-+ */
-+static u16 pfe_eth_select_queue(struct net_device *ndev, struct sk_buff *skb,
-+ struct net_device *sb_dev)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(ndev);
-+
-+ return pfe_eth_get_queuenum(priv, skb);
-+}
-+
-+/* pfe_eth_get_stats
-+ */
-+static struct net_device_stats *pfe_eth_get_stats(struct net_device *ndev)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(ndev);
-+
-+ netif_info(priv, drv, ndev, "%s\n", __func__);
-+
-+ return &priv->stats;
-+}
-+
-+/* pfe_eth_set_mac_address
-+ */
-+static int pfe_eth_set_mac_address(struct net_device *ndev, void *addr)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(ndev);
-+ struct sockaddr *sa = addr;
-+
-+ netif_info(priv, drv, ndev, "%s\n", __func__);
-+
-+ if (!is_valid_ether_addr(sa->sa_data))
-+ return -EADDRNOTAVAIL;
-+
-+ dev_addr_set(ndev, sa->sa_data);
-+
-+ gemac_set_laddrN(priv->EMAC_baseaddr,
-+ (struct pfe_mac_addr *)ndev->dev_addr, 1);
-+
-+ return 0;
-+}
-+
-+/* pfe_eth_enet_addr_byte_mac
-+ */
-+int pfe_eth_enet_addr_byte_mac(u8 *enet_byte_addr,
-+ struct pfe_mac_addr *enet_addr)
-+{
-+ if (!enet_byte_addr || !enet_addr) {
-+ return -1;
-+
-+ } else {
-+ enet_addr->bottom = enet_byte_addr[0] |
-+ (enet_byte_addr[1] << 8) |
-+ (enet_byte_addr[2] << 16) |
-+ (enet_byte_addr[3] << 24);
-+ enet_addr->top = enet_byte_addr[4] |
-+ (enet_byte_addr[5] << 8);
-+ return 0;
-+ }
-+}
-+
-+/* pfe_eth_set_multi
-+ */
-+static void pfe_eth_set_multi(struct net_device *ndev)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(ndev);
-+ struct pfe_mac_addr hash_addr; /* hash register structure */
-+ /* specific mac address register structure */
-+ struct pfe_mac_addr spec_addr;
-+ int result; /* index into hash register to set.. */
-+ int uc_count = 0;
-+ struct netdev_hw_addr *ha;
-+
-+ if (ndev->flags & IFF_PROMISC) {
-+ netif_info(priv, drv, ndev, "entering promiscuous mode\n");
-+
-+ priv->promisc = 1;
-+ gemac_enable_copy_all(priv->EMAC_baseaddr);
-+ } else {
-+ priv->promisc = 0;
-+ gemac_disable_copy_all(priv->EMAC_baseaddr);
-+ }
-+
-+ /* Enable broadcast frame reception if required. */
-+ if (ndev->flags & IFF_BROADCAST) {
-+ gemac_allow_broadcast(priv->EMAC_baseaddr);
-+ } else {
-+ netif_info(priv, drv, ndev,
-+ "disabling broadcast frame reception\n");
-+
-+ gemac_no_broadcast(priv->EMAC_baseaddr);
-+ }
-+
-+ if (ndev->flags & IFF_ALLMULTI) {
-+ /* Set the hash to rx all multicast frames */
-+ hash_addr.bottom = 0xFFFFFFFF;
-+ hash_addr.top = 0xFFFFFFFF;
-+ gemac_set_hash(priv->EMAC_baseaddr, &hash_addr);
-+ netdev_for_each_uc_addr(ha, ndev) {
-+ if (uc_count >= MAX_UC_SPEC_ADDR_REG)
-+ break;
-+ pfe_eth_enet_addr_byte_mac(ha->addr, &spec_addr);
-+ gemac_set_laddrN(priv->EMAC_baseaddr, &spec_addr,
-+ uc_count + 2);
-+ uc_count++;
-+ }
-+ } else if ((netdev_mc_count(ndev) > 0) || (netdev_uc_count(ndev))) {
-+ u8 *addr;
-+
-+ hash_addr.bottom = 0;
-+ hash_addr.top = 0;
-+
-+ netdev_for_each_mc_addr(ha, ndev) {
-+ addr = ha->addr;
-+
-+ netif_info(priv, drv, ndev,
-+ "adding multicast address %X:%X:%X:%X:%X:%X to gem filter\n",
-+ addr[0], addr[1], addr[2],
-+ addr[3], addr[4], addr[5]);
-+
-+ result = pfe_eth_get_hash(addr);
-+
-+ if (result < EMAC_HASH_REG_BITS) {
-+ if (result < 32)
-+ hash_addr.bottom |= (1 << result);
-+ else
-+ hash_addr.top |= (1 << (result - 32));
-+ } else {
-+ break;
-+ }
-+ }
-+
-+ uc_count = -1;
-+ netdev_for_each_uc_addr(ha, ndev) {
-+ addr = ha->addr;
-+
-+ if (++uc_count < MAX_UC_SPEC_ADDR_REG) {
-+ netdev_info(ndev,
-+ "adding unicast address %02x:%02x:%02x:%02x:%02x:%02x to gem filter\n",
-+ addr[0], addr[1], addr[2],
-+ addr[3], addr[4], addr[5]);
-+ pfe_eth_enet_addr_byte_mac(addr, &spec_addr);
-+ gemac_set_laddrN(priv->EMAC_baseaddr,
-+ &spec_addr, uc_count + 2);
-+ } else {
-+ netif_info(priv, drv, ndev,
-+ "adding unicast address %02x:%02x:%02x:%02x:%02x:%02x to gem hash\n",
-+ addr[0], addr[1], addr[2],
-+ addr[3], addr[4], addr[5]);
-+
-+ result = pfe_eth_get_hash(addr);
-+ if (result >= EMAC_HASH_REG_BITS) {
-+ break;
-+
-+ } else {
-+ if (result < 32)
-+ hash_addr.bottom |= (1 <<
-+ result);
-+ else
-+ hash_addr.top |= (1 <<
-+ (result - 32));
-+ }
-+ }
-+ }
-+
-+ gemac_set_hash(priv->EMAC_baseaddr, &hash_addr);
-+ }
-+
-+ if (!(netdev_uc_count(ndev) >= MAX_UC_SPEC_ADDR_REG)) {
-+ /*
-+ * Check if there are any specific address HW registers that
-+ * need to be flushed
-+ */
-+ for (uc_count = netdev_uc_count(ndev); uc_count <
-+ MAX_UC_SPEC_ADDR_REG; uc_count++)
-+ gemac_clear_laddrN(priv->EMAC_baseaddr, uc_count + 2);
-+ }
-+
-+ if (ndev->flags & IFF_LOOPBACK)
-+ gemac_set_loop(priv->EMAC_baseaddr, LB_LOCAL);
-+}
-+
-+/* pfe_eth_set_features
-+ */
-+static int pfe_eth_set_features(struct net_device *ndev, netdev_features_t
-+ features)
-+{
-+ struct pfe_eth_priv_s *priv = netdev_priv(ndev);
-+ int rc = 0;
-+
-+ if (features & NETIF_F_RXCSUM)
-+ gemac_enable_rx_checksum_offload(priv->EMAC_baseaddr);
-+ else
-+ gemac_disable_rx_checksum_offload(priv->EMAC_baseaddr);
-+ return rc;
-+}
-+
-+/* pfe_eth_fast_tx_timeout
-+ */
-+static enum hrtimer_restart pfe_eth_fast_tx_timeout(struct hrtimer *timer)
-+{
-+ struct pfe_eth_fast_timer *fast_tx_timeout = container_of(timer, struct
-+ pfe_eth_fast_timer,
-+ timer);
-+ struct pfe_eth_priv_s *priv = container_of(fast_tx_timeout->base,
-+ struct pfe_eth_priv_s,
-+ fast_tx_timeout);
-+ struct netdev_queue *tx_queue = netdev_get_tx_queue(priv->ndev,
-+ fast_tx_timeout->queuenum);
-+
-+ if (netif_tx_queue_stopped(tx_queue)) {
-+#ifdef PFE_ETH_TX_STATS
-+ priv->was_stopped[fast_tx_timeout->queuenum] = 1;
-+#endif
-+ netif_tx_wake_queue(tx_queue);
-+ }
-+
-+ return HRTIMER_NORESTART;
-+}
-+
-+/* pfe_eth_fast_tx_timeout_init
-+ */
-+static void pfe_eth_fast_tx_timeout_init(struct pfe_eth_priv_s *priv)
-+{
-+ int i;
-+
-+ for (i = 0; i < emac_txq_cnt; i++) {
-+ priv->fast_tx_timeout[i].queuenum = i;
-+ hrtimer_init(&priv->fast_tx_timeout[i].timer, CLOCK_MONOTONIC,
-+ HRTIMER_MODE_REL);
-+ priv->fast_tx_timeout[i].timer.function =
-+ pfe_eth_fast_tx_timeout;
-+ priv->fast_tx_timeout[i].base = priv->fast_tx_timeout;
-+ }
-+}
-+
-+static struct sk_buff *pfe_eth_rx_skb(struct net_device *ndev,
-+ struct pfe_eth_priv_s *priv,
-+ unsigned int qno)
-+{
-+ void *buf_addr;
-+ unsigned int rx_ctrl;
-+ unsigned int desc_ctrl = 0;
-+ struct hif_ipsec_hdr *ipsec_hdr = NULL;
-+ struct sk_buff *skb;
-+ struct sk_buff *skb_frag, *skb_frag_last = NULL;
-+ int length = 0, offset;
-+
-+ skb = priv->skb_inflight[qno];
-+
-+ if (skb) {
-+ skb_frag_last = skb_shinfo(skb)->frag_list;
-+ if (skb_frag_last) {
-+ while (skb_frag_last->next)
-+ skb_frag_last = skb_frag_last->next;
-+ }
-+ }
-+
-+ while (!(desc_ctrl & CL_DESC_LAST)) {
-+ buf_addr = hif_lib_receive_pkt(&priv->client, qno, &length,
-+ &offset, &rx_ctrl, &desc_ctrl,
-+ (void **)&ipsec_hdr);
-+ if (!buf_addr)
-+ goto incomplete;
-+
-+#ifdef PFE_ETH_NAPI_STATS
-+ priv->napi_counters[NAPI_DESC_COUNT]++;
-+#endif
-+
-+ /* First frag */
-+ if (desc_ctrl & CL_DESC_FIRST) {
-+ skb = build_skb(buf_addr, 0);
-+ if (unlikely(!skb))
-+ goto pkt_drop;
-+
-+ skb_reserve(skb, offset);
-+ skb_put(skb, length);
-+ skb->dev = ndev;
-+
-+ if ((ndev->features & NETIF_F_RXCSUM) && (rx_ctrl &
-+ HIF_CTRL_RX_CHECKSUMMED))
-+ skb->ip_summed = CHECKSUM_UNNECESSARY;
-+ else
-+ skb_checksum_none_assert(skb);
-+
-+ } else {
-+ /* Next frags */
-+ if (unlikely(!skb)) {
-+ pr_err("%s: NULL skb_inflight\n",
-+ __func__);
-+ goto pkt_drop;
-+ }
-+
-+ skb_frag = build_skb(buf_addr, 0);
-+
-+ if (unlikely(!skb_frag)) {
-+ kfree(buf_addr);
-+ goto pkt_drop;
-+ }
-+
-+ skb_reserve(skb_frag, offset);
-+ skb_put(skb_frag, length);
-+
-+ skb_frag->dev = ndev;
-+
-+ if (skb_shinfo(skb)->frag_list)
-+ skb_frag_last->next = skb_frag;
-+ else
-+ skb_shinfo(skb)->frag_list = skb_frag;
-+
-+ skb->truesize += skb_frag->truesize;
-+ skb->data_len += length;
-+ skb->len += length;
-+ skb_frag_last = skb_frag;
-+ }
-+ }
-+
-+ priv->skb_inflight[qno] = NULL;
-+ return skb;
-+
-+incomplete:
-+ priv->skb_inflight[qno] = skb;
-+ return NULL;
-+
-+pkt_drop:
-+ priv->skb_inflight[qno] = NULL;
-+
-+ if (skb)
-+ kfree_skb(skb);
-+ else
-+ kfree(buf_addr);
-+
-+ priv->stats.rx_errors++;
-+
-+ return NULL;
-+}
-+
-+/* pfe_eth_poll
-+ */
-+static int pfe_eth_poll(struct pfe_eth_priv_s *priv, struct napi_struct *napi,
-+ unsigned int qno, int budget)
-+{
-+ struct net_device *ndev = priv->ndev;
-+ struct sk_buff *skb;
-+ int work_done = 0;
-+ unsigned int len;
-+
-+ netif_info(priv, intr, priv->ndev, "%s\n", __func__);
-+
-+#ifdef PFE_ETH_NAPI_STATS
-+ priv->napi_counters[NAPI_POLL_COUNT]++;
-+#endif
-+
-+ do {
-+ skb = pfe_eth_rx_skb(ndev, priv, qno);
-+
-+ if (!skb)
-+ break;
-+
-+ len = skb->len;
-+
-+ /* Packet will be processed */
-+ skb->protocol = eth_type_trans(skb, ndev);
-+
-+ netif_receive_skb(skb);
-+
-+ priv->stats.rx_packets++;
-+ priv->stats.rx_bytes += len;
-+
-+ work_done++;
-+
-+#ifdef PFE_ETH_NAPI_STATS
-+ priv->napi_counters[NAPI_PACKET_COUNT]++;
-+#endif
-+
-+ } while (work_done < budget);
-+
-+ /*
-+ * If no Rx receive nor cleanup work was done, exit polling mode.
-+ * No more netif_running(dev) check is required here , as this is
-+ * checked in net/core/dev.c (2.6.33.5 kernel specific).
-+ */
-+ if (work_done < budget) {
-+ napi_complete(napi);
-+
-+ hif_lib_event_handler_start(&priv->client, EVENT_RX_PKT_IND,
-+ qno);
-+ }
-+#ifdef PFE_ETH_NAPI_STATS
-+ else
-+ priv->napi_counters[NAPI_FULL_BUDGET_COUNT]++;
-+#endif
-+
-+ return work_done;
-+}
-+
-+/*
-+ * pfe_eth_lro_poll
-+ */
-+static int pfe_eth_lro_poll(struct napi_struct *napi, int budget)
-+{
-+ struct pfe_eth_priv_s *priv = container_of(napi, struct pfe_eth_priv_s,
-+ lro_napi);
-+
-+ netif_info(priv, intr, priv->ndev, "%s\n", __func__);
-+
-+ return pfe_eth_poll(priv, napi, 2, budget);
-+}
-+
-+/* pfe_eth_low_poll
-+ */
-+static int pfe_eth_low_poll(struct napi_struct *napi, int budget)
-+{
-+ struct pfe_eth_priv_s *priv = container_of(napi, struct pfe_eth_priv_s,
-+ low_napi);
-+
-+ netif_info(priv, intr, priv->ndev, "%s\n", __func__);
-+
-+ return pfe_eth_poll(priv, napi, 1, budget);
-+}
-+
-+/* pfe_eth_high_poll
-+ */
-+static int pfe_eth_high_poll(struct napi_struct *napi, int budget)
-+{
-+ struct pfe_eth_priv_s *priv = container_of(napi, struct pfe_eth_priv_s,
-+ high_napi);
-+
-+ netif_info(priv, intr, priv->ndev, "%s\n", __func__);
-+
-+ return pfe_eth_poll(priv, napi, 0, budget);
-+}
-+
-+static const struct net_device_ops pfe_netdev_ops = {
-+ .ndo_open = pfe_eth_open,
-+ .ndo_stop = pfe_eth_close,
-+ .ndo_start_xmit = pfe_eth_send_packet,
-+ .ndo_select_queue = pfe_eth_select_queue,
-+ .ndo_set_rx_mode = pfe_eth_set_multi,
-+ .ndo_set_mac_address = pfe_eth_set_mac_address,
-+ .ndo_validate_addr = eth_validate_addr,
-+ .ndo_change_mtu = pfe_eth_change_mtu,
-+ .ndo_get_stats = pfe_eth_get_stats,
-+ .ndo_set_features = pfe_eth_set_features,
-+};
-+
-+/* pfe_eth_init_one
-+ */
-+static int pfe_eth_init_one(struct pfe *pfe,
-+ struct ls1012a_pfe_platform_data *pfe_info,
-+ int id)
-+{
-+ struct net_device *ndev = NULL;
-+ struct pfe_eth_priv_s *priv = NULL;
-+ struct ls1012a_eth_platform_data *einfo;
-+ int err;
-+
-+ einfo = (struct ls1012a_eth_platform_data *)
-+ pfe_info->ls1012a_eth_pdata;
-+
-+ /* einfo never be NULL, but no harm in having this check */
-+ if (!einfo) {
-+ pr_err(
-+ "%s: pfe missing additional gemacs platform data\n"
-+ , __func__);
-+ err = -ENODEV;
-+ goto err0;
-+ }
-+
-+ if (us)
-+ emac_txq_cnt = EMAC_TXQ_CNT;
-+ /* Create an ethernet device instance */
-+ ndev = alloc_etherdev_mq(sizeof(*priv), emac_txq_cnt);
-+
-+ if (!ndev) {
-+ pr_err("%s: gemac %d device allocation failed\n",
-+ __func__, einfo[id].gem_id);
-+ err = -ENOMEM;
-+ goto err0;
-+ }
-+
-+ priv = netdev_priv(ndev);
-+ priv->ndev = ndev;
-+ priv->id = einfo[id].gem_id;
-+ priv->pfe = pfe;
-+ priv->phy_node = einfo[id].phy_node;
-+
-+ SET_NETDEV_DEV(priv->ndev, priv->pfe->dev);
-+
-+ pfe->eth.eth_priv[id] = priv;
-+
-+ /* Set the info in the priv to the current info */
-+ priv->einfo = &einfo[id];
-+ priv->EMAC_baseaddr = cbus_emac_base[id];
-+ priv->GPI_baseaddr = cbus_gpi_base[id];
-+
-+ spin_lock_init(&priv->lock);
-+
-+ pfe_eth_fast_tx_timeout_init(priv);
-+
-+ /* Copy the station address into the dev structure, */
-+ dev_addr_set(ndev, einfo[id].mac_addr);
-+
-+ if (us)
-+ goto phy_init;
-+
-+ ndev->mtu = 1500;
-+
-+ /* Set MTU limits */
-+ ndev->min_mtu = ETH_MIN_MTU;
-+
-+/*
-+ * Jumbo frames are not supported on LS1012A rev-1.0.
-+ * So max mtu should be restricted to supported frame length.
-+ */
-+ if (pfe_errata_a010897)
-+ ndev->max_mtu = JUMBO_FRAME_SIZE_V1 - ETH_HLEN - ETH_FCS_LEN;
-+ else
-+ ndev->max_mtu = JUMBO_FRAME_SIZE_V2 - ETH_HLEN - ETH_FCS_LEN;
-+
-+ /*Enable after checksum offload is validated */
-+ ndev->hw_features = NETIF_F_RXCSUM | NETIF_F_IP_CSUM |
-+ NETIF_F_IPV6_CSUM | NETIF_F_SG;
-+
-+ /* enabled by default */
-+ ndev->features = ndev->hw_features;
-+
-+ priv->usr_features = ndev->features;
-+
-+ ndev->netdev_ops = &pfe_netdev_ops;
-+
-+ ndev->ethtool_ops = &pfe_ethtool_ops;
-+
-+ /* Enable basic messages by default */
-+ priv->msg_enable = NETIF_MSG_IFUP | NETIF_MSG_IFDOWN | NETIF_MSG_LINK |
-+ NETIF_MSG_PROBE;
-+
-+ netif_napi_add(ndev, &priv->low_napi, pfe_eth_low_poll);
-+ netif_napi_add(ndev, &priv->high_napi, pfe_eth_high_poll);
-+ netif_napi_add(ndev, &priv->lro_napi, pfe_eth_lro_poll);
-+
-+ err = register_netdev(ndev);
-+ if (err) {
-+ netdev_err(ndev, "register_netdev() failed\n");
-+ goto err1;
-+ }
-+
-+ if ((!(pfe_use_old_dts_phy) && !(priv->phy_node)) ||
-+ ((pfe_use_old_dts_phy) &&
-+ (priv->einfo->phy_flags & GEMAC_NO_PHY))) {
-+ pr_info("%s: No PHY or fixed-link\n", __func__);
-+ goto skip_phy_init;
-+ }
-+
-+phy_init:
-+ device_init_wakeup(&ndev->dev, true);
-+
-+ err = pfe_phy_init(ndev);
-+ if (err) {
-+ netdev_err(ndev, "%s: pfe_phy_init() failed\n",
-+ __func__);
-+ goto err2;
-+ }
-+
-+ if (us) {
-+ if (priv->phydev)
-+ phy_start(priv->phydev);
-+ return 0;
-+ }
-+
-+ netif_carrier_on(ndev);
-+
-+skip_phy_init:
-+ /* Create all the sysfs files */
-+ if (pfe_eth_sysfs_init(ndev))
-+ goto err3;
-+
-+ netif_info(priv, probe, ndev, "%s: created interface, baseaddr: %p\n",
-+ __func__, priv->EMAC_baseaddr);
-+
-+ return 0;
-+
-+err3:
-+ pfe_phy_exit(priv->ndev);
-+err2:
-+ if (us)
-+ goto err1;
-+ unregister_netdev(ndev);
-+err1:
-+ free_netdev(priv->ndev);
-+err0:
-+ return err;
-+}
-+
-+/* pfe_eth_init
-+ */
-+int pfe_eth_init(struct pfe *pfe)
-+{
-+ int ii = 0;
-+ int err;
-+ struct ls1012a_pfe_platform_data *pfe_info;
-+
-+ pr_info("%s\n", __func__);
-+
-+ cbus_emac_base[0] = EMAC1_BASE_ADDR;
-+ cbus_emac_base[1] = EMAC2_BASE_ADDR;
-+
-+ cbus_gpi_base[0] = EGPI1_BASE_ADDR;
-+ cbus_gpi_base[1] = EGPI2_BASE_ADDR;
-+
-+ pfe_info = (struct ls1012a_pfe_platform_data *)
-+ pfe->dev->platform_data;
-+ if (!pfe_info) {
-+ pr_err("%s: pfe missing additional platform data\n", __func__);
-+ err = -ENODEV;
-+ goto err_pdata;
-+ }
-+
-+ for (ii = 0; ii < NUM_GEMAC_SUPPORT; ii++) {
-+ err = pfe_eth_mdio_init(pfe, pfe_info, ii);
-+ if (err) {
-+ pr_err("%s: pfe_eth_mdio_init() failed\n", __func__);
-+ goto err_mdio_init;
-+ }
-+ }
-+
-+ if (soc_device_match(ls1012a_rev1_soc_attr))
-+ pfe_errata_a010897 = true;
-+ else
-+ pfe_errata_a010897 = false;
-+
-+ for (ii = 0; ii < NUM_GEMAC_SUPPORT; ii++) {
-+ err = pfe_eth_init_one(pfe, pfe_info, ii);
-+ if (err)
-+ goto err_eth_init;
-+ }
-+
-+ return 0;
-+
-+err_eth_init:
-+ while (ii--) {
-+ pfe_eth_exit_one(pfe->eth.eth_priv[ii]);
-+ pfe_eth_mdio_exit(pfe, ii);
-+ }
-+
-+err_mdio_init:
-+err_pdata:
-+ return err;
-+}
-+
-+/* pfe_eth_exit_one
-+ */
-+static void pfe_eth_exit_one(struct pfe_eth_priv_s *priv)
-+{
-+ netif_info(priv, probe, priv->ndev, "%s\n", __func__);
-+
-+ if (!us)
-+ pfe_eth_sysfs_exit(priv->ndev);
-+
-+ if ((!(pfe_use_old_dts_phy) && !(priv->phy_node)) ||
-+ ((pfe_use_old_dts_phy) &&
-+ (priv->einfo->phy_flags & GEMAC_NO_PHY))) {
-+ pr_info("%s: No PHY or fixed-link\n", __func__);
-+ goto skip_phy_exit;
-+ }
-+
-+ pfe_phy_exit(priv->ndev);
-+
-+skip_phy_exit:
-+ if (!us)
-+ unregister_netdev(priv->ndev);
-+
-+ free_netdev(priv->ndev);
-+}
-+
-+/* pfe_eth_exit
-+ */
-+void pfe_eth_exit(struct pfe *pfe)
-+{
-+ int ii;
-+
-+ pr_info("%s\n", __func__);
-+
-+ for (ii = NUM_GEMAC_SUPPORT - 1; ii >= 0; ii--)
-+ pfe_eth_exit_one(pfe->eth.eth_priv[ii]);
-+
-+ for (ii = NUM_GEMAC_SUPPORT - 1; ii >= 0; ii--)
-+ pfe_eth_mdio_exit(pfe, ii);
-+}
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/pfe_eth.h
-@@ -0,0 +1,175 @@
-+/* SPDX-License-Identifier: GPL-2.0+ */
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ */
-+
-+#ifndef _PFE_ETH_H_
-+#define _PFE_ETH_H_
-+#include <linux/kernel.h>
-+#include <linux/netdevice.h>
-+#include <linux/etherdevice.h>
-+#include <linux/ethtool.h>
-+#include <linux/mii.h>
-+#include <linux/phy.h>
-+#include <linux/clk.h>
-+#include <linux/interrupt.h>
-+#include <linux/time.h>
-+
-+#define PFE_ETH_NAPI_STATS
-+#define PFE_ETH_TX_STATS
-+
-+#define PFE_ETH_FRAGS_MAX (65536 / HIF_RX_PKT_MIN_SIZE)
-+#define LRO_LEN_COUNT_MAX 32
-+#define LRO_NB_COUNT_MAX 32
-+
-+#define PFE_PAUSE_FLAG_ENABLE 1
-+#define PFE_PAUSE_FLAG_AUTONEG 2
-+
-+/* GEMAC configured by SW */
-+/* GEMAC configured by phy lines (not for MII/GMII) */
-+
-+#define GEMAC_SW_FULL_DUPLEX BIT(9)
-+#define GEMAC_SW_SPEED_10M (0 << 12)
-+#define GEMAC_SW_SPEED_100M BIT(12)
-+#define GEMAC_SW_SPEED_1G (2 << 12)
-+
-+#define GEMAC_NO_PHY BIT(0)
-+
-+struct ls1012a_eth_platform_data {
-+ /* board specific information */
-+ phy_interface_t mii_config;
-+ u32 phy_flags;
-+ u32 gem_id;
-+ u32 phy_id;
-+ u32 mdio_muxval;
-+ u8 mac_addr[ETH_ALEN];
-+ struct device_node *phy_node;
-+};
-+
-+struct ls1012a_mdio_platform_data {
-+ int id;
-+ int irq[32];
-+ u32 phy_mask;
-+ int mdc_div;
-+};
-+
-+struct ls1012a_pfe_platform_data {
-+ struct ls1012a_eth_platform_data ls1012a_eth_pdata[3];
-+ struct ls1012a_mdio_platform_data ls1012a_mdio_pdata[3];
-+};
-+
-+#define NUM_GEMAC_SUPPORT 2
-+#define DRV_NAME "pfe-eth"
-+#define DRV_VERSION "1.0"
-+
-+#define LS1012A_TX_FAST_RECOVERY_TIMEOUT_MS 3
-+#define TX_POLL_TIMEOUT_MS 1000
-+
-+#define EMAC_TXQ_CNT 16
-+#define EMAC_TXQ_DEPTH (HIF_TX_DESC_NT)
-+
-+#define JUMBO_FRAME_SIZE_V1 1900
-+#define JUMBO_FRAME_SIZE_V2 10258
-+/*
-+ * Client Tx queue threshold, for txQ flush condition.
-+ * It must be smaller than the queue size (in case we ever change it in the
-+ * future).
-+ */
-+#define HIF_CL_TX_FLUSH_MARK 32
-+
-+/*
-+ * Max number of TX resources (HIF descriptors or skbs) that will be released
-+ * in a single go during batch recycling.
-+ * Should be lower than the flush mark so the SW can provide the HW with a
-+ * continuous stream of packets instead of bursts.
-+ */
-+#define TX_FREE_MAX_COUNT 16
-+#define EMAC_RXQ_CNT 3
-+#define EMAC_RXQ_DEPTH HIF_RX_DESC_NT
-+/* make sure clients can receive a full burst of packets */
-+#define EMAC_RMON_TXBYTES_POS 0x00
-+#define EMAC_RMON_RXBYTES_POS 0x14
-+
-+#define EMAC_QUEUENUM_MASK (emac_txq_cnt - 1)
-+#define EMAC_MDIO_TIMEOUT 1000
-+#define MAX_UC_SPEC_ADDR_REG 31
-+
-+struct pfe_eth_fast_timer {
-+ int queuenum;
-+ struct hrtimer timer;
-+ void *base;
-+};
-+
-+struct pfe_eth_priv_s {
-+ struct pfe *pfe;
-+ struct hif_client_s client;
-+ struct napi_struct lro_napi;
-+ struct napi_struct low_napi;
-+ struct napi_struct high_napi;
-+ int low_tmu_q;
-+ int high_tmu_q;
-+ struct net_device_stats stats;
-+ struct net_device *ndev;
-+ int id;
-+ int promisc;
-+ unsigned int msg_enable;
-+ unsigned int usr_features;
-+
-+ spinlock_t lock; /* protect member variables */
-+ unsigned int event_status;
-+ int irq;
-+ void *EMAC_baseaddr;
-+ void *GPI_baseaddr;
-+ /* PHY stuff */
-+ struct phy_device *phydev;
-+ int oldspeed;
-+ int oldduplex;
-+ int oldlink;
-+ struct device_node *phy_node;
-+ struct clk *gemtx_clk;
-+ int wol;
-+ int pause_flag;
-+
-+ int default_priority;
-+ struct pfe_eth_fast_timer fast_tx_timeout[EMAC_TXQ_CNT];
-+
-+ struct ls1012a_eth_platform_data *einfo;
-+ struct sk_buff *skb_inflight[EMAC_RXQ_CNT + 6];
-+
-+#ifdef PFE_ETH_TX_STATS
-+ unsigned int stop_queue_total[EMAC_TXQ_CNT];
-+ unsigned int stop_queue_hif[EMAC_TXQ_CNT];
-+ unsigned int stop_queue_hif_client[EMAC_TXQ_CNT];
-+ unsigned int stop_queue_credit[EMAC_TXQ_CNT];
-+ unsigned int clean_fail[EMAC_TXQ_CNT];
-+ unsigned int was_stopped[EMAC_TXQ_CNT];
-+#endif
-+
-+#ifdef PFE_ETH_NAPI_STATS
-+ unsigned int napi_counters[NAPI_MAX_COUNT];
-+#endif
-+ unsigned int frags_inflight[EMAC_RXQ_CNT + 6];
-+};
-+
-+struct pfe_eth {
-+ struct pfe_eth_priv_s *eth_priv[3];
-+};
-+
-+struct pfe_mdio_priv_s {
-+ void __iomem *mdio_base;
-+ int mdc_div;
-+ struct mii_bus *mii_bus;
-+};
-+
-+struct pfe_mdio {
-+ struct pfe_mdio_priv_s *mdio_priv[3];
-+};
-+
-+int pfe_eth_init(struct pfe *pfe);
-+void pfe_eth_exit(struct pfe *pfe);
-+int pfe_eth_suspend(struct net_device *dev);
-+int pfe_eth_resume(struct net_device *dev);
-+int pfe_eth_mdio_reset(struct mii_bus *bus);
-+
-+#endif /* _PFE_ETH_H_ */
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/pfe_firmware.c
-@@ -0,0 +1,398 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ */
-+
-+/*
-+ * @file
-+ * Contains all the functions to handle parsing and loading of PE firmware
-+ * files.
-+ */
-+#include <linux/firmware.h>
-+
-+#include "pfe_mod.h"
-+#include "pfe_firmware.h"
-+#include "pfe/pfe.h"
-+#include <linux/of_platform.h>
-+#include <linux/of_address.h>
-+
-+static struct elf32_shdr *get_elf_section_header(const u8 *fw,
-+ const char *section)
-+{
-+ struct elf32_hdr *elf_hdr = (struct elf32_hdr *)fw;
-+ struct elf32_shdr *shdr;
-+ struct elf32_shdr *shdr_shstr;
-+ Elf32_Off e_shoff = be32_to_cpu(elf_hdr->e_shoff);
-+ Elf32_Half e_shentsize = be16_to_cpu(elf_hdr->e_shentsize);
-+ Elf32_Half e_shnum = be16_to_cpu(elf_hdr->e_shnum);
-+ Elf32_Half e_shstrndx = be16_to_cpu(elf_hdr->e_shstrndx);
-+ Elf32_Off shstr_offset;
-+ Elf32_Word sh_name;
-+ const char *name;
-+ int i;
-+
-+ /* Section header strings */
-+ shdr_shstr = (struct elf32_shdr *)((u8 *)elf_hdr + e_shoff + e_shstrndx
-+ * e_shentsize);
-+ shstr_offset = be32_to_cpu(shdr_shstr->sh_offset);
-+
-+ for (i = 0; i < e_shnum; i++) {
-+ shdr = (struct elf32_shdr *)((u8 *)elf_hdr + e_shoff
-+ + i * e_shentsize);
-+
-+ sh_name = be32_to_cpu(shdr->sh_name);
-+
-+ name = (const char *)((u8 *)elf_hdr + shstr_offset + sh_name);
-+
-+ if (!strcmp(name, section))
-+ return shdr;
-+ }
-+
-+ pr_err("%s: didn't find section %s\n", __func__, section);
-+
-+ return NULL;
-+}
-+
-+#if defined(CFG_DIAGS)
-+static int pfe_get_diags_info(const u8 *fw, struct pfe_diags_info
-+ *diags_info)
-+{
-+ struct elf32_shdr *shdr;
-+ unsigned long offset, size;
-+
-+ shdr = get_elf_section_header(fw, ".pfe_diags_str");
-+ if (shdr) {
-+ offset = be32_to_cpu(shdr->sh_offset);
-+ size = be32_to_cpu(shdr->sh_size);
-+ diags_info->diags_str_base = be32_to_cpu(shdr->sh_addr);
-+ diags_info->diags_str_size = size;
-+ diags_info->diags_str_array = kmalloc(size, GFP_KERNEL);
-+ memcpy(diags_info->diags_str_array, fw + offset, size);
-+
-+ return 0;
-+ } else {
-+ return -1;
-+ }
-+}
-+#endif
-+
-+static void pfe_check_version_info(const u8 *fw)
-+{
-+ /*static char *version = NULL;*/
-+ const u8 *elf_data = fw;
-+ static char *version;
-+
-+ struct elf32_shdr *shdr = get_elf_section_header(fw, ".version");
-+
-+ if (shdr) {
-+ if (!version) {
-+ /*
-+ * this is the first fw we load, use its version
-+ * string as reference (whatever it is)
-+ */
-+ version = (char *)(elf_data +
-+ be32_to_cpu(shdr->sh_offset));
-+
-+ pr_info("PFE binary version: %s\n", version);
-+ } else {
-+ /*
-+ * already have loaded at least one firmware, check
-+ * sequence can start now
-+ */
-+ if (strcmp(version, (char *)(elf_data +
-+ be32_to_cpu(shdr->sh_offset)))) {
-+ pr_info(
-+ "WARNING: PFE firmware binaries from incompatible version\n");
-+ }
-+ }
-+ } else {
-+ /*
-+ * version cannot be verified, a potential issue that should
-+ * be reported
-+ */
-+ pr_info(
-+ "WARNING: PFE firmware binaries from incompatible version\n");
-+ }
-+}
-+
-+/* PFE elf firmware loader.
-+ * Loads an elf firmware image into a list of PE's (specified using a bitmask)
-+ *
-+ * @param pe_mask Mask of PE id's to load firmware to
-+ * @param fw Pointer to the firmware image
-+ *
-+ * @return 0 on success, a negative value on error
-+ *
-+ */
-+int pfe_load_elf(int pe_mask, const u8 *fw, struct pfe *pfe)
-+{
-+ struct elf32_hdr *elf_hdr = (struct elf32_hdr *)fw;
-+ Elf32_Half sections = be16_to_cpu(elf_hdr->e_shnum);
-+ struct elf32_shdr *shdr = (struct elf32_shdr *)(fw +
-+ be32_to_cpu(elf_hdr->e_shoff));
-+ int id, section;
-+ int rc;
-+
-+ pr_info("%s\n", __func__);
-+
-+ /* Some sanity checks */
-+ if (strncmp(&elf_hdr->e_ident[EI_MAG0], ELFMAG, SELFMAG)) {
-+ pr_err("%s: incorrect elf magic number\n", __func__);
-+ return -EINVAL;
-+ }
-+
-+ if (elf_hdr->e_ident[EI_CLASS] != ELFCLASS32) {
-+ pr_err("%s: incorrect elf class(%x)\n", __func__,
-+ elf_hdr->e_ident[EI_CLASS]);
-+ return -EINVAL;
-+ }
-+
-+ if (elf_hdr->e_ident[EI_DATA] != ELFDATA2MSB) {
-+ pr_err("%s: incorrect elf data(%x)\n", __func__,
-+ elf_hdr->e_ident[EI_DATA]);
-+ return -EINVAL;
-+ }
-+
-+ if (be16_to_cpu(elf_hdr->e_type) != ET_EXEC) {
-+ pr_err("%s: incorrect elf file type(%x)\n", __func__,
-+ be16_to_cpu(elf_hdr->e_type));
-+ return -EINVAL;
-+ }
-+
-+ for (section = 0; section < sections; section++, shdr++) {
-+ if (!(be32_to_cpu(shdr->sh_flags) & (SHF_WRITE | SHF_ALLOC |
-+ SHF_EXECINSTR)))
-+ continue;
-+
-+ for (id = 0; id < MAX_PE; id++)
-+ if (pe_mask & (1 << id)) {
-+ rc = pe_load_elf_section(id, elf_hdr, shdr,
-+ pfe->dev);
-+ if (rc < 0)
-+ goto err;
-+ }
-+ }
-+
-+ pfe_check_version_info(fw);
-+
-+ return 0;
-+
-+err:
-+ return rc;
-+}
-+
-+int get_firmware_in_fdt(const u8 **pe_fw, const char *name)
-+{
-+ struct device_node *np;
-+ const unsigned int *len;
-+ const void *data;
-+
-+ if (!strcmp(name, CLASS_FIRMWARE_FILENAME)) {
-+ /* The firmware should be inside the device tree. */
-+ np = of_find_compatible_node(NULL, NULL,
-+ "fsl,pfe-class-firmware");
-+ if (!np) {
-+ pr_info("Failed to find the node\n");
-+ return -ENOENT;
-+ }
-+
-+ data = of_get_property(np, "fsl,class-firmware", NULL);
-+ if (data) {
-+ len = of_get_property(np, "length", NULL);
-+ pr_info("CLASS fw of length %d bytes loaded from FDT.\n",
-+ be32_to_cpu(*len));
-+ } else {
-+ pr_info("fsl,class-firmware not found!!!!\n");
-+ return -ENOENT;
-+ }
-+ of_node_put(np);
-+ *pe_fw = data;
-+ } else if (!strcmp(name, TMU_FIRMWARE_FILENAME)) {
-+ np = of_find_compatible_node(NULL, NULL,
-+ "fsl,pfe-tmu-firmware");
-+ if (!np) {
-+ pr_info("Failed to find the node\n");
-+ return -ENOENT;
-+ }
-+
-+ data = of_get_property(np, "fsl,tmu-firmware", NULL);
-+ if (data) {
-+ len = of_get_property(np, "length", NULL);
-+ pr_info("TMU fw of length %d bytes loaded from FDT.\n",
-+ be32_to_cpu(*len));
-+ } else {
-+ pr_info("fsl,tmu-firmware not found!!!!\n");
-+ return -ENOENT;
-+ }
-+ of_node_put(np);
-+ *pe_fw = data;
-+ } else if (!strcmp(name, UTIL_FIRMWARE_FILENAME)) {
-+ np = of_find_compatible_node(NULL, NULL,
-+ "fsl,pfe-util-firmware");
-+ if (!np) {
-+ pr_info("Failed to find the node\n");
-+ return -ENOENT;
-+ }
-+
-+ data = of_get_property(np, "fsl,util-firmware", NULL);
-+ if (data) {
-+ len = of_get_property(np, "length", NULL);
-+ pr_info("UTIL fw of length %d bytes loaded from FDT.\n",
-+ be32_to_cpu(*len));
-+ } else {
-+ pr_info("fsl,util-firmware not found!!!!\n");
-+ return -ENOENT;
-+ }
-+ of_node_put(np);
-+ *pe_fw = data;
-+ } else {
-+ pr_err("firmware:%s not known\n", name);
-+ return -EINVAL;
-+ }
-+
-+ return 0;
-+}
-+
-+/* PFE firmware initialization.
-+ * Loads different firmware files from filesystem.
-+ * Initializes PE IMEM/DMEM and UTIL-PE DDR
-+ * Initializes control path symbol addresses (by looking them up in the elf
-+ * firmware files
-+ * Takes PE's out of reset
-+ *
-+ * @return 0 on success, a negative value on error
-+ *
-+ */
-+int pfe_firmware_init(struct pfe *pfe)
-+{
-+ const struct firmware *class_fw, *tmu_fw;
-+ const u8 *class_elf_fw, *tmu_elf_fw;
-+ int rc = 0, fs_load = 0;
-+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
-+ const struct firmware *util_fw;
-+ const u8 *util_elf_fw;
-+
-+#endif
-+
-+ pr_info("%s\n", __func__);
-+
-+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
-+ if (get_firmware_in_fdt(&class_elf_fw, CLASS_FIRMWARE_FILENAME) ||
-+ get_firmware_in_fdt(&tmu_elf_fw, TMU_FIRMWARE_FILENAME) ||
-+ get_firmware_in_fdt(&util_elf_fw, UTIL_FIRMWARE_FILENAME))
-+#else
-+ if (get_firmware_in_fdt(&class_elf_fw, CLASS_FIRMWARE_FILENAME) ||
-+ get_firmware_in_fdt(&tmu_elf_fw, TMU_FIRMWARE_FILENAME))
-+#endif
-+ {
-+ pr_info("%s:PFE firmware not found in FDT.\n", __func__);
-+ pr_info("%s:Trying to load firmware from filesystem...!\n", __func__);
-+
-+ /* look for firmware in filesystem...!*/
-+ fs_load = 1;
-+ if (request_firmware(&class_fw, CLASS_FIRMWARE_FILENAME, pfe->dev)) {
-+ pr_err("%s: request firmware %s failed\n", __func__,
-+ CLASS_FIRMWARE_FILENAME);
-+ rc = -ETIMEDOUT;
-+ goto err0;
-+ }
-+ class_elf_fw = class_fw->data;
-+
-+ if (request_firmware(&tmu_fw, TMU_FIRMWARE_FILENAME, pfe->dev)) {
-+ pr_err("%s: request firmware %s failed\n", __func__,
-+ TMU_FIRMWARE_FILENAME);
-+ rc = -ETIMEDOUT;
-+ goto err1;
-+ }
-+ tmu_elf_fw = tmu_fw->data;
-+
-+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
-+ if (request_firmware(&util_fw, UTIL_FIRMWARE_FILENAME, pfe->dev)) {
-+ pr_err("%s: request firmware %s failed\n", __func__,
-+ UTIL_FIRMWARE_FILENAME);
-+ rc = -ETIMEDOUT;
-+ goto err2;
-+ }
-+ util_elf_fw = util_fw->data;
-+#endif
-+ }
-+
-+ rc = pfe_load_elf(CLASS_MASK, class_elf_fw, pfe);
-+ if (rc < 0) {
-+ pr_err("%s: class firmware load failed\n", __func__);
-+ goto err3;
-+ }
-+
-+#if defined(CFG_DIAGS)
-+ rc = pfe_get_diags_info(class_elf_fw, &pfe->diags.class_diags_info);
-+ if (rc < 0) {
-+ pr_warn(
-+ "PFE diags won't be available for class PEs\n");
-+ rc = 0;
-+ }
-+#endif
-+
-+ rc = pfe_load_elf(TMU_MASK, tmu_elf_fw, pfe);
-+ if (rc < 0) {
-+ pr_err("%s: tmu firmware load failed\n", __func__);
-+ goto err3;
-+ }
-+
-+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
-+ rc = pfe_load_elf(UTIL_MASK, util_elf_fw, pfe);
-+ if (rc < 0) {
-+ pr_err("%s: util firmware load failed\n", __func__);
-+ goto err3;
-+ }
-+
-+#if defined(CFG_DIAGS)
-+ rc = pfe_get_diags_info(util_elf_fw, &pfe->diags.util_diags_info);
-+ if (rc < 0) {
-+ pr_warn(
-+ "PFE diags won't be available for util PE\n");
-+ rc = 0;
-+ }
-+#endif
-+
-+ util_enable();
-+#endif
-+
-+ tmu_enable(0xf);
-+ class_enable();
-+
-+err3:
-+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
-+ if (fs_load)
-+ release_firmware(util_fw);
-+err2:
-+#endif
-+ if (fs_load)
-+ release_firmware(tmu_fw);
-+
-+err1:
-+ if (fs_load)
-+ release_firmware(class_fw);
-+
-+err0:
-+ return rc;
-+}
-+
-+/* PFE firmware cleanup
-+ * Puts PE's in reset
-+ *
-+ *
-+ */
-+void pfe_firmware_exit(struct pfe *pfe)
-+{
-+ pr_info("%s\n", __func__);
-+
-+ if (pe_reset_all(&pfe->ctrl) != 0)
-+ pr_err("Error: Failed to stop PEs, PFE reload may not work correctly\n");
-+
-+ class_disable();
-+ tmu_disable(0xf);
-+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
-+ util_disable();
-+#endif
-+}
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/pfe_firmware.h
-@@ -0,0 +1,21 @@
-+/* SPDX-License-Identifier: GPL-2.0+ */
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ */
-+
-+#ifndef _PFE_FIRMWARE_H_
-+#define _PFE_FIRMWARE_H_
-+
-+#define CLASS_FIRMWARE_FILENAME "ppfe_class_ls1012a.elf"
-+#define TMU_FIRMWARE_FILENAME "ppfe_tmu_ls1012a.elf"
-+#define UTIL_FIRMWARE_FILENAME "ppfe_util_ls1012a.elf"
-+
-+#define PFE_FW_CHECK_PASS 0
-+#define PFE_FW_CHECK_FAIL 1
-+#define NUM_PFE_FW 3
-+
-+int pfe_firmware_init(struct pfe *pfe);
-+void pfe_firmware_exit(struct pfe *pfe);
-+
-+#endif /* _PFE_FIRMWARE_H_ */
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/pfe_hal.c
-@@ -0,0 +1,1517 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ */
-+
-+#include "pfe_mod.h"
-+#include "pfe/pfe.h"
-+
-+/* A-010897: Jumbo frame is not supported */
-+extern bool pfe_errata_a010897;
-+
-+#define PFE_RCR_MAX_FL_MASK 0xC000FFFF
-+
-+void *cbus_base_addr;
-+void *ddr_base_addr;
-+unsigned long ddr_phys_base_addr;
-+unsigned int ddr_size;
-+
-+static struct pe_info pe[MAX_PE];
-+
-+/* Initializes the PFE library.
-+ * Must be called before using any of the library functions.
-+ *
-+ * @param[in] cbus_base CBUS virtual base address (as mapped in
-+ * the host CPU address space)
-+ * @param[in] ddr_base PFE DDR range virtual base address (as
-+ * mapped in the host CPU address space)
-+ * @param[in] ddr_phys_base PFE DDR range physical base address (as
-+ * mapped in platform)
-+ * @param[in] size PFE DDR range size (as defined by the host
-+ * software)
-+ */
-+void pfe_lib_init(void *cbus_base, void *ddr_base, unsigned long ddr_phys_base,
-+ unsigned int size)
-+{
-+ cbus_base_addr = cbus_base;
-+ ddr_base_addr = ddr_base;
-+ ddr_phys_base_addr = ddr_phys_base;
-+ ddr_size = size;
-+
-+ pe[CLASS0_ID].dmem_base_addr = CLASS_DMEM_BASE_ADDR(0);
-+ pe[CLASS0_ID].pmem_base_addr = CLASS_IMEM_BASE_ADDR(0);
-+ pe[CLASS0_ID].pmem_size = CLASS_IMEM_SIZE;
-+ pe[CLASS0_ID].mem_access_wdata = CLASS_MEM_ACCESS_WDATA;
-+ pe[CLASS0_ID].mem_access_addr = CLASS_MEM_ACCESS_ADDR;
-+ pe[CLASS0_ID].mem_access_rdata = CLASS_MEM_ACCESS_RDATA;
-+
-+ pe[CLASS1_ID].dmem_base_addr = CLASS_DMEM_BASE_ADDR(1);
-+ pe[CLASS1_ID].pmem_base_addr = CLASS_IMEM_BASE_ADDR(1);
-+ pe[CLASS1_ID].pmem_size = CLASS_IMEM_SIZE;
-+ pe[CLASS1_ID].mem_access_wdata = CLASS_MEM_ACCESS_WDATA;
-+ pe[CLASS1_ID].mem_access_addr = CLASS_MEM_ACCESS_ADDR;
-+ pe[CLASS1_ID].mem_access_rdata = CLASS_MEM_ACCESS_RDATA;
-+
-+ pe[CLASS2_ID].dmem_base_addr = CLASS_DMEM_BASE_ADDR(2);
-+ pe[CLASS2_ID].pmem_base_addr = CLASS_IMEM_BASE_ADDR(2);
-+ pe[CLASS2_ID].pmem_size = CLASS_IMEM_SIZE;
-+ pe[CLASS2_ID].mem_access_wdata = CLASS_MEM_ACCESS_WDATA;
-+ pe[CLASS2_ID].mem_access_addr = CLASS_MEM_ACCESS_ADDR;
-+ pe[CLASS2_ID].mem_access_rdata = CLASS_MEM_ACCESS_RDATA;
-+
-+ pe[CLASS3_ID].dmem_base_addr = CLASS_DMEM_BASE_ADDR(3);
-+ pe[CLASS3_ID].pmem_base_addr = CLASS_IMEM_BASE_ADDR(3);
-+ pe[CLASS3_ID].pmem_size = CLASS_IMEM_SIZE;
-+ pe[CLASS3_ID].mem_access_wdata = CLASS_MEM_ACCESS_WDATA;
-+ pe[CLASS3_ID].mem_access_addr = CLASS_MEM_ACCESS_ADDR;
-+ pe[CLASS3_ID].mem_access_rdata = CLASS_MEM_ACCESS_RDATA;
-+
-+ pe[CLASS4_ID].dmem_base_addr = CLASS_DMEM_BASE_ADDR(4);
-+ pe[CLASS4_ID].pmem_base_addr = CLASS_IMEM_BASE_ADDR(4);
-+ pe[CLASS4_ID].pmem_size = CLASS_IMEM_SIZE;
-+ pe[CLASS4_ID].mem_access_wdata = CLASS_MEM_ACCESS_WDATA;
-+ pe[CLASS4_ID].mem_access_addr = CLASS_MEM_ACCESS_ADDR;
-+ pe[CLASS4_ID].mem_access_rdata = CLASS_MEM_ACCESS_RDATA;
-+
-+ pe[CLASS5_ID].dmem_base_addr = CLASS_DMEM_BASE_ADDR(5);
-+ pe[CLASS5_ID].pmem_base_addr = CLASS_IMEM_BASE_ADDR(5);
-+ pe[CLASS5_ID].pmem_size = CLASS_IMEM_SIZE;
-+ pe[CLASS5_ID].mem_access_wdata = CLASS_MEM_ACCESS_WDATA;
-+ pe[CLASS5_ID].mem_access_addr = CLASS_MEM_ACCESS_ADDR;
-+ pe[CLASS5_ID].mem_access_rdata = CLASS_MEM_ACCESS_RDATA;
-+
-+ pe[TMU0_ID].dmem_base_addr = TMU_DMEM_BASE_ADDR(0);
-+ pe[TMU0_ID].pmem_base_addr = TMU_IMEM_BASE_ADDR(0);
-+ pe[TMU0_ID].pmem_size = TMU_IMEM_SIZE;
-+ pe[TMU0_ID].mem_access_wdata = TMU_MEM_ACCESS_WDATA;
-+ pe[TMU0_ID].mem_access_addr = TMU_MEM_ACCESS_ADDR;
-+ pe[TMU0_ID].mem_access_rdata = TMU_MEM_ACCESS_RDATA;
-+
-+ pe[TMU1_ID].dmem_base_addr = TMU_DMEM_BASE_ADDR(1);
-+ pe[TMU1_ID].pmem_base_addr = TMU_IMEM_BASE_ADDR(1);
-+ pe[TMU1_ID].pmem_size = TMU_IMEM_SIZE;
-+ pe[TMU1_ID].mem_access_wdata = TMU_MEM_ACCESS_WDATA;
-+ pe[TMU1_ID].mem_access_addr = TMU_MEM_ACCESS_ADDR;
-+ pe[TMU1_ID].mem_access_rdata = TMU_MEM_ACCESS_RDATA;
-+
-+ pe[TMU3_ID].dmem_base_addr = TMU_DMEM_BASE_ADDR(3);
-+ pe[TMU3_ID].pmem_base_addr = TMU_IMEM_BASE_ADDR(3);
-+ pe[TMU3_ID].pmem_size = TMU_IMEM_SIZE;
-+ pe[TMU3_ID].mem_access_wdata = TMU_MEM_ACCESS_WDATA;
-+ pe[TMU3_ID].mem_access_addr = TMU_MEM_ACCESS_ADDR;
-+ pe[TMU3_ID].mem_access_rdata = TMU_MEM_ACCESS_RDATA;
-+
-+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
-+ pe[UTIL_ID].dmem_base_addr = UTIL_DMEM_BASE_ADDR;
-+ pe[UTIL_ID].mem_access_wdata = UTIL_MEM_ACCESS_WDATA;
-+ pe[UTIL_ID].mem_access_addr = UTIL_MEM_ACCESS_ADDR;
-+ pe[UTIL_ID].mem_access_rdata = UTIL_MEM_ACCESS_RDATA;
-+#endif
-+}
-+
-+/* Writes a buffer to PE internal memory from the host
-+ * through indirect access registers.
-+ *
-+ * @param[in] id PE identification (CLASS0_ID, ..., TMU0_ID,
-+ * ..., UTIL_ID)
-+ * @param[in] src Buffer source address
-+ * @param[in] mem_access_addr DMEM destination address (must be 32bit
-+ * aligned)
-+ * @param[in] len Number of bytes to copy
-+ */
-+void pe_mem_memcpy_to32(int id, u32 mem_access_addr, const void *src, unsigned
-+int len)
-+{
-+ u32 offset = 0, val, addr;
-+ unsigned int len32 = len >> 2;
-+ int i;
-+
-+ addr = mem_access_addr | PE_MEM_ACCESS_WRITE |
-+ PE_MEM_ACCESS_BYTE_ENABLE(0, 4);
-+
-+ for (i = 0; i < len32; i++, offset += 4, src += 4) {
-+ val = *(u32 *)src;
-+ writel(cpu_to_be32(val), pe[id].mem_access_wdata);
-+ writel(addr + offset, pe[id].mem_access_addr);
-+ }
-+
-+ len = (len & 0x3);
-+ if (len) {
-+ val = 0;
-+
-+ addr = (mem_access_addr | PE_MEM_ACCESS_WRITE |
-+ PE_MEM_ACCESS_BYTE_ENABLE(0, len)) + offset;
-+
-+ for (i = 0; i < len; i++, src++)
-+ val |= (*(u8 *)src) << (8 * i);
-+
-+ writel(cpu_to_be32(val), pe[id].mem_access_wdata);
-+ writel(addr, pe[id].mem_access_addr);
-+ }
-+}
-+
-+/* Writes a buffer to PE internal data memory (DMEM) from the host
-+ * through indirect access registers.
-+ * @param[in] id PE identification (CLASS0_ID, ..., TMU0_ID,
-+ * ..., UTIL_ID)
-+ * @param[in] src Buffer source address
-+ * @param[in] dst DMEM destination address (must be 32bit
-+ * aligned)
-+ * @param[in] len Number of bytes to copy
-+ */
-+void pe_dmem_memcpy_to32(int id, u32 dst, const void *src, unsigned int len)
-+{
-+ pe_mem_memcpy_to32(id, pe[id].dmem_base_addr | dst |
-+ PE_MEM_ACCESS_DMEM, src, len);
-+}
-+
-+/* Writes a buffer to PE internal program memory (PMEM) from the host
-+ * through indirect access registers.
-+ * @param[in] id PE identification (CLASS0_ID, ..., TMU0_ID,
-+ * ..., TMU3_ID)
-+ * @param[in] src Buffer source address
-+ * @param[in] dst PMEM destination address (must be 32bit
-+ * aligned)
-+ * @param[in] len Number of bytes to copy
-+ */
-+void pe_pmem_memcpy_to32(int id, u32 dst, const void *src, unsigned int len)
-+{
-+ pe_mem_memcpy_to32(id, pe[id].pmem_base_addr | (dst & (pe[id].pmem_size
-+ - 1)) | PE_MEM_ACCESS_IMEM, src, len);
-+}
-+
-+/* Reads PE internal program memory (IMEM) from the host
-+ * through indirect access registers.
-+ * @param[in] id PE identification (CLASS0_ID, ..., TMU0_ID,
-+ * ..., TMU3_ID)
-+ * @param[in] addr PMEM read address (must be aligned on size)
-+ * @param[in] size Number of bytes to read (maximum 4, must not
-+ * cross 32bit boundaries)
-+ * @return the data read (in PE endianness, i.e BE).
-+ */
-+u32 pe_pmem_read(int id, u32 addr, u8 size)
-+{
-+ u32 offset = addr & 0x3;
-+ u32 mask = 0xffffffff >> ((4 - size) << 3);
-+ u32 val;
-+
-+ addr = pe[id].pmem_base_addr | ((addr & ~0x3) & (pe[id].pmem_size - 1))
-+ | PE_MEM_ACCESS_IMEM | PE_MEM_ACCESS_BYTE_ENABLE(offset, size);
-+
-+ writel(addr, pe[id].mem_access_addr);
-+ val = be32_to_cpu(readl(pe[id].mem_access_rdata));
-+
-+ return (val >> (offset << 3)) & mask;
-+}
-+
-+/* Writes PE internal data memory (DMEM) from the host
-+ * through indirect access registers.
-+ * @param[in] id PE identification (CLASS0_ID, ..., TMU0_ID,
-+ * ..., UTIL_ID)
-+ * @param[in] addr DMEM write address (must be aligned on size)
-+ * @param[in] val Value to write (in PE endianness, i.e BE)
-+ * @param[in] size Number of bytes to write (maximum 4, must not
-+ * cross 32bit boundaries)
-+ */
-+void pe_dmem_write(int id, u32 val, u32 addr, u8 size)
-+{
-+ u32 offset = addr & 0x3;
-+
-+ addr = pe[id].dmem_base_addr | (addr & ~0x3) | PE_MEM_ACCESS_WRITE |
-+ PE_MEM_ACCESS_DMEM | PE_MEM_ACCESS_BYTE_ENABLE(offset, size);
-+
-+ /* Indirect access interface is byte swapping data being written */
-+ writel(cpu_to_be32(val << (offset << 3)), pe[id].mem_access_wdata);
-+ writel(addr, pe[id].mem_access_addr);
-+}
-+
-+/* Reads PE internal data memory (DMEM) from the host
-+ * through indirect access registers.
-+ * @param[in] id PE identification (CLASS0_ID, ..., TMU0_ID,
-+ * ..., UTIL_ID)
-+ * @param[in] addr DMEM read address (must be aligned on size)
-+ * @param[in] size Number of bytes to read (maximum 4, must not
-+ * cross 32bit boundaries)
-+ * @return the data read (in PE endianness, i.e BE).
-+ */
-+u32 pe_dmem_read(int id, u32 addr, u8 size)
-+{
-+ u32 offset = addr & 0x3;
-+ u32 mask = 0xffffffff >> ((4 - size) << 3);
-+ u32 val;
-+
-+ addr = pe[id].dmem_base_addr | (addr & ~0x3) | PE_MEM_ACCESS_DMEM |
-+ PE_MEM_ACCESS_BYTE_ENABLE(offset, size);
-+
-+ writel(addr, pe[id].mem_access_addr);
-+
-+ /* Indirect access interface is byte swapping data being read */
-+ val = be32_to_cpu(readl(pe[id].mem_access_rdata));
-+
-+ return (val >> (offset << 3)) & mask;
-+}
-+
-+/* This function is used to write to CLASS internal bus peripherals (ccu,
-+ * pe-lem) from the host
-+ * through indirect access registers.
-+ * @param[in] val value to write
-+ * @param[in] addr Address to write to (must be aligned on size)
-+ * @param[in] size Number of bytes to write (1, 2 or 4)
-+ *
-+ */
-+void class_bus_write(u32 val, u32 addr, u8 size)
-+{
-+ u32 offset = addr & 0x3;
-+
-+ writel((addr & CLASS_BUS_ACCESS_BASE_MASK), CLASS_BUS_ACCESS_BASE);
-+
-+ addr = (addr & ~CLASS_BUS_ACCESS_BASE_MASK) | PE_MEM_ACCESS_WRITE |
-+ (size << 24);
-+
-+ writel(cpu_to_be32(val << (offset << 3)), CLASS_BUS_ACCESS_WDATA);
-+ writel(addr, CLASS_BUS_ACCESS_ADDR);
-+}
-+
-+/* Reads from CLASS internal bus peripherals (ccu, pe-lem) from the host
-+ * through indirect access registers.
-+ * @param[in] addr Address to read from (must be aligned on size)
-+ * @param[in] size Number of bytes to read (1, 2 or 4)
-+ * @return the read data
-+ *
-+ */
-+u32 class_bus_read(u32 addr, u8 size)
-+{
-+ u32 offset = addr & 0x3;
-+ u32 mask = 0xffffffff >> ((4 - size) << 3);
-+ u32 val;
-+
-+ writel((addr & CLASS_BUS_ACCESS_BASE_MASK), CLASS_BUS_ACCESS_BASE);
-+
-+ addr = (addr & ~CLASS_BUS_ACCESS_BASE_MASK) | (size << 24);
-+
-+ writel(addr, CLASS_BUS_ACCESS_ADDR);
-+ val = be32_to_cpu(readl(CLASS_BUS_ACCESS_RDATA));
-+
-+ return (val >> (offset << 3)) & mask;
-+}
-+
-+/* Writes data to the cluster memory (PE_LMEM)
-+ * @param[in] dst PE LMEM destination address (must be 32bit aligned)
-+ * @param[in] src Buffer source address
-+ * @param[in] len Number of bytes to copy
-+ */
-+void class_pe_lmem_memcpy_to32(u32 dst, const void *src, unsigned int len)
-+{
-+ u32 len32 = len >> 2;
-+ int i;
-+
-+ for (i = 0; i < len32; i++, src += 4, dst += 4)
-+ class_bus_write(*(u32 *)src, dst, 4);
-+
-+ if (len & 0x2) {
-+ class_bus_write(*(u16 *)src, dst, 2);
-+ src += 2;
-+ dst += 2;
-+ }
-+
-+ if (len & 0x1) {
-+ class_bus_write(*(u8 *)src, dst, 1);
-+ src++;
-+ dst++;
-+ }
-+}
-+
-+/* Writes value to the cluster memory (PE_LMEM)
-+ * @param[in] dst PE LMEM destination address (must be 32bit aligned)
-+ * @param[in] val Value to write
-+ * @param[in] len Number of bytes to write
-+ */
-+void class_pe_lmem_memset(u32 dst, int val, unsigned int len)
-+{
-+ u32 len32 = len >> 2;
-+ int i;
-+
-+ val = val | (val << 8) | (val << 16) | (val << 24);
-+
-+ for (i = 0; i < len32; i++, dst += 4)
-+ class_bus_write(val, dst, 4);
-+
-+ if (len & 0x2) {
-+ class_bus_write(val, dst, 2);
-+ dst += 2;
-+ }
-+
-+ if (len & 0x1) {
-+ class_bus_write(val, dst, 1);
-+ dst++;
-+ }
-+}
-+
-+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
-+
-+/* Writes UTIL program memory (DDR) from the host.
-+ *
-+ * @param[in] addr Address to write (virtual, must be aligned on size)
-+ * @param[in] val Value to write (in PE endianness, i.e BE)
-+ * @param[in] size Number of bytes to write (2 or 4)
-+ */
-+static void util_pmem_write(u32 val, void *addr, u8 size)
-+{
-+ void *addr64 = (void *)((unsigned long)addr & ~0x7);
-+ unsigned long off = 8 - ((unsigned long)addr & 0x7) - size;
-+
-+ /*
-+ * IMEM should be loaded as a 64bit swapped value in a 64bit aligned
-+ * location
-+ */
-+ if (size == 4)
-+ writel(be32_to_cpu(val), addr64 + off);
-+ else
-+ writew(be16_to_cpu((u16)val), addr64 + off);
-+}
-+
-+/* Writes a buffer to UTIL program memory (DDR) from the host.
-+ *
-+ * @param[in] dst Address to write (virtual, must be at least 16bit
-+ * aligned)
-+ * @param[in] src Buffer to write (in PE endianness, i.e BE, must have
-+ * same alignment as dst)
-+ * @param[in] len Number of bytes to write (must be at least 16bit
-+ * aligned)
-+ */
-+static void util_pmem_memcpy(void *dst, const void *src, unsigned int len)
-+{
-+ unsigned int len32;
-+ int i;
-+
-+ if ((unsigned long)src & 0x2) {
-+ util_pmem_write(*(u16 *)src, dst, 2);
-+ src += 2;
-+ dst += 2;
-+ len -= 2;
-+ }
-+
-+ len32 = len >> 2;
-+
-+ for (i = 0; i < len32; i++, dst += 4, src += 4)
-+ util_pmem_write(*(u32 *)src, dst, 4);
-+
-+ if (len & 0x2)
-+ util_pmem_write(*(u16 *)src, dst, len & 0x2);
-+}
-+#endif
-+
-+/* Loads an elf section into pmem
-+ * Code needs to be at least 16bit aligned and only PROGBITS sections are
-+ * supported
-+ *
-+ * @param[in] id PE identification (CLASS0_ID, ..., TMU0_ID, ...,
-+ * TMU3_ID)
-+ * @param[in] data pointer to the elf firmware
-+ * @param[in] shdr pointer to the elf section header
-+ *
-+ */
-+static int pe_load_pmem_section(int id, const void *data,
-+ struct elf32_shdr *shdr)
-+{
-+ u32 offset = be32_to_cpu(shdr->sh_offset);
-+ u32 addr = be32_to_cpu(shdr->sh_addr);
-+ u32 size = be32_to_cpu(shdr->sh_size);
-+ u32 type = be32_to_cpu(shdr->sh_type);
-+
-+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
-+ if (id == UTIL_ID) {
-+ pr_err("%s: unsupported pmem section for UTIL\n",
-+ __func__);
-+ return -EINVAL;
-+ }
-+#endif
-+
-+ if (((unsigned long)(data + offset) & 0x3) != (addr & 0x3)) {
-+ pr_err(
-+ "%s: load address(%x) and elf file address(%lx) don't have the same alignment\n"
-+ , __func__, addr, (unsigned long)data + offset);
-+
-+ return -EINVAL;
-+ }
-+
-+ if (addr & 0x1) {
-+ pr_err("%s: load address(%x) is not 16bit aligned\n",
-+ __func__, addr);
-+ return -EINVAL;
-+ }
-+
-+ if (size & 0x1) {
-+ pr_err("%s: load size(%x) is not 16bit aligned\n",
-+ __func__, size);
-+ return -EINVAL;
-+ }
-+
-+ switch (type) {
-+ case SHT_PROGBITS:
-+ pe_pmem_memcpy_to32(id, addr, data + offset, size);
-+
-+ break;
-+
-+ default:
-+ pr_err("%s: unsupported section type(%x)\n", __func__,
-+ type);
-+ return -EINVAL;
-+ }
-+
-+ return 0;
-+}
-+
-+/* Loads an elf section into dmem
-+ * Data needs to be at least 32bit aligned, NOBITS sections are correctly
-+ * initialized to 0
-+ *
-+ * @param[in] id PE identification (CLASS0_ID, ..., TMU0_ID,
-+ * ..., UTIL_ID)
-+ * @param[in] data pointer to the elf firmware
-+ * @param[in] shdr pointer to the elf section header
-+ *
-+ */
-+static int pe_load_dmem_section(int id, const void *data,
-+ struct elf32_shdr *shdr)
-+{
-+ u32 offset = be32_to_cpu(shdr->sh_offset);
-+ u32 addr = be32_to_cpu(shdr->sh_addr);
-+ u32 size = be32_to_cpu(shdr->sh_size);
-+ u32 type = be32_to_cpu(shdr->sh_type);
-+ u32 size32 = size >> 2;
-+ int i;
-+
-+ if (((unsigned long)(data + offset) & 0x3) != (addr & 0x3)) {
-+ pr_err(
-+ "%s: load address(%x) and elf file address(%lx) don't have the same alignment\n",
-+ __func__, addr, (unsigned long)data + offset);
-+
-+ return -EINVAL;
-+ }
-+
-+ if (addr & 0x3) {
-+ pr_err("%s: load address(%x) is not 32bit aligned\n",
-+ __func__, addr);
-+ return -EINVAL;
-+ }
-+
-+ switch (type) {
-+ case SHT_PROGBITS:
-+ pe_dmem_memcpy_to32(id, addr, data + offset, size);
-+ break;
-+
-+ case SHT_NOBITS:
-+ for (i = 0; i < size32; i++, addr += 4)
-+ pe_dmem_write(id, 0, addr, 4);
-+
-+ if (size & 0x3)
-+ pe_dmem_write(id, 0, addr, size & 0x3);
-+
-+ break;
-+
-+ default:
-+ pr_err("%s: unsupported section type(%x)\n", __func__,
-+ type);
-+ return -EINVAL;
-+ }
-+
-+ return 0;
-+}
-+
-+/* Loads an elf section into DDR
-+ * Data needs to be at least 32bit aligned, NOBITS sections are correctly
-+ * initialized to 0
-+ *
-+ * @param[in] id PE identification (CLASS0_ID, ..., TMU0_ID,
-+ * ..., UTIL_ID)
-+ * @param[in] data pointer to the elf firmware
-+ * @param[in] shdr pointer to the elf section header
-+ *
-+ */
-+static int pe_load_ddr_section(int id, const void *data,
-+ struct elf32_shdr *shdr,
-+ struct device *dev) {
-+ u32 offset = be32_to_cpu(shdr->sh_offset);
-+ u32 addr = be32_to_cpu(shdr->sh_addr);
-+ u32 size = be32_to_cpu(shdr->sh_size);
-+ u32 type = be32_to_cpu(shdr->sh_type);
-+ u32 flags = be32_to_cpu(shdr->sh_flags);
-+
-+ switch (type) {
-+ case SHT_PROGBITS:
-+ if (flags & SHF_EXECINSTR) {
-+ if (id <= CLASS_MAX_ID) {
-+ /* DO the loading only once in DDR */
-+ if (id == CLASS0_ID) {
-+ pr_err(
-+ "%s: load address(%x) and elf file address(%lx) rcvd\n",
-+ __func__, addr,
-+ (unsigned long)data + offset);
-+ if (((unsigned long)(data + offset)
-+ & 0x3) != (addr & 0x3)) {
-+ pr_err(
-+ "%s: load address(%x) and elf file address(%lx) don't have the same alignment\n"
-+ , __func__, addr,
-+ (unsigned long)data + offset);
-+
-+ return -EINVAL;
-+ }
-+
-+ if (addr & 0x1) {
-+ pr_err(
-+ "%s: load address(%x) is not 16bit aligned\n"
-+ , __func__, addr);
-+ return -EINVAL;
-+ }
-+
-+ if (size & 0x1) {
-+ pr_err(
-+ "%s: load length(%x) is not 16bit aligned\n"
-+ , __func__, size);
-+ return -EINVAL;
-+ }
-+ memcpy(DDR_PHYS_TO_VIRT(
-+ DDR_PFE_TO_PHYS(addr)),
-+ data + offset, size);
-+ }
-+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
-+ } else if (id == UTIL_ID) {
-+ if (((unsigned long)(data + offset) & 0x3)
-+ != (addr & 0x3)) {
-+ pr_err(
-+ "%s: load address(%x) and elf file address(%lx) don't have the same alignment\n"
-+ , __func__, addr,
-+ (unsigned long)data + offset);
-+
-+ return -EINVAL;
-+ }
-+
-+ if (addr & 0x1) {
-+ pr_err(
-+ "%s: load address(%x) is not 16bit aligned\n"
-+ , __func__, addr);
-+ return -EINVAL;
-+ }
-+
-+ if (size & 0x1) {
-+ pr_err(
-+ "%s: load length(%x) is not 16bit aligned\n"
-+ , __func__, size);
-+ return -EINVAL;
-+ }
-+
-+ util_pmem_memcpy(DDR_PHYS_TO_VIRT(
-+ DDR_PFE_TO_PHYS(addr)),
-+ data + offset, size);
-+ }
-+#endif
-+ } else {
-+ pr_err(
-+ "%s: unsupported ddr section type(%x) for PE(%d)\n"
-+ , __func__, type, id);
-+ return -EINVAL;
-+ }
-+
-+ } else {
-+ memcpy(DDR_PHYS_TO_VIRT(DDR_PFE_TO_PHYS(addr)), data
-+ + offset, size);
-+ }
-+
-+ break;
-+
-+ case SHT_NOBITS:
-+ memset(DDR_PHYS_TO_VIRT(DDR_PFE_TO_PHYS(addr)), 0, size);
-+
-+ break;
-+
-+ default:
-+ pr_err("%s: unsupported section type(%x)\n", __func__,
-+ type);
-+ return -EINVAL;
-+ }
-+
-+ return 0;
-+}
-+
-+/* Loads an elf section into pe lmem
-+ * Data needs to be at least 32bit aligned, NOBITS sections are correctly
-+ * initialized to 0
-+ *
-+ * @param[in] id PE identification (CLASS0_ID,..., CLASS5_ID)
-+ * @param[in] data pointer to the elf firmware
-+ * @param[in] shdr pointer to the elf section header
-+ *
-+ */
-+static int pe_load_pe_lmem_section(int id, const void *data,
-+ struct elf32_shdr *shdr)
-+{
-+ u32 offset = be32_to_cpu(shdr->sh_offset);
-+ u32 addr = be32_to_cpu(shdr->sh_addr);
-+ u32 size = be32_to_cpu(shdr->sh_size);
-+ u32 type = be32_to_cpu(shdr->sh_type);
-+
-+ if (id > CLASS_MAX_ID) {
-+ pr_err(
-+ "%s: unsupported pe-lmem section type(%x) for PE(%d)\n",
-+ __func__, type, id);
-+ return -EINVAL;
-+ }
-+
-+ if (((unsigned long)(data + offset) & 0x3) != (addr & 0x3)) {
-+ pr_err(
-+ "%s: load address(%x) and elf file address(%lx) don't have the same alignment\n",
-+ __func__, addr, (unsigned long)data + offset);
-+
-+ return -EINVAL;
-+ }
-+
-+ if (addr & 0x3) {
-+ pr_err("%s: load address(%x) is not 32bit aligned\n",
-+ __func__, addr);
-+ return -EINVAL;
-+ }
-+
-+ switch (type) {
-+ case SHT_PROGBITS:
-+ class_pe_lmem_memcpy_to32(addr, data + offset, size);
-+ break;
-+
-+ case SHT_NOBITS:
-+ class_pe_lmem_memset(addr, 0, size);
-+ break;
-+
-+ default:
-+ pr_err("%s: unsupported section type(%x)\n", __func__,
-+ type);
-+ return -EINVAL;
-+ }
-+
-+ return 0;
-+}
-+
-+/* Loads an elf section into a PE
-+ * For now only supports loading a section to dmem (all PE's), pmem (class and
-+ * tmu PE's),
-+ * DDDR (util PE code)
-+ *
-+ * @param[in] id PE identification (CLASS0_ID, ..., TMU0_ID,
-+ * ..., UTIL_ID)
-+ * @param[in] data pointer to the elf firmware
-+ * @param[in] shdr pointer to the elf section header
-+ *
-+ */
-+int pe_load_elf_section(int id, const void *data, struct elf32_shdr *shdr,
-+ struct device *dev) {
-+ u32 addr = be32_to_cpu(shdr->sh_addr);
-+ u32 size = be32_to_cpu(shdr->sh_size);
-+
-+ if (IS_DMEM(addr, size))
-+ return pe_load_dmem_section(id, data, shdr);
-+ else if (IS_PMEM(addr, size))
-+ return pe_load_pmem_section(id, data, shdr);
-+ else if (IS_PFE_LMEM(addr, size))
-+ return 0;
-+ else if (IS_PHYS_DDR(addr, size))
-+ return pe_load_ddr_section(id, data, shdr, dev);
-+ else if (IS_PE_LMEM(addr, size))
-+ return pe_load_pe_lmem_section(id, data, shdr);
-+
-+ pr_err("%s: unsupported memory range(%x)\n", __func__,
-+ addr);
-+ return 0;
-+}
-+
-+/**************************** BMU ***************************/
-+
-+/* Initializes a BMU block.
-+ * @param[in] base BMU block base address
-+ * @param[in] cfg BMU configuration
-+ */
-+void bmu_init(void *base, struct BMU_CFG *cfg)
-+{
-+ bmu_disable(base);
-+
-+ bmu_set_config(base, cfg);
-+
-+ bmu_reset(base);
-+}
-+
-+/* Resets a BMU block.
-+ * @param[in] base BMU block base address
-+ */
-+void bmu_reset(void *base)
-+{
-+ writel(CORE_SW_RESET, base + BMU_CTRL);
-+
-+ /* Wait for self clear */
-+ while (readl(base + BMU_CTRL) & CORE_SW_RESET)
-+ ;
-+}
-+
-+/* Enabled a BMU block.
-+ * @param[in] base BMU block base address
-+ */
-+void bmu_enable(void *base)
-+{
-+ writel(CORE_ENABLE, base + BMU_CTRL);
-+}
-+
-+/* Disables a BMU block.
-+ * @param[in] base BMU block base address
-+ */
-+void bmu_disable(void *base)
-+{
-+ writel(CORE_DISABLE, base + BMU_CTRL);
-+}
-+
-+/* Sets the configuration of a BMU block.
-+ * @param[in] base BMU block base address
-+ * @param[in] cfg BMU configuration
-+ */
-+void bmu_set_config(void *base, struct BMU_CFG *cfg)
-+{
-+ writel(cfg->baseaddr, base + BMU_UCAST_BASE_ADDR);
-+ writel(cfg->count & 0xffff, base + BMU_UCAST_CONFIG);
-+ writel(cfg->size & 0xffff, base + BMU_BUF_SIZE);
-+
-+ /* Interrupts are never used */
-+ writel(cfg->low_watermark, base + BMU_LOW_WATERMARK);
-+ writel(cfg->high_watermark, base + BMU_HIGH_WATERMARK);
-+ writel(0x0, base + BMU_INT_ENABLE);
-+}
-+
-+/**************************** MTIP GEMAC ***************************/
-+
-+/* Enable Rx Checksum Engine. With this enabled, Frame with bad IP,
-+ * TCP or UDP checksums are discarded
-+ *
-+ * @param[in] base GEMAC base address.
-+ */
-+void gemac_enable_rx_checksum_offload(void *base)
-+{
-+ /*Do not find configuration to do this */
-+}
-+
-+/* Disable Rx Checksum Engine.
-+ *
-+ * @param[in] base GEMAC base address.
-+ */
-+void gemac_disable_rx_checksum_offload(void *base)
-+{
-+ /*Do not find configuration to do this */
-+}
-+
-+/* GEMAC set speed.
-+ * @param[in] base GEMAC base address
-+ * @param[in] speed GEMAC speed (10, 100 or 1000 Mbps)
-+ */
-+void gemac_set_speed(void *base, enum mac_speed gem_speed)
-+{
-+ u32 ecr = readl(base + EMAC_ECNTRL_REG) & ~EMAC_ECNTRL_SPEED;
-+ u32 rcr = readl(base + EMAC_RCNTRL_REG) & ~EMAC_RCNTRL_RMII_10T;
-+
-+ switch (gem_speed) {
-+ case SPEED_10M:
-+ rcr |= EMAC_RCNTRL_RMII_10T;
-+ break;
-+
-+ case SPEED_1000M:
-+ ecr |= EMAC_ECNTRL_SPEED;
-+ break;
-+
-+ case SPEED_100M:
-+ default:
-+ /*It is in 100M mode */
-+ break;
-+ }
-+ writel(ecr, (base + EMAC_ECNTRL_REG));
-+ writel(rcr, (base + EMAC_RCNTRL_REG));
-+}
-+
-+/* GEMAC set duplex.
-+ * @param[in] base GEMAC base address
-+ * @param[in] duplex GEMAC duplex mode (Full, Half)
-+ */
-+void gemac_set_duplex(void *base, int duplex)
-+{
-+ if (duplex == DUPLEX_HALF) {
-+ writel(readl(base + EMAC_TCNTRL_REG) & ~EMAC_TCNTRL_FDEN, base
-+ + EMAC_TCNTRL_REG);
-+ writel(readl(base + EMAC_RCNTRL_REG) | EMAC_RCNTRL_DRT, (base
-+ + EMAC_RCNTRL_REG));
-+ } else{
-+ writel(readl(base + EMAC_TCNTRL_REG) | EMAC_TCNTRL_FDEN, base
-+ + EMAC_TCNTRL_REG);
-+ writel(readl(base + EMAC_RCNTRL_REG) & ~EMAC_RCNTRL_DRT, (base
-+ + EMAC_RCNTRL_REG));
-+ }
-+}
-+
-+/* GEMAC set mode.
-+ * @param[in] base GEMAC base address
-+ * @param[in] mode GEMAC operation mode (MII, RMII, RGMII, SGMII)
-+ */
-+void gemac_set_mode(void *base, int mode)
-+{
-+ u32 val = readl(base + EMAC_RCNTRL_REG);
-+
-+ /*Remove loopbank*/
-+ val &= ~EMAC_RCNTRL_LOOP;
-+
-+ /* Enable flow control and MII mode.PFE firmware always expects
-+ CRC should be forwarded by MAC to validate CRC in software.*/
-+ val |= (EMAC_RCNTRL_FCE | EMAC_RCNTRL_MII_MODE);
-+
-+ writel(val, base + EMAC_RCNTRL_REG);
-+}
-+
-+/* GEMAC enable function.
-+ * @param[in] base GEMAC base address
-+ */
-+void gemac_enable(void *base)
-+{
-+ writel(readl(base + EMAC_ECNTRL_REG) | EMAC_ECNTRL_ETHER_EN, base +
-+ EMAC_ECNTRL_REG);
-+}
-+
-+/* GEMAC disable function.
-+ * @param[in] base GEMAC base address
-+ */
-+void gemac_disable(void *base)
-+{
-+ writel(readl(base + EMAC_ECNTRL_REG) & ~EMAC_ECNTRL_ETHER_EN, base +
-+ EMAC_ECNTRL_REG);
-+}
-+
-+/* GEMAC TX disable function.
-+ * @param[in] base GEMAC base address
-+ */
-+void gemac_tx_disable(void *base)
-+{
-+ writel(readl(base + EMAC_TCNTRL_REG) | EMAC_TCNTRL_GTS, base +
-+ EMAC_TCNTRL_REG);
-+}
-+
-+void gemac_tx_enable(void *base)
-+{
-+ writel(readl(base + EMAC_TCNTRL_REG) & ~EMAC_TCNTRL_GTS, base +
-+ EMAC_TCNTRL_REG);
-+}
-+
-+/* Sets the hash register of the MAC.
-+ * This register is used for matching unicast and multicast frames.
-+ *
-+ * @param[in] base GEMAC base address.
-+ * @param[in] hash 64-bit hash to be configured.
-+ */
-+void gemac_set_hash(void *base, struct pfe_mac_addr *hash)
-+{
-+ writel(hash->bottom, base + EMAC_GALR);
-+ writel(hash->top, base + EMAC_GAUR);
-+}
-+
-+void gemac_set_laddrN(void *base, struct pfe_mac_addr *address,
-+ unsigned int entry_index)
-+{
-+ if ((entry_index < 1) || (entry_index > EMAC_SPEC_ADDR_MAX))
-+ return;
-+
-+ entry_index = entry_index - 1;
-+ if (entry_index < 1) {
-+ writel(htonl(address->bottom), base + EMAC_PHY_ADDR_LOW);
-+ writel((htonl(address->top) | 0x8808), base +
-+ EMAC_PHY_ADDR_HIGH);
-+ } else {
-+ writel(htonl(address->bottom), base + ((entry_index - 1) * 8)
-+ + EMAC_SMAC_0_0);
-+ writel((htonl(address->top) | 0x8808), base + ((entry_index -
-+ 1) * 8) + EMAC_SMAC_0_1);
-+ }
-+}
-+
-+void gemac_clear_laddrN(void *base, unsigned int entry_index)
-+{
-+ if ((entry_index < 1) || (entry_index > EMAC_SPEC_ADDR_MAX))
-+ return;
-+
-+ entry_index = entry_index - 1;
-+ if (entry_index < 1) {
-+ writel(0, base + EMAC_PHY_ADDR_LOW);
-+ writel(0, base + EMAC_PHY_ADDR_HIGH);
-+ } else {
-+ writel(0, base + ((entry_index - 1) * 8) + EMAC_SMAC_0_0);
-+ writel(0, base + ((entry_index - 1) * 8) + EMAC_SMAC_0_1);
-+ }
-+}
-+
-+/* Set the loopback mode of the MAC. This can be either no loopback for
-+ * normal operation, local loopback through MAC internal loopback module or PHY
-+ * loopback for external loopback through a PHY. This asserts the external
-+ * loop pin.
-+ *
-+ * @param[in] base GEMAC base address.
-+ * @param[in] gem_loop Loopback mode to be enabled. LB_LOCAL - MAC
-+ * Loopback,
-+ * LB_EXT - PHY Loopback.
-+ */
-+void gemac_set_loop(void *base, enum mac_loop gem_loop)
-+{
-+ pr_info("%s()\n", __func__);
-+ writel(readl(base + EMAC_RCNTRL_REG) | EMAC_RCNTRL_LOOP, (base +
-+ EMAC_RCNTRL_REG));
-+}
-+
-+/* GEMAC allow frames
-+ * @param[in] base GEMAC base address
-+ */
-+void gemac_enable_copy_all(void *base)
-+{
-+ writel(readl(base + EMAC_RCNTRL_REG) | EMAC_RCNTRL_PROM, (base +
-+ EMAC_RCNTRL_REG));
-+}
-+
-+/* GEMAC do not allow frames
-+ * @param[in] base GEMAC base address
-+ */
-+void gemac_disable_copy_all(void *base)
-+{
-+ writel(readl(base + EMAC_RCNTRL_REG) & ~EMAC_RCNTRL_PROM, (base +
-+ EMAC_RCNTRL_REG));
-+}
-+
-+/* GEMAC allow broadcast function.
-+ * @param[in] base GEMAC base address
-+ */
-+void gemac_allow_broadcast(void *base)
-+{
-+ writel(readl(base + EMAC_RCNTRL_REG) & ~EMAC_RCNTRL_BC_REJ, base +
-+ EMAC_RCNTRL_REG);
-+}
-+
-+/* GEMAC no broadcast function.
-+ * @param[in] base GEMAC base address
-+ */
-+void gemac_no_broadcast(void *base)
-+{
-+ writel(readl(base + EMAC_RCNTRL_REG) | EMAC_RCNTRL_BC_REJ, base +
-+ EMAC_RCNTRL_REG);
-+}
-+
-+/* GEMAC enable 1536 rx function.
-+ * @param[in] base GEMAC base address
-+ */
-+void gemac_enable_1536_rx(void *base)
-+{
-+ /* Set 1536 as Maximum frame length */
-+ writel((readl(base + EMAC_RCNTRL_REG) & PFE_RCR_MAX_FL_MASK)
-+ | (1536 << 16), base + EMAC_RCNTRL_REG);
-+}
-+
-+/* GEMAC set rx Max frame length.
-+ * @param[in] base GEMAC base address
-+ * @param[in] mtu new mtu
-+ */
-+void gemac_set_rx_max_fl(void *base, int mtu)
-+{
-+ /* Set mtu as Maximum frame length */
-+ writel((readl(base + EMAC_RCNTRL_REG) & PFE_RCR_MAX_FL_MASK)
-+ | (mtu << 16), base + EMAC_RCNTRL_REG);
-+}
-+
-+/* GEMAC enable stacked vlan function.
-+ * @param[in] base GEMAC base address
-+ */
-+void gemac_enable_stacked_vlan(void *base)
-+{
-+ /* MTIP doesn't support stacked vlan */
-+}
-+
-+/* GEMAC enable pause rx function.
-+ * @param[in] base GEMAC base address
-+ */
-+void gemac_enable_pause_rx(void *base)
-+{
-+ writel(readl(base + EMAC_RCNTRL_REG) | EMAC_RCNTRL_FCE,
-+ base + EMAC_RCNTRL_REG);
-+}
-+
-+/* GEMAC disable pause rx function.
-+ * @param[in] base GEMAC base address
-+ */
-+void gemac_disable_pause_rx(void *base)
-+{
-+ writel(readl(base + EMAC_RCNTRL_REG) & ~EMAC_RCNTRL_FCE,
-+ base + EMAC_RCNTRL_REG);
-+}
-+
-+/* GEMAC enable pause tx function.
-+ * @param[in] base GEMAC base address
-+ */
-+void gemac_enable_pause_tx(void *base)
-+{
-+ writel(EMAC_RX_SECTION_EMPTY_V, base + EMAC_RX_SECTION_EMPTY);
-+}
-+
-+/* GEMAC disable pause tx function.
-+ * @param[in] base GEMAC base address
-+ */
-+void gemac_disable_pause_tx(void *base)
-+{
-+ writel(0x0, base + EMAC_RX_SECTION_EMPTY);
-+}
-+
-+/* GEMAC wol configuration
-+ * @param[in] base GEMAC base address
-+ * @param[in] wol_conf WoL register configuration
-+ */
-+void gemac_set_wol(void *base, u32 wol_conf)
-+{
-+ u32 val = readl(base + EMAC_ECNTRL_REG);
-+
-+ if (wol_conf)
-+ val |= (EMAC_ECNTRL_MAGIC_ENA | EMAC_ECNTRL_SLEEP);
-+ else
-+ val &= ~(EMAC_ECNTRL_MAGIC_ENA | EMAC_ECNTRL_SLEEP);
-+ writel(val, base + EMAC_ECNTRL_REG);
-+}
-+
-+/* Sets Gemac bus width to 64bit
-+ * @param[in] base GEMAC base address
-+ * @param[in] width gemac bus width to be set possible values are 32/64/128
-+ */
-+void gemac_set_bus_width(void *base, int width)
-+{
-+}
-+
-+/* Sets Gemac configuration.
-+ * @param[in] base GEMAC base address
-+ * @param[in] cfg GEMAC configuration
-+ */
-+void gemac_set_config(void *base, struct gemac_cfg *cfg)
-+{
-+ /*GEMAC config taken from VLSI */
-+ writel(0x00000004, base + EMAC_TFWR_STR_FWD);
-+ writel(0x00000005, base + EMAC_RX_SECTION_FULL);
-+
-+ if (pfe_errata_a010897)
-+ writel(0x0000076c, base + EMAC_TRUNC_FL);
-+ else
-+ writel(0x00003fff, base + EMAC_TRUNC_FL);
-+
-+ writel(0x00000030, base + EMAC_TX_SECTION_EMPTY);
-+ writel(0x00000000, base + EMAC_MIB_CTRL_STS_REG);
-+
-+ gemac_set_mode(base, cfg->mode);
-+
-+ gemac_set_speed(base, cfg->speed);
-+
-+ gemac_set_duplex(base, cfg->duplex);
-+}
-+
-+/**************************** GPI ***************************/
-+
-+/* Initializes a GPI block.
-+ * @param[in] base GPI base address
-+ * @param[in] cfg GPI configuration
-+ */
-+void gpi_init(void *base, struct gpi_cfg *cfg)
-+{
-+ gpi_reset(base);
-+
-+ gpi_disable(base);
-+
-+ gpi_set_config(base, cfg);
-+}
-+
-+/* Resets a GPI block.
-+ * @param[in] base GPI base address
-+ */
-+void gpi_reset(void *base)
-+{
-+ writel(CORE_SW_RESET, base + GPI_CTRL);
-+}
-+
-+/* Enables a GPI block.
-+ * @param[in] base GPI base address
-+ */
-+void gpi_enable(void *base)
-+{
-+ writel(CORE_ENABLE, base + GPI_CTRL);
-+}
-+
-+/* Disables a GPI block.
-+ * @param[in] base GPI base address
-+ */
-+void gpi_disable(void *base)
-+{
-+ writel(CORE_DISABLE, base + GPI_CTRL);
-+}
-+
-+/* Sets the configuration of a GPI block.
-+ * @param[in] base GPI base address
-+ * @param[in] cfg GPI configuration
-+ */
-+void gpi_set_config(void *base, struct gpi_cfg *cfg)
-+{
-+ writel(CBUS_VIRT_TO_PFE(BMU1_BASE_ADDR + BMU_ALLOC_CTRL), base
-+ + GPI_LMEM_ALLOC_ADDR);
-+ writel(CBUS_VIRT_TO_PFE(BMU1_BASE_ADDR + BMU_FREE_CTRL), base
-+ + GPI_LMEM_FREE_ADDR);
-+ writel(CBUS_VIRT_TO_PFE(BMU2_BASE_ADDR + BMU_ALLOC_CTRL), base
-+ + GPI_DDR_ALLOC_ADDR);
-+ writel(CBUS_VIRT_TO_PFE(BMU2_BASE_ADDR + BMU_FREE_CTRL), base
-+ + GPI_DDR_FREE_ADDR);
-+ writel(CBUS_VIRT_TO_PFE(CLASS_INQ_PKTPTR), base + GPI_CLASS_ADDR);
-+ writel(DDR_HDR_SIZE, base + GPI_DDR_DATA_OFFSET);
-+ writel(LMEM_HDR_SIZE, base + GPI_LMEM_DATA_OFFSET);
-+ writel(0, base + GPI_LMEM_SEC_BUF_DATA_OFFSET);
-+ writel(0, base + GPI_DDR_SEC_BUF_DATA_OFFSET);
-+ writel((DDR_HDR_SIZE << 16) | LMEM_HDR_SIZE, base + GPI_HDR_SIZE);
-+ writel((DDR_BUF_SIZE << 16) | LMEM_BUF_SIZE, base + GPI_BUF_SIZE);
-+
-+ writel(((cfg->lmem_rtry_cnt << 16) | (GPI_DDR_BUF_EN << 1) |
-+ GPI_LMEM_BUF_EN), base + GPI_RX_CONFIG);
-+ writel(cfg->tmlf_txthres, base + GPI_TMLF_TX);
-+ writel(cfg->aseq_len, base + GPI_DTX_ASEQ);
-+ writel(1, base + GPI_TOE_CHKSUM_EN);
-+
-+ if (cfg->mtip_pause_reg) {
-+ writel(cfg->mtip_pause_reg, base + GPI_CSR_MTIP_PAUSE_REG);
-+ writel(EGPI_PAUSE_TIME, base + GPI_TX_PAUSE_TIME);
-+ }
-+}
-+
-+/**************************** CLASSIFIER ***************************/
-+
-+/* Initializes CLASSIFIER block.
-+ * @param[in] cfg CLASSIFIER configuration
-+ */
-+void class_init(struct class_cfg *cfg)
-+{
-+ class_reset();
-+
-+ class_disable();
-+
-+ class_set_config(cfg);
-+}
-+
-+/* Resets CLASSIFIER block.
-+ *
-+ */
-+void class_reset(void)
-+{
-+ writel(CORE_SW_RESET, CLASS_TX_CTRL);
-+}
-+
-+/* Enables all CLASS-PE's cores.
-+ *
-+ */
-+void class_enable(void)
-+{
-+ writel(CORE_ENABLE, CLASS_TX_CTRL);
-+}
-+
-+/* Disables all CLASS-PE's cores.
-+ *
-+ */
-+void class_disable(void)
-+{
-+ writel(CORE_DISABLE, CLASS_TX_CTRL);
-+}
-+
-+/*
-+ * Sets the configuration of the CLASSIFIER block.
-+ * @param[in] cfg CLASSIFIER configuration
-+ */
-+void class_set_config(struct class_cfg *cfg)
-+{
-+ u32 val;
-+
-+ /* Initialize route table */
-+ if (!cfg->resume)
-+ memset(DDR_PHYS_TO_VIRT(cfg->route_table_baseaddr), 0, (1 <<
-+ cfg->route_table_hash_bits) * CLASS_ROUTE_SIZE);
-+
-+#if !defined(LS1012A_PFE_RESET_WA)
-+ writel(cfg->pe_sys_clk_ratio, CLASS_PE_SYS_CLK_RATIO);
-+#endif
-+
-+ writel((DDR_HDR_SIZE << 16) | LMEM_HDR_SIZE, CLASS_HDR_SIZE);
-+ writel(LMEM_BUF_SIZE, CLASS_LMEM_BUF_SIZE);
-+ writel(CLASS_ROUTE_ENTRY_SIZE(CLASS_ROUTE_SIZE) |
-+ CLASS_ROUTE_HASH_SIZE(cfg->route_table_hash_bits),
-+ CLASS_ROUTE_HASH_ENTRY_SIZE);
-+ writel(HIF_PKT_CLASS_EN | HIF_PKT_OFFSET(sizeof(struct hif_hdr)),
-+ CLASS_HIF_PARSE);
-+
-+ val = HASH_CRC_PORT_IP | QB2BUS_LE;
-+
-+#if defined(CONFIG_IP_ALIGNED)
-+ val |= IP_ALIGNED;
-+#endif
-+
-+ /*
-+ * Class PE packet steering will only work if TOE mode, bridge fetch or
-+ * route fetch are enabled (see class/qb_fet.v). Route fetch would
-+ * trigger additional memory copies (likely from DDR because of hash
-+ * table size, which cannot be reduced because PE software still
-+ * relies on hash value computed in HW), so when not in TOE mode we
-+ * simply enable HW bridge fetch even though we don't use it.
-+ */
-+ if (cfg->toe_mode)
-+ val |= CLASS_TOE;
-+ else
-+ val |= HW_BRIDGE_FETCH;
-+
-+ writel(val, CLASS_ROUTE_MULTI);
-+
-+ writel(DDR_PHYS_TO_PFE(cfg->route_table_baseaddr),
-+ CLASS_ROUTE_TABLE_BASE);
-+ writel(CLASS_PE0_RO_DM_ADDR0_VAL, CLASS_PE0_RO_DM_ADDR0);
-+ writel(CLASS_PE0_RO_DM_ADDR1_VAL, CLASS_PE0_RO_DM_ADDR1);
-+ writel(CLASS_PE0_QB_DM_ADDR0_VAL, CLASS_PE0_QB_DM_ADDR0);
-+ writel(CLASS_PE0_QB_DM_ADDR1_VAL, CLASS_PE0_QB_DM_ADDR1);
-+ writel(CBUS_VIRT_TO_PFE(TMU_PHY_INQ_PKTPTR), CLASS_TM_INQ_ADDR);
-+
-+ writel(23, CLASS_AFULL_THRES);
-+ writel(23, CLASS_TSQ_FIFO_THRES);
-+
-+ writel(24, CLASS_MAX_BUF_CNT);
-+ writel(24, CLASS_TSQ_MAX_CNT);
-+}
-+
-+/**************************** TMU ***************************/
-+
-+void tmu_reset(void)
-+{
-+ writel(SW_RESET, TMU_CTRL);
-+}
-+
-+/* Initializes TMU block.
-+ * @param[in] cfg TMU configuration
-+ */
-+void tmu_init(struct tmu_cfg *cfg)
-+{
-+ int q, phyno;
-+
-+ tmu_disable(0xF);
-+ mdelay(10);
-+
-+#if !defined(LS1012A_PFE_RESET_WA)
-+ /* keep in soft reset */
-+ writel(SW_RESET, TMU_CTRL);
-+#endif
-+ writel(0x3, TMU_SYS_GENERIC_CONTROL);
-+ writel(750, TMU_INQ_WATERMARK);
-+ writel(CBUS_VIRT_TO_PFE(EGPI1_BASE_ADDR +
-+ GPI_INQ_PKTPTR), TMU_PHY0_INQ_ADDR);
-+ writel(CBUS_VIRT_TO_PFE(EGPI2_BASE_ADDR +
-+ GPI_INQ_PKTPTR), TMU_PHY1_INQ_ADDR);
-+ writel(CBUS_VIRT_TO_PFE(HGPI_BASE_ADDR +
-+ GPI_INQ_PKTPTR), TMU_PHY3_INQ_ADDR);
-+ writel(CBUS_VIRT_TO_PFE(HIF_NOCPY_RX_INQ0_PKTPTR), TMU_PHY4_INQ_ADDR);
-+ writel(CBUS_VIRT_TO_PFE(UTIL_INQ_PKTPTR), TMU_PHY5_INQ_ADDR);
-+ writel(CBUS_VIRT_TO_PFE(BMU2_BASE_ADDR + BMU_FREE_CTRL),
-+ TMU_BMU_INQ_ADDR);
-+
-+ writel(0x3FF, TMU_TDQ0_SCH_CTRL); /*
-+ * enabling all 10
-+ * schedulers [9:0] of each TDQ
-+ */
-+ writel(0x3FF, TMU_TDQ1_SCH_CTRL);
-+ writel(0x3FF, TMU_TDQ3_SCH_CTRL);
-+
-+#if !defined(LS1012A_PFE_RESET_WA)
-+ writel(cfg->pe_sys_clk_ratio, TMU_PE_SYS_CLK_RATIO);
-+#endif
-+
-+#if !defined(LS1012A_PFE_RESET_WA)
-+ writel(DDR_PHYS_TO_PFE(cfg->llm_base_addr), TMU_LLM_BASE_ADDR);
-+ /* Extra packet pointers will be stored from this address onwards */
-+
-+ writel(cfg->llm_queue_len, TMU_LLM_QUE_LEN);
-+ writel(5, TMU_TDQ_IIFG_CFG);
-+ writel(DDR_BUF_SIZE, TMU_BMU_BUF_SIZE);
-+
-+ writel(0x0, TMU_CTRL);
-+
-+ /* MEM init */
-+ pr_info("%s: mem init\n", __func__);
-+ writel(MEM_INIT, TMU_CTRL);
-+
-+ while (!(readl(TMU_CTRL) & MEM_INIT_DONE))
-+ ;
-+
-+ /* LLM init */
-+ pr_info("%s: lmem init\n", __func__);
-+ writel(LLM_INIT, TMU_CTRL);
-+
-+ while (!(readl(TMU_CTRL) & LLM_INIT_DONE))
-+ ;
-+#endif
-+ /* set up each queue for tail drop */
-+ for (phyno = 0; phyno < 4; phyno++) {
-+ if (phyno == 2)
-+ continue;
-+ for (q = 0; q < 16; q++) {
-+ u32 qdepth;
-+
-+ writel((phyno << 8) | q, TMU_TEQ_CTRL);
-+ writel(1 << 22, TMU_TEQ_QCFG); /*Enable tail drop */
-+
-+ if (phyno == 3)
-+ qdepth = DEFAULT_TMU3_QDEPTH;
-+ else
-+ qdepth = (q == 0) ? DEFAULT_Q0_QDEPTH :
-+ DEFAULT_MAX_QDEPTH;
-+
-+ /* LOG: 68855 */
-+ /*
-+ * The following is a workaround for the reordered
-+ * packet and BMU2 buffer leakage issue.
-+ */
-+ if (CHIP_REVISION() == 0)
-+ qdepth = 31;
-+
-+ writel(qdepth << 18, TMU_TEQ_HW_PROB_CFG2);
-+ writel(qdepth >> 14, TMU_TEQ_HW_PROB_CFG3);
-+ }
-+ }
-+
-+#ifdef CFG_LRO
-+ /* Set TMU-3 queue 5 (LRO) in no-drop mode */
-+ writel((3 << 8) | TMU_QUEUE_LRO, TMU_TEQ_CTRL);
-+ writel(0, TMU_TEQ_QCFG);
-+#endif
-+
-+ writel(0x05, TMU_TEQ_DISABLE_DROPCHK);
-+
-+ writel(0x0, TMU_CTRL);
-+}
-+
-+/* Enables TMU-PE cores.
-+ * @param[in] pe_mask TMU PE mask
-+ */
-+void tmu_enable(u32 pe_mask)
-+{
-+ writel(readl(TMU_TX_CTRL) | (pe_mask & 0xF), TMU_TX_CTRL);
-+}
-+
-+/* Disables TMU cores.
-+ * @param[in] pe_mask TMU PE mask
-+ */
-+void tmu_disable(u32 pe_mask)
-+{
-+ writel(readl(TMU_TX_CTRL) & ~(pe_mask & 0xF), TMU_TX_CTRL);
-+}
-+
-+/* This will return the tmu queue status
-+ * @param[in] if_id gem interface id or TMU index
-+ * @return returns the bit mask of busy queues, zero means all
-+ * queues are empty
-+ */
-+u32 tmu_qstatus(u32 if_id)
-+{
-+ return cpu_to_be32(pe_dmem_read(TMU0_ID + if_id, TMU_DM_PESTATUS +
-+ offsetof(struct pe_status, tmu_qstatus), 4));
-+}
-+
-+u32 tmu_pkts_processed(u32 if_id)
-+{
-+ return cpu_to_be32(pe_dmem_read(TMU0_ID + if_id, TMU_DM_PESTATUS +
-+ offsetof(struct pe_status, rx), 4));
-+}
-+
-+/**************************** UTIL ***************************/
-+
-+/* Resets UTIL block.
-+ */
-+void util_reset(void)
-+{
-+ writel(CORE_SW_RESET, UTIL_TX_CTRL);
-+}
-+
-+/* Initializes UTIL block.
-+ * @param[in] cfg UTIL configuration
-+ */
-+void util_init(struct util_cfg *cfg)
-+{
-+ writel(cfg->pe_sys_clk_ratio, UTIL_PE_SYS_CLK_RATIO);
-+}
-+
-+/* Enables UTIL-PE core.
-+ *
-+ */
-+void util_enable(void)
-+{
-+ writel(CORE_ENABLE, UTIL_TX_CTRL);
-+}
-+
-+/* Disables UTIL-PE core.
-+ *
-+ */
-+void util_disable(void)
-+{
-+ writel(CORE_DISABLE, UTIL_TX_CTRL);
-+}
-+
-+/**************************** HIF ***************************/
-+/* Initializes HIF copy block.
-+ *
-+ */
-+void hif_init(void)
-+{
-+ /*Initialize HIF registers*/
-+ writel((HIF_RX_POLL_CTRL_CYCLE << 16) | HIF_TX_POLL_CTRL_CYCLE,
-+ HIF_POLL_CTRL);
-+}
-+
-+/* Enable hif tx DMA and interrupt
-+ *
-+ */
-+void hif_tx_enable(void)
-+{
-+ writel(HIF_CTRL_DMA_EN, HIF_TX_CTRL);
-+ writel((readl(HIF_INT_ENABLE) | HIF_INT_EN | HIF_TXPKT_INT_EN),
-+ HIF_INT_ENABLE);
-+}
-+
-+/* Disable hif tx DMA and interrupt
-+ *
-+ */
-+void hif_tx_disable(void)
-+{
-+ u32 hif_int;
-+
-+ writel(0, HIF_TX_CTRL);
-+
-+ hif_int = readl(HIF_INT_ENABLE);
-+ hif_int &= HIF_TXPKT_INT_EN;
-+ writel(hif_int, HIF_INT_ENABLE);
-+}
-+
-+/* Enable hif rx DMA and interrupt
-+ *
-+ */
-+void hif_rx_enable(void)
-+{
-+ hif_rx_dma_start();
-+ writel((readl(HIF_INT_ENABLE) | HIF_INT_EN | HIF_RXPKT_INT_EN),
-+ HIF_INT_ENABLE);
-+}
-+
-+/* Disable hif rx DMA and interrupt
-+ *
-+ */
-+void hif_rx_disable(void)
-+{
-+ u32 hif_int;
-+
-+ writel(0, HIF_RX_CTRL);
-+
-+ hif_int = readl(HIF_INT_ENABLE);
-+ hif_int &= HIF_RXPKT_INT_EN;
-+ writel(hif_int, HIF_INT_ENABLE);
-+}
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/pfe_hif.c
-@@ -0,0 +1,1063 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/interrupt.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/dmapool.h>
-+#include <linux/sched.h>
-+#include <linux/module.h>
-+#include <linux/list.h>
-+#include <linux/kthread.h>
-+#include <linux/slab.h>
-+
-+#include <linux/io.h>
-+#include <asm/irq.h>
-+
-+#include "pfe_mod.h"
-+
-+#define HIF_INT_MASK (HIF_INT | HIF_RXPKT_INT | HIF_TXPKT_INT)
-+
-+unsigned char napi_first_batch;
-+
-+static void pfe_tx_do_cleanup(unsigned long data);
-+
-+static int pfe_hif_alloc_descr(struct pfe_hif *hif)
-+{
-+ void *addr;
-+ dma_addr_t dma_addr;
-+ int err = 0;
-+
-+ pr_info("%s\n", __func__);
-+ addr = dma_alloc_coherent(pfe->dev,
-+ HIF_RX_DESC_NT * sizeof(struct hif_desc) +
-+ HIF_TX_DESC_NT * sizeof(struct hif_desc),
-+ &dma_addr, GFP_KERNEL);
-+
-+ if (!addr) {
-+ pr_err("%s: Could not allocate buffer descriptors!\n"
-+ , __func__);
-+ err = -ENOMEM;
-+ goto err0;
-+ }
-+
-+ hif->descr_baseaddr_p = dma_addr;
-+ hif->descr_baseaddr_v = addr;
-+ hif->rx_ring_size = HIF_RX_DESC_NT;
-+ hif->tx_ring_size = HIF_TX_DESC_NT;
-+
-+ return 0;
-+
-+err0:
-+ return err;
-+}
-+
-+#if defined(LS1012A_PFE_RESET_WA)
-+static void pfe_hif_disable_rx_desc(struct pfe_hif *hif)
-+{
-+ int ii;
-+ struct hif_desc *desc = hif->rx_base;
-+
-+ /*Mark all descriptors as LAST_BD */
-+ for (ii = 0; ii < hif->rx_ring_size; ii++) {
-+ desc->ctrl |= BD_CTRL_LAST_BD;
-+ desc++;
-+ }
-+}
-+
-+struct class_rx_hdr_t {
-+ u32 next_ptr; /* ptr to the start of the first DDR buffer */
-+ u16 length; /* total packet length */
-+ u16 phyno; /* input physical port number */
-+ u32 status; /* gemac status bits */
-+ u32 status2; /* reserved for software usage */
-+};
-+
-+/* STATUS_BAD_FRAME_ERR is set for all errors (including checksums if enabled)
-+ * except overflow
-+ */
-+#define STATUS_BAD_FRAME_ERR BIT(16)
-+#define STATUS_LENGTH_ERR BIT(17)
-+#define STATUS_CRC_ERR BIT(18)
-+#define STATUS_TOO_SHORT_ERR BIT(19)
-+#define STATUS_TOO_LONG_ERR BIT(20)
-+#define STATUS_CODE_ERR BIT(21)
-+#define STATUS_MC_HASH_MATCH BIT(22)
-+#define STATUS_CUMULATIVE_ARC_HIT BIT(23)
-+#define STATUS_UNICAST_HASH_MATCH BIT(24)
-+#define STATUS_IP_CHECKSUM_CORRECT BIT(25)
-+#define STATUS_TCP_CHECKSUM_CORRECT BIT(26)
-+#define STATUS_UDP_CHECKSUM_CORRECT BIT(27)
-+#define STATUS_OVERFLOW_ERR BIT(28) /* GPI error */
-+#define MIN_PKT_SIZE 64
-+
-+static inline void copy_to_lmem(u32 *dst, u32 *src, int len)
-+{
-+ int i;
-+
-+ for (i = 0; i < len; i += sizeof(u32)) {
-+ *dst = htonl(*src);
-+ dst++; src++;
-+ }
-+}
-+
-+static void send_dummy_pkt_to_hif(void)
-+{
-+ void *lmem_ptr, *ddr_ptr, *lmem_virt_addr;
-+ u32 physaddr;
-+ struct class_rx_hdr_t local_hdr;
-+ static u32 dummy_pkt[] = {
-+ 0x33221100, 0x2b785544, 0xd73093cb, 0x01000608,
-+ 0x04060008, 0x2b780200, 0xd73093cb, 0x0a01a8c0,
-+ 0x33221100, 0xa8c05544, 0x00000301, 0x00000000,
-+ 0x00000000, 0x00000000, 0x00000000, 0xbe86c51f };
-+
-+ ddr_ptr = (void *)((u64)readl(BMU2_BASE_ADDR + BMU_ALLOC_CTRL));
-+ if (!ddr_ptr)
-+ return;
-+
-+ lmem_ptr = (void *)((u64)readl(BMU1_BASE_ADDR + BMU_ALLOC_CTRL));
-+ if (!lmem_ptr)
-+ return;
-+
-+ pr_info("Sending a dummy pkt to HIF %p %p\n", ddr_ptr, lmem_ptr);
-+ physaddr = (u32)DDR_VIRT_TO_PFE(ddr_ptr);
-+
-+ lmem_virt_addr = (void *)CBUS_PFE_TO_VIRT((unsigned long int)lmem_ptr);
-+
-+ local_hdr.phyno = htons(0); /* RX_PHY_0 */
-+ local_hdr.length = htons(MIN_PKT_SIZE);
-+
-+ local_hdr.next_ptr = htonl((u32)physaddr);
-+ /*Mark checksum is correct */
-+ local_hdr.status = htonl((STATUS_IP_CHECKSUM_CORRECT |
-+ STATUS_UDP_CHECKSUM_CORRECT |
-+ STATUS_TCP_CHECKSUM_CORRECT |
-+ STATUS_UNICAST_HASH_MATCH |
-+ STATUS_CUMULATIVE_ARC_HIT));
-+ local_hdr.status2 = 0;
-+
-+ copy_to_lmem((u32 *)lmem_virt_addr, (u32 *)&local_hdr,
-+ sizeof(local_hdr));
-+
-+ copy_to_lmem((u32 *)(lmem_virt_addr + LMEM_HDR_SIZE), (u32 *)dummy_pkt,
-+ 0x40);
-+
-+ writel((unsigned long int)lmem_ptr, CLASS_INQ_PKTPTR);
-+}
-+
-+void pfe_hif_rx_idle(struct pfe_hif *hif)
-+{
-+ int hif_stop_loop = 10;
-+ u32 rx_status;
-+
-+ pfe_hif_disable_rx_desc(hif);
-+ pr_info("Bringing hif to idle state...");
-+ writel(0, HIF_INT_ENABLE);
-+ /*If HIF Rx BDP is busy send a dummy packet */
-+ do {
-+ rx_status = readl(HIF_RX_STATUS);
-+ if (rx_status & BDP_CSR_RX_DMA_ACTV)
-+ send_dummy_pkt_to_hif();
-+
-+ usleep_range(100, 150);
-+ } while (--hif_stop_loop);
-+
-+ if (readl(HIF_RX_STATUS) & BDP_CSR_RX_DMA_ACTV)
-+ pr_info("Failed\n");
-+ else
-+ pr_info("Done\n");
-+}
-+#endif
-+
-+static void pfe_hif_free_descr(struct pfe_hif *hif)
-+{
-+ pr_info("%s\n", __func__);
-+
-+ dma_free_coherent(pfe->dev,
-+ hif->rx_ring_size * sizeof(struct hif_desc) +
-+ hif->tx_ring_size * sizeof(struct hif_desc),
-+ hif->descr_baseaddr_v, hif->descr_baseaddr_p);
-+}
-+
-+void pfe_hif_desc_dump(struct pfe_hif *hif)
-+{
-+ struct hif_desc *desc;
-+ unsigned long desc_p;
-+ int ii = 0;
-+
-+ pr_info("%s\n", __func__);
-+
-+ desc = hif->rx_base;
-+ desc_p = (u32)((u64)desc - (u64)hif->descr_baseaddr_v +
-+ hif->descr_baseaddr_p);
-+
-+ pr_info("HIF Rx desc base %p physical %x\n", desc, (u32)desc_p);
-+ for (ii = 0; ii < hif->rx_ring_size; ii++) {
-+ pr_info("status: %08x, ctrl: %08x, data: %08x, next: %x\n",
-+ readl(&desc->status), readl(&desc->ctrl),
-+ readl(&desc->data), readl(&desc->next));
-+ desc++;
-+ }
-+
-+ desc = hif->tx_base;
-+ desc_p = ((u64)desc - (u64)hif->descr_baseaddr_v +
-+ hif->descr_baseaddr_p);
-+
-+ pr_info("HIF Tx desc base %p physical %x\n", desc, (u32)desc_p);
-+ for (ii = 0; ii < hif->tx_ring_size; ii++) {
-+ pr_info("status: %08x, ctrl: %08x, data: %08x, next: %x\n",
-+ readl(&desc->status), readl(&desc->ctrl),
-+ readl(&desc->data), readl(&desc->next));
-+ desc++;
-+ }
-+}
-+
-+/* pfe_hif_release_buffers */
-+static void pfe_hif_release_buffers(struct pfe_hif *hif)
-+{
-+ struct hif_desc *desc;
-+ int i = 0;
-+
-+ hif->rx_base = hif->descr_baseaddr_v;
-+
-+ pr_info("%s\n", __func__);
-+
-+ /*Free Rx buffers */
-+ desc = hif->rx_base;
-+ for (i = 0; i < hif->rx_ring_size; i++) {
-+ if (readl(&desc->data)) {
-+ if ((i < hif->shm->rx_buf_pool_cnt) &&
-+ (!hif->shm->rx_buf_pool[i])) {
-+ /*
-+ * dma_unmap_single(hif->dev, desc->data,
-+ * hif->rx_buf_len[i], DMA_FROM_DEVICE);
-+ */
-+ dma_unmap_single(hif->dev,
-+ DDR_PFE_TO_PHYS(
-+ readl(&desc->data)),
-+ hif->rx_buf_len[i],
-+ DMA_FROM_DEVICE);
-+ hif->shm->rx_buf_pool[i] = hif->rx_buf_addr[i];
-+ } else {
-+ pr_err("%s: buffer pool already full\n"
-+ , __func__);
-+ }
-+ }
-+
-+ writel(0, &desc->data);
-+ writel(0, &desc->status);
-+ writel(0, &desc->ctrl);
-+ desc++;
-+ }
-+}
-+
-+/*
-+ * pfe_hif_init_buffers
-+ * This function initializes the HIF Rx/Tx ring descriptors and
-+ * initialize Rx queue with buffers.
-+ */
-+static int pfe_hif_init_buffers(struct pfe_hif *hif)
-+{
-+ struct hif_desc *desc, *first_desc_p;
-+ u32 data;
-+ int i = 0;
-+
-+ pr_info("%s\n", __func__);
-+
-+ /* Check enough Rx buffers available in the shared memory */
-+ if (hif->shm->rx_buf_pool_cnt < hif->rx_ring_size)
-+ return -ENOMEM;
-+
-+ hif->rx_base = hif->descr_baseaddr_v;
-+ memset(hif->rx_base, 0, hif->rx_ring_size * sizeof(struct hif_desc));
-+
-+ /*Initialize Rx descriptors */
-+ desc = hif->rx_base;
-+ first_desc_p = (struct hif_desc *)hif->descr_baseaddr_p;
-+
-+ for (i = 0; i < hif->rx_ring_size; i++) {
-+ /* Initialize Rx buffers from the shared memory */
-+
-+ data = (u32)dma_map_single(hif->dev, hif->shm->rx_buf_pool[i],
-+ pfe_pkt_size, DMA_FROM_DEVICE);
-+ hif->rx_buf_addr[i] = hif->shm->rx_buf_pool[i];
-+ hif->rx_buf_len[i] = pfe_pkt_size;
-+ hif->shm->rx_buf_pool[i] = NULL;
-+
-+ if (likely(dma_mapping_error(hif->dev, data) == 0)) {
-+ writel(DDR_PHYS_TO_PFE(data), &desc->data);
-+ } else {
-+ pr_err("%s : low on mem\n", __func__);
-+
-+ goto err;
-+ }
-+
-+ writel(0, &desc->status);
-+
-+ /*
-+ * Ensure everything else is written to DDR before
-+ * writing bd->ctrl
-+ */
-+ wmb();
-+
-+ writel((BD_CTRL_PKT_INT_EN | BD_CTRL_LIFM
-+ | BD_CTRL_DIR | BD_CTRL_DESC_EN
-+ | BD_BUF_LEN(pfe_pkt_size)), &desc->ctrl);
-+
-+ /* Chain descriptors */
-+ writel((u32)DDR_PHYS_TO_PFE(first_desc_p + i + 1), &desc->next);
-+ desc++;
-+ }
-+
-+ /* Overwrite last descriptor to chain it to first one*/
-+ desc--;
-+ writel((u32)DDR_PHYS_TO_PFE(first_desc_p), &desc->next);
-+
-+ hif->rxtoclean_index = 0;
-+
-+ /*Initialize Rx buffer descriptor ring base address */
-+ writel(DDR_PHYS_TO_PFE(hif->descr_baseaddr_p), HIF_RX_BDP_ADDR);
-+
-+ hif->tx_base = hif->rx_base + hif->rx_ring_size;
-+ first_desc_p = (struct hif_desc *)hif->descr_baseaddr_p +
-+ hif->rx_ring_size;
-+ memset(hif->tx_base, 0, hif->tx_ring_size * sizeof(struct hif_desc));
-+
-+ /*Initialize tx descriptors */
-+ desc = hif->tx_base;
-+
-+ for (i = 0; i < hif->tx_ring_size; i++) {
-+ /* Chain descriptors */
-+ writel((u32)DDR_PHYS_TO_PFE(first_desc_p + i + 1), &desc->next);
-+ writel(0, &desc->ctrl);
-+ desc++;
-+ }
-+
-+ /* Overwrite last descriptor to chain it to first one */
-+ desc--;
-+ writel((u32)DDR_PHYS_TO_PFE(first_desc_p), &desc->next);
-+ hif->txavail = hif->tx_ring_size;
-+ hif->txtosend = 0;
-+ hif->txtoclean = 0;
-+ hif->txtoflush = 0;
-+
-+ /*Initialize Tx buffer descriptor ring base address */
-+ writel((u32)DDR_PHYS_TO_PFE(first_desc_p), HIF_TX_BDP_ADDR);
-+
-+ return 0;
-+
-+err:
-+ pfe_hif_release_buffers(hif);
-+ return -ENOMEM;
-+}
-+
-+/*
-+ * pfe_hif_client_register
-+ *
-+ * This function used to register a client driver with the HIF driver.
-+ *
-+ * Return value:
-+ * 0 - on Successful registration
-+ */
-+static int pfe_hif_client_register(struct pfe_hif *hif, u32 client_id,
-+ struct hif_client_shm *client_shm)
-+{
-+ struct hif_client *client = &hif->client[client_id];
-+ u32 i, cnt;
-+ struct rx_queue_desc *rx_qbase;
-+ struct tx_queue_desc *tx_qbase;
-+ struct hif_rx_queue *rx_queue;
-+ struct hif_tx_queue *tx_queue;
-+ int err = 0;
-+
-+ pr_info("%s\n", __func__);
-+
-+ spin_lock_bh(&hif->tx_lock);
-+
-+ if (test_bit(client_id, &hif->shm->g_client_status[0])) {
-+ pr_err("%s: client %d already registered\n",
-+ __func__, client_id);
-+ err = -1;
-+ goto unlock;
-+ }
-+
-+ memset(client, 0, sizeof(struct hif_client));
-+
-+ /* Initialize client Rx queues baseaddr, size */
-+
-+ cnt = CLIENT_CTRL_RX_Q_CNT(client_shm->ctrl);
-+ /* Check if client is requesting for more queues than supported */
-+ if (cnt > HIF_CLIENT_QUEUES_MAX)
-+ cnt = HIF_CLIENT_QUEUES_MAX;
-+
-+ client->rx_qn = cnt;
-+ rx_qbase = (struct rx_queue_desc *)client_shm->rx_qbase;
-+ for (i = 0; i < cnt; i++) {
-+ rx_queue = &client->rx_q[i];
-+ rx_queue->base = rx_qbase + i * client_shm->rx_qsize;
-+ rx_queue->size = client_shm->rx_qsize;
-+ rx_queue->write_idx = 0;
-+ }
-+
-+ /* Initialize client Tx queues baseaddr, size */
-+ cnt = CLIENT_CTRL_TX_Q_CNT(client_shm->ctrl);
-+
-+ /* Check if client is requesting for more queues than supported */
-+ if (cnt > HIF_CLIENT_QUEUES_MAX)
-+ cnt = HIF_CLIENT_QUEUES_MAX;
-+
-+ client->tx_qn = cnt;
-+ tx_qbase = (struct tx_queue_desc *)client_shm->tx_qbase;
-+ for (i = 0; i < cnt; i++) {
-+ tx_queue = &client->tx_q[i];
-+ tx_queue->base = tx_qbase + i * client_shm->tx_qsize;
-+ tx_queue->size = client_shm->tx_qsize;
-+ tx_queue->ack_idx = 0;
-+ }
-+
-+ set_bit(client_id, &hif->shm->g_client_status[0]);
-+
-+unlock:
-+ spin_unlock_bh(&hif->tx_lock);
-+
-+ return err;
-+}
-+
-+/*
-+ * pfe_hif_client_unregister
-+ *
-+ * This function used to unregister a client from the HIF driver.
-+ *
-+ */
-+static void pfe_hif_client_unregister(struct pfe_hif *hif, u32 client_id)
-+{
-+ pr_info("%s\n", __func__);
-+
-+ /*
-+ * Mark client as no longer available (which prevents further packet
-+ * receive for this client)
-+ */
-+ spin_lock_bh(&hif->tx_lock);
-+
-+ if (!test_bit(client_id, &hif->shm->g_client_status[0])) {
-+ pr_err("%s: client %d not registered\n", __func__,
-+ client_id);
-+
-+ spin_unlock_bh(&hif->tx_lock);
-+ return;
-+ }
-+
-+ clear_bit(client_id, &hif->shm->g_client_status[0]);
-+
-+ spin_unlock_bh(&hif->tx_lock);
-+}
-+
-+/*
-+ * client_put_rxpacket-
-+ * This functions puts the Rx pkt in the given client Rx queue.
-+ * It actually swap the Rx pkt in the client Rx descriptor buffer
-+ * and returns the free buffer from it.
-+ *
-+ * If the function returns NULL means client Rx queue is full and
-+ * packet couldn't send to client queue.
-+ */
-+static void *client_put_rxpacket(struct hif_rx_queue *queue, void *pkt, u32 len,
-+ u32 flags, u32 client_ctrl, u32 *rem_len)
-+{
-+ void *free_pkt = NULL;
-+ struct rx_queue_desc *desc = queue->base + queue->write_idx;
-+
-+ if (readl(&desc->ctrl) & CL_DESC_OWN) {
-+ if (page_mode) {
-+ int rem_page_size = PAGE_SIZE -
-+ PRESENT_OFST_IN_PAGE(pkt);
-+ int cur_pkt_size = ROUND_MIN_RX_SIZE(len +
-+ pfe_pkt_headroom);
-+ *rem_len = (rem_page_size - cur_pkt_size);
-+ if (*rem_len) {
-+ free_pkt = pkt + cur_pkt_size;
-+ get_page(virt_to_page(free_pkt));
-+ } else {
-+ free_pkt = (void
-+ *)__get_free_page(GFP_ATOMIC | GFP_DMA_PFE);
-+ *rem_len = pfe_pkt_size;
-+ }
-+ } else {
-+ free_pkt = kmalloc(PFE_BUF_SIZE, GFP_ATOMIC |
-+ GFP_DMA_PFE);
-+ *rem_len = PFE_BUF_SIZE - pfe_pkt_headroom;
-+ }
-+
-+ if (free_pkt) {
-+ desc->data = pkt;
-+ desc->client_ctrl = client_ctrl;
-+ /*
-+ * Ensure everything else is written to DDR before
-+ * writing bd->ctrl
-+ */
-+ smp_wmb();
-+ writel(CL_DESC_BUF_LEN(len) | flags, &desc->ctrl);
-+ queue->write_idx = (queue->write_idx + 1)
-+ & (queue->size - 1);
-+
-+ free_pkt += pfe_pkt_headroom;
-+ }
-+ }
-+
-+ return free_pkt;
-+}
-+
-+/*
-+ * pfe_hif_rx_process-
-+ * This function does pfe hif rx queue processing.
-+ * Dequeue packet from Rx queue and send it to corresponding client queue
-+ */
-+static int pfe_hif_rx_process(struct pfe_hif *hif, int budget)
-+{
-+ struct hif_desc *desc;
-+ struct hif_hdr *pkt_hdr;
-+ struct __hif_hdr hif_hdr;
-+ void *free_buf;
-+ int rtc, len, rx_processed = 0;
-+ struct __hif_desc local_desc;
-+ int flags;
-+ unsigned int desc_p;
-+ unsigned int buf_size = 0;
-+
-+ spin_lock_bh(&hif->lock);
-+
-+ rtc = hif->rxtoclean_index;
-+
-+ while (rx_processed < budget) {
-+ desc = hif->rx_base + rtc;
-+
-+ __memcpy12(&local_desc, desc);
-+
-+ /* ACK pending Rx interrupt */
-+ if (local_desc.ctrl & BD_CTRL_DESC_EN) {
-+ writel(HIF_INT | HIF_RXPKT_INT, HIF_INT_SRC);
-+
-+ if (rx_processed == 0) {
-+ if (napi_first_batch == 1) {
-+ desc_p = hif->descr_baseaddr_p +
-+ ((unsigned long int)(desc) -
-+ (unsigned long
-+ int)hif->descr_baseaddr_v);
-+ napi_first_batch = 0;
-+ }
-+ }
-+
-+ __memcpy12(&local_desc, desc);
-+
-+ if (local_desc.ctrl & BD_CTRL_DESC_EN)
-+ break;
-+ }
-+
-+ napi_first_batch = 0;
-+
-+#ifdef HIF_NAPI_STATS
-+ hif->napi_counters[NAPI_DESC_COUNT]++;
-+#endif
-+ len = BD_BUF_LEN(local_desc.ctrl);
-+ /*
-+ * dma_unmap_single(hif->dev, DDR_PFE_TO_PHYS(local_desc.data),
-+ * hif->rx_buf_len[rtc], DMA_FROM_DEVICE);
-+ */
-+ dma_unmap_single(hif->dev, DDR_PFE_TO_PHYS(local_desc.data),
-+ hif->rx_buf_len[rtc], DMA_FROM_DEVICE);
-+
-+ pkt_hdr = (struct hif_hdr *)hif->rx_buf_addr[rtc];
-+
-+ /* Track last HIF header received */
-+ if (!hif->started) {
-+ hif->started = 1;
-+
-+ __memcpy8(&hif_hdr, pkt_hdr);
-+
-+ hif->qno = hif_hdr.hdr.q_num;
-+ hif->client_id = hif_hdr.hdr.client_id;
-+ hif->client_ctrl = (hif_hdr.hdr.client_ctrl1 << 16) |
-+ hif_hdr.hdr.client_ctrl;
-+ flags = CL_DESC_FIRST;
-+
-+ } else {
-+ flags = 0;
-+ }
-+
-+ if (local_desc.ctrl & BD_CTRL_LIFM)
-+ flags |= CL_DESC_LAST;
-+
-+ /* Check for valid client id and still registered */
-+ if ((hif->client_id >= HIF_CLIENTS_MAX) ||
-+ !(test_bit(hif->client_id,
-+ &hif->shm->g_client_status[0]))) {
-+ printk_ratelimited("%s: packet with invalid client id %d q_num %d\n",
-+ __func__,
-+ hif->client_id,
-+ hif->qno);
-+
-+ free_buf = pkt_hdr;
-+
-+ goto pkt_drop;
-+ }
-+
-+ /* Check to valid queue number */
-+ if (hif->client[hif->client_id].rx_qn <= hif->qno) {
-+ pr_info("%s: packet with invalid queue: %d\n"
-+ , __func__, hif->qno);
-+ hif->qno = 0;
-+ }
-+
-+ free_buf =
-+ client_put_rxpacket(&hif->client[hif->client_id].rx_q[hif->qno],
-+ (void *)pkt_hdr, len, flags,
-+ hif->client_ctrl, &buf_size);
-+
-+ hif_lib_indicate_client(hif->client_id, EVENT_RX_PKT_IND,
-+ hif->qno);
-+
-+ if (unlikely(!free_buf)) {
-+#ifdef HIF_NAPI_STATS
-+ hif->napi_counters[NAPI_CLIENT_FULL_COUNT]++;
-+#endif
-+ /*
-+ * If we want to keep in polling mode to retry later,
-+ * we need to tell napi that we consumed
-+ * the full budget or we will hit a livelock scenario.
-+ * The core code keeps this napi instance
-+ * at the head of the list and none of the other
-+ * instances get to run
-+ */
-+ rx_processed = budget;
-+
-+ if (flags & CL_DESC_FIRST)
-+ hif->started = 0;
-+
-+ break;
-+ }
-+
-+pkt_drop:
-+ /*Fill free buffer in the descriptor */
-+ hif->rx_buf_addr[rtc] = free_buf;
-+ hif->rx_buf_len[rtc] = min(pfe_pkt_size, buf_size);
-+ writel((DDR_PHYS_TO_PFE
-+ ((u32)dma_map_single(hif->dev,
-+ free_buf, hif->rx_buf_len[rtc], DMA_FROM_DEVICE))),
-+ &desc->data);
-+ /*
-+ * Ensure everything else is written to DDR before
-+ * writing bd->ctrl
-+ */
-+ wmb();
-+ writel((BD_CTRL_PKT_INT_EN | BD_CTRL_LIFM | BD_CTRL_DIR |
-+ BD_CTRL_DESC_EN | BD_BUF_LEN(hif->rx_buf_len[rtc])),
-+ &desc->ctrl);
-+
-+ rtc = (rtc + 1) & (hif->rx_ring_size - 1);
-+
-+ if (local_desc.ctrl & BD_CTRL_LIFM) {
-+ if (!(hif->client_ctrl & HIF_CTRL_RX_CONTINUED)) {
-+ rx_processed++;
-+
-+#ifdef HIF_NAPI_STATS
-+ hif->napi_counters[NAPI_PACKET_COUNT]++;
-+#endif
-+ }
-+ hif->started = 0;
-+ }
-+ }
-+
-+ hif->rxtoclean_index = rtc;
-+ spin_unlock_bh(&hif->lock);
-+
-+ /* we made some progress, re-start rx dma in case it stopped */
-+ hif_rx_dma_start();
-+
-+ return rx_processed;
-+}
-+
-+/*
-+ * client_ack_txpacket-
-+ * This function ack the Tx packet in the give client Tx queue by resetting
-+ * ownership bit in the descriptor.
-+ */
-+static int client_ack_txpacket(struct pfe_hif *hif, unsigned int client_id,
-+ unsigned int q_no)
-+{
-+ struct hif_tx_queue *queue = &hif->client[client_id].tx_q[q_no];
-+ struct tx_queue_desc *desc = queue->base + queue->ack_idx;
-+
-+ if (readl(&desc->ctrl) & CL_DESC_OWN) {
-+ writel((readl(&desc->ctrl) & ~CL_DESC_OWN), &desc->ctrl);
-+ queue->ack_idx = (queue->ack_idx + 1) & (queue->size - 1);
-+
-+ return 0;
-+
-+ } else {
-+ /*This should not happen */
-+ pr_err("%s: %d %d %d %d %d %p %d\n", __func__,
-+ hif->txtosend, hif->txtoclean, hif->txavail,
-+ client_id, q_no, queue, queue->ack_idx);
-+ WARN(1, "%s: doesn't own this descriptor", __func__);
-+ return 1;
-+ }
-+}
-+
-+void __hif_tx_done_process(struct pfe_hif *hif, int count)
-+{
-+ struct hif_desc *desc;
-+ struct hif_desc_sw *desc_sw;
-+ int ttc, tx_avl;
-+ int pkts_done[HIF_CLIENTS_MAX] = {0, 0};
-+
-+ ttc = hif->txtoclean;
-+ tx_avl = hif->txavail;
-+
-+ while ((tx_avl < hif->tx_ring_size) && count--) {
-+ desc = hif->tx_base + ttc;
-+
-+ if (readl(&desc->ctrl) & BD_CTRL_DESC_EN)
-+ break;
-+
-+ desc_sw = &hif->tx_sw_queue[ttc];
-+
-+ if (desc_sw->data) {
-+ /*
-+ * dmap_unmap_single(hif->dev, desc_sw->data,
-+ * desc_sw->len, DMA_TO_DEVICE);
-+ */
-+ dma_unmap_single(hif->dev, desc_sw->data,
-+ desc_sw->len, DMA_TO_DEVICE);
-+ }
-+
-+ if (desc_sw->client_id >= HIF_CLIENTS_MAX) {
-+ pr_err("Invalid cl id %d\n", desc_sw->client_id);
-+ break;
-+ }
-+
-+ pkts_done[desc_sw->client_id]++;
-+
-+ client_ack_txpacket(hif, desc_sw->client_id, desc_sw->q_no);
-+
-+ ttc = (ttc + 1) & (hif->tx_ring_size - 1);
-+ tx_avl++;
-+ }
-+
-+ if (pkts_done[0])
-+ hif_lib_indicate_client(0, EVENT_TXDONE_IND, 0);
-+ if (pkts_done[1])
-+ hif_lib_indicate_client(1, EVENT_TXDONE_IND, 0);
-+
-+ hif->txtoclean = ttc;
-+ hif->txavail = tx_avl;
-+
-+ if (!count) {
-+ tasklet_schedule(&hif->tx_cleanup_tasklet);
-+ } else {
-+ /*Enable Tx done interrupt */
-+ writel(readl_relaxed(HIF_INT_ENABLE) | HIF_TXPKT_INT,
-+ HIF_INT_ENABLE);
-+ }
-+}
-+
-+static void pfe_tx_do_cleanup(unsigned long data)
-+{
-+ struct pfe_hif *hif = (struct pfe_hif *)data;
-+
-+ writel(HIF_INT | HIF_TXPKT_INT, HIF_INT_SRC);
-+
-+ hif_tx_done_process(hif, 64);
-+}
-+
-+/*
-+ * __hif_xmit_pkt -
-+ * This function puts one packet in the HIF Tx queue
-+ */
-+void __hif_xmit_pkt(struct pfe_hif *hif, unsigned int client_id, unsigned int
-+ q_no, void *data, u32 len, unsigned int flags)
-+{
-+ struct hif_desc *desc;
-+ struct hif_desc_sw *desc_sw;
-+
-+ desc = hif->tx_base + hif->txtosend;
-+ desc_sw = &hif->tx_sw_queue[hif->txtosend];
-+
-+ desc_sw->len = len;
-+ desc_sw->client_id = client_id;
-+ desc_sw->q_no = q_no;
-+ desc_sw->flags = flags;
-+
-+ if (flags & HIF_DONT_DMA_MAP) {
-+ desc_sw->data = 0;
-+ writel((u32)DDR_PHYS_TO_PFE(data), &desc->data);
-+ } else {
-+ desc_sw->data = dma_map_single(hif->dev, data, len,
-+ DMA_TO_DEVICE);
-+ writel((u32)DDR_PHYS_TO_PFE(desc_sw->data), &desc->data);
-+ }
-+
-+ hif->txtosend = (hif->txtosend + 1) & (hif->tx_ring_size - 1);
-+ hif->txavail--;
-+
-+ if ((!((flags & HIF_DATA_VALID) && (flags &
-+ HIF_LAST_BUFFER))))
-+ goto skip_tx;
-+
-+ /*
-+ * Ensure everything else is written to DDR before
-+ * writing bd->ctrl
-+ */
-+ wmb();
-+
-+ do {
-+ desc_sw = &hif->tx_sw_queue[hif->txtoflush];
-+ desc = hif->tx_base + hif->txtoflush;
-+
-+ if (desc_sw->flags & HIF_LAST_BUFFER) {
-+ writel((BD_CTRL_LIFM |
-+ BD_CTRL_BRFETCH_DISABLE | BD_CTRL_RTFETCH_DISABLE
-+ | BD_CTRL_PARSE_DISABLE | BD_CTRL_DESC_EN |
-+ BD_CTRL_PKT_INT_EN | BD_BUF_LEN(desc_sw->len)),
-+ &desc->ctrl);
-+ } else {
-+ writel((BD_CTRL_DESC_EN |
-+ BD_BUF_LEN(desc_sw->len)), &desc->ctrl);
-+ }
-+ hif->txtoflush = (hif->txtoflush + 1) & (hif->tx_ring_size - 1);
-+ }
-+ while (hif->txtoflush != hif->txtosend)
-+ ;
-+
-+skip_tx:
-+ return;
-+}
-+
-+static irqreturn_t wol_isr(int irq, void *dev_id)
-+{
-+ pr_info("WoL\n");
-+ gemac_set_wol(EMAC1_BASE_ADDR, 0);
-+ gemac_set_wol(EMAC2_BASE_ADDR, 0);
-+ return IRQ_HANDLED;
-+}
-+
-+/*
-+ * hif_isr-
-+ * This ISR routine processes Rx/Tx done interrupts from the HIF hardware block
-+ */
-+static irqreturn_t hif_isr(int irq, void *dev_id)
-+{
-+ struct pfe_hif *hif = (struct pfe_hif *)dev_id;
-+ int int_status;
-+ int int_enable_mask;
-+
-+ /*Read hif interrupt source register */
-+ int_status = readl_relaxed(HIF_INT_SRC);
-+ int_enable_mask = readl_relaxed(HIF_INT_ENABLE);
-+
-+ if ((int_status & HIF_INT) == 0)
-+ return IRQ_NONE;
-+
-+ int_status &= ~(HIF_INT);
-+
-+ if (int_status & HIF_RXPKT_INT) {
-+ int_status &= ~(HIF_RXPKT_INT);
-+ int_enable_mask &= ~(HIF_RXPKT_INT);
-+
-+ napi_first_batch = 1;
-+
-+ if (napi_schedule_prep(&hif->napi)) {
-+#ifdef HIF_NAPI_STATS
-+ hif->napi_counters[NAPI_SCHED_COUNT]++;
-+#endif
-+ __napi_schedule(&hif->napi);
-+ }
-+ }
-+
-+ if (int_status & HIF_TXPKT_INT) {
-+ int_status &= ~(HIF_TXPKT_INT);
-+ int_enable_mask &= ~(HIF_TXPKT_INT);
-+ /*Schedule tx cleanup tassklet */
-+ tasklet_schedule(&hif->tx_cleanup_tasklet);
-+ }
-+
-+ /*Disable interrupts, they will be enabled after they are serviced */
-+ writel_relaxed(int_enable_mask, HIF_INT_ENABLE);
-+
-+ if (int_status) {
-+ pr_info("%s : Invalid interrupt : %d\n", __func__,
-+ int_status);
-+ writel(int_status, HIF_INT_SRC);
-+ }
-+
-+ return IRQ_HANDLED;
-+}
-+
-+void hif_process_client_req(struct pfe_hif *hif, int req, int data1, int data2)
-+{
-+ unsigned int client_id = data1;
-+
-+ if (client_id >= HIF_CLIENTS_MAX) {
-+ pr_err("%s: client id %d out of bounds\n", __func__,
-+ client_id);
-+ return;
-+ }
-+
-+ switch (req) {
-+ case REQUEST_CL_REGISTER:
-+ /* Request for register a client */
-+ pr_info("%s: register client_id %d\n",
-+ __func__, client_id);
-+ pfe_hif_client_register(hif, client_id, (struct
-+ hif_client_shm *)&hif->shm->client[client_id]);
-+ break;
-+
-+ case REQUEST_CL_UNREGISTER:
-+ pr_info("%s: unregister client_id %d\n",
-+ __func__, client_id);
-+
-+ /* Request for unregister a client */
-+ pfe_hif_client_unregister(hif, client_id);
-+
-+ break;
-+
-+ default:
-+ pr_err("%s: unsupported request %d\n",
-+ __func__, req);
-+ break;
-+ }
-+
-+ /*
-+ * Process client Tx queues
-+ * Currently we don't have checking for tx pending
-+ */
-+}
-+
-+/*
-+ * pfe_hif_rx_poll
-+ * This function is NAPI poll function to process HIF Rx queue.
-+ */
-+static int pfe_hif_rx_poll(struct napi_struct *napi, int budget)
-+{
-+ struct pfe_hif *hif = container_of(napi, struct pfe_hif, napi);
-+ int work_done;
-+
-+#ifdef HIF_NAPI_STATS
-+ hif->napi_counters[NAPI_POLL_COUNT]++;
-+#endif
-+
-+ work_done = pfe_hif_rx_process(hif, budget);
-+
-+ if (work_done < budget) {
-+ napi_complete(napi);
-+ writel(readl_relaxed(HIF_INT_ENABLE) | HIF_RXPKT_INT,
-+ HIF_INT_ENABLE);
-+ }
-+#ifdef HIF_NAPI_STATS
-+ else
-+ hif->napi_counters[NAPI_FULL_BUDGET_COUNT]++;
-+#endif
-+
-+ return work_done;
-+}
-+
-+/*
-+ * pfe_hif_init
-+ * This function initializes the baseaddresses and irq, etc.
-+ */
-+int pfe_hif_init(struct pfe *pfe)
-+{
-+ struct pfe_hif *hif = &pfe->hif;
-+ int err;
-+
-+ pr_info("%s\n", __func__);
-+
-+ hif->dev = pfe->dev;
-+ hif->irq = pfe->hif_irq;
-+
-+ err = pfe_hif_alloc_descr(hif);
-+ if (err)
-+ goto err0;
-+
-+ if (pfe_hif_init_buffers(hif)) {
-+ pr_err("%s: Could not initialize buffer descriptors\n"
-+ , __func__);
-+ err = -ENOMEM;
-+ goto err1;
-+ }
-+
-+ /* Initialize NAPI for Rx processing */
-+ init_dummy_netdev(&hif->dummy_dev);
-+ netif_napi_add(&hif->dummy_dev, &hif->napi, pfe_hif_rx_poll);
-+ napi_enable(&hif->napi);
-+
-+ spin_lock_init(&hif->tx_lock);
-+ spin_lock_init(&hif->lock);
-+
-+ hif_init();
-+ hif_rx_enable();
-+ hif_tx_enable();
-+
-+ /* Disable tx done interrupt */
-+ writel(HIF_INT_MASK, HIF_INT_ENABLE);
-+
-+ gpi_enable(HGPI_BASE_ADDR);
-+
-+ err = request_irq(hif->irq, hif_isr, 0, "pfe_hif", hif);
-+ if (err) {
-+ pr_err("%s: failed to get the hif IRQ = %d\n",
-+ __func__, hif->irq);
-+ goto err1;
-+ }
-+
-+ err = request_irq(pfe->wol_irq, wol_isr, 0, "pfe_wol", pfe);
-+ if (err) {
-+ pr_err("%s: failed to get the wol IRQ = %d\n",
-+ __func__, pfe->wol_irq);
-+ goto err1;
-+ }
-+
-+ tasklet_init(&hif->tx_cleanup_tasklet,
-+ (void(*)(unsigned long))pfe_tx_do_cleanup,
-+ (unsigned long)hif);
-+
-+ return 0;
-+err1:
-+ pfe_hif_free_descr(hif);
-+err0:
-+ return err;
-+}
-+
-+/* pfe_hif_exit- */
-+void pfe_hif_exit(struct pfe *pfe)
-+{
-+ struct pfe_hif *hif = &pfe->hif;
-+
-+ pr_info("%s\n", __func__);
-+
-+ tasklet_kill(&hif->tx_cleanup_tasklet);
-+
-+ spin_lock_bh(&hif->lock);
-+ hif->shm->g_client_status[0] = 0;
-+ /* Make sure all clients are disabled*/
-+ hif->shm->g_client_status[1] = 0;
-+
-+ spin_unlock_bh(&hif->lock);
-+
-+ /*Disable Rx/Tx */
-+ gpi_disable(HGPI_BASE_ADDR);
-+ hif_rx_disable();
-+ hif_tx_disable();
-+
-+ napi_disable(&hif->napi);
-+ netif_napi_del(&hif->napi);
-+
-+ free_irq(pfe->wol_irq, pfe);
-+ free_irq(hif->irq, hif);
-+
-+ pfe_hif_release_buffers(hif);
-+ pfe_hif_free_descr(hif);
-+}
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/pfe_hif.h
-@@ -0,0 +1,199 @@
-+/* SPDX-License-Identifier: GPL-2.0+ */
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ */
-+
-+#ifndef _PFE_HIF_H_
-+#define _PFE_HIF_H_
-+
-+#include <linux/netdevice.h>
-+
-+#define HIF_NAPI_STATS
-+
-+#define HIF_CLIENT_QUEUES_MAX 16
-+#define HIF_RX_POLL_WEIGHT 64
-+
-+#define HIF_RX_PKT_MIN_SIZE 0x800 /* 2KB */
-+#define HIF_RX_PKT_MIN_SIZE_MASK ~(HIF_RX_PKT_MIN_SIZE - 1)
-+#define ROUND_MIN_RX_SIZE(_sz) (((_sz) + (HIF_RX_PKT_MIN_SIZE - 1)) \
-+ & HIF_RX_PKT_MIN_SIZE_MASK)
-+#define PRESENT_OFST_IN_PAGE(_buf) (((unsigned long int)(_buf) & (PAGE_SIZE \
-+ - 1)) & HIF_RX_PKT_MIN_SIZE_MASK)
-+
-+enum {
-+ NAPI_SCHED_COUNT = 0,
-+ NAPI_POLL_COUNT,
-+ NAPI_PACKET_COUNT,
-+ NAPI_DESC_COUNT,
-+ NAPI_FULL_BUDGET_COUNT,
-+ NAPI_CLIENT_FULL_COUNT,
-+ NAPI_MAX_COUNT
-+};
-+
-+/*
-+ * HIF_TX_DESC_NT value should be always greter than 4,
-+ * Otherwise HIF_TX_POLL_MARK will become zero.
-+ */
-+#define HIF_RX_DESC_NT 256
-+#define HIF_TX_DESC_NT 2048
-+
-+#define HIF_FIRST_BUFFER BIT(0)
-+#define HIF_LAST_BUFFER BIT(1)
-+#define HIF_DONT_DMA_MAP BIT(2)
-+#define HIF_DATA_VALID BIT(3)
-+#define HIF_TSO BIT(4)
-+
-+enum {
-+ PFE_CL_GEM0 = 0,
-+ PFE_CL_GEM1,
-+ HIF_CLIENTS_MAX
-+};
-+
-+/*structure to store client queue info */
-+struct hif_rx_queue {
-+ struct rx_queue_desc *base;
-+ u32 size;
-+ u32 write_idx;
-+};
-+
-+struct hif_tx_queue {
-+ struct tx_queue_desc *base;
-+ u32 size;
-+ u32 ack_idx;
-+};
-+
-+/*Structure to store the client info */
-+struct hif_client {
-+ int rx_qn;
-+ struct hif_rx_queue rx_q[HIF_CLIENT_QUEUES_MAX];
-+ int tx_qn;
-+ struct hif_tx_queue tx_q[HIF_CLIENT_QUEUES_MAX];
-+};
-+
-+/*HIF hardware buffer descriptor */
-+struct hif_desc {
-+ u32 ctrl;
-+ u32 status;
-+ u32 data;
-+ u32 next;
-+};
-+
-+struct __hif_desc {
-+ u32 ctrl;
-+ u32 status;
-+ u32 data;
-+};
-+
-+struct hif_desc_sw {
-+ dma_addr_t data;
-+ u16 len;
-+ u8 client_id;
-+ u8 q_no;
-+ u16 flags;
-+};
-+
-+struct hif_hdr {
-+ u8 client_id;
-+ u8 q_num;
-+ u16 client_ctrl;
-+ u16 client_ctrl1;
-+};
-+
-+struct __hif_hdr {
-+ union {
-+ struct hif_hdr hdr;
-+ u32 word[2];
-+ };
-+};
-+
-+struct hif_ipsec_hdr {
-+ u16 sa_handle[2];
-+} __packed;
-+
-+/* HIF_CTRL_TX... defines */
-+#define HIF_CTRL_TX_CHECKSUM BIT(2)
-+
-+/* HIF_CTRL_RX... defines */
-+#define HIF_CTRL_RX_OFFSET_OFST (24)
-+#define HIF_CTRL_RX_CHECKSUMMED BIT(2)
-+#define HIF_CTRL_RX_CONTINUED BIT(1)
-+
-+struct pfe_hif {
-+ /* To store registered clients in hif layer */
-+ struct hif_client client[HIF_CLIENTS_MAX];
-+ struct hif_shm *shm;
-+ int irq;
-+
-+ void *descr_baseaddr_v;
-+ unsigned long descr_baseaddr_p;
-+
-+ struct hif_desc *rx_base;
-+ u32 rx_ring_size;
-+ u32 rxtoclean_index;
-+ void *rx_buf_addr[HIF_RX_DESC_NT];
-+ int rx_buf_len[HIF_RX_DESC_NT];
-+ unsigned int qno;
-+ unsigned int client_id;
-+ unsigned int client_ctrl;
-+ unsigned int started;
-+
-+ struct hif_desc *tx_base;
-+ u32 tx_ring_size;
-+ u32 txtosend;
-+ u32 txtoclean;
-+ u32 txavail;
-+ u32 txtoflush;
-+ struct hif_desc_sw tx_sw_queue[HIF_TX_DESC_NT];
-+
-+/* tx_lock synchronizes hif packet tx as well as pfe_hif structure access */
-+ spinlock_t tx_lock;
-+/* lock synchronizes hif rx queue processing */
-+ spinlock_t lock;
-+ struct net_device dummy_dev;
-+ struct napi_struct napi;
-+ struct device *dev;
-+
-+#ifdef HIF_NAPI_STATS
-+ unsigned int napi_counters[NAPI_MAX_COUNT];
-+#endif
-+ struct tasklet_struct tx_cleanup_tasklet;
-+};
-+
-+void __hif_xmit_pkt(struct pfe_hif *hif, unsigned int client_id, unsigned int
-+ q_no, void *data, u32 len, unsigned int flags);
-+int hif_xmit_pkt(struct pfe_hif *hif, unsigned int client_id, unsigned int q_no,
-+ void *data, unsigned int len);
-+void __hif_tx_done_process(struct pfe_hif *hif, int count);
-+void hif_process_client_req(struct pfe_hif *hif, int req, int data1, int
-+ data2);
-+int pfe_hif_init(struct pfe *pfe);
-+void pfe_hif_exit(struct pfe *pfe);
-+void pfe_hif_rx_idle(struct pfe_hif *hif);
-+static inline void hif_tx_done_process(struct pfe_hif *hif, int count)
-+{
-+ spin_lock_bh(&hif->tx_lock);
-+ __hif_tx_done_process(hif, count);
-+ spin_unlock_bh(&hif->tx_lock);
-+}
-+
-+static inline void hif_tx_lock(struct pfe_hif *hif)
-+{
-+ spin_lock_bh(&hif->tx_lock);
-+}
-+
-+static inline void hif_tx_unlock(struct pfe_hif *hif)
-+{
-+ spin_unlock_bh(&hif->tx_lock);
-+}
-+
-+static inline int __hif_tx_avail(struct pfe_hif *hif)
-+{
-+ return hif->txavail;
-+}
-+
-+#define __memcpy8(dst, src) memcpy(dst, src, 8)
-+#define __memcpy12(dst, src) memcpy(dst, src, 12)
-+#define __memcpy(dst, src, len) memcpy(dst, src, len)
-+
-+#endif /* _PFE_HIF_H_ */
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/pfe_hif_lib.c
-@@ -0,0 +1,628 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ */
-+
-+#include <linux/version.h>
-+#include <linux/kernel.h>
-+#include <linux/slab.h>
-+#include <linux/interrupt.h>
-+#include <linux/workqueue.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/dmapool.h>
-+#include <linux/sched.h>
-+#include <linux/skbuff.h>
-+#include <linux/moduleparam.h>
-+#include <linux/cpu.h>
-+
-+#include "pfe_mod.h"
-+#include "pfe_hif.h"
-+#include "pfe_hif_lib.h"
-+
-+unsigned int lro_mode;
-+unsigned int page_mode;
-+unsigned int tx_qos = 1;
-+module_param(tx_qos, uint, 0444);
-+MODULE_PARM_DESC(tx_qos, "0: disable ,\n"
-+ "1: enable (default), guarantee no packet drop at TMU level\n");
-+unsigned int pfe_pkt_size;
-+unsigned int pfe_pkt_headroom;
-+unsigned int emac_txq_cnt;
-+
-+/*
-+ * @pfe_hal_lib.c.
-+ * Common functions used by HIF client drivers
-+ */
-+
-+/*HIF shared memory Global variable */
-+struct hif_shm ghif_shm;
-+
-+/* Cleanup the HIF shared memory, release HIF rx_buffer_pool.
-+ * This function should be called after pfe_hif_exit
-+ *
-+ * @param[in] hif_shm Shared memory address location in DDR
-+ */
-+static void pfe_hif_shm_clean(struct hif_shm *hif_shm)
-+{
-+ int i;
-+ void *pkt;
-+
-+ for (i = 0; i < hif_shm->rx_buf_pool_cnt; i++) {
-+ pkt = hif_shm->rx_buf_pool[i];
-+ if (pkt) {
-+ hif_shm->rx_buf_pool[i] = NULL;
-+ pkt -= pfe_pkt_headroom;
-+
-+ if (page_mode)
-+ put_page(virt_to_page(pkt));
-+ else
-+ kfree(pkt);
-+ }
-+ }
-+}
-+
-+/* Initialize shared memory used between HIF driver and clients,
-+ * allocate rx_buffer_pool required for HIF Rx descriptors.
-+ * This function should be called before initializing HIF driver.
-+ *
-+ * @param[in] hif_shm Shared memory address location in DDR
-+ * @rerurn 0 - on succes, <0 on fail to initialize
-+ */
-+static int pfe_hif_shm_init(struct hif_shm *hif_shm)
-+{
-+ int i;
-+ void *pkt;
-+
-+ memset(hif_shm, 0, sizeof(struct hif_shm));
-+ hif_shm->rx_buf_pool_cnt = HIF_RX_DESC_NT;
-+
-+ for (i = 0; i < hif_shm->rx_buf_pool_cnt; i++) {
-+ if (page_mode) {
-+ pkt = (void *)__get_free_page(GFP_KERNEL |
-+ GFP_DMA_PFE);
-+ } else {
-+ pkt = kmalloc(PFE_BUF_SIZE, GFP_KERNEL | GFP_DMA_PFE);
-+ }
-+
-+ if (pkt)
-+ hif_shm->rx_buf_pool[i] = pkt + pfe_pkt_headroom;
-+ else
-+ goto err0;
-+ }
-+
-+ return 0;
-+
-+err0:
-+ pr_err("%s Low memory\n", __func__);
-+ pfe_hif_shm_clean(hif_shm);
-+ return -ENOMEM;
-+}
-+
-+/*This function sends indication to HIF driver
-+ *
-+ * @param[in] hif hif context
-+ */
-+static void hif_lib_indicate_hif(struct pfe_hif *hif, int req, int data1, int
-+ data2)
-+{
-+ hif_process_client_req(hif, req, data1, data2);
-+}
-+
-+void hif_lib_indicate_client(int client_id, int event_type, int qno)
-+{
-+ struct hif_client_s *client = pfe->hif_client[client_id];
-+
-+ if (!client || (event_type >= HIF_EVENT_MAX) || (qno >=
-+ HIF_CLIENT_QUEUES_MAX))
-+ return;
-+
-+ if (!test_and_set_bit(qno, &client->queue_mask[event_type]))
-+ client->event_handler(client->priv, event_type, qno);
-+}
-+
-+/*This function releases Rx queue descriptors memory and pre-filled buffers
-+ *
-+ * @param[in] client hif_client context
-+ */
-+static void hif_lib_client_release_rx_buffers(struct hif_client_s *client)
-+{
-+ struct rx_queue_desc *desc;
-+ int qno, ii;
-+ void *buf;
-+
-+ for (qno = 0; qno < client->rx_qn; qno++) {
-+ desc = client->rx_q[qno].base;
-+
-+ for (ii = 0; ii < client->rx_q[qno].size; ii++) {
-+ buf = (void *)desc->data;
-+ if (buf) {
-+ buf -= pfe_pkt_headroom;
-+
-+ if (page_mode)
-+ free_page((unsigned long)buf);
-+ else
-+ kfree(buf);
-+
-+ desc->ctrl = 0;
-+ }
-+
-+ desc++;
-+ }
-+ }
-+
-+ kfree(client->rx_qbase);
-+}
-+
-+/*This function allocates memory for the rxq descriptors and pre-fill rx queues
-+ * with buffers.
-+ * @param[in] client client context
-+ * @param[in] q_size size of the rxQ, all queues are of same size
-+ */
-+static int hif_lib_client_init_rx_buffers(struct hif_client_s *client, int
-+ q_size)
-+{
-+ struct rx_queue_desc *desc;
-+ struct hif_client_rx_queue *queue;
-+ int ii, qno;
-+
-+ /*Allocate memory for the client queues */
-+ client->rx_qbase = kzalloc(client->rx_qn * q_size * sizeof(struct
-+ rx_queue_desc), GFP_KERNEL);
-+ if (!client->rx_qbase)
-+ goto err;
-+
-+ for (qno = 0; qno < client->rx_qn; qno++) {
-+ queue = &client->rx_q[qno];
-+
-+ queue->base = client->rx_qbase + qno * q_size * sizeof(struct
-+ rx_queue_desc);
-+ queue->size = q_size;
-+ queue->read_idx = 0;
-+ queue->write_idx = 0;
-+
-+ pr_debug("rx queue: %d, base: %p, size: %d\n", qno,
-+ queue->base, queue->size);
-+ }
-+
-+ for (qno = 0; qno < client->rx_qn; qno++) {
-+ queue = &client->rx_q[qno];
-+ desc = queue->base;
-+
-+ for (ii = 0; ii < queue->size; ii++) {
-+ desc->ctrl = CL_DESC_BUF_LEN(pfe_pkt_size) |
-+ CL_DESC_OWN;
-+ desc++;
-+ }
-+ }
-+
-+ return 0;
-+
-+err:
-+ return 1;
-+}
-+
-+
-+static void hif_lib_client_cleanup_tx_queue(struct hif_client_tx_queue *queue)
-+{
-+ pr_debug("%s\n", __func__);
-+
-+ /*
-+ * Check if there are any pending packets. Client must flush the tx
-+ * queues before unregistering, by calling by calling
-+ * hif_lib_tx_get_next_complete()
-+ *
-+ * Hif no longer calls since we are no longer registered
-+ */
-+ if (queue->tx_pending)
-+ pr_err("%s: pending transmit packets\n", __func__);
-+}
-+
-+static void hif_lib_client_release_tx_buffers(struct hif_client_s *client)
-+{
-+ int qno;
-+
-+ pr_debug("%s\n", __func__);
-+
-+ for (qno = 0; qno < client->tx_qn; qno++)
-+ hif_lib_client_cleanup_tx_queue(&client->tx_q[qno]);
-+
-+ kfree(client->tx_qbase);
-+}
-+
-+static int hif_lib_client_init_tx_buffers(struct hif_client_s *client, int
-+ q_size)
-+{
-+ struct hif_client_tx_queue *queue;
-+ int qno;
-+
-+ client->tx_qbase = kzalloc(client->tx_qn * q_size * sizeof(struct
-+ tx_queue_desc), GFP_KERNEL);
-+ if (!client->tx_qbase)
-+ return 1;
-+
-+ for (qno = 0; qno < client->tx_qn; qno++) {
-+ queue = &client->tx_q[qno];
-+
-+ queue->base = client->tx_qbase + qno * q_size * sizeof(struct
-+ tx_queue_desc);
-+ queue->size = q_size;
-+ queue->read_idx = 0;
-+ queue->write_idx = 0;
-+ queue->tx_pending = 0;
-+ queue->nocpy_flag = 0;
-+ queue->prev_tmu_tx_pkts = 0;
-+ queue->done_tmu_tx_pkts = 0;
-+
-+ pr_debug("tx queue: %d, base: %p, size: %d\n", qno,
-+ queue->base, queue->size);
-+ }
-+
-+ return 0;
-+}
-+
-+static int hif_lib_event_dummy(void *priv, int event_type, int qno)
-+{
-+ return 0;
-+}
-+
-+int hif_lib_client_register(struct hif_client_s *client)
-+{
-+ struct hif_shm *hif_shm;
-+ struct hif_client_shm *client_shm;
-+ int err, i;
-+ /* int loop_cnt = 0; */
-+
-+ pr_debug("%s\n", __func__);
-+
-+ /*Allocate memory before spin_lock*/
-+ if (hif_lib_client_init_rx_buffers(client, client->rx_qsize)) {
-+ err = -ENOMEM;
-+ goto err_rx;
-+ }
-+
-+ if (hif_lib_client_init_tx_buffers(client, client->tx_qsize)) {
-+ err = -ENOMEM;
-+ goto err_tx;
-+ }
-+
-+ spin_lock_bh(&pfe->hif.lock);
-+ if (!(client->pfe) || (client->id >= HIF_CLIENTS_MAX) ||
-+ (pfe->hif_client[client->id])) {
-+ err = -EINVAL;
-+ goto err;
-+ }
-+
-+ hif_shm = client->pfe->hif.shm;
-+
-+ if (!client->event_handler)
-+ client->event_handler = hif_lib_event_dummy;
-+
-+ /*Initialize client specific shared memory */
-+ client_shm = (struct hif_client_shm *)&hif_shm->client[client->id];
-+ client_shm->rx_qbase = (unsigned long int)client->rx_qbase;
-+ client_shm->rx_qsize = client->rx_qsize;
-+ client_shm->tx_qbase = (unsigned long int)client->tx_qbase;
-+ client_shm->tx_qsize = client->tx_qsize;
-+ client_shm->ctrl = (client->tx_qn << CLIENT_CTRL_TX_Q_CNT_OFST) |
-+ (client->rx_qn << CLIENT_CTRL_RX_Q_CNT_OFST);
-+ /* spin_lock_init(&client->rx_lock); */
-+
-+ for (i = 0; i < HIF_EVENT_MAX; i++) {
-+ client->queue_mask[i] = 0; /*
-+ * By default all events are
-+ * unmasked
-+ */
-+ }
-+
-+ /*Indicate to HIF driver*/
-+ hif_lib_indicate_hif(&pfe->hif, REQUEST_CL_REGISTER, client->id, 0);
-+
-+ pr_debug("%s: client: %p, client_id: %d, tx_qsize: %d, rx_qsize: %d\n",
-+ __func__, client, client->id, client->tx_qsize,
-+ client->rx_qsize);
-+
-+ client->cpu_id = -1;
-+
-+ pfe->hif_client[client->id] = client;
-+ spin_unlock_bh(&pfe->hif.lock);
-+
-+ return 0;
-+
-+err:
-+ spin_unlock_bh(&pfe->hif.lock);
-+ hif_lib_client_release_tx_buffers(client);
-+
-+err_tx:
-+ hif_lib_client_release_rx_buffers(client);
-+
-+err_rx:
-+ return err;
-+}
-+
-+int hif_lib_client_unregister(struct hif_client_s *client)
-+{
-+ struct pfe *pfe = client->pfe;
-+ u32 client_id = client->id;
-+
-+ pr_info(
-+ "%s : client: %p, client_id: %d, txQ_depth: %d, rxQ_depth: %d\n"
-+ , __func__, client, client->id, client->tx_qsize,
-+ client->rx_qsize);
-+
-+ spin_lock_bh(&pfe->hif.lock);
-+ hif_lib_indicate_hif(&pfe->hif, REQUEST_CL_UNREGISTER, client->id, 0);
-+
-+ hif_lib_client_release_tx_buffers(client);
-+ hif_lib_client_release_rx_buffers(client);
-+ pfe->hif_client[client_id] = NULL;
-+ spin_unlock_bh(&pfe->hif.lock);
-+
-+ return 0;
-+}
-+
-+int hif_lib_event_handler_start(struct hif_client_s *client, int event,
-+ int qno)
-+{
-+ struct hif_client_rx_queue *queue = &client->rx_q[qno];
-+ struct rx_queue_desc *desc = queue->base + queue->read_idx;
-+
-+ if ((event >= HIF_EVENT_MAX) || (qno >= HIF_CLIENT_QUEUES_MAX)) {
-+ pr_debug("%s: Unsupported event : %d queue number : %d\n",
-+ __func__, event, qno);
-+ return -1;
-+ }
-+
-+ test_and_clear_bit(qno, &client->queue_mask[event]);
-+
-+ switch (event) {
-+ case EVENT_RX_PKT_IND:
-+ if (!(desc->ctrl & CL_DESC_OWN))
-+ hif_lib_indicate_client(client->id,
-+ EVENT_RX_PKT_IND, qno);
-+ break;
-+
-+ case EVENT_HIGH_RX_WM:
-+ case EVENT_TXDONE_IND:
-+ default:
-+ break;
-+ }
-+
-+ return 0;
-+}
-+
-+/*
-+ * This function gets one packet from the specified client queue
-+ * It also refill the rx buffer
-+ */
-+void *hif_lib_receive_pkt(struct hif_client_s *client, int qno, int *len, int
-+ *ofst, unsigned int *rx_ctrl,
-+ unsigned int *desc_ctrl, void **priv_data)
-+{
-+ struct hif_client_rx_queue *queue = &client->rx_q[qno];
-+ struct rx_queue_desc *desc;
-+ void *pkt = NULL;
-+
-+ /*
-+ * Following lock is to protect rx queue access from,
-+ * hif_lib_event_handler_start.
-+ * In general below lock is not required, because hif_lib_xmit_pkt and
-+ * hif_lib_event_handler_start are called from napi poll and which is
-+ * not re-entrant. But if some client use in different way this lock is
-+ * required.
-+ */
-+ /*spin_lock_irqsave(&client->rx_lock, flags); */
-+ desc = queue->base + queue->read_idx;
-+ if (!(desc->ctrl & CL_DESC_OWN)) {
-+ pkt = desc->data - pfe_pkt_headroom;
-+
-+ *rx_ctrl = desc->client_ctrl;
-+ *desc_ctrl = desc->ctrl;
-+
-+ if (desc->ctrl & CL_DESC_FIRST) {
-+ u16 size = *rx_ctrl >> HIF_CTRL_RX_OFFSET_OFST;
-+
-+ if (size) {
-+ size += PFE_PARSE_INFO_SIZE;
-+ *len = CL_DESC_BUF_LEN(desc->ctrl) -
-+ PFE_PKT_HEADER_SZ - size;
-+ *ofst = pfe_pkt_headroom + PFE_PKT_HEADER_SZ
-+ + size;
-+ *priv_data = desc->data + PFE_PKT_HEADER_SZ;
-+ } else {
-+ *len = CL_DESC_BUF_LEN(desc->ctrl) -
-+ PFE_PKT_HEADER_SZ - PFE_PARSE_INFO_SIZE;
-+ *ofst = pfe_pkt_headroom
-+ + PFE_PKT_HEADER_SZ
-+ + PFE_PARSE_INFO_SIZE;
-+ *priv_data = NULL;
-+ }
-+
-+ } else {
-+ *len = CL_DESC_BUF_LEN(desc->ctrl);
-+ *ofst = pfe_pkt_headroom;
-+ }
-+
-+ /*
-+ * Needed so we don't free a buffer/page
-+ * twice on module_exit
-+ */
-+ desc->data = NULL;
-+
-+ /*
-+ * Ensure everything else is written to DDR before
-+ * writing bd->ctrl
-+ */
-+ smp_wmb();
-+
-+ desc->ctrl = CL_DESC_BUF_LEN(pfe_pkt_size) | CL_DESC_OWN;
-+ queue->read_idx = (queue->read_idx + 1) & (queue->size - 1);
-+ }
-+
-+ /*spin_unlock_irqrestore(&client->rx_lock, flags); */
-+ return pkt;
-+}
-+
-+static inline void hif_hdr_write(struct hif_hdr *pkt_hdr, unsigned int
-+ client_id, unsigned int qno,
-+ u32 client_ctrl)
-+{
-+ /* Optimize the write since the destinaton may be non-cacheable */
-+ if (!((unsigned long)pkt_hdr & 0x3)) {
-+ ((u32 *)pkt_hdr)[0] = (client_ctrl << 16) | (qno << 8) |
-+ client_id;
-+ } else {
-+ ((u16 *)pkt_hdr)[0] = (qno << 8) | (client_id & 0xFF);
-+ ((u16 *)pkt_hdr)[1] = (client_ctrl & 0xFFFF);
-+ }
-+}
-+
-+/*This function puts the given packet in the specific client queue */
-+void __hif_lib_xmit_pkt(struct hif_client_s *client, unsigned int qno, void
-+ *data, unsigned int len, u32 client_ctrl,
-+ unsigned int flags, void *client_data)
-+{
-+ struct hif_client_tx_queue *queue = &client->tx_q[qno];
-+ struct tx_queue_desc *desc = queue->base + queue->write_idx;
-+
-+ /* First buffer */
-+ if (flags & HIF_FIRST_BUFFER) {
-+ data -= sizeof(struct hif_hdr);
-+ len += sizeof(struct hif_hdr);
-+
-+ hif_hdr_write(data, client->id, qno, client_ctrl);
-+ }
-+
-+ desc->data = client_data;
-+ desc->ctrl = CL_DESC_OWN | CL_DESC_FLAGS(flags);
-+
-+ __hif_xmit_pkt(&pfe->hif, client->id, qno, data, len, flags);
-+
-+ queue->write_idx = (queue->write_idx + 1) & (queue->size - 1);
-+ queue->tx_pending++;
-+ queue->jiffies_last_packet = jiffies;
-+}
-+
-+void *hif_lib_tx_get_next_complete(struct hif_client_s *client, int qno,
-+ unsigned int *flags, int count)
-+{
-+ struct hif_client_tx_queue *queue = &client->tx_q[qno];
-+ struct tx_queue_desc *desc = queue->base + queue->read_idx;
-+
-+ pr_debug("%s: qno : %d rd_indx: %d pending:%d\n", __func__, qno,
-+ queue->read_idx, queue->tx_pending);
-+
-+ if (!queue->tx_pending)
-+ return NULL;
-+
-+ if (queue->nocpy_flag && !queue->done_tmu_tx_pkts) {
-+ u32 tmu_tx_pkts = be32_to_cpu(pe_dmem_read(TMU0_ID +
-+ client->id, TMU_DM_TX_TRANS, 4));
-+
-+ if (queue->prev_tmu_tx_pkts > tmu_tx_pkts)
-+ queue->done_tmu_tx_pkts = UINT_MAX -
-+ queue->prev_tmu_tx_pkts + tmu_tx_pkts;
-+ else
-+ queue->done_tmu_tx_pkts = tmu_tx_pkts -
-+ queue->prev_tmu_tx_pkts;
-+
-+ queue->prev_tmu_tx_pkts = tmu_tx_pkts;
-+
-+ if (!queue->done_tmu_tx_pkts)
-+ return NULL;
-+ }
-+
-+ if (desc->ctrl & CL_DESC_OWN)
-+ return NULL;
-+
-+ queue->read_idx = (queue->read_idx + 1) & (queue->size - 1);
-+ queue->tx_pending--;
-+
-+ *flags = CL_DESC_GET_FLAGS(desc->ctrl);
-+
-+ if (queue->done_tmu_tx_pkts && (*flags & HIF_LAST_BUFFER))
-+ queue->done_tmu_tx_pkts--;
-+
-+ return desc->data;
-+}
-+
-+static void hif_lib_tmu_credit_init(struct pfe *pfe)
-+{
-+ int i, q;
-+
-+ for (i = 0; i < NUM_GEMAC_SUPPORT; i++)
-+ for (q = 0; q < emac_txq_cnt; q++) {
-+ pfe->tmu_credit.tx_credit_max[i][q] = (q == 0) ?
-+ DEFAULT_Q0_QDEPTH : DEFAULT_MAX_QDEPTH;
-+ pfe->tmu_credit.tx_credit[i][q] =
-+ pfe->tmu_credit.tx_credit_max[i][q];
-+ }
-+}
-+
-+/* __hif_lib_update_credit
-+ *
-+ * @param[in] client hif client context
-+ * @param[in] queue queue number in match with TMU
-+ */
-+void __hif_lib_update_credit(struct hif_client_s *client, unsigned int queue)
-+{
-+ unsigned int tmu_tx_packets, tmp;
-+
-+ if (tx_qos) {
-+ tmu_tx_packets = be32_to_cpu(pe_dmem_read(TMU0_ID +
-+ client->id, (TMU_DM_TX_TRANS + (queue * 4)), 4));
-+
-+ /* tx_packets counter overflowed */
-+ if (tmu_tx_packets >
-+ pfe->tmu_credit.tx_packets[client->id][queue]) {
-+ tmp = UINT_MAX - tmu_tx_packets +
-+ pfe->tmu_credit.tx_packets[client->id][queue];
-+
-+ pfe->tmu_credit.tx_credit[client->id][queue] =
-+ pfe->tmu_credit.tx_credit_max[client->id][queue] - tmp;
-+ } else {
-+ /* TMU tx <= pfe_eth tx, normal case or both OF since
-+ * last time
-+ */
-+ pfe->tmu_credit.tx_credit[client->id][queue] =
-+ pfe->tmu_credit.tx_credit_max[client->id][queue] -
-+ (pfe->tmu_credit.tx_packets[client->id][queue] -
-+ tmu_tx_packets);
-+ }
-+ }
-+}
-+
-+int pfe_hif_lib_init(struct pfe *pfe)
-+{
-+ int rc;
-+
-+ pr_info("%s\n", __func__);
-+
-+ if (lro_mode) {
-+ page_mode = 1;
-+ pfe_pkt_size = min(PAGE_SIZE, MAX_PFE_PKT_SIZE);
-+ pfe_pkt_headroom = 0;
-+ } else {
-+ page_mode = 0;
-+ pfe_pkt_size = PFE_PKT_SIZE;
-+ pfe_pkt_headroom = PFE_PKT_HEADROOM;
-+ }
-+
-+ if (tx_qos)
-+ emac_txq_cnt = EMAC_TXQ_CNT / 2;
-+ else
-+ emac_txq_cnt = EMAC_TXQ_CNT;
-+
-+ hif_lib_tmu_credit_init(pfe);
-+ pfe->hif.shm = &ghif_shm;
-+ rc = pfe_hif_shm_init(pfe->hif.shm);
-+
-+ return rc;
-+}
-+
-+void pfe_hif_lib_exit(struct pfe *pfe)
-+{
-+ pr_info("%s\n", __func__);
-+
-+ pfe_hif_shm_clean(pfe->hif.shm);
-+}
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/pfe_hif_lib.h
-@@ -0,0 +1,229 @@
-+/* SPDX-License-Identifier: GPL-2.0+ */
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ */
-+
-+#ifndef _PFE_HIF_LIB_H_
-+#define _PFE_HIF_LIB_H_
-+
-+#include "pfe_hif.h"
-+
-+#define HIF_CL_REQ_TIMEOUT 10
-+#define GFP_DMA_PFE 0
-+#define PFE_PARSE_INFO_SIZE 16
-+
-+enum {
-+ REQUEST_CL_REGISTER = 0,
-+ REQUEST_CL_UNREGISTER,
-+ HIF_REQUEST_MAX
-+};
-+
-+enum {
-+ /* Event to indicate that client rx queue is reached water mark level */
-+ EVENT_HIGH_RX_WM = 0,
-+ /* Event to indicate that, packet received for client */
-+ EVENT_RX_PKT_IND,
-+ /* Event to indicate that, packet tx done for client */
-+ EVENT_TXDONE_IND,
-+ HIF_EVENT_MAX
-+};
-+
-+/*structure to store client queue info */
-+
-+/*structure to store client queue info */
-+struct hif_client_rx_queue {
-+ struct rx_queue_desc *base;
-+ u32 size;
-+ u32 read_idx;
-+ u32 write_idx;
-+};
-+
-+struct hif_client_tx_queue {
-+ struct tx_queue_desc *base;
-+ u32 size;
-+ u32 read_idx;
-+ u32 write_idx;
-+ u32 tx_pending;
-+ unsigned long jiffies_last_packet;
-+ u32 nocpy_flag;
-+ u32 prev_tmu_tx_pkts;
-+ u32 done_tmu_tx_pkts;
-+};
-+
-+struct hif_client_s {
-+ int id;
-+ int tx_qn;
-+ int rx_qn;
-+ void *rx_qbase;
-+ void *tx_qbase;
-+ int tx_qsize;
-+ int rx_qsize;
-+ int cpu_id;
-+ struct hif_client_tx_queue tx_q[HIF_CLIENT_QUEUES_MAX];
-+ struct hif_client_rx_queue rx_q[HIF_CLIENT_QUEUES_MAX];
-+ int (*event_handler)(void *priv, int event, int data);
-+ unsigned long queue_mask[HIF_EVENT_MAX];
-+ struct pfe *pfe;
-+ void *priv;
-+};
-+
-+/*
-+ * Client specific shared memory
-+ * It contains number of Rx/Tx queues, base addresses and queue sizes
-+ */
-+struct hif_client_shm {
-+ u32 ctrl; /*0-7: number of Rx queues, 8-15: number of tx queues */
-+ unsigned long rx_qbase; /*Rx queue base address */
-+ u32 rx_qsize; /*each Rx queue size, all Rx queues are of same size */
-+ unsigned long tx_qbase; /* Tx queue base address */
-+ u32 tx_qsize; /*each Tx queue size, all Tx queues are of same size */
-+};
-+
-+/*Client shared memory ctrl bit description */
-+#define CLIENT_CTRL_RX_Q_CNT_OFST 0
-+#define CLIENT_CTRL_TX_Q_CNT_OFST 8
-+#define CLIENT_CTRL_RX_Q_CNT(ctrl) (((ctrl) >> CLIENT_CTRL_RX_Q_CNT_OFST) \
-+ & 0xFF)
-+#define CLIENT_CTRL_TX_Q_CNT(ctrl) (((ctrl) >> CLIENT_CTRL_TX_Q_CNT_OFST) \
-+ & 0xFF)
-+
-+/*
-+ * Shared memory used to communicate between HIF driver and host/client drivers
-+ * Before starting the hif driver rx_buf_pool ans rx_buf_pool_cnt should be
-+ * initialized with host buffers and buffers count in the pool.
-+ * rx_buf_pool_cnt should be >= HIF_RX_DESC_NT.
-+ *
-+ */
-+struct hif_shm {
-+ u32 rx_buf_pool_cnt; /*Number of rx buffers available*/
-+ /*Rx buffers required to initialize HIF rx descriptors */
-+ void *rx_buf_pool[HIF_RX_DESC_NT];
-+ unsigned long g_client_status[2]; /*Global client status bit mask */
-+ /* Client specific shared memory */
-+ struct hif_client_shm client[HIF_CLIENTS_MAX];
-+};
-+
-+#define CL_DESC_OWN BIT(31)
-+/* This sets owner ship to HIF driver */
-+#define CL_DESC_LAST BIT(30)
-+/* This indicates last packet for multi buffers handling */
-+#define CL_DESC_FIRST BIT(29)
-+/* This indicates first packet for multi buffers handling */
-+
-+#define CL_DESC_BUF_LEN(x) ((x) & 0xFFFF)
-+#define CL_DESC_FLAGS(x) (((x) & 0xF) << 16)
-+#define CL_DESC_GET_FLAGS(x) (((x) >> 16) & 0xF)
-+
-+struct rx_queue_desc {
-+ void *data;
-+ u32 ctrl; /*0-15bit len, 16-20bit flags, 31bit owner*/
-+ u32 client_ctrl;
-+};
-+
-+struct tx_queue_desc {
-+ void *data;
-+ u32 ctrl; /*0-15bit len, 16-20bit flags, 31bit owner*/
-+};
-+
-+/* HIF Rx is not working properly for 2-byte aligned buffers and
-+ * ip_header should be 4byte aligned for better iperformance.
-+ * "ip_header = 64 + 6(hif_header) + 14 (MAC Header)" will be 4byte aligned.
-+ */
-+#define PFE_PKT_HEADER_SZ sizeof(struct hif_hdr)
-+/* must be big enough for headroom, pkt size and skb shared info */
-+#define PFE_BUF_SIZE 2048
-+#define PFE_PKT_HEADROOM 128
-+
-+#define SKB_SHARED_INFO_SIZE SKB_DATA_ALIGN(sizeof(struct skb_shared_info))
-+#define PFE_PKT_SIZE (PFE_BUF_SIZE - PFE_PKT_HEADROOM \
-+ - SKB_SHARED_INFO_SIZE)
-+#define MAX_L2_HDR_SIZE 14 /* Not correct for VLAN/PPPoE */
-+#define MAX_L3_HDR_SIZE 20 /* Not correct for IPv6 */
-+#define MAX_L4_HDR_SIZE 60 /* TCP with maximum options */
-+#define MAX_HDR_SIZE (MAX_L2_HDR_SIZE + MAX_L3_HDR_SIZE \
-+ + MAX_L4_HDR_SIZE)
-+/* Used in page mode to clamp packet size to the maximum supported by the hif
-+ *hw interface (<16KiB)
-+ */
-+#define MAX_PFE_PKT_SIZE 16380UL
-+
-+extern unsigned int pfe_pkt_size;
-+extern unsigned int pfe_pkt_headroom;
-+extern unsigned int page_mode;
-+extern unsigned int lro_mode;
-+extern unsigned int tx_qos;
-+extern unsigned int emac_txq_cnt;
-+
-+int pfe_hif_lib_init(struct pfe *pfe);
-+void pfe_hif_lib_exit(struct pfe *pfe);
-+int hif_lib_client_register(struct hif_client_s *client);
-+int hif_lib_client_unregister(struct hif_client_s *client);
-+void __hif_lib_xmit_pkt(struct hif_client_s *client, unsigned int qno, void
-+ *data, unsigned int len, u32 client_ctrl,
-+ unsigned int flags, void *client_data);
-+int hif_lib_xmit_pkt(struct hif_client_s *client, unsigned int qno, void *data,
-+ unsigned int len, u32 client_ctrl, void *client_data);
-+void hif_lib_indicate_client(int cl_id, int event, int data);
-+int hif_lib_event_handler_start(struct hif_client_s *client, int event, int
-+ data);
-+int hif_lib_tmu_queue_start(struct hif_client_s *client, int qno);
-+int hif_lib_tmu_queue_stop(struct hif_client_s *client, int qno);
-+void *hif_lib_tx_get_next_complete(struct hif_client_s *client, int qno,
-+ unsigned int *flags, int count);
-+void *hif_lib_receive_pkt(struct hif_client_s *client, int qno, int *len, int
-+ *ofst, unsigned int *rx_ctrl,
-+ unsigned int *desc_ctrl, void **priv_data);
-+void __hif_lib_update_credit(struct hif_client_s *client, unsigned int queue);
-+void hif_lib_set_rx_cpu_affinity(struct hif_client_s *client, int cpu_id);
-+void hif_lib_set_tx_queue_nocpy(struct hif_client_s *client, int qno, int
-+ enable);
-+static inline int hif_lib_tx_avail(struct hif_client_s *client, unsigned int
-+ qno)
-+{
-+ struct hif_client_tx_queue *queue = &client->tx_q[qno];
-+
-+ return (queue->size - queue->tx_pending);
-+}
-+
-+static inline int hif_lib_get_tx_wr_index(struct hif_client_s *client, unsigned
-+ int qno)
-+{
-+ struct hif_client_tx_queue *queue = &client->tx_q[qno];
-+
-+ return queue->write_idx;
-+}
-+
-+static inline int hif_lib_tx_pending(struct hif_client_s *client, unsigned int
-+ qno)
-+{
-+ struct hif_client_tx_queue *queue = &client->tx_q[qno];
-+
-+ return queue->tx_pending;
-+}
-+
-+#define hif_lib_tx_credit_avail(pfe, id, qno) \
-+ ((pfe)->tmu_credit.tx_credit[id][qno])
-+
-+#define hif_lib_tx_credit_max(pfe, id, qno) \
-+ ((pfe)->tmu_credit.tx_credit_max[id][qno])
-+
-+/*
-+ * Test comment
-+ */
-+#define hif_lib_tx_credit_use(pfe, id, qno, credit) \
-+ ({ typeof(pfe) pfe_ = pfe; \
-+ typeof(id) id_ = id; \
-+ typeof(qno) qno_ = qno; \
-+ typeof(credit) credit_ = credit; \
-+ do { \
-+ if (tx_qos) { \
-+ (pfe_)->tmu_credit.tx_credit[id_][qno_]\
-+ -= credit_; \
-+ (pfe_)->tmu_credit.tx_packets[id_][qno_]\
-+ += credit_; \
-+ } \
-+ } while (0); \
-+ })
-+
-+#endif /* _PFE_HIF_LIB_H_ */
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/pfe_hw.c
-@@ -0,0 +1,164 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ */
-+
-+#include "pfe_mod.h"
-+#include "pfe_hw.h"
-+
-+/* Functions to handle most of pfe hw register initialization */
-+int pfe_hw_init(struct pfe *pfe, int resume)
-+{
-+ struct class_cfg class_cfg = {
-+ .pe_sys_clk_ratio = PE_SYS_CLK_RATIO,
-+ .route_table_baseaddr = pfe->ddr_phys_baseaddr +
-+ ROUTE_TABLE_BASEADDR,
-+ .route_table_hash_bits = ROUTE_TABLE_HASH_BITS,
-+ };
-+
-+ struct tmu_cfg tmu_cfg = {
-+ .pe_sys_clk_ratio = PE_SYS_CLK_RATIO,
-+ .llm_base_addr = pfe->ddr_phys_baseaddr + TMU_LLM_BASEADDR,
-+ .llm_queue_len = TMU_LLM_QUEUE_LEN,
-+ };
-+
-+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
-+ struct util_cfg util_cfg = {
-+ .pe_sys_clk_ratio = PE_SYS_CLK_RATIO,
-+ };
-+#endif
-+
-+ struct BMU_CFG bmu1_cfg = {
-+ .baseaddr = CBUS_VIRT_TO_PFE(LMEM_BASE_ADDR +
-+ BMU1_LMEM_BASEADDR),
-+ .count = BMU1_BUF_COUNT,
-+ .size = BMU1_BUF_SIZE,
-+ .low_watermark = 10,
-+ .high_watermark = 15,
-+ };
-+
-+ struct BMU_CFG bmu2_cfg = {
-+ .baseaddr = DDR_PHYS_TO_PFE(pfe->ddr_phys_baseaddr +
-+ BMU2_DDR_BASEADDR),
-+ .count = BMU2_BUF_COUNT,
-+ .size = BMU2_BUF_SIZE,
-+ .low_watermark = 250,
-+ .high_watermark = 253,
-+ };
-+
-+ struct gpi_cfg egpi1_cfg = {
-+ .lmem_rtry_cnt = EGPI1_LMEM_RTRY_CNT,
-+ .tmlf_txthres = EGPI1_TMLF_TXTHRES,
-+ .aseq_len = EGPI1_ASEQ_LEN,
-+ .mtip_pause_reg = CBUS_VIRT_TO_PFE(EMAC1_BASE_ADDR +
-+ EMAC_TCNTRL_REG),
-+ };
-+
-+ struct gpi_cfg egpi2_cfg = {
-+ .lmem_rtry_cnt = EGPI2_LMEM_RTRY_CNT,
-+ .tmlf_txthres = EGPI2_TMLF_TXTHRES,
-+ .aseq_len = EGPI2_ASEQ_LEN,
-+ .mtip_pause_reg = CBUS_VIRT_TO_PFE(EMAC2_BASE_ADDR +
-+ EMAC_TCNTRL_REG),
-+ };
-+
-+ struct gpi_cfg hgpi_cfg = {
-+ .lmem_rtry_cnt = HGPI_LMEM_RTRY_CNT,
-+ .tmlf_txthres = HGPI_TMLF_TXTHRES,
-+ .aseq_len = HGPI_ASEQ_LEN,
-+ .mtip_pause_reg = 0,
-+ };
-+
-+ pr_info("%s\n", __func__);
-+
-+#if !defined(LS1012A_PFE_RESET_WA)
-+ /* LS1012A needs this to make PE work correctly */
-+ writel(0x3, CLASS_PE_SYS_CLK_RATIO);
-+ writel(0x3, TMU_PE_SYS_CLK_RATIO);
-+ writel(0x3, UTIL_PE_SYS_CLK_RATIO);
-+ usleep_range(10, 20);
-+#endif
-+
-+ pr_info("CLASS version: %x\n", readl(CLASS_VERSION));
-+ pr_info("TMU version: %x\n", readl(TMU_VERSION));
-+
-+ pr_info("BMU1 version: %x\n", readl(BMU1_BASE_ADDR +
-+ BMU_VERSION));
-+ pr_info("BMU2 version: %x\n", readl(BMU2_BASE_ADDR +
-+ BMU_VERSION));
-+
-+ pr_info("EGPI1 version: %x\n", readl(EGPI1_BASE_ADDR +
-+ GPI_VERSION));
-+ pr_info("EGPI2 version: %x\n", readl(EGPI2_BASE_ADDR +
-+ GPI_VERSION));
-+ pr_info("HGPI version: %x\n", readl(HGPI_BASE_ADDR +
-+ GPI_VERSION));
-+
-+ pr_info("HIF version: %x\n", readl(HIF_VERSION));
-+ pr_info("HIF NOPCY version: %x\n", readl(HIF_NOCPY_VERSION));
-+
-+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
-+ pr_info("UTIL version: %x\n", readl(UTIL_VERSION));
-+#endif
-+ while (!(readl(TMU_CTRL) & ECC_MEM_INIT_DONE))
-+ ;
-+
-+ hif_rx_disable();
-+ hif_tx_disable();
-+
-+ bmu_init(BMU1_BASE_ADDR, &bmu1_cfg);
-+
-+ pr_info("bmu_init(1) done\n");
-+
-+ bmu_init(BMU2_BASE_ADDR, &bmu2_cfg);
-+
-+ pr_info("bmu_init(2) done\n");
-+
-+ class_cfg.resume = resume ? 1 : 0;
-+
-+ class_init(&class_cfg);
-+
-+ pr_info("class_init() done\n");
-+
-+ tmu_init(&tmu_cfg);
-+
-+ pr_info("tmu_init() done\n");
-+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
-+ util_init(&util_cfg);
-+
-+ pr_info("util_init() done\n");
-+#endif
-+ gpi_init(EGPI1_BASE_ADDR, &egpi1_cfg);
-+
-+ pr_info("gpi_init(1) done\n");
-+
-+ gpi_init(EGPI2_BASE_ADDR, &egpi2_cfg);
-+
-+ pr_info("gpi_init(2) done\n");
-+
-+ gpi_init(HGPI_BASE_ADDR, &hgpi_cfg);
-+
-+ pr_info("gpi_init(hif) done\n");
-+
-+ bmu_enable(BMU1_BASE_ADDR);
-+
-+ pr_info("bmu_enable(1) done\n");
-+
-+ bmu_enable(BMU2_BASE_ADDR);
-+
-+ pr_info("bmu_enable(2) done\n");
-+
-+ return 0;
-+}
-+
-+void pfe_hw_exit(struct pfe *pfe)
-+{
-+ pr_info("%s\n", __func__);
-+
-+ bmu_disable(BMU1_BASE_ADDR);
-+ bmu_reset(BMU1_BASE_ADDR);
-+
-+ bmu_disable(BMU2_BASE_ADDR);
-+ bmu_reset(BMU2_BASE_ADDR);
-+}
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/pfe_hw.h
-@@ -0,0 +1,15 @@
-+/* SPDX-License-Identifier: GPL-2.0+ */
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ */
-+
-+#ifndef _PFE_HW_H_
-+#define _PFE_HW_H_
-+
-+#define PE_SYS_CLK_RATIO 1 /* SYS/AXI = 250MHz, HFE = 500MHz */
-+
-+int pfe_hw_init(struct pfe *pfe, int resume);
-+void pfe_hw_exit(struct pfe *pfe);
-+
-+#endif /* _PFE_HW_H_ */
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c
-@@ -0,0 +1,383 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/device.h>
-+#include <linux/of.h>
-+#include <linux/of_net.h>
-+#include <linux/of_address.h>
-+#include <linux/of_mdio.h>
-+#include <linux/platform_device.h>
-+#include <linux/slab.h>
-+#include <linux/clk.h>
-+#include <linux/mfd/syscon.h>
-+#include <linux/regmap.h>
-+
-+#include "pfe_mod.h"
-+
-+extern bool pfe_use_old_dts_phy;
-+struct ls1012a_pfe_platform_data pfe_platform_data;
-+
-+static int pfe_get_gemac_if_properties(struct device_node *gem,
-+ int port,
-+ struct ls1012a_pfe_platform_data *pdata)
-+{
-+ struct device_node *phy_node = NULL;
-+ int size;
-+ int phy_id = 0;
-+ const u32 *addr;
-+ int err;
-+
-+ addr = of_get_property(gem, "reg", &size);
-+ if (addr)
-+ port = be32_to_cpup(addr);
-+ else
-+ goto err;
-+
-+ pdata->ls1012a_eth_pdata[port].gem_id = port;
-+
-+ err = of_get_mac_address(gem, pdata->ls1012a_eth_pdata[port].mac_addr);
-+
-+ phy_node = of_parse_phandle(gem, "phy-handle", 0);
-+ pdata->ls1012a_eth_pdata[port].phy_node = phy_node;
-+ if (phy_node) {
-+ pfe_use_old_dts_phy = false;
-+ goto process_phynode;
-+ } else if (of_phy_is_fixed_link(gem)) {
-+ pfe_use_old_dts_phy = false;
-+ if (of_phy_register_fixed_link(gem) < 0) {
-+ pr_err("broken fixed-link specification\n");
-+ goto err;
-+ }
-+ phy_node = of_node_get(gem);
-+ pdata->ls1012a_eth_pdata[port].phy_node = phy_node;
-+ } else if (of_get_property(gem, "fsl,pfe-phy-if-flags", &size)) {
-+ pfe_use_old_dts_phy = true;
-+ /* Use old dts properties for phy handling */
-+ addr = of_get_property(gem, "fsl,pfe-phy-if-flags", &size);
-+ pdata->ls1012a_eth_pdata[port].phy_flags = be32_to_cpup(addr);
-+
-+ addr = of_get_property(gem, "fsl,gemac-phy-id", &size);
-+ if (!addr) {
-+ pr_err("%s:%d Invalid gemac-phy-id....\n", __func__,
-+ __LINE__);
-+ } else {
-+ phy_id = be32_to_cpup(addr);
-+ pdata->ls1012a_eth_pdata[port].phy_id = phy_id;
-+ pdata->ls1012a_mdio_pdata[0].phy_mask &= ~(1 << phy_id);
-+ }
-+
-+ /* If PHY is enabled, read mdio properties */
-+ if (pdata->ls1012a_eth_pdata[port].phy_flags & GEMAC_NO_PHY)
-+ goto done;
-+
-+ } else {
-+ pr_info("%s: No PHY or fixed-link\n", __func__);
-+ return 0;
-+ }
-+
-+process_phynode:
-+ err = of_get_phy_mode(gem, &pdata->ls1012a_eth_pdata[port].mii_config);
-+ if (err)
-+ pr_err("%s:%d Incorrect Phy mode....\n", __func__,
-+ __LINE__);
-+
-+ addr = of_get_property(gem, "fsl,mdio-mux-val", &size);
-+ if (!addr) {
-+ pr_err("%s: Invalid mdio-mux-val....\n", __func__);
-+ } else {
-+ phy_id = be32_to_cpup(addr);
-+ pdata->ls1012a_eth_pdata[port].mdio_muxval = phy_id;
-+ }
-+
-+ if (pdata->ls1012a_eth_pdata[port].phy_id < 32)
-+ pfe->mdio_muxval[pdata->ls1012a_eth_pdata[port].phy_id] =
-+ pdata->ls1012a_eth_pdata[port].mdio_muxval;
-+
-+
-+ pdata->ls1012a_mdio_pdata[port].irq[0] = PHY_POLL;
-+
-+done:
-+ return 0;
-+
-+err:
-+ return -1;
-+}
-+
-+/*
-+ *
-+ * pfe_platform_probe -
-+ *
-+ *
-+ */
-+static int pfe_platform_probe(struct platform_device *pdev)
-+{
-+ struct resource res;
-+ int ii = 0, rc, interface_count = 0, size = 0;
-+ const u32 *prop;
-+ struct device_node *np, *gem = NULL;
-+ struct clk *pfe_clk;
-+
-+ np = pdev->dev.of_node;
-+
-+ if (!np) {
-+ pr_err("Invalid device node\n");
-+ return -EINVAL;
-+ }
-+
-+ pfe = kzalloc(sizeof(*pfe), GFP_KERNEL);
-+ if (!pfe) {
-+ rc = -ENOMEM;
-+ goto err_alloc;
-+ }
-+
-+ platform_set_drvdata(pdev, pfe);
-+
-+ if (dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32))) {
-+ rc = -ENOMEM;
-+ pr_err("unable to configure DMA mask.\n");
-+ goto err_ddr;
-+ }
-+
-+ if (of_address_to_resource(np, 1, &res)) {
-+ rc = -ENOMEM;
-+ pr_err("failed to get ddr resource\n");
-+ goto err_ddr;
-+ }
-+
-+ pfe->ddr_phys_baseaddr = res.start;
-+ pfe->ddr_size = resource_size(&res);
-+
-+ pfe->ddr_baseaddr = memremap(res.start, resource_size(&res),
-+ MEMREMAP_WB);
-+ if (!pfe->ddr_baseaddr) {
-+ pr_err("memremap() ddr failed\n");
-+ rc = -ENOMEM;
-+ goto err_ddr;
-+ }
-+
-+ pfe->scfg =
-+ syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
-+ "fsl,pfe-scfg");
-+ if (IS_ERR(pfe->scfg)) {
-+ dev_err(&pdev->dev, "No syscfg phandle specified\n");
-+ return PTR_ERR(pfe->scfg);
-+ }
-+
-+ pfe->cbus_baseaddr = of_iomap(np, 0);
-+ if (!pfe->cbus_baseaddr) {
-+ rc = -ENOMEM;
-+ pr_err("failed to get axi resource\n");
-+ goto err_axi;
-+ }
-+
-+ pfe->hif_irq = platform_get_irq(pdev, 0);
-+ if (pfe->hif_irq < 0) {
-+ pr_err("platform_get_irq for hif failed\n");
-+ rc = pfe->hif_irq;
-+ goto err_hif_irq;
-+ }
-+
-+ pfe->wol_irq = platform_get_irq(pdev, 2);
-+ if (pfe->wol_irq < 0) {
-+ pr_err("platform_get_irq for WoL failed\n");
-+ rc = pfe->wol_irq;
-+ goto err_hif_irq;
-+ }
-+
-+ /* Read interface count */
-+ prop = of_get_property(np, "fsl,pfe-num-interfaces", &size);
-+ if (!prop) {
-+ pr_err("Failed to read number of interfaces\n");
-+ rc = -ENXIO;
-+ goto err_prop;
-+ }
-+
-+ interface_count = be32_to_cpup(prop);
-+ if (interface_count <= 0) {
-+ pr_err("No ethernet interface count : %d\n",
-+ interface_count);
-+ rc = -ENXIO;
-+ goto err_prop;
-+ }
-+
-+ pfe_platform_data.ls1012a_mdio_pdata[0].phy_mask = 0xffffffff;
-+
-+ while ((gem = of_get_next_child(np, gem))) {
-+ if (of_find_property(gem, "reg", &size)) {
-+ pfe_get_gemac_if_properties(gem, ii,
-+ &pfe_platform_data);
-+ ii++;
-+ }
-+ }
-+
-+ if (interface_count != ii)
-+ pr_info("missing some of gemac interface properties.\n");
-+
-+ pfe->dev = &pdev->dev;
-+
-+ pfe->dev->platform_data = &pfe_platform_data;
-+
-+ /* declare WoL capabilities */
-+ device_init_wakeup(&pdev->dev, true);
-+
-+ /* find the clocks */
-+ pfe_clk = devm_clk_get(pfe->dev, "pfe");
-+ if (IS_ERR(pfe_clk))
-+ return PTR_ERR(pfe_clk);
-+
-+ /* PFE clock is (platform clock / 2) */
-+ /* save sys_clk value as KHz */
-+ pfe->ctrl.sys_clk = clk_get_rate(pfe_clk) / (2 * 1000);
-+
-+ rc = pfe_probe(pfe);
-+ if (rc < 0)
-+ goto err_probe;
-+
-+ return 0;
-+
-+err_probe:
-+err_prop:
-+err_hif_irq:
-+ iounmap(pfe->cbus_baseaddr);
-+
-+err_axi:
-+ memunmap(pfe->ddr_baseaddr);
-+
-+err_ddr:
-+ platform_set_drvdata(pdev, NULL);
-+
-+ kfree(pfe);
-+
-+err_alloc:
-+ return rc;
-+}
-+
-+/*
-+ * pfe_platform_remove -
-+ */
-+static int pfe_platform_remove(struct platform_device *pdev)
-+{
-+ struct pfe *pfe = platform_get_drvdata(pdev);
-+ int rc;
-+
-+ pr_info("%s\n", __func__);
-+
-+ rc = pfe_remove(pfe);
-+
-+ iounmap(pfe->cbus_baseaddr);
-+
-+ memunmap(pfe->ddr_baseaddr);
-+
-+ platform_set_drvdata(pdev, NULL);
-+
-+ kfree(pfe);
-+
-+ return rc;
-+}
-+
-+#ifdef CONFIG_PM
-+#ifdef CONFIG_PM_SLEEP
-+int pfe_platform_suspend(struct device *dev)
-+{
-+ struct pfe *pfe = platform_get_drvdata(to_platform_device(dev));
-+ struct net_device *netdev;
-+ int i;
-+
-+ pfe->wake = 0;
-+
-+ for (i = 0; i < (NUM_GEMAC_SUPPORT); i++) {
-+ netdev = pfe->eth.eth_priv[i]->ndev;
-+
-+ netif_device_detach(netdev);
-+
-+ if (netif_running(netdev))
-+ if (pfe_eth_suspend(netdev))
-+ pfe->wake = 1;
-+ }
-+
-+ /* Shutdown PFE only if we're not waking up the system */
-+ if (!pfe->wake) {
-+#if defined(LS1012A_PFE_RESET_WA)
-+ pfe_hif_rx_idle(&pfe->hif);
-+#endif
-+ pfe_ctrl_suspend(&pfe->ctrl);
-+ pfe_firmware_exit(pfe);
-+
-+ pfe_hif_exit(pfe);
-+ pfe_hif_lib_exit(pfe);
-+
-+ pfe_hw_exit(pfe);
-+ }
-+
-+ return 0;
-+}
-+
-+static int pfe_platform_resume(struct device *dev)
-+{
-+ struct pfe *pfe = platform_get_drvdata(to_platform_device(dev));
-+ struct net_device *netdev;
-+ int i;
-+
-+ if (!pfe->wake) {
-+ pfe_hw_init(pfe, 1);
-+ pfe_hif_lib_init(pfe);
-+ pfe_hif_init(pfe);
-+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
-+ util_enable();
-+#endif
-+ tmu_enable(0xf);
-+ class_enable();
-+ pfe_ctrl_resume(&pfe->ctrl);
-+ }
-+
-+ for (i = 0; i < (NUM_GEMAC_SUPPORT); i++) {
-+ netdev = pfe->eth.eth_priv[i]->ndev;
-+
-+ if (pfe->mdio.mdio_priv[i]->mii_bus)
-+ pfe_eth_mdio_reset(pfe->mdio.mdio_priv[i]->mii_bus);
-+
-+ if (netif_running(netdev))
-+ pfe_eth_resume(netdev);
-+
-+ netif_device_attach(netdev);
-+ }
-+ return 0;
-+}
-+#else
-+#define pfe_platform_suspend NULL
-+#define pfe_platform_resume NULL
-+#endif
-+
-+static const struct dev_pm_ops pfe_platform_pm_ops = {
-+ SET_SYSTEM_SLEEP_PM_OPS(pfe_platform_suspend, pfe_platform_resume)
-+};
-+#endif
-+
-+static const struct of_device_id pfe_match[] = {
-+ {
-+ .compatible = "fsl,pfe",
-+ },
-+ {},
-+};
-+MODULE_DEVICE_TABLE(of, pfe_match);
-+
-+static struct platform_driver pfe_platform_driver = {
-+ .probe = pfe_platform_probe,
-+ .remove = pfe_platform_remove,
-+ .driver = {
-+ .name = "pfe",
-+ .of_match_table = pfe_match,
-+#ifdef CONFIG_PM
-+ .pm = &pfe_platform_pm_ops,
-+#endif
-+ },
-+};
-+
-+module_platform_driver(pfe_platform_driver);
-+MODULE_LICENSE("GPL");
-+MODULE_DESCRIPTION("PFE Ethernet driver");
-+MODULE_AUTHOR("NXP DNCPE");
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/pfe_mod.c
-@@ -0,0 +1,158 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ */
-+
-+#include <linux/dma-mapping.h>
-+#include "pfe_mod.h"
-+#include "pfe_cdev.h"
-+
-+unsigned int us;
-+module_param(us, uint, 0444);
-+MODULE_PARM_DESC(us, "0: module enabled for kernel networking (DEFAULT)\n"
-+ "1: module enabled for userspace networking\n");
-+struct pfe *pfe;
-+
-+/*
-+ * pfe_probe -
-+ */
-+int pfe_probe(struct pfe *pfe)
-+{
-+ int rc;
-+
-+ if (pfe->ddr_size < DDR_MAX_SIZE) {
-+ pr_err("%s: required DDR memory (%x) above platform ddr memory (%x)\n",
-+ __func__, (unsigned int)DDR_MAX_SIZE, pfe->ddr_size);
-+ rc = -ENOMEM;
-+ goto err_hw;
-+ }
-+
-+ if (((int)(pfe->ddr_phys_baseaddr + BMU2_DDR_BASEADDR) &
-+ (8 * SZ_1M - 1)) != 0) {
-+ pr_err("%s: BMU2 base address (0x%x) must be aligned on 8MB boundary\n",
-+ __func__, (int)pfe->ddr_phys_baseaddr +
-+ BMU2_DDR_BASEADDR);
-+ rc = -ENOMEM;
-+ goto err_hw;
-+ }
-+
-+ pr_info("cbus_baseaddr: %lx, ddr_baseaddr: %lx, ddr_phys_baseaddr: %lx, ddr_size: %x\n",
-+ (unsigned long)pfe->cbus_baseaddr,
-+ (unsigned long)pfe->ddr_baseaddr,
-+ pfe->ddr_phys_baseaddr, pfe->ddr_size);
-+
-+ pfe_lib_init(pfe->cbus_baseaddr, pfe->ddr_baseaddr,
-+ pfe->ddr_phys_baseaddr, pfe->ddr_size);
-+
-+ rc = pfe_hw_init(pfe, 0);
-+ if (rc < 0)
-+ goto err_hw;
-+
-+ if (us)
-+ goto firmware_init;
-+
-+ rc = pfe_hif_lib_init(pfe);
-+ if (rc < 0)
-+ goto err_hif_lib;
-+
-+ rc = pfe_hif_init(pfe);
-+ if (rc < 0)
-+ goto err_hif;
-+
-+firmware_init:
-+ rc = pfe_firmware_init(pfe);
-+ if (rc < 0)
-+ goto err_firmware;
-+
-+ rc = pfe_ctrl_init(pfe);
-+ if (rc < 0)
-+ goto err_ctrl;
-+
-+ rc = pfe_eth_init(pfe);
-+ if (rc < 0)
-+ goto err_eth;
-+
-+ rc = pfe_sysfs_init(pfe);
-+ if (rc < 0)
-+ goto err_sysfs;
-+
-+ rc = pfe_debugfs_init(pfe);
-+ if (rc < 0)
-+ goto err_debugfs;
-+
-+ if (us) {
-+ /* Creating a character device */
-+ rc = pfe_cdev_init();
-+ if (rc < 0)
-+ goto err_cdev;
-+ }
-+
-+ return 0;
-+
-+err_cdev:
-+ pfe_debugfs_exit(pfe);
-+
-+err_debugfs:
-+ pfe_sysfs_exit(pfe);
-+
-+err_sysfs:
-+ pfe_eth_exit(pfe);
-+
-+err_eth:
-+ pfe_ctrl_exit(pfe);
-+
-+err_ctrl:
-+ pfe_firmware_exit(pfe);
-+
-+err_firmware:
-+ if (us)
-+ goto err_hif_lib;
-+
-+ pfe_hif_exit(pfe);
-+
-+err_hif:
-+ pfe_hif_lib_exit(pfe);
-+
-+err_hif_lib:
-+ pfe_hw_exit(pfe);
-+
-+err_hw:
-+ return rc;
-+}
-+
-+/*
-+ * pfe_remove -
-+ */
-+int pfe_remove(struct pfe *pfe)
-+{
-+ pr_info("%s\n", __func__);
-+
-+ if (us)
-+ pfe_cdev_exit();
-+
-+ pfe_debugfs_exit(pfe);
-+
-+ pfe_sysfs_exit(pfe);
-+
-+ pfe_eth_exit(pfe);
-+
-+ pfe_ctrl_exit(pfe);
-+
-+#if defined(LS1012A_PFE_RESET_WA)
-+ pfe_hif_rx_idle(&pfe->hif);
-+#endif
-+ pfe_firmware_exit(pfe);
-+
-+ if (us)
-+ goto hw_exit;
-+
-+ pfe_hif_exit(pfe);
-+
-+ pfe_hif_lib_exit(pfe);
-+
-+hw_exit:
-+ pfe_hw_exit(pfe);
-+
-+ return 0;
-+}
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/pfe_mod.h
-@@ -0,0 +1,103 @@
-+/* SPDX-License-Identifier: GPL-2.0+ */
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ */
-+
-+#ifndef _PFE_MOD_H_
-+#define _PFE_MOD_H_
-+
-+#include <linux/device.h>
-+#include <linux/elf.h>
-+
-+extern unsigned int us;
-+
-+struct pfe;
-+
-+#include "pfe_hw.h"
-+#include "pfe_firmware.h"
-+#include "pfe_ctrl.h"
-+#include "pfe_hif.h"
-+#include "pfe_hif_lib.h"
-+#include "pfe_eth.h"
-+#include "pfe_sysfs.h"
-+#include "pfe_perfmon.h"
-+#include "pfe_debugfs.h"
-+
-+#define PHYID_MAX_VAL 32
-+
-+struct pfe_tmu_credit {
-+ /* Number of allowed TX packet in-flight, matches TMU queue size */
-+ unsigned int tx_credit[NUM_GEMAC_SUPPORT][EMAC_TXQ_CNT];
-+ unsigned int tx_credit_max[NUM_GEMAC_SUPPORT][EMAC_TXQ_CNT];
-+ unsigned int tx_packets[NUM_GEMAC_SUPPORT][EMAC_TXQ_CNT];
-+};
-+
-+struct pfe {
-+ struct regmap *scfg;
-+ unsigned long ddr_phys_baseaddr;
-+ void *ddr_baseaddr;
-+ unsigned int ddr_size;
-+ void *cbus_baseaddr;
-+ void *apb_baseaddr;
-+ unsigned long iram_phys_baseaddr;
-+ void *iram_baseaddr;
-+ unsigned long ipsec_phys_baseaddr;
-+ void *ipsec_baseaddr;
-+ int hif_irq;
-+ int wol_irq;
-+ int hif_client_irq;
-+ struct device *dev;
-+ struct dentry *dentry;
-+ struct pfe_ctrl ctrl;
-+ struct pfe_hif hif;
-+ struct pfe_eth eth;
-+ struct pfe_mdio mdio;
-+ struct hif_client_s *hif_client[HIF_CLIENTS_MAX];
-+#if defined(CFG_DIAGS)
-+ struct pfe_diags diags;
-+#endif
-+ struct pfe_tmu_credit tmu_credit;
-+ struct pfe_cpumon cpumon;
-+ struct pfe_memmon memmon;
-+ int wake;
-+ int mdio_muxval[PHYID_MAX_VAL];
-+ struct clk *hfe_clock;
-+};
-+
-+extern struct pfe *pfe;
-+
-+int pfe_probe(struct pfe *pfe);
-+int pfe_remove(struct pfe *pfe);
-+
-+/* DDR Mapping in reserved memory*/
-+#define ROUTE_TABLE_BASEADDR 0
-+#define ROUTE_TABLE_HASH_BITS 15 /* 32K entries */
-+#define ROUTE_TABLE_SIZE ((1 << ROUTE_TABLE_HASH_BITS) \
-+ * CLASS_ROUTE_SIZE)
-+#define BMU2_DDR_BASEADDR (ROUTE_TABLE_BASEADDR + ROUTE_TABLE_SIZE)
-+#define BMU2_BUF_COUNT (4096 - 256)
-+/* This is to get a total DDR size of 12MiB */
-+#define BMU2_DDR_SIZE (DDR_BUF_SIZE * BMU2_BUF_COUNT)
-+#define UTIL_CODE_BASEADDR (BMU2_DDR_BASEADDR + BMU2_DDR_SIZE)
-+#define UTIL_CODE_SIZE (128 * SZ_1K)
-+#define UTIL_DDR_DATA_BASEADDR (UTIL_CODE_BASEADDR + UTIL_CODE_SIZE)
-+#define UTIL_DDR_DATA_SIZE (64 * SZ_1K)
-+#define CLASS_DDR_DATA_BASEADDR (UTIL_DDR_DATA_BASEADDR + UTIL_DDR_DATA_SIZE)
-+#define CLASS_DDR_DATA_SIZE (32 * SZ_1K)
-+#define TMU_DDR_DATA_BASEADDR (CLASS_DDR_DATA_BASEADDR + CLASS_DDR_DATA_SIZE)
-+#define TMU_DDR_DATA_SIZE (32 * SZ_1K)
-+#define TMU_LLM_BASEADDR (TMU_DDR_DATA_BASEADDR + TMU_DDR_DATA_SIZE)
-+#define TMU_LLM_QUEUE_LEN (8 * 512)
-+/* Must be power of two and at least 16 * 8 = 128 bytes */
-+#define TMU_LLM_SIZE (4 * 16 * TMU_LLM_QUEUE_LEN)
-+/* (4 TMU's x 16 queues x queue_len) */
-+
-+#define DDR_MAX_SIZE (TMU_LLM_BASEADDR + TMU_LLM_SIZE)
-+
-+/* LMEM Mapping */
-+#define BMU1_LMEM_BASEADDR 0
-+#define BMU1_BUF_COUNT 256
-+#define BMU1_LMEM_SIZE (LMEM_BUF_SIZE * BMU1_BUF_COUNT)
-+
-+#endif /* _PFE_MOD_H */
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/pfe_perfmon.h
-@@ -0,0 +1,26 @@
-+/* SPDX-License-Identifier: GPL-2.0+ */
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ */
-+
-+#ifndef _PFE_PERFMON_H_
-+#define _PFE_PERFMON_H_
-+
-+#include "pfe/pfe.h"
-+
-+#define CT_CPUMON_INTERVAL (1 * TIMER_TICKS_PER_SEC)
-+
-+struct pfe_cpumon {
-+ u32 cpu_usage_pct[MAX_PE];
-+ u32 class_usage_pct;
-+};
-+
-+struct pfe_memmon {
-+ u32 kernel_memory_allocated;
-+};
-+
-+int pfe_perfmon_init(struct pfe *pfe);
-+void pfe_perfmon_exit(struct pfe *pfe);
-+
-+#endif /* _PFE_PERFMON_H_ */
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/pfe_sysfs.c
-@@ -0,0 +1,840 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/platform_device.h>
-+
-+#include "pfe_mod.h"
-+
-+#define PE_EXCEPTION_DUMP_ADDRESS 0x1fa8
-+#define NUM_QUEUES 16
-+
-+static char register_name[20][5] = {
-+ "EPC", "ECAS", "EID", "ED",
-+ "r0", "r1", "r2", "r3",
-+ "r4", "r5", "r6", "r7",
-+ "r8", "r9", "r10", "r11",
-+ "r12", "r13", "r14", "r15",
-+};
-+
-+static char exception_name[14][20] = {
-+ "Reset",
-+ "HardwareFailure",
-+ "NMI",
-+ "InstBreakpoint",
-+ "DataBreakpoint",
-+ "Unsupported",
-+ "PrivilegeViolation",
-+ "InstBusError",
-+ "DataBusError",
-+ "AlignmentError",
-+ "ArithmeticError",
-+ "SystemCall",
-+ "MemoryManagement",
-+ "Interrupt",
-+};
-+
-+static unsigned long class_do_clear;
-+static unsigned long tmu_do_clear;
-+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
-+static unsigned long util_do_clear;
-+#endif
-+
-+static ssize_t display_pe_status(char *buf, int id, u32 dmem_addr, unsigned long
-+ do_clear)
-+{
-+ ssize_t len = 0;
-+ u32 val;
-+ char statebuf[5];
-+ struct pfe_cpumon *cpumon = &pfe->cpumon;
-+ u32 debug_indicator;
-+ u32 debug[20];
-+
-+ if (id < CLASS0_ID || id >= MAX_PE)
-+ return len;
-+
-+ *(u32 *)statebuf = pe_dmem_read(id, dmem_addr, 4);
-+ dmem_addr += 4;
-+
-+ statebuf[4] = '\0';
-+ len += sprintf(buf + len, "state=%4s ", statebuf);
-+
-+ val = pe_dmem_read(id, dmem_addr, 4);
-+ dmem_addr += 4;
-+ len += sprintf(buf + len, "ctr=%08x ", cpu_to_be32(val));
-+
-+ val = pe_dmem_read(id, dmem_addr, 4);
-+ if (do_clear && val)
-+ pe_dmem_write(id, 0, dmem_addr, 4);
-+ dmem_addr += 4;
-+ len += sprintf(buf + len, "rx=%u ", cpu_to_be32(val));
-+
-+ val = pe_dmem_read(id, dmem_addr, 4);
-+ if (do_clear && val)
-+ pe_dmem_write(id, 0, dmem_addr, 4);
-+ dmem_addr += 4;
-+ if (id >= TMU0_ID && id <= TMU_MAX_ID)
-+ len += sprintf(buf + len, "qstatus=%x", cpu_to_be32(val));
-+ else
-+ len += sprintf(buf + len, "tx=%u", cpu_to_be32(val));
-+
-+ val = pe_dmem_read(id, dmem_addr, 4);
-+ if (do_clear && val)
-+ pe_dmem_write(id, 0, dmem_addr, 4);
-+ dmem_addr += 4;
-+ if (val)
-+ len += sprintf(buf + len, " drop=%u", cpu_to_be32(val));
-+
-+ len += sprintf(buf + len, " load=%d%%", cpumon->cpu_usage_pct[id]);
-+
-+ len += sprintf(buf + len, "\n");
-+
-+ debug_indicator = pe_dmem_read(id, dmem_addr, 4);
-+ dmem_addr += 4;
-+ if (!strncmp((char *)&debug_indicator, "DBUG", 4)) {
-+ int j, last = 0;
-+
-+ for (j = 0; j < 16; j++) {
-+ debug[j] = pe_dmem_read(id, dmem_addr, 4);
-+ if (debug[j]) {
-+ if (do_clear)
-+ pe_dmem_write(id, 0, dmem_addr, 4);
-+ last = j + 1;
-+ }
-+ dmem_addr += 4;
-+ }
-+ for (j = 0; j < last; j++) {
-+ len += sprintf(buf + len, "%08x%s",
-+ cpu_to_be32(debug[j]),
-+ (j & 0x7) == 0x7 || j == last - 1 ? "\n" : " ");
-+ }
-+ }
-+
-+ if (!strncmp(statebuf, "DEAD", 4)) {
-+ u32 i, dump = PE_EXCEPTION_DUMP_ADDRESS;
-+
-+ len += sprintf(buf + len, "Exception details:\n");
-+ for (i = 0; i < 20; i++) {
-+ debug[i] = pe_dmem_read(id, dump, 4);
-+ dump += 4;
-+ if (i == 2)
-+ len += sprintf(buf + len, "%4s = %08x (=%s) ",
-+ register_name[i], cpu_to_be32(debug[i]),
-+ exception_name[min((u32)
-+ cpu_to_be32(debug[i]), (u32)13)]);
-+ else
-+ len += sprintf(buf + len, "%4s = %08x%s",
-+ register_name[i], cpu_to_be32(debug[i]),
-+ (i & 0x3) == 0x3 || i == 19 ? "\n" : " ");
-+ }
-+ }
-+
-+ return len;
-+}
-+
-+static ssize_t class_phy_stats(char *buf, int phy)
-+{
-+ ssize_t len = 0;
-+ int off1 = phy * 0x28;
-+ int off2 = phy * 0x10;
-+
-+ if (phy == 3)
-+ off1 = CLASS_PHY4_RX_PKTS - CLASS_PHY1_RX_PKTS;
-+
-+ len += sprintf(buf + len, "phy: %d\n", phy);
-+ len += sprintf(buf + len,
-+ " rx: %10u, tx: %10u, intf: %10u, ipv4: %10u, ipv6: %10u\n",
-+ readl(CLASS_PHY1_RX_PKTS + off1),
-+ readl(CLASS_PHY1_TX_PKTS + off1),
-+ readl(CLASS_PHY1_INTF_MATCH_PKTS + off1),
-+ readl(CLASS_PHY1_V4_PKTS + off1),
-+ readl(CLASS_PHY1_V6_PKTS + off1));
-+
-+ len += sprintf(buf + len,
-+ " icmp: %10u, igmp: %10u, tcp: %10u, udp: %10u\n",
-+ readl(CLASS_PHY1_ICMP_PKTS + off2),
-+ readl(CLASS_PHY1_IGMP_PKTS + off2),
-+ readl(CLASS_PHY1_TCP_PKTS + off2),
-+ readl(CLASS_PHY1_UDP_PKTS + off2));
-+
-+ len += sprintf(buf + len, " err\n");
-+ len += sprintf(buf + len,
-+ " lp: %10u, intf: %10u, l3: %10u, chcksum: %10u, ttl: %10u\n",
-+ readl(CLASS_PHY1_LP_FAIL_PKTS + off1),
-+ readl(CLASS_PHY1_INTF_FAIL_PKTS + off1),
-+ readl(CLASS_PHY1_L3_FAIL_PKTS + off1),
-+ readl(CLASS_PHY1_CHKSUM_ERR_PKTS + off1),
-+ readl(CLASS_PHY1_TTL_ERR_PKTS + off1));
-+
-+ return len;
-+}
-+
-+/* qm_read_drop_stat
-+ * This function is used to read the drop statistics from the TMU
-+ * hw drop counter. Since the hw counter is always cleared afer
-+ * reading, this function maintains the previous drop count, and
-+ * adds the new value to it. That value can be retrieved by
-+ * passing a pointer to it with the total_drops arg.
-+ *
-+ * @param tmu TMU number (0 - 3)
-+ * @param queue queue number (0 - 15)
-+ * @param total_drops pointer to location to store total drops (or NULL)
-+ * @param do_reset if TRUE, clear total drops after updating
-+ */
-+u32 qm_read_drop_stat(u32 tmu, u32 queue, u32 *total_drops, int do_reset)
-+{
-+ static u32 qtotal[TMU_MAX_ID + 1][NUM_QUEUES];
-+ u32 val;
-+
-+ writel((tmu << 8) | queue, TMU_TEQ_CTRL);
-+ writel((tmu << 8) | queue, TMU_LLM_CTRL);
-+ val = readl(TMU_TEQ_DROP_STAT);
-+ qtotal[tmu][queue] += val;
-+ if (total_drops)
-+ *total_drops = qtotal[tmu][queue];
-+ if (do_reset)
-+ qtotal[tmu][queue] = 0;
-+ return val;
-+}
-+
-+static ssize_t tmu_queue_stats(char *buf, int tmu, int queue)
-+{
-+ ssize_t len = 0;
-+ u32 drops;
-+
-+ len += sprintf(buf + len, "%d-%02d, ", tmu, queue);
-+
-+ drops = qm_read_drop_stat(tmu, queue, NULL, 0);
-+
-+ /* Select queue */
-+ writel((tmu << 8) | queue, TMU_TEQ_CTRL);
-+ writel((tmu << 8) | queue, TMU_LLM_CTRL);
-+
-+ len += sprintf(buf + len,
-+ "(teq) drop: %10u, tx: %10u (llm) head: %08x, tail: %08x, drop: %10u\n",
-+ drops, readl(TMU_TEQ_TRANS_STAT),
-+ readl(TMU_LLM_QUE_HEADPTR), readl(TMU_LLM_QUE_TAILPTR),
-+ readl(TMU_LLM_QUE_DROPCNT));
-+
-+ return len;
-+}
-+
-+static ssize_t tmu_queues(char *buf, int tmu)
-+{
-+ ssize_t len = 0;
-+ int queue;
-+
-+ for (queue = 0; queue < 16; queue++)
-+ len += tmu_queue_stats(buf + len, tmu, queue);
-+
-+ return len;
-+}
-+
-+static ssize_t block_version(char *buf, void *addr)
-+{
-+ ssize_t len = 0;
-+ u32 val;
-+
-+ val = readl(addr);
-+ len += sprintf(buf + len, "revision: %x, version: %x, id: %x\n",
-+ (val >> 24) & 0xff, (val >> 16) & 0xff, val & 0xffff);
-+
-+ return len;
-+}
-+
-+static ssize_t bmu(char *buf, int id, void *base)
-+{
-+ ssize_t len = 0;
-+
-+ len += sprintf(buf + len, "%s: %d\n ", __func__, id);
-+
-+ len += block_version(buf + len, base + BMU_VERSION);
-+
-+ len += sprintf(buf + len, " buf size: %x\n", (1 << readl(base +
-+ BMU_BUF_SIZE)));
-+ len += sprintf(buf + len, " buf count: %x\n", readl(base +
-+ BMU_BUF_CNT));
-+ len += sprintf(buf + len, " buf rem: %x\n", readl(base +
-+ BMU_REM_BUF_CNT));
-+ len += sprintf(buf + len, " buf curr: %x\n", readl(base +
-+ BMU_CURR_BUF_CNT));
-+ len += sprintf(buf + len, " free err: %x\n", readl(base +
-+ BMU_FREE_ERR_ADDR));
-+
-+ return len;
-+}
-+
-+static ssize_t gpi(char *buf, int id, void *base)
-+{
-+ ssize_t len = 0;
-+ u32 val;
-+
-+ len += sprintf(buf + len, "%s%d:\n ", __func__, id);
-+ len += block_version(buf + len, base + GPI_VERSION);
-+
-+ len += sprintf(buf + len, " tx under stick: %x\n", readl(base +
-+ GPI_FIFO_STATUS));
-+ val = readl(base + GPI_FIFO_DEBUG);
-+ len += sprintf(buf + len, " tx pkts: %x\n", (val >> 23) &
-+ 0x3f);
-+ len += sprintf(buf + len, " rx pkts: %x\n", (val >> 18) &
-+ 0x3f);
-+ len += sprintf(buf + len, " tx bytes: %x\n", (val >> 9) &
-+ 0x1ff);
-+ len += sprintf(buf + len, " rx bytes: %x\n", (val >> 0) &
-+ 0x1ff);
-+ len += sprintf(buf + len, " overrun: %x\n", readl(base +
-+ GPI_OVERRUN_DROPCNT));
-+
-+ return len;
-+}
-+
-+static ssize_t pfe_set_class(struct device *dev, struct device_attribute *attr,
-+ const char *buf, size_t count)
-+{
-+ class_do_clear = kstrtoul(buf, 0, 0);
-+ return count;
-+}
-+
-+static ssize_t pfe_show_class(struct device *dev, struct device_attribute *attr,
-+ char *buf)
-+{
-+ ssize_t len = 0;
-+ int id;
-+ u32 val;
-+ struct pfe_cpumon *cpumon = &pfe->cpumon;
-+
-+ len += block_version(buf + len, CLASS_VERSION);
-+
-+ for (id = CLASS0_ID; id <= CLASS_MAX_ID; id++) {
-+ len += sprintf(buf + len, "%d: ", id - CLASS0_ID);
-+
-+ val = readl(CLASS_PE0_DEBUG + id * 4);
-+ len += sprintf(buf + len, "pc=1%04x ", val & 0xffff);
-+
-+ len += display_pe_status(buf + len, id, CLASS_DM_PESTATUS,
-+ class_do_clear);
-+ }
-+ len += sprintf(buf + len, "aggregate load=%d%%\n\n",
-+ cpumon->class_usage_pct);
-+
-+ len += sprintf(buf + len, "pe status: 0x%x\n",
-+ readl(CLASS_PE_STATUS));
-+ len += sprintf(buf + len, "max buf cnt: 0x%x afull thres: 0x%x\n",
-+ readl(CLASS_MAX_BUF_CNT), readl(CLASS_AFULL_THRES));
-+ len += sprintf(buf + len, "tsq max cnt: 0x%x tsq fifo thres: 0x%x\n",
-+ readl(CLASS_TSQ_MAX_CNT), readl(CLASS_TSQ_FIFO_THRES));
-+ len += sprintf(buf + len, "state: 0x%x\n", readl(CLASS_STATE));
-+
-+ len += class_phy_stats(buf + len, 0);
-+ len += class_phy_stats(buf + len, 1);
-+ len += class_phy_stats(buf + len, 2);
-+ len += class_phy_stats(buf + len, 3);
-+
-+ return len;
-+}
-+
-+static ssize_t pfe_set_tmu(struct device *dev, struct device_attribute *attr,
-+ const char *buf, size_t count)
-+{
-+ tmu_do_clear = kstrtoul(buf, 0, 0);
-+ return count;
-+}
-+
-+static ssize_t pfe_show_tmu(struct device *dev, struct device_attribute *attr,
-+ char *buf)
-+{
-+ ssize_t len = 0;
-+ int id;
-+ u32 val;
-+
-+ len += block_version(buf + len, TMU_VERSION);
-+
-+ for (id = TMU0_ID; id <= TMU_MAX_ID; id++) {
-+ if (id == TMU2_ID)
-+ continue;
-+ len += sprintf(buf + len, "%d: ", id - TMU0_ID);
-+
-+ len += display_pe_status(buf + len, id, TMU_DM_PESTATUS,
-+ tmu_do_clear);
-+ }
-+
-+ len += sprintf(buf + len, "pe status: %x\n", readl(TMU_PE_STATUS));
-+ len += sprintf(buf + len, "inq fifo cnt: %x\n",
-+ readl(TMU_PHY_INQ_FIFO_CNT));
-+ val = readl(TMU_INQ_STAT);
-+ len += sprintf(buf + len, "inq wr ptr: %x\n", val & 0x3ff);
-+ len += sprintf(buf + len, "inq rd ptr: %x\n", val >> 10);
-+
-+ return len;
-+}
-+
-+static unsigned long drops_do_clear;
-+static u32 class_drop_counter[CLASS_NUM_DROP_COUNTERS];
-+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
-+static u32 util_drop_counter[UTIL_NUM_DROP_COUNTERS];
-+#endif
-+
-+char *class_drop_description[CLASS_NUM_DROP_COUNTERS] = {
-+ "ICC",
-+ "Host Pkt Error",
-+ "Rx Error",
-+ "IPsec Outbound",
-+ "IPsec Inbound",
-+ "EXPT IPsec Error",
-+ "Reassembly",
-+ "Fragmenter",
-+ "NAT-T",
-+ "Socket",
-+ "Multicast",
-+ "NAT-PT",
-+ "Tx Disabled",
-+};
-+
-+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
-+char *util_drop_description[UTIL_NUM_DROP_COUNTERS] = {
-+ "IPsec Outbound",
-+ "IPsec Inbound",
-+ "IPsec Rate Limiter",
-+ "Fragmenter",
-+ "Socket",
-+ "Tx Disabled",
-+ "Rx Error",
-+};
-+#endif
-+
-+static ssize_t pfe_set_drops(struct device *dev, struct device_attribute *attr,
-+ const char *buf, size_t count)
-+{
-+ drops_do_clear = kstrtoul(buf, 0, 0);
-+ return count;
-+}
-+
-+static u32 tmu_drops[4][16];
-+static ssize_t pfe_show_drops(struct device *dev, struct device_attribute *attr,
-+ char *buf)
-+{
-+ ssize_t len = 0;
-+ int id, dropnum;
-+ int tmu, queue;
-+ u32 val;
-+ u32 dmem_addr;
-+ int num_class_drops = 0, num_tmu_drops = 0, num_util_drops = 0;
-+ struct pfe_ctrl *ctrl = &pfe->ctrl;
-+
-+ memset(class_drop_counter, 0, sizeof(class_drop_counter));
-+ for (id = CLASS0_ID; id <= CLASS_MAX_ID; id++) {
-+ if (drops_do_clear)
-+ pe_sync_stop(ctrl, (1 << id));
-+ for (dropnum = 0; dropnum < CLASS_NUM_DROP_COUNTERS;
-+ dropnum++) {
-+ dmem_addr = CLASS_DM_DROP_CNTR;
-+ val = be32_to_cpu(pe_dmem_read(id, dmem_addr, 4));
-+ class_drop_counter[dropnum] += val;
-+ num_class_drops += val;
-+ if (drops_do_clear)
-+ pe_dmem_write(id, 0, dmem_addr, 4);
-+ }
-+ if (drops_do_clear)
-+ pe_start(ctrl, (1 << id));
-+ }
-+
-+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
-+ if (drops_do_clear)
-+ pe_sync_stop(ctrl, (1 << UTIL_ID));
-+ for (dropnum = 0; dropnum < UTIL_NUM_DROP_COUNTERS; dropnum++) {
-+ dmem_addr = UTIL_DM_DROP_CNTR;
-+ val = be32_to_cpu(pe_dmem_read(UTIL_ID, dmem_addr, 4));
-+ util_drop_counter[dropnum] = val;
-+ num_util_drops += val;
-+ if (drops_do_clear)
-+ pe_dmem_write(UTIL_ID, 0, dmem_addr, 4);
-+ }
-+ if (drops_do_clear)
-+ pe_start(ctrl, (1 << UTIL_ID));
-+#endif
-+ for (tmu = 0; tmu < 4; tmu++) {
-+ for (queue = 0; queue < 16; queue++) {
-+ qm_read_drop_stat(tmu, queue, &tmu_drops[tmu][queue],
-+ drops_do_clear);
-+ num_tmu_drops += tmu_drops[tmu][queue];
-+ }
-+ }
-+
-+ if (num_class_drops == 0 && num_util_drops == 0 && num_tmu_drops == 0)
-+ len += sprintf(buf + len, "No PE drops\n\n");
-+
-+ if (num_class_drops > 0) {
-+ len += sprintf(buf + len, "Class PE drops --\n");
-+ for (dropnum = 0; dropnum < CLASS_NUM_DROP_COUNTERS;
-+ dropnum++) {
-+ if (class_drop_counter[dropnum] > 0)
-+ len += sprintf(buf + len, " %s: %d\n",
-+ class_drop_description[dropnum],
-+ class_drop_counter[dropnum]);
-+ }
-+ len += sprintf(buf + len, "\n");
-+ }
-+
-+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
-+ if (num_util_drops > 0) {
-+ len += sprintf(buf + len, "Util PE drops --\n");
-+ for (dropnum = 0; dropnum < UTIL_NUM_DROP_COUNTERS; dropnum++) {
-+ if (util_drop_counter[dropnum] > 0)
-+ len += sprintf(buf + len, " %s: %d\n",
-+ util_drop_description[dropnum],
-+ util_drop_counter[dropnum]);
-+ }
-+ len += sprintf(buf + len, "\n");
-+ }
-+#endif
-+ if (num_tmu_drops > 0) {
-+ len += sprintf(buf + len, "TMU drops --\n");
-+ for (tmu = 0; tmu < 4; tmu++) {
-+ for (queue = 0; queue < 16; queue++) {
-+ if (tmu_drops[tmu][queue] > 0)
-+ len += sprintf(buf + len,
-+ " TMU%d-Q%d: %d\n"
-+ , tmu, queue, tmu_drops[tmu][queue]);
-+ }
-+ }
-+ len += sprintf(buf + len, "\n");
-+ }
-+
-+ return len;
-+}
-+
-+static ssize_t pfe_show_tmu0_queues(struct device *dev, struct device_attribute
-+ *attr, char *buf)
-+{
-+ return tmu_queues(buf, 0);
-+}
-+
-+static ssize_t pfe_show_tmu1_queues(struct device *dev, struct device_attribute
-+ *attr, char *buf)
-+{
-+ return tmu_queues(buf, 1);
-+}
-+
-+static ssize_t pfe_show_tmu2_queues(struct device *dev, struct device_attribute
-+ *attr, char *buf)
-+{
-+ return tmu_queues(buf, 2);
-+}
-+
-+static ssize_t pfe_show_tmu3_queues(struct device *dev, struct device_attribute
-+ *attr, char *buf)
-+{
-+ return tmu_queues(buf, 3);
-+}
-+
-+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
-+static ssize_t pfe_set_util(struct device *dev, struct device_attribute *attr,
-+ const char *buf, size_t count)
-+{
-+ util_do_clear = kstrtoul(buf, NULL, 0);
-+ return count;
-+}
-+
-+static ssize_t pfe_show_util(struct device *dev, struct device_attribute *attr,
-+ char *buf)
-+{
-+ ssize_t len = 0;
-+ struct pfe_ctrl *ctrl = &pfe->ctrl;
-+
-+ len += block_version(buf + len, UTIL_VERSION);
-+
-+ pe_sync_stop(ctrl, (1 << UTIL_ID));
-+ len += display_pe_status(buf + len, UTIL_ID, UTIL_DM_PESTATUS,
-+ util_do_clear);
-+ pe_start(ctrl, (1 << UTIL_ID));
-+
-+ len += sprintf(buf + len, "pe status: %x\n", readl(UTIL_PE_STATUS));
-+ len += sprintf(buf + len, "max buf cnt: %x\n",
-+ readl(UTIL_MAX_BUF_CNT));
-+ len += sprintf(buf + len, "tsq max cnt: %x\n",
-+ readl(UTIL_TSQ_MAX_CNT));
-+
-+ return len;
-+}
-+#endif
-+
-+static ssize_t pfe_show_bmu(struct device *dev, struct device_attribute *attr,
-+ char *buf)
-+{
-+ ssize_t len = 0;
-+
-+ len += bmu(buf + len, 1, BMU1_BASE_ADDR);
-+ len += bmu(buf + len, 2, BMU2_BASE_ADDR);
-+
-+ return len;
-+}
-+
-+static ssize_t pfe_show_hif(struct device *dev, struct device_attribute *attr,
-+ char *buf)
-+{
-+ ssize_t len = 0;
-+
-+ len += sprintf(buf + len, "hif:\n ");
-+ len += block_version(buf + len, HIF_VERSION);
-+
-+ len += sprintf(buf + len, " tx curr bd: %x\n",
-+ readl(HIF_TX_CURR_BD_ADDR));
-+ len += sprintf(buf + len, " tx status: %x\n",
-+ readl(HIF_TX_STATUS));
-+ len += sprintf(buf + len, " tx dma status: %x\n",
-+ readl(HIF_TX_DMA_STATUS));
-+
-+ len += sprintf(buf + len, " rx curr bd: %x\n",
-+ readl(HIF_RX_CURR_BD_ADDR));
-+ len += sprintf(buf + len, " rx status: %x\n",
-+ readl(HIF_RX_STATUS));
-+ len += sprintf(buf + len, " rx dma status: %x\n",
-+ readl(HIF_RX_DMA_STATUS));
-+
-+ len += sprintf(buf + len, "hif nocopy:\n ");
-+ len += block_version(buf + len, HIF_NOCPY_VERSION);
-+
-+ len += sprintf(buf + len, " tx curr bd: %x\n",
-+ readl(HIF_NOCPY_TX_CURR_BD_ADDR));
-+ len += sprintf(buf + len, " tx status: %x\n",
-+ readl(HIF_NOCPY_TX_STATUS));
-+ len += sprintf(buf + len, " tx dma status: %x\n",
-+ readl(HIF_NOCPY_TX_DMA_STATUS));
-+
-+ len += sprintf(buf + len, " rx curr bd: %x\n",
-+ readl(HIF_NOCPY_RX_CURR_BD_ADDR));
-+ len += sprintf(buf + len, " rx status: %x\n",
-+ readl(HIF_NOCPY_RX_STATUS));
-+ len += sprintf(buf + len, " rx dma status: %x\n",
-+ readl(HIF_NOCPY_RX_DMA_STATUS));
-+
-+ return len;
-+}
-+
-+static ssize_t pfe_show_gpi(struct device *dev, struct device_attribute *attr,
-+ char *buf)
-+{
-+ ssize_t len = 0;
-+
-+ len += gpi(buf + len, 0, EGPI1_BASE_ADDR);
-+ len += gpi(buf + len, 1, EGPI2_BASE_ADDR);
-+ len += gpi(buf + len, 3, HGPI_BASE_ADDR);
-+
-+ return len;
-+}
-+
-+static ssize_t pfe_show_pfemem(struct device *dev, struct device_attribute
-+ *attr, char *buf)
-+{
-+ ssize_t len = 0;
-+ struct pfe_memmon *memmon = &pfe->memmon;
-+
-+ len += sprintf(buf + len, "Kernel Memory: %d Bytes (%d KB)\n",
-+ memmon->kernel_memory_allocated,
-+ (memmon->kernel_memory_allocated + 1023) / 1024);
-+
-+ return len;
-+}
-+
-+static ssize_t pfe_show_crc_revalidated(struct device *dev,
-+ struct device_attribute *attr,
-+ char *buf)
-+{
-+ u64 crc_validated = 0;
-+ ssize_t len = 0;
-+ int id, phyid;
-+
-+ len += sprintf(buf + len, "FCS re-validated by PFE:\n");
-+
-+ for (phyid = 0; phyid < 2; phyid++) {
-+ crc_validated = 0;
-+ for (id = CLASS0_ID; id <= CLASS_MAX_ID; id++) {
-+ crc_validated += be32_to_cpu(pe_dmem_read(id,
-+ CLASS_DM_CRC_VALIDATED + (phyid * 4), 4));
-+ }
-+ len += sprintf(buf + len, "MAC %d:\n count:%10llu\n",
-+ phyid, crc_validated);
-+ }
-+
-+ return len;
-+}
-+
-+#ifdef HIF_NAPI_STATS
-+static ssize_t pfe_show_hif_napi_stats(struct device *dev,
-+ struct device_attribute *attr,
-+ char *buf)
-+{
-+ struct platform_device *pdev = to_platform_device(dev);
-+ struct pfe *pfe = platform_get_drvdata(pdev);
-+ ssize_t len = 0;
-+
-+ len += sprintf(buf + len, "sched: %u\n",
-+ pfe->hif.napi_counters[NAPI_SCHED_COUNT]);
-+ len += sprintf(buf + len, "poll: %u\n",
-+ pfe->hif.napi_counters[NAPI_POLL_COUNT]);
-+ len += sprintf(buf + len, "packet: %u\n",
-+ pfe->hif.napi_counters[NAPI_PACKET_COUNT]);
-+ len += sprintf(buf + len, "budget: %u\n",
-+ pfe->hif.napi_counters[NAPI_FULL_BUDGET_COUNT]);
-+ len += sprintf(buf + len, "desc: %u\n",
-+ pfe->hif.napi_counters[NAPI_DESC_COUNT]);
-+ len += sprintf(buf + len, "full: %u\n",
-+ pfe->hif.napi_counters[NAPI_CLIENT_FULL_COUNT]);
-+
-+ return len;
-+}
-+
-+static ssize_t pfe_set_hif_napi_stats(struct device *dev,
-+ struct device_attribute *attr,
-+ const char *buf, size_t count)
-+{
-+ struct platform_device *pdev = to_platform_device(dev);
-+ struct pfe *pfe = platform_get_drvdata(pdev);
-+
-+ memset(pfe->hif.napi_counters, 0, sizeof(pfe->hif.napi_counters));
-+
-+ return count;
-+}
-+
-+static DEVICE_ATTR(hif_napi_stats, 0644, pfe_show_hif_napi_stats,
-+ pfe_set_hif_napi_stats);
-+#endif
-+
-+static DEVICE_ATTR(class, 0644, pfe_show_class, pfe_set_class);
-+static DEVICE_ATTR(tmu, 0644, pfe_show_tmu, pfe_set_tmu);
-+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
-+static DEVICE_ATTR(util, 0644, pfe_show_util, pfe_set_util);
-+#endif
-+static DEVICE_ATTR(bmu, 0444, pfe_show_bmu, NULL);
-+static DEVICE_ATTR(hif, 0444, pfe_show_hif, NULL);
-+static DEVICE_ATTR(gpi, 0444, pfe_show_gpi, NULL);
-+static DEVICE_ATTR(drops, 0644, pfe_show_drops, pfe_set_drops);
-+static DEVICE_ATTR(tmu0_queues, 0444, pfe_show_tmu0_queues, NULL);
-+static DEVICE_ATTR(tmu1_queues, 0444, pfe_show_tmu1_queues, NULL);
-+static DEVICE_ATTR(tmu2_queues, 0444, pfe_show_tmu2_queues, NULL);
-+static DEVICE_ATTR(tmu3_queues, 0444, pfe_show_tmu3_queues, NULL);
-+static DEVICE_ATTR(pfemem, 0444, pfe_show_pfemem, NULL);
-+static DEVICE_ATTR(fcs_revalidated, 0444, pfe_show_crc_revalidated, NULL);
-+
-+int pfe_sysfs_init(struct pfe *pfe)
-+{
-+ if (device_create_file(pfe->dev, &dev_attr_class))
-+ goto err_class;
-+
-+ if (device_create_file(pfe->dev, &dev_attr_tmu))
-+ goto err_tmu;
-+
-+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
-+ if (device_create_file(pfe->dev, &dev_attr_util))
-+ goto err_util;
-+#endif
-+
-+ if (device_create_file(pfe->dev, &dev_attr_bmu))
-+ goto err_bmu;
-+
-+ if (device_create_file(pfe->dev, &dev_attr_hif))
-+ goto err_hif;
-+
-+ if (device_create_file(pfe->dev, &dev_attr_gpi))
-+ goto err_gpi;
-+
-+ if (device_create_file(pfe->dev, &dev_attr_drops))
-+ goto err_drops;
-+
-+ if (device_create_file(pfe->dev, &dev_attr_tmu0_queues))
-+ goto err_tmu0_queues;
-+
-+ if (device_create_file(pfe->dev, &dev_attr_tmu1_queues))
-+ goto err_tmu1_queues;
-+
-+ if (device_create_file(pfe->dev, &dev_attr_tmu2_queues))
-+ goto err_tmu2_queues;
-+
-+ if (device_create_file(pfe->dev, &dev_attr_tmu3_queues))
-+ goto err_tmu3_queues;
-+
-+ if (device_create_file(pfe->dev, &dev_attr_pfemem))
-+ goto err_pfemem;
-+
-+ if (device_create_file(pfe->dev, &dev_attr_fcs_revalidated))
-+ goto err_crc_revalidated;
-+
-+#ifdef HIF_NAPI_STATS
-+ if (device_create_file(pfe->dev, &dev_attr_hif_napi_stats))
-+ goto err_hif_napi_stats;
-+#endif
-+
-+ return 0;
-+
-+#ifdef HIF_NAPI_STATS
-+err_hif_napi_stats:
-+ device_remove_file(pfe->dev, &dev_attr_fcs_revalidated);
-+#endif
-+
-+err_crc_revalidated:
-+ device_remove_file(pfe->dev, &dev_attr_pfemem);
-+
-+err_pfemem:
-+ device_remove_file(pfe->dev, &dev_attr_tmu3_queues);
-+
-+err_tmu3_queues:
-+ device_remove_file(pfe->dev, &dev_attr_tmu2_queues);
-+
-+err_tmu2_queues:
-+ device_remove_file(pfe->dev, &dev_attr_tmu1_queues);
-+
-+err_tmu1_queues:
-+ device_remove_file(pfe->dev, &dev_attr_tmu0_queues);
-+
-+err_tmu0_queues:
-+ device_remove_file(pfe->dev, &dev_attr_drops);
-+
-+err_drops:
-+ device_remove_file(pfe->dev, &dev_attr_gpi);
-+
-+err_gpi:
-+ device_remove_file(pfe->dev, &dev_attr_hif);
-+
-+err_hif:
-+ device_remove_file(pfe->dev, &dev_attr_bmu);
-+
-+err_bmu:
-+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
-+ device_remove_file(pfe->dev, &dev_attr_util);
-+
-+err_util:
-+#endif
-+ device_remove_file(pfe->dev, &dev_attr_tmu);
-+
-+err_tmu:
-+ device_remove_file(pfe->dev, &dev_attr_class);
-+
-+err_class:
-+ return -1;
-+}
-+
-+void pfe_sysfs_exit(struct pfe *pfe)
-+{
-+#ifdef HIF_NAPI_STATS
-+ device_remove_file(pfe->dev, &dev_attr_hif_napi_stats);
-+#endif
-+ device_remove_file(pfe->dev, &dev_attr_fcs_revalidated);
-+ device_remove_file(pfe->dev, &dev_attr_pfemem);
-+ device_remove_file(pfe->dev, &dev_attr_tmu3_queues);
-+ device_remove_file(pfe->dev, &dev_attr_tmu2_queues);
-+ device_remove_file(pfe->dev, &dev_attr_tmu1_queues);
-+ device_remove_file(pfe->dev, &dev_attr_tmu0_queues);
-+ device_remove_file(pfe->dev, &dev_attr_drops);
-+ device_remove_file(pfe->dev, &dev_attr_gpi);
-+ device_remove_file(pfe->dev, &dev_attr_hif);
-+ device_remove_file(pfe->dev, &dev_attr_bmu);
-+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
-+ device_remove_file(pfe->dev, &dev_attr_util);
-+#endif
-+ device_remove_file(pfe->dev, &dev_attr_tmu);
-+ device_remove_file(pfe->dev, &dev_attr_class);
-+}
---- /dev/null
-+++ b/drivers/staging/fsl_ppfe/pfe_sysfs.h
-@@ -0,0 +1,17 @@
-+/* SPDX-License-Identifier: GPL-2.0+ */
-+/*
-+ * Copyright 2015-2016 Freescale Semiconductor, Inc.
-+ * Copyright 2017 NXP
-+ */
-+
-+#ifndef _PFE_SYSFS_H_
-+#define _PFE_SYSFS_H_
-+
-+#include <linux/proc_fs.h>
-+
-+u32 qm_read_drop_stat(u32 tmu, u32 queue, u32 *total_drops, int do_reset);
-+
-+int pfe_sysfs_init(struct pfe *pfe);
-+void pfe_sysfs_exit(struct pfe *pfe);
-+
-+#endif /* _PFE_SYSFS_H_ */
diff --git a/target/linux/layerscape/patches-6.1/702-phy-Add-2.5G-SGMII-interface-mode.patch b/target/linux/layerscape/patches-6.1/702-phy-Add-2.5G-SGMII-interface-mode.patch
deleted file mode 100644
index c125d293d7..0000000000
--- a/target/linux/layerscape/patches-6.1/702-phy-Add-2.5G-SGMII-interface-mode.patch
+++ /dev/null
@@ -1,54 +0,0 @@
-From fd32b1bc9a49919d3d59a50d775d03fe7ca5e654 Mon Sep 17 00:00:00 2001
-From: Bhaskar Upadhaya <Bhaskar.Upadhaya@nxp.com>
-Date: Wed, 29 Nov 2017 15:27:57 +0530
-Subject: [PATCH] phy: Add 2.5G SGMII interface mode
-
-Add 2.5G SGMII interface mode(PHY_INTERFACE_MODE_2500SGMII)
-in existing phy_interface list
-
-Signed-off-by: Bhaskar Upadhaya <Bhaskar.Upadhaya@nxp.com>
----
- drivers/net/phy/phy-core.c | 1 +
- drivers/net/phy/phylink.c | 1 +
- include/linux/phy.h | 3 +++
- 3 files changed, 5 insertions(+)
-
---- a/drivers/net/phy/phy-core.c
-+++ b/drivers/net/phy/phy-core.c
-@@ -136,6 +136,7 @@ int phy_interface_num_ports(phy_interfac
- case PHY_INTERFACE_MODE_RXAUI:
- case PHY_INTERFACE_MODE_XAUI:
- case PHY_INTERFACE_MODE_1000BASEKX:
-+ case PHY_INTERFACE_MODE_2500SGMII:
- return 1;
- case PHY_INTERFACE_MODE_QSGMII:
- case PHY_INTERFACE_MODE_QUSGMII:
---- a/drivers/net/phy/phylink.c
-+++ b/drivers/net/phy/phylink.c
-@@ -231,6 +231,7 @@ static int phylink_interface_max_speed(p
- return SPEED_1000;
-
- case PHY_INTERFACE_MODE_2500BASEX:
-+ case PHY_INTERFACE_MODE_2500SGMII:
- return SPEED_2500;
-
- case PHY_INTERFACE_MODE_5GBASER:
---- a/include/linux/phy.h
-+++ b/include/linux/phy.h
-@@ -159,6 +159,7 @@ typedef enum {
- PHY_INTERFACE_MODE_10GKR,
- PHY_INTERFACE_MODE_QUSGMII,
- PHY_INTERFACE_MODE_1000BASEKX,
-+ PHY_INTERFACE_MODE_2500SGMII,
- PHY_INTERFACE_MODE_MAX,
- } phy_interface_t;
-
-@@ -280,6 +281,8 @@ static inline const char *phy_modes(phy_
- return "100base-x";
- case PHY_INTERFACE_MODE_QUSGMII:
- return "qusgmii";
-+ case PHY_INTERFACE_MODE_2500SGMII:
-+ return "sgmii-2500";
- default:
- return "unknown";
- }
diff --git a/target/linux/layerscape/patches-6.1/703-layerscape-6.1-fix-compilation-warning-for-fsl-ppfe-.patch b/target/linux/layerscape/patches-6.1/703-layerscape-6.1-fix-compilation-warning-for-fsl-ppfe-.patch
deleted file mode 100644
index d49488ab4c..0000000000
--- a/target/linux/layerscape/patches-6.1/703-layerscape-6.1-fix-compilation-warning-for-fsl-ppfe-.patch
+++ /dev/null
@@ -1,239 +0,0 @@
-From 1dc3a2e216d99adc2df022ab37eab32f61d80e0e Mon Sep 17 00:00:00 2001
-From: Christian Marangi <ansuelsmth@gmail.com>
-Date: Mon, 8 May 2023 19:26:48 +0200
-Subject: [PATCH] layerscape: 6.1: fix compilation warning for fsl ppfe driver
-
-Rework some desc dump and dummy pkt function to fix compilation warning.
-Fix compilation warning:
-drivers/staging/fsl_ppfe/pfe_hif.c: In function 'send_dummy_pkt_to_hif':
-drivers/staging/fsl_ppfe/pfe_hif.c:118:19: error: cast to pointer from integer of different size [-Werror=int-to-pointer-cast]
- 118 | ddr_ptr = (void *)((u64)readl(BMU2_BASE_ADDR + BMU_ALLOC_CTRL));
- | ^
-drivers/staging/fsl_ppfe/pfe_hif.c:122:20: error: cast to pointer from integer of different size [-Werror=int-to-pointer-cast]
- 122 | lmem_ptr = (void *)((u64)readl(BMU1_BASE_ADDR + BMU_ALLOC_CTRL));
- | ^
-drivers/staging/fsl_ppfe/pfe_hif.c: In function 'pfe_hif_desc_dump':
-drivers/staging/fsl_ppfe/pfe_hif.c:195:24: error: cast from pointer to integer of different size [-Werror=pointer-to-int-cast]
- 195 | desc_p = (u32)((u64)desc - (u64)hif->descr_baseaddr_v +
- | ^
-drivers/staging/fsl_ppfe/pfe_hif.c:195:36: error: cast from pointer to integer of different size [-Werror=pointer-to-int-cast]
- 195 | desc_p = (u32)((u64)desc - (u64)hif->descr_baseaddr_v +
- | ^
-drivers/staging/fsl_ppfe/pfe_hif.c:207:19: error: cast from pointer to integer of different size [-Werror=pointer-to-int-cast]
- 207 | desc_p = ((u64)desc - (u64)hif->descr_baseaddr_v +
- | ^
-drivers/staging/fsl_ppfe/pfe_hif.c:207:31: error: cast from pointer to integer of different size [-Werror=pointer-to-int-cast]
- 207 | desc_p = ((u64)desc - (u64)hif->descr_baseaddr_v +
- | ^
-cc1: all warnings being treated as errors
-
-In file included from ./include/linux/kernel.h:19,
- from ./include/linux/list.h:9,
- from ./include/linux/wait.h:7,
- from ./include/linux/eventfd.h:13,
- from drivers/staging/fsl_ppfe/pfe_cdev.c:11:
-drivers/staging/fsl_ppfe/pfe_cdev.c: In function 'pfe_cdev_read':
-./include/linux/kern_levels.h:5:25: error: format '%lu' expects argument of type 'long unsigned int', but argument 3 has type 'int' [-Werror=format=]
- 5 | #define KERN_SOH "\001" /* ASCII Start Of Header */
- | ^~~~~~
-./include/linux/printk.h:422:25: note: in definition of macro 'printk_index_wrap'
- 422 | _p_func(_fmt, ##__VA_ARGS__); \
- | ^~~~
-./include/linux/printk.h:132:17: note: in expansion of macro 'printk'
- 132 | printk(fmt, ##__VA_ARGS__); \
- | ^~~~~~
-./include/linux/printk.h:580:9: note: in expansion of macro 'no_printk'
- 580 | no_printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
- | ^~~~~~~~~
-./include/linux/kern_levels.h:15:25: note: in expansion of macro 'KERN_SOH'
- 15 | #define KERN_DEBUG KERN_SOH "7" /* debug-level messages */
- | ^~~~~~~~
-./include/linux/printk.h:580:19: note: in expansion of macro 'KERN_DEBUG'
- 580 | no_printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
- | ^~~~~~~~~~
-drivers/staging/fsl_ppfe/pfe_cdev.c:42:17: note: in expansion of macro 'pr_debug'
- 42 | pr_debug("%u %lu", link_states[ret].phy_id,
- | ^~~~~~~~
-./include/linux/kern_levels.h:5:25: error: format '%lu' expects argument of type 'long unsigned int', but argument 3 has type 'size_t' {aka 'unsigned int'} [-Werror=format=]
- 5 | #define KERN_SOH "\001" /* ASCII Start Of Header */
- | ^~~~~~
-./include/linux/printk.h:422:25: note: in definition of macro 'printk_index_wrap'
- 422 | _p_func(_fmt, ##__VA_ARGS__); \
- | ^~~~
-./include/linux/printk.h:493:9: note: in expansion of macro 'printk'
- 493 | printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__)
- | ^~~~~~
-./include/linux/kern_levels.h:11:25: note: in expansion of macro 'KERN_SOH'
- 11 | #define KERN_ERR KERN_SOH "3" /* error conditions */
- | ^~~~~~~~
-./include/linux/printk.h:493:16: note: in expansion of macro 'KERN_ERR'
- 493 | printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__)
- | ^~~~~~~~
-drivers/staging/fsl_ppfe/pfe_cdev.c:50:17: note: in expansion of macro 'pr_err'
- 50 | pr_err("Failed to send (%d)bytes of (%lu) requested.\n",
- | ^~~~~~
-./include/linux/kern_levels.h:5:25: error: format '%lu' expects argument of type 'long unsigned int', but argument 2 has type 'unsigned int' [-Werror=format=]
- 5 | #define KERN_SOH "\001" /* ASCII Start Of Header */
- | ^~~~~~
-./include/linux/printk.h:422:25: note: in definition of macro 'printk_index_wrap'
- 422 | _p_func(_fmt, ##__VA_ARGS__); \
- | ^~~~
-./include/linux/printk.h:132:17: note: in expansion of macro 'printk'
- 132 | printk(fmt, ##__VA_ARGS__); \
- | ^~~~~~
-./include/linux/printk.h:580:9: note: in expansion of macro 'no_printk'
- 580 | no_printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
- | ^~~~~~~~~
-./include/linux/kern_levels.h:15:25: note: in expansion of macro 'KERN_SOH'
- 15 | #define KERN_DEBUG KERN_SOH "7" /* debug-level messages */
- | ^~~~~~~~
-./include/linux/printk.h:580:19: note: in expansion of macro 'KERN_DEBUG'
- 580 | no_printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
- | ^~~~~~~~~~
-drivers/staging/fsl_ppfe/pfe_cdev.c:57:9: note: in expansion of macro 'pr_debug'
- 57 | pr_debug("Read of (%lu) bytes performed.\n", sizeof(link_states));
- | ^~~~~~~~
-cc1: all warnings being treated as errors
-
-In file included from ./include/uapi/linux/posix_types.h:5,
- from ./include/uapi/linux/types.h:14,
- from ./include/linux/types.h:6,
- from ./include/linux/list.h:5,
- from ./include/linux/module.h:12,
- from drivers/staging/fsl_ppfe/pfe_sysfs.c:7:
-drivers/staging/fsl_ppfe/pfe_sysfs.c: In function 'pfe_set_util':
-./include/linux/stddef.h:8:14: error: passing argument 2 of 'kstrtoul' makes integer from pointer without a cast [-Werror=int-conversion]
- 8 | #define NULL ((void *)0)
- | ^~~~~~~~~~~
- | |
- | void *
-drivers/staging/fsl_ppfe/pfe_sysfs.c:538:39: note: in expansion of macro 'NULL'
- 538 | util_do_clear = kstrtoul(buf, NULL, 0);
- | ^~~~
-In file included from ./include/linux/kernel.h:13,
- from ./include/linux/list.h:9:
-./include/linux/kstrtox.h:30:69: note: expected 'unsigned int' but argument is of type 'void *'
- 30 | static inline int __must_check kstrtoul(const char *s, unsigned int base, unsigned long *res)
- | ~~~~~~~~~~~~~^~~~
-cc1: all warnings being treated as errors
-
-With UTIL compiled on, fix compilation warning:
-drivers/staging/fsl_ppfe/pfe_hal.c: In function 'pe_load_ddr_section':
-drivers/staging/fsl_ppfe/pfe_hal.c:617:19: error: 'else' without a previous 'if'
- 617 | } else {
- | ^~~~
-drivers/staging/fsl_ppfe/pfe_hal.c:622:17: error: break statement not within loop or switch
- 622 | break;
- | ^~~~~
-drivers/staging/fsl_ppfe/pfe_hal.c:624:9: error: case label not within a switch statement
- 624 | case SHT_NOBITS:
- | ^~~~
-drivers/staging/fsl_ppfe/pfe_hal.c:627:17: error: break statement not within loop or switch
- 627 | break;
- | ^~~~~
-drivers/staging/fsl_ppfe/pfe_hal.c:629:9: error: 'default' label not within a switch statement
- 629 | default:
- | ^~~~~~~
-drivers/staging/fsl_ppfe/pfe_hal.c: At top level:
-drivers/staging/fsl_ppfe/pfe_hal.c:635:9: error: expected identifier or '(' before 'return'
- 635 | return 0;
- | ^~~~~~
-drivers/staging/fsl_ppfe/pfe_hal.c:636:1: error: expected identifier or '(' before '}' token
- 636 | }
-
-Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
-Signed-off-by: Pawel Dembicki <paweldembicki@gmail.com>
----
- drivers/staging/fsl_ppfe/pfe_cdev.c | 6 +++---
- drivers/staging/fsl_ppfe/pfe_hif.c | 14 +++++++-------
- drivers/staging/fsl_ppfe/pfe_sysfs.c | 2 +-
- 3 files changed, 11 insertions(+), 11 deletions(-)
-
---- a/drivers/staging/fsl_ppfe/pfe_cdev.c
-+++ b/drivers/staging/fsl_ppfe/pfe_cdev.c
-@@ -34,7 +34,7 @@ static ssize_t pfe_cdev_read(struct file
- {
- int ret = 0;
-
-- pr_info("PFE CDEV attempt copying (%lu) size of user.\n",
-+ pr_info("PFE CDEV attempt copying (%zu) size of user.\n",
- sizeof(link_states));
-
- pr_debug("Dump link_state on screen before copy_to_user\n");
-@@ -47,14 +47,14 @@ static ssize_t pfe_cdev_read(struct file
- /* Copy to user the value in buffer sized len */
- ret = copy_to_user(buf, &link_states, sizeof(link_states));
- if (ret != 0) {
-- pr_err("Failed to send (%d)bytes of (%lu) requested.\n",
-+ pr_err("Failed to send (%d)bytes of (%zu) requested.\n",
- ret, len);
- return -EFAULT;
- }
-
- /* offset set back to 0 as there is contextual reading offset */
- *off = 0;
-- pr_debug("Read of (%lu) bytes performed.\n", sizeof(link_states));
-+ pr_debug("Read of (%zu) bytes performed.\n", sizeof(link_states));
-
- return sizeof(link_states);
- }
---- a/drivers/staging/fsl_ppfe/pfe_hif.c
-+++ b/drivers/staging/fsl_ppfe/pfe_hif.c
-@@ -115,11 +115,11 @@ static void send_dummy_pkt_to_hif(void)
- 0x33221100, 0xa8c05544, 0x00000301, 0x00000000,
- 0x00000000, 0x00000000, 0x00000000, 0xbe86c51f };
-
-- ddr_ptr = (void *)((u64)readl(BMU2_BASE_ADDR + BMU_ALLOC_CTRL));
-+ ddr_ptr = (void *)((uintptr_t)readl(BMU2_BASE_ADDR + BMU_ALLOC_CTRL));
- if (!ddr_ptr)
- return;
-
-- lmem_ptr = (void *)((u64)readl(BMU1_BASE_ADDR + BMU_ALLOC_CTRL));
-+ lmem_ptr = (void *)((uintptr_t)readl(BMU1_BASE_ADDR + BMU_ALLOC_CTRL));
- if (!lmem_ptr)
- return;
-
-@@ -186,16 +186,16 @@ static void pfe_hif_free_descr(struct pf
- void pfe_hif_desc_dump(struct pfe_hif *hif)
- {
- struct hif_desc *desc;
-- unsigned long desc_p;
-+ u64 desc_p;
- int ii = 0;
-
- pr_info("%s\n", __func__);
-
- desc = hif->rx_base;
-- desc_p = (u32)((u64)desc - (u64)hif->descr_baseaddr_v +
-+ desc_p = ((void *)desc - hif->descr_baseaddr_v +
- hif->descr_baseaddr_p);
-
-- pr_info("HIF Rx desc base %p physical %x\n", desc, (u32)desc_p);
-+ pr_info("HIF Rx desc base %p physical %llx\n", desc, desc_p);
- for (ii = 0; ii < hif->rx_ring_size; ii++) {
- pr_info("status: %08x, ctrl: %08x, data: %08x, next: %x\n",
- readl(&desc->status), readl(&desc->ctrl),
-@@ -204,10 +204,10 @@ void pfe_hif_desc_dump(struct pfe_hif *h
- }
-
- desc = hif->tx_base;
-- desc_p = ((u64)desc - (u64)hif->descr_baseaddr_v +
-+ desc_p = ((void *)desc - hif->descr_baseaddr_v +
- hif->descr_baseaddr_p);
-
-- pr_info("HIF Tx desc base %p physical %x\n", desc, (u32)desc_p);
-+ pr_info("HIF Tx desc base %p physical %llx\n", desc, desc_p);
- for (ii = 0; ii < hif->tx_ring_size; ii++) {
- pr_info("status: %08x, ctrl: %08x, data: %08x, next: %x\n",
- readl(&desc->status), readl(&desc->ctrl),
---- a/drivers/staging/fsl_ppfe/pfe_sysfs.c
-+++ b/drivers/staging/fsl_ppfe/pfe_sysfs.c
-@@ -535,7 +535,7 @@ static ssize_t pfe_show_tmu3_queues(stru
- static ssize_t pfe_set_util(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count)
- {
-- util_do_clear = kstrtoul(buf, NULL, 0);
-+ util_do_clear = kstrtoul(buf, 0, 0);
- return count;
- }
-
diff --git a/target/linux/layerscape/patches-6.1/704-net-phylink-treat-PHY_INTERFACE_MODE_2500SGMII-in-ph.patch b/target/linux/layerscape/patches-6.1/704-net-phylink-treat-PHY_INTERFACE_MODE_2500SGMII-in-ph.patch
deleted file mode 100644
index ed7b2c2609..0000000000
--- a/target/linux/layerscape/patches-6.1/704-net-phylink-treat-PHY_INTERFACE_MODE_2500SGMII-in-ph.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-From eb57941154e2ad142c07d47e874a221328467349 Mon Sep 17 00:00:00 2001
-From: Ioana Ciornei <ioana.ciornei@nxp.com>
-Date: Thu, 2 Jun 2022 12:11:11 +0300
-Subject: [PATCH] net: phylink: treat PHY_INTERFACE_MODE_2500SGMII in
- phylink_get_linkmodes
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-There is a downstream patch which adds a new interface type -
-PHY_INTERFACE_MODE_2500SGMII (which is really the same one as
-PHY_INTERFACE_MODE_2500BASEX).
-
-We backported from upstream the following phylink patch which, of
-course, does not treat the PHY_INTERFACE_MODE_2500SGMII interface mode
-in a switch case statement.
- 34ae2c09d46a ("net: phylink: add generic validate implementation")
-
-Because of this, we get the following build warning.
-
-drivers/net/phy/phylink.c: In function ‘phylink_get_linkmodes’:
-drivers/net/phy/phylink.c:322:2: warning: enumeration value ‘PHY_INTERFACE_MODE_2500SGMII’ not handled in switch [-Wswitch]
- 322 | switch (interface) {
- | ^~~~~~
-
-Fix it by treating the new interface mode in the switch-case statement.
-
-Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
----
- drivers/net/phy/phylink.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/drivers/net/phy/phylink.c
-+++ b/drivers/net/phy/phylink.c
-@@ -518,6 +518,7 @@ unsigned long phylink_get_capabilities(p
- break;
-
- case PHY_INTERFACE_MODE_2500BASEX:
-+ case PHY_INTERFACE_MODE_2500SGMII:
- caps |= MAC_2500FD;
- break;
-
diff --git a/target/linux/loongarch64/config-6.6 b/target/linux/loongarch64/config-6.6
index 6f637a6f01..46a90c1284 100644
--- a/target/linux/loongarch64/config-6.6
+++ b/target/linux/loongarch64/config-6.6
@@ -234,8 +234,6 @@ CONFIG_ENCRYPTED_KEYS=y
CONFIG_EXCLUSIVE_SYSTEM_RAM=y
CONFIG_EXPORTFS_BLOCK_OPS=y
CONFIG_EXT4_FS=y
-CONFIG_EXT4_FS_POSIX_ACL=y
-CONFIG_EXT4_FS_SECURITY=y
CONFIG_FAILOVER=y
CONFIG_FAIR_GROUP_SCHED=y
CONFIG_FANOTIFY=y
@@ -282,7 +280,6 @@ CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
CONFIG_FREEZER=y
CONFIG_FS_IOMAP=y
CONFIG_FS_MBCACHE=y
-CONFIG_FS_POSIX_ACL=y
CONFIG_FUNCTION_ALIGNMENT=0
CONFIG_FW_CACHE=y
# CONFIG_FW_DEVLINK_SYNC_STATE_TIMEOUT is not set
@@ -752,7 +749,6 @@ CONFIG_THERMAL_STATISTICS=y
CONFIG_THERMAL_WRITABLE_TRIPS=y
CONFIG_TICK_CPU_ACCOUNTING=y
CONFIG_TMPFS_INODE64=y
-CONFIG_TMPFS_POSIX_ACL=y
# CONFIG_TMPFS_QUOTA is not set
CONFIG_TRANSPARENT_HUGEPAGE=y
CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y
diff --git a/target/linux/malta/config-6.6 b/target/linux/malta/config-6.6
index 7c72f49265..73db6cea21 100644
--- a/target/linux/malta/config-6.6
+++ b/target/linux/malta/config-6.6
@@ -81,7 +81,6 @@ CONFIG_EXT4_FS=y
CONFIG_F2FS_FS=y
CONFIG_FS_IOMAP=y
CONFIG_FS_MBCACHE=y
-CONFIG_FS_POSIX_ACL=y
CONFIG_FUNCTION_ALIGNMENT=0
CONFIG_FW_LOADER_PAGED_BUF=y
CONFIG_FW_LOADER_SYSFS=y
@@ -131,8 +130,6 @@ CONFIG_IRQ_MIPS_CPU=y
CONFIG_IRQ_WORK=y
CONFIG_ISA_DMA_API=y
CONFIG_JBD2=y
-CONFIG_JFFS2_FS_POSIX_ACL=y
-CONFIG_JFFS2_FS_SECURITY=y
CONFIG_KALLSYMS=y
CONFIG_KERNEL_GZIP=y
# CONFIG_KERNEL_XZ is not set
diff --git a/target/linux/mediatek/base-files/lib/preinit/05_set_preinit_iface b/target/linux/mediatek/base-files/lib/preinit/05_set_preinit_iface
index 6dfa52c291..8e74c577cd 100644
--- a/target/linux/mediatek/base-files/lib/preinit/05_set_preinit_iface
+++ b/target/linux/mediatek/base-files/lib/preinit/05_set_preinit_iface
@@ -6,6 +6,7 @@ set_preinit_iface() {
ip link set eth1 up
ifname=eth1
;;
+ cudy,ap3000outdoor-v1|\
cudy,re3000-v1|\
ubnt,unifi-6-lr|\
zyxel,nwa50ax-pro)
diff --git a/target/linux/mediatek/base-files/lib/preinit/07_trigger_fip_scrubbing b/target/linux/mediatek/base-files/lib/preinit/07_trigger_fip_scrubbing
new file mode 100644
index 0000000000..74458e075b
--- /dev/null
+++ b/target/linux/mediatek/base-files/lib/preinit/07_trigger_fip_scrubbing
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+trigger_fip_scrubbing() {
+ local vol voltype volname
+ for vol in /sys/class/ubi/ubi*_*; do
+ [ -e "$vol" ] || continue
+ voltype="$(cat "$vol"/type)"
+ volname="$(cat "$vol"/name)"
+ if [ "$voltype" = "static" ] && [ "$volname" = "fip" ]; then
+ cat "/dev/${vol##*/}" > /dev/null
+ break
+ fi
+ done
+}
+
+boot_hook_add preinit_main trigger_fip_scrubbing
diff --git a/target/linux/mediatek/dts/mt7629-linksys-ea7500-v3.dts b/target/linux/mediatek/dts/mt7629-linksys-ea7500-v3.dts
new file mode 100644
index 0000000000..70b7cde6d9
--- /dev/null
+++ b/target/linux/mediatek/dts/mt7629-linksys-ea7500-v3.dts
@@ -0,0 +1,300 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/dts-v1/;
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+#include "mt7629.dtsi"
+
+/ {
+ model = "Linksys EA7500 v3";
+ compatible = "linksys,ea7500-v3", "mediatek,mt7629";
+
+ aliases {
+ led-boot = &led_power;
+ led-failsafe = &led_power;
+ led-running = &led_power;
+ led-upgrade = &led_power;
+ serial0 = &uart0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ bootargs-override = "console=ttyS0,115200n8";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led_power: power {
+ function = LED_FUNCTION_POWER;
+ color = <LED_COLOR_ID_WHITE>;
+ gpios = <&pio 52 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ keys {
+ compatible = "gpio-keys";
+
+ reset {
+ label = "reset";
+ linux,code = <KEY_RESTART>;
+ gpios = <&pio 60 GPIO_ACTIVE_LOW>;
+ };
+
+ wps {
+ label = "wps";
+ linux,code = <KEY_WPS_BUTTON>;
+ gpios = <&pio 58 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ memory@40000000 {
+ device_type = "memory";
+ reg = <0x40000000 0x10000000>;
+ };
+
+ 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_5v: regulator-5v {
+ compatible = "regulator-fixed";
+ regulator-name = "fixed-5V";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+};
+
+&eth {
+ pinctrl-names = "default";
+ pinctrl-0 = <&eth_pins>;
+ pinctrl-1 = <&ephy_leds_pins>;
+ status = "okay";
+
+ gmac0: mac@0 {
+ compatible = "mediatek,eth-mac";
+ reg = <0>;
+ phy-mode = "2500base-x";
+
+ fixed-link {
+ speed = <2500>;
+ full-duplex;
+ pause;
+ };
+ };
+
+ gmac1: mac@1 {
+ compatible = "mediatek,eth-mac";
+ reg = <1>;
+ phy-mode = "gmii";
+ phy-handle = <&phy0>;
+ };
+
+ mdio: mdio-bus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+
+ switch@1f {
+ compatible = "mediatek,mt7531";
+ reg = <31>;
+ reset-gpios = <&pio 28 0>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ interrupt-parent = <&pio>;
+ interrupts = <6 IRQ_TYPE_LEVEL_HIGH>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ label = "lan1";
+ };
+
+ port@1 {
+ reg = <1>;
+ label = "lan2";
+ };
+
+ port@2 {
+ reg = <2>;
+ label = "lan3";
+ };
+
+ port@3 {
+ reg = <3>;
+ label = "lan4";
+ };
+
+ port@6 {
+ reg = <6>;
+ ethernet = <&gmac0>;
+ phy-mode = "2500base-x";
+
+ fixed-link {
+ speed = <2500>;
+ full-duplex;
+ pause;
+ };
+ };
+ };
+ };
+ };
+};
+
+&bch {
+ status = "okay";
+};
+
+&snfi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&serial_nand_pins>;
+ status = "okay";
+ flash@0 {
+ compatible = "spi-nand";
+ reg = <0>;
+ spi-tx-bus-width = <4>;
+ spi-rx-bus-width = <4>;
+ nand-ecc-engine = <&snfi>;
+ mediatek,bmt-v2;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "Bootloader";
+ reg = <0x0 0x100000>;
+ read-only;
+ };
+
+ partition@100000 {
+ label = "Config";
+ reg = <0x100000 0x40000>;
+ };
+
+ partition@140000 {
+ label = "Factory";
+ reg = <0x140000 0x80000>;
+ read-only;
+ };
+
+ partition@1c0000 {
+ label = "kernel";
+ reg = <0x1c0000 0x800000>;
+ };
+
+ partition@9c0000 {
+ label = "ubi";
+ reg = <0x9c0000 0x2000000>;
+ };
+
+ partition@29c0000 {
+ label = "Kernel2";
+ reg = <0x29c0000 0x2800000>;
+ read-only;
+ };
+
+ partition@51c0000 {
+ label = "devinfo";
+ reg = <0x51c0000 0x40000>;
+ read-only;
+ };
+
+ partition@5200000 {
+ label = "sysdiag";
+ reg = <0x5200000 0x100000>;
+ read-only;
+ };
+
+ partition@5300000 {
+ label = "syscfg";
+ reg = <0x5300000 0x2000000>;
+ read-only;
+ };
+
+ partition@7300000 {
+ label = "s_env";
+ reg = <0x7300000 0x40000>;
+ };
+ };
+ };
+};
+
+&pio {
+ eth_pins: eth-pins {
+ mux {
+ function = "eth";
+ groups = "mdc_mdio";
+ };
+ };
+
+ ephy_leds_pins: ephy-leds-pins {
+ mux {
+ function = "led";
+ groups = "ephy_leds";
+ };
+ };
+
+ /* Serial NAND is shared pin with SPI-NOR */
+ serial_nand_pins: serial-nand-pins {
+ mux {
+ function = "flash";
+ groups = "snfi";
+ };
+ };
+
+ uart0_pins: uart0-pins {
+ mux {
+ function = "uart";
+ groups = "uart0_txd_rxd" ;
+ };
+ };
+
+ watchdog_pins: watchdog-pins {
+ mux {
+ function = "watchdog";
+ groups = "watchdog";
+ };
+ };
+};
+
+&ssusb {
+ vusb33-supply = <&reg_3p3v>;
+ vbus-supply = <&reg_5v>;
+ status = "okay";
+};
+
+&u3phy0 {
+ status = "okay";
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins>;
+ status = "okay";
+};
+
+&watchdog {
+ pinctrl-names = "default";
+ pinctrl-0 = <&watchdog_pins>;
+ status = "okay";
+
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ interrupt-parent = <&pio>;
+ interrupts = <GIC_SPI 0x80 IRQ_TYPE_EDGE_FALLING>;
+};
diff --git a/target/linux/mediatek/dts/mt7981a-edgecore-eap111.dts b/target/linux/mediatek/dts/mt7981a-edgecore-eap111.dts
index c306a5eb7b..0e7c4fe8b5 100644
--- a/target/linux/mediatek/dts/mt7981a-edgecore-eap111.dts
+++ b/target/linux/mediatek/dts/mt7981a-edgecore-eap111.dts
@@ -15,6 +15,7 @@
led-failsafe = &led_green;
led-running = &led_green;
led-upgrade = &led_green;
+ label-mac-device = &gmac1;
};
chosen {
diff --git a/target/linux/mediatek/dts/mt7981a-glinet-gl-x3000-xe3000-common.dtsi b/target/linux/mediatek/dts/mt7981a-glinet-gl-x3000-xe3000-common.dtsi
index e9050e02e5..919fb23c53 100644
--- a/target/linux/mediatek/dts/mt7981a-glinet-gl-x3000-xe3000-common.dtsi
+++ b/target/linux/mediatek/dts/mt7981a-glinet-gl-x3000-xe3000-common.dtsi
@@ -148,7 +148,7 @@
partname = "u-boot-env";
nvmem-layout {
- compatible = "u-boot,env-layout";
+ compatible = "u-boot,env";
};
};
diff --git a/target/linux/mediatek/dts/mt7981b-abt-asr3000.dts b/target/linux/mediatek/dts/mt7981b-abt-asr3000.dts
new file mode 100644
index 0000000000..dd07def303
--- /dev/null
+++ b/target/linux/mediatek/dts/mt7981b-abt-asr3000.dts
@@ -0,0 +1,275 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+/dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+#include "mt7981.dtsi"
+
+/ {
+ model = "ABT ASR3000";
+ compatible = "abt,asr3000", "mediatek,mt7981";
+
+ aliases {
+ led-boot = &mesh_led;
+ led-failsafe = &mesh_led;
+ led-upgrade = &mesh_led;
+ label-mac-device = &gmac1;
+ serial0 = &uart0;
+ };
+
+ chosen {
+ rootdisk = <&ubi_rootdisk>;
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory@40000000 {
+ reg = <0 0x40000000 0 0x10000000>;
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ button-reset {
+ label = "reset";
+ linux,code = <KEY_RESTART>;
+ gpios = <&pio 1 GPIO_ACTIVE_LOW>;
+ };
+
+ button-mesh {
+ label = "mesh";
+ linux,code = <BTN_9>;
+ linux,input-type = <EV_SW>;
+ gpios = <&pio 0 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+
+ led-0 {
+ function = LED_FUNCTION_WAN;
+ color = <LED_COLOR_ID_RED>;
+ gpios = <&pio 4 GPIO_ACTIVE_LOW>;
+ };
+
+ led-1 {
+ function = LED_FUNCTION_WAN;
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&pio 8 GPIO_ACTIVE_LOW>;
+ };
+
+ mesh_led: led-2 {
+ label = "green:mesh";
+ gpios = <&pio 15 GPIO_ACTIVE_HIGH>;
+ };
+
+ led-3 {
+ function = LED_FUNCTION_WLAN_2GHZ;
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&pio 34 GPIO_ACTIVE_LOW>;
+ };
+
+ led-4 {
+ function = LED_FUNCTION_WLAN_5GHZ;
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&pio 35 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
+
+&eth {
+ status = "okay";
+
+ gmac0: mac@0 {
+ compatible = "mediatek,eth-mac";
+ reg = <0>;
+ phy-mode = "2500base-x";
+
+ nvmem-cells = <&macaddr_art_0 0>;
+ nvmem-cell-names = "mac-address";
+
+ fixed-link {
+ speed = <2500>;
+ full-duplex;
+ pause;
+ };
+ };
+
+ gmac1: mac@1 {
+ compatible = "mediatek,eth-mac";
+ reg = <1>;
+ phy-mode = "gmii";
+ phy-handle = <&int_gbe_phy>;
+
+ nvmem-cells = <&macaddr_art_0 0>;
+ nvmem-cell-names = "mac-address";
+ };
+};
+
+&mdio_bus {
+ switch: switch@1f {
+ compatible = "mediatek,mt7531";
+ reg = <31>;
+ reset-gpios = <&pio 39 GPIO_ACTIVE_HIGH>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ interrupt-parent = <&pio>;
+ interrupts = <38 IRQ_TYPE_LEVEL_HIGH>;
+ };
+};
+
+&pio {
+ spi0_flash_pins: spi0-pins {
+ mux {
+ function = "spi";
+ groups = "spi0", "spi0_wp_hold";
+ };
+
+ conf-pu {
+ pins = "SPI0_CS", "SPI0_HOLD", "SPI0_WP";
+ drive-strength = <8>;
+ mediatek,pull-up-adv = <0>; /* bias-disable */
+ };
+
+ conf-pd {
+ pins = "SPI0_CLK", "SPI0_MOSI", "SPI0_MISO";
+ drive-strength = <8>;
+ mediatek,pull-up-adv = <0>; /* bias-disable */
+ };
+ };
+};
+
+&spi0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_flash_pins>;
+ status = "okay";
+
+ spi_nand: flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spi-nand";
+ reg = <0>;
+
+ spi-max-frequency = <52000000>;
+ spi-tx-bus-width = <4>;
+ spi-rx-bus-width = <4>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "bl2";
+ reg = <0x0 0x100000>;
+ read-only;
+ };
+
+ partition@100000 {
+ label = "u-boot-env";
+ reg = <0x100000 0x80000>;
+ };
+
+ partition@180000 {
+ label = "art";
+ reg = <0x180000 0x100000>;
+ read-only;
+
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ macaddr_art_0: macaddr@0 {
+ compatible = "mac-base";
+ reg = <0x0 0x6>;
+ #nvmem-cell-cells = <1>;
+ };
+ };
+ };
+
+ partition@280000 {
+ label = "factory";
+ reg = <0x280000 0x100000>;
+ read-only;
+
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ eeprom_factory_0: eeprom@0 {
+ reg = <0x0 0x1000>;
+ };
+ };
+ };
+
+ partition@380000 {
+ label = "fip";
+ reg = <0x380000 0x200000>;
+ read-only;
+ };
+
+ partition@580000 {
+ compatible = "linux,ubi";
+ label = "ubi";
+ reg = <0x580000 0x7a80000>;
+
+ volumes {
+ ubi_rootdisk: ubi-volume-fit {
+ volname = "fit";
+ };
+ };
+ };
+ };
+ };
+};
+
+&switch {
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ label = "lan3";
+ };
+
+ port@1 {
+ reg = <1>;
+ label = "lan2";
+ };
+
+ port@2 {
+ reg = <2>;
+ label = "lan1";
+ };
+
+ port@6 {
+ reg = <6>;
+ ethernet = <&gmac0>;
+ phy-mode = "2500base-x";
+
+ fixed-link {
+ speed = <2500>;
+ full-duplex;
+ pause;
+ };
+ };
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&watchdog {
+ status = "okay";
+};
+
+&wifi {
+ nvmem-cells = <&eeprom_factory_0>;
+ nvmem-cell-names = "eeprom";
+ status = "okay";
+};
diff --git a/target/linux/mediatek/dts/mt7981b-cmcc-rax3000m-emmc.dtso b/target/linux/mediatek/dts/mt7981b-cmcc-rax3000m-emmc.dtso
index c1c9c75c27..e6b140bfad 100644
--- a/target/linux/mediatek/dts/mt7981b-cmcc-rax3000m-emmc.dtso
+++ b/target/linux/mediatek/dts/mt7981b-cmcc-rax3000m-emmc.dtso
@@ -7,6 +7,29 @@
compatible = "cmcc,rax3000m", "mediatek,mt7981";
fragment@0 {
+ target = <&chosen>;
+ __overlay__ {
+ rootdisk = <&emmc_rootdisk>;
+ };
+ };
+
+ fragment@1 {
+ target = <&gmac0>;
+ __overlay__ {
+ nvmem-cells = <&macaddr_factory_2a 0>;
+ nvmem-cell-names = "mac-address";
+ };
+ };
+
+ fragment@2 {
+ target = <&gmac1>;
+ __overlay__ {
+ nvmem-cells = <&macaddr_factory_24 0>;
+ nvmem-cell-names = "mac-address";
+ };
+ };
+
+ fragment@3 {
target = <&mmc0>;
__overlay__ {
bus-width = <8>;
@@ -19,10 +42,51 @@
pinctrl-1 = <&mmc0_pins_uhs>;
vmmc-supply = <&reg_3p3v>;
status = "okay";
+
+ card@0 {
+ compatible = "mmc-card";
+ reg = <0>;
+
+ block {
+ compatible = "block-device";
+
+ partitions {
+ block-partition-factory {
+ partname = "factory";
+
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ eeprom_factory_0: eeprom@0 {
+ reg = <0x0 0x1000>;
+ };
+
+ macaddr_factory_24: macaddr@24 {
+ compatible = "mac-base";
+ reg = <0x24 0x6>;
+ #nvmem-cell-cells = <1>;
+ };
+
+ macaddr_factory_2a: macaddr@2a {
+ compatible = "mac-base";
+ reg = <0x2a 0x6>;
+ #nvmem-cell-cells = <1>;
+ };
+ };
+ };
+
+ emmc_rootdisk: block-partition-production {
+ partname = "production";
+ };
+ };
+ };
+ };
};
};
- fragment@1 {
+ fragment@4 {
target = <&pio>;
__overlay__ {
mmc0_pins_default: mmc0-pins {
@@ -40,4 +104,12 @@
};
};
};
+
+ fragment@5 {
+ target = <&wifi>;
+ __overlay__ {
+ nvmem-cells = <&eeprom_factory_0>;
+ nvmem-cell-names = "eeprom";
+ };
+ };
};
diff --git a/target/linux/mediatek/dts/mt7981b-cmcc-rax3000m-nand.dtso b/target/linux/mediatek/dts/mt7981b-cmcc-rax3000m-nand.dtso
index 4d2b01cb63..fded878332 100644
--- a/target/linux/mediatek/dts/mt7981b-cmcc-rax3000m-nand.dtso
+++ b/target/linux/mediatek/dts/mt7981b-cmcc-rax3000m-nand.dtso
@@ -7,6 +7,13 @@
compatible = "cmcc,rax3000m", "mediatek,mt7981";
fragment@0 {
+ target = <&chosen>;
+ __overlay__ {
+ rootdisk = <&ubi_rootdisk>;
+ };
+ };
+
+ fragment@1 {
target = <&gmac0>;
__overlay__ {
nvmem-cells = <&macaddr_factory_2a 0>;
@@ -14,7 +21,7 @@
};
};
- fragment@1 {
+ fragment@2 {
target = <&gmac1>;
__overlay__ {
nvmem-cells = <&macaddr_factory_24 0>;
@@ -22,7 +29,7 @@
};
};
- fragment@2 {
+ fragment@3 {
target = <&pio>;
__overlay__ {
spi0_flash_pins: spi0-pins {
@@ -46,7 +53,7 @@
};
};
- fragment@3 {
+ fragment@4 {
target = <&spi0>;
__overlay__ {
pinctrl-names = "default";
@@ -79,7 +86,7 @@
reg = <0x100000 0x80000>;
};
- factory: partition@180000 {
+ partition@180000 {
label = "factory";
reg = <0x180000 0x200000>;
read-only;
@@ -89,6 +96,10 @@
#address-cells = <1>;
#size-cells = <1>;
+ eeprom_factory_0: eeprom@0 {
+ reg = <0x0 0x1000>;
+ };
+
macaddr_factory_24: macaddr@24 {
compatible = "mac-base";
reg = <0x24 0x6>;
@@ -110,18 +121,26 @@
};
partition@580000 {
+ compatible = "linux,ubi";
label = "ubi";
reg = <0x580000 0x7200000>;
+
+ volumes {
+ ubi_rootdisk: ubi-volume-fit {
+ volname = "fit";
+ };
+ };
};
};
};
};
};
- fragment@4 {
+ fragment@5 {
target = <&wifi>;
__overlay__ {
- mediatek,mtd-eeprom = <&factory 0x0>;
+ nvmem-cells = <&eeprom_factory_0>;
+ nvmem-cell-names = "eeprom";
};
};
};
diff --git a/target/linux/mediatek/dts/mt7981b-cmcc-rax3000m.dts b/target/linux/mediatek/dts/mt7981b-cmcc-rax3000m.dts
index c8db5b58f5..977a613333 100644
--- a/target/linux/mediatek/dts/mt7981b-cmcc-rax3000m.dts
+++ b/target/linux/mediatek/dts/mt7981b-cmcc-rax3000m.dts
@@ -22,7 +22,8 @@
serial0 = &uart0;
};
- chosen {
+ chosen: chosen {
+ bootargs-override = "root=/dev/fit0 rootwait";
stdout-path = "serial0:115200n8";
};
diff --git a/target/linux/mediatek/dts/mt7981b-cudy-ap3000outdoor-v1.dts b/target/linux/mediatek/dts/mt7981b-cudy-ap3000outdoor-v1.dts
new file mode 100644
index 0000000000..62e4063947
--- /dev/null
+++ b/target/linux/mediatek/dts/mt7981b-cudy-ap3000outdoor-v1.dts
@@ -0,0 +1,209 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+
+/dts-v1/;
+
+#include <dt-bindings/leds/common.h>
+
+#include "mt7981.dtsi"
+
+/ {
+ model = "Cudy AP3000 Outdoor v1";
+ compatible = "cudy,ap3000outdoor-v1", "mediatek,mt7981-spim-snand-rfb";
+
+ aliases {
+ label-mac-device = &gmac1;
+ led-boot = &led_status_green;
+ led-failsafe = &led_status_red;
+ led-running = &led_status_green;
+ led-upgrade = &led_status_red;
+ serial0 = &uart0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ reset {
+ label = "reset";
+ linux,code = <KEY_RESTART>;
+ gpios = <&pio 1 GPIO_ACTIVE_LOW>;
+ };
+
+ wps {
+ label = "wps";
+ linux,code = <KEY_WPS_BUTTON>;
+ gpios = <&pio 0 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led_status_green: led@0 {
+ function = LED_FUNCTION_STATUS;
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&pio 10 GPIO_ACTIVE_HIGH>;
+ };
+
+ led_status_red: led_1 {
+ function = LED_FUNCTION_POWER;
+ color = <LED_COLOR_ID_RED>;
+ gpios = <&pio 11 GPIO_ACTIVE_HIGH>;
+ };
+ };
+ gpio_export {
+ compatible = "gpio-export";
+ #size-cells = <0>;
+
+ antctrl {
+ /* Not sure if this pin does anything.
+ * It was taken from GPL sources.
+ * Intermediate image doesn't have it.
+ */
+ gpio-export,name = "antctrl";
+ gpio-export,output = <1>;
+ gpios = <&pio 7 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ watchdog-hw {
+ compatible = "linux,wdt-gpio";
+ gpios = <&pio 6 GPIO_ACTIVE_HIGH>;
+ hw_algo = "level";
+ hw_margin_ms = <10000>;
+ always-running;
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&watchdog {
+ status = "okay";
+};
+
+&eth {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mdio_pins>;
+
+ status = "okay";
+
+ gmac1: mac@1 {
+ compatible = "mediatek,eth-mac";
+ reg = <1>;
+ phy-mode = "gmii";
+ phy-handle = <&int_gbe_phy>;
+ nvmem-cell-names = "mac-address";
+ nvmem-cells = <&macaddr_bdinfo_de00 1>;
+ };
+};
+
+&spi0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_flash_pins>;
+ status = "okay";
+
+ spi_nand: flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spi-nand";
+ reg = <0>;
+ spi-max-frequency = <52000000>;
+
+ spi-cal-enable;
+ spi-cal-mode = "read-data";
+ spi-cal-datalen = <7>;
+ spi-cal-data = /bits/ 8 <0x53 0x50 0x49 0x4E 0x41 0x4E 0x44>;
+ spi-cal-addrlen = <5>;
+ spi-cal-addr = /bits/ 32 <0x0 0x0 0x0 0x0 0x0>;
+
+ spi-tx-bus-width = <4>;
+ spi-rx-bus-width = <4>;
+ mediatek,nmbm;
+ mediatek,bmt-max-ratio = <1>;
+ mediatek,bmt-max-reserved-blocks = <64>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "BL2";
+ reg = <0x00000 0x0100000>;
+ read-only;
+ };
+
+ partition@100000 {
+ label = "u-boot-env";
+ reg = <0x0100000 0x0080000>;
+ read-only;
+ };
+
+ factory: partition@180000 {
+ label = "Factory";
+ reg = <0x180000 0x0200000>;
+ read-only;
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ eeprom_factory_0: eeprom@0 {
+ reg = <0x0 0x1000>;
+ };
+ };
+ };
+
+ partition@380000 {
+ label = "bdinfo";
+ reg = <0x380000 0x0040000>;
+ read-only;
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ macaddr_bdinfo_de00: macaddr@de00 {
+ compatible = "mac-base";
+ reg = <0xde00 0x6>;
+ #nvmem-cell-cells = <1>;
+ };
+ };
+
+ };
+
+ partition@3C0000 {
+ label = "FIP";
+ reg = <0x3C0000 0x0200000>;
+ read-only;
+ };
+
+ partition@580000 {
+ label = "ubi";
+ reg = <0x5C0000 0x4000000>;
+ compatible = "linux,ubi";
+ };
+ };
+ };
+};
+
+
+&pio {
+ spi0_flash_pins: spi0-pins {
+ mux {
+ function = "spi";
+ groups = "spi0", "spi0_wp_hold";
+ };
+ };
+};
+
+&wifi {
+ status = "okay";
+ nvmem-cells = <&eeprom_factory_0>;
+ nvmem-cell-names = "eeprom";
+};
diff --git a/target/linux/mediatek/dts/mt7981b-glinet-gl-mt2500.dts b/target/linux/mediatek/dts/mt7981b-glinet-gl-mt2500.dts
index 15818a90fc..0bd3ac0a29 100644
--- a/target/linux/mediatek/dts/mt7981b-glinet-gl-mt2500.dts
+++ b/target/linux/mediatek/dts/mt7981b-glinet-gl-mt2500.dts
@@ -164,7 +164,7 @@
block-partition-u-boot-env {
partname = "u-boot-env";
nvmem-layout {
- compatible = "u-boot,env-layout";
+ compatible = "u-boot,env";
};
};
};
diff --git a/target/linux/mediatek/dts/mt7981b-h3c-magic-nx30-pro.dts b/target/linux/mediatek/dts/mt7981b-h3c-magic-nx30-pro.dts
index 030cc25041..c405ce977e 100644
--- a/target/linux/mediatek/dts/mt7981b-h3c-magic-nx30-pro.dts
+++ b/target/linux/mediatek/dts/mt7981b-h3c-magic-nx30-pro.dts
@@ -20,6 +20,8 @@
};
chosen {
+ bootargs-append = " root=/dev/fit0 rootwait";
+ rootdisk = <&ubi_rootdisk>;
stdout-path = "serial0:115200n8";
};
@@ -141,6 +143,13 @@
partition@580000 {
label = "ubi";
reg = <0x0580000 0x4000000>;
+ compatible = "linux,ubi";
+
+ volumes {
+ ubi_rootdisk: ubi-volume-fit {
+ volname = "fit";
+ };
+ };
};
/* yaffs partition */
diff --git a/target/linux/mediatek/dts/mt7981b-jcg-q30-pro.dts b/target/linux/mediatek/dts/mt7981b-jcg-q30-pro.dts
index c8b9aeba42..e866799ebc 100644
--- a/target/linux/mediatek/dts/mt7981b-jcg-q30-pro.dts
+++ b/target/linux/mediatek/dts/mt7981b-jcg-q30-pro.dts
@@ -21,6 +21,8 @@
};
chosen {
+ bootargs-append = " root=/dev/fit0 rootwait";
+ rootdisk = <&ubi_rootdisk>;
stdout-path = "serial0:115200n8";
};
@@ -146,6 +148,13 @@
partition@580000 {
label = "ubi";
reg = <0x0580000 0x7000000>;
+ compatible = "linux,ubi";
+
+ volumes {
+ ubi_rootdisk: ubi-volume-fit {
+ volname = "fit";
+ };
+ };
};
};
};
diff --git a/target/linux/mediatek/dts/mt7981b-openwrt-one.dts b/target/linux/mediatek/dts/mt7981b-openwrt-one.dts
index b2223f8d76..cfc5319d91 100644
--- a/target/linux/mediatek/dts/mt7981b-openwrt-one.dts
+++ b/target/linux/mediatek/dts/mt7981b-openwrt-one.dts
@@ -8,8 +8,6 @@
compatible = "openwrt,one", "mediatek,mt7981";
aliases {
- ethernet0 = &gmac0;
- ethernet1 = &gmac1;
serial0 = &uart0;
led-boot = &led_status_white;
led-failsafe = &led_status_red;
@@ -140,7 +138,7 @@
phy-handle = <&phy15>;
phy-mode = "2500base-x";
nvmem-cell-names = "mac-address";
- nvmem-cells = <&macaddr_factory_4>;
+ nvmem-cells = <&macaddr_factory_24>;
};
gmac1: mac@1 {
@@ -149,7 +147,7 @@
phy-mode = "gmii";
phy-handle = <&int_gbe_phy>;
nvmem-cell-names = "mac-address";
- nvmem-cells = <&macaddr_factory_a>;
+ nvmem-cells = <&macaddr_factory_2a>;
};
};
@@ -331,7 +329,7 @@
partition@580000 {
label = "ubi";
- reg = <0x100000 0x7F00000>;
+ reg = <0x100000 0xFF00000>;
compatible = "linux,ubi";
volumes {
@@ -388,15 +386,19 @@
};
macaddr_factory_4: macaddr@4 {
+ reg = <0x4 0x6>;
compatible = "mac-base";
- reg = <0x24 0x6>;
#nvmem-cell-cells = <1>;
};
- macaddr_factory_a: macaddr@a {
+ macaddr_factory_24: macaddr@24 {
+ reg = <0x24 0x6>;
compatible = "mac-base";
+ };
+
+ macaddr_factory_2a: macaddr@2a {
reg = <0x2a 0x6>;
- #nvmem-cell-cells = <1>;
+ compatible = "mac-base";
};
};
};
@@ -444,6 +446,18 @@
nvmem-cells = <&eeprom_factory_0>;
nvmem-cell-names = "eeprom";
status = "okay";
+
+ band@0 {
+ reg = <0>;
+ nvmem-cells = <&macaddr_factory_4 0>;
+ nvmem-cell-names = "mac-address";
+ };
+
+ band@1 {
+ reg = <1>;
+ nvmem-cells = <&macaddr_factory_4 1>;
+ nvmem-cell-names = "mac-address";
+ };
};
&pcie {
diff --git a/target/linux/mediatek/dts/mt7981b-qihoo-360t7.dts b/target/linux/mediatek/dts/mt7981b-qihoo-360t7.dts
index 3925f80ba3..f167600f30 100644
--- a/target/linux/mediatek/dts/mt7981b-qihoo-360t7.dts
+++ b/target/linux/mediatek/dts/mt7981b-qihoo-360t7.dts
@@ -20,6 +20,8 @@
};
chosen {
+ bootargs-append = " root=/dev/fit0 rootwait";
+ rootdisk = <&ubi_rootdisk>;
stdout-path = "serial0:115200n8";
};
@@ -134,6 +136,13 @@
partition@580000 {
label = "ubi";
reg = <0x0580000 0x6c00000>;
+ compatible = "linux,ubi";
+
+ volumes {
+ ubi_rootdisk: ubi-volume-fit {
+ volname = "fit";
+ };
+ };
};
partition@7180000 {
diff --git a/target/linux/mediatek/dts/mt7981b-unielec-u7981-01-emmc.dts b/target/linux/mediatek/dts/mt7981b-unielec-u7981-01-emmc.dts
index abd4d4e59d..264c985612 100644
--- a/target/linux/mediatek/dts/mt7981b-unielec-u7981-01-emmc.dts
+++ b/target/linux/mediatek/dts/mt7981b-unielec-u7981-01-emmc.dts
@@ -32,7 +32,7 @@
partname = "u-boot-env";
nvmem-layout {
- compatible = "u-boot,env-layout";
+ compatible = "u-boot,env";
};
};
diff --git a/target/linux/mediatek/dts/mt7981b-xiaomi-mi-router-ax3000t-ubootmod.dts b/target/linux/mediatek/dts/mt7981b-xiaomi-mi-router-ax3000t-ubootmod.dts
index 809e625ce1..7466b8f7c6 100644
--- a/target/linux/mediatek/dts/mt7981b-xiaomi-mi-router-ax3000t-ubootmod.dts
+++ b/target/linux/mediatek/dts/mt7981b-xiaomi-mi-router-ax3000t-ubootmod.dts
@@ -6,11 +6,23 @@
/ {
model = "Xiaomi Mi Router AX3000T (OpenWrt U-Boot layout)";
compatible = "xiaomi,mi-router-ax3000t-ubootmod", "mediatek,mt7981";
+
+ chosen {
+ bootargs-append = " root=/dev/fit0 rootwait";
+ rootdisk = <&ubi_rootdisk>;
+ };
};
&partitions {
partition@600000 {
label = "ubi";
reg = <0x600000 0x7000000>;
+ compatible = "linux,ubi";
+
+ volumes {
+ ubi_rootdisk: ubi-volume-fit {
+ volname = "fit";
+ };
+ };
};
};
diff --git a/target/linux/mediatek/dts/mt7981b-xiaomi-mi-router-wr30u-ubootmod.dts b/target/linux/mediatek/dts/mt7981b-xiaomi-mi-router-wr30u-ubootmod.dts
index 6d0f3feb45..b22bbed379 100644
--- a/target/linux/mediatek/dts/mt7981b-xiaomi-mi-router-wr30u-ubootmod.dts
+++ b/target/linux/mediatek/dts/mt7981b-xiaomi-mi-router-wr30u-ubootmod.dts
@@ -6,11 +6,23 @@
/ {
model = "Xiaomi Mi Router WR30U (OpenWrt U-Boot layout)";
compatible = "xiaomi,mi-router-wr30u-ubootmod", "mediatek,mt7981";
+
+ chosen {
+ bootargs-append = " root=/dev/fit0 rootwait";
+ rootdisk = <&ubi_rootdisk>;
+ };
};
&partitions {
partition@600000 {
label = "ubi";
reg = <0x600000 0x7000000>;
+ compatible = "linux,ubi";
+
+ volumes {
+ ubi_rootdisk: ubi-volume-fit {
+ volname = "fit";
+ };
+ };
};
};
diff --git a/target/linux/mediatek/dts/mt7981b-zyxel-nwa50ax-pro.dts b/target/linux/mediatek/dts/mt7981b-zyxel-nwa50ax-pro.dts
index 54df8c054a..95247eba9d 100644
--- a/target/linux/mediatek/dts/mt7981b-zyxel-nwa50ax-pro.dts
+++ b/target/linux/mediatek/dts/mt7981b-zyxel-nwa50ax-pro.dts
@@ -4,7 +4,7 @@
#include "mt7981.dtsi"
/ {
- model = "ZyXEL NWA50AX Pro";
+ model = "Zyxel NWA50AX Pro";
compatible = "zyxel,nwa50ax-pro", "mediatek,mt7981";
aliases {
diff --git a/target/linux/mediatek/dts/mt7986a-glinet-gl-mt6000.dts b/target/linux/mediatek/dts/mt7986a-glinet-gl-mt6000.dts
index fd0e1a6915..fe55f2ea3a 100644
--- a/target/linux/mediatek/dts/mt7986a-glinet-gl-mt6000.dts
+++ b/target/linux/mediatek/dts/mt7986a-glinet-gl-mt6000.dts
@@ -325,7 +325,7 @@
partname = "u-boot-env";
nvmem-layout {
- compatible = "u-boot,env-layout";
+ compatible = "u-boot,env";
};
};
diff --git a/target/linux/mediatek/dts/mt7986a-jdcloud-re-cp-03.dts b/target/linux/mediatek/dts/mt7986a-jdcloud-re-cp-03.dts
index 372d4ec22a..7461cdd49b 100644
--- a/target/linux/mediatek/dts/mt7986a-jdcloud-re-cp-03.dts
+++ b/target/linux/mediatek/dts/mt7986a-jdcloud-re-cp-03.dts
@@ -133,8 +133,8 @@
reg = <6>;
reset-gpios = <&pio 6 GPIO_ACTIVE_LOW>;
- reset-assert-us = <10000>;
- reset-deassert-us = <50000>;
+ reset-assert-us = <15000>;
+ reset-deassert-us = <68000>;
realtek,aldps-enable;
};
diff --git a/target/linux/mediatek/dts/mt7986a-netcore-n60.dts b/target/linux/mediatek/dts/mt7986a-netcore-n60.dts
index b96b1e2ec0..2c129acbba 100644
--- a/target/linux/mediatek/dts/mt7986a-netcore-n60.dts
+++ b/target/linux/mediatek/dts/mt7986a-netcore-n60.dts
@@ -21,6 +21,8 @@
};
chosen {
+ bootargs-append = " root=/dev/fit0 rootwait";
+ rootdisk = <&ubi_rootdisk>;
stdout-path = "serial0:115200n8";
};
@@ -206,6 +208,13 @@
partition@580000 {
label = "ubi";
reg = <0x0580000 0x7280000>;
+ compatible = "linux,ubi";
+
+ volumes {
+ ubi_rootdisk: ubi-volume-fit {
+ volname = "fit";
+ };
+ };
};
};
};
diff --git a/target/linux/mediatek/dts/mt7986a-tplink-tl-xtr8488.dts b/target/linux/mediatek/dts/mt7986a-tplink-tl-xtr8488.dts
new file mode 100644
index 0000000000..1b26b25f49
--- /dev/null
+++ b/target/linux/mediatek/dts/mt7986a-tplink-tl-xtr8488.dts
@@ -0,0 +1,390 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+/dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+
+#include "mt7986a.dtsi"
+
+/ {
+ model = "TP-Link TL-XTR8488";
+ compatible = "tplink,tl-xtr8488", "mediatek,mt7986a";
+
+ aliases {
+ serial0 = &uart0;
+ label-mac-device = &gmac0;
+ led-boot = &led_status_green;
+ led-failsafe = &led_status_red;
+ led-running = &led_status_green;
+ led-upgrade = &led_status_red;
+ };
+
+ chosen {
+ bootargs = "root=/dev/fit0 rootwait";
+ rootdisk = <&ubi_rootdisk>;
+ stdout-path = "serial0:115200n8";
+ };
+
+ 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_5v: regulator-5v {
+ compatible = "regulator-fixed";
+ regulator-name = "fixed-5V";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ keys {
+ compatible = "gpio-keys";
+
+ reset {
+ label = "reset";
+ linux,code = <KEY_RESTART>;
+ gpios = <&pio 15 GPIO_ACTIVE_LOW>;
+ };
+
+ wps {
+ label = "wps";
+ linux,code = <KEY_WPS_BUTTON>;
+ gpios = <&pio 16 GPIO_ACTIVE_LOW>;
+ };
+
+ turbo {
+ label = "turbo";
+ linux,code = <BTN_1>;
+ gpios = <&pio 11 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led_status_red: status-red {
+ color = <LED_COLOR_ID_RED>;
+ function = LED_FUNCTION_STATUS;
+ gpios = <&pio 7 GPIO_ACTIVE_HIGH>;
+ };
+
+ led_status_green: status-green {
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_STATUS;
+ gpios = <&pio 8 GPIO_ACTIVE_HIGH>;
+ };
+
+ turbo {
+ label = "green:turbo";
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&pio 12 GPIO_ACTIVE_LOW>;
+ };
+ };
+};
+
+&crypto {
+ status = "okay";
+};
+
+&eth {
+ status = "okay";
+
+ gmac0: mac@0 {
+ compatible = "mediatek,eth-mac";
+ reg = <0>;
+ phy-mode = "2500base-x";
+
+ nvmem-cells = <&macaddr_config_1c 0>;
+ nvmem-cell-names = "mac-address";
+
+ fixed-link {
+ speed = <2500>;
+ full-duplex;
+ pause;
+ };
+ };
+
+ gmac1: mac@1 {
+ compatible = "mediatek,eth-mac";
+ reg = <1>;
+ phy-handle = <&phy7>;
+ phy-mode = "2500base-x";
+
+ nvmem-cells = <&macaddr_config_1c 1>;
+ nvmem-cell-names = "mac-address";
+ };
+
+ mdio: mdio-bus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+};
+
+&mdio {
+ phy5: phy@5 {
+ compatible = "ethernet-phy-ieee802.3-c45";
+ reg = <5>;
+ realtek,aldps-enable;
+ };
+
+ phy7: phy@7 {
+ compatible = "ethernet-phy-ieee802.3-c45";
+ reg = <7>;
+ realtek,aldps-enable;
+ };
+
+ switch: switch@1f {
+ compatible = "mediatek,mt7531";
+ reg = <31>;
+ reset-gpios = <&pio 6 GPIO_ACTIVE_HIGH>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ interrupt-parent = <&pio>;
+ interrupts = <66 IRQ_TYPE_LEVEL_HIGH>;
+ };
+};
+
+&switch {
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ label = "lan1";
+ };
+
+ port@1 {
+ reg = <1>;
+ label = "lan2";
+ };
+
+ port@2 {
+ reg = <2>;
+ label = "lan3";
+ };
+
+ port@3 {
+ reg = <3>;
+ label = "lan4";
+ };
+
+ port@5 {
+ reg = <5>;
+ label = "lan5";
+ phy-handle = <&phy5>;
+ phy-mode = "2500base-x";
+ };
+
+ port@6 {
+ reg = <6>;
+ ethernet = <&gmac0>;
+ phy-mode = "2500base-x";
+
+ fixed-link {
+ speed = <2500>;
+ full-duplex;
+ pause;
+ };
+ };
+ };
+};
+
+&spi0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi_flash_pins>;
+ status = "okay";
+
+ flash@0 {
+ compatible = "spi-nand";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0>;
+
+ spi-max-frequency = <20000000>;
+ spi-tx-bus-width = <4>;
+ spi-rx-bus-width = <4>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "bl2";
+ reg = <0x000000 0x0100000>;
+ read-only;
+ };
+
+ partition@100000 {
+ label = "config";
+ reg = <0x100000 0x0040000>;
+ read-only;
+
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ macaddr_config_1c: macaddr@1c {
+ compatible = "mac-base";
+ reg = <0x1c 0x6>;
+ #nvmem-cell-cells = <1>;
+ };
+ };
+ };
+
+ partition@140000 {
+ label = "factory";
+ reg = <0x140000 0x0040000>;
+ read-only;
+
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ eeprom_factory_0: eeprom@0 {
+ reg = <0x0 0x1000>;
+ };
+
+ eeprom_factory_1000: eeprom@1000 {
+ reg = <0x1000 0xe00>;
+ };
+ };
+ };
+
+ partition@180000 {
+ label = "reserved";
+ reg = <0x180000 0x0200000>;
+ read-only;
+ };
+
+ partition@380000 {
+ label = "fip";
+ reg = <0x380000 0x0200000>;
+ read-only;
+ };
+
+ partition@580000 {
+ compatible = "linux,ubi";
+ reg = <0x580000 0x7800000>;
+ label = "ubi";
+
+ volumes {
+ ubi_rootdisk: ubi-volume-fit {
+ volname = "fit";
+ };
+ };
+ };
+ };
+ };
+};
+
+&pcie {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie_pins>;
+ status = "okay";
+
+ pcie@0,0 {
+ reg = <0x0000 0 0 0 0>;
+
+ wifi@0,0 {
+ compatible = "mediatek,mt76";
+ reg = <0x0000 0 0 0 0>;
+ ieee80211-freq-limit = <5470000 5875000>;
+
+ nvmem-cells = <&eeprom_factory_1000>, <&macaddr_config_1c 3>;
+ nvmem-cell-names = "eeprom", "mac-address";
+ };
+ };
+};
+
+&pcie_phy {
+ status = "okay";
+};
+
+&pio {
+ pcie_pins: pcie-pins {
+ mux {
+ function = "pcie";
+ groups = "pcie_clk", "pcie_wake", "pcie_pereset";
+ };
+ };
+
+ spi_flash_pins: spi-flash-pins {
+ mux {
+ function = "spi";
+ groups = "spi0", "spi0_wp_hold";
+ };
+ conf-pu {
+ pins = "SPI2_CS", "SPI2_HOLD", "SPI2_WP";
+ drive-strength = <8>;
+ mediatek,pull-up-adv = <0>; /* bias-disable */
+ };
+ conf-pd {
+ pins = "SPI2_CLK", "SPI2_MOSI", "SPI2_MISO";
+ drive-strength = <8>;
+ mediatek,pull-down-adv = <0>; /* bias-disable */
+ };
+ };
+
+ wf_2g_5g_pins: wf_2g_5g-pins {
+ mux {
+ function = "wifi";
+ groups = "wf_2g", "wf_5g";
+ };
+ conf {
+ pins = "WF0_HB1", "WF0_HB2", "WF0_HB3", "WF0_HB4",
+ "WF0_HB0", "WF0_HB0_B", "WF0_HB5", "WF0_HB6",
+ "WF0_HB7", "WF0_HB8", "WF0_HB9", "WF0_HB10",
+ "WF0_TOP_CLK", "WF0_TOP_DATA", "WF1_HB1",
+ "WF1_HB2", "WF1_HB3", "WF1_HB4", "WF1_HB0",
+ "WF1_HB5", "WF1_HB6", "WF1_HB7", "WF1_HB8",
+ "WF1_TOP_CLK", "WF1_TOP_DATA";
+ drive-strength = <4>;
+ };
+ };
+};
+
+&ssusb {
+ vusb33-supply = <&reg_3p3v>;
+ vbus-supply = <&reg_5v>;
+ status = "okay";
+};
+
+&trng {
+ status = "okay";
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&usb_phy {
+ status = "okay";
+};
+
+&watchdog {
+ status = "okay";
+};
+
+&wifi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&wf_2g_5g_pins>;
+ ieee80211-freq-limit = <2400000 2500000>, <5170000 5350000>;
+ nvmem-cells = <&eeprom_factory_0>, <&macaddr_config_1c 2>;
+ nvmem-cell-names = "eeprom", "mac-address";
+ status = "okay";
+};
diff --git a/target/linux/mediatek/dts/mt7986a-zyxel-ex5601-t0-ubootmod.dts b/target/linux/mediatek/dts/mt7986a-zyxel-ex5601-t0-ubootmod.dts
index 62ce50ed23..d562243970 100644
--- a/target/linux/mediatek/dts/mt7986a-zyxel-ex5601-t0-ubootmod.dts
+++ b/target/linux/mediatek/dts/mt7986a-zyxel-ex5601-t0-ubootmod.dts
@@ -13,10 +13,16 @@
/ {
model = "Zyxel EX5601-T0 ubootmod";
compatible = "zyxel,ex5601-t0-ubootmod", "mediatek,mt7986a";
+
memory@40000000 {
device_type = "memory";
reg = <0x40000000 0x20000000>;
};
+
+ chosen {
+ bootargs-append = " root=/dev/fit0 rootwait";
+ rootdisk = <&ubi_rootdisk>;
+ };
};
&nand_partitions {
@@ -72,16 +78,23 @@
reg = <0x380000 0x0200000>;
read-only;
};
-
+
partition@540000 {
label = "zloader";
reg = <0x540000 0x0040000>;
read-only;
};
-
+
partition@580000 {
label = "ubi";
reg = <0x580000 0x1da80000>;
+ compatible = "linux,ubi";
+
+ volumes {
+ ubi_rootdisk: ubi-volume-fit {
+ volname = "fit";
+ };
+ };
};
};
diff --git a/target/linux/mediatek/dts/mt7986a-zyxel-ex5700-telenor.dts b/target/linux/mediatek/dts/mt7986a-zyxel-ex5700-telenor.dts
index 29961e528c..51147c1d81 100644
--- a/target/linux/mediatek/dts/mt7986a-zyxel-ex5700-telenor.dts
+++ b/target/linux/mediatek/dts/mt7986a-zyxel-ex5700-telenor.dts
@@ -8,7 +8,7 @@
#include "mt7986a.dtsi"
/ {
- model = "ZyXEL EX5700 (Telenor)";
+ model = "Zyxel EX5700 (Telenor)";
compatible = "zyxel,ex5700-telenor", "mediatek,mt7986a";
aliases {
@@ -158,11 +158,13 @@
phy5: phy@5 {
compatible = "ethernet-phy-ieee802.3-c45";
reg = <5>;
+ mxl,led-config = <0x3f0 0x330 0x0 0x0>;
};
phy6: phy@6 {
compatible = "ethernet-phy-ieee802.3-c45";
reg = <6>;
+ mxl,led-config = <0x3f0 0x330 0x0 0x0>;
};
switch: switch@1f {
diff --git a/target/linux/mediatek/files-6.6/arch/arm64/boot/dts/mediatek/mt7981-rfb-spim-nand.dtso b/target/linux/mediatek/files-6.6/arch/arm64/boot/dts/mediatek/mt7981-rfb-spim-nand.dtso
index 5b51dfd671..ab53f96cde 100644
--- a/target/linux/mediatek/files-6.6/arch/arm64/boot/dts/mediatek/mt7981-rfb-spim-nand.dtso
+++ b/target/linux/mediatek/files-6.6/arch/arm64/boot/dts/mediatek/mt7981-rfb-spim-nand.dtso
@@ -6,6 +6,11 @@
compatible = "mediatek,mt7981-rfb", "mediatek,mt7981";
fragment@0 {
+ target = <&chosen>;
+ rootdisk-spim-nand = <&ubi_rootdisk>;
+ };
+
+ fragment@1 {
target = <&spi0>;
__overlay__ {
status = "okay";
@@ -50,13 +55,20 @@
partition@580000 {
label = "ubi";
reg = <0x580000 0x4000000>;
+ compatible = "linux,ubi";
+
+ volumes {
+ ubi_rootdisk: ubi-volume-fit {
+ volname = "fit";
+ };
+ };
};
};
};
};
};
- fragment@1 {
+ fragment@2 {
target = <&wifi>;
__overlay__ {
mediatek,mtd-eeprom = <&factory 0x0>;
diff --git a/target/linux/mediatek/files-6.6/arch/arm64/boot/dts/mediatek/mt7981-rfb.dts b/target/linux/mediatek/files-6.6/arch/arm64/boot/dts/mediatek/mt7981-rfb.dts
index b2bb692956..791b56113a 100644
--- a/target/linux/mediatek/files-6.6/arch/arm64/boot/dts/mediatek/mt7981-rfb.dts
+++ b/target/linux/mediatek/files-6.6/arch/arm64/boot/dts/mediatek/mt7981-rfb.dts
@@ -15,8 +15,9 @@
serial0 = &uart0;
};
- chosen {
+ chosen: chosen {
stdout-path = "serial0:115200n8";
+ bootargs-append = " root=/dev/fit0 rootwait";
};
memory {
diff --git a/target/linux/mediatek/files-6.6/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-emmc.dtso b/target/linux/mediatek/files-6.6/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-emmc.dtso
index 4945185d69..cd266d6b0f 100644
--- a/target/linux/mediatek/files-6.6/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-emmc.dtso
+++ b/target/linux/mediatek/files-6.6/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-emmc.dtso
@@ -41,7 +41,7 @@
block-partition-env {
partname = "ubootenv";
nvmem-layout {
- compatible = "u-boot,env-layout";
+ compatible = "u-boot,env";
};
};
emmc_rootfs: block-partition-production {
diff --git a/target/linux/mediatek/files-6.6/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-sd.dtso b/target/linux/mediatek/files-6.6/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-sd.dtso
index 1f5e1491a4..c2ab424e3e 100644
--- a/target/linux/mediatek/files-6.6/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-sd.dtso
+++ b/target/linux/mediatek/files-6.6/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-sd.dtso
@@ -39,7 +39,7 @@
block-partition-env {
partname = "ubootenv";
nvmem-layout {
- compatible = "u-boot,env-layout";
+ compatible = "u-boot,env";
};
};
sd_rootfs: block-partition-production {
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 9ad068fe05..6a15dcff3d 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
@@ -1490,6 +1490,23 @@
compatible = "ethernet-phy-ieee802.3-c45";
reg = <15>;
phy-mode = "internal";
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ i2p5gbe_led0: i2p5gbe-led0@0 {
+ reg = <0>;
+ function = LED_FUNCTION_LAN;
+ status = "disabled";
+ };
+
+ i2p5gbe_led1: i2p5gbe-led1@1 {
+ reg = <1>;
+ function = LED_FUNCTION_LAN;
+ status = "disabled";
+ };
+ };
};
};
};
diff --git a/target/linux/mediatek/files-6.6/drivers/net/phy/mediatek-2p5ge.c b/target/linux/mediatek/files-6.6/drivers/net/phy/mediatek-2p5ge.c
deleted file mode 100644
index d1d01190ed..0000000000
--- a/target/linux/mediatek/files-6.6/drivers/net/phy/mediatek-2p5ge.c
+++ /dev/null
@@ -1,321 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-#include <linux/bitfield.h>
-#include <linux/firmware.h>
-#include <linux/module.h>
-#include <linux/nvmem-consumer.h>
-#include <linux/of_address.h>
-#include <linux/of_platform.h>
-#include <linux/pinctrl/consumer.h>
-#include <linux/phy.h>
-#include <linux/pm_domain.h>
-#include <linux/pm_runtime.h>
-
-#define MT7988_2P5GE_PMB "mediatek/mt7988/i2p5ge-phy-pmb.bin"
-
-#define MD32_EN BIT(0)
-#define PMEM_PRIORITY BIT(8)
-#define DMEM_PRIORITY BIT(16)
-
-#define BASE100T_STATUS_EXTEND 0x10
-#define BASE1000T_STATUS_EXTEND 0x11
-#define EXTEND_CTRL_AND_STATUS 0x16
-
-#define PHY_AUX_CTRL_STATUS 0x1d
-#define PHY_AUX_DPX_MASK GENMASK(5, 5)
-#define PHY_AUX_SPEED_MASK GENMASK(4, 2)
-
-/* Registers on MDIO_MMD_VEND1 */
-#define MTK_PHY_LINK_STATUS_MISC 0xa2
-#define MTK_PHY_FDX_ENABLE BIT(5)
-
-#define MTK_PHY_LPI_PCS_DSP_CTRL 0x121
-#define MTK_PHY_LPI_SIG_EN_LO_THRESH100_MASK GENMASK(12, 8)
-
-/* Registers on MDIO_MMD_VEND2 */
-#define MTK_PHY_LED0_ON_CTRL 0x24
-#define MTK_PHY_LED0_ON_LINK1000 BIT(0)
-#define MTK_PHY_LED0_ON_LINK100 BIT(1)
-#define MTK_PHY_LED0_ON_LINK10 BIT(2)
-#define MTK_PHY_LED0_ON_LINK2500 BIT(7)
-#define MTK_PHY_LED0_POLARITY BIT(14)
-
-#define MTK_PHY_LED1_ON_CTRL 0x26
-#define MTK_PHY_LED1_ON_FDX BIT(4)
-#define MTK_PHY_LED1_ON_HDX BIT(5)
-#define MTK_PHY_LED1_POLARITY BIT(14)
-
-#define MTK_EXT_PAGE_ACCESS 0x1f
-#define MTK_PHY_PAGE_STANDARD 0x0000
-#define MTK_PHY_PAGE_EXTENDED_52B5 0x52b5
-
-struct mtk_i2p5ge_phy_priv {
- bool fw_loaded;
-};
-
-enum {
- PHY_AUX_SPD_10 = 0,
- PHY_AUX_SPD_100,
- PHY_AUX_SPD_1000,
- PHY_AUX_SPD_2500,
-};
-
-static int mtk_2p5ge_phy_read_page(struct phy_device *phydev)
-{
- return __phy_read(phydev, MTK_EXT_PAGE_ACCESS);
-}
-
-static int mtk_2p5ge_phy_write_page(struct phy_device *phydev, int page)
-{
- return __phy_write(phydev, MTK_EXT_PAGE_ACCESS, page);
-}
-
-static int mt7988_2p5ge_phy_probe(struct phy_device *phydev)
-{
- struct mtk_i2p5ge_phy_priv *phy_priv;
-
- phy_priv = devm_kzalloc(&phydev->mdio.dev,
- sizeof(struct mtk_i2p5ge_phy_priv), GFP_KERNEL);
- if (!phy_priv)
- return -ENOMEM;
-
- phydev->priv = phy_priv;
-
- return 0;
-}
-
-static int mt7988_2p5ge_phy_config_init(struct phy_device *phydev)
-{
- int ret, i;
- const struct firmware *fw;
- struct device *dev = &phydev->mdio.dev;
- struct device_node *np;
- void __iomem *pmb_addr;
- void __iomem *md32_en_cfg_base;
- struct mtk_i2p5ge_phy_priv *phy_priv = phydev->priv;
- u16 reg;
- struct pinctrl *pinctrl;
-
- if (!phy_priv->fw_loaded) {
- np = of_find_compatible_node(NULL, NULL, "mediatek,2p5gphy-fw");
- if (!np)
- return -ENOENT;
- pmb_addr = of_iomap(np, 0);
- if (!pmb_addr)
- return -ENOMEM;
- md32_en_cfg_base = of_iomap(np, 1);
- if (!md32_en_cfg_base)
- return -ENOMEM;
-
- ret = request_firmware(&fw, MT7988_2P5GE_PMB, dev);
- if (ret) {
- dev_err(dev, "failed to load firmware: %s, ret: %d\n",
- MT7988_2P5GE_PMB, ret);
- return ret;
- }
-
- reg = readw(md32_en_cfg_base);
- if (reg & MD32_EN) {
- phy_set_bits(phydev, 0, BIT(15));
- usleep_range(10000, 11000);
- }
- phy_set_bits(phydev, 0, BIT(11));
-
- /* Write magic number to safely stall MCU */
- phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x800e, 0x1100);
- phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x800f, 0x00df);
-
- for (i = 0; i < fw->size - 1; i += 4)
- writel(*((uint32_t *)(fw->data + i)), pmb_addr + i);
- release_firmware(fw);
-
- writew(reg & ~MD32_EN, md32_en_cfg_base);
- writew(reg | MD32_EN, md32_en_cfg_base);
- phy_set_bits(phydev, 0, BIT(15));
- dev_info(dev, "Firmware loading/trigger ok.\n");
-
- phy_priv->fw_loaded = true;
- }
-
- /* Setup LED */
-
- /* Set polarity of led0 to active-high for BPI-R4 */
- phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED0_ON_CTRL,
- MTK_PHY_LED0_POLARITY);
-
- phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED0_ON_CTRL,
- MTK_PHY_LED0_ON_LINK10 |
- MTK_PHY_LED0_ON_LINK100 |
- MTK_PHY_LED0_ON_LINK1000 |
- MTK_PHY_LED0_ON_LINK2500);
- phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED1_ON_CTRL,
- MTK_PHY_LED1_ON_FDX | MTK_PHY_LED1_ON_HDX);
-
- pinctrl = devm_pinctrl_get_select(&phydev->mdio.dev, "i2p5gbe-led");
- if (IS_ERR(pinctrl)) {
- dev_err(&phydev->mdio.dev, "Fail to set LED pins!\n");
- return PTR_ERR(pinctrl);
- }
-
- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LPI_PCS_DSP_CTRL,
- MTK_PHY_LPI_SIG_EN_LO_THRESH100_MASK, 0);
-
- /* Enable 16-bit next page exchange bit if 1000-BT isn't advertizing */
- phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
- __phy_write(phydev, 0x11, 0xfbfa);
- __phy_write(phydev, 0x12, 0xc3);
- __phy_write(phydev, 0x10, 0x87f8);
- phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
-
- return 0;
-}
-
-static int mt7988_2p5ge_phy_config_aneg(struct phy_device *phydev)
-{
- bool changed = false;
- u32 adv;
- int ret;
-
- if (phydev->autoneg == AUTONEG_DISABLE) {
- /* Configure half duplex with genphy_setup_forced,
- * because genphy_c45_pma_setup_forced does not support.
- */
- return phydev->duplex != DUPLEX_FULL
- ? genphy_setup_forced(phydev)
- : genphy_c45_pma_setup_forced(phydev);
- }
-
- ret = genphy_c45_an_config_aneg(phydev);
- if (ret < 0)
- return ret;
- if (ret > 0)
- changed = true;
-
- adv = linkmode_adv_to_mii_ctrl1000_t(phydev->advertising);
- ret = phy_modify_changed(phydev, MII_CTRL1000,
- ADVERTISE_1000FULL | ADVERTISE_1000HALF,
- adv);
- if (ret < 0)
- return ret;
- if (ret > 0)
- changed = true;
-
- return genphy_c45_check_and_restart_aneg(phydev, changed);
-}
-
-static int mt7988_2p5ge_phy_get_features(struct phy_device *phydev)
-{
- int ret;
-
- ret = genphy_read_abilities(phydev);
- if (ret)
- return ret;
-
- /* We don't support HDX at MAC layer on mt7988.
- * So mask phy's HDX capabilities, too.
- */
- linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT,
- phydev->supported);
- linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT,
- phydev->supported);
- linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
- phydev->supported);
- linkmode_set_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
- phydev->supported);
- linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, phydev->supported);
-
- return 0;
-}
-
-static int mt7988_2p5ge_phy_read_status(struct phy_device *phydev)
-{
- int ret;
-
- ret = genphy_update_link(phydev);
- if (ret)
- return ret;
-
- phydev->speed = SPEED_UNKNOWN;
- phydev->duplex = DUPLEX_UNKNOWN;
- phydev->pause = 0;
- phydev->asym_pause = 0;
-
- if (phydev->autoneg == AUTONEG_ENABLE && phydev->autoneg_complete) {
- ret = genphy_c45_read_lpa(phydev);
- if (ret < 0)
- return ret;
-
- /* Read the link partner's 1G advertisement */
- ret = phy_read(phydev, MII_STAT1000);
- if (ret < 0)
- return ret;
- mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, ret);
- } else if (phydev->autoneg == AUTONEG_DISABLE) {
- linkmode_zero(phydev->lp_advertising);
- }
-
- ret = phy_read(phydev, PHY_AUX_CTRL_STATUS);
- if (ret < 0)
- return ret;
-
- switch (FIELD_GET(PHY_AUX_SPEED_MASK, ret)) {
- case PHY_AUX_SPD_10:
- phydev->speed = SPEED_10;
- break;
- case PHY_AUX_SPD_100:
- phydev->speed = SPEED_100;
- break;
- case PHY_AUX_SPD_1000:
- phydev->speed = SPEED_1000;
- break;
- case PHY_AUX_SPD_2500:
- phydev->speed = SPEED_2500;
- break;
- }
-
- ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LINK_STATUS_MISC);
- if (ret < 0)
- return ret;
-
- phydev->duplex = (ret & MTK_PHY_FDX_ENABLE) ? DUPLEX_FULL : DUPLEX_HALF;
- /* FIXME: The current firmware always enables rate adaptation mode. */
- phydev->rate_matching = RATE_MATCH_PAUSE;
-
- return 0;
-}
-
-static int mt7988_2p5ge_phy_get_rate_matching(struct phy_device *phydev,
- phy_interface_t iface)
-{
- return RATE_MATCH_PAUSE;
-}
-
-static struct phy_driver mtk_gephy_driver[] = {
- {
- PHY_ID_MATCH_MODEL(0x00339c11),
- .name = "MediaTek MT798x 2.5GbE PHY",
- .probe = mt7988_2p5ge_phy_probe,
- .config_init = mt7988_2p5ge_phy_config_init,
- .config_aneg = mt7988_2p5ge_phy_config_aneg,
- .get_features = mt7988_2p5ge_phy_get_features,
- .read_status = mt7988_2p5ge_phy_read_status,
- .get_rate_matching = mt7988_2p5ge_phy_get_rate_matching,
- .suspend = genphy_suspend,
- .resume = genphy_resume,
- .read_page = mtk_2p5ge_phy_read_page,
- .write_page = mtk_2p5ge_phy_write_page,
- },
-};
-
-module_phy_driver(mtk_gephy_driver);
-
-static struct mdio_device_id __maybe_unused mtk_2p5ge_phy_tbl[] = {
- { PHY_ID_MATCH_VENDOR(0x00339c00) },
- { }
-};
-
-MODULE_DESCRIPTION("MediaTek 2.5Gb Ethernet PHY driver");
-MODULE_AUTHOR("SkyLake Huang <SkyLake.Huang@mediatek.com>");
-MODULE_LICENSE("GPL");
-
-MODULE_DEVICE_TABLE(mdio, mtk_2p5ge_phy_tbl);
-MODULE_FIRMWARE(MT7988_2P5GE_PMB);
diff --git a/target/linux/mediatek/files/block/partitions/fit.c b/target/linux/mediatek/files/block/partitions/fit.c
deleted file mode 100644
index 01b0f42c7c..0000000000
--- a/target/linux/mediatek/files/block/partitions/fit.c
+++ /dev/null
@@ -1,307 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * fs/partitions/fit.c
- * Copyright (C) 2021 Daniel Golle
- *
- * headers extracted from U-Boot mkimage sources
- * (C) Copyright 2008 Semihalf
- * (C) Copyright 2000-2005
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * based on existing partition parsers
- * Copyright (C) 1991-1998 Linus Torvalds
- * Re-organised Feb 1998 Russell King
- */
-
-#define pr_fmt(fmt) fmt
-
-#include <linux/types.h>
-#include <linux/of.h>
-#include <linux/of_device.h>
-#include <linux/of_fdt.h>
-#include <linux/libfdt.h>
-#include <linux/version.h>
-
-#include "check.h"
-
-#define FIT_IMAGES_PATH "/images"
-#define FIT_CONFS_PATH "/configurations"
-
-/* hash/signature/key node */
-#define FIT_HASH_NODENAME "hash"
-#define FIT_ALGO_PROP "algo"
-#define FIT_VALUE_PROP "value"
-#define FIT_IGNORE_PROP "uboot-ignore"
-#define FIT_SIG_NODENAME "signature"
-#define FIT_KEY_REQUIRED "required"
-#define FIT_KEY_HINT "key-name-hint"
-
-/* cipher node */
-#define FIT_CIPHER_NODENAME "cipher"
-#define FIT_ALGO_PROP "algo"
-
-/* image node */
-#define FIT_DATA_PROP "data"
-#define FIT_DATA_POSITION_PROP "data-position"
-#define FIT_DATA_OFFSET_PROP "data-offset"
-#define FIT_DATA_SIZE_PROP "data-size"
-#define FIT_TIMESTAMP_PROP "timestamp"
-#define FIT_DESC_PROP "description"
-#define FIT_ARCH_PROP "arch"
-#define FIT_TYPE_PROP "type"
-#define FIT_OS_PROP "os"
-#define FIT_COMP_PROP "compression"
-#define FIT_ENTRY_PROP "entry"
-#define FIT_LOAD_PROP "load"
-
-/* configuration node */
-#define FIT_KERNEL_PROP "kernel"
-#define FIT_FILESYSTEM_PROP "filesystem"
-#define FIT_RAMDISK_PROP "ramdisk"
-#define FIT_FDT_PROP "fdt"
-#define FIT_LOADABLE_PROP "loadables"
-#define FIT_DEFAULT_PROP "default"
-#define FIT_SETUP_PROP "setup"
-#define FIT_FPGA_PROP "fpga"
-#define FIT_FIRMWARE_PROP "firmware"
-#define FIT_STANDALONE_PROP "standalone"
-
-#define FIT_MAX_HASH_LEN HASH_MAX_DIGEST_SIZE
-
-#define MIN_FREE_SECT 16
-#define REMAIN_VOLNAME "rootfs_data"
-
-int parse_fit_partitions(struct parsed_partitions *state, u64 fit_start_sector, u64 sectors, int *slot, int add_remain)
-{
- struct block_device *bdev = state->disk->part0;
- struct address_space *mapping = bdev->bd_inode->i_mapping;
- struct page *page;
- void *fit, *init_fit;
- struct partition_meta_info *info;
- char tmp[sizeof(info->volname)];
- u64 dsize, dsectors, imgmaxsect = 0;
- u32 size, image_pos, image_len;
- const u32 *image_offset_be, *image_len_be, *image_pos_be;
- int ret = 1, node, images, config;
- const char *image_name, *image_type, *image_description, *config_default,
- *config_description, *config_loadables, *bootconf_c;
- int image_name_len, image_type_len, image_description_len, config_default_len,
- config_description_len, config_loadables_len, bootconf_len;
- sector_t start_sect, nr_sects;
- size_t label_min;
- struct device_node *np = NULL;
- char *bootconf = NULL, *bootconf_term;
- const char *loadable;
- const char *select_rootfs = NULL;
- bool found;
- int loadables_rem_len, loadable_len;
-
- if (fit_start_sector % (1<<(PAGE_SHIFT - SECTOR_SHIFT)))
- return -ERANGE;
-
- page = read_mapping_page(mapping, fit_start_sector >> (PAGE_SHIFT - SECTOR_SHIFT), NULL);
- if (IS_ERR(page))
- return -EFAULT;
-
- if (PageError(page))
- return -EFAULT;
-
- init_fit = page_address(page);
-
- if (!init_fit) {
- put_page(page);
- return -EFAULT;
- }
-
- if (fdt_check_header(init_fit)) {
- put_page(page);
- return 0;
- }
-
- dsectors = get_capacity(bdev->bd_disk);
- if (sectors)
- dsectors = (dsectors>sectors)?sectors:dsectors;
-
- dsize = dsectors << SECTOR_SHIFT;
- size = fdt_totalsize(init_fit);
-
- /* silently skip non-external-data legacy FIT images */
- if (size > PAGE_SIZE) {
- put_page(page);
- return 0;
- }
-
- if (size >= dsize) {
- state->access_beyond_eod = 1;
- put_page(page);
- return -EFBIG;
- }
-
- fit = kmemdup(init_fit, size, GFP_KERNEL);
- put_page(page);
- if (!fit)
- return -ENOMEM;
-
- np = of_find_node_by_path("/chosen");
- if (np) {
- /* new fitblk driver should take over if /chosen/rootdisk is defined */
- if (of_get_property(np, "rootdisk", NULL))
- return 0;
-
- bootconf_c = of_get_property(np, "u-boot,bootconf", &bootconf_len);
- if (bootconf_c && bootconf_len)
- bootconf = kmemdup_nul(bootconf_c, bootconf_len, GFP_KERNEL);
- }
-
- if (bootconf) {
- bootconf_term = strchr(bootconf, '#');
- if (bootconf_term)
- *bootconf_term = '\0';
- }
-
- config = fdt_path_offset(fit, FIT_CONFS_PATH);
- if (config < 0) {
- printk(KERN_ERR "FIT: Cannot find %s node: %d\n", FIT_CONFS_PATH, config);
- ret = -ENOENT;
- goto ret_out;
- }
-
- config_default = fdt_getprop(fit, config, FIT_DEFAULT_PROP, &config_default_len);
-
- if (!config_default && !bootconf) {
- printk(KERN_ERR "FIT: Cannot find default configuration\n");
- ret = -ENOENT;
- goto ret_out;
- }
-
- node = fdt_subnode_offset(fit, config, bootconf?:config_default);
- if (node < 0) {
- printk(KERN_ERR "FIT: Cannot find %s node: %d\n", bootconf?:config_default, node);
- ret = -ENOENT;
- goto ret_out;
- }
-
- config_description = fdt_getprop(fit, node, FIT_DESC_PROP, &config_description_len);
- config_loadables = fdt_getprop(fit, node, FIT_LOADABLE_PROP, &config_loadables_len);
-
- printk(KERN_DEBUG "FIT: %s configuration: \"%s\"%s%s%s\n",
- bootconf?"Selected":"Default", bootconf?:config_default,
- config_description?" (":"", config_description?:"", config_description?")":"");
-
- if (!config_loadables || !config_loadables_len) {
- printk(KERN_ERR "FIT: No loadables configured in \"%s\"\n", bootconf?:config_default);
- ret = -ENOENT;
- goto ret_out;
- }
-
- images = fdt_path_offset(fit, FIT_IMAGES_PATH);
- if (images < 0) {
- printk(KERN_ERR "FIT: Cannot find %s node: %d\n", FIT_IMAGES_PATH, images);
- ret = -EINVAL;
- goto ret_out;
- }
-
- fdt_for_each_subnode(node, fit, images) {
- image_name = fdt_get_name(fit, node, &image_name_len);
- image_type = fdt_getprop(fit, node, FIT_TYPE_PROP, &image_type_len);
- image_offset_be = fdt_getprop(fit, node, FIT_DATA_OFFSET_PROP, NULL);
- image_pos_be = fdt_getprop(fit, node, FIT_DATA_POSITION_PROP, NULL);
- image_len_be = fdt_getprop(fit, node, FIT_DATA_SIZE_PROP, NULL);
- if (!image_name || !image_type || !image_len_be)
- continue;
-
- image_len = be32_to_cpu(*image_len_be);
- if (!image_len)
- continue;
-
- if (image_offset_be)
- image_pos = be32_to_cpu(*image_offset_be) + size;
- else if (image_pos_be)
- image_pos = be32_to_cpu(*image_pos_be);
- else
- continue;
-
- image_description = fdt_getprop(fit, node, FIT_DESC_PROP, &image_description_len);
-
- printk(KERN_DEBUG "FIT: %16s sub-image 0x%08x..0x%08x \"%s\" %s%s%s\n",
- image_type, image_pos, image_pos + image_len - 1, image_name,
- image_description?"(":"", image_description?:"", image_description?") ":"");
-
- if (strcmp(image_type, FIT_FILESYSTEM_PROP))
- continue;
-
- /* check if sub-image is part of configured loadables */
- found = false;
- loadable = config_loadables;
- loadables_rem_len = config_loadables_len;
- while (loadables_rem_len > 1) {
- loadable_len = strnlen(loadable, loadables_rem_len - 1) + 1;
- loadables_rem_len -= loadable_len;
- if (!strncmp(image_name, loadable, loadable_len)) {
- found = true;
- break;
- }
- loadable += loadable_len;
- }
- if (!found)
- continue;
-
- if (image_pos & ((1 << PAGE_SHIFT)-1)) {
- printk(KERN_ERR "FIT: image %s start not aligned to page boundaries, skipping\n", image_name);
- continue;
- }
-
- if (image_len & ((1 << PAGE_SHIFT)-1)) {
- printk(KERN_ERR "FIT: sub-image %s end not aligned to page boundaries, skipping\n", image_name);
- continue;
- }
-
- start_sect = image_pos >> SECTOR_SHIFT;
- nr_sects = image_len >> SECTOR_SHIFT;
- imgmaxsect = (imgmaxsect < (start_sect + nr_sects))?(start_sect + nr_sects):imgmaxsect;
-
- if (start_sect + nr_sects > dsectors) {
- state->access_beyond_eod = 1;
- continue;
- }
-
- put_partition(state, ++(*slot), fit_start_sector + start_sect, nr_sects);
- state->parts[*slot].flags = ADDPART_FLAG_READONLY;
- state->parts[*slot].has_info = true;
- info = &state->parts[*slot].info;
-
- label_min = min_t(int, sizeof(info->volname) - 1, image_name_len);
- strncpy(info->volname, image_name, label_min);
- info->volname[label_min] = '\0';
-
- snprintf(tmp, sizeof(tmp), "(%s)", info->volname);
- strlcat(state->pp_buf, tmp, PAGE_SIZE);
-
- /* Mark first loadable listed to be mounted as rootfs */
- if (!strcmp(image_name, config_loadables)) {
- select_rootfs = image_name;
- state->parts[*slot].flags |= ADDPART_FLAG_ROOTDEV;
- }
- }
-
- if (select_rootfs)
- printk(KERN_DEBUG "FIT: selecting configured loadable \"%s\" to be root filesystem\n", select_rootfs);
-
- if (add_remain && (imgmaxsect + MIN_FREE_SECT) < dsectors) {
- put_partition(state, ++(*slot), fit_start_sector + imgmaxsect, dsectors - imgmaxsect);
- state->parts[*slot].flags = 0;
- info = &state->parts[*slot].info;
- strcpy(info->volname, REMAIN_VOLNAME);
- snprintf(tmp, sizeof(tmp), "(%s)", REMAIN_VOLNAME);
- strlcat(state->pp_buf, tmp, PAGE_SIZE);
- }
-ret_out:
- kfree(bootconf);
- kfree(fit);
- return ret;
-}
-
-int fit_partition(struct parsed_partitions *state) {
- int slot = 0;
- return parse_fit_partitions(state, 0, 0, &slot, 0);
-}
diff --git a/target/linux/mediatek/filogic/base-files/etc/board.d/01_leds b/target/linux/mediatek/filogic/base-files/etc/board.d/01_leds
index 16d8617c54..82f61dd5d9 100644
--- a/target/linux/mediatek/filogic/base-files/etc/board.d/01_leds
+++ b/target/linux/mediatek/filogic/base-files/etc/board.d/01_leds
@@ -6,6 +6,11 @@ board=$(board_name)
board_config_update
case $board in
+abt,asr3000)
+ ucidef_set_led_netdev "wan" "WAN" "green:wan" "eth1"
+ ucidef_set_led_netdev "wlan2g" "WLAN2G" "green:wlan-2ghz" "phy0-ap0"
+ ucidef_set_led_netdev "wlan5g" "WLAN5G" "green:wlan-5ghz" "phy1-ap0"
+ ;;
confiabits,mt7981)
ucidef_set_led_netdev "lan1" "lan1" "blue:lan-1" "lan1" "link tx rx"
ucidef_set_led_netdev "lan2" "lan2" "blue:lan-2" "lan2" "link tx rx"
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 1a210810bc..1eecfa81e3 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
@@ -11,6 +11,13 @@ mediatek_setup_interfaces()
acelink,ew-7886cax)
ucidef_set_interface_lan "eth0" "dhcp"
;;
+ abt,asr3000|\
+ cmcc,rax3000m|\
+ h3c,magic-nx30-pro|\
+ nokia,ea0326gmp|\
+ zbtlink,zbt-z8103ax)
+ ucidef_set_interfaces_lan_wan "lan1 lan2 lan3" eth1
+ ;;
acer,predator-w6)
ucidef_set_interfaces_lan_wan "lan1 lan2 lan3 game" eth1
;;
@@ -46,12 +53,6 @@ mediatek_setup_interfaces()
bananapi,bpi-r4-poe)
ucidef_set_interfaces_lan_wan "lan1 lan2 lan3 eth1" "wan eth2"
;;
- cmcc,rax3000m|\
- h3c,magic-nx30-pro|\
- nokia,ea0326gmp|\
- zbtlink,zbt-z8103ax)
- ucidef_set_interfaces_lan_wan "lan1 lan2 lan3" eth1
- ;;
comfast,cf-e393ax)
ucidef_set_interfaces_lan_wan "lan1" eth1
;;
@@ -70,7 +71,8 @@ mediatek_setup_interfaces()
;;
glinet,gl-mt6000|\
tplink,tl-xdr4288|\
- tplink,tl-xdr6088)
+ tplink,tl-xdr6088|\
+ tplink,tl-xtr8488)
ucidef_set_interfaces_lan_wan "lan1 lan2 lan3 lan4 lan5" eth1
;;
mediatek,mt7986a-rfb)
@@ -80,11 +82,12 @@ mediatek_setup_interfaces()
ucidef_set_interfaces_lan_wan "lan0 lan1 lan2 lan3" eth1
;;
mediatek,mt7988a-rfb)
- ucidef_set_interfaces_lan_wan "lan0 lan1 lan2 lan3 eth1" eth2
+ ucidef_set_interfaces_lan_wan "lan0 lan1 lan2 lan3 eth2" eth1
;;
mercusys,mr90x-v1)
ucidef_set_interfaces_lan_wan "lan0 lan1 lan2" eth1
;;
+ cudy,ap3000outdoor-v1|\
cudy,re3000-v1|\
netgear,wax220|\
ubnt,unifi-6-plus|\
@@ -134,15 +137,6 @@ mediatek_setup_macs()
bananapi,bpi-r4)
wan_mac=$(macaddr_add $(cat /sys/class/net/eth0/address) 1)
;;
- cmcc,rax3000m)
- case "$(cmdline_get_var root)" in
- /dev/mmc*)
- wan_mac=$(mmc_get_mac_binary factory 0x2a)
- lan_mac=$(mmc_get_mac_binary factory 0x24)
- label_mac=$wan_mac
- ;;
- esac
- ;;
h3c,magic-nx30-pro)
wan_mac=$(mtd_get_mac_ascii pdt_data_1 ethaddr)
lan_mac=$(macaddr_add "$wan_mac" 1)
diff --git a/target/linux/mediatek/filogic/base-files/etc/hotplug.d/firmware/11-mt76-caldata b/target/linux/mediatek/filogic/base-files/etc/hotplug.d/firmware/11-mt76-caldata
index 920a16d05d..c6900e6ebd 100644
--- a/target/linux/mediatek/filogic/base-files/etc/hotplug.d/firmware/11-mt76-caldata
+++ b/target/linux/mediatek/filogic/base-files/etc/hotplug.d/firmware/11-mt76-caldata
@@ -24,13 +24,6 @@ case "$FIRMWARE" in
;;
"mediatek/mt7981_eeprom_mt7976_dbdc.bin")
case "$board" in
- cmcc,rax3000m)
- case "$(cmdline_get_var root)" in
- /dev/mmc*)
- caldata_extract_mmc "factory" 0x0 0x1000
- ;;
- esac
- ;;
ubnt,unifi-6-plus)
caldata_extract_mmc "factory" 0x0 0x1000
;;
diff --git a/target/linux/mediatek/filogic/base-files/etc/hotplug.d/ieee80211/11_fix_wifi_mac b/target/linux/mediatek/filogic/base-files/etc/hotplug.d/ieee80211/11_fix_wifi_mac
index 942facee87..ff9e9f881c 100644
--- a/target/linux/mediatek/filogic/base-files/etc/hotplug.d/ieee80211/11_fix_wifi_mac
+++ b/target/linux/mediatek/filogic/base-files/etc/hotplug.d/ieee80211/11_fix_wifi_mac
@@ -10,6 +10,13 @@ PHYNBR=${DEVPATH##*/phy}
board=$(board_name)
case "$board" in
+ abt,asr3000)
+ # Originally, phy1 is phy0 mac with LA bit set. However, this would conflict
+ # addresses on multiple VIFs with the other radio. Use label mac to set LA bit.
+ addr=$(cat /sys/class/net/eth1/address)
+ [ "$PHYNBR" = "0" ] && macaddr_add $addr 1 > /sys${DEVPATH}/macaddress
+ [ "$PHYNBR" = "1" ] && macaddr_setbit_la $addr > /sys${DEVPATH}/macaddress
+ ;;
acer,predator-w6)
key_path="/var/qcidata/data"
[ "$PHYNBR" = "0" ] && cat $key_path/2gMAC > /sys${DEVPATH}/macaddress
@@ -55,15 +62,8 @@ case "$board" in
[ "$PHYNBR" = "1" ] && macaddr_setbit_la $(macaddr_add $addr 2) > /sys${DEVPATH}/macaddress
;;
cmcc,rax3000m)
- case "$(cmdline_get_var root)" in
- /dev/mmc*)
- addr=$(mmc_get_mac_binary factory 0xa)
- ;;
- *)
- addr=$(mtd_get_mac_binary factory 0xa)
- ;;
- esac
- [ "$PHYNBR" = "1" ] && echo "$addr" > /sys${DEVPATH}/macaddress
+ addr=$(cat /sys/class/net/eth0/address)
+ [ "$PHYNBR" = "1" ] && macaddr_add $addr -1 > /sys${DEVPATH}/macaddress
;;
comfast,cf-e393ax)
addr=$(mtd_get_mac_binary "Factory" 0x8000)
@@ -75,6 +75,7 @@ case "$board" in
[ "$PHYNBR" = "0" ] && echo "$addr" > /sys${DEVPATH}/macaddress
[ "$PHYNBR" = "1" ] && macaddr_setbit_la $(macaddr_add $addr 1) > /sys${DEVPATH}/macaddress
;;
+ cudy,ap3000outdoor-v1|\
cudy,m3000-v1|\
cudy,wr3000-v1)
addr=$(mtd_get_mac_binary bdinfo 0xde00)
@@ -159,6 +160,9 @@ case "$board" in
tplink,tl-xdr6088)
[ "$PHYNBR" = "0" ] && get_mac_label > /sys${DEVPATH}/macaddress
;;
+ tplink,tl-xtr8488)
+ [ "$PHYNBR" = "1" ] && get_mac_label > /sys${DEVPATH}/macaddress
+ ;;
ubnt,unifi-6-plus)
addr=$(mtd_get_mac_binary EEPROM 0x6)
[ "$PHYNBR" = "0" ] && echo "$addr" > /sys${DEVPATH}/macaddress
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 2fed8a0ab5..bf4919653f 100755
--- a/target/linux/mediatek/filogic/base-files/lib/upgrade/platform.sh
+++ b/target/linux/mediatek/filogic/base-files/lib/upgrade/platform.sh
@@ -64,6 +64,31 @@ platform_do_upgrade() {
local board=$(board_name)
case "$board" in
+ abt,asr3000|\
+ bananapi,bpi-r3|\
+ bananapi,bpi-r3-mini|\
+ bananapi,bpi-r4|\
+ bananapi,bpi-r4-poe|\
+ cmcc,rax3000m|\
+ h3c,magic-nx30-pro|\
+ jcg,q30-pro|\
+ jdcloud,re-cp-03|\
+ mediatek,mt7981-rfb|\
+ mediatek,mt7988a-rfb|\
+ nokia,ea0326gmp|\
+ openwrt,one|\
+ netcore,n60|\
+ qihoo,360t7|\
+ tplink,tl-xdr4288|\
+ tplink,tl-xdr6086|\
+ tplink,tl-xdr6088|\
+ tplink,tl-xtr8488|\
+ xiaomi,mi-router-ax3000t-ubootmod|\
+ xiaomi,redmi-router-ax6000-ubootmod|\
+ xiaomi,mi-router-wr30u-ubootmod|\
+ zyxel,ex5601-t0-ubootmod)
+ fit_do_upgrade "$1"
+ ;;
acer,predator-w6|\
smartrg,sdg-8612|\
smartrg,sdg-8614|\
@@ -82,43 +107,6 @@ platform_do_upgrade() {
CI_KERNPART="linux"
nand_do_upgrade "$1"
;;
- bananapi,bpi-r3|\
- bananapi,bpi-r3-mini|\
- bananapi,bpi-r4|\
- bananapi,bpi-r4-poe|\
- jdcloud,re-cp-03|\
- mediatek,mt7988a-rfb|\
- openwrt,one)
- [ -e /dev/fit0 ] && fitblk /dev/fit0
- [ -e /dev/fitrw ] && fitblk /dev/fitrw
- bootdev="$(fitblk_get_bootdev)"
- case "$bootdev" in
- mmcblk*)
- EMMC_KERN_DEV="/dev/$bootdev"
- emmc_do_upgrade "$1"
- ;;
- mtdblock*)
- PART_NAME="/dev/mtd${bootdev:8}"
- default_do_upgrade "$1"
- ;;
- ubiblock*)
- CI_KERNPART="fit"
- nand_do_upgrade "$1"
- ;;
- esac
- ;;
- cmcc,rax3000m)
- case "$(cmdline_get_var root)" in
- /dev/mmc*)
- CI_KERNPART="production"
- emmc_do_upgrade "$1"
- ;;
- *)
- CI_KERNPART="fit"
- nand_do_upgrade "$1"
- ;;
- esac
- ;;
cudy,re3000-v1|\
cudy,wr3000-v1|\
yuncore,ax835)
@@ -132,31 +120,11 @@ platform_do_upgrade() {
CI_ROOTPART="rootfs"
emmc_do_upgrade "$1"
;;
- h3c,magic-nx30-pro|\
- jcg,q30-pro|\
- mediatek,mt7981-rfb|\
- netcore,n60|\
- qihoo,360t7|\
- xiaomi,mi-router-ax3000t-ubootmod|\
- xiaomi,mi-router-wr30u-ubootmod)
- CI_KERNPART="fit"
- nand_do_upgrade "$1"
- ;;
mercusys,mr90x-v1|\
tplink,re6000xd)
CI_UBIPART="ubi0"
nand_do_upgrade "$1"
;;
- nokia,ea0326gmp|\
- tplink,tl-xdr4288|\
- tplink,tl-xdr6086|\
- tplink,tl-xdr6088|\
- xiaomi,redmi-router-ax6000-ubootmod)
- [ -e /dev/fit0 ] && fitblk /dev/fit0
- [ -e /dev/fitrw ] && fitblk /dev/fitrw
- CI_KERNPART="fit"
- nand_do_upgrade "$1"
- ;;
ubnt,unifi-6-plus)
CI_KERNPART="kernel0"
EMMC_ROOT_DEV="$(cmdline_get_var root)"
@@ -169,11 +137,6 @@ platform_do_upgrade() {
CI_ROOT_UBIPART=ubi
nand_do_upgrade "$1"
;;
- zyxel,ex5601-t0-ubootmod)
- CI_KERNPART="fit"
- CI_ROOTPART="ubi_rootfs"
- nand_do_upgrade "$1"
- ;;
unielec,u7981-01*)
local rootdev="$(cmdline_get_var root)"
rootdev="${rootdev##*/}"
@@ -228,22 +191,14 @@ platform_check_image() {
platform_copy_config() {
case "$(board_name)" in
- cmcc,rax3000m)
- case "$(cmdline_get_var root)" in
- /dev/mmc*)
- emmc_copy_config
- ;;
- esac
- ;;
bananapi,bpi-r3|\
bananapi,bpi-r3-mini|\
bananapi,bpi-r4|\
- bananapi,bpi-r4-poe)
- case "$(fitblk_get_bootdev)" in
- mmcblk*)
+ bananapi,bpi-r4-poe|\
+ cmcc,rax3000m)
+ if [ "$CI_METHOD" = "emmc" ]; then
emmc_copy_config
- ;;
- esac
+ fi
;;
acer,predator-w6|\
glinet,gl-mt2500|\
diff --git a/target/linux/mediatek/filogic/config-6.6 b/target/linux/mediatek/filogic/config-6.6
index 6d9d42853b..818bcfa081 100644
--- a/target/linux/mediatek/filogic/config-6.6
+++ b/target/linux/mediatek/filogic/config-6.6
@@ -158,7 +158,6 @@ CONFIG_EINT_MTK=y
CONFIG_EXCLUSIVE_SYSTEM_RAM=y
CONFIG_EXT4_FS=y
CONFIG_F2FS_FS=y
-CONFIG_FIT_PARTITION=y
CONFIG_FIXED_PHY=y
CONFIG_FIX_EARLYCON_MEM=y
CONFIG_FRAME_POINTER=y
@@ -240,7 +239,7 @@ CONFIG_MAXLINEAR_GPHY=y
CONFIG_MDIO_BUS=y
CONFIG_MDIO_DEVICE=y
CONFIG_MDIO_DEVRES=y
-CONFIG_MEDIATEK_2P5G_PHY=y
+CONFIG_MEDIATEK_2P5GE_PHY=y
CONFIG_MEDIATEK_GE_PHY=y
CONFIG_MEDIATEK_GE_SOC_PHY=y
CONFIG_MEDIATEK_WATCHDOG=y
diff --git a/target/linux/mediatek/image/filogic.mk b/target/linux/mediatek/image/filogic.mk
index 94b3098b3d..e21794600d 100644
--- a/target/linux/mediatek/image/filogic.mk
+++ b/target/linux/mediatek/image/filogic.mk
@@ -105,6 +105,30 @@ define Build/cetron-header
rm $@.tmp
endef
+define Device/abt_asr3000
+ DEVICE_VENDOR := ABT
+ DEVICE_MODEL := ASR3000
+ DEVICE_DTS := mt7981b-abt-asr3000
+ DEVICE_DTS_DIR := ../dts
+ DEVICE_PACKAGES := kmod-mt7915e kmod-mt7981-firmware mt7981-wo-firmware
+ UBINIZE_OPTS := -E 5
+ BLOCKSIZE := 128k
+ PAGESIZE := 2048
+ KERNEL_IN_UBI := 1
+ UBOOTENV_IN_UBI := 1
+ IMAGES := sysupgrade.itb
+ KERNEL_INITRAMFS_SUFFIX := -recovery.itb
+ KERNEL := kernel-bin | gzip
+ KERNEL_INITRAMFS := kernel-bin | lzma | \
+ fit lzma $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb with-initrd | pad-to 64k
+ IMAGE/sysupgrade.itb := append-kernel | \
+ fit gzip $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb external-static-with-rootfs | append-metadata
+ ARTIFACTS := preloader.bin bl31-uboot.fip
+ ARTIFACT/preloader.bin := mt7981-bl2 spim-nand-ddr3
+ ARTIFACT/bl31-uboot.fip := mt7981-bl31-uboot abt_asr3000
+endef
+TARGET_DEVICES += abt_asr3000
+
define Device/acelink_ew-7886cax
DEVICE_VENDOR := Acelink
DEVICE_MODEL := EW-7886CAX
@@ -444,7 +468,7 @@ endef
TARGET_DEVICES += cmcc_rax3000m
define Device/comfast_cf-e393ax
- DEVICE_VENDOR := Comfast
+ DEVICE_VENDOR := COMFAST
DEVICE_MODEL := CF-E393AX
DEVICE_DTS := mt7981a-comfast-cf-e393ax
DEVICE_DTS_DIR := ../dts
@@ -483,6 +507,23 @@ define Device/confiabits_mt7981
endef
TARGET_DEVICES += confiabits_mt7981
+define Device/cudy_ap3000outdoor-v1
+ DEVICE_VENDOR := Cudy
+ DEVICE_MODEL := AP3000 Outdoor
+ DEVICE_VARIANT := v1
+ DEVICE_DTS := mt7981b-cudy-ap3000outdoor-v1
+ DEVICE_DTS_DIR := ../dts
+ SUPPORTED_DEVICES += R51
+ UBINIZE_OPTS := -E 5
+ BLOCKSIZE := 128k
+ PAGESIZE := 2048
+ IMAGE_SIZE := 65536k
+ KERNEL_IN_UBI := 1
+ IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata
+ DEVICE_PACKAGES := kmod-mt7915e kmod-mt7981-firmware mt7981-wo-firmware
+endef
+TARGET_DEVICES += cudy_ap3000outdoor-v1
+
define Device/cudy_m3000-v1
DEVICE_VENDOR := Cudy
DEVICE_MODEL := M3000
@@ -1143,9 +1184,19 @@ define Device/tplink_tl-xdr6088
endef
TARGET_DEVICES += tplink_tl-xdr6088
+define Device/tplink_tl-xtr8488
+ DEVICE_MODEL := TL-XTR8488
+ DEVICE_DTS := mt7986a-tplink-tl-xtr8488
+ $(call Device/tplink_tl-xdr-common)
+ DEVICE_PACKAGES += kmod-mt7915-firmware
+ ARTIFACT/preloader.bin := mt7986-bl2 spim-nand-ddr4
+ ARTIFACT/bl31-uboot.fip := mt7986-bl31-uboot tplink_tl-xtr8488
+endef
+TARGET_DEVICES += tplink_tl-xtr8488
+
define Device/ubnt_unifi-6-plus
DEVICE_VENDOR := Ubiquiti
- DEVICE_MODEL := UniFi 6 Plus
+ DEVICE_MODEL := UniFi U6+
DEVICE_DTS := mt7981a-ubnt-unifi-6-plus
DEVICE_DTS_DIR := ../dts
DEVICE_PACKAGES := kmod-mt7915e kmod-mt7981-firmware mt7981-wo-firmware e2fsprogs f2fsck mkf2fs fdisk partx-utils
@@ -1427,7 +1478,7 @@ endef
TARGET_DEVICES += zyxel_ex5601-t0-ubootmod
define Device/zyxel_ex5700-telenor
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
DEVICE_MODEL := EX5700 (Telenor)
DEVICE_DTS := mt7986a-zyxel-ex5700-telenor
DEVICE_DTS_DIR := ../dts
@@ -1441,7 +1492,7 @@ endef
TARGET_DEVICES += zyxel_ex5700-telenor
define Device/zyxel_nwa50ax-pro
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
DEVICE_MODEL := NWA50AX Pro
DEVICE_DTS := mt7981b-zyxel-nwa50ax-pro
DEVICE_DTS_DIR := ../dts
diff --git a/target/linux/mediatek/image/mt7622.mk b/target/linux/mediatek/image/mt7622.mk
index f91720479a..e1d9a09c64 100644
--- a/target/linux/mediatek/image/mt7622.mk
+++ b/target/linux/mediatek/image/mt7622.mk
@@ -328,7 +328,7 @@ TARGET_DEVICES += totolink_a8000ru
define Device/ubnt_unifi-6-lr-v1
DEVICE_VENDOR := Ubiquiti
- DEVICE_MODEL := UniFi 6 LR
+ DEVICE_MODEL := UniFi U6 Long-Range
DEVICE_VARIANT := v1
DEVICE_DTS_CONFIG := config@1
DEVICE_DTS := mt7622-ubnt-unifi-6-lr-v1
@@ -340,7 +340,7 @@ TARGET_DEVICES += ubnt_unifi-6-lr-v1
define Device/ubnt_unifi-6-lr-v1-ubootmod
DEVICE_VENDOR := Ubiquiti
- DEVICE_MODEL := UniFi 6 LR
+ DEVICE_MODEL := UniFi U6 Long-Range
DEVICE_VARIANT := v1 U-Boot mod
DEVICE_DTS := mt7622-ubnt-unifi-6-lr-v1-ubootmod
DEVICE_DTS_DIR := ../dts
@@ -359,7 +359,7 @@ TARGET_DEVICES += ubnt_unifi-6-lr-v1-ubootmod
define Device/ubnt_unifi-6-lr-v2
DEVICE_VENDOR := Ubiquiti
- DEVICE_MODEL := UniFi 6 LR
+ DEVICE_MODEL := UniFi U6 Long-Range
DEVICE_VARIANT := v2
DEVICE_DTS_CONFIG := config@1
DEVICE_DTS := mt7622-ubnt-unifi-6-lr-v2
@@ -370,7 +370,7 @@ TARGET_DEVICES += ubnt_unifi-6-lr-v2
define Device/ubnt_unifi-6-lr-v2-ubootmod
DEVICE_VENDOR := Ubiquiti
- DEVICE_MODEL := UniFi 6 LR
+ DEVICE_MODEL := UniFi U6 Long-Range
DEVICE_VARIANT := v2 U-Boot mod
DEVICE_DTS := mt7622-ubnt-unifi-6-lr-v2-ubootmod
DEVICE_DTS_DIR := ../dts
@@ -388,7 +388,7 @@ TARGET_DEVICES += ubnt_unifi-6-lr-v2-ubootmod
define Device/ubnt_unifi-6-lr-v3
DEVICE_VENDOR := Ubiquiti
- DEVICE_MODEL := UniFi 6 LR
+ DEVICE_MODEL := UniFi U6 Long-Range
DEVICE_VARIANT := v3
DEVICE_DTS_CONFIG := config@1
DEVICE_DTS := mt7622-ubnt-unifi-6-lr-v3
@@ -399,7 +399,7 @@ TARGET_DEVICES += ubnt_unifi-6-lr-v3
define Device/ubnt_unifi-6-lr-v3-ubootmod
DEVICE_VENDOR := Ubiquiti
- DEVICE_MODEL := UniFi 6 LR
+ DEVICE_MODEL := UniFi U6 Long-Range
DEVICE_VARIANT := v3 U-Boot mod
DEVICE_DTS := mt7622-ubnt-unifi-6-lr-v3-ubootmod
DEVICE_DTS_DIR := ../dts
diff --git a/target/linux/mediatek/image/mt7629.mk b/target/linux/mediatek/image/mt7629.mk
index 9f0ea98950..57c0a5bc54 100644
--- a/target/linux/mediatek/image/mt7629.mk
+++ b/target/linux/mediatek/image/mt7629.mk
@@ -27,6 +27,22 @@ define Device/iptime_a6004mx
endef
TARGET_DEVICES += iptime_a6004mx
+define Device/linksys_ea7500-v3
+ $(Device/uimage-lzma-loader)
+ DEVICE_VENDOR := Linksys
+ DEVICE_MODEL := EA7500
+ DEVICE_VARIANT := v3
+ DEVICE_DTS := mt7629-linksys-ea7500-v3
+ DEVICE_DTS_DIR := ../dts
+ DEVICE_PACKAGES := kmod-usb3 uboot-envtools
+ IMAGE_SIZE := 40m
+ UBINIZE_OPTS := -E 5
+ BLOCKSIZE := 128k
+ PAGESIZE := 2048
+ IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata | check-size
+endef
+TARGET_DEVICES += linksys_ea7500-v3
+
define Device/netgear_ex6250-v2
DEVICE_VENDOR := NETGEAR
DEVICE_MODEL := EX6250
diff --git a/target/linux/mediatek/mt7622/base-files/lib/upgrade/platform.sh b/target/linux/mediatek/mt7622/base-files/lib/upgrade/platform.sh
index 59375ccd9b..61025fb380 100755
--- a/target/linux/mediatek/mt7622/base-files/lib/upgrade/platform.sh
+++ b/target/linux/mediatek/mt7622/base-files/lib/upgrade/platform.sh
@@ -12,25 +12,8 @@ platform_do_upgrade() {
ubnt,unifi-6-lr-v2-ubootmod|\
ubnt,unifi-6-lr-v3-ubootmod|\
xiaomi,redmi-router-ax6s)
- [ -e /dev/fit0 ] && fitblk /dev/fit0
- [ -e /dev/fitrw ] && fitblk /dev/fitrw
- bootdev="$(fitblk_get_bootdev)"
- case "$bootdev" in
- mmcblk*)
- EMMC_KERN_DEV="/dev/$bootdev"
- emmc_do_upgrade "$1"
- ;;
- mtdblock*)
- PART_NAME="/dev/mtd${bootdev:8}"
- default_do_upgrade "$1"
- ;;
- ubiblock*)
- CI_KERNPART="fit"
- nand_do_upgrade "$1"
- ;;
- esac
+ fit_do_upgrade "$1"
;;
-
buffalo,wsr-2533dhp2|\
buffalo,wsr-3200ax4s)
local magic="$(get_magic_long "$1")"
@@ -103,7 +86,7 @@ platform_check_image() {
platform_copy_config() {
case "$(board_name)" in
bananapi,bpi-r64)
- if fitblk_get_bootdev | grep -q mmc; then
+ if [ "$CI_METHOD" = "emmc" ]; then
emmc_copy_config
fi
;;
diff --git a/target/linux/mediatek/mt7622/config-6.6 b/target/linux/mediatek/mt7622/config-6.6
index 067dd02d31..cf445b2b71 100644
--- a/target/linux/mediatek/mt7622/config-6.6
+++ b/target/linux/mediatek/mt7622/config-6.6
@@ -164,7 +164,6 @@ CONFIG_EINT_MTK=y
CONFIG_EXCLUSIVE_SYSTEM_RAM=y
CONFIG_EXT4_FS=y
CONFIG_F2FS_FS=y
-# CONFIG_FIT_PARTITION is not set
CONFIG_FIXED_PHY=y
CONFIG_FIX_EARLYCON_MEM=y
CONFIG_FRAME_POINTER=y
@@ -242,7 +241,7 @@ CONFIG_MAXLINEAR_GPHY=y
CONFIG_MDIO_BUS=y
CONFIG_MDIO_DEVICE=y
CONFIG_MDIO_DEVRES=y
-# CONFIG_MEDIATEK_2P5G_PHY is not set
+# CONFIG_MEDIATEK_2P5GE_PHY is not set
CONFIG_MEDIATEK_GE_PHY=y
# CONFIG_MEDIATEK_GE_SOC_PHY is not set
CONFIG_MEDIATEK_WATCHDOG=y
diff --git a/target/linux/mediatek/mt7623/base-files/lib/upgrade/platform.sh b/target/linux/mediatek/mt7623/base-files/lib/upgrade/platform.sh
index 9cfb15cf3d..bce6709a58 100755
--- a/target/linux/mediatek/mt7623/base-files/lib/upgrade/platform.sh
+++ b/target/linux/mediatek/mt7623/base-files/lib/upgrade/platform.sh
@@ -1,4 +1,5 @@
REQUIRE_IMAGE_METADATA=1
+RAMFS_COPY_BIN='fitblk'
# Legacy full system upgrade including preloader for MediaTek SoCs on eMMC or SD
legacy_mtk_mmc_full_upgrade() {
@@ -83,11 +84,7 @@ platform_do_upgrade() {
case "$board" in
bananapi,bpi-r2|\
unielec,u7623-02)
- [ -e /dev/fit0 ] && fitblk /dev/fit0
- [ -e /dev/fitrw ] && fitblk /dev/fitrw
- bootdev="$(fitblk_get_bootdev)"
- EMMC_KERN_DEV="/dev/$bootdev"
- emmc_do_upgrade "$1"
+ fit_do_upgrade "$1"
;;
unielec,u7623-02-emmc-512m)
local magic="$(get_magic_long "$1")"
diff --git a/target/linux/mediatek/mt7623/config-6.6 b/target/linux/mediatek/mt7623/config-6.6
index 9d6c5eed96..bb00bee8f3 100644
--- a/target/linux/mediatek/mt7623/config-6.6
+++ b/target/linux/mediatek/mt7623/config-6.6
@@ -224,7 +224,6 @@ CONFIG_FB_SYS_COPYAREA=y
CONFIG_FB_SYS_FILLRECT=y
CONFIG_FB_SYS_FOPS=y
CONFIG_FB_SYS_IMAGEBLIT=y
-# CONFIG_FIT_PARTITION is not set
CONFIG_FIXED_PHY=y
CONFIG_FIX_EARLYCON_MEM=y
CONFIG_FONT_8x16=y
diff --git a/target/linux/mediatek/mt7629/base-files/etc/board.d/02_network b/target/linux/mediatek/mt7629/base-files/etc/board.d/02_network
index df042f8ad2..875ed34dcc 100644
--- a/target/linux/mediatek/mt7629/base-files/etc/board.d/02_network
+++ b/target/linux/mediatek/mt7629/base-files/etc/board.d/02_network
@@ -8,7 +8,8 @@ mediatek_setup_interfaces()
local board="$1"
case $board in
- iptime,a6004mx)
+ iptime,a6004mx|\
+ linksys,ea7500-v3)
ucidef_set_interfaces_lan_wan "lan1 lan2 lan3 lan4" "eth1"
;;
mediatek,mt7629-rfb)
@@ -28,6 +29,11 @@ mediatek_setup_macs()
local board="$1"
case $board in
+ linksys,ea7500-v3)
+ lan_mac=$(mtd_get_mac_ascii devinfo hw_mac_addr)
+ wan_mac=$lan_mac
+ label_mac=$lan_mac
+ ;;
netgear,ex6250-v2)
lan_mac=$(mtd_get_mac_ascii Config mac)
label_mac=$lan_mac
diff --git a/target/linux/mediatek/mt7629/base-files/etc/init.d/bootcount b/target/linux/mediatek/mt7629/base-files/etc/init.d/bootcount
index a6b8fac1d9..959944fef8 100755
--- a/target/linux/mediatek/mt7629/base-files/etc/init.d/bootcount
+++ b/target/linux/mediatek/mt7629/base-files/etc/init.d/bootcount
@@ -13,5 +13,8 @@ boot() {
exit 1
fi
;;
+ linksys,ea7500-v3)
+ mtd resetbc s_env || true
+ ;;
esac
}
diff --git a/target/linux/mediatek/mt7629/base-files/lib/upgrade/platform.sh b/target/linux/mediatek/mt7629/base-files/lib/upgrade/platform.sh
index f10ad14b49..ebd3678c2e 100755
--- a/target/linux/mediatek/mt7629/base-files/lib/upgrade/platform.sh
+++ b/target/linux/mediatek/mt7629/base-files/lib/upgrade/platform.sh
@@ -12,6 +12,11 @@ platform_do_upgrade() {
iptime,a6004mx)
nand_do_upgrade "$1"
;;
+ linksys,ea7500-v3)
+ fw_setenv boot_part 1
+ fw_setenv bootimage 1
+ nand_do_upgrade "$1"
+ ;;
*)
default_do_upgrade "$1"
;;
diff --git a/target/linux/mediatek/mt7629/config-6.6 b/target/linux/mediatek/mt7629/config-6.6
index ec029de2fe..1748efab77 100644
--- a/target/linux/mediatek/mt7629/config-6.6
+++ b/target/linux/mediatek/mt7629/config-6.6
@@ -106,7 +106,6 @@ CONFIG_EDAC_ATOMIC_SCRUB=y
CONFIG_EDAC_SUPPORT=y
CONFIG_EINT_MTK=y
CONFIG_EXCLUSIVE_SYSTEM_RAM=y
-# CONFIG_FIT_PARTITION is not set
CONFIG_FIXED_PHY=y
CONFIG_FIX_EARLYCON_MEM=y
CONFIG_FS_IOMAP=y
diff --git a/target/linux/mediatek/patches-6.6/041-block-fit-partition-parser.patch b/target/linux/mediatek/patches-6.6/041-block-fit-partition-parser.patch
deleted file mode 100644
index 49fc7e638c..0000000000
--- a/target/linux/mediatek/patches-6.6/041-block-fit-partition-parser.patch
+++ /dev/null
@@ -1,216 +0,0 @@
-From 69357074558daf6ff24c9f58714935e9e095a865 Mon Sep 17 00:00:00 2001
-From: OpenWrt community <openwrt-devel@lists.openwrt.org>
-Date: Wed, 13 Jul 2022 13:37:33 +0200
-Subject: [PATCH] kernel: add block fit partition parser
-
----
- block/blk.h | 2 ++
- block/partitions/Kconfig | 7 +++++++
- block/partitions/Makefile | 1 +
- block/partitions/check.h | 3 +++
- block/partitions/core.c | 17 +++++++++++++++++
- block/partitions/efi.c | 8 ++++++++
- block/partitions/efi.h | 3 +++
- block/partitions/msdos.c | 10 ++++++++++
- drivers/mtd/mtd_blkdevs.c | 2 ++
- drivers/mtd/ubi/block.c | 3 +++
- include/linux/msdos_partition.h | 1 +
- 11 files changed, 57 insertions(+)
-
---- a/block/blk.h
-+++ b/block/blk.h
-@@ -424,6 +424,8 @@ void blk_free_ext_minor(unsigned int min
- #define ADDPART_FLAG_NONE 0
- #define ADDPART_FLAG_RAID 1
- #define ADDPART_FLAG_WHOLEDISK 2
-+#define ADDPART_FLAG_READONLY 4
-+#define ADDPART_FLAG_ROOTDEV 8
- int bdev_add_partition(struct gendisk *disk, int partno, sector_t start,
- sector_t length);
- int bdev_del_partition(struct gendisk *disk, int partno);
---- a/block/partitions/Kconfig
-+++ b/block/partitions/Kconfig
-@@ -103,6 +103,13 @@ config ATARI_PARTITION
- Say Y here if you would like to use hard disks under Linux which
- were partitioned under the Atari OS.
-
-+config FIT_PARTITION
-+ bool "Flattened-Image-Tree (FIT) partition support" if PARTITION_ADVANCED
-+ default n
-+ help
-+ Say Y here if your system needs to mount the filesystem part of
-+ a Flattened-Image-Tree (FIT) image commonly used with Das U-Boot.
-+
- config IBM_PARTITION
- bool "IBM disk label and partition support"
- depends on PARTITION_ADVANCED && S390
---- a/block/partitions/Makefile
-+++ b/block/partitions/Makefile
-@@ -8,6 +8,7 @@ obj-$(CONFIG_ACORN_PARTITION) += acorn.o
- obj-$(CONFIG_AMIGA_PARTITION) += amiga.o
- obj-$(CONFIG_ATARI_PARTITION) += atari.o
- obj-$(CONFIG_AIX_PARTITION) += aix.o
-+obj-$(CONFIG_FIT_PARTITION) += fit.o
- obj-$(CONFIG_CMDLINE_PARTITION) += cmdline.o
- obj-$(CONFIG_MAC_PARTITION) += mac.o
- obj-$(CONFIG_LDM_PARTITION) += ldm.o
---- a/block/partitions/check.h
-+++ b/block/partitions/check.h
-@@ -57,6 +57,7 @@ int amiga_partition(struct parsed_partit
- int atari_partition(struct parsed_partitions *state);
- int cmdline_partition(struct parsed_partitions *state);
- int efi_partition(struct parsed_partitions *state);
-+int fit_partition(struct parsed_partitions *state);
- int ibm_partition(struct parsed_partitions *);
- int karma_partition(struct parsed_partitions *state);
- int ldm_partition(struct parsed_partitions *state);
-@@ -67,3 +68,5 @@ int sgi_partition(struct parsed_partitio
- int sun_partition(struct parsed_partitions *state);
- int sysv68_partition(struct parsed_partitions *state);
- int ultrix_partition(struct parsed_partitions *state);
-+
-+int parse_fit_partitions(struct parsed_partitions *state, u64 start_sector, u64 nr_sectors, int *slot, int add_remain);
---- a/block/partitions/core.c
-+++ b/block/partitions/core.c
-@@ -11,6 +11,9 @@
- #include <linux/vmalloc.h>
- #include <linux/raid/detect.h>
- #include <linux/property.h>
-+#ifdef CONFIG_FIT_PARTITION
-+#include <linux/root_dev.h>
-+#endif
-
- #include "check.h"
-
-@@ -48,6 +51,9 @@ static int (*const check_part[])(struct
- #ifdef CONFIG_EFI_PARTITION
- efi_partition, /* this must come before msdos */
- #endif
-+#ifdef CONFIG_FIT_PARTITION
-+ fit_partition,
-+#endif
- #ifdef CONFIG_SGI_PARTITION
- sgi_partition,
- #endif
-@@ -430,6 +436,11 @@ static struct block_device *add_partitio
- goto out_del;
- }
-
-+#ifdef CONFIG_FIT_PARTITION
-+ if (flags & ADDPART_FLAG_READONLY)
-+ bdev->bd_read_only = true;
-+#endif
-+
- /* everything is up and running, commence */
- err = xa_insert(&disk->part_tbl, partno, bdev, GFP_KERNEL);
- if (err)
-@@ -622,6 +633,11 @@ static bool blk_add_partition(struct gen
- (state->parts[p].flags & ADDPART_FLAG_RAID))
- md_autodetect_dev(part->bd_dev);
-
-+#ifdef CONFIG_FIT_PARTITION
-+ if ((state->parts[p].flags & ADDPART_FLAG_ROOTDEV) && ROOT_DEV == 0)
-+ ROOT_DEV = part->bd_dev;
-+#endif
-+
- return true;
- }
-
---- a/block/partitions/efi.c
-+++ b/block/partitions/efi.c
-@@ -716,6 +716,9 @@ int efi_partition(struct parsed_partitio
- gpt_entry *ptes = NULL;
- u32 i;
- unsigned ssz = queue_logical_block_size(state->disk->queue) / 512;
-+#ifdef CONFIG_FIT_PARTITION
-+ u32 extra_slot = 64;
-+#endif
-
- if (!find_valid_gpt(state, &gpt, &ptes) || !gpt || !ptes) {
- kfree(gpt);
-@@ -749,6 +752,11 @@ int efi_partition(struct parsed_partitio
- ARRAY_SIZE(ptes[i].partition_name));
- utf16_le_to_7bit(ptes[i].partition_name, label_max, info->volname);
- state->parts[i + 1].has_info = true;
-+#ifdef CONFIG_FIT_PARTITION
-+ /* If this is a U-Boot FIT volume it may have subpartitions */
-+ if (!efi_guidcmp(ptes[i].partition_type_guid, PARTITION_LINUX_FIT_GUID))
-+ (void) parse_fit_partitions(state, start * ssz, size * ssz, &extra_slot, 1);
-+#endif
- }
- kfree(ptes);
- kfree(gpt);
---- a/block/partitions/efi.h
-+++ b/block/partitions/efi.h
-@@ -51,6 +51,9 @@
- #define PARTITION_LINUX_LVM_GUID \
- EFI_GUID( 0xe6d6d379, 0xf507, 0x44c2, \
- 0xa2, 0x3c, 0x23, 0x8f, 0x2a, 0x3d, 0xf9, 0x28)
-+#define PARTITION_LINUX_FIT_GUID \
-+ EFI_GUID( 0xcae9be83, 0xb15f, 0x49cc, \
-+ 0x86, 0x3f, 0x08, 0x1b, 0x74, 0x4a, 0x2d, 0x93)
-
- typedef struct _gpt_header {
- __le64 signature;
---- a/block/partitions/msdos.c
-+++ b/block/partitions/msdos.c
-@@ -564,6 +564,15 @@ static void parse_minix(struct parsed_pa
- #endif /* CONFIG_MINIX_SUBPARTITION */
- }
-
-+static void parse_fit_mbr(struct parsed_partitions *state,
-+ sector_t offset, sector_t size, int origin)
-+{
-+#ifdef CONFIG_FIT_PARTITION
-+ u32 extra_slot = 64;
-+ (void) parse_fit_partitions(state, offset, size, &extra_slot, 1);
-+#endif /* CONFIG_FIT_PARTITION */
-+}
-+
- static struct {
- unsigned char id;
- void (*parse)(struct parsed_partitions *, sector_t, sector_t, int);
-@@ -575,6 +584,7 @@ static struct {
- {UNIXWARE_PARTITION, parse_unixware},
- {SOLARIS_X86_PARTITION, parse_solaris_x86},
- {NEW_SOLARIS_X86_PARTITION, parse_solaris_x86},
-+ {FIT_PARTITION, parse_fit_mbr},
- {0, NULL},
- };
-
---- a/drivers/mtd/mtd_blkdevs.c
-+++ b/drivers/mtd/mtd_blkdevs.c
-@@ -359,7 +359,9 @@ int add_mtd_blktrans_dev(struct mtd_blkt
- } else {
- snprintf(gd->disk_name, sizeof(gd->disk_name),
- "%s%d", tr->name, new->devnum);
-- gd->flags |= GENHD_FL_NO_PART;
-+
-+ if (!IS_ENABLED(CONFIG_FIT_PARTITION) || mtd_type_is_nand(new->mtd))
-+ gd->flags |= GENHD_FL_NO_PART;
- }
-
- set_capacity(gd, ((u64)new->size * tr->blksize) >> 9);
---- a/drivers/mtd/ubi/block.c
-+++ b/drivers/mtd/ubi/block.c
-@@ -410,7 +410,9 @@ int ubiblock_create(struct ubi_volume_in
- ret = -ENODEV;
- goto out_cleanup_disk;
- }
-- gd->flags |= GENHD_FL_NO_PART;
-+ if (!IS_ENABLED(CONFIG_FIT_PARTITION))
-+ gd->flags |= GENHD_FL_NO_PART;
-+
- gd->private_data = dev;
- sprintf(gd->disk_name, "ubiblock%d_%d", dev->ubi_num, dev->vol_id);
- set_capacity(gd, disk_capacity);
---- a/include/linux/msdos_partition.h
-+++ b/include/linux/msdos_partition.h
-@@ -31,6 +31,7 @@ enum msdos_sys_ind {
- LINUX_LVM_PARTITION = 0x8e,
- LINUX_RAID_PARTITION = 0xfd, /* autodetect RAID partition */
-
-+ FIT_PARTITION = 0x2e, /* U-Boot uImage.FIT */
- SOLARIS_X86_PARTITION = 0x82, /* also Linux swap partitions */
- NEW_SOLARIS_X86_PARTITION = 0xbf,
-
diff --git a/target/linux/mediatek/patches-6.6/330-snand-mtk-bmt-support.patch b/target/linux/mediatek/patches-6.6/330-snand-mtk-bmt-support.patch
index 8a4ec2bcbd..de8e880643 100644
--- a/target/linux/mediatek/patches-6.6/330-snand-mtk-bmt-support.patch
+++ b/target/linux/mediatek/patches-6.6/330-snand-mtk-bmt-support.patch
@@ -8,7 +8,7 @@
static int spinand_read_reg_op(struct spinand_device *spinand, u8 reg, u8 *val)
{
-@@ -1345,6 +1346,7 @@ static int spinand_probe(struct spi_mem
+@@ -1346,6 +1347,7 @@ static int spinand_probe(struct spi_mem
if (ret)
return ret;
@@ -16,7 +16,7 @@
ret = mtd_device_register(mtd, NULL, 0);
if (ret)
goto err_spinand_cleanup;
-@@ -1352,6 +1354,7 @@ static int spinand_probe(struct spi_mem
+@@ -1353,6 +1355,7 @@ static int spinand_probe(struct spi_mem
return 0;
err_spinand_cleanup:
@@ -24,7 +24,7 @@
spinand_cleanup(spinand);
return ret;
-@@ -1370,6 +1373,7 @@ static int spinand_remove(struct spi_mem
+@@ -1371,6 +1374,7 @@ static int spinand_remove(struct spi_mem
if (ret)
return ret;
diff --git a/target/linux/mediatek/patches-6.6/351-pinctrl-add-mt7988-pd-pulltype-support.patch b/target/linux/mediatek/patches-6.6/351-pinctrl-add-mt7988-pd-pulltype-support.patch
index 1fcb1e64c7..fb65adb011 100644
--- a/target/linux/mediatek/patches-6.6/351-pinctrl-add-mt7988-pd-pulltype-support.patch
+++ b/target/linux/mediatek/patches-6.6/351-pinctrl-add-mt7988-pd-pulltype-support.patch
@@ -31,8 +31,8 @@
static int mtk_pinconf_bias_set_pullsel_pullen(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc,
u32 pullup, u32 arg)
-@@ -755,6 +779,12 @@ int mtk_pinconf_bias_set_combo(struct mt
- return err;
+@@ -758,6 +782,12 @@ int mtk_pinconf_bias_set_combo(struct mt
+ return 0;
}
+ if (try_all_type & MTK_PULL_PD_TYPE) {
@@ -44,7 +44,7 @@
if (try_all_type & MTK_PULL_PU_PD_TYPE) {
err = mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, arg);
if (!err)
-@@ -875,6 +905,29 @@ out:
+@@ -878,6 +908,29 @@ out:
return err;
}
@@ -74,19 +74,19 @@
static int mtk_pinconf_bias_get_pullsel_pullen(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc,
u32 *pullup, u32 *enable)
-@@ -943,6 +996,12 @@ int mtk_pinconf_bias_get_combo(struct mt
- if (!err)
- return err;
+@@ -947,6 +1000,12 @@ int mtk_pinconf_bias_get_combo(struct mt
+ return 0;
}
-+
+
+ if (try_all_type & MTK_PULL_PD_TYPE) {
+ err = mtk_pinconf_bias_get_pd(hw, desc, pullup, enable);
+ if (!err)
+ return err;
+ }
-
++
if (try_all_type & MTK_PULL_PU_PD_TYPE) {
err = mtk_pinconf_bias_get_pu_pd(hw, desc, pullup, enable);
+ if (!err)
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
@@ -24,6 +24,7 @@
diff --git a/target/linux/mediatek/patches-6.6/432-drivers-spi-Add-support-for-dynamic-calibration.patch b/target/linux/mediatek/patches-6.6/432-drivers-spi-Add-support-for-dynamic-calibration.patch
index 7ad07c3583..19fe984aa6 100644
--- a/target/linux/mediatek/patches-6.6/432-drivers-spi-Add-support-for-dynamic-calibration.patch
+++ b/target/linux/mediatek/patches-6.6/432-drivers-spi-Add-support-for-dynamic-calibration.patch
@@ -224,7 +224,7 @@ Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
int (*fw_translate_cs)(struct spi_controller *ctlr, unsigned cs);
/*
-@@ -1600,6 +1639,9 @@ spi_register_board_info(struct spi_board
+@@ -1601,6 +1640,9 @@ spi_register_board_info(struct spi_board
{ return 0; }
#endif
diff --git a/target/linux/mediatek/patches-6.6/733-01-net-phy-mediatek-Re-organize-MediaTek-ethernet-phy-d.patch b/target/linux/mediatek/patches-6.6/733-01-net-phy-mediatek-Re-organize-MediaTek-ethernet-phy-d.patch
new file mode 100644
index 0000000000..3ec756bb4b
--- /dev/null
+++ b/target/linux/mediatek/patches-6.6/733-01-net-phy-mediatek-Re-organize-MediaTek-ethernet-phy-d.patch
@@ -0,0 +1,3513 @@
+From c14e7c954fd752fbb3da17a8bcf65cd9dbf41186 Mon Sep 17 00:00:00 2001
+From: "SkyLake.Huang" <skylake.huang@mediatek.com>
+Date: Mon, 1 Jul 2024 18:54:05 +0800
+Subject: [PATCH 01/13] net: phy: mediatek: Re-organize MediaTek ethernet phy
+ drivers
+
+Re-organize MediaTek ethernet phy driver files and get ready to integrate
+some common functions and add new 2.5G phy driver.
+mtk-ge.c: MT7530 Gphy on MT7621 & MT7531 Gphy
+mtk-ge-soc.c: Built-in Gphy on MT7981 & Built-in switch Gphy on MT7988
+mtk-2p5ge.c: Planned for built-in 2.5G phy on MT7988
+
+Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
+---
+ drivers/net/phy/Kconfig | 17 +-------------
+ drivers/net/phy/Makefile | 3 +--
+ drivers/net/phy/mediatek/Kconfig | 22 +++++++++++++++++++
+ drivers/net/phy/mediatek/Makefile | 3 +++
+ .../mtk-ge-soc.c} | 0
+ .../phy/{mediatek-ge.c => mediatek/mtk-ge.c} | 0
+ 7 files changed, 29 insertions(+), 20 deletions(-)
+ create mode 100644 drivers/net/phy/mediatek/Kconfig
+ create mode 100644 drivers/net/phy/mediatek/Makefile
+ rename drivers/net/phy/{mediatek-ge-soc.c => mediatek/mtk-ge-soc.c} (100%)
+ rename drivers/net/phy/{mediatek-ge.c => mediatek/mtk-ge.c} (100%)
+
+--- a/drivers/net/phy/Kconfig
++++ b/drivers/net/phy/Kconfig
+@@ -313,22 +313,7 @@ config MAXLINEAR_GPHY
+ Support for the Maxlinear GPY115, GPY211, GPY212, GPY215,
+ GPY241, GPY245 PHYs.
+
+-config MEDIATEK_GE_PHY
+- tristate "MediaTek Gigabit Ethernet PHYs"
+- help
+- Supports the MediaTek Gigabit Ethernet PHYs.
+-
+-config MEDIATEK_GE_SOC_PHY
+- tristate "MediaTek SoC Ethernet PHYs"
+- depends on (ARM64 && ARCH_MEDIATEK) || COMPILE_TEST
+- depends on NVMEM_MTK_EFUSE
+- help
+- Supports MediaTek SoC built-in Gigabit Ethernet PHYs.
+-
+- Include support for built-in Ethernet PHYs which are present in
+- the MT7981 and MT7988 SoCs. These PHYs need calibration data
+- present in the SoCs efuse and will dynamically calibrate VCM
+- (common-mode voltage) during startup.
++source "drivers/net/phy/mediatek/Kconfig"
+
+ config MICREL_PHY
+ tristate "Micrel PHYs"
+--- a/drivers/net/phy/Makefile
++++ b/drivers/net/phy/Makefile
+@@ -82,8 +82,7 @@ obj-$(CONFIG_MARVELL_PHY) += marvell.o
+ obj-$(CONFIG_MARVELL_88Q2XXX_PHY) += marvell-88q2xxx.o
+ obj-$(CONFIG_MARVELL_88X2222_PHY) += marvell-88x2222.o
+ obj-$(CONFIG_MAXLINEAR_GPHY) += mxl-gpy.o
+-obj-$(CONFIG_MEDIATEK_GE_PHY) += mediatek-ge.o
+-obj-$(CONFIG_MEDIATEK_GE_SOC_PHY) += mediatek-ge-soc.o
++obj-y += mediatek/
+ obj-$(CONFIG_MESON_GXL_PHY) += meson-gxl.o
+ obj-$(CONFIG_MICREL_KS8995MA) += spi_ks8995.o
+ obj-$(CONFIG_MICREL_PHY) += micrel.o
+--- /dev/null
++++ b/drivers/net/phy/mediatek/Kconfig
+@@ -0,0 +1,22 @@
++# SPDX-License-Identifier: GPL-2.0-only
++config MEDIATEK_GE_PHY
++ tristate "MediaTek Gigabit Ethernet PHYs"
++ help
++ Supports the MediaTek non-built-in Gigabit Ethernet PHYs.
++
++ Non-built-in Gigabit Ethernet PHYs include mt7530/mt7531.
++ You may find mt7530 inside mt7621. This driver shares some
++ common operations with MediaTek SoC built-in Gigabit
++ Ethernet PHYs.
++
++config MEDIATEK_GE_SOC_PHY
++ tristate "MediaTek SoC Ethernet PHYs"
++ depends on (ARM64 && ARCH_MEDIATEK) || COMPILE_TEST
++ select NVMEM_MTK_EFUSE
++ help
++ Supports MediaTek SoC built-in Gigabit Ethernet PHYs.
++
++ Include support for built-in Ethernet PHYs which are present in
++ the MT7981 and MT7988 SoCs. These PHYs need calibration data
++ present in the SoCs efuse and will dynamically calibrate VCM
++ (common-mode voltage) during startup.
+--- /dev/null
++++ b/drivers/net/phy/mediatek/Makefile
+@@ -0,0 +1,3 @@
++# SPDX-License-Identifier: GPL-2.0
++obj-$(CONFIG_MEDIATEK_GE_PHY) += mtk-ge.o
++obj-$(CONFIG_MEDIATEK_GE_SOC_PHY) += mtk-ge-soc.o
+--- a/drivers/net/phy/mediatek-ge-soc.c
++++ /dev/null
+@@ -1,1555 +0,0 @@
+-// SPDX-License-Identifier: GPL-2.0+
+-#include <linux/bitfield.h>
+-#include <linux/bitmap.h>
+-#include <linux/mfd/syscon.h>
+-#include <linux/module.h>
+-#include <linux/nvmem-consumer.h>
+-#include <linux/pinctrl/consumer.h>
+-#include <linux/phy.h>
+-#include <linux/regmap.h>
+-
+-#define MTK_GPHY_ID_MT7981 0x03a29461
+-#define MTK_GPHY_ID_MT7988 0x03a29481
+-
+-#define MTK_EXT_PAGE_ACCESS 0x1f
+-#define MTK_PHY_PAGE_STANDARD 0x0000
+-#define MTK_PHY_PAGE_EXTENDED_3 0x0003
+-
+-#define MTK_PHY_LPI_REG_14 0x14
+-#define MTK_PHY_LPI_WAKE_TIMER_1000_MASK GENMASK(8, 0)
+-
+-#define MTK_PHY_LPI_REG_1c 0x1c
+-#define MTK_PHY_SMI_DET_ON_THRESH_MASK GENMASK(13, 8)
+-
+-#define MTK_PHY_PAGE_EXTENDED_2A30 0x2a30
+-#define MTK_PHY_PAGE_EXTENDED_52B5 0x52b5
+-
+-#define ANALOG_INTERNAL_OPERATION_MAX_US 20
+-#define TXRESERVE_MIN 0
+-#define TXRESERVE_MAX 7
+-
+-#define MTK_PHY_ANARG_RG 0x10
+-#define MTK_PHY_TCLKOFFSET_MASK GENMASK(12, 8)
+-
+-/* Registers on MDIO_MMD_VEND1 */
+-#define MTK_PHY_TXVLD_DA_RG 0x12
+-#define MTK_PHY_DA_TX_I2MPB_A_GBE_MASK GENMASK(15, 10)
+-#define MTK_PHY_DA_TX_I2MPB_A_TBT_MASK GENMASK(5, 0)
+-
+-#define MTK_PHY_TX_I2MPB_TEST_MODE_A2 0x16
+-#define MTK_PHY_DA_TX_I2MPB_A_HBT_MASK GENMASK(15, 10)
+-#define MTK_PHY_DA_TX_I2MPB_A_TST_MASK GENMASK(5, 0)
+-
+-#define MTK_PHY_TX_I2MPB_TEST_MODE_B1 0x17
+-#define MTK_PHY_DA_TX_I2MPB_B_GBE_MASK GENMASK(13, 8)
+-#define MTK_PHY_DA_TX_I2MPB_B_TBT_MASK GENMASK(5, 0)
+-
+-#define MTK_PHY_TX_I2MPB_TEST_MODE_B2 0x18
+-#define MTK_PHY_DA_TX_I2MPB_B_HBT_MASK GENMASK(13, 8)
+-#define MTK_PHY_DA_TX_I2MPB_B_TST_MASK GENMASK(5, 0)
+-
+-#define MTK_PHY_TX_I2MPB_TEST_MODE_C1 0x19
+-#define MTK_PHY_DA_TX_I2MPB_C_GBE_MASK GENMASK(13, 8)
+-#define MTK_PHY_DA_TX_I2MPB_C_TBT_MASK GENMASK(5, 0)
+-
+-#define MTK_PHY_TX_I2MPB_TEST_MODE_C2 0x20
+-#define MTK_PHY_DA_TX_I2MPB_C_HBT_MASK GENMASK(13, 8)
+-#define MTK_PHY_DA_TX_I2MPB_C_TST_MASK GENMASK(5, 0)
+-
+-#define MTK_PHY_TX_I2MPB_TEST_MODE_D1 0x21
+-#define MTK_PHY_DA_TX_I2MPB_D_GBE_MASK GENMASK(13, 8)
+-#define MTK_PHY_DA_TX_I2MPB_D_TBT_MASK GENMASK(5, 0)
+-
+-#define MTK_PHY_TX_I2MPB_TEST_MODE_D2 0x22
+-#define MTK_PHY_DA_TX_I2MPB_D_HBT_MASK GENMASK(13, 8)
+-#define MTK_PHY_DA_TX_I2MPB_D_TST_MASK GENMASK(5, 0)
+-
+-#define MTK_PHY_RXADC_CTRL_RG7 0xc6
+-#define MTK_PHY_DA_AD_BUF_BIAS_LP_MASK GENMASK(9, 8)
+-
+-#define MTK_PHY_RXADC_CTRL_RG9 0xc8
+-#define MTK_PHY_DA_RX_PSBN_TBT_MASK GENMASK(14, 12)
+-#define MTK_PHY_DA_RX_PSBN_HBT_MASK GENMASK(10, 8)
+-#define MTK_PHY_DA_RX_PSBN_GBE_MASK GENMASK(6, 4)
+-#define MTK_PHY_DA_RX_PSBN_LP_MASK GENMASK(2, 0)
+-
+-#define MTK_PHY_LDO_OUTPUT_V 0xd7
+-
+-#define MTK_PHY_RG_ANA_CAL_RG0 0xdb
+-#define MTK_PHY_RG_CAL_CKINV BIT(12)
+-#define MTK_PHY_RG_ANA_CALEN BIT(8)
+-#define MTK_PHY_RG_ZCALEN_A BIT(0)
+-
+-#define MTK_PHY_RG_ANA_CAL_RG1 0xdc
+-#define MTK_PHY_RG_ZCALEN_B BIT(12)
+-#define MTK_PHY_RG_ZCALEN_C BIT(8)
+-#define MTK_PHY_RG_ZCALEN_D BIT(4)
+-#define MTK_PHY_RG_TXVOS_CALEN BIT(0)
+-
+-#define MTK_PHY_RG_ANA_CAL_RG5 0xe0
+-#define MTK_PHY_RG_REXT_TRIM_MASK GENMASK(13, 8)
+-
+-#define MTK_PHY_RG_TX_FILTER 0xfe
+-
+-#define MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG120 0x120
+-#define MTK_PHY_LPI_SIG_EN_LO_THRESH1000_MASK GENMASK(12, 8)
+-#define MTK_PHY_LPI_SIG_EN_HI_THRESH1000_MASK GENMASK(4, 0)
+-
+-#define MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG122 0x122
+-#define MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK GENMASK(7, 0)
+-
+-#define MTK_PHY_RG_TESTMUX_ADC_CTRL 0x144
+-#define MTK_PHY_RG_TXEN_DIG_MASK GENMASK(5, 5)
+-
+-#define MTK_PHY_RG_CR_TX_AMP_OFFSET_A_B 0x172
+-#define MTK_PHY_CR_TX_AMP_OFFSET_A_MASK GENMASK(13, 8)
+-#define MTK_PHY_CR_TX_AMP_OFFSET_B_MASK GENMASK(6, 0)
+-
+-#define MTK_PHY_RG_CR_TX_AMP_OFFSET_C_D 0x173
+-#define MTK_PHY_CR_TX_AMP_OFFSET_C_MASK GENMASK(13, 8)
+-#define MTK_PHY_CR_TX_AMP_OFFSET_D_MASK GENMASK(6, 0)
+-
+-#define MTK_PHY_RG_AD_CAL_COMP 0x17a
+-#define MTK_PHY_AD_CAL_COMP_OUT_SHIFT (8)
+-
+-#define MTK_PHY_RG_AD_CAL_CLK 0x17b
+-#define MTK_PHY_DA_CAL_CLK BIT(0)
+-
+-#define MTK_PHY_RG_AD_CALIN 0x17c
+-#define MTK_PHY_DA_CALIN_FLAG BIT(0)
+-
+-#define MTK_PHY_RG_DASN_DAC_IN0_A 0x17d
+-#define MTK_PHY_DASN_DAC_IN0_A_MASK GENMASK(9, 0)
+-
+-#define MTK_PHY_RG_DASN_DAC_IN0_B 0x17e
+-#define MTK_PHY_DASN_DAC_IN0_B_MASK GENMASK(9, 0)
+-
+-#define MTK_PHY_RG_DASN_DAC_IN0_C 0x17f
+-#define MTK_PHY_DASN_DAC_IN0_C_MASK GENMASK(9, 0)
+-
+-#define MTK_PHY_RG_DASN_DAC_IN0_D 0x180
+-#define MTK_PHY_DASN_DAC_IN0_D_MASK GENMASK(9, 0)
+-
+-#define MTK_PHY_RG_DASN_DAC_IN1_A 0x181
+-#define MTK_PHY_DASN_DAC_IN1_A_MASK GENMASK(9, 0)
+-
+-#define MTK_PHY_RG_DASN_DAC_IN1_B 0x182
+-#define MTK_PHY_DASN_DAC_IN1_B_MASK GENMASK(9, 0)
+-
+-#define MTK_PHY_RG_DASN_DAC_IN1_C 0x183
+-#define MTK_PHY_DASN_DAC_IN1_C_MASK GENMASK(9, 0)
+-
+-#define MTK_PHY_RG_DASN_DAC_IN1_D 0x184
+-#define MTK_PHY_DASN_DAC_IN1_D_MASK GENMASK(9, 0)
+-
+-#define MTK_PHY_RG_DEV1E_REG19b 0x19b
+-#define MTK_PHY_BYPASS_DSP_LPI_READY BIT(8)
+-
+-#define MTK_PHY_RG_LP_IIR2_K1_L 0x22a
+-#define MTK_PHY_RG_LP_IIR2_K1_U 0x22b
+-#define MTK_PHY_RG_LP_IIR2_K2_L 0x22c
+-#define MTK_PHY_RG_LP_IIR2_K2_U 0x22d
+-#define MTK_PHY_RG_LP_IIR2_K3_L 0x22e
+-#define MTK_PHY_RG_LP_IIR2_K3_U 0x22f
+-#define MTK_PHY_RG_LP_IIR2_K4_L 0x230
+-#define MTK_PHY_RG_LP_IIR2_K4_U 0x231
+-#define MTK_PHY_RG_LP_IIR2_K5_L 0x232
+-#define MTK_PHY_RG_LP_IIR2_K5_U 0x233
+-
+-#define MTK_PHY_RG_DEV1E_REG234 0x234
+-#define MTK_PHY_TR_OPEN_LOOP_EN_MASK GENMASK(0, 0)
+-#define MTK_PHY_LPF_X_AVERAGE_MASK GENMASK(7, 4)
+-#define MTK_PHY_TR_LP_IIR_EEE_EN BIT(12)
+-
+-#define MTK_PHY_RG_LPF_CNT_VAL 0x235
+-
+-#define MTK_PHY_RG_DEV1E_REG238 0x238
+-#define MTK_PHY_LPI_SLV_SEND_TX_TIMER_MASK GENMASK(8, 0)
+-#define MTK_PHY_LPI_SLV_SEND_TX_EN BIT(12)
+-
+-#define MTK_PHY_RG_DEV1E_REG239 0x239
+-#define MTK_PHY_LPI_SEND_LOC_TIMER_MASK GENMASK(8, 0)
+-#define MTK_PHY_LPI_TXPCS_LOC_RCV BIT(12)
+-
+-#define MTK_PHY_RG_DEV1E_REG27C 0x27c
+-#define MTK_PHY_VGASTATE_FFE_THR_ST1_MASK GENMASK(12, 8)
+-#define MTK_PHY_RG_DEV1E_REG27D 0x27d
+-#define MTK_PHY_VGASTATE_FFE_THR_ST2_MASK GENMASK(4, 0)
+-
+-#define MTK_PHY_RG_DEV1E_REG2C7 0x2c7
+-#define MTK_PHY_MAX_GAIN_MASK GENMASK(4, 0)
+-#define MTK_PHY_MIN_GAIN_MASK GENMASK(12, 8)
+-
+-#define MTK_PHY_RG_DEV1E_REG2D1 0x2d1
+-#define MTK_PHY_VCO_SLICER_THRESH_BITS_HIGH_EEE_MASK GENMASK(7, 0)
+-#define MTK_PHY_LPI_SKIP_SD_SLV_TR BIT(8)
+-#define MTK_PHY_LPI_TR_READY BIT(9)
+-#define MTK_PHY_LPI_VCO_EEE_STG0_EN BIT(10)
+-
+-#define MTK_PHY_RG_DEV1E_REG323 0x323
+-#define MTK_PHY_EEE_WAKE_MAS_INT_DC BIT(0)
+-#define MTK_PHY_EEE_WAKE_SLV_INT_DC BIT(4)
+-
+-#define MTK_PHY_RG_DEV1E_REG324 0x324
+-#define MTK_PHY_SMI_DETCNT_MAX_MASK GENMASK(5, 0)
+-#define MTK_PHY_SMI_DET_MAX_EN BIT(8)
+-
+-#define MTK_PHY_RG_DEV1E_REG326 0x326
+-#define MTK_PHY_LPI_MODE_SD_ON BIT(0)
+-#define MTK_PHY_RESET_RANDUPD_CNT BIT(1)
+-#define MTK_PHY_TREC_UPDATE_ENAB_CLR BIT(2)
+-#define MTK_PHY_LPI_QUIT_WAIT_DFE_SIG_DET_OFF BIT(4)
+-#define MTK_PHY_TR_READY_SKIP_AFE_WAKEUP BIT(5)
+-
+-#define MTK_PHY_LDO_PUMP_EN_PAIRAB 0x502
+-#define MTK_PHY_LDO_PUMP_EN_PAIRCD 0x503
+-
+-#define MTK_PHY_DA_TX_R50_PAIR_A 0x53d
+-#define MTK_PHY_DA_TX_R50_PAIR_B 0x53e
+-#define MTK_PHY_DA_TX_R50_PAIR_C 0x53f
+-#define MTK_PHY_DA_TX_R50_PAIR_D 0x540
+-
+-/* Registers on MDIO_MMD_VEND2 */
+-#define MTK_PHY_LED0_ON_CTRL 0x24
+-#define MTK_PHY_LED1_ON_CTRL 0x26
+-#define MTK_PHY_LED_ON_MASK GENMASK(6, 0)
+-#define MTK_PHY_LED_ON_LINK1000 BIT(0)
+-#define MTK_PHY_LED_ON_LINK100 BIT(1)
+-#define MTK_PHY_LED_ON_LINK10 BIT(2)
+-#define MTK_PHY_LED_ON_LINK (MTK_PHY_LED_ON_LINK10 |\
+- MTK_PHY_LED_ON_LINK100 |\
+- MTK_PHY_LED_ON_LINK1000)
+-#define MTK_PHY_LED_ON_LINKDOWN BIT(3)
+-#define MTK_PHY_LED_ON_FDX BIT(4) /* Full duplex */
+-#define MTK_PHY_LED_ON_HDX BIT(5) /* Half duplex */
+-#define MTK_PHY_LED_ON_FORCE_ON BIT(6)
+-#define MTK_PHY_LED_ON_POLARITY BIT(14)
+-#define MTK_PHY_LED_ON_ENABLE BIT(15)
+-
+-#define MTK_PHY_LED0_BLINK_CTRL 0x25
+-#define MTK_PHY_LED1_BLINK_CTRL 0x27
+-#define MTK_PHY_LED_BLINK_1000TX BIT(0)
+-#define MTK_PHY_LED_BLINK_1000RX BIT(1)
+-#define MTK_PHY_LED_BLINK_100TX BIT(2)
+-#define MTK_PHY_LED_BLINK_100RX BIT(3)
+-#define MTK_PHY_LED_BLINK_10TX BIT(4)
+-#define MTK_PHY_LED_BLINK_10RX BIT(5)
+-#define MTK_PHY_LED_BLINK_RX (MTK_PHY_LED_BLINK_10RX |\
+- MTK_PHY_LED_BLINK_100RX |\
+- MTK_PHY_LED_BLINK_1000RX)
+-#define MTK_PHY_LED_BLINK_TX (MTK_PHY_LED_BLINK_10TX |\
+- MTK_PHY_LED_BLINK_100TX |\
+- MTK_PHY_LED_BLINK_1000TX)
+-#define MTK_PHY_LED_BLINK_COLLISION BIT(6)
+-#define MTK_PHY_LED_BLINK_RX_CRC_ERR BIT(7)
+-#define MTK_PHY_LED_BLINK_RX_IDLE_ERR BIT(8)
+-#define MTK_PHY_LED_BLINK_FORCE_BLINK BIT(9)
+-
+-#define MTK_PHY_LED1_DEFAULT_POLARITIES BIT(1)
+-
+-#define MTK_PHY_RG_BG_RASEL 0x115
+-#define MTK_PHY_RG_BG_RASEL_MASK GENMASK(2, 0)
+-
+-/* 'boottrap' register reflecting the configuration of the 4 PHY LEDs */
+-#define RG_GPIO_MISC_TPBANK0 0x6f0
+-#define RG_GPIO_MISC_TPBANK0_BOOTMODE GENMASK(11, 8)
+-
+-/* These macro privides efuse parsing for internal phy. */
+-#define EFS_DA_TX_I2MPB_A(x) (((x) >> 0) & GENMASK(5, 0))
+-#define EFS_DA_TX_I2MPB_B(x) (((x) >> 6) & GENMASK(5, 0))
+-#define EFS_DA_TX_I2MPB_C(x) (((x) >> 12) & GENMASK(5, 0))
+-#define EFS_DA_TX_I2MPB_D(x) (((x) >> 18) & GENMASK(5, 0))
+-#define EFS_DA_TX_AMP_OFFSET_A(x) (((x) >> 24) & GENMASK(5, 0))
+-
+-#define EFS_DA_TX_AMP_OFFSET_B(x) (((x) >> 0) & GENMASK(5, 0))
+-#define EFS_DA_TX_AMP_OFFSET_C(x) (((x) >> 6) & GENMASK(5, 0))
+-#define EFS_DA_TX_AMP_OFFSET_D(x) (((x) >> 12) & GENMASK(5, 0))
+-#define EFS_DA_TX_R50_A(x) (((x) >> 18) & GENMASK(5, 0))
+-#define EFS_DA_TX_R50_B(x) (((x) >> 24) & GENMASK(5, 0))
+-
+-#define EFS_DA_TX_R50_C(x) (((x) >> 0) & GENMASK(5, 0))
+-#define EFS_DA_TX_R50_D(x) (((x) >> 6) & GENMASK(5, 0))
+-
+-#define EFS_RG_BG_RASEL(x) (((x) >> 4) & GENMASK(2, 0))
+-#define EFS_RG_REXT_TRIM(x) (((x) >> 7) & GENMASK(5, 0))
+-
+-enum {
+- NO_PAIR,
+- PAIR_A,
+- PAIR_B,
+- PAIR_C,
+- PAIR_D,
+-};
+-
+-enum calibration_mode {
+- EFUSE_K,
+- SW_K
+-};
+-
+-enum CAL_ITEM {
+- REXT,
+- TX_OFFSET,
+- TX_AMP,
+- TX_R50,
+- TX_VCM
+-};
+-
+-enum CAL_MODE {
+- EFUSE_M,
+- SW_M
+-};
+-
+-#define MTK_PHY_LED_STATE_FORCE_ON 0
+-#define MTK_PHY_LED_STATE_FORCE_BLINK 1
+-#define MTK_PHY_LED_STATE_NETDEV 2
+-
+-struct mtk_socphy_priv {
+- unsigned long led_state;
+-};
+-
+-struct mtk_socphy_shared {
+- u32 boottrap;
+- struct mtk_socphy_priv priv[4];
+-};
+-
+-static int mtk_socphy_read_page(struct phy_device *phydev)
+-{
+- return __phy_read(phydev, MTK_EXT_PAGE_ACCESS);
+-}
+-
+-static int mtk_socphy_write_page(struct phy_device *phydev, int page)
+-{
+- return __phy_write(phydev, MTK_EXT_PAGE_ACCESS, page);
+-}
+-
+-/* One calibration cycle consists of:
+- * 1.Set DA_CALIN_FLAG high to start calibration. Keep it high
+- * until AD_CAL_COMP is ready to output calibration result.
+- * 2.Wait until DA_CAL_CLK is available.
+- * 3.Fetch AD_CAL_COMP_OUT.
+- */
+-static int cal_cycle(struct phy_device *phydev, int devad,
+- u32 regnum, u16 mask, u16 cal_val)
+-{
+- int reg_val;
+- int ret;
+-
+- phy_modify_mmd(phydev, devad, regnum,
+- mask, cal_val);
+- phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_AD_CALIN,
+- MTK_PHY_DA_CALIN_FLAG);
+-
+- ret = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1,
+- MTK_PHY_RG_AD_CAL_CLK, reg_val,
+- reg_val & MTK_PHY_DA_CAL_CLK, 500,
+- ANALOG_INTERNAL_OPERATION_MAX_US, false);
+- if (ret) {
+- phydev_err(phydev, "Calibration cycle timeout\n");
+- return ret;
+- }
+-
+- phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_AD_CALIN,
+- MTK_PHY_DA_CALIN_FLAG);
+- ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_AD_CAL_COMP) >>
+- MTK_PHY_AD_CAL_COMP_OUT_SHIFT;
+- phydev_dbg(phydev, "cal_val: 0x%x, ret: %d\n", cal_val, ret);
+-
+- return ret;
+-}
+-
+-static int rext_fill_result(struct phy_device *phydev, u16 *buf)
+-{
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
+- MTK_PHY_RG_REXT_TRIM_MASK, buf[0] << 8);
+- phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_BG_RASEL,
+- MTK_PHY_RG_BG_RASEL_MASK, buf[1]);
+-
+- return 0;
+-}
+-
+-static int rext_cal_efuse(struct phy_device *phydev, u32 *buf)
+-{
+- u16 rext_cal_val[2];
+-
+- rext_cal_val[0] = EFS_RG_REXT_TRIM(buf[3]);
+- rext_cal_val[1] = EFS_RG_BG_RASEL(buf[3]);
+- rext_fill_result(phydev, rext_cal_val);
+-
+- return 0;
+-}
+-
+-static int tx_offset_fill_result(struct phy_device *phydev, u16 *buf)
+-{
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_CR_TX_AMP_OFFSET_A_B,
+- MTK_PHY_CR_TX_AMP_OFFSET_A_MASK, buf[0] << 8);
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_CR_TX_AMP_OFFSET_A_B,
+- MTK_PHY_CR_TX_AMP_OFFSET_B_MASK, buf[1]);
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_CR_TX_AMP_OFFSET_C_D,
+- MTK_PHY_CR_TX_AMP_OFFSET_C_MASK, buf[2] << 8);
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_CR_TX_AMP_OFFSET_C_D,
+- MTK_PHY_CR_TX_AMP_OFFSET_D_MASK, buf[3]);
+-
+- return 0;
+-}
+-
+-static int tx_offset_cal_efuse(struct phy_device *phydev, u32 *buf)
+-{
+- u16 tx_offset_cal_val[4];
+-
+- tx_offset_cal_val[0] = EFS_DA_TX_AMP_OFFSET_A(buf[0]);
+- tx_offset_cal_val[1] = EFS_DA_TX_AMP_OFFSET_B(buf[1]);
+- tx_offset_cal_val[2] = EFS_DA_TX_AMP_OFFSET_C(buf[1]);
+- tx_offset_cal_val[3] = EFS_DA_TX_AMP_OFFSET_D(buf[1]);
+-
+- tx_offset_fill_result(phydev, tx_offset_cal_val);
+-
+- return 0;
+-}
+-
+-static int tx_amp_fill_result(struct phy_device *phydev, u16 *buf)
+-{
+- int i;
+- int bias[16] = {};
+- const int vals_9461[16] = { 7, 1, 4, 7,
+- 7, 1, 4, 7,
+- 7, 1, 4, 7,
+- 7, 1, 4, 7 };
+- const int vals_9481[16] = { 10, 6, 6, 10,
+- 10, 6, 6, 10,
+- 10, 6, 6, 10,
+- 10, 6, 6, 10 };
+- switch (phydev->drv->phy_id) {
+- case MTK_GPHY_ID_MT7981:
+- /* We add some calibration to efuse values
+- * due to board level influence.
+- * GBE: +7, TBT: +1, HBT: +4, TST: +7
+- */
+- memcpy(bias, (const void *)vals_9461, sizeof(bias));
+- break;
+- case MTK_GPHY_ID_MT7988:
+- memcpy(bias, (const void *)vals_9481, sizeof(bias));
+- break;
+- }
+-
+- /* Prevent overflow */
+- for (i = 0; i < 12; i++) {
+- if (buf[i >> 2] + bias[i] > 63) {
+- buf[i >> 2] = 63;
+- bias[i] = 0;
+- }
+- }
+-
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG,
+- MTK_PHY_DA_TX_I2MPB_A_GBE_MASK, (buf[0] + bias[0]) << 10);
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG,
+- MTK_PHY_DA_TX_I2MPB_A_TBT_MASK, buf[0] + bias[1]);
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2,
+- MTK_PHY_DA_TX_I2MPB_A_HBT_MASK, (buf[0] + bias[2]) << 10);
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2,
+- MTK_PHY_DA_TX_I2MPB_A_TST_MASK, buf[0] + bias[3]);
+-
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1,
+- MTK_PHY_DA_TX_I2MPB_B_GBE_MASK, (buf[1] + bias[4]) << 8);
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1,
+- MTK_PHY_DA_TX_I2MPB_B_TBT_MASK, buf[1] + bias[5]);
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2,
+- MTK_PHY_DA_TX_I2MPB_B_HBT_MASK, (buf[1] + bias[6]) << 8);
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2,
+- MTK_PHY_DA_TX_I2MPB_B_TST_MASK, buf[1] + bias[7]);
+-
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1,
+- MTK_PHY_DA_TX_I2MPB_C_GBE_MASK, (buf[2] + bias[8]) << 8);
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1,
+- MTK_PHY_DA_TX_I2MPB_C_TBT_MASK, buf[2] + bias[9]);
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2,
+- MTK_PHY_DA_TX_I2MPB_C_HBT_MASK, (buf[2] + bias[10]) << 8);
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2,
+- MTK_PHY_DA_TX_I2MPB_C_TST_MASK, buf[2] + bias[11]);
+-
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1,
+- MTK_PHY_DA_TX_I2MPB_D_GBE_MASK, (buf[3] + bias[12]) << 8);
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1,
+- MTK_PHY_DA_TX_I2MPB_D_TBT_MASK, buf[3] + bias[13]);
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2,
+- MTK_PHY_DA_TX_I2MPB_D_HBT_MASK, (buf[3] + bias[14]) << 8);
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2,
+- MTK_PHY_DA_TX_I2MPB_D_TST_MASK, buf[3] + bias[15]);
+-
+- return 0;
+-}
+-
+-static int tx_amp_cal_efuse(struct phy_device *phydev, u32 *buf)
+-{
+- u16 tx_amp_cal_val[4];
+-
+- tx_amp_cal_val[0] = EFS_DA_TX_I2MPB_A(buf[0]);
+- tx_amp_cal_val[1] = EFS_DA_TX_I2MPB_B(buf[0]);
+- tx_amp_cal_val[2] = EFS_DA_TX_I2MPB_C(buf[0]);
+- tx_amp_cal_val[3] = EFS_DA_TX_I2MPB_D(buf[0]);
+- tx_amp_fill_result(phydev, tx_amp_cal_val);
+-
+- return 0;
+-}
+-
+-static int tx_r50_fill_result(struct phy_device *phydev, u16 tx_r50_cal_val,
+- u8 txg_calen_x)
+-{
+- int bias = 0;
+- u16 reg, val;
+-
+- if (phydev->drv->phy_id == MTK_GPHY_ID_MT7988)
+- bias = -1;
+-
+- val = clamp_val(bias + tx_r50_cal_val, 0, 63);
+-
+- switch (txg_calen_x) {
+- case PAIR_A:
+- reg = MTK_PHY_DA_TX_R50_PAIR_A;
+- break;
+- case PAIR_B:
+- reg = MTK_PHY_DA_TX_R50_PAIR_B;
+- break;
+- case PAIR_C:
+- reg = MTK_PHY_DA_TX_R50_PAIR_C;
+- break;
+- case PAIR_D:
+- reg = MTK_PHY_DA_TX_R50_PAIR_D;
+- break;
+- default:
+- return -EINVAL;
+- }
+-
+- phy_write_mmd(phydev, MDIO_MMD_VEND1, reg, val | val << 8);
+-
+- return 0;
+-}
+-
+-static int tx_r50_cal_efuse(struct phy_device *phydev, u32 *buf,
+- u8 txg_calen_x)
+-{
+- u16 tx_r50_cal_val;
+-
+- switch (txg_calen_x) {
+- case PAIR_A:
+- tx_r50_cal_val = EFS_DA_TX_R50_A(buf[1]);
+- break;
+- case PAIR_B:
+- tx_r50_cal_val = EFS_DA_TX_R50_B(buf[1]);
+- break;
+- case PAIR_C:
+- tx_r50_cal_val = EFS_DA_TX_R50_C(buf[2]);
+- break;
+- case PAIR_D:
+- tx_r50_cal_val = EFS_DA_TX_R50_D(buf[2]);
+- break;
+- default:
+- return -EINVAL;
+- }
+- tx_r50_fill_result(phydev, tx_r50_cal_val, txg_calen_x);
+-
+- return 0;
+-}
+-
+-static int tx_vcm_cal_sw(struct phy_device *phydev, u8 rg_txreserve_x)
+-{
+- u8 lower_idx, upper_idx, txreserve_val;
+- u8 lower_ret, upper_ret;
+- int ret;
+-
+- phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
+- MTK_PHY_RG_ANA_CALEN);
+- phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
+- MTK_PHY_RG_CAL_CKINV);
+- phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
+- MTK_PHY_RG_TXVOS_CALEN);
+-
+- switch (rg_txreserve_x) {
+- case PAIR_A:
+- phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
+- MTK_PHY_RG_DASN_DAC_IN0_A,
+- MTK_PHY_DASN_DAC_IN0_A_MASK);
+- phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
+- MTK_PHY_RG_DASN_DAC_IN1_A,
+- MTK_PHY_DASN_DAC_IN1_A_MASK);
+- phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
+- MTK_PHY_RG_ANA_CAL_RG0,
+- MTK_PHY_RG_ZCALEN_A);
+- break;
+- case PAIR_B:
+- phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
+- MTK_PHY_RG_DASN_DAC_IN0_B,
+- MTK_PHY_DASN_DAC_IN0_B_MASK);
+- phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
+- MTK_PHY_RG_DASN_DAC_IN1_B,
+- MTK_PHY_DASN_DAC_IN1_B_MASK);
+- phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
+- MTK_PHY_RG_ANA_CAL_RG1,
+- MTK_PHY_RG_ZCALEN_B);
+- break;
+- case PAIR_C:
+- phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
+- MTK_PHY_RG_DASN_DAC_IN0_C,
+- MTK_PHY_DASN_DAC_IN0_C_MASK);
+- phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
+- MTK_PHY_RG_DASN_DAC_IN1_C,
+- MTK_PHY_DASN_DAC_IN1_C_MASK);
+- phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
+- MTK_PHY_RG_ANA_CAL_RG1,
+- MTK_PHY_RG_ZCALEN_C);
+- break;
+- case PAIR_D:
+- phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
+- MTK_PHY_RG_DASN_DAC_IN0_D,
+- MTK_PHY_DASN_DAC_IN0_D_MASK);
+- phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
+- MTK_PHY_RG_DASN_DAC_IN1_D,
+- MTK_PHY_DASN_DAC_IN1_D_MASK);
+- phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
+- MTK_PHY_RG_ANA_CAL_RG1,
+- MTK_PHY_RG_ZCALEN_D);
+- break;
+- default:
+- ret = -EINVAL;
+- goto restore;
+- }
+-
+- lower_idx = TXRESERVE_MIN;
+- upper_idx = TXRESERVE_MAX;
+-
+- phydev_dbg(phydev, "Start TX-VCM SW cal.\n");
+- while ((upper_idx - lower_idx) > 1) {
+- txreserve_val = DIV_ROUND_CLOSEST(lower_idx + upper_idx, 2);
+- ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
+- MTK_PHY_DA_RX_PSBN_TBT_MASK |
+- MTK_PHY_DA_RX_PSBN_HBT_MASK |
+- MTK_PHY_DA_RX_PSBN_GBE_MASK |
+- MTK_PHY_DA_RX_PSBN_LP_MASK,
+- txreserve_val << 12 | txreserve_val << 8 |
+- txreserve_val << 4 | txreserve_val);
+- if (ret == 1) {
+- upper_idx = txreserve_val;
+- upper_ret = ret;
+- } else if (ret == 0) {
+- lower_idx = txreserve_val;
+- lower_ret = ret;
+- } else {
+- goto restore;
+- }
+- }
+-
+- if (lower_idx == TXRESERVE_MIN) {
+- lower_ret = cal_cycle(phydev, MDIO_MMD_VEND1,
+- MTK_PHY_RXADC_CTRL_RG9,
+- MTK_PHY_DA_RX_PSBN_TBT_MASK |
+- MTK_PHY_DA_RX_PSBN_HBT_MASK |
+- MTK_PHY_DA_RX_PSBN_GBE_MASK |
+- MTK_PHY_DA_RX_PSBN_LP_MASK,
+- lower_idx << 12 | lower_idx << 8 |
+- lower_idx << 4 | lower_idx);
+- ret = lower_ret;
+- } else if (upper_idx == TXRESERVE_MAX) {
+- upper_ret = cal_cycle(phydev, MDIO_MMD_VEND1,
+- MTK_PHY_RXADC_CTRL_RG9,
+- MTK_PHY_DA_RX_PSBN_TBT_MASK |
+- MTK_PHY_DA_RX_PSBN_HBT_MASK |
+- MTK_PHY_DA_RX_PSBN_GBE_MASK |
+- MTK_PHY_DA_RX_PSBN_LP_MASK,
+- upper_idx << 12 | upper_idx << 8 |
+- upper_idx << 4 | upper_idx);
+- ret = upper_ret;
+- }
+- if (ret < 0)
+- goto restore;
+-
+- /* We calibrate TX-VCM in different logic. Check upper index and then
+- * lower index. If this calibration is valid, apply lower index's result.
+- */
+- ret = upper_ret - lower_ret;
+- if (ret == 1) {
+- ret = 0;
+- /* Make sure we use upper_idx in our calibration system */
+- cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
+- MTK_PHY_DA_RX_PSBN_TBT_MASK |
+- MTK_PHY_DA_RX_PSBN_HBT_MASK |
+- MTK_PHY_DA_RX_PSBN_GBE_MASK |
+- MTK_PHY_DA_RX_PSBN_LP_MASK,
+- upper_idx << 12 | upper_idx << 8 |
+- upper_idx << 4 | upper_idx);
+- phydev_dbg(phydev, "TX-VCM SW cal result: 0x%x\n", upper_idx);
+- } else if (lower_idx == TXRESERVE_MIN && upper_ret == 1 &&
+- lower_ret == 1) {
+- ret = 0;
+- cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
+- MTK_PHY_DA_RX_PSBN_TBT_MASK |
+- MTK_PHY_DA_RX_PSBN_HBT_MASK |
+- MTK_PHY_DA_RX_PSBN_GBE_MASK |
+- MTK_PHY_DA_RX_PSBN_LP_MASK,
+- lower_idx << 12 | lower_idx << 8 |
+- lower_idx << 4 | lower_idx);
+- phydev_warn(phydev, "TX-VCM SW cal result at low margin 0x%x\n",
+- lower_idx);
+- } else if (upper_idx == TXRESERVE_MAX && upper_ret == 0 &&
+- lower_ret == 0) {
+- ret = 0;
+- phydev_warn(phydev, "TX-VCM SW cal result at high margin 0x%x\n",
+- upper_idx);
+- } else {
+- ret = -EINVAL;
+- }
+-
+-restore:
+- phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
+- MTK_PHY_RG_ANA_CALEN);
+- phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
+- MTK_PHY_RG_TXVOS_CALEN);
+- phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
+- MTK_PHY_RG_ZCALEN_A);
+- phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
+- MTK_PHY_RG_ZCALEN_B | MTK_PHY_RG_ZCALEN_C |
+- MTK_PHY_RG_ZCALEN_D);
+-
+- return ret;
+-}
+-
+-static void mt798x_phy_common_finetune(struct phy_device *phydev)
+-{
+- phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
+- /* SlvDSPreadyTime = 24, MasDSPreadyTime = 24 */
+- __phy_write(phydev, 0x11, 0xc71);
+- __phy_write(phydev, 0x12, 0xc);
+- __phy_write(phydev, 0x10, 0x8fae);
+-
+- /* EnabRandUpdTrig = 1 */
+- __phy_write(phydev, 0x11, 0x2f00);
+- __phy_write(phydev, 0x12, 0xe);
+- __phy_write(phydev, 0x10, 0x8fb0);
+-
+- /* NormMseLoThresh = 85 */
+- __phy_write(phydev, 0x11, 0x55a0);
+- __phy_write(phydev, 0x12, 0x0);
+- __phy_write(phydev, 0x10, 0x83aa);
+-
+- /* FfeUpdGainForce = 1(Enable), FfeUpdGainForceVal = 4 */
+- __phy_write(phydev, 0x11, 0x240);
+- __phy_write(phydev, 0x12, 0x0);
+- __phy_write(phydev, 0x10, 0x9680);
+-
+- /* TrFreeze = 0 (mt7988 default) */
+- __phy_write(phydev, 0x11, 0x0);
+- __phy_write(phydev, 0x12, 0x0);
+- __phy_write(phydev, 0x10, 0x9686);
+-
+- /* SSTrKp100 = 5 */
+- /* SSTrKf100 = 6 */
+- /* SSTrKp1000Mas = 5 */
+- /* SSTrKf1000Mas = 6 */
+- /* SSTrKp1000Slv = 5 */
+- /* SSTrKf1000Slv = 6 */
+- __phy_write(phydev, 0x11, 0xbaef);
+- __phy_write(phydev, 0x12, 0x2e);
+- __phy_write(phydev, 0x10, 0x968c);
+- phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
+-}
+-
+-static void mt7981_phy_finetune(struct phy_device *phydev)
+-{
+- u16 val[8] = { 0x01ce, 0x01c1,
+- 0x020f, 0x0202,
+- 0x03d0, 0x03c0,
+- 0x0013, 0x0005 };
+- int i, k;
+-
+- /* 100M eye finetune:
+- * Keep middle level of TX MLT3 shapper as default.
+- * Only change TX MLT3 overshoot level here.
+- */
+- for (k = 0, i = 1; i < 12; i++) {
+- if (i % 3 == 0)
+- continue;
+- phy_write_mmd(phydev, MDIO_MMD_VEND1, i, val[k++]);
+- }
+-
+- phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
+- /* ResetSyncOffset = 6 */
+- __phy_write(phydev, 0x11, 0x600);
+- __phy_write(phydev, 0x12, 0x0);
+- __phy_write(phydev, 0x10, 0x8fc0);
+-
+- /* VgaDecRate = 1 */
+- __phy_write(phydev, 0x11, 0x4c2a);
+- __phy_write(phydev, 0x12, 0x3e);
+- __phy_write(phydev, 0x10, 0x8fa4);
+-
+- /* MrvlTrFix100Kp = 3, MrvlTrFix100Kf = 2,
+- * MrvlTrFix1000Kp = 3, MrvlTrFix1000Kf = 2
+- */
+- __phy_write(phydev, 0x11, 0xd10a);
+- __phy_write(phydev, 0x12, 0x34);
+- __phy_write(phydev, 0x10, 0x8f82);
+-
+- /* VcoSlicerThreshBitsHigh */
+- __phy_write(phydev, 0x11, 0x5555);
+- __phy_write(phydev, 0x12, 0x55);
+- __phy_write(phydev, 0x10, 0x8ec0);
+- phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
+-
+- /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 9 */
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234,
+- MTK_PHY_TR_OPEN_LOOP_EN_MASK | MTK_PHY_LPF_X_AVERAGE_MASK,
+- BIT(0) | FIELD_PREP(MTK_PHY_LPF_X_AVERAGE_MASK, 0x9));
+-
+- /* rg_tr_lpf_cnt_val = 512 */
+- phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LPF_CNT_VAL, 0x200);
+-
+- /* IIR2 related */
+- phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K1_L, 0x82);
+- phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K1_U, 0x0);
+- phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K2_L, 0x103);
+- phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K2_U, 0x0);
+- phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K3_L, 0x82);
+- phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K3_U, 0x0);
+- phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K4_L, 0xd177);
+- phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K4_U, 0x3);
+- phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K5_L, 0x2c82);
+- phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K5_U, 0xe);
+-
+- /* FFE peaking */
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG27C,
+- MTK_PHY_VGASTATE_FFE_THR_ST1_MASK, 0x1b << 8);
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG27D,
+- MTK_PHY_VGASTATE_FFE_THR_ST2_MASK, 0x1e);
+-
+- /* Disable LDO pump */
+- phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LDO_PUMP_EN_PAIRAB, 0x0);
+- phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LDO_PUMP_EN_PAIRCD, 0x0);
+- /* Adjust LDO output voltage */
+- phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LDO_OUTPUT_V, 0x2222);
+-}
+-
+-static void mt7988_phy_finetune(struct phy_device *phydev)
+-{
+- u16 val[12] = { 0x0187, 0x01cd, 0x01c8, 0x0182,
+- 0x020d, 0x0206, 0x0384, 0x03d0,
+- 0x03c6, 0x030a, 0x0011, 0x0005 };
+- int i;
+-
+- /* Set default MLT3 shaper first */
+- for (i = 0; i < 12; i++)
+- phy_write_mmd(phydev, MDIO_MMD_VEND1, i, val[i]);
+-
+- /* TCT finetune */
+- phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_TX_FILTER, 0x5);
+-
+- phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
+- /* ResetSyncOffset = 5 */
+- __phy_write(phydev, 0x11, 0x500);
+- __phy_write(phydev, 0x12, 0x0);
+- __phy_write(phydev, 0x10, 0x8fc0);
+-
+- /* VgaDecRate is 1 at default on mt7988 */
+-
+- /* MrvlTrFix100Kp = 6, MrvlTrFix100Kf = 7,
+- * MrvlTrFix1000Kp = 6, MrvlTrFix1000Kf = 7
+- */
+- __phy_write(phydev, 0x11, 0xb90a);
+- __phy_write(phydev, 0x12, 0x6f);
+- __phy_write(phydev, 0x10, 0x8f82);
+-
+- /* RemAckCntLimitCtrl = 1 */
+- __phy_write(phydev, 0x11, 0xfbba);
+- __phy_write(phydev, 0x12, 0xc3);
+- __phy_write(phydev, 0x10, 0x87f8);
+-
+- phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
+-
+- /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 10 */
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234,
+- MTK_PHY_TR_OPEN_LOOP_EN_MASK | MTK_PHY_LPF_X_AVERAGE_MASK,
+- BIT(0) | FIELD_PREP(MTK_PHY_LPF_X_AVERAGE_MASK, 0xa));
+-
+- /* rg_tr_lpf_cnt_val = 1023 */
+- phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LPF_CNT_VAL, 0x3ff);
+-}
+-
+-static void mt798x_phy_eee(struct phy_device *phydev)
+-{
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1,
+- MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG120,
+- MTK_PHY_LPI_SIG_EN_LO_THRESH1000_MASK |
+- MTK_PHY_LPI_SIG_EN_HI_THRESH1000_MASK,
+- FIELD_PREP(MTK_PHY_LPI_SIG_EN_LO_THRESH1000_MASK, 0x0) |
+- FIELD_PREP(MTK_PHY_LPI_SIG_EN_HI_THRESH1000_MASK, 0x14));
+-
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1,
+- MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG122,
+- MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK,
+- FIELD_PREP(MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK,
+- 0xff));
+-
+- phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
+- MTK_PHY_RG_TESTMUX_ADC_CTRL,
+- MTK_PHY_RG_TXEN_DIG_MASK);
+-
+- phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
+- MTK_PHY_RG_DEV1E_REG19b, MTK_PHY_BYPASS_DSP_LPI_READY);
+-
+- phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
+- MTK_PHY_RG_DEV1E_REG234, MTK_PHY_TR_LP_IIR_EEE_EN);
+-
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG238,
+- MTK_PHY_LPI_SLV_SEND_TX_TIMER_MASK |
+- MTK_PHY_LPI_SLV_SEND_TX_EN,
+- FIELD_PREP(MTK_PHY_LPI_SLV_SEND_TX_TIMER_MASK, 0x120));
+-
+- /* Keep MTK_PHY_LPI_SEND_LOC_TIMER as 375 */
+- phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG239,
+- MTK_PHY_LPI_TXPCS_LOC_RCV);
+-
+- /* This also fixes some IoT issues, such as CH340 */
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG2C7,
+- MTK_PHY_MAX_GAIN_MASK | MTK_PHY_MIN_GAIN_MASK,
+- FIELD_PREP(MTK_PHY_MAX_GAIN_MASK, 0x8) |
+- FIELD_PREP(MTK_PHY_MIN_GAIN_MASK, 0x13));
+-
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG2D1,
+- MTK_PHY_VCO_SLICER_THRESH_BITS_HIGH_EEE_MASK,
+- FIELD_PREP(MTK_PHY_VCO_SLICER_THRESH_BITS_HIGH_EEE_MASK,
+- 0x33) |
+- MTK_PHY_LPI_SKIP_SD_SLV_TR | MTK_PHY_LPI_TR_READY |
+- MTK_PHY_LPI_VCO_EEE_STG0_EN);
+-
+- phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG323,
+- MTK_PHY_EEE_WAKE_MAS_INT_DC |
+- MTK_PHY_EEE_WAKE_SLV_INT_DC);
+-
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG324,
+- MTK_PHY_SMI_DETCNT_MAX_MASK,
+- FIELD_PREP(MTK_PHY_SMI_DETCNT_MAX_MASK, 0x3f) |
+- MTK_PHY_SMI_DET_MAX_EN);
+-
+- phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG326,
+- MTK_PHY_LPI_MODE_SD_ON | MTK_PHY_RESET_RANDUPD_CNT |
+- MTK_PHY_TREC_UPDATE_ENAB_CLR |
+- MTK_PHY_LPI_QUIT_WAIT_DFE_SIG_DET_OFF |
+- MTK_PHY_TR_READY_SKIP_AFE_WAKEUP);
+-
+- phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
+- /* Regsigdet_sel_1000 = 0 */
+- __phy_write(phydev, 0x11, 0xb);
+- __phy_write(phydev, 0x12, 0x0);
+- __phy_write(phydev, 0x10, 0x9690);
+-
+- /* REG_EEE_st2TrKf1000 = 2 */
+- __phy_write(phydev, 0x11, 0x114f);
+- __phy_write(phydev, 0x12, 0x2);
+- __phy_write(phydev, 0x10, 0x969a);
+-
+- /* RegEEE_slv_wake_tr_timer_tar = 6, RegEEE_slv_remtx_timer_tar = 20 */
+- __phy_write(phydev, 0x11, 0x3028);
+- __phy_write(phydev, 0x12, 0x0);
+- __phy_write(phydev, 0x10, 0x969e);
+-
+- /* RegEEE_slv_wake_int_timer_tar = 8 */
+- __phy_write(phydev, 0x11, 0x5010);
+- __phy_write(phydev, 0x12, 0x0);
+- __phy_write(phydev, 0x10, 0x96a0);
+-
+- /* RegEEE_trfreeze_timer2 = 586 */
+- __phy_write(phydev, 0x11, 0x24a);
+- __phy_write(phydev, 0x12, 0x0);
+- __phy_write(phydev, 0x10, 0x96a8);
+-
+- /* RegEEE100Stg1_tar = 16 */
+- __phy_write(phydev, 0x11, 0x3210);
+- __phy_write(phydev, 0x12, 0x0);
+- __phy_write(phydev, 0x10, 0x96b8);
+-
+- /* REGEEE_wake_slv_tr_wait_dfesigdet_en = 0 */
+- __phy_write(phydev, 0x11, 0x1463);
+- __phy_write(phydev, 0x12, 0x0);
+- __phy_write(phydev, 0x10, 0x96ca);
+-
+- /* DfeTailEnableVgaThresh1000 = 27 */
+- __phy_write(phydev, 0x11, 0x36);
+- __phy_write(phydev, 0x12, 0x0);
+- __phy_write(phydev, 0x10, 0x8f80);
+- phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
+-
+- phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_3);
+- __phy_modify(phydev, MTK_PHY_LPI_REG_14, MTK_PHY_LPI_WAKE_TIMER_1000_MASK,
+- FIELD_PREP(MTK_PHY_LPI_WAKE_TIMER_1000_MASK, 0x19c));
+-
+- __phy_modify(phydev, MTK_PHY_LPI_REG_1c, MTK_PHY_SMI_DET_ON_THRESH_MASK,
+- FIELD_PREP(MTK_PHY_SMI_DET_ON_THRESH_MASK, 0xc));
+- phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
+-
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1,
+- MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG122,
+- MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK,
+- FIELD_PREP(MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK, 0xff));
+-}
+-
+-static int cal_sw(struct phy_device *phydev, enum CAL_ITEM cal_item,
+- u8 start_pair, u8 end_pair)
+-{
+- u8 pair_n;
+- int ret;
+-
+- for (pair_n = start_pair; pair_n <= end_pair; pair_n++) {
+- /* TX_OFFSET & TX_AMP have no SW calibration. */
+- switch (cal_item) {
+- case TX_VCM:
+- ret = tx_vcm_cal_sw(phydev, pair_n);
+- break;
+- default:
+- return -EINVAL;
+- }
+- if (ret)
+- return ret;
+- }
+- return 0;
+-}
+-
+-static int cal_efuse(struct phy_device *phydev, enum CAL_ITEM cal_item,
+- u8 start_pair, u8 end_pair, u32 *buf)
+-{
+- u8 pair_n;
+- int ret;
+-
+- for (pair_n = start_pair; pair_n <= end_pair; pair_n++) {
+- /* TX_VCM has no efuse calibration. */
+- switch (cal_item) {
+- case REXT:
+- ret = rext_cal_efuse(phydev, buf);
+- break;
+- case TX_OFFSET:
+- ret = tx_offset_cal_efuse(phydev, buf);
+- break;
+- case TX_AMP:
+- ret = tx_amp_cal_efuse(phydev, buf);
+- break;
+- case TX_R50:
+- ret = tx_r50_cal_efuse(phydev, buf, pair_n);
+- break;
+- default:
+- return -EINVAL;
+- }
+- if (ret)
+- return ret;
+- }
+-
+- return 0;
+-}
+-
+-static int start_cal(struct phy_device *phydev, enum CAL_ITEM cal_item,
+- enum CAL_MODE cal_mode, u8 start_pair,
+- u8 end_pair, u32 *buf)
+-{
+- int ret;
+-
+- switch (cal_mode) {
+- case EFUSE_M:
+- ret = cal_efuse(phydev, cal_item, start_pair,
+- end_pair, buf);
+- break;
+- case SW_M:
+- ret = cal_sw(phydev, cal_item, start_pair, end_pair);
+- break;
+- default:
+- return -EINVAL;
+- }
+-
+- if (ret) {
+- phydev_err(phydev, "cal %d failed\n", cal_item);
+- return -EIO;
+- }
+-
+- return 0;
+-}
+-
+-static int mt798x_phy_calibration(struct phy_device *phydev)
+-{
+- int ret = 0;
+- u32 *buf;
+- size_t len;
+- struct nvmem_cell *cell;
+-
+- cell = nvmem_cell_get(&phydev->mdio.dev, "phy-cal-data");
+- if (IS_ERR(cell)) {
+- if (PTR_ERR(cell) == -EPROBE_DEFER)
+- return PTR_ERR(cell);
+- return 0;
+- }
+-
+- buf = (u32 *)nvmem_cell_read(cell, &len);
+- if (IS_ERR(buf))
+- return PTR_ERR(buf);
+- nvmem_cell_put(cell);
+-
+- if (!buf[0] || !buf[1] || !buf[2] || !buf[3] || len < 4 * sizeof(u32)) {
+- phydev_err(phydev, "invalid efuse data\n");
+- ret = -EINVAL;
+- goto out;
+- }
+-
+- ret = start_cal(phydev, REXT, EFUSE_M, NO_PAIR, NO_PAIR, buf);
+- if (ret)
+- goto out;
+- ret = start_cal(phydev, TX_OFFSET, EFUSE_M, NO_PAIR, NO_PAIR, buf);
+- if (ret)
+- goto out;
+- ret = start_cal(phydev, TX_AMP, EFUSE_M, NO_PAIR, NO_PAIR, buf);
+- if (ret)
+- goto out;
+- ret = start_cal(phydev, TX_R50, EFUSE_M, PAIR_A, PAIR_D, buf);
+- if (ret)
+- goto out;
+- ret = start_cal(phydev, TX_VCM, SW_M, PAIR_A, PAIR_A, buf);
+- if (ret)
+- goto out;
+-
+-out:
+- kfree(buf);
+- return ret;
+-}
+-
+-static int mt798x_phy_config_init(struct phy_device *phydev)
+-{
+- switch (phydev->drv->phy_id) {
+- case MTK_GPHY_ID_MT7981:
+- mt7981_phy_finetune(phydev);
+- break;
+- case MTK_GPHY_ID_MT7988:
+- mt7988_phy_finetune(phydev);
+- break;
+- }
+-
+- mt798x_phy_common_finetune(phydev);
+- mt798x_phy_eee(phydev);
+-
+- return mt798x_phy_calibration(phydev);
+-}
+-
+-static int mt798x_phy_hw_led_on_set(struct phy_device *phydev, u8 index,
+- bool on)
+-{
+- unsigned int bit_on = MTK_PHY_LED_STATE_FORCE_ON + (index ? 16 : 0);
+- struct mtk_socphy_priv *priv = phydev->priv;
+- bool changed;
+-
+- if (on)
+- changed = !test_and_set_bit(bit_on, &priv->led_state);
+- else
+- changed = !!test_and_clear_bit(bit_on, &priv->led_state);
+-
+- changed |= !!test_and_clear_bit(MTK_PHY_LED_STATE_NETDEV +
+- (index ? 16 : 0), &priv->led_state);
+- if (changed)
+- return phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ?
+- MTK_PHY_LED1_ON_CTRL : MTK_PHY_LED0_ON_CTRL,
+- MTK_PHY_LED_ON_MASK,
+- on ? MTK_PHY_LED_ON_FORCE_ON : 0);
+- else
+- return 0;
+-}
+-
+-static int mt798x_phy_hw_led_blink_set(struct phy_device *phydev, u8 index,
+- bool blinking)
+-{
+- unsigned int bit_blink = MTK_PHY_LED_STATE_FORCE_BLINK + (index ? 16 : 0);
+- struct mtk_socphy_priv *priv = phydev->priv;
+- bool changed;
+-
+- if (blinking)
+- changed = !test_and_set_bit(bit_blink, &priv->led_state);
+- else
+- changed = !!test_and_clear_bit(bit_blink, &priv->led_state);
+-
+- changed |= !!test_bit(MTK_PHY_LED_STATE_NETDEV +
+- (index ? 16 : 0), &priv->led_state);
+- if (changed)
+- return phy_write_mmd(phydev, MDIO_MMD_VEND2, index ?
+- MTK_PHY_LED1_BLINK_CTRL : MTK_PHY_LED0_BLINK_CTRL,
+- blinking ? MTK_PHY_LED_BLINK_FORCE_BLINK : 0);
+- else
+- return 0;
+-}
+-
+-static int mt798x_phy_led_blink_set(struct phy_device *phydev, u8 index,
+- unsigned long *delay_on,
+- unsigned long *delay_off)
+-{
+- bool blinking = false;
+- int err = 0;
+-
+- if (index > 1)
+- return -EINVAL;
+-
+- if (delay_on && delay_off && (*delay_on > 0) && (*delay_off > 0)) {
+- blinking = true;
+- *delay_on = 50;
+- *delay_off = 50;
+- }
+-
+- err = mt798x_phy_hw_led_blink_set(phydev, index, blinking);
+- if (err)
+- return err;
+-
+- return mt798x_phy_hw_led_on_set(phydev, index, false);
+-}
+-
+-static int mt798x_phy_led_brightness_set(struct phy_device *phydev,
+- u8 index, enum led_brightness value)
+-{
+- int err;
+-
+- err = mt798x_phy_hw_led_blink_set(phydev, index, false);
+- if (err)
+- return err;
+-
+- return mt798x_phy_hw_led_on_set(phydev, index, (value != LED_OFF));
+-}
+-
+-static const unsigned long supported_triggers = (BIT(TRIGGER_NETDEV_FULL_DUPLEX) |
+- BIT(TRIGGER_NETDEV_HALF_DUPLEX) |
+- BIT(TRIGGER_NETDEV_LINK) |
+- BIT(TRIGGER_NETDEV_LINK_10) |
+- BIT(TRIGGER_NETDEV_LINK_100) |
+- BIT(TRIGGER_NETDEV_LINK_1000) |
+- BIT(TRIGGER_NETDEV_RX) |
+- BIT(TRIGGER_NETDEV_TX));
+-
+-static int mt798x_phy_led_hw_is_supported(struct phy_device *phydev, u8 index,
+- unsigned long rules)
+-{
+- if (index > 1)
+- return -EINVAL;
+-
+- /* All combinations of the supported triggers are allowed */
+- if (rules & ~supported_triggers)
+- return -EOPNOTSUPP;
+-
+- return 0;
+-};
+-
+-static int mt798x_phy_led_hw_control_get(struct phy_device *phydev, u8 index,
+- unsigned long *rules)
+-{
+- unsigned int bit_blink = MTK_PHY_LED_STATE_FORCE_BLINK + (index ? 16 : 0);
+- unsigned int bit_netdev = MTK_PHY_LED_STATE_NETDEV + (index ? 16 : 0);
+- unsigned int bit_on = MTK_PHY_LED_STATE_FORCE_ON + (index ? 16 : 0);
+- struct mtk_socphy_priv *priv = phydev->priv;
+- int on, blink;
+-
+- if (index > 1)
+- return -EINVAL;
+-
+- on = phy_read_mmd(phydev, MDIO_MMD_VEND2,
+- index ? MTK_PHY_LED1_ON_CTRL : MTK_PHY_LED0_ON_CTRL);
+-
+- if (on < 0)
+- return -EIO;
+-
+- blink = phy_read_mmd(phydev, MDIO_MMD_VEND2,
+- index ? MTK_PHY_LED1_BLINK_CTRL :
+- MTK_PHY_LED0_BLINK_CTRL);
+- if (blink < 0)
+- return -EIO;
+-
+- if ((on & (MTK_PHY_LED_ON_LINK | MTK_PHY_LED_ON_FDX | MTK_PHY_LED_ON_HDX |
+- MTK_PHY_LED_ON_LINKDOWN)) ||
+- (blink & (MTK_PHY_LED_BLINK_RX | MTK_PHY_LED_BLINK_TX)))
+- set_bit(bit_netdev, &priv->led_state);
+- else
+- clear_bit(bit_netdev, &priv->led_state);
+-
+- if (on & MTK_PHY_LED_ON_FORCE_ON)
+- set_bit(bit_on, &priv->led_state);
+- else
+- clear_bit(bit_on, &priv->led_state);
+-
+- if (blink & MTK_PHY_LED_BLINK_FORCE_BLINK)
+- set_bit(bit_blink, &priv->led_state);
+- else
+- clear_bit(bit_blink, &priv->led_state);
+-
+- if (!rules)
+- return 0;
+-
+- if (on & MTK_PHY_LED_ON_LINK)
+- *rules |= BIT(TRIGGER_NETDEV_LINK);
+-
+- if (on & MTK_PHY_LED_ON_LINK10)
+- *rules |= BIT(TRIGGER_NETDEV_LINK_10);
+-
+- if (on & MTK_PHY_LED_ON_LINK100)
+- *rules |= BIT(TRIGGER_NETDEV_LINK_100);
+-
+- if (on & MTK_PHY_LED_ON_LINK1000)
+- *rules |= BIT(TRIGGER_NETDEV_LINK_1000);
+-
+- if (on & MTK_PHY_LED_ON_FDX)
+- *rules |= BIT(TRIGGER_NETDEV_FULL_DUPLEX);
+-
+- if (on & MTK_PHY_LED_ON_HDX)
+- *rules |= BIT(TRIGGER_NETDEV_HALF_DUPLEX);
+-
+- if (blink & MTK_PHY_LED_BLINK_RX)
+- *rules |= BIT(TRIGGER_NETDEV_RX);
+-
+- if (blink & MTK_PHY_LED_BLINK_TX)
+- *rules |= BIT(TRIGGER_NETDEV_TX);
+-
+- return 0;
+-};
+-
+-static int mt798x_phy_led_hw_control_set(struct phy_device *phydev, u8 index,
+- unsigned long rules)
+-{
+- unsigned int bit_netdev = MTK_PHY_LED_STATE_NETDEV + (index ? 16 : 0);
+- struct mtk_socphy_priv *priv = phydev->priv;
+- u16 on = 0, blink = 0;
+- int ret;
+-
+- if (index > 1)
+- return -EINVAL;
+-
+- if (rules & BIT(TRIGGER_NETDEV_FULL_DUPLEX))
+- on |= MTK_PHY_LED_ON_FDX;
+-
+- if (rules & BIT(TRIGGER_NETDEV_HALF_DUPLEX))
+- on |= MTK_PHY_LED_ON_HDX;
+-
+- if (rules & (BIT(TRIGGER_NETDEV_LINK_10) | BIT(TRIGGER_NETDEV_LINK)))
+- on |= MTK_PHY_LED_ON_LINK10;
+-
+- if (rules & (BIT(TRIGGER_NETDEV_LINK_100) | BIT(TRIGGER_NETDEV_LINK)))
+- on |= MTK_PHY_LED_ON_LINK100;
+-
+- if (rules & (BIT(TRIGGER_NETDEV_LINK_1000) | BIT(TRIGGER_NETDEV_LINK)))
+- on |= MTK_PHY_LED_ON_LINK1000;
+-
+- if (rules & BIT(TRIGGER_NETDEV_RX)) {
+- blink |= (on & MTK_PHY_LED_ON_LINK) ?
+- (((on & MTK_PHY_LED_ON_LINK10) ? MTK_PHY_LED_BLINK_10RX : 0) |
+- ((on & MTK_PHY_LED_ON_LINK100) ? MTK_PHY_LED_BLINK_100RX : 0) |
+- ((on & MTK_PHY_LED_ON_LINK1000) ? MTK_PHY_LED_BLINK_1000RX : 0)) :
+- MTK_PHY_LED_BLINK_RX;
+- }
+-
+- if (rules & BIT(TRIGGER_NETDEV_TX)) {
+- blink |= (on & MTK_PHY_LED_ON_LINK) ?
+- (((on & MTK_PHY_LED_ON_LINK10) ? MTK_PHY_LED_BLINK_10TX : 0) |
+- ((on & MTK_PHY_LED_ON_LINK100) ? MTK_PHY_LED_BLINK_100TX : 0) |
+- ((on & MTK_PHY_LED_ON_LINK1000) ? MTK_PHY_LED_BLINK_1000TX : 0)) :
+- MTK_PHY_LED_BLINK_TX;
+- }
+-
+- if (blink || on)
+- set_bit(bit_netdev, &priv->led_state);
+- else
+- clear_bit(bit_netdev, &priv->led_state);
+-
+- ret = phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ?
+- MTK_PHY_LED1_ON_CTRL :
+- MTK_PHY_LED0_ON_CTRL,
+- MTK_PHY_LED_ON_FDX |
+- MTK_PHY_LED_ON_HDX |
+- MTK_PHY_LED_ON_LINK,
+- on);
+-
+- if (ret)
+- return ret;
+-
+- return phy_write_mmd(phydev, MDIO_MMD_VEND2, index ?
+- MTK_PHY_LED1_BLINK_CTRL :
+- MTK_PHY_LED0_BLINK_CTRL, blink);
+-};
+-
+-static bool mt7988_phy_led_get_polarity(struct phy_device *phydev, int led_num)
+-{
+- struct mtk_socphy_shared *priv = phydev->shared->priv;
+- u32 polarities;
+-
+- if (led_num == 0)
+- polarities = ~(priv->boottrap);
+- else
+- polarities = MTK_PHY_LED1_DEFAULT_POLARITIES;
+-
+- if (polarities & BIT(phydev->mdio.addr))
+- return true;
+-
+- return false;
+-}
+-
+-static int mt7988_phy_fix_leds_polarities(struct phy_device *phydev)
+-{
+- struct pinctrl *pinctrl;
+- int index;
+-
+- /* Setup LED polarity according to bootstrap use of LED pins */
+- for (index = 0; index < 2; ++index)
+- phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ?
+- MTK_PHY_LED1_ON_CTRL : MTK_PHY_LED0_ON_CTRL,
+- MTK_PHY_LED_ON_POLARITY,
+- mt7988_phy_led_get_polarity(phydev, index) ?
+- MTK_PHY_LED_ON_POLARITY : 0);
+-
+- /* Only now setup pinctrl to avoid bogus blinking */
+- pinctrl = devm_pinctrl_get_select(&phydev->mdio.dev, "gbe-led");
+- if (IS_ERR(pinctrl))
+- dev_err(&phydev->mdio.bus->dev, "Failed to setup PHY LED pinctrl\n");
+-
+- return 0;
+-}
+-
+-static int mt7988_phy_probe_shared(struct phy_device *phydev)
+-{
+- struct device_node *np = dev_of_node(&phydev->mdio.bus->dev);
+- struct mtk_socphy_shared *shared = phydev->shared->priv;
+- struct regmap *regmap;
+- u32 reg;
+- int ret;
+-
+- /* The LED0 of the 4 PHYs in MT7988 are wired to SoC pins LED_A, LED_B,
+- * LED_C and LED_D respectively. At the same time those pins are used to
+- * bootstrap configuration of the reference clock source (LED_A),
+- * DRAM DDRx16b x2/x1 (LED_B) and boot device (LED_C, LED_D).
+- * In practise this is done using a LED and a resistor pulling the pin
+- * either to GND or to VIO.
+- * The detected value at boot time is accessible at run-time using the
+- * TPBANK0 register located in the gpio base of the pinctrl, in order
+- * to read it here it needs to be referenced by a phandle called
+- * 'mediatek,pio' in the MDIO bus hosting the PHY.
+- * The 4 bits in TPBANK0 are kept as package shared data and are used to
+- * set LED polarity for each of the LED0.
+- */
+- regmap = syscon_regmap_lookup_by_phandle(np, "mediatek,pio");
+- if (IS_ERR(regmap))
+- return PTR_ERR(regmap);
+-
+- ret = regmap_read(regmap, RG_GPIO_MISC_TPBANK0, &reg);
+- if (ret)
+- return ret;
+-
+- shared->boottrap = FIELD_GET(RG_GPIO_MISC_TPBANK0_BOOTMODE, reg);
+-
+- return 0;
+-}
+-
+-static void mt798x_phy_leds_state_init(struct phy_device *phydev)
+-{
+- int i;
+-
+- for (i = 0; i < 2; ++i)
+- mt798x_phy_led_hw_control_get(phydev, i, NULL);
+-}
+-
+-static int mt7988_phy_probe(struct phy_device *phydev)
+-{
+- struct mtk_socphy_shared *shared;
+- struct mtk_socphy_priv *priv;
+- int err;
+-
+- if (phydev->mdio.addr > 3)
+- return -EINVAL;
+-
+- err = devm_phy_package_join(&phydev->mdio.dev, phydev, 0,
+- sizeof(struct mtk_socphy_shared));
+- if (err)
+- return err;
+-
+- if (phy_package_probe_once(phydev)) {
+- err = mt7988_phy_probe_shared(phydev);
+- if (err)
+- return err;
+- }
+-
+- shared = phydev->shared->priv;
+- priv = &shared->priv[phydev->mdio.addr];
+-
+- phydev->priv = priv;
+-
+- mt798x_phy_leds_state_init(phydev);
+-
+- err = mt7988_phy_fix_leds_polarities(phydev);
+- if (err)
+- return err;
+-
+- /* Disable TX power saving at probing to:
+- * 1. Meet common mode compliance test criteria
+- * 2. Make sure that TX-VCM calibration works fine
+- */
+- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG7,
+- MTK_PHY_DA_AD_BUF_BIAS_LP_MASK, 0x3 << 8);
+-
+- return mt798x_phy_calibration(phydev);
+-}
+-
+-static int mt7981_phy_probe(struct phy_device *phydev)
+-{
+- struct mtk_socphy_priv *priv;
+-
+- priv = devm_kzalloc(&phydev->mdio.dev, sizeof(struct mtk_socphy_priv),
+- GFP_KERNEL);
+- if (!priv)
+- return -ENOMEM;
+-
+- phydev->priv = priv;
+-
+- mt798x_phy_leds_state_init(phydev);
+-
+- return mt798x_phy_calibration(phydev);
+-}
+-
+-static struct phy_driver mtk_socphy_driver[] = {
+- {
+- PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7981),
+- .name = "MediaTek MT7981 PHY",
+- .config_init = mt798x_phy_config_init,
+- .config_intr = genphy_no_config_intr,
+- .handle_interrupt = genphy_handle_interrupt_no_ack,
+- .probe = mt7981_phy_probe,
+- .suspend = genphy_suspend,
+- .resume = genphy_resume,
+- .read_page = mtk_socphy_read_page,
+- .write_page = mtk_socphy_write_page,
+- .led_blink_set = mt798x_phy_led_blink_set,
+- .led_brightness_set = mt798x_phy_led_brightness_set,
+- .led_hw_is_supported = mt798x_phy_led_hw_is_supported,
+- .led_hw_control_set = mt798x_phy_led_hw_control_set,
+- .led_hw_control_get = mt798x_phy_led_hw_control_get,
+- },
+- {
+- PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7988),
+- .name = "MediaTek MT7988 PHY",
+- .config_init = mt798x_phy_config_init,
+- .config_intr = genphy_no_config_intr,
+- .handle_interrupt = genphy_handle_interrupt_no_ack,
+- .probe = mt7988_phy_probe,
+- .suspend = genphy_suspend,
+- .resume = genphy_resume,
+- .read_page = mtk_socphy_read_page,
+- .write_page = mtk_socphy_write_page,
+- .led_blink_set = mt798x_phy_led_blink_set,
+- .led_brightness_set = mt798x_phy_led_brightness_set,
+- .led_hw_is_supported = mt798x_phy_led_hw_is_supported,
+- .led_hw_control_set = mt798x_phy_led_hw_control_set,
+- .led_hw_control_get = mt798x_phy_led_hw_control_get,
+- },
+-};
+-
+-module_phy_driver(mtk_socphy_driver);
+-
+-static struct mdio_device_id __maybe_unused mtk_socphy_tbl[] = {
+- { PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7981) },
+- { PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7988) },
+- { }
+-};
+-
+-MODULE_DESCRIPTION("MediaTek SoC Gigabit Ethernet PHY driver");
+-MODULE_AUTHOR("Daniel Golle <daniel@makrotopia.org>");
+-MODULE_AUTHOR("SkyLake Huang <SkyLake.Huang@mediatek.com>");
+-MODULE_LICENSE("GPL");
+-
+-MODULE_DEVICE_TABLE(mdio, mtk_socphy_tbl);
+--- a/drivers/net/phy/mediatek-ge.c
++++ /dev/null
+@@ -1,148 +0,0 @@
+-// SPDX-License-Identifier: GPL-2.0+
+-#include <linux/of.h>
+-#include <linux/bitfield.h>
+-#include <linux/module.h>
+-#include <linux/phy.h>
+-
+-#define MTK_EXT_PAGE_ACCESS 0x1f
+-#define MTK_PHY_PAGE_STANDARD 0x0000
+-#define MTK_PHY_PAGE_EXTENDED 0x0001
+-#define MTK_PHY_PAGE_EXTENDED_2 0x0002
+-#define MTK_PHY_PAGE_EXTENDED_3 0x0003
+-#define MTK_PHY_PAGE_EXTENDED_2A30 0x2a30
+-#define MTK_PHY_PAGE_EXTENDED_52B5 0x52b5
+-
+-static int mtk_gephy_read_page(struct phy_device *phydev)
+-{
+- return __phy_read(phydev, MTK_EXT_PAGE_ACCESS);
+-}
+-
+-static int mtk_gephy_write_page(struct phy_device *phydev, int page)
+-{
+- return __phy_write(phydev, MTK_EXT_PAGE_ACCESS, page);
+-}
+-
+-static void mtk_gephy_config_init(struct phy_device *phydev)
+-{
+- /* Disable EEE */
+- phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0);
+-
+- /* Enable HW auto downshift */
+- phy_modify_paged(phydev, MTK_PHY_PAGE_EXTENDED, 0x14, 0, BIT(4));
+-
+- /* Increase SlvDPSready time */
+- phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
+- __phy_write(phydev, 0x10, 0xafae);
+- __phy_write(phydev, 0x12, 0x2f);
+- __phy_write(phydev, 0x10, 0x8fae);
+- phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
+-
+- /* Adjust 100_mse_threshold */
+- phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x123, 0xffff);
+-
+- /* Disable mcc */
+- phy_write_mmd(phydev, MDIO_MMD_VEND1, 0xa6, 0x300);
+-}
+-
+-static int mt7530_phy_config_init(struct phy_device *phydev)
+-{
+- mtk_gephy_config_init(phydev);
+-
+- /* Increase post_update_timer */
+- phy_write_paged(phydev, MTK_PHY_PAGE_EXTENDED_3, 0x11, 0x4b);
+-
+- return 0;
+-}
+-
+-static int mt7530_led_config_of(struct phy_device *phydev)
+-{
+- struct device_node *np = phydev->mdio.dev.of_node;
+- const __be32 *paddr;
+- int len;
+- int i;
+-
+- paddr = of_get_property(np, "mediatek,led-config", &len);
+- if (!paddr)
+- return 0;
+-
+- if (len < (2 * sizeof(*paddr)))
+- return -EINVAL;
+-
+- len /= sizeof(*paddr);
+-
+- phydev_warn(phydev, "Configure LED registers (num=%d)\n", len);
+- for (i = 0; i < len - 1; i += 2) {
+- u32 reg;
+- u32 val;
+-
+- reg = be32_to_cpup(paddr + i);
+- val = be32_to_cpup(paddr + i + 1);
+-
+- phy_write_mmd(phydev, MDIO_MMD_VEND2, reg, val);
+- }
+-
+- return 0;
+-}
+-
+-static int mt7531_phy_config_init(struct phy_device *phydev)
+-{
+- mtk_gephy_config_init(phydev);
+-
+- /* PHY link down power saving enable */
+- phy_set_bits(phydev, 0x17, BIT(4));
+- phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, 0xc6, 0x300);
+-
+- /* Set TX Pair delay selection */
+- phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x13, 0x404);
+- phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x14, 0x404);
+-
+- /* LED Config*/
+- mt7530_led_config_of(phydev);
+-
+- return 0;
+-}
+-
+-static struct phy_driver mtk_gephy_driver[] = {
+- {
+- PHY_ID_MATCH_EXACT(0x03a29412),
+- .name = "MediaTek MT7530 PHY",
+- .config_init = mt7530_phy_config_init,
+- /* Interrupts are handled by the switch, not the PHY
+- * itself.
+- */
+- .config_intr = genphy_no_config_intr,
+- .handle_interrupt = genphy_handle_interrupt_no_ack,
+- .suspend = genphy_suspend,
+- .resume = genphy_resume,
+- .read_page = mtk_gephy_read_page,
+- .write_page = mtk_gephy_write_page,
+- },
+- {
+- PHY_ID_MATCH_EXACT(0x03a29441),
+- .name = "MediaTek MT7531 PHY",
+- .config_init = mt7531_phy_config_init,
+- /* Interrupts are handled by the switch, not the PHY
+- * itself.
+- */
+- .config_intr = genphy_no_config_intr,
+- .handle_interrupt = genphy_handle_interrupt_no_ack,
+- .suspend = genphy_suspend,
+- .resume = genphy_resume,
+- .read_page = mtk_gephy_read_page,
+- .write_page = mtk_gephy_write_page,
+- },
+-};
+-
+-module_phy_driver(mtk_gephy_driver);
+-
+-static struct mdio_device_id __maybe_unused mtk_gephy_tbl[] = {
+- { PHY_ID_MATCH_EXACT(0x03a29441) },
+- { PHY_ID_MATCH_EXACT(0x03a29412) },
+- { }
+-};
+-
+-MODULE_DESCRIPTION("MediaTek Gigabit Ethernet PHY driver");
+-MODULE_AUTHOR("DENG, Qingfang <dqfext@gmail.com>");
+-MODULE_LICENSE("GPL");
+-
+-MODULE_DEVICE_TABLE(mdio, mtk_gephy_tbl);
+--- /dev/null
++++ b/drivers/net/phy/mediatek/mtk-ge-soc.c
+@@ -0,0 +1,1555 @@
++// SPDX-License-Identifier: GPL-2.0+
++#include <linux/bitfield.h>
++#include <linux/bitmap.h>
++#include <linux/mfd/syscon.h>
++#include <linux/module.h>
++#include <linux/nvmem-consumer.h>
++#include <linux/pinctrl/consumer.h>
++#include <linux/phy.h>
++#include <linux/regmap.h>
++
++#define MTK_GPHY_ID_MT7981 0x03a29461
++#define MTK_GPHY_ID_MT7988 0x03a29481
++
++#define MTK_EXT_PAGE_ACCESS 0x1f
++#define MTK_PHY_PAGE_STANDARD 0x0000
++#define MTK_PHY_PAGE_EXTENDED_3 0x0003
++
++#define MTK_PHY_LPI_REG_14 0x14
++#define MTK_PHY_LPI_WAKE_TIMER_1000_MASK GENMASK(8, 0)
++
++#define MTK_PHY_LPI_REG_1c 0x1c
++#define MTK_PHY_SMI_DET_ON_THRESH_MASK GENMASK(13, 8)
++
++#define MTK_PHY_PAGE_EXTENDED_2A30 0x2a30
++#define MTK_PHY_PAGE_EXTENDED_52B5 0x52b5
++
++#define ANALOG_INTERNAL_OPERATION_MAX_US 20
++#define TXRESERVE_MIN 0
++#define TXRESERVE_MAX 7
++
++#define MTK_PHY_ANARG_RG 0x10
++#define MTK_PHY_TCLKOFFSET_MASK GENMASK(12, 8)
++
++/* Registers on MDIO_MMD_VEND1 */
++#define MTK_PHY_TXVLD_DA_RG 0x12
++#define MTK_PHY_DA_TX_I2MPB_A_GBE_MASK GENMASK(15, 10)
++#define MTK_PHY_DA_TX_I2MPB_A_TBT_MASK GENMASK(5, 0)
++
++#define MTK_PHY_TX_I2MPB_TEST_MODE_A2 0x16
++#define MTK_PHY_DA_TX_I2MPB_A_HBT_MASK GENMASK(15, 10)
++#define MTK_PHY_DA_TX_I2MPB_A_TST_MASK GENMASK(5, 0)
++
++#define MTK_PHY_TX_I2MPB_TEST_MODE_B1 0x17
++#define MTK_PHY_DA_TX_I2MPB_B_GBE_MASK GENMASK(13, 8)
++#define MTK_PHY_DA_TX_I2MPB_B_TBT_MASK GENMASK(5, 0)
++
++#define MTK_PHY_TX_I2MPB_TEST_MODE_B2 0x18
++#define MTK_PHY_DA_TX_I2MPB_B_HBT_MASK GENMASK(13, 8)
++#define MTK_PHY_DA_TX_I2MPB_B_TST_MASK GENMASK(5, 0)
++
++#define MTK_PHY_TX_I2MPB_TEST_MODE_C1 0x19
++#define MTK_PHY_DA_TX_I2MPB_C_GBE_MASK GENMASK(13, 8)
++#define MTK_PHY_DA_TX_I2MPB_C_TBT_MASK GENMASK(5, 0)
++
++#define MTK_PHY_TX_I2MPB_TEST_MODE_C2 0x20
++#define MTK_PHY_DA_TX_I2MPB_C_HBT_MASK GENMASK(13, 8)
++#define MTK_PHY_DA_TX_I2MPB_C_TST_MASK GENMASK(5, 0)
++
++#define MTK_PHY_TX_I2MPB_TEST_MODE_D1 0x21
++#define MTK_PHY_DA_TX_I2MPB_D_GBE_MASK GENMASK(13, 8)
++#define MTK_PHY_DA_TX_I2MPB_D_TBT_MASK GENMASK(5, 0)
++
++#define MTK_PHY_TX_I2MPB_TEST_MODE_D2 0x22
++#define MTK_PHY_DA_TX_I2MPB_D_HBT_MASK GENMASK(13, 8)
++#define MTK_PHY_DA_TX_I2MPB_D_TST_MASK GENMASK(5, 0)
++
++#define MTK_PHY_RXADC_CTRL_RG7 0xc6
++#define MTK_PHY_DA_AD_BUF_BIAS_LP_MASK GENMASK(9, 8)
++
++#define MTK_PHY_RXADC_CTRL_RG9 0xc8
++#define MTK_PHY_DA_RX_PSBN_TBT_MASK GENMASK(14, 12)
++#define MTK_PHY_DA_RX_PSBN_HBT_MASK GENMASK(10, 8)
++#define MTK_PHY_DA_RX_PSBN_GBE_MASK GENMASK(6, 4)
++#define MTK_PHY_DA_RX_PSBN_LP_MASK GENMASK(2, 0)
++
++#define MTK_PHY_LDO_OUTPUT_V 0xd7
++
++#define MTK_PHY_RG_ANA_CAL_RG0 0xdb
++#define MTK_PHY_RG_CAL_CKINV BIT(12)
++#define MTK_PHY_RG_ANA_CALEN BIT(8)
++#define MTK_PHY_RG_ZCALEN_A BIT(0)
++
++#define MTK_PHY_RG_ANA_CAL_RG1 0xdc
++#define MTK_PHY_RG_ZCALEN_B BIT(12)
++#define MTK_PHY_RG_ZCALEN_C BIT(8)
++#define MTK_PHY_RG_ZCALEN_D BIT(4)
++#define MTK_PHY_RG_TXVOS_CALEN BIT(0)
++
++#define MTK_PHY_RG_ANA_CAL_RG5 0xe0
++#define MTK_PHY_RG_REXT_TRIM_MASK GENMASK(13, 8)
++
++#define MTK_PHY_RG_TX_FILTER 0xfe
++
++#define MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG120 0x120
++#define MTK_PHY_LPI_SIG_EN_LO_THRESH1000_MASK GENMASK(12, 8)
++#define MTK_PHY_LPI_SIG_EN_HI_THRESH1000_MASK GENMASK(4, 0)
++
++#define MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG122 0x122
++#define MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK GENMASK(7, 0)
++
++#define MTK_PHY_RG_TESTMUX_ADC_CTRL 0x144
++#define MTK_PHY_RG_TXEN_DIG_MASK GENMASK(5, 5)
++
++#define MTK_PHY_RG_CR_TX_AMP_OFFSET_A_B 0x172
++#define MTK_PHY_CR_TX_AMP_OFFSET_A_MASK GENMASK(13, 8)
++#define MTK_PHY_CR_TX_AMP_OFFSET_B_MASK GENMASK(6, 0)
++
++#define MTK_PHY_RG_CR_TX_AMP_OFFSET_C_D 0x173
++#define MTK_PHY_CR_TX_AMP_OFFSET_C_MASK GENMASK(13, 8)
++#define MTK_PHY_CR_TX_AMP_OFFSET_D_MASK GENMASK(6, 0)
++
++#define MTK_PHY_RG_AD_CAL_COMP 0x17a
++#define MTK_PHY_AD_CAL_COMP_OUT_SHIFT (8)
++
++#define MTK_PHY_RG_AD_CAL_CLK 0x17b
++#define MTK_PHY_DA_CAL_CLK BIT(0)
++
++#define MTK_PHY_RG_AD_CALIN 0x17c
++#define MTK_PHY_DA_CALIN_FLAG BIT(0)
++
++#define MTK_PHY_RG_DASN_DAC_IN0_A 0x17d
++#define MTK_PHY_DASN_DAC_IN0_A_MASK GENMASK(9, 0)
++
++#define MTK_PHY_RG_DASN_DAC_IN0_B 0x17e
++#define MTK_PHY_DASN_DAC_IN0_B_MASK GENMASK(9, 0)
++
++#define MTK_PHY_RG_DASN_DAC_IN0_C 0x17f
++#define MTK_PHY_DASN_DAC_IN0_C_MASK GENMASK(9, 0)
++
++#define MTK_PHY_RG_DASN_DAC_IN0_D 0x180
++#define MTK_PHY_DASN_DAC_IN0_D_MASK GENMASK(9, 0)
++
++#define MTK_PHY_RG_DASN_DAC_IN1_A 0x181
++#define MTK_PHY_DASN_DAC_IN1_A_MASK GENMASK(9, 0)
++
++#define MTK_PHY_RG_DASN_DAC_IN1_B 0x182
++#define MTK_PHY_DASN_DAC_IN1_B_MASK GENMASK(9, 0)
++
++#define MTK_PHY_RG_DASN_DAC_IN1_C 0x183
++#define MTK_PHY_DASN_DAC_IN1_C_MASK GENMASK(9, 0)
++
++#define MTK_PHY_RG_DASN_DAC_IN1_D 0x184
++#define MTK_PHY_DASN_DAC_IN1_D_MASK GENMASK(9, 0)
++
++#define MTK_PHY_RG_DEV1E_REG19b 0x19b
++#define MTK_PHY_BYPASS_DSP_LPI_READY BIT(8)
++
++#define MTK_PHY_RG_LP_IIR2_K1_L 0x22a
++#define MTK_PHY_RG_LP_IIR2_K1_U 0x22b
++#define MTK_PHY_RG_LP_IIR2_K2_L 0x22c
++#define MTK_PHY_RG_LP_IIR2_K2_U 0x22d
++#define MTK_PHY_RG_LP_IIR2_K3_L 0x22e
++#define MTK_PHY_RG_LP_IIR2_K3_U 0x22f
++#define MTK_PHY_RG_LP_IIR2_K4_L 0x230
++#define MTK_PHY_RG_LP_IIR2_K4_U 0x231
++#define MTK_PHY_RG_LP_IIR2_K5_L 0x232
++#define MTK_PHY_RG_LP_IIR2_K5_U 0x233
++
++#define MTK_PHY_RG_DEV1E_REG234 0x234
++#define MTK_PHY_TR_OPEN_LOOP_EN_MASK GENMASK(0, 0)
++#define MTK_PHY_LPF_X_AVERAGE_MASK GENMASK(7, 4)
++#define MTK_PHY_TR_LP_IIR_EEE_EN BIT(12)
++
++#define MTK_PHY_RG_LPF_CNT_VAL 0x235
++
++#define MTK_PHY_RG_DEV1E_REG238 0x238
++#define MTK_PHY_LPI_SLV_SEND_TX_TIMER_MASK GENMASK(8, 0)
++#define MTK_PHY_LPI_SLV_SEND_TX_EN BIT(12)
++
++#define MTK_PHY_RG_DEV1E_REG239 0x239
++#define MTK_PHY_LPI_SEND_LOC_TIMER_MASK GENMASK(8, 0)
++#define MTK_PHY_LPI_TXPCS_LOC_RCV BIT(12)
++
++#define MTK_PHY_RG_DEV1E_REG27C 0x27c
++#define MTK_PHY_VGASTATE_FFE_THR_ST1_MASK GENMASK(12, 8)
++#define MTK_PHY_RG_DEV1E_REG27D 0x27d
++#define MTK_PHY_VGASTATE_FFE_THR_ST2_MASK GENMASK(4, 0)
++
++#define MTK_PHY_RG_DEV1E_REG2C7 0x2c7
++#define MTK_PHY_MAX_GAIN_MASK GENMASK(4, 0)
++#define MTK_PHY_MIN_GAIN_MASK GENMASK(12, 8)
++
++#define MTK_PHY_RG_DEV1E_REG2D1 0x2d1
++#define MTK_PHY_VCO_SLICER_THRESH_BITS_HIGH_EEE_MASK GENMASK(7, 0)
++#define MTK_PHY_LPI_SKIP_SD_SLV_TR BIT(8)
++#define MTK_PHY_LPI_TR_READY BIT(9)
++#define MTK_PHY_LPI_VCO_EEE_STG0_EN BIT(10)
++
++#define MTK_PHY_RG_DEV1E_REG323 0x323
++#define MTK_PHY_EEE_WAKE_MAS_INT_DC BIT(0)
++#define MTK_PHY_EEE_WAKE_SLV_INT_DC BIT(4)
++
++#define MTK_PHY_RG_DEV1E_REG324 0x324
++#define MTK_PHY_SMI_DETCNT_MAX_MASK GENMASK(5, 0)
++#define MTK_PHY_SMI_DET_MAX_EN BIT(8)
++
++#define MTK_PHY_RG_DEV1E_REG326 0x326
++#define MTK_PHY_LPI_MODE_SD_ON BIT(0)
++#define MTK_PHY_RESET_RANDUPD_CNT BIT(1)
++#define MTK_PHY_TREC_UPDATE_ENAB_CLR BIT(2)
++#define MTK_PHY_LPI_QUIT_WAIT_DFE_SIG_DET_OFF BIT(4)
++#define MTK_PHY_TR_READY_SKIP_AFE_WAKEUP BIT(5)
++
++#define MTK_PHY_LDO_PUMP_EN_PAIRAB 0x502
++#define MTK_PHY_LDO_PUMP_EN_PAIRCD 0x503
++
++#define MTK_PHY_DA_TX_R50_PAIR_A 0x53d
++#define MTK_PHY_DA_TX_R50_PAIR_B 0x53e
++#define MTK_PHY_DA_TX_R50_PAIR_C 0x53f
++#define MTK_PHY_DA_TX_R50_PAIR_D 0x540
++
++/* Registers on MDIO_MMD_VEND2 */
++#define MTK_PHY_LED0_ON_CTRL 0x24
++#define MTK_PHY_LED1_ON_CTRL 0x26
++#define MTK_PHY_LED_ON_MASK GENMASK(6, 0)
++#define MTK_PHY_LED_ON_LINK1000 BIT(0)
++#define MTK_PHY_LED_ON_LINK100 BIT(1)
++#define MTK_PHY_LED_ON_LINK10 BIT(2)
++#define MTK_PHY_LED_ON_LINK (MTK_PHY_LED_ON_LINK10 |\
++ MTK_PHY_LED_ON_LINK100 |\
++ MTK_PHY_LED_ON_LINK1000)
++#define MTK_PHY_LED_ON_LINKDOWN BIT(3)
++#define MTK_PHY_LED_ON_FDX BIT(4) /* Full duplex */
++#define MTK_PHY_LED_ON_HDX BIT(5) /* Half duplex */
++#define MTK_PHY_LED_ON_FORCE_ON BIT(6)
++#define MTK_PHY_LED_ON_POLARITY BIT(14)
++#define MTK_PHY_LED_ON_ENABLE BIT(15)
++
++#define MTK_PHY_LED0_BLINK_CTRL 0x25
++#define MTK_PHY_LED1_BLINK_CTRL 0x27
++#define MTK_PHY_LED_BLINK_1000TX BIT(0)
++#define MTK_PHY_LED_BLINK_1000RX BIT(1)
++#define MTK_PHY_LED_BLINK_100TX BIT(2)
++#define MTK_PHY_LED_BLINK_100RX BIT(3)
++#define MTK_PHY_LED_BLINK_10TX BIT(4)
++#define MTK_PHY_LED_BLINK_10RX BIT(5)
++#define MTK_PHY_LED_BLINK_RX (MTK_PHY_LED_BLINK_10RX |\
++ MTK_PHY_LED_BLINK_100RX |\
++ MTK_PHY_LED_BLINK_1000RX)
++#define MTK_PHY_LED_BLINK_TX (MTK_PHY_LED_BLINK_10TX |\
++ MTK_PHY_LED_BLINK_100TX |\
++ MTK_PHY_LED_BLINK_1000TX)
++#define MTK_PHY_LED_BLINK_COLLISION BIT(6)
++#define MTK_PHY_LED_BLINK_RX_CRC_ERR BIT(7)
++#define MTK_PHY_LED_BLINK_RX_IDLE_ERR BIT(8)
++#define MTK_PHY_LED_BLINK_FORCE_BLINK BIT(9)
++
++#define MTK_PHY_LED1_DEFAULT_POLARITIES BIT(1)
++
++#define MTK_PHY_RG_BG_RASEL 0x115
++#define MTK_PHY_RG_BG_RASEL_MASK GENMASK(2, 0)
++
++/* 'boottrap' register reflecting the configuration of the 4 PHY LEDs */
++#define RG_GPIO_MISC_TPBANK0 0x6f0
++#define RG_GPIO_MISC_TPBANK0_BOOTMODE GENMASK(11, 8)
++
++/* These macro privides efuse parsing for internal phy. */
++#define EFS_DA_TX_I2MPB_A(x) (((x) >> 0) & GENMASK(5, 0))
++#define EFS_DA_TX_I2MPB_B(x) (((x) >> 6) & GENMASK(5, 0))
++#define EFS_DA_TX_I2MPB_C(x) (((x) >> 12) & GENMASK(5, 0))
++#define EFS_DA_TX_I2MPB_D(x) (((x) >> 18) & GENMASK(5, 0))
++#define EFS_DA_TX_AMP_OFFSET_A(x) (((x) >> 24) & GENMASK(5, 0))
++
++#define EFS_DA_TX_AMP_OFFSET_B(x) (((x) >> 0) & GENMASK(5, 0))
++#define EFS_DA_TX_AMP_OFFSET_C(x) (((x) >> 6) & GENMASK(5, 0))
++#define EFS_DA_TX_AMP_OFFSET_D(x) (((x) >> 12) & GENMASK(5, 0))
++#define EFS_DA_TX_R50_A(x) (((x) >> 18) & GENMASK(5, 0))
++#define EFS_DA_TX_R50_B(x) (((x) >> 24) & GENMASK(5, 0))
++
++#define EFS_DA_TX_R50_C(x) (((x) >> 0) & GENMASK(5, 0))
++#define EFS_DA_TX_R50_D(x) (((x) >> 6) & GENMASK(5, 0))
++
++#define EFS_RG_BG_RASEL(x) (((x) >> 4) & GENMASK(2, 0))
++#define EFS_RG_REXT_TRIM(x) (((x) >> 7) & GENMASK(5, 0))
++
++enum {
++ NO_PAIR,
++ PAIR_A,
++ PAIR_B,
++ PAIR_C,
++ PAIR_D,
++};
++
++enum calibration_mode {
++ EFUSE_K,
++ SW_K
++};
++
++enum CAL_ITEM {
++ REXT,
++ TX_OFFSET,
++ TX_AMP,
++ TX_R50,
++ TX_VCM
++};
++
++enum CAL_MODE {
++ EFUSE_M,
++ SW_M
++};
++
++#define MTK_PHY_LED_STATE_FORCE_ON 0
++#define MTK_PHY_LED_STATE_FORCE_BLINK 1
++#define MTK_PHY_LED_STATE_NETDEV 2
++
++struct mtk_socphy_priv {
++ unsigned long led_state;
++};
++
++struct mtk_socphy_shared {
++ u32 boottrap;
++ struct mtk_socphy_priv priv[4];
++};
++
++static int mtk_socphy_read_page(struct phy_device *phydev)
++{
++ return __phy_read(phydev, MTK_EXT_PAGE_ACCESS);
++}
++
++static int mtk_socphy_write_page(struct phy_device *phydev, int page)
++{
++ return __phy_write(phydev, MTK_EXT_PAGE_ACCESS, page);
++}
++
++/* One calibration cycle consists of:
++ * 1.Set DA_CALIN_FLAG high to start calibration. Keep it high
++ * until AD_CAL_COMP is ready to output calibration result.
++ * 2.Wait until DA_CAL_CLK is available.
++ * 3.Fetch AD_CAL_COMP_OUT.
++ */
++static int cal_cycle(struct phy_device *phydev, int devad,
++ u32 regnum, u16 mask, u16 cal_val)
++{
++ int reg_val;
++ int ret;
++
++ phy_modify_mmd(phydev, devad, regnum,
++ mask, cal_val);
++ phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_AD_CALIN,
++ MTK_PHY_DA_CALIN_FLAG);
++
++ ret = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1,
++ MTK_PHY_RG_AD_CAL_CLK, reg_val,
++ reg_val & MTK_PHY_DA_CAL_CLK, 500,
++ ANALOG_INTERNAL_OPERATION_MAX_US, false);
++ if (ret) {
++ phydev_err(phydev, "Calibration cycle timeout\n");
++ return ret;
++ }
++
++ phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_AD_CALIN,
++ MTK_PHY_DA_CALIN_FLAG);
++ ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_AD_CAL_COMP) >>
++ MTK_PHY_AD_CAL_COMP_OUT_SHIFT;
++ phydev_dbg(phydev, "cal_val: 0x%x, ret: %d\n", cal_val, ret);
++
++ return ret;
++}
++
++static int rext_fill_result(struct phy_device *phydev, u16 *buf)
++{
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
++ MTK_PHY_RG_REXT_TRIM_MASK, buf[0] << 8);
++ phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_BG_RASEL,
++ MTK_PHY_RG_BG_RASEL_MASK, buf[1]);
++
++ return 0;
++}
++
++static int rext_cal_efuse(struct phy_device *phydev, u32 *buf)
++{
++ u16 rext_cal_val[2];
++
++ rext_cal_val[0] = EFS_RG_REXT_TRIM(buf[3]);
++ rext_cal_val[1] = EFS_RG_BG_RASEL(buf[3]);
++ rext_fill_result(phydev, rext_cal_val);
++
++ return 0;
++}
++
++static int tx_offset_fill_result(struct phy_device *phydev, u16 *buf)
++{
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_CR_TX_AMP_OFFSET_A_B,
++ MTK_PHY_CR_TX_AMP_OFFSET_A_MASK, buf[0] << 8);
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_CR_TX_AMP_OFFSET_A_B,
++ MTK_PHY_CR_TX_AMP_OFFSET_B_MASK, buf[1]);
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_CR_TX_AMP_OFFSET_C_D,
++ MTK_PHY_CR_TX_AMP_OFFSET_C_MASK, buf[2] << 8);
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_CR_TX_AMP_OFFSET_C_D,
++ MTK_PHY_CR_TX_AMP_OFFSET_D_MASK, buf[3]);
++
++ return 0;
++}
++
++static int tx_offset_cal_efuse(struct phy_device *phydev, u32 *buf)
++{
++ u16 tx_offset_cal_val[4];
++
++ tx_offset_cal_val[0] = EFS_DA_TX_AMP_OFFSET_A(buf[0]);
++ tx_offset_cal_val[1] = EFS_DA_TX_AMP_OFFSET_B(buf[1]);
++ tx_offset_cal_val[2] = EFS_DA_TX_AMP_OFFSET_C(buf[1]);
++ tx_offset_cal_val[3] = EFS_DA_TX_AMP_OFFSET_D(buf[1]);
++
++ tx_offset_fill_result(phydev, tx_offset_cal_val);
++
++ return 0;
++}
++
++static int tx_amp_fill_result(struct phy_device *phydev, u16 *buf)
++{
++ int i;
++ int bias[16] = {};
++ const int vals_9461[16] = { 7, 1, 4, 7,
++ 7, 1, 4, 7,
++ 7, 1, 4, 7,
++ 7, 1, 4, 7 };
++ const int vals_9481[16] = { 10, 6, 6, 10,
++ 10, 6, 6, 10,
++ 10, 6, 6, 10,
++ 10, 6, 6, 10 };
++ switch (phydev->drv->phy_id) {
++ case MTK_GPHY_ID_MT7981:
++ /* We add some calibration to efuse values
++ * due to board level influence.
++ * GBE: +7, TBT: +1, HBT: +4, TST: +7
++ */
++ memcpy(bias, (const void *)vals_9461, sizeof(bias));
++ break;
++ case MTK_GPHY_ID_MT7988:
++ memcpy(bias, (const void *)vals_9481, sizeof(bias));
++ break;
++ }
++
++ /* Prevent overflow */
++ for (i = 0; i < 12; i++) {
++ if (buf[i >> 2] + bias[i] > 63) {
++ buf[i >> 2] = 63;
++ bias[i] = 0;
++ }
++ }
++
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG,
++ MTK_PHY_DA_TX_I2MPB_A_GBE_MASK, (buf[0] + bias[0]) << 10);
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG,
++ MTK_PHY_DA_TX_I2MPB_A_TBT_MASK, buf[0] + bias[1]);
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2,
++ MTK_PHY_DA_TX_I2MPB_A_HBT_MASK, (buf[0] + bias[2]) << 10);
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2,
++ MTK_PHY_DA_TX_I2MPB_A_TST_MASK, buf[0] + bias[3]);
++
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1,
++ MTK_PHY_DA_TX_I2MPB_B_GBE_MASK, (buf[1] + bias[4]) << 8);
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1,
++ MTK_PHY_DA_TX_I2MPB_B_TBT_MASK, buf[1] + bias[5]);
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2,
++ MTK_PHY_DA_TX_I2MPB_B_HBT_MASK, (buf[1] + bias[6]) << 8);
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2,
++ MTK_PHY_DA_TX_I2MPB_B_TST_MASK, buf[1] + bias[7]);
++
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1,
++ MTK_PHY_DA_TX_I2MPB_C_GBE_MASK, (buf[2] + bias[8]) << 8);
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1,
++ MTK_PHY_DA_TX_I2MPB_C_TBT_MASK, buf[2] + bias[9]);
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2,
++ MTK_PHY_DA_TX_I2MPB_C_HBT_MASK, (buf[2] + bias[10]) << 8);
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2,
++ MTK_PHY_DA_TX_I2MPB_C_TST_MASK, buf[2] + bias[11]);
++
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1,
++ MTK_PHY_DA_TX_I2MPB_D_GBE_MASK, (buf[3] + bias[12]) << 8);
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1,
++ MTK_PHY_DA_TX_I2MPB_D_TBT_MASK, buf[3] + bias[13]);
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2,
++ MTK_PHY_DA_TX_I2MPB_D_HBT_MASK, (buf[3] + bias[14]) << 8);
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2,
++ MTK_PHY_DA_TX_I2MPB_D_TST_MASK, buf[3] + bias[15]);
++
++ return 0;
++}
++
++static int tx_amp_cal_efuse(struct phy_device *phydev, u32 *buf)
++{
++ u16 tx_amp_cal_val[4];
++
++ tx_amp_cal_val[0] = EFS_DA_TX_I2MPB_A(buf[0]);
++ tx_amp_cal_val[1] = EFS_DA_TX_I2MPB_B(buf[0]);
++ tx_amp_cal_val[2] = EFS_DA_TX_I2MPB_C(buf[0]);
++ tx_amp_cal_val[3] = EFS_DA_TX_I2MPB_D(buf[0]);
++ tx_amp_fill_result(phydev, tx_amp_cal_val);
++
++ return 0;
++}
++
++static int tx_r50_fill_result(struct phy_device *phydev, u16 tx_r50_cal_val,
++ u8 txg_calen_x)
++{
++ int bias = 0;
++ u16 reg, val;
++
++ if (phydev->drv->phy_id == MTK_GPHY_ID_MT7988)
++ bias = -1;
++
++ val = clamp_val(bias + tx_r50_cal_val, 0, 63);
++
++ switch (txg_calen_x) {
++ case PAIR_A:
++ reg = MTK_PHY_DA_TX_R50_PAIR_A;
++ break;
++ case PAIR_B:
++ reg = MTK_PHY_DA_TX_R50_PAIR_B;
++ break;
++ case PAIR_C:
++ reg = MTK_PHY_DA_TX_R50_PAIR_C;
++ break;
++ case PAIR_D:
++ reg = MTK_PHY_DA_TX_R50_PAIR_D;
++ break;
++ default:
++ return -EINVAL;
++ }
++
++ phy_write_mmd(phydev, MDIO_MMD_VEND1, reg, val | val << 8);
++
++ return 0;
++}
++
++static int tx_r50_cal_efuse(struct phy_device *phydev, u32 *buf,
++ u8 txg_calen_x)
++{
++ u16 tx_r50_cal_val;
++
++ switch (txg_calen_x) {
++ case PAIR_A:
++ tx_r50_cal_val = EFS_DA_TX_R50_A(buf[1]);
++ break;
++ case PAIR_B:
++ tx_r50_cal_val = EFS_DA_TX_R50_B(buf[1]);
++ break;
++ case PAIR_C:
++ tx_r50_cal_val = EFS_DA_TX_R50_C(buf[2]);
++ break;
++ case PAIR_D:
++ tx_r50_cal_val = EFS_DA_TX_R50_D(buf[2]);
++ break;
++ default:
++ return -EINVAL;
++ }
++ tx_r50_fill_result(phydev, tx_r50_cal_val, txg_calen_x);
++
++ return 0;
++}
++
++static int tx_vcm_cal_sw(struct phy_device *phydev, u8 rg_txreserve_x)
++{
++ u8 lower_idx, upper_idx, txreserve_val;
++ u8 lower_ret, upper_ret;
++ int ret;
++
++ phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
++ MTK_PHY_RG_ANA_CALEN);
++ phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
++ MTK_PHY_RG_CAL_CKINV);
++ phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
++ MTK_PHY_RG_TXVOS_CALEN);
++
++ switch (rg_txreserve_x) {
++ case PAIR_A:
++ phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
++ MTK_PHY_RG_DASN_DAC_IN0_A,
++ MTK_PHY_DASN_DAC_IN0_A_MASK);
++ phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
++ MTK_PHY_RG_DASN_DAC_IN1_A,
++ MTK_PHY_DASN_DAC_IN1_A_MASK);
++ phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
++ MTK_PHY_RG_ANA_CAL_RG0,
++ MTK_PHY_RG_ZCALEN_A);
++ break;
++ case PAIR_B:
++ phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
++ MTK_PHY_RG_DASN_DAC_IN0_B,
++ MTK_PHY_DASN_DAC_IN0_B_MASK);
++ phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
++ MTK_PHY_RG_DASN_DAC_IN1_B,
++ MTK_PHY_DASN_DAC_IN1_B_MASK);
++ phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
++ MTK_PHY_RG_ANA_CAL_RG1,
++ MTK_PHY_RG_ZCALEN_B);
++ break;
++ case PAIR_C:
++ phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
++ MTK_PHY_RG_DASN_DAC_IN0_C,
++ MTK_PHY_DASN_DAC_IN0_C_MASK);
++ phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
++ MTK_PHY_RG_DASN_DAC_IN1_C,
++ MTK_PHY_DASN_DAC_IN1_C_MASK);
++ phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
++ MTK_PHY_RG_ANA_CAL_RG1,
++ MTK_PHY_RG_ZCALEN_C);
++ break;
++ case PAIR_D:
++ phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
++ MTK_PHY_RG_DASN_DAC_IN0_D,
++ MTK_PHY_DASN_DAC_IN0_D_MASK);
++ phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
++ MTK_PHY_RG_DASN_DAC_IN1_D,
++ MTK_PHY_DASN_DAC_IN1_D_MASK);
++ phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
++ MTK_PHY_RG_ANA_CAL_RG1,
++ MTK_PHY_RG_ZCALEN_D);
++ break;
++ default:
++ ret = -EINVAL;
++ goto restore;
++ }
++
++ lower_idx = TXRESERVE_MIN;
++ upper_idx = TXRESERVE_MAX;
++
++ phydev_dbg(phydev, "Start TX-VCM SW cal.\n");
++ while ((upper_idx - lower_idx) > 1) {
++ txreserve_val = DIV_ROUND_CLOSEST(lower_idx + upper_idx, 2);
++ ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
++ MTK_PHY_DA_RX_PSBN_TBT_MASK |
++ MTK_PHY_DA_RX_PSBN_HBT_MASK |
++ MTK_PHY_DA_RX_PSBN_GBE_MASK |
++ MTK_PHY_DA_RX_PSBN_LP_MASK,
++ txreserve_val << 12 | txreserve_val << 8 |
++ txreserve_val << 4 | txreserve_val);
++ if (ret == 1) {
++ upper_idx = txreserve_val;
++ upper_ret = ret;
++ } else if (ret == 0) {
++ lower_idx = txreserve_val;
++ lower_ret = ret;
++ } else {
++ goto restore;
++ }
++ }
++
++ if (lower_idx == TXRESERVE_MIN) {
++ lower_ret = cal_cycle(phydev, MDIO_MMD_VEND1,
++ MTK_PHY_RXADC_CTRL_RG9,
++ MTK_PHY_DA_RX_PSBN_TBT_MASK |
++ MTK_PHY_DA_RX_PSBN_HBT_MASK |
++ MTK_PHY_DA_RX_PSBN_GBE_MASK |
++ MTK_PHY_DA_RX_PSBN_LP_MASK,
++ lower_idx << 12 | lower_idx << 8 |
++ lower_idx << 4 | lower_idx);
++ ret = lower_ret;
++ } else if (upper_idx == TXRESERVE_MAX) {
++ upper_ret = cal_cycle(phydev, MDIO_MMD_VEND1,
++ MTK_PHY_RXADC_CTRL_RG9,
++ MTK_PHY_DA_RX_PSBN_TBT_MASK |
++ MTK_PHY_DA_RX_PSBN_HBT_MASK |
++ MTK_PHY_DA_RX_PSBN_GBE_MASK |
++ MTK_PHY_DA_RX_PSBN_LP_MASK,
++ upper_idx << 12 | upper_idx << 8 |
++ upper_idx << 4 | upper_idx);
++ ret = upper_ret;
++ }
++ if (ret < 0)
++ goto restore;
++
++ /* We calibrate TX-VCM in different logic. Check upper index and then
++ * lower index. If this calibration is valid, apply lower index's result.
++ */
++ ret = upper_ret - lower_ret;
++ if (ret == 1) {
++ ret = 0;
++ /* Make sure we use upper_idx in our calibration system */
++ cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
++ MTK_PHY_DA_RX_PSBN_TBT_MASK |
++ MTK_PHY_DA_RX_PSBN_HBT_MASK |
++ MTK_PHY_DA_RX_PSBN_GBE_MASK |
++ MTK_PHY_DA_RX_PSBN_LP_MASK,
++ upper_idx << 12 | upper_idx << 8 |
++ upper_idx << 4 | upper_idx);
++ phydev_dbg(phydev, "TX-VCM SW cal result: 0x%x\n", upper_idx);
++ } else if (lower_idx == TXRESERVE_MIN && upper_ret == 1 &&
++ lower_ret == 1) {
++ ret = 0;
++ cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
++ MTK_PHY_DA_RX_PSBN_TBT_MASK |
++ MTK_PHY_DA_RX_PSBN_HBT_MASK |
++ MTK_PHY_DA_RX_PSBN_GBE_MASK |
++ MTK_PHY_DA_RX_PSBN_LP_MASK,
++ lower_idx << 12 | lower_idx << 8 |
++ lower_idx << 4 | lower_idx);
++ phydev_warn(phydev, "TX-VCM SW cal result at low margin 0x%x\n",
++ lower_idx);
++ } else if (upper_idx == TXRESERVE_MAX && upper_ret == 0 &&
++ lower_ret == 0) {
++ ret = 0;
++ phydev_warn(phydev, "TX-VCM SW cal result at high margin 0x%x\n",
++ upper_idx);
++ } else {
++ ret = -EINVAL;
++ }
++
++restore:
++ phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
++ MTK_PHY_RG_ANA_CALEN);
++ phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
++ MTK_PHY_RG_TXVOS_CALEN);
++ phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
++ MTK_PHY_RG_ZCALEN_A);
++ phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
++ MTK_PHY_RG_ZCALEN_B | MTK_PHY_RG_ZCALEN_C |
++ MTK_PHY_RG_ZCALEN_D);
++
++ return ret;
++}
++
++static void mt798x_phy_common_finetune(struct phy_device *phydev)
++{
++ phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
++ /* SlvDSPreadyTime = 24, MasDSPreadyTime = 24 */
++ __phy_write(phydev, 0x11, 0xc71);
++ __phy_write(phydev, 0x12, 0xc);
++ __phy_write(phydev, 0x10, 0x8fae);
++
++ /* EnabRandUpdTrig = 1 */
++ __phy_write(phydev, 0x11, 0x2f00);
++ __phy_write(phydev, 0x12, 0xe);
++ __phy_write(phydev, 0x10, 0x8fb0);
++
++ /* NormMseLoThresh = 85 */
++ __phy_write(phydev, 0x11, 0x55a0);
++ __phy_write(phydev, 0x12, 0x0);
++ __phy_write(phydev, 0x10, 0x83aa);
++
++ /* FfeUpdGainForce = 1(Enable), FfeUpdGainForceVal = 4 */
++ __phy_write(phydev, 0x11, 0x240);
++ __phy_write(phydev, 0x12, 0x0);
++ __phy_write(phydev, 0x10, 0x9680);
++
++ /* TrFreeze = 0 (mt7988 default) */
++ __phy_write(phydev, 0x11, 0x0);
++ __phy_write(phydev, 0x12, 0x0);
++ __phy_write(phydev, 0x10, 0x9686);
++
++ /* SSTrKp100 = 5 */
++ /* SSTrKf100 = 6 */
++ /* SSTrKp1000Mas = 5 */
++ /* SSTrKf1000Mas = 6 */
++ /* SSTrKp1000Slv = 5 */
++ /* SSTrKf1000Slv = 6 */
++ __phy_write(phydev, 0x11, 0xbaef);
++ __phy_write(phydev, 0x12, 0x2e);
++ __phy_write(phydev, 0x10, 0x968c);
++ phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
++}
++
++static void mt7981_phy_finetune(struct phy_device *phydev)
++{
++ u16 val[8] = { 0x01ce, 0x01c1,
++ 0x020f, 0x0202,
++ 0x03d0, 0x03c0,
++ 0x0013, 0x0005 };
++ int i, k;
++
++ /* 100M eye finetune:
++ * Keep middle level of TX MLT3 shapper as default.
++ * Only change TX MLT3 overshoot level here.
++ */
++ for (k = 0, i = 1; i < 12; i++) {
++ if (i % 3 == 0)
++ continue;
++ phy_write_mmd(phydev, MDIO_MMD_VEND1, i, val[k++]);
++ }
++
++ phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
++ /* ResetSyncOffset = 6 */
++ __phy_write(phydev, 0x11, 0x600);
++ __phy_write(phydev, 0x12, 0x0);
++ __phy_write(phydev, 0x10, 0x8fc0);
++
++ /* VgaDecRate = 1 */
++ __phy_write(phydev, 0x11, 0x4c2a);
++ __phy_write(phydev, 0x12, 0x3e);
++ __phy_write(phydev, 0x10, 0x8fa4);
++
++ /* MrvlTrFix100Kp = 3, MrvlTrFix100Kf = 2,
++ * MrvlTrFix1000Kp = 3, MrvlTrFix1000Kf = 2
++ */
++ __phy_write(phydev, 0x11, 0xd10a);
++ __phy_write(phydev, 0x12, 0x34);
++ __phy_write(phydev, 0x10, 0x8f82);
++
++ /* VcoSlicerThreshBitsHigh */
++ __phy_write(phydev, 0x11, 0x5555);
++ __phy_write(phydev, 0x12, 0x55);
++ __phy_write(phydev, 0x10, 0x8ec0);
++ phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
++
++ /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 9 */
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234,
++ MTK_PHY_TR_OPEN_LOOP_EN_MASK | MTK_PHY_LPF_X_AVERAGE_MASK,
++ BIT(0) | FIELD_PREP(MTK_PHY_LPF_X_AVERAGE_MASK, 0x9));
++
++ /* rg_tr_lpf_cnt_val = 512 */
++ phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LPF_CNT_VAL, 0x200);
++
++ /* IIR2 related */
++ phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K1_L, 0x82);
++ phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K1_U, 0x0);
++ phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K2_L, 0x103);
++ phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K2_U, 0x0);
++ phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K3_L, 0x82);
++ phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K3_U, 0x0);
++ phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K4_L, 0xd177);
++ phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K4_U, 0x3);
++ phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K5_L, 0x2c82);
++ phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K5_U, 0xe);
++
++ /* FFE peaking */
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG27C,
++ MTK_PHY_VGASTATE_FFE_THR_ST1_MASK, 0x1b << 8);
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG27D,
++ MTK_PHY_VGASTATE_FFE_THR_ST2_MASK, 0x1e);
++
++ /* Disable LDO pump */
++ phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LDO_PUMP_EN_PAIRAB, 0x0);
++ phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LDO_PUMP_EN_PAIRCD, 0x0);
++ /* Adjust LDO output voltage */
++ phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LDO_OUTPUT_V, 0x2222);
++}
++
++static void mt7988_phy_finetune(struct phy_device *phydev)
++{
++ u16 val[12] = { 0x0187, 0x01cd, 0x01c8, 0x0182,
++ 0x020d, 0x0206, 0x0384, 0x03d0,
++ 0x03c6, 0x030a, 0x0011, 0x0005 };
++ int i;
++
++ /* Set default MLT3 shaper first */
++ for (i = 0; i < 12; i++)
++ phy_write_mmd(phydev, MDIO_MMD_VEND1, i, val[i]);
++
++ /* TCT finetune */
++ phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_TX_FILTER, 0x5);
++
++ phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
++ /* ResetSyncOffset = 5 */
++ __phy_write(phydev, 0x11, 0x500);
++ __phy_write(phydev, 0x12, 0x0);
++ __phy_write(phydev, 0x10, 0x8fc0);
++
++ /* VgaDecRate is 1 at default on mt7988 */
++
++ /* MrvlTrFix100Kp = 6, MrvlTrFix100Kf = 7,
++ * MrvlTrFix1000Kp = 6, MrvlTrFix1000Kf = 7
++ */
++ __phy_write(phydev, 0x11, 0xb90a);
++ __phy_write(phydev, 0x12, 0x6f);
++ __phy_write(phydev, 0x10, 0x8f82);
++
++ /* RemAckCntLimitCtrl = 1 */
++ __phy_write(phydev, 0x11, 0xfbba);
++ __phy_write(phydev, 0x12, 0xc3);
++ __phy_write(phydev, 0x10, 0x87f8);
++
++ phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
++
++ /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 10 */
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234,
++ MTK_PHY_TR_OPEN_LOOP_EN_MASK | MTK_PHY_LPF_X_AVERAGE_MASK,
++ BIT(0) | FIELD_PREP(MTK_PHY_LPF_X_AVERAGE_MASK, 0xa));
++
++ /* rg_tr_lpf_cnt_val = 1023 */
++ phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LPF_CNT_VAL, 0x3ff);
++}
++
++static void mt798x_phy_eee(struct phy_device *phydev)
++{
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1,
++ MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG120,
++ MTK_PHY_LPI_SIG_EN_LO_THRESH1000_MASK |
++ MTK_PHY_LPI_SIG_EN_HI_THRESH1000_MASK,
++ FIELD_PREP(MTK_PHY_LPI_SIG_EN_LO_THRESH1000_MASK, 0x0) |
++ FIELD_PREP(MTK_PHY_LPI_SIG_EN_HI_THRESH1000_MASK, 0x14));
++
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1,
++ MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG122,
++ MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK,
++ FIELD_PREP(MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK,
++ 0xff));
++
++ phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
++ MTK_PHY_RG_TESTMUX_ADC_CTRL,
++ MTK_PHY_RG_TXEN_DIG_MASK);
++
++ phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
++ MTK_PHY_RG_DEV1E_REG19b, MTK_PHY_BYPASS_DSP_LPI_READY);
++
++ phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
++ MTK_PHY_RG_DEV1E_REG234, MTK_PHY_TR_LP_IIR_EEE_EN);
++
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG238,
++ MTK_PHY_LPI_SLV_SEND_TX_TIMER_MASK |
++ MTK_PHY_LPI_SLV_SEND_TX_EN,
++ FIELD_PREP(MTK_PHY_LPI_SLV_SEND_TX_TIMER_MASK, 0x120));
++
++ /* Keep MTK_PHY_LPI_SEND_LOC_TIMER as 375 */
++ phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG239,
++ MTK_PHY_LPI_TXPCS_LOC_RCV);
++
++ /* This also fixes some IoT issues, such as CH340 */
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG2C7,
++ MTK_PHY_MAX_GAIN_MASK | MTK_PHY_MIN_GAIN_MASK,
++ FIELD_PREP(MTK_PHY_MAX_GAIN_MASK, 0x8) |
++ FIELD_PREP(MTK_PHY_MIN_GAIN_MASK, 0x13));
++
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG2D1,
++ MTK_PHY_VCO_SLICER_THRESH_BITS_HIGH_EEE_MASK,
++ FIELD_PREP(MTK_PHY_VCO_SLICER_THRESH_BITS_HIGH_EEE_MASK,
++ 0x33) |
++ MTK_PHY_LPI_SKIP_SD_SLV_TR | MTK_PHY_LPI_TR_READY |
++ MTK_PHY_LPI_VCO_EEE_STG0_EN);
++
++ phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG323,
++ MTK_PHY_EEE_WAKE_MAS_INT_DC |
++ MTK_PHY_EEE_WAKE_SLV_INT_DC);
++
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG324,
++ MTK_PHY_SMI_DETCNT_MAX_MASK,
++ FIELD_PREP(MTK_PHY_SMI_DETCNT_MAX_MASK, 0x3f) |
++ MTK_PHY_SMI_DET_MAX_EN);
++
++ phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG326,
++ MTK_PHY_LPI_MODE_SD_ON | MTK_PHY_RESET_RANDUPD_CNT |
++ MTK_PHY_TREC_UPDATE_ENAB_CLR |
++ MTK_PHY_LPI_QUIT_WAIT_DFE_SIG_DET_OFF |
++ MTK_PHY_TR_READY_SKIP_AFE_WAKEUP);
++
++ phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
++ /* Regsigdet_sel_1000 = 0 */
++ __phy_write(phydev, 0x11, 0xb);
++ __phy_write(phydev, 0x12, 0x0);
++ __phy_write(phydev, 0x10, 0x9690);
++
++ /* REG_EEE_st2TrKf1000 = 2 */
++ __phy_write(phydev, 0x11, 0x114f);
++ __phy_write(phydev, 0x12, 0x2);
++ __phy_write(phydev, 0x10, 0x969a);
++
++ /* RegEEE_slv_wake_tr_timer_tar = 6, RegEEE_slv_remtx_timer_tar = 20 */
++ __phy_write(phydev, 0x11, 0x3028);
++ __phy_write(phydev, 0x12, 0x0);
++ __phy_write(phydev, 0x10, 0x969e);
++
++ /* RegEEE_slv_wake_int_timer_tar = 8 */
++ __phy_write(phydev, 0x11, 0x5010);
++ __phy_write(phydev, 0x12, 0x0);
++ __phy_write(phydev, 0x10, 0x96a0);
++
++ /* RegEEE_trfreeze_timer2 = 586 */
++ __phy_write(phydev, 0x11, 0x24a);
++ __phy_write(phydev, 0x12, 0x0);
++ __phy_write(phydev, 0x10, 0x96a8);
++
++ /* RegEEE100Stg1_tar = 16 */
++ __phy_write(phydev, 0x11, 0x3210);
++ __phy_write(phydev, 0x12, 0x0);
++ __phy_write(phydev, 0x10, 0x96b8);
++
++ /* REGEEE_wake_slv_tr_wait_dfesigdet_en = 0 */
++ __phy_write(phydev, 0x11, 0x1463);
++ __phy_write(phydev, 0x12, 0x0);
++ __phy_write(phydev, 0x10, 0x96ca);
++
++ /* DfeTailEnableVgaThresh1000 = 27 */
++ __phy_write(phydev, 0x11, 0x36);
++ __phy_write(phydev, 0x12, 0x0);
++ __phy_write(phydev, 0x10, 0x8f80);
++ phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
++
++ phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_3);
++ __phy_modify(phydev, MTK_PHY_LPI_REG_14, MTK_PHY_LPI_WAKE_TIMER_1000_MASK,
++ FIELD_PREP(MTK_PHY_LPI_WAKE_TIMER_1000_MASK, 0x19c));
++
++ __phy_modify(phydev, MTK_PHY_LPI_REG_1c, MTK_PHY_SMI_DET_ON_THRESH_MASK,
++ FIELD_PREP(MTK_PHY_SMI_DET_ON_THRESH_MASK, 0xc));
++ phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
++
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1,
++ MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG122,
++ MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK,
++ FIELD_PREP(MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK, 0xff));
++}
++
++static int cal_sw(struct phy_device *phydev, enum CAL_ITEM cal_item,
++ u8 start_pair, u8 end_pair)
++{
++ u8 pair_n;
++ int ret;
++
++ for (pair_n = start_pair; pair_n <= end_pair; pair_n++) {
++ /* TX_OFFSET & TX_AMP have no SW calibration. */
++ switch (cal_item) {
++ case TX_VCM:
++ ret = tx_vcm_cal_sw(phydev, pair_n);
++ break;
++ default:
++ return -EINVAL;
++ }
++ if (ret)
++ return ret;
++ }
++ return 0;
++}
++
++static int cal_efuse(struct phy_device *phydev, enum CAL_ITEM cal_item,
++ u8 start_pair, u8 end_pair, u32 *buf)
++{
++ u8 pair_n;
++ int ret;
++
++ for (pair_n = start_pair; pair_n <= end_pair; pair_n++) {
++ /* TX_VCM has no efuse calibration. */
++ switch (cal_item) {
++ case REXT:
++ ret = rext_cal_efuse(phydev, buf);
++ break;
++ case TX_OFFSET:
++ ret = tx_offset_cal_efuse(phydev, buf);
++ break;
++ case TX_AMP:
++ ret = tx_amp_cal_efuse(phydev, buf);
++ break;
++ case TX_R50:
++ ret = tx_r50_cal_efuse(phydev, buf, pair_n);
++ break;
++ default:
++ return -EINVAL;
++ }
++ if (ret)
++ return ret;
++ }
++
++ return 0;
++}
++
++static int start_cal(struct phy_device *phydev, enum CAL_ITEM cal_item,
++ enum CAL_MODE cal_mode, u8 start_pair,
++ u8 end_pair, u32 *buf)
++{
++ int ret;
++
++ switch (cal_mode) {
++ case EFUSE_M:
++ ret = cal_efuse(phydev, cal_item, start_pair,
++ end_pair, buf);
++ break;
++ case SW_M:
++ ret = cal_sw(phydev, cal_item, start_pair, end_pair);
++ break;
++ default:
++ return -EINVAL;
++ }
++
++ if (ret) {
++ phydev_err(phydev, "cal %d failed\n", cal_item);
++ return -EIO;
++ }
++
++ return 0;
++}
++
++static int mt798x_phy_calibration(struct phy_device *phydev)
++{
++ int ret = 0;
++ u32 *buf;
++ size_t len;
++ struct nvmem_cell *cell;
++
++ cell = nvmem_cell_get(&phydev->mdio.dev, "phy-cal-data");
++ if (IS_ERR(cell)) {
++ if (PTR_ERR(cell) == -EPROBE_DEFER)
++ return PTR_ERR(cell);
++ return 0;
++ }
++
++ buf = (u32 *)nvmem_cell_read(cell, &len);
++ if (IS_ERR(buf))
++ return PTR_ERR(buf);
++ nvmem_cell_put(cell);
++
++ if (!buf[0] || !buf[1] || !buf[2] || !buf[3] || len < 4 * sizeof(u32)) {
++ phydev_err(phydev, "invalid efuse data\n");
++ ret = -EINVAL;
++ goto out;
++ }
++
++ ret = start_cal(phydev, REXT, EFUSE_M, NO_PAIR, NO_PAIR, buf);
++ if (ret)
++ goto out;
++ ret = start_cal(phydev, TX_OFFSET, EFUSE_M, NO_PAIR, NO_PAIR, buf);
++ if (ret)
++ goto out;
++ ret = start_cal(phydev, TX_AMP, EFUSE_M, NO_PAIR, NO_PAIR, buf);
++ if (ret)
++ goto out;
++ ret = start_cal(phydev, TX_R50, EFUSE_M, PAIR_A, PAIR_D, buf);
++ if (ret)
++ goto out;
++ ret = start_cal(phydev, TX_VCM, SW_M, PAIR_A, PAIR_A, buf);
++ if (ret)
++ goto out;
++
++out:
++ kfree(buf);
++ return ret;
++}
++
++static int mt798x_phy_config_init(struct phy_device *phydev)
++{
++ switch (phydev->drv->phy_id) {
++ case MTK_GPHY_ID_MT7981:
++ mt7981_phy_finetune(phydev);
++ break;
++ case MTK_GPHY_ID_MT7988:
++ mt7988_phy_finetune(phydev);
++ break;
++ }
++
++ mt798x_phy_common_finetune(phydev);
++ mt798x_phy_eee(phydev);
++
++ return mt798x_phy_calibration(phydev);
++}
++
++static int mt798x_phy_hw_led_on_set(struct phy_device *phydev, u8 index,
++ bool on)
++{
++ unsigned int bit_on = MTK_PHY_LED_STATE_FORCE_ON + (index ? 16 : 0);
++ struct mtk_socphy_priv *priv = phydev->priv;
++ bool changed;
++
++ if (on)
++ changed = !test_and_set_bit(bit_on, &priv->led_state);
++ else
++ changed = !!test_and_clear_bit(bit_on, &priv->led_state);
++
++ changed |= !!test_and_clear_bit(MTK_PHY_LED_STATE_NETDEV +
++ (index ? 16 : 0), &priv->led_state);
++ if (changed)
++ return phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ?
++ MTK_PHY_LED1_ON_CTRL : MTK_PHY_LED0_ON_CTRL,
++ MTK_PHY_LED_ON_MASK,
++ on ? MTK_PHY_LED_ON_FORCE_ON : 0);
++ else
++ return 0;
++}
++
++static int mt798x_phy_hw_led_blink_set(struct phy_device *phydev, u8 index,
++ bool blinking)
++{
++ unsigned int bit_blink = MTK_PHY_LED_STATE_FORCE_BLINK + (index ? 16 : 0);
++ struct mtk_socphy_priv *priv = phydev->priv;
++ bool changed;
++
++ if (blinking)
++ changed = !test_and_set_bit(bit_blink, &priv->led_state);
++ else
++ changed = !!test_and_clear_bit(bit_blink, &priv->led_state);
++
++ changed |= !!test_bit(MTK_PHY_LED_STATE_NETDEV +
++ (index ? 16 : 0), &priv->led_state);
++ if (changed)
++ return phy_write_mmd(phydev, MDIO_MMD_VEND2, index ?
++ MTK_PHY_LED1_BLINK_CTRL : MTK_PHY_LED0_BLINK_CTRL,
++ blinking ? MTK_PHY_LED_BLINK_FORCE_BLINK : 0);
++ else
++ return 0;
++}
++
++static int mt798x_phy_led_blink_set(struct phy_device *phydev, u8 index,
++ unsigned long *delay_on,
++ unsigned long *delay_off)
++{
++ bool blinking = false;
++ int err = 0;
++
++ if (index > 1)
++ return -EINVAL;
++
++ if (delay_on && delay_off && (*delay_on > 0) && (*delay_off > 0)) {
++ blinking = true;
++ *delay_on = 50;
++ *delay_off = 50;
++ }
++
++ err = mt798x_phy_hw_led_blink_set(phydev, index, blinking);
++ if (err)
++ return err;
++
++ return mt798x_phy_hw_led_on_set(phydev, index, false);
++}
++
++static int mt798x_phy_led_brightness_set(struct phy_device *phydev,
++ u8 index, enum led_brightness value)
++{
++ int err;
++
++ err = mt798x_phy_hw_led_blink_set(phydev, index, false);
++ if (err)
++ return err;
++
++ return mt798x_phy_hw_led_on_set(phydev, index, (value != LED_OFF));
++}
++
++static const unsigned long supported_triggers = (BIT(TRIGGER_NETDEV_FULL_DUPLEX) |
++ BIT(TRIGGER_NETDEV_HALF_DUPLEX) |
++ BIT(TRIGGER_NETDEV_LINK) |
++ BIT(TRIGGER_NETDEV_LINK_10) |
++ BIT(TRIGGER_NETDEV_LINK_100) |
++ BIT(TRIGGER_NETDEV_LINK_1000) |
++ BIT(TRIGGER_NETDEV_RX) |
++ BIT(TRIGGER_NETDEV_TX));
++
++static int mt798x_phy_led_hw_is_supported(struct phy_device *phydev, u8 index,
++ unsigned long rules)
++{
++ if (index > 1)
++ return -EINVAL;
++
++ /* All combinations of the supported triggers are allowed */
++ if (rules & ~supported_triggers)
++ return -EOPNOTSUPP;
++
++ return 0;
++};
++
++static int mt798x_phy_led_hw_control_get(struct phy_device *phydev, u8 index,
++ unsigned long *rules)
++{
++ unsigned int bit_blink = MTK_PHY_LED_STATE_FORCE_BLINK + (index ? 16 : 0);
++ unsigned int bit_netdev = MTK_PHY_LED_STATE_NETDEV + (index ? 16 : 0);
++ unsigned int bit_on = MTK_PHY_LED_STATE_FORCE_ON + (index ? 16 : 0);
++ struct mtk_socphy_priv *priv = phydev->priv;
++ int on, blink;
++
++ if (index > 1)
++ return -EINVAL;
++
++ on = phy_read_mmd(phydev, MDIO_MMD_VEND2,
++ index ? MTK_PHY_LED1_ON_CTRL : MTK_PHY_LED0_ON_CTRL);
++
++ if (on < 0)
++ return -EIO;
++
++ blink = phy_read_mmd(phydev, MDIO_MMD_VEND2,
++ index ? MTK_PHY_LED1_BLINK_CTRL :
++ MTK_PHY_LED0_BLINK_CTRL);
++ if (blink < 0)
++ return -EIO;
++
++ if ((on & (MTK_PHY_LED_ON_LINK | MTK_PHY_LED_ON_FDX | MTK_PHY_LED_ON_HDX |
++ MTK_PHY_LED_ON_LINKDOWN)) ||
++ (blink & (MTK_PHY_LED_BLINK_RX | MTK_PHY_LED_BLINK_TX)))
++ set_bit(bit_netdev, &priv->led_state);
++ else
++ clear_bit(bit_netdev, &priv->led_state);
++
++ if (on & MTK_PHY_LED_ON_FORCE_ON)
++ set_bit(bit_on, &priv->led_state);
++ else
++ clear_bit(bit_on, &priv->led_state);
++
++ if (blink & MTK_PHY_LED_BLINK_FORCE_BLINK)
++ set_bit(bit_blink, &priv->led_state);
++ else
++ clear_bit(bit_blink, &priv->led_state);
++
++ if (!rules)
++ return 0;
++
++ if (on & MTK_PHY_LED_ON_LINK)
++ *rules |= BIT(TRIGGER_NETDEV_LINK);
++
++ if (on & MTK_PHY_LED_ON_LINK10)
++ *rules |= BIT(TRIGGER_NETDEV_LINK_10);
++
++ if (on & MTK_PHY_LED_ON_LINK100)
++ *rules |= BIT(TRIGGER_NETDEV_LINK_100);
++
++ if (on & MTK_PHY_LED_ON_LINK1000)
++ *rules |= BIT(TRIGGER_NETDEV_LINK_1000);
++
++ if (on & MTK_PHY_LED_ON_FDX)
++ *rules |= BIT(TRIGGER_NETDEV_FULL_DUPLEX);
++
++ if (on & MTK_PHY_LED_ON_HDX)
++ *rules |= BIT(TRIGGER_NETDEV_HALF_DUPLEX);
++
++ if (blink & MTK_PHY_LED_BLINK_RX)
++ *rules |= BIT(TRIGGER_NETDEV_RX);
++
++ if (blink & MTK_PHY_LED_BLINK_TX)
++ *rules |= BIT(TRIGGER_NETDEV_TX);
++
++ return 0;
++};
++
++static int mt798x_phy_led_hw_control_set(struct phy_device *phydev, u8 index,
++ unsigned long rules)
++{
++ unsigned int bit_netdev = MTK_PHY_LED_STATE_NETDEV + (index ? 16 : 0);
++ struct mtk_socphy_priv *priv = phydev->priv;
++ u16 on = 0, blink = 0;
++ int ret;
++
++ if (index > 1)
++ return -EINVAL;
++
++ if (rules & BIT(TRIGGER_NETDEV_FULL_DUPLEX))
++ on |= MTK_PHY_LED_ON_FDX;
++
++ if (rules & BIT(TRIGGER_NETDEV_HALF_DUPLEX))
++ on |= MTK_PHY_LED_ON_HDX;
++
++ if (rules & (BIT(TRIGGER_NETDEV_LINK_10) | BIT(TRIGGER_NETDEV_LINK)))
++ on |= MTK_PHY_LED_ON_LINK10;
++
++ if (rules & (BIT(TRIGGER_NETDEV_LINK_100) | BIT(TRIGGER_NETDEV_LINK)))
++ on |= MTK_PHY_LED_ON_LINK100;
++
++ if (rules & (BIT(TRIGGER_NETDEV_LINK_1000) | BIT(TRIGGER_NETDEV_LINK)))
++ on |= MTK_PHY_LED_ON_LINK1000;
++
++ if (rules & BIT(TRIGGER_NETDEV_RX)) {
++ blink |= (on & MTK_PHY_LED_ON_LINK) ?
++ (((on & MTK_PHY_LED_ON_LINK10) ? MTK_PHY_LED_BLINK_10RX : 0) |
++ ((on & MTK_PHY_LED_ON_LINK100) ? MTK_PHY_LED_BLINK_100RX : 0) |
++ ((on & MTK_PHY_LED_ON_LINK1000) ? MTK_PHY_LED_BLINK_1000RX : 0)) :
++ MTK_PHY_LED_BLINK_RX;
++ }
++
++ if (rules & BIT(TRIGGER_NETDEV_TX)) {
++ blink |= (on & MTK_PHY_LED_ON_LINK) ?
++ (((on & MTK_PHY_LED_ON_LINK10) ? MTK_PHY_LED_BLINK_10TX : 0) |
++ ((on & MTK_PHY_LED_ON_LINK100) ? MTK_PHY_LED_BLINK_100TX : 0) |
++ ((on & MTK_PHY_LED_ON_LINK1000) ? MTK_PHY_LED_BLINK_1000TX : 0)) :
++ MTK_PHY_LED_BLINK_TX;
++ }
++
++ if (blink || on)
++ set_bit(bit_netdev, &priv->led_state);
++ else
++ clear_bit(bit_netdev, &priv->led_state);
++
++ ret = phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ?
++ MTK_PHY_LED1_ON_CTRL :
++ MTK_PHY_LED0_ON_CTRL,
++ MTK_PHY_LED_ON_FDX |
++ MTK_PHY_LED_ON_HDX |
++ MTK_PHY_LED_ON_LINK,
++ on);
++
++ if (ret)
++ return ret;
++
++ return phy_write_mmd(phydev, MDIO_MMD_VEND2, index ?
++ MTK_PHY_LED1_BLINK_CTRL :
++ MTK_PHY_LED0_BLINK_CTRL, blink);
++};
++
++static bool mt7988_phy_led_get_polarity(struct phy_device *phydev, int led_num)
++{
++ struct mtk_socphy_shared *priv = phydev->shared->priv;
++ u32 polarities;
++
++ if (led_num == 0)
++ polarities = ~(priv->boottrap);
++ else
++ polarities = MTK_PHY_LED1_DEFAULT_POLARITIES;
++
++ if (polarities & BIT(phydev->mdio.addr))
++ return true;
++
++ return false;
++}
++
++static int mt7988_phy_fix_leds_polarities(struct phy_device *phydev)
++{
++ struct pinctrl *pinctrl;
++ int index;
++
++ /* Setup LED polarity according to bootstrap use of LED pins */
++ for (index = 0; index < 2; ++index)
++ phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ?
++ MTK_PHY_LED1_ON_CTRL : MTK_PHY_LED0_ON_CTRL,
++ MTK_PHY_LED_ON_POLARITY,
++ mt7988_phy_led_get_polarity(phydev, index) ?
++ MTK_PHY_LED_ON_POLARITY : 0);
++
++ /* Only now setup pinctrl to avoid bogus blinking */
++ pinctrl = devm_pinctrl_get_select(&phydev->mdio.dev, "gbe-led");
++ if (IS_ERR(pinctrl))
++ dev_err(&phydev->mdio.bus->dev, "Failed to setup PHY LED pinctrl\n");
++
++ return 0;
++}
++
++static int mt7988_phy_probe_shared(struct phy_device *phydev)
++{
++ struct device_node *np = dev_of_node(&phydev->mdio.bus->dev);
++ struct mtk_socphy_shared *shared = phydev->shared->priv;
++ struct regmap *regmap;
++ u32 reg;
++ int ret;
++
++ /* The LED0 of the 4 PHYs in MT7988 are wired to SoC pins LED_A, LED_B,
++ * LED_C and LED_D respectively. At the same time those pins are used to
++ * bootstrap configuration of the reference clock source (LED_A),
++ * DRAM DDRx16b x2/x1 (LED_B) and boot device (LED_C, LED_D).
++ * In practise this is done using a LED and a resistor pulling the pin
++ * either to GND or to VIO.
++ * The detected value at boot time is accessible at run-time using the
++ * TPBANK0 register located in the gpio base of the pinctrl, in order
++ * to read it here it needs to be referenced by a phandle called
++ * 'mediatek,pio' in the MDIO bus hosting the PHY.
++ * The 4 bits in TPBANK0 are kept as package shared data and are used to
++ * set LED polarity for each of the LED0.
++ */
++ regmap = syscon_regmap_lookup_by_phandle(np, "mediatek,pio");
++ if (IS_ERR(regmap))
++ return PTR_ERR(regmap);
++
++ ret = regmap_read(regmap, RG_GPIO_MISC_TPBANK0, &reg);
++ if (ret)
++ return ret;
++
++ shared->boottrap = FIELD_GET(RG_GPIO_MISC_TPBANK0_BOOTMODE, reg);
++
++ return 0;
++}
++
++static void mt798x_phy_leds_state_init(struct phy_device *phydev)
++{
++ int i;
++
++ for (i = 0; i < 2; ++i)
++ mt798x_phy_led_hw_control_get(phydev, i, NULL);
++}
++
++static int mt7988_phy_probe(struct phy_device *phydev)
++{
++ struct mtk_socphy_shared *shared;
++ struct mtk_socphy_priv *priv;
++ int err;
++
++ if (phydev->mdio.addr > 3)
++ return -EINVAL;
++
++ err = devm_phy_package_join(&phydev->mdio.dev, phydev, 0,
++ sizeof(struct mtk_socphy_shared));
++ if (err)
++ return err;
++
++ if (phy_package_probe_once(phydev)) {
++ err = mt7988_phy_probe_shared(phydev);
++ if (err)
++ return err;
++ }
++
++ shared = phydev->shared->priv;
++ priv = &shared->priv[phydev->mdio.addr];
++
++ phydev->priv = priv;
++
++ mt798x_phy_leds_state_init(phydev);
++
++ err = mt7988_phy_fix_leds_polarities(phydev);
++ if (err)
++ return err;
++
++ /* Disable TX power saving at probing to:
++ * 1. Meet common mode compliance test criteria
++ * 2. Make sure that TX-VCM calibration works fine
++ */
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG7,
++ MTK_PHY_DA_AD_BUF_BIAS_LP_MASK, 0x3 << 8);
++
++ return mt798x_phy_calibration(phydev);
++}
++
++static int mt7981_phy_probe(struct phy_device *phydev)
++{
++ struct mtk_socphy_priv *priv;
++
++ priv = devm_kzalloc(&phydev->mdio.dev, sizeof(struct mtk_socphy_priv),
++ GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ phydev->priv = priv;
++
++ mt798x_phy_leds_state_init(phydev);
++
++ return mt798x_phy_calibration(phydev);
++}
++
++static struct phy_driver mtk_socphy_driver[] = {
++ {
++ PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7981),
++ .name = "MediaTek MT7981 PHY",
++ .config_init = mt798x_phy_config_init,
++ .config_intr = genphy_no_config_intr,
++ .handle_interrupt = genphy_handle_interrupt_no_ack,
++ .probe = mt7981_phy_probe,
++ .suspend = genphy_suspend,
++ .resume = genphy_resume,
++ .read_page = mtk_socphy_read_page,
++ .write_page = mtk_socphy_write_page,
++ .led_blink_set = mt798x_phy_led_blink_set,
++ .led_brightness_set = mt798x_phy_led_brightness_set,
++ .led_hw_is_supported = mt798x_phy_led_hw_is_supported,
++ .led_hw_control_set = mt798x_phy_led_hw_control_set,
++ .led_hw_control_get = mt798x_phy_led_hw_control_get,
++ },
++ {
++ PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7988),
++ .name = "MediaTek MT7988 PHY",
++ .config_init = mt798x_phy_config_init,
++ .config_intr = genphy_no_config_intr,
++ .handle_interrupt = genphy_handle_interrupt_no_ack,
++ .probe = mt7988_phy_probe,
++ .suspend = genphy_suspend,
++ .resume = genphy_resume,
++ .read_page = mtk_socphy_read_page,
++ .write_page = mtk_socphy_write_page,
++ .led_blink_set = mt798x_phy_led_blink_set,
++ .led_brightness_set = mt798x_phy_led_brightness_set,
++ .led_hw_is_supported = mt798x_phy_led_hw_is_supported,
++ .led_hw_control_set = mt798x_phy_led_hw_control_set,
++ .led_hw_control_get = mt798x_phy_led_hw_control_get,
++ },
++};
++
++module_phy_driver(mtk_socphy_driver);
++
++static struct mdio_device_id __maybe_unused mtk_socphy_tbl[] = {
++ { PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7981) },
++ { PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7988) },
++ { }
++};
++
++MODULE_DESCRIPTION("MediaTek SoC Gigabit Ethernet PHY driver");
++MODULE_AUTHOR("Daniel Golle <daniel@makrotopia.org>");
++MODULE_AUTHOR("SkyLake Huang <SkyLake.Huang@mediatek.com>");
++MODULE_LICENSE("GPL");
++
++MODULE_DEVICE_TABLE(mdio, mtk_socphy_tbl);
+--- /dev/null
++++ b/drivers/net/phy/mediatek/mtk-ge.c
+@@ -0,0 +1,148 @@
++// SPDX-License-Identifier: GPL-2.0+
++#include <linux/of.h>
++#include <linux/bitfield.h>
++#include <linux/module.h>
++#include <linux/phy.h>
++
++#define MTK_EXT_PAGE_ACCESS 0x1f
++#define MTK_PHY_PAGE_STANDARD 0x0000
++#define MTK_PHY_PAGE_EXTENDED 0x0001
++#define MTK_PHY_PAGE_EXTENDED_2 0x0002
++#define MTK_PHY_PAGE_EXTENDED_3 0x0003
++#define MTK_PHY_PAGE_EXTENDED_2A30 0x2a30
++#define MTK_PHY_PAGE_EXTENDED_52B5 0x52b5
++
++static int mtk_gephy_read_page(struct phy_device *phydev)
++{
++ return __phy_read(phydev, MTK_EXT_PAGE_ACCESS);
++}
++
++static int mtk_gephy_write_page(struct phy_device *phydev, int page)
++{
++ return __phy_write(phydev, MTK_EXT_PAGE_ACCESS, page);
++}
++
++static void mtk_gephy_config_init(struct phy_device *phydev)
++{
++ /* Disable EEE */
++ phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0);
++
++ /* Enable HW auto downshift */
++ phy_modify_paged(phydev, MTK_PHY_PAGE_EXTENDED, 0x14, 0, BIT(4));
++
++ /* Increase SlvDPSready time */
++ phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
++ __phy_write(phydev, 0x10, 0xafae);
++ __phy_write(phydev, 0x12, 0x2f);
++ __phy_write(phydev, 0x10, 0x8fae);
++ phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
++
++ /* Adjust 100_mse_threshold */
++ phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x123, 0xffff);
++
++ /* Disable mcc */
++ phy_write_mmd(phydev, MDIO_MMD_VEND1, 0xa6, 0x300);
++}
++
++static int mt7530_phy_config_init(struct phy_device *phydev)
++{
++ mtk_gephy_config_init(phydev);
++
++ /* Increase post_update_timer */
++ phy_write_paged(phydev, MTK_PHY_PAGE_EXTENDED_3, 0x11, 0x4b);
++
++ return 0;
++}
++
++static int mt7530_led_config_of(struct phy_device *phydev)
++{
++ struct device_node *np = phydev->mdio.dev.of_node;
++ const __be32 *paddr;
++ int len;
++ int i;
++
++ paddr = of_get_property(np, "mediatek,led-config", &len);
++ if (!paddr)
++ return 0;
++
++ if (len < (2 * sizeof(*paddr)))
++ return -EINVAL;
++
++ len /= sizeof(*paddr);
++
++ phydev_warn(phydev, "Configure LED registers (num=%d)\n", len);
++ for (i = 0; i < len - 1; i += 2) {
++ u32 reg;
++ u32 val;
++
++ reg = be32_to_cpup(paddr + i);
++ val = be32_to_cpup(paddr + i + 1);
++
++ phy_write_mmd(phydev, MDIO_MMD_VEND2, reg, val);
++ }
++
++ return 0;
++}
++
++static int mt7531_phy_config_init(struct phy_device *phydev)
++{
++ mtk_gephy_config_init(phydev);
++
++ /* PHY link down power saving enable */
++ phy_set_bits(phydev, 0x17, BIT(4));
++ phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, 0xc6, 0x300);
++
++ /* Set TX Pair delay selection */
++ phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x13, 0x404);
++ phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x14, 0x404);
++
++ /* LED Config*/
++ mt7530_led_config_of(phydev);
++
++ return 0;
++}
++
++static struct phy_driver mtk_gephy_driver[] = {
++ {
++ PHY_ID_MATCH_EXACT(0x03a29412),
++ .name = "MediaTek MT7530 PHY",
++ .config_init = mt7530_phy_config_init,
++ /* Interrupts are handled by the switch, not the PHY
++ * itself.
++ */
++ .config_intr = genphy_no_config_intr,
++ .handle_interrupt = genphy_handle_interrupt_no_ack,
++ .suspend = genphy_suspend,
++ .resume = genphy_resume,
++ .read_page = mtk_gephy_read_page,
++ .write_page = mtk_gephy_write_page,
++ },
++ {
++ PHY_ID_MATCH_EXACT(0x03a29441),
++ .name = "MediaTek MT7531 PHY",
++ .config_init = mt7531_phy_config_init,
++ /* Interrupts are handled by the switch, not the PHY
++ * itself.
++ */
++ .config_intr = genphy_no_config_intr,
++ .handle_interrupt = genphy_handle_interrupt_no_ack,
++ .suspend = genphy_suspend,
++ .resume = genphy_resume,
++ .read_page = mtk_gephy_read_page,
++ .write_page = mtk_gephy_write_page,
++ },
++};
++
++module_phy_driver(mtk_gephy_driver);
++
++static struct mdio_device_id __maybe_unused mtk_gephy_tbl[] = {
++ { PHY_ID_MATCH_EXACT(0x03a29441) },
++ { PHY_ID_MATCH_EXACT(0x03a29412) },
++ { }
++};
++
++MODULE_DESCRIPTION("MediaTek Gigabit Ethernet PHY driver");
++MODULE_AUTHOR("DENG, Qingfang <dqfext@gmail.com>");
++MODULE_LICENSE("GPL");
++
++MODULE_DEVICE_TABLE(mdio, mtk_gephy_tbl);
diff --git a/target/linux/mediatek/patches-6.6/733-02-net-phy-mediatek-Fix-spelling-errors-and-rearrange-v.patch b/target/linux/mediatek/patches-6.6/733-02-net-phy-mediatek-Fix-spelling-errors-and-rearrange-v.patch
new file mode 100644
index 0000000000..901949fe9f
--- /dev/null
+++ b/target/linux/mediatek/patches-6.6/733-02-net-phy-mediatek-Fix-spelling-errors-and-rearrange-v.patch
@@ -0,0 +1,62 @@
+From 12054d38fc55adbfa2b40299ad8af3449d882ee2 Mon Sep 17 00:00:00 2001
+From: "SkyLake.Huang" <skylake.huang@mediatek.com>
+Date: Mon, 1 Jul 2024 18:54:06 +0800
+Subject: [PATCH 02/13] net: phy: mediatek: Fix spelling errors and rearrange
+ variables
+
+This patch fixes spelling errors which comes from mediatek-ge-soc.c and
+rearrange variables with reverse Xmas tree order.
+
+Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
+---
+ drivers/net/phy/mediatek/mtk-ge-soc.c | 19 ++++++++++---------
+ 1 file changed, 10 insertions(+), 9 deletions(-)
+
+--- a/drivers/net/phy/mediatek/mtk-ge-soc.c
++++ b/drivers/net/phy/mediatek/mtk-ge-soc.c
+@@ -408,16 +408,17 @@ static int tx_offset_cal_efuse(struct ph
+
+ static int tx_amp_fill_result(struct phy_device *phydev, u16 *buf)
+ {
+- int i;
+- int bias[16] = {};
+- const int vals_9461[16] = { 7, 1, 4, 7,
+- 7, 1, 4, 7,
+- 7, 1, 4, 7,
+- 7, 1, 4, 7 };
+ const int vals_9481[16] = { 10, 6, 6, 10,
+ 10, 6, 6, 10,
+ 10, 6, 6, 10,
+ 10, 6, 6, 10 };
++ const int vals_9461[16] = { 7, 1, 4, 7,
++ 7, 1, 4, 7,
++ 7, 1, 4, 7,
++ 7, 1, 4, 7 };
++ int bias[16] = {};
++ int i;
++
+ switch (phydev->drv->phy_id) {
+ case MTK_GPHY_ID_MT7981:
+ /* We add some calibration to efuse values
+@@ -1069,10 +1070,10 @@ static int start_cal(struct phy_device *
+
+ static int mt798x_phy_calibration(struct phy_device *phydev)
+ {
++ struct nvmem_cell *cell;
+ int ret = 0;
+- u32 *buf;
+ size_t len;
+- struct nvmem_cell *cell;
++ u32 *buf;
+
+ cell = nvmem_cell_get(&phydev->mdio.dev, "phy-cal-data");
+ if (IS_ERR(cell)) {
+@@ -1415,7 +1416,7 @@ static int mt7988_phy_probe_shared(struc
+ * LED_C and LED_D respectively. At the same time those pins are used to
+ * bootstrap configuration of the reference clock source (LED_A),
+ * DRAM DDRx16b x2/x1 (LED_B) and boot device (LED_C, LED_D).
+- * In practise this is done using a LED and a resistor pulling the pin
++ * In practice this is done using a LED and a resistor pulling the pin
+ * either to GND or to VIO.
+ * The detected value at boot time is accessible at run-time using the
+ * TPBANK0 register located in the gpio base of the pinctrl, in order
diff --git a/target/linux/mediatek/patches-6.6/733-03-net-phy-mediatek-Move-LED-helper-functions-into-mtk-.patch b/target/linux/mediatek/patches-6.6/733-03-net-phy-mediatek-Move-LED-helper-functions-into-mtk-.patch
new file mode 100644
index 0000000000..9e6ae4b136
--- /dev/null
+++ b/target/linux/mediatek/patches-6.6/733-03-net-phy-mediatek-Move-LED-helper-functions-into-mtk-.patch
@@ -0,0 +1,742 @@
+From 434e41555c45ec10b19320024163bb009da168bc Mon Sep 17 00:00:00 2001
+From: "SkyLake.Huang" <skylake.huang@mediatek.com>
+Date: Mon, 1 Jul 2024 18:54:07 +0800
+Subject: [PATCH 03/13] net: phy: mediatek: Move LED helper functions into mtk
+ phy lib
+
+This patch creates mtk-phy-lib.c & mtk-phy.h and integrates mtk-ge-soc.c's
+LED helper functions so that we can use those helper functions in other
+MTK's ethernet phy driver.
+
+Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
+---
+ drivers/net/phy/mediatek/Kconfig | 5 +
+ drivers/net/phy/mediatek/Makefile | 1 +
+ drivers/net/phy/mediatek/mtk-ge-soc.c | 262 +++----------------------
+ drivers/net/phy/mediatek/mtk-phy-lib.c | 251 +++++++++++++++++++++++
+ drivers/net/phy/mediatek/mtk.h | 82 ++++++++
+ 6 files changed, 368 insertions(+), 235 deletions(-)
+ create mode 100644 drivers/net/phy/mediatek/mtk-phy-lib.c
+ create mode 100644 drivers/net/phy/mediatek/mtk.h
+
+--- a/drivers/net/phy/mediatek/Kconfig
++++ b/drivers/net/phy/mediatek/Kconfig
+@@ -1,6 +1,10 @@
+ # SPDX-License-Identifier: GPL-2.0-only
++config MTK_NET_PHYLIB
++ tristate
++
+ config MEDIATEK_GE_PHY
+ tristate "MediaTek Gigabit Ethernet PHYs"
++ select MTK_NET_PHYLIB
+ help
+ Supports the MediaTek non-built-in Gigabit Ethernet PHYs.
+
+@@ -13,6 +17,7 @@ config MEDIATEK_GE_SOC_PHY
+ tristate "MediaTek SoC Ethernet PHYs"
+ depends on (ARM64 && ARCH_MEDIATEK) || COMPILE_TEST
+ select NVMEM_MTK_EFUSE
++ select MTK_NET_PHYLIB
+ help
+ Supports MediaTek SoC built-in Gigabit Ethernet PHYs.
+
+--- a/drivers/net/phy/mediatek/Makefile
++++ b/drivers/net/phy/mediatek/Makefile
+@@ -1,3 +1,4 @@
+ # SPDX-License-Identifier: GPL-2.0
++obj-$(CONFIG_MTK_NET_PHYLIB) += mtk-phy-lib.o
+ obj-$(CONFIG_MEDIATEK_GE_PHY) += mtk-ge.o
+ obj-$(CONFIG_MEDIATEK_GE_SOC_PHY) += mtk-ge-soc.o
+--- a/drivers/net/phy/mediatek/mtk-ge-soc.c
++++ b/drivers/net/phy/mediatek/mtk-ge-soc.c
+@@ -8,6 +8,8 @@
+ #include <linux/phy.h>
+ #include <linux/regmap.h>
+
++#include "mtk.h"
++
+ #define MTK_GPHY_ID_MT7981 0x03a29461
+ #define MTK_GPHY_ID_MT7988 0x03a29481
+
+@@ -210,41 +212,6 @@
+ #define MTK_PHY_DA_TX_R50_PAIR_D 0x540
+
+ /* Registers on MDIO_MMD_VEND2 */
+-#define MTK_PHY_LED0_ON_CTRL 0x24
+-#define MTK_PHY_LED1_ON_CTRL 0x26
+-#define MTK_PHY_LED_ON_MASK GENMASK(6, 0)
+-#define MTK_PHY_LED_ON_LINK1000 BIT(0)
+-#define MTK_PHY_LED_ON_LINK100 BIT(1)
+-#define MTK_PHY_LED_ON_LINK10 BIT(2)
+-#define MTK_PHY_LED_ON_LINK (MTK_PHY_LED_ON_LINK10 |\
+- MTK_PHY_LED_ON_LINK100 |\
+- MTK_PHY_LED_ON_LINK1000)
+-#define MTK_PHY_LED_ON_LINKDOWN BIT(3)
+-#define MTK_PHY_LED_ON_FDX BIT(4) /* Full duplex */
+-#define MTK_PHY_LED_ON_HDX BIT(5) /* Half duplex */
+-#define MTK_PHY_LED_ON_FORCE_ON BIT(6)
+-#define MTK_PHY_LED_ON_POLARITY BIT(14)
+-#define MTK_PHY_LED_ON_ENABLE BIT(15)
+-
+-#define MTK_PHY_LED0_BLINK_CTRL 0x25
+-#define MTK_PHY_LED1_BLINK_CTRL 0x27
+-#define MTK_PHY_LED_BLINK_1000TX BIT(0)
+-#define MTK_PHY_LED_BLINK_1000RX BIT(1)
+-#define MTK_PHY_LED_BLINK_100TX BIT(2)
+-#define MTK_PHY_LED_BLINK_100RX BIT(3)
+-#define MTK_PHY_LED_BLINK_10TX BIT(4)
+-#define MTK_PHY_LED_BLINK_10RX BIT(5)
+-#define MTK_PHY_LED_BLINK_RX (MTK_PHY_LED_BLINK_10RX |\
+- MTK_PHY_LED_BLINK_100RX |\
+- MTK_PHY_LED_BLINK_1000RX)
+-#define MTK_PHY_LED_BLINK_TX (MTK_PHY_LED_BLINK_10TX |\
+- MTK_PHY_LED_BLINK_100TX |\
+- MTK_PHY_LED_BLINK_1000TX)
+-#define MTK_PHY_LED_BLINK_COLLISION BIT(6)
+-#define MTK_PHY_LED_BLINK_RX_CRC_ERR BIT(7)
+-#define MTK_PHY_LED_BLINK_RX_IDLE_ERR BIT(8)
+-#define MTK_PHY_LED_BLINK_FORCE_BLINK BIT(9)
+-
+ #define MTK_PHY_LED1_DEFAULT_POLARITIES BIT(1)
+
+ #define MTK_PHY_RG_BG_RASEL 0x115
+@@ -299,10 +266,6 @@ enum CAL_MODE {
+ SW_M
+ };
+
+-#define MTK_PHY_LED_STATE_FORCE_ON 0
+-#define MTK_PHY_LED_STATE_FORCE_BLINK 1
+-#define MTK_PHY_LED_STATE_NETDEV 2
+-
+ struct mtk_socphy_priv {
+ unsigned long led_state;
+ };
+@@ -1131,84 +1094,39 @@ static int mt798x_phy_config_init(struct
+ return mt798x_phy_calibration(phydev);
+ }
+
+-static int mt798x_phy_hw_led_on_set(struct phy_device *phydev, u8 index,
+- bool on)
+-{
+- unsigned int bit_on = MTK_PHY_LED_STATE_FORCE_ON + (index ? 16 : 0);
+- struct mtk_socphy_priv *priv = phydev->priv;
+- bool changed;
+-
+- if (on)
+- changed = !test_and_set_bit(bit_on, &priv->led_state);
+- else
+- changed = !!test_and_clear_bit(bit_on, &priv->led_state);
+-
+- changed |= !!test_and_clear_bit(MTK_PHY_LED_STATE_NETDEV +
+- (index ? 16 : 0), &priv->led_state);
+- if (changed)
+- return phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ?
+- MTK_PHY_LED1_ON_CTRL : MTK_PHY_LED0_ON_CTRL,
+- MTK_PHY_LED_ON_MASK,
+- on ? MTK_PHY_LED_ON_FORCE_ON : 0);
+- else
+- return 0;
+-}
+-
+-static int mt798x_phy_hw_led_blink_set(struct phy_device *phydev, u8 index,
+- bool blinking)
+-{
+- unsigned int bit_blink = MTK_PHY_LED_STATE_FORCE_BLINK + (index ? 16 : 0);
+- struct mtk_socphy_priv *priv = phydev->priv;
+- bool changed;
+-
+- if (blinking)
+- changed = !test_and_set_bit(bit_blink, &priv->led_state);
+- else
+- changed = !!test_and_clear_bit(bit_blink, &priv->led_state);
+-
+- changed |= !!test_bit(MTK_PHY_LED_STATE_NETDEV +
+- (index ? 16 : 0), &priv->led_state);
+- if (changed)
+- return phy_write_mmd(phydev, MDIO_MMD_VEND2, index ?
+- MTK_PHY_LED1_BLINK_CTRL : MTK_PHY_LED0_BLINK_CTRL,
+- blinking ? MTK_PHY_LED_BLINK_FORCE_BLINK : 0);
+- else
+- return 0;
+-}
+-
+ static int mt798x_phy_led_blink_set(struct phy_device *phydev, u8 index,
+ unsigned long *delay_on,
+ unsigned long *delay_off)
+ {
++ struct mtk_socphy_priv *priv = phydev->priv;
+ bool blinking = false;
+ int err = 0;
+
+- if (index > 1)
+- return -EINVAL;
+-
+- if (delay_on && delay_off && (*delay_on > 0) && (*delay_off > 0)) {
+- blinking = true;
+- *delay_on = 50;
+- *delay_off = 50;
+- }
++ err = mtk_phy_led_num_dly_cfg(index, delay_on, delay_off, &blinking);
++ if (err < 0)
++ return err;
+
+- err = mt798x_phy_hw_led_blink_set(phydev, index, blinking);
++ err = mtk_phy_hw_led_blink_set(phydev, index, &priv->led_state,
++ blinking);
+ if (err)
+ return err;
+
+- return mt798x_phy_hw_led_on_set(phydev, index, false);
++ return mtk_phy_hw_led_on_set(phydev, index, &priv->led_state,
++ MTK_GPHY_LED_ON_MASK, false);
+ }
+
+ static int mt798x_phy_led_brightness_set(struct phy_device *phydev,
+ u8 index, enum led_brightness value)
+ {
++ struct mtk_socphy_priv *priv = phydev->priv;
+ int err;
+
+- err = mt798x_phy_hw_led_blink_set(phydev, index, false);
++ err = mtk_phy_hw_led_blink_set(phydev, index, &priv->led_state, false);
+ if (err)
+ return err;
+
+- return mt798x_phy_hw_led_on_set(phydev, index, (value != LED_OFF));
++ return mtk_phy_hw_led_on_set(phydev, index, &priv->led_state,
++ MTK_GPHY_LED_ON_MASK, (value != LED_OFF));
+ }
+
+ static const unsigned long supported_triggers = (BIT(TRIGGER_NETDEV_FULL_DUPLEX) |
+@@ -1223,148 +1141,30 @@ static const unsigned long supported_tri
+ static int mt798x_phy_led_hw_is_supported(struct phy_device *phydev, u8 index,
+ unsigned long rules)
+ {
+- if (index > 1)
+- return -EINVAL;
+-
+- /* All combinations of the supported triggers are allowed */
+- if (rules & ~supported_triggers)
+- return -EOPNOTSUPP;
+-
+- return 0;
+-};
++ return mtk_phy_led_hw_is_supported(phydev, index, rules,
++ supported_triggers);
++}
+
+ static int mt798x_phy_led_hw_control_get(struct phy_device *phydev, u8 index,
+ unsigned long *rules)
+ {
+- unsigned int bit_blink = MTK_PHY_LED_STATE_FORCE_BLINK + (index ? 16 : 0);
+- unsigned int bit_netdev = MTK_PHY_LED_STATE_NETDEV + (index ? 16 : 0);
+- unsigned int bit_on = MTK_PHY_LED_STATE_FORCE_ON + (index ? 16 : 0);
+ struct mtk_socphy_priv *priv = phydev->priv;
+- int on, blink;
+-
+- if (index > 1)
+- return -EINVAL;
+-
+- on = phy_read_mmd(phydev, MDIO_MMD_VEND2,
+- index ? MTK_PHY_LED1_ON_CTRL : MTK_PHY_LED0_ON_CTRL);
+-
+- if (on < 0)
+- return -EIO;
+-
+- blink = phy_read_mmd(phydev, MDIO_MMD_VEND2,
+- index ? MTK_PHY_LED1_BLINK_CTRL :
+- MTK_PHY_LED0_BLINK_CTRL);
+- if (blink < 0)
+- return -EIO;
+-
+- if ((on & (MTK_PHY_LED_ON_LINK | MTK_PHY_LED_ON_FDX | MTK_PHY_LED_ON_HDX |
+- MTK_PHY_LED_ON_LINKDOWN)) ||
+- (blink & (MTK_PHY_LED_BLINK_RX | MTK_PHY_LED_BLINK_TX)))
+- set_bit(bit_netdev, &priv->led_state);
+- else
+- clear_bit(bit_netdev, &priv->led_state);
+-
+- if (on & MTK_PHY_LED_ON_FORCE_ON)
+- set_bit(bit_on, &priv->led_state);
+- else
+- clear_bit(bit_on, &priv->led_state);
+-
+- if (blink & MTK_PHY_LED_BLINK_FORCE_BLINK)
+- set_bit(bit_blink, &priv->led_state);
+- else
+- clear_bit(bit_blink, &priv->led_state);
+-
+- if (!rules)
+- return 0;
+-
+- if (on & MTK_PHY_LED_ON_LINK)
+- *rules |= BIT(TRIGGER_NETDEV_LINK);
+
+- if (on & MTK_PHY_LED_ON_LINK10)
+- *rules |= BIT(TRIGGER_NETDEV_LINK_10);
+-
+- if (on & MTK_PHY_LED_ON_LINK100)
+- *rules |= BIT(TRIGGER_NETDEV_LINK_100);
+-
+- if (on & MTK_PHY_LED_ON_LINK1000)
+- *rules |= BIT(TRIGGER_NETDEV_LINK_1000);
+-
+- if (on & MTK_PHY_LED_ON_FDX)
+- *rules |= BIT(TRIGGER_NETDEV_FULL_DUPLEX);
+-
+- if (on & MTK_PHY_LED_ON_HDX)
+- *rules |= BIT(TRIGGER_NETDEV_HALF_DUPLEX);
+-
+- if (blink & MTK_PHY_LED_BLINK_RX)
+- *rules |= BIT(TRIGGER_NETDEV_RX);
+-
+- if (blink & MTK_PHY_LED_BLINK_TX)
+- *rules |= BIT(TRIGGER_NETDEV_TX);
+-
+- return 0;
++ return mtk_phy_led_hw_ctrl_get(phydev, index, rules, &priv->led_state,
++ MTK_GPHY_LED_ON_SET,
++ MTK_GPHY_LED_RX_BLINK_SET,
++ MTK_GPHY_LED_TX_BLINK_SET);
+ };
+
+ static int mt798x_phy_led_hw_control_set(struct phy_device *phydev, u8 index,
+ unsigned long rules)
+ {
+- unsigned int bit_netdev = MTK_PHY_LED_STATE_NETDEV + (index ? 16 : 0);
+ struct mtk_socphy_priv *priv = phydev->priv;
+- u16 on = 0, blink = 0;
+- int ret;
+
+- if (index > 1)
+- return -EINVAL;
+-
+- if (rules & BIT(TRIGGER_NETDEV_FULL_DUPLEX))
+- on |= MTK_PHY_LED_ON_FDX;
+-
+- if (rules & BIT(TRIGGER_NETDEV_HALF_DUPLEX))
+- on |= MTK_PHY_LED_ON_HDX;
+-
+- if (rules & (BIT(TRIGGER_NETDEV_LINK_10) | BIT(TRIGGER_NETDEV_LINK)))
+- on |= MTK_PHY_LED_ON_LINK10;
+-
+- if (rules & (BIT(TRIGGER_NETDEV_LINK_100) | BIT(TRIGGER_NETDEV_LINK)))
+- on |= MTK_PHY_LED_ON_LINK100;
+-
+- if (rules & (BIT(TRIGGER_NETDEV_LINK_1000) | BIT(TRIGGER_NETDEV_LINK)))
+- on |= MTK_PHY_LED_ON_LINK1000;
+-
+- if (rules & BIT(TRIGGER_NETDEV_RX)) {
+- blink |= (on & MTK_PHY_LED_ON_LINK) ?
+- (((on & MTK_PHY_LED_ON_LINK10) ? MTK_PHY_LED_BLINK_10RX : 0) |
+- ((on & MTK_PHY_LED_ON_LINK100) ? MTK_PHY_LED_BLINK_100RX : 0) |
+- ((on & MTK_PHY_LED_ON_LINK1000) ? MTK_PHY_LED_BLINK_1000RX : 0)) :
+- MTK_PHY_LED_BLINK_RX;
+- }
+-
+- if (rules & BIT(TRIGGER_NETDEV_TX)) {
+- blink |= (on & MTK_PHY_LED_ON_LINK) ?
+- (((on & MTK_PHY_LED_ON_LINK10) ? MTK_PHY_LED_BLINK_10TX : 0) |
+- ((on & MTK_PHY_LED_ON_LINK100) ? MTK_PHY_LED_BLINK_100TX : 0) |
+- ((on & MTK_PHY_LED_ON_LINK1000) ? MTK_PHY_LED_BLINK_1000TX : 0)) :
+- MTK_PHY_LED_BLINK_TX;
+- }
+-
+- if (blink || on)
+- set_bit(bit_netdev, &priv->led_state);
+- else
+- clear_bit(bit_netdev, &priv->led_state);
+-
+- ret = phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ?
+- MTK_PHY_LED1_ON_CTRL :
+- MTK_PHY_LED0_ON_CTRL,
+- MTK_PHY_LED_ON_FDX |
+- MTK_PHY_LED_ON_HDX |
+- MTK_PHY_LED_ON_LINK,
+- on);
+-
+- if (ret)
+- return ret;
+-
+- return phy_write_mmd(phydev, MDIO_MMD_VEND2, index ?
+- MTK_PHY_LED1_BLINK_CTRL :
+- MTK_PHY_LED0_BLINK_CTRL, blink);
++ return mtk_phy_led_hw_ctrl_set(phydev, index, rules, &priv->led_state,
++ MTK_GPHY_LED_ON_SET,
++ MTK_GPHY_LED_RX_BLINK_SET,
++ MTK_GPHY_LED_TX_BLINK_SET);
+ };
+
+ static bool mt7988_phy_led_get_polarity(struct phy_device *phydev, int led_num)
+@@ -1438,14 +1238,6 @@ static int mt7988_phy_probe_shared(struc
+ return 0;
+ }
+
+-static void mt798x_phy_leds_state_init(struct phy_device *phydev)
+-{
+- int i;
+-
+- for (i = 0; i < 2; ++i)
+- mt798x_phy_led_hw_control_get(phydev, i, NULL);
+-}
+-
+ static int mt7988_phy_probe(struct phy_device *phydev)
+ {
+ struct mtk_socphy_shared *shared;
+@@ -1471,7 +1263,7 @@ static int mt7988_phy_probe(struct phy_d
+
+ phydev->priv = priv;
+
+- mt798x_phy_leds_state_init(phydev);
++ mtk_phy_leds_state_init(phydev);
+
+ err = mt7988_phy_fix_leds_polarities(phydev);
+ if (err)
+@@ -1498,7 +1290,7 @@ static int mt7981_phy_probe(struct phy_d
+
+ phydev->priv = priv;
+
+- mt798x_phy_leds_state_init(phydev);
++ mtk_phy_leds_state_init(phydev);
+
+ return mt798x_phy_calibration(phydev);
+ }
+--- /dev/null
++++ b/drivers/net/phy/mediatek/mtk-phy-lib.c
+@@ -0,0 +1,251 @@
++// SPDX-License-Identifier: GPL-2.0
++#include <linux/phy.h>
++#include <linux/module.h>
++
++#include <linux/netdevice.h>
++
++#include "mtk.h"
++
++int mtk_phy_led_hw_is_supported(struct phy_device *phydev, u8 index,
++ unsigned long rules,
++ unsigned long supported_triggers)
++{
++ if (index > 1)
++ return -EINVAL;
++
++ /* All combinations of the supported triggers are allowed */
++ if (rules & ~supported_triggers)
++ return -EOPNOTSUPP;
++
++ return 0;
++}
++EXPORT_SYMBOL_GPL(mtk_phy_led_hw_is_supported);
++
++int mtk_phy_led_hw_ctrl_get(struct phy_device *phydev, u8 index,
++ unsigned long *rules, unsigned long *led_state,
++ u16 on_set, u16 rx_blink_set, u16 tx_blink_set)
++{
++ unsigned int bit_blink = MTK_PHY_LED_STATE_FORCE_BLINK +
++ (index ? 16 : 0);
++ unsigned int bit_netdev = MTK_PHY_LED_STATE_NETDEV + (index ? 16 : 0);
++ unsigned int bit_on = MTK_PHY_LED_STATE_FORCE_ON + (index ? 16 : 0);
++ int on, blink;
++
++ if (index > 1)
++ return -EINVAL;
++
++ on = phy_read_mmd(phydev, MDIO_MMD_VEND2,
++ index ? MTK_PHY_LED1_ON_CTRL : MTK_PHY_LED0_ON_CTRL);
++
++ if (on < 0)
++ return -EIO;
++
++ blink = phy_read_mmd(phydev, MDIO_MMD_VEND2,
++ index ? MTK_PHY_LED1_BLINK_CTRL :
++ MTK_PHY_LED0_BLINK_CTRL);
++ if (blink < 0)
++ return -EIO;
++
++ if ((on & (on_set | MTK_PHY_LED_ON_FDX |
++ MTK_PHY_LED_ON_HDX | MTK_PHY_LED_ON_LINKDOWN)) ||
++ (blink & (rx_blink_set | tx_blink_set)))
++ set_bit(bit_netdev, led_state);
++ else
++ clear_bit(bit_netdev, led_state);
++
++ if (on & MTK_PHY_LED_ON_FORCE_ON)
++ set_bit(bit_on, led_state);
++ else
++ clear_bit(bit_on, led_state);
++
++ if (blink & MTK_PHY_LED_BLINK_FORCE_BLINK)
++ set_bit(bit_blink, led_state);
++ else
++ clear_bit(bit_blink, led_state);
++
++ if (!rules)
++ return 0;
++
++ if (on & on_set)
++ *rules |= BIT(TRIGGER_NETDEV_LINK);
++
++ if (on & MTK_PHY_LED_ON_LINK10)
++ *rules |= BIT(TRIGGER_NETDEV_LINK_10);
++
++ if (on & MTK_PHY_LED_ON_LINK100)
++ *rules |= BIT(TRIGGER_NETDEV_LINK_100);
++
++ if (on & MTK_PHY_LED_ON_LINK1000)
++ *rules |= BIT(TRIGGER_NETDEV_LINK_1000);
++
++ if (on & MTK_PHY_LED_ON_LINK2500)
++ *rules |= BIT(TRIGGER_NETDEV_LINK_2500);
++
++ if (on & MTK_PHY_LED_ON_FDX)
++ *rules |= BIT(TRIGGER_NETDEV_FULL_DUPLEX);
++
++ if (on & MTK_PHY_LED_ON_HDX)
++ *rules |= BIT(TRIGGER_NETDEV_HALF_DUPLEX);
++
++ if (blink & rx_blink_set)
++ *rules |= BIT(TRIGGER_NETDEV_RX);
++
++ if (blink & tx_blink_set)
++ *rules |= BIT(TRIGGER_NETDEV_TX);
++
++ return 0;
++}
++EXPORT_SYMBOL_GPL(mtk_phy_led_hw_ctrl_get);
++
++int mtk_phy_led_hw_ctrl_set(struct phy_device *phydev, u8 index,
++ unsigned long rules, unsigned long *led_state,
++ u16 on_set, u16 rx_blink_set, u16 tx_blink_set)
++{
++ unsigned int bit_netdev = MTK_PHY_LED_STATE_NETDEV + (index ? 16 : 0);
++ u16 on = 0, blink = 0;
++ int ret;
++
++ if (index > 1)
++ return -EINVAL;
++
++ if (rules & BIT(TRIGGER_NETDEV_FULL_DUPLEX))
++ on |= MTK_PHY_LED_ON_FDX;
++
++ if (rules & BIT(TRIGGER_NETDEV_HALF_DUPLEX))
++ on |= MTK_PHY_LED_ON_HDX;
++
++ if (rules & (BIT(TRIGGER_NETDEV_LINK_10) | BIT(TRIGGER_NETDEV_LINK)))
++ on |= MTK_PHY_LED_ON_LINK10;
++
++ if (rules & (BIT(TRIGGER_NETDEV_LINK_100) | BIT(TRIGGER_NETDEV_LINK)))
++ on |= MTK_PHY_LED_ON_LINK100;
++
++ if (rules & (BIT(TRIGGER_NETDEV_LINK_1000) | BIT(TRIGGER_NETDEV_LINK)))
++ on |= MTK_PHY_LED_ON_LINK1000;
++
++ if (rules & (BIT(TRIGGER_NETDEV_LINK_2500) | BIT(TRIGGER_NETDEV_LINK)))
++ on |= MTK_PHY_LED_ON_LINK2500;
++
++ if (rules & BIT(TRIGGER_NETDEV_RX)) {
++ blink |= (on & on_set) ?
++ (((on & MTK_PHY_LED_ON_LINK10) ?
++ MTK_PHY_LED_BLINK_10RX : 0) |
++ ((on & MTK_PHY_LED_ON_LINK100) ?
++ MTK_PHY_LED_BLINK_100RX : 0) |
++ ((on & MTK_PHY_LED_ON_LINK1000) ?
++ MTK_PHY_LED_BLINK_1000RX : 0) |
++ ((on & MTK_PHY_LED_ON_LINK2500) ?
++ MTK_PHY_LED_BLINK_2500RX : 0)) :
++ rx_blink_set;
++ }
++
++ if (rules & BIT(TRIGGER_NETDEV_TX)) {
++ blink |= (on & on_set) ?
++ (((on & MTK_PHY_LED_ON_LINK10) ?
++ MTK_PHY_LED_BLINK_10TX : 0) |
++ ((on & MTK_PHY_LED_ON_LINK100) ?
++ MTK_PHY_LED_BLINK_100TX : 0) |
++ ((on & MTK_PHY_LED_ON_LINK1000) ?
++ MTK_PHY_LED_BLINK_1000TX : 0) |
++ ((on & MTK_PHY_LED_ON_LINK2500) ?
++ MTK_PHY_LED_BLINK_2500TX : 0)) :
++ tx_blink_set;
++ }
++
++ if (blink || on)
++ set_bit(bit_netdev, led_state);
++ else
++ clear_bit(bit_netdev, led_state);
++
++ ret = phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ?
++ MTK_PHY_LED1_ON_CTRL : MTK_PHY_LED0_ON_CTRL,
++ MTK_PHY_LED_ON_FDX | MTK_PHY_LED_ON_HDX | on_set,
++ on);
++
++ if (ret)
++ return ret;
++
++ return phy_write_mmd(phydev, MDIO_MMD_VEND2, index ?
++ MTK_PHY_LED1_BLINK_CTRL :
++ MTK_PHY_LED0_BLINK_CTRL, blink);
++}
++EXPORT_SYMBOL_GPL(mtk_phy_led_hw_ctrl_set);
++
++int mtk_phy_led_num_dly_cfg(u8 index, unsigned long *delay_on,
++ unsigned long *delay_off, bool *blinking)
++{
++ if (index > 1)
++ return -EINVAL;
++
++ if (delay_on && delay_off && (*delay_on > 0) && (*delay_off > 0)) {
++ *blinking = true;
++ *delay_on = 50;
++ *delay_off = 50;
++ }
++
++ return 0;
++}
++EXPORT_SYMBOL_GPL(mtk_phy_led_num_dly_cfg);
++
++int mtk_phy_hw_led_on_set(struct phy_device *phydev, u8 index,
++ unsigned long *led_state, u16 led_on_mask, bool on)
++{
++ unsigned int bit_on = MTK_PHY_LED_STATE_FORCE_ON + (index ? 16 : 0);
++ bool changed;
++
++ if (on)
++ changed = !test_and_set_bit(bit_on, led_state);
++ else
++ changed = !!test_and_clear_bit(bit_on, led_state);
++
++ changed |= !!test_and_clear_bit(MTK_PHY_LED_STATE_NETDEV +
++ (index ? 16 : 0), led_state);
++ if (changed)
++ return phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ?
++ MTK_PHY_LED1_ON_CTRL :
++ MTK_PHY_LED0_ON_CTRL,
++ led_on_mask,
++ on ? MTK_PHY_LED_ON_FORCE_ON : 0);
++ else
++ return 0;
++}
++EXPORT_SYMBOL_GPL(mtk_phy_hw_led_on_set);
++
++int mtk_phy_hw_led_blink_set(struct phy_device *phydev, u8 index,
++ unsigned long *led_state, bool blinking)
++{
++ unsigned int bit_blink = MTK_PHY_LED_STATE_FORCE_BLINK +
++ (index ? 16 : 0);
++ bool changed;
++
++ if (blinking)
++ changed = !test_and_set_bit(bit_blink, led_state);
++ else
++ changed = !!test_and_clear_bit(bit_blink, led_state);
++
++ changed |= !!test_bit(MTK_PHY_LED_STATE_NETDEV +
++ (index ? 16 : 0), led_state);
++ if (changed)
++ return phy_write_mmd(phydev, MDIO_MMD_VEND2, index ?
++ MTK_PHY_LED1_BLINK_CTRL :
++ MTK_PHY_LED0_BLINK_CTRL,
++ blinking ?
++ MTK_PHY_LED_BLINK_FORCE_BLINK : 0);
++ else
++ return 0;
++}
++EXPORT_SYMBOL_GPL(mtk_phy_hw_led_blink_set);
++
++void mtk_phy_leds_state_init(struct phy_device *phydev)
++{
++ int i;
++
++ for (i = 0; i < 2; ++i)
++ phydev->drv->led_hw_control_get(phydev, i, NULL);
++}
++EXPORT_SYMBOL_GPL(mtk_phy_leds_state_init);
++
++MODULE_DESCRIPTION("MediaTek Ethernet PHY driver common");
++MODULE_AUTHOR("Sky Huang <SkyLake.Huang@mediatek.com>");
++MODULE_AUTHOR("Daniel Golle <daniel@makrotopia.org>");
++MODULE_LICENSE("GPL");
+--- /dev/null
++++ b/drivers/net/phy/mediatek/mtk.h
+@@ -0,0 +1,82 @@
++/* SPDX-License-Identifier: GPL-2.0
++ *
++ * Common definition for Mediatek Ethernet PHYs
++ * Author: SkyLake Huang <SkyLake.Huang@mediatek.com>
++ * Copyright (c) 2024 MediaTek Inc.
++ */
++
++#ifndef _MTK_EPHY_H_
++#define _MTK_EPHY_H_
++
++#define MTK_EXT_PAGE_ACCESS 0x1f
++
++/* Registers on MDIO_MMD_VEND2 */
++#define MTK_PHY_LED0_ON_CTRL 0x24
++#define MTK_PHY_LED1_ON_CTRL 0x26
++#define MTK_GPHY_LED_ON_MASK GENMASK(6, 0)
++#define MTK_2P5GPHY_LED_ON_MASK GENMASK(7, 0)
++#define MTK_PHY_LED_ON_LINK1000 BIT(0)
++#define MTK_PHY_LED_ON_LINK100 BIT(1)
++#define MTK_PHY_LED_ON_LINK10 BIT(2)
++#define MTK_PHY_LED_ON_LINKDOWN BIT(3)
++#define MTK_PHY_LED_ON_FDX BIT(4) /* Full duplex */
++#define MTK_PHY_LED_ON_HDX BIT(5) /* Half duplex */
++#define MTK_PHY_LED_ON_FORCE_ON BIT(6)
++#define MTK_PHY_LED_ON_LINK2500 BIT(7)
++#define MTK_PHY_LED_ON_POLARITY BIT(14)
++#define MTK_PHY_LED_ON_ENABLE BIT(15)
++
++#define MTK_PHY_LED0_BLINK_CTRL 0x25
++#define MTK_PHY_LED1_BLINK_CTRL 0x27
++#define MTK_PHY_LED_BLINK_1000TX BIT(0)
++#define MTK_PHY_LED_BLINK_1000RX BIT(1)
++#define MTK_PHY_LED_BLINK_100TX BIT(2)
++#define MTK_PHY_LED_BLINK_100RX BIT(3)
++#define MTK_PHY_LED_BLINK_10TX BIT(4)
++#define MTK_PHY_LED_BLINK_10RX BIT(5)
++#define MTK_PHY_LED_BLINK_COLLISION BIT(6)
++#define MTK_PHY_LED_BLINK_RX_CRC_ERR BIT(7)
++#define MTK_PHY_LED_BLINK_RX_IDLE_ERR BIT(8)
++#define MTK_PHY_LED_BLINK_FORCE_BLINK BIT(9)
++#define MTK_PHY_LED_BLINK_2500TX BIT(10)
++#define MTK_PHY_LED_BLINK_2500RX BIT(11)
++
++#define MTK_GPHY_LED_ON_SET (MTK_PHY_LED_ON_LINK1000 | \
++ MTK_PHY_LED_ON_LINK100 | \
++ MTK_PHY_LED_ON_LINK10)
++#define MTK_GPHY_LED_RX_BLINK_SET (MTK_PHY_LED_BLINK_1000RX | \
++ MTK_PHY_LED_BLINK_100RX | \
++ MTK_PHY_LED_BLINK_10RX)
++#define MTK_GPHY_LED_TX_BLINK_SET (MTK_PHY_LED_BLINK_1000RX | \
++ MTK_PHY_LED_BLINK_100RX | \
++ MTK_PHY_LED_BLINK_10RX)
++
++#define MTK_2P5GPHY_LED_ON_SET (MTK_PHY_LED_ON_LINK2500 | \
++ MTK_GPHY_LED_ON_SET)
++#define MTK_2P5GPHY_LED_RX_BLINK_SET (MTK_PHY_LED_BLINK_2500RX | \
++ MTK_GPHY_LED_RX_BLINK_SET)
++#define MTK_2P5GPHY_LED_TX_BLINK_SET (MTK_PHY_LED_BLINK_2500RX | \
++ MTK_GPHY_LED_TX_BLINK_SET)
++
++#define MTK_PHY_LED_STATE_FORCE_ON 0
++#define MTK_PHY_LED_STATE_FORCE_BLINK 1
++#define MTK_PHY_LED_STATE_NETDEV 2
++
++int mtk_phy_led_hw_is_supported(struct phy_device *phydev, u8 index,
++ unsigned long rules,
++ unsigned long supported_triggers);
++int mtk_phy_led_hw_ctrl_set(struct phy_device *phydev, u8 index,
++ unsigned long rules, unsigned long *led_state,
++ u16 on_set, u16 rx_blink_set, u16 tx_blink_set);
++int mtk_phy_led_hw_ctrl_get(struct phy_device *phydev, u8 index,
++ unsigned long *rules, unsigned long *led_state,
++ u16 on_set, u16 rx_blink_set, u16 tx_blink_set);
++int mtk_phy_led_num_dly_cfg(u8 index, unsigned long *delay_on,
++ unsigned long *delay_off, bool *blinking);
++int mtk_phy_hw_led_on_set(struct phy_device *phydev, u8 index,
++ unsigned long *led_state, u16 led_on_mask, bool on);
++int mtk_phy_hw_led_blink_set(struct phy_device *phydev, u8 index,
++ unsigned long *led_state, bool blinking);
++void mtk_phy_leds_state_init(struct phy_device *phydev);
++
++#endif /* _MTK_EPHY_H_ */
diff --git a/target/linux/mediatek/patches-6.6/733-04-net-phy-mediatek-Improve-readability-of-mtk-phy-lib..patch b/target/linux/mediatek/patches-6.6/733-04-net-phy-mediatek-Improve-readability-of-mtk-phy-lib..patch
new file mode 100644
index 0000000000..717dc890e3
--- /dev/null
+++ b/target/linux/mediatek/patches-6.6/733-04-net-phy-mediatek-Improve-readability-of-mtk-phy-lib..patch
@@ -0,0 +1,70 @@
+From 2783929879854d5750ba82e2e203663313362abb Mon Sep 17 00:00:00 2001
+From: "SkyLake.Huang" <skylake.huang@mediatek.com>
+Date: Mon, 1 Jul 2024 18:54:08 +0800
+Subject: [PATCH 04/13] net: phy: mediatek: Improve readability of
+ mtk-phy-lib.c's mtk_phy_led_hw_ctrl_set()
+
+This patch removes parens around TRIGGER_NETDEV_RX/TRIGGER_NETDEV_TX in
+mtk_phy_led_hw_ctrl_set(), which improves readability.
+
+Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
+---
+ drivers/net/phy/mediatek/mtk-phy-lib.c | 44 ++++++++++++++------------
+ 1 file changed, 24 insertions(+), 20 deletions(-)
+
+--- a/drivers/net/phy/mediatek/mtk-phy-lib.c
++++ b/drivers/net/phy/mediatek/mtk-phy-lib.c
+@@ -127,29 +127,33 @@ int mtk_phy_led_hw_ctrl_set(struct phy_d
+ on |= MTK_PHY_LED_ON_LINK2500;
+
+ if (rules & BIT(TRIGGER_NETDEV_RX)) {
+- blink |= (on & on_set) ?
+- (((on & MTK_PHY_LED_ON_LINK10) ?
+- MTK_PHY_LED_BLINK_10RX : 0) |
+- ((on & MTK_PHY_LED_ON_LINK100) ?
+- MTK_PHY_LED_BLINK_100RX : 0) |
+- ((on & MTK_PHY_LED_ON_LINK1000) ?
+- MTK_PHY_LED_BLINK_1000RX : 0) |
+- ((on & MTK_PHY_LED_ON_LINK2500) ?
+- MTK_PHY_LED_BLINK_2500RX : 0)) :
+- rx_blink_set;
++ if (on & on_set) {
++ if (on & MTK_PHY_LED_ON_LINK10)
++ blink |= MTK_PHY_LED_BLINK_10RX;
++ if (on & MTK_PHY_LED_ON_LINK100)
++ blink |= MTK_PHY_LED_BLINK_100RX;
++ if (on & MTK_PHY_LED_ON_LINK1000)
++ blink |= MTK_PHY_LED_BLINK_1000RX;
++ if (on & MTK_PHY_LED_ON_LINK2500)
++ blink |= MTK_PHY_LED_BLINK_2500RX;
++ } else {
++ blink |= rx_blink_set;
++ }
+ }
+
+ if (rules & BIT(TRIGGER_NETDEV_TX)) {
+- blink |= (on & on_set) ?
+- (((on & MTK_PHY_LED_ON_LINK10) ?
+- MTK_PHY_LED_BLINK_10TX : 0) |
+- ((on & MTK_PHY_LED_ON_LINK100) ?
+- MTK_PHY_LED_BLINK_100TX : 0) |
+- ((on & MTK_PHY_LED_ON_LINK1000) ?
+- MTK_PHY_LED_BLINK_1000TX : 0) |
+- ((on & MTK_PHY_LED_ON_LINK2500) ?
+- MTK_PHY_LED_BLINK_2500TX : 0)) :
+- tx_blink_set;
++ if (on & on_set) {
++ if (on & MTK_PHY_LED_ON_LINK10)
++ blink |= MTK_PHY_LED_BLINK_10TX;
++ if (on & MTK_PHY_LED_ON_LINK100)
++ blink |= MTK_PHY_LED_BLINK_100TX;
++ if (on & MTK_PHY_LED_ON_LINK1000)
++ blink |= MTK_PHY_LED_BLINK_1000TX;
++ if (on & MTK_PHY_LED_ON_LINK2500)
++ blink |= MTK_PHY_LED_BLINK_2500TX;
++ } else {
++ blink |= tx_blink_set;
++ }
+ }
+
+ if (blink || on)
diff --git a/target/linux/mediatek/patches-6.6/733-05-net-phy-mediatek-Integrate-read-write-page-helper-fu.patch b/target/linux/mediatek/patches-6.6/733-05-net-phy-mediatek-Integrate-read-write-page-helper-fu.patch
new file mode 100644
index 0000000000..4a112a202c
--- /dev/null
+++ b/target/linux/mediatek/patches-6.6/733-05-net-phy-mediatek-Integrate-read-write-page-helper-fu.patch
@@ -0,0 +1,141 @@
+From 58c1270423ab48464cdc31ef71ffe7f5b2441961 Mon Sep 17 00:00:00 2001
+From: "SkyLake.Huang" <skylake.huang@mediatek.com>
+Date: Mon, 1 Jul 2024 18:54:09 +0800
+Subject: [PATCH 05/13] net: phy: mediatek: Integrate read/write page helper
+ functions
+
+This patch integrates read/write page helper functions as MTK phy lib.
+They are basically the same in mtk-ge.c & mtk-ge-soc.c.
+
+Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
+---
+ drivers/net/phy/mediatek/mtk-ge-soc.c | 18 ++++--------------
+ drivers/net/phy/mediatek/mtk-ge.c | 20 ++++++--------------
+ drivers/net/phy/mediatek/mtk-phy-lib.c | 12 ++++++++++++
+ drivers/net/phy/mediatek/mtk.h | 3 +++
+ 4 files changed, 25 insertions(+), 28 deletions(-)
+
+--- a/drivers/net/phy/mediatek/mtk-ge-soc.c
++++ b/drivers/net/phy/mediatek/mtk-ge-soc.c
+@@ -275,16 +275,6 @@ struct mtk_socphy_shared {
+ struct mtk_socphy_priv priv[4];
+ };
+
+-static int mtk_socphy_read_page(struct phy_device *phydev)
+-{
+- return __phy_read(phydev, MTK_EXT_PAGE_ACCESS);
+-}
+-
+-static int mtk_socphy_write_page(struct phy_device *phydev, int page)
+-{
+- return __phy_write(phydev, MTK_EXT_PAGE_ACCESS, page);
+-}
+-
+ /* One calibration cycle consists of:
+ * 1.Set DA_CALIN_FLAG high to start calibration. Keep it high
+ * until AD_CAL_COMP is ready to output calibration result.
+@@ -1305,8 +1295,8 @@ static struct phy_driver mtk_socphy_driv
+ .probe = mt7981_phy_probe,
+ .suspend = genphy_suspend,
+ .resume = genphy_resume,
+- .read_page = mtk_socphy_read_page,
+- .write_page = mtk_socphy_write_page,
++ .read_page = mtk_phy_read_page,
++ .write_page = mtk_phy_write_page,
+ .led_blink_set = mt798x_phy_led_blink_set,
+ .led_brightness_set = mt798x_phy_led_brightness_set,
+ .led_hw_is_supported = mt798x_phy_led_hw_is_supported,
+@@ -1322,8 +1312,8 @@ static struct phy_driver mtk_socphy_driv
+ .probe = mt7988_phy_probe,
+ .suspend = genphy_suspend,
+ .resume = genphy_resume,
+- .read_page = mtk_socphy_read_page,
+- .write_page = mtk_socphy_write_page,
++ .read_page = mtk_phy_read_page,
++ .write_page = mtk_phy_write_page,
+ .led_blink_set = mt798x_phy_led_blink_set,
+ .led_brightness_set = mt798x_phy_led_brightness_set,
+ .led_hw_is_supported = mt798x_phy_led_hw_is_supported,
+--- a/drivers/net/phy/mediatek/mtk-ge.c
++++ b/drivers/net/phy/mediatek/mtk-ge.c
+@@ -4,6 +4,8 @@
+ #include <linux/module.h>
+ #include <linux/phy.h>
+
++#include "mtk.h"
++
+ #define MTK_EXT_PAGE_ACCESS 0x1f
+ #define MTK_PHY_PAGE_STANDARD 0x0000
+ #define MTK_PHY_PAGE_EXTENDED 0x0001
+@@ -12,16 +14,6 @@
+ #define MTK_PHY_PAGE_EXTENDED_2A30 0x2a30
+ #define MTK_PHY_PAGE_EXTENDED_52B5 0x52b5
+
+-static int mtk_gephy_read_page(struct phy_device *phydev)
+-{
+- return __phy_read(phydev, MTK_EXT_PAGE_ACCESS);
+-}
+-
+-static int mtk_gephy_write_page(struct phy_device *phydev, int page)
+-{
+- return __phy_write(phydev, MTK_EXT_PAGE_ACCESS, page);
+-}
+-
+ static void mtk_gephy_config_init(struct phy_device *phydev)
+ {
+ /* Disable EEE */
+@@ -114,8 +106,8 @@ static struct phy_driver mtk_gephy_drive
+ .handle_interrupt = genphy_handle_interrupt_no_ack,
+ .suspend = genphy_suspend,
+ .resume = genphy_resume,
+- .read_page = mtk_gephy_read_page,
+- .write_page = mtk_gephy_write_page,
++ .read_page = mtk_phy_read_page,
++ .write_page = mtk_phy_write_page,
+ },
+ {
+ PHY_ID_MATCH_EXACT(0x03a29441),
+@@ -128,8 +120,8 @@ static struct phy_driver mtk_gephy_drive
+ .handle_interrupt = genphy_handle_interrupt_no_ack,
+ .suspend = genphy_suspend,
+ .resume = genphy_resume,
+- .read_page = mtk_gephy_read_page,
+- .write_page = mtk_gephy_write_page,
++ .read_page = mtk_phy_read_page,
++ .write_page = mtk_phy_write_page,
+ },
+ };
+
+--- a/drivers/net/phy/mediatek/mtk-phy-lib.c
++++ b/drivers/net/phy/mediatek/mtk-phy-lib.c
+@@ -6,6 +6,18 @@
+
+ #include "mtk.h"
+
++int mtk_phy_read_page(struct phy_device *phydev)
++{
++ return __phy_read(phydev, MTK_EXT_PAGE_ACCESS);
++}
++EXPORT_SYMBOL_GPL(mtk_phy_read_page);
++
++int mtk_phy_write_page(struct phy_device *phydev, int page)
++{
++ return __phy_write(phydev, MTK_EXT_PAGE_ACCESS, page);
++}
++EXPORT_SYMBOL_GPL(mtk_phy_write_page);
++
+ int mtk_phy_led_hw_is_supported(struct phy_device *phydev, u8 index,
+ unsigned long rules,
+ unsigned long supported_triggers)
+--- a/drivers/net/phy/mediatek/mtk.h
++++ b/drivers/net/phy/mediatek/mtk.h
+@@ -62,6 +62,9 @@
+ #define MTK_PHY_LED_STATE_FORCE_BLINK 1
+ #define MTK_PHY_LED_STATE_NETDEV 2
+
++int mtk_phy_read_page(struct phy_device *phydev);
++int mtk_phy_write_page(struct phy_device *phydev, int page);
++
+ int mtk_phy_led_hw_is_supported(struct phy_device *phydev, u8 index,
+ unsigned long rules,
+ unsigned long supported_triggers);
diff --git a/target/linux/mediatek/patches-6.6/733-06-net-phy-mediatek-Hook-LED-helper-functions-in-mtk-ge.patch b/target/linux/mediatek/patches-6.6/733-06-net-phy-mediatek-Hook-LED-helper-functions-in-mtk-ge.patch
new file mode 100644
index 0000000000..485e262134
--- /dev/null
+++ b/target/linux/mediatek/patches-6.6/733-06-net-phy-mediatek-Hook-LED-helper-functions-in-mtk-ge.patch
@@ -0,0 +1,146 @@
+From 9403f1d54598ae56386a8bf47a5b6b34c884e4f5 Mon Sep 17 00:00:00 2001
+From: "SkyLake.Huang" <skylake.huang@mediatek.com>
+Date: Mon, 1 Jul 2024 18:54:10 +0800
+Subject: [PATCH 06/13] net: phy: mediatek: Hook LED helper functions in
+ mtk-ge.c
+
+We have mtk-phy-lib.c now so that we can use LED helper functions in
+mtk-ge.c(mt7531 part). It also means that mt7531/mt7981/mt7988's
+Giga ethernet phys share almost the same HW LED controller design.
+Also, add probe function for mt7531 so that it can initialize LED state.
+
+Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
+---
+ drivers/net/phy/mediatek/mtk-ge.c | 100 ++++++++++++++++++++++++++++++
+ 1 file changed, 100 insertions(+)
+
+--- a/drivers/net/phy/mediatek/mtk-ge.c
++++ b/drivers/net/phy/mediatek/mtk-ge.c
+@@ -14,6 +14,10 @@
+ #define MTK_PHY_PAGE_EXTENDED_2A30 0x2a30
+ #define MTK_PHY_PAGE_EXTENDED_52B5 0x52b5
+
++struct mtk_gephy_priv {
++ unsigned long led_state;
++};
++
+ static void mtk_gephy_config_init(struct phy_device *phydev)
+ {
+ /* Disable EEE */
+@@ -94,6 +98,96 @@ static int mt7531_phy_config_init(struct
+ return 0;
+ }
+
++static int mt7531_phy_probe(struct phy_device *phydev)
++{
++ struct mtk_gephy_priv *priv;
++
++ priv = devm_kzalloc(&phydev->mdio.dev, sizeof(struct mtk_gephy_priv),
++ GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ phydev->priv = priv;
++
++ mtk_phy_leds_state_init(phydev);
++
++ return 0;
++}
++
++static int mt753x_phy_led_blink_set(struct phy_device *phydev, u8 index,
++ unsigned long *delay_on,
++ unsigned long *delay_off)
++{
++ struct mtk_gephy_priv *priv = phydev->priv;
++ bool blinking = false;
++ int err = 0;
++
++ err = mtk_phy_led_num_dly_cfg(index, delay_on, delay_off, &blinking);
++ if (err < 0)
++ return err;
++
++ err = mtk_phy_hw_led_blink_set(phydev, index, &priv->led_state,
++ blinking);
++ if (err)
++ return err;
++
++ return mtk_phy_hw_led_on_set(phydev, index, &priv->led_state,
++ MTK_GPHY_LED_ON_MASK, false);
++}
++
++static int mt753x_phy_led_brightness_set(struct phy_device *phydev,
++ u8 index, enum led_brightness value)
++{
++ struct mtk_gephy_priv *priv = phydev->priv;
++ int err;
++
++ err = mtk_phy_hw_led_blink_set(phydev, index, &priv->led_state, false);
++ if (err)
++ return err;
++
++ return mtk_phy_hw_led_on_set(phydev, index, &priv->led_state,
++ MTK_GPHY_LED_ON_MASK, (value != LED_OFF));
++}
++
++static const unsigned long supported_triggers =
++ (BIT(TRIGGER_NETDEV_FULL_DUPLEX) |
++ BIT(TRIGGER_NETDEV_HALF_DUPLEX) |
++ BIT(TRIGGER_NETDEV_LINK) |
++ BIT(TRIGGER_NETDEV_LINK_10) |
++ BIT(TRIGGER_NETDEV_LINK_100) |
++ BIT(TRIGGER_NETDEV_LINK_1000) |
++ BIT(TRIGGER_NETDEV_RX) |
++ BIT(TRIGGER_NETDEV_TX));
++
++static int mt753x_phy_led_hw_is_supported(struct phy_device *phydev, u8 index,
++ unsigned long rules)
++{
++ return mtk_phy_led_hw_is_supported(phydev, index, rules,
++ supported_triggers);
++}
++
++static int mt753x_phy_led_hw_control_get(struct phy_device *phydev, u8 index,
++ unsigned long *rules)
++{
++ struct mtk_gephy_priv *priv = phydev->priv;
++
++ return mtk_phy_led_hw_ctrl_get(phydev, index, rules, &priv->led_state,
++ MTK_GPHY_LED_ON_SET,
++ MTK_GPHY_LED_RX_BLINK_SET,
++ MTK_GPHY_LED_TX_BLINK_SET);
++};
++
++static int mt753x_phy_led_hw_control_set(struct phy_device *phydev, u8 index,
++ unsigned long rules)
++{
++ struct mtk_gephy_priv *priv = phydev->priv;
++
++ return mtk_phy_led_hw_ctrl_set(phydev, index, rules, &priv->led_state,
++ MTK_GPHY_LED_ON_SET,
++ MTK_GPHY_LED_RX_BLINK_SET,
++ MTK_GPHY_LED_TX_BLINK_SET);
++};
++
+ static struct phy_driver mtk_gephy_driver[] = {
+ {
+ PHY_ID_MATCH_EXACT(0x03a29412),
+@@ -112,6 +206,7 @@ static struct phy_driver mtk_gephy_drive
+ {
+ PHY_ID_MATCH_EXACT(0x03a29441),
+ .name = "MediaTek MT7531 PHY",
++ .probe = mt7531_phy_probe,
+ .config_init = mt7531_phy_config_init,
+ /* Interrupts are handled by the switch, not the PHY
+ * itself.
+@@ -122,6 +217,11 @@ static struct phy_driver mtk_gephy_drive
+ .resume = genphy_resume,
+ .read_page = mtk_phy_read_page,
+ .write_page = mtk_phy_write_page,
++ .led_blink_set = mt753x_phy_led_blink_set,
++ .led_brightness_set = mt753x_phy_led_brightness_set,
++ .led_hw_is_supported = mt753x_phy_led_hw_is_supported,
++ .led_hw_control_set = mt753x_phy_led_hw_control_set,
++ .led_hw_control_get = mt753x_phy_led_hw_control_get,
+ },
+ };
+
diff --git a/target/linux/mediatek/patches-6.6/733-07-net-phy-mediatek-add-MT7530-MT7531-s-PHY-ID-macros.patch b/target/linux/mediatek/patches-6.6/733-07-net-phy-mediatek-add-MT7530-MT7531-s-PHY-ID-macros.patch
new file mode 100644
index 0000000000..bfdf864f8d
--- /dev/null
+++ b/target/linux/mediatek/patches-6.6/733-07-net-phy-mediatek-add-MT7530-MT7531-s-PHY-ID-macros.patch
@@ -0,0 +1,54 @@
+From 51ee83602dbb84716180d9b6e43f6bebb0c2d7bd Mon Sep 17 00:00:00 2001
+From: "SkyLake.Huang" <skylake.huang@mediatek.com>
+Date: Mon, 1 Jul 2024 18:54:11 +0800
+Subject: [PATCH 07/13] net: phy: mediatek: add MT7530 & MT7531's PHY ID macros
+
+This patch adds MT7530 & MT7531's PHY ID macros in mtk-ge.c so that
+it follows the same rule of mtk-ge-soc.c.
+
+Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
+---
+ drivers/net/phy/mediatek/mtk-ge.c | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/phy/mediatek/mtk-ge.c
++++ b/drivers/net/phy/mediatek/mtk-ge.c
+@@ -6,6 +6,9 @@
+
+ #include "mtk.h"
+
++#define MTK_GPHY_ID_MT7530 0x03a29412
++#define MTK_GPHY_ID_MT7531 0x03a29441
++
+ #define MTK_EXT_PAGE_ACCESS 0x1f
+ #define MTK_PHY_PAGE_STANDARD 0x0000
+ #define MTK_PHY_PAGE_EXTENDED 0x0001
+@@ -190,7 +193,7 @@ static int mt753x_phy_led_hw_control_set
+
+ static struct phy_driver mtk_gephy_driver[] = {
+ {
+- PHY_ID_MATCH_EXACT(0x03a29412),
++ PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7530),
+ .name = "MediaTek MT7530 PHY",
+ .config_init = mt7530_phy_config_init,
+ /* Interrupts are handled by the switch, not the PHY
+@@ -204,7 +207,7 @@ static struct phy_driver mtk_gephy_drive
+ .write_page = mtk_phy_write_page,
+ },
+ {
+- PHY_ID_MATCH_EXACT(0x03a29441),
++ PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7531),
+ .name = "MediaTek MT7531 PHY",
+ .probe = mt7531_phy_probe,
+ .config_init = mt7531_phy_config_init,
+@@ -228,8 +231,8 @@ static struct phy_driver mtk_gephy_drive
+ module_phy_driver(mtk_gephy_driver);
+
+ static struct mdio_device_id __maybe_unused mtk_gephy_tbl[] = {
+- { PHY_ID_MATCH_EXACT(0x03a29441) },
+- { PHY_ID_MATCH_EXACT(0x03a29412) },
++ { PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7530) },
++ { PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7531) },
+ { }
+ };
+
diff --git a/target/linux/mediatek/patches-6.6/733-08-net-phy-mediatek-Change-mtk-ge-soc.c-line-wrapping.patch b/target/linux/mediatek/patches-6.6/733-08-net-phy-mediatek-Change-mtk-ge-soc.c-line-wrapping.patch
new file mode 100644
index 0000000000..ca155e5012
--- /dev/null
+++ b/target/linux/mediatek/patches-6.6/733-08-net-phy-mediatek-Change-mtk-ge-soc.c-line-wrapping.patch
@@ -0,0 +1,182 @@
+From e73df692396b0d6bdcb2317299fa1e8e547f3446 Mon Sep 17 00:00:00 2001
+From: "SkyLake.Huang" <skylake.huang@mediatek.com>
+Date: Mon, 1 Jul 2024 18:54:12 +0800
+Subject: [PATCH 08/13] net: phy: mediatek: Change mtk-ge-soc.c line wrapping
+
+This patch shrinks mtk-ge-soc.c line wrapping to 80 characters.
+
+Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
+---
+ drivers/net/phy/mediatek/mtk-ge-soc.c | 67 +++++++++++++++++----------
+ 1 file changed, 42 insertions(+), 25 deletions(-)
+
+--- a/drivers/net/phy/mediatek/mtk-ge-soc.c
++++ b/drivers/net/phy/mediatek/mtk-ge-soc.c
+@@ -295,7 +295,8 @@ static int cal_cycle(struct phy_device *
+ ret = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1,
+ MTK_PHY_RG_AD_CAL_CLK, reg_val,
+ reg_val & MTK_PHY_DA_CAL_CLK, 500,
+- ANALOG_INTERNAL_OPERATION_MAX_US, false);
++ ANALOG_INTERNAL_OPERATION_MAX_US,
++ false);
+ if (ret) {
+ phydev_err(phydev, "Calibration cycle timeout\n");
+ return ret;
+@@ -304,7 +305,7 @@ static int cal_cycle(struct phy_device *
+ phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_AD_CALIN,
+ MTK_PHY_DA_CALIN_FLAG);
+ ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_AD_CAL_COMP) >>
+- MTK_PHY_AD_CAL_COMP_OUT_SHIFT;
++ MTK_PHY_AD_CAL_COMP_OUT_SHIFT;
+ phydev_dbg(phydev, "cal_val: 0x%x, ret: %d\n", cal_val, ret);
+
+ return ret;
+@@ -394,38 +395,46 @@ static int tx_amp_fill_result(struct phy
+ }
+
+ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG,
+- MTK_PHY_DA_TX_I2MPB_A_GBE_MASK, (buf[0] + bias[0]) << 10);
++ MTK_PHY_DA_TX_I2MPB_A_GBE_MASK,
++ (buf[0] + bias[0]) << 10);
+ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG,
+ MTK_PHY_DA_TX_I2MPB_A_TBT_MASK, buf[0] + bias[1]);
+ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2,
+- MTK_PHY_DA_TX_I2MPB_A_HBT_MASK, (buf[0] + bias[2]) << 10);
++ MTK_PHY_DA_TX_I2MPB_A_HBT_MASK,
++ (buf[0] + bias[2]) << 10);
+ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2,
+ MTK_PHY_DA_TX_I2MPB_A_TST_MASK, buf[0] + bias[3]);
+
+ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1,
+- MTK_PHY_DA_TX_I2MPB_B_GBE_MASK, (buf[1] + bias[4]) << 8);
++ MTK_PHY_DA_TX_I2MPB_B_GBE_MASK,
++ (buf[1] + bias[4]) << 8);
+ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1,
+ MTK_PHY_DA_TX_I2MPB_B_TBT_MASK, buf[1] + bias[5]);
+ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2,
+- MTK_PHY_DA_TX_I2MPB_B_HBT_MASK, (buf[1] + bias[6]) << 8);
++ MTK_PHY_DA_TX_I2MPB_B_HBT_MASK,
++ (buf[1] + bias[6]) << 8);
+ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2,
+ MTK_PHY_DA_TX_I2MPB_B_TST_MASK, buf[1] + bias[7]);
+
+ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1,
+- MTK_PHY_DA_TX_I2MPB_C_GBE_MASK, (buf[2] + bias[8]) << 8);
++ MTK_PHY_DA_TX_I2MPB_C_GBE_MASK,
++ (buf[2] + bias[8]) << 8);
+ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1,
+ MTK_PHY_DA_TX_I2MPB_C_TBT_MASK, buf[2] + bias[9]);
+ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2,
+- MTK_PHY_DA_TX_I2MPB_C_HBT_MASK, (buf[2] + bias[10]) << 8);
++ MTK_PHY_DA_TX_I2MPB_C_HBT_MASK,
++ (buf[2] + bias[10]) << 8);
+ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2,
+ MTK_PHY_DA_TX_I2MPB_C_TST_MASK, buf[2] + bias[11]);
+
+ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1,
+- MTK_PHY_DA_TX_I2MPB_D_GBE_MASK, (buf[3] + bias[12]) << 8);
++ MTK_PHY_DA_TX_I2MPB_D_GBE_MASK,
++ (buf[3] + bias[12]) << 8);
+ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1,
+ MTK_PHY_DA_TX_I2MPB_D_TBT_MASK, buf[3] + bias[13]);
+ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2,
+- MTK_PHY_DA_TX_I2MPB_D_HBT_MASK, (buf[3] + bias[14]) << 8);
++ MTK_PHY_DA_TX_I2MPB_D_HBT_MASK,
++ (buf[3] + bias[14]) << 8);
+ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2,
+ MTK_PHY_DA_TX_I2MPB_D_TST_MASK, buf[3] + bias[15]);
+
+@@ -616,7 +625,8 @@ static int tx_vcm_cal_sw(struct phy_devi
+ goto restore;
+
+ /* We calibrate TX-VCM in different logic. Check upper index and then
+- * lower index. If this calibration is valid, apply lower index's result.
++ * lower index. If this calibration is valid, apply lower index's
++ * result.
+ */
+ ret = upper_ret - lower_ret;
+ if (ret == 1) {
+@@ -645,7 +655,8 @@ static int tx_vcm_cal_sw(struct phy_devi
+ } else if (upper_idx == TXRESERVE_MAX && upper_ret == 0 &&
+ lower_ret == 0) {
+ ret = 0;
+- phydev_warn(phydev, "TX-VCM SW cal result at high margin 0x%x\n",
++ phydev_warn(phydev,
++ "TX-VCM SW cal result at high margin 0x%x\n",
+ upper_idx);
+ } else {
+ ret = -EINVAL;
+@@ -749,7 +760,8 @@ static void mt7981_phy_finetune(struct p
+
+ /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 9 */
+ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234,
+- MTK_PHY_TR_OPEN_LOOP_EN_MASK | MTK_PHY_LPF_X_AVERAGE_MASK,
++ MTK_PHY_TR_OPEN_LOOP_EN_MASK |
++ MTK_PHY_LPF_X_AVERAGE_MASK,
+ BIT(0) | FIELD_PREP(MTK_PHY_LPF_X_AVERAGE_MASK, 0x9));
+
+ /* rg_tr_lpf_cnt_val = 512 */
+@@ -818,7 +830,8 @@ static void mt7988_phy_finetune(struct p
+
+ /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 10 */
+ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234,
+- MTK_PHY_TR_OPEN_LOOP_EN_MASK | MTK_PHY_LPF_X_AVERAGE_MASK,
++ MTK_PHY_TR_OPEN_LOOP_EN_MASK |
++ MTK_PHY_LPF_X_AVERAGE_MASK,
+ BIT(0) | FIELD_PREP(MTK_PHY_LPF_X_AVERAGE_MASK, 0xa));
+
+ /* rg_tr_lpf_cnt_val = 1023 */
+@@ -930,7 +943,8 @@ static void mt798x_phy_eee(struct phy_de
+ phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
+
+ phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_3);
+- __phy_modify(phydev, MTK_PHY_LPI_REG_14, MTK_PHY_LPI_WAKE_TIMER_1000_MASK,
++ __phy_modify(phydev, MTK_PHY_LPI_REG_14,
++ MTK_PHY_LPI_WAKE_TIMER_1000_MASK,
+ FIELD_PREP(MTK_PHY_LPI_WAKE_TIMER_1000_MASK, 0x19c));
+
+ __phy_modify(phydev, MTK_PHY_LPI_REG_1c, MTK_PHY_SMI_DET_ON_THRESH_MASK,
+@@ -940,7 +954,8 @@ static void mt798x_phy_eee(struct phy_de
+ phy_modify_mmd(phydev, MDIO_MMD_VEND1,
+ MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG122,
+ MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK,
+- FIELD_PREP(MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK, 0xff));
++ FIELD_PREP(MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK,
++ 0xff));
+ }
+
+ static int cal_sw(struct phy_device *phydev, enum CAL_ITEM cal_item,
+@@ -1119,14 +1134,15 @@ static int mt798x_phy_led_brightness_set
+ MTK_GPHY_LED_ON_MASK, (value != LED_OFF));
+ }
+
+-static const unsigned long supported_triggers = (BIT(TRIGGER_NETDEV_FULL_DUPLEX) |
+- BIT(TRIGGER_NETDEV_HALF_DUPLEX) |
+- BIT(TRIGGER_NETDEV_LINK) |
+- BIT(TRIGGER_NETDEV_LINK_10) |
+- BIT(TRIGGER_NETDEV_LINK_100) |
+- BIT(TRIGGER_NETDEV_LINK_1000) |
+- BIT(TRIGGER_NETDEV_RX) |
+- BIT(TRIGGER_NETDEV_TX));
++static const unsigned long supported_triggers =
++ (BIT(TRIGGER_NETDEV_FULL_DUPLEX) |
++ BIT(TRIGGER_NETDEV_HALF_DUPLEX) |
++ BIT(TRIGGER_NETDEV_LINK) |
++ BIT(TRIGGER_NETDEV_LINK_10) |
++ BIT(TRIGGER_NETDEV_LINK_100) |
++ BIT(TRIGGER_NETDEV_LINK_1000) |
++ BIT(TRIGGER_NETDEV_RX) |
++ BIT(TRIGGER_NETDEV_TX));
+
+ static int mt798x_phy_led_hw_is_supported(struct phy_device *phydev, u8 index,
+ unsigned long rules)
+@@ -1189,7 +1205,8 @@ static int mt7988_phy_fix_leds_polaritie
+ /* Only now setup pinctrl to avoid bogus blinking */
+ pinctrl = devm_pinctrl_get_select(&phydev->mdio.dev, "gbe-led");
+ if (IS_ERR(pinctrl))
+- dev_err(&phydev->mdio.bus->dev, "Failed to setup PHY LED pinctrl\n");
++ dev_err(&phydev->mdio.bus->dev,
++ "Failed to setup PHY LED pinctrl\n");
+
+ return 0;
+ }
diff --git a/target/linux/mediatek/patches-6.6/733-09-net-phy-mediatek-Add-token-ring-access-helper-functi.patch b/target/linux/mediatek/patches-6.6/733-09-net-phy-mediatek-Add-token-ring-access-helper-functi.patch
new file mode 100644
index 0000000000..49e4c2057f
--- /dev/null
+++ b/target/linux/mediatek/patches-6.6/733-09-net-phy-mediatek-Add-token-ring-access-helper-functi.patch
@@ -0,0 +1,614 @@
+From 60228de48d8bfde62b4db5945314e6a62079f091 Mon Sep 17 00:00:00 2001
+From: "SkyLake.Huang" <skylake.huang@mediatek.com>
+Date: Mon, 1 Jul 2024 18:54:13 +0800
+Subject: [PATCH 09/13] net: phy: mediatek: Add token ring access helper
+ functions in mtk-phy-lib
+
+This patch adds TR(token ring) manipulations and adds correct
+macro names for those magic numbers. TR is a way to access
+proprietary registers on page 52b5. Use these helper functions
+so we can see which fields we're going to modify/set/clear.
+
+This patch doesn't really change registers' settings but just
+enhances readability and maintainability.
+
+Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
+---
+ drivers/net/phy/mediatek/mtk-ge-soc.c | 297 ++++++++++++++++---------
+ drivers/net/phy/mediatek/mtk-ge.c | 82 +++++--
+ drivers/net/phy/mediatek/mtk-phy-lib.c | 91 ++++++++
+ drivers/net/phy/mediatek/mtk.h | 13 ++
+ 4 files changed, 358 insertions(+), 125 deletions(-)
+
+--- a/drivers/net/phy/mediatek/mtk-ge-soc.c
++++ b/drivers/net/phy/mediatek/mtk-ge-soc.c
+@@ -24,7 +24,108 @@
+ #define MTK_PHY_SMI_DET_ON_THRESH_MASK GENMASK(13, 8)
+
+ #define MTK_PHY_PAGE_EXTENDED_2A30 0x2a30
+-#define MTK_PHY_PAGE_EXTENDED_52B5 0x52b5
++
++/* Registers on Token Ring debug nodes */
++/* ch_addr = 0x0, node_addr = 0x7, data_addr = 0x15 */
++/* NormMseLoThresh */
++#define NORMAL_MSE_LO_THRESH_MASK GENMASK(15, 8)
++
++/* ch_addr = 0x0, node_addr = 0xf, data_addr = 0x3c */
++/* RemAckCntLimitCtrl */
++#define REMOTE_ACK_COUNT_LIMIT_CTRL_MASK GENMASK(2, 1)
++
++/* ch_addr = 0x1, node_addr = 0xd, data_addr = 0x20 */
++/* VcoSlicerThreshBitsHigh */
++#define VCO_SLICER_THRESH_HIGH_MASK GENMASK(23, 0)
++
++/* ch_addr = 0x1, node_addr = 0xf, data_addr = 0x0 */
++/* DfeTailEnableVgaThresh1000 */
++#define DFE_TAIL_EANBLE_VGA_TRHESH_1000 GENMASK(5, 1)
++
++/* ch_addr = 0x1, node_addr = 0xf, data_addr = 0x1 */
++/* MrvlTrFix100Kp */
++#define MRVL_TR_FIX_100KP_MASK GENMASK(22, 20)
++/* MrvlTrFix100Kf */
++#define MRVL_TR_FIX_100KF_MASK GENMASK(19, 17)
++/* MrvlTrFix1000Kp */
++#define MRVL_TR_FIX_1000KP_MASK GENMASK(16, 14)
++/* MrvlTrFix1000Kf */
++#define MRVL_TR_FIX_1000KF_MASK GENMASK(13, 11)
++
++/* ch_addr = 0x1, node_addr = 0xf, data_addr = 0x12 */
++/* VgaDecRate */
++#define VGA_DECIMATION_RATE_MASK GENMASK(8, 5)
++
++/* ch_addr = 0x1, node_addr = 0xf, data_addr = 0x17 */
++/* SlvDSPreadyTime */
++#define SLAVE_DSP_READY_TIME_MASK GENMASK(22, 15)
++/* MasDSPreadyTime */
++#define MASTER_DSP_READY_TIME_MASK GENMASK(14, 7)
++
++/* ch_addr = 0x1, node_addr = 0xf, data_addr = 0x18 */
++/* EnabRandUpdTrig */
++#define ENABLE_RANDOM_UPDOWN_COUNTER_TRIGGER BIT(8)
++
++/* ch_addr = 0x1, node_addr = 0xf, data_addr = 0x20 */
++/* ResetSyncOffset */
++#define RESET_SYNC_OFFSET_MASK GENMASK(11, 8)
++
++/* ch_addr = 0x2, node_addr = 0xd, data_addr = 0x0 */
++/* FfeUpdGainForceVal */
++#define FFE_UPDATE_GAIN_FORCE_VAL_MASK GENMASK(9, 7)
++/* FfeUpdGainForce */
++#define FFE_UPDATE_GAIN_FORCE BIT(6)
++
++/* ch_addr = 0x2, node_addr = 0xd, data_addr = 0x3 */
++/* TrFreeze */
++#define TR_FREEZE_MASK GENMASK(11, 0)
++
++/* ch_addr = 0x2, node_addr = 0xd, data_addr = 0x6 */
++/* SS: Steady-state, KP: Proportional Gain */
++/* SSTrKp100 */
++#define SS_TR_KP100_MASK GENMASK(21, 19)
++/* SSTrKf100 */
++#define SS_TR_KF100_MASK GENMASK(18, 16)
++/* SSTrKp1000Mas */
++#define SS_TR_KP1000_MASTER_MASK GENMASK(15, 13)
++/* SSTrKf1000Mas */
++#define SS_TR_KF1000_MASTER_MASK GENMASK(12, 10)
++/* SSTrKp1000Slv */
++#define SS_TR_KP1000_SLAVE_MASK GENMASK(9, 7)
++/* SSTrKf1000Slv */
++#define SS_TR_KF1000_SLAVE_MASK GENMASK(6, 4)
++
++/* ch_addr = 0x2, node_addr = 0xd, data_addr = 0x8 */
++/* clear this bit if wanna select from AFE */
++/* Regsigdet_sel_1000 */
++#define EEE1000_SELECT_SIGNAL_DETECTION_FROM_DFE BIT(4)
++
++/* ch_addr = 0x2, node_addr = 0xd, data_addr = 0xd */
++/* RegEEE_st2TrKf1000 */
++#define EEE1000_STAGE2_TR_KF_MASK GENMASK(13, 11)
++
++/* ch_addr = 0x2, node_addr = 0xd, data_addr = 0xf */
++/* RegEEE_slv_waketr_timer_tar */
++#define SLAVE_WAKETR_TIMER_MASK GENMASK(20, 11)
++/* RegEEE_slv_remtx_timer_tar */
++#define SLAVE_REMTX_TIMER_MASK GENMASK(10, 1)
++
++/* ch_addr = 0x2, node_addr = 0xd, data_addr = 0x10 */
++/* RegEEE_slv_wake_int_timer_tar */
++#define SLAVE_WAKEINT_TIMER_MASK GENMASK(10, 1)
++
++/* ch_addr = 0x2, node_addr = 0xd, data_addr = 0x14 */
++/* RegEEE_trfreeze_timer2 */
++#define TR_FREEZE_TIMER2_MASK GENMASK(9, 0)
++
++/* ch_addr = 0x2, node_addr = 0xd, data_addr = 0x1c */
++/* RegEEE100Stg1_tar */
++#define EEE100_LPSYNC_STAGE1_UPDATE_TIMER_MASK GENMASK(8, 0)
++
++/* ch_addr = 0x2, node_addr = 0xd, data_addr = 0x25 */
++/* REGEEE_wake_slv_tr_wait_dfesigdet_en */
++#define WAKE_SLAVE_TR_WAIT_DFE_DETECTION_EN BIT(11)
++
+
+ #define ANALOG_INTERNAL_OPERATION_MAX_US 20
+ #define TXRESERVE_MIN 0
+@@ -679,40 +780,36 @@ restore:
+ static void mt798x_phy_common_finetune(struct phy_device *phydev)
+ {
+ phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
+- /* SlvDSPreadyTime = 24, MasDSPreadyTime = 24 */
+- __phy_write(phydev, 0x11, 0xc71);
+- __phy_write(phydev, 0x12, 0xc);
+- __phy_write(phydev, 0x10, 0x8fae);
+-
+- /* EnabRandUpdTrig = 1 */
+- __phy_write(phydev, 0x11, 0x2f00);
+- __phy_write(phydev, 0x12, 0xe);
+- __phy_write(phydev, 0x10, 0x8fb0);
+-
+- /* NormMseLoThresh = 85 */
+- __phy_write(phydev, 0x11, 0x55a0);
+- __phy_write(phydev, 0x12, 0x0);
+- __phy_write(phydev, 0x10, 0x83aa);
+-
+- /* FfeUpdGainForce = 1(Enable), FfeUpdGainForceVal = 4 */
+- __phy_write(phydev, 0x11, 0x240);
+- __phy_write(phydev, 0x12, 0x0);
+- __phy_write(phydev, 0x10, 0x9680);
+-
+- /* TrFreeze = 0 (mt7988 default) */
+- __phy_write(phydev, 0x11, 0x0);
+- __phy_write(phydev, 0x12, 0x0);
+- __phy_write(phydev, 0x10, 0x9686);
+-
+- /* SSTrKp100 = 5 */
+- /* SSTrKf100 = 6 */
+- /* SSTrKp1000Mas = 5 */
+- /* SSTrKf1000Mas = 6 */
+- /* SSTrKp1000Slv = 5 */
+- /* SSTrKf1000Slv = 6 */
+- __phy_write(phydev, 0x11, 0xbaef);
+- __phy_write(phydev, 0x12, 0x2e);
+- __phy_write(phydev, 0x10, 0x968c);
++ __mtk_tr_modify(phydev, 0x1, 0xf, 0x17,
++ SLAVE_DSP_READY_TIME_MASK | MASTER_DSP_READY_TIME_MASK,
++ FIELD_PREP(SLAVE_DSP_READY_TIME_MASK, 0x18) |
++ FIELD_PREP(MASTER_DSP_READY_TIME_MASK, 0x18));
++
++ __mtk_tr_set_bits(phydev, 0x1, 0xf, 0x18,
++ ENABLE_RANDOM_UPDOWN_COUNTER_TRIGGER);
++
++ __mtk_tr_modify(phydev, 0x0, 0x7, 0x15,
++ NORMAL_MSE_LO_THRESH_MASK,
++ FIELD_PREP(NORMAL_MSE_LO_THRESH_MASK, 0x55));
++
++ __mtk_tr_modify(phydev, 0x2, 0xd, 0x0,
++ FFE_UPDATE_GAIN_FORCE_VAL_MASK,
++ FIELD_PREP(FFE_UPDATE_GAIN_FORCE_VAL_MASK, 0x4) |
++ FFE_UPDATE_GAIN_FORCE);
++
++ __mtk_tr_clr_bits(phydev, 0x2, 0xd, 0x3, TR_FREEZE_MASK);
++
++ __mtk_tr_modify(phydev, 0x2, 0xd, 0x6,
++ SS_TR_KP100_MASK | SS_TR_KF100_MASK |
++ SS_TR_KP1000_MASTER_MASK | SS_TR_KF1000_MASTER_MASK |
++ SS_TR_KP1000_SLAVE_MASK | SS_TR_KF1000_SLAVE_MASK,
++ FIELD_PREP(SS_TR_KP100_MASK, 0x5) |
++ FIELD_PREP(SS_TR_KF100_MASK, 0x6) |
++ FIELD_PREP(SS_TR_KP1000_MASTER_MASK, 0x5) |
++ FIELD_PREP(SS_TR_KF1000_MASTER_MASK, 0x6) |
++ FIELD_PREP(SS_TR_KP1000_SLAVE_MASK, 0x5) |
++ FIELD_PREP(SS_TR_KF1000_SLAVE_MASK, 0x6));
++
+ phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
+ }
+
+@@ -735,27 +832,29 @@ static void mt7981_phy_finetune(struct p
+ }
+
+ phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
+- /* ResetSyncOffset = 6 */
+- __phy_write(phydev, 0x11, 0x600);
+- __phy_write(phydev, 0x12, 0x0);
+- __phy_write(phydev, 0x10, 0x8fc0);
+-
+- /* VgaDecRate = 1 */
+- __phy_write(phydev, 0x11, 0x4c2a);
+- __phy_write(phydev, 0x12, 0x3e);
+- __phy_write(phydev, 0x10, 0x8fa4);
++ __mtk_tr_modify(phydev, 0x1, 0xf, 0x20,
++ RESET_SYNC_OFFSET_MASK,
++ FIELD_PREP(RESET_SYNC_OFFSET_MASK, 0x6));
++
++ __mtk_tr_modify(phydev, 0x1, 0xf, 0x12,
++ VGA_DECIMATION_RATE_MASK,
++ FIELD_PREP(VGA_DECIMATION_RATE_MASK, 0x1));
+
+ /* MrvlTrFix100Kp = 3, MrvlTrFix100Kf = 2,
+ * MrvlTrFix1000Kp = 3, MrvlTrFix1000Kf = 2
+ */
+- __phy_write(phydev, 0x11, 0xd10a);
+- __phy_write(phydev, 0x12, 0x34);
+- __phy_write(phydev, 0x10, 0x8f82);
++ __mtk_tr_modify(phydev, 0x1, 0xf, 0x1,
++ MRVL_TR_FIX_100KP_MASK | MRVL_TR_FIX_100KF_MASK |
++ MRVL_TR_FIX_1000KP_MASK | MRVL_TR_FIX_1000KF_MASK,
++ FIELD_PREP(MRVL_TR_FIX_100KP_MASK, 0x3) |
++ FIELD_PREP(MRVL_TR_FIX_100KF_MASK, 0x2) |
++ FIELD_PREP(MRVL_TR_FIX_1000KP_MASK, 0x3) |
++ FIELD_PREP(MRVL_TR_FIX_1000KF_MASK, 0x2));
+
+ /* VcoSlicerThreshBitsHigh */
+- __phy_write(phydev, 0x11, 0x5555);
+- __phy_write(phydev, 0x12, 0x55);
+- __phy_write(phydev, 0x10, 0x8ec0);
++ __mtk_tr_modify(phydev, 0x1, 0xd, 0x20,
++ VCO_SLICER_THRESH_HIGH_MASK,
++ FIELD_PREP(VCO_SLICER_THRESH_HIGH_MASK, 0x555555));
+ phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
+
+ /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 9 */
+@@ -807,25 +906,23 @@ static void mt7988_phy_finetune(struct p
+ phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_TX_FILTER, 0x5);
+
+ phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
+- /* ResetSyncOffset = 5 */
+- __phy_write(phydev, 0x11, 0x500);
+- __phy_write(phydev, 0x12, 0x0);
+- __phy_write(phydev, 0x10, 0x8fc0);
++ __mtk_tr_modify(phydev, 0x1, 0xf, 0x20,
++ RESET_SYNC_OFFSET_MASK,
++ FIELD_PREP(RESET_SYNC_OFFSET_MASK, 0x5));
+
+ /* VgaDecRate is 1 at default on mt7988 */
+
+- /* MrvlTrFix100Kp = 6, MrvlTrFix100Kf = 7,
+- * MrvlTrFix1000Kp = 6, MrvlTrFix1000Kf = 7
+- */
+- __phy_write(phydev, 0x11, 0xb90a);
+- __phy_write(phydev, 0x12, 0x6f);
+- __phy_write(phydev, 0x10, 0x8f82);
+-
+- /* RemAckCntLimitCtrl = 1 */
+- __phy_write(phydev, 0x11, 0xfbba);
+- __phy_write(phydev, 0x12, 0xc3);
+- __phy_write(phydev, 0x10, 0x87f8);
+-
++ __mtk_tr_modify(phydev, 0x1, 0xf, 0x1,
++ MRVL_TR_FIX_100KP_MASK | MRVL_TR_FIX_100KF_MASK |
++ MRVL_TR_FIX_1000KP_MASK | MRVL_TR_FIX_1000KF_MASK,
++ FIELD_PREP(MRVL_TR_FIX_100KP_MASK, 0x6) |
++ FIELD_PREP(MRVL_TR_FIX_100KF_MASK, 0x7) |
++ FIELD_PREP(MRVL_TR_FIX_1000KP_MASK, 0x6) |
++ FIELD_PREP(MRVL_TR_FIX_1000KF_MASK, 0x7));
++
++ __mtk_tr_modify(phydev, 0x0, 0xf, 0x3c,
++ REMOTE_ACK_COUNT_LIMIT_CTRL_MASK,
++ FIELD_PREP(REMOTE_ACK_COUNT_LIMIT_CTRL_MASK, 0x1));
+ phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
+
+ /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 10 */
+@@ -901,45 +998,37 @@ static void mt798x_phy_eee(struct phy_de
+ MTK_PHY_TR_READY_SKIP_AFE_WAKEUP);
+
+ phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
+- /* Regsigdet_sel_1000 = 0 */
+- __phy_write(phydev, 0x11, 0xb);
+- __phy_write(phydev, 0x12, 0x0);
+- __phy_write(phydev, 0x10, 0x9690);
+-
+- /* REG_EEE_st2TrKf1000 = 2 */
+- __phy_write(phydev, 0x11, 0x114f);
+- __phy_write(phydev, 0x12, 0x2);
+- __phy_write(phydev, 0x10, 0x969a);
+-
+- /* RegEEE_slv_wake_tr_timer_tar = 6, RegEEE_slv_remtx_timer_tar = 20 */
+- __phy_write(phydev, 0x11, 0x3028);
+- __phy_write(phydev, 0x12, 0x0);
+- __phy_write(phydev, 0x10, 0x969e);
+-
+- /* RegEEE_slv_wake_int_timer_tar = 8 */
+- __phy_write(phydev, 0x11, 0x5010);
+- __phy_write(phydev, 0x12, 0x0);
+- __phy_write(phydev, 0x10, 0x96a0);
+-
+- /* RegEEE_trfreeze_timer2 = 586 */
+- __phy_write(phydev, 0x11, 0x24a);
+- __phy_write(phydev, 0x12, 0x0);
+- __phy_write(phydev, 0x10, 0x96a8);
+-
+- /* RegEEE100Stg1_tar = 16 */
+- __phy_write(phydev, 0x11, 0x3210);
+- __phy_write(phydev, 0x12, 0x0);
+- __phy_write(phydev, 0x10, 0x96b8);
+-
+- /* REGEEE_wake_slv_tr_wait_dfesigdet_en = 0 */
+- __phy_write(phydev, 0x11, 0x1463);
+- __phy_write(phydev, 0x12, 0x0);
+- __phy_write(phydev, 0x10, 0x96ca);
+-
+- /* DfeTailEnableVgaThresh1000 = 27 */
+- __phy_write(phydev, 0x11, 0x36);
+- __phy_write(phydev, 0x12, 0x0);
+- __phy_write(phydev, 0x10, 0x8f80);
++ __mtk_tr_clr_bits(phydev, 0x2, 0xd, 0x8,
++ EEE1000_SELECT_SIGNAL_DETECTION_FROM_DFE);
++
++ __mtk_tr_modify(phydev, 0x2, 0xd, 0xd,
++ EEE1000_STAGE2_TR_KF_MASK,
++ FIELD_PREP(EEE1000_STAGE2_TR_KF_MASK, 0x2));
++
++ __mtk_tr_modify(phydev, 0x2, 0xd, 0xf,
++ SLAVE_WAKETR_TIMER_MASK | SLAVE_REMTX_TIMER_MASK,
++ FIELD_PREP(SLAVE_WAKETR_TIMER_MASK, 0x6) |
++ FIELD_PREP(SLAVE_REMTX_TIMER_MASK, 0x14));
++
++ __mtk_tr_modify(phydev, 0x2, 0xd, 0x10,
++ SLAVE_WAKEINT_TIMER_MASK,
++ FIELD_PREP(SLAVE_WAKEINT_TIMER_MASK, 0x8));
++
++ __mtk_tr_modify(phydev, 0x2, 0xd, 0x14,
++ TR_FREEZE_TIMER2_MASK,
++ FIELD_PREP(TR_FREEZE_TIMER2_MASK, 0x24a));
++
++ __mtk_tr_modify(phydev, 0x2, 0xd, 0x1c,
++ EEE100_LPSYNC_STAGE1_UPDATE_TIMER_MASK,
++ FIELD_PREP(EEE100_LPSYNC_STAGE1_UPDATE_TIMER_MASK,
++ 0x10));
++
++ __mtk_tr_clr_bits(phydev, 0x2, 0xd, 0x25,
++ WAKE_SLAVE_TR_WAIT_DFE_DETECTION_EN);
++
++ __mtk_tr_modify(phydev, 0x1, 0xf, 0x0,
++ DFE_TAIL_EANBLE_VGA_TRHESH_1000,
++ FIELD_PREP(DFE_TAIL_EANBLE_VGA_TRHESH_1000, 0x1b));
+ phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
+
+ phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_3);
+--- a/drivers/net/phy/mediatek/mtk-ge.c
++++ b/drivers/net/phy/mediatek/mtk-ge.c
+@@ -9,13 +9,35 @@
+ #define MTK_GPHY_ID_MT7530 0x03a29412
+ #define MTK_GPHY_ID_MT7531 0x03a29441
+
+-#define MTK_EXT_PAGE_ACCESS 0x1f
+-#define MTK_PHY_PAGE_STANDARD 0x0000
+-#define MTK_PHY_PAGE_EXTENDED 0x0001
+-#define MTK_PHY_PAGE_EXTENDED_2 0x0002
+-#define MTK_PHY_PAGE_EXTENDED_3 0x0003
+-#define MTK_PHY_PAGE_EXTENDED_2A30 0x2a30
+-#define MTK_PHY_PAGE_EXTENDED_52B5 0x52b5
++#define MTK_PHY_PAGE_EXTENDED_1 0x0001
++#define MTK_PHY_AUX_CTRL_AND_STATUS 0x14
++#define MTK_PHY_ENABLE_DOWNSHIFT BIT(4)
++
++#define MTK_PHY_PAGE_EXTENDED_2 0x0002
++#define MTK_PHY_PAGE_EXTENDED_3 0x0003
++#define MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG11 0x11
++
++#define MTK_PHY_PAGE_EXTENDED_2A30 0x2a30
++
++/* Registers on Token Ring debug nodes */
++/* ch_addr = 0x1, node_addr = 0xf, data_addr = 0x17 */
++#define SLAVE_DSP_READY_TIME_MASK GENMASK(22, 15)
++
++/* Registers on MDIO_MMD_VEND1 */
++#define MTK_PHY_GBE_MODE_TX_DELAY_SEL 0x13
++#define MTK_PHY_TEST_MODE_TX_DELAY_SEL 0x14
++#define MTK_TX_DELAY_PAIR_B_MASK GENMASK(10, 8)
++#define MTK_TX_DELAY_PAIR_D_MASK GENMASK(2, 0)
++
++#define MTK_PHY_MCC_CTRL_AND_TX_POWER_CTRL 0xa6
++#define MTK_MCC_NEARECHO_OFFSET_MASK GENMASK(15, 8)
++
++#define MTK_PHY_RXADC_CTRL_RG7 0xc6
++#define MTK_PHY_DA_AD_BUF_BIAS_LP_MASK GENMASK(9, 8)
++
++#define MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG123 0x123
++#define MTK_PHY_LPI_NORM_MSE_LO_THRESH100_MASK GENMASK(15, 8)
++#define MTK_PHY_LPI_NORM_MSE_HI_THRESH100_MASK GENMASK(7, 0)
+
+ struct mtk_gephy_priv {
+ unsigned long led_state;
+@@ -27,20 +49,29 @@ static void mtk_gephy_config_init(struct
+ phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0);
+
+ /* Enable HW auto downshift */
+- phy_modify_paged(phydev, MTK_PHY_PAGE_EXTENDED, 0x14, 0, BIT(4));
++ phy_modify_paged(phydev, MTK_PHY_PAGE_EXTENDED_1,
++ MTK_PHY_AUX_CTRL_AND_STATUS,
++ 0, MTK_PHY_ENABLE_DOWNSHIFT);
+
+ /* Increase SlvDPSready time */
+- phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
+- __phy_write(phydev, 0x10, 0xafae);
+- __phy_write(phydev, 0x12, 0x2f);
+- __phy_write(phydev, 0x10, 0x8fae);
+- phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
++ mtk_tr_modify(phydev, 0x1, 0xf, 0x17, SLAVE_DSP_READY_TIME_MASK,
++ FIELD_PREP(SLAVE_DSP_READY_TIME_MASK, 0x5e));
+
+ /* Adjust 100_mse_threshold */
+- phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x123, 0xffff);
+-
+- /* Disable mcc */
+- phy_write_mmd(phydev, MDIO_MMD_VEND1, 0xa6, 0x300);
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1,
++ MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG123,
++ MTK_PHY_LPI_NORM_MSE_LO_THRESH100_MASK |
++ MTK_PHY_LPI_NORM_MSE_HI_THRESH100_MASK,
++ FIELD_PREP(MTK_PHY_LPI_NORM_MSE_LO_THRESH100_MASK,
++ 0xff) |
++ FIELD_PREP(MTK_PHY_LPI_NORM_MSE_HI_THRESH100_MASK,
++ 0xff));
++
++ /* If echo time is narrower than 0x3, it will be regarded as noise */
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1,
++ MTK_PHY_MCC_CTRL_AND_TX_POWER_CTRL,
++ MTK_MCC_NEARECHO_OFFSET_MASK,
++ FIELD_PREP(MTK_MCC_NEARECHO_OFFSET_MASK, 0x3));
+ }
+
+ static int mt7530_phy_config_init(struct phy_device *phydev)
+@@ -48,7 +79,8 @@ static int mt7530_phy_config_init(struct
+ mtk_gephy_config_init(phydev);
+
+ /* Increase post_update_timer */
+- phy_write_paged(phydev, MTK_PHY_PAGE_EXTENDED_3, 0x11, 0x4b);
++ phy_write_paged(phydev, MTK_PHY_PAGE_EXTENDED_3,
++ MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG11, 0x4b);
+
+ return 0;
+ }
+@@ -89,11 +121,19 @@ static int mt7531_phy_config_init(struct
+
+ /* PHY link down power saving enable */
+ phy_set_bits(phydev, 0x17, BIT(4));
+- phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, 0xc6, 0x300);
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG7,
++ MTK_PHY_DA_AD_BUF_BIAS_LP_MASK,
++ FIELD_PREP(MTK_PHY_DA_AD_BUF_BIAS_LP_MASK, 0x3));
+
+ /* Set TX Pair delay selection */
+- phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x13, 0x404);
+- phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x14, 0x404);
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_GBE_MODE_TX_DELAY_SEL,
++ MTK_TX_DELAY_PAIR_B_MASK | MTK_TX_DELAY_PAIR_D_MASK,
++ FIELD_PREP(MTK_TX_DELAY_PAIR_B_MASK, 0x4) |
++ FIELD_PREP(MTK_TX_DELAY_PAIR_D_MASK, 0x4));
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TEST_MODE_TX_DELAY_SEL,
++ MTK_TX_DELAY_PAIR_B_MASK | MTK_TX_DELAY_PAIR_D_MASK,
++ FIELD_PREP(MTK_TX_DELAY_PAIR_B_MASK, 0x4) |
++ FIELD_PREP(MTK_TX_DELAY_PAIR_D_MASK, 0x4));
+
+ /* LED Config*/
+ mt7530_led_config_of(phydev);
+--- a/drivers/net/phy/mediatek/mtk-phy-lib.c
++++ b/drivers/net/phy/mediatek/mtk-phy-lib.c
+@@ -6,6 +6,97 @@
+
+ #include "mtk.h"
+
++/* Difference between functions with mtk_tr* and __mtk_tr* prefixes is
++ * mtk_tr* functions: wrapped by page switching operations
++ * __mtk_tr* functions: no page switching operations
++ */
++
++static void __mtk_tr_access(struct phy_device *phydev, bool read, u8 ch_addr,
++ u8 node_addr, u8 data_addr)
++{
++ u16 tr_cmd = BIT(15); /* bit 14 & 0 are reserved */
++
++ if (read)
++ tr_cmd |= BIT(13);
++
++ tr_cmd |= (((ch_addr & 0x3) << 11) |
++ ((node_addr & 0xf) << 7) |
++ ((data_addr & 0x3f) << 1));
++ dev_dbg(&phydev->mdio.dev, "tr_cmd: 0x%x\n", tr_cmd);
++ __phy_write(phydev, 0x10, tr_cmd);
++}
++
++static void __mtk_tr_read(struct phy_device *phydev, u8 ch_addr, u8 node_addr,
++ u8 data_addr, u16 *tr_high, u16 *tr_low)
++{
++ __mtk_tr_access(phydev, true, ch_addr, node_addr, data_addr);
++ *tr_low = __phy_read(phydev, 0x11);
++ *tr_high = __phy_read(phydev, 0x12);
++ dev_dbg(&phydev->mdio.dev, "tr_high read: 0x%x, tr_low read: 0x%x\n",
++ *tr_high, *tr_low);
++}
++
++u32 mtk_tr_read(struct phy_device *phydev, u8 ch_addr, u8 node_addr,
++ u8 data_addr)
++{
++ u16 tr_high;
++ u16 tr_low;
++
++ phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
++ __mtk_tr_read(phydev, ch_addr, node_addr, data_addr, &tr_high, &tr_low);
++ phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
++
++ return (tr_high << 16) | tr_low;
++}
++EXPORT_SYMBOL_GPL(mtk_tr_read);
++
++static void __mtk_tr_write(struct phy_device *phydev, u8 ch_addr, u8 node_addr,
++ u8 data_addr, u32 tr_data)
++{
++ __phy_write(phydev, 0x11, tr_data & 0xffff);
++ __phy_write(phydev, 0x12, tr_data >> 16);
++ dev_dbg(&phydev->mdio.dev, "tr_high write: 0x%x, tr_low write: 0x%x\n",
++ tr_data >> 16, tr_data & 0xffff);
++ __mtk_tr_access(phydev, false, ch_addr, node_addr, data_addr);
++}
++
++void __mtk_tr_modify(struct phy_device *phydev, u8 ch_addr, u8 node_addr,
++ u8 data_addr, u32 mask, u32 set)
++{
++ u32 tr_data;
++ u16 tr_high;
++ u16 tr_low;
++
++ __mtk_tr_read(phydev, ch_addr, node_addr, data_addr, &tr_high, &tr_low);
++ tr_data = (tr_high << 16) | tr_low;
++ tr_data = (tr_data & ~mask) | set;
++ __mtk_tr_write(phydev, ch_addr, node_addr, data_addr, tr_data);
++}
++EXPORT_SYMBOL_GPL(__mtk_tr_modify);
++
++void mtk_tr_modify(struct phy_device *phydev, u8 ch_addr, u8 node_addr,
++ u8 data_addr, u32 mask, u32 set)
++{
++ phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
++ __mtk_tr_modify(phydev, ch_addr, node_addr, data_addr, mask, set);
++ phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
++}
++EXPORT_SYMBOL_GPL(mtk_tr_modify);
++
++void __mtk_tr_set_bits(struct phy_device *phydev, u8 ch_addr, u8 node_addr,
++ u8 data_addr, u32 set)
++{
++ __mtk_tr_modify(phydev, ch_addr, node_addr, data_addr, 0, set);
++}
++EXPORT_SYMBOL_GPL(__mtk_tr_set_bits);
++
++void __mtk_tr_clr_bits(struct phy_device *phydev, u8 ch_addr, u8 node_addr,
++ u8 data_addr, u32 clr)
++{
++ __mtk_tr_modify(phydev, ch_addr, node_addr, data_addr, clr, 0);
++}
++EXPORT_SYMBOL_GPL(__mtk_tr_clr_bits);
++
+ int mtk_phy_read_page(struct phy_device *phydev)
+ {
+ return __phy_read(phydev, MTK_EXT_PAGE_ACCESS);
+--- a/drivers/net/phy/mediatek/mtk.h
++++ b/drivers/net/phy/mediatek/mtk.h
+@@ -9,6 +9,8 @@
+ #define _MTK_EPHY_H_
+
+ #define MTK_EXT_PAGE_ACCESS 0x1f
++#define MTK_PHY_PAGE_STANDARD 0x0000
++#define MTK_PHY_PAGE_EXTENDED_52B5 0x52b5
+
+ /* Registers on MDIO_MMD_VEND2 */
+ #define MTK_PHY_LED0_ON_CTRL 0x24
+@@ -62,6 +64,17 @@
+ #define MTK_PHY_LED_STATE_FORCE_BLINK 1
+ #define MTK_PHY_LED_STATE_NETDEV 2
+
++u32 mtk_tr_read(struct phy_device *phydev, u8 ch_addr, u8 node_addr,
++ u8 data_addr);
++void __mtk_tr_modify(struct phy_device *phydev, u8 ch_addr, u8 node_addr,
++ u8 data_addr, u32 mask, u32 set);
++void mtk_tr_modify(struct phy_device *phydev, u8 ch_addr, u8 node_addr,
++ u8 data_addr, u32 mask, u32 set);
++void __mtk_tr_set_bits(struct phy_device *phydev, u8 ch_addr, u8 node_addr,
++ u8 data_addr, u32 set);
++void __mtk_tr_clr_bits(struct phy_device *phydev, u8 ch_addr, u8 node_addr,
++ u8 data_addr, u32 clr);
++
+ int mtk_phy_read_page(struct phy_device *phydev);
+ int mtk_phy_write_page(struct phy_device *phydev, int page);
+
diff --git a/target/linux/mediatek/patches-6.6/733-10-net-phy-mediatek-Extend-1G-TX-RX-link-pulse-time.patch b/target/linux/mediatek/patches-6.6/733-10-net-phy-mediatek-Extend-1G-TX-RX-link-pulse-time.patch
new file mode 100644
index 0000000000..2fc1adb5ec
--- /dev/null
+++ b/target/linux/mediatek/patches-6.6/733-10-net-phy-mediatek-Extend-1G-TX-RX-link-pulse-time.patch
@@ -0,0 +1,219 @@
+From 3c05195fc2c232cd853fc8cebf55310c4605111d Mon Sep 17 00:00:00 2001
+From: "SkyLake.Huang" <skylake.huang@mediatek.com>
+Date: Mon, 1 Jul 2024 18:54:14 +0800
+Subject: [PATCH 10/13] net: phy: mediatek: Extend 1G TX/RX link pulse time
+
+We observe that some 10G devices' (mostly Marvell's chips inside) 1G
+training time violates specification, which may last 2230ms and affect
+later TX/RX link pulse time. This will invalidate MediaTek series
+gigabit Ethernet PHYs' hardware auto downshift mechanism.
+
+Without this patch, if someone is trying to use "4-wire" cable to
+connect above devices, MediaTek' gigabit Ethernet PHYs may fail
+to downshift to 100Mbps. (If partner 10G devices' downshift mechanism
+stops at 1G)
+
+This patch extends our 1G TX/RX link pulse time so that we can still
+link up with those 10G devices.
+
+Tested device:
+- Netgear GS110EMX's 10G port (Marvell 88X3340P)
+- QNAP QSW-M408-4C
+
+Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
+---
+ drivers/net/phy/mediatek/mtk-ge-soc.c | 2 +
+ drivers/net/phy/mediatek/mtk-ge.c | 5 +-
+ drivers/net/phy/mediatek/mtk-phy-lib.c | 92 ++++++++++++++++++++++++++
+ drivers/net/phy/mediatek/mtk.h | 21 ++++++
+ 4 files changed, 116 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/phy/mediatek/mtk-ge-soc.c
++++ b/drivers/net/phy/mediatek/mtk-ge-soc.c
+@@ -1396,6 +1396,7 @@ static struct phy_driver mtk_socphy_driv
+ PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7981),
+ .name = "MediaTek MT7981 PHY",
+ .config_init = mt798x_phy_config_init,
++ .read_status = mtk_gphy_cl22_read_status,
+ .config_intr = genphy_no_config_intr,
+ .handle_interrupt = genphy_handle_interrupt_no_ack,
+ .probe = mt7981_phy_probe,
+@@ -1413,6 +1414,7 @@ static struct phy_driver mtk_socphy_driv
+ PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7988),
+ .name = "MediaTek MT7988 PHY",
+ .config_init = mt798x_phy_config_init,
++ .read_status = mtk_gphy_cl22_read_status,
+ .config_intr = genphy_no_config_intr,
+ .handle_interrupt = genphy_handle_interrupt_no_ack,
+ .probe = mt7988_phy_probe,
+--- a/drivers/net/phy/mediatek/mtk-ge.c
++++ b/drivers/net/phy/mediatek/mtk-ge.c
+@@ -9,10 +9,6 @@
+ #define MTK_GPHY_ID_MT7530 0x03a29412
+ #define MTK_GPHY_ID_MT7531 0x03a29441
+
+-#define MTK_PHY_PAGE_EXTENDED_1 0x0001
+-#define MTK_PHY_AUX_CTRL_AND_STATUS 0x14
+-#define MTK_PHY_ENABLE_DOWNSHIFT BIT(4)
+-
+ #define MTK_PHY_PAGE_EXTENDED_2 0x0002
+ #define MTK_PHY_PAGE_EXTENDED_3 0x0003
+ #define MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG11 0x11
+@@ -251,6 +247,7 @@ static struct phy_driver mtk_gephy_drive
+ .name = "MediaTek MT7531 PHY",
+ .probe = mt7531_phy_probe,
+ .config_init = mt7531_phy_config_init,
++ .read_status = mtk_gphy_cl22_read_status,
+ /* Interrupts are handled by the switch, not the PHY
+ * itself.
+ */
+--- a/drivers/net/phy/mediatek/mtk-phy-lib.c
++++ b/drivers/net/phy/mediatek/mtk-phy-lib.c
+@@ -109,6 +109,108 @@ int mtk_phy_write_page(struct phy_device
+ }
+ EXPORT_SYMBOL_GPL(mtk_phy_write_page);
+
++/* This function deals with the case that 1G AN starts but isn't completed. We
++ * set AN_NEW_LP_CNT_LIMIT with different values time after time to let our
++ * 1G->100Mbps hardware automatic downshift to fit more partner devices.
++ */
++static int extend_an_new_lp_cnt_limit(struct phy_device *phydev)
++{
++ int ret;
++ u32 reg_val;
++ int timeout;
++
++ /* According to table 28-9 & Figure 28-18 in IEEE 802.3,
++ * link_fail_inhibit_timer of 10/100/1000 Mbps devices ranges from 750
++ * to "1000ms". Once MTK_PHY_FINAL_SPEED_1000 is set, it means that we
++ * enter "FLP LINK GOOD CHECK" state, link_fail_inhibit_timer starts and
++ * this PHY's 1G training starts. If 1G training never starts, we do
++ * nothing but leave.
++ */
++ timeout = read_poll_timeout(ret = phy_read_mmd, reg_val,
++ (ret < 0) ||
++ reg_val & MTK_PHY_FINAL_SPEED_1000,
++ 10000, 500000, false, phydev,
++ MDIO_MMD_VEND1, MTK_PHY_LINK_STATUS_MISC);
++ phydev_dbg(phydev, "%s: Training Indicator: 0x%x\n", __func__, reg_val);
++ if (ret < 0)
++ return ret;
++
++ if (!timeout) {
++ /* Once we found MTK_PHY_FINAL_SPEED_1000 is set, no matter 1G
++ * AN is completed or not, we'll set AN_NEW_LP_CNT_LIMIT again
++ * and again.
++ */
++ mtk_tr_modify(phydev, 0x0, 0xf, 0x3c, AN_NEW_LP_CNT_LIMIT_MASK,
++ FIELD_PREP(AN_NEW_LP_CNT_LIMIT_MASK, 0xf));
++ msleep(1500);
++
++ /* Read phy status again to make sure the following step won't
++ * affect normal devices.
++ */
++ ret = genphy_read_status(phydev);
++ if (ret)
++ return ret;
++ if (phydev->link)
++ return 0;
++
++ timeout = read_poll_timeout(mtk_tr_read, reg_val,
++ (reg_val & AN_STATE_MASK) !=
++ (AN_STATE_TX_DISABLE <<
++ AN_STATE_SHIFT),
++ 10000, 1000000, false, phydev,
++ 0x0, 0xf, 0x2);
++ phydev_dbg(phydev, "%s: AN State: 0x%x\n", __func__, reg_val);
++ if (!timeout) {
++ msleep(625);
++ mtk_tr_modify(phydev, 0x0, 0xf, 0x3c,
++ AN_NEW_LP_CNT_LIMIT_MASK,
++ FIELD_PREP(AN_NEW_LP_CNT_LIMIT_MASK,
++ 0x8));
++ msleep(500);
++ mtk_tr_modify(phydev, 0x0, 0xf, 0x3c,
++ AN_NEW_LP_CNT_LIMIT_MASK,
++ FIELD_PREP(AN_NEW_LP_CNT_LIMIT_MASK,
++ 0xf));
++ }
++ }
++
++ return 0;
++}
++
++int mtk_gphy_cl22_read_status(struct phy_device *phydev)
++{
++ int ret;
++
++ ret = genphy_read_status(phydev);
++ if (ret)
++ return ret;
++
++ if (phydev->autoneg == AUTONEG_ENABLE && !phydev->autoneg_complete) {
++ ret = phy_read_paged(phydev, MTK_PHY_PAGE_EXTENDED_1,
++ MTK_PHY_AUX_CTRL_AND_STATUS);
++ if (ret < 0)
++ return ret;
++
++ /* Once LP_DETECTED is set, it means that"ability_match" in
++ * IEEE 802.3 Figure 28-18 is set. This happens after we plug in
++ * cable. Also, LP_DETECTED will be cleared after AN complete.
++ */
++ if (!FIELD_GET(MTK_PHY_LP_DETECTED_MASK, ret))
++ return 0;
++
++ ret = phy_read(phydev, MII_CTRL1000);
++ if (ret & (ADVERTISE_1000FULL | ADVERTISE_1000HALF)) {
++ ret = extend_an_new_lp_cnt_limit(phydev);
++ phydev_dbg(phydev, "%s: counter limit ret: %d\n", __func__, ret);
++ if (ret < 0)
++ return ret;
++ }
++ }
++
++ return 0;
++}
++EXPORT_SYMBOL_GPL(mtk_gphy_cl22_read_status);
++
+ int mtk_phy_led_hw_is_supported(struct phy_device *phydev, u8 index,
+ unsigned long rules,
+ unsigned long supported_triggers)
+--- a/drivers/net/phy/mediatek/mtk.h
++++ b/drivers/net/phy/mediatek/mtk.h
+@@ -10,8 +10,28 @@
+
+ #define MTK_EXT_PAGE_ACCESS 0x1f
+ #define MTK_PHY_PAGE_STANDARD 0x0000
++#define MTK_PHY_PAGE_EXTENDED_1 0x0001
++#define MTK_PHY_AUX_CTRL_AND_STATUS 0x14
++/* suprv_media_select_RefClk */
++#define MTK_PHY_LP_DETECTED_MASK GENMASK(7, 6)
++#define MTK_PHY_ENABLE_DOWNSHIFT BIT(4)
++
+ #define MTK_PHY_PAGE_EXTENDED_52B5 0x52b5
+
++/* Registers on Token Ring debug nodes */
++/* ch_addr = 0x0, node_addr = 0xf, data_addr = 0x2 */
++#define AN_STATE_MASK GENMASK(22, 19)
++#define AN_STATE_SHIFT 19
++#define AN_STATE_TX_DISABLE 1
++
++/* ch_addr = 0x0, node_addr = 0xf, data_addr = 0x3c */
++#define AN_NEW_LP_CNT_LIMIT_MASK GENMASK(23, 20)
++#define AUTO_NP_10XEN BIT(6)
++
++/* Registers on MDIO_MMD_VEND1 */
++#define MTK_PHY_LINK_STATUS_MISC (0xa2)
++#define MTK_PHY_FINAL_SPEED_1000 BIT(3)
++
+ /* Registers on MDIO_MMD_VEND2 */
+ #define MTK_PHY_LED0_ON_CTRL 0x24
+ #define MTK_PHY_LED1_ON_CTRL 0x26
+@@ -78,6 +98,7 @@ void __mtk_tr_clr_bits(struct phy_device
+ int mtk_phy_read_page(struct phy_device *phydev);
+ int mtk_phy_write_page(struct phy_device *phydev, int page);
+
++int mtk_gphy_cl22_read_status(struct phy_device *phydev);
+ int mtk_phy_led_hw_is_supported(struct phy_device *phydev, u8 index,
+ unsigned long rules,
+ unsigned long supported_triggers);
diff --git a/target/linux/mediatek/patches-6.6/733-11-net-phy-add-driver-for-built-in-2.5G-ethernet-PHY-on.patch b/target/linux/mediatek/patches-6.6/733-11-net-phy-add-driver-for-built-in-2.5G-ethernet-PHY-on.patch
new file mode 100644
index 0000000000..a9595157ff
--- /dev/null
+++ b/target/linux/mediatek/patches-6.6/733-11-net-phy-add-driver-for-built-in-2.5G-ethernet-PHY-on.patch
@@ -0,0 +1,477 @@
+From 69ca89165e39e6b6f4c79e6b4c03559e0fac7051 Mon Sep 17 00:00:00 2001
+From: "SkyLake.Huang" <skylake.huang@mediatek.com>
+Date: Mon, 1 Jul 2024 18:54:15 +0800
+Subject: [PATCH 11/13] net: phy: add driver for built-in 2.5G ethernet PHY on
+ MT7988
+
+Add support for internal 2.5Gphy on MT7988. This driver will load
+necessary firmware, add appropriate time delay and figure out LED.
+Also, certain control registers will be set to fix link-up issues.
+
+Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
+---
+ drivers/net/phy/mediatek/Kconfig | 11 +
+ drivers/net/phy/mediatek/Makefile | 1 +
+ drivers/net/phy/mediatek/mtk-2p5ge.c | 432 +++++++++++++++++++++++++++
+ 4 files changed, 445 insertions(+)
+ create mode 100644 drivers/net/phy/mediatek/mtk-2p5ge.c
+
+--- a/drivers/net/phy/mediatek/Kconfig
++++ b/drivers/net/phy/mediatek/Kconfig
+@@ -25,3 +25,14 @@ config MEDIATEK_GE_SOC_PHY
+ the MT7981 and MT7988 SoCs. These PHYs need calibration data
+ present in the SoCs efuse and will dynamically calibrate VCM
+ (common-mode voltage) during startup.
++
++config MEDIATEK_2P5GE_PHY
++ tristate "MediaTek 2.5Gb Ethernet PHYs"
++ depends on (ARM64 && ARCH_MEDIATEK) || COMPILE_TEST
++ select MTK_NET_PHYLIB
++ help
++ Supports MediaTek SoC built-in 2.5Gb Ethernet PHYs.
++
++ This will load necessary firmware and add appropriate time delay.
++ Accelerate this procedure through internal pbus instead of MDIO
++ bus. Certain link-up issues will also be fixed here.
+--- a/drivers/net/phy/mediatek/Makefile
++++ b/drivers/net/phy/mediatek/Makefile
+@@ -2,3 +2,4 @@
+ obj-$(CONFIG_MTK_NET_PHYLIB) += mtk-phy-lib.o
+ obj-$(CONFIG_MEDIATEK_GE_PHY) += mtk-ge.o
+ obj-$(CONFIG_MEDIATEK_GE_SOC_PHY) += mtk-ge-soc.o
++obj-$(CONFIG_MEDIATEK_2P5GE_PHY) += mtk-2p5ge.o
+--- /dev/null
++++ b/drivers/net/phy/mediatek/mtk-2p5ge.c
+@@ -0,0 +1,432 @@
++// SPDX-License-Identifier: GPL-2.0+
++#include <linux/bitfield.h>
++#include <linux/firmware.h>
++#include <linux/module.h>
++#include <linux/nvmem-consumer.h>
++#include <linux/of_address.h>
++#include <linux/of_platform.h>
++#include <linux/pinctrl/consumer.h>
++#include <linux/phy.h>
++#include <linux/pm_domain.h>
++#include <linux/pm_runtime.h>
++
++#include "mtk.h"
++
++#define MTK_2P5GPHY_ID_MT7988 (0x00339c11)
++
++#define MT7988_2P5GE_PMB_FW "mediatek/mt7988/i2p5ge-phy-pmb.bin"
++#define MT7988_2P5GE_PMB_FW_SIZE (0x20000)
++#define MT7988_2P5GE_PMB_FW_BASE (0x0f100000)
++#define MT7988_2P5GE_PMB_FW_LEN (0x20000)
++#define MT7988_2P5GE_MD32_EN_CFG_BASE (0x0f0f0018)
++#define MT7988_2P5GE_MD32_EN_CFG_LEN (0x20)
++#define MD32_EN BIT(0)
++
++#define BASE100T_STATUS_EXTEND (0x10)
++#define BASE1000T_STATUS_EXTEND (0x11)
++#define EXTEND_CTRL_AND_STATUS (0x16)
++
++#define PHY_AUX_CTRL_STATUS (0x1d)
++#define PHY_AUX_DPX_MASK GENMASK(5, 5)
++#define PHY_AUX_SPEED_MASK GENMASK(4, 2)
++
++#define MTK_PHY_LPI_PCS_DSP_CTRL (0x121)
++#define MTK_PHY_LPI_SIG_EN_LO_THRESH100_MASK GENMASK(12, 8)
++
++/* Registers on Token Ring debug nodes */
++/* ch_addr = 0x0, node_addr = 0xf, data_addr = 0x3c */
++#define AUTO_NP_10XEN BIT(6)
++
++struct mtk_i2p5ge_phy_priv {
++ bool fw_loaded;
++ unsigned long led_state;
++};
++
++enum {
++ PHY_AUX_SPD_10 = 0,
++ PHY_AUX_SPD_100,
++ PHY_AUX_SPD_1000,
++ PHY_AUX_SPD_2500,
++};
++
++static int mt798x_2p5ge_phy_load_fw(struct phy_device *phydev)
++{
++ struct mtk_i2p5ge_phy_priv *priv = phydev->priv;
++ void __iomem *md32_en_cfg_base, *pmb_addr;
++ struct device *dev = &phydev->mdio.dev;
++ const struct firmware *fw;
++ int ret, i;
++ u16 reg;
++
++ if (priv->fw_loaded)
++ return 0;
++
++ pmb_addr = ioremap(MT7988_2P5GE_PMB_FW_BASE, MT7988_2P5GE_PMB_FW_LEN);
++ if (!pmb_addr)
++ return -ENOMEM;
++ md32_en_cfg_base = ioremap(MT7988_2P5GE_MD32_EN_CFG_BASE,
++ MT7988_2P5GE_MD32_EN_CFG_LEN);
++ if (!md32_en_cfg_base) {
++ ret = -ENOMEM;
++ goto free_pmb;
++ }
++
++ ret = request_firmware(&fw, MT7988_2P5GE_PMB_FW, dev);
++ if (ret) {
++ dev_err(dev, "failed to load firmware: %s, ret: %d\n",
++ MT7988_2P5GE_PMB_FW, ret);
++ goto free;
++ }
++
++ if (fw->size != MT7988_2P5GE_PMB_FW_SIZE) {
++ dev_err(dev, "Firmware size 0x%zx != 0x%x\n",
++ fw->size, MT7988_2P5GE_PMB_FW_SIZE);
++ ret = -EINVAL;
++ goto release_fw;
++ }
++
++ reg = readw(md32_en_cfg_base);
++ if (reg & MD32_EN) {
++ phy_set_bits(phydev, MII_BMCR, BMCR_RESET);
++ usleep_range(10000, 11000);
++ }
++ phy_set_bits(phydev, MII_BMCR, BMCR_PDOWN);
++
++ /* Write magic number to safely stall MCU */
++ phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x800e, 0x1100);
++ phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x800f, 0x00df);
++
++ for (i = 0; i < MT7988_2P5GE_PMB_FW_SIZE - 1; i += 4)
++ writel(*((uint32_t *)(fw->data + i)), pmb_addr + i);
++ dev_info(dev, "Firmware date code: %x/%x/%x, version: %x.%x\n",
++ be16_to_cpu(*((__be16 *)(fw->data +
++ MT7988_2P5GE_PMB_FW_SIZE - 8))),
++ *(fw->data + MT7988_2P5GE_PMB_FW_SIZE - 6),
++ *(fw->data + MT7988_2P5GE_PMB_FW_SIZE - 5),
++ *(fw->data + MT7988_2P5GE_PMB_FW_SIZE - 2),
++ *(fw->data + MT7988_2P5GE_PMB_FW_SIZE - 1));
++
++ writew(reg & ~MD32_EN, md32_en_cfg_base);
++ writew(reg | MD32_EN, md32_en_cfg_base);
++ phy_set_bits(phydev, MII_BMCR, BMCR_RESET);
++ /* We need a delay here to stabilize initialization of MCU */
++ usleep_range(7000, 8000);
++ dev_info(dev, "Firmware loading/trigger ok.\n");
++
++ priv->fw_loaded = true;
++
++release_fw:
++ release_firmware(fw);
++free:
++ iounmap(md32_en_cfg_base);
++free_pmb:
++ iounmap(pmb_addr);
++
++ return ret;
++}
++
++static int mt798x_2p5ge_phy_config_init(struct phy_device *phydev)
++{
++ struct pinctrl *pinctrl;
++ int ret;
++
++ /* Check if PHY interface type is compatible */
++ if (phydev->interface != PHY_INTERFACE_MODE_INTERNAL)
++ return -ENODEV;
++
++ ret = mt798x_2p5ge_phy_load_fw(phydev);
++ if (ret < 0)
++ return ret;
++
++ /* Setup LED */
++ phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED0_ON_CTRL,
++ MTK_PHY_LED_ON_POLARITY | MTK_PHY_LED_ON_LINK10 |
++ MTK_PHY_LED_ON_LINK100 | MTK_PHY_LED_ON_LINK1000 |
++ MTK_PHY_LED_ON_LINK2500);
++ phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED1_ON_CTRL,
++ MTK_PHY_LED_ON_FDX | MTK_PHY_LED_ON_HDX);
++
++ /* Switch pinctrl after setting polarity to avoid bogus blinking */
++ pinctrl = devm_pinctrl_get_select(&phydev->mdio.dev, "i2p5gbe-led");
++ if (IS_ERR(pinctrl))
++ dev_err(&phydev->mdio.dev, "Fail to set LED pins!\n");
++
++ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LPI_PCS_DSP_CTRL,
++ MTK_PHY_LPI_SIG_EN_LO_THRESH100_MASK, 0);
++
++ /* Enable 16-bit next page exchange bit if 1000-BT isn't advertising */
++ mtk_tr_modify(phydev, 0x0, 0xf, 0x3c, AUTO_NP_10XEN,
++ FIELD_PREP(AUTO_NP_10XEN, 0x1));
++
++ /* Enable HW auto downshift */
++ phy_modify_paged(phydev, MTK_PHY_PAGE_EXTENDED_1,
++ MTK_PHY_AUX_CTRL_AND_STATUS,
++ 0, MTK_PHY_ENABLE_DOWNSHIFT);
++
++ return 0;
++}
++
++static int mt798x_2p5ge_phy_config_aneg(struct phy_device *phydev)
++{
++ bool changed = false;
++ u32 adv;
++ int ret;
++
++ /* In fact, if we disable autoneg, we can't link up correctly:
++ * 2.5G/1G: Need AN to exchange master/slave information.
++ * 100M/10M: Without AN, link starts at half duplex (According to
++ * IEEE 802.3-2018), which this phy doesn't support.
++ */
++ if (phydev->autoneg == AUTONEG_DISABLE)
++ return -EOPNOTSUPP;
++
++ ret = genphy_c45_an_config_aneg(phydev);
++ if (ret < 0)
++ return ret;
++ if (ret > 0)
++ changed = true;
++
++ /* Clause 45 doesn't define 1000BaseT support. Use Clause 22 instead in
++ * our design.
++ */
++ adv = linkmode_adv_to_mii_ctrl1000_t(phydev->advertising);
++ ret = phy_modify_changed(phydev, MII_CTRL1000, ADVERTISE_1000FULL, adv);
++ if (ret < 0)
++ return ret;
++ if (ret > 0)
++ changed = true;
++
++ return genphy_c45_check_and_restart_aneg(phydev, changed);
++}
++
++static int mt798x_2p5ge_phy_get_features(struct phy_device *phydev)
++{
++ int ret;
++
++ ret = genphy_c45_pma_read_abilities(phydev);
++ if (ret)
++ return ret;
++
++ /* This phy can't handle collision, and neither can (XFI)MAC it's
++ * connected to. Although it can do HDX handshake, it doesn't support
++ * CSMA/CD that HDX requires.
++ */
++ linkmode_clear_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT,
++ phydev->supported);
++
++ return 0;
++}
++
++static int mt798x_2p5ge_phy_read_status(struct phy_device *phydev)
++{
++ int ret;
++
++ /* When MDIO_STAT1_LSTATUS is raised genphy_c45_read_link(), this phy
++ * actually hasn't finished AN. So use CL22's link update function
++ * instead.
++ */
++ ret = genphy_update_link(phydev);
++ if (ret)
++ return ret;
++
++ phydev->speed = SPEED_UNKNOWN;
++ phydev->duplex = DUPLEX_UNKNOWN;
++ phydev->pause = 0;
++ phydev->asym_pause = 0;
++
++ /* We'll read link speed through vendor specific registers down below.
++ * So remove phy_resolve_aneg_linkmode (AN on) & genphy_c45_read_pma
++ * (AN off).
++ */
++ if (phydev->autoneg == AUTONEG_ENABLE && phydev->autoneg_complete) {
++ ret = genphy_c45_read_lpa(phydev);
++ if (ret < 0)
++ return ret;
++
++ /* Clause 45 doesn't define 1000BaseT support. Read the link
++ * partner's 1G advertisement via Clause 22.
++ */
++ ret = phy_read(phydev, MII_STAT1000);
++ if (ret < 0)
++ return ret;
++ mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, ret);
++ } else if (phydev->autoneg == AUTONEG_DISABLE) {
++ linkmode_zero(phydev->lp_advertising);
++ }
++
++ if (phydev->link) {
++ ret = phy_read(phydev, PHY_AUX_CTRL_STATUS);
++ if (ret < 0)
++ return ret;
++
++ switch (FIELD_GET(PHY_AUX_SPEED_MASK, ret)) {
++ case PHY_AUX_SPD_10:
++ phydev->speed = SPEED_10;
++ break;
++ case PHY_AUX_SPD_100:
++ phydev->speed = SPEED_100;
++ break;
++ case PHY_AUX_SPD_1000:
++ phydev->speed = SPEED_1000;
++ break;
++ case PHY_AUX_SPD_2500:
++ phydev->speed = SPEED_2500;
++ break;
++ }
++
++ phydev->duplex = DUPLEX_FULL;
++ /* FIXME:
++ * The current firmware always enables rate adaptation mode.
++ */
++ phydev->rate_matching = RATE_MATCH_PAUSE;
++ }
++
++ return 0;
++}
++
++static int mt798x_2p5ge_phy_get_rate_matching(struct phy_device *phydev,
++ phy_interface_t iface)
++{
++ return RATE_MATCH_PAUSE;
++}
++
++static const unsigned long supported_triggers =
++ BIT(TRIGGER_NETDEV_FULL_DUPLEX) |
++ BIT(TRIGGER_NETDEV_LINK) |
++ BIT(TRIGGER_NETDEV_LINK_10) |
++ BIT(TRIGGER_NETDEV_LINK_100) |
++ BIT(TRIGGER_NETDEV_LINK_1000) |
++ BIT(TRIGGER_NETDEV_LINK_2500) |
++ BIT(TRIGGER_NETDEV_RX) |
++ BIT(TRIGGER_NETDEV_TX);
++
++static int mt798x_2p5ge_phy_led_blink_set(struct phy_device *phydev, u8 index,
++ unsigned long *delay_on,
++ unsigned long *delay_off)
++{
++ struct mtk_i2p5ge_phy_priv *priv = phydev->priv;
++ bool blinking = false;
++ int err = 0;
++
++ err = mtk_phy_led_num_dly_cfg(index, delay_on, delay_off, &blinking);
++ if (err < 0)
++ return err;
++
++ err = mtk_phy_hw_led_blink_set(phydev, index, &priv->led_state,
++ blinking);
++ if (err)
++ return err;
++
++ return mtk_phy_hw_led_on_set(phydev, index, &priv->led_state,
++ MTK_2P5GPHY_LED_ON_MASK, false);
++}
++
++static int mt798x_2p5ge_phy_led_brightness_set(struct phy_device *phydev,
++ u8 index,
++ enum led_brightness value)
++{
++ struct mtk_i2p5ge_phy_priv *priv = phydev->priv;
++ int err;
++
++ err = mtk_phy_hw_led_blink_set(phydev, index, &priv->led_state, false);
++ if (err)
++ return err;
++
++ return mtk_phy_hw_led_on_set(phydev, index, &priv->led_state,
++ MTK_2P5GPHY_LED_ON_MASK,
++ (value != LED_OFF));
++}
++
++static int mt798x_2p5ge_phy_led_hw_is_supported(struct phy_device *phydev,
++ u8 index, unsigned long rules)
++{
++ return mtk_phy_led_hw_is_supported(phydev, index, rules,
++ supported_triggers);
++}
++
++static int mt798x_2p5ge_phy_led_hw_control_get(struct phy_device *phydev,
++ u8 index, unsigned long *rules)
++{
++ struct mtk_i2p5ge_phy_priv *priv = phydev->priv;
++
++ return mtk_phy_led_hw_ctrl_get(phydev, index, rules, &priv->led_state,
++ MTK_2P5GPHY_LED_ON_SET,
++ MTK_2P5GPHY_LED_RX_BLINK_SET,
++ MTK_2P5GPHY_LED_TX_BLINK_SET);
++};
++
++static int mt798x_2p5ge_phy_led_hw_control_set(struct phy_device *phydev,
++ u8 index, unsigned long rules)
++{
++ struct mtk_i2p5ge_phy_priv *priv = phydev->priv;
++
++ return mtk_phy_led_hw_ctrl_set(phydev, index, rules, &priv->led_state,
++ MTK_2P5GPHY_LED_ON_SET,
++ MTK_2P5GPHY_LED_RX_BLINK_SET,
++ MTK_2P5GPHY_LED_TX_BLINK_SET);
++};
++
++static int mt798x_2p5ge_phy_probe(struct phy_device *phydev)
++{
++ struct mtk_i2p5ge_phy_priv *priv;
++
++ priv = devm_kzalloc(&phydev->mdio.dev,
++ sizeof(struct mtk_i2p5ge_phy_priv), GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ switch (phydev->drv->phy_id) {
++ case MTK_2P5GPHY_ID_MT7988:
++ /* The original hardware only sets MDIO_DEVS_PMAPMD */
++ phydev->c45_ids.mmds_present |= MDIO_DEVS_PCS |
++ MDIO_DEVS_AN |
++ MDIO_DEVS_VEND1 |
++ MDIO_DEVS_VEND2;
++ break;
++ default:
++ return -EINVAL;
++ }
++
++ priv->fw_loaded = false;
++ phydev->priv = priv;
++
++ mtk_phy_leds_state_init(phydev);
++
++ return 0;
++}
++
++static struct phy_driver mtk_2p5gephy_driver[] = {
++ {
++ PHY_ID_MATCH_MODEL(MTK_2P5GPHY_ID_MT7988),
++ .name = "MediaTek MT7988 2.5GbE PHY",
++ .probe = mt798x_2p5ge_phy_probe,
++ .config_init = mt798x_2p5ge_phy_config_init,
++ .config_aneg = mt798x_2p5ge_phy_config_aneg,
++ .get_features = mt798x_2p5ge_phy_get_features,
++ .read_status = mt798x_2p5ge_phy_read_status,
++ .get_rate_matching = mt798x_2p5ge_phy_get_rate_matching,
++ .suspend = genphy_suspend,
++ .resume = genphy_resume,
++ .read_page = mtk_phy_read_page,
++ .write_page = mtk_phy_write_page,
++ .led_blink_set = mt798x_2p5ge_phy_led_blink_set,
++ .led_brightness_set = mt798x_2p5ge_phy_led_brightness_set,
++ .led_hw_is_supported = mt798x_2p5ge_phy_led_hw_is_supported,
++ .led_hw_control_get = mt798x_2p5ge_phy_led_hw_control_get,
++ .led_hw_control_set = mt798x_2p5ge_phy_led_hw_control_set,
++ },
++};
++
++module_phy_driver(mtk_2p5gephy_driver);
++
++static struct mdio_device_id __maybe_unused mtk_2p5ge_phy_tbl[] = {
++ { PHY_ID_MATCH_VENDOR(0x00339c00) },
++ { }
++};
++
++MODULE_DESCRIPTION("MediaTek 2.5Gb Ethernet PHY driver");
++MODULE_AUTHOR("SkyLake Huang <SkyLake.Huang@mediatek.com>");
++MODULE_LICENSE("GPL");
++
++MODULE_DEVICE_TABLE(mdio, mtk_2p5ge_phy_tbl);
++MODULE_FIRMWARE(MT7988_2P5GE_PMB_FW);
diff --git a/target/linux/mediatek/patches-6.6/733-12-net-phy-mediatek-Fix-alignment-in-callback-functions.patch b/target/linux/mediatek/patches-6.6/733-12-net-phy-mediatek-Fix-alignment-in-callback-functions.patch
new file mode 100644
index 0000000000..8657886138
--- /dev/null
+++ b/target/linux/mediatek/patches-6.6/733-12-net-phy-mediatek-Fix-alignment-in-callback-functions.patch
@@ -0,0 +1,130 @@
+From 07e90eb1819319a0c34b0cf3a57a4a3878e96e4d Mon Sep 17 00:00:00 2001
+From: "SkyLake.Huang" <skylake.huang@mediatek.com>
+Date: Mon, 1 Jul 2024 18:54:16 +0800
+Subject: [PATCH 12/13] net: phy: mediatek: Fix alignment in callback
+ functions' hook
+
+Align declarations in mtk_gephy_driver(mtk-ge.c) and
+mtk_socphy_driver(mtk-ge-soc.c). At first, some of them are
+".foo<tab>= method_foo", and others are ".bar<space>= method_bar".
+Use space instead for all of them here in case line is longer than
+80 chars.
+
+Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
+---
+ drivers/net/phy/mediatek/mtk-ge-soc.c | 40 +++++++++++++--------------
+ drivers/net/phy/mediatek/mtk-ge.c | 34 +++++++++++------------
+ 2 files changed, 37 insertions(+), 37 deletions(-)
+
+--- a/drivers/net/phy/mediatek/mtk-ge-soc.c
++++ b/drivers/net/phy/mediatek/mtk-ge-soc.c
+@@ -1394,17 +1394,17 @@ static int mt7981_phy_probe(struct phy_d
+ static struct phy_driver mtk_socphy_driver[] = {
+ {
+ PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7981),
+- .name = "MediaTek MT7981 PHY",
+- .config_init = mt798x_phy_config_init,
+- .read_status = mtk_gphy_cl22_read_status,
+- .config_intr = genphy_no_config_intr,
++ .name = "MediaTek MT7981 PHY",
++ .config_init = mt798x_phy_config_init,
++ .read_status = mtk_gphy_cl22_read_status,
++ .config_intr = genphy_no_config_intr,
+ .handle_interrupt = genphy_handle_interrupt_no_ack,
+- .probe = mt7981_phy_probe,
+- .suspend = genphy_suspend,
+- .resume = genphy_resume,
+- .read_page = mtk_phy_read_page,
+- .write_page = mtk_phy_write_page,
+- .led_blink_set = mt798x_phy_led_blink_set,
++ .probe = mt7981_phy_probe,
++ .suspend = genphy_suspend,
++ .resume = genphy_resume,
++ .read_page = mtk_phy_read_page,
++ .write_page = mtk_phy_write_page,
++ .led_blink_set = mt798x_phy_led_blink_set,
+ .led_brightness_set = mt798x_phy_led_brightness_set,
+ .led_hw_is_supported = mt798x_phy_led_hw_is_supported,
+ .led_hw_control_set = mt798x_phy_led_hw_control_set,
+@@ -1412,17 +1412,17 @@ static struct phy_driver mtk_socphy_driv
+ },
+ {
+ PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7988),
+- .name = "MediaTek MT7988 PHY",
+- .config_init = mt798x_phy_config_init,
+- .read_status = mtk_gphy_cl22_read_status,
+- .config_intr = genphy_no_config_intr,
++ .name = "MediaTek MT7988 PHY",
++ .config_init = mt798x_phy_config_init,
++ .read_status = mtk_gphy_cl22_read_status,
++ .config_intr = genphy_no_config_intr,
+ .handle_interrupt = genphy_handle_interrupt_no_ack,
+- .probe = mt7988_phy_probe,
+- .suspend = genphy_suspend,
+- .resume = genphy_resume,
+- .read_page = mtk_phy_read_page,
+- .write_page = mtk_phy_write_page,
+- .led_blink_set = mt798x_phy_led_blink_set,
++ .probe = mt7988_phy_probe,
++ .suspend = genphy_suspend,
++ .resume = genphy_resume,
++ .read_page = mtk_phy_read_page,
++ .write_page = mtk_phy_write_page,
++ .led_blink_set = mt798x_phy_led_blink_set,
+ .led_brightness_set = mt798x_phy_led_brightness_set,
+ .led_hw_is_supported = mt798x_phy_led_hw_is_supported,
+ .led_hw_control_set = mt798x_phy_led_hw_control_set,
+--- a/drivers/net/phy/mediatek/mtk-ge.c
++++ b/drivers/net/phy/mediatek/mtk-ge.c
+@@ -230,34 +230,34 @@ static int mt753x_phy_led_hw_control_set
+ static struct phy_driver mtk_gephy_driver[] = {
+ {
+ PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7530),
+- .name = "MediaTek MT7530 PHY",
+- .config_init = mt7530_phy_config_init,
++ .name = "MediaTek MT7530 PHY",
++ .config_init = mt7530_phy_config_init,
+ /* Interrupts are handled by the switch, not the PHY
+ * itself.
+ */
+- .config_intr = genphy_no_config_intr,
++ .config_intr = genphy_no_config_intr,
+ .handle_interrupt = genphy_handle_interrupt_no_ack,
+- .suspend = genphy_suspend,
+- .resume = genphy_resume,
+- .read_page = mtk_phy_read_page,
+- .write_page = mtk_phy_write_page,
++ .suspend = genphy_suspend,
++ .resume = genphy_resume,
++ .read_page = mtk_phy_read_page,
++ .write_page = mtk_phy_write_page,
+ },
+ {
+ PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7531),
+- .name = "MediaTek MT7531 PHY",
+- .probe = mt7531_phy_probe,
+- .config_init = mt7531_phy_config_init,
+- .read_status = mtk_gphy_cl22_read_status,
++ .name = "MediaTek MT7531 PHY",
++ .probe = mt7531_phy_probe,
++ .config_init = mt7531_phy_config_init,
++ .read_status = mtk_gphy_cl22_read_status,
+ /* Interrupts are handled by the switch, not the PHY
+ * itself.
+ */
+- .config_intr = genphy_no_config_intr,
++ .config_intr = genphy_no_config_intr,
+ .handle_interrupt = genphy_handle_interrupt_no_ack,
+- .suspend = genphy_suspend,
+- .resume = genphy_resume,
+- .read_page = mtk_phy_read_page,
+- .write_page = mtk_phy_write_page,
+- .led_blink_set = mt753x_phy_led_blink_set,
++ .suspend = genphy_suspend,
++ .resume = genphy_resume,
++ .read_page = mtk_phy_read_page,
++ .write_page = mtk_phy_write_page,
++ .led_blink_set = mt753x_phy_led_blink_set,
+ .led_brightness_set = mt753x_phy_led_brightness_set,
+ .led_hw_is_supported = mt753x_phy_led_hw_is_supported,
+ .led_hw_control_set = mt753x_phy_led_hw_control_set,
diff --git a/target/linux/mediatek/patches-6.6/733-13-net-phy-mediatek-Remove-unnecessary-outer-parens-of-.patch b/target/linux/mediatek/patches-6.6/733-13-net-phy-mediatek-Remove-unnecessary-outer-parens-of-.patch
new file mode 100644
index 0000000000..dd99bbba9a
--- /dev/null
+++ b/target/linux/mediatek/patches-6.6/733-13-net-phy-mediatek-Remove-unnecessary-outer-parens-of-.patch
@@ -0,0 +1,65 @@
+From e59883b637ae317c2ac275b542e8a50670d76e7c Mon Sep 17 00:00:00 2001
+From: "SkyLake.Huang" <skylake.huang@mediatek.com>
+Date: Mon, 1 Jul 2024 18:54:17 +0800
+Subject: [PATCH 13/13] net: phy: mediatek: Remove unnecessary outer parens of
+ "supported_triggers" var
+
+This patch removes unnecessary outer parens of "supported_triggers" vars
+in mtk-ge.c & mtk-ge-soc.c to improve readability.
+
+Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
+---
+ drivers/net/phy/mediatek/mtk-ge-soc.c | 16 ++++++++--------
+ drivers/net/phy/mediatek/mtk-ge.c | 16 ++++++++--------
+ 2 files changed, 16 insertions(+), 16 deletions(-)
+
+--- a/drivers/net/phy/mediatek/mtk-ge-soc.c
++++ b/drivers/net/phy/mediatek/mtk-ge-soc.c
+@@ -1224,14 +1224,14 @@ static int mt798x_phy_led_brightness_set
+ }
+
+ static const unsigned long supported_triggers =
+- (BIT(TRIGGER_NETDEV_FULL_DUPLEX) |
+- BIT(TRIGGER_NETDEV_HALF_DUPLEX) |
+- BIT(TRIGGER_NETDEV_LINK) |
+- BIT(TRIGGER_NETDEV_LINK_10) |
+- BIT(TRIGGER_NETDEV_LINK_100) |
+- BIT(TRIGGER_NETDEV_LINK_1000) |
+- BIT(TRIGGER_NETDEV_RX) |
+- BIT(TRIGGER_NETDEV_TX));
++ BIT(TRIGGER_NETDEV_FULL_DUPLEX) |
++ BIT(TRIGGER_NETDEV_HALF_DUPLEX) |
++ BIT(TRIGGER_NETDEV_LINK) |
++ BIT(TRIGGER_NETDEV_LINK_10) |
++ BIT(TRIGGER_NETDEV_LINK_100) |
++ BIT(TRIGGER_NETDEV_LINK_1000) |
++ BIT(TRIGGER_NETDEV_RX) |
++ BIT(TRIGGER_NETDEV_TX);
+
+ static int mt798x_phy_led_hw_is_supported(struct phy_device *phydev, u8 index,
+ unsigned long rules)
+--- a/drivers/net/phy/mediatek/mtk-ge.c
++++ b/drivers/net/phy/mediatek/mtk-ge.c
+@@ -189,14 +189,14 @@ static int mt753x_phy_led_brightness_set
+ }
+
+ static const unsigned long supported_triggers =
+- (BIT(TRIGGER_NETDEV_FULL_DUPLEX) |
+- BIT(TRIGGER_NETDEV_HALF_DUPLEX) |
+- BIT(TRIGGER_NETDEV_LINK) |
+- BIT(TRIGGER_NETDEV_LINK_10) |
+- BIT(TRIGGER_NETDEV_LINK_100) |
+- BIT(TRIGGER_NETDEV_LINK_1000) |
+- BIT(TRIGGER_NETDEV_RX) |
+- BIT(TRIGGER_NETDEV_TX));
++ BIT(TRIGGER_NETDEV_FULL_DUPLEX) |
++ BIT(TRIGGER_NETDEV_HALF_DUPLEX) |
++ BIT(TRIGGER_NETDEV_LINK) |
++ BIT(TRIGGER_NETDEV_LINK_10) |
++ BIT(TRIGGER_NETDEV_LINK_100) |
++ BIT(TRIGGER_NETDEV_LINK_1000) |
++ BIT(TRIGGER_NETDEV_RX) |
++ BIT(TRIGGER_NETDEV_TX);
+
+ static int mt753x_phy_led_hw_is_supported(struct phy_device *phydev, u8 index,
+ unsigned long rules)
diff --git a/target/linux/mediatek/patches-6.6/733-net-phy-add-driver-for-MediaTek-2.5G-PHY.patch b/target/linux/mediatek/patches-6.6/733-net-phy-add-driver-for-MediaTek-2.5G-PHY.patch
deleted file mode 100644
index 74b16be152..0000000000
--- a/target/linux/mediatek/patches-6.6/733-net-phy-add-driver-for-MediaTek-2.5G-PHY.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-From 128dc09b0af36772062142ce9e85b19c84ac789a Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Tue, 28 Feb 2023 17:53:37 +0000
-Subject: [PATCH] net: phy: add driver for MediaTek 2.5G PHY
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/phy/Kconfig | 7 ++
- drivers/net/phy/Makefile | 1 +
- drivers/net/phy/mediatek-2p5ge.c | 220 +++++++++++++++++++++++++++++++
- 3 files changed, 226 insertions(+)
- create mode 100644 drivers/net/phy/mediatek-2p5ge.c
-
---- a/drivers/net/phy/Kconfig
-+++ b/drivers/net/phy/Kconfig
-@@ -330,6 +330,13 @@ config MEDIATEK_GE_SOC_PHY
- present in the SoCs efuse and will dynamically calibrate VCM
- (common-mode voltage) during startup.
-
-+config MEDIATEK_2P5G_PHY
-+ tristate "MediaTek 2.5G Ethernet PHY"
-+ depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
-+ default NET_MEDIATEK_SOC
-+ help
-+ Supports the MediaTek 2.5G Ethernet PHY.
-+
- config MICREL_PHY
- tristate "Micrel PHYs"
- depends on PTP_1588_CLOCK_OPTIONAL
---- a/drivers/net/phy/Makefile
-+++ b/drivers/net/phy/Makefile
-@@ -82,6 +82,7 @@ obj-$(CONFIG_MARVELL_PHY) += marvell.o
- obj-$(CONFIG_MARVELL_88Q2XXX_PHY) += marvell-88q2xxx.o
- obj-$(CONFIG_MARVELL_88X2222_PHY) += marvell-88x2222.o
- obj-$(CONFIG_MAXLINEAR_GPHY) += mxl-gpy.o
-+obj-$(CONFIG_MEDIATEK_2P5G_PHY) += mediatek-2p5ge.o
- obj-$(CONFIG_MEDIATEK_GE_PHY) += mediatek-ge.o
- obj-$(CONFIG_MEDIATEK_GE_SOC_PHY) += mediatek-ge-soc.o
- obj-$(CONFIG_MESON_GXL_PHY) += meson-gxl.o
diff --git a/target/linux/mediatek/patches-6.6/901-arm-add-cmdline-override.patch b/target/linux/mediatek/patches-6.6/901-arm-add-cmdline-override.patch
index 8397915b26..21bbed88d7 100644
--- a/target/linux/mediatek/patches-6.6/901-arm-add-cmdline-override.patch
+++ b/target/linux/mediatek/patches-6.6/901-arm-add-cmdline-override.patch
@@ -37,7 +37,7 @@
* CONFIG_CMDLINE is meant to be a default in case nothing else
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
-@@ -2269,6 +2269,14 @@ config CMDLINE_FORCE
+@@ -2307,6 +2307,14 @@ config CMDLINE_FORCE
endchoice
diff --git a/target/linux/mediatek/patches-6.6/911-dts-mt7622-bpi-r64-add-rootdisk.patch b/target/linux/mediatek/patches-6.6/911-dts-mt7622-bpi-r64-add-rootdisk.patch
index 4feb0e5d1a..a28d274493 100644
--- a/target/linux/mediatek/patches-6.6/911-dts-mt7622-bpi-r64-add-rootdisk.patch
+++ b/target/linux/mediatek/patches-6.6/911-dts-mt7622-bpi-r64-add-rootdisk.patch
@@ -25,7 +25,7 @@
+ block-partition-env {
+ partname = "ubootenv";
+ nvmem-layout {
-+ compatible = "u-boot,env-layout";
++ compatible = "u-boot,env";
+ };
+ };
+ emmc_rootfs: block-partition-production {
@@ -52,7 +52,7 @@
+ block-partition-env {
+ partname = "ubootenv";
+ nvmem-layout {
-+ compatible = "u-boot,env-layout";
++ compatible = "u-boot,env";
+ };
+ };
+ sd_rootfs: block-partition-production {
diff --git a/target/linux/mpc85xx/Makefile b/target/linux/mpc85xx/Makefile
index b9bf0eaff0..a095714c8a 100644
--- a/target/linux/mpc85xx/Makefile
+++ b/target/linux/mpc85xx/Makefile
@@ -11,8 +11,7 @@ CPU_TYPE:=8548
FEATURES:=squashfs ramdisk nand
SUBTARGETS:=p1010 p1020 p2020
-KERNEL_PATCHVER:=6.1
-KERNEL_TESTING_PATCHVER:=6.6
+KERNEL_PATCHVER:=6.6
KERNELNAME:=zImage
@@ -21,6 +20,6 @@ include $(INCLUDE_DIR)/target.mk
DEFAULT_PACKAGES += \
kmod-input-core kmod-input-gpio-keys kmod-button-hotplug \
kmod-leds-gpio swconfig kmod-ath9k wpad-basic-mbedtls kmod-usb2 \
- uboot-envtools
+ uboot-envtools kmod-crypto-hw-talitos
$(eval $(call BuildTarget))
diff --git a/target/linux/mpc85xx/base-files/etc/board.d/02_network b/target/linux/mpc85xx/base-files/etc/board.d/02_network
index 2574ebc9b9..601bd7e9f1 100644
--- a/target/linux/mpc85xx/base-files/etc/board.d/02_network
+++ b/target/linux/mpc85xx/base-files/etc/board.d/02_network
@@ -24,13 +24,10 @@ hpe,msm460)
ucidef_set_interface_lan "eth0"
;;
ocedo,panda)
- ucidef_set_interface_wan "eth1"
- ucidef_add_switch "switch0" \
- "0:lan" "1:lan" "2:lan" "3:lan" "4:lan" "5:lan" "6:lan" "7:lan" "8u@eth0"
+ ucidef_set_interface_lan_wan "lan1 lan2 lan3 lan4 lan5 lan6 lan7 lan8" "eth1"
;;
tplink,tl-wdr4900-v1)
ucidef_set_interfaces_lan_wan "lan1 lan2 lan3 lan4" "wan"
- ucidef_set_interface_macaddr "wan" "$(macaddr_add $(mtd_get_mac_binary u-boot 0x4fc00) 1)"
;;
watchguard,firebox-t10)
ucidef_set_interfaces_lan_wan "eth1 eth2" "eth0"
diff --git a/target/linux/mpc85xx/base-files/etc/hotplug.d/firmware/10-ath9k-eeprom b/target/linux/mpc85xx/base-files/etc/hotplug.d/firmware/10-ath9k-eeprom
deleted file mode 100644
index be6ee40389..0000000000
--- a/target/linux/mpc85xx/base-files/etc/hotplug.d/firmware/10-ath9k-eeprom
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/bin/sh
-
-[ -e /lib/firmware/$FIRMWARE ] && exit 0
-
-. /lib/functions/caldata.sh
-
-board=$(board_name)
-
-case "$FIRMWARE" in
-"pci_wmac0.eeprom")
- case $board in
- tplink,tl-wdr4900-v1)
- caldata_extract "caldata" 0x1000 0x800
- ath9k_patch_mac $(mtd_get_mac_binary u-boot 0x4fc00)
- ;;
- *)
- caldata_die "board $board is not supported yet"
- ;;
- esac
- ;;
-
-"pci_wmac1.eeprom")
- case $board in
- tplink,tl-wdr4900-v1)
- caldata_extract "caldata" 0x5000 0x800
- ath9k_patch_mac $(macaddr_add $(mtd_get_mac_binary u-boot 0x4fc00) -1)
- ;;
- *)
- caldata_die "board $board is not supported yet"
- ;;
- esac
- ;;
-esac
diff --git a/target/linux/mpc85xx/config-6.1 b/target/linux/mpc85xx/config-6.1
deleted file mode 100644
index c017422714..0000000000
--- a/target/linux/mpc85xx/config-6.1
+++ /dev/null
@@ -1,295 +0,0 @@
-# CONFIG_40x is not set
-# CONFIG_44x is not set
-# CONFIG_ADVANCED_OPTIONS is not set
-CONFIG_ARCH_32BIT_OFF_T=y
-CONFIG_ARCH_HIBERNATION_POSSIBLE=y
-CONFIG_ARCH_KEEP_MEMBLOCK=y
-CONFIG_ARCH_MAY_HAVE_PC_FDC=y
-CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
-CONFIG_ARCH_MIGHT_HAVE_PC_SERIO=y
-CONFIG_ARCH_MMAP_RND_BITS=11
-CONFIG_ARCH_MMAP_RND_BITS_MAX=17
-CONFIG_ARCH_MMAP_RND_BITS_MIN=11
-CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=17
-CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11
-CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y
-CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y
-CONFIG_ARCH_SPLIT_ARG64=y
-CONFIG_ARCH_STACKWALK=y
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
-CONFIG_ARCH_WEAK_RELEASE_ACQUIRE=y
-CONFIG_ASN1=y
-CONFIG_AUDIT_ARCH=y
-CONFIG_BLK_MQ_PCI=y
-CONFIG_BOOKE=y
-CONFIG_BOOKE_OR_40x=y
-CONFIG_BOOKE_WDT=y
-# CONFIG_BR200_WP is not set
-# CONFIG_BSC9131_RDB is not set
-# CONFIG_BSC9132_QDS is not set
-# CONFIG_C293_PCIE is not set
-CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
-CONFIG_CC_NO_ARRAY_BOUNDS=y
-CONFIG_CLONE_BACKWARDS=y
-CONFIG_CLZ_TAB=y
-CONFIG_CMDLINE="console=ttyS0,115200"
-CONFIG_CMDLINE_FROM_BOOTLOADER=y
-# CONFIG_CMDLINE_OVERRIDE is not set
-# CONFIG_COMMON_CLK is not set
-CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
-CONFIG_COMPAT_32BIT_TIME=y
-# CONFIG_CORENET_GENERIC is not set
-# CONFIG_CPM2 is not set
-CONFIG_CPU_BIG_ENDIAN=y
-# CONFIG_CRYPTO_AES_PPC_SPE is not set
-CONFIG_CRYPTO_AUTHENC=y
-CONFIG_CRYPTO_HW=y
-CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
-CONFIG_CRYPTO_LIB_POLY1305_RSIZE=1
-CONFIG_CRYPTO_LIB_SHA1=y
-CONFIG_CRYPTO_LIB_UTILS=y
-# CONFIG_CRYPTO_MD5_PPC is not set
-CONFIG_CRYPTO_RNG=y
-CONFIG_CRYPTO_RNG2=y
-CONFIG_CRYPTO_RSA=y
-# CONFIG_CRYPTO_SHA1_PPC is not set
-# CONFIG_CRYPTO_SHA1_PPC_SPE is not set
-# CONFIG_CRYPTO_SHA256_PPC_SPE is not set
-CONFIG_DATA_SHIFT=24
-CONFIG_DEBUG_BUGVERBOSE=y
-CONFIG_DEBUG_INFO=y
-CONFIG_DNOTIFY=y
-CONFIG_DTC=y
-CONFIG_E500_CPU=y
-CONFIG_EARLY_PRINTK=y
-CONFIG_EDAC=y
-CONFIG_EDAC_ATOMIC_SCRUB=y
-# CONFIG_EDAC_DEBUG is not set
-CONFIG_EDAC_LEGACY_SYSFS=y
-CONFIG_EDAC_MPC85XX=y
-CONFIG_EDAC_SUPPORT=y
-CONFIG_EXCLUSIVE_SYSTEM_RAM=y
-# CONFIG_FIREBOX_T10 is not set
-CONFIG_FIXED_PHY=y
-CONFIG_FSL_EMB_PERFMON=y
-# CONFIG_FSL_FMAN is not set
-CONFIG_FSL_LBC=y
-CONFIG_FSL_PCI=y
-CONFIG_FSL_PQ_MDIO=y
-CONFIG_FSL_SOC=y
-CONFIG_FSL_SOC_BOOKE=y
-CONFIG_FWNODE_MDIO=y
-CONFIG_FW_LOADER_PAGED_BUF=y
-CONFIG_FW_LOADER_SYSFS=y
-CONFIG_GCC11_NO_ARRAY_BOUNDS=y
-CONFIG_GCC_ASM_GOTO_OUTPUT_WORKAROUND=y
-CONFIG_GENERIC_ALLOCATOR=y
-CONFIG_GENERIC_ATOMIC64=y
-CONFIG_GENERIC_BUG=y
-CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_GENERIC_CMOS_UPDATE=y
-CONFIG_GENERIC_CPU_AUTOPROBE=y
-CONFIG_GENERIC_CPU_VULNERABILITIES=y
-CONFIG_GENERIC_EARLY_IOREMAP=y
-CONFIG_GENERIC_GETTIMEOFDAY=y
-CONFIG_GENERIC_IRQ_SHOW=y
-CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
-CONFIG_GENERIC_ISA_DMA=y
-CONFIG_GENERIC_PCI_IOMAP=y
-CONFIG_GENERIC_SMP_IDLE_THREAD=y
-CONFIG_GENERIC_STRNCPY_FROM_USER=y
-CONFIG_GENERIC_STRNLEN_USER=y
-CONFIG_GENERIC_TIME_VSYSCALL=y
-CONFIG_GEN_RTC=y
-# CONFIG_GE_IMP3A is not set
-CONFIG_GIANFAR=y
-CONFIG_GPIO_CDEV=y
-CONFIG_GPIO_GENERIC=y
-CONFIG_GPIO_MPC8XXX=y
-CONFIG_HAS_DMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT_MAP=y
-# CONFIG_HIVEAP_330 is not set
-CONFIG_HW_RANDOM=y
-CONFIG_HZ_PERIODIC=y
-CONFIG_I2C=y
-CONFIG_I2C_BOARDINFO=y
-CONFIG_I2C_MPC=y
-CONFIG_ILLEGAL_POINTER_VALUE=0
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_IRQCHIP=y
-CONFIG_IRQ_DOMAIN=y
-CONFIG_IRQ_FORCED_THREADING=y
-CONFIG_IRQ_WORK=y
-CONFIG_ISA_DMA_API=y
-CONFIG_KERNEL_START=0xc0000000
-# CONFIG_KSI8560 is not set
-CONFIG_LIBFDT=y
-CONFIG_LOCK_DEBUGGING_SUPPORT=y
-CONFIG_LOWMEM_CAM_NUM=9
-CONFIG_LOWMEM_SIZE=0x30000000
-CONFIG_LXT_PHY=y
-# CONFIG_MATH_EMULATION is not set
-CONFIG_MDIO_BUS=y
-CONFIG_MDIO_DEVICE=y
-CONFIG_MDIO_DEVRES=y
-CONFIG_MEMFD_CREATE=y
-CONFIG_MIGRATION=y
-CONFIG_MMU_GATHER_MERGE_VMAS=y
-CONFIG_MMU_GATHER_PAGE_SIZE=y
-CONFIG_MODULES_USE_ELF_RELA=y
-# CONFIG_MPC8536_DS is not set
-# CONFIG_MPC8540_ADS is not set
-# CONFIG_MPC8560_ADS is not set
-# CONFIG_MPC85xx_CDS is not set
-# CONFIG_MPC85xx_DS is not set
-# CONFIG_MPC85xx_MDS is not set
-# CONFIG_MPC85xx_RDB is not set
-CONFIG_MPIC=y
-# CONFIG_MPIC_MSGR is not set
-CONFIG_MPIC_TIMER=y
-CONFIG_MPILIB=y
-# CONFIG_MSM460 is not set
-# CONFIG_MTD_CFI is not set
-CONFIG_MTD_NAND_CORE=y
-CONFIG_MTD_NAND_ECC=y
-CONFIG_MTD_NAND_ECC_SW_HAMMING=y
-CONFIG_MTD_RAW_NAND=y
-CONFIG_MTD_SPI_NOR=y
-# CONFIG_MVME2500 is not set
-CONFIG_NEED_PER_CPU_KM=y
-CONFIG_NEED_SG_DMA_LENGTH=y
-CONFIG_NET_SELFTESTS=y
-CONFIG_NLS=y
-CONFIG_NR_CPUS=1
-CONFIG_NR_IRQS=512
-CONFIG_NVMEM=y
-CONFIG_NVMEM_LAYOUTS=y
-# CONFIG_NVMEM_QORIQ_EFUSE is not set
-CONFIG_OF=y
-CONFIG_OF_ADDRESS=y
-CONFIG_OF_DMA_DEFAULT_COHERENT=y
-CONFIG_OF_EARLY_FLATTREE=y
-CONFIG_OF_FLATTREE=y
-CONFIG_OF_GPIO=y
-CONFIG_OF_IRQ=y
-CONFIG_OF_KOBJ=y
-CONFIG_OF_MDIO=y
-CONFIG_OLD_SIGACTION=y
-CONFIG_OLD_SIGSUSPEND=y
-# CONFIG_P1010_RDB is not set
-# CONFIG_P1022_DS is not set
-# CONFIG_P1022_RDK is not set
-# CONFIG_P1023_RDB is not set
-CONFIG_PAGE_OFFSET=0xc0000000
-CONFIG_PAGE_POOL=y
-CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
-CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
-# CONFIG_PANDA is not set
-CONFIG_PCI=y
-CONFIG_PCIEAER=y
-CONFIG_PCIEASPM=y
-CONFIG_PCIEASPM_DEFAULT=y
-# CONFIG_PCIEASPM_PERFORMANCE is not set
-# CONFIG_PCIEASPM_POWERSAVE is not set
-# CONFIG_PCIEASPM_POWER_SUPERSAVE is not set
-CONFIG_PCIEPORTBUS=y
-CONFIG_PCI_DOMAINS=y
-CONFIG_PGTABLE_LEVELS=2
-CONFIG_PHYLIB=y
-CONFIG_PHYLIB_LEDS=y
-CONFIG_PHYSICAL_ALIGN=0x04000000
-CONFIG_PHYSICAL_START=0x00000000
-# CONFIG_PHYS_64BIT is not set
-# CONFIG_PMU_SYSFS is not set
-# CONFIG_PPA8548 is not set
-CONFIG_PPC=y
-CONFIG_PPC32=y
-# CONFIG_PPC64 is not set
-CONFIG_PPC_85xx=y
-# CONFIG_PPC_8xx is not set
-CONFIG_PPC_ADV_DEBUG_DACS=2
-CONFIG_PPC_ADV_DEBUG_DVCS=0
-CONFIG_PPC_ADV_DEBUG_IACS=2
-CONFIG_PPC_ADV_DEBUG_REGS=y
-CONFIG_PPC_BARRIER_NOSPEC=y
-# CONFIG_PPC_BOOK3S_32 is not set
-CONFIG_PPC_DOORBELL=y
-CONFIG_PPC_E500=y
-# CONFIG_PPC_E500MC is not set
-# CONFIG_PPC_EARLY_DEBUG is not set
-CONFIG_PPC_INDIRECT_PCI=y
-CONFIG_PPC_KUAP=y
-# CONFIG_PPC_KUAP_DEBUG is not set
-CONFIG_PPC_KUEP=y
-CONFIG_PPC_MMU_NOHASH=y
-CONFIG_PPC_PAGE_SHIFT=12
-# CONFIG_PPC_PCI_BUS_NUM_DOMAIN_DEPENDENT is not set
-# CONFIG_PPC_QEMU_E500 is not set
-CONFIG_PPC_SMP_MUXED_IPI=y
-CONFIG_PPC_UDBG_16550=y
-CONFIG_PPC_WERROR=y
-CONFIG_PREEMPT_NONE_BUILD=y
-CONFIG_PTP_1588_CLOCK_OPTIONAL=y
-CONFIG_QE_GPIO=y
-CONFIG_QUICC_ENGINE=y
-CONFIG_RANDSTRUCT_NONE=y
-CONFIG_RAS=y
-# CONFIG_RED_15W_REV1 is not set
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_GENERIC=y
-CONFIG_RTC_I2C_AND_SPI=y
-CONFIG_RTC_MC146818_LIB=y
-# CONFIG_SCOM_DEBUGFS is not set
-CONFIG_SERIAL_8250_EXTENDED=y
-CONFIG_SERIAL_8250_FSL=y
-CONFIG_SERIAL_8250_SHARE_IRQ=y
-CONFIG_SERIAL_MCTRL_GPIO=y
-CONFIG_SERIAL_OF_PLATFORM=y
-# CONFIG_SERIAL_QE is not set
-# CONFIG_SOCRATES is not set
-CONFIG_SOFTIRQ_ON_OWN_STACK=y
-CONFIG_SPARSE_IRQ=y
-CONFIG_SPE=y
-CONFIG_SPE_POSSIBLE=y
-CONFIG_SPI=y
-CONFIG_SPI_FSL_ESPI=y
-CONFIG_SPI_MASTER=y
-CONFIG_SPI_MEM=y
-CONFIG_SRCU=y
-# CONFIG_STATIC_CALL_SELFTEST is not set
-# CONFIG_STRIP_ASM_SYMS is not set
-# CONFIG_STX_GP3 is not set
-CONFIG_SWPHY=y
-CONFIG_SYSCTL_EXCEPTION_TRACE=y
-CONFIG_TARGET_CPU="8540"
-CONFIG_TARGET_CPU_BOOL=y
-CONFIG_TASK_SIZE=0xc0000000
-CONFIG_THREAD_INFO_IN_TASK=y
-CONFIG_THREAD_SHIFT=13
-CONFIG_TICK_CPU_ACCOUNTING=y
-CONFIG_TINY_SRCU=y
-# CONFIG_TL_WDR4900_V1 is not set
-# CONFIG_TOOLCHAIN_DEFAULT_CPU is not set
-# CONFIG_TQM8540 is not set
-# CONFIG_TQM8541 is not set
-# CONFIG_TQM8548 is not set
-# CONFIG_TQM8555 is not set
-# CONFIG_TQM8560 is not set
-# CONFIG_TWR_P102x is not set
-CONFIG_UCC=y
-CONFIG_UCC_FAST=y
-CONFIG_UCC_GETH=y
-# CONFIG_UGETH_TX_ON_DEMAND is not set
-CONFIG_USB_SUPPORT=y
-CONFIG_VDSO32=y
-# CONFIG_VIRT_CPU_ACCOUNTING_NATIVE is not set
-CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_WATCHDOG_CORE=y
-# CONFIG_WS_AP3710I is not set
-# CONFIG_WS_AP3715I is not set
-# CONFIG_WS_AP3825I is not set
-# CONFIG_XES_MPC85xx is not set
-CONFIG_XZ_DEC_BCJ=y
-CONFIG_XZ_DEC_POWERPC=y
diff --git a/target/linux/mpc85xx/files/arch/powerpc/boot/dts/panda.dts b/target/linux/mpc85xx/files/arch/powerpc/boot/dts/panda.dts
index 4b3b52d35b..c4125052ec 100644
--- a/target/linux/mpc85xx/files/arch/powerpc/boot/dts/panda.dts
+++ b/target/linux/mpc85xx/files/arch/powerpc/boot/dts/panda.dts
@@ -87,6 +87,7 @@
};
switch0: ethernet-phy@0 {
+ compatible = "brcm,bcm53128";
reg = <0x0>;
ports {
@@ -135,7 +136,8 @@
port@8 {
reg = <8>;
- label = "cpu";
+ phy-mode = "rgmii-id";
+ ethernet = <&enet0>;
fixed-link {
speed = <1000>;
@@ -160,7 +162,6 @@
enet0: ethernet@b0000 {
phy-connection-type = "rgmii-id";
- phy-handle = <&switch0>;
fixed-link {
speed = <1000>;
diff --git a/target/linux/mpc85xx/files/arch/powerpc/boot/dts/tl-wdr4900-v1.dts b/target/linux/mpc85xx/files/arch/powerpc/boot/dts/tl-wdr4900-v1.dts
index 5cf3c26fc9..4fd9767d2d 100644
--- a/target/linux/mpc85xx/files/arch/powerpc/boot/dts/tl-wdr4900-v1.dts
+++ b/target/linux/mpc85xx/files/arch/powerpc/boot/dts/tl-wdr4900-v1.dts
@@ -9,6 +9,7 @@
* option) any later version.
*/
+#include <dt-bindings/leds/common.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/gpio/gpio.h>
@@ -63,7 +64,9 @@
#size-cells = <1>;
macaddr_uboot_4fc00: macaddr@4fc00 {
+ compatible = "mac-base";
reg = <0x4fc00 0x6>;
+ #nvmem-cell-cells = <1>;
};
};
};
@@ -90,6 +93,20 @@
reg = <0x00ff0000 0x00010000>;
label = "caldata";
read-only;
+
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ cal_caldata_1000: calibration@1000 {
+ reg = <0x1000 0x440>;
+ };
+
+ cal_caldata_5000: calibration@5000 {
+ reg = <0x5000 0x440>;
+ };
+ };
};
};
};
@@ -101,6 +118,23 @@
usb@22000 {
phy_type = "utmi";
dr_mode = "host";
+
+ port@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>;
+ #trigger-source-cells = <0>;
+
+ hub_port1: port@1 {
+ reg = <1>;
+ #trigger-source-cells = <0>;
+ };
+
+ hub_port2: port@2 {
+ reg = <2>;
+ #trigger-source-cells = <0>;
+ };
+ };
};
mdio@24000 {
@@ -148,30 +182,93 @@
reg = <1>;
label = "wan";
phy-handle = <&phy_port1>;
+
+ nvmem-cells = <&macaddr_uboot_4fc00 1>;
+ nvmem-cell-names = "mac-address";
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@0 {
+ reg = <0>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_WAN;
+ default-state = "keep";
+ };
+ };
};
port@2 {
reg = <2>;
label = "lan1";
phy-handle = <&phy_port2>;
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@0 {
+ reg = <0>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_LAN;
+ default-state = "keep";
+ };
+ };
};
port@3 {
reg = <3>;
label = "lan2";
phy-handle = <&phy_port3>;
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@0 {
+ reg = <0>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_LAN;
+ default-state = "keep";
+ };
+ };
};
port@4 {
reg = <4>;
label = "lan3";
phy-handle = <&phy_port4>;
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@0 {
+ reg = <0>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_LAN;
+ default-state = "keep";
+ };
+ };
};
port@5 {
reg = <5>;
label = "lan4";
phy-handle = <&phy_port5>;
+
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ led@0 {
+ reg = <0>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_LAN;
+ default-state = "keep";
+ };
+ };
};
};
};
@@ -187,7 +284,7 @@
enet0: ethernet@b0000 {
phy-connection-type = "rgmii-id";
- nvmem-cells = <&macaddr_uboot_4fc00>;
+ nvmem-cells = <&macaddr_uboot_4fc00 0>;
nvmem-cell-names = "mac-address";
fixed-link {
@@ -246,6 +343,16 @@
0x1000000 0x0 0x0
0x1000000 0x0 0x0
0x0 0x100000>;
+
+ ath9k: wifi@0,0 {
+ compatible = "pci168c,0033";
+ reg = <0x0000 0 0 0 0>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ qca,led-pin = /bits/ 8 <0>;
+ nvmem-cells = <&cal_caldata_1000>, <&macaddr_uboot_4fc00 0>;
+ nvmem-cell-names = "calibration", "mac-address";
+ };
};
};
@@ -261,6 +368,22 @@
0x1000000 0x0 0x0
0x1000000 0x0 0x0
0x0 0x100000>;
+
+ wifi@0,0 {
+ compatible = "pci168c,0030";
+ reg = <0x0000 0 0 0 0>;
+ /*
+ * The PCI header of the AR9381 chip is not programmed
+ * correctly by the bootloader and the device uses wrong
+ * data due to that. Replace the broken values with the
+ * correct ones.
+ */
+ device-id = <0x0030>;
+ class-code = <0x028000>;
+ qca,led-pin = /bits/ 8 <0>;
+ nvmem-cells = <&cal_caldata_5000>, <&macaddr_uboot_4fc00 (-1)>;
+ nvmem-cell-names = "calibration", "mac-address";
+ };
};
};
@@ -271,26 +394,47 @@
leds {
compatible = "gpio-leds";
- system_green: system {
+ led-0 {
+ gpios = <&ath9k 1 GPIO_ACTIVE_LOW>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_WPS;
+ };
+
+ system_green: led-1 {
gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
- label = "tp-link:blue:system";
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_STATUS;
};
- usb1 {
+ led-2 {
gpios = <&gpio0 3 GPIO_ACTIVE_LOW>;
- label = "tp-link:green:usb1";
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_USB;
+ function-enumerator = <1>;
+ linux,default-trigger = "usbport";
+ trigger-sources = <&hub_port1>;
};
- usb2 {
+ led-3 {
gpios = <&gpio0 4 GPIO_ACTIVE_LOW>;
- label = "tp-link:green:usb2";
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_USB;
+ function-enumerator = <2>;
+ linux,default-trigger = "usbport";
+ trigger-sources = <&hub_port2>;
};
+ };
- usbpower {
- gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
- label = "tp-link:usb:power";
+ gpio_export {
+ compatible = "gpio-export";
+ #size-cells = <0>;
+
+ usb-pwr {
+ gpio-export,name = "usb_pwr";
+ gpio-export,output = <1>;
+ gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+ };
};
- };
buttons {
compatible = "gpio-keys";
diff --git a/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/br200-wp.c b/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/br200-wp.c
index 23fd11a5c6..8bd5a679b8 100644
--- a/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/br200-wp.c
+++ b/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/br200-wp.c
@@ -13,7 +13,6 @@
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
-#include <linux/of_platform.h>
#include <asm/time.h>
#include <asm/machdep.h>
@@ -29,7 +28,7 @@
#include "mpc85xx.h"
-void __init br200_wp_pic_init(void)
+static void __init br200_wp_pic_init(void)
{
struct mpic *mpic;
@@ -57,19 +56,9 @@ static void __init br200_wp_setup_arch(void)
machine_arch_initcall(br200_wp, mpc85xx_common_publish_devices);
-/*
- * Called very early, device-tree isn't unflattened
- */
-static int __init br200_wp_probe(void)
-{
- if (of_machine_is_compatible("aerohive,br200-wp"))
- return 1;
- return 0;
-}
-
define_machine(br200_wp) {
.name = "P1020 RDB",
- .probe = br200_wp_probe,
+ .compatible = "aerohive,br200-wp",
.setup_arch = br200_wp_setup_arch,
.init_IRQ = br200_wp_pic_init,
#ifdef CONFIG_PCI
@@ -77,6 +66,5 @@ define_machine(br200_wp) {
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif
.get_irq = mpic_get_irq,
- .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress,
};
diff --git a/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/firebox_t10.c b/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/firebox_t10.c
index 422bde6903..f8f90b22bf 100644
--- a/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/firebox_t10.c
+++ b/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/firebox_t10.c
@@ -20,7 +20,6 @@
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
-#include <linux/of_platform.h>
#include <asm/time.h>
#include <asm/machdep.h>
@@ -35,7 +34,7 @@
#include "mpc85xx.h"
-void __init firebox_t10_pic_init(void)
+static void __init firebox_t10_pic_init(void)
{
struct mpic *mpic;
@@ -62,19 +61,9 @@ static void __init firebox_t10_setup_arch(void)
machine_arch_initcall(firebox_t10, mpc85xx_common_publish_devices);
-/*
- * Called very early, device-tree isn't unflattened
- */
-static int __init firebox_t10_probe(void)
-{
- if (of_machine_is_compatible("watchguard,firebox-t10"))
- return 1;
- return 0;
-}
-
define_machine(firebox_t10) {
.name = "P1010 RDB",
- .probe = firebox_t10_probe,
+ .compatible = "watchguard,firebox-t10",
.setup_arch = firebox_t10_setup_arch,
.init_IRQ = firebox_t10_pic_init,
#ifdef CONFIG_PCI
@@ -82,6 +71,5 @@ define_machine(firebox_t10) {
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif
.get_irq = mpic_get_irq,
- .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress,
};
diff --git a/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/hiveap-330.c b/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/hiveap-330.c
index f325b32ce6..3c97eeaff7 100644
--- a/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/hiveap-330.c
+++ b/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/hiveap-330.c
@@ -18,7 +18,6 @@
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
-#include <linux/of_platform.h>
#include <asm/time.h>
#include <asm/machdep.h>
@@ -34,7 +33,7 @@
#include "mpc85xx.h"
-void __init hiveap_330_pic_init(void)
+static void __init hiveap_330_pic_init(void)
{
struct mpic *mpic;
@@ -64,19 +63,9 @@ static void __init hiveap_330_setup_arch(void)
machine_arch_initcall(hiveap_330, mpc85xx_common_publish_devices);
-/*
- * Called very early, device-tree isn't unflattened
- */
-static int __init hiveap_330_probe(void)
-{
- if (of_machine_is_compatible("aerohive,hiveap-330"))
- return 1;
- return 0;
-}
-
define_machine(hiveap_330) {
.name = "P1020 RDB",
- .probe = hiveap_330_probe,
+ .compatible = "aerohive,hiveap-330",
.setup_arch = hiveap_330_setup_arch,
.init_IRQ = hiveap_330_pic_init,
#ifdef CONFIG_PCI
@@ -84,6 +73,5 @@ define_machine(hiveap_330) {
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif
.get_irq = mpic_get_irq,
- .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress,
};
diff --git a/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/msm460.c b/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/msm460.c
index a4f547d313..24eac19a76 100644
--- a/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/msm460.c
+++ b/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/msm460.c
@@ -20,7 +20,6 @@
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
-#include <linux/of_platform.h>
#include <asm/time.h>
#include <asm/machdep.h>
@@ -36,7 +35,7 @@
#include "mpc85xx.h"
-void __init msm_pic_init(void)
+static void __init msm_pic_init(void)
{
struct mpic *mpic;
@@ -66,19 +65,9 @@ static void __init msm_setup_arch(void)
machine_arch_initcall(msm, mpc85xx_common_publish_devices);
-/*
- * Called very early, device-tree isn't unflattened
- */
-static int __init msm_probe(void)
-{
- if (of_machine_is_compatible("hpe,msm460"))
- return 1;
- return 0;
-}
-
define_machine(msm) {
.name = "P1020 RDB",
- .probe = msm_probe,
+ .compatible = "hpe,msm460",
.setup_arch = msm_setup_arch,
.init_IRQ = msm_pic_init,
#ifdef CONFIG_PCI
@@ -86,6 +75,5 @@ define_machine(msm) {
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif
.get_irq = mpic_get_irq,
- .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress,
};
diff --git a/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/panda.c b/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/panda.c
index 7eec2cf15c..aab2b591ae 100644
--- a/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/panda.c
+++ b/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/panda.c
@@ -20,7 +20,6 @@
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
-#include <linux/of_platform.h>
#include <asm/time.h>
#include <asm/machdep.h>
@@ -36,7 +35,7 @@
#include "mpc85xx.h"
-void __init panda_pic_init(void)
+static void __init panda_pic_init(void)
{
struct mpic *mpic;
@@ -66,19 +65,9 @@ static void __init panda_setup_arch(void)
machine_arch_initcall(panda, mpc85xx_common_publish_devices);
-/*
- * Called very early, device-tree isn't unflattened
- */
-static int __init panda_probe(void)
-{
- if (of_machine_is_compatible("ocedo,panda"))
- return 1;
- return 0;
-}
-
define_machine(panda) {
.name = "P1020 RDB",
- .probe = panda_probe,
+ .compatible = "ocedo,panda",
.setup_arch = panda_setup_arch,
.init_IRQ = panda_pic_init,
#ifdef CONFIG_PCI
@@ -86,6 +75,5 @@ define_machine(panda) {
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif
.get_irq = mpic_get_irq,
- .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress,
};
diff --git a/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/red15w_rev1.c b/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/red15w_rev1.c
index 1b2be853a5..8966cc3452 100644
--- a/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/red15w_rev1.c
+++ b/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/red15w_rev1.c
@@ -20,7 +20,6 @@
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
-#include <linux/of_platform.h>
#include <asm/time.h>
#include <asm/machdep.h>
@@ -35,7 +34,7 @@
#include "mpc85xx.h"
-void __init red_15w_rev1_pic_init(void)
+static void __init red_15w_rev1_pic_init(void)
{
struct mpic *mpic;
@@ -62,19 +61,9 @@ static void __init red_15w_rev1_setup_arch(void)
machine_arch_initcall(red_15w_rev1, mpc85xx_common_publish_devices);
-/*
- * Called very early, device-tree isn't unflattened
- */
-static int __init red_15w_rev1_probe(void)
-{
- if (of_machine_is_compatible("sophos,red-15w-rev1"))
- return 1;
- return 0;
-}
-
define_machine(red_15w_rev1) {
.name = "P1010 RDB",
- .probe = red_15w_rev1_probe,
+ .compatible = "sophos,red-15w-rev1",
.setup_arch = red_15w_rev1_setup_arch,
.init_IRQ = red_15w_rev1_pic_init,
#ifdef CONFIG_PCI
@@ -82,6 +71,5 @@ define_machine(red_15w_rev1) {
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif
.get_irq = mpic_get_irq,
- .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress,
};
diff --git a/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/tl_wdr4900_v1.c b/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/tl_wdr4900_v1.c
index 87a97e65c8..8180ddaeef 100644
--- a/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/tl_wdr4900_v1.c
+++ b/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/tl_wdr4900_v1.c
@@ -16,12 +16,8 @@
#include <linux/stddef.h>
#include <linux/kernel.h>
-#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
-#include <linux/of_platform.h>
-#include <linux/ath9k_platform.h>
-#include <linux/leds.h>
#include <asm/time.h>
#include <asm/machdep.h>
@@ -36,7 +32,7 @@
#include "mpc85xx.h"
-void __init tl_wdr4900_v1_pic_init(void)
+static void __init tl_wdr4900_v1_pic_init(void)
{
struct mpic *mpic = mpic_alloc(NULL, 0, MPIC_BIG_ENDIAN |
MPIC_SINGLE_DEST_CPU,
@@ -47,60 +43,6 @@ void __init tl_wdr4900_v1_pic_init(void)
mpic_init(mpic);
}
-#ifdef CONFIG_PCI
-static struct gpio_led tl_wdr4900_v1_wmac_leds_gpio[] = {
- {
- .name = "tp-link:blue:wps",
- .gpio = 1,
- .active_low = 1,
- },
-};
-
-static struct ath9k_platform_data tl_wdr4900_v1_wmac0_data = {
- .led_pin = 0,
- .eeprom_name = "pci_wmac0.eeprom",
- .leds = tl_wdr4900_v1_wmac_leds_gpio,
- .num_leds = ARRAY_SIZE(tl_wdr4900_v1_wmac_leds_gpio),
-};
-
-static struct ath9k_platform_data tl_wdr4900_v1_wmac1_data = {
- .led_pin = 0,
- .eeprom_name = "pci_wmac1.eeprom",
-};
-
-static void tl_wdr4900_v1_pci_wmac_fixup(struct pci_dev *dev)
-{
- if (!machine_is(tl_wdr4900_v1))
- return;
-
- if (dev->bus->number == 1 &&
- PCI_SLOT(dev->devfn) == 0) {
- dev->dev.platform_data = &tl_wdr4900_v1_wmac0_data;
- return;
- }
-
- if (dev->bus->number == 3 &&
- PCI_SLOT(dev->devfn) == 0 &&
- dev->device == 0xabcd) {
- dev->dev.platform_data = &tl_wdr4900_v1_wmac1_data;
-
- /*
- * The PCI header of the AR9381 chip is not programmed
- * correctly by the bootloader and the device uses wrong
- * data due to that. Replace the broken values with the
- * correct ones.
- */
- dev->device = 0x30;
- dev->class = 0x028000;
-
- pr_info("pci %s: AR9381 fixup applied\n", pci_name(dev));
- }
-}
-
-DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATHEROS, PCI_ANY_ID,
- tl_wdr4900_v1_pci_wmac_fixup);
-#endif /* CONFIG_PCI */
-
/*
* Setup the architecture
*/
@@ -116,25 +58,14 @@ static void __init tl_wdr4900_v1_setup_arch(void)
machine_arch_initcall(tl_wdr4900_v1, mpc85xx_common_publish_devices);
-/*
- * Called very early, device-tree isn't unflattened
- */
-static int __init tl_wdr4900_v1_probe(void)
-{
- if (of_machine_is_compatible("tplink,tl-wdr4900-v1"))
- return 1;
- return 0;
-}
-
define_machine(tl_wdr4900_v1) {
.name = "Freescale P1014",
- .probe = tl_wdr4900_v1_probe,
+ .compatible = "tplink,tl-wdr4900-v1",
.setup_arch = tl_wdr4900_v1_setup_arch,
.init_IRQ = tl_wdr4900_v1_pic_init,
#ifdef CONFIG_PCI
.pcibios_fixup_bus = fsl_pcibios_fixup_bus,
#endif
.get_irq = mpic_get_irq,
- .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress,
};
diff --git a/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/ws-ap3710i.c b/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/ws-ap3710i.c
index f23902de39..75f881a119 100644
--- a/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/ws-ap3710i.c
+++ b/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/ws-ap3710i.c
@@ -20,7 +20,6 @@
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
-#include <linux/of_platform.h>
#include <asm/time.h>
#include <asm/machdep.h>
@@ -36,7 +35,7 @@
#include "mpc85xx.h"
-void __init ws_ap3710i_pic_init(void)
+static void __init ws_ap3710i_pic_init(void)
{
struct mpic *mpic;
@@ -66,19 +65,9 @@ static void __init ws_ap3710i_setup_arch(void)
machine_arch_initcall(ws_ap3710i, mpc85xx_common_publish_devices);
-/*
- * Called very early, device-tree isn't unflattened
- */
-static int __init ws_ap3710i_probe(void)
-{
- if (of_machine_is_compatible("enterasys,ws-ap3710i"))
- return 1;
- return 0;
-}
-
define_machine(ws_ap3710i) {
.name = "P1020 RDB",
- .probe = ws_ap3710i_probe,
+ .compatible = "enterasys,ws-ap3710i",
.setup_arch = ws_ap3710i_setup_arch,
.init_IRQ = ws_ap3710i_pic_init,
#ifdef CONFIG_PCI
@@ -86,6 +75,5 @@ define_machine(ws_ap3710i) {
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif
.get_irq = mpic_get_irq,
- .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress,
};
diff --git a/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/ws-ap3715i.c b/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/ws-ap3715i.c
index aa2a366b3d..3c3d2bf255 100644
--- a/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/ws-ap3715i.c
+++ b/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/ws-ap3715i.c
@@ -20,7 +20,6 @@
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
-#include <linux/of_platform.h>
#include <asm/time.h>
#include <asm/machdep.h>
@@ -35,7 +34,7 @@
#include "mpc85xx.h"
-void __init wsap3715i_pic_init(void)
+static void __init wsap3715i_pic_init(void)
{
struct mpic *mpic;
@@ -62,19 +61,9 @@ static void __init wsap3715i_setup_arch(void)
machine_arch_initcall(wsap3715i, mpc85xx_common_publish_devices);
-/*
- * Called very early, device-tree isn't unflattened
- */
-static int __init wsap3715i_probe(void)
-{
- if (of_machine_is_compatible("enterasys,ws-ap3715i"))
- return 1;
- return 0;
-}
-
define_machine(wsap3715i) {
.name = "P1010 RDB",
- .probe = wsap3715i_probe,
+ .compatible = "enterasys,ws-ap3715i",
.setup_arch = wsap3715i_setup_arch,
.init_IRQ = wsap3715i_pic_init,
#ifdef CONFIG_PCI
@@ -82,6 +71,5 @@ define_machine(wsap3715i) {
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif
.get_irq = mpic_get_irq,
- .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress,
};
diff --git a/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/ws-ap3825i.c b/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/ws-ap3825i.c
index 5a0919c200..fbacbc96c4 100644
--- a/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/ws-ap3825i.c
+++ b/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/ws-ap3825i.c
@@ -20,7 +20,6 @@
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
-#include <linux/of_platform.h>
#include <asm/time.h>
#include <asm/machdep.h>
@@ -36,7 +35,7 @@
#include "mpc85xx.h"
-void __init ws_ap3825i_pic_init(void)
+static void __init ws_ap3825i_pic_init(void)
{
struct mpic *mpic;
@@ -66,19 +65,9 @@ static void __init ws_ap3825i_setup_arch(void)
machine_arch_initcall(ws_ap3825i, mpc85xx_common_publish_devices);
-/*
- * Called very early, device-tree isn't unflattened
- */
-static int __init ws_ap3825i_probe(void)
-{
- if (of_machine_is_compatible("extreme-networks,ws-ap3825i"))
- return 1;
- return 0;
-}
-
define_machine(ws_ap3825i) {
.name = "P1020 RDB",
- .probe = ws_ap3825i_probe,
+ .compatible = "extreme-networks,ws-ap3825i",
.setup_arch = ws_ap3825i_setup_arch,
.init_IRQ = ws_ap3825i_pic_init,
#ifdef CONFIG_PCI
@@ -86,6 +75,5 @@ define_machine(ws_ap3825i) {
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif
.get_irq = mpic_get_irq,
- .calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress,
};
diff --git a/target/linux/mpc85xx/image/p1010.mk b/target/linux/mpc85xx/image/p1010.mk
index a4f2d13dd4..1f898c483f 100644
--- a/target/linux/mpc85xx/image/p1010.mk
+++ b/target/linux/mpc85xx/image/p1010.mk
@@ -53,6 +53,7 @@ define Device/tplink_tl-wdr4900-v1
DEVICE_VARIANT := v1
DEVICE_COMPAT_VERSION := 1.1
DEVICE_COMPAT_MESSAGE := Config cannot be migrated from swconfig to DSA
+ DEVICE_PACKAGES := kmod-usb-ledtrig-usbport
TPLINK_HEADER_VERSION := 1
TPLINK_HWID := 0x49000001
TPLINK_HWREV := 1
diff --git a/target/linux/mpc85xx/image/p1020.mk b/target/linux/mpc85xx/image/p1020.mk
index e3902d23d6..c310b26c87 100644
--- a/target/linux/mpc85xx/image/p1020.mk
+++ b/target/linux/mpc85xx/image/p1020.mk
@@ -120,5 +120,7 @@ define Device/ocedo_panda
IMAGES := fdt.bin sysupgrade.bin
IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata
IMAGE/fdt.bin := append-dtb
+ DEVICE_COMPAT_VERSION := 1.1
+ DEVICE_COMPAT_MESSAGE := Config cannot be migrated from swconfig to DSA
endef
TARGET_DEVICES += ocedo_panda
diff --git a/target/linux/mpc85xx/p1010/config-default b/target/linux/mpc85xx/p1010/config-default
index f00fb4d5fd..afa930f4b4 100644
--- a/target/linux/mpc85xx/p1010/config-default
+++ b/target/linux/mpc85xx/p1010/config-default
@@ -1,4 +1,3 @@
-CONFIG_AT803X_PHY=y
CONFIG_BR200_WP=y
CONFIG_CMDLINE_OVERRIDE=y
CONFIG_FIREBOX_T10=y
@@ -21,6 +20,8 @@ CONFIG_NET_DSA_QCA8K_LEDS_SUPPORT=y
CONFIG_NET_DSA_TAG_QCA=y
CONFIG_NET_SWITCHDEV=y
CONFIG_PHYLINK=y
+CONFIG_QCA83XX_PHY=y
+CONFIG_QCOM_NET_PHYLIB=y
CONFIG_REALTEK_PHY=y
CONFIG_RED_15W_REV1=y
CONFIG_REGMAP=y
diff --git a/target/linux/mpc85xx/p1020/config-default b/target/linux/mpc85xx/p1020/config-default
index d1c0532582..36ace8015f 100644
--- a/target/linux/mpc85xx/p1020/config-default
+++ b/target/linux/mpc85xx/p1020/config-default
@@ -1,5 +1,8 @@
CONFIG_ARCH_HAS_TICK_BROADCAST=y
CONFIG_AT803X_PHY=y
+CONFIG_B53=y
+CONFIG_B53_MDIO_DRIVER=y
+CONFIG_BCM_NET_PHYLIB=y
CONFIG_BROADCOM_PHY=y
CONFIG_CMDLINE_OVERRIDE=y
CONFIG_CPU_RMAP=y
@@ -8,6 +11,7 @@ CONFIG_EEPROM_LEGACY=y
CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
CONFIG_GENERIC_TBSYNC=y
CONFIG_GPIO_74X164=y
+CONFIG_GRO_CELLS=y
# CONFIG_GPIO_MAX77620 is not set
CONFIG_HAVE_RCU_TABLE_FREE=y
CONFIG_HIVEAP_330=y
@@ -32,7 +36,15 @@ CONFIG_MTD_UBI_BEB_LIMIT=20
CONFIG_MTD_UBI_BLOCK=y
CONFIG_MTD_UBI_WL_THRESHOLD=4096
CONFIG_MUTEX_SPIN_ON_OWNER=y
+CONFIG_NET_DEVLINK=y
+CONFIG_NET_DSA=y
+CONFIG_NET_DSA_TAG_BRCM=y
+CONFIG_NET_DSA_TAG_BRCM_COMMON=y
+CONFIG_NET_DSA_TAG_BRCM_LEGACY=y
+CONFIG_NET_DSA_TAG_BRCM_PREPEND=y
+CONFIG_NET_DSA_TAG_NONE=y
CONFIG_NET_FLOW_LIMIT=y
+CONFIG_NET_SWITCHDEV=y
CONFIG_NR_CPUS=2
CONFIG_PADATA=y
CONFIG_REGMAP_IRQ=y
@@ -43,13 +55,6 @@ CONFIG_RPS=y
CONFIG_RWSEM_SPIN_ON_OWNER=y
CONFIG_SMP=y
CONFIG_SPI_GPIO=y
-CONFIG_SWCONFIG=y
-CONFIG_SWCONFIG_B53=y
-# CONFIG_SWCONFIG_B53_MMAP_DRIVER is not set
-CONFIG_SWCONFIG_B53_PHY_DRIVER=y
-# CONFIG_SWCONFIG_B53_PHY_FIXUP is not set
-# CONFIG_SWCONFIG_B53_SPI_DRIVER is not set
-# CONFIG_SWCONFIG_B53_SRAB_DRIVER is not set
CONFIG_TREE_RCU=y
CONFIG_UBIFS_FS=y
CONFIG_WS_AP3710I=y
diff --git a/target/linux/mpc85xx/patches-6.1/001-powerpc-85xx-add-gpio-keys-to-of-match-table.patch b/target/linux/mpc85xx/patches-6.1/001-powerpc-85xx-add-gpio-keys-to-of-match-table.patch
deleted file mode 100644
index 5e5ab10daf..0000000000
--- a/target/linux/mpc85xx/patches-6.1/001-powerpc-85xx-add-gpio-keys-to-of-match-table.patch
+++ /dev/null
@@ -1,10 +0,0 @@
---- a/arch/powerpc/platforms/85xx/common.c
-+++ b/arch/powerpc/platforms/85xx/common.c
-@@ -30,6 +30,7 @@ static const struct of_device_id mpc85xx
- { .compatible = "fsl,mpc8548-guts", },
- /* Probably unnecessary? */
- { .compatible = "gpio-leds", },
-+ { .compatible = "gpio-keys", },
- /* For all PCI controllers */
- { .compatible = "fsl,mpc8540-pci", },
- { .compatible = "fsl,mpc8548-pcie", },
diff --git a/target/linux/mpc85xx/patches-6.1/010-powerpc-add-compressed-zImage-for-mpc85xx.patch b/target/linux/mpc85xx/patches-6.1/010-powerpc-add-compressed-zImage-for-mpc85xx.patch
deleted file mode 100644
index 16ef37bd78..0000000000
--- a/target/linux/mpc85xx/patches-6.1/010-powerpc-add-compressed-zImage-for-mpc85xx.patch
+++ /dev/null
@@ -1,61 +0,0 @@
-From b30ba76a980b3a9282f309c23e3bb0b0eb2c72cd Mon Sep 17 00:00:00 2001
-From: David Bauer <mail@david-bauer.net>
-Date: Thu, 30 May 2024 02:55:38 +0200
-Subject: [PATCH] powerpc: add compressed zImage for mpc85xx
-
-Add a universal zImage which can be loaded by mpc85xx boards at
-load address 0x3000000. This allows boards to boot kernels larger than
-16MB even if the image is loaded temporarily from NAND at offset
-0x1000000 which some bootloaders do by default.
-
-Signed-off-by: David Bauer <mail@david-bauer.net>
----
- arch/powerpc/boot/Makefile | 1 +
- arch/powerpc/boot/wrapper | 5 +++++
- 2 files changed, 6 insertions(+)
-
---- a/arch/powerpc/boot/Makefile
-+++ b/arch/powerpc/boot/Makefile
-@@ -175,6 +175,7 @@ src-plat-$(CONFIG_EMBEDDED6xx) += cuboot
- src-plat-$(CONFIG_AMIGAONE) += cuboot-amigaone.c
- src-plat-$(CONFIG_PPC_PS3) += ps3-head.S ps3-hvcall.S ps3.c
- src-plat-$(CONFIG_EPAPR_BOOT) += epapr.c epapr-wrapper.c
-+src-plat-$(CONFIG_PPC_ZIMAGE_LA3000000) += fixed-head.S
- src-plat-$(CONFIG_PPC_PSERIES) += pseries-head.S
- src-plat-$(CONFIG_PPC_POWERNV) += pseries-head.S
- src-plat-$(CONFIG_PPC_IBM_CELL_BLADE) += pseries-head.S
-@@ -345,6 +346,7 @@ image-$(CONFIG_MPC836x_MDS) += cuImage.
- image-$(CONFIG_ASP834x) += dtbImage.asp834x-redboot
-
- # Board ports in arch/powerpc/platform/85xx/Kconfig
-+image-$(CONFIG_PPC_ZIMAGE_LA3000000) += zImage.la3000000
- image-$(CONFIG_MPC8540_ADS) += cuImage.mpc8540ads
- image-$(CONFIG_MPC8560_ADS) += cuImage.mpc8560ads
- image-$(CONFIG_MPC85xx_CDS) += cuImage.mpc8541cds \
---- a/arch/powerpc/boot/wrapper
-+++ b/arch/powerpc/boot/wrapper
-@@ -254,6 +254,11 @@ if [ -n "$esm_blob" -a "$platform" != "p
- fi
-
- case "$platform" in
-+la3000000)
-+ binary=y
-+ platformo="$object/fixed-head.o $object/of.o $object/epapr.o"
-+ link_address='0x3000000'
-+ ;;
- of)
- platformo="$object/of.o $object/epapr.o"
- make_space=n
---- a/arch/powerpc/Kconfig
-+++ b/arch/powerpc/Kconfig
-@@ -74,6 +74,10 @@ config NMI_IPI
- depends on SMP && (DEBUGGER || KEXEC_CORE || HARDLOCKUP_DETECTOR)
- default y
-
-+config PPC_ZIMAGE_LA3000000
-+ bool
-+ default n
-+
- config PPC_WATCHDOG
- bool
- depends on HARDLOCKUP_DETECTOR
diff --git a/target/linux/mpc85xx/patches-6.1/100-powerpc-85xx-tl-wdr4900-v1-support.patch b/target/linux/mpc85xx/patches-6.1/100-powerpc-85xx-tl-wdr4900-v1-support.patch
deleted file mode 100644
index 5f8d84ccee..0000000000
--- a/target/linux/mpc85xx/patches-6.1/100-powerpc-85xx-tl-wdr4900-v1-support.patch
+++ /dev/null
@@ -1,83 +0,0 @@
-From 1d9f596e572917772b87a2a37e1680902964782f Mon Sep 17 00:00:00 2001
-From: Gabor Juhos <juhosg@openwrt.org>
-Date: Wed, 20 Feb 2013 08:40:33 +0100
-Subject: [PATCH] powerpc: 85xx: add support for the TP-Link TL-WDR4900 v1
- board
-
-This patch adds support for the TP-Link TL-WDR4900 v1
-concurrent dual-band wireless router. The devices uses
-the Freescale P1014 SoC.
-
-Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-Signed-off-by: Pawel Dembicki <paweldembicki@gmail.com>
----
- arch/powerpc/boot/Makefile | 3 ++-
- arch/powerpc/boot/wrapper | 5 +++++
- arch/powerpc/platforms/85xx/Kconfig | 12 ++++++++++++
- arch/powerpc/platforms/85xx/Makefile | 1 +
- 4 files changed, 20 insertions(+), 1 deletion(-)
-
---- a/arch/powerpc/boot/Makefile
-+++ b/arch/powerpc/boot/Makefile
-@@ -180,6 +180,7 @@ src-plat-$(CONFIG_PPC_PSERIES) += pserie
- src-plat-$(CONFIG_PPC_POWERNV) += pseries-head.S
- src-plat-$(CONFIG_PPC_IBM_CELL_BLADE) += pseries-head.S
- src-plat-$(CONFIG_MVME7100) += motload-head.S mvme7100.c
-+src-plat-$(CONFIG_TL_WDR4900_V1) += simpleboot.c fixed-head.S
-
- src-plat-$(CONFIG_PPC_MICROWATT) += fixed-head.S microwatt.c
-
-@@ -361,7 +362,7 @@ image-$(CONFIG_TQM8548) += cuImage.tqm
- image-$(CONFIG_TQM8555) += cuImage.tqm8555
- image-$(CONFIG_TQM8560) += cuImage.tqm8560
- image-$(CONFIG_KSI8560) += cuImage.ksi8560
--
-+image-$(CONFIG_TL_WDR4900_V1) += simpleImage.tl-wdr4900-v1
- # Board ports in arch/powerpc/platform/86xx/Kconfig
- image-$(CONFIG_MVME7100) += dtbImage.mvme7100
-
---- a/arch/powerpc/boot/wrapper
-+++ b/arch/powerpc/boot/wrapper
-@@ -346,6 +346,11 @@ adder875-redboot)
- platformo="$object/fixed-head.o $object/redboot-8xx.o"
- binary=y
- ;;
-+simpleboot-tl-wdr4900-v1)
-+ platformo="$object/fixed-head.o $object/simpleboot.o"
-+ link_address='0x1500000'
-+ binary=y
-+ ;;
- simpleboot-*)
- platformo="$object/fixed-head.o $object/simpleboot.o"
- binary=y
---- a/arch/powerpc/platforms/85xx/Kconfig
-+++ b/arch/powerpc/platforms/85xx/Kconfig
-@@ -163,6 +163,18 @@ config STX_GP3
- select CPM2
- select DEFAULT_UIMAGE
-
-+config TL_WDR4900_V1
-+ bool "TP-Link TL-WDR4900 v1"
-+ select DEFAULT_UIMAGE
-+ select ARCH_REQUIRE_GPIOLIB
-+ select GPIO_MPC8XXX
-+ select SWIOTLB
-+ help
-+ This option enables support for the TP-Link TL-WDR4900 v1 board.
-+
-+ This board is a Concurrent Dual-Band wireless router with a
-+ Freescale P1014 SoC.
-+
- config TQM8540
- bool "TQ Components TQM8540"
- help
---- a/arch/powerpc/platforms/85xx/Makefile
-+++ b/arch/powerpc/platforms/85xx/Makefile
-@@ -27,6 +27,7 @@ obj-$(CONFIG_TWR_P102x) += twr_p102x.o
- obj-$(CONFIG_CORENET_GENERIC) += corenet_generic.o
- obj-$(CONFIG_FB_FSL_DIU) += t1042rdb_diu.o
- obj-$(CONFIG_STX_GP3) += stx_gp3.o
-+obj-$(CONFIG_TL_WDR4900_V1) += tl_wdr4900_v1.o
- obj-$(CONFIG_TQM85xx) += tqm85xx.o
- obj-$(CONFIG_PPA8548) += ppa8548.o
- obj-$(CONFIG_SOCRATES) += socrates.o socrates_fpga_pic.o
diff --git a/target/linux/mpc85xx/patches-6.1/101-powerpc-85xx-hiveap-330-support.patch b/target/linux/mpc85xx/patches-6.1/101-powerpc-85xx-hiveap-330-support.patch
deleted file mode 100644
index 18466216c0..0000000000
--- a/target/linux/mpc85xx/patches-6.1/101-powerpc-85xx-hiveap-330-support.patch
+++ /dev/null
@@ -1,58 +0,0 @@
---- a/arch/powerpc/platforms/85xx/Kconfig
-+++ b/arch/powerpc/platforms/85xx/Kconfig
-@@ -40,6 +40,17 @@ config BSC9132_QDS
- and dual StarCore SC3850 DSP cores.
- Manufacturer : Freescale Semiconductor, Inc
-
-+config HIVEAP_330
-+ bool "Aerohive HiveAP-330"
-+ select DEFAULT_UIMAGE
-+ select ARCH_REQUIRE_GPIOLIB
-+ select GPIO_MPC8XXX
-+ help
-+ This option enables support for the Aerohive HiveAP-330 board.
-+
-+ This board is a Concurrent Dual-Band wireless access point with a
-+ Freescale P1020 SoC.
-+
- config MPC8540_ADS
- bool "Freescale MPC8540 ADS"
- select DEFAULT_UIMAGE
---- a/arch/powerpc/platforms/85xx/Makefile
-+++ b/arch/powerpc/platforms/85xx/Makefile
-@@ -12,6 +12,7 @@ obj-y += common.o
- obj-$(CONFIG_BSC9131_RDB) += bsc913x_rdb.o
- obj-$(CONFIG_BSC9132_QDS) += bsc913x_qds.o
- obj-$(CONFIG_C293_PCIE) += c293pcie.o
-+obj-$(CONFIG_HIVEAP_330) += hiveap-330.o
- obj-$(CONFIG_MPC8540_ADS) += mpc85xx_ads.o
- obj-$(CONFIG_MPC8560_ADS) += mpc85xx_ads.o
- obj-$(CONFIG_MPC85xx_CDS) += mpc85xx_cds.o
---- a/arch/powerpc/boot/Makefile
-+++ b/arch/powerpc/boot/Makefile
-@@ -180,6 +180,7 @@ src-plat-$(CONFIG_PPC_PSERIES) += pserie
- src-plat-$(CONFIG_PPC_POWERNV) += pseries-head.S
- src-plat-$(CONFIG_PPC_IBM_CELL_BLADE) += pseries-head.S
- src-plat-$(CONFIG_MVME7100) += motload-head.S mvme7100.c
-+src-plat-$(CONFIG_HIVEAP_330) += simpleboot.c fixed-head.S
- src-plat-$(CONFIG_TL_WDR4900_V1) += simpleboot.c fixed-head.S
-
- src-plat-$(CONFIG_PPC_MICROWATT) += fixed-head.S microwatt.c
-@@ -362,6 +363,7 @@ image-$(CONFIG_TQM8548) += cuImage.tqm
- image-$(CONFIG_TQM8555) += cuImage.tqm8555
- image-$(CONFIG_TQM8560) += cuImage.tqm8560
- image-$(CONFIG_KSI8560) += cuImage.ksi8560
-+image-$(CONFIG_HIVEAP_330) += simpleImage.hiveap-330
- image-$(CONFIG_TL_WDR4900_V1) += simpleImage.tl-wdr4900-v1
- # Board ports in arch/powerpc/platform/86xx/Kconfig
- image-$(CONFIG_MVME7100) += dtbImage.mvme7100
---- a/arch/powerpc/boot/wrapper
-+++ b/arch/powerpc/boot/wrapper
-@@ -346,6 +346,7 @@ adder875-redboot)
- platformo="$object/fixed-head.o $object/redboot-8xx.o"
- binary=y
- ;;
-+simpleboot-hiveap-330|\
- simpleboot-tl-wdr4900-v1)
- platformo="$object/fixed-head.o $object/simpleboot.o"
- link_address='0x1500000'
diff --git a/target/linux/mpc85xx/patches-6.1/102-powerpc-add-cmdline-override.patch b/target/linux/mpc85xx/patches-6.1/102-powerpc-add-cmdline-override.patch
deleted file mode 100644
index 2ac10eae8e..0000000000
--- a/target/linux/mpc85xx/patches-6.1/102-powerpc-add-cmdline-override.patch
+++ /dev/null
@@ -1,37 +0,0 @@
---- a/arch/powerpc/Kconfig
-+++ b/arch/powerpc/Kconfig
-@@ -958,6 +958,14 @@ config CMDLINE_FORCE
-
- endchoice
-
-+config CMDLINE_OVERRIDE
-+ bool "Use alternative cmdline from device tree"
-+ help
-+ Some bootloaders may have uneditable bootargs. While CMDLINE_FORCE can
-+ be used, this is not a good option for kernels that are shared across
-+ devices. This setting enables using "chosen/cmdline-override" as the
-+ cmdline if it exists in the device tree.
-+
- config EXTRA_TARGETS
- string "Additional default image types"
- help
---- a/drivers/of/fdt.c
-+++ b/drivers/of/fdt.c
-@@ -1187,6 +1187,17 @@ int __init early_init_dt_scan_chosen(cha
- if (p != NULL && l > 0)
- strlcat(cmdline, p, min_t(int, strlen(cmdline) + (int)l, COMMAND_LINE_SIZE));
-
-+ /* CONFIG_CMDLINE_OVERRIDE is used to fallback to a different
-+ * device tree option of chosen/bootargs-override. This is
-+ * helpful on boards where u-boot sets bootargs, and is unable
-+ * to be modified.
-+ */
-+#ifdef CONFIG_CMDLINE_OVERRIDE
-+ p = of_get_flat_dt_prop(node, "bootargs-override", &l);
-+ if (p != NULL && l > 0)
-+ strlcpy(cmdline, p, min((int)l, COMMAND_LINE_SIZE));
-+#endif
-+
- handle_cmdline:
- /*
- * CONFIG_CMDLINE is meant to be a default in case nothing else
diff --git a/target/linux/mpc85xx/patches-6.1/103-powerpc-85xx-red-15w-rev1.patch b/target/linux/mpc85xx/patches-6.1/103-powerpc-85xx-red-15w-rev1.patch
deleted file mode 100644
index 711d98abe7..0000000000
--- a/target/linux/mpc85xx/patches-6.1/103-powerpc-85xx-red-15w-rev1.patch
+++ /dev/null
@@ -1,29 +0,0 @@
---- a/arch/powerpc/platforms/85xx/Kconfig
-+++ b/arch/powerpc/platforms/85xx/Kconfig
-@@ -166,6 +166,16 @@ config XES_MPC85xx
- Manufacturer: Extreme Engineering Solutions, Inc.
- URL: <https://www.xes-inc.com/>
-
-+config RED_15W_REV1
-+ bool "Sophos RED 15w Rev.1"
-+ select DEFAULT_UIMAGE
-+ select ARCH_REQUIRE_GPIOLIB
-+ select GPIO_MPC8XXX
-+ help
-+ This option enables support for the Sophos RED 15w Rev.1 board.
-+
-+ This board is a wireless VPN router with a Freescale P1010 SoC.
-+
- config STX_GP3
- bool "Silicon Turnkey Express GP3"
- help
---- a/arch/powerpc/platforms/85xx/Makefile
-+++ b/arch/powerpc/platforms/85xx/Makefile
-@@ -27,6 +27,7 @@ obj-$(CONFIG_P1023_RDB) += p1023_rdb.o
- obj-$(CONFIG_TWR_P102x) += twr_p102x.o
- obj-$(CONFIG_CORENET_GENERIC) += corenet_generic.o
- obj-$(CONFIG_FB_FSL_DIU) += t1042rdb_diu.o
-+obj-$(CONFIG_RED_15W_REV1) += red15w_rev1.o
- obj-$(CONFIG_STX_GP3) += stx_gp3.o
- obj-$(CONFIG_TL_WDR4900_V1) += tl_wdr4900_v1.o
- obj-$(CONFIG_TQM85xx) += tqm85xx.o
diff --git a/target/linux/mpc85xx/patches-6.1/104-powerpc-mpc85xx-change-P2020RDB-dts-file-for-OpenWRT.patch b/target/linux/mpc85xx/patches-6.1/104-powerpc-mpc85xx-change-P2020RDB-dts-file-for-OpenWRT.patch
deleted file mode 100644
index 94ed26c3df..0000000000
--- a/target/linux/mpc85xx/patches-6.1/104-powerpc-mpc85xx-change-P2020RDB-dts-file-for-OpenWRT.patch
+++ /dev/null
@@ -1,170 +0,0 @@
-From 93514afd769c305182beeed1f9c4c46235879ef8 Mon Sep 17 00:00:00 2001
-From: Pawel Dembicki <paweldembicki@gmail.com>
-Date: Sun, 30 Dec 2018 23:24:41 +0100
-Subject: [PATCH] powerpc: mpc85xx: change P2020RDB dts file for OpenWRT
-
-This patch apply chages for OpenWRT in P2020RDB
-dts file.
-
-Signed-off-by: Pawel Dembicki <paweldembicki@gmail.com>
----
- arch/powerpc/boot/dts/fsl/p2020rdb.dts | 98 +++++++++++++++++---------
- 1 file changed, 63 insertions(+), 35 deletions(-)
-
---- a/arch/powerpc/boot/dts/fsl/p2020rdb.dts
-+++ b/arch/powerpc/boot/dts/fsl/p2020rdb.dts
-@@ -5,10 +5,15 @@
- * Copyright 2009-2012 Freescale Semiconductor Inc.
- */
-
-+/dts-v1/;
-+
- /include/ "p2020si-pre.dtsi"
-
-+#include <dt-bindings/gpio/gpio.h>
-+#include <dt-bindings/input/input.h>
-+
- / {
-- model = "fsl,P2020RDB";
-+ model = "Freescale P2020RDB";
- compatible = "fsl,P2020RDB";
-
- aliases {
-@@ -34,48 +39,38 @@
- 0x2 0x0 0x0 0xffb00000 0x00020000>;
-
- nor@0,0 {
-- #address-cells = <1>;
-- #size-cells = <1>;
- compatible = "cfi-flash";
- reg = <0x0 0x0 0x1000000>;
- bank-width = <2>;
- device-width = <1>;
-
-- partition@0 {
-- /* This location must not be altered */
-- /* 256KB for Vitesse 7385 Switch firmware */
-- reg = <0x0 0x00040000>;
-- label = "NOR (RO) Vitesse-7385 Firmware";
-- read-only;
-- };
--
-- partition@40000 {
-- /* 256KB for DTB Image */
-- reg = <0x00040000 0x00040000>;
-- label = "NOR (RO) DTB Image";
-- read-only;
-- };
-+ partitions {
-+ compatible = "fixed-partitions";
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-
-- partition@80000 {
-- /* 3.5 MB for Linux Kernel Image */
-- reg = <0x00080000 0x00380000>;
-- label = "NOR (RO) Linux Kernel Image";
-- read-only;
-- };
-+ partition@0 {
-+ /* This location must not be altered */
-+ /* 256KB for Vitesse 7385 Switch firmware */
-+ reg = <0x0 0x00040000>;
-+ label = "NOR (RO) Vitesse-7385 Firmware";
-+ read-only;
-+ };
-
-- partition@400000 {
-- /* 11MB for JFFS2 based Root file System */
-- reg = <0x00400000 0x00b00000>;
-- label = "NOR (RW) JFFS2 Root File System";
-- };
-+ partition@40000 {
-+ compatible = "denx,fit";
-+ reg = <0x00040000 0x00ec0000>;
-+ label = "firmware";
-+ };
-
-- partition@f00000 {
-- /* This location must not be altered */
-- /* 512KB for u-boot Bootloader Image */
-- /* 512KB for u-boot Environment Variables */
-- reg = <0x00f00000 0x00100000>;
-- label = "NOR (RO) U-Boot Image";
-- read-only;
-+ partition@f00000 {
-+ /* This location must not be altered */
-+ /* 512KB for u-boot Bootloader Image */
-+ /* 512KB for u-boot Environment Variables */
-+ reg = <0x00f00000 0x00100000>;
-+ label = "u-boot";
-+ read-only;
-+ };
- };
- };
-
-@@ -85,6 +80,7 @@
- compatible = "fsl,p2020-fcm-nand",
- "fsl,elbc-fcm-nand";
- reg = <0x1 0x0 0x40000>;
-+ nand-ecc-mode = "none";
-
- partition@0 {
- /* This location must not be altered */
-@@ -140,13 +136,43 @@
- soc: soc@ffe00000 {
- ranges = <0x0 0x0 0xffe00000 0x100000>;
-
-+ gpio0: gpio-controller@fc00 {
-+ };
-+
- i2c@3000 {
-+ temperature-sensor@4c {
-+ compatible = "adi,adt7461";
-+ reg = <0x4c>;
-+ };
-+
-+ eeprom@50 {
-+ compatible = "atmel,24c256";
-+ reg = <0x50>;
-+ };
-+
- rtc@68 {
- compatible = "dallas,ds1339";
- reg = <0x68>;
- };
- };
-
-+ i2c@3100 {
-+ pmic@11 {
-+ compatible = "zl2006";
-+ reg = <0x11>;
-+ };
-+
-+ gpio@18 {
-+ compatible = "nxp,pca9557";
-+ reg = <0x18>;
-+ };
-+
-+ eeprom@52 {
-+ compatible = "atmel,24c01";
-+ reg = <0x52>;
-+ };
-+ };
-+
- spi@7000 {
- flash@0 {
- #address-cells = <1>;
-@@ -200,10 +226,12 @@
- phy0: ethernet-phy@0 {
- interrupts = <3 1 0 0>;
- reg = <0x0>;
-+ reset-gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
- };
- phy1: ethernet-phy@1 {
- interrupts = <3 1 0 0>;
- reg = <0x1>;
-+ reset-gpios = <&gpio0 6 GPIO_ACTIVE_LOW>;
- };
- tbi-phy@2 {
- device_type = "tbi-phy";
diff --git a/target/linux/mpc85xx/patches-6.1/105-powerpc-85xx-panda-support.patch b/target/linux/mpc85xx/patches-6.1/105-powerpc-85xx-panda-support.patch
deleted file mode 100644
index 3c24a373ab..0000000000
--- a/target/linux/mpc85xx/patches-6.1/105-powerpc-85xx-panda-support.patch
+++ /dev/null
@@ -1,30 +0,0 @@
---- a/arch/powerpc/platforms/85xx/Kconfig
-+++ b/arch/powerpc/platforms/85xx/Kconfig
-@@ -51,6 +51,17 @@ config HIVEAP_330
- This board is a Concurrent Dual-Band wireless access point with a
- Freescale P1020 SoC.
-
-+config PANDA
-+ bool "OCEDO PANDA"
-+ select DEFAULT_UIMAGE
-+ select ARCH_REQUIRE_GPIOLIB
-+ select GPIO_MPC8XXX
-+ help
-+ This option enables support for the OCEDO PANDA board.
-+
-+ This board is a Concurrent Dual-Band wireless access point with a
-+ Freescale P1020 SoC.
-+
- config MPC8540_ADS
- bool "Freescale MPC8540 ADS"
- select DEFAULT_UIMAGE
---- a/arch/powerpc/platforms/85xx/Makefile
-+++ b/arch/powerpc/platforms/85xx/Makefile
-@@ -24,6 +24,7 @@ obj-$(CONFIG_P1010_RDB) += p1010rdb.o
- obj-$(CONFIG_P1022_DS) += p1022_ds.o
- obj-$(CONFIG_P1022_RDK) += p1022_rdk.o
- obj-$(CONFIG_P1023_RDB) += p1023_rdb.o
-+obj-$(CONFIG_PANDA) += panda.o
- obj-$(CONFIG_TWR_P102x) += twr_p102x.o
- obj-$(CONFIG_CORENET_GENERIC) += corenet_generic.o
- obj-$(CONFIG_FB_FSL_DIU) += t1042rdb_diu.o
diff --git a/target/linux/mpc85xx/patches-6.1/106-powerpc-85xx-ws-ap3710i-support.patch b/target/linux/mpc85xx/patches-6.1/106-powerpc-85xx-ws-ap3710i-support.patch
deleted file mode 100644
index 742fe7c2c0..0000000000
--- a/target/linux/mpc85xx/patches-6.1/106-powerpc-85xx-ws-ap3710i-support.patch
+++ /dev/null
@@ -1,60 +0,0 @@
---- a/arch/powerpc/platforms/85xx/Kconfig
-+++ b/arch/powerpc/platforms/85xx/Kconfig
-@@ -62,6 +62,17 @@ config PANDA
- This board is a Concurrent Dual-Band wireless access point with a
- Freescale P1020 SoC.
-
-+config WS_AP3710I
-+ bool "Enterasys WS-AP3710i"
-+ select DEFAULT_UIMAGE
-+ select ARCH_REQUIRE_GPIOLIB
-+ select GPIO_MPC8XXX
-+ help
-+ This option enables support for the Enterasys WS-AP3710i board.
-+
-+ This board is a Concurrent Dual-Band wireless access point with a
-+ Freescale P1020 SoC.
-+
- config MPC8540_ADS
- bool "Freescale MPC8540 ADS"
- select DEFAULT_UIMAGE
---- a/arch/powerpc/platforms/85xx/Makefile
-+++ b/arch/powerpc/platforms/85xx/Makefile
-@@ -26,6 +26,7 @@ obj-$(CONFIG_P1022_RDK) += p1022_rdk.o
- obj-$(CONFIG_P1023_RDB) += p1023_rdb.o
- obj-$(CONFIG_PANDA) += panda.o
- obj-$(CONFIG_TWR_P102x) += twr_p102x.o
-+obj-$(CONFIG_WS_AP3710I) += ws-ap3710i.o
- obj-$(CONFIG_CORENET_GENERIC) += corenet_generic.o
- obj-$(CONFIG_FB_FSL_DIU) += t1042rdb_diu.o
- obj-$(CONFIG_RED_15W_REV1) += red15w_rev1.o
---- a/arch/powerpc/boot/Makefile
-+++ b/arch/powerpc/boot/Makefile
-@@ -182,6 +182,7 @@ src-plat-$(CONFIG_PPC_IBM_CELL_BLADE) +=
- src-plat-$(CONFIG_MVME7100) += motload-head.S mvme7100.c
- src-plat-$(CONFIG_HIVEAP_330) += simpleboot.c fixed-head.S
- src-plat-$(CONFIG_TL_WDR4900_V1) += simpleboot.c fixed-head.S
-+src-plat-$(CONFIG_WS_AP3710I) += simpleboot.c fixed-head.S
-
- src-plat-$(CONFIG_PPC_MICROWATT) += fixed-head.S microwatt.c
-
-@@ -365,6 +366,7 @@ image-$(CONFIG_TQM8560) += cuImage.tqm
- image-$(CONFIG_KSI8560) += cuImage.ksi8560
- image-$(CONFIG_HIVEAP_330) += simpleImage.hiveap-330
- image-$(CONFIG_TL_WDR4900_V1) += simpleImage.tl-wdr4900-v1
-+image-$(CONFIG_WS_AP3710I) += simpleImage.ws-ap3710i
- # Board ports in arch/powerpc/platform/86xx/Kconfig
- image-$(CONFIG_MVME7100) += dtbImage.mvme7100
-
---- a/arch/powerpc/boot/wrapper
-+++ b/arch/powerpc/boot/wrapper
-@@ -347,7 +347,8 @@ adder875-redboot)
- binary=y
- ;;
- simpleboot-hiveap-330|\
--simpleboot-tl-wdr4900-v1)
-+simpleboot-tl-wdr4900-v1|\
-+simpleboot-ws-ap3710i)
- platformo="$object/fixed-head.o $object/simpleboot.o"
- link_address='0x1500000'
- binary=y
diff --git a/target/linux/mpc85xx/patches-6.1/107-powerpc-85xx-add-ws-ap3825i-support.patch b/target/linux/mpc85xx/patches-6.1/107-powerpc-85xx-add-ws-ap3825i-support.patch
deleted file mode 100644
index 346001271b..0000000000
--- a/target/linux/mpc85xx/patches-6.1/107-powerpc-85xx-add-ws-ap3825i-support.patch
+++ /dev/null
@@ -1,67 +0,0 @@
-From 2fa1a7983ef30f3c7486f9b07c001bee87d1f6d6 Mon Sep 17 00:00:00 2001
-From: Martin Kennedy <hurricos@gmail.com>
-Date: Sat, 1 Jan 2022 11:01:37 -0500
-Subject: [PATCH] PowerPC 85xx: Add WS-AP3825i support
-
-This patch adds support for building Linux for the Extreme Networks
-WS-AP3825i AP.
-
---- a/arch/powerpc/platforms/85xx/Kconfig
-+++ b/arch/powerpc/platforms/85xx/Kconfig
-@@ -73,6 +73,16 @@ config WS_AP3710I
- This board is a Concurrent Dual-Band wireless access point with a
- Freescale P1020 SoC.
-
-+config WS_AP3825I
-+ bool "Extreme Networks WS-AP3825i"
-+ select DEFAULT_UIMAGE
-+ select ARCH_REQUIRE_GPIOLIB
-+ select GPIO_MPC8XXX
-+ help
-+ This option enables support for the Extreme Networks WS-AP3825i board.
-+ This board is a Concurrent Dual-Band wireless access point with a
-+ Freescale P1020 SoC.
-+
- config MPC8540_ADS
- bool "Freescale MPC8540 ADS"
- select DEFAULT_UIMAGE
---- a/arch/powerpc/platforms/85xx/Makefile
-+++ b/arch/powerpc/platforms/85xx/Makefile
-@@ -27,6 +27,7 @@ obj-$(CONFIG_P1023_RDB) += p1023_rdb.o
- obj-$(CONFIG_PANDA) += panda.o
- obj-$(CONFIG_TWR_P102x) += twr_p102x.o
- obj-$(CONFIG_WS_AP3710I) += ws-ap3710i.o
-+obj-$(CONFIG_WS_AP3825I) += ws-ap3825i.o
- obj-$(CONFIG_CORENET_GENERIC) += corenet_generic.o
- obj-$(CONFIG_FB_FSL_DIU) += t1042rdb_diu.o
- obj-$(CONFIG_RED_15W_REV1) += red15w_rev1.o
---- a/arch/powerpc/boot/Makefile
-+++ b/arch/powerpc/boot/Makefile
-@@ -183,6 +183,7 @@ src-plat-$(CONFIG_MVME7100) += motload-h
- src-plat-$(CONFIG_HIVEAP_330) += simpleboot.c fixed-head.S
- src-plat-$(CONFIG_TL_WDR4900_V1) += simpleboot.c fixed-head.S
- src-plat-$(CONFIG_WS_AP3710I) += simpleboot.c fixed-head.S
-+src-plat-$(CONFIG_WS_AP3825I) += simpleboot.c fixed-head.S
-
- src-plat-$(CONFIG_PPC_MICROWATT) += fixed-head.S microwatt.c
-
-@@ -367,6 +368,7 @@ image-$(CONFIG_KSI8560) += cuImage.ksi
- image-$(CONFIG_HIVEAP_330) += simpleImage.hiveap-330
- image-$(CONFIG_TL_WDR4900_V1) += simpleImage.tl-wdr4900-v1
- image-$(CONFIG_WS_AP3710I) += simpleImage.ws-ap3710i
-+image-$(CONFIG_WS_AP3825I) += simpleImage.ws-ap3825i
- # Board ports in arch/powerpc/platform/86xx/Kconfig
- image-$(CONFIG_MVME7100) += dtbImage.mvme7100
-
---- a/arch/powerpc/boot/wrapper
-+++ b/arch/powerpc/boot/wrapper
-@@ -348,7 +348,8 @@ adder875-redboot)
- ;;
- simpleboot-hiveap-330|\
- simpleboot-tl-wdr4900-v1|\
--simpleboot-ws-ap3710i)
-+simpleboot-ws-ap3710i|\
-+simpleboot-ws-ap3825i)
- platformo="$object/fixed-head.o $object/simpleboot.o"
- link_address='0x1500000'
- binary=y
diff --git a/target/linux/mpc85xx/patches-6.1/108-powerpc-85xx-firebox-t10-support.patch.patch b/target/linux/mpc85xx/patches-6.1/108-powerpc-85xx-firebox-t10-support.patch.patch
deleted file mode 100644
index 0b3a93b848..0000000000
--- a/target/linux/mpc85xx/patches-6.1/108-powerpc-85xx-firebox-t10-support.patch.patch
+++ /dev/null
@@ -1,29 +0,0 @@
---- a/arch/powerpc/platforms/85xx/Kconfig
-+++ b/arch/powerpc/platforms/85xx/Kconfig
-@@ -83,6 +83,16 @@ config WS_AP3825I
- This board is a Concurrent Dual-Band wireless access point with a
- Freescale P1020 SoC.
-
-+config FIREBOX_T10
-+ bool "Watchguard Firebox T10"
-+ select DEFAULT_UIMAGE
-+ select ARCH_REQUIRE_GPIOLIB
-+ select GPIO_MPC8XXX
-+ help
-+ This option enables support for the Watchguard Firebox T10 board.
-+ This board is a VPN Gateway-Router with a
-+ Freescale P1010 SoC.
-+
- config MPC8540_ADS
- bool "Freescale MPC8540 ADS"
- select DEFAULT_UIMAGE
---- a/arch/powerpc/platforms/85xx/Makefile
-+++ b/arch/powerpc/platforms/85xx/Makefile
-@@ -28,6 +28,7 @@ obj-$(CONFIG_PANDA) += panda.o
- obj-$(CONFIG_TWR_P102x) += twr_p102x.o
- obj-$(CONFIG_WS_AP3710I) += ws-ap3710i.o
- obj-$(CONFIG_WS_AP3825I) += ws-ap3825i.o
-+obj-$(CONFIG_FIREBOX_T10) += firebox_t10.o
- obj-$(CONFIG_CORENET_GENERIC) += corenet_generic.o
- obj-$(CONFIG_FB_FSL_DIU) += t1042rdb_diu.o
- obj-$(CONFIG_RED_15W_REV1) += red15w_rev1.o
diff --git a/target/linux/mpc85xx/patches-6.1/109-powerpc-85xx-add-ws-ap3715i-support.patch b/target/linux/mpc85xx/patches-6.1/109-powerpc-85xx-add-ws-ap3715i-support.patch
deleted file mode 100644
index a9f7079866..0000000000
--- a/target/linux/mpc85xx/patches-6.1/109-powerpc-85xx-add-ws-ap3715i-support.patch
+++ /dev/null
@@ -1,48 +0,0 @@
---- a/arch/powerpc/platforms/85xx/Kconfig
-+++ b/arch/powerpc/platforms/85xx/Kconfig
-@@ -73,6 +73,17 @@ config WS_AP3710I
- This board is a Concurrent Dual-Band wireless access point with a
- Freescale P1020 SoC.
-
-+config WS_AP3715I
-+ bool "Enterasys WS-AP3715i"
-+ select DEFAULT_UIMAGE
-+ select ARCH_REQUIRE_GPIOLIB
-+ select GPIO_MPC8XXX
-+ help
-+ This option enables support for the Enterasys WS-AP3715i board.
-+
-+ This board is a Concurrent Dual-Band wireless access point with a
-+ Freescale P1010 SoC.
-+
- config WS_AP3825I
- bool "Extreme Networks WS-AP3825i"
- select DEFAULT_UIMAGE
---- a/arch/powerpc/platforms/85xx/Makefile
-+++ b/arch/powerpc/platforms/85xx/Makefile
-@@ -27,6 +27,7 @@ obj-$(CONFIG_P1023_RDB) += p1023_rdb.o
- obj-$(CONFIG_PANDA) += panda.o
- obj-$(CONFIG_TWR_P102x) += twr_p102x.o
- obj-$(CONFIG_WS_AP3710I) += ws-ap3710i.o
-+obj-$(CONFIG_WS_AP3715I) += ws-ap3715i.o
- obj-$(CONFIG_WS_AP3825I) += ws-ap3825i.o
- obj-$(CONFIG_FIREBOX_T10) += firebox_t10.o
- obj-$(CONFIG_CORENET_GENERIC) += corenet_generic.o
---- a/arch/powerpc/boot/Makefile
-+++ b/arch/powerpc/boot/Makefile
-@@ -183,6 +183,7 @@ src-plat-$(CONFIG_MVME7100) += motload-h
- src-plat-$(CONFIG_HIVEAP_330) += simpleboot.c fixed-head.S
- src-plat-$(CONFIG_TL_WDR4900_V1) += simpleboot.c fixed-head.S
- src-plat-$(CONFIG_WS_AP3710I) += simpleboot.c fixed-head.S
-+src-plat-$(CONFIG_WS_AP3715I) += simpleboot.c fixed-head.S
- src-plat-$(CONFIG_WS_AP3825I) += simpleboot.c fixed-head.S
-
- src-plat-$(CONFIG_PPC_MICROWATT) += fixed-head.S microwatt.c
-@@ -368,6 +369,7 @@ image-$(CONFIG_KSI8560) += cuImage.ksi
- image-$(CONFIG_HIVEAP_330) += simpleImage.hiveap-330
- image-$(CONFIG_TL_WDR4900_V1) += simpleImage.tl-wdr4900-v1
- image-$(CONFIG_WS_AP3710I) += simpleImage.ws-ap3710i
-+image-$(CONFIG_WS_AP3715I) += simpleImage.ws-ap3715i
- image-$(CONFIG_WS_AP3825I) += simpleImage.ws-ap3825i
- # Board ports in arch/powerpc/platform/86xx/Kconfig
- image-$(CONFIG_MVME7100) += dtbImage.mvme7100
diff --git a/target/linux/mpc85xx/patches-6.1/110-powerpc-85xx-br200-wp-support.patch b/target/linux/mpc85xx/patches-6.1/110-powerpc-85xx-br200-wp-support.patch
deleted file mode 100644
index a58d12aef2..0000000000
--- a/target/linux/mpc85xx/patches-6.1/110-powerpc-85xx-br200-wp-support.patch
+++ /dev/null
@@ -1,57 +0,0 @@
---- a/arch/powerpc/platforms/85xx/Kconfig
-+++ b/arch/powerpc/platforms/85xx/Kconfig
-@@ -40,6 +40,16 @@ config BSC9132_QDS
- and dual StarCore SC3850 DSP cores.
- Manufacturer : Freescale Semiconductor, Inc
-
-+config BR200_WP
-+ bool "Aerohive BR200-WP"
-+ select DEFAULT_UIMAGE
-+ select ARCH_REQUIRE_GPIOLIB
-+ select GPIO_MPC8XXX
-+ help
-+ This option enables support for the Aerohive BR200-WP board.
-+
-+ This board is a wireless router with a Freescale P1011 SoC.
-+
- config HIVEAP_330
- bool "Aerohive HiveAP-330"
- select DEFAULT_UIMAGE
---- a/arch/powerpc/platforms/85xx/Makefile
-+++ b/arch/powerpc/platforms/85xx/Makefile
-@@ -12,6 +12,7 @@ obj-y += common.o
- obj-$(CONFIG_BSC9131_RDB) += bsc913x_rdb.o
- obj-$(CONFIG_BSC9132_QDS) += bsc913x_qds.o
- obj-$(CONFIG_C293_PCIE) += c293pcie.o
-+obj-$(CONFIG_BR200_WP) += br200-wp.o
- obj-$(CONFIG_HIVEAP_330) += hiveap-330.o
- obj-$(CONFIG_MPC8540_ADS) += mpc85xx_ads.o
- obj-$(CONFIG_MPC8560_ADS) += mpc85xx_ads.o
---- a/arch/powerpc/boot/Makefile
-+++ b/arch/powerpc/boot/Makefile
-@@ -180,6 +180,7 @@ src-plat-$(CONFIG_PPC_PSERIES) += pserie
- src-plat-$(CONFIG_PPC_POWERNV) += pseries-head.S
- src-plat-$(CONFIG_PPC_IBM_CELL_BLADE) += pseries-head.S
- src-plat-$(CONFIG_MVME7100) += motload-head.S mvme7100.c
-+src-plat-$(CONFIG_BR200_WP) += simpleboot.c fixed-head.S
- src-plat-$(CONFIG_HIVEAP_330) += simpleboot.c fixed-head.S
- src-plat-$(CONFIG_TL_WDR4900_V1) += simpleboot.c fixed-head.S
- src-plat-$(CONFIG_WS_AP3710I) += simpleboot.c fixed-head.S
-@@ -366,6 +367,7 @@ image-$(CONFIG_TQM8548) += cuImage.tqm
- image-$(CONFIG_TQM8555) += cuImage.tqm8555
- image-$(CONFIG_TQM8560) += cuImage.tqm8560
- image-$(CONFIG_KSI8560) += cuImage.ksi8560
-+image-$(CONFIG_BR200_WP) += simpleImage.br200-wp
- image-$(CONFIG_HIVEAP_330) += simpleImage.hiveap-330
- image-$(CONFIG_TL_WDR4900_V1) += simpleImage.tl-wdr4900-v1
- image-$(CONFIG_WS_AP3710I) += simpleImage.ws-ap3710i
---- a/arch/powerpc/boot/wrapper
-+++ b/arch/powerpc/boot/wrapper
-@@ -346,6 +346,7 @@ adder875-redboot)
- platformo="$object/fixed-head.o $object/redboot-8xx.o"
- binary=y
- ;;
-+simpleboot-br200-wp|\
- simpleboot-hiveap-330|\
- simpleboot-tl-wdr4900-v1|\
- simpleboot-ws-ap3710i|\
diff --git a/target/linux/mpc85xx/patches-6.1/111-powerpc-85xx-hpe-msm-support.patch b/target/linux/mpc85xx/patches-6.1/111-powerpc-85xx-hpe-msm-support.patch
deleted file mode 100644
index 4b9c6f8219..0000000000
--- a/target/linux/mpc85xx/patches-6.1/111-powerpc-85xx-hpe-msm-support.patch
+++ /dev/null
@@ -1,31 +0,0 @@
---- a/arch/powerpc/platforms/85xx/Kconfig
-+++ b/arch/powerpc/platforms/85xx/Kconfig
-@@ -114,6 +114,18 @@ config FIREBOX_T10
- This board is a VPN Gateway-Router with a
- Freescale P1010 SoC.
-
-+config MSM460
-+ bool "HPE MSM460"
-+ select DEFAULT_UIMAGE
-+ select ARCH_REQUIRE_GPIOLIB
-+ select GPIO_MPC8XXX
-+ select PPC_ZIMAGE_LA3000000
-+ help
-+ This option enables support for the HPE MSM460 board.
-+
-+ This board is a Concurrent Dual-Band wireless access point with a
-+ Freescale P1020 SoC.
-+
- config MPC8540_ADS
- bool "Freescale MPC8540 ADS"
- select DEFAULT_UIMAGE
---- a/arch/powerpc/platforms/85xx/Makefile
-+++ b/arch/powerpc/platforms/85xx/Makefile
-@@ -21,6 +21,7 @@ obj-$(CONFIG_MPC8536_DS) += mpc8536_ds.
- obj-$(CONFIG_MPC85xx_DS) += mpc85xx_ds.o
- obj-$(CONFIG_MPC85xx_MDS) += mpc85xx_mds.o
- obj-$(CONFIG_MPC85xx_RDB) += mpc85xx_rdb.o
-+obj-$(CONFIG_MSM460) += msm460.o
- obj-$(CONFIG_P1010_RDB) += p1010rdb.o
- obj-$(CONFIG_P1022_DS) += p1022_ds.o
- obj-$(CONFIG_P1022_RDK) += p1022_rdk.o
diff --git a/target/linux/mpc85xx/patches-6.1/150-arch-powerpc-simpleboot-prevent-overwrite-of-CPU1-sp.patch b/target/linux/mpc85xx/patches-6.1/150-arch-powerpc-simpleboot-prevent-overwrite-of-CPU1-sp.patch
deleted file mode 100644
index 1ff80a5016..0000000000
--- a/target/linux/mpc85xx/patches-6.1/150-arch-powerpc-simpleboot-prevent-overwrite-of-CPU1-sp.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From 5f856ccc34df25060d36a5a81b7b45b574d86e35 Mon Sep 17 00:00:00 2001
-From: David Bauer <mail@david-bauer.net>
-Date: Sun, 3 Dec 2023 20:09:24 +0100
-Subject: [PATCH] arch: powerpc: simpleboot: prevent overwrite of CPU1
- spin-table
-
-Don't overwrite the spin-table of additional CPU cores with loader-heap.
-
-U-Boot places the spin-table for CPU1 on P1020 SoCs in the top 1MB of
-system-memory. Instead of parsing reserved-memory (which would be
-considerable more work), reduce the available system-memory for the
-loader by 1MB.
-
-This prevents the loader from overwriting the spin-table of
-additional CPU cores on these platforms.
-
-Linux itself needs to be made aware by this using reserved-memory
-definitions.
-
-This patch is required for using CPU1 on the Extreme Networks
-WS-AP3825i.
-
-Signed-off-by: David Bauer <mail@david-bauer.net>
----
- arch/powerpc/boot/simpleboot.c | 5 +++++
- 1 file changed, 5 insertions(+)
-
---- a/arch/powerpc/boot/simpleboot.c
-+++ b/arch/powerpc/boot/simpleboot.c
-@@ -65,6 +65,11 @@ void platform_init(unsigned long r3, uns
- if (sizeof(void *) == 4 && memsize64 >= 0x100000000ULL)
- memsize64 = 0xffffffff;
-
-+ /* Reserve upper 1 MB of memory for CPU1 spin-table */
-+ if (memsize64 > 0x100000) {
-+ memsize64 = memsize64 - 0x100000;
-+ }
-+
- /* finally, setup the timebase */
- node = fdt_node_offset_by_prop_value(_dtb_start, -1, "device_type",
- "cpu", sizeof("cpu"));
diff --git a/target/linux/mpc85xx/patches-6.1/900-powerpc-bootwrapper-disable-uImage-generation.patch b/target/linux/mpc85xx/patches-6.1/900-powerpc-bootwrapper-disable-uImage-generation.patch
deleted file mode 100644
index a997a1b9b7..0000000000
--- a/target/linux/mpc85xx/patches-6.1/900-powerpc-bootwrapper-disable-uImage-generation.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-From d43ab14605510d9d2bd257a8cd70f24ada4621b0 Mon Sep 17 00:00:00 2001
-From: David Bauer <mail@david-bauer.net>
-Date: Sat, 29 Feb 2020 14:27:04 +0100
-Subject: [PATCH] powerpc: bootwrapper: disable uImage generation
-
-Due to CONFIG_KERNEL_XZ symbol, the bootwrapper code tries to
-instruct the mkimage to use the xz compression, which isn't
-supported. This disables the uImage generation, as OpenWrt
-generates individual uImages for each board using it's own
-toolchain.
-
-Signed-off-by: David Bauer <mail@david-bauer.net>
----
- arch/powerpc/boot/Makefile | 9 ---------
- 1 file changed, 9 deletions(-)
-
---- a/arch/powerpc/boot/Makefile
-+++ b/arch/powerpc/boot/Makefile
-@@ -294,7 +294,6 @@ image-$(CONFIG_PPC_CHRP) += zImage.chrp
- image-$(CONFIG_PPC_EFIKA) += zImage.chrp
- image-$(CONFIG_PPC_PMAC) += zImage.pmac
- image-$(CONFIG_PPC_HOLLY) += dtbImage.holly
--image-$(CONFIG_DEFAULT_UIMAGE) += uImage
- image-$(CONFIG_EPAPR_BOOT) += zImage.epapr
-
- #
-@@ -432,15 +431,6 @@ $(obj)/dtbImage.%: vmlinux $(wrapperbits
- $(obj)/vmlinux.strip: vmlinux
- $(STRIP) -s -R .comment $< -o $@
-
--$(obj)/uImage: vmlinux $(wrapperbits) FORCE
-- $(call if_changed,wrap,uboot)
--
--$(obj)/uImage.initrd.%: vmlinux $(obj)/dts/%.dtb $(wrapperbits) FORCE
-- $(call if_changed,wrap,uboot-$*,,$(obj)/dts/$*.dtb,$(obj)/ramdisk.image.gz)
--
--$(obj)/uImage.%: vmlinux $(obj)/dts/%.dtb $(wrapperbits) FORCE
-- $(call if_changed,wrap,uboot-$*,,$(obj)/dts/$*.dtb)
--
- $(obj)/cuImage.initrd.%: vmlinux $(obj)/dts/%.dtb $(wrapperbits) FORCE
- $(call if_changed,wrap,cuboot-$*,,$(obj)/dts/$*.dtb,$(obj)/ramdisk.image.gz)
-
diff --git a/target/linux/mvebu/config-6.6 b/target/linux/mvebu/config-6.6
index 88e5fff4d9..a4572d8a89 100644
--- a/target/linux/mvebu/config-6.6
+++ b/target/linux/mvebu/config-6.6
@@ -270,6 +270,7 @@ CONFIG_MTD_NAND_ECC_SW_HAMMING=y
CONFIG_MTD_NAND_MARVELL=y
CONFIG_MTD_RAW_NAND=y
CONFIG_MTD_SPI_NOR=y
+CONFIG_MTD_SPI_NOR_USE_VARIABLE_ERASE=y
CONFIG_MTD_SPLIT_FIRMWARE=y
CONFIG_MTD_UBI=y
CONFIG_MTD_UBI_BEB_LIMIT=20
diff --git a/target/linux/mvebu/files-6.6/arch/arm64/boot/dts/marvell/armada-3720-gl-mv1000.dts b/target/linux/mvebu/files-6.6/arch/arm64/boot/dts/marvell/armada-3720-gl-mv1000.dts
index 07400fce3a..e098ede75f 100644
--- a/target/linux/mvebu/files-6.6/arch/arm64/boot/dts/marvell/armada-3720-gl-mv1000.dts
+++ b/target/linux/mvebu/files-6.6/arch/arm64/boot/dts/marvell/armada-3720-gl-mv1000.dts
@@ -100,7 +100,6 @@
partition@f0000 {
label = "u-boot-env";
reg = <0xf0000 0x8000>;
- read-only;
};
factory: partition@f8000 {
diff --git a/target/linux/mvebu/image/cortexa53.mk b/target/linux/mvebu/image/cortexa53.mk
index afe8d9ce21..2a3b5ee11e 100644
--- a/target/linux/mvebu/image/cortexa53.mk
+++ b/target/linux/mvebu/image/cortexa53.mk
@@ -3,6 +3,7 @@ define Device/glinet_gl-mv1000
DEVICE_VENDOR := GL.iNet
DEVICE_MODEL := GL-MV1000
SOC := armada-3720
+ BOOT_SCRIPT := gl-mv1000
endef
TARGET_DEVICES += glinet_gl-mv1000
diff --git a/target/linux/mvebu/image/cortexa9.mk b/target/linux/mvebu/image/cortexa9.mk
index b3b8960a32..a396b48675 100644
--- a/target/linux/mvebu/image/cortexa9.mk
+++ b/target/linux/mvebu/image/cortexa9.mk
@@ -106,7 +106,8 @@ define Device/cznic_turris-omnia
DEVICE_PACKAGES := \
mkf2fs e2fsprogs kmod-fs-vfat kmod-nls-cp437 kmod-nls-iso8859-1 \
wpad-basic-mbedtls kmod-ath9k kmod-ath10k-ct ath10k-firmware-qca988x-ct \
- kmod-mt7915-firmware partx-utils kmod-i2c-mux-pca954x kmod-leds-turris-omnia
+ kmod-mt7915-firmware partx-utils kmod-i2c-mux-pca954x kmod-leds-turris-omnia \
+ kmod-turris-omnia-mcu kmod-gpio-button-hotplug omnia-mcu-firmware omnia-mcutool
IMAGES := sysupgrade.img.gz
IMAGE/sysupgrade.img.gz := boot-scr | boot-img | sdcard-img | gzip | append-metadata
SUPPORTED_DEVICES += armada-385-turris-omnia
diff --git a/target/linux/mvebu/image/gl-mv1000.bootscript b/target/linux/mvebu/image/gl-mv1000.bootscript
new file mode 100644
index 0000000000..be93aa36a0
--- /dev/null
+++ b/target/linux/mvebu/image/gl-mv1000.bootscript
@@ -0,0 +1,28 @@
+# Boot script for GL.iNet GL-MV1000 to make it easier to boot from eMMC or SD
+# card.
+
+setenv bootargs "root=PARTUUID=@ROOT@-02 rw rootwait"
+
+if test -n "${console}"; then
+ setenv bootargs "${bootargs} ${console}"
+fi
+
+# Should mmc_dev not be present, default to internal MMC boot
+if test -z "${mmc_dev}"; then
+ setenv mmc_dev 0
+fi
+
+setenv mmcdev "${mmc_dev}"
+
+if test -n "${fdt_addr_r}"; then
+ setenv fdt_addr ${fdt_addr_r}
+fi
+
+if test -n "${kernel_addr_r}"; then
+ setenv kernel_addr ${kernel_addr_r}
+fi
+
+load mmc ${mmcdev}:1 ${fdt_addr} @DTB@.dtb
+load mmc ${mmcdev}:1 ${kernel_addr} Image
+
+booti ${kernel_addr} - ${fdt_addr}
diff --git a/target/linux/mvebu/modules.mk b/target/linux/mvebu/modules.mk
index 311cc07c7f..e6fa6ab3ed 100644
--- a/target/linux/mvebu/modules.mk
+++ b/target/linux/mvebu/modules.mk
@@ -17,6 +17,27 @@ endef
$(eval $(call KernelPackage,linkstation-poweroff))
+define KernelPackage/turris-omnia-mcu
+ SUBMENU:=$(OTHER_MENU)
+ TITLE:=CZ.NIC's Turris Omnia MCU driver
+ DEPENDS:=@TARGET_mvebu_cortexa9
+ KCONFIG:= \
+ CONFIG_CZNIC_PLATFORMS=y \
+ CONFIG_TURRIS_OMNIA_MCU
+ FILES:=$(LINUX_DIR)/drivers/platform/cznic/turris-omnia-mcu.ko
+ AUTOLOAD:=$(call AutoProbe,turris-omnia-mcu,1)
+endef
+
+define KernelPackage/turris-omnia-mcu/description
+ This adds support for the features implemented by the microcontroller
+ on the CZ.NIC's Turris Omnia SOHO router, including true board
+ poweroff, the ability to configure wake up from powered off state at
+ a specific time, MCU watchdog and MCU connected GPIO pins.
+endef
+
+$(eval $(call KernelPackage,turris-omnia-mcu))
+
+
define KernelPackage/leds-turris-omnia
SUBMENU:=$(LEDS_MENU)
TITLE:=LED support for CZ.NIC's Turris Omnia
diff --git a/target/linux/mvebu/patches-6.6/820-v6.11-01-dt-bindings-firmware-add-cznic-turris-omnia-mcu-bind.patch b/target/linux/mvebu/patches-6.6/820-v6.11-01-dt-bindings-firmware-add-cznic-turris-omnia-mcu-bind.patch
new file mode 100644
index 0000000000..4d6d8e82c2
--- /dev/null
+++ b/target/linux/mvebu/patches-6.6/820-v6.11-01-dt-bindings-firmware-add-cznic-turris-omnia-mcu-bind.patch
@@ -0,0 +1,125 @@
+From cdfed4d05780450817ef96567e2cd8d355ca9e70 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
+Date: Mon, 1 Jul 2024 13:30:03 +0200
+Subject: [PATCH 01/11] dt-bindings: firmware: add cznic,turris-omnia-mcu
+ binding
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add binding for cznic,turris-omnia-mcu, the device-tree node
+representing the system-controller features provided by the MCU on the
+Turris Omnia router.
+
+Signed-off-by: Marek Behún <kabel@kernel.org>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+Reviewed-by: Andy Shevchenko <andy@kernel.org>
+Acked-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Link: https://lore.kernel.org/r/20240701113010.16447-2-kabel@kernel.org
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+---
+ .../firmware/cznic,turris-omnia-mcu.yaml | 86 +++++++++++++++++++
+ MAINTAINERS | 1 +
+ 2 files changed, 87 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/firmware/cznic,turris-omnia-mcu.yaml
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/firmware/cznic,turris-omnia-mcu.yaml
+@@ -0,0 +1,86 @@
++# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/firmware/cznic,turris-omnia-mcu.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: CZ.NIC's Turris Omnia MCU
++
++maintainers:
++ - Marek Behún <kabel@kernel.org>
++
++description:
++ The MCU on Turris Omnia acts as a system controller providing additional
++ GPIOs, interrupts, watchdog, system power off and wakeup configuration.
++
++properties:
++ compatible:
++ const: cznic,turris-omnia-mcu
++
++ reg:
++ description: MCU I2C slave address
++ maxItems: 1
++
++ interrupts:
++ maxItems: 1
++
++ interrupt-controller: true
++
++ '#interrupt-cells':
++ const: 2
++ description: |
++ The first cell specifies the interrupt number (0 to 63), the second cell
++ specifies interrupt type (which can be one of IRQ_TYPE_EDGE_RISING,
++ IRQ_TYPE_EDGE_FALLING or IRQ_TYPE_EDGE_BOTH).
++ The interrupt numbers correspond sequentially to GPIO numbers, taking the
++ GPIO banks into account:
++ IRQ number GPIO bank GPIO pin within bank
++ 0 - 15 0 0 - 15
++ 16 - 47 1 0 - 31
++ 48 - 63 2 0 - 15
++ There are several exceptions:
++ IRQ number meaning
++ 11 LED panel brightness changed by button press
++ 13 TRNG entropy ready
++ 14 ECDSA message signature computation done
++
++ gpio-controller: true
++
++ '#gpio-cells':
++ const: 3
++ description:
++ The first cell is bank number (0, 1 or 2), the second cell is pin number
++ within the bank (0 to 15 for banks 0 and 2, 0 to 31 for bank 1), and the
++ third cell specifies consumer flags.
++
++required:
++ - compatible
++ - reg
++ - interrupts
++ - interrupt-controller
++ - gpio-controller
++
++additionalProperties: false
++
++examples:
++ - |
++ #include <dt-bindings/interrupt-controller/irq.h>
++
++ i2c {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ system-controller@2a {
++ compatible = "cznic,turris-omnia-mcu";
++ reg = <0x2a>;
++
++ interrupt-parent = <&gpio1>;
++ interrupts = <11 IRQ_TYPE_NONE>;
++
++ gpio-controller;
++ #gpio-cells = <3>;
++
++ interrupt-controller;
++ #interrupt-cells = <2>;
++ };
++ };
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -2104,6 +2104,7 @@ F: Documentation/ABI/testing/sysfs-bus-m
+ F: Documentation/ABI/testing/sysfs-firmware-turris-mox-rwtm
+ F: Documentation/devicetree/bindings/bus/moxtet.txt
+ F: Documentation/devicetree/bindings/firmware/cznic,turris-mox-rwtm.txt
++F: Documentation/devicetree/bindings/firmware/cznic,turris-omnia-mcu.yaml
+ F: Documentation/devicetree/bindings/gpio/gpio-moxtet.txt
+ F: Documentation/devicetree/bindings/leds/cznic,turris-omnia-leds.yaml
+ F: Documentation/devicetree/bindings/watchdog/armada-37xx-wdt.txt
diff --git a/target/linux/mvebu/patches-6.6/820-v6.11-02-platform-cznic-Add-preliminary-support-for-Turris-Om.patch b/target/linux/mvebu/patches-6.6/820-v6.11-02-platform-cznic-Add-preliminary-support-for-Turris-Om.patch
new file mode 100644
index 0000000000..72bd18d144
--- /dev/null
+++ b/target/linux/mvebu/patches-6.6/820-v6.11-02-platform-cznic-Add-preliminary-support-for-Turris-Om.patch
@@ -0,0 +1,922 @@
+From 4a63f684c8badfc43f384df2291ed2566909a3bc Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
+Date: Mon, 1 Jul 2024 13:30:04 +0200
+Subject: [PATCH 02/11] platform: cznic: Add preliminary support for Turris
+ Omnia MCU
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add the basic skeleton for a new platform driver for the microcontroller
+found on the Turris Omnia board.
+
+Signed-off-by: Marek Behún <kabel@kernel.org>
+Reviewed-by: Andy Shevchenko <andy@kernel.org>
+Acked-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Link: https://lore.kernel.org/r/20240701113010.16447-3-kabel@kernel.org
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+---
+ .../sysfs-bus-i2c-devices-turris-omnia-mcu | 81 ++++
+ MAINTAINERS | 3 +
+ drivers/platform/Kconfig | 2 +
+ drivers/platform/Makefile | 1 +
+ drivers/platform/cznic/Kconfig | 25 ++
+ drivers/platform/cznic/Makefile | 4 +
+ .../platform/cznic/turris-omnia-mcu-base.c | 393 ++++++++++++++++++
+ drivers/platform/cznic/turris-omnia-mcu.h | 74 ++++
+ include/linux/turris-omnia-mcu-interface.h | 249 +++++++++++
+ 9 files changed, 832 insertions(+)
+ create mode 100644 Documentation/ABI/testing/sysfs-bus-i2c-devices-turris-omnia-mcu
+ create mode 100644 drivers/platform/cznic/Kconfig
+ create mode 100644 drivers/platform/cznic/Makefile
+ create mode 100644 drivers/platform/cznic/turris-omnia-mcu-base.c
+ create mode 100644 drivers/platform/cznic/turris-omnia-mcu.h
+ create mode 100644 include/linux/turris-omnia-mcu-interface.h
+
+--- /dev/null
++++ b/Documentation/ABI/testing/sysfs-bus-i2c-devices-turris-omnia-mcu
+@@ -0,0 +1,81 @@
++What: /sys/bus/i2c/devices/<mcu_device>/board_revision
++Date: September 2024
++KernelVersion: 6.11
++Contact: Marek Behún <kabel@kernel.org>
++Description: (RO) Contains board revision number.
++
++ Only available if board information is burned in the MCU (older
++ revisions have board information burned in the ATSHA204-A chip).
++
++ Format: %u.
++
++What: /sys/bus/i2c/devices/<mcu_device>/first_mac_address
++Date: September 2024
++KernelVersion: 6.11
++Contact: Marek Behún <kabel@kernel.org>
++Description: (RO) Contains device first MAC address. Each Turris Omnia is
++ allocated 3 MAC addresses. The two additional addresses are
++ computed from the first one by incrementing it.
++
++ Only available if board information is burned in the MCU (older
++ revisions have board information burned in the ATSHA204-A chip).
++
++ Format: %pM.
++
++What: /sys/bus/i2c/devices/<mcu_device>/fw_features
++Date: September 2024
++KernelVersion: 6.11
++Contact: Marek Behún <kabel@kernel.org>
++Description: (RO) Newer versions of the microcontroller firmware report the
++ features they support. These can be read from this file. If the
++ MCU firmware is too old, this file reads 0x0.
++
++ Format: 0x%x.
++
++What: /sys/bus/i2c/devices/<mcu_device>/fw_version_hash_application
++Date: September 2024
++KernelVersion: 6.11
++Contact: Marek Behún <kabel@kernel.org>
++Description: (RO) Contains the version hash (commit hash) of the application
++ part of the microcontroller firmware.
++
++ Format: %s.
++
++What: /sys/bus/i2c/devices/<mcu_device>/fw_version_hash_bootloader
++Date: September 2024
++KernelVersion: 6.11
++Contact: Marek Behún <kabel@kernel.org>
++Description: (RO) Contains the version hash (commit hash) of the bootloader
++ part of the microcontroller firmware.
++
++ Format: %s.
++
++What: /sys/bus/i2c/devices/<mcu_device>/mcu_type
++Date: September 2024
++KernelVersion: 6.11
++Contact: Marek Behún <kabel@kernel.org>
++Description: (RO) Contains the microcontroller type (STM32, GD32, MKL).
++
++ Format: %s.
++
++What: /sys/bus/i2c/devices/<mcu_device>/reset_selector
++Date: September 2024
++KernelVersion: 6.11
++Contact: Marek Behún <kabel@kernel.org>
++Description: (RO) Contains the selected factory reset level, determined by
++ how long the rear reset button was held by the user during board
++ reset.
++
++ Format: %i.
++
++What: /sys/bus/i2c/devices/<mcu_device>/serial_number
++Date: September 2024
++KernelVersion: 6.11
++Contact: Marek Behún <kabel@kernel.org>
++Description: (RO) Contains the 64-bit board serial number in hexadecimal
++ format.
++
++ Only available if board information is burned in the MCU (older
++ revisions have board information burned in the ATSHA204-A chip).
++
++ Format: %016X.
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -2100,6 +2100,7 @@ M: Marek Behún <kabel@kernel.org>
+ S: Maintained
+ W: https://www.turris.cz/
+ F: Documentation/ABI/testing/debugfs-moxtet
++F: Documentation/ABI/testing/sysfs-bus-i2c-devices-turris-omnia-mcu
+ F: Documentation/ABI/testing/sysfs-bus-moxtet-devices
+ F: Documentation/ABI/testing/sysfs-firmware-turris-mox-rwtm
+ F: Documentation/devicetree/bindings/bus/moxtet.txt
+@@ -2113,10 +2114,12 @@ F: drivers/firmware/turris-mox-rwtm.c
+ F: drivers/gpio/gpio-moxtet.c
+ F: drivers/leds/leds-turris-omnia.c
+ F: drivers/mailbox/armada-37xx-rwtm-mailbox.c
++F: drivers/platform/cznic/
+ F: drivers/watchdog/armada_37xx_wdt.c
+ F: include/dt-bindings/bus/moxtet.h
+ F: include/linux/armada-37xx-rwtm-mailbox.h
+ F: include/linux/moxtet.h
++F: include/linux/turris-omnia-mcu-interface.h
+
+ ARM/FARADAY FA526 PORT
+ M: Hans Ulli Kroll <ulli.kroll@googlemail.com>
+--- a/drivers/platform/Kconfig
++++ b/drivers/platform/Kconfig
+@@ -7,6 +7,8 @@ source "drivers/platform/goldfish/Kconfi
+
+ source "drivers/platform/chrome/Kconfig"
+
++source "drivers/platform/cznic/Kconfig"
++
+ source "drivers/platform/mellanox/Kconfig"
+
+ source "drivers/platform/olpc/Kconfig"
+--- a/drivers/platform/Makefile
++++ b/drivers/platform/Makefile
+@@ -10,5 +10,6 @@ obj-$(CONFIG_MIPS) += mips/
+ obj-$(CONFIG_OLPC_EC) += olpc/
+ obj-$(CONFIG_GOLDFISH) += goldfish/
+ obj-$(CONFIG_CHROME_PLATFORMS) += chrome/
++obj-$(CONFIG_CZNIC_PLATFORMS) += cznic/
+ obj-$(CONFIG_SURFACE_PLATFORMS) += surface/
+ obj-$(CONFIG_MIKROTIK) += mikrotik/
+--- /dev/null
++++ b/drivers/platform/cznic/Kconfig
+@@ -0,0 +1,25 @@
++# SPDX-License-Identifier: GPL-2.0-only
++#
++# For a description of the syntax of this configuration file,
++# see Documentation/kbuild/kconfig-language.rst.
++#
++
++menuconfig CZNIC_PLATFORMS
++ bool "Platform support for CZ.NIC's Turris hardware"
++ help
++ Say Y here to be able to choose driver support for CZ.NIC's Turris
++ devices. This option alone does not add any kernel code.
++
++if CZNIC_PLATFORMS
++
++config TURRIS_OMNIA_MCU
++ tristate "Turris Omnia MCU driver"
++ depends on MACH_ARMADA_38X || COMPILE_TEST
++ depends on I2C
++ help
++ Say Y here to add support for the features implemented by the
++ microcontroller on the CZ.NIC's Turris Omnia SOHO router.
++ To compile this driver as a module, choose M here; the module will be
++ called turris-omnia-mcu.
++
++endif # CZNIC_PLATFORMS
+--- /dev/null
++++ b/drivers/platform/cznic/Makefile
+@@ -0,0 +1,4 @@
++# SPDX-License-Identifier: GPL-2.0-only
++
++obj-$(CONFIG_TURRIS_OMNIA_MCU) += turris-omnia-mcu.o
++turris-omnia-mcu-y := turris-omnia-mcu-base.o
+--- /dev/null
++++ b/drivers/platform/cznic/turris-omnia-mcu-base.c
+@@ -0,0 +1,393 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * CZ.NIC's Turris Omnia MCU driver
++ *
++ * 2024 by Marek Behún <kabel@kernel.org>
++ */
++
++#include <linux/bits.h>
++#include <linux/device.h>
++#include <linux/errno.h>
++#include <linux/hex.h>
++#include <linux/i2c.h>
++#include <linux/module.h>
++#include <linux/string.h>
++#include <linux/sysfs.h>
++#include <linux/types.h>
++
++#include <linux/turris-omnia-mcu-interface.h>
++#include "turris-omnia-mcu.h"
++
++#define OMNIA_FW_VERSION_LEN 20
++#define OMNIA_FW_VERSION_HEX_LEN (2 * OMNIA_FW_VERSION_LEN + 1)
++#define OMNIA_BOARD_INFO_LEN 16
++
++int omnia_cmd_write_read(const struct i2c_client *client,
++ void *cmd, unsigned int cmd_len,
++ void *reply, unsigned int reply_len)
++{
++ struct i2c_msg msgs[2];
++ int ret, num;
++
++ msgs[0].addr = client->addr;
++ msgs[0].flags = 0;
++ msgs[0].len = cmd_len;
++ msgs[0].buf = cmd;
++ num = 1;
++
++ if (reply_len) {
++ msgs[1].addr = client->addr;
++ msgs[1].flags = I2C_M_RD;
++ msgs[1].len = reply_len;
++ msgs[1].buf = reply;
++ num++;
++ }
++
++ ret = i2c_transfer(client->adapter, msgs, num);
++ if (ret < 0)
++ return ret;
++ if (ret != num)
++ return -EIO;
++
++ return 0;
++}
++
++static int omnia_get_version_hash(struct omnia_mcu *mcu, bool bootloader,
++ char version[static OMNIA_FW_VERSION_HEX_LEN])
++{
++ u8 reply[OMNIA_FW_VERSION_LEN];
++ char *p;
++ int err;
++
++ err = omnia_cmd_read(mcu->client,
++ bootloader ? OMNIA_CMD_GET_FW_VERSION_BOOT
++ : OMNIA_CMD_GET_FW_VERSION_APP,
++ reply, sizeof(reply));
++ if (err)
++ return err;
++
++ p = bin2hex(version, reply, OMNIA_FW_VERSION_LEN);
++ *p = '\0';
++
++ return 0;
++}
++
++static ssize_t fw_version_hash_show(struct device *dev, char *buf,
++ bool bootloader)
++{
++ struct omnia_mcu *mcu = dev_get_drvdata(dev);
++ char version[OMNIA_FW_VERSION_HEX_LEN];
++ int err;
++
++ err = omnia_get_version_hash(mcu, bootloader, version);
++ if (err)
++ return err;
++
++ return sysfs_emit(buf, "%s\n", version);
++}
++
++static ssize_t fw_version_hash_application_show(struct device *dev,
++ struct device_attribute *a,
++ char *buf)
++{
++ return fw_version_hash_show(dev, buf, false);
++}
++static DEVICE_ATTR_RO(fw_version_hash_application);
++
++static ssize_t fw_version_hash_bootloader_show(struct device *dev,
++ struct device_attribute *a,
++ char *buf)
++{
++ return fw_version_hash_show(dev, buf, true);
++}
++static DEVICE_ATTR_RO(fw_version_hash_bootloader);
++
++static ssize_t fw_features_show(struct device *dev, struct device_attribute *a,
++ char *buf)
++{
++ struct omnia_mcu *mcu = dev_get_drvdata(dev);
++
++ return sysfs_emit(buf, "0x%x\n", mcu->features);
++}
++static DEVICE_ATTR_RO(fw_features);
++
++static ssize_t mcu_type_show(struct device *dev, struct device_attribute *a,
++ char *buf)
++{
++ struct omnia_mcu *mcu = dev_get_drvdata(dev);
++
++ return sysfs_emit(buf, "%s\n", mcu->type);
++}
++static DEVICE_ATTR_RO(mcu_type);
++
++static ssize_t reset_selector_show(struct device *dev,
++ struct device_attribute *a, char *buf)
++{
++ u8 reply;
++ int err;
++
++ err = omnia_cmd_read_u8(to_i2c_client(dev), OMNIA_CMD_GET_RESET,
++ &reply);
++ if (err)
++ return err;
++
++ return sysfs_emit(buf, "%d\n", reply);
++}
++static DEVICE_ATTR_RO(reset_selector);
++
++static ssize_t serial_number_show(struct device *dev,
++ struct device_attribute *a, char *buf)
++{
++ struct omnia_mcu *mcu = dev_get_drvdata(dev);
++
++ return sysfs_emit(buf, "%016llX\n", mcu->board_serial_number);
++}
++static DEVICE_ATTR_RO(serial_number);
++
++static ssize_t first_mac_address_show(struct device *dev,
++ struct device_attribute *a, char *buf)
++{
++ struct omnia_mcu *mcu = dev_get_drvdata(dev);
++
++ return sysfs_emit(buf, "%pM\n", mcu->board_first_mac);
++}
++static DEVICE_ATTR_RO(first_mac_address);
++
++static ssize_t board_revision_show(struct device *dev,
++ struct device_attribute *a, char *buf)
++{
++ struct omnia_mcu *mcu = dev_get_drvdata(dev);
++
++ return sysfs_emit(buf, "%u\n", mcu->board_revision);
++}
++static DEVICE_ATTR_RO(board_revision);
++
++static struct attribute *omnia_mcu_base_attrs[] = {
++ &dev_attr_fw_version_hash_application.attr,
++ &dev_attr_fw_version_hash_bootloader.attr,
++ &dev_attr_fw_features.attr,
++ &dev_attr_mcu_type.attr,
++ &dev_attr_reset_selector.attr,
++ &dev_attr_serial_number.attr,
++ &dev_attr_first_mac_address.attr,
++ &dev_attr_board_revision.attr,
++ NULL
++};
++
++static umode_t omnia_mcu_base_attrs_visible(struct kobject *kobj,
++ struct attribute *a, int n)
++{
++ struct device *dev = kobj_to_dev(kobj);
++ struct omnia_mcu *mcu = dev_get_drvdata(dev);
++
++ if ((a == &dev_attr_serial_number.attr ||
++ a == &dev_attr_first_mac_address.attr ||
++ a == &dev_attr_board_revision.attr) &&
++ !(mcu->features & OMNIA_FEAT_BOARD_INFO))
++ return 0;
++
++ return a->mode;
++}
++
++static const struct attribute_group omnia_mcu_base_group = {
++ .attrs = omnia_mcu_base_attrs,
++ .is_visible = omnia_mcu_base_attrs_visible,
++};
++
++static const struct attribute_group *omnia_mcu_groups[] = {
++ &omnia_mcu_base_group,
++ NULL
++};
++
++static void omnia_mcu_print_version_hash(struct omnia_mcu *mcu, bool bootloader)
++{
++ const char *type = bootloader ? "bootloader" : "application";
++ struct device *dev = &mcu->client->dev;
++ char version[OMNIA_FW_VERSION_HEX_LEN];
++ int err;
++
++ err = omnia_get_version_hash(mcu, bootloader, version);
++ if (err) {
++ dev_err(dev, "Cannot read MCU %s firmware version: %d\n",
++ type, err);
++ return;
++ }
++
++ dev_info(dev, "MCU %s firmware version hash: %s\n", type, version);
++}
++
++static const char *omnia_status_to_mcu_type(u16 status)
++{
++ switch (status & OMNIA_STS_MCU_TYPE_MASK) {
++ case OMNIA_STS_MCU_TYPE_STM32:
++ return "STM32";
++ case OMNIA_STS_MCU_TYPE_GD32:
++ return "GD32";
++ case OMNIA_STS_MCU_TYPE_MKL:
++ return "MKL";
++ default:
++ return "unknown";
++ }
++}
++
++static void omnia_info_missing_feature(struct device *dev, const char *feature)
++{
++ dev_info(dev,
++ "Your board's MCU firmware does not support the %s feature.\n",
++ feature);
++}
++
++static int omnia_mcu_read_features(struct omnia_mcu *mcu)
++{
++ static const struct {
++ u16 mask;
++ const char *name;
++ } features[] = {
++#define _DEF_FEAT(_n, _m) { OMNIA_FEAT_ ## _n, _m }
++ _DEF_FEAT(EXT_CMDS, "extended control and status"),
++ _DEF_FEAT(WDT_PING, "watchdog pinging"),
++ _DEF_FEAT(LED_STATE_EXT_MASK, "peripheral LED pins reading"),
++ _DEF_FEAT(NEW_INT_API, "new interrupt API"),
++ _DEF_FEAT(POWEROFF_WAKEUP, "poweroff and wakeup"),
++ _DEF_FEAT(TRNG, "true random number generator"),
++#undef _DEF_FEAT
++ };
++ struct i2c_client *client = mcu->client;
++ struct device *dev = &client->dev;
++ bool suggest_fw_upgrade = false;
++ u16 status;
++ int err;
++
++ /* status word holds MCU type, which we need below */
++ err = omnia_cmd_read_u16(client, OMNIA_CMD_GET_STATUS_WORD, &status);
++ if (err)
++ return err;
++
++ /*
++ * Check whether MCU firmware supports the OMNIA_CMD_GET_FEATURES
++ * command.
++ */
++ if (status & OMNIA_STS_FEATURES_SUPPORTED) {
++ /* try read 32-bit features */
++ err = omnia_cmd_read_u32(client, OMNIA_CMD_GET_FEATURES,
++ &mcu->features);
++ if (err) {
++ /* try read 16-bit features */
++ u16 features16;
++
++ err = omnia_cmd_read_u16(client, OMNIA_CMD_GET_FEATURES,
++ &features16);
++ if (err)
++ return err;
++
++ mcu->features = features16;
++ } else {
++ if (mcu->features & OMNIA_FEAT_FROM_BIT_16_INVALID)
++ mcu->features &= GENMASK(15, 0);
++ }
++ } else {
++ dev_info(dev,
++ "Your board's MCU firmware does not support feature reading.\n");
++ suggest_fw_upgrade = true;
++ }
++
++ mcu->type = omnia_status_to_mcu_type(status);
++ dev_info(dev, "MCU type %s%s\n", mcu->type,
++ (mcu->features & OMNIA_FEAT_PERIPH_MCU) ?
++ ", with peripheral resets wired" : "");
++
++ omnia_mcu_print_version_hash(mcu, true);
++
++ if (mcu->features & OMNIA_FEAT_BOOTLOADER)
++ dev_warn(dev,
++ "MCU is running bootloader firmware. Was firmware upgrade interrupted?\n");
++ else
++ omnia_mcu_print_version_hash(mcu, false);
++
++ for (unsigned int i = 0; i < ARRAY_SIZE(features); i++) {
++ if (mcu->features & features[i].mask)
++ continue;
++
++ omnia_info_missing_feature(dev, features[i].name);
++ suggest_fw_upgrade = true;
++ }
++
++ if (suggest_fw_upgrade)
++ dev_info(dev,
++ "Consider upgrading MCU firmware with the omnia-mcutool utility.\n");
++
++ return 0;
++}
++
++static int omnia_mcu_read_board_info(struct omnia_mcu *mcu)
++{
++ u8 reply[1 + OMNIA_BOARD_INFO_LEN];
++ int err;
++
++ err = omnia_cmd_read(mcu->client, OMNIA_CMD_BOARD_INFO_GET, reply,
++ sizeof(reply));
++ if (err)
++ return err;
++
++ if (reply[0] != OMNIA_BOARD_INFO_LEN)
++ return -EIO;
++
++ mcu->board_serial_number = get_unaligned_le64(&reply[1]);
++
++ /* we can't use ether_addr_copy() because reply is not u16-aligned */
++ memcpy(mcu->board_first_mac, &reply[9], sizeof(mcu->board_first_mac));
++
++ mcu->board_revision = reply[15];
++
++ return 0;
++}
++
++static int omnia_mcu_probe(struct i2c_client *client)
++{
++ struct device *dev = &client->dev;
++ struct omnia_mcu *mcu;
++ int err;
++
++ if (!client->irq)
++ return dev_err_probe(dev, -EINVAL, "IRQ resource not found\n");
++
++ mcu = devm_kzalloc(dev, sizeof(*mcu), GFP_KERNEL);
++ if (!mcu)
++ return -ENOMEM;
++
++ mcu->client = client;
++ i2c_set_clientdata(client, mcu);
++
++ err = omnia_mcu_read_features(mcu);
++ if (err)
++ return dev_err_probe(dev, err,
++ "Cannot determine MCU supported features\n");
++
++ if (mcu->features & OMNIA_FEAT_BOARD_INFO) {
++ err = omnia_mcu_read_board_info(mcu);
++ if (err)
++ return dev_err_probe(dev, err,
++ "Cannot read board info\n");
++ }
++
++ return 0;
++}
++
++static const struct of_device_id of_omnia_mcu_match[] = {
++ { .compatible = "cznic,turris-omnia-mcu" },
++ {}
++};
++
++static struct i2c_driver omnia_mcu_driver = {
++ .probe = omnia_mcu_probe,
++ .driver = {
++ .name = "turris-omnia-mcu",
++ .of_match_table = of_omnia_mcu_match,
++ .dev_groups = omnia_mcu_groups,
++ },
++};
++module_i2c_driver(omnia_mcu_driver);
++
++MODULE_AUTHOR("Marek Behun <kabel@kernel.org>");
++MODULE_DESCRIPTION("CZ.NIC's Turris Omnia MCU");
++MODULE_LICENSE("GPL");
+--- /dev/null
++++ b/drivers/platform/cznic/turris-omnia-mcu.h
+@@ -0,0 +1,74 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++/*
++ * CZ.NIC's Turris Omnia MCU driver
++ *
++ * 2024 by Marek Behún <kabel@kernel.org>
++ */
++
++#ifndef __TURRIS_OMNIA_MCU_H
++#define __TURRIS_OMNIA_MCU_H
++
++#include <linux/if_ether.h>
++#include <linux/types.h>
++#include <asm/byteorder.h>
++
++struct i2c_client;
++
++struct omnia_mcu {
++ struct i2c_client *client;
++ const char *type;
++ u32 features;
++
++ /* board information */
++ u64 board_serial_number;
++ u8 board_first_mac[ETH_ALEN];
++ u8 board_revision;
++};
++
++int omnia_cmd_write_read(const struct i2c_client *client,
++ void *cmd, unsigned int cmd_len,
++ void *reply, unsigned int reply_len);
++
++static inline int omnia_cmd_read(const struct i2c_client *client, u8 cmd,
++ void *reply, unsigned int len)
++{
++ return omnia_cmd_write_read(client, &cmd, 1, reply, len);
++}
++
++static inline int omnia_cmd_read_u32(const struct i2c_client *client, u8 cmd,
++ u32 *dst)
++{
++ __le32 reply;
++ int err;
++
++ err = omnia_cmd_read(client, cmd, &reply, sizeof(reply));
++ if (err)
++ return err;
++
++ *dst = le32_to_cpu(reply);
++
++ return 0;
++}
++
++static inline int omnia_cmd_read_u16(const struct i2c_client *client, u8 cmd,
++ u16 *dst)
++{
++ __le16 reply;
++ int err;
++
++ err = omnia_cmd_read(client, cmd, &reply, sizeof(reply));
++ if (err)
++ return err;
++
++ *dst = le16_to_cpu(reply);
++
++ return 0;
++}
++
++static inline int omnia_cmd_read_u8(const struct i2c_client *client, u8 cmd,
++ u8 *reply)
++{
++ return omnia_cmd_read(client, cmd, reply, sizeof(*reply));
++}
++
++#endif /* __TURRIS_OMNIA_MCU_H */
+--- /dev/null
++++ b/include/linux/turris-omnia-mcu-interface.h
+@@ -0,0 +1,249 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++/*
++ * CZ.NIC's Turris Omnia MCU I2C interface commands definitions
++ *
++ * 2024 by Marek Behún <kabel@kernel.org>
++ */
++
++#ifndef __TURRIS_OMNIA_MCU_INTERFACE_H
++#define __TURRIS_OMNIA_MCU_INTERFACE_H
++
++#include <linux/bitfield.h>
++#include <linux/bits.h>
++
++enum omnia_commands_e {
++ OMNIA_CMD_GET_STATUS_WORD = 0x01, /* slave sends status word back */
++ OMNIA_CMD_GENERAL_CONTROL = 0x02,
++ OMNIA_CMD_LED_MODE = 0x03, /* default/user */
++ OMNIA_CMD_LED_STATE = 0x04, /* LED on/off */
++ OMNIA_CMD_LED_COLOR = 0x05, /* LED number + RED + GREEN + BLUE */
++ OMNIA_CMD_USER_VOLTAGE = 0x06,
++ OMNIA_CMD_SET_BRIGHTNESS = 0x07,
++ OMNIA_CMD_GET_BRIGHTNESS = 0x08,
++ OMNIA_CMD_GET_RESET = 0x09,
++ OMNIA_CMD_GET_FW_VERSION_APP = 0x0A, /* 20B git hash number */
++ OMNIA_CMD_SET_WATCHDOG_STATE = 0x0B, /* 0 - disable
++ * 1 - enable / ping
++ * after boot watchdog is started
++ * with 2 minutes timeout
++ */
++
++ /* OMNIA_CMD_WATCHDOG_STATUS = 0x0C, not implemented anymore */
++
++ OMNIA_CMD_GET_WATCHDOG_STATE = 0x0D,
++ OMNIA_CMD_GET_FW_VERSION_BOOT = 0x0E, /* 20B Git hash number */
++ OMNIA_CMD_GET_FW_CHECKSUM = 0x0F, /* 4B length, 4B checksum */
++
++ /* available if FEATURES_SUPPORTED bit set in status word */
++ OMNIA_CMD_GET_FEATURES = 0x10,
++
++ /* available if EXT_CMD bit set in features */
++ OMNIA_CMD_GET_EXT_STATUS_DWORD = 0x11,
++ OMNIA_CMD_EXT_CONTROL = 0x12,
++ OMNIA_CMD_GET_EXT_CONTROL_STATUS = 0x13,
++
++ /* available if NEW_INT_API bit set in features */
++ OMNIA_CMD_GET_INT_AND_CLEAR = 0x14,
++ OMNIA_CMD_GET_INT_MASK = 0x15,
++ OMNIA_CMD_SET_INT_MASK = 0x16,
++
++ /* available if FLASHING bit set in features */
++ OMNIA_CMD_FLASH = 0x19,
++
++ /* available if WDT_PING bit set in features */
++ OMNIA_CMD_SET_WDT_TIMEOUT = 0x20,
++ OMNIA_CMD_GET_WDT_TIMELEFT = 0x21,
++
++ /* available if POWEROFF_WAKEUP bit set in features */
++ OMNIA_CMD_SET_WAKEUP = 0x22,
++ OMNIA_CMD_GET_UPTIME_AND_WAKEUP = 0x23,
++ OMNIA_CMD_POWER_OFF = 0x24,
++
++ /* available if USB_OVC_PROT_SETTING bit set in features */
++ OMNIA_CMD_SET_USB_OVC_PROT = 0x25,
++ OMNIA_CMD_GET_USB_OVC_PROT = 0x26,
++
++ /* available if TRNG bit set in features */
++ OMNIA_CMD_TRNG_COLLECT_ENTROPY = 0x28,
++
++ /* available if CRYPTO bit set in features */
++ OMNIA_CMD_CRYPTO_GET_PUBLIC_KEY = 0x29,
++ OMNIA_CMD_CRYPTO_SIGN_MESSAGE = 0x2A,
++ OMNIA_CMD_CRYPTO_COLLECT_SIGNATURE = 0x2B,
++
++ /* available if BOARD_INFO it set in features */
++ OMNIA_CMD_BOARD_INFO_GET = 0x2C,
++ OMNIA_CMD_BOARD_INFO_BURN = 0x2D,
++
++ /* available only at address 0x2b (LED-controller) */
++ /* available only if LED_GAMMA_CORRECTION bit set in features */
++ OMNIA_CMD_SET_GAMMA_CORRECTION = 0x30,
++ OMNIA_CMD_GET_GAMMA_CORRECTION = 0x31,
++
++ /* available only at address 0x2b (LED-controller) */
++ /* available only if PER_LED_CORRECTION bit set in features */
++ /* available only if FROM_BIT_16_INVALID bit NOT set in features */
++ OMNIA_CMD_SET_LED_CORRECTIONS = 0x32,
++ OMNIA_CMD_GET_LED_CORRECTIONS = 0x33,
++};
++
++enum omnia_flashing_commands_e {
++ OMNIA_FLASH_CMD_UNLOCK = 0x01,
++ OMNIA_FLASH_CMD_SIZE_AND_CSUM = 0x02,
++ OMNIA_FLASH_CMD_PROGRAM = 0x03,
++ OMNIA_FLASH_CMD_RESET = 0x04,
++};
++
++enum omnia_sts_word_e {
++ OMNIA_STS_MCU_TYPE_MASK = GENMASK(1, 0),
++ OMNIA_STS_MCU_TYPE_STM32 = FIELD_PREP_CONST(OMNIA_STS_MCU_TYPE_MASK, 0),
++ OMNIA_STS_MCU_TYPE_GD32 = FIELD_PREP_CONST(OMNIA_STS_MCU_TYPE_MASK, 1),
++ OMNIA_STS_MCU_TYPE_MKL = FIELD_PREP_CONST(OMNIA_STS_MCU_TYPE_MASK, 2),
++ OMNIA_STS_FEATURES_SUPPORTED = BIT(2),
++ OMNIA_STS_USER_REGULATOR_NOT_SUPPORTED = BIT(3),
++ OMNIA_STS_CARD_DET = BIT(4),
++ OMNIA_STS_MSATA_IND = BIT(5),
++ OMNIA_STS_USB30_OVC = BIT(6),
++ OMNIA_STS_USB31_OVC = BIT(7),
++ OMNIA_STS_USB30_PWRON = BIT(8),
++ OMNIA_STS_USB31_PWRON = BIT(9),
++ OMNIA_STS_ENABLE_4V5 = BIT(10),
++ OMNIA_STS_BUTTON_MODE = BIT(11),
++ OMNIA_STS_BUTTON_PRESSED = BIT(12),
++ OMNIA_STS_BUTTON_COUNTER_MASK = GENMASK(15, 13),
++};
++
++enum omnia_ctl_byte_e {
++ OMNIA_CTL_LIGHT_RST = BIT(0),
++ OMNIA_CTL_HARD_RST = BIT(1),
++ /* BIT(2) is currently reserved */
++ OMNIA_CTL_USB30_PWRON = BIT(3),
++ OMNIA_CTL_USB31_PWRON = BIT(4),
++ OMNIA_CTL_ENABLE_4V5 = BIT(5),
++ OMNIA_CTL_BUTTON_MODE = BIT(6),
++ OMNIA_CTL_BOOTLOADER = BIT(7),
++};
++
++enum omnia_features_e {
++ OMNIA_FEAT_PERIPH_MCU = BIT(0),
++ OMNIA_FEAT_EXT_CMDS = BIT(1),
++ OMNIA_FEAT_WDT_PING = BIT(2),
++ OMNIA_FEAT_LED_STATE_EXT_MASK = GENMASK(4, 3),
++ OMNIA_FEAT_LED_STATE_EXT = FIELD_PREP_CONST(OMNIA_FEAT_LED_STATE_EXT_MASK, 1),
++ OMNIA_FEAT_LED_STATE_EXT_V32 = FIELD_PREP_CONST(OMNIA_FEAT_LED_STATE_EXT_MASK, 2),
++ OMNIA_FEAT_LED_GAMMA_CORRECTION = BIT(5),
++ OMNIA_FEAT_NEW_INT_API = BIT(6),
++ OMNIA_FEAT_BOOTLOADER = BIT(7),
++ OMNIA_FEAT_FLASHING = BIT(8),
++ OMNIA_FEAT_NEW_MESSAGE_API = BIT(9),
++ OMNIA_FEAT_BRIGHTNESS_INT = BIT(10),
++ OMNIA_FEAT_POWEROFF_WAKEUP = BIT(11),
++ OMNIA_FEAT_CAN_OLD_MESSAGE_API = BIT(12),
++ OMNIA_FEAT_TRNG = BIT(13),
++ OMNIA_FEAT_CRYPTO = BIT(14),
++ OMNIA_FEAT_BOARD_INFO = BIT(15),
++
++ /*
++ * Orginally the features command replied only 16 bits. If more were
++ * read, either the I2C transaction failed or 0xff bytes were sent.
++ * Therefore to consider bits 16 - 31 valid, one bit (20) was reserved
++ * to be zero.
++ */
++
++ /* Bits 16 - 19 correspond to bits 0 - 3 of status word */
++ OMNIA_FEAT_MCU_TYPE_MASK = GENMASK(17, 16),
++ OMNIA_FEAT_MCU_TYPE_STM32 = FIELD_PREP_CONST(OMNIA_FEAT_MCU_TYPE_MASK, 0),
++ OMNIA_FEAT_MCU_TYPE_GD32 = FIELD_PREP_CONST(OMNIA_FEAT_MCU_TYPE_MASK, 1),
++ OMNIA_FEAT_MCU_TYPE_MKL = FIELD_PREP_CONST(OMNIA_FEAT_MCU_TYPE_MASK, 2),
++ OMNIA_FEAT_FEATURES_SUPPORTED = BIT(18),
++ OMNIA_FEAT_USER_REGULATOR_NOT_SUPPORTED = BIT(19),
++
++ /* must not be set */
++ OMNIA_FEAT_FROM_BIT_16_INVALID = BIT(20),
++
++ OMNIA_FEAT_PER_LED_CORRECTION = BIT(21),
++ OMNIA_FEAT_USB_OVC_PROT_SETTING = BIT(22),
++};
++
++enum omnia_ext_sts_dword_e {
++ OMNIA_EXT_STS_SFP_nDET = BIT(0),
++ OMNIA_EXT_STS_LED_STATES_MASK = GENMASK(31, 12),
++ OMNIA_EXT_STS_WLAN0_MSATA_LED = BIT(12),
++ OMNIA_EXT_STS_WLAN1_LED = BIT(13),
++ OMNIA_EXT_STS_WLAN2_LED = BIT(14),
++ OMNIA_EXT_STS_WPAN0_LED = BIT(15),
++ OMNIA_EXT_STS_WPAN1_LED = BIT(16),
++ OMNIA_EXT_STS_WPAN2_LED = BIT(17),
++ OMNIA_EXT_STS_WAN_LED0 = BIT(18),
++ OMNIA_EXT_STS_WAN_LED1 = BIT(19),
++ OMNIA_EXT_STS_LAN0_LED0 = BIT(20),
++ OMNIA_EXT_STS_LAN0_LED1 = BIT(21),
++ OMNIA_EXT_STS_LAN1_LED0 = BIT(22),
++ OMNIA_EXT_STS_LAN1_LED1 = BIT(23),
++ OMNIA_EXT_STS_LAN2_LED0 = BIT(24),
++ OMNIA_EXT_STS_LAN2_LED1 = BIT(25),
++ OMNIA_EXT_STS_LAN3_LED0 = BIT(26),
++ OMNIA_EXT_STS_LAN3_LED1 = BIT(27),
++ OMNIA_EXT_STS_LAN4_LED0 = BIT(28),
++ OMNIA_EXT_STS_LAN4_LED1 = BIT(29),
++ OMNIA_EXT_STS_LAN5_LED0 = BIT(30),
++ OMNIA_EXT_STS_LAN5_LED1 = BIT(31),
++};
++
++enum omnia_ext_ctl_e {
++ OMNIA_EXT_CTL_nRES_MMC = BIT(0),
++ OMNIA_EXT_CTL_nRES_LAN = BIT(1),
++ OMNIA_EXT_CTL_nRES_PHY = BIT(2),
++ OMNIA_EXT_CTL_nPERST0 = BIT(3),
++ OMNIA_EXT_CTL_nPERST1 = BIT(4),
++ OMNIA_EXT_CTL_nPERST2 = BIT(5),
++ OMNIA_EXT_CTL_PHY_SFP = BIT(6),
++ OMNIA_EXT_CTL_PHY_SFP_AUTO = BIT(7),
++ OMNIA_EXT_CTL_nVHV_CTRL = BIT(8),
++};
++
++enum omnia_int_e {
++ OMNIA_INT_CARD_DET = BIT(0),
++ OMNIA_INT_MSATA_IND = BIT(1),
++ OMNIA_INT_USB30_OVC = BIT(2),
++ OMNIA_INT_USB31_OVC = BIT(3),
++ OMNIA_INT_BUTTON_PRESSED = BIT(4),
++ OMNIA_INT_SFP_nDET = BIT(5),
++ OMNIA_INT_BRIGHTNESS_CHANGED = BIT(6),
++ OMNIA_INT_TRNG = BIT(7),
++ OMNIA_INT_MESSAGE_SIGNED = BIT(8),
++
++ OMNIA_INT_LED_STATES_MASK = GENMASK(31, 12),
++ OMNIA_INT_WLAN0_MSATA_LED = BIT(12),
++ OMNIA_INT_WLAN1_LED = BIT(13),
++ OMNIA_INT_WLAN2_LED = BIT(14),
++ OMNIA_INT_WPAN0_LED = BIT(15),
++ OMNIA_INT_WPAN1_LED = BIT(16),
++ OMNIA_INT_WPAN2_LED = BIT(17),
++ OMNIA_INT_WAN_LED0 = BIT(18),
++ OMNIA_INT_WAN_LED1 = BIT(19),
++ OMNIA_INT_LAN0_LED0 = BIT(20),
++ OMNIA_INT_LAN0_LED1 = BIT(21),
++ OMNIA_INT_LAN1_LED0 = BIT(22),
++ OMNIA_INT_LAN1_LED1 = BIT(23),
++ OMNIA_INT_LAN2_LED0 = BIT(24),
++ OMNIA_INT_LAN2_LED1 = BIT(25),
++ OMNIA_INT_LAN3_LED0 = BIT(26),
++ OMNIA_INT_LAN3_LED1 = BIT(27),
++ OMNIA_INT_LAN4_LED0 = BIT(28),
++ OMNIA_INT_LAN4_LED1 = BIT(29),
++ OMNIA_INT_LAN5_LED0 = BIT(30),
++ OMNIA_INT_LAN5_LED1 = BIT(31),
++};
++
++enum omnia_cmd_poweroff_e {
++ OMNIA_CMD_POWER_OFF_POWERON_BUTTON = BIT(0),
++ OMNIA_CMD_POWER_OFF_MAGIC = 0xdead,
++};
++
++enum omnia_cmd_usb_ovc_prot_e {
++ OMNIA_CMD_xET_USB_OVC_PROT_PORT_MASK = GENMASK(3, 0),
++ OMNIA_CMD_xET_USB_OVC_PROT_ENABLE = BIT(4),
++};
++
++#endif /* __TURRIS_OMNIA_MCU_INTERFACE_H */
diff --git a/target/linux/mvebu/patches-6.6/820-v6.11-03-platform-cznic-turris-omnia-mcu-Add-support-for-MCU-.patch b/target/linux/mvebu/patches-6.6/820-v6.11-03-platform-cznic-turris-omnia-mcu-Add-support-for-MCU-.patch
new file mode 100644
index 0000000000..3309a773a9
--- /dev/null
+++ b/target/linux/mvebu/patches-6.6/820-v6.11-03-platform-cznic-turris-omnia-mcu-Add-support-for-MCU-.patch
@@ -0,0 +1,1311 @@
+From 7f4f2744f9788312e12940b516b51a0a466b137e Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
+Date: Mon, 1 Jul 2024 13:30:05 +0200
+Subject: [PATCH 03/11] platform: cznic: turris-omnia-mcu: Add support for MCU
+ connected GPIOs
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add support for GPIOs connected to the MCU on the Turris Omnia board.
+
+This includes:
+- front button pin
+- enable pins for USB regulators
+- MiniPCIe / mSATA card presence pins in MiniPCIe port 0
+- LED output pins from WAN ethernet PHY, LAN switch and MiniPCIe ports
+- on board revisions 32+ also various peripheral resets and another
+ voltage regulator enable pin
+
+Signed-off-by: Marek Behún <kabel@kernel.org>
+Acked-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Link: https://lore.kernel.org/r/20240701113010.16447-4-kabel@kernel.org
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+---
+ .../sysfs-bus-i2c-devices-turris-omnia-mcu | 16 +
+ drivers/platform/cznic/Kconfig | 15 +
+ drivers/platform/cznic/Makefile | 1 +
+ .../platform/cznic/turris-omnia-mcu-base.c | 3 +-
+ .../platform/cznic/turris-omnia-mcu-gpio.c | 1094 +++++++++++++++++
+ drivers/platform/cznic/turris-omnia-mcu.h | 68 +
+ 6 files changed, 1196 insertions(+), 1 deletion(-)
+ create mode 100644 drivers/platform/cznic/turris-omnia-mcu-gpio.c
+
+--- a/Documentation/ABI/testing/sysfs-bus-i2c-devices-turris-omnia-mcu
++++ b/Documentation/ABI/testing/sysfs-bus-i2c-devices-turris-omnia-mcu
+@@ -22,6 +22,22 @@ Description: (RO) Contains device first
+
+ Format: %pM.
+
++What: /sys/bus/i2c/devices/<mcu_device>/front_button_mode
++Date: September 2024
++KernelVersion: 6.11
++Contact: Marek Behún <kabel@kernel.org>
++Description: (RW) The front button on the Turris Omnia router can be
++ configured either to change the intensity of all the LEDs on the
++ front panel, or to send the press event to the CPU as an
++ interrupt.
++
++ This file switches between these two modes:
++ - "mcu" makes the button press event be handled by the MCU to
++ change the LEDs panel intensity.
++ - "cpu" makes the button press event be handled by the CPU.
++
++ Format: %s.
++
+ What: /sys/bus/i2c/devices/<mcu_device>/fw_features
+ Date: September 2024
+ KernelVersion: 6.11
+--- a/drivers/platform/cznic/Kconfig
++++ b/drivers/platform/cznic/Kconfig
+@@ -16,9 +16,24 @@ config TURRIS_OMNIA_MCU
+ tristate "Turris Omnia MCU driver"
+ depends on MACH_ARMADA_38X || COMPILE_TEST
+ depends on I2C
++ select GPIOLIB
++ select GPIOLIB_IRQCHIP
+ help
+ Say Y here to add support for the features implemented by the
+ microcontroller on the CZ.NIC's Turris Omnia SOHO router.
++ The features include:
++ - GPIO pins
++ - to get front button press events (the front button can be
++ configured either to generate press events to the CPU or to change
++ front LEDs panel brightness)
++ - to enable / disable USB port voltage regulators and to detect
++ USB overcurrent
++ - to detect MiniPCIe / mSATA card presence in MiniPCIe port 0
++ - to configure resets of various peripherals on board revisions 32+
++ - to enable / disable the VHV voltage regulator to the SOC in order
++ to be able to program SOC's OTP on board revisions 32+
++ - to get input from the LED output pins of the WAN ethernet PHY, LAN
++ switch and MiniPCIe ports
+ To compile this driver as a module, choose M here; the module will be
+ called turris-omnia-mcu.
+
+--- a/drivers/platform/cznic/Makefile
++++ b/drivers/platform/cznic/Makefile
+@@ -2,3 +2,4 @@
+
+ obj-$(CONFIG_TURRIS_OMNIA_MCU) += turris-omnia-mcu.o
+ turris-omnia-mcu-y := turris-omnia-mcu-base.o
++turris-omnia-mcu-y += turris-omnia-mcu-gpio.o
+--- a/drivers/platform/cznic/turris-omnia-mcu-base.c
++++ b/drivers/platform/cznic/turris-omnia-mcu-base.c
+@@ -196,6 +196,7 @@ static const struct attribute_group omni
+
+ static const struct attribute_group *omnia_mcu_groups[] = {
+ &omnia_mcu_base_group,
++ &omnia_mcu_gpio_group,
+ NULL
+ };
+
+@@ -370,7 +371,7 @@ static int omnia_mcu_probe(struct i2c_cl
+ "Cannot read board info\n");
+ }
+
+- return 0;
++ return omnia_mcu_register_gpiochip(mcu);
+ }
+
+ static const struct of_device_id of_omnia_mcu_match[] = {
+--- /dev/null
++++ b/drivers/platform/cznic/turris-omnia-mcu-gpio.c
+@@ -0,0 +1,1094 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * CZ.NIC's Turris Omnia MCU GPIO and IRQ driver
++ *
++ * 2024 by Marek Behún <kabel@kernel.org>
++ */
++
++#include <linux/bitfield.h>
++#include <linux/bitops.h>
++#include <linux/bug.h>
++#include <linux/cleanup.h>
++#include <linux/device.h>
++#include <linux/devm-helpers.h>
++#include <linux/errno.h>
++#include <linux/gpio/driver.h>
++#include <linux/i2c.h>
++#include <linux/interrupt.h>
++#include <linux/mutex.h>
++#include <linux/sysfs.h>
++#include <linux/types.h>
++#include <linux/workqueue.h>
++#include <asm/unaligned.h>
++
++#include <linux/turris-omnia-mcu-interface.h>
++#include "turris-omnia-mcu.h"
++
++#define OMNIA_CMD_INT_ARG_LEN 8
++#define FRONT_BUTTON_RELEASE_DELAY_MS 50
++
++static const char * const omnia_mcu_gpio_templates[64] = {
++ /* GPIOs with value read from the 16-bit wide status */
++ [4] = "MiniPCIe0 Card Detect",
++ [5] = "MiniPCIe0 mSATA Indicator",
++ [6] = "Front USB3 port over-current",
++ [7] = "Rear USB3 port over-current",
++ [8] = "Front USB3 port power",
++ [9] = "Rear USB3 port power",
++ [12] = "Front Button",
++
++ /* GPIOs with value read from the 32-bit wide extended status */
++ [16] = "SFP nDET",
++ [28] = "MiniPCIe0 LED",
++ [29] = "MiniPCIe1 LED",
++ [30] = "MiniPCIe2 LED",
++ [31] = "MiniPCIe0 PAN LED",
++ [32] = "MiniPCIe1 PAN LED",
++ [33] = "MiniPCIe2 PAN LED",
++ [34] = "WAN PHY LED0",
++ [35] = "WAN PHY LED1",
++ [36] = "LAN switch p0 LED0",
++ [37] = "LAN switch p0 LED1",
++ [38] = "LAN switch p1 LED0",
++ [39] = "LAN switch p1 LED1",
++ [40] = "LAN switch p2 LED0",
++ [41] = "LAN switch p2 LED1",
++ [42] = "LAN switch p3 LED0",
++ [43] = "LAN switch p3 LED1",
++ [44] = "LAN switch p4 LED0",
++ [45] = "LAN switch p4 LED1",
++ [46] = "LAN switch p5 LED0",
++ [47] = "LAN switch p5 LED1",
++
++ /* GPIOs with value read from the 16-bit wide extended control status */
++ [48] = "eMMC nRESET",
++ [49] = "LAN switch nRESET",
++ [50] = "WAN PHY nRESET",
++ [51] = "MiniPCIe0 nPERST",
++ [52] = "MiniPCIe1 nPERST",
++ [53] = "MiniPCIe2 nPERST",
++ [54] = "WAN PHY SFP mux",
++ [56] = "VHV power disable",
++};
++
++struct omnia_gpio {
++ u8 cmd;
++ u8 ctl_cmd;
++ u8 bit;
++ u8 ctl_bit;
++ u8 int_bit;
++ u16 feat;
++ u16 feat_mask;
++};
++
++#define OMNIA_GPIO_INVALID_INT_BIT 0xff
++
++#define _DEF_GPIO(_cmd, _ctl_cmd, _bit, _ctl_bit, _int_bit, _feat, _feat_mask) \
++ { \
++ .cmd = _cmd, \
++ .ctl_cmd = _ctl_cmd, \
++ .bit = _bit, \
++ .ctl_bit = _ctl_bit, \
++ .int_bit = (_int_bit) < 0 ? OMNIA_GPIO_INVALID_INT_BIT \
++ : (_int_bit), \
++ .feat = _feat, \
++ .feat_mask = _feat_mask, \
++ }
++
++#define _DEF_GPIO_STS(_name) \
++ _DEF_GPIO(OMNIA_CMD_GET_STATUS_WORD, 0, __bf_shf(OMNIA_STS_ ## _name), \
++ 0, __bf_shf(OMNIA_INT_ ## _name), 0, 0)
++
++#define _DEF_GPIO_CTL(_name) \
++ _DEF_GPIO(OMNIA_CMD_GET_STATUS_WORD, OMNIA_CMD_GENERAL_CONTROL, \
++ __bf_shf(OMNIA_STS_ ## _name), __bf_shf(OMNIA_CTL_ ## _name), \
++ -1, 0, 0)
++
++#define _DEF_GPIO_EXT_STS(_name, _feat) \
++ _DEF_GPIO(OMNIA_CMD_GET_EXT_STATUS_DWORD, 0, \
++ __bf_shf(OMNIA_EXT_STS_ ## _name), 0, \
++ __bf_shf(OMNIA_INT_ ## _name), \
++ OMNIA_FEAT_ ## _feat | OMNIA_FEAT_EXT_CMDS, \
++ OMNIA_FEAT_ ## _feat | OMNIA_FEAT_EXT_CMDS)
++
++#define _DEF_GPIO_EXT_STS_LED(_name, _ledext) \
++ _DEF_GPIO(OMNIA_CMD_GET_EXT_STATUS_DWORD, 0, \
++ __bf_shf(OMNIA_EXT_STS_ ## _name), 0, \
++ __bf_shf(OMNIA_INT_ ## _name), \
++ OMNIA_FEAT_LED_STATE_ ## _ledext, \
++ OMNIA_FEAT_LED_STATE_EXT_MASK)
++
++#define _DEF_GPIO_EXT_STS_LEDALL(_name) \
++ _DEF_GPIO(OMNIA_CMD_GET_EXT_STATUS_DWORD, 0, \
++ __bf_shf(OMNIA_EXT_STS_ ## _name), 0, \
++ __bf_shf(OMNIA_INT_ ## _name), \
++ OMNIA_FEAT_LED_STATE_EXT_MASK, 0)
++
++#define _DEF_GPIO_EXT_CTL(_name, _feat) \
++ _DEF_GPIO(OMNIA_CMD_GET_EXT_CONTROL_STATUS, OMNIA_CMD_EXT_CONTROL, \
++ __bf_shf(OMNIA_EXT_CTL_ ## _name), \
++ __bf_shf(OMNIA_EXT_CTL_ ## _name), -1, \
++ OMNIA_FEAT_ ## _feat | OMNIA_FEAT_EXT_CMDS, \
++ OMNIA_FEAT_ ## _feat | OMNIA_FEAT_EXT_CMDS)
++
++#define _DEF_INT(_name) \
++ _DEF_GPIO(0, 0, 0, 0, __bf_shf(OMNIA_INT_ ## _name), 0, 0)
++
++static inline bool is_int_bit_valid(const struct omnia_gpio *gpio)
++{
++ return gpio->int_bit != OMNIA_GPIO_INVALID_INT_BIT;
++}
++
++static const struct omnia_gpio omnia_gpios[64] = {
++ /* GPIOs with value read from the 16-bit wide status */
++ [4] = _DEF_GPIO_STS(CARD_DET),
++ [5] = _DEF_GPIO_STS(MSATA_IND),
++ [6] = _DEF_GPIO_STS(USB30_OVC),
++ [7] = _DEF_GPIO_STS(USB31_OVC),
++ [8] = _DEF_GPIO_CTL(USB30_PWRON),
++ [9] = _DEF_GPIO_CTL(USB31_PWRON),
++
++ /* brightness changed interrupt, no GPIO */
++ [11] = _DEF_INT(BRIGHTNESS_CHANGED),
++
++ [12] = _DEF_GPIO_STS(BUTTON_PRESSED),
++
++ /* TRNG interrupt, no GPIO */
++ [13] = _DEF_INT(TRNG),
++
++ /* MESSAGE_SIGNED interrupt, no GPIO */
++ [14] = _DEF_INT(MESSAGE_SIGNED),
++
++ /* GPIOs with value read from the 32-bit wide extended status */
++ [16] = _DEF_GPIO_EXT_STS(SFP_nDET, PERIPH_MCU),
++ [28] = _DEF_GPIO_EXT_STS_LEDALL(WLAN0_MSATA_LED),
++ [29] = _DEF_GPIO_EXT_STS_LEDALL(WLAN1_LED),
++ [30] = _DEF_GPIO_EXT_STS_LEDALL(WLAN2_LED),
++ [31] = _DEF_GPIO_EXT_STS_LED(WPAN0_LED, EXT),
++ [32] = _DEF_GPIO_EXT_STS_LED(WPAN1_LED, EXT),
++ [33] = _DEF_GPIO_EXT_STS_LED(WPAN2_LED, EXT),
++ [34] = _DEF_GPIO_EXT_STS_LEDALL(WAN_LED0),
++ [35] = _DEF_GPIO_EXT_STS_LED(WAN_LED1, EXT_V32),
++ [36] = _DEF_GPIO_EXT_STS_LEDALL(LAN0_LED0),
++ [37] = _DEF_GPIO_EXT_STS_LEDALL(LAN0_LED1),
++ [38] = _DEF_GPIO_EXT_STS_LEDALL(LAN1_LED0),
++ [39] = _DEF_GPIO_EXT_STS_LEDALL(LAN1_LED1),
++ [40] = _DEF_GPIO_EXT_STS_LEDALL(LAN2_LED0),
++ [41] = _DEF_GPIO_EXT_STS_LEDALL(LAN2_LED1),
++ [42] = _DEF_GPIO_EXT_STS_LEDALL(LAN3_LED0),
++ [43] = _DEF_GPIO_EXT_STS_LEDALL(LAN3_LED1),
++ [44] = _DEF_GPIO_EXT_STS_LEDALL(LAN4_LED0),
++ [45] = _DEF_GPIO_EXT_STS_LEDALL(LAN4_LED1),
++ [46] = _DEF_GPIO_EXT_STS_LEDALL(LAN5_LED0),
++ [47] = _DEF_GPIO_EXT_STS_LEDALL(LAN5_LED1),
++
++ /* GPIOs with value read from the 16-bit wide extended control status */
++ [48] = _DEF_GPIO_EXT_CTL(nRES_MMC, PERIPH_MCU),
++ [49] = _DEF_GPIO_EXT_CTL(nRES_LAN, PERIPH_MCU),
++ [50] = _DEF_GPIO_EXT_CTL(nRES_PHY, PERIPH_MCU),
++ [51] = _DEF_GPIO_EXT_CTL(nPERST0, PERIPH_MCU),
++ [52] = _DEF_GPIO_EXT_CTL(nPERST1, PERIPH_MCU),
++ [53] = _DEF_GPIO_EXT_CTL(nPERST2, PERIPH_MCU),
++ [54] = _DEF_GPIO_EXT_CTL(PHY_SFP, PERIPH_MCU),
++ [56] = _DEF_GPIO_EXT_CTL(nVHV_CTRL, PERIPH_MCU),
++};
++
++/* mapping from interrupts to indexes of GPIOs in the omnia_gpios array */
++static const u8 omnia_int_to_gpio_idx[32] = {
++ [__bf_shf(OMNIA_INT_CARD_DET)] = 4,
++ [__bf_shf(OMNIA_INT_MSATA_IND)] = 5,
++ [__bf_shf(OMNIA_INT_USB30_OVC)] = 6,
++ [__bf_shf(OMNIA_INT_USB31_OVC)] = 7,
++ [__bf_shf(OMNIA_INT_BUTTON_PRESSED)] = 12,
++ [__bf_shf(OMNIA_INT_TRNG)] = 13,
++ [__bf_shf(OMNIA_INT_MESSAGE_SIGNED)] = 14,
++ [__bf_shf(OMNIA_INT_SFP_nDET)] = 16,
++ [__bf_shf(OMNIA_INT_BRIGHTNESS_CHANGED)] = 11,
++ [__bf_shf(OMNIA_INT_WLAN0_MSATA_LED)] = 28,
++ [__bf_shf(OMNIA_INT_WLAN1_LED)] = 29,
++ [__bf_shf(OMNIA_INT_WLAN2_LED)] = 30,
++ [__bf_shf(OMNIA_INT_WPAN0_LED)] = 31,
++ [__bf_shf(OMNIA_INT_WPAN1_LED)] = 32,
++ [__bf_shf(OMNIA_INT_WPAN2_LED)] = 33,
++ [__bf_shf(OMNIA_INT_WAN_LED0)] = 34,
++ [__bf_shf(OMNIA_INT_WAN_LED1)] = 35,
++ [__bf_shf(OMNIA_INT_LAN0_LED0)] = 36,
++ [__bf_shf(OMNIA_INT_LAN0_LED1)] = 37,
++ [__bf_shf(OMNIA_INT_LAN1_LED0)] = 38,
++ [__bf_shf(OMNIA_INT_LAN1_LED1)] = 39,
++ [__bf_shf(OMNIA_INT_LAN2_LED0)] = 40,
++ [__bf_shf(OMNIA_INT_LAN2_LED1)] = 41,
++ [__bf_shf(OMNIA_INT_LAN3_LED0)] = 42,
++ [__bf_shf(OMNIA_INT_LAN3_LED1)] = 43,
++ [__bf_shf(OMNIA_INT_LAN4_LED0)] = 44,
++ [__bf_shf(OMNIA_INT_LAN4_LED1)] = 45,
++ [__bf_shf(OMNIA_INT_LAN5_LED0)] = 46,
++ [__bf_shf(OMNIA_INT_LAN5_LED1)] = 47,
++};
++
++/* index of PHY_SFP GPIO in the omnia_gpios array */
++#define OMNIA_GPIO_PHY_SFP_OFFSET 54
++
++static int omnia_ctl_cmd_locked(struct omnia_mcu *mcu, u8 cmd, u16 val, u16 mask)
++{
++ unsigned int len;
++ u8 buf[5];
++
++ buf[0] = cmd;
++
++ switch (cmd) {
++ case OMNIA_CMD_GENERAL_CONTROL:
++ buf[1] = val;
++ buf[2] = mask;
++ len = 3;
++ break;
++
++ case OMNIA_CMD_EXT_CONTROL:
++ put_unaligned_le16(val, &buf[1]);
++ put_unaligned_le16(mask, &buf[3]);
++ len = 5;
++ break;
++
++ default:
++ BUG();
++ }
++
++ return omnia_cmd_write(mcu->client, buf, len);
++}
++
++static int omnia_ctl_cmd(struct omnia_mcu *mcu, u8 cmd, u16 val, u16 mask)
++{
++ guard(mutex)(&mcu->lock);
++
++ return omnia_ctl_cmd_locked(mcu, cmd, val, mask);
++}
++
++static int omnia_gpio_request(struct gpio_chip *gc, unsigned int offset)
++{
++ if (!omnia_gpios[offset].cmd)
++ return -EINVAL;
++
++ return 0;
++}
++
++static int omnia_gpio_get_direction(struct gpio_chip *gc, unsigned int offset)
++{
++ struct omnia_mcu *mcu = gpiochip_get_data(gc);
++
++ if (offset == OMNIA_GPIO_PHY_SFP_OFFSET) {
++ int val;
++
++ scoped_guard(mutex, &mcu->lock) {
++ val = omnia_cmd_read_bit(mcu->client,
++ OMNIA_CMD_GET_EXT_CONTROL_STATUS,
++ OMNIA_EXT_CTL_PHY_SFP_AUTO);
++ if (val < 0)
++ return val;
++ }
++
++ if (val)
++ return GPIO_LINE_DIRECTION_IN;
++
++ return GPIO_LINE_DIRECTION_OUT;
++ }
++
++ if (omnia_gpios[offset].ctl_cmd)
++ return GPIO_LINE_DIRECTION_OUT;
++
++ return GPIO_LINE_DIRECTION_IN;
++}
++
++static int omnia_gpio_direction_input(struct gpio_chip *gc, unsigned int offset)
++{
++ const struct omnia_gpio *gpio = &omnia_gpios[offset];
++ struct omnia_mcu *mcu = gpiochip_get_data(gc);
++
++ if (offset == OMNIA_GPIO_PHY_SFP_OFFSET)
++ return omnia_ctl_cmd(mcu, OMNIA_CMD_EXT_CONTROL,
++ OMNIA_EXT_CTL_PHY_SFP_AUTO,
++ OMNIA_EXT_CTL_PHY_SFP_AUTO);
++
++ if (gpio->ctl_cmd)
++ return -ENOTSUPP;
++
++ return 0;
++}
++
++static int omnia_gpio_direction_output(struct gpio_chip *gc,
++ unsigned int offset, int value)
++{
++ const struct omnia_gpio *gpio = &omnia_gpios[offset];
++ struct omnia_mcu *mcu = gpiochip_get_data(gc);
++ u16 val, mask;
++
++ if (!gpio->ctl_cmd)
++ return -ENOTSUPP;
++
++ mask = BIT(gpio->ctl_bit);
++ val = value ? mask : 0;
++
++ if (offset == OMNIA_GPIO_PHY_SFP_OFFSET)
++ mask |= OMNIA_EXT_CTL_PHY_SFP_AUTO;
++
++ return omnia_ctl_cmd(mcu, gpio->ctl_cmd, val, mask);
++}
++
++static int omnia_gpio_get(struct gpio_chip *gc, unsigned int offset)
++{
++ const struct omnia_gpio *gpio = &omnia_gpios[offset];
++ struct omnia_mcu *mcu = gpiochip_get_data(gc);
++
++ /*
++ * If firmware does not support the new interrupt API, we are informed
++ * of every change of the status word by an interrupt from MCU and save
++ * its value in the interrupt service routine. Simply return the saved
++ * value.
++ */
++ if (gpio->cmd == OMNIA_CMD_GET_STATUS_WORD &&
++ !(mcu->features & OMNIA_FEAT_NEW_INT_API))
++ return test_bit(gpio->bit, &mcu->last_status);
++
++ guard(mutex)(&mcu->lock);
++
++ /*
++ * If firmware does support the new interrupt API, we may have cached
++ * the value of a GPIO in the interrupt service routine. If not, read
++ * the relevant bit now.
++ */
++ if (is_int_bit_valid(gpio) && test_bit(gpio->int_bit, &mcu->is_cached))
++ return test_bit(gpio->int_bit, &mcu->cached);
++
++ return omnia_cmd_read_bit(mcu->client, gpio->cmd, BIT(gpio->bit));
++}
++
++static unsigned long *
++_relevant_field_for_sts_cmd(u8 cmd, unsigned long *sts, unsigned long *ext_sts,
++ unsigned long *ext_ctl)
++{
++ switch (cmd) {
++ case OMNIA_CMD_GET_STATUS_WORD:
++ return sts;
++ case OMNIA_CMD_GET_EXT_STATUS_DWORD:
++ return ext_sts;
++ case OMNIA_CMD_GET_EXT_CONTROL_STATUS:
++ return ext_ctl;
++ default:
++ return NULL;
++ }
++}
++
++static int omnia_gpio_get_multiple(struct gpio_chip *gc, unsigned long *mask,
++ unsigned long *bits)
++{
++ unsigned long sts = 0, ext_sts = 0, ext_ctl = 0, *field;
++ struct omnia_mcu *mcu = gpiochip_get_data(gc);
++ struct i2c_client *client = mcu->client;
++ unsigned int i;
++ int err;
++
++ /* determine which bits to read from the 3 possible commands */
++ for_each_set_bit(i, mask, ARRAY_SIZE(omnia_gpios)) {
++ field = _relevant_field_for_sts_cmd(omnia_gpios[i].cmd,
++ &sts, &ext_sts, &ext_ctl);
++ if (!field)
++ continue;
++
++ __set_bit(omnia_gpios[i].bit, field);
++ }
++
++ guard(mutex)(&mcu->lock);
++
++ if (mcu->features & OMNIA_FEAT_NEW_INT_API) {
++ /* read relevant bits from status */
++ err = omnia_cmd_read_bits(client, OMNIA_CMD_GET_STATUS_WORD,
++ sts, &sts);
++ if (err)
++ return err;
++ } else {
++ /*
++ * Use status word value cached in the interrupt service routine
++ * if firmware does not support the new interrupt API.
++ */
++ sts = mcu->last_status;
++ }
++
++ /* read relevant bits from extended status */
++ err = omnia_cmd_read_bits(client, OMNIA_CMD_GET_EXT_STATUS_DWORD,
++ ext_sts, &ext_sts);
++ if (err)
++ return err;
++
++ /* read relevant bits from extended control */
++ err = omnia_cmd_read_bits(client, OMNIA_CMD_GET_EXT_CONTROL_STATUS,
++ ext_ctl, &ext_ctl);
++ if (err)
++ return err;
++
++ /* assign relevant bits in result */
++ for_each_set_bit(i, mask, ARRAY_SIZE(omnia_gpios)) {
++ field = _relevant_field_for_sts_cmd(omnia_gpios[i].cmd,
++ &sts, &ext_sts, &ext_ctl);
++ if (!field)
++ continue;
++
++ __assign_bit(i, bits, test_bit(omnia_gpios[i].bit, field));
++ }
++
++ return 0;
++}
++
++static void omnia_gpio_set(struct gpio_chip *gc, unsigned int offset, int value)
++{
++ const struct omnia_gpio *gpio = &omnia_gpios[offset];
++ struct omnia_mcu *mcu = gpiochip_get_data(gc);
++ u16 val, mask;
++
++ if (!gpio->ctl_cmd)
++ return;
++
++ mask = BIT(gpio->ctl_bit);
++ val = value ? mask : 0;
++
++ omnia_ctl_cmd(mcu, gpio->ctl_cmd, val, mask);
++}
++
++static void omnia_gpio_set_multiple(struct gpio_chip *gc, unsigned long *mask,
++ unsigned long *bits)
++{
++ unsigned long ctl = 0, ctl_mask = 0, ext_ctl = 0, ext_ctl_mask = 0;
++ struct omnia_mcu *mcu = gpiochip_get_data(gc);
++ unsigned int i;
++
++ for_each_set_bit(i, mask, ARRAY_SIZE(omnia_gpios)) {
++ unsigned long *field, *field_mask;
++ u8 bit = omnia_gpios[i].ctl_bit;
++
++ switch (omnia_gpios[i].ctl_cmd) {
++ case OMNIA_CMD_GENERAL_CONTROL:
++ field = &ctl;
++ field_mask = &ctl_mask;
++ break;
++ case OMNIA_CMD_EXT_CONTROL:
++ field = &ext_ctl;
++ field_mask = &ext_ctl_mask;
++ break;
++ default:
++ field = field_mask = NULL;
++ break;
++ }
++
++ if (!field)
++ continue;
++
++ __set_bit(bit, field_mask);
++ __assign_bit(bit, field, test_bit(i, bits));
++ }
++
++ guard(mutex)(&mcu->lock);
++
++ if (ctl_mask)
++ omnia_ctl_cmd_locked(mcu, OMNIA_CMD_GENERAL_CONTROL,
++ ctl, ctl_mask);
++
++ if (ext_ctl_mask)
++ omnia_ctl_cmd_locked(mcu, OMNIA_CMD_EXT_CONTROL,
++ ext_ctl, ext_ctl_mask);
++}
++
++static bool omnia_gpio_available(struct omnia_mcu *mcu,
++ const struct omnia_gpio *gpio)
++{
++ if (gpio->feat_mask)
++ return (mcu->features & gpio->feat_mask) == gpio->feat;
++
++ if (gpio->feat)
++ return mcu->features & gpio->feat;
++
++ return true;
++}
++
++static int omnia_gpio_init_valid_mask(struct gpio_chip *gc,
++ unsigned long *valid_mask,
++ unsigned int ngpios)
++{
++ struct omnia_mcu *mcu = gpiochip_get_data(gc);
++
++ for (unsigned int i = 0; i < ngpios; i++) {
++ const struct omnia_gpio *gpio = &omnia_gpios[i];
++
++ if (gpio->cmd || is_int_bit_valid(gpio))
++ __assign_bit(i, valid_mask,
++ omnia_gpio_available(mcu, gpio));
++ else
++ __clear_bit(i, valid_mask);
++ }
++
++ return 0;
++}
++
++static int omnia_gpio_of_xlate(struct gpio_chip *gc,
++ const struct of_phandle_args *gpiospec,
++ u32 *flags)
++{
++ u32 bank, gpio;
++
++ if (WARN_ON(gpiospec->args_count != 3))
++ return -EINVAL;
++
++ if (flags)
++ *flags = gpiospec->args[2];
++
++ bank = gpiospec->args[0];
++ gpio = gpiospec->args[1];
++
++ switch (bank) {
++ case 0:
++ return gpio < 16 ? gpio : -EINVAL;
++ case 1:
++ return gpio < 32 ? 16 + gpio : -EINVAL;
++ case 2:
++ return gpio < 16 ? 48 + gpio : -EINVAL;
++ default:
++ return -EINVAL;
++ }
++}
++
++static void omnia_irq_shutdown(struct irq_data *d)
++{
++ struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
++ struct omnia_mcu *mcu = gpiochip_get_data(gc);
++ irq_hw_number_t hwirq = irqd_to_hwirq(d);
++ u8 bit = omnia_gpios[hwirq].int_bit;
++
++ __clear_bit(bit, &mcu->rising);
++ __clear_bit(bit, &mcu->falling);
++}
++
++static void omnia_irq_mask(struct irq_data *d)
++{
++ struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
++ struct omnia_mcu *mcu = gpiochip_get_data(gc);
++ irq_hw_number_t hwirq = irqd_to_hwirq(d);
++ u8 bit = omnia_gpios[hwirq].int_bit;
++
++ if (!omnia_gpios[hwirq].cmd)
++ __clear_bit(bit, &mcu->rising);
++ __clear_bit(bit, &mcu->mask);
++ gpiochip_disable_irq(gc, hwirq);
++}
++
++static void omnia_irq_unmask(struct irq_data *d)
++{
++ struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
++ struct omnia_mcu *mcu = gpiochip_get_data(gc);
++ irq_hw_number_t hwirq = irqd_to_hwirq(d);
++ u8 bit = omnia_gpios[hwirq].int_bit;
++
++ gpiochip_enable_irq(gc, hwirq);
++ __set_bit(bit, &mcu->mask);
++ if (!omnia_gpios[hwirq].cmd)
++ __set_bit(bit, &mcu->rising);
++}
++
++static int omnia_irq_set_type(struct irq_data *d, unsigned int type)
++{
++ struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
++ struct omnia_mcu *mcu = gpiochip_get_data(gc);
++ irq_hw_number_t hwirq = irqd_to_hwirq(d);
++ struct device *dev = &mcu->client->dev;
++ u8 bit = omnia_gpios[hwirq].int_bit;
++
++ if (!(type & IRQ_TYPE_EDGE_BOTH)) {
++ dev_err(dev, "irq %u: unsupported type %u\n", d->irq, type);
++ return -EINVAL;
++ }
++
++ __assign_bit(bit, &mcu->rising, type & IRQ_TYPE_EDGE_RISING);
++ __assign_bit(bit, &mcu->falling, type & IRQ_TYPE_EDGE_FALLING);
++
++ return 0;
++}
++
++static void omnia_irq_bus_lock(struct irq_data *d)
++{
++ struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
++ struct omnia_mcu *mcu = gpiochip_get_data(gc);
++
++ /* nothing to do if MCU firmware does not support new interrupt API */
++ if (!(mcu->features & OMNIA_FEAT_NEW_INT_API))
++ return;
++
++ mutex_lock(&mcu->lock);
++}
++
++/**
++ * omnia_mask_interleave - Interleaves the bytes from @rising and @falling
++ * @dst: the destination u8 array of interleaved bytes
++ * @rising: rising mask
++ * @falling: falling mask
++ *
++ * Interleaves the little-endian bytes from @rising and @falling words.
++ *
++ * If @rising = (r0, r1, r2, r3) and @falling = (f0, f1, f2, f3), the result is
++ * @dst = (r0, f0, r1, f1, r2, f2, r3, f3).
++ *
++ * The MCU receives an interrupt mask and reports a pending interrupt bitmap in
++ * this interleaved format. The rationale behind this is that the low-indexed
++ * bits are more important - in many cases, the user will be interested only in
++ * interrupts with indexes 0 to 7, and so the system can stop reading after
++ * first 2 bytes (r0, f0), to save time on the slow I2C bus.
++ *
++ * Feel free to remove this function and its inverse, omnia_mask_deinterleave,
++ * and use an appropriate bitmap_*() function once such a function exists.
++ */
++static void
++omnia_mask_interleave(u8 *dst, unsigned long rising, unsigned long falling)
++{
++ for (unsigned int i = 0; i < sizeof(u32); i++) {
++ dst[2 * i] = rising >> (8 * i);
++ dst[2 * i + 1] = falling >> (8 * i);
++ }
++}
++
++/**
++ * omnia_mask_deinterleave - Deinterleaves the bytes into @rising and @falling
++ * @src: the source u8 array containing the interleaved bytes
++ * @rising: pointer where to store the rising mask gathered from @src
++ * @falling: pointer where to store the falling mask gathered from @src
++ *
++ * This is the inverse function to omnia_mask_interleave.
++ */
++static void omnia_mask_deinterleave(const u8 *src, unsigned long *rising,
++ unsigned long *falling)
++{
++ *rising = *falling = 0;
++
++ for (unsigned int i = 0; i < sizeof(u32); i++) {
++ *rising |= src[2 * i] << (8 * i);
++ *falling |= src[2 * i + 1] << (8 * i);
++ }
++}
++
++static void omnia_irq_bus_sync_unlock(struct irq_data *d)
++{
++ struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
++ struct omnia_mcu *mcu = gpiochip_get_data(gc);
++ struct device *dev = &mcu->client->dev;
++ u8 cmd[1 + OMNIA_CMD_INT_ARG_LEN];
++ unsigned long rising, falling;
++ int err;
++
++ /* nothing to do if MCU firmware does not support new interrupt API */
++ if (!(mcu->features & OMNIA_FEAT_NEW_INT_API))
++ return;
++
++ cmd[0] = OMNIA_CMD_SET_INT_MASK;
++
++ rising = mcu->rising & mcu->mask;
++ falling = mcu->falling & mcu->mask;
++
++ /* interleave the rising and falling bytes into the command arguments */
++ omnia_mask_interleave(&cmd[1], rising, falling);
++
++ dev_dbg(dev, "set int mask %8ph\n", &cmd[1]);
++
++ err = omnia_cmd_write(mcu->client, cmd, sizeof(cmd));
++ if (err) {
++ dev_err(dev, "Cannot set mask: %d\n", err);
++ goto unlock;
++ }
++
++ /*
++ * Remember which GPIOs have both rising and falling interrupts enabled.
++ * For those we will cache their value so that .get() method is faster.
++ * We also need to forget cached values of GPIOs that aren't cached
++ * anymore.
++ */
++ mcu->both = rising & falling;
++ mcu->is_cached &= mcu->both;
++
++unlock:
++ mutex_unlock(&mcu->lock);
++}
++
++static const struct irq_chip omnia_mcu_irq_chip = {
++ .name = "Turris Omnia MCU interrupts",
++ .irq_shutdown = omnia_irq_shutdown,
++ .irq_mask = omnia_irq_mask,
++ .irq_unmask = omnia_irq_unmask,
++ .irq_set_type = omnia_irq_set_type,
++ .irq_bus_lock = omnia_irq_bus_lock,
++ .irq_bus_sync_unlock = omnia_irq_bus_sync_unlock,
++ .flags = IRQCHIP_IMMUTABLE,
++ GPIOCHIP_IRQ_RESOURCE_HELPERS,
++};
++
++static void omnia_irq_init_valid_mask(struct gpio_chip *gc,
++ unsigned long *valid_mask,
++ unsigned int ngpios)
++{
++ struct omnia_mcu *mcu = gpiochip_get_data(gc);
++
++ for (unsigned int i = 0; i < ngpios; i++) {
++ const struct omnia_gpio *gpio = &omnia_gpios[i];
++
++ if (is_int_bit_valid(gpio))
++ __assign_bit(i, valid_mask,
++ omnia_gpio_available(mcu, gpio));
++ else
++ __clear_bit(i, valid_mask);
++ }
++}
++
++static int omnia_irq_init_hw(struct gpio_chip *gc)
++{
++ struct omnia_mcu *mcu = gpiochip_get_data(gc);
++ u8 cmd[1 + OMNIA_CMD_INT_ARG_LEN] = {};
++
++ cmd[0] = OMNIA_CMD_SET_INT_MASK;
++
++ return omnia_cmd_write(mcu->client, cmd, sizeof(cmd));
++}
++
++/*
++ * Determine how many bytes we need to read from the reply to the
++ * OMNIA_CMD_GET_INT_AND_CLEAR command in order to retrieve all unmasked
++ * interrupts.
++ */
++static unsigned int
++omnia_irq_compute_pending_length(unsigned long rising, unsigned long falling)
++{
++ return max(omnia_compute_reply_length(rising, true, 0),
++ omnia_compute_reply_length(falling, true, 1));
++}
++
++static bool omnia_irq_read_pending_new(struct omnia_mcu *mcu,
++ unsigned long *pending)
++{
++ struct device *dev = &mcu->client->dev;
++ u8 reply[OMNIA_CMD_INT_ARG_LEN] = {};
++ unsigned long rising, falling;
++ unsigned int len;
++ int err;
++
++ len = omnia_irq_compute_pending_length(mcu->rising & mcu->mask,
++ mcu->falling & mcu->mask);
++ if (!len)
++ return false;
++
++ guard(mutex)(&mcu->lock);
++
++ err = omnia_cmd_read(mcu->client, OMNIA_CMD_GET_INT_AND_CLEAR, reply,
++ len);
++ if (err) {
++ dev_err(dev, "Cannot read pending IRQs: %d\n", err);
++ return false;
++ }
++
++ /* deinterleave the reply bytes into rising and falling */
++ omnia_mask_deinterleave(reply, &rising, &falling);
++
++ rising &= mcu->mask;
++ falling &= mcu->mask;
++ *pending = rising | falling;
++
++ /* cache values for GPIOs that have both edges enabled */
++ mcu->is_cached &= ~(rising & falling);
++ mcu->is_cached |= mcu->both & (rising ^ falling);
++ mcu->cached = (mcu->cached | rising) & ~falling;
++
++ return true;
++}
++
++static int omnia_read_status_word_old_fw(struct omnia_mcu *mcu,
++ unsigned long *status)
++{
++ u16 raw_status;
++ int err;
++
++ err = omnia_cmd_read_u16(mcu->client, OMNIA_CMD_GET_STATUS_WORD,
++ &raw_status);
++ if (err)
++ return err;
++
++ /*
++ * Old firmware has a bug wherein it never resets the USB port
++ * overcurrent bits back to zero. Ignore them.
++ */
++ *status = raw_status & ~(OMNIA_STS_USB30_OVC | OMNIA_STS_USB31_OVC);
++
++ return 0;
++}
++
++static void button_release_emul_fn(struct work_struct *work)
++{
++ struct omnia_mcu *mcu = container_of(to_delayed_work(work),
++ struct omnia_mcu,
++ button_release_emul_work);
++
++ mcu->button_pressed_emul = false;
++ generic_handle_irq_safe(mcu->client->irq);
++}
++
++static void
++fill_int_from_sts(unsigned long *rising, unsigned long *falling,
++ unsigned long rising_sts, unsigned long falling_sts,
++ unsigned long sts_bit, unsigned long int_bit)
++{
++ if (rising_sts & sts_bit)
++ *rising |= int_bit;
++ if (falling_sts & sts_bit)
++ *falling |= int_bit;
++}
++
++static bool omnia_irq_read_pending_old(struct omnia_mcu *mcu,
++ unsigned long *pending)
++{
++ unsigned long status, rising_sts, falling_sts, rising, falling;
++ struct device *dev = &mcu->client->dev;
++ int err;
++
++ guard(mutex)(&mcu->lock);
++
++ err = omnia_read_status_word_old_fw(mcu, &status);
++ if (err) {
++ dev_err(dev, "Cannot read pending IRQs: %d\n", err);
++ return false;
++ }
++
++ /*
++ * The old firmware triggers an interrupt whenever status word changes,
++ * but does not inform about which bits rose or fell. We need to compute
++ * this here by comparing with the last status word value.
++ *
++ * The OMNIA_STS_BUTTON_PRESSED bit needs special handling, because the
++ * old firmware clears the OMNIA_STS_BUTTON_PRESSED bit on successful
++ * completion of the OMNIA_CMD_GET_STATUS_WORD command, resulting in
++ * another interrupt:
++ * - first we get an interrupt, we read the status word where
++ * OMNIA_STS_BUTTON_PRESSED is present,
++ * - MCU clears the OMNIA_STS_BUTTON_PRESSED bit because we read the
++ * status word,
++ * - we get another interrupt because the status word changed again
++ * (the OMNIA_STS_BUTTON_PRESSED bit was cleared).
++ *
++ * The gpiolib-cdev, gpiolib-sysfs and gpio-keys input driver all call
++ * the gpiochip's .get() method after an edge event on a requested GPIO
++ * occurs.
++ *
++ * We ensure that the .get() method reads 1 for the button GPIO for some
++ * time.
++ */
++
++ if (status & OMNIA_STS_BUTTON_PRESSED) {
++ mcu->button_pressed_emul = true;
++ mod_delayed_work(system_wq, &mcu->button_release_emul_work,
++ msecs_to_jiffies(FRONT_BUTTON_RELEASE_DELAY_MS));
++ } else if (mcu->button_pressed_emul) {
++ status |= OMNIA_STS_BUTTON_PRESSED;
++ }
++
++ rising_sts = ~mcu->last_status & status;
++ falling_sts = mcu->last_status & ~status;
++
++ mcu->last_status = status;
++
++ /*
++ * Fill in the relevant interrupt bits from status bits for CARD_DET,
++ * MSATA_IND and BUTTON_PRESSED.
++ */
++ rising = 0;
++ falling = 0;
++ fill_int_from_sts(&rising, &falling, rising_sts, falling_sts,
++ OMNIA_STS_CARD_DET, OMNIA_INT_CARD_DET);
++ fill_int_from_sts(&rising, &falling, rising_sts, falling_sts,
++ OMNIA_STS_MSATA_IND, OMNIA_INT_MSATA_IND);
++ fill_int_from_sts(&rising, &falling, rising_sts, falling_sts,
++ OMNIA_STS_BUTTON_PRESSED, OMNIA_INT_BUTTON_PRESSED);
++
++ /* Use only bits that are enabled */
++ rising &= mcu->rising & mcu->mask;
++ falling &= mcu->falling & mcu->mask;
++ *pending = rising | falling;
++
++ return true;
++}
++
++static bool omnia_irq_read_pending(struct omnia_mcu *mcu,
++ unsigned long *pending)
++{
++ if (mcu->features & OMNIA_FEAT_NEW_INT_API)
++ return omnia_irq_read_pending_new(mcu, pending);
++ else
++ return omnia_irq_read_pending_old(mcu, pending);
++}
++
++static irqreturn_t omnia_irq_thread_handler(int irq, void *dev_id)
++{
++ struct omnia_mcu *mcu = dev_id;
++ struct irq_domain *domain;
++ unsigned long pending;
++ unsigned int i;
++
++ if (!omnia_irq_read_pending(mcu, &pending))
++ return IRQ_NONE;
++
++ domain = mcu->gc.irq.domain;
++
++ for_each_set_bit(i, &pending, 32) {
++ unsigned int nested_irq;
++
++ nested_irq = irq_find_mapping(domain, omnia_int_to_gpio_idx[i]);
++
++ handle_nested_irq(nested_irq);
++ }
++
++ return IRQ_RETVAL(pending);
++}
++
++static const char * const front_button_modes[] = { "mcu", "cpu" };
++
++static ssize_t front_button_mode_show(struct device *dev,
++ struct device_attribute *a, char *buf)
++{
++ struct omnia_mcu *mcu = dev_get_drvdata(dev);
++ int val;
++
++ if (mcu->features & OMNIA_FEAT_NEW_INT_API) {
++ val = omnia_cmd_read_bit(mcu->client, OMNIA_CMD_GET_STATUS_WORD,
++ OMNIA_STS_BUTTON_MODE);
++ if (val < 0)
++ return val;
++ } else {
++ val = !!(mcu->last_status & OMNIA_STS_BUTTON_MODE);
++ }
++
++ return sysfs_emit(buf, "%s\n", front_button_modes[val]);
++}
++
++static ssize_t front_button_mode_store(struct device *dev,
++ struct device_attribute *a,
++ const char *buf, size_t count)
++{
++ struct omnia_mcu *mcu = dev_get_drvdata(dev);
++ int err, i;
++
++ i = sysfs_match_string(front_button_modes, buf);
++ if (i < 0)
++ return i;
++
++ err = omnia_ctl_cmd_locked(mcu, OMNIA_CMD_GENERAL_CONTROL,
++ i ? OMNIA_CTL_BUTTON_MODE : 0,
++ OMNIA_CTL_BUTTON_MODE);
++ if (err)
++ return err;
++
++ return count;
++}
++static DEVICE_ATTR_RW(front_button_mode);
++
++static struct attribute *omnia_mcu_gpio_attrs[] = {
++ &dev_attr_front_button_mode.attr,
++ NULL
++};
++
++const struct attribute_group omnia_mcu_gpio_group = {
++ .attrs = omnia_mcu_gpio_attrs,
++};
++
++int omnia_mcu_register_gpiochip(struct omnia_mcu *mcu)
++{
++ bool new_api = mcu->features & OMNIA_FEAT_NEW_INT_API;
++ struct device *dev = &mcu->client->dev;
++ unsigned long irqflags;
++ int err;
++
++ err = devm_mutex_init(dev, &mcu->lock);
++ if (err)
++ return err;
++
++ mcu->gc.request = omnia_gpio_request;
++ mcu->gc.get_direction = omnia_gpio_get_direction;
++ mcu->gc.direction_input = omnia_gpio_direction_input;
++ mcu->gc.direction_output = omnia_gpio_direction_output;
++ mcu->gc.get = omnia_gpio_get;
++ mcu->gc.get_multiple = omnia_gpio_get_multiple;
++ mcu->gc.set = omnia_gpio_set;
++ mcu->gc.set_multiple = omnia_gpio_set_multiple;
++ mcu->gc.init_valid_mask = omnia_gpio_init_valid_mask;
++ mcu->gc.can_sleep = true;
++ mcu->gc.names = omnia_mcu_gpio_templates;
++ mcu->gc.base = -1;
++ mcu->gc.ngpio = ARRAY_SIZE(omnia_gpios);
++ mcu->gc.label = "Turris Omnia MCU GPIOs";
++ mcu->gc.parent = dev;
++ mcu->gc.owner = THIS_MODULE;
++ mcu->gc.of_gpio_n_cells = 3;
++ mcu->gc.of_xlate = omnia_gpio_of_xlate;
++
++ gpio_irq_chip_set_chip(&mcu->gc.irq, &omnia_mcu_irq_chip);
++ /* This will let us handle the parent IRQ in the driver */
++ mcu->gc.irq.parent_handler = NULL;
++ mcu->gc.irq.num_parents = 0;
++ mcu->gc.irq.parents = NULL;
++ mcu->gc.irq.default_type = IRQ_TYPE_NONE;
++ mcu->gc.irq.handler = handle_bad_irq;
++ mcu->gc.irq.threaded = true;
++ if (new_api)
++ mcu->gc.irq.init_hw = omnia_irq_init_hw;
++ mcu->gc.irq.init_valid_mask = omnia_irq_init_valid_mask;
++
++ err = devm_gpiochip_add_data(dev, &mcu->gc, mcu);
++ if (err)
++ return dev_err_probe(dev, err, "Cannot add GPIO chip\n");
++
++ /*
++ * Before requesting the interrupt, if firmware does not support the new
++ * interrupt API, we need to cache the value of the status word, so that
++ * when it changes, we may compare the new value with the cached one in
++ * the interrupt handler.
++ */
++ if (!new_api) {
++ err = omnia_read_status_word_old_fw(mcu, &mcu->last_status);
++ if (err)
++ return dev_err_probe(dev, err,
++ "Cannot read status word\n");
++
++ INIT_DELAYED_WORK(&mcu->button_release_emul_work,
++ button_release_emul_fn);
++ }
++
++ irqflags = IRQF_ONESHOT;
++ if (new_api)
++ irqflags |= IRQF_TRIGGER_LOW;
++ else
++ irqflags |= IRQF_TRIGGER_FALLING;
++
++ err = devm_request_threaded_irq(dev, mcu->client->irq, NULL,
++ omnia_irq_thread_handler, irqflags,
++ "turris-omnia-mcu", mcu);
++ if (err)
++ return dev_err_probe(dev, err, "Cannot request IRQ\n");
++
++ if (!new_api) {
++ /*
++ * The button_release_emul_work has to be initialized before the
++ * thread is requested, and on driver remove it needs to be
++ * canceled before the thread is freed. Therefore we can't use
++ * devm_delayed_work_autocancel() directly, because the order
++ * devm_delayed_work_autocancel();
++ * devm_request_threaded_irq();
++ * would cause improper release order:
++ * free_irq();
++ * cancel_delayed_work_sync();
++ * Instead we first initialize the work above, and only now
++ * after IRQ is requested we add the work devm action.
++ */
++ err = devm_add_action(dev, devm_delayed_work_drop,
++ &mcu->button_release_emul_work);
++ if (err)
++ return err;
++ }
++
++ return 0;
++}
+--- a/drivers/platform/cznic/turris-omnia-mcu.h
++++ b/drivers/platform/cznic/turris-omnia-mcu.h
+@@ -8,8 +8,12 @@
+ #ifndef __TURRIS_OMNIA_MCU_H
+ #define __TURRIS_OMNIA_MCU_H
+
++#include <linux/bitops.h>
++#include <linux/gpio/driver.h>
+ #include <linux/if_ether.h>
++#include <linux/mutex.h>
+ #include <linux/types.h>
++#include <linux/workqueue.h>
+ #include <asm/byteorder.h>
+
+ struct i2c_client;
+@@ -23,18 +27,78 @@ struct omnia_mcu {
+ u64 board_serial_number;
+ u8 board_first_mac[ETH_ALEN];
+ u8 board_revision;
++
++ /* GPIO chip */
++ struct gpio_chip gc;
++ struct mutex lock;
++ unsigned long mask, rising, falling, both, cached, is_cached;
++ /* Old MCU firmware handling needs the following */
++ struct delayed_work button_release_emul_work;
++ unsigned long last_status;
++ bool button_pressed_emul;
+ };
+
+ int omnia_cmd_write_read(const struct i2c_client *client,
+ void *cmd, unsigned int cmd_len,
+ void *reply, unsigned int reply_len);
+
++static inline int omnia_cmd_write(const struct i2c_client *client, void *cmd,
++ unsigned int len)
++{
++ return omnia_cmd_write_read(client, cmd, len, NULL, 0);
++}
++
+ static inline int omnia_cmd_read(const struct i2c_client *client, u8 cmd,
+ void *reply, unsigned int len)
+ {
+ return omnia_cmd_write_read(client, &cmd, 1, reply, len);
+ }
+
++static inline unsigned int
++omnia_compute_reply_length(unsigned long mask, bool interleaved,
++ unsigned int offset)
++{
++ if (!mask)
++ return 0;
++
++ return ((__fls(mask) >> 3) << interleaved) + 1 + offset;
++}
++
++/* Returns 0 on success */
++static inline int omnia_cmd_read_bits(const struct i2c_client *client, u8 cmd,
++ unsigned long bits, unsigned long *dst)
++{
++ __le32 reply;
++ int err;
++
++ if (!bits) {
++ *dst = 0;
++ return 0;
++ }
++
++ err = omnia_cmd_read(client, cmd, &reply,
++ omnia_compute_reply_length(bits, false, 0));
++ if (err)
++ return err;
++
++ *dst = le32_to_cpu(reply) & bits;
++
++ return 0;
++}
++
++static inline int omnia_cmd_read_bit(const struct i2c_client *client, u8 cmd,
++ unsigned long bit)
++{
++ unsigned long reply;
++ int err;
++
++ err = omnia_cmd_read_bits(client, cmd, bit, &reply);
++ if (err)
++ return err;
++
++ return !!reply;
++}
++
+ static inline int omnia_cmd_read_u32(const struct i2c_client *client, u8 cmd,
+ u32 *dst)
+ {
+@@ -71,4 +135,8 @@ static inline int omnia_cmd_read_u8(cons
+ return omnia_cmd_read(client, cmd, reply, sizeof(*reply));
+ }
+
++extern const struct attribute_group omnia_mcu_gpio_group;
++
++int omnia_mcu_register_gpiochip(struct omnia_mcu *mcu);
++
+ #endif /* __TURRIS_OMNIA_MCU_H */
diff --git a/target/linux/mvebu/patches-6.6/820-v6.11-04-platform-cznic-turris-omnia-mcu-Add-support-for-powe.patch b/target/linux/mvebu/patches-6.6/820-v6.11-04-platform-cznic-turris-omnia-mcu-Add-support-for-powe.patch
new file mode 100644
index 0000000000..2ef6242d70
--- /dev/null
+++ b/target/linux/mvebu/patches-6.6/820-v6.11-04-platform-cznic-turris-omnia-mcu-Add-support-for-powe.patch
@@ -0,0 +1,415 @@
+From f69e0a731ab471f3a57c48258ad2d9990820c173 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
+Date: Mon, 1 Jul 2024 13:30:06 +0200
+Subject: [PATCH 04/11] platform: cznic: turris-omnia-mcu: Add support for
+ poweroff and wakeup
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add support for true board poweroff (MCU can disable all unnecessary
+voltage regulators) and wakeup at a specified time, implemented via a
+RTC driver so that the rtcwake utility can be used to configure it.
+
+Signed-off-by: Marek Behún <kabel@kernel.org>
+Reviewed-by: Andy Shevchenko <andy@kernel.org>
+Acked-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Acked-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Link: https://lore.kernel.org/r/20240701113010.16447-5-kabel@kernel.org
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+---
+ .../sysfs-bus-i2c-devices-turris-omnia-mcu | 16 ++
+ drivers/platform/cznic/Kconfig | 4 +
+ drivers/platform/cznic/Makefile | 1 +
+ .../platform/cznic/turris-omnia-mcu-base.c | 5 +
+ .../cznic/turris-omnia-mcu-sys-off-wakeup.c | 260 ++++++++++++++++++
+ drivers/platform/cznic/turris-omnia-mcu.h | 20 ++
+ 6 files changed, 306 insertions(+)
+ create mode 100644 drivers/platform/cznic/turris-omnia-mcu-sys-off-wakeup.c
+
+--- a/Documentation/ABI/testing/sysfs-bus-i2c-devices-turris-omnia-mcu
++++ b/Documentation/ABI/testing/sysfs-bus-i2c-devices-turris-omnia-mcu
+@@ -38,6 +38,22 @@ Description: (RW) The front button on th
+
+ Format: %s.
+
++What: /sys/bus/i2c/devices/<mcu_device>/front_button_poweron
++Date: September 2024
++KernelVersion: 6.11
++Contact: Marek Behún <kabel@kernel.org>
++Description: (RW) Newer versions of the microcontroller firmware of the
++ Turris Omnia router support powering off the router into true
++ low power mode. The router can be powered on by pressing the
++ front button.
++
++ This file configures whether front button power on is enabled.
++
++ This file is present only if the power off feature is supported
++ by the firmware.
++
++ Format: %i.
++
+ What: /sys/bus/i2c/devices/<mcu_device>/fw_features
+ Date: September 2024
+ KernelVersion: 6.11
+--- a/drivers/platform/cznic/Kconfig
++++ b/drivers/platform/cznic/Kconfig
+@@ -18,10 +18,14 @@ config TURRIS_OMNIA_MCU
+ depends on I2C
+ select GPIOLIB
+ select GPIOLIB_IRQCHIP
++ select RTC_CLASS
+ help
+ Say Y here to add support for the features implemented by the
+ microcontroller on the CZ.NIC's Turris Omnia SOHO router.
+ The features include:
++ - board poweroff into true low power mode (with voltage regulators
++ disabled) and the ability to configure wake up from this mode (via
++ rtcwake)
+ - GPIO pins
+ - to get front button press events (the front button can be
+ configured either to generate press events to the CPU or to change
+--- a/drivers/platform/cznic/Makefile
++++ b/drivers/platform/cznic/Makefile
+@@ -3,3 +3,4 @@
+ obj-$(CONFIG_TURRIS_OMNIA_MCU) += turris-omnia-mcu.o
+ turris-omnia-mcu-y := turris-omnia-mcu-base.o
+ turris-omnia-mcu-y += turris-omnia-mcu-gpio.o
++turris-omnia-mcu-y += turris-omnia-mcu-sys-off-wakeup.o
+--- a/drivers/platform/cznic/turris-omnia-mcu-base.c
++++ b/drivers/platform/cznic/turris-omnia-mcu-base.c
+@@ -197,6 +197,7 @@ static const struct attribute_group omni
+ static const struct attribute_group *omnia_mcu_groups[] = {
+ &omnia_mcu_base_group,
+ &omnia_mcu_gpio_group,
++ &omnia_mcu_poweroff_group,
+ NULL
+ };
+
+@@ -371,6 +372,10 @@ static int omnia_mcu_probe(struct i2c_cl
+ "Cannot read board info\n");
+ }
+
++ err = omnia_mcu_register_sys_off_and_wakeup(mcu);
++ if (err)
++ return err;
++
+ return omnia_mcu_register_gpiochip(mcu);
+ }
+
+--- /dev/null
++++ b/drivers/platform/cznic/turris-omnia-mcu-sys-off-wakeup.c
+@@ -0,0 +1,260 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * CZ.NIC's Turris Omnia MCU system off and RTC wakeup driver
++ *
++ * This is not a true RTC driver (in the sense that it does not provide a
++ * real-time clock), rather the MCU implements a wakeup from powered off state
++ * at a specified time relative to MCU boot, and we expose this feature via RTC
++ * alarm, so that it can be used via the rtcwake command, which is the standard
++ * Linux command for this.
++ *
++ * 2024 by Marek Behún <kabel@kernel.org>
++ */
++
++#include <linux/crc32.h>
++#include <linux/delay.h>
++#include <linux/device.h>
++#include <linux/err.h>
++#include <linux/i2c.h>
++#include <linux/kstrtox.h>
++#include <linux/reboot.h>
++#include <linux/rtc.h>
++#include <linux/sysfs.h>
++#include <linux/types.h>
++
++#include <linux/turris-omnia-mcu-interface.h>
++#include "turris-omnia-mcu.h"
++
++static int omnia_get_uptime_wakeup(const struct i2c_client *client, u32 *uptime,
++ u32 *wakeup)
++{
++ __le32 reply[2];
++ int err;
++
++ err = omnia_cmd_read(client, OMNIA_CMD_GET_UPTIME_AND_WAKEUP, reply,
++ sizeof(reply));
++ if (err)
++ return err;
++
++ if (uptime)
++ *uptime = le32_to_cpu(reply[0]);
++
++ if (wakeup)
++ *wakeup = le32_to_cpu(reply[1]);
++
++ return 0;
++}
++
++static int omnia_read_time(struct device *dev, struct rtc_time *tm)
++{
++ u32 uptime;
++ int err;
++
++ err = omnia_get_uptime_wakeup(to_i2c_client(dev), &uptime, NULL);
++ if (err)
++ return err;
++
++ rtc_time64_to_tm(uptime, tm);
++
++ return 0;
++}
++
++static int omnia_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ struct omnia_mcu *mcu = i2c_get_clientdata(client);
++ u32 wakeup;
++ int err;
++
++ err = omnia_get_uptime_wakeup(client, NULL, &wakeup);
++ if (err)
++ return err;
++
++ alrm->enabled = !!wakeup;
++ rtc_time64_to_tm(wakeup ?: mcu->rtc_alarm, &alrm->time);
++
++ return 0;
++}
++
++static int omnia_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ struct omnia_mcu *mcu = i2c_get_clientdata(client);
++
++ mcu->rtc_alarm = rtc_tm_to_time64(&alrm->time);
++
++ if (alrm->enabled)
++ return omnia_cmd_write_u32(client, OMNIA_CMD_SET_WAKEUP,
++ mcu->rtc_alarm);
++
++ return 0;
++}
++
++static int omnia_alarm_irq_enable(struct device *dev, unsigned int enabled)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ struct omnia_mcu *mcu = i2c_get_clientdata(client);
++
++ return omnia_cmd_write_u32(client, OMNIA_CMD_SET_WAKEUP,
++ enabled ? mcu->rtc_alarm : 0);
++}
++
++static const struct rtc_class_ops omnia_rtc_ops = {
++ .read_time = omnia_read_time,
++ .read_alarm = omnia_read_alarm,
++ .set_alarm = omnia_set_alarm,
++ .alarm_irq_enable = omnia_alarm_irq_enable,
++};
++
++static int omnia_power_off(struct sys_off_data *data)
++{
++ struct omnia_mcu *mcu = data->cb_data;
++ __be32 tmp;
++ u8 cmd[9];
++ u16 arg;
++ int err;
++
++ if (mcu->front_button_poweron)
++ arg = OMNIA_CMD_POWER_OFF_POWERON_BUTTON;
++ else
++ arg = 0;
++
++ cmd[0] = OMNIA_CMD_POWER_OFF;
++ put_unaligned_le16(OMNIA_CMD_POWER_OFF_MAGIC, &cmd[1]);
++ put_unaligned_le16(arg, &cmd[3]);
++
++ /*
++ * Although all values from and to MCU are passed in little-endian, the
++ * MCU's CRC unit uses big-endian CRC32 polynomial (0x04c11db7), so we
++ * need to use crc32_be() here.
++ */
++ tmp = cpu_to_be32(get_unaligned_le32(&cmd[1]));
++ put_unaligned_le32(crc32_be(~0, (void *)&tmp, sizeof(tmp)), &cmd[5]);
++
++ err = omnia_cmd_write(mcu->client, cmd, sizeof(cmd));
++ if (err)
++ dev_err(&mcu->client->dev,
++ "Unable to send the poweroff command: %d\n", err);
++
++ return NOTIFY_DONE;
++}
++
++static int omnia_restart(struct sys_off_data *data)
++{
++ struct omnia_mcu *mcu = data->cb_data;
++ u8 cmd[3];
++ int err;
++
++ cmd[0] = OMNIA_CMD_GENERAL_CONTROL;
++
++ if (reboot_mode == REBOOT_HARD)
++ cmd[1] = cmd[2] = OMNIA_CTL_HARD_RST;
++ else
++ cmd[1] = cmd[2] = OMNIA_CTL_LIGHT_RST;
++
++ err = omnia_cmd_write(mcu->client, cmd, sizeof(cmd));
++ if (err)
++ dev_err(&mcu->client->dev,
++ "Unable to send the restart command: %d\n", err);
++
++ /*
++ * MCU needs a little bit to process the I2C command, otherwise it will
++ * do a light reset based on SOC SYSRES_OUT pin.
++ */
++ mdelay(1);
++
++ return NOTIFY_DONE;
++}
++
++static ssize_t front_button_poweron_show(struct device *dev,
++ struct device_attribute *a, char *buf)
++{
++ struct omnia_mcu *mcu = dev_get_drvdata(dev);
++
++ return sysfs_emit(buf, "%d\n", mcu->front_button_poweron);
++}
++
++static ssize_t front_button_poweron_store(struct device *dev,
++ struct device_attribute *a,
++ const char *buf, size_t count)
++{
++ struct omnia_mcu *mcu = dev_get_drvdata(dev);
++ bool val;
++ int err;
++
++ err = kstrtobool(buf, &val);
++ if (err)
++ return err;
++
++ mcu->front_button_poweron = val;
++
++ return count;
++}
++static DEVICE_ATTR_RW(front_button_poweron);
++
++static struct attribute *omnia_mcu_poweroff_attrs[] = {
++ &dev_attr_front_button_poweron.attr,
++ NULL
++};
++
++static umode_t poweroff_attrs_visible(struct kobject *kobj, struct attribute *a,
++ int n)
++{
++ struct device *dev = kobj_to_dev(kobj);
++ struct omnia_mcu *mcu = dev_get_drvdata(dev);
++
++ if (mcu->features & OMNIA_FEAT_POWEROFF_WAKEUP)
++ return a->mode;
++
++ return 0;
++}
++
++const struct attribute_group omnia_mcu_poweroff_group = {
++ .attrs = omnia_mcu_poweroff_attrs,
++ .is_visible = poweroff_attrs_visible,
++};
++
++int omnia_mcu_register_sys_off_and_wakeup(struct omnia_mcu *mcu)
++{
++ struct device *dev = &mcu->client->dev;
++ int err;
++
++ /* MCU restart is always available */
++ err = devm_register_sys_off_handler(dev, SYS_OFF_MODE_RESTART,
++ SYS_OFF_PRIO_FIRMWARE,
++ omnia_restart, mcu);
++ if (err)
++ return dev_err_probe(dev, err,
++ "Cannot register system restart handler\n");
++
++ /*
++ * Poweroff and wakeup are available only if POWEROFF_WAKEUP feature is
++ * present.
++ */
++ if (!(mcu->features & OMNIA_FEAT_POWEROFF_WAKEUP))
++ return 0;
++
++ err = devm_register_sys_off_handler(dev, SYS_OFF_MODE_POWER_OFF,
++ SYS_OFF_PRIO_FIRMWARE,
++ omnia_power_off, mcu);
++ if (err)
++ return dev_err_probe(dev, err,
++ "Cannot register system power off handler\n");
++
++ mcu->rtcdev = devm_rtc_allocate_device(dev);
++ if (IS_ERR(mcu->rtcdev))
++ return dev_err_probe(dev, PTR_ERR(mcu->rtcdev),
++ "Cannot allocate RTC device\n");
++
++ mcu->rtcdev->ops = &omnia_rtc_ops;
++ mcu->rtcdev->range_max = U32_MAX;
++ set_bit(RTC_FEATURE_ALARM_WAKEUP_ONLY, mcu->rtcdev->features);
++
++ err = devm_rtc_register_device(mcu->rtcdev);
++ if (err)
++ return dev_err_probe(dev, err, "Cannot register RTC device\n");
++
++ mcu->front_button_poweron = true;
++
++ return 0;
++}
+--- a/drivers/platform/cznic/turris-omnia-mcu.h
++++ b/drivers/platform/cznic/turris-omnia-mcu.h
+@@ -15,8 +15,10 @@
+ #include <linux/types.h>
+ #include <linux/workqueue.h>
+ #include <asm/byteorder.h>
++#include <asm/unaligned.h>
+
+ struct i2c_client;
++struct rtc_device;
+
+ struct omnia_mcu {
+ struct i2c_client *client;
+@@ -36,6 +38,11 @@ struct omnia_mcu {
+ struct delayed_work button_release_emul_work;
+ unsigned long last_status;
+ bool button_pressed_emul;
++
++ /* RTC device for configuring wake-up */
++ struct rtc_device *rtcdev;
++ u32 rtc_alarm;
++ bool front_button_poweron;
+ };
+
+ int omnia_cmd_write_read(const struct i2c_client *client,
+@@ -48,6 +55,17 @@ static inline int omnia_cmd_write(const
+ return omnia_cmd_write_read(client, cmd, len, NULL, 0);
+ }
+
++static inline int omnia_cmd_write_u32(const struct i2c_client *client, u8 cmd,
++ u32 val)
++{
++ u8 buf[5];
++
++ buf[0] = cmd;
++ put_unaligned_le32(val, &buf[1]);
++
++ return omnia_cmd_write(client, buf, sizeof(buf));
++}
++
+ static inline int omnia_cmd_read(const struct i2c_client *client, u8 cmd,
+ void *reply, unsigned int len)
+ {
+@@ -136,7 +154,9 @@ static inline int omnia_cmd_read_u8(cons
+ }
+
+ extern const struct attribute_group omnia_mcu_gpio_group;
++extern const struct attribute_group omnia_mcu_poweroff_group;
+
+ int omnia_mcu_register_gpiochip(struct omnia_mcu *mcu);
++int omnia_mcu_register_sys_off_and_wakeup(struct omnia_mcu *mcu);
+
+ #endif /* __TURRIS_OMNIA_MCU_H */
diff --git a/target/linux/mvebu/patches-6.6/820-v6.11-05-platform-cznic-turris-omnia-mcu-Add-support-for-MCU-.patch b/target/linux/mvebu/patches-6.6/820-v6.11-05-platform-cznic-turris-omnia-mcu-Add-support-for-MCU-.patch
new file mode 100644
index 0000000000..cf3f88bfcf
--- /dev/null
+++ b/target/linux/mvebu/patches-6.6/820-v6.11-05-platform-cznic-turris-omnia-mcu-Add-support-for-MCU-.patch
@@ -0,0 +1,250 @@
+From 33ae4e4c86bc6ff298489fb8b743e2743dd0af6d Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
+Date: Mon, 1 Jul 2024 13:30:07 +0200
+Subject: [PATCH 05/11] platform: cznic: turris-omnia-mcu: Add support for MCU
+ watchdog
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add support for the watchdog mechanism provided by the MCU.
+
+Signed-off-by: Marek Behún <kabel@kernel.org>
+Reviewed-by: Andy Shevchenko <andy@kernel.org>
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+Acked-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Link: https://lore.kernel.org/r/20240701113010.16447-6-kabel@kernel.org
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+---
+ drivers/platform/cznic/Kconfig | 2 +
+ drivers/platform/cznic/Makefile | 1 +
+ .../platform/cznic/turris-omnia-mcu-base.c | 4 +
+ .../cznic/turris-omnia-mcu-watchdog.c | 130 ++++++++++++++++++
+ drivers/platform/cznic/turris-omnia-mcu.h | 24 ++++
+ 5 files changed, 161 insertions(+)
+ create mode 100644 drivers/platform/cznic/turris-omnia-mcu-watchdog.c
+
+--- a/drivers/platform/cznic/Kconfig
++++ b/drivers/platform/cznic/Kconfig
+@@ -19,6 +19,7 @@ config TURRIS_OMNIA_MCU
+ select GPIOLIB
+ select GPIOLIB_IRQCHIP
+ select RTC_CLASS
++ select WATCHDOG_CORE
+ help
+ Say Y here to add support for the features implemented by the
+ microcontroller on the CZ.NIC's Turris Omnia SOHO router.
+@@ -26,6 +27,7 @@ config TURRIS_OMNIA_MCU
+ - board poweroff into true low power mode (with voltage regulators
+ disabled) and the ability to configure wake up from this mode (via
+ rtcwake)
++ - MCU watchdog
+ - GPIO pins
+ - to get front button press events (the front button can be
+ configured either to generate press events to the CPU or to change
+--- a/drivers/platform/cznic/Makefile
++++ b/drivers/platform/cznic/Makefile
+@@ -4,3 +4,4 @@ obj-$(CONFIG_TURRIS_OMNIA_MCU) += turris
+ turris-omnia-mcu-y := turris-omnia-mcu-base.o
+ turris-omnia-mcu-y += turris-omnia-mcu-gpio.o
+ turris-omnia-mcu-y += turris-omnia-mcu-sys-off-wakeup.o
++turris-omnia-mcu-y += turris-omnia-mcu-watchdog.o
+--- a/drivers/platform/cznic/turris-omnia-mcu-base.c
++++ b/drivers/platform/cznic/turris-omnia-mcu-base.c
+@@ -376,6 +376,10 @@ static int omnia_mcu_probe(struct i2c_cl
+ if (err)
+ return err;
+
++ err = omnia_mcu_register_watchdog(mcu);
++ if (err)
++ return err;
++
+ return omnia_mcu_register_gpiochip(mcu);
+ }
+
+--- /dev/null
++++ b/drivers/platform/cznic/turris-omnia-mcu-watchdog.c
+@@ -0,0 +1,130 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * CZ.NIC's Turris Omnia MCU watchdog driver
++ *
++ * 2024 by Marek Behún <kabel@kernel.org>
++ */
++
++#include <linux/bitops.h>
++#include <linux/device.h>
++#include <linux/i2c.h>
++#include <linux/moduleparam.h>
++#include <linux/types.h>
++#include <linux/units.h>
++#include <linux/watchdog.h>
++
++#include <linux/turris-omnia-mcu-interface.h>
++#include "turris-omnia-mcu.h"
++
++#define WATCHDOG_TIMEOUT 120
++
++static unsigned int timeout;
++module_param(timeout, int, 0);
++MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds");
++
++static bool nowayout = WATCHDOG_NOWAYOUT;
++module_param(nowayout, bool, 0);
++MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
++ __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
++
++static int omnia_wdt_start(struct watchdog_device *wdt)
++{
++ struct omnia_mcu *mcu = watchdog_get_drvdata(wdt);
++
++ return omnia_cmd_write_u8(mcu->client, OMNIA_CMD_SET_WATCHDOG_STATE, 1);
++}
++
++static int omnia_wdt_stop(struct watchdog_device *wdt)
++{
++ struct omnia_mcu *mcu = watchdog_get_drvdata(wdt);
++
++ return omnia_cmd_write_u8(mcu->client, OMNIA_CMD_SET_WATCHDOG_STATE, 0);
++}
++
++static int omnia_wdt_ping(struct watchdog_device *wdt)
++{
++ struct omnia_mcu *mcu = watchdog_get_drvdata(wdt);
++
++ return omnia_cmd_write_u8(mcu->client, OMNIA_CMD_SET_WATCHDOG_STATE, 1);
++}
++
++static int omnia_wdt_set_timeout(struct watchdog_device *wdt,
++ unsigned int timeout)
++{
++ struct omnia_mcu *mcu = watchdog_get_drvdata(wdt);
++
++ return omnia_cmd_write_u16(mcu->client, OMNIA_CMD_SET_WDT_TIMEOUT,
++ timeout * DECI);
++}
++
++static unsigned int omnia_wdt_get_timeleft(struct watchdog_device *wdt)
++{
++ struct omnia_mcu *mcu = watchdog_get_drvdata(wdt);
++ u16 timeleft;
++ int err;
++
++ err = omnia_cmd_read_u16(mcu->client, OMNIA_CMD_GET_WDT_TIMELEFT,
++ &timeleft);
++ if (err) {
++ dev_err(&mcu->client->dev, "Cannot get watchdog timeleft: %d\n",
++ err);
++ return 0;
++ }
++
++ return timeleft / DECI;
++}
++
++static const struct watchdog_info omnia_wdt_info = {
++ .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
++ .identity = "Turris Omnia MCU Watchdog",
++};
++
++static const struct watchdog_ops omnia_wdt_ops = {
++ .owner = THIS_MODULE,
++ .start = omnia_wdt_start,
++ .stop = omnia_wdt_stop,
++ .ping = omnia_wdt_ping,
++ .set_timeout = omnia_wdt_set_timeout,
++ .get_timeleft = omnia_wdt_get_timeleft,
++};
++
++int omnia_mcu_register_watchdog(struct omnia_mcu *mcu)
++{
++ struct device *dev = &mcu->client->dev;
++ u8 state;
++ int err;
++
++ if (!(mcu->features & OMNIA_FEAT_WDT_PING))
++ return 0;
++
++ mcu->wdt.info = &omnia_wdt_info;
++ mcu->wdt.ops = &omnia_wdt_ops;
++ mcu->wdt.parent = dev;
++ mcu->wdt.min_timeout = 1;
++ mcu->wdt.max_timeout = 65535 / DECI;
++
++ mcu->wdt.timeout = WATCHDOG_TIMEOUT;
++ watchdog_init_timeout(&mcu->wdt, timeout, dev);
++
++ watchdog_set_drvdata(&mcu->wdt, mcu);
++
++ omnia_wdt_set_timeout(&mcu->wdt, mcu->wdt.timeout);
++
++ err = omnia_cmd_read_u8(mcu->client, OMNIA_CMD_GET_WATCHDOG_STATE,
++ &state);
++ if (err)
++ return dev_err_probe(dev, err,
++ "Cannot get MCU watchdog state\n");
++
++ if (state)
++ set_bit(WDOG_HW_RUNNING, &mcu->wdt.status);
++
++ watchdog_set_nowayout(&mcu->wdt, nowayout);
++ watchdog_stop_on_reboot(&mcu->wdt);
++ err = devm_watchdog_register_device(dev, &mcu->wdt);
++ if (err)
++ return dev_err_probe(dev, err,
++ "Cannot register MCU watchdog\n");
++
++ return 0;
++}
+--- a/drivers/platform/cznic/turris-omnia-mcu.h
++++ b/drivers/platform/cznic/turris-omnia-mcu.h
+@@ -13,6 +13,7 @@
+ #include <linux/if_ether.h>
+ #include <linux/mutex.h>
+ #include <linux/types.h>
++#include <linux/watchdog.h>
+ #include <linux/workqueue.h>
+ #include <asm/byteorder.h>
+ #include <asm/unaligned.h>
+@@ -43,6 +44,9 @@ struct omnia_mcu {
+ struct rtc_device *rtcdev;
+ u32 rtc_alarm;
+ bool front_button_poweron;
++
++ /* MCU watchdog */
++ struct watchdog_device wdt;
+ };
+
+ int omnia_cmd_write_read(const struct i2c_client *client,
+@@ -55,6 +59,25 @@ static inline int omnia_cmd_write(const
+ return omnia_cmd_write_read(client, cmd, len, NULL, 0);
+ }
+
++static inline int omnia_cmd_write_u8(const struct i2c_client *client, u8 cmd,
++ u8 val)
++{
++ u8 buf[2] = { cmd, val };
++
++ return omnia_cmd_write(client, buf, sizeof(buf));
++}
++
++static inline int omnia_cmd_write_u16(const struct i2c_client *client, u8 cmd,
++ u16 val)
++{
++ u8 buf[3];
++
++ buf[0] = cmd;
++ put_unaligned_le16(val, &buf[1]);
++
++ return omnia_cmd_write(client, buf, sizeof(buf));
++}
++
+ static inline int omnia_cmd_write_u32(const struct i2c_client *client, u8 cmd,
+ u32 val)
+ {
+@@ -158,5 +181,6 @@ extern const struct attribute_group omni
+
+ int omnia_mcu_register_gpiochip(struct omnia_mcu *mcu);
+ int omnia_mcu_register_sys_off_and_wakeup(struct omnia_mcu *mcu);
++int omnia_mcu_register_watchdog(struct omnia_mcu *mcu);
+
+ #endif /* __TURRIS_OMNIA_MCU_H */
diff --git a/target/linux/mvebu/patches-6.6/820-v6.11-06-platform-cznic-turris-omnia-mcu-Add-support-for-MCU-.patch b/target/linux/mvebu/patches-6.6/820-v6.11-06-platform-cznic-turris-omnia-mcu-Add-support-for-MCU-.patch
new file mode 100644
index 0000000000..35387e34c7
--- /dev/null
+++ b/target/linux/mvebu/patches-6.6/820-v6.11-06-platform-cznic-turris-omnia-mcu-Add-support-for-MCU-.patch
@@ -0,0 +1,225 @@
+From b3ed8645c45567b598bef0868dca166f8ed166a0 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
+Date: Mon, 1 Jul 2024 13:30:08 +0200
+Subject: [PATCH 06/11] platform: cznic: turris-omnia-mcu: Add support for MCU
+ provided TRNG
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add support for true random number generator provided by the MCU.
+New Omnia boards come without the Atmel SHA204-A chip. Instead the
+crypto functionality is provided by new microcontroller, which has
+a TRNG peripheral.
+
+Signed-off-by: Marek Behún <kabel@kernel.org>
+Acked-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Link: https://lore.kernel.org/r/20240701113010.16447-7-kabel@kernel.org
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+---
+ drivers/platform/cznic/Kconfig | 2 +
+ drivers/platform/cznic/Makefile | 1 +
+ .../platform/cznic/turris-omnia-mcu-base.c | 6 +-
+ .../platform/cznic/turris-omnia-mcu-gpio.c | 2 +-
+ .../platform/cznic/turris-omnia-mcu-trng.c | 105 ++++++++++++++++++
+ drivers/platform/cznic/turris-omnia-mcu.h | 8 ++
+ 6 files changed, 122 insertions(+), 2 deletions(-)
+ create mode 100644 drivers/platform/cznic/turris-omnia-mcu-trng.c
+
+--- a/drivers/platform/cznic/Kconfig
++++ b/drivers/platform/cznic/Kconfig
+@@ -18,6 +18,7 @@ config TURRIS_OMNIA_MCU
+ depends on I2C
+ select GPIOLIB
+ select GPIOLIB_IRQCHIP
++ select HW_RANDOM
+ select RTC_CLASS
+ select WATCHDOG_CORE
+ help
+@@ -27,6 +28,7 @@ config TURRIS_OMNIA_MCU
+ - board poweroff into true low power mode (with voltage regulators
+ disabled) and the ability to configure wake up from this mode (via
+ rtcwake)
++ - true random number generator (if available on the MCU)
+ - MCU watchdog
+ - GPIO pins
+ - to get front button press events (the front button can be
+--- a/drivers/platform/cznic/Makefile
++++ b/drivers/platform/cznic/Makefile
+@@ -4,4 +4,5 @@ obj-$(CONFIG_TURRIS_OMNIA_MCU) += turris
+ turris-omnia-mcu-y := turris-omnia-mcu-base.o
+ turris-omnia-mcu-y += turris-omnia-mcu-gpio.o
+ turris-omnia-mcu-y += turris-omnia-mcu-sys-off-wakeup.o
++turris-omnia-mcu-y += turris-omnia-mcu-trng.o
+ turris-omnia-mcu-y += turris-omnia-mcu-watchdog.o
+--- a/drivers/platform/cznic/turris-omnia-mcu-base.c
++++ b/drivers/platform/cznic/turris-omnia-mcu-base.c
+@@ -380,7 +380,11 @@ static int omnia_mcu_probe(struct i2c_cl
+ if (err)
+ return err;
+
+- return omnia_mcu_register_gpiochip(mcu);
++ err = omnia_mcu_register_gpiochip(mcu);
++ if (err)
++ return err;
++
++ return omnia_mcu_register_trng(mcu);
+ }
+
+ static const struct of_device_id of_omnia_mcu_match[] = {
+--- a/drivers/platform/cznic/turris-omnia-mcu-gpio.c
++++ b/drivers/platform/cznic/turris-omnia-mcu-gpio.c
+@@ -194,7 +194,7 @@ static const struct omnia_gpio omnia_gpi
+ };
+
+ /* mapping from interrupts to indexes of GPIOs in the omnia_gpios array */
+-static const u8 omnia_int_to_gpio_idx[32] = {
++const u8 omnia_int_to_gpio_idx[32] = {
+ [__bf_shf(OMNIA_INT_CARD_DET)] = 4,
+ [__bf_shf(OMNIA_INT_MSATA_IND)] = 5,
+ [__bf_shf(OMNIA_INT_USB30_OVC)] = 6,
+--- /dev/null
++++ b/drivers/platform/cznic/turris-omnia-mcu-trng.c
+@@ -0,0 +1,105 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * CZ.NIC's Turris Omnia MCU TRNG driver
++ *
++ * 2024 by Marek Behún <kabel@kernel.org>
++ */
++
++#include <linux/bitfield.h>
++#include <linux/completion.h>
++#include <linux/container_of.h>
++#include <linux/errno.h>
++#include <linux/gpio/consumer.h>
++#include <linux/gpio/driver.h>
++#include <linux/hw_random.h>
++#include <linux/i2c.h>
++#include <linux/interrupt.h>
++#include <linux/minmax.h>
++#include <linux/string.h>
++#include <linux/types.h>
++
++#include "../../gpio/gpiolib.h"
++
++#include <linux/turris-omnia-mcu-interface.h>
++#include "turris-omnia-mcu.h"
++
++#define OMNIA_CMD_TRNG_MAX_ENTROPY_LEN 64
++
++static irqreturn_t omnia_trng_irq_handler(int irq, void *dev_id)
++{
++ struct omnia_mcu *mcu = dev_id;
++
++ complete(&mcu->trng_entropy_ready);
++
++ return IRQ_HANDLED;
++}
++
++static int omnia_trng_read(struct hwrng *rng, void *data, size_t max, bool wait)
++{
++ struct omnia_mcu *mcu = container_of(rng, struct omnia_mcu, trng);
++ u8 reply[1 + OMNIA_CMD_TRNG_MAX_ENTROPY_LEN];
++ int err, bytes;
++
++ if (!wait && !completion_done(&mcu->trng_entropy_ready))
++ return 0;
++
++ do {
++ if (wait_for_completion_interruptible(&mcu->trng_entropy_ready))
++ return -ERESTARTSYS;
++
++ err = omnia_cmd_read(mcu->client,
++ OMNIA_CMD_TRNG_COLLECT_ENTROPY,
++ reply, sizeof(reply));
++ if (err)
++ return err;
++
++ bytes = min3(reply[0], max, OMNIA_CMD_TRNG_MAX_ENTROPY_LEN);
++ } while (wait && !bytes);
++
++ memcpy(data, &reply[1], bytes);
++
++ return bytes;
++}
++
++int omnia_mcu_register_trng(struct omnia_mcu *mcu)
++{
++ struct device *dev = &mcu->client->dev;
++ u8 irq_idx, dummy;
++ int irq, err;
++
++ if (!(mcu->features & OMNIA_FEAT_TRNG))
++ return 0;
++
++ irq_idx = omnia_int_to_gpio_idx[__bf_shf(OMNIA_INT_TRNG)];
++ irq = gpiod_to_irq(gpiochip_get_desc(&mcu->gc, irq_idx));
++ if (!irq)
++ return dev_err_probe(dev, -ENXIO, "Cannot get TRNG IRQ\n");
++
++ /*
++ * If someone else cleared the TRNG interrupt but did not read the
++ * entropy, a new interrupt won't be generated, and entropy collection
++ * will be stuck. Ensure an interrupt will be generated by executing
++ * the collect entropy command (and discarding the result).
++ */
++ err = omnia_cmd_read(mcu->client, OMNIA_CMD_TRNG_COLLECT_ENTROPY,
++ &dummy, 1);
++ if (err)
++ return err;
++
++ init_completion(&mcu->trng_entropy_ready);
++
++ err = devm_request_threaded_irq(dev, irq, NULL, omnia_trng_irq_handler,
++ IRQF_ONESHOT, "turris-omnia-mcu-trng",
++ mcu);
++ if (err)
++ return dev_err_probe(dev, err, "Cannot request TRNG IRQ\n");
++
++ mcu->trng.name = "turris-omnia-mcu-trng";
++ mcu->trng.read = omnia_trng_read;
++
++ err = devm_hwrng_register(dev, &mcu->trng);
++ if (err)
++ return dev_err_probe(dev, err, "Cannot register TRNG\n");
++
++ return 0;
++}
+--- a/drivers/platform/cznic/turris-omnia-mcu.h
++++ b/drivers/platform/cznic/turris-omnia-mcu.h
+@@ -9,7 +9,9 @@
+ #define __TURRIS_OMNIA_MCU_H
+
+ #include <linux/bitops.h>
++#include <linux/completion.h>
+ #include <linux/gpio/driver.h>
++#include <linux/hw_random.h>
+ #include <linux/if_ether.h>
+ #include <linux/mutex.h>
+ #include <linux/types.h>
+@@ -47,6 +49,10 @@ struct omnia_mcu {
+
+ /* MCU watchdog */
+ struct watchdog_device wdt;
++
++ /* true random number generator */
++ struct hwrng trng;
++ struct completion trng_entropy_ready;
+ };
+
+ int omnia_cmd_write_read(const struct i2c_client *client,
+@@ -176,11 +182,13 @@ static inline int omnia_cmd_read_u8(cons
+ return omnia_cmd_read(client, cmd, reply, sizeof(*reply));
+ }
+
++extern const u8 omnia_int_to_gpio_idx[32];
+ extern const struct attribute_group omnia_mcu_gpio_group;
+ extern const struct attribute_group omnia_mcu_poweroff_group;
+
+ int omnia_mcu_register_gpiochip(struct omnia_mcu *mcu);
+ int omnia_mcu_register_sys_off_and_wakeup(struct omnia_mcu *mcu);
++int omnia_mcu_register_trng(struct omnia_mcu *mcu);
+ int omnia_mcu_register_watchdog(struct omnia_mcu *mcu);
+
+ #endif /* __TURRIS_OMNIA_MCU_H */
diff --git a/target/linux/mvebu/patches-6.6/820-v6.11-07-ARM-dts-turris-omnia-Add-MCU-system-controller-node.patch b/target/linux/mvebu/patches-6.6/820-v6.11-07-ARM-dts-turris-omnia-Add-MCU-system-controller-node.patch
new file mode 100644
index 0000000000..ad65de2f52
--- /dev/null
+++ b/target/linux/mvebu/patches-6.6/820-v6.11-07-ARM-dts-turris-omnia-Add-MCU-system-controller-node.patch
@@ -0,0 +1,69 @@
+From 4f11095a4ae00b2fe4cebb21e36ee37cc62f5e1a Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
+Date: Mon, 1 Jul 2024 13:30:09 +0200
+Subject: [PATCH 07/11] ARM: dts: turris-omnia: Add MCU system-controller node
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Turris Omnia's MCU provides various features that can be configured over
+I2C at address 0x2a. Add device-tree node.
+
+This does not carry a Fixes tag - we do not want this to get backported
+to stable kernels for the following reason: U-Boot since v2022.10
+inserts a phy-reset-gpio property into the WAN ethernet node pointing to
+the MCU node if it finds the MCU node with a cznic,turris-omnia-mcu
+compatible. Thus if this change got backported to a stable kernel, the
+WAN interface driver would defer probe indefinitely (since it would wait
+for the turris-omnia-mcu driver which would not be present).
+
+Signed-off-by: Marek Behún <kabel@kernel.org>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Reviewed-by: Andy Shevchenko <andy@kernel.org>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+Acked-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Acked-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Link: https://lore.kernel.org/r/20240701113010.16447-8-kabel@kernel.org
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+---
+ .../dts/marvell/armada-385-turris-omnia.dts | 22 ++++++++++++++++++-
+ 1 file changed, 21 insertions(+), 1 deletion(-)
+
+--- a/arch/arm/boot/dts/marvell/armada-385-turris-omnia.dts
++++ b/arch/arm/boot/dts/marvell/armada-385-turris-omnia.dts
+@@ -218,7 +218,22 @@
+ #size-cells = <0>;
+ reg = <0>;
+
+- /* STM32F0 command interface at address 0x2a */
++ mcu: system-controller@2a {
++ compatible = "cznic,turris-omnia-mcu";
++ reg = <0x2a>;
++
++ pinctrl-names = "default";
++ pinctrl-0 = <&mcu_pins>;
++
++ interrupt-parent = <&gpio1>;
++ interrupts = <11 IRQ_TYPE_NONE>;
++
++ gpio-controller;
++ #gpio-cells = <3>;
++
++ interrupt-controller;
++ #interrupt-cells = <2>;
++ };
+
+ led-controller@2b {
+ compatible = "cznic,turris-omnia-leds";
+@@ -503,6 +518,11 @@
+ };
+
+ &pinctrl {
++ mcu_pins: mcu-pins {
++ marvell,pins = "mpp43";
++ marvell,function = "gpio";
++ };
++
+ pcawan_pins: pcawan-pins {
+ marvell,pins = "mpp46";
+ marvell,function = "gpio";
diff --git a/target/linux/mvebu/patches-6.6/820-v6.11-08-ARM-dts-turris-omnia-Add-GPIO-key-node-for-front-but.patch b/target/linux/mvebu/patches-6.6/820-v6.11-08-ARM-dts-turris-omnia-Add-GPIO-key-node-for-front-but.patch
new file mode 100644
index 0000000000..4b36167d66
--- /dev/null
+++ b/target/linux/mvebu/patches-6.6/820-v6.11-08-ARM-dts-turris-omnia-Add-GPIO-key-node-for-front-but.patch
@@ -0,0 +1,46 @@
+From c3eeabe0b8d22d7c869278cc0cb35b83512fbed5 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
+Date: Mon, 1 Jul 2024 13:30:10 +0200
+Subject: [PATCH 08/11] ARM: dts: turris-omnia: Add GPIO key node for front
+ button
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Now that we have the MCU device-tree node, which acts as a GPIO
+controller, add GPIO key node for the front button.
+
+Signed-off-by: Marek Behún <kabel@kernel.org>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Reviewed-by: Andy Shevchenko <andy@kernel.org>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+Acked-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Acked-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Link: https://lore.kernel.org/r/20240701113010.16447-9-kabel@kernel.org
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+---
+ .../boot/dts/marvell/armada-385-turris-omnia.dts | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+--- a/arch/arm/boot/dts/marvell/armada-385-turris-omnia.dts
++++ b/arch/arm/boot/dts/marvell/armada-385-turris-omnia.dts
+@@ -112,6 +112,19 @@
+ status = "disabled";
+ };
+
++ gpio-keys {
++ compatible = "gpio-keys";
++
++ front-button {
++ label = "Front Button";
++ linux,code = <KEY_VENDOR>;
++ linux,can-disable;
++ gpios = <&mcu 0 12 GPIO_ACTIVE_HIGH>;
++ /* debouncing is done by the microcontroller */
++ debounce-interval = <0>;
++ };
++ };
++
+ sound {
+ compatible = "simple-audio-card";
+ simple-audio-card,name = "SPDIF";
diff --git a/target/linux/mvebu/patches-6.6/820-v6.11-09-platform-cznic-turris-omnia-mcu-Depend-on-OF.patch b/target/linux/mvebu/patches-6.6/820-v6.11-09-platform-cznic-turris-omnia-mcu-Depend-on-OF.patch
new file mode 100644
index 0000000000..80c9e1a3cc
--- /dev/null
+++ b/target/linux/mvebu/patches-6.6/820-v6.11-09-platform-cznic-turris-omnia-mcu-Depend-on-OF.patch
@@ -0,0 +1,32 @@
+From 08838657bbc35494276c7ba4ef53f30a9816f8c9 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
+Date: Mon, 8 Jul 2024 13:40:01 +0200
+Subject: [PATCH 09/11] platform: cznic: turris-omnia-mcu: Depend on OF
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add depend on OF, otherwise the compilation fails with
+ error: no member named 'of_gpio_n_cells' in 'struct gpio_chip'
+ error: no member named 'of_xlate' in 'struct gpio_chip'
+
+Fixes: dfa556e45ae9 ("platform: cznic: turris-omnia-mcu: Add support for MCU connected GPIOs")
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202407031646.trNSwajF-lkp@intel.com/
+Signed-off-by: Marek Behún <kabel@kernel.org>
+Link: https://lore.kernel.org/r/20240708114002.4285-2-kabel@kernel.org
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+---
+ drivers/platform/cznic/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/platform/cznic/Kconfig
++++ b/drivers/platform/cznic/Kconfig
+@@ -16,6 +16,7 @@ config TURRIS_OMNIA_MCU
+ tristate "Turris Omnia MCU driver"
+ depends on MACH_ARMADA_38X || COMPILE_TEST
+ depends on I2C
++ depends on OF
+ select GPIOLIB
+ select GPIOLIB_IRQCHIP
+ select HW_RANDOM
diff --git a/target/linux/mvebu/patches-6.6/820-v6.11-10-platform-cznic-turris-omnia-mcu-Depend-on-WATCHDOG.patch b/target/linux/mvebu/patches-6.6/820-v6.11-10-platform-cznic-turris-omnia-mcu-Depend-on-WATCHDOG.patch
new file mode 100644
index 0000000000..50e028752a
--- /dev/null
+++ b/target/linux/mvebu/patches-6.6/820-v6.11-10-platform-cznic-turris-omnia-mcu-Depend-on-WATCHDOG.patch
@@ -0,0 +1,32 @@
+From 5e425e6eca155c162da58d4e58e896ed4109c7fd Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
+Date: Mon, 8 Jul 2024 13:40:02 +0200
+Subject: [PATCH 10/11] platform: cznic: turris-omnia-mcu: Depend on WATCHDOG
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add depend on WATCHDOG, otherwise modpost fails with
+ ERROR: modpost: "watchdog_init_timeout" [drivers/platform/cznic/turris-omnia-mcu.ko] undefined!
+ ERROR: modpost: "devm_watchdog_register_device" [drivers/platform/cznic/turris-omnia-mcu.ko] undefined!
+
+Fixes: ab89fb5fb92c ("platform: cznic: turris-omnia-mcu: Add support for MCU watchdog")
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202407040711.g19y3cWq-lkp@intel.com/
+Signed-off-by: Marek Behún <kabel@kernel.org>
+Link: https://lore.kernel.org/r/20240708114002.4285-3-kabel@kernel.org
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+---
+ drivers/platform/cznic/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/platform/cznic/Kconfig
++++ b/drivers/platform/cznic/Kconfig
+@@ -17,6 +17,7 @@ config TURRIS_OMNIA_MCU
+ depends on MACH_ARMADA_38X || COMPILE_TEST
+ depends on I2C
+ depends on OF
++ depends on WATCHDOG
+ select GPIOLIB
+ select GPIOLIB_IRQCHIP
+ select HW_RANDOM
diff --git a/target/linux/mvebu/patches-6.6/820-v6.11-11-platform-cznic-turris-omnia-mcu-fix-Kconfig-dependen.patch b/target/linux/mvebu/patches-6.6/820-v6.11-11-platform-cznic-turris-omnia-mcu-fix-Kconfig-dependen.patch
new file mode 100644
index 0000000000..30a476586e
--- /dev/null
+++ b/target/linux/mvebu/patches-6.6/820-v6.11-11-platform-cznic-turris-omnia-mcu-fix-Kconfig-dependen.patch
@@ -0,0 +1,45 @@
+From 24c68c2525de5fcd0f3b16b2ad1028fb13b53393 Mon Sep 17 00:00:00 2001
+From: Arnd Bergmann <arnd@arndb.de>
+Date: Mon, 15 Jul 2024 08:02:30 +0200
+Subject: [PATCH 11/11] platform: cznic: turris-omnia-mcu: fix Kconfig
+ dependencies
+
+The newly added driver causes a Kconfig warning:
+
+WARNING: unmet direct dependencies detected for RTC_CLASS
+ Depends on [n]: !S390 [=y]
+ Selected by [m]:
+ - TURRIS_OMNIA_MCU [=m] && CZNIC_PLATFORMS [=y] && (MACH_ARMADA_38X || COMPILE_TEST [=y]) && I2C [=m] && OF [=y] && WATCHDOG [=y]
+
+The problem here is that it selects entire subsystems, which normal
+device drivers should not do. Changes all of these to 'depends on'
+instead.
+
+Fixes: dfa556e45ae9e ("platform: cznic: turris-omnia-mcu: Add support for MCU connected GPIOs")
+Fixes: 90e700fd12b61 ("platform: cznic: turris-omnia-mcu: Add support for poweroff and wakeup")
+Fixes: ab89fb5fb92c7 ("platform: cznic: turris-omnia-mcu: Add support for MCU watchdog")
+Fixes: 41bb142a40289 ("platform: cznic: turris-omnia-mcu: Add support for MCU provided TRNG")
+Reported-by: Nathan Chancellor <nathan@kernel.org>
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+---
+ drivers/platform/cznic/Kconfig | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/platform/cznic/Kconfig
++++ b/drivers/platform/cznic/Kconfig
+@@ -18,11 +18,11 @@ config TURRIS_OMNIA_MCU
+ depends on I2C
+ depends on OF
+ depends on WATCHDOG
+- select GPIOLIB
++ depends on GPIOLIB
++ depends on HW_RANDOM
++ depends on RTC_CLASS
++ depends on WATCHDOG_CORE
+ select GPIOLIB_IRQCHIP
+- select HW_RANDOM
+- select RTC_CLASS
+- select WATCHDOG_CORE
+ help
+ Say Y here to add support for the features implemented by the
+ microcontroller on the CZ.NIC's Turris Omnia SOHO router.
diff --git a/target/linux/mvebu/patches-6.6/907-MAINTAINERS-Add-an-entry-for-the-IEI-WT61P803-PUZZLE.patch b/target/linux/mvebu/patches-6.6/907-MAINTAINERS-Add-an-entry-for-the-IEI-WT61P803-PUZZLE.patch
index 2a8397d0b5..dad8c16be1 100644
--- a/target/linux/mvebu/patches-6.6/907-MAINTAINERS-Add-an-entry-for-the-IEI-WT61P803-PUZZLE.patch
+++ b/target/linux/mvebu/patches-6.6/907-MAINTAINERS-Add-an-entry-for-the-IEI-WT61P803-PUZZLE.patch
@@ -16,7 +16,7 @@ Cc: Robert Marko <robert.marko@sartura.hr>
--- a/MAINTAINERS
+++ b/MAINTAINERS
-@@ -10138,6 +10138,22 @@ IFCVF VIRTIO DATA PATH ACCELERATOR
+@@ -10142,6 +10142,22 @@ IFCVF VIRTIO DATA PATH ACCELERATOR
R: Zhu Lingshan <lingshan.zhu@intel.com>
F: drivers/vdpa/ifcvf/
diff --git a/target/linux/octeon/Makefile b/target/linux/octeon/Makefile
index fa3da97579..c59b0af6a2 100644
--- a/target/linux/octeon/Makefile
+++ b/target/linux/octeon/Makefile
@@ -10,7 +10,7 @@ BOARDNAME:=Cavium Networks Octeon
FEATURES:=squashfs ramdisk pci usb
CPU_TYPE:=octeonplus
-KERNEL_PATCHVER:=6.1
+KERNEL_PATCHVER:=6.6
define Target/Description
Build firmware images for Cavium Networks Octeon-based boards.
diff --git a/target/linux/octeon/base-files/lib/preinit/79_move_config b/target/linux/octeon/base-files/lib/preinit/79_move_config
index 01491500a0..db99e02ce8 100644
--- a/target/linux/octeon/base-files/lib/preinit/79_move_config
+++ b/target/linux/octeon/base-files/lib/preinit/79_move_config
@@ -4,28 +4,46 @@ move_config() {
. /lib/upgrade/common.sh
local device="$1"
+ local fstype="$2"
[ -n "$device" ] && [ -b "$device" ] && {
- mount -t vfat "$device" /mnt
+ mount -t "${fstype}" "$device" /mnt
[ -f "/mnt/$BACKUP_FILE" ] && mv -f "/mnt/$BACKUP_FILE" /
umount /mnt
}
}
+octeon_get_n821_disk() {
+ local partnum=$1
+ local MAJOR MINOR DEVNAME DEVTYPE
+ while read line; do
+ export -n "${line}"
+ done < $(find /sys/bus/platform/devices/16f0000000000.ehci/ -path \*block/sd[a-z]/uevent)
+ echo "/dev/${DEVNAME}${partnum}"
+}
+
octeon_move_config() {
. /lib/functions.sh
case "$(board_name)" in
erlite|\
ubnt,usg)
- move_config "/dev/sda1"
+ move_config "/dev/sda1" "vfat"
;;
itus,shield-router)
- move_config "/dev/mmcblk1p1"
+ move_config "/dev/mmcblk1p1" "vfat"
;;
- ubnt,edgerouter-4 | \
+ er|\
+ ubnt,edgerouter-4|\
ubnt,edgerouter-6p)
- move_config "/dev/mmcblk0p1"
+ move_config "/dev/mmcblk0p1" "vfat"
;;
+ cisco,vedge1000)
+ # Copy from the internal USB disk's first partition.
+ # It is resolved from the device path to not be dependent on which
+ # /dev/sd? path it is at, nor which UUID it happens to have.
+ move_config "$(octeon_get_n821_disk 1)" "ext2"
+ ;;
+
esac
}
diff --git a/target/linux/octeon/base-files/lib/upgrade/platform.sh b/target/linux/octeon/base-files/lib/upgrade/platform.sh
index 14b3eefe7e..b8a856712b 100755
--- a/target/linux/octeon/base-files/lib/upgrade/platform.sh
+++ b/target/linux/octeon/base-files/lib/upgrade/platform.sh
@@ -2,11 +2,21 @@
# Copyright (C) 2021 OpenWrt.org
#
+if [ -x /usr/sbin/blkid ]; then
+ RAMFS_COPY_BIN="/usr/sbin/blkid"
+fi
+
platform_get_rootfs() {
local rootfsdev
+ local rootpartuuid
if read cmdline < /proc/cmdline; then
case "$cmdline" in
+ *root=PARTUUID=*)
+ rootpartuuid="${cmdline##*root=PARTUUID=}"
+ rootpartuuid="${rootpartuuid%% *}"
+ rootfsdev="$(blkid -o device -t PARTUUID="${rootpartuuid}")"
+ ;;
*root=*)
rootfsdev="${cmdline##*root=}"
rootfsdev="${rootfsdev%% *}"
@@ -17,10 +27,20 @@ platform_get_rootfs() {
fi
}
+platform_get_n821_disk() {
+ local partnum=$1
+ local DEVNAME
+ while read line; do
+ export -n "${line}"
+ done < $(find /sys/bus/platform/devices/16f0000000000.ehci/ -path \*block/sd[a-z]/uevent)
+ echo "/dev/${DEVNAME}${partnum}"
+}
+
platform_copy_config_helper() {
local device=$1
+ local fstype=$2
- mount -t vfat "$device" /mnt
+ mount -t "${fstype}" "$device" /mnt
cp -af "$UPGRADE_BACKUP" "/mnt/$BACKUP_FILE"
umount /mnt
}
@@ -29,14 +49,18 @@ platform_copy_config() {
case "$(board_name)" in
erlite|\
ubnt,usg)
- platform_copy_config_helper /dev/sda1
+ platform_copy_config_helper /dev/sda1 vfat
;;
itus,shield-router)
- platform_copy_config_helper /dev/mmcblk1p1
+ platform_copy_config_helper /dev/mmcblk1p1 vfat
;;
+ er|\
ubnt,edgerouter-4|\
ubnt,edgerouter-6p)
- platform_copy_config_helper /dev/mmcblk0p1
+ platform_copy_config_helper /dev/mmcblk0p1 vfat
+ ;;
+ cisco,vedge1000)
+ platform_copy_config_helper "$(platform_get_n821_disk 1)" ext2
;;
esac
}
@@ -60,14 +84,26 @@ platform_do_flash() {
echo "flashing Itus Kernel to /boot/$kernel (/dev/mmblk1p1)"
tar -Oxf $tar_file "$board_dir/kernel" > /boot/$kernel
else
- mount -t vfat /dev/$kernel /boot
+ if [ "${board}" = "cisco,vedge1000" ]; then
+ local rootpartuuid
+ rootpartuuid="$(/usr/sbin/blkid -o value -s PARTUUID "${rootfs}")"
+ if [ -n "${rootpartuuid}" ]; then
+ echo "setting root partition to PARTUUID=${rootpartuuid}"
+ fw_setenv bootcmd 'usb start; ext2load usb 0:1 $loadaddr vmlinux.64; bootoctlinux $loadaddr coremask=f endbootargs rootfstype=squashfs rootwait root=PARTUUID='"${rootpartuuid}"
+ else
+ echo "WARNING: unable to figure out root partition UUID, leaving bootcmd unchanged"
+ fi
+ mount -t ext2 "${kernel}" /boot
+ else
+ mount -t vfat "${kernel}" /boot
+ fi
[ -f /boot/vmlinux.64 -a ! -L /boot/vmlinux.64 ] && {
mv /boot/vmlinux.64 /boot/vmlinux.64.previous
mv /boot/vmlinux.64.md5 /boot/vmlinux.64.md5.previous
}
- echo "flashing kernel to /dev/$kernel"
+ echo "flashing kernel to $(awk '/\/boot/ {print $1}' /proc/mounts)"
tar xf $tar_file $board_dir/kernel -O > /boot/vmlinux.64
md5sum /boot/vmlinux.64 | cut -f1 -d " " > /boot/vmlinux.64.md5
fi
@@ -85,20 +121,27 @@ platform_do_upgrade() {
local rootfs="$(platform_get_rootfs)"
local kernel=
+ if [ ! -b "${rootfs}" ] && [ "${board}" = "cisco,vedge1000" ]; then
+ # Default to the built-in USB disk for N821
+ rootfs="$(platform_get_n821_disk 2)"
+ fi
[ -b "${rootfs}" ] || return 1
case "$board" in
er | \
ubnt,edgerouter-4 | \
ubnt,edgerouter-6p)
- kernel=mmcblk0p1
+ kernel=/dev/mmcblk0p1
;;
erlite|\
ubnt,usg)
- kernel=sda1
+ kernel=/dev/sda1
;;
itus,shield-router)
kernel=ItusrouterImage
;;
+ cisco,vedge1000)
+ kernel="$(platform_get_n821_disk 1)"
+ ;;
*)
return 1
esac
@@ -122,7 +165,8 @@ platform_check_image() {
itus,shield-router | \
ubnt,edgerouter-4 | \
ubnt,edgerouter-6p | \
- ubnt,usg)
+ ubnt,usg | \
+ cisco,vedge1000)
local kernel_length=$(tar xf $tar_file $board_dir/kernel -O | wc -c 2> /dev/null)
local rootfs_length=$(tar xf $tar_file $board_dir/root -O | wc -c 2> /dev/null)
[ "$kernel_length" = 0 -o "$rootfs_length" = 0 ] && {
diff --git a/target/linux/octeon/config-6.1 b/target/linux/octeon/config-6.1
deleted file mode 100644
index af5cdf4852..0000000000
--- a/target/linux/octeon/config-6.1
+++ /dev/null
@@ -1,274 +0,0 @@
-CONFIG_64BIT=y
-CONFIG_AHCI_OCTEON=y
-CONFIG_ARCH_DMA_ADDR_T_64BIT=y
-CONFIG_ARCH_HIBERNATION_POSSIBLE=y
-CONFIG_ARCH_KEEP_MEMBLOCK=y
-CONFIG_ARCH_MMAP_RND_BITS=12
-CONFIG_ARCH_MMAP_RND_BITS_MAX=18
-CONFIG_ARCH_MMAP_RND_BITS_MIN=12
-CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=15
-CONFIG_ARCH_SPARSEMEM_ENABLE=y
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
-CONFIG_ATA=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_BLK_MQ_PCI=y
-CONFIG_BUILTIN_DTB=y
-CONFIG_CAVIUM_CN63XXP1=y
-CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE=0
-CONFIG_CAVIUM_OCTEON_LOCK_L2=y
-CONFIG_CAVIUM_OCTEON_LOCK_L2_EXCEPTION=y
-CONFIG_CAVIUM_OCTEON_LOCK_L2_INTERRUPT=y
-CONFIG_CAVIUM_OCTEON_LOCK_L2_LOW_LEVEL_INTERRUPT=y
-CONFIG_CAVIUM_OCTEON_LOCK_L2_MEMCPY=y
-CONFIG_CAVIUM_OCTEON_LOCK_L2_TLB=y
-CONFIG_CAVIUM_OCTEON_SOC=y
-CONFIG_CAVIUM_RESERVE32=0
-CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
-CONFIG_CC_NO_ARRAY_BOUNDS=y
-CONFIG_CEVT_R4K=y
-CONFIG_CLONE_BACKWARDS=y
-# CONFIG_COMMON_CLK is not set
-CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
-CONFIG_COMPAT_32BIT_TIME=y
-CONFIG_CONTEXT_TRACKING=y
-CONFIG_CONTEXT_TRACKING_IDLE=y
-CONFIG_CPU_BIG_ENDIAN=y
-CONFIG_CPU_CAVIUM_OCTEON=y
-CONFIG_CPU_GENERIC_DUMP_TLB=y
-CONFIG_CPU_HAS_DIEI=y
-CONFIG_CPU_HAS_PREFETCH=y
-CONFIG_CPU_HAS_RIXI=y
-CONFIG_CPU_HAS_SYNC=y
-CONFIG_CPU_MIPS64=y
-CONFIG_CPU_MIPSR2=y
-CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y
-CONFIG_CPU_R4K_FPU=y
-CONFIG_CPU_RMAP=y
-CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_HIGHMEM=y
-CONFIG_CPU_SUPPORTS_HUGEPAGES=y
-CONFIG_CRAMFS=y
-CONFIG_CRC16=y
-CONFIG_CRYPTO_CRC32=y
-CONFIG_CRYPTO_CRC32C=y
-CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
-CONFIG_CRYPTO_LIB_POLY1305_RSIZE=2
-CONFIG_CRYPTO_LIB_SHA1=y
-CONFIG_CRYPTO_LIB_UTILS=y
-# CONFIG_CRYPTO_MD5_OCTEON is not set
-CONFIG_CRYPTO_RNG2=y
-# CONFIG_CRYPTO_SHA1_OCTEON is not set
-# CONFIG_CRYPTO_SHA256_OCTEON is not set
-# CONFIG_CRYPTO_SHA512_OCTEON is not set
-# CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT is not set
-CONFIG_DEBUG_INFO_NONE=y
-CONFIG_DEPRECATED_IRQ_CPU_ONOFFLINE=y
-CONFIG_DNOTIFY=y
-CONFIG_DTC=y
-CONFIG_EARLY_PRINTK=y
-CONFIG_EDAC=y
-CONFIG_EDAC_ATOMIC_SCRUB=y
-# CONFIG_EDAC_DEBUG is not set
-CONFIG_EDAC_LEGACY_SYSFS=y
-CONFIG_EDAC_OCTEON_L2C=y
-CONFIG_EDAC_OCTEON_LMC=y
-CONFIG_EDAC_OCTEON_PC=y
-CONFIG_EDAC_OCTEON_PCI=y
-CONFIG_EDAC_SUPPORT=y
-CONFIG_EEPROM_AT24=y
-CONFIG_EXCLUSIVE_SYSTEM_RAM=y
-CONFIG_EXT4_FS=y
-CONFIG_F2FS_FS=y
-CONFIG_FAT_FS=y
-CONFIG_FIXED_PHY=y
-CONFIG_FS_IOMAP=y
-CONFIG_FS_MBCACHE=y
-CONFIG_FWNODE_MDIO=y
-CONFIG_FW_LOADER_PAGED_BUF=y
-CONFIG_FW_LOADER_SYSFS=y
-CONFIG_GCC11_NO_ARRAY_BOUNDS=y
-CONFIG_GENERIC_ALLOCATOR=y
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_GENERIC_CMOS_UPDATE=y
-CONFIG_GENERIC_CPU_AUTOPROBE=y
-CONFIG_GENERIC_GETTIMEOFDAY=y
-CONFIG_GENERIC_IOMAP=y
-CONFIG_GENERIC_IRQ_SHOW=y
-CONFIG_GENERIC_LIB_ASHLDI3=y
-CONFIG_GENERIC_LIB_ASHRDI3=y
-CONFIG_GENERIC_LIB_CMPDI2=y
-CONFIG_GENERIC_LIB_LSHRDI3=y
-CONFIG_GENERIC_LIB_UCMPDI2=y
-CONFIG_GENERIC_PCI_IOMAP=y
-CONFIG_GENERIC_SMP_IDLE_THREAD=y
-CONFIG_GENERIC_TIME_VSYSCALL=y
-CONFIG_GLOB=y
-CONFIG_GPIO_CDEV=y
-CONFIG_GPIO_OCTEON=y
-CONFIG_GRO_CELLS=y
-CONFIG_HARDWARE_WATCHPOINTS=y
-CONFIG_HAS_DMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT_MAP=y
-CONFIG_HW_RANDOM=y
-CONFIG_HW_RANDOM_OCTEON=y
-CONFIG_HZ_PERIODIC=y
-CONFIG_I2C=y
-CONFIG_I2C_BOARDINFO=y
-CONFIG_I2C_OCTEON=y
-CONFIG_IMAGE_CMDLINE_HACK=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_IRQCHIP=y
-CONFIG_IRQ_DOMAIN=y
-CONFIG_IRQ_FORCED_THREADING=y
-CONFIG_IRQ_WORK=y
-CONFIG_JBD2=y
-CONFIG_LIBFDT=y
-CONFIG_LOCK_DEBUGGING_SUPPORT=y
-CONFIG_MDIO_BUS=y
-CONFIG_MDIO_CAVIUM=y
-CONFIG_MDIO_DEVICE=y
-CONFIG_MDIO_DEVRES=y
-CONFIG_MDIO_OCTEON=y
-CONFIG_MEMFD_CREATE=y
-CONFIG_MIGRATION=y
-CONFIG_MIPS=y
-CONFIG_MIPS_ASID_BITS=8
-CONFIG_MIPS_ASID_SHIFT=0
-CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER=y
-CONFIG_MIPS_ELF_APPENDED_DTB=y
-CONFIG_MIPS_FP_SUPPORT=y
-CONFIG_MIPS_L1_CACHE_SHIFT=7
-CONFIG_MIPS_L1_CACHE_SHIFT_7=y
-CONFIG_MIPS_LD_CAN_LINK_VDSO=y
-# CONFIG_MIPS_NO_APPENDED_DTB is not set
-CONFIG_MIPS_NR_CPU_NR_MAP=1024
-CONFIG_MIPS_NR_CPU_NR_MAP_1024=y
-CONFIG_MIPS_PGD_C0_CONTEXT=y
-CONFIG_MIPS_SPRAM=y
-CONFIG_MMC=y
-CONFIG_MMC_BLOCK=y
-CONFIG_MMC_CAVIUM_OCTEON=y
-CONFIG_MODULES_USE_ELF_REL=y
-CONFIG_MODULES_USE_ELF_RELA=y
-# CONFIG_MTD_CFI_INTELEXT is not set
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_SPI_NOR=y
-CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NET_DEVLINK=y
-CONFIG_NET_DSA=y
-CONFIG_NET_FLOW_LIMIT=y
-CONFIG_NET_SELFTESTS=y
-CONFIG_NET_SWITCHDEV=y
-CONFIG_NLS=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y
-CONFIG_NR_CPUS=16
-CONFIG_NR_CPUS_DEFAULT_64=y
-CONFIG_NVMEM=y
-CONFIG_NVMEM_SYSFS=y
-CONFIG_OCTEON_ETHERNET=y
-CONFIG_OCTEON_ILM=y
-CONFIG_OCTEON_MGMT_ETHERNET=y
-CONFIG_OCTEON_WDT=y
-CONFIG_OF=y
-CONFIG_OF_ADDRESS=y
-CONFIG_OF_EARLY_FLATTREE=y
-CONFIG_OF_FLATTREE=y
-CONFIG_OF_GPIO=y
-CONFIG_OF_IRQ=y
-CONFIG_OF_KOBJ=y
-CONFIG_OF_MDIO=y
-CONFIG_PADATA=y
-CONFIG_PAGE_POOL=y
-CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
-CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
-# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_PATA_OCTEON_CF=y
-CONFIG_PATA_TIMINGS=y
-CONFIG_PCI=y
-CONFIG_PCIEAER=y
-CONFIG_PCIEPORTBUS=y
-CONFIG_PCI_DOMAINS=y
-CONFIG_PCI_DRIVERS_LEGACY=y
-CONFIG_PERF_USE_VMALLOC=y
-CONFIG_PGTABLE_LEVELS=3
-CONFIG_PHYLIB=y
-CONFIG_PHYLINK=y
-CONFIG_PHYS_ADDR_T_64BIT=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_POSIX_MQUEUE_SYSCTL=y
-CONFIG_PREEMPT_NONE_BUILD=y
-CONFIG_PTP_1588_CLOCK_OPTIONAL=y
-CONFIG_QUEUED_RWLOCKS=y
-CONFIG_QUEUED_SPINLOCKS=y
-CONFIG_RANDSTRUCT_NONE=y
-CONFIG_RAS=y
-CONFIG_REGMAP=y
-CONFIG_REGMAP_I2C=y
-CONFIG_RELAY=y
-CONFIG_RFS_ACCEL=y
-CONFIG_RPS=y
-CONFIG_SATA_AHCI_PLATFORM=y
-CONFIG_SATA_HOST=y
-CONFIG_SCSI=y
-CONFIG_SCSI_COMMON=y
-CONFIG_SECCOMP=y
-CONFIG_SECCOMP_FILTER=y
-CONFIG_SERIAL_8250_DW=y
-CONFIG_SERIAL_8250_DWLIB=y
-CONFIG_SERIAL_MCTRL_GPIO=y
-CONFIG_SG_POOL=y
-CONFIG_SMP=y
-CONFIG_SOCK_RX_QUEUE_MAPPING=y
-CONFIG_SPARSEMEM=y
-CONFIG_SPARSEMEM_EXTREME=y
-CONFIG_SPI=y
-CONFIG_SPI_MASTER=y
-CONFIG_SPI_MEM=y
-CONFIG_SPI_OCTEON=y
-CONFIG_SRCU=y
-CONFIG_SWIOTLB=y
-CONFIG_SWPHY=y
-CONFIG_SYSCTL_EXCEPTION_TRACE=y
-CONFIG_SYS_HAS_CPU_CAVIUM_OCTEON=y
-CONFIG_SYS_HAS_EARLY_PRINTK=y
-CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
-CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
-CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
-CONFIG_SYS_SUPPORTS_HOTPLUG_CPU=y
-CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
-CONFIG_SYS_SUPPORTS_RELOCATABLE=y
-CONFIG_SYS_SUPPORTS_SMP=y
-CONFIG_TARGET_ISA_REV=2
-CONFIG_TICK_CPU_ACCOUNTING=y
-CONFIG_TREE_RCU=y
-CONFIG_TREE_SRCU=y
-CONFIG_USB=y
-CONFIG_USB_COMMON=y
-CONFIG_USB_EHCI_BIG_ENDIAN_MMIO=y
-CONFIG_USB_EHCI_HCD=y
-CONFIG_USB_EHCI_HCD_PLATFORM=y
-# CONFIG_USB_OCTEON_EHCI is not set
-CONFIG_USB_OCTEON_HCD=y
-# CONFIG_USB_OCTEON_OHCI is not set
-CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_OHCI_HCD_PLATFORM=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_SUPPORT=y
-CONFIG_USB_XHCI_HCD=y
-CONFIG_USB_XHCI_PLATFORM=y
-CONFIG_USE_OF=y
-CONFIG_VFAT_FS=y
-CONFIG_VITESSE_PHY=y
-CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_WATCHDOG_CORE=y
-CONFIG_WEAK_ORDERING=y
-CONFIG_XPS=y
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZONE_DMA32=y
diff --git a/target/linux/octeon/config-6.6 b/target/linux/octeon/config-6.6
new file mode 100644
index 0000000000..724361d5ea
--- /dev/null
+++ b/target/linux/octeon/config-6.6
@@ -0,0 +1,283 @@
+CONFIG_64BIT=y
+CONFIG_AHCI_OCTEON=y
+CONFIG_ARCH_DMA_ADDR_T_64BIT=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_KEEP_MEMBLOCK=y
+CONFIG_ARCH_MMAP_RND_BITS=12
+CONFIG_ARCH_MMAP_RND_BITS_MAX=18
+CONFIG_ARCH_MMAP_RND_BITS_MIN=12
+CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=15
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ATA=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_BLK_MQ_PCI=y
+CONFIG_BUFFER_HEAD=y
+CONFIG_BUILTIN_DTB=y
+CONFIG_CAVIUM_CN63XXP1=y
+CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE=0
+CONFIG_CAVIUM_OCTEON_LOCK_L2=y
+CONFIG_CAVIUM_OCTEON_LOCK_L2_EXCEPTION=y
+CONFIG_CAVIUM_OCTEON_LOCK_L2_INTERRUPT=y
+CONFIG_CAVIUM_OCTEON_LOCK_L2_LOW_LEVEL_INTERRUPT=y
+CONFIG_CAVIUM_OCTEON_LOCK_L2_MEMCPY=y
+CONFIG_CAVIUM_OCTEON_LOCK_L2_TLB=y
+CONFIG_CAVIUM_OCTEON_SOC=y
+CONFIG_CAVIUM_RESERVE32=0
+CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
+CONFIG_CC_NO_ARRAY_BOUNDS=y
+CONFIG_CEVT_R4K=y
+CONFIG_CLONE_BACKWARDS=y
+# CONFIG_COMMON_CLK is not set
+CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
+CONFIG_COMPAT_32BIT_TIME=y
+CONFIG_CONTEXT_TRACKING=y
+CONFIG_CONTEXT_TRACKING_IDLE=y
+CONFIG_CPU_BIG_ENDIAN=y
+CONFIG_CPU_CAVIUM_OCTEON=y
+CONFIG_CPU_GENERIC_DUMP_TLB=y
+CONFIG_CPU_HAS_DIEI=y
+CONFIG_CPU_HAS_PREFETCH=y
+CONFIG_CPU_HAS_RIXI=y
+CONFIG_CPU_HAS_SYNC=y
+CONFIG_CPU_MIPS64=y
+CONFIG_CPU_MIPSR2=y
+CONFIG_CPU_MITIGATIONS=y
+CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y
+CONFIG_CPU_R4K_FPU=y
+CONFIG_CPU_RMAP=y
+CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_CPU_SUPPORTS_HUGEPAGES=y
+CONFIG_CRAMFS=y
+CONFIG_CRC16=y
+CONFIG_CRYPTO_CRC32=y
+CONFIG_CRYPTO_CRC32C=y
+CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
+CONFIG_CRYPTO_LIB_GF128MUL=y
+CONFIG_CRYPTO_LIB_POLY1305_RSIZE=2
+CONFIG_CRYPTO_LIB_SHA1=y
+CONFIG_CRYPTO_LIB_UTILS=y
+# CONFIG_CRYPTO_MD5_OCTEON is not set
+# CONFIG_CRYPTO_SHA1_OCTEON is not set
+# CONFIG_CRYPTO_SHA256_OCTEON is not set
+# CONFIG_CRYPTO_SHA512_OCTEON is not set
+# CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT is not set
+CONFIG_DEBUG_INFO_NONE=y
+CONFIG_DEPRECATED_IRQ_CPU_ONOFFLINE=y
+CONFIG_DNOTIFY=y
+CONFIG_DTC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_EDAC=y
+CONFIG_EDAC_ATOMIC_SCRUB=y
+# CONFIG_EDAC_DEBUG is not set
+CONFIG_EDAC_LEGACY_SYSFS=y
+CONFIG_EDAC_OCTEON_L2C=y
+CONFIG_EDAC_OCTEON_LMC=y
+CONFIG_EDAC_OCTEON_PC=y
+CONFIG_EDAC_OCTEON_PCI=y
+CONFIG_EDAC_SUPPORT=y
+CONFIG_EEPROM_AT24=y
+CONFIG_EXCLUSIVE_SYSTEM_RAM=y
+CONFIG_EXT4_FS=y
+CONFIG_F2FS_FS=y
+CONFIG_FAT_FS=y
+CONFIG_FIXED_PHY=y
+CONFIG_FS_IOMAP=y
+CONFIG_FS_MBCACHE=y
+CONFIG_FUNCTION_ALIGNMENT=0
+CONFIG_FWNODE_MDIO=y
+CONFIG_FW_LOADER_PAGED_BUF=y
+CONFIG_FW_LOADER_SYSFS=y
+CONFIG_GCC10_NO_ARRAY_BOUNDS=y
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_GENERIC_CPU_AUTOPROBE=y
+CONFIG_GENERIC_GETTIMEOFDAY=y
+CONFIG_GENERIC_IDLE_POLL_SETUP=y
+CONFIG_GENERIC_IOMAP=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_GENERIC_LIB_ASHLDI3=y
+CONFIG_GENERIC_LIB_ASHRDI3=y
+CONFIG_GENERIC_LIB_CMPDI2=y
+CONFIG_GENERIC_LIB_LSHRDI3=y
+CONFIG_GENERIC_LIB_UCMPDI2=y
+CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_SMP_IDLE_THREAD=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GLOB=y
+CONFIG_GPIO_CDEV=y
+CONFIG_GPIO_OCTEON=y
+CONFIG_GRO_CELLS=y
+CONFIG_HARDWARE_WATCHPOINTS=y
+CONFIG_HAS_DMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_IOPORT_MAP=y
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_OCTEON=y
+CONFIG_HZ_PERIODIC=y
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_OCTEON=y
+CONFIG_IMAGE_CMDLINE_HACK=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_IRQCHIP=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_FORCED_THREADING=y
+CONFIG_IRQ_WORK=y
+CONFIG_JBD2=y
+CONFIG_LEGACY_DIRECT_IO=y
+CONFIG_LIBFDT=y
+CONFIG_LOCK_DEBUGGING_SUPPORT=y
+CONFIG_MDIO_BUS=y
+CONFIG_MDIO_CAVIUM=y
+CONFIG_MDIO_DEVICE=y
+CONFIG_MDIO_DEVRES=y
+CONFIG_MDIO_OCTEON=y
+CONFIG_MIGRATION=y
+CONFIG_MIPS=y
+CONFIG_MIPS_ASID_BITS=8
+CONFIG_MIPS_ASID_SHIFT=0
+CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER=y
+CONFIG_MIPS_ELF_APPENDED_DTB=y
+CONFIG_MIPS_FP_SUPPORT=y
+CONFIG_MIPS_L1_CACHE_SHIFT=7
+CONFIG_MIPS_L1_CACHE_SHIFT_7=y
+# CONFIG_MIPS_NO_APPENDED_DTB is not set
+CONFIG_MIPS_NR_CPU_NR_MAP=1024
+CONFIG_MIPS_NR_CPU_NR_MAP_1024=y
+CONFIG_MIPS_PGD_C0_CONTEXT=y
+CONFIG_MIPS_SPRAM=y
+CONFIG_MMC=y
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_CAVIUM_OCTEON=y
+CONFIG_MMU_LAZY_TLB_REFCOUNT=y
+CONFIG_MODULES_USE_ELF_REL=y
+CONFIG_MODULES_USE_ELF_RELA=y
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_SPI_NOR=y
+CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_NEED_SRCU_NMI_SAFE=y
+CONFIG_NET_DEVLINK=y
+CONFIG_NET_DSA=y
+CONFIG_NET_EGRESS=y
+CONFIG_NET_FLOW_LIMIT=y
+CONFIG_NET_INGRESS=y
+CONFIG_NET_SELFTESTS=y
+CONFIG_NET_SWITCHDEV=y
+CONFIG_NET_XGRESS=y
+CONFIG_NLS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y
+CONFIG_NR_CPUS=16
+CONFIG_NR_CPUS_DEFAULT_64=y
+CONFIG_NVMEM=y
+CONFIG_NVMEM_LAYOUTS=y
+CONFIG_NVMEM_SYSFS=y
+CONFIG_OCTEON_ETHERNET=y
+CONFIG_OCTEON_ILM=y
+CONFIG_OCTEON_MGMT_ETHERNET=y
+CONFIG_OCTEON_WDT=y
+CONFIG_OF=y
+CONFIG_OF_ADDRESS=y
+CONFIG_OF_EARLY_FLATTREE=y
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_GPIO=y
+CONFIG_OF_IRQ=y
+CONFIG_OF_KOBJ=y
+CONFIG_OF_MDIO=y
+CONFIG_PADATA=y
+CONFIG_PAGE_POOL=y
+CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
+CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_PATA_OCTEON_CF=y
+CONFIG_PATA_TIMINGS=y
+CONFIG_PCI=y
+CONFIG_PCIEAER=y
+CONFIG_PCIEPORTBUS=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_DRIVERS_LEGACY=y
+CONFIG_PERF_USE_VMALLOC=y
+CONFIG_PGTABLE_LEVELS=3
+CONFIG_PHYLIB=y
+CONFIG_PHYLIB_LEDS=y
+CONFIG_PHYLINK=y
+CONFIG_PHYS_ADDR_T_64BIT=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+CONFIG_PREEMPT_NONE_BUILD=y
+CONFIG_PTP_1588_CLOCK_OPTIONAL=y
+CONFIG_QUEUED_RWLOCKS=y
+CONFIG_QUEUED_SPINLOCKS=y
+CONFIG_RANDSTRUCT_NONE=y
+CONFIG_RAS=y
+CONFIG_REGMAP=y
+CONFIG_REGMAP_I2C=y
+CONFIG_RELAY=y
+CONFIG_RFS_ACCEL=y
+CONFIG_RPS=y
+CONFIG_SATA_AHCI_PLATFORM=y
+CONFIG_SATA_HOST=y
+CONFIG_SCSI=y
+CONFIG_SCSI_COMMON=y
+CONFIG_SERIAL_8250_DW=y
+CONFIG_SERIAL_8250_DWLIB=y
+CONFIG_SERIAL_MCTRL_GPIO=y
+CONFIG_SG_POOL=y
+CONFIG_SMP=y
+CONFIG_SOCK_RX_QUEUE_MAPPING=y
+CONFIG_SPARSEMEM=y
+CONFIG_SPARSEMEM_EXTREME=y
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+CONFIG_SPI_MEM=y
+CONFIG_SPI_OCTEON=y
+CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y
+CONFIG_SWIOTLB=y
+CONFIG_SWPHY=y
+CONFIG_SYSCTL_EXCEPTION_TRACE=y
+CONFIG_SYS_HAS_CPU_CAVIUM_OCTEON=y
+CONFIG_SYS_HAS_EARLY_PRINTK=y
+CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
+CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
+CONFIG_SYS_SUPPORTS_HOTPLUG_CPU=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_RELOCATABLE=y
+CONFIG_SYS_SUPPORTS_SMP=y
+CONFIG_TARGET_ISA_REV=2
+CONFIG_TICK_CPU_ACCOUNTING=y
+CONFIG_TREE_RCU=y
+CONFIG_TREE_SRCU=y
+CONFIG_USB=y
+CONFIG_USB_COMMON=y
+CONFIG_USB_EHCI_BIG_ENDIAN_MMIO=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_HCD_PLATFORM=y
+# CONFIG_USB_OCTEON_EHCI is not set
+CONFIG_USB_OCTEON_HCD=y
+# CONFIG_USB_OCTEON_OHCI is not set
+CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_HCD_PLATFORM=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_XHCI_PLATFORM=y
+CONFIG_USE_OF=y
+CONFIG_VFAT_FS=y
+CONFIG_VITESSE_PHY=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_WATCHDOG_CORE=y
+CONFIG_WEAK_ORDERING=y
+CONFIG_XPS=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZONE_DMA32=y
diff --git a/target/linux/octeon/image/Makefile b/target/linux/octeon/image/Makefile
index dcab815791..f00e87c520 100644
--- a/target/linux/octeon/image/Makefile
+++ b/target/linux/octeon/image/Makefile
@@ -42,7 +42,8 @@ define Device/itus_shield-router
endef
TARGET_DEVICES += itus_shield-router
-ER_CMDLINE:=-mtdparts=phys_mapped_flash:640k(boot0)ro,640k(boot1)ro,64k(eeprom)ro root=/dev/mmcblk0p2 rootfstype=squashfs,ext4 rootwait
+# Disable PCIe on ER as it doesn't have PCIe peripherals and some devices lock up on initialization
+ER_CMDLINE:=-mtdparts=phys_mapped_flash:640k(boot0)ro,640k(boot1)ro,64k(eeprom)ro root=/dev/mmcblk0p2 rootfstype=squashfs,ext4 rootwait pcie_octeon.pcie_disable=1
define Device/ubnt_edgerouter
DEVICE_VENDOR := Ubiquiti
DEVICE_MODEL := EdgeRouter
@@ -99,13 +100,16 @@ define Device/cisco_vedge1000
DEVICE_MODEL := vEdge 1000
BOARD_NAME := cisco,vedge1000
DEVICE_PACKAGES += \
+ blkid \
kmod-hwmon-jc42 \
kmod-hwmon-max6697 \
kmod-of-mdio \
kmod-rtc-ds1307 \
kmod-usb-dwc3 \
kmod-usb-storage-uas \
- kmod-usb3
+ kmod-usb3 \
+ sfdisk \
+ uboot-envtools
KERNEL := kernel-bin | append-dtb-elf
KERNEL_DEPENDS := $$(wildcard $(DTS_DIR)/$(DEVICE_DTS).dts)
DEVICE_DTS := cn6130_cisco_vedge1000
diff --git a/target/linux/octeon/patches-6.1/100-mips_image_cmdline_hack.patch b/target/linux/octeon/patches-6.1/100-mips_image_cmdline_hack.patch
deleted file mode 100644
index f63af640dd..0000000000
--- a/target/linux/octeon/patches-6.1/100-mips_image_cmdline_hack.patch
+++ /dev/null
@@ -1,38 +0,0 @@
-From: John Crispin <john@phrozen.org>
-Subject: hack: kernel: add generic image_cmdline hack to MIPS targets
-
-lede-commit: d59f5b3a987a48508257a0ddbaeadc7909f9f976
-Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
----
- arch/mips/Kconfig | 4 ++++
- arch/mips/kernel/head.S | 6 ++++++
- 2 files changed, 10 insertions(+)
-
---- a/arch/mips/Kconfig
-+++ b/arch/mips/Kconfig
-@@ -1115,6 +1115,10 @@ config MIPS_MSC
- config SYNC_R4K
- bool
-
-+config IMAGE_CMDLINE_HACK
-+ bool "OpenWrt specific image command line hack"
-+ default n
-+
- config NO_IOPORT_MAP
- def_bool n
-
---- a/arch/mips/kernel/head.S
-+++ b/arch/mips/kernel/head.S
-@@ -79,6 +79,12 @@ FEXPORT(__kernel_entry)
- j kernel_entry
- #endif /* CONFIG_BOOT_RAW */
-
-+#ifdef CONFIG_IMAGE_CMDLINE_HACK
-+ .ascii "CMDLINE:"
-+EXPORT(__image_cmdline)
-+ .fill 0x400
-+#endif /* CONFIG_IMAGE_CMDLINE_HACK */
-+
- __REF
-
- NESTED(kernel_entry, 16, sp) # kernel entry point
diff --git a/target/linux/octeon/patches-6.1/130-add_itus_support.patch b/target/linux/octeon/patches-6.1/130-add_itus_support.patch
deleted file mode 100644
index d76e8637ea..0000000000
--- a/target/linux/octeon/patches-6.1/130-add_itus_support.patch
+++ /dev/null
@@ -1,42 +0,0 @@
---- a/arch/mips/cavium-octeon/octeon-platform.c
-+++ b/arch/mips/cavium-octeon/octeon-platform.c
-@@ -774,7 +774,7 @@ int __init octeon_prune_device_tree(void
- if (fdt_check_header(initial_boot_params))
- panic("Corrupt Device Tree.");
-
-- WARN(octeon_bootinfo->board_type == CVMX_BOARD_TYPE_CUST_DSR1000N,
-+ WARN(octeon_bootinfo->board_type == CVMX_BOARD_TYPE_ITUS_SHIELD,
- "Built-in DTB booting is deprecated on %s. Please switch to use appended DTB.",
- cvmx_board_type_to_string(octeon_bootinfo->board_type));
-
---- a/arch/mips/include/asm/octeon/cvmx-bootinfo.h
-+++ b/arch/mips/include/asm/octeon/cvmx-bootinfo.h
-@@ -298,7 +298,7 @@ enum cvmx_board_types_enum {
- CVMX_BOARD_TYPE_UBNT_E100 = 20002,
- CVMX_BOARD_TYPE_UBNT_E200 = 20003,
- CVMX_BOARD_TYPE_UBNT_E220 = 20005,
-- CVMX_BOARD_TYPE_CUST_DSR1000N = 20006,
-+ CVMX_BOARD_TYPE_ITUS_SHIELD = 20006,
- CVMX_BOARD_TYPE_UBNT_E300 = 20300,
- CVMX_BOARD_TYPE_KONTRON_S1901 = 21901,
- CVMX_BOARD_TYPE_CUST_PRIVATE_MAX = 30000,
-@@ -403,7 +403,7 @@ static inline const char *cvmx_board_typ
- ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_UBNT_E100)
- ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_UBNT_E200)
- ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_UBNT_E220)
-- ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_DSR1000N)
-+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_ITUS_SHIELD)
- ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_UBNT_E300)
- ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_KONTRON_S1901)
- ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_PRIVATE_MAX)
---- a/arch/mips/pci/pci-octeon.c
-+++ b/arch/mips/pci/pci-octeon.c
-@@ -211,7 +211,7 @@ const char *octeon_get_pci_interrupts(vo
- return "AAABAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
- case CVMX_BOARD_TYPE_BBGW_REF:
- return "AABCD";
-- case CVMX_BOARD_TYPE_CUST_DSR1000N:
-+ case CVMX_BOARD_TYPE_ITUS_SHIELD:
- return "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC";
- case CVMX_BOARD_TYPE_THUNDER:
- case CVMX_BOARD_TYPE_EBH3000:
diff --git a/target/linux/octeon/patches-6.1/150-ubnt_usg_support.patch b/target/linux/octeon/patches-6.1/150-ubnt_usg_support.patch
deleted file mode 100644
index 00c268eda8..0000000000
--- a/target/linux/octeon/patches-6.1/150-ubnt_usg_support.patch
+++ /dev/null
@@ -1,46 +0,0 @@
---- a/arch/mips/include/asm/octeon/cvmx-bootinfo.h
-+++ b/arch/mips/include/asm/octeon/cvmx-bootinfo.h
-@@ -297,6 +297,7 @@ enum cvmx_board_types_enum {
- CVMX_BOARD_TYPE_CUST_PRIVATE_MIN = 20001,
- CVMX_BOARD_TYPE_UBNT_E100 = 20002,
- CVMX_BOARD_TYPE_UBNT_E200 = 20003,
-+ CVMX_BOARD_TYPE_UBNT_USG = 20004,
- CVMX_BOARD_TYPE_UBNT_E220 = 20005,
- CVMX_BOARD_TYPE_ITUS_SHIELD = 20006,
- CVMX_BOARD_TYPE_UBNT_E300 = 20300,
-@@ -401,6 +402,7 @@ static inline const char *cvmx_board_typ
- /* Customer private range */
- ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_PRIVATE_MIN)
- ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_UBNT_E100)
-+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_UBNT_USG)
- ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_UBNT_E200)
- ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_UBNT_E220)
- ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_ITUS_SHIELD)
---- a/arch/mips/cavium-octeon/octeon-platform.c
-+++ b/arch/mips/cavium-octeon/octeon-platform.c
-@@ -635,6 +635,7 @@ static void __init octeon_rx_tx_delay(in
- }
- break;
- case CVMX_BOARD_TYPE_UBNT_E100:
-+ case CVMX_BOARD_TYPE_UBNT_USG:
- if (iface == 0 && port <= 2) {
- _octeon_rx_tx_delay(eth, 0x0, 0x10);
- return;
---- a/arch/mips/cavium-octeon/executive/cvmx-helper-board.c
-+++ b/arch/mips/cavium-octeon/executive/cvmx-helper-board.c
-@@ -170,6 +170,7 @@ int cvmx_helper_board_get_mii_address(in
- else
- return -1;
- case CVMX_BOARD_TYPE_UBNT_E100:
-+ case CVMX_BOARD_TYPE_UBNT_USG:
- if (ipd_port >= 0 && ipd_port <= 2)
- return 7 - ipd_port;
- else
-@@ -337,6 +338,7 @@ enum cvmx_helper_board_usb_clock_types _
- case CVMX_BOARD_TYPE_LANAI2_G:
- case CVMX_BOARD_TYPE_NIC10E_66:
- case CVMX_BOARD_TYPE_UBNT_E100:
-+ case CVMX_BOARD_TYPE_UBNT_USG:
- return USB_CLOCK_TYPE_CRYSTAL_12;
- case CVMX_BOARD_TYPE_NIC10E:
- return USB_CLOCK_TYPE_REF_12;
diff --git a/target/linux/octeon/patches-6.6/100-mips_image_cmdline_hack.patch b/target/linux/octeon/patches-6.6/100-mips_image_cmdline_hack.patch
new file mode 100644
index 0000000000..5a5cc21808
--- /dev/null
+++ b/target/linux/octeon/patches-6.6/100-mips_image_cmdline_hack.patch
@@ -0,0 +1,38 @@
+From: John Crispin <john@phrozen.org>
+Subject: hack: kernel: add generic image_cmdline hack to MIPS targets
+
+lede-commit: d59f5b3a987a48508257a0ddbaeadc7909f9f976
+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
+---
+ arch/mips/Kconfig | 4 ++++
+ arch/mips/kernel/head.S | 6 ++++++
+ 2 files changed, 10 insertions(+)
+
+--- a/arch/mips/Kconfig
++++ b/arch/mips/Kconfig
+@@ -1090,6 +1090,10 @@ config MIPS_MSC
+ config SYNC_R4K
+ bool
+
++config IMAGE_CMDLINE_HACK
++ bool "OpenWrt specific image command line hack"
++ default n
++
+ config NO_IOPORT_MAP
+ def_bool n
+
+--- a/arch/mips/kernel/head.S
++++ b/arch/mips/kernel/head.S
+@@ -79,6 +79,12 @@ FEXPORT(__kernel_entry)
+ j kernel_entry
+ #endif /* CONFIG_BOOT_RAW */
+
++#ifdef CONFIG_IMAGE_CMDLINE_HACK
++ .ascii "CMDLINE:"
++EXPORT(__image_cmdline)
++ .fill 0x400
++#endif /* CONFIG_IMAGE_CMDLINE_HACK */
++
+ __REF
+
+ NESTED(kernel_entry, 16, sp) # kernel entry point
diff --git a/target/linux/octeon/patches-6.1/100-ubnt_edgerouter2_support.patch b/target/linux/octeon/patches-6.6/100-ubnt_edgerouter2_support.patch
index 606debda7f..606debda7f 100644
--- a/target/linux/octeon/patches-6.1/100-ubnt_edgerouter2_support.patch
+++ b/target/linux/octeon/patches-6.6/100-ubnt_edgerouter2_support.patch
diff --git a/target/linux/octeon/patches-6.1/110-er200-ethernet_probe_order.patch b/target/linux/octeon/patches-6.6/110-er200-ethernet_probe_order.patch
index 133e167d2c..133e167d2c 100644
--- a/target/linux/octeon/patches-6.1/110-er200-ethernet_probe_order.patch
+++ b/target/linux/octeon/patches-6.6/110-er200-ethernet_probe_order.patch
diff --git a/target/linux/octeon/patches-6.1/120-cmdline-hack.patch b/target/linux/octeon/patches-6.6/120-cmdline-hack.patch
index e65cf78da4..e65cf78da4 100644
--- a/target/linux/octeon/patches-6.1/120-cmdline-hack.patch
+++ b/target/linux/octeon/patches-6.6/120-cmdline-hack.patch
diff --git a/target/linux/octeon/patches-6.6/130-add_itus_support.patch b/target/linux/octeon/patches-6.6/130-add_itus_support.patch
new file mode 100644
index 0000000000..cf841c613e
--- /dev/null
+++ b/target/linux/octeon/patches-6.6/130-add_itus_support.patch
@@ -0,0 +1,42 @@
+--- a/arch/mips/cavium-octeon/octeon-platform.c
++++ b/arch/mips/cavium-octeon/octeon-platform.c
+@@ -775,7 +775,7 @@ int __init octeon_prune_device_tree(void
+ if (fdt_check_header(initial_boot_params))
+ panic("Corrupt Device Tree.");
+
+- WARN(octeon_bootinfo->board_type == CVMX_BOARD_TYPE_CUST_DSR1000N,
++ WARN(octeon_bootinfo->board_type == CVMX_BOARD_TYPE_ITUS_SHIELD,
+ "Built-in DTB booting is deprecated on %s. Please switch to use appended DTB.",
+ cvmx_board_type_to_string(octeon_bootinfo->board_type));
+
+--- a/arch/mips/include/asm/octeon/cvmx-bootinfo.h
++++ b/arch/mips/include/asm/octeon/cvmx-bootinfo.h
+@@ -298,7 +298,7 @@ enum cvmx_board_types_enum {
+ CVMX_BOARD_TYPE_UBNT_E100 = 20002,
+ CVMX_BOARD_TYPE_UBNT_E200 = 20003,
+ CVMX_BOARD_TYPE_UBNT_E220 = 20005,
+- CVMX_BOARD_TYPE_CUST_DSR1000N = 20006,
++ CVMX_BOARD_TYPE_ITUS_SHIELD = 20006,
+ CVMX_BOARD_TYPE_UBNT_E300 = 20300,
+ CVMX_BOARD_TYPE_KONTRON_S1901 = 21901,
+ CVMX_BOARD_TYPE_CUST_PRIVATE_MAX = 30000,
+@@ -403,7 +403,7 @@ static inline const char *cvmx_board_typ
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_UBNT_E100)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_UBNT_E200)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_UBNT_E220)
+- ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_DSR1000N)
++ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_ITUS_SHIELD)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_UBNT_E300)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_KONTRON_S1901)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_PRIVATE_MAX)
+--- a/arch/mips/pci/pci-octeon.c
++++ b/arch/mips/pci/pci-octeon.c
+@@ -211,7 +211,7 @@ const char *octeon_get_pci_interrupts(vo
+ return "AAABAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
+ case CVMX_BOARD_TYPE_BBGW_REF:
+ return "AABCD";
+- case CVMX_BOARD_TYPE_CUST_DSR1000N:
++ case CVMX_BOARD_TYPE_ITUS_SHIELD:
+ return "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC";
+ case CVMX_BOARD_TYPE_THUNDER:
+ case CVMX_BOARD_TYPE_EBH3000:
diff --git a/target/linux/octeon/patches-6.6/150-ubnt_usg_support.patch b/target/linux/octeon/patches-6.6/150-ubnt_usg_support.patch
new file mode 100644
index 0000000000..dd69f728a1
--- /dev/null
+++ b/target/linux/octeon/patches-6.6/150-ubnt_usg_support.patch
@@ -0,0 +1,46 @@
+--- a/arch/mips/include/asm/octeon/cvmx-bootinfo.h
++++ b/arch/mips/include/asm/octeon/cvmx-bootinfo.h
+@@ -297,6 +297,7 @@ enum cvmx_board_types_enum {
+ CVMX_BOARD_TYPE_CUST_PRIVATE_MIN = 20001,
+ CVMX_BOARD_TYPE_UBNT_E100 = 20002,
+ CVMX_BOARD_TYPE_UBNT_E200 = 20003,
++ CVMX_BOARD_TYPE_UBNT_USG = 20004,
+ CVMX_BOARD_TYPE_UBNT_E220 = 20005,
+ CVMX_BOARD_TYPE_ITUS_SHIELD = 20006,
+ CVMX_BOARD_TYPE_UBNT_E300 = 20300,
+@@ -401,6 +402,7 @@ static inline const char *cvmx_board_typ
+ /* Customer private range */
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_PRIVATE_MIN)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_UBNT_E100)
++ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_UBNT_USG)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_UBNT_E200)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_UBNT_E220)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_ITUS_SHIELD)
+--- a/arch/mips/cavium-octeon/octeon-platform.c
++++ b/arch/mips/cavium-octeon/octeon-platform.c
+@@ -636,6 +636,7 @@ static void __init octeon_rx_tx_delay(in
+ }
+ break;
+ case CVMX_BOARD_TYPE_UBNT_E100:
++ case CVMX_BOARD_TYPE_UBNT_USG:
+ if (iface == 0 && port <= 2) {
+ _octeon_rx_tx_delay(eth, 0x0, 0x10);
+ return;
+--- a/arch/mips/cavium-octeon/executive/cvmx-helper-board.c
++++ b/arch/mips/cavium-octeon/executive/cvmx-helper-board.c
+@@ -170,6 +170,7 @@ int cvmx_helper_board_get_mii_address(in
+ else
+ return -1;
+ case CVMX_BOARD_TYPE_UBNT_E100:
++ case CVMX_BOARD_TYPE_UBNT_USG:
+ if (ipd_port >= 0 && ipd_port <= 2)
+ return 7 - ipd_port;
+ else
+@@ -337,6 +338,7 @@ enum cvmx_helper_board_usb_clock_types _
+ case CVMX_BOARD_TYPE_LANAI2_G:
+ case CVMX_BOARD_TYPE_NIC10E_66:
+ case CVMX_BOARD_TYPE_UBNT_E100:
++ case CVMX_BOARD_TYPE_UBNT_USG:
+ return USB_CLOCK_TYPE_CRYSTAL_12;
+ case CVMX_BOARD_TYPE_NIC10E:
+ return USB_CLOCK_TYPE_REF_12;
diff --git a/target/linux/octeon/patches-6.1/700-allocate_interface_by_label.patch b/target/linux/octeon/patches-6.6/700-allocate_interface_by_label.patch
index 22f284b2c0..22f284b2c0 100644
--- a/target/linux/octeon/patches-6.1/700-allocate_interface_by_label.patch
+++ b/target/linux/octeon/patches-6.6/700-allocate_interface_by_label.patch
diff --git a/target/linux/octeon/patches-6.1/701-honor_sgmii_node_device_tree_status.patch b/target/linux/octeon/patches-6.6/701-honor_sgmii_node_device_tree_status.patch
index fdfbc233ab..fdfbc233ab 100644
--- a/target/linux/octeon/patches-6.1/701-honor_sgmii_node_device_tree_status.patch
+++ b/target/linux/octeon/patches-6.6/701-honor_sgmii_node_device_tree_status.patch
diff --git a/target/linux/omap/Makefile b/target/linux/omap/Makefile
index fc0842d056..a3c61efc9a 100644
--- a/target/linux/omap/Makefile
+++ b/target/linux/omap/Makefile
@@ -7,7 +7,7 @@ include $(TOPDIR)/rules.mk
ARCH:=arm
BOARD:=omap
BOARDNAME:=TI OMAP3/4/AM33xx
-FEATURES:=usb usbgadget ext4 targz fpu audio display nand rootfs-part squashfs source-only
+FEATURES:=usb usbgadget ext4 targz fpu audio display nand rootfs-part squashfs
CPU_TYPE:=cortex-a8
CPU_SUBTYPE:=vfpv3
SUBTARGETS:=generic
diff --git a/target/linux/omap/config-6.1 b/target/linux/omap/config-6.1
index d5ed19afe1..94c6b5922d 100644
--- a/target/linux/omap/config-6.1
+++ b/target/linux/omap/config-6.1
@@ -234,7 +234,6 @@ CONFIG_FIXED_PHY=y
CONFIG_FIX_EARLYCON_MEM=y
CONFIG_FS_IOMAP=y
CONFIG_FS_MBCACHE=y
-CONFIG_FS_POSIX_ACL=y
CONFIG_FWNODE_MDIO=y
CONFIG_FW_LOADER_PAGED_BUF=y
CONFIG_FW_LOADER_SYSFS=y
@@ -655,7 +654,6 @@ CONFIG_TI_PWMSS=y
CONFIG_TI_SOC_THERMAL=y
CONFIG_TI_SYSC=y
CONFIG_TI_THERMAL=y
-CONFIG_TMPFS_POSIX_ACL=y
CONFIG_TREE_RCU=y
CONFIG_TREE_SRCU=y
CONFIG_TWL4030_CORE=y
diff --git a/target/linux/omap/patches/900-use-cpsw-ethernet-driver.patch b/target/linux/omap/patches/900-use-cpsw-ethernet-driver.patch
new file mode 100644
index 0000000000..17c07fbdfb
--- /dev/null
+++ b/target/linux/omap/patches/900-use-cpsw-ethernet-driver.patch
@@ -0,0 +1,93 @@
+From: Jan Hoffmann <jan@3e8.eu>
+Date: Sat, 27 Apr 2024 20:41:43 +0200
+Subject: ARM: dts: Use cpsw ethernet driver for some am335x devices
+
+The new cpsw-switch driver requires a vid for every port which is
+reserved for internal usage (defaulting to 1 and 2). As a result, some
+network configurations are impossible, such as a bridge with
+default_pvid of 1 (even if it is not vlan aware).
+
+As a simple workaround, the ti,dual-emac-pvid property could be changed
+to another value, but that would just shift the problem. Instead, switch
+some devices back to the older cpsw ethernet driver.
+
+(This patch is not suitable for upstreaming, it just makes the affected
+devices in OpenWrt usable again with the default network config.)
+
+Signed-off-by: Jan Hoffmann <jan@3e8.eu>
+---
+
+--- a/arch/arm/boot/dts/am335x-bone-common.dtsi
++++ b/arch/arm/boot/dts/am335x-bone-common.dtsi
+@@ -353,27 +353,24 @@
+ };
+ };
+
+-&cpsw_port1 {
++&cpsw_emac0 {
+ phy-handle = <&ethphy0>;
+ phy-mode = "mii";
+- ti,dual-emac-pvid = <1>;
+ };
+
+-&cpsw_port2 {
+- status = "disabled";
+-};
+-
+-&mac_sw {
++&mac {
++ slaves = <1>;
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&cpsw_default>;
+ pinctrl-1 = <&cpsw_sleep>;
+ status = "okay";
+ };
+
+-&davinci_mdio_sw {
++&davinci_mdio {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&davinci_mdio_default>;
+ pinctrl-1 = <&davinci_mdio_sleep>;
++ status = "okay";
+
+ ethphy0: ethernet-phy@0 {
+ reg = <0>;
+--- a/arch/arm/boot/dts/am335x-evm.dts
++++ b/arch/arm/boot/dts/am335x-evm.dts
+@@ -682,31 +682,28 @@
+ };
+ };
+
+-&mac_sw {
++&mac {
++ slaves = <1>;
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&cpsw_default>;
+ pinctrl-1 = <&cpsw_sleep>;
+ status = "okay";
+ };
+
+-&davinci_mdio_sw {
++&davinci_mdio {
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&davinci_mdio_default>;
+ pinctrl-1 = <&davinci_mdio_sleep>;
++ status = "okay";
+
+ ethphy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+ };
+
+-&cpsw_port1 {
++&cpsw_emac0 {
+ phy-handle = <&ethphy0>;
+ phy-mode = "rgmii-id";
+- ti,dual-emac-pvid = <1>;
+-};
+-
+-&cpsw_port2 {
+- status = "disabled";
+ };
+
+ &tscadc {
diff --git a/target/linux/pistachio/config-6.1 b/target/linux/pistachio/config-6.1
index 926b5e67f7..54145cd1f4 100644
--- a/target/linux/pistachio/config-6.1
+++ b/target/linux/pistachio/config-6.1
@@ -83,7 +83,6 @@ CONFIG_FIT_IMAGE_FDT_MARDUK=y
CONFIG_FIXED_PHY=y
CONFIG_FS_IOMAP=y
CONFIG_FS_MBCACHE=y
-CONFIG_FS_POSIX_ACL=y
CONFIG_FWNODE_MDIO=y
CONFIG_FW_LOADER_PAGED_BUF=y
CONFIG_GENERIC_ALLOCATOR=y
@@ -304,7 +303,6 @@ CONFIG_TARGET_ISA_REV=2
CONFIG_TICK_CPU_ACCOUNTING=y
CONFIG_TIMER_OF=y
CONFIG_TIMER_PROBE=y
-CONFIG_TMPFS_POSIX_ACL=y
CONFIG_TREE_RCU=y
CONFIG_TREE_SRCU=y
CONFIG_UBIFS_FS=y
diff --git a/target/linux/pistachio/config-6.6 b/target/linux/pistachio/config-6.6
index f1b98868e0..80ff36ebbb 100644
--- a/target/linux/pistachio/config-6.6
+++ b/target/linux/pistachio/config-6.6
@@ -98,7 +98,6 @@ CONFIG_FIT_IMAGE_FDT_MARDUK=y
CONFIG_FIXED_PHY=y
CONFIG_FS_IOMAP=y
CONFIG_FS_MBCACHE=y
-CONFIG_FS_POSIX_ACL=y
CONFIG_FUNCTION_ALIGNMENT=0
CONFIG_FWNODE_MDIO=y
CONFIG_FW_LOADER_PAGED_BUF=y
@@ -333,7 +332,6 @@ CONFIG_TARGET_ISA_REV=2
CONFIG_TICK_CPU_ACCOUNTING=y
CONFIG_TIMER_OF=y
CONFIG_TIMER_PROBE=y
-CONFIG_TMPFS_POSIX_ACL=y
CONFIG_TREE_RCU=y
CONFIG_TREE_SRCU=y
CONFIG_UBIFS_FS=y
diff --git a/target/linux/qoriq/Makefile b/target/linux/qoriq/Makefile
index 50d3187d84..9d03c3183f 100644
--- a/target/linux/qoriq/Makefile
+++ b/target/linux/qoriq/Makefile
@@ -12,6 +12,7 @@ FEATURES:=boot-part ext4 fpu legacy-sdcard powerpc64 ramdisk rootfs-part rtc sou
SUBTARGETS:=generic
KERNEL_PATCHVER:=6.1
+KERNEL_TESTING_PATCHVER:=6.6
KERNELNAME:=zImage
diff --git a/target/linux/qoriq/config-6.1 b/target/linux/qoriq/config-6.1
index bf3b2cfae8..4d803ffa80 100644
--- a/target/linux/qoriq/config-6.1
+++ b/target/linux/qoriq/config-6.1
@@ -115,7 +115,6 @@ CONFIG_EDAC_SUPPORT=y
CONFIG_EPAPR_PARAVIRT=y
CONFIG_EXCLUSIVE_SYSTEM_RAM=y
CONFIG_EXT4_FS=y
-CONFIG_EXT4_FS_POSIX_ACL=y
CONFIG_F2FS_FS=y
CONFIG_FIXED_PHY=y
# CONFIG_FSL_BMAN_TEST is not set
@@ -139,7 +138,6 @@ CONFIG_FSL_SOC_BOOKE=y
CONFIG_FSL_XGMAC_MDIO=y
CONFIG_FS_IOMAP=y
CONFIG_FS_MBCACHE=y
-CONFIG_FS_POSIX_ACL=y
CONFIG_FTL=y
CONFIG_FUNCTION_ERROR_INJECTION=y
CONFIG_FWNODE_MDIO=y
diff --git a/target/linux/qoriq/config-6.6 b/target/linux/qoriq/config-6.6
new file mode 100644
index 0000000000..3f42563db1
--- /dev/null
+++ b/target/linux/qoriq/config-6.6
@@ -0,0 +1,430 @@
+CONFIG_64BIT=y
+CONFIG_ALTIVEC=y
+CONFIG_ARCH_DMA_ADDR_T_64BIT=y
+CONFIG_ARCH_DMA_DEFAULT_COHERENT=y
+CONFIG_ARCH_FORCE_MAX_ORDER=12
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_KEEP_MEMBLOCK=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
+CONFIG_ARCH_MIGHT_HAVE_PC_SERIO=y
+CONFIG_ARCH_MMAP_RND_BITS=18
+CONFIG_ARCH_MMAP_RND_BITS_MAX=32
+CONFIG_ARCH_MMAP_RND_BITS_MIN=18
+CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=17
+CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11
+CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_STACKWALK=y
+CONFIG_ARCH_WEAK_RELEASE_ACQUIRE=y
+CONFIG_ASN1=y
+CONFIG_ASYNC_TX_ENABLE_CHANNEL_SWITCH=y
+CONFIG_AUDIT_ARCH=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_BLK_MQ_PCI=y
+CONFIG_BLK_PM=y
+CONFIG_BOOKE=y
+CONFIG_BOOKE_OR_40x=y
+CONFIG_BOOKE_WDT=y
+CONFIG_BUFFER_HEAD=y
+CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
+CONFIG_CC_NO_ARRAY_BOUNDS=y
+CONFIG_CLK_QORIQ=y
+CONFIG_CLONE_BACKWARDS=y
+CONFIG_CLZ_TAB=y
+CONFIG_COMMON_CLK=y
+CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
+# CONFIG_COMPAT_32BIT_TIME is not set
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_CONTEXT_TRACKING=y
+CONFIG_CONTEXT_TRACKING_IDLE=y
+CONFIG_CORENET_GENERIC=y
+CONFIG_CPU_BIG_ENDIAN=y
+CONFIG_CPU_FREQ=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL=y
+CONFIG_CPU_FREQ_GOV_ATTR_SET=y
+CONFIG_CPU_FREQ_GOV_COMMON=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+# CONFIG_CPU_FREQ_STAT is not set
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_IDLE_GOV_TEO=y
+CONFIG_CPU_ISOLATION=y
+CONFIG_CPU_MITIGATIONS=y
+CONFIG_CPU_RMAP=y
+CONFIG_CRC16=y
+CONFIG_CRYPTO_AUTHENC=y
+CONFIG_CRYPTO_CRC32=y
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_CRC32C_VPMSUM is not set
+CONFIG_CRYPTO_CURVE25519=y
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_DEV_FSL_CAAM=y
+CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API=y
+CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API_DESC=y
+CONFIG_CRYPTO_DEV_FSL_CAAM_COMMON=y
+CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API=y
+CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_DESC=y
+CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI=y
+CONFIG_CRYPTO_DEV_FSL_CAAM_JR=y
+CONFIG_CRYPTO_DEV_FSL_CAAM_PKC_API=y
+CONFIG_CRYPTO_DEV_FSL_CAAM_PRNG_API=y
+CONFIG_CRYPTO_DEV_FSL_CAAM_RINGSIZE=9
+CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_API=y
+# CONFIG_CRYPTO_DEV_NX is not set
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_ENGINE=y
+CONFIG_CRYPTO_HW=y
+CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
+CONFIG_CRYPTO_LIB_CURVE25519_GENERIC=y
+CONFIG_CRYPTO_LIB_DES=y
+CONFIG_CRYPTO_LIB_GF128MUL=y
+CONFIG_CRYPTO_LIB_POLY1305_RSIZE=1
+CONFIG_CRYPTO_LIB_SHA1=y
+CONFIG_CRYPTO_LIB_UTILS=y
+# CONFIG_CRYPTO_MD5_PPC is not set
+CONFIG_CRYPTO_RNG=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_RSA=y
+# CONFIG_CRYPTO_SHA1_PPC is not set
+CONFIG_CRYPTO_XTS=y
+CONFIG_DATA_SHIFT=12
+CONFIG_DEBUG_INFO=y
+CONFIG_DEFAULT_UIMAGE=y
+CONFIG_DMADEVICES=y
+CONFIG_DMA_ENGINE=y
+CONFIG_DMA_OF=y
+CONFIG_DMA_OPS=y
+CONFIG_DMA_OPS_BYPASS=y
+CONFIG_DTC=y
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_E5500_CPU is not set
+CONFIG_E6500_CPU=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_EDAC=y
+CONFIG_EDAC_ATOMIC_SCRUB=y
+# CONFIG_EDAC_CPC925 is not set
+# CONFIG_EDAC_DEBUG is not set
+CONFIG_EDAC_LEGACY_SYSFS=y
+CONFIG_EDAC_MPC85XX=y
+CONFIG_EDAC_SUPPORT=y
+CONFIG_EPAPR_PARAVIRT=y
+CONFIG_EXCLUSIVE_SYSTEM_RAM=y
+CONFIG_EXT4_FS=y
+CONFIG_F2FS_FS=y
+CONFIG_FIXED_PHY=y
+# CONFIG_FSL_BMAN_TEST is not set
+CONFIG_FSL_CORENET_CF=y
+CONFIG_FSL_CORENET_RCPM=y
+CONFIG_FSL_DMA=y
+CONFIG_FSL_DPAA=y
+# CONFIG_FSL_DPAA_CHECKING is not set
+CONFIG_FSL_DPAA_ETH=y
+CONFIG_FSL_EMB_PERFMON=y
+CONFIG_FSL_FMAN=y
+CONFIG_FSL_GUTS=y
+CONFIG_FSL_IFC=y
+CONFIG_FSL_LBC=y
+CONFIG_FSL_MPIC_TIMER_WAKEUP=y
+CONFIG_FSL_PAMU=y
+CONFIG_FSL_PCI=y
+# CONFIG_FSL_QMAN_TEST is not set
+CONFIG_FSL_SOC=y
+CONFIG_FSL_SOC_BOOKE=y
+# CONFIG_FSL_ULI1575 is not set
+CONFIG_FSL_XGMAC_MDIO=y
+CONFIG_FS_IOMAP=y
+CONFIG_FS_MBCACHE=y
+CONFIG_FTL=y
+CONFIG_FUNCTION_ALIGNMENT=0
+CONFIG_FUNCTION_ERROR_INJECTION=y
+CONFIG_FWNODE_MDIO=y
+CONFIG_FW_LOADER_PAGED_BUF=y
+CONFIG_FW_LOADER_SYSFS=y
+CONFIG_GCC10_NO_ARRAY_BOUNDS=y
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_GENERIC_CPU_AUTOPROBE=y
+CONFIG_GENERIC_CPU_VULNERABILITIES=y
+CONFIG_GENERIC_EARLY_IOREMAP=y
+CONFIG_GENERIC_GETTIMEOFDAY=y
+CONFIG_GENERIC_IDLE_POLL_SETUP=y
+CONFIG_GENERIC_IOREMAP=y
+CONFIG_GENERIC_IRQ_MIGRATION=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_GENERIC_MSI_IRQ=y
+CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_PHY=y
+CONFIG_GENERIC_SMP_IDLE_THREAD=y
+CONFIG_GENERIC_STRNCPY_FROM_USER=y
+CONFIG_GENERIC_STRNLEN_USER=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+# CONFIG_GEN_RTC is not set
+# CONFIG_GIANFAR is not set
+CONFIG_GLOB=y
+CONFIG_GPIO_CDEV=y
+CONFIG_GPIO_GENERIC=y
+CONFIG_GPIO_MPC8XXX=y
+CONFIG_GRO_CELLS=y
+# CONFIG_HANGCHECK_TIMER is not set
+CONFIG_HAS_DMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_IOPORT_MAP=y
+CONFIG_HWMON=y
+CONFIG_HW_CONSOLE=y
+CONFIG_HW_RANDOM=y
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_MPC=y
+CONFIG_ILLEGAL_POINTER_VALUE=0x5deadbeef0000000
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_INPUT=y
+CONFIG_INTERRUPT_SANITIZE_REGISTERS=y
+# CONFIG_IOMMUFD is not set
+CONFIG_IOMMU_API=y
+# CONFIG_IOMMU_DEBUGFS is not set
+# CONFIG_IOMMU_DEFAULT_DMA_LAZY is not set
+CONFIG_IOMMU_DEFAULT_DMA_STRICT=y
+# CONFIG_IOMMU_DEFAULT_PASSTHROUGH is not set
+CONFIG_IOMMU_HELPER=y
+CONFIG_IOMMU_SUPPORT=y
+CONFIG_IRQCHIP=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_DOMAIN_HIERARCHY=y
+CONFIG_IRQ_FORCED_THREADING=y
+CONFIG_IRQ_WORK=y
+CONFIG_ISA_DMA_API=y
+CONFIG_JBD2=y
+CONFIG_JUMP_LABEL=y
+CONFIG_JUMP_LABEL_FEATURE_CHECKS=y
+# CONFIG_JUMP_LABEL_FEATURE_CHECK_DEBUG is not set
+CONFIG_KALLSYMS=y
+CONFIG_KERNEL_GZIP=y
+CONFIG_KERNEL_START=0xc000000000000000
+CONFIG_KPROBES=y
+CONFIG_KRETPROBES=y
+CONFIG_LIBFDT=y
+CONFIG_LOCK_DEBUGGING_SUPPORT=y
+CONFIG_LOCK_SPIN_ON_OWNER=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_MARVELL_PHY=y
+CONFIG_MATH_EMULATION=y
+# CONFIG_MATH_EMULATION_FULL is not set
+CONFIG_MATH_EMULATION_HW_UNIMPLEMENTED=y
+CONFIG_MDIO_BUS=y
+CONFIG_MDIO_DEVICE=y
+CONFIG_MDIO_DEVRES=y
+CONFIG_MEMORY=y
+CONFIG_MIGRATION=y
+CONFIG_MMC=y
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_DEBUG=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_IO_ACCESSORS=y
+CONFIG_MMC_SDHCI_OF_ESDHC=y
+# CONFIG_MMC_SDHCI_PCI is not set
+CONFIG_MMC_SDHCI_PLTFM=y
+# CONFIG_MMC_WBSD is not set
+CONFIG_MMIOWB=y
+CONFIG_MMU_GATHER_MERGE_VMAS=y
+CONFIG_MMU_GATHER_PAGE_SIZE=y
+CONFIG_MMU_LAZY_TLB_REFCOUNT=y
+CONFIG_MODULES_USE_ELF_RELA=y
+CONFIG_MPIC=y
+CONFIG_MPIC_MSGR=y
+CONFIG_MPIC_TIMER=y
+CONFIG_MPILIB=y
+CONFIG_MTD_NAND_CORE=y
+CONFIG_MTD_NAND_ECC=y
+CONFIG_MTD_NAND_ECC_SW_HAMMING=y
+CONFIG_MTD_NAND_FSL_IFC=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_RAW_NAND=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_LENGTH=y
+CONFIG_NET_DEVLINK=y
+CONFIG_NET_DSA=y
+CONFIG_NET_DSA_MV88E6XXX=y
+CONFIG_NET_DSA_TAG_DSA=y
+CONFIG_NET_DSA_TAG_DSA_COMMON=y
+CONFIG_NET_DSA_TAG_EDSA=y
+CONFIG_NET_DSA_TAG_OCELOT=y
+CONFIG_NET_DSA_TAG_TRAILER=y
+CONFIG_NET_EGRESS=y
+CONFIG_NET_FLOW_LIMIT=y
+CONFIG_NET_INGRESS=y
+CONFIG_NET_PTP_CLASSIFY=y
+CONFIG_NET_SELFTESTS=y
+CONFIG_NET_SWITCHDEV=y
+CONFIG_NET_XGRESS=y
+CONFIG_NLS=y
+CONFIG_NONSTATIC_KERNEL=y
+CONFIG_NO_HZ_COMMON=y
+CONFIG_NO_HZ_IDLE=y
+CONFIG_NR_CPUS=24
+CONFIG_NR_IRQS=512
+CONFIG_OF=y
+CONFIG_OF_ADDRESS=y
+CONFIG_OF_EARLY_FLATTREE=y
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_GPIO=y
+CONFIG_OF_IOMMU=y
+CONFIG_OF_IRQ=y
+CONFIG_OF_KOBJ=y
+CONFIG_OF_MDIO=y
+CONFIG_OLD_SIGSUSPEND=y
+CONFIG_OPTPROBES=y
+CONFIG_PACKING=y
+CONFIG_PADATA=y
+CONFIG_PAGE_OFFSET=0xc000000000000000
+CONFIG_PAGE_POOL=y
+CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
+CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_MSI=y
+CONFIG_PCI_MSI_ARCH_FALLBACKS=y
+CONFIG_PCS_LYNX=y
+CONFIG_PGTABLE_LEVELS=4
+CONFIG_PHYLIB=y
+CONFIG_PHYLIB_LEDS=y
+CONFIG_PHYLINK=y
+CONFIG_PHYSICAL_START=0x00000000
+CONFIG_PHYS_64BIT=y
+CONFIG_PHYS_ADDR_T_64BIT=y
+CONFIG_PM=y
+# CONFIG_PMU_SYSFS is not set
+CONFIG_PM_CLK=y
+CONFIG_PPC=y
+CONFIG_PPC64=y
+CONFIG_PPC64_BIG_ENDIAN_ELF_ABI_V2=y
+CONFIG_PPC64_ELF_ABI_V2=y
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_BARRIER_NOSPEC=y
+CONFIG_PPC_BOOK3E_64=y
+# CONFIG_PPC_BOOK3S_64 is not set
+CONFIG_PPC_DAWR=y
+CONFIG_PPC_DOORBELL=y
+CONFIG_PPC_E500=y
+CONFIG_PPC_E500MC=y
+# CONFIG_PPC_EARLY_DEBUG is not set
+CONFIG_PPC_EPAPR_HV_PIC=y
+CONFIG_PPC_FPU=y
+CONFIG_PPC_FPU_REGS=y
+CONFIG_PPC_HAS_LBARX_LHARX=y
+CONFIG_PPC_INDIRECT_PCI=y
+# CONFIG_PPC_IRQ_SOFT_MASK_DEBUG is not set
+CONFIG_PPC_KUAP=y
+# CONFIG_PPC_KUAP_DEBUG is not set
+CONFIG_PPC_KUEP=y
+CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_MSI_BITMAP=y
+CONFIG_PPC_OF_BOOT_TRAMPOLINE=y
+CONFIG_PPC_PAGE_SHIFT=12
+# CONFIG_PPC_QEMU_E500 is not set
+CONFIG_PPC_QUEUED_SPINLOCKS=y
+CONFIG_PPC_SMP_MUXED_IPI=y
+CONFIG_PPC_UDBG_16550=y
+CONFIG_PPC_WERROR=y
+CONFIG_PPS=y
+CONFIG_PREEMPT_NONE_BUILD=y
+CONFIG_PTE_64BIT=y
+CONFIG_PTP_1588_CLOCK=y
+CONFIG_PTP_1588_CLOCK_OPTIONAL=y
+CONFIG_PTP_1588_CLOCK_QORIQ=y
+CONFIG_QORIQ_CPUFREQ=y
+CONFIG_QORIQ_THERMAL=y
+CONFIG_QUEUED_RWLOCKS=y
+CONFIG_RANDSTRUCT_NONE=y
+CONFIG_RAS=y
+CONFIG_RATIONAL=y
+# CONFIG_RAVE_SP_CORE is not set
+CONFIG_REGMAP=y
+CONFIG_REGMAP_MMIO=y
+CONFIG_RELOCATABLE=y
+# CONFIG_RELOCATABLE_TEST is not set
+CONFIG_RFS_ACCEL=y
+CONFIG_RPS=y
+CONFIG_RWSEM_SPIN_ON_OWNER=y
+# CONFIG_SCOM_DEBUGFS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_COMMON=y
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_FSL=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_DEV_BUS=y
+CONFIG_SERIAL_DEV_CTRL_TTYPORT=y
+CONFIG_SERIAL_FSL_LINFLEXUART=y
+CONFIG_SERIAL_FSL_LINFLEXUART_CONSOLE=y
+CONFIG_SERIAL_FSL_LPUART=y
+CONFIG_SERIAL_FSL_LPUART_CONSOLE=y
+CONFIG_SERIAL_MCTRL_GPIO=y
+CONFIG_SG_POOL=y
+CONFIG_SMP=y
+CONFIG_SMT_NUM_THREADS_DYNAMIC=y
+CONFIG_SOCK_RX_QUEUE_MAPPING=y
+CONFIG_SOC_BUS=y
+CONFIG_SOFTIRQ_ON_OWN_STACK=y
+CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_SPI=y
+CONFIG_SPI_FSL_ESPI=y
+CONFIG_SPI_MASTER=y
+CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y
+CONFIG_SWIOTLB=y
+CONFIG_SWPHY=y
+CONFIG_SYSCTL_EXCEPTION_TRACE=y
+CONFIG_TARGET_CPU="e6500"
+CONFIG_TARGET_CPU_BOOL=y
+CONFIG_THERMAL=y
+CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
+CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
+CONFIG_THERMAL_GOV_STEP_WISE=y
+CONFIG_THERMAL_OF=y
+CONFIG_THREAD_INFO_IN_TASK=y
+CONFIG_THREAD_SHIFT=14
+# CONFIG_TOOLCHAIN_DEFAULT_CPU is not set
+CONFIG_TOOLS_SUPPORT_RELR=y
+CONFIG_TREE_RCU=y
+CONFIG_TREE_SRCU=y
+# CONFIG_UCLAMP_TASK is not set
+CONFIG_USB=y
+CONFIG_USB_COMMON=y
+CONFIG_USB_EHCI_FSL=y
+CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_HCD_PLATFORM is not set
+CONFIG_USB_STORAGE=y
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_UAS=y
+CONFIG_VGA_CONSOLE=y
+CONFIG_VIRT_CPU_ACCOUNTING=y
+CONFIG_VIRT_CPU_ACCOUNTING_NATIVE=y
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_WATCHDOG_CORE=y
+# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set
+CONFIG_XPS=y
+CONFIG_ZLIB_DEFLATE=y
diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6010-xe3-4.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6010-xe3-4.dts
new file mode 100644
index 0000000000..eba4d116ad
--- /dev/null
+++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6010-xe3-4.dts
@@ -0,0 +1,454 @@
+// SPDX-License-Identifier: (GPL-2.0+)
+
+/dts-v1/;
+
+#include "ipq6018.dtsi"
+#include "ipq6018-fixed-smps.dtsi"
+#include "ipq6018-ess.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+ /* Qualcomm Technologies, Inc. IPQ6018/AP-CP01-C3 */
+ model = "Cambium Networks XE3-4";
+ compatible = "cambiumnetworks,xe3-4", "qcom,ipq6018-cp01", "qcom,ipq6018";
+
+ aliases {
+ serial0 = &blsp1_uart3;
+ sdhc2 = &sdhc_1;
+ ethernet0 = &dp5;
+ ethernet1 = &dp4;
+ label-mac-device = &dp5;
+
+ led-boot = &led_status_amber;
+ led-failsafe = &led_status_amber;
+ led-running = &led_status_white;
+ led-upgrade = &led_status_amber;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ bootargs-append = " root=/dev/ubiblock0_1";
+ };
+
+ keys {
+ compatible = "gpio-keys";
+
+ reset {
+ label = "reset";
+ gpios = <&tlmm 19 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_RESTART>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-0 = <&led_pins>;
+ pinctrl-names = "default";
+
+ led_status_white: status-white {
+ color = <LED_COLOR_ID_WHITE>;
+ function = LED_FUNCTION_STATUS;
+ gpio = <&tlmm 56 GPIO_ACTIVE_LOW>;
+ };
+
+ led_status_amber: status-amber {
+ color = <LED_COLOR_ID_AMBER>;
+ function = LED_FUNCTION_STATUS;
+ gpio = <&tlmm 35 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ reg_sd_vmmc: regulator-sdcard-vmmc {
+ compatible = "regulator-fixed";
+ regulator-name = "sdcard-vmmc";
+ regulator-min-microvolt = <2950000>;
+ regulator-max-microvolt = <2950000>;
+
+ startup-delay-us = <200>;
+
+ gpio = <&tlmm 66 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd_vmmc_en_default>;
+ };
+};
+
+&blsp1_uart3 {
+ pinctrl-0 = <&serial_3_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&blsp1_i2c3 {
+ pinctrl-0 = <&i2c_1_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&tlmm {
+ /* TZ has exclusive control over GPIO20 */
+ gpio-reserved-ranges = <20 1>;
+
+ mdio_pins: mdio-pins {
+ mdc {
+ pins = "gpio64";
+ function = "mdc";
+ drive-strength = <8>;
+ bias-pull-up;
+ };
+
+ mdio {
+ pins = "gpio65";
+ function = "mdio";
+ drive-strength = <8>;
+ bias-pull-up;
+ };
+ };
+
+ i2c_1_pins: i2c-1-state {
+ pins = "gpio42", "gpio43";
+ function = "blsp2_i2c";
+ drive-strength = <8>;
+ };
+
+ spi_0_pins: spi-0-state {
+ pins = "gpio38", "gpio39", "gpio40", "gpio41";
+ function = "blsp0_spi";
+ drive-strength = <8>;
+ bias-pull-down;
+ };
+
+ led_pins: led_pins {
+ leds {
+ pins = "gpio35", "gpio37", "gpio50";
+ function = "gpio";
+ drive-strength = <8>;
+ bias-pull-down;
+ };
+ };
+
+ sd_vmmc_en_default: sd-vmmc-en-default-state {
+ pins = "gpio66";
+ function = "gpio";
+ drive-strength = <8>;
+ bias-pull-down;
+ };
+
+ sd_pins: sd-state {
+ pins = "gpio62";
+ function = "gpio";
+ drive-strength = <8>;
+ bias-pull-up;
+ };
+};
+
+&pcie_phy {
+ status = "okay";
+};
+
+&pcie0 {
+ status = "okay";
+ perst-gpio = <&tlmm 60 GPIO_ACTIVE_LOW>;
+
+ bridge@0,0 {
+ reg = <0x00000000 0 0 0 0>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges;
+
+ wifi@1,0 {
+ status = "okay";
+
+ /* ath11k has no DT compatible for PCI cards */
+ compatible = "pci17cb,1104";
+ reg = <0x00010000 0 0 0 0>;
+
+ qcom,ath11k-fw-memory-mode = <0>;
+ qcom,ath11k-calibration-variant = "CambiumNetworks-XE34";
+ };
+ };
+};
+
+&sdhc_1 {
+ pinctrl-0 = <&sd_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ cd-gpios = <&tlmm 62 GPIO_ACTIVE_LOW>;
+ vqmmc-supply = <&reg_sd_vmmc>;
+ bus-width = <4>;
+};
+
+&edma {
+ status = "okay";
+};
+
+&switch {
+ status = "okay";
+
+ switch_lan_bmp = <(ESS_PORT4 | ESS_PORT5)>;
+ switch_mac_mode = <MAC_MODE_PSGMII>;
+ switch_mac_mode2 = <MAC_MODE_SGMII_PLUS>;
+
+ qcom,port_phyinfo {
+ port@4 {
+ port_id = <4>;
+ phy_address = <3>;
+ };
+
+ port@5 {
+ port_id = <5>;
+ phy_address = <24>;
+ port_mac_sel = "QGMAC_PORT";
+ };
+ };
+};
+
+&mdio {
+ status = "okay";
+ pinctrl-0 = <&mdio_pins>;
+ pinctrl-names = "default";
+ reset-gpios = <&tlmm 75 GPIO_ACTIVE_LOW>;
+ reset-delay-us = <10000>;
+ reset-post-delay-us = <50000>;
+
+ ethernet-phy-package@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "qcom,qca8075-package";
+ reg = <0>;
+
+ qcom,package-mode = "psgmii";
+
+ qca8072: ethernet-phy@3 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <3>;
+ };
+ };
+
+ qca8081: ethernet-phy@24 {
+ compatible = "ethernet-phy-id004d.d101";
+ reg = <24>;
+ reset-gpios = <&tlmm 77 GPIO_ACTIVE_LOW>;
+ reset-assert-us = <10000>;
+ reset-deassert-us = <50000>;
+ };
+};
+
+&dp4 {
+ status = "okay";
+
+ phy-handle = <&qca8072>;
+ nvmem-cell-names = "mac-address";
+ nvmem-cells = <&eth1addr 0>;
+ label = "lan2";
+};
+
+&dp5 {
+ status = "okay";
+
+ phy-mode = "sgmii";
+ phy-handle = <&qca8081>;
+ nvmem-cell-names = "mac-address";
+ nvmem-cells = <&ethaddr 0>;
+ label = "lan1";
+};
+
+&blsp1_spi1 {
+ pinctrl-0 = <&spi_0_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+
+ flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0>;
+ /*
+ * U-boot looks for "n25q128a11" node,
+ * if we don't have it, it will spit out the following warning:
+ * "ipq: fdt fixup unable to find compatible node".
+ */
+ linux,modalias = "m25p80", "mx30uf2g18ac", "n25q128a11";
+ compatible = "micron,n25q128a11", "jedec,spi-nor";
+ spi-max-frequency = <50000000>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "0:SBL1";
+ reg = <0x0 0xc0000>;
+ read-only;
+ };
+
+ partition@c0000 {
+ label = "0:MIBIB";
+ reg = <0xc0000 0x10000>;
+ read-only;
+ };
+
+ partition@d0000 {
+ label = "0:BOOTCONFIG";
+ reg = <0xd0000 0x20000>;
+ read-only;
+ };
+
+ partition@f0000 {
+ label = "0:BOOTCONFIG1";
+ reg = <0xf0000 0x20000>;
+ read-only;
+ };
+
+ partition@110000 {
+ label = "0:QSEE";
+ reg = <0x110000 0x1a0000>;
+ read-only;
+ };
+
+ partition@2b0000 {
+ label = "0:QSEE_1";
+ reg = <0x2b0000 0x1a0000>;
+ read-only;
+ };
+
+ partition@450000 {
+ label = "0:DEVCFG";
+ reg = <0x450000 0x10000>;
+ read-only;
+ };
+
+ partition@460000 {
+ label = "mfginfo";
+ reg = <0x460000 0x10000>;
+ read-only;
+ };
+
+ partition@470000 {
+ label = "0:RPM";
+ reg = <0x470000 0x40000>;
+ read-only;
+ };
+
+ partition@4b0000 {
+ label = "0:RPM_1";
+ reg = <0x4b0000 0x40000>;
+ read-only;
+ };
+
+ partition@4f0000 {
+ label = "0:CDT";
+ reg = <0x4f0000 0x10000>;
+ read-only;
+ };
+
+ partition@500000 {
+ label = "0:CDT_1";
+ reg = <0x500000 0x10000>;
+ read-only;
+ };
+
+ partition@510000 {
+ compatible = "u-boot,env";
+ label = "0:APPSBLENV";
+ reg = <0x510000 0x10000>;
+
+ ethaddr: ethaddr {
+ #nvmem-cell-cells = <0>;
+ };
+
+ eth1addr: eth1addr {
+ #nvmem-cell-cells = <0>;
+ };
+
+ eth2addr: eth2addr {
+ #nvmem-cell-cells = <0>;
+ };
+
+ eth5addr: eth5addr {
+ #nvmem-cell-cells = <0>;
+ };
+ };
+
+ partition@520000 {
+ label = "0:APPSBL";
+ reg = <0x520000 0xa0000>;
+ read-only;
+ };
+
+ partition@5c0000 {
+ label = "0:APPSBL_1";
+ reg = <0x5c0000 0xa0000>;
+ read-only;
+ };
+
+ partition@660000 {
+ label = "0:ART";
+ reg = <0x660000 0x80000>;
+ read-only;
+ };
+ };
+ };
+};
+
+&qpic_bam {
+ status = "okay";
+};
+
+&qpic_nand {
+ status = "okay";
+
+ nand@0 {
+ reg = <0>;
+
+ nand-ecc-strength = <4>;
+ nand-ecc-step-size = <512>;
+ nand-bus-width = <8>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "rootfs";
+ reg = <0x0 0x6000000>;
+ };
+
+ partition@6000000 {
+ label = "rootfs_1";
+ reg = <0x6000000 0x6000000>;
+ };
+
+ partition@c000000 {
+ label = "NVRAM";
+ reg = <0xc000000 0x3000000>;
+ };
+
+ partition@f000000 {
+ label = "crashLog";
+ reg = <0xf000000 0x1000000>;
+ };
+ };
+ };
+};
+
+&wifi {
+ status = "okay";
+ qcom,ath11k-calibration-variant = "CambiumNetworks-XE34";
+
+ nvmem-cell-names = "mac-address";
+ nvmem-cells = <&eth2addr>;
+};
+
+&qusb_phy_1 {
+ status = "okay";
+};
+
+&usb2 {
+ status = "okay";
+};
diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6018-fixed-smps.dtsi b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6018-fixed-smps.dtsi
new file mode 100644
index 0000000000..e867daf866
--- /dev/null
+++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6018-fixed-smps.dtsi
@@ -0,0 +1,52 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+/*
+ * Board does not use companion MP5496 PMIC,
+ * but rather uses fixed external SMPS.
+ */
+
+&rpm {
+ status = "disabled";
+};
+
+&CPU0 {
+ /delete-property/ cpu-supply;
+};
+
+&CPU1 {
+ /delete-property/ cpu-supply;
+};
+
+&CPU2 {
+ /delete-property/ cpu-supply;
+};
+
+&CPU3 {
+ /delete-property/ cpu-supply;
+};
+
+&cpu_opp_table {
+ opp-864000000 {
+ opp-microvolt = <1100000>;
+ };
+
+ opp-1056000000 {
+ opp-microvolt = <1100000>;
+ };
+
+ opp-1320000000 {
+ opp-microvolt = <1100000>;
+ };
+
+ opp-1440000000 {
+ opp-microvolt = <1100000>;
+ };
+
+ opp-1608000000 {
+ opp-microvolt = <1100000>;
+ };
+
+ opp-1800000000 {
+ opp-microvolt = <1100000>;
+ };
+};
diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-eap660hd-v1.dts b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-eap660hd-v1.dts
new file mode 100644
index 0000000000..500847c98b
--- /dev/null
+++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq8072-eap660hd-v1.dts
@@ -0,0 +1,131 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR BSD-2-Clause
+
+/dts-v1/;
+
+#include "ipq8074.dtsi"
+#include "ipq8074-hk-cpu.dtsi"
+#include "ipq8074-ess.dtsi"
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ model = "TP-Link EAP660 HD v1";
+ compatible = "tplink,eap660hd-v1", "qcom,ipq8074";
+
+ aliases {
+ serial0 = &blsp1_uart5;
+ led-boot = &led_status_blue;
+ led-failsafe = &led_status_blue;
+ led-running = &led_status_blue;
+ led-upgrade = &led_status_blue;
+ };
+
+ chosen {
+ stdout-path = "serial0,115200n8";
+ bootargs-append = " root=/dev/ubiblock0_1";
+ };
+
+ keys {
+ compatible = "gpio-keys";
+
+ reset {
+ label = "reset";
+ gpios = <&tlmm 50 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_RESTART>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led_status_blue: status-blue {
+ function = LED_FUNCTION_STATUS;
+ gpios = <&tlmm 42 GPIO_ACTIVE_HIGH>;
+ color = <LED_COLOR_ID_BLUE>;
+ };
+ };
+};
+
+&blsp1_uart5 {
+ status = "okay";
+};
+
+&tlmm {
+ mdio_pins: mdio-pins {
+ mdc {
+ pins = "gpio68";
+ function = "mdc";
+ drive-strength = <8>;
+ bias-pull-up;
+ };
+
+ mdio {
+ pins = "gpio69";
+ function = "mdio";
+ drive-strength = <8>;
+ bias-pull-up;
+ };
+ };
+};
+
+&mdio {
+ status = "okay";
+ pinctrl-0 = <&mdio_pins>;
+ pinctrl-names = "default";
+ reset-gpios = <&tlmm 25 GPIO_ACTIVE_LOW>;
+
+ qca8081_28: ethernet-phy@28 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <28>;
+ };
+};
+
+&dp5 {
+ status = "okay";
+ phy-mode = "sgmii";
+ phy-handle = <&qca8081_28>;
+ label = "lan";
+};
+
+&switch {
+ status = "okay";
+ switch_lan_bmp = <ESS_PORT5>;
+ switch_mac_mode1 = <MAC_MODE_SGMII_PLUS>;
+
+ qcom,port_phyinfo {
+ port@5 {
+ phy_address = <28>;
+ port_id = <5>;
+ port_mac_sel = "QGMAC_PORT";
+ };
+ };
+};
+
+&edma {
+ status = "okay";
+};
+
+&qpic_bam {
+ status = "okay";
+};
+
+&qpic_nand {
+ status = "okay";
+
+ nand@0 {
+ reg = <0>;
+ nand-ecc-strength = <4>;
+ nand-ecc-step-size = <512>;
+ nand-bus-width = <8>;
+
+ partitions {
+ compatible = "qcom,smem-part";
+ };
+ };
+};
+
+&wifi {
+ status = "okay";
+ qcom,ath11k-calibration-variant = "TP-Link-EAP660-HD-v1";
+};
diff --git a/target/linux/qualcommax/image/ipq60xx.mk b/target/linux/qualcommax/image/ipq60xx.mk
index 79822ceb01..41cfd164ee 100644
--- a/target/linux/qualcommax/image/ipq60xx.mk
+++ b/target/linux/qualcommax/image/ipq60xx.mk
@@ -11,6 +11,19 @@ define Device/8devices_mango-dvk
endef
TARGET_DEVICES += 8devices_mango-dvk
+define Device/cambiumnetworks_xe3-4
+ $(call Device/FitImage)
+ $(call Device/UbiFit)
+ DEVICE_VENDOR := Cambium Networks
+ DEVICE_MODEL := XE3-4
+ BLOCKSIZE := 128k
+ PAGESIZE := 2048
+ DEVICE_DTS_CONFIG := config@cp01-c3-xv3-4
+ SOC := ipq6010
+ DEVICE_PACKAGES := ipq-wifi-cambiumnetworks_xe34 ath11k-firmware-qcn9074 kmod-ath11k-pci
+endef
+TARGET_DEVICES += cambiumnetworks_xe3-4
+
define Device/netgear_wax214
$(call Device/FitImage)
$(call Device/UbiFit)
diff --git a/target/linux/qualcommax/image/ipq807x.mk b/target/linux/qualcommax/image/ipq807x.mk
index 8caa6a322c..b62734334d 100644
--- a/target/linux/qualcommax/image/ipq807x.mk
+++ b/target/linux/qualcommax/image/ipq807x.mk
@@ -344,6 +344,20 @@ define Device/spectrum_sax1v1k
endef
TARGET_DEVICES += spectrum_sax1v1k
+define Device/tplink_eap660hd-v1
+ $(call Device/FitImage)
+ $(call Device/UbiFit)
+ DEVICE_VENDOR := TP-Link
+ DEVICE_MODEL := EAP660 HD
+ DEVICE_VARIANT := v1
+ BLOCKSIZE := 128k
+ PAGESIZE := 2048
+ SOC := ipq8072
+ DEVICE_PACKAGES := ipq-wifi-tplink_eap660hd-v1
+ TPLINK_SUPPORT_STRING := SupportList:\r\nEAP660 HD(TP-Link|UN|AX3600-D):1.0\r\n
+endef
+TARGET_DEVICES += tplink_eap660hd-v1
+
define Device/xiaomi_ax3600
$(call Device/FitImage)
$(call Device/UbiFit)
diff --git a/target/linux/qualcommax/ipq60xx/base-files/etc/board.d/02_network b/target/linux/qualcommax/ipq60xx/base-files/etc/board.d/02_network
index f5fd35cf44..86d55de7b8 100644
--- a/target/linux/qualcommax/ipq60xx/base-files/etc/board.d/02_network
+++ b/target/linux/qualcommax/ipq60xx/base-files/etc/board.d/02_network
@@ -14,6 +14,9 @@ ipq60xx_setup_interfaces()
8devices,mango-dvk)
ucidef_set_interfaces_lan_wan "lan1 lan2" "wan"
;;
+ cambiumnetworks,xe3-4)
+ ucidef_set_interface_lan "lan1 lan2" "dhcp"
+ ;;
netgear,wax214)
ucidef_set_interfaces_lan_wan "lan"
;;
diff --git a/target/linux/qualcommax/ipq60xx/base-files/etc/hotplug.d/firmware/11-ath11-caldata b/target/linux/qualcommax/ipq60xx/base-files/etc/hotplug.d/firmware/11-ath11-caldata
index 23a3da0b4b..cc2de7514e 100644
--- a/target/linux/qualcommax/ipq60xx/base-files/etc/hotplug.d/firmware/11-ath11-caldata
+++ b/target/linux/qualcommax/ipq60xx/base-files/etc/hotplug.d/firmware/11-ath11-caldata
@@ -12,6 +12,9 @@ case "$FIRMWARE" in
8devices,mango-dvk)
caldata_extract "0:ART" 0x1000 0x20000
;;
+ cambiumnetworks,xe3-4)
+ caldata_extract "0:ART" 0x1000 0x10000
+ ;;
netgear,wax214)
caldata_extract "0:art" 0x1000 0x10000
;;
@@ -20,6 +23,13 @@ case "$FIRMWARE" in
;;
esac
;;
+"ath11k/QCN9074/hw1.0/cal-pci-0000:01:00.0.bin")
+ case "$board" in
+ cambiumnetworks,xe3-4)
+ caldata_extract "0:ART" 0x26800 0x20000
+ ;;
+ esac
+ ;;
*)
exit 1
;;
diff --git a/target/linux/qualcommax/ipq60xx/base-files/lib/upgrade/platform.sh b/target/linux/qualcommax/ipq60xx/base-files/lib/upgrade/platform.sh
index a8e4872cdd..cbc6292978 100644
--- a/target/linux/qualcommax/ipq60xx/base-files/lib/upgrade/platform.sh
+++ b/target/linux/qualcommax/ipq60xx/base-files/lib/upgrade/platform.sh
@@ -33,6 +33,10 @@ EOF
platform_do_upgrade() {
case "$(board_name)" in
+ cambiumnetworks,xe3-4)
+ fw_setenv bootcount 0
+ nand_do_upgrade "$1"
+ ;;
netgear,wax214)
nand_do_upgrade "$1"
;;
diff --git a/target/linux/qualcommax/ipq807x/base-files/etc/board.d/02_network b/target/linux/qualcommax/ipq807x/base-files/etc/board.d/02_network
index f87dbdd2be..437581d001 100644
--- a/target/linux/qualcommax/ipq807x/base-files/etc/board.d/02_network
+++ b/target/linux/qualcommax/ipq807x/base-files/etc/board.d/02_network
@@ -60,6 +60,9 @@ ipq807x_setup_interfaces()
qnap,301w)
ucidef_set_interfaces_lan_wan "lan1 lan2 lan3 lan4 10g-2" "10g-1"
;;
+ tplink,eap660hd-v1)
+ ucidef_set_interface_lan "lan" "dhcp"
+ ;;
zyxel,nbg7815)
ucidef_set_interfaces_lan_wan "lan1 lan2 lan3 lan4 10g" "wan"
;;
@@ -89,6 +92,10 @@ ipq807x_setup_macs()
lan_mac=$(macaddr_add $label_mac 1)
wan_mac=$label_mac
;;
+ tplink,eap660hd-v1)
+ label_mac=$(get_mac_binary /tmp/factory_data/default-mac 0)
+ lan_mac=$label_mac
+ ;;
esac
[ -n "$lan_mac" ] && ucidef_set_interface_macaddr "lan" $lan_mac
diff --git a/target/linux/qualcommax/ipq807x/base-files/etc/hotplug.d/firmware/11-ath11k-caldata b/target/linux/qualcommax/ipq807x/base-files/etc/hotplug.d/firmware/11-ath11k-caldata
index e413801ef9..2e741f0448 100644
--- a/target/linux/qualcommax/ipq807x/base-files/etc/hotplug.d/firmware/11-ath11k-caldata
+++ b/target/linux/qualcommax/ipq807x/base-files/etc/hotplug.d/firmware/11-ath11k-caldata
@@ -80,6 +80,13 @@ case "$FIRMWARE" in
spectrum,sax1v1k)
caldata_extract_mmc "0:ART" 0x1000 0x20000
;;
+ tplink,eap660hd-v1)
+ caldata_from_file "/tmp/factory_data/radio" 0 0x20000
+ label_mac=$(get_mac_binary /tmp/factory_data/default-mac 0)
+ ath11k_patch_mac $label_mac 1
+ ath11k_patch_mac $(macaddr_add $label_mac 1) 0
+ ath11k_set_macflag
+ ;;
zbtlink,zbt-z800ax)
caldata_extract "0:art" 0x1000 0x20000
label_mac=$(get_mac_label)
diff --git a/target/linux/qualcommax/ipq807x/base-files/lib/preinit/09_mount_factory_data b/target/linux/qualcommax/ipq807x/base-files/lib/preinit/09_mount_factory_data
new file mode 100644
index 0000000000..59fde529d3
--- /dev/null
+++ b/target/linux/qualcommax/ipq807x/base-files/lib/preinit/09_mount_factory_data
@@ -0,0 +1,19 @@
+#!/bin/sh
+
+preinit_mount_factory_data() {
+ local mtd_path
+
+ . /lib/functions.sh
+ . /lib/functions/system.sh
+
+ case $(board_name) in
+ tplink,eap660hd-v1)
+ mtd_path=$(find_mtd_chardev "factory_data")
+ ubiattach --dev-path="$mtd_path" --devn=1
+ mkdir /tmp/factory_data
+ mount -o ro,noatime -t ubifs ubi1:ubi_factory_data /tmp/factory_data
+ ;;
+ esac
+}
+
+boot_hook_add preinit_main preinit_mount_factory_data
diff --git a/target/linux/qualcommax/ipq807x/base-files/lib/upgrade/platform.sh b/target/linux/qualcommax/ipq807x/base-files/lib/upgrade/platform.sh
index f78a4b04f1..92ef5fef2c 100644
--- a/target/linux/qualcommax/ipq807x/base-files/lib/upgrade/platform.sh
+++ b/target/linux/qualcommax/ipq807x/base-files/lib/upgrade/platform.sh
@@ -35,6 +35,79 @@ asus_initial_setup() {
ubirmvol /dev/ubi0 -N jffs2
}
+remove_oem_ubi_volume() {
+ local oem_volume_name="$1"
+ local oem_ubivol
+ local mtdnum
+ local ubidev
+
+ mtdnum=$(find_mtd_index "$CI_UBIPART")
+ if [ ! "$mtdnum" ]; then
+ return
+ fi
+
+ ubidev=$(nand_find_ubi "$CI_UBIPART")
+ if [ ! "$ubidev" ]; then
+ ubiattach --mtdn="$mtdnum"
+ ubidev=$(nand_find_ubi "$CI_UBIPART")
+ fi
+
+ if [ "$ubidev" ]; then
+ oem_ubivol=$(nand_find_volume "$ubidev" "$oem_volume_name")
+ [ "$oem_ubivol" ] && ubirmvol "/dev/$ubidev" --name="$oem_volume_name"
+ fi
+}
+
+tplink_get_boot_part() {
+ local cur_boot_part
+ local args
+
+ # Try to find rootfs from kernel arguments
+ read -r args < /proc/cmdline
+ for arg in $args; do
+ local ubi_mtd_arg=${arg#ubi.mtd=}
+ case "$ubi_mtd_arg" in
+ rootfs|rootfs_1)
+ echo "$ubi_mtd_arg"
+ return
+ ;;
+ esac
+ done
+
+ # Fallback to u-boot env (e.g. when running initramfs)
+ cur_boot_part="$(/usr/sbin/fw_printenv -n tp_boot_idx)"
+ case $cur_boot_part in
+ 1)
+ echo rootfs_1
+ ;;
+ 0|*)
+ echo rootfs
+ ;;
+ esac
+}
+
+tplink_do_upgrade() {
+ local new_boot_part
+
+ case $(tplink_get_boot_part) in
+ rootfs)
+ CI_UBIPART="rootfs_1"
+ new_boot_part=1
+ ;;
+ rootfs_1)
+ CI_UBIPART="rootfs"
+ new_boot_part=0
+ ;;
+ esac
+
+ fw_setenv -s - <<-EOF
+ tp_boot_idx $new_boot_part
+ EOF
+
+ remove_oem_ubi_volume ubi_rootfs
+ nand_do_upgrade "$1"
+}
+
platform_check_image() {
return 0;
}
@@ -117,6 +190,9 @@ platform_do_upgrade() {
rootfsname="rootfs"
mmc_do_upgrade "$1"
;;
+ tplink,eap660hd-v1)
+ tplink_do_upgrade "$1"
+ ;;
redmi,ax6|\
xiaomi,ax3600|\
xiaomi,ax9000)
diff --git a/target/linux/qualcommax/patches-6.6/0025-v6.7-cpufreq-qcom-nvmem-add-support-for-IPQ6018.patch b/target/linux/qualcommax/patches-6.6/0025-v6.7-cpufreq-qcom-nvmem-add-support-for-IPQ6018.patch
index 6b305cc282..95c6c9505d 100644
--- a/target/linux/qualcommax/patches-6.6/0025-v6.7-cpufreq-qcom-nvmem-add-support-for-IPQ6018.patch
+++ b/target/linux/qualcommax/patches-6.6/0025-v6.7-cpufreq-qcom-nvmem-add-support-for-IPQ6018.patch
@@ -44,7 +44,7 @@ Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
struct qcom_cpufreq_drv;
struct qcom_cpufreq_match_data {
-@@ -203,6 +205,57 @@ len_error:
+@@ -207,6 +209,57 @@ len_error:
return ret;
}
@@ -102,7 +102,7 @@ Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
static const struct qcom_cpufreq_match_data match_data_kryo = {
.get_version = qcom_cpufreq_kryo_name_version,
};
-@@ -217,6 +270,10 @@ static const struct qcom_cpufreq_match_d
+@@ -221,6 +274,10 @@ static const struct qcom_cpufreq_match_d
.genpd_names = qcs404_genpd_names,
};
@@ -113,7 +113,7 @@ Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
static int qcom_cpufreq_probe(struct platform_device *pdev)
{
struct qcom_cpufreq_drv *drv;
-@@ -359,6 +416,7 @@ static const struct of_device_id qcom_cp
+@@ -353,6 +410,7 @@ static const struct of_device_id qcom_cp
{ .compatible = "qcom,apq8096", .data = &match_data_kryo },
{ .compatible = "qcom,msm8996", .data = &match_data_kryo },
{ .compatible = "qcom,qcs404", .data = &match_data_qcs404 },
diff --git a/target/linux/qualcommax/patches-6.6/0026-v6.7-cpufreq-qcom-nvmem-add-support-for-IPQ8074.patch b/target/linux/qualcommax/patches-6.6/0026-v6.7-cpufreq-qcom-nvmem-add-support-for-IPQ8074.patch
index 8ff3b5f9b1..5640038404 100644
--- a/target/linux/qualcommax/patches-6.6/0026-v6.7-cpufreq-qcom-nvmem-add-support-for-IPQ8074.patch
+++ b/target/linux/qualcommax/patches-6.6/0026-v6.7-cpufreq-qcom-nvmem-add-support-for-IPQ8074.patch
@@ -47,7 +47,7 @@ Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
struct qcom_cpufreq_drv;
struct qcom_cpufreq_match_data {
-@@ -256,6 +261,44 @@ static int qcom_cpufreq_ipq6018_name_ver
+@@ -260,6 +265,44 @@ static int qcom_cpufreq_ipq6018_name_ver
return 0;
}
@@ -92,7 +92,7 @@ Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
static const struct qcom_cpufreq_match_data match_data_kryo = {
.get_version = qcom_cpufreq_kryo_name_version,
};
-@@ -274,6 +317,10 @@ static const struct qcom_cpufreq_match_d
+@@ -278,6 +321,10 @@ static const struct qcom_cpufreq_match_d
.get_version = qcom_cpufreq_ipq6018_name_version,
};
@@ -103,7 +103,7 @@ Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
static int qcom_cpufreq_probe(struct platform_device *pdev)
{
struct qcom_cpufreq_drv *drv;
-@@ -418,6 +465,7 @@ static const struct of_device_id qcom_cp
+@@ -412,6 +459,7 @@ static const struct of_device_id qcom_cp
{ .compatible = "qcom,qcs404", .data = &match_data_qcs404 },
{ .compatible = "qcom,ipq6018", .data = &match_data_ipq6018 },
{ .compatible = "qcom,ipq8064", .data = &match_data_krait },
diff --git a/target/linux/qualcommax/patches-6.6/0028-v6.7-arm64-dts-qcom-ipq8074-include-the-GPLL0-as-clock-pr.patch b/target/linux/qualcommax/patches-6.6/0028-v6.7-arm64-dts-qcom-ipq8074-include-the-GPLL0-as-clock-pr.patch
index 7607bdad8b..6b7dd2f261 100644
--- a/target/linux/qualcommax/patches-6.6/0028-v6.7-arm64-dts-qcom-ipq8074-include-the-GPLL0-as-clock-pr.patch
+++ b/target/linux/qualcommax/patches-6.6/0028-v6.7-arm64-dts-qcom-ipq8074-include-the-GPLL0-as-clock-pr.patch
@@ -19,7 +19,7 @@ Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
--- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
-@@ -721,8 +721,8 @@
+@@ -723,8 +723,8 @@
compatible = "qcom,ipq8074-apcs-apps-global",
"qcom,ipq6018-apcs-apps-global";
reg = <0x0b111000 0x1000>;
diff --git a/target/linux/qualcommax/patches-6.6/0052-v6.7-arm64-dts-qcom-ipq6018-include-the-GPLL0-as.patch b/target/linux/qualcommax/patches-6.6/0052-v6.7-arm64-dts-qcom-ipq6018-include-the-GPLL0-as.patch
index 3239404977..d407b9c5c4 100644
--- a/target/linux/qualcommax/patches-6.6/0052-v6.7-arm64-dts-qcom-ipq6018-include-the-GPLL0-as.patch
+++ b/target/linux/qualcommax/patches-6.6/0052-v6.7-arm64-dts-qcom-ipq6018-include-the-GPLL0-as.patch
@@ -22,7 +22,7 @@ Signed-off-by: Bjorn Andersson <andersson@kernel.org>
--- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi
-@@ -619,8 +619,8 @@
+@@ -620,8 +620,8 @@
compatible = "qcom,ipq6018-apcs-apps-global";
reg = <0x0 0x0b111000 0x0 0x1000>;
#clock-cells = <1>;
diff --git a/target/linux/qualcommax/patches-6.6/0056-v6.9-arm64-dts-qcom-Fix-hs_phy_irq-for-QUSB2-targets.patch b/target/linux/qualcommax/patches-6.6/0056-v6.9-arm64-dts-qcom-Fix-hs_phy_irq-for-QUSB2-targets.patch
index 8eb3915057..6559f3bbe9 100644
--- a/target/linux/qualcommax/patches-6.6/0056-v6.9-arm64-dts-qcom-Fix-hs_phy_irq-for-QUSB2-targets.patch
+++ b/target/linux/qualcommax/patches-6.6/0056-v6.9-arm64-dts-qcom-Fix-hs_phy_irq-for-QUSB2-targets.patch
@@ -79,7 +79,7 @@ Signed-off-by: Bjorn Andersson <andersson@kernel.org>
power-domains = <&gcc USB0_GDSC>;
resets = <&gcc GCC_USB0_BCR>;
-@@ -674,6 +681,13 @@
+@@ -675,6 +682,13 @@
<133330000>,
<19200000>;
diff --git a/target/linux/qualcommax/patches-6.6/0059-v6.9-arm64-dts-qcom-ipq6018-add-thermal-zones.patch b/target/linux/qualcommax/patches-6.6/0059-v6.9-arm64-dts-qcom-ipq6018-add-thermal-zones.patch
index b8b623c8bc..7e8c84558e 100644
--- a/target/linux/qualcommax/patches-6.6/0059-v6.9-arm64-dts-qcom-ipq6018-add-thermal-zones.patch
+++ b/target/linux/qualcommax/patches-6.6/0059-v6.9-arm64-dts-qcom-ipq6018-add-thermal-zones.patch
@@ -55,7 +55,7 @@ Signed-off-by: Bjorn Andersson <andersson@kernel.org>
};
L2_0: l2-cache {
-@@ -889,6 +894,122 @@
+@@ -890,6 +895,122 @@
};
};
diff --git a/target/linux/qualcommax/patches-6.6/0111-arm64-dts-qcom-ipq8074-use-msi-parent-for-PCIe.patch b/target/linux/qualcommax/patches-6.6/0111-arm64-dts-qcom-ipq8074-use-msi-parent-for-PCIe.patch
index dc009cd414..fdf7f84b92 100644
--- a/target/linux/qualcommax/patches-6.6/0111-arm64-dts-qcom-ipq8074-use-msi-parent-for-PCIe.patch
+++ b/target/linux/qualcommax/patches-6.6/0111-arm64-dts-qcom-ipq8074-use-msi-parent-for-PCIe.patch
@@ -12,7 +12,7 @@ Signed-off-by: Robert Marko <robimarko@gmail.com>
--- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
-@@ -755,7 +755,7 @@
+@@ -757,7 +757,7 @@
reg = <0x0b000000 0x1000>, <0x0b002000 0x1000>;
ranges = <0 0xb00a000 0xffd>;
@@ -21,7 +21,7 @@ Signed-off-by: Robert Marko <robimarko@gmail.com>
compatible = "arm,gic-v2m-frame";
msi-controller;
reg = <0x0 0xffd>;
-@@ -868,8 +868,7 @@
+@@ -870,8 +870,7 @@
ranges = <0x81000000 0x0 0x00000000 0x10200000 0x0 0x10000>, /* I/O */
<0x82000000 0x0 0x10220000 0x10220000 0x0 0xfde0000>; /* MEM */
@@ -31,7 +31,7 @@ Signed-off-by: Robert Marko <robimarko@gmail.com>
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 0x7>;
interrupt-map = <0 0 0 1 &intc 0 0 142
-@@ -930,8 +929,7 @@
+@@ -932,8 +931,7 @@
ranges = <0x81000000 0x0 0x00000000 0x20200000 0x0 0x10000>, /* I/O */
<0x82000000 0x0 0x20220000 0x20220000 0x0 0xfde0000>; /* MEM */
diff --git a/target/linux/qualcommax/patches-6.6/0120-arm64-dts-qcom-Enable-Q6v5-WCSS-for-ipq8074-SoC.patch b/target/linux/qualcommax/patches-6.6/0120-arm64-dts-qcom-Enable-Q6v5-WCSS-for-ipq8074-SoC.patch
index 2ea9bcb9fc..07f5144108 100644
--- a/target/linux/qualcommax/patches-6.6/0120-arm64-dts-qcom-Enable-Q6v5-WCSS-for-ipq8074-SoC.patch
+++ b/target/linux/qualcommax/patches-6.6/0120-arm64-dts-qcom-Enable-Q6v5-WCSS-for-ipq8074-SoC.patch
@@ -61,7 +61,7 @@ Signed-off-by: Robert Marko <robimarko@gmail.com>
spmi_bus: spmi@200f000 {
compatible = "qcom,spmi-pmic-arb";
reg = <0x0200f000 0x001000>,
-@@ -970,6 +1001,56 @@
+@@ -972,6 +1003,56 @@
"axi_s_sticky";
status = "disabled";
};
diff --git a/target/linux/qualcommax/patches-6.6/0121-arm64-dts-ipq8074-Add-WLAN-node.patch b/target/linux/qualcommax/patches-6.6/0121-arm64-dts-ipq8074-Add-WLAN-node.patch
index 627b0711b7..ef34c50eca 100644
--- a/target/linux/qualcommax/patches-6.6/0121-arm64-dts-ipq8074-Add-WLAN-node.patch
+++ b/target/linux/qualcommax/patches-6.6/0121-arm64-dts-ipq8074-Add-WLAN-node.patch
@@ -15,7 +15,7 @@ Signed-off-by: Robert Marko <robimarko@gmail.com>
--- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
-@@ -1051,6 +1051,117 @@
+@@ -1053,6 +1053,117 @@
};
};
};
diff --git a/target/linux/qualcommax/patches-6.6/0906-arm64-dts-qcom-ipq6018-add-wifi-node.patch b/target/linux/qualcommax/patches-6.6/0906-arm64-dts-qcom-ipq6018-add-wifi-node.patch
index 3e040cd2fd..f4968f1a4d 100644
--- a/target/linux/qualcommax/patches-6.6/0906-arm64-dts-qcom-ipq6018-add-wifi-node.patch
+++ b/target/linux/qualcommax/patches-6.6/0906-arm64-dts-qcom-ipq6018-add-wifi-node.patch
@@ -15,7 +15,7 @@ Signed-off-by: Mantas Pucka <mantas@8devices.com>
--- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi
-@@ -808,6 +808,102 @@
+@@ -809,6 +809,102 @@
};
};
diff --git a/target/linux/qualcommax/patches-6.6/0907-soc-qcom-fix-smp2p-ack-on-ipq6018.patch b/target/linux/qualcommax/patches-6.6/0907-soc-qcom-fix-smp2p-ack-on-ipq6018.patch
index d1bca14063..094442a59b 100644
--- a/target/linux/qualcommax/patches-6.6/0907-soc-qcom-fix-smp2p-ack-on-ipq6018.patch
+++ b/target/linux/qualcommax/patches-6.6/0907-soc-qcom-fix-smp2p-ack-on-ipq6018.patch
@@ -15,7 +15,7 @@ Signed-off-by: Mantas Pucka <mantas@8devices.com>
--- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi
-@@ -1156,6 +1156,7 @@
+@@ -1157,6 +1157,7 @@
wcss_smp2p_out: master-kernel {
qcom,entry-name = "master-kernel";
diff --git a/target/linux/qualcommax/patches-6.6/0909-arm64-dts-qcom-ipq6018-assign-QDSS_AT-clock-to-wifi-.patch b/target/linux/qualcommax/patches-6.6/0909-arm64-dts-qcom-ipq6018-assign-QDSS_AT-clock-to-wifi-.patch
index 3e0ac68f2b..a0528e7f50 100644
--- a/target/linux/qualcommax/patches-6.6/0909-arm64-dts-qcom-ipq6018-assign-QDSS_AT-clock-to-wifi-.patch
+++ b/target/linux/qualcommax/patches-6.6/0909-arm64-dts-qcom-ipq6018-assign-QDSS_AT-clock-to-wifi-.patch
@@ -13,7 +13,7 @@ Signed-off-by: Mantas Pucka <mantas@8devices.com>
--- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi
-@@ -929,8 +929,8 @@
+@@ -930,8 +930,8 @@
"wcss_reset",
"wcss_q6_reset";
diff --git a/target/linux/ramips/dts/mt7620a_iodata_wn-ac733gr3.dts b/target/linux/ramips/dts/mt7620a_iodata_wn-ac733gr3.dts
index d95a4ad99d..19b1538241 100644
--- a/target/linux/ramips/dts/mt7620a_iodata_wn-ac733gr3.dts
+++ b/target/linux/ramips/dts/mt7620a_iodata_wn-ac733gr3.dts
@@ -77,7 +77,7 @@
compatible = "realtek,rtl8367b";
gpio-sda = <&gpio0 22 GPIO_ACTIVE_HIGH>;
gpio-sck = <&gpio0 23 GPIO_ACTIVE_HIGH>;
- realtek,extif1 = <1 0 1 1 1 1 1 1 2>;
+ realtek,extif = <6 1 0 1 1 1 1 1 1 2>;
};
};
diff --git a/target/linux/ramips/dts/mt7620a_tplink_archer-c2-v1.dts b/target/linux/ramips/dts/mt7620a_tplink_archer-c2-v1.dts
index 06f3eba37b..feb619a0c0 100644
--- a/target/linux/ramips/dts/mt7620a_tplink_archer-c2-v1.dts
+++ b/target/linux/ramips/dts/mt7620a_tplink_archer-c2-v1.dts
@@ -55,7 +55,7 @@
rtl8367rb {
compatible = "realtek,rtl8367b";
- realtek,extif1 = <1 0 1 1 1 1 1 1 2>;
+ realtek,extif = <6 1 0 1 1 1 1 1 1 2>;
mii-bus = <&mdio0>;
};
};
diff --git a/target/linux/ramips/dts/mt7620a_tplink_archer-c5-v4.dts b/target/linux/ramips/dts/mt7620a_tplink_archer-c5-v4.dts
index 855e06e9f6..91b3a255c1 100644
--- a/target/linux/ramips/dts/mt7620a_tplink_archer-c5-v4.dts
+++ b/target/linux/ramips/dts/mt7620a_tplink_archer-c5-v4.dts
@@ -74,7 +74,7 @@
rtl8367s {
compatible = "realtek,rtl8367b";
- realtek,extif2 = <1 0 1 1 1 1 1 1 2>;
+ realtek,extif = <7 1 0 1 1 1 1 1 1 2>;
mii-bus = <&mdio0>;
phy-id = <29>;
};
diff --git a/target/linux/ramips/dts/mt7620a_tplink_ec220-g5-v2.dts b/target/linux/ramips/dts/mt7620a_tplink_ec220-g5-v2.dts
index 7fc075aedd..a39455cf29 100644
--- a/target/linux/ramips/dts/mt7620a_tplink_ec220-g5-v2.dts
+++ b/target/linux/ramips/dts/mt7620a_tplink_ec220-g5-v2.dts
@@ -82,7 +82,7 @@
rtl8367s {
compatible = "realtek,rtl8367b";
- realtek,extif2 = <1 0 1 1 1 1 1 1 2>;
+ realtek,extif = <7 1 0 1 1 1 1 1 1 2>;
mii-bus = <&mdio0>;
phy-id = <29>;
};
diff --git a/target/linux/ramips/dts/mt7620a_wavlink_wl-wn531g3-a2.dts b/target/linux/ramips/dts/mt7620a_wavlink_wl-wn531g3-a2.dts
new file mode 100644
index 0000000000..1a12005c92
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_wavlink_wl-wn531g3-a2.dts
@@ -0,0 +1,201 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "mt7620a.dtsi"
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+ compatible = "wavlink,wl-wn531g3", "ralink,mt7620a-soc";
+ model = "Wavlink WL-WN531G3";
+
+ aliases {
+ led-boot = &led_status_blue;
+ led-failsafe = &led_status_red;
+ led-running = &led_status_blue;
+ led-upgrade = &led_status_red;
+ };
+
+ keys {
+ compatible = "gpio-keys";
+
+ reset {
+ label = "reset";
+ gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_RESTART>;
+ };
+
+ turbo {
+ label = "turbo";
+ gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+ linux,code = <BTN_1>;
+ };
+
+ wps {
+ label = "wps";
+ gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_WPS_BUTTON>;
+ };
+
+ touchlink {
+ label = "touchlink";
+ gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
+ linux,code = <BTN_0>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led_status_blue: led_status_blue {
+ function = LED_FUNCTION_STATUS;
+ color = <LED_COLOR_ID_BLUE>;
+ gpios = <&gpio0 9 GPIO_ACTIVE_HIGH>;
+ };
+
+ led_status_red: led_status_red {
+ function = LED_FUNCTION_STATUS;
+ color = <LED_COLOR_ID_RED>;
+ gpios = <&gpio0 14 GPIO_ACTIVE_HIGH>;
+ };
+ };
+};
+
+&ehci {
+ status = "okay";
+};
+
+&ohci {
+ status = "okay";
+};
+
+&spi0 {
+ status = "okay";
+
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <50000000>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "u-boot";
+ reg = <0x0 0x30000>;
+ read-only;
+ };
+
+ partition@30000 {
+ label = "u-boot-env";
+ reg = <0x30000 0x10000>;
+ read-only;
+ };
+
+ factory: partition@40000 {
+ label = "factory";
+ reg = <0x40000 0x10000>;
+ read-only;
+
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ macaddr_factory_28: macaddr@28 {
+ reg = <0x28 0x6>;
+ };
+
+ macaddr_factory_2e: macaddr@2e {
+ reg = <0x2e 0x6>;
+ };
+
+ eeprom_radio_0: eeprom@0 {
+ reg = <0x0 0x200>;
+ };
+
+ eeprom_radio_8000: eeprom@8000 {
+ reg = <0x8000 0x200>;
+ };
+ };
+ };
+
+ partition@50000 {
+ compatible = "denx,uimage";
+ label = "firmware";
+ reg = <0x50000 0x7b0000>;
+ };
+ };
+ };
+};
+
+&ethernet {
+ pinctrl-names = "default";
+ pinctrl-0 = <&rgmii1_pins>, <&rgmii2_pins>, <&mdio_pins>;
+
+ nvmem-cells = <&macaddr_factory_28>;
+ nvmem-cell-names = "mac-address";
+
+ mediatek,portmap = "llllw";
+
+ port@4 {
+ status = "okay";
+ phy-handle = <&phy4>;
+ phy-mode = "rgmii";
+
+ nvmem-cells = <&macaddr_factory_2e>;
+ nvmem-cell-names = "mac-address";
+ };
+
+ port@5 {
+ status = "okay";
+ phy-handle = <&phy5>;
+ phy-mode = "rgmii";
+ };
+
+ mdio-bus {
+ status = "okay";
+
+ phy4: ethernet-phy@4 {
+ reg = <4>;
+ phy-mode = "rgmii";
+ };
+
+ phy5: ethernet-phy@5 {
+ reg = <5>;
+ phy-mode = "rgmii";
+ };
+ };
+};
+
+&pcie {
+ status = "okay";
+};
+
+&pcie0 {
+ mt76@0,0 {
+ compatible = "mediatek,mt76";
+ reg = <0x0000 0 0 0 0>;
+ nvmem-cells = <&eeprom_radio_8000>;
+ nvmem-cell-names = "eeprom";
+ ieee80211-freq-limit = <5000000 6000000>;
+ };
+};
+
+&gsw {
+ mediatek,port4-gmac;
+};
+
+&wmac {
+ nvmem-cells = <&eeprom_radio_0>;
+ nvmem-cell-names = "eeprom";
+};
+
+&state_default {
+ gpio {
+ groups = "i2c", "uartf";
+ function = "gpio";
+ };
+};
diff --git a/target/linux/ramips/dts/mt7620a_zyxel_keenetic-viva.dts b/target/linux/ramips/dts/mt7620a_zyxel_keenetic-viva.dts
index 0630e8a160..9921db770a 100644
--- a/target/linux/ramips/dts/mt7620a_zyxel_keenetic-viva.dts
+++ b/target/linux/ramips/dts/mt7620a_zyxel_keenetic-viva.dts
@@ -6,7 +6,7 @@
/ {
compatible = "zyxel,keenetic-viva", "ralink,mt7620a-soc";
- model = "ZyXEL Keenetic Viva";
+ model = "Zyxel Keenetic Viva";
aliases {
led-boot = &led_power_green;
@@ -85,7 +85,7 @@
rtl8367rb {
compatible = "realtek,rtl8367b";
- realtek,extif2 = <1 0 1 1 1 1 1 1 2>;
+ realtek,extif = <7 1 0 1 1 1 1 1 1 2>;
mii-bus = <&mdio0>;
};
};
diff --git a/target/linux/ramips/dts/mt7620n_zyxel_keenetic-lite-iii-a.dts b/target/linux/ramips/dts/mt7620n_zyxel_keenetic-lite-iii-a.dts
index 899479781e..eb3e8aac54 100644
--- a/target/linux/ramips/dts/mt7620n_zyxel_keenetic-lite-iii-a.dts
+++ b/target/linux/ramips/dts/mt7620n_zyxel_keenetic-lite-iii-a.dts
@@ -8,7 +8,7 @@
/ {
compatible = "zyxel,keenetic-lite-iii-a", "ralink,mt7620n-soc";
- model = "ZyXEL Keenetic Lite III (rev. A)";
+ model = "Zyxel Keenetic Lite III (rev. A)";
aliases {
led-boot = &led_wan;
diff --git a/target/linux/ramips/dts/mt7620n_zyxel_keenetic-omni-ii.dts b/target/linux/ramips/dts/mt7620n_zyxel_keenetic-omni-ii.dts
index dd1d256f41..ff4667f458 100644
--- a/target/linux/ramips/dts/mt7620n_zyxel_keenetic-omni-ii.dts
+++ b/target/linux/ramips/dts/mt7620n_zyxel_keenetic-omni-ii.dts
@@ -6,7 +6,7 @@
/ {
compatible = "zyxel,keenetic-omni-ii", "ralink,mt7620n-soc";
- model = "ZyXEL Keenetic Omni II";
+ model = "Zyxel Keenetic Omni II";
aliases {
led-boot = &led_power;
diff --git a/target/linux/ramips/dts/mt7620n_zyxel_keenetic-omni.dts b/target/linux/ramips/dts/mt7620n_zyxel_keenetic-omni.dts
index 0ba185b7eb..b5722d2427 100644
--- a/target/linux/ramips/dts/mt7620n_zyxel_keenetic-omni.dts
+++ b/target/linux/ramips/dts/mt7620n_zyxel_keenetic-omni.dts
@@ -6,7 +6,7 @@
/ {
compatible = "zyxel,keenetic-omni", "ralink,mt7620n-soc";
- model = "ZyXEL Keenetic Omni";
+ model = "Zyxel Keenetic Omni";
aliases {
led-boot = &led_power;
diff --git a/target/linux/ramips/dts/mt7621_keenetic_kn-3510.dts b/target/linux/ramips/dts/mt7621_keenetic_kn-3510.dts
new file mode 100644
index 0000000000..5a647d75e8
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_keenetic_kn-3510.dts
@@ -0,0 +1,247 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+ compatible = "keenetic,kn-3510", "mediatek,mt7621-soc";
+ model = "Keenetic KN-3510";
+
+ aliases {
+ led-boot = &led_status_green;
+ led-failsafe = &led_status_green;
+ led-running = &led_status_green;
+ led-upgrade = &led_status_green;
+ label-mac-device = &gmac0;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led-0 {
+ function = LED_FUNCTION_WPS;
+ color = <LED_COLOR_ID_AMBER>;
+ gpios = <&gpio 16 GPIO_ACTIVE_LOW>;
+ };
+
+ led_status_green: led-1 {
+ function = LED_FUNCTION_STATUS;
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&gpio 17 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ keys {
+ compatible = "gpio-keys";
+
+ reset {
+ label = "reset";
+ gpios = <&gpio 6 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_RESTART>;
+ };
+
+ wps {
+ label = "wps";
+ gpios = <&gpio 7 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_WPS_BUTTON>;
+ };
+
+ fn1 {
+ label = "fn1";
+ gpios = <&gpio 8 GPIO_ACTIVE_LOW>;
+ linux,code = <BTN_0>;
+ };
+ };
+
+ virtual_flash {
+ compatible = "mtd-concat";
+ devices = <&firmware1 &storage1 &firmware2 &storage2>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "kernel";
+ reg = <0x0 0x400000>;
+ };
+
+ partition@400000 {
+ label = "ubi";
+ reg = <0x400000 0x0>;
+ };
+ };
+ };
+};
+
+&state_default {
+ gpio {
+ groups = "uart3", "jtag";
+ function = "gpio";
+ };
+};
+
+&nand {
+ status = "okay";
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "u-boot";
+ reg = <0x0 0x80000>;
+ read-only;
+ };
+
+ partition@80000 {
+ label = "u-config";
+ reg = <0x80000 0x80000>;
+ read-only;
+ };
+
+ partition@100000 {
+ label = "rf-eeprom";
+ reg = <0x100000 0x80000>;
+ read-only;
+
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ eeprom_factory_0: eeprom@0 {
+ reg = <0x0 0xe00>;
+ };
+
+ macaddr_factory_4: macaddr@4 {
+ reg = <0x4 0x6>;
+ };
+
+ macaddr_factory_a: macaddr@a {
+ reg = <0xa 0x6>;
+ };
+
+ precal_factory_e10: precal@e10 {
+ reg = <0xe10 0x19c10>;
+ };
+ };
+ };
+
+ firmware1: partition@180000 {
+ label = "firmware_1";
+ reg = <0x180000 0x1a40000>;
+ };
+
+ partition@1bc0000 {
+ label = "config_1";
+ reg = <0x1bc0000 0x20000>;
+ read-only;
+ };
+
+ partition@1dc0000 {
+ label = "storage_legacy";
+ reg = <0x1dc0000 0x20000>;
+ read-only;
+ };
+
+ partition@1fc0000 {
+ label = "dump";
+ reg = <0x1fc0000 0x40000>;
+ read-only;
+ };
+
+ storage1: partition@2000000 {
+ label = "storage_a";
+ reg = <0x2000000 0x1fc0000>;
+ };
+
+ partition@3fc0000 {
+ label = "u-state";
+ reg = <0x3fc0000 0x80000>;
+ read-only;
+ };
+
+ partition@4040000 {
+ label = "u-config_res";
+ reg = <0x4040000 0x80000>;
+ read-only;
+ };
+
+ partition@40c0000 {
+ label = "rf-eeprom_res";
+ reg = <0x40c0000 0x80000>;
+ read-only;
+ };
+
+ firmware2: partition@4140000 {
+ label = "firmware_2";
+ reg = <0x4140000 0x1a40000>;
+ };
+
+ partition@5b80000 {
+ label = "config_2";
+ reg = <0x5d00000 0x20000>;
+ read-only;
+ };
+
+ storage2: partition@5d80000 {
+ label = "storage_b";
+ reg = <0x5d80000 0x2200000>;
+ };
+ };
+};
+
+&ethphy0 {
+ /delete-property/ interrupts;
+};
+
+&gmac0 {
+ nvmem-cells = <&macaddr_factory_4>;
+ nvmem-cell-names = "mac-address";
+};
+
+&gmac1 {
+ status = "okay";
+ label = "wan";
+ phy-handle = <&ethphy0>;
+
+ nvmem-cells = <&macaddr_factory_a>;
+ nvmem-cell-names = "mac-address";
+};
+
+&switch0 {
+ ports {
+ port@3 {
+ status = "okay";
+ label = "lan";
+ };
+ };
+};
+
+&pcie {
+ status = "okay";
+};
+
+&pcie1 {
+ wifi@0,0 {
+ compatible = "mediatek,mt76";
+ reg = <0x0000 0 0 0 0>;
+ nvmem-cells = <&eeprom_factory_0>, <&precal_factory_e10>;
+ nvmem-cell-names = "eeprom", "precal";
+ mediatek,disable-radar-background;
+ };
+};
+
+&xhci {
+ status = "disabled";
+};
diff --git a/target/linux/ramips/dts/mt7621_mtc_wr1201.dts b/target/linux/ramips/dts/mt7621_mtc_wr1201.dts
index 31f3eb8657..24303ec5b3 100644
--- a/target/linux/ramips/dts/mt7621_mtc_wr1201.dts
+++ b/target/linux/ramips/dts/mt7621_mtc_wr1201.dts
@@ -166,8 +166,18 @@
status = "okay";
};
+&pcie_pins {
+ uart3 {
+ groups = "uart3";
+ function = "gpio";
+ };
+};
+
&pcie {
status = "okay";
+
+ reset-gpios = <&gpio 8 GPIO_ACTIVE_LOW>,
+ <&gpio 19 GPIO_ACTIVE_LOW>;
};
&pcie0 {
diff --git a/target/linux/ramips/dts/mt7621_netgear_wax214v2.dts b/target/linux/ramips/dts/mt7621_netgear_wax214v2.dts
new file mode 100644
index 0000000000..a9597119fa
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_netgear_wax214v2.dts
@@ -0,0 +1,228 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+ compatible = "netgear,wax214v2", "mediatek,mt7621-soc";
+ model = "Netgear WAX214v2";
+
+ aliases {
+ led-boot = &led_power_green;
+ led-failsafe = &led_power_amber;
+ led-running = &led_power_green;
+ led-upgrade = &led_power_blue;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200";
+ };
+
+ keys {
+ compatible = "gpio-keys";
+
+ reset {
+ label = "reset";
+ gpios = <&gpio 10 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_RESTART>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led_power_green: power_green {
+ function = LED_FUNCTION_POWER;
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&gpio 15 GPIO_ACTIVE_LOW>;
+ };
+
+ led_power_blue: power_blue {
+ function = LED_FUNCTION_POWER;
+ color = <LED_COLOR_ID_BLUE>;
+ gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
+ };
+
+ led_power_amber: power_amber {
+ function = LED_FUNCTION_POWER;
+ color = <LED_COLOR_ID_AMBER>;
+ gpios = <&gpio 13 GPIO_ACTIVE_LOW>;
+ };
+
+ wifin_green {
+ function = LED_FUNCTION_WLAN_2GHZ;
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&gpio 12 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "phy0radio";
+ };
+
+ wifia_green {
+ function = LED_FUNCTION_WLAN_5GHZ;
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&gpio 8 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "phy1radio";
+ };
+ };
+};
+
+&nand {
+ status = "okay";
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "Bootloader";
+ reg = <0x0 0x80000>;
+ read-only;
+ };
+
+ partition@80000 {
+ label = "Config";
+ reg = <0x80000 0x80000>;
+ };
+
+ partition@100000 {
+ label = "Factory";
+ reg = <0x100000 0x80000>;
+ read-only;
+
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ eeprom_factory_0: eeprom@0 {
+ reg = <0x0 0xe00>;
+ };
+
+ precal_factory_e10: precal@e10 {
+ reg = <0xe10 0x19c10>;
+ };
+ };
+ };
+
+ partition@180000 {
+ label = "firmware";
+ reg = <0x180000 0x2600000>;
+
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "kernel";
+ reg = <0x0 0x400000>;
+ };
+
+ partition@400000 {
+ label = "ubi";
+ reg = <0x400000 0x2200000>;
+ };
+ };
+
+ partition@2780000 {
+ label = "firmware_backup";
+ reg = <0x2780000 0x2600000>;
+ read-only;
+ };
+
+ partition@4d80000 {
+ label = "CFG";
+ reg = <0x4d80000 0x800000>;
+ read-only;
+ };
+
+ partition@5580000 {
+ label = "RAE";
+ reg = <0x5580000 0x400000>;
+ read-only;
+ };
+
+ partition@5980000 {
+ label = "POT";
+ reg = <0x5980000 0x100000>;
+ read-only;
+ };
+
+ partition@5a80000 {
+ label = "Language";
+ reg = <0x5a80000 0x400000>;
+ read-only;
+ };
+
+ partition@5e80000 {
+ label = "Traffic";
+ reg = <0x5e80000 0x200000>;
+ read-only;
+ };
+
+ partition@6080000 {
+ label = "Cert";
+ reg = <0x6080000 0x100000>;
+ read-only;
+ };
+
+ partition@6180000 {
+ label = "NTGRcryptK";
+ reg = <0x6180000 0x100000>;
+ read-only;
+ };
+
+ partition@6280000 {
+ label = "NTGRcryptD";
+ reg = <0x6280000 0x500000>;
+ read-only;
+ };
+
+ partition@6780000 {
+ label = "LOG";
+ reg = <0x6780000 0x100000>;
+ read-only;
+ };
+
+ partition@6880000 {
+ label = "User_data";
+ reg = <0x6880000 0x640000>;
+ read-only;
+ };
+ };
+};
+
+&pcie {
+ status = "okay";
+};
+
+&pcie1 {
+ wifi@0,0 {
+ compatible = "mediatek,mt76";
+ reg = <0x0000 0 0 0 0>;
+ nvmem-cells = <&eeprom_factory_0>, <&precal_factory_e10>;
+ nvmem-cell-names = "eeprom", "precal";
+ };
+};
+
+&state_default {
+ gpio {
+ groups = "uart3", "uart2", "jtag";
+ function = "gpio";
+ };
+};
+
+&switch0 {
+ ports {
+ port@0 {
+ status = "okay";
+ label = "lan";
+ };
+ };
+};
+
+&xhci {
+ status = "disabled";
+};
diff --git a/target/linux/ramips/dts/mt7621_wodesys_wd-r1802u.dts b/target/linux/ramips/dts/mt7621_wodesys_wd-r1802u.dts
new file mode 100644
index 0000000000..f16d27e8d7
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_wodesys_wd-r1802u.dts
@@ -0,0 +1,153 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+ compatible = "wodesys,wd-r1802u", "mediatek,mt7621-soc";
+ model = "Wodesys WD-R1802U";
+
+ aliases {
+ label-mac-device = &gmac0;
+ led-boot = &led_blue;
+ led-failsafe = &led_red;
+ led-running = &led_green;
+ led-upgrade = &led_blue;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200";
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ key-0 {
+ label = "reset";
+ gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_RESTART>;
+ };
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+
+ led_green: led-0 {
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_STATUS;
+ gpios = <&gpio 13 GPIO_ACTIVE_LOW>;
+ };
+
+ led_blue: led-1 {
+ color = <LED_COLOR_ID_BLUE>;
+ function = LED_FUNCTION_STATUS;
+ gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
+ };
+
+ led_red: led-2 {
+ color = <LED_COLOR_ID_RED>;
+ function = LED_FUNCTION_STATUS;
+ gpios = <&gpio 17 GPIO_ACTIVE_LOW>;
+ panic-indicator;
+ };
+ };
+};
+
+&gmac0 {
+ nvmem-cells = <&macaddr_factory_4 1>;
+ nvmem-cell-names = "mac-address";
+};
+
+&pcie {
+ status = "okay";
+};
+
+&pcie1 {
+ wifi@0,0 {
+ compatible = "mediatek,mt76";
+ reg = <0x0000 0 0 0 0>;
+ nvmem-cells = <&eeprom_factory_0>, <&precal_factory_e10>;
+ nvmem-cell-names = "eeprom", "precal";
+ mediatek,disable-radar-background;
+ };
+};
+
+&spi0 {
+ status = "okay";
+
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <50000000>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "u-boot";
+ reg = <0x00000 0x30000>;
+ read-only;
+ };
+
+ /* 0x30000-0x4ffff are unused
+ (flash contents is 0xff) */
+
+ partition@50000 {
+ label = "factory";
+ reg = <0x50000 0x40000>;
+ read-only;
+
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ eeprom_factory_0: eeprom@0 {
+ reg = <0x0 0xe00>;
+ };
+
+ macaddr_factory_4: macaddr@4 { // wifi 2.4
+ compatible = "mac-base";
+ reg = <0x4 0x6>;
+ #nvmem-cell-cells = <1>;
+ };
+
+ precal_factory_e10: precal@e10 {
+ reg = <0xe10 0x19c10>;
+ };
+ };
+ };
+
+ partition@90000 {
+ compatible = "denx,uimage";
+ label = "firmware";
+ reg = <0x90000 0xf70000>;
+ };
+ };
+ };
+};
+
+&state_default {
+ gpio {
+ groups = "jtag", "wdt";
+ function = "gpio";
+ };
+};
+
+&switch0 {
+ ports {
+ port@4 {
+ status = "okay";
+ label = "lan";
+ };
+ };
+};
+
+&xhci {
+ status = "disabled";
+};
diff --git a/target/linux/ramips/dts/mt7621_zbtlink_zbt-we1326.dts b/target/linux/ramips/dts/mt7621_zbtlink_zbt-we1326.dts
index 7dfe9a7699..2b54faae9e 100644
--- a/target/linux/ramips/dts/mt7621_zbtlink_zbt-we1326.dts
+++ b/target/linux/ramips/dts/mt7621_zbtlink_zbt-we1326.dts
@@ -1,7 +1,6 @@
-#include "mt7621.dtsi"
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-#include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/input/input.h>
+#include "mt7621_zbtlink_zbt-wexx26.dtsi"
/ {
compatible = "zbtlink,zbt-we1326", "mediatek,mt7621-soc";
@@ -10,167 +9,4 @@
aliases {
label-mac-device = &wifi1;
};
-
- chosen {
- bootargs = "console=ttyS0,115200";
- };
-
- keys {
- compatible = "gpio-keys";
-
- reset {
- label = "reset";
- gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
- linux,code = <KEY_RESTART>;
- };
- };
-};
-
-&state_default {
- gpio {
- groups = "wdt";
- function = "gpio";
- };
-};
-
-&spi0 {
- status = "okay";
-
- flash@0 {
- compatible = "jedec,spi-nor";
- reg = <0>;
- spi-max-frequency = <10000000>;
-
- partitions {
- compatible = "fixed-partitions";
- #address-cells = <1>;
- #size-cells = <1>;
-
- partition@0 {
- label = "u-boot";
- reg = <0x0 0x30000>;
- read-only;
- };
-
- partition@30000 {
- label = "u-boot-env";
- reg = <0x30000 0x10000>;
- read-only;
- };
-
- partition@40000 {
- label = "factory";
- reg = <0x40000 0x10000>;
- read-only;
-
- nvmem-layout {
- compatible = "fixed-layout";
- #address-cells = <1>;
- #size-cells = <1>;
-
- eeprom_factory_0: eeprom@0 {
- reg = <0x0 0x400>;
- };
-
- eeprom_factory_8000: eeprom@8000 {
- reg = <0x8000 0x200>;
- };
-
- macaddr_factory_e000: macaddr@e000 {
- reg = <0xe000 0x6>;
- };
-
- macaddr_factory_e006: macaddr@e006 {
- reg = <0xe006 0x6>;
- };
- };
- };
-
- partition@50000 {
- compatible = "denx,uimage";
- label = "firmware";
- reg = <0x50000 0xfb0000>;
- };
- };
- };
-};
-
-&gmac0 {
- nvmem-cells = <&macaddr_factory_e000>;
- nvmem-cell-names = "mac-address";
-};
-
-&gmac1 {
- status = "okay";
- label = "wan";
- phy-handle = <&ethphy4>;
-
- nvmem-cells = <&macaddr_factory_e006>;
- nvmem-cell-names = "mac-address";
-};
-
-&ethphy4 {
- /delete-property/ interrupts;
-};
-
-&switch0 {
- ports {
- port@0 {
- status = "okay";
- label = "lan1";
- };
-
- port@1 {
- status = "okay";
- label = "lan2";
- };
-
- port@2 {
- status = "okay";
- label = "lan3";
- };
-
- port@3 {
- status = "okay";
- label = "lan4";
- };
- };
-};
-
-&pcie {
- status = "okay";
-};
-
-&pcie1 {
- wifi@0,0 {
- compatible = "mediatek,mt76";
- reg = <0x0000 0 0 0 0>;
- nvmem-cells = <&eeprom_factory_8000>;
- nvmem-cell-names = "eeprom";
- ieee80211-freq-limit = <5000000 6000000>;
-
- led {
- led-sources = <2>;
- led-active-low;
- };
- };
-};
-
-&pcie2 {
- wifi1: wifi@0,0 {
- compatible = "mediatek,mt76";
- reg = <0x0000 0 0 0 0>;
- nvmem-cells = <&eeprom_factory_0>;
- nvmem-cell-names = "eeprom";
- ieee80211-freq-limit = <2400000 2500000>;
-
- led {
- led-sources = <0>;
- led-active-low;
- };
- };
-};
-
-&sdhci {
- status = "okay";
};
diff --git a/target/linux/ramips/dts/mt7621_zbtlink_zbt-we3526.dts b/target/linux/ramips/dts/mt7621_zbtlink_zbt-we3526.dts
index 31a4e4482a..4f40f2926c 100644
--- a/target/linux/ramips/dts/mt7621_zbtlink_zbt-we3526.dts
+++ b/target/linux/ramips/dts/mt7621_zbtlink_zbt-we3526.dts
@@ -1,169 +1,8 @@
-#include "mt7621.dtsi"
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-#include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/input/input.h>
+#include "mt7621_zbtlink_zbt-wexx26.dtsi"
/ {
compatible = "zbtlink,zbt-we3526", "mediatek,mt7621-soc";
model = "Zbtlink ZBT-WE3526";
-
- chosen {
- bootargs = "console=ttyS0,115200";
- };
-
- keys {
- compatible = "gpio-keys";
-
- reset {
- label = "reset";
- gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
- linux,code = <KEY_RESTART>;
- };
- };
-};
-
-&i2c {
- status = "okay";
-};
-
-&sdhci {
- status = "okay";
-};
-
-&spi0 {
- status = "okay";
-
- flash@0 {
- compatible = "jedec,spi-nor";
- reg = <0>;
- spi-max-frequency = <10000000>;
-
- partitions {
- compatible = "fixed-partitions";
- #address-cells = <1>;
- #size-cells = <1>;
-
- partition@0 {
- label = "u-boot";
- reg = <0x0 0x30000>;
- read-only;
- };
-
- partition@30000 {
- label = "u-boot-env";
- reg = <0x30000 0x10000>;
- read-only;
- };
-
- partition@40000 {
- label = "factory";
- reg = <0x40000 0x10000>;
- read-only;
-
- nvmem-layout {
- compatible = "fixed-layout";
- #address-cells = <1>;
- #size-cells = <1>;
-
- eeprom_factory_0: eeprom@0 {
- reg = <0x0 0x400>;
- };
-
- eeprom_factory_8000: eeprom@8000 {
- reg = <0x8000 0x200>;
- };
-
- macaddr_factory_e000: macaddr@e000 {
- reg = <0xe000 0x6>;
- };
-
- macaddr_factory_e006: macaddr@e006 {
- reg = <0xe006 0x6>;
- };
- };
- };
-
- partition@50000 {
- compatible = "denx,uimage";
- label = "firmware";
- reg = <0x50000 0xfb0000>;
- };
- };
- };
-};
-
-&pcie {
- status = "okay";
-};
-
-&pcie0 {
- wifi@0,0 {
- compatible = "pci14c3,7662";
- reg = <0x0000 0 0 0 0>;
- nvmem-cells = <&eeprom_factory_8000>;
- nvmem-cell-names = "eeprom";
- ieee80211-freq-limit = <5000000 6000000>;
-
- led {
- led-sources = <2>;
- };
- };
-};
-
-&pcie1 {
- wifi@0,0 {
- compatible = "pci14c3,7603";
- reg = <0x0000 0 0 0 0>;
- nvmem-cells = <&eeprom_factory_0>;
- nvmem-cell-names = "eeprom";
- };
-};
-
-&gmac0 {
- nvmem-cells = <&macaddr_factory_e000>;
- nvmem-cell-names = "mac-address";
-};
-
-&gmac1 {
- status = "okay";
- label = "wan";
- phy-handle = <&ethphy4>;
-
- nvmem-cells = <&macaddr_factory_e006>;
- nvmem-cell-names = "mac-address";
-};
-
-&ethphy4 {
- /delete-property/ interrupts;
-};
-
-&switch0 {
- ports {
- port@0 {
- status = "okay";
- label = "lan1";
- };
-
- port@1 {
- status = "okay";
- label = "lan2";
- };
-
- port@2 {
- status = "okay";
- label = "lan3";
- };
-
- port@3 {
- status = "okay";
- label = "lan4";
- };
- };
-};
-
-&state_default {
- gpio {
- groups = "wdt";
- function = "gpio";
- };
};
diff --git a/target/linux/ramips/dts/mt7621_zbtlink_zbt-wexx26.dtsi b/target/linux/ramips/dts/mt7621_zbtlink_zbt-wexx26.dtsi
new file mode 100644
index 0000000000..e1428b7148
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_zbtlink_zbt-wexx26.dtsi
@@ -0,0 +1,171 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+ chosen {
+ bootargs = "console=ttyS0,115200";
+ };
+
+ keys {
+ compatible = "gpio-keys";
+
+ reset {
+ label = "reset";
+ gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_RESTART>;
+ };
+ };
+};
+
+&ethphy4 {
+ /delete-property/ interrupts;
+};
+
+&gmac0 {
+ nvmem-cells = <&macaddr_factory_e000>;
+ nvmem-cell-names = "mac-address";
+};
+
+&gmac1 {
+ status = "okay";
+ label = "wan";
+ phy-handle = <&ethphy4>;
+
+ nvmem-cells = <&macaddr_factory_e006>;
+ nvmem-cell-names = "mac-address";
+};
+
+&pcie {
+ status = "okay";
+};
+
+&pcie1 {
+ wifi@0,0 {
+ compatible = "mediatek,mt76";
+ reg = <0x0000 0 0 0 0>;
+ nvmem-cells = <&eeprom_factory_8000>;
+ nvmem-cell-names = "eeprom";
+ ieee80211-freq-limit = <5000000 6000000>;
+
+ led {
+ led-sources = <2>;
+ led-active-low;
+ };
+ };
+};
+
+&pcie2 {
+ wifi1: wifi@0,0 {
+ compatible = "mediatek,mt76";
+ reg = <0x0000 0 0 0 0>;
+ nvmem-cells = <&eeprom_factory_0>;
+ nvmem-cell-names = "eeprom";
+ ieee80211-freq-limit = <2400000 2500000>;
+
+ led {
+ led-sources = <0>;
+ led-active-low;
+ };
+ };
+};
+
+&sdhci {
+ status = "okay";
+};
+
+&spi0 {
+ status = "okay";
+
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <10000000>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "u-boot";
+ reg = <0x0 0x30000>;
+ read-only;
+ };
+
+ partition@30000 {
+ label = "u-boot-env";
+ reg = <0x30000 0x10000>;
+ read-only;
+ };
+
+ partition@40000 {
+ label = "factory";
+ reg = <0x40000 0x10000>;
+ read-only;
+
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ eeprom_factory_0: eeprom@0 {
+ reg = <0x0 0x400>;
+ };
+
+ eeprom_factory_8000: eeprom@8000 {
+ reg = <0x8000 0x200>;
+ };
+
+ macaddr_factory_e000: macaddr@e000 {
+ reg = <0xe000 0x6>;
+ };
+
+ macaddr_factory_e006: macaddr@e006 {
+ reg = <0xe006 0x6>;
+ };
+ };
+ };
+
+ partition@50000 {
+ compatible = "denx,uimage";
+ label = "firmware";
+ reg = <0x50000 0xfb0000>;
+ };
+ };
+ };
+};
+
+&state_default {
+ gpio {
+ groups = "wdt";
+ function = "gpio";
+ };
+};
+
+&switch0 {
+ ports {
+ port@0 {
+ status = "okay";
+ label = "lan1";
+ };
+
+ port@1 {
+ status = "okay";
+ label = "lan2";
+ };
+
+ port@2 {
+ status = "okay";
+ label = "lan3";
+ };
+
+ port@3 {
+ status = "okay";
+ label = "lan4";
+ };
+ };
+};
diff --git a/target/linux/ramips/dts/mt7621_zyxel_lte3301-plus.dts b/target/linux/ramips/dts/mt7621_zyxel_lte3301-plus.dts
index edc861db61..9eed123157 100644
--- a/target/linux/ramips/dts/mt7621_zyxel_lte3301-plus.dts
+++ b/target/linux/ramips/dts/mt7621_zyxel_lte3301-plus.dts
@@ -7,7 +7,7 @@
/ {
compatible = "zyxel,lte3301-plus", "mediatek,mt7621-soc";
- model = "ZyXEL LTE3301-Plus";
+ model = "Zyxel LTE3301-Plus";
aliases {
label-mac-device = &gmac0;
diff --git a/target/linux/ramips/dts/mt7621_zyxel_lte5398-m904.dts b/target/linux/ramips/dts/mt7621_zyxel_lte5398-m904.dts
index ca8adfe10e..e121077b0a 100644
--- a/target/linux/ramips/dts/mt7621_zyxel_lte5398-m904.dts
+++ b/target/linux/ramips/dts/mt7621_zyxel_lte5398-m904.dts
@@ -8,7 +8,7 @@
/ {
compatible = "zyxel,lte5398-m904", "mediatek,mt7621-soc";
- model = "ZyXEL LTE5398-M904";
+ model = "Zyxel LTE5398-M904";
aliases {
label-mac-device = &gmac0;
diff --git a/target/linux/ramips/dts/mt7621_zyxel_nr7101.dts b/target/linux/ramips/dts/mt7621_zyxel_nr7101.dts
index 756d4bd6e6..070ea4a13f 100644
--- a/target/linux/ramips/dts/mt7621_zyxel_nr7101.dts
+++ b/target/linux/ramips/dts/mt7621_zyxel_nr7101.dts
@@ -7,7 +7,7 @@
/ {
compatible = "zyxel,nr7101", "mediatek,mt7621-soc";
- model = "ZyXEL NR7101";
+ model = "Zyxel NR7101";
aliases {
led-boot = &led_system_green;
diff --git a/target/linux/ramips/dts/mt7621_zyxel_nwa50ax.dts b/target/linux/ramips/dts/mt7621_zyxel_nwa50ax.dts
index 2cdaa40a1c..1ae3b9ad63 100644
--- a/target/linux/ramips/dts/mt7621_zyxel_nwa50ax.dts
+++ b/target/linux/ramips/dts/mt7621_zyxel_nwa50ax.dts
@@ -5,7 +5,7 @@
/ {
compatible = "zyxel,nwa50ax", "mediatek,mt7621-soc";
- model = "ZyXEL NWA50AX";
+ model = "Zyxel NWA50AX";
aliases {
led-boot = &led_system_green;
diff --git a/target/linux/ramips/dts/mt7621_zyxel_nwa55axe.dts b/target/linux/ramips/dts/mt7621_zyxel_nwa55axe.dts
index 7f0a6d2cdf..0dc4943cb4 100644
--- a/target/linux/ramips/dts/mt7621_zyxel_nwa55axe.dts
+++ b/target/linux/ramips/dts/mt7621_zyxel_nwa55axe.dts
@@ -2,5 +2,5 @@
/ {
compatible = "zyxel,nwa55axe", "mediatek,mt7621-soc";
- model = "ZyXEL NWA55AXE";
+ model = "Zyxel NWA55AXE";
};
diff --git a/target/linux/ramips/dts/mt7621_zyxel_wap6805.dts b/target/linux/ramips/dts/mt7621_zyxel_wap6805.dts
index eabfcc2ef0..b3e8f6db74 100644
--- a/target/linux/ramips/dts/mt7621_zyxel_wap6805.dts
+++ b/target/linux/ramips/dts/mt7621_zyxel_wap6805.dts
@@ -8,7 +8,7 @@
/ {
compatible = "zyxel,wap6805", "mediatek,mt7621-soc";
- model = "ZyXEL WAP6805";
+ model = "Zyxel WAP6805";
aliases {
led-boot = &led_status_green;
diff --git a/target/linux/ramips/dts/mt7621_zyxel_wsm20.dts b/target/linux/ramips/dts/mt7621_zyxel_wsm20.dts
index 6bf65a0218..42dc716027 100644
--- a/target/linux/ramips/dts/mt7621_zyxel_wsm20.dts
+++ b/target/linux/ramips/dts/mt7621_zyxel_wsm20.dts
@@ -7,7 +7,7 @@
/ {
compatible = "zyxel,wsm20", "mediatek,mt7621-soc";
- model = "ZyXEL WSM20";
+ model = "Zyxel WSM20";
aliases {
led-boot = &led_system_white;
diff --git a/target/linux/ramips/dts/mt7628an_xiaomi_mi-router-4a-100m-intl-v2.dts b/target/linux/ramips/dts/mt7628an_xiaomi_mi-router-4a-100m-intl-v2.dts
new file mode 100644
index 0000000000..b12901bd5b
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_xiaomi_mi-router-4a-100m-intl-v2.dts
@@ -0,0 +1,94 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include <dt-bindings/leds/common.h>
+
+#include "mt7628an_xiaomi_mi-router-4.dtsi"
+
+/ {
+ compatible = "xiaomi,mi-router-4a-100m-intl-v2", "mediatek,mt7628an-soc";
+ model = "Xiaomi Mi Router 4A (100M International Edition V2)";
+
+ aliases {
+ led-boot = &led_power_yellow;
+ led-failsafe = &led_power_yellow;
+ led-running = &led_power_blue;
+ led-upgrade = &led_power_yellow;
+ label-mac-device = &ethernet;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led_power_blue: power_blue {
+ color = <LED_COLOR_ID_BLUE>;
+ function = LED_FUNCTION_POWER;
+ gpios = <&gpio 11 GPIO_ACTIVE_LOW>;
+ };
+
+ led_power_yellow: power_yellow {
+ color = <LED_COLOR_ID_YELLOW>;
+ function = LED_FUNCTION_POWER;
+ gpios = <&gpio 44 GPIO_ACTIVE_LOW>;
+ };
+
+ wan {
+ color = <LED_COLOR_ID_BLUE>;
+ function = LED_FUNCTION_WAN;
+ gpios = <&gpio 37 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+};
+
+&partitions {
+ partition@60000 {
+ label = "overlay";
+ reg = <0x60000 0x100000>;
+ read-only;
+ };
+
+ partition@160000 {
+ label = "firmware";
+ reg = <0x160000 0xea0000>;
+ compatible = "denx,uimage";
+ };
+};
+
+&pcie {
+ status = "okay";
+};
+
+&eeprom_factory_8000 {
+ /* MT7613 has different eeprom size '0x4da8' */
+ /* See https://github.com/openwrt/openwrt/pull/13587 */
+ /* You can also see this in mt76/mt7615/eeprom.h: */
+ /* MT7615_EEPROM_FULL_SIZE = MT7615_EEPROM_TXDPD_OFFSET + \ */
+ /* MT7615_EEPROM_TXDPD_COUNT * MT7615_EEPROM_TXDPD_SIZE */
+ /* where MT7615_EEPROM_TXDPD_OFFSET is 1024 + 256 * 34 = 9728: */
+ /* MT7615_EEPROM_SIZE(1024 defined in mt7615.h) + \ */
+ /* MT7615_EEPROM_DCOC_COUNT(34) * MT7615_EEPROM_DCOC_SIZE(256)*/
+ /* where MT7615_EEPROM_TXDPD_COUNT = 44 + 3 = 47 */
+ /* and MT7615_EEPROM_TXDPD_SIZE = 216. */
+ /* Altogether it will be 19880 or 0x4da8. */
+ reg = <0x8000 0x4da8>;
+};
+
+&pcie0 {
+ wifi@0,0 {
+ compatible = "mediatek,mt76";
+ reg = <0x0000 0 0 0 0>;
+ nvmem-cells = <&eeprom_factory_8000>;
+ nvmem-cell-names = "eeprom";
+ ieee80211-freq-limit = <5000000 6000000>;
+ };
+};
+
+&ethernet {
+ nvmem-cells = <&macaddr_factory_4 (-1)>;
+ nvmem-cell-names = "mac-address";
+};
+
+&esw {
+ mediatek,portmap = <0x3e>;
+ mediatek,portdisable = <0x2a>;
+};
diff --git a/target/linux/ramips/dts/mt7628an_yuncore_cpe200.dts b/target/linux/ramips/dts/mt7628an_yuncore_cpe200.dts
new file mode 100644
index 0000000000..6e6202f02b
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_yuncore_cpe200.dts
@@ -0,0 +1,165 @@
+#include "mt7628an.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+ compatible = "yuncore,cpe200", "mediatek,mt7628an-soc";
+ model = "Yuncore CPE200";
+
+ chosen {
+ bootargs = "console=ttyS0,57600";
+ };
+
+ aliases {
+ label-mac = &ethernet;
+ led-boot = &led_power;
+ led-failsafe = &led_power;
+ led-running = &led_power;
+ led-upgrade = &led_power;
+ };
+
+ keys {
+ compatible = "gpio-keys";
+
+ reset {
+ label = "reset";
+ gpios = <&gpio 38 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_RESTART>;
+ };
+
+ mode {
+ label = "mode";
+ linux,input-type = <EV_SW>;
+ linux,code = <BTN_0>;
+ gpios = <&gpio 0 GPIO_ACTIVE_LOW>;
+ debounce-interval = <60>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led_power: power {
+ function = LED_FUNCTION_POWER;
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&gpio 11 GPIO_ACTIVE_LOW>;
+ };
+
+ lan {
+ function = LED_FUNCTION_LAN;
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&gpio 43 GPIO_ACTIVE_LOW>;
+ };
+
+ wan {
+ function = LED_FUNCTION_WAN;
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&gpio 39 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ watchdog {
+ compatible = "linux,wdt-gpio";
+ gpios = <&gpio 37 GPIO_ACTIVE_HIGH>;
+ hw_algo = "toggle";
+ hw_margin_ms = <20000>;
+ always-running;
+ };
+};
+
+&spi0 {
+ status = "okay";
+
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <10000000>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "u-boot";
+ reg = <0x0 0x30000>;
+ read-only;
+ };
+
+ partition@30000 {
+ label = "u-boot-env";
+ reg = <0x30000 0x10000>;
+ read-only;
+ };
+
+ partition@40000 {
+ label = "factory";
+ reg = <0x40000 0x10000>;
+ read-only;
+
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ macaddr_factory_4: macaddr@4 {
+ reg = <0x4 0x6>;
+ };
+
+ eeprom_factory_8000: eeprom@8000 {
+ reg = <0x8000 0x600>;
+ };
+
+ macaddr_factory_8004: macaddr@8004 {
+ reg = <0x8004 0x6>;
+ };
+ };
+ };
+
+ partition@50000 {
+ compatible = "denx,uimage";
+ label = "firmware";
+ reg = <0x50000 0x7b0000>;
+ };
+ };
+ };
+};
+
+&ethernet {
+ nvmem-cells = <&macaddr_factory_4>;
+ nvmem-cell-names = "mac-address";
+};
+
+&esw {
+ mediatek,portmap = <0x2f>;
+};
+
+&pcie {
+ status = "okay";
+};
+
+&pcie0 {
+ mt76@0,0 {
+ reg = <0x0000 0 0 0 0>;
+ ieee80211-freq-limit = <5000000 6000000>;
+ nvmem-cells = <&eeprom_factory_8000>, <&macaddr_factory_8004>;
+ nvmem-cell-names = "eeprom", "mac-address";
+
+ led {
+ led-sources = <0>;
+ led-active-low;
+ };
+ };
+};
+
+&state_default {
+ gpio {
+ groups = "pwm0", "i2c", "refclk", "wdt", "i2s", "spi cs1",
+ "spis", "gpio", "p0led_an", "p1led_an", "p2led_an",
+ "p3led_an", "p4led_an", "wled_kn", "p0led_kn",
+ "p1led_kn", "p2led_kn", "p3led_kn", "p4led_kn", "wled_an";
+ function = "gpio";
+ };
+};
diff --git a/target/linux/ramips/dts/mt7628an_yuncore_m300.dts b/target/linux/ramips/dts/mt7628an_yuncore_m300.dts
new file mode 100644
index 0000000000..8897c11d67
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_yuncore_m300.dts
@@ -0,0 +1,148 @@
+#include "mt7628an.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+ compatible = "yuncore,m300", "mediatek,mt7628an-soc";
+ model = "Yuncore M300";
+
+ chosen {
+ bootargs = "console=ttyS0,57600";
+ };
+
+ keys {
+ compatible = "gpio-keys";
+
+ reset {
+ label = "reset";
+ gpios = <&gpio 38 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_RESTART>;
+ };
+ };
+
+ aliases {
+ label-mac = &ethernet;
+ led-boot = &led_indicator;
+ led-failsafe = &led_indicator;
+ led-running = &led_indicator;
+ led-upgrade = &led_indicator;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led_indicator: indicator {
+ function = LED_FUNCTION_INDICATOR;
+ color = <LED_COLOR_ID_RED>;
+ gpios = <&gpio 11 GPIO_ACTIVE_LOW>;
+ };
+
+ lan {
+ function = LED_FUNCTION_LAN;
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&gpio 40 GPIO_ACTIVE_LOW>;
+ };
+
+ wan {
+ function = LED_FUNCTION_WAN;
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&gpio 39 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ watchdog {
+ compatible = "linux,wdt-gpio";
+ gpios = <&gpio 37 GPIO_ACTIVE_HIGH>;
+ hw_algo = "toggle";
+ hw_margin_ms = <20000>;
+ always-running;
+ };
+};
+
+&spi0 {
+ status = "okay";
+
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <10000000>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "u-boot";
+ reg = <0x0 0x30000>;
+ read-only;
+ };
+
+ partition@30000 {
+ label = "u-boot-env";
+ reg = <0x30000 0x10000>;
+ read-only;
+ };
+
+ partition@40000 {
+ label = "factory";
+ reg = <0x40000 0x10000>;
+ read-only;
+
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ eeprom_factory_0: eeprom@0 {
+ reg = <0x0 0x400>;
+ };
+
+ macaddr_factory_4: macaddr@4 {
+ reg = <0x4 0x6>;
+ };
+ };
+ };
+
+ partition@50000 {
+ compatible = "denx,uimage";
+ label = "firmware";
+ reg = <0x50000 0x7b0000>;
+ };
+ };
+ };
+};
+
+&ethernet {
+ nvmem-cells = <&macaddr_factory_4>;
+ nvmem-cell-names = "mac-address";
+};
+
+&esw {
+ mediatek,portmap = <0x3e>;
+};
+
+&wmac {
+ status = "okay";
+
+ nvmem-cells = <&eeprom_factory_0>;
+ nvmem-cell-names = "eeprom";
+};
+
+&state_default {
+ gpio {
+ groups = "pwm1", "pwm0", "uart2", "uart1", "i2c", "refclk",
+ "perst", "wdt", "sdmode", "i2s", "spi cs1", "spis",
+ "gpio", "p0led_an", "p1led_an", "p2led_an", "p3led_an",
+ "p4led_an", "wled_kn", "p0led_kn", "p1led_kn",
+ "p2led_kn", "p3led_kn", "p4led_kn";
+ function = "gpio";
+ };
+
+ wlan {
+ groups = "wled_an";
+ function = "wled_an";
+ };
+};
diff --git a/target/linux/ramips/dts/mt7628an_zyxel_keenetic-extra-ii.dts b/target/linux/ramips/dts/mt7628an_zyxel_keenetic-extra-ii.dts
index 70956724fb..3e59fc6bf4 100644
--- a/target/linux/ramips/dts/mt7628an_zyxel_keenetic-extra-ii.dts
+++ b/target/linux/ramips/dts/mt7628an_zyxel_keenetic-extra-ii.dts
@@ -6,7 +6,7 @@
/ {
compatible = "zyxel,keenetic-extra-ii", "mediatek,mt7628an-soc";
- model = "ZyXEL Keenetic Extra II";
+ model = "Zyxel Keenetic Extra II";
aliases {
led-boot = &led_power;
diff --git a/target/linux/ramips/dts/rt3052_zyxel_keenetic.dts b/target/linux/ramips/dts/rt3052_zyxel_keenetic.dts
index e7db3eda15..c7285150d9 100644
--- a/target/linux/ramips/dts/rt3052_zyxel_keenetic.dts
+++ b/target/linux/ramips/dts/rt3052_zyxel_keenetic.dts
@@ -6,7 +6,7 @@
/ {
compatible = "zyxel,keenetic", "ralink,rt3052-soc";
- model = "ZyXEL Keenetic";
+ model = "Zyxel Keenetic";
aliases {
led-boot = &led_power;
diff --git a/target/linux/ramips/dts/rt3052_zyxel_nbg-419n.dts b/target/linux/ramips/dts/rt3052_zyxel_nbg-419n.dts
index 8dee38c1f8..fc6cd21f3c 100644
--- a/target/linux/ramips/dts/rt3052_zyxel_nbg-419n.dts
+++ b/target/linux/ramips/dts/rt3052_zyxel_nbg-419n.dts
@@ -6,7 +6,7 @@
/ {
compatible = "zyxel,nbg-419n", "ralink,rt3052-soc";
- model = "ZyXEL NBG-419N";
+ model = "Zyxel NBG-419N";
aliases {
led-boot = &led_power;
diff --git a/target/linux/ramips/dts/rt3352_zyxel_nbg-419n-v2.dts b/target/linux/ramips/dts/rt3352_zyxel_nbg-419n-v2.dts
index f00fd58b71..ce776d4603 100644
--- a/target/linux/ramips/dts/rt3352_zyxel_nbg-419n-v2.dts
+++ b/target/linux/ramips/dts/rt3352_zyxel_nbg-419n-v2.dts
@@ -6,7 +6,7 @@
/ {
compatible = "zyxel,nbg-419n-v2", "ralink,rt3352-soc";
- model = "ZyXEL NBG-419N v2";
+ model = "Zyxel NBG-419N v2";
aliases {
led-boot = &led_power;
diff --git a/target/linux/ramips/dts/rt3662_asus_rt-n56u.dts b/target/linux/ramips/dts/rt3662_asus_rt-n56u.dts
index 391076cee9..c381aa3e03 100644
--- a/target/linux/ramips/dts/rt3662_asus_rt-n56u.dts
+++ b/target/linux/ramips/dts/rt3662_asus_rt-n56u.dts
@@ -73,7 +73,7 @@
compatible = "realtek,rtl8367";
gpio-sda = <&gpio0 1 GPIO_ACTIVE_HIGH>;
gpio-sck = <&gpio0 2 GPIO_ACTIVE_HIGH>;
- realtek,extif1 = <1 0 1 1 1 1 1 1 2>;
+ realtek,extif = <8 1 0 1 1 1 1 1 1 2>;
};
keys {
diff --git a/target/linux/ramips/dts/rt3662_dlink_dir-645.dts b/target/linux/ramips/dts/rt3662_dlink_dir-645.dts
index 3d6479f44f..8cfa48e195 100644
--- a/target/linux/ramips/dts/rt3662_dlink_dir-645.dts
+++ b/target/linux/ramips/dts/rt3662_dlink_dir-645.dts
@@ -19,7 +19,7 @@
compatible = "realtek,rtl8367b";
gpio-sda = <&gpio0 1 GPIO_ACTIVE_HIGH>;
gpio-sck = <&gpio0 2 GPIO_ACTIVE_HIGH>;
- realtek,extif1 = <1 0 1 1 1 1 1 1 2>;
+ realtek,extif = <6 1 0 1 1 1 1 1 1 2>;
};
keys {
diff --git a/target/linux/ramips/dts/rt3662_edimax_br-6475nd.dts b/target/linux/ramips/dts/rt3662_edimax_br-6475nd.dts
index 051e28da8f..fbc795b24f 100644
--- a/target/linux/ramips/dts/rt3662_edimax_br-6475nd.dts
+++ b/target/linux/ramips/dts/rt3662_edimax_br-6475nd.dts
@@ -127,7 +127,7 @@
compatible = "realtek,rtl8367";
gpio-sda = <&gpio0 5 GPIO_ACTIVE_HIGH>;
gpio-sck = <&gpio0 4 GPIO_ACTIVE_HIGH>;
- realtek,extif0 = <1 0 1 1 1 1 1 1 2>;
+ realtek,extif = <9 1 0 1 1 1 1 1 1 2>;
};
/*
diff --git a/target/linux/ramips/dts/rt3662_samsung_cy-swr1100.dts b/target/linux/ramips/dts/rt3662_samsung_cy-swr1100.dts
index 9964fcf600..bcc215c17a 100644
--- a/target/linux/ramips/dts/rt3662_samsung_cy-swr1100.dts
+++ b/target/linux/ramips/dts/rt3662_samsung_cy-swr1100.dts
@@ -81,7 +81,7 @@
compatible = "realtek,rtl8367";
gpio-sda = <&gpio0 1 GPIO_ACTIVE_HIGH>;
gpio-sck = <&gpio0 2 GPIO_ACTIVE_HIGH>;
- realtek,extif0 = <1 0 1 1 1 1 1 1 2>;
+ realtek,extif = <9 1 0 1 1 1 1 1 1 2>;
};
keys {
diff --git a/target/linux/ramips/dts/rt3883_belkin_f9k110x.dtsi b/target/linux/ramips/dts/rt3883_belkin_f9k110x.dtsi
index a2d1906b89..4d60bb3c05 100644
--- a/target/linux/ramips/dts/rt3883_belkin_f9k110x.dtsi
+++ b/target/linux/ramips/dts/rt3883_belkin_f9k110x.dtsi
@@ -12,7 +12,7 @@
compatible = "realtek,rtl8367b";
gpio-sda = <&gpio0 1 GPIO_ACTIVE_HIGH>;
gpio-sck = <&gpio0 2 GPIO_ACTIVE_HIGH>;
- realtek,extif1 = <1 0 1 1 1 1 1 1 2>;
+ realtek,extif = <5 1 0 1 1 1 1 1 1 2>;
};
};
diff --git a/target/linux/ramips/dts/rt5350_zyxel_keenetic-4g-b.dts b/target/linux/ramips/dts/rt5350_zyxel_keenetic-4g-b.dts
index d37e4189a8..511d97a336 100644
--- a/target/linux/ramips/dts/rt5350_zyxel_keenetic-4g-b.dts
+++ b/target/linux/ramips/dts/rt5350_zyxel_keenetic-4g-b.dts
@@ -8,7 +8,7 @@
/ {
compatible = "zyxel,keenetic-4g-b", "ralink,rt5350-soc";
- model = "ZyXEL Keenetic 4G Rev.B";
+ model = "Zyxel Keenetic 4G Rev.B";
aliases {
led-boot = &led_power;
diff --git a/target/linux/ramips/dts/rt5350_zyxel_keenetic-lite-b.dts b/target/linux/ramips/dts/rt5350_zyxel_keenetic-lite-b.dts
index 658a71066a..433701397a 100644
--- a/target/linux/ramips/dts/rt5350_zyxel_keenetic-lite-b.dts
+++ b/target/linux/ramips/dts/rt5350_zyxel_keenetic-lite-b.dts
@@ -8,7 +8,7 @@
/ {
compatible = "zyxel,keenetic-lite-b", "ralink,rt5350-soc";
- model = "ZyXEL Keenetic Lite Rev.B";
+ model = "Zyxel Keenetic Lite Rev.B";
aliases {
led-boot = &led_power;
diff --git a/target/linux/ramips/dts/rt5350_zyxel_keenetic-start.dts b/target/linux/ramips/dts/rt5350_zyxel_keenetic-start.dts
index 663b9a3d8c..459350fade 100644
--- a/target/linux/ramips/dts/rt5350_zyxel_keenetic-start.dts
+++ b/target/linux/ramips/dts/rt5350_zyxel_keenetic-start.dts
@@ -8,7 +8,7 @@
/ {
compatible = "zyxel,keenetic-start", "ralink,rt5350-soc";
- model = "ZyXEL Keenetic Start";
+ model = "Zyxel Keenetic Start";
aliases {
led-boot = &led_power;
diff --git a/target/linux/ramips/files/drivers/mtd/nand/raw/mt7621_nand.c b/target/linux/ramips/files/drivers/mtd/nand/raw/mt7621_nand.c
index 89cc7e2624..fba389e5a9 100644
--- a/target/linux/ramips/files/drivers/mtd/nand/raw/mt7621_nand.c
+++ b/target/linux/ramips/files/drivers/mtd/nand/raw/mt7621_nand.c
@@ -1248,7 +1248,6 @@ static int mt7621_nfc_init_chip(struct mt7621_nfc *nfc)
nand->ecc.write_oob_raw = mt7621_nfc_write_oob_raw;
mtd = nand_to_mtd(nand);
- mtd->owner = THIS_MODULE;
mtd->dev.parent = nfc->dev;
mtd->name = MT7621_NFC_NAME;
mtd_set_ooblayout(mtd, &mt7621_nfc_ooblayout_ops);
@@ -1290,44 +1289,28 @@ static int mt7621_nfc_probe(struct platform_device *pdev)
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nfi");
nfc->nfi_base = res->start;
nfc->nfi_regs = devm_ioremap_resource(dev, res);
- if (IS_ERR(nfc->nfi_regs)) {
- ret = PTR_ERR(nfc->nfi_regs);
- return ret;
- }
+ if (IS_ERR(nfc->nfi_regs))
+ return PTR_ERR(nfc->nfi_regs);
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ecc");
nfc->ecc_regs = devm_ioremap_resource(dev, res);
- if (IS_ERR(nfc->ecc_regs)) {
- ret = PTR_ERR(nfc->ecc_regs);
- return ret;
- }
+ if (IS_ERR(nfc->ecc_regs))
+ return PTR_ERR(nfc->ecc_regs);
- nfc->nfi_clk = devm_clk_get(dev, "nfi_clk");
- if (IS_ERR(nfc->nfi_clk)) {
+ nfc->nfi_clk = devm_clk_get_optional_enabled(dev, "nfi_clk");
+ if (IS_ERR(nfc->nfi_clk))
+ return PTR_ERR(nfc->nfi_clk);
+
+ if (!nfc->nfi_clk)
dev_warn(dev, "nfi clk not provided\n");
- nfc->nfi_clk = NULL;
- } else {
- ret = clk_prepare_enable(nfc->nfi_clk);
- if (ret) {
- dev_err(dev, "Failed to enable nfi core clock\n");
- return ret;
- }
- }
platform_set_drvdata(pdev, nfc);
ret = mt7621_nfc_init_chip(nfc);
- if (ret) {
- dev_err(dev, "Failed to initialize nand chip\n");
- goto clk_disable;
- }
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to initialize nand chip\n");
return 0;
-
-clk_disable:
- clk_disable_unprepare(nfc->nfi_clk);
-
- return ret;
}
static int mt7621_nfc_remove(struct platform_device *pdev)
@@ -1339,7 +1322,6 @@ static int mt7621_nfc_remove(struct platform_device *pdev)
mtk_bmt_detach(mtd);
mtd_device_unregister(mtd);
nand_cleanup(nand);
- clk_disable_unprepare(nfc->nfi_clk);
return 0;
}
@@ -1355,7 +1337,6 @@ static struct platform_driver mt7621_nfc_driver = {
.remove = mt7621_nfc_remove,
.driver = {
.name = MT7621_NFC_NAME,
- .owner = THIS_MODULE,
.of_match_table = mt7621_nfc_id_table,
},
};
diff --git a/target/linux/ramips/files/drivers/net/ethernet/ralink/gsw_mt7620.c b/target/linux/ramips/files/drivers/net/ethernet/ralink/gsw_mt7620.c
index dcaff04db1..5853df70c5 100644
--- a/target/linux/ramips/files/drivers/net/ethernet/ralink/gsw_mt7620.c
+++ b/target/linux/ramips/files/drivers/net/ethernet/ralink/gsw_mt7620.c
@@ -245,7 +245,7 @@ int mtk_gsw_init(struct fe_priv *priv)
mt7620_ephy_init(gsw);
if (gsw->irq) {
- ret = request_irq(gsw->irq, gsw_interrupt_mt7620, 0,
+ ret = devm_request_irq(&pdev->dev, gsw->irq, gsw_interrupt_mt7620, 0,
"gsw", priv);
if (ret) {
dev_err(&pdev->dev, "Failed to request irq");
diff --git a/target/linux/ramips/files/drivers/net/ethernet/ralink/mtk_eth_soc.c b/target/linux/ramips/files/drivers/net/ethernet/ralink/mtk_eth_soc.c
index c8afa4e3bb..e261d90924 100644
--- a/target/linux/ramips/files/drivers/net/ethernet/ralink/mtk_eth_soc.c
+++ b/target/linux/ramips/files/drivers/net/ethernet/ralink/mtk_eth_soc.c
@@ -1414,7 +1414,6 @@ static void fe_uninit(struct net_device *dev)
fe_mdio_cleanup(priv);
fe_reg_w32(0, FE_REG_FE_INT_ENABLE);
- free_irq(dev->irq, dev);
}
static int fe_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
@@ -1480,7 +1479,7 @@ static const struct net_device_ops fe_netdev_ops = {
.ndo_start_xmit = fe_start_xmit,
.ndo_set_mac_address = fe_set_mac_address,
.ndo_validate_addr = eth_validate_addr,
- .ndo_do_ioctl = fe_do_ioctl,
+ .ndo_eth_ioctl = fe_do_ioctl,
.ndo_change_mtu = fe_change_mtu,
.ndo_tx_timeout = fe_tx_timeout,
.ndo_get_stats64 = fe_get_stats64,
diff --git a/target/linux/ramips/files/drivers/pinctrl/pinctrl-aw9523.c b/target/linux/ramips/files/drivers/pinctrl/pinctrl-aw9523.c
deleted file mode 100644
index 8b642e28b1..0000000000
--- a/target/linux/ramips/files/drivers/pinctrl/pinctrl-aw9523.c
+++ /dev/null
@@ -1,1128 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Awinic AW9523B i2c pin controller driver
- * Copyright (c) 2020, AngeloGioacchino Del Regno
- * <angelogioacchino.delregno@somainline.org>
- */
-
-#include <linux/bitfield.h>
-#include <linux/regmap.h>
-#include <linux/i2c.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/mutex.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/of.h>
-#include <linux/of_device.h>
-#include <linux/gpio/consumer.h>
-#include <linux/gpio/driver.h>
-#include <linux/pinctrl/pinconf.h>
-#include <linux/pinctrl/pinctrl.h>
-#include <linux/pinctrl/pinmux.h>
-#include <linux/pinctrl/pinconf-generic.h>
-#include <linux/regulator/consumer.h>
-
-#include "core.h"
-#include "pinconf.h"
-#include "pinctrl-utils.h"
-
-#define AW9523_MAX_FUNCS 2
-#define AW9523_NUM_PORTS 2
-#define AW9523_PINS_PER_PORT 8
-
-/*
- * HW needs at least 20uS for reset and at least 1-2uS to recover from
- * reset, but we have to account for eventual board quirks, if any:
- * for this reason, keep reset asserted for 50uS and wait for 20uS
- * to recover from the reset.
- */
-#define AW9523_HW_RESET_US 50
-#define AW9523_HW_RESET_RECOVERY_US 20
-
-/* Port 0: P0_0...P0_7 - Port 1: P1_0...P1_7 */
-#define AW9523_PIN_TO_PORT(pin) (pin >> 3)
-#define AW9523_REG_IN_STATE(pin) (0x00 + AW9523_PIN_TO_PORT(pin))
-#define AW9523_REG_OUT_STATE(pin) (0x02 + AW9523_PIN_TO_PORT(pin))
-#define AW9523_REG_CONF_STATE(pin) (0x04 + AW9523_PIN_TO_PORT(pin))
-#define AW9523_REG_INTR_DIS(pin) (0x06 + AW9523_PIN_TO_PORT(pin))
-#define AW9523_REG_CHIPID 0x10
-#define AW9523_VAL_EXPECTED_CHIPID 0x23
-
-#define AW9523_REG_GCR 0x11
-#define AW9523_GCR_ISEL_MASK GENMASK(0, 1)
-#define AW9523_GCR_GPOMD_MASK BIT(4)
-
-#define AW9523_REG_PORT_MODE(pin) (0x12 + AW9523_PIN_TO_PORT(pin))
-#define AW9523_REG_SOFT_RESET 0x7f
-#define AW9523_VAL_RESET 0x00
-
-/*
- * struct aw9523_irq - Interrupt controller structure
- * @lock: mutex locking for the irq bus
- * @irqchip: structure holding irqchip params
- * @cached_gpio: stores the previous gpio status for bit comparison
- */
-struct aw9523_irq {
- struct mutex lock;
- struct irq_chip *irqchip;
- u16 cached_gpio;
-};
-
-/*
- * struct aw9523_pinmux - Pin mux params
- * @name: Name of the mux
- * @grps: Groups of the mux
- * @num_grps: Number of groups (sizeof array grps)
- */
-struct aw9523_pinmux {
- const char *name;
- const char * const *grps;
- const u8 num_grps;
-};
-
-/*
- * struct aw9523 - Main driver structure
- * @dev: device handle
- * @regmap: regmap handle for current device
- * @i2c_lock: Mutex lock for i2c operations
- * @reset_gpio: Hardware reset (RSTN) signal GPIO
- * @vio_vreg: VCC regulator (Optional)
- * @pctl: pinctrl handle for current device
- * @gpio: structure holding gpiochip params
- * @irq: Interrupt controller structure
- */
-struct aw9523 {
- struct device *dev;
- struct regmap *regmap;
- struct mutex i2c_lock;
- struct gpio_desc *reset_gpio;
- struct regulator *vio_vreg;
- struct pinctrl_dev *pctl;
- struct gpio_chip gpio;
- struct aw9523_irq *irq;
-};
-
-static const struct pinctrl_pin_desc aw9523_pins[] = {
- /* Port 0 */
- PINCTRL_PIN(0, "gpio0"),
- PINCTRL_PIN(1, "gpio1"),
- PINCTRL_PIN(2, "gpio2"),
- PINCTRL_PIN(3, "gpio3"),
- PINCTRL_PIN(4, "gpio4"),
- PINCTRL_PIN(5, "gpio5"),
- PINCTRL_PIN(6, "gpio6"),
- PINCTRL_PIN(7, "gpio7"),
-
- /* Port 1 */
- PINCTRL_PIN(8, "gpio8"),
- PINCTRL_PIN(9, "gpio9"),
- PINCTRL_PIN(10, "gpio10"),
- PINCTRL_PIN(11, "gpio11"),
- PINCTRL_PIN(12, "gpio12"),
- PINCTRL_PIN(13, "gpio13"),
- PINCTRL_PIN(14, "gpio14"),
- PINCTRL_PIN(15, "gpio15"),
-};
-
-static int aw9523_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
-{
- return ARRAY_SIZE(aw9523_pins);
-}
-
-static const char *aw9523_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
- unsigned int selector)
-{
- return aw9523_pins[selector].name;
-}
-
-static int aw9523_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
- unsigned int selector,
- const unsigned int **pins,
- unsigned int *num_pins)
-{
- *pins = &aw9523_pins[selector].number;
- *num_pins = 1;
- return 0;
-}
-
-static const struct pinctrl_ops aw9523_pinctrl_ops = {
- .get_groups_count = aw9523_pinctrl_get_groups_count,
- .get_group_pins = aw9523_pinctrl_get_group_pins,
- .get_group_name = aw9523_pinctrl_get_group_name,
- .dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
- .dt_free_map = pinconf_generic_dt_free_map,
-};
-
-static const char * const gpio_pwm_groups[] = {
- "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5",
- "gpio6", "gpio7", "gpio8", "gpio9", "gpio10", "gpio11",
- "gpio12", "gpio13", "gpio14", "gpio15"
-};
-
-/* Warning: Do NOT reorder this array */
-static const struct aw9523_pinmux aw9523_pmx[] = {
- {
- .name = "pwm",
- .grps = gpio_pwm_groups,
- .num_grps = ARRAY_SIZE(gpio_pwm_groups),
- },
- {
- .name = "gpio",
- .grps = gpio_pwm_groups,
- .num_grps = ARRAY_SIZE(gpio_pwm_groups),
- },
-};
-
-static int aw9523_pmx_get_funcs_count(struct pinctrl_dev *pctl)
-{
- return ARRAY_SIZE(aw9523_pmx);
-}
-
-static const char *aw9523_pmx_get_fname(struct pinctrl_dev *pctl,
- unsigned int sel)
-{
- return aw9523_pmx[sel].name;
-}
-
-static int aw9523_pmx_get_groups(struct pinctrl_dev *pctl, unsigned int sel,
- const char * const **groups,
- unsigned int * const num_groups)
-{
- *groups = aw9523_pmx[sel].grps;
- *num_groups = aw9523_pmx[sel].num_grps;
- return 0;
-}
-
-static int aw9523_pmx_set_mux(struct pinctrl_dev *pctl, unsigned int fsel,
- unsigned int grp)
-{
- struct aw9523 *awi = pinctrl_dev_get_drvdata(pctl);
- int ret, pin = aw9523_pins[grp].number % AW9523_PINS_PER_PORT;
-
- if (fsel >= ARRAY_SIZE(aw9523_pmx))
- return -EINVAL;
-
- /*
- * This maps directly to the aw9523_pmx array: programming a
- * high bit means "gpio" and a low bit means "pwm".
- */
- mutex_lock(&awi->i2c_lock);
- ret = regmap_update_bits(awi->regmap, AW9523_REG_PORT_MODE(pin),
- BIT(pin), (fsel ? BIT(pin) : 0));
- mutex_unlock(&awi->i2c_lock);
- return ret;
-}
-
-static const struct pinmux_ops aw9523_pinmux_ops = {
- .get_functions_count = aw9523_pmx_get_funcs_count,
- .get_function_name = aw9523_pmx_get_fname,
- .get_function_groups = aw9523_pmx_get_groups,
- .set_mux = aw9523_pmx_set_mux,
-};
-
-static int aw9523_pcfg_param_to_reg(enum pin_config_param pcp, int pin, u8 *r)
-{
- u8 reg;
-
- switch (pcp) {
- case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
- case PIN_CONFIG_BIAS_PULL_DOWN:
- case PIN_CONFIG_BIAS_PULL_UP:
- reg = AW9523_REG_IN_STATE(pin);
- break;
- case PIN_CONFIG_DRIVE_OPEN_DRAIN:
- case PIN_CONFIG_DRIVE_PUSH_PULL:
- reg = AW9523_REG_GCR;
- break;
- case PIN_CONFIG_INPUT_ENABLE:
- case PIN_CONFIG_OUTPUT_ENABLE:
- reg = AW9523_REG_CONF_STATE(pin);
- break;
- case PIN_CONFIG_OUTPUT:
- reg = AW9523_REG_OUT_STATE(pin);
- break;
- default:
- return -ENOTSUPP;
- }
- *r = reg;
-
- return 0;
-}
-
-static int aw9523_pconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
- unsigned long *config)
-{
- struct aw9523 *awi = pinctrl_dev_get_drvdata(pctldev);
- enum pin_config_param param = pinconf_to_config_param(*config);
- int regbit = pin % AW9523_PINS_PER_PORT;
- unsigned int val;
- u8 reg;
- int rc;
-
- rc = aw9523_pcfg_param_to_reg(param, pin, &reg);
- if (rc)
- return rc;
-
- mutex_lock(&awi->i2c_lock);
- rc = regmap_read(awi->regmap, reg, &val);
- mutex_unlock(&awi->i2c_lock);
- if (rc)
- return rc;
-
- switch (param) {
- case PIN_CONFIG_BIAS_PULL_UP:
- case PIN_CONFIG_INPUT_ENABLE:
- case PIN_CONFIG_OUTPUT:
- val &= BIT(regbit);
- break;
- case PIN_CONFIG_BIAS_PULL_DOWN:
- case PIN_CONFIG_OUTPUT_ENABLE:
- val &= BIT(regbit);
- val = !val;
- break;
- case PIN_CONFIG_DRIVE_OPEN_DRAIN:
- if (pin >= AW9523_PINS_PER_PORT)
- val = 0;
- else
- val = !FIELD_GET(AW9523_GCR_GPOMD_MASK, val);
- break;
- case PIN_CONFIG_DRIVE_PUSH_PULL:
- if (pin >= AW9523_PINS_PER_PORT)
- val = 1;
- else
- val = FIELD_GET(AW9523_GCR_GPOMD_MASK, val);
- break;
- default:
- return -ENOTSUPP;
- }
- if (val < 1)
- return -EINVAL;
-
- *config = pinconf_to_config_packed(param, !!val);
-
- return rc;
-}
-
-static int aw9523_pconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
- unsigned long *configs, unsigned int num_configs)
-{
- struct aw9523 *awi = pinctrl_dev_get_drvdata(pctldev);
- enum pin_config_param param;
- int regbit = pin % AW9523_PINS_PER_PORT;
- u32 arg;
- u8 reg;
- unsigned int mask, val;
- int i, rc;
-
- mutex_lock(&awi->i2c_lock);
- for (i = 0; i < num_configs; i++) {
- param = pinconf_to_config_param(configs[i]);
- arg = pinconf_to_config_argument(configs[i]);
-
- rc = aw9523_pcfg_param_to_reg(param, pin, &reg);
- if (rc)
- goto end;
-
- switch (param) {
- case PIN_CONFIG_OUTPUT:
- /* First, enable pin output */
- rc = regmap_update_bits(awi->regmap,
- AW9523_REG_CONF_STATE(pin),
- BIT(regbit), 0);
- if (rc)
- goto end;
-
- /* Then, fall through to config output level */
- fallthrough;
- case PIN_CONFIG_OUTPUT_ENABLE:
- arg = !arg;
- fallthrough;
- case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
- case PIN_CONFIG_BIAS_PULL_DOWN:
- case PIN_CONFIG_BIAS_PULL_UP:
- case PIN_CONFIG_INPUT_ENABLE:
- mask = BIT(regbit);
- val = arg ? BIT(regbit) : 0;
- break;
- case PIN_CONFIG_DRIVE_OPEN_DRAIN:
- /* Open-Drain is supported only on port 0 */
- if (pin >= AW9523_PINS_PER_PORT) {
- rc = -ENOTSUPP;
- goto end;
- }
- mask = AW9523_GCR_GPOMD_MASK;
- val = 0;
- break;
- case PIN_CONFIG_DRIVE_PUSH_PULL:
- /* Port 1 is always Push-Pull */
- if (pin >= AW9523_PINS_PER_PORT) {
- mask = 0;
- val = 0;
- continue;
- }
- mask = AW9523_GCR_GPOMD_MASK;
- val = AW9523_GCR_GPOMD_MASK;
- break;
- default:
- rc = -ENOTSUPP;
- goto end;
- }
-
- rc = regmap_update_bits(awi->regmap, reg, mask, val);
- if (rc)
- goto end;
- }
-end:
- mutex_unlock(&awi->i2c_lock);
- return rc;
-}
-
-static const struct pinconf_ops aw9523_pinconf_ops = {
- .pin_config_get = aw9523_pconf_get,
- .pin_config_set = aw9523_pconf_set,
- .is_generic = true,
-};
-
-/*
- * aw9523_get_pin_direction - Get pin direction
- * @regmap: Regmap structure
- * @pin: gpiolib pin number
- * @n: pin index in port register
- *
- * Return: Pin direction for success or negative number for error
- */
-static int aw9523_get_pin_direction(struct regmap *regmap, u8 pin, u8 n)
-{
- int val, ret;
-
- ret = regmap_read(regmap, AW9523_REG_CONF_STATE(pin), &val);
- if (ret < 0)
- return ret;
-
- return (val & BIT(n)) == BIT(n);
-}
-
-/*
- * aw9523_get_port_state - Get input or output state for entire port
- * @regmap: Regmap structure
- * @pin: gpiolib pin number
- * @regbit: hw pin index, used to retrieve port number
- * @state: returned port state
- *
- * Return: Zero for success or negative number for error
- */
-static int aw9523_get_port_state(struct regmap *regmap, u8 pin,
- u8 regbit, unsigned int *state)
-{
- u8 reg;
- int dir;
-
- dir = aw9523_get_pin_direction(regmap, pin, regbit);
- if (dir < 0)
- return dir;
-
- if (dir == GPIO_LINE_DIRECTION_IN)
- reg = AW9523_REG_IN_STATE(pin);
- else
- reg = AW9523_REG_OUT_STATE(pin);
-
- return regmap_read(regmap, reg, state);
-}
-
-static int aw9523_gpio_irq_type(struct irq_data *d, unsigned int type)
-{
- switch (type) {
- case IRQ_TYPE_NONE:
- case IRQ_TYPE_EDGE_BOTH:
- return 0;
- default:
- return -EINVAL;
- };
-}
-
-/*
- * aw9523_irq_mask - Mask interrupt
- * @d: irq data
- *
- * Sets which interrupt to mask in the bitmap;
- * The interrupt will be masked when unlocking the irq bus.
- */
-static void aw9523_irq_mask(struct irq_data *d)
-{
- struct aw9523 *awi = gpiochip_get_data(irq_data_get_irq_chip_data(d));
- unsigned int n = d->hwirq % AW9523_PINS_PER_PORT;
-
- regmap_update_bits(awi->regmap,
- AW9523_REG_INTR_DIS(d->hwirq),
- BIT(n), BIT(n));
-}
-
-/*
- * aw9523_irq_unmask - Unmask interrupt
- * @d: irq data
- *
- * Sets which interrupt to unmask in the bitmap;
- * The interrupt will be masked when unlocking the irq bus.
- */
-static void aw9523_irq_unmask(struct irq_data *d)
-{
- struct aw9523 *awi = gpiochip_get_data(irq_data_get_irq_chip_data(d));
- unsigned int n = d->hwirq % AW9523_PINS_PER_PORT;
-
- regmap_update_bits(awi->regmap,
- AW9523_REG_INTR_DIS(d->hwirq),
- BIT(n), 0);
-}
-
-static irqreturn_t aw9523_irq_thread_func(int irq, void *dev_id)
-{
- struct aw9523 *awi = (struct aw9523 *)dev_id;
- unsigned long n, val = 0;
- unsigned long changed_gpio;
- unsigned int tmp, port_pin, i, ret;
-
- for (i = 0; i < AW9523_NUM_PORTS; i++) {
- port_pin = i * AW9523_PINS_PER_PORT;
- ret = regmap_read(awi->regmap,
- AW9523_REG_IN_STATE(port_pin),
- &tmp);
- if (ret)
- return ret;
- val |= (u8)tmp << (i * 8);
- }
-
- /* Handle GPIO input release interrupt as well */
- changed_gpio = awi->irq->cached_gpio ^ val;
- awi->irq->cached_gpio = val;
-
- /*
- * To avoid up to four *slow* i2c reads from any driver hooked
- * up to our interrupts, just check for the irq_find_mapping
- * result: if the interrupt is not mapped, then we don't want
- * to care about it.
- */
- for_each_set_bit(n, &changed_gpio, awi->gpio.ngpio) {
- tmp = irq_find_mapping(awi->gpio.irq.domain, n);
- if (tmp <= 0)
- continue;
- handle_nested_irq(tmp);
- }
-
- return IRQ_HANDLED;
-}
-
-/*
- * aw9523_irq_bus_lock - Grab lock for interrupt operation
- * @d: irq data
- */
-static void aw9523_irq_bus_lock(struct irq_data *d)
-{
- struct aw9523 *awi = gpiochip_get_data(irq_data_get_irq_chip_data(d));
-
- mutex_lock(&awi->irq->lock);
- regcache_cache_only(awi->regmap, true);
-}
-
-/*
- * aw9523_irq_bus_sync_unlock - Synchronize state and unlock
- * @d: irq data
- *
- * Writes the interrupt mask bits (found in the bit map) to the
- * hardware, then unlocks the bus.
- */
-static void aw9523_irq_bus_sync_unlock(struct irq_data *d)
-{
- struct aw9523 *awi = gpiochip_get_data(irq_data_get_irq_chip_data(d));
-
- regcache_cache_only(awi->regmap, false);
- regcache_sync(awi->regmap);
- mutex_unlock(&awi->irq->lock);
-}
-
-static int aw9523_gpio_get_direction(struct gpio_chip *chip,
- unsigned int offset)
-{
- struct aw9523 *awi = gpiochip_get_data(chip);
- u8 regbit = offset % AW9523_PINS_PER_PORT;
- int ret;
-
- mutex_lock(&awi->i2c_lock);
- ret = aw9523_get_pin_direction(awi->regmap, offset, regbit);
- mutex_unlock(&awi->i2c_lock);
-
- return ret;
-}
-
-static int aw9523_gpio_get(struct gpio_chip *chip, unsigned int offset)
-{
- struct aw9523 *awi = gpiochip_get_data(chip);
- u8 regbit = offset % AW9523_PINS_PER_PORT;
- unsigned int val;
- int ret;
-
- mutex_lock(&awi->i2c_lock);
- ret = aw9523_get_port_state(awi->regmap, offset, regbit, &val);
- mutex_unlock(&awi->i2c_lock);
- if (ret)
- return ret;
-
- return !!(val & BIT(regbit));
-}
-
-/**
- * _aw9523_gpio_get_multiple - Get I/O state for an entire port
- * @regmap: Regmap structure
- * @pin: gpiolib pin number
- * @regbit: hw pin index, used to retrieve port number
- * @state: returned port I/O state
- *
- * Return: Zero for success or negative number for error
- */
-static int _aw9523_gpio_get_multiple(struct aw9523 *awi, u8 regbit,
- u8 *state, u8 mask)
-{
- u32 dir_in, val;
- u8 m;
- int ret;
-
- /* Registers are 8-bits wide */
- ret = regmap_read(awi->regmap, AW9523_REG_CONF_STATE(regbit), &dir_in);
- if (ret)
- return ret;
- *state = 0;
-
- m = mask & dir_in;
- if (m) {
- ret = regmap_read(awi->regmap, AW9523_REG_IN_STATE(regbit),
- &val);
- if (ret)
- return ret;
- *state |= (u8)val & m;
- }
-
- m = mask & ~dir_in;
- if (m) {
- ret = regmap_read(awi->regmap, AW9523_REG_OUT_STATE(regbit),
- &val);
- if (ret)
- return ret;
- *state |= (u8)val & m;
- }
-
- return 0;
-}
-
-static int aw9523_gpio_get_multiple(struct gpio_chip *chip,
- unsigned long *mask,
- unsigned long *bits)
-{
- struct aw9523 *awi = gpiochip_get_data(chip);
- u8 m, state = 0;
- int ret;
-
- mutex_lock(&awi->i2c_lock);
-
- /* Port 0 (gpio 0-7) */
- m = *mask & U8_MAX;
- if (m) {
- ret = _aw9523_gpio_get_multiple(awi, 0, &state, m);
- if (ret)
- goto out;
- }
- *bits = state;
-
- /* Port 1 (gpio 8-15) */
- m = (*mask >> 8) & U8_MAX;
- if (m) {
- ret = _aw9523_gpio_get_multiple(awi, AW9523_PINS_PER_PORT,
- &state, m);
- if (ret)
- goto out;
-
- *bits |= (state << 8);
- }
-out:
- mutex_unlock(&awi->i2c_lock);
- return ret;
-}
-
-static void aw9523_gpio_set_multiple(struct gpio_chip *chip,
- unsigned long *mask,
- unsigned long *bits)
-{
- struct aw9523 *awi = gpiochip_get_data(chip);
- u8 mask_lo, mask_hi, bits_lo, bits_hi;
- unsigned int reg;
- int ret = 0;
-
- mask_lo = *mask & U8_MAX;
- mask_hi = (*mask >> 8) & U8_MAX;
- mutex_lock(&awi->i2c_lock);
- if (mask_hi) {
- reg = AW9523_REG_OUT_STATE(AW9523_PINS_PER_PORT);
- bits_hi = (*bits >> 8) & U8_MAX;
-
- ret = regmap_write_bits(awi->regmap, reg, mask_hi, bits_hi);
- if (ret) {
- dev_warn(awi->dev, "Cannot write port1 out level\n");
- goto out;
- }
- }
- if (mask_lo) {
- reg = AW9523_REG_OUT_STATE(0);
- bits_lo = *bits & U8_MAX;
- ret = regmap_write_bits(awi->regmap, reg, mask_lo, bits_lo);
- if (ret)
- dev_warn(awi->dev, "Cannot write port0 out level\n");
- }
-out:
- mutex_unlock(&awi->i2c_lock);
-}
-
-static void aw9523_gpio_set(struct gpio_chip *chip,
- unsigned int offset, int value)
-{
- struct aw9523 *awi = gpiochip_get_data(chip);
- u8 regbit = offset % AW9523_PINS_PER_PORT;
-
- mutex_lock(&awi->i2c_lock);
- regmap_update_bits(awi->regmap, AW9523_REG_OUT_STATE(offset),
- BIT(regbit), value ? BIT(regbit) : 0);
- mutex_unlock(&awi->i2c_lock);
-}
-
-
-static int aw9523_direction_input(struct gpio_chip *chip, unsigned int offset)
-{
- struct aw9523 *awi = gpiochip_get_data(chip);
- u8 regbit = offset % AW9523_PINS_PER_PORT;
- int ret;
-
- mutex_lock(&awi->i2c_lock);
- ret = regmap_update_bits(awi->regmap, AW9523_REG_CONF_STATE(offset),
- BIT(regbit), BIT(regbit));
- mutex_unlock(&awi->i2c_lock);
-
- return ret;
-}
-
-static int aw9523_direction_output(struct gpio_chip *chip,
- unsigned int offset, int value)
-{
- struct aw9523 *awi = gpiochip_get_data(chip);
- u8 regbit = offset % AW9523_PINS_PER_PORT;
- int ret;
-
- mutex_lock(&awi->i2c_lock);
- ret = regmap_update_bits(awi->regmap, AW9523_REG_OUT_STATE(offset),
- BIT(regbit), value ? BIT(regbit) : 0);
- if (ret)
- goto end;
-
- ret = regmap_update_bits(awi->regmap, AW9523_REG_CONF_STATE(offset),
- BIT(regbit), 0);
-end:
- mutex_unlock(&awi->i2c_lock);
- return ret;
-}
-
-static int aw9523_drive_reset_gpio(struct aw9523 *awi)
-{
- unsigned int chip_id;
- int ret;
-
- /*
- * If the chip is already configured for any reason, then we
- * will probably succeed in sending the soft reset signal to
- * the hardware through I2C: this operation takes less time
- * compared to a full HW reset and it gives the same results.
- */
- ret = regmap_write(awi->regmap, AW9523_REG_SOFT_RESET, 0);
- if (ret == 0)
- goto done;
-
- dev_dbg(awi->dev, "Cannot execute soft reset: trying hard reset\n");
- ret = gpiod_direction_output(awi->reset_gpio, 0);
- if (ret)
- return ret;
-
- /* The reset pulse has to be longer than 20uS due to deglitch */
- usleep_range(AW9523_HW_RESET_US, AW9523_HW_RESET_US + 1);
-
- ret = gpiod_direction_output(awi->reset_gpio, 1);
- if (ret)
- return ret;
-done:
- /* The HW needs at least 1uS to reliably recover after reset */
- usleep_range(AW9523_HW_RESET_RECOVERY_US,
- AW9523_HW_RESET_RECOVERY_US + 1);
-
- /* Check the ChipID */
- ret = regmap_read(awi->regmap, AW9523_REG_CHIPID, &chip_id);
- if (ret) {
- dev_err(awi->dev, "Cannot read Chip ID: %d\n", ret);
- return ret;
- }
- if (chip_id != AW9523_VAL_EXPECTED_CHIPID) {
- dev_err(awi->dev, "Bad ChipID; read 0x%x, expected 0x%x\n",
- chip_id, AW9523_VAL_EXPECTED_CHIPID);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int aw9523_hw_reset(struct aw9523 *awi)
-{
- int ret, max_retries = 2;
-
- /* Sometimes the chip needs more than one reset cycle */
- do {
- ret = aw9523_drive_reset_gpio(awi);
- if (ret == 0)
- break;
- max_retries--;
- } while (max_retries);
-
- return ret;
-}
-
-static int aw9523_init_gpiochip(struct aw9523 *awi, unsigned int npins)
-{
- struct device *dev = awi->dev;
- struct gpio_chip *gpiochip = &awi->gpio;
-
- gpiochip->label = devm_kstrdup(dev, dev_name(dev), GFP_KERNEL);
- if (!gpiochip->label)
- return -ENOMEM;
-
- gpiochip->base = -1;
- gpiochip->ngpio = npins;
- gpiochip->get_direction = aw9523_gpio_get_direction;
- gpiochip->direction_input = aw9523_direction_input;
- gpiochip->direction_output = aw9523_direction_output;
- gpiochip->get = aw9523_gpio_get;
- gpiochip->get_multiple = aw9523_gpio_get_multiple;
- gpiochip->set = aw9523_gpio_set;
- gpiochip->set_multiple = aw9523_gpio_set_multiple;
- gpiochip->set_config = gpiochip_generic_config;
- gpiochip->parent = dev;
- gpiochip->fwnode = dev->fwnode;
- gpiochip->owner = THIS_MODULE;
- gpiochip->can_sleep = true;
-
- return 0;
-}
-
-static int aw9523_init_irq(struct aw9523 *awi, int irq)
-{
- struct device *dev = awi->dev;
- struct gpio_irq_chip *gpioirq;
- struct irq_chip *irqchip;
- int ret;
-
- if (!device_property_read_bool(dev, "interrupt-controller"))
- return 0;
-
- irqchip = devm_kzalloc(dev, sizeof(*irqchip), GFP_KERNEL);
- if (!irqchip)
- return -ENOMEM;
-
- awi->irq = devm_kzalloc(dev, sizeof(*awi->irq), GFP_KERNEL);
- if (!awi->irq)
- return -ENOMEM;
-
- irqchip->name = devm_kstrdup(dev, dev_name(dev), GFP_KERNEL);
- if (!irqchip->name)
- return -ENOMEM;
-
- irqchip->irq_mask = aw9523_irq_mask;
- irqchip->irq_unmask = aw9523_irq_unmask;
- irqchip->irq_bus_lock = aw9523_irq_bus_lock;
- irqchip->irq_bus_sync_unlock = aw9523_irq_bus_sync_unlock;
- irqchip->irq_set_type = aw9523_gpio_irq_type;
- awi->irq->irqchip = irqchip;
- mutex_init(&awi->irq->lock);
-
- ret = devm_request_threaded_irq(dev, irq, NULL, aw9523_irq_thread_func,
- IRQF_ONESHOT, dev_name(dev), awi);
- if (ret) {
- dev_err(dev, "Failed to request irq %d\n", irq);
- return ret;
- }
-
- gpioirq = &awi->gpio.irq;
- gpioirq->chip = irqchip;
- gpioirq->parent_handler = NULL;
- gpioirq->num_parents = 0;
- gpioirq->parents = NULL;
- gpioirq->default_type = IRQ_TYPE_LEVEL_MASK;
- gpioirq->handler = handle_simple_irq;
- gpioirq->threaded = true;
- gpioirq->first = 0;
-
- return 0;
-}
-
-static bool aw9523_is_reg_hole(unsigned int reg)
-{
- return (reg > AW9523_REG_PORT_MODE(AW9523_PINS_PER_PORT) &&
- reg < AW9523_REG_SOFT_RESET) ||
- (reg > AW9523_REG_INTR_DIS(AW9523_PINS_PER_PORT) &&
- reg < AW9523_REG_CHIPID);
-}
-
-static bool aw9523_readable_reg(struct device *dev, unsigned int reg)
-{
- /* All available registers (minus holes) can be read */
- return !aw9523_is_reg_hole(reg);
-}
-
-static bool aw9523_volatile_reg(struct device *dev, unsigned int reg)
-{
- return aw9523_is_reg_hole(reg) ||
- reg == AW9523_REG_IN_STATE(0) ||
- reg == AW9523_REG_IN_STATE(AW9523_PINS_PER_PORT) ||
- reg == AW9523_REG_CHIPID ||
- reg == AW9523_REG_SOFT_RESET;
-}
-
-static bool aw9523_writeable_reg(struct device *dev, unsigned int reg)
-{
- return !aw9523_is_reg_hole(reg) && reg != AW9523_REG_CHIPID;
-}
-
-static bool aw9523_precious_reg(struct device *dev, unsigned int reg)
-{
- /* Reading AW9523_REG_IN_STATE clears interrupt status */
- return aw9523_is_reg_hole(reg) ||
- reg == AW9523_REG_IN_STATE(0) ||
- reg == AW9523_REG_IN_STATE(AW9523_PINS_PER_PORT);
-}
-
-static const struct regmap_config aw9523_regmap = {
- .reg_bits = 8,
- .val_bits = 8,
- .reg_stride = 1,
-
- .precious_reg = aw9523_precious_reg,
- .readable_reg = aw9523_readable_reg,
- .volatile_reg = aw9523_volatile_reg,
- .writeable_reg = aw9523_writeable_reg,
-
- .cache_type = REGCACHE_FLAT,
- .disable_locking = true,
-
- .num_reg_defaults_raw = AW9523_REG_SOFT_RESET,
-};
-
-static int aw9523_hw_init(struct aw9523 *awi)
-{
- u8 p1_pin = AW9523_PINS_PER_PORT;
- unsigned int val;
- int ret;
-
- /* No register caching during initialization */
- regcache_cache_bypass(awi->regmap, true);
-
- /* Bring up the chip */
- ret = aw9523_hw_reset(awi);
- if (ret) {
- dev_err(awi->dev, "HW Reset failed: %d\n", ret);
- return ret;
- }
-
- /*
- * This is the expected chip and it is running: it's time to
- * set a safe default configuration in case the user doesn't
- * configure (all of the available) pins in this chip.
- * P.S.: The writes order doesn't matter.
- */
-
- /* Set all pins as GPIO */
- ret = regmap_write(awi->regmap, AW9523_REG_PORT_MODE(0), U8_MAX);
- if (ret)
- return ret;
- ret = regmap_write(awi->regmap, AW9523_REG_PORT_MODE(p1_pin), U8_MAX);
- if (ret)
- return ret;
-
- /* Set Open-Drain mode on Port 0 (Port 1 is always P-P) */
- ret = regmap_write(awi->regmap, AW9523_REG_GCR, 0);
- if (ret)
- return ret;
-
- /* Set all pins as inputs */
- ret = regmap_write(awi->regmap, AW9523_REG_CONF_STATE(0), U8_MAX);
- if (ret)
- return ret;
- ret = regmap_write(awi->regmap, AW9523_REG_CONF_STATE(p1_pin), U8_MAX);
- if (ret)
- return ret;
-
- /* Disable all interrupts to avoid unreasoned wakeups */
- ret = regmap_write(awi->regmap, AW9523_REG_INTR_DIS(0), U8_MAX);
- if (ret)
- return ret;
- ret = regmap_write(awi->regmap, AW9523_REG_INTR_DIS(p1_pin), U8_MAX);
- if (ret)
- return ret;
-
- /* Clear setup-generated interrupts by performing a port state read */
- ret = aw9523_get_port_state(awi->regmap, 0, 0, &val);
- if (ret)
- return ret;
- ret = aw9523_get_port_state(awi->regmap, p1_pin, 0, &val);
- if (ret)
- return ret;
-
- /* Everything went fine: activate and reinitialize register cache */
- regcache_cache_bypass(awi->regmap, false);
- return regmap_reinit_cache(awi->regmap, &aw9523_regmap);
-}
-
-static int aw9523_probe(struct i2c_client *client)
-{
- struct device *dev = &client->dev;
- struct pinctrl_desc *pdesc;
- struct aw9523 *awi;
- int ret;
-
- awi = devm_kzalloc(dev, sizeof(*awi), GFP_KERNEL);
- if (!awi)
- return -ENOMEM;
-
- i2c_set_clientdata(client, awi);
-
- awi->dev = dev;
- awi->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
- if (IS_ERR(awi->reset_gpio))
- return PTR_ERR(awi->reset_gpio);
- gpiod_set_consumer_name(awi->reset_gpio, "aw9523 reset");
-
- awi->regmap = devm_regmap_init_i2c(client, &aw9523_regmap);
- if (IS_ERR(awi->regmap))
- return PTR_ERR(awi->regmap);
-
- awi->vio_vreg = devm_regulator_get_optional(dev, "vio");
- if (IS_ERR(awi->vio_vreg)) {
- if (PTR_ERR(awi->vio_vreg) == -EPROBE_DEFER)
- return -EPROBE_DEFER;
- awi->vio_vreg = NULL;
- } else {
- ret = regulator_enable(awi->vio_vreg);
- if (ret)
- return ret;
- }
-
- mutex_init(&awi->i2c_lock);
- lockdep_set_subclass(&awi->i2c_lock,
- i2c_adapter_depth(client->adapter));
-
- pdesc = devm_kzalloc(dev, sizeof(*pdesc), GFP_KERNEL);
- if (!pdesc)
- return -ENOMEM;
-
- ret = aw9523_hw_init(awi);
- if (ret)
- goto err_disable_vregs;
-
- pdesc->name = dev_name(dev);
- pdesc->owner = THIS_MODULE;
- pdesc->pctlops = &aw9523_pinctrl_ops;
- pdesc->pmxops = &aw9523_pinmux_ops;
- pdesc->confops = &aw9523_pinconf_ops;
- pdesc->pins = aw9523_pins;
- pdesc->npins = ARRAY_SIZE(aw9523_pins);
-
- ret = aw9523_init_gpiochip(awi, pdesc->npins);
- if (ret)
- goto err_disable_vregs;
-
- if (client->irq) {
- ret = aw9523_init_irq(awi, client->irq);
- if (ret)
- goto err_disable_vregs;
- }
-
- awi->pctl = devm_pinctrl_register(dev, pdesc, awi);
- if (IS_ERR(awi->pctl)) {
- ret = PTR_ERR(awi->pctl);
- dev_err(dev, "Cannot register pinctrl: %d", ret);
- goto err_disable_vregs;
- }
-
- ret = devm_gpiochip_add_data(dev, &awi->gpio, awi);
- if (ret)
- goto err_disable_vregs;
-
- return ret;
-
-err_disable_vregs:
- if (awi->vio_vreg)
- regulator_disable(awi->vio_vreg);
- mutex_destroy(&awi->i2c_lock);
- return ret;
-}
-
-static int aw9523_remove(struct i2c_client *client)
-{
- struct aw9523 *awi = i2c_get_clientdata(client);
- int ret;
-
- if (!awi)
- return 0;
-
- /*
- * If the chip VIO is connected to a regulator that we can turn
- * off, life is easy... otherwise, reinitialize the chip and
- * set the pins to hardware defaults before removing the driver
- * to leave it in a clean, safe and predictable state.
- */
- if (awi->vio_vreg) {
- regulator_disable(awi->vio_vreg);
- } else {
- mutex_lock(&awi->i2c_lock);
- ret = aw9523_hw_init(awi);
- mutex_unlock(&awi->i2c_lock);
- if (ret)
- return ret;
- }
-
- mutex_destroy(&awi->i2c_lock);
- return 0;
-}
-
-static void aw9523_remove_void(struct i2c_client *client)
-{
- aw9523_remove(client);
-}
-
-static const struct i2c_device_id aw9523_i2c_id_table[] = {
- { "aw9523_i2c", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, aw9523_i2c_id_table);
-
-static const struct of_device_id of_aw9523_i2c_match[] = {
- { .compatible = "awinic,aw9523-pinctrl", },
-};
-MODULE_DEVICE_TABLE(of, of_aw9523_i2c_match);
-
-static struct i2c_driver aw9523_driver = {
- .driver = {
- .name = "aw9523-pinctrl",
- .of_match_table = of_aw9523_i2c_match,
- },
- .probe = aw9523_probe,
- .remove = aw9523_remove_void,
- .id_table = aw9523_i2c_id_table,
-};
-module_i2c_driver(aw9523_driver);
-
-MODULE_DESCRIPTION("Awinic AW9523 I2C GPIO Expander driver");
-MODULE_AUTHOR("AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>");
-MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("platform:aw9523");
diff --git a/target/linux/ramips/image/mt7620.mk b/target/linux/ramips/image/mt7620.mk
index da1c3e69e6..9f3a8dce0e 100644
--- a/target/linux/ramips/image/mt7620.mk
+++ b/target/linux/ramips/image/mt7620.mk
@@ -1220,7 +1220,7 @@ define Device/tplink_archer-c2-v1
DEVICE_MODEL := Archer C2
DEVICE_VARIANT := v1
DEVICE_PACKAGES := kmod-mt76x0e kmod-usb2 kmod-usb-ohci \
- kmod-usb-ledtrig-usbport kmod-switch-rtl8366-smi kmod-switch-rtl8367b
+ kmod-usb-ledtrig-usbport kmod-switch-rtl8367b
endef
TARGET_DEVICES += tplink_archer-c2-v1
@@ -1349,6 +1349,16 @@ define Device/wavlink_wl-wn531g3
endef
TARGET_DEVICES += wavlink_wl-wn531g3
+
+define Device/wavlink_wl-wn531g3-a2
+ SOC := mt7620a
+ IMAGE_SIZE := 7872k
+ DEVICE_VENDOR := Wavlink
+ DEVICE_MODEL := WL-WN531G3-A2
+ DEVICE_PACKAGES := kmod-mt76x2 kmod-phy-realtek kmod-usb2 kmod-usb-ohci
+endef
+TARGET_DEVICES += wavlink_wl-wn531g3-a2
+
define Device/wavlink_wl-wn535k1
SOC := mt7620a
IMAGE_SIZE := 7360k
@@ -1564,7 +1574,7 @@ TARGET_DEVICES += zte_q7
define Device/zyxel_keenetic-lite-iii-a
SOC := mt7620n
IMAGE_SIZE := 7872k
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
DEVICE_MODEL := Keenetic Lite III
DEVICE_VARIANT := A
IMAGES += factory.bin
@@ -1576,7 +1586,7 @@ TARGET_DEVICES += zyxel_keenetic-lite-iii-a
define Device/zyxel_keenetic-omni
SOC := mt7620n
IMAGE_SIZE := 7872k
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
DEVICE_MODEL := Keenetic Omni
DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci kmod-usb-ledtrig-usbport
IMAGES += factory.bin
@@ -1589,7 +1599,7 @@ TARGET_DEVICES += zyxel_keenetic-omni
define Device/zyxel_keenetic-omni-ii
SOC := mt7620n
IMAGE_SIZE := 7872k
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
DEVICE_MODEL := Keenetic Omni II
DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci kmod-usb-ledtrig-usbport
IMAGES += factory.bin
@@ -1602,10 +1612,10 @@ TARGET_DEVICES += zyxel_keenetic-omni-ii
define Device/zyxel_keenetic-viva
SOC := mt7620a
IMAGE_SIZE := 16064k
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
DEVICE_MODEL := Keenetic Viva
DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci kmod-usb-ledtrig-usbport \
- kmod-switch-rtl8366-smi kmod-switch-rtl8367b
+ kmod-switch-rtl8367b
IMAGES += factory.bin
IMAGE/factory.bin := $$(sysupgrade_bin) | pad-to 64k | check-size | \
zyimage -d 8997 -v "ZyXEL Keenetic Viva"
diff --git a/target/linux/ramips/image/mt7621.mk b/target/linux/ramips/image/mt7621.mk
index 44672a9542..18dbbcadf3 100644
--- a/target/linux/ramips/image/mt7621.mk
+++ b/target/linux/ramips/image/mt7621.mk
@@ -604,7 +604,7 @@ define Device/comfast_cf-e390ax
$(Device/dsa-migration)
$(Device/uimage-lzma-loader)
IMAGE_SIZE := 15808k
- DEVICE_VENDOR := ComFast
+ DEVICE_VENDOR := COMFAST
DEVICE_MODEL := CF-E390AX
DEVICE_PACKAGES := kmod-mt7915-firmware -uboot-envtools
IMAGES += factory.bin
@@ -618,7 +618,7 @@ define Device/comfast_cf-ew72-v2
$(Device/dsa-migration)
$(Device/uimage-lzma-loader)
IMAGE_SIZE := 15808k
- DEVICE_VENDOR := ComFast
+ DEVICE_VENDOR := COMFAST
DEVICE_MODEL := CF-EW72 V2
DEVICE_PACKAGES := kmod-mt7603 kmod-mt7615e kmod-mt7663-firmware-ap \
-uboot-envtools
@@ -1650,6 +1650,19 @@ define Device/keenetic_kn-3010
endef
TARGET_DEVICES += keenetic_kn-3010
+define Device/keenetic_kn-3510
+ $(Device/nand)
+ $(Device/uimage-lzma-loader)
+ IMAGE_SIZE := 121088k
+ DEVICE_VENDOR := Keenetic
+ DEVICE_MODEL := KN-3510
+ DEVICE_PACKAGES := kmod-mt7915-firmware -uboot-envtools
+ IMAGES += factory.bin
+ IMAGE/factory.bin := append-kernel | pad-to $$(KERNEL_SIZE) | append-ubi | \
+ check-size | zyimage -d 0x803510 -v "KN-3510"
+endef
+TARGET_DEVICES += keenetic_kn-3510
+
define Device/lenovo_newifi-d1
$(Device/dsa-migration)
$(Device/uimage-lzma-loader)
@@ -2113,6 +2126,24 @@ define Device/netgear_wax202
endef
TARGET_DEVICES += netgear_wax202
+define Device/netgear_wax214v2
+ $(Device/nand)
+ DEVICE_VENDOR := NETGEAR
+ DEVICE_MODEL := WAX214v2
+ DEVICE_PACKAGES := kmod-mt7915-firmware
+ NETGEAR_ENC_MODEL := WAX214v2
+ NETGEAR_ENC_REGION := US
+ IMAGE_SIZE := 38912k
+ KERNEL_LOADADDR := 0x82000000
+ KERNEL := kernel-bin | relocate-kernel 0x80001000 | lzma | \
+ fit lzma $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb | \
+ append-squashfs4-fakeroot
+ IMAGES += factory.img
+ IMAGE/factory.img := append-kernel | pad-to $$(KERNEL_SIZE) | \
+ append-ubi | check-size | netgear-encrypted-factory
+endef
+TARGET_DEVICES += netgear_wax214v2
+
define Device/netgear_wndr3700-v5
$(Device/dsa-migration)
$(Device/netgear_sercomm_nor)
@@ -2656,7 +2687,7 @@ TARGET_DEVICES += ubnt_edgerouter-x-sfp
define Device/ubnt_unifi-6-lite
$(Device/dsa-migration)
DEVICE_VENDOR := Ubiquiti
- DEVICE_MODEL := UniFi 6 Lite
+ DEVICE_MODEL := UniFi U6 Lite
DEVICE_DTS_CONFIG := config@1
DEVICE_DTS_LOADADDR := 0x87000000
DEVICE_PACKAGES += kmod-mt7603 kmod-mt7915-firmware -uboot-envtools
@@ -2867,6 +2898,17 @@ define Device/winstars_ws-wn583a6
endef
TARGET_DEVICES += winstars_ws-wn583a6
+define Device/wodesys_wd-r1802u
+ $(Device/dsa-migration)
+ $(Device/uimage-lzma-loader)
+ IMAGE_SIZE := 15808k
+ DEVICE_VENDOR := Wodesys
+ DEVICE_MODEL := WD-R1802U
+ DEVICE_PACKAGES := kmod-mt7915-firmware -uboot-envtools
+ SUPPORTED_DEVICES += mt7621-rfb-ax-nor
+endef
+TARGET_DEVICES += wodesys_wd-r1802u
+
define Device/xiaomi_nand_separate
$(Device/nand)
$(Device/uimage-lzma-loader)
@@ -3220,7 +3262,7 @@ TARGET_DEVICES += zio_freezio
define Device/zyxel_lte3301-plus
$(Device/nand)
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
DEVICE_MODEL := LTE3301-PLUS
KERNEL_SIZE := 31488k
DEVICE_PACKAGES := kmod-mt7615-firmware kmod-usb3 kmod-usb-ledtrig-usbport \
@@ -3235,7 +3277,7 @@ TARGET_DEVICES += zyxel_lte3301-plus
define Device/zyxel_lte5398-m904
$(Device/nand)
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
DEVICE_MODEL := LTE5398-M904
KERNEL_SIZE := 31488k
DEVICE_PACKAGES := kmod-mt7603 kmod-mt7615-firmware kmod-usb3 uqmi \
@@ -3250,7 +3292,7 @@ TARGET_DEVICES += zyxel_lte5398-m904
define Device/zyxel_nr7101
$(Device/nand)
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
DEVICE_MODEL := NR7101
KERNEL_SIZE := 31488k
DEVICE_PACKAGES := kmod-mt7603 kmod-usb3 kmod-usb-net-qmi-wwan kmod-usb-serial-option uqmi
@@ -3262,7 +3304,7 @@ TARGET_DEVICES += zyxel_nr7101
define Device/zyxel_nwa-ax
$(Device/nand)
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
KERNEL_SIZE := 8192k
DEVICE_PACKAGES := kmod-mt7915-firmware zyxel-bootconfig
KERNEL := kernel-bin | lzma | fit lzma $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb
@@ -3287,7 +3329,7 @@ define Device/zyxel_wap6805
$(Device/nand)
$(Device/uimage-lzma-loader)
IMAGE_SIZE := 32448k
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
DEVICE_MODEL := WAP6805
DEVICE_PACKAGES := kmod-mt7603 kmod-mt7621-qtn-rgmii -uboot-envtools
KERNEL := $$(KERNEL/lzma-loader) | uImage none | uimage-padhdr 160
@@ -3298,7 +3340,7 @@ define Device/zyxel_wsm20
$(Device/nand)
KERNEL_SIZE := 8192k
IMAGE_SIZE := 41943040
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
DEVICE_MODEL := WSM20
DEVICE_PACKAGES := kmod-mt7915-firmware
KERNEL := kernel-bin | lzma | fit lzma $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb | znet-header V1.00(ABZF.0)C0
diff --git a/target/linux/ramips/image/mt76x8.mk b/target/linux/ramips/image/mt76x8.mk
index 2ea948a5f9..8ad840ddfe 100644
--- a/target/linux/ramips/image/mt76x8.mk
+++ b/target/linux/ramips/image/mt76x8.mk
@@ -135,7 +135,7 @@ TARGET_DEVICES += buffalo_wcr-1166ds
define Device/comfast_cf-wr617ac
IMAGE_SIZE := 7872k
DTS := CF-WR617AC
- DEVICE_VENDOR := Comfast
+ DEVICE_VENDOR := COMFAST
DEVICE_MODEL := CF-WR617AC
DEVICE_PACKAGES := kmod-mt76x2 kmod-rt2800-pci
endef
@@ -1092,6 +1092,15 @@ define Device/xiaomi_mi-router-4a-100m-intl
endef
TARGET_DEVICES += xiaomi_mi-router-4a-100m-intl
+define Device/xiaomi_mi-router-4a-100m-intl-v2
+ IMAGE_SIZE := 14976k
+ DEVICE_VENDOR := Xiaomi
+ DEVICE_MODEL := Mi Router 4A
+ DEVICE_VARIANT := 100M International Edition V2
+ DEVICE_PACKAGES := kmod-mt7615e kmod-mt7663-firmware-ap
+endef
+TARGET_DEVICES += xiaomi_mi-router-4a-100m-intl-v2
+
define Device/xiaomi_mi-router-4c
IMAGE_SIZE := 14976k
DEVICE_VENDOR := Xiaomi
@@ -1127,6 +1136,21 @@ define Device/xiaomi_mi-ra75
endef
TARGET_DEVICES += xiaomi_mi-ra75
+define Device/yuncore_cpe200
+ IMAGE_SIZE := 7872k
+ DEVICE_VENDOR := Yuncore
+ DEVICE_MODEL := CPE200
+ DEVICE_PACKAGES := -kmod-mt7603 kmod-mt7615e kmod-mt7663-firmware-ap kmod-mt7663-firmware-sta
+endef
+TARGET_DEVICES += yuncore_cpe200
+
+define Device/yuncore_m300
+ IMAGE_SIZE := 7872k
+ DEVICE_VENDOR := Yuncore
+ DEVICE_MODEL := M300
+endef
+TARGET_DEVICES += yuncore_m300
+
define Device/zbtlink_zbt-we1226
IMAGE_SIZE := 7872k
DEVICE_VENDOR := Zbtlink
@@ -1136,7 +1160,7 @@ TARGET_DEVICES += zbtlink_zbt-we1226
define Device/zyxel_keenetic-extra-ii
IMAGE_SIZE := 29824k
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
DEVICE_MODEL := Keenetic Extra II
DEVICE_PACKAGES := kmod-mt76x2 kmod-usb2 kmod-usb-ohci \
kmod-usb-ledtrig-usbport
diff --git a/target/linux/ramips/image/rt305x.mk b/target/linux/ramips/image/rt305x.mk
index 815e03a8d4..f52098c733 100644
--- a/target/linux/ramips/image/rt305x.mk
+++ b/target/linux/ramips/image/rt305x.mk
@@ -1220,7 +1220,7 @@ TARGET_DEVICES += zte_mf283plus
define Device/zyxel_keenetic
SOC := rt3052
IMAGE_SIZE := 7872k
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
DEVICE_MODEL := Keenetic
DEVICE_PACKAGES := kmod-usb2 kmod-usb-ehci kmod-usb-ledtrig-usbport \
kmod-usb-dwc2
@@ -1233,7 +1233,7 @@ define Device/zyxel_keenetic-4g-b
$(Device/uimage-lzma-loader)
SOC := rt5350
IMAGE_SIZE := 7872k
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
DEVICE_MODEL := Keenetic 4G
DEVICE_VARIANT := B
DEFAULT := n
@@ -1244,7 +1244,7 @@ define Device/zyxel_keenetic-lite-b
$(Device/uimage-lzma-loader)
SOC := rt5350
IMAGE_SIZE := 7872k
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
DEVICE_MODEL := Keenetic Lite
DEVICE_VARIANT := B
DEFAULT := n
@@ -1254,7 +1254,7 @@ TARGET_DEVICES += zyxel_keenetic-lite-b
define Device/zyxel_keenetic-start
SOC := rt5350
IMAGE_SIZE := 3776k
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
DEVICE_MODEL := Keenetic Start
DEFAULT := n
endef
@@ -1263,7 +1263,7 @@ TARGET_DEVICES += zyxel_keenetic-start
define Device/zyxel_nbg-419n
SOC := rt3052
IMAGE_SIZE := 3776k
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
DEVICE_MODEL := NBG-419N
SUPPORTED_DEVICES += nbg-419n
DEFAULT := n
@@ -1274,7 +1274,7 @@ define Device/zyxel_nbg-419n-v2
$(Device/uimage-lzma-loader)
SOC := rt3352
IMAGE_SIZE := 7872k
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
DEVICE_MODEL := NBG-419N
DEVICE_VARIANT := v2
SUPPORTED_DEVICES += nbg-419n2
diff --git a/target/linux/ramips/mt7620/base-files/etc/board.d/02_network b/target/linux/ramips/mt7620/base-files/etc/board.d/02_network
index d23ec76327..577f77cb93 100644
--- a/target/linux/ramips/mt7620/base-files/etc/board.d/02_network
+++ b/target/linux/ramips/mt7620/base-files/etc/board.d/02_network
@@ -257,6 +257,10 @@ ramips_setup_interfaces()
ucidef_add_switch "switch0" \
"0:lan:4" "1:lan:3" "2:lan:2" "5:lan:1" "4:wan" "6@eth0"
;;
+ wavlink,wl-wn531g3-a2)
+ ucidef_add_switch "switch0" \
+ "0:lan:4" "1:lan:3" "2:lan:2" "5:lan:1" "4:wan" "6@eth0"
+ ;;
wavlink,wl-wn535k1)
ucidef_add_switch "switch0" \
"2:lan:2" "5:lan:1" "4:wan" "6@eth0"
@@ -431,6 +435,7 @@ ramips_setup_macs()
wan_mac=$(macaddr_add "$(mtd_get_mac_binary rom 0xf100)" 1)
;;
wavlink,wl-wn531g3|\
+ wavlink,wl-wn531g3-a2|\
zbtlink,zbt-we1026-5g-16m)
label_mac=$(mtd_get_mac_binary factory 0x4)
;;
diff --git a/target/linux/ramips/mt7621/base-files/etc/board.d/02_network b/target/linux/ramips/mt7621/base-files/etc/board.d/02_network
index 386a3bb41d..b7e3a49b43 100644
--- a/target/linux/ramips/mt7621/base-files/etc/board.d/02_network
+++ b/target/linux/ramips/mt7621/base-files/etc/board.d/02_network
@@ -47,6 +47,7 @@ ramips_setup_interfaces()
mikrotik,routerboard-m11g|\
netgear,eax12|\
netgear,ex6150|\
+ netgear,wax214v2|\
sercomm,na502|\
sercomm,na502s|\
thunder,timecloud|\
@@ -60,12 +61,14 @@ ramips_setup_interfaces()
ubnt,unifi-nanohd|\
yuncore,fap690|\
wavlink,wl-wn573hx1|\
+ wodesys,wd-r1802u|\
zyxel,nwa50ax|\
zyxel,nwa55axe)
ucidef_set_interface_lan "lan"
;;
asiarf,ap7621-001|\
humax,e10|\
+ keenetic,kn-3510|\
openfi,5pro|\
wavlink,ws-wn572hp3-4g|\
winstars,ws-wn583a6)
@@ -325,6 +328,10 @@ ramips_setup_macs()
wan_mac=$(macaddr_add "$lan_mac" 1)
label_mac=$lan_mac
;;
+ netgear,wax214v2)
+ lan_mac=$(mtd_get_mac_ascii Config ethaddr)
+ label_mac=$lan_mac
+ ;;
yuncore,ax820)
label_mac=$(mtd_get_mac_binary Factory 0x4)
;;
diff --git a/target/linux/ramips/mt7621/base-files/etc/hotplug.d/ieee80211/05-wifi-migrate b/target/linux/ramips/mt7621/base-files/etc/hotplug.d/ieee80211/05-wifi-migrate
index 6504dc81a5..0e7ff41453 100644
--- a/target/linux/ramips/mt7621/base-files/etc/hotplug.d/ieee80211/05-wifi-migrate
+++ b/target/linux/ramips/mt7621/base-files/etc/hotplug.d/ieee80211/05-wifi-migrate
@@ -63,7 +63,8 @@ netgear,wac104|\
netgear,wndr3700-v5)
migrate_radio '1e140000.pcie/pci0000:00/0000:00:01.0/0000:02:00.0' '1e140000.pcie/pci0000:00/0000:00:02.0/0000:02:00.0'
;;
-zbtlink,zbt-we1326)
+zbtlink,zbt-we1326|\
+zbtlink,zbt-we3526)
migrate_radio '1e140000.pcie/pci0000:00/0000:00:01.0/0000:02:00.0' '1e140000.pcie/pci0000:00/0000:00:02.0/0000:02:00.0'
migrate_radio '1e140000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0' '1e140000.pcie/pci0000:00/0000:00:01.0/0000:01:00.0'
;;
diff --git a/target/linux/ramips/mt7621/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac b/target/linux/ramips/mt7621/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac
index 9350d67466..91c17f8a77 100644
--- a/target/linux/ramips/mt7621/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac
+++ b/target/linux/ramips/mt7621/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac
@@ -126,6 +126,10 @@ case "$board" in
[ "$PHYNBR" = "1" ] && \
macaddr_setbit_la "$(mtd_get_mac_binary Factory 0x4)" > /sys${DEVPATH}/macaddress
;;
+ keenetic,kn-3510)
+ [ "$PHYNBR" = "1" ] && \
+ macaddr_setbit_la "$(mtd_get_mac_binary rf-eeprom 0x4)" > /sys${DEVPATH}/macaddress
+ ;;
linksys,e5600|\
linksys,ea6350-v4|\
linksys,ea7300-v1|\
@@ -153,6 +157,11 @@ case "$board" in
[ "$PHYNBR" = "0" ] && macaddr_add $hw_mac_addr 2 > /sys${DEVPATH}/macaddress
[ "$PHYNBR" = "1" ] && macaddr_add $hw_mac_addr 3 > /sys${DEVPATH}/macaddress
;;
+ netgear,wax214v2)
+ hw_mac_addr=$(mtd_get_mac_ascii Config ethaddr)
+ [ "$PHYNBR" = "0" ] && macaddr_add $hw_mac_addr 2 > /sys${DEVPATH}/macaddress
+ [ "$PHYNBR" = "1" ] && macaddr_add $hw_mac_addr 3 > /sys${DEVPATH}/macaddress
+ ;;
mercusys,mr70x-v1|\
tplink,archer-ax23-v1)
hw_mac_addr="$(mtd_get_mac_binary config 0x8)"
diff --git a/target/linux/ramips/mt7621/base-files/lib/upgrade/platform.sh b/target/linux/ramips/mt7621/base-files/lib/upgrade/platform.sh
index 32dad72944..bad7e30ca6 100755
--- a/target/linux/ramips/mt7621/base-files/lib/upgrade/platform.sh
+++ b/target/linux/ramips/mt7621/base-files/lib/upgrade/platform.sh
@@ -100,6 +100,7 @@ platform_do_upgrade() {
iptime,ax2004m|\
iptime,t5004|\
jcg,q20|\
+ keenetic,kn-3510|\
linksys,e5600|\
linksys,e7350|\
linksys,ea6350-v4|\
@@ -122,6 +123,7 @@ platform_do_upgrade() {
netgear,wac104|\
netgear,wac124|\
netgear,wax202|\
+ netgear,wax214v2|\
netis,wf2881|\
raisecom,msg1500-x-00|\
rostelecom,rt-fe-1a|\
diff --git a/target/linux/ramips/mt76x8/base-files/etc/board.d/01_leds b/target/linux/ramips/mt76x8/base-files/etc/board.d/01_leds
index 3e0b70cc20..5ea668de01 100644
--- a/target/linux/ramips/mt76x8/base-files/etc/board.d/01_leds
+++ b/target/linux/ramips/mt76x8/base-files/etc/board.d/01_leds
@@ -18,7 +18,9 @@ asus,rt-n11p-b1|\
asus,rt-n12-vp-b1|\
netgear,r6020|\
netgear,r6080|\
-netgear,r6120)
+netgear,r6120|\
+yuncore,cpe200|\
+yuncore,m300)
ucidef_set_led_switch "lan" "lan" "green:lan" "switch0" "0xf"
ucidef_set_led_switch "wan" "wan" "green:wan" "switch0" "0x10"
;;
@@ -171,7 +173,8 @@ wavlink,wl-wn578a2)
ucidef_set_led_switch "wan" "wan" "green:wan" "switch0" "0x10"
;;
xiaomi,mi-router-4a-100m|\
-xiaomi,mi-router-4a-100m-intl)
+xiaomi,mi-router-4a-100m-intl|\
+xiaomi,mi-router-4a-100m-intl-v2)
ucidef_set_led_switch "wan" "WAN" "blue:wan" "switch0" "0x01"
;;
xiaomi,mi-router-4c)
diff --git a/target/linux/ramips/mt76x8/base-files/etc/board.d/02_network b/target/linux/ramips/mt76x8/base-files/etc/board.d/02_network
index c44361a439..cb0983b9dc 100644
--- a/target/linux/ramips/mt76x8/base-files/etc/board.d/02_network
+++ b/target/linux/ramips/mt76x8/base-files/etc/board.d/02_network
@@ -81,7 +81,8 @@ ramips_setup_interfaces()
buffalo,wcr-1166ds|\
elecom,wrc-1167fs|\
wavlink,wl-wn577a2|\
- wavlink,wl-wn578a2)
+ wavlink,wl-wn578a2|\
+ yuncore,m300)
ucidef_add_switch "switch0" \
"3:lan" "4:wan" "6@eth0"
;;
@@ -186,7 +187,8 @@ ramips_setup_interfaces()
"0:wan" "3:lan" "4:lan" "6@eth0"
;;
xiaomi,mi-router-4a-100m|\
- xiaomi,mi-router-4a-100m-intl)
+ xiaomi,mi-router-4a-100m-intl|\
+ xiaomi,mi-router-4a-100m-intl-v2)
ucidef_add_switch "switch0" \
"4:lan:1" "2:lan:2" "0:wan" "6@eth0"
;;
@@ -202,6 +204,10 @@ ramips_setup_interfaces()
ucidef_add_switch "switch0" \
"0:lan:2" "2:lan:1" "4:wan" "6@eth0"
;;
+ yuncore,cpe200)
+ ucidef_add_switch "switch0" \
+ "0:lan" "4:wan" "6@eth0"
+ ;;
zbtlink,zbt-we1226)
ucidef_add_switch "switch0" \
"0:lan:2" "1:lan:1" "4:wan" "6@eth0"
@@ -323,6 +329,7 @@ ramips_setup_macs()
;;
xiaomi,mi-router-4a-100m|\
xiaomi,mi-router-4a-100m-intl|\
+ xiaomi,mi-router-4a-100m-intl-v2|\
xiaomi,mi-router-4c)
wan_mac=$(mtd_get_mac_binary factory 0x4)
;;
diff --git a/target/linux/ramips/mt76x8/config-6.6 b/target/linux/ramips/mt76x8/config-6.6
index a2d7bc9866..b9dc8525df 100644
--- a/target/linux/ramips/mt76x8/config-6.6
+++ b/target/linux/ramips/mt76x8/config-6.6
@@ -84,6 +84,8 @@ CONFIG_GPIO_CDEV=y
CONFIG_GPIO_GENERIC=y
CONFIG_GPIO_MT7621=y
# CONFIG_GPIO_RALINK is not set
+CONFIG_GPIO_WATCHDOG=y
+# CONFIG_GPIO_WATCHDOG_ARCH_INITCALL is not set
CONFIG_HARDWARE_WATCHPOINTS=y
CONFIG_HAS_DMA=y
CONFIG_HAS_IOMEM=y
diff --git a/target/linux/ramips/patches-6.6/410-mtd-rawnand-add-driver-support-for-MT7621-nand-flash.patch b/target/linux/ramips/patches-6.6/410-mtd-rawnand-add-driver-support-for-MT7621-nand-flash.patch
index 51f1a5ec5e..f87edd3e67 100644
--- a/target/linux/ramips/patches-6.6/410-mtd-rawnand-add-driver-support-for-MT7621-nand-flash.patch
+++ b/target/linux/ramips/patches-6.6/410-mtd-rawnand-add-driver-support-for-MT7621-nand-flash.patch
@@ -20,7 +20,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
--- a/drivers/mtd/nand/raw/Kconfig
+++ b/drivers/mtd/nand/raw/Kconfig
-@@ -338,6 +338,14 @@ config MTD_NAND_QCOM
+@@ -337,6 +337,14 @@ config MTD_NAND_QCOM
Enables support for NAND flash chips on SoCs containing the EBI2 NAND
controller. This controller is found on IPQ806x SoC.
diff --git a/target/linux/ramips/patches-6.6/805-01-v6.9-pinctrl-Add-driver-for-Awinic-AW9523-B-I2C-GPIO-Expa.patch b/target/linux/ramips/patches-6.6/805-01-v6.9-pinctrl-Add-driver-for-Awinic-AW9523-B-I2C-GPIO-Expa.patch
new file mode 100644
index 0000000000..84b4571b48
--- /dev/null
+++ b/target/linux/ramips/patches-6.6/805-01-v6.9-pinctrl-Add-driver-for-Awinic-AW9523-B-I2C-GPIO-Expa.patch
@@ -0,0 +1,1190 @@
+From 576623d706613feec2392ef16b84e23a46200552 Mon Sep 17 00:00:00 2001
+From: AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
+Date: Fri, 1 Mar 2024 14:29:24 +0100
+Subject: [PATCH] pinctrl: Add driver for Awinic AW9523/B I2C GPIO Expander
+
+The Awinic AW9523(B) is a multi-function I2C gpio expander in a
+TQFN-24L package, featuring PWM (max 37mA per pin, or total max
+power 3.2Watts) for LED driving capability.
+
+It has two ports with 8 pins per port (for a total of 16 pins),
+configurable as either PWM with 1/256 stepping or GPIO input/output,
+1.8V logic input; each GPIO can be configured as input or output
+independently from each other.
+
+This IC also has an internal interrupt controller, which is capable
+of generating an interrupt for each GPIO, depending on the
+configuration, and will raise an interrupt on the INTN pin to
+advertise this to an external interrupt controller.
+
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
+Signed-off-by: David Bauer <mail@david-bauer.net>
+Link: https://lore.kernel.org/r/20210624214458.68716-2-mail@david-bauer.net
+Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Link: https://lore.kernel.org/r/20240301-awinic-aw9523-v8-1-7ec572f5dfb4@linaro.org
+---
+ drivers/pinctrl/Kconfig | 18 +
+ drivers/pinctrl/Makefile | 1 +
+ drivers/pinctrl/pinctrl-aw9523.c | 1118 ++++++++++++++++++++++++++++++
+ 3 files changed, 1137 insertions(+)
+ create mode 100644 drivers/pinctrl/pinctrl-aw9523.c
+
+--- a/drivers/pinctrl/Kconfig
++++ b/drivers/pinctrl/Kconfig
+@@ -127,6 +127,24 @@ config PINCTRL_AXP209
+ selected.
+ Say Y to enable pinctrl and GPIO support for the AXP209 PMIC.
+
++config PINCTRL_AW9523
++ bool "Awinic AW9523/AW9523B I2C GPIO expander pinctrl driver"
++ depends on OF && I2C
++ select PINMUX
++ select PINCONF
++ select GENERIC_PINCONF
++ select GPIOLIB
++ select GPIOLIB_IRQCHIP
++ select REGMAP
++ select REGMAP_I2C
++ help
++ The Awinic AW9523/AW9523B is a multi-function I2C GPIO
++ expander with PWM functionality. This driver bundles a
++ pinctrl driver to select the function muxing and a GPIO
++ driver to handle GPIO, when the GPIO function is selected.
++
++ Say yes to enable pinctrl and GPIO support for the AW9523(B).
++
+ config PINCTRL_BM1880
+ bool "Bitmain BM1880 Pinctrl driver"
+ depends on OF && (ARCH_BITMAIN || COMPILE_TEST)
+--- a/drivers/pinctrl/Makefile
++++ b/drivers/pinctrl/Makefile
+@@ -15,6 +15,7 @@ obj-$(CONFIG_PINCTRL_ARTPEC6) += pinctrl
+ obj-$(CONFIG_PINCTRL_AS3722) += pinctrl-as3722.o
+ obj-$(CONFIG_PINCTRL_AT91) += pinctrl-at91.o
+ obj-$(CONFIG_PINCTRL_AT91PIO4) += pinctrl-at91-pio4.o
++obj-$(CONFIG_PINCTRL_AW9523) += pinctrl-aw9523.o
+ obj-$(CONFIG_PINCTRL_AXP209) += pinctrl-axp209.o
+ obj-$(CONFIG_PINCTRL_BM1880) += pinctrl-bm1880.o
+ obj-$(CONFIG_PINCTRL_CY8C95X0) += pinctrl-cy8c95x0.o
+--- /dev/null
++++ b/drivers/pinctrl/pinctrl-aw9523.c
+@@ -0,0 +1,1118 @@
++// SPDX-License-Identifier: GPL-2.0-only
++/*
++ * Awinic AW9523B i2c pin controller driver
++ * Copyright (c) 2020, AngeloGioacchino Del Regno
++ * <angelogioacchino.delregno@somainline.org>
++ */
++
++#include <linux/bitfield.h>
++#include <linux/gpio/consumer.h>
++#include <linux/gpio/driver.h>
++#include <linux/i2c.h>
++#include <linux/init.h>
++#include <linux/interrupt.h>
++#include <linux/irq.h>
++#include <linux/mutex.h>
++#include <linux/module.h>
++#include <linux/pinctrl/pinconf.h>
++#include <linux/pinctrl/pinctrl.h>
++#include <linux/pinctrl/pinmux.h>
++#include <linux/pinctrl/pinconf-generic.h>
++#include <linux/property.h>
++#include <linux/regmap.h>
++#include <linux/regulator/consumer.h>
++#include <linux/slab.h>
++
++#define AW9523_MAX_FUNCS 2
++#define AW9523_NUM_PORTS 2
++#define AW9523_PINS_PER_PORT 8
++
++/*
++ * HW needs at least 20uS for reset and at least 1-2uS to recover from
++ * reset, but we have to account for eventual board quirks, if any:
++ * for this reason, keep reset asserted for 50uS and wait for 20uS
++ * to recover from the reset.
++ */
++#define AW9523_HW_RESET_US 50
++#define AW9523_HW_RESET_RECOVERY_US 20
++
++/* Port 0: P0_0...P0_7 - Port 1: P1_0...P1_7 */
++#define AW9523_PIN_TO_PORT(pin) (pin >> 3)
++#define AW9523_REG_IN_STATE(pin) (0x00 + AW9523_PIN_TO_PORT(pin))
++#define AW9523_REG_OUT_STATE(pin) (0x02 + AW9523_PIN_TO_PORT(pin))
++#define AW9523_REG_CONF_STATE(pin) (0x04 + AW9523_PIN_TO_PORT(pin))
++#define AW9523_REG_INTR_DIS(pin) (0x06 + AW9523_PIN_TO_PORT(pin))
++#define AW9523_REG_CHIPID 0x10
++#define AW9523_VAL_EXPECTED_CHIPID 0x23
++
++#define AW9523_REG_GCR 0x11
++#define AW9523_GCR_ISEL_MASK GENMASK(0, 1)
++#define AW9523_GCR_GPOMD_MASK BIT(4)
++
++#define AW9523_REG_PORT_MODE(pin) (0x12 + AW9523_PIN_TO_PORT(pin))
++#define AW9523_REG_SOFT_RESET 0x7f
++#define AW9523_VAL_RESET 0x00
++
++/*
++ * struct aw9523_irq - Interrupt controller structure
++ * @lock: mutex locking for the irq bus
++ * @irqchip: structure holding irqchip params
++ * @cached_gpio: stores the previous gpio status for bit comparison
++ */
++struct aw9523_irq {
++ struct mutex lock;
++ struct irq_chip *irqchip;
++ u16 cached_gpio;
++};
++
++/*
++ * struct aw9523_pinmux - Pin mux params
++ * @name: Name of the mux
++ * @grps: Groups of the mux
++ * @num_grps: Number of groups (sizeof array grps)
++ */
++struct aw9523_pinmux {
++ const char *name;
++ const char * const *grps;
++ const u8 num_grps;
++};
++
++/*
++ * struct aw9523 - Main driver structure
++ * @dev: device handle
++ * @regmap: regmap handle for current device
++ * @i2c_lock: Mutex lock for i2c operations
++ * @reset_gpio: Hardware reset (RSTN) signal GPIO
++ * @vio_vreg: VCC regulator (Optional)
++ * @pctl: pinctrl handle for current device
++ * @gpio: structure holding gpiochip params
++ * @irq: Interrupt controller structure
++ */
++struct aw9523 {
++ struct device *dev;
++ struct regmap *regmap;
++ struct mutex i2c_lock;
++ struct gpio_desc *reset_gpio;
++ struct regulator *vio_vreg;
++ struct pinctrl_dev *pctl;
++ struct gpio_chip gpio;
++ struct aw9523_irq *irq;
++};
++
++static const struct pinctrl_pin_desc aw9523_pins[] = {
++ /* Port 0 */
++ PINCTRL_PIN(0, "gpio0"),
++ PINCTRL_PIN(1, "gpio1"),
++ PINCTRL_PIN(2, "gpio2"),
++ PINCTRL_PIN(3, "gpio3"),
++ PINCTRL_PIN(4, "gpio4"),
++ PINCTRL_PIN(5, "gpio5"),
++ PINCTRL_PIN(6, "gpio6"),
++ PINCTRL_PIN(7, "gpio7"),
++
++ /* Port 1 */
++ PINCTRL_PIN(8, "gpio8"),
++ PINCTRL_PIN(9, "gpio9"),
++ PINCTRL_PIN(10, "gpio10"),
++ PINCTRL_PIN(11, "gpio11"),
++ PINCTRL_PIN(12, "gpio12"),
++ PINCTRL_PIN(13, "gpio13"),
++ PINCTRL_PIN(14, "gpio14"),
++ PINCTRL_PIN(15, "gpio15"),
++};
++
++static int aw9523_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
++{
++ return ARRAY_SIZE(aw9523_pins);
++}
++
++static const char *aw9523_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
++ unsigned int selector)
++{
++ return aw9523_pins[selector].name;
++}
++
++static int aw9523_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
++ unsigned int selector,
++ const unsigned int **pins,
++ unsigned int *num_pins)
++{
++ *pins = &aw9523_pins[selector].number;
++ *num_pins = 1;
++ return 0;
++}
++
++static const struct pinctrl_ops aw9523_pinctrl_ops = {
++ .get_groups_count = aw9523_pinctrl_get_groups_count,
++ .get_group_pins = aw9523_pinctrl_get_group_pins,
++ .get_group_name = aw9523_pinctrl_get_group_name,
++ .dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
++ .dt_free_map = pinconf_generic_dt_free_map,
++};
++
++static const char * const gpio_pwm_groups[] = {
++ "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5",
++ "gpio6", "gpio7", "gpio8", "gpio9", "gpio10", "gpio11",
++ "gpio12", "gpio13", "gpio14", "gpio15"
++};
++
++/* Warning: Do NOT reorder this array */
++static const struct aw9523_pinmux aw9523_pmx[] = {
++ {
++ .name = "pwm",
++ .grps = gpio_pwm_groups,
++ .num_grps = ARRAY_SIZE(gpio_pwm_groups),
++ },
++ {
++ .name = "gpio",
++ .grps = gpio_pwm_groups,
++ .num_grps = ARRAY_SIZE(gpio_pwm_groups),
++ },
++};
++
++static int aw9523_pmx_get_funcs_count(struct pinctrl_dev *pctl)
++{
++ return ARRAY_SIZE(aw9523_pmx);
++}
++
++static const char *aw9523_pmx_get_fname(struct pinctrl_dev *pctl,
++ unsigned int sel)
++{
++ return aw9523_pmx[sel].name;
++}
++
++static int aw9523_pmx_get_groups(struct pinctrl_dev *pctl, unsigned int sel,
++ const char * const **groups,
++ unsigned int * const num_groups)
++{
++ *groups = aw9523_pmx[sel].grps;
++ *num_groups = aw9523_pmx[sel].num_grps;
++ return 0;
++}
++
++static int aw9523_pmx_set_mux(struct pinctrl_dev *pctl, unsigned int fsel,
++ unsigned int grp)
++{
++ struct aw9523 *awi = pinctrl_dev_get_drvdata(pctl);
++ int ret, pin = aw9523_pins[grp].number % AW9523_PINS_PER_PORT;
++
++ if (fsel >= ARRAY_SIZE(aw9523_pmx))
++ return -EINVAL;
++
++ /*
++ * This maps directly to the aw9523_pmx array: programming a
++ * high bit means "gpio" and a low bit means "pwm".
++ */
++ mutex_lock(&awi->i2c_lock);
++ ret = regmap_update_bits(awi->regmap, AW9523_REG_PORT_MODE(pin),
++ BIT(pin), (fsel ? BIT(pin) : 0));
++ mutex_unlock(&awi->i2c_lock);
++ return ret;
++}
++
++static const struct pinmux_ops aw9523_pinmux_ops = {
++ .get_functions_count = aw9523_pmx_get_funcs_count,
++ .get_function_name = aw9523_pmx_get_fname,
++ .get_function_groups = aw9523_pmx_get_groups,
++ .set_mux = aw9523_pmx_set_mux,
++};
++
++static int aw9523_pcfg_param_to_reg(enum pin_config_param pcp, int pin, u8 *r)
++{
++ u8 reg;
++
++ switch (pcp) {
++ case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
++ case PIN_CONFIG_BIAS_PULL_DOWN:
++ case PIN_CONFIG_BIAS_PULL_UP:
++ reg = AW9523_REG_IN_STATE(pin);
++ break;
++ case PIN_CONFIG_DRIVE_OPEN_DRAIN:
++ case PIN_CONFIG_DRIVE_PUSH_PULL:
++ reg = AW9523_REG_GCR;
++ break;
++ case PIN_CONFIG_INPUT_ENABLE:
++ case PIN_CONFIG_OUTPUT_ENABLE:
++ reg = AW9523_REG_CONF_STATE(pin);
++ break;
++ case PIN_CONFIG_OUTPUT:
++ reg = AW9523_REG_OUT_STATE(pin);
++ break;
++ default:
++ return -EOPNOTSUPP;
++ }
++ *r = reg;
++
++ return 0;
++}
++
++static int aw9523_pconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
++ unsigned long *config)
++{
++ struct aw9523 *awi = pinctrl_dev_get_drvdata(pctldev);
++ enum pin_config_param param = pinconf_to_config_param(*config);
++ int regbit = pin % AW9523_PINS_PER_PORT;
++ unsigned int val;
++ u8 reg;
++ int rc;
++
++ rc = aw9523_pcfg_param_to_reg(param, pin, &reg);
++ if (rc)
++ return rc;
++
++ mutex_lock(&awi->i2c_lock);
++ rc = regmap_read(awi->regmap, reg, &val);
++ mutex_unlock(&awi->i2c_lock);
++ if (rc)
++ return rc;
++
++ switch (param) {
++ case PIN_CONFIG_BIAS_PULL_UP:
++ case PIN_CONFIG_INPUT_ENABLE:
++ case PIN_CONFIG_OUTPUT:
++ val &= BIT(regbit);
++ break;
++ case PIN_CONFIG_BIAS_PULL_DOWN:
++ case PIN_CONFIG_OUTPUT_ENABLE:
++ val &= BIT(regbit);
++ val = !val;
++ break;
++ case PIN_CONFIG_DRIVE_OPEN_DRAIN:
++ if (pin >= AW9523_PINS_PER_PORT)
++ val = 0;
++ else
++ val = !FIELD_GET(AW9523_GCR_GPOMD_MASK, val);
++ break;
++ case PIN_CONFIG_DRIVE_PUSH_PULL:
++ if (pin >= AW9523_PINS_PER_PORT)
++ val = 1;
++ else
++ val = FIELD_GET(AW9523_GCR_GPOMD_MASK, val);
++ break;
++ default:
++ return -EOPNOTSUPP;
++ }
++ if (val < 1)
++ return -EINVAL;
++
++ *config = pinconf_to_config_packed(param, !!val);
++
++ return rc;
++}
++
++static int aw9523_pconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
++ unsigned long *configs, unsigned int num_configs)
++{
++ struct aw9523 *awi = pinctrl_dev_get_drvdata(pctldev);
++ enum pin_config_param param;
++ int regbit = pin % AW9523_PINS_PER_PORT;
++ u32 arg;
++ u8 reg;
++ unsigned int mask, val;
++ int i, rc;
++
++ mutex_lock(&awi->i2c_lock);
++ for (i = 0; i < num_configs; i++) {
++ param = pinconf_to_config_param(configs[i]);
++ arg = pinconf_to_config_argument(configs[i]);
++
++ rc = aw9523_pcfg_param_to_reg(param, pin, &reg);
++ if (rc)
++ goto end;
++
++ switch (param) {
++ case PIN_CONFIG_OUTPUT:
++ /* First, enable pin output */
++ rc = regmap_update_bits(awi->regmap,
++ AW9523_REG_CONF_STATE(pin),
++ BIT(regbit), 0);
++ if (rc)
++ goto end;
++
++ /* Then, fall through to config output level */
++ fallthrough;
++ case PIN_CONFIG_OUTPUT_ENABLE:
++ arg = !arg;
++ fallthrough;
++ case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
++ case PIN_CONFIG_BIAS_PULL_DOWN:
++ case PIN_CONFIG_BIAS_PULL_UP:
++ case PIN_CONFIG_INPUT_ENABLE:
++ mask = BIT(regbit);
++ val = arg ? BIT(regbit) : 0;
++ break;
++ case PIN_CONFIG_DRIVE_OPEN_DRAIN:
++ /* Open-Drain is supported only on port 0 */
++ if (pin >= AW9523_PINS_PER_PORT) {
++ rc = -EOPNOTSUPP;
++ goto end;
++ }
++ mask = AW9523_GCR_GPOMD_MASK;
++ val = 0;
++ break;
++ case PIN_CONFIG_DRIVE_PUSH_PULL:
++ /* Port 1 is always Push-Pull */
++ if (pin >= AW9523_PINS_PER_PORT) {
++ mask = 0;
++ val = 0;
++ continue;
++ }
++ mask = AW9523_GCR_GPOMD_MASK;
++ val = AW9523_GCR_GPOMD_MASK;
++ break;
++ default:
++ rc = -EOPNOTSUPP;
++ goto end;
++ }
++
++ rc = regmap_update_bits(awi->regmap, reg, mask, val);
++ if (rc)
++ goto end;
++ }
++end:
++ mutex_unlock(&awi->i2c_lock);
++ return rc;
++}
++
++static const struct pinconf_ops aw9523_pinconf_ops = {
++ .pin_config_get = aw9523_pconf_get,
++ .pin_config_set = aw9523_pconf_set,
++ .is_generic = true,
++};
++
++/*
++ * aw9523_get_pin_direction - Get pin direction
++ * @regmap: Regmap structure
++ * @pin: gpiolib pin number
++ * @n: pin index in port register
++ *
++ * Return: Pin direction for success or negative number for error
++ */
++static int aw9523_get_pin_direction(struct regmap *regmap, u8 pin, u8 n)
++{
++ int ret;
++
++ ret = regmap_test_bits(regmap, AW9523_REG_CONF_STATE(pin), BIT(n));
++ if (ret < 0)
++ return ret;
++
++ return ret ? GPIO_LINE_DIRECTION_IN : GPIO_LINE_DIRECTION_OUT;
++}
++
++/*
++ * aw9523_get_port_state - Get input or output state for entire port
++ * @regmap: Regmap structure
++ * @pin: gpiolib pin number
++ * @regbit: hw pin index, used to retrieve port number
++ * @state: returned port state
++ *
++ * Return: Zero for success or negative number for error
++ */
++static int aw9523_get_port_state(struct regmap *regmap, u8 pin,
++ u8 regbit, unsigned int *state)
++{
++ u8 reg;
++ int dir;
++
++ dir = aw9523_get_pin_direction(regmap, pin, regbit);
++ if (dir < 0)
++ return dir;
++
++ if (dir == GPIO_LINE_DIRECTION_IN)
++ reg = AW9523_REG_IN_STATE(pin);
++ else
++ reg = AW9523_REG_OUT_STATE(pin);
++
++ return regmap_read(regmap, reg, state);
++}
++
++static int aw9523_gpio_irq_type(struct irq_data *d, unsigned int type)
++{
++ switch (type) {
++ case IRQ_TYPE_NONE:
++ case IRQ_TYPE_EDGE_BOTH:
++ return 0;
++ default:
++ return -EINVAL;
++ };
++}
++
++/*
++ * aw9523_irq_mask - Mask interrupt
++ * @d: irq data
++ *
++ * Sets which interrupt to mask in the bitmap;
++ * The interrupt will be masked when unlocking the irq bus.
++ */
++static void aw9523_irq_mask(struct irq_data *d)
++{
++ struct aw9523 *awi = gpiochip_get_data(irq_data_get_irq_chip_data(d));
++ unsigned int n = d->hwirq % AW9523_PINS_PER_PORT;
++
++ regmap_update_bits(awi->regmap,
++ AW9523_REG_INTR_DIS(d->hwirq),
++ BIT(n), BIT(n));
++ gpiochip_disable_irq(&awi->gpio, irqd_to_hwirq(d));
++}
++
++/*
++ * aw9523_irq_unmask - Unmask interrupt
++ * @d: irq data
++ *
++ * Sets which interrupt to unmask in the bitmap;
++ * The interrupt will be masked when unlocking the irq bus.
++ */
++static void aw9523_irq_unmask(struct irq_data *d)
++{
++ struct aw9523 *awi = gpiochip_get_data(irq_data_get_irq_chip_data(d));
++ unsigned int n = d->hwirq % AW9523_PINS_PER_PORT;
++
++ gpiochip_enable_irq(&awi->gpio, irqd_to_hwirq(d));
++ regmap_update_bits(awi->regmap,
++ AW9523_REG_INTR_DIS(d->hwirq),
++ BIT(n), 0);
++}
++
++static irqreturn_t aw9523_irq_thread_func(int irq, void *dev_id)
++{
++ struct aw9523 *awi = (struct aw9523 *)dev_id;
++ unsigned long n, val = 0;
++ unsigned long changed_gpio;
++ unsigned int tmp, port_pin, i, ret;
++
++ for (i = 0; i < AW9523_NUM_PORTS; i++) {
++ port_pin = i * AW9523_PINS_PER_PORT;
++ ret = regmap_read(awi->regmap,
++ AW9523_REG_IN_STATE(port_pin),
++ &tmp);
++ if (ret)
++ return ret;
++ val |= (u8)tmp << (i * 8);
++ }
++
++ /* Handle GPIO input release interrupt as well */
++ changed_gpio = awi->irq->cached_gpio ^ val;
++ awi->irq->cached_gpio = val;
++
++ /*
++ * To avoid up to four *slow* i2c reads from any driver hooked
++ * up to our interrupts, just check for the irq_find_mapping
++ * result: if the interrupt is not mapped, then we don't want
++ * to care about it.
++ */
++ for_each_set_bit(n, &changed_gpio, awi->gpio.ngpio) {
++ tmp = irq_find_mapping(awi->gpio.irq.domain, n);
++ if (tmp <= 0)
++ continue;
++ handle_nested_irq(tmp);
++ }
++
++ return IRQ_HANDLED;
++}
++
++/*
++ * aw9523_irq_bus_lock - Grab lock for interrupt operation
++ * @d: irq data
++ */
++static void aw9523_irq_bus_lock(struct irq_data *d)
++{
++ struct aw9523 *awi = gpiochip_get_data(irq_data_get_irq_chip_data(d));
++
++ mutex_lock(&awi->irq->lock);
++ regcache_cache_only(awi->regmap, true);
++}
++
++/*
++ * aw9523_irq_bus_sync_unlock - Synchronize state and unlock
++ * @d: irq data
++ *
++ * Writes the interrupt mask bits (found in the bit map) to the
++ * hardware, then unlocks the bus.
++ */
++static void aw9523_irq_bus_sync_unlock(struct irq_data *d)
++{
++ struct aw9523 *awi = gpiochip_get_data(irq_data_get_irq_chip_data(d));
++
++ regcache_cache_only(awi->regmap, false);
++ regcache_sync(awi->regmap);
++ mutex_unlock(&awi->irq->lock);
++}
++
++static int aw9523_gpio_get_direction(struct gpio_chip *chip,
++ unsigned int offset)
++{
++ struct aw9523 *awi = gpiochip_get_data(chip);
++ u8 regbit = offset % AW9523_PINS_PER_PORT;
++ int ret;
++
++ mutex_lock(&awi->i2c_lock);
++ ret = aw9523_get_pin_direction(awi->regmap, offset, regbit);
++ mutex_unlock(&awi->i2c_lock);
++
++ return ret;
++}
++
++static int aw9523_gpio_get(struct gpio_chip *chip, unsigned int offset)
++{
++ struct aw9523 *awi = gpiochip_get_data(chip);
++ u8 regbit = offset % AW9523_PINS_PER_PORT;
++ unsigned int val;
++ int ret;
++
++ mutex_lock(&awi->i2c_lock);
++ ret = aw9523_get_port_state(awi->regmap, offset, regbit, &val);
++ mutex_unlock(&awi->i2c_lock);
++ if (ret)
++ return ret;
++
++ return !!(val & BIT(regbit));
++}
++
++/**
++ * _aw9523_gpio_get_multiple - Get I/O state for an entire port
++ * @regmap: Regmap structure
++ * @pin: gpiolib pin number
++ * @regbit: hw pin index, used to retrieve port number
++ * @state: returned port I/O state
++ *
++ * Return: Zero for success or negative number for error
++ */
++static int _aw9523_gpio_get_multiple(struct aw9523 *awi, u8 regbit,
++ u8 *state, u8 mask)
++{
++ u32 dir_in, val;
++ u8 m;
++ int ret;
++
++ /* Registers are 8-bits wide */
++ ret = regmap_read(awi->regmap, AW9523_REG_CONF_STATE(regbit), &dir_in);
++ if (ret)
++ return ret;
++ *state = 0;
++
++ m = mask & dir_in;
++ if (m) {
++ ret = regmap_read(awi->regmap, AW9523_REG_IN_STATE(regbit),
++ &val);
++ if (ret)
++ return ret;
++ *state |= (u8)val & m;
++ }
++
++ m = mask & ~dir_in;
++ if (m) {
++ ret = regmap_read(awi->regmap, AW9523_REG_OUT_STATE(regbit),
++ &val);
++ if (ret)
++ return ret;
++ *state |= (u8)val & m;
++ }
++
++ return 0;
++}
++
++static int aw9523_gpio_get_multiple(struct gpio_chip *chip,
++ unsigned long *mask,
++ unsigned long *bits)
++{
++ struct aw9523 *awi = gpiochip_get_data(chip);
++ u8 m, state = 0;
++ int ret;
++
++ mutex_lock(&awi->i2c_lock);
++
++ /* Port 0 (gpio 0-7) */
++ m = *mask & U8_MAX;
++ if (m) {
++ ret = _aw9523_gpio_get_multiple(awi, 0, &state, m);
++ if (ret)
++ goto out;
++ }
++ *bits = state;
++
++ /* Port 1 (gpio 8-15) */
++ m = (*mask >> 8) & U8_MAX;
++ if (m) {
++ ret = _aw9523_gpio_get_multiple(awi, AW9523_PINS_PER_PORT,
++ &state, m);
++ if (ret)
++ goto out;
++
++ *bits |= (state << 8);
++ }
++out:
++ mutex_unlock(&awi->i2c_lock);
++ return ret;
++}
++
++static void aw9523_gpio_set_multiple(struct gpio_chip *chip,
++ unsigned long *mask,
++ unsigned long *bits)
++{
++ struct aw9523 *awi = gpiochip_get_data(chip);
++ u8 mask_lo, mask_hi, bits_lo, bits_hi;
++ unsigned int reg;
++ int ret = 0;
++
++ mask_lo = *mask & U8_MAX;
++ mask_hi = (*mask >> 8) & U8_MAX;
++ mutex_lock(&awi->i2c_lock);
++ if (mask_hi) {
++ reg = AW9523_REG_OUT_STATE(AW9523_PINS_PER_PORT);
++ bits_hi = (*bits >> 8) & U8_MAX;
++
++ ret = regmap_write_bits(awi->regmap, reg, mask_hi, bits_hi);
++ if (ret) {
++ dev_warn(awi->dev, "Cannot write port1 out level\n");
++ goto out;
++ }
++ }
++ if (mask_lo) {
++ reg = AW9523_REG_OUT_STATE(0);
++ bits_lo = *bits & U8_MAX;
++ ret = regmap_write_bits(awi->regmap, reg, mask_lo, bits_lo);
++ if (ret)
++ dev_warn(awi->dev, "Cannot write port0 out level\n");
++ }
++out:
++ mutex_unlock(&awi->i2c_lock);
++}
++
++static void aw9523_gpio_set(struct gpio_chip *chip,
++ unsigned int offset, int value)
++{
++ struct aw9523 *awi = gpiochip_get_data(chip);
++ u8 regbit = offset % AW9523_PINS_PER_PORT;
++
++ mutex_lock(&awi->i2c_lock);
++ regmap_update_bits(awi->regmap, AW9523_REG_OUT_STATE(offset),
++ BIT(regbit), value ? BIT(regbit) : 0);
++ mutex_unlock(&awi->i2c_lock);
++}
++
++
++static int aw9523_direction_input(struct gpio_chip *chip, unsigned int offset)
++{
++ struct aw9523 *awi = gpiochip_get_data(chip);
++ u8 regbit = offset % AW9523_PINS_PER_PORT;
++ int ret;
++
++ mutex_lock(&awi->i2c_lock);
++ ret = regmap_update_bits(awi->regmap, AW9523_REG_CONF_STATE(offset),
++ BIT(regbit), BIT(regbit));
++ mutex_unlock(&awi->i2c_lock);
++
++ return ret;
++}
++
++static int aw9523_direction_output(struct gpio_chip *chip,
++ unsigned int offset, int value)
++{
++ struct aw9523 *awi = gpiochip_get_data(chip);
++ u8 regbit = offset % AW9523_PINS_PER_PORT;
++ int ret;
++
++ mutex_lock(&awi->i2c_lock);
++ ret = regmap_update_bits(awi->regmap, AW9523_REG_OUT_STATE(offset),
++ BIT(regbit), value ? BIT(regbit) : 0);
++ if (ret)
++ goto end;
++
++ ret = regmap_update_bits(awi->regmap, AW9523_REG_CONF_STATE(offset),
++ BIT(regbit), 0);
++end:
++ mutex_unlock(&awi->i2c_lock);
++ return ret;
++}
++
++static int aw9523_drive_reset_gpio(struct aw9523 *awi)
++{
++ unsigned int chip_id;
++ int ret;
++
++ /*
++ * If the chip is already configured for any reason, then we
++ * will probably succeed in sending the soft reset signal to
++ * the hardware through I2C: this operation takes less time
++ * compared to a full HW reset and it gives the same results.
++ */
++ ret = regmap_write(awi->regmap, AW9523_REG_SOFT_RESET, 0);
++ if (ret == 0)
++ goto done;
++
++ dev_dbg(awi->dev, "Cannot execute soft reset: trying hard reset\n");
++ ret = gpiod_direction_output(awi->reset_gpio, 0);
++ if (ret)
++ return ret;
++
++ /* The reset pulse has to be longer than 20uS due to deglitch */
++ usleep_range(AW9523_HW_RESET_US, AW9523_HW_RESET_US + 1);
++
++ ret = gpiod_direction_output(awi->reset_gpio, 1);
++ if (ret)
++ return ret;
++done:
++ /* The HW needs at least 1uS to reliably recover after reset */
++ usleep_range(AW9523_HW_RESET_RECOVERY_US,
++ AW9523_HW_RESET_RECOVERY_US + 1);
++
++ /* Check the ChipID */
++ ret = regmap_read(awi->regmap, AW9523_REG_CHIPID, &chip_id);
++ if (ret) {
++ dev_err(awi->dev, "Cannot read Chip ID: %d\n", ret);
++ return ret;
++ }
++ if (chip_id != AW9523_VAL_EXPECTED_CHIPID) {
++ dev_err(awi->dev, "Bad ChipID; read 0x%x, expected 0x%x\n",
++ chip_id, AW9523_VAL_EXPECTED_CHIPID);
++ return -EINVAL;
++ }
++
++ return 0;
++}
++
++static int aw9523_hw_reset(struct aw9523 *awi)
++{
++ int ret, max_retries = 2;
++
++ /* Sometimes the chip needs more than one reset cycle */
++ do {
++ ret = aw9523_drive_reset_gpio(awi);
++ if (ret == 0)
++ break;
++ max_retries--;
++ } while (max_retries);
++
++ return ret;
++}
++
++static int aw9523_init_gpiochip(struct aw9523 *awi, unsigned int npins)
++{
++ struct device *dev = awi->dev;
++ struct gpio_chip *gc = &awi->gpio;
++
++ gc->label = devm_kstrdup(dev, dev_name(dev), GFP_KERNEL);
++ if (!gc->label)
++ return -ENOMEM;
++
++ gc->base = -1;
++ gc->ngpio = npins;
++ gc->get_direction = aw9523_gpio_get_direction;
++ gc->direction_input = aw9523_direction_input;
++ gc->direction_output = aw9523_direction_output;
++ gc->get = aw9523_gpio_get;
++ gc->get_multiple = aw9523_gpio_get_multiple;
++ gc->set = aw9523_gpio_set;
++ gc->set_multiple = aw9523_gpio_set_multiple;
++ gc->set_config = gpiochip_generic_config;
++ gc->parent = dev;
++ gc->owner = THIS_MODULE;
++ gc->can_sleep = false;
++
++ return 0;
++}
++
++static const struct irq_chip aw9523_irq_chip = {
++ .name = "aw9523",
++ .irq_mask = aw9523_irq_mask,
++ .irq_unmask = aw9523_irq_unmask,
++ .irq_bus_lock = aw9523_irq_bus_lock,
++ .irq_bus_sync_unlock = aw9523_irq_bus_sync_unlock,
++ .irq_set_type = aw9523_gpio_irq_type,
++ .flags = IRQCHIP_IMMUTABLE,
++ GPIOCHIP_IRQ_RESOURCE_HELPERS,
++};
++
++static int aw9523_init_irq(struct aw9523 *awi, int irq)
++{
++ struct device *dev = awi->dev;
++ struct gpio_irq_chip *girq;
++ struct irq_chip *irqchip;
++ int ret;
++
++ if (!device_property_read_bool(dev, "interrupt-controller"))
++ return 0;
++
++ irqchip = devm_kzalloc(dev, sizeof(*irqchip), GFP_KERNEL);
++ if (!irqchip)
++ return -ENOMEM;
++
++ awi->irq = devm_kzalloc(dev, sizeof(*awi->irq), GFP_KERNEL);
++ if (!awi->irq)
++ return -ENOMEM;
++
++ awi->irq->irqchip = irqchip;
++ mutex_init(&awi->irq->lock);
++
++ ret = devm_request_threaded_irq(dev, irq, NULL, aw9523_irq_thread_func,
++ IRQF_ONESHOT, dev_name(dev), awi);
++ if (ret) {
++ dev_err(dev, "Failed to request irq %d\n", irq);
++ return ret;
++ }
++
++ girq = &awi->gpio.irq;
++ gpio_irq_chip_set_chip(girq, &aw9523_irq_chip);
++ girq->parent_handler = NULL;
++ girq->num_parents = 0;
++ girq->parents = NULL;
++ girq->default_type = IRQ_TYPE_EDGE_BOTH;
++ girq->handler = handle_simple_irq;
++ girq->threaded = true;
++
++ return 0;
++}
++
++static bool aw9523_is_reg_hole(unsigned int reg)
++{
++ return (reg > AW9523_REG_PORT_MODE(AW9523_PINS_PER_PORT) &&
++ reg < AW9523_REG_SOFT_RESET) ||
++ (reg > AW9523_REG_INTR_DIS(AW9523_PINS_PER_PORT) &&
++ reg < AW9523_REG_CHIPID);
++}
++
++static bool aw9523_readable_reg(struct device *dev, unsigned int reg)
++{
++ /* All available registers (minus holes) can be read */
++ return !aw9523_is_reg_hole(reg);
++}
++
++static bool aw9523_volatile_reg(struct device *dev, unsigned int reg)
++{
++ return aw9523_is_reg_hole(reg) ||
++ reg == AW9523_REG_IN_STATE(0) ||
++ reg == AW9523_REG_IN_STATE(AW9523_PINS_PER_PORT) ||
++ reg == AW9523_REG_CHIPID ||
++ reg == AW9523_REG_SOFT_RESET;
++}
++
++static bool aw9523_writeable_reg(struct device *dev, unsigned int reg)
++{
++ return !aw9523_is_reg_hole(reg) && reg != AW9523_REG_CHIPID;
++}
++
++static bool aw9523_precious_reg(struct device *dev, unsigned int reg)
++{
++ /* Reading AW9523_REG_IN_STATE clears interrupt status */
++ return aw9523_is_reg_hole(reg) ||
++ reg == AW9523_REG_IN_STATE(0) ||
++ reg == AW9523_REG_IN_STATE(AW9523_PINS_PER_PORT);
++}
++
++static const struct regmap_config aw9523_regmap = {
++ .reg_bits = 8,
++ .val_bits = 8,
++ .reg_stride = 1,
++
++ .precious_reg = aw9523_precious_reg,
++ .readable_reg = aw9523_readable_reg,
++ .volatile_reg = aw9523_volatile_reg,
++ .writeable_reg = aw9523_writeable_reg,
++
++ .cache_type = REGCACHE_FLAT,
++ .disable_locking = true,
++
++ .num_reg_defaults_raw = AW9523_REG_SOFT_RESET,
++};
++
++static int aw9523_hw_init(struct aw9523 *awi)
++{
++ u8 p1_pin = AW9523_PINS_PER_PORT;
++ unsigned int val;
++ int ret;
++
++ /* No register caching during initialization */
++ regcache_cache_bypass(awi->regmap, true);
++
++ /* Bring up the chip */
++ ret = aw9523_hw_reset(awi);
++ if (ret) {
++ dev_err(awi->dev, "HW Reset failed: %d\n", ret);
++ return ret;
++ }
++
++ /*
++ * This is the expected chip and it is running: it's time to
++ * set a safe default configuration in case the user doesn't
++ * configure (all of the available) pins in this chip.
++ * P.S.: The writes order doesn't matter.
++ */
++
++ /* Set all pins as GPIO */
++ ret = regmap_write(awi->regmap, AW9523_REG_PORT_MODE(0), U8_MAX);
++ if (ret)
++ return ret;
++ ret = regmap_write(awi->regmap, AW9523_REG_PORT_MODE(p1_pin), U8_MAX);
++ if (ret)
++ return ret;
++
++ /* Set Open-Drain mode on Port 0 (Port 1 is always P-P) */
++ ret = regmap_write(awi->regmap, AW9523_REG_GCR, 0);
++ if (ret)
++ return ret;
++
++ /* Set all pins as inputs */
++ ret = regmap_write(awi->regmap, AW9523_REG_CONF_STATE(0), U8_MAX);
++ if (ret)
++ return ret;
++ ret = regmap_write(awi->regmap, AW9523_REG_CONF_STATE(p1_pin), U8_MAX);
++ if (ret)
++ return ret;
++
++ /* Disable all interrupts to avoid unreasoned wakeups */
++ ret = regmap_write(awi->regmap, AW9523_REG_INTR_DIS(0), U8_MAX);
++ if (ret)
++ return ret;
++ ret = regmap_write(awi->regmap, AW9523_REG_INTR_DIS(p1_pin), U8_MAX);
++ if (ret)
++ return ret;
++
++ /* Clear setup-generated interrupts by performing a port state read */
++ ret = aw9523_get_port_state(awi->regmap, 0, 0, &val);
++ if (ret)
++ return ret;
++ ret = aw9523_get_port_state(awi->regmap, p1_pin, 0, &val);
++ if (ret)
++ return ret;
++
++ /* Everything went fine: activate and reinitialize register cache */
++ regcache_cache_bypass(awi->regmap, false);
++ return regmap_reinit_cache(awi->regmap, &aw9523_regmap);
++}
++
++static int aw9523_probe(struct i2c_client *client)
++{
++ struct device *dev = &client->dev;
++ struct pinctrl_desc *pdesc;
++ struct aw9523 *awi;
++ int ret;
++
++ awi = devm_kzalloc(dev, sizeof(*awi), GFP_KERNEL);
++ if (!awi)
++ return -ENOMEM;
++
++ i2c_set_clientdata(client, awi);
++
++ awi->dev = dev;
++ awi->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
++ if (IS_ERR(awi->reset_gpio))
++ return PTR_ERR(awi->reset_gpio);
++ gpiod_set_consumer_name(awi->reset_gpio, "aw9523 reset");
++
++ awi->regmap = devm_regmap_init_i2c(client, &aw9523_regmap);
++ if (IS_ERR(awi->regmap))
++ return PTR_ERR(awi->regmap);
++
++ awi->vio_vreg = devm_regulator_get_optional(dev, "vio");
++ if (IS_ERR(awi->vio_vreg)) {
++ if (PTR_ERR(awi->vio_vreg) == -EPROBE_DEFER)
++ return -EPROBE_DEFER;
++ awi->vio_vreg = NULL;
++ } else {
++ ret = regulator_enable(awi->vio_vreg);
++ if (ret)
++ return ret;
++ }
++
++ mutex_init(&awi->i2c_lock);
++ lockdep_set_subclass(&awi->i2c_lock,
++ i2c_adapter_depth(client->adapter));
++
++ pdesc = devm_kzalloc(dev, sizeof(*pdesc), GFP_KERNEL);
++ if (!pdesc)
++ return -ENOMEM;
++
++ ret = aw9523_hw_init(awi);
++ if (ret)
++ goto err_disable_vregs;
++
++ pdesc->name = dev_name(dev);
++ pdesc->owner = THIS_MODULE;
++ pdesc->pctlops = &aw9523_pinctrl_ops;
++ pdesc->pmxops = &aw9523_pinmux_ops;
++ pdesc->confops = &aw9523_pinconf_ops;
++ pdesc->pins = aw9523_pins;
++ pdesc->npins = ARRAY_SIZE(aw9523_pins);
++
++ ret = aw9523_init_gpiochip(awi, pdesc->npins);
++ if (ret)
++ goto err_disable_vregs;
++
++ if (client->irq) {
++ ret = aw9523_init_irq(awi, client->irq);
++ if (ret)
++ goto err_disable_vregs;
++ }
++
++ awi->pctl = devm_pinctrl_register(dev, pdesc, awi);
++ if (IS_ERR(awi->pctl)) {
++ ret = PTR_ERR(awi->pctl);
++ dev_err(dev, "Cannot register pinctrl: %d", ret);
++ goto err_disable_vregs;
++ }
++
++ ret = devm_gpiochip_add_data(dev, &awi->gpio, awi);
++ if (ret)
++ goto err_disable_vregs;
++
++ return ret;
++
++err_disable_vregs:
++ if (awi->vio_vreg)
++ regulator_disable(awi->vio_vreg);
++ mutex_destroy(&awi->i2c_lock);
++ return ret;
++}
++
++static void aw9523_remove(struct i2c_client *client)
++{
++ struct aw9523 *awi = i2c_get_clientdata(client);
++ int ret;
++
++ if (!awi)
++ return;
++
++ /*
++ * If the chip VIO is connected to a regulator that we can turn
++ * off, life is easy... otherwise, reinitialize the chip and
++ * set the pins to hardware defaults before removing the driver
++ * to leave it in a clean, safe and predictable state.
++ */
++ if (awi->vio_vreg) {
++ regulator_disable(awi->vio_vreg);
++ } else {
++ mutex_lock(&awi->i2c_lock);
++ ret = aw9523_hw_init(awi);
++ mutex_unlock(&awi->i2c_lock);
++ if (ret)
++ return;
++ }
++
++ mutex_destroy(&awi->i2c_lock);
++}
++
++static const struct i2c_device_id aw9523_i2c_id_table[] = {
++ { "aw9523_i2c", 0 },
++ { }
++};
++MODULE_DEVICE_TABLE(i2c, aw9523_i2c_id_table);
++
++static const struct of_device_id of_aw9523_i2c_match[] = {
++ { .compatible = "awinic,aw9523-pinctrl", },
++};
++MODULE_DEVICE_TABLE(of, of_aw9523_i2c_match);
++
++static struct i2c_driver aw9523_driver = {
++ .driver = {
++ .name = "aw9523-pinctrl",
++ .of_match_table = of_aw9523_i2c_match,
++ },
++ .probe = aw9523_probe,
++ .remove = aw9523_remove,
++ .id_table = aw9523_i2c_id_table,
++};
++module_i2c_driver(aw9523_driver);
++
++MODULE_DESCRIPTION("Awinic AW9523 I2C GPIO Expander driver");
++MODULE_AUTHOR("AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>");
++MODULE_LICENSE("GPL v2");
diff --git a/target/linux/ramips/patches-6.6/805-02-v6.9-pinctrl-aw9523-Add-proper-terminator.patch b/target/linux/ramips/patches-6.6/805-02-v6.9-pinctrl-aw9523-Add-proper-terminator.patch
new file mode 100644
index 0000000000..193c797c21
--- /dev/null
+++ b/target/linux/ramips/patches-6.6/805-02-v6.9-pinctrl-aw9523-Add-proper-terminator.patch
@@ -0,0 +1,26 @@
+From 52279c3d50d964c646692c42a0db87ef7bb451cc Mon Sep 17 00:00:00 2001
+From: Linus Walleij <linus.walleij@linaro.org>
+Date: Wed, 6 Mar 2024 08:54:25 +0100
+Subject: [PATCH] pinctrl: aw9523: Add proper terminator
+
+The of_device_id array needs to be terminated with a NULL
+entry.
+
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202403061147.85XYVsk3-lkp@intel.com/
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Link: https://lore.kernel.org/r/20240306-fix-aw9523-terminator-v1-1-13f90f87a7f6@linaro.org
+---
+ drivers/pinctrl/pinctrl-aw9523.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/pinctrl/pinctrl-aw9523.c
++++ b/drivers/pinctrl/pinctrl-aw9523.c
+@@ -1099,6 +1099,7 @@ MODULE_DEVICE_TABLE(i2c, aw9523_i2c_id_t
+
+ static const struct of_device_id of_aw9523_i2c_match[] = {
+ { .compatible = "awinic,aw9523-pinctrl", },
++ { }
+ };
+ MODULE_DEVICE_TABLE(of, of_aw9523_i2c_match);
+
diff --git a/target/linux/ramips/patches-6.6/805-03-v6.10-pinctrl-aw9523-Destroy-mutex-on-remove.patch b/target/linux/ramips/patches-6.6/805-03-v6.10-pinctrl-aw9523-Destroy-mutex-on-remove.patch
new file mode 100644
index 0000000000..97d262451e
--- /dev/null
+++ b/target/linux/ramips/patches-6.6/805-03-v6.10-pinctrl-aw9523-Destroy-mutex-on-remove.patch
@@ -0,0 +1,41 @@
+From e5e8a58023707472e5dbe9bc7b473a8703b401e0 Mon Sep 17 00:00:00 2001
+From: Andy Shevchenko <andy.shevchenko@gmail.com>
+Date: Fri, 29 Mar 2024 12:55:15 +0200
+Subject: [PATCH] pinctrl: aw9523: Destroy mutex on ->remove()
+
+If aw9523_hw_init() fails on ->remove() the mutex left alive.
+Destroy it in that case as well. While at it, remove never
+true check at the beginning of the function.
+
+Signed-off-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Message-ID: <20240329105634.712457-2-andy.shevchenko@gmail.com>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ drivers/pinctrl/pinctrl-aw9523.c | 8 +-------
+ 1 file changed, 1 insertion(+), 7 deletions(-)
+
+--- a/drivers/pinctrl/pinctrl-aw9523.c
++++ b/drivers/pinctrl/pinctrl-aw9523.c
+@@ -1067,10 +1067,6 @@ err_disable_vregs:
+ static void aw9523_remove(struct i2c_client *client)
+ {
+ struct aw9523 *awi = i2c_get_clientdata(client);
+- int ret;
+-
+- if (!awi)
+- return;
+
+ /*
+ * If the chip VIO is connected to a regulator that we can turn
+@@ -1082,10 +1078,8 @@ static void aw9523_remove(struct i2c_cli
+ regulator_disable(awi->vio_vreg);
+ } else {
+ mutex_lock(&awi->i2c_lock);
+- ret = aw9523_hw_init(awi);
++ aw9523_hw_init(awi);
+ mutex_unlock(&awi->i2c_lock);
+- if (ret)
+- return;
+ }
+
+ mutex_destroy(&awi->i2c_lock);
diff --git a/target/linux/ramips/patches-6.6/805-04-v6.10-pinctrl-aw9523-Use-correct-error-code-for-not-suppor.patch b/target/linux/ramips/patches-6.6/805-04-v6.10-pinctrl-aw9523-Use-correct-error-code-for-not-suppor.patch
new file mode 100644
index 0000000000..1217a6ce5e
--- /dev/null
+++ b/target/linux/ramips/patches-6.6/805-04-v6.10-pinctrl-aw9523-Use-correct-error-code-for-not-suppor.patch
@@ -0,0 +1,62 @@
+From f91eafcb18e096108cd19d24ab71a0db5bc12416 Mon Sep 17 00:00:00 2001
+From: Andy Shevchenko <andy.shevchenko@gmail.com>
+Date: Fri, 29 Mar 2024 12:55:16 +0200
+Subject: [PATCH] pinctrl: aw9523: Use correct error code for not supported
+ functionality
+
+The pin control subsystem internally uses ENOTSUPP for the not supported
+functionality. The checkpatch is false positive about this error code.
+
+Signed-off-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Message-ID: <20240329105634.712457-3-andy.shevchenko@gmail.com>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ drivers/pinctrl/pinctrl-aw9523.c | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+--- a/drivers/pinctrl/pinctrl-aw9523.c
++++ b/drivers/pinctrl/pinctrl-aw9523.c
+@@ -6,6 +6,7 @@
+ */
+
+ #include <linux/bitfield.h>
++#include <linux/errno.h>
+ #include <linux/gpio/consumer.h>
+ #include <linux/gpio/driver.h>
+ #include <linux/i2c.h>
+@@ -239,7 +240,7 @@ static int aw9523_pcfg_param_to_reg(enum
+ reg = AW9523_REG_OUT_STATE(pin);
+ break;
+ default:
+- return -EOPNOTSUPP;
++ return -ENOTSUPP;
+ }
+ *r = reg;
+
+@@ -290,7 +291,7 @@ static int aw9523_pconf_get(struct pinct
+ val = FIELD_GET(AW9523_GCR_GPOMD_MASK, val);
+ break;
+ default:
+- return -EOPNOTSUPP;
++ return -ENOTSUPP;
+ }
+ if (val < 1)
+ return -EINVAL;
+@@ -344,7 +345,7 @@ static int aw9523_pconf_set(struct pinct
+ case PIN_CONFIG_DRIVE_OPEN_DRAIN:
+ /* Open-Drain is supported only on port 0 */
+ if (pin >= AW9523_PINS_PER_PORT) {
+- rc = -EOPNOTSUPP;
++ rc = -ENOTSUPP;
+ goto end;
+ }
+ mask = AW9523_GCR_GPOMD_MASK;
+@@ -361,7 +362,7 @@ static int aw9523_pconf_set(struct pinct
+ val = AW9523_GCR_GPOMD_MASK;
+ break;
+ default:
+- rc = -EOPNOTSUPP;
++ rc = -ENOTSUPP;
+ goto end;
+ }
+
diff --git a/target/linux/ramips/patches-6.6/805-05-v6.10-pinctrl-aw9523-Always-try-both-ports-in-aw9523_gpio_.patch b/target/linux/ramips/patches-6.6/805-05-v6.10-pinctrl-aw9523-Always-try-both-ports-in-aw9523_gpio_.patch
new file mode 100644
index 0000000000..c90d4dac32
--- /dev/null
+++ b/target/linux/ramips/patches-6.6/805-05-v6.10-pinctrl-aw9523-Always-try-both-ports-in-aw9523_gpio_.patch
@@ -0,0 +1,47 @@
+From 091655b9285d837db520381924c689bd5dc5d286 Mon Sep 17 00:00:00 2001
+From: Andy Shevchenko <andy.shevchenko@gmail.com>
+Date: Fri, 29 Mar 2024 12:55:17 +0200
+Subject: [PATCH] pinctrl: aw9523: Always try both ports in
+ aw9523_gpio_set_multiple()
+
+The ports are equivalent from the user's point of view. Don't limit
+trying them both if writing to one fails.
+
+Signed-off-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Message-ID: <20240329105634.712457-4-andy.shevchenko@gmail.com>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ drivers/pinctrl/pinctrl-aw9523.c | 7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+--- a/drivers/pinctrl/pinctrl-aw9523.c
++++ b/drivers/pinctrl/pinctrl-aw9523.c
+@@ -653,7 +653,7 @@ static void aw9523_gpio_set_multiple(str
+ struct aw9523 *awi = gpiochip_get_data(chip);
+ u8 mask_lo, mask_hi, bits_lo, bits_hi;
+ unsigned int reg;
+- int ret = 0;
++ int ret;
+
+ mask_lo = *mask & U8_MAX;
+ mask_hi = (*mask >> 8) & U8_MAX;
+@@ -663,10 +663,8 @@ static void aw9523_gpio_set_multiple(str
+ bits_hi = (*bits >> 8) & U8_MAX;
+
+ ret = regmap_write_bits(awi->regmap, reg, mask_hi, bits_hi);
+- if (ret) {
++ if (ret)
+ dev_warn(awi->dev, "Cannot write port1 out level\n");
+- goto out;
+- }
+ }
+ if (mask_lo) {
+ reg = AW9523_REG_OUT_STATE(0);
+@@ -675,7 +673,6 @@ static void aw9523_gpio_set_multiple(str
+ if (ret)
+ dev_warn(awi->dev, "Cannot write port0 out level\n");
+ }
+-out:
+ mutex_unlock(&awi->i2c_lock);
+ }
+
diff --git a/target/linux/ramips/patches-6.6/805-06-v6.10-pinctrl-aw9523-Make-use-of-struct-pinfunction-and-PI.patch b/target/linux/ramips/patches-6.6/805-06-v6.10-pinctrl-aw9523-Make-use-of-struct-pinfunction-and-PI.patch
new file mode 100644
index 0000000000..f300fa0193
--- /dev/null
+++ b/target/linux/ramips/patches-6.6/805-06-v6.10-pinctrl-aw9523-Make-use-of-struct-pinfunction-and-PI.patch
@@ -0,0 +1,72 @@
+From 418ee9488ff74ab4ada3a539a2840dda9e56f847 Mon Sep 17 00:00:00 2001
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Date: Fri, 29 Mar 2024 12:55:18 +0200
+Subject: [PATCH] pinctrl: aw9523: Make use of struct pinfunction and
+ PINCTRL_PINFUNCTION()
+
+Since pin control provides a generic data type and a macro for
+the pin function definition, use them in the driver.
+
+Signed-off-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Message-ID: <20240329105634.712457-5-andy.shevchenko@gmail.com>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ drivers/pinctrl/pinctrl-aw9523.c | 32 ++++++--------------------------
+ 1 file changed, 6 insertions(+), 26 deletions(-)
+
+--- a/drivers/pinctrl/pinctrl-aw9523.c
++++ b/drivers/pinctrl/pinctrl-aw9523.c
+@@ -67,18 +67,6 @@ struct aw9523_irq {
+ };
+
+ /*
+- * struct aw9523_pinmux - Pin mux params
+- * @name: Name of the mux
+- * @grps: Groups of the mux
+- * @num_grps: Number of groups (sizeof array grps)
+- */
+-struct aw9523_pinmux {
+- const char *name;
+- const char * const *grps;
+- const u8 num_grps;
+-};
+-
+-/*
+ * struct aw9523 - Main driver structure
+ * @dev: device handle
+ * @regmap: regmap handle for current device
+@@ -158,17 +146,9 @@ static const char * const gpio_pwm_group
+ };
+
+ /* Warning: Do NOT reorder this array */
+-static const struct aw9523_pinmux aw9523_pmx[] = {
+- {
+- .name = "pwm",
+- .grps = gpio_pwm_groups,
+- .num_grps = ARRAY_SIZE(gpio_pwm_groups),
+- },
+- {
+- .name = "gpio",
+- .grps = gpio_pwm_groups,
+- .num_grps = ARRAY_SIZE(gpio_pwm_groups),
+- },
++static const struct pinfunction aw9523_pmx[] = {
++ PINCTRL_PINFUNCTION("pwm", gpio_pwm_groups, ARRAY_SIZE(gpio_pwm_groups)),
++ PINCTRL_PINFUNCTION("gpio", gpio_pwm_groups, ARRAY_SIZE(gpio_pwm_groups)),
+ };
+
+ static int aw9523_pmx_get_funcs_count(struct pinctrl_dev *pctl)
+@@ -184,10 +164,10 @@ static const char *aw9523_pmx_get_fname(
+
+ static int aw9523_pmx_get_groups(struct pinctrl_dev *pctl, unsigned int sel,
+ const char * const **groups,
+- unsigned int * const num_groups)
++ unsigned int * const ngroups)
+ {
+- *groups = aw9523_pmx[sel].grps;
+- *num_groups = aw9523_pmx[sel].num_grps;
++ *groups = aw9523_pmx[sel].groups;
++ *ngroups = aw9523_pmx[sel].ngroups;
+ return 0;
+ }
+
diff --git a/target/linux/ramips/patches-6.6/805-07-v6.10-pinctrl-aw9523-Use-temporary-variable-for-HW-IRQ-num.patch b/target/linux/ramips/patches-6.6/805-07-v6.10-pinctrl-aw9523-Use-temporary-variable-for-HW-IRQ-num.patch
new file mode 100644
index 0000000000..98a1310ad5
--- /dev/null
+++ b/target/linux/ramips/patches-6.6/805-07-v6.10-pinctrl-aw9523-Use-temporary-variable-for-HW-IRQ-num.patch
@@ -0,0 +1,50 @@
+From 66413f0468d35adb352c76bc286bf6f6746ba354 Mon Sep 17 00:00:00 2001
+From: Andy Shevchenko <andy.shevchenko@gmail.com>
+Date: Fri, 29 Mar 2024 12:55:19 +0200
+Subject: [PATCH] pinctrl: aw9523: Use temporary variable for HW IRQ number
+
+There are two different ways on how to get HW IRQ number in some functions.
+Unify that by using temporary variable and irqd_to_hwirq() call.
+
+Signed-off-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Message-ID: <20240329105634.712457-6-andy.shevchenko@gmail.com>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ drivers/pinctrl/pinctrl-aw9523.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+--- a/drivers/pinctrl/pinctrl-aw9523.c
++++ b/drivers/pinctrl/pinctrl-aw9523.c
+@@ -428,12 +428,12 @@ static int aw9523_gpio_irq_type(struct i
+ static void aw9523_irq_mask(struct irq_data *d)
+ {
+ struct aw9523 *awi = gpiochip_get_data(irq_data_get_irq_chip_data(d));
+- unsigned int n = d->hwirq % AW9523_PINS_PER_PORT;
++ irq_hw_number_t hwirq = irqd_to_hwirq(d);
++ unsigned int n = hwirq % AW9523_PINS_PER_PORT;
+
+- regmap_update_bits(awi->regmap,
+- AW9523_REG_INTR_DIS(d->hwirq),
++ regmap_update_bits(awi->regmap, AW9523_REG_INTR_DIS(hwirq),
+ BIT(n), BIT(n));
+- gpiochip_disable_irq(&awi->gpio, irqd_to_hwirq(d));
++ gpiochip_disable_irq(&awi->gpio, hwirq);
+ }
+
+ /*
+@@ -446,11 +446,11 @@ static void aw9523_irq_mask(struct irq_d
+ static void aw9523_irq_unmask(struct irq_data *d)
+ {
+ struct aw9523 *awi = gpiochip_get_data(irq_data_get_irq_chip_data(d));
+- unsigned int n = d->hwirq % AW9523_PINS_PER_PORT;
++ irq_hw_number_t hwirq = irqd_to_hwirq(d);
++ unsigned int n = hwirq % AW9523_PINS_PER_PORT;
+
+- gpiochip_enable_irq(&awi->gpio, irqd_to_hwirq(d));
+- regmap_update_bits(awi->regmap,
+- AW9523_REG_INTR_DIS(d->hwirq),
++ gpiochip_enable_irq(&awi->gpio, hwirq);
++ regmap_update_bits(awi->regmap, AW9523_REG_INTR_DIS(hwirq),
+ BIT(n), 0);
+ }
+
diff --git a/target/linux/ramips/patches-6.6/805-08-v6.10-pinctrl-aw9523-Get-rid-of-redundant-U8_MAX-pieces.patch b/target/linux/ramips/patches-6.6/805-08-v6.10-pinctrl-aw9523-Get-rid-of-redundant-U8_MAX-pieces.patch
new file mode 100644
index 0000000000..a9f86481e3
--- /dev/null
+++ b/target/linux/ramips/patches-6.6/805-08-v6.10-pinctrl-aw9523-Get-rid-of-redundant-U8_MAX-pieces.patch
@@ -0,0 +1,61 @@
+From 4210ef801a248223a0ea5f47b5446081b4925e10 Mon Sep 17 00:00:00 2001
+From: Andy Shevchenko <andy.shevchenko@gmail.com>
+Date: Fri, 29 Mar 2024 12:55:20 +0200
+Subject: [PATCH] pinctrl: aw9523: Get rid of redundant ' & U8_MAX' pieces
+
+When the variable is declared as u8, no need to perform ' & U8_MAX'
+as it's implied anyway.
+
+Signed-off-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Message-ID: <20240329105634.712457-7-andy.shevchenko@gmail.com>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ drivers/pinctrl/pinctrl-aw9523.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+--- a/drivers/pinctrl/pinctrl-aw9523.c
++++ b/drivers/pinctrl/pinctrl-aw9523.c
+@@ -603,7 +603,7 @@ static int aw9523_gpio_get_multiple(stru
+ mutex_lock(&awi->i2c_lock);
+
+ /* Port 0 (gpio 0-7) */
+- m = *mask & U8_MAX;
++ m = *mask;
+ if (m) {
+ ret = _aw9523_gpio_get_multiple(awi, 0, &state, m);
+ if (ret)
+@@ -612,7 +612,7 @@ static int aw9523_gpio_get_multiple(stru
+ *bits = state;
+
+ /* Port 1 (gpio 8-15) */
+- m = (*mask >> 8) & U8_MAX;
++ m = *mask >> 8;
+ if (m) {
+ ret = _aw9523_gpio_get_multiple(awi, AW9523_PINS_PER_PORT,
+ &state, m);
+@@ -635,20 +635,20 @@ static void aw9523_gpio_set_multiple(str
+ unsigned int reg;
+ int ret;
+
+- mask_lo = *mask & U8_MAX;
+- mask_hi = (*mask >> 8) & U8_MAX;
++ mask_lo = *mask;
++ mask_hi = *mask >> 8;
++ bits_lo = *bits;
++ bits_hi = *bits >> 8;
++
+ mutex_lock(&awi->i2c_lock);
+ if (mask_hi) {
+ reg = AW9523_REG_OUT_STATE(AW9523_PINS_PER_PORT);
+- bits_hi = (*bits >> 8) & U8_MAX;
+-
+ ret = regmap_write_bits(awi->regmap, reg, mask_hi, bits_hi);
+ if (ret)
+ dev_warn(awi->dev, "Cannot write port1 out level\n");
+ }
+ if (mask_lo) {
+ reg = AW9523_REG_OUT_STATE(0);
+- bits_lo = *bits & U8_MAX;
+ ret = regmap_write_bits(awi->regmap, reg, mask_lo, bits_lo);
+ if (ret)
+ dev_warn(awi->dev, "Cannot write port0 out level\n");
diff --git a/target/linux/ramips/patches-6.6/805-09-v6.10-pinctrl-aw9523-Remove-unused-irqchip-field-in-struct.patch b/target/linux/ramips/patches-6.6/805-09-v6.10-pinctrl-aw9523-Remove-unused-irqchip-field-in-struct.patch
new file mode 100644
index 0000000000..b37a425e8d
--- /dev/null
+++ b/target/linux/ramips/patches-6.6/805-09-v6.10-pinctrl-aw9523-Remove-unused-irqchip-field-in-struct.patch
@@ -0,0 +1,52 @@
+From 6bf270863ade776485d1c6bdb8f69d642b0e5f64 Mon Sep 17 00:00:00 2001
+From: Andy Shevchenko <andy.shevchenko@gmail.com>
+Date: Fri, 29 Mar 2024 12:55:21 +0200
+Subject: [PATCH] pinctrl: aw9523: Remove unused irqchip field in struct
+ aw9523_irq
+
+The irqchip field is allocated, assigned but never used. Remove it.
+
+Signed-off-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Message-ID: <20240329105634.712457-8-andy.shevchenko@gmail.com>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ drivers/pinctrl/pinctrl-aw9523.c | 8 --------
+ 1 file changed, 8 deletions(-)
+
+--- a/drivers/pinctrl/pinctrl-aw9523.c
++++ b/drivers/pinctrl/pinctrl-aw9523.c
+@@ -57,12 +57,10 @@
+ /*
+ * struct aw9523_irq - Interrupt controller structure
+ * @lock: mutex locking for the irq bus
+- * @irqchip: structure holding irqchip params
+ * @cached_gpio: stores the previous gpio status for bit comparison
+ */
+ struct aw9523_irq {
+ struct mutex lock;
+- struct irq_chip *irqchip;
+ u16 cached_gpio;
+ };
+
+@@ -805,21 +803,15 @@ static int aw9523_init_irq(struct aw9523
+ {
+ struct device *dev = awi->dev;
+ struct gpio_irq_chip *girq;
+- struct irq_chip *irqchip;
+ int ret;
+
+ if (!device_property_read_bool(dev, "interrupt-controller"))
+ return 0;
+
+- irqchip = devm_kzalloc(dev, sizeof(*irqchip), GFP_KERNEL);
+- if (!irqchip)
+- return -ENOMEM;
+-
+ awi->irq = devm_kzalloc(dev, sizeof(*awi->irq), GFP_KERNEL);
+ if (!awi->irq)
+ return -ENOMEM;
+
+- awi->irq->irqchip = irqchip;
+ mutex_init(&awi->irq->lock);
+
+ ret = devm_request_threaded_irq(dev, irq, NULL, aw9523_irq_thread_func,
diff --git a/target/linux/ramips/patches-6.6/805-10-v6.10-pinctrl-aw9523-Make-use-of-dev_err_probe.patch b/target/linux/ramips/patches-6.6/805-10-v6.10-pinctrl-aw9523-Make-use-of-dev_err_probe.patch
new file mode 100644
index 0000000000..f1f4e52140
--- /dev/null
+++ b/target/linux/ramips/patches-6.6/805-10-v6.10-pinctrl-aw9523-Make-use-of-dev_err_probe.patch
@@ -0,0 +1,40 @@
+From c567b00cc3d73f3ce4e92126731545d177262090 Mon Sep 17 00:00:00 2001
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Date: Fri, 29 Mar 2024 12:55:22 +0200
+Subject: [PATCH] pinctrl: aw9523: Make use of dev_err_probe()
+
+Simplify the error handling in probe function by switching from
+dev_err() to dev_err_probe().
+
+Signed-off-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Message-ID: <20240329105634.712457-9-andy.shevchenko@gmail.com>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ drivers/pinctrl/pinctrl-aw9523.c | 9 +++------
+ 1 file changed, 3 insertions(+), 6 deletions(-)
+
+--- a/drivers/pinctrl/pinctrl-aw9523.c
++++ b/drivers/pinctrl/pinctrl-aw9523.c
+@@ -816,10 +816,8 @@ static int aw9523_init_irq(struct aw9523
+
+ ret = devm_request_threaded_irq(dev, irq, NULL, aw9523_irq_thread_func,
+ IRQF_ONESHOT, dev_name(dev), awi);
+- if (ret) {
+- dev_err(dev, "Failed to request irq %d\n", irq);
+- return ret;
+- }
++ if (ret)
++ return dev_err_probe(dev, ret, "Failed to request irq %d\n", irq);
+
+ girq = &awi->gpio.irq;
+ gpio_irq_chip_set_chip(girq, &aw9523_irq_chip);
+@@ -1016,8 +1014,7 @@ static int aw9523_probe(struct i2c_clien
+
+ awi->pctl = devm_pinctrl_register(dev, pdesc, awi);
+ if (IS_ERR(awi->pctl)) {
+- ret = PTR_ERR(awi->pctl);
+- dev_err(dev, "Cannot register pinctrl: %d", ret);
++ ret = dev_err_probe(dev, PTR_ERR(awi->pctl), "Cannot register pinctrl");
+ goto err_disable_vregs;
+ }
+
diff --git a/target/linux/ramips/patches-6.6/805-11-v6.10-pinctrl-aw9523-Sort-headers-and-group-pinctrl.patch b/target/linux/ramips/patches-6.6/805-11-v6.10-pinctrl-aw9523-Sort-headers-and-group-pinctrl.patch
new file mode 100644
index 0000000000..4d81c6ae7f
--- /dev/null
+++ b/target/linux/ramips/patches-6.6/805-11-v6.10-pinctrl-aw9523-Sort-headers-and-group-pinctrl.patch
@@ -0,0 +1,41 @@
+From 7b8b9b5450b89d01e4b8f120b903cee85b529231 Mon Sep 17 00:00:00 2001
+From: Andy Shevchenko <andy.shevchenko@gmail.com>
+Date: Fri, 29 Mar 2024 12:55:23 +0200
+Subject: [PATCH] pinctrl: aw9523: Sort headers and group pinctrl/*
+
+One header was misplaced and group pinctrl/* ones to show the relation
+with the pin control subsystem.
+
+Signed-off-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Message-ID: <20240329105634.712457-10-andy.shevchenko@gmail.com>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ drivers/pinctrl/pinctrl-aw9523.c | 11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+--- a/drivers/pinctrl/pinctrl-aw9523.c
++++ b/drivers/pinctrl/pinctrl-aw9523.c
+@@ -13,17 +13,18 @@
+ #include <linux/init.h>
+ #include <linux/interrupt.h>
+ #include <linux/irq.h>
+-#include <linux/mutex.h>
+ #include <linux/module.h>
+-#include <linux/pinctrl/pinconf.h>
+-#include <linux/pinctrl/pinctrl.h>
+-#include <linux/pinctrl/pinmux.h>
+-#include <linux/pinctrl/pinconf-generic.h>
++#include <linux/mutex.h>
+ #include <linux/property.h>
+ #include <linux/regmap.h>
+ #include <linux/regulator/consumer.h>
+ #include <linux/slab.h>
+
++#include <linux/pinctrl/pinconf-generic.h>
++#include <linux/pinctrl/pinconf.h>
++#include <linux/pinctrl/pinctrl.h>
++#include <linux/pinctrl/pinmux.h>
++
+ #define AW9523_MAX_FUNCS 2
+ #define AW9523_NUM_PORTS 2
+ #define AW9523_PINS_PER_PORT 8
diff --git a/target/linux/ramips/patches-6.6/805-12-v6.10-pinctrl-aw9523-Fix-indentation-in-a-few-places.patch b/target/linux/ramips/patches-6.6/805-12-v6.10-pinctrl-aw9523-Fix-indentation-in-a-few-places.patch
new file mode 100644
index 0000000000..3ebdcdfa4a
--- /dev/null
+++ b/target/linux/ramips/patches-6.6/805-12-v6.10-pinctrl-aw9523-Fix-indentation-in-a-few-places.patch
@@ -0,0 +1,62 @@
+From 4aad0ad20f4ea80180a3e58b04b701728541c0f7 Mon Sep 17 00:00:00 2001
+From: Andy Shevchenko <andy.shevchenko@gmail.com>
+Date: Fri, 29 Mar 2024 12:55:24 +0200
+Subject: [PATCH] pinctrl: aw9523: Fix indentation in a few places
+
+In the comment, function prototype, and array of strings indentation
+is kinda broken. Reindent that.
+
+Signed-off-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Message-ID: <20240329105634.712457-11-andy.shevchenko@gmail.com>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ drivers/pinctrl/pinctrl-aw9523.c | 17 ++++++++---------
+ 1 file changed, 8 insertions(+), 9 deletions(-)
+
+--- a/drivers/pinctrl/pinctrl-aw9523.c
++++ b/drivers/pinctrl/pinctrl-aw9523.c
+@@ -1,8 +1,7 @@
+ // SPDX-License-Identifier: GPL-2.0-only
+ /*
+ * Awinic AW9523B i2c pin controller driver
+- * Copyright (c) 2020, AngeloGioacchino Del Regno
+- * <angelogioacchino.delregno@somainline.org>
++ * Copyright (c) 2020, AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
+ */
+
+ #include <linux/bitfield.h>
+@@ -139,9 +138,10 @@ static const struct pinctrl_ops aw9523_p
+ };
+
+ static const char * const gpio_pwm_groups[] = {
+- "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5",
+- "gpio6", "gpio7", "gpio8", "gpio9", "gpio10", "gpio11",
+- "gpio12", "gpio13", "gpio14", "gpio15"
++ "gpio0", "gpio1", "gpio2", "gpio3", /* 0-3 */
++ "gpio4", "gpio5", "gpio6", "gpio7", /* 4-7 */
++ "gpio8", "gpio9", "gpio10", "gpio11", /* 8-11 */
++ "gpio12", "gpio13", "gpio14", "gpio15", /* 11-15 */
+ };
+
+ /* Warning: Do NOT reorder this array */
+@@ -388,8 +388,8 @@ static int aw9523_get_pin_direction(stru
+ *
+ * Return: Zero for success or negative number for error
+ */
+-static int aw9523_get_port_state(struct regmap *regmap, u8 pin,
+- u8 regbit, unsigned int *state)
++static int aw9523_get_port_state(struct regmap *regmap, u8 pin, u8 regbit,
++ unsigned int *state)
+ {
+ u8 reg;
+ int dir;
+@@ -984,8 +984,7 @@ static int aw9523_probe(struct i2c_clien
+ }
+
+ mutex_init(&awi->i2c_lock);
+- lockdep_set_subclass(&awi->i2c_lock,
+- i2c_adapter_depth(client->adapter));
++ lockdep_set_subclass(&awi->i2c_lock, i2c_adapter_depth(client->adapter));
+
+ pdesc = devm_kzalloc(dev, sizeof(*pdesc), GFP_KERNEL);
+ if (!pdesc)
diff --git a/target/linux/ramips/patches-6.6/805-pinctrl-AW9523.patch b/target/linux/ramips/patches-6.6/805-pinctrl-AW9523.patch
deleted file mode 100644
index f9fa791fe1..0000000000
--- a/target/linux/ramips/patches-6.6/805-pinctrl-AW9523.patch
+++ /dev/null
@@ -1,72 +0,0 @@
-From: AngeloGioacchino Del Regno
- <angelogioacchino.delregno@somainline.org>
-To: linus.walleij@linaro.org
-Cc: linux-kernel@vger.kernel.org, konrad.dybcio@somainline.org,
- marijn.suijten@somainline.org, martin.botka@somainline.org,
- phone-devel@vger.kernel.org, linux-gpio@vger.kernel.org,
- devicetree@vger.kernel.org, robh+dt@kernel.org,
- AngeloGioacchino Del Regno
- <angelogioacchino.delregno@somainline.org>
-Subject: [PATCH v5 1/2] pinctrl: Add driver for Awinic AW9523/B I2C GPIO
- Expander
-Date: Mon, 25 Jan 2021 19:22:18 +0100
-
-The Awinic AW9523(B) is a multi-function I2C gpio expander in a
-TQFN-24L package, featuring PWM (max 37mA per pin, or total max
-power 3.2Watts) for LED driving capability.
-
-It has two ports with 8 pins per port (for a total of 16 pins),
-configurable as either PWM with 1/256 stepping or GPIO input/output,
-1.8V logic input; each GPIO can be configured as input or output
-independently from each other.
-
-This IC also has an internal interrupt controller, which is capable
-of generating an interrupt for each GPIO, depending on the
-configuration, and will raise an interrupt on the INTN pin to
-advertise this to an external interrupt controller.
-
-Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
----
- drivers/pinctrl/Kconfig | 17 +
- drivers/pinctrl/Makefile | 1 +
- drivers/pinctrl/pinctrl-aw9523.c | 1122 ++++++++++++++++++++++++++++++
- 3 files changed, 1140 insertions(+)
- create mode 100644 drivers/pinctrl/pinctrl-aw9523.c
-
---- a/drivers/pinctrl/Kconfig
-+++ b/drivers/pinctrl/Kconfig
-@@ -113,6 +113,24 @@ config PINCTRL_AT91PIO4
- Say Y here to enable the at91 pinctrl/gpio driver for Atmel PIO4
- controller available on sama5d2 SoC.
-
-+config PINCTRL_AW9523
-+ bool "Awinic AW9523/AW9523B I2C GPIO expander pinctrl driver"
-+ depends on OF && I2C
-+ select PINMUX
-+ select PINCONF
-+ select GENERIC_PINCONF
-+ select GPIOLIB
-+ select GPIOLIB_IRQCHIP
-+ select REGMAP
-+ select REGMAP_I2C
-+ help
-+ The Awinic AW9523/AW9523B is a multi-function I2C GPIO
-+ expander with PWM functionality. This driver bundles a
-+ pinctrl driver to select the function muxing and a GPIO
-+ driver to handle GPIO, when the GPIO function is selected.
-+
-+ Say yes to enable pinctrl and GPIO support for the AW9523(B).
-+
- config PINCTRL_AXP209
- tristate "X-Powers AXP209 PMIC pinctrl and GPIO Support"
- depends on MFD_AXP20X
---- a/drivers/pinctrl/Makefile
-+++ b/drivers/pinctrl/Makefile
-@@ -15,6 +15,7 @@ obj-$(CONFIG_PINCTRL_ARTPEC6) += pinctrl
- obj-$(CONFIG_PINCTRL_AS3722) += pinctrl-as3722.o
- obj-$(CONFIG_PINCTRL_AT91) += pinctrl-at91.o
- obj-$(CONFIG_PINCTRL_AT91PIO4) += pinctrl-at91-pio4.o
-+obj-$(CONFIG_PINCTRL_AW9523) += pinctrl-aw9523.o
- obj-$(CONFIG_PINCTRL_AXP209) += pinctrl-axp209.o
- obj-$(CONFIG_PINCTRL_BM1880) += pinctrl-bm1880.o
- obj-$(CONFIG_PINCTRL_CY8C95X0) += pinctrl-cy8c95x0.o
diff --git a/target/linux/ramips/patches-6.6/810-uvc-add-iPassion-iP2970-support.patch b/target/linux/ramips/patches-6.6/810-uvc-add-iPassion-iP2970-support.patch
index b58cb786ad..71adf6600f 100644
--- a/target/linux/ramips/patches-6.6/810-uvc-add-iPassion-iP2970-support.patch
+++ b/target/linux/ramips/patches-6.6/810-uvc-add-iPassion-iP2970-support.patch
@@ -13,7 +13,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
--- a/drivers/media/usb/uvc/uvc_driver.c
+++ b/drivers/media/usb/uvc/uvc_driver.c
-@@ -3151,6 +3151,18 @@ static const struct usb_device_id uvc_id
+@@ -3183,6 +3183,18 @@ static const struct usb_device_id uvc_id
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
.driver_info = UVC_INFO_META(V4L2_META_FMT_D4XX) },
@@ -64,7 +64,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
#include <media/v4l2-common.h>
-@@ -1235,9 +1240,149 @@ static void uvc_video_decode_data(struct
+@@ -1275,9 +1280,149 @@ static void uvc_video_decode_data(struct
uvc_urb->async_operations++;
}
@@ -214,7 +214,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
/* Mark the buffer as done if the EOF marker is set. */
if (data[1] & UVC_STREAM_EOF && buf->bytesused != 0) {
uvc_dbg(stream->dev, FRAME, "Frame complete (EOF found)\n");
-@@ -1819,6 +1964,8 @@ static int uvc_init_video_isoc(struct uv
+@@ -1859,6 +2004,8 @@ static int uvc_init_video_isoc(struct uv
if (npackets == 0)
return -ENOMEM;
@@ -225,16 +225,16 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
for_each_uvc_urb(uvc_urb, stream) {
--- a/drivers/media/usb/uvc/uvcvideo.h
+++ b/drivers/media/usb/uvc/uvcvideo.h
-@@ -74,6 +74,8 @@
- #define UVC_QUIRK_FORCE_BPP 0x00001000
- #define UVC_QUIRK_WAKE_AUTOSUSPEND 0x00002000
+@@ -76,6 +76,8 @@
#define UVC_QUIRK_NO_RESET_RESUME 0x00004000
-+#define UVC_QUIRK_MOTION 0x00008000
-+#define UVC_QUIRK_SINGLE_ISO 0x00010000
+ #define UVC_QUIRK_DISABLE_AUTOSUSPEND 0x00008000
+ #define UVC_QUIRK_INVALID_DEVICE_SOF 0x00010000
++#define UVC_QUIRK_MOTION 0x00020000
++#define UVC_QUIRK_SINGLE_ISO 0x00040000
/* Format flags */
#define UVC_FMT_FLAG_COMPRESSED 0x00000001
-@@ -583,6 +585,7 @@ struct uvc_device {
+@@ -585,6 +587,7 @@ struct uvc_device {
struct input_dev *input;
char input_phys[64];
diff --git a/target/linux/realtek/dts-5.15/rtl8380_zyxel_gs1900-10hp.dts b/target/linux/realtek/dts-5.15/rtl8380_zyxel_gs1900-10hp.dts
index 82df6789a9..190a77b7ff 100644
--- a/target/linux/realtek/dts-5.15/rtl8380_zyxel_gs1900-10hp.dts
+++ b/target/linux/realtek/dts-5.15/rtl8380_zyxel_gs1900-10hp.dts
@@ -4,7 +4,7 @@
/ {
compatible = "zyxel,gs1900-10hp", "realtek,rtl838x-soc";
- model = "ZyXEL GS1900-10HP Switch";
+ model = "Zyxel GS1900-10HP Switch";
/* i2c of the left SFP cage: port 9 */
i2c0: i2c-gpio-0 {
diff --git a/target/linux/realtek/dts-5.15/rtl8380_zyxel_gs1900-8.dts b/target/linux/realtek/dts-5.15/rtl8380_zyxel_gs1900-8.dts
index 7aa1cc274c..548e83ba73 100644
--- a/target/linux/realtek/dts-5.15/rtl8380_zyxel_gs1900-8.dts
+++ b/target/linux/realtek/dts-5.15/rtl8380_zyxel_gs1900-8.dts
@@ -4,7 +4,7 @@
/ {
compatible = "zyxel,gs1900-8", "realtek,rtl838x-soc";
- model = "ZyXEL GS1900-8v1/v2 Switch";
+ model = "Zyxel GS1900-8v1/v2 Switch";
};
&gpio1 {
diff --git a/target/linux/realtek/dts-5.15/rtl8380_zyxel_gs1900-8hp-v1.dts b/target/linux/realtek/dts-5.15/rtl8380_zyxel_gs1900-8hp-v1.dts
index 5ee340eac6..386edfb015 100644
--- a/target/linux/realtek/dts-5.15/rtl8380_zyxel_gs1900-8hp-v1.dts
+++ b/target/linux/realtek/dts-5.15/rtl8380_zyxel_gs1900-8hp-v1.dts
@@ -4,7 +4,7 @@
/ {
compatible = "zyxel,gs1900-8hp-v1", "realtek,rtl838x-soc";
- model = "ZyXEL GS1900-8HP v1 Switch";
+ model = "Zyxel GS1900-8HP v1 Switch";
};
&uart1 {
diff --git a/target/linux/realtek/dts-5.15/rtl8380_zyxel_gs1900-8hp-v2.dts b/target/linux/realtek/dts-5.15/rtl8380_zyxel_gs1900-8hp-v2.dts
index 0768462255..2702f2ba1c 100644
--- a/target/linux/realtek/dts-5.15/rtl8380_zyxel_gs1900-8hp-v2.dts
+++ b/target/linux/realtek/dts-5.15/rtl8380_zyxel_gs1900-8hp-v2.dts
@@ -4,7 +4,7 @@
/ {
compatible = "zyxel,gs1900-8hp-v2", "realtek,rtl838x-soc";
- model = "ZyXEL GS1900-8HP v2 Switch";
+ model = "Zyxel GS1900-8HP v2 Switch";
};
&uart1 {
diff --git a/target/linux/realtek/dts-5.15/rtl8382_zyxel_gs1900-16.dts b/target/linux/realtek/dts-5.15/rtl8382_zyxel_gs1900-16.dts
index ac2eea7015..6010da2e26 100644
--- a/target/linux/realtek/dts-5.15/rtl8382_zyxel_gs1900-16.dts
+++ b/target/linux/realtek/dts-5.15/rtl8382_zyxel_gs1900-16.dts
@@ -4,7 +4,7 @@
/ {
compatible = "zyxel,gs1900-16", "realtek,rtl838x-soc";
- model = "ZyXEL GS1900-16";
+ model = "Zyxel GS1900-16";
};
&mdio {
diff --git a/target/linux/realtek/dts-5.15/rtl8382_zyxel_gs1900-24-v1.dts b/target/linux/realtek/dts-5.15/rtl8382_zyxel_gs1900-24-v1.dts
index 81482dde10..6d98e7fae1 100644
--- a/target/linux/realtek/dts-5.15/rtl8382_zyxel_gs1900-24-v1.dts
+++ b/target/linux/realtek/dts-5.15/rtl8382_zyxel_gs1900-24-v1.dts
@@ -4,7 +4,7 @@
/ {
compatible = "zyxel,gs1900-24-v1", "realtek,rtl838x-soc";
- model = "ZyXEL GS1900-24 v1";
+ model = "Zyxel GS1900-24 v1";
memory@0 {
reg = <0x0 0x4000000>;
diff --git a/target/linux/realtek/dts-5.15/rtl8382_zyxel_gs1900-24e.dts b/target/linux/realtek/dts-5.15/rtl8382_zyxel_gs1900-24e.dts
index 3d00034a3b..b455ddf23a 100644
--- a/target/linux/realtek/dts-5.15/rtl8382_zyxel_gs1900-24e.dts
+++ b/target/linux/realtek/dts-5.15/rtl8382_zyxel_gs1900-24e.dts
@@ -4,7 +4,7 @@
/ {
compatible = "zyxel,gs1900-24e", "realtek,rtl838x-soc";
- model = "ZyXEL GS1900-24E";
+ model = "Zyxel GS1900-24E";
};
&mdio {
diff --git a/target/linux/realtek/dts-5.15/rtl8382_zyxel_gs1900-24ep.dts b/target/linux/realtek/dts-5.15/rtl8382_zyxel_gs1900-24ep.dts
index 8a77121f4c..25c82f089e 100644
--- a/target/linux/realtek/dts-5.15/rtl8382_zyxel_gs1900-24ep.dts
+++ b/target/linux/realtek/dts-5.15/rtl8382_zyxel_gs1900-24ep.dts
@@ -4,7 +4,7 @@
/ {
compatible = "zyxel,gs1900-24ep", "realtek,rtl838x-soc";
- model = "ZyXEL GS1900-24EP Switch";
+ model = "Zyxel GS1900-24EP Switch";
};
&uart1 {
diff --git a/target/linux/realtek/dts-5.15/rtl8382_zyxel_gs1900-24hp-v1.dts b/target/linux/realtek/dts-5.15/rtl8382_zyxel_gs1900-24hp-v1.dts
index 7bb3410a31..fa9bef89d6 100644
--- a/target/linux/realtek/dts-5.15/rtl8382_zyxel_gs1900-24hp-v1.dts
+++ b/target/linux/realtek/dts-5.15/rtl8382_zyxel_gs1900-24hp-v1.dts
@@ -4,7 +4,7 @@
/ {
compatible = "zyxel,gs1900-24hp-v1", "realtek,rtl838x-soc";
- model = "ZyXEL GS1900-24HP v1";
+ model = "Zyxel GS1900-24HP v1";
memory@0 {
reg = <0x0 0x4000000>;
diff --git a/target/linux/realtek/dts-5.15/rtl8382_zyxel_gs1900-24hp-v2.dts b/target/linux/realtek/dts-5.15/rtl8382_zyxel_gs1900-24hp-v2.dts
index 7b6a9a1e7f..93011cbdaa 100644
--- a/target/linux/realtek/dts-5.15/rtl8382_zyxel_gs1900-24hp-v2.dts
+++ b/target/linux/realtek/dts-5.15/rtl8382_zyxel_gs1900-24hp-v2.dts
@@ -4,7 +4,7 @@
/ {
compatible = "zyxel,gs1900-24hp-v2", "realtek,rtl838x-soc";
- model = "ZyXEL GS1900-24HP v2 Switch";
+ model = "Zyxel GS1900-24HP v2 Switch";
/* i2c of the left SFP cage: port 25 */
i2c0: i2c-gpio-0 {
diff --git a/target/linux/realtek/image/common.mk b/target/linux/realtek/image/common.mk
index 37370f1999..27fcea86ec 100644
--- a/target/linux/realtek/image/common.mk
+++ b/target/linux/realtek/image/common.mk
@@ -57,7 +57,7 @@ define Device/hpe_1920
endef
define Device/zyxel_gs1900
- DEVICE_VENDOR := ZyXEL
+ DEVICE_VENDOR := Zyxel
IMAGE_SIZE := 6976k
UIMAGE_MAGIC := 0x83800000
KERNEL_INITRAMFS := \
diff --git a/target/linux/realtek/image/rtl838x.mk b/target/linux/realtek/image/rtl838x.mk
index 7c64d8d667..05574e5375 100644
--- a/target/linux/realtek/image/rtl838x.mk
+++ b/target/linux/realtek/image/rtl838x.mk
@@ -314,7 +314,7 @@ define Device/zyxel_gs1900-8
SOC := rtl8380
DEVICE_MODEL := GS1900-8
DEVICE_VARIANT := v1
- DEVICE_ALT0_VENDOR := ZyXEL
+ DEVICE_ALT0_VENDOR := Zyxel
DEVICE_ALT0_MODEL := GS1900-8
DEVICE_ALT0_VARIANT := v2
ZYXEL_VERS := AAHH
diff --git a/target/linux/rockchip/armv8/base-files/etc/board.d/01_leds b/target/linux/rockchip/armv8/base-files/etc/board.d/01_leds
index ef89461056..6f6dfbf73e 100644
--- a/target/linux/rockchip/armv8/base-files/etc/board.d/01_leds
+++ b/target/linux/rockchip/armv8/base-files/etc/board.d/01_leds
@@ -28,6 +28,11 @@ friendlyarm,nanopi-r5s)
ucidef_set_led_netdev "lan1" "LAN1" "green:lan-1" "eth1"
ucidef_set_led_netdev "lan2" "LAN2" "green:lan-2" "eth2"
;;
+friendlyarm,nanopi-r6s)
+ ucidef_set_led_netdev "wan" "WAN" "wan_led" "eth1"
+ ucidef_set_led_netdev "lan1" "LAN1" "lan1_led" "eth2"
+ ucidef_set_led_netdev "lan2" "LAN2" "lan2_led" "eth0"
+ ;;
esac
board_config_flush
diff --git a/target/linux/rockchip/armv8/base-files/etc/board.d/02_network b/target/linux/rockchip/armv8/base-files/etc/board.d/02_network
index 8729bd52f2..078ecfaabe 100644
--- a/target/linux/rockchip/armv8/base-files/etc/board.d/02_network
+++ b/target/linux/rockchip/armv8/base-files/etc/board.d/02_network
@@ -7,22 +7,28 @@ rockchip_setup_interfaces()
local board="$1"
case "$board" in
+ friendlyarm,nanopc-t6|\
+ friendlyarm,nanopi-r5c|\
+ radxa,e25|\
+ radxa,rock-3b)
+ ucidef_set_interfaces_lan_wan 'eth0' 'eth1'
+ ;;
friendlyarm,nanopi-r2c|\
friendlyarm,nanopi-r2c-plus|\
friendlyarm,nanopi-r2s|\
friendlyarm,nanopi-r4s|\
friendlyarm,nanopi-r4s-enterprise|\
+ radxa,rockpi-e|\
xunlong,orangepi-r1-plus|\
xunlong,orangepi-r1-plus-lts)
ucidef_set_interfaces_lan_wan 'eth1' 'eth0'
;;
- friendlyarm,nanopi-r5c|\
- radxa,e25)
- ucidef_set_interfaces_lan_wan 'eth0' 'eth1'
- ;;
friendlyarm,nanopi-r5s)
ucidef_set_interfaces_lan_wan 'eth1 eth2' 'eth0'
;;
+ friendlyarm,nanopi-r6s)
+ ucidef_set_interfaces_lan_wan 'eth0 eth2' 'eth1'
+ ;;
sinovoip,rk3568-bpi-r2pro)
ucidef_set_interfaces_lan_wan 'lan0 lan1 lan2 lan3' 'eth0'
;;
@@ -40,6 +46,7 @@ rockchip_setup_macs()
local label_mac=""
case "$board" in
+ friendlyarm,nanopc-t6|\
friendlyarm,nanopi-r2c|\
friendlyarm,nanopi-r2s)
wan_mac=$(macaddr_generate_from_mmc_cid mmcblk0)
@@ -56,7 +63,8 @@ rockchip_setup_macs()
wan_mac=$(get_mac_binary "/sys/bus/i2c/devices/2-0051/eeprom" 0xfa)
lan_mac=$(macaddr_setbit_la "$wan_mac")
;;
- friendlyarm,nanopi-r5c)
+ friendlyarm,nanopi-r5c|\
+ friendlyarm,nanopi-r6s)
wan_mac=$(macaddr_generate_from_mmc_cid mmcblk*)
lan_mac=$(macaddr_add "$wan_mac" 1)
;;
diff --git a/target/linux/rockchip/armv8/base-files/etc/hotplug.d/net/40-net-smp-affinity b/target/linux/rockchip/armv8/base-files/etc/hotplug.d/net/40-net-smp-affinity
index 8bbce1c328..db1bb2ba65 100644
--- a/target/linux/rockchip/armv8/base-files/etc/hotplug.d/net/40-net-smp-affinity
+++ b/target/linux/rockchip/armv8/base-files/etc/hotplug.d/net/40-net-smp-affinity
@@ -29,6 +29,13 @@ set_interface_core() {
}
case "$(board_name)" in
+friendlyarm,nanopc-t6|\
+friendlyarm,nanopi-r5c|\
+radxa,e25|\
+sinovoip,rk3568-bpi-r2pro)
+ set_interface_core 2 "eth0"
+ set_interface_core 4 "eth1"
+ ;;
friendlyarm,nanopi-r2c|\
friendlyarm,nanopi-r2c-plus|\
friendlyarm,nanopi-r2s|\
@@ -43,13 +50,8 @@ friendlyarm,nanopi-r4s-enterprise)
set_interface_core 10 "eth0"
set_interface_core 20 "eth1"
;;
-friendlyarm,nanopi-r5c|\
-radxa,e25|\
-sinovoip,rk3568-bpi-r2pro)
- set_interface_core 2 "eth0"
- set_interface_core 4 "eth1"
- ;;
-friendlyarm,nanopi-r5s)
+friendlyarm,nanopi-r5s|\
+friendlyarm,nanopi-r6s)
set_interface_core 2 "eth0"
set_interface_core 4 "eth1"
set_interface_core 8 "eth2"
diff --git a/target/linux/rockchip/armv8/config-6.6 b/target/linux/rockchip/armv8/config-6.6
index fb57fc6260..c92f2b1c48 100644
--- a/target/linux/rockchip/armv8/config-6.6
+++ b/target/linux/rockchip/armv8/config-6.6
@@ -22,13 +22,20 @@ CONFIG_ARCH_WANTS_THP_SWAP=y
CONFIG_ARC_EMAC_CORE=y
CONFIG_ARM64=y
CONFIG_ARM64_4K_PAGES=y
-CONFIG_ARM64_CNP=y
-CONFIG_ARM64_EPAN=y
+CONFIG_ARM64_ERRATUM_1024718=y
+CONFIG_ARM64_ERRATUM_1165522=y
+CONFIG_ARM64_ERRATUM_1286807=y
+CONFIG_ARM64_ERRATUM_1319367=y
+CONFIG_ARM64_ERRATUM_1463225=y
+CONFIG_ARM64_ERRATUM_1530923=y
CONFIG_ARM64_ERRATUM_2051678=y
CONFIG_ARM64_ERRATUM_2054223=y
CONFIG_ARM64_ERRATUM_2067961=y
CONFIG_ARM64_ERRATUM_2077057=y
+CONFIG_ARM64_ERRATUM_2441007=y
+CONFIG_ARM64_ERRATUM_2441009=y
CONFIG_ARM64_ERRATUM_2658417=y
+CONFIG_ARM64_ERRATUM_3117295=y
CONFIG_ARM64_ERRATUM_819472=y
CONFIG_ARM64_ERRATUM_824069=y
CONFIG_ARM64_ERRATUM_826319=y
@@ -39,7 +46,6 @@ CONFIG_ARM64_ERRATUM_858921=y
CONFIG_ARM64_HW_AFDBM=y
CONFIG_ARM64_LD_HAS_FIX_ERRATUM_843419=y
CONFIG_ARM64_PAGE_SHIFT=12
-CONFIG_ARM64_PAN=y
CONFIG_ARM64_PA_BITS=48
CONFIG_ARM64_PA_BITS_48=y
CONFIG_ARM64_PTR_AUTH=y
@@ -52,6 +58,9 @@ CONFIG_ARM64_VA_BITS=48
# CONFIG_ARM64_VA_BITS_39 is not set
CONFIG_ARM64_VA_BITS_48=y
CONFIG_ARM64_WORKAROUND_CLEAN_CACHE=y
+CONFIG_ARM64_WORKAROUND_REPEAT_TLBI=y
+CONFIG_ARM64_WORKAROUND_SPECULATIVE_AT=y
+CONFIG_ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD=y
CONFIG_ARM64_WORKAROUND_TSB_FLUSH_FAILURE=y
CONFIG_ARM_AMBA=y
CONFIG_ARM_ARCH_TIMER=y
@@ -163,6 +172,7 @@ CONFIG_CPU_IDLE_GOV_MENU=y
CONFIG_CPU_IDLE_MULTIPLE_DRIVERS=y
CONFIG_CPU_ISOLATION=y
CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_CPU_MITIGATIONS=y
CONFIG_CPU_PM=y
CONFIG_CPU_RMAP=y
CONFIG_CPU_THERMAL=y
@@ -235,7 +245,6 @@ CONFIG_EMAC_ROCKCHIP=y
CONFIG_ENERGY_MODEL=y
CONFIG_EXCLUSIVE_SYSTEM_RAM=y
CONFIG_EXT4_FS=y
-CONFIG_EXT4_FS_POSIX_ACL=y
CONFIG_EXTCON=y
CONFIG_F2FS_FS=y
CONFIG_FANOTIFY=y
@@ -246,7 +255,6 @@ CONFIG_FIX_EARLYCON_MEM=y
CONFIG_FRAME_POINTER=y
CONFIG_FS_IOMAP=y
CONFIG_FS_MBCACHE=y
-CONFIG_FS_POSIX_ACL=y
CONFIG_FUNCTION_ALIGNMENT=4
CONFIG_FUNCTION_ALIGNMENT_4B=y
CONFIG_FWNODE_MDIO=y
@@ -442,7 +450,7 @@ CONFIG_NR_CPUS=256
CONFIG_NVMEM=y
CONFIG_NVMEM_LAYOUTS=y
CONFIG_NVMEM_ROCKCHIP_EFUSE=y
-# CONFIG_NVMEM_ROCKCHIP_OTP is not set
+CONFIG_NVMEM_ROCKCHIP_OTP=y
CONFIG_NVMEM_SYSFS=y
CONFIG_NVME_CORE=y
# CONFIG_NVME_HWMON is not set
@@ -507,6 +515,7 @@ CONFIG_PHY_ROCKCHIP_PCIE=y
CONFIG_PHY_ROCKCHIP_SNPS_PCIE3=y
CONFIG_PHY_ROCKCHIP_TYPEC=y
CONFIG_PHY_ROCKCHIP_USB=y
+CONFIG_PHY_ROCKCHIP_USBDP=y
CONFIG_PINCTRL=y
CONFIG_PINCTRL_RK805=y
CONFIG_PINCTRL_ROCKCHIP=y
@@ -567,6 +576,7 @@ CONFIG_RELOCATABLE=y
CONFIG_RESET_CONTROLLER=y
CONFIG_RESET_SCMI=y
CONFIG_RFS_ACCEL=y
+CONFIG_ROCKCHIP_ERRATUM_3588001=y
CONFIG_ROCKCHIP_GRF=y
CONFIG_ROCKCHIP_IODOMAIN=y
CONFIG_ROCKCHIP_IOMMU=y
diff --git a/target/linux/rockchip/armv8/target.mk b/target/linux/rockchip/armv8/target.mk
index 085b475c4b..2fd1292817 100644
--- a/target/linux/rockchip/armv8/target.mk
+++ b/target/linux/rockchip/armv8/target.mk
@@ -1,8 +1,8 @@
ARCH:=aarch64
SUBTARGET:=armv8
-BOARDNAME:=RK33xx/RK356x boards (64 bit)
+BOARDNAME:=RK33xx/RK35xx boards (64 bit)
define Target/Description
- Build firmware image for Rockchip RK33xx devices.
+ Build firmware image for Rockchip RK33xx/RK35xx devices.
This firmware features a 64 bit kernel.
endef
diff --git a/target/linux/rockchip/image/armv8.mk b/target/linux/rockchip/image/armv8.mk
index 3f1e6934d1..8bbdf0b3d7 100644
--- a/target/linux/rockchip/image/armv8.mk
+++ b/target/linux/rockchip/image/armv8.mk
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: GPL-2.0-only
#
-# Copyright (C) 2020 Tobias Maedel
+# Copyright (C) 2020 Sarah Maedel
# FIT will be loaded at 0x02080000. Leave 16M for that, align it to 2M and load the kernel after it.
KERNEL_LOADADDR := 0x03200000
@@ -22,6 +22,14 @@ define Device/friendlyarm_nanopc-t4
endef
TARGET_DEVICES += friendlyarm_nanopc-t4
+define Device/friendlyarm_nanopc-t6
+ DEVICE_VENDOR := FriendlyARM
+ DEVICE_MODEL := NanoPC T6
+ SOC := rk3588
+ DEVICE_PACKAGES := kmod-r8169
+endef
+TARGET_DEVICES += friendlyarm_nanopc-t6
+
define Device/friendlyarm_nanopi-r2c
DEVICE_VENDOR := FriendlyARM
DEVICE_MODEL := NanoPi R2C
@@ -81,6 +89,14 @@ define Device/friendlyarm_nanopi-r5s
endef
TARGET_DEVICES += friendlyarm_nanopi-r5s
+define Device/friendlyarm_nanopi-r6s
+ DEVICE_VENDOR := FriendlyARM
+ DEVICE_MODEL := NanoPi R6S
+ SOC := rk3588s
+ DEVICE_PACKAGES := kmod-r8169
+endef
+TARGET_DEVICES += friendlyarm_nanopi-r6s
+
define Device/pine64_rock64
DEVICE_VENDOR := Pine64
DEVICE_MODEL := Rock64
@@ -111,10 +127,53 @@ define Device/radxa_e25
DEVICE_DTS := rockchip/rk3568-radxa-e25
BOOT_SCRIPT := radxa-e25
UBOOT_DEVICE_NAME := radxa-e25-rk3568
- DEVICE_PACKAGES := kmod-r8169 kmod-ata-ahci-platform
+ DEVICE_PACKAGES := kmod-r8169 kmod-ata-ahci-dwc
endef
TARGET_DEVICES += radxa_e25
+define Device/radxa_rock-3a
+ DEVICE_VENDOR := Radxa
+ DEVICE_MODEL := ROCK 3A
+ SOC := rk3568
+ SUPPORTED_DEVICES := radxa,rock3a
+ DEVICE_PACKAGES := kmod-usb-net-cdc-ncm kmod-usb-net-rndis
+endef
+TARGET_DEVICES += radxa_rock-3a
+
+define Device/radxa_rock-3b
+ DEVICE_VENDOR := Radxa
+ DEVICE_MODEL := ROCK 3B
+ SOC := rk3568
+ DEVICE_PACKAGES := kmod-usb-net-cdc-ncm kmod-usb-net-rndis
+endef
+TARGET_DEVICES += radxa_rock-3b
+
+define Device/radxa_rock-3c
+ DEVICE_VENDOR := Radxa
+ DEVICE_MODEL := ROCK 3C
+ SOC := rk3566
+ DEVICE_PACKAGES := kmod-usb-net-cdc-ncm kmod-usb-net-rndis
+endef
+TARGET_DEVICES += radxa_rock-3c
+
+define Device/radxa_rock-5a
+ DEVICE_VENDOR := Radxa
+ DEVICE_MODEL := ROCK 5A
+ SOC := rk3588s
+ UBOOT_DEVICE_NAME := rock5a-rk3588s
+ DEVICE_PACKAGES := kmod-hwmon-pwmfan
+endef
+TARGET_DEVICES += radxa_rock-5a
+
+define Device/radxa_rock-5b
+ DEVICE_VENDOR := Radxa
+ DEVICE_MODEL := ROCK 5B
+ SOC := rk3588
+ UBOOT_DEVICE_NAME := rock5b-rk3588
+ DEVICE_PACKAGES := kmod-r8169 kmod-hwmon-pwmfan
+endef
+TARGET_DEVICES += radxa_rock-5b
+
define Device/radxa_rock-pi-4a
DEVICE_VENDOR := Radxa
DEVICE_MODEL := ROCK Pi 4A
@@ -131,6 +190,45 @@ define Device/radxa_rock-pi-e
endef
TARGET_DEVICES += radxa_rock-pi-e
+define Device/radxa_rock-pi-e-v3
+ DEVICE_VENDOR := Radxa
+ DEVICE_MODEL := ROCK Pi E v3.0
+ SOC := rk3328
+ DEVICE_DTS := rockchip/rk3328-rock-pi-e
+ DEVICE_PACKAGES := kmod-rtw88-8723du kmod-usb-net-cdc-ncm kmod-usb-net-rndis wpad-basic-mbedtls
+endef
+TARGET_DEVICES += radxa_rock-pi-e-v3
+
+define Device/radxa_rock-pi-s
+ DEVICE_VENDOR := Radxa
+ DEVICE_MODEL := ROCK Pi S
+ SOC := rk3308
+ SUPPORTED_DEVICES := radxa,rockpis
+ BOOT_SCRIPT := rock-pi-s
+ DEVICE_PACKAGES := kmod-rtw88-8723ds kmod-usb-net-cdc-ncm kmod-usb-net-rndis wpad-basic-mbedtls
+endef
+TARGET_DEVICES += radxa_rock-pi-s
+
+define Device/radxa_zero-3e
+ DEVICE_VENDOR := Radxa
+ DEVICE_MODEL := ZERO 3E
+ SOC := rk3566
+ DEVICE_DTS := rockchip/rk3566-radxa-zero-3e
+ UBOOT_DEVICE_NAME := radxa-zero-3-rk3566
+ DEVICE_PACKAGES := kmod-usb-net-cdc-ncm kmod-usb-net-rndis
+endef
+TARGET_DEVICES += radxa_zero-3e
+
+define Device/radxa_zero-3w
+ DEVICE_VENDOR := Radxa
+ DEVICE_MODEL := ZERO 3W
+ SOC := rk3566
+ DEVICE_DTS := rockchip/rk3566-radxa-zero-3w
+ UBOOT_DEVICE_NAME := radxa-zero-3-rk3566
+ DEVICE_PACKAGES := kmod-usb-net-cdc-ncm kmod-usb-net-rndis
+endef
+TARGET_DEVICES += radxa_zero-3w
+
define Device/sinovoip_bpi-r2-pro
DEVICE_VENDOR := Sinovoip
DEVICE_MODEL := Bananapi-R2 Pro
diff --git a/target/linux/rockchip/image/default.bootscript b/target/linux/rockchip/image/default.bootscript
index cca0b8d4ac..10ca93ceda 100644
--- a/target/linux/rockchip/image/default.bootscript
+++ b/target/linux/rockchip/image/default.bootscript
@@ -2,6 +2,8 @@ part uuid ${devtype} ${devnum}:2 uuid
if test $stdout = 'serial@fe660000' ;
then serial_addr=',0xfe660000';
+elif test $stdout = 'serial@feb50000' ;
+then serial_addr=',0xfeb50000';
elif test $stdout = 'serial@ff130000' ;
then serial_addr=',0xff130000';
elif test $stdout = 'serial@ff1a0000' ;
diff --git a/target/linux/rockchip/image/rock-pi-s.bootscript b/target/linux/rockchip/image/rock-pi-s.bootscript
new file mode 100644
index 0000000000..c968e53d81
--- /dev/null
+++ b/target/linux/rockchip/image/rock-pi-s.bootscript
@@ -0,0 +1,7 @@
+part uuid ${devtype} ${devnum}:2 uuid
+
+setenv bootargs "console=ttyS0,1500000 earlycon=uart8250,mmio32,0xff0a0000 root=PARTUUID=${uuid} rw rootwait";
+
+load ${devtype} ${devnum}:1 ${kernel_addr_r} kernel.img
+
+bootm ${kernel_addr_r}
diff --git a/target/linux/rockchip/patches-6.6/023-v6.8-arm64-dts-rockchip-Add-ethernet0-alias-to-the-dts-for-RK3566-boards.patch b/target/linux/rockchip/patches-6.6/001-v6.8-arm64-dts-rockchip-Add-ethernet0-alias-to-the-dts-for-RK3566-boards.patch
index fb5015cf6e..fb5015cf6e 100644
--- a/target/linux/rockchip/patches-6.6/023-v6.8-arm64-dts-rockchip-Add-ethernet0-alias-to-the-dts-for-RK3566-boards.patch
+++ b/target/linux/rockchip/patches-6.6/001-v6.8-arm64-dts-rockchip-Add-ethernet0-alias-to-the-dts-for-RK3566-boards.patch
diff --git a/target/linux/rockchip/patches-6.6/030-v6.9-arm64-dts-rockchip-adjust-vendor-on-Banana-Pi-R2-Pro.patch b/target/linux/rockchip/patches-6.6/002-v6.9-arm64-dts-rockchip-adjust-vendor-on-Banana-Pi-R2-Pro.patch
index 9be609f661..9be609f661 100644
--- a/target/linux/rockchip/patches-6.6/030-v6.9-arm64-dts-rockchip-adjust-vendor-on-Banana-Pi-R2-Pro.patch
+++ b/target/linux/rockchip/patches-6.6/002-v6.9-arm64-dts-rockchip-adjust-vendor-on-Banana-Pi-R2-Pro.patch
diff --git a/target/linux/rockchip/patches-6.6/031-v6.10-arm64-dts-rockchip-Add-cache-information-to-the-SoC-dtsi-.patch b/target/linux/rockchip/patches-6.6/003-v6.10-arm64-dts-rockchip-Add-cache-information-to-the-SoC-dtsi-.patch
index b23d7e06b9..b23d7e06b9 100644
--- a/target/linux/rockchip/patches-6.6/031-v6.10-arm64-dts-rockchip-Add-cache-information-to-the-SoC-dtsi-.patch
+++ b/target/linux/rockchip/patches-6.6/003-v6.10-arm64-dts-rockchip-Add-cache-information-to-the-SoC-dtsi-.patch
diff --git a/target/linux/rockchip/patches-6.6/004-next-soc-rockchip-io-domain-Add-RK3308-IO-voltage-domains.patch b/target/linux/rockchip/patches-6.6/004-next-soc-rockchip-io-domain-Add-RK3308-IO-voltage-domains.patch
new file mode 100644
index 0000000000..bb7f833977
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/004-next-soc-rockchip-io-domain-Add-RK3308-IO-voltage-domains.patch
@@ -0,0 +1,86 @@
+From 0536fa6e6fa3e48f4ca11855b586c277be524fbe Mon Sep 17 00:00:00 2001
+From: David Wu <david.wu@rock-chips.com>
+Date: Tue, 21 May 2024 21:10:13 +0000
+Subject: [PATCH] soc: rockchip: io-domain: Add RK3308 IO voltage domains
+
+Add IO voltage domains support for the RK3308 SoC.
+
+Signed-off-by: David Wu <david.wu@rock-chips.com>
+Signed-off-by: Jianqun Xu <jay.xu@rock-chips.com>
+Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
+Link: https://lore.kernel.org/r/20240521211029.1236094-11-jonas@kwiboo.se
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ drivers/soc/rockchip/io-domain.c | 40 ++++++++++++++++++++++++++++++++
+ 1 file changed, 40 insertions(+)
+
+--- a/drivers/soc/rockchip/io-domain.c
++++ b/drivers/soc/rockchip/io-domain.c
+@@ -39,6 +39,10 @@
+ #define RK3288_SOC_CON2_FLASH0 BIT(7)
+ #define RK3288_SOC_FLASH_SUPPLY_NUM 2
+
++#define RK3308_SOC_CON0 0x300
++#define RK3308_SOC_CON0_VCCIO3 BIT(8)
++#define RK3308_SOC_VCCIO3_SUPPLY_NUM 3
++
+ #define RK3328_SOC_CON4 0x410
+ #define RK3328_SOC_CON4_VCCIO2 BIT(7)
+ #define RK3328_SOC_VCCIO2_SUPPLY_NUM 1
+@@ -229,6 +233,25 @@ static void rk3288_iodomain_init(struct
+ dev_warn(iod->dev, "couldn't update flash0 ctrl\n");
+ }
+
++static void rk3308_iodomain_init(struct rockchip_iodomain *iod)
++{
++ int ret;
++ u32 val;
++
++ /* if no vccio3 supply we should leave things alone */
++ if (!iod->supplies[RK3308_SOC_VCCIO3_SUPPLY_NUM].reg)
++ return;
++
++ /*
++ * set vccio3 iodomain to also use this framework
++ * instead of a special gpio.
++ */
++ val = RK3308_SOC_CON0_VCCIO3 | (RK3308_SOC_CON0_VCCIO3 << 16);
++ ret = regmap_write(iod->grf, RK3308_SOC_CON0, val);
++ if (ret < 0)
++ dev_warn(iod->dev, "couldn't update vccio3 vsel ctrl\n");
++}
++
+ static void rk3328_iodomain_init(struct rockchip_iodomain *iod)
+ {
+ int ret;
+@@ -376,6 +399,19 @@ static const struct rockchip_iodomain_so
+ .init = rk3288_iodomain_init,
+ };
+
++static const struct rockchip_iodomain_soc_data soc_data_rk3308 = {
++ .grf_offset = 0x300,
++ .supply_names = {
++ "vccio0",
++ "vccio1",
++ "vccio2",
++ "vccio3",
++ "vccio4",
++ "vccio5",
++ },
++ .init = rk3308_iodomain_init,
++};
++
+ static const struct rockchip_iodomain_soc_data soc_data_rk3328 = {
+ .grf_offset = 0x410,
+ .supply_names = {
+@@ -529,6 +565,10 @@ static const struct of_device_id rockchi
+ .data = &soc_data_rk3288
+ },
+ {
++ .compatible = "rockchip,rk3308-io-voltage-domain",
++ .data = &soc_data_rk3308
++ },
++ {
+ .compatible = "rockchip,rk3328-io-voltage-domain",
+ .data = &soc_data_rk3328
+ },
diff --git a/target/linux/rockchip/patches-6.6/005-v6.11-arm64-dts-rockchip-Add-rk3308-IO-voltage-domains.patch b/target/linux/rockchip/patches-6.6/005-v6.11-arm64-dts-rockchip-Add-rk3308-IO-voltage-domains.patch
new file mode 100644
index 0000000000..3565acd2e4
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/005-v6.11-arm64-dts-rockchip-Add-rk3308-IO-voltage-domains.patch
@@ -0,0 +1,28 @@
+From d1829ba469d5743734e37d59fece73e3668ab084 Mon Sep 17 00:00:00 2001
+From: Jonas Karlman <jonas@kwiboo.se>
+Date: Tue, 21 May 2024 21:10:14 +0000
+Subject: [PATCH] arm64: dts: rockchip: Add rk3308 IO voltage domains
+
+Add a disabled RK3308 IO voltage domains node to SoC DT.
+
+Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
+Link: https://lore.kernel.org/r/20240521211029.1236094-12-jonas@kwiboo.se
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3308.dtsi | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3308.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3308.dtsi
+@@ -168,6 +168,11 @@
+ compatible = "rockchip,rk3308-grf", "syscon", "simple-mfd";
+ reg = <0x0 0xff000000 0x0 0x08000>;
+
++ io_domains: io-domains {
++ compatible = "rockchip,rk3308-io-voltage-domain";
++ status = "disabled";
++ };
++
+ reboot-mode {
+ compatible = "syscon-reboot-mode";
+ offset = <0x500>;
diff --git a/target/linux/rockchip/patches-6.6/006-v6.8-arm64-dts-rockchip-add-gpio-line-names-to-rk3308-roc.patch b/target/linux/rockchip/patches-6.6/006-v6.8-arm64-dts-rockchip-add-gpio-line-names-to-rk3308-roc.patch
new file mode 100644
index 0000000000..83ebe67789
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/006-v6.8-arm64-dts-rockchip-add-gpio-line-names-to-rk3308-roc.patch
@@ -0,0 +1,84 @@
+From c45de75d7a9ab44a15dedc7a121d6371d6891301 Mon Sep 17 00:00:00 2001
+From: Trevor Woerner <twoerner@gmail.com>
+Date: Mon, 20 Nov 2023 11:22:32 -0500
+Subject: [PATCH] arm64: dts: rockchip: add gpio-line-names to rk3308-rock-pi-s
+
+Add names to the pins of the general-purpose expansion header as given in the
+Radxa GPIO page[1] following the conventions in the kernel documentation[2] to
+make it easier for users to correlate the pins with functions when using
+utilities such as gpioinfo.
+
+[1] https://wiki.radxa.com/RockpiS/hardware/gpio
+[2] Documentation/devicetree/bindings/gpio/gpio.txt
+
+Signed-off-by: Trevor Woerner <twoerner@gmail.com>
+Link: https://lore.kernel.org/r/20231120162232.27653-1-twoerner@gmail.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ .../boot/dts/rockchip/rk3308-rock-pi-s.dts | 58 +++++++++++++++++++
+ 1 file changed, 58 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts
+@@ -315,3 +315,61 @@
+ &wdt {
+ status = "okay";
+ };
++
++&gpio0 {
++ gpio-line-names =
++ /* GPIO0_A0 - A7 */
++ "", "", "", "", "", "", "", "",
++ /* GPIO0_B0 - B7 */
++ "", "", "", "header1-pin3 [GPIO0_B3]", "header1-pin5 [GPIO0_B4]",
++ "", "", "header1-pin11 [GPIO0_B7]",
++ /* GPIO0_C0 - C7 */
++ "header1-pin13 [GPIO0_C0]", "header1-pin15 [GPIO0_C1]", "", "", "",
++ "", "", "",
++ /* GPIO0_D0 - D8 */
++ "", "", "", "", "", "", "", "";
++};
++
++&gpio1 {
++ gpio-line-names =
++ /* GPIO1_A0 - A7 */
++ "", "", "", "", "", "", "", "",
++ /* GPIO1_B0 - B7 */
++ "", "", "", "", "", "", "", "",
++ /* GPIO1_C0 - C7 */
++ "", "", "", "", "", "", "header1-pin21 [GPIO1_C6]",
++ "header1-pin19 [GPIO1_C7]",
++ /* GPIO1_D0 - D8 */
++ "header1-pin23 [GPIO1_D0]", "header1-pin24 [GPIO1_D1]", "", "", "",
++ "", "", "";
++};
++
++&gpio2 {
++ gpio-line-names =
++ /* GPIO2_A0 - A7 */
++ "header1-pin10 [GPIO2_A0]", "header1-pin8 [GPIO2_A1]", "", "",
++ "header1-pin7 [GPIO2_A4]", "header1-pin12 [GPIO2_A5]",
++ "header2-pin46 [GPIO2_A6]", "header1-pin22 [GPIO1_A7]",
++ /* GPIO2_B0 - B7 */
++ "header2-pin45 [GPIO2_B0]", "header1-pin18 [GPIO2_B1]",
++ "header1-pin16 [GPIO2_B2]", "header2-pin44 [GPIO2_B3]",
++ "header2-pin43 [GPIO2_B4]", "header2-pin28 [GPIO2_B5]",
++ "header2-pin30 [GPIO2_B6]", "header2-pin32 [GPIO2_B7]",
++ /* GPIO2_C0 - C7 */
++ "header2-pin34 [GPIO2_C0]", "", "", "", "", "", "", "",
++ /* GPIO2_D0 - D8 */
++ "", "", "", "", "", "", "", "";
++};
++
++&gpio3 {
++ gpio-line-names =
++ /* GPIO3_A0 - A7 */
++ "", "", "", "", "", "", "", "",
++ /* GPIO3_B0 - B7 */
++ "", "", "header2-pin42 [GPIO3_B2]", "header2-pin41 [GPIO3_B3]",
++ "header2-pin40 [GPIO3_B4]", "header2-pin39 [GPIO3_B5]", "", "",
++ /* GPIO3_C0 - C7 */
++ "", "", "", "", "", "", "", "",
++ /* GPIO3_D0 - D8 */
++ "", "", "", "", "", "", "", "";
++};
diff --git a/target/linux/rockchip/patches-6.6/007-v6.8-arm64-dts-rockchip-rk3308-rock-pi-s-gpio-line-names-.patch b/target/linux/rockchip/patches-6.6/007-v6.8-arm64-dts-rockchip-rk3308-rock-pi-s-gpio-line-names-.patch
new file mode 100644
index 0000000000..994644e142
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/007-v6.8-arm64-dts-rockchip-rk3308-rock-pi-s-gpio-line-names-.patch
@@ -0,0 +1,152 @@
+From 085021cc825ed90a6ddc4406f608fb8a85745f81 Mon Sep 17 00:00:00 2001
+From: Trevor Woerner <twoerner@gmail.com>
+Date: Tue, 19 Dec 2023 12:38:13 -0500
+Subject: [PATCH] arm64: dts: rockchip: rk3308-rock-pi-s gpio-line-names
+ cleanup
+
+Perform the following cleanups on a previous patch:
+- indent lines after "gpio-line-names"
+- fix D0-D8 -> D0-D7
+- sort phandle references
+
+Fixes: c45de75d7a9a ("arm64: dts: rockchip: add gpio-line-names to rk3308-rock-pi-s")
+Signed-off-by: Trevor Woerner <twoerner@gmail.com>
+Link: https://lore.kernel.org/r/20231219173814.1569-1-twoerner@gmail.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ .../boot/dts/rockchip/rk3308-rock-pi-s.dts | 120 +++++++++---------
+ 1 file changed, 62 insertions(+), 58 deletions(-)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts
+@@ -166,6 +166,68 @@
+ };
+ };
+
++&gpio0 {
++ gpio-line-names =
++ /* GPIO0_A0 - A7 */
++ "", "", "", "", "", "", "", "",
++ /* GPIO0_B0 - B7 */
++ "", "", "", "header1-pin3 [GPIO0_B3]",
++ "header1-pin5 [GPIO0_B4]", "", "",
++ "header1-pin11 [GPIO0_B7]",
++ /* GPIO0_C0 - C7 */
++ "header1-pin13 [GPIO0_C0]",
++ "header1-pin15 [GPIO0_C1]", "", "", "",
++ "", "", "",
++ /* GPIO0_D0 - D7 */
++ "", "", "", "", "", "", "", "";
++};
++
++&gpio1 {
++ gpio-line-names =
++ /* GPIO1_A0 - A7 */
++ "", "", "", "", "", "", "", "",
++ /* GPIO1_B0 - B7 */
++ "", "", "", "", "", "", "", "",
++ /* GPIO1_C0 - C7 */
++ "", "", "", "", "", "", "header1-pin21 [GPIO1_C6]",
++ "header1-pin19 [GPIO1_C7]",
++ /* GPIO1_D0 - D7 */
++ "header1-pin23 [GPIO1_D0]", "header1-pin24 [GPIO1_D1]",
++ "", "", "", "", "", "";
++};
++
++&gpio2 {
++ gpio-line-names =
++ /* GPIO2_A0 - A7 */
++ "header1-pin10 [GPIO2_A0]", "header1-pin8 [GPIO2_A1]",
++ "", "",
++ "header1-pin7 [GPIO2_A4]", "header1-pin12 [GPIO2_A5]",
++ "header2-pin46 [GPIO2_A6]", "header1-pin22 [GPIO1_A7]",
++ /* GPIO2_B0 - B7 */
++ "header2-pin45 [GPIO2_B0]", "header1-pin18 [GPIO2_B1]",
++ "header1-pin16 [GPIO2_B2]", "header2-pin44 [GPIO2_B3]",
++ "header2-pin43 [GPIO2_B4]", "header2-pin28 [GPIO2_B5]",
++ "header2-pin30 [GPIO2_B6]", "header2-pin32 [GPIO2_B7]",
++ /* GPIO2_C0 - C7 */
++ "header2-pin34 [GPIO2_C0]", "", "", "", "", "", "", "",
++ /* GPIO2_D0 - D7 */
++ "", "", "", "", "", "", "", "";
++};
++
++&gpio3 {
++ gpio-line-names =
++ /* GPIO3_A0 - A7 */
++ "", "", "", "", "", "", "", "",
++ /* GPIO3_B0 - B7 */
++ "", "", "header2-pin42 [GPIO3_B2]",
++ "header2-pin41 [GPIO3_B3]", "header2-pin40 [GPIO3_B4]",
++ "header2-pin39 [GPIO3_B5]", "", "",
++ /* GPIO3_C0 - C7 */
++ "", "", "", "", "", "", "", "",
++ /* GPIO3_D0 - D7 */
++ "", "", "", "", "", "", "", "";
++};
++
+ &i2c1 {
+ status = "okay";
+ };
+@@ -315,61 +377,3 @@
+ &wdt {
+ status = "okay";
+ };
+-
+-&gpio0 {
+- gpio-line-names =
+- /* GPIO0_A0 - A7 */
+- "", "", "", "", "", "", "", "",
+- /* GPIO0_B0 - B7 */
+- "", "", "", "header1-pin3 [GPIO0_B3]", "header1-pin5 [GPIO0_B4]",
+- "", "", "header1-pin11 [GPIO0_B7]",
+- /* GPIO0_C0 - C7 */
+- "header1-pin13 [GPIO0_C0]", "header1-pin15 [GPIO0_C1]", "", "", "",
+- "", "", "",
+- /* GPIO0_D0 - D8 */
+- "", "", "", "", "", "", "", "";
+-};
+-
+-&gpio1 {
+- gpio-line-names =
+- /* GPIO1_A0 - A7 */
+- "", "", "", "", "", "", "", "",
+- /* GPIO1_B0 - B7 */
+- "", "", "", "", "", "", "", "",
+- /* GPIO1_C0 - C7 */
+- "", "", "", "", "", "", "header1-pin21 [GPIO1_C6]",
+- "header1-pin19 [GPIO1_C7]",
+- /* GPIO1_D0 - D8 */
+- "header1-pin23 [GPIO1_D0]", "header1-pin24 [GPIO1_D1]", "", "", "",
+- "", "", "";
+-};
+-
+-&gpio2 {
+- gpio-line-names =
+- /* GPIO2_A0 - A7 */
+- "header1-pin10 [GPIO2_A0]", "header1-pin8 [GPIO2_A1]", "", "",
+- "header1-pin7 [GPIO2_A4]", "header1-pin12 [GPIO2_A5]",
+- "header2-pin46 [GPIO2_A6]", "header1-pin22 [GPIO1_A7]",
+- /* GPIO2_B0 - B7 */
+- "header2-pin45 [GPIO2_B0]", "header1-pin18 [GPIO2_B1]",
+- "header1-pin16 [GPIO2_B2]", "header2-pin44 [GPIO2_B3]",
+- "header2-pin43 [GPIO2_B4]", "header2-pin28 [GPIO2_B5]",
+- "header2-pin30 [GPIO2_B6]", "header2-pin32 [GPIO2_B7]",
+- /* GPIO2_C0 - C7 */
+- "header2-pin34 [GPIO2_C0]", "", "", "", "", "", "", "",
+- /* GPIO2_D0 - D8 */
+- "", "", "", "", "", "", "", "";
+-};
+-
+-&gpio3 {
+- gpio-line-names =
+- /* GPIO3_A0 - A7 */
+- "", "", "", "", "", "", "", "",
+- /* GPIO3_B0 - B7 */
+- "", "", "header2-pin42 [GPIO3_B2]", "header2-pin41 [GPIO3_B3]",
+- "header2-pin40 [GPIO3_B4]", "header2-pin39 [GPIO3_B5]", "", "",
+- /* GPIO3_C0 - C7 */
+- "", "", "", "", "", "", "", "",
+- /* GPIO3_D0 - D8 */
+- "", "", "", "", "", "", "", "";
+-};
diff --git a/target/linux/rockchip/patches-6.6/008-v6.11-arm64-dts-rockchip-Add-io-domains-to-rk3308-rock-pi-.patch b/target/linux/rockchip/patches-6.6/008-v6.11-arm64-dts-rockchip-Add-io-domains-to-rk3308-rock-pi-.patch
new file mode 100644
index 0000000000..ad746df3b0
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/008-v6.11-arm64-dts-rockchip-Add-io-domains-to-rk3308-rock-pi-.patch
@@ -0,0 +1,35 @@
+From 100b3bdee6035192f6d4a1847970fe004bb505fb Mon Sep 17 00:00:00 2001
+From: Jonas Karlman <jonas@kwiboo.se>
+Date: Tue, 21 May 2024 21:10:15 +0000
+Subject: [PATCH] arm64: dts: rockchip: Add io-domains to rk3308-rock-pi-s
+
+The VCCIO4 io-domain used for WiFi/BT is using 1v8 IO signal voltage.
+
+Add io-domains node with the VCCIO supplies connected on the board.
+
+Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
+Link: https://lore.kernel.org/r/20240521211029.1236094-13-jonas@kwiboo.se
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts
+@@ -232,6 +232,16 @@
+ status = "okay";
+ };
+
++&io_domains {
++ vccio0-supply = <&vcc_io>;
++ vccio1-supply = <&vcc_io>;
++ vccio2-supply = <&vcc_io>;
++ vccio3-supply = <&vcc_io>;
++ vccio4-supply = <&vcc_1v8>;
++ vccio5-supply = <&vcc_io>;
++ status = "okay";
++};
++
+ &pinctrl {
+ pinctrl-names = "default";
+ pinctrl-0 = <&rtc_32k>;
diff --git a/target/linux/rockchip/patches-6.6/009-v6.10-arm64-dts-rockchip-Add-Radxa-ROCK-3C.patch b/target/linux/rockchip/patches-6.6/009-v6.10-arm64-dts-rockchip-Add-Radxa-ROCK-3C.patch
new file mode 100644
index 0000000000..9901d9fff0
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/009-v6.10-arm64-dts-rockchip-Add-Radxa-ROCK-3C.patch
@@ -0,0 +1,769 @@
+From ee219017ddb50be14c60d3cbe3e51ac0b2008d40 Mon Sep 17 00:00:00 2001
+From: Chukun Pan <amadeus@jmu.edu.cn>
+Date: Sun, 28 Apr 2024 20:36:18 +0800
+Subject: [PATCH] arm64: dts: rockchip: Add Radxa ROCK 3C
+
+The Radxa ROCK 3C is a development board with the
+Rockchip RK3566 SoC. It has the following features:
+
+- 1/2/4GB LPDDR4
+- 1x HDMI Type A
+- 1x PCIE 2.0 slot
+- 1x FAN connector
+- 3.5mm jack with mic
+- 1GbE RTL8211F Ethernet
+- 1x USB 3.0, 3x USB 2.0
+- 40-pin expansion header
+- MicroSD card/eMMC socket
+- 16MB SPI NOR (gd25lq128d)
+- AP6256 or AIC8800 WiFi/BT
+
+Signed-off-by: Chukun Pan <amadeus@jmu.edu.cn>
+Link: https://lore.kernel.org/r/20240428123618.72170-3-amadeus@jmu.edu.cn
+[dropped rk809-sound and not specified pmic sound properties]
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/Makefile | 1 +
+ .../boot/dts/rockchip/rk3566-rock-3c.dts | 726 ++++++++++++++++++
+ 2 files changed, 727 insertions(+)
+ create mode 100644 arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts
+
+--- a/arch/arm64/boot/dts/rockchip/Makefile
++++ b/arch/arm64/boot/dts/rockchip/Makefile
+@@ -81,6 +81,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-qu
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-quartz64-b.dtb
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-radxa-cm3-io.dtb
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-roc-pc.dtb
++dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-rock-3c.dtb
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-soquartz-blade.dtb
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-soquartz-cm4.dtb
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-soquartz-model-a.dtb
+--- /dev/null
++++ b/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts
+@@ -0,0 +1,726 @@
++// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
++
++/dts-v1/;
++#include <dt-bindings/gpio/gpio.h>
++#include <dt-bindings/leds/common.h>
++#include <dt-bindings/pinctrl/rockchip.h>
++#include <dt-bindings/soc/rockchip,vop2.h>
++#include "rk3566.dtsi"
++
++/ {
++ model = "Radxa ROCK 3C";
++ compatible = "radxa,rock-3c", "rockchip,rk3566";
++
++ aliases {
++ ethernet0 = &gmac1;
++ mmc0 = &sdhci;
++ mmc1 = &sdmmc0;
++ mmc2 = &sdmmc1;
++ };
++
++ chosen: chosen {
++ stdout-path = "serial2:1500000n8";
++ };
++
++ gmac1_clkin: external-gmac1-clock {
++ compatible = "fixed-clock";
++ clock-frequency = <125000000>;
++ clock-output-names = "gmac1_clkin";
++ #clock-cells = <0>;
++ };
++
++ hdmi-con {
++ compatible = "hdmi-connector";
++ type = "a";
++
++ port {
++ hdmi_con_in: endpoint {
++ remote-endpoint = <&hdmi_out_con>;
++ };
++ };
++ };
++
++ leds {
++ compatible = "gpio-leds";
++
++ led-0 {
++ gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>;
++ function = LED_FUNCTION_HEARTBEAT;
++ color = <LED_COLOR_ID_BLUE>;
++ linux,default-trigger = "heartbeat";
++ pinctrl-names = "default";
++ pinctrl-0 = <&user_led2>;
++ };
++ };
++
++ sdio_pwrseq: sdio-pwrseq {
++ compatible = "mmc-pwrseq-simple";
++ clocks = <&rk809 1>;
++ clock-names = "ext_clock";
++ pinctrl-names = "default";
++ pinctrl-0 = <&wifi_reg_on_h>;
++ post-power-on-delay-ms = <100>;
++ power-off-delay-us = <5000000>;
++ reset-gpios = <&gpio0 RK_PC0 GPIO_ACTIVE_LOW>;
++ };
++
++ vcc5v_dcin: vcc5v-dcin-regulator {
++ compatible = "regulator-fixed";
++ regulator-name = "vcc5v_dcin";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <5000000>;
++ regulator-max-microvolt = <5000000>;
++ };
++
++ vcc3v3_pcie: vcc3v3-pcie-regulator {
++ compatible = "regulator-fixed";
++ enable-active-high;
++ gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&pcie_pwr_en>;
++ regulator-name = "vcc3v3_pcie";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ vin-supply = <&vcc3v3_sys>;
++ };
++
++ vcc3v3_sys: vcc3v3-sys-regulator {
++ compatible = "regulator-fixed";
++ regulator-name = "vcc3v3_sys";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ vin-supply = <&vcc5v0_sys>;
++ };
++
++ vcc5v0_sys: vcc5v0-sys-regulator {
++ compatible = "regulator-fixed";
++ regulator-name = "vcc5v0_sys";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <5000000>;
++ regulator-max-microvolt = <5000000>;
++ vin-supply = <&vcc5v_dcin>;
++ };
++
++ vcc5v0_usb30_host: vcc5v0-usb30-host-regulator {
++ compatible = "regulator-fixed";
++ enable-active-high;
++ gpio = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&vcc5v0_usb30_host_en>;
++ regulator-name = "vcc5v0_usb30_host";
++ regulator-min-microvolt = <5000000>;
++ regulator-max-microvolt = <5000000>;
++ vin-supply = <&vcc5v0_sys>;
++ };
++
++ vcc5v0_usb_otg: vcc5v0-usb-otg-regulator {
++ compatible = "regulator-fixed";
++ enable-active-high;
++ gpio = <&gpio0 RK_PC6 GPIO_ACTIVE_HIGH>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&vcc5v0_usb_otg_en>;
++ regulator-name = "vcc5v0_usb_otg";
++ regulator-min-microvolt = <5000000>;
++ regulator-max-microvolt = <5000000>;
++ vin-supply = <&vcc5v0_sys>;
++ };
++
++ vcc_cam: vcc-cam-regulator {
++ compatible = "regulator-fixed";
++ enable-active-high;
++ gpio = <&gpio0 RK_PC4 GPIO_ACTIVE_HIGH>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&vcc_cam_en>;
++ regulator-name = "vcc_cam";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ vin-supply = <&vcc3v3_sys>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vcc_mipi: vcc-mipi-regulator {
++ compatible = "regulator-fixed";
++ enable-active-high;
++ gpio = <&gpio0 RK_PC7 GPIO_ACTIVE_HIGH>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&vcc_mipi_en>;
++ regulator-name = "vcc_mipi";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ vin-supply = <&vcc3v3_sys>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++};
++
++&combphy1 {
++ status = "okay";
++};
++
++&combphy2 {
++ status = "okay";
++};
++
++&cpu0 {
++ cpu-supply = <&vdd_cpu>;
++};
++
++&cpu1 {
++ cpu-supply = <&vdd_cpu>;
++};
++
++&cpu2 {
++ cpu-supply = <&vdd_cpu>;
++};
++
++&cpu3 {
++ cpu-supply = <&vdd_cpu>;
++};
++
++&gmac1 {
++ assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1>;
++ assigned-clock-parents = <&cru SCLK_GMAC1_RGMII_SPEED>, <&gmac1_clkin>;
++ clock_in_out = "input";
++ phy-handle = <&rgmii_phy1>;
++ phy-mode = "rgmii-id";
++ phy-supply = <&vcc_3v3>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&gmac1m1_miim
++ &gmac1m1_tx_bus2
++ &gmac1m1_rx_bus2
++ &gmac1m1_rgmii_clk
++ &gmac1m1_rgmii_bus
++ &gmac1m1_clkinout>;
++ status = "okay";
++};
++
++&gpu {
++ mali-supply = <&vdd_gpu>;
++ status = "okay";
++};
++
++&hdmi {
++ avdd-0v9-supply = <&vdda0v9_image>;
++ avdd-1v8-supply = <&vcca1v8_image>;
++ status = "okay";
++};
++
++&hdmi_in {
++ hdmi_in_vp0: endpoint {
++ remote-endpoint = <&vp0_out_hdmi>;
++ };
++};
++
++&hdmi_out {
++ hdmi_out_con: endpoint {
++ remote-endpoint = <&hdmi_con_in>;
++ };
++};
++
++&hdmi_sound {
++ status = "okay";
++};
++
++&i2c0 {
++ status = "okay";
++
++ vdd_cpu: regulator@1c {
++ compatible = "tcs,tcs4525";
++ reg = <0x1c>;
++ fcs,suspend-voltage-selector = <1>;
++ regulator-name = "vdd_cpu";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <800000>;
++ regulator-max-microvolt = <1150000>;
++ regulator-ramp-delay = <2300>;
++ vin-supply = <&vcc5v0_sys>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ rk809: pmic@20 {
++ compatible = "rockchip,rk809";
++ reg = <0x20>;
++ interrupt-parent = <&gpio0>;
++ interrupts = <RK_PA3 IRQ_TYPE_LEVEL_LOW>;
++ clock-output-names = "rk808-clkout1", "rk808-clkout2";
++ pinctrl-names = "default";
++ pinctrl-0 = <&pmic_int_l>, <&i2s1m0_mclk>;
++ system-power-controller;
++ vcc1-supply = <&vcc3v3_sys>;
++ vcc2-supply = <&vcc3v3_sys>;
++ vcc3-supply = <&vcc3v3_sys>;
++ vcc4-supply = <&vcc3v3_sys>;
++ vcc5-supply = <&vcc3v3_sys>;
++ vcc6-supply = <&vcc3v3_sys>;
++ vcc7-supply = <&vcc3v3_sys>;
++ vcc8-supply = <&vcc3v3_sys>;
++ vcc9-supply = <&vcc3v3_sys>;
++ wakeup-source;
++ #clock-cells = <1>;
++
++ regulators {
++ vdd_logic: DCDC_REG1 {
++ regulator-name = "vdd_logic";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-initial-mode = <0x2>;
++ regulator-min-microvolt = <500000>;
++ regulator-max-microvolt = <1350000>;
++ regulator-ramp-delay = <6001>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ regulator-suspend-microvolt = <900000>;
++ };
++ };
++
++ vdd_gpu: DCDC_REG2 {
++ regulator-name = "vdd_gpu";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-initial-mode = <0x2>;
++ regulator-min-microvolt = <500000>;
++ regulator-max-microvolt = <1350000>;
++ regulator-ramp-delay = <6001>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ regulator-suspend-microvolt = <900000>;
++ };
++ };
++
++ vcc_ddr: DCDC_REG3 {
++ regulator-name = "vcc_ddr";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-initial-mode = <0x2>;
++
++ regulator-state-mem {
++ regulator-on-in-suspend;
++ };
++ };
++
++ vdd_npu: DCDC_REG4 {
++ regulator-name = "vdd_npu";
++ regulator-initial-mode = <0x2>;
++ regulator-min-microvolt = <500000>;
++ regulator-max-microvolt = <1350000>;
++ regulator-ramp-delay = <6001>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vcc_1v8: DCDC_REG5 {
++ regulator-name = "vcc_1v8";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vdda0v9_image: LDO_REG1 {
++ regulator-name = "vdda0v9_image";
++ regulator-min-microvolt = <900000>;
++ regulator-max-microvolt = <900000>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vdda_0v9: LDO_REG2 {
++ regulator-name = "vdda_0v9";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <900000>;
++ regulator-max-microvolt = <900000>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vdda0v9_pmu: LDO_REG3 {
++ regulator-name = "vdda0v9_pmu";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <900000>;
++ regulator-max-microvolt = <900000>;
++
++ regulator-state-mem {
++ regulator-on-in-suspend;
++ regulator-suspend-microvolt = <900000>;
++ };
++ };
++
++ vccio_acodec: LDO_REG4 {
++ regulator-name = "vccio_acodec";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vccio_sd: LDO_REG5 {
++ regulator-name = "vccio_sd";
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <3300000>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vcc3v3_pmu: LDO_REG6 {
++ regulator-name = "vcc3v3_pmu";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++
++ regulator-state-mem {
++ regulator-on-in-suspend;
++ regulator-suspend-microvolt = <3300000>;
++ };
++ };
++
++ vcca_1v8: LDO_REG7 {
++ regulator-name = "vcca_1v8";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vcca1v8_pmu: LDO_REG8 {
++ regulator-name = "vcca1v8_pmu";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++
++ regulator-state-mem {
++ regulator-on-in-suspend;
++ regulator-suspend-microvolt = <1800000>;
++ };
++ };
++
++ vcca1v8_image: LDO_REG9 {
++ regulator-name = "vcca1v8_image";
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vcc_3v3: SWITCH_REG1 {
++ regulator-name = "vcc_3v3";
++ regulator-always-on;
++ regulator-boot-on;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vcc3v3_sd: SWITCH_REG2 {
++ regulator-name = "vcc3v3_sd";
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++ };
++ };
++
++ eeprom: eeprom@50 {
++ compatible = "belling,bl24c16a", "atmel,24c16";
++ reg = <0x50>;
++ pagesize = <16>;
++ };
++};
++
++&i2s0_8ch {
++ status = "okay";
++};
++
++&i2s1_8ch {
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2s1m0_sclktx &i2s1m0_lrcktx &i2s1m0_sdi0 &i2s1m0_sdo0>;
++ rockchip,trcm-sync-tx-only;
++ status = "okay";
++};
++
++&mdio1 {
++ rgmii_phy1: ethernet-phy@1 {
++ compatible = "ethernet-phy-ieee802.3-c22";
++ reg = <0x1>;
++ reset-assert-us = <20000>;
++ reset-deassert-us = <100000>;
++ reset-gpios = <&gpio3 RK_PC0 GPIO_ACTIVE_LOW>;
++ };
++};
++
++&pcie2x1 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&pcie_reset_h>;
++ reset-gpios = <&gpio1 RK_PB2 GPIO_ACTIVE_HIGH>;
++ vpcie3v3-supply = <&vcc3v3_pcie>;
++ status = "okay";
++};
++
++&pinctrl {
++ bluetooth {
++ bt_reg_on_h: bt-reg-on-h {
++ rockchip,pins = <0 RK_PC1 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++
++ bt_wake_host_h: bt-wake-host-h {
++ rockchip,pins = <0 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++
++ bt_host_wake_h: bt-host-wake-h {
++ rockchip,pins = <0 RK_PB4 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
++
++ cam {
++ vcc_cam_en: vcc_cam_en {
++ rockchip,pins = <0 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
++
++ display {
++ vcc_mipi_en: vcc_mipi_en {
++ rockchip,pins = <0 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
++
++ leds {
++ user_led2: user-led2 {
++ rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
++
++ pcie {
++ pcie_pwr_en: pcie-pwr-en {
++ rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++
++ pcie_reset_h: pcie-reset-h {
++ rockchip,pins = <1 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
++
++ pmic {
++ pmic_int_l: pmic-int-l {
++ rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
++ };
++ };
++
++ usb {
++ vcc5v0_usb30_host_en: vcc5v0-usb30-host-en {
++ rockchip,pins = <0 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++
++ vcc5v0_usb_otg_en: vcc5v0-usb-otg-en {
++ rockchip,pins = <0 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
++
++ wifi {
++ wifi_host_wake_h: wifi-host-wake-h {
++ rockchip,pins = <0 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++
++ wifi_reg_on_h: wifi-reg-on-h {
++ rockchip,pins = <0 RK_PC0 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
++};
++
++&pmu_io_domains {
++ pmuio1-supply = <&vcc3v3_pmu>;
++ pmuio2-supply = <&vcca1v8_pmu>;
++ vccio1-supply = <&vccio_acodec>;
++ vccio2-supply = <&vcc_1v8>;
++ vccio3-supply = <&vccio_sd>;
++ vccio4-supply = <&vcca1v8_pmu>;
++ vccio5-supply = <&vcc_3v3>;
++ vccio6-supply = <&vcc_3v3>;
++ vccio7-supply = <&vcc_3v3>;
++ status = "okay";
++};
++
++&saradc {
++ vref-supply = <&vcca_1v8>;
++ status = "okay";
++};
++
++&sdhci {
++ bus-width = <8>;
++ max-frequency = <200000000>;
++ mmc-hs200-1_8v;
++ non-removable;
++ pinctrl-names = "default";
++ pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd &emmc_datastrobe>;
++ vmmc-supply = <&vcc_3v3>;
++ vqmmc-supply = <&vcc_1v8>;
++ status = "okay";
++};
++
++&sdmmc0 {
++ bus-width = <4>;
++ cap-sd-highspeed;
++ disable-wp;
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd &sdmmc0_det>;
++ sd-uhs-sdr50;
++ vmmc-supply = <&vcc3v3_sys>;
++ vqmmc-supply = <&vccio_sd>;
++ status = "okay";
++};
++
++&sdmmc1 {
++ bus-width = <4>;
++ cap-sd-highspeed;
++ cap-sdio-irq;
++ keep-power-in-suspend;
++ mmc-pwrseq = <&sdio_pwrseq>;
++ non-removable;
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdmmc1_bus4 &sdmmc1_clk &sdmmc1_cmd>;
++ sd-uhs-sdr104;
++ vmmc-supply = <&vcc3v3_sys>;
++ vqmmc-supply = <&vcca1v8_pmu>;
++ status = "okay";
++};
++
++&sfc {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "okay";
++
++ flash@0 {
++ compatible = "jedec,spi-nor";
++ reg = <0x0>;
++ spi-max-frequency = <120000000>;
++ spi-rx-bus-width = <4>;
++ spi-tx-bus-width = <1>;
++ };
++};
++
++&tsadc {
++ rockchip,hw-tshut-mode = <1>;
++ rockchip,hw-tshut-polarity = <0>;
++ status = "okay";
++};
++
++&uart1 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&uart1m0_ctsn &uart1m0_rtsn &uart1m0_xfer>;
++ status = "okay";
++};
++
++&uart2 {
++ status = "okay";
++};
++
++&usb_host0_ehci {
++ status = "okay";
++};
++
++&usb_host0_ohci {
++ status = "okay";
++};
++
++&usb_host0_xhci {
++ dr_mode = "host";
++ status = "okay";
++};
++
++&usb_host1_ehci {
++ status = "okay";
++};
++
++&usb_host1_ohci {
++ status = "okay";
++};
++
++&usb_host1_xhci {
++ status = "okay";
++};
++
++&usb2phy0 {
++ status = "okay";
++};
++
++&usb2phy0_host {
++ phy-supply = <&vcc5v0_usb30_host>;
++ status = "okay";
++};
++
++&usb2phy0_otg {
++ phy-supply = <&vcc5v0_usb_otg>;
++ status = "okay";
++};
++
++&usb2phy1 {
++ status = "okay";
++};
++
++&usb2phy1_host {
++ phy-supply = <&vcc5v0_usb30_host>;
++ status = "okay";
++};
++
++&usb2phy1_otg {
++ phy-supply = <&vcc5v0_usb30_host>;
++ status = "okay";
++};
++
++&vop {
++ assigned-clocks = <&cru DCLK_VOP0>, <&cru DCLK_VOP1>;
++ assigned-clock-parents = <&pmucru PLL_HPLL>, <&cru PLL_VPLL>;
++ status = "okay";
++};
++
++&vop_mmu {
++ status = "okay";
++};
++
++&vp0 {
++ vp0_out_hdmi: endpoint@ROCKCHIP_VOP2_EP_HDMI0 {
++ reg = <ROCKCHIP_VOP2_EP_HDMI0>;
++ remote-endpoint = <&hdmi_in_vp0>;
++ };
++};
diff --git a/target/linux/rockchip/patches-6.6/010-v6.11-arm64-dts-rockchip-change-spi-max-frequency-for-Radx.patch b/target/linux/rockchip/patches-6.6/010-v6.11-arm64-dts-rockchip-change-spi-max-frequency-for-Radx.patch
new file mode 100644
index 0000000000..936fe91c5d
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/010-v6.11-arm64-dts-rockchip-change-spi-max-frequency-for-Radx.patch
@@ -0,0 +1,26 @@
+From 06f6dd4d607766a527e37529f2f3f90dd1464293 Mon Sep 17 00:00:00 2001
+From: FUKAUMI Naoki <naoki@radxa.com>
+Date: Sun, 23 Jun 2024 11:33:29 +0900
+Subject: [PATCH] arm64: dts: rockchip: change spi-max-frequency for Radxa ROCK
+ 3C
+
+SPI NOR flash chip may vary, so use safe(lowest) spi-max-frequency.
+
+Signed-off-by: FUKAUMI Naoki <naoki@radxa.com>
+Link: https://lore.kernel.org/r/20240623023329.1044-3-naoki@radxa.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts
+@@ -633,7 +633,7 @@
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0x0>;
+- spi-max-frequency = <120000000>;
++ spi-max-frequency = <104000000>;
+ spi-rx-bus-width = <4>;
+ spi-tx-bus-width = <1>;
+ };
diff --git a/target/linux/rockchip/patches-6.6/011-v6.11-arm64-dts-rockchip-Add-Radxa-ZERO-3W-3E.patch b/target/linux/rockchip/patches-6.6/011-v6.11-arm64-dts-rockchip-Add-Radxa-ZERO-3W-3E.patch
new file mode 100644
index 0000000000..746078cf9e
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/011-v6.11-arm64-dts-rockchip-Add-Radxa-ZERO-3W-3E.patch
@@ -0,0 +1,657 @@
+From 1a5c8d307c83c808a32686ed51afb4bac2092d39 Mon Sep 17 00:00:00 2001
+From: Jonas Karlman <jonas@kwiboo.se>
+Date: Tue, 21 May 2024 20:28:05 +0000
+Subject: [PATCH] arm64: dts: rockchip: Add Radxa ZERO 3W/3E
+
+The Radxa ZERO 3W/3E is an ultra-small, high-performance single board
+computer based on the Rockchip RK3566, with a compact form factor and
+rich interfaces.
+
+The ZERO 3W and ZERO 3E are basically the same size and model, but
+differ only in storage and network interfaces.
+
+- eMMC (3W)
+- SD-card (both)
+- Ethernet (3E)
+- WiFi/BT (3W)
+
+Add initial support for eMMC, SD-card, Ethernet, HDMI and USB.
+
+Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
+Link: https://lore.kernel.org/r/20240521202810.1225636-3-jonas@kwiboo.se
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/Makefile | 2 +
+ .../dts/rockchip/rk3566-radxa-zero-3.dtsi | 463 ++++++++++++++++++
+ .../dts/rockchip/rk3566-radxa-zero-3e.dts | 51 ++
+ .../dts/rockchip/rk3566-radxa-zero-3w.dts | 91 ++++
+ 4 files changed, 607 insertions(+)
+ create mode 100644 arch/arm64/boot/dts/rockchip/rk3566-radxa-zero-3.dtsi
+ create mode 100644 arch/arm64/boot/dts/rockchip/rk3566-radxa-zero-3e.dts
+ create mode 100644 arch/arm64/boot/dts/rockchip/rk3566-radxa-zero-3w.dts
+
+--- a/arch/arm64/boot/dts/rockchip/Makefile
++++ b/arch/arm64/boot/dts/rockchip/Makefile
+@@ -80,6 +80,8 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-pi
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-quartz64-a.dtb
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-quartz64-b.dtb
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-radxa-cm3-io.dtb
++dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-radxa-zero-3e.dtb
++dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-radxa-zero-3w.dtb
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-roc-pc.dtb
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-rock-3c.dtb
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-soquartz-blade.dtb
+--- /dev/null
++++ b/arch/arm64/boot/dts/rockchip/rk3566-radxa-zero-3.dtsi
+@@ -0,0 +1,463 @@
++// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
++
++#include <dt-bindings/gpio/gpio.h>
++#include <dt-bindings/leds/common.h>
++#include <dt-bindings/soc/rockchip,vop2.h>
++#include "rk3566.dtsi"
++
++/ {
++ aliases {
++ mmc0 = &sdmmc0;
++ };
++
++ chosen {
++ stdout-path = "serial2:1500000n8";
++ };
++
++ hdmi-con {
++ compatible = "hdmi-connector";
++ type = "d";
++
++ port {
++ hdmi_con_in: endpoint {
++ remote-endpoint = <&hdmi_out_con>;
++ };
++ };
++ };
++
++ leds {
++ compatible = "gpio-leds";
++ pinctrl-names = "default";
++ pinctrl-0 = <&user_led2>;
++
++ led-green {
++ color = <LED_COLOR_ID_GREEN>;
++ default-state = "on";
++ function = LED_FUNCTION_HEARTBEAT;
++ gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>;
++ linux,default-trigger = "heartbeat";
++ };
++ };
++
++ vcc_1v8: regulator-1v8-vcc {
++ compatible = "regulator-fixed";
++ regulator-name = "vcc_1v8";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ vin-supply = <&vcc_1v8_p>;
++ };
++
++ vcca_1v8: regulator-1v8-vcca {
++ compatible = "regulator-fixed";
++ regulator-name = "vcca_1v8";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ vin-supply = <&vcc_1v8_p>;
++ };
++
++ vcca1v8_image: regulator-1v8-vcca-image {
++ compatible = "regulator-fixed";
++ regulator-name = "vcca1v8_image";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ vin-supply = <&vcc_1v8_p>;
++ };
++
++ vcc_3v3: regulator-3v3-vcc {
++ compatible = "regulator-fixed";
++ regulator-name = "vcc_3v3";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ vin-supply = <&vcc3v3_sys>;
++ };
++
++ vcc_sys: regulator-5v0-vcc-sys {
++ compatible = "regulator-fixed";
++ regulator-name = "vcc_sys";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <5000000>;
++ regulator-max-microvolt = <5000000>;
++ };
++};
++
++&combphy1 {
++ status = "okay";
++};
++
++&cpu0 {
++ cpu-supply = <&vdd_cpu>;
++};
++
++&cpu1 {
++ cpu-supply = <&vdd_cpu>;
++};
++
++&cpu2 {
++ cpu-supply = <&vdd_cpu>;
++};
++
++&cpu3 {
++ cpu-supply = <&vdd_cpu>;
++};
++
++&gpu {
++ mali-supply = <&vdd_gpu_npu>;
++ status = "okay";
++};
++
++&hdmi {
++ avdd-0v9-supply = <&vdda_0v9>;
++ avdd-1v8-supply = <&vcca1v8_image>;
++ status = "okay";
++};
++
++&hdmi_in {
++ hdmi_in_vp0: endpoint {
++ remote-endpoint = <&vp0_out_hdmi>;
++ };
++};
++
++&hdmi_out {
++ hdmi_out_con: endpoint {
++ remote-endpoint = <&hdmi_con_in>;
++ };
++};
++
++&hdmi_sound {
++ status = "okay";
++};
++
++&i2c0 {
++ status = "okay";
++
++ rk817: pmic@20 {
++ compatible = "rockchip,rk817";
++ reg = <0x20>;
++ #clock-cells = <1>;
++ clock-output-names = "rk817-clkout1", "rk817-clkout2";
++ interrupt-parent = <&gpio0>;
++ interrupts = <RK_PA3 IRQ_TYPE_LEVEL_LOW>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&pmic_int_l>;
++ system-power-controller;
++ wakeup-source;
++
++ vcc1-supply = <&vcc_sys>;
++ vcc2-supply = <&vcc_sys>;
++ vcc3-supply = <&vcc_sys>;
++ vcc4-supply = <&vcc_sys>;
++ vcc5-supply = <&vcc_sys>;
++ vcc6-supply = <&vcc_sys>;
++ vcc7-supply = <&vcc_sys>;
++ vcc8-supply = <&vcc_sys>;
++ vcc9-supply = <&vcc5v_midu>;
++
++ regulators {
++ vdd_logic: DCDC_REG1 {
++ regulator-name = "vdd_logic";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-initial-mode = <0x2>;
++ regulator-min-microvolt = <500000>;
++ regulator-max-microvolt = <1350000>;
++ regulator-ramp-delay = <6001>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ regulator-suspend-microvolt = <900000>;
++ };
++ };
++
++ vdd_gpu_npu: DCDC_REG2 {
++ regulator-name = "vdd_gpu_npu";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-initial-mode = <0x2>;
++ regulator-min-microvolt = <500000>;
++ regulator-max-microvolt = <1350000>;
++ regulator-ramp-delay = <6001>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vcc_ddr: DCDC_REG3 {
++ regulator-name = "vcc_ddr";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-initial-mode = <0x2>;
++
++ regulator-state-mem {
++ regulator-on-in-suspend;
++ };
++ };
++
++ vcc3v3_sys: DCDC_REG4 {
++ regulator-name = "vcc3v3_sys";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-initial-mode = <0x2>;
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++
++ regulator-state-mem {
++ regulator-on-in-suspend;
++ regulator-suspend-microvolt = <3300000>;
++ };
++ };
++
++ vcca1v8_pmu: LDO_REG1 {
++ regulator-name = "vcca1v8_pmu";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++
++ regulator-state-mem {
++ regulator-on-in-suspend;
++ regulator-suspend-microvolt = <1800000>;
++ };
++ };
++
++ vdda_0v9: LDO_REG2 {
++ regulator-name = "vdda_0v9";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <900000>;
++ regulator-max-microvolt = <900000>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vdda0v9_pmu: LDO_REG3 {
++ regulator-name = "vdda0v9_pmu";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <900000>;
++ regulator-max-microvolt = <900000>;
++
++ regulator-state-mem {
++ regulator-on-in-suspend;
++ regulator-suspend-microvolt = <900000>;
++ };
++ };
++
++ vccio_acodec: LDO_REG4 {
++ regulator-name = "vccio_acodec";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vccio_sd: LDO_REG5 {
++ regulator-name = "vccio_sd";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <3300000>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vcc3v3_pmu: LDO_REG6 {
++ regulator-name = "vcc3v3_pmu";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++
++ regulator-state-mem {
++ regulator-on-in-suspend;
++ regulator-suspend-microvolt = <3300000>;
++ };
++ };
++
++ vcc_1v8_p: LDO_REG7 {
++ regulator-name = "vcc_1v8_p";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vcc1v8_dvp: LDO_REG8 {
++ regulator-name = "vcc1v8_dvp";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vcc2v8_dvp: LDO_REG9 {
++ regulator-name = "vcc2v8_dvp";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <2800000>;
++ regulator-max-microvolt = <2800000>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vcc5v_midu: BOOST {
++ regulator-name = "vcc5v_midu";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <5000000>;
++ regulator-max-microvolt = <5000000>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vbus: OTG_SWITCH {
++ regulator-name = "vbus";
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++ };
++ };
++
++ vdd_cpu: regulator@40 {
++ compatible = "rockchip,rk8600";
++ reg = <0x40>;
++ fcs,suspend-voltage-selector = <1>;
++ regulator-name = "vdd_cpu";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <712500>;
++ regulator-max-microvolt = <1390000>;
++ regulator-ramp-delay = <2300>;
++ vin-supply = <&vcc_sys>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++};
++
++&i2s0_8ch {
++ status = "okay";
++};
++
++&pinctrl {
++ leds {
++ user_led2: user-led2 {
++ rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
++
++ pmic {
++ pmic_int_l: pmic-int-l {
++ rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
++ };
++ };
++};
++
++&pmu_io_domains {
++ pmuio1-supply = <&vcc3v3_pmu>;
++ pmuio2-supply = <&vcca1v8_pmu>;
++ vccio1-supply = <&vccio_acodec>;
++ vccio2-supply = <&vcc_1v8>;
++ vccio3-supply = <&vccio_sd>;
++ vccio4-supply = <&vcc_1v8>;
++ vccio5-supply = <&vcc_3v3>;
++ vccio6-supply = <&vcc_3v3>;
++ vccio7-supply = <&vcc_3v3>;
++ status = "okay";
++};
++
++&saradc {
++ vref-supply = <&vcca_1v8>;
++ status = "okay";
++};
++
++&sdmmc0 {
++ bus-width = <4>;
++ cap-sd-highspeed;
++ disable-wp;
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd &sdmmc0_det>;
++ vmmc-supply = <&vcc3v3_sys>;
++ vqmmc-supply = <&vccio_sd>;
++ status = "okay";
++};
++
++&tsadc {
++ rockchip,hw-tshut-mode = <1>;
++ rockchip,hw-tshut-polarity = <0>;
++ status = "okay";
++};
++
++&uart2 {
++ status = "okay";
++};
++
++&usb_host0_xhci {
++ dr_mode = "peripheral";
++ status = "okay";
++};
++
++&usb_host1_xhci {
++ status = "okay";
++};
++
++&usb2phy0 {
++ status = "okay";
++};
++
++&usb2phy0_host {
++ status = "okay";
++};
++
++&usb2phy0_otg {
++ status = "okay";
++};
++
++&vop {
++ assigned-clocks = <&cru DCLK_VOP0>, <&cru DCLK_VOP1>;
++ assigned-clock-parents = <&pmucru PLL_HPLL>, <&cru PLL_VPLL>;
++ status = "okay";
++};
++
++&vop_mmu {
++ status = "okay";
++};
++
++&vp0 {
++ vp0_out_hdmi: endpoint@ROCKCHIP_VOP2_EP_HDMI0 {
++ reg = <ROCKCHIP_VOP2_EP_HDMI0>;
++ remote-endpoint = <&hdmi_in_vp0>;
++ };
++};
+--- /dev/null
++++ b/arch/arm64/boot/dts/rockchip/rk3566-radxa-zero-3e.dts
+@@ -0,0 +1,51 @@
++// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
++
++/dts-v1/;
++
++#include "rk3566-radxa-zero-3.dtsi"
++
++/ {
++ model = "Radxa ZERO 3E";
++ compatible = "radxa,zero-3e", "rockchip,rk3566";
++
++ aliases {
++ ethernet0 = &gmac1;
++ };
++};
++
++&gmac1 {
++ assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1>;
++ assigned-clock-parents = <&cru SCLK_GMAC1_RGMII_SPEED>, <&cru CLK_MAC1_2TOP>;
++ clock_in_out = "input";
++ phy-handle = <&rgmii_phy1>;
++ phy-mode = "rgmii-id";
++ phy-supply = <&vcc_3v3>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&gmac1m1_miim
++ &gmac1m1_tx_bus2
++ &gmac1m1_rx_bus2
++ &gmac1m1_rgmii_clk
++ &gmac1m1_rgmii_bus
++ &gmac1m1_clkinout>;
++ status = "okay";
++};
++
++&mdio1 {
++ rgmii_phy1: ethernet-phy@1 {
++ compatible = "ethernet-phy-ieee802.3-c22";
++ reg = <1>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&gmac1_rstn>;
++ reset-assert-us = <20000>;
++ reset-deassert-us = <50000>;
++ reset-gpios = <&gpio3 RK_PC0 GPIO_ACTIVE_LOW>;
++ };
++};
++
++&pinctrl {
++ gmac1 {
++ gmac1_rstn: gmac1-rstn {
++ rockchip,pins = <3 RK_PC0 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
++};
+--- /dev/null
++++ b/arch/arm64/boot/dts/rockchip/rk3566-radxa-zero-3w.dts
+@@ -0,0 +1,91 @@
++// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
++
++/dts-v1/;
++
++#include "rk3566-radxa-zero-3.dtsi"
++
++/ {
++ model = "Radxa ZERO 3W";
++ compatible = "radxa,zero-3w", "rockchip,rk3566";
++
++ aliases {
++ mmc1 = &sdhci;
++ mmc2 = &sdmmc1;
++ };
++
++ sdio_pwrseq: sdio-pwrseq {
++ compatible = "mmc-pwrseq-simple";
++ clocks = <&rk817 1>;
++ clock-names = "ext_clock";
++ pinctrl-names = "default";
++ pinctrl-0 = <&wifi_reg_on_h>;
++ post-power-on-delay-ms = <100>;
++ power-off-delay-us = <5000000>;
++ reset-gpios = <&gpio0 RK_PC0 GPIO_ACTIVE_LOW>;
++ };
++};
++
++&pinctrl {
++ bluetooth {
++ bt_reg_on_h: bt-reg-on-h {
++ rockchip,pins = <0 RK_PC1 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++
++ bt_wake_host_h: bt-wake-host-h {
++ rockchip,pins = <0 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++
++ host_wake_bt_h: host-wake-bt-h {
++ rockchip,pins = <0 RK_PB4 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
++
++ wifi {
++ wifi_reg_on_h: wifi-reg-on-h {
++ rockchip,pins = <0 RK_PC0 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++
++ wifi_wake_host_h: wifi-wake-host-h {
++ rockchip,pins = <0 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
++};
++
++&sdhci {
++ bus-width = <8>;
++ cap-mmc-highspeed;
++ max-frequency = <200000000>;
++ mmc-hs200-1_8v;
++ no-sd;
++ no-sdio;
++ non-removable;
++ pinctrl-names = "default";
++ pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd &emmc_datastrobe>;
++ vmmc-supply = <&vcc_3v3>;
++ vqmmc-supply = <&vcc_1v8>;
++ status = "okay";
++};
++
++&sdmmc1 {
++ bus-width = <4>;
++ cap-sd-highspeed;
++ cap-sdio-irq;
++ keep-power-in-suspend;
++ mmc-pwrseq = <&sdio_pwrseq>;
++ no-mmc;
++ no-sd;
++ non-removable;
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdmmc1_bus4 &sdmmc1_clk &sdmmc1_cmd>;
++ sd-uhs-sdr104;
++ vmmc-supply = <&vcc_3v3>;
++ vqmmc-supply = <&vcc_1v8>;
++ status = "okay";
++};
++
++&uart1 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&uart1m0_xfer &uart1m0_ctsn &uart1m0_rtsn>;
++ uart-has-rtscts;
++ status = "okay";
++};
diff --git a/target/linux/rockchip/patches-6.6/012-v6.11-arm64-dts-rockchip-fix-mmc-aliases-for-Radxa-ZERO-3E.patch b/target/linux/rockchip/patches-6.6/012-v6.11-arm64-dts-rockchip-fix-mmc-aliases-for-Radxa-ZERO-3E.patch
new file mode 100644
index 0000000000..b96e8e1774
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/012-v6.11-arm64-dts-rockchip-fix-mmc-aliases-for-Radxa-ZERO-3E.patch
@@ -0,0 +1,64 @@
+From 060c1950037e4c54ca4d8186a8f46269e35db901 Mon Sep 17 00:00:00 2001
+From: FUKAUMI Naoki <naoki@radxa.com>
+Date: Fri, 21 Jun 2024 07:44:35 +0900
+Subject: [PATCH] arm64: dts: rockchip: fix mmc aliases for Radxa ZERO 3E/3W
+
+align with other Radxa products.
+
+- mmc0 is eMMC
+- mmc1 is microSD
+
+for ZERO 3E, there is no eMMC, but aliases should start at 0, so mmc0
+is microSD as exception.
+
+Fixes: 1a5c8d307c83 ("arm64: dts: rockchip: Add Radxa ZERO 3W/3E")
+Signed-off-by: FUKAUMI Naoki <naoki@radxa.com>
+
+Changes in v3:
+- fix syntax error in rk3566-radxa-zero-3e.dts
+Changes in v2:
+- microSD is mmc0 instead of mmc1 for ZERO 3E
+
+Link: https://lore.kernel.org/r/20240620224435.2752-1-naoki@radxa.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3566-radxa-zero-3.dtsi | 4 ----
+ arch/arm64/boot/dts/rockchip/rk3566-radxa-zero-3e.dts | 1 +
+ arch/arm64/boot/dts/rockchip/rk3566-radxa-zero-3w.dts | 3 ++-
+ 3 files changed, 3 insertions(+), 5 deletions(-)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3566-radxa-zero-3.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3566-radxa-zero-3.dtsi
+@@ -6,10 +6,6 @@
+ #include "rk3566.dtsi"
+
+ / {
+- aliases {
+- mmc0 = &sdmmc0;
+- };
+-
+ chosen {
+ stdout-path = "serial2:1500000n8";
+ };
+--- a/arch/arm64/boot/dts/rockchip/rk3566-radxa-zero-3e.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3566-radxa-zero-3e.dts
+@@ -10,6 +10,7 @@
+
+ aliases {
+ ethernet0 = &gmac1;
++ mmc0 = &sdmmc0;
+ };
+ };
+
+--- a/arch/arm64/boot/dts/rockchip/rk3566-radxa-zero-3w.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3566-radxa-zero-3w.dts
+@@ -9,7 +9,8 @@
+ compatible = "radxa,zero-3w", "rockchip,rk3566";
+
+ aliases {
+- mmc1 = &sdhci;
++ mmc0 = &sdhci;
++ mmc1 = &sdmmc0;
+ mmc2 = &sdmmc1;
+ };
+
diff --git a/target/linux/rockchip/patches-6.6/013-v6.11-arm64-dts-rockchip-add-gpio-line-names-to-radxa-zero.patch b/target/linux/rockchip/patches-6.6/013-v6.11-arm64-dts-rockchip-add-gpio-line-names-to-radxa-zero.patch
new file mode 100644
index 0000000000..4c5107ab35
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/013-v6.11-arm64-dts-rockchip-add-gpio-line-names-to-radxa-zero.patch
@@ -0,0 +1,101 @@
+From f7c742cbe664ebdedc075945e75443683d1175f7 Mon Sep 17 00:00:00 2001
+From: Trevor Woerner <twoerner@gmail.com>
+Date: Wed, 19 Jun 2024 21:32:49 -0400
+Subject: [PATCH] arm64: dts: rockchip: add gpio-line-names to radxa-zero-3
+
+Add names to the pins of the general-purpose expansion header as given
+in the Radxa documentation[1] following the conventions in the kernel[2]
+to make it easier for users to correlate pins with functions when using
+utilities such as 'gpioinfo'.
+
+[1] https://docs.radxa.com/en/zero/zero3/hardware-design/hardware-interface
+[2] https://www.kernel.org/doc/Documentation/devicetree/bindings/gpio/gpio.txt
+
+Signed-off-by: Trevor Woerner <twoerner@gmail.com>
+Link: https://lore.kernel.org/r/20240620013301.33653-1-twoerner@gmail.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ .../dts/rockchip/rk3566-radxa-zero-3.dtsi | 72 +++++++++++++++++++
+ 1 file changed, 72 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3566-radxa-zero-3.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3566-radxa-zero-3.dtsi
+@@ -105,6 +105,78 @@
+ cpu-supply = <&vdd_cpu>;
+ };
+
++&gpio0 {
++ gpio-line-names =
++ /* GPIO0_A0 - A7 */
++ "", "", "", "", "", "", "", "",
++ /* GPIO0_B0 - B7 */
++ "", "", "", "", "", "", "", "",
++ /* GPIO0_C0 - C7 */
++ "", "", "", "", "", "", "", "",
++ /* GPIO0_D0 - D7 */
++ "pin-10 [GPIO0_D0]", "pin-08 [GPIO0_D1]", "",
++ "", "", "", "", "";
++};
++
++&gpio1 {
++ gpio-line-names =
++ /* GPIO1_A0 - A7 */
++ "pin-03 [GPIO1_A0]", "pin-05 [GPIO1_A1]", "",
++ "", "pin-37 [GPIO1_A4]", "",
++ "", "",
++ /* GPIO1_B0 - B7 */
++ "", "", "", "", "", "", "", "",
++ /* GPIO1_C0 - C7 */
++ "", "", "", "", "", "", "", "",
++ /* GPIO1_D0 - D7 */
++ "", "", "", "", "", "", "", "";
++};
++
++&gpio2 {
++ gpio-line-names =
++ /* GPIO2_A0 - A7 */
++ "", "", "", "", "", "", "", "",
++ /* GPIO2_B0 - B7 */
++ "", "", "", "", "", "", "", "",
++ /* GPIO2_C0 - C7 */
++ "", "", "", "", "", "", "", "",
++ /* GPIO2_D0 - D7 */
++ "", "", "", "", "", "", "", "";
++};
++
++&gpio3 {
++ gpio-line-names =
++ /* GPIO3_A0 - A7 */
++ "", "pin-11 [GPIO3_A1]", "pin-13 [GPIO3_A2]",
++ "pin-12 [GPIO3_A3]", "pin-35 [GPIO3_A4]", "pin-40 [GPIO3_A5]",
++ "pin-38 [GPIO3_A6]", "pin-36 [GPIO3_A7]",
++ /* GPIO3_B0 - B7 */
++ "pin-15 [GPIO3_B0]", "pin-16 [GPIO3_B1]", "pin-18 [GPIO3_B2]",
++ "pin-29 [GPIO3_B3]", "pin-31 [GPIO3_B4]", "",
++ "", "",
++ /* GPIO3_C0 - C7 */
++ "", "pin-22 [GPIO3_C1]", "pin-32 [GPIO3_C2]",
++ "pin-33 [GPIO3_C3]", "pin-07 [GPIO3_C4]", "",
++ "", "",
++ /* GPIO3_D0 - D7 */
++ "", "", "", "", "", "", "", "";
++};
++
++&gpio4 {
++ gpio-line-names =
++ /* GPIO4_A0 - A7 */
++ "", "", "", "", "", "", "", "",
++ /* GPIO4_B0 - B7 */
++ "", "", "pin-27 [GPIO4_B2]",
++ "pin-28 [GPIO4_B3]", "", "", "", "",
++ /* GPIO4_C0 - C7 */
++ "", "", "pin-23 [GPIO4_C2]",
++ "pin-19 [GPIO4_C3]", "", "pin-21 [GPIO4_C5]",
++ "pin-24 [GPIO4_C6]", "",
++ /* GPIO4_D0 - D7 */
++ "", "", "", "", "", "", "", "";
++};
++
+ &gpu {
+ mali-supply = <&vdd_gpu_npu>;
+ status = "okay";
diff --git a/target/linux/rockchip/patches-6.6/014-v6.11-arm64-dts-rockchip-Add-Radxa-ROCK-3B.patch b/target/linux/rockchip/patches-6.6/014-v6.11-arm64-dts-rockchip-Add-Radxa-ROCK-3B.patch
new file mode 100644
index 0000000000..e93a055c3e
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/014-v6.11-arm64-dts-rockchip-Add-Radxa-ROCK-3B.patch
@@ -0,0 +1,815 @@
+From 846ef7748fa9124c8eea76e2d5e833fa69b3ef7c Mon Sep 17 00:00:00 2001
+From: Jonas Karlman <jonas@kwiboo.se>
+Date: Thu, 27 Jun 2024 21:17:31 +0000
+Subject: [PATCH] arm64: dts: rockchip: Add Radxa ROCK 3B
+
+The Radxa ROCK 3B is a single-board computer based on the Pico-ITX form
+factor (100mm x 75mm). Two versions of the ROCK 3B exists, a community
+version based on the RK3568 SoC and an industrial version based on the
+RK3568J SoC.
+
+Add initial support for eMMC, SD-card, Ethernet, HDMI, PCIe and USB.
+
+Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
+Link: https://lore.kernel.org/r/20240627211737.1985549-3-jonas@kwiboo.se
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/Makefile | 1 +
+ .../boot/dts/rockchip/rk3568-rock-3b.dts | 781 ++++++++++++++++++
+ 2 files changed, 782 insertions(+)
+ create mode 100644 arch/arm64/boot/dts/rockchip/rk3568-rock-3b.dts
+
+--- a/arch/arm64/boot/dts/rockchip/Makefile
++++ b/arch/arm64/boot/dts/rockchip/Makefile
+@@ -100,6 +100,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-od
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-radxa-e25.dtb
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-roc-pc.dtb
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-rock-3a.dtb
++dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-rock-3b.dtb
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-edgeble-neu6a-io.dtb
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-edgeble-neu6b-io.dtb
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-evb1-v10.dtb
+--- /dev/null
++++ b/arch/arm64/boot/dts/rockchip/rk3568-rock-3b.dts
+@@ -0,0 +1,781 @@
++// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
++
++/dts-v1/;
++
++#include <dt-bindings/gpio/gpio.h>
++#include <dt-bindings/leds/common.h>
++#include <dt-bindings/pinctrl/rockchip.h>
++#include <dt-bindings/soc/rockchip,vop2.h>
++#include "rk3568.dtsi"
++
++/ {
++ model = "Radxa ROCK 3B";
++ compatible = "radxa,rock-3b", "rockchip,rk3568";
++
++ aliases {
++ ethernet0 = &gmac0;
++ ethernet1 = &gmac1;
++ mmc0 = &sdhci;
++ mmc1 = &sdmmc0;
++ mmc2 = &sdmmc2;
++ };
++
++ chosen {
++ stdout-path = "serial2:1500000n8";
++ };
++
++ hdmi-con {
++ compatible = "hdmi-connector";
++ type = "a";
++
++ port {
++ hdmi_con_in: endpoint {
++ remote-endpoint = <&hdmi_out_con>;
++ };
++ };
++ };
++
++ ir-receiver {
++ compatible = "gpio-ir-receiver";
++ gpios = <&gpio0 RK_PC2 GPIO_ACTIVE_LOW>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&pwm3_ir>;
++ };
++
++ leds {
++ compatible = "gpio-leds";
++ pinctrl-names = "default";
++ pinctrl-0 = <&led>;
++
++ led-0 {
++ color = <LED_COLOR_ID_GREEN>;
++ default-state = "on";
++ function = LED_FUNCTION_HEARTBEAT;
++ gpios = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>;
++ linux,default-trigger = "heartbeat";
++ };
++ };
++
++ /* pi6c pcie clock generator */
++ vcc3v3_pi6c_03: regulator-3v3-vcc-pi6c-03 {
++ compatible = "regulator-fixed";
++ enable-active-high;
++ gpios = <&gpio0 RK_PD4 GPIO_ACTIVE_HIGH>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&pcie_pwren_h>;
++ regulator-name = "vcc3v3_pi6c_03";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ startup-delay-us = <10000>;
++ vin-supply = <&vcc5v0_sys>;
++ };
++
++ vcc3v3_sys: regulator-3v3-vcc-sys {
++ compatible = "regulator-fixed";
++ regulator-name = "vcc3v3_sys";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ vin-supply = <&vcc5v0_sys>;
++ };
++
++ vcc3v3_sys2: regulator-3v3-vcc-sys2 {
++ compatible = "regulator-fixed";
++ regulator-name = "vcc3v3_sys2";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ vin-supply = <&vcc5v0_sys>;
++ };
++
++ vcc5v0_sys: regulator-5v0-vcc-sys {
++ compatible = "regulator-fixed";
++ regulator-name = "vcc5v0_sys";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <5000000>;
++ regulator-max-microvolt = <5000000>;
++ };
++
++ vcc5v0_usb_host: regulator-5v0-vcc-usb-host {
++ compatible = "regulator-fixed";
++ enable-active-high;
++ gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&usb_host_pwren_h>;
++ regulator-name = "vcc5v0_usb_host";
++ regulator-min-microvolt = <5000000>;
++ regulator-max-microvolt = <5000000>;
++ vin-supply = <&vcc5v0_sys>;
++ };
++
++ vcc5v0_usb_otg: regulator-5v0-vcc-usb-otg {
++ compatible = "regulator-fixed";
++ enable-active-high;
++ gpios = <&gpio0 RK_PA5 GPIO_ACTIVE_HIGH>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&usb_otg_pwren_h>;
++ regulator-name = "vcc5v0_usb_otg";
++ regulator-min-microvolt = <5000000>;
++ regulator-max-microvolt = <5000000>;
++ vin-supply = <&vcc5v0_sys>;
++ };
++
++ sdio_pwrseq: sdio-pwrseq {
++ compatible = "mmc-pwrseq-simple";
++ clocks = <&rk809 1>;
++ clock-names = "ext_clock";
++ pinctrl-names = "default";
++ pinctrl-0 = <&wifi_reg_on_h>;
++ post-power-on-delay-ms = <100>;
++ power-off-delay-us = <5000000>;
++ reset-gpios = <&gpio3 RK_PD4 GPIO_ACTIVE_LOW>;
++ };
++
++ sound {
++ compatible = "simple-audio-card";
++ simple-audio-card,format = "i2s";
++ simple-audio-card,name = "Analog RK809";
++ simple-audio-card,mclk-fs = <256>;
++
++ simple-audio-card,cpu {
++ sound-dai = <&i2s1_8ch>;
++ };
++
++ simple-audio-card,codec {
++ sound-dai = <&rk809>;
++ };
++ };
++};
++
++&combphy0 {
++ status = "okay";
++};
++
++&combphy1 {
++ status = "okay";
++};
++
++&combphy2 {
++ status = "okay";
++};
++
++&cpu0 {
++ cpu-supply = <&vdd_cpu>;
++};
++
++&cpu1 {
++ cpu-supply = <&vdd_cpu>;
++};
++
++&cpu2 {
++ cpu-supply = <&vdd_cpu>;
++};
++
++&cpu3 {
++ cpu-supply = <&vdd_cpu>;
++};
++
++&gmac0 {
++ assigned-clocks = <&cru SCLK_GMAC0_RX_TX>, <&cru SCLK_GMAC0>;
++ assigned-clock-parents = <&cru SCLK_GMAC0_RGMII_SPEED>, <&cru CLK_MAC0_2TOP>;
++ clock_in_out = "input";
++ phy-handle = <&rgmii_phy0>;
++ phy-mode = "rgmii-id";
++ phy-supply = <&vcc_3v3>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&gmac0_miim
++ &gmac0_tx_bus2
++ &gmac0_rx_bus2
++ &gmac0_rgmii_clk
++ &gmac0_rgmii_bus
++ &gmac0_clkinout>;
++ status = "okay";
++};
++
++&gmac1 {
++ assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1>;
++ assigned-clock-parents = <&cru SCLK_GMAC1_RGMII_SPEED>, <&cru CLK_MAC1_2TOP>;
++ clock_in_out = "input";
++ phy-handle = <&rgmii_phy1>;
++ phy-mode = "rgmii-id";
++ phy-supply = <&vcc_3v3>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&gmac1m1_miim
++ &gmac1m1_tx_bus2
++ &gmac1m1_rx_bus2
++ &gmac1m1_rgmii_clk
++ &gmac1m1_rgmii_bus
++ &gmac1m1_clkinout>;
++ status = "okay";
++};
++
++&gpu {
++ mali-supply = <&vdd_gpu>;
++ status = "okay";
++};
++
++&hdmi {
++ avdd-0v9-supply = <&vdda0v9_image>;
++ avdd-1v8-supply = <&vcca1v8_image>;
++ status = "okay";
++};
++
++&hdmi_in {
++ hdmi_in_vp0: endpoint {
++ remote-endpoint = <&vp0_out_hdmi>;
++ };
++};
++
++&hdmi_out {
++ hdmi_out_con: endpoint {
++ remote-endpoint = <&hdmi_con_in>;
++ };
++};
++
++&hdmi_sound {
++ status = "okay";
++};
++
++&i2c0 {
++ status = "okay";
++
++ vdd_cpu: regulator@1c {
++ compatible = "tcs,tcs4525";
++ reg = <0x1c>;
++ fcs,suspend-voltage-selector = <1>;
++ regulator-name = "vdd_cpu";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <800000>;
++ regulator-max-microvolt = <1150000>;
++ regulator-ramp-delay = <2300>;
++ vin-supply = <&vcc5v0_sys>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ rk809: pmic@20 {
++ compatible = "rockchip,rk809";
++ reg = <0x20>;
++ assigned-clocks = <&cru I2S1_MCLKOUT_TX>;
++ assigned-clock-parents = <&cru CLK_I2S1_8CH_TX>;
++ #clock-cells = <1>;
++ clocks = <&cru I2S1_MCLKOUT_TX>;
++ clock-names = "mclk";
++ clock-output-names = "rk809-clkout1", "rk809-clkout2";
++ interrupt-parent = <&gpio0>;
++ interrupts = <RK_PA3 IRQ_TYPE_LEVEL_LOW>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&pmic_int_l>, <&i2s1m0_mclk>;
++ #sound-dai-cells = <0>;
++ system-power-controller;
++ wakeup-source;
++
++ vcc1-supply = <&vcc3v3_sys>;
++ vcc2-supply = <&vcc3v3_sys>;
++ vcc3-supply = <&vcc3v3_sys>;
++ vcc4-supply = <&vcc3v3_sys>;
++ vcc5-supply = <&vcc3v3_sys>;
++ vcc6-supply = <&vcc3v3_sys>;
++ vcc7-supply = <&vcc3v3_sys>;
++ vcc8-supply = <&vcc3v3_sys>;
++ vcc9-supply = <&vcc3v3_sys>;
++
++ regulators {
++ vdd_logic: DCDC_REG1 {
++ regulator-name = "vdd_logic";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-initial-mode = <0x2>;
++ regulator-min-microvolt = <500000>;
++ regulator-max-microvolt = <1350000>;
++ regulator-ramp-delay = <6001>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vdd_gpu: DCDC_REG2 {
++ regulator-name = "vdd_gpu";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-initial-mode = <0x2>;
++ regulator-min-microvolt = <500000>;
++ regulator-max-microvolt = <1350000>;
++ regulator-ramp-delay = <6001>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vcc_ddr: DCDC_REG3 {
++ regulator-name = "vcc_ddr";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-initial-mode = <0x2>;
++
++ regulator-state-mem {
++ regulator-on-in-suspend;
++ };
++ };
++
++ vdd_npu: DCDC_REG4 {
++ regulator-name = "vdd_npu";
++ regulator-initial-mode = <0x2>;
++ regulator-min-microvolt = <500000>;
++ regulator-max-microvolt = <1350000>;
++ regulator-ramp-delay = <6001>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vcc_1v8: DCDC_REG5 {
++ regulator-name = "vcc_1v8";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vdda0v9_image: LDO_REG1 {
++ regulator-name = "vdda0v9_image";
++ regulator-min-microvolt = <900000>;
++ regulator-max-microvolt = <900000>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vdda_0v9: LDO_REG2 {
++ regulator-name = "vdda_0v9";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <900000>;
++ regulator-max-microvolt = <900000>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vdda0v9_pmu: LDO_REG3 {
++ regulator-name = "vdda0v9_pmu";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <900000>;
++ regulator-max-microvolt = <900000>;
++
++ regulator-state-mem {
++ regulator-on-in-suspend;
++ regulator-suspend-microvolt = <900000>;
++ };
++ };
++
++ vccio_acodec: LDO_REG4 {
++ regulator-name = "vccio_acodec";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vccio_sd: LDO_REG5 {
++ regulator-name = "vccio_sd";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <3300000>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vcc3v3_pmu: LDO_REG6 {
++ regulator-name = "vcc3v3_pmu";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++
++ regulator-state-mem {
++ regulator-on-in-suspend;
++ regulator-suspend-microvolt = <3300000>;
++ };
++ };
++
++ vcca_1v8: LDO_REG7 {
++ regulator-name = "vcca_1v8";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vcca1v8_pmu: LDO_REG8 {
++ regulator-name = "vcca1v8_pmu";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++
++ regulator-state-mem {
++ regulator-on-in-suspend;
++ regulator-suspend-microvolt = <1800000>;
++ };
++ };
++
++ vcca1v8_image: LDO_REG9 {
++ regulator-name = "vcca1v8_image";
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vcc_3v3: SWITCH_REG1 {
++ regulator-name = "vcc_3v3";
++ regulator-always-on;
++ regulator-boot-on;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vcc3v3_sd: SWITCH_REG2 {
++ regulator-name = "vcc3v3_sd";
++ regulator-always-on;
++ regulator-boot-on;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++ };
++ };
++};
++
++&i2c5 {
++ status = "okay";
++
++ hym8563: rtc@51 {
++ compatible = "haoyu,hym8563";
++ reg = <0x51>;
++ interrupt-parent = <&gpio0>;
++ interrupts = <RK_PD3 IRQ_TYPE_LEVEL_LOW>;
++ #clock-cells = <0>;
++ clock-output-names = "rtcic_32kout";
++ pinctrl-names = "default";
++ pinctrl-0 = <&rtcic_int_l>;
++ wakeup-source;
++ };
++};
++
++&i2s0_8ch {
++ status = "okay";
++};
++
++&i2s1_8ch {
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2s1m0_sclktx
++ &i2s1m0_lrcktx
++ &i2s1m0_sdi0
++ &i2s1m0_sdo0>;
++ rockchip,trcm-sync-tx-only;
++ status = "okay";
++};
++
++&mdio0 {
++ rgmii_phy0: ethernet-phy@1 {
++ compatible = "ethernet-phy-ieee802.3-c22";
++ reg = <1>;
++ reset-assert-us = <20000>;
++ reset-deassert-us = <50000>;
++ reset-gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>;
++ };
++};
++
++&mdio1 {
++ rgmii_phy1: ethernet-phy@1 {
++ compatible = "ethernet-phy-ieee802.3-c22";
++ reg = <1>;
++ reset-assert-us = <20000>;
++ reset-deassert-us = <50000>;
++ reset-gpios = <&gpio3 RK_PB0 GPIO_ACTIVE_LOW>;
++ };
++};
++
++&pcie2x1 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&pcie20m1_pins>;
++ reset-gpios = <&gpio3 RK_PC1 GPIO_ACTIVE_HIGH>;
++ vpcie3v3-supply = <&vcc3v3_sys2>;
++ status = "okay";
++};
++
++&pcie30phy {
++ status = "okay";
++};
++
++&pcie3x2 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&pcie30x2m1_pins>;
++ reset-gpios = <&gpio2 RK_PD6 GPIO_ACTIVE_HIGH>;
++ status = "okay";
++};
++
++&pinctrl {
++ bluetooth {
++ bt_reg_on_h: bt-reg-on-h {
++ rockchip,pins = <4 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++
++ bt_wake_host_h: bt-wake-host-h {
++ rockchip,pins = <4 RK_PB4 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++
++ host_wake_bt_h: host-wake-bt-h {
++ rockchip,pins = <4 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
++
++ ir-receiver {
++ pwm3_ir: pwm3-ir {
++ rockchip,pins = <0 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
++
++ leds {
++ led: led {
++ rockchip,pins = <0 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
++
++ pcie {
++ pcie_pwren_h: pcie-pwren-h {
++ rockchip,pins = <0 RK_PD4 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
++
++ pcie20 {
++ pcie20m1_pins: pcie20m1-pins {
++ rockchip,pins =
++ <2 RK_PD0 4 &pcfg_pull_none>,
++ <3 RK_PC1 RK_FUNC_GPIO &pcfg_pull_none>,
++ <2 RK_PD1 4 &pcfg_pull_none>;
++ };
++ };
++
++ pcie30x2 {
++ pcie30x2m1_pins: pcie30x2m1-pins {
++ rockchip,pins =
++ <2 RK_PD4 4 &pcfg_pull_none>,
++ <2 RK_PD6 RK_FUNC_GPIO &pcfg_pull_none>,
++ <2 RK_PD5 4 &pcfg_pull_none>;
++ };
++ };
++
++ pmic {
++ pmic_int_l: pmic-int-l {
++ rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
++ };
++ };
++
++ rtc {
++ rtcic_int_l: rtcic-int-l {
++ rockchip,pins = <0 RK_PD3 RK_FUNC_GPIO &pcfg_pull_up>;
++ };
++ };
++
++ usb {
++ usb_host_pwren_h: usb-host-pwren-h {
++ rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++
++ usb_otg_pwren_h: usb-otg-pwren-h {
++ rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
++
++ wifi {
++ wifi_reg_on_h: wifi-reg-on-h {
++ rockchip,pins = <3 RK_PD4 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++
++ wifi_wake_host_h: wifi-wake-host-h {
++ rockchip,pins = <3 RK_PD5 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
++};
++
++&pmu_io_domains {
++ pmuio1-supply = <&vcc3v3_pmu>;
++ pmuio2-supply = <&vcc3v3_pmu>;
++ vccio1-supply = <&vccio_acodec>;
++ vccio2-supply = <&vcc_1v8>;
++ vccio3-supply = <&vccio_sd>;
++ vccio4-supply = <&vcc_1v8>;
++ vccio5-supply = <&vcc_3v3>;
++ vccio6-supply = <&vcc_1v8>;
++ vccio7-supply = <&vcc_3v3>;
++ status = "okay";
++};
++
++&saradc {
++ vref-supply = <&vcca_1v8>;
++ status = "okay";
++};
++
++&sdhci {
++ bus-width = <8>;
++ cap-mmc-highspeed;
++ max-frequency = <200000000>;
++ mmc-hs200-1_8v;
++ non-removable;
++ pinctrl-names = "default";
++ pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd &emmc_datastrobe>;
++ vmmc-supply = <&vcc_3v3>;
++ vqmmc-supply = <&vcc_1v8>;
++ status = "okay";
++};
++
++&sdmmc0 {
++ bus-width = <4>;
++ cap-sd-highspeed;
++ disable-wp;
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd &sdmmc0_det>;
++ vmmc-supply = <&vcc3v3_sd>;
++ vqmmc-supply = <&vccio_sd>;
++ status = "okay";
++};
++
++&sdmmc2 {
++ bus-width = <4>;
++ cap-sd-highspeed;
++ cap-sdio-irq;
++ keep-power-in-suspend;
++ mmc-pwrseq = <&sdio_pwrseq>;
++ non-removable;
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdmmc2m0_bus4 &sdmmc2m0_clk &sdmmc2m0_cmd>;
++ sd-uhs-sdr104;
++ vmmc-supply = <&vcc3v3_sys2>;
++ vqmmc-supply = <&vcc_1v8>;
++ status = "disabled";
++};
++
++&sfc {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "okay";
++
++ flash@0 {
++ compatible = "jedec,spi-nor";
++ reg = <0>;
++ spi-max-frequency = <104000000>;
++ spi-rx-bus-width = <4>;
++ spi-tx-bus-width = <1>;
++ };
++};
++
++&tsadc {
++ rockchip,hw-tshut-mode = <1>;
++ rockchip,hw-tshut-polarity = <0>;
++ status = "okay";
++};
++
++&uart2 {
++ status = "okay";
++};
++
++&uart8 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&uart8m0_xfer &uart8m0_ctsn &uart8m0_rtsn>;
++ uart-has-rtscts;
++ status = "disabled";
++};
++
++&usb_host0_ehci {
++ status = "okay";
++};
++
++&usb_host0_ohci {
++ status = "okay";
++};
++
++&usb_host0_xhci {
++ extcon = <&usb2phy0>;
++ status = "okay";
++};
++
++&usb_host1_xhci {
++ status = "okay";
++};
++
++&usb2phy0 {
++ status = "okay";
++};
++
++&usb2phy0_host {
++ phy-supply = <&vcc5v0_usb_host>;
++ status = "okay";
++};
++
++&usb2phy0_otg {
++ phy-supply = <&vcc5v0_usb_otg>;
++ status = "okay";
++};
++
++&usb2phy1 {
++ status = "okay";
++};
++
++&usb2phy1_otg {
++ phy-supply = <&vcc5v0_usb_host>;
++ status = "okay";
++};
++
++&vop {
++ assigned-clocks = <&cru DCLK_VOP0>, <&cru DCLK_VOP1>;
++ assigned-clock-parents = <&pmucru PLL_HPLL>, <&cru PLL_VPLL>;
++ status = "okay";
++};
++
++&vop_mmu {
++ status = "okay";
++};
++
++&vp0 {
++ vp0_out_hdmi: endpoint@ROCKCHIP_VOP2_EP_HDMI0 {
++ reg = <ROCKCHIP_VOP2_EP_HDMI0>;
++ remote-endpoint = <&hdmi_in_vp0>;
++ };
++};
diff --git a/target/linux/rockchip/patches-6.6/015-v6.10-arm64-dts-rockchip-correct-the-model-name-for-Radxa-.patch b/target/linux/rockchip/patches-6.6/015-v6.10-arm64-dts-rockchip-correct-the-model-name-for-Radxa-.patch
new file mode 100644
index 0000000000..d03039d978
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/015-v6.10-arm64-dts-rockchip-correct-the-model-name-for-Radxa-.patch
@@ -0,0 +1,29 @@
+From 626a479873b6a680b3227c4852bde4a1f2c17fdf Mon Sep 17 00:00:00 2001
+From: Chukun Pan <amadeus@jmu.edu.cn>
+Date: Fri, 19 Apr 2024 18:30:19 +0800
+Subject: [PATCH] arm64: dts: rockchip: correct the model name for Radxa ROCK
+ 3A
+
+According to https://radxa.com/products/rock3/3a,
+the name of this board should be "Radxa ROCK 3A".
+
+Suggested-by: FUKAUMI Naoki <naoki@radxa.com>
+Signed-off-by: Chukun Pan <amadeus@jmu.edu.cn>
+Reviewed-by: Dragan Simic <dsimic@manjaro.org>
+Link: https://lore.kernel.org/r/20240419103019.992586-3-amadeus@jmu.edu.cn
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts
+@@ -8,7 +8,7 @@
+ #include "rk3568.dtsi"
+
+ / {
+- model = "Radxa ROCK3 Model A";
++ model = "Radxa ROCK 3A";
+ compatible = "radxa,rock3a", "rockchip,rk3568";
+
+ aliases {
diff --git a/target/linux/rockchip/patches-6.6/030-01-v6.9-clk-rockchip-rk3588-fix-CLK_NR_CLKS-usage.patch b/target/linux/rockchip/patches-6.6/030-01-v6.9-clk-rockchip-rk3588-fix-CLK_NR_CLKS-usage.patch
new file mode 100644
index 0000000000..6becaf6e86
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/030-01-v6.9-clk-rockchip-rk3588-fix-CLK_NR_CLKS-usage.patch
@@ -0,0 +1,78 @@
+From 2dc66a5ab2c6fb532fbb16107ee7efcb0effbfa5 Mon Sep 17 00:00:00 2001
+From: Sebastian Reichel <sebastian.reichel@collabora.com>
+Date: Fri, 26 Jan 2024 19:18:22 +0100
+Subject: [PATCH] clk: rockchip: rk3588: fix CLK_NR_CLKS usage
+
+CLK_NR_CLKS is not part of the DT bindings and needs to be removed
+from it, just like it recently happened for other platforms. This
+takes care of it by introducing a new function identifying the
+maximum used clock ID at runtime.
+
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20240126182919.48402-2-sebastian.reichel@collabora.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ drivers/clk/rockchip/clk-rk3588.c | 5 ++++-
+ drivers/clk/rockchip/clk.c | 17 +++++++++++++++++
+ drivers/clk/rockchip/clk.h | 2 ++
+ 3 files changed, 23 insertions(+), 1 deletion(-)
+
+--- a/drivers/clk/rockchip/clk-rk3588.c
++++ b/drivers/clk/rockchip/clk-rk3588.c
+@@ -2458,15 +2458,18 @@ static struct rockchip_clk_branch rk3588
+ static void __init rk3588_clk_init(struct device_node *np)
+ {
+ struct rockchip_clk_provider *ctx;
++ unsigned long clk_nr_clks;
+ void __iomem *reg_base;
+
++ clk_nr_clks = rockchip_clk_find_max_clk_id(rk3588_clk_branches,
++ ARRAY_SIZE(rk3588_clk_branches)) + 1;
+ reg_base = of_iomap(np, 0);
+ if (!reg_base) {
+ pr_err("%s: could not map cru region\n", __func__);
+ return;
+ }
+
+- ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS);
++ ctx = rockchip_clk_init(np, reg_base, clk_nr_clks);
+ if (IS_ERR(ctx)) {
+ pr_err("%s: rockchip clk init failed\n", __func__);
+ iounmap(reg_base);
+--- a/drivers/clk/rockchip/clk.c
++++ b/drivers/clk/rockchip/clk.c
+@@ -429,6 +429,23 @@ void rockchip_clk_register_plls(struct r
+ }
+ EXPORT_SYMBOL_GPL(rockchip_clk_register_plls);
+
++unsigned long rockchip_clk_find_max_clk_id(struct rockchip_clk_branch *list,
++ unsigned int nr_clk)
++{
++ unsigned long max = 0;
++ unsigned int idx;
++
++ for (idx = 0; idx < nr_clk; idx++, list++) {
++ if (list->id > max)
++ max = list->id;
++ if (list->child && list->child->id > max)
++ max = list->id;
++ }
++
++ return max;
++}
++EXPORT_SYMBOL_GPL(rockchip_clk_find_max_clk_id);
++
+ void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx,
+ struct rockchip_clk_branch *list,
+ unsigned int nr_clk)
+--- a/drivers/clk/rockchip/clk.h
++++ b/drivers/clk/rockchip/clk.h
+@@ -973,6 +973,8 @@ struct rockchip_clk_provider *rockchip_c
+ void __iomem *base, unsigned long nr_clks);
+ void rockchip_clk_of_add_provider(struct device_node *np,
+ struct rockchip_clk_provider *ctx);
++unsigned long rockchip_clk_find_max_clk_id(struct rockchip_clk_branch *list,
++ unsigned int nr_clk);
+ void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx,
+ struct rockchip_clk_branch *list,
+ unsigned int nr_clk);
diff --git a/target/linux/rockchip/patches-6.6/030-02-v6.9-dt-bindings-clock-rk3588-drop-CLK_NR_CLKS.patch b/target/linux/rockchip/patches-6.6/030-02-v6.9-dt-bindings-clock-rk3588-drop-CLK_NR_CLKS.patch
new file mode 100644
index 0000000000..c8117f08c5
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/030-02-v6.9-dt-bindings-clock-rk3588-drop-CLK_NR_CLKS.patch
@@ -0,0 +1,27 @@
+From 11a29dc2e41ead2be78cfa9d532edf924b461acc Mon Sep 17 00:00:00 2001
+From: Sebastian Reichel <sebastian.reichel@collabora.com>
+Date: Fri, 26 Jan 2024 19:18:23 +0100
+Subject: [PATCH] dt-bindings: clock: rk3588: drop CLK_NR_CLKS
+
+CLK_NR_CLKS should not be part of the binding. Let's drop it, since
+the kernel code no longer uses it either.
+
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20240126182919.48402-3-sebastian.reichel@collabora.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ include/dt-bindings/clock/rockchip,rk3588-cru.h | 2 --
+ 1 file changed, 2 deletions(-)
+
+--- a/include/dt-bindings/clock/rockchip,rk3588-cru.h
++++ b/include/dt-bindings/clock/rockchip,rk3588-cru.h
+@@ -734,8 +734,6 @@
+ #define PCLK_AV1_PRE 719
+ #define HCLK_SDIO_PRE 720
+
+-#define CLK_NR_CLKS (HCLK_SDIO_PRE + 1)
+-
+ /* scmi-clocks indices */
+
+ #define SCMI_CLK_CPUL 0
diff --git a/target/linux/rockchip/patches-6.6/030-03-v6.9-dt-bindings-clock-rk3588-add-missing-PCLK_VO1GRF.patch b/target/linux/rockchip/patches-6.6/030-03-v6.9-dt-bindings-clock-rk3588-add-missing-PCLK_VO1GRF.patch
new file mode 100644
index 0000000000..b960bc6197
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/030-03-v6.9-dt-bindings-clock-rk3588-add-missing-PCLK_VO1GRF.patch
@@ -0,0 +1,26 @@
+From c81798cf9dd2f324934585b2b52a0398caefb88e Mon Sep 17 00:00:00 2001
+From: Sebastian Reichel <sebastian.reichel@collabora.com>
+Date: Fri, 26 Jan 2024 19:18:24 +0100
+Subject: [PATCH] dt-bindings: clock: rk3588: add missing PCLK_VO1GRF
+
+Add PCLK_VO1GRF to complement PCLK_VO0GRF. This will be needed
+for HDMI support.
+
+Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20240126182919.48402-4-sebastian.reichel@collabora.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ include/dt-bindings/clock/rockchip,rk3588-cru.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/include/dt-bindings/clock/rockchip,rk3588-cru.h
++++ b/include/dt-bindings/clock/rockchip,rk3588-cru.h
+@@ -733,6 +733,7 @@
+ #define ACLK_AV1_PRE 718
+ #define PCLK_AV1_PRE 719
+ #define HCLK_SDIO_PRE 720
++#define PCLK_VO1GRF 721
+
+ /* scmi-clocks indices */
+
diff --git a/target/linux/rockchip/patches-6.6/030-04-v6.9-clk-rockchip-rk3588-fix-pclk_vo0grf-and-pclk_vo1grf.patch b/target/linux/rockchip/patches-6.6/030-04-v6.9-clk-rockchip-rk3588-fix-pclk_vo0grf-and-pclk_vo1grf.patch
new file mode 100644
index 0000000000..e12b73fb30
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/030-04-v6.9-clk-rockchip-rk3588-fix-pclk_vo0grf-and-pclk_vo1grf.patch
@@ -0,0 +1,59 @@
+From 326be62eaf2e89767b7b9223f88eaf3c041b98d2 Mon Sep 17 00:00:00 2001
+From: Sebastian Reichel <sebastian.reichel@collabora.com>
+Date: Fri, 26 Jan 2024 19:18:25 +0100
+Subject: [PATCH] clk: rockchip: rk3588: fix pclk_vo0grf and pclk_vo1grf
+
+Currently pclk_vo1grf is not exposed, but it should be referenced
+from the vo1_grf syscon, which needs it enabled. That syscon is
+required for HDMI RX and TX functionality among other things.
+
+Apart from that pclk_vo0grf and pclk_vo1grf are both linked gates
+and need the VO's hclk enabled in addition to their parent clock.
+
+No Fixes tag has been added, since the logic requiring these clocks
+is not yet upstream anyways.
+
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20240126182919.48402-5-sebastian.reichel@collabora.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ drivers/clk/rockchip/clk-rk3588.c | 10 ++++------
+ 1 file changed, 4 insertions(+), 6 deletions(-)
+
+--- a/drivers/clk/rockchip/clk-rk3588.c
++++ b/drivers/clk/rockchip/clk-rk3588.c
+@@ -1851,8 +1851,6 @@ static struct rockchip_clk_branch rk3588
+ RK3588_CLKGATE_CON(56), 0, GFLAGS),
+ GATE(PCLK_TRNG0, "pclk_trng0", "pclk_vo0_root", 0,
+ RK3588_CLKGATE_CON(56), 1, GFLAGS),
+- GATE(PCLK_VO0GRF, "pclk_vo0grf", "pclk_vo0_root", CLK_IGNORE_UNUSED,
+- RK3588_CLKGATE_CON(55), 10, GFLAGS),
+ COMPOSITE(CLK_I2S4_8CH_TX_SRC, "clk_i2s4_8ch_tx_src", gpll_aupll_p, 0,
+ RK3588_CLKSEL_CON(118), 5, 1, MFLAGS, 0, 5, DFLAGS,
+ RK3588_CLKGATE_CON(56), 11, GFLAGS),
+@@ -1998,8 +1996,6 @@ static struct rockchip_clk_branch rk3588
+ RK3588_CLKGATE_CON(60), 9, GFLAGS),
+ GATE(PCLK_TRNG1, "pclk_trng1", "pclk_vo1_root", 0,
+ RK3588_CLKGATE_CON(60), 10, GFLAGS),
+- GATE(0, "pclk_vo1grf", "pclk_vo1_root", CLK_IGNORE_UNUSED,
+- RK3588_CLKGATE_CON(59), 12, GFLAGS),
+ GATE(PCLK_S_EDP0, "pclk_s_edp0", "pclk_vo1_s_root", 0,
+ RK3588_CLKGATE_CON(59), 14, GFLAGS),
+ GATE(PCLK_S_EDP1, "pclk_s_edp1", "pclk_vo1_s_root", 0,
+@@ -2447,12 +2443,14 @@ static struct rockchip_clk_branch rk3588
+ GATE_LINK(HCLK_RKVDEC1_PRE, "hclk_rkvdec1_pre", "hclk_rkvdec1_root", "hclk_vdpu_root", 0, RK3588_CLKGATE_CON(41), 4, GFLAGS),
+ GATE_LINK(ACLK_RKVDEC1_PRE, "aclk_rkvdec1_pre", "aclk_rkvdec1_root", "aclk_vdpu_root", 0, RK3588_CLKGATE_CON(41), 5, GFLAGS),
+ GATE_LINK(ACLK_HDCP0_PRE, "aclk_hdcp0_pre", "aclk_vo0_root", "aclk_vop_low_root", 0, RK3588_CLKGATE_CON(55), 9, GFLAGS),
+- GATE_LINK(HCLK_VO0, "hclk_vo0", "hclk_vo0_root", "hclk_vop_root", 0, RK3588_CLKGATE_CON(55), 5, GFLAGS),
++ GATE_LINK(HCLK_VO0, "hclk_vo0", "hclk_vo0_root", "hclk_vop_root", RK3588_LINKED_CLK, RK3588_CLKGATE_CON(55), 5, GFLAGS),
+ GATE_LINK(ACLK_HDCP1_PRE, "aclk_hdcp1_pre", "aclk_hdcp1_root", "aclk_vo1usb_top_root", 0, RK3588_CLKGATE_CON(59), 6, GFLAGS),
+- GATE_LINK(HCLK_VO1, "hclk_vo1", "hclk_vo1_root", "hclk_vo1usb_top_root", 0, RK3588_CLKGATE_CON(59), 9, GFLAGS),
++ GATE_LINK(HCLK_VO1, "hclk_vo1", "hclk_vo1_root", "hclk_vo1usb_top_root", RK3588_LINKED_CLK, RK3588_CLKGATE_CON(59), 9, GFLAGS),
+ GATE_LINK(ACLK_AV1_PRE, "aclk_av1_pre", "aclk_av1_root", "aclk_vdpu_root", 0, RK3588_CLKGATE_CON(68), 1, GFLAGS),
+ GATE_LINK(PCLK_AV1_PRE, "pclk_av1_pre", "pclk_av1_root", "hclk_vdpu_root", 0, RK3588_CLKGATE_CON(68), 4, GFLAGS),
+ GATE_LINK(HCLK_SDIO_PRE, "hclk_sdio_pre", "hclk_sdio_root", "hclk_nvm", 0, RK3588_CLKGATE_CON(75), 1, GFLAGS),
++ GATE_LINK(PCLK_VO0GRF, "pclk_vo0grf", "pclk_vo0_root", "hclk_vo0", CLK_IGNORE_UNUSED, RK3588_CLKGATE_CON(55), 10, GFLAGS),
++ GATE_LINK(PCLK_VO1GRF, "pclk_vo1grf", "pclk_vo1_root", "hclk_vo1", CLK_IGNORE_UNUSED, RK3588_CLKGATE_CON(59), 12, GFLAGS),
+ };
+
+ static void __init rk3588_clk_init(struct device_node *np)
diff --git a/target/linux/rockchip/patches-6.6/030-05-v6.9-clk-rockchip-rk3588-fix-indent.patch b/target/linux/rockchip/patches-6.6/030-05-v6.9-clk-rockchip-rk3588-fix-indent.patch
new file mode 100644
index 0000000000..27aa28edd5
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/030-05-v6.9-clk-rockchip-rk3588-fix-indent.patch
@@ -0,0 +1,26 @@
+From 2a6e4710672242281347103b64e01693aa823a29 Mon Sep 17 00:00:00 2001
+From: Sebastian Reichel <sebastian.reichel@collabora.com>
+Date: Fri, 26 Jan 2024 19:18:26 +0100
+Subject: [PATCH] clk: rockchip: rk3588: fix indent
+
+pclk_mailbox2 is the only RK3588 clock indented with one tab instead of
+two tabs. Let's fix this.
+
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20240126182919.48402-6-sebastian.reichel@collabora.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ drivers/clk/rockchip/clk-rk3588.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/clk/rockchip/clk-rk3588.c
++++ b/drivers/clk/rockchip/clk-rk3588.c
+@@ -1004,7 +1004,7 @@ static struct rockchip_clk_branch rk3588
+ GATE(PCLK_MAILBOX1, "pclk_mailbox1", "pclk_top_root", 0,
+ RK3588_CLKGATE_CON(16), 12, GFLAGS),
+ GATE(PCLK_MAILBOX2, "pclk_mailbox2", "pclk_top_root", 0,
+- RK3588_CLKGATE_CON(16), 13, GFLAGS),
++ RK3588_CLKGATE_CON(16), 13, GFLAGS),
+ GATE(PCLK_PMU2, "pclk_pmu2", "pclk_top_root", CLK_IS_CRITICAL,
+ RK3588_CLKGATE_CON(19), 3, GFLAGS),
+ GATE(PCLK_PMUCM0_INTMUX, "pclk_pmucm0_intmux", "pclk_top_root", CLK_IS_CRITICAL,
diff --git a/target/linux/rockchip/patches-6.6/030-06-v6.9-clk-rockchip-rk3588-use-linked-clock-ID-for-GATE_LINK.patch b/target/linux/rockchip/patches-6.6/030-06-v6.9-clk-rockchip-rk3588-use-linked-clock-ID-for-GATE_LINK.patch
new file mode 100644
index 0000000000..949041fb9f
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/030-06-v6.9-clk-rockchip-rk3588-use-linked-clock-ID-for-GATE_LINK.patch
@@ -0,0 +1,78 @@
+From dae3e57000fb2d6f491e3ee2956f5918326d6b72 Mon Sep 17 00:00:00 2001
+From: Sebastian Reichel <sebastian.reichel@collabora.com>
+Date: Fri, 26 Jan 2024 19:18:27 +0100
+Subject: [PATCH] clk: rockchip: rk3588: use linked clock ID for GATE_LINK
+
+In preparation for properly supporting GATE_LINK switch the unused
+linked clock argument from the clock's name to its ID. This allows
+easy and fast lookup of the 'struct clk'.
+
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20240126182919.48402-7-sebastian.reichel@collabora.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ drivers/clk/rockchip/clk-rk3588.c | 46 +++++++++++++++----------------
+ 1 file changed, 23 insertions(+), 23 deletions(-)
+
+--- a/drivers/clk/rockchip/clk-rk3588.c
++++ b/drivers/clk/rockchip/clk-rk3588.c
+@@ -29,7 +29,7 @@
+ * power, but avoids leaking implementation details into DT or hanging the
+ * system.
+ */
+-#define GATE_LINK(_id, cname, pname, linkname, f, o, b, gf) \
++#define GATE_LINK(_id, cname, pname, linkedclk, f, o, b, gf) \
+ GATE(_id, cname, pname, f, o, b, gf)
+ #define RK3588_LINKED_CLK CLK_IS_CRITICAL
+
+@@ -2429,28 +2429,28 @@ static struct rockchip_clk_branch rk3588
+ GATE(ACLK_AV1, "aclk_av1", "aclk_av1_pre", 0,
+ RK3588_CLKGATE_CON(68), 2, GFLAGS),
+
+- GATE_LINK(ACLK_ISP1_PRE, "aclk_isp1_pre", "aclk_isp1_root", "aclk_vi_root", 0, RK3588_CLKGATE_CON(26), 6, GFLAGS),
+- GATE_LINK(HCLK_ISP1_PRE, "hclk_isp1_pre", "hclk_isp1_root", "hclk_vi_root", 0, RK3588_CLKGATE_CON(26), 8, GFLAGS),
+- GATE_LINK(HCLK_NVM, "hclk_nvm", "hclk_nvm_root", "aclk_nvm_root", RK3588_LINKED_CLK, RK3588_CLKGATE_CON(31), 2, GFLAGS),
+- GATE_LINK(ACLK_USB, "aclk_usb", "aclk_usb_root", "aclk_vo1usb_top_root", 0, RK3588_CLKGATE_CON(42), 2, GFLAGS),
+- GATE_LINK(HCLK_USB, "hclk_usb", "hclk_usb_root", "hclk_vo1usb_top_root", 0, RK3588_CLKGATE_CON(42), 3, GFLAGS),
+- GATE_LINK(ACLK_JPEG_DECODER_PRE, "aclk_jpeg_decoder_pre", "aclk_jpeg_decoder_root", "aclk_vdpu_root", 0, RK3588_CLKGATE_CON(44), 7, GFLAGS),
+- GATE_LINK(ACLK_VDPU_LOW_PRE, "aclk_vdpu_low_pre", "aclk_vdpu_low_root", "aclk_vdpu_root", 0, RK3588_CLKGATE_CON(44), 5, GFLAGS),
+- GATE_LINK(ACLK_RKVENC1_PRE, "aclk_rkvenc1_pre", "aclk_rkvenc1_root", "aclk_rkvenc0", 0, RK3588_CLKGATE_CON(48), 3, GFLAGS),
+- GATE_LINK(HCLK_RKVENC1_PRE, "hclk_rkvenc1_pre", "hclk_rkvenc1_root", "hclk_rkvenc0", 0, RK3588_CLKGATE_CON(48), 2, GFLAGS),
+- GATE_LINK(HCLK_RKVDEC0_PRE, "hclk_rkvdec0_pre", "hclk_rkvdec0_root", "hclk_vdpu_root", 0, RK3588_CLKGATE_CON(40), 5, GFLAGS),
+- GATE_LINK(ACLK_RKVDEC0_PRE, "aclk_rkvdec0_pre", "aclk_rkvdec0_root", "aclk_vdpu_root", 0, RK3588_CLKGATE_CON(40), 6, GFLAGS),
+- GATE_LINK(HCLK_RKVDEC1_PRE, "hclk_rkvdec1_pre", "hclk_rkvdec1_root", "hclk_vdpu_root", 0, RK3588_CLKGATE_CON(41), 4, GFLAGS),
+- GATE_LINK(ACLK_RKVDEC1_PRE, "aclk_rkvdec1_pre", "aclk_rkvdec1_root", "aclk_vdpu_root", 0, RK3588_CLKGATE_CON(41), 5, GFLAGS),
+- GATE_LINK(ACLK_HDCP0_PRE, "aclk_hdcp0_pre", "aclk_vo0_root", "aclk_vop_low_root", 0, RK3588_CLKGATE_CON(55), 9, GFLAGS),
+- GATE_LINK(HCLK_VO0, "hclk_vo0", "hclk_vo0_root", "hclk_vop_root", RK3588_LINKED_CLK, RK3588_CLKGATE_CON(55), 5, GFLAGS),
+- GATE_LINK(ACLK_HDCP1_PRE, "aclk_hdcp1_pre", "aclk_hdcp1_root", "aclk_vo1usb_top_root", 0, RK3588_CLKGATE_CON(59), 6, GFLAGS),
+- GATE_LINK(HCLK_VO1, "hclk_vo1", "hclk_vo1_root", "hclk_vo1usb_top_root", RK3588_LINKED_CLK, RK3588_CLKGATE_CON(59), 9, GFLAGS),
+- GATE_LINK(ACLK_AV1_PRE, "aclk_av1_pre", "aclk_av1_root", "aclk_vdpu_root", 0, RK3588_CLKGATE_CON(68), 1, GFLAGS),
+- GATE_LINK(PCLK_AV1_PRE, "pclk_av1_pre", "pclk_av1_root", "hclk_vdpu_root", 0, RK3588_CLKGATE_CON(68), 4, GFLAGS),
+- GATE_LINK(HCLK_SDIO_PRE, "hclk_sdio_pre", "hclk_sdio_root", "hclk_nvm", 0, RK3588_CLKGATE_CON(75), 1, GFLAGS),
+- GATE_LINK(PCLK_VO0GRF, "pclk_vo0grf", "pclk_vo0_root", "hclk_vo0", CLK_IGNORE_UNUSED, RK3588_CLKGATE_CON(55), 10, GFLAGS),
+- GATE_LINK(PCLK_VO1GRF, "pclk_vo1grf", "pclk_vo1_root", "hclk_vo1", CLK_IGNORE_UNUSED, RK3588_CLKGATE_CON(59), 12, GFLAGS),
++ GATE_LINK(ACLK_ISP1_PRE, "aclk_isp1_pre", "aclk_isp1_root", ACLK_VI_ROOT, 0, RK3588_CLKGATE_CON(26), 6, GFLAGS),
++ GATE_LINK(HCLK_ISP1_PRE, "hclk_isp1_pre", "hclk_isp1_root", HCLK_VI_ROOT, 0, RK3588_CLKGATE_CON(26), 8, GFLAGS),
++ GATE_LINK(HCLK_NVM, "hclk_nvm", "hclk_nvm_root", ACLK_NVM_ROOT, RK3588_LINKED_CLK, RK3588_CLKGATE_CON(31), 2, GFLAGS),
++ GATE_LINK(ACLK_USB, "aclk_usb", "aclk_usb_root", ACLK_VO1USB_TOP_ROOT, 0, RK3588_CLKGATE_CON(42), 2, GFLAGS),
++ GATE_LINK(HCLK_USB, "hclk_usb", "hclk_usb_root", HCLK_VO1USB_TOP_ROOT, 0, RK3588_CLKGATE_CON(42), 3, GFLAGS),
++ GATE_LINK(ACLK_JPEG_DECODER_PRE, "aclk_jpeg_decoder_pre", "aclk_jpeg_decoder_root", ACLK_VDPU_ROOT, 0, RK3588_CLKGATE_CON(44), 7, GFLAGS),
++ GATE_LINK(ACLK_VDPU_LOW_PRE, "aclk_vdpu_low_pre", "aclk_vdpu_low_root", ACLK_VDPU_ROOT, 0, RK3588_CLKGATE_CON(44), 5, GFLAGS),
++ GATE_LINK(ACLK_RKVENC1_PRE, "aclk_rkvenc1_pre", "aclk_rkvenc1_root", ACLK_RKVENC0, 0, RK3588_CLKGATE_CON(48), 3, GFLAGS),
++ GATE_LINK(HCLK_RKVENC1_PRE, "hclk_rkvenc1_pre", "hclk_rkvenc1_root", HCLK_RKVENC0, 0, RK3588_CLKGATE_CON(48), 2, GFLAGS),
++ GATE_LINK(HCLK_RKVDEC0_PRE, "hclk_rkvdec0_pre", "hclk_rkvdec0_root", HCLK_VDPU_ROOT, 0, RK3588_CLKGATE_CON(40), 5, GFLAGS),
++ GATE_LINK(ACLK_RKVDEC0_PRE, "aclk_rkvdec0_pre", "aclk_rkvdec0_root", ACLK_VDPU_ROOT, 0, RK3588_CLKGATE_CON(40), 6, GFLAGS),
++ GATE_LINK(HCLK_RKVDEC1_PRE, "hclk_rkvdec1_pre", "hclk_rkvdec1_root", HCLK_VDPU_ROOT, 0, RK3588_CLKGATE_CON(41), 4, GFLAGS),
++ GATE_LINK(ACLK_RKVDEC1_PRE, "aclk_rkvdec1_pre", "aclk_rkvdec1_root", ACLK_VDPU_ROOT, 0, RK3588_CLKGATE_CON(41), 5, GFLAGS),
++ GATE_LINK(ACLK_HDCP0_PRE, "aclk_hdcp0_pre", "aclk_vo0_root", ACLK_VOP_LOW_ROOT, 0, RK3588_CLKGATE_CON(55), 9, GFLAGS),
++ GATE_LINK(HCLK_VO0, "hclk_vo0", "hclk_vo0_root", HCLK_VOP_ROOT, RK3588_LINKED_CLK, RK3588_CLKGATE_CON(55), 5, GFLAGS),
++ GATE_LINK(ACLK_HDCP1_PRE, "aclk_hdcp1_pre", "aclk_hdcp1_root", ACLK_VO1USB_TOP_ROOT, 0, RK3588_CLKGATE_CON(59), 6, GFLAGS),
++ GATE_LINK(HCLK_VO1, "hclk_vo1", "hclk_vo1_root", HCLK_VO1USB_TOP_ROOT, RK3588_LINKED_CLK, RK3588_CLKGATE_CON(59), 9, GFLAGS),
++ GATE_LINK(ACLK_AV1_PRE, "aclk_av1_pre", "aclk_av1_root", ACLK_VDPU_ROOT, 0, RK3588_CLKGATE_CON(68), 1, GFLAGS),
++ GATE_LINK(PCLK_AV1_PRE, "pclk_av1_pre", "pclk_av1_root", HCLK_VDPU_ROOT, 0, RK3588_CLKGATE_CON(68), 4, GFLAGS),
++ GATE_LINK(HCLK_SDIO_PRE, "hclk_sdio_pre", "hclk_sdio_root", HCLK_NVM, 0, RK3588_CLKGATE_CON(75), 1, GFLAGS),
++ GATE_LINK(PCLK_VO0GRF, "pclk_vo0grf", "pclk_vo0_root", HCLK_VO0, CLK_IGNORE_UNUSED, RK3588_CLKGATE_CON(55), 10, GFLAGS),
++ GATE_LINK(PCLK_VO1GRF, "pclk_vo1grf", "pclk_vo1_root", HCLK_VO1, CLK_IGNORE_UNUSED, RK3588_CLKGATE_CON(59), 12, GFLAGS),
+ };
+
+ static void __init rk3588_clk_init(struct device_node *np)
diff --git a/target/linux/rockchip/patches-6.6/030-07-v6.10-dt-bindings-reset-Define-reset-id-used-for-HDMI-Receiver.patch b/target/linux/rockchip/patches-6.6/030-07-v6.10-dt-bindings-reset-Define-reset-id-used-for-HDMI-Receiver.patch
new file mode 100644
index 0000000000..0b9082f9b6
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/030-07-v6.10-dt-bindings-reset-Define-reset-id-used-for-HDMI-Receiver.patch
@@ -0,0 +1,24 @@
+From ca151fd56b5736a7adbdba5675b9d87d70f20b23 Mon Sep 17 00:00:00 2001
+From: Shreeya Patel <shreeya.patel@collabora.com>
+Date: Thu, 28 Mar 2024 04:20:52 +0530
+Subject: [PATCH] dt-bindings: reset: Define reset id used for HDMI Receiver
+
+Add reset id used for HDMI Receiver in RK3588 SoCs
+
+Acked-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Shreeya Patel <shreeya.patel@collabora.com>
+Link: https://lore.kernel.org/r/20240327225057.672304-2-shreeya.patel@collabora.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ include/dt-bindings/reset/rockchip,rk3588-cru.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/include/dt-bindings/reset/rockchip,rk3588-cru.h
++++ b/include/dt-bindings/reset/rockchip,rk3588-cru.h
+@@ -751,4 +751,6 @@
+ #define SRST_P_TRNG_CHK 658
+ #define SRST_TRNG_S 659
+
++#define SRST_A_HDMIRX_BIU 660
++
+ #endif
diff --git a/target/linux/rockchip/patches-6.6/030-08-v6.10-clk-rockchip-rk3588-Add-reset-line-for-HDMI-Receiver.patch b/target/linux/rockchip/patches-6.6/030-08-v6.10-clk-rockchip-rk3588-Add-reset-line-for-HDMI-Receiver.patch
new file mode 100644
index 0000000000..6aa9c058a3
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/030-08-v6.10-clk-rockchip-rk3588-Add-reset-line-for-HDMI-Receiver.patch
@@ -0,0 +1,25 @@
+From 7af67019cd78d028ef377df689ac103d51905518 Mon Sep 17 00:00:00 2001
+From: Shreeya Patel <shreeya.patel@collabora.com>
+Date: Thu, 28 Mar 2024 04:20:53 +0530
+Subject: [PATCH] clk: rockchip: rk3588: Add reset line for HDMI Receiver
+
+Export hdmirx_biu reset line required by the Synopsys
+DesignWare HDMIRX Controller.
+
+Signed-off-by: Shreeya Patel <shreeya.patel@collabora.com>
+Link: https://lore.kernel.org/r/20240327225057.672304-3-shreeya.patel@collabora.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ drivers/clk/rockchip/rst-rk3588.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/clk/rockchip/rst-rk3588.c
++++ b/drivers/clk/rockchip/rst-rk3588.c
+@@ -577,6 +577,7 @@ static const int rk3588_register_offset[
+
+ /* SOFTRST_CON59 */
+ RK3588_CRU_RESET_OFFSET(SRST_A_HDCP1_BIU, 59, 6),
++ RK3588_CRU_RESET_OFFSET(SRST_A_HDMIRX_BIU, 59, 7),
+ RK3588_CRU_RESET_OFFSET(SRST_A_VO1_BIU, 59, 8),
+ RK3588_CRU_RESET_OFFSET(SRST_H_VOP1_BIU, 59, 9),
+ RK3588_CRU_RESET_OFFSET(SRST_H_VOP1_S_BIU, 59, 10),
diff --git a/target/linux/rockchip/patches-6.6/031-01-v6.7-mfd-rk8xx-Add-support-for-standard-system-power-controlle.patch b/target/linux/rockchip/patches-6.6/031-01-v6.7-mfd-rk8xx-Add-support-for-standard-system-power-controlle.patch
new file mode 100644
index 0000000000..94d998fe93
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/031-01-v6.7-mfd-rk8xx-Add-support-for-standard-system-power-controlle.patch
@@ -0,0 +1,28 @@
+From 2a46cd97f401a669d71b3d36b78bd6653f8424ee Mon Sep 17 00:00:00 2001
+From: Ondrej Jirman <megi@xff.cz>
+Date: Thu, 19 Oct 2023 18:57:25 +0200
+Subject: [PATCH] mfd: rk8xx: Add support for standard system-power-controller
+ property
+
+DT property rockchip,system-power-controller is now deprecated.
+
+Signed-off-by: Ondrej Jirman <megi@xff.cz>
+Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20231019165732.3818789-4-megi@xff.cz
+Signed-off-by: Lee Jones <lee@kernel.org>
+---
+ drivers/mfd/rk8xx-core.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/mfd/rk8xx-core.c
++++ b/drivers/mfd/rk8xx-core.c
+@@ -677,7 +677,8 @@ int rk8xx_probe(struct device *dev, int
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to add MFD devices\n");
+
+- if (device_property_read_bool(dev, "rockchip,system-power-controller")) {
++ if (device_property_read_bool(dev, "rockchip,system-power-controller") ||
++ device_property_read_bool(dev, "system-power-controller")) {
+ ret = devm_register_sys_off_handler(dev,
+ SYS_OFF_MODE_POWER_OFF_PREPARE, SYS_OFF_PRIO_HIGH,
+ &rk808_power_off, rk808);
diff --git a/target/linux/rockchip/patches-6.6/031-02-v6.7-mfd-rk8xx-Add-support-for-RK806-power-off.patch b/target/linux/rockchip/patches-6.6/031-02-v6.7-mfd-rk8xx-Add-support-for-RK806-power-off.patch
new file mode 100644
index 0000000000..2ac0ff537e
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/031-02-v6.7-mfd-rk8xx-Add-support-for-RK806-power-off.patch
@@ -0,0 +1,29 @@
+From b0227e7081404448a0059b8698fdffd2dec280d2 Mon Sep 17 00:00:00 2001
+From: Ondrej Jirman <megi@xff.cz>
+Date: Thu, 19 Oct 2023 18:57:26 +0200
+Subject: [PATCH] mfd: rk8xx: Add support for RK806 power off
+
+Use DEV_OFF bit to power off the RK806 PMIC, when system-power-controller
+is used in DTS.
+
+Signed-off-by: Ondrej Jirman <megi@xff.cz>
+Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20231019165732.3818789-5-megi@xff.cz
+Signed-off-by: Lee Jones <lee@kernel.org>
+---
+ drivers/mfd/rk8xx-core.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/mfd/rk8xx-core.c
++++ b/drivers/mfd/rk8xx-core.c
+@@ -517,6 +517,10 @@ static int rk808_power_off(struct sys_of
+ reg = RK805_DEV_CTRL_REG;
+ bit = DEV_OFF;
+ break;
++ case RK806_ID:
++ reg = RK806_SYS_CFG3;
++ bit = DEV_OFF;
++ break;
+ case RK808_ID:
+ reg = RK808_DEVCTRL_REG,
+ bit = DEV_OFF_RST;
diff --git a/target/linux/rockchip/patches-6.6/032-01-v6.10-phy-rockchip-add-usbdp-combo-phy-driver.patch b/target/linux/rockchip/patches-6.6/032-01-v6.10-phy-rockchip-add-usbdp-combo-phy-driver.patch
new file mode 100644
index 0000000000..69b44deba3
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/032-01-v6.10-phy-rockchip-add-usbdp-combo-phy-driver.patch
@@ -0,0 +1,1670 @@
+From 2f70bbddeb457580cef3ceb574506083b9272188 Mon Sep 17 00:00:00 2001
+From: Sebastian Reichel <sebastian.reichel@collabora.com>
+Date: Tue, 9 Apr 2024 00:50:29 +0200
+Subject: [PATCH] phy: rockchip: add usbdp combo phy driver
+
+This adds a new USBDP combo PHY with Samsung IP block driver.
+
+The driver get lane mux and mapping info in 2 ways, supporting
+DisplayPort alternate mode or parsing from DT. When parsing from DT,
+the property "rockchip,dp-lane-mux" provide the DP mux and mapping
+info. This is needed when the PHY is not used with TypeC Alt-Mode.
+For example if the USB3 interface of the PHY is connected to a USB
+Type A connector and the DP interface is connected to a DisplayPort
+connector.
+
+When do DP link training, need to set lane number, link rate, swing,
+and pre-emphasis via PHY configure interface.
+
+Co-developed-by: Heiko Stuebner <heiko@sntech.de>
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Co-developed-by: Zhang Yubing <yubing.zhang@rock-chips.com>
+Signed-off-by: Zhang Yubing <yubing.zhang@rock-chips.com>
+Co-developed-by: Frank Wang <frank.wang@rock-chips.com>
+Signed-off-by: Frank Wang <frank.wang@rock-chips.com>
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20240408225109.128953-3-sebastian.reichel@collabora.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+---
+ drivers/phy/rockchip/Kconfig | 12 +
+ drivers/phy/rockchip/Makefile | 1 +
+ drivers/phy/rockchip/phy-rockchip-usbdp.c | 1608 +++++++++++++++++++++
+ 3 files changed, 1621 insertions(+)
+ create mode 100644 drivers/phy/rockchip/phy-rockchip-usbdp.c
+
+--- a/drivers/phy/rockchip/Kconfig
++++ b/drivers/phy/rockchip/Kconfig
+@@ -107,3 +107,15 @@ config PHY_ROCKCHIP_USB
+ select GENERIC_PHY
+ help
+ Enable this to support the Rockchip USB 2.0 PHY.
++
++config PHY_ROCKCHIP_USBDP
++ tristate "Rockchip USBDP COMBO PHY Driver"
++ depends on ARCH_ROCKCHIP && OF
++ select GENERIC_PHY
++ select TYPEC
++ help
++ Enable this to support the Rockchip USB3.0/DP combo PHY with
++ Samsung IP block. This is required for USB3 support on RK3588.
++
++ To compile this driver as a module, choose M here: the module
++ will be called phy-rockchip-usbdp
+--- a/drivers/phy/rockchip/Makefile
++++ b/drivers/phy/rockchip/Makefile
+@@ -11,3 +11,4 @@ obj-$(CONFIG_PHY_ROCKCHIP_PCIE) += phy-
+ obj-$(CONFIG_PHY_ROCKCHIP_SNPS_PCIE3) += phy-rockchip-snps-pcie3.o
+ obj-$(CONFIG_PHY_ROCKCHIP_TYPEC) += phy-rockchip-typec.o
+ obj-$(CONFIG_PHY_ROCKCHIP_USB) += phy-rockchip-usb.o
++obj-$(CONFIG_PHY_ROCKCHIP_USBDP) += phy-rockchip-usbdp.o
+--- /dev/null
++++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c
+@@ -0,0 +1,1608 @@
++// SPDX-License-Identifier: GPL-2.0-or-later
++/*
++ * Rockchip USBDP Combo PHY with Samsung IP block driver
++ *
++ * Copyright (C) 2021-2024 Rockchip Electronics Co., Ltd
++ * Copyright (C) 2024 Collabora Ltd
++ */
++
++#include <dt-bindings/phy/phy.h>
++#include <linux/bitfield.h>
++#include <linux/bits.h>
++#include <linux/clk.h>
++#include <linux/delay.h>
++#include <linux/gpio.h>
++#include <linux/mfd/syscon.h>
++#include <linux/mod_devicetable.h>
++#include <linux/module.h>
++#include <linux/mutex.h>
++#include <linux/phy/phy.h>
++#include <linux/platform_device.h>
++#include <linux/property.h>
++#include <linux/regmap.h>
++#include <linux/reset.h>
++#include <linux/usb/ch9.h>
++#include <linux/usb/typec_dp.h>
++#include <linux/usb/typec_mux.h>
++
++/* USBDP PHY Register Definitions */
++#define UDPHY_PCS 0x4000
++#define UDPHY_PMA 0x8000
++
++/* VO0 GRF Registers */
++#define DP_SINK_HPD_CFG BIT(11)
++#define DP_SINK_HPD_SEL BIT(10)
++#define DP_AUX_DIN_SEL BIT(9)
++#define DP_AUX_DOUT_SEL BIT(8)
++#define DP_LANE_SEL_N(n) GENMASK(2 * (n) + 1, 2 * (n))
++#define DP_LANE_SEL_ALL GENMASK(7, 0)
++
++/* PMA CMN Registers */
++#define CMN_LANE_MUX_AND_EN_OFFSET 0x0288 /* cmn_reg00A2 */
++#define CMN_DP_LANE_MUX_N(n) BIT((n) + 4)
++#define CMN_DP_LANE_EN_N(n) BIT(n)
++#define CMN_DP_LANE_MUX_ALL GENMASK(7, 4)
++#define CMN_DP_LANE_EN_ALL GENMASK(3, 0)
++
++#define CMN_DP_LINK_OFFSET 0x28c /* cmn_reg00A3 */
++#define CMN_DP_TX_LINK_BW GENMASK(6, 5)
++#define CMN_DP_TX_LANE_SWAP_EN BIT(2)
++
++#define CMN_SSC_EN_OFFSET 0x2d0 /* cmn_reg00B4 */
++#define CMN_ROPLL_SSC_EN BIT(1)
++#define CMN_LCPLL_SSC_EN BIT(0)
++
++#define CMN_ANA_LCPLL_DONE_OFFSET 0x0350 /* cmn_reg00D4 */
++#define CMN_ANA_LCPLL_LOCK_DONE BIT(7)
++#define CMN_ANA_LCPLL_AFC_DONE BIT(6)
++
++#define CMN_ANA_ROPLL_DONE_OFFSET 0x0354 /* cmn_reg00D5 */
++#define CMN_ANA_ROPLL_LOCK_DONE BIT(1)
++#define CMN_ANA_ROPLL_AFC_DONE BIT(0)
++
++#define CMN_DP_RSTN_OFFSET 0x038c /* cmn_reg00E3 */
++#define CMN_DP_INIT_RSTN BIT(3)
++#define CMN_DP_CMN_RSTN BIT(2)
++#define CMN_CDR_WTCHDG_EN BIT(1)
++#define CMN_CDR_WTCHDG_MSK_CDR_EN BIT(0)
++
++#define TRSV_ANA_TX_CLK_OFFSET_N(n) (0x854 + (n) * 0x800) /* trsv_reg0215 */
++#define LN_ANA_TX_SER_TXCLK_INV BIT(1)
++
++#define TRSV_LN0_MON_RX_CDR_DONE_OFFSET 0x0b84 /* trsv_reg02E1 */
++#define TRSV_LN0_MON_RX_CDR_LOCK_DONE BIT(0)
++
++#define TRSV_LN2_MON_RX_CDR_DONE_OFFSET 0x1b84 /* trsv_reg06E1 */
++#define TRSV_LN2_MON_RX_CDR_LOCK_DONE BIT(0)
++
++#define BIT_WRITEABLE_SHIFT 16
++#define PHY_AUX_DP_DATA_POL_NORMAL 0
++#define PHY_AUX_DP_DATA_POL_INVERT 1
++#define PHY_LANE_MUX_USB 0
++#define PHY_LANE_MUX_DP 1
++
++enum {
++ DP_BW_RBR,
++ DP_BW_HBR,
++ DP_BW_HBR2,
++ DP_BW_HBR3,
++};
++
++enum {
++ UDPHY_MODE_NONE = 0,
++ UDPHY_MODE_USB = BIT(0),
++ UDPHY_MODE_DP = BIT(1),
++ UDPHY_MODE_DP_USB = BIT(1) | BIT(0),
++};
++
++struct rk_udphy_grf_reg {
++ unsigned int offset;
++ unsigned int disable;
++ unsigned int enable;
++};
++
++#define _RK_UDPHY_GEN_GRF_REG(offset, mask, disable, enable) \
++{\
++ offset, \
++ FIELD_PREP_CONST(mask, disable) | (mask << BIT_WRITEABLE_SHIFT), \
++ FIELD_PREP_CONST(mask, enable) | (mask << BIT_WRITEABLE_SHIFT), \
++}
++
++#define RK_UDPHY_GEN_GRF_REG(offset, bitend, bitstart, disable, enable) \
++ _RK_UDPHY_GEN_GRF_REG(offset, GENMASK(bitend, bitstart), disable, enable)
++
++struct rk_udphy_grf_cfg {
++ /* u2phy-grf */
++ struct rk_udphy_grf_reg bvalid_phy_con;
++ struct rk_udphy_grf_reg bvalid_grf_con;
++
++ /* usb-grf */
++ struct rk_udphy_grf_reg usb3otg0_cfg;
++ struct rk_udphy_grf_reg usb3otg1_cfg;
++
++ /* usbdpphy-grf */
++ struct rk_udphy_grf_reg low_pwrn;
++ struct rk_udphy_grf_reg rx_lfps;
++};
++
++struct rk_udphy_vogrf_cfg {
++ /* vo-grf */
++ struct rk_udphy_grf_reg hpd_trigger;
++ u32 dp_lane_reg;
++};
++
++struct rk_udphy_dp_tx_drv_ctrl {
++ u32 trsv_reg0204;
++ u32 trsv_reg0205;
++ u32 trsv_reg0206;
++ u32 trsv_reg0207;
++};
++
++struct rk_udphy_cfg {
++ unsigned int num_phys;
++ unsigned int phy_ids[2];
++ /* resets to be requested */
++ const char * const *rst_list;
++ int num_rsts;
++
++ struct rk_udphy_grf_cfg grfcfg;
++ struct rk_udphy_vogrf_cfg vogrfcfg[2];
++ const struct rk_udphy_dp_tx_drv_ctrl (*dp_tx_ctrl_cfg[4])[4];
++ const struct rk_udphy_dp_tx_drv_ctrl (*dp_tx_ctrl_cfg_typec[4])[4];
++};
++
++struct rk_udphy {
++ struct device *dev;
++ struct regmap *pma_regmap;
++ struct regmap *u2phygrf;
++ struct regmap *udphygrf;
++ struct regmap *usbgrf;
++ struct regmap *vogrf;
++ struct typec_switch_dev *sw;
++ struct typec_mux_dev *mux;
++ struct mutex mutex; /* mutex to protect access to individual PHYs */
++
++ /* clocks and rests */
++ int num_clks;
++ struct clk_bulk_data *clks;
++ struct clk *refclk;
++ int num_rsts;
++ struct reset_control_bulk_data *rsts;
++
++ /* PHY status management */
++ bool flip;
++ bool mode_change;
++ u8 mode;
++ u8 status;
++
++ /* utilized for USB */
++ bool hs; /* flag for high-speed */
++
++ /* utilized for DP */
++ struct gpio_desc *sbu1_dc_gpio;
++ struct gpio_desc *sbu2_dc_gpio;
++ u32 lane_mux_sel[4];
++ u32 dp_lane_sel[4];
++ u32 dp_aux_dout_sel;
++ u32 dp_aux_din_sel;
++ bool dp_sink_hpd_sel;
++ bool dp_sink_hpd_cfg;
++ u8 bw;
++ int id;
++
++ bool dp_in_use;
++
++ /* PHY const config */
++ const struct rk_udphy_cfg *cfgs;
++
++ /* PHY devices */
++ struct phy *phy_dp;
++ struct phy *phy_u3;
++};
++
++static const struct rk_udphy_dp_tx_drv_ctrl rk3588_dp_tx_drv_ctrl_rbr_hbr[4][4] = {
++ /* voltage swing 0, pre-emphasis 0->3 */
++ {
++ { 0x20, 0x10, 0x42, 0xe5 },
++ { 0x26, 0x14, 0x42, 0xe5 },
++ { 0x29, 0x18, 0x42, 0xe5 },
++ { 0x2b, 0x1c, 0x43, 0xe7 },
++ },
++
++ /* voltage swing 1, pre-emphasis 0->2 */
++ {
++ { 0x23, 0x10, 0x42, 0xe7 },
++ { 0x2a, 0x17, 0x43, 0xe7 },
++ { 0x2b, 0x1a, 0x43, 0xe7 },
++ },
++
++ /* voltage swing 2, pre-emphasis 0->1 */
++ {
++ { 0x27, 0x10, 0x42, 0xe7 },
++ { 0x2b, 0x17, 0x43, 0xe7 },
++ },
++
++ /* voltage swing 3, pre-emphasis 0 */
++ {
++ { 0x29, 0x10, 0x43, 0xe7 },
++ },
++};
++
++static const struct rk_udphy_dp_tx_drv_ctrl rk3588_dp_tx_drv_ctrl_rbr_hbr_typec[4][4] = {
++ /* voltage swing 0, pre-emphasis 0->3 */
++ {
++ { 0x20, 0x10, 0x42, 0xe5 },
++ { 0x26, 0x14, 0x42, 0xe5 },
++ { 0x29, 0x18, 0x42, 0xe5 },
++ { 0x2b, 0x1c, 0x43, 0xe7 },
++ },
++
++ /* voltage swing 1, pre-emphasis 0->2 */
++ {
++ { 0x23, 0x10, 0x42, 0xe7 },
++ { 0x2a, 0x17, 0x43, 0xe7 },
++ { 0x2b, 0x1a, 0x43, 0xe7 },
++ },
++
++ /* voltage swing 2, pre-emphasis 0->1 */
++ {
++ { 0x27, 0x10, 0x43, 0x67 },
++ { 0x2b, 0x17, 0x43, 0xe7 },
++ },
++
++ /* voltage swing 3, pre-emphasis 0 */
++ {
++ { 0x29, 0x10, 0x43, 0xe7 },
++ },
++};
++
++static const struct rk_udphy_dp_tx_drv_ctrl rk3588_dp_tx_drv_ctrl_hbr2[4][4] = {
++ /* voltage swing 0, pre-emphasis 0->3 */
++ {
++ { 0x21, 0x10, 0x42, 0xe5 },
++ { 0x26, 0x14, 0x42, 0xe5 },
++ { 0x26, 0x16, 0x43, 0xe5 },
++ { 0x2a, 0x19, 0x43, 0xe7 },
++ },
++
++ /* voltage swing 1, pre-emphasis 0->2 */
++ {
++ { 0x24, 0x10, 0x42, 0xe7 },
++ { 0x2a, 0x17, 0x43, 0xe7 },
++ { 0x2b, 0x1a, 0x43, 0xe7 },
++ },
++
++ /* voltage swing 2, pre-emphasis 0->1 */
++ {
++ { 0x28, 0x10, 0x42, 0xe7 },
++ { 0x2b, 0x17, 0x43, 0xe7 },
++ },
++
++ /* voltage swing 3, pre-emphasis 0 */
++ {
++ { 0x28, 0x10, 0x43, 0xe7 },
++ },
++};
++
++static const struct rk_udphy_dp_tx_drv_ctrl rk3588_dp_tx_drv_ctrl_hbr3[4][4] = {
++ /* voltage swing 0, pre-emphasis 0->3 */
++ {
++ { 0x21, 0x10, 0x42, 0xe5 },
++ { 0x26, 0x14, 0x42, 0xe5 },
++ { 0x26, 0x16, 0x43, 0xe5 },
++ { 0x29, 0x18, 0x43, 0xe7 },
++ },
++
++ /* voltage swing 1, pre-emphasis 0->2 */
++ {
++ { 0x24, 0x10, 0x42, 0xe7 },
++ { 0x2a, 0x18, 0x43, 0xe7 },
++ { 0x2b, 0x1b, 0x43, 0xe7 }
++ },
++
++ /* voltage swing 2, pre-emphasis 0->1 */
++ {
++ { 0x27, 0x10, 0x42, 0xe7 },
++ { 0x2b, 0x18, 0x43, 0xe7 }
++ },
++
++ /* voltage swing 3, pre-emphasis 0 */
++ {
++ { 0x28, 0x10, 0x43, 0xe7 },
++ },
++};
++
++static const struct reg_sequence rk_udphy_24m_refclk_cfg[] = {
++ {0x0090, 0x68}, {0x0094, 0x68},
++ {0x0128, 0x24}, {0x012c, 0x44},
++ {0x0130, 0x3f}, {0x0134, 0x44},
++ {0x015c, 0xa9}, {0x0160, 0x71},
++ {0x0164, 0x71}, {0x0168, 0xa9},
++ {0x0174, 0xa9}, {0x0178, 0x71},
++ {0x017c, 0x71}, {0x0180, 0xa9},
++ {0x018c, 0x41}, {0x0190, 0x00},
++ {0x0194, 0x05}, {0x01ac, 0x2a},
++ {0x01b0, 0x17}, {0x01b4, 0x17},
++ {0x01b8, 0x2a}, {0x01c8, 0x04},
++ {0x01cc, 0x08}, {0x01d0, 0x08},
++ {0x01d4, 0x04}, {0x01d8, 0x20},
++ {0x01dc, 0x01}, {0x01e0, 0x09},
++ {0x01e4, 0x03}, {0x01f0, 0x29},
++ {0x01f4, 0x02}, {0x01f8, 0x02},
++ {0x01fc, 0x29}, {0x0208, 0x2a},
++ {0x020c, 0x17}, {0x0210, 0x17},
++ {0x0214, 0x2a}, {0x0224, 0x20},
++ {0x03f0, 0x0a}, {0x03f4, 0x07},
++ {0x03f8, 0x07}, {0x03fc, 0x0c},
++ {0x0404, 0x12}, {0x0408, 0x1a},
++ {0x040c, 0x1a}, {0x0410, 0x3f},
++ {0x0ce0, 0x68}, {0x0ce8, 0xd0},
++ {0x0cf0, 0x87}, {0x0cf8, 0x70},
++ {0x0d00, 0x70}, {0x0d08, 0xa9},
++ {0x1ce0, 0x68}, {0x1ce8, 0xd0},
++ {0x1cf0, 0x87}, {0x1cf8, 0x70},
++ {0x1d00, 0x70}, {0x1d08, 0xa9},
++ {0x0a3c, 0xd0}, {0x0a44, 0xd0},
++ {0x0a48, 0x01}, {0x0a4c, 0x0d},
++ {0x0a54, 0xe0}, {0x0a5c, 0xe0},
++ {0x0a64, 0xa8}, {0x1a3c, 0xd0},
++ {0x1a44, 0xd0}, {0x1a48, 0x01},
++ {0x1a4c, 0x0d}, {0x1a54, 0xe0},
++ {0x1a5c, 0xe0}, {0x1a64, 0xa8}
++};
++
++static const struct reg_sequence rk_udphy_26m_refclk_cfg[] = {
++ {0x0830, 0x07}, {0x085c, 0x80},
++ {0x1030, 0x07}, {0x105c, 0x80},
++ {0x1830, 0x07}, {0x185c, 0x80},
++ {0x2030, 0x07}, {0x205c, 0x80},
++ {0x0228, 0x38}, {0x0104, 0x44},
++ {0x0248, 0x44}, {0x038c, 0x02},
++ {0x0878, 0x04}, {0x1878, 0x04},
++ {0x0898, 0x77}, {0x1898, 0x77},
++ {0x0054, 0x01}, {0x00e0, 0x38},
++ {0x0060, 0x24}, {0x0064, 0x77},
++ {0x0070, 0x76}, {0x0234, 0xe8},
++ {0x0af4, 0x15}, {0x1af4, 0x15},
++ {0x081c, 0xe5}, {0x181c, 0xe5},
++ {0x099c, 0x48}, {0x199c, 0x48},
++ {0x09a4, 0x07}, {0x09a8, 0x22},
++ {0x19a4, 0x07}, {0x19a8, 0x22},
++ {0x09b8, 0x3e}, {0x19b8, 0x3e},
++ {0x09e4, 0x02}, {0x19e4, 0x02},
++ {0x0a34, 0x1e}, {0x1a34, 0x1e},
++ {0x0a98, 0x2f}, {0x1a98, 0x2f},
++ {0x0c30, 0x0e}, {0x0c48, 0x06},
++ {0x1c30, 0x0e}, {0x1c48, 0x06},
++ {0x028c, 0x18}, {0x0af0, 0x00},
++ {0x1af0, 0x00}
++};
++
++static const struct reg_sequence rk_udphy_init_sequence[] = {
++ {0x0104, 0x44}, {0x0234, 0xe8},
++ {0x0248, 0x44}, {0x028c, 0x18},
++ {0x081c, 0xe5}, {0x0878, 0x00},
++ {0x0994, 0x1c}, {0x0af0, 0x00},
++ {0x181c, 0xe5}, {0x1878, 0x00},
++ {0x1994, 0x1c}, {0x1af0, 0x00},
++ {0x0428, 0x60}, {0x0d58, 0x33},
++ {0x1d58, 0x33}, {0x0990, 0x74},
++ {0x0d64, 0x17}, {0x08c8, 0x13},
++ {0x1990, 0x74}, {0x1d64, 0x17},
++ {0x18c8, 0x13}, {0x0d90, 0x40},
++ {0x0da8, 0x40}, {0x0dc0, 0x40},
++ {0x0dd8, 0x40}, {0x1d90, 0x40},
++ {0x1da8, 0x40}, {0x1dc0, 0x40},
++ {0x1dd8, 0x40}, {0x03c0, 0x30},
++ {0x03c4, 0x06}, {0x0e10, 0x00},
++ {0x1e10, 0x00}, {0x043c, 0x0f},
++ {0x0d2c, 0xff}, {0x1d2c, 0xff},
++ {0x0d34, 0x0f}, {0x1d34, 0x0f},
++ {0x08fc, 0x2a}, {0x0914, 0x28},
++ {0x0a30, 0x03}, {0x0e38, 0x03},
++ {0x0ecc, 0x27}, {0x0ed0, 0x22},
++ {0x0ed4, 0x26}, {0x18fc, 0x2a},
++ {0x1914, 0x28}, {0x1a30, 0x03},
++ {0x1e38, 0x03}, {0x1ecc, 0x27},
++ {0x1ed0, 0x22}, {0x1ed4, 0x26},
++ {0x0048, 0x0f}, {0x0060, 0x3c},
++ {0x0064, 0xf7}, {0x006c, 0x20},
++ {0x0070, 0x7d}, {0x0074, 0x68},
++ {0x0af4, 0x1a}, {0x1af4, 0x1a},
++ {0x0440, 0x3f}, {0x10d4, 0x08},
++ {0x20d4, 0x08}, {0x00d4, 0x30},
++ {0x0024, 0x6e},
++};
++
++static inline int rk_udphy_grfreg_write(struct regmap *base,
++ const struct rk_udphy_grf_reg *reg, bool en)
++{
++ return regmap_write(base, reg->offset, en ? reg->enable : reg->disable);
++}
++
++static int rk_udphy_clk_init(struct rk_udphy *udphy, struct device *dev)
++{
++ int i;
++
++ udphy->num_clks = devm_clk_bulk_get_all(dev, &udphy->clks);
++ if (udphy->num_clks < 1)
++ return -ENODEV;
++
++ /* used for configure phy reference clock frequency */
++ for (i = 0; i < udphy->num_clks; i++) {
++ if (!strncmp(udphy->clks[i].id, "refclk", 6)) {
++ udphy->refclk = udphy->clks[i].clk;
++ break;
++ }
++ }
++
++ if (!udphy->refclk)
++ return dev_err_probe(udphy->dev, -EINVAL, "no refclk found\n");
++
++ return 0;
++}
++
++static int rk_udphy_reset_assert_all(struct rk_udphy *udphy)
++{
++ return reset_control_bulk_assert(udphy->num_rsts, udphy->rsts);
++}
++
++static int rk_udphy_reset_deassert_all(struct rk_udphy *udphy)
++{
++ return reset_control_bulk_deassert(udphy->num_rsts, udphy->rsts);
++}
++
++static int rk_udphy_reset_deassert(struct rk_udphy *udphy, char *name)
++{
++ struct reset_control_bulk_data *list = udphy->rsts;
++ int idx;
++
++ for (idx = 0; idx < udphy->num_rsts; idx++) {
++ if (!strcmp(list[idx].id, name))
++ return reset_control_deassert(list[idx].rstc);
++ }
++
++ return -EINVAL;
++}
++
++static int rk_udphy_reset_init(struct rk_udphy *udphy, struct device *dev)
++{
++ const struct rk_udphy_cfg *cfg = udphy->cfgs;
++ int idx;
++
++ udphy->num_rsts = cfg->num_rsts;
++ udphy->rsts = devm_kcalloc(dev, udphy->num_rsts,
++ sizeof(*udphy->rsts), GFP_KERNEL);
++ if (!udphy->rsts)
++ return -ENOMEM;
++
++ for (idx = 0; idx < cfg->num_rsts; idx++)
++ udphy->rsts[idx].id = cfg->rst_list[idx];
++
++ return devm_reset_control_bulk_get_exclusive(dev, cfg->num_rsts,
++ udphy->rsts);
++}
++
++static void rk_udphy_u3_port_disable(struct rk_udphy *udphy, u8 disable)
++{
++ const struct rk_udphy_cfg *cfg = udphy->cfgs;
++ const struct rk_udphy_grf_reg *preg;
++
++ preg = udphy->id ? &cfg->grfcfg.usb3otg1_cfg : &cfg->grfcfg.usb3otg0_cfg;
++ rk_udphy_grfreg_write(udphy->usbgrf, preg, disable);
++}
++
++static void rk_udphy_usb_bvalid_enable(struct rk_udphy *udphy, u8 enable)
++{
++ const struct rk_udphy_cfg *cfg = udphy->cfgs;
++
++ rk_udphy_grfreg_write(udphy->u2phygrf, &cfg->grfcfg.bvalid_phy_con, enable);
++ rk_udphy_grfreg_write(udphy->u2phygrf, &cfg->grfcfg.bvalid_grf_con, enable);
++}
++
++/*
++ * In usb/dp combo phy driver, here are 2 ways to mapping lanes.
++ *
++ * 1 Type-C Mapping table (DP_Alt_Mode V1.0b remove ABF pin mapping)
++ * ---------------------------------------------------------------------------
++ * Type-C Pin B11-B10 A2-A3 A11-A10 B2-B3
++ * PHY Pad ln0(tx/rx) ln1(tx) ln2(tx/rx) ln3(tx)
++ * C/E(Normal) dpln3 dpln2 dpln0 dpln1
++ * C/E(Flip ) dpln0 dpln1 dpln3 dpln2
++ * D/F(Normal) usbrx usbtx dpln0 dpln1
++ * D/F(Flip ) dpln0 dpln1 usbrx usbtx
++ * A(Normal ) dpln3 dpln1 dpln2 dpln0
++ * A(Flip ) dpln2 dpln0 dpln3 dpln1
++ * B(Normal ) usbrx usbtx dpln1 dpln0
++ * B(Flip ) dpln1 dpln0 usbrx usbtx
++ * ---------------------------------------------------------------------------
++ *
++ * 2 Mapping the lanes in dtsi
++ * if all 4 lane assignment for dp function, define rockchip,dp-lane-mux = <x x x x>;
++ * sample as follow:
++ * ---------------------------------------------------------------------------
++ * B11-B10 A2-A3 A11-A10 B2-B3
++ * rockchip,dp-lane-mux ln0(tx/rx) ln1(tx) ln2(tx/rx) ln3(tx)
++ * <0 1 2 3> dpln0 dpln1 dpln2 dpln3
++ * <2 3 0 1> dpln2 dpln3 dpln0 dpln1
++ * ---------------------------------------------------------------------------
++ * if 2 lane for dp function, 2 lane for usb function, define rockchip,dp-lane-mux = <x x>;
++ * sample as follow:
++ * ---------------------------------------------------------------------------
++ * B11-B10 A2-A3 A11-A10 B2-B3
++ * rockchip,dp-lane-mux ln0(tx/rx) ln1(tx) ln2(tx/rx) ln3(tx)
++ * <0 1> dpln0 dpln1 usbrx usbtx
++ * <2 3> usbrx usbtx dpln0 dpln1
++ * ---------------------------------------------------------------------------
++ */
++
++static void rk_udphy_dplane_select(struct rk_udphy *udphy)
++{
++ const struct rk_udphy_cfg *cfg = udphy->cfgs;
++ u32 value = 0;
++
++ switch (udphy->mode) {
++ case UDPHY_MODE_DP:
++ value |= 2 << udphy->dp_lane_sel[2] * 2;
++ value |= 3 << udphy->dp_lane_sel[3] * 2;
++ fallthrough;
++
++ case UDPHY_MODE_DP_USB:
++ value |= 0 << udphy->dp_lane_sel[0] * 2;
++ value |= 1 << udphy->dp_lane_sel[1] * 2;
++ break;
++
++ case UDPHY_MODE_USB:
++ break;
++
++ default:
++ break;
++ }
++
++ regmap_write(udphy->vogrf, cfg->vogrfcfg[udphy->id].dp_lane_reg,
++ ((DP_AUX_DIN_SEL | DP_AUX_DOUT_SEL | DP_LANE_SEL_ALL) << 16) |
++ FIELD_PREP(DP_AUX_DIN_SEL, udphy->dp_aux_din_sel) |
++ FIELD_PREP(DP_AUX_DOUT_SEL, udphy->dp_aux_dout_sel) | value);
++}
++
++static int rk_udphy_dplane_get(struct rk_udphy *udphy)
++{
++ int dp_lanes;
++
++ switch (udphy->mode) {
++ case UDPHY_MODE_DP:
++ dp_lanes = 4;
++ break;
++
++ case UDPHY_MODE_DP_USB:
++ dp_lanes = 2;
++ break;
++
++ case UDPHY_MODE_USB:
++ default:
++ dp_lanes = 0;
++ break;
++ }
++
++ return dp_lanes;
++}
++
++static void rk_udphy_dplane_enable(struct rk_udphy *udphy, int dp_lanes)
++{
++ u32 val = 0;
++ int i;
++
++ for (i = 0; i < dp_lanes; i++)
++ val |= BIT(udphy->dp_lane_sel[i]);
++
++ regmap_update_bits(udphy->pma_regmap, CMN_LANE_MUX_AND_EN_OFFSET, CMN_DP_LANE_EN_ALL,
++ FIELD_PREP(CMN_DP_LANE_EN_ALL, val));
++
++ if (!dp_lanes)
++ regmap_update_bits(udphy->pma_regmap, CMN_DP_RSTN_OFFSET,
++ CMN_DP_CMN_RSTN, FIELD_PREP(CMN_DP_CMN_RSTN, 0x0));
++}
++
++static void rk_udphy_dp_hpd_event_trigger(struct rk_udphy *udphy, bool hpd)
++{
++ const struct rk_udphy_cfg *cfg = udphy->cfgs;
++
++ udphy->dp_sink_hpd_sel = true;
++ udphy->dp_sink_hpd_cfg = hpd;
++
++ if (!udphy->dp_in_use)
++ return;
++
++ rk_udphy_grfreg_write(udphy->vogrf, &cfg->vogrfcfg[udphy->id].hpd_trigger, hpd);
++}
++
++static void rk_udphy_set_typec_default_mapping(struct rk_udphy *udphy)
++{
++ if (udphy->flip) {
++ udphy->dp_lane_sel[0] = 0;
++ udphy->dp_lane_sel[1] = 1;
++ udphy->dp_lane_sel[2] = 3;
++ udphy->dp_lane_sel[3] = 2;
++ udphy->lane_mux_sel[0] = PHY_LANE_MUX_DP;
++ udphy->lane_mux_sel[1] = PHY_LANE_MUX_DP;
++ udphy->lane_mux_sel[2] = PHY_LANE_MUX_USB;
++ udphy->lane_mux_sel[3] = PHY_LANE_MUX_USB;
++ udphy->dp_aux_dout_sel = PHY_AUX_DP_DATA_POL_INVERT;
++ udphy->dp_aux_din_sel = PHY_AUX_DP_DATA_POL_INVERT;
++ gpiod_set_value_cansleep(udphy->sbu1_dc_gpio, 1);
++ gpiod_set_value_cansleep(udphy->sbu2_dc_gpio, 0);
++ } else {
++ udphy->dp_lane_sel[0] = 2;
++ udphy->dp_lane_sel[1] = 3;
++ udphy->dp_lane_sel[2] = 1;
++ udphy->dp_lane_sel[3] = 0;
++ udphy->lane_mux_sel[0] = PHY_LANE_MUX_USB;
++ udphy->lane_mux_sel[1] = PHY_LANE_MUX_USB;
++ udphy->lane_mux_sel[2] = PHY_LANE_MUX_DP;
++ udphy->lane_mux_sel[3] = PHY_LANE_MUX_DP;
++ udphy->dp_aux_dout_sel = PHY_AUX_DP_DATA_POL_NORMAL;
++ udphy->dp_aux_din_sel = PHY_AUX_DP_DATA_POL_NORMAL;
++ gpiod_set_value_cansleep(udphy->sbu1_dc_gpio, 0);
++ gpiod_set_value_cansleep(udphy->sbu2_dc_gpio, 1);
++ }
++
++ udphy->mode = UDPHY_MODE_DP_USB;
++}
++
++static int rk_udphy_orien_sw_set(struct typec_switch_dev *sw,
++ enum typec_orientation orien)
++{
++ struct rk_udphy *udphy = typec_switch_get_drvdata(sw);
++
++ mutex_lock(&udphy->mutex);
++
++ if (orien == TYPEC_ORIENTATION_NONE) {
++ gpiod_set_value_cansleep(udphy->sbu1_dc_gpio, 0);
++ gpiod_set_value_cansleep(udphy->sbu2_dc_gpio, 0);
++ /* unattached */
++ rk_udphy_usb_bvalid_enable(udphy, false);
++ goto unlock_ret;
++ }
++
++ udphy->flip = (orien == TYPEC_ORIENTATION_REVERSE) ? true : false;
++ rk_udphy_set_typec_default_mapping(udphy);
++ rk_udphy_usb_bvalid_enable(udphy, true);
++
++unlock_ret:
++ mutex_unlock(&udphy->mutex);
++ return 0;
++}
++
++static void rk_udphy_orien_switch_unregister(void *data)
++{
++ struct rk_udphy *udphy = data;
++
++ typec_switch_unregister(udphy->sw);
++}
++
++static int rk_udphy_setup_orien_switch(struct rk_udphy *udphy)
++{
++ struct typec_switch_desc sw_desc = { };
++
++ sw_desc.drvdata = udphy;
++ sw_desc.fwnode = dev_fwnode(udphy->dev);
++ sw_desc.set = rk_udphy_orien_sw_set;
++
++ udphy->sw = typec_switch_register(udphy->dev, &sw_desc);
++ if (IS_ERR(udphy->sw)) {
++ dev_err(udphy->dev, "Error register typec orientation switch: %ld\n",
++ PTR_ERR(udphy->sw));
++ return PTR_ERR(udphy->sw);
++ }
++
++ return devm_add_action_or_reset(udphy->dev,
++ rk_udphy_orien_switch_unregister, udphy);
++}
++
++static int rk_udphy_refclk_set(struct rk_udphy *udphy)
++{
++ unsigned long rate;
++ int ret;
++
++ /* configure phy reference clock */
++ rate = clk_get_rate(udphy->refclk);
++ dev_dbg(udphy->dev, "refclk freq %ld\n", rate);
++
++ switch (rate) {
++ case 24000000:
++ ret = regmap_multi_reg_write(udphy->pma_regmap, rk_udphy_24m_refclk_cfg,
++ ARRAY_SIZE(rk_udphy_24m_refclk_cfg));
++ if (ret)
++ return ret;
++ break;
++
++ case 26000000:
++ /* register default is 26MHz */
++ ret = regmap_multi_reg_write(udphy->pma_regmap, rk_udphy_26m_refclk_cfg,
++ ARRAY_SIZE(rk_udphy_26m_refclk_cfg));
++ if (ret)
++ return ret;
++ break;
++
++ default:
++ dev_err(udphy->dev, "unsupported refclk freq %ld\n", rate);
++ return -EINVAL;
++ }
++
++ return 0;
++}
++
++static int rk_udphy_status_check(struct rk_udphy *udphy)
++{
++ unsigned int val;
++ int ret;
++
++ /* LCPLL check */
++ if (udphy->mode & UDPHY_MODE_USB) {
++ ret = regmap_read_poll_timeout(udphy->pma_regmap, CMN_ANA_LCPLL_DONE_OFFSET,
++ val, (val & CMN_ANA_LCPLL_AFC_DONE) &&
++ (val & CMN_ANA_LCPLL_LOCK_DONE), 200, 100000);
++ if (ret) {
++ dev_err(udphy->dev, "cmn ana lcpll lock timeout\n");
++ /*
++ * If earlier software (U-Boot) enabled USB once already
++ * the PLL may have problems locking on the first try.
++ * It will be successful on the second try, so for the
++ * time being a -EPROBE_DEFER will solve the issue.
++ *
++ * This requires further investigation to understand the
++ * root cause, especially considering that the driver is
++ * asserting all reset lines at probe time.
++ */
++ return -EPROBE_DEFER;
++ }
++
++ if (!udphy->flip) {
++ ret = regmap_read_poll_timeout(udphy->pma_regmap,
++ TRSV_LN0_MON_RX_CDR_DONE_OFFSET, val,
++ val & TRSV_LN0_MON_RX_CDR_LOCK_DONE,
++ 200, 100000);
++ if (ret)
++ dev_err(udphy->dev, "trsv ln0 mon rx cdr lock timeout\n");
++ } else {
++ ret = regmap_read_poll_timeout(udphy->pma_regmap,
++ TRSV_LN2_MON_RX_CDR_DONE_OFFSET, val,
++ val & TRSV_LN2_MON_RX_CDR_LOCK_DONE,
++ 200, 100000);
++ if (ret)
++ dev_err(udphy->dev, "trsv ln2 mon rx cdr lock timeout\n");
++ }
++ }
++
++ return 0;
++}
++
++static int rk_udphy_init(struct rk_udphy *udphy)
++{
++ const struct rk_udphy_cfg *cfg = udphy->cfgs;
++ int ret;
++
++ rk_udphy_reset_assert_all(udphy);
++ usleep_range(10000, 11000);
++
++ /* enable rx lfps for usb */
++ if (udphy->mode & UDPHY_MODE_USB)
++ rk_udphy_grfreg_write(udphy->udphygrf, &cfg->grfcfg.rx_lfps, true);
++
++ /* Step 1: power on pma and deassert apb rstn */
++ rk_udphy_grfreg_write(udphy->udphygrf, &cfg->grfcfg.low_pwrn, true);
++
++ rk_udphy_reset_deassert(udphy, "pma_apb");
++ rk_udphy_reset_deassert(udphy, "pcs_apb");
++
++ /* Step 2: set init sequence and phy refclk */
++ ret = regmap_multi_reg_write(udphy->pma_regmap, rk_udphy_init_sequence,
++ ARRAY_SIZE(rk_udphy_init_sequence));
++ if (ret) {
++ dev_err(udphy->dev, "init sequence set error %d\n", ret);
++ goto assert_resets;
++ }
++
++ ret = rk_udphy_refclk_set(udphy);
++ if (ret) {
++ dev_err(udphy->dev, "refclk set error %d\n", ret);
++ goto assert_resets;
++ }
++
++ /* Step 3: configure lane mux */
++ regmap_update_bits(udphy->pma_regmap, CMN_LANE_MUX_AND_EN_OFFSET,
++ CMN_DP_LANE_MUX_ALL | CMN_DP_LANE_EN_ALL,
++ FIELD_PREP(CMN_DP_LANE_MUX_N(3), udphy->lane_mux_sel[3]) |
++ FIELD_PREP(CMN_DP_LANE_MUX_N(2), udphy->lane_mux_sel[2]) |
++ FIELD_PREP(CMN_DP_LANE_MUX_N(1), udphy->lane_mux_sel[1]) |
++ FIELD_PREP(CMN_DP_LANE_MUX_N(0), udphy->lane_mux_sel[0]) |
++ FIELD_PREP(CMN_DP_LANE_EN_ALL, 0));
++
++ /* Step 4: deassert init rstn and wait for 200ns from datasheet */
++ if (udphy->mode & UDPHY_MODE_USB)
++ rk_udphy_reset_deassert(udphy, "init");
++
++ if (udphy->mode & UDPHY_MODE_DP) {
++ regmap_update_bits(udphy->pma_regmap, CMN_DP_RSTN_OFFSET,
++ CMN_DP_INIT_RSTN,
++ FIELD_PREP(CMN_DP_INIT_RSTN, 0x1));
++ }
++
++ udelay(1);
++
++ /* Step 5: deassert cmn/lane rstn */
++ if (udphy->mode & UDPHY_MODE_USB) {
++ rk_udphy_reset_deassert(udphy, "cmn");
++ rk_udphy_reset_deassert(udphy, "lane");
++ }
++
++ /* Step 6: wait for lock done of pll */
++ ret = rk_udphy_status_check(udphy);
++ if (ret)
++ goto assert_resets;
++
++ return 0;
++
++assert_resets:
++ rk_udphy_reset_assert_all(udphy);
++ return ret;
++}
++
++static int rk_udphy_setup(struct rk_udphy *udphy)
++{
++ int ret;
++
++ ret = clk_bulk_prepare_enable(udphy->num_clks, udphy->clks);
++ if (ret) {
++ dev_err(udphy->dev, "failed to enable clk\n");
++ return ret;
++ }
++
++ ret = rk_udphy_init(udphy);
++ if (ret) {
++ dev_err(udphy->dev, "failed to init combophy\n");
++ clk_bulk_disable_unprepare(udphy->num_clks, udphy->clks);
++ return ret;
++ }
++
++ return 0;
++}
++
++static void rk_udphy_disable(struct rk_udphy *udphy)
++{
++ clk_bulk_disable_unprepare(udphy->num_clks, udphy->clks);
++ rk_udphy_reset_assert_all(udphy);
++}
++
++static int rk_udphy_parse_lane_mux_data(struct rk_udphy *udphy)
++{
++ int ret, i, num_lanes;
++
++ num_lanes = device_property_count_u32(udphy->dev, "rockchip,dp-lane-mux");
++ if (num_lanes < 0) {
++ dev_dbg(udphy->dev, "no dp-lane-mux, following dp alt mode\n");
++ udphy->mode = UDPHY_MODE_USB;
++ return 0;
++ }
++
++ if (num_lanes != 2 && num_lanes != 4)
++ return dev_err_probe(udphy->dev, -EINVAL,
++ "invalid number of lane mux\n");
++
++ ret = device_property_read_u32_array(udphy->dev, "rockchip,dp-lane-mux",
++ udphy->dp_lane_sel, num_lanes);
++ if (ret)
++ return dev_err_probe(udphy->dev, ret, "get dp lane mux failed\n");
++
++ for (i = 0; i < num_lanes; i++) {
++ int j;
++
++ if (udphy->dp_lane_sel[i] > 3)
++ return dev_err_probe(udphy->dev, -EINVAL,
++ "lane mux between 0 and 3, exceeding the range\n");
++
++ udphy->lane_mux_sel[udphy->dp_lane_sel[i]] = PHY_LANE_MUX_DP;
++
++ for (j = i + 1; j < num_lanes; j++) {
++ if (udphy->dp_lane_sel[i] == udphy->dp_lane_sel[j])
++ return dev_err_probe(udphy->dev, -EINVAL,
++ "set repeat lane mux value\n");
++ }
++ }
++
++ udphy->mode = UDPHY_MODE_DP;
++ if (num_lanes == 2) {
++ udphy->mode |= UDPHY_MODE_USB;
++ udphy->flip = (udphy->lane_mux_sel[0] == PHY_LANE_MUX_DP);
++ }
++
++ return 0;
++}
++
++static int rk_udphy_get_initial_status(struct rk_udphy *udphy)
++{
++ int ret;
++ u32 value;
++
++ ret = clk_bulk_prepare_enable(udphy->num_clks, udphy->clks);
++ if (ret) {
++ dev_err(udphy->dev, "failed to enable clk\n");
++ return ret;
++ }
++
++ rk_udphy_reset_deassert_all(udphy);
++
++ regmap_read(udphy->pma_regmap, CMN_LANE_MUX_AND_EN_OFFSET, &value);
++ if (FIELD_GET(CMN_DP_LANE_MUX_ALL, value) && FIELD_GET(CMN_DP_LANE_EN_ALL, value))
++ udphy->status = UDPHY_MODE_DP;
++ else
++ rk_udphy_disable(udphy);
++
++ return 0;
++}
++
++static int rk_udphy_parse_dt(struct rk_udphy *udphy)
++{
++ struct device *dev = udphy->dev;
++ struct device_node *np = dev_of_node(dev);
++ enum usb_device_speed maximum_speed;
++ int ret;
++
++ udphy->u2phygrf = syscon_regmap_lookup_by_phandle(np, "rockchip,u2phy-grf");
++ if (IS_ERR(udphy->u2phygrf))
++ return dev_err_probe(dev, PTR_ERR(udphy->u2phygrf), "failed to get u2phy-grf\n");
++
++ udphy->udphygrf = syscon_regmap_lookup_by_phandle(np, "rockchip,usbdpphy-grf");
++ if (IS_ERR(udphy->udphygrf))
++ return dev_err_probe(dev, PTR_ERR(udphy->udphygrf), "failed to get usbdpphy-grf\n");
++
++ udphy->usbgrf = syscon_regmap_lookup_by_phandle(np, "rockchip,usb-grf");
++ if (IS_ERR(udphy->usbgrf))
++ return dev_err_probe(dev, PTR_ERR(udphy->usbgrf), "failed to get usb-grf\n");
++
++ udphy->vogrf = syscon_regmap_lookup_by_phandle(np, "rockchip,vo-grf");
++ if (IS_ERR(udphy->vogrf))
++ return dev_err_probe(dev, PTR_ERR(udphy->vogrf), "failed to get vo-grf\n");
++
++ ret = rk_udphy_parse_lane_mux_data(udphy);
++ if (ret)
++ return ret;
++
++ udphy->sbu1_dc_gpio = devm_gpiod_get_optional(dev, "sbu1-dc", GPIOD_OUT_LOW);
++ if (IS_ERR(udphy->sbu1_dc_gpio))
++ return PTR_ERR(udphy->sbu1_dc_gpio);
++
++ udphy->sbu2_dc_gpio = devm_gpiod_get_optional(dev, "sbu2-dc", GPIOD_OUT_LOW);
++ if (IS_ERR(udphy->sbu2_dc_gpio))
++ return PTR_ERR(udphy->sbu2_dc_gpio);
++
++ if (device_property_present(dev, "maximum-speed")) {
++ maximum_speed = usb_get_maximum_speed(dev);
++ udphy->hs = maximum_speed <= USB_SPEED_HIGH ? true : false;
++ }
++
++ ret = rk_udphy_clk_init(udphy, dev);
++ if (ret)
++ return ret;
++
++ return rk_udphy_reset_init(udphy, dev);
++}
++
++static int rk_udphy_power_on(struct rk_udphy *udphy, u8 mode)
++{
++ int ret;
++
++ if (!(udphy->mode & mode)) {
++ dev_info(udphy->dev, "mode 0x%02x is not support\n", mode);
++ return 0;
++ }
++
++ if (udphy->status == UDPHY_MODE_NONE) {
++ udphy->mode_change = false;
++ ret = rk_udphy_setup(udphy);
++ if (ret)
++ return ret;
++
++ if (udphy->mode & UDPHY_MODE_USB)
++ rk_udphy_u3_port_disable(udphy, false);
++ } else if (udphy->mode_change) {
++ udphy->mode_change = false;
++ udphy->status = UDPHY_MODE_NONE;
++ if (udphy->mode == UDPHY_MODE_DP)
++ rk_udphy_u3_port_disable(udphy, true);
++
++ rk_udphy_disable(udphy);
++ ret = rk_udphy_setup(udphy);
++ if (ret)
++ return ret;
++ }
++
++ udphy->status |= mode;
++
++ return 0;
++}
++
++static void rk_udphy_power_off(struct rk_udphy *udphy, u8 mode)
++{
++ if (!(udphy->mode & mode)) {
++ dev_info(udphy->dev, "mode 0x%02x is not support\n", mode);
++ return;
++ }
++
++ if (!udphy->status)
++ return;
++
++ udphy->status &= ~mode;
++
++ if (udphy->status == UDPHY_MODE_NONE)
++ rk_udphy_disable(udphy);
++}
++
++static int rk_udphy_dp_phy_init(struct phy *phy)
++{
++ struct rk_udphy *udphy = phy_get_drvdata(phy);
++
++ mutex_lock(&udphy->mutex);
++
++ udphy->dp_in_use = true;
++ rk_udphy_dp_hpd_event_trigger(udphy, udphy->dp_sink_hpd_cfg);
++
++ mutex_unlock(&udphy->mutex);
++
++ return 0;
++}
++
++static int rk_udphy_dp_phy_exit(struct phy *phy)
++{
++ struct rk_udphy *udphy = phy_get_drvdata(phy);
++
++ mutex_lock(&udphy->mutex);
++ udphy->dp_in_use = false;
++ mutex_unlock(&udphy->mutex);
++ return 0;
++}
++
++static int rk_udphy_dp_phy_power_on(struct phy *phy)
++{
++ struct rk_udphy *udphy = phy_get_drvdata(phy);
++ int ret, dp_lanes;
++
++ mutex_lock(&udphy->mutex);
++
++ dp_lanes = rk_udphy_dplane_get(udphy);
++ phy_set_bus_width(phy, dp_lanes);
++
++ ret = rk_udphy_power_on(udphy, UDPHY_MODE_DP);
++ if (ret)
++ goto unlock;
++
++ rk_udphy_dplane_enable(udphy, dp_lanes);
++
++ rk_udphy_dplane_select(udphy);
++
++unlock:
++ mutex_unlock(&udphy->mutex);
++ /*
++ * If data send by aux channel too fast after phy power on,
++ * the aux may be not ready which will cause aux error. Adding
++ * delay to avoid this issue.
++ */
++ usleep_range(10000, 11000);
++ return ret;
++}
++
++static int rk_udphy_dp_phy_power_off(struct phy *phy)
++{
++ struct rk_udphy *udphy = phy_get_drvdata(phy);
++
++ mutex_lock(&udphy->mutex);
++ rk_udphy_dplane_enable(udphy, 0);
++ rk_udphy_power_off(udphy, UDPHY_MODE_DP);
++ mutex_unlock(&udphy->mutex);
++
++ return 0;
++}
++
++static int rk_udphy_dp_phy_verify_link_rate(unsigned int link_rate)
++{
++ switch (link_rate) {
++ case 1620:
++ case 2700:
++ case 5400:
++ case 8100:
++ break;
++
++ default:
++ return -EINVAL;
++ }
++
++ return 0;
++}
++
++static int rk_udphy_dp_phy_verify_config(struct rk_udphy *udphy,
++ struct phy_configure_opts_dp *dp)
++{
++ int i, ret;
++
++ /* If changing link rate was required, verify it's supported. */
++ ret = rk_udphy_dp_phy_verify_link_rate(dp->link_rate);
++ if (ret)
++ return ret;
++
++ /* Verify lane count. */
++ switch (dp->lanes) {
++ case 1:
++ case 2:
++ case 4:
++ /* valid lane count. */
++ break;
++
++ default:
++ return -EINVAL;
++ }
++
++ /*
++ * If changing voltages is required, check swing and pre-emphasis
++ * levels, per-lane.
++ */
++ if (dp->set_voltages) {
++ /* Lane count verified previously. */
++ for (i = 0; i < dp->lanes; i++) {
++ if (dp->voltage[i] > 3 || dp->pre[i] > 3)
++ return -EINVAL;
++
++ /*
++ * Sum of voltage swing and pre-emphasis levels cannot
++ * exceed 3.
++ */
++ if (dp->voltage[i] + dp->pre[i] > 3)
++ return -EINVAL;
++ }
++ }
++
++ return 0;
++}
++
++static void rk_udphy_dp_set_voltage(struct rk_udphy *udphy, u8 bw,
++ u32 voltage, u32 pre, u32 lane)
++{
++ const struct rk_udphy_cfg *cfg = udphy->cfgs;
++ const struct rk_udphy_dp_tx_drv_ctrl (*dp_ctrl)[4];
++ u32 offset = 0x800 * lane;
++ u32 val;
++
++ if (udphy->mux)
++ dp_ctrl = cfg->dp_tx_ctrl_cfg_typec[bw];
++ else
++ dp_ctrl = cfg->dp_tx_ctrl_cfg[bw];
++
++ val = dp_ctrl[voltage][pre].trsv_reg0204;
++ regmap_write(udphy->pma_regmap, 0x0810 + offset, val);
++
++ val = dp_ctrl[voltage][pre].trsv_reg0205;
++ regmap_write(udphy->pma_regmap, 0x0814 + offset, val);
++
++ val = dp_ctrl[voltage][pre].trsv_reg0206;
++ regmap_write(udphy->pma_regmap, 0x0818 + offset, val);
++
++ val = dp_ctrl[voltage][pre].trsv_reg0207;
++ regmap_write(udphy->pma_regmap, 0x081c + offset, val);
++}
++
++static int rk_udphy_dp_phy_configure(struct phy *phy,
++ union phy_configure_opts *opts)
++{
++ struct rk_udphy *udphy = phy_get_drvdata(phy);
++ struct phy_configure_opts_dp *dp = &opts->dp;
++ u32 i, val, lane;
++ int ret;
++
++ ret = rk_udphy_dp_phy_verify_config(udphy, dp);
++ if (ret)
++ return ret;
++
++ if (dp->set_rate) {
++ regmap_update_bits(udphy->pma_regmap, CMN_DP_RSTN_OFFSET,
++ CMN_DP_CMN_RSTN, FIELD_PREP(CMN_DP_CMN_RSTN, 0x0));
++
++ switch (dp->link_rate) {
++ case 1620:
++ udphy->bw = DP_BW_RBR;
++ break;
++
++ case 2700:
++ udphy->bw = DP_BW_HBR;
++ break;
++
++ case 5400:
++ udphy->bw = DP_BW_HBR2;
++ break;
++
++ case 8100:
++ udphy->bw = DP_BW_HBR3;
++ break;
++
++ default:
++ return -EINVAL;
++ }
++
++ regmap_update_bits(udphy->pma_regmap, CMN_DP_LINK_OFFSET, CMN_DP_TX_LINK_BW,
++ FIELD_PREP(CMN_DP_TX_LINK_BW, udphy->bw));
++ regmap_update_bits(udphy->pma_regmap, CMN_SSC_EN_OFFSET, CMN_ROPLL_SSC_EN,
++ FIELD_PREP(CMN_ROPLL_SSC_EN, dp->ssc));
++ regmap_update_bits(udphy->pma_regmap, CMN_DP_RSTN_OFFSET, CMN_DP_CMN_RSTN,
++ FIELD_PREP(CMN_DP_CMN_RSTN, 0x1));
++
++ ret = regmap_read_poll_timeout(udphy->pma_regmap, CMN_ANA_ROPLL_DONE_OFFSET, val,
++ FIELD_GET(CMN_ANA_ROPLL_LOCK_DONE, val) &&
++ FIELD_GET(CMN_ANA_ROPLL_AFC_DONE, val),
++ 0, 1000);
++ if (ret) {
++ dev_err(udphy->dev, "ROPLL is not lock, set_rate failed\n");
++ return ret;
++ }
++ }
++
++ if (dp->set_voltages) {
++ for (i = 0; i < dp->lanes; i++) {
++ lane = udphy->dp_lane_sel[i];
++ switch (dp->link_rate) {
++ case 1620:
++ case 2700:
++ regmap_update_bits(udphy->pma_regmap,
++ TRSV_ANA_TX_CLK_OFFSET_N(lane),
++ LN_ANA_TX_SER_TXCLK_INV,
++ FIELD_PREP(LN_ANA_TX_SER_TXCLK_INV,
++ udphy->lane_mux_sel[lane]));
++ break;
++
++ case 5400:
++ case 8100:
++ regmap_update_bits(udphy->pma_regmap,
++ TRSV_ANA_TX_CLK_OFFSET_N(lane),
++ LN_ANA_TX_SER_TXCLK_INV,
++ FIELD_PREP(LN_ANA_TX_SER_TXCLK_INV, 0x0));
++ break;
++ }
++
++ rk_udphy_dp_set_voltage(udphy, udphy->bw, dp->voltage[i],
++ dp->pre[i], lane);
++ }
++ }
++
++ return 0;
++}
++
++static const struct phy_ops rk_udphy_dp_phy_ops = {
++ .init = rk_udphy_dp_phy_init,
++ .exit = rk_udphy_dp_phy_exit,
++ .power_on = rk_udphy_dp_phy_power_on,
++ .power_off = rk_udphy_dp_phy_power_off,
++ .configure = rk_udphy_dp_phy_configure,
++ .owner = THIS_MODULE,
++};
++
++static int rk_udphy_usb3_phy_init(struct phy *phy)
++{
++ struct rk_udphy *udphy = phy_get_drvdata(phy);
++ int ret;
++
++ mutex_lock(&udphy->mutex);
++ /* DP only or high-speed, disable U3 port */
++ if (!(udphy->mode & UDPHY_MODE_USB) || udphy->hs) {
++ rk_udphy_u3_port_disable(udphy, true);
++ goto unlock;
++ }
++
++ ret = rk_udphy_power_on(udphy, UDPHY_MODE_USB);
++
++unlock:
++ mutex_unlock(&udphy->mutex);
++ return ret;
++}
++
++static int rk_udphy_usb3_phy_exit(struct phy *phy)
++{
++ struct rk_udphy *udphy = phy_get_drvdata(phy);
++
++ mutex_lock(&udphy->mutex);
++ /* DP only or high-speed */
++ if (!(udphy->mode & UDPHY_MODE_USB) || udphy->hs)
++ goto unlock;
++
++ rk_udphy_power_off(udphy, UDPHY_MODE_USB);
++
++unlock:
++ mutex_unlock(&udphy->mutex);
++ return 0;
++}
++
++static const struct phy_ops rk_udphy_usb3_phy_ops = {
++ .init = rk_udphy_usb3_phy_init,
++ .exit = rk_udphy_usb3_phy_exit,
++ .owner = THIS_MODULE,
++};
++
++static int rk_udphy_typec_mux_set(struct typec_mux_dev *mux,
++ struct typec_mux_state *state)
++{
++ struct rk_udphy *udphy = typec_mux_get_drvdata(mux);
++ u8 mode;
++
++ mutex_lock(&udphy->mutex);
++
++ switch (state->mode) {
++ case TYPEC_DP_STATE_C:
++ case TYPEC_DP_STATE_E:
++ udphy->lane_mux_sel[0] = PHY_LANE_MUX_DP;
++ udphy->lane_mux_sel[1] = PHY_LANE_MUX_DP;
++ udphy->lane_mux_sel[2] = PHY_LANE_MUX_DP;
++ udphy->lane_mux_sel[3] = PHY_LANE_MUX_DP;
++ mode = UDPHY_MODE_DP;
++ break;
++
++ case TYPEC_DP_STATE_D:
++ default:
++ if (udphy->flip) {
++ udphy->lane_mux_sel[0] = PHY_LANE_MUX_DP;
++ udphy->lane_mux_sel[1] = PHY_LANE_MUX_DP;
++ udphy->lane_mux_sel[2] = PHY_LANE_MUX_USB;
++ udphy->lane_mux_sel[3] = PHY_LANE_MUX_USB;
++ } else {
++ udphy->lane_mux_sel[0] = PHY_LANE_MUX_USB;
++ udphy->lane_mux_sel[1] = PHY_LANE_MUX_USB;
++ udphy->lane_mux_sel[2] = PHY_LANE_MUX_DP;
++ udphy->lane_mux_sel[3] = PHY_LANE_MUX_DP;
++ }
++ mode = UDPHY_MODE_DP_USB;
++ break;
++ }
++
++ if (state->alt && state->alt->svid == USB_TYPEC_DP_SID) {
++ struct typec_displayport_data *data = state->data;
++
++ if (!data) {
++ rk_udphy_dp_hpd_event_trigger(udphy, false);
++ } else if (data->status & DP_STATUS_IRQ_HPD) {
++ rk_udphy_dp_hpd_event_trigger(udphy, false);
++ usleep_range(750, 800);
++ rk_udphy_dp_hpd_event_trigger(udphy, true);
++ } else if (data->status & DP_STATUS_HPD_STATE) {
++ if (udphy->mode != mode) {
++ udphy->mode = mode;
++ udphy->mode_change = true;
++ }
++ rk_udphy_dp_hpd_event_trigger(udphy, true);
++ } else {
++ rk_udphy_dp_hpd_event_trigger(udphy, false);
++ }
++ }
++
++ mutex_unlock(&udphy->mutex);
++ return 0;
++}
++
++static void rk_udphy_typec_mux_unregister(void *data)
++{
++ struct rk_udphy *udphy = data;
++
++ typec_mux_unregister(udphy->mux);
++}
++
++static int rk_udphy_setup_typec_mux(struct rk_udphy *udphy)
++{
++ struct typec_mux_desc mux_desc = {};
++
++ mux_desc.drvdata = udphy;
++ mux_desc.fwnode = dev_fwnode(udphy->dev);
++ mux_desc.set = rk_udphy_typec_mux_set;
++
++ udphy->mux = typec_mux_register(udphy->dev, &mux_desc);
++ if (IS_ERR(udphy->mux)) {
++ dev_err(udphy->dev, "Error register typec mux: %ld\n",
++ PTR_ERR(udphy->mux));
++ return PTR_ERR(udphy->mux);
++ }
++
++ return devm_add_action_or_reset(udphy->dev, rk_udphy_typec_mux_unregister,
++ udphy);
++}
++
++static const struct regmap_config rk_udphy_pma_regmap_cfg = {
++ .reg_bits = 32,
++ .reg_stride = 4,
++ .val_bits = 32,
++ .fast_io = true,
++ .max_register = 0x20dc,
++};
++
++static struct phy *rk_udphy_phy_xlate(struct device *dev, struct of_phandle_args *args)
++{
++ struct rk_udphy *udphy = dev_get_drvdata(dev);
++
++ if (args->args_count == 0)
++ return ERR_PTR(-EINVAL);
++
++ switch (args->args[0]) {
++ case PHY_TYPE_USB3:
++ return udphy->phy_u3;
++ case PHY_TYPE_DP:
++ return udphy->phy_dp;
++ }
++
++ return ERR_PTR(-EINVAL);
++}
++
++static int rk_udphy_probe(struct platform_device *pdev)
++{
++ struct device *dev = &pdev->dev;
++ struct phy_provider *phy_provider;
++ struct resource *res;
++ struct rk_udphy *udphy;
++ void __iomem *base;
++ int id, ret;
++
++ udphy = devm_kzalloc(dev, sizeof(*udphy), GFP_KERNEL);
++ if (!udphy)
++ return -ENOMEM;
++
++ udphy->cfgs = device_get_match_data(dev);
++ if (!udphy->cfgs)
++ return dev_err_probe(dev, -EINVAL, "missing match data\n");
++
++ base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
++ if (IS_ERR(base))
++ return PTR_ERR(base);
++
++ /* find the phy-id from the io address */
++ udphy->id = -ENODEV;
++ for (id = 0; id < udphy->cfgs->num_phys; id++) {
++ if (res->start == udphy->cfgs->phy_ids[id]) {
++ udphy->id = id;
++ break;
++ }
++ }
++
++ if (udphy->id < 0)
++ return dev_err_probe(dev, -ENODEV, "no matching device found\n");
++
++ udphy->pma_regmap = devm_regmap_init_mmio(dev, base + UDPHY_PMA,
++ &rk_udphy_pma_regmap_cfg);
++ if (IS_ERR(udphy->pma_regmap))
++ return PTR_ERR(udphy->pma_regmap);
++
++ udphy->dev = dev;
++ ret = rk_udphy_parse_dt(udphy);
++ if (ret)
++ return ret;
++
++ ret = rk_udphy_get_initial_status(udphy);
++ if (ret)
++ return ret;
++
++ mutex_init(&udphy->mutex);
++ platform_set_drvdata(pdev, udphy);
++
++ if (device_property_present(dev, "orientation-switch")) {
++ ret = rk_udphy_setup_orien_switch(udphy);
++ if (ret)
++ return ret;
++ }
++
++ if (device_property_present(dev, "mode-switch")) {
++ ret = rk_udphy_setup_typec_mux(udphy);
++ if (ret)
++ return ret;
++ }
++
++ udphy->phy_u3 = devm_phy_create(dev, dev->of_node, &rk_udphy_usb3_phy_ops);
++ if (IS_ERR(udphy->phy_u3)) {
++ ret = PTR_ERR(udphy->phy_u3);
++ return dev_err_probe(dev, ret, "failed to create USB3 phy\n");
++ }
++ phy_set_drvdata(udphy->phy_u3, udphy);
++
++ udphy->phy_dp = devm_phy_create(dev, dev->of_node, &rk_udphy_dp_phy_ops);
++ if (IS_ERR(udphy->phy_dp)) {
++ ret = PTR_ERR(udphy->phy_dp);
++ return dev_err_probe(dev, ret, "failed to create DP phy\n");
++ }
++ phy_set_bus_width(udphy->phy_dp, rk_udphy_dplane_get(udphy));
++ udphy->phy_dp->attrs.max_link_rate = 8100;
++ phy_set_drvdata(udphy->phy_dp, udphy);
++
++ phy_provider = devm_of_phy_provider_register(dev, rk_udphy_phy_xlate);
++ if (IS_ERR(phy_provider)) {
++ ret = PTR_ERR(phy_provider);
++ return dev_err_probe(dev, ret, "failed to register phy provider\n");
++ }
++
++ return 0;
++}
++
++static int __maybe_unused rk_udphy_resume(struct device *dev)
++{
++ struct rk_udphy *udphy = dev_get_drvdata(dev);
++
++ if (udphy->dp_sink_hpd_sel)
++ rk_udphy_dp_hpd_event_trigger(udphy, udphy->dp_sink_hpd_cfg);
++
++ return 0;
++}
++
++static const struct dev_pm_ops rk_udphy_pm_ops = {
++ SET_LATE_SYSTEM_SLEEP_PM_OPS(NULL, rk_udphy_resume)
++};
++
++static const char * const rk_udphy_rst_list[] = {
++ "init", "cmn", "lane", "pcs_apb", "pma_apb"
++};
++
++static const struct rk_udphy_cfg rk3588_udphy_cfgs = {
++ .num_phys = 2,
++ .phy_ids = {
++ 0xfed80000,
++ 0xfed90000,
++ },
++ .num_rsts = ARRAY_SIZE(rk_udphy_rst_list),
++ .rst_list = rk_udphy_rst_list,
++ .grfcfg = {
++ /* u2phy-grf */
++ .bvalid_phy_con = RK_UDPHY_GEN_GRF_REG(0x0008, 1, 0, 0x2, 0x3),
++ .bvalid_grf_con = RK_UDPHY_GEN_GRF_REG(0x0010, 3, 2, 0x2, 0x3),
++
++ /* usb-grf */
++ .usb3otg0_cfg = RK_UDPHY_GEN_GRF_REG(0x001c, 15, 0, 0x1100, 0x0188),
++ .usb3otg1_cfg = RK_UDPHY_GEN_GRF_REG(0x0034, 15, 0, 0x1100, 0x0188),
++
++ /* usbdpphy-grf */
++ .low_pwrn = RK_UDPHY_GEN_GRF_REG(0x0004, 13, 13, 0, 1),
++ .rx_lfps = RK_UDPHY_GEN_GRF_REG(0x0004, 14, 14, 0, 1),
++ },
++ .vogrfcfg = {
++ {
++ .hpd_trigger = RK_UDPHY_GEN_GRF_REG(0x0000, 11, 10, 1, 3),
++ .dp_lane_reg = 0x0000,
++ },
++ {
++ .hpd_trigger = RK_UDPHY_GEN_GRF_REG(0x0008, 11, 10, 1, 3),
++ .dp_lane_reg = 0x0008,
++ },
++ },
++ .dp_tx_ctrl_cfg = {
++ rk3588_dp_tx_drv_ctrl_rbr_hbr,
++ rk3588_dp_tx_drv_ctrl_rbr_hbr,
++ rk3588_dp_tx_drv_ctrl_hbr2,
++ rk3588_dp_tx_drv_ctrl_hbr3,
++ },
++ .dp_tx_ctrl_cfg_typec = {
++ rk3588_dp_tx_drv_ctrl_rbr_hbr_typec,
++ rk3588_dp_tx_drv_ctrl_rbr_hbr_typec,
++ rk3588_dp_tx_drv_ctrl_hbr2,
++ rk3588_dp_tx_drv_ctrl_hbr3,
++ },
++};
++
++static const struct of_device_id rk_udphy_dt_match[] = {
++ {
++ .compatible = "rockchip,rk3588-usbdp-phy",
++ .data = &rk3588_udphy_cfgs
++ },
++ { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, rk_udphy_dt_match);
++
++static struct platform_driver rk_udphy_driver = {
++ .probe = rk_udphy_probe,
++ .driver = {
++ .name = "rockchip-usbdp-phy",
++ .of_match_table = rk_udphy_dt_match,
++ .pm = &rk_udphy_pm_ops,
++ },
++};
++module_platform_driver(rk_udphy_driver);
++
++MODULE_AUTHOR("Frank Wang <frank.wang@rock-chips.com>");
++MODULE_AUTHOR("Zhang Yubing <yubing.zhang@rock-chips.com>");
++MODULE_DESCRIPTION("Rockchip USBDP Combo PHY driver");
++MODULE_LICENSE("GPL");
diff --git a/target/linux/rockchip/patches-6.6/032-02-v6.10-phy-rockchip-usbdp-fix-uninitialized-variable.patch b/target/linux/rockchip/patches-6.6/032-02-v6.10-phy-rockchip-usbdp-fix-uninitialized-variable.patch
new file mode 100644
index 0000000000..65bd8a7ed8
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/032-02-v6.10-phy-rockchip-usbdp-fix-uninitialized-variable.patch
@@ -0,0 +1,35 @@
+From c9342d1a351ee1249fa98d936f756299a83d5684 Mon Sep 17 00:00:00 2001
+From: Sebastian Reichel <sebastian.reichel@collabora.com>
+Date: Tue, 16 Apr 2024 16:51:23 +0200
+Subject: [PATCH] phy: rockchip: usbdp: fix uninitialized variable
+
+The ret variable may not be initialized in rk_udphy_usb3_phy_init(), if
+the PHY is not using USB3 mode.
+
+Since the DisplayPort part is handled separately and the PHY does not
+support USB2 (which is routed to another PHY on Rockchip RK3588), the
+right exit code for this case is 0. Thus let's initialize the variable
+accordingly.
+
+Fixes: 2f70bbddeb457 ("phy: rockchip: add usbdp combo phy driver")
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202404141048.qFAYDctQ-lkp@intel.com/
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Reviewed-by: Muhammad Usama Anjum <usama.anjum@collabora.com>
+Link: https://lore.kernel.org/r/20240416145233.94687-1-sebastian.reichel@collabora.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+---
+ drivers/phy/rockchip/phy-rockchip-usbdp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/phy/rockchip/phy-rockchip-usbdp.c
++++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c
+@@ -1285,7 +1285,7 @@ static const struct phy_ops rk_udphy_dp_
+ static int rk_udphy_usb3_phy_init(struct phy *phy)
+ {
+ struct rk_udphy *udphy = phy_get_drvdata(phy);
+- int ret;
++ int ret = 0;
+
+ mutex_lock(&udphy->mutex);
+ /* DP only or high-speed, disable U3 port */
diff --git a/target/linux/rockchip/patches-6.6/032-03-v6.10-phy-rockchip-fix-CONFIG_TYPEC-dependency.patch b/target/linux/rockchip/patches-6.6/032-03-v6.10-phy-rockchip-fix-CONFIG_TYPEC-dependency.patch
new file mode 100644
index 0000000000..a8b9aa15fc
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/032-03-v6.10-phy-rockchip-fix-CONFIG_TYPEC-dependency.patch
@@ -0,0 +1,43 @@
+From 9c79b779643e56d4253bd3ba6998c58c819943af Mon Sep 17 00:00:00 2001
+From: Arnd Bergmann <arnd@arndb.de>
+Date: Mon, 15 Apr 2024 19:42:25 +0200
+Subject: [PATCH] phy: rockchip: fix CONFIG_TYPEC dependency
+
+The newly added driver causes a warning about missing dependencies
+by selecting CONFIG_TYPEC unconditionally:
+
+WARNING: unmet direct dependencies detected for TYPEC
+ Depends on [n]: USB_SUPPORT [=n]
+ Selected by [y]:
+ - PHY_ROCKCHIP_USBDP [=y] && ARCH_ROCKCHIP [=y] && OF [=y]
+
+WARNING: unmet direct dependencies detected for USB_COMMON
+ Depends on [n]: USB_SUPPORT [=n]
+ Selected by [y]:
+ - EXTCON_RTK_TYPE_C [=y] && EXTCON [=y] && (ARCH_REALTEK [=y] || COMPILE_TEST [=y]) && TYPEC [=y]
+
+Since that is a user-visible option, it should not really be selected
+in the first place. Replace the 'select' with a 'depends on' as
+we have for similar drivers.
+
+Fixes: 2f70bbddeb45 ("phy: rockchip: add usbdp combo phy driver")
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Reviewed-by: Heiko Stuebner <heiko@sntech.de>
+Link: https://lore.kernel.org/r/20240415174241.77982-1-arnd@kernel.org
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+---
+ drivers/phy/rockchip/Kconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/phy/rockchip/Kconfig
++++ b/drivers/phy/rockchip/Kconfig
+@@ -111,8 +111,8 @@ config PHY_ROCKCHIP_USB
+ config PHY_ROCKCHIP_USBDP
+ tristate "Rockchip USBDP COMBO PHY Driver"
+ depends on ARCH_ROCKCHIP && OF
++ depends on TYPEC
+ select GENERIC_PHY
+- select TYPEC
+ help
+ Enable this to support the Rockchip USB3.0/DP combo PHY with
+ Samsung IP block. This is required for USB3 support on RK3588.
diff --git a/target/linux/rockchip/patches-6.6/032-04-v6.10-phy-rockchip-Fix-typo-in-function-names.patch b/target/linux/rockchip/patches-6.6/032-04-v6.10-phy-rockchip-Fix-typo-in-function-names.patch
new file mode 100644
index 0000000000..9495dd2b10
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/032-04-v6.10-phy-rockchip-Fix-typo-in-function-names.patch
@@ -0,0 +1,79 @@
+From 9b6bfad9070a95d19973be17177e5d9220cbbf1f Mon Sep 17 00:00:00 2001
+From: Rick Wertenbroek <rick.wertenbroek@gmail.com>
+Date: Thu, 7 Mar 2024 10:53:18 +0100
+Subject: [PATCH] phy: rockchip: Fix typo in function names
+
+Several functions had "rochchip" instead of "rockchip" in their name.
+Replace "rochchip" by "rockchip".
+
+Signed-off-By: Rick Wertenbroek <rick.wertenbroek@gmail.com>
+Reviewed-by: Heiko Stuebner <heiko@sntech.de>
+Link: https://lore.kernel.org/r/20240307095318.3651498-1-rick.wertenbroek@gmail.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+---
+ drivers/phy/rockchip/phy-rockchip-naneng-combphy.c | 4 ++--
+ drivers/phy/rockchip/phy-rockchip-snps-pcie3.c | 12 ++++++------
+ 2 files changed, 8 insertions(+), 8 deletions(-)
+
+--- a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
++++ b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
+@@ -248,7 +248,7 @@ static int rockchip_combphy_exit(struct
+ return 0;
+ }
+
+-static const struct phy_ops rochchip_combphy_ops = {
++static const struct phy_ops rockchip_combphy_ops = {
+ .init = rockchip_combphy_init,
+ .exit = rockchip_combphy_exit,
+ .owner = THIS_MODULE,
+@@ -364,7 +364,7 @@ static int rockchip_combphy_probe(struct
+ return ret;
+ }
+
+- priv->phy = devm_phy_create(dev, NULL, &rochchip_combphy_ops);
++ priv->phy = devm_phy_create(dev, NULL, &rockchip_combphy_ops);
+ if (IS_ERR(priv->phy)) {
+ dev_err(dev, "failed to create combphy\n");
+ return PTR_ERR(priv->phy);
+--- a/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c
++++ b/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c
+@@ -182,7 +182,7 @@ static const struct rockchip_p3phy_ops r
+ .phy_init = rockchip_p3phy_rk3588_init,
+ };
+
+-static int rochchip_p3phy_init(struct phy *phy)
++static int rockchip_p3phy_init(struct phy *phy)
+ {
+ struct rockchip_p3phy_priv *priv = phy_get_drvdata(phy);
+ int ret;
+@@ -205,7 +205,7 @@ static int rochchip_p3phy_init(struct ph
+ return ret;
+ }
+
+-static int rochchip_p3phy_exit(struct phy *phy)
++static int rockchip_p3phy_exit(struct phy *phy)
+ {
+ struct rockchip_p3phy_priv *priv = phy_get_drvdata(phy);
+
+@@ -214,9 +214,9 @@ static int rochchip_p3phy_exit(struct ph
+ return 0;
+ }
+
+-static const struct phy_ops rochchip_p3phy_ops = {
+- .init = rochchip_p3phy_init,
+- .exit = rochchip_p3phy_exit,
++static const struct phy_ops rockchip_p3phy_ops = {
++ .init = rockchip_p3phy_init,
++ .exit = rockchip_p3phy_exit,
+ .set_mode = rockchip_p3phy_set_mode,
+ .owner = THIS_MODULE,
+ };
+@@ -275,7 +275,7 @@ static int rockchip_p3phy_probe(struct p
+ return priv->num_lanes;
+ }
+
+- priv->phy = devm_phy_create(dev, NULL, &rochchip_p3phy_ops);
++ priv->phy = devm_phy_create(dev, NULL, &rockchip_p3phy_ops);
+ if (IS_ERR(priv->phy)) {
+ dev_err(dev, "failed to create combphy\n");
+ return PTR_ERR(priv->phy);
diff --git a/target/linux/rockchip/patches-6.6/032-05-v6.10-phy-rockchip-snps-pcie3-add-support-for.patch b/target/linux/rockchip/patches-6.6/032-05-v6.10-phy-rockchip-snps-pcie3-add-support-for.patch
new file mode 100644
index 0000000000..61c3e0e53c
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/032-05-v6.10-phy-rockchip-snps-pcie3-add-support-for.patch
@@ -0,0 +1,106 @@
+From a1fe1eca0d8be69ccc1f3d615e5a529df1c82e66 Mon Sep 17 00:00:00 2001
+From: Niklas Cassel <cassel@kernel.org>
+Date: Fri, 12 Apr 2024 14:58:16 +0200
+Subject: [PATCH] phy: rockchip-snps-pcie3: add support for
+ rockchip,rx-common-refclk-mode
+
+>From the RK3588 Technical Reference Manual, Part1,
+section 6.19 PCIe3PHY_GRF Register Description:
+"rxX_cmn_refclk_mode"
+RX common reference clock mode for lane X. This mode should be enabled
+only when the far-end and near-end devices are running with a common
+reference clock.
+
+The hardware reset value for this field is 0x1 (enabled).
+Note that this register field is only available on RK3588, not on RK3568.
+
+The link training either fails or is highly unstable (link state will jump
+continuously between L0 and recovery) when this mode is enabled while
+using an endpoint running in Separate Reference Clock with No SSC (SRNS)
+mode or Separate Reference Clock with SSC (SRIS) mode.
+(Which is usually the case when using a real SoC as endpoint, e.g. the
+RK3588 PCIe controller can run in both Root Complex and Endpoint mode.)
+
+Add support for the device tree property rockchip,rx-common-refclk-mode,
+such that the PCIe PHY can be used in configurations where the Root
+Complex and Endpoint are not using a common reference clock.
+
+Signed-off-by: Niklas Cassel <cassel@kernel.org>
+Link: https://lore.kernel.org/r/20240412125818.17052-3-cassel@kernel.org
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+---
+ .../phy/rockchip/phy-rockchip-snps-pcie3.c | 37 +++++++++++++++++++
+ 1 file changed, 37 insertions(+)
+
+--- a/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c
++++ b/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c
+@@ -35,11 +35,17 @@
+ #define RK3588_PCIE3PHY_GRF_CMN_CON0 0x0
+ #define RK3588_PCIE3PHY_GRF_PHY0_STATUS1 0x904
+ #define RK3588_PCIE3PHY_GRF_PHY1_STATUS1 0xa04
++#define RK3588_PCIE3PHY_GRF_PHY0_LN0_CON1 0x1004
++#define RK3588_PCIE3PHY_GRF_PHY0_LN1_CON1 0x1104
++#define RK3588_PCIE3PHY_GRF_PHY1_LN0_CON1 0x2004
++#define RK3588_PCIE3PHY_GRF_PHY1_LN1_CON1 0x2104
+ #define RK3588_SRAM_INIT_DONE(reg) (reg & BIT(0))
+
+ #define RK3588_BIFURCATION_LANE_0_1 BIT(0)
+ #define RK3588_BIFURCATION_LANE_2_3 BIT(1)
+ #define RK3588_LANE_AGGREGATION BIT(2)
++#define RK3588_RX_CMN_REFCLK_MODE_EN ((BIT(7) << 16) | BIT(7))
++#define RK3588_RX_CMN_REFCLK_MODE_DIS (BIT(7) << 16)
+ #define RK3588_PCIE1LN_SEL_EN (GENMASK(1, 0) << 16)
+ #define RK3588_PCIE30_PHY_MODE_EN (GENMASK(2, 0) << 16)
+
+@@ -60,6 +66,7 @@ struct rockchip_p3phy_priv {
+ int num_clks;
+ int num_lanes;
+ u32 lanes[4];
++ u32 rx_cmn_refclk_mode[4];
+ };
+
+ struct rockchip_p3phy_ops {
+@@ -137,6 +144,19 @@ static int rockchip_p3phy_rk3588_init(st
+ u8 mode = RK3588_LANE_AGGREGATION; /* default */
+ int ret;
+
++ regmap_write(priv->phy_grf, RK3588_PCIE3PHY_GRF_PHY0_LN0_CON1,
++ priv->rx_cmn_refclk_mode[0] ? RK3588_RX_CMN_REFCLK_MODE_EN :
++ RK3588_RX_CMN_REFCLK_MODE_DIS);
++ regmap_write(priv->phy_grf, RK3588_PCIE3PHY_GRF_PHY0_LN1_CON1,
++ priv->rx_cmn_refclk_mode[1] ? RK3588_RX_CMN_REFCLK_MODE_EN :
++ RK3588_RX_CMN_REFCLK_MODE_DIS);
++ regmap_write(priv->phy_grf, RK3588_PCIE3PHY_GRF_PHY1_LN0_CON1,
++ priv->rx_cmn_refclk_mode[2] ? RK3588_RX_CMN_REFCLK_MODE_EN :
++ RK3588_RX_CMN_REFCLK_MODE_DIS);
++ regmap_write(priv->phy_grf, RK3588_PCIE3PHY_GRF_PHY1_LN1_CON1,
++ priv->rx_cmn_refclk_mode[3] ? RK3588_RX_CMN_REFCLK_MODE_EN :
++ RK3588_RX_CMN_REFCLK_MODE_DIS);
++
+ /* Deassert PCIe PMA output clamp mode */
+ regmap_write(priv->phy_grf, RK3588_PCIE3PHY_GRF_CMN_CON0, BIT(8) | BIT(24));
+
+@@ -275,6 +295,23 @@ static int rockchip_p3phy_probe(struct p
+ return priv->num_lanes;
+ }
+
++ ret = of_property_read_variable_u32_array(dev->of_node,
++ "rockchip,rx-common-refclk-mode",
++ priv->rx_cmn_refclk_mode, 1,
++ ARRAY_SIZE(priv->rx_cmn_refclk_mode));
++ /*
++ * if no rockchip,rx-common-refclk-mode, assume enabled for all lanes in
++ * order to be DT backwards compatible. (Since HW reset val is enabled.)
++ */
++ if (ret == -EINVAL) {
++ for (int i = 0; i < ARRAY_SIZE(priv->rx_cmn_refclk_mode); i++)
++ priv->rx_cmn_refclk_mode[i] = 1;
++ } else if (ret < 0) {
++ dev_err(dev, "failed to read rockchip,rx-common-refclk-mode property %d\n",
++ ret);
++ return ret;
++ }
++
+ priv->phy = devm_phy_create(dev, NULL, &rockchip_p3phy_ops);
+ if (IS_ERR(priv->phy)) {
+ dev_err(dev, "failed to create combphy\n");
diff --git a/target/linux/rockchip/patches-6.6/034-v6.7-usb-dwc3-add-optional-PHY-interface-clocks.patch b/target/linux/rockchip/patches-6.6/034-v6.7-usb-dwc3-add-optional-PHY-interface-clocks.patch
new file mode 100644
index 0000000000..1b82072933
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/034-v6.7-usb-dwc3-add-optional-PHY-interface-clocks.patch
@@ -0,0 +1,91 @@
+From 97789b93b792fc97ad4476b79e0f38ffa8e7e0ee Mon Sep 17 00:00:00 2001
+From: Sebastian Reichel <sebastian.reichel@collabora.com>
+Date: Fri, 20 Oct 2023 16:11:41 +0200
+Subject: [PATCH] usb: dwc3: add optional PHY interface clocks
+
+On Rockchip RK3588 one of the DWC3 cores is integrated weirdly and
+requires two extra clocks to be enabled. Without these extra clocks
+hot-plugging USB devices is broken.
+
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Acked-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+Link: https://lore.kernel.org/r/20231020150022.48725-3-sebastian.reichel@collabora.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/dwc3/core.c | 28 ++++++++++++++++++++++++++++
+ drivers/usb/dwc3/core.h | 4 ++++
+ 2 files changed, 32 insertions(+)
+
+--- a/drivers/usb/dwc3/core.c
++++ b/drivers/usb/dwc3/core.c
+@@ -839,8 +839,20 @@ static int dwc3_clk_enable(struct dwc3 *
+ if (ret)
+ goto disable_ref_clk;
+
++ ret = clk_prepare_enable(dwc->utmi_clk);
++ if (ret)
++ goto disable_susp_clk;
++
++ ret = clk_prepare_enable(dwc->pipe_clk);
++ if (ret)
++ goto disable_utmi_clk;
++
+ return 0;
+
++disable_utmi_clk:
++ clk_disable_unprepare(dwc->utmi_clk);
++disable_susp_clk:
++ clk_disable_unprepare(dwc->susp_clk);
+ disable_ref_clk:
+ clk_disable_unprepare(dwc->ref_clk);
+ disable_bus_clk:
+@@ -850,6 +862,8 @@ disable_bus_clk:
+
+ static void dwc3_clk_disable(struct dwc3 *dwc)
+ {
++ clk_disable_unprepare(dwc->pipe_clk);
++ clk_disable_unprepare(dwc->utmi_clk);
+ clk_disable_unprepare(dwc->susp_clk);
+ clk_disable_unprepare(dwc->ref_clk);
+ clk_disable_unprepare(dwc->bus_clk);
+@@ -1863,6 +1877,20 @@ static int dwc3_get_clocks(struct dwc3 *
+ }
+ }
+
++ /* specific to Rockchip RK3588 */
++ dwc->utmi_clk = devm_clk_get_optional(dev, "utmi");
++ if (IS_ERR(dwc->utmi_clk)) {
++ return dev_err_probe(dev, PTR_ERR(dwc->utmi_clk),
++ "could not get utmi clock\n");
++ }
++
++ /* specific to Rockchip RK3588 */
++ dwc->pipe_clk = devm_clk_get_optional(dev, "pipe");
++ if (IS_ERR(dwc->pipe_clk)) {
++ return dev_err_probe(dev, PTR_ERR(dwc->pipe_clk),
++ "could not get pipe clock\n");
++ }
++
+ return 0;
+ }
+
+--- a/drivers/usb/dwc3/core.h
++++ b/drivers/usb/dwc3/core.h
+@@ -996,6 +996,8 @@ struct dwc3_scratchpad_array {
+ * @bus_clk: clock for accessing the registers
+ * @ref_clk: reference clock
+ * @susp_clk: clock used when the SS phy is in low power (S3) state
++ * @utmi_clk: clock used for USB2 PHY communication
++ * @pipe_clk: clock used for USB3 PHY communication
+ * @reset: reset control
+ * @regs: base address for our registers
+ * @regs_size: address space size
+@@ -1166,6 +1168,8 @@ struct dwc3 {
+ struct clk *bus_clk;
+ struct clk *ref_clk;
+ struct clk *susp_clk;
++ struct clk *utmi_clk;
++ struct clk *pipe_clk;
+
+ struct reset_control *reset;
+
diff --git a/target/linux/rockchip/patches-6.6/050-01-v6.8-arm64-dts-rockchip-Add-sfc-node-to-rk3588s.patch b/target/linux/rockchip/patches-6.6/050-01-v6.8-arm64-dts-rockchip-Add-sfc-node-to-rk3588s.patch
new file mode 100644
index 0000000000..fcbec5f63a
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/050-01-v6.8-arm64-dts-rockchip-Add-sfc-node-to-rk3588s.patch
@@ -0,0 +1,35 @@
+From 3eaf2abd11aa7f3b2fb04d60c64b2c756fe030eb Mon Sep 17 00:00:00 2001
+From: Muhammed Efe Cetin <efectn@6tel.net>
+Date: Mon, 9 Oct 2023 22:27:26 +0300
+Subject: [PATCH] arm64: dts: rockchip: Add sfc node to rk3588s
+
+Add SFC (SPI Flash) to RK3588S SOC.
+
+Reviewed-by: Dhruva Gole <d-gole@ti.com>
+Signed-off-by: Muhammed Efe Cetin <efectn@6tel.net>
+Link: https://lore.kernel.org/r/d36a64edfaede92ce2e158b0d9dc4f5998e019e3.1696878787.git.efectn@6tel.net
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
+@@ -1425,6 +1425,17 @@
+ };
+ };
+
++ sfc: spi@fe2b0000 {
++ compatible = "rockchip,sfc";
++ reg = <0x0 0xfe2b0000 0x0 0x4000>;
++ interrupts = <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru SCLK_SFC>, <&cru HCLK_SFC>;
++ clock-names = "clk_sfc", "hclk_sfc";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
+ sdmmc: mmc@fe2c0000 {
+ compatible = "rockchip,rk3588-dw-mshc", "rockchip,rk3288-dw-mshc";
+ reg = <0x0 0xfe2c0000 0x0 0x4000>;
diff --git a/target/linux/rockchip/patches-6.6/050-02-v6.8-arm64-dts-rockchip-Add-I2S2-M0-pin-definitions-to-rk3588s.patch b/target/linux/rockchip/patches-6.6/050-02-v6.8-arm64-dts-rockchip-Add-I2S2-M0-pin-definitions-to-rk3588s.patch
new file mode 100644
index 0000000000..25526ba23c
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/050-02-v6.8-arm64-dts-rockchip-Add-I2S2-M0-pin-definitions-to-rk3588s.patch
@@ -0,0 +1,58 @@
+From bf012368bb0ab69167d49715789fac34dfcd457e Mon Sep 17 00:00:00 2001
+From: Ondrej Jirman <megi@xff.cz>
+Date: Sun, 8 Oct 2023 15:04:59 +0200
+Subject: [PATCH] arm64: dts: rockchip: Add I2S2 M0 pin definitions to rk3588s
+
+This is used on Orange Pi 5 Plus.
+
+Signed-off-by: Ondrej Jirman <megi@xff.cz>
+Link: https://lore.kernel.org/r/20231008130515.1155664-2-megi@xff.cz
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ .../boot/dts/rockchip/rk3588s-pinctrl.dtsi | 35 +++++++++++++++++++
+ 1 file changed, 35 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588s-pinctrl.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588s-pinctrl.dtsi
+@@ -1350,6 +1350,41 @@
+
+ i2s2 {
+ /omit-if-no-ref/
++ i2s2m0_lrck: i2s2m0-lrck {
++ rockchip,pins =
++ /* i2s2m0_lrck */
++ <2 RK_PC0 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s2m0_mclk: i2s2m0-mclk {
++ rockchip,pins =
++ /* i2s2m0_mclk */
++ <2 RK_PB6 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s2m0_sclk: i2s2m0-sclk {
++ rockchip,pins =
++ /* i2s2m0_sclk */
++ <2 RK_PB7 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s2m0_sdi: i2s2m0-sdi {
++ rockchip,pins =
++ /* i2s2m0_sdi */
++ <2 RK_PC3 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s2m0_sdo: i2s2m0-sdo {
++ rockchip,pins =
++ /* i2s2m0_sdo */
++ <4 RK_PC3 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
+ i2s2m1_lrck: i2s2m1-lrck {
+ rockchip,pins =
+ /* i2s2m1_lrck */
diff --git a/target/linux/rockchip/patches-6.6/050-03-v6.8-arm64-dts-rockchip-Add-UART9-M0-pin-definitions-to-rk3588.patch b/target/linux/rockchip/patches-6.6/050-03-v6.8-arm64-dts-rockchip-Add-UART9-M0-pin-definitions-to-rk3588.patch
new file mode 100644
index 0000000000..4a9cb6ea39
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/050-03-v6.8-arm64-dts-rockchip-Add-UART9-M0-pin-definitions-to-rk3588.patch
@@ -0,0 +1,32 @@
+From 3d77a3e51b0faed820a8db985dce5af1cc4eae32 Mon Sep 17 00:00:00 2001
+From: Ondrej Jirman <megi@xff.cz>
+Date: Sun, 8 Oct 2023 15:05:00 +0200
+Subject: [PATCH] arm64: dts: rockchip: Add UART9 M0 pin definitions to rk3588s
+
+This is used on Orange Pi 5 Plus.
+
+Signed-off-by: Ondrej Jirman <megi@xff.cz>
+Link: https://lore.kernel.org/r/20231008130515.1155664-3-megi@xff.cz
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588s-pinctrl.dtsi | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588s-pinctrl.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588s-pinctrl.dtsi
+@@ -3343,6 +3343,15 @@
+
+ uart9 {
+ /omit-if-no-ref/
++ uart9m0_xfer: uart9m0-xfer {
++ rockchip,pins =
++ /* uart9_rx_m0 */
++ <2 RK_PC4 10 &pcfg_pull_up>,
++ /* uart9_tx_m0 */
++ <2 RK_PC2 10 &pcfg_pull_up>;
++ };
++
++ /omit-if-no-ref/
+ uart9m1_xfer: uart9m1-xfer {
+ rockchip,pins =
+ /* uart9_rx_m1 */
diff --git a/target/linux/rockchip/patches-6.6/050-04-v6.8-arm64-dts-rockchip-Add-AV1-decoder-node-to-rk3588s.patch b/target/linux/rockchip/patches-6.6/050-04-v6.8-arm64-dts-rockchip-Add-AV1-decoder-node-to-rk3588s.patch
new file mode 100644
index 0000000000..6fce4f0f4c
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/050-04-v6.8-arm64-dts-rockchip-Add-AV1-decoder-node-to-rk3588s.patch
@@ -0,0 +1,37 @@
+From dd6dc0c4c1265129c229e26917bf4de1d97ff91f Mon Sep 17 00:00:00 2001
+From: Benjamin Gaignard <benjamin.gaignard@collabora.com>
+Date: Fri, 6 Oct 2023 08:53:34 +0200
+Subject: [PATCH] arm64: dts: rockchip: Add AV1 decoder node to rk3588s
+
+Add node for AV1 video decoder.
+
+Signed-off-by: Benjamin Gaignard <benjamin.gaignard@collabora.com>
+Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20231006065334.8117-1-benjamin.gaignard@collabora.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
+@@ -2314,6 +2314,19 @@
+ #interrupt-cells = <2>;
+ };
+ };
++
++ av1d: video-codec@fdc70000 {
++ compatible = "rockchip,rk3588-av1-vpu";
++ reg = <0x0 0xfdc70000 0x0 0x800>;
++ interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH 0>;
++ interrupt-names = "vdpu";
++ assigned-clocks = <&cru ACLK_AV1>, <&cru PCLK_AV1>;
++ assigned-clock-rates = <400000000>, <400000000>;
++ clocks = <&cru ACLK_AV1>, <&cru PCLK_AV1>;
++ clock-names = "aclk", "hclk";
++ power-domains = <&power RK3588_PD_AV1>;
++ resets = <&cru SRST_A_AV1>, <&cru SRST_P_AV1>, <&cru SRST_A_AV1_BIU>, <&cru SRST_P_AV1_BIU>;
++ };
+ };
+
+ #include "rk3588s-pinctrl.dtsi"
diff --git a/target/linux/rockchip/patches-6.6/050-05-v6.8-arm64-dts-rockchip-Add-DFI-to-rk3588s.patch b/target/linux/rockchip/patches-6.6/050-05-v6.8-arm64-dts-rockchip-Add-DFI-to-rk3588s.patch
new file mode 100644
index 0000000000..714dc4883b
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/050-05-v6.8-arm64-dts-rockchip-Add-DFI-to-rk3588s.patch
@@ -0,0 +1,50 @@
+From 5a6976b1040a2f99ab84eddbfa7cd072ac5d10fc Mon Sep 17 00:00:00 2001
+From: Sascha Hauer <s.hauer@pengutronix.de>
+Date: Wed, 18 Oct 2023 08:17:14 +0200
+Subject: [PATCH] arm64: dts: rockchip: Add DFI to rk3588s
+
+The DFI unit can be used to measure DRAM utilization using perf. Add the
+node to the device tree. The DFI needs a rockchip,pmu phandle to the pmu
+containing registers for SDRAM configuration details. This is added in
+this patch as well.
+
+Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
+Link: https://lore.kernel.org/r/20231018061714.3553817-27-s.hauer@pengutronix.de
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
+@@ -443,6 +443,11 @@
+ status = "disabled";
+ };
+
++ pmu1grf: syscon@fd58a000 {
++ compatible = "rockchip,rk3588-pmugrf", "syscon", "simple-mfd";
++ reg = <0x0 0xfd58a000 0x0 0x10000>;
++ };
++
+ sys_grf: syscon@fd58c000 {
+ compatible = "rockchip,rk3588-sys-grf", "syscon";
+ reg = <0x0 0xfd58c000 0x0 0x1000>;
+@@ -1330,6 +1335,17 @@
+ };
+ };
+
++ dfi: dfi@fe060000 {
++ reg = <0x00 0xfe060000 0x00 0x10000>;
++ compatible = "rockchip,rk3588-dfi";
++ interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH 0>;
++ interrupt-names = "ch0", "ch1", "ch2", "ch3";
++ rockchip,pmu = <&pmu1grf>;
++ };
++
+ gmac1: ethernet@fe1c0000 {
+ compatible = "rockchip,rk3588-gmac", "snps,dwmac-4.20a";
+ reg = <0x0 0xfe1c0000 0x0 0x10000>;
diff --git a/target/linux/rockchip/patches-6.6/050-06-v6.8-arm64-dts-rockchip-rk3588s-Add-USB3-host-controller.patch b/target/linux/rockchip/patches-6.6/050-06-v6.8-arm64-dts-rockchip-rk3588s-Add-USB3-host-controller.patch
new file mode 100644
index 0000000000..f4e835a9f5
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/050-06-v6.8-arm64-dts-rockchip-rk3588s-Add-USB3-host-controller.patch
@@ -0,0 +1,48 @@
+From bbd3778da16b3d448832b843f80bcde1aff26290 Mon Sep 17 00:00:00 2001
+From: Sebastian Reichel <sebastian.reichel@collabora.com>
+Date: Fri, 20 Oct 2023 16:11:42 +0200
+Subject: [PATCH] arm64: dts: rockchip: rk3588s: Add USB3 host controller
+
+RK3588 has three USB3 controllers. This adds the host-only controller,
+which is using the naneng-combphy shared with PCIe and SATA.
+
+The other two are dual-role and using a different PHY that is not yet
+supported upstream.
+
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20231020150022.48725-4-sebastian.reichel@collabora.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 21 +++++++++++++++++++++
+ 1 file changed, 21 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
+@@ -443,6 +443,27 @@
+ status = "disabled";
+ };
+
++ usb_host2_xhci: usb@fcd00000 {
++ compatible = "rockchip,rk3588-dwc3", "snps,dwc3";
++ reg = <0x0 0xfcd00000 0x0 0x400000>;
++ interrupts = <GIC_SPI 222 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru REF_CLK_USB3OTG2>, <&cru SUSPEND_CLK_USB3OTG2>,
++ <&cru ACLK_USB3OTG2>, <&cru CLK_UTMI_OTG2>,
++ <&cru CLK_PIPEPHY2_PIPE_U3_G>;
++ clock-names = "ref_clk", "suspend_clk", "bus_clk", "utmi", "pipe";
++ dr_mode = "host";
++ phys = <&combphy2_psu PHY_TYPE_USB3>;
++ phy-names = "usb3-phy";
++ phy_type = "utmi_wide";
++ resets = <&cru SRST_A_USB3OTG2>;
++ snps,dis_enblslpm_quirk;
++ snps,dis-u2-freeclk-exists-quirk;
++ snps,dis-del-phy-power-chg-quirk;
++ snps,dis-tx-ipgap-linecheck-quirk;
++ snps,dis_rxdet_inp3_quirk;
++ status = "disabled";
++ };
++
+ pmu1grf: syscon@fd58a000 {
+ compatible = "rockchip,rk3588-pmugrf", "syscon", "simple-mfd";
+ reg = <0x0 0xfd58a000 0x0 0x10000>;
diff --git a/target/linux/rockchip/patches-6.6/050-07-v6.7-arm64-dts-rockchip-drop-interrupt-names-property-from.patch b/target/linux/rockchip/patches-6.6/050-07-v6.7-arm64-dts-rockchip-drop-interrupt-names-property-from.patch
new file mode 100644
index 0000000000..9076ca2d13
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/050-07-v6.7-arm64-dts-rockchip-drop-interrupt-names-property-from.patch
@@ -0,0 +1,27 @@
+From 815f986f33eeb06652d59d8a4d405d4fdb4e59a8 Mon Sep 17 00:00:00 2001
+From: Heiko Stuebner <heiko.stuebner@cherry.de>
+Date: Fri, 1 Dec 2023 14:48:59 +0100
+Subject: [PATCH] arm64: dts: rockchip: drop interrupt-names property from
+ rk3588s dfi
+
+The dfi binding does not specify interrupt names, with the interrupts
+just specifying channels 0-x. So drop the unspecified property.
+
+Fixes: 5a6976b1040a ("arm64: dts: rockchip: Add DFI to rk3588s")
+Reported-by: Jagan Teki <jagan@edgeble.ai>
+Signed-off-by: Heiko Stuebner <heiko.stuebner@cherry.de>
+Link: https://lore.kernel.org/r/20231201134859.322491-1-heiko@sntech.de
+---
+ arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
+@@ -1363,7 +1363,6 @@
+ <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH 0>;
+- interrupt-names = "ch0", "ch1", "ch2", "ch3";
+ rockchip,pmu = <&pmu1grf>;
+ };
+
diff --git a/target/linux/rockchip/patches-6.6/050-08-v6.8-arm64-dts-rockchip-move-rk3588-serial-aliases-to-soc-dtsi.patch b/target/linux/rockchip/patches-6.6/050-08-v6.8-arm64-dts-rockchip-move-rk3588-serial-aliases-to-soc-dtsi.patch
new file mode 100644
index 0000000000..60c2b269b5
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/050-08-v6.8-arm64-dts-rockchip-move-rk3588-serial-aliases-to-soc-dtsi.patch
@@ -0,0 +1,139 @@
+From 9918d10d16665527e59fdb87c5acac70cc1cfe8f Mon Sep 17 00:00:00 2001
+From: Heiko Stuebner <heiko.stuebner@cherry.de>
+Date: Tue, 5 Dec 2023 17:48:39 +0100
+Subject: [PATCH] arm64: dts: rockchip: move rk3588 serial aliases to soc dtsi
+
+The serial ports on rk3588 are named uart0 - uart9. Board schematics
+also use these exact numbers and we want those names to also reflect
+in the OS devices because everything else would just cause confusion.
+
+To prevent each board repeating their list of serial aliases, move them
+to the soc dtsi, as all previous Rockchip soc do already.
+
+Signed-off-by: Heiko Stuebner <heiko.stuebner@cherry.de>
+Reviewed-by: Dragan Simic <dsimic@manjaro.org>
+Link: https://lore.kernel.org/r/20231205164842.556684-2-heiko@sntech.de
+---
+ .../boot/dts/rockchip/rk3588-edgeble-neu6a-io.dts | 4 ----
+ .../boot/dts/rockchip/rk3588-edgeble-neu6b-io.dts | 4 ----
+ arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts | 1 -
+ arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dts | 1 -
+ .../boot/dts/rockchip/rk3588-orangepi-5-plus.dts | 1 -
+ arch/arm64/boot/dts/rockchip/rk3588-quartzpro64.dts | 1 -
+ arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts | 1 -
+ arch/arm64/boot/dts/rockchip/rk3588-turing-rk1.dtsi | 2 --
+ .../boot/dts/rockchip/rk3588s-indiedroid-nova.dts | 1 -
+ .../boot/dts/rockchip/rk3588s-khadas-edge2.dts | 1 -
+ arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dts | 1 -
+ arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts | 1 -
+ arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 13 +++++++++++++
+ 13 files changed, 13 insertions(+), 19 deletions(-)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6a-io.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6a-io.dts
+@@ -12,10 +12,6 @@
+ compatible = "edgeble,neural-compute-module-6a-io",
+ "edgeble,neural-compute-module-6a", "rockchip,rk3588";
+
+- aliases {
+- serial2 = &uart2;
+- };
+-
+ chosen {
+ stdout-path = "serial2:1500000n8";
+ };
+--- a/arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6b-io.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6b-io.dts
+@@ -12,10 +12,6 @@
+ compatible = "edgeble,neural-compute-module-6b-io",
+ "edgeble,neural-compute-module-6b", "rockchip,rk3588";
+
+- aliases {
+- serial2 = &uart2;
+- };
+-
+ chosen {
+ stdout-path = "serial2:1500000n8";
+ };
+--- a/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts
+@@ -16,7 +16,6 @@
+
+ aliases {
+ mmc0 = &sdhci;
+- serial2 = &uart2;
+ };
+
+ chosen {
+--- a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dts
+@@ -19,7 +19,6 @@
+ aliases {
+ mmc0 = &sdhci;
+ mmc1 = &sdmmc;
+- serial2 = &uart2;
+ };
+
+ chosen {
+--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
+@@ -12,7 +12,6 @@
+ aliases {
+ mmc0 = &sdhci;
+ mmc1 = &sdmmc;
+- serial2 = &uart2;
+ };
+
+ chosen {
+--- a/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
+@@ -15,7 +15,6 @@
+ mmc0 = &sdhci;
+ mmc1 = &sdmmc;
+ mmc2 = &sdio;
+- serial2 = &uart2;
+ };
+
+ chosen {
+--- a/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts
+@@ -12,7 +12,6 @@
+
+ aliases {
+ mmc0 = &sdhci;
+- serial2 = &uart2;
+ };
+
+ chosen {
+--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
+@@ -14,7 +14,6 @@
+ aliases {
+ mmc0 = &sdhci;
+ mmc1 = &sdmmc;
+- serial2 = &uart2;
+ };
+
+ analog-sound {
+--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
+@@ -18,6 +18,19 @@
+ #address-cells = <2>;
+ #size-cells = <2>;
+
++ aliases {
++ serial0 = &uart0;
++ serial1 = &uart1;
++ serial2 = &uart2;
++ serial3 = &uart3;
++ serial4 = &uart4;
++ serial5 = &uart5;
++ serial6 = &uart6;
++ serial7 = &uart7;
++ serial8 = &uart8;
++ serial9 = &uart9;
++ };
++
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
diff --git a/target/linux/rockchip/patches-6.6/050-09-v6.8-arm64-dts-rockchip-add-rk3588-i2c-aliases-to-soc-dtsi.patch b/target/linux/rockchip/patches-6.6/050-09-v6.8-arm64-dts-rockchip-add-rk3588-i2c-aliases-to-soc-dtsi.patch
new file mode 100644
index 0000000000..2daaec3953
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/050-09-v6.8-arm64-dts-rockchip-add-rk3588-i2c-aliases-to-soc-dtsi.patch
@@ -0,0 +1,38 @@
+From 328e901b7b03d292c1520ffb38e9164feef4f1ea Mon Sep 17 00:00:00 2001
+From: Heiko Stuebner <heiko.stuebner@cherry.de>
+Date: Tue, 5 Dec 2023 17:48:40 +0100
+Subject: [PATCH] arm64: dts: rockchip: add rk3588 i2c aliases to soc dtsi
+
+The i2c controllers on rk3588 are named i2c0 - i2c8. Board schematics
+also use these exact numbers and we want those names to also reflect
+in the OS devices because everything else would just cause confusion.
+Userspace i2c access is a thing afterall.
+
+To prevent each board repeating their list of i2c aliases, define them
+in the soc dtsi, as all previous Rockchip soc do already.
+
+Signed-off-by: Heiko Stuebner <heiko.stuebner@cherry.de>
+Reviewed-by: Dragan Simic <dsimic@manjaro.org>
+Link: https://lore.kernel.org/r/20231205164842.556684-3-heiko@sntech.de
+---
+ arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
+@@ -19,6 +19,15 @@
+ #size-cells = <2>;
+
+ aliases {
++ i2c0 = &i2c0;
++ i2c1 = &i2c1;
++ i2c2 = &i2c2;
++ i2c3 = &i2c3;
++ i2c4 = &i2c4;
++ i2c5 = &i2c5;
++ i2c6 = &i2c6;
++ i2c7 = &i2c7;
++ i2c8 = &i2c8;
+ serial0 = &uart0;
+ serial1 = &uart1;
+ serial2 = &uart2;
diff --git a/target/linux/rockchip/patches-6.6/050-10-v6.8-arm64-dts-rockchip-add-rk3588-gpio-aliases-to-soc-dtsi.patch b/target/linux/rockchip/patches-6.6/050-10-v6.8-arm64-dts-rockchip-add-rk3588-gpio-aliases-to-soc-dtsi.patch
new file mode 100644
index 0000000000..19e6c6a4f5
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/050-10-v6.8-arm64-dts-rockchip-add-rk3588-gpio-aliases-to-soc-dtsi.patch
@@ -0,0 +1,34 @@
+From a024abedbca99a20aeb96f5beec9ded13c85dcb3 Mon Sep 17 00:00:00 2001
+From: Heiko Stuebner <heiko.stuebner@cherry.de>
+Date: Tue, 5 Dec 2023 17:48:41 +0100
+Subject: [PATCH] arm64: dts: rockchip: add rk3588 gpio aliases to soc dtsi
+
+The gpio controllers on rk3588 are named gpio0 - gpio4. Board schematics
+also use these exact numbers and we want those names to also reflect
+in the OS devices because everything else would just cause confusion.
+Userspace gpio access is a thing afterall.
+
+To prevent each board repeating their list of gpio aliases, define them
+in the soc dtsi, as previous Rockchip soc like the rk356x do already.
+
+Signed-off-by: Heiko Stuebner <heiko.stuebner@cherry.de>
+Reviewed-by: Dragan Simic <dsimic@manjaro.org>
+Link: https://lore.kernel.org/r/20231205164842.556684-4-heiko@sntech.de
+---
+ arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
+@@ -19,6 +19,11 @@
+ #size-cells = <2>;
+
+ aliases {
++ gpio0 = &gpio0;
++ gpio1 = &gpio1;
++ gpio2 = &gpio2;
++ gpio3 = &gpio3;
++ gpio4 = &gpio4;
+ i2c0 = &i2c0;
+ i2c1 = &i2c1;
+ i2c2 = &i2c2;
diff --git a/target/linux/rockchip/patches-6.6/050-11-v6.8-arm64-dts-rockchip-add-rk3588-spi-aliases-to-soc-dtsi.patch b/target/linux/rockchip/patches-6.6/050-11-v6.8-arm64-dts-rockchip-add-rk3588-spi-aliases-to-soc-dtsi.patch
new file mode 100644
index 0000000000..6a66d99668
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/050-11-v6.8-arm64-dts-rockchip-add-rk3588-spi-aliases-to-soc-dtsi.patch
@@ -0,0 +1,34 @@
+From a86e88043de929da76f7f6cf0990ba92aed8391a Mon Sep 17 00:00:00 2001
+From: Heiko Stuebner <heiko.stuebner@cherry.de>
+Date: Tue, 5 Dec 2023 17:48:42 +0100
+Subject: [PATCH] arm64: dts: rockchip: add rk3588 spi aliases to soc dtsi
+
+The spi controllers on rk3588 are named spi0 - spi4. Board schematics
+also use these exact numbers and we want those names to also reflect
+in the OS devices because everything else would just cause confusion.
+Userspace spi access is a thing afterall.
+
+To prevent each board repeating their list of spi aliases, define them
+in the soc dtsi, as previous Rockchip soc like the rk356x do already.
+
+Signed-off-by: Heiko Stuebner <heiko.stuebner@cherry.de>
+Reviewed-by: Dragan Simic <dsimic@manjaro.org>
+Link: https://lore.kernel.org/r/20231205164842.556684-5-heiko@sntech.de
+---
+ arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
+@@ -43,6 +43,11 @@
+ serial7 = &uart7;
+ serial8 = &uart8;
+ serial9 = &uart9;
++ spi0 = &spi0;
++ spi1 = &spi1;
++ spi2 = &spi2;
++ spi3 = &spi3;
++ spi4 = &spi4;
+ };
+
+ cpus {
diff --git a/target/linux/rockchip/patches-6.6/050-12-v6.8-arm64-dts-rockchip-Add-vop-on-rk3588.patch b/target/linux/rockchip/patches-6.6/050-12-v6.8-arm64-dts-rockchip-Add-vop-on-rk3588.patch
new file mode 100644
index 0000000000..3936df7a73
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/050-12-v6.8-arm64-dts-rockchip-Add-vop-on-rk3588.patch
@@ -0,0 +1,120 @@
+From d895dbef3f3a31ab50491bb48552e798cf555987 Mon Sep 17 00:00:00 2001
+From: Andy Yan <andy.yan@rock-chips.com>
+Date: Mon, 11 Dec 2023 20:00:04 +0800
+Subject: [PATCH] arm64: dts: rockchip: Add vop on rk3588
+
+Add vop dt node for rk3588.
+
+Signed-off-by: Andy Yan <andy.yan@rock-chips.com>
+Link: https://lore.kernel.org/r/20231211120004.1785616-1-andyshrk@163.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 83 +++++++++++++++++++++++
+ 1 file changed, 83 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
+@@ -394,6 +394,11 @@
+ #clock-cells = <0>;
+ };
+
++ display_subsystem: display-subsystem {
++ compatible = "rockchip,display-subsystem";
++ ports = <&vop_out>;
++ };
++
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_HIGH 0>,
+@@ -506,6 +511,16 @@
+ reg = <0x0 0xfd58c000 0x0 0x1000>;
+ };
+
++ vop_grf: syscon@fd5a4000 {
++ compatible = "rockchip,rk3588-vop-grf", "syscon";
++ reg = <0x0 0xfd5a4000 0x0 0x2000>;
++ };
++
++ vo1_grf: syscon@fd5a8000 {
++ compatible = "rockchip,rk3588-vo-grf", "syscon";
++ reg = <0x0 0xfd5a8000 0x0 0x100>;
++ };
++
+ php_grf: syscon@fd5b0000 {
+ compatible = "rockchip,rk3588-php-grf", "syscon";
+ reg = <0x0 0xfd5b0000 0x0 0x1000>;
+@@ -625,6 +640,74 @@
+ status = "disabled";
+ };
+
++ vop: vop@fdd90000 {
++ compatible = "rockchip,rk3588-vop";
++ reg = <0x0 0xfdd90000 0x0 0x4200>, <0x0 0xfdd95000 0x0 0x1000>;
++ reg-names = "vop", "gamma-lut";
++ interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru ACLK_VOP>,
++ <&cru HCLK_VOP>,
++ <&cru DCLK_VOP0>,
++ <&cru DCLK_VOP1>,
++ <&cru DCLK_VOP2>,
++ <&cru DCLK_VOP3>,
++ <&cru PCLK_VOP_ROOT>;
++ clock-names = "aclk",
++ "hclk",
++ "dclk_vp0",
++ "dclk_vp1",
++ "dclk_vp2",
++ "dclk_vp3",
++ "pclk_vop";
++ iommus = <&vop_mmu>;
++ power-domains = <&power RK3588_PD_VOP>;
++ rockchip,grf = <&sys_grf>;
++ rockchip,vop-grf = <&vop_grf>;
++ rockchip,vo1-grf = <&vo1_grf>;
++ rockchip,pmu = <&pmu>;
++ status = "disabled";
++
++ vop_out: ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ vp0: port@0 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0>;
++ };
++
++ vp1: port@1 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <1>;
++ };
++
++ vp2: port@2 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <2>;
++ };
++
++ vp3: port@3 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <3>;
++ };
++ };
++ };
++
++ vop_mmu: iommu@fdd97e00 {
++ compatible = "rockchip,rk3588-iommu", "rockchip,rk3568-iommu";
++ reg = <0x0 0xfdd97e00 0x0 0x100>, <0x0 0xfdd97f00 0x0 0x100>;
++ interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru ACLK_VOP>, <&cru HCLK_VOP>;
++ clock-names = "aclk", "iface";
++ #iommu-cells = <0>;
++ power-domains = <&power RK3588_PD_VOP>;
++ status = "disabled";
++ };
++
+ uart0: serial@fd890000 {
+ compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
+ reg = <0x0 0xfd890000 0x0 0x100>;
diff --git a/target/linux/rockchip/patches-6.6/050-13-v6.9-arm64-dts-rockchip-Add-HDMI0-PHY-to-rk3588.patch b/target/linux/rockchip/patches-6.6/050-13-v6.9-arm64-dts-rockchip-Add-HDMI0-PHY-to-rk3588.patch
new file mode 100644
index 0000000000..d9bd3ab019
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/050-13-v6.9-arm64-dts-rockchip-Add-HDMI0-PHY-to-rk3588.patch
@@ -0,0 +1,51 @@
+From 11d28971aaaf5de6f50790fb21f1113fee21d320 Mon Sep 17 00:00:00 2001
+From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
+Date: Mon, 19 Feb 2024 22:46:25 +0200
+Subject: [PATCH] arm64: dts: rockchip: Add HDMI0 PHY to rk3588
+
+Add DT nodes for HDMI0 PHY and related syscon found on RK3588 SoC.
+
+Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
+Link: https://lore.kernel.org/r/20240219204626.284399-1-cristian.ciocaltea@collabora.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 21 +++++++++++++++++++++
+ 1 file changed, 21 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
+@@ -586,6 +586,11 @@
+ };
+ };
+
++ hdptxphy0_grf: syscon@fd5e0000 {
++ compatible = "rockchip,rk3588-hdptxphy-grf", "syscon";
++ reg = <0x0 0xfd5e0000 0x0 0x100>;
++ };
++
+ ioc: syscon@fd5f0000 {
+ compatible = "rockchip,rk3588-ioc", "syscon";
+ reg = <0x0 0xfd5f0000 0x0 0x10000>;
+@@ -2358,6 +2363,22 @@
+ #dma-cells = <1>;
+ };
+
++ hdptxphy_hdmi0: phy@fed60000 {
++ compatible = "rockchip,rk3588-hdptx-phy";
++ reg = <0x0 0xfed60000 0x0 0x2000>;
++ clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>, <&cru PCLK_HDPTX0>;
++ clock-names = "ref", "apb";
++ #phy-cells = <0>;
++ resets = <&cru SRST_HDPTX0>, <&cru SRST_P_HDPTX0>,
++ <&cru SRST_HDPTX0_INIT>, <&cru SRST_HDPTX0_CMN>,
++ <&cru SRST_HDPTX0_LANE>, <&cru SRST_HDPTX0_ROPLL>,
++ <&cru SRST_HDPTX0_LCPLL>;
++ reset-names = "phy", "apb", "init", "cmn", "lane", "ropll",
++ "lcpll";
++ rockchip,grf = <&hdptxphy0_grf>;
++ status = "disabled";
++ };
++
+ combphy0_ps: phy@fee00000 {
+ compatible = "rockchip,rk3588-naneng-combphy";
+ reg = <0x0 0xfee00000 0x0 0x100>;
diff --git a/target/linux/rockchip/patches-6.6/050-14-v6.9-arm64-dts-rockchip-add-clock-to-vo1-grf-syscon-on-rk3588.patch b/target/linux/rockchip/patches-6.6/050-14-v6.9-arm64-dts-rockchip-add-clock-to-vo1-grf-syscon-on-rk3588.patch
new file mode 100644
index 0000000000..6ffc2c751a
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/050-14-v6.9-arm64-dts-rockchip-add-clock-to-vo1-grf-syscon-on-rk3588.patch
@@ -0,0 +1,25 @@
+From 2047366b9eff8fada2a118588b0478de6e92d02c Mon Sep 17 00:00:00 2001
+From: Heiko Stuebner <heiko@sntech.de>
+Date: Tue, 27 Feb 2024 22:05:21 +0100
+Subject: [PATCH] arm64: dts: rockchip: add clock to vo1-grf syscon on rk3588
+
+The VO*-general-register-files need a clock, so add the correct one.
+
+Cc: Sebastian Reichel <sebastian.reichel@collabora.com>
+Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Link: https://lore.kernel.org/r/20240227210521.724754-1-heiko@sntech.de
+---
+ arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
+@@ -519,6 +519,7 @@
+ vo1_grf: syscon@fd5a8000 {
+ compatible = "rockchip,rk3588-vo-grf", "syscon";
+ reg = <0x0 0xfd5a8000 0x0 0x100>;
++ clocks = <&cru PCLK_VO1GRF>;
+ };
+
+ php_grf: syscon@fd5b0000 {
diff --git a/target/linux/rockchip/patches-6.6/050-15-v6.10-arm64-dts-rockchip-Add-rk3588-GPU-node.patch b/target/linux/rockchip/patches-6.6/050-15-v6.10-arm64-dts-rockchip-Add-rk3588-GPU-node.patch
new file mode 100644
index 0000000000..dafdd69d68
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/050-15-v6.10-arm64-dts-rockchip-Add-rk3588-GPU-node.patch
@@ -0,0 +1,81 @@
+From 6fca4edb93d335f29f81e484936f38a5eed6a9b1 Mon Sep 17 00:00:00 2001
+From: Boris Brezillon <boris.brezillon@collabora.com>
+Date: Tue, 26 Mar 2024 17:52:06 +0100
+Subject: [PATCH] arm64: dts: rockchip: Add rk3588 GPU node
+
+Add Mali GPU Node to the RK3588 SoC DT including GPU clock
+operating points
+
+Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20240326165232.73585-3-sebastian.reichel@collabora.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 56 +++++++++++++++++++++++
+ 1 file changed, 56 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
+@@ -501,6 +501,62 @@
+ status = "disabled";
+ };
+
++ gpu: gpu@fb000000 {
++ compatible = "rockchip,rk3588-mali", "arm,mali-valhall-csf";
++ reg = <0x0 0xfb000000 0x0 0x200000>;
++ #cooling-cells = <2>;
++ assigned-clocks = <&scmi_clk SCMI_CLK_GPU>;
++ assigned-clock-rates = <200000000>;
++ clocks = <&cru CLK_GPU>, <&cru CLK_GPU_COREGROUP>,
++ <&cru CLK_GPU_STACKS>;
++ clock-names = "core", "coregroup", "stacks";
++ dynamic-power-coefficient = <2982>;
++ interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH 0>;
++ interrupt-names = "job", "mmu", "gpu";
++ operating-points-v2 = <&gpu_opp_table>;
++ power-domains = <&power RK3588_PD_GPU>;
++ status = "disabled";
++
++ gpu_opp_table: opp-table {
++ compatible = "operating-points-v2";
++
++ opp-300000000 {
++ opp-hz = /bits/ 64 <300000000>;
++ opp-microvolt = <675000 675000 850000>;
++ };
++ opp-400000000 {
++ opp-hz = /bits/ 64 <400000000>;
++ opp-microvolt = <675000 675000 850000>;
++ };
++ opp-500000000 {
++ opp-hz = /bits/ 64 <500000000>;
++ opp-microvolt = <675000 675000 850000>;
++ };
++ opp-600000000 {
++ opp-hz = /bits/ 64 <600000000>;
++ opp-microvolt = <675000 675000 850000>;
++ };
++ opp-700000000 {
++ opp-hz = /bits/ 64 <700000000>;
++ opp-microvolt = <700000 700000 850000>;
++ };
++ opp-800000000 {
++ opp-hz = /bits/ 64 <800000000>;
++ opp-microvolt = <750000 750000 850000>;
++ };
++ opp-900000000 {
++ opp-hz = /bits/ 64 <900000000>;
++ opp-microvolt = <800000 800000 850000>;
++ };
++ opp-1000000000 {
++ opp-hz = /bits/ 64 <1000000000>;
++ opp-microvolt = <850000 850000 850000>;
++ };
++ };
++ };
++
+ pmu1grf: syscon@fd58a000 {
+ compatible = "rockchip,rk3588-pmugrf", "syscon", "simple-mfd";
+ reg = <0x0 0xfd58a000 0x0 0x10000>;
diff --git a/target/linux/rockchip/patches-6.6/050-16-v6.10-arm64-dts-rockchip-Fix-ordering-of-nodes-on-rk3588s.patch b/target/linux/rockchip/patches-6.6/050-16-v6.10-arm64-dts-rockchip-Fix-ordering-of-nodes-on-rk3588s.patch
new file mode 100644
index 0000000000..7b69e0a195
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/050-16-v6.10-arm64-dts-rockchip-Fix-ordering-of-nodes-on-rk3588s.patch
@@ -0,0 +1,384 @@
+From cbb97fe18e299ece1c0074924c630de6a19b320f Mon Sep 17 00:00:00 2001
+From: Diederik de Haas <didi.debian@cknow.org>
+Date: Sat, 6 Apr 2024 19:28:04 +0200
+Subject: [PATCH] arm64: dts: rockchip: Fix ordering of nodes on rk3588s
+
+Fix the ordering of the main nodes by sorting them alphabetically and
+then the ones with a memory address sequentially by that address.
+
+Signed-off-by: Diederik de Haas <didi.debian@cknow.org>
+Link: https://lore.kernel.org/r/20240406172821.34173-1-didi.debian@cknow.org
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 304 +++++++++++-----------
+ 1 file changed, 152 insertions(+), 152 deletions(-)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
+@@ -347,6 +347,11 @@
+ };
+ };
+
++ display_subsystem: display-subsystem {
++ compatible = "rockchip,display-subsystem";
++ ports = <&vop_out>;
++ };
++
+ firmware {
+ optee: optee {
+ compatible = "linaro,optee-tz";
+@@ -394,11 +399,6 @@
+ #clock-cells = <0>;
+ };
+
+- display_subsystem: display-subsystem {
+- compatible = "rockchip,display-subsystem";
+- ports = <&vop_out>;
+- };
+-
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_HIGH 0>,
+@@ -436,6 +436,62 @@
+ };
+ };
+
++ gpu: gpu@fb000000 {
++ compatible = "rockchip,rk3588-mali", "arm,mali-valhall-csf";
++ reg = <0x0 0xfb000000 0x0 0x200000>;
++ #cooling-cells = <2>;
++ assigned-clocks = <&scmi_clk SCMI_CLK_GPU>;
++ assigned-clock-rates = <200000000>;
++ clocks = <&cru CLK_GPU>, <&cru CLK_GPU_COREGROUP>,
++ <&cru CLK_GPU_STACKS>;
++ clock-names = "core", "coregroup", "stacks";
++ dynamic-power-coefficient = <2982>;
++ interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH 0>;
++ interrupt-names = "job", "mmu", "gpu";
++ operating-points-v2 = <&gpu_opp_table>;
++ power-domains = <&power RK3588_PD_GPU>;
++ status = "disabled";
++
++ gpu_opp_table: opp-table {
++ compatible = "operating-points-v2";
++
++ opp-300000000 {
++ opp-hz = /bits/ 64 <300000000>;
++ opp-microvolt = <675000 675000 850000>;
++ };
++ opp-400000000 {
++ opp-hz = /bits/ 64 <400000000>;
++ opp-microvolt = <675000 675000 850000>;
++ };
++ opp-500000000 {
++ opp-hz = /bits/ 64 <500000000>;
++ opp-microvolt = <675000 675000 850000>;
++ };
++ opp-600000000 {
++ opp-hz = /bits/ 64 <600000000>;
++ opp-microvolt = <675000 675000 850000>;
++ };
++ opp-700000000 {
++ opp-hz = /bits/ 64 <700000000>;
++ opp-microvolt = <700000 700000 850000>;
++ };
++ opp-800000000 {
++ opp-hz = /bits/ 64 <800000000>;
++ opp-microvolt = <750000 750000 850000>;
++ };
++ opp-900000000 {
++ opp-hz = /bits/ 64 <900000000>;
++ opp-microvolt = <800000 800000 850000>;
++ };
++ opp-1000000000 {
++ opp-hz = /bits/ 64 <1000000000>;
++ opp-microvolt = <850000 850000 850000>;
++ };
++ };
++ };
++
+ usb_host0_ehci: usb@fc800000 {
+ compatible = "rockchip,rk3588-ehci", "generic-ehci";
+ reg = <0x0 0xfc800000 0x0 0x40000>;
+@@ -501,62 +557,6 @@
+ status = "disabled";
+ };
+
+- gpu: gpu@fb000000 {
+- compatible = "rockchip,rk3588-mali", "arm,mali-valhall-csf";
+- reg = <0x0 0xfb000000 0x0 0x200000>;
+- #cooling-cells = <2>;
+- assigned-clocks = <&scmi_clk SCMI_CLK_GPU>;
+- assigned-clock-rates = <200000000>;
+- clocks = <&cru CLK_GPU>, <&cru CLK_GPU_COREGROUP>,
+- <&cru CLK_GPU_STACKS>;
+- clock-names = "core", "coregroup", "stacks";
+- dynamic-power-coefficient = <2982>;
+- interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH 0>;
+- interrupt-names = "job", "mmu", "gpu";
+- operating-points-v2 = <&gpu_opp_table>;
+- power-domains = <&power RK3588_PD_GPU>;
+- status = "disabled";
+-
+- gpu_opp_table: opp-table {
+- compatible = "operating-points-v2";
+-
+- opp-300000000 {
+- opp-hz = /bits/ 64 <300000000>;
+- opp-microvolt = <675000 675000 850000>;
+- };
+- opp-400000000 {
+- opp-hz = /bits/ 64 <400000000>;
+- opp-microvolt = <675000 675000 850000>;
+- };
+- opp-500000000 {
+- opp-hz = /bits/ 64 <500000000>;
+- opp-microvolt = <675000 675000 850000>;
+- };
+- opp-600000000 {
+- opp-hz = /bits/ 64 <600000000>;
+- opp-microvolt = <675000 675000 850000>;
+- };
+- opp-700000000 {
+- opp-hz = /bits/ 64 <700000000>;
+- opp-microvolt = <700000 700000 850000>;
+- };
+- opp-800000000 {
+- opp-hz = /bits/ 64 <800000000>;
+- opp-microvolt = <750000 750000 850000>;
+- };
+- opp-900000000 {
+- opp-hz = /bits/ 64 <900000000>;
+- opp-microvolt = <800000 800000 850000>;
+- };
+- opp-1000000000 {
+- opp-hz = /bits/ 64 <1000000000>;
+- opp-microvolt = <850000 850000 850000>;
+- };
+- };
+- };
+-
+ pmu1grf: syscon@fd58a000 {
+ compatible = "rockchip,rk3588-pmugrf", "syscon", "simple-mfd";
+ reg = <0x0 0xfd58a000 0x0 0x10000>;
+@@ -702,74 +702,6 @@
+ status = "disabled";
+ };
+
+- vop: vop@fdd90000 {
+- compatible = "rockchip,rk3588-vop";
+- reg = <0x0 0xfdd90000 0x0 0x4200>, <0x0 0xfdd95000 0x0 0x1000>;
+- reg-names = "vop", "gamma-lut";
+- interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru ACLK_VOP>,
+- <&cru HCLK_VOP>,
+- <&cru DCLK_VOP0>,
+- <&cru DCLK_VOP1>,
+- <&cru DCLK_VOP2>,
+- <&cru DCLK_VOP3>,
+- <&cru PCLK_VOP_ROOT>;
+- clock-names = "aclk",
+- "hclk",
+- "dclk_vp0",
+- "dclk_vp1",
+- "dclk_vp2",
+- "dclk_vp3",
+- "pclk_vop";
+- iommus = <&vop_mmu>;
+- power-domains = <&power RK3588_PD_VOP>;
+- rockchip,grf = <&sys_grf>;
+- rockchip,vop-grf = <&vop_grf>;
+- rockchip,vo1-grf = <&vo1_grf>;
+- rockchip,pmu = <&pmu>;
+- status = "disabled";
+-
+- vop_out: ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- vp0: port@0 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+- reg = <0>;
+- };
+-
+- vp1: port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+- reg = <1>;
+- };
+-
+- vp2: port@2 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+- reg = <2>;
+- };
+-
+- vp3: port@3 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+- reg = <3>;
+- };
+- };
+- };
+-
+- vop_mmu: iommu@fdd97e00 {
+- compatible = "rockchip,rk3588-iommu", "rockchip,rk3568-iommu";
+- reg = <0x0 0xfdd97e00 0x0 0x100>, <0x0 0xfdd97f00 0x0 0x100>;
+- interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru ACLK_VOP>, <&cru HCLK_VOP>;
+- clock-names = "aclk", "iface";
+- #iommu-cells = <0>;
+- power-domains = <&power RK3588_PD_VOP>;
+- status = "disabled";
+- };
+-
+ uart0: serial@fd890000 {
+ compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
+ reg = <0x0 0xfd890000 0x0 0x100>;
+@@ -1140,6 +1072,87 @@
+ };
+ };
+
++ av1d: video-codec@fdc70000 {
++ compatible = "rockchip,rk3588-av1-vpu";
++ reg = <0x0 0xfdc70000 0x0 0x800>;
++ interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH 0>;
++ interrupt-names = "vdpu";
++ assigned-clocks = <&cru ACLK_AV1>, <&cru PCLK_AV1>;
++ assigned-clock-rates = <400000000>, <400000000>;
++ clocks = <&cru ACLK_AV1>, <&cru PCLK_AV1>;
++ clock-names = "aclk", "hclk";
++ power-domains = <&power RK3588_PD_AV1>;
++ resets = <&cru SRST_A_AV1>, <&cru SRST_P_AV1>, <&cru SRST_A_AV1_BIU>, <&cru SRST_P_AV1_BIU>;
++ };
++
++ vop: vop@fdd90000 {
++ compatible = "rockchip,rk3588-vop";
++ reg = <0x0 0xfdd90000 0x0 0x4200>, <0x0 0xfdd95000 0x0 0x1000>;
++ reg-names = "vop", "gamma-lut";
++ interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru ACLK_VOP>,
++ <&cru HCLK_VOP>,
++ <&cru DCLK_VOP0>,
++ <&cru DCLK_VOP1>,
++ <&cru DCLK_VOP2>,
++ <&cru DCLK_VOP3>,
++ <&cru PCLK_VOP_ROOT>;
++ clock-names = "aclk",
++ "hclk",
++ "dclk_vp0",
++ "dclk_vp1",
++ "dclk_vp2",
++ "dclk_vp3",
++ "pclk_vop";
++ iommus = <&vop_mmu>;
++ power-domains = <&power RK3588_PD_VOP>;
++ rockchip,grf = <&sys_grf>;
++ rockchip,vop-grf = <&vop_grf>;
++ rockchip,vo1-grf = <&vo1_grf>;
++ rockchip,pmu = <&pmu>;
++ status = "disabled";
++
++ vop_out: ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ vp0: port@0 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0>;
++ };
++
++ vp1: port@1 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <1>;
++ };
++
++ vp2: port@2 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <2>;
++ };
++
++ vp3: port@3 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <3>;
++ };
++ };
++ };
++
++ vop_mmu: iommu@fdd97e00 {
++ compatible = "rockchip,rk3588-iommu", "rockchip,rk3568-iommu";
++ reg = <0x0 0xfdd97e00 0x0 0x100>, <0x0 0xfdd97f00 0x0 0x100>;
++ interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru ACLK_VOP>, <&cru HCLK_VOP>;
++ clock-names = "aclk", "iface";
++ #iommu-cells = <0>;
++ power-domains = <&power RK3588_PD_VOP>;
++ status = "disabled";
++ };
++
+ i2s4_8ch: i2s@fddc0000 {
+ compatible = "rockchip,rk3588-i2s-tdm";
+ reg = <0x0 0xfddc0000 0x0 0x1000>;
+@@ -1431,6 +1444,16 @@
+ reg = <0x0 0xfdf82200 0x0 0x20>;
+ };
+
++ dfi: dfi@fe060000 {
++ reg = <0x00 0xfe060000 0x00 0x10000>;
++ compatible = "rockchip,rk3588-dfi";
++ interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH 0>;
++ rockchip,pmu = <&pmu1grf>;
++ };
++
+ pcie2x1l1: pcie@fe180000 {
+ compatible = "rockchip,rk3588-pcie", "rockchip,rk3568-pcie";
+ bus-range = <0x30 0x3f>;
+@@ -1533,16 +1556,6 @@
+ };
+ };
+
+- dfi: dfi@fe060000 {
+- reg = <0x00 0xfe060000 0x00 0x10000>;
+- compatible = "rockchip,rk3588-dfi";
+- interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH 0>;
+- rockchip,pmu = <&pmu1grf>;
+- };
+-
+ gmac1: ethernet@fe1c0000 {
+ compatible = "rockchip,rk3588-gmac", "snps,dwmac-4.20a";
+ reg = <0x0 0xfe1c0000 0x0 0x10000>;
+@@ -2543,19 +2556,6 @@
+ #interrupt-cells = <2>;
+ };
+ };
+-
+- av1d: video-codec@fdc70000 {
+- compatible = "rockchip,rk3588-av1-vpu";
+- reg = <0x0 0xfdc70000 0x0 0x800>;
+- interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH 0>;
+- interrupt-names = "vdpu";
+- assigned-clocks = <&cru ACLK_AV1>, <&cru PCLK_AV1>;
+- assigned-clock-rates = <400000000>, <400000000>;
+- clocks = <&cru ACLK_AV1>, <&cru PCLK_AV1>;
+- clock-names = "aclk", "hclk";
+- power-domains = <&power RK3588_PD_AV1>;
+- resets = <&cru SRST_A_AV1>, <&cru SRST_P_AV1>, <&cru SRST_A_AV1_BIU>, <&cru SRST_P_AV1_BIU>;
+- };
+ };
+
+ #include "rk3588s-pinctrl.dtsi"
diff --git a/target/linux/rockchip/patches-6.6/050-17-v6.10-arm64-dts-rockchip-fix-usb2phy-nodename-for-rk3588.patch b/target/linux/rockchip/patches-6.6/050-17-v6.10-arm64-dts-rockchip-fix-usb2phy-nodename-for-rk3588.patch
new file mode 100644
index 0000000000..065cb4b410
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/050-17-v6.10-arm64-dts-rockchip-fix-usb2phy-nodename-for-rk3588.patch
@@ -0,0 +1,35 @@
+From 4e07a95f7402de092cd71b2cb96c69f85c98f251 Mon Sep 17 00:00:00 2001
+From: Sebastian Reichel <sebastian.reichel@collabora.com>
+Date: Tue, 9 Apr 2024 00:50:31 +0200
+Subject: [PATCH] arm64: dts: rockchip: fix usb2phy nodename for rk3588
+
+usb2-phy should be named usb2phy according to the DT binding,
+so let's fix it up accordingly.
+
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20240408225109.128953-5-sebastian.reichel@collabora.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
+@@ -599,7 +599,7 @@
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+- u2phy2: usb2-phy@8000 {
++ u2phy2: usb2phy@8000 {
+ compatible = "rockchip,rk3588-usb2phy";
+ reg = <0x8000 0x10>;
+ interrupts = <GIC_SPI 391 IRQ_TYPE_LEVEL_HIGH 0>;
+@@ -624,7 +624,7 @@
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+- u2phy3: usb2-phy@c000 {
++ u2phy3: usb2phy@c000 {
+ compatible = "rockchip,rk3588-usb2phy";
+ reg = <0xc000 0x10>;
+ interrupts = <GIC_SPI 392 IRQ_TYPE_LEVEL_HIGH 0>;
diff --git a/target/linux/rockchip/patches-6.6/050-18-v6.10-arm64-dts-rockchip-reorder-usb2phy-properties-for-rk3588.patch b/target/linux/rockchip/patches-6.6/050-18-v6.10-arm64-dts-rockchip-reorder-usb2phy-properties-for-rk3588.patch
new file mode 100644
index 0000000000..81e8ed1011
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/050-18-v6.10-arm64-dts-rockchip-reorder-usb2phy-properties-for-rk3588.patch
@@ -0,0 +1,53 @@
+From abe68e0ca71dddce0e5419e35507cb464d61870d Mon Sep 17 00:00:00 2001
+From: Sebastian Reichel <sebastian.reichel@collabora.com>
+Date: Tue, 9 Apr 2024 00:50:32 +0200
+Subject: [PATCH] arm64: dts: rockchip: reorder usb2phy properties for rk3588
+
+Reorder common DT properties alphabetically for usb2phy, according
+to latest DT style rules.
+
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20240408225109.128953-6-sebastian.reichel@collabora.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
+@@ -602,13 +602,13 @@
+ u2phy2: usb2phy@8000 {
+ compatible = "rockchip,rk3588-usb2phy";
+ reg = <0x8000 0x10>;
+- interrupts = <GIC_SPI 391 IRQ_TYPE_LEVEL_HIGH 0>;
+- resets = <&cru SRST_OTGPHY_U2_0>, <&cru SRST_P_USB2PHY_U2_0_GRF0>;
+- reset-names = "phy", "apb";
++ #clock-cells = <0>;
+ clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>;
+ clock-names = "phyclk";
+ clock-output-names = "usb480m_phy2";
+- #clock-cells = <0>;
++ interrupts = <GIC_SPI 391 IRQ_TYPE_LEVEL_HIGH 0>;
++ resets = <&cru SRST_OTGPHY_U2_0>, <&cru SRST_P_USB2PHY_U2_0_GRF0>;
++ reset-names = "phy", "apb";
+ status = "disabled";
+
+ u2phy2_host: host-port {
+@@ -627,13 +627,13 @@
+ u2phy3: usb2phy@c000 {
+ compatible = "rockchip,rk3588-usb2phy";
+ reg = <0xc000 0x10>;
+- interrupts = <GIC_SPI 392 IRQ_TYPE_LEVEL_HIGH 0>;
+- resets = <&cru SRST_OTGPHY_U2_1>, <&cru SRST_P_USB2PHY_U2_1_GRF0>;
+- reset-names = "phy", "apb";
++ #clock-cells = <0>;
+ clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>;
+ clock-names = "phyclk";
+ clock-output-names = "usb480m_phy3";
+- #clock-cells = <0>;
++ interrupts = <GIC_SPI 392 IRQ_TYPE_LEVEL_HIGH 0>;
++ resets = <&cru SRST_OTGPHY_U2_1>, <&cru SRST_P_USB2PHY_U2_1_GRF0>;
++ reset-names = "phy", "apb";
+ status = "disabled";
+
+ u2phy3_host: host-port {
diff --git a/target/linux/rockchip/patches-6.6/050-19-v6.10-arm64-dts-rockchip-add-USBDP-phys-on-rk3588.patch b/target/linux/rockchip/patches-6.6/050-19-v6.10-arm64-dts-rockchip-add-USBDP-phys-on-rk3588.patch
new file mode 100644
index 0000000000..985a799df1
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/050-19-v6.10-arm64-dts-rockchip-add-USBDP-phys-on-rk3588.patch
@@ -0,0 +1,175 @@
+From e18e5e8188f2671abf63abe7db5f21555705130f Mon Sep 17 00:00:00 2001
+From: Sebastian Reichel <sebastian.reichel@collabora.com>
+Date: Tue, 9 Apr 2024 00:50:33 +0200
+Subject: [PATCH] arm64: dts: rockchip: add USBDP phys on rk3588
+
+Add both USB3-DisplayPort PHYs to RK3588 SoC DT.
+
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20240408225109.128953-7-sebastian.reichel@collabora.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588.dtsi | 52 +++++++++++++++++++
+ arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 63 +++++++++++++++++++++++
+ 2 files changed, 115 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588.dtsi
+@@ -17,6 +17,36 @@
+ reg = <0x0 0xfd5c0000 0x0 0x100>;
+ };
+
++ usbdpphy1_grf: syscon@fd5cc000 {
++ compatible = "rockchip,rk3588-usbdpphy-grf", "syscon";
++ reg = <0x0 0xfd5cc000 0x0 0x4000>;
++ };
++
++ usb2phy1_grf: syscon@fd5d4000 {
++ compatible = "rockchip,rk3588-usb2phy-grf", "syscon", "simple-mfd";
++ reg = <0x0 0xfd5d4000 0x0 0x4000>;
++ #address-cells = <1>;
++ #size-cells = <1>;
++
++ u2phy1: usb2phy@4000 {
++ compatible = "rockchip,rk3588-usb2phy";
++ reg = <0x4000 0x10>;
++ #clock-cells = <0>;
++ clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>;
++ clock-names = "phyclk";
++ clock-output-names = "usb480m_phy1";
++ interrupts = <GIC_SPI 394 IRQ_TYPE_LEVEL_HIGH 0>;
++ resets = <&cru SRST_OTGPHY_U3_1>, <&cru SRST_P_USB2PHY_U3_1_GRF0>;
++ reset-names = "phy", "apb";
++ status = "disabled";
++
++ u2phy1_otg: otg-port {
++ #phy-cells = <0>;
++ status = "disabled";
++ };
++ };
++ };
++
+ i2s8_8ch: i2s@fddc8000 {
+ compatible = "rockchip,rk3588-i2s-tdm";
+ reg = <0x0 0xfddc8000 0x0 0x1000>;
+@@ -310,6 +340,28 @@
+ };
+ };
+
++ usbdp_phy1: phy@fed90000 {
++ compatible = "rockchip,rk3588-usbdp-phy";
++ reg = <0x0 0xfed90000 0x0 0x10000>;
++ #phy-cells = <1>;
++ clocks = <&cru CLK_USBDPPHY_MIPIDCPPHY_REF>,
++ <&cru CLK_USBDP_PHY1_IMMORTAL>,
++ <&cru PCLK_USBDPPHY1>,
++ <&u2phy1>;
++ clock-names = "refclk", "immortal", "pclk", "utmi";
++ resets = <&cru SRST_USBDP_COMBO_PHY1_INIT>,
++ <&cru SRST_USBDP_COMBO_PHY1_CMN>,
++ <&cru SRST_USBDP_COMBO_PHY1_LANE>,
++ <&cru SRST_USBDP_COMBO_PHY1_PCS>,
++ <&cru SRST_P_USBDPPHY1>;
++ reset-names = "init", "cmn", "lane", "pcs_apb", "pma_apb";
++ rockchip,u2phy-grf = <&usb2phy1_grf>;
++ rockchip,usb-grf = <&usb_grf>;
++ rockchip,usbdpphy-grf = <&usbdpphy1_grf>;
++ rockchip,vo-grf = <&vo0_grf>;
++ status = "disabled";
++ };
++
+ combphy1_ps: phy@fee10000 {
+ compatible = "rockchip,rk3588-naneng-combphy";
+ reg = <0x0 0xfee10000 0x0 0x100>;
+--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
+@@ -572,12 +572,23 @@
+ reg = <0x0 0xfd5a4000 0x0 0x2000>;
+ };
+
++ vo0_grf: syscon@fd5a6000 {
++ compatible = "rockchip,rk3588-vo-grf", "syscon";
++ reg = <0x0 0xfd5a6000 0x0 0x2000>;
++ clocks = <&cru PCLK_VO0GRF>;
++ };
++
+ vo1_grf: syscon@fd5a8000 {
+ compatible = "rockchip,rk3588-vo-grf", "syscon";
+ reg = <0x0 0xfd5a8000 0x0 0x100>;
+ clocks = <&cru PCLK_VO1GRF>;
+ };
+
++ usb_grf: syscon@fd5ac000 {
++ compatible = "rockchip,rk3588-usb-grf", "syscon";
++ reg = <0x0 0xfd5ac000 0x0 0x4000>;
++ };
++
+ php_grf: syscon@fd5b0000 {
+ compatible = "rockchip,rk3588-php-grf", "syscon";
+ reg = <0x0 0xfd5b0000 0x0 0x1000>;
+@@ -593,6 +604,36 @@
+ reg = <0x0 0xfd5c4000 0x0 0x100>;
+ };
+
++ usbdpphy0_grf: syscon@fd5c8000 {
++ compatible = "rockchip,rk3588-usbdpphy-grf", "syscon";
++ reg = <0x0 0xfd5c8000 0x0 0x4000>;
++ };
++
++ usb2phy0_grf: syscon@fd5d0000 {
++ compatible = "rockchip,rk3588-usb2phy-grf", "syscon", "simple-mfd";
++ reg = <0x0 0xfd5d0000 0x0 0x4000>;
++ #address-cells = <1>;
++ #size-cells = <1>;
++
++ u2phy0: usb2phy@0 {
++ compatible = "rockchip,rk3588-usb2phy";
++ reg = <0x0 0x10>;
++ #clock-cells = <0>;
++ clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>;
++ clock-names = "phyclk";
++ clock-output-names = "usb480m_phy0";
++ interrupts = <GIC_SPI 393 IRQ_TYPE_LEVEL_HIGH 0>;
++ resets = <&cru SRST_OTGPHY_U3_0>, <&cru SRST_P_USB2PHY_U3_0_GRF0>;
++ reset-names = "phy", "apb";
++ status = "disabled";
++
++ u2phy0_otg: otg-port {
++ #phy-cells = <0>;
++ status = "disabled";
++ };
++ };
++ };
++
+ usb2phy2_grf: syscon@fd5d8000 {
+ compatible = "rockchip,rk3588-usb2phy-grf", "syscon", "simple-mfd";
+ reg = <0x0 0xfd5d8000 0x0 0x4000>;
+@@ -2449,6 +2490,28 @@
+ status = "disabled";
+ };
+
++ usbdp_phy0: phy@fed80000 {
++ compatible = "rockchip,rk3588-usbdp-phy";
++ reg = <0x0 0xfed80000 0x0 0x10000>;
++ #phy-cells = <1>;
++ clocks = <&cru CLK_USBDPPHY_MIPIDCPPHY_REF>,
++ <&cru CLK_USBDP_PHY0_IMMORTAL>,
++ <&cru PCLK_USBDPPHY0>,
++ <&u2phy0>;
++ clock-names = "refclk", "immortal", "pclk", "utmi";
++ resets = <&cru SRST_USBDP_COMBO_PHY0_INIT>,
++ <&cru SRST_USBDP_COMBO_PHY0_CMN>,
++ <&cru SRST_USBDP_COMBO_PHY0_LANE>,
++ <&cru SRST_USBDP_COMBO_PHY0_PCS>,
++ <&cru SRST_P_USBDPPHY0>;
++ reset-names = "init", "cmn", "lane", "pcs_apb", "pma_apb";
++ rockchip,u2phy-grf = <&usb2phy0_grf>;
++ rockchip,usb-grf = <&usb_grf>;
++ rockchip,usbdpphy-grf = <&usbdpphy0_grf>;
++ rockchip,vo-grf = <&vo0_grf>;
++ status = "disabled";
++ };
++
+ combphy0_ps: phy@fee00000 {
+ compatible = "rockchip,rk3588-naneng-combphy";
+ reg = <0x0 0xfee00000 0x0 0x100>;
diff --git a/target/linux/rockchip/patches-6.6/050-20-v6.10-arm64-dts-rockchip-add-USB3-DRD-controllers-on-rk3588.patch b/target/linux/rockchip/patches-6.6/050-20-v6.10-arm64-dts-rockchip-add-USB3-DRD-controllers-on-rk3588.patch
new file mode 100644
index 0000000000..7bfa205514
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/050-20-v6.10-arm64-dts-rockchip-add-USB3-DRD-controllers-on-rk3588.patch
@@ -0,0 +1,75 @@
+From 33f393a2a990e16f56931ca708295f31d2b44415 Mon Sep 17 00:00:00 2001
+From: Sebastian Reichel <sebastian.reichel@collabora.com>
+Date: Tue, 9 Apr 2024 00:50:34 +0200
+Subject: [PATCH] arm64: dts: rockchip: add USB3 DRD controllers on rk3588
+
+Add both USB3 dual-role controllers to the RK3588 devicetree.
+
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20240408225109.128953-8-sebastian.reichel@collabora.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588.dtsi | 20 ++++++++++++++++++++
+ arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 22 ++++++++++++++++++++++
+ 2 files changed, 42 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588.dtsi
+@@ -7,6 +7,26 @@
+ #include "rk3588-pinctrl.dtsi"
+
+ / {
++ usb_host1_xhci: usb@fc400000 {
++ compatible = "rockchip,rk3588-dwc3", "snps,dwc3";
++ reg = <0x0 0xfc400000 0x0 0x400000>;
++ interrupts = <GIC_SPI 221 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru REF_CLK_USB3OTG1>, <&cru SUSPEND_CLK_USB3OTG1>,
++ <&cru ACLK_USB3OTG1>;
++ clock-names = "ref_clk", "suspend_clk", "bus_clk";
++ dr_mode = "otg";
++ phys = <&u2phy1_otg>, <&usbdp_phy1 PHY_TYPE_USB3>;
++ phy-names = "usb2-phy", "usb3-phy";
++ phy_type = "utmi_wide";
++ power-domains = <&power RK3588_PD_USB>;
++ resets = <&cru SRST_A_USB3OTG1>;
++ snps,dis_enblslpm_quirk;
++ snps,dis-u2-freeclk-exists-quirk;
++ snps,dis-del-phy-power-chg-quirk;
++ snps,dis-tx-ipgap-linecheck-quirk;
++ status = "disabled";
++ };
++
+ pcie30_phy_grf: syscon@fd5b8000 {
+ compatible = "rockchip,rk3588-pcie3-phy-grf", "syscon";
+ reg = <0x0 0xfd5b8000 0x0 0x10000>;
+--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
+@@ -492,6 +492,28 @@
+ };
+ };
+
++ usb_host0_xhci: usb@fc000000 {
++ compatible = "rockchip,rk3588-dwc3", "snps,dwc3";
++ reg = <0x0 0xfc000000 0x0 0x400000>;
++ interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru REF_CLK_USB3OTG0>, <&cru SUSPEND_CLK_USB3OTG0>,
++ <&cru ACLK_USB3OTG0>;
++ clock-names = "ref_clk", "suspend_clk", "bus_clk";
++ dr_mode = "otg";
++ phys = <&u2phy0_otg>, <&usbdp_phy0 PHY_TYPE_USB3>;
++ phy-names = "usb2-phy", "usb3-phy";
++ phy_type = "utmi_wide";
++ power-domains = <&power RK3588_PD_USB>;
++ resets = <&cru SRST_A_USB3OTG0>;
++ snps,dis_enblslpm_quirk;
++ snps,dis-u1-entry-quirk;
++ snps,dis-u2-entry-quirk;
++ snps,dis-u2-freeclk-exists-quirk;
++ snps,dis-del-phy-power-chg-quirk;
++ snps,dis-tx-ipgap-linecheck-quirk;
++ status = "disabled";
++ };
++
+ usb_host0_ehci: usb@fc800000 {
+ compatible = "rockchip,rk3588-ehci", "generic-ehci";
+ reg = <0x0 0xfc800000 0x0 0x40000>;
diff --git a/target/linux/rockchip/patches-6.6/050-21-v6.10-arm64-dts-rockchip-add-rk3588-pcie-and-php-IOMMUs.patch b/target/linux/rockchip/patches-6.6/050-21-v6.10-arm64-dts-rockchip-add-rk3588-pcie-and-php-IOMMUs.patch
new file mode 100644
index 0000000000..fa98e5ec70
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/050-21-v6.10-arm64-dts-rockchip-add-rk3588-pcie-and-php-IOMMUs.patch
@@ -0,0 +1,74 @@
+From cd81d3a0695cc54ad6ac0ef4bbb67a7c8f55d592 Mon Sep 17 00:00:00 2001
+From: Niklas Cassel <cassel@kernel.org>
+Date: Thu, 2 May 2024 16:02:32 +0200
+Subject: [PATCH] arm64: dts: rockchip: add rk3588 pcie and php IOMMUs
+
+The mmu600_pcie is connected with the five PCIe controllers.
+The mmu600_php is connected with the USB3 controller, the GMAC
+controllers, and the SATA controllers.
+
+See 8.2 Block Diagram, in rk3588 TRM (Technical Reference Manual).
+
+The IOMMUs are disabled by default, as further patches are needed to
+program the SID/SSIDs in to the IOMMUs.
+
+iommu: Default domain type: Translated
+iommu: DMA domain TLB invalidation policy: strict mode
+arm-smmu-v3 fc900000.iommu: ias 48-bit, oas 48-bit (features 0x001c1eaf)
+arm-smmu-v3 fc900000.iommu: allocated 65536 entries for cmdq
+arm-smmu-v3 fc900000.iommu: allocated 32768 entries for evtq
+arm-smmu-v3 fc900000.iommu: msi_domain absent - falling back to wired irqs
+
+Additionally, the IOMMU correctly triggers an IOMMU fault when
+a PCIe device performs a write (since the device hasn't been
+assigned a SID/SSID):
+arm-smmu-v3 fc900000.iommu: event 0x02 received:
+arm-smmu-v3 fc900000.iommu: 0x0000010000000002
+arm-smmu-v3 fc900000.iommu: 0x0000000000000000
+arm-smmu-v3 fc900000.iommu: 0x0000000000000000
+arm-smmu-v3 fc900000.iommu: 0x0000000000000000
+
+While this doesn't provide much value as is, having the devices as
+disabled in the device tree will allow developers to see that the rk3588
+actually has IOMMUs on the SoC.
+
+Signed-off-by: Niklas Cassel <cassel@kernel.org>
+Link: https://lore.kernel.org/r/20240502140231.477049-2-cassel@kernel.org
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 24 +++++++++++++++++++++++
+ 1 file changed, 24 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
+@@ -579,6 +579,30 @@
+ status = "disabled";
+ };
+
++ mmu600_pcie: iommu@fc900000 {
++ compatible = "arm,smmu-v3";
++ reg = <0x0 0xfc900000 0x0 0x200000>;
++ interrupts = <GIC_SPI 369 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 371 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 374 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 367 IRQ_TYPE_LEVEL_HIGH 0>;
++ interrupt-names = "eventq", "gerror", "priq", "cmdq-sync";
++ #iommu-cells = <1>;
++ status = "disabled";
++ };
++
++ mmu600_php: iommu@fcb00000 {
++ compatible = "arm,smmu-v3";
++ reg = <0x0 0xfcb00000 0x0 0x200000>;
++ interrupts = <GIC_SPI 381 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 383 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 386 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 379 IRQ_TYPE_LEVEL_HIGH 0>;
++ interrupt-names = "eventq", "gerror", "priq", "cmdq-sync";
++ #iommu-cells = <1>;
++ status = "disabled";
++ };
++
+ pmu1grf: syscon@fd58a000 {
+ compatible = "rockchip,rk3588-pmugrf", "syscon", "simple-mfd";
+ reg = <0x0 0xfd58a000 0x0 0x10000>;
diff --git a/target/linux/rockchip/patches-6.6/050-22-v6.11-arm64-dts-rockchip-Prepare-RK3588-SoC-dtsi-files-for.patch b/target/linux/rockchip/patches-6.6/050-22-v6.11-arm64-dts-rockchip-Prepare-RK3588-SoC-dtsi-files-for.patch
new file mode 100644
index 0000000000..08460b5b41
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/050-22-v6.11-arm64-dts-rockchip-Prepare-RK3588-SoC-dtsi-files-for.patch
@@ -0,0 +1,14208 @@
+From def88eb4d8365a4aa064d28405d03550a9d0a3be Mon Sep 17 00:00:00 2001
+From: Dragan Simic <dsimic@manjaro.org>
+Date: Sun, 9 Jun 2024 10:58:19 +0200
+Subject: [PATCH] arm64: dts: rockchip: Prepare RK3588 SoC dtsi files for
+ per-variant OPPs
+
+Rename the Rockchip RK3588 SoC dtsi files and, consequently, adjust their
+contents appropriately, to prepare them for the ability to specify different
+CPU and GPU OPPs for each of the supported RK3588 SoC variants.
+
+As already discussed, [1][2][3][4] some of the RK3588 SoC variants require
+different OPPs, and it makes more sense to have the OPPs already defined when
+a board dts(i) file includes one of the SoC variant dtsi files (rk3588.dtsi,
+rk3588j.dtsi or rk3588s.dtsi), rather than requiring the board dts(i) file
+to also include a separate rk3588*-opp.dtsi file. The choice of the SoC
+variant is already made by the inclusion of the SoC dtsi file into the board
+dts(i) file, and it doesn't make much sense to, effectively, allow the board
+dts(i) file to include and use an incompatible set of OPPs for the already
+selected RK3588 SoC variant.
+
+The new naming scheme for the RK3588 SoC dtsi files uses "-base" and "-extra"
+suffixes to denote the DT data shared between all RK5588 SoC variants, and
+the DT data shared between the unrestricted SoC variants, respectively.
+For example, the DT data for the RK3588 includes both rk3588-base.dtsi and
+rk3588-extra.dtsi, because it's an unrestricted SoC variant, while the DT
+data for the RK3588S variant includes rk3588-base.dtsi only, because it's
+a restricted SoC variant, feature- and interface-wise. This achieves a more
+logical naming of the RK3588 SoC dtsi files, which reflects the way DT data
+for the SoC variants is built by "stacking" the SoC variant features made
+available through the "-base" and "-extra" SoC dtsi files. Additionally,
+the SoC variant dtsi files (rk3588.dtsi, rk3588j.dtsi and rk3588s.dtsi) are
+no longer parents to any other SoC variant dtsi files, which should help with
+making the new "stacking" approach cleaner and easier to follow.
+
+The RK3588 pinctrl dtsi files are also renamed in the same way, for the sake
+of consistency. This also keeps the "-base" and "-extra" groups of the dtsi
+files together when looked at in a directory listing, which is helpful.
+
+The per-SoC-variant OPPs should go directly into the SoC dtsi files, if no
+more than one SoC variant uses those OPPs, or be put into a separate "-opp"
+dtsi file that's shared between and included from two or more SoC variant
+dtsi files. An example for the former is the non-shared OPP data that should
+go directly into the RK3588J SoC variant dtsi file (i.e. rk3588j.dtsi), and
+an example for the latter is the shared OPP data that should be put into
+rk3588-opp.dtsi and be included from the RK3588 and RK3588S SoC variant dtsi
+files (i.e. rk3588.dtsi and rk3588s.dtsi, respectively). Consequently, if
+the OPPs for the RK3588 and RK3588S SoC variants are ever made different,
+the shared rk3588-opp.dtsi file should be deleted and the new OPPs should
+be put directly into rk3588.dtsi and rk3588s.dtsi. [4]
+
+No functional changes are introduced, which was validated by decompiling and
+comparing all affected dtb files before and after these changes.
+
+As a side note, due to the nature of introduced changes, this commit is best
+viewed using the --break-rewrites option for git-log(1).
+
+[1] https://lore.kernel.org/linux-rockchip/646a33e0-5c1b-471c-8183-2c0df40ea51a@cherry.de/
+[2] https://lore.kernel.org/linux-rockchip/CABjd4Yxi=+3gkNnH3BysUzzYsji-=-yROtzEc8jM_g0roKB0-w@mail.gmail.com/
+[3] https://lore.kernel.org/linux-rockchip/035a274be262528012173d463e25b55f@manjaro.org/
+[4] https://lore.kernel.org/linux-rockchip/673dcf47596e7bc8ba065034e339bb1bbf9cdcb0.1716948159.git.dsimic@manjaro.org/T/#u
+
+Signed-off-by: Dragan Simic <dsimic@manjaro.org>
+Link: https://lore.kernel.org/r/9ffedc0e2ca7f167d9d795b2a8f43cb9f56a653b.1717923308.git.dsimic@manjaro.org
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ ...-pinctrl.dtsi => rk3588-base-pinctrl.dtsi} | 0
+ arch/arm64/boot/dts/rockchip/rk3588-base.dtsi | 2670 +++++++++++++++++
+ ...pinctrl.dtsi => rk3588-extra-pinctrl.dtsi} | 0
+ .../arm64/boot/dts/rockchip/rk3588-extra.dtsi | 413 +++
+ arch/arm64/boot/dts/rockchip/rk3588.dtsi | 412 +--
+ arch/arm64/boot/dts/rockchip/rk3588j.dtsi | 2 +-
+ arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 2669 +---------------
+ 7 files changed, 3090 insertions(+), 3076 deletions(-)
+ rename arch/arm64/boot/dts/rockchip/{rk3588s-pinctrl.dtsi => rk3588-base-pinctrl.dtsi} (100%)
+ create mode 100644 arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
+ rename arch/arm64/boot/dts/rockchip/{rk3588-pinctrl.dtsi => rk3588-extra-pinctrl.dtsi} (100%)
+ create mode 100644 arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi
+
+--- /dev/null
++++ b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
+@@ -0,0 +1,2670 @@
++// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
++/*
++ * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
++ */
++
++#include <dt-bindings/clock/rockchip,rk3588-cru.h>
++#include <dt-bindings/interrupt-controller/arm-gic.h>
++#include <dt-bindings/interrupt-controller/irq.h>
++#include <dt-bindings/power/rk3588-power.h>
++#include <dt-bindings/reset/rockchip,rk3588-cru.h>
++#include <dt-bindings/phy/phy.h>
++#include <dt-bindings/ata/ahci.h>
++
++/ {
++ compatible = "rockchip,rk3588";
++
++ interrupt-parent = <&gic>;
++ #address-cells = <2>;
++ #size-cells = <2>;
++
++ aliases {
++ gpio0 = &gpio0;
++ gpio1 = &gpio1;
++ gpio2 = &gpio2;
++ gpio3 = &gpio3;
++ gpio4 = &gpio4;
++ i2c0 = &i2c0;
++ i2c1 = &i2c1;
++ i2c2 = &i2c2;
++ i2c3 = &i2c3;
++ i2c4 = &i2c4;
++ i2c5 = &i2c5;
++ i2c6 = &i2c6;
++ i2c7 = &i2c7;
++ i2c8 = &i2c8;
++ serial0 = &uart0;
++ serial1 = &uart1;
++ serial2 = &uart2;
++ serial3 = &uart3;
++ serial4 = &uart4;
++ serial5 = &uart5;
++ serial6 = &uart6;
++ serial7 = &uart7;
++ serial8 = &uart8;
++ serial9 = &uart9;
++ spi0 = &spi0;
++ spi1 = &spi1;
++ spi2 = &spi2;
++ spi3 = &spi3;
++ spi4 = &spi4;
++ };
++
++ cpus {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ cpu-map {
++ cluster0 {
++ core0 {
++ cpu = <&cpu_l0>;
++ };
++ core1 {
++ cpu = <&cpu_l1>;
++ };
++ core2 {
++ cpu = <&cpu_l2>;
++ };
++ core3 {
++ cpu = <&cpu_l3>;
++ };
++ };
++ cluster1 {
++ core0 {
++ cpu = <&cpu_b0>;
++ };
++ core1 {
++ cpu = <&cpu_b1>;
++ };
++ };
++ cluster2 {
++ core0 {
++ cpu = <&cpu_b2>;
++ };
++ core1 {
++ cpu = <&cpu_b3>;
++ };
++ };
++ };
++
++ cpu_l0: cpu@0 {
++ device_type = "cpu";
++ compatible = "arm,cortex-a55";
++ reg = <0x0>;
++ enable-method = "psci";
++ capacity-dmips-mhz = <530>;
++ clocks = <&scmi_clk SCMI_CLK_CPUL>;
++ assigned-clocks = <&scmi_clk SCMI_CLK_CPUL>;
++ assigned-clock-rates = <816000000>;
++ cpu-idle-states = <&CPU_SLEEP>;
++ i-cache-size = <32768>;
++ i-cache-line-size = <64>;
++ i-cache-sets = <128>;
++ d-cache-size = <32768>;
++ d-cache-line-size = <64>;
++ d-cache-sets = <128>;
++ next-level-cache = <&l2_cache_l0>;
++ dynamic-power-coefficient = <228>;
++ #cooling-cells = <2>;
++ };
++
++ cpu_l1: cpu@100 {
++ device_type = "cpu";
++ compatible = "arm,cortex-a55";
++ reg = <0x100>;
++ enable-method = "psci";
++ capacity-dmips-mhz = <530>;
++ clocks = <&scmi_clk SCMI_CLK_CPUL>;
++ cpu-idle-states = <&CPU_SLEEP>;
++ i-cache-size = <32768>;
++ i-cache-line-size = <64>;
++ i-cache-sets = <128>;
++ d-cache-size = <32768>;
++ d-cache-line-size = <64>;
++ d-cache-sets = <128>;
++ next-level-cache = <&l2_cache_l1>;
++ dynamic-power-coefficient = <228>;
++ #cooling-cells = <2>;
++ };
++
++ cpu_l2: cpu@200 {
++ device_type = "cpu";
++ compatible = "arm,cortex-a55";
++ reg = <0x200>;
++ enable-method = "psci";
++ capacity-dmips-mhz = <530>;
++ clocks = <&scmi_clk SCMI_CLK_CPUL>;
++ cpu-idle-states = <&CPU_SLEEP>;
++ i-cache-size = <32768>;
++ i-cache-line-size = <64>;
++ i-cache-sets = <128>;
++ d-cache-size = <32768>;
++ d-cache-line-size = <64>;
++ d-cache-sets = <128>;
++ next-level-cache = <&l2_cache_l2>;
++ dynamic-power-coefficient = <228>;
++ #cooling-cells = <2>;
++ };
++
++ cpu_l3: cpu@300 {
++ device_type = "cpu";
++ compatible = "arm,cortex-a55";
++ reg = <0x300>;
++ enable-method = "psci";
++ capacity-dmips-mhz = <530>;
++ clocks = <&scmi_clk SCMI_CLK_CPUL>;
++ cpu-idle-states = <&CPU_SLEEP>;
++ i-cache-size = <32768>;
++ i-cache-line-size = <64>;
++ i-cache-sets = <128>;
++ d-cache-size = <32768>;
++ d-cache-line-size = <64>;
++ d-cache-sets = <128>;
++ next-level-cache = <&l2_cache_l3>;
++ dynamic-power-coefficient = <228>;
++ #cooling-cells = <2>;
++ };
++
++ cpu_b0: cpu@400 {
++ device_type = "cpu";
++ compatible = "arm,cortex-a76";
++ reg = <0x400>;
++ enable-method = "psci";
++ capacity-dmips-mhz = <1024>;
++ clocks = <&scmi_clk SCMI_CLK_CPUB01>;
++ assigned-clocks = <&scmi_clk SCMI_CLK_CPUB01>;
++ assigned-clock-rates = <816000000>;
++ cpu-idle-states = <&CPU_SLEEP>;
++ i-cache-size = <65536>;
++ i-cache-line-size = <64>;
++ i-cache-sets = <256>;
++ d-cache-size = <65536>;
++ d-cache-line-size = <64>;
++ d-cache-sets = <256>;
++ next-level-cache = <&l2_cache_b0>;
++ dynamic-power-coefficient = <416>;
++ #cooling-cells = <2>;
++ };
++
++ cpu_b1: cpu@500 {
++ device_type = "cpu";
++ compatible = "arm,cortex-a76";
++ reg = <0x500>;
++ enable-method = "psci";
++ capacity-dmips-mhz = <1024>;
++ clocks = <&scmi_clk SCMI_CLK_CPUB01>;
++ cpu-idle-states = <&CPU_SLEEP>;
++ i-cache-size = <65536>;
++ i-cache-line-size = <64>;
++ i-cache-sets = <256>;
++ d-cache-size = <65536>;
++ d-cache-line-size = <64>;
++ d-cache-sets = <256>;
++ next-level-cache = <&l2_cache_b1>;
++ dynamic-power-coefficient = <416>;
++ #cooling-cells = <2>;
++ };
++
++ cpu_b2: cpu@600 {
++ device_type = "cpu";
++ compatible = "arm,cortex-a76";
++ reg = <0x600>;
++ enable-method = "psci";
++ capacity-dmips-mhz = <1024>;
++ clocks = <&scmi_clk SCMI_CLK_CPUB23>;
++ assigned-clocks = <&scmi_clk SCMI_CLK_CPUB23>;
++ assigned-clock-rates = <816000000>;
++ cpu-idle-states = <&CPU_SLEEP>;
++ i-cache-size = <65536>;
++ i-cache-line-size = <64>;
++ i-cache-sets = <256>;
++ d-cache-size = <65536>;
++ d-cache-line-size = <64>;
++ d-cache-sets = <256>;
++ next-level-cache = <&l2_cache_b2>;
++ dynamic-power-coefficient = <416>;
++ #cooling-cells = <2>;
++ };
++
++ cpu_b3: cpu@700 {
++ device_type = "cpu";
++ compatible = "arm,cortex-a76";
++ reg = <0x700>;
++ enable-method = "psci";
++ capacity-dmips-mhz = <1024>;
++ clocks = <&scmi_clk SCMI_CLK_CPUB23>;
++ cpu-idle-states = <&CPU_SLEEP>;
++ i-cache-size = <65536>;
++ i-cache-line-size = <64>;
++ i-cache-sets = <256>;
++ d-cache-size = <65536>;
++ d-cache-line-size = <64>;
++ d-cache-sets = <256>;
++ next-level-cache = <&l2_cache_b3>;
++ dynamic-power-coefficient = <416>;
++ #cooling-cells = <2>;
++ };
++
++ idle-states {
++ entry-method = "psci";
++ CPU_SLEEP: cpu-sleep {
++ compatible = "arm,idle-state";
++ local-timer-stop;
++ arm,psci-suspend-param = <0x0010000>;
++ entry-latency-us = <100>;
++ exit-latency-us = <120>;
++ min-residency-us = <1000>;
++ };
++ };
++
++ l2_cache_l0: l2-cache-l0 {
++ compatible = "cache";
++ cache-size = <131072>;
++ cache-line-size = <64>;
++ cache-sets = <512>;
++ cache-level = <2>;
++ cache-unified;
++ next-level-cache = <&l3_cache>;
++ };
++
++ l2_cache_l1: l2-cache-l1 {
++ compatible = "cache";
++ cache-size = <131072>;
++ cache-line-size = <64>;
++ cache-sets = <512>;
++ cache-level = <2>;
++ cache-unified;
++ next-level-cache = <&l3_cache>;
++ };
++
++ l2_cache_l2: l2-cache-l2 {
++ compatible = "cache";
++ cache-size = <131072>;
++ cache-line-size = <64>;
++ cache-sets = <512>;
++ cache-level = <2>;
++ cache-unified;
++ next-level-cache = <&l3_cache>;
++ };
++
++ l2_cache_l3: l2-cache-l3 {
++ compatible = "cache";
++ cache-size = <131072>;
++ cache-line-size = <64>;
++ cache-sets = <512>;
++ cache-level = <2>;
++ cache-unified;
++ next-level-cache = <&l3_cache>;
++ };
++
++ l2_cache_b0: l2-cache-b0 {
++ compatible = "cache";
++ cache-size = <524288>;
++ cache-line-size = <64>;
++ cache-sets = <1024>;
++ cache-level = <2>;
++ cache-unified;
++ next-level-cache = <&l3_cache>;
++ };
++
++ l2_cache_b1: l2-cache-b1 {
++ compatible = "cache";
++ cache-size = <524288>;
++ cache-line-size = <64>;
++ cache-sets = <1024>;
++ cache-level = <2>;
++ cache-unified;
++ next-level-cache = <&l3_cache>;
++ };
++
++ l2_cache_b2: l2-cache-b2 {
++ compatible = "cache";
++ cache-size = <524288>;
++ cache-line-size = <64>;
++ cache-sets = <1024>;
++ cache-level = <2>;
++ cache-unified;
++ next-level-cache = <&l3_cache>;
++ };
++
++ l2_cache_b3: l2-cache-b3 {
++ compatible = "cache";
++ cache-size = <524288>;
++ cache-line-size = <64>;
++ cache-sets = <1024>;
++ cache-level = <2>;
++ cache-unified;
++ next-level-cache = <&l3_cache>;
++ };
++
++ l3_cache: l3-cache {
++ compatible = "cache";
++ cache-size = <3145728>;
++ cache-line-size = <64>;
++ cache-sets = <4096>;
++ cache-level = <3>;
++ cache-unified;
++ };
++ };
++
++ display_subsystem: display-subsystem {
++ compatible = "rockchip,display-subsystem";
++ ports = <&vop_out>;
++ };
++
++ firmware {
++ optee: optee {
++ compatible = "linaro,optee-tz";
++ method = "smc";
++ };
++
++ scmi: scmi {
++ compatible = "arm,scmi-smc";
++ arm,smc-id = <0x82000010>;
++ shmem = <&scmi_shmem>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ scmi_clk: protocol@14 {
++ reg = <0x14>;
++ #clock-cells = <1>;
++ };
++
++ scmi_reset: protocol@16 {
++ reg = <0x16>;
++ #reset-cells = <1>;
++ };
++ };
++ };
++
++ pmu-a55 {
++ compatible = "arm,cortex-a55-pmu";
++ interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH &ppi_partition0>;
++ };
++
++ pmu-a76 {
++ compatible = "arm,cortex-a76-pmu";
++ interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH &ppi_partition1>;
++ };
++
++ psci {
++ compatible = "arm,psci-1.0";
++ method = "smc";
++ };
++
++ spll: clock-0 {
++ compatible = "fixed-clock";
++ clock-frequency = <702000000>;
++ clock-output-names = "spll";
++ #clock-cells = <0>;
++ };
++
++ timer {
++ compatible = "arm,armv8-timer";
++ interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_PPI 14 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_PPI 10 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_PPI 12 IRQ_TYPE_LEVEL_HIGH 0>;
++ interrupt-names = "sec-phys", "phys", "virt", "hyp-phys", "hyp-virt";
++ };
++
++ xin24m: clock-1 {
++ compatible = "fixed-clock";
++ clock-frequency = <24000000>;
++ clock-output-names = "xin24m";
++ #clock-cells = <0>;
++ };
++
++ xin32k: clock-2 {
++ compatible = "fixed-clock";
++ clock-frequency = <32768>;
++ clock-output-names = "xin32k";
++ #clock-cells = <0>;
++ };
++
++ pmu_sram: sram@10f000 {
++ compatible = "mmio-sram";
++ reg = <0x0 0x0010f000 0x0 0x100>;
++ ranges = <0 0x0 0x0010f000 0x100>;
++ #address-cells = <1>;
++ #size-cells = <1>;
++
++ scmi_shmem: sram@0 {
++ compatible = "arm,scmi-shmem";
++ reg = <0x0 0x100>;
++ };
++ };
++
++ gpu: gpu@fb000000 {
++ compatible = "rockchip,rk3588-mali", "arm,mali-valhall-csf";
++ reg = <0x0 0xfb000000 0x0 0x200000>;
++ #cooling-cells = <2>;
++ assigned-clocks = <&scmi_clk SCMI_CLK_GPU>;
++ assigned-clock-rates = <200000000>;
++ clocks = <&cru CLK_GPU>, <&cru CLK_GPU_COREGROUP>,
++ <&cru CLK_GPU_STACKS>;
++ clock-names = "core", "coregroup", "stacks";
++ dynamic-power-coefficient = <2982>;
++ interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH 0>;
++ interrupt-names = "job", "mmu", "gpu";
++ operating-points-v2 = <&gpu_opp_table>;
++ power-domains = <&power RK3588_PD_GPU>;
++ status = "disabled";
++
++ gpu_opp_table: opp-table {
++ compatible = "operating-points-v2";
++
++ opp-300000000 {
++ opp-hz = /bits/ 64 <300000000>;
++ opp-microvolt = <675000 675000 850000>;
++ };
++ opp-400000000 {
++ opp-hz = /bits/ 64 <400000000>;
++ opp-microvolt = <675000 675000 850000>;
++ };
++ opp-500000000 {
++ opp-hz = /bits/ 64 <500000000>;
++ opp-microvolt = <675000 675000 850000>;
++ };
++ opp-600000000 {
++ opp-hz = /bits/ 64 <600000000>;
++ opp-microvolt = <675000 675000 850000>;
++ };
++ opp-700000000 {
++ opp-hz = /bits/ 64 <700000000>;
++ opp-microvolt = <700000 700000 850000>;
++ };
++ opp-800000000 {
++ opp-hz = /bits/ 64 <800000000>;
++ opp-microvolt = <750000 750000 850000>;
++ };
++ opp-900000000 {
++ opp-hz = /bits/ 64 <900000000>;
++ opp-microvolt = <800000 800000 850000>;
++ };
++ opp-1000000000 {
++ opp-hz = /bits/ 64 <1000000000>;
++ opp-microvolt = <850000 850000 850000>;
++ };
++ };
++ };
++
++ usb_host0_xhci: usb@fc000000 {
++ compatible = "rockchip,rk3588-dwc3", "snps,dwc3";
++ reg = <0x0 0xfc000000 0x0 0x400000>;
++ interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru REF_CLK_USB3OTG0>, <&cru SUSPEND_CLK_USB3OTG0>,
++ <&cru ACLK_USB3OTG0>;
++ clock-names = "ref_clk", "suspend_clk", "bus_clk";
++ dr_mode = "otg";
++ phys = <&u2phy0_otg>, <&usbdp_phy0 PHY_TYPE_USB3>;
++ phy-names = "usb2-phy", "usb3-phy";
++ phy_type = "utmi_wide";
++ power-domains = <&power RK3588_PD_USB>;
++ resets = <&cru SRST_A_USB3OTG0>;
++ snps,dis_enblslpm_quirk;
++ snps,dis-u1-entry-quirk;
++ snps,dis-u2-entry-quirk;
++ snps,dis-u2-freeclk-exists-quirk;
++ snps,dis-del-phy-power-chg-quirk;
++ snps,dis-tx-ipgap-linecheck-quirk;
++ status = "disabled";
++ };
++
++ usb_host0_ehci: usb@fc800000 {
++ compatible = "rockchip,rk3588-ehci", "generic-ehci";
++ reg = <0x0 0xfc800000 0x0 0x40000>;
++ interrupts = <GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru HCLK_HOST0>, <&cru HCLK_HOST_ARB0>, <&cru ACLK_USB>, <&u2phy2>;
++ phys = <&u2phy2_host>;
++ phy-names = "usb";
++ power-domains = <&power RK3588_PD_USB>;
++ status = "disabled";
++ };
++
++ usb_host0_ohci: usb@fc840000 {
++ compatible = "rockchip,rk3588-ohci", "generic-ohci";
++ reg = <0x0 0xfc840000 0x0 0x40000>;
++ interrupts = <GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru HCLK_HOST0>, <&cru HCLK_HOST_ARB0>, <&cru ACLK_USB>, <&u2phy2>;
++ phys = <&u2phy2_host>;
++ phy-names = "usb";
++ power-domains = <&power RK3588_PD_USB>;
++ status = "disabled";
++ };
++
++ usb_host1_ehci: usb@fc880000 {
++ compatible = "rockchip,rk3588-ehci", "generic-ehci";
++ reg = <0x0 0xfc880000 0x0 0x40000>;
++ interrupts = <GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru HCLK_HOST1>, <&cru HCLK_HOST_ARB1>, <&cru ACLK_USB>, <&u2phy3>;
++ phys = <&u2phy3_host>;
++ phy-names = "usb";
++ power-domains = <&power RK3588_PD_USB>;
++ status = "disabled";
++ };
++
++ usb_host1_ohci: usb@fc8c0000 {
++ compatible = "rockchip,rk3588-ohci", "generic-ohci";
++ reg = <0x0 0xfc8c0000 0x0 0x40000>;
++ interrupts = <GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru HCLK_HOST1>, <&cru HCLK_HOST_ARB1>, <&cru ACLK_USB>, <&u2phy3>;
++ phys = <&u2phy3_host>;
++ phy-names = "usb";
++ power-domains = <&power RK3588_PD_USB>;
++ status = "disabled";
++ };
++
++ usb_host2_xhci: usb@fcd00000 {
++ compatible = "rockchip,rk3588-dwc3", "snps,dwc3";
++ reg = <0x0 0xfcd00000 0x0 0x400000>;
++ interrupts = <GIC_SPI 222 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru REF_CLK_USB3OTG2>, <&cru SUSPEND_CLK_USB3OTG2>,
++ <&cru ACLK_USB3OTG2>, <&cru CLK_UTMI_OTG2>,
++ <&cru CLK_PIPEPHY2_PIPE_U3_G>;
++ clock-names = "ref_clk", "suspend_clk", "bus_clk", "utmi", "pipe";
++ dr_mode = "host";
++ phys = <&combphy2_psu PHY_TYPE_USB3>;
++ phy-names = "usb3-phy";
++ phy_type = "utmi_wide";
++ resets = <&cru SRST_A_USB3OTG2>;
++ snps,dis_enblslpm_quirk;
++ snps,dis-u2-freeclk-exists-quirk;
++ snps,dis-del-phy-power-chg-quirk;
++ snps,dis-tx-ipgap-linecheck-quirk;
++ snps,dis_rxdet_inp3_quirk;
++ status = "disabled";
++ };
++
++ mmu600_pcie: iommu@fc900000 {
++ compatible = "arm,smmu-v3";
++ reg = <0x0 0xfc900000 0x0 0x200000>;
++ interrupts = <GIC_SPI 369 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 371 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 374 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 367 IRQ_TYPE_LEVEL_HIGH 0>;
++ interrupt-names = "eventq", "gerror", "priq", "cmdq-sync";
++ #iommu-cells = <1>;
++ status = "disabled";
++ };
++
++ mmu600_php: iommu@fcb00000 {
++ compatible = "arm,smmu-v3";
++ reg = <0x0 0xfcb00000 0x0 0x200000>;
++ interrupts = <GIC_SPI 381 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 383 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 386 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 379 IRQ_TYPE_LEVEL_HIGH 0>;
++ interrupt-names = "eventq", "gerror", "priq", "cmdq-sync";
++ #iommu-cells = <1>;
++ status = "disabled";
++ };
++
++ pmu1grf: syscon@fd58a000 {
++ compatible = "rockchip,rk3588-pmugrf", "syscon", "simple-mfd";
++ reg = <0x0 0xfd58a000 0x0 0x10000>;
++ };
++
++ sys_grf: syscon@fd58c000 {
++ compatible = "rockchip,rk3588-sys-grf", "syscon";
++ reg = <0x0 0xfd58c000 0x0 0x1000>;
++ };
++
++ vop_grf: syscon@fd5a4000 {
++ compatible = "rockchip,rk3588-vop-grf", "syscon";
++ reg = <0x0 0xfd5a4000 0x0 0x2000>;
++ };
++
++ vo0_grf: syscon@fd5a6000 {
++ compatible = "rockchip,rk3588-vo-grf", "syscon";
++ reg = <0x0 0xfd5a6000 0x0 0x2000>;
++ clocks = <&cru PCLK_VO0GRF>;
++ };
++
++ vo1_grf: syscon@fd5a8000 {
++ compatible = "rockchip,rk3588-vo-grf", "syscon";
++ reg = <0x0 0xfd5a8000 0x0 0x100>;
++ clocks = <&cru PCLK_VO1GRF>;
++ };
++
++ usb_grf: syscon@fd5ac000 {
++ compatible = "rockchip,rk3588-usb-grf", "syscon";
++ reg = <0x0 0xfd5ac000 0x0 0x4000>;
++ };
++
++ php_grf: syscon@fd5b0000 {
++ compatible = "rockchip,rk3588-php-grf", "syscon";
++ reg = <0x0 0xfd5b0000 0x0 0x1000>;
++ };
++
++ pipe_phy0_grf: syscon@fd5bc000 {
++ compatible = "rockchip,rk3588-pipe-phy-grf", "syscon";
++ reg = <0x0 0xfd5bc000 0x0 0x100>;
++ };
++
++ pipe_phy2_grf: syscon@fd5c4000 {
++ compatible = "rockchip,rk3588-pipe-phy-grf", "syscon";
++ reg = <0x0 0xfd5c4000 0x0 0x100>;
++ };
++
++ usbdpphy0_grf: syscon@fd5c8000 {
++ compatible = "rockchip,rk3588-usbdpphy-grf", "syscon";
++ reg = <0x0 0xfd5c8000 0x0 0x4000>;
++ };
++
++ usb2phy0_grf: syscon@fd5d0000 {
++ compatible = "rockchip,rk3588-usb2phy-grf", "syscon", "simple-mfd";
++ reg = <0x0 0xfd5d0000 0x0 0x4000>;
++ #address-cells = <1>;
++ #size-cells = <1>;
++
++ u2phy0: usb2phy@0 {
++ compatible = "rockchip,rk3588-usb2phy";
++ reg = <0x0 0x10>;
++ #clock-cells = <0>;
++ clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>;
++ clock-names = "phyclk";
++ clock-output-names = "usb480m_phy0";
++ interrupts = <GIC_SPI 393 IRQ_TYPE_LEVEL_HIGH 0>;
++ resets = <&cru SRST_OTGPHY_U3_0>, <&cru SRST_P_USB2PHY_U3_0_GRF0>;
++ reset-names = "phy", "apb";
++ status = "disabled";
++
++ u2phy0_otg: otg-port {
++ #phy-cells = <0>;
++ status = "disabled";
++ };
++ };
++ };
++
++ usb2phy2_grf: syscon@fd5d8000 {
++ compatible = "rockchip,rk3588-usb2phy-grf", "syscon", "simple-mfd";
++ reg = <0x0 0xfd5d8000 0x0 0x4000>;
++ #address-cells = <1>;
++ #size-cells = <1>;
++
++ u2phy2: usb2phy@8000 {
++ compatible = "rockchip,rk3588-usb2phy";
++ reg = <0x8000 0x10>;
++ #clock-cells = <0>;
++ clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>;
++ clock-names = "phyclk";
++ clock-output-names = "usb480m_phy2";
++ interrupts = <GIC_SPI 391 IRQ_TYPE_LEVEL_HIGH 0>;
++ resets = <&cru SRST_OTGPHY_U2_0>, <&cru SRST_P_USB2PHY_U2_0_GRF0>;
++ reset-names = "phy", "apb";
++ status = "disabled";
++
++ u2phy2_host: host-port {
++ #phy-cells = <0>;
++ status = "disabled";
++ };
++ };
++ };
++
++ usb2phy3_grf: syscon@fd5dc000 {
++ compatible = "rockchip,rk3588-usb2phy-grf", "syscon", "simple-mfd";
++ reg = <0x0 0xfd5dc000 0x0 0x4000>;
++ #address-cells = <1>;
++ #size-cells = <1>;
++
++ u2phy3: usb2phy@c000 {
++ compatible = "rockchip,rk3588-usb2phy";
++ reg = <0xc000 0x10>;
++ #clock-cells = <0>;
++ clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>;
++ clock-names = "phyclk";
++ clock-output-names = "usb480m_phy3";
++ interrupts = <GIC_SPI 392 IRQ_TYPE_LEVEL_HIGH 0>;
++ resets = <&cru SRST_OTGPHY_U2_1>, <&cru SRST_P_USB2PHY_U2_1_GRF0>;
++ reset-names = "phy", "apb";
++ status = "disabled";
++
++ u2phy3_host: host-port {
++ #phy-cells = <0>;
++ status = "disabled";
++ };
++ };
++ };
++
++ hdptxphy0_grf: syscon@fd5e0000 {
++ compatible = "rockchip,rk3588-hdptxphy-grf", "syscon";
++ reg = <0x0 0xfd5e0000 0x0 0x100>;
++ };
++
++ ioc: syscon@fd5f0000 {
++ compatible = "rockchip,rk3588-ioc", "syscon";
++ reg = <0x0 0xfd5f0000 0x0 0x10000>;
++ };
++
++ system_sram1: sram@fd600000 {
++ compatible = "mmio-sram";
++ reg = <0x0 0xfd600000 0x0 0x100000>;
++ ranges = <0x0 0x0 0xfd600000 0x100000>;
++ #address-cells = <1>;
++ #size-cells = <1>;
++ };
++
++ cru: clock-controller@fd7c0000 {
++ compatible = "rockchip,rk3588-cru";
++ reg = <0x0 0xfd7c0000 0x0 0x5c000>;
++ assigned-clocks =
++ <&cru PLL_PPLL>, <&cru PLL_AUPLL>,
++ <&cru PLL_NPLL>, <&cru PLL_GPLL>,
++ <&cru ACLK_CENTER_ROOT>,
++ <&cru HCLK_CENTER_ROOT>, <&cru ACLK_CENTER_LOW_ROOT>,
++ <&cru ACLK_TOP_ROOT>, <&cru PCLK_TOP_ROOT>,
++ <&cru ACLK_LOW_TOP_ROOT>, <&cru PCLK_PMU0_ROOT>,
++ <&cru HCLK_PMU_CM0_ROOT>, <&cru ACLK_VOP>,
++ <&cru ACLK_BUS_ROOT>, <&cru CLK_150M_SRC>,
++ <&cru CLK_GPU>;
++ assigned-clock-rates =
++ <1100000000>, <786432000>,
++ <850000000>, <1188000000>,
++ <702000000>,
++ <400000000>, <500000000>,
++ <800000000>, <100000000>,
++ <400000000>, <100000000>,
++ <200000000>, <500000000>,
++ <375000000>, <150000000>,
++ <200000000>;
++ rockchip,grf = <&php_grf>;
++ #clock-cells = <1>;
++ #reset-cells = <1>;
++ };
++
++ i2c0: i2c@fd880000 {
++ compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
++ reg = <0x0 0xfd880000 0x0 0x1000>;
++ interrupts = <GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru CLK_I2C0>, <&cru PCLK_I2C0>;
++ clock-names = "i2c", "pclk";
++ pinctrl-0 = <&i2c0m0_xfer>;
++ pinctrl-names = "default";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ uart0: serial@fd890000 {
++ compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
++ reg = <0x0 0xfd890000 0x0 0x100>;
++ interrupts = <GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru SCLK_UART0>, <&cru PCLK_UART0>;
++ clock-names = "baudclk", "apb_pclk";
++ dmas = <&dmac0 6>, <&dmac0 7>;
++ dma-names = "tx", "rx";
++ pinctrl-0 = <&uart0m1_xfer>;
++ pinctrl-names = "default";
++ reg-shift = <2>;
++ reg-io-width = <4>;
++ status = "disabled";
++ };
++
++ pwm0: pwm@fd8b0000 {
++ compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
++ reg = <0x0 0xfd8b0000 0x0 0x10>;
++ clocks = <&cru CLK_PMU1PWM>, <&cru PCLK_PMU1PWM>;
++ clock-names = "pwm", "pclk";
++ pinctrl-0 = <&pwm0m0_pins>;
++ pinctrl-names = "default";
++ #pwm-cells = <3>;
++ status = "disabled";
++ };
++
++ pwm1: pwm@fd8b0010 {
++ compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
++ reg = <0x0 0xfd8b0010 0x0 0x10>;
++ clocks = <&cru CLK_PMU1PWM>, <&cru PCLK_PMU1PWM>;
++ clock-names = "pwm", "pclk";
++ pinctrl-0 = <&pwm1m0_pins>;
++ pinctrl-names = "default";
++ #pwm-cells = <3>;
++ status = "disabled";
++ };
++
++ pwm2: pwm@fd8b0020 {
++ compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
++ reg = <0x0 0xfd8b0020 0x0 0x10>;
++ clocks = <&cru CLK_PMU1PWM>, <&cru PCLK_PMU1PWM>;
++ clock-names = "pwm", "pclk";
++ pinctrl-0 = <&pwm2m0_pins>;
++ pinctrl-names = "default";
++ #pwm-cells = <3>;
++ status = "disabled";
++ };
++
++ pwm3: pwm@fd8b0030 {
++ compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
++ reg = <0x0 0xfd8b0030 0x0 0x10>;
++ clocks = <&cru CLK_PMU1PWM>, <&cru PCLK_PMU1PWM>;
++ clock-names = "pwm", "pclk";
++ pinctrl-0 = <&pwm3m0_pins>;
++ pinctrl-names = "default";
++ #pwm-cells = <3>;
++ status = "disabled";
++ };
++
++ pmu: power-management@fd8d8000 {
++ compatible = "rockchip,rk3588-pmu", "syscon", "simple-mfd";
++ reg = <0x0 0xfd8d8000 0x0 0x400>;
++
++ power: power-controller {
++ compatible = "rockchip,rk3588-power-controller";
++ #address-cells = <1>;
++ #power-domain-cells = <1>;
++ #size-cells = <0>;
++ status = "okay";
++
++ /* These power domains are grouped by VD_NPU */
++ power-domain@RK3588_PD_NPU {
++ reg = <RK3588_PD_NPU>;
++ #power-domain-cells = <0>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ power-domain@RK3588_PD_NPUTOP {
++ reg = <RK3588_PD_NPUTOP>;
++ clocks = <&cru HCLK_NPU_ROOT>,
++ <&cru PCLK_NPU_ROOT>,
++ <&cru CLK_NPU_DSU0>,
++ <&cru HCLK_NPU_CM0_ROOT>;
++ pm_qos = <&qos_npu0_mwr>,
++ <&qos_npu0_mro>,
++ <&qos_mcu_npu>;
++ #power-domain-cells = <0>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ power-domain@RK3588_PD_NPU1 {
++ reg = <RK3588_PD_NPU1>;
++ clocks = <&cru HCLK_NPU_ROOT>,
++ <&cru PCLK_NPU_ROOT>,
++ <&cru CLK_NPU_DSU0>;
++ pm_qos = <&qos_npu1>;
++ #power-domain-cells = <0>;
++ };
++ power-domain@RK3588_PD_NPU2 {
++ reg = <RK3588_PD_NPU2>;
++ clocks = <&cru HCLK_NPU_ROOT>,
++ <&cru PCLK_NPU_ROOT>,
++ <&cru CLK_NPU_DSU0>;
++ pm_qos = <&qos_npu2>;
++ #power-domain-cells = <0>;
++ };
++ };
++ };
++ /* These power domains are grouped by VD_GPU */
++ power-domain@RK3588_PD_GPU {
++ reg = <RK3588_PD_GPU>;
++ clocks = <&cru CLK_GPU>,
++ <&cru CLK_GPU_COREGROUP>,
++ <&cru CLK_GPU_STACKS>;
++ pm_qos = <&qos_gpu_m0>,
++ <&qos_gpu_m1>,
++ <&qos_gpu_m2>,
++ <&qos_gpu_m3>;
++ #power-domain-cells = <0>;
++ };
++ /* These power domains are grouped by VD_VCODEC */
++ power-domain@RK3588_PD_VCODEC {
++ reg = <RK3588_PD_VCODEC>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ #power-domain-cells = <0>;
++
++ power-domain@RK3588_PD_RKVDEC0 {
++ reg = <RK3588_PD_RKVDEC0>;
++ clocks = <&cru HCLK_RKVDEC0>,
++ <&cru HCLK_VDPU_ROOT>,
++ <&cru ACLK_VDPU_ROOT>,
++ <&cru ACLK_RKVDEC0>,
++ <&cru ACLK_RKVDEC_CCU>;
++ pm_qos = <&qos_rkvdec0>;
++ #power-domain-cells = <0>;
++ };
++ power-domain@RK3588_PD_RKVDEC1 {
++ reg = <RK3588_PD_RKVDEC1>;
++ clocks = <&cru HCLK_RKVDEC1>,
++ <&cru HCLK_VDPU_ROOT>,
++ <&cru ACLK_VDPU_ROOT>,
++ <&cru ACLK_RKVDEC1>;
++ pm_qos = <&qos_rkvdec1>;
++ #power-domain-cells = <0>;
++ };
++ power-domain@RK3588_PD_VENC0 {
++ reg = <RK3588_PD_VENC0>;
++ clocks = <&cru HCLK_RKVENC0>,
++ <&cru ACLK_RKVENC0>;
++ pm_qos = <&qos_rkvenc0_m0ro>,
++ <&qos_rkvenc0_m1ro>,
++ <&qos_rkvenc0_m2wo>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ #power-domain-cells = <0>;
++
++ power-domain@RK3588_PD_VENC1 {
++ reg = <RK3588_PD_VENC1>;
++ clocks = <&cru HCLK_RKVENC1>,
++ <&cru HCLK_RKVENC0>,
++ <&cru ACLK_RKVENC0>,
++ <&cru ACLK_RKVENC1>;
++ pm_qos = <&qos_rkvenc1_m0ro>,
++ <&qos_rkvenc1_m1ro>,
++ <&qos_rkvenc1_m2wo>;
++ #power-domain-cells = <0>;
++ };
++ };
++ };
++ /* These power domains are grouped by VD_LOGIC */
++ power-domain@RK3588_PD_VDPU {
++ reg = <RK3588_PD_VDPU>;
++ clocks = <&cru HCLK_VDPU_ROOT>,
++ <&cru ACLK_VDPU_LOW_ROOT>,
++ <&cru ACLK_VDPU_ROOT>,
++ <&cru ACLK_JPEG_DECODER_ROOT>,
++ <&cru ACLK_IEP2P0>,
++ <&cru HCLK_IEP2P0>,
++ <&cru ACLK_JPEG_ENCODER0>,
++ <&cru HCLK_JPEG_ENCODER0>,
++ <&cru ACLK_JPEG_ENCODER1>,
++ <&cru HCLK_JPEG_ENCODER1>,
++ <&cru ACLK_JPEG_ENCODER2>,
++ <&cru HCLK_JPEG_ENCODER2>,
++ <&cru ACLK_JPEG_ENCODER3>,
++ <&cru HCLK_JPEG_ENCODER3>,
++ <&cru ACLK_JPEG_DECODER>,
++ <&cru HCLK_JPEG_DECODER>,
++ <&cru ACLK_RGA2>,
++ <&cru HCLK_RGA2>;
++ pm_qos = <&qos_iep>,
++ <&qos_jpeg_dec>,
++ <&qos_jpeg_enc0>,
++ <&qos_jpeg_enc1>,
++ <&qos_jpeg_enc2>,
++ <&qos_jpeg_enc3>,
++ <&qos_rga2_mro>,
++ <&qos_rga2_mwo>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ #power-domain-cells = <0>;
++
++
++ power-domain@RK3588_PD_AV1 {
++ reg = <RK3588_PD_AV1>;
++ clocks = <&cru PCLK_AV1>,
++ <&cru ACLK_AV1>,
++ <&cru HCLK_VDPU_ROOT>;
++ pm_qos = <&qos_av1>;
++ #power-domain-cells = <0>;
++ };
++ power-domain@RK3588_PD_RKVDEC0 {
++ reg = <RK3588_PD_RKVDEC0>;
++ clocks = <&cru HCLK_RKVDEC0>,
++ <&cru HCLK_VDPU_ROOT>,
++ <&cru ACLK_VDPU_ROOT>,
++ <&cru ACLK_RKVDEC0>;
++ pm_qos = <&qos_rkvdec0>;
++ #power-domain-cells = <0>;
++ };
++ power-domain@RK3588_PD_RKVDEC1 {
++ reg = <RK3588_PD_RKVDEC1>;
++ clocks = <&cru HCLK_RKVDEC1>,
++ <&cru HCLK_VDPU_ROOT>,
++ <&cru ACLK_VDPU_ROOT>;
++ pm_qos = <&qos_rkvdec1>;
++ #power-domain-cells = <0>;
++ };
++ power-domain@RK3588_PD_RGA30 {
++ reg = <RK3588_PD_RGA30>;
++ clocks = <&cru ACLK_RGA3_0>,
++ <&cru HCLK_RGA3_0>;
++ pm_qos = <&qos_rga3_0>;
++ #power-domain-cells = <0>;
++ };
++ };
++ power-domain@RK3588_PD_VOP {
++ reg = <RK3588_PD_VOP>;
++ clocks = <&cru PCLK_VOP_ROOT>,
++ <&cru HCLK_VOP_ROOT>,
++ <&cru ACLK_VOP>;
++ pm_qos = <&qos_vop_m0>,
++ <&qos_vop_m1>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ #power-domain-cells = <0>;
++
++ power-domain@RK3588_PD_VO0 {
++ reg = <RK3588_PD_VO0>;
++ clocks = <&cru PCLK_VO0_ROOT>,
++ <&cru PCLK_VO0_S_ROOT>,
++ <&cru HCLK_VO0_S_ROOT>,
++ <&cru ACLK_VO0_ROOT>,
++ <&cru HCLK_HDCP0>,
++ <&cru ACLK_HDCP0>,
++ <&cru HCLK_VOP_ROOT>;
++ pm_qos = <&qos_hdcp0>;
++ #power-domain-cells = <0>;
++ };
++ };
++ power-domain@RK3588_PD_VO1 {
++ reg = <RK3588_PD_VO1>;
++ clocks = <&cru PCLK_VO1_ROOT>,
++ <&cru PCLK_VO1_S_ROOT>,
++ <&cru HCLK_VO1_S_ROOT>,
++ <&cru HCLK_HDCP1>,
++ <&cru ACLK_HDCP1>,
++ <&cru ACLK_HDMIRX_ROOT>,
++ <&cru HCLK_VO1USB_TOP_ROOT>;
++ pm_qos = <&qos_hdcp1>,
++ <&qos_hdmirx>;
++ #power-domain-cells = <0>;
++ };
++ power-domain@RK3588_PD_VI {
++ reg = <RK3588_PD_VI>;
++ clocks = <&cru HCLK_VI_ROOT>,
++ <&cru PCLK_VI_ROOT>,
++ <&cru HCLK_ISP0>,
++ <&cru ACLK_ISP0>,
++ <&cru HCLK_VICAP>,
++ <&cru ACLK_VICAP>;
++ pm_qos = <&qos_isp0_mro>,
++ <&qos_isp0_mwo>,
++ <&qos_vicap_m0>,
++ <&qos_vicap_m1>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ #power-domain-cells = <0>;
++
++ power-domain@RK3588_PD_ISP1 {
++ reg = <RK3588_PD_ISP1>;
++ clocks = <&cru HCLK_ISP1>,
++ <&cru ACLK_ISP1>,
++ <&cru HCLK_VI_ROOT>,
++ <&cru PCLK_VI_ROOT>;
++ pm_qos = <&qos_isp1_mwo>,
++ <&qos_isp1_mro>;
++ #power-domain-cells = <0>;
++ };
++ power-domain@RK3588_PD_FEC {
++ reg = <RK3588_PD_FEC>;
++ clocks = <&cru HCLK_FISHEYE0>,
++ <&cru ACLK_FISHEYE0>,
++ <&cru HCLK_FISHEYE1>,
++ <&cru ACLK_FISHEYE1>,
++ <&cru PCLK_VI_ROOT>;
++ pm_qos = <&qos_fisheye0>,
++ <&qos_fisheye1>;
++ #power-domain-cells = <0>;
++ };
++ };
++ power-domain@RK3588_PD_RGA31 {
++ reg = <RK3588_PD_RGA31>;
++ clocks = <&cru HCLK_RGA3_1>,
++ <&cru ACLK_RGA3_1>;
++ pm_qos = <&qos_rga3_1>;
++ #power-domain-cells = <0>;
++ };
++ power-domain@RK3588_PD_USB {
++ reg = <RK3588_PD_USB>;
++ clocks = <&cru PCLK_PHP_ROOT>,
++ <&cru ACLK_USB_ROOT>,
++ <&cru ACLK_USB>,
++ <&cru HCLK_USB_ROOT>,
++ <&cru HCLK_HOST0>,
++ <&cru HCLK_HOST_ARB0>,
++ <&cru HCLK_HOST1>,
++ <&cru HCLK_HOST_ARB1>;
++ pm_qos = <&qos_usb3_0>,
++ <&qos_usb3_1>,
++ <&qos_usb2host_0>,
++ <&qos_usb2host_1>;
++ #power-domain-cells = <0>;
++ };
++ power-domain@RK3588_PD_GMAC {
++ reg = <RK3588_PD_GMAC>;
++ clocks = <&cru PCLK_PHP_ROOT>,
++ <&cru ACLK_PCIE_ROOT>,
++ <&cru ACLK_PHP_ROOT>;
++ #power-domain-cells = <0>;
++ };
++ power-domain@RK3588_PD_PCIE {
++ reg = <RK3588_PD_PCIE>;
++ clocks = <&cru PCLK_PHP_ROOT>,
++ <&cru ACLK_PCIE_ROOT>,
++ <&cru ACLK_PHP_ROOT>;
++ #power-domain-cells = <0>;
++ };
++ power-domain@RK3588_PD_SDIO {
++ reg = <RK3588_PD_SDIO>;
++ clocks = <&cru HCLK_SDIO>,
++ <&cru HCLK_NVM_ROOT>;
++ pm_qos = <&qos_sdio>;
++ #power-domain-cells = <0>;
++ };
++ power-domain@RK3588_PD_AUDIO {
++ reg = <RK3588_PD_AUDIO>;
++ clocks = <&cru HCLK_AUDIO_ROOT>,
++ <&cru PCLK_AUDIO_ROOT>;
++ #power-domain-cells = <0>;
++ };
++ power-domain@RK3588_PD_SDMMC {
++ reg = <RK3588_PD_SDMMC>;
++ pm_qos = <&qos_sdmmc>;
++ #power-domain-cells = <0>;
++ };
++ };
++ };
++
++ av1d: video-codec@fdc70000 {
++ compatible = "rockchip,rk3588-av1-vpu";
++ reg = <0x0 0xfdc70000 0x0 0x800>;
++ interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH 0>;
++ interrupt-names = "vdpu";
++ assigned-clocks = <&cru ACLK_AV1>, <&cru PCLK_AV1>;
++ assigned-clock-rates = <400000000>, <400000000>;
++ clocks = <&cru ACLK_AV1>, <&cru PCLK_AV1>;
++ clock-names = "aclk", "hclk";
++ power-domains = <&power RK3588_PD_AV1>;
++ resets = <&cru SRST_A_AV1>, <&cru SRST_P_AV1>, <&cru SRST_A_AV1_BIU>, <&cru SRST_P_AV1_BIU>;
++ };
++
++ vop: vop@fdd90000 {
++ compatible = "rockchip,rk3588-vop";
++ reg = <0x0 0xfdd90000 0x0 0x4200>, <0x0 0xfdd95000 0x0 0x1000>;
++ reg-names = "vop", "gamma-lut";
++ interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru ACLK_VOP>,
++ <&cru HCLK_VOP>,
++ <&cru DCLK_VOP0>,
++ <&cru DCLK_VOP1>,
++ <&cru DCLK_VOP2>,
++ <&cru DCLK_VOP3>,
++ <&cru PCLK_VOP_ROOT>;
++ clock-names = "aclk",
++ "hclk",
++ "dclk_vp0",
++ "dclk_vp1",
++ "dclk_vp2",
++ "dclk_vp3",
++ "pclk_vop";
++ iommus = <&vop_mmu>;
++ power-domains = <&power RK3588_PD_VOP>;
++ rockchip,grf = <&sys_grf>;
++ rockchip,vop-grf = <&vop_grf>;
++ rockchip,vo1-grf = <&vo1_grf>;
++ rockchip,pmu = <&pmu>;
++ status = "disabled";
++
++ vop_out: ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ vp0: port@0 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0>;
++ };
++
++ vp1: port@1 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <1>;
++ };
++
++ vp2: port@2 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <2>;
++ };
++
++ vp3: port@3 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <3>;
++ };
++ };
++ };
++
++ vop_mmu: iommu@fdd97e00 {
++ compatible = "rockchip,rk3588-iommu", "rockchip,rk3568-iommu";
++ reg = <0x0 0xfdd97e00 0x0 0x100>, <0x0 0xfdd97f00 0x0 0x100>;
++ interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru ACLK_VOP>, <&cru HCLK_VOP>;
++ clock-names = "aclk", "iface";
++ #iommu-cells = <0>;
++ power-domains = <&power RK3588_PD_VOP>;
++ status = "disabled";
++ };
++
++ i2s4_8ch: i2s@fddc0000 {
++ compatible = "rockchip,rk3588-i2s-tdm";
++ reg = <0x0 0xfddc0000 0x0 0x1000>;
++ interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru MCLK_I2S4_8CH_TX>, <&cru MCLK_I2S4_8CH_TX>, <&cru HCLK_I2S4_8CH>;
++ clock-names = "mclk_tx", "mclk_rx", "hclk";
++ assigned-clocks = <&cru CLK_I2S4_8CH_TX_SRC>;
++ assigned-clock-parents = <&cru PLL_AUPLL>;
++ dmas = <&dmac2 0>;
++ dma-names = "tx";
++ power-domains = <&power RK3588_PD_VO0>;
++ resets = <&cru SRST_M_I2S4_8CH_TX>;
++ reset-names = "tx-m";
++ #sound-dai-cells = <0>;
++ status = "disabled";
++ };
++
++ i2s5_8ch: i2s@fddf0000 {
++ compatible = "rockchip,rk3588-i2s-tdm";
++ reg = <0x0 0xfddf0000 0x0 0x1000>;
++ interrupts = <GIC_SPI 185 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru MCLK_I2S5_8CH_TX>, <&cru MCLK_I2S5_8CH_TX>, <&cru HCLK_I2S5_8CH>;
++ clock-names = "mclk_tx", "mclk_rx", "hclk";
++ assigned-clocks = <&cru CLK_I2S5_8CH_TX_SRC>;
++ assigned-clock-parents = <&cru PLL_AUPLL>;
++ dmas = <&dmac2 2>;
++ dma-names = "tx";
++ power-domains = <&power RK3588_PD_VO1>;
++ resets = <&cru SRST_M_I2S5_8CH_TX>;
++ reset-names = "tx-m";
++ #sound-dai-cells = <0>;
++ status = "disabled";
++ };
++
++ i2s9_8ch: i2s@fddfc000 {
++ compatible = "rockchip,rk3588-i2s-tdm";
++ reg = <0x0 0xfddfc000 0x0 0x1000>;
++ interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru MCLK_I2S9_8CH_RX>, <&cru MCLK_I2S9_8CH_RX>, <&cru HCLK_I2S9_8CH>;
++ clock-names = "mclk_tx", "mclk_rx", "hclk";
++ assigned-clocks = <&cru CLK_I2S9_8CH_RX_SRC>;
++ assigned-clock-parents = <&cru PLL_AUPLL>;
++ dmas = <&dmac2 23>;
++ dma-names = "rx";
++ power-domains = <&power RK3588_PD_VO1>;
++ resets = <&cru SRST_M_I2S9_8CH_RX>;
++ reset-names = "rx-m";
++ #sound-dai-cells = <0>;
++ status = "disabled";
++ };
++
++ qos_gpu_m0: qos@fdf35000 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf35000 0x0 0x20>;
++ };
++
++ qos_gpu_m1: qos@fdf35200 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf35200 0x0 0x20>;
++ };
++
++ qos_gpu_m2: qos@fdf35400 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf35400 0x0 0x20>;
++ };
++
++ qos_gpu_m3: qos@fdf35600 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf35600 0x0 0x20>;
++ };
++
++ qos_rga3_1: qos@fdf36000 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf36000 0x0 0x20>;
++ };
++
++ qos_sdio: qos@fdf39000 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf39000 0x0 0x20>;
++ };
++
++ qos_sdmmc: qos@fdf3d800 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf3d800 0x0 0x20>;
++ };
++
++ qos_usb3_1: qos@fdf3e000 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf3e000 0x0 0x20>;
++ };
++
++ qos_usb3_0: qos@fdf3e200 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf3e200 0x0 0x20>;
++ };
++
++ qos_usb2host_0: qos@fdf3e400 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf3e400 0x0 0x20>;
++ };
++
++ qos_usb2host_1: qos@fdf3e600 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf3e600 0x0 0x20>;
++ };
++
++ qos_fisheye0: qos@fdf40000 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf40000 0x0 0x20>;
++ };
++
++ qos_fisheye1: qos@fdf40200 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf40200 0x0 0x20>;
++ };
++
++ qos_isp0_mro: qos@fdf40400 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf40400 0x0 0x20>;
++ };
++
++ qos_isp0_mwo: qos@fdf40500 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf40500 0x0 0x20>;
++ };
++
++ qos_vicap_m0: qos@fdf40600 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf40600 0x0 0x20>;
++ };
++
++ qos_vicap_m1: qos@fdf40800 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf40800 0x0 0x20>;
++ };
++
++ qos_isp1_mwo: qos@fdf41000 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf41000 0x0 0x20>;
++ };
++
++ qos_isp1_mro: qos@fdf41100 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf41100 0x0 0x20>;
++ };
++
++ qos_rkvenc0_m0ro: qos@fdf60000 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf60000 0x0 0x20>;
++ };
++
++ qos_rkvenc0_m1ro: qos@fdf60200 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf60200 0x0 0x20>;
++ };
++
++ qos_rkvenc0_m2wo: qos@fdf60400 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf60400 0x0 0x20>;
++ };
++
++ qos_rkvenc1_m0ro: qos@fdf61000 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf61000 0x0 0x20>;
++ };
++
++ qos_rkvenc1_m1ro: qos@fdf61200 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf61200 0x0 0x20>;
++ };
++
++ qos_rkvenc1_m2wo: qos@fdf61400 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf61400 0x0 0x20>;
++ };
++
++ qos_rkvdec0: qos@fdf62000 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf62000 0x0 0x20>;
++ };
++
++ qos_rkvdec1: qos@fdf63000 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf63000 0x0 0x20>;
++ };
++
++ qos_av1: qos@fdf64000 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf64000 0x0 0x20>;
++ };
++
++ qos_iep: qos@fdf66000 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf66000 0x0 0x20>;
++ };
++
++ qos_jpeg_dec: qos@fdf66200 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf66200 0x0 0x20>;
++ };
++
++ qos_jpeg_enc0: qos@fdf66400 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf66400 0x0 0x20>;
++ };
++
++ qos_jpeg_enc1: qos@fdf66600 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf66600 0x0 0x20>;
++ };
++
++ qos_jpeg_enc2: qos@fdf66800 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf66800 0x0 0x20>;
++ };
++
++ qos_jpeg_enc3: qos@fdf66a00 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf66a00 0x0 0x20>;
++ };
++
++ qos_rga2_mro: qos@fdf66c00 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf66c00 0x0 0x20>;
++ };
++
++ qos_rga2_mwo: qos@fdf66e00 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf66e00 0x0 0x20>;
++ };
++
++ qos_rga3_0: qos@fdf67000 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf67000 0x0 0x20>;
++ };
++
++ qos_vdpu: qos@fdf67200 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf67200 0x0 0x20>;
++ };
++
++ qos_npu1: qos@fdf70000 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf70000 0x0 0x20>;
++ };
++
++ qos_npu2: qos@fdf71000 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf71000 0x0 0x20>;
++ };
++
++ qos_npu0_mwr: qos@fdf72000 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf72000 0x0 0x20>;
++ };
++
++ qos_npu0_mro: qos@fdf72200 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf72200 0x0 0x20>;
++ };
++
++ qos_mcu_npu: qos@fdf72400 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf72400 0x0 0x20>;
++ };
++
++ qos_hdcp0: qos@fdf80000 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf80000 0x0 0x20>;
++ };
++
++ qos_hdcp1: qos@fdf81000 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf81000 0x0 0x20>;
++ };
++
++ qos_hdmirx: qos@fdf81200 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf81200 0x0 0x20>;
++ };
++
++ qos_vop_m0: qos@fdf82000 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf82000 0x0 0x20>;
++ };
++
++ qos_vop_m1: qos@fdf82200 {
++ compatible = "rockchip,rk3588-qos", "syscon";
++ reg = <0x0 0xfdf82200 0x0 0x20>;
++ };
++
++ dfi: dfi@fe060000 {
++ reg = <0x00 0xfe060000 0x00 0x10000>;
++ compatible = "rockchip,rk3588-dfi";
++ interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH 0>;
++ rockchip,pmu = <&pmu1grf>;
++ };
++
++ pcie2x1l1: pcie@fe180000 {
++ compatible = "rockchip,rk3588-pcie", "rockchip,rk3568-pcie";
++ bus-range = <0x30 0x3f>;
++ clocks = <&cru ACLK_PCIE_1L1_MSTR>, <&cru ACLK_PCIE_1L1_SLV>,
++ <&cru ACLK_PCIE_1L1_DBI>, <&cru PCLK_PCIE_1L1>,
++ <&cru CLK_PCIE_AUX3>, <&cru CLK_PCIE1L1_PIPE>;
++ clock-names = "aclk_mst", "aclk_slv",
++ "aclk_dbi", "pclk",
++ "aux", "pipe";
++ device_type = "pci";
++ interrupts = <GIC_SPI 248 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 247 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 245 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 244 IRQ_TYPE_LEVEL_HIGH 0>;
++ interrupt-names = "sys", "pmc", "msg", "legacy", "err";
++ #interrupt-cells = <1>;
++ interrupt-map-mask = <0 0 0 7>;
++ interrupt-map = <0 0 0 1 &pcie2x1l1_intc 0>,
++ <0 0 0 2 &pcie2x1l1_intc 1>,
++ <0 0 0 3 &pcie2x1l1_intc 2>,
++ <0 0 0 4 &pcie2x1l1_intc 3>;
++ linux,pci-domain = <3>;
++ max-link-speed = <2>;
++ msi-map = <0x3000 &its0 0x3000 0x1000>;
++ num-lanes = <1>;
++ phys = <&combphy2_psu PHY_TYPE_PCIE>;
++ phy-names = "pcie-phy";
++ power-domains = <&power RK3588_PD_PCIE>;
++ ranges = <0x01000000 0x0 0xf3100000 0x0 0xf3100000 0x0 0x00100000>,
++ <0x02000000 0x0 0xf3200000 0x0 0xf3200000 0x0 0x00e00000>,
++ <0x03000000 0x0 0x40000000 0x9 0xc0000000 0x0 0x40000000>;
++ reg = <0xa 0x40c00000 0x0 0x00400000>,
++ <0x0 0xfe180000 0x0 0x00010000>,
++ <0x0 0xf3000000 0x0 0x00100000>;
++ reg-names = "dbi", "apb", "config";
++ resets = <&cru SRST_PCIE3_POWER_UP>, <&cru SRST_P_PCIE3>;
++ reset-names = "pwr", "pipe";
++ #address-cells = <3>;
++ #size-cells = <2>;
++ status = "disabled";
++
++ pcie2x1l1_intc: legacy-interrupt-controller {
++ interrupt-controller;
++ #address-cells = <0>;
++ #interrupt-cells = <1>;
++ interrupt-parent = <&gic>;
++ interrupts = <GIC_SPI 245 IRQ_TYPE_EDGE_RISING 0>;
++ };
++ };
++
++ pcie2x1l2: pcie@fe190000 {
++ compatible = "rockchip,rk3588-pcie", "rockchip,rk3568-pcie";
++ bus-range = <0x40 0x4f>;
++ clocks = <&cru ACLK_PCIE_1L2_MSTR>, <&cru ACLK_PCIE_1L2_SLV>,
++ <&cru ACLK_PCIE_1L2_DBI>, <&cru PCLK_PCIE_1L2>,
++ <&cru CLK_PCIE_AUX4>, <&cru CLK_PCIE1L2_PIPE>;
++ clock-names = "aclk_mst", "aclk_slv",
++ "aclk_dbi", "pclk",
++ "aux", "pipe";
++ device_type = "pci";
++ interrupts = <GIC_SPI 253 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 252 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 251 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 250 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 249 IRQ_TYPE_LEVEL_HIGH 0>;
++ interrupt-names = "sys", "pmc", "msg", "legacy", "err";
++ #interrupt-cells = <1>;
++ interrupt-map-mask = <0 0 0 7>;
++ interrupt-map = <0 0 0 1 &pcie2x1l2_intc 0>,
++ <0 0 0 2 &pcie2x1l2_intc 1>,
++ <0 0 0 3 &pcie2x1l2_intc 2>,
++ <0 0 0 4 &pcie2x1l2_intc 3>;
++ linux,pci-domain = <4>;
++ max-link-speed = <2>;
++ msi-map = <0x4000 &its0 0x4000 0x1000>;
++ num-lanes = <1>;
++ phys = <&combphy0_ps PHY_TYPE_PCIE>;
++ phy-names = "pcie-phy";
++ power-domains = <&power RK3588_PD_PCIE>;
++ ranges = <0x01000000 0x0 0xf4100000 0x0 0xf4100000 0x0 0x00100000>,
++ <0x02000000 0x0 0xf4200000 0x0 0xf4200000 0x0 0x00e00000>,
++ <0x03000000 0x0 0x40000000 0xa 0x00000000 0x0 0x40000000>;
++ reg = <0xa 0x41000000 0x0 0x00400000>,
++ <0x0 0xfe190000 0x0 0x00010000>,
++ <0x0 0xf4000000 0x0 0x00100000>;
++ reg-names = "dbi", "apb", "config";
++ resets = <&cru SRST_PCIE4_POWER_UP>, <&cru SRST_P_PCIE4>;
++ reset-names = "pwr", "pipe";
++ #address-cells = <3>;
++ #size-cells = <2>;
++ status = "disabled";
++
++ pcie2x1l2_intc: legacy-interrupt-controller {
++ interrupt-controller;
++ #address-cells = <0>;
++ #interrupt-cells = <1>;
++ interrupt-parent = <&gic>;
++ interrupts = <GIC_SPI 250 IRQ_TYPE_EDGE_RISING 0>;
++ };
++ };
++
++ gmac1: ethernet@fe1c0000 {
++ compatible = "rockchip,rk3588-gmac", "snps,dwmac-4.20a";
++ reg = <0x0 0xfe1c0000 0x0 0x10000>;
++ interrupts = <GIC_SPI 234 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 233 IRQ_TYPE_LEVEL_HIGH 0>;
++ interrupt-names = "macirq", "eth_wake_irq";
++ clocks = <&cru CLK_GMAC_125M>, <&cru CLK_GMAC_50M>,
++ <&cru PCLK_GMAC1>, <&cru ACLK_GMAC1>,
++ <&cru CLK_GMAC1_PTP_REF>;
++ clock-names = "stmmaceth", "clk_mac_ref",
++ "pclk_mac", "aclk_mac",
++ "ptp_ref";
++ power-domains = <&power RK3588_PD_GMAC>;
++ resets = <&cru SRST_A_GMAC1>;
++ reset-names = "stmmaceth";
++ rockchip,grf = <&sys_grf>;
++ rockchip,php-grf = <&php_grf>;
++ snps,axi-config = <&gmac1_stmmac_axi_setup>;
++ snps,mixed-burst;
++ snps,mtl-rx-config = <&gmac1_mtl_rx_setup>;
++ snps,mtl-tx-config = <&gmac1_mtl_tx_setup>;
++ snps,tso;
++ status = "disabled";
++
++ mdio1: mdio {
++ compatible = "snps,dwmac-mdio";
++ #address-cells = <0x1>;
++ #size-cells = <0x0>;
++ };
++
++ gmac1_stmmac_axi_setup: stmmac-axi-config {
++ snps,blen = <0 0 0 0 16 8 4>;
++ snps,wr_osr_lmt = <4>;
++ snps,rd_osr_lmt = <8>;
++ };
++
++ gmac1_mtl_rx_setup: rx-queues-config {
++ snps,rx-queues-to-use = <2>;
++ queue0 {};
++ queue1 {};
++ };
++
++ gmac1_mtl_tx_setup: tx-queues-config {
++ snps,tx-queues-to-use = <2>;
++ queue0 {};
++ queue1 {};
++ };
++ };
++
++ sata0: sata@fe210000 {
++ compatible = "rockchip,rk3588-dwc-ahci", "snps,dwc-ahci";
++ reg = <0 0xfe210000 0 0x1000>;
++ interrupts = <GIC_SPI 273 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru ACLK_SATA0>, <&cru CLK_PMALIVE0>,
++ <&cru CLK_RXOOB0>, <&cru CLK_PIPEPHY0_REF>,
++ <&cru CLK_PIPEPHY0_PIPE_ASIC_G>;
++ clock-names = "sata", "pmalive", "rxoob", "ref", "asic";
++ ports-implemented = <0x1>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++
++ sata-port@0 {
++ reg = <0>;
++ hba-port-cap = <HBA_PORT_FBSCP>;
++ phys = <&combphy0_ps PHY_TYPE_SATA>;
++ phy-names = "sata-phy";
++ snps,rx-ts-max = <32>;
++ snps,tx-ts-max = <32>;
++ };
++ };
++
++ sata2: sata@fe230000 {
++ compatible = "rockchip,rk3588-dwc-ahci", "snps,dwc-ahci";
++ reg = <0 0xfe230000 0 0x1000>;
++ interrupts = <GIC_SPI 275 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru ACLK_SATA2>, <&cru CLK_PMALIVE2>,
++ <&cru CLK_RXOOB2>, <&cru CLK_PIPEPHY2_REF>,
++ <&cru CLK_PIPEPHY2_PIPE_ASIC_G>;
++ clock-names = "sata", "pmalive", "rxoob", "ref", "asic";
++ ports-implemented = <0x1>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++
++ sata-port@0 {
++ reg = <0>;
++ hba-port-cap = <HBA_PORT_FBSCP>;
++ phys = <&combphy2_psu PHY_TYPE_SATA>;
++ phy-names = "sata-phy";
++ snps,rx-ts-max = <32>;
++ snps,tx-ts-max = <32>;
++ };
++ };
++
++ sfc: spi@fe2b0000 {
++ compatible = "rockchip,sfc";
++ reg = <0x0 0xfe2b0000 0x0 0x4000>;
++ interrupts = <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru SCLK_SFC>, <&cru HCLK_SFC>;
++ clock-names = "clk_sfc", "hclk_sfc";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ sdmmc: mmc@fe2c0000 {
++ compatible = "rockchip,rk3588-dw-mshc", "rockchip,rk3288-dw-mshc";
++ reg = <0x0 0xfe2c0000 0x0 0x4000>;
++ interrupts = <GIC_SPI 203 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&scmi_clk SCMI_HCLK_SD>, <&scmi_clk SCMI_CCLK_SD>,
++ <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>;
++ clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
++ fifo-depth = <0x100>;
++ max-frequency = <200000000>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_det &sdmmc_bus4>;
++ power-domains = <&power RK3588_PD_SDMMC>;
++ status = "disabled";
++ };
++
++ sdio: mmc@fe2d0000 {
++ compatible = "rockchip,rk3588-dw-mshc", "rockchip,rk3288-dw-mshc";
++ reg = <0x00 0xfe2d0000 0x00 0x4000>;
++ interrupts = <GIC_SPI 204 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru HCLK_SDIO>, <&cru CCLK_SRC_SDIO>,
++ <&cru SCLK_SDIO_DRV>, <&cru SCLK_SDIO_SAMPLE>;
++ clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
++ fifo-depth = <0x100>;
++ max-frequency = <200000000>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdiom1_pins>;
++ power-domains = <&power RK3588_PD_SDIO>;
++ status = "disabled";
++ };
++
++ sdhci: mmc@fe2e0000 {
++ compatible = "rockchip,rk3588-dwcmshc";
++ reg = <0x0 0xfe2e0000 0x0 0x10000>;
++ interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH 0>;
++ assigned-clocks = <&cru BCLK_EMMC>, <&cru TMCLK_EMMC>, <&cru CCLK_EMMC>;
++ assigned-clock-rates = <200000000>, <24000000>, <200000000>;
++ clocks = <&cru CCLK_EMMC>, <&cru HCLK_EMMC>,
++ <&cru ACLK_EMMC>, <&cru BCLK_EMMC>,
++ <&cru TMCLK_EMMC>;
++ clock-names = "core", "bus", "axi", "block", "timer";
++ max-frequency = <200000000>;
++ pinctrl-0 = <&emmc_rstnout>, <&emmc_bus8>, <&emmc_clk>,
++ <&emmc_cmd>, <&emmc_data_strobe>;
++ pinctrl-names = "default";
++ resets = <&cru SRST_C_EMMC>, <&cru SRST_H_EMMC>,
++ <&cru SRST_A_EMMC>, <&cru SRST_B_EMMC>,
++ <&cru SRST_T_EMMC>;
++ reset-names = "core", "bus", "axi", "block", "timer";
++ status = "disabled";
++ };
++
++ i2s0_8ch: i2s@fe470000 {
++ compatible = "rockchip,rk3588-i2s-tdm";
++ reg = <0x0 0xfe470000 0x0 0x1000>;
++ interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru MCLK_I2S0_8CH_TX>, <&cru MCLK_I2S0_8CH_RX>, <&cru HCLK_I2S0_8CH>;
++ clock-names = "mclk_tx", "mclk_rx", "hclk";
++ assigned-clocks = <&cru CLK_I2S0_8CH_TX_SRC>, <&cru CLK_I2S0_8CH_RX_SRC>;
++ assigned-clock-parents = <&cru PLL_AUPLL>, <&cru PLL_AUPLL>;
++ dmas = <&dmac0 0>, <&dmac0 1>;
++ dma-names = "tx", "rx";
++ power-domains = <&power RK3588_PD_AUDIO>;
++ resets = <&cru SRST_M_I2S0_8CH_TX>, <&cru SRST_M_I2S0_8CH_RX>;
++ reset-names = "tx-m", "rx-m";
++ rockchip,trcm-sync-tx-only;
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2s0_lrck
++ &i2s0_sclk
++ &i2s0_sdi0
++ &i2s0_sdi1
++ &i2s0_sdi2
++ &i2s0_sdi3
++ &i2s0_sdo0
++ &i2s0_sdo1
++ &i2s0_sdo2
++ &i2s0_sdo3>;
++ #sound-dai-cells = <0>;
++ status = "disabled";
++ };
++
++ i2s1_8ch: i2s@fe480000 {
++ compatible = "rockchip,rk3588-i2s-tdm";
++ reg = <0x0 0xfe480000 0x0 0x1000>;
++ interrupts = <GIC_SPI 181 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru MCLK_I2S1_8CH_TX>, <&cru MCLK_I2S1_8CH_RX>, <&cru HCLK_I2S1_8CH>;
++ clock-names = "mclk_tx", "mclk_rx", "hclk";
++ dmas = <&dmac0 2>, <&dmac0 3>;
++ dma-names = "tx", "rx";
++ resets = <&cru SRST_M_I2S1_8CH_TX>, <&cru SRST_M_I2S1_8CH_RX>;
++ reset-names = "tx-m", "rx-m";
++ rockchip,trcm-sync-tx-only;
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2s1m0_lrck
++ &i2s1m0_sclk
++ &i2s1m0_sdi0
++ &i2s1m0_sdi1
++ &i2s1m0_sdi2
++ &i2s1m0_sdi3
++ &i2s1m0_sdo0
++ &i2s1m0_sdo1
++ &i2s1m0_sdo2
++ &i2s1m0_sdo3>;
++ #sound-dai-cells = <0>;
++ status = "disabled";
++ };
++
++ i2s2_2ch: i2s@fe490000 {
++ compatible = "rockchip,rk3588-i2s", "rockchip,rk3066-i2s";
++ reg = <0x0 0xfe490000 0x0 0x1000>;
++ interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru MCLK_I2S2_2CH>, <&cru HCLK_I2S2_2CH>;
++ clock-names = "i2s_clk", "i2s_hclk";
++ assigned-clocks = <&cru CLK_I2S2_2CH_SRC>;
++ assigned-clock-parents = <&cru PLL_AUPLL>;
++ dmas = <&dmac1 0>, <&dmac1 1>;
++ dma-names = "tx", "rx";
++ power-domains = <&power RK3588_PD_AUDIO>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2s2m1_lrck
++ &i2s2m1_sclk
++ &i2s2m1_sdi
++ &i2s2m1_sdo>;
++ #sound-dai-cells = <0>;
++ status = "disabled";
++ };
++
++ i2s3_2ch: i2s@fe4a0000 {
++ compatible = "rockchip,rk3588-i2s", "rockchip,rk3066-i2s";
++ reg = <0x0 0xfe4a0000 0x0 0x1000>;
++ interrupts = <GIC_SPI 183 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru MCLK_I2S3_2CH>, <&cru HCLK_I2S3_2CH>;
++ clock-names = "i2s_clk", "i2s_hclk";
++ assigned-clocks = <&cru CLK_I2S3_2CH_SRC>;
++ assigned-clock-parents = <&cru PLL_AUPLL>;
++ dmas = <&dmac1 2>, <&dmac1 3>;
++ dma-names = "tx", "rx";
++ power-domains = <&power RK3588_PD_AUDIO>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2s3_lrck
++ &i2s3_sclk
++ &i2s3_sdi
++ &i2s3_sdo>;
++ #sound-dai-cells = <0>;
++ status = "disabled";
++ };
++
++ gic: interrupt-controller@fe600000 {
++ compatible = "arm,gic-v3";
++ reg = <0x0 0xfe600000 0 0x10000>, /* GICD */
++ <0x0 0xfe680000 0 0x100000>; /* GICR */
++ interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH 0>;
++ interrupt-controller;
++ mbi-alias = <0x0 0xfe610000>;
++ mbi-ranges = <424 56>;
++ msi-controller;
++ ranges;
++ #address-cells = <2>;
++ #interrupt-cells = <4>;
++ #size-cells = <2>;
++
++ its0: msi-controller@fe640000 {
++ compatible = "arm,gic-v3-its";
++ reg = <0x0 0xfe640000 0x0 0x20000>;
++ msi-controller;
++ #msi-cells = <1>;
++ };
++
++ its1: msi-controller@fe660000 {
++ compatible = "arm,gic-v3-its";
++ reg = <0x0 0xfe660000 0x0 0x20000>;
++ msi-controller;
++ #msi-cells = <1>;
++ };
++
++ ppi-partitions {
++ ppi_partition0: interrupt-partition-0 {
++ affinity = <&cpu_l0 &cpu_l1 &cpu_l2 &cpu_l3>;
++ };
++
++ ppi_partition1: interrupt-partition-1 {
++ affinity = <&cpu_b0 &cpu_b1 &cpu_b2 &cpu_b3>;
++ };
++ };
++ };
++
++ dmac0: dma-controller@fea10000 {
++ compatible = "arm,pl330", "arm,primecell";
++ reg = <0x0 0xfea10000 0x0 0x4000>;
++ interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH 0>;
++ arm,pl330-periph-burst;
++ clocks = <&cru ACLK_DMAC0>;
++ clock-names = "apb_pclk";
++ #dma-cells = <1>;
++ };
++
++ dmac1: dma-controller@fea30000 {
++ compatible = "arm,pl330", "arm,primecell";
++ reg = <0x0 0xfea30000 0x0 0x4000>;
++ interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH 0>;
++ arm,pl330-periph-burst;
++ clocks = <&cru ACLK_DMAC1>;
++ clock-names = "apb_pclk";
++ #dma-cells = <1>;
++ };
++
++ i2c1: i2c@fea90000 {
++ compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
++ reg = <0x0 0xfea90000 0x0 0x1000>;
++ clocks = <&cru CLK_I2C1>, <&cru PCLK_I2C1>;
++ clock-names = "i2c", "pclk";
++ interrupts = <GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH 0>;
++ pinctrl-0 = <&i2c1m0_xfer>;
++ pinctrl-names = "default";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ i2c2: i2c@feaa0000 {
++ compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
++ reg = <0x0 0xfeaa0000 0x0 0x1000>;
++ clocks = <&cru CLK_I2C2>, <&cru PCLK_I2C2>;
++ clock-names = "i2c", "pclk";
++ interrupts = <GIC_SPI 319 IRQ_TYPE_LEVEL_HIGH 0>;
++ pinctrl-0 = <&i2c2m0_xfer>;
++ pinctrl-names = "default";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ i2c3: i2c@feab0000 {
++ compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
++ reg = <0x0 0xfeab0000 0x0 0x1000>;
++ clocks = <&cru CLK_I2C3>, <&cru PCLK_I2C3>;
++ clock-names = "i2c", "pclk";
++ interrupts = <GIC_SPI 320 IRQ_TYPE_LEVEL_HIGH 0>;
++ pinctrl-0 = <&i2c3m0_xfer>;
++ pinctrl-names = "default";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ i2c4: i2c@feac0000 {
++ compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
++ reg = <0x0 0xfeac0000 0x0 0x1000>;
++ clocks = <&cru CLK_I2C4>, <&cru PCLK_I2C4>;
++ clock-names = "i2c", "pclk";
++ interrupts = <GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH 0>;
++ pinctrl-0 = <&i2c4m0_xfer>;
++ pinctrl-names = "default";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ i2c5: i2c@fead0000 {
++ compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
++ reg = <0x0 0xfead0000 0x0 0x1000>;
++ clocks = <&cru CLK_I2C5>, <&cru PCLK_I2C5>;
++ clock-names = "i2c", "pclk";
++ interrupts = <GIC_SPI 322 IRQ_TYPE_LEVEL_HIGH 0>;
++ pinctrl-0 = <&i2c5m0_xfer>;
++ pinctrl-names = "default";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ timer0: timer@feae0000 {
++ compatible = "rockchip,rk3588-timer", "rockchip,rk3288-timer";
++ reg = <0x0 0xfeae0000 0x0 0x20>;
++ interrupts = <GIC_SPI 289 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru PCLK_BUSTIMER0>, <&cru CLK_BUSTIMER0>;
++ clock-names = "pclk", "timer";
++ };
++
++ wdt: watchdog@feaf0000 {
++ compatible = "rockchip,rk3588-wdt", "snps,dw-wdt";
++ reg = <0x0 0xfeaf0000 0x0 0x100>;
++ clocks = <&cru TCLK_WDT0>, <&cru PCLK_WDT0>;
++ clock-names = "tclk", "pclk";
++ interrupts = <GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH 0>;
++ };
++
++ spi0: spi@feb00000 {
++ compatible = "rockchip,rk3588-spi", "rockchip,rk3066-spi";
++ reg = <0x0 0xfeb00000 0x0 0x1000>;
++ interrupts = <GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru CLK_SPI0>, <&cru PCLK_SPI0>;
++ clock-names = "spiclk", "apb_pclk";
++ dmas = <&dmac0 14>, <&dmac0 15>;
++ dma-names = "tx", "rx";
++ num-cs = <2>;
++ pinctrl-0 = <&spi0m0_cs0 &spi0m0_cs1 &spi0m0_pins>;
++ pinctrl-names = "default";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ spi1: spi@feb10000 {
++ compatible = "rockchip,rk3588-spi", "rockchip,rk3066-spi";
++ reg = <0x0 0xfeb10000 0x0 0x1000>;
++ interrupts = <GIC_SPI 327 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru CLK_SPI1>, <&cru PCLK_SPI1>;
++ clock-names = "spiclk", "apb_pclk";
++ dmas = <&dmac0 16>, <&dmac0 17>;
++ dma-names = "tx", "rx";
++ num-cs = <2>;
++ pinctrl-0 = <&spi1m1_cs0 &spi1m1_cs1 &spi1m1_pins>;
++ pinctrl-names = "default";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ spi2: spi@feb20000 {
++ compatible = "rockchip,rk3588-spi", "rockchip,rk3066-spi";
++ reg = <0x0 0xfeb20000 0x0 0x1000>;
++ interrupts = <GIC_SPI 328 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru CLK_SPI2>, <&cru PCLK_SPI2>;
++ clock-names = "spiclk", "apb_pclk";
++ dmas = <&dmac1 15>, <&dmac1 16>;
++ dma-names = "tx", "rx";
++ num-cs = <2>;
++ pinctrl-0 = <&spi2m2_cs0 &spi2m2_cs1 &spi2m2_pins>;
++ pinctrl-names = "default";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ spi3: spi@feb30000 {
++ compatible = "rockchip,rk3588-spi", "rockchip,rk3066-spi";
++ reg = <0x0 0xfeb30000 0x0 0x1000>;
++ interrupts = <GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru CLK_SPI3>, <&cru PCLK_SPI3>;
++ clock-names = "spiclk", "apb_pclk";
++ dmas = <&dmac1 17>, <&dmac1 18>;
++ dma-names = "tx", "rx";
++ num-cs = <2>;
++ pinctrl-0 = <&spi3m1_cs0 &spi3m1_cs1 &spi3m1_pins>;
++ pinctrl-names = "default";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ uart1: serial@feb40000 {
++ compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
++ reg = <0x0 0xfeb40000 0x0 0x100>;
++ interrupts = <GIC_SPI 332 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru SCLK_UART1>, <&cru PCLK_UART1>;
++ clock-names = "baudclk", "apb_pclk";
++ dmas = <&dmac0 8>, <&dmac0 9>;
++ dma-names = "tx", "rx";
++ pinctrl-0 = <&uart1m1_xfer>;
++ pinctrl-names = "default";
++ reg-io-width = <4>;
++ reg-shift = <2>;
++ status = "disabled";
++ };
++
++ uart2: serial@feb50000 {
++ compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
++ reg = <0x0 0xfeb50000 0x0 0x100>;
++ interrupts = <GIC_SPI 333 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>;
++ clock-names = "baudclk", "apb_pclk";
++ dmas = <&dmac0 10>, <&dmac0 11>;
++ dma-names = "tx", "rx";
++ pinctrl-0 = <&uart2m1_xfer>;
++ pinctrl-names = "default";
++ reg-io-width = <4>;
++ reg-shift = <2>;
++ status = "disabled";
++ };
++
++ uart3: serial@feb60000 {
++ compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
++ reg = <0x0 0xfeb60000 0x0 0x100>;
++ interrupts = <GIC_SPI 334 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru SCLK_UART3>, <&cru PCLK_UART3>;
++ clock-names = "baudclk", "apb_pclk";
++ dmas = <&dmac0 12>, <&dmac0 13>;
++ dma-names = "tx", "rx";
++ pinctrl-0 = <&uart3m1_xfer>;
++ pinctrl-names = "default";
++ reg-io-width = <4>;
++ reg-shift = <2>;
++ status = "disabled";
++ };
++
++ uart4: serial@feb70000 {
++ compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
++ reg = <0x0 0xfeb70000 0x0 0x100>;
++ interrupts = <GIC_SPI 335 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru SCLK_UART4>, <&cru PCLK_UART4>;
++ clock-names = "baudclk", "apb_pclk";
++ dmas = <&dmac1 9>, <&dmac1 10>;
++ dma-names = "tx", "rx";
++ pinctrl-0 = <&uart4m1_xfer>;
++ pinctrl-names = "default";
++ reg-io-width = <4>;
++ reg-shift = <2>;
++ status = "disabled";
++ };
++
++ uart5: serial@feb80000 {
++ compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
++ reg = <0x0 0xfeb80000 0x0 0x100>;
++ interrupts = <GIC_SPI 336 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru SCLK_UART5>, <&cru PCLK_UART5>;
++ clock-names = "baudclk", "apb_pclk";
++ dmas = <&dmac1 11>, <&dmac1 12>;
++ dma-names = "tx", "rx";
++ pinctrl-0 = <&uart5m1_xfer>;
++ pinctrl-names = "default";
++ reg-io-width = <4>;
++ reg-shift = <2>;
++ status = "disabled";
++ };
++
++ uart6: serial@feb90000 {
++ compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
++ reg = <0x0 0xfeb90000 0x0 0x100>;
++ interrupts = <GIC_SPI 337 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru SCLK_UART6>, <&cru PCLK_UART6>;
++ clock-names = "baudclk", "apb_pclk";
++ dmas = <&dmac1 13>, <&dmac1 14>;
++ dma-names = "tx", "rx";
++ pinctrl-0 = <&uart6m1_xfer>;
++ pinctrl-names = "default";
++ reg-io-width = <4>;
++ reg-shift = <2>;
++ status = "disabled";
++ };
++
++ uart7: serial@feba0000 {
++ compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
++ reg = <0x0 0xfeba0000 0x0 0x100>;
++ interrupts = <GIC_SPI 338 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru SCLK_UART7>, <&cru PCLK_UART7>;
++ clock-names = "baudclk", "apb_pclk";
++ dmas = <&dmac2 7>, <&dmac2 8>;
++ dma-names = "tx", "rx";
++ pinctrl-0 = <&uart7m1_xfer>;
++ pinctrl-names = "default";
++ reg-io-width = <4>;
++ reg-shift = <2>;
++ status = "disabled";
++ };
++
++ uart8: serial@febb0000 {
++ compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
++ reg = <0x0 0xfebb0000 0x0 0x100>;
++ interrupts = <GIC_SPI 339 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru SCLK_UART8>, <&cru PCLK_UART8>;
++ clock-names = "baudclk", "apb_pclk";
++ dmas = <&dmac2 9>, <&dmac2 10>;
++ dma-names = "tx", "rx";
++ pinctrl-0 = <&uart8m1_xfer>;
++ pinctrl-names = "default";
++ reg-io-width = <4>;
++ reg-shift = <2>;
++ status = "disabled";
++ };
++
++ uart9: serial@febc0000 {
++ compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
++ reg = <0x0 0xfebc0000 0x0 0x100>;
++ interrupts = <GIC_SPI 340 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru SCLK_UART9>, <&cru PCLK_UART9>;
++ clock-names = "baudclk", "apb_pclk";
++ dmas = <&dmac2 11>, <&dmac2 12>;
++ dma-names = "tx", "rx";
++ pinctrl-0 = <&uart9m1_xfer>;
++ pinctrl-names = "default";
++ reg-io-width = <4>;
++ reg-shift = <2>;
++ status = "disabled";
++ };
++
++ pwm4: pwm@febd0000 {
++ compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
++ reg = <0x0 0xfebd0000 0x0 0x10>;
++ clocks = <&cru CLK_PWM1>, <&cru PCLK_PWM1>;
++ clock-names = "pwm", "pclk";
++ pinctrl-0 = <&pwm4m0_pins>;
++ pinctrl-names = "default";
++ #pwm-cells = <3>;
++ status = "disabled";
++ };
++
++ pwm5: pwm@febd0010 {
++ compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
++ reg = <0x0 0xfebd0010 0x0 0x10>;
++ clocks = <&cru CLK_PWM1>, <&cru PCLK_PWM1>;
++ clock-names = "pwm", "pclk";
++ pinctrl-0 = <&pwm5m0_pins>;
++ pinctrl-names = "default";
++ #pwm-cells = <3>;
++ status = "disabled";
++ };
++
++ pwm6: pwm@febd0020 {
++ compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
++ reg = <0x0 0xfebd0020 0x0 0x10>;
++ clocks = <&cru CLK_PWM1>, <&cru PCLK_PWM1>;
++ clock-names = "pwm", "pclk";
++ pinctrl-0 = <&pwm6m0_pins>;
++ pinctrl-names = "default";
++ #pwm-cells = <3>;
++ status = "disabled";
++ };
++
++ pwm7: pwm@febd0030 {
++ compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
++ reg = <0x0 0xfebd0030 0x0 0x10>;
++ clocks = <&cru CLK_PWM1>, <&cru PCLK_PWM1>;
++ clock-names = "pwm", "pclk";
++ pinctrl-0 = <&pwm7m0_pins>;
++ pinctrl-names = "default";
++ #pwm-cells = <3>;
++ status = "disabled";
++ };
++
++ pwm8: pwm@febe0000 {
++ compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
++ reg = <0x0 0xfebe0000 0x0 0x10>;
++ clocks = <&cru CLK_PWM2>, <&cru PCLK_PWM2>;
++ clock-names = "pwm", "pclk";
++ pinctrl-0 = <&pwm8m0_pins>;
++ pinctrl-names = "default";
++ #pwm-cells = <3>;
++ status = "disabled";
++ };
++
++ pwm9: pwm@febe0010 {
++ compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
++ reg = <0x0 0xfebe0010 0x0 0x10>;
++ clocks = <&cru CLK_PWM2>, <&cru PCLK_PWM2>;
++ clock-names = "pwm", "pclk";
++ pinctrl-0 = <&pwm9m0_pins>;
++ pinctrl-names = "default";
++ #pwm-cells = <3>;
++ status = "disabled";
++ };
++
++ pwm10: pwm@febe0020 {
++ compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
++ reg = <0x0 0xfebe0020 0x0 0x10>;
++ clocks = <&cru CLK_PWM2>, <&cru PCLK_PWM2>;
++ clock-names = "pwm", "pclk";
++ pinctrl-0 = <&pwm10m0_pins>;
++ pinctrl-names = "default";
++ #pwm-cells = <3>;
++ status = "disabled";
++ };
++
++ pwm11: pwm@febe0030 {
++ compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
++ reg = <0x0 0xfebe0030 0x0 0x10>;
++ clocks = <&cru CLK_PWM2>, <&cru PCLK_PWM2>;
++ clock-names = "pwm", "pclk";
++ pinctrl-0 = <&pwm11m0_pins>;
++ pinctrl-names = "default";
++ #pwm-cells = <3>;
++ status = "disabled";
++ };
++
++ pwm12: pwm@febf0000 {
++ compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
++ reg = <0x0 0xfebf0000 0x0 0x10>;
++ clocks = <&cru CLK_PWM3>, <&cru PCLK_PWM3>;
++ clock-names = "pwm", "pclk";
++ pinctrl-0 = <&pwm12m0_pins>;
++ pinctrl-names = "default";
++ #pwm-cells = <3>;
++ status = "disabled";
++ };
++
++ pwm13: pwm@febf0010 {
++ compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
++ reg = <0x0 0xfebf0010 0x0 0x10>;
++ clocks = <&cru CLK_PWM3>, <&cru PCLK_PWM3>;
++ clock-names = "pwm", "pclk";
++ pinctrl-0 = <&pwm13m0_pins>;
++ pinctrl-names = "default";
++ #pwm-cells = <3>;
++ status = "disabled";
++ };
++
++ pwm14: pwm@febf0020 {
++ compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
++ reg = <0x0 0xfebf0020 0x0 0x10>;
++ clocks = <&cru CLK_PWM3>, <&cru PCLK_PWM3>;
++ clock-names = "pwm", "pclk";
++ pinctrl-0 = <&pwm14m0_pins>;
++ pinctrl-names = "default";
++ #pwm-cells = <3>;
++ status = "disabled";
++ };
++
++ pwm15: pwm@febf0030 {
++ compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
++ reg = <0x0 0xfebf0030 0x0 0x10>;
++ clocks = <&cru CLK_PWM3>, <&cru PCLK_PWM3>;
++ clock-names = "pwm", "pclk";
++ pinctrl-0 = <&pwm15m0_pins>;
++ pinctrl-names = "default";
++ #pwm-cells = <3>;
++ status = "disabled";
++ };
++
++ tsadc: tsadc@fec00000 {
++ compatible = "rockchip,rk3588-tsadc";
++ reg = <0x0 0xfec00000 0x0 0x400>;
++ interrupts = <GIC_SPI 397 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru CLK_TSADC>, <&cru PCLK_TSADC>;
++ clock-names = "tsadc", "apb_pclk";
++ assigned-clocks = <&cru CLK_TSADC>;
++ assigned-clock-rates = <2000000>;
++ resets = <&cru SRST_P_TSADC>, <&cru SRST_TSADC>;
++ reset-names = "tsadc-apb", "tsadc";
++ rockchip,hw-tshut-temp = <120000>;
++ rockchip,hw-tshut-mode = <0>; /* tshut mode 0:CRU 1:GPIO */
++ rockchip,hw-tshut-polarity = <0>; /* tshut polarity 0:LOW 1:HIGH */
++ pinctrl-0 = <&tsadc_gpio_func>;
++ pinctrl-1 = <&tsadc_shut>;
++ pinctrl-names = "gpio", "otpout";
++ #thermal-sensor-cells = <1>;
++ status = "disabled";
++ };
++
++ saradc: adc@fec10000 {
++ compatible = "rockchip,rk3588-saradc";
++ reg = <0x0 0xfec10000 0x0 0x10000>;
++ interrupts = <GIC_SPI 398 IRQ_TYPE_LEVEL_HIGH 0>;
++ #io-channel-cells = <1>;
++ clocks = <&cru CLK_SARADC>, <&cru PCLK_SARADC>;
++ clock-names = "saradc", "apb_pclk";
++ resets = <&cru SRST_P_SARADC>;
++ reset-names = "saradc-apb";
++ status = "disabled";
++ };
++
++ i2c6: i2c@fec80000 {
++ compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
++ reg = <0x0 0xfec80000 0x0 0x1000>;
++ clocks = <&cru CLK_I2C6>, <&cru PCLK_I2C6>;
++ clock-names = "i2c", "pclk";
++ interrupts = <GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH 0>;
++ pinctrl-0 = <&i2c6m0_xfer>;
++ pinctrl-names = "default";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ i2c7: i2c@fec90000 {
++ compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
++ reg = <0x0 0xfec90000 0x0 0x1000>;
++ clocks = <&cru CLK_I2C7>, <&cru PCLK_I2C7>;
++ clock-names = "i2c", "pclk";
++ interrupts = <GIC_SPI 324 IRQ_TYPE_LEVEL_HIGH 0>;
++ pinctrl-0 = <&i2c7m0_xfer>;
++ pinctrl-names = "default";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ i2c8: i2c@feca0000 {
++ compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
++ reg = <0x0 0xfeca0000 0x0 0x1000>;
++ clocks = <&cru CLK_I2C8>, <&cru PCLK_I2C8>;
++ clock-names = "i2c", "pclk";
++ interrupts = <GIC_SPI 325 IRQ_TYPE_LEVEL_HIGH 0>;
++ pinctrl-0 = <&i2c8m0_xfer>;
++ pinctrl-names = "default";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ spi4: spi@fecb0000 {
++ compatible = "rockchip,rk3588-spi", "rockchip,rk3066-spi";
++ reg = <0x0 0xfecb0000 0x0 0x1000>;
++ interrupts = <GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru CLK_SPI4>, <&cru PCLK_SPI4>;
++ clock-names = "spiclk", "apb_pclk";
++ dmas = <&dmac2 13>, <&dmac2 14>;
++ dma-names = "tx", "rx";
++ num-cs = <2>;
++ pinctrl-0 = <&spi4m0_cs0 &spi4m0_cs1 &spi4m0_pins>;
++ pinctrl-names = "default";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ otp: efuse@fecc0000 {
++ compatible = "rockchip,rk3588-otp";
++ reg = <0x0 0xfecc0000 0x0 0x400>;
++ clocks = <&cru CLK_OTPC_NS>, <&cru PCLK_OTPC_NS>,
++ <&cru CLK_OTP_PHY_G>, <&cru CLK_OTPC_ARB>;
++ clock-names = "otp", "apb_pclk", "phy", "arb";
++ resets = <&cru SRST_OTPC_NS>, <&cru SRST_P_OTPC_NS>,
++ <&cru SRST_OTPC_ARB>;
++ reset-names = "otp", "apb", "arb";
++ #address-cells = <1>;
++ #size-cells = <1>;
++
++ cpu_code: cpu-code@2 {
++ reg = <0x02 0x2>;
++ };
++
++ otp_id: id@7 {
++ reg = <0x07 0x10>;
++ };
++
++ cpub0_leakage: cpu-leakage@17 {
++ reg = <0x17 0x1>;
++ };
++
++ cpub1_leakage: cpu-leakage@18 {
++ reg = <0x18 0x1>;
++ };
++
++ cpul_leakage: cpu-leakage@19 {
++ reg = <0x19 0x1>;
++ };
++
++ log_leakage: log-leakage@1a {
++ reg = <0x1a 0x1>;
++ };
++
++ gpu_leakage: gpu-leakage@1b {
++ reg = <0x1b 0x1>;
++ };
++
++ otp_cpu_version: cpu-version@1c {
++ reg = <0x1c 0x1>;
++ bits = <3 3>;
++ };
++
++ npu_leakage: npu-leakage@28 {
++ reg = <0x28 0x1>;
++ };
++
++ codec_leakage: codec-leakage@29 {
++ reg = <0x29 0x1>;
++ };
++ };
++
++ dmac2: dma-controller@fed10000 {
++ compatible = "arm,pl330", "arm,primecell";
++ reg = <0x0 0xfed10000 0x0 0x4000>;
++ interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH 0>;
++ arm,pl330-periph-burst;
++ clocks = <&cru ACLK_DMAC2>;
++ clock-names = "apb_pclk";
++ #dma-cells = <1>;
++ };
++
++ hdptxphy_hdmi0: phy@fed60000 {
++ compatible = "rockchip,rk3588-hdptx-phy";
++ reg = <0x0 0xfed60000 0x0 0x2000>;
++ clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>, <&cru PCLK_HDPTX0>;
++ clock-names = "ref", "apb";
++ #phy-cells = <0>;
++ resets = <&cru SRST_HDPTX0>, <&cru SRST_P_HDPTX0>,
++ <&cru SRST_HDPTX0_INIT>, <&cru SRST_HDPTX0_CMN>,
++ <&cru SRST_HDPTX0_LANE>, <&cru SRST_HDPTX0_ROPLL>,
++ <&cru SRST_HDPTX0_LCPLL>;
++ reset-names = "phy", "apb", "init", "cmn", "lane", "ropll",
++ "lcpll";
++ rockchip,grf = <&hdptxphy0_grf>;
++ status = "disabled";
++ };
++
++ usbdp_phy0: phy@fed80000 {
++ compatible = "rockchip,rk3588-usbdp-phy";
++ reg = <0x0 0xfed80000 0x0 0x10000>;
++ #phy-cells = <1>;
++ clocks = <&cru CLK_USBDPPHY_MIPIDCPPHY_REF>,
++ <&cru CLK_USBDP_PHY0_IMMORTAL>,
++ <&cru PCLK_USBDPPHY0>,
++ <&u2phy0>;
++ clock-names = "refclk", "immortal", "pclk", "utmi";
++ resets = <&cru SRST_USBDP_COMBO_PHY0_INIT>,
++ <&cru SRST_USBDP_COMBO_PHY0_CMN>,
++ <&cru SRST_USBDP_COMBO_PHY0_LANE>,
++ <&cru SRST_USBDP_COMBO_PHY0_PCS>,
++ <&cru SRST_P_USBDPPHY0>;
++ reset-names = "init", "cmn", "lane", "pcs_apb", "pma_apb";
++ rockchip,u2phy-grf = <&usb2phy0_grf>;
++ rockchip,usb-grf = <&usb_grf>;
++ rockchip,usbdpphy-grf = <&usbdpphy0_grf>;
++ rockchip,vo-grf = <&vo0_grf>;
++ status = "disabled";
++ };
++
++ combphy0_ps: phy@fee00000 {
++ compatible = "rockchip,rk3588-naneng-combphy";
++ reg = <0x0 0xfee00000 0x0 0x100>;
++ clocks = <&cru CLK_REF_PIPE_PHY0>, <&cru PCLK_PCIE_COMBO_PIPE_PHY0>,
++ <&cru PCLK_PHP_ROOT>;
++ clock-names = "ref", "apb", "pipe";
++ assigned-clocks = <&cru CLK_REF_PIPE_PHY0>;
++ assigned-clock-rates = <100000000>;
++ #phy-cells = <1>;
++ resets = <&cru SRST_REF_PIPE_PHY0>, <&cru SRST_P_PCIE2_PHY0>;
++ reset-names = "phy", "apb";
++ rockchip,pipe-grf = <&php_grf>;
++ rockchip,pipe-phy-grf = <&pipe_phy0_grf>;
++ status = "disabled";
++ };
++
++ combphy2_psu: phy@fee20000 {
++ compatible = "rockchip,rk3588-naneng-combphy";
++ reg = <0x0 0xfee20000 0x0 0x100>;
++ clocks = <&cru CLK_REF_PIPE_PHY2>, <&cru PCLK_PCIE_COMBO_PIPE_PHY2>,
++ <&cru PCLK_PHP_ROOT>;
++ clock-names = "ref", "apb", "pipe";
++ assigned-clocks = <&cru CLK_REF_PIPE_PHY2>;
++ assigned-clock-rates = <100000000>;
++ #phy-cells = <1>;
++ resets = <&cru SRST_REF_PIPE_PHY2>, <&cru SRST_P_PCIE2_PHY2>;
++ reset-names = "phy", "apb";
++ rockchip,pipe-grf = <&php_grf>;
++ rockchip,pipe-phy-grf = <&pipe_phy2_grf>;
++ status = "disabled";
++ };
++
++ system_sram2: sram@ff001000 {
++ compatible = "mmio-sram";
++ reg = <0x0 0xff001000 0x0 0xef000>;
++ ranges = <0x0 0x0 0xff001000 0xef000>;
++ #address-cells = <1>;
++ #size-cells = <1>;
++ };
++
++ pinctrl: pinctrl {
++ compatible = "rockchip,rk3588-pinctrl";
++ ranges;
++ rockchip,grf = <&ioc>;
++ #address-cells = <2>;
++ #size-cells = <2>;
++
++ gpio0: gpio@fd8a0000 {
++ compatible = "rockchip,gpio-bank";
++ reg = <0x0 0xfd8a0000 0x0 0x100>;
++ interrupts = <GIC_SPI 277 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru PCLK_GPIO0>, <&cru DBCLK_GPIO0>;
++ gpio-controller;
++ gpio-ranges = <&pinctrl 0 0 32>;
++ interrupt-controller;
++ #gpio-cells = <2>;
++ #interrupt-cells = <2>;
++ };
++
++ gpio1: gpio@fec20000 {
++ compatible = "rockchip,gpio-bank";
++ reg = <0x0 0xfec20000 0x0 0x100>;
++ interrupts = <GIC_SPI 278 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru PCLK_GPIO1>, <&cru DBCLK_GPIO1>;
++ gpio-controller;
++ gpio-ranges = <&pinctrl 0 32 32>;
++ interrupt-controller;
++ #gpio-cells = <2>;
++ #interrupt-cells = <2>;
++ };
++
++ gpio2: gpio@fec30000 {
++ compatible = "rockchip,gpio-bank";
++ reg = <0x0 0xfec30000 0x0 0x100>;
++ interrupts = <GIC_SPI 279 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru PCLK_GPIO2>, <&cru DBCLK_GPIO2>;
++ gpio-controller;
++ gpio-ranges = <&pinctrl 0 64 32>;
++ interrupt-controller;
++ #gpio-cells = <2>;
++ #interrupt-cells = <2>;
++ };
++
++ gpio3: gpio@fec40000 {
++ compatible = "rockchip,gpio-bank";
++ reg = <0x0 0xfec40000 0x0 0x100>;
++ interrupts = <GIC_SPI 280 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru PCLK_GPIO3>, <&cru DBCLK_GPIO3>;
++ gpio-controller;
++ gpio-ranges = <&pinctrl 0 96 32>;
++ interrupt-controller;
++ #gpio-cells = <2>;
++ #interrupt-cells = <2>;
++ };
++
++ gpio4: gpio@fec50000 {
++ compatible = "rockchip,gpio-bank";
++ reg = <0x0 0xfec50000 0x0 0x100>;
++ interrupts = <GIC_SPI 281 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru PCLK_GPIO4>, <&cru DBCLK_GPIO4>;
++ gpio-controller;
++ gpio-ranges = <&pinctrl 0 128 32>;
++ interrupt-controller;
++ #gpio-cells = <2>;
++ #interrupt-cells = <2>;
++ };
++ };
++};
++
++#include "rk3588-base-pinctrl.dtsi"
+--- /dev/null
++++ b/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi
+@@ -0,0 +1,413 @@
++// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
++/*
++ * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
++ */
++
++#include "rk3588-base.dtsi"
++#include "rk3588-extra-pinctrl.dtsi"
++
++/ {
++ usb_host1_xhci: usb@fc400000 {
++ compatible = "rockchip,rk3588-dwc3", "snps,dwc3";
++ reg = <0x0 0xfc400000 0x0 0x400000>;
++ interrupts = <GIC_SPI 221 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru REF_CLK_USB3OTG1>, <&cru SUSPEND_CLK_USB3OTG1>,
++ <&cru ACLK_USB3OTG1>;
++ clock-names = "ref_clk", "suspend_clk", "bus_clk";
++ dr_mode = "otg";
++ phys = <&u2phy1_otg>, <&usbdp_phy1 PHY_TYPE_USB3>;
++ phy-names = "usb2-phy", "usb3-phy";
++ phy_type = "utmi_wide";
++ power-domains = <&power RK3588_PD_USB>;
++ resets = <&cru SRST_A_USB3OTG1>;
++ snps,dis_enblslpm_quirk;
++ snps,dis-u2-freeclk-exists-quirk;
++ snps,dis-del-phy-power-chg-quirk;
++ snps,dis-tx-ipgap-linecheck-quirk;
++ status = "disabled";
++ };
++
++ pcie30_phy_grf: syscon@fd5b8000 {
++ compatible = "rockchip,rk3588-pcie3-phy-grf", "syscon";
++ reg = <0x0 0xfd5b8000 0x0 0x10000>;
++ };
++
++ pipe_phy1_grf: syscon@fd5c0000 {
++ compatible = "rockchip,rk3588-pipe-phy-grf", "syscon";
++ reg = <0x0 0xfd5c0000 0x0 0x100>;
++ };
++
++ usbdpphy1_grf: syscon@fd5cc000 {
++ compatible = "rockchip,rk3588-usbdpphy-grf", "syscon";
++ reg = <0x0 0xfd5cc000 0x0 0x4000>;
++ };
++
++ usb2phy1_grf: syscon@fd5d4000 {
++ compatible = "rockchip,rk3588-usb2phy-grf", "syscon", "simple-mfd";
++ reg = <0x0 0xfd5d4000 0x0 0x4000>;
++ #address-cells = <1>;
++ #size-cells = <1>;
++
++ u2phy1: usb2phy@4000 {
++ compatible = "rockchip,rk3588-usb2phy";
++ reg = <0x4000 0x10>;
++ #clock-cells = <0>;
++ clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>;
++ clock-names = "phyclk";
++ clock-output-names = "usb480m_phy1";
++ interrupts = <GIC_SPI 394 IRQ_TYPE_LEVEL_HIGH 0>;
++ resets = <&cru SRST_OTGPHY_U3_1>, <&cru SRST_P_USB2PHY_U3_1_GRF0>;
++ reset-names = "phy", "apb";
++ status = "disabled";
++
++ u2phy1_otg: otg-port {
++ #phy-cells = <0>;
++ status = "disabled";
++ };
++ };
++ };
++
++ i2s8_8ch: i2s@fddc8000 {
++ compatible = "rockchip,rk3588-i2s-tdm";
++ reg = <0x0 0xfddc8000 0x0 0x1000>;
++ interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru MCLK_I2S8_8CH_TX>, <&cru MCLK_I2S8_8CH_TX>, <&cru HCLK_I2S8_8CH>;
++ clock-names = "mclk_tx", "mclk_rx", "hclk";
++ assigned-clocks = <&cru CLK_I2S8_8CH_TX_SRC>;
++ assigned-clock-parents = <&cru PLL_AUPLL>;
++ dmas = <&dmac2 22>;
++ dma-names = "tx";
++ power-domains = <&power RK3588_PD_VO0>;
++ resets = <&cru SRST_M_I2S8_8CH_TX>;
++ reset-names = "tx-m";
++ #sound-dai-cells = <0>;
++ status = "disabled";
++ };
++
++ i2s6_8ch: i2s@fddf4000 {
++ compatible = "rockchip,rk3588-i2s-tdm";
++ reg = <0x0 0xfddf4000 0x0 0x1000>;
++ interrupts = <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru MCLK_I2S6_8CH_TX>, <&cru MCLK_I2S6_8CH_TX>, <&cru HCLK_I2S6_8CH>;
++ clock-names = "mclk_tx", "mclk_rx", "hclk";
++ assigned-clocks = <&cru CLK_I2S6_8CH_TX_SRC>;
++ assigned-clock-parents = <&cru PLL_AUPLL>;
++ dmas = <&dmac2 4>;
++ dma-names = "tx";
++ power-domains = <&power RK3588_PD_VO1>;
++ resets = <&cru SRST_M_I2S6_8CH_TX>;
++ reset-names = "tx-m";
++ #sound-dai-cells = <0>;
++ status = "disabled";
++ };
++
++ i2s7_8ch: i2s@fddf8000 {
++ compatible = "rockchip,rk3588-i2s-tdm";
++ reg = <0x0 0xfddf8000 0x0 0x1000>;
++ interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru MCLK_I2S7_8CH_RX>, <&cru MCLK_I2S7_8CH_RX>, <&cru HCLK_I2S7_8CH>;
++ clock-names = "mclk_tx", "mclk_rx", "hclk";
++ assigned-clocks = <&cru CLK_I2S7_8CH_RX_SRC>;
++ assigned-clock-parents = <&cru PLL_AUPLL>;
++ dmas = <&dmac2 21>;
++ dma-names = "rx";
++ power-domains = <&power RK3588_PD_VO1>;
++ resets = <&cru SRST_M_I2S7_8CH_RX>;
++ reset-names = "rx-m";
++ #sound-dai-cells = <0>;
++ status = "disabled";
++ };
++
++ i2s10_8ch: i2s@fde00000 {
++ compatible = "rockchip,rk3588-i2s-tdm";
++ reg = <0x0 0xfde00000 0x0 0x1000>;
++ interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru MCLK_I2S10_8CH_RX>, <&cru MCLK_I2S10_8CH_RX>, <&cru HCLK_I2S10_8CH>;
++ clock-names = "mclk_tx", "mclk_rx", "hclk";
++ assigned-clocks = <&cru CLK_I2S10_8CH_RX_SRC>;
++ assigned-clock-parents = <&cru PLL_AUPLL>;
++ dmas = <&dmac2 24>;
++ dma-names = "rx";
++ power-domains = <&power RK3588_PD_VO1>;
++ resets = <&cru SRST_M_I2S10_8CH_RX>;
++ reset-names = "rx-m";
++ #sound-dai-cells = <0>;
++ status = "disabled";
++ };
++
++ pcie3x4: pcie@fe150000 {
++ compatible = "rockchip,rk3588-pcie", "rockchip,rk3568-pcie";
++ #address-cells = <3>;
++ #size-cells = <2>;
++ bus-range = <0x00 0x0f>;
++ clocks = <&cru ACLK_PCIE_4L_MSTR>, <&cru ACLK_PCIE_4L_SLV>,
++ <&cru ACLK_PCIE_4L_DBI>, <&cru PCLK_PCIE_4L>,
++ <&cru CLK_PCIE_AUX0>, <&cru CLK_PCIE4L_PIPE>;
++ clock-names = "aclk_mst", "aclk_slv",
++ "aclk_dbi", "pclk",
++ "aux", "pipe";
++ device_type = "pci";
++ interrupts = <GIC_SPI 263 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 262 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 261 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 260 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 259 IRQ_TYPE_LEVEL_HIGH 0>;
++ interrupt-names = "sys", "pmc", "msg", "legacy", "err";
++ #interrupt-cells = <1>;
++ interrupt-map-mask = <0 0 0 7>;
++ interrupt-map = <0 0 0 1 &pcie3x4_intc 0>,
++ <0 0 0 2 &pcie3x4_intc 1>,
++ <0 0 0 3 &pcie3x4_intc 2>,
++ <0 0 0 4 &pcie3x4_intc 3>;
++ linux,pci-domain = <0>;
++ max-link-speed = <3>;
++ msi-map = <0x0000 &its1 0x0000 0x1000>;
++ num-lanes = <4>;
++ phys = <&pcie30phy>;
++ phy-names = "pcie-phy";
++ power-domains = <&power RK3588_PD_PCIE>;
++ ranges = <0x01000000 0x0 0xf0100000 0x0 0xf0100000 0x0 0x00100000>,
++ <0x02000000 0x0 0xf0200000 0x0 0xf0200000 0x0 0x00e00000>,
++ <0x03000000 0x0 0x40000000 0x9 0x00000000 0x0 0x40000000>;
++ reg = <0xa 0x40000000 0x0 0x00400000>,
++ <0x0 0xfe150000 0x0 0x00010000>,
++ <0x0 0xf0000000 0x0 0x00100000>;
++ reg-names = "dbi", "apb", "config";
++ resets = <&cru SRST_PCIE0_POWER_UP>, <&cru SRST_P_PCIE0>;
++ reset-names = "pwr", "pipe";
++ status = "disabled";
++
++ pcie3x4_intc: legacy-interrupt-controller {
++ interrupt-controller;
++ #address-cells = <0>;
++ #interrupt-cells = <1>;
++ interrupt-parent = <&gic>;
++ interrupts = <GIC_SPI 260 IRQ_TYPE_EDGE_RISING 0>;
++ };
++ };
++
++ pcie3x2: pcie@fe160000 {
++ compatible = "rockchip,rk3588-pcie", "rockchip,rk3568-pcie";
++ #address-cells = <3>;
++ #size-cells = <2>;
++ bus-range = <0x10 0x1f>;
++ clocks = <&cru ACLK_PCIE_2L_MSTR>, <&cru ACLK_PCIE_2L_SLV>,
++ <&cru ACLK_PCIE_2L_DBI>, <&cru PCLK_PCIE_2L>,
++ <&cru CLK_PCIE_AUX1>, <&cru CLK_PCIE2L_PIPE>;
++ clock-names = "aclk_mst", "aclk_slv",
++ "aclk_dbi", "pclk",
++ "aux", "pipe";
++ device_type = "pci";
++ interrupts = <GIC_SPI 258 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 257 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 255 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 254 IRQ_TYPE_LEVEL_HIGH 0>;
++ interrupt-names = "sys", "pmc", "msg", "legacy", "err";
++ #interrupt-cells = <1>;
++ interrupt-map-mask = <0 0 0 7>;
++ interrupt-map = <0 0 0 1 &pcie3x2_intc 0>,
++ <0 0 0 2 &pcie3x2_intc 1>,
++ <0 0 0 3 &pcie3x2_intc 2>,
++ <0 0 0 4 &pcie3x2_intc 3>;
++ linux,pci-domain = <1>;
++ max-link-speed = <3>;
++ msi-map = <0x1000 &its1 0x1000 0x1000>;
++ num-lanes = <2>;
++ phys = <&pcie30phy>;
++ phy-names = "pcie-phy";
++ power-domains = <&power RK3588_PD_PCIE>;
++ ranges = <0x01000000 0x0 0xf1100000 0x0 0xf1100000 0x0 0x00100000>,
++ <0x02000000 0x0 0xf1200000 0x0 0xf1200000 0x0 0x00e00000>,
++ <0x03000000 0x0 0x40000000 0x9 0x40000000 0x0 0x40000000>;
++ reg = <0xa 0x40400000 0x0 0x00400000>,
++ <0x0 0xfe160000 0x0 0x00010000>,
++ <0x0 0xf1000000 0x0 0x00100000>;
++ reg-names = "dbi", "apb", "config";
++ resets = <&cru SRST_PCIE1_POWER_UP>, <&cru SRST_P_PCIE1>;
++ reset-names = "pwr", "pipe";
++ status = "disabled";
++
++ pcie3x2_intc: legacy-interrupt-controller {
++ interrupt-controller;
++ #address-cells = <0>;
++ #interrupt-cells = <1>;
++ interrupt-parent = <&gic>;
++ interrupts = <GIC_SPI 255 IRQ_TYPE_EDGE_RISING 0>;
++ };
++ };
++
++ pcie2x1l0: pcie@fe170000 {
++ compatible = "rockchip,rk3588-pcie", "rockchip,rk3568-pcie";
++ bus-range = <0x20 0x2f>;
++ clocks = <&cru ACLK_PCIE_1L0_MSTR>, <&cru ACLK_PCIE_1L0_SLV>,
++ <&cru ACLK_PCIE_1L0_DBI>, <&cru PCLK_PCIE_1L0>,
++ <&cru CLK_PCIE_AUX2>, <&cru CLK_PCIE1L0_PIPE>;
++ clock-names = "aclk_mst", "aclk_slv",
++ "aclk_dbi", "pclk",
++ "aux", "pipe";
++ device_type = "pci";
++ interrupts = <GIC_SPI 243 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 242 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 241 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 239 IRQ_TYPE_LEVEL_HIGH 0>;
++ interrupt-names = "sys", "pmc", "msg", "legacy", "err";
++ #interrupt-cells = <1>;
++ interrupt-map-mask = <0 0 0 7>;
++ interrupt-map = <0 0 0 1 &pcie2x1l0_intc 0>,
++ <0 0 0 2 &pcie2x1l0_intc 1>,
++ <0 0 0 3 &pcie2x1l0_intc 2>,
++ <0 0 0 4 &pcie2x1l0_intc 3>;
++ linux,pci-domain = <2>;
++ max-link-speed = <2>;
++ msi-map = <0x2000 &its0 0x2000 0x1000>;
++ num-lanes = <1>;
++ phys = <&combphy1_ps PHY_TYPE_PCIE>;
++ phy-names = "pcie-phy";
++ power-domains = <&power RK3588_PD_PCIE>;
++ ranges = <0x01000000 0x0 0xf2100000 0x0 0xf2100000 0x0 0x00100000>,
++ <0x02000000 0x0 0xf2200000 0x0 0xf2200000 0x0 0x00e00000>,
++ <0x03000000 0x0 0x40000000 0x9 0x80000000 0x0 0x40000000>;
++ reg = <0xa 0x40800000 0x0 0x00400000>,
++ <0x0 0xfe170000 0x0 0x00010000>,
++ <0x0 0xf2000000 0x0 0x00100000>;
++ reg-names = "dbi", "apb", "config";
++ resets = <&cru SRST_PCIE2_POWER_UP>, <&cru SRST_P_PCIE2>;
++ reset-names = "pwr", "pipe";
++ #address-cells = <3>;
++ #size-cells = <2>;
++ status = "disabled";
++
++ pcie2x1l0_intc: legacy-interrupt-controller {
++ interrupt-controller;
++ #address-cells = <0>;
++ #interrupt-cells = <1>;
++ interrupt-parent = <&gic>;
++ interrupts = <GIC_SPI 240 IRQ_TYPE_EDGE_RISING 0>;
++ };
++ };
++
++ gmac0: ethernet@fe1b0000 {
++ compatible = "rockchip,rk3588-gmac", "snps,dwmac-4.20a";
++ reg = <0x0 0xfe1b0000 0x0 0x10000>;
++ interrupts = <GIC_SPI 227 IRQ_TYPE_LEVEL_HIGH 0>,
++ <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH 0>;
++ interrupt-names = "macirq", "eth_wake_irq";
++ clocks = <&cru CLK_GMAC_125M>, <&cru CLK_GMAC_50M>,
++ <&cru PCLK_GMAC0>, <&cru ACLK_GMAC0>,
++ <&cru CLK_GMAC0_PTP_REF>;
++ clock-names = "stmmaceth", "clk_mac_ref",
++ "pclk_mac", "aclk_mac",
++ "ptp_ref";
++ power-domains = <&power RK3588_PD_GMAC>;
++ resets = <&cru SRST_A_GMAC0>;
++ reset-names = "stmmaceth";
++ rockchip,grf = <&sys_grf>;
++ rockchip,php-grf = <&php_grf>;
++ snps,axi-config = <&gmac0_stmmac_axi_setup>;
++ snps,mixed-burst;
++ snps,mtl-rx-config = <&gmac0_mtl_rx_setup>;
++ snps,mtl-tx-config = <&gmac0_mtl_tx_setup>;
++ snps,tso;
++ status = "disabled";
++
++ mdio0: mdio {
++ compatible = "snps,dwmac-mdio";
++ #address-cells = <0x1>;
++ #size-cells = <0x0>;
++ };
++
++ gmac0_stmmac_axi_setup: stmmac-axi-config {
++ snps,blen = <0 0 0 0 16 8 4>;
++ snps,wr_osr_lmt = <4>;
++ snps,rd_osr_lmt = <8>;
++ };
++
++ gmac0_mtl_rx_setup: rx-queues-config {
++ snps,rx-queues-to-use = <2>;
++ queue0 {};
++ queue1 {};
++ };
++
++ gmac0_mtl_tx_setup: tx-queues-config {
++ snps,tx-queues-to-use = <2>;
++ queue0 {};
++ queue1 {};
++ };
++ };
++
++ sata1: sata@fe220000 {
++ compatible = "rockchip,rk3588-dwc-ahci", "snps,dwc-ahci";
++ reg = <0 0xfe220000 0 0x1000>;
++ interrupts = <GIC_SPI 274 IRQ_TYPE_LEVEL_HIGH 0>;
++ clocks = <&cru ACLK_SATA1>, <&cru CLK_PMALIVE1>,
++ <&cru CLK_RXOOB1>, <&cru CLK_PIPEPHY1_REF>,
++ <&cru CLK_PIPEPHY1_PIPE_ASIC_G>;
++ clock-names = "sata", "pmalive", "rxoob", "ref", "asic";
++ ports-implemented = <0x1>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++
++ sata-port@0 {
++ reg = <0>;
++ hba-port-cap = <HBA_PORT_FBSCP>;
++ phys = <&combphy1_ps PHY_TYPE_SATA>;
++ phy-names = "sata-phy";
++ snps,rx-ts-max = <32>;
++ snps,tx-ts-max = <32>;
++ };
++ };
++
++ usbdp_phy1: phy@fed90000 {
++ compatible = "rockchip,rk3588-usbdp-phy";
++ reg = <0x0 0xfed90000 0x0 0x10000>;
++ #phy-cells = <1>;
++ clocks = <&cru CLK_USBDPPHY_MIPIDCPPHY_REF>,
++ <&cru CLK_USBDP_PHY1_IMMORTAL>,
++ <&cru PCLK_USBDPPHY1>,
++ <&u2phy1>;
++ clock-names = "refclk", "immortal", "pclk", "utmi";
++ resets = <&cru SRST_USBDP_COMBO_PHY1_INIT>,
++ <&cru SRST_USBDP_COMBO_PHY1_CMN>,
++ <&cru SRST_USBDP_COMBO_PHY1_LANE>,
++ <&cru SRST_USBDP_COMBO_PHY1_PCS>,
++ <&cru SRST_P_USBDPPHY1>;
++ reset-names = "init", "cmn", "lane", "pcs_apb", "pma_apb";
++ rockchip,u2phy-grf = <&usb2phy1_grf>;
++ rockchip,usb-grf = <&usb_grf>;
++ rockchip,usbdpphy-grf = <&usbdpphy1_grf>;
++ rockchip,vo-grf = <&vo0_grf>;
++ status = "disabled";
++ };
++
++ combphy1_ps: phy@fee10000 {
++ compatible = "rockchip,rk3588-naneng-combphy";
++ reg = <0x0 0xfee10000 0x0 0x100>;
++ clocks = <&cru CLK_REF_PIPE_PHY1>, <&cru PCLK_PCIE_COMBO_PIPE_PHY1>,
++ <&cru PCLK_PHP_ROOT>;
++ clock-names = "ref", "apb", "pipe";
++ assigned-clocks = <&cru CLK_REF_PIPE_PHY1>;
++ assigned-clock-rates = <100000000>;
++ #phy-cells = <1>;
++ resets = <&cru SRST_REF_PIPE_PHY1>, <&cru SRST_P_PCIE2_PHY1>;
++ reset-names = "phy", "apb";
++ rockchip,pipe-grf = <&php_grf>;
++ rockchip,pipe-phy-grf = <&pipe_phy1_grf>;
++ status = "disabled";
++ };
++
++ pcie30phy: phy@fee80000 {
++ compatible = "rockchip,rk3588-pcie3-phy";
++ reg = <0x0 0xfee80000 0x0 0x20000>;
++ #phy-cells = <0>;
++ clocks = <&cru PCLK_PCIE_COMBO_PIPE_PHY>;
++ clock-names = "pclk";
++ resets = <&cru SRST_PCIE30_PHY>;
++ reset-names = "phy";
++ rockchip,pipe-grf = <&php_grf>;
++ rockchip,phy-grf = <&pcie30_phy_grf>;
++ status = "disabled";
++ };
++};
+--- a/arch/arm64/boot/dts/rockchip/rk3588.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588.dtsi
+@@ -1,413 +1,7 @@
+ // SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+ /*
+- * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
++ * Copyright (c) 2022 Rockchip Electronics Co., Ltd.
++ *
+ */
+
+-#include "rk3588s.dtsi"
+-#include "rk3588-pinctrl.dtsi"
+-
+-/ {
+- usb_host1_xhci: usb@fc400000 {
+- compatible = "rockchip,rk3588-dwc3", "snps,dwc3";
+- reg = <0x0 0xfc400000 0x0 0x400000>;
+- interrupts = <GIC_SPI 221 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru REF_CLK_USB3OTG1>, <&cru SUSPEND_CLK_USB3OTG1>,
+- <&cru ACLK_USB3OTG1>;
+- clock-names = "ref_clk", "suspend_clk", "bus_clk";
+- dr_mode = "otg";
+- phys = <&u2phy1_otg>, <&usbdp_phy1 PHY_TYPE_USB3>;
+- phy-names = "usb2-phy", "usb3-phy";
+- phy_type = "utmi_wide";
+- power-domains = <&power RK3588_PD_USB>;
+- resets = <&cru SRST_A_USB3OTG1>;
+- snps,dis_enblslpm_quirk;
+- snps,dis-u2-freeclk-exists-quirk;
+- snps,dis-del-phy-power-chg-quirk;
+- snps,dis-tx-ipgap-linecheck-quirk;
+- status = "disabled";
+- };
+-
+- pcie30_phy_grf: syscon@fd5b8000 {
+- compatible = "rockchip,rk3588-pcie3-phy-grf", "syscon";
+- reg = <0x0 0xfd5b8000 0x0 0x10000>;
+- };
+-
+- pipe_phy1_grf: syscon@fd5c0000 {
+- compatible = "rockchip,rk3588-pipe-phy-grf", "syscon";
+- reg = <0x0 0xfd5c0000 0x0 0x100>;
+- };
+-
+- usbdpphy1_grf: syscon@fd5cc000 {
+- compatible = "rockchip,rk3588-usbdpphy-grf", "syscon";
+- reg = <0x0 0xfd5cc000 0x0 0x4000>;
+- };
+-
+- usb2phy1_grf: syscon@fd5d4000 {
+- compatible = "rockchip,rk3588-usb2phy-grf", "syscon", "simple-mfd";
+- reg = <0x0 0xfd5d4000 0x0 0x4000>;
+- #address-cells = <1>;
+- #size-cells = <1>;
+-
+- u2phy1: usb2phy@4000 {
+- compatible = "rockchip,rk3588-usb2phy";
+- reg = <0x4000 0x10>;
+- #clock-cells = <0>;
+- clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>;
+- clock-names = "phyclk";
+- clock-output-names = "usb480m_phy1";
+- interrupts = <GIC_SPI 394 IRQ_TYPE_LEVEL_HIGH 0>;
+- resets = <&cru SRST_OTGPHY_U3_1>, <&cru SRST_P_USB2PHY_U3_1_GRF0>;
+- reset-names = "phy", "apb";
+- status = "disabled";
+-
+- u2phy1_otg: otg-port {
+- #phy-cells = <0>;
+- status = "disabled";
+- };
+- };
+- };
+-
+- i2s8_8ch: i2s@fddc8000 {
+- compatible = "rockchip,rk3588-i2s-tdm";
+- reg = <0x0 0xfddc8000 0x0 0x1000>;
+- interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru MCLK_I2S8_8CH_TX>, <&cru MCLK_I2S8_8CH_TX>, <&cru HCLK_I2S8_8CH>;
+- clock-names = "mclk_tx", "mclk_rx", "hclk";
+- assigned-clocks = <&cru CLK_I2S8_8CH_TX_SRC>;
+- assigned-clock-parents = <&cru PLL_AUPLL>;
+- dmas = <&dmac2 22>;
+- dma-names = "tx";
+- power-domains = <&power RK3588_PD_VO0>;
+- resets = <&cru SRST_M_I2S8_8CH_TX>;
+- reset-names = "tx-m";
+- #sound-dai-cells = <0>;
+- status = "disabled";
+- };
+-
+- i2s6_8ch: i2s@fddf4000 {
+- compatible = "rockchip,rk3588-i2s-tdm";
+- reg = <0x0 0xfddf4000 0x0 0x1000>;
+- interrupts = <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru MCLK_I2S6_8CH_TX>, <&cru MCLK_I2S6_8CH_TX>, <&cru HCLK_I2S6_8CH>;
+- clock-names = "mclk_tx", "mclk_rx", "hclk";
+- assigned-clocks = <&cru CLK_I2S6_8CH_TX_SRC>;
+- assigned-clock-parents = <&cru PLL_AUPLL>;
+- dmas = <&dmac2 4>;
+- dma-names = "tx";
+- power-domains = <&power RK3588_PD_VO1>;
+- resets = <&cru SRST_M_I2S6_8CH_TX>;
+- reset-names = "tx-m";
+- #sound-dai-cells = <0>;
+- status = "disabled";
+- };
+-
+- i2s7_8ch: i2s@fddf8000 {
+- compatible = "rockchip,rk3588-i2s-tdm";
+- reg = <0x0 0xfddf8000 0x0 0x1000>;
+- interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru MCLK_I2S7_8CH_RX>, <&cru MCLK_I2S7_8CH_RX>, <&cru HCLK_I2S7_8CH>;
+- clock-names = "mclk_tx", "mclk_rx", "hclk";
+- assigned-clocks = <&cru CLK_I2S7_8CH_RX_SRC>;
+- assigned-clock-parents = <&cru PLL_AUPLL>;
+- dmas = <&dmac2 21>;
+- dma-names = "rx";
+- power-domains = <&power RK3588_PD_VO1>;
+- resets = <&cru SRST_M_I2S7_8CH_RX>;
+- reset-names = "rx-m";
+- #sound-dai-cells = <0>;
+- status = "disabled";
+- };
+-
+- i2s10_8ch: i2s@fde00000 {
+- compatible = "rockchip,rk3588-i2s-tdm";
+- reg = <0x0 0xfde00000 0x0 0x1000>;
+- interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru MCLK_I2S10_8CH_RX>, <&cru MCLK_I2S10_8CH_RX>, <&cru HCLK_I2S10_8CH>;
+- clock-names = "mclk_tx", "mclk_rx", "hclk";
+- assigned-clocks = <&cru CLK_I2S10_8CH_RX_SRC>;
+- assigned-clock-parents = <&cru PLL_AUPLL>;
+- dmas = <&dmac2 24>;
+- dma-names = "rx";
+- power-domains = <&power RK3588_PD_VO1>;
+- resets = <&cru SRST_M_I2S10_8CH_RX>;
+- reset-names = "rx-m";
+- #sound-dai-cells = <0>;
+- status = "disabled";
+- };
+-
+- pcie3x4: pcie@fe150000 {
+- compatible = "rockchip,rk3588-pcie", "rockchip,rk3568-pcie";
+- #address-cells = <3>;
+- #size-cells = <2>;
+- bus-range = <0x00 0x0f>;
+- clocks = <&cru ACLK_PCIE_4L_MSTR>, <&cru ACLK_PCIE_4L_SLV>,
+- <&cru ACLK_PCIE_4L_DBI>, <&cru PCLK_PCIE_4L>,
+- <&cru CLK_PCIE_AUX0>, <&cru CLK_PCIE4L_PIPE>;
+- clock-names = "aclk_mst", "aclk_slv",
+- "aclk_dbi", "pclk",
+- "aux", "pipe";
+- device_type = "pci";
+- interrupts = <GIC_SPI 263 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 262 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 261 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 260 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 259 IRQ_TYPE_LEVEL_HIGH 0>;
+- interrupt-names = "sys", "pmc", "msg", "legacy", "err";
+- #interrupt-cells = <1>;
+- interrupt-map-mask = <0 0 0 7>;
+- interrupt-map = <0 0 0 1 &pcie3x4_intc 0>,
+- <0 0 0 2 &pcie3x4_intc 1>,
+- <0 0 0 3 &pcie3x4_intc 2>,
+- <0 0 0 4 &pcie3x4_intc 3>;
+- linux,pci-domain = <0>;
+- max-link-speed = <3>;
+- msi-map = <0x0000 &its1 0x0000 0x1000>;
+- num-lanes = <4>;
+- phys = <&pcie30phy>;
+- phy-names = "pcie-phy";
+- power-domains = <&power RK3588_PD_PCIE>;
+- ranges = <0x01000000 0x0 0xf0100000 0x0 0xf0100000 0x0 0x00100000>,
+- <0x02000000 0x0 0xf0200000 0x0 0xf0200000 0x0 0x00e00000>,
+- <0x03000000 0x0 0x40000000 0x9 0x00000000 0x0 0x40000000>;
+- reg = <0xa 0x40000000 0x0 0x00400000>,
+- <0x0 0xfe150000 0x0 0x00010000>,
+- <0x0 0xf0000000 0x0 0x00100000>;
+- reg-names = "dbi", "apb", "config";
+- resets = <&cru SRST_PCIE0_POWER_UP>, <&cru SRST_P_PCIE0>;
+- reset-names = "pwr", "pipe";
+- status = "disabled";
+-
+- pcie3x4_intc: legacy-interrupt-controller {
+- interrupt-controller;
+- #address-cells = <0>;
+- #interrupt-cells = <1>;
+- interrupt-parent = <&gic>;
+- interrupts = <GIC_SPI 260 IRQ_TYPE_EDGE_RISING 0>;
+- };
+- };
+-
+- pcie3x2: pcie@fe160000 {
+- compatible = "rockchip,rk3588-pcie", "rockchip,rk3568-pcie";
+- #address-cells = <3>;
+- #size-cells = <2>;
+- bus-range = <0x10 0x1f>;
+- clocks = <&cru ACLK_PCIE_2L_MSTR>, <&cru ACLK_PCIE_2L_SLV>,
+- <&cru ACLK_PCIE_2L_DBI>, <&cru PCLK_PCIE_2L>,
+- <&cru CLK_PCIE_AUX1>, <&cru CLK_PCIE2L_PIPE>;
+- clock-names = "aclk_mst", "aclk_slv",
+- "aclk_dbi", "pclk",
+- "aux", "pipe";
+- device_type = "pci";
+- interrupts = <GIC_SPI 258 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 257 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 255 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 254 IRQ_TYPE_LEVEL_HIGH 0>;
+- interrupt-names = "sys", "pmc", "msg", "legacy", "err";
+- #interrupt-cells = <1>;
+- interrupt-map-mask = <0 0 0 7>;
+- interrupt-map = <0 0 0 1 &pcie3x2_intc 0>,
+- <0 0 0 2 &pcie3x2_intc 1>,
+- <0 0 0 3 &pcie3x2_intc 2>,
+- <0 0 0 4 &pcie3x2_intc 3>;
+- linux,pci-domain = <1>;
+- max-link-speed = <3>;
+- msi-map = <0x1000 &its1 0x1000 0x1000>;
+- num-lanes = <2>;
+- phys = <&pcie30phy>;
+- phy-names = "pcie-phy";
+- power-domains = <&power RK3588_PD_PCIE>;
+- ranges = <0x01000000 0x0 0xf1100000 0x0 0xf1100000 0x0 0x00100000>,
+- <0x02000000 0x0 0xf1200000 0x0 0xf1200000 0x0 0x00e00000>,
+- <0x03000000 0x0 0x40000000 0x9 0x40000000 0x0 0x40000000>;
+- reg = <0xa 0x40400000 0x0 0x00400000>,
+- <0x0 0xfe160000 0x0 0x00010000>,
+- <0x0 0xf1000000 0x0 0x00100000>;
+- reg-names = "dbi", "apb", "config";
+- resets = <&cru SRST_PCIE1_POWER_UP>, <&cru SRST_P_PCIE1>;
+- reset-names = "pwr", "pipe";
+- status = "disabled";
+-
+- pcie3x2_intc: legacy-interrupt-controller {
+- interrupt-controller;
+- #address-cells = <0>;
+- #interrupt-cells = <1>;
+- interrupt-parent = <&gic>;
+- interrupts = <GIC_SPI 255 IRQ_TYPE_EDGE_RISING 0>;
+- };
+- };
+-
+- pcie2x1l0: pcie@fe170000 {
+- compatible = "rockchip,rk3588-pcie", "rockchip,rk3568-pcie";
+- bus-range = <0x20 0x2f>;
+- clocks = <&cru ACLK_PCIE_1L0_MSTR>, <&cru ACLK_PCIE_1L0_SLV>,
+- <&cru ACLK_PCIE_1L0_DBI>, <&cru PCLK_PCIE_1L0>,
+- <&cru CLK_PCIE_AUX2>, <&cru CLK_PCIE1L0_PIPE>;
+- clock-names = "aclk_mst", "aclk_slv",
+- "aclk_dbi", "pclk",
+- "aux", "pipe";
+- device_type = "pci";
+- interrupts = <GIC_SPI 243 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 242 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 241 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 239 IRQ_TYPE_LEVEL_HIGH 0>;
+- interrupt-names = "sys", "pmc", "msg", "legacy", "err";
+- #interrupt-cells = <1>;
+- interrupt-map-mask = <0 0 0 7>;
+- interrupt-map = <0 0 0 1 &pcie2x1l0_intc 0>,
+- <0 0 0 2 &pcie2x1l0_intc 1>,
+- <0 0 0 3 &pcie2x1l0_intc 2>,
+- <0 0 0 4 &pcie2x1l0_intc 3>;
+- linux,pci-domain = <2>;
+- max-link-speed = <2>;
+- msi-map = <0x2000 &its0 0x2000 0x1000>;
+- num-lanes = <1>;
+- phys = <&combphy1_ps PHY_TYPE_PCIE>;
+- phy-names = "pcie-phy";
+- power-domains = <&power RK3588_PD_PCIE>;
+- ranges = <0x01000000 0x0 0xf2100000 0x0 0xf2100000 0x0 0x00100000>,
+- <0x02000000 0x0 0xf2200000 0x0 0xf2200000 0x0 0x00e00000>,
+- <0x03000000 0x0 0x40000000 0x9 0x80000000 0x0 0x40000000>;
+- reg = <0xa 0x40800000 0x0 0x00400000>,
+- <0x0 0xfe170000 0x0 0x00010000>,
+- <0x0 0xf2000000 0x0 0x00100000>;
+- reg-names = "dbi", "apb", "config";
+- resets = <&cru SRST_PCIE2_POWER_UP>, <&cru SRST_P_PCIE2>;
+- reset-names = "pwr", "pipe";
+- #address-cells = <3>;
+- #size-cells = <2>;
+- status = "disabled";
+-
+- pcie2x1l0_intc: legacy-interrupt-controller {
+- interrupt-controller;
+- #address-cells = <0>;
+- #interrupt-cells = <1>;
+- interrupt-parent = <&gic>;
+- interrupts = <GIC_SPI 240 IRQ_TYPE_EDGE_RISING 0>;
+- };
+- };
+-
+- gmac0: ethernet@fe1b0000 {
+- compatible = "rockchip,rk3588-gmac", "snps,dwmac-4.20a";
+- reg = <0x0 0xfe1b0000 0x0 0x10000>;
+- interrupts = <GIC_SPI 227 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH 0>;
+- interrupt-names = "macirq", "eth_wake_irq";
+- clocks = <&cru CLK_GMAC_125M>, <&cru CLK_GMAC_50M>,
+- <&cru PCLK_GMAC0>, <&cru ACLK_GMAC0>,
+- <&cru CLK_GMAC0_PTP_REF>;
+- clock-names = "stmmaceth", "clk_mac_ref",
+- "pclk_mac", "aclk_mac",
+- "ptp_ref";
+- power-domains = <&power RK3588_PD_GMAC>;
+- resets = <&cru SRST_A_GMAC0>;
+- reset-names = "stmmaceth";
+- rockchip,grf = <&sys_grf>;
+- rockchip,php-grf = <&php_grf>;
+- snps,axi-config = <&gmac0_stmmac_axi_setup>;
+- snps,mixed-burst;
+- snps,mtl-rx-config = <&gmac0_mtl_rx_setup>;
+- snps,mtl-tx-config = <&gmac0_mtl_tx_setup>;
+- snps,tso;
+- status = "disabled";
+-
+- mdio0: mdio {
+- compatible = "snps,dwmac-mdio";
+- #address-cells = <0x1>;
+- #size-cells = <0x0>;
+- };
+-
+- gmac0_stmmac_axi_setup: stmmac-axi-config {
+- snps,blen = <0 0 0 0 16 8 4>;
+- snps,wr_osr_lmt = <4>;
+- snps,rd_osr_lmt = <8>;
+- };
+-
+- gmac0_mtl_rx_setup: rx-queues-config {
+- snps,rx-queues-to-use = <2>;
+- queue0 {};
+- queue1 {};
+- };
+-
+- gmac0_mtl_tx_setup: tx-queues-config {
+- snps,tx-queues-to-use = <2>;
+- queue0 {};
+- queue1 {};
+- };
+- };
+-
+- sata1: sata@fe220000 {
+- compatible = "rockchip,rk3588-dwc-ahci", "snps,dwc-ahci";
+- reg = <0 0xfe220000 0 0x1000>;
+- interrupts = <GIC_SPI 274 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru ACLK_SATA1>, <&cru CLK_PMALIVE1>,
+- <&cru CLK_RXOOB1>, <&cru CLK_PIPEPHY1_REF>,
+- <&cru CLK_PIPEPHY1_PIPE_ASIC_G>;
+- clock-names = "sata", "pmalive", "rxoob", "ref", "asic";
+- ports-implemented = <0x1>;
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+-
+- sata-port@0 {
+- reg = <0>;
+- hba-port-cap = <HBA_PORT_FBSCP>;
+- phys = <&combphy1_ps PHY_TYPE_SATA>;
+- phy-names = "sata-phy";
+- snps,rx-ts-max = <32>;
+- snps,tx-ts-max = <32>;
+- };
+- };
+-
+- usbdp_phy1: phy@fed90000 {
+- compatible = "rockchip,rk3588-usbdp-phy";
+- reg = <0x0 0xfed90000 0x0 0x10000>;
+- #phy-cells = <1>;
+- clocks = <&cru CLK_USBDPPHY_MIPIDCPPHY_REF>,
+- <&cru CLK_USBDP_PHY1_IMMORTAL>,
+- <&cru PCLK_USBDPPHY1>,
+- <&u2phy1>;
+- clock-names = "refclk", "immortal", "pclk", "utmi";
+- resets = <&cru SRST_USBDP_COMBO_PHY1_INIT>,
+- <&cru SRST_USBDP_COMBO_PHY1_CMN>,
+- <&cru SRST_USBDP_COMBO_PHY1_LANE>,
+- <&cru SRST_USBDP_COMBO_PHY1_PCS>,
+- <&cru SRST_P_USBDPPHY1>;
+- reset-names = "init", "cmn", "lane", "pcs_apb", "pma_apb";
+- rockchip,u2phy-grf = <&usb2phy1_grf>;
+- rockchip,usb-grf = <&usb_grf>;
+- rockchip,usbdpphy-grf = <&usbdpphy1_grf>;
+- rockchip,vo-grf = <&vo0_grf>;
+- status = "disabled";
+- };
+-
+- combphy1_ps: phy@fee10000 {
+- compatible = "rockchip,rk3588-naneng-combphy";
+- reg = <0x0 0xfee10000 0x0 0x100>;
+- clocks = <&cru CLK_REF_PIPE_PHY1>, <&cru PCLK_PCIE_COMBO_PIPE_PHY1>,
+- <&cru PCLK_PHP_ROOT>;
+- clock-names = "ref", "apb", "pipe";
+- assigned-clocks = <&cru CLK_REF_PIPE_PHY1>;
+- assigned-clock-rates = <100000000>;
+- #phy-cells = <1>;
+- resets = <&cru SRST_REF_PIPE_PHY1>, <&cru SRST_P_PCIE2_PHY1>;
+- reset-names = "phy", "apb";
+- rockchip,pipe-grf = <&php_grf>;
+- rockchip,pipe-phy-grf = <&pipe_phy1_grf>;
+- status = "disabled";
+- };
+-
+- pcie30phy: phy@fee80000 {
+- compatible = "rockchip,rk3588-pcie3-phy";
+- reg = <0x0 0xfee80000 0x0 0x20000>;
+- #phy-cells = <0>;
+- clocks = <&cru PCLK_PCIE_COMBO_PIPE_PHY>;
+- clock-names = "pclk";
+- resets = <&cru SRST_PCIE30_PHY>;
+- reset-names = "phy";
+- rockchip,pipe-grf = <&php_grf>;
+- rockchip,phy-grf = <&pcie30_phy_grf>;
+- status = "disabled";
+- };
+-};
++#include "rk3588-extra.dtsi"
+--- a/arch/arm64/boot/dts/rockchip/rk3588j.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588j.dtsi
+@@ -4,4 +4,4 @@
+ *
+ */
+
+-#include "rk3588.dtsi"
++#include "rk3588-extra.dtsi"
+--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
+@@ -1,2670 +1,7 @@
+ // SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+ /*
+- * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
++ * Copyright (c) 2022 Rockchip Electronics Co., Ltd.
++ *
+ */
+
+-#include <dt-bindings/clock/rockchip,rk3588-cru.h>
+-#include <dt-bindings/interrupt-controller/arm-gic.h>
+-#include <dt-bindings/interrupt-controller/irq.h>
+-#include <dt-bindings/power/rk3588-power.h>
+-#include <dt-bindings/reset/rockchip,rk3588-cru.h>
+-#include <dt-bindings/phy/phy.h>
+-#include <dt-bindings/ata/ahci.h>
+-
+-/ {
+- compatible = "rockchip,rk3588";
+-
+- interrupt-parent = <&gic>;
+- #address-cells = <2>;
+- #size-cells = <2>;
+-
+- aliases {
+- gpio0 = &gpio0;
+- gpio1 = &gpio1;
+- gpio2 = &gpio2;
+- gpio3 = &gpio3;
+- gpio4 = &gpio4;
+- i2c0 = &i2c0;
+- i2c1 = &i2c1;
+- i2c2 = &i2c2;
+- i2c3 = &i2c3;
+- i2c4 = &i2c4;
+- i2c5 = &i2c5;
+- i2c6 = &i2c6;
+- i2c7 = &i2c7;
+- i2c8 = &i2c8;
+- serial0 = &uart0;
+- serial1 = &uart1;
+- serial2 = &uart2;
+- serial3 = &uart3;
+- serial4 = &uart4;
+- serial5 = &uart5;
+- serial6 = &uart6;
+- serial7 = &uart7;
+- serial8 = &uart8;
+- serial9 = &uart9;
+- spi0 = &spi0;
+- spi1 = &spi1;
+- spi2 = &spi2;
+- spi3 = &spi3;
+- spi4 = &spi4;
+- };
+-
+- cpus {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- cpu-map {
+- cluster0 {
+- core0 {
+- cpu = <&cpu_l0>;
+- };
+- core1 {
+- cpu = <&cpu_l1>;
+- };
+- core2 {
+- cpu = <&cpu_l2>;
+- };
+- core3 {
+- cpu = <&cpu_l3>;
+- };
+- };
+- cluster1 {
+- core0 {
+- cpu = <&cpu_b0>;
+- };
+- core1 {
+- cpu = <&cpu_b1>;
+- };
+- };
+- cluster2 {
+- core0 {
+- cpu = <&cpu_b2>;
+- };
+- core1 {
+- cpu = <&cpu_b3>;
+- };
+- };
+- };
+-
+- cpu_l0: cpu@0 {
+- device_type = "cpu";
+- compatible = "arm,cortex-a55";
+- reg = <0x0>;
+- enable-method = "psci";
+- capacity-dmips-mhz = <530>;
+- clocks = <&scmi_clk SCMI_CLK_CPUL>;
+- assigned-clocks = <&scmi_clk SCMI_CLK_CPUL>;
+- assigned-clock-rates = <816000000>;
+- cpu-idle-states = <&CPU_SLEEP>;
+- i-cache-size = <32768>;
+- i-cache-line-size = <64>;
+- i-cache-sets = <128>;
+- d-cache-size = <32768>;
+- d-cache-line-size = <64>;
+- d-cache-sets = <128>;
+- next-level-cache = <&l2_cache_l0>;
+- dynamic-power-coefficient = <228>;
+- #cooling-cells = <2>;
+- };
+-
+- cpu_l1: cpu@100 {
+- device_type = "cpu";
+- compatible = "arm,cortex-a55";
+- reg = <0x100>;
+- enable-method = "psci";
+- capacity-dmips-mhz = <530>;
+- clocks = <&scmi_clk SCMI_CLK_CPUL>;
+- cpu-idle-states = <&CPU_SLEEP>;
+- i-cache-size = <32768>;
+- i-cache-line-size = <64>;
+- i-cache-sets = <128>;
+- d-cache-size = <32768>;
+- d-cache-line-size = <64>;
+- d-cache-sets = <128>;
+- next-level-cache = <&l2_cache_l1>;
+- dynamic-power-coefficient = <228>;
+- #cooling-cells = <2>;
+- };
+-
+- cpu_l2: cpu@200 {
+- device_type = "cpu";
+- compatible = "arm,cortex-a55";
+- reg = <0x200>;
+- enable-method = "psci";
+- capacity-dmips-mhz = <530>;
+- clocks = <&scmi_clk SCMI_CLK_CPUL>;
+- cpu-idle-states = <&CPU_SLEEP>;
+- i-cache-size = <32768>;
+- i-cache-line-size = <64>;
+- i-cache-sets = <128>;
+- d-cache-size = <32768>;
+- d-cache-line-size = <64>;
+- d-cache-sets = <128>;
+- next-level-cache = <&l2_cache_l2>;
+- dynamic-power-coefficient = <228>;
+- #cooling-cells = <2>;
+- };
+-
+- cpu_l3: cpu@300 {
+- device_type = "cpu";
+- compatible = "arm,cortex-a55";
+- reg = <0x300>;
+- enable-method = "psci";
+- capacity-dmips-mhz = <530>;
+- clocks = <&scmi_clk SCMI_CLK_CPUL>;
+- cpu-idle-states = <&CPU_SLEEP>;
+- i-cache-size = <32768>;
+- i-cache-line-size = <64>;
+- i-cache-sets = <128>;
+- d-cache-size = <32768>;
+- d-cache-line-size = <64>;
+- d-cache-sets = <128>;
+- next-level-cache = <&l2_cache_l3>;
+- dynamic-power-coefficient = <228>;
+- #cooling-cells = <2>;
+- };
+-
+- cpu_b0: cpu@400 {
+- device_type = "cpu";
+- compatible = "arm,cortex-a76";
+- reg = <0x400>;
+- enable-method = "psci";
+- capacity-dmips-mhz = <1024>;
+- clocks = <&scmi_clk SCMI_CLK_CPUB01>;
+- assigned-clocks = <&scmi_clk SCMI_CLK_CPUB01>;
+- assigned-clock-rates = <816000000>;
+- cpu-idle-states = <&CPU_SLEEP>;
+- i-cache-size = <65536>;
+- i-cache-line-size = <64>;
+- i-cache-sets = <256>;
+- d-cache-size = <65536>;
+- d-cache-line-size = <64>;
+- d-cache-sets = <256>;
+- next-level-cache = <&l2_cache_b0>;
+- dynamic-power-coefficient = <416>;
+- #cooling-cells = <2>;
+- };
+-
+- cpu_b1: cpu@500 {
+- device_type = "cpu";
+- compatible = "arm,cortex-a76";
+- reg = <0x500>;
+- enable-method = "psci";
+- capacity-dmips-mhz = <1024>;
+- clocks = <&scmi_clk SCMI_CLK_CPUB01>;
+- cpu-idle-states = <&CPU_SLEEP>;
+- i-cache-size = <65536>;
+- i-cache-line-size = <64>;
+- i-cache-sets = <256>;
+- d-cache-size = <65536>;
+- d-cache-line-size = <64>;
+- d-cache-sets = <256>;
+- next-level-cache = <&l2_cache_b1>;
+- dynamic-power-coefficient = <416>;
+- #cooling-cells = <2>;
+- };
+-
+- cpu_b2: cpu@600 {
+- device_type = "cpu";
+- compatible = "arm,cortex-a76";
+- reg = <0x600>;
+- enable-method = "psci";
+- capacity-dmips-mhz = <1024>;
+- clocks = <&scmi_clk SCMI_CLK_CPUB23>;
+- assigned-clocks = <&scmi_clk SCMI_CLK_CPUB23>;
+- assigned-clock-rates = <816000000>;
+- cpu-idle-states = <&CPU_SLEEP>;
+- i-cache-size = <65536>;
+- i-cache-line-size = <64>;
+- i-cache-sets = <256>;
+- d-cache-size = <65536>;
+- d-cache-line-size = <64>;
+- d-cache-sets = <256>;
+- next-level-cache = <&l2_cache_b2>;
+- dynamic-power-coefficient = <416>;
+- #cooling-cells = <2>;
+- };
+-
+- cpu_b3: cpu@700 {
+- device_type = "cpu";
+- compatible = "arm,cortex-a76";
+- reg = <0x700>;
+- enable-method = "psci";
+- capacity-dmips-mhz = <1024>;
+- clocks = <&scmi_clk SCMI_CLK_CPUB23>;
+- cpu-idle-states = <&CPU_SLEEP>;
+- i-cache-size = <65536>;
+- i-cache-line-size = <64>;
+- i-cache-sets = <256>;
+- d-cache-size = <65536>;
+- d-cache-line-size = <64>;
+- d-cache-sets = <256>;
+- next-level-cache = <&l2_cache_b3>;
+- dynamic-power-coefficient = <416>;
+- #cooling-cells = <2>;
+- };
+-
+- idle-states {
+- entry-method = "psci";
+- CPU_SLEEP: cpu-sleep {
+- compatible = "arm,idle-state";
+- local-timer-stop;
+- arm,psci-suspend-param = <0x0010000>;
+- entry-latency-us = <100>;
+- exit-latency-us = <120>;
+- min-residency-us = <1000>;
+- };
+- };
+-
+- l2_cache_l0: l2-cache-l0 {
+- compatible = "cache";
+- cache-size = <131072>;
+- cache-line-size = <64>;
+- cache-sets = <512>;
+- cache-level = <2>;
+- cache-unified;
+- next-level-cache = <&l3_cache>;
+- };
+-
+- l2_cache_l1: l2-cache-l1 {
+- compatible = "cache";
+- cache-size = <131072>;
+- cache-line-size = <64>;
+- cache-sets = <512>;
+- cache-level = <2>;
+- cache-unified;
+- next-level-cache = <&l3_cache>;
+- };
+-
+- l2_cache_l2: l2-cache-l2 {
+- compatible = "cache";
+- cache-size = <131072>;
+- cache-line-size = <64>;
+- cache-sets = <512>;
+- cache-level = <2>;
+- cache-unified;
+- next-level-cache = <&l3_cache>;
+- };
+-
+- l2_cache_l3: l2-cache-l3 {
+- compatible = "cache";
+- cache-size = <131072>;
+- cache-line-size = <64>;
+- cache-sets = <512>;
+- cache-level = <2>;
+- cache-unified;
+- next-level-cache = <&l3_cache>;
+- };
+-
+- l2_cache_b0: l2-cache-b0 {
+- compatible = "cache";
+- cache-size = <524288>;
+- cache-line-size = <64>;
+- cache-sets = <1024>;
+- cache-level = <2>;
+- cache-unified;
+- next-level-cache = <&l3_cache>;
+- };
+-
+- l2_cache_b1: l2-cache-b1 {
+- compatible = "cache";
+- cache-size = <524288>;
+- cache-line-size = <64>;
+- cache-sets = <1024>;
+- cache-level = <2>;
+- cache-unified;
+- next-level-cache = <&l3_cache>;
+- };
+-
+- l2_cache_b2: l2-cache-b2 {
+- compatible = "cache";
+- cache-size = <524288>;
+- cache-line-size = <64>;
+- cache-sets = <1024>;
+- cache-level = <2>;
+- cache-unified;
+- next-level-cache = <&l3_cache>;
+- };
+-
+- l2_cache_b3: l2-cache-b3 {
+- compatible = "cache";
+- cache-size = <524288>;
+- cache-line-size = <64>;
+- cache-sets = <1024>;
+- cache-level = <2>;
+- cache-unified;
+- next-level-cache = <&l3_cache>;
+- };
+-
+- l3_cache: l3-cache {
+- compatible = "cache";
+- cache-size = <3145728>;
+- cache-line-size = <64>;
+- cache-sets = <4096>;
+- cache-level = <3>;
+- cache-unified;
+- };
+- };
+-
+- display_subsystem: display-subsystem {
+- compatible = "rockchip,display-subsystem";
+- ports = <&vop_out>;
+- };
+-
+- firmware {
+- optee: optee {
+- compatible = "linaro,optee-tz";
+- method = "smc";
+- };
+-
+- scmi: scmi {
+- compatible = "arm,scmi-smc";
+- arm,smc-id = <0x82000010>;
+- shmem = <&scmi_shmem>;
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- scmi_clk: protocol@14 {
+- reg = <0x14>;
+- #clock-cells = <1>;
+- };
+-
+- scmi_reset: protocol@16 {
+- reg = <0x16>;
+- #reset-cells = <1>;
+- };
+- };
+- };
+-
+- pmu-a55 {
+- compatible = "arm,cortex-a55-pmu";
+- interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH &ppi_partition0>;
+- };
+-
+- pmu-a76 {
+- compatible = "arm,cortex-a76-pmu";
+- interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH &ppi_partition1>;
+- };
+-
+- psci {
+- compatible = "arm,psci-1.0";
+- method = "smc";
+- };
+-
+- spll: clock-0 {
+- compatible = "fixed-clock";
+- clock-frequency = <702000000>;
+- clock-output-names = "spll";
+- #clock-cells = <0>;
+- };
+-
+- timer {
+- compatible = "arm,armv8-timer";
+- interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_PPI 14 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_PPI 10 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_PPI 12 IRQ_TYPE_LEVEL_HIGH 0>;
+- interrupt-names = "sec-phys", "phys", "virt", "hyp-phys", "hyp-virt";
+- };
+-
+- xin24m: clock-1 {
+- compatible = "fixed-clock";
+- clock-frequency = <24000000>;
+- clock-output-names = "xin24m";
+- #clock-cells = <0>;
+- };
+-
+- xin32k: clock-2 {
+- compatible = "fixed-clock";
+- clock-frequency = <32768>;
+- clock-output-names = "xin32k";
+- #clock-cells = <0>;
+- };
+-
+- pmu_sram: sram@10f000 {
+- compatible = "mmio-sram";
+- reg = <0x0 0x0010f000 0x0 0x100>;
+- ranges = <0 0x0 0x0010f000 0x100>;
+- #address-cells = <1>;
+- #size-cells = <1>;
+-
+- scmi_shmem: sram@0 {
+- compatible = "arm,scmi-shmem";
+- reg = <0x0 0x100>;
+- };
+- };
+-
+- gpu: gpu@fb000000 {
+- compatible = "rockchip,rk3588-mali", "arm,mali-valhall-csf";
+- reg = <0x0 0xfb000000 0x0 0x200000>;
+- #cooling-cells = <2>;
+- assigned-clocks = <&scmi_clk SCMI_CLK_GPU>;
+- assigned-clock-rates = <200000000>;
+- clocks = <&cru CLK_GPU>, <&cru CLK_GPU_COREGROUP>,
+- <&cru CLK_GPU_STACKS>;
+- clock-names = "core", "coregroup", "stacks";
+- dynamic-power-coefficient = <2982>;
+- interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH 0>;
+- interrupt-names = "job", "mmu", "gpu";
+- operating-points-v2 = <&gpu_opp_table>;
+- power-domains = <&power RK3588_PD_GPU>;
+- status = "disabled";
+-
+- gpu_opp_table: opp-table {
+- compatible = "operating-points-v2";
+-
+- opp-300000000 {
+- opp-hz = /bits/ 64 <300000000>;
+- opp-microvolt = <675000 675000 850000>;
+- };
+- opp-400000000 {
+- opp-hz = /bits/ 64 <400000000>;
+- opp-microvolt = <675000 675000 850000>;
+- };
+- opp-500000000 {
+- opp-hz = /bits/ 64 <500000000>;
+- opp-microvolt = <675000 675000 850000>;
+- };
+- opp-600000000 {
+- opp-hz = /bits/ 64 <600000000>;
+- opp-microvolt = <675000 675000 850000>;
+- };
+- opp-700000000 {
+- opp-hz = /bits/ 64 <700000000>;
+- opp-microvolt = <700000 700000 850000>;
+- };
+- opp-800000000 {
+- opp-hz = /bits/ 64 <800000000>;
+- opp-microvolt = <750000 750000 850000>;
+- };
+- opp-900000000 {
+- opp-hz = /bits/ 64 <900000000>;
+- opp-microvolt = <800000 800000 850000>;
+- };
+- opp-1000000000 {
+- opp-hz = /bits/ 64 <1000000000>;
+- opp-microvolt = <850000 850000 850000>;
+- };
+- };
+- };
+-
+- usb_host0_xhci: usb@fc000000 {
+- compatible = "rockchip,rk3588-dwc3", "snps,dwc3";
+- reg = <0x0 0xfc000000 0x0 0x400000>;
+- interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru REF_CLK_USB3OTG0>, <&cru SUSPEND_CLK_USB3OTG0>,
+- <&cru ACLK_USB3OTG0>;
+- clock-names = "ref_clk", "suspend_clk", "bus_clk";
+- dr_mode = "otg";
+- phys = <&u2phy0_otg>, <&usbdp_phy0 PHY_TYPE_USB3>;
+- phy-names = "usb2-phy", "usb3-phy";
+- phy_type = "utmi_wide";
+- power-domains = <&power RK3588_PD_USB>;
+- resets = <&cru SRST_A_USB3OTG0>;
+- snps,dis_enblslpm_quirk;
+- snps,dis-u1-entry-quirk;
+- snps,dis-u2-entry-quirk;
+- snps,dis-u2-freeclk-exists-quirk;
+- snps,dis-del-phy-power-chg-quirk;
+- snps,dis-tx-ipgap-linecheck-quirk;
+- status = "disabled";
+- };
+-
+- usb_host0_ehci: usb@fc800000 {
+- compatible = "rockchip,rk3588-ehci", "generic-ehci";
+- reg = <0x0 0xfc800000 0x0 0x40000>;
+- interrupts = <GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru HCLK_HOST0>, <&cru HCLK_HOST_ARB0>, <&cru ACLK_USB>, <&u2phy2>;
+- phys = <&u2phy2_host>;
+- phy-names = "usb";
+- power-domains = <&power RK3588_PD_USB>;
+- status = "disabled";
+- };
+-
+- usb_host0_ohci: usb@fc840000 {
+- compatible = "rockchip,rk3588-ohci", "generic-ohci";
+- reg = <0x0 0xfc840000 0x0 0x40000>;
+- interrupts = <GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru HCLK_HOST0>, <&cru HCLK_HOST_ARB0>, <&cru ACLK_USB>, <&u2phy2>;
+- phys = <&u2phy2_host>;
+- phy-names = "usb";
+- power-domains = <&power RK3588_PD_USB>;
+- status = "disabled";
+- };
+-
+- usb_host1_ehci: usb@fc880000 {
+- compatible = "rockchip,rk3588-ehci", "generic-ehci";
+- reg = <0x0 0xfc880000 0x0 0x40000>;
+- interrupts = <GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru HCLK_HOST1>, <&cru HCLK_HOST_ARB1>, <&cru ACLK_USB>, <&u2phy3>;
+- phys = <&u2phy3_host>;
+- phy-names = "usb";
+- power-domains = <&power RK3588_PD_USB>;
+- status = "disabled";
+- };
+-
+- usb_host1_ohci: usb@fc8c0000 {
+- compatible = "rockchip,rk3588-ohci", "generic-ohci";
+- reg = <0x0 0xfc8c0000 0x0 0x40000>;
+- interrupts = <GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru HCLK_HOST1>, <&cru HCLK_HOST_ARB1>, <&cru ACLK_USB>, <&u2phy3>;
+- phys = <&u2phy3_host>;
+- phy-names = "usb";
+- power-domains = <&power RK3588_PD_USB>;
+- status = "disabled";
+- };
+-
+- usb_host2_xhci: usb@fcd00000 {
+- compatible = "rockchip,rk3588-dwc3", "snps,dwc3";
+- reg = <0x0 0xfcd00000 0x0 0x400000>;
+- interrupts = <GIC_SPI 222 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru REF_CLK_USB3OTG2>, <&cru SUSPEND_CLK_USB3OTG2>,
+- <&cru ACLK_USB3OTG2>, <&cru CLK_UTMI_OTG2>,
+- <&cru CLK_PIPEPHY2_PIPE_U3_G>;
+- clock-names = "ref_clk", "suspend_clk", "bus_clk", "utmi", "pipe";
+- dr_mode = "host";
+- phys = <&combphy2_psu PHY_TYPE_USB3>;
+- phy-names = "usb3-phy";
+- phy_type = "utmi_wide";
+- resets = <&cru SRST_A_USB3OTG2>;
+- snps,dis_enblslpm_quirk;
+- snps,dis-u2-freeclk-exists-quirk;
+- snps,dis-del-phy-power-chg-quirk;
+- snps,dis-tx-ipgap-linecheck-quirk;
+- snps,dis_rxdet_inp3_quirk;
+- status = "disabled";
+- };
+-
+- mmu600_pcie: iommu@fc900000 {
+- compatible = "arm,smmu-v3";
+- reg = <0x0 0xfc900000 0x0 0x200000>;
+- interrupts = <GIC_SPI 369 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 371 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 374 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 367 IRQ_TYPE_LEVEL_HIGH 0>;
+- interrupt-names = "eventq", "gerror", "priq", "cmdq-sync";
+- #iommu-cells = <1>;
+- status = "disabled";
+- };
+-
+- mmu600_php: iommu@fcb00000 {
+- compatible = "arm,smmu-v3";
+- reg = <0x0 0xfcb00000 0x0 0x200000>;
+- interrupts = <GIC_SPI 381 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 383 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 386 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 379 IRQ_TYPE_LEVEL_HIGH 0>;
+- interrupt-names = "eventq", "gerror", "priq", "cmdq-sync";
+- #iommu-cells = <1>;
+- status = "disabled";
+- };
+-
+- pmu1grf: syscon@fd58a000 {
+- compatible = "rockchip,rk3588-pmugrf", "syscon", "simple-mfd";
+- reg = <0x0 0xfd58a000 0x0 0x10000>;
+- };
+-
+- sys_grf: syscon@fd58c000 {
+- compatible = "rockchip,rk3588-sys-grf", "syscon";
+- reg = <0x0 0xfd58c000 0x0 0x1000>;
+- };
+-
+- vop_grf: syscon@fd5a4000 {
+- compatible = "rockchip,rk3588-vop-grf", "syscon";
+- reg = <0x0 0xfd5a4000 0x0 0x2000>;
+- };
+-
+- vo0_grf: syscon@fd5a6000 {
+- compatible = "rockchip,rk3588-vo-grf", "syscon";
+- reg = <0x0 0xfd5a6000 0x0 0x2000>;
+- clocks = <&cru PCLK_VO0GRF>;
+- };
+-
+- vo1_grf: syscon@fd5a8000 {
+- compatible = "rockchip,rk3588-vo-grf", "syscon";
+- reg = <0x0 0xfd5a8000 0x0 0x100>;
+- clocks = <&cru PCLK_VO1GRF>;
+- };
+-
+- usb_grf: syscon@fd5ac000 {
+- compatible = "rockchip,rk3588-usb-grf", "syscon";
+- reg = <0x0 0xfd5ac000 0x0 0x4000>;
+- };
+-
+- php_grf: syscon@fd5b0000 {
+- compatible = "rockchip,rk3588-php-grf", "syscon";
+- reg = <0x0 0xfd5b0000 0x0 0x1000>;
+- };
+-
+- pipe_phy0_grf: syscon@fd5bc000 {
+- compatible = "rockchip,rk3588-pipe-phy-grf", "syscon";
+- reg = <0x0 0xfd5bc000 0x0 0x100>;
+- };
+-
+- pipe_phy2_grf: syscon@fd5c4000 {
+- compatible = "rockchip,rk3588-pipe-phy-grf", "syscon";
+- reg = <0x0 0xfd5c4000 0x0 0x100>;
+- };
+-
+- usbdpphy0_grf: syscon@fd5c8000 {
+- compatible = "rockchip,rk3588-usbdpphy-grf", "syscon";
+- reg = <0x0 0xfd5c8000 0x0 0x4000>;
+- };
+-
+- usb2phy0_grf: syscon@fd5d0000 {
+- compatible = "rockchip,rk3588-usb2phy-grf", "syscon", "simple-mfd";
+- reg = <0x0 0xfd5d0000 0x0 0x4000>;
+- #address-cells = <1>;
+- #size-cells = <1>;
+-
+- u2phy0: usb2phy@0 {
+- compatible = "rockchip,rk3588-usb2phy";
+- reg = <0x0 0x10>;
+- #clock-cells = <0>;
+- clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>;
+- clock-names = "phyclk";
+- clock-output-names = "usb480m_phy0";
+- interrupts = <GIC_SPI 393 IRQ_TYPE_LEVEL_HIGH 0>;
+- resets = <&cru SRST_OTGPHY_U3_0>, <&cru SRST_P_USB2PHY_U3_0_GRF0>;
+- reset-names = "phy", "apb";
+- status = "disabled";
+-
+- u2phy0_otg: otg-port {
+- #phy-cells = <0>;
+- status = "disabled";
+- };
+- };
+- };
+-
+- usb2phy2_grf: syscon@fd5d8000 {
+- compatible = "rockchip,rk3588-usb2phy-grf", "syscon", "simple-mfd";
+- reg = <0x0 0xfd5d8000 0x0 0x4000>;
+- #address-cells = <1>;
+- #size-cells = <1>;
+-
+- u2phy2: usb2phy@8000 {
+- compatible = "rockchip,rk3588-usb2phy";
+- reg = <0x8000 0x10>;
+- #clock-cells = <0>;
+- clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>;
+- clock-names = "phyclk";
+- clock-output-names = "usb480m_phy2";
+- interrupts = <GIC_SPI 391 IRQ_TYPE_LEVEL_HIGH 0>;
+- resets = <&cru SRST_OTGPHY_U2_0>, <&cru SRST_P_USB2PHY_U2_0_GRF0>;
+- reset-names = "phy", "apb";
+- status = "disabled";
+-
+- u2phy2_host: host-port {
+- #phy-cells = <0>;
+- status = "disabled";
+- };
+- };
+- };
+-
+- usb2phy3_grf: syscon@fd5dc000 {
+- compatible = "rockchip,rk3588-usb2phy-grf", "syscon", "simple-mfd";
+- reg = <0x0 0xfd5dc000 0x0 0x4000>;
+- #address-cells = <1>;
+- #size-cells = <1>;
+-
+- u2phy3: usb2phy@c000 {
+- compatible = "rockchip,rk3588-usb2phy";
+- reg = <0xc000 0x10>;
+- #clock-cells = <0>;
+- clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>;
+- clock-names = "phyclk";
+- clock-output-names = "usb480m_phy3";
+- interrupts = <GIC_SPI 392 IRQ_TYPE_LEVEL_HIGH 0>;
+- resets = <&cru SRST_OTGPHY_U2_1>, <&cru SRST_P_USB2PHY_U2_1_GRF0>;
+- reset-names = "phy", "apb";
+- status = "disabled";
+-
+- u2phy3_host: host-port {
+- #phy-cells = <0>;
+- status = "disabled";
+- };
+- };
+- };
+-
+- hdptxphy0_grf: syscon@fd5e0000 {
+- compatible = "rockchip,rk3588-hdptxphy-grf", "syscon";
+- reg = <0x0 0xfd5e0000 0x0 0x100>;
+- };
+-
+- ioc: syscon@fd5f0000 {
+- compatible = "rockchip,rk3588-ioc", "syscon";
+- reg = <0x0 0xfd5f0000 0x0 0x10000>;
+- };
+-
+- system_sram1: sram@fd600000 {
+- compatible = "mmio-sram";
+- reg = <0x0 0xfd600000 0x0 0x100000>;
+- ranges = <0x0 0x0 0xfd600000 0x100000>;
+- #address-cells = <1>;
+- #size-cells = <1>;
+- };
+-
+- cru: clock-controller@fd7c0000 {
+- compatible = "rockchip,rk3588-cru";
+- reg = <0x0 0xfd7c0000 0x0 0x5c000>;
+- assigned-clocks =
+- <&cru PLL_PPLL>, <&cru PLL_AUPLL>,
+- <&cru PLL_NPLL>, <&cru PLL_GPLL>,
+- <&cru ACLK_CENTER_ROOT>,
+- <&cru HCLK_CENTER_ROOT>, <&cru ACLK_CENTER_LOW_ROOT>,
+- <&cru ACLK_TOP_ROOT>, <&cru PCLK_TOP_ROOT>,
+- <&cru ACLK_LOW_TOP_ROOT>, <&cru PCLK_PMU0_ROOT>,
+- <&cru HCLK_PMU_CM0_ROOT>, <&cru ACLK_VOP>,
+- <&cru ACLK_BUS_ROOT>, <&cru CLK_150M_SRC>,
+- <&cru CLK_GPU>;
+- assigned-clock-rates =
+- <1100000000>, <786432000>,
+- <850000000>, <1188000000>,
+- <702000000>,
+- <400000000>, <500000000>,
+- <800000000>, <100000000>,
+- <400000000>, <100000000>,
+- <200000000>, <500000000>,
+- <375000000>, <150000000>,
+- <200000000>;
+- rockchip,grf = <&php_grf>;
+- #clock-cells = <1>;
+- #reset-cells = <1>;
+- };
+-
+- i2c0: i2c@fd880000 {
+- compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
+- reg = <0x0 0xfd880000 0x0 0x1000>;
+- interrupts = <GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru CLK_I2C0>, <&cru PCLK_I2C0>;
+- clock-names = "i2c", "pclk";
+- pinctrl-0 = <&i2c0m0_xfer>;
+- pinctrl-names = "default";
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- uart0: serial@fd890000 {
+- compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
+- reg = <0x0 0xfd890000 0x0 0x100>;
+- interrupts = <GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru SCLK_UART0>, <&cru PCLK_UART0>;
+- clock-names = "baudclk", "apb_pclk";
+- dmas = <&dmac0 6>, <&dmac0 7>;
+- dma-names = "tx", "rx";
+- pinctrl-0 = <&uart0m1_xfer>;
+- pinctrl-names = "default";
+- reg-shift = <2>;
+- reg-io-width = <4>;
+- status = "disabled";
+- };
+-
+- pwm0: pwm@fd8b0000 {
+- compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+- reg = <0x0 0xfd8b0000 0x0 0x10>;
+- clocks = <&cru CLK_PMU1PWM>, <&cru PCLK_PMU1PWM>;
+- clock-names = "pwm", "pclk";
+- pinctrl-0 = <&pwm0m0_pins>;
+- pinctrl-names = "default";
+- #pwm-cells = <3>;
+- status = "disabled";
+- };
+-
+- pwm1: pwm@fd8b0010 {
+- compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+- reg = <0x0 0xfd8b0010 0x0 0x10>;
+- clocks = <&cru CLK_PMU1PWM>, <&cru PCLK_PMU1PWM>;
+- clock-names = "pwm", "pclk";
+- pinctrl-0 = <&pwm1m0_pins>;
+- pinctrl-names = "default";
+- #pwm-cells = <3>;
+- status = "disabled";
+- };
+-
+- pwm2: pwm@fd8b0020 {
+- compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+- reg = <0x0 0xfd8b0020 0x0 0x10>;
+- clocks = <&cru CLK_PMU1PWM>, <&cru PCLK_PMU1PWM>;
+- clock-names = "pwm", "pclk";
+- pinctrl-0 = <&pwm2m0_pins>;
+- pinctrl-names = "default";
+- #pwm-cells = <3>;
+- status = "disabled";
+- };
+-
+- pwm3: pwm@fd8b0030 {
+- compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+- reg = <0x0 0xfd8b0030 0x0 0x10>;
+- clocks = <&cru CLK_PMU1PWM>, <&cru PCLK_PMU1PWM>;
+- clock-names = "pwm", "pclk";
+- pinctrl-0 = <&pwm3m0_pins>;
+- pinctrl-names = "default";
+- #pwm-cells = <3>;
+- status = "disabled";
+- };
+-
+- pmu: power-management@fd8d8000 {
+- compatible = "rockchip,rk3588-pmu", "syscon", "simple-mfd";
+- reg = <0x0 0xfd8d8000 0x0 0x400>;
+-
+- power: power-controller {
+- compatible = "rockchip,rk3588-power-controller";
+- #address-cells = <1>;
+- #power-domain-cells = <1>;
+- #size-cells = <0>;
+- status = "okay";
+-
+- /* These power domains are grouped by VD_NPU */
+- power-domain@RK3588_PD_NPU {
+- reg = <RK3588_PD_NPU>;
+- #power-domain-cells = <0>;
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- power-domain@RK3588_PD_NPUTOP {
+- reg = <RK3588_PD_NPUTOP>;
+- clocks = <&cru HCLK_NPU_ROOT>,
+- <&cru PCLK_NPU_ROOT>,
+- <&cru CLK_NPU_DSU0>,
+- <&cru HCLK_NPU_CM0_ROOT>;
+- pm_qos = <&qos_npu0_mwr>,
+- <&qos_npu0_mro>,
+- <&qos_mcu_npu>;
+- #power-domain-cells = <0>;
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- power-domain@RK3588_PD_NPU1 {
+- reg = <RK3588_PD_NPU1>;
+- clocks = <&cru HCLK_NPU_ROOT>,
+- <&cru PCLK_NPU_ROOT>,
+- <&cru CLK_NPU_DSU0>;
+- pm_qos = <&qos_npu1>;
+- #power-domain-cells = <0>;
+- };
+- power-domain@RK3588_PD_NPU2 {
+- reg = <RK3588_PD_NPU2>;
+- clocks = <&cru HCLK_NPU_ROOT>,
+- <&cru PCLK_NPU_ROOT>,
+- <&cru CLK_NPU_DSU0>;
+- pm_qos = <&qos_npu2>;
+- #power-domain-cells = <0>;
+- };
+- };
+- };
+- /* These power domains are grouped by VD_GPU */
+- power-domain@RK3588_PD_GPU {
+- reg = <RK3588_PD_GPU>;
+- clocks = <&cru CLK_GPU>,
+- <&cru CLK_GPU_COREGROUP>,
+- <&cru CLK_GPU_STACKS>;
+- pm_qos = <&qos_gpu_m0>,
+- <&qos_gpu_m1>,
+- <&qos_gpu_m2>,
+- <&qos_gpu_m3>;
+- #power-domain-cells = <0>;
+- };
+- /* These power domains are grouped by VD_VCODEC */
+- power-domain@RK3588_PD_VCODEC {
+- reg = <RK3588_PD_VCODEC>;
+- #address-cells = <1>;
+- #size-cells = <0>;
+- #power-domain-cells = <0>;
+-
+- power-domain@RK3588_PD_RKVDEC0 {
+- reg = <RK3588_PD_RKVDEC0>;
+- clocks = <&cru HCLK_RKVDEC0>,
+- <&cru HCLK_VDPU_ROOT>,
+- <&cru ACLK_VDPU_ROOT>,
+- <&cru ACLK_RKVDEC0>,
+- <&cru ACLK_RKVDEC_CCU>;
+- pm_qos = <&qos_rkvdec0>;
+- #power-domain-cells = <0>;
+- };
+- power-domain@RK3588_PD_RKVDEC1 {
+- reg = <RK3588_PD_RKVDEC1>;
+- clocks = <&cru HCLK_RKVDEC1>,
+- <&cru HCLK_VDPU_ROOT>,
+- <&cru ACLK_VDPU_ROOT>,
+- <&cru ACLK_RKVDEC1>;
+- pm_qos = <&qos_rkvdec1>;
+- #power-domain-cells = <0>;
+- };
+- power-domain@RK3588_PD_VENC0 {
+- reg = <RK3588_PD_VENC0>;
+- clocks = <&cru HCLK_RKVENC0>,
+- <&cru ACLK_RKVENC0>;
+- pm_qos = <&qos_rkvenc0_m0ro>,
+- <&qos_rkvenc0_m1ro>,
+- <&qos_rkvenc0_m2wo>;
+- #address-cells = <1>;
+- #size-cells = <0>;
+- #power-domain-cells = <0>;
+-
+- power-domain@RK3588_PD_VENC1 {
+- reg = <RK3588_PD_VENC1>;
+- clocks = <&cru HCLK_RKVENC1>,
+- <&cru HCLK_RKVENC0>,
+- <&cru ACLK_RKVENC0>,
+- <&cru ACLK_RKVENC1>;
+- pm_qos = <&qos_rkvenc1_m0ro>,
+- <&qos_rkvenc1_m1ro>,
+- <&qos_rkvenc1_m2wo>;
+- #power-domain-cells = <0>;
+- };
+- };
+- };
+- /* These power domains are grouped by VD_LOGIC */
+- power-domain@RK3588_PD_VDPU {
+- reg = <RK3588_PD_VDPU>;
+- clocks = <&cru HCLK_VDPU_ROOT>,
+- <&cru ACLK_VDPU_LOW_ROOT>,
+- <&cru ACLK_VDPU_ROOT>,
+- <&cru ACLK_JPEG_DECODER_ROOT>,
+- <&cru ACLK_IEP2P0>,
+- <&cru HCLK_IEP2P0>,
+- <&cru ACLK_JPEG_ENCODER0>,
+- <&cru HCLK_JPEG_ENCODER0>,
+- <&cru ACLK_JPEG_ENCODER1>,
+- <&cru HCLK_JPEG_ENCODER1>,
+- <&cru ACLK_JPEG_ENCODER2>,
+- <&cru HCLK_JPEG_ENCODER2>,
+- <&cru ACLK_JPEG_ENCODER3>,
+- <&cru HCLK_JPEG_ENCODER3>,
+- <&cru ACLK_JPEG_DECODER>,
+- <&cru HCLK_JPEG_DECODER>,
+- <&cru ACLK_RGA2>,
+- <&cru HCLK_RGA2>;
+- pm_qos = <&qos_iep>,
+- <&qos_jpeg_dec>,
+- <&qos_jpeg_enc0>,
+- <&qos_jpeg_enc1>,
+- <&qos_jpeg_enc2>,
+- <&qos_jpeg_enc3>,
+- <&qos_rga2_mro>,
+- <&qos_rga2_mwo>;
+- #address-cells = <1>;
+- #size-cells = <0>;
+- #power-domain-cells = <0>;
+-
+-
+- power-domain@RK3588_PD_AV1 {
+- reg = <RK3588_PD_AV1>;
+- clocks = <&cru PCLK_AV1>,
+- <&cru ACLK_AV1>,
+- <&cru HCLK_VDPU_ROOT>;
+- pm_qos = <&qos_av1>;
+- #power-domain-cells = <0>;
+- };
+- power-domain@RK3588_PD_RKVDEC0 {
+- reg = <RK3588_PD_RKVDEC0>;
+- clocks = <&cru HCLK_RKVDEC0>,
+- <&cru HCLK_VDPU_ROOT>,
+- <&cru ACLK_VDPU_ROOT>,
+- <&cru ACLK_RKVDEC0>;
+- pm_qos = <&qos_rkvdec0>;
+- #power-domain-cells = <0>;
+- };
+- power-domain@RK3588_PD_RKVDEC1 {
+- reg = <RK3588_PD_RKVDEC1>;
+- clocks = <&cru HCLK_RKVDEC1>,
+- <&cru HCLK_VDPU_ROOT>,
+- <&cru ACLK_VDPU_ROOT>;
+- pm_qos = <&qos_rkvdec1>;
+- #power-domain-cells = <0>;
+- };
+- power-domain@RK3588_PD_RGA30 {
+- reg = <RK3588_PD_RGA30>;
+- clocks = <&cru ACLK_RGA3_0>,
+- <&cru HCLK_RGA3_0>;
+- pm_qos = <&qos_rga3_0>;
+- #power-domain-cells = <0>;
+- };
+- };
+- power-domain@RK3588_PD_VOP {
+- reg = <RK3588_PD_VOP>;
+- clocks = <&cru PCLK_VOP_ROOT>,
+- <&cru HCLK_VOP_ROOT>,
+- <&cru ACLK_VOP>;
+- pm_qos = <&qos_vop_m0>,
+- <&qos_vop_m1>;
+- #address-cells = <1>;
+- #size-cells = <0>;
+- #power-domain-cells = <0>;
+-
+- power-domain@RK3588_PD_VO0 {
+- reg = <RK3588_PD_VO0>;
+- clocks = <&cru PCLK_VO0_ROOT>,
+- <&cru PCLK_VO0_S_ROOT>,
+- <&cru HCLK_VO0_S_ROOT>,
+- <&cru ACLK_VO0_ROOT>,
+- <&cru HCLK_HDCP0>,
+- <&cru ACLK_HDCP0>,
+- <&cru HCLK_VOP_ROOT>;
+- pm_qos = <&qos_hdcp0>;
+- #power-domain-cells = <0>;
+- };
+- };
+- power-domain@RK3588_PD_VO1 {
+- reg = <RK3588_PD_VO1>;
+- clocks = <&cru PCLK_VO1_ROOT>,
+- <&cru PCLK_VO1_S_ROOT>,
+- <&cru HCLK_VO1_S_ROOT>,
+- <&cru HCLK_HDCP1>,
+- <&cru ACLK_HDCP1>,
+- <&cru ACLK_HDMIRX_ROOT>,
+- <&cru HCLK_VO1USB_TOP_ROOT>;
+- pm_qos = <&qos_hdcp1>,
+- <&qos_hdmirx>;
+- #power-domain-cells = <0>;
+- };
+- power-domain@RK3588_PD_VI {
+- reg = <RK3588_PD_VI>;
+- clocks = <&cru HCLK_VI_ROOT>,
+- <&cru PCLK_VI_ROOT>,
+- <&cru HCLK_ISP0>,
+- <&cru ACLK_ISP0>,
+- <&cru HCLK_VICAP>,
+- <&cru ACLK_VICAP>;
+- pm_qos = <&qos_isp0_mro>,
+- <&qos_isp0_mwo>,
+- <&qos_vicap_m0>,
+- <&qos_vicap_m1>;
+- #address-cells = <1>;
+- #size-cells = <0>;
+- #power-domain-cells = <0>;
+-
+- power-domain@RK3588_PD_ISP1 {
+- reg = <RK3588_PD_ISP1>;
+- clocks = <&cru HCLK_ISP1>,
+- <&cru ACLK_ISP1>,
+- <&cru HCLK_VI_ROOT>,
+- <&cru PCLK_VI_ROOT>;
+- pm_qos = <&qos_isp1_mwo>,
+- <&qos_isp1_mro>;
+- #power-domain-cells = <0>;
+- };
+- power-domain@RK3588_PD_FEC {
+- reg = <RK3588_PD_FEC>;
+- clocks = <&cru HCLK_FISHEYE0>,
+- <&cru ACLK_FISHEYE0>,
+- <&cru HCLK_FISHEYE1>,
+- <&cru ACLK_FISHEYE1>,
+- <&cru PCLK_VI_ROOT>;
+- pm_qos = <&qos_fisheye0>,
+- <&qos_fisheye1>;
+- #power-domain-cells = <0>;
+- };
+- };
+- power-domain@RK3588_PD_RGA31 {
+- reg = <RK3588_PD_RGA31>;
+- clocks = <&cru HCLK_RGA3_1>,
+- <&cru ACLK_RGA3_1>;
+- pm_qos = <&qos_rga3_1>;
+- #power-domain-cells = <0>;
+- };
+- power-domain@RK3588_PD_USB {
+- reg = <RK3588_PD_USB>;
+- clocks = <&cru PCLK_PHP_ROOT>,
+- <&cru ACLK_USB_ROOT>,
+- <&cru ACLK_USB>,
+- <&cru HCLK_USB_ROOT>,
+- <&cru HCLK_HOST0>,
+- <&cru HCLK_HOST_ARB0>,
+- <&cru HCLK_HOST1>,
+- <&cru HCLK_HOST_ARB1>;
+- pm_qos = <&qos_usb3_0>,
+- <&qos_usb3_1>,
+- <&qos_usb2host_0>,
+- <&qos_usb2host_1>;
+- #power-domain-cells = <0>;
+- };
+- power-domain@RK3588_PD_GMAC {
+- reg = <RK3588_PD_GMAC>;
+- clocks = <&cru PCLK_PHP_ROOT>,
+- <&cru ACLK_PCIE_ROOT>,
+- <&cru ACLK_PHP_ROOT>;
+- #power-domain-cells = <0>;
+- };
+- power-domain@RK3588_PD_PCIE {
+- reg = <RK3588_PD_PCIE>;
+- clocks = <&cru PCLK_PHP_ROOT>,
+- <&cru ACLK_PCIE_ROOT>,
+- <&cru ACLK_PHP_ROOT>;
+- #power-domain-cells = <0>;
+- };
+- power-domain@RK3588_PD_SDIO {
+- reg = <RK3588_PD_SDIO>;
+- clocks = <&cru HCLK_SDIO>,
+- <&cru HCLK_NVM_ROOT>;
+- pm_qos = <&qos_sdio>;
+- #power-domain-cells = <0>;
+- };
+- power-domain@RK3588_PD_AUDIO {
+- reg = <RK3588_PD_AUDIO>;
+- clocks = <&cru HCLK_AUDIO_ROOT>,
+- <&cru PCLK_AUDIO_ROOT>;
+- #power-domain-cells = <0>;
+- };
+- power-domain@RK3588_PD_SDMMC {
+- reg = <RK3588_PD_SDMMC>;
+- pm_qos = <&qos_sdmmc>;
+- #power-domain-cells = <0>;
+- };
+- };
+- };
+-
+- av1d: video-codec@fdc70000 {
+- compatible = "rockchip,rk3588-av1-vpu";
+- reg = <0x0 0xfdc70000 0x0 0x800>;
+- interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH 0>;
+- interrupt-names = "vdpu";
+- assigned-clocks = <&cru ACLK_AV1>, <&cru PCLK_AV1>;
+- assigned-clock-rates = <400000000>, <400000000>;
+- clocks = <&cru ACLK_AV1>, <&cru PCLK_AV1>;
+- clock-names = "aclk", "hclk";
+- power-domains = <&power RK3588_PD_AV1>;
+- resets = <&cru SRST_A_AV1>, <&cru SRST_P_AV1>, <&cru SRST_A_AV1_BIU>, <&cru SRST_P_AV1_BIU>;
+- };
+-
+- vop: vop@fdd90000 {
+- compatible = "rockchip,rk3588-vop";
+- reg = <0x0 0xfdd90000 0x0 0x4200>, <0x0 0xfdd95000 0x0 0x1000>;
+- reg-names = "vop", "gamma-lut";
+- interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru ACLK_VOP>,
+- <&cru HCLK_VOP>,
+- <&cru DCLK_VOP0>,
+- <&cru DCLK_VOP1>,
+- <&cru DCLK_VOP2>,
+- <&cru DCLK_VOP3>,
+- <&cru PCLK_VOP_ROOT>;
+- clock-names = "aclk",
+- "hclk",
+- "dclk_vp0",
+- "dclk_vp1",
+- "dclk_vp2",
+- "dclk_vp3",
+- "pclk_vop";
+- iommus = <&vop_mmu>;
+- power-domains = <&power RK3588_PD_VOP>;
+- rockchip,grf = <&sys_grf>;
+- rockchip,vop-grf = <&vop_grf>;
+- rockchip,vo1-grf = <&vo1_grf>;
+- rockchip,pmu = <&pmu>;
+- status = "disabled";
+-
+- vop_out: ports {
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+- vp0: port@0 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+- reg = <0>;
+- };
+-
+- vp1: port@1 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+- reg = <1>;
+- };
+-
+- vp2: port@2 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+- reg = <2>;
+- };
+-
+- vp3: port@3 {
+- #address-cells = <1>;
+- #size-cells = <0>;
+- reg = <3>;
+- };
+- };
+- };
+-
+- vop_mmu: iommu@fdd97e00 {
+- compatible = "rockchip,rk3588-iommu", "rockchip,rk3568-iommu";
+- reg = <0x0 0xfdd97e00 0x0 0x100>, <0x0 0xfdd97f00 0x0 0x100>;
+- interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru ACLK_VOP>, <&cru HCLK_VOP>;
+- clock-names = "aclk", "iface";
+- #iommu-cells = <0>;
+- power-domains = <&power RK3588_PD_VOP>;
+- status = "disabled";
+- };
+-
+- i2s4_8ch: i2s@fddc0000 {
+- compatible = "rockchip,rk3588-i2s-tdm";
+- reg = <0x0 0xfddc0000 0x0 0x1000>;
+- interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru MCLK_I2S4_8CH_TX>, <&cru MCLK_I2S4_8CH_TX>, <&cru HCLK_I2S4_8CH>;
+- clock-names = "mclk_tx", "mclk_rx", "hclk";
+- assigned-clocks = <&cru CLK_I2S4_8CH_TX_SRC>;
+- assigned-clock-parents = <&cru PLL_AUPLL>;
+- dmas = <&dmac2 0>;
+- dma-names = "tx";
+- power-domains = <&power RK3588_PD_VO0>;
+- resets = <&cru SRST_M_I2S4_8CH_TX>;
+- reset-names = "tx-m";
+- #sound-dai-cells = <0>;
+- status = "disabled";
+- };
+-
+- i2s5_8ch: i2s@fddf0000 {
+- compatible = "rockchip,rk3588-i2s-tdm";
+- reg = <0x0 0xfddf0000 0x0 0x1000>;
+- interrupts = <GIC_SPI 185 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru MCLK_I2S5_8CH_TX>, <&cru MCLK_I2S5_8CH_TX>, <&cru HCLK_I2S5_8CH>;
+- clock-names = "mclk_tx", "mclk_rx", "hclk";
+- assigned-clocks = <&cru CLK_I2S5_8CH_TX_SRC>;
+- assigned-clock-parents = <&cru PLL_AUPLL>;
+- dmas = <&dmac2 2>;
+- dma-names = "tx";
+- power-domains = <&power RK3588_PD_VO1>;
+- resets = <&cru SRST_M_I2S5_8CH_TX>;
+- reset-names = "tx-m";
+- #sound-dai-cells = <0>;
+- status = "disabled";
+- };
+-
+- i2s9_8ch: i2s@fddfc000 {
+- compatible = "rockchip,rk3588-i2s-tdm";
+- reg = <0x0 0xfddfc000 0x0 0x1000>;
+- interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru MCLK_I2S9_8CH_RX>, <&cru MCLK_I2S9_8CH_RX>, <&cru HCLK_I2S9_8CH>;
+- clock-names = "mclk_tx", "mclk_rx", "hclk";
+- assigned-clocks = <&cru CLK_I2S9_8CH_RX_SRC>;
+- assigned-clock-parents = <&cru PLL_AUPLL>;
+- dmas = <&dmac2 23>;
+- dma-names = "rx";
+- power-domains = <&power RK3588_PD_VO1>;
+- resets = <&cru SRST_M_I2S9_8CH_RX>;
+- reset-names = "rx-m";
+- #sound-dai-cells = <0>;
+- status = "disabled";
+- };
+-
+- qos_gpu_m0: qos@fdf35000 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf35000 0x0 0x20>;
+- };
+-
+- qos_gpu_m1: qos@fdf35200 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf35200 0x0 0x20>;
+- };
+-
+- qos_gpu_m2: qos@fdf35400 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf35400 0x0 0x20>;
+- };
+-
+- qos_gpu_m3: qos@fdf35600 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf35600 0x0 0x20>;
+- };
+-
+- qos_rga3_1: qos@fdf36000 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf36000 0x0 0x20>;
+- };
+-
+- qos_sdio: qos@fdf39000 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf39000 0x0 0x20>;
+- };
+-
+- qos_sdmmc: qos@fdf3d800 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf3d800 0x0 0x20>;
+- };
+-
+- qos_usb3_1: qos@fdf3e000 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf3e000 0x0 0x20>;
+- };
+-
+- qos_usb3_0: qos@fdf3e200 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf3e200 0x0 0x20>;
+- };
+-
+- qos_usb2host_0: qos@fdf3e400 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf3e400 0x0 0x20>;
+- };
+-
+- qos_usb2host_1: qos@fdf3e600 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf3e600 0x0 0x20>;
+- };
+-
+- qos_fisheye0: qos@fdf40000 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf40000 0x0 0x20>;
+- };
+-
+- qos_fisheye1: qos@fdf40200 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf40200 0x0 0x20>;
+- };
+-
+- qos_isp0_mro: qos@fdf40400 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf40400 0x0 0x20>;
+- };
+-
+- qos_isp0_mwo: qos@fdf40500 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf40500 0x0 0x20>;
+- };
+-
+- qos_vicap_m0: qos@fdf40600 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf40600 0x0 0x20>;
+- };
+-
+- qos_vicap_m1: qos@fdf40800 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf40800 0x0 0x20>;
+- };
+-
+- qos_isp1_mwo: qos@fdf41000 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf41000 0x0 0x20>;
+- };
+-
+- qos_isp1_mro: qos@fdf41100 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf41100 0x0 0x20>;
+- };
+-
+- qos_rkvenc0_m0ro: qos@fdf60000 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf60000 0x0 0x20>;
+- };
+-
+- qos_rkvenc0_m1ro: qos@fdf60200 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf60200 0x0 0x20>;
+- };
+-
+- qos_rkvenc0_m2wo: qos@fdf60400 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf60400 0x0 0x20>;
+- };
+-
+- qos_rkvenc1_m0ro: qos@fdf61000 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf61000 0x0 0x20>;
+- };
+-
+- qos_rkvenc1_m1ro: qos@fdf61200 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf61200 0x0 0x20>;
+- };
+-
+- qos_rkvenc1_m2wo: qos@fdf61400 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf61400 0x0 0x20>;
+- };
+-
+- qos_rkvdec0: qos@fdf62000 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf62000 0x0 0x20>;
+- };
+-
+- qos_rkvdec1: qos@fdf63000 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf63000 0x0 0x20>;
+- };
+-
+- qos_av1: qos@fdf64000 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf64000 0x0 0x20>;
+- };
+-
+- qos_iep: qos@fdf66000 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf66000 0x0 0x20>;
+- };
+-
+- qos_jpeg_dec: qos@fdf66200 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf66200 0x0 0x20>;
+- };
+-
+- qos_jpeg_enc0: qos@fdf66400 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf66400 0x0 0x20>;
+- };
+-
+- qos_jpeg_enc1: qos@fdf66600 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf66600 0x0 0x20>;
+- };
+-
+- qos_jpeg_enc2: qos@fdf66800 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf66800 0x0 0x20>;
+- };
+-
+- qos_jpeg_enc3: qos@fdf66a00 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf66a00 0x0 0x20>;
+- };
+-
+- qos_rga2_mro: qos@fdf66c00 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf66c00 0x0 0x20>;
+- };
+-
+- qos_rga2_mwo: qos@fdf66e00 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf66e00 0x0 0x20>;
+- };
+-
+- qos_rga3_0: qos@fdf67000 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf67000 0x0 0x20>;
+- };
+-
+- qos_vdpu: qos@fdf67200 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf67200 0x0 0x20>;
+- };
+-
+- qos_npu1: qos@fdf70000 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf70000 0x0 0x20>;
+- };
+-
+- qos_npu2: qos@fdf71000 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf71000 0x0 0x20>;
+- };
+-
+- qos_npu0_mwr: qos@fdf72000 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf72000 0x0 0x20>;
+- };
+-
+- qos_npu0_mro: qos@fdf72200 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf72200 0x0 0x20>;
+- };
+-
+- qos_mcu_npu: qos@fdf72400 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf72400 0x0 0x20>;
+- };
+-
+- qos_hdcp0: qos@fdf80000 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf80000 0x0 0x20>;
+- };
+-
+- qos_hdcp1: qos@fdf81000 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf81000 0x0 0x20>;
+- };
+-
+- qos_hdmirx: qos@fdf81200 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf81200 0x0 0x20>;
+- };
+-
+- qos_vop_m0: qos@fdf82000 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf82000 0x0 0x20>;
+- };
+-
+- qos_vop_m1: qos@fdf82200 {
+- compatible = "rockchip,rk3588-qos", "syscon";
+- reg = <0x0 0xfdf82200 0x0 0x20>;
+- };
+-
+- dfi: dfi@fe060000 {
+- reg = <0x00 0xfe060000 0x00 0x10000>;
+- compatible = "rockchip,rk3588-dfi";
+- interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH 0>;
+- rockchip,pmu = <&pmu1grf>;
+- };
+-
+- pcie2x1l1: pcie@fe180000 {
+- compatible = "rockchip,rk3588-pcie", "rockchip,rk3568-pcie";
+- bus-range = <0x30 0x3f>;
+- clocks = <&cru ACLK_PCIE_1L1_MSTR>, <&cru ACLK_PCIE_1L1_SLV>,
+- <&cru ACLK_PCIE_1L1_DBI>, <&cru PCLK_PCIE_1L1>,
+- <&cru CLK_PCIE_AUX3>, <&cru CLK_PCIE1L1_PIPE>;
+- clock-names = "aclk_mst", "aclk_slv",
+- "aclk_dbi", "pclk",
+- "aux", "pipe";
+- device_type = "pci";
+- interrupts = <GIC_SPI 248 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 247 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 245 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 244 IRQ_TYPE_LEVEL_HIGH 0>;
+- interrupt-names = "sys", "pmc", "msg", "legacy", "err";
+- #interrupt-cells = <1>;
+- interrupt-map-mask = <0 0 0 7>;
+- interrupt-map = <0 0 0 1 &pcie2x1l1_intc 0>,
+- <0 0 0 2 &pcie2x1l1_intc 1>,
+- <0 0 0 3 &pcie2x1l1_intc 2>,
+- <0 0 0 4 &pcie2x1l1_intc 3>;
+- linux,pci-domain = <3>;
+- max-link-speed = <2>;
+- msi-map = <0x3000 &its0 0x3000 0x1000>;
+- num-lanes = <1>;
+- phys = <&combphy2_psu PHY_TYPE_PCIE>;
+- phy-names = "pcie-phy";
+- power-domains = <&power RK3588_PD_PCIE>;
+- ranges = <0x01000000 0x0 0xf3100000 0x0 0xf3100000 0x0 0x00100000>,
+- <0x02000000 0x0 0xf3200000 0x0 0xf3200000 0x0 0x00e00000>,
+- <0x03000000 0x0 0x40000000 0x9 0xc0000000 0x0 0x40000000>;
+- reg = <0xa 0x40c00000 0x0 0x00400000>,
+- <0x0 0xfe180000 0x0 0x00010000>,
+- <0x0 0xf3000000 0x0 0x00100000>;
+- reg-names = "dbi", "apb", "config";
+- resets = <&cru SRST_PCIE3_POWER_UP>, <&cru SRST_P_PCIE3>;
+- reset-names = "pwr", "pipe";
+- #address-cells = <3>;
+- #size-cells = <2>;
+- status = "disabled";
+-
+- pcie2x1l1_intc: legacy-interrupt-controller {
+- interrupt-controller;
+- #address-cells = <0>;
+- #interrupt-cells = <1>;
+- interrupt-parent = <&gic>;
+- interrupts = <GIC_SPI 245 IRQ_TYPE_EDGE_RISING 0>;
+- };
+- };
+-
+- pcie2x1l2: pcie@fe190000 {
+- compatible = "rockchip,rk3588-pcie", "rockchip,rk3568-pcie";
+- bus-range = <0x40 0x4f>;
+- clocks = <&cru ACLK_PCIE_1L2_MSTR>, <&cru ACLK_PCIE_1L2_SLV>,
+- <&cru ACLK_PCIE_1L2_DBI>, <&cru PCLK_PCIE_1L2>,
+- <&cru CLK_PCIE_AUX4>, <&cru CLK_PCIE1L2_PIPE>;
+- clock-names = "aclk_mst", "aclk_slv",
+- "aclk_dbi", "pclk",
+- "aux", "pipe";
+- device_type = "pci";
+- interrupts = <GIC_SPI 253 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 252 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 251 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 250 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 249 IRQ_TYPE_LEVEL_HIGH 0>;
+- interrupt-names = "sys", "pmc", "msg", "legacy", "err";
+- #interrupt-cells = <1>;
+- interrupt-map-mask = <0 0 0 7>;
+- interrupt-map = <0 0 0 1 &pcie2x1l2_intc 0>,
+- <0 0 0 2 &pcie2x1l2_intc 1>,
+- <0 0 0 3 &pcie2x1l2_intc 2>,
+- <0 0 0 4 &pcie2x1l2_intc 3>;
+- linux,pci-domain = <4>;
+- max-link-speed = <2>;
+- msi-map = <0x4000 &its0 0x4000 0x1000>;
+- num-lanes = <1>;
+- phys = <&combphy0_ps PHY_TYPE_PCIE>;
+- phy-names = "pcie-phy";
+- power-domains = <&power RK3588_PD_PCIE>;
+- ranges = <0x01000000 0x0 0xf4100000 0x0 0xf4100000 0x0 0x00100000>,
+- <0x02000000 0x0 0xf4200000 0x0 0xf4200000 0x0 0x00e00000>,
+- <0x03000000 0x0 0x40000000 0xa 0x00000000 0x0 0x40000000>;
+- reg = <0xa 0x41000000 0x0 0x00400000>,
+- <0x0 0xfe190000 0x0 0x00010000>,
+- <0x0 0xf4000000 0x0 0x00100000>;
+- reg-names = "dbi", "apb", "config";
+- resets = <&cru SRST_PCIE4_POWER_UP>, <&cru SRST_P_PCIE4>;
+- reset-names = "pwr", "pipe";
+- #address-cells = <3>;
+- #size-cells = <2>;
+- status = "disabled";
+-
+- pcie2x1l2_intc: legacy-interrupt-controller {
+- interrupt-controller;
+- #address-cells = <0>;
+- #interrupt-cells = <1>;
+- interrupt-parent = <&gic>;
+- interrupts = <GIC_SPI 250 IRQ_TYPE_EDGE_RISING 0>;
+- };
+- };
+-
+- gmac1: ethernet@fe1c0000 {
+- compatible = "rockchip,rk3588-gmac", "snps,dwmac-4.20a";
+- reg = <0x0 0xfe1c0000 0x0 0x10000>;
+- interrupts = <GIC_SPI 234 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 233 IRQ_TYPE_LEVEL_HIGH 0>;
+- interrupt-names = "macirq", "eth_wake_irq";
+- clocks = <&cru CLK_GMAC_125M>, <&cru CLK_GMAC_50M>,
+- <&cru PCLK_GMAC1>, <&cru ACLK_GMAC1>,
+- <&cru CLK_GMAC1_PTP_REF>;
+- clock-names = "stmmaceth", "clk_mac_ref",
+- "pclk_mac", "aclk_mac",
+- "ptp_ref";
+- power-domains = <&power RK3588_PD_GMAC>;
+- resets = <&cru SRST_A_GMAC1>;
+- reset-names = "stmmaceth";
+- rockchip,grf = <&sys_grf>;
+- rockchip,php-grf = <&php_grf>;
+- snps,axi-config = <&gmac1_stmmac_axi_setup>;
+- snps,mixed-burst;
+- snps,mtl-rx-config = <&gmac1_mtl_rx_setup>;
+- snps,mtl-tx-config = <&gmac1_mtl_tx_setup>;
+- snps,tso;
+- status = "disabled";
+-
+- mdio1: mdio {
+- compatible = "snps,dwmac-mdio";
+- #address-cells = <0x1>;
+- #size-cells = <0x0>;
+- };
+-
+- gmac1_stmmac_axi_setup: stmmac-axi-config {
+- snps,blen = <0 0 0 0 16 8 4>;
+- snps,wr_osr_lmt = <4>;
+- snps,rd_osr_lmt = <8>;
+- };
+-
+- gmac1_mtl_rx_setup: rx-queues-config {
+- snps,rx-queues-to-use = <2>;
+- queue0 {};
+- queue1 {};
+- };
+-
+- gmac1_mtl_tx_setup: tx-queues-config {
+- snps,tx-queues-to-use = <2>;
+- queue0 {};
+- queue1 {};
+- };
+- };
+-
+- sata0: sata@fe210000 {
+- compatible = "rockchip,rk3588-dwc-ahci", "snps,dwc-ahci";
+- reg = <0 0xfe210000 0 0x1000>;
+- interrupts = <GIC_SPI 273 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru ACLK_SATA0>, <&cru CLK_PMALIVE0>,
+- <&cru CLK_RXOOB0>, <&cru CLK_PIPEPHY0_REF>,
+- <&cru CLK_PIPEPHY0_PIPE_ASIC_G>;
+- clock-names = "sata", "pmalive", "rxoob", "ref", "asic";
+- ports-implemented = <0x1>;
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+-
+- sata-port@0 {
+- reg = <0>;
+- hba-port-cap = <HBA_PORT_FBSCP>;
+- phys = <&combphy0_ps PHY_TYPE_SATA>;
+- phy-names = "sata-phy";
+- snps,rx-ts-max = <32>;
+- snps,tx-ts-max = <32>;
+- };
+- };
+-
+- sata2: sata@fe230000 {
+- compatible = "rockchip,rk3588-dwc-ahci", "snps,dwc-ahci";
+- reg = <0 0xfe230000 0 0x1000>;
+- interrupts = <GIC_SPI 275 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru ACLK_SATA2>, <&cru CLK_PMALIVE2>,
+- <&cru CLK_RXOOB2>, <&cru CLK_PIPEPHY2_REF>,
+- <&cru CLK_PIPEPHY2_PIPE_ASIC_G>;
+- clock-names = "sata", "pmalive", "rxoob", "ref", "asic";
+- ports-implemented = <0x1>;
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+-
+- sata-port@0 {
+- reg = <0>;
+- hba-port-cap = <HBA_PORT_FBSCP>;
+- phys = <&combphy2_psu PHY_TYPE_SATA>;
+- phy-names = "sata-phy";
+- snps,rx-ts-max = <32>;
+- snps,tx-ts-max = <32>;
+- };
+- };
+-
+- sfc: spi@fe2b0000 {
+- compatible = "rockchip,sfc";
+- reg = <0x0 0xfe2b0000 0x0 0x4000>;
+- interrupts = <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru SCLK_SFC>, <&cru HCLK_SFC>;
+- clock-names = "clk_sfc", "hclk_sfc";
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- sdmmc: mmc@fe2c0000 {
+- compatible = "rockchip,rk3588-dw-mshc", "rockchip,rk3288-dw-mshc";
+- reg = <0x0 0xfe2c0000 0x0 0x4000>;
+- interrupts = <GIC_SPI 203 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&scmi_clk SCMI_HCLK_SD>, <&scmi_clk SCMI_CCLK_SD>,
+- <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>;
+- clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
+- fifo-depth = <0x100>;
+- max-frequency = <200000000>;
+- pinctrl-names = "default";
+- pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_det &sdmmc_bus4>;
+- power-domains = <&power RK3588_PD_SDMMC>;
+- status = "disabled";
+- };
+-
+- sdio: mmc@fe2d0000 {
+- compatible = "rockchip,rk3588-dw-mshc", "rockchip,rk3288-dw-mshc";
+- reg = <0x00 0xfe2d0000 0x00 0x4000>;
+- interrupts = <GIC_SPI 204 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru HCLK_SDIO>, <&cru CCLK_SRC_SDIO>,
+- <&cru SCLK_SDIO_DRV>, <&cru SCLK_SDIO_SAMPLE>;
+- clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
+- fifo-depth = <0x100>;
+- max-frequency = <200000000>;
+- pinctrl-names = "default";
+- pinctrl-0 = <&sdiom1_pins>;
+- power-domains = <&power RK3588_PD_SDIO>;
+- status = "disabled";
+- };
+-
+- sdhci: mmc@fe2e0000 {
+- compatible = "rockchip,rk3588-dwcmshc";
+- reg = <0x0 0xfe2e0000 0x0 0x10000>;
+- interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH 0>;
+- assigned-clocks = <&cru BCLK_EMMC>, <&cru TMCLK_EMMC>, <&cru CCLK_EMMC>;
+- assigned-clock-rates = <200000000>, <24000000>, <200000000>;
+- clocks = <&cru CCLK_EMMC>, <&cru HCLK_EMMC>,
+- <&cru ACLK_EMMC>, <&cru BCLK_EMMC>,
+- <&cru TMCLK_EMMC>;
+- clock-names = "core", "bus", "axi", "block", "timer";
+- max-frequency = <200000000>;
+- pinctrl-0 = <&emmc_rstnout>, <&emmc_bus8>, <&emmc_clk>,
+- <&emmc_cmd>, <&emmc_data_strobe>;
+- pinctrl-names = "default";
+- resets = <&cru SRST_C_EMMC>, <&cru SRST_H_EMMC>,
+- <&cru SRST_A_EMMC>, <&cru SRST_B_EMMC>,
+- <&cru SRST_T_EMMC>;
+- reset-names = "core", "bus", "axi", "block", "timer";
+- status = "disabled";
+- };
+-
+- i2s0_8ch: i2s@fe470000 {
+- compatible = "rockchip,rk3588-i2s-tdm";
+- reg = <0x0 0xfe470000 0x0 0x1000>;
+- interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru MCLK_I2S0_8CH_TX>, <&cru MCLK_I2S0_8CH_RX>, <&cru HCLK_I2S0_8CH>;
+- clock-names = "mclk_tx", "mclk_rx", "hclk";
+- assigned-clocks = <&cru CLK_I2S0_8CH_TX_SRC>, <&cru CLK_I2S0_8CH_RX_SRC>;
+- assigned-clock-parents = <&cru PLL_AUPLL>, <&cru PLL_AUPLL>;
+- dmas = <&dmac0 0>, <&dmac0 1>;
+- dma-names = "tx", "rx";
+- power-domains = <&power RK3588_PD_AUDIO>;
+- resets = <&cru SRST_M_I2S0_8CH_TX>, <&cru SRST_M_I2S0_8CH_RX>;
+- reset-names = "tx-m", "rx-m";
+- rockchip,trcm-sync-tx-only;
+- pinctrl-names = "default";
+- pinctrl-0 = <&i2s0_lrck
+- &i2s0_sclk
+- &i2s0_sdi0
+- &i2s0_sdi1
+- &i2s0_sdi2
+- &i2s0_sdi3
+- &i2s0_sdo0
+- &i2s0_sdo1
+- &i2s0_sdo2
+- &i2s0_sdo3>;
+- #sound-dai-cells = <0>;
+- status = "disabled";
+- };
+-
+- i2s1_8ch: i2s@fe480000 {
+- compatible = "rockchip,rk3588-i2s-tdm";
+- reg = <0x0 0xfe480000 0x0 0x1000>;
+- interrupts = <GIC_SPI 181 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru MCLK_I2S1_8CH_TX>, <&cru MCLK_I2S1_8CH_RX>, <&cru HCLK_I2S1_8CH>;
+- clock-names = "mclk_tx", "mclk_rx", "hclk";
+- dmas = <&dmac0 2>, <&dmac0 3>;
+- dma-names = "tx", "rx";
+- resets = <&cru SRST_M_I2S1_8CH_TX>, <&cru SRST_M_I2S1_8CH_RX>;
+- reset-names = "tx-m", "rx-m";
+- rockchip,trcm-sync-tx-only;
+- pinctrl-names = "default";
+- pinctrl-0 = <&i2s1m0_lrck
+- &i2s1m0_sclk
+- &i2s1m0_sdi0
+- &i2s1m0_sdi1
+- &i2s1m0_sdi2
+- &i2s1m0_sdi3
+- &i2s1m0_sdo0
+- &i2s1m0_sdo1
+- &i2s1m0_sdo2
+- &i2s1m0_sdo3>;
+- #sound-dai-cells = <0>;
+- status = "disabled";
+- };
+-
+- i2s2_2ch: i2s@fe490000 {
+- compatible = "rockchip,rk3588-i2s", "rockchip,rk3066-i2s";
+- reg = <0x0 0xfe490000 0x0 0x1000>;
+- interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru MCLK_I2S2_2CH>, <&cru HCLK_I2S2_2CH>;
+- clock-names = "i2s_clk", "i2s_hclk";
+- assigned-clocks = <&cru CLK_I2S2_2CH_SRC>;
+- assigned-clock-parents = <&cru PLL_AUPLL>;
+- dmas = <&dmac1 0>, <&dmac1 1>;
+- dma-names = "tx", "rx";
+- power-domains = <&power RK3588_PD_AUDIO>;
+- pinctrl-names = "default";
+- pinctrl-0 = <&i2s2m1_lrck
+- &i2s2m1_sclk
+- &i2s2m1_sdi
+- &i2s2m1_sdo>;
+- #sound-dai-cells = <0>;
+- status = "disabled";
+- };
+-
+- i2s3_2ch: i2s@fe4a0000 {
+- compatible = "rockchip,rk3588-i2s", "rockchip,rk3066-i2s";
+- reg = <0x0 0xfe4a0000 0x0 0x1000>;
+- interrupts = <GIC_SPI 183 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru MCLK_I2S3_2CH>, <&cru HCLK_I2S3_2CH>;
+- clock-names = "i2s_clk", "i2s_hclk";
+- assigned-clocks = <&cru CLK_I2S3_2CH_SRC>;
+- assigned-clock-parents = <&cru PLL_AUPLL>;
+- dmas = <&dmac1 2>, <&dmac1 3>;
+- dma-names = "tx", "rx";
+- power-domains = <&power RK3588_PD_AUDIO>;
+- pinctrl-names = "default";
+- pinctrl-0 = <&i2s3_lrck
+- &i2s3_sclk
+- &i2s3_sdi
+- &i2s3_sdo>;
+- #sound-dai-cells = <0>;
+- status = "disabled";
+- };
+-
+- gic: interrupt-controller@fe600000 {
+- compatible = "arm,gic-v3";
+- reg = <0x0 0xfe600000 0 0x10000>, /* GICD */
+- <0x0 0xfe680000 0 0x100000>; /* GICR */
+- interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH 0>;
+- interrupt-controller;
+- mbi-alias = <0x0 0xfe610000>;
+- mbi-ranges = <424 56>;
+- msi-controller;
+- ranges;
+- #address-cells = <2>;
+- #interrupt-cells = <4>;
+- #size-cells = <2>;
+-
+- its0: msi-controller@fe640000 {
+- compatible = "arm,gic-v3-its";
+- reg = <0x0 0xfe640000 0x0 0x20000>;
+- msi-controller;
+- #msi-cells = <1>;
+- };
+-
+- its1: msi-controller@fe660000 {
+- compatible = "arm,gic-v3-its";
+- reg = <0x0 0xfe660000 0x0 0x20000>;
+- msi-controller;
+- #msi-cells = <1>;
+- };
+-
+- ppi-partitions {
+- ppi_partition0: interrupt-partition-0 {
+- affinity = <&cpu_l0 &cpu_l1 &cpu_l2 &cpu_l3>;
+- };
+-
+- ppi_partition1: interrupt-partition-1 {
+- affinity = <&cpu_b0 &cpu_b1 &cpu_b2 &cpu_b3>;
+- };
+- };
+- };
+-
+- dmac0: dma-controller@fea10000 {
+- compatible = "arm,pl330", "arm,primecell";
+- reg = <0x0 0xfea10000 0x0 0x4000>;
+- interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH 0>;
+- arm,pl330-periph-burst;
+- clocks = <&cru ACLK_DMAC0>;
+- clock-names = "apb_pclk";
+- #dma-cells = <1>;
+- };
+-
+- dmac1: dma-controller@fea30000 {
+- compatible = "arm,pl330", "arm,primecell";
+- reg = <0x0 0xfea30000 0x0 0x4000>;
+- interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH 0>;
+- arm,pl330-periph-burst;
+- clocks = <&cru ACLK_DMAC1>;
+- clock-names = "apb_pclk";
+- #dma-cells = <1>;
+- };
+-
+- i2c1: i2c@fea90000 {
+- compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
+- reg = <0x0 0xfea90000 0x0 0x1000>;
+- clocks = <&cru CLK_I2C1>, <&cru PCLK_I2C1>;
+- clock-names = "i2c", "pclk";
+- interrupts = <GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH 0>;
+- pinctrl-0 = <&i2c1m0_xfer>;
+- pinctrl-names = "default";
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- i2c2: i2c@feaa0000 {
+- compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
+- reg = <0x0 0xfeaa0000 0x0 0x1000>;
+- clocks = <&cru CLK_I2C2>, <&cru PCLK_I2C2>;
+- clock-names = "i2c", "pclk";
+- interrupts = <GIC_SPI 319 IRQ_TYPE_LEVEL_HIGH 0>;
+- pinctrl-0 = <&i2c2m0_xfer>;
+- pinctrl-names = "default";
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- i2c3: i2c@feab0000 {
+- compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
+- reg = <0x0 0xfeab0000 0x0 0x1000>;
+- clocks = <&cru CLK_I2C3>, <&cru PCLK_I2C3>;
+- clock-names = "i2c", "pclk";
+- interrupts = <GIC_SPI 320 IRQ_TYPE_LEVEL_HIGH 0>;
+- pinctrl-0 = <&i2c3m0_xfer>;
+- pinctrl-names = "default";
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- i2c4: i2c@feac0000 {
+- compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
+- reg = <0x0 0xfeac0000 0x0 0x1000>;
+- clocks = <&cru CLK_I2C4>, <&cru PCLK_I2C4>;
+- clock-names = "i2c", "pclk";
+- interrupts = <GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH 0>;
+- pinctrl-0 = <&i2c4m0_xfer>;
+- pinctrl-names = "default";
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- i2c5: i2c@fead0000 {
+- compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
+- reg = <0x0 0xfead0000 0x0 0x1000>;
+- clocks = <&cru CLK_I2C5>, <&cru PCLK_I2C5>;
+- clock-names = "i2c", "pclk";
+- interrupts = <GIC_SPI 322 IRQ_TYPE_LEVEL_HIGH 0>;
+- pinctrl-0 = <&i2c5m0_xfer>;
+- pinctrl-names = "default";
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- timer0: timer@feae0000 {
+- compatible = "rockchip,rk3588-timer", "rockchip,rk3288-timer";
+- reg = <0x0 0xfeae0000 0x0 0x20>;
+- interrupts = <GIC_SPI 289 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru PCLK_BUSTIMER0>, <&cru CLK_BUSTIMER0>;
+- clock-names = "pclk", "timer";
+- };
+-
+- wdt: watchdog@feaf0000 {
+- compatible = "rockchip,rk3588-wdt", "snps,dw-wdt";
+- reg = <0x0 0xfeaf0000 0x0 0x100>;
+- clocks = <&cru TCLK_WDT0>, <&cru PCLK_WDT0>;
+- clock-names = "tclk", "pclk";
+- interrupts = <GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH 0>;
+- };
+-
+- spi0: spi@feb00000 {
+- compatible = "rockchip,rk3588-spi", "rockchip,rk3066-spi";
+- reg = <0x0 0xfeb00000 0x0 0x1000>;
+- interrupts = <GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru CLK_SPI0>, <&cru PCLK_SPI0>;
+- clock-names = "spiclk", "apb_pclk";
+- dmas = <&dmac0 14>, <&dmac0 15>;
+- dma-names = "tx", "rx";
+- num-cs = <2>;
+- pinctrl-0 = <&spi0m0_cs0 &spi0m0_cs1 &spi0m0_pins>;
+- pinctrl-names = "default";
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- spi1: spi@feb10000 {
+- compatible = "rockchip,rk3588-spi", "rockchip,rk3066-spi";
+- reg = <0x0 0xfeb10000 0x0 0x1000>;
+- interrupts = <GIC_SPI 327 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru CLK_SPI1>, <&cru PCLK_SPI1>;
+- clock-names = "spiclk", "apb_pclk";
+- dmas = <&dmac0 16>, <&dmac0 17>;
+- dma-names = "tx", "rx";
+- num-cs = <2>;
+- pinctrl-0 = <&spi1m1_cs0 &spi1m1_cs1 &spi1m1_pins>;
+- pinctrl-names = "default";
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- spi2: spi@feb20000 {
+- compatible = "rockchip,rk3588-spi", "rockchip,rk3066-spi";
+- reg = <0x0 0xfeb20000 0x0 0x1000>;
+- interrupts = <GIC_SPI 328 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru CLK_SPI2>, <&cru PCLK_SPI2>;
+- clock-names = "spiclk", "apb_pclk";
+- dmas = <&dmac1 15>, <&dmac1 16>;
+- dma-names = "tx", "rx";
+- num-cs = <2>;
+- pinctrl-0 = <&spi2m2_cs0 &spi2m2_cs1 &spi2m2_pins>;
+- pinctrl-names = "default";
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- spi3: spi@feb30000 {
+- compatible = "rockchip,rk3588-spi", "rockchip,rk3066-spi";
+- reg = <0x0 0xfeb30000 0x0 0x1000>;
+- interrupts = <GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru CLK_SPI3>, <&cru PCLK_SPI3>;
+- clock-names = "spiclk", "apb_pclk";
+- dmas = <&dmac1 17>, <&dmac1 18>;
+- dma-names = "tx", "rx";
+- num-cs = <2>;
+- pinctrl-0 = <&spi3m1_cs0 &spi3m1_cs1 &spi3m1_pins>;
+- pinctrl-names = "default";
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- uart1: serial@feb40000 {
+- compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
+- reg = <0x0 0xfeb40000 0x0 0x100>;
+- interrupts = <GIC_SPI 332 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru SCLK_UART1>, <&cru PCLK_UART1>;
+- clock-names = "baudclk", "apb_pclk";
+- dmas = <&dmac0 8>, <&dmac0 9>;
+- dma-names = "tx", "rx";
+- pinctrl-0 = <&uart1m1_xfer>;
+- pinctrl-names = "default";
+- reg-io-width = <4>;
+- reg-shift = <2>;
+- status = "disabled";
+- };
+-
+- uart2: serial@feb50000 {
+- compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
+- reg = <0x0 0xfeb50000 0x0 0x100>;
+- interrupts = <GIC_SPI 333 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>;
+- clock-names = "baudclk", "apb_pclk";
+- dmas = <&dmac0 10>, <&dmac0 11>;
+- dma-names = "tx", "rx";
+- pinctrl-0 = <&uart2m1_xfer>;
+- pinctrl-names = "default";
+- reg-io-width = <4>;
+- reg-shift = <2>;
+- status = "disabled";
+- };
+-
+- uart3: serial@feb60000 {
+- compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
+- reg = <0x0 0xfeb60000 0x0 0x100>;
+- interrupts = <GIC_SPI 334 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru SCLK_UART3>, <&cru PCLK_UART3>;
+- clock-names = "baudclk", "apb_pclk";
+- dmas = <&dmac0 12>, <&dmac0 13>;
+- dma-names = "tx", "rx";
+- pinctrl-0 = <&uart3m1_xfer>;
+- pinctrl-names = "default";
+- reg-io-width = <4>;
+- reg-shift = <2>;
+- status = "disabled";
+- };
+-
+- uart4: serial@feb70000 {
+- compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
+- reg = <0x0 0xfeb70000 0x0 0x100>;
+- interrupts = <GIC_SPI 335 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru SCLK_UART4>, <&cru PCLK_UART4>;
+- clock-names = "baudclk", "apb_pclk";
+- dmas = <&dmac1 9>, <&dmac1 10>;
+- dma-names = "tx", "rx";
+- pinctrl-0 = <&uart4m1_xfer>;
+- pinctrl-names = "default";
+- reg-io-width = <4>;
+- reg-shift = <2>;
+- status = "disabled";
+- };
+-
+- uart5: serial@feb80000 {
+- compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
+- reg = <0x0 0xfeb80000 0x0 0x100>;
+- interrupts = <GIC_SPI 336 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru SCLK_UART5>, <&cru PCLK_UART5>;
+- clock-names = "baudclk", "apb_pclk";
+- dmas = <&dmac1 11>, <&dmac1 12>;
+- dma-names = "tx", "rx";
+- pinctrl-0 = <&uart5m1_xfer>;
+- pinctrl-names = "default";
+- reg-io-width = <4>;
+- reg-shift = <2>;
+- status = "disabled";
+- };
+-
+- uart6: serial@feb90000 {
+- compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
+- reg = <0x0 0xfeb90000 0x0 0x100>;
+- interrupts = <GIC_SPI 337 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru SCLK_UART6>, <&cru PCLK_UART6>;
+- clock-names = "baudclk", "apb_pclk";
+- dmas = <&dmac1 13>, <&dmac1 14>;
+- dma-names = "tx", "rx";
+- pinctrl-0 = <&uart6m1_xfer>;
+- pinctrl-names = "default";
+- reg-io-width = <4>;
+- reg-shift = <2>;
+- status = "disabled";
+- };
+-
+- uart7: serial@feba0000 {
+- compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
+- reg = <0x0 0xfeba0000 0x0 0x100>;
+- interrupts = <GIC_SPI 338 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru SCLK_UART7>, <&cru PCLK_UART7>;
+- clock-names = "baudclk", "apb_pclk";
+- dmas = <&dmac2 7>, <&dmac2 8>;
+- dma-names = "tx", "rx";
+- pinctrl-0 = <&uart7m1_xfer>;
+- pinctrl-names = "default";
+- reg-io-width = <4>;
+- reg-shift = <2>;
+- status = "disabled";
+- };
+-
+- uart8: serial@febb0000 {
+- compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
+- reg = <0x0 0xfebb0000 0x0 0x100>;
+- interrupts = <GIC_SPI 339 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru SCLK_UART8>, <&cru PCLK_UART8>;
+- clock-names = "baudclk", "apb_pclk";
+- dmas = <&dmac2 9>, <&dmac2 10>;
+- dma-names = "tx", "rx";
+- pinctrl-0 = <&uart8m1_xfer>;
+- pinctrl-names = "default";
+- reg-io-width = <4>;
+- reg-shift = <2>;
+- status = "disabled";
+- };
+-
+- uart9: serial@febc0000 {
+- compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
+- reg = <0x0 0xfebc0000 0x0 0x100>;
+- interrupts = <GIC_SPI 340 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru SCLK_UART9>, <&cru PCLK_UART9>;
+- clock-names = "baudclk", "apb_pclk";
+- dmas = <&dmac2 11>, <&dmac2 12>;
+- dma-names = "tx", "rx";
+- pinctrl-0 = <&uart9m1_xfer>;
+- pinctrl-names = "default";
+- reg-io-width = <4>;
+- reg-shift = <2>;
+- status = "disabled";
+- };
+-
+- pwm4: pwm@febd0000 {
+- compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+- reg = <0x0 0xfebd0000 0x0 0x10>;
+- clocks = <&cru CLK_PWM1>, <&cru PCLK_PWM1>;
+- clock-names = "pwm", "pclk";
+- pinctrl-0 = <&pwm4m0_pins>;
+- pinctrl-names = "default";
+- #pwm-cells = <3>;
+- status = "disabled";
+- };
+-
+- pwm5: pwm@febd0010 {
+- compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+- reg = <0x0 0xfebd0010 0x0 0x10>;
+- clocks = <&cru CLK_PWM1>, <&cru PCLK_PWM1>;
+- clock-names = "pwm", "pclk";
+- pinctrl-0 = <&pwm5m0_pins>;
+- pinctrl-names = "default";
+- #pwm-cells = <3>;
+- status = "disabled";
+- };
+-
+- pwm6: pwm@febd0020 {
+- compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+- reg = <0x0 0xfebd0020 0x0 0x10>;
+- clocks = <&cru CLK_PWM1>, <&cru PCLK_PWM1>;
+- clock-names = "pwm", "pclk";
+- pinctrl-0 = <&pwm6m0_pins>;
+- pinctrl-names = "default";
+- #pwm-cells = <3>;
+- status = "disabled";
+- };
+-
+- pwm7: pwm@febd0030 {
+- compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+- reg = <0x0 0xfebd0030 0x0 0x10>;
+- clocks = <&cru CLK_PWM1>, <&cru PCLK_PWM1>;
+- clock-names = "pwm", "pclk";
+- pinctrl-0 = <&pwm7m0_pins>;
+- pinctrl-names = "default";
+- #pwm-cells = <3>;
+- status = "disabled";
+- };
+-
+- pwm8: pwm@febe0000 {
+- compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+- reg = <0x0 0xfebe0000 0x0 0x10>;
+- clocks = <&cru CLK_PWM2>, <&cru PCLK_PWM2>;
+- clock-names = "pwm", "pclk";
+- pinctrl-0 = <&pwm8m0_pins>;
+- pinctrl-names = "default";
+- #pwm-cells = <3>;
+- status = "disabled";
+- };
+-
+- pwm9: pwm@febe0010 {
+- compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+- reg = <0x0 0xfebe0010 0x0 0x10>;
+- clocks = <&cru CLK_PWM2>, <&cru PCLK_PWM2>;
+- clock-names = "pwm", "pclk";
+- pinctrl-0 = <&pwm9m0_pins>;
+- pinctrl-names = "default";
+- #pwm-cells = <3>;
+- status = "disabled";
+- };
+-
+- pwm10: pwm@febe0020 {
+- compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+- reg = <0x0 0xfebe0020 0x0 0x10>;
+- clocks = <&cru CLK_PWM2>, <&cru PCLK_PWM2>;
+- clock-names = "pwm", "pclk";
+- pinctrl-0 = <&pwm10m0_pins>;
+- pinctrl-names = "default";
+- #pwm-cells = <3>;
+- status = "disabled";
+- };
+-
+- pwm11: pwm@febe0030 {
+- compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+- reg = <0x0 0xfebe0030 0x0 0x10>;
+- clocks = <&cru CLK_PWM2>, <&cru PCLK_PWM2>;
+- clock-names = "pwm", "pclk";
+- pinctrl-0 = <&pwm11m0_pins>;
+- pinctrl-names = "default";
+- #pwm-cells = <3>;
+- status = "disabled";
+- };
+-
+- pwm12: pwm@febf0000 {
+- compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+- reg = <0x0 0xfebf0000 0x0 0x10>;
+- clocks = <&cru CLK_PWM3>, <&cru PCLK_PWM3>;
+- clock-names = "pwm", "pclk";
+- pinctrl-0 = <&pwm12m0_pins>;
+- pinctrl-names = "default";
+- #pwm-cells = <3>;
+- status = "disabled";
+- };
+-
+- pwm13: pwm@febf0010 {
+- compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+- reg = <0x0 0xfebf0010 0x0 0x10>;
+- clocks = <&cru CLK_PWM3>, <&cru PCLK_PWM3>;
+- clock-names = "pwm", "pclk";
+- pinctrl-0 = <&pwm13m0_pins>;
+- pinctrl-names = "default";
+- #pwm-cells = <3>;
+- status = "disabled";
+- };
+-
+- pwm14: pwm@febf0020 {
+- compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+- reg = <0x0 0xfebf0020 0x0 0x10>;
+- clocks = <&cru CLK_PWM3>, <&cru PCLK_PWM3>;
+- clock-names = "pwm", "pclk";
+- pinctrl-0 = <&pwm14m0_pins>;
+- pinctrl-names = "default";
+- #pwm-cells = <3>;
+- status = "disabled";
+- };
+-
+- pwm15: pwm@febf0030 {
+- compatible = "rockchip,rk3588-pwm", "rockchip,rk3328-pwm";
+- reg = <0x0 0xfebf0030 0x0 0x10>;
+- clocks = <&cru CLK_PWM3>, <&cru PCLK_PWM3>;
+- clock-names = "pwm", "pclk";
+- pinctrl-0 = <&pwm15m0_pins>;
+- pinctrl-names = "default";
+- #pwm-cells = <3>;
+- status = "disabled";
+- };
+-
+- tsadc: tsadc@fec00000 {
+- compatible = "rockchip,rk3588-tsadc";
+- reg = <0x0 0xfec00000 0x0 0x400>;
+- interrupts = <GIC_SPI 397 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru CLK_TSADC>, <&cru PCLK_TSADC>;
+- clock-names = "tsadc", "apb_pclk";
+- assigned-clocks = <&cru CLK_TSADC>;
+- assigned-clock-rates = <2000000>;
+- resets = <&cru SRST_P_TSADC>, <&cru SRST_TSADC>;
+- reset-names = "tsadc-apb", "tsadc";
+- rockchip,hw-tshut-temp = <120000>;
+- rockchip,hw-tshut-mode = <0>; /* tshut mode 0:CRU 1:GPIO */
+- rockchip,hw-tshut-polarity = <0>; /* tshut polarity 0:LOW 1:HIGH */
+- pinctrl-0 = <&tsadc_gpio_func>;
+- pinctrl-1 = <&tsadc_shut>;
+- pinctrl-names = "gpio", "otpout";
+- #thermal-sensor-cells = <1>;
+- status = "disabled";
+- };
+-
+- saradc: adc@fec10000 {
+- compatible = "rockchip,rk3588-saradc";
+- reg = <0x0 0xfec10000 0x0 0x10000>;
+- interrupts = <GIC_SPI 398 IRQ_TYPE_LEVEL_HIGH 0>;
+- #io-channel-cells = <1>;
+- clocks = <&cru CLK_SARADC>, <&cru PCLK_SARADC>;
+- clock-names = "saradc", "apb_pclk";
+- resets = <&cru SRST_P_SARADC>;
+- reset-names = "saradc-apb";
+- status = "disabled";
+- };
+-
+- i2c6: i2c@fec80000 {
+- compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
+- reg = <0x0 0xfec80000 0x0 0x1000>;
+- clocks = <&cru CLK_I2C6>, <&cru PCLK_I2C6>;
+- clock-names = "i2c", "pclk";
+- interrupts = <GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH 0>;
+- pinctrl-0 = <&i2c6m0_xfer>;
+- pinctrl-names = "default";
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- i2c7: i2c@fec90000 {
+- compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
+- reg = <0x0 0xfec90000 0x0 0x1000>;
+- clocks = <&cru CLK_I2C7>, <&cru PCLK_I2C7>;
+- clock-names = "i2c", "pclk";
+- interrupts = <GIC_SPI 324 IRQ_TYPE_LEVEL_HIGH 0>;
+- pinctrl-0 = <&i2c7m0_xfer>;
+- pinctrl-names = "default";
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- i2c8: i2c@feca0000 {
+- compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c";
+- reg = <0x0 0xfeca0000 0x0 0x1000>;
+- clocks = <&cru CLK_I2C8>, <&cru PCLK_I2C8>;
+- clock-names = "i2c", "pclk";
+- interrupts = <GIC_SPI 325 IRQ_TYPE_LEVEL_HIGH 0>;
+- pinctrl-0 = <&i2c8m0_xfer>;
+- pinctrl-names = "default";
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- spi4: spi@fecb0000 {
+- compatible = "rockchip,rk3588-spi", "rockchip,rk3066-spi";
+- reg = <0x0 0xfecb0000 0x0 0x1000>;
+- interrupts = <GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru CLK_SPI4>, <&cru PCLK_SPI4>;
+- clock-names = "spiclk", "apb_pclk";
+- dmas = <&dmac2 13>, <&dmac2 14>;
+- dma-names = "tx", "rx";
+- num-cs = <2>;
+- pinctrl-0 = <&spi4m0_cs0 &spi4m0_cs1 &spi4m0_pins>;
+- pinctrl-names = "default";
+- #address-cells = <1>;
+- #size-cells = <0>;
+- status = "disabled";
+- };
+-
+- otp: efuse@fecc0000 {
+- compatible = "rockchip,rk3588-otp";
+- reg = <0x0 0xfecc0000 0x0 0x400>;
+- clocks = <&cru CLK_OTPC_NS>, <&cru PCLK_OTPC_NS>,
+- <&cru CLK_OTP_PHY_G>, <&cru CLK_OTPC_ARB>;
+- clock-names = "otp", "apb_pclk", "phy", "arb";
+- resets = <&cru SRST_OTPC_NS>, <&cru SRST_P_OTPC_NS>,
+- <&cru SRST_OTPC_ARB>;
+- reset-names = "otp", "apb", "arb";
+- #address-cells = <1>;
+- #size-cells = <1>;
+-
+- cpu_code: cpu-code@2 {
+- reg = <0x02 0x2>;
+- };
+-
+- otp_id: id@7 {
+- reg = <0x07 0x10>;
+- };
+-
+- cpub0_leakage: cpu-leakage@17 {
+- reg = <0x17 0x1>;
+- };
+-
+- cpub1_leakage: cpu-leakage@18 {
+- reg = <0x18 0x1>;
+- };
+-
+- cpul_leakage: cpu-leakage@19 {
+- reg = <0x19 0x1>;
+- };
+-
+- log_leakage: log-leakage@1a {
+- reg = <0x1a 0x1>;
+- };
+-
+- gpu_leakage: gpu-leakage@1b {
+- reg = <0x1b 0x1>;
+- };
+-
+- otp_cpu_version: cpu-version@1c {
+- reg = <0x1c 0x1>;
+- bits = <3 3>;
+- };
+-
+- npu_leakage: npu-leakage@28 {
+- reg = <0x28 0x1>;
+- };
+-
+- codec_leakage: codec-leakage@29 {
+- reg = <0x29 0x1>;
+- };
+- };
+-
+- dmac2: dma-controller@fed10000 {
+- compatible = "arm,pl330", "arm,primecell";
+- reg = <0x0 0xfed10000 0x0 0x4000>;
+- interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH 0>,
+- <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH 0>;
+- arm,pl330-periph-burst;
+- clocks = <&cru ACLK_DMAC2>;
+- clock-names = "apb_pclk";
+- #dma-cells = <1>;
+- };
+-
+- hdptxphy_hdmi0: phy@fed60000 {
+- compatible = "rockchip,rk3588-hdptx-phy";
+- reg = <0x0 0xfed60000 0x0 0x2000>;
+- clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>, <&cru PCLK_HDPTX0>;
+- clock-names = "ref", "apb";
+- #phy-cells = <0>;
+- resets = <&cru SRST_HDPTX0>, <&cru SRST_P_HDPTX0>,
+- <&cru SRST_HDPTX0_INIT>, <&cru SRST_HDPTX0_CMN>,
+- <&cru SRST_HDPTX0_LANE>, <&cru SRST_HDPTX0_ROPLL>,
+- <&cru SRST_HDPTX0_LCPLL>;
+- reset-names = "phy", "apb", "init", "cmn", "lane", "ropll",
+- "lcpll";
+- rockchip,grf = <&hdptxphy0_grf>;
+- status = "disabled";
+- };
+-
+- usbdp_phy0: phy@fed80000 {
+- compatible = "rockchip,rk3588-usbdp-phy";
+- reg = <0x0 0xfed80000 0x0 0x10000>;
+- #phy-cells = <1>;
+- clocks = <&cru CLK_USBDPPHY_MIPIDCPPHY_REF>,
+- <&cru CLK_USBDP_PHY0_IMMORTAL>,
+- <&cru PCLK_USBDPPHY0>,
+- <&u2phy0>;
+- clock-names = "refclk", "immortal", "pclk", "utmi";
+- resets = <&cru SRST_USBDP_COMBO_PHY0_INIT>,
+- <&cru SRST_USBDP_COMBO_PHY0_CMN>,
+- <&cru SRST_USBDP_COMBO_PHY0_LANE>,
+- <&cru SRST_USBDP_COMBO_PHY0_PCS>,
+- <&cru SRST_P_USBDPPHY0>;
+- reset-names = "init", "cmn", "lane", "pcs_apb", "pma_apb";
+- rockchip,u2phy-grf = <&usb2phy0_grf>;
+- rockchip,usb-grf = <&usb_grf>;
+- rockchip,usbdpphy-grf = <&usbdpphy0_grf>;
+- rockchip,vo-grf = <&vo0_grf>;
+- status = "disabled";
+- };
+-
+- combphy0_ps: phy@fee00000 {
+- compatible = "rockchip,rk3588-naneng-combphy";
+- reg = <0x0 0xfee00000 0x0 0x100>;
+- clocks = <&cru CLK_REF_PIPE_PHY0>, <&cru PCLK_PCIE_COMBO_PIPE_PHY0>,
+- <&cru PCLK_PHP_ROOT>;
+- clock-names = "ref", "apb", "pipe";
+- assigned-clocks = <&cru CLK_REF_PIPE_PHY0>;
+- assigned-clock-rates = <100000000>;
+- #phy-cells = <1>;
+- resets = <&cru SRST_REF_PIPE_PHY0>, <&cru SRST_P_PCIE2_PHY0>;
+- reset-names = "phy", "apb";
+- rockchip,pipe-grf = <&php_grf>;
+- rockchip,pipe-phy-grf = <&pipe_phy0_grf>;
+- status = "disabled";
+- };
+-
+- combphy2_psu: phy@fee20000 {
+- compatible = "rockchip,rk3588-naneng-combphy";
+- reg = <0x0 0xfee20000 0x0 0x100>;
+- clocks = <&cru CLK_REF_PIPE_PHY2>, <&cru PCLK_PCIE_COMBO_PIPE_PHY2>,
+- <&cru PCLK_PHP_ROOT>;
+- clock-names = "ref", "apb", "pipe";
+- assigned-clocks = <&cru CLK_REF_PIPE_PHY2>;
+- assigned-clock-rates = <100000000>;
+- #phy-cells = <1>;
+- resets = <&cru SRST_REF_PIPE_PHY2>, <&cru SRST_P_PCIE2_PHY2>;
+- reset-names = "phy", "apb";
+- rockchip,pipe-grf = <&php_grf>;
+- rockchip,pipe-phy-grf = <&pipe_phy2_grf>;
+- status = "disabled";
+- };
+-
+- system_sram2: sram@ff001000 {
+- compatible = "mmio-sram";
+- reg = <0x0 0xff001000 0x0 0xef000>;
+- ranges = <0x0 0x0 0xff001000 0xef000>;
+- #address-cells = <1>;
+- #size-cells = <1>;
+- };
+-
+- pinctrl: pinctrl {
+- compatible = "rockchip,rk3588-pinctrl";
+- ranges;
+- rockchip,grf = <&ioc>;
+- #address-cells = <2>;
+- #size-cells = <2>;
+-
+- gpio0: gpio@fd8a0000 {
+- compatible = "rockchip,gpio-bank";
+- reg = <0x0 0xfd8a0000 0x0 0x100>;
+- interrupts = <GIC_SPI 277 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru PCLK_GPIO0>, <&cru DBCLK_GPIO0>;
+- gpio-controller;
+- gpio-ranges = <&pinctrl 0 0 32>;
+- interrupt-controller;
+- #gpio-cells = <2>;
+- #interrupt-cells = <2>;
+- };
+-
+- gpio1: gpio@fec20000 {
+- compatible = "rockchip,gpio-bank";
+- reg = <0x0 0xfec20000 0x0 0x100>;
+- interrupts = <GIC_SPI 278 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru PCLK_GPIO1>, <&cru DBCLK_GPIO1>;
+- gpio-controller;
+- gpio-ranges = <&pinctrl 0 32 32>;
+- interrupt-controller;
+- #gpio-cells = <2>;
+- #interrupt-cells = <2>;
+- };
+-
+- gpio2: gpio@fec30000 {
+- compatible = "rockchip,gpio-bank";
+- reg = <0x0 0xfec30000 0x0 0x100>;
+- interrupts = <GIC_SPI 279 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru PCLK_GPIO2>, <&cru DBCLK_GPIO2>;
+- gpio-controller;
+- gpio-ranges = <&pinctrl 0 64 32>;
+- interrupt-controller;
+- #gpio-cells = <2>;
+- #interrupt-cells = <2>;
+- };
+-
+- gpio3: gpio@fec40000 {
+- compatible = "rockchip,gpio-bank";
+- reg = <0x0 0xfec40000 0x0 0x100>;
+- interrupts = <GIC_SPI 280 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru PCLK_GPIO3>, <&cru DBCLK_GPIO3>;
+- gpio-controller;
+- gpio-ranges = <&pinctrl 0 96 32>;
+- interrupt-controller;
+- #gpio-cells = <2>;
+- #interrupt-cells = <2>;
+- };
+-
+- gpio4: gpio@fec50000 {
+- compatible = "rockchip,gpio-bank";
+- reg = <0x0 0xfec50000 0x0 0x100>;
+- interrupts = <GIC_SPI 281 IRQ_TYPE_LEVEL_HIGH 0>;
+- clocks = <&cru PCLK_GPIO4>, <&cru DBCLK_GPIO4>;
+- gpio-controller;
+- gpio-ranges = <&pinctrl 0 128 32>;
+- interrupt-controller;
+- #gpio-cells = <2>;
+- #interrupt-cells = <2>;
+- };
+- };
+-};
+-
+-#include "rk3588s-pinctrl.dtsi"
++#include "rk3588-base.dtsi"
+--- /dev/null
++++ b/arch/arm64/boot/dts/rockchip/rk3588-base-pinctrl.dtsi
+@@ -0,0 +1,3447 @@
++// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
++/*
++ * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
++ */
++
++#include <dt-bindings/pinctrl/rockchip.h>
++#include "rockchip-pinconf.dtsi"
++
++/*
++ * This file is auto generated by pin2dts tool, please keep these code
++ * by adding changes at end of this file.
++ */
++&pinctrl {
++ auddsm {
++ /omit-if-no-ref/
++ auddsm_pins: auddsm-pins {
++ rockchip,pins =
++ /* auddsm_ln */
++ <3 RK_PA1 4 &pcfg_pull_none>,
++ /* auddsm_lp */
++ <3 RK_PA2 4 &pcfg_pull_none>,
++ /* auddsm_rn */
++ <3 RK_PA3 4 &pcfg_pull_none>,
++ /* auddsm_rp */
++ <3 RK_PA4 4 &pcfg_pull_none>;
++ };
++ };
++
++ bt1120 {
++ /omit-if-no-ref/
++ bt1120_pins: bt1120-pins {
++ rockchip,pins =
++ /* bt1120_clkout */
++ <4 RK_PB0 2 &pcfg_pull_none>,
++ /* bt1120_d0 */
++ <4 RK_PA0 2 &pcfg_pull_none>,
++ /* bt1120_d1 */
++ <4 RK_PA1 2 &pcfg_pull_none>,
++ /* bt1120_d2 */
++ <4 RK_PA2 2 &pcfg_pull_none>,
++ /* bt1120_d3 */
++ <4 RK_PA3 2 &pcfg_pull_none>,
++ /* bt1120_d4 */
++ <4 RK_PA4 2 &pcfg_pull_none>,
++ /* bt1120_d5 */
++ <4 RK_PA5 2 &pcfg_pull_none>,
++ /* bt1120_d6 */
++ <4 RK_PA6 2 &pcfg_pull_none>,
++ /* bt1120_d7 */
++ <4 RK_PA7 2 &pcfg_pull_none>,
++ /* bt1120_d8 */
++ <4 RK_PB2 2 &pcfg_pull_none>,
++ /* bt1120_d9 */
++ <4 RK_PB3 2 &pcfg_pull_none>,
++ /* bt1120_d10 */
++ <4 RK_PB4 2 &pcfg_pull_none>,
++ /* bt1120_d11 */
++ <4 RK_PB5 2 &pcfg_pull_none>,
++ /* bt1120_d12 */
++ <4 RK_PB6 2 &pcfg_pull_none>,
++ /* bt1120_d13 */
++ <4 RK_PB7 2 &pcfg_pull_none>,
++ /* bt1120_d14 */
++ <4 RK_PC0 2 &pcfg_pull_none>,
++ /* bt1120_d15 */
++ <4 RK_PC1 2 &pcfg_pull_none>;
++ };
++ };
++
++ can0 {
++ /omit-if-no-ref/
++ can0m0_pins: can0m0-pins {
++ rockchip,pins =
++ /* can0_rx_m0 */
++ <0 RK_PC0 11 &pcfg_pull_none>,
++ /* can0_tx_m0 */
++ <0 RK_PB7 11 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ can0m1_pins: can0m1-pins {
++ rockchip,pins =
++ /* can0_rx_m1 */
++ <4 RK_PD5 9 &pcfg_pull_none>,
++ /* can0_tx_m1 */
++ <4 RK_PD4 9 &pcfg_pull_none>;
++ };
++ };
++
++ can1 {
++ /omit-if-no-ref/
++ can1m0_pins: can1m0-pins {
++ rockchip,pins =
++ /* can1_rx_m0 */
++ <3 RK_PB5 9 &pcfg_pull_none>,
++ /* can1_tx_m0 */
++ <3 RK_PB6 9 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ can1m1_pins: can1m1-pins {
++ rockchip,pins =
++ /* can1_rx_m1 */
++ <4 RK_PB2 12 &pcfg_pull_none>,
++ /* can1_tx_m1 */
++ <4 RK_PB3 12 &pcfg_pull_none>;
++ };
++ };
++
++ can2 {
++ /omit-if-no-ref/
++ can2m0_pins: can2m0-pins {
++ rockchip,pins =
++ /* can2_rx_m0 */
++ <3 RK_PC4 9 &pcfg_pull_none>,
++ /* can2_tx_m0 */
++ <3 RK_PC5 9 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ can2m1_pins: can2m1-pins {
++ rockchip,pins =
++ /* can2_rx_m1 */
++ <0 RK_PD4 10 &pcfg_pull_none>,
++ /* can2_tx_m1 */
++ <0 RK_PD5 10 &pcfg_pull_none>;
++ };
++ };
++
++ cif {
++ /omit-if-no-ref/
++ cif_clk: cif-clk {
++ rockchip,pins =
++ /* cif_clkout */
++ <4 RK_PB4 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ cif_dvp_clk: cif-dvp-clk {
++ rockchip,pins =
++ /* cif_clkin */
++ <4 RK_PB0 1 &pcfg_pull_none>,
++ /* cif_href */
++ <4 RK_PB2 1 &pcfg_pull_none>,
++ /* cif_vsync */
++ <4 RK_PB3 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ cif_dvp_bus16: cif-dvp-bus16 {
++ rockchip,pins =
++ /* cif_d8 */
++ <3 RK_PC4 1 &pcfg_pull_none>,
++ /* cif_d9 */
++ <3 RK_PC5 1 &pcfg_pull_none>,
++ /* cif_d10 */
++ <3 RK_PC6 1 &pcfg_pull_none>,
++ /* cif_d11 */
++ <3 RK_PC7 1 &pcfg_pull_none>,
++ /* cif_d12 */
++ <3 RK_PD0 1 &pcfg_pull_none>,
++ /* cif_d13 */
++ <3 RK_PD1 1 &pcfg_pull_none>,
++ /* cif_d14 */
++ <3 RK_PD2 1 &pcfg_pull_none>,
++ /* cif_d15 */
++ <3 RK_PD3 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ cif_dvp_bus8: cif-dvp-bus8 {
++ rockchip,pins =
++ /* cif_d0 */
++ <4 RK_PA0 1 &pcfg_pull_none>,
++ /* cif_d1 */
++ <4 RK_PA1 1 &pcfg_pull_none>,
++ /* cif_d2 */
++ <4 RK_PA2 1 &pcfg_pull_none>,
++ /* cif_d3 */
++ <4 RK_PA3 1 &pcfg_pull_none>,
++ /* cif_d4 */
++ <4 RK_PA4 1 &pcfg_pull_none>,
++ /* cif_d5 */
++ <4 RK_PA5 1 &pcfg_pull_none>,
++ /* cif_d6 */
++ <4 RK_PA6 1 &pcfg_pull_none>,
++ /* cif_d7 */
++ <4 RK_PA7 1 &pcfg_pull_none>;
++ };
++ };
++
++ clk32k {
++ /omit-if-no-ref/
++ clk32k_in: clk32k-in {
++ rockchip,pins =
++ /* clk32k_in */
++ <0 RK_PB2 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ clk32k_out0: clk32k-out0 {
++ rockchip,pins =
++ /* clk32k_out0 */
++ <0 RK_PB2 2 &pcfg_pull_none>;
++ };
++ };
++
++ cpu {
++ /omit-if-no-ref/
++ cpu_pins: cpu-pins {
++ rockchip,pins =
++ /* cpu_big0_avs */
++ <0 RK_PD1 2 &pcfg_pull_none>,
++ /* cpu_big1_avs */
++ <0 RK_PD5 2 &pcfg_pull_none>;
++ };
++ };
++
++ ddrphych0 {
++ /omit-if-no-ref/
++ ddrphych0_pins: ddrphych0-pins {
++ rockchip,pins =
++ /* ddrphych0_dtb0 */
++ <4 RK_PA0 7 &pcfg_pull_none>,
++ /* ddrphych0_dtb1 */
++ <4 RK_PA1 7 &pcfg_pull_none>,
++ /* ddrphych0_dtb2 */
++ <4 RK_PA2 7 &pcfg_pull_none>,
++ /* ddrphych0_dtb3 */
++ <4 RK_PA3 7 &pcfg_pull_none>;
++ };
++ };
++
++ ddrphych1 {
++ /omit-if-no-ref/
++ ddrphych1_pins: ddrphych1-pins {
++ rockchip,pins =
++ /* ddrphych1_dtb0 */
++ <4 RK_PA4 7 &pcfg_pull_none>,
++ /* ddrphych1_dtb1 */
++ <4 RK_PA5 7 &pcfg_pull_none>,
++ /* ddrphych1_dtb2 */
++ <4 RK_PA6 7 &pcfg_pull_none>,
++ /* ddrphych1_dtb3 */
++ <4 RK_PA7 7 &pcfg_pull_none>;
++ };
++ };
++
++ ddrphych2 {
++ /omit-if-no-ref/
++ ddrphych2_pins: ddrphych2-pins {
++ rockchip,pins =
++ /* ddrphych2_dtb0 */
++ <4 RK_PB0 7 &pcfg_pull_none>,
++ /* ddrphych2_dtb1 */
++ <4 RK_PB1 7 &pcfg_pull_none>,
++ /* ddrphych2_dtb2 */
++ <4 RK_PB2 7 &pcfg_pull_none>,
++ /* ddrphych2_dtb3 */
++ <4 RK_PB3 7 &pcfg_pull_none>;
++ };
++ };
++
++ ddrphych3 {
++ /omit-if-no-ref/
++ ddrphych3_pins: ddrphych3-pins {
++ rockchip,pins =
++ /* ddrphych3_dtb0 */
++ <4 RK_PB4 7 &pcfg_pull_none>,
++ /* ddrphych3_dtb1 */
++ <4 RK_PB5 7 &pcfg_pull_none>,
++ /* ddrphych3_dtb2 */
++ <4 RK_PB6 7 &pcfg_pull_none>,
++ /* ddrphych3_dtb3 */
++ <4 RK_PB7 7 &pcfg_pull_none>;
++ };
++ };
++
++ dp0 {
++ /omit-if-no-ref/
++ dp0m0_pins: dp0m0-pins {
++ rockchip,pins =
++ /* dp0_hpdin_m0 */
++ <4 RK_PB4 5 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ dp0m1_pins: dp0m1-pins {
++ rockchip,pins =
++ /* dp0_hpdin_m1 */
++ <0 RK_PC4 10 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ dp0m2_pins: dp0m2-pins {
++ rockchip,pins =
++ /* dp0_hpdin_m2 */
++ <1 RK_PA0 5 &pcfg_pull_none>;
++ };
++ };
++
++ dp1 {
++ /omit-if-no-ref/
++ dp1m0_pins: dp1m0-pins {
++ rockchip,pins =
++ /* dp1_hpdin_m0 */
++ <3 RK_PD5 5 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ dp1m1_pins: dp1m1-pins {
++ rockchip,pins =
++ /* dp1_hpdin_m1 */
++ <0 RK_PC5 10 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ dp1m2_pins: dp1m2-pins {
++ rockchip,pins =
++ /* dp1_hpdin_m2 */
++ <1 RK_PA1 5 &pcfg_pull_none>;
++ };
++ };
++
++ emmc {
++ /omit-if-no-ref/
++ emmc_rstnout: emmc-rstnout {
++ rockchip,pins =
++ /* emmc_rstn */
++ <2 RK_PA3 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ emmc_bus8: emmc-bus8 {
++ rockchip,pins =
++ /* emmc_d0 */
++ <2 RK_PD0 1 &pcfg_pull_up_drv_level_2>,
++ /* emmc_d1 */
++ <2 RK_PD1 1 &pcfg_pull_up_drv_level_2>,
++ /* emmc_d2 */
++ <2 RK_PD2 1 &pcfg_pull_up_drv_level_2>,
++ /* emmc_d3 */
++ <2 RK_PD3 1 &pcfg_pull_up_drv_level_2>,
++ /* emmc_d4 */
++ <2 RK_PD4 1 &pcfg_pull_up_drv_level_2>,
++ /* emmc_d5 */
++ <2 RK_PD5 1 &pcfg_pull_up_drv_level_2>,
++ /* emmc_d6 */
++ <2 RK_PD6 1 &pcfg_pull_up_drv_level_2>,
++ /* emmc_d7 */
++ <2 RK_PD7 1 &pcfg_pull_up_drv_level_2>;
++ };
++
++ /omit-if-no-ref/
++ emmc_clk: emmc-clk {
++ rockchip,pins =
++ /* emmc_clkout */
++ <2 RK_PA1 1 &pcfg_pull_up_drv_level_2>;
++ };
++
++ /omit-if-no-ref/
++ emmc_cmd: emmc-cmd {
++ rockchip,pins =
++ /* emmc_cmd */
++ <2 RK_PA0 1 &pcfg_pull_up_drv_level_2>;
++ };
++
++ /omit-if-no-ref/
++ emmc_data_strobe: emmc-data-strobe {
++ rockchip,pins =
++ /* emmc_data_strobe */
++ <2 RK_PA2 1 &pcfg_pull_down>;
++ };
++ };
++
++ eth1 {
++ /omit-if-no-ref/
++ eth1_pins: eth1-pins {
++ rockchip,pins =
++ /* eth1_refclko_25m */
++ <3 RK_PA6 1 &pcfg_pull_none>;
++ };
++ };
++
++ fspi {
++ /omit-if-no-ref/
++ fspim0_pins: fspim0-pins {
++ rockchip,pins =
++ /* fspi_clk_m0 */
++ <2 RK_PA0 2 &pcfg_pull_up_drv_level_2>,
++ /* fspi_cs0n_m0 */
++ <2 RK_PD6 2 &pcfg_pull_up_drv_level_2>,
++ /* fspi_d0_m0 */
++ <2 RK_PD0 2 &pcfg_pull_up_drv_level_2>,
++ /* fspi_d1_m0 */
++ <2 RK_PD1 2 &pcfg_pull_up_drv_level_2>,
++ /* fspi_d2_m0 */
++ <2 RK_PD2 2 &pcfg_pull_up_drv_level_2>,
++ /* fspi_d3_m0 */
++ <2 RK_PD3 2 &pcfg_pull_up_drv_level_2>;
++ };
++
++ /omit-if-no-ref/
++ fspim0_cs1: fspim0-cs1 {
++ rockchip,pins =
++ /* fspi_cs1n_m0 */
++ <2 RK_PD7 2 &pcfg_pull_up_drv_level_2>;
++ };
++
++ /omit-if-no-ref/
++ fspim2_pins: fspim2-pins {
++ rockchip,pins =
++ /* fspi_clk_m2 */
++ <3 RK_PA5 5 &pcfg_pull_up_drv_level_2>,
++ /* fspi_cs0n_m2 */
++ <3 RK_PC4 2 &pcfg_pull_up_drv_level_2>,
++ /* fspi_d0_m2 */
++ <3 RK_PA0 5 &pcfg_pull_up_drv_level_2>,
++ /* fspi_d1_m2 */
++ <3 RK_PA1 5 &pcfg_pull_up_drv_level_2>,
++ /* fspi_d2_m2 */
++ <3 RK_PA2 5 &pcfg_pull_up_drv_level_2>,
++ /* fspi_d3_m2 */
++ <3 RK_PA3 5 &pcfg_pull_up_drv_level_2>;
++ };
++
++ /omit-if-no-ref/
++ fspim2_cs1: fspim2-cs1 {
++ rockchip,pins =
++ /* fspi_cs1n_m2 */
++ <3 RK_PC5 2 &pcfg_pull_up_drv_level_2>;
++ };
++ };
++
++ gmac1 {
++ /omit-if-no-ref/
++ gmac1_miim: gmac1-miim {
++ rockchip,pins =
++ /* gmac1_mdc */
++ <3 RK_PC2 1 &pcfg_pull_none>,
++ /* gmac1_mdio */
++ <3 RK_PC3 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ gmac1_clkinout: gmac1-clkinout {
++ rockchip,pins =
++ /* gmac1_mclkinout */
++ <3 RK_PB6 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ gmac1_rx_bus2: gmac1-rx-bus2 {
++ rockchip,pins =
++ /* gmac1_rxd0 */
++ <3 RK_PA7 1 &pcfg_pull_none>,
++ /* gmac1_rxd1 */
++ <3 RK_PB0 1 &pcfg_pull_none>,
++ /* gmac1_rxdv_crs */
++ <3 RK_PB1 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ gmac1_tx_bus2: gmac1-tx-bus2 {
++ rockchip,pins =
++ /* gmac1_txd0 */
++ <3 RK_PB3 1 &pcfg_pull_none>,
++ /* gmac1_txd1 */
++ <3 RK_PB4 1 &pcfg_pull_none>,
++ /* gmac1_txen */
++ <3 RK_PB5 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ gmac1_rgmii_clk: gmac1-rgmii-clk {
++ rockchip,pins =
++ /* gmac1_rxclk */
++ <3 RK_PA5 1 &pcfg_pull_none>,
++ /* gmac1_txclk */
++ <3 RK_PA4 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ gmac1_rgmii_bus: gmac1-rgmii-bus {
++ rockchip,pins =
++ /* gmac1_rxd2 */
++ <3 RK_PA2 1 &pcfg_pull_none>,
++ /* gmac1_rxd3 */
++ <3 RK_PA3 1 &pcfg_pull_none>,
++ /* gmac1_txd2 */
++ <3 RK_PA0 1 &pcfg_pull_none>,
++ /* gmac1_txd3 */
++ <3 RK_PA1 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ gmac1_ppsclk: gmac1-ppsclk {
++ rockchip,pins =
++ /* gmac1_ppsclk */
++ <3 RK_PC1 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ gmac1_ppstrig: gmac1-ppstrig {
++ rockchip,pins =
++ /* gmac1_ppstrig */
++ <3 RK_PC0 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ gmac1_ptp_ref_clk: gmac1-ptp-ref-clk {
++ rockchip,pins =
++ /* gmac1_ptp_ref_clk */
++ <3 RK_PB7 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ gmac1_txer: gmac1-txer {
++ rockchip,pins =
++ /* gmac1_txer */
++ <3 RK_PB2 1 &pcfg_pull_none>;
++ };
++ };
++
++ gpu {
++ /omit-if-no-ref/
++ gpu_pins: gpu-pins {
++ rockchip,pins =
++ /* gpu_avs */
++ <0 RK_PC5 2 &pcfg_pull_none>;
++ };
++ };
++
++ hdmi {
++ /omit-if-no-ref/
++ hdmim0_rx_cec: hdmim0-rx-cec {
++ rockchip,pins =
++ /* hdmim0_rx_cec */
++ <4 RK_PB5 5 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmim0_rx_hpdin: hdmim0-rx-hpdin {
++ rockchip,pins =
++ /* hdmim0_rx_hpdin */
++ <4 RK_PB6 5 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmim0_rx_scl: hdmim0-rx-scl {
++ rockchip,pins =
++ /* hdmim0_rx_scl */
++ <0 RK_PD2 11 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmim0_rx_sda: hdmim0-rx-sda {
++ rockchip,pins =
++ /* hdmim0_rx_sda */
++ <0 RK_PD1 11 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmim0_tx0_cec: hdmim0-tx0-cec {
++ rockchip,pins =
++ /* hdmim0_tx0_cec */
++ <4 RK_PC1 5 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmim0_tx0_hpd: hdmim0-tx0-hpd {
++ rockchip,pins =
++ /* hdmim0_tx0_hpd */
++ <1 RK_PA5 5 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmim0_tx0_scl: hdmim0-tx0-scl {
++ rockchip,pins =
++ /* hdmim0_tx0_scl */
++ <4 RK_PB7 5 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmim0_tx0_sda: hdmim0-tx0-sda {
++ rockchip,pins =
++ /* hdmim0_tx0_sda */
++ <4 RK_PC0 5 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmim0_tx1_hpd: hdmim0-tx1-hpd {
++ rockchip,pins =
++ /* hdmim0_tx1_hpd */
++ <1 RK_PA6 5 &pcfg_pull_none>;
++ };
++ /omit-if-no-ref/
++ hdmim1_rx_cec: hdmim1-rx-cec {
++ rockchip,pins =
++ /* hdmim1_rx_cec */
++ <3 RK_PD1 5 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmim1_rx_hpdin: hdmim1-rx-hpdin {
++ rockchip,pins =
++ /* hdmim1_rx_hpdin */
++ <3 RK_PD4 5 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmim1_rx_scl: hdmim1-rx-scl {
++ rockchip,pins =
++ /* hdmim1_rx_scl */
++ <3 RK_PD2 5 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmim1_rx_sda: hdmim1-rx-sda {
++ rockchip,pins =
++ /* hdmim1_rx_sda */
++ <3 RK_PD3 5 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmim1_tx0_cec: hdmim1-tx0-cec {
++ rockchip,pins =
++ /* hdmim1_tx0_cec */
++ <0 RK_PD1 13 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmim1_tx0_hpd: hdmim1-tx0-hpd {
++ rockchip,pins =
++ /* hdmim1_tx0_hpd */
++ <3 RK_PD4 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmim1_tx0_scl: hdmim1-tx0-scl {
++ rockchip,pins =
++ /* hdmim1_tx0_scl */
++ <0 RK_PD5 11 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmim1_tx0_sda: hdmim1-tx0-sda {
++ rockchip,pins =
++ /* hdmim1_tx0_sda */
++ <0 RK_PD4 11 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmim1_tx1_cec: hdmim1-tx1-cec {
++ rockchip,pins =
++ /* hdmim1_tx1_cec */
++ <0 RK_PD2 13 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmim1_tx1_hpd: hdmim1-tx1-hpd {
++ rockchip,pins =
++ /* hdmim1_tx1_hpd */
++ <3 RK_PB7 5 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmim1_tx1_scl: hdmim1-tx1-scl {
++ rockchip,pins =
++ /* hdmim1_tx1_scl */
++ <3 RK_PC6 5 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmim1_tx1_sda: hdmim1-tx1-sda {
++ rockchip,pins =
++ /* hdmim1_tx1_sda */
++ <3 RK_PC5 5 &pcfg_pull_none>;
++ };
++ /omit-if-no-ref/
++ hdmim2_rx_cec: hdmim2-rx-cec {
++ rockchip,pins =
++ /* hdmim2_rx_cec */
++ <1 RK_PB7 5 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmim2_rx_hpdin: hdmim2-rx-hpdin {
++ rockchip,pins =
++ /* hdmim2_rx_hpdin */
++ <1 RK_PB6 5 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmim2_rx_scl: hdmim2-rx-scl {
++ rockchip,pins =
++ /* hdmim2_rx_scl */
++ <1 RK_PD6 5 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmim2_rx_sda: hdmim2-rx-sda {
++ rockchip,pins =
++ /* hdmim2_rx_sda */
++ <1 RK_PD7 5 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmim2_tx0_scl: hdmim2-tx0-scl {
++ rockchip,pins =
++ /* hdmim2_tx0_scl */
++ <3 RK_PC7 5 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmim2_tx0_sda: hdmim2-tx0-sda {
++ rockchip,pins =
++ /* hdmim2_tx0_sda */
++ <3 RK_PD0 5 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmim2_tx1_cec: hdmim2-tx1-cec {
++ rockchip,pins =
++ /* hdmim2_tx1_cec */
++ <3 RK_PC4 5 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmim2_tx1_scl: hdmim2-tx1-scl {
++ rockchip,pins =
++ /* hdmim2_tx1_scl */
++ <1 RK_PA4 5 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmim2_tx1_sda: hdmim2-tx1-sda {
++ rockchip,pins =
++ /* hdmim2_tx1_sda */
++ <1 RK_PA3 5 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmi_debug0: hdmi-debug0 {
++ rockchip,pins =
++ /* hdmi_debug0 */
++ <1 RK_PA7 7 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmi_debug1: hdmi-debug1 {
++ rockchip,pins =
++ /* hdmi_debug1 */
++ <1 RK_PB0 7 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmi_debug2: hdmi-debug2 {
++ rockchip,pins =
++ /* hdmi_debug2 */
++ <1 RK_PB1 7 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmi_debug3: hdmi-debug3 {
++ rockchip,pins =
++ /* hdmi_debug3 */
++ <1 RK_PB2 7 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmi_debug4: hdmi-debug4 {
++ rockchip,pins =
++ /* hdmi_debug4 */
++ <1 RK_PB3 7 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmi_debug5: hdmi-debug5 {
++ rockchip,pins =
++ /* hdmi_debug5 */
++ <1 RK_PB4 7 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmi_debug6: hdmi-debug6 {
++ rockchip,pins =
++ /* hdmi_debug6 */
++ <1 RK_PA0 7 &pcfg_pull_none>;
++ };
++ };
++
++ i2c0 {
++ /omit-if-no-ref/
++ i2c0m0_xfer: i2c0m0-xfer {
++ rockchip,pins =
++ /* i2c0_scl_m0 */
++ <0 RK_PB3 2 &pcfg_pull_none_smt>,
++ /* i2c0_sda_m0 */
++ <0 RK_PA6 2 &pcfg_pull_none_smt>;
++ };
++
++ /omit-if-no-ref/
++ i2c0m2_xfer: i2c0m2-xfer {
++ rockchip,pins =
++ /* i2c0_scl_m2 */
++ <0 RK_PD1 3 &pcfg_pull_none_smt>,
++ /* i2c0_sda_m2 */
++ <0 RK_PD2 3 &pcfg_pull_none_smt>;
++ };
++ };
++
++ i2c1 {
++ /omit-if-no-ref/
++ i2c1m0_xfer: i2c1m0-xfer {
++ rockchip,pins =
++ /* i2c1_scl_m0 */
++ <0 RK_PB5 9 &pcfg_pull_none_smt>,
++ /* i2c1_sda_m0 */
++ <0 RK_PB6 9 &pcfg_pull_none_smt>;
++ };
++
++ /omit-if-no-ref/
++ i2c1m1_xfer: i2c1m1-xfer {
++ rockchip,pins =
++ /* i2c1_scl_m1 */
++ <0 RK_PB0 2 &pcfg_pull_none_smt>,
++ /* i2c1_sda_m1 */
++ <0 RK_PB1 2 &pcfg_pull_none_smt>;
++ };
++
++ /omit-if-no-ref/
++ i2c1m2_xfer: i2c1m2-xfer {
++ rockchip,pins =
++ /* i2c1_scl_m2 */
++ <0 RK_PD4 9 &pcfg_pull_none_smt>,
++ /* i2c1_sda_m2 */
++ <0 RK_PD5 9 &pcfg_pull_none_smt>;
++ };
++
++ /omit-if-no-ref/
++ i2c1m3_xfer: i2c1m3-xfer {
++ rockchip,pins =
++ /* i2c1_scl_m3 */
++ <2 RK_PD4 9 &pcfg_pull_none_smt>,
++ /* i2c1_sda_m3 */
++ <2 RK_PD5 9 &pcfg_pull_none_smt>;
++ };
++
++ /omit-if-no-ref/
++ i2c1m4_xfer: i2c1m4-xfer {
++ rockchip,pins =
++ /* i2c1_scl_m4 */
++ <1 RK_PD2 9 &pcfg_pull_none_smt>,
++ /* i2c1_sda_m4 */
++ <1 RK_PD3 9 &pcfg_pull_none_smt>;
++ };
++ };
++
++ i2c2 {
++ /omit-if-no-ref/
++ i2c2m0_xfer: i2c2m0-xfer {
++ rockchip,pins =
++ /* i2c2_scl_m0 */
++ <0 RK_PB7 9 &pcfg_pull_none_smt>,
++ /* i2c2_sda_m0 */
++ <0 RK_PC0 9 &pcfg_pull_none_smt>;
++ };
++
++ /omit-if-no-ref/
++ i2c2m2_xfer: i2c2m2-xfer {
++ rockchip,pins =
++ /* i2c2_scl_m2 */
++ <2 RK_PA3 9 &pcfg_pull_none_smt>,
++ /* i2c2_sda_m2 */
++ <2 RK_PA2 9 &pcfg_pull_none_smt>;
++ };
++
++ /omit-if-no-ref/
++ i2c2m3_xfer: i2c2m3-xfer {
++ rockchip,pins =
++ /* i2c2_scl_m3 */
++ <1 RK_PC5 9 &pcfg_pull_none_smt>,
++ /* i2c2_sda_m3 */
++ <1 RK_PC4 9 &pcfg_pull_none_smt>;
++ };
++
++ /omit-if-no-ref/
++ i2c2m4_xfer: i2c2m4-xfer {
++ rockchip,pins =
++ /* i2c2_scl_m4 */
++ <1 RK_PA1 9 &pcfg_pull_none_smt>,
++ /* i2c2_sda_m4 */
++ <1 RK_PA0 9 &pcfg_pull_none_smt>;
++ };
++ };
++
++ i2c3 {
++ /omit-if-no-ref/
++ i2c3m0_xfer: i2c3m0-xfer {
++ rockchip,pins =
++ /* i2c3_scl_m0 */
++ <1 RK_PC1 9 &pcfg_pull_none_smt>,
++ /* i2c3_sda_m0 */
++ <1 RK_PC0 9 &pcfg_pull_none_smt>;
++ };
++
++ /omit-if-no-ref/
++ i2c3m1_xfer: i2c3m1-xfer {
++ rockchip,pins =
++ /* i2c3_scl_m1 */
++ <3 RK_PB7 9 &pcfg_pull_none_smt>,
++ /* i2c3_sda_m1 */
++ <3 RK_PC0 9 &pcfg_pull_none_smt>;
++ };
++
++ /omit-if-no-ref/
++ i2c3m2_xfer: i2c3m2-xfer {
++ rockchip,pins =
++ /* i2c3_scl_m2 */
++ <4 RK_PA4 9 &pcfg_pull_none_smt>,
++ /* i2c3_sda_m2 */
++ <4 RK_PA5 9 &pcfg_pull_none_smt>;
++ };
++
++ /omit-if-no-ref/
++ i2c3m4_xfer: i2c3m4-xfer {
++ rockchip,pins =
++ /* i2c3_scl_m4 */
++ <4 RK_PD0 9 &pcfg_pull_none_smt>,
++ /* i2c3_sda_m4 */
++ <4 RK_PD1 9 &pcfg_pull_none_smt>;
++ };
++ };
++
++ i2c4 {
++ /omit-if-no-ref/
++ i2c4m0_xfer: i2c4m0-xfer {
++ rockchip,pins =
++ /* i2c4_scl_m0 */
++ <3 RK_PA6 9 &pcfg_pull_none_smt>,
++ /* i2c4_sda_m0 */
++ <3 RK_PA5 9 &pcfg_pull_none_smt>;
++ };
++
++ /omit-if-no-ref/
++ i2c4m2_xfer: i2c4m2-xfer {
++ rockchip,pins =
++ /* i2c4_scl_m2 */
++ <0 RK_PC5 9 &pcfg_pull_none_smt>,
++ /* i2c4_sda_m2 */
++ <0 RK_PC4 9 &pcfg_pull_none_smt>;
++ };
++
++ /omit-if-no-ref/
++ i2c4m3_xfer: i2c4m3-xfer {
++ rockchip,pins =
++ /* i2c4_scl_m3 */
++ <1 RK_PA3 9 &pcfg_pull_none_smt>,
++ /* i2c4_sda_m3 */
++ <1 RK_PA2 9 &pcfg_pull_none_smt>;
++ };
++
++ /omit-if-no-ref/
++ i2c4m4_xfer: i2c4m4-xfer {
++ rockchip,pins =
++ /* i2c4_scl_m4 */
++ <1 RK_PC7 9 &pcfg_pull_none_smt>,
++ /* i2c4_sda_m4 */
++ <1 RK_PC6 9 &pcfg_pull_none_smt>;
++ };
++ };
++
++ i2c5 {
++ /omit-if-no-ref/
++ i2c5m0_xfer: i2c5m0-xfer {
++ rockchip,pins =
++ /* i2c5_scl_m0 */
++ <3 RK_PC7 9 &pcfg_pull_none_smt>,
++ /* i2c5_sda_m0 */
++ <3 RK_PD0 9 &pcfg_pull_none_smt>;
++ };
++
++ /omit-if-no-ref/
++ i2c5m1_xfer: i2c5m1-xfer {
++ rockchip,pins =
++ /* i2c5_scl_m1 */
++ <4 RK_PB6 9 &pcfg_pull_none_smt>,
++ /* i2c5_sda_m1 */
++ <4 RK_PB7 9 &pcfg_pull_none_smt>;
++ };
++
++ /omit-if-no-ref/
++ i2c5m2_xfer: i2c5m2-xfer {
++ rockchip,pins =
++ /* i2c5_scl_m2 */
++ <4 RK_PA6 9 &pcfg_pull_none_smt>,
++ /* i2c5_sda_m2 */
++ <4 RK_PA7 9 &pcfg_pull_none_smt>;
++ };
++
++ /omit-if-no-ref/
++ i2c5m3_xfer: i2c5m3-xfer {
++ rockchip,pins =
++ /* i2c5_scl_m3 */
++ <1 RK_PB6 9 &pcfg_pull_none_smt>,
++ /* i2c5_sda_m3 */
++ <1 RK_PB7 9 &pcfg_pull_none_smt>;
++ };
++ };
++
++ i2c6 {
++ /omit-if-no-ref/
++ i2c6m0_xfer: i2c6m0-xfer {
++ rockchip,pins =
++ /* i2c6_scl_m0 */
++ <0 RK_PD0 9 &pcfg_pull_none_smt>,
++ /* i2c6_sda_m0 */
++ <0 RK_PC7 9 &pcfg_pull_none_smt>;
++ };
++
++ /omit-if-no-ref/
++ i2c6m1_xfer: i2c6m1-xfer {
++ rockchip,pins =
++ /* i2c6_scl_m1 */
++ <1 RK_PC3 9 &pcfg_pull_none_smt>,
++ /* i2c6_sda_m1 */
++ <1 RK_PC2 9 &pcfg_pull_none_smt>;
++ };
++
++ /omit-if-no-ref/
++ i2c6m3_xfer: i2c6m3-xfer {
++ rockchip,pins =
++ /* i2c6_scl_m3 */
++ <4 RK_PB1 9 &pcfg_pull_none_smt>,
++ /* i2c6_sda_m3 */
++ <4 RK_PB0 9 &pcfg_pull_none_smt>;
++ };
++
++ /omit-if-no-ref/
++ i2c6m4_xfer: i2c6m4-xfer {
++ rockchip,pins =
++ /* i2c6_scl_m4 */
++ <3 RK_PA1 9 &pcfg_pull_none_smt>,
++ /* i2c6_sda_m4 */
++ <3 RK_PA0 9 &pcfg_pull_none_smt>;
++ };
++ };
++
++ i2c7 {
++ /omit-if-no-ref/
++ i2c7m0_xfer: i2c7m0-xfer {
++ rockchip,pins =
++ /* i2c7_scl_m0 */
++ <1 RK_PD0 9 &pcfg_pull_none_smt>,
++ /* i2c7_sda_m0 */
++ <1 RK_PD1 9 &pcfg_pull_none_smt>;
++ };
++
++ /omit-if-no-ref/
++ i2c7m2_xfer: i2c7m2-xfer {
++ rockchip,pins =
++ /* i2c7_scl_m2 */
++ <3 RK_PD2 9 &pcfg_pull_none_smt>,
++ /* i2c7_sda_m2 */
++ <3 RK_PD3 9 &pcfg_pull_none_smt>;
++ };
++
++ /omit-if-no-ref/
++ i2c7m3_xfer: i2c7m3-xfer {
++ rockchip,pins =
++ /* i2c7_scl_m3 */
++ <4 RK_PB2 9 &pcfg_pull_none_smt>,
++ /* i2c7_sda_m3 */
++ <4 RK_PB3 9 &pcfg_pull_none_smt>;
++ };
++ };
++
++ i2c8 {
++ /omit-if-no-ref/
++ i2c8m0_xfer: i2c8m0-xfer {
++ rockchip,pins =
++ /* i2c8_scl_m0 */
++ <4 RK_PD2 9 &pcfg_pull_none_smt>,
++ /* i2c8_sda_m0 */
++ <4 RK_PD3 9 &pcfg_pull_none_smt>;
++ };
++
++ /omit-if-no-ref/
++ i2c8m2_xfer: i2c8m2-xfer {
++ rockchip,pins =
++ /* i2c8_scl_m2 */
++ <1 RK_PD6 9 &pcfg_pull_none_smt>,
++ /* i2c8_sda_m2 */
++ <1 RK_PD7 9 &pcfg_pull_none_smt>;
++ };
++
++ /omit-if-no-ref/
++ i2c8m3_xfer: i2c8m3-xfer {
++ rockchip,pins =
++ /* i2c8_scl_m3 */
++ <4 RK_PC0 9 &pcfg_pull_none_smt>,
++ /* i2c8_sda_m3 */
++ <4 RK_PC1 9 &pcfg_pull_none_smt>;
++ };
++
++ /omit-if-no-ref/
++ i2c8m4_xfer: i2c8m4-xfer {
++ rockchip,pins =
++ /* i2c8_scl_m4 */
++ <3 RK_PC2 9 &pcfg_pull_none_smt>,
++ /* i2c8_sda_m4 */
++ <3 RK_PC3 9 &pcfg_pull_none_smt>;
++ };
++ };
++
++ i2s0 {
++ /omit-if-no-ref/
++ i2s0_lrck: i2s0-lrck {
++ rockchip,pins =
++ /* i2s0_lrck */
++ <1 RK_PC5 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s0_mclk: i2s0-mclk {
++ rockchip,pins =
++ /* i2s0_mclk */
++ <1 RK_PC2 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s0_sclk: i2s0-sclk {
++ rockchip,pins =
++ /* i2s0_sclk */
++ <1 RK_PC3 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s0_sdi0: i2s0-sdi0 {
++ rockchip,pins =
++ /* i2s0_sdi0 */
++ <1 RK_PD4 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s0_sdi1: i2s0-sdi1 {
++ rockchip,pins =
++ /* i2s0_sdi1 */
++ <1 RK_PD3 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s0_sdi2: i2s0-sdi2 {
++ rockchip,pins =
++ /* i2s0_sdi2 */
++ <1 RK_PD2 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s0_sdi3: i2s0-sdi3 {
++ rockchip,pins =
++ /* i2s0_sdi3 */
++ <1 RK_PD1 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s0_sdo0: i2s0-sdo0 {
++ rockchip,pins =
++ /* i2s0_sdo0 */
++ <1 RK_PC7 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s0_sdo1: i2s0-sdo1 {
++ rockchip,pins =
++ /* i2s0_sdo1 */
++ <1 RK_PD0 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s0_sdo2: i2s0-sdo2 {
++ rockchip,pins =
++ /* i2s0_sdo2 */
++ <1 RK_PD1 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s0_sdo3: i2s0-sdo3 {
++ rockchip,pins =
++ /* i2s0_sdo3 */
++ <1 RK_PD2 1 &pcfg_pull_none>;
++ };
++ };
++
++ i2s1 {
++ /omit-if-no-ref/
++ i2s1m0_lrck: i2s1m0-lrck {
++ rockchip,pins =
++ /* i2s1m0_lrck */
++ <4 RK_PA2 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s1m0_mclk: i2s1m0-mclk {
++ rockchip,pins =
++ /* i2s1m0_mclk */
++ <4 RK_PA0 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s1m0_sclk: i2s1m0-sclk {
++ rockchip,pins =
++ /* i2s1m0_sclk */
++ <4 RK_PA1 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s1m0_sdi0: i2s1m0-sdi0 {
++ rockchip,pins =
++ /* i2s1m0_sdi0 */
++ <4 RK_PA5 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s1m0_sdi1: i2s1m0-sdi1 {
++ rockchip,pins =
++ /* i2s1m0_sdi1 */
++ <4 RK_PA6 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s1m0_sdi2: i2s1m0-sdi2 {
++ rockchip,pins =
++ /* i2s1m0_sdi2 */
++ <4 RK_PA7 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s1m0_sdi3: i2s1m0-sdi3 {
++ rockchip,pins =
++ /* i2s1m0_sdi3 */
++ <4 RK_PB0 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s1m0_sdo0: i2s1m0-sdo0 {
++ rockchip,pins =
++ /* i2s1m0_sdo0 */
++ <4 RK_PB1 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s1m0_sdo1: i2s1m0-sdo1 {
++ rockchip,pins =
++ /* i2s1m0_sdo1 */
++ <4 RK_PB2 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s1m0_sdo2: i2s1m0-sdo2 {
++ rockchip,pins =
++ /* i2s1m0_sdo2 */
++ <4 RK_PB3 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s1m0_sdo3: i2s1m0-sdo3 {
++ rockchip,pins =
++ /* i2s1m0_sdo3 */
++ <4 RK_PB4 3 &pcfg_pull_none>;
++ };
++ /omit-if-no-ref/
++ i2s1m1_lrck: i2s1m1-lrck {
++ rockchip,pins =
++ /* i2s1m1_lrck */
++ <0 RK_PB7 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s1m1_mclk: i2s1m1-mclk {
++ rockchip,pins =
++ /* i2s1m1_mclk */
++ <0 RK_PB5 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s1m1_sclk: i2s1m1-sclk {
++ rockchip,pins =
++ /* i2s1m1_sclk */
++ <0 RK_PB6 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s1m1_sdi0: i2s1m1-sdi0 {
++ rockchip,pins =
++ /* i2s1m1_sdi0 */
++ <0 RK_PC5 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s1m1_sdi1: i2s1m1-sdi1 {
++ rockchip,pins =
++ /* i2s1m1_sdi1 */
++ <0 RK_PC6 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s1m1_sdi2: i2s1m1-sdi2 {
++ rockchip,pins =
++ /* i2s1m1_sdi2 */
++ <0 RK_PC7 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s1m1_sdi3: i2s1m1-sdi3 {
++ rockchip,pins =
++ /* i2s1m1_sdi3 */
++ <0 RK_PD0 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s1m1_sdo0: i2s1m1-sdo0 {
++ rockchip,pins =
++ /* i2s1m1_sdo0 */
++ <0 RK_PD1 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s1m1_sdo1: i2s1m1-sdo1 {
++ rockchip,pins =
++ /* i2s1m1_sdo1 */
++ <0 RK_PD2 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s1m1_sdo2: i2s1m1-sdo2 {
++ rockchip,pins =
++ /* i2s1m1_sdo2 */
++ <0 RK_PD4 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s1m1_sdo3: i2s1m1-sdo3 {
++ rockchip,pins =
++ /* i2s1m1_sdo3 */
++ <0 RK_PD5 1 &pcfg_pull_none>;
++ };
++ };
++
++ i2s2 {
++ /omit-if-no-ref/
++ i2s2m0_lrck: i2s2m0-lrck {
++ rockchip,pins =
++ /* i2s2m0_lrck */
++ <2 RK_PC0 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s2m0_mclk: i2s2m0-mclk {
++ rockchip,pins =
++ /* i2s2m0_mclk */
++ <2 RK_PB6 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s2m0_sclk: i2s2m0-sclk {
++ rockchip,pins =
++ /* i2s2m0_sclk */
++ <2 RK_PB7 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s2m0_sdi: i2s2m0-sdi {
++ rockchip,pins =
++ /* i2s2m0_sdi */
++ <2 RK_PC3 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s2m0_sdo: i2s2m0-sdo {
++ rockchip,pins =
++ /* i2s2m0_sdo */
++ <4 RK_PC3 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s2m1_lrck: i2s2m1-lrck {
++ rockchip,pins =
++ /* i2s2m1_lrck */
++ <3 RK_PB6 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s2m1_mclk: i2s2m1-mclk {
++ rockchip,pins =
++ /* i2s2m1_mclk */
++ <3 RK_PB4 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s2m1_sclk: i2s2m1-sclk {
++ rockchip,pins =
++ /* i2s2m1_sclk */
++ <3 RK_PB5 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s2m1_sdi: i2s2m1-sdi {
++ rockchip,pins =
++ /* i2s2m1_sdi */
++ <3 RK_PB2 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s2m1_sdo: i2s2m1-sdo {
++ rockchip,pins =
++ /* i2s2m1_sdo */
++ <3 RK_PB3 3 &pcfg_pull_none>;
++ };
++ };
++
++ i2s3 {
++ /omit-if-no-ref/
++ i2s3_lrck: i2s3-lrck {
++ rockchip,pins =
++ /* i2s3_lrck */
++ <3 RK_PA2 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s3_mclk: i2s3-mclk {
++ rockchip,pins =
++ /* i2s3_mclk */
++ <3 RK_PA0 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s3_sclk: i2s3-sclk {
++ rockchip,pins =
++ /* i2s3_sclk */
++ <3 RK_PA1 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s3_sdi: i2s3-sdi {
++ rockchip,pins =
++ /* i2s3_sdi */
++ <3 RK_PA4 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s3_sdo: i2s3-sdo {
++ rockchip,pins =
++ /* i2s3_sdo */
++ <3 RK_PA3 3 &pcfg_pull_none>;
++ };
++ };
++
++ jtag {
++ /omit-if-no-ref/
++ jtagm0_pins: jtagm0-pins {
++ rockchip,pins =
++ /* jtag_tck_m0 */
++ <4 RK_PD2 5 &pcfg_pull_none>,
++ /* jtag_tms_m0 */
++ <4 RK_PD3 5 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ jtagm1_pins: jtagm1-pins {
++ rockchip,pins =
++ /* jtag_tck_m1 */
++ <4 RK_PD0 5 &pcfg_pull_none>,
++ /* jtag_tms_m1 */
++ <4 RK_PD1 5 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ jtagm2_pins: jtagm2-pins {
++ rockchip,pins =
++ /* jtag_tck_m2 */
++ <0 RK_PB5 2 &pcfg_pull_none>,
++ /* jtag_tms_m2 */
++ <0 RK_PB6 2 &pcfg_pull_none>;
++ };
++ };
++
++ litcpu {
++ /omit-if-no-ref/
++ litcpu_pins: litcpu-pins {
++ rockchip,pins =
++ /* litcpu_avs */
++ <0 RK_PD3 1 &pcfg_pull_none>;
++ };
++ };
++
++ mcu {
++ /omit-if-no-ref/
++ mcum0_pins: mcum0-pins {
++ rockchip,pins =
++ /* mcu_jtag_tck_m0 */
++ <4 RK_PD4 5 &pcfg_pull_none>,
++ /* mcu_jtag_tms_m0 */
++ <4 RK_PD5 5 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ mcum1_pins: mcum1-pins {
++ rockchip,pins =
++ /* mcu_jtag_tck_m1 */
++ <3 RK_PD4 6 &pcfg_pull_none>,
++ /* mcu_jtag_tms_m1 */
++ <3 RK_PD5 6 &pcfg_pull_none>;
++ };
++ };
++
++ mipi {
++ /omit-if-no-ref/
++ mipim0_camera0_clk: mipim0-camera0-clk {
++ rockchip,pins =
++ /* mipim0_camera0_clk */
++ <4 RK_PB1 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ mipim0_camera1_clk: mipim0-camera1-clk {
++ rockchip,pins =
++ /* mipim0_camera1_clk */
++ <1 RK_PB6 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ mipim0_camera2_clk: mipim0-camera2-clk {
++ rockchip,pins =
++ /* mipim0_camera2_clk */
++ <1 RK_PB7 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ mipim0_camera3_clk: mipim0-camera3-clk {
++ rockchip,pins =
++ /* mipim0_camera3_clk */
++ <1 RK_PD6 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ mipim0_camera4_clk: mipim0-camera4-clk {
++ rockchip,pins =
++ /* mipim0_camera4_clk */
++ <1 RK_PD7 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ mipim1_camera0_clk: mipim1-camera0-clk {
++ rockchip,pins =
++ /* mipim1_camera0_clk */
++ <3 RK_PA5 4 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ mipim1_camera1_clk: mipim1-camera1-clk {
++ rockchip,pins =
++ /* mipim1_camera1_clk */
++ <3 RK_PA6 4 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ mipim1_camera2_clk: mipim1-camera2-clk {
++ rockchip,pins =
++ /* mipim1_camera2_clk */
++ <3 RK_PA7 4 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ mipim1_camera3_clk: mipim1-camera3-clk {
++ rockchip,pins =
++ /* mipim1_camera3_clk */
++ <3 RK_PB0 4 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ mipim1_camera4_clk: mipim1-camera4-clk {
++ rockchip,pins =
++ /* mipim1_camera4_clk */
++ <3 RK_PB1 4 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ mipi_te0: mipi-te0 {
++ rockchip,pins =
++ /* mipi_te0 */
++ <3 RK_PC2 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ mipi_te1: mipi-te1 {
++ rockchip,pins =
++ /* mipi_te1 */
++ <3 RK_PC3 2 &pcfg_pull_none>;
++ };
++ };
++
++ npu {
++ /omit-if-no-ref/
++ npu_pins: npu-pins {
++ rockchip,pins =
++ /* npu_avs */
++ <0 RK_PC6 2 &pcfg_pull_none>;
++ };
++ };
++
++ pcie20x1 {
++ /omit-if-no-ref/
++ pcie20x1m0_pins: pcie20x1m0-pins {
++ rockchip,pins =
++ /* pcie20x1_2_clkreqn_m0 */
++ <3 RK_PC7 4 &pcfg_pull_none>,
++ /* pcie20x1_2_perstn_m0 */
++ <3 RK_PD1 4 &pcfg_pull_none>,
++ /* pcie20x1_2_waken_m0 */
++ <3 RK_PD0 4 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pcie20x1m1_pins: pcie20x1m1-pins {
++ rockchip,pins =
++ /* pcie20x1_2_clkreqn_m1 */
++ <4 RK_PB7 4 &pcfg_pull_none>,
++ /* pcie20x1_2_perstn_m1 */
++ <4 RK_PC1 4 &pcfg_pull_none>,
++ /* pcie20x1_2_waken_m1 */
++ <4 RK_PC0 4 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pcie20x1_2_button_rstn: pcie20x1-2-button-rstn {
++ rockchip,pins =
++ /* pcie20x1_2_button_rstn */
++ <4 RK_PB3 4 &pcfg_pull_none>;
++ };
++ };
++
++ pcie30phy {
++ /omit-if-no-ref/
++ pcie30phy_pins: pcie30phy-pins {
++ rockchip,pins =
++ /* pcie30phy_dtb0 */
++ <1 RK_PC4 4 &pcfg_pull_none>,
++ /* pcie30phy_dtb1 */
++ <1 RK_PD1 4 &pcfg_pull_none>;
++ };
++ };
++
++ pcie30x1 {
++ /omit-if-no-ref/
++ pcie30x1m0_pins: pcie30x1m0-pins {
++ rockchip,pins =
++ /* pcie30x1_0_clkreqn_m0 */
++ <0 RK_PC0 12 &pcfg_pull_none>,
++ /* pcie30x1_0_perstn_m0 */
++ <0 RK_PC5 12 &pcfg_pull_none>,
++ /* pcie30x1_0_waken_m0 */
++ <0 RK_PC4 12 &pcfg_pull_none>,
++ /* pcie30x1_1_clkreqn_m0 */
++ <0 RK_PB5 12 &pcfg_pull_none>,
++ /* pcie30x1_1_perstn_m0 */
++ <0 RK_PB7 12 &pcfg_pull_none>,
++ /* pcie30x1_1_waken_m0 */
++ <0 RK_PB6 12 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pcie30x1m1_pins: pcie30x1m1-pins {
++ rockchip,pins =
++ /* pcie30x1_0_clkreqn_m1 */
++ <4 RK_PA3 4 &pcfg_pull_none>,
++ /* pcie30x1_0_perstn_m1 */
++ <4 RK_PA5 4 &pcfg_pull_none>,
++ /* pcie30x1_0_waken_m1 */
++ <4 RK_PA4 4 &pcfg_pull_none>,
++ /* pcie30x1_1_clkreqn_m1 */
++ <4 RK_PA0 4 &pcfg_pull_none>,
++ /* pcie30x1_1_perstn_m1 */
++ <4 RK_PA2 4 &pcfg_pull_none>,
++ /* pcie30x1_1_waken_m1 */
++ <4 RK_PA1 4 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pcie30x1m2_pins: pcie30x1m2-pins {
++ rockchip,pins =
++ /* pcie30x1_0_clkreqn_m2 */
++ <1 RK_PB5 4 &pcfg_pull_none>,
++ /* pcie30x1_0_perstn_m2 */
++ <1 RK_PB4 4 &pcfg_pull_none>,
++ /* pcie30x1_0_waken_m2 */
++ <1 RK_PB3 4 &pcfg_pull_none>,
++ /* pcie30x1_1_clkreqn_m2 */
++ <1 RK_PA0 4 &pcfg_pull_none>,
++ /* pcie30x1_1_perstn_m2 */
++ <1 RK_PA7 4 &pcfg_pull_none>,
++ /* pcie30x1_1_waken_m2 */
++ <1 RK_PA1 4 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pcie30x1_0_button_rstn: pcie30x1-0-button-rstn {
++ rockchip,pins =
++ /* pcie30x1_0_button_rstn */
++ <4 RK_PB1 4 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pcie30x1_1_button_rstn: pcie30x1-1-button-rstn {
++ rockchip,pins =
++ /* pcie30x1_1_button_rstn */
++ <4 RK_PB2 4 &pcfg_pull_none>;
++ };
++ };
++
++ pcie30x2 {
++ /omit-if-no-ref/
++ pcie30x2m0_pins: pcie30x2m0-pins {
++ rockchip,pins =
++ /* pcie30x2_clkreqn_m0 */
++ <0 RK_PD1 12 &pcfg_pull_none>,
++ /* pcie30x2_perstn_m0 */
++ <0 RK_PD4 12 &pcfg_pull_none>,
++ /* pcie30x2_waken_m0 */
++ <0 RK_PD2 12 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pcie30x2m1_pins: pcie30x2m1-pins {
++ rockchip,pins =
++ /* pcie30x2_clkreqn_m1 */
++ <4 RK_PA6 4 &pcfg_pull_none>,
++ /* pcie30x2_perstn_m1 */
++ <4 RK_PB0 4 &pcfg_pull_none>,
++ /* pcie30x2_waken_m1 */
++ <4 RK_PA7 4 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pcie30x2m2_pins: pcie30x2m2-pins {
++ rockchip,pins =
++ /* pcie30x2_clkreqn_m2 */
++ <3 RK_PD2 4 &pcfg_pull_none>,
++ /* pcie30x2_perstn_m2 */
++ <3 RK_PD4 4 &pcfg_pull_none>,
++ /* pcie30x2_waken_m2 */
++ <3 RK_PD3 4 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pcie30x2m3_pins: pcie30x2m3-pins {
++ rockchip,pins =
++ /* pcie30x2_clkreqn_m3 */
++ <1 RK_PD7 4 &pcfg_pull_none>,
++ /* pcie30x2_perstn_m3 */
++ <1 RK_PB7 4 &pcfg_pull_none>,
++ /* pcie30x2_waken_m3 */
++ <1 RK_PB6 4 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pcie30x2_button_rstn: pcie30x2-button-rstn {
++ rockchip,pins =
++ /* pcie30x2_button_rstn */
++ <3 RK_PC1 4 &pcfg_pull_none>;
++ };
++ };
++
++ pcie30x4 {
++ /omit-if-no-ref/
++ pcie30x4m0_pins: pcie30x4m0-pins {
++ rockchip,pins =
++ /* pcie30x4_clkreqn_m0 */
++ <0 RK_PC6 12 &pcfg_pull_none>,
++ /* pcie30x4_perstn_m0 */
++ <0 RK_PD0 12 &pcfg_pull_none>,
++ /* pcie30x4_waken_m0 */
++ <0 RK_PC7 12 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pcie30x4m1_pins: pcie30x4m1-pins {
++ rockchip,pins =
++ /* pcie30x4_clkreqn_m1 */
++ <4 RK_PB4 4 &pcfg_pull_none>,
++ /* pcie30x4_perstn_m1 */
++ <4 RK_PB6 4 &pcfg_pull_none>,
++ /* pcie30x4_waken_m1 */
++ <4 RK_PB5 4 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pcie30x4m2_pins: pcie30x4m2-pins {
++ rockchip,pins =
++ /* pcie30x4_clkreqn_m2 */
++ <3 RK_PC4 4 &pcfg_pull_none>,
++ /* pcie30x4_perstn_m2 */
++ <3 RK_PC6 4 &pcfg_pull_none>,
++ /* pcie30x4_waken_m2 */
++ <3 RK_PC5 4 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pcie30x4m3_pins: pcie30x4m3-pins {
++ rockchip,pins =
++ /* pcie30x4_clkreqn_m3 */
++ <1 RK_PB0 4 &pcfg_pull_none>,
++ /* pcie30x4_perstn_m3 */
++ <1 RK_PB2 4 &pcfg_pull_none>,
++ /* pcie30x4_waken_m3 */
++ <1 RK_PB1 4 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pcie30x4_button_rstn: pcie30x4-button-rstn {
++ rockchip,pins =
++ /* pcie30x4_button_rstn */
++ <3 RK_PD5 4 &pcfg_pull_none>;
++ };
++ };
++
++ pdm0 {
++ /omit-if-no-ref/
++ pdm0m0_clk: pdm0m0-clk {
++ rockchip,pins =
++ /* pdm0_clk0_m0 */
++ <1 RK_PC6 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pdm0m0_clk1: pdm0m0-clk1 {
++ rockchip,pins =
++ /* pdm0m0_clk1 */
++ <1 RK_PC4 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pdm0m0_sdi0: pdm0m0-sdi0 {
++ rockchip,pins =
++ /* pdm0m0_sdi0 */
++ <1 RK_PD5 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pdm0m0_sdi1: pdm0m0-sdi1 {
++ rockchip,pins =
++ /* pdm0m0_sdi1 */
++ <1 RK_PD1 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pdm0m0_sdi2: pdm0m0-sdi2 {
++ rockchip,pins =
++ /* pdm0m0_sdi2 */
++ <1 RK_PD2 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pdm0m0_sdi3: pdm0m0-sdi3 {
++ rockchip,pins =
++ /* pdm0m0_sdi3 */
++ <1 RK_PD3 3 &pcfg_pull_none>;
++ };
++ /omit-if-no-ref/
++ pdm0m1_clk: pdm0m1-clk {
++ rockchip,pins =
++ /* pdm0_clk0_m1 */
++ <0 RK_PC0 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pdm0m1_clk1: pdm0m1-clk1 {
++ rockchip,pins =
++ /* pdm0m1_clk1 */
++ <0 RK_PC4 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pdm0m1_sdi0: pdm0m1-sdi0 {
++ rockchip,pins =
++ /* pdm0m1_sdi0 */
++ <0 RK_PC7 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pdm0m1_sdi1: pdm0m1-sdi1 {
++ rockchip,pins =
++ /* pdm0m1_sdi1 */
++ <0 RK_PD0 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pdm0m1_sdi2: pdm0m1-sdi2 {
++ rockchip,pins =
++ /* pdm0m1_sdi2 */
++ <0 RK_PD4 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pdm0m1_sdi3: pdm0m1-sdi3 {
++ rockchip,pins =
++ /* pdm0m1_sdi3 */
++ <0 RK_PD6 2 &pcfg_pull_none>;
++ };
++ };
++
++ pdm1 {
++ /omit-if-no-ref/
++ pdm1m0_clk: pdm1m0-clk {
++ rockchip,pins =
++ /* pdm1_clk0_m0 */
++ <4 RK_PD5 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pdm1m0_clk1: pdm1m0-clk1 {
++ rockchip,pins =
++ /* pdm1m0_clk1 */
++ <4 RK_PD4 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pdm1m0_sdi0: pdm1m0-sdi0 {
++ rockchip,pins =
++ /* pdm1m0_sdi0 */
++ <4 RK_PD3 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pdm1m0_sdi1: pdm1m0-sdi1 {
++ rockchip,pins =
++ /* pdm1m0_sdi1 */
++ <4 RK_PD2 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pdm1m0_sdi2: pdm1m0-sdi2 {
++ rockchip,pins =
++ /* pdm1m0_sdi2 */
++ <4 RK_PD1 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pdm1m0_sdi3: pdm1m0-sdi3 {
++ rockchip,pins =
++ /* pdm1m0_sdi3 */
++ <4 RK_PD0 2 &pcfg_pull_none>;
++ };
++ /omit-if-no-ref/
++ pdm1m1_clk: pdm1m1-clk {
++ rockchip,pins =
++ /* pdm1_clk0_m1 */
++ <1 RK_PB4 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pdm1m1_clk1: pdm1m1-clk1 {
++ rockchip,pins =
++ /* pdm1m1_clk1 */
++ <1 RK_PB3 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pdm1m1_sdi0: pdm1m1-sdi0 {
++ rockchip,pins =
++ /* pdm1m1_sdi0 */
++ <1 RK_PA7 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pdm1m1_sdi1: pdm1m1-sdi1 {
++ rockchip,pins =
++ /* pdm1m1_sdi1 */
++ <1 RK_PB0 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pdm1m1_sdi2: pdm1m1-sdi2 {
++ rockchip,pins =
++ /* pdm1m1_sdi2 */
++ <1 RK_PB1 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pdm1m1_sdi3: pdm1m1-sdi3 {
++ rockchip,pins =
++ /* pdm1m1_sdi3 */
++ <1 RK_PB2 2 &pcfg_pull_none>;
++ };
++ };
++
++ pmic {
++ /omit-if-no-ref/
++ pmic_pins: pmic-pins {
++ rockchip,pins =
++ /* pmic_int_l */
++ <0 RK_PA7 0 &pcfg_pull_up>,
++ /* pmic_sleep1 */
++ <0 RK_PA2 1 &pcfg_pull_none>,
++ /* pmic_sleep2 */
++ <0 RK_PA3 1 &pcfg_pull_none>,
++ /* pmic_sleep3 */
++ <0 RK_PC1 1 &pcfg_pull_none>,
++ /* pmic_sleep4 */
++ <0 RK_PC2 1 &pcfg_pull_none>,
++ /* pmic_sleep5 */
++ <0 RK_PC3 1 &pcfg_pull_none>,
++ /* pmic_sleep6 */
++ <0 RK_PD6 1 &pcfg_pull_none>;
++ };
++ };
++
++ pmu {
++ /omit-if-no-ref/
++ pmu_pins: pmu-pins {
++ rockchip,pins =
++ /* pmu_debug */
++ <0 RK_PA5 3 &pcfg_pull_none>;
++ };
++ };
++
++ pwm0 {
++ /omit-if-no-ref/
++ pwm0m0_pins: pwm0m0-pins {
++ rockchip,pins =
++ /* pwm0_m0 */
++ <0 RK_PB7 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pwm0m1_pins: pwm0m1-pins {
++ rockchip,pins =
++ /* pwm0_m1 */
++ <1 RK_PD2 11 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pwm0m2_pins: pwm0m2-pins {
++ rockchip,pins =
++ /* pwm0_m2 */
++ <1 RK_PA2 11 &pcfg_pull_none>;
++ };
++ };
++
++ pwm1 {
++ /omit-if-no-ref/
++ pwm1m0_pins: pwm1m0-pins {
++ rockchip,pins =
++ /* pwm1_m0 */
++ <0 RK_PC0 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pwm1m1_pins: pwm1m1-pins {
++ rockchip,pins =
++ /* pwm1_m1 */
++ <1 RK_PD3 11 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pwm1m2_pins: pwm1m2-pins {
++ rockchip,pins =
++ /* pwm1_m2 */
++ <1 RK_PA3 11 &pcfg_pull_none>;
++ };
++ };
++
++ pwm2 {
++ /omit-if-no-ref/
++ pwm2m0_pins: pwm2m0-pins {
++ rockchip,pins =
++ /* pwm2_m0 */
++ <0 RK_PC4 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pwm2m1_pins: pwm2m1-pins {
++ rockchip,pins =
++ /* pwm2_m1 */
++ <3 RK_PB1 11 &pcfg_pull_none>;
++ };
++ };
++
++ pwm3 {
++ /omit-if-no-ref/
++ pwm3m0_pins: pwm3m0-pins {
++ rockchip,pins =
++ /* pwm3_ir_m0 */
++ <0 RK_PD4 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pwm3m1_pins: pwm3m1-pins {
++ rockchip,pins =
++ /* pwm3_ir_m1 */
++ <3 RK_PB2 11 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pwm3m2_pins: pwm3m2-pins {
++ rockchip,pins =
++ /* pwm3_ir_m2 */
++ <1 RK_PC2 11 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pwm3m3_pins: pwm3m3-pins {
++ rockchip,pins =
++ /* pwm3_ir_m3 */
++ <1 RK_PA7 11 &pcfg_pull_none>;
++ };
++ };
++
++ pwm4 {
++ /omit-if-no-ref/
++ pwm4m0_pins: pwm4m0-pins {
++ rockchip,pins =
++ /* pwm4_m0 */
++ <0 RK_PC5 11 &pcfg_pull_none>;
++ };
++ };
++
++ pwm5 {
++ /omit-if-no-ref/
++ pwm5m0_pins: pwm5m0-pins {
++ rockchip,pins =
++ /* pwm5_m0 */
++ <0 RK_PB1 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pwm5m1_pins: pwm5m1-pins {
++ rockchip,pins =
++ /* pwm5_m1 */
++ <0 RK_PC6 11 &pcfg_pull_none>;
++ };
++ };
++
++ pwm6 {
++ /omit-if-no-ref/
++ pwm6m0_pins: pwm6m0-pins {
++ rockchip,pins =
++ /* pwm6_m0 */
++ <0 RK_PC7 11 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pwm6m1_pins: pwm6m1-pins {
++ rockchip,pins =
++ /* pwm6_m1 */
++ <4 RK_PC1 11 &pcfg_pull_none>;
++ };
++ };
++
++ pwm7 {
++ /omit-if-no-ref/
++ pwm7m0_pins: pwm7m0-pins {
++ rockchip,pins =
++ /* pwm7_ir_m0 */
++ <0 RK_PD0 11 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pwm7m1_pins: pwm7m1-pins {
++ rockchip,pins =
++ /* pwm7_ir_m1 */
++ <4 RK_PD4 11 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pwm7m2_pins: pwm7m2-pins {
++ rockchip,pins =
++ /* pwm7_ir_m2 */
++ <1 RK_PC3 11 &pcfg_pull_none>;
++ };
++ };
++
++ pwm8 {
++ /omit-if-no-ref/
++ pwm8m0_pins: pwm8m0-pins {
++ rockchip,pins =
++ /* pwm8_m0 */
++ <3 RK_PA7 11 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pwm8m1_pins: pwm8m1-pins {
++ rockchip,pins =
++ /* pwm8_m1 */
++ <4 RK_PD0 11 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pwm8m2_pins: pwm8m2-pins {
++ rockchip,pins =
++ /* pwm8_m2 */
++ <3 RK_PD0 11 &pcfg_pull_none>;
++ };
++ };
++
++ pwm9 {
++ /omit-if-no-ref/
++ pwm9m0_pins: pwm9m0-pins {
++ rockchip,pins =
++ /* pwm9_m0 */
++ <3 RK_PB0 11 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pwm9m1_pins: pwm9m1-pins {
++ rockchip,pins =
++ /* pwm9_m1 */
++ <4 RK_PD1 11 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pwm9m2_pins: pwm9m2-pins {
++ rockchip,pins =
++ /* pwm9_m2 */
++ <3 RK_PD1 11 &pcfg_pull_none>;
++ };
++ };
++
++ pwm10 {
++ /omit-if-no-ref/
++ pwm10m0_pins: pwm10m0-pins {
++ rockchip,pins =
++ /* pwm10_m0 */
++ <3 RK_PA0 11 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pwm10m1_pins: pwm10m1-pins {
++ rockchip,pins =
++ /* pwm10_m1 */
++ <4 RK_PD3 11 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pwm10m2_pins: pwm10m2-pins {
++ rockchip,pins =
++ /* pwm10_m2 */
++ <3 RK_PD3 11 &pcfg_pull_none>;
++ };
++ };
++
++ pwm11 {
++ /omit-if-no-ref/
++ pwm11m0_pins: pwm11m0-pins {
++ rockchip,pins =
++ /* pwm11_ir_m0 */
++ <3 RK_PA1 11 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pwm11m1_pins: pwm11m1-pins {
++ rockchip,pins =
++ /* pwm11_ir_m1 */
++ <4 RK_PB4 11 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pwm11m2_pins: pwm11m2-pins {
++ rockchip,pins =
++ /* pwm11_ir_m2 */
++ <1 RK_PC4 11 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pwm11m3_pins: pwm11m3-pins {
++ rockchip,pins =
++ /* pwm11_ir_m3 */
++ <3 RK_PD5 11 &pcfg_pull_none>;
++ };
++ };
++
++ pwm12 {
++ /omit-if-no-ref/
++ pwm12m0_pins: pwm12m0-pins {
++ rockchip,pins =
++ /* pwm12_m0 */
++ <3 RK_PB5 11 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pwm12m1_pins: pwm12m1-pins {
++ rockchip,pins =
++ /* pwm12_m1 */
++ <4 RK_PB5 11 &pcfg_pull_none>;
++ };
++ };
++
++ pwm13 {
++ /omit-if-no-ref/
++ pwm13m0_pins: pwm13m0-pins {
++ rockchip,pins =
++ /* pwm13_m0 */
++ <3 RK_PB6 11 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pwm13m1_pins: pwm13m1-pins {
++ rockchip,pins =
++ /* pwm13_m1 */
++ <4 RK_PB6 11 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pwm13m2_pins: pwm13m2-pins {
++ rockchip,pins =
++ /* pwm13_m2 */
++ <1 RK_PB7 11 &pcfg_pull_none>;
++ };
++ };
++
++ pwm14 {
++ /omit-if-no-ref/
++ pwm14m0_pins: pwm14m0-pins {
++ rockchip,pins =
++ /* pwm14_m0 */
++ <3 RK_PC2 11 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pwm14m1_pins: pwm14m1-pins {
++ rockchip,pins =
++ /* pwm14_m1 */
++ <4 RK_PB2 11 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pwm14m2_pins: pwm14m2-pins {
++ rockchip,pins =
++ /* pwm14_m2 */
++ <1 RK_PD6 11 &pcfg_pull_none>;
++ };
++ };
++
++ pwm15 {
++ /omit-if-no-ref/
++ pwm15m0_pins: pwm15m0-pins {
++ rockchip,pins =
++ /* pwm15_ir_m0 */
++ <3 RK_PC3 11 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pwm15m1_pins: pwm15m1-pins {
++ rockchip,pins =
++ /* pwm15_ir_m1 */
++ <4 RK_PB3 11 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pwm15m2_pins: pwm15m2-pins {
++ rockchip,pins =
++ /* pwm15_ir_m2 */
++ <1 RK_PC6 11 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ pwm15m3_pins: pwm15m3-pins {
++ rockchip,pins =
++ /* pwm15_ir_m3 */
++ <1 RK_PD7 11 &pcfg_pull_none>;
++ };
++ };
++
++ refclk {
++ /omit-if-no-ref/
++ refclk_pins: refclk-pins {
++ rockchip,pins =
++ /* refclk_out */
++ <0 RK_PA0 1 &pcfg_pull_none>;
++ };
++ };
++
++ sata {
++ /omit-if-no-ref/
++ sata_pins: sata-pins {
++ rockchip,pins =
++ /* sata_cp_pod */
++ <0 RK_PC6 13 &pcfg_pull_none>,
++ /* sata_cpdet */
++ <0 RK_PD4 13 &pcfg_pull_none>,
++ /* sata_mp_switch */
++ <0 RK_PD5 13 &pcfg_pull_none>;
++ };
++ };
++
++ sata0 {
++ /omit-if-no-ref/
++ sata0m0_pins: sata0m0-pins {
++ rockchip,pins =
++ /* sata0_act_led_m0 */
++ <4 RK_PB6 6 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ sata0m1_pins: sata0m1-pins {
++ rockchip,pins =
++ /* sata0_act_led_m1 */
++ <1 RK_PB3 6 &pcfg_pull_none>;
++ };
++ };
++
++ sata1 {
++ /omit-if-no-ref/
++ sata1m0_pins: sata1m0-pins {
++ rockchip,pins =
++ /* sata1_act_led_m0 */
++ <4 RK_PB5 6 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ sata1m1_pins: sata1m1-pins {
++ rockchip,pins =
++ /* sata1_act_led_m1 */
++ <1 RK_PA1 6 &pcfg_pull_none>;
++ };
++ };
++
++ sata2 {
++ /omit-if-no-ref/
++ sata2m0_pins: sata2m0-pins {
++ rockchip,pins =
++ /* sata2_act_led_m0 */
++ <4 RK_PB1 6 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ sata2m1_pins: sata2m1-pins {
++ rockchip,pins =
++ /* sata2_act_led_m1 */
++ <1 RK_PB7 6 &pcfg_pull_none>;
++ };
++ };
++
++ sdio {
++ /omit-if-no-ref/
++ sdiom1_pins: sdiom1-pins {
++ rockchip,pins =
++ /* sdio_clk_m1 */
++ <3 RK_PA5 2 &pcfg_pull_none>,
++ /* sdio_cmd_m1 */
++ <3 RK_PA4 2 &pcfg_pull_none>,
++ /* sdio_d0_m1 */
++ <3 RK_PA0 2 &pcfg_pull_none>,
++ /* sdio_d1_m1 */
++ <3 RK_PA1 2 &pcfg_pull_none>,
++ /* sdio_d2_m1 */
++ <3 RK_PA2 2 &pcfg_pull_none>,
++ /* sdio_d3_m1 */
++ <3 RK_PA3 2 &pcfg_pull_none>;
++ };
++ };
++
++ sdmmc {
++ /omit-if-no-ref/
++ sdmmc_bus4: sdmmc-bus4 {
++ rockchip,pins =
++ /* sdmmc_d0 */
++ <4 RK_PD0 1 &pcfg_pull_up_drv_level_2>,
++ /* sdmmc_d1 */
++ <4 RK_PD1 1 &pcfg_pull_up_drv_level_2>,
++ /* sdmmc_d2 */
++ <4 RK_PD2 1 &pcfg_pull_up_drv_level_2>,
++ /* sdmmc_d3 */
++ <4 RK_PD3 1 &pcfg_pull_up_drv_level_2>;
++ };
++
++ /omit-if-no-ref/
++ sdmmc_clk: sdmmc-clk {
++ rockchip,pins =
++ /* sdmmc_clk */
++ <4 RK_PD5 1 &pcfg_pull_up_drv_level_2>;
++ };
++
++ /omit-if-no-ref/
++ sdmmc_cmd: sdmmc-cmd {
++ rockchip,pins =
++ /* sdmmc_cmd */
++ <4 RK_PD4 1 &pcfg_pull_up_drv_level_2>;
++ };
++
++ /omit-if-no-ref/
++ sdmmc_det: sdmmc-det {
++ rockchip,pins =
++ /* sdmmc_det */
++ <0 RK_PA4 1 &pcfg_pull_up>;
++ };
++
++ /omit-if-no-ref/
++ sdmmc_pwren: sdmmc-pwren {
++ rockchip,pins =
++ /* sdmmc_pwren */
++ <0 RK_PA5 2 &pcfg_pull_none>;
++ };
++ };
++
++ spdif0 {
++ /omit-if-no-ref/
++ spdif0m0_tx: spdif0m0-tx {
++ rockchip,pins =
++ /* spdif0m0_tx */
++ <1 RK_PB6 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ spdif0m1_tx: spdif0m1-tx {
++ rockchip,pins =
++ /* spdif0m1_tx */
++ <4 RK_PB4 6 &pcfg_pull_none>;
++ };
++ };
++
++ spdif1 {
++ /omit-if-no-ref/
++ spdif1m0_tx: spdif1m0-tx {
++ rockchip,pins =
++ /* spdif1m0_tx */
++ <1 RK_PB7 3 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ spdif1m1_tx: spdif1m1-tx {
++ rockchip,pins =
++ /* spdif1m1_tx */
++ <4 RK_PB1 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ spdif1m2_tx: spdif1m2-tx {
++ rockchip,pins =
++ /* spdif1m2_tx */
++ <4 RK_PC1 3 &pcfg_pull_none>;
++ };
++ };
++
++ spi0 {
++ /omit-if-no-ref/
++ spi0m0_pins: spi0m0-pins {
++ rockchip,pins =
++ /* spi0_clk_m0 */
++ <0 RK_PC6 8 &pcfg_pull_up_drv_level_1>,
++ /* spi0_miso_m0 */
++ <0 RK_PC7 8 &pcfg_pull_up_drv_level_1>,
++ /* spi0_mosi_m0 */
++ <0 RK_PC0 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi0m0_cs0: spi0m0-cs0 {
++ rockchip,pins =
++ /* spi0_cs0_m0 */
++ <0 RK_PD1 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi0m0_cs1: spi0m0-cs1 {
++ rockchip,pins =
++ /* spi0_cs1_m0 */
++ <0 RK_PB7 8 &pcfg_pull_up_drv_level_1>;
++ };
++ /omit-if-no-ref/
++ spi0m1_pins: spi0m1-pins {
++ rockchip,pins =
++ /* spi0_clk_m1 */
++ <4 RK_PA2 8 &pcfg_pull_up_drv_level_1>,
++ /* spi0_miso_m1 */
++ <4 RK_PA0 8 &pcfg_pull_up_drv_level_1>,
++ /* spi0_mosi_m1 */
++ <4 RK_PA1 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi0m1_cs0: spi0m1-cs0 {
++ rockchip,pins =
++ /* spi0_cs0_m1 */
++ <4 RK_PB2 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi0m1_cs1: spi0m1-cs1 {
++ rockchip,pins =
++ /* spi0_cs1_m1 */
++ <4 RK_PB1 8 &pcfg_pull_up_drv_level_1>;
++ };
++ /omit-if-no-ref/
++ spi0m2_pins: spi0m2-pins {
++ rockchip,pins =
++ /* spi0_clk_m2 */
++ <1 RK_PB3 8 &pcfg_pull_up_drv_level_1>,
++ /* spi0_miso_m2 */
++ <1 RK_PB1 8 &pcfg_pull_up_drv_level_1>,
++ /* spi0_mosi_m2 */
++ <1 RK_PB2 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi0m2_cs0: spi0m2-cs0 {
++ rockchip,pins =
++ /* spi0_cs0_m2 */
++ <1 RK_PB4 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi0m2_cs1: spi0m2-cs1 {
++ rockchip,pins =
++ /* spi0_cs1_m2 */
++ <1 RK_PB5 8 &pcfg_pull_up_drv_level_1>;
++ };
++ /omit-if-no-ref/
++ spi0m3_pins: spi0m3-pins {
++ rockchip,pins =
++ /* spi0_clk_m3 */
++ <3 RK_PD3 8 &pcfg_pull_up_drv_level_1>,
++ /* spi0_miso_m3 */
++ <3 RK_PD1 8 &pcfg_pull_up_drv_level_1>,
++ /* spi0_mosi_m3 */
++ <3 RK_PD2 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi0m3_cs0: spi0m3-cs0 {
++ rockchip,pins =
++ /* spi0_cs0_m3 */
++ <3 RK_PD4 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi0m3_cs1: spi0m3-cs1 {
++ rockchip,pins =
++ /* spi0_cs1_m3 */
++ <3 RK_PD5 8 &pcfg_pull_up_drv_level_1>;
++ };
++ };
++
++ spi1 {
++ /omit-if-no-ref/
++ spi1m1_pins: spi1m1-pins {
++ rockchip,pins =
++ /* spi1_clk_m1 */
++ <3 RK_PC1 8 &pcfg_pull_up_drv_level_1>,
++ /* spi1_miso_m1 */
++ <3 RK_PC0 8 &pcfg_pull_up_drv_level_1>,
++ /* spi1_mosi_m1 */
++ <3 RK_PB7 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi1m1_cs0: spi1m1-cs0 {
++ rockchip,pins =
++ /* spi1_cs0_m1 */
++ <3 RK_PC2 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi1m1_cs1: spi1m1-cs1 {
++ rockchip,pins =
++ /* spi1_cs1_m1 */
++ <3 RK_PC3 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi1m2_pins: spi1m2-pins {
++ rockchip,pins =
++ /* spi1_clk_m2 */
++ <1 RK_PD2 8 &pcfg_pull_up_drv_level_1>,
++ /* spi1_miso_m2 */
++ <1 RK_PD0 8 &pcfg_pull_up_drv_level_1>,
++ /* spi1_mosi_m2 */
++ <1 RK_PD1 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi1m2_cs0: spi1m2-cs0 {
++ rockchip,pins =
++ /* spi1_cs0_m2 */
++ <1 RK_PD3 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi1m2_cs1: spi1m2-cs1 {
++ rockchip,pins =
++ /* spi1_cs1_m2 */
++ <1 RK_PD5 8 &pcfg_pull_up_drv_level_1>;
++ };
++ };
++
++ spi2 {
++ /omit-if-no-ref/
++ spi2m0_pins: spi2m0-pins {
++ rockchip,pins =
++ /* spi2_clk_m0 */
++ <1 RK_PA6 8 &pcfg_pull_up_drv_level_1>,
++ /* spi2_miso_m0 */
++ <1 RK_PA4 8 &pcfg_pull_up_drv_level_1>,
++ /* spi2_mosi_m0 */
++ <1 RK_PA5 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi2m0_cs0: spi2m0-cs0 {
++ rockchip,pins =
++ /* spi2_cs0_m0 */
++ <1 RK_PA7 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi2m0_cs1: spi2m0-cs1 {
++ rockchip,pins =
++ /* spi2_cs1_m0 */
++ <1 RK_PB0 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi2m1_pins: spi2m1-pins {
++ rockchip,pins =
++ /* spi2_clk_m1 */
++ <4 RK_PA6 8 &pcfg_pull_up_drv_level_1>,
++ /* spi2_miso_m1 */
++ <4 RK_PA4 8 &pcfg_pull_up_drv_level_1>,
++ /* spi2_mosi_m1 */
++ <4 RK_PA5 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi2m1_cs0: spi2m1-cs0 {
++ rockchip,pins =
++ /* spi2_cs0_m1 */
++ <4 RK_PA7 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi2m1_cs1: spi2m1-cs1 {
++ rockchip,pins =
++ /* spi2_cs1_m1 */
++ <4 RK_PB0 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi2m2_pins: spi2m2-pins {
++ rockchip,pins =
++ /* spi2_clk_m2 */
++ <0 RK_PA5 1 &pcfg_pull_up_drv_level_1>,
++ /* spi2_miso_m2 */
++ <0 RK_PB3 1 &pcfg_pull_up_drv_level_1>,
++ /* spi2_mosi_m2 */
++ <0 RK_PA6 1 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi2m2_cs0: spi2m2-cs0 {
++ rockchip,pins =
++ /* spi2_cs0_m2 */
++ <0 RK_PB1 1 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi2m2_cs1: spi2m2-cs1 {
++ rockchip,pins =
++ /* spi2_cs1_m2 */
++ <0 RK_PB0 1 &pcfg_pull_up_drv_level_1>;
++ };
++ };
++
++ spi3 {
++ /omit-if-no-ref/
++ spi3m1_pins: spi3m1-pins {
++ rockchip,pins =
++ /* spi3_clk_m1 */
++ <4 RK_PB7 8 &pcfg_pull_up_drv_level_1>,
++ /* spi3_miso_m1 */
++ <4 RK_PB5 8 &pcfg_pull_up_drv_level_1>,
++ /* spi3_mosi_m1 */
++ <4 RK_PB6 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi3m1_cs0: spi3m1-cs0 {
++ rockchip,pins =
++ /* spi3_cs0_m1 */
++ <4 RK_PC0 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi3m1_cs1: spi3m1-cs1 {
++ rockchip,pins =
++ /* spi3_cs1_m1 */
++ <4 RK_PC1 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi3m2_pins: spi3m2-pins {
++ rockchip,pins =
++ /* spi3_clk_m2 */
++ <0 RK_PD3 8 &pcfg_pull_up_drv_level_1>,
++ /* spi3_miso_m2 */
++ <0 RK_PD0 8 &pcfg_pull_up_drv_level_1>,
++ /* spi3_mosi_m2 */
++ <0 RK_PD2 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi3m2_cs0: spi3m2-cs0 {
++ rockchip,pins =
++ /* spi3_cs0_m2 */
++ <0 RK_PD4 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi3m2_cs1: spi3m2-cs1 {
++ rockchip,pins =
++ /* spi3_cs1_m2 */
++ <0 RK_PD5 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi3m3_pins: spi3m3-pins {
++ rockchip,pins =
++ /* spi3_clk_m3 */
++ <3 RK_PD0 8 &pcfg_pull_up_drv_level_1>,
++ /* spi3_miso_m3 */
++ <3 RK_PC6 8 &pcfg_pull_up_drv_level_1>,
++ /* spi3_mosi_m3 */
++ <3 RK_PC7 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi3m3_cs0: spi3m3-cs0 {
++ rockchip,pins =
++ /* spi3_cs0_m3 */
++ <3 RK_PC4 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi3m3_cs1: spi3m3-cs1 {
++ rockchip,pins =
++ /* spi3_cs1_m3 */
++ <3 RK_PC5 8 &pcfg_pull_up_drv_level_1>;
++ };
++ };
++
++ spi4 {
++ /omit-if-no-ref/
++ spi4m0_pins: spi4m0-pins {
++ rockchip,pins =
++ /* spi4_clk_m0 */
++ <1 RK_PC2 8 &pcfg_pull_up_drv_level_1>,
++ /* spi4_miso_m0 */
++ <1 RK_PC0 8 &pcfg_pull_up_drv_level_1>,
++ /* spi4_mosi_m0 */
++ <1 RK_PC1 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi4m0_cs0: spi4m0-cs0 {
++ rockchip,pins =
++ /* spi4_cs0_m0 */
++ <1 RK_PC3 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi4m0_cs1: spi4m0-cs1 {
++ rockchip,pins =
++ /* spi4_cs1_m0 */
++ <1 RK_PC4 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi4m1_pins: spi4m1-pins {
++ rockchip,pins =
++ /* spi4_clk_m1 */
++ <3 RK_PA2 8 &pcfg_pull_up_drv_level_1>,
++ /* spi4_miso_m1 */
++ <3 RK_PA0 8 &pcfg_pull_up_drv_level_1>,
++ /* spi4_mosi_m1 */
++ <3 RK_PA1 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi4m1_cs0: spi4m1-cs0 {
++ rockchip,pins =
++ /* spi4_cs0_m1 */
++ <3 RK_PA3 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi4m1_cs1: spi4m1-cs1 {
++ rockchip,pins =
++ /* spi4_cs1_m1 */
++ <3 RK_PA4 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi4m2_pins: spi4m2-pins {
++ rockchip,pins =
++ /* spi4_clk_m2 */
++ <1 RK_PA2 8 &pcfg_pull_up_drv_level_1>,
++ /* spi4_miso_m2 */
++ <1 RK_PA0 8 &pcfg_pull_up_drv_level_1>,
++ /* spi4_mosi_m2 */
++ <1 RK_PA1 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi4m2_cs0: spi4m2-cs0 {
++ rockchip,pins =
++ /* spi4_cs0_m2 */
++ <1 RK_PA3 8 &pcfg_pull_up_drv_level_1>;
++ };
++ };
++
++ tsadc {
++ /omit-if-no-ref/
++ tsadcm1_shut: tsadcm1-shut {
++ rockchip,pins =
++ /* tsadcm1_shut */
++ <0 RK_PA2 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ tsadc_shut: tsadc-shut {
++ rockchip,pins =
++ /* tsadc_shut */
++ <0 RK_PA1 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ tsadc_shut_org: tsadc-shut-org {
++ rockchip,pins =
++ /* tsadc_shut_org */
++ <0 RK_PA1 1 &pcfg_pull_none>;
++ };
++ };
++
++ uart0 {
++ /omit-if-no-ref/
++ uart0m0_xfer: uart0m0-xfer {
++ rockchip,pins =
++ /* uart0_rx_m0 */
++ <0 RK_PC4 4 &pcfg_pull_up>,
++ /* uart0_tx_m0 */
++ <0 RK_PC5 4 &pcfg_pull_up>;
++ };
++
++ /omit-if-no-ref/
++ uart0m1_xfer: uart0m1-xfer {
++ rockchip,pins =
++ /* uart0_rx_m1 */
++ <0 RK_PB0 4 &pcfg_pull_up>,
++ /* uart0_tx_m1 */
++ <0 RK_PB1 4 &pcfg_pull_up>;
++ };
++
++ /omit-if-no-ref/
++ uart0m2_xfer: uart0m2-xfer {
++ rockchip,pins =
++ /* uart0_rx_m2 */
++ <4 RK_PA4 10 &pcfg_pull_up>,
++ /* uart0_tx_m2 */
++ <4 RK_PA3 10 &pcfg_pull_up>;
++ };
++
++ /omit-if-no-ref/
++ uart0_ctsn: uart0-ctsn {
++ rockchip,pins =
++ /* uart0_ctsn */
++ <0 RK_PD1 4 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ uart0_rtsn: uart0-rtsn {
++ rockchip,pins =
++ /* uart0_rtsn */
++ <0 RK_PC6 4 &pcfg_pull_none>;
++ };
++ };
++
++ uart1 {
++ /omit-if-no-ref/
++ uart1m1_xfer: uart1m1-xfer {
++ rockchip,pins =
++ /* uart1_rx_m1 */
++ <1 RK_PB7 10 &pcfg_pull_up>,
++ /* uart1_tx_m1 */
++ <1 RK_PB6 10 &pcfg_pull_up>;
++ };
++
++ /omit-if-no-ref/
++ uart1m1_ctsn: uart1m1-ctsn {
++ rockchip,pins =
++ /* uart1m1_ctsn */
++ <1 RK_PD7 10 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ uart1m1_rtsn: uart1m1-rtsn {
++ rockchip,pins =
++ /* uart1m1_rtsn */
++ <1 RK_PD6 10 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ uart1m2_xfer: uart1m2-xfer {
++ rockchip,pins =
++ /* uart1_rx_m2 */
++ <0 RK_PD2 10 &pcfg_pull_up>,
++ /* uart1_tx_m2 */
++ <0 RK_PD1 10 &pcfg_pull_up>;
++ };
++
++ /omit-if-no-ref/
++ uart1m2_ctsn: uart1m2-ctsn {
++ rockchip,pins =
++ /* uart1m2_ctsn */
++ <0 RK_PD0 10 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ uart1m2_rtsn: uart1m2-rtsn {
++ rockchip,pins =
++ /* uart1m2_rtsn */
++ <0 RK_PC7 10 &pcfg_pull_none>;
++ };
++ };
++
++ uart2 {
++ /omit-if-no-ref/
++ uart2m0_xfer: uart2m0-xfer {
++ rockchip,pins =
++ /* uart2_rx_m0 */
++ <0 RK_PB6 10 &pcfg_pull_up>,
++ /* uart2_tx_m0 */
++ <0 RK_PB5 10 &pcfg_pull_up>;
++ };
++
++ /omit-if-no-ref/
++ uart2m1_xfer: uart2m1-xfer {
++ rockchip,pins =
++ /* uart2_rx_m1 */
++ <4 RK_PD1 10 &pcfg_pull_up>,
++ /* uart2_tx_m1 */
++ <4 RK_PD0 10 &pcfg_pull_up>;
++ };
++
++ /omit-if-no-ref/
++ uart2m2_xfer: uart2m2-xfer {
++ rockchip,pins =
++ /* uart2_rx_m2 */
++ <3 RK_PB2 10 &pcfg_pull_up>,
++ /* uart2_tx_m2 */
++ <3 RK_PB1 10 &pcfg_pull_up>;
++ };
++
++ /omit-if-no-ref/
++ uart2_ctsn: uart2-ctsn {
++ rockchip,pins =
++ /* uart2_ctsn */
++ <3 RK_PB4 10 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ uart2_rtsn: uart2-rtsn {
++ rockchip,pins =
++ /* uart2_rtsn */
++ <3 RK_PB3 10 &pcfg_pull_none>;
++ };
++ };
++
++ uart3 {
++ /omit-if-no-ref/
++ uart3m0_xfer: uart3m0-xfer {
++ rockchip,pins =
++ /* uart3_rx_m0 */
++ <1 RK_PC0 10 &pcfg_pull_up>,
++ /* uart3_tx_m0 */
++ <1 RK_PC1 10 &pcfg_pull_up>;
++ };
++
++ /omit-if-no-ref/
++ uart3m1_xfer: uart3m1-xfer {
++ rockchip,pins =
++ /* uart3_rx_m1 */
++ <3 RK_PB6 10 &pcfg_pull_up>,
++ /* uart3_tx_m1 */
++ <3 RK_PB5 10 &pcfg_pull_up>;
++ };
++
++ /omit-if-no-ref/
++ uart3m2_xfer: uart3m2-xfer {
++ rockchip,pins =
++ /* uart3_rx_m2 */
++ <4 RK_PA6 10 &pcfg_pull_up>,
++ /* uart3_tx_m2 */
++ <4 RK_PA5 10 &pcfg_pull_up>;
++ };
++
++ /omit-if-no-ref/
++ uart3_ctsn: uart3-ctsn {
++ rockchip,pins =
++ /* uart3_ctsn */
++ <1 RK_PC3 10 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ uart3_rtsn: uart3-rtsn {
++ rockchip,pins =
++ /* uart3_rtsn */
++ <1 RK_PC2 10 &pcfg_pull_none>;
++ };
++ };
++
++ uart4 {
++ /omit-if-no-ref/
++ uart4m0_xfer: uart4m0-xfer {
++ rockchip,pins =
++ /* uart4_rx_m0 */
++ <1 RK_PD3 10 &pcfg_pull_up>,
++ /* uart4_tx_m0 */
++ <1 RK_PD2 10 &pcfg_pull_up>;
++ };
++
++ /omit-if-no-ref/
++ uart4m1_xfer: uart4m1-xfer {
++ rockchip,pins =
++ /* uart4_rx_m1 */
++ <3 RK_PD0 10 &pcfg_pull_up>,
++ /* uart4_tx_m1 */
++ <3 RK_PD1 10 &pcfg_pull_up>;
++ };
++
++ /omit-if-no-ref/
++ uart4m2_xfer: uart4m2-xfer {
++ rockchip,pins =
++ /* uart4_rx_m2 */
++ <1 RK_PB2 10 &pcfg_pull_up>,
++ /* uart4_tx_m2 */
++ <1 RK_PB3 10 &pcfg_pull_up>;
++ };
++
++ /omit-if-no-ref/
++ uart4_ctsn: uart4-ctsn {
++ rockchip,pins =
++ /* uart4_ctsn */
++ <1 RK_PC7 10 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ uart4_rtsn: uart4-rtsn {
++ rockchip,pins =
++ /* uart4_rtsn */
++ <1 RK_PC5 10 &pcfg_pull_none>;
++ };
++ };
++
++ uart5 {
++ /omit-if-no-ref/
++ uart5m0_xfer: uart5m0-xfer {
++ rockchip,pins =
++ /* uart5_rx_m0 */
++ <4 RK_PD4 10 &pcfg_pull_up>,
++ /* uart5_tx_m0 */
++ <4 RK_PD5 10 &pcfg_pull_up>;
++ };
++
++ /omit-if-no-ref/
++ uart5m0_ctsn: uart5m0-ctsn {
++ rockchip,pins =
++ /* uart5m0_ctsn */
++ <4 RK_PD2 10 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ uart5m0_rtsn: uart5m0-rtsn {
++ rockchip,pins =
++ /* uart5m0_rtsn */
++ <4 RK_PD3 10 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ uart5m1_xfer: uart5m1-xfer {
++ rockchip,pins =
++ /* uart5_rx_m1 */
++ <3 RK_PC5 10 &pcfg_pull_up>,
++ /* uart5_tx_m1 */
++ <3 RK_PC4 10 &pcfg_pull_up>;
++ };
++
++ /omit-if-no-ref/
++ uart5m1_ctsn: uart5m1-ctsn {
++ rockchip,pins =
++ /* uart5m1_ctsn */
++ <2 RK_PA2 10 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ uart5m1_rtsn: uart5m1-rtsn {
++ rockchip,pins =
++ /* uart5m1_rtsn */
++ <2 RK_PA3 10 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ uart5m2_xfer: uart5m2-xfer {
++ rockchip,pins =
++ /* uart5_rx_m2 */
++ <2 RK_PD4 10 &pcfg_pull_up>,
++ /* uart5_tx_m2 */
++ <2 RK_PD5 10 &pcfg_pull_up>;
++ };
++ };
++
++ uart6 {
++ /omit-if-no-ref/
++ uart6m1_xfer: uart6m1-xfer {
++ rockchip,pins =
++ /* uart6_rx_m1 */
++ <1 RK_PA0 10 &pcfg_pull_up>,
++ /* uart6_tx_m1 */
++ <1 RK_PA1 10 &pcfg_pull_up>;
++ };
++
++ /omit-if-no-ref/
++ uart6m1_ctsn: uart6m1-ctsn {
++ rockchip,pins =
++ /* uart6m1_ctsn */
++ <1 RK_PA3 10 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ uart6m1_rtsn: uart6m1-rtsn {
++ rockchip,pins =
++ /* uart6m1_rtsn */
++ <1 RK_PA2 10 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ uart6m2_xfer: uart6m2-xfer {
++ rockchip,pins =
++ /* uart6_rx_m2 */
++ <1 RK_PD1 10 &pcfg_pull_up>,
++ /* uart6_tx_m2 */
++ <1 RK_PD0 10 &pcfg_pull_up>;
++ };
++ };
++
++ uart7 {
++ /omit-if-no-ref/
++ uart7m1_xfer: uart7m1-xfer {
++ rockchip,pins =
++ /* uart7_rx_m1 */
++ <3 RK_PC1 10 &pcfg_pull_up>,
++ /* uart7_tx_m1 */
++ <3 RK_PC0 10 &pcfg_pull_up>;
++ };
++
++ /omit-if-no-ref/
++ uart7m1_ctsn: uart7m1-ctsn {
++ rockchip,pins =
++ /* uart7m1_ctsn */
++ <3 RK_PC3 10 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ uart7m1_rtsn: uart7m1-rtsn {
++ rockchip,pins =
++ /* uart7m1_rtsn */
++ <3 RK_PC2 10 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ uart7m2_xfer: uart7m2-xfer {
++ rockchip,pins =
++ /* uart7_rx_m2 */
++ <1 RK_PB4 10 &pcfg_pull_up>,
++ /* uart7_tx_m2 */
++ <1 RK_PB5 10 &pcfg_pull_up>;
++ };
++ };
++
++ uart8 {
++ /omit-if-no-ref/
++ uart8m0_xfer: uart8m0-xfer {
++ rockchip,pins =
++ /* uart8_rx_m0 */
++ <4 RK_PB1 10 &pcfg_pull_up>,
++ /* uart8_tx_m0 */
++ <4 RK_PB0 10 &pcfg_pull_up>;
++ };
++
++ /omit-if-no-ref/
++ uart8m0_ctsn: uart8m0-ctsn {
++ rockchip,pins =
++ /* uart8m0_ctsn */
++ <4 RK_PB3 10 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ uart8m0_rtsn: uart8m0-rtsn {
++ rockchip,pins =
++ /* uart8m0_rtsn */
++ <4 RK_PB2 10 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ uart8m1_xfer: uart8m1-xfer {
++ rockchip,pins =
++ /* uart8_rx_m1 */
++ <3 RK_PA3 10 &pcfg_pull_up>,
++ /* uart8_tx_m1 */
++ <3 RK_PA2 10 &pcfg_pull_up>;
++ };
++
++ /omit-if-no-ref/
++ uart8m1_ctsn: uart8m1-ctsn {
++ rockchip,pins =
++ /* uart8m1_ctsn */
++ <3 RK_PA5 10 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ uart8m1_rtsn: uart8m1-rtsn {
++ rockchip,pins =
++ /* uart8m1_rtsn */
++ <3 RK_PA4 10 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ uart8_xfer: uart8-xfer {
++ rockchip,pins =
++ /* uart8_rx_ */
++ <4 RK_PB1 10 &pcfg_pull_up>;
++ };
++ };
++
++ uart9 {
++ /omit-if-no-ref/
++ uart9m0_xfer: uart9m0-xfer {
++ rockchip,pins =
++ /* uart9_rx_m0 */
++ <2 RK_PC4 10 &pcfg_pull_up>,
++ /* uart9_tx_m0 */
++ <2 RK_PC2 10 &pcfg_pull_up>;
++ };
++
++ /omit-if-no-ref/
++ uart9m1_xfer: uart9m1-xfer {
++ rockchip,pins =
++ /* uart9_rx_m1 */
++ <4 RK_PB5 10 &pcfg_pull_up>,
++ /* uart9_tx_m1 */
++ <4 RK_PB4 10 &pcfg_pull_up>;
++ };
++
++ /omit-if-no-ref/
++ uart9m1_ctsn: uart9m1-ctsn {
++ rockchip,pins =
++ /* uart9m1_ctsn */
++ <4 RK_PA1 10 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ uart9m1_rtsn: uart9m1-rtsn {
++ rockchip,pins =
++ /* uart9m1_rtsn */
++ <4 RK_PA0 10 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ uart9m2_xfer: uart9m2-xfer {
++ rockchip,pins =
++ /* uart9_rx_m2 */
++ <3 RK_PD4 10 &pcfg_pull_up>,
++ /* uart9_tx_m2 */
++ <3 RK_PD5 10 &pcfg_pull_up>;
++ };
++
++ /omit-if-no-ref/
++ uart9m2_ctsn: uart9m2-ctsn {
++ rockchip,pins =
++ /* uart9m2_ctsn */
++ <3 RK_PD3 10 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ uart9m2_rtsn: uart9m2-rtsn {
++ rockchip,pins =
++ /* uart9m2_rtsn */
++ <3 RK_PD2 10 &pcfg_pull_none>;
++ };
++ };
++
++ vop {
++ /omit-if-no-ref/
++ vop_pins: vop-pins {
++ rockchip,pins =
++ /* vop_post_empty */
++ <1 RK_PA2 1 &pcfg_pull_none>;
++ };
++ };
++};
++
++/*
++ * This part is edited handly.
++ */
++&pinctrl {
++ bt656 {
++ /omit-if-no-ref/
++ bt656_pins: bt656-pins {
++ rockchip,pins =
++ /* bt1120_clkout */
++ <4 RK_PB0 2 &pcfg_pull_none_drv_level_2>,
++ /* bt1120_d0 */
++ <4 RK_PA0 2 &pcfg_pull_none_drv_level_2>,
++ /* bt1120_d1 */
++ <4 RK_PA1 2 &pcfg_pull_none_drv_level_2>,
++ /* bt1120_d2 */
++ <4 RK_PA2 2 &pcfg_pull_none_drv_level_2>,
++ /* bt1120_d3 */
++ <4 RK_PA3 2 &pcfg_pull_none_drv_level_2>,
++ /* bt1120_d4 */
++ <4 RK_PA4 2 &pcfg_pull_none_drv_level_2>,
++ /* bt1120_d5 */
++ <4 RK_PA5 2 &pcfg_pull_none_drv_level_2>,
++ /* bt1120_d6 */
++ <4 RK_PA6 2 &pcfg_pull_none_drv_level_2>,
++ /* bt1120_d7 */
++ <4 RK_PA7 2 &pcfg_pull_none_drv_level_2>;
++ };
++ };
++
++ gpio-func {
++ /omit-if-no-ref/
++ tsadc_gpio_func: tsadc-gpio-func {
++ rockchip,pins =
++ <0 RK_PA1 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
++};
+--- /dev/null
++++ b/arch/arm64/boot/dts/rockchip/rk3588-extra-pinctrl.dtsi
+@@ -0,0 +1,516 @@
++// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
++/*
++ * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
++ */
++
++#include <dt-bindings/pinctrl/rockchip.h>
++#include "rockchip-pinconf.dtsi"
++
++/*
++ * This file is auto generated by pin2dts tool, please keep these code
++ * by adding changes at end of this file.
++ */
++&pinctrl {
++ clk32k {
++ /omit-if-no-ref/
++ clk32k_out1: clk32k-out1 {
++ rockchip,pins =
++ /* clk32k_out1 */
++ <2 RK_PC5 1 &pcfg_pull_none>;
++ };
++
++ };
++
++ eth0 {
++ /omit-if-no-ref/
++ eth0_pins: eth0-pins {
++ rockchip,pins =
++ /* eth0_refclko_25m */
++ <2 RK_PC3 1 &pcfg_pull_none>;
++ };
++
++ };
++
++ fspi {
++ /omit-if-no-ref/
++ fspim1_pins: fspim1-pins {
++ rockchip,pins =
++ /* fspi_clk_m1 */
++ <2 RK_PB3 3 &pcfg_pull_up_drv_level_2>,
++ /* fspi_cs0n_m1 */
++ <2 RK_PB4 3 &pcfg_pull_up_drv_level_2>,
++ /* fspi_d0_m1 */
++ <2 RK_PA6 3 &pcfg_pull_up_drv_level_2>,
++ /* fspi_d1_m1 */
++ <2 RK_PA7 3 &pcfg_pull_up_drv_level_2>,
++ /* fspi_d2_m1 */
++ <2 RK_PB0 3 &pcfg_pull_up_drv_level_2>,
++ /* fspi_d3_m1 */
++ <2 RK_PB1 3 &pcfg_pull_up_drv_level_2>;
++ };
++
++ /omit-if-no-ref/
++ fspim1_cs1: fspim1-cs1 {
++ rockchip,pins =
++ /* fspi_cs1n_m1 */
++ <2 RK_PB5 3 &pcfg_pull_up_drv_level_2>;
++ };
++ };
++
++ gmac0 {
++ /omit-if-no-ref/
++ gmac0_miim: gmac0-miim {
++ rockchip,pins =
++ /* gmac0_mdc */
++ <4 RK_PC4 1 &pcfg_pull_none>,
++ /* gmac0_mdio */
++ <4 RK_PC5 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ gmac0_clkinout: gmac0-clkinout {
++ rockchip,pins =
++ /* gmac0_mclkinout */
++ <4 RK_PC3 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ gmac0_rx_bus2: gmac0-rx-bus2 {
++ rockchip,pins =
++ /* gmac0_rxd0 */
++ <2 RK_PC1 1 &pcfg_pull_none>,
++ /* gmac0_rxd1 */
++ <2 RK_PC2 1 &pcfg_pull_none>,
++ /* gmac0_rxdv_crs */
++ <4 RK_PC2 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ gmac0_tx_bus2: gmac0-tx-bus2 {
++ rockchip,pins =
++ /* gmac0_txd0 */
++ <2 RK_PB6 1 &pcfg_pull_none>,
++ /* gmac0_txd1 */
++ <2 RK_PB7 1 &pcfg_pull_none>,
++ /* gmac0_txen */
++ <2 RK_PC0 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ gmac0_rgmii_clk: gmac0-rgmii-clk {
++ rockchip,pins =
++ /* gmac0_rxclk */
++ <2 RK_PB0 1 &pcfg_pull_none>,
++ /* gmac0_txclk */
++ <2 RK_PB3 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ gmac0_rgmii_bus: gmac0-rgmii-bus {
++ rockchip,pins =
++ /* gmac0_rxd2 */
++ <2 RK_PA6 1 &pcfg_pull_none>,
++ /* gmac0_rxd3 */
++ <2 RK_PA7 1 &pcfg_pull_none>,
++ /* gmac0_txd2 */
++ <2 RK_PB1 1 &pcfg_pull_none>,
++ /* gmac0_txd3 */
++ <2 RK_PB2 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ gmac0_ppsclk: gmac0-ppsclk {
++ rockchip,pins =
++ /* gmac0_ppsclk */
++ <2 RK_PC4 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ gmac0_ppstring: gmac0-ppstring {
++ rockchip,pins =
++ /* gmac0_ppstring */
++ <2 RK_PB5 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ gmac0_ptp_refclk: gmac0-ptp-refclk {
++ rockchip,pins =
++ /* gmac0_ptp_refclk */
++ <2 RK_PB4 1 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ gmac0_txer: gmac0-txer {
++ rockchip,pins =
++ /* gmac0_txer */
++ <4 RK_PC6 1 &pcfg_pull_none>;
++ };
++
++ };
++
++ hdmi {
++ /omit-if-no-ref/
++ hdmim0_tx1_cec: hdmim0-tx1-cec {
++ rockchip,pins =
++ /* hdmim0_tx1_cec */
++ <2 RK_PC4 4 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmim0_tx1_scl: hdmim0-tx1-scl {
++ rockchip,pins =
++ /* hdmim0_tx1_scl */
++ <2 RK_PB5 4 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ hdmim0_tx1_sda: hdmim0-tx1-sda {
++ rockchip,pins =
++ /* hdmim0_tx1_sda */
++ <2 RK_PB4 4 &pcfg_pull_none>;
++ };
++ };
++
++ i2c0 {
++ /omit-if-no-ref/
++ i2c0m1_xfer: i2c0m1-xfer {
++ rockchip,pins =
++ /* i2c0_scl_m1 */
++ <4 RK_PC5 9 &pcfg_pull_none_smt>,
++ /* i2c0_sda_m1 */
++ <4 RK_PC6 9 &pcfg_pull_none_smt>;
++ };
++ };
++
++ i2c2 {
++ /omit-if-no-ref/
++ i2c2m1_xfer: i2c2m1-xfer {
++ rockchip,pins =
++ /* i2c2_scl_m1 */
++ <2 RK_PC1 9 &pcfg_pull_none_smt>,
++ /* i2c2_sda_m1 */
++ <2 RK_PC0 9 &pcfg_pull_none_smt>;
++ };
++ };
++
++ i2c3 {
++ /omit-if-no-ref/
++ i2c3m3_xfer: i2c3m3-xfer {
++ rockchip,pins =
++ /* i2c3_scl_m3 */
++ <2 RK_PB2 9 &pcfg_pull_none_smt>,
++ /* i2c3_sda_m3 */
++ <2 RK_PB3 9 &pcfg_pull_none_smt>;
++ };
++ };
++
++ i2c4 {
++ /omit-if-no-ref/
++ i2c4m1_xfer: i2c4m1-xfer {
++ rockchip,pins =
++ /* i2c4_scl_m1 */
++ <2 RK_PB5 9 &pcfg_pull_none_smt>,
++ /* i2c4_sda_m1 */
++ <2 RK_PB4 9 &pcfg_pull_none_smt>;
++ };
++ };
++
++ i2c5 {
++ /omit-if-no-ref/
++ i2c5m4_xfer: i2c5m4-xfer {
++ rockchip,pins =
++ /* i2c5_scl_m4 */
++ <2 RK_PB6 9 &pcfg_pull_none_smt>,
++ /* i2c5_sda_m4 */
++ <2 RK_PB7 9 &pcfg_pull_none_smt>;
++ };
++ };
++
++ i2c6 {
++ /omit-if-no-ref/
++ i2c6m2_xfer: i2c6m2-xfer {
++ rockchip,pins =
++ /* i2c6_scl_m2 */
++ <2 RK_PC3 9 &pcfg_pull_none_smt>,
++ /* i2c6_sda_m2 */
++ <2 RK_PC2 9 &pcfg_pull_none_smt>;
++ };
++ };
++
++ i2c7 {
++ /omit-if-no-ref/
++ i2c7m1_xfer: i2c7m1-xfer {
++ rockchip,pins =
++ /* i2c7_scl_m1 */
++ <4 RK_PC3 9 &pcfg_pull_none_smt>,
++ /* i2c7_sda_m1 */
++ <4 RK_PC4 9 &pcfg_pull_none_smt>;
++ };
++ };
++
++ i2c8 {
++ /omit-if-no-ref/
++ i2c8m1_xfer: i2c8m1-xfer {
++ rockchip,pins =
++ /* i2c8_scl_m1 */
++ <2 RK_PB0 9 &pcfg_pull_none_smt>,
++ /* i2c8_sda_m1 */
++ <2 RK_PB1 9 &pcfg_pull_none_smt>;
++ };
++ };
++
++ i2s2 {
++ /omit-if-no-ref/
++ i2s2m0_lrck: i2s2m0-lrck {
++ rockchip,pins =
++ /* i2s2m0_lrck */
++ <2 RK_PC0 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s2m0_mclk: i2s2m0-mclk {
++ rockchip,pins =
++ /* i2s2m0_mclk */
++ <2 RK_PB6 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s2m0_sclk: i2s2m0-sclk {
++ rockchip,pins =
++ /* i2s2m0_sclk */
++ <2 RK_PB7 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s2m0_sdi: i2s2m0-sdi {
++ rockchip,pins =
++ /* i2s2m0_sdi */
++ <2 RK_PC3 2 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ i2s2m0_sdo: i2s2m0-sdo {
++ rockchip,pins =
++ /* i2s2m0_sdo */
++ <4 RK_PC3 2 &pcfg_pull_none>;
++ };
++ };
++
++ pwm2 {
++ /omit-if-no-ref/
++ pwm2m2_pins: pwm2m2-pins {
++ rockchip,pins =
++ /* pwm2_m2 */
++ <4 RK_PC2 11 &pcfg_pull_none>;
++ };
++ };
++
++ pwm4 {
++ /omit-if-no-ref/
++ pwm4m1_pins: pwm4m1-pins {
++ rockchip,pins =
++ /* pwm4_m1 */
++ <4 RK_PC3 11 &pcfg_pull_none>;
++ };
++ };
++
++ pwm5 {
++ /omit-if-no-ref/
++ pwm5m2_pins: pwm5m2-pins {
++ rockchip,pins =
++ /* pwm5_m2 */
++ <4 RK_PC4 11 &pcfg_pull_none>;
++ };
++ };
++
++ pwm6 {
++ /omit-if-no-ref/
++ pwm6m2_pins: pwm6m2-pins {
++ rockchip,pins =
++ /* pwm6_m2 */
++ <4 RK_PC5 11 &pcfg_pull_none>;
++ };
++ };
++
++ pwm7 {
++ /omit-if-no-ref/
++ pwm7m3_pins: pwm7m3-pins {
++ rockchip,pins =
++ /* pwm7_ir_m3 */
++ <4 RK_PC6 11 &pcfg_pull_none>;
++ };
++ };
++
++ sdio {
++ /omit-if-no-ref/
++ sdiom0_pins: sdiom0-pins {
++ rockchip,pins =
++ /* sdio_clk_m0 */
++ <2 RK_PB3 2 &pcfg_pull_none>,
++ /* sdio_cmd_m0 */
++ <2 RK_PB2 2 &pcfg_pull_none>,
++ /* sdio_d0_m0 */
++ <2 RK_PA6 2 &pcfg_pull_none>,
++ /* sdio_d1_m0 */
++ <2 RK_PA7 2 &pcfg_pull_none>,
++ /* sdio_d2_m0 */
++ <2 RK_PB0 2 &pcfg_pull_none>,
++ /* sdio_d3_m0 */
++ <2 RK_PB1 2 &pcfg_pull_none>;
++ };
++ };
++
++ spi1 {
++ /omit-if-no-ref/
++ spi1m0_pins: spi1m0-pins {
++ rockchip,pins =
++ /* spi1_clk_m0 */
++ <2 RK_PC0 8 &pcfg_pull_up_drv_level_1>,
++ /* spi1_miso_m0 */
++ <2 RK_PC1 8 &pcfg_pull_up_drv_level_1>,
++ /* spi1_mosi_m0 */
++ <2 RK_PC2 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi1m0_cs0: spi1m0-cs0 {
++ rockchip,pins =
++ /* spi1_cs0_m0 */
++ <2 RK_PC3 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi1m0_cs1: spi1m0-cs1 {
++ rockchip,pins =
++ /* spi1_cs1_m0 */
++ <2 RK_PC4 8 &pcfg_pull_up_drv_level_1>;
++ };
++ };
++
++ spi3 {
++ /omit-if-no-ref/
++ spi3m0_pins: spi3m0-pins {
++ rockchip,pins =
++ /* spi3_clk_m0 */
++ <4 RK_PC6 8 &pcfg_pull_up_drv_level_1>,
++ /* spi3_miso_m0 */
++ <4 RK_PC4 8 &pcfg_pull_up_drv_level_1>,
++ /* spi3_mosi_m0 */
++ <4 RK_PC5 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi3m0_cs0: spi3m0-cs0 {
++ rockchip,pins =
++ /* spi3_cs0_m0 */
++ <4 RK_PC2 8 &pcfg_pull_up_drv_level_1>;
++ };
++
++ /omit-if-no-ref/
++ spi3m0_cs1: spi3m0-cs1 {
++ rockchip,pins =
++ /* spi3_cs1_m0 */
++ <4 RK_PC3 8 &pcfg_pull_up_drv_level_1>;
++ };
++ };
++
++ uart1 {
++ /omit-if-no-ref/
++ uart1m0_xfer: uart1m0-xfer {
++ rockchip,pins =
++ /* uart1_rx_m0 */
++ <2 RK_PB6 10 &pcfg_pull_up>,
++ /* uart1_tx_m0 */
++ <2 RK_PB7 10 &pcfg_pull_up>;
++ };
++
++ /omit-if-no-ref/
++ uart1m0_ctsn: uart1m0-ctsn {
++ rockchip,pins =
++ /* uart1m0_ctsn */
++ <2 RK_PC1 10 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ uart1m0_rtsn: uart1m0-rtsn {
++ rockchip,pins =
++ /* uart1m0_rtsn */
++ <2 RK_PC0 10 &pcfg_pull_none>;
++ };
++ };
++
++ uart6 {
++ /omit-if-no-ref/
++ uart6m0_xfer: uart6m0-xfer {
++ rockchip,pins =
++ /* uart6_rx_m0 */
++ <2 RK_PA6 10 &pcfg_pull_up>,
++ /* uart6_tx_m0 */
++ <2 RK_PA7 10 &pcfg_pull_up>;
++ };
++
++ /omit-if-no-ref/
++ uart6m0_ctsn: uart6m0-ctsn {
++ rockchip,pins =
++ /* uart6m0_ctsn */
++ <2 RK_PB1 10 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ uart6m0_rtsn: uart6m0-rtsn {
++ rockchip,pins =
++ /* uart6m0_rtsn */
++ <2 RK_PB0 10 &pcfg_pull_none>;
++ };
++ };
++
++ uart7 {
++ /omit-if-no-ref/
++ uart7m0_xfer: uart7m0-xfer {
++ rockchip,pins =
++ /* uart7_rx_m0 */
++ <2 RK_PB4 10 &pcfg_pull_up>,
++ /* uart7_tx_m0 */
++ <2 RK_PB5 10 &pcfg_pull_up>;
++ };
++
++ /omit-if-no-ref/
++ uart7m0_ctsn: uart7m0-ctsn {
++ rockchip,pins =
++ /* uart7m0_ctsn */
++ <4 RK_PC6 10 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ uart7m0_rtsn: uart7m0-rtsn {
++ rockchip,pins =
++ /* uart7m0_rtsn */
++ <4 RK_PC2 10 &pcfg_pull_none>;
++ };
++ };
++
++ uart9 {
++ /omit-if-no-ref/
++ uart9m0_xfer: uart9m0-xfer {
++ rockchip,pins =
++ /* uart9_rx_m0 */
++ <2 RK_PC4 10 &pcfg_pull_up>,
++ /* uart9_tx_m0 */
++ <2 RK_PC2 10 &pcfg_pull_up>;
++ };
++
++ /omit-if-no-ref/
++ uart9m0_ctsn: uart9m0-ctsn {
++ rockchip,pins =
++ /* uart9m0_ctsn */
++ <4 RK_PC5 10 &pcfg_pull_none>;
++ };
++
++ /omit-if-no-ref/
++ uart9m0_rtsn: uart9m0-rtsn {
++ rockchip,pins =
++ /* uart9m0_rtsn */
++ <4 RK_PC4 10 &pcfg_pull_none>;
++ };
++ };
++};
+--- a/arch/arm64/boot/dts/rockchip/rk3588-pinctrl.dtsi
++++ /dev/null
+@@ -1,516 +0,0 @@
+-// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+-/*
+- * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
+- */
+-
+-#include <dt-bindings/pinctrl/rockchip.h>
+-#include "rockchip-pinconf.dtsi"
+-
+-/*
+- * This file is auto generated by pin2dts tool, please keep these code
+- * by adding changes at end of this file.
+- */
+-&pinctrl {
+- clk32k {
+- /omit-if-no-ref/
+- clk32k_out1: clk32k-out1 {
+- rockchip,pins =
+- /* clk32k_out1 */
+- <2 RK_PC5 1 &pcfg_pull_none>;
+- };
+-
+- };
+-
+- eth0 {
+- /omit-if-no-ref/
+- eth0_pins: eth0-pins {
+- rockchip,pins =
+- /* eth0_refclko_25m */
+- <2 RK_PC3 1 &pcfg_pull_none>;
+- };
+-
+- };
+-
+- fspi {
+- /omit-if-no-ref/
+- fspim1_pins: fspim1-pins {
+- rockchip,pins =
+- /* fspi_clk_m1 */
+- <2 RK_PB3 3 &pcfg_pull_up_drv_level_2>,
+- /* fspi_cs0n_m1 */
+- <2 RK_PB4 3 &pcfg_pull_up_drv_level_2>,
+- /* fspi_d0_m1 */
+- <2 RK_PA6 3 &pcfg_pull_up_drv_level_2>,
+- /* fspi_d1_m1 */
+- <2 RK_PA7 3 &pcfg_pull_up_drv_level_2>,
+- /* fspi_d2_m1 */
+- <2 RK_PB0 3 &pcfg_pull_up_drv_level_2>,
+- /* fspi_d3_m1 */
+- <2 RK_PB1 3 &pcfg_pull_up_drv_level_2>;
+- };
+-
+- /omit-if-no-ref/
+- fspim1_cs1: fspim1-cs1 {
+- rockchip,pins =
+- /* fspi_cs1n_m1 */
+- <2 RK_PB5 3 &pcfg_pull_up_drv_level_2>;
+- };
+- };
+-
+- gmac0 {
+- /omit-if-no-ref/
+- gmac0_miim: gmac0-miim {
+- rockchip,pins =
+- /* gmac0_mdc */
+- <4 RK_PC4 1 &pcfg_pull_none>,
+- /* gmac0_mdio */
+- <4 RK_PC5 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- gmac0_clkinout: gmac0-clkinout {
+- rockchip,pins =
+- /* gmac0_mclkinout */
+- <4 RK_PC3 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- gmac0_rx_bus2: gmac0-rx-bus2 {
+- rockchip,pins =
+- /* gmac0_rxd0 */
+- <2 RK_PC1 1 &pcfg_pull_none>,
+- /* gmac0_rxd1 */
+- <2 RK_PC2 1 &pcfg_pull_none>,
+- /* gmac0_rxdv_crs */
+- <4 RK_PC2 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- gmac0_tx_bus2: gmac0-tx-bus2 {
+- rockchip,pins =
+- /* gmac0_txd0 */
+- <2 RK_PB6 1 &pcfg_pull_none>,
+- /* gmac0_txd1 */
+- <2 RK_PB7 1 &pcfg_pull_none>,
+- /* gmac0_txen */
+- <2 RK_PC0 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- gmac0_rgmii_clk: gmac0-rgmii-clk {
+- rockchip,pins =
+- /* gmac0_rxclk */
+- <2 RK_PB0 1 &pcfg_pull_none>,
+- /* gmac0_txclk */
+- <2 RK_PB3 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- gmac0_rgmii_bus: gmac0-rgmii-bus {
+- rockchip,pins =
+- /* gmac0_rxd2 */
+- <2 RK_PA6 1 &pcfg_pull_none>,
+- /* gmac0_rxd3 */
+- <2 RK_PA7 1 &pcfg_pull_none>,
+- /* gmac0_txd2 */
+- <2 RK_PB1 1 &pcfg_pull_none>,
+- /* gmac0_txd3 */
+- <2 RK_PB2 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- gmac0_ppsclk: gmac0-ppsclk {
+- rockchip,pins =
+- /* gmac0_ppsclk */
+- <2 RK_PC4 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- gmac0_ppstring: gmac0-ppstring {
+- rockchip,pins =
+- /* gmac0_ppstring */
+- <2 RK_PB5 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- gmac0_ptp_refclk: gmac0-ptp-refclk {
+- rockchip,pins =
+- /* gmac0_ptp_refclk */
+- <2 RK_PB4 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- gmac0_txer: gmac0-txer {
+- rockchip,pins =
+- /* gmac0_txer */
+- <4 RK_PC6 1 &pcfg_pull_none>;
+- };
+-
+- };
+-
+- hdmi {
+- /omit-if-no-ref/
+- hdmim0_tx1_cec: hdmim0-tx1-cec {
+- rockchip,pins =
+- /* hdmim0_tx1_cec */
+- <2 RK_PC4 4 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmim0_tx1_scl: hdmim0-tx1-scl {
+- rockchip,pins =
+- /* hdmim0_tx1_scl */
+- <2 RK_PB5 4 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmim0_tx1_sda: hdmim0-tx1-sda {
+- rockchip,pins =
+- /* hdmim0_tx1_sda */
+- <2 RK_PB4 4 &pcfg_pull_none>;
+- };
+- };
+-
+- i2c0 {
+- /omit-if-no-ref/
+- i2c0m1_xfer: i2c0m1-xfer {
+- rockchip,pins =
+- /* i2c0_scl_m1 */
+- <4 RK_PC5 9 &pcfg_pull_none_smt>,
+- /* i2c0_sda_m1 */
+- <4 RK_PC6 9 &pcfg_pull_none_smt>;
+- };
+- };
+-
+- i2c2 {
+- /omit-if-no-ref/
+- i2c2m1_xfer: i2c2m1-xfer {
+- rockchip,pins =
+- /* i2c2_scl_m1 */
+- <2 RK_PC1 9 &pcfg_pull_none_smt>,
+- /* i2c2_sda_m1 */
+- <2 RK_PC0 9 &pcfg_pull_none_smt>;
+- };
+- };
+-
+- i2c3 {
+- /omit-if-no-ref/
+- i2c3m3_xfer: i2c3m3-xfer {
+- rockchip,pins =
+- /* i2c3_scl_m3 */
+- <2 RK_PB2 9 &pcfg_pull_none_smt>,
+- /* i2c3_sda_m3 */
+- <2 RK_PB3 9 &pcfg_pull_none_smt>;
+- };
+- };
+-
+- i2c4 {
+- /omit-if-no-ref/
+- i2c4m1_xfer: i2c4m1-xfer {
+- rockchip,pins =
+- /* i2c4_scl_m1 */
+- <2 RK_PB5 9 &pcfg_pull_none_smt>,
+- /* i2c4_sda_m1 */
+- <2 RK_PB4 9 &pcfg_pull_none_smt>;
+- };
+- };
+-
+- i2c5 {
+- /omit-if-no-ref/
+- i2c5m4_xfer: i2c5m4-xfer {
+- rockchip,pins =
+- /* i2c5_scl_m4 */
+- <2 RK_PB6 9 &pcfg_pull_none_smt>,
+- /* i2c5_sda_m4 */
+- <2 RK_PB7 9 &pcfg_pull_none_smt>;
+- };
+- };
+-
+- i2c6 {
+- /omit-if-no-ref/
+- i2c6m2_xfer: i2c6m2-xfer {
+- rockchip,pins =
+- /* i2c6_scl_m2 */
+- <2 RK_PC3 9 &pcfg_pull_none_smt>,
+- /* i2c6_sda_m2 */
+- <2 RK_PC2 9 &pcfg_pull_none_smt>;
+- };
+- };
+-
+- i2c7 {
+- /omit-if-no-ref/
+- i2c7m1_xfer: i2c7m1-xfer {
+- rockchip,pins =
+- /* i2c7_scl_m1 */
+- <4 RK_PC3 9 &pcfg_pull_none_smt>,
+- /* i2c7_sda_m1 */
+- <4 RK_PC4 9 &pcfg_pull_none_smt>;
+- };
+- };
+-
+- i2c8 {
+- /omit-if-no-ref/
+- i2c8m1_xfer: i2c8m1-xfer {
+- rockchip,pins =
+- /* i2c8_scl_m1 */
+- <2 RK_PB0 9 &pcfg_pull_none_smt>,
+- /* i2c8_sda_m1 */
+- <2 RK_PB1 9 &pcfg_pull_none_smt>;
+- };
+- };
+-
+- i2s2 {
+- /omit-if-no-ref/
+- i2s2m0_lrck: i2s2m0-lrck {
+- rockchip,pins =
+- /* i2s2m0_lrck */
+- <2 RK_PC0 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s2m0_mclk: i2s2m0-mclk {
+- rockchip,pins =
+- /* i2s2m0_mclk */
+- <2 RK_PB6 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s2m0_sclk: i2s2m0-sclk {
+- rockchip,pins =
+- /* i2s2m0_sclk */
+- <2 RK_PB7 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s2m0_sdi: i2s2m0-sdi {
+- rockchip,pins =
+- /* i2s2m0_sdi */
+- <2 RK_PC3 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s2m0_sdo: i2s2m0-sdo {
+- rockchip,pins =
+- /* i2s2m0_sdo */
+- <4 RK_PC3 2 &pcfg_pull_none>;
+- };
+- };
+-
+- pwm2 {
+- /omit-if-no-ref/
+- pwm2m2_pins: pwm2m2-pins {
+- rockchip,pins =
+- /* pwm2_m2 */
+- <4 RK_PC2 11 &pcfg_pull_none>;
+- };
+- };
+-
+- pwm4 {
+- /omit-if-no-ref/
+- pwm4m1_pins: pwm4m1-pins {
+- rockchip,pins =
+- /* pwm4_m1 */
+- <4 RK_PC3 11 &pcfg_pull_none>;
+- };
+- };
+-
+- pwm5 {
+- /omit-if-no-ref/
+- pwm5m2_pins: pwm5m2-pins {
+- rockchip,pins =
+- /* pwm5_m2 */
+- <4 RK_PC4 11 &pcfg_pull_none>;
+- };
+- };
+-
+- pwm6 {
+- /omit-if-no-ref/
+- pwm6m2_pins: pwm6m2-pins {
+- rockchip,pins =
+- /* pwm6_m2 */
+- <4 RK_PC5 11 &pcfg_pull_none>;
+- };
+- };
+-
+- pwm7 {
+- /omit-if-no-ref/
+- pwm7m3_pins: pwm7m3-pins {
+- rockchip,pins =
+- /* pwm7_ir_m3 */
+- <4 RK_PC6 11 &pcfg_pull_none>;
+- };
+- };
+-
+- sdio {
+- /omit-if-no-ref/
+- sdiom0_pins: sdiom0-pins {
+- rockchip,pins =
+- /* sdio_clk_m0 */
+- <2 RK_PB3 2 &pcfg_pull_none>,
+- /* sdio_cmd_m0 */
+- <2 RK_PB2 2 &pcfg_pull_none>,
+- /* sdio_d0_m0 */
+- <2 RK_PA6 2 &pcfg_pull_none>,
+- /* sdio_d1_m0 */
+- <2 RK_PA7 2 &pcfg_pull_none>,
+- /* sdio_d2_m0 */
+- <2 RK_PB0 2 &pcfg_pull_none>,
+- /* sdio_d3_m0 */
+- <2 RK_PB1 2 &pcfg_pull_none>;
+- };
+- };
+-
+- spi1 {
+- /omit-if-no-ref/
+- spi1m0_pins: spi1m0-pins {
+- rockchip,pins =
+- /* spi1_clk_m0 */
+- <2 RK_PC0 8 &pcfg_pull_up_drv_level_1>,
+- /* spi1_miso_m0 */
+- <2 RK_PC1 8 &pcfg_pull_up_drv_level_1>,
+- /* spi1_mosi_m0 */
+- <2 RK_PC2 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi1m0_cs0: spi1m0-cs0 {
+- rockchip,pins =
+- /* spi1_cs0_m0 */
+- <2 RK_PC3 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi1m0_cs1: spi1m0-cs1 {
+- rockchip,pins =
+- /* spi1_cs1_m0 */
+- <2 RK_PC4 8 &pcfg_pull_up_drv_level_1>;
+- };
+- };
+-
+- spi3 {
+- /omit-if-no-ref/
+- spi3m0_pins: spi3m0-pins {
+- rockchip,pins =
+- /* spi3_clk_m0 */
+- <4 RK_PC6 8 &pcfg_pull_up_drv_level_1>,
+- /* spi3_miso_m0 */
+- <4 RK_PC4 8 &pcfg_pull_up_drv_level_1>,
+- /* spi3_mosi_m0 */
+- <4 RK_PC5 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi3m0_cs0: spi3m0-cs0 {
+- rockchip,pins =
+- /* spi3_cs0_m0 */
+- <4 RK_PC2 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi3m0_cs1: spi3m0-cs1 {
+- rockchip,pins =
+- /* spi3_cs1_m0 */
+- <4 RK_PC3 8 &pcfg_pull_up_drv_level_1>;
+- };
+- };
+-
+- uart1 {
+- /omit-if-no-ref/
+- uart1m0_xfer: uart1m0-xfer {
+- rockchip,pins =
+- /* uart1_rx_m0 */
+- <2 RK_PB6 10 &pcfg_pull_up>,
+- /* uart1_tx_m0 */
+- <2 RK_PB7 10 &pcfg_pull_up>;
+- };
+-
+- /omit-if-no-ref/
+- uart1m0_ctsn: uart1m0-ctsn {
+- rockchip,pins =
+- /* uart1m0_ctsn */
+- <2 RK_PC1 10 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- uart1m0_rtsn: uart1m0-rtsn {
+- rockchip,pins =
+- /* uart1m0_rtsn */
+- <2 RK_PC0 10 &pcfg_pull_none>;
+- };
+- };
+-
+- uart6 {
+- /omit-if-no-ref/
+- uart6m0_xfer: uart6m0-xfer {
+- rockchip,pins =
+- /* uart6_rx_m0 */
+- <2 RK_PA6 10 &pcfg_pull_up>,
+- /* uart6_tx_m0 */
+- <2 RK_PA7 10 &pcfg_pull_up>;
+- };
+-
+- /omit-if-no-ref/
+- uart6m0_ctsn: uart6m0-ctsn {
+- rockchip,pins =
+- /* uart6m0_ctsn */
+- <2 RK_PB1 10 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- uart6m0_rtsn: uart6m0-rtsn {
+- rockchip,pins =
+- /* uart6m0_rtsn */
+- <2 RK_PB0 10 &pcfg_pull_none>;
+- };
+- };
+-
+- uart7 {
+- /omit-if-no-ref/
+- uart7m0_xfer: uart7m0-xfer {
+- rockchip,pins =
+- /* uart7_rx_m0 */
+- <2 RK_PB4 10 &pcfg_pull_up>,
+- /* uart7_tx_m0 */
+- <2 RK_PB5 10 &pcfg_pull_up>;
+- };
+-
+- /omit-if-no-ref/
+- uart7m0_ctsn: uart7m0-ctsn {
+- rockchip,pins =
+- /* uart7m0_ctsn */
+- <4 RK_PC6 10 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- uart7m0_rtsn: uart7m0-rtsn {
+- rockchip,pins =
+- /* uart7m0_rtsn */
+- <4 RK_PC2 10 &pcfg_pull_none>;
+- };
+- };
+-
+- uart9 {
+- /omit-if-no-ref/
+- uart9m0_xfer: uart9m0-xfer {
+- rockchip,pins =
+- /* uart9_rx_m0 */
+- <2 RK_PC4 10 &pcfg_pull_up>,
+- /* uart9_tx_m0 */
+- <2 RK_PC2 10 &pcfg_pull_up>;
+- };
+-
+- /omit-if-no-ref/
+- uart9m0_ctsn: uart9m0-ctsn {
+- rockchip,pins =
+- /* uart9m0_ctsn */
+- <4 RK_PC5 10 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- uart9m0_rtsn: uart9m0-rtsn {
+- rockchip,pins =
+- /* uart9m0_rtsn */
+- <4 RK_PC4 10 &pcfg_pull_none>;
+- };
+- };
+-};
+--- a/arch/arm64/boot/dts/rockchip/rk3588s-pinctrl.dtsi
++++ /dev/null
+@@ -1,3447 +0,0 @@
+-// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+-/*
+- * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
+- */
+-
+-#include <dt-bindings/pinctrl/rockchip.h>
+-#include "rockchip-pinconf.dtsi"
+-
+-/*
+- * This file is auto generated by pin2dts tool, please keep these code
+- * by adding changes at end of this file.
+- */
+-&pinctrl {
+- auddsm {
+- /omit-if-no-ref/
+- auddsm_pins: auddsm-pins {
+- rockchip,pins =
+- /* auddsm_ln */
+- <3 RK_PA1 4 &pcfg_pull_none>,
+- /* auddsm_lp */
+- <3 RK_PA2 4 &pcfg_pull_none>,
+- /* auddsm_rn */
+- <3 RK_PA3 4 &pcfg_pull_none>,
+- /* auddsm_rp */
+- <3 RK_PA4 4 &pcfg_pull_none>;
+- };
+- };
+-
+- bt1120 {
+- /omit-if-no-ref/
+- bt1120_pins: bt1120-pins {
+- rockchip,pins =
+- /* bt1120_clkout */
+- <4 RK_PB0 2 &pcfg_pull_none>,
+- /* bt1120_d0 */
+- <4 RK_PA0 2 &pcfg_pull_none>,
+- /* bt1120_d1 */
+- <4 RK_PA1 2 &pcfg_pull_none>,
+- /* bt1120_d2 */
+- <4 RK_PA2 2 &pcfg_pull_none>,
+- /* bt1120_d3 */
+- <4 RK_PA3 2 &pcfg_pull_none>,
+- /* bt1120_d4 */
+- <4 RK_PA4 2 &pcfg_pull_none>,
+- /* bt1120_d5 */
+- <4 RK_PA5 2 &pcfg_pull_none>,
+- /* bt1120_d6 */
+- <4 RK_PA6 2 &pcfg_pull_none>,
+- /* bt1120_d7 */
+- <4 RK_PA7 2 &pcfg_pull_none>,
+- /* bt1120_d8 */
+- <4 RK_PB2 2 &pcfg_pull_none>,
+- /* bt1120_d9 */
+- <4 RK_PB3 2 &pcfg_pull_none>,
+- /* bt1120_d10 */
+- <4 RK_PB4 2 &pcfg_pull_none>,
+- /* bt1120_d11 */
+- <4 RK_PB5 2 &pcfg_pull_none>,
+- /* bt1120_d12 */
+- <4 RK_PB6 2 &pcfg_pull_none>,
+- /* bt1120_d13 */
+- <4 RK_PB7 2 &pcfg_pull_none>,
+- /* bt1120_d14 */
+- <4 RK_PC0 2 &pcfg_pull_none>,
+- /* bt1120_d15 */
+- <4 RK_PC1 2 &pcfg_pull_none>;
+- };
+- };
+-
+- can0 {
+- /omit-if-no-ref/
+- can0m0_pins: can0m0-pins {
+- rockchip,pins =
+- /* can0_rx_m0 */
+- <0 RK_PC0 11 &pcfg_pull_none>,
+- /* can0_tx_m0 */
+- <0 RK_PB7 11 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- can0m1_pins: can0m1-pins {
+- rockchip,pins =
+- /* can0_rx_m1 */
+- <4 RK_PD5 9 &pcfg_pull_none>,
+- /* can0_tx_m1 */
+- <4 RK_PD4 9 &pcfg_pull_none>;
+- };
+- };
+-
+- can1 {
+- /omit-if-no-ref/
+- can1m0_pins: can1m0-pins {
+- rockchip,pins =
+- /* can1_rx_m0 */
+- <3 RK_PB5 9 &pcfg_pull_none>,
+- /* can1_tx_m0 */
+- <3 RK_PB6 9 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- can1m1_pins: can1m1-pins {
+- rockchip,pins =
+- /* can1_rx_m1 */
+- <4 RK_PB2 12 &pcfg_pull_none>,
+- /* can1_tx_m1 */
+- <4 RK_PB3 12 &pcfg_pull_none>;
+- };
+- };
+-
+- can2 {
+- /omit-if-no-ref/
+- can2m0_pins: can2m0-pins {
+- rockchip,pins =
+- /* can2_rx_m0 */
+- <3 RK_PC4 9 &pcfg_pull_none>,
+- /* can2_tx_m0 */
+- <3 RK_PC5 9 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- can2m1_pins: can2m1-pins {
+- rockchip,pins =
+- /* can2_rx_m1 */
+- <0 RK_PD4 10 &pcfg_pull_none>,
+- /* can2_tx_m1 */
+- <0 RK_PD5 10 &pcfg_pull_none>;
+- };
+- };
+-
+- cif {
+- /omit-if-no-ref/
+- cif_clk: cif-clk {
+- rockchip,pins =
+- /* cif_clkout */
+- <4 RK_PB4 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- cif_dvp_clk: cif-dvp-clk {
+- rockchip,pins =
+- /* cif_clkin */
+- <4 RK_PB0 1 &pcfg_pull_none>,
+- /* cif_href */
+- <4 RK_PB2 1 &pcfg_pull_none>,
+- /* cif_vsync */
+- <4 RK_PB3 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- cif_dvp_bus16: cif-dvp-bus16 {
+- rockchip,pins =
+- /* cif_d8 */
+- <3 RK_PC4 1 &pcfg_pull_none>,
+- /* cif_d9 */
+- <3 RK_PC5 1 &pcfg_pull_none>,
+- /* cif_d10 */
+- <3 RK_PC6 1 &pcfg_pull_none>,
+- /* cif_d11 */
+- <3 RK_PC7 1 &pcfg_pull_none>,
+- /* cif_d12 */
+- <3 RK_PD0 1 &pcfg_pull_none>,
+- /* cif_d13 */
+- <3 RK_PD1 1 &pcfg_pull_none>,
+- /* cif_d14 */
+- <3 RK_PD2 1 &pcfg_pull_none>,
+- /* cif_d15 */
+- <3 RK_PD3 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- cif_dvp_bus8: cif-dvp-bus8 {
+- rockchip,pins =
+- /* cif_d0 */
+- <4 RK_PA0 1 &pcfg_pull_none>,
+- /* cif_d1 */
+- <4 RK_PA1 1 &pcfg_pull_none>,
+- /* cif_d2 */
+- <4 RK_PA2 1 &pcfg_pull_none>,
+- /* cif_d3 */
+- <4 RK_PA3 1 &pcfg_pull_none>,
+- /* cif_d4 */
+- <4 RK_PA4 1 &pcfg_pull_none>,
+- /* cif_d5 */
+- <4 RK_PA5 1 &pcfg_pull_none>,
+- /* cif_d6 */
+- <4 RK_PA6 1 &pcfg_pull_none>,
+- /* cif_d7 */
+- <4 RK_PA7 1 &pcfg_pull_none>;
+- };
+- };
+-
+- clk32k {
+- /omit-if-no-ref/
+- clk32k_in: clk32k-in {
+- rockchip,pins =
+- /* clk32k_in */
+- <0 RK_PB2 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- clk32k_out0: clk32k-out0 {
+- rockchip,pins =
+- /* clk32k_out0 */
+- <0 RK_PB2 2 &pcfg_pull_none>;
+- };
+- };
+-
+- cpu {
+- /omit-if-no-ref/
+- cpu_pins: cpu-pins {
+- rockchip,pins =
+- /* cpu_big0_avs */
+- <0 RK_PD1 2 &pcfg_pull_none>,
+- /* cpu_big1_avs */
+- <0 RK_PD5 2 &pcfg_pull_none>;
+- };
+- };
+-
+- ddrphych0 {
+- /omit-if-no-ref/
+- ddrphych0_pins: ddrphych0-pins {
+- rockchip,pins =
+- /* ddrphych0_dtb0 */
+- <4 RK_PA0 7 &pcfg_pull_none>,
+- /* ddrphych0_dtb1 */
+- <4 RK_PA1 7 &pcfg_pull_none>,
+- /* ddrphych0_dtb2 */
+- <4 RK_PA2 7 &pcfg_pull_none>,
+- /* ddrphych0_dtb3 */
+- <4 RK_PA3 7 &pcfg_pull_none>;
+- };
+- };
+-
+- ddrphych1 {
+- /omit-if-no-ref/
+- ddrphych1_pins: ddrphych1-pins {
+- rockchip,pins =
+- /* ddrphych1_dtb0 */
+- <4 RK_PA4 7 &pcfg_pull_none>,
+- /* ddrphych1_dtb1 */
+- <4 RK_PA5 7 &pcfg_pull_none>,
+- /* ddrphych1_dtb2 */
+- <4 RK_PA6 7 &pcfg_pull_none>,
+- /* ddrphych1_dtb3 */
+- <4 RK_PA7 7 &pcfg_pull_none>;
+- };
+- };
+-
+- ddrphych2 {
+- /omit-if-no-ref/
+- ddrphych2_pins: ddrphych2-pins {
+- rockchip,pins =
+- /* ddrphych2_dtb0 */
+- <4 RK_PB0 7 &pcfg_pull_none>,
+- /* ddrphych2_dtb1 */
+- <4 RK_PB1 7 &pcfg_pull_none>,
+- /* ddrphych2_dtb2 */
+- <4 RK_PB2 7 &pcfg_pull_none>,
+- /* ddrphych2_dtb3 */
+- <4 RK_PB3 7 &pcfg_pull_none>;
+- };
+- };
+-
+- ddrphych3 {
+- /omit-if-no-ref/
+- ddrphych3_pins: ddrphych3-pins {
+- rockchip,pins =
+- /* ddrphych3_dtb0 */
+- <4 RK_PB4 7 &pcfg_pull_none>,
+- /* ddrphych3_dtb1 */
+- <4 RK_PB5 7 &pcfg_pull_none>,
+- /* ddrphych3_dtb2 */
+- <4 RK_PB6 7 &pcfg_pull_none>,
+- /* ddrphych3_dtb3 */
+- <4 RK_PB7 7 &pcfg_pull_none>;
+- };
+- };
+-
+- dp0 {
+- /omit-if-no-ref/
+- dp0m0_pins: dp0m0-pins {
+- rockchip,pins =
+- /* dp0_hpdin_m0 */
+- <4 RK_PB4 5 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- dp0m1_pins: dp0m1-pins {
+- rockchip,pins =
+- /* dp0_hpdin_m1 */
+- <0 RK_PC4 10 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- dp0m2_pins: dp0m2-pins {
+- rockchip,pins =
+- /* dp0_hpdin_m2 */
+- <1 RK_PA0 5 &pcfg_pull_none>;
+- };
+- };
+-
+- dp1 {
+- /omit-if-no-ref/
+- dp1m0_pins: dp1m0-pins {
+- rockchip,pins =
+- /* dp1_hpdin_m0 */
+- <3 RK_PD5 5 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- dp1m1_pins: dp1m1-pins {
+- rockchip,pins =
+- /* dp1_hpdin_m1 */
+- <0 RK_PC5 10 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- dp1m2_pins: dp1m2-pins {
+- rockchip,pins =
+- /* dp1_hpdin_m2 */
+- <1 RK_PA1 5 &pcfg_pull_none>;
+- };
+- };
+-
+- emmc {
+- /omit-if-no-ref/
+- emmc_rstnout: emmc-rstnout {
+- rockchip,pins =
+- /* emmc_rstn */
+- <2 RK_PA3 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- emmc_bus8: emmc-bus8 {
+- rockchip,pins =
+- /* emmc_d0 */
+- <2 RK_PD0 1 &pcfg_pull_up_drv_level_2>,
+- /* emmc_d1 */
+- <2 RK_PD1 1 &pcfg_pull_up_drv_level_2>,
+- /* emmc_d2 */
+- <2 RK_PD2 1 &pcfg_pull_up_drv_level_2>,
+- /* emmc_d3 */
+- <2 RK_PD3 1 &pcfg_pull_up_drv_level_2>,
+- /* emmc_d4 */
+- <2 RK_PD4 1 &pcfg_pull_up_drv_level_2>,
+- /* emmc_d5 */
+- <2 RK_PD5 1 &pcfg_pull_up_drv_level_2>,
+- /* emmc_d6 */
+- <2 RK_PD6 1 &pcfg_pull_up_drv_level_2>,
+- /* emmc_d7 */
+- <2 RK_PD7 1 &pcfg_pull_up_drv_level_2>;
+- };
+-
+- /omit-if-no-ref/
+- emmc_clk: emmc-clk {
+- rockchip,pins =
+- /* emmc_clkout */
+- <2 RK_PA1 1 &pcfg_pull_up_drv_level_2>;
+- };
+-
+- /omit-if-no-ref/
+- emmc_cmd: emmc-cmd {
+- rockchip,pins =
+- /* emmc_cmd */
+- <2 RK_PA0 1 &pcfg_pull_up_drv_level_2>;
+- };
+-
+- /omit-if-no-ref/
+- emmc_data_strobe: emmc-data-strobe {
+- rockchip,pins =
+- /* emmc_data_strobe */
+- <2 RK_PA2 1 &pcfg_pull_down>;
+- };
+- };
+-
+- eth1 {
+- /omit-if-no-ref/
+- eth1_pins: eth1-pins {
+- rockchip,pins =
+- /* eth1_refclko_25m */
+- <3 RK_PA6 1 &pcfg_pull_none>;
+- };
+- };
+-
+- fspi {
+- /omit-if-no-ref/
+- fspim0_pins: fspim0-pins {
+- rockchip,pins =
+- /* fspi_clk_m0 */
+- <2 RK_PA0 2 &pcfg_pull_up_drv_level_2>,
+- /* fspi_cs0n_m0 */
+- <2 RK_PD6 2 &pcfg_pull_up_drv_level_2>,
+- /* fspi_d0_m0 */
+- <2 RK_PD0 2 &pcfg_pull_up_drv_level_2>,
+- /* fspi_d1_m0 */
+- <2 RK_PD1 2 &pcfg_pull_up_drv_level_2>,
+- /* fspi_d2_m0 */
+- <2 RK_PD2 2 &pcfg_pull_up_drv_level_2>,
+- /* fspi_d3_m0 */
+- <2 RK_PD3 2 &pcfg_pull_up_drv_level_2>;
+- };
+-
+- /omit-if-no-ref/
+- fspim0_cs1: fspim0-cs1 {
+- rockchip,pins =
+- /* fspi_cs1n_m0 */
+- <2 RK_PD7 2 &pcfg_pull_up_drv_level_2>;
+- };
+-
+- /omit-if-no-ref/
+- fspim2_pins: fspim2-pins {
+- rockchip,pins =
+- /* fspi_clk_m2 */
+- <3 RK_PA5 5 &pcfg_pull_up_drv_level_2>,
+- /* fspi_cs0n_m2 */
+- <3 RK_PC4 2 &pcfg_pull_up_drv_level_2>,
+- /* fspi_d0_m2 */
+- <3 RK_PA0 5 &pcfg_pull_up_drv_level_2>,
+- /* fspi_d1_m2 */
+- <3 RK_PA1 5 &pcfg_pull_up_drv_level_2>,
+- /* fspi_d2_m2 */
+- <3 RK_PA2 5 &pcfg_pull_up_drv_level_2>,
+- /* fspi_d3_m2 */
+- <3 RK_PA3 5 &pcfg_pull_up_drv_level_2>;
+- };
+-
+- /omit-if-no-ref/
+- fspim2_cs1: fspim2-cs1 {
+- rockchip,pins =
+- /* fspi_cs1n_m2 */
+- <3 RK_PC5 2 &pcfg_pull_up_drv_level_2>;
+- };
+- };
+-
+- gmac1 {
+- /omit-if-no-ref/
+- gmac1_miim: gmac1-miim {
+- rockchip,pins =
+- /* gmac1_mdc */
+- <3 RK_PC2 1 &pcfg_pull_none>,
+- /* gmac1_mdio */
+- <3 RK_PC3 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- gmac1_clkinout: gmac1-clkinout {
+- rockchip,pins =
+- /* gmac1_mclkinout */
+- <3 RK_PB6 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- gmac1_rx_bus2: gmac1-rx-bus2 {
+- rockchip,pins =
+- /* gmac1_rxd0 */
+- <3 RK_PA7 1 &pcfg_pull_none>,
+- /* gmac1_rxd1 */
+- <3 RK_PB0 1 &pcfg_pull_none>,
+- /* gmac1_rxdv_crs */
+- <3 RK_PB1 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- gmac1_tx_bus2: gmac1-tx-bus2 {
+- rockchip,pins =
+- /* gmac1_txd0 */
+- <3 RK_PB3 1 &pcfg_pull_none>,
+- /* gmac1_txd1 */
+- <3 RK_PB4 1 &pcfg_pull_none>,
+- /* gmac1_txen */
+- <3 RK_PB5 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- gmac1_rgmii_clk: gmac1-rgmii-clk {
+- rockchip,pins =
+- /* gmac1_rxclk */
+- <3 RK_PA5 1 &pcfg_pull_none>,
+- /* gmac1_txclk */
+- <3 RK_PA4 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- gmac1_rgmii_bus: gmac1-rgmii-bus {
+- rockchip,pins =
+- /* gmac1_rxd2 */
+- <3 RK_PA2 1 &pcfg_pull_none>,
+- /* gmac1_rxd3 */
+- <3 RK_PA3 1 &pcfg_pull_none>,
+- /* gmac1_txd2 */
+- <3 RK_PA0 1 &pcfg_pull_none>,
+- /* gmac1_txd3 */
+- <3 RK_PA1 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- gmac1_ppsclk: gmac1-ppsclk {
+- rockchip,pins =
+- /* gmac1_ppsclk */
+- <3 RK_PC1 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- gmac1_ppstrig: gmac1-ppstrig {
+- rockchip,pins =
+- /* gmac1_ppstrig */
+- <3 RK_PC0 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- gmac1_ptp_ref_clk: gmac1-ptp-ref-clk {
+- rockchip,pins =
+- /* gmac1_ptp_ref_clk */
+- <3 RK_PB7 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- gmac1_txer: gmac1-txer {
+- rockchip,pins =
+- /* gmac1_txer */
+- <3 RK_PB2 1 &pcfg_pull_none>;
+- };
+- };
+-
+- gpu {
+- /omit-if-no-ref/
+- gpu_pins: gpu-pins {
+- rockchip,pins =
+- /* gpu_avs */
+- <0 RK_PC5 2 &pcfg_pull_none>;
+- };
+- };
+-
+- hdmi {
+- /omit-if-no-ref/
+- hdmim0_rx_cec: hdmim0-rx-cec {
+- rockchip,pins =
+- /* hdmim0_rx_cec */
+- <4 RK_PB5 5 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmim0_rx_hpdin: hdmim0-rx-hpdin {
+- rockchip,pins =
+- /* hdmim0_rx_hpdin */
+- <4 RK_PB6 5 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmim0_rx_scl: hdmim0-rx-scl {
+- rockchip,pins =
+- /* hdmim0_rx_scl */
+- <0 RK_PD2 11 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmim0_rx_sda: hdmim0-rx-sda {
+- rockchip,pins =
+- /* hdmim0_rx_sda */
+- <0 RK_PD1 11 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmim0_tx0_cec: hdmim0-tx0-cec {
+- rockchip,pins =
+- /* hdmim0_tx0_cec */
+- <4 RK_PC1 5 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmim0_tx0_hpd: hdmim0-tx0-hpd {
+- rockchip,pins =
+- /* hdmim0_tx0_hpd */
+- <1 RK_PA5 5 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmim0_tx0_scl: hdmim0-tx0-scl {
+- rockchip,pins =
+- /* hdmim0_tx0_scl */
+- <4 RK_PB7 5 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmim0_tx0_sda: hdmim0-tx0-sda {
+- rockchip,pins =
+- /* hdmim0_tx0_sda */
+- <4 RK_PC0 5 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmim0_tx1_hpd: hdmim0-tx1-hpd {
+- rockchip,pins =
+- /* hdmim0_tx1_hpd */
+- <1 RK_PA6 5 &pcfg_pull_none>;
+- };
+- /omit-if-no-ref/
+- hdmim1_rx_cec: hdmim1-rx-cec {
+- rockchip,pins =
+- /* hdmim1_rx_cec */
+- <3 RK_PD1 5 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmim1_rx_hpdin: hdmim1-rx-hpdin {
+- rockchip,pins =
+- /* hdmim1_rx_hpdin */
+- <3 RK_PD4 5 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmim1_rx_scl: hdmim1-rx-scl {
+- rockchip,pins =
+- /* hdmim1_rx_scl */
+- <3 RK_PD2 5 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmim1_rx_sda: hdmim1-rx-sda {
+- rockchip,pins =
+- /* hdmim1_rx_sda */
+- <3 RK_PD3 5 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmim1_tx0_cec: hdmim1-tx0-cec {
+- rockchip,pins =
+- /* hdmim1_tx0_cec */
+- <0 RK_PD1 13 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmim1_tx0_hpd: hdmim1-tx0-hpd {
+- rockchip,pins =
+- /* hdmim1_tx0_hpd */
+- <3 RK_PD4 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmim1_tx0_scl: hdmim1-tx0-scl {
+- rockchip,pins =
+- /* hdmim1_tx0_scl */
+- <0 RK_PD5 11 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmim1_tx0_sda: hdmim1-tx0-sda {
+- rockchip,pins =
+- /* hdmim1_tx0_sda */
+- <0 RK_PD4 11 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmim1_tx1_cec: hdmim1-tx1-cec {
+- rockchip,pins =
+- /* hdmim1_tx1_cec */
+- <0 RK_PD2 13 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmim1_tx1_hpd: hdmim1-tx1-hpd {
+- rockchip,pins =
+- /* hdmim1_tx1_hpd */
+- <3 RK_PB7 5 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmim1_tx1_scl: hdmim1-tx1-scl {
+- rockchip,pins =
+- /* hdmim1_tx1_scl */
+- <3 RK_PC6 5 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmim1_tx1_sda: hdmim1-tx1-sda {
+- rockchip,pins =
+- /* hdmim1_tx1_sda */
+- <3 RK_PC5 5 &pcfg_pull_none>;
+- };
+- /omit-if-no-ref/
+- hdmim2_rx_cec: hdmim2-rx-cec {
+- rockchip,pins =
+- /* hdmim2_rx_cec */
+- <1 RK_PB7 5 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmim2_rx_hpdin: hdmim2-rx-hpdin {
+- rockchip,pins =
+- /* hdmim2_rx_hpdin */
+- <1 RK_PB6 5 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmim2_rx_scl: hdmim2-rx-scl {
+- rockchip,pins =
+- /* hdmim2_rx_scl */
+- <1 RK_PD6 5 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmim2_rx_sda: hdmim2-rx-sda {
+- rockchip,pins =
+- /* hdmim2_rx_sda */
+- <1 RK_PD7 5 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmim2_tx0_scl: hdmim2-tx0-scl {
+- rockchip,pins =
+- /* hdmim2_tx0_scl */
+- <3 RK_PC7 5 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmim2_tx0_sda: hdmim2-tx0-sda {
+- rockchip,pins =
+- /* hdmim2_tx0_sda */
+- <3 RK_PD0 5 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmim2_tx1_cec: hdmim2-tx1-cec {
+- rockchip,pins =
+- /* hdmim2_tx1_cec */
+- <3 RK_PC4 5 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmim2_tx1_scl: hdmim2-tx1-scl {
+- rockchip,pins =
+- /* hdmim2_tx1_scl */
+- <1 RK_PA4 5 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmim2_tx1_sda: hdmim2-tx1-sda {
+- rockchip,pins =
+- /* hdmim2_tx1_sda */
+- <1 RK_PA3 5 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmi_debug0: hdmi-debug0 {
+- rockchip,pins =
+- /* hdmi_debug0 */
+- <1 RK_PA7 7 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmi_debug1: hdmi-debug1 {
+- rockchip,pins =
+- /* hdmi_debug1 */
+- <1 RK_PB0 7 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmi_debug2: hdmi-debug2 {
+- rockchip,pins =
+- /* hdmi_debug2 */
+- <1 RK_PB1 7 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmi_debug3: hdmi-debug3 {
+- rockchip,pins =
+- /* hdmi_debug3 */
+- <1 RK_PB2 7 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmi_debug4: hdmi-debug4 {
+- rockchip,pins =
+- /* hdmi_debug4 */
+- <1 RK_PB3 7 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmi_debug5: hdmi-debug5 {
+- rockchip,pins =
+- /* hdmi_debug5 */
+- <1 RK_PB4 7 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- hdmi_debug6: hdmi-debug6 {
+- rockchip,pins =
+- /* hdmi_debug6 */
+- <1 RK_PA0 7 &pcfg_pull_none>;
+- };
+- };
+-
+- i2c0 {
+- /omit-if-no-ref/
+- i2c0m0_xfer: i2c0m0-xfer {
+- rockchip,pins =
+- /* i2c0_scl_m0 */
+- <0 RK_PB3 2 &pcfg_pull_none_smt>,
+- /* i2c0_sda_m0 */
+- <0 RK_PA6 2 &pcfg_pull_none_smt>;
+- };
+-
+- /omit-if-no-ref/
+- i2c0m2_xfer: i2c0m2-xfer {
+- rockchip,pins =
+- /* i2c0_scl_m2 */
+- <0 RK_PD1 3 &pcfg_pull_none_smt>,
+- /* i2c0_sda_m2 */
+- <0 RK_PD2 3 &pcfg_pull_none_smt>;
+- };
+- };
+-
+- i2c1 {
+- /omit-if-no-ref/
+- i2c1m0_xfer: i2c1m0-xfer {
+- rockchip,pins =
+- /* i2c1_scl_m0 */
+- <0 RK_PB5 9 &pcfg_pull_none_smt>,
+- /* i2c1_sda_m0 */
+- <0 RK_PB6 9 &pcfg_pull_none_smt>;
+- };
+-
+- /omit-if-no-ref/
+- i2c1m1_xfer: i2c1m1-xfer {
+- rockchip,pins =
+- /* i2c1_scl_m1 */
+- <0 RK_PB0 2 &pcfg_pull_none_smt>,
+- /* i2c1_sda_m1 */
+- <0 RK_PB1 2 &pcfg_pull_none_smt>;
+- };
+-
+- /omit-if-no-ref/
+- i2c1m2_xfer: i2c1m2-xfer {
+- rockchip,pins =
+- /* i2c1_scl_m2 */
+- <0 RK_PD4 9 &pcfg_pull_none_smt>,
+- /* i2c1_sda_m2 */
+- <0 RK_PD5 9 &pcfg_pull_none_smt>;
+- };
+-
+- /omit-if-no-ref/
+- i2c1m3_xfer: i2c1m3-xfer {
+- rockchip,pins =
+- /* i2c1_scl_m3 */
+- <2 RK_PD4 9 &pcfg_pull_none_smt>,
+- /* i2c1_sda_m3 */
+- <2 RK_PD5 9 &pcfg_pull_none_smt>;
+- };
+-
+- /omit-if-no-ref/
+- i2c1m4_xfer: i2c1m4-xfer {
+- rockchip,pins =
+- /* i2c1_scl_m4 */
+- <1 RK_PD2 9 &pcfg_pull_none_smt>,
+- /* i2c1_sda_m4 */
+- <1 RK_PD3 9 &pcfg_pull_none_smt>;
+- };
+- };
+-
+- i2c2 {
+- /omit-if-no-ref/
+- i2c2m0_xfer: i2c2m0-xfer {
+- rockchip,pins =
+- /* i2c2_scl_m0 */
+- <0 RK_PB7 9 &pcfg_pull_none_smt>,
+- /* i2c2_sda_m0 */
+- <0 RK_PC0 9 &pcfg_pull_none_smt>;
+- };
+-
+- /omit-if-no-ref/
+- i2c2m2_xfer: i2c2m2-xfer {
+- rockchip,pins =
+- /* i2c2_scl_m2 */
+- <2 RK_PA3 9 &pcfg_pull_none_smt>,
+- /* i2c2_sda_m2 */
+- <2 RK_PA2 9 &pcfg_pull_none_smt>;
+- };
+-
+- /omit-if-no-ref/
+- i2c2m3_xfer: i2c2m3-xfer {
+- rockchip,pins =
+- /* i2c2_scl_m3 */
+- <1 RK_PC5 9 &pcfg_pull_none_smt>,
+- /* i2c2_sda_m3 */
+- <1 RK_PC4 9 &pcfg_pull_none_smt>;
+- };
+-
+- /omit-if-no-ref/
+- i2c2m4_xfer: i2c2m4-xfer {
+- rockchip,pins =
+- /* i2c2_scl_m4 */
+- <1 RK_PA1 9 &pcfg_pull_none_smt>,
+- /* i2c2_sda_m4 */
+- <1 RK_PA0 9 &pcfg_pull_none_smt>;
+- };
+- };
+-
+- i2c3 {
+- /omit-if-no-ref/
+- i2c3m0_xfer: i2c3m0-xfer {
+- rockchip,pins =
+- /* i2c3_scl_m0 */
+- <1 RK_PC1 9 &pcfg_pull_none_smt>,
+- /* i2c3_sda_m0 */
+- <1 RK_PC0 9 &pcfg_pull_none_smt>;
+- };
+-
+- /omit-if-no-ref/
+- i2c3m1_xfer: i2c3m1-xfer {
+- rockchip,pins =
+- /* i2c3_scl_m1 */
+- <3 RK_PB7 9 &pcfg_pull_none_smt>,
+- /* i2c3_sda_m1 */
+- <3 RK_PC0 9 &pcfg_pull_none_smt>;
+- };
+-
+- /omit-if-no-ref/
+- i2c3m2_xfer: i2c3m2-xfer {
+- rockchip,pins =
+- /* i2c3_scl_m2 */
+- <4 RK_PA4 9 &pcfg_pull_none_smt>,
+- /* i2c3_sda_m2 */
+- <4 RK_PA5 9 &pcfg_pull_none_smt>;
+- };
+-
+- /omit-if-no-ref/
+- i2c3m4_xfer: i2c3m4-xfer {
+- rockchip,pins =
+- /* i2c3_scl_m4 */
+- <4 RK_PD0 9 &pcfg_pull_none_smt>,
+- /* i2c3_sda_m4 */
+- <4 RK_PD1 9 &pcfg_pull_none_smt>;
+- };
+- };
+-
+- i2c4 {
+- /omit-if-no-ref/
+- i2c4m0_xfer: i2c4m0-xfer {
+- rockchip,pins =
+- /* i2c4_scl_m0 */
+- <3 RK_PA6 9 &pcfg_pull_none_smt>,
+- /* i2c4_sda_m0 */
+- <3 RK_PA5 9 &pcfg_pull_none_smt>;
+- };
+-
+- /omit-if-no-ref/
+- i2c4m2_xfer: i2c4m2-xfer {
+- rockchip,pins =
+- /* i2c4_scl_m2 */
+- <0 RK_PC5 9 &pcfg_pull_none_smt>,
+- /* i2c4_sda_m2 */
+- <0 RK_PC4 9 &pcfg_pull_none_smt>;
+- };
+-
+- /omit-if-no-ref/
+- i2c4m3_xfer: i2c4m3-xfer {
+- rockchip,pins =
+- /* i2c4_scl_m3 */
+- <1 RK_PA3 9 &pcfg_pull_none_smt>,
+- /* i2c4_sda_m3 */
+- <1 RK_PA2 9 &pcfg_pull_none_smt>;
+- };
+-
+- /omit-if-no-ref/
+- i2c4m4_xfer: i2c4m4-xfer {
+- rockchip,pins =
+- /* i2c4_scl_m4 */
+- <1 RK_PC7 9 &pcfg_pull_none_smt>,
+- /* i2c4_sda_m4 */
+- <1 RK_PC6 9 &pcfg_pull_none_smt>;
+- };
+- };
+-
+- i2c5 {
+- /omit-if-no-ref/
+- i2c5m0_xfer: i2c5m0-xfer {
+- rockchip,pins =
+- /* i2c5_scl_m0 */
+- <3 RK_PC7 9 &pcfg_pull_none_smt>,
+- /* i2c5_sda_m0 */
+- <3 RK_PD0 9 &pcfg_pull_none_smt>;
+- };
+-
+- /omit-if-no-ref/
+- i2c5m1_xfer: i2c5m1-xfer {
+- rockchip,pins =
+- /* i2c5_scl_m1 */
+- <4 RK_PB6 9 &pcfg_pull_none_smt>,
+- /* i2c5_sda_m1 */
+- <4 RK_PB7 9 &pcfg_pull_none_smt>;
+- };
+-
+- /omit-if-no-ref/
+- i2c5m2_xfer: i2c5m2-xfer {
+- rockchip,pins =
+- /* i2c5_scl_m2 */
+- <4 RK_PA6 9 &pcfg_pull_none_smt>,
+- /* i2c5_sda_m2 */
+- <4 RK_PA7 9 &pcfg_pull_none_smt>;
+- };
+-
+- /omit-if-no-ref/
+- i2c5m3_xfer: i2c5m3-xfer {
+- rockchip,pins =
+- /* i2c5_scl_m3 */
+- <1 RK_PB6 9 &pcfg_pull_none_smt>,
+- /* i2c5_sda_m3 */
+- <1 RK_PB7 9 &pcfg_pull_none_smt>;
+- };
+- };
+-
+- i2c6 {
+- /omit-if-no-ref/
+- i2c6m0_xfer: i2c6m0-xfer {
+- rockchip,pins =
+- /* i2c6_scl_m0 */
+- <0 RK_PD0 9 &pcfg_pull_none_smt>,
+- /* i2c6_sda_m0 */
+- <0 RK_PC7 9 &pcfg_pull_none_smt>;
+- };
+-
+- /omit-if-no-ref/
+- i2c6m1_xfer: i2c6m1-xfer {
+- rockchip,pins =
+- /* i2c6_scl_m1 */
+- <1 RK_PC3 9 &pcfg_pull_none_smt>,
+- /* i2c6_sda_m1 */
+- <1 RK_PC2 9 &pcfg_pull_none_smt>;
+- };
+-
+- /omit-if-no-ref/
+- i2c6m3_xfer: i2c6m3-xfer {
+- rockchip,pins =
+- /* i2c6_scl_m3 */
+- <4 RK_PB1 9 &pcfg_pull_none_smt>,
+- /* i2c6_sda_m3 */
+- <4 RK_PB0 9 &pcfg_pull_none_smt>;
+- };
+-
+- /omit-if-no-ref/
+- i2c6m4_xfer: i2c6m4-xfer {
+- rockchip,pins =
+- /* i2c6_scl_m4 */
+- <3 RK_PA1 9 &pcfg_pull_none_smt>,
+- /* i2c6_sda_m4 */
+- <3 RK_PA0 9 &pcfg_pull_none_smt>;
+- };
+- };
+-
+- i2c7 {
+- /omit-if-no-ref/
+- i2c7m0_xfer: i2c7m0-xfer {
+- rockchip,pins =
+- /* i2c7_scl_m0 */
+- <1 RK_PD0 9 &pcfg_pull_none_smt>,
+- /* i2c7_sda_m0 */
+- <1 RK_PD1 9 &pcfg_pull_none_smt>;
+- };
+-
+- /omit-if-no-ref/
+- i2c7m2_xfer: i2c7m2-xfer {
+- rockchip,pins =
+- /* i2c7_scl_m2 */
+- <3 RK_PD2 9 &pcfg_pull_none_smt>,
+- /* i2c7_sda_m2 */
+- <3 RK_PD3 9 &pcfg_pull_none_smt>;
+- };
+-
+- /omit-if-no-ref/
+- i2c7m3_xfer: i2c7m3-xfer {
+- rockchip,pins =
+- /* i2c7_scl_m3 */
+- <4 RK_PB2 9 &pcfg_pull_none_smt>,
+- /* i2c7_sda_m3 */
+- <4 RK_PB3 9 &pcfg_pull_none_smt>;
+- };
+- };
+-
+- i2c8 {
+- /omit-if-no-ref/
+- i2c8m0_xfer: i2c8m0-xfer {
+- rockchip,pins =
+- /* i2c8_scl_m0 */
+- <4 RK_PD2 9 &pcfg_pull_none_smt>,
+- /* i2c8_sda_m0 */
+- <4 RK_PD3 9 &pcfg_pull_none_smt>;
+- };
+-
+- /omit-if-no-ref/
+- i2c8m2_xfer: i2c8m2-xfer {
+- rockchip,pins =
+- /* i2c8_scl_m2 */
+- <1 RK_PD6 9 &pcfg_pull_none_smt>,
+- /* i2c8_sda_m2 */
+- <1 RK_PD7 9 &pcfg_pull_none_smt>;
+- };
+-
+- /omit-if-no-ref/
+- i2c8m3_xfer: i2c8m3-xfer {
+- rockchip,pins =
+- /* i2c8_scl_m3 */
+- <4 RK_PC0 9 &pcfg_pull_none_smt>,
+- /* i2c8_sda_m3 */
+- <4 RK_PC1 9 &pcfg_pull_none_smt>;
+- };
+-
+- /omit-if-no-ref/
+- i2c8m4_xfer: i2c8m4-xfer {
+- rockchip,pins =
+- /* i2c8_scl_m4 */
+- <3 RK_PC2 9 &pcfg_pull_none_smt>,
+- /* i2c8_sda_m4 */
+- <3 RK_PC3 9 &pcfg_pull_none_smt>;
+- };
+- };
+-
+- i2s0 {
+- /omit-if-no-ref/
+- i2s0_lrck: i2s0-lrck {
+- rockchip,pins =
+- /* i2s0_lrck */
+- <1 RK_PC5 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s0_mclk: i2s0-mclk {
+- rockchip,pins =
+- /* i2s0_mclk */
+- <1 RK_PC2 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s0_sclk: i2s0-sclk {
+- rockchip,pins =
+- /* i2s0_sclk */
+- <1 RK_PC3 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s0_sdi0: i2s0-sdi0 {
+- rockchip,pins =
+- /* i2s0_sdi0 */
+- <1 RK_PD4 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s0_sdi1: i2s0-sdi1 {
+- rockchip,pins =
+- /* i2s0_sdi1 */
+- <1 RK_PD3 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s0_sdi2: i2s0-sdi2 {
+- rockchip,pins =
+- /* i2s0_sdi2 */
+- <1 RK_PD2 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s0_sdi3: i2s0-sdi3 {
+- rockchip,pins =
+- /* i2s0_sdi3 */
+- <1 RK_PD1 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s0_sdo0: i2s0-sdo0 {
+- rockchip,pins =
+- /* i2s0_sdo0 */
+- <1 RK_PC7 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s0_sdo1: i2s0-sdo1 {
+- rockchip,pins =
+- /* i2s0_sdo1 */
+- <1 RK_PD0 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s0_sdo2: i2s0-sdo2 {
+- rockchip,pins =
+- /* i2s0_sdo2 */
+- <1 RK_PD1 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s0_sdo3: i2s0-sdo3 {
+- rockchip,pins =
+- /* i2s0_sdo3 */
+- <1 RK_PD2 1 &pcfg_pull_none>;
+- };
+- };
+-
+- i2s1 {
+- /omit-if-no-ref/
+- i2s1m0_lrck: i2s1m0-lrck {
+- rockchip,pins =
+- /* i2s1m0_lrck */
+- <4 RK_PA2 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s1m0_mclk: i2s1m0-mclk {
+- rockchip,pins =
+- /* i2s1m0_mclk */
+- <4 RK_PA0 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s1m0_sclk: i2s1m0-sclk {
+- rockchip,pins =
+- /* i2s1m0_sclk */
+- <4 RK_PA1 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s1m0_sdi0: i2s1m0-sdi0 {
+- rockchip,pins =
+- /* i2s1m0_sdi0 */
+- <4 RK_PA5 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s1m0_sdi1: i2s1m0-sdi1 {
+- rockchip,pins =
+- /* i2s1m0_sdi1 */
+- <4 RK_PA6 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s1m0_sdi2: i2s1m0-sdi2 {
+- rockchip,pins =
+- /* i2s1m0_sdi2 */
+- <4 RK_PA7 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s1m0_sdi3: i2s1m0-sdi3 {
+- rockchip,pins =
+- /* i2s1m0_sdi3 */
+- <4 RK_PB0 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s1m0_sdo0: i2s1m0-sdo0 {
+- rockchip,pins =
+- /* i2s1m0_sdo0 */
+- <4 RK_PB1 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s1m0_sdo1: i2s1m0-sdo1 {
+- rockchip,pins =
+- /* i2s1m0_sdo1 */
+- <4 RK_PB2 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s1m0_sdo2: i2s1m0-sdo2 {
+- rockchip,pins =
+- /* i2s1m0_sdo2 */
+- <4 RK_PB3 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s1m0_sdo3: i2s1m0-sdo3 {
+- rockchip,pins =
+- /* i2s1m0_sdo3 */
+- <4 RK_PB4 3 &pcfg_pull_none>;
+- };
+- /omit-if-no-ref/
+- i2s1m1_lrck: i2s1m1-lrck {
+- rockchip,pins =
+- /* i2s1m1_lrck */
+- <0 RK_PB7 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s1m1_mclk: i2s1m1-mclk {
+- rockchip,pins =
+- /* i2s1m1_mclk */
+- <0 RK_PB5 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s1m1_sclk: i2s1m1-sclk {
+- rockchip,pins =
+- /* i2s1m1_sclk */
+- <0 RK_PB6 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s1m1_sdi0: i2s1m1-sdi0 {
+- rockchip,pins =
+- /* i2s1m1_sdi0 */
+- <0 RK_PC5 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s1m1_sdi1: i2s1m1-sdi1 {
+- rockchip,pins =
+- /* i2s1m1_sdi1 */
+- <0 RK_PC6 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s1m1_sdi2: i2s1m1-sdi2 {
+- rockchip,pins =
+- /* i2s1m1_sdi2 */
+- <0 RK_PC7 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s1m1_sdi3: i2s1m1-sdi3 {
+- rockchip,pins =
+- /* i2s1m1_sdi3 */
+- <0 RK_PD0 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s1m1_sdo0: i2s1m1-sdo0 {
+- rockchip,pins =
+- /* i2s1m1_sdo0 */
+- <0 RK_PD1 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s1m1_sdo1: i2s1m1-sdo1 {
+- rockchip,pins =
+- /* i2s1m1_sdo1 */
+- <0 RK_PD2 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s1m1_sdo2: i2s1m1-sdo2 {
+- rockchip,pins =
+- /* i2s1m1_sdo2 */
+- <0 RK_PD4 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s1m1_sdo3: i2s1m1-sdo3 {
+- rockchip,pins =
+- /* i2s1m1_sdo3 */
+- <0 RK_PD5 1 &pcfg_pull_none>;
+- };
+- };
+-
+- i2s2 {
+- /omit-if-no-ref/
+- i2s2m0_lrck: i2s2m0-lrck {
+- rockchip,pins =
+- /* i2s2m0_lrck */
+- <2 RK_PC0 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s2m0_mclk: i2s2m0-mclk {
+- rockchip,pins =
+- /* i2s2m0_mclk */
+- <2 RK_PB6 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s2m0_sclk: i2s2m0-sclk {
+- rockchip,pins =
+- /* i2s2m0_sclk */
+- <2 RK_PB7 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s2m0_sdi: i2s2m0-sdi {
+- rockchip,pins =
+- /* i2s2m0_sdi */
+- <2 RK_PC3 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s2m0_sdo: i2s2m0-sdo {
+- rockchip,pins =
+- /* i2s2m0_sdo */
+- <4 RK_PC3 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s2m1_lrck: i2s2m1-lrck {
+- rockchip,pins =
+- /* i2s2m1_lrck */
+- <3 RK_PB6 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s2m1_mclk: i2s2m1-mclk {
+- rockchip,pins =
+- /* i2s2m1_mclk */
+- <3 RK_PB4 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s2m1_sclk: i2s2m1-sclk {
+- rockchip,pins =
+- /* i2s2m1_sclk */
+- <3 RK_PB5 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s2m1_sdi: i2s2m1-sdi {
+- rockchip,pins =
+- /* i2s2m1_sdi */
+- <3 RK_PB2 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s2m1_sdo: i2s2m1-sdo {
+- rockchip,pins =
+- /* i2s2m1_sdo */
+- <3 RK_PB3 3 &pcfg_pull_none>;
+- };
+- };
+-
+- i2s3 {
+- /omit-if-no-ref/
+- i2s3_lrck: i2s3-lrck {
+- rockchip,pins =
+- /* i2s3_lrck */
+- <3 RK_PA2 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s3_mclk: i2s3-mclk {
+- rockchip,pins =
+- /* i2s3_mclk */
+- <3 RK_PA0 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s3_sclk: i2s3-sclk {
+- rockchip,pins =
+- /* i2s3_sclk */
+- <3 RK_PA1 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s3_sdi: i2s3-sdi {
+- rockchip,pins =
+- /* i2s3_sdi */
+- <3 RK_PA4 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- i2s3_sdo: i2s3-sdo {
+- rockchip,pins =
+- /* i2s3_sdo */
+- <3 RK_PA3 3 &pcfg_pull_none>;
+- };
+- };
+-
+- jtag {
+- /omit-if-no-ref/
+- jtagm0_pins: jtagm0-pins {
+- rockchip,pins =
+- /* jtag_tck_m0 */
+- <4 RK_PD2 5 &pcfg_pull_none>,
+- /* jtag_tms_m0 */
+- <4 RK_PD3 5 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- jtagm1_pins: jtagm1-pins {
+- rockchip,pins =
+- /* jtag_tck_m1 */
+- <4 RK_PD0 5 &pcfg_pull_none>,
+- /* jtag_tms_m1 */
+- <4 RK_PD1 5 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- jtagm2_pins: jtagm2-pins {
+- rockchip,pins =
+- /* jtag_tck_m2 */
+- <0 RK_PB5 2 &pcfg_pull_none>,
+- /* jtag_tms_m2 */
+- <0 RK_PB6 2 &pcfg_pull_none>;
+- };
+- };
+-
+- litcpu {
+- /omit-if-no-ref/
+- litcpu_pins: litcpu-pins {
+- rockchip,pins =
+- /* litcpu_avs */
+- <0 RK_PD3 1 &pcfg_pull_none>;
+- };
+- };
+-
+- mcu {
+- /omit-if-no-ref/
+- mcum0_pins: mcum0-pins {
+- rockchip,pins =
+- /* mcu_jtag_tck_m0 */
+- <4 RK_PD4 5 &pcfg_pull_none>,
+- /* mcu_jtag_tms_m0 */
+- <4 RK_PD5 5 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- mcum1_pins: mcum1-pins {
+- rockchip,pins =
+- /* mcu_jtag_tck_m1 */
+- <3 RK_PD4 6 &pcfg_pull_none>,
+- /* mcu_jtag_tms_m1 */
+- <3 RK_PD5 6 &pcfg_pull_none>;
+- };
+- };
+-
+- mipi {
+- /omit-if-no-ref/
+- mipim0_camera0_clk: mipim0-camera0-clk {
+- rockchip,pins =
+- /* mipim0_camera0_clk */
+- <4 RK_PB1 1 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- mipim0_camera1_clk: mipim0-camera1-clk {
+- rockchip,pins =
+- /* mipim0_camera1_clk */
+- <1 RK_PB6 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- mipim0_camera2_clk: mipim0-camera2-clk {
+- rockchip,pins =
+- /* mipim0_camera2_clk */
+- <1 RK_PB7 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- mipim0_camera3_clk: mipim0-camera3-clk {
+- rockchip,pins =
+- /* mipim0_camera3_clk */
+- <1 RK_PD6 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- mipim0_camera4_clk: mipim0-camera4-clk {
+- rockchip,pins =
+- /* mipim0_camera4_clk */
+- <1 RK_PD7 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- mipim1_camera0_clk: mipim1-camera0-clk {
+- rockchip,pins =
+- /* mipim1_camera0_clk */
+- <3 RK_PA5 4 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- mipim1_camera1_clk: mipim1-camera1-clk {
+- rockchip,pins =
+- /* mipim1_camera1_clk */
+- <3 RK_PA6 4 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- mipim1_camera2_clk: mipim1-camera2-clk {
+- rockchip,pins =
+- /* mipim1_camera2_clk */
+- <3 RK_PA7 4 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- mipim1_camera3_clk: mipim1-camera3-clk {
+- rockchip,pins =
+- /* mipim1_camera3_clk */
+- <3 RK_PB0 4 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- mipim1_camera4_clk: mipim1-camera4-clk {
+- rockchip,pins =
+- /* mipim1_camera4_clk */
+- <3 RK_PB1 4 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- mipi_te0: mipi-te0 {
+- rockchip,pins =
+- /* mipi_te0 */
+- <3 RK_PC2 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- mipi_te1: mipi-te1 {
+- rockchip,pins =
+- /* mipi_te1 */
+- <3 RK_PC3 2 &pcfg_pull_none>;
+- };
+- };
+-
+- npu {
+- /omit-if-no-ref/
+- npu_pins: npu-pins {
+- rockchip,pins =
+- /* npu_avs */
+- <0 RK_PC6 2 &pcfg_pull_none>;
+- };
+- };
+-
+- pcie20x1 {
+- /omit-if-no-ref/
+- pcie20x1m0_pins: pcie20x1m0-pins {
+- rockchip,pins =
+- /* pcie20x1_2_clkreqn_m0 */
+- <3 RK_PC7 4 &pcfg_pull_none>,
+- /* pcie20x1_2_perstn_m0 */
+- <3 RK_PD1 4 &pcfg_pull_none>,
+- /* pcie20x1_2_waken_m0 */
+- <3 RK_PD0 4 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pcie20x1m1_pins: pcie20x1m1-pins {
+- rockchip,pins =
+- /* pcie20x1_2_clkreqn_m1 */
+- <4 RK_PB7 4 &pcfg_pull_none>,
+- /* pcie20x1_2_perstn_m1 */
+- <4 RK_PC1 4 &pcfg_pull_none>,
+- /* pcie20x1_2_waken_m1 */
+- <4 RK_PC0 4 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pcie20x1_2_button_rstn: pcie20x1-2-button-rstn {
+- rockchip,pins =
+- /* pcie20x1_2_button_rstn */
+- <4 RK_PB3 4 &pcfg_pull_none>;
+- };
+- };
+-
+- pcie30phy {
+- /omit-if-no-ref/
+- pcie30phy_pins: pcie30phy-pins {
+- rockchip,pins =
+- /* pcie30phy_dtb0 */
+- <1 RK_PC4 4 &pcfg_pull_none>,
+- /* pcie30phy_dtb1 */
+- <1 RK_PD1 4 &pcfg_pull_none>;
+- };
+- };
+-
+- pcie30x1 {
+- /omit-if-no-ref/
+- pcie30x1m0_pins: pcie30x1m0-pins {
+- rockchip,pins =
+- /* pcie30x1_0_clkreqn_m0 */
+- <0 RK_PC0 12 &pcfg_pull_none>,
+- /* pcie30x1_0_perstn_m0 */
+- <0 RK_PC5 12 &pcfg_pull_none>,
+- /* pcie30x1_0_waken_m0 */
+- <0 RK_PC4 12 &pcfg_pull_none>,
+- /* pcie30x1_1_clkreqn_m0 */
+- <0 RK_PB5 12 &pcfg_pull_none>,
+- /* pcie30x1_1_perstn_m0 */
+- <0 RK_PB7 12 &pcfg_pull_none>,
+- /* pcie30x1_1_waken_m0 */
+- <0 RK_PB6 12 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pcie30x1m1_pins: pcie30x1m1-pins {
+- rockchip,pins =
+- /* pcie30x1_0_clkreqn_m1 */
+- <4 RK_PA3 4 &pcfg_pull_none>,
+- /* pcie30x1_0_perstn_m1 */
+- <4 RK_PA5 4 &pcfg_pull_none>,
+- /* pcie30x1_0_waken_m1 */
+- <4 RK_PA4 4 &pcfg_pull_none>,
+- /* pcie30x1_1_clkreqn_m1 */
+- <4 RK_PA0 4 &pcfg_pull_none>,
+- /* pcie30x1_1_perstn_m1 */
+- <4 RK_PA2 4 &pcfg_pull_none>,
+- /* pcie30x1_1_waken_m1 */
+- <4 RK_PA1 4 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pcie30x1m2_pins: pcie30x1m2-pins {
+- rockchip,pins =
+- /* pcie30x1_0_clkreqn_m2 */
+- <1 RK_PB5 4 &pcfg_pull_none>,
+- /* pcie30x1_0_perstn_m2 */
+- <1 RK_PB4 4 &pcfg_pull_none>,
+- /* pcie30x1_0_waken_m2 */
+- <1 RK_PB3 4 &pcfg_pull_none>,
+- /* pcie30x1_1_clkreqn_m2 */
+- <1 RK_PA0 4 &pcfg_pull_none>,
+- /* pcie30x1_1_perstn_m2 */
+- <1 RK_PA7 4 &pcfg_pull_none>,
+- /* pcie30x1_1_waken_m2 */
+- <1 RK_PA1 4 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pcie30x1_0_button_rstn: pcie30x1-0-button-rstn {
+- rockchip,pins =
+- /* pcie30x1_0_button_rstn */
+- <4 RK_PB1 4 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pcie30x1_1_button_rstn: pcie30x1-1-button-rstn {
+- rockchip,pins =
+- /* pcie30x1_1_button_rstn */
+- <4 RK_PB2 4 &pcfg_pull_none>;
+- };
+- };
+-
+- pcie30x2 {
+- /omit-if-no-ref/
+- pcie30x2m0_pins: pcie30x2m0-pins {
+- rockchip,pins =
+- /* pcie30x2_clkreqn_m0 */
+- <0 RK_PD1 12 &pcfg_pull_none>,
+- /* pcie30x2_perstn_m0 */
+- <0 RK_PD4 12 &pcfg_pull_none>,
+- /* pcie30x2_waken_m0 */
+- <0 RK_PD2 12 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pcie30x2m1_pins: pcie30x2m1-pins {
+- rockchip,pins =
+- /* pcie30x2_clkreqn_m1 */
+- <4 RK_PA6 4 &pcfg_pull_none>,
+- /* pcie30x2_perstn_m1 */
+- <4 RK_PB0 4 &pcfg_pull_none>,
+- /* pcie30x2_waken_m1 */
+- <4 RK_PA7 4 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pcie30x2m2_pins: pcie30x2m2-pins {
+- rockchip,pins =
+- /* pcie30x2_clkreqn_m2 */
+- <3 RK_PD2 4 &pcfg_pull_none>,
+- /* pcie30x2_perstn_m2 */
+- <3 RK_PD4 4 &pcfg_pull_none>,
+- /* pcie30x2_waken_m2 */
+- <3 RK_PD3 4 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pcie30x2m3_pins: pcie30x2m3-pins {
+- rockchip,pins =
+- /* pcie30x2_clkreqn_m3 */
+- <1 RK_PD7 4 &pcfg_pull_none>,
+- /* pcie30x2_perstn_m3 */
+- <1 RK_PB7 4 &pcfg_pull_none>,
+- /* pcie30x2_waken_m3 */
+- <1 RK_PB6 4 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pcie30x2_button_rstn: pcie30x2-button-rstn {
+- rockchip,pins =
+- /* pcie30x2_button_rstn */
+- <3 RK_PC1 4 &pcfg_pull_none>;
+- };
+- };
+-
+- pcie30x4 {
+- /omit-if-no-ref/
+- pcie30x4m0_pins: pcie30x4m0-pins {
+- rockchip,pins =
+- /* pcie30x4_clkreqn_m0 */
+- <0 RK_PC6 12 &pcfg_pull_none>,
+- /* pcie30x4_perstn_m0 */
+- <0 RK_PD0 12 &pcfg_pull_none>,
+- /* pcie30x4_waken_m0 */
+- <0 RK_PC7 12 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pcie30x4m1_pins: pcie30x4m1-pins {
+- rockchip,pins =
+- /* pcie30x4_clkreqn_m1 */
+- <4 RK_PB4 4 &pcfg_pull_none>,
+- /* pcie30x4_perstn_m1 */
+- <4 RK_PB6 4 &pcfg_pull_none>,
+- /* pcie30x4_waken_m1 */
+- <4 RK_PB5 4 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pcie30x4m2_pins: pcie30x4m2-pins {
+- rockchip,pins =
+- /* pcie30x4_clkreqn_m2 */
+- <3 RK_PC4 4 &pcfg_pull_none>,
+- /* pcie30x4_perstn_m2 */
+- <3 RK_PC6 4 &pcfg_pull_none>,
+- /* pcie30x4_waken_m2 */
+- <3 RK_PC5 4 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pcie30x4m3_pins: pcie30x4m3-pins {
+- rockchip,pins =
+- /* pcie30x4_clkreqn_m3 */
+- <1 RK_PB0 4 &pcfg_pull_none>,
+- /* pcie30x4_perstn_m3 */
+- <1 RK_PB2 4 &pcfg_pull_none>,
+- /* pcie30x4_waken_m3 */
+- <1 RK_PB1 4 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pcie30x4_button_rstn: pcie30x4-button-rstn {
+- rockchip,pins =
+- /* pcie30x4_button_rstn */
+- <3 RK_PD5 4 &pcfg_pull_none>;
+- };
+- };
+-
+- pdm0 {
+- /omit-if-no-ref/
+- pdm0m0_clk: pdm0m0-clk {
+- rockchip,pins =
+- /* pdm0_clk0_m0 */
+- <1 RK_PC6 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pdm0m0_clk1: pdm0m0-clk1 {
+- rockchip,pins =
+- /* pdm0m0_clk1 */
+- <1 RK_PC4 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pdm0m0_sdi0: pdm0m0-sdi0 {
+- rockchip,pins =
+- /* pdm0m0_sdi0 */
+- <1 RK_PD5 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pdm0m0_sdi1: pdm0m0-sdi1 {
+- rockchip,pins =
+- /* pdm0m0_sdi1 */
+- <1 RK_PD1 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pdm0m0_sdi2: pdm0m0-sdi2 {
+- rockchip,pins =
+- /* pdm0m0_sdi2 */
+- <1 RK_PD2 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pdm0m0_sdi3: pdm0m0-sdi3 {
+- rockchip,pins =
+- /* pdm0m0_sdi3 */
+- <1 RK_PD3 3 &pcfg_pull_none>;
+- };
+- /omit-if-no-ref/
+- pdm0m1_clk: pdm0m1-clk {
+- rockchip,pins =
+- /* pdm0_clk0_m1 */
+- <0 RK_PC0 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pdm0m1_clk1: pdm0m1-clk1 {
+- rockchip,pins =
+- /* pdm0m1_clk1 */
+- <0 RK_PC4 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pdm0m1_sdi0: pdm0m1-sdi0 {
+- rockchip,pins =
+- /* pdm0m1_sdi0 */
+- <0 RK_PC7 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pdm0m1_sdi1: pdm0m1-sdi1 {
+- rockchip,pins =
+- /* pdm0m1_sdi1 */
+- <0 RK_PD0 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pdm0m1_sdi2: pdm0m1-sdi2 {
+- rockchip,pins =
+- /* pdm0m1_sdi2 */
+- <0 RK_PD4 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pdm0m1_sdi3: pdm0m1-sdi3 {
+- rockchip,pins =
+- /* pdm0m1_sdi3 */
+- <0 RK_PD6 2 &pcfg_pull_none>;
+- };
+- };
+-
+- pdm1 {
+- /omit-if-no-ref/
+- pdm1m0_clk: pdm1m0-clk {
+- rockchip,pins =
+- /* pdm1_clk0_m0 */
+- <4 RK_PD5 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pdm1m0_clk1: pdm1m0-clk1 {
+- rockchip,pins =
+- /* pdm1m0_clk1 */
+- <4 RK_PD4 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pdm1m0_sdi0: pdm1m0-sdi0 {
+- rockchip,pins =
+- /* pdm1m0_sdi0 */
+- <4 RK_PD3 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pdm1m0_sdi1: pdm1m0-sdi1 {
+- rockchip,pins =
+- /* pdm1m0_sdi1 */
+- <4 RK_PD2 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pdm1m0_sdi2: pdm1m0-sdi2 {
+- rockchip,pins =
+- /* pdm1m0_sdi2 */
+- <4 RK_PD1 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pdm1m0_sdi3: pdm1m0-sdi3 {
+- rockchip,pins =
+- /* pdm1m0_sdi3 */
+- <4 RK_PD0 2 &pcfg_pull_none>;
+- };
+- /omit-if-no-ref/
+- pdm1m1_clk: pdm1m1-clk {
+- rockchip,pins =
+- /* pdm1_clk0_m1 */
+- <1 RK_PB4 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pdm1m1_clk1: pdm1m1-clk1 {
+- rockchip,pins =
+- /* pdm1m1_clk1 */
+- <1 RK_PB3 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pdm1m1_sdi0: pdm1m1-sdi0 {
+- rockchip,pins =
+- /* pdm1m1_sdi0 */
+- <1 RK_PA7 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pdm1m1_sdi1: pdm1m1-sdi1 {
+- rockchip,pins =
+- /* pdm1m1_sdi1 */
+- <1 RK_PB0 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pdm1m1_sdi2: pdm1m1-sdi2 {
+- rockchip,pins =
+- /* pdm1m1_sdi2 */
+- <1 RK_PB1 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pdm1m1_sdi3: pdm1m1-sdi3 {
+- rockchip,pins =
+- /* pdm1m1_sdi3 */
+- <1 RK_PB2 2 &pcfg_pull_none>;
+- };
+- };
+-
+- pmic {
+- /omit-if-no-ref/
+- pmic_pins: pmic-pins {
+- rockchip,pins =
+- /* pmic_int_l */
+- <0 RK_PA7 0 &pcfg_pull_up>,
+- /* pmic_sleep1 */
+- <0 RK_PA2 1 &pcfg_pull_none>,
+- /* pmic_sleep2 */
+- <0 RK_PA3 1 &pcfg_pull_none>,
+- /* pmic_sleep3 */
+- <0 RK_PC1 1 &pcfg_pull_none>,
+- /* pmic_sleep4 */
+- <0 RK_PC2 1 &pcfg_pull_none>,
+- /* pmic_sleep5 */
+- <0 RK_PC3 1 &pcfg_pull_none>,
+- /* pmic_sleep6 */
+- <0 RK_PD6 1 &pcfg_pull_none>;
+- };
+- };
+-
+- pmu {
+- /omit-if-no-ref/
+- pmu_pins: pmu-pins {
+- rockchip,pins =
+- /* pmu_debug */
+- <0 RK_PA5 3 &pcfg_pull_none>;
+- };
+- };
+-
+- pwm0 {
+- /omit-if-no-ref/
+- pwm0m0_pins: pwm0m0-pins {
+- rockchip,pins =
+- /* pwm0_m0 */
+- <0 RK_PB7 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pwm0m1_pins: pwm0m1-pins {
+- rockchip,pins =
+- /* pwm0_m1 */
+- <1 RK_PD2 11 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pwm0m2_pins: pwm0m2-pins {
+- rockchip,pins =
+- /* pwm0_m2 */
+- <1 RK_PA2 11 &pcfg_pull_none>;
+- };
+- };
+-
+- pwm1 {
+- /omit-if-no-ref/
+- pwm1m0_pins: pwm1m0-pins {
+- rockchip,pins =
+- /* pwm1_m0 */
+- <0 RK_PC0 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pwm1m1_pins: pwm1m1-pins {
+- rockchip,pins =
+- /* pwm1_m1 */
+- <1 RK_PD3 11 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pwm1m2_pins: pwm1m2-pins {
+- rockchip,pins =
+- /* pwm1_m2 */
+- <1 RK_PA3 11 &pcfg_pull_none>;
+- };
+- };
+-
+- pwm2 {
+- /omit-if-no-ref/
+- pwm2m0_pins: pwm2m0-pins {
+- rockchip,pins =
+- /* pwm2_m0 */
+- <0 RK_PC4 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pwm2m1_pins: pwm2m1-pins {
+- rockchip,pins =
+- /* pwm2_m1 */
+- <3 RK_PB1 11 &pcfg_pull_none>;
+- };
+- };
+-
+- pwm3 {
+- /omit-if-no-ref/
+- pwm3m0_pins: pwm3m0-pins {
+- rockchip,pins =
+- /* pwm3_ir_m0 */
+- <0 RK_PD4 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pwm3m1_pins: pwm3m1-pins {
+- rockchip,pins =
+- /* pwm3_ir_m1 */
+- <3 RK_PB2 11 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pwm3m2_pins: pwm3m2-pins {
+- rockchip,pins =
+- /* pwm3_ir_m2 */
+- <1 RK_PC2 11 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pwm3m3_pins: pwm3m3-pins {
+- rockchip,pins =
+- /* pwm3_ir_m3 */
+- <1 RK_PA7 11 &pcfg_pull_none>;
+- };
+- };
+-
+- pwm4 {
+- /omit-if-no-ref/
+- pwm4m0_pins: pwm4m0-pins {
+- rockchip,pins =
+- /* pwm4_m0 */
+- <0 RK_PC5 11 &pcfg_pull_none>;
+- };
+- };
+-
+- pwm5 {
+- /omit-if-no-ref/
+- pwm5m0_pins: pwm5m0-pins {
+- rockchip,pins =
+- /* pwm5_m0 */
+- <0 RK_PB1 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pwm5m1_pins: pwm5m1-pins {
+- rockchip,pins =
+- /* pwm5_m1 */
+- <0 RK_PC6 11 &pcfg_pull_none>;
+- };
+- };
+-
+- pwm6 {
+- /omit-if-no-ref/
+- pwm6m0_pins: pwm6m0-pins {
+- rockchip,pins =
+- /* pwm6_m0 */
+- <0 RK_PC7 11 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pwm6m1_pins: pwm6m1-pins {
+- rockchip,pins =
+- /* pwm6_m1 */
+- <4 RK_PC1 11 &pcfg_pull_none>;
+- };
+- };
+-
+- pwm7 {
+- /omit-if-no-ref/
+- pwm7m0_pins: pwm7m0-pins {
+- rockchip,pins =
+- /* pwm7_ir_m0 */
+- <0 RK_PD0 11 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pwm7m1_pins: pwm7m1-pins {
+- rockchip,pins =
+- /* pwm7_ir_m1 */
+- <4 RK_PD4 11 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pwm7m2_pins: pwm7m2-pins {
+- rockchip,pins =
+- /* pwm7_ir_m2 */
+- <1 RK_PC3 11 &pcfg_pull_none>;
+- };
+- };
+-
+- pwm8 {
+- /omit-if-no-ref/
+- pwm8m0_pins: pwm8m0-pins {
+- rockchip,pins =
+- /* pwm8_m0 */
+- <3 RK_PA7 11 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pwm8m1_pins: pwm8m1-pins {
+- rockchip,pins =
+- /* pwm8_m1 */
+- <4 RK_PD0 11 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pwm8m2_pins: pwm8m2-pins {
+- rockchip,pins =
+- /* pwm8_m2 */
+- <3 RK_PD0 11 &pcfg_pull_none>;
+- };
+- };
+-
+- pwm9 {
+- /omit-if-no-ref/
+- pwm9m0_pins: pwm9m0-pins {
+- rockchip,pins =
+- /* pwm9_m0 */
+- <3 RK_PB0 11 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pwm9m1_pins: pwm9m1-pins {
+- rockchip,pins =
+- /* pwm9_m1 */
+- <4 RK_PD1 11 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pwm9m2_pins: pwm9m2-pins {
+- rockchip,pins =
+- /* pwm9_m2 */
+- <3 RK_PD1 11 &pcfg_pull_none>;
+- };
+- };
+-
+- pwm10 {
+- /omit-if-no-ref/
+- pwm10m0_pins: pwm10m0-pins {
+- rockchip,pins =
+- /* pwm10_m0 */
+- <3 RK_PA0 11 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pwm10m1_pins: pwm10m1-pins {
+- rockchip,pins =
+- /* pwm10_m1 */
+- <4 RK_PD3 11 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pwm10m2_pins: pwm10m2-pins {
+- rockchip,pins =
+- /* pwm10_m2 */
+- <3 RK_PD3 11 &pcfg_pull_none>;
+- };
+- };
+-
+- pwm11 {
+- /omit-if-no-ref/
+- pwm11m0_pins: pwm11m0-pins {
+- rockchip,pins =
+- /* pwm11_ir_m0 */
+- <3 RK_PA1 11 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pwm11m1_pins: pwm11m1-pins {
+- rockchip,pins =
+- /* pwm11_ir_m1 */
+- <4 RK_PB4 11 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pwm11m2_pins: pwm11m2-pins {
+- rockchip,pins =
+- /* pwm11_ir_m2 */
+- <1 RK_PC4 11 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pwm11m3_pins: pwm11m3-pins {
+- rockchip,pins =
+- /* pwm11_ir_m3 */
+- <3 RK_PD5 11 &pcfg_pull_none>;
+- };
+- };
+-
+- pwm12 {
+- /omit-if-no-ref/
+- pwm12m0_pins: pwm12m0-pins {
+- rockchip,pins =
+- /* pwm12_m0 */
+- <3 RK_PB5 11 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pwm12m1_pins: pwm12m1-pins {
+- rockchip,pins =
+- /* pwm12_m1 */
+- <4 RK_PB5 11 &pcfg_pull_none>;
+- };
+- };
+-
+- pwm13 {
+- /omit-if-no-ref/
+- pwm13m0_pins: pwm13m0-pins {
+- rockchip,pins =
+- /* pwm13_m0 */
+- <3 RK_PB6 11 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pwm13m1_pins: pwm13m1-pins {
+- rockchip,pins =
+- /* pwm13_m1 */
+- <4 RK_PB6 11 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pwm13m2_pins: pwm13m2-pins {
+- rockchip,pins =
+- /* pwm13_m2 */
+- <1 RK_PB7 11 &pcfg_pull_none>;
+- };
+- };
+-
+- pwm14 {
+- /omit-if-no-ref/
+- pwm14m0_pins: pwm14m0-pins {
+- rockchip,pins =
+- /* pwm14_m0 */
+- <3 RK_PC2 11 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pwm14m1_pins: pwm14m1-pins {
+- rockchip,pins =
+- /* pwm14_m1 */
+- <4 RK_PB2 11 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pwm14m2_pins: pwm14m2-pins {
+- rockchip,pins =
+- /* pwm14_m2 */
+- <1 RK_PD6 11 &pcfg_pull_none>;
+- };
+- };
+-
+- pwm15 {
+- /omit-if-no-ref/
+- pwm15m0_pins: pwm15m0-pins {
+- rockchip,pins =
+- /* pwm15_ir_m0 */
+- <3 RK_PC3 11 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pwm15m1_pins: pwm15m1-pins {
+- rockchip,pins =
+- /* pwm15_ir_m1 */
+- <4 RK_PB3 11 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pwm15m2_pins: pwm15m2-pins {
+- rockchip,pins =
+- /* pwm15_ir_m2 */
+- <1 RK_PC6 11 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- pwm15m3_pins: pwm15m3-pins {
+- rockchip,pins =
+- /* pwm15_ir_m3 */
+- <1 RK_PD7 11 &pcfg_pull_none>;
+- };
+- };
+-
+- refclk {
+- /omit-if-no-ref/
+- refclk_pins: refclk-pins {
+- rockchip,pins =
+- /* refclk_out */
+- <0 RK_PA0 1 &pcfg_pull_none>;
+- };
+- };
+-
+- sata {
+- /omit-if-no-ref/
+- sata_pins: sata-pins {
+- rockchip,pins =
+- /* sata_cp_pod */
+- <0 RK_PC6 13 &pcfg_pull_none>,
+- /* sata_cpdet */
+- <0 RK_PD4 13 &pcfg_pull_none>,
+- /* sata_mp_switch */
+- <0 RK_PD5 13 &pcfg_pull_none>;
+- };
+- };
+-
+- sata0 {
+- /omit-if-no-ref/
+- sata0m0_pins: sata0m0-pins {
+- rockchip,pins =
+- /* sata0_act_led_m0 */
+- <4 RK_PB6 6 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- sata0m1_pins: sata0m1-pins {
+- rockchip,pins =
+- /* sata0_act_led_m1 */
+- <1 RK_PB3 6 &pcfg_pull_none>;
+- };
+- };
+-
+- sata1 {
+- /omit-if-no-ref/
+- sata1m0_pins: sata1m0-pins {
+- rockchip,pins =
+- /* sata1_act_led_m0 */
+- <4 RK_PB5 6 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- sata1m1_pins: sata1m1-pins {
+- rockchip,pins =
+- /* sata1_act_led_m1 */
+- <1 RK_PA1 6 &pcfg_pull_none>;
+- };
+- };
+-
+- sata2 {
+- /omit-if-no-ref/
+- sata2m0_pins: sata2m0-pins {
+- rockchip,pins =
+- /* sata2_act_led_m0 */
+- <4 RK_PB1 6 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- sata2m1_pins: sata2m1-pins {
+- rockchip,pins =
+- /* sata2_act_led_m1 */
+- <1 RK_PB7 6 &pcfg_pull_none>;
+- };
+- };
+-
+- sdio {
+- /omit-if-no-ref/
+- sdiom1_pins: sdiom1-pins {
+- rockchip,pins =
+- /* sdio_clk_m1 */
+- <3 RK_PA5 2 &pcfg_pull_none>,
+- /* sdio_cmd_m1 */
+- <3 RK_PA4 2 &pcfg_pull_none>,
+- /* sdio_d0_m1 */
+- <3 RK_PA0 2 &pcfg_pull_none>,
+- /* sdio_d1_m1 */
+- <3 RK_PA1 2 &pcfg_pull_none>,
+- /* sdio_d2_m1 */
+- <3 RK_PA2 2 &pcfg_pull_none>,
+- /* sdio_d3_m1 */
+- <3 RK_PA3 2 &pcfg_pull_none>;
+- };
+- };
+-
+- sdmmc {
+- /omit-if-no-ref/
+- sdmmc_bus4: sdmmc-bus4 {
+- rockchip,pins =
+- /* sdmmc_d0 */
+- <4 RK_PD0 1 &pcfg_pull_up_drv_level_2>,
+- /* sdmmc_d1 */
+- <4 RK_PD1 1 &pcfg_pull_up_drv_level_2>,
+- /* sdmmc_d2 */
+- <4 RK_PD2 1 &pcfg_pull_up_drv_level_2>,
+- /* sdmmc_d3 */
+- <4 RK_PD3 1 &pcfg_pull_up_drv_level_2>;
+- };
+-
+- /omit-if-no-ref/
+- sdmmc_clk: sdmmc-clk {
+- rockchip,pins =
+- /* sdmmc_clk */
+- <4 RK_PD5 1 &pcfg_pull_up_drv_level_2>;
+- };
+-
+- /omit-if-no-ref/
+- sdmmc_cmd: sdmmc-cmd {
+- rockchip,pins =
+- /* sdmmc_cmd */
+- <4 RK_PD4 1 &pcfg_pull_up_drv_level_2>;
+- };
+-
+- /omit-if-no-ref/
+- sdmmc_det: sdmmc-det {
+- rockchip,pins =
+- /* sdmmc_det */
+- <0 RK_PA4 1 &pcfg_pull_up>;
+- };
+-
+- /omit-if-no-ref/
+- sdmmc_pwren: sdmmc-pwren {
+- rockchip,pins =
+- /* sdmmc_pwren */
+- <0 RK_PA5 2 &pcfg_pull_none>;
+- };
+- };
+-
+- spdif0 {
+- /omit-if-no-ref/
+- spdif0m0_tx: spdif0m0-tx {
+- rockchip,pins =
+- /* spdif0m0_tx */
+- <1 RK_PB6 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- spdif0m1_tx: spdif0m1-tx {
+- rockchip,pins =
+- /* spdif0m1_tx */
+- <4 RK_PB4 6 &pcfg_pull_none>;
+- };
+- };
+-
+- spdif1 {
+- /omit-if-no-ref/
+- spdif1m0_tx: spdif1m0-tx {
+- rockchip,pins =
+- /* spdif1m0_tx */
+- <1 RK_PB7 3 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- spdif1m1_tx: spdif1m1-tx {
+- rockchip,pins =
+- /* spdif1m1_tx */
+- <4 RK_PB1 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- spdif1m2_tx: spdif1m2-tx {
+- rockchip,pins =
+- /* spdif1m2_tx */
+- <4 RK_PC1 3 &pcfg_pull_none>;
+- };
+- };
+-
+- spi0 {
+- /omit-if-no-ref/
+- spi0m0_pins: spi0m0-pins {
+- rockchip,pins =
+- /* spi0_clk_m0 */
+- <0 RK_PC6 8 &pcfg_pull_up_drv_level_1>,
+- /* spi0_miso_m0 */
+- <0 RK_PC7 8 &pcfg_pull_up_drv_level_1>,
+- /* spi0_mosi_m0 */
+- <0 RK_PC0 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi0m0_cs0: spi0m0-cs0 {
+- rockchip,pins =
+- /* spi0_cs0_m0 */
+- <0 RK_PD1 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi0m0_cs1: spi0m0-cs1 {
+- rockchip,pins =
+- /* spi0_cs1_m0 */
+- <0 RK_PB7 8 &pcfg_pull_up_drv_level_1>;
+- };
+- /omit-if-no-ref/
+- spi0m1_pins: spi0m1-pins {
+- rockchip,pins =
+- /* spi0_clk_m1 */
+- <4 RK_PA2 8 &pcfg_pull_up_drv_level_1>,
+- /* spi0_miso_m1 */
+- <4 RK_PA0 8 &pcfg_pull_up_drv_level_1>,
+- /* spi0_mosi_m1 */
+- <4 RK_PA1 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi0m1_cs0: spi0m1-cs0 {
+- rockchip,pins =
+- /* spi0_cs0_m1 */
+- <4 RK_PB2 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi0m1_cs1: spi0m1-cs1 {
+- rockchip,pins =
+- /* spi0_cs1_m1 */
+- <4 RK_PB1 8 &pcfg_pull_up_drv_level_1>;
+- };
+- /omit-if-no-ref/
+- spi0m2_pins: spi0m2-pins {
+- rockchip,pins =
+- /* spi0_clk_m2 */
+- <1 RK_PB3 8 &pcfg_pull_up_drv_level_1>,
+- /* spi0_miso_m2 */
+- <1 RK_PB1 8 &pcfg_pull_up_drv_level_1>,
+- /* spi0_mosi_m2 */
+- <1 RK_PB2 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi0m2_cs0: spi0m2-cs0 {
+- rockchip,pins =
+- /* spi0_cs0_m2 */
+- <1 RK_PB4 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi0m2_cs1: spi0m2-cs1 {
+- rockchip,pins =
+- /* spi0_cs1_m2 */
+- <1 RK_PB5 8 &pcfg_pull_up_drv_level_1>;
+- };
+- /omit-if-no-ref/
+- spi0m3_pins: spi0m3-pins {
+- rockchip,pins =
+- /* spi0_clk_m3 */
+- <3 RK_PD3 8 &pcfg_pull_up_drv_level_1>,
+- /* spi0_miso_m3 */
+- <3 RK_PD1 8 &pcfg_pull_up_drv_level_1>,
+- /* spi0_mosi_m3 */
+- <3 RK_PD2 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi0m3_cs0: spi0m3-cs0 {
+- rockchip,pins =
+- /* spi0_cs0_m3 */
+- <3 RK_PD4 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi0m3_cs1: spi0m3-cs1 {
+- rockchip,pins =
+- /* spi0_cs1_m3 */
+- <3 RK_PD5 8 &pcfg_pull_up_drv_level_1>;
+- };
+- };
+-
+- spi1 {
+- /omit-if-no-ref/
+- spi1m1_pins: spi1m1-pins {
+- rockchip,pins =
+- /* spi1_clk_m1 */
+- <3 RK_PC1 8 &pcfg_pull_up_drv_level_1>,
+- /* spi1_miso_m1 */
+- <3 RK_PC0 8 &pcfg_pull_up_drv_level_1>,
+- /* spi1_mosi_m1 */
+- <3 RK_PB7 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi1m1_cs0: spi1m1-cs0 {
+- rockchip,pins =
+- /* spi1_cs0_m1 */
+- <3 RK_PC2 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi1m1_cs1: spi1m1-cs1 {
+- rockchip,pins =
+- /* spi1_cs1_m1 */
+- <3 RK_PC3 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi1m2_pins: spi1m2-pins {
+- rockchip,pins =
+- /* spi1_clk_m2 */
+- <1 RK_PD2 8 &pcfg_pull_up_drv_level_1>,
+- /* spi1_miso_m2 */
+- <1 RK_PD0 8 &pcfg_pull_up_drv_level_1>,
+- /* spi1_mosi_m2 */
+- <1 RK_PD1 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi1m2_cs0: spi1m2-cs0 {
+- rockchip,pins =
+- /* spi1_cs0_m2 */
+- <1 RK_PD3 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi1m2_cs1: spi1m2-cs1 {
+- rockchip,pins =
+- /* spi1_cs1_m2 */
+- <1 RK_PD5 8 &pcfg_pull_up_drv_level_1>;
+- };
+- };
+-
+- spi2 {
+- /omit-if-no-ref/
+- spi2m0_pins: spi2m0-pins {
+- rockchip,pins =
+- /* spi2_clk_m0 */
+- <1 RK_PA6 8 &pcfg_pull_up_drv_level_1>,
+- /* spi2_miso_m0 */
+- <1 RK_PA4 8 &pcfg_pull_up_drv_level_1>,
+- /* spi2_mosi_m0 */
+- <1 RK_PA5 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi2m0_cs0: spi2m0-cs0 {
+- rockchip,pins =
+- /* spi2_cs0_m0 */
+- <1 RK_PA7 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi2m0_cs1: spi2m0-cs1 {
+- rockchip,pins =
+- /* spi2_cs1_m0 */
+- <1 RK_PB0 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi2m1_pins: spi2m1-pins {
+- rockchip,pins =
+- /* spi2_clk_m1 */
+- <4 RK_PA6 8 &pcfg_pull_up_drv_level_1>,
+- /* spi2_miso_m1 */
+- <4 RK_PA4 8 &pcfg_pull_up_drv_level_1>,
+- /* spi2_mosi_m1 */
+- <4 RK_PA5 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi2m1_cs0: spi2m1-cs0 {
+- rockchip,pins =
+- /* spi2_cs0_m1 */
+- <4 RK_PA7 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi2m1_cs1: spi2m1-cs1 {
+- rockchip,pins =
+- /* spi2_cs1_m1 */
+- <4 RK_PB0 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi2m2_pins: spi2m2-pins {
+- rockchip,pins =
+- /* spi2_clk_m2 */
+- <0 RK_PA5 1 &pcfg_pull_up_drv_level_1>,
+- /* spi2_miso_m2 */
+- <0 RK_PB3 1 &pcfg_pull_up_drv_level_1>,
+- /* spi2_mosi_m2 */
+- <0 RK_PA6 1 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi2m2_cs0: spi2m2-cs0 {
+- rockchip,pins =
+- /* spi2_cs0_m2 */
+- <0 RK_PB1 1 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi2m2_cs1: spi2m2-cs1 {
+- rockchip,pins =
+- /* spi2_cs1_m2 */
+- <0 RK_PB0 1 &pcfg_pull_up_drv_level_1>;
+- };
+- };
+-
+- spi3 {
+- /omit-if-no-ref/
+- spi3m1_pins: spi3m1-pins {
+- rockchip,pins =
+- /* spi3_clk_m1 */
+- <4 RK_PB7 8 &pcfg_pull_up_drv_level_1>,
+- /* spi3_miso_m1 */
+- <4 RK_PB5 8 &pcfg_pull_up_drv_level_1>,
+- /* spi3_mosi_m1 */
+- <4 RK_PB6 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi3m1_cs0: spi3m1-cs0 {
+- rockchip,pins =
+- /* spi3_cs0_m1 */
+- <4 RK_PC0 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi3m1_cs1: spi3m1-cs1 {
+- rockchip,pins =
+- /* spi3_cs1_m1 */
+- <4 RK_PC1 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi3m2_pins: spi3m2-pins {
+- rockchip,pins =
+- /* spi3_clk_m2 */
+- <0 RK_PD3 8 &pcfg_pull_up_drv_level_1>,
+- /* spi3_miso_m2 */
+- <0 RK_PD0 8 &pcfg_pull_up_drv_level_1>,
+- /* spi3_mosi_m2 */
+- <0 RK_PD2 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi3m2_cs0: spi3m2-cs0 {
+- rockchip,pins =
+- /* spi3_cs0_m2 */
+- <0 RK_PD4 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi3m2_cs1: spi3m2-cs1 {
+- rockchip,pins =
+- /* spi3_cs1_m2 */
+- <0 RK_PD5 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi3m3_pins: spi3m3-pins {
+- rockchip,pins =
+- /* spi3_clk_m3 */
+- <3 RK_PD0 8 &pcfg_pull_up_drv_level_1>,
+- /* spi3_miso_m3 */
+- <3 RK_PC6 8 &pcfg_pull_up_drv_level_1>,
+- /* spi3_mosi_m3 */
+- <3 RK_PC7 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi3m3_cs0: spi3m3-cs0 {
+- rockchip,pins =
+- /* spi3_cs0_m3 */
+- <3 RK_PC4 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi3m3_cs1: spi3m3-cs1 {
+- rockchip,pins =
+- /* spi3_cs1_m3 */
+- <3 RK_PC5 8 &pcfg_pull_up_drv_level_1>;
+- };
+- };
+-
+- spi4 {
+- /omit-if-no-ref/
+- spi4m0_pins: spi4m0-pins {
+- rockchip,pins =
+- /* spi4_clk_m0 */
+- <1 RK_PC2 8 &pcfg_pull_up_drv_level_1>,
+- /* spi4_miso_m0 */
+- <1 RK_PC0 8 &pcfg_pull_up_drv_level_1>,
+- /* spi4_mosi_m0 */
+- <1 RK_PC1 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi4m0_cs0: spi4m0-cs0 {
+- rockchip,pins =
+- /* spi4_cs0_m0 */
+- <1 RK_PC3 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi4m0_cs1: spi4m0-cs1 {
+- rockchip,pins =
+- /* spi4_cs1_m0 */
+- <1 RK_PC4 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi4m1_pins: spi4m1-pins {
+- rockchip,pins =
+- /* spi4_clk_m1 */
+- <3 RK_PA2 8 &pcfg_pull_up_drv_level_1>,
+- /* spi4_miso_m1 */
+- <3 RK_PA0 8 &pcfg_pull_up_drv_level_1>,
+- /* spi4_mosi_m1 */
+- <3 RK_PA1 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi4m1_cs0: spi4m1-cs0 {
+- rockchip,pins =
+- /* spi4_cs0_m1 */
+- <3 RK_PA3 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi4m1_cs1: spi4m1-cs1 {
+- rockchip,pins =
+- /* spi4_cs1_m1 */
+- <3 RK_PA4 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi4m2_pins: spi4m2-pins {
+- rockchip,pins =
+- /* spi4_clk_m2 */
+- <1 RK_PA2 8 &pcfg_pull_up_drv_level_1>,
+- /* spi4_miso_m2 */
+- <1 RK_PA0 8 &pcfg_pull_up_drv_level_1>,
+- /* spi4_mosi_m2 */
+- <1 RK_PA1 8 &pcfg_pull_up_drv_level_1>;
+- };
+-
+- /omit-if-no-ref/
+- spi4m2_cs0: spi4m2-cs0 {
+- rockchip,pins =
+- /* spi4_cs0_m2 */
+- <1 RK_PA3 8 &pcfg_pull_up_drv_level_1>;
+- };
+- };
+-
+- tsadc {
+- /omit-if-no-ref/
+- tsadcm1_shut: tsadcm1-shut {
+- rockchip,pins =
+- /* tsadcm1_shut */
+- <0 RK_PA2 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- tsadc_shut: tsadc-shut {
+- rockchip,pins =
+- /* tsadc_shut */
+- <0 RK_PA1 2 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- tsadc_shut_org: tsadc-shut-org {
+- rockchip,pins =
+- /* tsadc_shut_org */
+- <0 RK_PA1 1 &pcfg_pull_none>;
+- };
+- };
+-
+- uart0 {
+- /omit-if-no-ref/
+- uart0m0_xfer: uart0m0-xfer {
+- rockchip,pins =
+- /* uart0_rx_m0 */
+- <0 RK_PC4 4 &pcfg_pull_up>,
+- /* uart0_tx_m0 */
+- <0 RK_PC5 4 &pcfg_pull_up>;
+- };
+-
+- /omit-if-no-ref/
+- uart0m1_xfer: uart0m1-xfer {
+- rockchip,pins =
+- /* uart0_rx_m1 */
+- <0 RK_PB0 4 &pcfg_pull_up>,
+- /* uart0_tx_m1 */
+- <0 RK_PB1 4 &pcfg_pull_up>;
+- };
+-
+- /omit-if-no-ref/
+- uart0m2_xfer: uart0m2-xfer {
+- rockchip,pins =
+- /* uart0_rx_m2 */
+- <4 RK_PA4 10 &pcfg_pull_up>,
+- /* uart0_tx_m2 */
+- <4 RK_PA3 10 &pcfg_pull_up>;
+- };
+-
+- /omit-if-no-ref/
+- uart0_ctsn: uart0-ctsn {
+- rockchip,pins =
+- /* uart0_ctsn */
+- <0 RK_PD1 4 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- uart0_rtsn: uart0-rtsn {
+- rockchip,pins =
+- /* uart0_rtsn */
+- <0 RK_PC6 4 &pcfg_pull_none>;
+- };
+- };
+-
+- uart1 {
+- /omit-if-no-ref/
+- uart1m1_xfer: uart1m1-xfer {
+- rockchip,pins =
+- /* uart1_rx_m1 */
+- <1 RK_PB7 10 &pcfg_pull_up>,
+- /* uart1_tx_m1 */
+- <1 RK_PB6 10 &pcfg_pull_up>;
+- };
+-
+- /omit-if-no-ref/
+- uart1m1_ctsn: uart1m1-ctsn {
+- rockchip,pins =
+- /* uart1m1_ctsn */
+- <1 RK_PD7 10 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- uart1m1_rtsn: uart1m1-rtsn {
+- rockchip,pins =
+- /* uart1m1_rtsn */
+- <1 RK_PD6 10 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- uart1m2_xfer: uart1m2-xfer {
+- rockchip,pins =
+- /* uart1_rx_m2 */
+- <0 RK_PD2 10 &pcfg_pull_up>,
+- /* uart1_tx_m2 */
+- <0 RK_PD1 10 &pcfg_pull_up>;
+- };
+-
+- /omit-if-no-ref/
+- uart1m2_ctsn: uart1m2-ctsn {
+- rockchip,pins =
+- /* uart1m2_ctsn */
+- <0 RK_PD0 10 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- uart1m2_rtsn: uart1m2-rtsn {
+- rockchip,pins =
+- /* uart1m2_rtsn */
+- <0 RK_PC7 10 &pcfg_pull_none>;
+- };
+- };
+-
+- uart2 {
+- /omit-if-no-ref/
+- uart2m0_xfer: uart2m0-xfer {
+- rockchip,pins =
+- /* uart2_rx_m0 */
+- <0 RK_PB6 10 &pcfg_pull_up>,
+- /* uart2_tx_m0 */
+- <0 RK_PB5 10 &pcfg_pull_up>;
+- };
+-
+- /omit-if-no-ref/
+- uart2m1_xfer: uart2m1-xfer {
+- rockchip,pins =
+- /* uart2_rx_m1 */
+- <4 RK_PD1 10 &pcfg_pull_up>,
+- /* uart2_tx_m1 */
+- <4 RK_PD0 10 &pcfg_pull_up>;
+- };
+-
+- /omit-if-no-ref/
+- uart2m2_xfer: uart2m2-xfer {
+- rockchip,pins =
+- /* uart2_rx_m2 */
+- <3 RK_PB2 10 &pcfg_pull_up>,
+- /* uart2_tx_m2 */
+- <3 RK_PB1 10 &pcfg_pull_up>;
+- };
+-
+- /omit-if-no-ref/
+- uart2_ctsn: uart2-ctsn {
+- rockchip,pins =
+- /* uart2_ctsn */
+- <3 RK_PB4 10 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- uart2_rtsn: uart2-rtsn {
+- rockchip,pins =
+- /* uart2_rtsn */
+- <3 RK_PB3 10 &pcfg_pull_none>;
+- };
+- };
+-
+- uart3 {
+- /omit-if-no-ref/
+- uart3m0_xfer: uart3m0-xfer {
+- rockchip,pins =
+- /* uart3_rx_m0 */
+- <1 RK_PC0 10 &pcfg_pull_up>,
+- /* uart3_tx_m0 */
+- <1 RK_PC1 10 &pcfg_pull_up>;
+- };
+-
+- /omit-if-no-ref/
+- uart3m1_xfer: uart3m1-xfer {
+- rockchip,pins =
+- /* uart3_rx_m1 */
+- <3 RK_PB6 10 &pcfg_pull_up>,
+- /* uart3_tx_m1 */
+- <3 RK_PB5 10 &pcfg_pull_up>;
+- };
+-
+- /omit-if-no-ref/
+- uart3m2_xfer: uart3m2-xfer {
+- rockchip,pins =
+- /* uart3_rx_m2 */
+- <4 RK_PA6 10 &pcfg_pull_up>,
+- /* uart3_tx_m2 */
+- <4 RK_PA5 10 &pcfg_pull_up>;
+- };
+-
+- /omit-if-no-ref/
+- uart3_ctsn: uart3-ctsn {
+- rockchip,pins =
+- /* uart3_ctsn */
+- <1 RK_PC3 10 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- uart3_rtsn: uart3-rtsn {
+- rockchip,pins =
+- /* uart3_rtsn */
+- <1 RK_PC2 10 &pcfg_pull_none>;
+- };
+- };
+-
+- uart4 {
+- /omit-if-no-ref/
+- uart4m0_xfer: uart4m0-xfer {
+- rockchip,pins =
+- /* uart4_rx_m0 */
+- <1 RK_PD3 10 &pcfg_pull_up>,
+- /* uart4_tx_m0 */
+- <1 RK_PD2 10 &pcfg_pull_up>;
+- };
+-
+- /omit-if-no-ref/
+- uart4m1_xfer: uart4m1-xfer {
+- rockchip,pins =
+- /* uart4_rx_m1 */
+- <3 RK_PD0 10 &pcfg_pull_up>,
+- /* uart4_tx_m1 */
+- <3 RK_PD1 10 &pcfg_pull_up>;
+- };
+-
+- /omit-if-no-ref/
+- uart4m2_xfer: uart4m2-xfer {
+- rockchip,pins =
+- /* uart4_rx_m2 */
+- <1 RK_PB2 10 &pcfg_pull_up>,
+- /* uart4_tx_m2 */
+- <1 RK_PB3 10 &pcfg_pull_up>;
+- };
+-
+- /omit-if-no-ref/
+- uart4_ctsn: uart4-ctsn {
+- rockchip,pins =
+- /* uart4_ctsn */
+- <1 RK_PC7 10 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- uart4_rtsn: uart4-rtsn {
+- rockchip,pins =
+- /* uart4_rtsn */
+- <1 RK_PC5 10 &pcfg_pull_none>;
+- };
+- };
+-
+- uart5 {
+- /omit-if-no-ref/
+- uart5m0_xfer: uart5m0-xfer {
+- rockchip,pins =
+- /* uart5_rx_m0 */
+- <4 RK_PD4 10 &pcfg_pull_up>,
+- /* uart5_tx_m0 */
+- <4 RK_PD5 10 &pcfg_pull_up>;
+- };
+-
+- /omit-if-no-ref/
+- uart5m0_ctsn: uart5m0-ctsn {
+- rockchip,pins =
+- /* uart5m0_ctsn */
+- <4 RK_PD2 10 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- uart5m0_rtsn: uart5m0-rtsn {
+- rockchip,pins =
+- /* uart5m0_rtsn */
+- <4 RK_PD3 10 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- uart5m1_xfer: uart5m1-xfer {
+- rockchip,pins =
+- /* uart5_rx_m1 */
+- <3 RK_PC5 10 &pcfg_pull_up>,
+- /* uart5_tx_m1 */
+- <3 RK_PC4 10 &pcfg_pull_up>;
+- };
+-
+- /omit-if-no-ref/
+- uart5m1_ctsn: uart5m1-ctsn {
+- rockchip,pins =
+- /* uart5m1_ctsn */
+- <2 RK_PA2 10 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- uart5m1_rtsn: uart5m1-rtsn {
+- rockchip,pins =
+- /* uart5m1_rtsn */
+- <2 RK_PA3 10 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- uart5m2_xfer: uart5m2-xfer {
+- rockchip,pins =
+- /* uart5_rx_m2 */
+- <2 RK_PD4 10 &pcfg_pull_up>,
+- /* uart5_tx_m2 */
+- <2 RK_PD5 10 &pcfg_pull_up>;
+- };
+- };
+-
+- uart6 {
+- /omit-if-no-ref/
+- uart6m1_xfer: uart6m1-xfer {
+- rockchip,pins =
+- /* uart6_rx_m1 */
+- <1 RK_PA0 10 &pcfg_pull_up>,
+- /* uart6_tx_m1 */
+- <1 RK_PA1 10 &pcfg_pull_up>;
+- };
+-
+- /omit-if-no-ref/
+- uart6m1_ctsn: uart6m1-ctsn {
+- rockchip,pins =
+- /* uart6m1_ctsn */
+- <1 RK_PA3 10 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- uart6m1_rtsn: uart6m1-rtsn {
+- rockchip,pins =
+- /* uart6m1_rtsn */
+- <1 RK_PA2 10 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- uart6m2_xfer: uart6m2-xfer {
+- rockchip,pins =
+- /* uart6_rx_m2 */
+- <1 RK_PD1 10 &pcfg_pull_up>,
+- /* uart6_tx_m2 */
+- <1 RK_PD0 10 &pcfg_pull_up>;
+- };
+- };
+-
+- uart7 {
+- /omit-if-no-ref/
+- uart7m1_xfer: uart7m1-xfer {
+- rockchip,pins =
+- /* uart7_rx_m1 */
+- <3 RK_PC1 10 &pcfg_pull_up>,
+- /* uart7_tx_m1 */
+- <3 RK_PC0 10 &pcfg_pull_up>;
+- };
+-
+- /omit-if-no-ref/
+- uart7m1_ctsn: uart7m1-ctsn {
+- rockchip,pins =
+- /* uart7m1_ctsn */
+- <3 RK_PC3 10 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- uart7m1_rtsn: uart7m1-rtsn {
+- rockchip,pins =
+- /* uart7m1_rtsn */
+- <3 RK_PC2 10 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- uart7m2_xfer: uart7m2-xfer {
+- rockchip,pins =
+- /* uart7_rx_m2 */
+- <1 RK_PB4 10 &pcfg_pull_up>,
+- /* uart7_tx_m2 */
+- <1 RK_PB5 10 &pcfg_pull_up>;
+- };
+- };
+-
+- uart8 {
+- /omit-if-no-ref/
+- uart8m0_xfer: uart8m0-xfer {
+- rockchip,pins =
+- /* uart8_rx_m0 */
+- <4 RK_PB1 10 &pcfg_pull_up>,
+- /* uart8_tx_m0 */
+- <4 RK_PB0 10 &pcfg_pull_up>;
+- };
+-
+- /omit-if-no-ref/
+- uart8m0_ctsn: uart8m0-ctsn {
+- rockchip,pins =
+- /* uart8m0_ctsn */
+- <4 RK_PB3 10 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- uart8m0_rtsn: uart8m0-rtsn {
+- rockchip,pins =
+- /* uart8m0_rtsn */
+- <4 RK_PB2 10 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- uart8m1_xfer: uart8m1-xfer {
+- rockchip,pins =
+- /* uart8_rx_m1 */
+- <3 RK_PA3 10 &pcfg_pull_up>,
+- /* uart8_tx_m1 */
+- <3 RK_PA2 10 &pcfg_pull_up>;
+- };
+-
+- /omit-if-no-ref/
+- uart8m1_ctsn: uart8m1-ctsn {
+- rockchip,pins =
+- /* uart8m1_ctsn */
+- <3 RK_PA5 10 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- uart8m1_rtsn: uart8m1-rtsn {
+- rockchip,pins =
+- /* uart8m1_rtsn */
+- <3 RK_PA4 10 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- uart8_xfer: uart8-xfer {
+- rockchip,pins =
+- /* uart8_rx_ */
+- <4 RK_PB1 10 &pcfg_pull_up>;
+- };
+- };
+-
+- uart9 {
+- /omit-if-no-ref/
+- uart9m0_xfer: uart9m0-xfer {
+- rockchip,pins =
+- /* uart9_rx_m0 */
+- <2 RK_PC4 10 &pcfg_pull_up>,
+- /* uart9_tx_m0 */
+- <2 RK_PC2 10 &pcfg_pull_up>;
+- };
+-
+- /omit-if-no-ref/
+- uart9m1_xfer: uart9m1-xfer {
+- rockchip,pins =
+- /* uart9_rx_m1 */
+- <4 RK_PB5 10 &pcfg_pull_up>,
+- /* uart9_tx_m1 */
+- <4 RK_PB4 10 &pcfg_pull_up>;
+- };
+-
+- /omit-if-no-ref/
+- uart9m1_ctsn: uart9m1-ctsn {
+- rockchip,pins =
+- /* uart9m1_ctsn */
+- <4 RK_PA1 10 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- uart9m1_rtsn: uart9m1-rtsn {
+- rockchip,pins =
+- /* uart9m1_rtsn */
+- <4 RK_PA0 10 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- uart9m2_xfer: uart9m2-xfer {
+- rockchip,pins =
+- /* uart9_rx_m2 */
+- <3 RK_PD4 10 &pcfg_pull_up>,
+- /* uart9_tx_m2 */
+- <3 RK_PD5 10 &pcfg_pull_up>;
+- };
+-
+- /omit-if-no-ref/
+- uart9m2_ctsn: uart9m2-ctsn {
+- rockchip,pins =
+- /* uart9m2_ctsn */
+- <3 RK_PD3 10 &pcfg_pull_none>;
+- };
+-
+- /omit-if-no-ref/
+- uart9m2_rtsn: uart9m2-rtsn {
+- rockchip,pins =
+- /* uart9m2_rtsn */
+- <3 RK_PD2 10 &pcfg_pull_none>;
+- };
+- };
+-
+- vop {
+- /omit-if-no-ref/
+- vop_pins: vop-pins {
+- rockchip,pins =
+- /* vop_post_empty */
+- <1 RK_PA2 1 &pcfg_pull_none>;
+- };
+- };
+-};
+-
+-/*
+- * This part is edited handly.
+- */
+-&pinctrl {
+- bt656 {
+- /omit-if-no-ref/
+- bt656_pins: bt656-pins {
+- rockchip,pins =
+- /* bt1120_clkout */
+- <4 RK_PB0 2 &pcfg_pull_none_drv_level_2>,
+- /* bt1120_d0 */
+- <4 RK_PA0 2 &pcfg_pull_none_drv_level_2>,
+- /* bt1120_d1 */
+- <4 RK_PA1 2 &pcfg_pull_none_drv_level_2>,
+- /* bt1120_d2 */
+- <4 RK_PA2 2 &pcfg_pull_none_drv_level_2>,
+- /* bt1120_d3 */
+- <4 RK_PA3 2 &pcfg_pull_none_drv_level_2>,
+- /* bt1120_d4 */
+- <4 RK_PA4 2 &pcfg_pull_none_drv_level_2>,
+- /* bt1120_d5 */
+- <4 RK_PA5 2 &pcfg_pull_none_drv_level_2>,
+- /* bt1120_d6 */
+- <4 RK_PA6 2 &pcfg_pull_none_drv_level_2>,
+- /* bt1120_d7 */
+- <4 RK_PA7 2 &pcfg_pull_none_drv_level_2>;
+- };
+- };
+-
+- gpio-func {
+- /omit-if-no-ref/
+- tsadc_gpio_func: tsadc-gpio-func {
+- rockchip,pins =
+- <0 RK_PA1 RK_FUNC_GPIO &pcfg_pull_none>;
+- };
+- };
+-};
diff --git a/target/linux/rockchip/patches-6.6/050-23-v6.11-arm64-dts-rockchip-add-thermal-zones-information-on-RK358.patch b/target/linux/rockchip/patches-6.6/050-23-v6.11-arm64-dts-rockchip-add-thermal-zones-information-on-RK358.patch
new file mode 100644
index 0000000000..1a18eb9358
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/050-23-v6.11-arm64-dts-rockchip-add-thermal-zones-information-on-RK358.patch
@@ -0,0 +1,193 @@
+From 510cd9e688453166b2bff3999ed21cac97385bb5 Mon Sep 17 00:00:00 2001
+From: Alexey Charkov <alchark@gmail.com>
+Date: Mon, 17 Jun 2024 22:28:51 +0400
+Subject: [PATCH] arm64: dts: rockchip: add thermal zones information on RK3588
+
+This includes the necessary device tree data to allow thermal
+monitoring on RK3588(s) using the on-chip TSADC device, along with
+trip points for automatic thermal management.
+
+Each of the CPU clusters (one for the little cores and two for
+the big cores) get a passive cooling trip point at 85C, which
+will trigger DVFS throttling of the respective cluster upon
+reaching a high temperature condition.
+
+All zones also have a critical trip point at 115C, which will
+trigger a reset.
+
+Signed-off-by: Alexey Charkov <alchark@gmail.com>
+Link: https://lore.kernel.org/r/20240617-rk-dts-additions-v5-1-c1f5f3267f1e@gmail.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588-base.dtsi | 153 ++++++++++++++++++
+ 1 file changed, 153 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
+@@ -10,6 +10,7 @@
+ #include <dt-bindings/reset/rockchip,rk3588-cru.h>
+ #include <dt-bindings/phy/phy.h>
+ #include <dt-bindings/ata/ahci.h>
++#include <dt-bindings/thermal/thermal.h>
+
+ / {
+ compatible = "rockchip,rk3588";
+@@ -2368,6 +2369,158 @@
+ status = "disabled";
+ };
+
++ thermal_zones: thermal-zones {
++ /* sensor near the center of the SoC */
++ package_thermal: package-thermal {
++ polling-delay-passive = <0>;
++ polling-delay = <0>;
++ thermal-sensors = <&tsadc 0>;
++
++ trips {
++ package_crit: package-crit {
++ temperature = <115000>;
++ hysteresis = <0>;
++ type = "critical";
++ };
++ };
++ };
++
++ /* sensor between A76 cores 0 and 1 */
++ bigcore0_thermal: bigcore0-thermal {
++ polling-delay-passive = <100>;
++ polling-delay = <0>;
++ thermal-sensors = <&tsadc 1>;
++
++ trips {
++ bigcore0_alert: bigcore0-alert {
++ temperature = <85000>;
++ hysteresis = <2000>;
++ type = "passive";
++ };
++
++ bigcore0_crit: bigcore0-crit {
++ temperature = <115000>;
++ hysteresis = <0>;
++ type = "critical";
++ };
++ };
++
++ cooling-maps {
++ map0 {
++ trip = <&bigcore0_alert>;
++ cooling-device =
++ <&cpu_b0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
++ <&cpu_b1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
++ };
++ };
++ };
++
++ /* sensor between A76 cores 2 and 3 */
++ bigcore2_thermal: bigcore2-thermal {
++ polling-delay-passive = <100>;
++ polling-delay = <0>;
++ thermal-sensors = <&tsadc 2>;
++
++ trips {
++ bigcore2_alert: bigcore2-alert {
++ temperature = <85000>;
++ hysteresis = <2000>;
++ type = "passive";
++ };
++
++ bigcore2_crit: bigcore2-crit {
++ temperature = <115000>;
++ hysteresis = <0>;
++ type = "critical";
++ };
++ };
++
++ cooling-maps {
++ map0 {
++ trip = <&bigcore2_alert>;
++ cooling-device =
++ <&cpu_b2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
++ <&cpu_b3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
++ };
++ };
++ };
++
++ /* sensor between the four A55 cores */
++ little_core_thermal: littlecore-thermal {
++ polling-delay-passive = <100>;
++ polling-delay = <0>;
++ thermal-sensors = <&tsadc 3>;
++
++ trips {
++ littlecore_alert: littlecore-alert {
++ temperature = <85000>;
++ hysteresis = <2000>;
++ type = "passive";
++ };
++
++ littlecore_crit: littlecore-crit {
++ temperature = <115000>;
++ hysteresis = <0>;
++ type = "critical";
++ };
++ };
++
++ cooling-maps {
++ map0 {
++ trip = <&littlecore_alert>;
++ cooling-device =
++ <&cpu_l0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
++ <&cpu_l1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
++ <&cpu_l2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
++ <&cpu_l3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
++ };
++ };
++ };
++
++ /* sensor near the PD_CENTER power domain */
++ center_thermal: center-thermal {
++ polling-delay-passive = <0>;
++ polling-delay = <0>;
++ thermal-sensors = <&tsadc 4>;
++
++ trips {
++ center_crit: center-crit {
++ temperature = <115000>;
++ hysteresis = <0>;
++ type = "critical";
++ };
++ };
++ };
++
++ gpu_thermal: gpu-thermal {
++ polling-delay-passive = <0>;
++ polling-delay = <0>;
++ thermal-sensors = <&tsadc 5>;
++
++ trips {
++ gpu_crit: gpu-crit {
++ temperature = <115000>;
++ hysteresis = <0>;
++ type = "critical";
++ };
++ };
++ };
++
++ npu_thermal: npu-thermal {
++ polling-delay-passive = <0>;
++ polling-delay = <0>;
++ thermal-sensors = <&tsadc 6>;
++
++ trips {
++ npu_crit: npu-crit {
++ temperature = <115000>;
++ hysteresis = <0>;
++ type = "critical";
++ };
++ };
++ };
++ };
++
+ tsadc: tsadc@fec00000 {
+ compatible = "rockchip,rk3588-tsadc";
+ reg = <0x0 0xfec00000 0x0 0x400>;
diff --git a/target/linux/rockchip/patches-6.6/050-24-v6.11-arm64-dts-rockchip-add-passive-GPU-cooling-on-RK3588.patch b/target/linux/rockchip/patches-6.6/050-24-v6.11-arm64-dts-rockchip-add-passive-GPU-cooling-on-RK3588.patch
new file mode 100644
index 0000000000..c7a8bb8aa9
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/050-24-v6.11-arm64-dts-rockchip-add-passive-GPU-cooling-on-RK3588.patch
@@ -0,0 +1,50 @@
+From b78f87940a79321a444083aca46ac3e8e53d1a90 Mon Sep 17 00:00:00 2001
+From: Alexey Charkov <alchark@gmail.com>
+Date: Mon, 17 Jun 2024 22:28:53 +0400
+Subject: [PATCH] arm64: dts: rockchip: add passive GPU cooling on RK3588
+
+As the GPU support on RK3588 has been merged upstream, along with OPP
+values, add a corresponding cooling map for passive cooling using the GPU.
+
+Signed-off-by: Alexey Charkov <alchark@gmail.com>
+Link: https://lore.kernel.org/r/20240617-rk-dts-additions-v5-3-c1f5f3267f1e@gmail.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588-base.dtsi | 16 +++++++++++++++-
+ 1 file changed, 15 insertions(+), 1 deletion(-)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
+@@ -2493,17 +2493,31 @@
+ };
+
+ gpu_thermal: gpu-thermal {
+- polling-delay-passive = <0>;
++ polling-delay-passive = <100>;
+ polling-delay = <0>;
+ thermal-sensors = <&tsadc 5>;
+
+ trips {
++ gpu_alert: gpu-alert {
++ temperature = <85000>;
++ hysteresis = <2000>;
++ type = "passive";
++ };
++
+ gpu_crit: gpu-crit {
+ temperature = <115000>;
+ hysteresis = <0>;
+ type = "critical";
+ };
+ };
++
++ cooling-maps {
++ map0 {
++ trip = <&gpu_alert>;
++ cooling-device =
++ <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
++ };
++ };
+ };
+
+ npu_thermal: npu-thermal {
diff --git a/target/linux/rockchip/patches-6.6/050-25-v6.11-arm64-dts-rockchip-Add-OPP-data-for-CPU-cores-on-RK3588.patch b/target/linux/rockchip/patches-6.6/050-25-v6.11-arm64-dts-rockchip-Add-OPP-data-for-CPU-cores-on-RK3588.patch
new file mode 100644
index 0000000000..cb5c254ffb
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/050-25-v6.11-arm64-dts-rockchip-Add-OPP-data-for-CPU-cores-on-RK3588.patch
@@ -0,0 +1,205 @@
+From 276856db91b46eaa7a4c19226c096a9dc899a3e9 Mon Sep 17 00:00:00 2001
+From: Alexey Charkov <alchark@gmail.com>
+Date: Mon, 17 Jun 2024 22:28:56 +0400
+Subject: [PATCH] arm64: dts: rockchip: Add OPP data for CPU cores on RK3588
+
+By default the CPUs on RK3588 start up in a conservative performance
+mode. Add frequency and voltage mappings to the device tree to enable
+dynamic scaling via cpufreq.
+
+OPP values are adapted from Radxa's downstream kernel for Rock 5B [1],
+stripping them down to the minimum frequency and voltage combinations
+as expected by the generic upstream cpufreq-dt driver, and also dropping
+those OPPs that don't differ in voltage but only in frequency (keeping
+the top frequency OPP in each case).
+
+Note that this patch ignores voltage scaling for the CPU memory
+interface which the downstream kernel does through a custom cpufreq
+driver, and which is why the downstream version has two sets of voltage
+values for each OPP (the second one being meant for the memory
+interface supply regulator). This is done instead via regulator
+coupling between CPU and memory interface supplies on affected boards.
+
+This has been tested on Rock 5B with u-boot 2023.11 compiled from
+Collabora's integration tree [2] with binary bl31 and appears to be
+stable both under active cooling and passive cooling (with throttling)
+
+[1] https://github.com/radxa/kernel/blob/stable-5.10-rock5/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
+[2] https://gitlab.collabora.com/hardware-enablement/rockchip-3588/u-boot
+
+Signed-off-by: Alexey Charkov <alchark@gmail.com>
+Link: https://lore.kernel.org/r/20240617-rk-dts-additions-v5-6-c1f5f3267f1e@gmail.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588-opp.dtsi | 149 +++++++++++++++++++
+ arch/arm64/boot/dts/rockchip/rk3588.dtsi | 1 +
+ arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 1 +
+ 3 files changed, 151 insertions(+)
+ create mode 100644 arch/arm64/boot/dts/rockchip/rk3588-opp.dtsi
+
+--- /dev/null
++++ b/arch/arm64/boot/dts/rockchip/rk3588-opp.dtsi
+@@ -0,0 +1,149 @@
++// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
++
++/ {
++ cluster0_opp_table: opp-table-cluster0 {
++ compatible = "operating-points-v2";
++ opp-shared;
++
++ opp-1008000000 {
++ opp-hz = /bits/ 64 <1008000000>;
++ opp-microvolt = <675000 675000 950000>;
++ clock-latency-ns = <40000>;
++ };
++ opp-1200000000 {
++ opp-hz = /bits/ 64 <1200000000>;
++ opp-microvolt = <712500 712500 950000>;
++ clock-latency-ns = <40000>;
++ };
++ opp-1416000000 {
++ opp-hz = /bits/ 64 <1416000000>;
++ opp-microvolt = <762500 762500 950000>;
++ clock-latency-ns = <40000>;
++ opp-suspend;
++ };
++ opp-1608000000 {
++ opp-hz = /bits/ 64 <1608000000>;
++ opp-microvolt = <850000 850000 950000>;
++ clock-latency-ns = <40000>;
++ };
++ opp-1800000000 {
++ opp-hz = /bits/ 64 <1800000000>;
++ opp-microvolt = <950000 950000 950000>;
++ clock-latency-ns = <40000>;
++ };
++ };
++
++ cluster1_opp_table: opp-table-cluster1 {
++ compatible = "operating-points-v2";
++ opp-shared;
++
++ opp-1200000000 {
++ opp-hz = /bits/ 64 <1200000000>;
++ opp-microvolt = <675000 675000 1000000>;
++ clock-latency-ns = <40000>;
++ };
++ opp-1416000000 {
++ opp-hz = /bits/ 64 <1416000000>;
++ opp-microvolt = <725000 725000 1000000>;
++ clock-latency-ns = <40000>;
++ };
++ opp-1608000000 {
++ opp-hz = /bits/ 64 <1608000000>;
++ opp-microvolt = <762500 762500 1000000>;
++ clock-latency-ns = <40000>;
++ };
++ opp-1800000000 {
++ opp-hz = /bits/ 64 <1800000000>;
++ opp-microvolt = <850000 850000 1000000>;
++ clock-latency-ns = <40000>;
++ };
++ opp-2016000000 {
++ opp-hz = /bits/ 64 <2016000000>;
++ opp-microvolt = <925000 925000 1000000>;
++ clock-latency-ns = <40000>;
++ };
++ opp-2208000000 {
++ opp-hz = /bits/ 64 <2208000000>;
++ opp-microvolt = <987500 987500 1000000>;
++ clock-latency-ns = <40000>;
++ };
++ opp-2400000000 {
++ opp-hz = /bits/ 64 <2400000000>;
++ opp-microvolt = <1000000 1000000 1000000>;
++ clock-latency-ns = <40000>;
++ };
++ };
++
++ cluster2_opp_table: opp-table-cluster2 {
++ compatible = "operating-points-v2";
++ opp-shared;
++
++ opp-1200000000 {
++ opp-hz = /bits/ 64 <1200000000>;
++ opp-microvolt = <675000 675000 1000000>;
++ clock-latency-ns = <40000>;
++ };
++ opp-1416000000 {
++ opp-hz = /bits/ 64 <1416000000>;
++ opp-microvolt = <725000 725000 1000000>;
++ clock-latency-ns = <40000>;
++ };
++ opp-1608000000 {
++ opp-hz = /bits/ 64 <1608000000>;
++ opp-microvolt = <762500 762500 1000000>;
++ clock-latency-ns = <40000>;
++ };
++ opp-1800000000 {
++ opp-hz = /bits/ 64 <1800000000>;
++ opp-microvolt = <850000 850000 1000000>;
++ clock-latency-ns = <40000>;
++ };
++ opp-2016000000 {
++ opp-hz = /bits/ 64 <2016000000>;
++ opp-microvolt = <925000 925000 1000000>;
++ clock-latency-ns = <40000>;
++ };
++ opp-2208000000 {
++ opp-hz = /bits/ 64 <2208000000>;
++ opp-microvolt = <987500 987500 1000000>;
++ clock-latency-ns = <40000>;
++ };
++ opp-2400000000 {
++ opp-hz = /bits/ 64 <2400000000>;
++ opp-microvolt = <1000000 1000000 1000000>;
++ clock-latency-ns = <40000>;
++ };
++ };
++};
++
++&cpu_b0 {
++ operating-points-v2 = <&cluster1_opp_table>;
++};
++
++&cpu_b1 {
++ operating-points-v2 = <&cluster1_opp_table>;
++};
++
++&cpu_b2 {
++ operating-points-v2 = <&cluster2_opp_table>;
++};
++
++&cpu_b3 {
++ operating-points-v2 = <&cluster2_opp_table>;
++};
++
++&cpu_l0 {
++ operating-points-v2 = <&cluster0_opp_table>;
++};
++
++&cpu_l1 {
++ operating-points-v2 = <&cluster0_opp_table>;
++};
++
++&cpu_l2 {
++ operating-points-v2 = <&cluster0_opp_table>;
++};
++
++&cpu_l3 {
++ operating-points-v2 = <&cluster0_opp_table>;
++};
+--- a/arch/arm64/boot/dts/rockchip/rk3588.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588.dtsi
+@@ -5,3 +5,4 @@
+ */
+
+ #include "rk3588-extra.dtsi"
++#include "rk3588-opp.dtsi"
+--- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
+@@ -5,3 +5,4 @@
+ */
+
+ #include "rk3588-base.dtsi"
++#include "rk3588-opp.dtsi"
diff --git a/target/linux/rockchip/patches-6.6/050-26-v6.11-arm64-dts-rockchip-Add-OPP-data-for-CPU-cores-on-RK3588j.patch b/target/linux/rockchip/patches-6.6/050-26-v6.11-arm64-dts-rockchip-Add-OPP-data-for-CPU-cores-on-RK3588j.patch
new file mode 100644
index 0000000000..3b39a60ade
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/050-26-v6.11-arm64-dts-rockchip-Add-OPP-data-for-CPU-cores-on-RK3588j.patch
@@ -0,0 +1,140 @@
+From 667885a6865832eb0678c7e02e47a3392f177ecb Mon Sep 17 00:00:00 2001
+From: Alexey Charkov <alchark@gmail.com>
+Date: Mon, 17 Jun 2024 22:28:57 +0400
+Subject: [PATCH] arm64: dts: rockchip: Add OPP data for CPU cores on RK3588j
+
+RK3588j is the 'industrial' variant of RK3588, and it uses a different
+set of OPPs both in terms of allowed frequencies and in terms of
+applicable voltages at each frequency setpoint.
+
+Add the OPPs that apply to RK3588j (and apparently RK3588m too) to
+enable dynamic CPU frequency scaling.
+
+OPP values are derived from Rockchip downstream sources [1] by taking
+only those OPPs which have the highest frequency for a given voltage
+level and dropping the rest (if they are included, the kernel complains
+at boot time about them being inefficient)
+
+[1] https://github.com/rockchip-linux/kernel/blob/604cec4004abe5a96c734f2fab7b74809d2d742f/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
+
+Signed-off-by: Alexey Charkov <alchark@gmail.com>
+Link: https://lore.kernel.org/r/20240617-rk-dts-additions-v5-7-c1f5f3267f1e@gmail.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588j.dtsi | 108 ++++++++++++++++++++++
+ 1 file changed, 108 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588j.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588j.dtsi
+@@ -5,3 +5,111 @@
+ */
+
+ #include "rk3588-extra.dtsi"
++
++/ {
++ cluster0_opp_table: opp-table-cluster0 {
++ compatible = "operating-points-v2";
++ opp-shared;
++
++ opp-1416000000 {
++ opp-hz = /bits/ 64 <1416000000>;
++ opp-microvolt = <750000 750000 950000>;
++ clock-latency-ns = <40000>;
++ opp-suspend;
++ };
++ opp-1608000000 {
++ opp-hz = /bits/ 64 <1608000000>;
++ opp-microvolt = <887500 887500 950000>;
++ clock-latency-ns = <40000>;
++ };
++ opp-1704000000 {
++ opp-hz = /bits/ 64 <1704000000>;
++ opp-microvolt = <937500 937500 950000>;
++ clock-latency-ns = <40000>;
++ };
++ };
++
++ cluster1_opp_table: opp-table-cluster1 {
++ compatible = "operating-points-v2";
++ opp-shared;
++
++ opp-1416000000 {
++ opp-hz = /bits/ 64 <1416000000>;
++ opp-microvolt = <750000 750000 950000>;
++ clock-latency-ns = <40000>;
++ };
++ opp-1608000000 {
++ opp-hz = /bits/ 64 <1608000000>;
++ opp-microvolt = <787500 787500 950000>;
++ clock-latency-ns = <40000>;
++ };
++ opp-1800000000 {
++ opp-hz = /bits/ 64 <1800000000>;
++ opp-microvolt = <875000 875000 950000>;
++ clock-latency-ns = <40000>;
++ };
++ opp-2016000000 {
++ opp-hz = /bits/ 64 <2016000000>;
++ opp-microvolt = <950000 950000 950000>;
++ clock-latency-ns = <40000>;
++ };
++ };
++
++ cluster2_opp_table: opp-table-cluster2 {
++ compatible = "operating-points-v2";
++ opp-shared;
++
++ opp-1416000000 {
++ opp-hz = /bits/ 64 <1416000000>;
++ opp-microvolt = <750000 750000 950000>;
++ clock-latency-ns = <40000>;
++ };
++ opp-1608000000 {
++ opp-hz = /bits/ 64 <1608000000>;
++ opp-microvolt = <787500 787500 950000>;
++ clock-latency-ns = <40000>;
++ };
++ opp-1800000000 {
++ opp-hz = /bits/ 64 <1800000000>;
++ opp-microvolt = <875000 875000 950000>;
++ clock-latency-ns = <40000>;
++ };
++ opp-2016000000 {
++ opp-hz = /bits/ 64 <2016000000>;
++ opp-microvolt = <950000 950000 950000>;
++ clock-latency-ns = <40000>;
++ };
++ };
++};
++
++&cpu_b0 {
++ operating-points-v2 = <&cluster1_opp_table>;
++};
++
++&cpu_b1 {
++ operating-points-v2 = <&cluster1_opp_table>;
++};
++
++&cpu_b2 {
++ operating-points-v2 = <&cluster2_opp_table>;
++};
++
++&cpu_b3 {
++ operating-points-v2 = <&cluster2_opp_table>;
++};
++
++&cpu_l0 {
++ operating-points-v2 = <&cluster0_opp_table>;
++};
++
++&cpu_l1 {
++ operating-points-v2 = <&cluster0_opp_table>;
++};
++
++&cpu_l2 {
++ operating-points-v2 = <&cluster0_opp_table>;
++};
++
++&cpu_l3 {
++ operating-points-v2 = <&cluster0_opp_table>;
++};
diff --git a/target/linux/rockchip/patches-6.6/050-27-v6.11-arm64-dts-rockchip-Split-GPU-OPPs-of-RK3588-and-RK3588j.patch b/target/linux/rockchip/patches-6.6/050-27-v6.11-arm64-dts-rockchip-Split-GPU-OPPs-of-RK3588-and-RK3588j.patch
new file mode 100644
index 0000000000..06befc8af9
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/050-27-v6.11-arm64-dts-rockchip-Split-GPU-OPPs-of-RK3588-and-RK3588j.patch
@@ -0,0 +1,177 @@
+From a7b2070505a2a09ea65fa0c8c480c97f62d1978d Mon Sep 17 00:00:00 2001
+From: Alexey Charkov <alchark@gmail.com>
+Date: Mon, 17 Jun 2024 22:28:58 +0400
+Subject: [PATCH] arm64: dts: rockchip: Split GPU OPPs of RK3588 and RK3588j
+
+RK3588j uses a different set of OPPs for its GPU, both in terms of
+allowed frequencies and in terms of voltages.
+
+Move the GPU OPPs table into per-variant .dtsi files to accommodate
+for this difference.
+
+The table for RK3588j is adapted from Rockchip downstream sources [1],
+while RK3588 one is moved verbatim into the per-variant .dtsi file.
+The values provided for RK3588 in the downstream sources match those
+in the original commit.
+
+[1] https://github.com/rockchip-linux/kernel/blob/604cec4004abe5a96c734f2fab7b74809d2d742f/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
+
+Fixes: 6fca4edb93d3 ("arm64: dts: rockchip: Add rk3588 GPU node")
+Signed-off-by: Alexey Charkov <alchark@gmail.com>
+Link: https://lore.kernel.org/r/20240617-rk-dts-additions-v5-8-c1f5f3267f1e@gmail.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588-base.dtsi | 38 -----------------
+ arch/arm64/boot/dts/rockchip/rk3588-opp.dtsi | 41 +++++++++++++++++++
+ arch/arm64/boot/dts/rockchip/rk3588j.dtsi | 33 +++++++++++++++
+ 3 files changed, 74 insertions(+), 38 deletions(-)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
+@@ -451,46 +451,8 @@
+ <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH 0>;
+ interrupt-names = "job", "mmu", "gpu";
+- operating-points-v2 = <&gpu_opp_table>;
+ power-domains = <&power RK3588_PD_GPU>;
+ status = "disabled";
+-
+- gpu_opp_table: opp-table {
+- compatible = "operating-points-v2";
+-
+- opp-300000000 {
+- opp-hz = /bits/ 64 <300000000>;
+- opp-microvolt = <675000 675000 850000>;
+- };
+- opp-400000000 {
+- opp-hz = /bits/ 64 <400000000>;
+- opp-microvolt = <675000 675000 850000>;
+- };
+- opp-500000000 {
+- opp-hz = /bits/ 64 <500000000>;
+- opp-microvolt = <675000 675000 850000>;
+- };
+- opp-600000000 {
+- opp-hz = /bits/ 64 <600000000>;
+- opp-microvolt = <675000 675000 850000>;
+- };
+- opp-700000000 {
+- opp-hz = /bits/ 64 <700000000>;
+- opp-microvolt = <700000 700000 850000>;
+- };
+- opp-800000000 {
+- opp-hz = /bits/ 64 <800000000>;
+- opp-microvolt = <750000 750000 850000>;
+- };
+- opp-900000000 {
+- opp-hz = /bits/ 64 <900000000>;
+- opp-microvolt = <800000 800000 850000>;
+- };
+- opp-1000000000 {
+- opp-hz = /bits/ 64 <1000000000>;
+- opp-microvolt = <850000 850000 850000>;
+- };
+- };
+ };
+
+ usb_host0_xhci: usb@fc000000 {
+--- a/arch/arm64/boot/dts/rockchip/rk3588-opp.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588-opp.dtsi
+@@ -114,6 +114,43 @@
+ clock-latency-ns = <40000>;
+ };
+ };
++
++ gpu_opp_table: opp-table {
++ compatible = "operating-points-v2";
++
++ opp-300000000 {
++ opp-hz = /bits/ 64 <300000000>;
++ opp-microvolt = <675000 675000 850000>;
++ };
++ opp-400000000 {
++ opp-hz = /bits/ 64 <400000000>;
++ opp-microvolt = <675000 675000 850000>;
++ };
++ opp-500000000 {
++ opp-hz = /bits/ 64 <500000000>;
++ opp-microvolt = <675000 675000 850000>;
++ };
++ opp-600000000 {
++ opp-hz = /bits/ 64 <600000000>;
++ opp-microvolt = <675000 675000 850000>;
++ };
++ opp-700000000 {
++ opp-hz = /bits/ 64 <700000000>;
++ opp-microvolt = <700000 700000 850000>;
++ };
++ opp-800000000 {
++ opp-hz = /bits/ 64 <800000000>;
++ opp-microvolt = <750000 750000 850000>;
++ };
++ opp-900000000 {
++ opp-hz = /bits/ 64 <900000000>;
++ opp-microvolt = <800000 800000 850000>;
++ };
++ opp-1000000000 {
++ opp-hz = /bits/ 64 <1000000000>;
++ opp-microvolt = <850000 850000 850000>;
++ };
++ };
+ };
+
+ &cpu_b0 {
+@@ -147,3 +184,7 @@
+ &cpu_l3 {
+ operating-points-v2 = <&cluster0_opp_table>;
+ };
++
++&gpu {
++ operating-points-v2 = <&gpu_opp_table>;
++};
+--- a/arch/arm64/boot/dts/rockchip/rk3588j.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3588j.dtsi
+@@ -80,6 +80,35 @@
+ clock-latency-ns = <40000>;
+ };
+ };
++
++ gpu_opp_table: opp-table {
++ compatible = "operating-points-v2";
++
++ opp-300000000 {
++ opp-hz = /bits/ 64 <300000000>;
++ opp-microvolt = <750000 750000 850000>;
++ };
++ opp-400000000 {
++ opp-hz = /bits/ 64 <400000000>;
++ opp-microvolt = <750000 750000 850000>;
++ };
++ opp-500000000 {
++ opp-hz = /bits/ 64 <500000000>;
++ opp-microvolt = <750000 750000 850000>;
++ };
++ opp-600000000 {
++ opp-hz = /bits/ 64 <600000000>;
++ opp-microvolt = <750000 750000 850000>;
++ };
++ opp-700000000 {
++ opp-hz = /bits/ 64 <700000000>;
++ opp-microvolt = <750000 750000 850000>;
++ };
++ opp-850000000 {
++ opp-hz = /bits/ 64 <800000000>;
++ opp-microvolt = <787500 787500 850000>;
++ };
++ };
+ };
+
+ &cpu_b0 {
+@@ -113,3 +142,7 @@
+ &cpu_l3 {
+ operating-points-v2 = <&cluster0_opp_table>;
+ };
++
++&gpu {
++ operating-points-v2 = <&gpu_opp_table>;
++};
diff --git a/target/linux/rockchip/patches-6.6/051-01-v6.8-arm64-dts-rockchip-add-USB3-host-to-rock-5a.patch b/target/linux/rockchip/patches-6.6/051-01-v6.8-arm64-dts-rockchip-add-USB3-host-to-rock-5a.patch
new file mode 100644
index 0000000000..a9bf3986e2
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/051-01-v6.8-arm64-dts-rockchip-add-USB3-host-to-rock-5a.patch
@@ -0,0 +1,39 @@
+From 0773a4a199aabb60afe50f5a19a6772abf4ad0bf Mon Sep 17 00:00:00 2001
+From: Sebastian Reichel <sebastian.reichel@collabora.com>
+Date: Mon, 6 Nov 2023 16:54:32 +0100
+Subject: [PATCH] arm64: dts: rockchip: add USB3 host to rock-5a
+
+Enable USB3 host controller for the Radxa ROCK 5 Model A. This adds
+USB3 for the lower USB3 port (the one closer to the PCB).
+
+The upper USB3 port uses the RK3588 USB TypeC host controller, which
+use a different PHY without upstream support.
+
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20231106155934.80838-2-sebastian.reichel@collabora.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
+@@ -113,6 +113,10 @@
+ };
+ };
+
++&combphy2_psu {
++ status = "okay";
++};
++
+ &cpu_b0 {
+ cpu-supply = <&vdd_cpu_big0_s0>;
+ };
+@@ -734,3 +738,7 @@
+ &usb_host1_ohci {
+ status = "okay";
+ };
++
++&usb_host2_xhci {
++ status = "okay";
++};
diff --git a/target/linux/rockchip/patches-6.6/051-02-v6.10-arm64-dts-rockchip-add-upper-USB3-port-to-rock-5a.patch b/target/linux/rockchip/patches-6.6/051-02-v6.10-arm64-dts-rockchip-add-upper-USB3-port-to-rock-5a.patch
new file mode 100644
index 0000000000..5c1ebb85ea
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/051-02-v6.10-arm64-dts-rockchip-add-upper-USB3-port-to-rock-5a.patch
@@ -0,0 +1,56 @@
+From af7ec140ddc1815bc462109792d95bcad05cfbc4 Mon Sep 17 00:00:00 2001
+From: Sebastian Reichel <sebastian.reichel@collabora.com>
+Date: Tue, 9 Apr 2024 00:50:36 +0200
+Subject: [PATCH] arm64: dts: rockchip: add upper USB3 port to rock-5a
+
+Enable full support (XHCI, EHCI, OHCI) for the upper USB3 port from
+Radxa Rock 5 Model A. The lower one is already supported.
+
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20240408225109.128953-10-sebastian.reichel@collabora.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ .../boot/dts/rockchip/rk3588s-rock-5a.dts | 18 ++++++++++++++++++
+ 1 file changed, 18 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
+@@ -698,6 +698,14 @@
+ };
+ };
+
++&u2phy0 {
++ status = "okay";
++};
++
++&u2phy0_otg {
++ status = "okay";
++};
++
+ &u2phy2 {
+ status = "okay";
+ };
+@@ -721,6 +729,11 @@
+ status = "okay";
+ };
+
++&usbdp_phy0 {
++ status = "okay";
++ rockchip,dp-lane-mux = <2 3>;
++};
++
+ &usb_host0_ehci {
+ status = "okay";
+ pinctrl-names = "default";
+@@ -731,6 +744,11 @@
+ status = "okay";
+ };
+
++&usb_host0_xhci {
++ dr_mode = "host";
++ status = "okay";
++};
++
+ &usb_host1_ehci {
+ status = "okay";
+ };
diff --git a/target/linux/rockchip/patches-6.6/051-03-v6.11-arm64-dts-rockchip-add-but-disabled-SFC-node-for-Radxa.patch b/target/linux/rockchip/patches-6.6/051-03-v6.11-arm64-dts-rockchip-add-but-disabled-SFC-node-for-Radxa.patch
new file mode 100644
index 0000000000..b71246f0ad
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/051-03-v6.11-arm64-dts-rockchip-add-but-disabled-SFC-node-for-Radxa.patch
@@ -0,0 +1,45 @@
+From 00224650dd45e166ea6eb1593f5f064583963ccf Mon Sep 17 00:00:00 2001
+From: FUKAUMI Naoki <naoki@radxa.com>
+Date: Sun, 23 Jun 2024 11:33:28 +0900
+Subject: [PATCH] arm64: dts: rockchip: add (but disabled) SFC node for Radxa
+ ROCK 5A
+
+This commit adds SFC node for Radxa ROCK 5A.
+
+since sdhci and sfc on RK3588s share pins(i.e. exclusive), it cannot
+be enabled both nodes at the same time. so status = "okay" is omitted
+here.
+
+you may be able to enable sfc (and disable sdhci) by fdt overlay.
+
+SPI NOR flash chip may vary, so use safe(lowest) spi-max-frequency.
+
+Signed-off-by: FUKAUMI Naoki <naoki@radxa.com>
+Link: https://lore.kernel.org/r/20240623023329.1044-2-naoki@radxa.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
+@@ -376,6 +376,19 @@
+ status = "okay";
+ };
+
++&sfc {
++ pinctrl-names = "default";
++ pinctrl-0 = <&fspim0_pins>;
++
++ flash@0 {
++ compatible = "jedec,spi-nor";
++ reg = <0>;
++ spi-max-frequency = <104000000>;
++ spi-rx-bus-width = <4>;
++ spi-tx-bus-width = <1>;
++ };
++};
++
+ &spi2 {
+ status = "okay";
+ assigned-clocks = <&cru CLK_SPI2>;
diff --git a/target/linux/rockchip/patches-6.6/051-04-v6.12-arm64-dts-rockchip-enable-PCIe-on-M.2-E-key-for-Radxa-ROC.patch b/target/linux/rockchip/patches-6.6/051-04-v6.12-arm64-dts-rockchip-enable-PCIe-on-M.2-E-key-for-Radxa-ROC.patch
new file mode 100644
index 0000000000..e4fe686da9
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/051-04-v6.12-arm64-dts-rockchip-enable-PCIe-on-M.2-E-key-for-Radxa-ROC.patch
@@ -0,0 +1,110 @@
+From b728d4c51f0ce9207daf502f3a85073785c46319 Mon Sep 17 00:00:00 2001
+From: FUKAUMI Naoki <naoki@radxa.com>
+Date: Mon, 26 Aug 2024 17:04:56 +0900
+Subject: [PATCH] arm64: dts: rockchip: enable PCIe on M.2 E key for Radxa ROCK
+ 5A
+
+Enable pcie2x1l2 and related combphy/regulator routed to M.2 E key
+connector on Radxa ROCK 5A.
+
+Tested with Radxa Wireless Module A8:
+
+$ lspci
+0004:40:00.0 PCI bridge: Rockchip Electronics Co., Ltd RK3588 (rev 01)
+0004:41:00.0 Network controller: Realtek Semiconductor Co., Ltd. RTL8852BE PCIe 802.11ax Wireless Network Controller
+
+$ ip l
+1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
+ link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
+2: end0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000
+ link/ether c2:58:fc:70:55:86 brd ff:ff:ff:ff:ff:ff
+3: wlP4p65s0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
+ link/ether 2c:05:47:65:5b:ed brd ff:ff:ff:ff:ff:ff
+
+$ lsusb
+Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
+Bus 001 Device 002: ID 1a40:0101 Terminus Technology Inc. Hub
+Bus 001 Device 003: ID 0bda:b85b Realtek Semiconductor Corp. Bluetooth Radio
+Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
+Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
+Bus 004 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
+Bus 005 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
+Bus 006 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
+Bus 006 Device 002: ID 0789:0336 Logitec Corp. LMD USB Device
+Bus 007 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
+Bus 008 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
+
+$ hciconfig
+hci0: Type: Primary Bus: USB
+ BD Address: 2C:05:47:65:5B:EE ACL MTU: 1021:6 SCO MTU: 255:12
+ UP RUNNING
+ RX bytes:2698 acl:0 sco:0 events:329 errors:0
+ TX bytes:69393 acl:0 sco:0 commands:329 errors:0
+
+Signed-off-by: FUKAUMI Naoki <naoki@radxa.com>
+Link: https://lore.kernel.org/r/20240826080456.525-1-naoki@radxa.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ .../boot/dts/rockchip/rk3588s-rock-5a.dts | 30 +++++++++++++++++++
+ 1 file changed, 30 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
+@@ -64,6 +64,18 @@
+ regulator-max-microvolt = <12000000>;
+ };
+
++ vcc3v3_wf: vcc3v3-wf-regulator {
++ compatible = "regulator-fixed";
++ regulator-name = "vcc3v3_wf";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ enable-active-high;
++ gpio = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>;
++ pinctrl-0 = <&pow_en>;
++ pinctrl-names = "default";
++ vin-supply = <&vcc5v0_sys>;
++ };
++
+ vcc5v0_host: vcc5v0-host-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc5v0_host";
+@@ -113,6 +125,10 @@
+ };
+ };
+
++&combphy0_ps {
++ status = "okay";
++};
++
+ &combphy2_psu {
+ status = "okay";
+ };
+@@ -292,6 +308,14 @@
+ };
+ };
+
++&pcie2x1l2 {
++ pinctrl-0 = <&pcie20x1m0_pins>;
++ pinctrl-names = "default";
++ reset-gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_HIGH>;
++ vpcie3v3-supply = <&vcc3v3_wf>;
++ status = "okay";
++};
++
+ &pinctrl {
+ leds {
+ io_led: io-led {
+@@ -299,6 +323,12 @@
+ };
+ };
+
++ pcie {
++ pow_en: pow-en {
++ rockchip,pins = <0 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
++
+ power {
+ vcc_5v0_en: vcc-5v0-en {
+ rockchip,pins = <4 RK_PA3 RK_FUNC_GPIO &pcfg_pull_none>;
diff --git a/target/linux/rockchip/patches-6.6/052-01-v6.7-arm64-dts-rockchip-add-PCIe-network-controller-to-rock-5b.patch b/target/linux/rockchip/patches-6.6/052-01-v6.7-arm64-dts-rockchip-add-PCIe-network-controller-to-rock-5b.patch
new file mode 100644
index 0000000000..7ce349d5d8
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/052-01-v6.7-arm64-dts-rockchip-add-PCIe-network-controller-to-rock-5b.patch
@@ -0,0 +1,72 @@
+From 42145b7a823530f57983fb6e6897f40c0be278d5 Mon Sep 17 00:00:00 2001
+From: Sebastian Reichel <sebastian.reichel@collabora.com>
+Date: Mon, 18 Sep 2023 16:14:49 +0200
+Subject: [PATCH] arm64: dts: rockchip: add PCIe network controller to rock-5b
+
+Enable the RTL8125 network controller, which is connected via
+PCIe.
+
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20230918141451.131247-2-sebastian.reichel@collabora.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ .../boot/dts/rockchip/rk3588-rock-5b.dts | 27 +++++++++++++++++++
+ 1 file changed, 27 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
+@@ -43,6 +43,15 @@
+ #cooling-cells = <2>;
+ };
+
++ vcc3v3_pcie2x1l2: vcc3v3-pcie2x1l2-regulator {
++ compatible = "regulator-fixed";
++ regulator-name = "vcc3v3_pcie2x1l2";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ startup-delay-us = <5000>;
++ vin-supply = <&vcc_3v3_s3>;
++ };
++
+ vcc5v0_host: vcc5v0-host-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc5v0_host";
+@@ -77,6 +86,10 @@
+ };
+ };
+
++&combphy0_ps {
++ status = "okay";
++};
++
+ &cpu_b0 {
+ cpu-supply = <&vdd_cpu_big0_s0>;
+ };
+@@ -203,6 +216,14 @@
+ };
+ };
+
++&pcie2x1l2 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&pcie2_2_rst>;
++ reset-gpios = <&gpio3 RK_PB0 GPIO_ACTIVE_HIGH>;
++ vpcie3v3-supply = <&vcc3v3_pcie2x1l2>;
++ status = "okay";
++};
++
+ &pinctrl {
+ hym8563 {
+ hym8563_int: hym8563-int {
+@@ -216,6 +237,12 @@
+ };
+ };
+
++ pcie2 {
++ pcie2_2_rst: pcie2-2-rst {
++ rockchip,pins = <3 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
++
+ usb {
+ vcc5v0_host_en: vcc5v0-host-en {
+ rockchip,pins = <4 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
diff --git a/target/linux/rockchip/patches-6.6/052-02-v6.7-arm64-dts-rockchip-add-PCIe-for-M.2-M-key-to-rock-5b.patch b/target/linux/rockchip/patches-6.6/052-02-v6.7-arm64-dts-rockchip-add-PCIe-for-M.2-M-key-to-rock-5b.patch
new file mode 100644
index 0000000000..456474cb86
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/052-02-v6.7-arm64-dts-rockchip-add-PCIe-for-M.2-M-key-to-rock-5b.patch
@@ -0,0 +1,73 @@
+From 199cbd5f195adbc0e70ad218cdba82f45750f11b Mon Sep 17 00:00:00 2001
+From: Sebastian Reichel <sebastian.reichel@collabora.com>
+Date: Mon, 18 Sep 2023 16:14:50 +0200
+Subject: [PATCH] arm64: dts: rockchip: add PCIe for M.2 M-key to rock-5b
+
+The Radxa Rock 5B has PCIe 3x4 routed to its M.2 M-key connector
+on the board's back.
+
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20230918141451.131247-3-sebastian.reichel@collabora.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ .../boot/dts/rockchip/rk3588-rock-5b.dts | 35 +++++++++++++++++++
+ 1 file changed, 35 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
+@@ -52,6 +52,19 @@
+ vin-supply = <&vcc_3v3_s3>;
+ };
+
++ vcc3v3_pcie30: vcc3v3-pcie30-regulator {
++ compatible = "regulator-fixed";
++ enable-active-high;
++ gpios = <&gpio1 RK_PA4 GPIO_ACTIVE_HIGH>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&pcie3_vcc3v3_en>;
++ regulator-name = "vcc3v3_pcie30";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ startup-delay-us = <5000>;
++ vin-supply = <&vcc5v0_sys>;
++ };
++
+ vcc5v0_host: vcc5v0-host-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc5v0_host";
+@@ -224,6 +237,18 @@
+ status = "okay";
+ };
+
++&pcie30phy {
++ status = "okay";
++};
++
++&pcie3x4 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&pcie3_rst>;
++ reset-gpios = <&gpio4 RK_PB6 GPIO_ACTIVE_HIGH>;
++ vpcie3v3-supply = <&vcc3v3_pcie30>;
++ status = "okay";
++};
++
+ &pinctrl {
+ hym8563 {
+ hym8563_int: hym8563-int {
+@@ -243,6 +268,16 @@
+ };
+ };
+
++ pcie3 {
++ pcie3_rst: pcie3-rst {
++ rockchip,pins = <4 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++
++ pcie3_vcc3v3_en: pcie3-vcc3v3-en {
++ rockchip,pins = <1 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
++
+ usb {
+ vcc5v0_host_en: vcc5v0-host-en {
+ rockchip,pins = <4 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
diff --git a/target/linux/rockchip/patches-6.6/052-03-v6.7-arm64-dts-rockchip-add-PCIe-for-M.2-E-Key-to-rock-5b.patch b/target/linux/rockchip/patches-6.6/052-03-v6.7-arm64-dts-rockchip-add-PCIe-for-M.2-E-Key-to-rock-5b.patch
new file mode 100644
index 0000000000..349a17eb77
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/052-03-v6.7-arm64-dts-rockchip-add-PCIe-for-M.2-E-Key-to-rock-5b.patch
@@ -0,0 +1,80 @@
+From da447ec387800bdf2df1fb1d8c1522991d025952 Mon Sep 17 00:00:00 2001
+From: Sebastian Reichel <sebastian.reichel@collabora.com>
+Date: Mon, 18 Sep 2023 16:14:51 +0200
+Subject: [PATCH] arm64: dts: rockchip: add PCIe for M.2 E-Key to rock-5b
+
+Enable PCIe2_0 controller and its voltage supply, which is routed
+to the M.2 E-Key on the upper side of the Radxa Rock 5B.
+
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20230918141451.131247-4-sebastian.reichel@collabora.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ .../boot/dts/rockchip/rk3588-rock-5b.dts | 35 +++++++++++++++++++
+ 1 file changed, 35 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
+@@ -43,6 +43,21 @@
+ #cooling-cells = <2>;
+ };
+
++ vcc3v3_pcie2x1l0: vcc3v3-pcie2x1l0-regulator {
++ compatible = "regulator-fixed";
++ enable-active-high;
++ gpios = <&gpio1 RK_PD2 GPIO_ACTIVE_HIGH>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&pcie2_0_vcc3v3_en>;
++ regulator-name = "vcc3v3_pcie2x1l0";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ startup-delay-us = <50000>;
++ vin-supply = <&vcc5v0_sys>;
++ };
++
+ vcc3v3_pcie2x1l2: vcc3v3-pcie2x1l2-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc3v3_pcie2x1l2";
+@@ -103,6 +118,10 @@
+ status = "okay";
+ };
+
++&combphy1_ps {
++ status = "okay";
++};
++
+ &cpu_b0 {
+ cpu-supply = <&vdd_cpu_big0_s0>;
+ };
+@@ -229,6 +248,14 @@
+ };
+ };
+
++&pcie2x1l0 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&pcie2_0_rst>;
++ reset-gpios = <&gpio4 RK_PA5 GPIO_ACTIVE_HIGH>;
++ vpcie3v3-supply = <&vcc3v3_pcie2x1l0>;
++ status = "okay";
++};
++
+ &pcie2x1l2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie2_2_rst>;
+@@ -263,6 +290,14 @@
+ };
+
+ pcie2 {
++ pcie2_0_rst: pcie2-0-rst {
++ rockchip,pins = <4 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++
++ pcie2_0_vcc3v3_en: pcie2-0-vcc-en {
++ rockchip,pins = <1 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++
+ pcie2_2_rst: pcie2-2-rst {
+ rockchip,pins = <3 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
diff --git a/target/linux/rockchip/patches-6.6/052-04-v6.7-arm64-dts-rockchip-Add-sdio-node-to-rock-5b.patch b/target/linux/rockchip/patches-6.6/052-04-v6.7-arm64-dts-rockchip-Add-sdio-node-to-rock-5b.patch
new file mode 100644
index 0000000000..cdf555f450
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/052-04-v6.7-arm64-dts-rockchip-Add-sdio-node-to-rock-5b.patch
@@ -0,0 +1,93 @@
+From 1c9a53ff7ece056eb995332f0d9523ca43fdcb5a Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Tam=C3=A1s=20Sz=C5=B1cs?= <tszucs@protonmail.ch>
+Date: Sun, 24 Sep 2023 20:37:45 +0000
+Subject: [PATCH] arm64: dts: rockchip: Add sdio node to rock-5b
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Enable SDIO on Radxa ROCK 5 Model B M.2 Key E. Add sdio node and alias as mmc2.
+Add regulator for the 3.3 V rail bringing it up during boot. Make sure EKEY_EN
+is muxed as GPIO.
+
+Signed-off-by: Tamás Szűcs <tszucs@protonmail.ch>
+Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20230924203740.65744-1-tszucs@protonmail.ch
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ .../boot/dts/rockchip/rk3588-rock-5b.dts | 43 +++++++++++++++++++
+ 1 file changed, 43 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
+@@ -12,6 +12,7 @@
+ aliases {
+ mmc0 = &sdhci;
+ mmc1 = &sdmmc;
++ mmc2 = &sdio;
+ };
+
+ chosen {
+@@ -112,6 +113,21 @@
+ regulator-max-microvolt = <1100000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
++
++ vcc3v3_wf: vcc3v3-wf-regulator {
++ compatible = "regulator-fixed";
++ regulator-name = "vcc3v3_wf";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ enable-active-high;
++ gpios = <&gpio1 RK_PD2 GPIO_ACTIVE_HIGH>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&vcc3v3_wf_en>;
++ startup-delay-us = <50000>;
++ vin-supply = <&vcc5v0_sys>;
++ };
+ };
+
+ &combphy0_ps {
+@@ -318,6 +334,12 @@
+ rockchip,pins = <4 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
++
++ m2e {
++ vcc3v3_wf_en: vcc3v3-wf-en {
++ rockchip,pins = <1 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
+ };
+
+ &pwm1 {
+@@ -354,6 +376,27 @@
+ status = "okay";
+ };
+
++&sdio {
++ max-frequency = <200000000>;
++ no-sd;
++ no-mmc;
++ non-removable;
++ bus-width = <4>;
++ cap-sdio-irq;
++ disable-wp;
++ keep-power-in-suspend;
++ wakeup-source;
++ sd-uhs-sdr12;
++ sd-uhs-sdr25;
++ sd-uhs-sdr50;
++ sd-uhs-sdr104;
++ vmmc-supply = <&vcc3v3_wf>;
++ vqmmc-supply = <&vcc_1v8_s3>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdiom0_pins>;
++ status = "okay";
++};
++
+ &spi2 {
+ status = "okay";
+ assigned-clocks = <&cru CLK_SPI2>;
diff --git a/target/linux/rockchip/patches-6.6/052-05-v6.8-arm64-dts-rockchip-Remove-duplicate-regulator-vcc3v3_wf.patch b/target/linux/rockchip/patches-6.6/052-05-v6.8-arm64-dts-rockchip-Remove-duplicate-regulator-vcc3v3_wf.patch
new file mode 100644
index 0000000000..3d1283d31f
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/052-05-v6.8-arm64-dts-rockchip-Remove-duplicate-regulator-vcc3v3_wf.patch
@@ -0,0 +1,65 @@
+From 0002c377e862140ad65b67b8b9dbf086d4578f95 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Tam=C3=A1s=20Sz=C5=B1cs?= <tszucs@protonmail.ch>
+Date: Wed, 11 Oct 2023 18:18:05 +0000
+Subject: [PATCH] arm64: dts: rockchip: Remove duplicate regulator vcc3v3_wf
+ from rock-5b
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Regulator for VCC3V3_WF has been added as vcc3v3_pcie2x1l0 first. Clean this up.
+
+Fixes: 1c9a53ff7ece ("arm64: dts: rockchip: Add sdio node to rock-5b")
+Signed-off-by: Tamás Szűcs <tszucs@protonmail.ch>
+Link: https://lore.kernel.org/r/20231011181757.58047-1-tszucs@protonmail.ch
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ .../boot/dts/rockchip/rk3588-rock-5b.dts | 23 +------------------
+ 1 file changed, 1 insertion(+), 22 deletions(-)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
+@@ -113,21 +113,6 @@
+ regulator-max-microvolt = <1100000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+-
+- vcc3v3_wf: vcc3v3-wf-regulator {
+- compatible = "regulator-fixed";
+- regulator-name = "vcc3v3_wf";
+- regulator-always-on;
+- regulator-boot-on;
+- regulator-min-microvolt = <3300000>;
+- regulator-max-microvolt = <3300000>;
+- enable-active-high;
+- gpios = <&gpio1 RK_PD2 GPIO_ACTIVE_HIGH>;
+- pinctrl-names = "default";
+- pinctrl-0 = <&vcc3v3_wf_en>;
+- startup-delay-us = <50000>;
+- vin-supply = <&vcc5v0_sys>;
+- };
+ };
+
+ &combphy0_ps {
+@@ -334,12 +319,6 @@
+ rockchip,pins = <4 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+-
+- m2e {
+- vcc3v3_wf_en: vcc3v3-wf-en {
+- rockchip,pins = <1 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>;
+- };
+- };
+ };
+
+ &pwm1 {
+@@ -390,7 +369,7 @@
+ sd-uhs-sdr25;
+ sd-uhs-sdr50;
+ sd-uhs-sdr104;
+- vmmc-supply = <&vcc3v3_wf>;
++ vmmc-supply = <&vcc3v3_pcie2x1l0>;
+ vqmmc-supply = <&vcc_1v8_s3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdiom0_pins>;
diff --git a/target/linux/rockchip/patches-6.6/052-06-v6.8-arm64-dts-rockchip-Enable-UART6-on-rock-5b.patch b/target/linux/rockchip/patches-6.6/052-06-v6.8-arm64-dts-rockchip-Enable-UART6-on-rock-5b.patch
new file mode 100644
index 0000000000..41c108f01a
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/052-06-v6.8-arm64-dts-rockchip-Enable-UART6-on-rock-5b.patch
@@ -0,0 +1,32 @@
+From a6169ab369236f15c79b45037074a2567d30b037 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Tam=C3=A1s=20Sz=C5=B1cs?= <szucst@iit.uni-miskolc.hu>
+Date: Fri, 13 Oct 2023 23:51:53 +0200
+Subject: [PATCH] arm64: dts: rockchip: Enable UART6 on rock-5b
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Enable UART lines on Radxa ROCK 5 Model B M.2 Key E.
+
+Signed-off-by: Tamás Szűcs <szucst@iit.uni-miskolc.hu>
+Link: https://lore.kernel.org/r/20231013215208.81345-1-szucst@iit.uni-miskolc.hu
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
+@@ -376,6 +376,12 @@
+ status = "okay";
+ };
+
++&uart6 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&uart6m1_xfer &uart6m1_ctsn &uart6m1_rtsn>;
++ status = "okay";
++};
++
+ &spi2 {
+ status = "okay";
+ assigned-clocks = <&cru CLK_SPI2>;
diff --git a/target/linux/rockchip/patches-6.6/052-07-v6.8-arm64-dts-rockchip-add-status-LED-to-rock-5b.patch b/target/linux/rockchip/patches-6.6/052-07-v6.8-arm64-dts-rockchip-add-status-LED-to-rock-5b.patch
new file mode 100644
index 0000000000..03d1ed860f
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/052-07-v6.8-arm64-dts-rockchip-add-status-LED-to-rock-5b.patch
@@ -0,0 +1,57 @@
+From 7952cbbda301f7d297c6ac761f9dfafb90205358 Mon Sep 17 00:00:00 2001
+From: Sebastian Reichel <sebastian.reichel@collabora.com>
+Date: Thu, 5 Oct 2023 15:40:37 +0200
+Subject: [PATCH] arm64: dts: rockchip: add status LED to rock-5b
+
+Describe the Rock 5B status LED in its device tree.
+
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20231005134037.33231-1-sebastian.reichel@collabora.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ .../boot/dts/rockchip/rk3588-rock-5b.dts | 20 +++++++++++++++++++
+ 1 file changed, 20 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
+@@ -3,6 +3,7 @@
+ /dts-v1/;
+
+ #include <dt-bindings/gpio/gpio.h>
++#include <dt-bindings/leds/common.h>
+ #include "rk3588.dtsi"
+
+ / {
+@@ -36,6 +37,19 @@
+ pinctrl-0 = <&hp_detect>;
+ };
+
++ leds {
++ compatible = "gpio-leds";
++ pinctrl-names = "default";
++ pinctrl-0 = <&led_rgb_b>;
++
++ led_rgb_b {
++ function = LED_FUNCTION_STATUS;
++ color = <LED_COLOR_ID_BLUE>;
++ gpios = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>;
++ linux,default-trigger = "heartbeat";
++ };
++ };
++
+ fan: pwm-fan {
+ compatible = "pwm-fan";
+ cooling-levels = <0 95 145 195 255>;
+@@ -284,6 +298,12 @@
+ };
+ };
+
++ leds {
++ led_rgb_b: led-rgb-b {
++ rockchip,pins = <0 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
++
+ sound {
+ hp_detect: hp-detect {
+ rockchip,pins = <1 RK_PD5 RK_FUNC_GPIO &pcfg_pull_none>;
diff --git a/target/linux/rockchip/patches-6.6/052-08-v6.8-arm64-dts-rockchip-add-USB3-host-to-rock-5b.patch b/target/linux/rockchip/patches-6.6/052-08-v6.8-arm64-dts-rockchip-add-USB3-host-to-rock-5b.patch
new file mode 100644
index 0000000000..b288ba858b
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/052-08-v6.8-arm64-dts-rockchip-add-USB3-host-to-rock-5b.patch
@@ -0,0 +1,39 @@
+From f97d78b9f6cff4c680206a8c8b03f726f0dc2c8b Mon Sep 17 00:00:00 2001
+From: Sebastian Reichel <sebastian.reichel@collabora.com>
+Date: Mon, 6 Nov 2023 16:54:31 +0100
+Subject: [PATCH] arm64: dts: rockchip: add USB3 host to rock-5b
+
+Enable USB3 host controller for the Radxa ROCK 5 Model B. This adds
+USB3 for the upper USB3 port (the one further away from the PCB).
+
+The lower USB3 and the USB-C ports use the RK3588 USB TypeC host
+controller, which use a different PHY without upstream support.
+
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20231106155934.80838-1-sebastian.reichel@collabora.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
+@@ -137,6 +137,10 @@
+ status = "okay";
+ };
+
++&combphy2_psu {
++ status = "okay";
++};
++
+ &cpu_b0 {
+ cpu-supply = <&vdd_cpu_big0_s0>;
+ };
+@@ -764,3 +768,7 @@
+ &usb_host1_ohci {
+ status = "okay";
+ };
++
++&usb_host2_xhci {
++ status = "okay";
++};
diff --git a/target/linux/rockchip/patches-6.6/052-09-v6.9-arm64-dts-rockchip-support-poweroff-on-the-rock-5b.patch b/target/linux/rockchip/patches-6.6/052-09-v6.9-arm64-dts-rockchip-support-poweroff-on-the-rock-5b.patch
new file mode 100644
index 0000000000..a1d2b7fe10
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/052-09-v6.9-arm64-dts-rockchip-support-poweroff-on-the-rock-5b.patch
@@ -0,0 +1,31 @@
+From 7738f551173540b3daa63a91b384b167eacd24fd Mon Sep 17 00:00:00 2001
+From: John Clark <inindev@gmail.com>
+Date: Mon, 25 Dec 2023 22:28:19 +0000
+Subject: [PATCH] arm64: dts: rockchip: support poweroff on the rock-5b
+
+Allow the rock-5b to poweroff its pmic. When issuing a "shutdown -h now"
+on the rock-5b it reboots instead. Defining 'system-power-controller'
+allows the rk806 to power down.
+
+Commit c699fbfdfd54 ("arm64: dts: rockchip: Support poweroff on
+NanoPC-T6") similarly resolves this issue for the nanopc-t6.
+
+Signed-off-by: John Clark <inindev@gmail.com>
+Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20231225222859.17153-1-inindev@gmail.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
+@@ -426,6 +426,8 @@
+ pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>,
+ <&rk806_dvs2_null>, <&rk806_dvs3_null>;
+
++ system-power-controller;
++
+ vcc1-supply = <&vcc5v0_sys>;
+ vcc2-supply = <&vcc5v0_sys>;
+ vcc3-supply = <&vcc5v0_sys>;
diff --git a/target/linux/rockchip/patches-6.6/052-10-v6.9-arm64-dts-rockchip-correct-gpio_pwrctrl1-typo-on-rock-5b.patch b/target/linux/rockchip/patches-6.6/052-10-v6.9-arm64-dts-rockchip-correct-gpio_pwrctrl1-typo-on-rock-5b.patch
new file mode 100644
index 0000000000..616f7a742f
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/052-10-v6.9-arm64-dts-rockchip-correct-gpio_pwrctrl1-typo-on-rock-5b.patch
@@ -0,0 +1,27 @@
+From aed6514c4e3aee843385ded4c5ee0921b51c30fa Mon Sep 17 00:00:00 2001
+From: John Clark <inindev@gmail.com>
+Date: Mon, 25 Dec 2023 22:28:20 +0000
+Subject: [PATCH] arm64: dts: rockchip: correct gpio_pwrctrl1 typo on rock-5b
+
+Both rk806_dvs1_null and rk806_dvs2_null duplicate gpio_pwrctrl2 and
+gpio_pwrctrl1 is not set. This patch sets gpio_pwrctrl1.
+
+Signed-off-by: John Clark <inindev@gmail.com>
+Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20231225222859.17153-2-inindev@gmail.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
+@@ -448,7 +448,7 @@
+ #gpio-cells = <2>;
+
+ rk806_dvs1_null: dvs1-null-pins {
+- pins = "gpio_pwrctrl2";
++ pins = "gpio_pwrctrl1";
+ function = "pin_fun0";
+ };
+
diff --git a/target/linux/rockchip/patches-6.6/052-11-v6.9-arm64-dts-rockchip-add-rfkill-node-for-M-2-Key-E-WiFi-on-.patch b/target/linux/rockchip/patches-6.6/052-11-v6.9-arm64-dts-rockchip-add-rfkill-node-for-M-2-Key-E-WiFi-on-.patch
new file mode 100644
index 0000000000..31ca0b8479
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/052-11-v6.9-arm64-dts-rockchip-add-rfkill-node-for-M-2-Key-E-WiFi-on-.patch
@@ -0,0 +1,34 @@
+From 82d40b141a4c7ab6608a84a5ce0c58b747cb7163 Mon Sep 17 00:00:00 2001
+From: Alexey Charkov <alchark@gmail.com>
+Date: Sun, 7 Jan 2024 00:26:45 +0400
+Subject: [PATCH] arm64: dts: rockchip: add rfkill node for M.2 Key E WiFi on rock-5b
+
+By default the GPIO pin that connects to the WiFi enable signal
+inside the M.2 Key E slot is driven low, resulting in impossibility
+to connect to any network. Add a DT node to expose it as an RFKILL
+device, which lets the WiFi driver or userspace toggle it as
+required.
+
+Signed-off-by: Alexey Charkov <alchark@gmail.com>
+Link: https://lore.kernel.org/r/20240106202650.22310-1-alchark@gmail.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
+@@ -58,6 +58,13 @@
+ #cooling-cells = <2>;
+ };
+
++ rfkill {
++ compatible = "rfkill-gpio";
++ label = "rfkill-pcie-wlan";
++ radio-type = "wlan";
++ shutdown-gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_HIGH>;
++ };
++
+ vcc3v3_pcie2x1l0: vcc3v3-pcie2x1l0-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
diff --git a/target/linux/rockchip/patches-6.6/052-12-v6.10-arm64-dts-rockchip-Enable-GPU-on-rk3588-rock5b.patch b/target/linux/rockchip/patches-6.6/052-12-v6.10-arm64-dts-rockchip-Enable-GPU-on-rk3588-rock5b.patch
new file mode 100644
index 0000000000..69c0c2551e
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/052-12-v6.10-arm64-dts-rockchip-Enable-GPU-on-rk3588-rock5b.patch
@@ -0,0 +1,29 @@
+From 038347286941148b6fd0cc2c40afcd540315aa6f Mon Sep 17 00:00:00 2001
+From: Boris Brezillon <boris.brezillon@collabora.com>
+Date: Tue, 26 Mar 2024 17:52:07 +0100
+Subject: [PATCH] arm64: dts: rockchip: Enable GPU on rk3588-rock5b
+
+Enable the Mali GPU in the Rock 5B.
+
+Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20240326165232.73585-4-sebastian.reichel@collabora.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
+@@ -180,6 +180,11 @@
+ cpu-supply = <&vdd_cpu_lit_s0>;
+ };
+
++&gpu {
++ mali-supply = <&vdd_gpu_s0>;
++ status = "okay";
++};
++
+ &i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0m2_xfer>;
diff --git a/target/linux/rockchip/patches-6.6/052-13-v6.10-arm64-dts-rockchip-Correct-the-model-names-for-Radxa-ROCK.patch b/target/linux/rockchip/patches-6.6/052-13-v6.10-arm64-dts-rockchip-Correct-the-model-names-for-Radxa-ROCK.patch
new file mode 100644
index 0000000000..99e98a8655
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/052-13-v6.10-arm64-dts-rockchip-Correct-the-model-names-for-Radxa-ROCK.patch
@@ -0,0 +1,43 @@
+From 45e831033f7a00a14f64afa1e34c476a9ff0f9f0 Mon Sep 17 00:00:00 2001
+From: Dragan Simic <dsimic@manjaro.org>
+Date: Thu, 18 Apr 2024 18:26:20 +0200
+Subject: [PATCH] arm64: dts: rockchip: Correct the model names for Radxa ROCK
+ 5 boards
+
+Correct the descriptions of a few Radxa boards, according to the up-to-date
+documentation from Radxa and the detailed explanation from Naoki. [1] To sum
+it up, the short naming, as specified by Radxa, is preferred.
+
+[1] https://lore.kernel.org/linux-rockchip/B26C732A4DCEA9B3+282b8775-601b-4d4a-a513-4924b7940076@radxa.com/
+
+Suggested-by: FUKAUMI Naoki <naoki@radxa.com>
+Signed-off-by: Dragan Simic <dsimic@manjaro.org>
+Link: https://lore.kernel.org/r/6931289a252dc2d6c7bfd2388835c5e98ba0d8c9.1713457260.git.dsimic@manjaro.org
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts | 2 +-
+ arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
+@@ -7,7 +7,7 @@
+ #include "rk3588.dtsi"
+
+ / {
+- model = "Radxa ROCK 5 Model B";
++ model = "Radxa ROCK 5B";
+ compatible = "radxa,rock-5b", "rockchip,rk3588";
+
+ aliases {
+--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
+@@ -8,7 +8,7 @@
+ #include "rk3588s.dtsi"
+
+ / {
+- model = "Radxa ROCK 5 Model A";
++ model = "Radxa ROCK 5A";
+ compatible = "radxa,rock-5a", "rockchip,rk3588s";
+
+ aliases {
diff --git a/target/linux/rockchip/patches-6.6/052-13-v6.10-arm64-dts-rockchip-add-lower-USB3-port-to-rock-5b.patch b/target/linux/rockchip/patches-6.6/052-13-v6.10-arm64-dts-rockchip-add-lower-USB3-port-to-rock-5b.patch
new file mode 100644
index 0000000000..8a3fab1576
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/052-13-v6.10-arm64-dts-rockchip-add-lower-USB3-port-to-rock-5b.patch
@@ -0,0 +1,55 @@
+From 494532921aacb496529d544fedfdb3a7b43dfef0 Mon Sep 17 00:00:00 2001
+From: Sebastian Reichel <sebastian.reichel@collabora.com>
+Date: Tue, 9 Apr 2024 00:50:37 +0200
+Subject: [PATCH] arm64: dts: rockchip: add lower USB3 port to rock-5b
+
+Enable full support (XHCI, EHCI, OHCI) for the lower USB3 port from
+Radxa Rock 5 Model B. The upper one is already supported.
+
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20240408225109.128953-11-sebastian.reichel@collabora.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts | 17 +++++++++++++++++
+ 1 file changed, 17 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
+@@ -748,6 +748,14 @@
+ status = "okay";
+ };
+
++&u2phy1 {
++ status = "okay";
++};
++
++&u2phy1_otg {
++ status = "okay";
++};
++
+ &u2phy2 {
+ status = "okay";
+ };
+@@ -767,6 +775,10 @@
+ status = "okay";
+ };
+
++&usbdp_phy1 {
++ status = "okay";
++};
++
+ &usb_host0_ehci {
+ status = "okay";
+ };
+@@ -783,6 +795,11 @@
+ status = "okay";
+ };
+
++&usb_host1_xhci {
++ dr_mode = "host";
++ status = "okay";
++};
++
+ &usb_host2_xhci {
+ status = "okay";
+ };
diff --git a/target/linux/rockchip/patches-6.6/052-14-v6.11-arm64-dts-rockchip-enable-automatic-fan-control-on-Rock-5.patch b/target/linux/rockchip/patches-6.6/052-14-v6.11-arm64-dts-rockchip-enable-automatic-fan-control-on-Rock-5.patch
new file mode 100644
index 0000000000..0b2d0a3dec
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/052-14-v6.11-arm64-dts-rockchip-enable-automatic-fan-control-on-Rock-5.patch
@@ -0,0 +1,67 @@
+From 4a152231b050590af771fa3cc8462ed08b691a24 Mon Sep 17 00:00:00 2001
+From: Alexey Charkov <alchark@gmail.com>
+Date: Mon, 17 Jun 2024 22:28:54 +0400
+Subject: [PATCH] arm64: dts: rockchip: enable automatic fan control on Rock 5B
+
+This links the PWM fan on Radxa Rock 5B as an active cooling device
+managed automatically by the thermal subsystem, with a target SoC
+temperature of 65C and a minimum-spin interval from 55C to 65C to
+ensure airflow when the system gets warm
+
+Helped-by: Dragan Simic <dsimic@manjaro.org>
+Reviewed-by: Dragan Simic <dsimic@manjaro.org>
+Signed-off-by: Alexey Charkov <alchark@gmail.com>
+Link: https://lore.kernel.org/r/20240617-rk-dts-additions-v5-4-c1f5f3267f1e@gmail.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ .../boot/dts/rockchip/rk3588-rock-5b.dts | 32 ++++++++++++++++++-
+ 1 file changed, 31 insertions(+), 1 deletion(-)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
+@@ -52,7 +52,7 @@
+
+ fan: pwm-fan {
+ compatible = "pwm-fan";
+- cooling-levels = <0 95 145 195 255>;
++ cooling-levels = <0 120 150 180 210 240 255>;
+ fan-supply = <&vcc5v0_sys>;
+ pwms = <&pwm1 0 50000 0>;
+ #cooling-cells = <2>;
+@@ -278,6 +278,36 @@
+ };
+ };
+ };
++
++&package_thermal {
++ polling-delay = <1000>;
++
++ trips {
++ package_fan0: package-fan0 {
++ temperature = <55000>;
++ hysteresis = <2000>;
++ type = "active";
++ };
++
++ package_fan1: package-fan1 {
++ temperature = <65000>;
++ hysteresis = <2000>;
++ type = "active";
++ };
++ };
++
++ cooling-maps {
++ map1 {
++ trip = <&package_fan0>;
++ cooling-device = <&fan THERMAL_NO_LIMIT 1>;
++ };
++
++ map2 {
++ trip = <&package_fan1>;
++ cooling-device = <&fan 2 THERMAL_NO_LIMIT>;
++ };
++ };
++};
+
+ &pcie2x1l0 {
+ pinctrl-names = "default";
diff --git a/target/linux/rockchip/patches-6.6/052-15-v6.11-arm64-dts-rockchip-add-SFC-support-for-Radxa-ROCK-5B.patch b/target/linux/rockchip/patches-6.6/052-15-v6.11-arm64-dts-rockchip-add-SFC-support-for-Radxa-ROCK-5B.patch
new file mode 100644
index 0000000000..043b983877
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/052-15-v6.11-arm64-dts-rockchip-add-SFC-support-for-Radxa-ROCK-5B.patch
@@ -0,0 +1,39 @@
+From 9204a7ecca96403ee3d61c14cb9eb87ec89b0fcd Mon Sep 17 00:00:00 2001
+From: FUKAUMI Naoki <naoki@radxa.com>
+Date: Sun, 23 Jun 2024 11:33:27 +0900
+Subject: [PATCH] arm64: dts: rockchip: add SFC support for Radxa ROCK 5B
+
+This commit adds support for SPI NOR flash on Radxa ROCK 5B.
+
+SPI NOR flash chip may vary, so use safe(lowest) spi-max-frequency.
+
+Signed-off-by: FUKAUMI Naoki <naoki@radxa.com>
+Link: https://lore.kernel.org/r/20240623023329.1044-1-naoki@radxa.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
+@@ -442,6 +442,20 @@
+ status = "okay";
+ };
+
++&sfc {
++ pinctrl-names = "default";
++ pinctrl-0 = <&fspim2_pins>;
++ status = "okay";
++
++ flash@0 {
++ compatible = "jedec,spi-nor";
++ reg = <0>;
++ spi-max-frequency = <104000000>;
++ spi-rx-bus-width = <4>;
++ spi-tx-bus-width = <1>;
++ };
++};
++
+ &uart6 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart6m1_xfer &uart6m1_ctsn &uart6m1_rtsn>;
diff --git a/target/linux/rockchip/patches-6.6/052-16-v6.11-arm64-dts-rockchip-enable-thermal-management-on-all-RK358.patch b/target/linux/rockchip/patches-6.6/052-16-v6.11-arm64-dts-rockchip-enable-thermal-management-on-all-RK358.patch
new file mode 100644
index 0000000000..d59574bc49
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/052-16-v6.11-arm64-dts-rockchip-enable-thermal-management-on-all-RK358.patch
@@ -0,0 +1,66 @@
+From 2f8064b9c4a012b4d4e8383818f13b682b6c156a Mon Sep 17 00:00:00 2001
+From: Alexey Charkov <alchark@gmail.com>
+Date: Mon, 17 Jun 2024 22:28:52 +0400
+Subject: [PATCH] arm64: dts: rockchip: enable thermal management on all RK3588
+ boards
+
+This enables the on-chip thermal monitoring sensor (TSADC) on all
+RK3588(s) boards that don't have it enabled yet. It provides temperature
+monitoring for the SoC and emergency thermal shutdowns, and is thus
+important to have in place before CPU DVFS is enabled, as high CPU
+operating performance points can overheat the chip quickly in the
+absence of thermal management.
+
+Signed-off-by: Alexey Charkov <alchark@gmail.com>
+Link: https://lore.kernel.org/r/20240617-rk-dts-additions-v5-2-c1f5f3267f1e@gmail.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3588-armsom-sige7.dts | 4 ++++
+ arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6a-common.dtsi | 4 ++++
+ arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts | 4 ++++
+ arch/arm64/boot/dts/rockchip/rk3588-ok3588-c.dts | 4 ++++
+ arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts | 4 ++++
+ arch/arm64/boot/dts/rockchip/rk3588-toybrick-x0.dts | 4 ++++
+ arch/arm64/boot/dts/rockchip/rk3588-turing-rk1.dtsi | 4 ++++
+ arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts | 4 ++++
+ 8 files changed, 32 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts
+@@ -807,6 +807,10 @@
+ status = "okay";
+ };
+
++&tsadc {
++ status = "okay";
++};
++
+ &u2phy2 {
+ status = "okay";
+ };
+--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
+@@ -787,6 +787,10 @@
+ };
+ };
+
++&tsadc {
++ status = "okay";
++};
++
+ &uart2 {
+ pinctrl-0 = <&uart2m0_xfer>;
+ status = "okay";
+--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
+@@ -741,6 +741,10 @@
+ };
+ };
+
++&tsadc {
++ status = "okay";
++};
++
+ &u2phy0 {
+ status = "okay";
+ };
diff --git a/target/linux/rockchip/patches-6.6/053-v6.9-arm64-dts-rockchip-Add-support-for-NanoPi-R6S.patch b/target/linux/rockchip/patches-6.6/053-v6.9-arm64-dts-rockchip-Add-support-for-NanoPi-R6S.patch
new file mode 100644
index 0000000000..d0243023fc
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/053-v6.9-arm64-dts-rockchip-Add-support-for-NanoPi-R6S.patch
@@ -0,0 +1,792 @@
+From f1b11f43b3e983b26d8010fc43ba6c2b979826f2 Mon Sep 17 00:00:00 2001
+From: Muhammed Efe Cetin <efectn@protonmail.com>
+Date: Sat, 30 Dec 2023 14:18:00 +0300
+Subject: [PATCH] arm64: dts: rockchip: Add support for NanoPi R6S
+
+Add basic NanoPi R6S support that comes with USB2, PCIe, SD card, eMMC
+support.
+
+Signed-off-by: Muhammed Efe Cetin <efectn@protonmail.com>
+Link: https://lore.kernel.org/r/6db3b653efc6f0a2dca8e96fdd0503906db72fb6.1703934548.git.efectn@protonmail.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/Makefile | 1 +
+ .../boot/dts/rockchip/rk3588s-nanopi-r6s.dts | 764 ++++++++++++++++++
+ 2 files changed, 765 insertions(+)
+ create mode 100644 arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6s.dts
+
+--- a/arch/arm64/boot/dts/rockchip/Makefile
++++ b/arch/arm64/boot/dts/rockchip/Makefile
+@@ -108,4 +108,5 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-na
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-rock-5b.dtb
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-indiedroid-nova.dtb
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-khadas-edge2.dtb
++dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-nanopi-r6s.dtb
+ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-rock-5a.dtb
+--- /dev/null
++++ b/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6s.dts
+@@ -0,0 +1,764 @@
++// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
++
++/dts-v1/;
++
++#include <dt-bindings/pinctrl/rockchip.h>
++#include <dt-bindings/gpio/gpio.h>
++#include <dt-bindings/input/input.h>
++#include "rk3588s.dtsi"
++
++/ {
++ model = "FriendlyElec NanoPi R6S";
++ compatible = "friendlyarm,nanopi-r6s", "rockchip,rk3588s";
++
++ aliases {
++ ethernet0 = &gmac1;
++ mmc0 = &sdmmc;
++ mmc1 = &sdhci;
++ };
++
++ chosen {
++ stdout-path = "serial2:1500000n8";
++ };
++
++ adc-keys {
++ compatible = "adc-keys";
++ io-channels = <&saradc 0>;
++ io-channel-names = "buttons";
++ keyup-threshold-microvolt = <1800000>;
++ poll-interval = <100>;
++
++ button-maskrom {
++ label = "Maskrom";
++ linux,code = <KEY_VENDOR>;
++ press-threshold-microvolt = <1800>;
++ };
++ };
++
++ gpio-keys {
++ compatible = "gpio-keys";
++ pinctrl-names = "default";
++ pinctrl-0 = <&key1_pin>;
++
++ button-user {
++ label = "User";
++ linux,code = <BTN_1>;
++ gpios = <&gpio1 RK_PC0 GPIO_ACTIVE_LOW>;
++ debounce-interval = <50>;
++ };
++ };
++
++ leds {
++ compatible = "gpio-leds";
++
++ sys_led: led-0 {
++ label = "sys_led";
++ gpios = <&gpio1 RK_PC1 GPIO_ACTIVE_HIGH>;
++ linux,default-trigger = "heartbeat";
++ pinctrl-names = "default";
++ pinctrl-0 = <&sys_led_pin>;
++ };
++
++ wan_led: led-1 {
++ label = "wan_led";
++ gpios = <&gpio1 RK_PC2 GPIO_ACTIVE_HIGH>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&wan_led_pin>;
++ };
++
++ lan1_led: led-2 {
++ label = "lan1_led";
++ gpios = <&gpio1 RK_PC3 GPIO_ACTIVE_HIGH>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&lan1_led_pin>;
++ };
++
++ lan2_led: led-3 {
++ label = "lan2_led";
++ gpios = <&gpio1 RK_PC4 GPIO_ACTIVE_HIGH>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&lan2_led_pin>;
++ };
++ };
++
++ vcc5v0_sys: vcc5v0-sys-regulator {
++ compatible = "regulator-fixed";
++ regulator-name = "vcc5v0_sys";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <5000000>;
++ regulator-max-microvolt = <5000000>;
++ };
++
++ vcc_1v1_nldo_s3: vcc-1v1-nldo-s3-regulator {
++ compatible = "regulator-fixed";
++ regulator-name = "vcc_1v1_nldo_s3";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <1100000>;
++ regulator-max-microvolt = <1100000>;
++ vin-supply = <&vcc5v0_sys>;
++ };
++
++ vcc_3v3_s0: vcc-3v3-s0-regulator {
++ compatible = "regulator-fixed";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ regulator-name = "vcc_3v3_s0";
++ vin-supply = <&vcc_3v3_s3>;
++ };
++
++ vcc_3v3_sd_s0: vcc-3v3-sd-s0-regulator {
++ compatible = "regulator-fixed";
++ enable-active-high;
++ gpios = <&gpio4 RK_PB4 GPIO_ACTIVE_HIGH>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&sd_s0_pwr>;
++ regulator-name = "vcc_3v3_sd_s0";
++ regulator-boot-on;
++ regulator-max-microvolt = <3000000>;
++ regulator-min-microvolt = <3000000>;
++ vin-supply = <&vcc_3v3_s3>;
++ };
++
++ vcc_3v3_pcie20: vcc3v3-pcie20-regulator {
++ compatible = "regulator-fixed";
++ regulator-name = "vcc_3v3_pcie20";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ vin-supply = <&vcc_3v3_s3>;
++ };
++
++ vcc5v0_usb: vcc5v0-usb-regulator {
++ compatible = "regulator-fixed";
++ regulator-name = "vcc5v0_usb";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <5000000>;
++ regulator-max-microvolt = <5000000>;
++ vin-supply = <&vcc5v0_sys>;
++ };
++
++ vcc5v0_usb_otg0: vcc5v0-usb-otg0-regulator {
++ compatible = "regulator-fixed";
++ enable-active-high;
++ gpios = <&gpio1 RK_PD2 GPIO_ACTIVE_HIGH>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&typec5v_pwren>;
++ regulator-name = "vcc5v0_usb_otg0";
++ regulator-min-microvolt = <5000000>;
++ regulator-max-microvolt = <5000000>;
++ vin-supply = <&vcc5v0_usb>;
++ };
++
++ vcc5v0_host_20: vcc5v0-host-20-regulator {
++ compatible = "regulator-fixed";
++ enable-active-high;
++ gpios = <&gpio4 RK_PB5 GPIO_ACTIVE_HIGH>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&vcc5v0_host20_en>;
++ regulator-name = "vcc5v0_host_20";
++ regulator-min-microvolt = <5000000>;
++ regulator-max-microvolt = <5000000>;
++ vin-supply = <&vcc5v0_usb>;
++ };
++};
++
++&combphy0_ps {
++ status = "okay";
++};
++
++&combphy2_psu {
++ status = "okay";
++};
++
++&cpu_b0 {
++ cpu-supply = <&vdd_cpu_big0_s0>;
++};
++
++&cpu_b1 {
++ cpu-supply = <&vdd_cpu_big0_s0>;
++};
++
++&cpu_b2 {
++ cpu-supply = <&vdd_cpu_big1_s0>;
++};
++
++&cpu_b3 {
++ cpu-supply = <&vdd_cpu_big1_s0>;
++};
++
++&cpu_l0 {
++ cpu-supply = <&vdd_cpu_lit_s0>;
++};
++
++&cpu_l1 {
++ cpu-supply = <&vdd_cpu_lit_s0>;
++};
++
++&cpu_l2 {
++ cpu-supply = <&vdd_cpu_lit_s0>;
++};
++
++&cpu_l3 {
++ cpu-supply = <&vdd_cpu_lit_s0>;
++};
++
++&gmac1 {
++ clock_in_out = "output";
++ phy-handle = <&rgmii_phy1>;
++ phy-mode = "rgmii-rxid";
++ pinctrl-0 = <&gmac1_miim
++ &gmac1_tx_bus2
++ &gmac1_rx_bus2
++ &gmac1_rgmii_clk
++ &gmac1_rgmii_bus>;
++ pinctrl-names = "default";
++ tx_delay = <0x42>;
++ status = "okay";
++};
++
++&i2c0 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2c0m2_xfer>;
++ status = "okay";
++
++ vdd_cpu_big0_s0: regulator@42 {
++ compatible = "rockchip,rk8602";
++ reg = <0x42>;
++ fcs,suspend-voltage-selector = <1>;
++ regulator-name = "vdd_cpu_big0_s0";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <550000>;
++ regulator-max-microvolt = <1050000>;
++ regulator-ramp-delay = <2300>;
++ vin-supply = <&vcc5v0_sys>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vdd_cpu_big1_s0: regulator@43 {
++ compatible = "rockchip,rk8603", "rockchip,rk8602";
++ reg = <0x43>;
++ fcs,suspend-voltage-selector = <1>;
++ regulator-name = "vdd_cpu_big1_s0";
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <550000>;
++ regulator-max-microvolt = <1050000>;
++ regulator-ramp-delay = <2300>;
++ vin-supply = <&vcc5v0_sys>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++};
++
++&i2c2 {
++ status = "okay";
++
++ vdd_npu_s0: regulator@42 {
++ compatible = "rockchip,rk8602";
++ reg = <0x42>;
++ fcs,suspend-voltage-selector = <1>;
++ regulator-name = "vdd_npu_s0";
++ regulator-min-microvolt = <550000>;
++ regulator-max-microvolt = <950000>;
++ regulator-ramp-delay = <2300>;
++ regulator-boot-on;
++ regulator-always-on;
++ vin-supply = <&vcc5v0_sys>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++};
++
++&i2c6 {
++ clock-frequency = <200000>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2c6m0_xfer>;
++ status = "okay";
++
++ hym8563: rtc@51 {
++ compatible = "haoyu,hym8563";
++ reg = <0x51>;
++ #clock-cells = <0>;
++ clock-output-names = "hym8563";
++ pinctrl-names = "default";
++ pinctrl-0 = <&rtc_int>;
++ interrupt-parent = <&gpio0>;
++ interrupts = <RK_PB0 IRQ_TYPE_LEVEL_LOW>;
++ wakeup-source;
++ };
++};
++
++&mdio1 {
++ rgmii_phy1: ethernet-phy@1 {
++ compatible = "ethernet-phy-id001c.c916";
++ reg = <0x1>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&rtl8211f_rst>;
++ reset-assert-us = <20000>;
++ reset-deassert-us = <100000>;
++ reset-gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>;
++ };
++};
++
++&pcie2x1l1 {
++ reset-gpios = <&gpio1 RK_PA7 GPIO_ACTIVE_HIGH>;
++ vpcie3v3-supply = <&vcc_3v3_pcie20>;
++ status = "okay";
++};
++
++&pcie2x1l2 {
++ reset-gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_HIGH>;
++ vpcie3v3-supply = <&vcc_3v3_pcie20>;
++ status = "okay";
++};
++
++&pinctrl {
++ gpio-key {
++ key1_pin: key1-pin {
++ rockchip,pins = <1 RK_PC0 RK_FUNC_GPIO &pcfg_pull_up>;
++ };
++ };
++
++ gpio-leds {
++ sys_led_pin: sys-led-pin {
++ rockchip,pins =
++ <1 RK_PC1 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++
++ wan_led_pin: wan-led-pin {
++ rockchip,pins =
++ <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++
++ lan1_led_pin: lan1-led-pin {
++ rockchip,pins =
++ <1 RK_PC3 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++
++ lan2_led_pin: lan2-led-pin {
++ rockchip,pins =
++ <1 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
++
++ hym8563 {
++ rtc_int: rtc-int {
++ rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_up>;
++ };
++ };
++
++ sdmmc {
++ sd_s0_pwr: sd-s0-pwr {
++ rockchip,pins = <4 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>;
++ };
++ };
++
++ usb {
++ typec5v_pwren: typec5v-pwren {
++ rockchip,pins = <1 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++
++ vcc5v0_host20_en: vcc5v0-host20-en {
++ rockchip,pins = <4 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
++
++ rtl8211f {
++ rtl8211f_rst: rtl8211f-rst {
++ rockchip,pins = <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>;
++ };
++ };
++};
++
++&saradc {
++ vref-supply = <&avcc_1v8_s0>;
++ status = "okay";
++};
++
++&sdhci {
++ bus-width = <8>;
++ no-sdio;
++ no-sd;
++ non-removable;
++ mmc-hs200-1_8v;
++ status = "okay";
++};
++
++&sdmmc {
++ bus-width = <4>;
++ cap-sd-highspeed;
++ disable-wp;
++ max-frequency = <150000000>;
++ no-mmc;
++ no-sdio;
++ sd-uhs-sdr104;
++ vmmc-supply = <&vcc_3v3_sd_s0>;
++ vqmmc-supply = <&vccio_sd_s0>;
++ status = "okay";
++};
++
++&spi2 {
++ status = "okay";
++ assigned-clocks = <&cru CLK_SPI2>;
++ assigned-clock-rates = <200000000>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&spi2m2_cs0 &spi2m2_pins>;
++ num-cs = <1>;
++
++ pmic@0 {
++ compatible = "rockchip,rk806";
++ spi-max-frequency = <1000000>;
++ reg = <0x0>;
++
++ interrupt-parent = <&gpio0>;
++ interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
++
++ pinctrl-names = "default";
++ pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>,
++ <&rk806_dvs2_null>, <&rk806_dvs3_null>;
++
++ system-power-controller;
++
++ vcc1-supply = <&vcc5v0_sys>;
++ vcc2-supply = <&vcc5v0_sys>;
++ vcc3-supply = <&vcc5v0_sys>;
++ vcc4-supply = <&vcc5v0_sys>;
++ vcc5-supply = <&vcc5v0_sys>;
++ vcc6-supply = <&vcc5v0_sys>;
++ vcc7-supply = <&vcc5v0_sys>;
++ vcc8-supply = <&vcc5v0_sys>;
++ vcc9-supply = <&vcc5v0_sys>;
++ vcc10-supply = <&vcc5v0_sys>;
++ vcc11-supply = <&vcc_2v0_pldo_s3>;
++ vcc12-supply = <&vcc5v0_sys>;
++ vcc13-supply = <&vcc_1v1_nldo_s3>;
++ vcc14-supply = <&vcc_1v1_nldo_s3>;
++ vcca-supply = <&vcc5v0_sys>;
++
++ gpio-controller;
++ #gpio-cells = <2>;
++
++ rk806_dvs1_null: dvs1-null-pins {
++ pins = "gpio_pwrctrl1";
++ function = "pin_fun0";
++ };
++
++ rk806_dvs2_null: dvs2-null-pins {
++ pins = "gpio_pwrctrl2";
++ function = "pin_fun0";
++ };
++
++ rk806_dvs3_null: dvs3-null-pins {
++ pins = "gpio_pwrctrl3";
++ function = "pin_fun0";
++ };
++
++ regulators {
++ vdd_gpu_s0: vdd_gpu_mem_s0: dcdc-reg1 {
++ regulator-boot-on;
++ regulator-min-microvolt = <550000>;
++ regulator-max-microvolt = <950000>;
++ regulator-ramp-delay = <12500>;
++ regulator-name = "vdd_gpu_s0";
++ regulator-enable-ramp-delay = <400>;
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vdd_cpu_lit_s0: vdd_cpu_lit_mem_s0: dcdc-reg2 {
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <550000>;
++ regulator-max-microvolt = <950000>;
++ regulator-ramp-delay = <12500>;
++ regulator-name = "vdd_cpu_lit_s0";
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vdd_log_s0: dcdc-reg3 {
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <675000>;
++ regulator-max-microvolt = <750000>;
++ regulator-ramp-delay = <12500>;
++ regulator-name = "vdd_log_s0";
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ regulator-suspend-microvolt = <750000>;
++ };
++ };
++
++ vdd_vdenc_s0: vdd_vdenc_mem_s0: dcdc-reg4 {
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <550000>;
++ regulator-max-microvolt = <950000>;
++ regulator-ramp-delay = <12500>;
++ regulator-name = "vdd_vdenc_s0";
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vdd_ddr_s0: dcdc-reg5 {
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <675000>;
++ regulator-max-microvolt = <900000>;
++ regulator-ramp-delay = <12500>;
++ regulator-name = "vdd_ddr_s0";
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ regulator-suspend-microvolt = <850000>;
++ };
++ };
++
++ vdd2_ddr_s3: dcdc-reg6 {
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-name = "vdd2_ddr_s3";
++
++ regulator-state-mem {
++ regulator-on-in-suspend;
++ };
++ };
++
++ vcc_2v0_pldo_s3: dcdc-reg7 {
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <2000000>;
++ regulator-max-microvolt = <2000000>;
++ regulator-ramp-delay = <12500>;
++ regulator-name = "vdd_2v0_pldo_s3";
++
++ regulator-state-mem {
++ regulator-on-in-suspend;
++ regulator-suspend-microvolt = <2000000>;
++ };
++ };
++
++ vcc_3v3_s3: dcdc-reg8 {
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ regulator-name = "vcc_3v3_s3";
++
++ regulator-state-mem {
++ regulator-on-in-suspend;
++ regulator-suspend-microvolt = <3300000>;
++ };
++ };
++
++ vddq_ddr_s0: dcdc-reg9 {
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-name = "vddq_ddr_s0";
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vcc_1v8_s3: dcdc-reg10 {
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ regulator-name = "vcc_1v8_s3";
++
++ regulator-state-mem {
++ regulator-on-in-suspend;
++ regulator-suspend-microvolt = <1800000>;
++ };
++ };
++
++ avcc_1v8_s0: pldo-reg1 {
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ regulator-name = "avcc_1v8_s0";
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ regulator-suspend-microvolt = <1800000>;
++ };
++ };
++
++ vcc_1v8_s0: pldo-reg2 {
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ regulator-name = "vcc_1v8_s0";
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ regulator-suspend-microvolt = <1800000>;
++ };
++ };
++
++ avdd_1v2_s0: pldo-reg3 {
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <1200000>;
++ regulator-max-microvolt = <1200000>;
++ regulator-name = "avdd_1v2_s0";
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ avcc_3v3_s0: pldo-reg4 {
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ regulator-ramp-delay = <12500>;
++ regulator-name = "avcc_3v3_s0";
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vccio_sd_s0: pldo-reg5 {
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <3300000>;
++ regulator-ramp-delay = <12500>;
++ regulator-name = "vccio_sd_s0";
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ pldo6_s3: pldo-reg6 {
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ regulator-name = "pldo6_s3";
++
++ regulator-state-mem {
++ regulator-on-in-suspend;
++ regulator-suspend-microvolt = <1800000>;
++ };
++ };
++
++ vdd_0v75_s3: nldo-reg1 {
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <750000>;
++ regulator-max-microvolt = <750000>;
++ regulator-name = "vdd_0v75_s3";
++
++ regulator-state-mem {
++ regulator-on-in-suspend;
++ regulator-suspend-microvolt = <750000>;
++ };
++ };
++
++ avdd_ddr_pll_s0: nldo-reg2 {
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <850000>;
++ regulator-max-microvolt = <850000>;
++ regulator-name = "avdd_ddr_pll_s0";
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ regulator-suspend-microvolt = <850000>;
++ };
++ };
++
++ avdd_0v75_s0: nldo-reg3 {
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <750000>;
++ regulator-max-microvolt = <750000>;
++ regulator-name = "avdd_0v75_s0";
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ avdd_0v85_s0: nldo-reg4 {
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <850000>;
++ regulator-max-microvolt = <850000>;
++ regulator-name = "avdd_0v85_s0";
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++
++ vdd_0v75_s0: nldo-reg5 {
++ regulator-always-on;
++ regulator-boot-on;
++ regulator-min-microvolt = <750000>;
++ regulator-max-microvolt = <750000>;
++ regulator-name = "vdd_0v75_s0";
++
++ regulator-state-mem {
++ regulator-off-in-suspend;
++ };
++ };
++ };
++ };
++};
++
++&tsadc {
++ status = "okay";
++};
++
++&u2phy2 {
++ status = "okay";
++};
++
++&u2phy2_host {
++ phy-supply = <&vcc5v0_host_20>;
++ status = "okay";
++};
++
++&uart2 {
++ pinctrl-0 = <&uart2m0_xfer>;
++ status = "okay";
++};
++
++&usb_host0_ehci {
++ status = "okay";
++};
++
++&usb_host0_ohci {
++ status = "okay";
++};
diff --git a/target/linux/rockchip/patches-6.6/113-rock-pi-s-add-led-aliases-and-stop-heartbeat.patch b/target/linux/rockchip/patches-6.6/113-rock-pi-s-add-led-aliases-and-stop-heartbeat.patch
new file mode 100644
index 0000000000..48a617b09a
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/113-rock-pi-s-add-led-aliases-and-stop-heartbeat.patch
@@ -0,0 +1,38 @@
+--- a/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts
+@@ -18,6 +18,10 @@
+ mmc0 = &emmc;
+ mmc1 = &sdmmc;
+ mmc2 = &sdio;
++ led-boot = &blue_led;
++ led-failsafe = &blue_led;
++ led-running = &blue_led;
++ led-upgrade = &blue_led;
+ };
+
+ chosen {
+@@ -29,22 +33,19 @@
+ pinctrl-names = "default";
+ pinctrl-0 = <&green_led>, <&heartbeat_led>;
+
+- green-led {
++ led-0 {
+ color = <LED_COLOR_ID_GREEN>;
+ default-state = "on";
+ function = LED_FUNCTION_POWER;
+ gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
+- label = "rockpis:green:power";
+ linux,default-trigger = "default-on";
+ };
+
+- blue-led {
++ blue_led: led-1 {
+ color = <LED_COLOR_ID_BLUE>;
+ default-state = "on";
+ function = LED_FUNCTION_HEARTBEAT;
+ gpios = <&gpio0 RK_PA5 GPIO_ACTIVE_HIGH>;
+- label = "rockpis:blue:user";
+- linux,default-trigger = "heartbeat";
+ };
+ };
+
diff --git a/target/linux/rockchip/patches-6.6/114-rock-pi-e-add-led-aliases-and-stop-heartbeat.patch b/target/linux/rockchip/patches-6.6/114-rock-pi-e-add-led-aliases-and-stop-heartbeat.patch
new file mode 100644
index 0000000000..e2ea7fdd63
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/114-rock-pi-e-add-led-aliases-and-stop-heartbeat.patch
@@ -0,0 +1,27 @@
+--- a/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts
+@@ -23,6 +23,10 @@
+ aliases {
+ mmc0 = &sdmmc;
+ mmc1 = &emmc;
++ led-boot = &led_blue;
++ led-failsafe = &led_blue;
++ led-running = &led_blue;
++ led-upgrade = &led_blue;
+ };
+
+ chosen {
+@@ -55,10 +59,11 @@
+ pinctrl-0 = <&led_pin>;
+ pinctrl-names = "default";
+
+- led-0 {
++ led_blue: led-0 {
+ color = <LED_COLOR_ID_BLUE>;
++ default-state = "on";
++ function = LED_FUNCTION_HEARTBEAT;
+ gpios = <&gpio3 RK_PA5 GPIO_ACTIVE_LOW>;
+- linux,default-trigger = "heartbeat";
+ };
+ };
+
diff --git a/target/linux/rockchip/patches-6.6/115-rock-3a-add-led-aliases-and-stop-heartbeat.patch b/target/linux/rockchip/patches-6.6/115-rock-3a-add-led-aliases-and-stop-heartbeat.patch
new file mode 100644
index 0000000000..bdcc96ce83
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/115-rock-3a-add-led-aliases-and-stop-heartbeat.patch
@@ -0,0 +1,29 @@
+--- a/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts
+@@ -15,6 +15,10 @@
+ ethernet0 = &gmac1;
+ mmc0 = &sdhci;
+ mmc1 = &sdmmc0;
++ led-boot = &led_blue;
++ led-failsafe = &led_blue;
++ led-running = &led_blue;
++ led-upgrade = &led_blue;
+ };
+
+ chosen: chosen {
+@@ -42,11 +46,11 @@
+ leds {
+ compatible = "gpio-leds";
+
+- led_user: led-0 {
+- gpios = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>;
+- function = LED_FUNCTION_HEARTBEAT;
++ led_blue: led-0 {
+ color = <LED_COLOR_ID_BLUE>;
+- linux,default-trigger = "heartbeat";
++ default-state = "on";
++ function = LED_FUNCTION_HEARTBEAT;
++ gpios = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_user_en>;
+ };
diff --git a/target/linux/rockchip/patches-6.6/116-arm64-dts-rockchip-Update-LED-properties-for-Radxa-Ro.patch b/target/linux/rockchip/patches-6.6/116-arm64-dts-rockchip-Update-LED-properties-for-Radxa-Ro.patch
new file mode 100644
index 0000000000..c09915b0e8
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/116-arm64-dts-rockchip-Update-LED-properties-for-Radxa-Ro.patch
@@ -0,0 +1,38 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Tianling Shen <cnsztl@gmail.com>
+Date: Mon Aug 05 16:14:33 2024 +0800
+Subject: [PATCH] arm64: dts: rockchip: Update LED properties for Radxa
+ Rock 5A
+
+Add OpenWrt's LED aliases for showing system status.
+
+Signed-off-by: Tianling Shen <cnsztl@gmail.com>
+---
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
+@@ -14,6 +14,11 @@
+ aliases {
+ mmc0 = &sdhci;
+ mmc1 = &sdmmc;
++
++ led-boot = &status_led;
++ led-failsafe = &status_led;
++ led-running = &status_led;
++ led-upgrade = &status_led;
+ };
+
+ analog-sound {
+@@ -39,11 +44,10 @@
+ pinctrl-names = "default";
+ pinctrl-0 = <&io_led>;
+
+- io-led {
++ status_led: io-led {
+ color = <LED_COLOR_ID_BLUE>;
+ function = LED_FUNCTION_STATUS;
+ gpios = <&gpio3 RK_PD5 GPIO_ACTIVE_HIGH>;
+- linux,default-trigger = "heartbeat";
+ };
+ };
+
diff --git a/target/linux/rockchip/patches-6.6/117-arm64-dts-rockchip-lower-mmc-speed-for-Radxa-Rock-5A.patch b/target/linux/rockchip/patches-6.6/117-arm64-dts-rockchip-lower-mmc-speed-for-Radxa-Rock-5A.patch
new file mode 100644
index 0000000000..675d083a3a
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/117-arm64-dts-rockchip-lower-mmc-speed-for-Radxa-Rock-5A.patch
@@ -0,0 +1,26 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Tianling Shen <cnsztl@gmail.com>
+Date: Mon Aug 05 16:14:33 2024 +0800
+Subject: [PATCH] arm64: dts: rockchip: lower mmc speed for Radxa Rock 5A
+
+The previously stated speed of sdr-104 in is too high for the hardware
+to reliably communicate with some fast SD cards.
+Rockchip boards have a common bug when operating uhs speed, which will
+hang the system during a soft reboot.
+
+To be on the safe side, lower the speed to workaround.
+
+Signed-off-by: Tianling Shen <cnsztl@gmail.com>
+---
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
+@@ -404,7 +404,7 @@
+ max-frequency = <150000000>;
+ no-sdio;
+ no-mmc;
+- sd-uhs-sdr104;
++ sd-uhs-sdr50;
+ vmmc-supply = <&vcc_3v3_s0>;
+ vqmmc-supply = <&vccio_sd_s0>;
+ status = "okay";
diff --git a/target/linux/rockchip/patches-6.6/118-arm64-dts-rockchip-Update-LED-properties-for-Radxa-Ro.patch b/target/linux/rockchip/patches-6.6/118-arm64-dts-rockchip-Update-LED-properties-for-Radxa-Ro.patch
new file mode 100644
index 0000000000..5ac968aa75
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/118-arm64-dts-rockchip-Update-LED-properties-for-Radxa-Ro.patch
@@ -0,0 +1,38 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Tianling Shen <cnsztl@gmail.com>
+Date: Mon Aug 05 16:14:33 2024 +0800
+Subject: [PATCH] arm64: dts: rockchip: Update LED properties for Radxa
+ Rock 5B
+
+Add OpenWrt's LED aliases for showing system status.
+
+Signed-off-by: Tianling Shen <cnsztl@gmail.com>
+---
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
+@@ -14,6 +14,11 @@
+ mmc0 = &sdhci;
+ mmc1 = &sdmmc;
+ mmc2 = &sdio;
++
++ led-boot = &status_led;
++ led-failsafe = &status_led;
++ led-running = &status_led;
++ led-upgrade = &status_led;
+ };
+
+ chosen {
+@@ -42,11 +47,10 @@
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_rgb_b>;
+
+- led_rgb_b {
++ status_led: led_rgb_b {
+ function = LED_FUNCTION_STATUS;
+ color = <LED_COLOR_ID_BLUE>;
+ gpios = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>;
+- linux,default-trigger = "heartbeat";
+ };
+ };
+
diff --git a/target/linux/rockchip/patches-6.6/119-arm64-dts-rockchip-lower-mmc-speed-for-Radxa-Rock-5B.patch b/target/linux/rockchip/patches-6.6/119-arm64-dts-rockchip-lower-mmc-speed-for-Radxa-Rock-5B.patch
new file mode 100644
index 0000000000..496a2911e0
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/119-arm64-dts-rockchip-lower-mmc-speed-for-Radxa-Rock-5B.patch
@@ -0,0 +1,26 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Tianling Shen <cnsztl@gmail.com>
+Date: Mon Aug 05 16:14:33 2024 +0800
+Subject: [PATCH] arm64: dts: rockchip: lower mmc speed for Radxa Rock 5B
+
+The previously stated speed of sdr-104 in is too high for the hardware
+to reliably communicate with some fast SD cards.
+Rockchip boards have a common bug when operating uhs speed, which will
+hang the system during a soft reboot.
+
+To be on the safe side, lower the speed to workaround.
+
+Signed-off-by: Tianling Shen <cnsztl@gmail.com>
+---
+
+--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
+@@ -419,7 +419,7 @@
+ cap-sd-highspeed;
+ cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
+ disable-wp;
+- sd-uhs-sdr104;
++ sd-uhs-sdr50;
+ vmmc-supply = <&vcc_3v3_s3>;
+ vqmmc-supply = <&vccio_sd_s0>;
+ status = "okay";
diff --git a/target/linux/rockchip/patches-6.6/120-arm64-dts-rockchip-add-led-aliases-and-stop-heartbeat-for-nanopc-t6.patch b/target/linux/rockchip/patches-6.6/120-arm64-dts-rockchip-add-led-aliases-and-stop-heartbeat-for-nanopc-t6.patch
new file mode 100644
index 0000000000..bef4b0fdbb
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/120-arm64-dts-rockchip-add-led-aliases-and-stop-heartbeat-for-nanopc-t6.patch
@@ -0,0 +1,22 @@
+--- a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dts
+@@ -19,6 +19,10 @@
+ aliases {
+ mmc0 = &sdhci;
+ mmc1 = &sdmmc;
++ led-boot = &sys_led;
++ led-failsafe = &sys_led;
++ led-running = &sys_led;
++ led-upgrade = &sys_led;
+ };
+
+ chosen {
+@@ -31,7 +35,7 @@
+ sys_led: led-0 {
+ gpios = <&gpio2 RK_PB7 GPIO_ACTIVE_HIGH>;
+ label = "system-led";
+- linux,default-trigger = "heartbeat";
++ default-state = "on";
+ pinctrl-names = "default";
+ pinctrl-0 = <&sys_led_pin>;
+ };
diff --git a/target/linux/rockchip/patches-6.6/121-arm64-dts-rockchip-lower-mmc-speed-for-nanopc-t6.patch b/target/linux/rockchip/patches-6.6/121-arm64-dts-rockchip-lower-mmc-speed-for-nanopc-t6.patch
new file mode 100644
index 0000000000..c73b807f33
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/121-arm64-dts-rockchip-lower-mmc-speed-for-nanopc-t6.patch
@@ -0,0 +1,11 @@
+--- a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dts
+@@ -547,7 +547,7 @@
+ cap-mmc-highspeed;
+ cap-sd-highspeed;
+ disable-wp;
+- sd-uhs-sdr104;
++ sd-uhs-sdr50;
+ vmmc-supply = <&vcc_3v3_s3>;
+ vqmmc-supply = <&vccio_sd_s0>;
+ status = "okay";
diff --git a/target/linux/rockchip/patches-6.6/122-rock-3c-add-led-aliases-and-stop-heartbeat.patch b/target/linux/rockchip/patches-6.6/122-rock-3c-add-led-aliases-and-stop-heartbeat.patch
new file mode 100644
index 0000000000..ee5a297887
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/122-rock-3c-add-led-aliases-and-stop-heartbeat.patch
@@ -0,0 +1,29 @@
+--- a/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts
+@@ -16,6 +16,10 @@
+ mmc0 = &sdhci;
+ mmc1 = &sdmmc0;
+ mmc2 = &sdmmc1;
++ led-boot = &led_blue;
++ led-failsafe = &led_blue;
++ led-running = &led_blue;
++ led-upgrade = &led_blue;
+ };
+
+ chosen: chosen {
+@@ -43,11 +47,11 @@
+ leds {
+ compatible = "gpio-leds";
+
+- led-0 {
+- gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>;
+- function = LED_FUNCTION_HEARTBEAT;
++ led_blue: led-0 {
+ color = <LED_COLOR_ID_BLUE>;
+- linux,default-trigger = "heartbeat";
++ default-state = "on";
++ function = LED_FUNCTION_HEARTBEAT;
++ gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&user_led2>;
+ };
diff --git a/target/linux/rockchip/patches-6.6/123-radxa-zero-3-add-led-aliases-and-stop-heartbeat.patch b/target/linux/rockchip/patches-6.6/123-radxa-zero-3-add-led-aliases-and-stop-heartbeat.patch
new file mode 100644
index 0000000000..81a86e5edb
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/123-radxa-zero-3-add-led-aliases-and-stop-heartbeat.patch
@@ -0,0 +1,30 @@
+--- a/arch/arm64/boot/dts/rockchip/rk3566-radxa-zero-3.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3566-radxa-zero-3.dtsi
+@@ -6,6 +6,13 @@
+ #include "rk3566.dtsi"
+
+ / {
++ aliases {
++ led-boot = &led_green;
++ led-failsafe = &led_green;
++ led-running = &led_green;
++ led-upgrade = &led_green;
++ };
++
+ chosen {
+ stdout-path = "serial2:1500000n8";
+ };
+@@ -26,12 +33,11 @@
+ pinctrl-names = "default";
+ pinctrl-0 = <&user_led2>;
+
+- led-green {
++ led_green: led-green {
+ color = <LED_COLOR_ID_GREEN>;
+ default-state = "on";
+ function = LED_FUNCTION_HEARTBEAT;
+ gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>;
+- linux,default-trigger = "heartbeat";
+ };
+ };
+
diff --git a/target/linux/rockchip/patches-6.6/124-rock-3b-add-led-aliases-and-stop-heartbeat.patch b/target/linux/rockchip/patches-6.6/124-rock-3b-add-led-aliases-and-stop-heartbeat.patch
new file mode 100644
index 0000000000..420f3ccc4c
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/124-rock-3b-add-led-aliases-and-stop-heartbeat.patch
@@ -0,0 +1,27 @@
+--- a/arch/arm64/boot/dts/rockchip/rk3568-rock-3b.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3568-rock-3b.dts
+@@ -18,6 +18,10 @@
+ mmc0 = &sdhci;
+ mmc1 = &sdmmc0;
+ mmc2 = &sdmmc2;
++ led-boot = &led_green;
++ led-failsafe = &led_green;
++ led-running = &led_green;
++ led-upgrade = &led_green;
+ };
+
+ chosen {
+@@ -47,12 +51,11 @@
+ pinctrl-names = "default";
+ pinctrl-0 = <&led>;
+
+- led-0 {
++ led_green: led-0 {
+ color = <LED_COLOR_ID_GREEN>;
+ default-state = "on";
+ function = LED_FUNCTION_HEARTBEAT;
+ gpios = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>;
+- linux,default-trigger = "heartbeat";
+ };
+ };
+
diff --git a/target/linux/rockchip/patches-6.6/300-hwrng-add-Rockchip-SoC-hwrng-driver.patch b/target/linux/rockchip/patches-6.6/300-hwrng-add-Rockchip-SoC-hwrng-driver.patch
deleted file mode 100644
index 0be9a7300b..0000000000
--- a/target/linux/rockchip/patches-6.6/300-hwrng-add-Rockchip-SoC-hwrng-driver.patch
+++ /dev/null
@@ -1,340 +0,0 @@
-From patchwork Sat Nov 12 14:10:58 2022
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-X-Patchwork-Submitter: Aurelien Jarno <aurelien@aurel32.net>
-X-Patchwork-Id: 13041222
-Return-Path:
- <linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org>
-X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on
- aws-us-west-2-korg-lkml-1.web.codeaurora.org
-From: Aurelien Jarno <aurelien@aurel32.net>
-To: Olivia Mackall <olivia@selenic.com>,
- Herbert Xu <herbert@gondor.apana.org.au>,
- Rob Herring <robh+dt@kernel.org>,
- Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>,
- Heiko Stuebner <heiko@sntech.de>,
- Philipp Zabel <p.zabel@pengutronix.de>,
- Lin Jinhan <troy.lin@rock-chips.com>
-Cc: linux-crypto@vger.kernel.org (open list:HARDWARE RANDOM NUMBER GENERATOR
- CORE),
- devicetree@vger.kernel.org (open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE
- BINDINGS),
- linux-arm-kernel@lists.infradead.org (moderated list:ARM/Rockchip SoC
- support),
- linux-rockchip@lists.infradead.org (open list:ARM/Rockchip SoC support),
- linux-kernel@vger.kernel.org (open list),
- Aurelien Jarno <aurelien@aurel32.net>
-Subject: [PATCH v1 2/3] hwrng: add Rockchip SoC hwrng driver
-Date: Sat, 12 Nov 2022 15:10:58 +0100
-Message-Id: <20221112141059.3802506-3-aurelien@aurel32.net>
-In-Reply-To: <20221112141059.3802506-1-aurelien@aurel32.net>
-References: <20221112141059.3802506-1-aurelien@aurel32.net>
-MIME-Version: 1.0
-List-Id: <linux-arm-kernel.lists.infradead.org>
-
-Rockchip SoCs used to have a random number generator as part of their
-crypto device, and support for it has to be added to the corresponding
-driver. However newer Rockchip SoCs like the RK356x have an independent
-True Random Number Generator device. This patch adds a driver for it,
-greatly inspired from the downstream driver.
-
-The TRNG device does not seem to have a signal conditionner and the FIPS
-140-2 test returns a lot of failures. They can be reduced by increasing
-RK_RNG_SAMPLE_CNT, in a tradeoff between quality and speed. This value
-has been adjusted to get ~90% of successes and the quality value has
-been set accordingly.
-
-Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
----
- drivers/char/hw_random/Kconfig | 14 ++
- drivers/char/hw_random/Makefile | 1 +
- drivers/char/hw_random/rockchip-rng.c | 251 ++++++++++++++++++++++++++
- 3 files changed, 266 insertions(+)
- create mode 100644 drivers/char/hw_random/rockchip-rng.c
-
---- a/drivers/char/hw_random/Kconfig
-+++ b/drivers/char/hw_random/Kconfig
-@@ -573,6 +573,20 @@ config HW_RANDOM_JH7110
- To compile this driver as a module, choose M here.
- The module will be called jh7110-trng.
-
-+config HW_RANDOM_ROCKCHIP
-+ tristate "Rockchip True Random Number Generator"
-+ depends on HW_RANDOM && (ARCH_ROCKCHIP || COMPILE_TEST)
-+ depends on HAS_IOMEM
-+ default HW_RANDOM
-+ help
-+ This driver provides kernel-side support for the True Random Number
-+ Generator hardware found on some Rockchip SoC like RK3566 or RK3568.
-+
-+ To compile this driver as a module, choose M here: the
-+ module will be called rockchip-rng.
-+
-+ If unsure, say Y.
-+
- endif # HW_RANDOM
-
- config UML_RANDOM
---- a/drivers/char/hw_random/Makefile
-+++ b/drivers/char/hw_random/Makefile
-@@ -48,4 +48,5 @@ obj-$(CONFIG_HW_RANDOM_XIPHERA) += xiphe
- obj-$(CONFIG_HW_RANDOM_ARM_SMCCC_TRNG) += arm_smccc_trng.o
- obj-$(CONFIG_HW_RANDOM_CN10K) += cn10k-rng.o
- obj-$(CONFIG_HW_RANDOM_POLARFIRE_SOC) += mpfs-rng.o
-+obj-$(CONFIG_HW_RANDOM_ROCKCHIP) += rockchip-rng.o
- obj-$(CONFIG_HW_RANDOM_JH7110) += jh7110-trng.o
---- /dev/null
-+++ b/drivers/char/hw_random/rockchip-rng.c
-@@ -0,0 +1,251 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * rockchip-rng.c True Random Number Generator driver for Rockchip SoCs
-+ *
-+ * Copyright (c) 2018, Fuzhou Rockchip Electronics Co., Ltd.
-+ * Copyright (c) 2022, Aurelien Jarno
-+ * Authors:
-+ * Lin Jinhan <troy.lin@rock-chips.com>
-+ * Aurelien Jarno <aurelien@aurel32.net>
-+ */
-+#include <linux/clk.h>
-+#include <linux/hw_random.h>
-+#include <linux/io.h>
-+#include <linux/iopoll.h>
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/of_platform.h>
-+#include <linux/pm_runtime.h>
-+#include <linux/reset.h>
-+#include <linux/slab.h>
-+
-+#define RK_RNG_AUTOSUSPEND_DELAY 100
-+#define RK_RNG_MAX_BYTE 32
-+#define RK_RNG_POLL_PERIOD_US 100
-+#define RK_RNG_POLL_TIMEOUT_US 10000
-+
-+/*
-+ * TRNG collects osc ring output bit every RK_RNG_SAMPLE_CNT time. The value is
-+ * a tradeoff between speed and quality and has been adjusted to get a quality
-+ * of ~900 (~90% of FIPS 140-2 successes).
-+ */
-+#define RK_RNG_SAMPLE_CNT 1000
-+
-+/* TRNG registers from RK3568 TRM-Part2, section 5.4.1 */
-+#define TRNG_RST_CTL 0x0004
-+#define TRNG_RNG_CTL 0x0400
-+#define TRNG_RNG_CTL_LEN_64_BIT (0x00 << 4)
-+#define TRNG_RNG_CTL_LEN_128_BIT (0x01 << 4)
-+#define TRNG_RNG_CTL_LEN_192_BIT (0x02 << 4)
-+#define TRNG_RNG_CTL_LEN_256_BIT (0x03 << 4)
-+#define TRNG_RNG_CTL_OSC_RING_SPEED_0 (0x00 << 2)
-+#define TRNG_RNG_CTL_OSC_RING_SPEED_1 (0x01 << 2)
-+#define TRNG_RNG_CTL_OSC_RING_SPEED_2 (0x02 << 2)
-+#define TRNG_RNG_CTL_OSC_RING_SPEED_3 (0x03 << 2)
-+#define TRNG_RNG_CTL_ENABLE BIT(1)
-+#define TRNG_RNG_CTL_START BIT(0)
-+#define TRNG_RNG_SAMPLE_CNT 0x0404
-+#define TRNG_RNG_DOUT_0 0x0410
-+#define TRNG_RNG_DOUT_1 0x0414
-+#define TRNG_RNG_DOUT_2 0x0418
-+#define TRNG_RNG_DOUT_3 0x041c
-+#define TRNG_RNG_DOUT_4 0x0420
-+#define TRNG_RNG_DOUT_5 0x0424
-+#define TRNG_RNG_DOUT_6 0x0428
-+#define TRNG_RNG_DOUT_7 0x042c
-+
-+struct rk_rng {
-+ struct hwrng rng;
-+ void __iomem *base;
-+ struct reset_control *rst;
-+ int clk_num;
-+ struct clk_bulk_data *clk_bulks;
-+};
-+
-+/* The mask determine the bits that are updated */
-+static void rk_rng_write_ctl(struct rk_rng *rng, u32 val, u32 mask)
-+{
-+ writel_relaxed((mask << 16) | val, rng->base + TRNG_RNG_CTL);
-+}
-+
-+static int rk_rng_init(struct hwrng *rng)
-+{
-+ struct rk_rng *rk_rng = container_of(rng, struct rk_rng, rng);
-+ u32 reg;
-+ int ret;
-+
-+ /* start clocks */
-+ ret = clk_bulk_prepare_enable(rk_rng->clk_num, rk_rng->clk_bulks);
-+ if (ret < 0) {
-+ dev_err((struct device *) rk_rng->rng.priv,
-+ "Failed to enable clks %d\n", ret);
-+ return ret;
-+ }
-+
-+ /* set the sample period */
-+ writel(RK_RNG_SAMPLE_CNT, rk_rng->base + TRNG_RNG_SAMPLE_CNT);
-+
-+ /* set osc ring speed and enable it */
-+ reg = TRNG_RNG_CTL_LEN_256_BIT |
-+ TRNG_RNG_CTL_OSC_RING_SPEED_0 |
-+ TRNG_RNG_CTL_ENABLE;
-+ rk_rng_write_ctl(rk_rng, reg, 0xffff);
-+
-+ return 0;
-+}
-+
-+static void rk_rng_cleanup(struct hwrng *rng)
-+{
-+ struct rk_rng *rk_rng = container_of(rng, struct rk_rng, rng);
-+ u32 reg;
-+
-+ /* stop TRNG */
-+ reg = 0;
-+ rk_rng_write_ctl(rk_rng, reg, 0xffff);
-+
-+ /* stop clocks */
-+ clk_bulk_disable_unprepare(rk_rng->clk_num, rk_rng->clk_bulks);
-+}
-+
-+static int rk_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait)
-+{
-+ struct rk_rng *rk_rng = container_of(rng, struct rk_rng, rng);
-+ u32 reg;
-+ int ret = 0;
-+ int i;
-+
-+ pm_runtime_get_sync((struct device *) rk_rng->rng.priv);
-+
-+ /* Start collecting random data */
-+ reg = TRNG_RNG_CTL_START;
-+ rk_rng_write_ctl(rk_rng, reg, reg);
-+
-+ ret = readl_poll_timeout(rk_rng->base + TRNG_RNG_CTL, reg,
-+ !(reg & TRNG_RNG_CTL_START),
-+ RK_RNG_POLL_PERIOD_US,
-+ RK_RNG_POLL_TIMEOUT_US);
-+ if (ret < 0)
-+ goto out;
-+
-+ /* Read random data stored in big endian in the registers */
-+ ret = min_t(size_t, max, RK_RNG_MAX_BYTE);
-+ for (i = 0; i < ret; i += 4) {
-+ reg = readl_relaxed(rk_rng->base + TRNG_RNG_DOUT_0 + i);
-+ *(u32 *)(buf + i) = be32_to_cpu(reg);
-+ }
-+
-+out:
-+ pm_runtime_mark_last_busy((struct device *) rk_rng->rng.priv);
-+ pm_runtime_put_sync_autosuspend((struct device *) rk_rng->rng.priv);
-+
-+ return ret;
-+}
-+
-+static int rk_rng_probe(struct platform_device *pdev)
-+{
-+ struct device *dev = &pdev->dev;
-+ struct rk_rng *rk_rng;
-+ int ret;
-+
-+ rk_rng = devm_kzalloc(dev, sizeof(struct rk_rng), GFP_KERNEL);
-+ if (!rk_rng)
-+ return -ENOMEM;
-+
-+ rk_rng->base = devm_platform_ioremap_resource(pdev, 0);
-+ if (IS_ERR(rk_rng->base))
-+ return PTR_ERR(rk_rng->base);
-+
-+ rk_rng->clk_num = devm_clk_bulk_get_all(dev, &rk_rng->clk_bulks);
-+ if (rk_rng->clk_num < 0)
-+ return dev_err_probe(dev, rk_rng->clk_num,
-+ "Failed to get clks property\n");
-+
-+ rk_rng->rst = devm_reset_control_array_get(&pdev->dev, false, false);
-+ if (IS_ERR(rk_rng->rst))
-+ return dev_err_probe(dev, PTR_ERR(rk_rng->rst),
-+ "Failed to get reset property\n");
-+
-+ reset_control_assert(rk_rng->rst);
-+ udelay(2);
-+ reset_control_deassert(rk_rng->rst);
-+
-+ platform_set_drvdata(pdev, rk_rng);
-+
-+ rk_rng->rng.name = dev_driver_string(dev);
-+#ifndef CONFIG_PM
-+ rk_rng->rng.init = rk_rng_init;
-+ rk_rng->rng.cleanup = rk_rng_cleanup;
-+#endif
-+ rk_rng->rng.read = rk_rng_read;
-+ rk_rng->rng.priv = (unsigned long) dev;
-+ rk_rng->rng.quality = 900;
-+
-+ pm_runtime_set_autosuspend_delay(dev, RK_RNG_AUTOSUSPEND_DELAY);
-+ pm_runtime_use_autosuspend(dev);
-+ pm_runtime_enable(dev);
-+
-+ ret = devm_hwrng_register(dev, &rk_rng->rng);
-+ if (ret)
-+ return dev_err_probe(&pdev->dev, ret, "Failed to register Rockchip hwrng\n");
-+
-+ dev_info(&pdev->dev, "Registered Rockchip hwrng\n");
-+
-+ return 0;
-+}
-+
-+static int rk_rng_remove(struct platform_device *pdev)
-+{
-+ pm_runtime_disable(&pdev->dev);
-+
-+ return 0;
-+}
-+
-+#ifdef CONFIG_PM
-+static int rk_rng_runtime_suspend(struct device *dev)
-+{
-+ struct rk_rng *rk_rng = dev_get_drvdata(dev);
-+
-+ rk_rng_cleanup(&rk_rng->rng);
-+
-+ return 0;
-+}
-+
-+static int rk_rng_runtime_resume(struct device *dev)
-+{
-+ struct rk_rng *rk_rng = dev_get_drvdata(dev);
-+
-+ return rk_rng_init(&rk_rng->rng);
-+}
-+#endif
-+
-+static const struct dev_pm_ops rk_rng_pm_ops = {
-+ SET_RUNTIME_PM_OPS(rk_rng_runtime_suspend,
-+ rk_rng_runtime_resume, NULL)
-+ SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
-+ pm_runtime_force_resume)
-+};
-+
-+static const struct of_device_id rk_rng_dt_match[] = {
-+ {
-+ .compatible = "rockchip,rk3568-rng",
-+ },
-+ {},
-+};
-+
-+MODULE_DEVICE_TABLE(of, rk_rng_dt_match);
-+
-+static struct platform_driver rk_rng_driver = {
-+ .driver = {
-+ .name = "rockchip-rng",
-+ .pm = &rk_rng_pm_ops,
-+ .of_match_table = rk_rng_dt_match,
-+ },
-+ .probe = rk_rng_probe,
-+ .remove = rk_rng_remove,
-+};
-+
-+module_platform_driver(rk_rng_driver);
-+
-+MODULE_DESCRIPTION("Rockchip True Random Number Generator driver");
-+MODULE_AUTHOR("Lin Jinhan <troy.lin@rock-chips.com>, Aurelien Jarno <aurelien@aurel32.net>");
-+MODULE_LICENSE("GPL v2");
diff --git a/target/linux/rockchip/patches-6.6/300-hwrng-add-hwrng-driver-for-Rockchip-RK3568-SoC.patch b/target/linux/rockchip/patches-6.6/300-hwrng-add-hwrng-driver-for-Rockchip-RK3568-SoC.patch
new file mode 100644
index 0000000000..683d1b1d5e
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/300-hwrng-add-hwrng-driver-for-Rockchip-RK3568-SoC.patch
@@ -0,0 +1,290 @@
+From cea47ad1fbd46d3096fcf5c6905db3d12b5da960 Mon Sep 17 00:00:00 2001
+From: Aurelien Jarno <aurelien@aurel32.net>
+Date: Sun, 21 Jul 2024 01:48:04 +0100
+Subject: [PATCH 2/3] hwrng: add hwrng driver for Rockchip RK3568 SoC
+
+Rockchip SoCs used to have a random number generator as part of their
+crypto device, and support for it has to be added to the corresponding
+driver. However newer Rockchip SoCs like the RK3568 have an independent
+True Random Number Generator device. This patch adds a driver for it,
+greatly inspired from the downstream driver.
+
+The TRNG device does not seem to have a signal conditionner and the FIPS
+140-2 test returns a lot of failures. They can be reduced by increasing
+rockchip,sample-count in DT, in a tradeoff between quality and speed.
+
+Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
+[daniel@makrotpia.org: code style fixes, add DT properties]
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+---
+ drivers/char/hw_random/Kconfig | 14 ++
+ drivers/char/hw_random/Makefile | 1 +
+ drivers/char/hw_random/rockchip-rng.c | 230 ++++++++++++++++++++++++++
+ 4 files changed, 246 insertions(+)
+ create mode 100644 drivers/char/hw_random/rockchip-rng.c
+
+--- a/drivers/char/hw_random/Kconfig
++++ b/drivers/char/hw_random/Kconfig
+@@ -573,6 +573,20 @@ config HW_RANDOM_JH7110
+ To compile this driver as a module, choose M here.
+ The module will be called jh7110-trng.
+
++config HW_RANDOM_ROCKCHIP
++ tristate "Rockchip True Random Number Generator"
++ depends on HW_RANDOM && (ARCH_ROCKCHIP || COMPILE_TEST)
++ depends on HAS_IOMEM
++ default HW_RANDOM
++ help
++ This driver provides kernel-side support for the True Random Number
++ Generator hardware found on some Rockchip SoC like RK3566 or RK3568.
++
++ To compile this driver as a module, choose M here: the
++ module will be called rockchip-rng.
++
++ If unsure, say Y.
++
+ endif # HW_RANDOM
+
+ config UML_RANDOM
+--- a/drivers/char/hw_random/Makefile
++++ b/drivers/char/hw_random/Makefile
+@@ -48,4 +48,5 @@ obj-$(CONFIG_HW_RANDOM_XIPHERA) += xiphe
+ obj-$(CONFIG_HW_RANDOM_ARM_SMCCC_TRNG) += arm_smccc_trng.o
+ obj-$(CONFIG_HW_RANDOM_CN10K) += cn10k-rng.o
+ obj-$(CONFIG_HW_RANDOM_POLARFIRE_SOC) += mpfs-rng.o
++obj-$(CONFIG_HW_RANDOM_ROCKCHIP) += rockchip-rng.o
+ obj-$(CONFIG_HW_RANDOM_JH7110) += jh7110-trng.o
+--- /dev/null
++++ b/drivers/char/hw_random/rockchip-rng.c
+@@ -0,0 +1,230 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * rockchip-rng.c True Random Number Generator driver for Rockchip RK3568 SoC
++ *
++ * Copyright (c) 2018, Fuzhou Rockchip Electronics Co., Ltd.
++ * Copyright (c) 2022, Aurelien Jarno
++ * Authors:
++ * Lin Jinhan <troy.lin@rock-chips.com>
++ * Aurelien Jarno <aurelien@aurel32.net>
++ */
++#include <linux/clk.h>
++#include <linux/hw_random.h>
++#include <linux/io.h>
++#include <linux/iopoll.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/platform_device.h>
++#include <linux/pm_runtime.h>
++#include <linux/reset.h>
++#include <linux/slab.h>
++
++#define RK_RNG_AUTOSUSPEND_DELAY 100
++#define RK_RNG_MAX_BYTE 32
++#define RK_RNG_POLL_PERIOD_US 100
++#define RK_RNG_POLL_TIMEOUT_US 10000
++
++/* TRNG registers from RK3568 TRM-Part2, section 5.4.1 */
++#define TRNG_RST_CTL 0x0004
++#define TRNG_RNG_CTL 0x0400
++#define TRNG_RNG_CTL_LEN_64_BIT (0x00 << 4)
++#define TRNG_RNG_CTL_LEN_128_BIT (0x01 << 4)
++#define TRNG_RNG_CTL_LEN_192_BIT (0x02 << 4)
++#define TRNG_RNG_CTL_LEN_256_BIT (0x03 << 4)
++#define TRNG_RNG_CTL_OSC_RING_SPEED_0 (0x00 << 2)
++#define TRNG_RNG_CTL_OSC_RING_SPEED_1 (0x01 << 2)
++#define TRNG_RNG_CTL_OSC_RING_SPEED_2 (0x02 << 2)
++#define TRNG_RNG_CTL_OSC_RING_SPEED_3 (0x03 << 2)
++#define TRNG_RNG_CTL_MASK GENMASK(15, 0)
++#define TRNG_RNG_CTL_ENABLE BIT(1)
++#define TRNG_RNG_CTL_START BIT(0)
++#define TRNG_RNG_SAMPLE_CNT 0x0404
++#define TRNG_RNG_DOUT 0x0410
++
++struct rk_rng {
++ struct hwrng rng;
++ void __iomem *base;
++ struct reset_control *rst;
++ int clk_num;
++ struct clk_bulk_data *clk_bulks;
++ u32 sample_cnt;
++};
++
++/* The mask in the upper 16 bits determines the bits that are updated */
++static void rk_rng_write_ctl(struct rk_rng *rng, u32 val, u32 mask)
++{
++ writel((mask << 16) | val, rng->base + TRNG_RNG_CTL);
++}
++
++static int rk_rng_init(struct hwrng *rng)
++{
++ struct rk_rng *rk_rng = container_of(rng, struct rk_rng, rng);
++ int ret;
++
++ /* start clocks */
++ ret = clk_bulk_prepare_enable(rk_rng->clk_num, rk_rng->clk_bulks);
++ if (ret < 0) {
++ dev_err((struct device *) rk_rng->rng.priv,
++ "Failed to enable clks %d\n", ret);
++ return ret;
++ }
++
++ /* set the sample period */
++ writel(rk_rng->sample_cnt, rk_rng->base + TRNG_RNG_SAMPLE_CNT);
++
++ /* set osc ring speed and enable it */
++ rk_rng_write_ctl(rk_rng, TRNG_RNG_CTL_LEN_256_BIT |
++ TRNG_RNG_CTL_OSC_RING_SPEED_0 |
++ TRNG_RNG_CTL_ENABLE,
++ TRNG_RNG_CTL_MASK);
++
++ return 0;
++}
++
++static void rk_rng_cleanup(struct hwrng *rng)
++{
++ struct rk_rng *rk_rng = container_of(rng, struct rk_rng, rng);
++
++ /* stop TRNG */
++ rk_rng_write_ctl(rk_rng, 0, TRNG_RNG_CTL_MASK);
++
++ /* stop clocks */
++ clk_bulk_disable_unprepare(rk_rng->clk_num, rk_rng->clk_bulks);
++}
++
++static int rk_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait)
++{
++ struct rk_rng *rk_rng = container_of(rng, struct rk_rng, rng);
++ size_t to_read = min_t(size_t, max, RK_RNG_MAX_BYTE);
++ u32 reg;
++ int ret = 0;
++
++ ret = pm_runtime_resume_and_get((struct device *) rk_rng->rng.priv);
++ if (ret < 0)
++ return ret;
++
++ /* Start collecting random data */
++ rk_rng_write_ctl(rk_rng, TRNG_RNG_CTL_START, TRNG_RNG_CTL_START);
++
++ ret = readl_poll_timeout(rk_rng->base + TRNG_RNG_CTL, reg,
++ !(reg & TRNG_RNG_CTL_START),
++ RK_RNG_POLL_PERIOD_US,
++ RK_RNG_POLL_TIMEOUT_US);
++ if (ret < 0)
++ goto out;
++
++ /* Read random data stored in the registers */
++ memcpy_fromio(buf, rk_rng->base + TRNG_RNG_DOUT, to_read);
++out:
++ pm_runtime_mark_last_busy((struct device *) rk_rng->rng.priv);
++ pm_runtime_put_sync_autosuspend((struct device *) rk_rng->rng.priv);
++
++ return (ret < 0) ? ret : to_read;
++}
++
++static int rk_rng_probe(struct platform_device *pdev)
++{
++ struct device *dev = &pdev->dev;
++ struct rk_rng *rk_rng;
++ u32 quality;
++ int ret;
++
++ rk_rng = devm_kzalloc(dev, sizeof(*rk_rng), GFP_KERNEL);
++ if (!rk_rng)
++ return -ENOMEM;
++
++ rk_rng->base = devm_platform_ioremap_resource(pdev, 0);
++ if (IS_ERR(rk_rng->base))
++ return PTR_ERR(rk_rng->base);
++
++ rk_rng->clk_num = devm_clk_bulk_get_all(dev, &rk_rng->clk_bulks);
++ if (rk_rng->clk_num < 0)
++ return dev_err_probe(dev, rk_rng->clk_num,
++ "Failed to get clks property\n");
++
++ rk_rng->rst = devm_reset_control_array_get_exclusive(&pdev->dev);
++ if (IS_ERR(rk_rng->rst))
++ return dev_err_probe(dev, PTR_ERR(rk_rng->rst),
++ "Failed to get reset property\n");
++
++ ret = of_property_read_u32(dev->of_node, "rockchip,sample-count", &rk_rng->sample_cnt);
++ if (ret)
++ return dev_err_probe(dev, ret, "Failed to get sample-count property\n");
++
++ ret = of_property_read_u32(dev->of_node, "quality", &quality);
++ if (ret || quality > 1024)
++ return dev_err_probe(dev, ret, "Failed to get quality property\n");
++
++ reset_control_assert(rk_rng->rst);
++ udelay(2);
++ reset_control_deassert(rk_rng->rst);
++
++ platform_set_drvdata(pdev, rk_rng);
++
++ rk_rng->rng.name = dev_driver_string(dev);
++ if (!IS_ENABLED(CONFIG_PM)) {
++ rk_rng->rng.init = rk_rng_init;
++ rk_rng->rng.cleanup = rk_rng_cleanup;
++ }
++ rk_rng->rng.read = rk_rng_read;
++ rk_rng->rng.priv = (unsigned long) dev;
++ rk_rng->rng.quality = quality;
++
++ pm_runtime_set_autosuspend_delay(dev, RK_RNG_AUTOSUSPEND_DELAY);
++ pm_runtime_use_autosuspend(dev);
++ devm_pm_runtime_enable(dev);
++
++ ret = devm_hwrng_register(dev, &rk_rng->rng);
++ if (ret)
++ return dev_err_probe(&pdev->dev, ret, "Failed to register Rockchip hwrng\n");
++
++ return 0;
++}
++
++static int __maybe_unused rk_rng_runtime_suspend(struct device *dev)
++{
++ struct rk_rng *rk_rng = dev_get_drvdata(dev);
++
++ rk_rng_cleanup(&rk_rng->rng);
++
++ return 0;
++}
++
++static int __maybe_unused rk_rng_runtime_resume(struct device *dev)
++{
++ struct rk_rng *rk_rng = dev_get_drvdata(dev);
++
++ return rk_rng_init(&rk_rng->rng);
++}
++
++static const struct dev_pm_ops rk_rng_pm_ops = {
++ SET_RUNTIME_PM_OPS(rk_rng_runtime_suspend,
++ rk_rng_runtime_resume, NULL)
++ SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
++ pm_runtime_force_resume)
++};
++
++static const struct of_device_id rk_rng_dt_match[] = {
++ { .compatible = "rockchip,rk3568-rng", },
++ { /* sentinel */ },
++};
++
++MODULE_DEVICE_TABLE(of, rk_rng_dt_match);
++
++static struct platform_driver rk_rng_driver = {
++ .driver = {
++ .name = "rockchip-rng",
++ .pm = &rk_rng_pm_ops,
++ .of_match_table = rk_rng_dt_match,
++ },
++ .probe = rk_rng_probe,
++};
++
++module_platform_driver(rk_rng_driver);
++
++MODULE_DESCRIPTION("Rockchip RK3568 True Random Number Generator driver");
++MODULE_AUTHOR("Lin Jinhan <troy.lin@rock-chips.com>");
++MODULE_AUTHOR("Aurelien Jarno <aurelien@aurel32.net>");
++MODULE_AUTHOR("Daniel Golle <daniel@makrotopia.org>");
++MODULE_LICENSE("GPL");
diff --git a/target/linux/rockchip/patches-6.6/301-arm64-dts-rockchip-add-DT-entry-for-RNG-to-RK3568.patch b/target/linux/rockchip/patches-6.6/301-arm64-dts-rockchip-add-DT-entry-for-RNG-to-RK3568.patch
new file mode 100644
index 0000000000..130bf6723c
--- /dev/null
+++ b/target/linux/rockchip/patches-6.6/301-arm64-dts-rockchip-add-DT-entry-for-RNG-to-RK3568.patch
@@ -0,0 +1,49 @@
+From 756e7d3251ad8f6c72e7bf4c476537a89f673e38 Mon Sep 17 00:00:00 2001
+From: Aurelien Jarno <aurelien@aurel32.net>
+Date: Sun, 21 Jul 2024 01:48:38 +0100
+Subject: [PATCH 3/3] arm64: dts: rockchip: add DT entry for RNG to RK356x
+
+Enable the just added Rockchip RNG driver for RK356x SoCs.
+
+Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ arch/arm64/boot/dts/rockchip/rk3568.dtsi | 7 +++++++
+ arch/arm64/boot/dts/rockchip/rk356x.dtsi | 10 ++++++++++
+ 2 files changed, 17 insertions(+)
+
+--- a/arch/arm64/boot/dts/rockchip/rk3568.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3568.dtsi
+@@ -257,6 +257,13 @@
+ };
+ };
+
++&rng {
++ rockchip,sample-count = <1000>;
++ quality = <900>;
++
++ status = "okay";
++};
++
+ &usb_host0_xhci {
+ phys = <&usb2phy0_otg>, <&combphy0 PHY_TYPE_USB3>;
+ phy-names = "usb2-phy", "usb3-phy";
+--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
+@@ -1106,6 +1106,16 @@
+ status = "disabled";
+ };
+
++ rng: rng@fe388000 {
++ compatible = "rockchip,rk3568-rng";
++ reg = <0x0 0xfe388000 0x0 0x4000>;
++ clocks = <&cru CLK_TRNG_NS>, <&cru HCLK_TRNG_NS>;
++ clock-names = "core", "ahb";
++ resets = <&cru SRST_TRNG_NS>;
++ reset-names = "reset";
++ status = "disabled";
++ };
++
+ i2s0_8ch: i2s@fe400000 {
+ compatible = "rockchip,rk3568-i2s-tdm";
+ reg = <0x0 0xfe400000 0x0 0x1000>;
diff --git a/target/linux/rockchip/patches-6.6/301-arm64-dts-rockchip-add-DT-entry-for-RNG-to-RK356x.patch b/target/linux/rockchip/patches-6.6/301-arm64-dts-rockchip-add-DT-entry-for-RNG-to-RK356x.patch
deleted file mode 100644
index 3e65de7a20..0000000000
--- a/target/linux/rockchip/patches-6.6/301-arm64-dts-rockchip-add-DT-entry-for-RNG-to-RK356x.patch
+++ /dev/null
@@ -1,56 +0,0 @@
-From patchwork Sat Nov 12 14:10:59 2022
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-X-Patchwork-Submitter: Aurelien Jarno <aurelien@aurel32.net>
-X-Patchwork-Id: 13041221
-From: Aurelien Jarno <aurelien@aurel32.net>
-To: Olivia Mackall <olivia@selenic.com>,
- Herbert Xu <herbert@gondor.apana.org.au>,
- Rob Herring <robh+dt@kernel.org>,
- Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>,
- Heiko Stuebner <heiko@sntech.de>,
- Philipp Zabel <p.zabel@pengutronix.de>,
- Lin Jinhan <troy.lin@rock-chips.com>
-Cc: linux-crypto@vger.kernel.org (open list:HARDWARE RANDOM NUMBER GENERATOR
- CORE),
- devicetree@vger.kernel.org (open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE
- BINDINGS),
- linux-arm-kernel@lists.infradead.org (moderated list:ARM/Rockchip SoC
- support),
- linux-rockchip@lists.infradead.org (open list:ARM/Rockchip SoC support),
- linux-kernel@vger.kernel.org (open list),
- Aurelien Jarno <aurelien@aurel32.net>
-Subject: [PATCH v1 3/3] arm64: dts: rockchip: add DT entry for RNG to RK356x
-Date: Sat, 12 Nov 2022 15:10:59 +0100
-Message-Id: <20221112141059.3802506-4-aurelien@aurel32.net>
-In-Reply-To: <20221112141059.3802506-1-aurelien@aurel32.net>
-References: <20221112141059.3802506-1-aurelien@aurel32.net>
-MIME-Version: 1.0
-List-Id: <linux-arm-kernel.lists.infradead.org>
-
-Enable the just added Rockchip RNG driver for RK356x SoCs.
-
-Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
----
- arch/arm64/boot/dts/rockchip/rk356x.dtsi | 9 +++++++++
- 1 file changed, 9 insertions(+)
-
---- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi
-+++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
-@@ -1848,6 +1848,15 @@
- };
- };
-
-+ rng: rng@fe388000 {
-+ compatible = "rockchip,rk3568-rng";
-+ reg = <0x0 0xfe388000 0x0 0x4000>;
-+ clocks = <&cru CLK_TRNG_NS>, <&cru HCLK_TRNG_NS>;
-+ clock-names = "trng_clk", "trng_hclk";
-+ resets = <&cru SRST_TRNG_NS>;
-+ reset-names = "reset";
-+ };
-+
- pinctrl: pinctrl {
- compatible = "rockchip,rk3568-pinctrl";
- rockchip,grf = <&grf>;
diff --git a/target/linux/starfive/Makefile b/target/linux/starfive/Makefile
index f71f57e7f7..22bd463858 100644
--- a/target/linux/starfive/Makefile
+++ b/target/linux/starfive/Makefile
@@ -10,7 +10,7 @@ BOARDNAME:=StarFive JH71x0 (7100/7110)
FEATURES:=ext4
KERNELNAME:=Image dtbs
-KERNEL_PATCHVER:=6.1
+KERNEL_PATCHVER:=6.6
include $(INCLUDE_DIR)/target.mk
diff --git a/target/linux/starfive/config-6.1 b/target/linux/starfive/config-6.1
deleted file mode 100644
index 6da229ddb5..0000000000
--- a/target/linux/starfive/config-6.1
+++ /dev/null
@@ -1,555 +0,0 @@
-CONFIG_64BIT=y
-CONFIG_AMBA_PL08X=y
-CONFIG_ARCH_CLOCKSOURCE_INIT=y
-CONFIG_ARCH_DMA_ADDR_T_64BIT=y
-CONFIG_ARCH_HIBERNATION_POSSIBLE=y
-CONFIG_ARCH_MMAP_RND_BITS=18
-CONFIG_ARCH_MMAP_RND_BITS_MAX=24
-CONFIG_ARCH_MMAP_RND_BITS_MIN=18
-CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=17
-CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y
-CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y
-CONFIG_ARCH_RV64I=y
-CONFIG_ARCH_SELECT_MEMORY_MODEL=y
-CONFIG_ARCH_SIFIVE=y
-CONFIG_ARCH_SPARSEMEM_ENABLE=y
-CONFIG_ARCH_STACKWALK=y
-CONFIG_ARCH_STARFIVE=y
-CONFIG_ARCH_WANTS_THP_SWAP=y
-CONFIG_ARM_AMBA=y
-# CONFIG_ARM_MHU_V2 is not set
-CONFIG_ASN1=y
-CONFIG_ASSOCIATIVE_ARRAY=y
-CONFIG_AUXILIARY_BUS=y
-CONFIG_CC_HAVE_STACKPROTECTOR_TLS=y
-CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
-CONFIG_CC_NO_ARRAY_BOUNDS=y
-CONFIG_CHECKPOINT_RESTORE=y
-CONFIG_CLKSRC_MMIO=y
-CONFIG_CLK_ANALOGBITS_WRPLL_CLN28HPC=y
-CONFIG_CLK_SIFIVE=y
-CONFIG_CLK_SIFIVE_PRCI=y
-CONFIG_CLK_STARFIVE_JH7100=y
-CONFIG_CLK_STARFIVE_JH7100_AUDIO=y
-CONFIG_CLK_STARFIVE_JH7110_AON=y
-CONFIG_CLK_STARFIVE_JH7110_ISP=y
-CONFIG_CLK_STARFIVE_JH7110_PLL=y
-CONFIG_CLK_STARFIVE_JH7110_STG=y
-CONFIG_CLK_STARFIVE_JH7110_SYS=y
-CONFIG_CLK_STARFIVE_JH7110_VOUT=y
-CONFIG_CLK_STARFIVE_JH71X0=y
-CONFIG_CLONE_BACKWARDS=y
-CONFIG_CLZ_TAB=y
-CONFIG_CMODEL_MEDANY=y
-# CONFIG_CMODEL_MEDLOW is not set
-CONFIG_COMMON_CLK=y
-CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
-# CONFIG_COMPAT_32BIT_TIME is not set
-CONFIG_CONFIGFS_FS=y
-CONFIG_CONTEXT_TRACKING=y
-CONFIG_CONTEXT_TRACKING_IDLE=y
-CONFIG_CONTIG_ALLOC=y
-CONFIG_CPUFREQ_DT=y
-CONFIG_CPUFREQ_DT_PLATDEV=y
-CONFIG_CPU_FREQ=y
-CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
-CONFIG_CPU_FREQ_GOV_ATTR_SET=y
-CONFIG_CPU_FREQ_GOV_COMMON=y
-CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
-CONFIG_CPU_FREQ_GOV_ONDEMAND=y
-CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
-CONFIG_CPU_FREQ_GOV_POWERSAVE=y
-CONFIG_CPU_FREQ_GOV_USERSPACE=y
-CONFIG_CPU_FREQ_STAT=y
-CONFIG_CPU_IDLE=y
-CONFIG_CPU_IDLE_GOV_MENU=y
-CONFIG_CPU_IDLE_MULTIPLE_DRIVERS=y
-CONFIG_CPU_PM=y
-CONFIG_CPU_RMAP=y
-CONFIG_CRASH_CORE=y
-CONFIG_CRC16=y
-CONFIG_CRC7=y
-CONFIG_CRC_ITU_T=y
-CONFIG_CRYPTO_BLAKE2B=y
-CONFIG_CRYPTO_CMAC=y
-CONFIG_CRYPTO_CRC32C=y
-CONFIG_CRYPTO_DEV_JH7110=y
-CONFIG_CRYPTO_DRBG=y
-CONFIG_CRYPTO_DRBG_HMAC=y
-CONFIG_CRYPTO_DRBG_MENU=y
-CONFIG_CRYPTO_ECB=y
-CONFIG_CRYPTO_ECC=y
-CONFIG_CRYPTO_ECDH=y
-CONFIG_CRYPTO_ENGINE=y
-CONFIG_CRYPTO_HASH_INFO=y
-CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_HW=y
-CONFIG_CRYPTO_JITTERENTROPY=y
-CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
-CONFIG_CRYPTO_LIB_POLY1305_RSIZE=1
-CONFIG_CRYPTO_LIB_SHA1=y
-CONFIG_CRYPTO_LIB_SHA256=y
-CONFIG_CRYPTO_LIB_UTILS=y
-CONFIG_CRYPTO_RNG=y
-CONFIG_CRYPTO_RNG2=y
-CONFIG_CRYPTO_RNG_DEFAULT=y
-CONFIG_CRYPTO_RSA=y
-CONFIG_CRYPTO_SHA256=y
-CONFIG_CRYPTO_SHA512=y
-CONFIG_CRYPTO_SM3=y
-CONFIG_CRYPTO_SM3_GENERIC=y
-CONFIG_CRYPTO_USER=y
-CONFIG_CRYPTO_USER_API=y
-CONFIG_CRYPTO_USER_API_AEAD=y
-CONFIG_CRYPTO_USER_API_HASH=y
-CONFIG_CRYPTO_USER_API_RNG=y
-CONFIG_CRYPTO_USER_API_SKCIPHER=y
-CONFIG_CRYPTO_XXHASH=y
-CONFIG_CRYPTO_ZSTD=y
-CONFIG_DEBUG_ATOMIC_SLEEP=y
-CONFIG_DEBUG_GPIO=y
-CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_PINCTRL=y
-CONFIG_DEBUG_RODATA_TEST=y
-CONFIG_DEBUG_RT_MUTEXES=y
-CONFIG_DEBUG_RWSEMS=y
-CONFIG_DEBUG_SECTION_MISMATCH=y
-CONFIG_DEBUG_SG=y
-CONFIG_DEBUG_SPINLOCK=y
-CONFIG_DEBUG_TIMEKEEPING=y
-CONFIG_DEBUG_WX=y
-CONFIG_DECOMPRESS_GZIP=y
-# CONFIG_DEVFREQ_GOV_PASSIVE is not set
-# CONFIG_DEVFREQ_GOV_PERFORMANCE is not set
-# CONFIG_DEVFREQ_GOV_POWERSAVE is not set
-# CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND is not set
-# CONFIG_DEVFREQ_GOV_USERSPACE is not set
-# CONFIG_DEVFREQ_THERMAL is not set
-CONFIG_DEVTMPFS=y
-CONFIG_DEVTMPFS_MOUNT=y
-# CONFIG_DEVTMPFS_SAFE is not set
-CONFIG_DMADEVICES=y
-CONFIG_DMADEVICES_DEBUG=y
-CONFIG_DMADEVICES_VDEBUG=y
-CONFIG_DMA_ENGINE=y
-CONFIG_DMA_OF=y
-CONFIG_DMA_SHARED_BUFFER=y
-CONFIG_DMA_VIRTUAL_CHANNELS=y
-# CONFIG_DPM_WATCHDOG is not set
-CONFIG_DTC=y
-CONFIG_DT_IDLE_GENPD=y
-CONFIG_DT_IDLE_STATES=y
-CONFIG_DWMAC_DWC_QOS_ETH=y
-# CONFIG_DWMAC_GENERIC is not set
-CONFIG_DWMAC_STARFIVE=y
-CONFIG_DW_AXI_DMAC=y
-CONFIG_EDAC_SUPPORT=y
-CONFIG_EEPROM_AT24=y
-CONFIG_EFI=y
-CONFIG_EFIVAR_FS=y
-# CONFIG_EFI_BOOTLOADER_CONTROL is not set
-# CONFIG_EFI_CAPSULE_LOADER is not set
-# CONFIG_EFI_COCO_SECRET is not set
-# CONFIG_EFI_DISABLE_PCI_DMA is not set
-CONFIG_EFI_DISABLE_RUNTIME=y
-CONFIG_EFI_EARLYCON=y
-CONFIG_EFI_ESRT=y
-CONFIG_EFI_GENERIC_STUB=y
-CONFIG_EFI_PARAMS_FROM_FDT=y
-CONFIG_EFI_RUNTIME_WRAPPERS=y
-CONFIG_EFI_STUB=y
-# CONFIG_EFI_TEST is not set
-# CONFIG_EFI_ZBOOT is not set
-CONFIG_ERRATA_SIFIVE=y
-CONFIG_ERRATA_SIFIVE_CIP_1200=y
-CONFIG_ERRATA_SIFIVE_CIP_453=y
-# CONFIG_ERRATA_THEAD is not set
-CONFIG_EXCLUSIVE_SYSTEM_RAM=y
-CONFIG_EXT4_FS=y
-CONFIG_EXT4_FS_POSIX_ACL=y
-CONFIG_EXTCON=y
-CONFIG_FAILOVER=y
-CONFIG_FANOTIFY=y
-CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-15"
-CONFIG_FAT_DEFAULT_UTF8=y
-CONFIG_FAT_FS=y
-CONFIG_FIXED_PHY=y
-CONFIG_FIX_EARLYCON_MEM=y
-CONFIG_FONT_8x16=y
-CONFIG_FONT_AUTOSELECT=y
-CONFIG_FONT_SUPPORT=y
-CONFIG_FPU=y
-CONFIG_FS_IOMAP=y
-CONFIG_FS_MBCACHE=y
-CONFIG_FS_POSIX_ACL=y
-CONFIG_FWNODE_MDIO=y
-CONFIG_FW_LOADER_PAGED_BUF=y
-CONFIG_FW_LOADER_SYSFS=y
-CONFIG_GCC11_NO_ARRAY_BOUNDS=y
-CONFIG_GENERIC_ALLOCATOR=y
-CONFIG_GENERIC_ARCH_TOPOLOGY=y
-CONFIG_GENERIC_BUG=y
-CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
-CONFIG_GENERIC_CSUM=y
-CONFIG_GENERIC_EARLY_IOREMAP=y
-CONFIG_GENERIC_GETTIMEOFDAY=y
-CONFIG_GENERIC_IDLE_POLL_SETUP=y
-CONFIG_GENERIC_IOREMAP=y
-CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
-CONFIG_GENERIC_IRQ_MIGRATION=y
-CONFIG_GENERIC_IRQ_MULTI_HANDLER=y
-CONFIG_GENERIC_IRQ_SHOW=y
-CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
-CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y
-CONFIG_GENERIC_MSI_IRQ=y
-CONFIG_GENERIC_MSI_IRQ_DOMAIN=y
-CONFIG_GENERIC_PCI_IOMAP=y
-CONFIG_GENERIC_PHY=y
-CONFIG_GENERIC_PHY_MIPI_DPHY=y
-CONFIG_GENERIC_PINCONF=y
-CONFIG_GENERIC_PINCTRL_GROUPS=y
-CONFIG_GENERIC_PINMUX_FUNCTIONS=y
-CONFIG_GENERIC_SCHED_CLOCK=y
-CONFIG_GENERIC_SMP_IDLE_THREAD=y
-CONFIG_GENERIC_STRNCPY_FROM_USER=y
-CONFIG_GENERIC_STRNLEN_USER=y
-CONFIG_GENERIC_TIME_VSYSCALL=y
-CONFIG_GLOB=y
-CONFIG_GPIOLIB_FASTPATH_LIMIT=128
-CONFIG_GPIOLIB_IRQCHIP=y
-CONFIG_GPIO_CDEV=y
-CONFIG_GPIO_TPS65086=y
-CONFIG_HARDIRQS_SW_RESEND=y
-CONFIG_HAS_DMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT_MAP=y
-CONFIG_HOTPLUG_CPU=y
-CONFIG_HUGETLBFS=y
-CONFIG_HUGETLB_PAGE=y
-CONFIG_HVC_DRIVER=y
-CONFIG_HVC_RISCV_SBI=y
-CONFIG_HWMON=y
-CONFIG_HW_RANDOM=y
-CONFIG_HW_RANDOM_JH7110=y
-CONFIG_HW_RANDOM_STARFIVE_VIC=y
-CONFIG_I2C=y
-CONFIG_I2C_ALGOBIT=y
-CONFIG_I2C_BOARDINFO=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_DESIGNWARE_CORE=y
-CONFIG_I2C_DESIGNWARE_PLATFORM=y
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_IRQCHIP=y
-CONFIG_IRQ_DOMAIN=y
-CONFIG_IRQ_DOMAIN_HIERARCHY=y
-CONFIG_IRQ_FORCED_THREADING=y
-CONFIG_IRQ_WORK=y
-CONFIG_JBD2=y
-CONFIG_JH71XX_PMU=y
-CONFIG_JUMP_LABEL=y
-CONFIG_LIBFDT=y
-CONFIG_LOCKUP_DETECTOR=y
-CONFIG_LOCK_DEBUGGING_SUPPORT=y
-CONFIG_LOCK_SPIN_ON_OWNER=y
-CONFIG_LSM=""
-CONFIG_MARVELL_PHY=y
-CONFIG_MDIO_BUS=y
-CONFIG_MDIO_DEVICE=y
-CONFIG_MDIO_DEVRES=y
-CONFIG_MEMFD_CREATE=y
-CONFIG_MEMORY_ISOLATION=y
-CONFIG_MEMTEST=y
-CONFIG_MFD_AXP20X=y
-CONFIG_MFD_AXP20X_I2C=y
-CONFIG_MFD_CORE=y
-CONFIG_MFD_SYSCON=y
-CONFIG_MFD_TPS65086=y
-CONFIG_MICREL_PHY=y
-CONFIG_MICROCHIP_PHY=y
-CONFIG_MIGRATION=y
-CONFIG_MMC=y
-CONFIG_MMC_BLOCK=y
-CONFIG_MMC_DEBUG=y
-CONFIG_MMC_DW=y
-# CONFIG_MMC_DW_BLUEFIELD is not set
-# CONFIG_MMC_DW_EXYNOS is not set
-# CONFIG_MMC_DW_HI3798CV200 is not set
-# CONFIG_MMC_DW_K3 is not set
-# CONFIG_MMC_DW_PCI is not set
-CONFIG_MMC_DW_PLTFM=y
-CONFIG_MMC_DW_STARFIVE=y
-CONFIG_MMIOWB=y
-CONFIG_MODULES_TREE_LOOKUP=y
-CONFIG_MODULES_USE_ELF_RELA=y
-CONFIG_MODULE_SECTIONS=y
-CONFIG_MOTORCOMM_PHY=y
-CONFIG_MPILIB=y
-CONFIG_MTD_SPI_NOR=y
-CONFIG_MUTEX_SPIN_ON_OWNER=y
-CONFIG_NAMESPACES=y
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NET_FAILOVER=y
-CONFIG_NET_FLOW_LIMIT=y
-CONFIG_NET_NS=y
-CONFIG_NET_SELFTESTS=y
-CONFIG_NLS=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_DEFAULT="iso8859-15"
-CONFIG_NLS_ISO8859_1=y
-CONFIG_NLS_ISO8859_15=y
-CONFIG_NO_HZ_COMMON=y
-CONFIG_NO_HZ_IDLE=y
-# CONFIG_NONPORTABLE is not set
-CONFIG_NR_CPUS=8
-CONFIG_NVMEM=y
-CONFIG_NVMEM_SYSFS=y
-CONFIG_NVME_CORE=y
-CONFIG_NVME_HWMON=y
-# CONFIG_NVME_MULTIPATH is not set
-CONFIG_OF=y
-CONFIG_OF_ADDRESS=y
-CONFIG_OF_DMA_DEFAULT_COHERENT=y
-CONFIG_OF_DYNAMIC=y
-CONFIG_OF_EARLY_FLATTREE=y
-CONFIG_OF_FLATTREE=y
-CONFIG_OF_GPIO=y
-CONFIG_OF_IRQ=y
-CONFIG_OF_KOBJ=y
-CONFIG_OF_MDIO=y
-CONFIG_OF_OVERLAY=y
-CONFIG_OF_RESOLVE=y
-CONFIG_OID_REGISTRY=y
-CONFIG_OVERLAY_FS_INDEX=y
-CONFIG_OVERLAY_FS_METACOPY=y
-CONFIG_OVERLAY_FS_REDIRECT_DIR=y
-CONFIG_PADATA=y
-CONFIG_PAGE_EXTENSION=y
-CONFIG_PAGE_OFFSET=0xff60000000000000
-CONFIG_PAGE_POOL=y
-CONFIG_PAGE_REPORTING=y
-CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
-CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
-CONFIG_PCI=y
-CONFIG_PCIE_CADENCE=y
-CONFIG_PCIE_CADENCE_HOST=y
-CONFIG_PCIE_CADENCE_PLAT=y
-CONFIG_PCIE_CADENCE_PLAT_HOST=y
-# CONFIG_PCIE_FU740 is not set
-# CONFIG_PCIE_STARFIVE is not set
-CONFIG_PCI_DOMAINS=y
-CONFIG_PCI_DOMAINS_GENERIC=y
-CONFIG_PCI_MSI=y
-CONFIG_PCI_MSI_IRQ_DOMAIN=y
-CONFIG_PCS_XPCS=y
-CONFIG_PERF_EVENTS=y
-CONFIG_PGTABLE_LEVELS=5
-CONFIG_PHYLIB=y
-CONFIG_PHYLINK=y
-CONFIG_PHYS_ADDR_T_64BIT=y
-CONFIG_PHY_STARFIVE_DPHY_RX=y
-CONFIG_PHY_STARFIVE_JH7110_PCIE=y
-CONFIG_PHY_STARFIVE_JH7110_USB=y
-CONFIG_PINCTRL=y
-CONFIG_PINCTRL_STARFIVE_JH7100=y
-CONFIG_PINCTRL_STARFIVE_JH7110=y
-CONFIG_PINCTRL_STARFIVE_JH7110_AON=y
-CONFIG_PINCTRL_STARFIVE_JH7110_SYS=y
-CONFIG_PM=y
-CONFIG_PM_ADVANCED_DEBUG=y
-CONFIG_PM_CLK=y
-CONFIG_PM_DEBUG=y
-CONFIG_PM_DEVFREQ=y
-# CONFIG_PM_DEVFREQ_EVENT is not set
-CONFIG_PM_GENERIC_DOMAINS=y
-CONFIG_PM_GENERIC_DOMAINS_OF=y
-CONFIG_PM_OPP=y
-CONFIG_PORTABLE=y
-CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_POSIX_MQUEUE_SYSCTL=y
-CONFIG_POWER_RESET=y
-CONFIG_POWER_RESET_GPIO_RESTART=y
-CONFIG_POWER_RESET_SYSCON=y
-CONFIG_POWER_RESET_SYSCON_POWEROFF=y
-# CONFIG_POWER_RESET_TPS65086 is not set
-CONFIG_PPS=y
-CONFIG_PREEMPT_COUNT=y
-CONFIG_PREEMPT_NONE_BUILD=y
-CONFIG_PRINTK_TIME=y
-CONFIG_PROC_CHILDREN=y
-CONFIG_PROC_KCORE=y
-CONFIG_PTDUMP_CORE=y
-CONFIG_PTP_1588_CLOCK=y
-CONFIG_PTP_1588_CLOCK_OPTIONAL=y
-CONFIG_PWM=y
-# CONFIG_PWM_SIFIVE is not set
-CONFIG_PWM_SIFIVE_PTC=y
-CONFIG_PWM_STARFIVE_PTC=y
-CONFIG_PWM_SYSFS=y
-CONFIG_QUEUED_RWLOCKS=y
-CONFIG_RANDSTRUCT_NONE=y
-CONFIG_RATIONAL=y
-CONFIG_RCU_EQS_DEBUG=y
-CONFIG_RD_GZIP=y
-CONFIG_REALTEK_PHY=y
-CONFIG_REGMAP=y
-CONFIG_REGMAP_I2C=y
-CONFIG_REGMAP_IRQ=y
-CONFIG_REGMAP_MMIO=y
-CONFIG_REGULATOR=y
-CONFIG_REGULATOR_AXP20X=y
-CONFIG_REGULATOR_TPS65086=y
-# CONFIG_RESET_ATTACK_MITIGATION is not set
-CONFIG_RESET_CONTROLLER=y
-CONFIG_RESET_SIMPLE=y
-CONFIG_RESET_STARFIVE_JH7100=y
-CONFIG_RESET_STARFIVE_JH7100_AUDIO=y
-CONFIG_RESET_STARFIVE_JH7110=y
-CONFIG_RESET_STARFIVE_JH71X0=y
-CONFIG_RFS_ACCEL=y
-CONFIG_RISCV=y
-CONFIG_RISCV_ALTERNATIVE=y
-CONFIG_RISCV_BOOT_SPINWAIT=y
-CONFIG_RISCV_DMA_NONCOHERENT=y
-CONFIG_RISCV_INTC=y
-CONFIG_RISCV_ISA_C=y
-# CONFIG_RISCV_ISA_SVPBMT is not set
-CONFIG_RISCV_ISA_ZICBOM=y
-CONFIG_RISCV_PMU=y
-CONFIG_RISCV_PMU_LEGACY=y
-CONFIG_RISCV_PMU_SBI=y
-CONFIG_RISCV_SBI=y
-CONFIG_RISCV_SBI_CPUIDLE=y
-CONFIG_RISCV_SBI_V01=y
-CONFIG_RISCV_TIMER=y
-CONFIG_RPMSG=y
-CONFIG_RPMSG_CHAR=y
-# CONFIG_RPMSG_CTRL is not set
-CONFIG_RPMSG_NS=y
-# CONFIG_RPMSG_TTY is not set
-CONFIG_RPMSG_VIRTIO=y
-CONFIG_RPS=y
-CONFIG_RTC_CLASS=y
-# CONFIG_RTC_DRV_EFI is not set
-CONFIG_RTC_DRV_GOLDFISH=y
-CONFIG_RTC_DRV_HYM8563=y
-CONFIG_RTC_I2C_AND_SPI=y
-CONFIG_RWSEM_SPIN_ON_OWNER=y
-CONFIG_SCSI=y
-CONFIG_SCSI_COMMON=y
-CONFIG_SCSI_VIRTIO=y
-CONFIG_SENSORS_SFCTEMP=y
-# CONFIG_SERIAL_8250_16550A_VARIANTS is not set
-CONFIG_SERIAL_8250_DW=y
-CONFIG_SERIAL_8250_DWLIB=y
-CONFIG_SERIAL_8250_EXTENDED=y
-CONFIG_SERIAL_8250_MANY_PORTS=y
-CONFIG_SERIAL_8250_NR_UARTS=6
-CONFIG_SERIAL_8250_RUNTIME_UARTS=6
-# CONFIG_SERIAL_8250_SHARE_IRQ is not set
-CONFIG_SERIAL_EARLYCON_RISCV_SBI=y
-CONFIG_SERIAL_MCTRL_GPIO=y
-CONFIG_SERIAL_OF_PLATFORM=y
-CONFIG_SERIAL_SIFIVE=y
-CONFIG_SERIAL_SIFIVE_CONSOLE=y
-CONFIG_SGL_ALLOC=y
-CONFIG_SG_POOL=y
-CONFIG_SIFIVE_CCACHE=y
-CONFIG_SIFIVE_PLIC=y
-CONFIG_SMP=y
-# CONFIG_SND_SOC_STARFIVE is not set
-CONFIG_SOCK_DIAG=y
-CONFIG_SOCK_RX_QUEUE_MAPPING=y
-# CONFIG_SOC_MICROCHIP_POLARFIRE is not set
-CONFIG_SOC_SIFIVE=y
-CONFIG_SOC_STARFIVE=y
-# CONFIG_SOC_VIRT is not set
-CONFIG_SOFTLOCKUP_DETECTOR=y
-CONFIG_SOUND=y
-CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
-CONFIG_SPARSE_IRQ=y
-CONFIG_SPI=y
-CONFIG_SPI_CADENCE_QUADSPI=y
-CONFIG_SPI_DYNAMIC=y
-CONFIG_SPI_MASTER=y
-CONFIG_SPI_MEM=y
-CONFIG_SPI_SPIDEV=y
-CONFIG_SRCU=y
-CONFIG_STARFIVE_TIMER=y
-CONFIG_STARFIVE_WATCHDOG=y
-CONFIG_STMMAC_ETH=y
-CONFIG_STMMAC_PLATFORM=y
-CONFIG_STMMAC_SELFTESTS=y
-CONFIG_SWIOTLB=y
-CONFIG_SWPHY=y
-CONFIG_SYNC_FILE=y
-CONFIG_SYSCTL_EXCEPTION_TRACE=y
-# CONFIG_SYSFB_SIMPLEFB is not set
-CONFIG_THERMAL=y
-CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
-CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
-CONFIG_THERMAL_GOV_STEP_WISE=y
-CONFIG_THERMAL_OF=y
-CONFIG_THREAD_INFO_IN_TASK=y
-CONFIG_TICK_CPU_ACCOUNTING=y
-CONFIG_TIMER_OF=y
-CONFIG_TIMER_PROBE=y
-CONFIG_TMPFS_POSIX_ACL=y
-CONFIG_TOOLCHAIN_HAS_ZICBOM=y
-CONFIG_TOOLCHAIN_HAS_ZIHINTPAUSE=y
-CONFIG_TOOLCHAIN_NEEDS_EXPLICIT_ZICSR_ZIFENCEI=y
-CONFIG_TREE_RCU=y
-CONFIG_TREE_SRCU=y
-CONFIG_TTY_PRINTK=y
-CONFIG_TTY_PRINTK_LEVEL=6
-CONFIG_TUNE_GENERIC=y
-CONFIG_UCS2_STRING=y
-CONFIG_UNINLINE_SPIN_UNLOCK=y
-CONFIG_USB=y
-CONFIG_USB_COMMON=y
-CONFIG_USB_CONFIGFS=y
-# CONFIG_USB_CONFIGFS_ACM is not set
-# CONFIG_USB_CONFIGFS_ECM is not set
-# CONFIG_USB_CONFIGFS_ECM_SUBSET is not set
-# CONFIG_USB_CONFIGFS_EEM is not set
-CONFIG_USB_CONFIGFS_F_FS=y
-# CONFIG_USB_CONFIGFS_F_HID is not set
-# CONFIG_USB_CONFIGFS_F_LB_SS is not set
-# CONFIG_USB_CONFIGFS_F_MIDI is not set
-# CONFIG_USB_CONFIGFS_F_PRINTER is not set
-# CONFIG_USB_CONFIGFS_F_UAC1 is not set
-# CONFIG_USB_CONFIGFS_F_UAC1_LEGACY is not set
-# CONFIG_USB_CONFIGFS_F_UAC2 is not set
-# CONFIG_USB_CONFIGFS_F_UVC is not set
-CONFIG_USB_CONFIGFS_MASS_STORAGE=y
-# CONFIG_USB_CONFIGFS_NCM is not set
-# CONFIG_USB_CONFIGFS_OBEX is not set
-# CONFIG_USB_CONFIGFS_RNDIS is not set
-# CONFIG_USB_CONFIGFS_SERIAL is not set
-CONFIG_USB_F_FS=y
-CONFIG_USB_F_MASS_STORAGE=y
-CONFIG_USB_GADGET=y
-CONFIG_USB_LIBCOMPOSITE=y
-CONFIG_USB_PCI=y
-CONFIG_USB_PHY=y
-CONFIG_USB_ROLE_SWITCH=y
-CONFIG_USB_SUPPORT=y
-# CONFIG_USB_UHCI_HCD is not set
-CONFIG_USELIB=y
-CONFIG_USER_NS=y
-CONFIG_VFAT_FS=y
-# CONFIG_VIRTIO_BLK is not set
-# CONFIG_VIRTIO_NET is not set
-CONFIG_VMAP_STACK=y
-CONFIG_WATCHDOG_CORE=y
-CONFIG_WATCHDOG_SYSFS=y
-CONFIG_WERROR=y
-CONFIG_WQ_WATCHDOG=y
-CONFIG_XPS=y
-CONFIG_XXHASH=y
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZONE_DMA32=y
diff --git a/target/linux/starfive/config-6.6 b/target/linux/starfive/config-6.6
new file mode 100644
index 0000000000..cb39210a42
--- /dev/null
+++ b/target/linux/starfive/config-6.6
@@ -0,0 +1,579 @@
+CONFIG_64BIT=y
+# CONFIG_ACPI is not set
+CONFIG_AMBA_PL08X=y
+CONFIG_ARCH_CLOCKSOURCE_INIT=y
+CONFIG_ARCH_DMA_ADDR_T_64BIT=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_MMAP_RND_BITS=18
+CONFIG_ARCH_MMAP_RND_BITS_MAX=24
+CONFIG_ARCH_MMAP_RND_BITS_MIN=18
+CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=17
+CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y
+CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y
+# CONFIG_ARCH_RV32I is not set
+CONFIG_ARCH_RV64I=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_ARCH_SIFIVE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_STACKWALK=y
+CONFIG_ARCH_STARFIVE=y
+# CONFIG_ARCH_THEAD is not set
+CONFIG_ARCH_WANTS_THP_SWAP=y
+CONFIG_ARM_AMBA=y
+# CONFIG_ARM_MHU_V2 is not set
+CONFIG_ASN1=y
+CONFIG_ASSOCIATIVE_ARRAY=y
+CONFIG_AUXILIARY_BUS=y
+# CONFIG_AX45MP_L2_CACHE is not set
+# CONFIG_BT_AICUSB is not set
+CONFIG_CC_HAVE_STACKPROTECTOR_TLS=y
+CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
+CONFIG_CC_NO_ARRAY_BOUNDS=y
+CONFIG_CHECKPOINT_RESTORE=y
+CONFIG_CLKSRC_MMIO=y
+CONFIG_CLK_ANALOGBITS_WRPLL_CLN28HPC=y
+CONFIG_CLK_SIFIVE=y
+CONFIG_CLK_SIFIVE_PRCI=y
+CONFIG_CLK_STARFIVE_JH7100=y
+CONFIG_CLK_STARFIVE_JH7100_AUDIO=y
+CONFIG_CLK_STARFIVE_JH7110_AON=y
+CONFIG_CLK_STARFIVE_JH7110_ISP=y
+CONFIG_CLK_STARFIVE_JH7110_PLL=y
+CONFIG_CLK_STARFIVE_JH7110_STG=y
+CONFIG_CLK_STARFIVE_JH7110_SYS=y
+CONFIG_CLK_STARFIVE_JH7110_VOUT=y
+CONFIG_CLK_STARFIVE_JH71X0=y
+CONFIG_CLONE_BACKWARDS=y
+CONFIG_CLZ_TAB=y
+CONFIG_CMODEL_MEDANY=y
+# CONFIG_CMODEL_MEDLOW is not set
+CONFIG_COMMON_CLK=y
+CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
+# CONFIG_COMPAT_32BIT_TIME is not set
+CONFIG_CONFIGFS_FS=y
+CONFIG_CONTEXT_TRACKING=y
+CONFIG_CONTEXT_TRACKING_IDLE=y
+CONFIG_CONTIG_ALLOC=y
+CONFIG_CPUFREQ_DT=y
+CONFIG_CPUFREQ_DT_PLATDEV=y
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_ATTR_SET=y
+CONFIG_CPU_FREQ_GOV_COMMON=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_STAT=y
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_IDLE_GOV_MENU=y
+CONFIG_CPU_IDLE_MULTIPLE_DRIVERS=y
+CONFIG_CPU_PM=y
+CONFIG_CPU_RMAP=y
+CONFIG_CRASH_CORE=y
+CONFIG_CRC16=y
+CONFIG_CRC7=y
+CONFIG_CRC_ITU_T=y
+CONFIG_CRYPTO_BLAKE2B=y
+CONFIG_CRYPTO_CMAC=y
+CONFIG_CRYPTO_CRC32C=y
+CONFIG_CRYPTO_DEV_JH7110=y
+CONFIG_CRYPTO_DRBG=y
+CONFIG_CRYPTO_DRBG_HMAC=y
+CONFIG_CRYPTO_DRBG_MENU=y
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_ECC=y
+CONFIG_CRYPTO_ECDH=y
+CONFIG_CRYPTO_ENGINE=y
+CONFIG_CRYPTO_HASH_INFO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_HW=y
+CONFIG_CRYPTO_JITTERENTROPY=y
+CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
+CONFIG_CRYPTO_LIB_POLY1305_RSIZE=1
+CONFIG_CRYPTO_LIB_SHA1=y
+CONFIG_CRYPTO_LIB_SHA256=y
+CONFIG_CRYPTO_LIB_UTILS=y
+CONFIG_CRYPTO_RNG=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_RNG_DEFAULT=y
+CONFIG_CRYPTO_RSA=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_SM3=y
+CONFIG_CRYPTO_SM3_GENERIC=y
+CONFIG_CRYPTO_USER=y
+CONFIG_CRYPTO_USER_API=y
+CONFIG_CRYPTO_USER_API_AEAD=y
+CONFIG_CRYPTO_USER_API_HASH=y
+CONFIG_CRYPTO_USER_API_RNG=y
+CONFIG_CRYPTO_USER_API_SKCIPHER=y
+CONFIG_CRYPTO_XXHASH=y
+CONFIG_CRYPTO_ZSTD=y
+CONFIG_DEBUG_ATOMIC_SLEEP=y
+CONFIG_DEBUG_GPIO=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_PINCTRL=y
+CONFIG_DEBUG_RODATA_TEST=y
+CONFIG_DEBUG_RT_MUTEXES=y
+CONFIG_DEBUG_RWSEMS=y
+CONFIG_DEBUG_SECTION_MISMATCH=y
+CONFIG_DEBUG_SG=y
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_TIMEKEEPING=y
+CONFIG_DEBUG_WX=y
+CONFIG_DECOMPRESS_GZIP=y
+# CONFIG_DEVFREQ_GOV_PASSIVE is not set
+# CONFIG_DEVFREQ_GOV_PERFORMANCE is not set
+# CONFIG_DEVFREQ_GOV_POWERSAVE is not set
+# CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND is not set
+# CONFIG_DEVFREQ_GOV_USERSPACE is not set
+# CONFIG_DEVFREQ_THERMAL is not set
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_DEVTMPFS_SAFE is not set
+CONFIG_DMADEVICES=y
+CONFIG_DMADEVICES_DEBUG=y
+CONFIG_DMADEVICES_VDEBUG=y
+CONFIG_DMA_ENGINE=y
+CONFIG_DMA_OF=y
+CONFIG_DMA_SHARED_BUFFER=y
+CONFIG_DMA_VIRTUAL_CHANNELS=y
+# CONFIG_DPM_WATCHDOG is not set
+CONFIG_DTC=y
+CONFIG_DT_IDLE_GENPD=y
+CONFIG_DT_IDLE_STATES=y
+CONFIG_DWMAC_DWC_QOS_ETH=y
+# CONFIG_DWMAC_GENERIC is not set
+CONFIG_DWMAC_STARFIVE=y
+CONFIG_DW_AXI_DMAC=y
+CONFIG_EDAC_SUPPORT=y
+CONFIG_EEPROM_AT24=y
+CONFIG_EFI=y
+CONFIG_EFIVAR_FS=y
+# CONFIG_EFI_BOOTLOADER_CONTROL is not set
+# CONFIG_EFI_CAPSULE_LOADER is not set
+# CONFIG_EFI_COCO_SECRET is not set
+# CONFIG_EFI_DISABLE_PCI_DMA is not set
+CONFIG_EFI_DISABLE_RUNTIME=y
+CONFIG_EFI_EARLYCON=y
+CONFIG_EFI_ESRT=y
+CONFIG_EFI_GENERIC_STUB=y
+CONFIG_EFI_PARAMS_FROM_FDT=y
+CONFIG_EFI_RUNTIME_WRAPPERS=y
+CONFIG_EFI_STUB=y
+# CONFIG_EFI_TEST is not set
+# CONFIG_EFI_ZBOOT is not set
+# CONFIG_ERRATA_ANDES is not set
+CONFIG_ERRATA_STARFIVE_JH7100=y
+CONFIG_ERRATA_SIFIVE=y
+CONFIG_ERRATA_SIFIVE_CIP_1200=y
+CONFIG_ERRATA_SIFIVE_CIP_453=y
+# CONFIG_ERRATA_THEAD is not set
+CONFIG_EXCLUSIVE_SYSTEM_RAM=y
+CONFIG_EXT4_FS=y
+CONFIG_EXTCON=y
+CONFIG_FAILOVER=y
+CONFIG_FANOTIFY=y
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-15"
+CONFIG_FAT_DEFAULT_UTF8=y
+CONFIG_FAT_FS=y
+CONFIG_FIXED_PHY=y
+CONFIG_FIX_EARLYCON_MEM=y
+CONFIG_FONT_8x16=y
+CONFIG_FONT_AUTOSELECT=y
+CONFIG_FONT_SUPPORT=y
+CONFIG_FPU=y
+CONFIG_FS_IOMAP=y
+CONFIG_FS_MBCACHE=y
+CONFIG_FWNODE_MDIO=y
+CONFIG_FW_LOADER_PAGED_BUF=y
+CONFIG_FW_LOADER_SYSFS=y
+CONFIG_GCC11_NO_ARRAY_BOUNDS=y
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_GENERIC_ARCH_TOPOLOGY=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
+CONFIG_GENERIC_CSUM=y
+CONFIG_GENERIC_EARLY_IOREMAP=y
+CONFIG_GENERIC_GETTIMEOFDAY=y
+CONFIG_GENERIC_IDLE_POLL_SETUP=y
+CONFIG_GENERIC_IOREMAP=y
+CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
+CONFIG_GENERIC_IRQ_MIGRATION=y
+CONFIG_GENERIC_IRQ_MULTI_HANDLER=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
+CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y
+CONFIG_GENERIC_MSI_IRQ=y
+CONFIG_GENERIC_MSI_IRQ_DOMAIN=y
+CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_PHY=y
+CONFIG_GENERIC_PHY_MIPI_DPHY=y
+CONFIG_GENERIC_PINCONF=y
+CONFIG_GENERIC_PINCTRL_GROUPS=y
+CONFIG_GENERIC_PINMUX_FUNCTIONS=y
+CONFIG_GENERIC_SCHED_CLOCK=y
+CONFIG_GENERIC_SMP_IDLE_THREAD=y
+CONFIG_GENERIC_STRNCPY_FROM_USER=y
+CONFIG_GENERIC_STRNLEN_USER=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GLOB=y
+CONFIG_GPIOLIB_FASTPATH_LIMIT=128
+CONFIG_GPIOLIB_IRQCHIP=y
+CONFIG_GPIO_CDEV=y
+CONFIG_GPIO_TPS65086=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_HAS_DMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT_MAP=y
+CONFIG_HOTPLUG_CPU=y
+CONFIG_HUGETLBFS=y
+CONFIG_HUGETLB_PAGE=y
+CONFIG_HVC_DRIVER=y
+CONFIG_HVC_RISCV_SBI=y
+CONFIG_HWMON=y
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_JH7110=y
+CONFIG_HW_RANDOM_STARFIVE_VIC=y
+CONFIG_I2C=y
+CONFIG_I2C_ALGOBIT=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_DESIGNWARE_CORE=y
+CONFIG_I2C_DESIGNWARE_PLATFORM=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_IPMS_CAN is not set
+CONFIG_IRQCHIP=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_DOMAIN_HIERARCHY=y
+CONFIG_IRQ_FORCED_THREADING=y
+CONFIG_IRQ_STACKS=y
+CONFIG_IRQ_WORK=y
+CONFIG_JBD2=y
+CONFIG_JH71XX_PMU=y
+CONFIG_JUMP_LABEL=y
+CONFIG_LIBFDT=y
+CONFIG_LOCKUP_DETECTOR=y
+CONFIG_LOCK_DEBUGGING_SUPPORT=y
+CONFIG_LOCK_SPIN_ON_OWNER=y
+CONFIG_LSM=""
+CONFIG_MARVELL_PHY=y
+CONFIG_MDIO_BUS=y
+CONFIG_MDIO_DEVICE=y
+CONFIG_MDIO_DEVRES=y
+CONFIG_MEMFD_CREATE=y
+CONFIG_MEMORY_ISOLATION=y
+CONFIG_MEMTEST=y
+CONFIG_MFD_AXP20X=y
+CONFIG_MFD_AXP20X_I2C=y
+CONFIG_MFD_CORE=y
+CONFIG_MFD_SYSCON=y
+CONFIG_MFD_TPS65086=y
+CONFIG_MICREL_PHY=y
+CONFIG_MICROCHIP_PHY=y
+CONFIG_MIGRATION=y
+CONFIG_MMC=y
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_DEBUG=y
+CONFIG_MMC_DW=y
+# CONFIG_MMC_DW_BLUEFIELD is not set
+# CONFIG_MMC_DW_EXYNOS is not set
+# CONFIG_MMC_DW_HI3798CV200 is not set
+# CONFIG_MMC_DW_K3 is not set
+# CONFIG_MMC_DW_PCI is not set
+CONFIG_MMC_DW_PLTFM=y
+CONFIG_MMC_DW_STARFIVE=y
+CONFIG_MMIOWB=y
+CONFIG_MODULES_TREE_LOOKUP=y
+CONFIG_MODULES_USE_ELF_RELA=y
+CONFIG_MODULE_SECTIONS=y
+CONFIG_MOTORCOMM_PHY=y
+CONFIG_MPILIB=y
+CONFIG_MTD_SPI_NOR=y
+CONFIG_MUTEX_SPIN_ON_OWNER=y
+CONFIG_NAMESPACES=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_NET_FAILOVER=y
+CONFIG_NET_FLOW_LIMIT=y
+CONFIG_NET_NS=y
+CONFIG_NET_SELFTESTS=y
+CONFIG_NLS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_DEFAULT="iso8859-15"
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_15=y
+CONFIG_NO_HZ_COMMON=y
+CONFIG_NO_HZ_IDLE=y
+CONFIG_NONPORTABLE=y
+CONFIG_NR_CPUS=8
+CONFIG_NVMEM=y
+CONFIG_NVMEM_SYSFS=y
+CONFIG_NVME_CORE=y
+CONFIG_NVME_HWMON=y
+# CONFIG_NVME_MULTIPATH is not set
+CONFIG_OF=y
+CONFIG_OF_ADDRESS=y
+# CONFIG_OF_CONFIGFS is not set
+CONFIG_OF_DMA_DEFAULT_COHERENT=y
+CONFIG_OF_DYNAMIC=y
+CONFIG_OF_EARLY_FLATTREE=y
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_GPIO=y
+CONFIG_OF_IRQ=y
+CONFIG_OF_KOBJ=y
+CONFIG_OF_MDIO=y
+CONFIG_OF_OVERLAY=y
+CONFIG_OF_RESOLVE=y
+CONFIG_OID_REGISTRY=y
+CONFIG_OVERLAY_FS_INDEX=y
+CONFIG_OVERLAY_FS_METACOPY=y
+CONFIG_OVERLAY_FS_REDIRECT_DIR=y
+CONFIG_PADATA=y
+CONFIG_PAGE_EXTENSION=y
+CONFIG_PAGE_OFFSET=0xff60000000000000
+CONFIG_PAGE_POOL=y
+CONFIG_PAGE_REPORTING=y
+CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
+CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
+CONFIG_PCI=y
+CONFIG_PCIE_CADENCE=y
+CONFIG_PCIE_CADENCE_HOST=y
+CONFIG_PCIE_CADENCE_PLAT=y
+CONFIG_PCIE_CADENCE_PLAT_HOST=y
+# CONFIG_PCIE_FU740 is not set
+CONFIG_PCIE_STARFIVE_HOST=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_DOMAINS_GENERIC=y
+CONFIG_PCI_MSI=y
+CONFIG_PCI_MSI_IRQ_DOMAIN=y
+CONFIG_PCS_XPCS=y
+CONFIG_PERF_EVENTS=y
+CONFIG_PGTABLE_LEVELS=5
+CONFIG_PHYLIB=y
+CONFIG_PHYLINK=y
+CONFIG_PHYS_ADDR_T_64BIT=y
+# CONFIG_PHYS_RAM_BASE_FIXED is not set
+CONFIG_PHY_STARFIVE_DPHY_RX=y
+CONFIG_PHY_STARFIVE_JH7110_DPHY_RX=y
+CONFIG_PHY_STARFIVE_JH7110_PCIE=y
+CONFIG_PHY_STARFIVE_JH7110_USB=y
+CONFIG_PINCTRL=y
+CONFIG_PINCTRL_STARFIVE_JH7100=y
+CONFIG_PINCTRL_STARFIVE_JH7110=y
+CONFIG_PINCTRL_STARFIVE_JH7110_AON=y
+CONFIG_PINCTRL_STARFIVE_JH7110_SYS=y
+CONFIG_PM=y
+CONFIG_PM_ADVANCED_DEBUG=y
+CONFIG_PM_CLK=y
+CONFIG_PM_DEBUG=y
+CONFIG_PM_DEVFREQ=y
+# CONFIG_PM_DEVFREQ_EVENT is not set
+CONFIG_PM_GENERIC_DOMAINS=y
+CONFIG_PM_GENERIC_DOMAINS_OF=y
+CONFIG_PM_OPP=y
+CONFIG_PORTABLE=y
+CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_GPIO_RESTART=y
+CONFIG_POWER_RESET_SYSCON=y
+CONFIG_POWER_RESET_SYSCON_POWEROFF=y
+# CONFIG_POWER_RESET_TPS65086 is not set
+CONFIG_PPS=y
+CONFIG_PREEMPT_COUNT=y
+CONFIG_PREEMPT_NONE_BUILD=y
+CONFIG_PRINTK_TIME=y
+CONFIG_PROC_CHILDREN=y
+CONFIG_PROC_KCORE=y
+CONFIG_PTDUMP_CORE=y
+CONFIG_PTP_1588_CLOCK=y
+CONFIG_PTP_1588_CLOCK_OPTIONAL=y
+CONFIG_PWM=y
+CONFIG_PWM_OCORES=y
+# CONFIG_PWM_SIFIVE is not set
+CONFIG_PWM_SIFIVE_PTC=y
+CONFIG_PWM_STARFIVE_PTC=y
+CONFIG_PWM_SYSFS=y
+CONFIG_QUEUED_RWLOCKS=y
+CONFIG_RANDSTRUCT_NONE=y
+CONFIG_RATIONAL=y
+CONFIG_RCU_EQS_DEBUG=y
+CONFIG_RD_GZIP=y
+CONFIG_REALTEK_PHY=y
+CONFIG_REGMAP=y
+CONFIG_REGMAP_I2C=y
+CONFIG_REGMAP_IRQ=y
+CONFIG_REGMAP_MMIO=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_AXP20X=y
+CONFIG_REGULATOR_STARFIVE_JH7110=y
+CONFIG_REGULATOR_TPS65086=y
+# CONFIG_RESET_ATTACK_MITIGATION is not set
+CONFIG_RESET_CONTROLLER=y
+CONFIG_RESET_SIMPLE=y
+CONFIG_RESET_STARFIVE_JH7100=y
+CONFIG_RESET_STARFIVE_JH7100_AUDIO=y
+CONFIG_RESET_STARFIVE_JH7110=y
+CONFIG_RESET_STARFIVE_JH71X0=y
+CONFIG_RFS_ACCEL=y
+CONFIG_RISCV=y
+CONFIG_RISCV_ALTERNATIVE=y
+CONFIG_RISCV_BOOT_SPINWAIT=y
+CONFIG_RISCV_DMA_NONCOHERENT=y
+CONFIG_RISCV_INTC=y
+CONFIG_RISCV_ISA_C=y
+CONFIG_RISCV_ISA_FALLBACK=y
+CONFIG_RISCV_ISA_SVNAPOT=y
+# CONFIG_RISCV_ISA_SVPBMT is not set
+CONFIG_RISCV_ISA_V=y
+CONFIG_RISCV_ISA_V_DEFAULT_ENABLE=y
+CONFIG_RISCV_ISA_ZBB=y
+# CONFIG_RISCV_ISA_ZICBOM is not set
+CONFIG_RISCV_ISA_ZICBOZ=y
+CONFIG_RISCV_PMU=y
+CONFIG_RISCV_PMU_LEGACY=y
+CONFIG_RISCV_PMU_SBI=y
+CONFIG_RISCV_SBI=y
+CONFIG_RISCV_SBI_CPUIDLE=y
+CONFIG_RISCV_SBI_V01=y
+CONFIG_RISCV_TIMER=y
+CONFIG_RPMSG=y
+CONFIG_RPMSG_CHAR=y
+# CONFIG_RPMSG_CTRL is not set
+CONFIG_RPMSG_NS=y
+# CONFIG_RPMSG_TTY is not set
+CONFIG_RPMSG_VIRTIO=y
+CONFIG_RPS=y
+CONFIG_RTC_CLASS=y
+# CONFIG_RTC_DRV_EFI is not set
+CONFIG_RTC_DRV_GOLDFISH=y
+CONFIG_RTC_DRV_HYM8563=y
+CONFIG_RTC_DRV_STARFIVE=y
+CONFIG_RTC_I2C_AND_SPI=y
+CONFIG_RWSEM_SPIN_ON_OWNER=y
+CONFIG_SCSI=y
+CONFIG_SCSI_COMMON=y
+CONFIG_SCSI_VIRTIO=y
+CONFIG_SENSORS_SFCTEMP=y
+# CONFIG_SERIAL_8250_16550A_VARIANTS is not set
+CONFIG_SERIAL_8250_DW=y
+CONFIG_SERIAL_8250_DWLIB=y
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_NR_UARTS=6
+CONFIG_SERIAL_8250_RUNTIME_UARTS=6
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+CONFIG_SERIAL_EARLYCON_RISCV_SBI=y
+CONFIG_SERIAL_MCTRL_GPIO=y
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_SERIAL_SIFIVE=y
+CONFIG_SERIAL_SIFIVE_CONSOLE=y
+CONFIG_SGL_ALLOC=y
+CONFIG_SG_POOL=y
+CONFIG_SIFIVE_CCACHE=y
+CONFIG_SIFIVE_PLIC=y
+CONFIG_SMP=y
+# CONFIG_SND_SOC_AC108 is not set
+# CONFIG_SND_SOC_STARFIVE is not set
+CONFIG_SOCK_DIAG=y
+CONFIG_SOCK_RX_QUEUE_MAPPING=y
+# CONFIG_SOC_MICROCHIP_POLARFIRE is not set
+CONFIG_SOC_SIFIVE=y
+CONFIG_SOC_STARFIVE=y
+# CONFIG_SOC_VIRT is not set
+CONFIG_SOFTLOCKUP_DETECTOR=y
+CONFIG_SOUND=y
+CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_SPI=y
+CONFIG_SPI_CADENCE_QUADSPI=y
+CONFIG_SPI_DYNAMIC=y
+CONFIG_SPI_MASTER=y
+CONFIG_SPI_MEM=y
+CONFIG_SPI_SPIDEV=y
+CONFIG_SRCU=y
+CONFIG_STARFIVE_TIMER=y
+CONFIG_STARFIVE_JH7110_TIMER=y
+CONFIG_STARFIVE_WATCHDOG=y
+CONFIG_STMMAC_ETH=y
+CONFIG_STMMAC_PLATFORM=y
+CONFIG_STMMAC_SELFTESTS=y
+CONFIG_SWIOTLB=y
+CONFIG_SWPHY=y
+CONFIG_SYNC_FILE=y
+CONFIG_SYSCTL_EXCEPTION_TRACE=y
+# CONFIG_SYSFB_SIMPLEFB is not set
+CONFIG_THERMAL=y
+CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
+CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
+CONFIG_THERMAL_GOV_STEP_WISE=y
+CONFIG_THERMAL_OF=y
+CONFIG_THREAD_INFO_IN_TASK=y
+CONFIG_THREAD_SIZE_ORDER=2
+CONFIG_TICK_CPU_ACCOUNTING=y
+CONFIG_TIMER_OF=y
+CONFIG_TIMER_PROBE=y
+CONFIG_TOOLCHAIN_HAS_ZICBOM=y
+CONFIG_TOOLCHAIN_HAS_ZIHINTPAUSE=y
+CONFIG_TOOLCHAIN_NEEDS_EXPLICIT_ZICSR_ZIFENCEI=y
+# CONFIG_TOUCHSCREEN_TINKER_FT5406 is not set
+CONFIG_TREE_RCU=y
+CONFIG_TREE_SRCU=y
+CONFIG_TTY_PRINTK=y
+CONFIG_TTY_PRINTK_LEVEL=6
+CONFIG_TUNE_GENERIC=y
+CONFIG_UCS2_STRING=y
+CONFIG_UNINLINE_SPIN_UNLOCK=y
+CONFIG_USB=y
+CONFIG_USB_COMMON=y
+CONFIG_USB_CONFIGFS=y
+# CONFIG_USB_CONFIGFS_ACM is not set
+# CONFIG_USB_CONFIGFS_ECM is not set
+# CONFIG_USB_CONFIGFS_ECM_SUBSET is not set
+# CONFIG_USB_CONFIGFS_EEM is not set
+CONFIG_USB_CONFIGFS_F_FS=y
+# CONFIG_USB_CONFIGFS_F_HID is not set
+# CONFIG_USB_CONFIGFS_F_LB_SS is not set
+# CONFIG_USB_CONFIGFS_F_MIDI is not set
+# CONFIG_USB_CONFIGFS_F_MIDI2 is not set
+# CONFIG_USB_CONFIGFS_F_PRINTER is not set
+# CONFIG_USB_CONFIGFS_F_UAC1 is not set
+# CONFIG_USB_CONFIGFS_F_UAC1_LEGACY is not set
+# CONFIG_USB_CONFIGFS_F_UAC2 is not set
+# CONFIG_USB_CONFIGFS_F_UVC is not set
+CONFIG_USB_CONFIGFS_MASS_STORAGE=y
+# CONFIG_USB_CONFIGFS_NCM is not set
+# CONFIG_USB_CONFIGFS_OBEX is not set
+# CONFIG_USB_CONFIGFS_RNDIS is not set
+# CONFIG_USB_CONFIGFS_SERIAL is not set
+CONFIG_USB_F_FS=y
+CONFIG_USB_F_MASS_STORAGE=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_LIBCOMPOSITE=y
+CONFIG_USB_PCI=y
+CONFIG_USB_PHY=y
+CONFIG_USB_ROLE_SWITCH=y
+CONFIG_USB_SUPPORT=y
+# CONFIG_USB_UHCI_HCD is not set
+CONFIG_USELIB=y
+CONFIG_USER_NS=y
+CONFIG_VFAT_FS=y
+# CONFIG_VIDEO_STF_VIN is not set
+# CONFIG_VIRTIO_BLK is not set
+# CONFIG_VIRTIO_NET is not set
+CONFIG_VMAP_STACK=y
+CONFIG_WATCHDOG_CORE=y
+CONFIG_WATCHDOG_SYSFS=y
+CONFIG_WERROR=y
+CONFIG_WQ_WATCHDOG=y
+CONFIG_XPS=y
+CONFIG_XXHASH=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZONE_DMA32=y
diff --git a/target/linux/starfive/patches-6.1/0001-dt-bindings-clock-Add-StarFive-JH7110-system-clock-a.patch b/target/linux/starfive/patches-6.1/0001-dt-bindings-clock-Add-StarFive-JH7110-system-clock-a.patch
deleted file mode 100644
index 3e06d5a681..0000000000
--- a/target/linux/starfive/patches-6.1/0001-dt-bindings-clock-Add-StarFive-JH7110-system-clock-a.patch
+++ /dev/null
@@ -1,482 +0,0 @@
-From c960c73ee9fdaae51fcd8a14d44d576b1cf522b7 Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Sat, 1 Apr 2023 19:19:13 +0800
-Subject: [PATCH 001/122] dt-bindings: clock: Add StarFive JH7110 system clock
- and reset generator
-
-Add bindings for the system clock and reset generator (SYSCRG) on the
-JH7110 RISC-V SoC by StarFive Ltd.
-
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
-Reviewed-by: Rob Herring <robh@kernel.org>
-Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
-Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
-Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
----
- .../clock/starfive,jh7110-syscrg.yaml | 104 +++++++++
- .../dt-bindings/clock/starfive,jh7110-crg.h | 203 ++++++++++++++++++
- .../dt-bindings/reset/starfive,jh7110-crg.h | 142 ++++++++++++
- 3 files changed, 449 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/clock/starfive,jh7110-syscrg.yaml
- create mode 100644 include/dt-bindings/clock/starfive,jh7110-crg.h
- create mode 100644 include/dt-bindings/reset/starfive,jh7110-crg.h
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/clock/starfive,jh7110-syscrg.yaml
-@@ -0,0 +1,104 @@
-+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/clock/starfive,jh7110-syscrg.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: StarFive JH7110 System Clock and Reset Generator
-+
-+maintainers:
-+ - Emil Renner Berthing <kernel@esmil.dk>
-+
-+properties:
-+ compatible:
-+ const: starfive,jh7110-syscrg
-+
-+ reg:
-+ maxItems: 1
-+
-+ clocks:
-+ oneOf:
-+ - items:
-+ - description: Main Oscillator (24 MHz)
-+ - description: GMAC1 RMII reference or GMAC1 RGMII RX
-+ - description: External I2S TX bit clock
-+ - description: External I2S TX left/right channel clock
-+ - description: External I2S RX bit clock
-+ - description: External I2S RX left/right channel clock
-+ - description: External TDM clock
-+ - description: External audio master clock
-+
-+ - items:
-+ - description: Main Oscillator (24 MHz)
-+ - description: GMAC1 RMII reference
-+ - description: GMAC1 RGMII RX
-+ - description: External I2S TX bit clock
-+ - description: External I2S TX left/right channel clock
-+ - description: External I2S RX bit clock
-+ - description: External I2S RX left/right channel clock
-+ - description: External TDM clock
-+ - description: External audio master clock
-+
-+ clock-names:
-+ oneOf:
-+ - items:
-+ - const: osc
-+ - enum:
-+ - gmac1_rmii_refin
-+ - gmac1_rgmii_rxin
-+ - const: i2stx_bclk_ext
-+ - const: i2stx_lrck_ext
-+ - const: i2srx_bclk_ext
-+ - const: i2srx_lrck_ext
-+ - const: tdm_ext
-+ - const: mclk_ext
-+
-+ - items:
-+ - const: osc
-+ - const: gmac1_rmii_refin
-+ - const: gmac1_rgmii_rxin
-+ - const: i2stx_bclk_ext
-+ - const: i2stx_lrck_ext
-+ - const: i2srx_bclk_ext
-+ - const: i2srx_lrck_ext
-+ - const: tdm_ext
-+ - const: mclk_ext
-+
-+ '#clock-cells':
-+ const: 1
-+ description:
-+ See <dt-bindings/clock/starfive,jh7110-crg.h> for valid indices.
-+
-+ '#reset-cells':
-+ const: 1
-+ description:
-+ See <dt-bindings/reset/starfive,jh7110-crg.h> for valid indices.
-+
-+required:
-+ - compatible
-+ - reg
-+ - clocks
-+ - clock-names
-+ - '#clock-cells'
-+ - '#reset-cells'
-+
-+additionalProperties: false
-+
-+examples:
-+ - |
-+ clock-controller@13020000 {
-+ compatible = "starfive,jh7110-syscrg";
-+ reg = <0x13020000 0x10000>;
-+ clocks = <&osc>, <&gmac1_rmii_refin>,
-+ <&gmac1_rgmii_rxin>,
-+ <&i2stx_bclk_ext>, <&i2stx_lrck_ext>,
-+ <&i2srx_bclk_ext>, <&i2srx_lrck_ext>,
-+ <&tdm_ext>, <&mclk_ext>;
-+ clock-names = "osc", "gmac1_rmii_refin",
-+ "gmac1_rgmii_rxin",
-+ "i2stx_bclk_ext", "i2stx_lrck_ext",
-+ "i2srx_bclk_ext", "i2srx_lrck_ext",
-+ "tdm_ext", "mclk_ext";
-+ #clock-cells = <1>;
-+ #reset-cells = <1>;
-+ };
---- /dev/null
-+++ b/include/dt-bindings/clock/starfive,jh7110-crg.h
-@@ -0,0 +1,203 @@
-+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
-+/*
-+ * Copyright 2022 Emil Renner Berthing <kernel@esmil.dk>
-+ */
-+
-+#ifndef __DT_BINDINGS_CLOCK_STARFIVE_JH7110_CRG_H__
-+#define __DT_BINDINGS_CLOCK_STARFIVE_JH7110_CRG_H__
-+
-+/* SYSCRG clocks */
-+#define JH7110_SYSCLK_CPU_ROOT 0
-+#define JH7110_SYSCLK_CPU_CORE 1
-+#define JH7110_SYSCLK_CPU_BUS 2
-+#define JH7110_SYSCLK_GPU_ROOT 3
-+#define JH7110_SYSCLK_PERH_ROOT 4
-+#define JH7110_SYSCLK_BUS_ROOT 5
-+#define JH7110_SYSCLK_NOCSTG_BUS 6
-+#define JH7110_SYSCLK_AXI_CFG0 7
-+#define JH7110_SYSCLK_STG_AXIAHB 8
-+#define JH7110_SYSCLK_AHB0 9
-+#define JH7110_SYSCLK_AHB1 10
-+#define JH7110_SYSCLK_APB_BUS 11
-+#define JH7110_SYSCLK_APB0 12
-+#define JH7110_SYSCLK_PLL0_DIV2 13
-+#define JH7110_SYSCLK_PLL1_DIV2 14
-+#define JH7110_SYSCLK_PLL2_DIV2 15
-+#define JH7110_SYSCLK_AUDIO_ROOT 16
-+#define JH7110_SYSCLK_MCLK_INNER 17
-+#define JH7110_SYSCLK_MCLK 18
-+#define JH7110_SYSCLK_MCLK_OUT 19
-+#define JH7110_SYSCLK_ISP_2X 20
-+#define JH7110_SYSCLK_ISP_AXI 21
-+#define JH7110_SYSCLK_GCLK0 22
-+#define JH7110_SYSCLK_GCLK1 23
-+#define JH7110_SYSCLK_GCLK2 24
-+#define JH7110_SYSCLK_CORE 25
-+#define JH7110_SYSCLK_CORE1 26
-+#define JH7110_SYSCLK_CORE2 27
-+#define JH7110_SYSCLK_CORE3 28
-+#define JH7110_SYSCLK_CORE4 29
-+#define JH7110_SYSCLK_DEBUG 30
-+#define JH7110_SYSCLK_RTC_TOGGLE 31
-+#define JH7110_SYSCLK_TRACE0 32
-+#define JH7110_SYSCLK_TRACE1 33
-+#define JH7110_SYSCLK_TRACE2 34
-+#define JH7110_SYSCLK_TRACE3 35
-+#define JH7110_SYSCLK_TRACE4 36
-+#define JH7110_SYSCLK_TRACE_COM 37
-+#define JH7110_SYSCLK_NOC_BUS_CPU_AXI 38
-+#define JH7110_SYSCLK_NOC_BUS_AXICFG0_AXI 39
-+#define JH7110_SYSCLK_OSC_DIV2 40
-+#define JH7110_SYSCLK_PLL1_DIV4 41
-+#define JH7110_SYSCLK_PLL1_DIV8 42
-+#define JH7110_SYSCLK_DDR_BUS 43
-+#define JH7110_SYSCLK_DDR_AXI 44
-+#define JH7110_SYSCLK_GPU_CORE 45
-+#define JH7110_SYSCLK_GPU_CORE_CLK 46
-+#define JH7110_SYSCLK_GPU_SYS_CLK 47
-+#define JH7110_SYSCLK_GPU_APB 48
-+#define JH7110_SYSCLK_GPU_RTC_TOGGLE 49
-+#define JH7110_SYSCLK_NOC_BUS_GPU_AXI 50
-+#define JH7110_SYSCLK_ISP_TOP_CORE 51
-+#define JH7110_SYSCLK_ISP_TOP_AXI 52
-+#define JH7110_SYSCLK_NOC_BUS_ISP_AXI 53
-+#define JH7110_SYSCLK_HIFI4_CORE 54
-+#define JH7110_SYSCLK_HIFI4_AXI 55
-+#define JH7110_SYSCLK_AXI_CFG1_MAIN 56
-+#define JH7110_SYSCLK_AXI_CFG1_AHB 57
-+#define JH7110_SYSCLK_VOUT_SRC 58
-+#define JH7110_SYSCLK_VOUT_AXI 59
-+#define JH7110_SYSCLK_NOC_BUS_DISP_AXI 60
-+#define JH7110_SYSCLK_VOUT_TOP_AHB 61
-+#define JH7110_SYSCLK_VOUT_TOP_AXI 62
-+#define JH7110_SYSCLK_VOUT_TOP_HDMITX0_MCLK 63
-+#define JH7110_SYSCLK_VOUT_TOP_MIPIPHY_REF 64
-+#define JH7110_SYSCLK_JPEGC_AXI 65
-+#define JH7110_SYSCLK_CODAJ12_AXI 66
-+#define JH7110_SYSCLK_CODAJ12_CORE 67
-+#define JH7110_SYSCLK_CODAJ12_APB 68
-+#define JH7110_SYSCLK_VDEC_AXI 69
-+#define JH7110_SYSCLK_WAVE511_AXI 70
-+#define JH7110_SYSCLK_WAVE511_BPU 71
-+#define JH7110_SYSCLK_WAVE511_VCE 72
-+#define JH7110_SYSCLK_WAVE511_APB 73
-+#define JH7110_SYSCLK_VDEC_JPG 74
-+#define JH7110_SYSCLK_VDEC_MAIN 75
-+#define JH7110_SYSCLK_NOC_BUS_VDEC_AXI 76
-+#define JH7110_SYSCLK_VENC_AXI 77
-+#define JH7110_SYSCLK_WAVE420L_AXI 78
-+#define JH7110_SYSCLK_WAVE420L_BPU 79
-+#define JH7110_SYSCLK_WAVE420L_VCE 80
-+#define JH7110_SYSCLK_WAVE420L_APB 81
-+#define JH7110_SYSCLK_NOC_BUS_VENC_AXI 82
-+#define JH7110_SYSCLK_AXI_CFG0_MAIN_DIV 83
-+#define JH7110_SYSCLK_AXI_CFG0_MAIN 84
-+#define JH7110_SYSCLK_AXI_CFG0_HIFI4 85
-+#define JH7110_SYSCLK_AXIMEM2_AXI 86
-+#define JH7110_SYSCLK_QSPI_AHB 87
-+#define JH7110_SYSCLK_QSPI_APB 88
-+#define JH7110_SYSCLK_QSPI_REF_SRC 89
-+#define JH7110_SYSCLK_QSPI_REF 90
-+#define JH7110_SYSCLK_SDIO0_AHB 91
-+#define JH7110_SYSCLK_SDIO1_AHB 92
-+#define JH7110_SYSCLK_SDIO0_SDCARD 93
-+#define JH7110_SYSCLK_SDIO1_SDCARD 94
-+#define JH7110_SYSCLK_USB_125M 95
-+#define JH7110_SYSCLK_NOC_BUS_STG_AXI 96
-+#define JH7110_SYSCLK_GMAC1_AHB 97
-+#define JH7110_SYSCLK_GMAC1_AXI 98
-+#define JH7110_SYSCLK_GMAC_SRC 99
-+#define JH7110_SYSCLK_GMAC1_GTXCLK 100
-+#define JH7110_SYSCLK_GMAC1_RMII_RTX 101
-+#define JH7110_SYSCLK_GMAC1_PTP 102
-+#define JH7110_SYSCLK_GMAC1_RX 103
-+#define JH7110_SYSCLK_GMAC1_RX_INV 104
-+#define JH7110_SYSCLK_GMAC1_TX 105
-+#define JH7110_SYSCLK_GMAC1_TX_INV 106
-+#define JH7110_SYSCLK_GMAC1_GTXC 107
-+#define JH7110_SYSCLK_GMAC0_GTXCLK 108
-+#define JH7110_SYSCLK_GMAC0_PTP 109
-+#define JH7110_SYSCLK_GMAC_PHY 110
-+#define JH7110_SYSCLK_GMAC0_GTXC 111
-+#define JH7110_SYSCLK_IOMUX_APB 112
-+#define JH7110_SYSCLK_MAILBOX_APB 113
-+#define JH7110_SYSCLK_INT_CTRL_APB 114
-+#define JH7110_SYSCLK_CAN0_APB 115
-+#define JH7110_SYSCLK_CAN0_TIMER 116
-+#define JH7110_SYSCLK_CAN0_CAN 117
-+#define JH7110_SYSCLK_CAN1_APB 118
-+#define JH7110_SYSCLK_CAN1_TIMER 119
-+#define JH7110_SYSCLK_CAN1_CAN 120
-+#define JH7110_SYSCLK_PWM_APB 121
-+#define JH7110_SYSCLK_WDT_APB 122
-+#define JH7110_SYSCLK_WDT_CORE 123
-+#define JH7110_SYSCLK_TIMER_APB 124
-+#define JH7110_SYSCLK_TIMER0 125
-+#define JH7110_SYSCLK_TIMER1 126
-+#define JH7110_SYSCLK_TIMER2 127
-+#define JH7110_SYSCLK_TIMER3 128
-+#define JH7110_SYSCLK_TEMP_APB 129
-+#define JH7110_SYSCLK_TEMP_CORE 130
-+#define JH7110_SYSCLK_SPI0_APB 131
-+#define JH7110_SYSCLK_SPI1_APB 132
-+#define JH7110_SYSCLK_SPI2_APB 133
-+#define JH7110_SYSCLK_SPI3_APB 134
-+#define JH7110_SYSCLK_SPI4_APB 135
-+#define JH7110_SYSCLK_SPI5_APB 136
-+#define JH7110_SYSCLK_SPI6_APB 137
-+#define JH7110_SYSCLK_I2C0_APB 138
-+#define JH7110_SYSCLK_I2C1_APB 139
-+#define JH7110_SYSCLK_I2C2_APB 140
-+#define JH7110_SYSCLK_I2C3_APB 141
-+#define JH7110_SYSCLK_I2C4_APB 142
-+#define JH7110_SYSCLK_I2C5_APB 143
-+#define JH7110_SYSCLK_I2C6_APB 144
-+#define JH7110_SYSCLK_UART0_APB 145
-+#define JH7110_SYSCLK_UART0_CORE 146
-+#define JH7110_SYSCLK_UART1_APB 147
-+#define JH7110_SYSCLK_UART1_CORE 148
-+#define JH7110_SYSCLK_UART2_APB 149
-+#define JH7110_SYSCLK_UART2_CORE 150
-+#define JH7110_SYSCLK_UART3_APB 151
-+#define JH7110_SYSCLK_UART3_CORE 152
-+#define JH7110_SYSCLK_UART4_APB 153
-+#define JH7110_SYSCLK_UART4_CORE 154
-+#define JH7110_SYSCLK_UART5_APB 155
-+#define JH7110_SYSCLK_UART5_CORE 156
-+#define JH7110_SYSCLK_PWMDAC_APB 157
-+#define JH7110_SYSCLK_PWMDAC_CORE 158
-+#define JH7110_SYSCLK_SPDIF_APB 159
-+#define JH7110_SYSCLK_SPDIF_CORE 160
-+#define JH7110_SYSCLK_I2STX0_APB 161
-+#define JH7110_SYSCLK_I2STX0_BCLK_MST 162
-+#define JH7110_SYSCLK_I2STX0_BCLK_MST_INV 163
-+#define JH7110_SYSCLK_I2STX0_LRCK_MST 164
-+#define JH7110_SYSCLK_I2STX0_BCLK 165
-+#define JH7110_SYSCLK_I2STX0_BCLK_INV 166
-+#define JH7110_SYSCLK_I2STX0_LRCK 167
-+#define JH7110_SYSCLK_I2STX1_APB 168
-+#define JH7110_SYSCLK_I2STX1_BCLK_MST 169
-+#define JH7110_SYSCLK_I2STX1_BCLK_MST_INV 170
-+#define JH7110_SYSCLK_I2STX1_LRCK_MST 171
-+#define JH7110_SYSCLK_I2STX1_BCLK 172
-+#define JH7110_SYSCLK_I2STX1_BCLK_INV 173
-+#define JH7110_SYSCLK_I2STX1_LRCK 174
-+#define JH7110_SYSCLK_I2SRX_APB 175
-+#define JH7110_SYSCLK_I2SRX_BCLK_MST 176
-+#define JH7110_SYSCLK_I2SRX_BCLK_MST_INV 177
-+#define JH7110_SYSCLK_I2SRX_LRCK_MST 178
-+#define JH7110_SYSCLK_I2SRX_BCLK 179
-+#define JH7110_SYSCLK_I2SRX_BCLK_INV 180
-+#define JH7110_SYSCLK_I2SRX_LRCK 181
-+#define JH7110_SYSCLK_PDM_DMIC 182
-+#define JH7110_SYSCLK_PDM_APB 183
-+#define JH7110_SYSCLK_TDM_AHB 184
-+#define JH7110_SYSCLK_TDM_APB 185
-+#define JH7110_SYSCLK_TDM_INTERNAL 186
-+#define JH7110_SYSCLK_TDM_TDM 187
-+#define JH7110_SYSCLK_TDM_TDM_INV 188
-+#define JH7110_SYSCLK_JTAG_CERTIFICATION_TRNG 189
-+
-+#define JH7110_SYSCLK_END 190
-+
-+#endif /* __DT_BINDINGS_CLOCK_STARFIVE_JH7110_CRG_H__ */
---- /dev/null
-+++ b/include/dt-bindings/reset/starfive,jh7110-crg.h
-@@ -0,0 +1,142 @@
-+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
-+/*
-+ * Copyright (C) 2022 Emil Renner Berthing <kernel@esmil.dk>
-+ */
-+
-+#ifndef __DT_BINDINGS_RESET_STARFIVE_JH7110_CRG_H__
-+#define __DT_BINDINGS_RESET_STARFIVE_JH7110_CRG_H__
-+
-+/* SYSCRG resets */
-+#define JH7110_SYSRST_JTAG_APB 0
-+#define JH7110_SYSRST_SYSCON_APB 1
-+#define JH7110_SYSRST_IOMUX_APB 2
-+#define JH7110_SYSRST_BUS 3
-+#define JH7110_SYSRST_DEBUG 4
-+#define JH7110_SYSRST_CORE0 5
-+#define JH7110_SYSRST_CORE1 6
-+#define JH7110_SYSRST_CORE2 7
-+#define JH7110_SYSRST_CORE3 8
-+#define JH7110_SYSRST_CORE4 9
-+#define JH7110_SYSRST_CORE0_ST 10
-+#define JH7110_SYSRST_CORE1_ST 11
-+#define JH7110_SYSRST_CORE2_ST 12
-+#define JH7110_SYSRST_CORE3_ST 13
-+#define JH7110_SYSRST_CORE4_ST 14
-+#define JH7110_SYSRST_TRACE0 15
-+#define JH7110_SYSRST_TRACE1 16
-+#define JH7110_SYSRST_TRACE2 17
-+#define JH7110_SYSRST_TRACE3 18
-+#define JH7110_SYSRST_TRACE4 19
-+#define JH7110_SYSRST_TRACE_COM 20
-+#define JH7110_SYSRST_GPU_APB 21
-+#define JH7110_SYSRST_GPU_DOMA 22
-+#define JH7110_SYSRST_NOC_BUS_APB 23
-+#define JH7110_SYSRST_NOC_BUS_AXICFG0_AXI 24
-+#define JH7110_SYSRST_NOC_BUS_CPU_AXI 25
-+#define JH7110_SYSRST_NOC_BUS_DISP_AXI 26
-+#define JH7110_SYSRST_NOC_BUS_GPU_AXI 27
-+#define JH7110_SYSRST_NOC_BUS_ISP_AXI 28
-+#define JH7110_SYSRST_NOC_BUS_DDRC 29
-+#define JH7110_SYSRST_NOC_BUS_STG_AXI 30
-+#define JH7110_SYSRST_NOC_BUS_VDEC_AXI 31
-+
-+#define JH7110_SYSRST_NOC_BUS_VENC_AXI 32
-+#define JH7110_SYSRST_AXI_CFG1_AHB 33
-+#define JH7110_SYSRST_AXI_CFG1_MAIN 34
-+#define JH7110_SYSRST_AXI_CFG0_MAIN 35
-+#define JH7110_SYSRST_AXI_CFG0_MAIN_DIV 36
-+#define JH7110_SYSRST_AXI_CFG0_HIFI4 37
-+#define JH7110_SYSRST_DDR_AXI 38
-+#define JH7110_SYSRST_DDR_OSC 39
-+#define JH7110_SYSRST_DDR_APB 40
-+#define JH7110_SYSRST_ISP_TOP 41
-+#define JH7110_SYSRST_ISP_TOP_AXI 42
-+#define JH7110_SYSRST_VOUT_TOP_SRC 43
-+#define JH7110_SYSRST_CODAJ12_AXI 44
-+#define JH7110_SYSRST_CODAJ12_CORE 45
-+#define JH7110_SYSRST_CODAJ12_APB 46
-+#define JH7110_SYSRST_WAVE511_AXI 47
-+#define JH7110_SYSRST_WAVE511_BPU 48
-+#define JH7110_SYSRST_WAVE511_VCE 49
-+#define JH7110_SYSRST_WAVE511_APB 50
-+#define JH7110_SYSRST_VDEC_JPG 51
-+#define JH7110_SYSRST_VDEC_MAIN 52
-+#define JH7110_SYSRST_AXIMEM0_AXI 53
-+#define JH7110_SYSRST_WAVE420L_AXI 54
-+#define JH7110_SYSRST_WAVE420L_BPU 55
-+#define JH7110_SYSRST_WAVE420L_VCE 56
-+#define JH7110_SYSRST_WAVE420L_APB 57
-+#define JH7110_SYSRST_AXIMEM1_AXI 58
-+#define JH7110_SYSRST_AXIMEM2_AXI 59
-+#define JH7110_SYSRST_INTMEM 60
-+#define JH7110_SYSRST_QSPI_AHB 61
-+#define JH7110_SYSRST_QSPI_APB 62
-+#define JH7110_SYSRST_QSPI_REF 63
-+
-+#define JH7110_SYSRST_SDIO0_AHB 64
-+#define JH7110_SYSRST_SDIO1_AHB 65
-+#define JH7110_SYSRST_GMAC1_AXI 66
-+#define JH7110_SYSRST_GMAC1_AHB 67
-+#define JH7110_SYSRST_MAILBOX_APB 68
-+#define JH7110_SYSRST_SPI0_APB 69
-+#define JH7110_SYSRST_SPI1_APB 70
-+#define JH7110_SYSRST_SPI2_APB 71
-+#define JH7110_SYSRST_SPI3_APB 72
-+#define JH7110_SYSRST_SPI4_APB 73
-+#define JH7110_SYSRST_SPI5_APB 74
-+#define JH7110_SYSRST_SPI6_APB 75
-+#define JH7110_SYSRST_I2C0_APB 76
-+#define JH7110_SYSRST_I2C1_APB 77
-+#define JH7110_SYSRST_I2C2_APB 78
-+#define JH7110_SYSRST_I2C3_APB 79
-+#define JH7110_SYSRST_I2C4_APB 80
-+#define JH7110_SYSRST_I2C5_APB 81
-+#define JH7110_SYSRST_I2C6_APB 82
-+#define JH7110_SYSRST_UART0_APB 83
-+#define JH7110_SYSRST_UART0_CORE 84
-+#define JH7110_SYSRST_UART1_APB 85
-+#define JH7110_SYSRST_UART1_CORE 86
-+#define JH7110_SYSRST_UART2_APB 87
-+#define JH7110_SYSRST_UART2_CORE 88
-+#define JH7110_SYSRST_UART3_APB 89
-+#define JH7110_SYSRST_UART3_CORE 90
-+#define JH7110_SYSRST_UART4_APB 91
-+#define JH7110_SYSRST_UART4_CORE 92
-+#define JH7110_SYSRST_UART5_APB 93
-+#define JH7110_SYSRST_UART5_CORE 94
-+#define JH7110_SYSRST_SPDIF_APB 95
-+
-+#define JH7110_SYSRST_PWMDAC_APB 96
-+#define JH7110_SYSRST_PDM_DMIC 97
-+#define JH7110_SYSRST_PDM_APB 98
-+#define JH7110_SYSRST_I2SRX_APB 99
-+#define JH7110_SYSRST_I2SRX_BCLK 100
-+#define JH7110_SYSRST_I2STX0_APB 101
-+#define JH7110_SYSRST_I2STX0_BCLK 102
-+#define JH7110_SYSRST_I2STX1_APB 103
-+#define JH7110_SYSRST_I2STX1_BCLK 104
-+#define JH7110_SYSRST_TDM_AHB 105
-+#define JH7110_SYSRST_TDM_CORE 106
-+#define JH7110_SYSRST_TDM_APB 107
-+#define JH7110_SYSRST_PWM_APB 108
-+#define JH7110_SYSRST_WDT_APB 109
-+#define JH7110_SYSRST_WDT_CORE 110
-+#define JH7110_SYSRST_CAN0_APB 111
-+#define JH7110_SYSRST_CAN0_CORE 112
-+#define JH7110_SYSRST_CAN0_TIMER 113
-+#define JH7110_SYSRST_CAN1_APB 114
-+#define JH7110_SYSRST_CAN1_CORE 115
-+#define JH7110_SYSRST_CAN1_TIMER 116
-+#define JH7110_SYSRST_TIMER_APB 117
-+#define JH7110_SYSRST_TIMER0 118
-+#define JH7110_SYSRST_TIMER1 119
-+#define JH7110_SYSRST_TIMER2 120
-+#define JH7110_SYSRST_TIMER3 121
-+#define JH7110_SYSRST_INT_CTRL_APB 122
-+#define JH7110_SYSRST_TEMP_APB 123
-+#define JH7110_SYSRST_TEMP_CORE 124
-+#define JH7110_SYSRST_JTAG_CERTIFICATION 125
-+
-+#define JH7110_SYSRST_END 126
-+
-+#endif /* __DT_BINDINGS_RESET_STARFIVE_JH7110_CRG_H__ */
diff --git a/target/linux/starfive/patches-6.1/0002-dt-bindings-clock-Add-StarFive-JH7110-always-on-cloc.patch b/target/linux/starfive/patches-6.1/0002-dt-bindings-clock-Add-StarFive-JH7110-always-on-cloc.patch
deleted file mode 100644
index 94cb575a71..0000000000
--- a/target/linux/starfive/patches-6.1/0002-dt-bindings-clock-Add-StarFive-JH7110-always-on-cloc.patch
+++ /dev/null
@@ -1,176 +0,0 @@
-From cd833f484009f37be57a2aa09257af6e8c1b25b6 Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Sat, 1 Apr 2023 19:19:14 +0800
-Subject: [PATCH 002/122] dt-bindings: clock: Add StarFive JH7110 always-on
- clock and reset generator
-
-Add bindings for the always-on clock and reset generator (AONCRG) on the
-JH7110 RISC-V SoC by StarFive Ltd.
-
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
-Reviewed-by: Rob Herring <robh@kernel.org>
-Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
-Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
-Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
----
- .../clock/starfive,jh7110-aoncrg.yaml | 107 ++++++++++++++++++
- .../dt-bindings/clock/starfive,jh7110-crg.h | 18 +++
- .../dt-bindings/reset/starfive,jh7110-crg.h | 12 ++
- 3 files changed, 137 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/clock/starfive,jh7110-aoncrg.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/clock/starfive,jh7110-aoncrg.yaml
-@@ -0,0 +1,107 @@
-+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/clock/starfive,jh7110-aoncrg.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: StarFive JH7110 Always-On Clock and Reset Generator
-+
-+maintainers:
-+ - Emil Renner Berthing <kernel@esmil.dk>
-+
-+properties:
-+ compatible:
-+ const: starfive,jh7110-aoncrg
-+
-+ reg:
-+ maxItems: 1
-+
-+ clocks:
-+ oneOf:
-+ - items:
-+ - description: Main Oscillator (24 MHz)
-+ - description: GMAC0 RMII reference or GMAC0 RGMII RX
-+ - description: STG AXI/AHB
-+ - description: APB Bus
-+ - description: GMAC0 GTX
-+
-+ - items:
-+ - description: Main Oscillator (24 MHz)
-+ - description: GMAC0 RMII reference or GMAC0 RGMII RX
-+ - description: STG AXI/AHB or GMAC0 RGMII RX
-+ - description: APB Bus or STG AXI/AHB
-+ - description: GMAC0 GTX or APB Bus
-+ - description: RTC Oscillator (32.768 kHz) or GMAC0 GTX
-+
-+ - items:
-+ - description: Main Oscillator (24 MHz)
-+ - description: GMAC0 RMII reference
-+ - description: GMAC0 RGMII RX
-+ - description: STG AXI/AHB
-+ - description: APB Bus
-+ - description: GMAC0 GTX
-+ - description: RTC Oscillator (32.768 kHz)
-+
-+ clock-names:
-+ oneOf:
-+ - minItems: 5
-+ items:
-+ - const: osc
-+ - enum:
-+ - gmac0_rmii_refin
-+ - gmac0_rgmii_rxin
-+ - const: stg_axiahb
-+ - const: apb_bus
-+ - const: gmac0_gtxclk
-+ - const: rtc_osc
-+
-+ - minItems: 6
-+ items:
-+ - const: osc
-+ - const: gmac0_rmii_refin
-+ - const: gmac0_rgmii_rxin
-+ - const: stg_axiahb
-+ - const: apb_bus
-+ - const: gmac0_gtxclk
-+ - const: rtc_osc
-+
-+ '#clock-cells':
-+ const: 1
-+ description:
-+ See <dt-bindings/clock/starfive,jh7110-crg.h> for valid indices.
-+
-+ '#reset-cells':
-+ const: 1
-+ description:
-+ See <dt-bindings/reset/starfive,jh7110-crg.h> for valid indices.
-+
-+required:
-+ - compatible
-+ - reg
-+ - clocks
-+ - clock-names
-+ - '#clock-cells'
-+ - '#reset-cells'
-+
-+additionalProperties: false
-+
-+examples:
-+ - |
-+ #include <dt-bindings/clock/starfive,jh7110-crg.h>
-+
-+ clock-controller@17000000 {
-+ compatible = "starfive,jh7110-aoncrg";
-+ reg = <0x17000000 0x10000>;
-+ clocks = <&osc>, <&gmac0_rmii_refin>,
-+ <&gmac0_rgmii_rxin>,
-+ <&syscrg JH7110_SYSCLK_STG_AXIAHB>,
-+ <&syscrg JH7110_SYSCLK_APB_BUS>,
-+ <&syscrg JH7110_SYSCLK_GMAC0_GTXCLK>,
-+ <&rtc_osc>;
-+ clock-names = "osc", "gmac0_rmii_refin",
-+ "gmac0_rgmii_rxin", "stg_axiahb",
-+ "apb_bus", "gmac0_gtxclk",
-+ "rtc_osc";
-+ #clock-cells = <1>;
-+ #reset-cells = <1>;
-+ };
---- a/include/dt-bindings/clock/starfive,jh7110-crg.h
-+++ b/include/dt-bindings/clock/starfive,jh7110-crg.h
-@@ -200,4 +200,22 @@
-
- #define JH7110_SYSCLK_END 190
-
-+/* AONCRG clocks */
-+#define JH7110_AONCLK_OSC_DIV4 0
-+#define JH7110_AONCLK_APB_FUNC 1
-+#define JH7110_AONCLK_GMAC0_AHB 2
-+#define JH7110_AONCLK_GMAC0_AXI 3
-+#define JH7110_AONCLK_GMAC0_RMII_RTX 4
-+#define JH7110_AONCLK_GMAC0_TX 5
-+#define JH7110_AONCLK_GMAC0_TX_INV 6
-+#define JH7110_AONCLK_GMAC0_RX 7
-+#define JH7110_AONCLK_GMAC0_RX_INV 8
-+#define JH7110_AONCLK_OTPC_APB 9
-+#define JH7110_AONCLK_RTC_APB 10
-+#define JH7110_AONCLK_RTC_INTERNAL 11
-+#define JH7110_AONCLK_RTC_32K 12
-+#define JH7110_AONCLK_RTC_CAL 13
-+
-+#define JH7110_AONCLK_END 14
-+
- #endif /* __DT_BINDINGS_CLOCK_STARFIVE_JH7110_CRG_H__ */
---- a/include/dt-bindings/reset/starfive,jh7110-crg.h
-+++ b/include/dt-bindings/reset/starfive,jh7110-crg.h
-@@ -139,4 +139,16 @@
-
- #define JH7110_SYSRST_END 126
-
-+/* AONCRG resets */
-+#define JH7110_AONRST_GMAC0_AXI 0
-+#define JH7110_AONRST_GMAC0_AHB 1
-+#define JH7110_AONRST_IOMUX 2
-+#define JH7110_AONRST_PMU_APB 3
-+#define JH7110_AONRST_PMU_WKUP 4
-+#define JH7110_AONRST_RTC_APB 5
-+#define JH7110_AONRST_RTC_CAL 6
-+#define JH7110_AONRST_RTC_32K 7
-+
-+#define JH7110_AONRST_END 8
-+
- #endif /* __DT_BINDINGS_RESET_STARFIVE_JH7110_CRG_H__ */
diff --git a/target/linux/starfive/patches-6.1/0003-clk-starfive-Replace-SOC_STARFIVE-with-ARCH_STARFIVE.patch b/target/linux/starfive/patches-6.1/0003-clk-starfive-Replace-SOC_STARFIVE-with-ARCH_STARFIVE.patch
deleted file mode 100644
index 1cedd313d9..0000000000
--- a/target/linux/starfive/patches-6.1/0003-clk-starfive-Replace-SOC_STARFIVE-with-ARCH_STARFIVE.patch
+++ /dev/null
@@ -1,53 +0,0 @@
-From 124f322d1c42232e439ea9a356d68caf1d0656f3 Mon Sep 17 00:00:00 2001
-From: Hal Feng <hal.feng@starfivetech.com>
-Date: Sat, 1 Apr 2023 19:19:15 +0800
-Subject: [PATCH 003/122] clk: starfive: Replace SOC_STARFIVE with
- ARCH_STARFIVE
-
-Using ARCH_FOO symbol is preferred than SOC_FOO.
-Set obj-y for starfive/ in Makefile, so the StarFive drivers
-can be compiled with COMPILE_TEST=y but ARCH_STARFIVE=n.
-
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
-Reviewed-by: Heiko Stuebner <heiko.stuebner@vrull.eu>
-Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
-Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
-Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
----
- drivers/clk/Makefile | 2 +-
- drivers/clk/starfive/Kconfig | 6 +++---
- 2 files changed, 4 insertions(+), 4 deletions(-)
-
---- a/drivers/clk/Makefile
-+++ b/drivers/clk/Makefile
-@@ -117,7 +117,7 @@ obj-$(CONFIG_PLAT_SPEAR) += spear/
- obj-y += sprd/
- obj-$(CONFIG_ARCH_STI) += st/
- obj-$(CONFIG_ARCH_STM32) += stm32/
--obj-$(CONFIG_SOC_STARFIVE) += starfive/
-+obj-y += starfive/
- obj-$(CONFIG_ARCH_SUNXI) += sunxi/
- obj-y += sunxi-ng/
- obj-$(CONFIG_ARCH_TEGRA) += tegra/
---- a/drivers/clk/starfive/Kconfig
-+++ b/drivers/clk/starfive/Kconfig
-@@ -2,8 +2,8 @@
-
- config CLK_STARFIVE_JH7100
- bool "StarFive JH7100 clock support"
-- depends on SOC_STARFIVE || COMPILE_TEST
-- default SOC_STARFIVE
-+ depends on ARCH_STARFIVE || COMPILE_TEST
-+ default ARCH_STARFIVE
- help
- Say yes here to support the clock controller on the StarFive JH7100
- SoC.
-@@ -11,7 +11,7 @@ config CLK_STARFIVE_JH7100
- config CLK_STARFIVE_JH7100_AUDIO
- tristate "StarFive JH7100 audio clock support"
- depends on CLK_STARFIVE_JH7100
-- default m if SOC_STARFIVE
-+ default m if ARCH_STARFIVE
- help
- Say Y or M here to support the audio clocks on the StarFive JH7100
- SoC.
diff --git a/target/linux/starfive/patches-6.1/0004-clk-starfive-Factor-out-common-JH7100-and-JH7110-cod.patch b/target/linux/starfive/patches-6.1/0004-clk-starfive-Factor-out-common-JH7100-and-JH7110-cod.patch
deleted file mode 100644
index 72375bb0d9..0000000000
--- a/target/linux/starfive/patches-6.1/0004-clk-starfive-Factor-out-common-JH7100-and-JH7110-cod.patch
+++ /dev/null
@@ -1,749 +0,0 @@
-From 6f14eb919e5b92076e17aec5388655348963eef7 Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Sat, 1 Apr 2023 19:19:16 +0800
-Subject: [PATCH 004/122] clk: starfive: Factor out common JH7100 and JH7110
- code
-
-The clock control registers on the StarFive JH7100 and JH7110 work
-identically, so factor out the code then drivers for the two SoCs
-can share it without depending on each other. No functional change.
-
-Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
-Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
-Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
-Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
----
- drivers/clk/starfive/Kconfig | 5 +
- drivers/clk/starfive/Makefile | 3 +-
- drivers/clk/starfive/clk-starfive-jh7100.c | 325 --------------------
- drivers/clk/starfive/clk-starfive-jh7100.h | 2 +
- drivers/clk/starfive/clk-starfive-jh71x0.c | 333 +++++++++++++++++++++
- 5 files changed, 342 insertions(+), 326 deletions(-)
- create mode 100644 drivers/clk/starfive/clk-starfive-jh71x0.c
-
---- a/drivers/clk/starfive/Kconfig
-+++ b/drivers/clk/starfive/Kconfig
-@@ -1,8 +1,12 @@
- # SPDX-License-Identifier: GPL-2.0
-
-+config CLK_STARFIVE_JH71X0
-+ bool
-+
- config CLK_STARFIVE_JH7100
- bool "StarFive JH7100 clock support"
- depends on ARCH_STARFIVE || COMPILE_TEST
-+ select CLK_STARFIVE_JH71X0
- default ARCH_STARFIVE
- help
- Say yes here to support the clock controller on the StarFive JH7100
-@@ -11,6 +15,7 @@ config CLK_STARFIVE_JH7100
- config CLK_STARFIVE_JH7100_AUDIO
- tristate "StarFive JH7100 audio clock support"
- depends on CLK_STARFIVE_JH7100
-+ select CLK_STARFIVE_JH71X0
- default m if ARCH_STARFIVE
- help
- Say Y or M here to support the audio clocks on the StarFive JH7100
---- a/drivers/clk/starfive/Makefile
-+++ b/drivers/clk/starfive/Makefile
-@@ -1,4 +1,5 @@
- # SPDX-License-Identifier: GPL-2.0
--# StarFive Clock
-+obj-$(CONFIG_CLK_STARFIVE_JH71X0) += clk-starfive-jh71x0.o
-+
- obj-$(CONFIG_CLK_STARFIVE_JH7100) += clk-starfive-jh7100.o
- obj-$(CONFIG_CLK_STARFIVE_JH7100_AUDIO) += clk-starfive-jh7100-audio.o
---- a/drivers/clk/starfive/clk-starfive-jh7100.c
-+++ b/drivers/clk/starfive/clk-starfive-jh7100.c
-@@ -7,15 +7,10 @@
- * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
- */
-
--#include <linux/bits.h>
- #include <linux/clk-provider.h>
--#include <linux/debugfs.h>
- #include <linux/device.h>
- #include <linux/init.h>
--#include <linux/io.h>
--#include <linux/kernel.h>
- #include <linux/mod_devicetable.h>
--#include <linux/module.h>
- #include <linux/platform_device.h>
-
- #include <dt-bindings/clock/starfive-jh7100.h>
-@@ -269,326 +264,6 @@ static const struct jh7100_clk_data jh71
- JH7100_GATE(JH7100_CLK_SYSERR_APB, "syserr_apb", 0, JH7100_CLK_APB2_BUS),
- };
-
--static struct jh7100_clk *jh7100_clk_from(struct clk_hw *hw)
--{
-- return container_of(hw, struct jh7100_clk, hw);
--}
--
--static struct jh7100_clk_priv *jh7100_priv_from(struct jh7100_clk *clk)
--{
-- return container_of(clk, struct jh7100_clk_priv, reg[clk->idx]);
--}
--
--static u32 jh7100_clk_reg_get(struct jh7100_clk *clk)
--{
-- struct jh7100_clk_priv *priv = jh7100_priv_from(clk);
-- void __iomem *reg = priv->base + 4 * clk->idx;
--
-- return readl_relaxed(reg);
--}
--
--static void jh7100_clk_reg_rmw(struct jh7100_clk *clk, u32 mask, u32 value)
--{
-- struct jh7100_clk_priv *priv = jh7100_priv_from(clk);
-- void __iomem *reg = priv->base + 4 * clk->idx;
-- unsigned long flags;
--
-- spin_lock_irqsave(&priv->rmw_lock, flags);
-- value |= readl_relaxed(reg) & ~mask;
-- writel_relaxed(value, reg);
-- spin_unlock_irqrestore(&priv->rmw_lock, flags);
--}
--
--static int jh7100_clk_enable(struct clk_hw *hw)
--{
-- struct jh7100_clk *clk = jh7100_clk_from(hw);
--
-- jh7100_clk_reg_rmw(clk, JH7100_CLK_ENABLE, JH7100_CLK_ENABLE);
-- return 0;
--}
--
--static void jh7100_clk_disable(struct clk_hw *hw)
--{
-- struct jh7100_clk *clk = jh7100_clk_from(hw);
--
-- jh7100_clk_reg_rmw(clk, JH7100_CLK_ENABLE, 0);
--}
--
--static int jh7100_clk_is_enabled(struct clk_hw *hw)
--{
-- struct jh7100_clk *clk = jh7100_clk_from(hw);
--
-- return !!(jh7100_clk_reg_get(clk) & JH7100_CLK_ENABLE);
--}
--
--static unsigned long jh7100_clk_recalc_rate(struct clk_hw *hw,
-- unsigned long parent_rate)
--{
-- struct jh7100_clk *clk = jh7100_clk_from(hw);
-- u32 div = jh7100_clk_reg_get(clk) & JH7100_CLK_DIV_MASK;
--
-- return div ? parent_rate / div : 0;
--}
--
--static int jh7100_clk_determine_rate(struct clk_hw *hw,
-- struct clk_rate_request *req)
--{
-- struct jh7100_clk *clk = jh7100_clk_from(hw);
-- unsigned long parent = req->best_parent_rate;
-- unsigned long rate = clamp(req->rate, req->min_rate, req->max_rate);
-- unsigned long div = min_t(unsigned long, DIV_ROUND_UP(parent, rate), clk->max_div);
-- unsigned long result = parent / div;
--
-- /*
-- * we want the result clamped by min_rate and max_rate if possible:
-- * case 1: div hits the max divider value, which means it's less than
-- * parent / rate, so the result is greater than rate and min_rate in
-- * particular. we can't do anything about result > max_rate because the
-- * divider doesn't go any further.
-- * case 2: div = DIV_ROUND_UP(parent, rate) which means the result is
-- * always lower or equal to rate and max_rate. however the result may
-- * turn out lower than min_rate, but then the next higher rate is fine:
-- * div - 1 = ceil(parent / rate) - 1 < parent / rate
-- * and thus
-- * min_rate <= rate < parent / (div - 1)
-- */
-- if (result < req->min_rate && div > 1)
-- result = parent / (div - 1);
--
-- req->rate = result;
-- return 0;
--}
--
--static int jh7100_clk_set_rate(struct clk_hw *hw,
-- unsigned long rate,
-- unsigned long parent_rate)
--{
-- struct jh7100_clk *clk = jh7100_clk_from(hw);
-- unsigned long div = clamp(DIV_ROUND_CLOSEST(parent_rate, rate),
-- 1UL, (unsigned long)clk->max_div);
--
-- jh7100_clk_reg_rmw(clk, JH7100_CLK_DIV_MASK, div);
-- return 0;
--}
--
--static unsigned long jh7100_clk_frac_recalc_rate(struct clk_hw *hw,
-- unsigned long parent_rate)
--{
-- struct jh7100_clk *clk = jh7100_clk_from(hw);
-- u32 reg = jh7100_clk_reg_get(clk);
-- unsigned long div100 = 100 * (reg & JH7100_CLK_INT_MASK) +
-- ((reg & JH7100_CLK_FRAC_MASK) >> JH7100_CLK_FRAC_SHIFT);
--
-- return (div100 >= JH7100_CLK_FRAC_MIN) ? 100 * parent_rate / div100 : 0;
--}
--
--static int jh7100_clk_frac_determine_rate(struct clk_hw *hw,
-- struct clk_rate_request *req)
--{
-- unsigned long parent100 = 100 * req->best_parent_rate;
-- unsigned long rate = clamp(req->rate, req->min_rate, req->max_rate);
-- unsigned long div100 = clamp(DIV_ROUND_CLOSEST(parent100, rate),
-- JH7100_CLK_FRAC_MIN, JH7100_CLK_FRAC_MAX);
-- unsigned long result = parent100 / div100;
--
-- /* clamp the result as in jh7100_clk_determine_rate() above */
-- if (result > req->max_rate && div100 < JH7100_CLK_FRAC_MAX)
-- result = parent100 / (div100 + 1);
-- if (result < req->min_rate && div100 > JH7100_CLK_FRAC_MIN)
-- result = parent100 / (div100 - 1);
--
-- req->rate = result;
-- return 0;
--}
--
--static int jh7100_clk_frac_set_rate(struct clk_hw *hw,
-- unsigned long rate,
-- unsigned long parent_rate)
--{
-- struct jh7100_clk *clk = jh7100_clk_from(hw);
-- unsigned long div100 = clamp(DIV_ROUND_CLOSEST(100 * parent_rate, rate),
-- JH7100_CLK_FRAC_MIN, JH7100_CLK_FRAC_MAX);
-- u32 value = ((div100 % 100) << JH7100_CLK_FRAC_SHIFT) | (div100 / 100);
--
-- jh7100_clk_reg_rmw(clk, JH7100_CLK_DIV_MASK, value);
-- return 0;
--}
--
--static u8 jh7100_clk_get_parent(struct clk_hw *hw)
--{
-- struct jh7100_clk *clk = jh7100_clk_from(hw);
-- u32 value = jh7100_clk_reg_get(clk);
--
-- return (value & JH7100_CLK_MUX_MASK) >> JH7100_CLK_MUX_SHIFT;
--}
--
--static int jh7100_clk_set_parent(struct clk_hw *hw, u8 index)
--{
-- struct jh7100_clk *clk = jh7100_clk_from(hw);
-- u32 value = (u32)index << JH7100_CLK_MUX_SHIFT;
--
-- jh7100_clk_reg_rmw(clk, JH7100_CLK_MUX_MASK, value);
-- return 0;
--}
--
--static int jh7100_clk_mux_determine_rate(struct clk_hw *hw,
-- struct clk_rate_request *req)
--{
-- return clk_mux_determine_rate_flags(hw, req, 0);
--}
--
--static int jh7100_clk_get_phase(struct clk_hw *hw)
--{
-- struct jh7100_clk *clk = jh7100_clk_from(hw);
-- u32 value = jh7100_clk_reg_get(clk);
--
-- return (value & JH7100_CLK_INVERT) ? 180 : 0;
--}
--
--static int jh7100_clk_set_phase(struct clk_hw *hw, int degrees)
--{
-- struct jh7100_clk *clk = jh7100_clk_from(hw);
-- u32 value;
--
-- if (degrees == 0)
-- value = 0;
-- else if (degrees == 180)
-- value = JH7100_CLK_INVERT;
-- else
-- return -EINVAL;
--
-- jh7100_clk_reg_rmw(clk, JH7100_CLK_INVERT, value);
-- return 0;
--}
--
--#ifdef CONFIG_DEBUG_FS
--static void jh7100_clk_debug_init(struct clk_hw *hw, struct dentry *dentry)
--{
-- static const struct debugfs_reg32 jh7100_clk_reg = {
-- .name = "CTRL",
-- .offset = 0,
-- };
-- struct jh7100_clk *clk = jh7100_clk_from(hw);
-- struct jh7100_clk_priv *priv = jh7100_priv_from(clk);
-- struct debugfs_regset32 *regset;
--
-- regset = devm_kzalloc(priv->dev, sizeof(*regset), GFP_KERNEL);
-- if (!regset)
-- return;
--
-- regset->regs = &jh7100_clk_reg;
-- regset->nregs = 1;
-- regset->base = priv->base + 4 * clk->idx;
--
-- debugfs_create_regset32("registers", 0400, dentry, regset);
--}
--#else
--#define jh7100_clk_debug_init NULL
--#endif
--
--static const struct clk_ops jh7100_clk_gate_ops = {
-- .enable = jh7100_clk_enable,
-- .disable = jh7100_clk_disable,
-- .is_enabled = jh7100_clk_is_enabled,
-- .debug_init = jh7100_clk_debug_init,
--};
--
--static const struct clk_ops jh7100_clk_div_ops = {
-- .recalc_rate = jh7100_clk_recalc_rate,
-- .determine_rate = jh7100_clk_determine_rate,
-- .set_rate = jh7100_clk_set_rate,
-- .debug_init = jh7100_clk_debug_init,
--};
--
--static const struct clk_ops jh7100_clk_fdiv_ops = {
-- .recalc_rate = jh7100_clk_frac_recalc_rate,
-- .determine_rate = jh7100_clk_frac_determine_rate,
-- .set_rate = jh7100_clk_frac_set_rate,
-- .debug_init = jh7100_clk_debug_init,
--};
--
--static const struct clk_ops jh7100_clk_gdiv_ops = {
-- .enable = jh7100_clk_enable,
-- .disable = jh7100_clk_disable,
-- .is_enabled = jh7100_clk_is_enabled,
-- .recalc_rate = jh7100_clk_recalc_rate,
-- .determine_rate = jh7100_clk_determine_rate,
-- .set_rate = jh7100_clk_set_rate,
-- .debug_init = jh7100_clk_debug_init,
--};
--
--static const struct clk_ops jh7100_clk_mux_ops = {
-- .determine_rate = jh7100_clk_mux_determine_rate,
-- .set_parent = jh7100_clk_set_parent,
-- .get_parent = jh7100_clk_get_parent,
-- .debug_init = jh7100_clk_debug_init,
--};
--
--static const struct clk_ops jh7100_clk_gmux_ops = {
-- .enable = jh7100_clk_enable,
-- .disable = jh7100_clk_disable,
-- .is_enabled = jh7100_clk_is_enabled,
-- .determine_rate = jh7100_clk_mux_determine_rate,
-- .set_parent = jh7100_clk_set_parent,
-- .get_parent = jh7100_clk_get_parent,
-- .debug_init = jh7100_clk_debug_init,
--};
--
--static const struct clk_ops jh7100_clk_mdiv_ops = {
-- .recalc_rate = jh7100_clk_recalc_rate,
-- .determine_rate = jh7100_clk_determine_rate,
-- .get_parent = jh7100_clk_get_parent,
-- .set_parent = jh7100_clk_set_parent,
-- .set_rate = jh7100_clk_set_rate,
-- .debug_init = jh7100_clk_debug_init,
--};
--
--static const struct clk_ops jh7100_clk_gmd_ops = {
-- .enable = jh7100_clk_enable,
-- .disable = jh7100_clk_disable,
-- .is_enabled = jh7100_clk_is_enabled,
-- .recalc_rate = jh7100_clk_recalc_rate,
-- .determine_rate = jh7100_clk_determine_rate,
-- .get_parent = jh7100_clk_get_parent,
-- .set_parent = jh7100_clk_set_parent,
-- .set_rate = jh7100_clk_set_rate,
-- .debug_init = jh7100_clk_debug_init,
--};
--
--static const struct clk_ops jh7100_clk_inv_ops = {
-- .get_phase = jh7100_clk_get_phase,
-- .set_phase = jh7100_clk_set_phase,
-- .debug_init = jh7100_clk_debug_init,
--};
--
--const struct clk_ops *starfive_jh7100_clk_ops(u32 max)
--{
-- if (max & JH7100_CLK_DIV_MASK) {
-- if (max & JH7100_CLK_MUX_MASK) {
-- if (max & JH7100_CLK_ENABLE)
-- return &jh7100_clk_gmd_ops;
-- return &jh7100_clk_mdiv_ops;
-- }
-- if (max & JH7100_CLK_ENABLE)
-- return &jh7100_clk_gdiv_ops;
-- if (max == JH7100_CLK_FRAC_MAX)
-- return &jh7100_clk_fdiv_ops;
-- return &jh7100_clk_div_ops;
-- }
--
-- if (max & JH7100_CLK_MUX_MASK) {
-- if (max & JH7100_CLK_ENABLE)
-- return &jh7100_clk_gmux_ops;
-- return &jh7100_clk_mux_ops;
-- }
--
-- if (max & JH7100_CLK_ENABLE)
-- return &jh7100_clk_gate_ops;
--
-- return &jh7100_clk_inv_ops;
--}
--EXPORT_SYMBOL_GPL(starfive_jh7100_clk_ops);
--
- static struct clk_hw *jh7100_clk_get(struct of_phandle_args *clkspec, void *data)
- {
- struct jh7100_clk_priv *priv = data;
---- a/drivers/clk/starfive/clk-starfive-jh7100.h
-+++ b/drivers/clk/starfive/clk-starfive-jh7100.h
-@@ -4,6 +4,8 @@
-
- #include <linux/bits.h>
- #include <linux/clk-provider.h>
-+#include <linux/device.h>
-+#include <linux/spinlock.h>
-
- /* register fields */
- #define JH7100_CLK_ENABLE BIT(31)
---- /dev/null
-+++ b/drivers/clk/starfive/clk-starfive-jh71x0.c
-@@ -0,0 +1,333 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * StarFive JH7100 Clock Generator Driver
-+ *
-+ * Copyright (C) 2021-2022 Emil Renner Berthing <kernel@esmil.dk>
-+ */
-+
-+#include <linux/clk-provider.h>
-+#include <linux/debugfs.h>
-+#include <linux/device.h>
-+#include <linux/io.h>
-+
-+#include "clk-starfive-jh7100.h"
-+
-+static struct jh7100_clk *jh7100_clk_from(struct clk_hw *hw)
-+{
-+ return container_of(hw, struct jh7100_clk, hw);
-+}
-+
-+static struct jh7100_clk_priv *jh7100_priv_from(struct jh7100_clk *clk)
-+{
-+ return container_of(clk, struct jh7100_clk_priv, reg[clk->idx]);
-+}
-+
-+static u32 jh7100_clk_reg_get(struct jh7100_clk *clk)
-+{
-+ struct jh7100_clk_priv *priv = jh7100_priv_from(clk);
-+ void __iomem *reg = priv->base + 4 * clk->idx;
-+
-+ return readl_relaxed(reg);
-+}
-+
-+static void jh7100_clk_reg_rmw(struct jh7100_clk *clk, u32 mask, u32 value)
-+{
-+ struct jh7100_clk_priv *priv = jh7100_priv_from(clk);
-+ void __iomem *reg = priv->base + 4 * clk->idx;
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&priv->rmw_lock, flags);
-+ value |= readl_relaxed(reg) & ~mask;
-+ writel_relaxed(value, reg);
-+ spin_unlock_irqrestore(&priv->rmw_lock, flags);
-+}
-+
-+static int jh7100_clk_enable(struct clk_hw *hw)
-+{
-+ struct jh7100_clk *clk = jh7100_clk_from(hw);
-+
-+ jh7100_clk_reg_rmw(clk, JH7100_CLK_ENABLE, JH7100_CLK_ENABLE);
-+ return 0;
-+}
-+
-+static void jh7100_clk_disable(struct clk_hw *hw)
-+{
-+ struct jh7100_clk *clk = jh7100_clk_from(hw);
-+
-+ jh7100_clk_reg_rmw(clk, JH7100_CLK_ENABLE, 0);
-+}
-+
-+static int jh7100_clk_is_enabled(struct clk_hw *hw)
-+{
-+ struct jh7100_clk *clk = jh7100_clk_from(hw);
-+
-+ return !!(jh7100_clk_reg_get(clk) & JH7100_CLK_ENABLE);
-+}
-+
-+static unsigned long jh7100_clk_recalc_rate(struct clk_hw *hw,
-+ unsigned long parent_rate)
-+{
-+ struct jh7100_clk *clk = jh7100_clk_from(hw);
-+ u32 div = jh7100_clk_reg_get(clk) & JH7100_CLK_DIV_MASK;
-+
-+ return div ? parent_rate / div : 0;
-+}
-+
-+static int jh7100_clk_determine_rate(struct clk_hw *hw,
-+ struct clk_rate_request *req)
-+{
-+ struct jh7100_clk *clk = jh7100_clk_from(hw);
-+ unsigned long parent = req->best_parent_rate;
-+ unsigned long rate = clamp(req->rate, req->min_rate, req->max_rate);
-+ unsigned long div = min_t(unsigned long, DIV_ROUND_UP(parent, rate), clk->max_div);
-+ unsigned long result = parent / div;
-+
-+ /*
-+ * we want the result clamped by min_rate and max_rate if possible:
-+ * case 1: div hits the max divider value, which means it's less than
-+ * parent / rate, so the result is greater than rate and min_rate in
-+ * particular. we can't do anything about result > max_rate because the
-+ * divider doesn't go any further.
-+ * case 2: div = DIV_ROUND_UP(parent, rate) which means the result is
-+ * always lower or equal to rate and max_rate. however the result may
-+ * turn out lower than min_rate, but then the next higher rate is fine:
-+ * div - 1 = ceil(parent / rate) - 1 < parent / rate
-+ * and thus
-+ * min_rate <= rate < parent / (div - 1)
-+ */
-+ if (result < req->min_rate && div > 1)
-+ result = parent / (div - 1);
-+
-+ req->rate = result;
-+ return 0;
-+}
-+
-+static int jh7100_clk_set_rate(struct clk_hw *hw,
-+ unsigned long rate,
-+ unsigned long parent_rate)
-+{
-+ struct jh7100_clk *clk = jh7100_clk_from(hw);
-+ unsigned long div = clamp(DIV_ROUND_CLOSEST(parent_rate, rate),
-+ 1UL, (unsigned long)clk->max_div);
-+
-+ jh7100_clk_reg_rmw(clk, JH7100_CLK_DIV_MASK, div);
-+ return 0;
-+}
-+
-+static unsigned long jh7100_clk_frac_recalc_rate(struct clk_hw *hw,
-+ unsigned long parent_rate)
-+{
-+ struct jh7100_clk *clk = jh7100_clk_from(hw);
-+ u32 reg = jh7100_clk_reg_get(clk);
-+ unsigned long div100 = 100 * (reg & JH7100_CLK_INT_MASK) +
-+ ((reg & JH7100_CLK_FRAC_MASK) >> JH7100_CLK_FRAC_SHIFT);
-+
-+ return (div100 >= JH7100_CLK_FRAC_MIN) ? 100 * parent_rate / div100 : 0;
-+}
-+
-+static int jh7100_clk_frac_determine_rate(struct clk_hw *hw,
-+ struct clk_rate_request *req)
-+{
-+ unsigned long parent100 = 100 * req->best_parent_rate;
-+ unsigned long rate = clamp(req->rate, req->min_rate, req->max_rate);
-+ unsigned long div100 = clamp(DIV_ROUND_CLOSEST(parent100, rate),
-+ JH7100_CLK_FRAC_MIN, JH7100_CLK_FRAC_MAX);
-+ unsigned long result = parent100 / div100;
-+
-+ /* clamp the result as in jh7100_clk_determine_rate() above */
-+ if (result > req->max_rate && div100 < JH7100_CLK_FRAC_MAX)
-+ result = parent100 / (div100 + 1);
-+ if (result < req->min_rate && div100 > JH7100_CLK_FRAC_MIN)
-+ result = parent100 / (div100 - 1);
-+
-+ req->rate = result;
-+ return 0;
-+}
-+
-+static int jh7100_clk_frac_set_rate(struct clk_hw *hw,
-+ unsigned long rate,
-+ unsigned long parent_rate)
-+{
-+ struct jh7100_clk *clk = jh7100_clk_from(hw);
-+ unsigned long div100 = clamp(DIV_ROUND_CLOSEST(100 * parent_rate, rate),
-+ JH7100_CLK_FRAC_MIN, JH7100_CLK_FRAC_MAX);
-+ u32 value = ((div100 % 100) << JH7100_CLK_FRAC_SHIFT) | (div100 / 100);
-+
-+ jh7100_clk_reg_rmw(clk, JH7100_CLK_DIV_MASK, value);
-+ return 0;
-+}
-+
-+static u8 jh7100_clk_get_parent(struct clk_hw *hw)
-+{
-+ struct jh7100_clk *clk = jh7100_clk_from(hw);
-+ u32 value = jh7100_clk_reg_get(clk);
-+
-+ return (value & JH7100_CLK_MUX_MASK) >> JH7100_CLK_MUX_SHIFT;
-+}
-+
-+static int jh7100_clk_set_parent(struct clk_hw *hw, u8 index)
-+{
-+ struct jh7100_clk *clk = jh7100_clk_from(hw);
-+ u32 value = (u32)index << JH7100_CLK_MUX_SHIFT;
-+
-+ jh7100_clk_reg_rmw(clk, JH7100_CLK_MUX_MASK, value);
-+ return 0;
-+}
-+
-+static int jh7100_clk_mux_determine_rate(struct clk_hw *hw,
-+ struct clk_rate_request *req)
-+{
-+ return clk_mux_determine_rate_flags(hw, req, 0);
-+}
-+
-+static int jh7100_clk_get_phase(struct clk_hw *hw)
-+{
-+ struct jh7100_clk *clk = jh7100_clk_from(hw);
-+ u32 value = jh7100_clk_reg_get(clk);
-+
-+ return (value & JH7100_CLK_INVERT) ? 180 : 0;
-+}
-+
-+static int jh7100_clk_set_phase(struct clk_hw *hw, int degrees)
-+{
-+ struct jh7100_clk *clk = jh7100_clk_from(hw);
-+ u32 value;
-+
-+ if (degrees == 0)
-+ value = 0;
-+ else if (degrees == 180)
-+ value = JH7100_CLK_INVERT;
-+ else
-+ return -EINVAL;
-+
-+ jh7100_clk_reg_rmw(clk, JH7100_CLK_INVERT, value);
-+ return 0;
-+}
-+
-+#ifdef CONFIG_DEBUG_FS
-+static void jh7100_clk_debug_init(struct clk_hw *hw, struct dentry *dentry)
-+{
-+ static const struct debugfs_reg32 jh7100_clk_reg = {
-+ .name = "CTRL",
-+ .offset = 0,
-+ };
-+ struct jh7100_clk *clk = jh7100_clk_from(hw);
-+ struct jh7100_clk_priv *priv = jh7100_priv_from(clk);
-+ struct debugfs_regset32 *regset;
-+
-+ regset = devm_kzalloc(priv->dev, sizeof(*regset), GFP_KERNEL);
-+ if (!regset)
-+ return;
-+
-+ regset->regs = &jh7100_clk_reg;
-+ regset->nregs = 1;
-+ regset->base = priv->base + 4 * clk->idx;
-+
-+ debugfs_create_regset32("registers", 0400, dentry, regset);
-+}
-+#else
-+#define jh7100_clk_debug_init NULL
-+#endif
-+
-+static const struct clk_ops jh7100_clk_gate_ops = {
-+ .enable = jh7100_clk_enable,
-+ .disable = jh7100_clk_disable,
-+ .is_enabled = jh7100_clk_is_enabled,
-+ .debug_init = jh7100_clk_debug_init,
-+};
-+
-+static const struct clk_ops jh7100_clk_div_ops = {
-+ .recalc_rate = jh7100_clk_recalc_rate,
-+ .determine_rate = jh7100_clk_determine_rate,
-+ .set_rate = jh7100_clk_set_rate,
-+ .debug_init = jh7100_clk_debug_init,
-+};
-+
-+static const struct clk_ops jh7100_clk_fdiv_ops = {
-+ .recalc_rate = jh7100_clk_frac_recalc_rate,
-+ .determine_rate = jh7100_clk_frac_determine_rate,
-+ .set_rate = jh7100_clk_frac_set_rate,
-+ .debug_init = jh7100_clk_debug_init,
-+};
-+
-+static const struct clk_ops jh7100_clk_gdiv_ops = {
-+ .enable = jh7100_clk_enable,
-+ .disable = jh7100_clk_disable,
-+ .is_enabled = jh7100_clk_is_enabled,
-+ .recalc_rate = jh7100_clk_recalc_rate,
-+ .determine_rate = jh7100_clk_determine_rate,
-+ .set_rate = jh7100_clk_set_rate,
-+ .debug_init = jh7100_clk_debug_init,
-+};
-+
-+static const struct clk_ops jh7100_clk_mux_ops = {
-+ .determine_rate = jh7100_clk_mux_determine_rate,
-+ .set_parent = jh7100_clk_set_parent,
-+ .get_parent = jh7100_clk_get_parent,
-+ .debug_init = jh7100_clk_debug_init,
-+};
-+
-+static const struct clk_ops jh7100_clk_gmux_ops = {
-+ .enable = jh7100_clk_enable,
-+ .disable = jh7100_clk_disable,
-+ .is_enabled = jh7100_clk_is_enabled,
-+ .determine_rate = jh7100_clk_mux_determine_rate,
-+ .set_parent = jh7100_clk_set_parent,
-+ .get_parent = jh7100_clk_get_parent,
-+ .debug_init = jh7100_clk_debug_init,
-+};
-+
-+static const struct clk_ops jh7100_clk_mdiv_ops = {
-+ .recalc_rate = jh7100_clk_recalc_rate,
-+ .determine_rate = jh7100_clk_determine_rate,
-+ .get_parent = jh7100_clk_get_parent,
-+ .set_parent = jh7100_clk_set_parent,
-+ .set_rate = jh7100_clk_set_rate,
-+ .debug_init = jh7100_clk_debug_init,
-+};
-+
-+static const struct clk_ops jh7100_clk_gmd_ops = {
-+ .enable = jh7100_clk_enable,
-+ .disable = jh7100_clk_disable,
-+ .is_enabled = jh7100_clk_is_enabled,
-+ .recalc_rate = jh7100_clk_recalc_rate,
-+ .determine_rate = jh7100_clk_determine_rate,
-+ .get_parent = jh7100_clk_get_parent,
-+ .set_parent = jh7100_clk_set_parent,
-+ .set_rate = jh7100_clk_set_rate,
-+ .debug_init = jh7100_clk_debug_init,
-+};
-+
-+static const struct clk_ops jh7100_clk_inv_ops = {
-+ .get_phase = jh7100_clk_get_phase,
-+ .set_phase = jh7100_clk_set_phase,
-+ .debug_init = jh7100_clk_debug_init,
-+};
-+
-+const struct clk_ops *starfive_jh7100_clk_ops(u32 max)
-+{
-+ if (max & JH7100_CLK_DIV_MASK) {
-+ if (max & JH7100_CLK_MUX_MASK) {
-+ if (max & JH7100_CLK_ENABLE)
-+ return &jh7100_clk_gmd_ops;
-+ return &jh7100_clk_mdiv_ops;
-+ }
-+ if (max & JH7100_CLK_ENABLE)
-+ return &jh7100_clk_gdiv_ops;
-+ if (max == JH7100_CLK_FRAC_MAX)
-+ return &jh7100_clk_fdiv_ops;
-+ return &jh7100_clk_div_ops;
-+ }
-+
-+ if (max & JH7100_CLK_MUX_MASK) {
-+ if (max & JH7100_CLK_ENABLE)
-+ return &jh7100_clk_gmux_ops;
-+ return &jh7100_clk_mux_ops;
-+ }
-+
-+ if (max & JH7100_CLK_ENABLE)
-+ return &jh7100_clk_gate_ops;
-+
-+ return &jh7100_clk_inv_ops;
-+}
-+EXPORT_SYMBOL_GPL(starfive_jh7100_clk_ops);
diff --git a/target/linux/starfive/patches-6.1/0005-clk-starfive-Rename-clk-starfive-jh7100.h-to-clk-sta.patch b/target/linux/starfive/patches-6.1/0005-clk-starfive-Rename-clk-starfive-jh7100.h-to-clk-sta.patch
deleted file mode 100644
index e9d0e7a71f..0000000000
--- a/target/linux/starfive/patches-6.1/0005-clk-starfive-Rename-clk-starfive-jh7100.h-to-clk-sta.patch
+++ /dev/null
@@ -1,290 +0,0 @@
-From 8daa4c812f3b32a4d56ab48945e552a137fca9b7 Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Sat, 1 Apr 2023 19:19:17 +0800
-Subject: [PATCH 005/122] clk: starfive: Rename clk-starfive-jh7100.h to
- clk-starfive-jh71x0.h
-
-Rename clk-starfive-jh7100.h to clk-starfive-jh71x0.h for making
-the code to be common.
-
-Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
-Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
-Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
-Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
----
- drivers/clk/starfive/clk-starfive-jh7100-audio.c | 2 +-
- drivers/clk/starfive/clk-starfive-jh7100.c | 2 +-
- drivers/clk/starfive/clk-starfive-jh71x0.c | 2 +-
- .../starfive/{clk-starfive-jh7100.h => clk-starfive-jh71x0.h} | 0
- 4 files changed, 3 insertions(+), 3 deletions(-)
- rename drivers/clk/starfive/{clk-starfive-jh7100.h => clk-starfive-jh71x0.h} (100%)
-
---- a/drivers/clk/starfive/clk-starfive-jh7100-audio.c
-+++ b/drivers/clk/starfive/clk-starfive-jh7100-audio.c
-@@ -16,7 +16,7 @@
-
- #include <dt-bindings/clock/starfive-jh7100-audio.h>
-
--#include "clk-starfive-jh7100.h"
-+#include "clk-starfive-jh71x0.h"
-
- /* external clocks */
- #define JH7100_AUDCLK_AUDIO_SRC (JH7100_AUDCLK_END + 0)
---- a/drivers/clk/starfive/clk-starfive-jh7100.c
-+++ b/drivers/clk/starfive/clk-starfive-jh7100.c
-@@ -15,7 +15,7 @@
-
- #include <dt-bindings/clock/starfive-jh7100.h>
-
--#include "clk-starfive-jh7100.h"
-+#include "clk-starfive-jh71x0.h"
-
- /* external clocks */
- #define JH7100_CLK_OSC_SYS (JH7100_CLK_END + 0)
---- a/drivers/clk/starfive/clk-starfive-jh71x0.c
-+++ b/drivers/clk/starfive/clk-starfive-jh71x0.c
-@@ -10,7 +10,7 @@
- #include <linux/device.h>
- #include <linux/io.h>
-
--#include "clk-starfive-jh7100.h"
-+#include "clk-starfive-jh71x0.h"
-
- static struct jh7100_clk *jh7100_clk_from(struct clk_hw *hw)
- {
---- a/drivers/clk/starfive/clk-starfive-jh7100.h
-+++ /dev/null
-@@ -1,114 +0,0 @@
--/* SPDX-License-Identifier: GPL-2.0 */
--#ifndef __CLK_STARFIVE_JH7100_H
--#define __CLK_STARFIVE_JH7100_H
--
--#include <linux/bits.h>
--#include <linux/clk-provider.h>
--#include <linux/device.h>
--#include <linux/spinlock.h>
--
--/* register fields */
--#define JH7100_CLK_ENABLE BIT(31)
--#define JH7100_CLK_INVERT BIT(30)
--#define JH7100_CLK_MUX_MASK GENMASK(27, 24)
--#define JH7100_CLK_MUX_SHIFT 24
--#define JH7100_CLK_DIV_MASK GENMASK(23, 0)
--#define JH7100_CLK_FRAC_MASK GENMASK(15, 8)
--#define JH7100_CLK_FRAC_SHIFT 8
--#define JH7100_CLK_INT_MASK GENMASK(7, 0)
--
--/* fractional divider min/max */
--#define JH7100_CLK_FRAC_MIN 100UL
--#define JH7100_CLK_FRAC_MAX 25599UL
--
--/* clock data */
--struct jh7100_clk_data {
-- const char *name;
-- unsigned long flags;
-- u32 max;
-- u8 parents[4];
--};
--
--#define JH7100_GATE(_idx, _name, _flags, _parent) [_idx] = { \
-- .name = _name, \
-- .flags = CLK_SET_RATE_PARENT | (_flags), \
-- .max = JH7100_CLK_ENABLE, \
-- .parents = { [0] = _parent }, \
--}
--
--#define JH7100__DIV(_idx, _name, _max, _parent) [_idx] = { \
-- .name = _name, \
-- .flags = 0, \
-- .max = _max, \
-- .parents = { [0] = _parent }, \
--}
--
--#define JH7100_GDIV(_idx, _name, _flags, _max, _parent) [_idx] = { \
-- .name = _name, \
-- .flags = _flags, \
-- .max = JH7100_CLK_ENABLE | (_max), \
-- .parents = { [0] = _parent }, \
--}
--
--#define JH7100_FDIV(_idx, _name, _parent) [_idx] = { \
-- .name = _name, \
-- .flags = 0, \
-- .max = JH7100_CLK_FRAC_MAX, \
-- .parents = { [0] = _parent }, \
--}
--
--#define JH7100__MUX(_idx, _name, _nparents, ...) [_idx] = { \
-- .name = _name, \
-- .flags = 0, \
-- .max = ((_nparents) - 1) << JH7100_CLK_MUX_SHIFT, \
-- .parents = { __VA_ARGS__ }, \
--}
--
--#define JH7100_GMUX(_idx, _name, _flags, _nparents, ...) [_idx] = { \
-- .name = _name, \
-- .flags = _flags, \
-- .max = JH7100_CLK_ENABLE | \
-- (((_nparents) - 1) << JH7100_CLK_MUX_SHIFT), \
-- .parents = { __VA_ARGS__ }, \
--}
--
--#define JH7100_MDIV(_idx, _name, _max, _nparents, ...) [_idx] = { \
-- .name = _name, \
-- .flags = 0, \
-- .max = (((_nparents) - 1) << JH7100_CLK_MUX_SHIFT) | (_max), \
-- .parents = { __VA_ARGS__ }, \
--}
--
--#define JH7100__GMD(_idx, _name, _flags, _max, _nparents, ...) [_idx] = { \
-- .name = _name, \
-- .flags = _flags, \
-- .max = JH7100_CLK_ENABLE | \
-- (((_nparents) - 1) << JH7100_CLK_MUX_SHIFT) | (_max), \
-- .parents = { __VA_ARGS__ }, \
--}
--
--#define JH7100__INV(_idx, _name, _parent) [_idx] = { \
-- .name = _name, \
-- .flags = CLK_SET_RATE_PARENT, \
-- .max = JH7100_CLK_INVERT, \
-- .parents = { [0] = _parent }, \
--}
--
--struct jh7100_clk {
-- struct clk_hw hw;
-- unsigned int idx;
-- unsigned int max_div;
--};
--
--struct jh7100_clk_priv {
-- /* protect clk enable and set rate/parent from happening at the same time */
-- spinlock_t rmw_lock;
-- struct device *dev;
-- void __iomem *base;
-- struct clk_hw *pll[3];
-- struct jh7100_clk reg[];
--};
--
--const struct clk_ops *starfive_jh7100_clk_ops(u32 max);
--
--#endif
---- /dev/null
-+++ b/drivers/clk/starfive/clk-starfive-jh71x0.h
-@@ -0,0 +1,114 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+#ifndef __CLK_STARFIVE_JH7100_H
-+#define __CLK_STARFIVE_JH7100_H
-+
-+#include <linux/bits.h>
-+#include <linux/clk-provider.h>
-+#include <linux/device.h>
-+#include <linux/spinlock.h>
-+
-+/* register fields */
-+#define JH7100_CLK_ENABLE BIT(31)
-+#define JH7100_CLK_INVERT BIT(30)
-+#define JH7100_CLK_MUX_MASK GENMASK(27, 24)
-+#define JH7100_CLK_MUX_SHIFT 24
-+#define JH7100_CLK_DIV_MASK GENMASK(23, 0)
-+#define JH7100_CLK_FRAC_MASK GENMASK(15, 8)
-+#define JH7100_CLK_FRAC_SHIFT 8
-+#define JH7100_CLK_INT_MASK GENMASK(7, 0)
-+
-+/* fractional divider min/max */
-+#define JH7100_CLK_FRAC_MIN 100UL
-+#define JH7100_CLK_FRAC_MAX 25599UL
-+
-+/* clock data */
-+struct jh7100_clk_data {
-+ const char *name;
-+ unsigned long flags;
-+ u32 max;
-+ u8 parents[4];
-+};
-+
-+#define JH7100_GATE(_idx, _name, _flags, _parent) [_idx] = { \
-+ .name = _name, \
-+ .flags = CLK_SET_RATE_PARENT | (_flags), \
-+ .max = JH7100_CLK_ENABLE, \
-+ .parents = { [0] = _parent }, \
-+}
-+
-+#define JH7100__DIV(_idx, _name, _max, _parent) [_idx] = { \
-+ .name = _name, \
-+ .flags = 0, \
-+ .max = _max, \
-+ .parents = { [0] = _parent }, \
-+}
-+
-+#define JH7100_GDIV(_idx, _name, _flags, _max, _parent) [_idx] = { \
-+ .name = _name, \
-+ .flags = _flags, \
-+ .max = JH7100_CLK_ENABLE | (_max), \
-+ .parents = { [0] = _parent }, \
-+}
-+
-+#define JH7100_FDIV(_idx, _name, _parent) [_idx] = { \
-+ .name = _name, \
-+ .flags = 0, \
-+ .max = JH7100_CLK_FRAC_MAX, \
-+ .parents = { [0] = _parent }, \
-+}
-+
-+#define JH7100__MUX(_idx, _name, _nparents, ...) [_idx] = { \
-+ .name = _name, \
-+ .flags = 0, \
-+ .max = ((_nparents) - 1) << JH7100_CLK_MUX_SHIFT, \
-+ .parents = { __VA_ARGS__ }, \
-+}
-+
-+#define JH7100_GMUX(_idx, _name, _flags, _nparents, ...) [_idx] = { \
-+ .name = _name, \
-+ .flags = _flags, \
-+ .max = JH7100_CLK_ENABLE | \
-+ (((_nparents) - 1) << JH7100_CLK_MUX_SHIFT), \
-+ .parents = { __VA_ARGS__ }, \
-+}
-+
-+#define JH7100_MDIV(_idx, _name, _max, _nparents, ...) [_idx] = { \
-+ .name = _name, \
-+ .flags = 0, \
-+ .max = (((_nparents) - 1) << JH7100_CLK_MUX_SHIFT) | (_max), \
-+ .parents = { __VA_ARGS__ }, \
-+}
-+
-+#define JH7100__GMD(_idx, _name, _flags, _max, _nparents, ...) [_idx] = { \
-+ .name = _name, \
-+ .flags = _flags, \
-+ .max = JH7100_CLK_ENABLE | \
-+ (((_nparents) - 1) << JH7100_CLK_MUX_SHIFT) | (_max), \
-+ .parents = { __VA_ARGS__ }, \
-+}
-+
-+#define JH7100__INV(_idx, _name, _parent) [_idx] = { \
-+ .name = _name, \
-+ .flags = CLK_SET_RATE_PARENT, \
-+ .max = JH7100_CLK_INVERT, \
-+ .parents = { [0] = _parent }, \
-+}
-+
-+struct jh7100_clk {
-+ struct clk_hw hw;
-+ unsigned int idx;
-+ unsigned int max_div;
-+};
-+
-+struct jh7100_clk_priv {
-+ /* protect clk enable and set rate/parent from happening at the same time */
-+ spinlock_t rmw_lock;
-+ struct device *dev;
-+ void __iomem *base;
-+ struct clk_hw *pll[3];
-+ struct jh7100_clk reg[];
-+};
-+
-+const struct clk_ops *starfive_jh7100_clk_ops(u32 max);
-+
-+#endif
diff --git a/target/linux/starfive/patches-6.1/0006-clk-starfive-Rename-jh7100-to-jh71x0-for-the-common-.patch b/target/linux/starfive/patches-6.1/0006-clk-starfive-Rename-jh7100-to-jh71x0-for-the-common-.patch
deleted file mode 100644
index 60ebf2cc0a..0000000000
--- a/target/linux/starfive/patches-6.1/0006-clk-starfive-Rename-jh7100-to-jh71x0-for-the-common-.patch
+++ /dev/null
@@ -1,1249 +0,0 @@
-From 674fa25b207e4bef6c27af2acfbca3a0d765a45b Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Sat, 1 Apr 2023 19:19:18 +0800
-Subject: [PATCH 006/122] clk: starfive: Rename "jh7100" to "jh71x0" for the
- common code
-
-Rename some variables from "jh7100" or "JH7100" to "jh71x0"
-or "JH71X0".
-
-Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
-Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
-Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
-Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
----
- .../clk/starfive/clk-starfive-jh7100-audio.c | 72 ++--
- drivers/clk/starfive/clk-starfive-jh7100.c | 389 +++++++++---------
- drivers/clk/starfive/clk-starfive-jh71x0.c | 282 ++++++-------
- drivers/clk/starfive/clk-starfive-jh71x0.h | 81 ++--
- 4 files changed, 418 insertions(+), 406 deletions(-)
-
---- a/drivers/clk/starfive/clk-starfive-jh7100-audio.c
-+++ b/drivers/clk/starfive/clk-starfive-jh7100-audio.c
-@@ -28,66 +28,66 @@
- #define JH7100_AUDCLK_I2SDAC_LRCLK_IOPAD (JH7100_AUDCLK_END + 6)
- #define JH7100_AUDCLK_VAD_INTMEM (JH7100_AUDCLK_END + 7)
-
--static const struct jh7100_clk_data jh7100_audclk_data[] = {
-- JH7100__GMD(JH7100_AUDCLK_ADC_MCLK, "adc_mclk", 0, 15, 2,
-+static const struct jh71x0_clk_data jh7100_audclk_data[] = {
-+ JH71X0__GMD(JH7100_AUDCLK_ADC_MCLK, "adc_mclk", 0, 15, 2,
- JH7100_AUDCLK_AUDIO_SRC,
- JH7100_AUDCLK_AUDIO_12288),
-- JH7100__GMD(JH7100_AUDCLK_I2S1_MCLK, "i2s1_mclk", 0, 15, 2,
-+ JH71X0__GMD(JH7100_AUDCLK_I2S1_MCLK, "i2s1_mclk", 0, 15, 2,
- JH7100_AUDCLK_AUDIO_SRC,
- JH7100_AUDCLK_AUDIO_12288),
-- JH7100_GATE(JH7100_AUDCLK_I2SADC_APB, "i2sadc_apb", 0, JH7100_AUDCLK_APB0_BUS),
-- JH7100_MDIV(JH7100_AUDCLK_I2SADC_BCLK, "i2sadc_bclk", 31, 2,
-+ JH71X0_GATE(JH7100_AUDCLK_I2SADC_APB, "i2sadc_apb", 0, JH7100_AUDCLK_APB0_BUS),
-+ JH71X0_MDIV(JH7100_AUDCLK_I2SADC_BCLK, "i2sadc_bclk", 31, 2,
- JH7100_AUDCLK_ADC_MCLK,
- JH7100_AUDCLK_I2SADC_BCLK_IOPAD),
-- JH7100__INV(JH7100_AUDCLK_I2SADC_BCLK_N, "i2sadc_bclk_n", JH7100_AUDCLK_I2SADC_BCLK),
-- JH7100_MDIV(JH7100_AUDCLK_I2SADC_LRCLK, "i2sadc_lrclk", 63, 3,
-+ JH71X0__INV(JH7100_AUDCLK_I2SADC_BCLK_N, "i2sadc_bclk_n", JH7100_AUDCLK_I2SADC_BCLK),
-+ JH71X0_MDIV(JH7100_AUDCLK_I2SADC_LRCLK, "i2sadc_lrclk", 63, 3,
- JH7100_AUDCLK_I2SADC_BCLK_N,
- JH7100_AUDCLK_I2SADC_LRCLK_IOPAD,
- JH7100_AUDCLK_I2SADC_BCLK),
-- JH7100_GATE(JH7100_AUDCLK_PDM_APB, "pdm_apb", 0, JH7100_AUDCLK_APB0_BUS),
-- JH7100__GMD(JH7100_AUDCLK_PDM_MCLK, "pdm_mclk", 0, 15, 2,
-+ JH71X0_GATE(JH7100_AUDCLK_PDM_APB, "pdm_apb", 0, JH7100_AUDCLK_APB0_BUS),
-+ JH71X0__GMD(JH7100_AUDCLK_PDM_MCLK, "pdm_mclk", 0, 15, 2,
- JH7100_AUDCLK_AUDIO_SRC,
- JH7100_AUDCLK_AUDIO_12288),
-- JH7100_GATE(JH7100_AUDCLK_I2SVAD_APB, "i2svad_apb", 0, JH7100_AUDCLK_APB0_BUS),
-- JH7100__GMD(JH7100_AUDCLK_SPDIF, "spdif", 0, 15, 2,
-+ JH71X0_GATE(JH7100_AUDCLK_I2SVAD_APB, "i2svad_apb", 0, JH7100_AUDCLK_APB0_BUS),
-+ JH71X0__GMD(JH7100_AUDCLK_SPDIF, "spdif", 0, 15, 2,
- JH7100_AUDCLK_AUDIO_SRC,
- JH7100_AUDCLK_AUDIO_12288),
-- JH7100_GATE(JH7100_AUDCLK_SPDIF_APB, "spdif_apb", 0, JH7100_AUDCLK_APB0_BUS),
-- JH7100_GATE(JH7100_AUDCLK_PWMDAC_APB, "pwmdac_apb", 0, JH7100_AUDCLK_APB0_BUS),
-- JH7100__GMD(JH7100_AUDCLK_DAC_MCLK, "dac_mclk", 0, 15, 2,
-+ JH71X0_GATE(JH7100_AUDCLK_SPDIF_APB, "spdif_apb", 0, JH7100_AUDCLK_APB0_BUS),
-+ JH71X0_GATE(JH7100_AUDCLK_PWMDAC_APB, "pwmdac_apb", 0, JH7100_AUDCLK_APB0_BUS),
-+ JH71X0__GMD(JH7100_AUDCLK_DAC_MCLK, "dac_mclk", 0, 15, 2,
- JH7100_AUDCLK_AUDIO_SRC,
- JH7100_AUDCLK_AUDIO_12288),
-- JH7100_GATE(JH7100_AUDCLK_I2SDAC_APB, "i2sdac_apb", 0, JH7100_AUDCLK_APB0_BUS),
-- JH7100_MDIV(JH7100_AUDCLK_I2SDAC_BCLK, "i2sdac_bclk", 31, 2,
-+ JH71X0_GATE(JH7100_AUDCLK_I2SDAC_APB, "i2sdac_apb", 0, JH7100_AUDCLK_APB0_BUS),
-+ JH71X0_MDIV(JH7100_AUDCLK_I2SDAC_BCLK, "i2sdac_bclk", 31, 2,
- JH7100_AUDCLK_DAC_MCLK,
- JH7100_AUDCLK_I2SDAC_BCLK_IOPAD),
-- JH7100__INV(JH7100_AUDCLK_I2SDAC_BCLK_N, "i2sdac_bclk_n", JH7100_AUDCLK_I2SDAC_BCLK),
-- JH7100_MDIV(JH7100_AUDCLK_I2SDAC_LRCLK, "i2sdac_lrclk", 31, 2,
-+ JH71X0__INV(JH7100_AUDCLK_I2SDAC_BCLK_N, "i2sdac_bclk_n", JH7100_AUDCLK_I2SDAC_BCLK),
-+ JH71X0_MDIV(JH7100_AUDCLK_I2SDAC_LRCLK, "i2sdac_lrclk", 31, 2,
- JH7100_AUDCLK_I2S1_MCLK,
- JH7100_AUDCLK_I2SDAC_BCLK_IOPAD),
-- JH7100_GATE(JH7100_AUDCLK_I2S1_APB, "i2s1_apb", 0, JH7100_AUDCLK_APB0_BUS),
-- JH7100_MDIV(JH7100_AUDCLK_I2S1_BCLK, "i2s1_bclk", 31, 2,
-+ JH71X0_GATE(JH7100_AUDCLK_I2S1_APB, "i2s1_apb", 0, JH7100_AUDCLK_APB0_BUS),
-+ JH71X0_MDIV(JH7100_AUDCLK_I2S1_BCLK, "i2s1_bclk", 31, 2,
- JH7100_AUDCLK_I2S1_MCLK,
- JH7100_AUDCLK_I2SDAC_BCLK_IOPAD),
-- JH7100__INV(JH7100_AUDCLK_I2S1_BCLK_N, "i2s1_bclk_n", JH7100_AUDCLK_I2S1_BCLK),
-- JH7100_MDIV(JH7100_AUDCLK_I2S1_LRCLK, "i2s1_lrclk", 63, 3,
-+ JH71X0__INV(JH7100_AUDCLK_I2S1_BCLK_N, "i2s1_bclk_n", JH7100_AUDCLK_I2S1_BCLK),
-+ JH71X0_MDIV(JH7100_AUDCLK_I2S1_LRCLK, "i2s1_lrclk", 63, 3,
- JH7100_AUDCLK_I2S1_BCLK_N,
- JH7100_AUDCLK_I2SDAC_LRCLK_IOPAD),
-- JH7100_GATE(JH7100_AUDCLK_I2SDAC16K_APB, "i2s1dac16k_apb", 0, JH7100_AUDCLK_APB0_BUS),
-- JH7100__DIV(JH7100_AUDCLK_APB0_BUS, "apb0_bus", 8, JH7100_AUDCLK_DOM7AHB_BUS),
-- JH7100_GATE(JH7100_AUDCLK_DMA1P_AHB, "dma1p_ahb", 0, JH7100_AUDCLK_DOM7AHB_BUS),
-- JH7100_GATE(JH7100_AUDCLK_USB_APB, "usb_apb", CLK_IGNORE_UNUSED, JH7100_AUDCLK_APB_EN),
-- JH7100_GDIV(JH7100_AUDCLK_USB_LPM, "usb_lpm", CLK_IGNORE_UNUSED, 4, JH7100_AUDCLK_USB_APB),
-- JH7100_GDIV(JH7100_AUDCLK_USB_STB, "usb_stb", CLK_IGNORE_UNUSED, 3, JH7100_AUDCLK_USB_APB),
-- JH7100__DIV(JH7100_AUDCLK_APB_EN, "apb_en", 8, JH7100_AUDCLK_DOM7AHB_BUS),
-- JH7100__MUX(JH7100_AUDCLK_VAD_MEM, "vad_mem", 2,
-+ JH71X0_GATE(JH7100_AUDCLK_I2SDAC16K_APB, "i2s1dac16k_apb", 0, JH7100_AUDCLK_APB0_BUS),
-+ JH71X0__DIV(JH7100_AUDCLK_APB0_BUS, "apb0_bus", 8, JH7100_AUDCLK_DOM7AHB_BUS),
-+ JH71X0_GATE(JH7100_AUDCLK_DMA1P_AHB, "dma1p_ahb", 0, JH7100_AUDCLK_DOM7AHB_BUS),
-+ JH71X0_GATE(JH7100_AUDCLK_USB_APB, "usb_apb", CLK_IGNORE_UNUSED, JH7100_AUDCLK_APB_EN),
-+ JH71X0_GDIV(JH7100_AUDCLK_USB_LPM, "usb_lpm", CLK_IGNORE_UNUSED, 4, JH7100_AUDCLK_USB_APB),
-+ JH71X0_GDIV(JH7100_AUDCLK_USB_STB, "usb_stb", CLK_IGNORE_UNUSED, 3, JH7100_AUDCLK_USB_APB),
-+ JH71X0__DIV(JH7100_AUDCLK_APB_EN, "apb_en", 8, JH7100_AUDCLK_DOM7AHB_BUS),
-+ JH71X0__MUX(JH7100_AUDCLK_VAD_MEM, "vad_mem", 2,
- JH7100_AUDCLK_VAD_INTMEM,
- JH7100_AUDCLK_AUDIO_12288),
- };
-
- static struct clk_hw *jh7100_audclk_get(struct of_phandle_args *clkspec, void *data)
- {
-- struct jh7100_clk_priv *priv = data;
-+ struct jh71x0_clk_priv *priv = data;
- unsigned int idx = clkspec->args[0];
-
- if (idx < JH7100_AUDCLK_END)
-@@ -98,7 +98,7 @@ static struct clk_hw *jh7100_audclk_get(
-
- static int jh7100_audclk_probe(struct platform_device *pdev)
- {
-- struct jh7100_clk_priv *priv;
-+ struct jh71x0_clk_priv *priv;
- unsigned int idx;
- int ret;
-
-@@ -117,12 +117,12 @@ static int jh7100_audclk_probe(struct pl
- struct clk_parent_data parents[4] = {};
- struct clk_init_data init = {
- .name = jh7100_audclk_data[idx].name,
-- .ops = starfive_jh7100_clk_ops(max),
-+ .ops = starfive_jh71x0_clk_ops(max),
- .parent_data = parents,
-- .num_parents = ((max & JH7100_CLK_MUX_MASK) >> JH7100_CLK_MUX_SHIFT) + 1,
-+ .num_parents = ((max & JH71X0_CLK_MUX_MASK) >> JH71X0_CLK_MUX_SHIFT) + 1,
- .flags = jh7100_audclk_data[idx].flags,
- };
-- struct jh7100_clk *clk = &priv->reg[idx];
-+ struct jh71x0_clk *clk = &priv->reg[idx];
- unsigned int i;
-
- for (i = 0; i < init.num_parents; i++) {
-@@ -140,7 +140,7 @@ static int jh7100_audclk_probe(struct pl
-
- clk->hw.init = &init;
- clk->idx = idx;
-- clk->max_div = max & JH7100_CLK_DIV_MASK;
-+ clk->max_div = max & JH71X0_CLK_DIV_MASK;
-
- ret = devm_clk_hw_register(priv->dev, &clk->hw);
- if (ret)
---- a/drivers/clk/starfive/clk-starfive-jh7100.c
-+++ b/drivers/clk/starfive/clk-starfive-jh7100.c
-@@ -23,250 +23,253 @@
- #define JH7100_CLK_GMAC_RMII_REF (JH7100_CLK_END + 2)
- #define JH7100_CLK_GMAC_GR_MII_RX (JH7100_CLK_END + 3)
-
--static const struct jh7100_clk_data jh7100_clk_data[] __initconst = {
-- JH7100__MUX(JH7100_CLK_CPUNDBUS_ROOT, "cpundbus_root", 4,
-+static const struct jh71x0_clk_data jh7100_clk_data[] __initconst = {
-+ JH71X0__MUX(JH7100_CLK_CPUNDBUS_ROOT, "cpundbus_root", 4,
- JH7100_CLK_OSC_SYS,
- JH7100_CLK_PLL0_OUT,
- JH7100_CLK_PLL1_OUT,
- JH7100_CLK_PLL2_OUT),
-- JH7100__MUX(JH7100_CLK_DLA_ROOT, "dla_root", 3,
-+ JH71X0__MUX(JH7100_CLK_DLA_ROOT, "dla_root", 3,
- JH7100_CLK_OSC_SYS,
- JH7100_CLK_PLL1_OUT,
- JH7100_CLK_PLL2_OUT),
-- JH7100__MUX(JH7100_CLK_DSP_ROOT, "dsp_root", 4,
-+ JH71X0__MUX(JH7100_CLK_DSP_ROOT, "dsp_root", 4,
- JH7100_CLK_OSC_SYS,
- JH7100_CLK_PLL0_OUT,
- JH7100_CLK_PLL1_OUT,
- JH7100_CLK_PLL2_OUT),
-- JH7100__MUX(JH7100_CLK_GMACUSB_ROOT, "gmacusb_root", 3,
-+ JH71X0__MUX(JH7100_CLK_GMACUSB_ROOT, "gmacusb_root", 3,
- JH7100_CLK_OSC_SYS,
- JH7100_CLK_PLL0_OUT,
- JH7100_CLK_PLL2_OUT),
-- JH7100__MUX(JH7100_CLK_PERH0_ROOT, "perh0_root", 2,
-+ JH71X0__MUX(JH7100_CLK_PERH0_ROOT, "perh0_root", 2,
- JH7100_CLK_OSC_SYS,
- JH7100_CLK_PLL0_OUT),
-- JH7100__MUX(JH7100_CLK_PERH1_ROOT, "perh1_root", 2,
-+ JH71X0__MUX(JH7100_CLK_PERH1_ROOT, "perh1_root", 2,
- JH7100_CLK_OSC_SYS,
- JH7100_CLK_PLL2_OUT),
-- JH7100__MUX(JH7100_CLK_VIN_ROOT, "vin_root", 3,
-+ JH71X0__MUX(JH7100_CLK_VIN_ROOT, "vin_root", 3,
- JH7100_CLK_OSC_SYS,
- JH7100_CLK_PLL1_OUT,
- JH7100_CLK_PLL2_OUT),
-- JH7100__MUX(JH7100_CLK_VOUT_ROOT, "vout_root", 3,
-+ JH71X0__MUX(JH7100_CLK_VOUT_ROOT, "vout_root", 3,
- JH7100_CLK_OSC_AUD,
- JH7100_CLK_PLL0_OUT,
- JH7100_CLK_PLL2_OUT),
-- JH7100_GDIV(JH7100_CLK_AUDIO_ROOT, "audio_root", 0, 8, JH7100_CLK_PLL0_OUT),
-- JH7100__MUX(JH7100_CLK_CDECHIFI4_ROOT, "cdechifi4_root", 3,
-+ JH71X0_GDIV(JH7100_CLK_AUDIO_ROOT, "audio_root", 0, 8, JH7100_CLK_PLL0_OUT),
-+ JH71X0__MUX(JH7100_CLK_CDECHIFI4_ROOT, "cdechifi4_root", 3,
- JH7100_CLK_OSC_SYS,
- JH7100_CLK_PLL1_OUT,
- JH7100_CLK_PLL2_OUT),
-- JH7100__MUX(JH7100_CLK_CDEC_ROOT, "cdec_root", 3,
-+ JH71X0__MUX(JH7100_CLK_CDEC_ROOT, "cdec_root", 3,
- JH7100_CLK_OSC_SYS,
- JH7100_CLK_PLL0_OUT,
- JH7100_CLK_PLL1_OUT),
-- JH7100__MUX(JH7100_CLK_VOUTBUS_ROOT, "voutbus_root", 3,
-+ JH71X0__MUX(JH7100_CLK_VOUTBUS_ROOT, "voutbus_root", 3,
- JH7100_CLK_OSC_AUD,
- JH7100_CLK_PLL0_OUT,
- JH7100_CLK_PLL2_OUT),
-- JH7100__DIV(JH7100_CLK_CPUNBUS_ROOT_DIV, "cpunbus_root_div", 2, JH7100_CLK_CPUNDBUS_ROOT),
-- JH7100__DIV(JH7100_CLK_DSP_ROOT_DIV, "dsp_root_div", 4, JH7100_CLK_DSP_ROOT),
-- JH7100__DIV(JH7100_CLK_PERH0_SRC, "perh0_src", 4, JH7100_CLK_PERH0_ROOT),
-- JH7100__DIV(JH7100_CLK_PERH1_SRC, "perh1_src", 4, JH7100_CLK_PERH1_ROOT),
-- JH7100_GDIV(JH7100_CLK_PLL0_TESTOUT, "pll0_testout", 0, 31, JH7100_CLK_PERH0_SRC),
-- JH7100_GDIV(JH7100_CLK_PLL1_TESTOUT, "pll1_testout", 0, 31, JH7100_CLK_DLA_ROOT),
-- JH7100_GDIV(JH7100_CLK_PLL2_TESTOUT, "pll2_testout", 0, 31, JH7100_CLK_PERH1_SRC),
-- JH7100__MUX(JH7100_CLK_PLL2_REF, "pll2_refclk", 2,
-+ JH71X0__DIV(JH7100_CLK_CPUNBUS_ROOT_DIV, "cpunbus_root_div", 2, JH7100_CLK_CPUNDBUS_ROOT),
-+ JH71X0__DIV(JH7100_CLK_DSP_ROOT_DIV, "dsp_root_div", 4, JH7100_CLK_DSP_ROOT),
-+ JH71X0__DIV(JH7100_CLK_PERH0_SRC, "perh0_src", 4, JH7100_CLK_PERH0_ROOT),
-+ JH71X0__DIV(JH7100_CLK_PERH1_SRC, "perh1_src", 4, JH7100_CLK_PERH1_ROOT),
-+ JH71X0_GDIV(JH7100_CLK_PLL0_TESTOUT, "pll0_testout", 0, 31, JH7100_CLK_PERH0_SRC),
-+ JH71X0_GDIV(JH7100_CLK_PLL1_TESTOUT, "pll1_testout", 0, 31, JH7100_CLK_DLA_ROOT),
-+ JH71X0_GDIV(JH7100_CLK_PLL2_TESTOUT, "pll2_testout", 0, 31, JH7100_CLK_PERH1_SRC),
-+ JH71X0__MUX(JH7100_CLK_PLL2_REF, "pll2_refclk", 2,
- JH7100_CLK_OSC_SYS,
- JH7100_CLK_OSC_AUD),
-- JH7100__DIV(JH7100_CLK_CPU_CORE, "cpu_core", 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
-- JH7100__DIV(JH7100_CLK_CPU_AXI, "cpu_axi", 8, JH7100_CLK_CPU_CORE),
-- JH7100__DIV(JH7100_CLK_AHB_BUS, "ahb_bus", 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
-- JH7100__DIV(JH7100_CLK_APB1_BUS, "apb1_bus", 8, JH7100_CLK_AHB_BUS),
-- JH7100__DIV(JH7100_CLK_APB2_BUS, "apb2_bus", 8, JH7100_CLK_AHB_BUS),
-- JH7100_GATE(JH7100_CLK_DOM3AHB_BUS, "dom3ahb_bus", CLK_IS_CRITICAL, JH7100_CLK_AHB_BUS),
-- JH7100_GATE(JH7100_CLK_DOM7AHB_BUS, "dom7ahb_bus", CLK_IS_CRITICAL, JH7100_CLK_AHB_BUS),
-- JH7100_GATE(JH7100_CLK_U74_CORE0, "u74_core0", CLK_IS_CRITICAL, JH7100_CLK_CPU_CORE),
-- JH7100_GDIV(JH7100_CLK_U74_CORE1, "u74_core1", CLK_IS_CRITICAL, 8, JH7100_CLK_CPU_CORE),
-- JH7100_GATE(JH7100_CLK_U74_AXI, "u74_axi", CLK_IS_CRITICAL, JH7100_CLK_CPU_AXI),
-- JH7100_GATE(JH7100_CLK_U74RTC_TOGGLE, "u74rtc_toggle", CLK_IS_CRITICAL, JH7100_CLK_OSC_SYS),
-- JH7100_GATE(JH7100_CLK_SGDMA2P_AXI, "sgdma2p_axi", 0, JH7100_CLK_CPU_AXI),
-- JH7100_GATE(JH7100_CLK_DMA2PNOC_AXI, "dma2pnoc_axi", 0, JH7100_CLK_CPU_AXI),
-- JH7100_GATE(JH7100_CLK_SGDMA2P_AHB, "sgdma2p_ahb", 0, JH7100_CLK_AHB_BUS),
-- JH7100__DIV(JH7100_CLK_DLA_BUS, "dla_bus", 4, JH7100_CLK_DLA_ROOT),
-- JH7100_GATE(JH7100_CLK_DLA_AXI, "dla_axi", 0, JH7100_CLK_DLA_BUS),
-- JH7100_GATE(JH7100_CLK_DLANOC_AXI, "dlanoc_axi", 0, JH7100_CLK_DLA_BUS),
-- JH7100_GATE(JH7100_CLK_DLA_APB, "dla_apb", 0, JH7100_CLK_APB1_BUS),
-- JH7100_GDIV(JH7100_CLK_VP6_CORE, "vp6_core", 0, 4, JH7100_CLK_DSP_ROOT_DIV),
-- JH7100__DIV(JH7100_CLK_VP6BUS_SRC, "vp6bus_src", 4, JH7100_CLK_DSP_ROOT),
-- JH7100_GDIV(JH7100_CLK_VP6_AXI, "vp6_axi", 0, 4, JH7100_CLK_VP6BUS_SRC),
-- JH7100__DIV(JH7100_CLK_VCDECBUS_SRC, "vcdecbus_src", 4, JH7100_CLK_CDECHIFI4_ROOT),
-- JH7100__DIV(JH7100_CLK_VDEC_BUS, "vdec_bus", 8, JH7100_CLK_VCDECBUS_SRC),
-- JH7100_GATE(JH7100_CLK_VDEC_AXI, "vdec_axi", 0, JH7100_CLK_VDEC_BUS),
-- JH7100_GATE(JH7100_CLK_VDECBRG_MAIN, "vdecbrg_mainclk", 0, JH7100_CLK_VDEC_BUS),
-- JH7100_GDIV(JH7100_CLK_VDEC_BCLK, "vdec_bclk", 0, 8, JH7100_CLK_VCDECBUS_SRC),
-- JH7100_GDIV(JH7100_CLK_VDEC_CCLK, "vdec_cclk", 0, 8, JH7100_CLK_CDEC_ROOT),
-- JH7100_GATE(JH7100_CLK_VDEC_APB, "vdec_apb", 0, JH7100_CLK_APB1_BUS),
-- JH7100_GDIV(JH7100_CLK_JPEG_AXI, "jpeg_axi", 0, 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
-- JH7100_GDIV(JH7100_CLK_JPEG_CCLK, "jpeg_cclk", 0, 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
-- JH7100_GATE(JH7100_CLK_JPEG_APB, "jpeg_apb", 0, JH7100_CLK_APB1_BUS),
-- JH7100_GDIV(JH7100_CLK_GC300_2X, "gc300_2x", 0, 8, JH7100_CLK_CDECHIFI4_ROOT),
-- JH7100_GATE(JH7100_CLK_GC300_AHB, "gc300_ahb", 0, JH7100_CLK_AHB_BUS),
-- JH7100__DIV(JH7100_CLK_JPCGC300_AXIBUS, "jpcgc300_axibus", 8, JH7100_CLK_VCDECBUS_SRC),
-- JH7100_GATE(JH7100_CLK_GC300_AXI, "gc300_axi", 0, JH7100_CLK_JPCGC300_AXIBUS),
-- JH7100_GATE(JH7100_CLK_JPCGC300_MAIN, "jpcgc300_mainclk", 0, JH7100_CLK_JPCGC300_AXIBUS),
-- JH7100__DIV(JH7100_CLK_VENC_BUS, "venc_bus", 8, JH7100_CLK_VCDECBUS_SRC),
-- JH7100_GATE(JH7100_CLK_VENC_AXI, "venc_axi", 0, JH7100_CLK_VENC_BUS),
-- JH7100_GATE(JH7100_CLK_VENCBRG_MAIN, "vencbrg_mainclk", 0, JH7100_CLK_VENC_BUS),
-- JH7100_GDIV(JH7100_CLK_VENC_BCLK, "venc_bclk", 0, 8, JH7100_CLK_VCDECBUS_SRC),
-- JH7100_GDIV(JH7100_CLK_VENC_CCLK, "venc_cclk", 0, 8, JH7100_CLK_CDEC_ROOT),
-- JH7100_GATE(JH7100_CLK_VENC_APB, "venc_apb", 0, JH7100_CLK_APB1_BUS),
-- JH7100_GDIV(JH7100_CLK_DDRPLL_DIV2, "ddrpll_div2", CLK_IS_CRITICAL, 2, JH7100_CLK_PLL1_OUT),
-- JH7100_GDIV(JH7100_CLK_DDRPLL_DIV4, "ddrpll_div4", CLK_IS_CRITICAL, 2, JH7100_CLK_DDRPLL_DIV2),
-- JH7100_GDIV(JH7100_CLK_DDRPLL_DIV8, "ddrpll_div8", CLK_IS_CRITICAL, 2, JH7100_CLK_DDRPLL_DIV4),
-- JH7100_GDIV(JH7100_CLK_DDROSC_DIV2, "ddrosc_div2", CLK_IS_CRITICAL, 2, JH7100_CLK_OSC_SYS),
-- JH7100_GMUX(JH7100_CLK_DDRC0, "ddrc0", CLK_IS_CRITICAL, 4,
-+ JH71X0__DIV(JH7100_CLK_CPU_CORE, "cpu_core", 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
-+ JH71X0__DIV(JH7100_CLK_CPU_AXI, "cpu_axi", 8, JH7100_CLK_CPU_CORE),
-+ JH71X0__DIV(JH7100_CLK_AHB_BUS, "ahb_bus", 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
-+ JH71X0__DIV(JH7100_CLK_APB1_BUS, "apb1_bus", 8, JH7100_CLK_AHB_BUS),
-+ JH71X0__DIV(JH7100_CLK_APB2_BUS, "apb2_bus", 8, JH7100_CLK_AHB_BUS),
-+ JH71X0_GATE(JH7100_CLK_DOM3AHB_BUS, "dom3ahb_bus", CLK_IS_CRITICAL, JH7100_CLK_AHB_BUS),
-+ JH71X0_GATE(JH7100_CLK_DOM7AHB_BUS, "dom7ahb_bus", CLK_IS_CRITICAL, JH7100_CLK_AHB_BUS),
-+ JH71X0_GATE(JH7100_CLK_U74_CORE0, "u74_core0", CLK_IS_CRITICAL, JH7100_CLK_CPU_CORE),
-+ JH71X0_GDIV(JH7100_CLK_U74_CORE1, "u74_core1", CLK_IS_CRITICAL, 8, JH7100_CLK_CPU_CORE),
-+ JH71X0_GATE(JH7100_CLK_U74_AXI, "u74_axi", CLK_IS_CRITICAL, JH7100_CLK_CPU_AXI),
-+ JH71X0_GATE(JH7100_CLK_U74RTC_TOGGLE, "u74rtc_toggle", CLK_IS_CRITICAL, JH7100_CLK_OSC_SYS),
-+ JH71X0_GATE(JH7100_CLK_SGDMA2P_AXI, "sgdma2p_axi", 0, JH7100_CLK_CPU_AXI),
-+ JH71X0_GATE(JH7100_CLK_DMA2PNOC_AXI, "dma2pnoc_axi", 0, JH7100_CLK_CPU_AXI),
-+ JH71X0_GATE(JH7100_CLK_SGDMA2P_AHB, "sgdma2p_ahb", 0, JH7100_CLK_AHB_BUS),
-+ JH71X0__DIV(JH7100_CLK_DLA_BUS, "dla_bus", 4, JH7100_CLK_DLA_ROOT),
-+ JH71X0_GATE(JH7100_CLK_DLA_AXI, "dla_axi", 0, JH7100_CLK_DLA_BUS),
-+ JH71X0_GATE(JH7100_CLK_DLANOC_AXI, "dlanoc_axi", 0, JH7100_CLK_DLA_BUS),
-+ JH71X0_GATE(JH7100_CLK_DLA_APB, "dla_apb", 0, JH7100_CLK_APB1_BUS),
-+ JH71X0_GDIV(JH7100_CLK_VP6_CORE, "vp6_core", 0, 4, JH7100_CLK_DSP_ROOT_DIV),
-+ JH71X0__DIV(JH7100_CLK_VP6BUS_SRC, "vp6bus_src", 4, JH7100_CLK_DSP_ROOT),
-+ JH71X0_GDIV(JH7100_CLK_VP6_AXI, "vp6_axi", 0, 4, JH7100_CLK_VP6BUS_SRC),
-+ JH71X0__DIV(JH7100_CLK_VCDECBUS_SRC, "vcdecbus_src", 4, JH7100_CLK_CDECHIFI4_ROOT),
-+ JH71X0__DIV(JH7100_CLK_VDEC_BUS, "vdec_bus", 8, JH7100_CLK_VCDECBUS_SRC),
-+ JH71X0_GATE(JH7100_CLK_VDEC_AXI, "vdec_axi", 0, JH7100_CLK_VDEC_BUS),
-+ JH71X0_GATE(JH7100_CLK_VDECBRG_MAIN, "vdecbrg_mainclk", 0, JH7100_CLK_VDEC_BUS),
-+ JH71X0_GDIV(JH7100_CLK_VDEC_BCLK, "vdec_bclk", 0, 8, JH7100_CLK_VCDECBUS_SRC),
-+ JH71X0_GDIV(JH7100_CLK_VDEC_CCLK, "vdec_cclk", 0, 8, JH7100_CLK_CDEC_ROOT),
-+ JH71X0_GATE(JH7100_CLK_VDEC_APB, "vdec_apb", 0, JH7100_CLK_APB1_BUS),
-+ JH71X0_GDIV(JH7100_CLK_JPEG_AXI, "jpeg_axi", 0, 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
-+ JH71X0_GDIV(JH7100_CLK_JPEG_CCLK, "jpeg_cclk", 0, 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
-+ JH71X0_GATE(JH7100_CLK_JPEG_APB, "jpeg_apb", 0, JH7100_CLK_APB1_BUS),
-+ JH71X0_GDIV(JH7100_CLK_GC300_2X, "gc300_2x", 0, 8, JH7100_CLK_CDECHIFI4_ROOT),
-+ JH71X0_GATE(JH7100_CLK_GC300_AHB, "gc300_ahb", 0, JH7100_CLK_AHB_BUS),
-+ JH71X0__DIV(JH7100_CLK_JPCGC300_AXIBUS, "jpcgc300_axibus", 8, JH7100_CLK_VCDECBUS_SRC),
-+ JH71X0_GATE(JH7100_CLK_GC300_AXI, "gc300_axi", 0, JH7100_CLK_JPCGC300_AXIBUS),
-+ JH71X0_GATE(JH7100_CLK_JPCGC300_MAIN, "jpcgc300_mainclk", 0, JH7100_CLK_JPCGC300_AXIBUS),
-+ JH71X0__DIV(JH7100_CLK_VENC_BUS, "venc_bus", 8, JH7100_CLK_VCDECBUS_SRC),
-+ JH71X0_GATE(JH7100_CLK_VENC_AXI, "venc_axi", 0, JH7100_CLK_VENC_BUS),
-+ JH71X0_GATE(JH7100_CLK_VENCBRG_MAIN, "vencbrg_mainclk", 0, JH7100_CLK_VENC_BUS),
-+ JH71X0_GDIV(JH7100_CLK_VENC_BCLK, "venc_bclk", 0, 8, JH7100_CLK_VCDECBUS_SRC),
-+ JH71X0_GDIV(JH7100_CLK_VENC_CCLK, "venc_cclk", 0, 8, JH7100_CLK_CDEC_ROOT),
-+ JH71X0_GATE(JH7100_CLK_VENC_APB, "venc_apb", 0, JH7100_CLK_APB1_BUS),
-+ JH71X0_GDIV(JH7100_CLK_DDRPLL_DIV2, "ddrpll_div2", CLK_IS_CRITICAL, 2, JH7100_CLK_PLL1_OUT),
-+ JH71X0_GDIV(JH7100_CLK_DDRPLL_DIV4, "ddrpll_div4", CLK_IS_CRITICAL, 2,
-+ JH7100_CLK_DDRPLL_DIV2),
-+ JH71X0_GDIV(JH7100_CLK_DDRPLL_DIV8, "ddrpll_div8", CLK_IS_CRITICAL, 2,
-+ JH7100_CLK_DDRPLL_DIV4),
-+ JH71X0_GDIV(JH7100_CLK_DDROSC_DIV2, "ddrosc_div2", CLK_IS_CRITICAL, 2, JH7100_CLK_OSC_SYS),
-+ JH71X0_GMUX(JH7100_CLK_DDRC0, "ddrc0", CLK_IS_CRITICAL, 4,
- JH7100_CLK_DDROSC_DIV2,
- JH7100_CLK_DDRPLL_DIV2,
- JH7100_CLK_DDRPLL_DIV4,
- JH7100_CLK_DDRPLL_DIV8),
-- JH7100_GMUX(JH7100_CLK_DDRC1, "ddrc1", CLK_IS_CRITICAL, 4,
-+ JH71X0_GMUX(JH7100_CLK_DDRC1, "ddrc1", CLK_IS_CRITICAL, 4,
- JH7100_CLK_DDROSC_DIV2,
- JH7100_CLK_DDRPLL_DIV2,
- JH7100_CLK_DDRPLL_DIV4,
- JH7100_CLK_DDRPLL_DIV8),
-- JH7100_GATE(JH7100_CLK_DDRPHY_APB, "ddrphy_apb", 0, JH7100_CLK_APB1_BUS),
-- JH7100__DIV(JH7100_CLK_NOC_ROB, "noc_rob", 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
-- JH7100__DIV(JH7100_CLK_NOC_COG, "noc_cog", 8, JH7100_CLK_DLA_ROOT),
-- JH7100_GATE(JH7100_CLK_NNE_AHB, "nne_ahb", 0, JH7100_CLK_AHB_BUS),
-- JH7100__DIV(JH7100_CLK_NNEBUS_SRC1, "nnebus_src1", 4, JH7100_CLK_DSP_ROOT),
-- JH7100__MUX(JH7100_CLK_NNE_BUS, "nne_bus", 2,
-+ JH71X0_GATE(JH7100_CLK_DDRPHY_APB, "ddrphy_apb", 0, JH7100_CLK_APB1_BUS),
-+ JH71X0__DIV(JH7100_CLK_NOC_ROB, "noc_rob", 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
-+ JH71X0__DIV(JH7100_CLK_NOC_COG, "noc_cog", 8, JH7100_CLK_DLA_ROOT),
-+ JH71X0_GATE(JH7100_CLK_NNE_AHB, "nne_ahb", 0, JH7100_CLK_AHB_BUS),
-+ JH71X0__DIV(JH7100_CLK_NNEBUS_SRC1, "nnebus_src1", 4, JH7100_CLK_DSP_ROOT),
-+ JH71X0__MUX(JH7100_CLK_NNE_BUS, "nne_bus", 2,
- JH7100_CLK_CPU_AXI,
- JH7100_CLK_NNEBUS_SRC1),
-- JH7100_GATE(JH7100_CLK_NNE_AXI, "nne_axi", 0, JH7100_CLK_NNE_BUS),
-- JH7100_GATE(JH7100_CLK_NNENOC_AXI, "nnenoc_axi", 0, JH7100_CLK_NNE_BUS),
-- JH7100_GATE(JH7100_CLK_DLASLV_AXI, "dlaslv_axi", 0, JH7100_CLK_NNE_BUS),
-- JH7100_GATE(JH7100_CLK_DSPX2C_AXI, "dspx2c_axi", CLK_IS_CRITICAL, JH7100_CLK_NNE_BUS),
-- JH7100__DIV(JH7100_CLK_HIFI4_SRC, "hifi4_src", 4, JH7100_CLK_CDECHIFI4_ROOT),
-- JH7100__DIV(JH7100_CLK_HIFI4_COREFREE, "hifi4_corefree", 8, JH7100_CLK_HIFI4_SRC),
-- JH7100_GATE(JH7100_CLK_HIFI4_CORE, "hifi4_core", 0, JH7100_CLK_HIFI4_COREFREE),
-- JH7100__DIV(JH7100_CLK_HIFI4_BUS, "hifi4_bus", 8, JH7100_CLK_HIFI4_COREFREE),
-- JH7100_GATE(JH7100_CLK_HIFI4_AXI, "hifi4_axi", 0, JH7100_CLK_HIFI4_BUS),
-- JH7100_GATE(JH7100_CLK_HIFI4NOC_AXI, "hifi4noc_axi", 0, JH7100_CLK_HIFI4_BUS),
-- JH7100__DIV(JH7100_CLK_SGDMA1P_BUS, "sgdma1p_bus", 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
-- JH7100_GATE(JH7100_CLK_SGDMA1P_AXI, "sgdma1p_axi", 0, JH7100_CLK_SGDMA1P_BUS),
-- JH7100_GATE(JH7100_CLK_DMA1P_AXI, "dma1p_axi", 0, JH7100_CLK_SGDMA1P_BUS),
-- JH7100_GDIV(JH7100_CLK_X2C_AXI, "x2c_axi", CLK_IS_CRITICAL, 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
-- JH7100__DIV(JH7100_CLK_USB_BUS, "usb_bus", 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
-- JH7100_GATE(JH7100_CLK_USB_AXI, "usb_axi", 0, JH7100_CLK_USB_BUS),
-- JH7100_GATE(JH7100_CLK_USBNOC_AXI, "usbnoc_axi", 0, JH7100_CLK_USB_BUS),
-- JH7100__DIV(JH7100_CLK_USBPHY_ROOTDIV, "usbphy_rootdiv", 4, JH7100_CLK_GMACUSB_ROOT),
-- JH7100_GDIV(JH7100_CLK_USBPHY_125M, "usbphy_125m", 0, 8, JH7100_CLK_USBPHY_ROOTDIV),
-- JH7100_GDIV(JH7100_CLK_USBPHY_PLLDIV25M, "usbphy_plldiv25m", 0, 32, JH7100_CLK_USBPHY_ROOTDIV),
-- JH7100__MUX(JH7100_CLK_USBPHY_25M, "usbphy_25m", 2,
-+ JH71X0_GATE(JH7100_CLK_NNE_AXI, "nne_axi", 0, JH7100_CLK_NNE_BUS),
-+ JH71X0_GATE(JH7100_CLK_NNENOC_AXI, "nnenoc_axi", 0, JH7100_CLK_NNE_BUS),
-+ JH71X0_GATE(JH7100_CLK_DLASLV_AXI, "dlaslv_axi", 0, JH7100_CLK_NNE_BUS),
-+ JH71X0_GATE(JH7100_CLK_DSPX2C_AXI, "dspx2c_axi", CLK_IS_CRITICAL, JH7100_CLK_NNE_BUS),
-+ JH71X0__DIV(JH7100_CLK_HIFI4_SRC, "hifi4_src", 4, JH7100_CLK_CDECHIFI4_ROOT),
-+ JH71X0__DIV(JH7100_CLK_HIFI4_COREFREE, "hifi4_corefree", 8, JH7100_CLK_HIFI4_SRC),
-+ JH71X0_GATE(JH7100_CLK_HIFI4_CORE, "hifi4_core", 0, JH7100_CLK_HIFI4_COREFREE),
-+ JH71X0__DIV(JH7100_CLK_HIFI4_BUS, "hifi4_bus", 8, JH7100_CLK_HIFI4_COREFREE),
-+ JH71X0_GATE(JH7100_CLK_HIFI4_AXI, "hifi4_axi", 0, JH7100_CLK_HIFI4_BUS),
-+ JH71X0_GATE(JH7100_CLK_HIFI4NOC_AXI, "hifi4noc_axi", 0, JH7100_CLK_HIFI4_BUS),
-+ JH71X0__DIV(JH7100_CLK_SGDMA1P_BUS, "sgdma1p_bus", 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
-+ JH71X0_GATE(JH7100_CLK_SGDMA1P_AXI, "sgdma1p_axi", 0, JH7100_CLK_SGDMA1P_BUS),
-+ JH71X0_GATE(JH7100_CLK_DMA1P_AXI, "dma1p_axi", 0, JH7100_CLK_SGDMA1P_BUS),
-+ JH71X0_GDIV(JH7100_CLK_X2C_AXI, "x2c_axi", CLK_IS_CRITICAL, 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
-+ JH71X0__DIV(JH7100_CLK_USB_BUS, "usb_bus", 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
-+ JH71X0_GATE(JH7100_CLK_USB_AXI, "usb_axi", 0, JH7100_CLK_USB_BUS),
-+ JH71X0_GATE(JH7100_CLK_USBNOC_AXI, "usbnoc_axi", 0, JH7100_CLK_USB_BUS),
-+ JH71X0__DIV(JH7100_CLK_USBPHY_ROOTDIV, "usbphy_rootdiv", 4, JH7100_CLK_GMACUSB_ROOT),
-+ JH71X0_GDIV(JH7100_CLK_USBPHY_125M, "usbphy_125m", 0, 8, JH7100_CLK_USBPHY_ROOTDIV),
-+ JH71X0_GDIV(JH7100_CLK_USBPHY_PLLDIV25M, "usbphy_plldiv25m", 0, 32,
-+ JH7100_CLK_USBPHY_ROOTDIV),
-+ JH71X0__MUX(JH7100_CLK_USBPHY_25M, "usbphy_25m", 2,
- JH7100_CLK_OSC_SYS,
- JH7100_CLK_USBPHY_PLLDIV25M),
-- JH7100_FDIV(JH7100_CLK_AUDIO_DIV, "audio_div", JH7100_CLK_AUDIO_ROOT),
-- JH7100_GATE(JH7100_CLK_AUDIO_SRC, "audio_src", 0, JH7100_CLK_AUDIO_DIV),
-- JH7100_GATE(JH7100_CLK_AUDIO_12288, "audio_12288", 0, JH7100_CLK_OSC_AUD),
-- JH7100_GDIV(JH7100_CLK_VIN_SRC, "vin_src", 0, 4, JH7100_CLK_VIN_ROOT),
-- JH7100__DIV(JH7100_CLK_ISP0_BUS, "isp0_bus", 8, JH7100_CLK_VIN_SRC),
-- JH7100_GATE(JH7100_CLK_ISP0_AXI, "isp0_axi", 0, JH7100_CLK_ISP0_BUS),
-- JH7100_GATE(JH7100_CLK_ISP0NOC_AXI, "isp0noc_axi", 0, JH7100_CLK_ISP0_BUS),
-- JH7100_GATE(JH7100_CLK_ISPSLV_AXI, "ispslv_axi", 0, JH7100_CLK_ISP0_BUS),
-- JH7100__DIV(JH7100_CLK_ISP1_BUS, "isp1_bus", 8, JH7100_CLK_VIN_SRC),
-- JH7100_GATE(JH7100_CLK_ISP1_AXI, "isp1_axi", 0, JH7100_CLK_ISP1_BUS),
-- JH7100_GATE(JH7100_CLK_ISP1NOC_AXI, "isp1noc_axi", 0, JH7100_CLK_ISP1_BUS),
-- JH7100__DIV(JH7100_CLK_VIN_BUS, "vin_bus", 8, JH7100_CLK_VIN_SRC),
-- JH7100_GATE(JH7100_CLK_VIN_AXI, "vin_axi", 0, JH7100_CLK_VIN_BUS),
-- JH7100_GATE(JH7100_CLK_VINNOC_AXI, "vinnoc_axi", 0, JH7100_CLK_VIN_BUS),
-- JH7100_GDIV(JH7100_CLK_VOUT_SRC, "vout_src", 0, 4, JH7100_CLK_VOUT_ROOT),
-- JH7100__DIV(JH7100_CLK_DISPBUS_SRC, "dispbus_src", 4, JH7100_CLK_VOUTBUS_ROOT),
-- JH7100__DIV(JH7100_CLK_DISP_BUS, "disp_bus", 4, JH7100_CLK_DISPBUS_SRC),
-- JH7100_GATE(JH7100_CLK_DISP_AXI, "disp_axi", 0, JH7100_CLK_DISP_BUS),
-- JH7100_GATE(JH7100_CLK_DISPNOC_AXI, "dispnoc_axi", 0, JH7100_CLK_DISP_BUS),
-- JH7100_GATE(JH7100_CLK_SDIO0_AHB, "sdio0_ahb", 0, JH7100_CLK_AHB_BUS),
-- JH7100_GDIV(JH7100_CLK_SDIO0_CCLKINT, "sdio0_cclkint", 0, 24, JH7100_CLK_PERH0_SRC),
-- JH7100__INV(JH7100_CLK_SDIO0_CCLKINT_INV, "sdio0_cclkint_inv", JH7100_CLK_SDIO0_CCLKINT),
-- JH7100_GATE(JH7100_CLK_SDIO1_AHB, "sdio1_ahb", 0, JH7100_CLK_AHB_BUS),
-- JH7100_GDIV(JH7100_CLK_SDIO1_CCLKINT, "sdio1_cclkint", 0, 24, JH7100_CLK_PERH1_SRC),
-- JH7100__INV(JH7100_CLK_SDIO1_CCLKINT_INV, "sdio1_cclkint_inv", JH7100_CLK_SDIO1_CCLKINT),
-- JH7100_GATE(JH7100_CLK_GMAC_AHB, "gmac_ahb", 0, JH7100_CLK_AHB_BUS),
-- JH7100__DIV(JH7100_CLK_GMAC_ROOT_DIV, "gmac_root_div", 8, JH7100_CLK_GMACUSB_ROOT),
-- JH7100_GDIV(JH7100_CLK_GMAC_PTP_REF, "gmac_ptp_refclk", 0, 31, JH7100_CLK_GMAC_ROOT_DIV),
-- JH7100_GDIV(JH7100_CLK_GMAC_GTX, "gmac_gtxclk", 0, 255, JH7100_CLK_GMAC_ROOT_DIV),
-- JH7100_GDIV(JH7100_CLK_GMAC_RMII_TX, "gmac_rmii_txclk", 0, 8, JH7100_CLK_GMAC_RMII_REF),
-- JH7100_GDIV(JH7100_CLK_GMAC_RMII_RX, "gmac_rmii_rxclk", 0, 8, JH7100_CLK_GMAC_RMII_REF),
-- JH7100__MUX(JH7100_CLK_GMAC_TX, "gmac_tx", 3,
-+ JH71X0_FDIV(JH7100_CLK_AUDIO_DIV, "audio_div", JH7100_CLK_AUDIO_ROOT),
-+ JH71X0_GATE(JH7100_CLK_AUDIO_SRC, "audio_src", 0, JH7100_CLK_AUDIO_DIV),
-+ JH71X0_GATE(JH7100_CLK_AUDIO_12288, "audio_12288", 0, JH7100_CLK_OSC_AUD),
-+ JH71X0_GDIV(JH7100_CLK_VIN_SRC, "vin_src", 0, 4, JH7100_CLK_VIN_ROOT),
-+ JH71X0__DIV(JH7100_CLK_ISP0_BUS, "isp0_bus", 8, JH7100_CLK_VIN_SRC),
-+ JH71X0_GATE(JH7100_CLK_ISP0_AXI, "isp0_axi", 0, JH7100_CLK_ISP0_BUS),
-+ JH71X0_GATE(JH7100_CLK_ISP0NOC_AXI, "isp0noc_axi", 0, JH7100_CLK_ISP0_BUS),
-+ JH71X0_GATE(JH7100_CLK_ISPSLV_AXI, "ispslv_axi", 0, JH7100_CLK_ISP0_BUS),
-+ JH71X0__DIV(JH7100_CLK_ISP1_BUS, "isp1_bus", 8, JH7100_CLK_VIN_SRC),
-+ JH71X0_GATE(JH7100_CLK_ISP1_AXI, "isp1_axi", 0, JH7100_CLK_ISP1_BUS),
-+ JH71X0_GATE(JH7100_CLK_ISP1NOC_AXI, "isp1noc_axi", 0, JH7100_CLK_ISP1_BUS),
-+ JH71X0__DIV(JH7100_CLK_VIN_BUS, "vin_bus", 8, JH7100_CLK_VIN_SRC),
-+ JH71X0_GATE(JH7100_CLK_VIN_AXI, "vin_axi", 0, JH7100_CLK_VIN_BUS),
-+ JH71X0_GATE(JH7100_CLK_VINNOC_AXI, "vinnoc_axi", 0, JH7100_CLK_VIN_BUS),
-+ JH71X0_GDIV(JH7100_CLK_VOUT_SRC, "vout_src", 0, 4, JH7100_CLK_VOUT_ROOT),
-+ JH71X0__DIV(JH7100_CLK_DISPBUS_SRC, "dispbus_src", 4, JH7100_CLK_VOUTBUS_ROOT),
-+ JH71X0__DIV(JH7100_CLK_DISP_BUS, "disp_bus", 4, JH7100_CLK_DISPBUS_SRC),
-+ JH71X0_GATE(JH7100_CLK_DISP_AXI, "disp_axi", 0, JH7100_CLK_DISP_BUS),
-+ JH71X0_GATE(JH7100_CLK_DISPNOC_AXI, "dispnoc_axi", 0, JH7100_CLK_DISP_BUS),
-+ JH71X0_GATE(JH7100_CLK_SDIO0_AHB, "sdio0_ahb", 0, JH7100_CLK_AHB_BUS),
-+ JH71X0_GDIV(JH7100_CLK_SDIO0_CCLKINT, "sdio0_cclkint", 0, 24, JH7100_CLK_PERH0_SRC),
-+ JH71X0__INV(JH7100_CLK_SDIO0_CCLKINT_INV, "sdio0_cclkint_inv", JH7100_CLK_SDIO0_CCLKINT),
-+ JH71X0_GATE(JH7100_CLK_SDIO1_AHB, "sdio1_ahb", 0, JH7100_CLK_AHB_BUS),
-+ JH71X0_GDIV(JH7100_CLK_SDIO1_CCLKINT, "sdio1_cclkint", 0, 24, JH7100_CLK_PERH1_SRC),
-+ JH71X0__INV(JH7100_CLK_SDIO1_CCLKINT_INV, "sdio1_cclkint_inv", JH7100_CLK_SDIO1_CCLKINT),
-+ JH71X0_GATE(JH7100_CLK_GMAC_AHB, "gmac_ahb", 0, JH7100_CLK_AHB_BUS),
-+ JH71X0__DIV(JH7100_CLK_GMAC_ROOT_DIV, "gmac_root_div", 8, JH7100_CLK_GMACUSB_ROOT),
-+ JH71X0_GDIV(JH7100_CLK_GMAC_PTP_REF, "gmac_ptp_refclk", 0, 31, JH7100_CLK_GMAC_ROOT_DIV),
-+ JH71X0_GDIV(JH7100_CLK_GMAC_GTX, "gmac_gtxclk", 0, 255, JH7100_CLK_GMAC_ROOT_DIV),
-+ JH71X0_GDIV(JH7100_CLK_GMAC_RMII_TX, "gmac_rmii_txclk", 0, 8, JH7100_CLK_GMAC_RMII_REF),
-+ JH71X0_GDIV(JH7100_CLK_GMAC_RMII_RX, "gmac_rmii_rxclk", 0, 8, JH7100_CLK_GMAC_RMII_REF),
-+ JH71X0__MUX(JH7100_CLK_GMAC_TX, "gmac_tx", 3,
- JH7100_CLK_GMAC_GTX,
- JH7100_CLK_GMAC_TX_INV,
- JH7100_CLK_GMAC_RMII_TX),
-- JH7100__INV(JH7100_CLK_GMAC_TX_INV, "gmac_tx_inv", JH7100_CLK_GMAC_TX),
-- JH7100__MUX(JH7100_CLK_GMAC_RX_PRE, "gmac_rx_pre", 2,
-+ JH71X0__INV(JH7100_CLK_GMAC_TX_INV, "gmac_tx_inv", JH7100_CLK_GMAC_TX),
-+ JH71X0__MUX(JH7100_CLK_GMAC_RX_PRE, "gmac_rx_pre", 2,
- JH7100_CLK_GMAC_GR_MII_RX,
- JH7100_CLK_GMAC_RMII_RX),
-- JH7100__INV(JH7100_CLK_GMAC_RX_INV, "gmac_rx_inv", JH7100_CLK_GMAC_RX_PRE),
-- JH7100_GATE(JH7100_CLK_GMAC_RMII, "gmac_rmii", 0, JH7100_CLK_GMAC_RMII_REF),
-- JH7100_GDIV(JH7100_CLK_GMAC_TOPHYREF, "gmac_tophyref", 0, 127, JH7100_CLK_GMAC_ROOT_DIV),
-- JH7100_GATE(JH7100_CLK_SPI2AHB_AHB, "spi2ahb_ahb", 0, JH7100_CLK_AHB_BUS),
-- JH7100_GDIV(JH7100_CLK_SPI2AHB_CORE, "spi2ahb_core", 0, 31, JH7100_CLK_PERH0_SRC),
-- JH7100_GATE(JH7100_CLK_EZMASTER_AHB, "ezmaster_ahb", 0, JH7100_CLK_AHB_BUS),
-- JH7100_GATE(JH7100_CLK_E24_AHB, "e24_ahb", 0, JH7100_CLK_AHB_BUS),
-- JH7100_GATE(JH7100_CLK_E24RTC_TOGGLE, "e24rtc_toggle", 0, JH7100_CLK_OSC_SYS),
-- JH7100_GATE(JH7100_CLK_QSPI_AHB, "qspi_ahb", 0, JH7100_CLK_AHB_BUS),
-- JH7100_GATE(JH7100_CLK_QSPI_APB, "qspi_apb", 0, JH7100_CLK_APB1_BUS),
-- JH7100_GDIV(JH7100_CLK_QSPI_REF, "qspi_refclk", 0, 31, JH7100_CLK_PERH0_SRC),
-- JH7100_GATE(JH7100_CLK_SEC_AHB, "sec_ahb", 0, JH7100_CLK_AHB_BUS),
-- JH7100_GATE(JH7100_CLK_AES, "aes_clk", 0, JH7100_CLK_SEC_AHB),
-- JH7100_GATE(JH7100_CLK_SHA, "sha_clk", 0, JH7100_CLK_SEC_AHB),
-- JH7100_GATE(JH7100_CLK_PKA, "pka_clk", 0, JH7100_CLK_SEC_AHB),
-- JH7100_GATE(JH7100_CLK_TRNG_APB, "trng_apb", 0, JH7100_CLK_APB1_BUS),
-- JH7100_GATE(JH7100_CLK_OTP_APB, "otp_apb", 0, JH7100_CLK_APB1_BUS),
-- JH7100_GATE(JH7100_CLK_UART0_APB, "uart0_apb", 0, JH7100_CLK_APB1_BUS),
-- JH7100_GDIV(JH7100_CLK_UART0_CORE, "uart0_core", 0, 63, JH7100_CLK_PERH1_SRC),
-- JH7100_GATE(JH7100_CLK_UART1_APB, "uart1_apb", 0, JH7100_CLK_APB1_BUS),
-- JH7100_GDIV(JH7100_CLK_UART1_CORE, "uart1_core", 0, 63, JH7100_CLK_PERH1_SRC),
-- JH7100_GATE(JH7100_CLK_SPI0_APB, "spi0_apb", 0, JH7100_CLK_APB1_BUS),
-- JH7100_GDIV(JH7100_CLK_SPI0_CORE, "spi0_core", 0, 63, JH7100_CLK_PERH1_SRC),
-- JH7100_GATE(JH7100_CLK_SPI1_APB, "spi1_apb", 0, JH7100_CLK_APB1_BUS),
-- JH7100_GDIV(JH7100_CLK_SPI1_CORE, "spi1_core", 0, 63, JH7100_CLK_PERH1_SRC),
-- JH7100_GATE(JH7100_CLK_I2C0_APB, "i2c0_apb", 0, JH7100_CLK_APB1_BUS),
-- JH7100_GDIV(JH7100_CLK_I2C0_CORE, "i2c0_core", 0, 63, JH7100_CLK_PERH1_SRC),
-- JH7100_GATE(JH7100_CLK_I2C1_APB, "i2c1_apb", 0, JH7100_CLK_APB1_BUS),
-- JH7100_GDIV(JH7100_CLK_I2C1_CORE, "i2c1_core", 0, 63, JH7100_CLK_PERH1_SRC),
-- JH7100_GATE(JH7100_CLK_GPIO_APB, "gpio_apb", 0, JH7100_CLK_APB1_BUS),
-- JH7100_GATE(JH7100_CLK_UART2_APB, "uart2_apb", 0, JH7100_CLK_APB2_BUS),
-- JH7100_GDIV(JH7100_CLK_UART2_CORE, "uart2_core", 0, 63, JH7100_CLK_PERH0_SRC),
-- JH7100_GATE(JH7100_CLK_UART3_APB, "uart3_apb", 0, JH7100_CLK_APB2_BUS),
-- JH7100_GDIV(JH7100_CLK_UART3_CORE, "uart3_core", 0, 63, JH7100_CLK_PERH0_SRC),
-- JH7100_GATE(JH7100_CLK_SPI2_APB, "spi2_apb", 0, JH7100_CLK_APB2_BUS),
-- JH7100_GDIV(JH7100_CLK_SPI2_CORE, "spi2_core", 0, 63, JH7100_CLK_PERH0_SRC),
-- JH7100_GATE(JH7100_CLK_SPI3_APB, "spi3_apb", 0, JH7100_CLK_APB2_BUS),
-- JH7100_GDIV(JH7100_CLK_SPI3_CORE, "spi3_core", 0, 63, JH7100_CLK_PERH0_SRC),
-- JH7100_GATE(JH7100_CLK_I2C2_APB, "i2c2_apb", 0, JH7100_CLK_APB2_BUS),
-- JH7100_GDIV(JH7100_CLK_I2C2_CORE, "i2c2_core", 0, 63, JH7100_CLK_PERH0_SRC),
-- JH7100_GATE(JH7100_CLK_I2C3_APB, "i2c3_apb", 0, JH7100_CLK_APB2_BUS),
-- JH7100_GDIV(JH7100_CLK_I2C3_CORE, "i2c3_core", 0, 63, JH7100_CLK_PERH0_SRC),
-- JH7100_GATE(JH7100_CLK_WDTIMER_APB, "wdtimer_apb", 0, JH7100_CLK_APB2_BUS),
-- JH7100_GDIV(JH7100_CLK_WDT_CORE, "wdt_coreclk", 0, 63, JH7100_CLK_PERH0_SRC),
-- JH7100_GDIV(JH7100_CLK_TIMER0_CORE, "timer0_coreclk", 0, 63, JH7100_CLK_PERH0_SRC),
-- JH7100_GDIV(JH7100_CLK_TIMER1_CORE, "timer1_coreclk", 0, 63, JH7100_CLK_PERH0_SRC),
-- JH7100_GDIV(JH7100_CLK_TIMER2_CORE, "timer2_coreclk", 0, 63, JH7100_CLK_PERH0_SRC),
-- JH7100_GDIV(JH7100_CLK_TIMER3_CORE, "timer3_coreclk", 0, 63, JH7100_CLK_PERH0_SRC),
-- JH7100_GDIV(JH7100_CLK_TIMER4_CORE, "timer4_coreclk", 0, 63, JH7100_CLK_PERH0_SRC),
-- JH7100_GDIV(JH7100_CLK_TIMER5_CORE, "timer5_coreclk", 0, 63, JH7100_CLK_PERH0_SRC),
-- JH7100_GDIV(JH7100_CLK_TIMER6_CORE, "timer6_coreclk", 0, 63, JH7100_CLK_PERH0_SRC),
-- JH7100_GATE(JH7100_CLK_VP6INTC_APB, "vp6intc_apb", 0, JH7100_CLK_APB2_BUS),
-- JH7100_GATE(JH7100_CLK_PWM_APB, "pwm_apb", 0, JH7100_CLK_APB2_BUS),
-- JH7100_GATE(JH7100_CLK_MSI_APB, "msi_apb", 0, JH7100_CLK_APB2_BUS),
-- JH7100_GATE(JH7100_CLK_TEMP_APB, "temp_apb", 0, JH7100_CLK_APB2_BUS),
-- JH7100_GDIV(JH7100_CLK_TEMP_SENSE, "temp_sense", 0, 31, JH7100_CLK_OSC_SYS),
-- JH7100_GATE(JH7100_CLK_SYSERR_APB, "syserr_apb", 0, JH7100_CLK_APB2_BUS),
-+ JH71X0__INV(JH7100_CLK_GMAC_RX_INV, "gmac_rx_inv", JH7100_CLK_GMAC_RX_PRE),
-+ JH71X0_GATE(JH7100_CLK_GMAC_RMII, "gmac_rmii", 0, JH7100_CLK_GMAC_RMII_REF),
-+ JH71X0_GDIV(JH7100_CLK_GMAC_TOPHYREF, "gmac_tophyref", 0, 127, JH7100_CLK_GMAC_ROOT_DIV),
-+ JH71X0_GATE(JH7100_CLK_SPI2AHB_AHB, "spi2ahb_ahb", 0, JH7100_CLK_AHB_BUS),
-+ JH71X0_GDIV(JH7100_CLK_SPI2AHB_CORE, "spi2ahb_core", 0, 31, JH7100_CLK_PERH0_SRC),
-+ JH71X0_GATE(JH7100_CLK_EZMASTER_AHB, "ezmaster_ahb", 0, JH7100_CLK_AHB_BUS),
-+ JH71X0_GATE(JH7100_CLK_E24_AHB, "e24_ahb", 0, JH7100_CLK_AHB_BUS),
-+ JH71X0_GATE(JH7100_CLK_E24RTC_TOGGLE, "e24rtc_toggle", 0, JH7100_CLK_OSC_SYS),
-+ JH71X0_GATE(JH7100_CLK_QSPI_AHB, "qspi_ahb", 0, JH7100_CLK_AHB_BUS),
-+ JH71X0_GATE(JH7100_CLK_QSPI_APB, "qspi_apb", 0, JH7100_CLK_APB1_BUS),
-+ JH71X0_GDIV(JH7100_CLK_QSPI_REF, "qspi_refclk", 0, 31, JH7100_CLK_PERH0_SRC),
-+ JH71X0_GATE(JH7100_CLK_SEC_AHB, "sec_ahb", 0, JH7100_CLK_AHB_BUS),
-+ JH71X0_GATE(JH7100_CLK_AES, "aes_clk", 0, JH7100_CLK_SEC_AHB),
-+ JH71X0_GATE(JH7100_CLK_SHA, "sha_clk", 0, JH7100_CLK_SEC_AHB),
-+ JH71X0_GATE(JH7100_CLK_PKA, "pka_clk", 0, JH7100_CLK_SEC_AHB),
-+ JH71X0_GATE(JH7100_CLK_TRNG_APB, "trng_apb", 0, JH7100_CLK_APB1_BUS),
-+ JH71X0_GATE(JH7100_CLK_OTP_APB, "otp_apb", 0, JH7100_CLK_APB1_BUS),
-+ JH71X0_GATE(JH7100_CLK_UART0_APB, "uart0_apb", 0, JH7100_CLK_APB1_BUS),
-+ JH71X0_GDIV(JH7100_CLK_UART0_CORE, "uart0_core", 0, 63, JH7100_CLK_PERH1_SRC),
-+ JH71X0_GATE(JH7100_CLK_UART1_APB, "uart1_apb", 0, JH7100_CLK_APB1_BUS),
-+ JH71X0_GDIV(JH7100_CLK_UART1_CORE, "uart1_core", 0, 63, JH7100_CLK_PERH1_SRC),
-+ JH71X0_GATE(JH7100_CLK_SPI0_APB, "spi0_apb", 0, JH7100_CLK_APB1_BUS),
-+ JH71X0_GDIV(JH7100_CLK_SPI0_CORE, "spi0_core", 0, 63, JH7100_CLK_PERH1_SRC),
-+ JH71X0_GATE(JH7100_CLK_SPI1_APB, "spi1_apb", 0, JH7100_CLK_APB1_BUS),
-+ JH71X0_GDIV(JH7100_CLK_SPI1_CORE, "spi1_core", 0, 63, JH7100_CLK_PERH1_SRC),
-+ JH71X0_GATE(JH7100_CLK_I2C0_APB, "i2c0_apb", 0, JH7100_CLK_APB1_BUS),
-+ JH71X0_GDIV(JH7100_CLK_I2C0_CORE, "i2c0_core", 0, 63, JH7100_CLK_PERH1_SRC),
-+ JH71X0_GATE(JH7100_CLK_I2C1_APB, "i2c1_apb", 0, JH7100_CLK_APB1_BUS),
-+ JH71X0_GDIV(JH7100_CLK_I2C1_CORE, "i2c1_core", 0, 63, JH7100_CLK_PERH1_SRC),
-+ JH71X0_GATE(JH7100_CLK_GPIO_APB, "gpio_apb", 0, JH7100_CLK_APB1_BUS),
-+ JH71X0_GATE(JH7100_CLK_UART2_APB, "uart2_apb", 0, JH7100_CLK_APB2_BUS),
-+ JH71X0_GDIV(JH7100_CLK_UART2_CORE, "uart2_core", 0, 63, JH7100_CLK_PERH0_SRC),
-+ JH71X0_GATE(JH7100_CLK_UART3_APB, "uart3_apb", 0, JH7100_CLK_APB2_BUS),
-+ JH71X0_GDIV(JH7100_CLK_UART3_CORE, "uart3_core", 0, 63, JH7100_CLK_PERH0_SRC),
-+ JH71X0_GATE(JH7100_CLK_SPI2_APB, "spi2_apb", 0, JH7100_CLK_APB2_BUS),
-+ JH71X0_GDIV(JH7100_CLK_SPI2_CORE, "spi2_core", 0, 63, JH7100_CLK_PERH0_SRC),
-+ JH71X0_GATE(JH7100_CLK_SPI3_APB, "spi3_apb", 0, JH7100_CLK_APB2_BUS),
-+ JH71X0_GDIV(JH7100_CLK_SPI3_CORE, "spi3_core", 0, 63, JH7100_CLK_PERH0_SRC),
-+ JH71X0_GATE(JH7100_CLK_I2C2_APB, "i2c2_apb", 0, JH7100_CLK_APB2_BUS),
-+ JH71X0_GDIV(JH7100_CLK_I2C2_CORE, "i2c2_core", 0, 63, JH7100_CLK_PERH0_SRC),
-+ JH71X0_GATE(JH7100_CLK_I2C3_APB, "i2c3_apb", 0, JH7100_CLK_APB2_BUS),
-+ JH71X0_GDIV(JH7100_CLK_I2C3_CORE, "i2c3_core", 0, 63, JH7100_CLK_PERH0_SRC),
-+ JH71X0_GATE(JH7100_CLK_WDTIMER_APB, "wdtimer_apb", 0, JH7100_CLK_APB2_BUS),
-+ JH71X0_GDIV(JH7100_CLK_WDT_CORE, "wdt_coreclk", 0, 63, JH7100_CLK_PERH0_SRC),
-+ JH71X0_GDIV(JH7100_CLK_TIMER0_CORE, "timer0_coreclk", 0, 63, JH7100_CLK_PERH0_SRC),
-+ JH71X0_GDIV(JH7100_CLK_TIMER1_CORE, "timer1_coreclk", 0, 63, JH7100_CLK_PERH0_SRC),
-+ JH71X0_GDIV(JH7100_CLK_TIMER2_CORE, "timer2_coreclk", 0, 63, JH7100_CLK_PERH0_SRC),
-+ JH71X0_GDIV(JH7100_CLK_TIMER3_CORE, "timer3_coreclk", 0, 63, JH7100_CLK_PERH0_SRC),
-+ JH71X0_GDIV(JH7100_CLK_TIMER4_CORE, "timer4_coreclk", 0, 63, JH7100_CLK_PERH0_SRC),
-+ JH71X0_GDIV(JH7100_CLK_TIMER5_CORE, "timer5_coreclk", 0, 63, JH7100_CLK_PERH0_SRC),
-+ JH71X0_GDIV(JH7100_CLK_TIMER6_CORE, "timer6_coreclk", 0, 63, JH7100_CLK_PERH0_SRC),
-+ JH71X0_GATE(JH7100_CLK_VP6INTC_APB, "vp6intc_apb", 0, JH7100_CLK_APB2_BUS),
-+ JH71X0_GATE(JH7100_CLK_PWM_APB, "pwm_apb", 0, JH7100_CLK_APB2_BUS),
-+ JH71X0_GATE(JH7100_CLK_MSI_APB, "msi_apb", 0, JH7100_CLK_APB2_BUS),
-+ JH71X0_GATE(JH7100_CLK_TEMP_APB, "temp_apb", 0, JH7100_CLK_APB2_BUS),
-+ JH71X0_GDIV(JH7100_CLK_TEMP_SENSE, "temp_sense", 0, 31, JH7100_CLK_OSC_SYS),
-+ JH71X0_GATE(JH7100_CLK_SYSERR_APB, "syserr_apb", 0, JH7100_CLK_APB2_BUS),
- };
-
- static struct clk_hw *jh7100_clk_get(struct of_phandle_args *clkspec, void *data)
- {
-- struct jh7100_clk_priv *priv = data;
-+ struct jh71x0_clk_priv *priv = data;
- unsigned int idx = clkspec->args[0];
-
- if (idx < JH7100_CLK_PLL0_OUT)
-@@ -280,7 +283,7 @@ static struct clk_hw *jh7100_clk_get(str
-
- static int __init clk_starfive_jh7100_probe(struct platform_device *pdev)
- {
-- struct jh7100_clk_priv *priv;
-+ struct jh71x0_clk_priv *priv;
- unsigned int idx;
- int ret;
-
-@@ -314,12 +317,12 @@ static int __init clk_starfive_jh7100_pr
- struct clk_parent_data parents[4] = {};
- struct clk_init_data init = {
- .name = jh7100_clk_data[idx].name,
-- .ops = starfive_jh7100_clk_ops(max),
-+ .ops = starfive_jh71x0_clk_ops(max),
- .parent_data = parents,
-- .num_parents = ((max & JH7100_CLK_MUX_MASK) >> JH7100_CLK_MUX_SHIFT) + 1,
-+ .num_parents = ((max & JH71X0_CLK_MUX_MASK) >> JH71X0_CLK_MUX_SHIFT) + 1,
- .flags = jh7100_clk_data[idx].flags,
- };
-- struct jh7100_clk *clk = &priv->reg[idx];
-+ struct jh71x0_clk *clk = &priv->reg[idx];
- unsigned int i;
-
- for (i = 0; i < init.num_parents; i++) {
-@@ -341,7 +344,7 @@ static int __init clk_starfive_jh7100_pr
-
- clk->hw.init = &init;
- clk->idx = idx;
-- clk->max_div = max & JH7100_CLK_DIV_MASK;
-+ clk->max_div = max & JH71X0_CLK_DIV_MASK;
-
- ret = devm_clk_hw_register(priv->dev, &clk->hw);
- if (ret)
---- a/drivers/clk/starfive/clk-starfive-jh71x0.c
-+++ b/drivers/clk/starfive/clk-starfive-jh71x0.c
-@@ -1,6 +1,6 @@
- // SPDX-License-Identifier: GPL-2.0
- /*
-- * StarFive JH7100 Clock Generator Driver
-+ * StarFive JH71X0 Clock Generator Driver
- *
- * Copyright (C) 2021-2022 Emil Renner Berthing <kernel@esmil.dk>
- */
-@@ -12,27 +12,27 @@
-
- #include "clk-starfive-jh71x0.h"
-
--static struct jh7100_clk *jh7100_clk_from(struct clk_hw *hw)
-+static struct jh71x0_clk *jh71x0_clk_from(struct clk_hw *hw)
- {
-- return container_of(hw, struct jh7100_clk, hw);
-+ return container_of(hw, struct jh71x0_clk, hw);
- }
-
--static struct jh7100_clk_priv *jh7100_priv_from(struct jh7100_clk *clk)
-+static struct jh71x0_clk_priv *jh71x0_priv_from(struct jh71x0_clk *clk)
- {
-- return container_of(clk, struct jh7100_clk_priv, reg[clk->idx]);
-+ return container_of(clk, struct jh71x0_clk_priv, reg[clk->idx]);
- }
-
--static u32 jh7100_clk_reg_get(struct jh7100_clk *clk)
-+static u32 jh71x0_clk_reg_get(struct jh71x0_clk *clk)
- {
-- struct jh7100_clk_priv *priv = jh7100_priv_from(clk);
-+ struct jh71x0_clk_priv *priv = jh71x0_priv_from(clk);
- void __iomem *reg = priv->base + 4 * clk->idx;
-
- return readl_relaxed(reg);
- }
-
--static void jh7100_clk_reg_rmw(struct jh7100_clk *clk, u32 mask, u32 value)
-+static void jh71x0_clk_reg_rmw(struct jh71x0_clk *clk, u32 mask, u32 value)
- {
-- struct jh7100_clk_priv *priv = jh7100_priv_from(clk);
-+ struct jh71x0_clk_priv *priv = jh71x0_priv_from(clk);
- void __iomem *reg = priv->base + 4 * clk->idx;
- unsigned long flags;
-
-@@ -42,41 +42,41 @@ static void jh7100_clk_reg_rmw(struct jh
- spin_unlock_irqrestore(&priv->rmw_lock, flags);
- }
-
--static int jh7100_clk_enable(struct clk_hw *hw)
-+static int jh71x0_clk_enable(struct clk_hw *hw)
- {
-- struct jh7100_clk *clk = jh7100_clk_from(hw);
-+ struct jh71x0_clk *clk = jh71x0_clk_from(hw);
-
-- jh7100_clk_reg_rmw(clk, JH7100_CLK_ENABLE, JH7100_CLK_ENABLE);
-+ jh71x0_clk_reg_rmw(clk, JH71X0_CLK_ENABLE, JH71X0_CLK_ENABLE);
- return 0;
- }
-
--static void jh7100_clk_disable(struct clk_hw *hw)
-+static void jh71x0_clk_disable(struct clk_hw *hw)
- {
-- struct jh7100_clk *clk = jh7100_clk_from(hw);
-+ struct jh71x0_clk *clk = jh71x0_clk_from(hw);
-
-- jh7100_clk_reg_rmw(clk, JH7100_CLK_ENABLE, 0);
-+ jh71x0_clk_reg_rmw(clk, JH71X0_CLK_ENABLE, 0);
- }
-
--static int jh7100_clk_is_enabled(struct clk_hw *hw)
-+static int jh71x0_clk_is_enabled(struct clk_hw *hw)
- {
-- struct jh7100_clk *clk = jh7100_clk_from(hw);
-+ struct jh71x0_clk *clk = jh71x0_clk_from(hw);
-
-- return !!(jh7100_clk_reg_get(clk) & JH7100_CLK_ENABLE);
-+ return !!(jh71x0_clk_reg_get(clk) & JH71X0_CLK_ENABLE);
- }
-
--static unsigned long jh7100_clk_recalc_rate(struct clk_hw *hw,
-+static unsigned long jh71x0_clk_recalc_rate(struct clk_hw *hw,
- unsigned long parent_rate)
- {
-- struct jh7100_clk *clk = jh7100_clk_from(hw);
-- u32 div = jh7100_clk_reg_get(clk) & JH7100_CLK_DIV_MASK;
-+ struct jh71x0_clk *clk = jh71x0_clk_from(hw);
-+ u32 div = jh71x0_clk_reg_get(clk) & JH71X0_CLK_DIV_MASK;
-
- return div ? parent_rate / div : 0;
- }
-
--static int jh7100_clk_determine_rate(struct clk_hw *hw,
-+static int jh71x0_clk_determine_rate(struct clk_hw *hw,
- struct clk_rate_request *req)
- {
-- struct jh7100_clk *clk = jh7100_clk_from(hw);
-+ struct jh71x0_clk *clk = jh71x0_clk_from(hw);
- unsigned long parent = req->best_parent_rate;
- unsigned long rate = clamp(req->rate, req->min_rate, req->max_rate);
- unsigned long div = min_t(unsigned long, DIV_ROUND_UP(parent, rate), clk->max_div);
-@@ -102,232 +102,232 @@ static int jh7100_clk_determine_rate(str
- return 0;
- }
-
--static int jh7100_clk_set_rate(struct clk_hw *hw,
-+static int jh71x0_clk_set_rate(struct clk_hw *hw,
- unsigned long rate,
- unsigned long parent_rate)
- {
-- struct jh7100_clk *clk = jh7100_clk_from(hw);
-+ struct jh71x0_clk *clk = jh71x0_clk_from(hw);
- unsigned long div = clamp(DIV_ROUND_CLOSEST(parent_rate, rate),
- 1UL, (unsigned long)clk->max_div);
-
-- jh7100_clk_reg_rmw(clk, JH7100_CLK_DIV_MASK, div);
-+ jh71x0_clk_reg_rmw(clk, JH71X0_CLK_DIV_MASK, div);
- return 0;
- }
-
--static unsigned long jh7100_clk_frac_recalc_rate(struct clk_hw *hw,
-+static unsigned long jh71x0_clk_frac_recalc_rate(struct clk_hw *hw,
- unsigned long parent_rate)
- {
-- struct jh7100_clk *clk = jh7100_clk_from(hw);
-- u32 reg = jh7100_clk_reg_get(clk);
-- unsigned long div100 = 100 * (reg & JH7100_CLK_INT_MASK) +
-- ((reg & JH7100_CLK_FRAC_MASK) >> JH7100_CLK_FRAC_SHIFT);
-+ struct jh71x0_clk *clk = jh71x0_clk_from(hw);
-+ u32 reg = jh71x0_clk_reg_get(clk);
-+ unsigned long div100 = 100 * (reg & JH71X0_CLK_INT_MASK) +
-+ ((reg & JH71X0_CLK_FRAC_MASK) >> JH71X0_CLK_FRAC_SHIFT);
-
-- return (div100 >= JH7100_CLK_FRAC_MIN) ? 100 * parent_rate / div100 : 0;
-+ return (div100 >= JH71X0_CLK_FRAC_MIN) ? 100 * parent_rate / div100 : 0;
- }
-
--static int jh7100_clk_frac_determine_rate(struct clk_hw *hw,
-+static int jh71x0_clk_frac_determine_rate(struct clk_hw *hw,
- struct clk_rate_request *req)
- {
- unsigned long parent100 = 100 * req->best_parent_rate;
- unsigned long rate = clamp(req->rate, req->min_rate, req->max_rate);
- unsigned long div100 = clamp(DIV_ROUND_CLOSEST(parent100, rate),
-- JH7100_CLK_FRAC_MIN, JH7100_CLK_FRAC_MAX);
-+ JH71X0_CLK_FRAC_MIN, JH71X0_CLK_FRAC_MAX);
- unsigned long result = parent100 / div100;
-
-- /* clamp the result as in jh7100_clk_determine_rate() above */
-- if (result > req->max_rate && div100 < JH7100_CLK_FRAC_MAX)
-+ /* clamp the result as in jh71x0_clk_determine_rate() above */
-+ if (result > req->max_rate && div100 < JH71X0_CLK_FRAC_MAX)
- result = parent100 / (div100 + 1);
-- if (result < req->min_rate && div100 > JH7100_CLK_FRAC_MIN)
-+ if (result < req->min_rate && div100 > JH71X0_CLK_FRAC_MIN)
- result = parent100 / (div100 - 1);
-
- req->rate = result;
- return 0;
- }
-
--static int jh7100_clk_frac_set_rate(struct clk_hw *hw,
-+static int jh71x0_clk_frac_set_rate(struct clk_hw *hw,
- unsigned long rate,
- unsigned long parent_rate)
- {
-- struct jh7100_clk *clk = jh7100_clk_from(hw);
-+ struct jh71x0_clk *clk = jh71x0_clk_from(hw);
- unsigned long div100 = clamp(DIV_ROUND_CLOSEST(100 * parent_rate, rate),
-- JH7100_CLK_FRAC_MIN, JH7100_CLK_FRAC_MAX);
-- u32 value = ((div100 % 100) << JH7100_CLK_FRAC_SHIFT) | (div100 / 100);
-+ JH71X0_CLK_FRAC_MIN, JH71X0_CLK_FRAC_MAX);
-+ u32 value = ((div100 % 100) << JH71X0_CLK_FRAC_SHIFT) | (div100 / 100);
-
-- jh7100_clk_reg_rmw(clk, JH7100_CLK_DIV_MASK, value);
-+ jh71x0_clk_reg_rmw(clk, JH71X0_CLK_DIV_MASK, value);
- return 0;
- }
-
--static u8 jh7100_clk_get_parent(struct clk_hw *hw)
-+static u8 jh71x0_clk_get_parent(struct clk_hw *hw)
- {
-- struct jh7100_clk *clk = jh7100_clk_from(hw);
-- u32 value = jh7100_clk_reg_get(clk);
-+ struct jh71x0_clk *clk = jh71x0_clk_from(hw);
-+ u32 value = jh71x0_clk_reg_get(clk);
-
-- return (value & JH7100_CLK_MUX_MASK) >> JH7100_CLK_MUX_SHIFT;
-+ return (value & JH71X0_CLK_MUX_MASK) >> JH71X0_CLK_MUX_SHIFT;
- }
-
--static int jh7100_clk_set_parent(struct clk_hw *hw, u8 index)
-+static int jh71x0_clk_set_parent(struct clk_hw *hw, u8 index)
- {
-- struct jh7100_clk *clk = jh7100_clk_from(hw);
-- u32 value = (u32)index << JH7100_CLK_MUX_SHIFT;
-+ struct jh71x0_clk *clk = jh71x0_clk_from(hw);
-+ u32 value = (u32)index << JH71X0_CLK_MUX_SHIFT;
-
-- jh7100_clk_reg_rmw(clk, JH7100_CLK_MUX_MASK, value);
-+ jh71x0_clk_reg_rmw(clk, JH71X0_CLK_MUX_MASK, value);
- return 0;
- }
-
--static int jh7100_clk_mux_determine_rate(struct clk_hw *hw,
-+static int jh71x0_clk_mux_determine_rate(struct clk_hw *hw,
- struct clk_rate_request *req)
- {
- return clk_mux_determine_rate_flags(hw, req, 0);
- }
-
--static int jh7100_clk_get_phase(struct clk_hw *hw)
-+static int jh71x0_clk_get_phase(struct clk_hw *hw)
- {
-- struct jh7100_clk *clk = jh7100_clk_from(hw);
-- u32 value = jh7100_clk_reg_get(clk);
-+ struct jh71x0_clk *clk = jh71x0_clk_from(hw);
-+ u32 value = jh71x0_clk_reg_get(clk);
-
-- return (value & JH7100_CLK_INVERT) ? 180 : 0;
-+ return (value & JH71X0_CLK_INVERT) ? 180 : 0;
- }
-
--static int jh7100_clk_set_phase(struct clk_hw *hw, int degrees)
-+static int jh71x0_clk_set_phase(struct clk_hw *hw, int degrees)
- {
-- struct jh7100_clk *clk = jh7100_clk_from(hw);
-+ struct jh71x0_clk *clk = jh71x0_clk_from(hw);
- u32 value;
-
- if (degrees == 0)
- value = 0;
- else if (degrees == 180)
-- value = JH7100_CLK_INVERT;
-+ value = JH71X0_CLK_INVERT;
- else
- return -EINVAL;
-
-- jh7100_clk_reg_rmw(clk, JH7100_CLK_INVERT, value);
-+ jh71x0_clk_reg_rmw(clk, JH71X0_CLK_INVERT, value);
- return 0;
- }
-
- #ifdef CONFIG_DEBUG_FS
--static void jh7100_clk_debug_init(struct clk_hw *hw, struct dentry *dentry)
-+static void jh71x0_clk_debug_init(struct clk_hw *hw, struct dentry *dentry)
- {
-- static const struct debugfs_reg32 jh7100_clk_reg = {
-+ static const struct debugfs_reg32 jh71x0_clk_reg = {
- .name = "CTRL",
- .offset = 0,
- };
-- struct jh7100_clk *clk = jh7100_clk_from(hw);
-- struct jh7100_clk_priv *priv = jh7100_priv_from(clk);
-+ struct jh71x0_clk *clk = jh71x0_clk_from(hw);
-+ struct jh71x0_clk_priv *priv = jh71x0_priv_from(clk);
- struct debugfs_regset32 *regset;
-
- regset = devm_kzalloc(priv->dev, sizeof(*regset), GFP_KERNEL);
- if (!regset)
- return;
-
-- regset->regs = &jh7100_clk_reg;
-+ regset->regs = &jh71x0_clk_reg;
- regset->nregs = 1;
- regset->base = priv->base + 4 * clk->idx;
-
- debugfs_create_regset32("registers", 0400, dentry, regset);
- }
- #else
--#define jh7100_clk_debug_init NULL
-+#define jh71x0_clk_debug_init NULL
- #endif
-
--static const struct clk_ops jh7100_clk_gate_ops = {
-- .enable = jh7100_clk_enable,
-- .disable = jh7100_clk_disable,
-- .is_enabled = jh7100_clk_is_enabled,
-- .debug_init = jh7100_clk_debug_init,
-+static const struct clk_ops jh71x0_clk_gate_ops = {
-+ .enable = jh71x0_clk_enable,
-+ .disable = jh71x0_clk_disable,
-+ .is_enabled = jh71x0_clk_is_enabled,
-+ .debug_init = jh71x0_clk_debug_init,
- };
-
--static const struct clk_ops jh7100_clk_div_ops = {
-- .recalc_rate = jh7100_clk_recalc_rate,
-- .determine_rate = jh7100_clk_determine_rate,
-- .set_rate = jh7100_clk_set_rate,
-- .debug_init = jh7100_clk_debug_init,
-+static const struct clk_ops jh71x0_clk_div_ops = {
-+ .recalc_rate = jh71x0_clk_recalc_rate,
-+ .determine_rate = jh71x0_clk_determine_rate,
-+ .set_rate = jh71x0_clk_set_rate,
-+ .debug_init = jh71x0_clk_debug_init,
- };
-
--static const struct clk_ops jh7100_clk_fdiv_ops = {
-- .recalc_rate = jh7100_clk_frac_recalc_rate,
-- .determine_rate = jh7100_clk_frac_determine_rate,
-- .set_rate = jh7100_clk_frac_set_rate,
-- .debug_init = jh7100_clk_debug_init,
-+static const struct clk_ops jh71x0_clk_fdiv_ops = {
-+ .recalc_rate = jh71x0_clk_frac_recalc_rate,
-+ .determine_rate = jh71x0_clk_frac_determine_rate,
-+ .set_rate = jh71x0_clk_frac_set_rate,
-+ .debug_init = jh71x0_clk_debug_init,
- };
-
--static const struct clk_ops jh7100_clk_gdiv_ops = {
-- .enable = jh7100_clk_enable,
-- .disable = jh7100_clk_disable,
-- .is_enabled = jh7100_clk_is_enabled,
-- .recalc_rate = jh7100_clk_recalc_rate,
-- .determine_rate = jh7100_clk_determine_rate,
-- .set_rate = jh7100_clk_set_rate,
-- .debug_init = jh7100_clk_debug_init,
-+static const struct clk_ops jh71x0_clk_gdiv_ops = {
-+ .enable = jh71x0_clk_enable,
-+ .disable = jh71x0_clk_disable,
-+ .is_enabled = jh71x0_clk_is_enabled,
-+ .recalc_rate = jh71x0_clk_recalc_rate,
-+ .determine_rate = jh71x0_clk_determine_rate,
-+ .set_rate = jh71x0_clk_set_rate,
-+ .debug_init = jh71x0_clk_debug_init,
- };
-
--static const struct clk_ops jh7100_clk_mux_ops = {
-- .determine_rate = jh7100_clk_mux_determine_rate,
-- .set_parent = jh7100_clk_set_parent,
-- .get_parent = jh7100_clk_get_parent,
-- .debug_init = jh7100_clk_debug_init,
-+static const struct clk_ops jh71x0_clk_mux_ops = {
-+ .determine_rate = jh71x0_clk_mux_determine_rate,
-+ .set_parent = jh71x0_clk_set_parent,
-+ .get_parent = jh71x0_clk_get_parent,
-+ .debug_init = jh71x0_clk_debug_init,
- };
-
--static const struct clk_ops jh7100_clk_gmux_ops = {
-- .enable = jh7100_clk_enable,
-- .disable = jh7100_clk_disable,
-- .is_enabled = jh7100_clk_is_enabled,
-- .determine_rate = jh7100_clk_mux_determine_rate,
-- .set_parent = jh7100_clk_set_parent,
-- .get_parent = jh7100_clk_get_parent,
-- .debug_init = jh7100_clk_debug_init,
-+static const struct clk_ops jh71x0_clk_gmux_ops = {
-+ .enable = jh71x0_clk_enable,
-+ .disable = jh71x0_clk_disable,
-+ .is_enabled = jh71x0_clk_is_enabled,
-+ .determine_rate = jh71x0_clk_mux_determine_rate,
-+ .set_parent = jh71x0_clk_set_parent,
-+ .get_parent = jh71x0_clk_get_parent,
-+ .debug_init = jh71x0_clk_debug_init,
- };
-
--static const struct clk_ops jh7100_clk_mdiv_ops = {
-- .recalc_rate = jh7100_clk_recalc_rate,
-- .determine_rate = jh7100_clk_determine_rate,
-- .get_parent = jh7100_clk_get_parent,
-- .set_parent = jh7100_clk_set_parent,
-- .set_rate = jh7100_clk_set_rate,
-- .debug_init = jh7100_clk_debug_init,
-+static const struct clk_ops jh71x0_clk_mdiv_ops = {
-+ .recalc_rate = jh71x0_clk_recalc_rate,
-+ .determine_rate = jh71x0_clk_determine_rate,
-+ .get_parent = jh71x0_clk_get_parent,
-+ .set_parent = jh71x0_clk_set_parent,
-+ .set_rate = jh71x0_clk_set_rate,
-+ .debug_init = jh71x0_clk_debug_init,
- };
-
--static const struct clk_ops jh7100_clk_gmd_ops = {
-- .enable = jh7100_clk_enable,
-- .disable = jh7100_clk_disable,
-- .is_enabled = jh7100_clk_is_enabled,
-- .recalc_rate = jh7100_clk_recalc_rate,
-- .determine_rate = jh7100_clk_determine_rate,
-- .get_parent = jh7100_clk_get_parent,
-- .set_parent = jh7100_clk_set_parent,
-- .set_rate = jh7100_clk_set_rate,
-- .debug_init = jh7100_clk_debug_init,
-+static const struct clk_ops jh71x0_clk_gmd_ops = {
-+ .enable = jh71x0_clk_enable,
-+ .disable = jh71x0_clk_disable,
-+ .is_enabled = jh71x0_clk_is_enabled,
-+ .recalc_rate = jh71x0_clk_recalc_rate,
-+ .determine_rate = jh71x0_clk_determine_rate,
-+ .get_parent = jh71x0_clk_get_parent,
-+ .set_parent = jh71x0_clk_set_parent,
-+ .set_rate = jh71x0_clk_set_rate,
-+ .debug_init = jh71x0_clk_debug_init,
- };
-
--static const struct clk_ops jh7100_clk_inv_ops = {
-- .get_phase = jh7100_clk_get_phase,
-- .set_phase = jh7100_clk_set_phase,
-- .debug_init = jh7100_clk_debug_init,
-+static const struct clk_ops jh71x0_clk_inv_ops = {
-+ .get_phase = jh71x0_clk_get_phase,
-+ .set_phase = jh71x0_clk_set_phase,
-+ .debug_init = jh71x0_clk_debug_init,
- };
-
--const struct clk_ops *starfive_jh7100_clk_ops(u32 max)
-+const struct clk_ops *starfive_jh71x0_clk_ops(u32 max)
- {
-- if (max & JH7100_CLK_DIV_MASK) {
-- if (max & JH7100_CLK_MUX_MASK) {
-- if (max & JH7100_CLK_ENABLE)
-- return &jh7100_clk_gmd_ops;
-- return &jh7100_clk_mdiv_ops;
-+ if (max & JH71X0_CLK_DIV_MASK) {
-+ if (max & JH71X0_CLK_MUX_MASK) {
-+ if (max & JH71X0_CLK_ENABLE)
-+ return &jh71x0_clk_gmd_ops;
-+ return &jh71x0_clk_mdiv_ops;
- }
-- if (max & JH7100_CLK_ENABLE)
-- return &jh7100_clk_gdiv_ops;
-- if (max == JH7100_CLK_FRAC_MAX)
-- return &jh7100_clk_fdiv_ops;
-- return &jh7100_clk_div_ops;
-+ if (max & JH71X0_CLK_ENABLE)
-+ return &jh71x0_clk_gdiv_ops;
-+ if (max == JH71X0_CLK_FRAC_MAX)
-+ return &jh71x0_clk_fdiv_ops;
-+ return &jh71x0_clk_div_ops;
- }
-
-- if (max & JH7100_CLK_MUX_MASK) {
-- if (max & JH7100_CLK_ENABLE)
-- return &jh7100_clk_gmux_ops;
-- return &jh7100_clk_mux_ops;
-+ if (max & JH71X0_CLK_MUX_MASK) {
-+ if (max & JH71X0_CLK_ENABLE)
-+ return &jh71x0_clk_gmux_ops;
-+ return &jh71x0_clk_mux_ops;
- }
-
-- if (max & JH7100_CLK_ENABLE)
-- return &jh7100_clk_gate_ops;
-+ if (max & JH71X0_CLK_ENABLE)
-+ return &jh71x0_clk_gate_ops;
-
-- return &jh7100_clk_inv_ops;
-+ return &jh71x0_clk_inv_ops;
- }
--EXPORT_SYMBOL_GPL(starfive_jh7100_clk_ops);
-+EXPORT_SYMBOL_GPL(starfive_jh71x0_clk_ops);
---- a/drivers/clk/starfive/clk-starfive-jh71x0.h
-+++ b/drivers/clk/starfive/clk-starfive-jh71x0.h
-@@ -1,6 +1,6 @@
- /* SPDX-License-Identifier: GPL-2.0 */
--#ifndef __CLK_STARFIVE_JH7100_H
--#define __CLK_STARFIVE_JH7100_H
-+#ifndef __CLK_STARFIVE_JH71X0_H
-+#define __CLK_STARFIVE_JH71X0_H
-
- #include <linux/bits.h>
- #include <linux/clk-provider.h>
-@@ -8,107 +8,116 @@
- #include <linux/spinlock.h>
-
- /* register fields */
--#define JH7100_CLK_ENABLE BIT(31)
--#define JH7100_CLK_INVERT BIT(30)
--#define JH7100_CLK_MUX_MASK GENMASK(27, 24)
--#define JH7100_CLK_MUX_SHIFT 24
--#define JH7100_CLK_DIV_MASK GENMASK(23, 0)
--#define JH7100_CLK_FRAC_MASK GENMASK(15, 8)
--#define JH7100_CLK_FRAC_SHIFT 8
--#define JH7100_CLK_INT_MASK GENMASK(7, 0)
-+#define JH71X0_CLK_ENABLE BIT(31)
-+#define JH71X0_CLK_INVERT BIT(30)
-+#define JH71X0_CLK_MUX_MASK GENMASK(27, 24)
-+#define JH71X0_CLK_MUX_SHIFT 24
-+#define JH71X0_CLK_DIV_MASK GENMASK(23, 0)
-+#define JH71X0_CLK_FRAC_MASK GENMASK(15, 8)
-+#define JH71X0_CLK_FRAC_SHIFT 8
-+#define JH71X0_CLK_INT_MASK GENMASK(7, 0)
-
- /* fractional divider min/max */
--#define JH7100_CLK_FRAC_MIN 100UL
--#define JH7100_CLK_FRAC_MAX 25599UL
-+#define JH71X0_CLK_FRAC_MIN 100UL
-+#define JH71X0_CLK_FRAC_MAX 25599UL
-
- /* clock data */
--struct jh7100_clk_data {
-+struct jh71x0_clk_data {
- const char *name;
- unsigned long flags;
- u32 max;
- u8 parents[4];
- };
-
--#define JH7100_GATE(_idx, _name, _flags, _parent) [_idx] = { \
-+#define JH71X0_GATE(_idx, _name, _flags, _parent) \
-+[_idx] = { \
- .name = _name, \
- .flags = CLK_SET_RATE_PARENT | (_flags), \
-- .max = JH7100_CLK_ENABLE, \
-+ .max = JH71X0_CLK_ENABLE, \
- .parents = { [0] = _parent }, \
- }
-
--#define JH7100__DIV(_idx, _name, _max, _parent) [_idx] = { \
-+#define JH71X0__DIV(_idx, _name, _max, _parent) \
-+[_idx] = { \
- .name = _name, \
- .flags = 0, \
- .max = _max, \
- .parents = { [0] = _parent }, \
- }
-
--#define JH7100_GDIV(_idx, _name, _flags, _max, _parent) [_idx] = { \
-+#define JH71X0_GDIV(_idx, _name, _flags, _max, _parent) \
-+[_idx] = { \
- .name = _name, \
- .flags = _flags, \
-- .max = JH7100_CLK_ENABLE | (_max), \
-+ .max = JH71X0_CLK_ENABLE | (_max), \
- .parents = { [0] = _parent }, \
- }
-
--#define JH7100_FDIV(_idx, _name, _parent) [_idx] = { \
-+#define JH71X0_FDIV(_idx, _name, _parent) \
-+[_idx] = { \
- .name = _name, \
- .flags = 0, \
-- .max = JH7100_CLK_FRAC_MAX, \
-+ .max = JH71X0_CLK_FRAC_MAX, \
- .parents = { [0] = _parent }, \
- }
-
--#define JH7100__MUX(_idx, _name, _nparents, ...) [_idx] = { \
-+#define JH71X0__MUX(_idx, _name, _nparents, ...) \
-+[_idx] = { \
- .name = _name, \
- .flags = 0, \
-- .max = ((_nparents) - 1) << JH7100_CLK_MUX_SHIFT, \
-+ .max = ((_nparents) - 1) << JH71X0_CLK_MUX_SHIFT, \
- .parents = { __VA_ARGS__ }, \
- }
-
--#define JH7100_GMUX(_idx, _name, _flags, _nparents, ...) [_idx] = { \
-+#define JH71X0_GMUX(_idx, _name, _flags, _nparents, ...) \
-+[_idx] = { \
- .name = _name, \
- .flags = _flags, \
-- .max = JH7100_CLK_ENABLE | \
-- (((_nparents) - 1) << JH7100_CLK_MUX_SHIFT), \
-+ .max = JH71X0_CLK_ENABLE | \
-+ (((_nparents) - 1) << JH71X0_CLK_MUX_SHIFT), \
- .parents = { __VA_ARGS__ }, \
- }
-
--#define JH7100_MDIV(_idx, _name, _max, _nparents, ...) [_idx] = { \
-+#define JH71X0_MDIV(_idx, _name, _max, _nparents, ...) \
-+[_idx] = { \
- .name = _name, \
- .flags = 0, \
-- .max = (((_nparents) - 1) << JH7100_CLK_MUX_SHIFT) | (_max), \
-+ .max = (((_nparents) - 1) << JH71X0_CLK_MUX_SHIFT) | (_max), \
- .parents = { __VA_ARGS__ }, \
- }
-
--#define JH7100__GMD(_idx, _name, _flags, _max, _nparents, ...) [_idx] = { \
-+#define JH71X0__GMD(_idx, _name, _flags, _max, _nparents, ...) \
-+[_idx] = { \
- .name = _name, \
- .flags = _flags, \
-- .max = JH7100_CLK_ENABLE | \
-- (((_nparents) - 1) << JH7100_CLK_MUX_SHIFT) | (_max), \
-+ .max = JH71X0_CLK_ENABLE | \
-+ (((_nparents) - 1) << JH71X0_CLK_MUX_SHIFT) | (_max), \
- .parents = { __VA_ARGS__ }, \
- }
-
--#define JH7100__INV(_idx, _name, _parent) [_idx] = { \
-+#define JH71X0__INV(_idx, _name, _parent) \
-+[_idx] = { \
- .name = _name, \
- .flags = CLK_SET_RATE_PARENT, \
-- .max = JH7100_CLK_INVERT, \
-+ .max = JH71X0_CLK_INVERT, \
- .parents = { [0] = _parent }, \
- }
-
--struct jh7100_clk {
-+struct jh71x0_clk {
- struct clk_hw hw;
- unsigned int idx;
- unsigned int max_div;
- };
-
--struct jh7100_clk_priv {
-+struct jh71x0_clk_priv {
- /* protect clk enable and set rate/parent from happening at the same time */
- spinlock_t rmw_lock;
- struct device *dev;
- void __iomem *base;
- struct clk_hw *pll[3];
-- struct jh7100_clk reg[];
-+ struct jh71x0_clk reg[];
- };
-
--const struct clk_ops *starfive_jh7100_clk_ops(u32 max);
-+const struct clk_ops *starfive_jh71x0_clk_ops(u32 max);
-
- #endif
diff --git a/target/linux/starfive/patches-6.1/0007-reset-starfive-Replace-SOC_STARFIVE-with-ARCH_STARFI.patch b/target/linux/starfive/patches-6.1/0007-reset-starfive-Replace-SOC_STARFIVE-with-ARCH_STARFI.patch
deleted file mode 100644
index e5281b85e9..0000000000
--- a/target/linux/starfive/patches-6.1/0007-reset-starfive-Replace-SOC_STARFIVE-with-ARCH_STARFI.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 0ee5a7565601fa785d7e55c57f26ff5d79473eb2 Mon Sep 17 00:00:00 2001
-From: Hal Feng <hal.feng@starfivetech.com>
-Date: Sat, 1 Apr 2023 19:19:19 +0800
-Subject: [PATCH 007/122] reset: starfive: Replace SOC_STARFIVE with
- ARCH_STARFIVE
-
-Using ARCH_FOO symbol is preferred than SOC_FOO.
-
-Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
-Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
-Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
-Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
----
- drivers/reset/Kconfig | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/reset/Kconfig
-+++ b/drivers/reset/Kconfig
-@@ -234,8 +234,8 @@ config RESET_SOCFPGA
-
- config RESET_STARFIVE_JH7100
- bool "StarFive JH7100 Reset Driver"
-- depends on SOC_STARFIVE || COMPILE_TEST
-- default SOC_STARFIVE
-+ depends on ARCH_STARFIVE || COMPILE_TEST
-+ default ARCH_STARFIVE
- help
- This enables the reset controller driver for the StarFive JH7100 SoC.
-
diff --git a/target/linux/starfive/patches-6.1/0008-reset-Create-subdirectory-for-StarFive-drivers.patch b/target/linux/starfive/patches-6.1/0008-reset-Create-subdirectory-for-StarFive-drivers.patch
deleted file mode 100644
index 2e44f38e59..0000000000
--- a/target/linux/starfive/patches-6.1/0008-reset-Create-subdirectory-for-StarFive-drivers.patch
+++ /dev/null
@@ -1,436 +0,0 @@
-From ea9e5879793f9743fbfe613174900ab0c431ac0e Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Sat, 1 Apr 2023 19:19:20 +0800
-Subject: [PATCH 008/122] reset: Create subdirectory for StarFive drivers
-
-This moves the StarFive JH7100 reset driver to a new subdirectory in
-preparation for adding more StarFive reset drivers.
-
-Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
-Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
-Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
-Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
-Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
----
- drivers/reset/Kconfig | 8 +-------
- drivers/reset/Makefile | 2 +-
- drivers/reset/starfive/Kconfig | 8 ++++++++
- drivers/reset/starfive/Makefile | 2 ++
- drivers/reset/{ => starfive}/reset-starfive-jh7100.c | 0
- 5 files changed, 12 insertions(+), 8 deletions(-)
- create mode 100644 drivers/reset/starfive/Kconfig
- create mode 100644 drivers/reset/starfive/Makefile
- rename drivers/reset/{ => starfive}/reset-starfive-jh7100.c (100%)
-
---- a/drivers/reset/Kconfig
-+++ b/drivers/reset/Kconfig
-@@ -232,13 +232,6 @@ config RESET_SOCFPGA
- This enables the reset driver for the SoCFPGA ARMv7 platforms. This
- driver gets initialized early during platform init calls.
-
--config RESET_STARFIVE_JH7100
-- bool "StarFive JH7100 Reset Driver"
-- depends on ARCH_STARFIVE || COMPILE_TEST
-- default ARCH_STARFIVE
-- help
-- This enables the reset controller driver for the StarFive JH7100 SoC.
--
- config RESET_SUNPLUS
- bool "Sunplus SoCs Reset Driver" if COMPILE_TEST
- default ARCH_SUNPLUS
-@@ -320,6 +313,7 @@ config RESET_ZYNQ
- help
- This enables the reset controller driver for Xilinx Zynq SoCs.
-
-+source "drivers/reset/starfive/Kconfig"
- source "drivers/reset/sti/Kconfig"
- source "drivers/reset/hisilicon/Kconfig"
- source "drivers/reset/tegra/Kconfig"
---- a/drivers/reset/Makefile
-+++ b/drivers/reset/Makefile
-@@ -1,6 +1,7 @@
- # SPDX-License-Identifier: GPL-2.0
- obj-y += core.o
- obj-y += hisilicon/
-+obj-y += starfive/
- obj-$(CONFIG_ARCH_STI) += sti/
- obj-$(CONFIG_ARCH_TEGRA) += tegra/
- obj-$(CONFIG_RESET_A10SR) += reset-a10sr.o
-@@ -30,7 +31,6 @@ obj-$(CONFIG_RESET_RZG2L_USBPHY_CTRL) +=
- obj-$(CONFIG_RESET_SCMI) += reset-scmi.o
- obj-$(CONFIG_RESET_SIMPLE) += reset-simple.o
- obj-$(CONFIG_RESET_SOCFPGA) += reset-socfpga.o
--obj-$(CONFIG_RESET_STARFIVE_JH7100) += reset-starfive-jh7100.o
- obj-$(CONFIG_RESET_SUNPLUS) += reset-sunplus.o
- obj-$(CONFIG_RESET_SUNXI) += reset-sunxi.o
- obj-$(CONFIG_RESET_TI_SCI) += reset-ti-sci.o
---- /dev/null
-+++ b/drivers/reset/starfive/Kconfig
-@@ -0,0 +1,8 @@
-+# SPDX-License-Identifier: GPL-2.0-only
-+
-+config RESET_STARFIVE_JH7100
-+ bool "StarFive JH7100 Reset Driver"
-+ depends on ARCH_STARFIVE || COMPILE_TEST
-+ default ARCH_STARFIVE
-+ help
-+ This enables the reset controller driver for the StarFive JH7100 SoC.
---- /dev/null
-+++ b/drivers/reset/starfive/Makefile
-@@ -0,0 +1,2 @@
-+# SPDX-License-Identifier: GPL-2.0
-+obj-$(CONFIG_RESET_STARFIVE_JH7100) += reset-starfive-jh7100.o
---- a/drivers/reset/reset-starfive-jh7100.c
-+++ /dev/null
-@@ -1,173 +0,0 @@
--// SPDX-License-Identifier: GPL-2.0-or-later
--/*
-- * Reset driver for the StarFive JH7100 SoC
-- *
-- * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
-- */
--
--#include <linux/bitmap.h>
--#include <linux/io.h>
--#include <linux/io-64-nonatomic-lo-hi.h>
--#include <linux/iopoll.h>
--#include <linux/mod_devicetable.h>
--#include <linux/platform_device.h>
--#include <linux/reset-controller.h>
--#include <linux/spinlock.h>
--
--#include <dt-bindings/reset/starfive-jh7100.h>
--
--/* register offsets */
--#define JH7100_RESET_ASSERT0 0x00
--#define JH7100_RESET_ASSERT1 0x04
--#define JH7100_RESET_ASSERT2 0x08
--#define JH7100_RESET_ASSERT3 0x0c
--#define JH7100_RESET_STATUS0 0x10
--#define JH7100_RESET_STATUS1 0x14
--#define JH7100_RESET_STATUS2 0x18
--#define JH7100_RESET_STATUS3 0x1c
--
--/*
-- * Writing a 1 to the n'th bit of the m'th ASSERT register asserts
-- * line 32m + n, and writing a 0 deasserts the same line.
-- * Most reset lines have their status inverted so a 0 bit in the STATUS
-- * register means the line is asserted and a 1 means it's deasserted. A few
-- * lines don't though, so store the expected value of the status registers when
-- * all lines are asserted.
-- */
--static const u64 jh7100_reset_asserted[2] = {
-- /* STATUS0 */
-- BIT_ULL_MASK(JH7100_RST_U74) |
-- BIT_ULL_MASK(JH7100_RST_VP6_DRESET) |
-- BIT_ULL_MASK(JH7100_RST_VP6_BRESET) |
-- /* STATUS1 */
-- BIT_ULL_MASK(JH7100_RST_HIFI4_DRESET) |
-- BIT_ULL_MASK(JH7100_RST_HIFI4_BRESET),
-- /* STATUS2 */
-- BIT_ULL_MASK(JH7100_RST_E24) |
-- /* STATUS3 */
-- 0,
--};
--
--struct jh7100_reset {
-- struct reset_controller_dev rcdev;
-- /* protect registers against concurrent read-modify-write */
-- spinlock_t lock;
-- void __iomem *base;
--};
--
--static inline struct jh7100_reset *
--jh7100_reset_from(struct reset_controller_dev *rcdev)
--{
-- return container_of(rcdev, struct jh7100_reset, rcdev);
--}
--
--static int jh7100_reset_update(struct reset_controller_dev *rcdev,
-- unsigned long id, bool assert)
--{
-- struct jh7100_reset *data = jh7100_reset_from(rcdev);
-- unsigned long offset = BIT_ULL_WORD(id);
-- u64 mask = BIT_ULL_MASK(id);
-- void __iomem *reg_assert = data->base + JH7100_RESET_ASSERT0 + offset * sizeof(u64);
-- void __iomem *reg_status = data->base + JH7100_RESET_STATUS0 + offset * sizeof(u64);
-- u64 done = jh7100_reset_asserted[offset] & mask;
-- u64 value;
-- unsigned long flags;
-- int ret;
--
-- if (!assert)
-- done ^= mask;
--
-- spin_lock_irqsave(&data->lock, flags);
--
-- value = readq(reg_assert);
-- if (assert)
-- value |= mask;
-- else
-- value &= ~mask;
-- writeq(value, reg_assert);
--
-- /* if the associated clock is gated, deasserting might otherwise hang forever */
-- ret = readq_poll_timeout_atomic(reg_status, value, (value & mask) == done, 0, 1000);
--
-- spin_unlock_irqrestore(&data->lock, flags);
-- return ret;
--}
--
--static int jh7100_reset_assert(struct reset_controller_dev *rcdev,
-- unsigned long id)
--{
-- return jh7100_reset_update(rcdev, id, true);
--}
--
--static int jh7100_reset_deassert(struct reset_controller_dev *rcdev,
-- unsigned long id)
--{
-- return jh7100_reset_update(rcdev, id, false);
--}
--
--static int jh7100_reset_reset(struct reset_controller_dev *rcdev,
-- unsigned long id)
--{
-- int ret;
--
-- ret = jh7100_reset_assert(rcdev, id);
-- if (ret)
-- return ret;
--
-- return jh7100_reset_deassert(rcdev, id);
--}
--
--static int jh7100_reset_status(struct reset_controller_dev *rcdev,
-- unsigned long id)
--{
-- struct jh7100_reset *data = jh7100_reset_from(rcdev);
-- unsigned long offset = BIT_ULL_WORD(id);
-- u64 mask = BIT_ULL_MASK(id);
-- void __iomem *reg_status = data->base + JH7100_RESET_STATUS0 + offset * sizeof(u64);
-- u64 value = readq(reg_status);
--
-- return !((value ^ jh7100_reset_asserted[offset]) & mask);
--}
--
--static const struct reset_control_ops jh7100_reset_ops = {
-- .assert = jh7100_reset_assert,
-- .deassert = jh7100_reset_deassert,
-- .reset = jh7100_reset_reset,
-- .status = jh7100_reset_status,
--};
--
--static int __init jh7100_reset_probe(struct platform_device *pdev)
--{
-- struct jh7100_reset *data;
--
-- data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
-- if (!data)
-- return -ENOMEM;
--
-- data->base = devm_platform_ioremap_resource(pdev, 0);
-- if (IS_ERR(data->base))
-- return PTR_ERR(data->base);
--
-- data->rcdev.ops = &jh7100_reset_ops;
-- data->rcdev.owner = THIS_MODULE;
-- data->rcdev.nr_resets = JH7100_RSTN_END;
-- data->rcdev.dev = &pdev->dev;
-- data->rcdev.of_node = pdev->dev.of_node;
-- spin_lock_init(&data->lock);
--
-- return devm_reset_controller_register(&pdev->dev, &data->rcdev);
--}
--
--static const struct of_device_id jh7100_reset_dt_ids[] = {
-- { .compatible = "starfive,jh7100-reset" },
-- { /* sentinel */ }
--};
--
--static struct platform_driver jh7100_reset_driver = {
-- .driver = {
-- .name = "jh7100-reset",
-- .of_match_table = jh7100_reset_dt_ids,
-- .suppress_bind_attrs = true,
-- },
--};
--builtin_platform_driver_probe(jh7100_reset_driver, jh7100_reset_probe);
---- /dev/null
-+++ b/drivers/reset/starfive/reset-starfive-jh7100.c
-@@ -0,0 +1,173 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later
-+/*
-+ * Reset driver for the StarFive JH7100 SoC
-+ *
-+ * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
-+ */
-+
-+#include <linux/bitmap.h>
-+#include <linux/io.h>
-+#include <linux/io-64-nonatomic-lo-hi.h>
-+#include <linux/iopoll.h>
-+#include <linux/mod_devicetable.h>
-+#include <linux/platform_device.h>
-+#include <linux/reset-controller.h>
-+#include <linux/spinlock.h>
-+
-+#include <dt-bindings/reset/starfive-jh7100.h>
-+
-+/* register offsets */
-+#define JH7100_RESET_ASSERT0 0x00
-+#define JH7100_RESET_ASSERT1 0x04
-+#define JH7100_RESET_ASSERT2 0x08
-+#define JH7100_RESET_ASSERT3 0x0c
-+#define JH7100_RESET_STATUS0 0x10
-+#define JH7100_RESET_STATUS1 0x14
-+#define JH7100_RESET_STATUS2 0x18
-+#define JH7100_RESET_STATUS3 0x1c
-+
-+/*
-+ * Writing a 1 to the n'th bit of the m'th ASSERT register asserts
-+ * line 32m + n, and writing a 0 deasserts the same line.
-+ * Most reset lines have their status inverted so a 0 bit in the STATUS
-+ * register means the line is asserted and a 1 means it's deasserted. A few
-+ * lines don't though, so store the expected value of the status registers when
-+ * all lines are asserted.
-+ */
-+static const u64 jh7100_reset_asserted[2] = {
-+ /* STATUS0 */
-+ BIT_ULL_MASK(JH7100_RST_U74) |
-+ BIT_ULL_MASK(JH7100_RST_VP6_DRESET) |
-+ BIT_ULL_MASK(JH7100_RST_VP6_BRESET) |
-+ /* STATUS1 */
-+ BIT_ULL_MASK(JH7100_RST_HIFI4_DRESET) |
-+ BIT_ULL_MASK(JH7100_RST_HIFI4_BRESET),
-+ /* STATUS2 */
-+ BIT_ULL_MASK(JH7100_RST_E24) |
-+ /* STATUS3 */
-+ 0,
-+};
-+
-+struct jh7100_reset {
-+ struct reset_controller_dev rcdev;
-+ /* protect registers against concurrent read-modify-write */
-+ spinlock_t lock;
-+ void __iomem *base;
-+};
-+
-+static inline struct jh7100_reset *
-+jh7100_reset_from(struct reset_controller_dev *rcdev)
-+{
-+ return container_of(rcdev, struct jh7100_reset, rcdev);
-+}
-+
-+static int jh7100_reset_update(struct reset_controller_dev *rcdev,
-+ unsigned long id, bool assert)
-+{
-+ struct jh7100_reset *data = jh7100_reset_from(rcdev);
-+ unsigned long offset = BIT_ULL_WORD(id);
-+ u64 mask = BIT_ULL_MASK(id);
-+ void __iomem *reg_assert = data->base + JH7100_RESET_ASSERT0 + offset * sizeof(u64);
-+ void __iomem *reg_status = data->base + JH7100_RESET_STATUS0 + offset * sizeof(u64);
-+ u64 done = jh7100_reset_asserted[offset] & mask;
-+ u64 value;
-+ unsigned long flags;
-+ int ret;
-+
-+ if (!assert)
-+ done ^= mask;
-+
-+ spin_lock_irqsave(&data->lock, flags);
-+
-+ value = readq(reg_assert);
-+ if (assert)
-+ value |= mask;
-+ else
-+ value &= ~mask;
-+ writeq(value, reg_assert);
-+
-+ /* if the associated clock is gated, deasserting might otherwise hang forever */
-+ ret = readq_poll_timeout_atomic(reg_status, value, (value & mask) == done, 0, 1000);
-+
-+ spin_unlock_irqrestore(&data->lock, flags);
-+ return ret;
-+}
-+
-+static int jh7100_reset_assert(struct reset_controller_dev *rcdev,
-+ unsigned long id)
-+{
-+ return jh7100_reset_update(rcdev, id, true);
-+}
-+
-+static int jh7100_reset_deassert(struct reset_controller_dev *rcdev,
-+ unsigned long id)
-+{
-+ return jh7100_reset_update(rcdev, id, false);
-+}
-+
-+static int jh7100_reset_reset(struct reset_controller_dev *rcdev,
-+ unsigned long id)
-+{
-+ int ret;
-+
-+ ret = jh7100_reset_assert(rcdev, id);
-+ if (ret)
-+ return ret;
-+
-+ return jh7100_reset_deassert(rcdev, id);
-+}
-+
-+static int jh7100_reset_status(struct reset_controller_dev *rcdev,
-+ unsigned long id)
-+{
-+ struct jh7100_reset *data = jh7100_reset_from(rcdev);
-+ unsigned long offset = BIT_ULL_WORD(id);
-+ u64 mask = BIT_ULL_MASK(id);
-+ void __iomem *reg_status = data->base + JH7100_RESET_STATUS0 + offset * sizeof(u64);
-+ u64 value = readq(reg_status);
-+
-+ return !((value ^ jh7100_reset_asserted[offset]) & mask);
-+}
-+
-+static const struct reset_control_ops jh7100_reset_ops = {
-+ .assert = jh7100_reset_assert,
-+ .deassert = jh7100_reset_deassert,
-+ .reset = jh7100_reset_reset,
-+ .status = jh7100_reset_status,
-+};
-+
-+static int __init jh7100_reset_probe(struct platform_device *pdev)
-+{
-+ struct jh7100_reset *data;
-+
-+ data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
-+ if (!data)
-+ return -ENOMEM;
-+
-+ data->base = devm_platform_ioremap_resource(pdev, 0);
-+ if (IS_ERR(data->base))
-+ return PTR_ERR(data->base);
-+
-+ data->rcdev.ops = &jh7100_reset_ops;
-+ data->rcdev.owner = THIS_MODULE;
-+ data->rcdev.nr_resets = JH7100_RSTN_END;
-+ data->rcdev.dev = &pdev->dev;
-+ data->rcdev.of_node = pdev->dev.of_node;
-+ spin_lock_init(&data->lock);
-+
-+ return devm_reset_controller_register(&pdev->dev, &data->rcdev);
-+}
-+
-+static const struct of_device_id jh7100_reset_dt_ids[] = {
-+ { .compatible = "starfive,jh7100-reset" },
-+ { /* sentinel */ }
-+};
-+
-+static struct platform_driver jh7100_reset_driver = {
-+ .driver = {
-+ .name = "jh7100-reset",
-+ .of_match_table = jh7100_reset_dt_ids,
-+ .suppress_bind_attrs = true,
-+ },
-+};
-+builtin_platform_driver_probe(jh7100_reset_driver, jh7100_reset_probe);
diff --git a/target/linux/starfive/patches-6.1/0009-reset-starfive-Factor-out-common-JH71X0-reset-code.patch b/target/linux/starfive/patches-6.1/0009-reset-starfive-Factor-out-common-JH71X0-reset-code.patch
deleted file mode 100644
index cd192f80af..0000000000
--- a/target/linux/starfive/patches-6.1/0009-reset-starfive-Factor-out-common-JH71X0-reset-code.patch
+++ /dev/null
@@ -1,390 +0,0 @@
-From a8051a7daa45056f469686286886968bc62b94df Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Sat, 1 Apr 2023 19:19:21 +0800
-Subject: [PATCH 009/122] reset: starfive: Factor out common JH71X0 reset code
-
-The StarFive JH7100 SoC has additional reset controllers for audio and
-video, but the registers follow the same structure. On the JH7110 the
-reset registers don't get their own memory range, but instead follow the
-clock control registers. The registers still follow the same structure
-though, so let's factor out the common code to handle all these cases.
-
-Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
-Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
-Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
-Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
----
- drivers/reset/starfive/Kconfig | 4 +
- drivers/reset/starfive/Makefile | 2 +
- .../reset/starfive/reset-starfive-jh7100.c | 150 +---------------
- .../reset/starfive/reset-starfive-jh71x0.c | 162 ++++++++++++++++++
- .../reset/starfive/reset-starfive-jh71x0.h | 11 ++
- 5 files changed, 180 insertions(+), 149 deletions(-)
- create mode 100644 drivers/reset/starfive/reset-starfive-jh71x0.c
- create mode 100644 drivers/reset/starfive/reset-starfive-jh71x0.h
-
---- a/drivers/reset/starfive/Kconfig
-+++ b/drivers/reset/starfive/Kconfig
-@@ -1,8 +1,12 @@
- # SPDX-License-Identifier: GPL-2.0-only
-
-+config RESET_STARFIVE_JH71X0
-+ bool
-+
- config RESET_STARFIVE_JH7100
- bool "StarFive JH7100 Reset Driver"
- depends on ARCH_STARFIVE || COMPILE_TEST
-+ select RESET_STARFIVE_JH71X0
- default ARCH_STARFIVE
- help
- This enables the reset controller driver for the StarFive JH7100 SoC.
---- a/drivers/reset/starfive/Makefile
-+++ b/drivers/reset/starfive/Makefile
-@@ -1,2 +1,4 @@
- # SPDX-License-Identifier: GPL-2.0
-+obj-$(CONFIG_RESET_STARFIVE_JH71X0) += reset-starfive-jh71x0.o
-+
- obj-$(CONFIG_RESET_STARFIVE_JH7100) += reset-starfive-jh7100.o
---- a/drivers/reset/starfive/reset-starfive-jh7100.c
-+++ b/drivers/reset/starfive/reset-starfive-jh7100.c
-@@ -5,158 +5,10 @@
- * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
- */
-
--#include <linux/bitmap.h>
--#include <linux/io.h>
--#include <linux/io-64-nonatomic-lo-hi.h>
--#include <linux/iopoll.h>
- #include <linux/mod_devicetable.h>
- #include <linux/platform_device.h>
--#include <linux/reset-controller.h>
--#include <linux/spinlock.h>
-
--#include <dt-bindings/reset/starfive-jh7100.h>
--
--/* register offsets */
--#define JH7100_RESET_ASSERT0 0x00
--#define JH7100_RESET_ASSERT1 0x04
--#define JH7100_RESET_ASSERT2 0x08
--#define JH7100_RESET_ASSERT3 0x0c
--#define JH7100_RESET_STATUS0 0x10
--#define JH7100_RESET_STATUS1 0x14
--#define JH7100_RESET_STATUS2 0x18
--#define JH7100_RESET_STATUS3 0x1c
--
--/*
-- * Writing a 1 to the n'th bit of the m'th ASSERT register asserts
-- * line 32m + n, and writing a 0 deasserts the same line.
-- * Most reset lines have their status inverted so a 0 bit in the STATUS
-- * register means the line is asserted and a 1 means it's deasserted. A few
-- * lines don't though, so store the expected value of the status registers when
-- * all lines are asserted.
-- */
--static const u64 jh7100_reset_asserted[2] = {
-- /* STATUS0 */
-- BIT_ULL_MASK(JH7100_RST_U74) |
-- BIT_ULL_MASK(JH7100_RST_VP6_DRESET) |
-- BIT_ULL_MASK(JH7100_RST_VP6_BRESET) |
-- /* STATUS1 */
-- BIT_ULL_MASK(JH7100_RST_HIFI4_DRESET) |
-- BIT_ULL_MASK(JH7100_RST_HIFI4_BRESET),
-- /* STATUS2 */
-- BIT_ULL_MASK(JH7100_RST_E24) |
-- /* STATUS3 */
-- 0,
--};
--
--struct jh7100_reset {
-- struct reset_controller_dev rcdev;
-- /* protect registers against concurrent read-modify-write */
-- spinlock_t lock;
-- void __iomem *base;
--};
--
--static inline struct jh7100_reset *
--jh7100_reset_from(struct reset_controller_dev *rcdev)
--{
-- return container_of(rcdev, struct jh7100_reset, rcdev);
--}
--
--static int jh7100_reset_update(struct reset_controller_dev *rcdev,
-- unsigned long id, bool assert)
--{
-- struct jh7100_reset *data = jh7100_reset_from(rcdev);
-- unsigned long offset = BIT_ULL_WORD(id);
-- u64 mask = BIT_ULL_MASK(id);
-- void __iomem *reg_assert = data->base + JH7100_RESET_ASSERT0 + offset * sizeof(u64);
-- void __iomem *reg_status = data->base + JH7100_RESET_STATUS0 + offset * sizeof(u64);
-- u64 done = jh7100_reset_asserted[offset] & mask;
-- u64 value;
-- unsigned long flags;
-- int ret;
--
-- if (!assert)
-- done ^= mask;
--
-- spin_lock_irqsave(&data->lock, flags);
--
-- value = readq(reg_assert);
-- if (assert)
-- value |= mask;
-- else
-- value &= ~mask;
-- writeq(value, reg_assert);
--
-- /* if the associated clock is gated, deasserting might otherwise hang forever */
-- ret = readq_poll_timeout_atomic(reg_status, value, (value & mask) == done, 0, 1000);
--
-- spin_unlock_irqrestore(&data->lock, flags);
-- return ret;
--}
--
--static int jh7100_reset_assert(struct reset_controller_dev *rcdev,
-- unsigned long id)
--{
-- return jh7100_reset_update(rcdev, id, true);
--}
--
--static int jh7100_reset_deassert(struct reset_controller_dev *rcdev,
-- unsigned long id)
--{
-- return jh7100_reset_update(rcdev, id, false);
--}
--
--static int jh7100_reset_reset(struct reset_controller_dev *rcdev,
-- unsigned long id)
--{
-- int ret;
--
-- ret = jh7100_reset_assert(rcdev, id);
-- if (ret)
-- return ret;
--
-- return jh7100_reset_deassert(rcdev, id);
--}
--
--static int jh7100_reset_status(struct reset_controller_dev *rcdev,
-- unsigned long id)
--{
-- struct jh7100_reset *data = jh7100_reset_from(rcdev);
-- unsigned long offset = BIT_ULL_WORD(id);
-- u64 mask = BIT_ULL_MASK(id);
-- void __iomem *reg_status = data->base + JH7100_RESET_STATUS0 + offset * sizeof(u64);
-- u64 value = readq(reg_status);
--
-- return !((value ^ jh7100_reset_asserted[offset]) & mask);
--}
--
--static const struct reset_control_ops jh7100_reset_ops = {
-- .assert = jh7100_reset_assert,
-- .deassert = jh7100_reset_deassert,
-- .reset = jh7100_reset_reset,
-- .status = jh7100_reset_status,
--};
--
--static int __init jh7100_reset_probe(struct platform_device *pdev)
--{
-- struct jh7100_reset *data;
--
-- data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
-- if (!data)
-- return -ENOMEM;
--
-- data->base = devm_platform_ioremap_resource(pdev, 0);
-- if (IS_ERR(data->base))
-- return PTR_ERR(data->base);
--
-- data->rcdev.ops = &jh7100_reset_ops;
-- data->rcdev.owner = THIS_MODULE;
-- data->rcdev.nr_resets = JH7100_RSTN_END;
-- data->rcdev.dev = &pdev->dev;
-- data->rcdev.of_node = pdev->dev.of_node;
-- spin_lock_init(&data->lock);
--
-- return devm_reset_controller_register(&pdev->dev, &data->rcdev);
--}
-+#include "reset-starfive-jh71x0.h"
-
- static const struct of_device_id jh7100_reset_dt_ids[] = {
- { .compatible = "starfive,jh7100-reset" },
---- /dev/null
-+++ b/drivers/reset/starfive/reset-starfive-jh71x0.c
-@@ -0,0 +1,162 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later
-+/*
-+ * Reset driver for the StarFive JH7100 SoC
-+ *
-+ * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
-+ */
-+
-+#include <linux/bitmap.h>
-+#include <linux/device.h>
-+#include <linux/io.h>
-+#include <linux/io-64-nonatomic-lo-hi.h>
-+#include <linux/iopoll.h>
-+#include <linux/platform_device.h>
-+#include <linux/reset-controller.h>
-+#include <linux/spinlock.h>
-+
-+#include "reset-starfive-jh71x0.h"
-+
-+#include <dt-bindings/reset/starfive-jh7100.h>
-+
-+/* register offsets */
-+#define JH7100_RESET_ASSERT0 0x00
-+#define JH7100_RESET_ASSERT1 0x04
-+#define JH7100_RESET_ASSERT2 0x08
-+#define JH7100_RESET_ASSERT3 0x0c
-+#define JH7100_RESET_STATUS0 0x10
-+#define JH7100_RESET_STATUS1 0x14
-+#define JH7100_RESET_STATUS2 0x18
-+#define JH7100_RESET_STATUS3 0x1c
-+
-+/*
-+ * Writing a 1 to the n'th bit of the m'th ASSERT register asserts
-+ * line 32m + n, and writing a 0 deasserts the same line.
-+ * Most reset lines have their status inverted so a 0 bit in the STATUS
-+ * register means the line is asserted and a 1 means it's deasserted. A few
-+ * lines don't though, so store the expected value of the status registers when
-+ * all lines are asserted.
-+ */
-+static const u64 jh7100_reset_asserted[2] = {
-+ /* STATUS0 */
-+ BIT_ULL_MASK(JH7100_RST_U74) |
-+ BIT_ULL_MASK(JH7100_RST_VP6_DRESET) |
-+ BIT_ULL_MASK(JH7100_RST_VP6_BRESET) |
-+ /* STATUS1 */
-+ BIT_ULL_MASK(JH7100_RST_HIFI4_DRESET) |
-+ BIT_ULL_MASK(JH7100_RST_HIFI4_BRESET),
-+ /* STATUS2 */
-+ BIT_ULL_MASK(JH7100_RST_E24) |
-+ /* STATUS3 */
-+ 0,
-+};
-+
-+struct jh7100_reset {
-+ struct reset_controller_dev rcdev;
-+ /* protect registers against concurrent read-modify-write */
-+ spinlock_t lock;
-+ void __iomem *base;
-+};
-+
-+static inline struct jh7100_reset *
-+jh7100_reset_from(struct reset_controller_dev *rcdev)
-+{
-+ return container_of(rcdev, struct jh7100_reset, rcdev);
-+}
-+
-+static int jh7100_reset_update(struct reset_controller_dev *rcdev,
-+ unsigned long id, bool assert)
-+{
-+ struct jh7100_reset *data = jh7100_reset_from(rcdev);
-+ unsigned long offset = BIT_ULL_WORD(id);
-+ u64 mask = BIT_ULL_MASK(id);
-+ void __iomem *reg_assert = data->base + JH7100_RESET_ASSERT0 + offset * sizeof(u64);
-+ void __iomem *reg_status = data->base + JH7100_RESET_STATUS0 + offset * sizeof(u64);
-+ u64 done = jh7100_reset_asserted[offset] & mask;
-+ u64 value;
-+ unsigned long flags;
-+ int ret;
-+
-+ if (!assert)
-+ done ^= mask;
-+
-+ spin_lock_irqsave(&data->lock, flags);
-+
-+ value = readq(reg_assert);
-+ if (assert)
-+ value |= mask;
-+ else
-+ value &= ~mask;
-+ writeq(value, reg_assert);
-+
-+ /* if the associated clock is gated, deasserting might otherwise hang forever */
-+ ret = readq_poll_timeout_atomic(reg_status, value, (value & mask) == done, 0, 1000);
-+
-+ spin_unlock_irqrestore(&data->lock, flags);
-+ return ret;
-+}
-+
-+static int jh7100_reset_assert(struct reset_controller_dev *rcdev,
-+ unsigned long id)
-+{
-+ return jh7100_reset_update(rcdev, id, true);
-+}
-+
-+static int jh7100_reset_deassert(struct reset_controller_dev *rcdev,
-+ unsigned long id)
-+{
-+ return jh7100_reset_update(rcdev, id, false);
-+}
-+
-+static int jh7100_reset_reset(struct reset_controller_dev *rcdev,
-+ unsigned long id)
-+{
-+ int ret;
-+
-+ ret = jh7100_reset_assert(rcdev, id);
-+ if (ret)
-+ return ret;
-+
-+ return jh7100_reset_deassert(rcdev, id);
-+}
-+
-+static int jh7100_reset_status(struct reset_controller_dev *rcdev,
-+ unsigned long id)
-+{
-+ struct jh7100_reset *data = jh7100_reset_from(rcdev);
-+ unsigned long offset = BIT_ULL_WORD(id);
-+ u64 mask = BIT_ULL_MASK(id);
-+ void __iomem *reg_status = data->base + JH7100_RESET_STATUS0 + offset * sizeof(u64);
-+ u64 value = readq(reg_status);
-+
-+ return !((value ^ jh7100_reset_asserted[offset]) & mask);
-+}
-+
-+static const struct reset_control_ops jh7100_reset_ops = {
-+ .assert = jh7100_reset_assert,
-+ .deassert = jh7100_reset_deassert,
-+ .reset = jh7100_reset_reset,
-+ .status = jh7100_reset_status,
-+};
-+
-+int jh7100_reset_probe(struct platform_device *pdev)
-+{
-+ struct jh7100_reset *data;
-+
-+ data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
-+ if (!data)
-+ return -ENOMEM;
-+
-+ data->base = devm_platform_ioremap_resource(pdev, 0);
-+ if (IS_ERR(data->base))
-+ return PTR_ERR(data->base);
-+
-+ data->rcdev.ops = &jh7100_reset_ops;
-+ data->rcdev.owner = THIS_MODULE;
-+ data->rcdev.nr_resets = JH7100_RSTN_END;
-+ data->rcdev.dev = &pdev->dev;
-+ data->rcdev.of_node = pdev->dev.of_node;
-+ spin_lock_init(&data->lock);
-+
-+ return devm_reset_controller_register(&pdev->dev, &data->rcdev);
-+}
-+EXPORT_SYMBOL_GPL(jh7100_reset_probe);
---- /dev/null
-+++ b/drivers/reset/starfive/reset-starfive-jh71x0.h
-@@ -0,0 +1,11 @@
-+/* SPDX-License-Identifier: GPL-2.0-or-later */
-+/*
-+ * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
-+ */
-+
-+#ifndef __RESET_STARFIVE_JH71X0_H
-+#define __RESET_STARFIVE_JH71X0_H
-+
-+int jh7100_reset_probe(struct platform_device *pdev);
-+
-+#endif /* __RESET_STARFIVE_JH71X0_H */
diff --git a/target/linux/starfive/patches-6.1/0010-reset-starfive-Extract-the-common-JH71X0-reset-code.patch b/target/linux/starfive/patches-6.1/0010-reset-starfive-Extract-the-common-JH71X0-reset-code.patch
deleted file mode 100644
index 0a932f57b2..0000000000
--- a/target/linux/starfive/patches-6.1/0010-reset-starfive-Extract-the-common-JH71X0-reset-code.patch
+++ /dev/null
@@ -1,215 +0,0 @@
-From dbee38aac9811a25e3e3204f813048bf64155248 Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Sat, 1 Apr 2023 19:19:22 +0800
-Subject: [PATCH 010/122] reset: starfive: Extract the common JH71X0 reset code
-
-Extract the common JH71X0 reset code for reusing them to
-support JH7110 SoC.
-
-Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
-Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
-Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
-Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
----
- .../reset/starfive/reset-starfive-jh7100.c | 49 ++++++++++++
- .../reset/starfive/reset-starfive-jh71x0.c | 76 ++++++-------------
- .../reset/starfive/reset-starfive-jh71x0.h | 5 +-
- 3 files changed, 76 insertions(+), 54 deletions(-)
-
---- a/drivers/reset/starfive/reset-starfive-jh7100.c
-+++ b/drivers/reset/starfive/reset-starfive-jh7100.c
-@@ -10,6 +10,55 @@
-
- #include "reset-starfive-jh71x0.h"
-
-+#include <dt-bindings/reset/starfive-jh7100.h>
-+
-+/* register offsets */
-+#define JH7100_RESET_ASSERT0 0x00
-+#define JH7100_RESET_ASSERT1 0x04
-+#define JH7100_RESET_ASSERT2 0x08
-+#define JH7100_RESET_ASSERT3 0x0c
-+#define JH7100_RESET_STATUS0 0x10
-+#define JH7100_RESET_STATUS1 0x14
-+#define JH7100_RESET_STATUS2 0x18
-+#define JH7100_RESET_STATUS3 0x1c
-+
-+/*
-+ * Writing a 1 to the n'th bit of the m'th ASSERT register asserts
-+ * line 32m + n, and writing a 0 deasserts the same line.
-+ * Most reset lines have their status inverted so a 0 bit in the STATUS
-+ * register means the line is asserted and a 1 means it's deasserted. A few
-+ * lines don't though, so store the expected value of the status registers when
-+ * all lines are asserted.
-+ */
-+static const u64 jh7100_reset_asserted[2] = {
-+ /* STATUS0 */
-+ BIT_ULL_MASK(JH7100_RST_U74) |
-+ BIT_ULL_MASK(JH7100_RST_VP6_DRESET) |
-+ BIT_ULL_MASK(JH7100_RST_VP6_BRESET) |
-+ /* STATUS1 */
-+ BIT_ULL_MASK(JH7100_RST_HIFI4_DRESET) |
-+ BIT_ULL_MASK(JH7100_RST_HIFI4_BRESET),
-+ /* STATUS2 */
-+ BIT_ULL_MASK(JH7100_RST_E24) |
-+ /* STATUS3 */
-+ 0,
-+};
-+
-+static int __init jh7100_reset_probe(struct platform_device *pdev)
-+{
-+ void __iomem *base = devm_platform_ioremap_resource(pdev, 0);
-+
-+ if (IS_ERR(base))
-+ return PTR_ERR(base);
-+
-+ return reset_starfive_jh7100_register(&pdev->dev, pdev->dev.of_node,
-+ base + JH7100_RESET_ASSERT0,
-+ base + JH7100_RESET_STATUS0,
-+ jh7100_reset_asserted,
-+ JH7100_RSTN_END,
-+ THIS_MODULE);
-+}
-+
- static const struct of_device_id jh7100_reset_dt_ids[] = {
- { .compatible = "starfive,jh7100-reset" },
- { /* sentinel */ }
---- a/drivers/reset/starfive/reset-starfive-jh71x0.c
-+++ b/drivers/reset/starfive/reset-starfive-jh71x0.c
-@@ -10,51 +10,18 @@
- #include <linux/io.h>
- #include <linux/io-64-nonatomic-lo-hi.h>
- #include <linux/iopoll.h>
--#include <linux/platform_device.h>
- #include <linux/reset-controller.h>
- #include <linux/spinlock.h>
-
- #include "reset-starfive-jh71x0.h"
-
--#include <dt-bindings/reset/starfive-jh7100.h>
--
--/* register offsets */
--#define JH7100_RESET_ASSERT0 0x00
--#define JH7100_RESET_ASSERT1 0x04
--#define JH7100_RESET_ASSERT2 0x08
--#define JH7100_RESET_ASSERT3 0x0c
--#define JH7100_RESET_STATUS0 0x10
--#define JH7100_RESET_STATUS1 0x14
--#define JH7100_RESET_STATUS2 0x18
--#define JH7100_RESET_STATUS3 0x1c
--
--/*
-- * Writing a 1 to the n'th bit of the m'th ASSERT register asserts
-- * line 32m + n, and writing a 0 deasserts the same line.
-- * Most reset lines have their status inverted so a 0 bit in the STATUS
-- * register means the line is asserted and a 1 means it's deasserted. A few
-- * lines don't though, so store the expected value of the status registers when
-- * all lines are asserted.
-- */
--static const u64 jh7100_reset_asserted[2] = {
-- /* STATUS0 */
-- BIT_ULL_MASK(JH7100_RST_U74) |
-- BIT_ULL_MASK(JH7100_RST_VP6_DRESET) |
-- BIT_ULL_MASK(JH7100_RST_VP6_BRESET) |
-- /* STATUS1 */
-- BIT_ULL_MASK(JH7100_RST_HIFI4_DRESET) |
-- BIT_ULL_MASK(JH7100_RST_HIFI4_BRESET),
-- /* STATUS2 */
-- BIT_ULL_MASK(JH7100_RST_E24) |
-- /* STATUS3 */
-- 0,
--};
--
- struct jh7100_reset {
- struct reset_controller_dev rcdev;
- /* protect registers against concurrent read-modify-write */
- spinlock_t lock;
-- void __iomem *base;
-+ void __iomem *assert;
-+ void __iomem *status;
-+ const u64 *asserted;
- };
-
- static inline struct jh7100_reset *
-@@ -69,9 +36,9 @@ static int jh7100_reset_update(struct re
- struct jh7100_reset *data = jh7100_reset_from(rcdev);
- unsigned long offset = BIT_ULL_WORD(id);
- u64 mask = BIT_ULL_MASK(id);
-- void __iomem *reg_assert = data->base + JH7100_RESET_ASSERT0 + offset * sizeof(u64);
-- void __iomem *reg_status = data->base + JH7100_RESET_STATUS0 + offset * sizeof(u64);
-- u64 done = jh7100_reset_asserted[offset] & mask;
-+ void __iomem *reg_assert = data->assert + offset * sizeof(u64);
-+ void __iomem *reg_status = data->status + offset * sizeof(u64);
-+ u64 done = data->asserted ? data->asserted[offset] & mask : 0;
- u64 value;
- unsigned long flags;
- int ret;
-@@ -125,10 +92,10 @@ static int jh7100_reset_status(struct re
- struct jh7100_reset *data = jh7100_reset_from(rcdev);
- unsigned long offset = BIT_ULL_WORD(id);
- u64 mask = BIT_ULL_MASK(id);
-- void __iomem *reg_status = data->base + JH7100_RESET_STATUS0 + offset * sizeof(u64);
-+ void __iomem *reg_status = data->status + offset * sizeof(u64);
- u64 value = readq(reg_status);
-
-- return !((value ^ jh7100_reset_asserted[offset]) & mask);
-+ return !((value ^ data->asserted[offset]) & mask);
- }
-
- static const struct reset_control_ops jh7100_reset_ops = {
-@@ -138,25 +105,28 @@ static const struct reset_control_ops jh
- .status = jh7100_reset_status,
- };
-
--int jh7100_reset_probe(struct platform_device *pdev)
-+int reset_starfive_jh7100_register(struct device *dev, struct device_node *of_node,
-+ void __iomem *assert, void __iomem *status,
-+ const u64 *asserted, unsigned int nr_resets,
-+ struct module *owner)
- {
- struct jh7100_reset *data;
-
-- data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
-+ data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
- if (!data)
- return -ENOMEM;
-
-- data->base = devm_platform_ioremap_resource(pdev, 0);
-- if (IS_ERR(data->base))
-- return PTR_ERR(data->base);
--
- data->rcdev.ops = &jh7100_reset_ops;
-- data->rcdev.owner = THIS_MODULE;
-- data->rcdev.nr_resets = JH7100_RSTN_END;
-- data->rcdev.dev = &pdev->dev;
-- data->rcdev.of_node = pdev->dev.of_node;
-+ data->rcdev.owner = owner;
-+ data->rcdev.nr_resets = nr_resets;
-+ data->rcdev.dev = dev;
-+ data->rcdev.of_node = of_node;
-+
- spin_lock_init(&data->lock);
-+ data->assert = assert;
-+ data->status = status;
-+ data->asserted = asserted;
-
-- return devm_reset_controller_register(&pdev->dev, &data->rcdev);
-+ return devm_reset_controller_register(dev, &data->rcdev);
- }
--EXPORT_SYMBOL_GPL(jh7100_reset_probe);
-+EXPORT_SYMBOL_GPL(reset_starfive_jh7100_register);
---- a/drivers/reset/starfive/reset-starfive-jh71x0.h
-+++ b/drivers/reset/starfive/reset-starfive-jh71x0.h
-@@ -6,6 +6,9 @@
- #ifndef __RESET_STARFIVE_JH71X0_H
- #define __RESET_STARFIVE_JH71X0_H
-
--int jh7100_reset_probe(struct platform_device *pdev);
-+int reset_starfive_jh7100_register(struct device *dev, struct device_node *of_node,
-+ void __iomem *assert, void __iomem *status,
-+ const u64 *asserted, unsigned int nr_resets,
-+ struct module *owner);
-
- #endif /* __RESET_STARFIVE_JH71X0_H */
diff --git a/target/linux/starfive/patches-6.1/0011-reset-starfive-Rename-jh7100-to-jh71x0-for-the-commo.patch b/target/linux/starfive/patches-6.1/0011-reset-starfive-Rename-jh7100-to-jh71x0-for-the-commo.patch
deleted file mode 100644
index 144d847725..0000000000
--- a/target/linux/starfive/patches-6.1/0011-reset-starfive-Rename-jh7100-to-jh71x0-for-the-commo.patch
+++ /dev/null
@@ -1,167 +0,0 @@
-From 798b9b4681be53ddbf1d8db8a88ff19aaaca500f Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Sat, 1 Apr 2023 19:19:23 +0800
-Subject: [PATCH 011/122] reset: starfive: Rename "jh7100" to "jh71x0" for the
- common code
-
-For the common code will be shared with the StarFive JH7110 SoC.
-
-Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
-Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
-Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
-Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
----
- .../reset/starfive/reset-starfive-jh7100.c | 2 +-
- .../reset/starfive/reset-starfive-jh71x0.c | 50 +++++++++----------
- .../reset/starfive/reset-starfive-jh71x0.h | 2 +-
- 3 files changed, 27 insertions(+), 27 deletions(-)
-
---- a/drivers/reset/starfive/reset-starfive-jh7100.c
-+++ b/drivers/reset/starfive/reset-starfive-jh7100.c
-@@ -51,7 +51,7 @@ static int __init jh7100_reset_probe(str
- if (IS_ERR(base))
- return PTR_ERR(base);
-
-- return reset_starfive_jh7100_register(&pdev->dev, pdev->dev.of_node,
-+ return reset_starfive_jh71x0_register(&pdev->dev, pdev->dev.of_node,
- base + JH7100_RESET_ASSERT0,
- base + JH7100_RESET_STATUS0,
- jh7100_reset_asserted,
---- a/drivers/reset/starfive/reset-starfive-jh71x0.c
-+++ b/drivers/reset/starfive/reset-starfive-jh71x0.c
-@@ -1,6 +1,6 @@
- // SPDX-License-Identifier: GPL-2.0-or-later
- /*
-- * Reset driver for the StarFive JH7100 SoC
-+ * Reset driver for the StarFive JH71X0 SoCs
- *
- * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
- */
-@@ -15,7 +15,7 @@
-
- #include "reset-starfive-jh71x0.h"
-
--struct jh7100_reset {
-+struct jh71x0_reset {
- struct reset_controller_dev rcdev;
- /* protect registers against concurrent read-modify-write */
- spinlock_t lock;
-@@ -24,16 +24,16 @@ struct jh7100_reset {
- const u64 *asserted;
- };
-
--static inline struct jh7100_reset *
--jh7100_reset_from(struct reset_controller_dev *rcdev)
-+static inline struct jh71x0_reset *
-+jh71x0_reset_from(struct reset_controller_dev *rcdev)
- {
-- return container_of(rcdev, struct jh7100_reset, rcdev);
-+ return container_of(rcdev, struct jh71x0_reset, rcdev);
- }
-
--static int jh7100_reset_update(struct reset_controller_dev *rcdev,
-+static int jh71x0_reset_update(struct reset_controller_dev *rcdev,
- unsigned long id, bool assert)
- {
-- struct jh7100_reset *data = jh7100_reset_from(rcdev);
-+ struct jh71x0_reset *data = jh71x0_reset_from(rcdev);
- unsigned long offset = BIT_ULL_WORD(id);
- u64 mask = BIT_ULL_MASK(id);
- void __iomem *reg_assert = data->assert + offset * sizeof(u64);
-@@ -62,34 +62,34 @@ static int jh7100_reset_update(struct re
- return ret;
- }
-
--static int jh7100_reset_assert(struct reset_controller_dev *rcdev,
-+static int jh71x0_reset_assert(struct reset_controller_dev *rcdev,
- unsigned long id)
- {
-- return jh7100_reset_update(rcdev, id, true);
-+ return jh71x0_reset_update(rcdev, id, true);
- }
-
--static int jh7100_reset_deassert(struct reset_controller_dev *rcdev,
-+static int jh71x0_reset_deassert(struct reset_controller_dev *rcdev,
- unsigned long id)
- {
-- return jh7100_reset_update(rcdev, id, false);
-+ return jh71x0_reset_update(rcdev, id, false);
- }
-
--static int jh7100_reset_reset(struct reset_controller_dev *rcdev,
-+static int jh71x0_reset_reset(struct reset_controller_dev *rcdev,
- unsigned long id)
- {
- int ret;
-
-- ret = jh7100_reset_assert(rcdev, id);
-+ ret = jh71x0_reset_assert(rcdev, id);
- if (ret)
- return ret;
-
-- return jh7100_reset_deassert(rcdev, id);
-+ return jh71x0_reset_deassert(rcdev, id);
- }
-
--static int jh7100_reset_status(struct reset_controller_dev *rcdev,
-+static int jh71x0_reset_status(struct reset_controller_dev *rcdev,
- unsigned long id)
- {
-- struct jh7100_reset *data = jh7100_reset_from(rcdev);
-+ struct jh71x0_reset *data = jh71x0_reset_from(rcdev);
- unsigned long offset = BIT_ULL_WORD(id);
- u64 mask = BIT_ULL_MASK(id);
- void __iomem *reg_status = data->status + offset * sizeof(u64);
-@@ -98,25 +98,25 @@ static int jh7100_reset_status(struct re
- return !((value ^ data->asserted[offset]) & mask);
- }
-
--static const struct reset_control_ops jh7100_reset_ops = {
-- .assert = jh7100_reset_assert,
-- .deassert = jh7100_reset_deassert,
-- .reset = jh7100_reset_reset,
-- .status = jh7100_reset_status,
-+static const struct reset_control_ops jh71x0_reset_ops = {
-+ .assert = jh71x0_reset_assert,
-+ .deassert = jh71x0_reset_deassert,
-+ .reset = jh71x0_reset_reset,
-+ .status = jh71x0_reset_status,
- };
-
--int reset_starfive_jh7100_register(struct device *dev, struct device_node *of_node,
-+int reset_starfive_jh71x0_register(struct device *dev, struct device_node *of_node,
- void __iomem *assert, void __iomem *status,
- const u64 *asserted, unsigned int nr_resets,
- struct module *owner)
- {
-- struct jh7100_reset *data;
-+ struct jh71x0_reset *data;
-
- data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
- if (!data)
- return -ENOMEM;
-
-- data->rcdev.ops = &jh7100_reset_ops;
-+ data->rcdev.ops = &jh71x0_reset_ops;
- data->rcdev.owner = owner;
- data->rcdev.nr_resets = nr_resets;
- data->rcdev.dev = dev;
-@@ -129,4 +129,4 @@ int reset_starfive_jh7100_register(struc
-
- return devm_reset_controller_register(dev, &data->rcdev);
- }
--EXPORT_SYMBOL_GPL(reset_starfive_jh7100_register);
-+EXPORT_SYMBOL_GPL(reset_starfive_jh71x0_register);
---- a/drivers/reset/starfive/reset-starfive-jh71x0.h
-+++ b/drivers/reset/starfive/reset-starfive-jh71x0.h
-@@ -6,7 +6,7 @@
- #ifndef __RESET_STARFIVE_JH71X0_H
- #define __RESET_STARFIVE_JH71X0_H
-
--int reset_starfive_jh7100_register(struct device *dev, struct device_node *of_node,
-+int reset_starfive_jh71x0_register(struct device *dev, struct device_node *of_node,
- void __iomem *assert, void __iomem *status,
- const u64 *asserted, unsigned int nr_resets,
- struct module *owner);
diff --git a/target/linux/starfive/patches-6.1/0012-reset-starfive-jh71x0-Use-32bit-I-O-on-32bit-registe.patch b/target/linux/starfive/patches-6.1/0012-reset-starfive-jh71x0-Use-32bit-I-O-on-32bit-registe.patch
deleted file mode 100644
index 459ac5a3b6..0000000000
--- a/target/linux/starfive/patches-6.1/0012-reset-starfive-jh71x0-Use-32bit-I-O-on-32bit-registe.patch
+++ /dev/null
@@ -1,146 +0,0 @@
-From 365bb978e5e11a16c362d9c2c64d7bf8d04999df Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Sat, 1 Apr 2023 19:19:24 +0800
-Subject: [PATCH 012/122] reset: starfive: jh71x0: Use 32bit I/O on 32bit
- registers
-
-We currently use 64bit I/O on the 32bit registers. This works because
-there are an even number of assert and status registers, so they're only
-ever accessed in pairs on 64bit boundaries.
-
-There are however other reset controllers for audio and video on the
-JH7100 SoC with only one status register that isn't 64bit aligned so
-64bit I/O results in an unaligned access exception.
-
-Switch to 32bit I/O in preparation for supporting these resets too.
-
-Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
-Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
-Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
-Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
----
- .../reset/starfive/reset-starfive-jh7100.c | 14 ++++-----
- .../reset/starfive/reset-starfive-jh71x0.c | 31 +++++++++----------
- .../reset/starfive/reset-starfive-jh71x0.h | 2 +-
- 3 files changed, 23 insertions(+), 24 deletions(-)
-
---- a/drivers/reset/starfive/reset-starfive-jh7100.c
-+++ b/drivers/reset/starfive/reset-starfive-jh7100.c
-@@ -30,16 +30,16 @@
- * lines don't though, so store the expected value of the status registers when
- * all lines are asserted.
- */
--static const u64 jh7100_reset_asserted[2] = {
-+static const u32 jh7100_reset_asserted[4] = {
- /* STATUS0 */
-- BIT_ULL_MASK(JH7100_RST_U74) |
-- BIT_ULL_MASK(JH7100_RST_VP6_DRESET) |
-- BIT_ULL_MASK(JH7100_RST_VP6_BRESET) |
-+ BIT(JH7100_RST_U74 % 32) |
-+ BIT(JH7100_RST_VP6_DRESET % 32) |
-+ BIT(JH7100_RST_VP6_BRESET % 32),
- /* STATUS1 */
-- BIT_ULL_MASK(JH7100_RST_HIFI4_DRESET) |
-- BIT_ULL_MASK(JH7100_RST_HIFI4_BRESET),
-+ BIT(JH7100_RST_HIFI4_DRESET % 32) |
-+ BIT(JH7100_RST_HIFI4_BRESET % 32),
- /* STATUS2 */
-- BIT_ULL_MASK(JH7100_RST_E24) |
-+ BIT(JH7100_RST_E24 % 32),
- /* STATUS3 */
- 0,
- };
---- a/drivers/reset/starfive/reset-starfive-jh71x0.c
-+++ b/drivers/reset/starfive/reset-starfive-jh71x0.c
-@@ -8,7 +8,6 @@
- #include <linux/bitmap.h>
- #include <linux/device.h>
- #include <linux/io.h>
--#include <linux/io-64-nonatomic-lo-hi.h>
- #include <linux/iopoll.h>
- #include <linux/reset-controller.h>
- #include <linux/spinlock.h>
-@@ -21,7 +20,7 @@ struct jh71x0_reset {
- spinlock_t lock;
- void __iomem *assert;
- void __iomem *status;
-- const u64 *asserted;
-+ const u32 *asserted;
- };
-
- static inline struct jh71x0_reset *
-@@ -34,12 +33,12 @@ static int jh71x0_reset_update(struct re
- unsigned long id, bool assert)
- {
- struct jh71x0_reset *data = jh71x0_reset_from(rcdev);
-- unsigned long offset = BIT_ULL_WORD(id);
-- u64 mask = BIT_ULL_MASK(id);
-- void __iomem *reg_assert = data->assert + offset * sizeof(u64);
-- void __iomem *reg_status = data->status + offset * sizeof(u64);
-- u64 done = data->asserted ? data->asserted[offset] & mask : 0;
-- u64 value;
-+ unsigned long offset = id / 32;
-+ u32 mask = BIT(id % 32);
-+ void __iomem *reg_assert = data->assert + offset * sizeof(u32);
-+ void __iomem *reg_status = data->status + offset * sizeof(u32);
-+ u32 done = data->asserted ? data->asserted[offset] & mask : 0;
-+ u32 value;
- unsigned long flags;
- int ret;
-
-@@ -48,15 +47,15 @@ static int jh71x0_reset_update(struct re
-
- spin_lock_irqsave(&data->lock, flags);
-
-- value = readq(reg_assert);
-+ value = readl(reg_assert);
- if (assert)
- value |= mask;
- else
- value &= ~mask;
-- writeq(value, reg_assert);
-+ writel(value, reg_assert);
-
- /* if the associated clock is gated, deasserting might otherwise hang forever */
-- ret = readq_poll_timeout_atomic(reg_status, value, (value & mask) == done, 0, 1000);
-+ ret = readl_poll_timeout_atomic(reg_status, value, (value & mask) == done, 0, 1000);
-
- spin_unlock_irqrestore(&data->lock, flags);
- return ret;
-@@ -90,10 +89,10 @@ static int jh71x0_reset_status(struct re
- unsigned long id)
- {
- struct jh71x0_reset *data = jh71x0_reset_from(rcdev);
-- unsigned long offset = BIT_ULL_WORD(id);
-- u64 mask = BIT_ULL_MASK(id);
-- void __iomem *reg_status = data->status + offset * sizeof(u64);
-- u64 value = readq(reg_status);
-+ unsigned long offset = id / 32;
-+ u32 mask = BIT(id % 32);
-+ void __iomem *reg_status = data->status + offset * sizeof(u32);
-+ u32 value = readl(reg_status);
-
- return !((value ^ data->asserted[offset]) & mask);
- }
-@@ -107,7 +106,7 @@ static const struct reset_control_ops jh
-
- int reset_starfive_jh71x0_register(struct device *dev, struct device_node *of_node,
- void __iomem *assert, void __iomem *status,
-- const u64 *asserted, unsigned int nr_resets,
-+ const u32 *asserted, unsigned int nr_resets,
- struct module *owner)
- {
- struct jh71x0_reset *data;
---- a/drivers/reset/starfive/reset-starfive-jh71x0.h
-+++ b/drivers/reset/starfive/reset-starfive-jh71x0.h
-@@ -8,7 +8,7 @@
-
- int reset_starfive_jh71x0_register(struct device *dev, struct device_node *of_node,
- void __iomem *assert, void __iomem *status,
-- const u64 *asserted, unsigned int nr_resets,
-+ const u32 *asserted, unsigned int nr_resets,
- struct module *owner);
-
- #endif /* __RESET_STARFIVE_JH71X0_H */
diff --git a/target/linux/starfive/patches-6.1/0013-clk-starfive-Add-StarFive-JH7110-system-clock-driver.patch b/target/linux/starfive/patches-6.1/0013-clk-starfive-Add-StarFive-JH7110-system-clock-driver.patch
deleted file mode 100644
index f272d5179b..0000000000
--- a/target/linux/starfive/patches-6.1/0013-clk-starfive-Add-StarFive-JH7110-system-clock-driver.patch
+++ /dev/null
@@ -1,557 +0,0 @@
-From eea853275c704f6c24a418a50715bc5ad68a6283 Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Sat, 1 Apr 2023 19:19:25 +0800
-Subject: [PATCH 013/122] clk: starfive: Add StarFive JH7110 system clock
- driver
-
-Add driver for the StarFive JH7110 system clock controller and
-register an auxiliary device for system reset controller which
-is named as "rst-sys".
-
-Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
-Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
-Co-developed-by: Hal Feng <hal.feng@starfivetech.com>
-Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
-Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
----
- drivers/clk/starfive/Kconfig | 11 +
- drivers/clk/starfive/Makefile | 2 +
- .../clk/starfive/clk-starfive-jh7110-sys.c | 490 ++++++++++++++++++
- drivers/clk/starfive/clk-starfive-jh7110.h | 11 +
- 4 files changed, 514 insertions(+)
- create mode 100644 drivers/clk/starfive/clk-starfive-jh7110-sys.c
- create mode 100644 drivers/clk/starfive/clk-starfive-jh7110.h
-
---- a/drivers/clk/starfive/Kconfig
-+++ b/drivers/clk/starfive/Kconfig
-@@ -20,3 +20,14 @@ config CLK_STARFIVE_JH7100_AUDIO
- help
- Say Y or M here to support the audio clocks on the StarFive JH7100
- SoC.
-+
-+config CLK_STARFIVE_JH7110_SYS
-+ bool "StarFive JH7110 system clock support"
-+ depends on ARCH_STARFIVE || COMPILE_TEST
-+ select AUXILIARY_BUS
-+ select CLK_STARFIVE_JH71X0
-+ select RESET_STARFIVE_JH7110
-+ default ARCH_STARFIVE
-+ help
-+ Say yes here to support the system clock controller on the
-+ StarFive JH7110 SoC.
---- a/drivers/clk/starfive/Makefile
-+++ b/drivers/clk/starfive/Makefile
-@@ -3,3 +3,5 @@ obj-$(CONFIG_CLK_STARFIVE_JH71X0) += clk
-
- obj-$(CONFIG_CLK_STARFIVE_JH7100) += clk-starfive-jh7100.o
- obj-$(CONFIG_CLK_STARFIVE_JH7100_AUDIO) += clk-starfive-jh7100-audio.o
-+
-+obj-$(CONFIG_CLK_STARFIVE_JH7110_SYS) += clk-starfive-jh7110-sys.o
---- /dev/null
-+++ b/drivers/clk/starfive/clk-starfive-jh7110-sys.c
-@@ -0,0 +1,490 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * StarFive JH7110 System Clock Driver
-+ *
-+ * Copyright (C) 2022 Emil Renner Berthing <kernel@esmil.dk>
-+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
-+ */
-+
-+#include <linux/auxiliary_bus.h>
-+#include <linux/clk-provider.h>
-+#include <linux/init.h>
-+#include <linux/io.h>
-+#include <linux/platform_device.h>
-+
-+#include <dt-bindings/clock/starfive,jh7110-crg.h>
-+
-+#include "clk-starfive-jh7110.h"
-+
-+/* external clocks */
-+#define JH7110_SYSCLK_OSC (JH7110_SYSCLK_END + 0)
-+#define JH7110_SYSCLK_GMAC1_RMII_REFIN (JH7110_SYSCLK_END + 1)
-+#define JH7110_SYSCLK_GMAC1_RGMII_RXIN (JH7110_SYSCLK_END + 2)
-+#define JH7110_SYSCLK_I2STX_BCLK_EXT (JH7110_SYSCLK_END + 3)
-+#define JH7110_SYSCLK_I2STX_LRCK_EXT (JH7110_SYSCLK_END + 4)
-+#define JH7110_SYSCLK_I2SRX_BCLK_EXT (JH7110_SYSCLK_END + 5)
-+#define JH7110_SYSCLK_I2SRX_LRCK_EXT (JH7110_SYSCLK_END + 6)
-+#define JH7110_SYSCLK_TDM_EXT (JH7110_SYSCLK_END + 7)
-+#define JH7110_SYSCLK_MCLK_EXT (JH7110_SYSCLK_END + 8)
-+#define JH7110_SYSCLK_PLL0_OUT (JH7110_SYSCLK_END + 9)
-+#define JH7110_SYSCLK_PLL1_OUT (JH7110_SYSCLK_END + 10)
-+#define JH7110_SYSCLK_PLL2_OUT (JH7110_SYSCLK_END + 11)
-+
-+static const struct jh71x0_clk_data jh7110_sysclk_data[] __initconst = {
-+ /* root */
-+ JH71X0__MUX(JH7110_SYSCLK_CPU_ROOT, "cpu_root", 2,
-+ JH7110_SYSCLK_OSC,
-+ JH7110_SYSCLK_PLL0_OUT),
-+ JH71X0__DIV(JH7110_SYSCLK_CPU_CORE, "cpu_core", 7, JH7110_SYSCLK_CPU_ROOT),
-+ JH71X0__DIV(JH7110_SYSCLK_CPU_BUS, "cpu_bus", 2, JH7110_SYSCLK_CPU_CORE),
-+ JH71X0__MUX(JH7110_SYSCLK_GPU_ROOT, "gpu_root", 2,
-+ JH7110_SYSCLK_PLL2_OUT,
-+ JH7110_SYSCLK_PLL1_OUT),
-+ JH71X0_MDIV(JH7110_SYSCLK_PERH_ROOT, "perh_root", 2, 2,
-+ JH7110_SYSCLK_PLL0_OUT,
-+ JH7110_SYSCLK_PLL2_OUT),
-+ JH71X0__MUX(JH7110_SYSCLK_BUS_ROOT, "bus_root", 2,
-+ JH7110_SYSCLK_OSC,
-+ JH7110_SYSCLK_PLL2_OUT),
-+ JH71X0__DIV(JH7110_SYSCLK_NOCSTG_BUS, "nocstg_bus", 3, JH7110_SYSCLK_BUS_ROOT),
-+ JH71X0__DIV(JH7110_SYSCLK_AXI_CFG0, "axi_cfg0", 3, JH7110_SYSCLK_BUS_ROOT),
-+ JH71X0__DIV(JH7110_SYSCLK_STG_AXIAHB, "stg_axiahb", 2, JH7110_SYSCLK_AXI_CFG0),
-+ JH71X0_GATE(JH7110_SYSCLK_AHB0, "ahb0", CLK_IS_CRITICAL, JH7110_SYSCLK_STG_AXIAHB),
-+ JH71X0_GATE(JH7110_SYSCLK_AHB1, "ahb1", CLK_IS_CRITICAL, JH7110_SYSCLK_STG_AXIAHB),
-+ JH71X0__DIV(JH7110_SYSCLK_APB_BUS, "apb_bus", 8, JH7110_SYSCLK_STG_AXIAHB),
-+ JH71X0_GATE(JH7110_SYSCLK_APB0, "apb0", CLK_IS_CRITICAL, JH7110_SYSCLK_APB_BUS),
-+ JH71X0__DIV(JH7110_SYSCLK_PLL0_DIV2, "pll0_div2", 2, JH7110_SYSCLK_PLL0_OUT),
-+ JH71X0__DIV(JH7110_SYSCLK_PLL1_DIV2, "pll1_div2", 2, JH7110_SYSCLK_PLL1_OUT),
-+ JH71X0__DIV(JH7110_SYSCLK_PLL2_DIV2, "pll2_div2", 2, JH7110_SYSCLK_PLL2_OUT),
-+ JH71X0__DIV(JH7110_SYSCLK_AUDIO_ROOT, "audio_root", 8, JH7110_SYSCLK_PLL2_OUT),
-+ JH71X0__DIV(JH7110_SYSCLK_MCLK_INNER, "mclk_inner", 64, JH7110_SYSCLK_AUDIO_ROOT),
-+ JH71X0__MUX(JH7110_SYSCLK_MCLK, "mclk", 2,
-+ JH7110_SYSCLK_MCLK_INNER,
-+ JH7110_SYSCLK_MCLK_EXT),
-+ JH71X0_GATE(JH7110_SYSCLK_MCLK_OUT, "mclk_out", 0, JH7110_SYSCLK_MCLK_INNER),
-+ JH71X0_MDIV(JH7110_SYSCLK_ISP_2X, "isp_2x", 8, 2,
-+ JH7110_SYSCLK_PLL2_OUT,
-+ JH7110_SYSCLK_PLL1_OUT),
-+ JH71X0__DIV(JH7110_SYSCLK_ISP_AXI, "isp_axi", 4, JH7110_SYSCLK_ISP_2X),
-+ JH71X0_GDIV(JH7110_SYSCLK_GCLK0, "gclk0", 0, 62, JH7110_SYSCLK_PLL0_DIV2),
-+ JH71X0_GDIV(JH7110_SYSCLK_GCLK1, "gclk1", 0, 62, JH7110_SYSCLK_PLL1_DIV2),
-+ JH71X0_GDIV(JH7110_SYSCLK_GCLK2, "gclk2", 0, 62, JH7110_SYSCLK_PLL2_DIV2),
-+ /* cores */
-+ JH71X0_GATE(JH7110_SYSCLK_CORE, "core", CLK_IS_CRITICAL, JH7110_SYSCLK_CPU_CORE),
-+ JH71X0_GATE(JH7110_SYSCLK_CORE1, "core1", CLK_IS_CRITICAL, JH7110_SYSCLK_CPU_CORE),
-+ JH71X0_GATE(JH7110_SYSCLK_CORE2, "core2", CLK_IS_CRITICAL, JH7110_SYSCLK_CPU_CORE),
-+ JH71X0_GATE(JH7110_SYSCLK_CORE3, "core3", CLK_IS_CRITICAL, JH7110_SYSCLK_CPU_CORE),
-+ JH71X0_GATE(JH7110_SYSCLK_CORE4, "core4", CLK_IS_CRITICAL, JH7110_SYSCLK_CPU_CORE),
-+ JH71X0_GATE(JH7110_SYSCLK_DEBUG, "debug", 0, JH7110_SYSCLK_CPU_BUS),
-+ JH71X0__DIV(JH7110_SYSCLK_RTC_TOGGLE, "rtc_toggle", 6, JH7110_SYSCLK_OSC),
-+ JH71X0_GATE(JH7110_SYSCLK_TRACE0, "trace0", 0, JH7110_SYSCLK_CPU_CORE),
-+ JH71X0_GATE(JH7110_SYSCLK_TRACE1, "trace1", 0, JH7110_SYSCLK_CPU_CORE),
-+ JH71X0_GATE(JH7110_SYSCLK_TRACE2, "trace2", 0, JH7110_SYSCLK_CPU_CORE),
-+ JH71X0_GATE(JH7110_SYSCLK_TRACE3, "trace3", 0, JH7110_SYSCLK_CPU_CORE),
-+ JH71X0_GATE(JH7110_SYSCLK_TRACE4, "trace4", 0, JH7110_SYSCLK_CPU_CORE),
-+ JH71X0_GATE(JH7110_SYSCLK_TRACE_COM, "trace_com", 0, JH7110_SYSCLK_CPU_BUS),
-+ /* noc */
-+ JH71X0_GATE(JH7110_SYSCLK_NOC_BUS_CPU_AXI, "noc_bus_cpu_axi", CLK_IS_CRITICAL,
-+ JH7110_SYSCLK_CPU_BUS),
-+ JH71X0_GATE(JH7110_SYSCLK_NOC_BUS_AXICFG0_AXI, "noc_bus_axicfg0_axi", CLK_IS_CRITICAL,
-+ JH7110_SYSCLK_AXI_CFG0),
-+ /* ddr */
-+ JH71X0__DIV(JH7110_SYSCLK_OSC_DIV2, "osc_div2", 2, JH7110_SYSCLK_OSC),
-+ JH71X0__DIV(JH7110_SYSCLK_PLL1_DIV4, "pll1_div4", 2, JH7110_SYSCLK_PLL1_DIV2),
-+ JH71X0__DIV(JH7110_SYSCLK_PLL1_DIV8, "pll1_div8", 2, JH7110_SYSCLK_PLL1_DIV4),
-+ JH71X0__MUX(JH7110_SYSCLK_DDR_BUS, "ddr_bus", 4,
-+ JH7110_SYSCLK_OSC_DIV2,
-+ JH7110_SYSCLK_PLL1_DIV2,
-+ JH7110_SYSCLK_PLL1_DIV4,
-+ JH7110_SYSCLK_PLL1_DIV8),
-+ JH71X0_GATE(JH7110_SYSCLK_DDR_AXI, "ddr_axi", CLK_IS_CRITICAL, JH7110_SYSCLK_DDR_BUS),
-+ /* gpu */
-+ JH71X0__DIV(JH7110_SYSCLK_GPU_CORE, "gpu_core", 7, JH7110_SYSCLK_GPU_ROOT),
-+ JH71X0_GATE(JH7110_SYSCLK_GPU_CORE_CLK, "gpu_core_clk", 0, JH7110_SYSCLK_GPU_CORE),
-+ JH71X0_GATE(JH7110_SYSCLK_GPU_SYS_CLK, "gpu_sys_clk", 0, JH7110_SYSCLK_ISP_AXI),
-+ JH71X0_GATE(JH7110_SYSCLK_GPU_APB, "gpu_apb", 0, JH7110_SYSCLK_APB_BUS),
-+ JH71X0_GDIV(JH7110_SYSCLK_GPU_RTC_TOGGLE, "gpu_rtc_toggle", 0, 12, JH7110_SYSCLK_OSC),
-+ JH71X0_GATE(JH7110_SYSCLK_NOC_BUS_GPU_AXI, "noc_bus_gpu_axi", 0, JH7110_SYSCLK_GPU_CORE),
-+ /* isp */
-+ JH71X0_GATE(JH7110_SYSCLK_ISP_TOP_CORE, "isp_top_core", 0, JH7110_SYSCLK_ISP_2X),
-+ JH71X0_GATE(JH7110_SYSCLK_ISP_TOP_AXI, "isp_top_axi", 0, JH7110_SYSCLK_ISP_AXI),
-+ JH71X0_GATE(JH7110_SYSCLK_NOC_BUS_ISP_AXI, "noc_bus_isp_axi", CLK_IS_CRITICAL,
-+ JH7110_SYSCLK_ISP_AXI),
-+ /* hifi4 */
-+ JH71X0__DIV(JH7110_SYSCLK_HIFI4_CORE, "hifi4_core", 15, JH7110_SYSCLK_BUS_ROOT),
-+ JH71X0__DIV(JH7110_SYSCLK_HIFI4_AXI, "hifi4_axi", 2, JH7110_SYSCLK_HIFI4_CORE),
-+ /* axi_cfg1 */
-+ JH71X0_GATE(JH7110_SYSCLK_AXI_CFG1_MAIN, "axi_cfg1_main", CLK_IS_CRITICAL,
-+ JH7110_SYSCLK_ISP_AXI),
-+ JH71X0_GATE(JH7110_SYSCLK_AXI_CFG1_AHB, "axi_cfg1_ahb", CLK_IS_CRITICAL,
-+ JH7110_SYSCLK_AHB0),
-+ /* vout */
-+ JH71X0_GATE(JH7110_SYSCLK_VOUT_SRC, "vout_src", 0, JH7110_SYSCLK_PLL2_OUT),
-+ JH71X0__DIV(JH7110_SYSCLK_VOUT_AXI, "vout_axi", 7, JH7110_SYSCLK_PLL2_OUT),
-+ JH71X0_GATE(JH7110_SYSCLK_NOC_BUS_DISP_AXI, "noc_bus_disp_axi", 0, JH7110_SYSCLK_VOUT_AXI),
-+ JH71X0_GATE(JH7110_SYSCLK_VOUT_TOP_AHB, "vout_top_ahb", 0, JH7110_SYSCLK_AHB1),
-+ JH71X0_GATE(JH7110_SYSCLK_VOUT_TOP_AXI, "vout_top_axi", 0, JH7110_SYSCLK_VOUT_AXI),
-+ JH71X0_GATE(JH7110_SYSCLK_VOUT_TOP_HDMITX0_MCLK, "vout_top_hdmitx0_mclk", 0,
-+ JH7110_SYSCLK_MCLK),
-+ JH71X0__DIV(JH7110_SYSCLK_VOUT_TOP_MIPIPHY_REF, "vout_top_mipiphy_ref", 2,
-+ JH7110_SYSCLK_OSC),
-+ /* jpegc */
-+ JH71X0__DIV(JH7110_SYSCLK_JPEGC_AXI, "jpegc_axi", 16, JH7110_SYSCLK_PLL2_OUT),
-+ JH71X0_GATE(JH7110_SYSCLK_CODAJ12_AXI, "codaj12_axi", 0, JH7110_SYSCLK_JPEGC_AXI),
-+ JH71X0_GDIV(JH7110_SYSCLK_CODAJ12_CORE, "codaj12_core", 0, 16, JH7110_SYSCLK_PLL2_OUT),
-+ JH71X0_GATE(JH7110_SYSCLK_CODAJ12_APB, "codaj12_apb", 0, JH7110_SYSCLK_APB_BUS),
-+ /* vdec */
-+ JH71X0__DIV(JH7110_SYSCLK_VDEC_AXI, "vdec_axi", 7, JH7110_SYSCLK_BUS_ROOT),
-+ JH71X0_GATE(JH7110_SYSCLK_WAVE511_AXI, "wave511_axi", 0, JH7110_SYSCLK_VDEC_AXI),
-+ JH71X0_GDIV(JH7110_SYSCLK_WAVE511_BPU, "wave511_bpu", 0, 7, JH7110_SYSCLK_BUS_ROOT),
-+ JH71X0_GDIV(JH7110_SYSCLK_WAVE511_VCE, "wave511_vce", 0, 7, JH7110_SYSCLK_PLL0_OUT),
-+ JH71X0_GATE(JH7110_SYSCLK_WAVE511_APB, "wave511_apb", 0, JH7110_SYSCLK_APB_BUS),
-+ JH71X0_GATE(JH7110_SYSCLK_VDEC_JPG, "vdec_jpg", 0, JH7110_SYSCLK_JPEGC_AXI),
-+ JH71X0_GATE(JH7110_SYSCLK_VDEC_MAIN, "vdec_main", 0, JH7110_SYSCLK_VDEC_AXI),
-+ JH71X0_GATE(JH7110_SYSCLK_NOC_BUS_VDEC_AXI, "noc_bus_vdec_axi", 0, JH7110_SYSCLK_VDEC_AXI),
-+ /* venc */
-+ JH71X0__DIV(JH7110_SYSCLK_VENC_AXI, "venc_axi", 15, JH7110_SYSCLK_PLL2_OUT),
-+ JH71X0_GATE(JH7110_SYSCLK_WAVE420L_AXI, "wave420l_axi", 0, JH7110_SYSCLK_VENC_AXI),
-+ JH71X0_GDIV(JH7110_SYSCLK_WAVE420L_BPU, "wave420l_bpu", 0, 15, JH7110_SYSCLK_PLL2_OUT),
-+ JH71X0_GDIV(JH7110_SYSCLK_WAVE420L_VCE, "wave420l_vce", 0, 15, JH7110_SYSCLK_PLL2_OUT),
-+ JH71X0_GATE(JH7110_SYSCLK_WAVE420L_APB, "wave420l_apb", 0, JH7110_SYSCLK_APB_BUS),
-+ JH71X0_GATE(JH7110_SYSCLK_NOC_BUS_VENC_AXI, "noc_bus_venc_axi", 0, JH7110_SYSCLK_VENC_AXI),
-+ /* axi_cfg0 */
-+ JH71X0_GATE(JH7110_SYSCLK_AXI_CFG0_MAIN_DIV, "axi_cfg0_main_div", CLK_IS_CRITICAL,
-+ JH7110_SYSCLK_AHB1),
-+ JH71X0_GATE(JH7110_SYSCLK_AXI_CFG0_MAIN, "axi_cfg0_main", CLK_IS_CRITICAL,
-+ JH7110_SYSCLK_AXI_CFG0),
-+ JH71X0_GATE(JH7110_SYSCLK_AXI_CFG0_HIFI4, "axi_cfg0_hifi4", CLK_IS_CRITICAL,
-+ JH7110_SYSCLK_HIFI4_AXI),
-+ /* intmem */
-+ JH71X0_GATE(JH7110_SYSCLK_AXIMEM2_AXI, "aximem2_axi", 0, JH7110_SYSCLK_AXI_CFG0),
-+ /* qspi */
-+ JH71X0_GATE(JH7110_SYSCLK_QSPI_AHB, "qspi_ahb", 0, JH7110_SYSCLK_AHB1),
-+ JH71X0_GATE(JH7110_SYSCLK_QSPI_APB, "qspi_apb", 0, JH7110_SYSCLK_APB_BUS),
-+ JH71X0__DIV(JH7110_SYSCLK_QSPI_REF_SRC, "qspi_ref_src", 16, JH7110_SYSCLK_PLL0_OUT),
-+ JH71X0_GMUX(JH7110_SYSCLK_QSPI_REF, "qspi_ref", 0, 2,
-+ JH7110_SYSCLK_OSC,
-+ JH7110_SYSCLK_QSPI_REF_SRC),
-+ /* sdio */
-+ JH71X0_GATE(JH7110_SYSCLK_SDIO0_AHB, "sdio0_ahb", 0, JH7110_SYSCLK_AHB0),
-+ JH71X0_GATE(JH7110_SYSCLK_SDIO1_AHB, "sdio1_ahb", 0, JH7110_SYSCLK_AHB0),
-+ JH71X0_GDIV(JH7110_SYSCLK_SDIO0_SDCARD, "sdio0_sdcard", 0, 15, JH7110_SYSCLK_AXI_CFG0),
-+ JH71X0_GDIV(JH7110_SYSCLK_SDIO1_SDCARD, "sdio1_sdcard", 0, 15, JH7110_SYSCLK_AXI_CFG0),
-+ /* stg */
-+ JH71X0__DIV(JH7110_SYSCLK_USB_125M, "usb_125m", 15, JH7110_SYSCLK_PLL0_OUT),
-+ JH71X0_GATE(JH7110_SYSCLK_NOC_BUS_STG_AXI, "noc_bus_stg_axi", CLK_IS_CRITICAL,
-+ JH7110_SYSCLK_NOCSTG_BUS),
-+ /* gmac1 */
-+ JH71X0_GATE(JH7110_SYSCLK_GMAC1_AHB, "gmac1_ahb", 0, JH7110_SYSCLK_AHB0),
-+ JH71X0_GATE(JH7110_SYSCLK_GMAC1_AXI, "gmac1_axi", 0, JH7110_SYSCLK_STG_AXIAHB),
-+ JH71X0__DIV(JH7110_SYSCLK_GMAC_SRC, "gmac_src", 7, JH7110_SYSCLK_PLL0_OUT),
-+ JH71X0__DIV(JH7110_SYSCLK_GMAC1_GTXCLK, "gmac1_gtxclk", 15, JH7110_SYSCLK_PLL0_OUT),
-+ JH71X0__DIV(JH7110_SYSCLK_GMAC1_RMII_RTX, "gmac1_rmii_rtx", 30,
-+ JH7110_SYSCLK_GMAC1_RMII_REFIN),
-+ JH71X0_GDIV(JH7110_SYSCLK_GMAC1_PTP, "gmac1_ptp", 0, 31, JH7110_SYSCLK_GMAC_SRC),
-+ JH71X0__MUX(JH7110_SYSCLK_GMAC1_RX, "gmac1_rx", 2,
-+ JH7110_SYSCLK_GMAC1_RGMII_RXIN,
-+ JH7110_SYSCLK_GMAC1_RMII_RTX),
-+ JH71X0__INV(JH7110_SYSCLK_GMAC1_RX_INV, "gmac1_rx_inv", JH7110_SYSCLK_GMAC1_RX),
-+ JH71X0_GMUX(JH7110_SYSCLK_GMAC1_TX, "gmac1_tx",
-+ CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, 2,
-+ JH7110_SYSCLK_GMAC1_GTXCLK,
-+ JH7110_SYSCLK_GMAC1_RMII_RTX),
-+ JH71X0__INV(JH7110_SYSCLK_GMAC1_TX_INV, "gmac1_tx_inv", JH7110_SYSCLK_GMAC1_TX),
-+ JH71X0_GATE(JH7110_SYSCLK_GMAC1_GTXC, "gmac1_gtxc", 0, JH7110_SYSCLK_GMAC1_GTXCLK),
-+ /* gmac0 */
-+ JH71X0_GDIV(JH7110_SYSCLK_GMAC0_GTXCLK, "gmac0_gtxclk", 0, 15, JH7110_SYSCLK_PLL0_OUT),
-+ JH71X0_GDIV(JH7110_SYSCLK_GMAC0_PTP, "gmac0_ptp", 0, 31, JH7110_SYSCLK_GMAC_SRC),
-+ JH71X0_GDIV(JH7110_SYSCLK_GMAC_PHY, "gmac_phy", 0, 31, JH7110_SYSCLK_GMAC_SRC),
-+ JH71X0_GATE(JH7110_SYSCLK_GMAC0_GTXC, "gmac0_gtxc", 0, JH7110_SYSCLK_GMAC0_GTXCLK),
-+ /* apb misc */
-+ JH71X0_GATE(JH7110_SYSCLK_IOMUX_APB, "iomux_apb", 0, JH7110_SYSCLK_APB_BUS),
-+ JH71X0_GATE(JH7110_SYSCLK_MAILBOX_APB, "mailbox_apb", 0, JH7110_SYSCLK_APB_BUS),
-+ JH71X0_GATE(JH7110_SYSCLK_INT_CTRL_APB, "int_ctrl_apb", 0, JH7110_SYSCLK_APB_BUS),
-+ /* can0 */
-+ JH71X0_GATE(JH7110_SYSCLK_CAN0_APB, "can0_apb", 0, JH7110_SYSCLK_APB_BUS),
-+ JH71X0_GDIV(JH7110_SYSCLK_CAN0_TIMER, "can0_timer", 0, 24, JH7110_SYSCLK_OSC),
-+ JH71X0_GDIV(JH7110_SYSCLK_CAN0_CAN, "can0_can", 0, 63, JH7110_SYSCLK_PERH_ROOT),
-+ /* can1 */
-+ JH71X0_GATE(JH7110_SYSCLK_CAN1_APB, "can1_apb", 0, JH7110_SYSCLK_APB_BUS),
-+ JH71X0_GDIV(JH7110_SYSCLK_CAN1_TIMER, "can1_timer", 0, 24, JH7110_SYSCLK_OSC),
-+ JH71X0_GDIV(JH7110_SYSCLK_CAN1_CAN, "can1_can", 0, 63, JH7110_SYSCLK_PERH_ROOT),
-+ /* pwm */
-+ JH71X0_GATE(JH7110_SYSCLK_PWM_APB, "pwm_apb", 0, JH7110_SYSCLK_APB_BUS),
-+ /* wdt */
-+ JH71X0_GATE(JH7110_SYSCLK_WDT_APB, "wdt_apb", 0, JH7110_SYSCLK_APB_BUS),
-+ JH71X0_GATE(JH7110_SYSCLK_WDT_CORE, "wdt_core", 0, JH7110_SYSCLK_OSC),
-+ /* timer */
-+ JH71X0_GATE(JH7110_SYSCLK_TIMER_APB, "timer_apb", 0, JH7110_SYSCLK_APB_BUS),
-+ JH71X0_GATE(JH7110_SYSCLK_TIMER0, "timer0", 0, JH7110_SYSCLK_OSC),
-+ JH71X0_GATE(JH7110_SYSCLK_TIMER1, "timer1", 0, JH7110_SYSCLK_OSC),
-+ JH71X0_GATE(JH7110_SYSCLK_TIMER2, "timer2", 0, JH7110_SYSCLK_OSC),
-+ JH71X0_GATE(JH7110_SYSCLK_TIMER3, "timer3", 0, JH7110_SYSCLK_OSC),
-+ /* temp sensor */
-+ JH71X0_GATE(JH7110_SYSCLK_TEMP_APB, "temp_apb", 0, JH7110_SYSCLK_APB_BUS),
-+ JH71X0_GDIV(JH7110_SYSCLK_TEMP_CORE, "temp_core", 0, 24, JH7110_SYSCLK_OSC),
-+ /* spi */
-+ JH71X0_GATE(JH7110_SYSCLK_SPI0_APB, "spi0_apb", 0, JH7110_SYSCLK_APB0),
-+ JH71X0_GATE(JH7110_SYSCLK_SPI1_APB, "spi1_apb", 0, JH7110_SYSCLK_APB0),
-+ JH71X0_GATE(JH7110_SYSCLK_SPI2_APB, "spi2_apb", 0, JH7110_SYSCLK_APB0),
-+ JH71X0_GATE(JH7110_SYSCLK_SPI3_APB, "spi3_apb", 0, JH7110_SYSCLK_APB_BUS),
-+ JH71X0_GATE(JH7110_SYSCLK_SPI4_APB, "spi4_apb", 0, JH7110_SYSCLK_APB_BUS),
-+ JH71X0_GATE(JH7110_SYSCLK_SPI5_APB, "spi5_apb", 0, JH7110_SYSCLK_APB_BUS),
-+ JH71X0_GATE(JH7110_SYSCLK_SPI6_APB, "spi6_apb", 0, JH7110_SYSCLK_APB_BUS),
-+ /* i2c */
-+ JH71X0_GATE(JH7110_SYSCLK_I2C0_APB, "i2c0_apb", 0, JH7110_SYSCLK_APB0),
-+ JH71X0_GATE(JH7110_SYSCLK_I2C1_APB, "i2c1_apb", 0, JH7110_SYSCLK_APB0),
-+ JH71X0_GATE(JH7110_SYSCLK_I2C2_APB, "i2c2_apb", 0, JH7110_SYSCLK_APB0),
-+ JH71X0_GATE(JH7110_SYSCLK_I2C3_APB, "i2c3_apb", 0, JH7110_SYSCLK_APB_BUS),
-+ JH71X0_GATE(JH7110_SYSCLK_I2C4_APB, "i2c4_apb", 0, JH7110_SYSCLK_APB_BUS),
-+ JH71X0_GATE(JH7110_SYSCLK_I2C5_APB, "i2c5_apb", 0, JH7110_SYSCLK_APB_BUS),
-+ JH71X0_GATE(JH7110_SYSCLK_I2C6_APB, "i2c6_apb", 0, JH7110_SYSCLK_APB_BUS),
-+ /* uart */
-+ JH71X0_GATE(JH7110_SYSCLK_UART0_APB, "uart0_apb", 0, JH7110_SYSCLK_APB0),
-+ JH71X0_GATE(JH7110_SYSCLK_UART0_CORE, "uart0_core", 0, JH7110_SYSCLK_OSC),
-+ JH71X0_GATE(JH7110_SYSCLK_UART1_APB, "uart1_apb", 0, JH7110_SYSCLK_APB0),
-+ JH71X0_GATE(JH7110_SYSCLK_UART1_CORE, "uart1_core", 0, JH7110_SYSCLK_OSC),
-+ JH71X0_GATE(JH7110_SYSCLK_UART2_APB, "uart2_apb", 0, JH7110_SYSCLK_APB0),
-+ JH71X0_GATE(JH7110_SYSCLK_UART2_CORE, "uart2_core", 0, JH7110_SYSCLK_OSC),
-+ JH71X0_GATE(JH7110_SYSCLK_UART3_APB, "uart3_apb", 0, JH7110_SYSCLK_APB0),
-+ JH71X0_GDIV(JH7110_SYSCLK_UART3_CORE, "uart3_core", 0, 10, JH7110_SYSCLK_PERH_ROOT),
-+ JH71X0_GATE(JH7110_SYSCLK_UART4_APB, "uart4_apb", 0, JH7110_SYSCLK_APB0),
-+ JH71X0_GDIV(JH7110_SYSCLK_UART4_CORE, "uart4_core", 0, 10, JH7110_SYSCLK_PERH_ROOT),
-+ JH71X0_GATE(JH7110_SYSCLK_UART5_APB, "uart5_apb", 0, JH7110_SYSCLK_APB0),
-+ JH71X0_GDIV(JH7110_SYSCLK_UART5_CORE, "uart5_core", 0, 10, JH7110_SYSCLK_PERH_ROOT),
-+ /* pwmdac */
-+ JH71X0_GATE(JH7110_SYSCLK_PWMDAC_APB, "pwmdac_apb", 0, JH7110_SYSCLK_APB0),
-+ JH71X0_GDIV(JH7110_SYSCLK_PWMDAC_CORE, "pwmdac_core", 0, 256, JH7110_SYSCLK_AUDIO_ROOT),
-+ /* spdif */
-+ JH71X0_GATE(JH7110_SYSCLK_SPDIF_APB, "spdif_apb", 0, JH7110_SYSCLK_APB0),
-+ JH71X0_GATE(JH7110_SYSCLK_SPDIF_CORE, "spdif_core", 0, JH7110_SYSCLK_MCLK),
-+ /* i2stx0 */
-+ JH71X0_GATE(JH7110_SYSCLK_I2STX0_APB, "i2stx0_apb", 0, JH7110_SYSCLK_APB0),
-+ JH71X0_GDIV(JH7110_SYSCLK_I2STX0_BCLK_MST, "i2stx0_bclk_mst", 0, 32, JH7110_SYSCLK_MCLK),
-+ JH71X0__INV(JH7110_SYSCLK_I2STX0_BCLK_MST_INV, "i2stx0_bclk_mst_inv",
-+ JH7110_SYSCLK_I2STX0_BCLK_MST),
-+ JH71X0_MDIV(JH7110_SYSCLK_I2STX0_LRCK_MST, "i2stx0_lrck_mst", 64, 2,
-+ JH7110_SYSCLK_I2STX0_BCLK_MST_INV,
-+ JH7110_SYSCLK_I2STX0_BCLK_MST),
-+ JH71X0__MUX(JH7110_SYSCLK_I2STX0_BCLK, "i2stx0_bclk", 2,
-+ JH7110_SYSCLK_I2STX0_BCLK_MST,
-+ JH7110_SYSCLK_I2STX_BCLK_EXT),
-+ JH71X0__INV(JH7110_SYSCLK_I2STX0_BCLK_INV, "i2stx0_bclk_inv", JH7110_SYSCLK_I2STX0_BCLK),
-+ JH71X0__MUX(JH7110_SYSCLK_I2STX0_LRCK, "i2stx0_lrck", 2,
-+ JH7110_SYSCLK_I2STX0_LRCK_MST,
-+ JH7110_SYSCLK_I2STX_LRCK_EXT),
-+ /* i2stx1 */
-+ JH71X0_GATE(JH7110_SYSCLK_I2STX1_APB, "i2stx1_apb", 0, JH7110_SYSCLK_APB0),
-+ JH71X0_GDIV(JH7110_SYSCLK_I2STX1_BCLK_MST, "i2stx1_bclk_mst", 0, 32, JH7110_SYSCLK_MCLK),
-+ JH71X0__INV(JH7110_SYSCLK_I2STX1_BCLK_MST_INV, "i2stx1_bclk_mst_inv",
-+ JH7110_SYSCLK_I2STX1_BCLK_MST),
-+ JH71X0_MDIV(JH7110_SYSCLK_I2STX1_LRCK_MST, "i2stx1_lrck_mst", 64, 2,
-+ JH7110_SYSCLK_I2STX1_BCLK_MST_INV,
-+ JH7110_SYSCLK_I2STX1_BCLK_MST),
-+ JH71X0__MUX(JH7110_SYSCLK_I2STX1_BCLK, "i2stx1_bclk", 2,
-+ JH7110_SYSCLK_I2STX1_BCLK_MST,
-+ JH7110_SYSCLK_I2STX_BCLK_EXT),
-+ JH71X0__INV(JH7110_SYSCLK_I2STX1_BCLK_INV, "i2stx1_bclk_inv", JH7110_SYSCLK_I2STX1_BCLK),
-+ JH71X0__MUX(JH7110_SYSCLK_I2STX1_LRCK, "i2stx1_lrck", 2,
-+ JH7110_SYSCLK_I2STX1_LRCK_MST,
-+ JH7110_SYSCLK_I2STX_LRCK_EXT),
-+ /* i2srx */
-+ JH71X0_GATE(JH7110_SYSCLK_I2SRX_APB, "i2srx_apb", 0, JH7110_SYSCLK_APB0),
-+ JH71X0_GDIV(JH7110_SYSCLK_I2SRX_BCLK_MST, "i2srx_bclk_mst", 0, 32, JH7110_SYSCLK_MCLK),
-+ JH71X0__INV(JH7110_SYSCLK_I2SRX_BCLK_MST_INV, "i2srx_bclk_mst_inv",
-+ JH7110_SYSCLK_I2SRX_BCLK_MST),
-+ JH71X0_MDIV(JH7110_SYSCLK_I2SRX_LRCK_MST, "i2srx_lrck_mst", 64, 2,
-+ JH7110_SYSCLK_I2SRX_BCLK_MST_INV,
-+ JH7110_SYSCLK_I2SRX_BCLK_MST),
-+ JH71X0__MUX(JH7110_SYSCLK_I2SRX_BCLK, "i2srx_bclk", 2,
-+ JH7110_SYSCLK_I2SRX_BCLK_MST,
-+ JH7110_SYSCLK_I2SRX_BCLK_EXT),
-+ JH71X0__INV(JH7110_SYSCLK_I2SRX_BCLK_INV, "i2srx_bclk_inv", JH7110_SYSCLK_I2SRX_BCLK),
-+ JH71X0__MUX(JH7110_SYSCLK_I2SRX_LRCK, "i2srx_lrck", 2,
-+ JH7110_SYSCLK_I2SRX_LRCK_MST,
-+ JH7110_SYSCLK_I2SRX_LRCK_EXT),
-+ /* pdm */
-+ JH71X0_GDIV(JH7110_SYSCLK_PDM_DMIC, "pdm_dmic", 0, 64, JH7110_SYSCLK_MCLK),
-+ JH71X0_GATE(JH7110_SYSCLK_PDM_APB, "pdm_apb", 0, JH7110_SYSCLK_APB0),
-+ /* tdm */
-+ JH71X0_GATE(JH7110_SYSCLK_TDM_AHB, "tdm_ahb", 0, JH7110_SYSCLK_AHB0),
-+ JH71X0_GATE(JH7110_SYSCLK_TDM_APB, "tdm_apb", 0, JH7110_SYSCLK_APB0),
-+ JH71X0_GDIV(JH7110_SYSCLK_TDM_INTERNAL, "tdm_internal", 0, 64, JH7110_SYSCLK_MCLK),
-+ JH71X0__MUX(JH7110_SYSCLK_TDM_TDM, "tdm_tdm", 2,
-+ JH7110_SYSCLK_TDM_INTERNAL,
-+ JH7110_SYSCLK_TDM_EXT),
-+ JH71X0__INV(JH7110_SYSCLK_TDM_TDM_INV, "tdm_tdm_inv", JH7110_SYSCLK_TDM_TDM),
-+ /* jtag */
-+ JH71X0__DIV(JH7110_SYSCLK_JTAG_CERTIFICATION_TRNG, "jtag_certification_trng", 4,
-+ JH7110_SYSCLK_OSC),
-+};
-+
-+static struct clk_hw *jh7110_sysclk_get(struct of_phandle_args *clkspec, void *data)
-+{
-+ struct jh71x0_clk_priv *priv = data;
-+ unsigned int idx = clkspec->args[0];
-+
-+ if (idx < JH7110_SYSCLK_END)
-+ return &priv->reg[idx].hw;
-+
-+ return ERR_PTR(-EINVAL);
-+}
-+
-+static void jh7110_reset_unregister_adev(void *_adev)
-+{
-+ struct auxiliary_device *adev = _adev;
-+
-+ auxiliary_device_delete(adev);
-+}
-+
-+static void jh7110_reset_adev_release(struct device *dev)
-+{
-+ struct auxiliary_device *adev = to_auxiliary_dev(dev);
-+
-+ auxiliary_device_uninit(adev);
-+}
-+
-+int jh7110_reset_controller_register(struct jh71x0_clk_priv *priv,
-+ const char *adev_name,
-+ u32 adev_id)
-+{
-+ struct auxiliary_device *adev;
-+ int ret;
-+
-+ adev = devm_kzalloc(priv->dev, sizeof(*adev), GFP_KERNEL);
-+ if (!adev)
-+ return -ENOMEM;
-+
-+ adev->name = adev_name;
-+ adev->dev.parent = priv->dev;
-+ adev->dev.release = jh7110_reset_adev_release;
-+ adev->id = adev_id;
-+
-+ ret = auxiliary_device_init(adev);
-+ if (ret)
-+ return ret;
-+
-+ ret = auxiliary_device_add(adev);
-+ if (ret) {
-+ auxiliary_device_uninit(adev);
-+ return ret;
-+ }
-+
-+ return devm_add_action_or_reset(priv->dev,
-+ jh7110_reset_unregister_adev, adev);
-+}
-+EXPORT_SYMBOL_GPL(jh7110_reset_controller_register);
-+
-+static int __init jh7110_syscrg_probe(struct platform_device *pdev)
-+{
-+ struct jh71x0_clk_priv *priv;
-+ unsigned int idx;
-+ int ret;
-+
-+ priv = devm_kzalloc(&pdev->dev,
-+ struct_size(priv, reg, JH7110_SYSCLK_END),
-+ GFP_KERNEL);
-+ if (!priv)
-+ return -ENOMEM;
-+
-+ spin_lock_init(&priv->rmw_lock);
-+ priv->dev = &pdev->dev;
-+ priv->base = devm_platform_ioremap_resource(pdev, 0);
-+ if (IS_ERR(priv->base))
-+ return PTR_ERR(priv->base);
-+
-+ dev_set_drvdata(priv->dev, (void *)(&priv->base));
-+
-+ /*
-+ * These PLL clocks are not actually fixed factor clocks and can be
-+ * controlled by the syscon registers of JH7110. They will be dropped
-+ * and registered in the PLL clock driver instead.
-+ */
-+ /* 24MHz -> 1000.0MHz */
-+ priv->pll[0] = devm_clk_hw_register_fixed_factor(priv->dev, "pll0_out",
-+ "osc", 0, 125, 3);
-+ if (IS_ERR(priv->pll[0]))
-+ return PTR_ERR(priv->pll[0]);
-+
-+ /* 24MHz -> 1066.0MHz */
-+ priv->pll[1] = devm_clk_hw_register_fixed_factor(priv->dev, "pll1_out",
-+ "osc", 0, 533, 12);
-+ if (IS_ERR(priv->pll[1]))
-+ return PTR_ERR(priv->pll[1]);
-+
-+ /* 24MHz -> 1188.0MHz */
-+ priv->pll[2] = devm_clk_hw_register_fixed_factor(priv->dev, "pll2_out",
-+ "osc", 0, 99, 2);
-+ if (IS_ERR(priv->pll[2]))
-+ return PTR_ERR(priv->pll[2]);
-+
-+ for (idx = 0; idx < JH7110_SYSCLK_END; idx++) {
-+ u32 max = jh7110_sysclk_data[idx].max;
-+ struct clk_parent_data parents[4] = {};
-+ struct clk_init_data init = {
-+ .name = jh7110_sysclk_data[idx].name,
-+ .ops = starfive_jh71x0_clk_ops(max),
-+ .parent_data = parents,
-+ .num_parents =
-+ ((max & JH71X0_CLK_MUX_MASK) >> JH71X0_CLK_MUX_SHIFT) + 1,
-+ .flags = jh7110_sysclk_data[idx].flags,
-+ };
-+ struct jh71x0_clk *clk = &priv->reg[idx];
-+ unsigned int i;
-+
-+ for (i = 0; i < init.num_parents; i++) {
-+ unsigned int pidx = jh7110_sysclk_data[idx].parents[i];
-+
-+ if (pidx < JH7110_SYSCLK_END)
-+ parents[i].hw = &priv->reg[pidx].hw;
-+ else if (pidx == JH7110_SYSCLK_OSC)
-+ parents[i].fw_name = "osc";
-+ else if (pidx == JH7110_SYSCLK_GMAC1_RMII_REFIN)
-+ parents[i].fw_name = "gmac1_rmii_refin";
-+ else if (pidx == JH7110_SYSCLK_GMAC1_RGMII_RXIN)
-+ parents[i].fw_name = "gmac1_rgmii_rxin";
-+ else if (pidx == JH7110_SYSCLK_I2STX_BCLK_EXT)
-+ parents[i].fw_name = "i2stx_bclk_ext";
-+ else if (pidx == JH7110_SYSCLK_I2STX_LRCK_EXT)
-+ parents[i].fw_name = "i2stx_lrck_ext";
-+ else if (pidx == JH7110_SYSCLK_I2SRX_BCLK_EXT)
-+ parents[i].fw_name = "i2srx_bclk_ext";
-+ else if (pidx == JH7110_SYSCLK_I2SRX_LRCK_EXT)
-+ parents[i].fw_name = "i2srx_lrck_ext";
-+ else if (pidx == JH7110_SYSCLK_TDM_EXT)
-+ parents[i].fw_name = "tdm_ext";
-+ else if (pidx == JH7110_SYSCLK_MCLK_EXT)
-+ parents[i].fw_name = "mclk_ext";
-+ else
-+ parents[i].hw = priv->pll[pidx - JH7110_SYSCLK_PLL0_OUT];
-+ }
-+
-+ clk->hw.init = &init;
-+ clk->idx = idx;
-+ clk->max_div = max & JH71X0_CLK_DIV_MASK;
-+
-+ ret = devm_clk_hw_register(&pdev->dev, &clk->hw);
-+ if (ret)
-+ return ret;
-+ }
-+
-+ ret = devm_of_clk_add_hw_provider(&pdev->dev, jh7110_sysclk_get, priv);
-+ if (ret)
-+ return ret;
-+
-+ return jh7110_reset_controller_register(priv, "rst-sys", 0);
-+}
-+
-+static const struct of_device_id jh7110_syscrg_match[] = {
-+ { .compatible = "starfive,jh7110-syscrg" },
-+ { /* sentinel */ }
-+};
-+
-+static struct platform_driver jh7110_syscrg_driver = {
-+ .driver = {
-+ .name = "clk-starfive-jh7110-sys",
-+ .of_match_table = jh7110_syscrg_match,
-+ .suppress_bind_attrs = true,
-+ },
-+};
-+builtin_platform_driver_probe(jh7110_syscrg_driver, jh7110_syscrg_probe);
---- /dev/null
-+++ b/drivers/clk/starfive/clk-starfive-jh7110.h
-@@ -0,0 +1,11 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+#ifndef __CLK_STARFIVE_JH7110_H
-+#define __CLK_STARFIVE_JH7110_H
-+
-+#include "clk-starfive-jh71x0.h"
-+
-+int jh7110_reset_controller_register(struct jh71x0_clk_priv *priv,
-+ const char *adev_name,
-+ u32 adev_id);
-+
-+#endif
diff --git a/target/linux/starfive/patches-6.1/0014-clk-starfive-Add-StarFive-JH7110-always-on-clock-dri.patch b/target/linux/starfive/patches-6.1/0014-clk-starfive-Add-StarFive-JH7110-always-on-clock-dri.patch
deleted file mode 100644
index 4986c110f7..0000000000
--- a/target/linux/starfive/patches-6.1/0014-clk-starfive-Add-StarFive-JH7110-always-on-clock-dri.patch
+++ /dev/null
@@ -1,206 +0,0 @@
-From 6b9f7a65cd2e9cc4bdc2ee3c3fb46bef4568af0a Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Sat, 1 Apr 2023 19:19:26 +0800
-Subject: [PATCH 014/122] clk: starfive: Add StarFive JH7110 always-on clock
- driver
-
-Add driver for the StarFive JH7110 always-on clock controller
-and register an auxiliary device for always-on reset controller
-which is named as "rst-aon".
-
-Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
-Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
-Co-developed-by: Hal Feng <hal.feng@starfivetech.com>
-Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
-Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
----
- drivers/clk/starfive/Kconfig | 11 ++
- drivers/clk/starfive/Makefile | 1 +
- .../clk/starfive/clk-starfive-jh7110-aon.c | 156 ++++++++++++++++++
- 3 files changed, 168 insertions(+)
- create mode 100644 drivers/clk/starfive/clk-starfive-jh7110-aon.c
-
---- a/drivers/clk/starfive/Kconfig
-+++ b/drivers/clk/starfive/Kconfig
-@@ -31,3 +31,14 @@ config CLK_STARFIVE_JH7110_SYS
- help
- Say yes here to support the system clock controller on the
- StarFive JH7110 SoC.
-+
-+config CLK_STARFIVE_JH7110_AON
-+ tristate "StarFive JH7110 always-on clock support"
-+ depends on CLK_STARFIVE_JH7110_SYS
-+ select AUXILIARY_BUS
-+ select CLK_STARFIVE_JH71X0
-+ select RESET_STARFIVE_JH7110
-+ default m if ARCH_STARFIVE
-+ help
-+ Say yes here to support the always-on clock controller on the
-+ StarFive JH7110 SoC.
---- a/drivers/clk/starfive/Makefile
-+++ b/drivers/clk/starfive/Makefile
-@@ -5,3 +5,4 @@ obj-$(CONFIG_CLK_STARFIVE_JH7100) += clk
- obj-$(CONFIG_CLK_STARFIVE_JH7100_AUDIO) += clk-starfive-jh7100-audio.o
-
- obj-$(CONFIG_CLK_STARFIVE_JH7110_SYS) += clk-starfive-jh7110-sys.o
-+obj-$(CONFIG_CLK_STARFIVE_JH7110_AON) += clk-starfive-jh7110-aon.o
---- /dev/null
-+++ b/drivers/clk/starfive/clk-starfive-jh7110-aon.c
-@@ -0,0 +1,156 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * StarFive JH7110 Always-On Clock Driver
-+ *
-+ * Copyright (C) 2022 Emil Renner Berthing <kernel@esmil.dk>
-+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
-+ */
-+
-+#include <linux/clk-provider.h>
-+#include <linux/io.h>
-+#include <linux/platform_device.h>
-+
-+#include <dt-bindings/clock/starfive,jh7110-crg.h>
-+
-+#include "clk-starfive-jh7110.h"
-+
-+/* external clocks */
-+#define JH7110_AONCLK_OSC (JH7110_AONCLK_END + 0)
-+#define JH7110_AONCLK_GMAC0_RMII_REFIN (JH7110_AONCLK_END + 1)
-+#define JH7110_AONCLK_GMAC0_RGMII_RXIN (JH7110_AONCLK_END + 2)
-+#define JH7110_AONCLK_STG_AXIAHB (JH7110_AONCLK_END + 3)
-+#define JH7110_AONCLK_APB_BUS (JH7110_AONCLK_END + 4)
-+#define JH7110_AONCLK_GMAC0_GTXCLK (JH7110_AONCLK_END + 5)
-+#define JH7110_AONCLK_RTC_OSC (JH7110_AONCLK_END + 6)
-+
-+static const struct jh71x0_clk_data jh7110_aonclk_data[] = {
-+ /* source */
-+ JH71X0__DIV(JH7110_AONCLK_OSC_DIV4, "osc_div4", 4, JH7110_AONCLK_OSC),
-+ JH71X0__MUX(JH7110_AONCLK_APB_FUNC, "apb_func", 2,
-+ JH7110_AONCLK_OSC_DIV4,
-+ JH7110_AONCLK_OSC),
-+ /* gmac0 */
-+ JH71X0_GATE(JH7110_AONCLK_GMAC0_AHB, "gmac0_ahb", 0, JH7110_AONCLK_STG_AXIAHB),
-+ JH71X0_GATE(JH7110_AONCLK_GMAC0_AXI, "gmac0_axi", 0, JH7110_AONCLK_STG_AXIAHB),
-+ JH71X0__DIV(JH7110_AONCLK_GMAC0_RMII_RTX, "gmac0_rmii_rtx", 30,
-+ JH7110_AONCLK_GMAC0_RMII_REFIN),
-+ JH71X0_GMUX(JH7110_AONCLK_GMAC0_TX, "gmac0_tx",
-+ CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, 2,
-+ JH7110_AONCLK_GMAC0_GTXCLK,
-+ JH7110_AONCLK_GMAC0_RMII_RTX),
-+ JH71X0__INV(JH7110_AONCLK_GMAC0_TX_INV, "gmac0_tx_inv", JH7110_AONCLK_GMAC0_TX),
-+ JH71X0__MUX(JH7110_AONCLK_GMAC0_RX, "gmac0_rx", 2,
-+ JH7110_AONCLK_GMAC0_RGMII_RXIN,
-+ JH7110_AONCLK_GMAC0_RMII_RTX),
-+ JH71X0__INV(JH7110_AONCLK_GMAC0_RX_INV, "gmac0_rx_inv", JH7110_AONCLK_GMAC0_RX),
-+ /* otpc */
-+ JH71X0_GATE(JH7110_AONCLK_OTPC_APB, "otpc_apb", 0, JH7110_AONCLK_APB_BUS),
-+ /* rtc */
-+ JH71X0_GATE(JH7110_AONCLK_RTC_APB, "rtc_apb", 0, JH7110_AONCLK_APB_BUS),
-+ JH71X0__DIV(JH7110_AONCLK_RTC_INTERNAL, "rtc_internal", 1022, JH7110_AONCLK_OSC),
-+ JH71X0__MUX(JH7110_AONCLK_RTC_32K, "rtc_32k", 2,
-+ JH7110_AONCLK_RTC_OSC,
-+ JH7110_AONCLK_RTC_INTERNAL),
-+ JH71X0_GATE(JH7110_AONCLK_RTC_CAL, "rtc_cal", 0, JH7110_AONCLK_OSC),
-+};
-+
-+static struct clk_hw *jh7110_aonclk_get(struct of_phandle_args *clkspec, void *data)
-+{
-+ struct jh71x0_clk_priv *priv = data;
-+ unsigned int idx = clkspec->args[0];
-+
-+ if (idx < JH7110_AONCLK_END)
-+ return &priv->reg[idx].hw;
-+
-+ return ERR_PTR(-EINVAL);
-+}
-+
-+static int jh7110_aoncrg_probe(struct platform_device *pdev)
-+{
-+ struct jh71x0_clk_priv *priv;
-+ unsigned int idx;
-+ int ret;
-+
-+ priv = devm_kzalloc(&pdev->dev,
-+ struct_size(priv, reg, JH7110_AONCLK_END),
-+ GFP_KERNEL);
-+ if (!priv)
-+ return -ENOMEM;
-+
-+ spin_lock_init(&priv->rmw_lock);
-+ priv->dev = &pdev->dev;
-+ priv->base = devm_platform_ioremap_resource(pdev, 0);
-+ if (IS_ERR(priv->base))
-+ return PTR_ERR(priv->base);
-+
-+ dev_set_drvdata(priv->dev, (void *)(&priv->base));
-+
-+ for (idx = 0; idx < JH7110_AONCLK_END; idx++) {
-+ u32 max = jh7110_aonclk_data[idx].max;
-+ struct clk_parent_data parents[4] = {};
-+ struct clk_init_data init = {
-+ .name = jh7110_aonclk_data[idx].name,
-+ .ops = starfive_jh71x0_clk_ops(max),
-+ .parent_data = parents,
-+ .num_parents =
-+ ((max & JH71X0_CLK_MUX_MASK) >> JH71X0_CLK_MUX_SHIFT) + 1,
-+ .flags = jh7110_aonclk_data[idx].flags,
-+ };
-+ struct jh71x0_clk *clk = &priv->reg[idx];
-+ unsigned int i;
-+
-+ for (i = 0; i < init.num_parents; i++) {
-+ unsigned int pidx = jh7110_aonclk_data[idx].parents[i];
-+
-+ if (pidx < JH7110_AONCLK_END)
-+ parents[i].hw = &priv->reg[pidx].hw;
-+ else if (pidx == JH7110_AONCLK_OSC)
-+ parents[i].fw_name = "osc";
-+ else if (pidx == JH7110_AONCLK_GMAC0_RMII_REFIN)
-+ parents[i].fw_name = "gmac0_rmii_refin";
-+ else if (pidx == JH7110_AONCLK_GMAC0_RGMII_RXIN)
-+ parents[i].fw_name = "gmac0_rgmii_rxin";
-+ else if (pidx == JH7110_AONCLK_STG_AXIAHB)
-+ parents[i].fw_name = "stg_axiahb";
-+ else if (pidx == JH7110_AONCLK_APB_BUS)
-+ parents[i].fw_name = "apb_bus";
-+ else if (pidx == JH7110_AONCLK_GMAC0_GTXCLK)
-+ parents[i].fw_name = "gmac0_gtxclk";
-+ else if (pidx == JH7110_AONCLK_RTC_OSC)
-+ parents[i].fw_name = "rtc_osc";
-+ }
-+
-+ clk->hw.init = &init;
-+ clk->idx = idx;
-+ clk->max_div = max & JH71X0_CLK_DIV_MASK;
-+
-+ ret = devm_clk_hw_register(&pdev->dev, &clk->hw);
-+ if (ret)
-+ return ret;
-+ }
-+
-+ ret = devm_of_clk_add_hw_provider(&pdev->dev, jh7110_aonclk_get, priv);
-+ if (ret)
-+ return ret;
-+
-+ return jh7110_reset_controller_register(priv, "rst-aon", 1);
-+}
-+
-+static const struct of_device_id jh7110_aoncrg_match[] = {
-+ { .compatible = "starfive,jh7110-aoncrg" },
-+ { /* sentinel */ }
-+};
-+MODULE_DEVICE_TABLE(of, jh7110_aoncrg_match);
-+
-+static struct platform_driver jh7110_aoncrg_driver = {
-+ .probe = jh7110_aoncrg_probe,
-+ .driver = {
-+ .name = "clk-starfive-jh7110-aon",
-+ .of_match_table = jh7110_aoncrg_match,
-+ },
-+};
-+module_platform_driver(jh7110_aoncrg_driver);
-+
-+MODULE_AUTHOR("Emil Renner Berthing");
-+MODULE_DESCRIPTION("StarFive JH7110 always-on clock driver");
-+MODULE_LICENSE("GPL");
diff --git a/target/linux/starfive/patches-6.1/0015-reset-starfive-Add-StarFive-JH7110-reset-driver.patch b/target/linux/starfive/patches-6.1/0015-reset-starfive-Add-StarFive-JH7110-reset-driver.patch
deleted file mode 100644
index 1a2a9d9991..0000000000
--- a/target/linux/starfive/patches-6.1/0015-reset-starfive-Add-StarFive-JH7110-reset-driver.patch
+++ /dev/null
@@ -1,113 +0,0 @@
-From ea2f40c943f4a6d39a2f3ea4660266250d37c95a Mon Sep 17 00:00:00 2001
-From: Hal Feng <hal.feng@starfivetech.com>
-Date: Sat, 1 Apr 2023 19:19:27 +0800
-Subject: [PATCH 015/122] reset: starfive: Add StarFive JH7110 reset driver
-
-Add auxiliary driver to support StarFive JH7110 system
-and always-on resets.
-
-Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
-Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
-Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
-Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
----
- drivers/reset/starfive/Kconfig | 8 +++
- drivers/reset/starfive/Makefile | 1 +
- .../reset/starfive/reset-starfive-jh7110.c | 70 +++++++++++++++++++
- 3 files changed, 79 insertions(+)
- create mode 100644 drivers/reset/starfive/reset-starfive-jh7110.c
-
---- a/drivers/reset/starfive/Kconfig
-+++ b/drivers/reset/starfive/Kconfig
-@@ -10,3 +10,11 @@ config RESET_STARFIVE_JH7100
- default ARCH_STARFIVE
- help
- This enables the reset controller driver for the StarFive JH7100 SoC.
-+
-+config RESET_STARFIVE_JH7110
-+ bool "StarFive JH7110 Reset Driver"
-+ depends on AUXILIARY_BUS && CLK_STARFIVE_JH7110_SYS
-+ select RESET_STARFIVE_JH71X0
-+ default ARCH_STARFIVE
-+ help
-+ This enables the reset controller driver for the StarFive JH7110 SoC.
---- a/drivers/reset/starfive/Makefile
-+++ b/drivers/reset/starfive/Makefile
-@@ -2,3 +2,4 @@
- obj-$(CONFIG_RESET_STARFIVE_JH71X0) += reset-starfive-jh71x0.o
-
- obj-$(CONFIG_RESET_STARFIVE_JH7100) += reset-starfive-jh7100.o
-+obj-$(CONFIG_RESET_STARFIVE_JH7110) += reset-starfive-jh7110.o
---- /dev/null
-+++ b/drivers/reset/starfive/reset-starfive-jh7110.c
-@@ -0,0 +1,70 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later
-+/*
-+ * Reset driver for the StarFive JH7110 SoC
-+ *
-+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
-+ */
-+
-+#include <linux/auxiliary_bus.h>
-+
-+#include "reset-starfive-jh71x0.h"
-+
-+#include <dt-bindings/reset/starfive,jh7110-crg.h>
-+
-+struct jh7110_reset_info {
-+ unsigned int nr_resets;
-+ unsigned int assert_offset;
-+ unsigned int status_offset;
-+};
-+
-+static const struct jh7110_reset_info jh7110_sys_info = {
-+ .nr_resets = JH7110_SYSRST_END,
-+ .assert_offset = 0x2F8,
-+ .status_offset = 0x308,
-+};
-+
-+static const struct jh7110_reset_info jh7110_aon_info = {
-+ .nr_resets = JH7110_AONRST_END,
-+ .assert_offset = 0x38,
-+ .status_offset = 0x3C,
-+};
-+
-+static int jh7110_reset_probe(struct auxiliary_device *adev,
-+ const struct auxiliary_device_id *id)
-+{
-+ struct jh7110_reset_info *info = (struct jh7110_reset_info *)(id->driver_data);
-+ void __iomem **base = (void __iomem **)dev_get_drvdata(adev->dev.parent);
-+
-+ if (!info || !base)
-+ return -ENODEV;
-+
-+ return reset_starfive_jh71x0_register(&adev->dev, adev->dev.parent->of_node,
-+ *base + info->assert_offset,
-+ *base + info->status_offset,
-+ NULL,
-+ info->nr_resets,
-+ NULL);
-+}
-+
-+static const struct auxiliary_device_id jh7110_reset_ids[] = {
-+ {
-+ .name = "clk_starfive_jh7110_sys.rst-sys",
-+ .driver_data = (kernel_ulong_t)&jh7110_sys_info,
-+ },
-+ {
-+ .name = "clk_starfive_jh7110_sys.rst-aon",
-+ .driver_data = (kernel_ulong_t)&jh7110_aon_info,
-+ },
-+ { /* sentinel */ }
-+};
-+MODULE_DEVICE_TABLE(auxiliary, jh7110_reset_ids);
-+
-+static struct auxiliary_driver jh7110_reset_driver = {
-+ .probe = jh7110_reset_probe,
-+ .id_table = jh7110_reset_ids,
-+};
-+module_auxiliary_driver(jh7110_reset_driver);
-+
-+MODULE_AUTHOR("Hal Feng <hal.feng@starfivetech.com>");
-+MODULE_DESCRIPTION("StarFive JH7110 reset driver");
-+MODULE_LICENSE("GPL");
diff --git a/target/linux/starfive/patches-6.1/0016-MAINTAINERS-generalise-StarFive-clk-reset-entries.patch b/target/linux/starfive/patches-6.1/0016-MAINTAINERS-generalise-StarFive-clk-reset-entries.patch
deleted file mode 100644
index d3f9a9cf22..0000000000
--- a/target/linux/starfive/patches-6.1/0016-MAINTAINERS-generalise-StarFive-clk-reset-entries.patch
+++ /dev/null
@@ -1,50 +0,0 @@
-From 17fecb06e9de3ae5bbf7aecc4d91e14517982f5c Mon Sep 17 00:00:00 2001
-From: "shanlong.li" <shanlong.li@starfivetech.com>
-Date: Wed, 17 May 2023 20:41:51 -0700
-Subject: [PATCH 016/122] MAINTAINERS: generalise StarFive clk/reset entries
-
-Update the MAINTAINERS entry for StarFive's clock and reset drivers to
-account for the addition of JH7110 support and Hal's role in that.
-
-Signed-off-by: shanlong.li <shanlong.li@starfivetech.com>
----
- MAINTAINERS | 16 +++++++++-------
- 1 file changed, 9 insertions(+), 7 deletions(-)
-
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -19657,12 +19657,13 @@ M: Emil Renner Berthing <kernel@esmil.dk
- S: Maintained
- F: arch/riscv/boot/dts/starfive/
-
--STARFIVE JH7100 CLOCK DRIVERS
-+STARFIVE JH71X0 CLOCK DRIVERS
- M: Emil Renner Berthing <kernel@esmil.dk>
-+M: Hal Feng <hal.feng@starfivetech.com>
- S: Maintained
--F: Documentation/devicetree/bindings/clock/starfive,jh7100-*.yaml
--F: drivers/clk/starfive/clk-starfive-jh7100*
--F: include/dt-bindings/clock/starfive-jh7100*.h
-+F: Documentation/devicetree/bindings/clock/starfive,jh71*.yaml
-+F: drivers/clk/starfive/clk-starfive-jh71*
-+F: include/dt-bindings/clock/starfive?jh71*.h
-
- STARFIVE JH7100 PINCTRL DRIVER
- M: Emil Renner Berthing <kernel@esmil.dk>
-@@ -19672,12 +19673,13 @@ F: Documentation/devicetree/bindings/pin
- F: drivers/pinctrl/starfive/
- F: include/dt-bindings/pinctrl/pinctrl-starfive-jh7100.h
-
--STARFIVE JH7100 RESET CONTROLLER DRIVER
-+STARFIVE JH71X0 RESET CONTROLLER DRIVERS
- M: Emil Renner Berthing <kernel@esmil.dk>
-+M: Hal Feng <hal.feng@starfivetech.com>
- S: Maintained
- F: Documentation/devicetree/bindings/reset/starfive,jh7100-reset.yaml
--F: drivers/reset/reset-starfive-jh7100.c
--F: include/dt-bindings/reset/starfive-jh7100.h
-+F: drivers/reset/starfive/reset-starfive-jh71*
-+F: include/dt-bindings/reset/starfive?jh71*.h
-
- STATIC BRANCH/CALL
- M: Peter Zijlstra <peterz@infradead.org>
diff --git a/target/linux/starfive/patches-6.1/0017-clk-starfive-Avoid-casting-iomem-pointers.patch b/target/linux/starfive/patches-6.1/0017-clk-starfive-Avoid-casting-iomem-pointers.patch
deleted file mode 100644
index 9667f7256c..0000000000
--- a/target/linux/starfive/patches-6.1/0017-clk-starfive-Avoid-casting-iomem-pointers.patch
+++ /dev/null
@@ -1,128 +0,0 @@
-From d9d4e0fb44a50cace195e1639cfb23e518e17e88 Mon Sep 17 00:00:00 2001
-From: Stephen Boyd <sboyd@kernel.org>
-Date: Thu, 13 Apr 2023 13:55:28 -0700
-Subject: [PATCH 017/122] clk: starfive: Avoid casting iomem pointers
-
-Let's use a wrapper struct for the auxiliary_device made in
-jh7110_reset_controller_register() so that we can stop casting iomem
-pointers. The casts trip up tools like sparse, and make for some awkward
-casts that are largely unnecessary. While we're here, change the
-allocation from devm and actually free the auxiliary_device memory in
-the release function. This avoids any use after free problems where the
-parent device driver is unbound from the device but the
-auxiliuary_device is still in use accessing devm freed memory.
-
-Cc: Tommaso Merciai <tomm.merciai@gmail.com>
-Cc: Emil Renner Berthing <emil.renner.berthing@canonical.com>
-Cc: Hal Feng <hal.feng@starfivetech.com>
-Cc: Conor Dooley <conor.dooley@microchip.com>
-Cc: Xingyu Wu <xingyu.wu@starfivetech.com>
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
-Fixes: edab7204afe5 ("clk: starfive: Add StarFive JH7110 system clock driver")
-Signed-off-by: Stephen Boyd <sboyd@kernel.org>
-Link: https://lore.kernel.org/r/20230413205528.4044216-1-sboyd@kernel.org
----
- drivers/clk/starfive/clk-starfive-jh7110-sys.c | 15 ++++++++++++---
- drivers/reset/starfive/reset-starfive-jh7110.c | 9 ++++++---
- include/soc/starfive/reset-starfive-jh71x0.h | 17 +++++++++++++++++
- 3 files changed, 35 insertions(+), 6 deletions(-)
- create mode 100644 include/soc/starfive/reset-starfive-jh71x0.h
-
---- a/drivers/clk/starfive/clk-starfive-jh7110-sys.c
-+++ b/drivers/clk/starfive/clk-starfive-jh7110-sys.c
-@@ -11,6 +11,9 @@
- #include <linux/init.h>
- #include <linux/io.h>
- #include <linux/platform_device.h>
-+#include <linux/slab.h>
-+
-+#include <soc/starfive/reset-starfive-jh71x0.h>
-
- #include <dt-bindings/clock/starfive,jh7110-crg.h>
-
-@@ -335,26 +338,32 @@ static void jh7110_reset_unregister_adev
- struct auxiliary_device *adev = _adev;
-
- auxiliary_device_delete(adev);
-+ auxiliary_device_uninit(adev);
- }
-
- static void jh7110_reset_adev_release(struct device *dev)
- {
- struct auxiliary_device *adev = to_auxiliary_dev(dev);
-+ struct jh71x0_reset_adev *rdev = to_jh71x0_reset_adev(adev);
-
-- auxiliary_device_uninit(adev);
-+ kfree(rdev);
- }
-
- int jh7110_reset_controller_register(struct jh71x0_clk_priv *priv,
- const char *adev_name,
- u32 adev_id)
- {
-+ struct jh71x0_reset_adev *rdev;
- struct auxiliary_device *adev;
- int ret;
-
-- adev = devm_kzalloc(priv->dev, sizeof(*adev), GFP_KERNEL);
-- if (!adev)
-+ rdev = kzalloc(sizeof(*rdev), GFP_KERNEL);
-+ if (!rdev)
- return -ENOMEM;
-
-+ rdev->base = priv->base;
-+
-+ adev = &rdev->adev;
- adev->name = adev_name;
- adev->dev.parent = priv->dev;
- adev->dev.release = jh7110_reset_adev_release;
---- a/drivers/reset/starfive/reset-starfive-jh7110.c
-+++ b/drivers/reset/starfive/reset-starfive-jh7110.c
-@@ -7,6 +7,8 @@
-
- #include <linux/auxiliary_bus.h>
-
-+#include <soc/starfive/reset-starfive-jh71x0.h>
-+
- #include "reset-starfive-jh71x0.h"
-
- #include <dt-bindings/reset/starfive,jh7110-crg.h>
-@@ -33,14 +35,15 @@ static int jh7110_reset_probe(struct aux
- const struct auxiliary_device_id *id)
- {
- struct jh7110_reset_info *info = (struct jh7110_reset_info *)(id->driver_data);
-- void __iomem **base = (void __iomem **)dev_get_drvdata(adev->dev.parent);
-+ struct jh71x0_reset_adev *rdev = to_jh71x0_reset_adev(adev);
-+ void __iomem *base = rdev->base;
-
- if (!info || !base)
- return -ENODEV;
-
- return reset_starfive_jh71x0_register(&adev->dev, adev->dev.parent->of_node,
-- *base + info->assert_offset,
-- *base + info->status_offset,
-+ base + info->assert_offset,
-+ base + info->status_offset,
- NULL,
- info->nr_resets,
- NULL);
---- /dev/null
-+++ b/include/soc/starfive/reset-starfive-jh71x0.h
-@@ -0,0 +1,17 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+#ifndef __SOC_STARFIVE_RESET_JH71X0_H
-+#define __SOC_STARFIVE_RESET_JH71X0_H
-+
-+#include <linux/auxiliary_bus.h>
-+#include <linux/compiler_types.h>
-+#include <linux/container_of.h>
-+
-+struct jh71x0_reset_adev {
-+ void __iomem *base;
-+ struct auxiliary_device adev;
-+};
-+
-+#define to_jh71x0_reset_adev(_adev) \
-+ container_of((_adev), struct jh71x0_reset_adev, adev)
-+
-+#endif
diff --git a/target/linux/starfive/patches-6.1/0018-dt-bindings-timer-Add-StarFive-JH7110-clint.patch b/target/linux/starfive/patches-6.1/0018-dt-bindings-timer-Add-StarFive-JH7110-clint.patch
deleted file mode 100644
index 83de87edfc..0000000000
--- a/target/linux/starfive/patches-6.1/0018-dt-bindings-timer-Add-StarFive-JH7110-clint.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From f043ba93a8f22fda312574eb98217be15468b7ef Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Sat, 1 Apr 2023 19:19:28 +0800
-Subject: [PATCH 018/122] dt-bindings: timer: Add StarFive JH7110 clint
-
-Add compatible string for the StarFive JH7110 clint.
-
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
-Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
-Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
-Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
----
- Documentation/devicetree/bindings/timer/sifive,clint.yaml | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/Documentation/devicetree/bindings/timer/sifive,clint.yaml
-+++ b/Documentation/devicetree/bindings/timer/sifive,clint.yaml
-@@ -27,6 +27,7 @@ properties:
- - enum:
- - sifive,fu540-c000-clint
- - starfive,jh7100-clint
-+ - starfive,jh7110-clint
- - canaan,k210-clint
- - const: sifive,clint0
- - items:
diff --git a/target/linux/starfive/patches-6.1/0019-dt-bindings-interrupt-controller-Add-StarFive-JH7110.patch b/target/linux/starfive/patches-6.1/0019-dt-bindings-interrupt-controller-Add-StarFive-JH7110.patch
deleted file mode 100644
index bb604fee54..0000000000
--- a/target/linux/starfive/patches-6.1/0019-dt-bindings-interrupt-controller-Add-StarFive-JH7110.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From dba83b8b65b4ef47e8986739b6734894f3979c52 Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Sat, 1 Apr 2023 19:19:29 +0800
-Subject: [PATCH 019/122] dt-bindings: interrupt-controller: Add StarFive
- JH7110 plic
-
-Add compatible string for StarFive JH7110 plic.
-
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
-Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
-Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
-Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
----
- .../bindings/interrupt-controller/sifive,plic-1.0.0.yaml | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/Documentation/devicetree/bindings/interrupt-controller/sifive,plic-1.0.0.yaml
-+++ b/Documentation/devicetree/bindings/interrupt-controller/sifive,plic-1.0.0.yaml
-@@ -60,6 +60,7 @@ properties:
- - enum:
- - sifive,fu540-c000-plic
- - starfive,jh7100-plic
-+ - starfive,jh7110-plic
- - canaan,k210-plic
- - const: sifive,plic-1.0.0
- - items:
diff --git a/target/linux/starfive/patches-6.1/0020-dt-bindings-riscv-Add-SiFive-S7-compatible.patch b/target/linux/starfive/patches-6.1/0020-dt-bindings-riscv-Add-SiFive-S7-compatible.patch
deleted file mode 100644
index c8e282e04f..0000000000
--- a/target/linux/starfive/patches-6.1/0020-dt-bindings-riscv-Add-SiFive-S7-compatible.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From fccbb0c52438762999ea16c85d4ebf4cc7e2deff Mon Sep 17 00:00:00 2001
-From: Hal Feng <hal.feng@starfivetech.com>
-Date: Sat, 1 Apr 2023 19:19:30 +0800
-Subject: [PATCH 020/122] dt-bindings: riscv: Add SiFive S7 compatible
-
-Add a new compatible string in cpu.yaml for SiFive S7 CPU
-core which is used on SiFive U74-MC core complex etc.
-
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
-Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
-Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
-Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
----
- Documentation/devicetree/bindings/riscv/cpus.yaml | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/Documentation/devicetree/bindings/riscv/cpus.yaml
-+++ b/Documentation/devicetree/bindings/riscv/cpus.yaml
-@@ -33,6 +33,7 @@ properties:
- - sifive,e5
- - sifive,e7
- - sifive,e71
-+ - sifive,s7
- - sifive,u74-mc
- - sifive,u54
- - sifive,u74
diff --git a/target/linux/starfive/patches-6.1/0021-riscv-dts-starfive-Add-initial-StarFive-JH7110-devic.patch b/target/linux/starfive/patches-6.1/0021-riscv-dts-starfive-Add-initial-StarFive-JH7110-devic.patch
deleted file mode 100644
index d1e1cfc8cd..0000000000
--- a/target/linux/starfive/patches-6.1/0021-riscv-dts-starfive-Add-initial-StarFive-JH7110-devic.patch
+++ /dev/null
@@ -1,549 +0,0 @@
-From ca57ce82224c21f93ad43754474fb8de1baf5caa Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Sat, 1 Apr 2023 19:19:31 +0800
-Subject: [PATCH 021/122] riscv: dts: starfive: Add initial StarFive JH7110
- device tree
-
-Add initial device tree for the JH7110 RISC-V SoC by StarFive
-Technology Ltd.
-
-Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
-Co-developed-by: Jianlong Huang <jianlong.huang@starfivetech.com>
-Signed-off-by: Jianlong Huang <jianlong.huang@starfivetech.com>
-Co-developed-by: Hal Feng <hal.feng@starfivetech.com>
-Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
-[conor: squashed in the removal of the S7's non-existent mmu]
-Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
-Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
----
- arch/riscv/Kconfig.socs | 5 +
- arch/riscv/boot/dts/starfive/jh7110.dtsi | 500 +++++++++++++++++++++++
- 2 files changed, 505 insertions(+)
- create mode 100644 arch/riscv/boot/dts/starfive/jh7110.dtsi
-
---- a/arch/riscv/Kconfig.socs
-+++ b/arch/riscv/Kconfig.socs
-@@ -7,6 +7,8 @@ config SOC_MICROCHIP_POLARFIRE
- help
- This enables support for Microchip PolarFire SoC platforms.
-
-+config ARCH_SIFIVE
-+ def_bool SOC_SIFIVE
- config SOC_SIFIVE
- bool "SiFive SoCs"
- select SERIAL_SIFIVE if TTY
-@@ -18,6 +20,9 @@ config SOC_SIFIVE
- help
- This enables support for SiFive SoC platform hardware.
-
-+config ARCH_STARFIVE
-+ def_bool SOC_STARFIVE
-+
- config SOC_STARFIVE
- bool "StarFive SoCs"
- select PINCTRL
---- /dev/null
-+++ b/arch/riscv/boot/dts/starfive/jh7110.dtsi
-@@ -0,0 +1,500 @@
-+// SPDX-License-Identifier: GPL-2.0 OR MIT
-+/*
-+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
-+ * Copyright (C) 2022 Emil Renner Berthing <kernel@esmil.dk>
-+ */
-+
-+/dts-v1/;
-+#include <dt-bindings/clock/starfive,jh7110-crg.h>
-+#include <dt-bindings/reset/starfive,jh7110-crg.h>
-+
-+/ {
-+ compatible = "starfive,jh7110";
-+ #address-cells = <2>;
-+ #size-cells = <2>;
-+
-+ cpus {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ S7_0: cpu@0 {
-+ compatible = "sifive,s7", "riscv";
-+ reg = <0>;
-+ device_type = "cpu";
-+ i-cache-block-size = <64>;
-+ i-cache-sets = <64>;
-+ i-cache-size = <16384>;
-+ next-level-cache = <&ccache>;
-+ riscv,isa = "rv64imac_zba_zbb";
-+ status = "disabled";
-+
-+ cpu0_intc: interrupt-controller {
-+ compatible = "riscv,cpu-intc";
-+ interrupt-controller;
-+ #interrupt-cells = <1>;
-+ };
-+ };
-+
-+ U74_1: cpu@1 {
-+ compatible = "sifive,u74-mc", "riscv";
-+ reg = <1>;
-+ d-cache-block-size = <64>;
-+ d-cache-sets = <64>;
-+ d-cache-size = <32768>;
-+ d-tlb-sets = <1>;
-+ d-tlb-size = <40>;
-+ device_type = "cpu";
-+ i-cache-block-size = <64>;
-+ i-cache-sets = <64>;
-+ i-cache-size = <32768>;
-+ i-tlb-sets = <1>;
-+ i-tlb-size = <40>;
-+ mmu-type = "riscv,sv39";
-+ next-level-cache = <&ccache>;
-+ riscv,isa = "rv64imafdc_zba_zbb";
-+ tlb-split;
-+
-+ cpu1_intc: interrupt-controller {
-+ compatible = "riscv,cpu-intc";
-+ interrupt-controller;
-+ #interrupt-cells = <1>;
-+ };
-+ };
-+
-+ U74_2: cpu@2 {
-+ compatible = "sifive,u74-mc", "riscv";
-+ reg = <2>;
-+ d-cache-block-size = <64>;
-+ d-cache-sets = <64>;
-+ d-cache-size = <32768>;
-+ d-tlb-sets = <1>;
-+ d-tlb-size = <40>;
-+ device_type = "cpu";
-+ i-cache-block-size = <64>;
-+ i-cache-sets = <64>;
-+ i-cache-size = <32768>;
-+ i-tlb-sets = <1>;
-+ i-tlb-size = <40>;
-+ mmu-type = "riscv,sv39";
-+ next-level-cache = <&ccache>;
-+ riscv,isa = "rv64imafdc_zba_zbb";
-+ tlb-split;
-+
-+ cpu2_intc: interrupt-controller {
-+ compatible = "riscv,cpu-intc";
-+ interrupt-controller;
-+ #interrupt-cells = <1>;
-+ };
-+ };
-+
-+ U74_3: cpu@3 {
-+ compatible = "sifive,u74-mc", "riscv";
-+ reg = <3>;
-+ d-cache-block-size = <64>;
-+ d-cache-sets = <64>;
-+ d-cache-size = <32768>;
-+ d-tlb-sets = <1>;
-+ d-tlb-size = <40>;
-+ device_type = "cpu";
-+ i-cache-block-size = <64>;
-+ i-cache-sets = <64>;
-+ i-cache-size = <32768>;
-+ i-tlb-sets = <1>;
-+ i-tlb-size = <40>;
-+ mmu-type = "riscv,sv39";
-+ next-level-cache = <&ccache>;
-+ riscv,isa = "rv64imafdc_zba_zbb";
-+ tlb-split;
-+
-+ cpu3_intc: interrupt-controller {
-+ compatible = "riscv,cpu-intc";
-+ interrupt-controller;
-+ #interrupt-cells = <1>;
-+ };
-+ };
-+
-+ U74_4: cpu@4 {
-+ compatible = "sifive,u74-mc", "riscv";
-+ reg = <4>;
-+ d-cache-block-size = <64>;
-+ d-cache-sets = <64>;
-+ d-cache-size = <32768>;
-+ d-tlb-sets = <1>;
-+ d-tlb-size = <40>;
-+ device_type = "cpu";
-+ i-cache-block-size = <64>;
-+ i-cache-sets = <64>;
-+ i-cache-size = <32768>;
-+ i-tlb-sets = <1>;
-+ i-tlb-size = <40>;
-+ mmu-type = "riscv,sv39";
-+ next-level-cache = <&ccache>;
-+ riscv,isa = "rv64imafdc_zba_zbb";
-+ tlb-split;
-+
-+ cpu4_intc: interrupt-controller {
-+ compatible = "riscv,cpu-intc";
-+ interrupt-controller;
-+ #interrupt-cells = <1>;
-+ };
-+ };
-+
-+ cpu-map {
-+ cluster0 {
-+ core0 {
-+ cpu = <&S7_0>;
-+ };
-+
-+ core1 {
-+ cpu = <&U74_1>;
-+ };
-+
-+ core2 {
-+ cpu = <&U74_2>;
-+ };
-+
-+ core3 {
-+ cpu = <&U74_3>;
-+ };
-+
-+ core4 {
-+ cpu = <&U74_4>;
-+ };
-+ };
-+ };
-+ };
-+
-+ gmac0_rgmii_rxin: gmac0-rgmii-rxin-clock {
-+ compatible = "fixed-clock";
-+ clock-output-names = "gmac0_rgmii_rxin";
-+ #clock-cells = <0>;
-+ };
-+
-+ gmac0_rmii_refin: gmac0-rmii-refin-clock {
-+ compatible = "fixed-clock";
-+ clock-output-names = "gmac0_rmii_refin";
-+ #clock-cells = <0>;
-+ };
-+
-+ gmac1_rgmii_rxin: gmac1-rgmii-rxin-clock {
-+ compatible = "fixed-clock";
-+ clock-output-names = "gmac1_rgmii_rxin";
-+ #clock-cells = <0>;
-+ };
-+
-+ gmac1_rmii_refin: gmac1-rmii-refin-clock {
-+ compatible = "fixed-clock";
-+ clock-output-names = "gmac1_rmii_refin";
-+ #clock-cells = <0>;
-+ };
-+
-+ i2srx_bclk_ext: i2srx-bclk-ext-clock {
-+ compatible = "fixed-clock";
-+ clock-output-names = "i2srx_bclk_ext";
-+ #clock-cells = <0>;
-+ };
-+
-+ i2srx_lrck_ext: i2srx-lrck-ext-clock {
-+ compatible = "fixed-clock";
-+ clock-output-names = "i2srx_lrck_ext";
-+ #clock-cells = <0>;
-+ };
-+
-+ i2stx_bclk_ext: i2stx-bclk-ext-clock {
-+ compatible = "fixed-clock";
-+ clock-output-names = "i2stx_bclk_ext";
-+ #clock-cells = <0>;
-+ };
-+
-+ i2stx_lrck_ext: i2stx-lrck-ext-clock {
-+ compatible = "fixed-clock";
-+ clock-output-names = "i2stx_lrck_ext";
-+ #clock-cells = <0>;
-+ };
-+
-+ mclk_ext: mclk-ext-clock {
-+ compatible = "fixed-clock";
-+ clock-output-names = "mclk_ext";
-+ #clock-cells = <0>;
-+ };
-+
-+ osc: oscillator {
-+ compatible = "fixed-clock";
-+ clock-output-names = "osc";
-+ #clock-cells = <0>;
-+ };
-+
-+ rtc_osc: rtc-oscillator {
-+ compatible = "fixed-clock";
-+ clock-output-names = "rtc_osc";
-+ #clock-cells = <0>;
-+ };
-+
-+ tdm_ext: tdm-ext-clock {
-+ compatible = "fixed-clock";
-+ clock-output-names = "tdm_ext";
-+ #clock-cells = <0>;
-+ };
-+
-+ soc {
-+ compatible = "simple-bus";
-+ interrupt-parent = <&plic>;
-+ #address-cells = <2>;
-+ #size-cells = <2>;
-+ ranges;
-+
-+ clint: timer@2000000 {
-+ compatible = "starfive,jh7110-clint", "sifive,clint0";
-+ reg = <0x0 0x2000000 0x0 0x10000>;
-+ interrupts-extended = <&cpu0_intc 3>, <&cpu0_intc 7>,
-+ <&cpu1_intc 3>, <&cpu1_intc 7>,
-+ <&cpu2_intc 3>, <&cpu2_intc 7>,
-+ <&cpu3_intc 3>, <&cpu3_intc 7>,
-+ <&cpu4_intc 3>, <&cpu4_intc 7>;
-+ };
-+
-+ ccache: cache-controller@2010000 {
-+ compatible = "starfive,jh7110-ccache", "sifive,ccache0", "cache";
-+ reg = <0x0 0x2010000 0x0 0x4000>;
-+ interrupts = <1>, <3>, <4>, <2>;
-+ cache-block-size = <64>;
-+ cache-level = <2>;
-+ cache-sets = <2048>;
-+ cache-size = <2097152>;
-+ cache-unified;
-+ };
-+
-+ plic: interrupt-controller@c000000 {
-+ compatible = "starfive,jh7110-plic", "sifive,plic-1.0.0";
-+ reg = <0x0 0xc000000 0x0 0x4000000>;
-+ interrupts-extended = <&cpu0_intc 11>,
-+ <&cpu1_intc 11>, <&cpu1_intc 9>,
-+ <&cpu2_intc 11>, <&cpu2_intc 9>,
-+ <&cpu3_intc 11>, <&cpu3_intc 9>,
-+ <&cpu4_intc 11>, <&cpu4_intc 9>;
-+ interrupt-controller;
-+ #interrupt-cells = <1>;
-+ #address-cells = <0>;
-+ riscv,ndev = <136>;
-+ };
-+
-+ uart0: serial@10000000 {
-+ compatible = "snps,dw-apb-uart";
-+ reg = <0x0 0x10000000 0x0 0x10000>;
-+ clocks = <&syscrg JH7110_SYSCLK_UART0_CORE>,
-+ <&syscrg JH7110_SYSCLK_UART0_APB>;
-+ clock-names = "baudclk", "apb_pclk";
-+ resets = <&syscrg JH7110_SYSRST_UART0_APB>;
-+ interrupts = <32>;
-+ reg-io-width = <4>;
-+ reg-shift = <2>;
-+ status = "disabled";
-+ };
-+
-+ uart1: serial@10010000 {
-+ compatible = "snps,dw-apb-uart";
-+ reg = <0x0 0x10010000 0x0 0x10000>;
-+ clocks = <&syscrg JH7110_SYSCLK_UART1_CORE>,
-+ <&syscrg JH7110_SYSCLK_UART1_APB>;
-+ clock-names = "baudclk", "apb_pclk";
-+ resets = <&syscrg JH7110_SYSRST_UART1_APB>;
-+ interrupts = <33>;
-+ reg-io-width = <4>;
-+ reg-shift = <2>;
-+ status = "disabled";
-+ };
-+
-+ uart2: serial@10020000 {
-+ compatible = "snps,dw-apb-uart";
-+ reg = <0x0 0x10020000 0x0 0x10000>;
-+ clocks = <&syscrg JH7110_SYSCLK_UART2_CORE>,
-+ <&syscrg JH7110_SYSCLK_UART2_APB>;
-+ clock-names = "baudclk", "apb_pclk";
-+ resets = <&syscrg JH7110_SYSRST_UART2_APB>;
-+ interrupts = <34>;
-+ reg-io-width = <4>;
-+ reg-shift = <2>;
-+ status = "disabled";
-+ };
-+
-+ i2c0: i2c@10030000 {
-+ compatible = "snps,designware-i2c";
-+ reg = <0x0 0x10030000 0x0 0x10000>;
-+ clocks = <&syscrg JH7110_SYSCLK_I2C0_APB>;
-+ clock-names = "ref";
-+ resets = <&syscrg JH7110_SYSRST_I2C0_APB>;
-+ interrupts = <35>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ status = "disabled";
-+ };
-+
-+ i2c1: i2c@10040000 {
-+ compatible = "snps,designware-i2c";
-+ reg = <0x0 0x10040000 0x0 0x10000>;
-+ clocks = <&syscrg JH7110_SYSCLK_I2C1_APB>;
-+ clock-names = "ref";
-+ resets = <&syscrg JH7110_SYSRST_I2C1_APB>;
-+ interrupts = <36>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ status = "disabled";
-+ };
-+
-+ i2c2: i2c@10050000 {
-+ compatible = "snps,designware-i2c";
-+ reg = <0x0 0x10050000 0x0 0x10000>;
-+ clocks = <&syscrg JH7110_SYSCLK_I2C2_APB>;
-+ clock-names = "ref";
-+ resets = <&syscrg JH7110_SYSRST_I2C2_APB>;
-+ interrupts = <37>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ status = "disabled";
-+ };
-+
-+ uart3: serial@12000000 {
-+ compatible = "snps,dw-apb-uart";
-+ reg = <0x0 0x12000000 0x0 0x10000>;
-+ clocks = <&syscrg JH7110_SYSCLK_UART3_CORE>,
-+ <&syscrg JH7110_SYSCLK_UART3_APB>;
-+ clock-names = "baudclk", "apb_pclk";
-+ resets = <&syscrg JH7110_SYSRST_UART3_APB>;
-+ interrupts = <45>;
-+ reg-io-width = <4>;
-+ reg-shift = <2>;
-+ status = "disabled";
-+ };
-+
-+ uart4: serial@12010000 {
-+ compatible = "snps,dw-apb-uart";
-+ reg = <0x0 0x12010000 0x0 0x10000>;
-+ clocks = <&syscrg JH7110_SYSCLK_UART4_CORE>,
-+ <&syscrg JH7110_SYSCLK_UART4_APB>;
-+ clock-names = "baudclk", "apb_pclk";
-+ resets = <&syscrg JH7110_SYSRST_UART4_APB>;
-+ interrupts = <46>;
-+ reg-io-width = <4>;
-+ reg-shift = <2>;
-+ status = "disabled";
-+ };
-+
-+ uart5: serial@12020000 {
-+ compatible = "snps,dw-apb-uart";
-+ reg = <0x0 0x12020000 0x0 0x10000>;
-+ clocks = <&syscrg JH7110_SYSCLK_UART5_CORE>,
-+ <&syscrg JH7110_SYSCLK_UART5_APB>;
-+ clock-names = "baudclk", "apb_pclk";
-+ resets = <&syscrg JH7110_SYSRST_UART5_APB>;
-+ interrupts = <47>;
-+ reg-io-width = <4>;
-+ reg-shift = <2>;
-+ status = "disabled";
-+ };
-+
-+ i2c3: i2c@12030000 {
-+ compatible = "snps,designware-i2c";
-+ reg = <0x0 0x12030000 0x0 0x10000>;
-+ clocks = <&syscrg JH7110_SYSCLK_I2C3_APB>;
-+ clock-names = "ref";
-+ resets = <&syscrg JH7110_SYSRST_I2C3_APB>;
-+ interrupts = <48>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ status = "disabled";
-+ };
-+
-+ i2c4: i2c@12040000 {
-+ compatible = "snps,designware-i2c";
-+ reg = <0x0 0x12040000 0x0 0x10000>;
-+ clocks = <&syscrg JH7110_SYSCLK_I2C4_APB>;
-+ clock-names = "ref";
-+ resets = <&syscrg JH7110_SYSRST_I2C4_APB>;
-+ interrupts = <49>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ status = "disabled";
-+ };
-+
-+ i2c5: i2c@12050000 {
-+ compatible = "snps,designware-i2c";
-+ reg = <0x0 0x12050000 0x0 0x10000>;
-+ clocks = <&syscrg JH7110_SYSCLK_I2C5_APB>;
-+ clock-names = "ref";
-+ resets = <&syscrg JH7110_SYSRST_I2C5_APB>;
-+ interrupts = <50>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ status = "disabled";
-+ };
-+
-+ i2c6: i2c@12060000 {
-+ compatible = "snps,designware-i2c";
-+ reg = <0x0 0x12060000 0x0 0x10000>;
-+ clocks = <&syscrg JH7110_SYSCLK_I2C6_APB>;
-+ clock-names = "ref";
-+ resets = <&syscrg JH7110_SYSRST_I2C6_APB>;
-+ interrupts = <51>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ status = "disabled";
-+ };
-+
-+ syscrg: clock-controller@13020000 {
-+ compatible = "starfive,jh7110-syscrg";
-+ reg = <0x0 0x13020000 0x0 0x10000>;
-+ clocks = <&osc>, <&gmac1_rmii_refin>,
-+ <&gmac1_rgmii_rxin>,
-+ <&i2stx_bclk_ext>, <&i2stx_lrck_ext>,
-+ <&i2srx_bclk_ext>, <&i2srx_lrck_ext>,
-+ <&tdm_ext>, <&mclk_ext>;
-+ clock-names = "osc", "gmac1_rmii_refin",
-+ "gmac1_rgmii_rxin",
-+ "i2stx_bclk_ext", "i2stx_lrck_ext",
-+ "i2srx_bclk_ext", "i2srx_lrck_ext",
-+ "tdm_ext", "mclk_ext";
-+ #clock-cells = <1>;
-+ #reset-cells = <1>;
-+ };
-+
-+ sysgpio: pinctrl@13040000 {
-+ compatible = "starfive,jh7110-sys-pinctrl";
-+ reg = <0x0 0x13040000 0x0 0x10000>;
-+ clocks = <&syscrg JH7110_SYSCLK_IOMUX_APB>;
-+ resets = <&syscrg JH7110_SYSRST_IOMUX_APB>;
-+ interrupts = <86>;
-+ interrupt-controller;
-+ #interrupt-cells = <2>;
-+ gpio-controller;
-+ #gpio-cells = <2>;
-+ };
-+
-+ aoncrg: clock-controller@17000000 {
-+ compatible = "starfive,jh7110-aoncrg";
-+ reg = <0x0 0x17000000 0x0 0x10000>;
-+ clocks = <&osc>, <&gmac0_rmii_refin>,
-+ <&gmac0_rgmii_rxin>,
-+ <&syscrg JH7110_SYSCLK_STG_AXIAHB>,
-+ <&syscrg JH7110_SYSCLK_APB_BUS>,
-+ <&syscrg JH7110_SYSCLK_GMAC0_GTXCLK>,
-+ <&rtc_osc>;
-+ clock-names = "osc", "gmac0_rmii_refin",
-+ "gmac0_rgmii_rxin", "stg_axiahb",
-+ "apb_bus", "gmac0_gtxclk",
-+ "rtc_osc";
-+ #clock-cells = <1>;
-+ #reset-cells = <1>;
-+ };
-+
-+ aongpio: pinctrl@17020000 {
-+ compatible = "starfive,jh7110-aon-pinctrl";
-+ reg = <0x0 0x17020000 0x0 0x10000>;
-+ resets = <&aoncrg JH7110_AONRST_IOMUX>;
-+ interrupts = <85>;
-+ interrupt-controller;
-+ #interrupt-cells = <2>;
-+ gpio-controller;
-+ #gpio-cells = <2>;
-+ };
-+ };
-+};
diff --git a/target/linux/starfive/patches-6.1/0022-riscv-dts-starfive-Add-StarFive-JH7110-pin-function-.patch b/target/linux/starfive/patches-6.1/0022-riscv-dts-starfive-Add-StarFive-JH7110-pin-function-.patch
deleted file mode 100644
index 9c329d019f..0000000000
--- a/target/linux/starfive/patches-6.1/0022-riscv-dts-starfive-Add-StarFive-JH7110-pin-function-.patch
+++ /dev/null
@@ -1,331 +0,0 @@
-From 878c16d22c0feb52c3af65139734b8bb45e349e1 Mon Sep 17 00:00:00 2001
-From: Jianlong Huang <jianlong.huang@starfivetech.com>
-Date: Sat, 1 Apr 2023 19:19:32 +0800
-Subject: [PATCH 022/122] riscv: dts: starfive: Add StarFive JH7110 pin
- function definitions
-
-Add pin function definitions for StarFive JH7110 SoC.
-
-Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
-Co-developed-by: Emil Renner Berthing <kernel@esmil.dk>
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
-Signed-off-by: Jianlong Huang <jianlong.huang@starfivetech.com>
-Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
-Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
-Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
----
- arch/riscv/boot/dts/starfive/jh7110-pinfunc.h | 308 ++++++++++++++++++
- 1 file changed, 308 insertions(+)
- create mode 100644 arch/riscv/boot/dts/starfive/jh7110-pinfunc.h
-
---- /dev/null
-+++ b/arch/riscv/boot/dts/starfive/jh7110-pinfunc.h
-@@ -0,0 +1,308 @@
-+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
-+/*
-+ * Copyright (C) 2022 Emil Renner Berthing <kernel@esmil.dk>
-+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
-+ */
-+
-+#ifndef __JH7110_PINFUNC_H__
-+#define __JH7110_PINFUNC_H__
-+
-+/*
-+ * mux bits:
-+ * | 31 - 24 | 23 - 16 | 15 - 10 | 9 - 8 | 7 - 0 |
-+ * | din | dout | doen | function | gpio nr |
-+ *
-+ * dout: output signal
-+ * doen: output enable signal
-+ * din: optional input signal, 0xff = none
-+ * function: function selector
-+ * gpio nr: gpio number, 0 - 63
-+ */
-+#define GPIOMUX(n, dout, doen, din) ( \
-+ (((din) & 0xff) << 24) | \
-+ (((dout) & 0xff) << 16) | \
-+ (((doen) & 0x3f) << 10) | \
-+ ((n) & 0x3f))
-+
-+#define PINMUX(n, func) ((1 << 10) | (((func) & 0x3) << 8) | ((n) & 0xff))
-+
-+/* sys_iomux dout */
-+#define GPOUT_LOW 0
-+#define GPOUT_HIGH 1
-+#define GPOUT_SYS_WAVE511_UART_TX 2
-+#define GPOUT_SYS_CAN0_STBY 3
-+#define GPOUT_SYS_CAN0_TST_NEXT_BIT 4
-+#define GPOUT_SYS_CAN0_TST_SAMPLE_POINT 5
-+#define GPOUT_SYS_CAN0_TXD 6
-+#define GPOUT_SYS_USB_DRIVE_VBUS 7
-+#define GPOUT_SYS_QSPI_CS1 8
-+#define GPOUT_SYS_SPDIF 9
-+#define GPOUT_SYS_HDMI_CEC_SDA 10
-+#define GPOUT_SYS_HDMI_DDC_SCL 11
-+#define GPOUT_SYS_HDMI_DDC_SDA 12
-+#define GPOUT_SYS_WATCHDOG 13
-+#define GPOUT_SYS_I2C0_CLK 14
-+#define GPOUT_SYS_I2C0_DATA 15
-+#define GPOUT_SYS_SDIO0_BACK_END_POWER 16
-+#define GPOUT_SYS_SDIO0_CARD_POWER_EN 17
-+#define GPOUT_SYS_SDIO0_CCMD_OD_PULLUP_EN 18
-+#define GPOUT_SYS_SDIO0_RST 19
-+#define GPOUT_SYS_UART0_TX 20
-+#define GPOUT_SYS_HIFI4_JTAG_TDO 21
-+#define GPOUT_SYS_JTAG_TDO 22
-+#define GPOUT_SYS_PDM_MCLK 23
-+#define GPOUT_SYS_PWM_CHANNEL0 24
-+#define GPOUT_SYS_PWM_CHANNEL1 25
-+#define GPOUT_SYS_PWM_CHANNEL2 26
-+#define GPOUT_SYS_PWM_CHANNEL3 27
-+#define GPOUT_SYS_PWMDAC_LEFT 28
-+#define GPOUT_SYS_PWMDAC_RIGHT 29
-+#define GPOUT_SYS_SPI0_CLK 30
-+#define GPOUT_SYS_SPI0_FSS 31
-+#define GPOUT_SYS_SPI0_TXD 32
-+#define GPOUT_SYS_GMAC_PHYCLK 33
-+#define GPOUT_SYS_I2SRX_BCLK 34
-+#define GPOUT_SYS_I2SRX_LRCK 35
-+#define GPOUT_SYS_I2STX0_BCLK 36
-+#define GPOUT_SYS_I2STX0_LRCK 37
-+#define GPOUT_SYS_MCLK 38
-+#define GPOUT_SYS_TDM_CLK 39
-+#define GPOUT_SYS_TDM_SYNC 40
-+#define GPOUT_SYS_TDM_TXD 41
-+#define GPOUT_SYS_TRACE_DATA0 42
-+#define GPOUT_SYS_TRACE_DATA1 43
-+#define GPOUT_SYS_TRACE_DATA2 44
-+#define GPOUT_SYS_TRACE_DATA3 45
-+#define GPOUT_SYS_TRACE_REF 46
-+#define GPOUT_SYS_CAN1_STBY 47
-+#define GPOUT_SYS_CAN1_TST_NEXT_BIT 48
-+#define GPOUT_SYS_CAN1_TST_SAMPLE_POINT 49
-+#define GPOUT_SYS_CAN1_TXD 50
-+#define GPOUT_SYS_I2C1_CLK 51
-+#define GPOUT_SYS_I2C1_DATA 52
-+#define GPOUT_SYS_SDIO1_BACK_END_POWER 53
-+#define GPOUT_SYS_SDIO1_CARD_POWER_EN 54
-+#define GPOUT_SYS_SDIO1_CLK 55
-+#define GPOUT_SYS_SDIO1_CMD_OD_PULLUP_EN 56
-+#define GPOUT_SYS_SDIO1_CMD 57
-+#define GPOUT_SYS_SDIO1_DATA0 58
-+#define GPOUT_SYS_SDIO1_DATA1 59
-+#define GPOUT_SYS_SDIO1_DATA2 60
-+#define GPOUT_SYS_SDIO1_DATA3 61
-+#define GPOUT_SYS_SDIO1_DATA4 63
-+#define GPOUT_SYS_SDIO1_DATA5 63
-+#define GPOUT_SYS_SDIO1_DATA6 64
-+#define GPOUT_SYS_SDIO1_DATA7 65
-+#define GPOUT_SYS_SDIO1_RST 66
-+#define GPOUT_SYS_UART1_RTS 67
-+#define GPOUT_SYS_UART1_TX 68
-+#define GPOUT_SYS_I2STX1_SDO0 69
-+#define GPOUT_SYS_I2STX1_SDO1 70
-+#define GPOUT_SYS_I2STX1_SDO2 71
-+#define GPOUT_SYS_I2STX1_SDO3 72
-+#define GPOUT_SYS_SPI1_CLK 73
-+#define GPOUT_SYS_SPI1_FSS 74
-+#define GPOUT_SYS_SPI1_TXD 75
-+#define GPOUT_SYS_I2C2_CLK 76
-+#define GPOUT_SYS_I2C2_DATA 77
-+#define GPOUT_SYS_UART2_RTS 78
-+#define GPOUT_SYS_UART2_TX 79
-+#define GPOUT_SYS_SPI2_CLK 80
-+#define GPOUT_SYS_SPI2_FSS 81
-+#define GPOUT_SYS_SPI2_TXD 82
-+#define GPOUT_SYS_I2C3_CLK 83
-+#define GPOUT_SYS_I2C3_DATA 84
-+#define GPOUT_SYS_UART3_TX 85
-+#define GPOUT_SYS_SPI3_CLK 86
-+#define GPOUT_SYS_SPI3_FSS 87
-+#define GPOUT_SYS_SPI3_TXD 88
-+#define GPOUT_SYS_I2C4_CLK 89
-+#define GPOUT_SYS_I2C4_DATA 90
-+#define GPOUT_SYS_UART4_RTS 91
-+#define GPOUT_SYS_UART4_TX 92
-+#define GPOUT_SYS_SPI4_CLK 93
-+#define GPOUT_SYS_SPI4_FSS 94
-+#define GPOUT_SYS_SPI4_TXD 95
-+#define GPOUT_SYS_I2C5_CLK 96
-+#define GPOUT_SYS_I2C5_DATA 97
-+#define GPOUT_SYS_UART5_RTS 98
-+#define GPOUT_SYS_UART5_TX 99
-+#define GPOUT_SYS_SPI5_CLK 100
-+#define GPOUT_SYS_SPI5_FSS 101
-+#define GPOUT_SYS_SPI5_TXD 102
-+#define GPOUT_SYS_I2C6_CLK 103
-+#define GPOUT_SYS_I2C6_DATA 104
-+#define GPOUT_SYS_SPI6_CLK 105
-+#define GPOUT_SYS_SPI6_FSS 106
-+#define GPOUT_SYS_SPI6_TXD 107
-+
-+/* aon_iomux dout */
-+#define GPOUT_AON_CLK_32K_OUT 2
-+#define GPOUT_AON_PTC0_PWM4 3
-+#define GPOUT_AON_PTC0_PWM5 4
-+#define GPOUT_AON_PTC0_PWM6 5
-+#define GPOUT_AON_PTC0_PWM7 6
-+#define GPOUT_AON_CLK_GCLK0 7
-+#define GPOUT_AON_CLK_GCLK1 8
-+#define GPOUT_AON_CLK_GCLK2 9
-+
-+/* sys_iomux doen */
-+#define GPOEN_ENABLE 0
-+#define GPOEN_DISABLE 1
-+#define GPOEN_SYS_HDMI_CEC_SDA 2
-+#define GPOEN_SYS_HDMI_DDC_SCL 3
-+#define GPOEN_SYS_HDMI_DDC_SDA 4
-+#define GPOEN_SYS_I2C0_CLK 5
-+#define GPOEN_SYS_I2C0_DATA 6
-+#define GPOEN_SYS_HIFI4_JTAG_TDO 7
-+#define GPOEN_SYS_JTAG_TDO 8
-+#define GPOEN_SYS_PWM0_CHANNEL0 9
-+#define GPOEN_SYS_PWM0_CHANNEL1 10
-+#define GPOEN_SYS_PWM0_CHANNEL2 11
-+#define GPOEN_SYS_PWM0_CHANNEL3 12
-+#define GPOEN_SYS_SPI0_NSSPCTL 13
-+#define GPOEN_SYS_SPI0_NSSP 14
-+#define GPOEN_SYS_TDM_SYNC 15
-+#define GPOEN_SYS_TDM_TXD 16
-+#define GPOEN_SYS_I2C1_CLK 17
-+#define GPOEN_SYS_I2C1_DATA 18
-+#define GPOEN_SYS_SDIO1_CMD 19
-+#define GPOEN_SYS_SDIO1_DATA0 20
-+#define GPOEN_SYS_SDIO1_DATA1 21
-+#define GPOEN_SYS_SDIO1_DATA2 22
-+#define GPOEN_SYS_SDIO1_DATA3 23
-+#define GPOEN_SYS_SDIO1_DATA4 24
-+#define GPOEN_SYS_SDIO1_DATA5 25
-+#define GPOEN_SYS_SDIO1_DATA6 26
-+#define GPOEN_SYS_SDIO1_DATA7 27
-+#define GPOEN_SYS_SPI1_NSSPCTL 28
-+#define GPOEN_SYS_SPI1_NSSP 29
-+#define GPOEN_SYS_I2C2_CLK 30
-+#define GPOEN_SYS_I2C2_DATA 31
-+#define GPOEN_SYS_SPI2_NSSPCTL 32
-+#define GPOEN_SYS_SPI2_NSSP 33
-+#define GPOEN_SYS_I2C3_CLK 34
-+#define GPOEN_SYS_I2C3_DATA 35
-+#define GPOEN_SYS_SPI3_NSSPCTL 36
-+#define GPOEN_SYS_SPI3_NSSP 37
-+#define GPOEN_SYS_I2C4_CLK 38
-+#define GPOEN_SYS_I2C4_DATA 39
-+#define GPOEN_SYS_SPI4_NSSPCTL 40
-+#define GPOEN_SYS_SPI4_NSSP 41
-+#define GPOEN_SYS_I2C5_CLK 42
-+#define GPOEN_SYS_I2C5_DATA 43
-+#define GPOEN_SYS_SPI5_NSSPCTL 44
-+#define GPOEN_SYS_SPI5_NSSP 45
-+#define GPOEN_SYS_I2C6_CLK 46
-+#define GPOEN_SYS_I2C6_DATA 47
-+#define GPOEN_SYS_SPI6_NSSPCTL 48
-+#define GPOEN_SYS_SPI6_NSSP 49
-+
-+/* aon_iomux doen */
-+#define GPOEN_AON_PTC0_OE_N_4 2
-+#define GPOEN_AON_PTC0_OE_N_5 3
-+#define GPOEN_AON_PTC0_OE_N_6 4
-+#define GPOEN_AON_PTC0_OE_N_7 5
-+
-+/* sys_iomux gin */
-+#define GPI_NONE 255
-+
-+#define GPI_SYS_WAVE511_UART_RX 0
-+#define GPI_SYS_CAN0_RXD 1
-+#define GPI_SYS_USB_OVERCURRENT 2
-+#define GPI_SYS_SPDIF 3
-+#define GPI_SYS_JTAG_RST 4
-+#define GPI_SYS_HDMI_CEC_SDA 5
-+#define GPI_SYS_HDMI_DDC_SCL 6
-+#define GPI_SYS_HDMI_DDC_SDA 7
-+#define GPI_SYS_HDMI_HPD 8
-+#define GPI_SYS_I2C0_CLK 9
-+#define GPI_SYS_I2C0_DATA 10
-+#define GPI_SYS_SDIO0_CD 11
-+#define GPI_SYS_SDIO0_INT 12
-+#define GPI_SYS_SDIO0_WP 13
-+#define GPI_SYS_UART0_RX 14
-+#define GPI_SYS_HIFI4_JTAG_TCK 15
-+#define GPI_SYS_HIFI4_JTAG_TDI 16
-+#define GPI_SYS_HIFI4_JTAG_TMS 17
-+#define GPI_SYS_HIFI4_JTAG_RST 18
-+#define GPI_SYS_JTAG_TDI 19
-+#define GPI_SYS_JTAG_TMS 20
-+#define GPI_SYS_PDM_DMIC0 21
-+#define GPI_SYS_PDM_DMIC1 22
-+#define GPI_SYS_I2SRX_SDIN0 23
-+#define GPI_SYS_I2SRX_SDIN1 24
-+#define GPI_SYS_I2SRX_SDIN2 25
-+#define GPI_SYS_SPI0_CLK 26
-+#define GPI_SYS_SPI0_FSS 27
-+#define GPI_SYS_SPI0_RXD 28
-+#define GPI_SYS_JTAG_TCK 29
-+#define GPI_SYS_MCLK_EXT 30
-+#define GPI_SYS_I2SRX_BCLK 31
-+#define GPI_SYS_I2SRX_LRCK 32
-+#define GPI_SYS_I2STX0_BCLK 33
-+#define GPI_SYS_I2STX0_LRCK 34
-+#define GPI_SYS_TDM_CLK 35
-+#define GPI_SYS_TDM_RXD 36
-+#define GPI_SYS_TDM_SYNC 37
-+#define GPI_SYS_CAN1_RXD 38
-+#define GPI_SYS_I2C1_CLK 39
-+#define GPI_SYS_I2C1_DATA 40
-+#define GPI_SYS_SDIO1_CD 41
-+#define GPI_SYS_SDIO1_INT 42
-+#define GPI_SYS_SDIO1_WP 43
-+#define GPI_SYS_SDIO1_CMD 44
-+#define GPI_SYS_SDIO1_DATA0 45
-+#define GPI_SYS_SDIO1_DATA1 46
-+#define GPI_SYS_SDIO1_DATA2 47
-+#define GPI_SYS_SDIO1_DATA3 48
-+#define GPI_SYS_SDIO1_DATA4 49
-+#define GPI_SYS_SDIO1_DATA5 50
-+#define GPI_SYS_SDIO1_DATA6 51
-+#define GPI_SYS_SDIO1_DATA7 52
-+#define GPI_SYS_SDIO1_STRB 53
-+#define GPI_SYS_UART1_CTS 54
-+#define GPI_SYS_UART1_RX 55
-+#define GPI_SYS_SPI1_CLK 56
-+#define GPI_SYS_SPI1_FSS 57
-+#define GPI_SYS_SPI1_RXD 58
-+#define GPI_SYS_I2C2_CLK 59
-+#define GPI_SYS_I2C2_DATA 60
-+#define GPI_SYS_UART2_CTS 61
-+#define GPI_SYS_UART2_RX 62
-+#define GPI_SYS_SPI2_CLK 63
-+#define GPI_SYS_SPI2_FSS 64
-+#define GPI_SYS_SPI2_RXD 65
-+#define GPI_SYS_I2C3_CLK 66
-+#define GPI_SYS_I2C3_DATA 67
-+#define GPI_SYS_UART3_RX 68
-+#define GPI_SYS_SPI3_CLK 69
-+#define GPI_SYS_SPI3_FSS 70
-+#define GPI_SYS_SPI3_RXD 71
-+#define GPI_SYS_I2C4_CLK 72
-+#define GPI_SYS_I2C4_DATA 73
-+#define GPI_SYS_UART4_CTS 74
-+#define GPI_SYS_UART4_RX 75
-+#define GPI_SYS_SPI4_CLK 76
-+#define GPI_SYS_SPI4_FSS 77
-+#define GPI_SYS_SPI4_RXD 78
-+#define GPI_SYS_I2C5_CLK 79
-+#define GPI_SYS_I2C5_DATA 80
-+#define GPI_SYS_UART5_CTS 81
-+#define GPI_SYS_UART5_RX 82
-+#define GPI_SYS_SPI5_CLK 83
-+#define GPI_SYS_SPI5_FSS 84
-+#define GPI_SYS_SPI5_RXD 85
-+#define GPI_SYS_I2C6_CLK 86
-+#define GPI_SYS_I2C6_DATA 87
-+#define GPI_SYS_SPI6_CLK 88
-+#define GPI_SYS_SPI6_FSS 89
-+#define GPI_SYS_SPI6_RXD 90
-+
-+/* aon_iomux gin */
-+#define GPI_AON_PMU_GPIO_WAKEUP_0 0
-+#define GPI_AON_PMU_GPIO_WAKEUP_1 1
-+#define GPI_AON_PMU_GPIO_WAKEUP_2 2
-+#define GPI_AON_PMU_GPIO_WAKEUP_3 3
-+
-+#endif
diff --git a/target/linux/starfive/patches-6.1/0023-riscv-dts-starfive-Add-StarFive-JH7110-VisionFive-2-.patch b/target/linux/starfive/patches-6.1/0023-riscv-dts-starfive-Add-StarFive-JH7110-VisionFive-2-.patch
deleted file mode 100644
index 9e311bf527..0000000000
--- a/target/linux/starfive/patches-6.1/0023-riscv-dts-starfive-Add-StarFive-JH7110-VisionFive-2-.patch
+++ /dev/null
@@ -1,290 +0,0 @@
-From 76bc84c399f11c7d6a37fe68cbd5f182e4c18369 Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Sat, 1 Apr 2023 19:19:33 +0800
-Subject: [PATCH 023/122] riscv: dts: starfive: Add StarFive JH7110 VisionFive
- 2 board device tree
-
-Add a minimal device tree for StarFive JH7110 VisionFive 2 board
-which has version A and version B. Support booting and basic
-clock/reset/pinctrl/uart drivers.
-
-Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
-Acked-by: Conor Dooley <conor.dooley@microchip.com>
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
-Co-developed-by: Jianlong Huang <jianlong.huang@starfivetech.com>
-Signed-off-by: Jianlong Huang <jianlong.huang@starfivetech.com>
-Co-developed-by: Hal Feng <hal.feng@starfivetech.com>
-Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
-Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
-Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
----
- arch/riscv/boot/dts/starfive/Makefile | 6 +-
- .../jh7110-starfive-visionfive-2-v1.2a.dts | 13 ++
- .../jh7110-starfive-visionfive-2-v1.3b.dts | 13 ++
- .../jh7110-starfive-visionfive-2.dtsi | 215 ++++++++++++++++++
- 4 files changed, 246 insertions(+), 1 deletion(-)
- create mode 100644 arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-v1.2a.dts
- create mode 100644 arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-v1.3b.dts
- create mode 100644 arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
-
---- a/arch/riscv/boot/dts/starfive/Makefile
-+++ b/arch/riscv/boot/dts/starfive/Makefile
-@@ -1,2 +1,6 @@
- # SPDX-License-Identifier: GPL-2.0
--dtb-$(CONFIG_SOC_STARFIVE) += jh7100-beaglev-starlight.dtb
-+dtb-$(CONFIG_ARCH_STARFIVE) += jh7100-beaglev-starlight.dtb
-+dtb-$(CONFIG_ARCH_STARFIVE) += jh7100-starfive-visionfive-v1.dtb
-+
-+dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-starfive-visionfive-2-v1.2a.dtb
-+dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-starfive-visionfive-2-v1.3b.dtb
---- /dev/null
-+++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-v1.2a.dts
-@@ -0,0 +1,13 @@
-+// SPDX-License-Identifier: GPL-2.0 OR MIT
-+/*
-+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
-+ * Copyright (C) 2022 Emil Renner Berthing <kernel@esmil.dk>
-+ */
-+
-+/dts-v1/;
-+#include "jh7110-starfive-visionfive-2.dtsi"
-+
-+/ {
-+ model = "StarFive VisionFive 2 v1.2A";
-+ compatible = "starfive,visionfive-2-v1.2a", "starfive,jh7110";
-+};
---- /dev/null
-+++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-v1.3b.dts
-@@ -0,0 +1,13 @@
-+// SPDX-License-Identifier: GPL-2.0 OR MIT
-+/*
-+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
-+ * Copyright (C) 2022 Emil Renner Berthing <kernel@esmil.dk>
-+ */
-+
-+/dts-v1/;
-+#include "jh7110-starfive-visionfive-2.dtsi"
-+
-+/ {
-+ model = "StarFive VisionFive 2 v1.3B";
-+ compatible = "starfive,visionfive-2-v1.3b", "starfive,jh7110";
-+};
---- /dev/null
-+++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
-@@ -0,0 +1,215 @@
-+// SPDX-License-Identifier: GPL-2.0 OR MIT
-+/*
-+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
-+ * Copyright (C) 2022 Emil Renner Berthing <kernel@esmil.dk>
-+ */
-+
-+/dts-v1/;
-+#include "jh7110.dtsi"
-+#include "jh7110-pinfunc.h"
-+#include <dt-bindings/gpio/gpio.h>
-+
-+/ {
-+ aliases {
-+ i2c0 = &i2c0;
-+ i2c2 = &i2c2;
-+ i2c5 = &i2c5;
-+ i2c6 = &i2c6;
-+ serial0 = &uart0;
-+ };
-+
-+ chosen {
-+ stdout-path = "serial0:115200n8";
-+ };
-+
-+ cpus {
-+ timebase-frequency = <4000000>;
-+ };
-+
-+ memory@40000000 {
-+ device_type = "memory";
-+ reg = <0x0 0x40000000 0x1 0x0>;
-+ };
-+
-+ gpio-restart {
-+ compatible = "gpio-restart";
-+ gpios = <&sysgpio 35 GPIO_ACTIVE_HIGH>;
-+ priority = <224>;
-+ };
-+};
-+
-+&gmac0_rgmii_rxin {
-+ clock-frequency = <125000000>;
-+};
-+
-+&gmac0_rmii_refin {
-+ clock-frequency = <50000000>;
-+};
-+
-+&gmac1_rgmii_rxin {
-+ clock-frequency = <125000000>;
-+};
-+
-+&gmac1_rmii_refin {
-+ clock-frequency = <50000000>;
-+};
-+
-+&i2srx_bclk_ext {
-+ clock-frequency = <12288000>;
-+};
-+
-+&i2srx_lrck_ext {
-+ clock-frequency = <192000>;
-+};
-+
-+&i2stx_bclk_ext {
-+ clock-frequency = <12288000>;
-+};
-+
-+&i2stx_lrck_ext {
-+ clock-frequency = <192000>;
-+};
-+
-+&mclk_ext {
-+ clock-frequency = <12288000>;
-+};
-+
-+&osc {
-+ clock-frequency = <24000000>;
-+};
-+
-+&rtc_osc {
-+ clock-frequency = <32768>;
-+};
-+
-+&tdm_ext {
-+ clock-frequency = <49152000>;
-+};
-+
-+&i2c0 {
-+ clock-frequency = <100000>;
-+ i2c-sda-hold-time-ns = <300>;
-+ i2c-sda-falling-time-ns = <510>;
-+ i2c-scl-falling-time-ns = <510>;
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&i2c0_pins>;
-+ status = "okay";
-+};
-+
-+&i2c2 {
-+ clock-frequency = <100000>;
-+ i2c-sda-hold-time-ns = <300>;
-+ i2c-sda-falling-time-ns = <510>;
-+ i2c-scl-falling-time-ns = <510>;
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&i2c2_pins>;
-+ status = "okay";
-+};
-+
-+&i2c5 {
-+ clock-frequency = <100000>;
-+ i2c-sda-hold-time-ns = <300>;
-+ i2c-sda-falling-time-ns = <510>;
-+ i2c-scl-falling-time-ns = <510>;
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&i2c5_pins>;
-+ status = "okay";
-+};
-+
-+&i2c6 {
-+ clock-frequency = <100000>;
-+ i2c-sda-hold-time-ns = <300>;
-+ i2c-sda-falling-time-ns = <510>;
-+ i2c-scl-falling-time-ns = <510>;
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&i2c6_pins>;
-+ status = "okay";
-+};
-+
-+&sysgpio {
-+ i2c0_pins: i2c0-0 {
-+ i2c-pins {
-+ pinmux = <GPIOMUX(57, GPOUT_LOW,
-+ GPOEN_SYS_I2C0_CLK,
-+ GPI_SYS_I2C0_CLK)>,
-+ <GPIOMUX(58, GPOUT_LOW,
-+ GPOEN_SYS_I2C0_DATA,
-+ GPI_SYS_I2C0_DATA)>;
-+ bias-disable; /* external pull-up */
-+ input-enable;
-+ input-schmitt-enable;
-+ };
-+ };
-+
-+ i2c2_pins: i2c2-0 {
-+ i2c-pins {
-+ pinmux = <GPIOMUX(3, GPOUT_LOW,
-+ GPOEN_SYS_I2C2_CLK,
-+ GPI_SYS_I2C2_CLK)>,
-+ <GPIOMUX(2, GPOUT_LOW,
-+ GPOEN_SYS_I2C2_DATA,
-+ GPI_SYS_I2C2_DATA)>;
-+ bias-disable; /* external pull-up */
-+ input-enable;
-+ input-schmitt-enable;
-+ };
-+ };
-+
-+ i2c5_pins: i2c5-0 {
-+ i2c-pins {
-+ pinmux = <GPIOMUX(19, GPOUT_LOW,
-+ GPOEN_SYS_I2C5_CLK,
-+ GPI_SYS_I2C5_CLK)>,
-+ <GPIOMUX(20, GPOUT_LOW,
-+ GPOEN_SYS_I2C5_DATA,
-+ GPI_SYS_I2C5_DATA)>;
-+ bias-disable; /* external pull-up */
-+ input-enable;
-+ input-schmitt-enable;
-+ };
-+ };
-+
-+ i2c6_pins: i2c6-0 {
-+ i2c-pins {
-+ pinmux = <GPIOMUX(16, GPOUT_LOW,
-+ GPOEN_SYS_I2C6_CLK,
-+ GPI_SYS_I2C6_CLK)>,
-+ <GPIOMUX(17, GPOUT_LOW,
-+ GPOEN_SYS_I2C6_DATA,
-+ GPI_SYS_I2C6_DATA)>;
-+ bias-disable; /* external pull-up */
-+ input-enable;
-+ input-schmitt-enable;
-+ };
-+ };
-+
-+ uart0_pins: uart0-0 {
-+ tx-pins {
-+ pinmux = <GPIOMUX(5, GPOUT_SYS_UART0_TX,
-+ GPOEN_ENABLE,
-+ GPI_NONE)>;
-+ bias-disable;
-+ drive-strength = <12>;
-+ input-disable;
-+ input-schmitt-disable;
-+ slew-rate = <0>;
-+ };
-+
-+ rx-pins {
-+ pinmux = <GPIOMUX(6, GPOUT_LOW,
-+ GPOEN_DISABLE,
-+ GPI_SYS_UART0_RX)>;
-+ bias-disable; /* external pull-up */
-+ drive-strength = <2>;
-+ input-enable;
-+ input-schmitt-enable;
-+ slew-rate = <0>;
-+ };
-+ };
-+};
-+
-+&uart0 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&uart0_pins>;
-+ status = "okay";
-+};
diff --git a/target/linux/starfive/patches-6.1/0024-riscv-dts-starfive-Add-StarFive-VisionFive-V1-device.patch b/target/linux/starfive/patches-6.1/0024-riscv-dts-starfive-Add-StarFive-VisionFive-V1-device.patch
deleted file mode 100644
index f823aff9a1..0000000000
--- a/target/linux/starfive/patches-6.1/0024-riscv-dts-starfive-Add-StarFive-VisionFive-V1-device.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-From cbb348ddbc68fe4fc8ac80bed11c298149e7893f Mon Sep 17 00:00:00 2001
-From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
-Date: Tue, 18 Oct 2022 00:05:42 +0300
-Subject: [PATCH 024/122] riscv: dts: starfive: Add StarFive VisionFive V1
- device tree
-
-Add initial device tree for the StarFive VisionFive V1 SBC, which
-is similar with the already supported BeagleV Starlight Beta board,
-both being based on the StarFive JH7100 SoC.
-
-Link: https://github.com/starfive-tech/VisionFive
-Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
-Reviewed-by: Matthias Brugger <mbrugger@suse.com>
-Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
----
- .../jh7100-starfive-visionfive-v1.dts | 20 +++++++++++++++++++
- 1 file changed, 20 insertions(+)
- create mode 100644 arch/riscv/boot/dts/starfive/jh7100-starfive-visionfive-v1.dts
-
---- /dev/null
-+++ b/arch/riscv/boot/dts/starfive/jh7100-starfive-visionfive-v1.dts
-@@ -0,0 +1,20 @@
-+// SPDX-License-Identifier: GPL-2.0 OR MIT
-+/*
-+ * Copyright (C) 2021 StarFive Technology Co., Ltd.
-+ * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
-+ */
-+
-+/dts-v1/;
-+#include "jh7100-common.dtsi"
-+#include <dt-bindings/gpio/gpio.h>
-+
-+/ {
-+ model = "StarFive VisionFive V1";
-+ compatible = "starfive,visionfive-v1", "starfive,jh7100";
-+
-+ gpio-restart {
-+ compatible = "gpio-restart";
-+ gpios = <&gpio 63 GPIO_ACTIVE_HIGH>;
-+ priority = <224>;
-+ };
-+};
diff --git a/target/linux/starfive/patches-6.1/0025-riscv-dts-starfive-Add-common-DT-for-JH7100-based-bo.patch b/target/linux/starfive/patches-6.1/0025-riscv-dts-starfive-Add-common-DT-for-JH7100-based-bo.patch
deleted file mode 100644
index 44b5836c34..0000000000
--- a/target/linux/starfive/patches-6.1/0025-riscv-dts-starfive-Add-common-DT-for-JH7100-based-bo.patch
+++ /dev/null
@@ -1,349 +0,0 @@
-From 2101233d71b74e33de33e4cc292c6a8cf5da9d42 Mon Sep 17 00:00:00 2001
-From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
-Date: Tue, 18 Oct 2022 00:05:41 +0300
-Subject: [PATCH 025/122] riscv: dts: starfive: Add common DT for JH7100 based
- boards
-
-In preparation for adding initial device tree support for the StarFive
-VisionFive board, which is similar with BeagleV Starlight, move most
-of the content from jh7100-beaglev-starlight.dts to a new file, to be
-shared between the two boards.
-
-Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
-Reviewed-by: Matthias Brugger <mbrugger@suse.com>
-Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
----
- .../dts/starfive/jh7100-beaglev-starlight.dts | 153 +----------------
- .../boot/dts/starfive/jh7100-common.dtsi | 161 ++++++++++++++++++
- 2 files changed, 162 insertions(+), 152 deletions(-)
- create mode 100644 arch/riscv/boot/dts/starfive/jh7100-common.dtsi
-
---- a/arch/riscv/boot/dts/starfive/jh7100-beaglev-starlight.dts
-+++ b/arch/riscv/boot/dts/starfive/jh7100-beaglev-starlight.dts
-@@ -5,160 +5,9 @@
- */
-
- /dts-v1/;
--#include "jh7100.dtsi"
--#include <dt-bindings/gpio/gpio.h>
--#include <dt-bindings/leds/common.h>
--#include <dt-bindings/pinctrl/pinctrl-starfive-jh7100.h>
-+#include "jh7100-common.dtsi"
-
- / {
- model = "BeagleV Starlight Beta";
- compatible = "beagle,beaglev-starlight-jh7100-r0", "starfive,jh7100";
--
-- aliases {
-- serial0 = &uart3;
-- };
--
-- chosen {
-- stdout-path = "serial0:115200n8";
-- };
--
-- cpus {
-- timebase-frequency = <6250000>;
-- };
--
-- memory@80000000 {
-- device_type = "memory";
-- reg = <0x0 0x80000000 0x2 0x0>;
-- };
--
-- leds {
-- compatible = "gpio-leds";
--
-- led-ack {
-- gpios = <&gpio 43 GPIO_ACTIVE_HIGH>;
-- color = <LED_COLOR_ID_GREEN>;
-- function = LED_FUNCTION_HEARTBEAT;
-- linux,default-trigger = "heartbeat";
-- label = "ack";
-- };
-- };
--};
--
--&gpio {
-- i2c0_pins: i2c0-0 {
-- i2c-pins {
-- pinmux = <GPIOMUX(62, GPO_LOW,
-- GPO_I2C0_PAD_SCK_OEN,
-- GPI_I2C0_PAD_SCK_IN)>,
-- <GPIOMUX(61, GPO_LOW,
-- GPO_I2C0_PAD_SDA_OEN,
-- GPI_I2C0_PAD_SDA_IN)>;
-- bias-disable; /* external pull-up */
-- input-enable;
-- input-schmitt-enable;
-- };
-- };
--
-- i2c1_pins: i2c1-0 {
-- i2c-pins {
-- pinmux = <GPIOMUX(47, GPO_LOW,
-- GPO_I2C1_PAD_SCK_OEN,
-- GPI_I2C1_PAD_SCK_IN)>,
-- <GPIOMUX(48, GPO_LOW,
-- GPO_I2C1_PAD_SDA_OEN,
-- GPI_I2C1_PAD_SDA_IN)>;
-- bias-pull-up;
-- input-enable;
-- input-schmitt-enable;
-- };
-- };
--
-- i2c2_pins: i2c2-0 {
-- i2c-pins {
-- pinmux = <GPIOMUX(60, GPO_LOW,
-- GPO_I2C2_PAD_SCK_OEN,
-- GPI_I2C2_PAD_SCK_IN)>,
-- <GPIOMUX(59, GPO_LOW,
-- GPO_I2C2_PAD_SDA_OEN,
-- GPI_I2C2_PAD_SDA_IN)>;
-- bias-disable; /* external pull-up */
-- input-enable;
-- input-schmitt-enable;
-- };
-- };
--
-- uart3_pins: uart3-0 {
-- rx-pins {
-- pinmux = <GPIOMUX(13, GPO_LOW, GPO_DISABLE,
-- GPI_UART3_PAD_SIN)>;
-- bias-pull-up;
-- drive-strength = <14>;
-- input-enable;
-- input-schmitt-enable;
-- slew-rate = <0>;
-- };
-- tx-pins {
-- pinmux = <GPIOMUX(14, GPO_UART3_PAD_SOUT,
-- GPO_ENABLE, GPI_NONE)>;
-- bias-disable;
-- drive-strength = <35>;
-- input-disable;
-- input-schmitt-disable;
-- slew-rate = <0>;
-- };
-- };
--};
--
--&i2c0 {
-- clock-frequency = <100000>;
-- i2c-sda-hold-time-ns = <300>;
-- i2c-sda-falling-time-ns = <500>;
-- i2c-scl-falling-time-ns = <500>;
-- pinctrl-names = "default";
-- pinctrl-0 = <&i2c0_pins>;
-- status = "okay";
--
-- pmic@5e {
-- compatible = "ti,tps65086";
-- reg = <0x5e>;
-- gpio-controller;
-- #gpio-cells = <2>;
--
-- regulators {
-- };
-- };
--};
--
--&i2c1 {
-- clock-frequency = <400000>;
-- i2c-sda-hold-time-ns = <300>;
-- i2c-sda-falling-time-ns = <100>;
-- i2c-scl-falling-time-ns = <100>;
-- pinctrl-names = "default";
-- pinctrl-0 = <&i2c1_pins>;
-- status = "okay";
--};
--
--&i2c2 {
-- clock-frequency = <100000>;
-- i2c-sda-hold-time-ns = <300>;
-- i2c-sda-falling-time-ns = <500>;
-- i2c-scl-falling-time-ns = <500>;
-- pinctrl-names = "default";
-- pinctrl-0 = <&i2c2_pins>;
-- status = "okay";
--};
--
--&osc_sys {
-- clock-frequency = <25000000>;
--};
--
--&osc_aud {
-- clock-frequency = <27000000>;
--};
--
--&uart3 {
-- pinctrl-names = "default";
-- pinctrl-0 = <&uart3_pins>;
-- status = "okay";
- };
---- /dev/null
-+++ b/arch/riscv/boot/dts/starfive/jh7100-common.dtsi
-@@ -0,0 +1,161 @@
-+// SPDX-License-Identifier: GPL-2.0 OR MIT
-+/*
-+ * Copyright (C) 2021 StarFive Technology Co., Ltd.
-+ * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
-+ */
-+
-+/dts-v1/;
-+#include "jh7100.dtsi"
-+#include <dt-bindings/gpio/gpio.h>
-+#include <dt-bindings/leds/common.h>
-+#include <dt-bindings/pinctrl/pinctrl-starfive-jh7100.h>
-+
-+/ {
-+ aliases {
-+ serial0 = &uart3;
-+ };
-+
-+ chosen {
-+ stdout-path = "serial0:115200n8";
-+ };
-+
-+ cpus {
-+ timebase-frequency = <6250000>;
-+ };
-+
-+ memory@80000000 {
-+ device_type = "memory";
-+ reg = <0x0 0x80000000 0x2 0x0>;
-+ };
-+
-+ leds {
-+ compatible = "gpio-leds";
-+
-+ led-ack {
-+ gpios = <&gpio 43 GPIO_ACTIVE_HIGH>;
-+ color = <LED_COLOR_ID_GREEN>;
-+ function = LED_FUNCTION_HEARTBEAT;
-+ linux,default-trigger = "heartbeat";
-+ label = "ack";
-+ };
-+ };
-+};
-+
-+&gpio {
-+ i2c0_pins: i2c0-0 {
-+ i2c-pins {
-+ pinmux = <GPIOMUX(62, GPO_LOW,
-+ GPO_I2C0_PAD_SCK_OEN,
-+ GPI_I2C0_PAD_SCK_IN)>,
-+ <GPIOMUX(61, GPO_LOW,
-+ GPO_I2C0_PAD_SDA_OEN,
-+ GPI_I2C0_PAD_SDA_IN)>;
-+ bias-disable; /* external pull-up */
-+ input-enable;
-+ input-schmitt-enable;
-+ };
-+ };
-+
-+ i2c1_pins: i2c1-0 {
-+ i2c-pins {
-+ pinmux = <GPIOMUX(47, GPO_LOW,
-+ GPO_I2C1_PAD_SCK_OEN,
-+ GPI_I2C1_PAD_SCK_IN)>,
-+ <GPIOMUX(48, GPO_LOW,
-+ GPO_I2C1_PAD_SDA_OEN,
-+ GPI_I2C1_PAD_SDA_IN)>;
-+ bias-pull-up;
-+ input-enable;
-+ input-schmitt-enable;
-+ };
-+ };
-+
-+ i2c2_pins: i2c2-0 {
-+ i2c-pins {
-+ pinmux = <GPIOMUX(60, GPO_LOW,
-+ GPO_I2C2_PAD_SCK_OEN,
-+ GPI_I2C2_PAD_SCK_IN)>,
-+ <GPIOMUX(59, GPO_LOW,
-+ GPO_I2C2_PAD_SDA_OEN,
-+ GPI_I2C2_PAD_SDA_IN)>;
-+ bias-disable; /* external pull-up */
-+ input-enable;
-+ input-schmitt-enable;
-+ };
-+ };
-+
-+ uart3_pins: uart3-0 {
-+ rx-pins {
-+ pinmux = <GPIOMUX(13, GPO_LOW, GPO_DISABLE,
-+ GPI_UART3_PAD_SIN)>;
-+ bias-pull-up;
-+ drive-strength = <14>;
-+ input-enable;
-+ input-schmitt-enable;
-+ slew-rate = <0>;
-+ };
-+ tx-pins {
-+ pinmux = <GPIOMUX(14, GPO_UART3_PAD_SOUT,
-+ GPO_ENABLE, GPI_NONE)>;
-+ bias-disable;
-+ drive-strength = <35>;
-+ input-disable;
-+ input-schmitt-disable;
-+ slew-rate = <0>;
-+ };
-+ };
-+};
-+
-+&i2c0 {
-+ clock-frequency = <100000>;
-+ i2c-sda-hold-time-ns = <300>;
-+ i2c-sda-falling-time-ns = <500>;
-+ i2c-scl-falling-time-ns = <500>;
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&i2c0_pins>;
-+ status = "okay";
-+
-+ pmic@5e {
-+ compatible = "ti,tps65086";
-+ reg = <0x5e>;
-+ gpio-controller;
-+ #gpio-cells = <2>;
-+
-+ regulators {
-+ };
-+ };
-+};
-+
-+&i2c1 {
-+ clock-frequency = <400000>;
-+ i2c-sda-hold-time-ns = <300>;
-+ i2c-sda-falling-time-ns = <100>;
-+ i2c-scl-falling-time-ns = <100>;
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&i2c1_pins>;
-+ status = "okay";
-+};
-+
-+&i2c2 {
-+ clock-frequency = <100000>;
-+ i2c-sda-hold-time-ns = <300>;
-+ i2c-sda-falling-time-ns = <500>;
-+ i2c-scl-falling-time-ns = <500>;
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&i2c2_pins>;
-+ status = "okay";
-+};
-+
-+&osc_sys {
-+ clock-frequency = <25000000>;
-+};
-+
-+&osc_aud {
-+ clock-frequency = <27000000>;
-+};
-+
-+&uart3 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&uart3_pins>;
-+ status = "okay";
-+};
diff --git a/target/linux/starfive/patches-6.1/0026-dt-bindings-pinctrl-Add-StarFive-JH7110-sys-pinctrl.patch b/target/linux/starfive/patches-6.1/0026-dt-bindings-pinctrl-Add-StarFive-JH7110-sys-pinctrl.patch
deleted file mode 100644
index 9b3f41ec1e..0000000000
--- a/target/linux/starfive/patches-6.1/0026-dt-bindings-pinctrl-Add-StarFive-JH7110-sys-pinctrl.patch
+++ /dev/null
@@ -1,303 +0,0 @@
-From 28518a9637fee6b84464beff9d4308edc3efba72 Mon Sep 17 00:00:00 2001
-From: Jianlong Huang <jianlong.huang@starfivetech.com>
-Date: Thu, 9 Feb 2023 22:36:59 +0800
-Subject: [PATCH 026/122] dt-bindings: pinctrl: Add StarFive JH7110 sys pinctrl
-
-Add pinctrl bindings for StarFive JH7110 SoC sys pinctrl controller.
-
-Reviewed-by: Rob Herring <robh@kernel.org>
-Signed-off-by: Jianlong Huang <jianlong.huang@starfivetech.com>
-Co-developed-by: Emil Renner Berthing <kernel@esmil.dk>
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
-Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
----
- .../pinctrl/starfive,jh7110-sys-pinctrl.yaml | 142 ++++++++++++++++++
- MAINTAINERS | 6 +-
- .../pinctrl/starfive,jh7110-pinctrl.h | 115 ++++++++++++++
- 3 files changed, 261 insertions(+), 2 deletions(-)
- create mode 100644 Documentation/devicetree/bindings/pinctrl/starfive,jh7110-sys-pinctrl.yaml
- create mode 100644 include/dt-bindings/pinctrl/starfive,jh7110-pinctrl.h
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/pinctrl/starfive,jh7110-sys-pinctrl.yaml
-@@ -0,0 +1,142 @@
-+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/pinctrl/starfive,jh7110-sys-pinctrl.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: StarFive JH7110 SYS Pin Controller
-+
-+description: |
-+ Bindings for the JH7110 RISC-V SoC from StarFive Technology Ltd.
-+
-+ Out of the SoC's many pins only the ones named PAD_GPIO0 to PAD_GPIO63
-+ can be multiplexed and have configurable bias, drive strength,
-+ schmitt trigger etc.
-+ Some peripherals have their I/O go through the 64 "GPIOs". This also
-+ includes a number of other UARTs, I2Cs, SPIs, PWMs etc.
-+ All these peripherals are connected to all 64 GPIOs such that
-+ any GPIO can be set up to be controlled by any of the peripherals.
-+
-+maintainers:
-+ - Jianlong Huang <jianlong.huang@starfivetech.com>
-+
-+properties:
-+ compatible:
-+ const: starfive,jh7110-sys-pinctrl
-+
-+ reg:
-+ maxItems: 1
-+
-+ clocks:
-+ maxItems: 1
-+
-+ resets:
-+ maxItems: 1
-+
-+ interrupts:
-+ maxItems: 1
-+
-+ interrupt-controller: true
-+
-+ '#interrupt-cells':
-+ const: 2
-+
-+ gpio-controller: true
-+
-+ '#gpio-cells':
-+ const: 2
-+
-+patternProperties:
-+ '-[0-9]+$':
-+ type: object
-+ additionalProperties: false
-+ patternProperties:
-+ '-pins$':
-+ type: object
-+ description: |
-+ A pinctrl node should contain at least one subnode representing the
-+ pinctrl groups available on the machine. Each subnode will list the
-+ pins it needs, and how they should be configured, with regard to
-+ muxer configuration, bias, input enable/disable, input schmitt
-+ trigger enable/disable, slew-rate and drive strength.
-+ allOf:
-+ - $ref: /schemas/pinctrl/pincfg-node.yaml
-+ - $ref: /schemas/pinctrl/pinmux-node.yaml
-+ additionalProperties: false
-+
-+ properties:
-+ pinmux:
-+ description: |
-+ The list of GPIOs and their mux settings that properties in the
-+ node apply to. This should be set using the GPIOMUX or PINMUX
-+ macros.
-+
-+ bias-disable: true
-+
-+ bias-pull-up:
-+ type: boolean
-+
-+ bias-pull-down:
-+ type: boolean
-+
-+ drive-strength:
-+ enum: [ 2, 4, 8, 12 ]
-+
-+ input-enable: true
-+
-+ input-disable: true
-+
-+ input-schmitt-enable: true
-+
-+ input-schmitt-disable: true
-+
-+ slew-rate:
-+ maximum: 1
-+
-+required:
-+ - compatible
-+ - reg
-+ - clocks
-+ - interrupts
-+ - interrupt-controller
-+ - '#interrupt-cells'
-+ - gpio-controller
-+ - '#gpio-cells'
-+
-+additionalProperties: false
-+
-+examples:
-+ - |
-+ pinctrl@13040000 {
-+ compatible = "starfive,jh7110-sys-pinctrl";
-+ reg = <0x13040000 0x10000>;
-+ clocks = <&syscrg 112>;
-+ resets = <&syscrg 2>;
-+ interrupts = <86>;
-+ interrupt-controller;
-+ #interrupt-cells = <2>;
-+ gpio-controller;
-+ #gpio-cells = <2>;
-+
-+ uart0-0 {
-+ tx-pins {
-+ pinmux = <0xff140005>;
-+ bias-disable;
-+ drive-strength = <12>;
-+ input-disable;
-+ input-schmitt-disable;
-+ slew-rate = <0>;
-+ };
-+
-+ rx-pins {
-+ pinmux = <0x0E000406>;
-+ bias-pull-up;
-+ drive-strength = <2>;
-+ input-enable;
-+ input-schmitt-enable;
-+ slew-rate = <0>;
-+ };
-+ };
-+ };
-+
-+...
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -19665,13 +19665,15 @@ F: Documentation/devicetree/bindings/clo
- F: drivers/clk/starfive/clk-starfive-jh71*
- F: include/dt-bindings/clock/starfive?jh71*.h
-
--STARFIVE JH7100 PINCTRL DRIVER
-+STARFIVE JH71X0 PINCTRL DRIVERS
- M: Emil Renner Berthing <kernel@esmil.dk>
-+M: Jianlong Huang <jianlong.huang@starfivetech.com>
- L: linux-gpio@vger.kernel.org
- S: Maintained
--F: Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml
-+F: Documentation/devicetree/bindings/pinctrl/starfive,jh71*.yaml
- F: drivers/pinctrl/starfive/
- F: include/dt-bindings/pinctrl/pinctrl-starfive-jh7100.h
-+F: include/dt-bindings/pinctrl/starfive,jh7110-pinctrl.h
-
- STARFIVE JH71X0 RESET CONTROLLER DRIVERS
- M: Emil Renner Berthing <kernel@esmil.dk>
---- /dev/null
-+++ b/include/dt-bindings/pinctrl/starfive,jh7110-pinctrl.h
-@@ -0,0 +1,115 @@
-+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
-+/*
-+ * Copyright (C) 2022 Emil Renner Berthing <kernel@esmil.dk>
-+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
-+ */
-+
-+#ifndef __DT_BINDINGS_PINCTRL_STARFIVE_JH7110_H__
-+#define __DT_BINDINGS_PINCTRL_STARFIVE_JH7110_H__
-+
-+/* sys_iomux pins */
-+#define PAD_GPIO0 0
-+#define PAD_GPIO1 1
-+#define PAD_GPIO2 2
-+#define PAD_GPIO3 3
-+#define PAD_GPIO4 4
-+#define PAD_GPIO5 5
-+#define PAD_GPIO6 6
-+#define PAD_GPIO7 7
-+#define PAD_GPIO8 8
-+#define PAD_GPIO9 9
-+#define PAD_GPIO10 10
-+#define PAD_GPIO11 11
-+#define PAD_GPIO12 12
-+#define PAD_GPIO13 13
-+#define PAD_GPIO14 14
-+#define PAD_GPIO15 15
-+#define PAD_GPIO16 16
-+#define PAD_GPIO17 17
-+#define PAD_GPIO18 18
-+#define PAD_GPIO19 19
-+#define PAD_GPIO20 20
-+#define PAD_GPIO21 21
-+#define PAD_GPIO22 22
-+#define PAD_GPIO23 23
-+#define PAD_GPIO24 24
-+#define PAD_GPIO25 25
-+#define PAD_GPIO26 26
-+#define PAD_GPIO27 27
-+#define PAD_GPIO28 28
-+#define PAD_GPIO29 29
-+#define PAD_GPIO30 30
-+#define PAD_GPIO31 31
-+#define PAD_GPIO32 32
-+#define PAD_GPIO33 33
-+#define PAD_GPIO34 34
-+#define PAD_GPIO35 35
-+#define PAD_GPIO36 36
-+#define PAD_GPIO37 37
-+#define PAD_GPIO38 38
-+#define PAD_GPIO39 39
-+#define PAD_GPIO40 40
-+#define PAD_GPIO41 41
-+#define PAD_GPIO42 42
-+#define PAD_GPIO43 43
-+#define PAD_GPIO44 44
-+#define PAD_GPIO45 45
-+#define PAD_GPIO46 46
-+#define PAD_GPIO47 47
-+#define PAD_GPIO48 48
-+#define PAD_GPIO49 49
-+#define PAD_GPIO50 50
-+#define PAD_GPIO51 51
-+#define PAD_GPIO52 52
-+#define PAD_GPIO53 53
-+#define PAD_GPIO54 54
-+#define PAD_GPIO55 55
-+#define PAD_GPIO56 56
-+#define PAD_GPIO57 57
-+#define PAD_GPIO58 58
-+#define PAD_GPIO59 59
-+#define PAD_GPIO60 60
-+#define PAD_GPIO61 61
-+#define PAD_GPIO62 62
-+#define PAD_GPIO63 63
-+#define PAD_SD0_CLK 64
-+#define PAD_SD0_CMD 65
-+#define PAD_SD0_DATA0 66
-+#define PAD_SD0_DATA1 67
-+#define PAD_SD0_DATA2 68
-+#define PAD_SD0_DATA3 69
-+#define PAD_SD0_DATA4 70
-+#define PAD_SD0_DATA5 71
-+#define PAD_SD0_DATA6 72
-+#define PAD_SD0_DATA7 73
-+#define PAD_SD0_STRB 74
-+#define PAD_GMAC1_MDC 75
-+#define PAD_GMAC1_MDIO 76
-+#define PAD_GMAC1_RXD0 77
-+#define PAD_GMAC1_RXD1 78
-+#define PAD_GMAC1_RXD2 79
-+#define PAD_GMAC1_RXD3 80
-+#define PAD_GMAC1_RXDV 81
-+#define PAD_GMAC1_RXC 82
-+#define PAD_GMAC1_TXD0 83
-+#define PAD_GMAC1_TXD1 84
-+#define PAD_GMAC1_TXD2 85
-+#define PAD_GMAC1_TXD3 86
-+#define PAD_GMAC1_TXEN 87
-+#define PAD_GMAC1_TXC 88
-+#define PAD_QSPI_SCLK 89
-+#define PAD_QSPI_CS0 90
-+#define PAD_QSPI_DATA0 91
-+#define PAD_QSPI_DATA1 92
-+#define PAD_QSPI_DATA2 93
-+#define PAD_QSPI_DATA3 94
-+
-+#define GPOUT_LOW 0
-+#define GPOUT_HIGH 1
-+
-+#define GPOEN_ENABLE 0
-+#define GPOEN_DISABLE 1
-+
-+#define GPI_NONE 255
-+
-+#endif
diff --git a/target/linux/starfive/patches-6.1/0027-dt-bindings-pinctrl-Add-StarFive-JH7110-aon-pinctrl.patch b/target/linux/starfive/patches-6.1/0027-dt-bindings-pinctrl-Add-StarFive-JH7110-aon-pinctrl.patch
deleted file mode 100644
index 8ef08efca1..0000000000
--- a/target/linux/starfive/patches-6.1/0027-dt-bindings-pinctrl-Add-StarFive-JH7110-aon-pinctrl.patch
+++ /dev/null
@@ -1,176 +0,0 @@
-From 514cae455122c799638226f4358e8e6f5e155248 Mon Sep 17 00:00:00 2001
-From: Jianlong Huang <jianlong.huang@starfivetech.com>
-Date: Thu, 9 Feb 2023 22:37:00 +0800
-Subject: [PATCH 027/122] dt-bindings: pinctrl: Add StarFive JH7110 aon pinctrl
-
-Add pinctrl bindings for StarFive JH7110 SoC aon pinctrl controller.
-
-Reviewed-by: Rob Herring <robh@kernel.org>
-Signed-off-by: Jianlong Huang <jianlong.huang@starfivetech.com>
-Co-developed-by: Emil Renner Berthing <kernel@esmil.dk>
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
-Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
----
- .../pinctrl/starfive,jh7110-aon-pinctrl.yaml | 124 ++++++++++++++++++
- .../pinctrl/starfive,jh7110-pinctrl.h | 22 ++++
- 2 files changed, 146 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/pinctrl/starfive,jh7110-aon-pinctrl.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/pinctrl/starfive,jh7110-aon-pinctrl.yaml
-@@ -0,0 +1,124 @@
-+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/pinctrl/starfive,jh7110-aon-pinctrl.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: StarFive JH7110 AON Pin Controller
-+
-+description: |
-+ Bindings for the JH7110 RISC-V SoC from StarFive Technology Ltd.
-+
-+ Out of the SoC's many pins only the ones named PAD_RGPIO0 to PAD_RGPIO3
-+ can be multiplexed and have configurable bias, drive strength,
-+ schmitt trigger etc.
-+ Some peripherals such as PWM have their I/O go through the 4 "GPIOs".
-+
-+maintainers:
-+ - Jianlong Huang <jianlong.huang@starfivetech.com>
-+
-+properties:
-+ compatible:
-+ const: starfive,jh7110-aon-pinctrl
-+
-+ reg:
-+ maxItems: 1
-+
-+ resets:
-+ maxItems: 1
-+
-+ interrupts:
-+ maxItems: 1
-+
-+ interrupt-controller: true
-+
-+ '#interrupt-cells':
-+ const: 2
-+
-+ gpio-controller: true
-+
-+ '#gpio-cells':
-+ const: 2
-+
-+patternProperties:
-+ '-[0-9]+$':
-+ type: object
-+ additionalProperties: false
-+ patternProperties:
-+ '-pins$':
-+ type: object
-+ description: |
-+ A pinctrl node should contain at least one subnode representing the
-+ pinctrl groups available on the machine. Each subnode will list the
-+ pins it needs, and how they should be configured, with regard to
-+ muxer configuration, bias, input enable/disable, input schmitt
-+ trigger enable/disable, slew-rate and drive strength.
-+ allOf:
-+ - $ref: /schemas/pinctrl/pincfg-node.yaml
-+ - $ref: /schemas/pinctrl/pinmux-node.yaml
-+ additionalProperties: false
-+
-+ properties:
-+ pinmux:
-+ description: |
-+ The list of GPIOs and their mux settings that properties in the
-+ node apply to. This should be set using the GPIOMUX macro.
-+
-+ bias-disable: true
-+
-+ bias-pull-up:
-+ type: boolean
-+
-+ bias-pull-down:
-+ type: boolean
-+
-+ drive-strength:
-+ enum: [ 2, 4, 8, 12 ]
-+
-+ input-enable: true
-+
-+ input-disable: true
-+
-+ input-schmitt-enable: true
-+
-+ input-schmitt-disable: true
-+
-+ slew-rate:
-+ maximum: 1
-+
-+required:
-+ - compatible
-+ - reg
-+ - interrupts
-+ - interrupt-controller
-+ - '#interrupt-cells'
-+ - gpio-controller
-+ - '#gpio-cells'
-+
-+additionalProperties: false
-+
-+examples:
-+ - |
-+ pinctrl@17020000 {
-+ compatible = "starfive,jh7110-aon-pinctrl";
-+ reg = <0x17020000 0x10000>;
-+ resets = <&aoncrg 2>;
-+ interrupts = <85>;
-+ interrupt-controller;
-+ #interrupt-cells = <2>;
-+ gpio-controller;
-+ #gpio-cells = <2>;
-+
-+ pwm-0 {
-+ pwm-pins {
-+ pinmux = <0xff030802>;
-+ bias-disable;
-+ drive-strength = <12>;
-+ input-disable;
-+ input-schmitt-disable;
-+ slew-rate = <0>;
-+ };
-+ };
-+ };
-+
-+...
---- a/include/dt-bindings/pinctrl/starfive,jh7110-pinctrl.h
-+++ b/include/dt-bindings/pinctrl/starfive,jh7110-pinctrl.h
-@@ -104,6 +104,28 @@
- #define PAD_QSPI_DATA2 93
- #define PAD_QSPI_DATA3 94
-
-+/* aon_iomux pins */
-+#define PAD_TESTEN 0
-+#define PAD_RGPIO0 1
-+#define PAD_RGPIO1 2
-+#define PAD_RGPIO2 3
-+#define PAD_RGPIO3 4
-+#define PAD_RSTN 5
-+#define PAD_GMAC0_MDC 6
-+#define PAD_GMAC0_MDIO 7
-+#define PAD_GMAC0_RXD0 8
-+#define PAD_GMAC0_RXD1 9
-+#define PAD_GMAC0_RXD2 10
-+#define PAD_GMAC0_RXD3 11
-+#define PAD_GMAC0_RXDV 12
-+#define PAD_GMAC0_RXC 13
-+#define PAD_GMAC0_TXD0 14
-+#define PAD_GMAC0_TXD1 15
-+#define PAD_GMAC0_TXD2 16
-+#define PAD_GMAC0_TXD3 17
-+#define PAD_GMAC0_TXEN 18
-+#define PAD_GMAC0_TXC 19
-+
- #define GPOUT_LOW 0
- #define GPOUT_HIGH 1
-
diff --git a/target/linux/starfive/patches-6.1/0028-pinctrl-starfive-Add-StarFive-JH7110-sys-controller-.patch b/target/linux/starfive/patches-6.1/0028-pinctrl-starfive-Add-StarFive-JH7110-sys-controller-.patch
deleted file mode 100644
index d5735b5980..0000000000
--- a/target/linux/starfive/patches-6.1/0028-pinctrl-starfive-Add-StarFive-JH7110-sys-controller-.patch
+++ /dev/null
@@ -1,1581 +0,0 @@
-From 4dba3156173e59131d234d702388ee7283bac8a9 Mon Sep 17 00:00:00 2001
-From: Jianlong Huang <jianlong.huang@starfivetech.com>
-Date: Thu, 9 Feb 2023 22:37:01 +0800
-Subject: [PATCH 028/122] pinctrl: starfive: Add StarFive JH7110 sys controller
- driver
-
-Add pinctrl driver for StarFive JH7110 SoC sys pinctrl controller.
-
-Co-developed-by: Emil Renner Berthing <kernel@esmil.dk>
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
-Signed-off-by: Jianlong Huang <jianlong.huang@starfivetech.com>
-Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
----
- MAINTAINERS | 2 +-
- drivers/pinctrl/starfive/Kconfig | 21 +
- drivers/pinctrl/starfive/Makefile | 3 +
- .../starfive/pinctrl-starfive-jh7110-sys.c | 449 ++++++++
- .../starfive/pinctrl-starfive-jh7110.c | 982 ++++++++++++++++++
- .../starfive/pinctrl-starfive-jh7110.h | 70 ++
- 6 files changed, 1526 insertions(+), 1 deletion(-)
- create mode 100644 drivers/pinctrl/starfive/pinctrl-starfive-jh7110-sys.c
- create mode 100644 drivers/pinctrl/starfive/pinctrl-starfive-jh7110.c
- create mode 100644 drivers/pinctrl/starfive/pinctrl-starfive-jh7110.h
-
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -19671,7 +19671,7 @@ M: Jianlong Huang <jianlong.huang@starfi
- L: linux-gpio@vger.kernel.org
- S: Maintained
- F: Documentation/devicetree/bindings/pinctrl/starfive,jh71*.yaml
--F: drivers/pinctrl/starfive/
-+F: drivers/pinctrl/starfive/pinctrl-starfive-jh71*
- F: include/dt-bindings/pinctrl/pinctrl-starfive-jh7100.h
- F: include/dt-bindings/pinctrl/starfive,jh7110-pinctrl.h
-
---- a/drivers/pinctrl/starfive/Kconfig
-+++ b/drivers/pinctrl/starfive/Kconfig
-@@ -16,3 +16,24 @@ config PINCTRL_STARFIVE_JH7100
- This also provides an interface to the GPIO pins not used by other
- peripherals supporting inputs, outputs, configuring pull-up/pull-down
- and interrupts on input changes.
-+
-+config PINCTRL_STARFIVE_JH7110
-+ bool
-+ select GENERIC_PINCTRL_GROUPS
-+ select GENERIC_PINMUX_FUNCTIONS
-+ select GENERIC_PINCONF
-+ select GPIOLIB
-+ select GPIOLIB_IRQCHIP
-+ select OF_GPIO
-+
-+config PINCTRL_STARFIVE_JH7110_SYS
-+ tristate "System pinctrl and GPIO driver for the StarFive JH7110 SoC"
-+ depends on SOC_STARFIVE || COMPILE_TEST
-+ depends on OF
-+ select PINCTRL_STARFIVE_JH7110
-+ default SOC_STARFIVE
-+ help
-+ Say yes here to support system pin control on the StarFive JH7110 SoC.
-+ This also provides an interface to the GPIO pins not used by other
-+ peripherals supporting inputs, outputs, configuring pull-up/pull-down
-+ and interrupts on input changes.
---- a/drivers/pinctrl/starfive/Makefile
-+++ b/drivers/pinctrl/starfive/Makefile
-@@ -1,3 +1,6 @@
- # SPDX-License-Identifier: GPL-2.0
-
- obj-$(CONFIG_PINCTRL_STARFIVE_JH7100) += pinctrl-starfive-jh7100.o
-+
-+obj-$(CONFIG_PINCTRL_STARFIVE_JH7110) += pinctrl-starfive-jh7110.o
-+obj-$(CONFIG_PINCTRL_STARFIVE_JH7110_SYS) += pinctrl-starfive-jh7110-sys.o
---- /dev/null
-+++ b/drivers/pinctrl/starfive/pinctrl-starfive-jh7110-sys.c
-@@ -0,0 +1,449 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Pinctrl / GPIO driver for StarFive JH7110 SoC sys controller
-+ *
-+ * Copyright (C) 2022 Emil Renner Berthing <kernel@esmil.dk>
-+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
-+ */
-+
-+#include <linux/bits.h>
-+#include <linux/clk.h>
-+#include <linux/gpio/driver.h>
-+#include <linux/io.h>
-+#include <linux/mod_devicetable.h>
-+#include <linux/module.h>
-+#include <linux/mutex.h>
-+#include <linux/of.h>
-+#include <linux/of_device.h>
-+#include <linux/platform_device.h>
-+#include <linux/reset.h>
-+#include <linux/spinlock.h>
-+
-+#include <linux/pinctrl/pinctrl.h>
-+#include <linux/pinctrl/pinmux.h>
-+
-+#include <dt-bindings/pinctrl/starfive,jh7110-pinctrl.h>
-+
-+#include "../core.h"
-+#include "../pinctrl-utils.h"
-+#include "../pinmux.h"
-+#include "../pinconf.h"
-+#include "pinctrl-starfive-jh7110.h"
-+
-+#define JH7110_SYS_NGPIO 64
-+#define JH7110_SYS_GC_BASE 0
-+
-+/* registers */
-+#define JH7110_SYS_DOEN 0x000
-+#define JH7110_SYS_DOUT 0x040
-+#define JH7110_SYS_GPI 0x080
-+#define JH7110_SYS_GPIOIN 0x118
-+
-+#define JH7110_SYS_GPIOEN 0x0dc
-+#define JH7110_SYS_GPIOIS0 0x0e0
-+#define JH7110_SYS_GPIOIS1 0x0e4
-+#define JH7110_SYS_GPIOIC0 0x0e8
-+#define JH7110_SYS_GPIOIC1 0x0ec
-+#define JH7110_SYS_GPIOIBE0 0x0f0
-+#define JH7110_SYS_GPIOIBE1 0x0f4
-+#define JH7110_SYS_GPIOIEV0 0x0f8
-+#define JH7110_SYS_GPIOIEV1 0x0fc
-+#define JH7110_SYS_GPIOIE0 0x100
-+#define JH7110_SYS_GPIOIE1 0x104
-+#define JH7110_SYS_GPIORIS0 0x108
-+#define JH7110_SYS_GPIORIS1 0x10c
-+#define JH7110_SYS_GPIOMIS0 0x110
-+#define JH7110_SYS_GPIOMIS1 0x114
-+
-+#define JH7110_SYS_GPO_PDA_0_74_CFG 0x120
-+#define JH7110_SYS_GPO_PDA_89_94_CFG 0x284
-+
-+static const struct pinctrl_pin_desc jh7110_sys_pins[] = {
-+ PINCTRL_PIN(PAD_GPIO0, "GPIO0"),
-+ PINCTRL_PIN(PAD_GPIO1, "GPIO1"),
-+ PINCTRL_PIN(PAD_GPIO2, "GPIO2"),
-+ PINCTRL_PIN(PAD_GPIO3, "GPIO3"),
-+ PINCTRL_PIN(PAD_GPIO4, "GPIO4"),
-+ PINCTRL_PIN(PAD_GPIO5, "GPIO5"),
-+ PINCTRL_PIN(PAD_GPIO6, "GPIO6"),
-+ PINCTRL_PIN(PAD_GPIO7, "GPIO7"),
-+ PINCTRL_PIN(PAD_GPIO8, "GPIO8"),
-+ PINCTRL_PIN(PAD_GPIO9, "GPIO9"),
-+ PINCTRL_PIN(PAD_GPIO10, "GPIO10"),
-+ PINCTRL_PIN(PAD_GPIO11, "GPIO11"),
-+ PINCTRL_PIN(PAD_GPIO12, "GPIO12"),
-+ PINCTRL_PIN(PAD_GPIO13, "GPIO13"),
-+ PINCTRL_PIN(PAD_GPIO14, "GPIO14"),
-+ PINCTRL_PIN(PAD_GPIO15, "GPIO15"),
-+ PINCTRL_PIN(PAD_GPIO16, "GPIO16"),
-+ PINCTRL_PIN(PAD_GPIO17, "GPIO17"),
-+ PINCTRL_PIN(PAD_GPIO18, "GPIO18"),
-+ PINCTRL_PIN(PAD_GPIO19, "GPIO19"),
-+ PINCTRL_PIN(PAD_GPIO20, "GPIO20"),
-+ PINCTRL_PIN(PAD_GPIO21, "GPIO21"),
-+ PINCTRL_PIN(PAD_GPIO22, "GPIO22"),
-+ PINCTRL_PIN(PAD_GPIO23, "GPIO23"),
-+ PINCTRL_PIN(PAD_GPIO24, "GPIO24"),
-+ PINCTRL_PIN(PAD_GPIO25, "GPIO25"),
-+ PINCTRL_PIN(PAD_GPIO26, "GPIO26"),
-+ PINCTRL_PIN(PAD_GPIO27, "GPIO27"),
-+ PINCTRL_PIN(PAD_GPIO28, "GPIO28"),
-+ PINCTRL_PIN(PAD_GPIO29, "GPIO29"),
-+ PINCTRL_PIN(PAD_GPIO30, "GPIO30"),
-+ PINCTRL_PIN(PAD_GPIO31, "GPIO31"),
-+ PINCTRL_PIN(PAD_GPIO32, "GPIO32"),
-+ PINCTRL_PIN(PAD_GPIO33, "GPIO33"),
-+ PINCTRL_PIN(PAD_GPIO34, "GPIO34"),
-+ PINCTRL_PIN(PAD_GPIO35, "GPIO35"),
-+ PINCTRL_PIN(PAD_GPIO36, "GPIO36"),
-+ PINCTRL_PIN(PAD_GPIO37, "GPIO37"),
-+ PINCTRL_PIN(PAD_GPIO38, "GPIO38"),
-+ PINCTRL_PIN(PAD_GPIO39, "GPIO39"),
-+ PINCTRL_PIN(PAD_GPIO40, "GPIO40"),
-+ PINCTRL_PIN(PAD_GPIO41, "GPIO41"),
-+ PINCTRL_PIN(PAD_GPIO42, "GPIO42"),
-+ PINCTRL_PIN(PAD_GPIO43, "GPIO43"),
-+ PINCTRL_PIN(PAD_GPIO44, "GPIO44"),
-+ PINCTRL_PIN(PAD_GPIO45, "GPIO45"),
-+ PINCTRL_PIN(PAD_GPIO46, "GPIO46"),
-+ PINCTRL_PIN(PAD_GPIO47, "GPIO47"),
-+ PINCTRL_PIN(PAD_GPIO48, "GPIO48"),
-+ PINCTRL_PIN(PAD_GPIO49, "GPIO49"),
-+ PINCTRL_PIN(PAD_GPIO50, "GPIO50"),
-+ PINCTRL_PIN(PAD_GPIO51, "GPIO51"),
-+ PINCTRL_PIN(PAD_GPIO52, "GPIO52"),
-+ PINCTRL_PIN(PAD_GPIO53, "GPIO53"),
-+ PINCTRL_PIN(PAD_GPIO54, "GPIO54"),
-+ PINCTRL_PIN(PAD_GPIO55, "GPIO55"),
-+ PINCTRL_PIN(PAD_GPIO56, "GPIO56"),
-+ PINCTRL_PIN(PAD_GPIO57, "GPIO57"),
-+ PINCTRL_PIN(PAD_GPIO58, "GPIO58"),
-+ PINCTRL_PIN(PAD_GPIO59, "GPIO59"),
-+ PINCTRL_PIN(PAD_GPIO60, "GPIO60"),
-+ PINCTRL_PIN(PAD_GPIO61, "GPIO61"),
-+ PINCTRL_PIN(PAD_GPIO62, "GPIO62"),
-+ PINCTRL_PIN(PAD_GPIO63, "GPIO63"),
-+ PINCTRL_PIN(PAD_SD0_CLK, "SD0_CLK"),
-+ PINCTRL_PIN(PAD_SD0_CMD, "SD0_CMD"),
-+ PINCTRL_PIN(PAD_SD0_DATA0, "SD0_DATA0"),
-+ PINCTRL_PIN(PAD_SD0_DATA1, "SD0_DATA1"),
-+ PINCTRL_PIN(PAD_SD0_DATA2, "SD0_DATA2"),
-+ PINCTRL_PIN(PAD_SD0_DATA3, "SD0_DATA3"),
-+ PINCTRL_PIN(PAD_SD0_DATA4, "SD0_DATA4"),
-+ PINCTRL_PIN(PAD_SD0_DATA5, "SD0_DATA5"),
-+ PINCTRL_PIN(PAD_SD0_DATA6, "SD0_DATA6"),
-+ PINCTRL_PIN(PAD_SD0_DATA7, "SD0_DATA7"),
-+ PINCTRL_PIN(PAD_SD0_STRB, "SD0_STRB"),
-+ PINCTRL_PIN(PAD_GMAC1_MDC, "GMAC1_MDC"),
-+ PINCTRL_PIN(PAD_GMAC1_MDIO, "GMAC1_MDIO"),
-+ PINCTRL_PIN(PAD_GMAC1_RXD0, "GMAC1_RXD0"),
-+ PINCTRL_PIN(PAD_GMAC1_RXD1, "GMAC1_RXD1"),
-+ PINCTRL_PIN(PAD_GMAC1_RXD2, "GMAC1_RXD2"),
-+ PINCTRL_PIN(PAD_GMAC1_RXD3, "GMAC1_RXD3"),
-+ PINCTRL_PIN(PAD_GMAC1_RXDV, "GMAC1_RXDV"),
-+ PINCTRL_PIN(PAD_GMAC1_RXC, "GMAC1_RXC"),
-+ PINCTRL_PIN(PAD_GMAC1_TXD0, "GMAC1_TXD0"),
-+ PINCTRL_PIN(PAD_GMAC1_TXD1, "GMAC1_TXD1"),
-+ PINCTRL_PIN(PAD_GMAC1_TXD2, "GMAC1_TXD2"),
-+ PINCTRL_PIN(PAD_GMAC1_TXD3, "GMAC1_TXD3"),
-+ PINCTRL_PIN(PAD_GMAC1_TXEN, "GMAC1_TXEN"),
-+ PINCTRL_PIN(PAD_GMAC1_TXC, "GMAC1_TXC"),
-+ PINCTRL_PIN(PAD_QSPI_SCLK, "QSPI_SCLK"),
-+ PINCTRL_PIN(PAD_QSPI_CS0, "QSPI_CS0"),
-+ PINCTRL_PIN(PAD_QSPI_DATA0, "QSPI_DATA0"),
-+ PINCTRL_PIN(PAD_QSPI_DATA1, "QSPI_DATA1"),
-+ PINCTRL_PIN(PAD_QSPI_DATA2, "QSPI_DATA2"),
-+ PINCTRL_PIN(PAD_QSPI_DATA3, "QSPI_DATA3"),
-+};
-+
-+struct jh7110_func_sel {
-+ u16 offset;
-+ u8 shift;
-+ u8 max;
-+};
-+
-+static const struct jh7110_func_sel
-+ jh7110_sys_func_sel[ARRAY_SIZE(jh7110_sys_pins)] = {
-+ [PAD_GMAC1_RXC] = { 0x29c, 0, 1 },
-+ [PAD_GPIO10] = { 0x29c, 2, 3 },
-+ [PAD_GPIO11] = { 0x29c, 5, 3 },
-+ [PAD_GPIO12] = { 0x29c, 8, 3 },
-+ [PAD_GPIO13] = { 0x29c, 11, 3 },
-+ [PAD_GPIO14] = { 0x29c, 14, 3 },
-+ [PAD_GPIO15] = { 0x29c, 17, 3 },
-+ [PAD_GPIO16] = { 0x29c, 20, 3 },
-+ [PAD_GPIO17] = { 0x29c, 23, 3 },
-+ [PAD_GPIO18] = { 0x29c, 26, 3 },
-+ [PAD_GPIO19] = { 0x29c, 29, 3 },
-+
-+ [PAD_GPIO20] = { 0x2a0, 0, 3 },
-+ [PAD_GPIO21] = { 0x2a0, 3, 3 },
-+ [PAD_GPIO22] = { 0x2a0, 6, 3 },
-+ [PAD_GPIO23] = { 0x2a0, 9, 3 },
-+ [PAD_GPIO24] = { 0x2a0, 12, 3 },
-+ [PAD_GPIO25] = { 0x2a0, 15, 3 },
-+ [PAD_GPIO26] = { 0x2a0, 18, 3 },
-+ [PAD_GPIO27] = { 0x2a0, 21, 3 },
-+ [PAD_GPIO28] = { 0x2a0, 24, 3 },
-+ [PAD_GPIO29] = { 0x2a0, 27, 3 },
-+
-+ [PAD_GPIO30] = { 0x2a4, 0, 3 },
-+ [PAD_GPIO31] = { 0x2a4, 3, 3 },
-+ [PAD_GPIO32] = { 0x2a4, 6, 3 },
-+ [PAD_GPIO33] = { 0x2a4, 9, 3 },
-+ [PAD_GPIO34] = { 0x2a4, 12, 3 },
-+ [PAD_GPIO35] = { 0x2a4, 15, 3 },
-+ [PAD_GPIO36] = { 0x2a4, 17, 3 },
-+ [PAD_GPIO37] = { 0x2a4, 20, 3 },
-+ [PAD_GPIO38] = { 0x2a4, 23, 3 },
-+ [PAD_GPIO39] = { 0x2a4, 26, 3 },
-+ [PAD_GPIO40] = { 0x2a4, 29, 3 },
-+
-+ [PAD_GPIO41] = { 0x2a8, 0, 3 },
-+ [PAD_GPIO42] = { 0x2a8, 3, 3 },
-+ [PAD_GPIO43] = { 0x2a8, 6, 3 },
-+ [PAD_GPIO44] = { 0x2a8, 9, 3 },
-+ [PAD_GPIO45] = { 0x2a8, 12, 3 },
-+ [PAD_GPIO46] = { 0x2a8, 15, 3 },
-+ [PAD_GPIO47] = { 0x2a8, 18, 3 },
-+ [PAD_GPIO48] = { 0x2a8, 21, 3 },
-+ [PAD_GPIO49] = { 0x2a8, 24, 3 },
-+ [PAD_GPIO50] = { 0x2a8, 27, 3 },
-+ [PAD_GPIO51] = { 0x2a8, 30, 3 },
-+
-+ [PAD_GPIO52] = { 0x2ac, 0, 3 },
-+ [PAD_GPIO53] = { 0x2ac, 2, 3 },
-+ [PAD_GPIO54] = { 0x2ac, 4, 3 },
-+ [PAD_GPIO55] = { 0x2ac, 6, 3 },
-+ [PAD_GPIO56] = { 0x2ac, 9, 3 },
-+ [PAD_GPIO57] = { 0x2ac, 12, 3 },
-+ [PAD_GPIO58] = { 0x2ac, 15, 3 },
-+ [PAD_GPIO59] = { 0x2ac, 18, 3 },
-+ [PAD_GPIO60] = { 0x2ac, 21, 3 },
-+ [PAD_GPIO61] = { 0x2ac, 24, 3 },
-+ [PAD_GPIO62] = { 0x2ac, 27, 3 },
-+ [PAD_GPIO63] = { 0x2ac, 30, 3 },
-+
-+ [PAD_GPIO6] = { 0x2b0, 0, 3 },
-+ [PAD_GPIO7] = { 0x2b0, 2, 3 },
-+ [PAD_GPIO8] = { 0x2b0, 5, 3 },
-+ [PAD_GPIO9] = { 0x2b0, 8, 3 },
-+};
-+
-+struct jh7110_vin_group_sel {
-+ u16 offset;
-+ u8 shift;
-+ u8 group;
-+};
-+
-+static const struct jh7110_vin_group_sel
-+ jh7110_sys_vin_group_sel[ARRAY_SIZE(jh7110_sys_pins)] = {
-+ [PAD_GPIO6] = { 0x2b4, 21, 0 },
-+ [PAD_GPIO7] = { 0x2b4, 18, 0 },
-+ [PAD_GPIO8] = { 0x2b4, 15, 0 },
-+ [PAD_GPIO9] = { 0x2b0, 11, 0 },
-+ [PAD_GPIO10] = { 0x2b0, 20, 0 },
-+ [PAD_GPIO11] = { 0x2b0, 23, 0 },
-+ [PAD_GPIO12] = { 0x2b0, 26, 0 },
-+ [PAD_GPIO13] = { 0x2b0, 29, 0 },
-+ [PAD_GPIO14] = { 0x2b4, 0, 0 },
-+ [PAD_GPIO15] = { 0x2b4, 3, 0 },
-+ [PAD_GPIO16] = { 0x2b4, 6, 0 },
-+ [PAD_GPIO17] = { 0x2b4, 9, 0 },
-+ [PAD_GPIO18] = { 0x2b4, 12, 0 },
-+ [PAD_GPIO19] = { 0x2b0, 14, 0 },
-+ [PAD_GPIO20] = { 0x2b0, 17, 0 },
-+
-+ [PAD_GPIO21] = { 0x2b4, 21, 1 },
-+ [PAD_GPIO22] = { 0x2b4, 18, 1 },
-+ [PAD_GPIO23] = { 0x2b4, 15, 1 },
-+ [PAD_GPIO24] = { 0x2b0, 11, 1 },
-+ [PAD_GPIO25] = { 0x2b0, 20, 1 },
-+ [PAD_GPIO26] = { 0x2b0, 23, 1 },
-+ [PAD_GPIO27] = { 0x2b0, 26, 1 },
-+ [PAD_GPIO28] = { 0x2b0, 29, 1 },
-+ [PAD_GPIO29] = { 0x2b4, 0, 1 },
-+ [PAD_GPIO30] = { 0x2b4, 3, 1 },
-+ [PAD_GPIO31] = { 0x2b4, 6, 1 },
-+ [PAD_GPIO32] = { 0x2b4, 9, 1 },
-+ [PAD_GPIO33] = { 0x2b4, 12, 1 },
-+ [PAD_GPIO34] = { 0x2b0, 14, 1 },
-+ [PAD_GPIO35] = { 0x2b0, 17, 1 },
-+
-+ [PAD_GPIO36] = { 0x2b4, 21, 2 },
-+ [PAD_GPIO37] = { 0x2b4, 18, 2 },
-+ [PAD_GPIO38] = { 0x2b4, 15, 2 },
-+ [PAD_GPIO39] = { 0x2b0, 11, 2 },
-+ [PAD_GPIO40] = { 0x2b0, 20, 2 },
-+ [PAD_GPIO41] = { 0x2b0, 23, 2 },
-+ [PAD_GPIO42] = { 0x2b0, 26, 2 },
-+ [PAD_GPIO43] = { 0x2b0, 29, 2 },
-+ [PAD_GPIO44] = { 0x2b4, 0, 2 },
-+ [PAD_GPIO45] = { 0x2b4, 3, 2 },
-+ [PAD_GPIO46] = { 0x2b4, 6, 2 },
-+ [PAD_GPIO47] = { 0x2b4, 9, 2 },
-+ [PAD_GPIO48] = { 0x2b4, 12, 2 },
-+ [PAD_GPIO49] = { 0x2b0, 14, 2 },
-+ [PAD_GPIO50] = { 0x2b0, 17, 2 },
-+};
-+
-+static void jh7110_set_function(struct jh7110_pinctrl *sfp,
-+ unsigned int pin, u32 func)
-+{
-+ const struct jh7110_func_sel *fs = &jh7110_sys_func_sel[pin];
-+ unsigned long flags;
-+ void __iomem *reg;
-+ u32 mask;
-+
-+ if (!fs->offset)
-+ return;
-+
-+ if (func > fs->max)
-+ return;
-+
-+ reg = sfp->base + fs->offset;
-+ func = func << fs->shift;
-+ mask = 0x3U << fs->shift;
-+
-+ raw_spin_lock_irqsave(&sfp->lock, flags);
-+ func |= readl_relaxed(reg) & ~mask;
-+ writel_relaxed(func, reg);
-+ raw_spin_unlock_irqrestore(&sfp->lock, flags);
-+}
-+
-+static void jh7110_set_vin_group(struct jh7110_pinctrl *sfp,
-+ unsigned int pin)
-+{
-+ const struct jh7110_vin_group_sel *gs = &jh7110_sys_vin_group_sel[pin];
-+ unsigned long flags;
-+ void __iomem *reg;
-+ u32 mask;
-+ u32 grp;
-+
-+ if (!gs->offset)
-+ return;
-+
-+ reg = sfp->base + gs->offset;
-+ grp = gs->group << gs->shift;
-+ mask = 0x3U << gs->shift;
-+
-+ raw_spin_lock_irqsave(&sfp->lock, flags);
-+ grp |= readl_relaxed(reg) & ~mask;
-+ writel_relaxed(grp, reg);
-+ raw_spin_unlock_irqrestore(&sfp->lock, flags);
-+}
-+
-+static int jh7110_sys_set_one_pin_mux(struct jh7110_pinctrl *sfp,
-+ unsigned int pin,
-+ unsigned int din, u32 dout,
-+ u32 doen, u32 func)
-+{
-+ if (pin < sfp->gc.ngpio && func == 0)
-+ jh7110_set_gpiomux(sfp, pin, din, dout, doen);
-+
-+ jh7110_set_function(sfp, pin, func);
-+
-+ if (pin < sfp->gc.ngpio && func == 2)
-+ jh7110_set_vin_group(sfp, pin);
-+
-+ return 0;
-+}
-+
-+static int jh7110_sys_get_padcfg_base(struct jh7110_pinctrl *sfp,
-+ unsigned int pin)
-+{
-+ if (pin < PAD_GMAC1_MDC)
-+ return JH7110_SYS_GPO_PDA_0_74_CFG;
-+ else if (pin > PAD_GMAC1_TXC && pin <= PAD_QSPI_DATA3)
-+ return JH7110_SYS_GPO_PDA_89_94_CFG;
-+ else
-+ return -1;
-+}
-+
-+static void jh7110_sys_irq_handler(struct irq_desc *desc)
-+{
-+ struct jh7110_pinctrl *sfp = jh7110_from_irq_desc(desc);
-+ struct irq_chip *chip = irq_desc_get_chip(desc);
-+ unsigned long mis;
-+ unsigned int pin;
-+
-+ chained_irq_enter(chip, desc);
-+
-+ mis = readl_relaxed(sfp->base + JH7110_SYS_GPIOMIS0);
-+ for_each_set_bit(pin, &mis, 32)
-+ generic_handle_domain_irq(sfp->gc.irq.domain, pin);
-+
-+ mis = readl_relaxed(sfp->base + JH7110_SYS_GPIOMIS1);
-+ for_each_set_bit(pin, &mis, 32)
-+ generic_handle_domain_irq(sfp->gc.irq.domain, pin + 32);
-+
-+ chained_irq_exit(chip, desc);
-+}
-+
-+static int jh7110_sys_init_hw(struct gpio_chip *gc)
-+{
-+ struct jh7110_pinctrl *sfp = container_of(gc,
-+ struct jh7110_pinctrl, gc);
-+
-+ /* mask all GPIO interrupts */
-+ writel(0U, sfp->base + JH7110_SYS_GPIOIE0);
-+ writel(0U, sfp->base + JH7110_SYS_GPIOIE1);
-+ /* clear edge interrupt flags */
-+ writel(~0U, sfp->base + JH7110_SYS_GPIOIC0);
-+ writel(~0U, sfp->base + JH7110_SYS_GPIOIC1);
-+ /* enable GPIO interrupts */
-+ writel(1U, sfp->base + JH7110_SYS_GPIOEN);
-+ return 0;
-+}
-+
-+static const struct jh7110_gpio_irq_reg jh7110_sys_irq_reg = {
-+ .is_reg_base = JH7110_SYS_GPIOIS0,
-+ .ic_reg_base = JH7110_SYS_GPIOIC0,
-+ .ibe_reg_base = JH7110_SYS_GPIOIBE0,
-+ .iev_reg_base = JH7110_SYS_GPIOIEV0,
-+ .ie_reg_base = JH7110_SYS_GPIOIE0,
-+ .ris_reg_base = JH7110_SYS_GPIORIS0,
-+ .mis_reg_base = JH7110_SYS_GPIOMIS0,
-+};
-+
-+static const struct jh7110_pinctrl_soc_info jh7110_sys_pinctrl_info = {
-+ .pins = jh7110_sys_pins,
-+ .npins = ARRAY_SIZE(jh7110_sys_pins),
-+ .ngpios = JH7110_SYS_NGPIO,
-+ .gc_base = JH7110_SYS_GC_BASE,
-+ .dout_reg_base = JH7110_SYS_DOUT,
-+ .dout_mask = GENMASK(6, 0),
-+ .doen_reg_base = JH7110_SYS_DOEN,
-+ .doen_mask = GENMASK(5, 0),
-+ .gpi_reg_base = JH7110_SYS_GPI,
-+ .gpi_mask = GENMASK(6, 0),
-+ .gpioin_reg_base = JH7110_SYS_GPIOIN,
-+ .irq_reg = &jh7110_sys_irq_reg,
-+ .jh7110_set_one_pin_mux = jh7110_sys_set_one_pin_mux,
-+ .jh7110_get_padcfg_base = jh7110_sys_get_padcfg_base,
-+ .jh7110_gpio_irq_handler = jh7110_sys_irq_handler,
-+ .jh7110_gpio_init_hw = jh7110_sys_init_hw,
-+};
-+
-+static const struct of_device_id jh7110_sys_pinctrl_of_match[] = {
-+ {
-+ .compatible = "starfive,jh7110-sys-pinctrl",
-+ .data = &jh7110_sys_pinctrl_info,
-+ },
-+ { /* sentinel */ }
-+};
-+MODULE_DEVICE_TABLE(of, jh7110_sys_pinctrl_of_match);
-+
-+static struct platform_driver jh7110_sys_pinctrl_driver = {
-+ .probe = jh7110_pinctrl_probe,
-+ .driver = {
-+ .name = "starfive-jh7110-sys-pinctrl",
-+ .of_match_table = jh7110_sys_pinctrl_of_match,
-+ },
-+};
-+module_platform_driver(jh7110_sys_pinctrl_driver);
-+
-+MODULE_DESCRIPTION("Pinctrl driver for the StarFive JH7110 SoC sys controller");
-+MODULE_AUTHOR("Emil Renner Berthing <kernel@esmil.dk>");
-+MODULE_AUTHOR("Jianlong Huang <jianlong.huang@starfivetech.com>");
-+MODULE_LICENSE("GPL");
---- /dev/null
-+++ b/drivers/pinctrl/starfive/pinctrl-starfive-jh7110.c
-@@ -0,0 +1,982 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Pinctrl / GPIO driver for StarFive JH7110 SoC
-+ *
-+ * Copyright (C) 2022 Emil Renner Berthing <kernel@esmil.dk>
-+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
-+ */
-+
-+#include <linux/bits.h>
-+#include <linux/clk.h>
-+#include <linux/gpio/driver.h>
-+#include <linux/io.h>
-+#include <linux/mod_devicetable.h>
-+#include <linux/module.h>
-+#include <linux/mutex.h>
-+#include <linux/of.h>
-+#include <linux/of_device.h>
-+#include <linux/platform_device.h>
-+#include <linux/reset.h>
-+#include <linux/seq_file.h>
-+#include <linux/spinlock.h>
-+
-+#include <linux/pinctrl/consumer.h>
-+#include <linux/pinctrl/pinconf.h>
-+#include <linux/pinctrl/pinctrl.h>
-+#include <linux/pinctrl/pinmux.h>
-+
-+#include <dt-bindings/pinctrl/starfive,jh7110-pinctrl.h>
-+
-+#include "../core.h"
-+#include "../pinctrl-utils.h"
-+#include "../pinmux.h"
-+#include "../pinconf.h"
-+#include "pinctrl-starfive-jh7110.h"
-+
-+/* pad control bits */
-+#define JH7110_PADCFG_POS BIT(7)
-+#define JH7110_PADCFG_SMT BIT(6)
-+#define JH7110_PADCFG_SLEW BIT(5)
-+#define JH7110_PADCFG_PD BIT(4)
-+#define JH7110_PADCFG_PU BIT(3)
-+#define JH7110_PADCFG_BIAS (JH7110_PADCFG_PD | JH7110_PADCFG_PU)
-+#define JH7110_PADCFG_DS_MASK GENMASK(2, 1)
-+#define JH7110_PADCFG_DS_2MA (0U << 1)
-+#define JH7110_PADCFG_DS_4MA BIT(1)
-+#define JH7110_PADCFG_DS_8MA (2U << 1)
-+#define JH7110_PADCFG_DS_12MA (3U << 1)
-+#define JH7110_PADCFG_IE BIT(0)
-+
-+/*
-+ * The packed pinmux values from the device tree look like this:
-+ *
-+ * | 31 - 24 | 23 - 16 | 15 - 10 | 9 - 8 | 7 - 0 |
-+ * | din | dout | doen | function | pin |
-+ */
-+static unsigned int jh7110_pinmux_din(u32 v)
-+{
-+ return (v & GENMASK(31, 24)) >> 24;
-+}
-+
-+static u32 jh7110_pinmux_dout(u32 v)
-+{
-+ return (v & GENMASK(23, 16)) >> 16;
-+}
-+
-+static u32 jh7110_pinmux_doen(u32 v)
-+{
-+ return (v & GENMASK(15, 10)) >> 10;
-+}
-+
-+static u32 jh7110_pinmux_function(u32 v)
-+{
-+ return (v & GENMASK(9, 8)) >> 8;
-+}
-+
-+static unsigned int jh7110_pinmux_pin(u32 v)
-+{
-+ return v & GENMASK(7, 0);
-+}
-+
-+static struct jh7110_pinctrl *jh7110_from_irq_data(struct irq_data *d)
-+{
-+ struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
-+
-+ return container_of(gc, struct jh7110_pinctrl, gc);
-+}
-+
-+struct jh7110_pinctrl *jh7110_from_irq_desc(struct irq_desc *desc)
-+{
-+ struct gpio_chip *gc = irq_desc_get_handler_data(desc);
-+
-+ return container_of(gc, struct jh7110_pinctrl, gc);
-+}
-+EXPORT_SYMBOL_GPL(jh7110_from_irq_desc);
-+
-+#ifdef CONFIG_DEBUG_FS
-+static void jh7110_pin_dbg_show(struct pinctrl_dev *pctldev,
-+ struct seq_file *s, unsigned int pin)
-+{
-+ struct jh7110_pinctrl *sfp = pinctrl_dev_get_drvdata(pctldev);
-+ const struct jh7110_pinctrl_soc_info *info = sfp->info;
-+
-+ seq_printf(s, "%s", dev_name(pctldev->dev));
-+
-+ if (pin < sfp->gc.ngpio) {
-+ unsigned int offset = 4 * (pin / 4);
-+ unsigned int shift = 8 * (pin % 4);
-+ u32 dout = readl_relaxed(sfp->base + info->dout_reg_base + offset);
-+ u32 doen = readl_relaxed(sfp->base + info->doen_reg_base + offset);
-+ u32 gpi = readl_relaxed(sfp->base + info->gpi_reg_base + offset);
-+
-+ dout = (dout >> shift) & info->dout_mask;
-+ doen = (doen >> shift) & info->doen_mask;
-+ gpi = ((gpi >> shift) - 2) & info->gpi_mask;
-+
-+ seq_printf(s, " dout=%u doen=%u din=%u", dout, doen, gpi);
-+ }
-+}
-+#else
-+#define jh7110_pin_dbg_show NULL
-+#endif
-+
-+static int jh7110_dt_node_to_map(struct pinctrl_dev *pctldev,
-+ struct device_node *np,
-+ struct pinctrl_map **maps,
-+ unsigned int *num_maps)
-+{
-+ struct jh7110_pinctrl *sfp = pinctrl_dev_get_drvdata(pctldev);
-+ struct device *dev = sfp->gc.parent;
-+ struct device_node *child;
-+ struct pinctrl_map *map;
-+ const char **pgnames;
-+ const char *grpname;
-+ int ngroups;
-+ int nmaps;
-+ int ret;
-+
-+ ngroups = 0;
-+ for_each_child_of_node(np, child)
-+ ngroups += 1;
-+ nmaps = 2 * ngroups;
-+
-+ pgnames = devm_kcalloc(dev, ngroups, sizeof(*pgnames), GFP_KERNEL);
-+ if (!pgnames)
-+ return -ENOMEM;
-+
-+ map = kcalloc(nmaps, sizeof(*map), GFP_KERNEL);
-+ if (!map)
-+ return -ENOMEM;
-+
-+ nmaps = 0;
-+ ngroups = 0;
-+ mutex_lock(&sfp->mutex);
-+ for_each_child_of_node(np, child) {
-+ int npins = of_property_count_u32_elems(child, "pinmux");
-+ int *pins;
-+ u32 *pinmux;
-+ int i;
-+
-+ if (npins < 1) {
-+ dev_err(dev,
-+ "invalid pinctrl group %pOFn.%pOFn: pinmux not set\n",
-+ np, child);
-+ ret = -EINVAL;
-+ goto put_child;
-+ }
-+
-+ grpname = devm_kasprintf(dev, GFP_KERNEL, "%pOFn.%pOFn", np, child);
-+ if (!grpname) {
-+ ret = -ENOMEM;
-+ goto put_child;
-+ }
-+
-+ pgnames[ngroups++] = grpname;
-+
-+ pins = devm_kcalloc(dev, npins, sizeof(*pins), GFP_KERNEL);
-+ if (!pins) {
-+ ret = -ENOMEM;
-+ goto put_child;
-+ }
-+
-+ pinmux = devm_kcalloc(dev, npins, sizeof(*pinmux), GFP_KERNEL);
-+ if (!pinmux) {
-+ ret = -ENOMEM;
-+ goto put_child;
-+ }
-+
-+ ret = of_property_read_u32_array(child, "pinmux", pinmux, npins);
-+ if (ret)
-+ goto put_child;
-+
-+ for (i = 0; i < npins; i++)
-+ pins[i] = jh7110_pinmux_pin(pinmux[i]);
-+
-+ map[nmaps].type = PIN_MAP_TYPE_MUX_GROUP;
-+ map[nmaps].data.mux.function = np->name;
-+ map[nmaps].data.mux.group = grpname;
-+ nmaps += 1;
-+
-+ ret = pinctrl_generic_add_group(pctldev, grpname,
-+ pins, npins, pinmux);
-+ if (ret < 0) {
-+ dev_err(dev, "error adding group %s: %d\n", grpname, ret);
-+ goto put_child;
-+ }
-+
-+ ret = pinconf_generic_parse_dt_config(child, pctldev,
-+ &map[nmaps].data.configs.configs,
-+ &map[nmaps].data.configs.num_configs);
-+ if (ret) {
-+ dev_err(dev, "error parsing pin config of group %s: %d\n",
-+ grpname, ret);
-+ goto put_child;
-+ }
-+
-+ /* don't create a map if there are no pinconf settings */
-+ if (map[nmaps].data.configs.num_configs == 0)
-+ continue;
-+
-+ map[nmaps].type = PIN_MAP_TYPE_CONFIGS_GROUP;
-+ map[nmaps].data.configs.group_or_pin = grpname;
-+ nmaps += 1;
-+ }
-+
-+ ret = pinmux_generic_add_function(pctldev, np->name,
-+ pgnames, ngroups, NULL);
-+ if (ret < 0) {
-+ dev_err(dev, "error adding function %s: %d\n", np->name, ret);
-+ goto free_map;
-+ }
-+ mutex_unlock(&sfp->mutex);
-+
-+ *maps = map;
-+ *num_maps = nmaps;
-+ return 0;
-+
-+put_child:
-+ of_node_put(child);
-+free_map:
-+ pinctrl_utils_free_map(pctldev, map, nmaps);
-+ mutex_unlock(&sfp->mutex);
-+ return ret;
-+}
-+
-+static const struct pinctrl_ops jh7110_pinctrl_ops = {
-+ .get_groups_count = pinctrl_generic_get_group_count,
-+ .get_group_name = pinctrl_generic_get_group_name,
-+ .get_group_pins = pinctrl_generic_get_group_pins,
-+ .pin_dbg_show = jh7110_pin_dbg_show,
-+ .dt_node_to_map = jh7110_dt_node_to_map,
-+ .dt_free_map = pinctrl_utils_free_map,
-+};
-+
-+void jh7110_set_gpiomux(struct jh7110_pinctrl *sfp, unsigned int pin,
-+ unsigned int din, u32 dout, u32 doen)
-+{
-+ const struct jh7110_pinctrl_soc_info *info = sfp->info;
-+
-+ unsigned int offset = 4 * (pin / 4);
-+ unsigned int shift = 8 * (pin % 4);
-+ u32 dout_mask = info->dout_mask << shift;
-+ u32 done_mask = info->doen_mask << shift;
-+ u32 ival, imask;
-+ void __iomem *reg_dout;
-+ void __iomem *reg_doen;
-+ void __iomem *reg_din;
-+ unsigned long flags;
-+
-+ reg_dout = sfp->base + info->dout_reg_base + offset;
-+ reg_doen = sfp->base + info->doen_reg_base + offset;
-+ dout <<= shift;
-+ doen <<= shift;
-+ if (din != GPI_NONE) {
-+ unsigned int ioffset = 4 * (din / 4);
-+ unsigned int ishift = 8 * (din % 4);
-+
-+ reg_din = sfp->base + info->gpi_reg_base + ioffset;
-+ ival = (pin + 2) << ishift;
-+ imask = info->gpi_mask << ishift;
-+ } else {
-+ reg_din = NULL;
-+ }
-+
-+ raw_spin_lock_irqsave(&sfp->lock, flags);
-+ dout |= readl_relaxed(reg_dout) & ~dout_mask;
-+ writel_relaxed(dout, reg_dout);
-+ doen |= readl_relaxed(reg_doen) & ~done_mask;
-+ writel_relaxed(doen, reg_doen);
-+ if (reg_din) {
-+ ival |= readl_relaxed(reg_din) & ~imask;
-+ writel_relaxed(ival, reg_din);
-+ }
-+ raw_spin_unlock_irqrestore(&sfp->lock, flags);
-+}
-+EXPORT_SYMBOL_GPL(jh7110_set_gpiomux);
-+
-+static int jh7110_set_mux(struct pinctrl_dev *pctldev,
-+ unsigned int fsel, unsigned int gsel)
-+{
-+ struct jh7110_pinctrl *sfp = pinctrl_dev_get_drvdata(pctldev);
-+ const struct jh7110_pinctrl_soc_info *info = sfp->info;
-+ const struct group_desc *group;
-+ const u32 *pinmux;
-+ unsigned int i;
-+
-+ group = pinctrl_generic_get_group(pctldev, gsel);
-+ if (!group)
-+ return -EINVAL;
-+
-+ pinmux = group->data;
-+ for (i = 0; i < group->num_pins; i++) {
-+ u32 v = pinmux[i];
-+
-+ if (info->jh7110_set_one_pin_mux)
-+ info->jh7110_set_one_pin_mux(sfp,
-+ jh7110_pinmux_pin(v),
-+ jh7110_pinmux_din(v),
-+ jh7110_pinmux_dout(v),
-+ jh7110_pinmux_doen(v),
-+ jh7110_pinmux_function(v));
-+ }
-+
-+ return 0;
-+}
-+
-+static const struct pinmux_ops jh7110_pinmux_ops = {
-+ .get_functions_count = pinmux_generic_get_function_count,
-+ .get_function_name = pinmux_generic_get_function_name,
-+ .get_function_groups = pinmux_generic_get_function_groups,
-+ .set_mux = jh7110_set_mux,
-+ .strict = true,
-+};
-+
-+static const u8 jh7110_drive_strength_mA[4] = { 2, 4, 8, 12 };
-+
-+static u32 jh7110_padcfg_ds_to_mA(u32 padcfg)
-+{
-+ return jh7110_drive_strength_mA[(padcfg >> 1) & 3U];
-+}
-+
-+static u32 jh7110_padcfg_ds_from_mA(u32 v)
-+{
-+ int i;
-+
-+ for (i = 0; i < 3; i++) {
-+ if (v <= jh7110_drive_strength_mA[i])
-+ break;
-+ }
-+ return i << 1;
-+}
-+
-+static void jh7110_padcfg_rmw(struct jh7110_pinctrl *sfp,
-+ unsigned int pin, u32 mask, u32 value)
-+{
-+ const struct jh7110_pinctrl_soc_info *info = sfp->info;
-+ void __iomem *reg;
-+ unsigned long flags;
-+ int padcfg_base;
-+
-+ if (!info->jh7110_get_padcfg_base)
-+ return;
-+
-+ padcfg_base = info->jh7110_get_padcfg_base(sfp, pin);
-+ if (padcfg_base < 0)
-+ return;
-+
-+ reg = sfp->base + padcfg_base + 4 * pin;
-+ value &= mask;
-+
-+ raw_spin_lock_irqsave(&sfp->lock, flags);
-+ value |= readl_relaxed(reg) & ~mask;
-+ writel_relaxed(value, reg);
-+ raw_spin_unlock_irqrestore(&sfp->lock, flags);
-+}
-+
-+static int jh7110_pinconf_get(struct pinctrl_dev *pctldev,
-+ unsigned int pin, unsigned long *config)
-+{
-+ struct jh7110_pinctrl *sfp = pinctrl_dev_get_drvdata(pctldev);
-+ const struct jh7110_pinctrl_soc_info *info = sfp->info;
-+ int param = pinconf_to_config_param(*config);
-+ u32 padcfg, arg;
-+ bool enabled;
-+ int padcfg_base;
-+
-+ if (!info->jh7110_get_padcfg_base)
-+ return 0;
-+
-+ padcfg_base = info->jh7110_get_padcfg_base(sfp, pin);
-+ if (padcfg_base < 0)
-+ return 0;
-+
-+ padcfg = readl_relaxed(sfp->base + padcfg_base + 4 * pin);
-+ switch (param) {
-+ case PIN_CONFIG_BIAS_DISABLE:
-+ enabled = !(padcfg & JH7110_PADCFG_BIAS);
-+ arg = 0;
-+ break;
-+ case PIN_CONFIG_BIAS_PULL_DOWN:
-+ enabled = padcfg & JH7110_PADCFG_PD;
-+ arg = 1;
-+ break;
-+ case PIN_CONFIG_BIAS_PULL_UP:
-+ enabled = padcfg & JH7110_PADCFG_PU;
-+ arg = 1;
-+ break;
-+ case PIN_CONFIG_DRIVE_STRENGTH:
-+ enabled = true;
-+ arg = jh7110_padcfg_ds_to_mA(padcfg);
-+ break;
-+ case PIN_CONFIG_INPUT_ENABLE:
-+ enabled = padcfg & JH7110_PADCFG_IE;
-+ arg = enabled;
-+ break;
-+ case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
-+ enabled = padcfg & JH7110_PADCFG_SMT;
-+ arg = enabled;
-+ break;
-+ case PIN_CONFIG_SLEW_RATE:
-+ enabled = true;
-+ arg = !!(padcfg & JH7110_PADCFG_SLEW);
-+ break;
-+ default:
-+ return -ENOTSUPP;
-+ }
-+
-+ *config = pinconf_to_config_packed(param, arg);
-+ return enabled ? 0 : -EINVAL;
-+}
-+
-+static int jh7110_pinconf_group_get(struct pinctrl_dev *pctldev,
-+ unsigned int gsel,
-+ unsigned long *config)
-+{
-+ const struct group_desc *group;
-+
-+ group = pinctrl_generic_get_group(pctldev, gsel);
-+ if (!group)
-+ return -EINVAL;
-+
-+ return jh7110_pinconf_get(pctldev, group->pins[0], config);
-+}
-+
-+static int jh7110_pinconf_group_set(struct pinctrl_dev *pctldev,
-+ unsigned int gsel,
-+ unsigned long *configs,
-+ unsigned int num_configs)
-+{
-+ struct jh7110_pinctrl *sfp = pinctrl_dev_get_drvdata(pctldev);
-+ const struct group_desc *group;
-+ u16 mask, value;
-+ int i;
-+
-+ group = pinctrl_generic_get_group(pctldev, gsel);
-+ if (!group)
-+ return -EINVAL;
-+
-+ mask = 0;
-+ value = 0;
-+ for (i = 0; i < num_configs; i++) {
-+ int param = pinconf_to_config_param(configs[i]);
-+ u32 arg = pinconf_to_config_argument(configs[i]);
-+
-+ switch (param) {
-+ case PIN_CONFIG_BIAS_DISABLE:
-+ mask |= JH7110_PADCFG_BIAS;
-+ value &= ~JH7110_PADCFG_BIAS;
-+ break;
-+ case PIN_CONFIG_BIAS_PULL_DOWN:
-+ if (arg == 0)
-+ return -ENOTSUPP;
-+ mask |= JH7110_PADCFG_BIAS;
-+ value = (value & ~JH7110_PADCFG_BIAS) | JH7110_PADCFG_PD;
-+ break;
-+ case PIN_CONFIG_BIAS_PULL_UP:
-+ if (arg == 0)
-+ return -ENOTSUPP;
-+ mask |= JH7110_PADCFG_BIAS;
-+ value = (value & ~JH7110_PADCFG_BIAS) | JH7110_PADCFG_PU;
-+ break;
-+ case PIN_CONFIG_DRIVE_STRENGTH:
-+ mask |= JH7110_PADCFG_DS_MASK;
-+ value = (value & ~JH7110_PADCFG_DS_MASK) |
-+ jh7110_padcfg_ds_from_mA(arg);
-+ break;
-+ case PIN_CONFIG_INPUT_ENABLE:
-+ mask |= JH7110_PADCFG_IE;
-+ if (arg)
-+ value |= JH7110_PADCFG_IE;
-+ else
-+ value &= ~JH7110_PADCFG_IE;
-+ break;
-+ case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
-+ mask |= JH7110_PADCFG_SMT;
-+ if (arg)
-+ value |= JH7110_PADCFG_SMT;
-+ else
-+ value &= ~JH7110_PADCFG_SMT;
-+ break;
-+ case PIN_CONFIG_SLEW_RATE:
-+ mask |= JH7110_PADCFG_SLEW;
-+ if (arg)
-+ value |= JH7110_PADCFG_SLEW;
-+ else
-+ value &= ~JH7110_PADCFG_SLEW;
-+ break;
-+ default:
-+ return -ENOTSUPP;
-+ }
-+ }
-+
-+ for (i = 0; i < group->num_pins; i++)
-+ jh7110_padcfg_rmw(sfp, group->pins[i], mask, value);
-+
-+ return 0;
-+}
-+
-+#ifdef CONFIG_DEBUG_FS
-+static void jh7110_pinconf_dbg_show(struct pinctrl_dev *pctldev,
-+ struct seq_file *s, unsigned int pin)
-+{
-+ struct jh7110_pinctrl *sfp = pinctrl_dev_get_drvdata(pctldev);
-+ const struct jh7110_pinctrl_soc_info *info = sfp->info;
-+ u32 value;
-+ int padcfg_base;
-+
-+ if (!info->jh7110_get_padcfg_base)
-+ return;
-+
-+ padcfg_base = info->jh7110_get_padcfg_base(sfp, pin);
-+ if (padcfg_base < 0)
-+ return;
-+
-+ value = readl_relaxed(sfp->base + padcfg_base + 4 * pin);
-+ seq_printf(s, " (0x%02x)", value);
-+}
-+#else
-+#define jh7110_pinconf_dbg_show NULL
-+#endif
-+
-+static const struct pinconf_ops jh7110_pinconf_ops = {
-+ .pin_config_get = jh7110_pinconf_get,
-+ .pin_config_group_get = jh7110_pinconf_group_get,
-+ .pin_config_group_set = jh7110_pinconf_group_set,
-+ .pin_config_dbg_show = jh7110_pinconf_dbg_show,
-+ .is_generic = true,
-+};
-+
-+static int jh7110_gpio_request(struct gpio_chip *gc, unsigned int gpio)
-+{
-+ return pinctrl_gpio_request(gc->base + gpio);
-+}
-+
-+static void jh7110_gpio_free(struct gpio_chip *gc, unsigned int gpio)
-+{
-+ pinctrl_gpio_free(gc->base + gpio);
-+}
-+
-+static int jh7110_gpio_get_direction(struct gpio_chip *gc,
-+ unsigned int gpio)
-+{
-+ struct jh7110_pinctrl *sfp = container_of(gc,
-+ struct jh7110_pinctrl, gc);
-+ const struct jh7110_pinctrl_soc_info *info = sfp->info;
-+ unsigned int offset = 4 * (gpio / 4);
-+ unsigned int shift = 8 * (gpio % 4);
-+ u32 doen = readl_relaxed(sfp->base + info->doen_reg_base + offset);
-+
-+ doen = (doen >> shift) & info->doen_mask;
-+
-+ return doen == GPOEN_ENABLE ?
-+ GPIO_LINE_DIRECTION_OUT : GPIO_LINE_DIRECTION_IN;
-+}
-+
-+static int jh7110_gpio_direction_input(struct gpio_chip *gc,
-+ unsigned int gpio)
-+{
-+ struct jh7110_pinctrl *sfp = container_of(gc,
-+ struct jh7110_pinctrl, gc);
-+ const struct jh7110_pinctrl_soc_info *info = sfp->info;
-+
-+ /* enable input and schmitt trigger */
-+ jh7110_padcfg_rmw(sfp, gpio,
-+ JH7110_PADCFG_IE | JH7110_PADCFG_SMT,
-+ JH7110_PADCFG_IE | JH7110_PADCFG_SMT);
-+
-+ if (info->jh7110_set_one_pin_mux)
-+ info->jh7110_set_one_pin_mux(sfp, gpio,
-+ GPI_NONE, GPOUT_LOW, GPOEN_DISABLE, 0);
-+
-+ return 0;
-+}
-+
-+static int jh7110_gpio_direction_output(struct gpio_chip *gc,
-+ unsigned int gpio, int value)
-+{
-+ struct jh7110_pinctrl *sfp = container_of(gc,
-+ struct jh7110_pinctrl, gc);
-+ const struct jh7110_pinctrl_soc_info *info = sfp->info;
-+
-+ if (info->jh7110_set_one_pin_mux)
-+ info->jh7110_set_one_pin_mux(sfp, gpio,
-+ GPI_NONE, value ? GPOUT_HIGH : GPOUT_LOW,
-+ GPOEN_ENABLE, 0);
-+
-+ /* disable input, schmitt trigger and bias */
-+ jh7110_padcfg_rmw(sfp, gpio,
-+ JH7110_PADCFG_IE | JH7110_PADCFG_SMT |
-+ JH7110_PADCFG_BIAS, 0);
-+ return 0;
-+}
-+
-+static int jh7110_gpio_get(struct gpio_chip *gc, unsigned int gpio)
-+{
-+ struct jh7110_pinctrl *sfp = container_of(gc,
-+ struct jh7110_pinctrl, gc);
-+ const struct jh7110_pinctrl_soc_info *info = sfp->info;
-+ void __iomem *reg = sfp->base + info->gpioin_reg_base
-+ + 4 * (gpio / 32);
-+
-+ return !!(readl_relaxed(reg) & BIT(gpio % 32));
-+}
-+
-+static void jh7110_gpio_set(struct gpio_chip *gc,
-+ unsigned int gpio, int value)
-+{
-+ struct jh7110_pinctrl *sfp = container_of(gc,
-+ struct jh7110_pinctrl, gc);
-+ const struct jh7110_pinctrl_soc_info *info = sfp->info;
-+ unsigned int offset = 4 * (gpio / 4);
-+ unsigned int shift = 8 * (gpio % 4);
-+ void __iomem *reg_dout = sfp->base + info->dout_reg_base + offset;
-+ u32 dout = (value ? GPOUT_HIGH : GPOUT_LOW) << shift;
-+ u32 mask = info->dout_mask << shift;
-+ unsigned long flags;
-+
-+ raw_spin_lock_irqsave(&sfp->lock, flags);
-+ dout |= readl_relaxed(reg_dout) & ~mask;
-+ writel_relaxed(dout, reg_dout);
-+ raw_spin_unlock_irqrestore(&sfp->lock, flags);
-+}
-+
-+static int jh7110_gpio_set_config(struct gpio_chip *gc,
-+ unsigned int gpio, unsigned long config)
-+{
-+ struct jh7110_pinctrl *sfp = container_of(gc,
-+ struct jh7110_pinctrl, gc);
-+ u32 arg = pinconf_to_config_argument(config);
-+ u32 value;
-+ u32 mask;
-+
-+ switch (pinconf_to_config_param(config)) {
-+ case PIN_CONFIG_BIAS_DISABLE:
-+ mask = JH7110_PADCFG_BIAS;
-+ value = 0;
-+ break;
-+ case PIN_CONFIG_BIAS_PULL_DOWN:
-+ if (arg == 0)
-+ return -ENOTSUPP;
-+ mask = JH7110_PADCFG_BIAS;
-+ value = JH7110_PADCFG_PD;
-+ break;
-+ case PIN_CONFIG_BIAS_PULL_UP:
-+ if (arg == 0)
-+ return -ENOTSUPP;
-+ mask = JH7110_PADCFG_BIAS;
-+ value = JH7110_PADCFG_PU;
-+ break;
-+ case PIN_CONFIG_DRIVE_PUSH_PULL:
-+ return 0;
-+ case PIN_CONFIG_INPUT_ENABLE:
-+ mask = JH7110_PADCFG_IE;
-+ value = arg ? JH7110_PADCFG_IE : 0;
-+ break;
-+ case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
-+ mask = JH7110_PADCFG_SMT;
-+ value = arg ? JH7110_PADCFG_SMT : 0;
-+ break;
-+ default:
-+ return -ENOTSUPP;
-+ }
-+
-+ jh7110_padcfg_rmw(sfp, gpio, mask, value);
-+ return 0;
-+}
-+
-+static int jh7110_gpio_add_pin_ranges(struct gpio_chip *gc)
-+{
-+ struct jh7110_pinctrl *sfp = container_of(gc,
-+ struct jh7110_pinctrl, gc);
-+
-+ sfp->gpios.name = sfp->gc.label;
-+ sfp->gpios.base = sfp->gc.base;
-+ sfp->gpios.pin_base = 0;
-+ sfp->gpios.npins = sfp->gc.ngpio;
-+ sfp->gpios.gc = &sfp->gc;
-+ pinctrl_add_gpio_range(sfp->pctl, &sfp->gpios);
-+ return 0;
-+}
-+
-+static void jh7110_irq_ack(struct irq_data *d)
-+{
-+ struct jh7110_pinctrl *sfp = jh7110_from_irq_data(d);
-+ const struct jh7110_gpio_irq_reg *irq_reg = sfp->info->irq_reg;
-+ irq_hw_number_t gpio = irqd_to_hwirq(d);
-+ void __iomem *ic = sfp->base + irq_reg->ic_reg_base
-+ + 4 * (gpio / 32);
-+ u32 mask = BIT(gpio % 32);
-+ unsigned long flags;
-+ u32 value;
-+
-+ raw_spin_lock_irqsave(&sfp->lock, flags);
-+ value = readl_relaxed(ic) & ~mask;
-+ writel_relaxed(value, ic);
-+ writel_relaxed(value | mask, ic);
-+ raw_spin_unlock_irqrestore(&sfp->lock, flags);
-+}
-+
-+static void jh7110_irq_mask(struct irq_data *d)
-+{
-+ struct jh7110_pinctrl *sfp = jh7110_from_irq_data(d);
-+ const struct jh7110_gpio_irq_reg *irq_reg = sfp->info->irq_reg;
-+ irq_hw_number_t gpio = irqd_to_hwirq(d);
-+ void __iomem *ie = sfp->base + irq_reg->ie_reg_base
-+ + 4 * (gpio / 32);
-+ u32 mask = BIT(gpio % 32);
-+ unsigned long flags;
-+ u32 value;
-+
-+ raw_spin_lock_irqsave(&sfp->lock, flags);
-+ value = readl_relaxed(ie) & ~mask;
-+ writel_relaxed(value, ie);
-+ raw_spin_unlock_irqrestore(&sfp->lock, flags);
-+
-+ gpiochip_disable_irq(&sfp->gc, d->hwirq);
-+}
-+
-+static void jh7110_irq_mask_ack(struct irq_data *d)
-+{
-+ struct jh7110_pinctrl *sfp = jh7110_from_irq_data(d);
-+ const struct jh7110_gpio_irq_reg *irq_reg = sfp->info->irq_reg;
-+ irq_hw_number_t gpio = irqd_to_hwirq(d);
-+ void __iomem *ie = sfp->base + irq_reg->ie_reg_base
-+ + 4 * (gpio / 32);
-+ void __iomem *ic = sfp->base + irq_reg->ic_reg_base
-+ + 4 * (gpio / 32);
-+ u32 mask = BIT(gpio % 32);
-+ unsigned long flags;
-+ u32 value;
-+
-+ raw_spin_lock_irqsave(&sfp->lock, flags);
-+ value = readl_relaxed(ie) & ~mask;
-+ writel_relaxed(value, ie);
-+
-+ value = readl_relaxed(ic) & ~mask;
-+ writel_relaxed(value, ic);
-+ writel_relaxed(value | mask, ic);
-+ raw_spin_unlock_irqrestore(&sfp->lock, flags);
-+}
-+
-+static void jh7110_irq_unmask(struct irq_data *d)
-+{
-+ struct jh7110_pinctrl *sfp = jh7110_from_irq_data(d);
-+ const struct jh7110_gpio_irq_reg *irq_reg = sfp->info->irq_reg;
-+ irq_hw_number_t gpio = irqd_to_hwirq(d);
-+ void __iomem *ie = sfp->base + irq_reg->ie_reg_base
-+ + 4 * (gpio / 32);
-+ u32 mask = BIT(gpio % 32);
-+ unsigned long flags;
-+ u32 value;
-+
-+ gpiochip_enable_irq(&sfp->gc, d->hwirq);
-+
-+ raw_spin_lock_irqsave(&sfp->lock, flags);
-+ value = readl_relaxed(ie) | mask;
-+ writel_relaxed(value, ie);
-+ raw_spin_unlock_irqrestore(&sfp->lock, flags);
-+}
-+
-+static int jh7110_irq_set_type(struct irq_data *d, unsigned int trigger)
-+{
-+ struct jh7110_pinctrl *sfp = jh7110_from_irq_data(d);
-+ const struct jh7110_gpio_irq_reg *irq_reg = sfp->info->irq_reg;
-+ irq_hw_number_t gpio = irqd_to_hwirq(d);
-+ void __iomem *base = sfp->base + 4 * (gpio / 32);
-+ u32 mask = BIT(gpio % 32);
-+ u32 irq_type, edge_both, polarity;
-+ unsigned long flags;
-+
-+ switch (trigger) {
-+ case IRQ_TYPE_EDGE_RISING:
-+ irq_type = mask; /* 1: edge triggered */
-+ edge_both = 0; /* 0: single edge */
-+ polarity = mask; /* 1: rising edge */
-+ break;
-+ case IRQ_TYPE_EDGE_FALLING:
-+ irq_type = mask; /* 1: edge triggered */
-+ edge_both = 0; /* 0: single edge */
-+ polarity = 0; /* 0: falling edge */
-+ break;
-+ case IRQ_TYPE_EDGE_BOTH:
-+ irq_type = mask; /* 1: edge triggered */
-+ edge_both = mask; /* 1: both edges */
-+ polarity = 0; /* 0: ignored */
-+ break;
-+ case IRQ_TYPE_LEVEL_HIGH:
-+ irq_type = 0; /* 0: level triggered */
-+ edge_both = 0; /* 0: ignored */
-+ polarity = mask; /* 1: high level */
-+ break;
-+ case IRQ_TYPE_LEVEL_LOW:
-+ irq_type = 0; /* 0: level triggered */
-+ edge_both = 0; /* 0: ignored */
-+ polarity = 0; /* 0: low level */
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ if (trigger & IRQ_TYPE_EDGE_BOTH)
-+ irq_set_handler_locked(d, handle_edge_irq);
-+ else
-+ irq_set_handler_locked(d, handle_level_irq);
-+
-+ raw_spin_lock_irqsave(&sfp->lock, flags);
-+ irq_type |= readl_relaxed(base + irq_reg->is_reg_base) & ~mask;
-+ writel_relaxed(irq_type, base + irq_reg->is_reg_base);
-+
-+ edge_both |= readl_relaxed(base + irq_reg->ibe_reg_base) & ~mask;
-+ writel_relaxed(edge_both, base + irq_reg->ibe_reg_base);
-+
-+ polarity |= readl_relaxed(base + irq_reg->iev_reg_base) & ~mask;
-+ writel_relaxed(polarity, base + irq_reg->iev_reg_base);
-+ raw_spin_unlock_irqrestore(&sfp->lock, flags);
-+ return 0;
-+}
-+
-+static struct irq_chip jh7110_irq_chip = {
-+ .irq_ack = jh7110_irq_ack,
-+ .irq_mask = jh7110_irq_mask,
-+ .irq_mask_ack = jh7110_irq_mask_ack,
-+ .irq_unmask = jh7110_irq_unmask,
-+ .irq_set_type = jh7110_irq_set_type,
-+ .flags = IRQCHIP_IMMUTABLE | IRQCHIP_SET_TYPE_MASKED,
-+ GPIOCHIP_IRQ_RESOURCE_HELPERS,
-+};
-+
-+static void jh7110_disable_clock(void *data)
-+{
-+ clk_disable_unprepare(data);
-+}
-+
-+int jh7110_pinctrl_probe(struct platform_device *pdev)
-+{
-+ struct device *dev = &pdev->dev;
-+ const struct jh7110_pinctrl_soc_info *info;
-+ struct jh7110_pinctrl *sfp;
-+ struct pinctrl_desc *jh7110_pinctrl_desc;
-+ struct reset_control *rst;
-+ struct clk *clk;
-+ int ret;
-+
-+ info = of_device_get_match_data(&pdev->dev);
-+ if (!info)
-+ return -ENODEV;
-+
-+ if (!info->pins || !info->npins) {
-+ dev_err(dev, "wrong pinctrl info\n");
-+ return -EINVAL;
-+ }
-+
-+ sfp = devm_kzalloc(dev, sizeof(*sfp), GFP_KERNEL);
-+ if (!sfp)
-+ return -ENOMEM;
-+
-+ sfp->base = devm_platform_ioremap_resource(pdev, 0);
-+ if (IS_ERR(sfp->base))
-+ return PTR_ERR(sfp->base);
-+
-+ clk = devm_clk_get_optional(dev, NULL);
-+ if (IS_ERR(clk))
-+ return dev_err_probe(dev, PTR_ERR(clk), "could not get clock\n");
-+
-+ rst = devm_reset_control_get_exclusive(dev, NULL);
-+ if (IS_ERR(rst))
-+ return dev_err_probe(dev, PTR_ERR(rst), "could not get reset\n");
-+
-+ /*
-+ * we don't want to assert reset and risk undoing pin muxing for the
-+ * early boot serial console, but let's make sure the reset line is
-+ * deasserted in case someone runs a really minimal bootloader.
-+ */
-+ ret = reset_control_deassert(rst);
-+ if (ret)
-+ return dev_err_probe(dev, ret, "could not deassert reset\n");
-+
-+ if (clk) {
-+ ret = clk_prepare_enable(clk);
-+ if (ret)
-+ return dev_err_probe(dev, ret, "could not enable clock\n");
-+
-+ ret = devm_add_action_or_reset(dev, jh7110_disable_clock, clk);
-+ if (ret)
-+ return ret;
-+ }
-+
-+ jh7110_pinctrl_desc = devm_kzalloc(&pdev->dev,
-+ sizeof(*jh7110_pinctrl_desc),
-+ GFP_KERNEL);
-+ if (!jh7110_pinctrl_desc)
-+ return -ENOMEM;
-+
-+ jh7110_pinctrl_desc->name = dev_name(dev);
-+ jh7110_pinctrl_desc->pins = info->pins;
-+ jh7110_pinctrl_desc->npins = info->npins;
-+ jh7110_pinctrl_desc->pctlops = &jh7110_pinctrl_ops;
-+ jh7110_pinctrl_desc->pmxops = &jh7110_pinmux_ops;
-+ jh7110_pinctrl_desc->confops = &jh7110_pinconf_ops;
-+ jh7110_pinctrl_desc->owner = THIS_MODULE;
-+
-+ sfp->info = info;
-+ sfp->dev = dev;
-+ platform_set_drvdata(pdev, sfp);
-+ sfp->gc.parent = dev;
-+ raw_spin_lock_init(&sfp->lock);
-+ mutex_init(&sfp->mutex);
-+
-+ ret = devm_pinctrl_register_and_init(dev,
-+ jh7110_pinctrl_desc,
-+ sfp, &sfp->pctl);
-+ if (ret)
-+ return dev_err_probe(dev, ret,
-+ "could not register pinctrl driver\n");
-+
-+ sfp->gc.label = dev_name(dev);
-+ sfp->gc.owner = THIS_MODULE;
-+ sfp->gc.request = jh7110_gpio_request;
-+ sfp->gc.free = jh7110_gpio_free;
-+ sfp->gc.get_direction = jh7110_gpio_get_direction;
-+ sfp->gc.direction_input = jh7110_gpio_direction_input;
-+ sfp->gc.direction_output = jh7110_gpio_direction_output;
-+ sfp->gc.get = jh7110_gpio_get;
-+ sfp->gc.set = jh7110_gpio_set;
-+ sfp->gc.set_config = jh7110_gpio_set_config;
-+ sfp->gc.add_pin_ranges = jh7110_gpio_add_pin_ranges;
-+ sfp->gc.base = info->gc_base;
-+ sfp->gc.ngpio = info->ngpios;
-+
-+ jh7110_irq_chip.name = sfp->gc.label;
-+ gpio_irq_chip_set_chip(&sfp->gc.irq, &jh7110_irq_chip);
-+ sfp->gc.irq.parent_handler = info->jh7110_gpio_irq_handler;
-+ sfp->gc.irq.num_parents = 1;
-+ sfp->gc.irq.parents = devm_kcalloc(dev, sfp->gc.irq.num_parents,
-+ sizeof(*sfp->gc.irq.parents),
-+ GFP_KERNEL);
-+ if (!sfp->gc.irq.parents)
-+ return -ENOMEM;
-+ sfp->gc.irq.default_type = IRQ_TYPE_NONE;
-+ sfp->gc.irq.handler = handle_bad_irq;
-+ sfp->gc.irq.init_hw = info->jh7110_gpio_init_hw;
-+
-+ ret = platform_get_irq(pdev, 0);
-+ if (ret < 0)
-+ return ret;
-+ sfp->gc.irq.parents[0] = ret;
-+
-+ ret = devm_gpiochip_add_data(dev, &sfp->gc, sfp);
-+ if (ret)
-+ return dev_err_probe(dev, ret, "could not register gpiochip\n");
-+
-+ irq_domain_set_pm_device(sfp->gc.irq.domain, dev);
-+
-+ dev_info(dev, "StarFive GPIO chip registered %d GPIOs\n", sfp->gc.ngpio);
-+
-+ return pinctrl_enable(sfp->pctl);
-+}
-+EXPORT_SYMBOL_GPL(jh7110_pinctrl_probe);
-+
-+MODULE_DESCRIPTION("Pinctrl driver for the StarFive JH7110 SoC");
-+MODULE_AUTHOR("Emil Renner Berthing <kernel@esmil.dk>");
-+MODULE_AUTHOR("Jianlong Huang <jianlong.huang@starfivetech.com>");
-+MODULE_LICENSE("GPL");
---- /dev/null
-+++ b/drivers/pinctrl/starfive/pinctrl-starfive-jh7110.h
-@@ -0,0 +1,70 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+/*
-+ * Pinctrl / GPIO driver for StarFive JH7110 SoC
-+ *
-+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
-+ */
-+
-+#ifndef __PINCTRL_STARFIVE_JH7110_H__
-+#define __PINCTRL_STARFIVE_JH7110_H__
-+
-+#include <linux/pinctrl/pinconf-generic.h>
-+#include <linux/pinctrl/pinmux.h>
-+
-+struct jh7110_pinctrl {
-+ struct device *dev;
-+ struct gpio_chip gc;
-+ struct pinctrl_gpio_range gpios;
-+ raw_spinlock_t lock;
-+ void __iomem *base;
-+ struct pinctrl_dev *pctl;
-+ /* register read/write mutex */
-+ struct mutex mutex;
-+ const struct jh7110_pinctrl_soc_info *info;
-+};
-+
-+struct jh7110_gpio_irq_reg {
-+ unsigned int is_reg_base;
-+ unsigned int ic_reg_base;
-+ unsigned int ibe_reg_base;
-+ unsigned int iev_reg_base;
-+ unsigned int ie_reg_base;
-+ unsigned int ris_reg_base;
-+ unsigned int mis_reg_base;
-+};
-+
-+struct jh7110_pinctrl_soc_info {
-+ const struct pinctrl_pin_desc *pins;
-+ unsigned int npins;
-+ unsigned int ngpios;
-+ unsigned int gc_base;
-+
-+ /* gpio dout/doen/din/gpioinput register */
-+ unsigned int dout_reg_base;
-+ unsigned int dout_mask;
-+ unsigned int doen_reg_base;
-+ unsigned int doen_mask;
-+ unsigned int gpi_reg_base;
-+ unsigned int gpi_mask;
-+ unsigned int gpioin_reg_base;
-+
-+ const struct jh7110_gpio_irq_reg *irq_reg;
-+
-+ /* generic pinmux */
-+ int (*jh7110_set_one_pin_mux)(struct jh7110_pinctrl *sfp,
-+ unsigned int pin,
-+ unsigned int din, u32 dout,
-+ u32 doen, u32 func);
-+ /* gpio chip */
-+ int (*jh7110_get_padcfg_base)(struct jh7110_pinctrl *sfp,
-+ unsigned int pin);
-+ void (*jh7110_gpio_irq_handler)(struct irq_desc *desc);
-+ int (*jh7110_gpio_init_hw)(struct gpio_chip *gc);
-+};
-+
-+void jh7110_set_gpiomux(struct jh7110_pinctrl *sfp, unsigned int pin,
-+ unsigned int din, u32 dout, u32 doen);
-+int jh7110_pinctrl_probe(struct platform_device *pdev);
-+struct jh7110_pinctrl *jh7110_from_irq_desc(struct irq_desc *desc);
-+
-+#endif /* __PINCTRL_STARFIVE_JH7110_H__ */
diff --git a/target/linux/starfive/patches-6.1/0029-pinctrl-starfive-Add-StarFive-JH7110-aon-controller-.patch b/target/linux/starfive/patches-6.1/0029-pinctrl-starfive-Add-StarFive-JH7110-aon-controller-.patch
deleted file mode 100644
index 54e2c7c53b..0000000000
--- a/target/linux/starfive/patches-6.1/0029-pinctrl-starfive-Add-StarFive-JH7110-aon-controller-.patch
+++ /dev/null
@@ -1,224 +0,0 @@
-From 9c1a9d6dfd6a9c28794536c8af002746a20d840f Mon Sep 17 00:00:00 2001
-From: Jianlong Huang <jianlong.huang@starfivetech.com>
-Date: Thu, 9 Feb 2023 22:37:02 +0800
-Subject: [PATCH 029/122] pinctrl: starfive: Add StarFive JH7110 aon controller
- driver
-
-Add pinctrl driver for StarFive JH7110 SoC aon pinctrl controller.
-
-Co-developed-by: Emil Renner Berthing <kernel@esmil.dk>
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
-Signed-off-by: Jianlong Huang <jianlong.huang@starfivetech.com>
-Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
----
- drivers/pinctrl/starfive/Kconfig | 12 ++
- drivers/pinctrl/starfive/Makefile | 1 +
- .../starfive/pinctrl-starfive-jh7110-aon.c | 177 ++++++++++++++++++
- 3 files changed, 190 insertions(+)
- create mode 100644 drivers/pinctrl/starfive/pinctrl-starfive-jh7110-aon.c
-
---- a/drivers/pinctrl/starfive/Kconfig
-+++ b/drivers/pinctrl/starfive/Kconfig
-@@ -37,3 +37,15 @@ config PINCTRL_STARFIVE_JH7110_SYS
- This also provides an interface to the GPIO pins not used by other
- peripherals supporting inputs, outputs, configuring pull-up/pull-down
- and interrupts on input changes.
-+
-+config PINCTRL_STARFIVE_JH7110_AON
-+ tristate "Always-on pinctrl and GPIO driver for the StarFive JH7110 SoC"
-+ depends on SOC_STARFIVE || COMPILE_TEST
-+ depends on OF
-+ select PINCTRL_STARFIVE_JH7110
-+ default SOC_STARFIVE
-+ help
-+ Say yes here to support always-on pin control on the StarFive JH7110 SoC.
-+ This also provides an interface to the GPIO pins not used by other
-+ peripherals supporting inputs, outputs, configuring pull-up/pull-down
-+ and interrupts on input changes.
---- a/drivers/pinctrl/starfive/Makefile
-+++ b/drivers/pinctrl/starfive/Makefile
-@@ -4,3 +4,4 @@ obj-$(CONFIG_PINCTRL_STARFIVE_JH7100) +=
-
- obj-$(CONFIG_PINCTRL_STARFIVE_JH7110) += pinctrl-starfive-jh7110.o
- obj-$(CONFIG_PINCTRL_STARFIVE_JH7110_SYS) += pinctrl-starfive-jh7110-sys.o
-+obj-$(CONFIG_PINCTRL_STARFIVE_JH7110_AON) += pinctrl-starfive-jh7110-aon.o
---- /dev/null
-+++ b/drivers/pinctrl/starfive/pinctrl-starfive-jh7110-aon.c
-@@ -0,0 +1,177 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Pinctrl / GPIO driver for StarFive JH7110 SoC aon controller
-+ *
-+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
-+ */
-+
-+#include <linux/err.h>
-+#include <linux/gpio/driver.h>
-+#include <linux/init.h>
-+#include <linux/interrupt.h>
-+#include <linux/io.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/of_device.h>
-+#include <linux/of_irq.h>
-+#include <linux/of_platform.h>
-+#include <linux/pinctrl/pinconf.h>
-+#include <linux/pinctrl/pinconf-generic.h>
-+#include <linux/pinctrl/pinctrl.h>
-+#include <linux/pinctrl/pinmux.h>
-+#include <linux/platform_device.h>
-+#include <linux/pm_runtime.h>
-+#include <linux/regmap.h>
-+#include <linux/slab.h>
-+
-+#include <dt-bindings/pinctrl/starfive,jh7110-pinctrl.h>
-+
-+#include "../core.h"
-+#include "../pinconf.h"
-+#include "../pinmux.h"
-+#include "pinctrl-starfive-jh7110.h"
-+
-+#define JH7110_AON_NGPIO 4
-+#define JH7110_AON_GC_BASE 64
-+
-+/* registers */
-+#define JH7110_AON_DOEN 0x0
-+#define JH7110_AON_DOUT 0x4
-+#define JH7110_AON_GPI 0x8
-+#define JH7110_AON_GPIOIN 0x2c
-+
-+#define JH7110_AON_GPIOEN 0xc
-+#define JH7110_AON_GPIOIS 0x10
-+#define JH7110_AON_GPIOIC 0x14
-+#define JH7110_AON_GPIOIBE 0x18
-+#define JH7110_AON_GPIOIEV 0x1c
-+#define JH7110_AON_GPIOIE 0x20
-+#define JH7110_AON_GPIORIS 0x28
-+#define JH7110_AON_GPIOMIS 0x28
-+
-+#define JH7110_AON_GPO_PDA_0_5_CFG 0x30
-+
-+static const struct pinctrl_pin_desc jh7110_aon_pins[] = {
-+ PINCTRL_PIN(PAD_TESTEN, "TESTEN"),
-+ PINCTRL_PIN(PAD_RGPIO0, "RGPIO0"),
-+ PINCTRL_PIN(PAD_RGPIO1, "RGPIO1"),
-+ PINCTRL_PIN(PAD_RGPIO2, "RGPIO2"),
-+ PINCTRL_PIN(PAD_RGPIO3, "RGPIO3"),
-+ PINCTRL_PIN(PAD_RSTN, "RSTN"),
-+ PINCTRL_PIN(PAD_GMAC0_MDC, "GMAC0_MDC"),
-+ PINCTRL_PIN(PAD_GMAC0_MDIO, "GMAC0_MDIO"),
-+ PINCTRL_PIN(PAD_GMAC0_RXD0, "GMAC0_RXD0"),
-+ PINCTRL_PIN(PAD_GMAC0_RXD1, "GMAC0_RXD1"),
-+ PINCTRL_PIN(PAD_GMAC0_RXD2, "GMAC0_RXD2"),
-+ PINCTRL_PIN(PAD_GMAC0_RXD3, "GMAC0_RXD3"),
-+ PINCTRL_PIN(PAD_GMAC0_RXDV, "GMAC0_RXDV"),
-+ PINCTRL_PIN(PAD_GMAC0_RXC, "GMAC0_RXC"),
-+ PINCTRL_PIN(PAD_GMAC0_TXD0, "GMAC0_TXD0"),
-+ PINCTRL_PIN(PAD_GMAC0_TXD1, "GMAC0_TXD1"),
-+ PINCTRL_PIN(PAD_GMAC0_TXD2, "GMAC0_TXD2"),
-+ PINCTRL_PIN(PAD_GMAC0_TXD3, "GMAC0_TXD3"),
-+ PINCTRL_PIN(PAD_GMAC0_TXEN, "GMAC0_TXEN"),
-+ PINCTRL_PIN(PAD_GMAC0_TXC, "GMAC0_TXC"),
-+};
-+
-+static int jh7110_aon_set_one_pin_mux(struct jh7110_pinctrl *sfp,
-+ unsigned int pin,
-+ unsigned int din, u32 dout,
-+ u32 doen, u32 func)
-+{
-+ if (pin < sfp->gc.ngpio && func == 0)
-+ jh7110_set_gpiomux(sfp, pin, din, dout, doen);
-+
-+ return 0;
-+}
-+
-+static int jh7110_aon_get_padcfg_base(struct jh7110_pinctrl *sfp,
-+ unsigned int pin)
-+{
-+ if (pin < PAD_GMAC0_MDC)
-+ return JH7110_AON_GPO_PDA_0_5_CFG;
-+
-+ return -1;
-+}
-+
-+static void jh7110_aon_irq_handler(struct irq_desc *desc)
-+{
-+ struct jh7110_pinctrl *sfp = jh7110_from_irq_desc(desc);
-+ struct irq_chip *chip = irq_desc_get_chip(desc);
-+ unsigned long mis;
-+ unsigned int pin;
-+
-+ chained_irq_enter(chip, desc);
-+
-+ mis = readl_relaxed(sfp->base + JH7110_AON_GPIOMIS);
-+ for_each_set_bit(pin, &mis, JH7110_AON_NGPIO)
-+ generic_handle_domain_irq(sfp->gc.irq.domain, pin);
-+
-+ chained_irq_exit(chip, desc);
-+}
-+
-+static int jh7110_aon_init_hw(struct gpio_chip *gc)
-+{
-+ struct jh7110_pinctrl *sfp = container_of(gc,
-+ struct jh7110_pinctrl, gc);
-+
-+ /* mask all GPIO interrupts */
-+ writel_relaxed(0, sfp->base + JH7110_AON_GPIOIE);
-+ /* clear edge interrupt flags */
-+ writel_relaxed(0, sfp->base + JH7110_AON_GPIOIC);
-+ writel_relaxed(0x0f, sfp->base + JH7110_AON_GPIOIC);
-+ /* enable GPIO interrupts */
-+ writel_relaxed(1, sfp->base + JH7110_AON_GPIOEN);
-+ return 0;
-+}
-+
-+static const struct jh7110_gpio_irq_reg jh7110_aon_irq_reg = {
-+ .is_reg_base = JH7110_AON_GPIOIS,
-+ .ic_reg_base = JH7110_AON_GPIOIC,
-+ .ibe_reg_base = JH7110_AON_GPIOIBE,
-+ .iev_reg_base = JH7110_AON_GPIOIEV,
-+ .ie_reg_base = JH7110_AON_GPIOIE,
-+ .ris_reg_base = JH7110_AON_GPIORIS,
-+ .mis_reg_base = JH7110_AON_GPIOMIS,
-+};
-+
-+static const struct jh7110_pinctrl_soc_info jh7110_aon_pinctrl_info = {
-+ .pins = jh7110_aon_pins,
-+ .npins = ARRAY_SIZE(jh7110_aon_pins),
-+ .ngpios = JH7110_AON_NGPIO,
-+ .gc_base = JH7110_AON_GC_BASE,
-+ .dout_reg_base = JH7110_AON_DOUT,
-+ .dout_mask = GENMASK(3, 0),
-+ .doen_reg_base = JH7110_AON_DOEN,
-+ .doen_mask = GENMASK(2, 0),
-+ .gpi_reg_base = JH7110_AON_GPI,
-+ .gpi_mask = GENMASK(3, 0),
-+ .gpioin_reg_base = JH7110_AON_GPIOIN,
-+ .irq_reg = &jh7110_aon_irq_reg,
-+ .jh7110_set_one_pin_mux = jh7110_aon_set_one_pin_mux,
-+ .jh7110_get_padcfg_base = jh7110_aon_get_padcfg_base,
-+ .jh7110_gpio_irq_handler = jh7110_aon_irq_handler,
-+ .jh7110_gpio_init_hw = jh7110_aon_init_hw,
-+};
-+
-+static const struct of_device_id jh7110_aon_pinctrl_of_match[] = {
-+ {
-+ .compatible = "starfive,jh7110-aon-pinctrl",
-+ .data = &jh7110_aon_pinctrl_info,
-+ },
-+ { /* sentinel */ }
-+};
-+MODULE_DEVICE_TABLE(of, jh7110_aon_pinctrl_of_match);
-+
-+static struct platform_driver jh7110_aon_pinctrl_driver = {
-+ .probe = jh7110_pinctrl_probe,
-+ .driver = {
-+ .name = "starfive-jh7110-aon-pinctrl",
-+ .of_match_table = jh7110_aon_pinctrl_of_match,
-+ },
-+};
-+module_platform_driver(jh7110_aon_pinctrl_driver);
-+
-+MODULE_DESCRIPTION("Pinctrl driver for the StarFive JH7110 SoC aon controller");
-+MODULE_AUTHOR("Jianlong Huang <jianlong.huang@starfivetech.com>");
-+MODULE_LICENSE("GPL");
diff --git a/target/linux/starfive/patches-6.1/0030-config-add-jh7110-defconfig-for-test-mini.patch b/target/linux/starfive/patches-6.1/0030-config-add-jh7110-defconfig-for-test-mini.patch
deleted file mode 100644
index 6c6afb853d..0000000000
--- a/target/linux/starfive/patches-6.1/0030-config-add-jh7110-defconfig-for-test-mini.patch
+++ /dev/null
@@ -1,228 +0,0 @@
-From 537ee9e5bb7b4ebee4ad5a607098c8200af6c261 Mon Sep 17 00:00:00 2001
-From: "shanlong.li" <shanlong.li@starfivetech.com>
-Date: Thu, 18 May 2023 19:27:28 -0700
-Subject: [PATCH 030/122] config: add jh7110 defconfig for test mini
-
-add jh7110 defconfig for test mini
-
-Signed-off-by: shanlong.li <shanlong.li@starfivetech.com>
----
- arch/riscv/configs/jh7110_defconfig | 212 ++++++++++++++++++++++++++++
- 1 file changed, 212 insertions(+)
- create mode 100755 arch/riscv/configs/jh7110_defconfig
-
---- /dev/null
-+++ b/arch/riscv/configs/jh7110_defconfig
-@@ -0,0 +1,212 @@
-+CONFIG_WERROR=y
-+CONFIG_SYSVIPC=y
-+# CONFIG_CROSS_MEMORY_ATTACH is not set
-+CONFIG_NO_HZ_IDLE=y
-+CONFIG_HIGH_RES_TIMERS=y
-+CONFIG_PSI=y
-+# CONFIG_CPU_ISOLATION is not set
-+CONFIG_IKCONFIG=y
-+CONFIG_IKCONFIG_PROC=y
-+CONFIG_CGROUPS=y
-+CONFIG_CGROUP_SCHED=y
-+CONFIG_CGROUP_PIDS=y
-+CONFIG_CGROUP_CPUACCT=y
-+CONFIG_NAMESPACES=y
-+CONFIG_BLK_DEV_INITRD=y
-+CONFIG_RD_GZIP=y
-+# CONFIG_RD_BZIP2 is not set
-+# CONFIG_RD_LZMA is not set
-+# CONFIG_RD_XZ is not set
-+# CONFIG_RD_LZO is not set
-+# CONFIG_RD_LZ4 is not set
-+CONFIG_EXPERT=y
-+# CONFIG_SYSFS_SYSCALL is not set
-+CONFIG_KCMP=y
-+CONFIG_PERF_EVENTS=y
-+CONFIG_ARCH_STARFIVE=y
-+CONFIG_SOC_STARFIVE=y
-+CONFIG_ERRATA_SIFIVE=y
-+CONFIG_SMP=y
-+# CONFIG_RISCV_ISA_SVPBMT is not set
-+# CONFIG_COMPAT is not set
-+CONFIG_CPU_IDLE=y
-+CONFIG_RISCV_SBI_CPUIDLE=y
-+CONFIG_JUMP_LABEL=y
-+# CONFIG_STACKPROTECTOR is not set
-+CONFIG_MODULES=y
-+CONFIG_MODULE_UNLOAD=y
-+CONFIG_MODULE_COMPRESS_ZSTD=y
-+# CONFIG_BLOCK_LEGACY_AUTOLOAD is not set
-+CONFIG_BLK_WBT=y
-+# CONFIG_BLK_DEBUG_FS is not set
-+CONFIG_PARTITION_ADVANCED=y
-+# CONFIG_MQ_IOSCHED_DEADLINE is not set
-+# CONFIG_MQ_IOSCHED_KYBER is not set
-+CONFIG_IOSCHED_BFQ=y
-+CONFIG_KSM=y
-+# CONFIG_VM_EVENT_COUNTERS is not set
-+CONFIG_NET=y
-+CONFIG_PACKET=y
-+CONFIG_UNIX=y
-+CONFIG_INET=y
-+CONFIG_IP_ADVANCED_ROUTER=y
-+CONFIG_IP_MULTIPLE_TABLES=y
-+CONFIG_INET_DIAG=m
-+# CONFIG_IPV6_SIT is not set
-+CONFIG_IPV6_MULTIPLE_TABLES=y
-+# CONFIG_WIRELESS is not set
-+# CONFIG_ETHTOOL_NETLINK is not set
-+CONFIG_DEVTMPFS=y
-+CONFIG_DEVTMPFS_MOUNT=y
-+# CONFIG_STANDALONE is not set
-+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
-+# CONFIG_FW_LOADER is not set
-+CONFIG_EFI_DISABLE_RUNTIME=y
-+CONFIG_ZRAM=y
-+CONFIG_ZRAM_MEMORY_TRACKING=y
-+CONFIG_BLK_DEV_LOOP=y
-+CONFIG_BLK_DEV_LOOP_MIN_COUNT=1
-+CONFIG_NETDEVICES=y
-+CONFIG_STMMAC_ETH=y
-+CONFIG_DWMAC_DWC_QOS_ETH=y
-+# CONFIG_DWMAC_GENERIC is not set
-+CONFIG_DWMAC_STARFIVE=y
-+CONFIG_MICROCHIP_PHY=y
-+CONFIG_MOTORCOMM_PHY=y
-+# CONFIG_WLAN is not set
-+# CONFIG_INPUT_KEYBOARD is not set
-+# CONFIG_INPUT_MOUSE is not set
-+# CONFIG_SERIO is not set
-+# CONFIG_VT is not set
-+# CONFIG_LEGACY_PTYS is not set
-+# CONFIG_LDISC_AUTOLOAD is not set
-+CONFIG_SERIAL_8250=y
-+# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
-+# CONFIG_SERIAL_8250_16550A_VARIANTS is not set
-+CONFIG_SERIAL_8250_CONSOLE=y
-+CONFIG_SERIAL_8250_DW=y
-+CONFIG_SERIAL_OF_PLATFORM=y
-+# CONFIG_DEVMEM is not set
-+# CONFIG_RANDOM_TRUST_BOOTLOADER is not set
-+CONFIG_I2C=y
-+# CONFIG_I2C_COMPAT is not set
-+CONFIG_I2C_CHARDEV=y
-+# CONFIG_I2C_HELPER_AUTO is not set
-+CONFIG_I2C_DESIGNWARE_PLATFORM=y
-+# CONFIG_PTP_1588_CLOCK is not set
-+CONFIG_PINCTRL_STARFIVE_JH7110=y
-+CONFIG_GPIOLIB_FASTPATH_LIMIT=128
-+CONFIG_GPIO_SYSFS=y
-+CONFIG_POWER_RESET=y
-+CONFIG_POWER_RESET_GPIO_RESTART=y
-+CONFIG_SENSORS_SFCTEMP=y
-+# CONFIG_HID is not set
-+CONFIG_MMC=y
-+# CONFIG_PWRSEQ_EMMC is not set
-+# CONFIG_PWRSEQ_SIMPLE is not set
-+CONFIG_MMC_DW=y
-+# CONFIG_VIRTIO_MENU is not set
-+CONFIG_CLK_STARFIVE_JH7110_AON=y
-+# CONFIG_VHOST_MENU is not set
-+# CONFIG_IOMMU_SUPPORT is not set
-+CONFIG_BTRFS_FS=y
-+CONFIG_BTRFS_FS_POSIX_ACL=y
-+# CONFIG_DNOTIFY is not set
-+CONFIG_FANOTIFY=y
-+CONFIG_AUTOFS_FS=y
-+CONFIG_VFAT_FS=y
-+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-15"
-+CONFIG_FAT_DEFAULT_UTF8=y
-+CONFIG_PROC_KCORE=y
-+CONFIG_PROC_CHILDREN=y
-+CONFIG_TMPFS=y
-+CONFIG_TMPFS_POSIX_ACL=y
-+CONFIG_EFIVAR_FS=y
-+# CONFIG_MISC_FILESYSTEMS is not set
-+# CONFIG_NETWORK_FILESYSTEMS is not set
-+CONFIG_NLS_DEFAULT="iso8859-15"
-+CONFIG_NLS_CODEPAGE_437=y
-+CONFIG_NLS_ISO8859_15=y
-+CONFIG_LSM=""
-+CONFIG_CRYPTO_ZSTD=y
-+# CONFIG_RAID6_PQ_BENCHMARK is not set
-+# CONFIG_DEBUG_MISC is not set
-+CONFIG_STRIP_ASM_SYMS=y
-+CONFIG_DEBUG_SECTION_MISMATCH=y
-+# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
-+CONFIG_DEBUG_FS=y
-+# CONFIG_SLUB_DEBUG is not set
-+CONFIG_PAGE_TABLE_CHECK=y
-+CONFIG_DEBUG_RODATA_TEST=y
-+CONFIG_DEBUG_WX=y
-+CONFIG_SOFTLOCKUP_DETECTOR=y
-+CONFIG_WQ_WATCHDOG=y
-+# CONFIG_SCHED_DEBUG is not set
-+CONFIG_STACKTRACE=y
-+CONFIG_RCU_CPU_STALL_TIMEOUT=60
-+# CONFIG_RCU_TRACE is not set
-+# CONFIG_FTRACE is not set
-+# CONFIG_RUNTIME_TESTING_MENU is not set
-+CONFIG_EXT4_FS=y
-+CONFIG_CPUFREQ_DT_PLATDEV=y
-+CONFIG_CPUFREQ_DT=y
-+CONFIG_CPU_FREQ=y
-+CONFIG_HIBERNATION=y
-+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
-+CONFIG_SWAP=y
-+CONFIG_PCIE_STARFIVE=y
-+CONFIG_PCI_MSI=y
-+CONFIG_PCI=y
-+CONFIG_USB_CDNS3_STARFIVE=y
-+CONFIG_PHY_STARFIVE_JH7110_PCIE=y
-+CONFIG_PHY_STARFIVE_JH7110_USB=y
-+CONFIG_USB_CDNS_SUPPORT=y
-+CONFIG_USB_CDNS3=y
-+CONFIG_USB=y
-+CONFIG_USB_SUPPORT=y
-+CONFIG_VIDEO_STARFIVE_CAMSS=y
-+CONFIG_VIDEO_CADENCE_CSI2RX=y
-+CONFIG_VIDEO_DEV=y
-+CONFIG_V4L_PLATFORM_DRIVERS=y
-+CONFIG_MEDIA_PLATFORM_DRIVERS=y
-+CONFIG_MEDIA_PLATFORM_SUPPORT=y
-+CONFIG_MEDIA_SUPPORT=y
-+CONFIG_PHY_STARFIVE_DPHY_RX=y
-+CONFIG_CRYPTO_DEV_JH7110=y
-+CONFIG_CRYPTO_HW=y
-+CONFIG_CRYPTO=y
-+CONFIG_SND_SOC_JH7110_TDM=y
-+CONFIG_SND_SOC_STARFIVE=y
-+CONFIG_SND_SOC=y
-+CONFIG_SND=y
-+CONFIG_SOUND=y
-+CONFIG_DW_AXI_DMAC=y
-+CONFIG_DMADEVICES=y
-+CONFIG_HAS_IOMEM=y
-+CONFIG_PWM_STARFIVE_PTC=y
-+CONFIG_PWM=y
-+CONFIG_STARFIVE_TIMER=y
-+CONFIG_SECTION_MISMATCH_WARN_ONLY=y
-+CONFIG_GENERIC_CLOCKEVENTS=y
-+CONFIG_STARFIVE_WATCHDOG=y
-+CONFIG_WATCHDOG=y
-+CONFIG_HW_RANDOM_JH7110=y
-+CONFIG_HW_RANDOM=y
-+CONFIG_STMMAC_PLATFORM=y
-+CONFIG_SPI_CADENCE_QUADSPI=y
-+CONFIG_SPI_MASTER=y
-+CONFIG_SPI=y
-+CONFIG_MMC_DW_STARFIVE=y
-+CONFIG_CLK_STARFIVE_JH7110_PLL=y
-+CONFIG_CLK_STARFIVE_JH7110_VOUT=y
-+CONFIG_CLK_STARFIVE_JH7110_ISP=y
-+CONFIG_CLK_STARFIVE_JH7110_STG=y
-+CONFIG_JH71XX_PMU=y
-+CONFIG_PM=y
-+CONFIG_PINCTRL_STARFIVE_JH7110_AON=y
-+CONFIG_PINCTRL_STARFIVE_JH7110_SYS=y
-+CONFIG_CLK_STARFIVE_JH7110_AON=y
-+CONFIG_CLK_STARFIVE_JH7110_SYS=y
-+CONFIG_SIFIVE_CCACHE=y
-+CONFIG_CLINT_TIMER=y
-+CONFIG_SIFIVE_PLIC=y
diff --git a/target/linux/starfive/patches-6.1/0031-dt-bindings-clock-Add-StarFive-JH7110-PLL-clock-gene.patch b/target/linux/starfive/patches-6.1/0031-dt-bindings-clock-Add-StarFive-JH7110-PLL-clock-gene.patch
deleted file mode 100644
index 74eb4b2f18..0000000000
--- a/target/linux/starfive/patches-6.1/0031-dt-bindings-clock-Add-StarFive-JH7110-PLL-clock-gene.patch
+++ /dev/null
@@ -1,80 +0,0 @@
-From 07f62b08668c0295b1c6342f9708b7e36093ff59 Mon Sep 17 00:00:00 2001
-From: Xingyu Wu <xingyu.wu@starfivetech.com>
-Date: Tue, 21 Feb 2023 17:13:48 +0800
-Subject: [PATCH 031/122] dt-bindings: clock: Add StarFive JH7110 PLL clock
- generator
-
-Add bindings for the PLL clock generator on the JH7110 RISC-V SoC.
-
-Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
----
- .../bindings/clock/starfive,jh7110-pll.yaml | 46 +++++++++++++++++++
- .../dt-bindings/clock/starfive,jh7110-crg.h | 6 +++
- 2 files changed, 52 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/clock/starfive,jh7110-pll.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/clock/starfive,jh7110-pll.yaml
-@@ -0,0 +1,46 @@
-+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/clock/starfive,jh7110-pll.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: StarFive JH7110 PLL Clock Generator
-+
-+description:
-+ This PLL are high speed, low jitter frequency synthesizers in JH7110.
-+ Each PLL clocks work in integer mode or fraction mode by some dividers,
-+ and the configuration registers and dividers are set in several syscon
-+ registers. So pll node should be a child of SYS-SYSCON node.
-+ The formula for calculating frequency is that,
-+ Fvco = Fref * (NI + NF) / M / Q1
-+
-+maintainers:
-+ - Xingyu Wu <xingyu.wu@starfivetech.com>
-+
-+properties:
-+ compatible:
-+ const: starfive,jh7110-pll
-+
-+ clocks:
-+ maxItems: 1
-+ description: Main Oscillator (24 MHz)
-+
-+ '#clock-cells':
-+ const: 1
-+ description:
-+ See <dt-bindings/clock/starfive,jh7110-crg.h> for valid indices.
-+
-+required:
-+ - compatible
-+ - clocks
-+ - '#clock-cells'
-+
-+additionalProperties: false
-+
-+examples:
-+ - |
-+ pll-clock-controller {
-+ compatible = "starfive,jh7110-pll";
-+ clocks = <&osc>;
-+ #clock-cells = <1>;
-+ };
---- a/include/dt-bindings/clock/starfive,jh7110-crg.h
-+++ b/include/dt-bindings/clock/starfive,jh7110-crg.h
-@@ -6,6 +6,12 @@
- #ifndef __DT_BINDINGS_CLOCK_STARFIVE_JH7110_CRG_H__
- #define __DT_BINDINGS_CLOCK_STARFIVE_JH7110_CRG_H__
-
-+/* PLL clocks */
-+#define JH7110_CLK_PLL0_OUT 0
-+#define JH7110_CLK_PLL1_OUT 1
-+#define JH7110_CLK_PLL2_OUT 2
-+#define JH7110_PLLCLK_END 3
-+
- /* SYSCRG clocks */
- #define JH7110_SYSCLK_CPU_ROOT 0
- #define JH7110_SYSCLK_CPU_CORE 1
diff --git a/target/linux/starfive/patches-6.1/0032-clk-starfive-Add-StarFive-JH7110-PLL-clock-driver.patch b/target/linux/starfive/patches-6.1/0032-clk-starfive-Add-StarFive-JH7110-PLL-clock-driver.patch
deleted file mode 100644
index 69dc662f10..0000000000
--- a/target/linux/starfive/patches-6.1/0032-clk-starfive-Add-StarFive-JH7110-PLL-clock-driver.patch
+++ /dev/null
@@ -1,786 +0,0 @@
-From 0bc7aa28dcdee75a52b1874a02dfbf0107c2d448 Mon Sep 17 00:00:00 2001
-From: Xingyu Wu <xingyu.wu@starfivetech.com>
-Date: Fri, 17 Feb 2023 17:30:09 +0800
-Subject: [PATCH 032/122] clk: starfive: Add StarFive JH7110 PLL clock driver
-
-Add driver for the StarFive JH7110 PLL clock controller
-and they work by reading and setting syscon registers.
-
-Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
----
- MAINTAINERS | 6 +
- drivers/clk/starfive/Kconfig | 8 +
- drivers/clk/starfive/Makefile | 1 +
- .../clk/starfive/clk-starfive-jh7110-pll.c | 427 ++++++++++++++++++
- .../clk/starfive/clk-starfive-jh7110-pll.h | 293 ++++++++++++
- 5 files changed, 735 insertions(+)
- create mode 100644 drivers/clk/starfive/clk-starfive-jh7110-pll.c
- create mode 100644 drivers/clk/starfive/clk-starfive-jh7110-pll.h
-
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -19657,6 +19657,12 @@ M: Emil Renner Berthing <kernel@esmil.dk
- S: Maintained
- F: arch/riscv/boot/dts/starfive/
-
-+STARFIVE JH7110 PLL CLOCK DRIVER
-+M: Xingyu Wu <xingyu.wu@starfivetech.com>
-+S: Supported
-+F: Documentation/devicetree/bindings/clock/starfive,jh7110-pll.yaml
-+F: drivers/clk/starfive/clk-starfive-jh7110-pll.*
-+
- STARFIVE JH71X0 CLOCK DRIVERS
- M: Emil Renner Berthing <kernel@esmil.dk>
- M: Hal Feng <hal.feng@starfivetech.com>
---- a/drivers/clk/starfive/Kconfig
-+++ b/drivers/clk/starfive/Kconfig
-@@ -21,6 +21,14 @@ config CLK_STARFIVE_JH7100_AUDIO
- Say Y or M here to support the audio clocks on the StarFive JH7100
- SoC.
-
-+config CLK_STARFIVE_JH7110_PLL
-+ bool "StarFive JH7110 PLL clock support"
-+ depends on ARCH_STARFIVE || COMPILE_TEST
-+ default ARCH_STARFIVE
-+ help
-+ Say yes here to support the PLL clock controller on the
-+ StarFive JH7110 SoC.
-+
- config CLK_STARFIVE_JH7110_SYS
- bool "StarFive JH7110 system clock support"
- depends on ARCH_STARFIVE || COMPILE_TEST
---- a/drivers/clk/starfive/Makefile
-+++ b/drivers/clk/starfive/Makefile
-@@ -4,5 +4,6 @@ obj-$(CONFIG_CLK_STARFIVE_JH71X0) += clk
- obj-$(CONFIG_CLK_STARFIVE_JH7100) += clk-starfive-jh7100.o
- obj-$(CONFIG_CLK_STARFIVE_JH7100_AUDIO) += clk-starfive-jh7100-audio.o
-
-+obj-$(CONFIG_CLK_STARFIVE_JH7110_PLL) += clk-starfive-jh7110-pll.o
- obj-$(CONFIG_CLK_STARFIVE_JH7110_SYS) += clk-starfive-jh7110-sys.o
- obj-$(CONFIG_CLK_STARFIVE_JH7110_AON) += clk-starfive-jh7110-aon.o
---- /dev/null
-+++ b/drivers/clk/starfive/clk-starfive-jh7110-pll.c
-@@ -0,0 +1,427 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * StarFive JH7110 PLL Clock Generator Driver
-+ *
-+ * Copyright (C) 2023 StarFive Technology Co., Ltd.
-+ *
-+ * This driver is about to register JH7110 PLL clock generator and support ops.
-+ * The JH7110 have three PLL clock, PLL0, PLL1 and PLL2.
-+ * Each PLL clocks work in integer mode or fraction mode by some dividers,
-+ * and the configuration registers and dividers are set in several syscon registers.
-+ * The formula for calculating frequency is:
-+ * Fvco = Fref * (NI + NF) / M / Q1
-+ * Fref: OSC source clock rate
-+ * NI: integer frequency dividing ratio of feedback divider, set by fbdiv[11:0].
-+ * NF: fractional frequency dividing ratio, set by frac[23:0]. NF = frac[23:0] / 2^24 = 0 ~ 0.999.
-+ * M: frequency dividing ratio of pre-divider, set by prediv[5:0].
-+ * Q1: frequency dividing ratio of post divider, set by postdiv1[1:0], Q1= 1,2,4,8.
-+ */
-+
-+#include <linux/clk-provider.h>
-+#include <linux/debugfs.h>
-+#include <linux/device.h>
-+#include <linux/kernel.h>
-+#include <linux/mfd/syscon.h>
-+#include <linux/platform_device.h>
-+#include <linux/regmap.h>
-+
-+#include <dt-bindings/clock/starfive,jh7110-crg.h>
-+
-+#include "clk-starfive-jh7110-pll.h"
-+
-+static struct jh7110_clk_pll_data *jh7110_pll_data_from(struct clk_hw *hw)
-+{
-+ return container_of(hw, struct jh7110_clk_pll_data, hw);
-+}
-+
-+static struct jh7110_clk_pll_priv *jh7110_pll_priv_from(struct jh7110_clk_pll_data *data)
-+{
-+ return container_of(data, struct jh7110_clk_pll_priv, data[data->idx]);
-+}
-+
-+/* Read register value from syscon and calculate PLL(x) frequency */
-+static unsigned long jh7110_pll_get_freq(struct jh7110_clk_pll_data *data,
-+ unsigned long parent_rate)
-+{
-+ struct jh7110_clk_pll_priv *priv = jh7110_pll_priv_from(data);
-+ struct jh7110_pll_syscon_offset *offset = &data->offset;
-+ struct jh7110_pll_syscon_mask *mask = &data->mask;
-+ struct jh7110_pll_syscon_shift *shift = &data->shift;
-+ unsigned long freq = 0;
-+ unsigned long frac_cal;
-+ u32 dacpd;
-+ u32 dsmpd;
-+ u32 fbdiv;
-+ u32 prediv;
-+ u32 postdiv1;
-+ u32 frac;
-+ u32 reg_val;
-+
-+ if (regmap_read(priv->syscon_regmap, offset->dacpd, &reg_val))
-+ goto read_error;
-+ dacpd = (reg_val & mask->dacpd) >> shift->dacpd;
-+
-+ if (regmap_read(priv->syscon_regmap, offset->dsmpd, &reg_val))
-+ goto read_error;
-+ dsmpd = (reg_val & mask->dsmpd) >> shift->dsmpd;
-+
-+ if (regmap_read(priv->syscon_regmap, offset->fbdiv, &reg_val))
-+ goto read_error;
-+ fbdiv = (reg_val & mask->fbdiv) >> shift->fbdiv;
-+ /* fbdiv value should be 8 to 4095 */
-+ if (fbdiv < 8)
-+ goto read_error;
-+
-+ if (regmap_read(priv->syscon_regmap, offset->prediv, &reg_val))
-+ goto read_error;
-+ prediv = (reg_val & mask->prediv) >> shift->prediv;
-+
-+ if (regmap_read(priv->syscon_regmap, offset->postdiv1, &reg_val))
-+ goto read_error;
-+ /* postdiv1 = 2 ^ reg_val */
-+ postdiv1 = 1 << ((reg_val & mask->postdiv1) >> shift->postdiv1);
-+
-+ if (regmap_read(priv->syscon_regmap, offset->frac, &reg_val))
-+ goto read_error;
-+ frac = (reg_val & mask->frac) >> shift->frac;
-+
-+ /*
-+ * Integer Mode (Both 1) or Fraction Mode (Both 0).
-+ * And the decimal places are counted by expanding them by
-+ * a factor of STARFIVE_PLL_FRAC_PATR_SIZE.
-+ */
-+ if (dacpd == 1 && dsmpd == 1)
-+ frac_cal = 0;
-+ else if (dacpd == 0 && dsmpd == 0)
-+ frac_cal = (unsigned long)frac * STARFIVE_PLL_FRAC_PATR_SIZE / (1 << 24);
-+ else
-+ goto read_error;
-+
-+ /* Fvco = Fref * (NI + NF) / M / Q1 */
-+ freq = parent_rate / STARFIVE_PLL_FRAC_PATR_SIZE *
-+ (fbdiv * STARFIVE_PLL_FRAC_PATR_SIZE + frac_cal) / prediv / postdiv1;
-+
-+read_error:
-+ return freq;
-+}
-+
-+static unsigned long jh7110_pll_rate_sub_fabs(unsigned long rate1, unsigned long rate2)
-+{
-+ return rate1 > rate2 ? (rate1 - rate2) : (rate2 - rate1);
-+}
-+
-+/* Select the appropriate frequency from the already configured registers value */
-+static void jh7110_pll_select_near_freq_id(struct jh7110_clk_pll_data *data,
-+ unsigned long rate)
-+{
-+ const struct starfive_pll_syscon_value *syscon_val;
-+ unsigned int id;
-+ unsigned int pll_arry_size;
-+ unsigned long rate_diff;
-+
-+ if (data->idx == JH7110_CLK_PLL0_OUT)
-+ pll_arry_size = ARRAY_SIZE(jh7110_pll0_syscon_freq);
-+ else if (data->idx == JH7110_CLK_PLL1_OUT)
-+ pll_arry_size = ARRAY_SIZE(jh7110_pll1_syscon_freq);
-+ else
-+ pll_arry_size = ARRAY_SIZE(jh7110_pll2_syscon_freq);
-+
-+ /* compare the frequency one by one from small to large in order */
-+ for (id = 0; id < pll_arry_size; id++) {
-+ if (data->idx == JH7110_CLK_PLL0_OUT)
-+ syscon_val = &jh7110_pll0_syscon_freq[id];
-+ else if (data->idx == JH7110_CLK_PLL1_OUT)
-+ syscon_val = &jh7110_pll1_syscon_freq[id];
-+ else
-+ syscon_val = &jh7110_pll2_syscon_freq[id];
-+
-+ if (rate == syscon_val->freq)
-+ goto match_end;
-+
-+ /* select near frequency */
-+ if (rate < syscon_val->freq) {
-+ /* The last frequency is closer to the target rate than this time. */
-+ if (id > 0)
-+ if (rate_diff < jh7110_pll_rate_sub_fabs(rate, syscon_val->freq))
-+ id--;
-+
-+ goto match_end;
-+ } else {
-+ rate_diff = jh7110_pll_rate_sub_fabs(rate, syscon_val->freq);
-+ }
-+ }
-+
-+match_end:
-+ data->freq_select_idx = id;
-+}
-+
-+static int jh7110_pll_set_freq_syscon(struct jh7110_clk_pll_data *data)
-+{
-+ struct jh7110_clk_pll_priv *priv = jh7110_pll_priv_from(data);
-+ struct jh7110_pll_syscon_offset *offset = &data->offset;
-+ struct jh7110_pll_syscon_mask *mask = &data->mask;
-+ struct jh7110_pll_syscon_shift *shift = &data->shift;
-+ unsigned int freq_idx = data->freq_select_idx;
-+ const struct starfive_pll_syscon_value *syscon_val;
-+ int ret;
-+
-+ if (data->idx == JH7110_CLK_PLL0_OUT)
-+ syscon_val = &jh7110_pll0_syscon_freq[freq_idx];
-+ else if (data->idx == JH7110_CLK_PLL1_OUT)
-+ syscon_val = &jh7110_pll1_syscon_freq[freq_idx];
-+ else
-+ syscon_val = &jh7110_pll2_syscon_freq[freq_idx];
-+
-+ ret = regmap_update_bits(priv->syscon_regmap, offset->dacpd, mask->dacpd,
-+ (syscon_val->dacpd << shift->dacpd));
-+ if (ret)
-+ goto set_failed;
-+
-+ ret = regmap_update_bits(priv->syscon_regmap, offset->dsmpd, mask->dsmpd,
-+ (syscon_val->dsmpd << shift->dsmpd));
-+ if (ret)
-+ goto set_failed;
-+
-+ ret = regmap_update_bits(priv->syscon_regmap, offset->prediv, mask->prediv,
-+ (syscon_val->prediv << shift->prediv));
-+ if (ret)
-+ goto set_failed;
-+
-+ ret = regmap_update_bits(priv->syscon_regmap, offset->fbdiv, mask->fbdiv,
-+ (syscon_val->fbdiv << shift->fbdiv));
-+ if (ret)
-+ goto set_failed;
-+
-+ ret = regmap_update_bits(priv->syscon_regmap, offset->postdiv1, mask->postdiv1,
-+ ((syscon_val->postdiv1 >> 1) << shift->postdiv1));
-+ if (ret)
-+ goto set_failed;
-+
-+ /* frac: Integer Mode (Both 1) or Fraction Mode (Both 0) */
-+ if (syscon_val->dacpd == 0 && syscon_val->dsmpd == 0)
-+ ret = regmap_update_bits(priv->syscon_regmap, offset->frac, mask->frac,
-+ (syscon_val->frac << shift->frac));
-+ else if (syscon_val->dacpd != syscon_val->dsmpd)
-+ ret = -EINVAL;
-+
-+set_failed:
-+ return ret;
-+}
-+
-+static unsigned long jh7110_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
-+{
-+ struct jh7110_clk_pll_data *data = jh7110_pll_data_from(hw);
-+
-+ return jh7110_pll_get_freq(data, parent_rate);
-+}
-+
-+static int jh7110_pll_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)
-+{
-+ struct jh7110_clk_pll_data *data = jh7110_pll_data_from(hw);
-+
-+ jh7110_pll_select_near_freq_id(data, req->rate);
-+
-+ if (data->idx == JH7110_CLK_PLL0_OUT)
-+ req->rate = jh7110_pll0_syscon_freq[data->freq_select_idx].freq;
-+ else if (data->idx == JH7110_CLK_PLL1_OUT)
-+ req->rate = jh7110_pll1_syscon_freq[data->freq_select_idx].freq;
-+ else
-+ req->rate = jh7110_pll2_syscon_freq[data->freq_select_idx].freq;
-+
-+ return 0;
-+}
-+
-+static int jh7110_pll_set_rate(struct clk_hw *hw, unsigned long rate,
-+ unsigned long parent_rate)
-+{
-+ struct jh7110_clk_pll_data *data = jh7110_pll_data_from(hw);
-+
-+ return jh7110_pll_set_freq_syscon(data);
-+}
-+
-+#ifdef CONFIG_DEBUG_FS
-+static void jh7110_pll_debug_init(struct clk_hw *hw, struct dentry *dentry)
-+{
-+ static const struct debugfs_reg32 jh7110_clk_pll_reg = {
-+ .name = "CTRL",
-+ .offset = 0,
-+ };
-+ struct jh7110_clk_pll_data *data = jh7110_pll_data_from(hw);
-+ struct jh7110_clk_pll_priv *priv = jh7110_pll_priv_from(data);
-+ struct debugfs_regset32 *regset;
-+
-+ regset = devm_kzalloc(priv->dev, sizeof(*regset), GFP_KERNEL);
-+ if (!regset)
-+ return;
-+
-+ regset->regs = &jh7110_clk_pll_reg;
-+ regset->nregs = 1;
-+
-+ debugfs_create_regset32("registers", 0400, dentry, regset);
-+}
-+#else
-+#define jh7110_pll_debug_init NULL
-+#endif
-+
-+static const struct clk_ops jh7110_pll_ops = {
-+ .recalc_rate = jh7110_pll_recalc_rate,
-+ .determine_rate = jh7110_pll_determine_rate,
-+ .set_rate = jh7110_pll_set_rate,
-+ .debug_init = jh7110_pll_debug_init,
-+};
-+
-+/* get offset, mask and shift of PLL(x) syscon */
-+static int jh7110_pll_data_get(struct jh7110_clk_pll_data *data, int index)
-+{
-+ struct jh7110_pll_syscon_offset *offset = &data->offset;
-+ struct jh7110_pll_syscon_mask *mask = &data->mask;
-+ struct jh7110_pll_syscon_shift *shift = &data->shift;
-+
-+ if (index == JH7110_CLK_PLL0_OUT) {
-+ offset->dacpd = STARFIVE_JH7110_PLL0_DACPD_OFFSET;
-+ offset->dsmpd = STARFIVE_JH7110_PLL0_DSMPD_OFFSET;
-+ offset->fbdiv = STARFIVE_JH7110_PLL0_FBDIV_OFFSET;
-+ offset->frac = STARFIVE_JH7110_PLL0_FRAC_OFFSET;
-+ offset->prediv = STARFIVE_JH7110_PLL0_PREDIV_OFFSET;
-+ offset->postdiv1 = STARFIVE_JH7110_PLL0_POSTDIV1_OFFSET;
-+
-+ mask->dacpd = STARFIVE_JH7110_PLL0_DACPD_MASK;
-+ mask->dsmpd = STARFIVE_JH7110_PLL0_DSMPD_MASK;
-+ mask->fbdiv = STARFIVE_JH7110_PLL0_FBDIV_MASK;
-+ mask->frac = STARFIVE_JH7110_PLL0_FRAC_MASK;
-+ mask->prediv = STARFIVE_JH7110_PLL0_PREDIV_MASK;
-+ mask->postdiv1 = STARFIVE_JH7110_PLL0_POSTDIV1_MASK;
-+
-+ shift->dacpd = STARFIVE_JH7110_PLL0_DACPD_SHIFT;
-+ shift->dsmpd = STARFIVE_JH7110_PLL0_DSMPD_SHIFT;
-+ shift->fbdiv = STARFIVE_JH7110_PLL0_FBDIV_SHIFT;
-+ shift->frac = STARFIVE_JH7110_PLL0_FRAC_SHIFT;
-+ shift->prediv = STARFIVE_JH7110_PLL0_PREDIV_SHIFT;
-+ shift->postdiv1 = STARFIVE_JH7110_PLL0_POSTDIV1_SHIFT;
-+
-+ } else if (index == JH7110_CLK_PLL1_OUT) {
-+ offset->dacpd = STARFIVE_JH7110_PLL1_DACPD_OFFSET;
-+ offset->dsmpd = STARFIVE_JH7110_PLL1_DSMPD_OFFSET;
-+ offset->fbdiv = STARFIVE_JH7110_PLL1_FBDIV_OFFSET;
-+ offset->frac = STARFIVE_JH7110_PLL1_FRAC_OFFSET;
-+ offset->prediv = STARFIVE_JH7110_PLL1_PREDIV_OFFSET;
-+ offset->postdiv1 = STARFIVE_JH7110_PLL1_POSTDIV1_OFFSET;
-+
-+ mask->dacpd = STARFIVE_JH7110_PLL1_DACPD_MASK;
-+ mask->dsmpd = STARFIVE_JH7110_PLL1_DSMPD_MASK;
-+ mask->fbdiv = STARFIVE_JH7110_PLL1_FBDIV_MASK;
-+ mask->frac = STARFIVE_JH7110_PLL1_FRAC_MASK;
-+ mask->prediv = STARFIVE_JH7110_PLL1_PREDIV_MASK;
-+ mask->postdiv1 = STARFIVE_JH7110_PLL1_POSTDIV1_MASK;
-+
-+ shift->dacpd = STARFIVE_JH7110_PLL1_DACPD_SHIFT;
-+ shift->dsmpd = STARFIVE_JH7110_PLL1_DSMPD_SHIFT;
-+ shift->fbdiv = STARFIVE_JH7110_PLL1_FBDIV_SHIFT;
-+ shift->frac = STARFIVE_JH7110_PLL1_FRAC_SHIFT;
-+ shift->prediv = STARFIVE_JH7110_PLL1_PREDIV_SHIFT;
-+ shift->postdiv1 = STARFIVE_JH7110_PLL1_POSTDIV1_SHIFT;
-+
-+ } else if (index == JH7110_CLK_PLL2_OUT) {
-+ offset->dacpd = STARFIVE_JH7110_PLL2_DACPD_OFFSET;
-+ offset->dsmpd = STARFIVE_JH7110_PLL2_DSMPD_OFFSET;
-+ offset->fbdiv = STARFIVE_JH7110_PLL2_FBDIV_OFFSET;
-+ offset->frac = STARFIVE_JH7110_PLL2_FRAC_OFFSET;
-+ offset->prediv = STARFIVE_JH7110_PLL2_PREDIV_OFFSET;
-+ offset->postdiv1 = STARFIVE_JH7110_PLL2_POSTDIV1_OFFSET;
-+
-+ mask->dacpd = STARFIVE_JH7110_PLL2_DACPD_MASK;
-+ mask->dsmpd = STARFIVE_JH7110_PLL2_DSMPD_MASK;
-+ mask->fbdiv = STARFIVE_JH7110_PLL2_FBDIV_MASK;
-+ mask->frac = STARFIVE_JH7110_PLL2_FRAC_MASK;
-+ mask->prediv = STARFIVE_JH7110_PLL2_PREDIV_MASK;
-+ mask->postdiv1 = STARFIVE_JH7110_PLL2_POSTDIV1_MASK;
-+
-+ shift->dacpd = STARFIVE_JH7110_PLL2_DACPD_SHIFT;
-+ shift->dsmpd = STARFIVE_JH7110_PLL2_DSMPD_SHIFT;
-+ shift->fbdiv = STARFIVE_JH7110_PLL2_FBDIV_SHIFT;
-+ shift->frac = STARFIVE_JH7110_PLL2_FRAC_SHIFT;
-+ shift->prediv = STARFIVE_JH7110_PLL2_PREDIV_SHIFT;
-+ shift->postdiv1 = STARFIVE_JH7110_PLL2_POSTDIV1_SHIFT;
-+
-+ } else {
-+ return -ENOENT;
-+ }
-+
-+ return 0;
-+}
-+
-+static struct clk_hw *jh7110_pll_get(struct of_phandle_args *clkspec, void *data)
-+{
-+ struct jh7110_clk_pll_priv *priv = data;
-+ unsigned int idx = clkspec->args[0];
-+
-+ if (idx < JH7110_PLLCLK_END)
-+ return &priv->data[idx].hw;
-+
-+ return ERR_PTR(-EINVAL);
-+}
-+
-+static int jh7110_pll_probe(struct platform_device *pdev)
-+{
-+ const char *pll_name[JH7110_PLLCLK_END] = {
-+ "pll0_out",
-+ "pll1_out",
-+ "pll2_out"
-+ };
-+ struct jh7110_clk_pll_priv *priv;
-+ struct jh7110_clk_pll_data *data;
-+ int ret;
-+ unsigned int idx;
-+
-+ priv = devm_kzalloc(&pdev->dev, struct_size(priv, data, JH7110_PLLCLK_END),
-+ GFP_KERNEL);
-+ if (!priv)
-+ return -ENOMEM;
-+
-+ priv->dev = &pdev->dev;
-+ priv->syscon_regmap = syscon_node_to_regmap(priv->dev->of_node->parent);
-+ if (IS_ERR(priv->syscon_regmap))
-+ return PTR_ERR(priv->syscon_regmap);
-+
-+ for (idx = 0; idx < JH7110_PLLCLK_END; idx++) {
-+ struct clk_parent_data parents = {
-+ .index = 0,
-+ };
-+ struct clk_init_data init = {
-+ .name = pll_name[idx],
-+ .ops = &jh7110_pll_ops,
-+ .parent_data = &parents,
-+ .num_parents = 1,
-+ .flags = 0,
-+ };
-+
-+ data = &priv->data[idx];
-+
-+ ret = jh7110_pll_data_get(data, idx);
-+ if (ret)
-+ return ret;
-+
-+ data->hw.init = &init;
-+ data->idx = idx;
-+
-+ ret = devm_clk_hw_register(&pdev->dev, &data->hw);
-+ if (ret)
-+ return ret;
-+ }
-+
-+ return devm_of_clk_add_hw_provider(&pdev->dev, jh7110_pll_get, priv);
-+}
-+
-+static const struct of_device_id jh7110_pll_match[] = {
-+ { .compatible = "starfive,jh7110-pll" },
-+ { /* sentinel */ }
-+};
-+MODULE_DEVICE_TABLE(of, jh7110_pll_match);
-+
-+static struct platform_driver jh7110_pll_driver = {
-+ .driver = {
-+ .name = "clk-starfive-jh7110-pll",
-+ .of_match_table = jh7110_pll_match,
-+ },
-+};
-+builtin_platform_driver_probe(jh7110_pll_driver, jh7110_pll_probe);
---- /dev/null
-+++ b/drivers/clk/starfive/clk-starfive-jh7110-pll.h
-@@ -0,0 +1,293 @@
-+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
-+/*
-+ * StarFive JH7110 PLL Clock Generator Driver
-+ *
-+ * Copyright (C) 2023 StarFive Technology Co., Ltd.
-+ */
-+
-+#ifndef _CLK_STARFIVE_JH7110_PLL_H_
-+#define _CLK_STARFIVE_JH7110_PLL_H_
-+
-+#include <linux/bits.h>
-+
-+/* The decimal places are counted by expanding them by a factor of STARFIVE_PLL_FRAC_PATR_SIZE */
-+#define STARFIVE_PLL_FRAC_PATR_SIZE 1000
-+
-+#define STARFIVE_JH7110_PLL0_DACPD_OFFSET 0x18
-+#define STARFIVE_JH7110_PLL0_DACPD_SHIFT 24
-+#define STARFIVE_JH7110_PLL0_DACPD_MASK BIT(24)
-+#define STARFIVE_JH7110_PLL0_DSMPD_OFFSET 0x18
-+#define STARFIVE_JH7110_PLL0_DSMPD_SHIFT 25
-+#define STARFIVE_JH7110_PLL0_DSMPD_MASK BIT(25)
-+#define STARFIVE_JH7110_PLL0_FBDIV_OFFSET 0x1c
-+#define STARFIVE_JH7110_PLL0_FBDIV_SHIFT 0
-+#define STARFIVE_JH7110_PLL0_FBDIV_MASK GENMASK(11, 0)
-+#define STARFIVE_JH7110_PLL0_FRAC_OFFSET 0x20
-+#define STARFIVE_JH7110_PLL0_FRAC_SHIFT 0
-+#define STARFIVE_JH7110_PLL0_FRAC_MASK GENMASK(23, 0)
-+#define STARFIVE_JH7110_PLL0_POSTDIV1_OFFSET 0x20
-+#define STARFIVE_JH7110_PLL0_POSTDIV1_SHIFT 28
-+#define STARFIVE_JH7110_PLL0_POSTDIV1_MASK GENMASK(29, 28)
-+#define STARFIVE_JH7110_PLL0_PREDIV_OFFSET 0x24
-+#define STARFIVE_JH7110_PLL0_PREDIV_SHIFT 0
-+#define STARFIVE_JH7110_PLL0_PREDIV_MASK GENMASK(5, 0)
-+
-+#define STARFIVE_JH7110_PLL1_DACPD_OFFSET 0x24
-+#define STARFIVE_JH7110_PLL1_DACPD_SHIFT 15
-+#define STARFIVE_JH7110_PLL1_DACPD_MASK BIT(15)
-+#define STARFIVE_JH7110_PLL1_DSMPD_OFFSET 0x24
-+#define STARFIVE_JH7110_PLL1_DSMPD_SHIFT 16
-+#define STARFIVE_JH7110_PLL1_DSMPD_MASK BIT(16)
-+#define STARFIVE_JH7110_PLL1_FBDIV_OFFSET 0x24
-+#define STARFIVE_JH7110_PLL1_FBDIV_SHIFT 17
-+#define STARFIVE_JH7110_PLL1_FBDIV_MASK GENMASK(28, 17)
-+#define STARFIVE_JH7110_PLL1_FRAC_OFFSET 0x28
-+#define STARFIVE_JH7110_PLL1_FRAC_SHIFT 0
-+#define STARFIVE_JH7110_PLL1_FRAC_MASK GENMASK(23, 0)
-+#define STARFIVE_JH7110_PLL1_POSTDIV1_OFFSET 0x28
-+#define STARFIVE_JH7110_PLL1_POSTDIV1_SHIFT 28
-+#define STARFIVE_JH7110_PLL1_POSTDIV1_MASK GENMASK(29, 28)
-+#define STARFIVE_JH7110_PLL1_PREDIV_OFFSET 0x2c
-+#define STARFIVE_JH7110_PLL1_PREDIV_SHIFT 0
-+#define STARFIVE_JH7110_PLL1_PREDIV_MASK GENMASK(5, 0)
-+
-+#define STARFIVE_JH7110_PLL2_DACPD_OFFSET 0x2c
-+#define STARFIVE_JH7110_PLL2_DACPD_SHIFT 15
-+#define STARFIVE_JH7110_PLL2_DACPD_MASK BIT(15)
-+#define STARFIVE_JH7110_PLL2_DSMPD_OFFSET 0x2c
-+#define STARFIVE_JH7110_PLL2_DSMPD_SHIFT 16
-+#define STARFIVE_JH7110_PLL2_DSMPD_MASK BIT(16)
-+#define STARFIVE_JH7110_PLL2_FBDIV_OFFSET 0x2c
-+#define STARFIVE_JH7110_PLL2_FBDIV_SHIFT 17
-+#define STARFIVE_JH7110_PLL2_FBDIV_MASK GENMASK(28, 17)
-+#define STARFIVE_JH7110_PLL2_FRAC_OFFSET 0x30
-+#define STARFIVE_JH7110_PLL2_FRAC_SHIFT 0
-+#define STARFIVE_JH7110_PLL2_FRAC_MASK GENMASK(23, 0)
-+#define STARFIVE_JH7110_PLL2_POSTDIV1_OFFSET 0x30
-+#define STARFIVE_JH7110_PLL2_POSTDIV1_SHIFT 28
-+#define STARFIVE_JH7110_PLL2_POSTDIV1_MASK GENMASK(29, 28)
-+#define STARFIVE_JH7110_PLL2_PREDIV_OFFSET 0x34
-+#define STARFIVE_JH7110_PLL2_PREDIV_SHIFT 0
-+#define STARFIVE_JH7110_PLL2_PREDIV_MASK GENMASK(5, 0)
-+
-+struct jh7110_pll_syscon_offset {
-+ unsigned int dacpd;
-+ unsigned int dsmpd;
-+ unsigned int fbdiv;
-+ unsigned int frac;
-+ unsigned int prediv;
-+ unsigned int postdiv1;
-+};
-+
-+struct jh7110_pll_syscon_mask {
-+ u32 dacpd;
-+ u32 dsmpd;
-+ u32 fbdiv;
-+ u32 frac;
-+ u32 prediv;
-+ u32 postdiv1;
-+};
-+
-+struct jh7110_pll_syscon_shift {
-+ char dacpd;
-+ char dsmpd;
-+ char fbdiv;
-+ char frac;
-+ char prediv;
-+ char postdiv1;
-+};
-+
-+struct jh7110_clk_pll_data {
-+ struct clk_hw hw;
-+ unsigned int idx;
-+ unsigned int freq_select_idx;
-+
-+ struct jh7110_pll_syscon_offset offset;
-+ struct jh7110_pll_syscon_mask mask;
-+ struct jh7110_pll_syscon_shift shift;
-+};
-+
-+struct jh7110_clk_pll_priv {
-+ struct device *dev;
-+ struct regmap *syscon_regmap;
-+ struct jh7110_clk_pll_data data[];
-+};
-+
-+struct starfive_pll_syscon_value {
-+ unsigned long freq;
-+ u32 prediv;
-+ u32 fbdiv;
-+ u32 postdiv1;
-+/* Both daxpd and dsmpd set 1 while integer mode */
-+/* Both daxpd and dsmpd set 0 while fraction mode */
-+ u32 dacpd;
-+ u32 dsmpd;
-+/* frac value should be decimals multiplied by 2^24 */
-+ u32 frac;
-+};
-+
-+enum starfive_pll0_freq_index {
-+ PLL0_FREQ_375 = 0,
-+ PLL0_FREQ_500,
-+ PLL0_FREQ_625,
-+ PLL0_FREQ_750,
-+ PLL0_FREQ_875,
-+ PLL0_FREQ_1000,
-+ PLL0_FREQ_1250,
-+ PLL0_FREQ_1375,
-+ PLL0_FREQ_1500,
-+ PLL0_FREQ_MAX
-+};
-+
-+enum starfive_pll1_freq_index {
-+ PLL1_FREQ_1066 = 0,
-+ PLL1_FREQ_1200,
-+ PLL1_FREQ_1400,
-+ PLL1_FREQ_1600,
-+ PLL1_FREQ_MAX
-+};
-+
-+enum starfive_pll2_freq_index {
-+ PLL2_FREQ_1188 = 0,
-+ PLL2_FREQ_12288,
-+ PLL2_FREQ_MAX
-+};
-+
-+/*
-+ * Because the pll frequency is relatively fixed,
-+ * it cannot be set arbitrarily, so it needs a specific configuration.
-+ * PLL0 frequency should be multiple of 125MHz (USB frequency).
-+ */
-+static const struct starfive_pll_syscon_value
-+ jh7110_pll0_syscon_freq[PLL0_FREQ_MAX] = {
-+ [PLL0_FREQ_375] = {
-+ .freq = 375000000,
-+ .prediv = 8,
-+ .fbdiv = 125,
-+ .postdiv1 = 1,
-+ .dacpd = 1,
-+ .dsmpd = 1,
-+ },
-+ [PLL0_FREQ_500] = {
-+ .freq = 500000000,
-+ .prediv = 6,
-+ .fbdiv = 125,
-+ .postdiv1 = 1,
-+ .dacpd = 1,
-+ .dsmpd = 1,
-+ },
-+ [PLL0_FREQ_625] = {
-+ .freq = 625000000,
-+ .prediv = 24,
-+ .fbdiv = 625,
-+ .postdiv1 = 1,
-+ .dacpd = 1,
-+ .dsmpd = 1,
-+ },
-+ [PLL0_FREQ_750] = {
-+ .freq = 750000000,
-+ .prediv = 4,
-+ .fbdiv = 125,
-+ .postdiv1 = 1,
-+ .dacpd = 1,
-+ .dsmpd = 1,
-+ },
-+ [PLL0_FREQ_875] = {
-+ .freq = 875000000,
-+ .prediv = 24,
-+ .fbdiv = 875,
-+ .postdiv1 = 1,
-+ .dacpd = 1,
-+ .dsmpd = 1,
-+ },
-+ [PLL0_FREQ_1000] = {
-+ .freq = 1000000000,
-+ .prediv = 3,
-+ .fbdiv = 125,
-+ .postdiv1 = 1,
-+ .dacpd = 1,
-+ .dsmpd = 1,
-+ },
-+ [PLL0_FREQ_1250] = {
-+ .freq = 1250000000,
-+ .prediv = 12,
-+ .fbdiv = 625,
-+ .postdiv1 = 1,
-+ .dacpd = 1,
-+ .dsmpd = 1,
-+ },
-+ [PLL0_FREQ_1375] = {
-+ .freq = 1375000000,
-+ .prediv = 24,
-+ .fbdiv = 1375,
-+ .postdiv1 = 1,
-+ .dacpd = 1,
-+ .dsmpd = 1,
-+ },
-+ [PLL0_FREQ_1500] = {
-+ .freq = 1500000000,
-+ .prediv = 2,
-+ .fbdiv = 125,
-+ .postdiv1 = 1,
-+ .dacpd = 1,
-+ .dsmpd = 1,
-+ },
-+};
-+
-+static const struct starfive_pll_syscon_value
-+ jh7110_pll1_syscon_freq[PLL1_FREQ_MAX] = {
-+ [PLL1_FREQ_1066] = {
-+ .freq = 1066000000,
-+ .prediv = 12,
-+ .fbdiv = 533,
-+ .postdiv1 = 1,
-+ .dacpd = 1,
-+ .dsmpd = 1,
-+ },
-+ [PLL1_FREQ_1200] = {
-+ .freq = 1200000000,
-+ .prediv = 1,
-+ .fbdiv = 50,
-+ .postdiv1 = 1,
-+ .dacpd = 1,
-+ .dsmpd = 1,
-+ },
-+ [PLL1_FREQ_1400] = {
-+ .freq = 1400000000,
-+ .prediv = 6,
-+ .fbdiv = 350,
-+ .postdiv1 = 1,
-+ .dacpd = 1,
-+ .dsmpd = 1,
-+ },
-+ [PLL1_FREQ_1600] = {
-+ .freq = 1600000000,
-+ .prediv = 3,
-+ .fbdiv = 200,
-+ .postdiv1 = 1,
-+ .dacpd = 1,
-+ .dsmpd = 1,
-+ },
-+};
-+
-+static const struct starfive_pll_syscon_value
-+ jh7110_pll2_syscon_freq[PLL2_FREQ_MAX] = {
-+ [PLL2_FREQ_1188] = {
-+ .freq = 1188000000,
-+ .prediv = 2,
-+ .fbdiv = 99,
-+ .postdiv1 = 1,
-+ .dacpd = 1,
-+ .dsmpd = 1,
-+ },
-+ [PLL2_FREQ_12288] = {
-+ .freq = 1228800000,
-+ .prediv = 5,
-+ .fbdiv = 256,
-+ .postdiv1 = 1,
-+ .dacpd = 1,
-+ .dsmpd = 1,
-+ },
-+};
-+
-+#endif
diff --git a/target/linux/starfive/patches-6.1/0033-dt-bindings-clock-jh7110-syscrg-Add-PLL-clock-inputs.patch b/target/linux/starfive/patches-6.1/0033-dt-bindings-clock-jh7110-syscrg-Add-PLL-clock-inputs.patch
deleted file mode 100644
index 4fd78cd5bb..0000000000
--- a/target/linux/starfive/patches-6.1/0033-dt-bindings-clock-jh7110-syscrg-Add-PLL-clock-inputs.patch
+++ /dev/null
@@ -1,75 +0,0 @@
-From 1f788a0a5092b1e1cfd02aa7f31ceb551befa7e6 Mon Sep 17 00:00:00 2001
-From: Xingyu Wu <xingyu.wu@starfivetech.com>
-Date: Tue, 14 Mar 2023 16:43:50 +0800
-Subject: [PATCH 033/122] dt-bindings: clock: jh7110-syscrg: Add PLL clock
- inputs
-
-Add PLL clock inputs from PLL clock generator.
-
-Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
----
- .../clock/starfive,jh7110-syscrg.yaml | 20 +++++++++++++++++--
- 1 file changed, 18 insertions(+), 2 deletions(-)
-
---- a/Documentation/devicetree/bindings/clock/starfive,jh7110-syscrg.yaml
-+++ b/Documentation/devicetree/bindings/clock/starfive,jh7110-syscrg.yaml
-@@ -27,6 +27,9 @@ properties:
- - description: External I2S RX left/right channel clock
- - description: External TDM clock
- - description: External audio master clock
-+ - description: PLL0
-+ - description: PLL1
-+ - description: PLL2
-
- - items:
- - description: Main Oscillator (24 MHz)
-@@ -38,6 +41,9 @@ properties:
- - description: External I2S RX left/right channel clock
- - description: External TDM clock
- - description: External audio master clock
-+ - description: PLL0
-+ - description: PLL1
-+ - description: PLL2
-
- clock-names:
- oneOf:
-@@ -52,6 +58,9 @@ properties:
- - const: i2srx_lrck_ext
- - const: tdm_ext
- - const: mclk_ext
-+ - const: pll0_out
-+ - const: pll1_out
-+ - const: pll2_out
-
- - items:
- - const: osc
-@@ -63,6 +72,9 @@ properties:
- - const: i2srx_lrck_ext
- - const: tdm_ext
- - const: mclk_ext
-+ - const: pll0_out
-+ - const: pll1_out
-+ - const: pll2_out
-
- '#clock-cells':
- const: 1
-@@ -93,12 +105,16 @@ examples:
- <&gmac1_rgmii_rxin>,
- <&i2stx_bclk_ext>, <&i2stx_lrck_ext>,
- <&i2srx_bclk_ext>, <&i2srx_lrck_ext>,
-- <&tdm_ext>, <&mclk_ext>;
-+ <&tdm_ext>, <&mclk_ext>,
-+ <&pllclk JH7110_CLK_PLL0_OUT>,
-+ <&pllclk JH7110_CLK_PLL1_OUT>,
-+ <&pllclk JH7110_CLK_PLL2_OUT>;
- clock-names = "osc", "gmac1_rmii_refin",
- "gmac1_rgmii_rxin",
- "i2stx_bclk_ext", "i2stx_lrck_ext",
- "i2srx_bclk_ext", "i2srx_lrck_ext",
-- "tdm_ext", "mclk_ext";
-+ "tdm_ext", "mclk_ext",
-+ "pll0_out", "pll1_out", "pll2_out";
- #clock-cells = <1>;
- #reset-cells = <1>;
- };
diff --git a/target/linux/starfive/patches-6.1/0034-clk-starfive-jh7110-sys-Modify-PLL-clocks-source.patch b/target/linux/starfive/patches-6.1/0034-clk-starfive-jh7110-sys-Modify-PLL-clocks-source.patch
deleted file mode 100644
index 3e6237681f..0000000000
--- a/target/linux/starfive/patches-6.1/0034-clk-starfive-jh7110-sys-Modify-PLL-clocks-source.patch
+++ /dev/null
@@ -1,71 +0,0 @@
-From ffd7ee4fbd69d477a2156d9cba6ae80434a4c894 Mon Sep 17 00:00:00 2001
-From: Xingyu Wu <xingyu.wu@starfivetech.com>
-Date: Tue, 14 Mar 2023 17:16:07 +0800
-Subject: [PATCH 034/122] clk: starfive: jh7110-sys: Modify PLL clocks source
-
-Modify PLL clocks source to be got from dts instead of
-the fixed factor clocks.
-
-Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
----
- drivers/clk/starfive/Kconfig | 1 +
- .../clk/starfive/clk-starfive-jh7110-sys.c | 31 ++++---------------
- 2 files changed, 7 insertions(+), 25 deletions(-)
-
---- a/drivers/clk/starfive/Kconfig
-+++ b/drivers/clk/starfive/Kconfig
-@@ -35,6 +35,7 @@ config CLK_STARFIVE_JH7110_SYS
- select AUXILIARY_BUS
- select CLK_STARFIVE_JH71X0
- select RESET_STARFIVE_JH7110
-+ select CLK_STARFIVE_JH7110_PLL
- default ARCH_STARFIVE
- help
- Say yes here to support the system clock controller on the
---- a/drivers/clk/starfive/clk-starfive-jh7110-sys.c
-+++ b/drivers/clk/starfive/clk-starfive-jh7110-sys.c
-@@ -404,29 +404,6 @@ static int __init jh7110_syscrg_probe(st
-
- dev_set_drvdata(priv->dev, (void *)(&priv->base));
-
-- /*
-- * These PLL clocks are not actually fixed factor clocks and can be
-- * controlled by the syscon registers of JH7110. They will be dropped
-- * and registered in the PLL clock driver instead.
-- */
-- /* 24MHz -> 1000.0MHz */
-- priv->pll[0] = devm_clk_hw_register_fixed_factor(priv->dev, "pll0_out",
-- "osc", 0, 125, 3);
-- if (IS_ERR(priv->pll[0]))
-- return PTR_ERR(priv->pll[0]);
--
-- /* 24MHz -> 1066.0MHz */
-- priv->pll[1] = devm_clk_hw_register_fixed_factor(priv->dev, "pll1_out",
-- "osc", 0, 533, 12);
-- if (IS_ERR(priv->pll[1]))
-- return PTR_ERR(priv->pll[1]);
--
-- /* 24MHz -> 1188.0MHz */
-- priv->pll[2] = devm_clk_hw_register_fixed_factor(priv->dev, "pll2_out",
-- "osc", 0, 99, 2);
-- if (IS_ERR(priv->pll[2]))
-- return PTR_ERR(priv->pll[2]);
--
- for (idx = 0; idx < JH7110_SYSCLK_END; idx++) {
- u32 max = jh7110_sysclk_data[idx].max;
- struct clk_parent_data parents[4] = {};
-@@ -464,8 +441,12 @@ static int __init jh7110_syscrg_probe(st
- parents[i].fw_name = "tdm_ext";
- else if (pidx == JH7110_SYSCLK_MCLK_EXT)
- parents[i].fw_name = "mclk_ext";
-- else
-- parents[i].hw = priv->pll[pidx - JH7110_SYSCLK_PLL0_OUT];
-+ else if (pidx == JH7110_SYSCLK_PLL0_OUT)
-+ parents[i].fw_name = "pll0_out";
-+ else if (pidx == JH7110_SYSCLK_PLL1_OUT)
-+ parents[i].fw_name = "pll1_out";
-+ else if (pidx == JH7110_SYSCLK_PLL2_OUT)
-+ parents[i].fw_name = "pll2_out";
- }
-
- clk->hw.init = &init;
diff --git a/target/linux/starfive/patches-6.1/0035-dt-bindings-power-Add-starfive-jh7110-pmu.patch b/target/linux/starfive/patches-6.1/0035-dt-bindings-power-Add-starfive-jh7110-pmu.patch
deleted file mode 100644
index cf5fc7cbba..0000000000
--- a/target/linux/starfive/patches-6.1/0035-dt-bindings-power-Add-starfive-jh7110-pmu.patch
+++ /dev/null
@@ -1,86 +0,0 @@
-From 35bc6491a7b24872155a616f7770d3a5d6e40344 Mon Sep 17 00:00:00 2001
-From: Walker Chen <walker.chen@starfivetech.com>
-Date: Thu, 19 Jan 2023 17:44:46 +0800
-Subject: [PATCH 035/122] dt-bindings: power: Add starfive,jh7110-pmu
-
-Add bindings for the Power Management Unit on the StarFive JH7110 SoC.
-
-Signed-off-by: Walker Chen <walker.chen@starfivetech.com>
-Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
-Reviewed-by: Heiko Stuebner <heiko@sntech.de>
----
- .../bindings/power/starfive,jh7110-pmu.yaml | 45 +++++++++++++++++++
- .../dt-bindings/power/starfive,jh7110-pmu.h | 17 +++++++
- 2 files changed, 62 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/power/starfive,jh7110-pmu.yaml
- create mode 100644 include/dt-bindings/power/starfive,jh7110-pmu.h
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/power/starfive,jh7110-pmu.yaml
-@@ -0,0 +1,45 @@
-+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/power/starfive,jh7110-pmu.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: StarFive JH7110 Power Management Unit
-+
-+maintainers:
-+ - Walker Chen <walker.chen@starfivetech.com>
-+
-+description: |
-+ StarFive JH7110 SoC includes support for multiple power domains which can be
-+ powered on/off by software based on different application scenes to save power.
-+
-+properties:
-+ compatible:
-+ enum:
-+ - starfive,jh7110-pmu
-+
-+ reg:
-+ maxItems: 1
-+
-+ interrupts:
-+ maxItems: 1
-+
-+ "#power-domain-cells":
-+ const: 1
-+
-+required:
-+ - compatible
-+ - reg
-+ - interrupts
-+ - "#power-domain-cells"
-+
-+additionalProperties: false
-+
-+examples:
-+ - |
-+ pwrc: power-controller@17030000 {
-+ compatible = "starfive,jh7110-pmu";
-+ reg = <0x17030000 0x10000>;
-+ interrupts = <111>;
-+ #power-domain-cells = <1>;
-+ };
---- /dev/null
-+++ b/include/dt-bindings/power/starfive,jh7110-pmu.h
-@@ -0,0 +1,17 @@
-+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
-+/*
-+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
-+ * Author: Walker Chen <walker.chen@starfivetech.com>
-+ */
-+#ifndef __DT_BINDINGS_POWER_JH7110_POWER_H__
-+#define __DT_BINDINGS_POWER_JH7110_POWER_H__
-+
-+#define JH7110_PD_SYSTOP 0
-+#define JH7110_PD_CPU 1
-+#define JH7110_PD_GPUA 2
-+#define JH7110_PD_VDEC 3
-+#define JH7110_PD_VOUT 4
-+#define JH7110_PD_ISP 5
-+#define JH7110_PD_VENC 6
-+
-+#endif
diff --git a/target/linux/starfive/patches-6.1/0036-soc-starfive-Add-StarFive-JH71XX-pmu-driver.patch b/target/linux/starfive/patches-6.1/0036-soc-starfive-Add-StarFive-JH71XX-pmu-driver.patch
deleted file mode 100644
index 81c7548aa0..0000000000
--- a/target/linux/starfive/patches-6.1/0036-soc-starfive-Add-StarFive-JH71XX-pmu-driver.patch
+++ /dev/null
@@ -1,478 +0,0 @@
-From 3e3b85a1064b07a5107504af1e8f0a42ff9d1fc1 Mon Sep 17 00:00:00 2001
-From: Walker Chen <walker.chen@starfivetech.com>
-Date: Thu, 19 Jan 2023 17:44:47 +0800
-Subject: [PATCH 036/122] soc: starfive: Add StarFive JH71XX pmu driver
-
-Add pmu driver for the StarFive JH71XX SoC.
-
-As the power domains provider, the Power Management Unit (PMU) is
-designed for including multiple PM domains that can be used for power
-gating of selected IP blocks for power saving by reduced leakage
-current. It accepts software encourage command to switch the power mode
-of SoC.
-
-Signed-off-by: Walker Chen <walker.chen@starfivetech.com>
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
-Reviewed-by: Heiko Stuebner <heiko@sntech.de>
----
- MAINTAINERS | 14 ++
- drivers/soc/Kconfig | 1 +
- drivers/soc/Makefile | 1 +
- drivers/soc/starfive/Kconfig | 12 +
- drivers/soc/starfive/Makefile | 3 +
- drivers/soc/starfive/jh71xx_pmu.c | 383 ++++++++++++++++++++++++++++++
- 6 files changed, 414 insertions(+)
- create mode 100644 drivers/soc/starfive/Kconfig
- create mode 100644 drivers/soc/starfive/Makefile
- create mode 100644 drivers/soc/starfive/jh71xx_pmu.c
-
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -19689,6 +19689,20 @@ F: Documentation/devicetree/bindings/res
- F: drivers/reset/starfive/reset-starfive-jh71*
- F: include/dt-bindings/reset/starfive?jh71*.h
-
-+STARFIVE SOC DRIVER
-+M: Conor Dooley <conor@kernel.org>
-+S: Maintained
-+T: git https://git.kernel.org/pub/scm/linux/kernel/git/conor/linux.git/
-+F: drivers/soc/starfive/
-+F: include/soc/starfive/
-+
-+STARFIVE JH71XX PMU CONTROLLER DRIVER
-+M: Walker Chen <walker.chen@starfivetech.com>
-+S: Supported
-+F: Documentation/devicetree/bindings/power/starfive*
-+F: drivers/soc/starfive/jh71xx_pmu.c
-+F: include/dt-bindings/power/starfive,jh7110-pmu.h
-+
- STATIC BRANCH/CALL
- M: Peter Zijlstra <peterz@infradead.org>
- M: Josh Poimboeuf <jpoimboe@kernel.org>
---- a/drivers/soc/Kconfig
-+++ b/drivers/soc/Kconfig
-@@ -21,6 +21,7 @@ source "drivers/soc/renesas/Kconfig"
- source "drivers/soc/rockchip/Kconfig"
- source "drivers/soc/samsung/Kconfig"
- source "drivers/soc/sifive/Kconfig"
-+source "drivers/soc/starfive/Kconfig"
- source "drivers/soc/sunxi/Kconfig"
- source "drivers/soc/tegra/Kconfig"
- source "drivers/soc/ti/Kconfig"
---- a/drivers/soc/Makefile
-+++ b/drivers/soc/Makefile
-@@ -27,6 +27,7 @@ obj-y += renesas/
- obj-y += rockchip/
- obj-$(CONFIG_SOC_SAMSUNG) += samsung/
- obj-$(CONFIG_SOC_SIFIVE) += sifive/
-+obj-$(CONFIG_SOC_STARFIVE) += starfive/
- obj-y += sunxi/
- obj-$(CONFIG_ARCH_TEGRA) += tegra/
- obj-y += ti/
---- /dev/null
-+++ b/drivers/soc/starfive/Kconfig
-@@ -0,0 +1,12 @@
-+# SPDX-License-Identifier: GPL-2.0
-+
-+config JH71XX_PMU
-+ bool "Support PMU for StarFive JH71XX Soc"
-+ depends on PM
-+ depends on SOC_STARFIVE || COMPILE_TEST
-+ default SOC_STARFIVE
-+ select PM_GENERIC_DOMAINS
-+ help
-+ Say 'y' here to enable support power domain support.
-+ In order to meet low power requirements, a Power Management Unit (PMU)
-+ is designed for controlling power resources in StarFive JH71XX SoCs.
---- /dev/null
-+++ b/drivers/soc/starfive/Makefile
-@@ -0,0 +1,3 @@
-+# SPDX-License-Identifier: GPL-2.0
-+
-+obj-$(CONFIG_JH71XX_PMU) += jh71xx_pmu.o
---- /dev/null
-+++ b/drivers/soc/starfive/jh71xx_pmu.c
-@@ -0,0 +1,383 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later
-+/*
-+ * StarFive JH71XX PMU (Power Management Unit) Controller Driver
-+ *
-+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
-+ */
-+
-+#include <linux/interrupt.h>
-+#include <linux/io.h>
-+#include <linux/iopoll.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/of_device.h>
-+#include <linux/platform_device.h>
-+#include <linux/pm_domain.h>
-+#include <dt-bindings/power/starfive,jh7110-pmu.h>
-+
-+/* register offset */
-+#define JH71XX_PMU_SW_TURN_ON_POWER 0x0C
-+#define JH71XX_PMU_SW_TURN_OFF_POWER 0x10
-+#define JH71XX_PMU_SW_ENCOURAGE 0x44
-+#define JH71XX_PMU_TIMER_INT_MASK 0x48
-+#define JH71XX_PMU_CURR_POWER_MODE 0x80
-+#define JH71XX_PMU_EVENT_STATUS 0x88
-+#define JH71XX_PMU_INT_STATUS 0x8C
-+
-+/* sw encourage cfg */
-+#define JH71XX_PMU_SW_ENCOURAGE_EN_LO 0x05
-+#define JH71XX_PMU_SW_ENCOURAGE_EN_HI 0x50
-+#define JH71XX_PMU_SW_ENCOURAGE_DIS_LO 0x0A
-+#define JH71XX_PMU_SW_ENCOURAGE_DIS_HI 0xA0
-+#define JH71XX_PMU_SW_ENCOURAGE_ON 0xFF
-+
-+/* pmu int status */
-+#define JH71XX_PMU_INT_SEQ_DONE BIT(0)
-+#define JH71XX_PMU_INT_HW_REQ BIT(1)
-+#define JH71XX_PMU_INT_SW_FAIL GENMASK(3, 2)
-+#define JH71XX_PMU_INT_HW_FAIL GENMASK(5, 4)
-+#define JH71XX_PMU_INT_PCH_FAIL GENMASK(8, 6)
-+#define JH71XX_PMU_INT_ALL_MASK GENMASK(8, 0)
-+
-+/*
-+ * The time required for switching power status is based on the time
-+ * to turn on the largest domain's power, which is at microsecond level
-+ */
-+#define JH71XX_PMU_TIMEOUT_US 100
-+
-+struct jh71xx_domain_info {
-+ const char * const name;
-+ unsigned int flags;
-+ u8 bit;
-+};
-+
-+struct jh71xx_pmu_match_data {
-+ const struct jh71xx_domain_info *domain_info;
-+ int num_domains;
-+};
-+
-+struct jh71xx_pmu {
-+ struct device *dev;
-+ const struct jh71xx_pmu_match_data *match_data;
-+ void __iomem *base;
-+ struct generic_pm_domain **genpd;
-+ struct genpd_onecell_data genpd_data;
-+ int irq;
-+ spinlock_t lock; /* protects pmu reg */
-+};
-+
-+struct jh71xx_pmu_dev {
-+ const struct jh71xx_domain_info *domain_info;
-+ struct jh71xx_pmu *pmu;
-+ struct generic_pm_domain genpd;
-+};
-+
-+static int jh71xx_pmu_get_state(struct jh71xx_pmu_dev *pmd, u32 mask, bool *is_on)
-+{
-+ struct jh71xx_pmu *pmu = pmd->pmu;
-+
-+ if (!mask)
-+ return -EINVAL;
-+
-+ *is_on = readl(pmu->base + JH71XX_PMU_CURR_POWER_MODE) & mask;
-+
-+ return 0;
-+}
-+
-+static int jh71xx_pmu_set_state(struct jh71xx_pmu_dev *pmd, u32 mask, bool on)
-+{
-+ struct jh71xx_pmu *pmu = pmd->pmu;
-+ unsigned long flags;
-+ u32 val;
-+ u32 mode;
-+ u32 encourage_lo;
-+ u32 encourage_hi;
-+ bool is_on;
-+ int ret;
-+
-+ ret = jh71xx_pmu_get_state(pmd, mask, &is_on);
-+ if (ret) {
-+ dev_dbg(pmu->dev, "unable to get current state for %s\n",
-+ pmd->genpd.name);
-+ return ret;
-+ }
-+
-+ if (is_on == on) {
-+ dev_dbg(pmu->dev, "pm domain [%s] is already %sable status.\n",
-+ pmd->genpd.name, on ? "en" : "dis");
-+ return 0;
-+ }
-+
-+ spin_lock_irqsave(&pmu->lock, flags);
-+
-+ /*
-+ * The PMU accepts software encourage to switch power mode in the following 2 steps:
-+ *
-+ * 1.Configure the register SW_TURN_ON_POWER (offset 0x0c) by writing 1 to
-+ * the bit corresponding to the power domain that will be turned on
-+ * and writing 0 to the others.
-+ * Likewise, configure the register SW_TURN_OFF_POWER (offset 0x10) by
-+ * writing 1 to the bit corresponding to the power domain that will be
-+ * turned off and writing 0 to the others.
-+ */
-+ if (on) {
-+ mode = JH71XX_PMU_SW_TURN_ON_POWER;
-+ encourage_lo = JH71XX_PMU_SW_ENCOURAGE_EN_LO;
-+ encourage_hi = JH71XX_PMU_SW_ENCOURAGE_EN_HI;
-+ } else {
-+ mode = JH71XX_PMU_SW_TURN_OFF_POWER;
-+ encourage_lo = JH71XX_PMU_SW_ENCOURAGE_DIS_LO;
-+ encourage_hi = JH71XX_PMU_SW_ENCOURAGE_DIS_HI;
-+ }
-+
-+ writel(mask, pmu->base + mode);
-+
-+ /*
-+ * 2.Write SW encourage command sequence to the Software Encourage Reg (offset 0x44)
-+ * First write SW_MODE_ENCOURAGE_ON to JH71XX_PMU_SW_ENCOURAGE. This will reset
-+ * the state machine which parses the command sequence. This register must be
-+ * written every time software wants to power on/off a domain.
-+ * Then write the lower bits of the command sequence, followed by the upper
-+ * bits. The sequence differs between powering on & off a domain.
-+ */
-+ writel(JH71XX_PMU_SW_ENCOURAGE_ON, pmu->base + JH71XX_PMU_SW_ENCOURAGE);
-+ writel(encourage_lo, pmu->base + JH71XX_PMU_SW_ENCOURAGE);
-+ writel(encourage_hi, pmu->base + JH71XX_PMU_SW_ENCOURAGE);
-+
-+ spin_unlock_irqrestore(&pmu->lock, flags);
-+
-+ /* Wait for the power domain bit to be enabled / disabled */
-+ if (on) {
-+ ret = readl_poll_timeout_atomic(pmu->base + JH71XX_PMU_CURR_POWER_MODE,
-+ val, val & mask,
-+ 1, JH71XX_PMU_TIMEOUT_US);
-+ } else {
-+ ret = readl_poll_timeout_atomic(pmu->base + JH71XX_PMU_CURR_POWER_MODE,
-+ val, !(val & mask),
-+ 1, JH71XX_PMU_TIMEOUT_US);
-+ }
-+
-+ if (ret) {
-+ dev_err(pmu->dev, "%s: failed to power %s\n",
-+ pmd->genpd.name, on ? "on" : "off");
-+ return -ETIMEDOUT;
-+ }
-+
-+ return 0;
-+}
-+
-+static int jh71xx_pmu_on(struct generic_pm_domain *genpd)
-+{
-+ struct jh71xx_pmu_dev *pmd = container_of(genpd,
-+ struct jh71xx_pmu_dev, genpd);
-+ u32 pwr_mask = BIT(pmd->domain_info->bit);
-+
-+ return jh71xx_pmu_set_state(pmd, pwr_mask, true);
-+}
-+
-+static int jh71xx_pmu_off(struct generic_pm_domain *genpd)
-+{
-+ struct jh71xx_pmu_dev *pmd = container_of(genpd,
-+ struct jh71xx_pmu_dev, genpd);
-+ u32 pwr_mask = BIT(pmd->domain_info->bit);
-+
-+ return jh71xx_pmu_set_state(pmd, pwr_mask, false);
-+}
-+
-+static void jh71xx_pmu_int_enable(struct jh71xx_pmu *pmu, u32 mask, bool enable)
-+{
-+ u32 val;
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&pmu->lock, flags);
-+ val = readl(pmu->base + JH71XX_PMU_TIMER_INT_MASK);
-+
-+ if (enable)
-+ val &= ~mask;
-+ else
-+ val |= mask;
-+
-+ writel(val, pmu->base + JH71XX_PMU_TIMER_INT_MASK);
-+ spin_unlock_irqrestore(&pmu->lock, flags);
-+}
-+
-+static irqreturn_t jh71xx_pmu_interrupt(int irq, void *data)
-+{
-+ struct jh71xx_pmu *pmu = data;
-+ u32 val;
-+
-+ val = readl(pmu->base + JH71XX_PMU_INT_STATUS);
-+
-+ if (val & JH71XX_PMU_INT_SEQ_DONE)
-+ dev_dbg(pmu->dev, "sequence done.\n");
-+ if (val & JH71XX_PMU_INT_HW_REQ)
-+ dev_dbg(pmu->dev, "hardware encourage requestion.\n");
-+ if (val & JH71XX_PMU_INT_SW_FAIL)
-+ dev_err(pmu->dev, "software encourage fail.\n");
-+ if (val & JH71XX_PMU_INT_HW_FAIL)
-+ dev_err(pmu->dev, "hardware encourage fail.\n");
-+ if (val & JH71XX_PMU_INT_PCH_FAIL)
-+ dev_err(pmu->dev, "p-channel fail event.\n");
-+
-+ /* clear interrupts */
-+ writel(val, pmu->base + JH71XX_PMU_INT_STATUS);
-+ writel(val, pmu->base + JH71XX_PMU_EVENT_STATUS);
-+
-+ return IRQ_HANDLED;
-+}
-+
-+static int jh71xx_pmu_init_domain(struct jh71xx_pmu *pmu, int index)
-+{
-+ struct jh71xx_pmu_dev *pmd;
-+ u32 pwr_mask;
-+ int ret;
-+ bool is_on = false;
-+
-+ pmd = devm_kzalloc(pmu->dev, sizeof(*pmd), GFP_KERNEL);
-+ if (!pmd)
-+ return -ENOMEM;
-+
-+ pmd->domain_info = &pmu->match_data->domain_info[index];
-+ pmd->pmu = pmu;
-+ pwr_mask = BIT(pmd->domain_info->bit);
-+
-+ pmd->genpd.name = pmd->domain_info->name;
-+ pmd->genpd.flags = pmd->domain_info->flags;
-+
-+ ret = jh71xx_pmu_get_state(pmd, pwr_mask, &is_on);
-+ if (ret)
-+ dev_warn(pmu->dev, "unable to get current state for %s\n",
-+ pmd->genpd.name);
-+
-+ pmd->genpd.power_on = jh71xx_pmu_on;
-+ pmd->genpd.power_off = jh71xx_pmu_off;
-+ pm_genpd_init(&pmd->genpd, NULL, !is_on);
-+
-+ pmu->genpd_data.domains[index] = &pmd->genpd;
-+
-+ return 0;
-+}
-+
-+static int jh71xx_pmu_probe(struct platform_device *pdev)
-+{
-+ struct device *dev = &pdev->dev;
-+ struct device_node *np = dev->of_node;
-+ const struct jh71xx_pmu_match_data *match_data;
-+ struct jh71xx_pmu *pmu;
-+ unsigned int i;
-+ int ret;
-+
-+ pmu = devm_kzalloc(dev, sizeof(*pmu), GFP_KERNEL);
-+ if (!pmu)
-+ return -ENOMEM;
-+
-+ pmu->base = devm_platform_ioremap_resource(pdev, 0);
-+ if (IS_ERR(pmu->base))
-+ return PTR_ERR(pmu->base);
-+
-+ pmu->irq = platform_get_irq(pdev, 0);
-+ if (pmu->irq < 0)
-+ return pmu->irq;
-+
-+ ret = devm_request_irq(dev, pmu->irq, jh71xx_pmu_interrupt,
-+ 0, pdev->name, pmu);
-+ if (ret)
-+ dev_err(dev, "failed to request irq\n");
-+
-+ match_data = of_device_get_match_data(dev);
-+ if (!match_data)
-+ return -EINVAL;
-+
-+ pmu->genpd = devm_kcalloc(dev, match_data->num_domains,
-+ sizeof(struct generic_pm_domain *),
-+ GFP_KERNEL);
-+ if (!pmu->genpd)
-+ return -ENOMEM;
-+
-+ pmu->dev = dev;
-+ pmu->match_data = match_data;
-+ pmu->genpd_data.domains = pmu->genpd;
-+ pmu->genpd_data.num_domains = match_data->num_domains;
-+
-+ for (i = 0; i < match_data->num_domains; i++) {
-+ ret = jh71xx_pmu_init_domain(pmu, i);
-+ if (ret) {
-+ dev_err(dev, "failed to initialize power domain\n");
-+ return ret;
-+ }
-+ }
-+
-+ spin_lock_init(&pmu->lock);
-+ jh71xx_pmu_int_enable(pmu, JH71XX_PMU_INT_ALL_MASK & ~JH71XX_PMU_INT_PCH_FAIL, true);
-+
-+ ret = of_genpd_add_provider_onecell(np, &pmu->genpd_data);
-+ if (ret) {
-+ dev_err(dev, "failed to register genpd driver: %d\n", ret);
-+ return ret;
-+ }
-+
-+ dev_dbg(dev, "registered %u power domains\n", i);
-+
-+ return 0;
-+}
-+
-+static const struct jh71xx_domain_info jh7110_power_domains[] = {
-+ [JH7110_PD_SYSTOP] = {
-+ .name = "SYSTOP",
-+ .bit = 0,
-+ .flags = GENPD_FLAG_ALWAYS_ON,
-+ },
-+ [JH7110_PD_CPU] = {
-+ .name = "CPU",
-+ .bit = 1,
-+ .flags = GENPD_FLAG_ALWAYS_ON,
-+ },
-+ [JH7110_PD_GPUA] = {
-+ .name = "GPUA",
-+ .bit = 2,
-+ },
-+ [JH7110_PD_VDEC] = {
-+ .name = "VDEC",
-+ .bit = 3,
-+ },
-+ [JH7110_PD_VOUT] = {
-+ .name = "VOUT",
-+ .bit = 4,
-+ },
-+ [JH7110_PD_ISP] = {
-+ .name = "ISP",
-+ .bit = 5,
-+ },
-+ [JH7110_PD_VENC] = {
-+ .name = "VENC",
-+ .bit = 6,
-+ },
-+};
-+
-+static const struct jh71xx_pmu_match_data jh7110_pmu = {
-+ .num_domains = ARRAY_SIZE(jh7110_power_domains),
-+ .domain_info = jh7110_power_domains,
-+};
-+
-+static const struct of_device_id jh71xx_pmu_of_match[] = {
-+ {
-+ .compatible = "starfive,jh7110-pmu",
-+ .data = (void *)&jh7110_pmu,
-+ }, {
-+ /* sentinel */
-+ }
-+};
-+
-+static struct platform_driver jh71xx_pmu_driver = {
-+ .probe = jh71xx_pmu_probe,
-+ .driver = {
-+ .name = "jh71xx-pmu",
-+ .of_match_table = jh71xx_pmu_of_match,
-+ .suppress_bind_attrs = true,
-+ },
-+};
-+builtin_platform_driver(jh71xx_pmu_driver);
-+
-+MODULE_AUTHOR("Walker Chen <walker.chen@starfivetech.com>");
-+MODULE_DESCRIPTION("StarFive JH71XX PMU Driver");
-+MODULE_LICENSE("GPL");
diff --git a/target/linux/starfive/patches-6.1/0037-dt-bindings-soc-starfive-Add-StarFive-syscon-module.patch b/target/linux/starfive/patches-6.1/0037-dt-bindings-soc-starfive-Add-StarFive-syscon-module.patch
deleted file mode 100644
index 75b1d947b0..0000000000
--- a/target/linux/starfive/patches-6.1/0037-dt-bindings-soc-starfive-Add-StarFive-syscon-module.patch
+++ /dev/null
@@ -1,98 +0,0 @@
-From 27d38dda7527414eb84ef471425e96c9d2566b38 Mon Sep 17 00:00:00 2001
-From: William Qiu <william.qiu@starfivetech.com>
-Date: Thu, 6 Apr 2023 15:46:13 +0800
-Subject: [PATCH 037/122] dt-bindings: soc: starfive: Add StarFive syscon
- module
-
-Add documentation to describe StarFive System Controller Registers.
-
-Signed-off-by: William Qiu <william.qiu@starfivetech.com>
----
- .../soc/starfive/starfive,jh7110-syscon.yaml | 58 +++++++++++++++++++
- MAINTAINERS | 6 ++
- 2 files changed, 64 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/soc/starfive/starfive,jh7110-syscon.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/soc/starfive/starfive,jh7110-syscon.yaml
-@@ -0,0 +1,58 @@
-+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/soc/starfive/starfive,jh7110-syscon.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: StarFive JH7110 SoC system controller
-+
-+maintainers:
-+ - William Qiu <william.qiu@starfivetech.com>
-+
-+description: |
-+ The StarFive JH7110 SoC system controller provides register information such
-+ as offset, mask and shift to configure related modules such as MMC and PCIe.
-+
-+properties:
-+ compatible:
-+ oneOf:
-+ - items:
-+ - enum:
-+ - starfive,jh7110-aon-syscon
-+ - starfive,jh7110-sys-syscon
-+ - const: syscon
-+ - const: simple-mfd
-+ - items:
-+ - const: starfive,jh7110-stg-syscon
-+ - const: syscon
-+
-+ reg:
-+ maxItems: 1
-+
-+ clock-controller:
-+ $ref: /schemas/clock/starfive,jh7110-pll.yaml#
-+ type: object
-+
-+ power-controller:
-+ $ref: /schemas/power/starfive,jh7110-pmu.yaml#
-+ type: object
-+
-+required:
-+ - compatible
-+ - reg
-+
-+additionalProperties: false
-+
-+examples:
-+ - |
-+ syscon@10240000 {
-+ compatible = "starfive,jh7110-stg-syscon", "syscon";
-+ reg = <0x10240000 0x1000>;
-+ };
-+
-+ syscon@13030000 {
-+ compatible = "starfive,jh7110-sys-syscon", "syscon", "simple-mfd";
-+ reg = <0x13030000 0x1000>;
-+ };
-+
-+...
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -19663,6 +19663,11 @@ S: Supported
- F: Documentation/devicetree/bindings/clock/starfive,jh7110-pll.yaml
- F: drivers/clk/starfive/clk-starfive-jh7110-pll.*
-
-+STARFIVE JH7110 SYSCON
-+M: William Qiu <william.qiu@starfivetech.com>
-+S: Supported
-+F: Documentation/devicetree/bindings/soc/starfive/starfive,jh7110-syscon.yaml
-+
- STARFIVE JH71X0 CLOCK DRIVERS
- M: Emil Renner Berthing <kernel@esmil.dk>
- M: Hal Feng <hal.feng@starfivetech.com>
-@@ -19693,6 +19698,7 @@ STARFIVE SOC DRIVER
- M: Conor Dooley <conor@kernel.org>
- S: Maintained
- T: git https://git.kernel.org/pub/scm/linux/kernel/git/conor/linux.git/
-+F: Documentation/devicetree/bindings/soc/starfive/
- F: drivers/soc/starfive/
- F: include/soc/starfive/
-
diff --git a/target/linux/starfive/patches-6.1/0038-riscv-dts-starfive-jh7110-Add-syscon-nodes.patch b/target/linux/starfive/patches-6.1/0038-riscv-dts-starfive-jh7110-Add-syscon-nodes.patch
deleted file mode 100644
index ad748151c7..0000000000
--- a/target/linux/starfive/patches-6.1/0038-riscv-dts-starfive-jh7110-Add-syscon-nodes.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From 40098f3d986dc90f6a7be0e5a35ddaccd1ded0b5 Mon Sep 17 00:00:00 2001
-From: William Qiu <william.qiu@starfivetech.com>
-Date: Thu, 6 Apr 2023 15:46:34 +0800
-Subject: [PATCH 038/122] riscv: dts: starfive: jh7110: Add syscon nodes
-
-Add stg_syscon/sys_syscon/aon_syscon nodes for JH7110 Soc.
-
-Signed-off-by: William Qiu <william.qiu@starfivetech.com>
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
-Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
----
- arch/riscv/boot/dts/starfive/jh7110.dtsi | 15 +++++++++++++++
- 1 file changed, 15 insertions(+)
-
---- a/arch/riscv/boot/dts/starfive/jh7110.dtsi
-+++ b/arch/riscv/boot/dts/starfive/jh7110.dtsi
-@@ -353,6 +353,11 @@
- status = "disabled";
- };
-
-+ stg_syscon: syscon@10240000 {
-+ compatible = "starfive,jh7110-stg-syscon", "syscon";
-+ reg = <0x0 0x10240000 0x0 0x1000>;
-+ };
-+
- uart3: serial@12000000 {
- compatible = "snps,dw-apb-uart";
- reg = <0x0 0x12000000 0x0 0x10000>;
-@@ -457,6 +462,11 @@
- #reset-cells = <1>;
- };
-
-+ sys_syscon: syscon@13030000 {
-+ compatible = "starfive,jh7110-sys-syscon", "syscon", "simple-mfd";
-+ reg = <0x0 0x13030000 0x0 0x1000>;
-+ };
-+
- sysgpio: pinctrl@13040000 {
- compatible = "starfive,jh7110-sys-pinctrl";
- reg = <0x0 0x13040000 0x0 0x10000>;
-@@ -486,6 +496,11 @@
- #reset-cells = <1>;
- };
-
-+ aon_syscon: syscon@17010000 {
-+ compatible = "starfive,jh7110-aon-syscon", "syscon", "simple-mfd";
-+ reg = <0x0 0x17010000 0x0 0x1000>;
-+ };
-+
- aongpio: pinctrl@17020000 {
- compatible = "starfive,jh7110-aon-pinctrl";
- reg = <0x0 0x17020000 0x0 0x10000>;
diff --git a/target/linux/starfive/patches-6.1/0039-riscv-dts-starfive-jh7110-Add-PLL-clock-node-and-mod.patch b/target/linux/starfive/patches-6.1/0039-riscv-dts-starfive-jh7110-Add-PLL-clock-node-and-mod.patch
deleted file mode 100644
index c771512bd3..0000000000
--- a/target/linux/starfive/patches-6.1/0039-riscv-dts-starfive-jh7110-Add-PLL-clock-node-and-mod.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From f0548ab9212ef35abe79f46e5f509f4fc9d78699 Mon Sep 17 00:00:00 2001
-From: Xingyu Wu <xingyu.wu@starfivetech.com>
-Date: Mon, 20 Feb 2023 14:33:33 +0800
-Subject: [PATCH 039/122] riscv: dts: starfive: jh7110: Add PLL clock node and
- modify syscrg node
-
-Add the PLL clock node for the Starfive JH7110 SoC and
-modify the SYSCRG node to add PLL clocks input.
-
-Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
----
- arch/riscv/boot/dts/starfive/jh7110.dtsi | 14 ++++++++++++--
- 1 file changed, 12 insertions(+), 2 deletions(-)
-
---- a/arch/riscv/boot/dts/starfive/jh7110.dtsi
-+++ b/arch/riscv/boot/dts/starfive/jh7110.dtsi
-@@ -452,12 +452,16 @@
- <&gmac1_rgmii_rxin>,
- <&i2stx_bclk_ext>, <&i2stx_lrck_ext>,
- <&i2srx_bclk_ext>, <&i2srx_lrck_ext>,
-- <&tdm_ext>, <&mclk_ext>;
-+ <&tdm_ext>, <&mclk_ext>,
-+ <&pllclk JH7110_CLK_PLL0_OUT>,
-+ <&pllclk JH7110_CLK_PLL1_OUT>,
-+ <&pllclk JH7110_CLK_PLL2_OUT>;
- clock-names = "osc", "gmac1_rmii_refin",
- "gmac1_rgmii_rxin",
- "i2stx_bclk_ext", "i2stx_lrck_ext",
- "i2srx_bclk_ext", "i2srx_lrck_ext",
-- "tdm_ext", "mclk_ext";
-+ "tdm_ext", "mclk_ext",
-+ "pll0_out", "pll1_out", "pll2_out";
- #clock-cells = <1>;
- #reset-cells = <1>;
- };
-@@ -465,6 +469,12 @@
- sys_syscon: syscon@13030000 {
- compatible = "starfive,jh7110-sys-syscon", "syscon", "simple-mfd";
- reg = <0x0 0x13030000 0x0 0x1000>;
-+
-+ pllclk: clock-controller {
-+ compatible = "starfive,jh7110-pll";
-+ clocks = <&osc>;
-+ #clock-cells = <1>;
-+ };
- };
-
- sysgpio: pinctrl@13040000 {
diff --git a/target/linux/starfive/patches-6.1/0040-dt-bindings-net-snps-dwmac-Add-dwmac-5.20-version.patch b/target/linux/starfive/patches-6.1/0040-dt-bindings-net-snps-dwmac-Add-dwmac-5.20-version.patch
deleted file mode 100644
index 139cd8445b..0000000000
--- a/target/linux/starfive/patches-6.1/0040-dt-bindings-net-snps-dwmac-Add-dwmac-5.20-version.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-From 5866a8486a261decacd19769556d1b79b5d1269d Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Mon, 8 Aug 2022 17:13:34 +0200
-Subject: [PATCH 040/122] dt-bindings: net: snps,dwmac: Add dwmac-5.20 version
-
-Add dwmac-5.20 IP version to snps.dwmac.yaml
-
-Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
-Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- Documentation/devicetree/bindings/net/snps,dwmac.yaml | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- a/Documentation/devicetree/bindings/net/snps,dwmac.yaml
-+++ b/Documentation/devicetree/bindings/net/snps,dwmac.yaml
-@@ -30,6 +30,7 @@ select:
- - snps,dwmac-4.10a
- - snps,dwmac-4.20a
- - snps,dwmac-5.10a
-+ - snps,dwmac-5.20
- - snps,dwxgmac
- - snps,dwxgmac-2.10
-
-@@ -87,6 +88,7 @@ properties:
- - snps,dwmac-4.10a
- - snps,dwmac-4.20a
- - snps,dwmac-5.10a
-+ - snps,dwmac-5.20
- - snps,dwxgmac
- - snps,dwxgmac-2.10
-
-@@ -393,6 +395,7 @@ allOf:
- - snps,dwmac-3.50a
- - snps,dwmac-4.10a
- - snps,dwmac-4.20a
-+ - snps,dwmac-5.20
- - snps,dwxgmac
- - snps,dwxgmac-2.10
- - st,spear600-gmac
-@@ -447,6 +450,7 @@ allOf:
- - snps,dwmac-4.10a
- - snps,dwmac-4.20a
- - snps,dwmac-5.10a
-+ - snps,dwmac-5.20
- - snps,dwxgmac
- - snps,dwxgmac-2.10
- - st,spear600-gmac
diff --git a/target/linux/starfive/patches-6.1/0041-net-stmmac-platform-Add-snps-dwmac-5.20-IP-compatibl.patch b/target/linux/starfive/patches-6.1/0041-net-stmmac-platform-Add-snps-dwmac-5.20-IP-compatibl.patch
deleted file mode 100644
index 077f161dcd..0000000000
--- a/target/linux/starfive/patches-6.1/0041-net-stmmac-platform-Add-snps-dwmac-5.20-IP-compatibl.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From cb00f835fc9f3ece473e7081f17c8613bf08a8ef Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Sun, 7 Aug 2022 22:26:00 +0200
-Subject: [PATCH 041/122] net: stmmac: platform: Add snps,dwmac-5.20 IP
- compatible string
-
-Add "snps,dwmac-5.20" compatible string for 5.20 version that can avoid
-to define some platform data in the glue layer.
-
-Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
-Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
----
- drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
-@@ -519,7 +519,8 @@ stmmac_probe_config_dt(struct platform_d
- if (of_device_is_compatible(np, "snps,dwmac-4.00") ||
- of_device_is_compatible(np, "snps,dwmac-4.10a") ||
- of_device_is_compatible(np, "snps,dwmac-4.20a") ||
-- of_device_is_compatible(np, "snps,dwmac-5.10a")) {
-+ of_device_is_compatible(np, "snps,dwmac-5.10a") ||
-+ of_device_is_compatible(np, "snps,dwmac-5.20")) {
- plat->has_gmac4 = 1;
- plat->has_gmac = 0;
- plat->pmt = 1;
diff --git a/target/linux/starfive/patches-6.1/0042-dt-bindings-net-snps-dwmac-Add-ahb-reset-reset-name.patch b/target/linux/starfive/patches-6.1/0042-dt-bindings-net-snps-dwmac-Add-ahb-reset-reset-name.patch
deleted file mode 100644
index 5b73752fd6..0000000000
--- a/target/linux/starfive/patches-6.1/0042-dt-bindings-net-snps-dwmac-Add-ahb-reset-reset-name.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-From 3b0609e57e031a3b680131b3fc25bc1165e3360f Mon Sep 17 00:00:00 2001
-From: Samin Guo <samin.guo@starfivetech.com>
-Date: Mon, 27 Feb 2023 18:26:04 +0800
-Subject: [PATCH 042/122] dt-bindings: net: snps,dwmac: Add 'ahb'
- reset/reset-name
-
-According to:
-stmmac_platform.c: stmmac_probe_config_dt
-stmmac_main.c: stmmac_dvr_probe
-
-dwmac controller may require one (stmmaceth) or two (stmmaceth+ahb)
-reset signals, and the maxItems of resets/reset-names is going to be 2.
-
-The gmac of Starfive Jh7110 SOC must have two resets.
-it uses snps,dwmac-5.20 IP.
-
-Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
----
- .../devicetree/bindings/net/snps,dwmac.yaml | 12 ++++++++----
- 1 file changed, 8 insertions(+), 4 deletions(-)
-
---- a/Documentation/devicetree/bindings/net/snps,dwmac.yaml
-+++ b/Documentation/devicetree/bindings/net/snps,dwmac.yaml
-@@ -133,12 +133,16 @@ properties:
- - ptp_ref
-
- resets:
-- maxItems: 1
-- description:
-- MAC Reset signal.
-+ minItems: 1
-+ items:
-+ - description: GMAC stmmaceth reset
-+ - description: AHB reset
-
- reset-names:
-- const: stmmaceth
-+ minItems: 1
-+ items:
-+ - const: stmmaceth
-+ - const: ahb
-
- power-domains:
- maxItems: 1
diff --git a/target/linux/starfive/patches-6.1/0043-dt-bindings-net-Add-support-StarFive-dwmac.patch b/target/linux/starfive/patches-6.1/0043-dt-bindings-net-Add-support-StarFive-dwmac.patch
deleted file mode 100644
index a66452c382..0000000000
--- a/target/linux/starfive/patches-6.1/0043-dt-bindings-net-Add-support-StarFive-dwmac.patch
+++ /dev/null
@@ -1,190 +0,0 @@
-From 6bef17fa124f20723724e2a9a1d890fd1a9d5eaa Mon Sep 17 00:00:00 2001
-From: Yanhong Wang <yanhong.wang@starfivetech.com>
-Date: Mon, 31 Oct 2022 18:08:15 +0800
-Subject: [PATCH 043/122] dt-bindings: net: Add support StarFive dwmac
-
-Add documentation to describe StarFive dwmac driver(GMAC).
-
-Signed-off-by: Yanhong Wang <yanhong.wang@starfivetech.com>
-Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
-Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
----
- .../devicetree/bindings/net/snps,dwmac.yaml | 1 +
- .../bindings/net/starfive,jh7110-dwmac.yaml | 144 ++++++++++++++++++
- MAINTAINERS | 6 +
- 3 files changed, 151 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/net/starfive,jh7110-dwmac.yaml
-
---- a/Documentation/devicetree/bindings/net/snps,dwmac.yaml
-+++ b/Documentation/devicetree/bindings/net/snps,dwmac.yaml
-@@ -91,6 +91,7 @@ properties:
- - snps,dwmac-5.20
- - snps,dwxgmac
- - snps,dwxgmac-2.10
-+ - starfive,jh7110-dwmac
-
- reg:
- minItems: 1
---- /dev/null
-+++ b/Documentation/devicetree/bindings/net/starfive,jh7110-dwmac.yaml
-@@ -0,0 +1,144 @@
-+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-+# Copyright (C) 2022 StarFive Technology Co., Ltd.
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/net/starfive,jh7110-dwmac.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: StarFive JH7110 DWMAC glue layer
-+
-+maintainers:
-+ - Emil Renner Berthing <kernel@esmil.dk>
-+ - Samin Guo <samin.guo@starfivetech.com>
-+
-+select:
-+ properties:
-+ compatible:
-+ contains:
-+ enum:
-+ - starfive,jh7110-dwmac
-+ required:
-+ - compatible
-+
-+properties:
-+ compatible:
-+ items:
-+ - enum:
-+ - starfive,jh7110-dwmac
-+ - const: snps,dwmac-5.20
-+
-+ reg:
-+ maxItems: 1
-+
-+ clocks:
-+ items:
-+ - description: GMAC main clock
-+ - description: GMAC AHB clock
-+ - description: PTP clock
-+ - description: TX clock
-+ - description: GTX clock
-+
-+ clock-names:
-+ items:
-+ - const: stmmaceth
-+ - const: pclk
-+ - const: ptp_ref
-+ - const: tx
-+ - const: gtx
-+
-+ interrupts:
-+ minItems: 3
-+ maxItems: 3
-+
-+ interrupt-names:
-+ minItems: 3
-+ maxItems: 3
-+
-+ resets:
-+ items:
-+ - description: MAC Reset signal.
-+ - description: AHB Reset signal.
-+
-+ reset-names:
-+ items:
-+ - const: stmmaceth
-+ - const: ahb
-+
-+ starfive,tx-use-rgmii-clk:
-+ description:
-+ Tx clock is provided by external rgmii clock.
-+ type: boolean
-+
-+ starfive,syscon:
-+ $ref: /schemas/types.yaml#/definitions/phandle-array
-+ items:
-+ - items:
-+ - description: phandle to syscon that configures phy mode
-+ - description: Offset of phy mode selection
-+ - description: Shift of phy mode selection
-+ description:
-+ A phandle to syscon with two arguments that configure phy mode.
-+ The argument one is the offset of phy mode selection, the
-+ argument two is the shift of phy mode selection.
-+
-+required:
-+ - compatible
-+ - reg
-+ - clocks
-+ - clock-names
-+ - interrupts
-+ - interrupt-names
-+ - resets
-+ - reset-names
-+
-+allOf:
-+ - $ref: snps,dwmac.yaml#
-+
-+unevaluatedProperties: false
-+
-+examples:
-+ - |
-+ ethernet@16030000 {
-+ compatible = "starfive,jh7110-dwmac", "snps,dwmac-5.20";
-+ reg = <0x16030000 0x10000>;
-+ clocks = <&clk 3>, <&clk 2>, <&clk 109>,
-+ <&clk 6>, <&clk 111>;
-+ clock-names = "stmmaceth", "pclk", "ptp_ref",
-+ "tx", "gtx";
-+ resets = <&rst 1>, <&rst 2>;
-+ reset-names = "stmmaceth", "ahb";
-+ interrupts = <7>, <6>, <5>;
-+ interrupt-names = "macirq", "eth_wake_irq", "eth_lpi";
-+ phy-mode = "rgmii-id";
-+ snps,multicast-filter-bins = <64>;
-+ snps,perfect-filter-entries = <8>;
-+ rx-fifo-depth = <2048>;
-+ tx-fifo-depth = <2048>;
-+ snps,fixed-burst;
-+ snps,no-pbl-x8;
-+ snps,tso;
-+ snps,force_thresh_dma_mode;
-+ snps,axi-config = <&stmmac_axi_setup>;
-+ snps,en-tx-lpi-clockgating;
-+ snps,txpbl = <16>;
-+ snps,rxpbl = <16>;
-+ starfive,syscon = <&aon_syscon 0xc 0x12>;
-+ phy-handle = <&phy0>;
-+
-+ mdio {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ compatible = "snps,dwmac-mdio";
-+
-+ phy0: ethernet-phy@0 {
-+ reg = <0>;
-+ };
-+ };
-+
-+ stmmac_axi_setup: stmmac-axi-config {
-+ snps,lpi_en;
-+ snps,wr_osr_lmt = <4>;
-+ snps,rd_osr_lmt = <4>;
-+ snps,blen = <256 128 64 32 0 0 0>;
-+ };
-+ };
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -19657,6 +19657,12 @@ M: Emil Renner Berthing <kernel@esmil.dk
- S: Maintained
- F: arch/riscv/boot/dts/starfive/
-
-+STARFIVE DWMAC GLUE LAYER
-+M: Emil Renner Berthing <kernel@esmil.dk>
-+M: Samin Guo <samin.guo@starfivetech.com>
-+S: Maintained
-+F: Documentation/devicetree/bindings/net/starfive,jh7110-dwmac.yaml
-+
- STARFIVE JH7110 PLL CLOCK DRIVER
- M: Xingyu Wu <xingyu.wu@starfivetech.com>
- S: Supported
diff --git a/target/linux/starfive/patches-6.1/0044-net-stmmac-Add-glue-layer-for-StarFive-JH7110-SoC.patch b/target/linux/starfive/patches-6.1/0044-net-stmmac-Add-glue-layer-for-StarFive-JH7110-SoC.patch
deleted file mode 100644
index 59609809c1..0000000000
--- a/target/linux/starfive/patches-6.1/0044-net-stmmac-Add-glue-layer-for-StarFive-JH7110-SoC.patch
+++ /dev/null
@@ -1,187 +0,0 @@
-From 7c82049adb0460985dd6a1e5c9b6954d901247d2 Mon Sep 17 00:00:00 2001
-From: Samin Guo <samin.guo@starfivetech.com>
-Date: Fri, 3 Mar 2023 16:50:58 +0800
-Subject: [PATCH 044/122] net: stmmac: Add glue layer for StarFive JH7110 SoC
-
-This adds StarFive dwmac driver support on the StarFive JH7110 SoC.
-
-Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
-Co-developed-by: Emil Renner Berthing <kernel@esmil.dk>
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
-Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
----
- MAINTAINERS | 1 +
- drivers/net/ethernet/stmicro/stmmac/Kconfig | 12 ++
- drivers/net/ethernet/stmicro/stmmac/Makefile | 1 +
- .../ethernet/stmicro/stmmac/dwmac-starfive.c | 123 ++++++++++++++++++
- 4 files changed, 137 insertions(+)
- create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c
-
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -19662,6 +19662,7 @@ M: Emil Renner Berthing <kernel@esmil.dk
- M: Samin Guo <samin.guo@starfivetech.com>
- S: Maintained
- F: Documentation/devicetree/bindings/net/starfive,jh7110-dwmac.yaml
-+F: drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c
-
- STARFIVE JH7110 PLL CLOCK DRIVER
- M: Xingyu Wu <xingyu.wu@starfivetech.com>
---- a/drivers/net/ethernet/stmicro/stmmac/Kconfig
-+++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig
-@@ -165,6 +165,18 @@ config DWMAC_SOCFPGA
- for the stmmac device driver. This driver is used for
- arria5 and cyclone5 FPGA SoCs.
-
-+config DWMAC_STARFIVE
-+ tristate "StarFive dwmac support"
-+ depends on OF && (ARCH_STARFIVE || COMPILE_TEST)
-+ select MFD_SYSCON
-+ default m if ARCH_STARFIVE
-+ help
-+ Support for ethernet controllers on StarFive RISC-V SoCs
-+
-+ This selects the StarFive platform specific glue layer support for
-+ the stmmac device driver. This driver is used for StarFive JH7110
-+ ethernet controller.
-+
- config DWMAC_STI
- tristate "STi GMAC support"
- default ARCH_STI
---- a/drivers/net/ethernet/stmicro/stmmac/Makefile
-+++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
-@@ -23,6 +23,7 @@ obj-$(CONFIG_DWMAC_OXNAS) += dwmac-oxnas
- obj-$(CONFIG_DWMAC_QCOM_ETHQOS) += dwmac-qcom-ethqos.o
- obj-$(CONFIG_DWMAC_ROCKCHIP) += dwmac-rk.o
- obj-$(CONFIG_DWMAC_SOCFPGA) += dwmac-altr-socfpga.o
-+obj-$(CONFIG_DWMAC_STARFIVE) += dwmac-starfive.o
- obj-$(CONFIG_DWMAC_STI) += dwmac-sti.o
- obj-$(CONFIG_DWMAC_STM32) += dwmac-stm32.o
- obj-$(CONFIG_DWMAC_SUNXI) += dwmac-sunxi.o
---- /dev/null
-+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c
-@@ -0,0 +1,123 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+/*
-+ * StarFive DWMAC platform driver
-+ *
-+ * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
-+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
-+ *
-+ */
-+
-+#include <linux/mfd/syscon.h>
-+#include <linux/of_device.h>
-+#include <linux/regmap.h>
-+
-+#include "stmmac_platform.h"
-+
-+struct starfive_dwmac {
-+ struct device *dev;
-+ struct clk *clk_tx;
-+};
-+
-+static void starfive_dwmac_fix_mac_speed(void *priv, unsigned int speed)
-+{
-+ struct starfive_dwmac *dwmac = priv;
-+ unsigned long rate;
-+ int err;
-+
-+ rate = clk_get_rate(dwmac->clk_tx);
-+
-+ switch (speed) {
-+ case SPEED_1000:
-+ rate = 125000000;
-+ break;
-+ case SPEED_100:
-+ rate = 25000000;
-+ break;
-+ case SPEED_10:
-+ rate = 2500000;
-+ break;
-+ default:
-+ dev_err(dwmac->dev, "invalid speed %u\n", speed);
-+ break;
-+ }
-+
-+ err = clk_set_rate(dwmac->clk_tx, rate);
-+ if (err)
-+ dev_err(dwmac->dev, "failed to set tx rate %lu\n", rate);
-+}
-+
-+static int starfive_dwmac_probe(struct platform_device *pdev)
-+{
-+ struct plat_stmmacenet_data *plat_dat;
-+ struct stmmac_resources stmmac_res;
-+ struct starfive_dwmac *dwmac;
-+ struct clk *clk_gtx;
-+ int err;
-+
-+ err = stmmac_get_platform_resources(pdev, &stmmac_res);
-+ if (err)
-+ return dev_err_probe(&pdev->dev, err,
-+ "failed to get resources\n");
-+
-+ plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
-+ if (IS_ERR(plat_dat))
-+ return dev_err_probe(&pdev->dev, PTR_ERR(plat_dat),
-+ "dt configuration failed\n");
-+
-+ dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL);
-+ if (!dwmac)
-+ return -ENOMEM;
-+
-+ dwmac->clk_tx = devm_clk_get_enabled(&pdev->dev, "tx");
-+ if (IS_ERR(dwmac->clk_tx))
-+ return dev_err_probe(&pdev->dev, PTR_ERR(dwmac->clk_tx),
-+ "error getting tx clock\n");
-+
-+ clk_gtx = devm_clk_get_enabled(&pdev->dev, "gtx");
-+ if (IS_ERR(clk_gtx))
-+ return dev_err_probe(&pdev->dev, PTR_ERR(clk_gtx),
-+ "error getting gtx clock\n");
-+
-+ /* Generally, the rgmii_tx clock is provided by the internal clock,
-+ * which needs to match the corresponding clock frequency according
-+ * to different speeds. If the rgmii_tx clock is provided by the
-+ * external rgmii_rxin, there is no need to configure the clock
-+ * internally, because rgmii_rxin will be adaptively adjusted.
-+ */
-+ if (!device_property_read_bool(&pdev->dev, "starfive,tx-use-rgmii-clk"))
-+ plat_dat->fix_mac_speed = starfive_dwmac_fix_mac_speed;
-+
-+ dwmac->dev = &pdev->dev;
-+ plat_dat->bsp_priv = dwmac;
-+ plat_dat->dma_cfg->dche = true;
-+
-+ err = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
-+ if (err) {
-+ stmmac_remove_config_dt(pdev, plat_dat);
-+ return err;
-+ }
-+
-+ return 0;
-+}
-+
-+static const struct of_device_id starfive_dwmac_match[] = {
-+ { .compatible = "starfive,jh7110-dwmac" },
-+ { /* sentinel */ }
-+};
-+MODULE_DEVICE_TABLE(of, starfive_dwmac_match);
-+
-+static struct platform_driver starfive_dwmac_driver = {
-+ .probe = starfive_dwmac_probe,
-+ .remove = stmmac_pltfr_remove,
-+ .driver = {
-+ .name = "starfive-dwmac",
-+ .pm = &stmmac_pltfr_pm_ops,
-+ .of_match_table = starfive_dwmac_match,
-+ },
-+};
-+module_platform_driver(starfive_dwmac_driver);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_DESCRIPTION("StarFive DWMAC platform driver");
-+MODULE_AUTHOR("Emil Renner Berthing <kernel@esmil.dk>");
-+MODULE_AUTHOR("Samin Guo <samin.guo@starfivetech.com>");
diff --git a/target/linux/starfive/patches-6.1/0045-net-stmmac-dwmac-starfive-Add-phy-interface-settings.patch b/target/linux/starfive/patches-6.1/0045-net-stmmac-dwmac-starfive-Add-phy-interface-settings.patch
deleted file mode 100644
index a532c0e4dd..0000000000
--- a/target/linux/starfive/patches-6.1/0045-net-stmmac-dwmac-starfive-Add-phy-interface-settings.patch
+++ /dev/null
@@ -1,93 +0,0 @@
-From 20886cd583e8d569d78ea0e723f98384a61ab54b Mon Sep 17 00:00:00 2001
-From: Samin Guo <samin.guo@starfivetech.com>
-Date: Thu, 2 Mar 2023 19:52:37 +0800
-Subject: [PATCH 045/122] net: stmmac: dwmac-starfive: Add phy interface
- settings
-
-dwmac supports multiple modess. When working under rmii and rgmii,
-you need to set different phy interfaces.
-
-According to the dwmac document, when working in rmii, it needs to be
-set to 0x4, and rgmii needs to be set to 0x1.
-
-The phy interface needs to be set in syscon, the format is as follows:
-starfive,syscon: <&syscon, offset, shift>
-
-Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
-Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
----
- .../ethernet/stmicro/stmmac/dwmac-starfive.c | 48 +++++++++++++++++++
- 1 file changed, 48 insertions(+)
-
---- a/drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c
-@@ -13,6 +13,10 @@
-
- #include "stmmac_platform.h"
-
-+#define STARFIVE_DWMAC_PHY_INFT_RGMII 0x1
-+#define STARFIVE_DWMAC_PHY_INFT_RMII 0x4
-+#define STARFIVE_DWMAC_PHY_INFT_FIELD 0x7U
-+
- struct starfive_dwmac {
- struct device *dev;
- struct clk *clk_tx;
-@@ -46,6 +50,46 @@ static void starfive_dwmac_fix_mac_speed
- dev_err(dwmac->dev, "failed to set tx rate %lu\n", rate);
- }
-
-+static int starfive_dwmac_set_mode(struct plat_stmmacenet_data *plat_dat)
-+{
-+ struct starfive_dwmac *dwmac = plat_dat->bsp_priv;
-+ struct regmap *regmap;
-+ unsigned int args[2];
-+ unsigned int mode;
-+ int err;
-+
-+ switch (plat_dat->interface) {
-+ case PHY_INTERFACE_MODE_RMII:
-+ mode = STARFIVE_DWMAC_PHY_INFT_RMII;
-+ break;
-+
-+ case PHY_INTERFACE_MODE_RGMII:
-+ case PHY_INTERFACE_MODE_RGMII_ID:
-+ mode = STARFIVE_DWMAC_PHY_INFT_RGMII;
-+ break;
-+
-+ default:
-+ dev_err(dwmac->dev, "unsupported interface %d\n",
-+ plat_dat->interface);
-+ return -EINVAL;
-+ }
-+
-+ regmap = syscon_regmap_lookup_by_phandle_args(dwmac->dev->of_node,
-+ "starfive,syscon",
-+ 2, args);
-+ if (IS_ERR(regmap))
-+ return dev_err_probe(dwmac->dev, PTR_ERR(regmap), "getting the regmap failed\n");
-+
-+ /* args[0]:offset args[1]: shift */
-+ err = regmap_update_bits(regmap, args[0],
-+ STARFIVE_DWMAC_PHY_INFT_FIELD << args[1],
-+ mode << args[1]);
-+ if (err)
-+ return dev_err_probe(dwmac->dev, err, "error setting phy mode\n");
-+
-+ return 0;
-+}
-+
- static int starfive_dwmac_probe(struct platform_device *pdev)
- {
- struct plat_stmmacenet_data *plat_dat;
-@@ -91,6 +135,10 @@ static int starfive_dwmac_probe(struct p
- plat_dat->bsp_priv = dwmac;
- plat_dat->dma_cfg->dche = true;
-
-+ err = starfive_dwmac_set_mode(plat_dat);
-+ if (err)
-+ return err;
-+
- err = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
- if (err) {
- stmmac_remove_config_dt(pdev, plat_dat);
diff --git a/target/linux/starfive/patches-6.1/0046-riscv-dts-starfive-jh7110-Add-ethernet-device-nodes.patch b/target/linux/starfive/patches-6.1/0046-riscv-dts-starfive-jh7110-Add-ethernet-device-nodes.patch
deleted file mode 100644
index 50ad56f568..0000000000
--- a/target/linux/starfive/patches-6.1/0046-riscv-dts-starfive-jh7110-Add-ethernet-device-nodes.patch
+++ /dev/null
@@ -1,101 +0,0 @@
-From cad740398f4cb6604abf1ddcc70121b2634ac233 Mon Sep 17 00:00:00 2001
-From: Samin Guo <samin.guo@starfivetech.com>
-Date: Fri, 3 Mar 2023 16:49:31 +0800
-Subject: [PATCH 046/122] riscv: dts: starfive: jh7110: Add ethernet device
- nodes
-
-Add JH7110 ethernet device node to support gmac driver for the JH7110
-RISC-V SoC.
-
-Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
-Signed-off-by: Yanhong Wang <yanhong.wang@starfivetech.com>
-Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
----
- arch/riscv/boot/dts/starfive/jh7110.dtsi | 69 ++++++++++++++++++++++++
- 1 file changed, 69 insertions(+)
-
---- a/arch/riscv/boot/dts/starfive/jh7110.dtsi
-+++ b/arch/riscv/boot/dts/starfive/jh7110.dtsi
-@@ -230,6 +230,13 @@
- #clock-cells = <0>;
- };
-
-+ stmmac_axi_setup: stmmac-axi-config {
-+ snps,lpi_en;
-+ snps,wr_osr_lmt = <4>;
-+ snps,rd_osr_lmt = <4>;
-+ snps,blen = <256 128 64 32 0 0 0>;
-+ };
-+
- tdm_ext: tdm-ext-clock {
- compatible = "fixed-clock";
- clock-output-names = "tdm_ext";
-@@ -489,6 +496,68 @@
- #gpio-cells = <2>;
- };
-
-+ gmac0: ethernet@16030000 {
-+ compatible = "starfive,jh7110-dwmac", "snps,dwmac-5.20";
-+ reg = <0x0 0x16030000 0x0 0x10000>;
-+ clocks = <&aoncrg JH7110_AONCLK_GMAC0_AXI>,
-+ <&aoncrg JH7110_AONCLK_GMAC0_AHB>,
-+ <&syscrg JH7110_SYSCLK_GMAC0_PTP>,
-+ <&aoncrg JH7110_AONCLK_GMAC0_TX_INV>,
-+ <&syscrg JH7110_SYSCLK_GMAC0_GTXC>;
-+ clock-names = "stmmaceth", "pclk", "ptp_ref",
-+ "tx", "gtx";
-+ resets = <&aoncrg JH7110_AONRST_GMAC0_AXI>,
-+ <&aoncrg JH7110_AONRST_GMAC0_AHB>;
-+ reset-names = "stmmaceth", "ahb";
-+ interrupts = <7>, <6>, <5>;
-+ interrupt-names = "macirq", "eth_wake_irq", "eth_lpi";
-+ rx-fifo-depth = <2048>;
-+ tx-fifo-depth = <2048>;
-+ snps,multicast-filter-bins = <64>;
-+ snps,perfect-filter-entries = <8>;
-+ snps,fixed-burst;
-+ snps,no-pbl-x8;
-+ snps,force_thresh_dma_mode;
-+ snps,axi-config = <&stmmac_axi_setup>;
-+ snps,tso;
-+ snps,en-tx-lpi-clockgating;
-+ snps,txpbl = <16>;
-+ snps,rxpbl = <16>;
-+ starfive,syscon = <&aon_syscon 0xc 0x12>;
-+ status = "disabled";
-+ };
-+
-+ gmac1: ethernet@16040000 {
-+ compatible = "starfive,jh7110-dwmac", "snps,dwmac-5.20";
-+ reg = <0x0 0x16040000 0x0 0x10000>;
-+ clocks = <&syscrg JH7110_SYSCLK_GMAC1_AXI>,
-+ <&syscrg JH7110_SYSCLK_GMAC1_AHB>,
-+ <&syscrg JH7110_SYSCLK_GMAC1_PTP>,
-+ <&syscrg JH7110_SYSCLK_GMAC1_TX_INV>,
-+ <&syscrg JH7110_SYSCLK_GMAC1_GTXC>;
-+ clock-names = "stmmaceth", "pclk", "ptp_ref",
-+ "tx", "gtx";
-+ resets = <&syscrg JH7110_SYSRST_GMAC1_AXI>,
-+ <&syscrg JH7110_SYSRST_GMAC1_AHB>;
-+ reset-names = "stmmaceth", "ahb";
-+ interrupts = <78>, <77>, <76>;
-+ interrupt-names = "macirq", "eth_wake_irq", "eth_lpi";
-+ rx-fifo-depth = <2048>;
-+ tx-fifo-depth = <2048>;
-+ snps,multicast-filter-bins = <64>;
-+ snps,perfect-filter-entries = <8>;
-+ snps,fixed-burst;
-+ snps,no-pbl-x8;
-+ snps,force_thresh_dma_mode;
-+ snps,axi-config = <&stmmac_axi_setup>;
-+ snps,tso;
-+ snps,en-tx-lpi-clockgating;
-+ snps,txpbl = <16>;
-+ snps,rxpbl = <16>;
-+ starfive,syscon = <&sys_syscon 0x90 0x2>;
-+ status = "disabled";
-+ };
-+
- aoncrg: clock-controller@17000000 {
- compatible = "starfive,jh7110-aoncrg";
- reg = <0x0 0x17000000 0x0 0x10000>;
diff --git a/target/linux/starfive/patches-6.1/0047-riscv-dts-starfive-visionfive-2-Add-configuration-of.patch b/target/linux/starfive/patches-6.1/0047-riscv-dts-starfive-visionfive-2-Add-configuration-of.patch
deleted file mode 100644
index 9fbdebf5f4..0000000000
--- a/target/linux/starfive/patches-6.1/0047-riscv-dts-starfive-visionfive-2-Add-configuration-of.patch
+++ /dev/null
@@ -1,128 +0,0 @@
-From 6fd84cb9cceaa711671500a92dcee5b1072ab95a Mon Sep 17 00:00:00 2001
-From: Samin Guo <samin.guo@starfivetech.com>
-Date: Tue, 1 Nov 2022 18:11:02 +0800
-Subject: [PATCH 047/122] riscv: dts: starfive: visionfive 2: Add configuration
- of gmac and phy
-
-v1.3B:
- v1.3B uses motorcomm YT8531(rgmii-id phy) x2, need delay and
- inverse configurations.
- The tx_clk of v1.3B uses an external clock and needs to be
- switched to an external clock source.
-
-v1.2A:
- v1.2A gmac0 uses motorcomm YT8531(rgmii-id) PHY, and needs delay
- configurations.
- v1.2A gmac1 uses motorcomm YT8512(rmii) PHY, and needs to
- switch rx and rx to external clock sources.
-
-Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
-Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
----
- .../jh7110-starfive-visionfive-2-v1.2a.dts | 13 +++++++
- .../jh7110-starfive-visionfive-2-v1.3b.dts | 27 +++++++++++++++
- .../jh7110-starfive-visionfive-2.dtsi | 34 +++++++++++++++++++
- 3 files changed, 74 insertions(+)
-
---- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-v1.2a.dts
-+++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-v1.2a.dts
-@@ -11,3 +11,16 @@
- model = "StarFive VisionFive 2 v1.2A";
- compatible = "starfive,visionfive-2-v1.2a", "starfive,jh7110";
- };
-+
-+&gmac1 {
-+ phy-mode = "rmii";
-+ assigned-clocks = <&syscrg JH7110_SYSCLK_GMAC1_TX>,
-+ <&syscrg JH7110_SYSCLK_GMAC1_RX>;
-+ assigned-clock-parents = <&syscrg JH7110_SYSCLK_GMAC1_RMII_RTX>,
-+ <&syscrg JH7110_SYSCLK_GMAC1_RMII_RTX>;
-+};
-+
-+&phy0 {
-+ rx-internal-delay-ps = <1900>;
-+ tx-internal-delay-ps = <1350>;
-+};
---- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-v1.3b.dts
-+++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-v1.3b.dts
-@@ -11,3 +11,30 @@
- model = "StarFive VisionFive 2 v1.3B";
- compatible = "starfive,visionfive-2-v1.3b", "starfive,jh7110";
- };
-+
-+&gmac0 {
-+ starfive,tx-use-rgmii-clk;
-+ assigned-clocks = <&aoncrg JH7110_AONCLK_GMAC0_TX>;
-+ assigned-clock-parents = <&aoncrg JH7110_AONCLK_GMAC0_RMII_RTX>;
-+};
-+
-+&gmac1 {
-+ starfive,tx-use-rgmii-clk;
-+ assigned-clocks = <&syscrg JH7110_SYSCLK_GMAC1_TX>;
-+ assigned-clock-parents = <&syscrg JH7110_SYSCLK_GMAC1_RMII_RTX>;
-+};
-+
-+&phy0 {
-+ motorcomm,tx-clk-adj-enabled;
-+ motorcomm,tx-clk-100-inverted;
-+ motorcomm,tx-clk-1000-inverted;
-+ rx-internal-delay-ps = <1500>;
-+ tx-internal-delay-ps = <1500>;
-+};
-+
-+&phy1 {
-+ motorcomm,tx-clk-adj-enabled;
-+ motorcomm,tx-clk-100-inverted;
-+ rx-internal-delay-ps = <300>;
-+ tx-internal-delay-ps = <0>;
-+};
---- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
-+++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
-@@ -11,6 +11,8 @@
-
- / {
- aliases {
-+ ethernet0 = &gmac0;
-+ ethernet1 = &gmac1;
- i2c0 = &i2c0;
- i2c2 = &i2c2;
- i2c5 = &i2c5;
-@@ -86,6 +88,38 @@
- clock-frequency = <49152000>;
- };
-
-+&gmac0 {
-+ phy-handle = <&phy0>;
-+ phy-mode = "rgmii-id";
-+ status = "okay";
-+
-+ mdio {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ compatible = "snps,dwmac-mdio";
-+
-+ phy0: ethernet-phy@0 {
-+ reg = <0>;
-+ };
-+ };
-+};
-+
-+&gmac1 {
-+ phy-handle = <&phy1>;
-+ phy-mode = "rgmii-id";
-+ status = "okay";
-+
-+ mdio {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ compatible = "snps,dwmac-mdio";
-+
-+ phy1: ethernet-phy@1 {
-+ reg = <0>;
-+ };
-+ };
-+};
-+
- &i2c0 {
- clock-frequency = <100000>;
- i2c-sda-hold-time-ns = <300>;
diff --git a/target/linux/starfive/patches-6.1/0048-dt-bindings-net-Add-Motorcomm-yt8xxx-ethernet-phy.patch b/target/linux/starfive/patches-6.1/0048-dt-bindings-net-Add-Motorcomm-yt8xxx-ethernet-phy.patch
deleted file mode 100644
index 376481ee0f..0000000000
--- a/target/linux/starfive/patches-6.1/0048-dt-bindings-net-Add-Motorcomm-yt8xxx-ethernet-phy.patch
+++ /dev/null
@@ -1,147 +0,0 @@
-From 96edc2f71ea7ac6683011609f6d1f51ae9ea0b7a Mon Sep 17 00:00:00 2001
-From: Frank Sae <Frank.Sae@motor-comm.com>
-Date: Thu, 2 Feb 2023 11:00:33 +0800
-Subject: [PATCH 048/122] dt-bindings: net: Add Motorcomm yt8xxx ethernet phy
-
-Add a YAML binding document for the Motorcomm yt8xxx Ethernet phy.
-
-Signed-off-by: Frank Sae <Frank.Sae@motor-comm.com>
-Reviewed-by: Rob Herring <robh@kernel.org>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- .../bindings/net/motorcomm,yt8xxx.yaml | 117 ++++++++++++++++++
- .../devicetree/bindings/vendor-prefixes.yaml | 2 +
- 2 files changed, 119 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/net/motorcomm,yt8xxx.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/net/motorcomm,yt8xxx.yaml
-@@ -0,0 +1,117 @@
-+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/net/motorcomm,yt8xxx.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: MotorComm yt8xxx Ethernet PHY
-+
-+maintainers:
-+ - Frank Sae <frank.sae@motor-comm.com>
-+
-+allOf:
-+ - $ref: ethernet-phy.yaml#
-+
-+properties:
-+ compatible:
-+ enum:
-+ - ethernet-phy-id4f51.e91a
-+ - ethernet-phy-id4f51.e91b
-+
-+ rx-internal-delay-ps:
-+ description: |
-+ RGMII RX Clock Delay used only when PHY operates in RGMII mode with
-+ internal delay (phy-mode is 'rgmii-id' or 'rgmii-rxid') in pico-seconds.
-+ enum: [ 0, 150, 300, 450, 600, 750, 900, 1050, 1200, 1350, 1500, 1650,
-+ 1800, 1900, 1950, 2050, 2100, 2200, 2250, 2350, 2500, 2650, 2800,
-+ 2950, 3100, 3250, 3400, 3550, 3700, 3850, 4000, 4150 ]
-+ default: 1950
-+
-+ tx-internal-delay-ps:
-+ description: |
-+ RGMII TX Clock Delay used only when PHY operates in RGMII mode with
-+ internal delay (phy-mode is 'rgmii-id' or 'rgmii-txid') in pico-seconds.
-+ enum: [ 0, 150, 300, 450, 600, 750, 900, 1050, 1200, 1350, 1500, 1650, 1800,
-+ 1950, 2100, 2250 ]
-+ default: 1950
-+
-+ motorcomm,clk-out-frequency-hz:
-+ description: clock output on clock output pin.
-+ enum: [0, 25000000, 125000000]
-+ default: 0
-+
-+ motorcomm,keep-pll-enabled:
-+ description: |
-+ If set, keep the PLL enabled even if there is no link. Useful if you
-+ want to use the clock output without an ethernet link.
-+ type: boolean
-+
-+ motorcomm,auto-sleep-disabled:
-+ description: |
-+ If set, PHY will not enter sleep mode and close AFE after unplug cable
-+ for a timer.
-+ type: boolean
-+
-+ motorcomm,tx-clk-adj-enabled:
-+ description: |
-+ This configuration is mainly to adapt to VF2 with JH7110 SoC.
-+ Useful if you want to use tx-clk-xxxx-inverted to adj the delay of tx clk.
-+ type: boolean
-+
-+ motorcomm,tx-clk-10-inverted:
-+ description: |
-+ Use original or inverted RGMII Transmit PHY Clock to drive the RGMII
-+ Transmit PHY Clock delay train configuration when speed is 10Mbps.
-+ type: boolean
-+
-+ motorcomm,tx-clk-100-inverted:
-+ description: |
-+ Use original or inverted RGMII Transmit PHY Clock to drive the RGMII
-+ Transmit PHY Clock delay train configuration when speed is 100Mbps.
-+ type: boolean
-+
-+ motorcomm,tx-clk-1000-inverted:
-+ description: |
-+ Use original or inverted RGMII Transmit PHY Clock to drive the RGMII
-+ Transmit PHY Clock delay train configuration when speed is 1000Mbps.
-+ type: boolean
-+
-+unevaluatedProperties: false
-+
-+examples:
-+ - |
-+ mdio {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ phy-mode = "rgmii-id";
-+ ethernet-phy@4 {
-+ /* Only needed to make DT lint tools work. Do not copy/paste
-+ * into real DTS files.
-+ */
-+ compatible = "ethernet-phy-id4f51.e91a";
-+
-+ reg = <4>;
-+ rx-internal-delay-ps = <2100>;
-+ tx-internal-delay-ps = <150>;
-+ motorcomm,clk-out-frequency-hz = <0>;
-+ motorcomm,keep-pll-enabled;
-+ motorcomm,auto-sleep-disabled;
-+ };
-+ };
-+ - |
-+ mdio {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ phy-mode = "rgmii";
-+ ethernet-phy@5 {
-+ /* Only needed to make DT lint tools work. Do not copy/paste
-+ * into real DTS files.
-+ */
-+ compatible = "ethernet-phy-id4f51.e91a";
-+
-+ reg = <5>;
-+ motorcomm,clk-out-frequency-hz = <125000000>;
-+ motorcomm,keep-pll-enabled;
-+ motorcomm,auto-sleep-disabled;
-+ };
-+ };
---- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
-+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
-@@ -831,6 +831,8 @@ patternProperties:
- description: Moortec Semiconductor Ltd.
- "^mosaixtech,.*":
- description: Mosaix Technologies, Inc.
-+ "^motorcomm,.*":
-+ description: MotorComm, Inc.
- "^motorola,.*":
- description: Motorola, Inc.
- "^moxa,.*":
diff --git a/target/linux/starfive/patches-6.1/0049-dt-bindings-net-motorcomm-Add-pad-driver-strength-cf.patch b/target/linux/starfive/patches-6.1/0049-dt-bindings-net-motorcomm-Add-pad-driver-strength-cf.patch
deleted file mode 100644
index b9e9c65251..0000000000
--- a/target/linux/starfive/patches-6.1/0049-dt-bindings-net-motorcomm-Add-pad-driver-strength-cf.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From 2d146c6e550a4fb7f24ca44739cf14594cc2f892 Mon Sep 17 00:00:00 2001
-From: Samin Guo <samin.guo@starfivetech.com>
-Date: Tue, 25 Apr 2023 18:51:15 +0800
-Subject: [PATCH 049/122] dt-bindings: net: motorcomm: Add pad driver strength
- cfg
-
-The motorcomm phy (YT8531) supports the ability to adjust the drive
-strength of the rx_clk/rx_data, the value range of pad driver
-strength is 0 to 7.
-
-Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
----
- .../devicetree/bindings/net/motorcomm,yt8xxx.yaml | 10 ++++++++++
- 1 file changed, 10 insertions(+)
-
---- a/Documentation/devicetree/bindings/net/motorcomm,yt8xxx.yaml
-+++ b/Documentation/devicetree/bindings/net/motorcomm,yt8xxx.yaml
-@@ -18,6 +18,16 @@ properties:
- - ethernet-phy-id4f51.e91a
- - ethernet-phy-id4f51.e91b
-
-+ rx-clk-driver-strength:
-+ description: drive strength of rx_clk pad.
-+ enum: [ 0, 1, 2, 3, 4, 5, 6, 7 ]
-+ default: 3
-+
-+ rx-data-driver-strength:
-+ description: drive strength of rxd/rx_ctl rgmii pad.
-+ enum: [ 0, 1, 2, 3, 4, 5, 6, 7 ]
-+ default: 3
-+
- rx-internal-delay-ps:
- description: |
- RGMII RX Clock Delay used only when PHY operates in RGMII mode with
diff --git a/target/linux/starfive/patches-6.1/0050-riscv-dts-starfive-visionfive-2-v1.3B-Set-the-driver.patch b/target/linux/starfive/patches-6.1/0050-riscv-dts-starfive-visionfive-2-v1.3B-Set-the-driver.patch
deleted file mode 100644
index 8dca72ad16..0000000000
--- a/target/linux/starfive/patches-6.1/0050-riscv-dts-starfive-visionfive-2-v1.3B-Set-the-driver.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From c156cb9ec64669600c96dbb01bf38dd2370b1850 Mon Sep 17 00:00:00 2001
-From: Samin Guo <samin.guo@starfivetech.com>
-Date: Wed, 26 Apr 2023 14:41:12 +0800
-Subject: [PATCH 050/122] riscv: dts: starfive: visionfive-2-v1.3B: Set the
- driver strength of RXC/RXD
-
-VisionFive 2 v1.3B needs to increase the driver strength of rxd/rxc
-to increase the stability of gmac's transmission.
-
-Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
----
- .../boot/dts/starfive/jh7110-starfive-visionfive-2-v1.3b.dts | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-v1.3b.dts
-+++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-v1.3b.dts
-@@ -28,6 +28,8 @@
- motorcomm,tx-clk-adj-enabled;
- motorcomm,tx-clk-100-inverted;
- motorcomm,tx-clk-1000-inverted;
-+ rx-clk-driver-strength = <0x6>;
-+ rx-data-driver-strength = <0x3>;
- rx-internal-delay-ps = <1500>;
- tx-internal-delay-ps = <1500>;
- };
-@@ -35,6 +37,8 @@
- &phy1 {
- motorcomm,tx-clk-adj-enabled;
- motorcomm,tx-clk-100-inverted;
-+ rx-clk-driver-strength = <0x6>;
-+ rx-data-driver-strength = <0x3>;
- rx-internal-delay-ps = <300>;
- tx-internal-delay-ps = <0>;
- };
diff --git a/target/linux/starfive/patches-6.1/0051-dt-bindings-clock-Add-StarFive-JH7110-System-Top-Gro.patch b/target/linux/starfive/patches-6.1/0051-dt-bindings-clock-Add-StarFive-JH7110-System-Top-Gro.patch
deleted file mode 100644
index 6617e79965..0000000000
--- a/target/linux/starfive/patches-6.1/0051-dt-bindings-clock-Add-StarFive-JH7110-System-Top-Gro.patch
+++ /dev/null
@@ -1,193 +0,0 @@
-From 84575863e4cf1a5dd877a11d31115c19004ac36a Mon Sep 17 00:00:00 2001
-From: Xingyu Wu <xingyu.wu@starfivetech.com>
-Date: Thu, 18 May 2023 18:12:24 +0800
-Subject: [PATCH 051/122] dt-bindings: clock: Add StarFive JH7110
- System-Top-Group clock and reset generator
-
-Add bindings for the System-Top-Group clock and reset generator (STGCRG)
-on the JH7110 RISC-V SoC by StarFive Ltd.
-
-Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
----
- .../clock/starfive,jh7110-stgcrg.yaml | 82 +++++++++++++++++++
- .../dt-bindings/clock/starfive,jh7110-crg.h | 34 ++++++++
- .../dt-bindings/reset/starfive,jh7110-crg.h | 28 +++++++
- 3 files changed, 144 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/clock/starfive,jh7110-stgcrg.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/clock/starfive,jh7110-stgcrg.yaml
-@@ -0,0 +1,82 @@
-+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/clock/starfive,jh7110-stgcrg.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: StarFive JH7110 System-Top-Group Clock and Reset Generator
-+
-+maintainers:
-+ - Xingyu Wu <xingyu.wu@starfivetech.com>
-+
-+properties:
-+ compatible:
-+ const: starfive,jh7110-stgcrg
-+
-+ reg:
-+ maxItems: 1
-+
-+ clocks:
-+ items:
-+ - description: Main Oscillator (24 MHz)
-+ - description: HIFI4 core
-+ - description: STG AXI/AHB
-+ - description: USB (125 MHz)
-+ - description: CPU Bus
-+ - description: HIFI4 Axi
-+ - description: NOC STG Bus
-+ - description: APB Bus
-+
-+ clock-names:
-+ items:
-+ - const: osc
-+ - const: hifi4_core
-+ - const: stg_axiahb
-+ - const: usb_125m
-+ - const: cpu_bus
-+ - const: hifi4_axi
-+ - const: nocstg_bus
-+ - const: apb_bus
-+
-+ '#clock-cells':
-+ const: 1
-+ description:
-+ See <dt-bindings/clock/starfive,jh7110-crg.h> for valid indices.
-+
-+ '#reset-cells':
-+ const: 1
-+ description:
-+ See <dt-bindings/reset/starfive,jh7110-crg.h> for valid indices.
-+
-+required:
-+ - compatible
-+ - reg
-+ - clocks
-+ - clock-names
-+ - '#clock-cells'
-+ - '#reset-cells'
-+
-+additionalProperties: false
-+
-+examples:
-+ - |
-+ #include <dt-bindings/clock/starfive,jh7110-crg.h>
-+
-+ stgcrg: clock-controller@10230000 {
-+ compatible = "starfive,jh7110-stgcrg";
-+ reg = <0x10230000 0x10000>;
-+ clocks = <&osc>,
-+ <&syscrg JH7110_SYSCLK_HIFI4_CORE>,
-+ <&syscrg JH7110_SYSCLK_STG_AXIAHB>,
-+ <&syscrg JH7110_SYSCLK_USB_125M>,
-+ <&syscrg JH7110_SYSCLK_CPU_BUS>,
-+ <&syscrg JH7110_SYSCLK_HIFI4_AXI>,
-+ <&syscrg JH7110_SYSCLK_NOCSTG_BUS>,
-+ <&syscrg JH7110_SYSCLK_APB_BUS>;
-+ clock-names = "osc", "hifi4_core",
-+ "stg_axiahb", "usb_125m",
-+ "cpu_bus", "hifi4_axi",
-+ "nocstg_bus", "apb_bus";
-+ #clock-cells = <1>;
-+ #reset-cells = <1>;
-+ };
---- a/include/dt-bindings/clock/starfive,jh7110-crg.h
-+++ b/include/dt-bindings/clock/starfive,jh7110-crg.h
-@@ -1,6 +1,7 @@
- /* SPDX-License-Identifier: GPL-2.0 OR MIT */
- /*
- * Copyright 2022 Emil Renner Berthing <kernel@esmil.dk>
-+ * Copyright 2022 StarFive Technology Co., Ltd.
- */
-
- #ifndef __DT_BINDINGS_CLOCK_STARFIVE_JH7110_CRG_H__
-@@ -224,4 +225,37 @@
-
- #define JH7110_AONCLK_END 14
-
-+/* STGCRG clocks */
-+#define JH7110_STGCLK_HIFI4_CLK_CORE 0
-+#define JH7110_STGCLK_USB0_APB 1
-+#define JH7110_STGCLK_USB0_UTMI_APB 2
-+#define JH7110_STGCLK_USB0_AXI 3
-+#define JH7110_STGCLK_USB0_LPM 4
-+#define JH7110_STGCLK_USB0_STB 5
-+#define JH7110_STGCLK_USB0_APP_125 6
-+#define JH7110_STGCLK_USB0_REFCLK 7
-+#define JH7110_STGCLK_PCIE0_AXI_MST0 8
-+#define JH7110_STGCLK_PCIE0_APB 9
-+#define JH7110_STGCLK_PCIE0_TL 10
-+#define JH7110_STGCLK_PCIE1_AXI_MST0 11
-+#define JH7110_STGCLK_PCIE1_APB 12
-+#define JH7110_STGCLK_PCIE1_TL 13
-+#define JH7110_STGCLK_PCIE_SLV_MAIN 14
-+#define JH7110_STGCLK_SEC_AHB 15
-+#define JH7110_STGCLK_SEC_MISC_AHB 16
-+#define JH7110_STGCLK_GRP0_MAIN 17
-+#define JH7110_STGCLK_GRP0_BUS 18
-+#define JH7110_STGCLK_GRP0_STG 19
-+#define JH7110_STGCLK_GRP1_MAIN 20
-+#define JH7110_STGCLK_GRP1_BUS 21
-+#define JH7110_STGCLK_GRP1_STG 22
-+#define JH7110_STGCLK_GRP1_HIFI 23
-+#define JH7110_STGCLK_E2_RTC 24
-+#define JH7110_STGCLK_E2_CORE 25
-+#define JH7110_STGCLK_E2_DBG 26
-+#define JH7110_STGCLK_DMA1P_AXI 27
-+#define JH7110_STGCLK_DMA1P_AHB 28
-+
-+#define JH7110_STGCLK_END 29
-+
- #endif /* __DT_BINDINGS_CLOCK_STARFIVE_JH7110_CRG_H__ */
---- a/include/dt-bindings/reset/starfive,jh7110-crg.h
-+++ b/include/dt-bindings/reset/starfive,jh7110-crg.h
-@@ -1,6 +1,7 @@
- /* SPDX-License-Identifier: GPL-2.0 OR MIT */
- /*
- * Copyright (C) 2022 Emil Renner Berthing <kernel@esmil.dk>
-+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
- */
-
- #ifndef __DT_BINDINGS_RESET_STARFIVE_JH7110_CRG_H__
-@@ -151,4 +152,31 @@
-
- #define JH7110_AONRST_END 8
-
-+/* STGCRG resets */
-+#define JH7110_STGRST_SYSCON 0
-+#define JH7110_STGRST_HIFI4_CORE 1
-+#define JH7110_STGRST_HIFI4_AXI 2
-+#define JH7110_STGRST_SEC_AHB 3
-+#define JH7110_STGRST_E24_CORE 4
-+#define JH7110_STGRST_DMA1P_AXI 5
-+#define JH7110_STGRST_DMA1P_AHB 6
-+#define JH7110_STGRST_USB0_AXI 7
-+#define JH7110_STGRST_USB0_APB 8
-+#define JH7110_STGRST_USB0_UTMI_APB 9
-+#define JH7110_STGRST_USB0_PWRUP 10
-+#define JH7110_STGRST_PCIE0_AXI_MST0 11
-+#define JH7110_STGRST_PCIE0_AXI_SLV0 12
-+#define JH7110_STGRST_PCIE0_AXI_SLV 13
-+#define JH7110_STGRST_PCIE0_BRG 14
-+#define JH7110_STGRST_PCIE0_CORE 15
-+#define JH7110_STGRST_PCIE0_APB 16
-+#define JH7110_STGRST_PCIE1_AXI_MST0 17
-+#define JH7110_STGRST_PCIE1_AXI_SLV0 18
-+#define JH7110_STGRST_PCIE1_AXI_SLV 19
-+#define JH7110_STGRST_PCIE1_BRG 20
-+#define JH7110_STGRST_PCIE1_CORE 21
-+#define JH7110_STGRST_PCIE1_APB 22
-+
-+#define JH7110_STGRST_END 23
-+
- #endif /* __DT_BINDINGS_RESET_STARFIVE_JH7110_CRG_H__ */
diff --git a/target/linux/starfive/patches-6.1/0052-clk-starfive-Add-StarFive-JH7110-System-Top-Group-cl.patch b/target/linux/starfive/patches-6.1/0052-clk-starfive-Add-StarFive-JH7110-System-Top-Group-cl.patch
deleted file mode 100644
index 88b24a9c6d..0000000000
--- a/target/linux/starfive/patches-6.1/0052-clk-starfive-Add-StarFive-JH7110-System-Top-Group-cl.patch
+++ /dev/null
@@ -1,218 +0,0 @@
-From 9a02d66b0515d987037d0229b99367412b9eb38c Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <emil.renner.berthing@canonical.com>
-Date: Thu, 18 May 2023 18:12:25 +0800
-Subject: [PATCH 052/122] clk: starfive: Add StarFive JH7110 System-Top-Group
- clock driver
-
-Add driver for the StarFive JH7110 System-Top-Group clock controller.
-
-Co-developed-by: Xingyu Wu <xingyu.wu@starfivetech.com>
-Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
-Signed-off-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
----
- drivers/clk/starfive/Kconfig | 11 ++
- drivers/clk/starfive/Makefile | 1 +
- .../clk/starfive/clk-starfive-jh7110-stg.c | 173 ++++++++++++++++++
- 3 files changed, 185 insertions(+)
- create mode 100644 drivers/clk/starfive/clk-starfive-jh7110-stg.c
-
---- a/drivers/clk/starfive/Kconfig
-+++ b/drivers/clk/starfive/Kconfig
-@@ -51,3 +51,14 @@ config CLK_STARFIVE_JH7110_AON
- help
- Say yes here to support the always-on clock controller on the
- StarFive JH7110 SoC.
-+
-+config CLK_STARFIVE_JH7110_STG
-+ tristate "StarFive JH7110 System-Top-Group clock support"
-+ depends on CLK_STARFIVE_JH7110_SYS
-+ select AUXILIARY_BUS
-+ select CLK_STARFIVE_JH71X0
-+ select RESET_STARFIVE_JH7110
-+ default m if ARCH_STARFIVE
-+ help
-+ Say yes here to support the System-Top-Group clock controller
-+ on the StarFive JH7110 SoC.
---- a/drivers/clk/starfive/Makefile
-+++ b/drivers/clk/starfive/Makefile
-@@ -7,3 +7,4 @@ obj-$(CONFIG_CLK_STARFIVE_JH7100_AUDIO)
- obj-$(CONFIG_CLK_STARFIVE_JH7110_PLL) += clk-starfive-jh7110-pll.o
- obj-$(CONFIG_CLK_STARFIVE_JH7110_SYS) += clk-starfive-jh7110-sys.o
- obj-$(CONFIG_CLK_STARFIVE_JH7110_AON) += clk-starfive-jh7110-aon.o
-+obj-$(CONFIG_CLK_STARFIVE_JH7110_STG) += clk-starfive-jh7110-stg.o
---- /dev/null
-+++ b/drivers/clk/starfive/clk-starfive-jh7110-stg.c
-@@ -0,0 +1,173 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * StarFive JH7110 System-Top-Group Clock Driver
-+ *
-+ * Copyright (C) 2022 Emil Renner Berthing <kernel@esmil.dk>
-+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
-+ */
-+
-+#include <linux/clk-provider.h>
-+#include <linux/io.h>
-+#include <linux/platform_device.h>
-+
-+#include <dt-bindings/clock/starfive,jh7110-crg.h>
-+
-+#include "clk-starfive-jh7110.h"
-+
-+/* external clocks */
-+#define JH7110_STGCLK_OSC (JH7110_STGCLK_END + 0)
-+#define JH7110_STGCLK_HIFI4_CORE (JH7110_STGCLK_END + 1)
-+#define JH7110_STGCLK_STG_AXIAHB (JH7110_STGCLK_END + 2)
-+#define JH7110_STGCLK_USB_125M (JH7110_STGCLK_END + 3)
-+#define JH7110_STGCLK_CPU_BUS (JH7110_STGCLK_END + 4)
-+#define JH7110_STGCLK_HIFI4_AXI (JH7110_STGCLK_END + 5)
-+#define JH7110_STGCLK_NOCSTG_BUS (JH7110_STGCLK_END + 6)
-+#define JH7110_STGCLK_APB_BUS (JH7110_STGCLK_END + 7)
-+#define JH7110_STGCLK_EXT_END (JH7110_STGCLK_END + 8)
-+
-+static const struct jh71x0_clk_data jh7110_stgclk_data[] = {
-+ /* hifi4 */
-+ JH71X0_GATE(JH7110_STGCLK_HIFI4_CLK_CORE, "hifi4_clk_core", 0,
-+ JH7110_STGCLK_HIFI4_CORE),
-+ /* usb */
-+ JH71X0_GATE(JH7110_STGCLK_USB0_APB, "usb0_apb", 0, JH7110_STGCLK_APB_BUS),
-+ JH71X0_GATE(JH7110_STGCLK_USB0_UTMI_APB, "usb0_utmi_apb", 0, JH7110_STGCLK_APB_BUS),
-+ JH71X0_GATE(JH7110_STGCLK_USB0_AXI, "usb0_axi", 0, JH7110_STGCLK_STG_AXIAHB),
-+ JH71X0_GDIV(JH7110_STGCLK_USB0_LPM, "usb0_lpm", 0, 2, JH7110_STGCLK_OSC),
-+ JH71X0_GDIV(JH7110_STGCLK_USB0_STB, "usb0_stb", 0, 4, JH7110_STGCLK_OSC),
-+ JH71X0_GATE(JH7110_STGCLK_USB0_APP_125, "usb0_app_125", 0, JH7110_STGCLK_USB_125M),
-+ JH71X0__DIV(JH7110_STGCLK_USB0_REFCLK, "usb0_refclk", 2, JH7110_STGCLK_OSC),
-+ /* pci-e */
-+ JH71X0_GATE(JH7110_STGCLK_PCIE0_AXI_MST0, "pcie0_axi_mst0", 0,
-+ JH7110_STGCLK_STG_AXIAHB),
-+ JH71X0_GATE(JH7110_STGCLK_PCIE0_APB, "pcie0_apb", 0, JH7110_STGCLK_APB_BUS),
-+ JH71X0_GATE(JH7110_STGCLK_PCIE0_TL, "pcie0_tl", 0, JH7110_STGCLK_STG_AXIAHB),
-+ JH71X0_GATE(JH7110_STGCLK_PCIE1_AXI_MST0, "pcie1_axi_mst0", 0,
-+ JH7110_STGCLK_STG_AXIAHB),
-+ JH71X0_GATE(JH7110_STGCLK_PCIE1_APB, "pcie1_apb", 0, JH7110_STGCLK_APB_BUS),
-+ JH71X0_GATE(JH7110_STGCLK_PCIE1_TL, "pcie1_tl", 0, JH7110_STGCLK_STG_AXIAHB),
-+ JH71X0_GATE(JH7110_STGCLK_PCIE_SLV_MAIN, "pcie_slv_main", CLK_IS_CRITICAL,
-+ JH7110_STGCLK_STG_AXIAHB),
-+ /* security */
-+ JH71X0_GATE(JH7110_STGCLK_SEC_AHB, "sec_ahb", 0, JH7110_STGCLK_STG_AXIAHB),
-+ JH71X0_GATE(JH7110_STGCLK_SEC_MISC_AHB, "sec_misc_ahb", 0, JH7110_STGCLK_STG_AXIAHB),
-+ /* stg mtrx */
-+ JH71X0_GATE(JH7110_STGCLK_GRP0_MAIN, "mtrx_grp0_main", CLK_IS_CRITICAL,
-+ JH7110_STGCLK_CPU_BUS),
-+ JH71X0_GATE(JH7110_STGCLK_GRP0_BUS, "mtrx_grp0_bus", CLK_IS_CRITICAL,
-+ JH7110_STGCLK_NOCSTG_BUS),
-+ JH71X0_GATE(JH7110_STGCLK_GRP0_STG, "mtrx_grp0_stg", CLK_IS_CRITICAL,
-+ JH7110_STGCLK_STG_AXIAHB),
-+ JH71X0_GATE(JH7110_STGCLK_GRP1_MAIN, "mtrx_grp1_main", CLK_IS_CRITICAL,
-+ JH7110_STGCLK_CPU_BUS),
-+ JH71X0_GATE(JH7110_STGCLK_GRP1_BUS, "mtrx_grp1_bus", CLK_IS_CRITICAL,
-+ JH7110_STGCLK_NOCSTG_BUS),
-+ JH71X0_GATE(JH7110_STGCLK_GRP1_STG, "mtrx_grp1_stg", CLK_IS_CRITICAL,
-+ JH7110_STGCLK_STG_AXIAHB),
-+ JH71X0_GATE(JH7110_STGCLK_GRP1_HIFI, "mtrx_grp1_hifi", CLK_IS_CRITICAL,
-+ JH7110_STGCLK_HIFI4_AXI),
-+ /* e24_rvpi */
-+ JH71X0_GDIV(JH7110_STGCLK_E2_RTC, "e2_rtc", 0, 24, JH7110_STGCLK_OSC),
-+ JH71X0_GATE(JH7110_STGCLK_E2_CORE, "e2_core", 0, JH7110_STGCLK_STG_AXIAHB),
-+ JH71X0_GATE(JH7110_STGCLK_E2_DBG, "e2_dbg", 0, JH7110_STGCLK_STG_AXIAHB),
-+ /* dw_sgdma1p */
-+ JH71X0_GATE(JH7110_STGCLK_DMA1P_AXI, "dma1p_axi", 0, JH7110_STGCLK_STG_AXIAHB),
-+ JH71X0_GATE(JH7110_STGCLK_DMA1P_AHB, "dma1p_ahb", 0, JH7110_STGCLK_STG_AXIAHB),
-+};
-+
-+static struct clk_hw *jh7110_stgclk_get(struct of_phandle_args *clkspec, void *data)
-+{
-+ struct jh71x0_clk_priv *priv = data;
-+ unsigned int idx = clkspec->args[0];
-+
-+ if (idx < JH7110_STGCLK_END)
-+ return &priv->reg[idx].hw;
-+
-+ return ERR_PTR(-EINVAL);
-+}
-+
-+static int jh7110_stgcrg_probe(struct platform_device *pdev)
-+{
-+ struct jh71x0_clk_priv *priv;
-+ unsigned int idx;
-+ int ret;
-+
-+ priv = devm_kzalloc(&pdev->dev, struct_size(priv, reg, JH7110_STGCLK_END),
-+ GFP_KERNEL);
-+ if (!priv)
-+ return -ENOMEM;
-+
-+ spin_lock_init(&priv->rmw_lock);
-+ priv->dev = &pdev->dev;
-+ priv->base = devm_platform_ioremap_resource(pdev, 0);
-+ if (IS_ERR(priv->base))
-+ return PTR_ERR(priv->base);
-+
-+ for (idx = 0; idx < JH7110_STGCLK_END; idx++) {
-+ u32 max = jh7110_stgclk_data[idx].max;
-+ struct clk_parent_data parents[4] = {};
-+ struct clk_init_data init = {
-+ .name = jh7110_stgclk_data[idx].name,
-+ .ops = starfive_jh71x0_clk_ops(max),
-+ .parent_data = parents,
-+ .num_parents =
-+ ((max & JH71X0_CLK_MUX_MASK) >> JH71X0_CLK_MUX_SHIFT) + 1,
-+ .flags = jh7110_stgclk_data[idx].flags,
-+ };
-+ struct jh71x0_clk *clk = &priv->reg[idx];
-+ const char *fw_name[JH7110_STGCLK_EXT_END - JH7110_STGCLK_END] = {
-+ "osc",
-+ "hifi4_core",
-+ "stg_axiahb",
-+ "usb_125m",
-+ "cpu_bus",
-+ "hifi4_axi",
-+ "nocstg_bus",
-+ "apb_bus"
-+ };
-+ unsigned int i;
-+
-+ for (i = 0; i < init.num_parents; i++) {
-+ unsigned int pidx = jh7110_stgclk_data[idx].parents[i];
-+
-+ if (pidx < JH7110_STGCLK_END)
-+ parents[i].hw = &priv->reg[pidx].hw;
-+ else if (pidx < JH7110_STGCLK_EXT_END)
-+ parents[i].fw_name = fw_name[pidx - JH7110_STGCLK_END];
-+ }
-+
-+ clk->hw.init = &init;
-+ clk->idx = idx;
-+ clk->max_div = max & JH71X0_CLK_DIV_MASK;
-+
-+ ret = devm_clk_hw_register(&pdev->dev, &clk->hw);
-+ if (ret)
-+ return ret;
-+ }
-+
-+ ret = devm_of_clk_add_hw_provider(&pdev->dev, jh7110_stgclk_get, priv);
-+ if (ret)
-+ return ret;
-+
-+ return jh7110_reset_controller_register(priv, "rst-stg", 2);
-+}
-+
-+static const struct of_device_id jh7110_stgcrg_match[] = {
-+ { .compatible = "starfive,jh7110-stgcrg" },
-+ { /* sentinel */ }
-+};
-+MODULE_DEVICE_TABLE(of, jh7110_stgcrg_match);
-+
-+static struct platform_driver jh7110_stgcrg_driver = {
-+ .probe = jh7110_stgcrg_probe,
-+ .driver = {
-+ .name = "clk-starfive-jh7110-stg",
-+ .of_match_table = jh7110_stgcrg_match,
-+ },
-+};
-+module_platform_driver(jh7110_stgcrg_driver);
-+
-+MODULE_AUTHOR("Xingyu Wu <xingyu.wu@starfivetech.com>");
-+MODULE_AUTHOR("Emil Renner Berthing <kernel@esmil.dk>");
-+MODULE_DESCRIPTION("StarFive JH7110 System-Top-Group clock driver");
-+MODULE_LICENSE("GPL");
diff --git a/target/linux/starfive/patches-6.1/0053-dt-bindings-clock-Add-StarFive-JH7110-Image-Signal-P.patch b/target/linux/starfive/patches-6.1/0053-dt-bindings-clock-Add-StarFive-JH7110-Image-Signal-P.patch
deleted file mode 100644
index eda4a0280a..0000000000
--- a/target/linux/starfive/patches-6.1/0053-dt-bindings-clock-Add-StarFive-JH7110-Image-Signal-P.patch
+++ /dev/null
@@ -1,156 +0,0 @@
-From 70df2590923e262ce8bf2b4f497f3481511d4fd6 Mon Sep 17 00:00:00 2001
-From: Xingyu Wu <xingyu.wu@starfivetech.com>
-Date: Thu, 18 May 2023 18:12:26 +0800
-Subject: [PATCH 053/122] dt-bindings: clock: Add StarFive JH7110
- Image-Signal-Process clock and reset generator
-
-Add bindings for the Image-Signal-Process clock and reset
-generator (ISPCRG) on the JH7110 RISC-V SoC by StarFive Ltd.
-
-Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
----
- .../clock/starfive,jh7110-ispcrg.yaml | 87 +++++++++++++++++++
- .../dt-bindings/clock/starfive,jh7110-crg.h | 18 ++++
- .../dt-bindings/reset/starfive,jh7110-crg.h | 16 ++++
- 3 files changed, 121 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/clock/starfive,jh7110-ispcrg.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/clock/starfive,jh7110-ispcrg.yaml
-@@ -0,0 +1,87 @@
-+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/clock/starfive,jh7110-ispcrg.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: StarFive JH7110 Image-Signal-Process Clock and Reset Generator
-+
-+maintainers:
-+ - Xingyu Wu <xingyu.wu@starfivetech.com>
-+
-+properties:
-+ compatible:
-+ const: starfive,jh7110-ispcrg
-+
-+ reg:
-+ maxItems: 1
-+
-+ clocks:
-+ items:
-+ - description: ISP Top core
-+ - description: ISP Top Axi
-+ - description: NOC ISP Bus
-+ - description: external DVP
-+
-+ clock-names:
-+ items:
-+ - const: isp_top_core
-+ - const: isp_top_axi
-+ - const: noc_bus_isp_axi
-+ - const: dvp_clk
-+
-+ resets:
-+ items:
-+ - description: ISP Top core
-+ - description: ISP Top Axi
-+ - description: NOC ISP Bus
-+
-+ '#clock-cells':
-+ const: 1
-+ description:
-+ See <dt-bindings/clock/starfive,jh7110-crg.h> for valid indices.
-+
-+ '#reset-cells':
-+ const: 1
-+ description:
-+ See <dt-bindings/reset/starfive,jh7110-crg.h> for valid indices.
-+
-+ power-domains:
-+ maxItems: 1
-+ description:
-+ ISP domain power
-+
-+required:
-+ - compatible
-+ - reg
-+ - clocks
-+ - clock-names
-+ - resets
-+ - '#clock-cells'
-+ - '#reset-cells'
-+ - power-domains
-+
-+additionalProperties: false
-+
-+examples:
-+ - |
-+ #include <dt-bindings/clock/starfive,jh7110-crg.h>
-+ #include <dt-bindings/power/starfive,jh7110-pmu.h>
-+ #include <dt-bindings/reset/starfive,jh7110-crg.h>
-+
-+ ispcrg: clock-controller@19810000 {
-+ compatible = "starfive,jh7110-ispcrg";
-+ reg = <0x19810000 0x10000>;
-+ clocks = <&syscrg JH7110_SYSCLK_ISP_TOP_CORE>,
-+ <&syscrg JH7110_SYSCLK_ISP_TOP_AXI>,
-+ <&syscrg JH7110_SYSCLK_NOC_BUS_ISP_AXI>,
-+ <&dvp_clk>;
-+ clock-names = "isp_top_core", "isp_top_axi",
-+ "noc_bus_isp_axi", "dvp_clk";
-+ resets = <&syscrg JH7110_SYSRST_ISP_TOP>,
-+ <&syscrg JH7110_SYSRST_ISP_TOP_AXI>,
-+ <&syscrg JH7110_SYSRST_NOC_BUS_ISP_AXI>;
-+ #clock-cells = <1>;
-+ #reset-cells = <1>;
-+ power-domains = <&pwrc JH7110_PD_ISP>;
-+ };
---- a/include/dt-bindings/clock/starfive,jh7110-crg.h
-+++ b/include/dt-bindings/clock/starfive,jh7110-crg.h
-@@ -258,4 +258,22 @@
-
- #define JH7110_STGCLK_END 29
-
-+/* ISPCRG clocks */
-+#define JH7110_ISPCLK_DOM4_APB_FUNC 0
-+#define JH7110_ISPCLK_MIPI_RX0_PXL 1
-+#define JH7110_ISPCLK_DVP_INV 2
-+#define JH7110_ISPCLK_M31DPHY_CFG_IN 3
-+#define JH7110_ISPCLK_M31DPHY_REF_IN 4
-+#define JH7110_ISPCLK_M31DPHY_TX_ESC_LAN0 5
-+#define JH7110_ISPCLK_VIN_APB 6
-+#define JH7110_ISPCLK_VIN_SYS 7
-+#define JH7110_ISPCLK_VIN_PIXEL_IF0 8
-+#define JH7110_ISPCLK_VIN_PIXEL_IF1 9
-+#define JH7110_ISPCLK_VIN_PIXEL_IF2 10
-+#define JH7110_ISPCLK_VIN_PIXEL_IF3 11
-+#define JH7110_ISPCLK_VIN_P_AXI_WR 12
-+#define JH7110_ISPCLK_ISPV2_TOP_WRAPPER_C 13
-+
-+#define JH7110_ISPCLK_END 14
-+
- #endif /* __DT_BINDINGS_CLOCK_STARFIVE_JH7110_CRG_H__ */
---- a/include/dt-bindings/reset/starfive,jh7110-crg.h
-+++ b/include/dt-bindings/reset/starfive,jh7110-crg.h
-@@ -179,4 +179,20 @@
-
- #define JH7110_STGRST_END 23
-
-+/* ISPCRG resets */
-+#define JH7110_ISPRST_ISPV2_TOP_WRAPPER_P 0
-+#define JH7110_ISPRST_ISPV2_TOP_WRAPPER_C 1
-+#define JH7110_ISPRST_M31DPHY_HW 2
-+#define JH7110_ISPRST_M31DPHY_B09_AON 3
-+#define JH7110_ISPRST_VIN_APB 4
-+#define JH7110_ISPRST_VIN_PIXEL_IF0 5
-+#define JH7110_ISPRST_VIN_PIXEL_IF1 6
-+#define JH7110_ISPRST_VIN_PIXEL_IF2 7
-+#define JH7110_ISPRST_VIN_PIXEL_IF3 8
-+#define JH7110_ISPRST_VIN_SYS 9
-+#define JH7110_ISPRST_VIN_P_AXI_RD 10
-+#define JH7110_ISPRST_VIN_P_AXI_WR 11
-+
-+#define JH7110_ISPRST_END 12
-+
- #endif /* __DT_BINDINGS_RESET_STARFIVE_JH7110_CRG_H__ */
diff --git a/target/linux/starfive/patches-6.1/0054-clk-starfive-Add-StarFive-JH7110-Image-Signal-Proces.patch b/target/linux/starfive/patches-6.1/0054-clk-starfive-Add-StarFive-JH7110-Image-Signal-Proces.patch
deleted file mode 100644
index 2e049e77dd..0000000000
--- a/target/linux/starfive/patches-6.1/0054-clk-starfive-Add-StarFive-JH7110-Image-Signal-Proces.patch
+++ /dev/null
@@ -1,293 +0,0 @@
-From 003c13d81b525a184c5ca551e536e6786e2d2f5c Mon Sep 17 00:00:00 2001
-From: Xingyu Wu <xingyu.wu@starfivetech.com>
-Date: Thu, 18 May 2023 18:12:27 +0800
-Subject: [PATCH 054/122] clk: starfive: Add StarFive JH7110
- Image-Signal-Process clock driver
-
-Add driver for the StarFive JH7110 Image-Signal-Process clock controller.
-And these clock controllers should power on and enable the clocks from
-SYSCRG first before registering.
-
-Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
----
- drivers/clk/starfive/Kconfig | 11 +
- drivers/clk/starfive/Makefile | 1 +
- .../clk/starfive/clk-starfive-jh7110-isp.c | 232 ++++++++++++++++++
- drivers/clk/starfive/clk-starfive-jh7110.h | 6 +
- 4 files changed, 250 insertions(+)
- create mode 100644 drivers/clk/starfive/clk-starfive-jh7110-isp.c
-
---- a/drivers/clk/starfive/Kconfig
-+++ b/drivers/clk/starfive/Kconfig
-@@ -62,3 +62,14 @@ config CLK_STARFIVE_JH7110_STG
- help
- Say yes here to support the System-Top-Group clock controller
- on the StarFive JH7110 SoC.
-+
-+config CLK_STARFIVE_JH7110_ISP
-+ tristate "StarFive JH7110 Image-Signal-Process clock support"
-+ depends on CLK_STARFIVE_JH7110_SYS && JH71XX_PMU
-+ select AUXILIARY_BUS
-+ select CLK_STARFIVE_JH71X0
-+ select RESET_STARFIVE_JH7110
-+ default m if ARCH_STARFIVE
-+ help
-+ Say yes here to support the Image-Signal-Process clock controller
-+ on the StarFive JH7110 SoC.
---- a/drivers/clk/starfive/Makefile
-+++ b/drivers/clk/starfive/Makefile
-@@ -8,3 +8,4 @@ obj-$(CONFIG_CLK_STARFIVE_JH7110_PLL) +=
- obj-$(CONFIG_CLK_STARFIVE_JH7110_SYS) += clk-starfive-jh7110-sys.o
- obj-$(CONFIG_CLK_STARFIVE_JH7110_AON) += clk-starfive-jh7110-aon.o
- obj-$(CONFIG_CLK_STARFIVE_JH7110_STG) += clk-starfive-jh7110-stg.o
-+obj-$(CONFIG_CLK_STARFIVE_JH7110_ISP) += clk-starfive-jh7110-isp.o
---- /dev/null
-+++ b/drivers/clk/starfive/clk-starfive-jh7110-isp.c
-@@ -0,0 +1,232 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * StarFive JH7110 Image-Signal-Process Clock Driver
-+ *
-+ * Copyright (C) 2022-2023 StarFive Technology Co., Ltd.
-+ */
-+
-+#include <linux/clk.h>
-+#include <linux/clk-provider.h>
-+#include <linux/io.h>
-+#include <linux/platform_device.h>
-+#include <linux/pm_runtime.h>
-+#include <linux/reset.h>
-+
-+#include <dt-bindings/clock/starfive,jh7110-crg.h>
-+
-+#include "clk-starfive-jh7110.h"
-+
-+/* external clocks */
-+#define JH7110_ISPCLK_ISP_TOP_CORE (JH7110_ISPCLK_END + 0)
-+#define JH7110_ISPCLK_ISP_TOP_AXI (JH7110_ISPCLK_END + 1)
-+#define JH7110_ISPCLK_NOC_BUS_ISP_AXI (JH7110_ISPCLK_END + 2)
-+#define JH7110_ISPCLK_DVP_CLK (JH7110_ISPCLK_END + 3)
-+#define JH7110_ISPCLK_EXT_END (JH7110_ISPCLK_END + 4)
-+
-+static struct clk_bulk_data jh7110_isp_top_clks[] = {
-+ { .id = "isp_top_core" },
-+ { .id = "isp_top_axi" }
-+};
-+
-+static const struct jh71x0_clk_data jh7110_ispclk_data[] = {
-+ /* syscon */
-+ JH71X0__DIV(JH7110_ISPCLK_DOM4_APB_FUNC, "dom4_apb_func", 15,
-+ JH7110_ISPCLK_ISP_TOP_AXI),
-+ JH71X0__DIV(JH7110_ISPCLK_MIPI_RX0_PXL, "mipi_rx0_pxl", 8,
-+ JH7110_ISPCLK_ISP_TOP_CORE),
-+ JH71X0__INV(JH7110_ISPCLK_DVP_INV, "dvp_inv", JH7110_ISPCLK_DVP_CLK),
-+ /* vin */
-+ JH71X0__DIV(JH7110_ISPCLK_M31DPHY_CFG_IN, "m31dphy_cfg_in", 16,
-+ JH7110_ISPCLK_ISP_TOP_CORE),
-+ JH71X0__DIV(JH7110_ISPCLK_M31DPHY_REF_IN, "m31dphy_ref_in", 16,
-+ JH7110_ISPCLK_ISP_TOP_CORE),
-+ JH71X0__DIV(JH7110_ISPCLK_M31DPHY_TX_ESC_LAN0, "m31dphy_tx_esc_lan0", 60,
-+ JH7110_ISPCLK_ISP_TOP_CORE),
-+ JH71X0_GATE(JH7110_ISPCLK_VIN_APB, "vin_apb", 0,
-+ JH7110_ISPCLK_DOM4_APB_FUNC),
-+ JH71X0__DIV(JH7110_ISPCLK_VIN_SYS, "vin_sys", 8, JH7110_ISPCLK_ISP_TOP_CORE),
-+ JH71X0_GATE(JH7110_ISPCLK_VIN_PIXEL_IF0, "vin_pixel_if0", 0,
-+ JH7110_ISPCLK_MIPI_RX0_PXL),
-+ JH71X0_GATE(JH7110_ISPCLK_VIN_PIXEL_IF1, "vin_pixel_if1", 0,
-+ JH7110_ISPCLK_MIPI_RX0_PXL),
-+ JH71X0_GATE(JH7110_ISPCLK_VIN_PIXEL_IF2, "vin_pixel_if2", 0,
-+ JH7110_ISPCLK_MIPI_RX0_PXL),
-+ JH71X0_GATE(JH7110_ISPCLK_VIN_PIXEL_IF3, "vin_pixel_if3", 0,
-+ JH7110_ISPCLK_MIPI_RX0_PXL),
-+ JH71X0__MUX(JH7110_ISPCLK_VIN_P_AXI_WR, "vin_p_axi_wr", 2,
-+ JH7110_ISPCLK_MIPI_RX0_PXL,
-+ JH7110_ISPCLK_DVP_INV),
-+ /* ispv2_top_wrapper */
-+ JH71X0_GMUX(JH7110_ISPCLK_ISPV2_TOP_WRAPPER_C, "ispv2_top_wrapper_c", 0, 2,
-+ JH7110_ISPCLK_MIPI_RX0_PXL,
-+ JH7110_ISPCLK_DVP_INV),
-+};
-+
-+static inline int jh7110_isp_top_rst_init(struct jh71x0_clk_priv *priv)
-+{
-+ struct reset_control *top_rsts;
-+
-+ /* The resets should be shared and other ISP modules will use its. */
-+ top_rsts = devm_reset_control_array_get_shared(priv->dev);
-+ if (IS_ERR(top_rsts))
-+ return dev_err_probe(priv->dev, PTR_ERR(top_rsts),
-+ "failed to get top resets\n");
-+
-+ return reset_control_deassert(top_rsts);
-+}
-+
-+static struct clk_hw *jh7110_ispclk_get(struct of_phandle_args *clkspec, void *data)
-+{
-+ struct jh71x0_clk_priv *priv = data;
-+ unsigned int idx = clkspec->args[0];
-+
-+ if (idx < JH7110_ISPCLK_END)
-+ return &priv->reg[idx].hw;
-+
-+ return ERR_PTR(-EINVAL);
-+}
-+
-+#ifdef CONFIG_PM
-+static int jh7110_ispcrg_suspend(struct device *dev)
-+{
-+ struct top_sysclk *top = dev_get_drvdata(dev);
-+
-+ clk_bulk_disable_unprepare(top->top_clks_num, top->top_clks);
-+
-+ return 0;
-+}
-+
-+static int jh7110_ispcrg_resume(struct device *dev)
-+{
-+ struct top_sysclk *top = dev_get_drvdata(dev);
-+
-+ return clk_bulk_prepare_enable(top->top_clks_num, top->top_clks);
-+}
-+#endif
-+
-+static const struct dev_pm_ops jh7110_ispcrg_pm_ops = {
-+ SET_RUNTIME_PM_OPS(jh7110_ispcrg_suspend, jh7110_ispcrg_resume, NULL)
-+};
-+
-+static int jh7110_ispcrg_probe(struct platform_device *pdev)
-+{
-+ struct jh71x0_clk_priv *priv;
-+ struct top_sysclk *top;
-+ unsigned int idx;
-+ int ret;
-+
-+ priv = devm_kzalloc(&pdev->dev,
-+ struct_size(priv, reg, JH7110_ISPCLK_END),
-+ GFP_KERNEL);
-+ if (!priv)
-+ return -ENOMEM;
-+
-+ top = devm_kzalloc(&pdev->dev, sizeof(*top), GFP_KERNEL);
-+ if (!top)
-+ return -ENOMEM;
-+
-+ spin_lock_init(&priv->rmw_lock);
-+ priv->dev = &pdev->dev;
-+ priv->base = devm_platform_ioremap_resource(pdev, 0);
-+ if (IS_ERR(priv->base))
-+ return PTR_ERR(priv->base);
-+
-+ top->top_clks = jh7110_isp_top_clks;
-+ top->top_clks_num = ARRAY_SIZE(jh7110_isp_top_clks);
-+ ret = devm_clk_bulk_get(priv->dev, top->top_clks_num, top->top_clks);
-+ if (ret)
-+ return dev_err_probe(priv->dev, ret, "failed to get main clocks\n");
-+ dev_set_drvdata(priv->dev, top);
-+
-+ /* enable power domain and clocks */
-+ pm_runtime_enable(priv->dev);
-+ ret = pm_runtime_get_sync(priv->dev);
-+ if (ret < 0)
-+ return dev_err_probe(priv->dev, ret, "failed to turn on power\n");
-+
-+ ret = jh7110_isp_top_rst_init(priv);
-+ if (ret)
-+ goto err_exit;
-+
-+ for (idx = 0; idx < JH7110_ISPCLK_END; idx++) {
-+ u32 max = jh7110_ispclk_data[idx].max;
-+ struct clk_parent_data parents[4] = {};
-+ struct clk_init_data init = {
-+ .name = jh7110_ispclk_data[idx].name,
-+ .ops = starfive_jh71x0_clk_ops(max),
-+ .parent_data = parents,
-+ .num_parents =
-+ ((max & JH71X0_CLK_MUX_MASK) >> JH71X0_CLK_MUX_SHIFT) + 1,
-+ .flags = jh7110_ispclk_data[idx].flags,
-+ };
-+ struct jh71x0_clk *clk = &priv->reg[idx];
-+ unsigned int i;
-+ const char *fw_name[JH7110_ISPCLK_EXT_END - JH7110_ISPCLK_END] = {
-+ "isp_top_core",
-+ "isp_top_axi",
-+ "noc_bus_isp_axi",
-+ "dvp_clk"
-+ };
-+
-+ for (i = 0; i < init.num_parents; i++) {
-+ unsigned int pidx = jh7110_ispclk_data[idx].parents[i];
-+
-+ if (pidx < JH7110_ISPCLK_END)
-+ parents[i].hw = &priv->reg[pidx].hw;
-+ else
-+ parents[i].fw_name = fw_name[pidx - JH7110_ISPCLK_END];
-+ }
-+
-+ clk->hw.init = &init;
-+ clk->idx = idx;
-+ clk->max_div = max & JH71X0_CLK_DIV_MASK;
-+
-+ ret = devm_clk_hw_register(&pdev->dev, &clk->hw);
-+ if (ret)
-+ goto err_exit;
-+ }
-+
-+ ret = devm_of_clk_add_hw_provider(&pdev->dev, jh7110_ispclk_get, priv);
-+ if (ret)
-+ goto err_exit;
-+
-+ ret = jh7110_reset_controller_register(priv, "rst-isp", 3);
-+ if (ret)
-+ goto err_exit;
-+
-+ return 0;
-+
-+err_exit:
-+ pm_runtime_put_sync(priv->dev);
-+ pm_runtime_disable(priv->dev);
-+ return ret;
-+}
-+
-+static int jh7110_ispcrg_remove(struct platform_device *pdev)
-+{
-+ pm_runtime_put_sync(&pdev->dev);
-+ pm_runtime_disable(&pdev->dev);
-+
-+ return 0;
-+}
-+
-+static const struct of_device_id jh7110_ispcrg_match[] = {
-+ { .compatible = "starfive,jh7110-ispcrg" },
-+ { /* sentinel */ }
-+};
-+MODULE_DEVICE_TABLE(of, jh7110_ispcrg_match);
-+
-+static struct platform_driver jh7110_ispcrg_driver = {
-+ .probe = jh7110_ispcrg_probe,
-+ .remove = jh7110_ispcrg_remove,
-+ .driver = {
-+ .name = "clk-starfive-jh7110-isp",
-+ .of_match_table = jh7110_ispcrg_match,
-+ .pm = &jh7110_ispcrg_pm_ops,
-+ },
-+};
-+module_platform_driver(jh7110_ispcrg_driver);
-+
-+MODULE_AUTHOR("Xingyu Wu <xingyu.wu@starfivetech.com>");
-+MODULE_DESCRIPTION("StarFive JH7110 Image-Signal-Process clock driver");
-+MODULE_LICENSE("GPL");
---- a/drivers/clk/starfive/clk-starfive-jh7110.h
-+++ b/drivers/clk/starfive/clk-starfive-jh7110.h
-@@ -4,6 +4,12 @@
-
- #include "clk-starfive-jh71x0.h"
-
-+/* top clocks of ISP/VOUT domain from SYSCRG */
-+struct top_sysclk {
-+ struct clk_bulk_data *top_clks;
-+ int top_clks_num;
-+};
-+
- int jh7110_reset_controller_register(struct jh71x0_clk_priv *priv,
- const char *adev_name,
- u32 adev_id);
diff --git a/target/linux/starfive/patches-6.1/0055-dt-bindings-clock-Add-StarFive-JH7110-Video-Output-c.patch b/target/linux/starfive/patches-6.1/0055-dt-bindings-clock-Add-StarFive-JH7110-Video-Output-c.patch
deleted file mode 100644
index fabc6aac17..0000000000
--- a/target/linux/starfive/patches-6.1/0055-dt-bindings-clock-Add-StarFive-JH7110-Video-Output-c.patch
+++ /dev/null
@@ -1,163 +0,0 @@
-From 06fa910083f37ecbc9234c7230dcbbd4d83e2f02 Mon Sep 17 00:00:00 2001
-From: Xingyu Wu <xingyu.wu@starfivetech.com>
-Date: Thu, 18 May 2023 18:12:28 +0800
-Subject: [PATCH 055/122] dt-bindings: clock: Add StarFive JH7110 Video-Output
- clock and reset generator
-
-Add bindings for the Video-Output clock and reset generator (VOUTCRG)
-on the JH7110 RISC-V SoC by StarFive Ltd.
-
-Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
----
- .../clock/starfive,jh7110-voutcrg.yaml | 90 +++++++++++++++++++
- .../dt-bindings/clock/starfive,jh7110-crg.h | 22 +++++
- .../dt-bindings/reset/starfive,jh7110-crg.h | 16 ++++
- 3 files changed, 128 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/clock/starfive,jh7110-voutcrg.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/clock/starfive,jh7110-voutcrg.yaml
-@@ -0,0 +1,90 @@
-+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/clock/starfive,jh7110-voutcrg.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: StarFive JH7110 Video-Output Clock and Reset Generator
-+
-+maintainers:
-+ - Xingyu Wu <xingyu.wu@starfivetech.com>
-+
-+properties:
-+ compatible:
-+ const: starfive,jh7110-voutcrg
-+
-+ reg:
-+ maxItems: 1
-+
-+ clocks:
-+ items:
-+ - description: Vout Top core
-+ - description: Vout Top Ahb
-+ - description: Vout Top Axi
-+ - description: Vout Top HDMI MCLK
-+ - description: I2STX0 BCLK
-+ - description: external HDMI pixel
-+
-+ clock-names:
-+ items:
-+ - const: vout_src
-+ - const: vout_top_ahb
-+ - const: vout_top_axi
-+ - const: vout_top_hdmitx0_mclk
-+ - const: i2stx0_bclk
-+ - const: hdmitx0_pixelclk
-+
-+ resets:
-+ maxItems: 1
-+ description: Vout Top core
-+
-+ '#clock-cells':
-+ const: 1
-+ description:
-+ See <dt-bindings/clock/starfive,jh7110-crg.h> for valid indices.
-+
-+ '#reset-cells':
-+ const: 1
-+ description:
-+ See <dt-bindings/reset/starfive,jh7110-crg.h> for valid indices.
-+
-+ power-domains:
-+ maxItems: 1
-+ description:
-+ Vout domain power
-+
-+required:
-+ - compatible
-+ - reg
-+ - clocks
-+ - clock-names
-+ - resets
-+ - '#clock-cells'
-+ - '#reset-cells'
-+ - power-domains
-+
-+additionalProperties: false
-+
-+examples:
-+ - |
-+ #include <dt-bindings/clock/starfive,jh7110-crg.h>
-+ #include <dt-bindings/power/starfive,jh7110-pmu.h>
-+ #include <dt-bindings/reset/starfive,jh7110-crg.h>
-+
-+ voutcrg: clock-controller@295C0000 {
-+ compatible = "starfive,jh7110-voutcrg";
-+ reg = <0x295C0000 0x10000>;
-+ clocks = <&syscrg JH7110_SYSCLK_VOUT_SRC>,
-+ <&syscrg JH7110_SYSCLK_VOUT_TOP_AHB>,
-+ <&syscrg JH7110_SYSCLK_VOUT_TOP_AXI>,
-+ <&syscrg JH7110_SYSCLK_VOUT_TOP_HDMITX0_MCLK>,
-+ <&syscrg JH7110_SYSCLK_I2STX0_BCLK>,
-+ <&hdmitx0_pixelclk>;
-+ clock-names = "vout_src", "vout_top_ahb",
-+ "vout_top_axi", "vout_top_hdmitx0_mclk",
-+ "i2stx0_bclk", "hdmitx0_pixelclk";
-+ resets = <&syscrg JH7110_SYSRST_VOUT_TOP_SRC>;
-+ #clock-cells = <1>;
-+ #reset-cells = <1>;
-+ power-domains = <&pwrc JH7110_PD_VOUT>;
-+ };
---- a/include/dt-bindings/clock/starfive,jh7110-crg.h
-+++ b/include/dt-bindings/clock/starfive,jh7110-crg.h
-@@ -276,4 +276,26 @@
-
- #define JH7110_ISPCLK_END 14
-
-+/* VOUTCRG clocks */
-+#define JH7110_VOUTCLK_APB 0
-+#define JH7110_VOUTCLK_DC8200_PIX 1
-+#define JH7110_VOUTCLK_DSI_SYS 2
-+#define JH7110_VOUTCLK_TX_ESC 3
-+#define JH7110_VOUTCLK_DC8200_AXI 4
-+#define JH7110_VOUTCLK_DC8200_CORE 5
-+#define JH7110_VOUTCLK_DC8200_AHB 6
-+#define JH7110_VOUTCLK_DC8200_PIX0 7
-+#define JH7110_VOUTCLK_DC8200_PIX1 8
-+#define JH7110_VOUTCLK_DOM_VOUT_TOP_LCD 9
-+#define JH7110_VOUTCLK_DSITX_APB 10
-+#define JH7110_VOUTCLK_DSITX_SYS 11
-+#define JH7110_VOUTCLK_DSITX_DPI 12
-+#define JH7110_VOUTCLK_DSITX_TXESC 13
-+#define JH7110_VOUTCLK_MIPITX_DPHY_TXESC 14
-+#define JH7110_VOUTCLK_HDMI_TX_MCLK 15
-+#define JH7110_VOUTCLK_HDMI_TX_BCLK 16
-+#define JH7110_VOUTCLK_HDMI_TX_SYS 17
-+
-+#define JH7110_VOUTCLK_END 18
-+
- #endif /* __DT_BINDINGS_CLOCK_STARFIVE_JH7110_CRG_H__ */
---- a/include/dt-bindings/reset/starfive,jh7110-crg.h
-+++ b/include/dt-bindings/reset/starfive,jh7110-crg.h
-@@ -195,4 +195,20 @@
-
- #define JH7110_ISPRST_END 12
-
-+/* VOUTCRG resets */
-+#define JH7110_VOUTRST_DC8200_AXI 0
-+#define JH7110_VOUTRST_DC8200_AHB 1
-+#define JH7110_VOUTRST_DC8200_CORE 2
-+#define JH7110_VOUTRST_DSITX_DPI 3
-+#define JH7110_VOUTRST_DSITX_APB 4
-+#define JH7110_VOUTRST_DSITX_RXESC 5
-+#define JH7110_VOUTRST_DSITX_SYS 6
-+#define JH7110_VOUTRST_DSITX_TXBYTEHS 7
-+#define JH7110_VOUTRST_DSITX_TXESC 8
-+#define JH7110_VOUTRST_HDMI_TX_HDMI 9
-+#define JH7110_VOUTRST_MIPITX_DPHY_SYS 10
-+#define JH7110_VOUTRST_MIPITX_DPHY_TXBYTEHS 11
-+
-+#define JH7110_VOUTRST_END 12
-+
- #endif /* __DT_BINDINGS_RESET_STARFIVE_JH7110_CRG_H__ */
diff --git a/target/linux/starfive/patches-6.1/0056-clk-starfive-Add-StarFive-JH7110-Video-Output-clock-.patch b/target/linux/starfive/patches-6.1/0056-clk-starfive-Add-StarFive-JH7110-Video-Output-clock-.patch
deleted file mode 100644
index 8c31af5089..0000000000
--- a/target/linux/starfive/patches-6.1/0056-clk-starfive-Add-StarFive-JH7110-Video-Output-clock-.patch
+++ /dev/null
@@ -1,284 +0,0 @@
-From 2e632d5c5f8b4577ac823f6a9dcf3eacdb14a0ba Mon Sep 17 00:00:00 2001
-From: Xingyu Wu <xingyu.wu@starfivetech.com>
-Date: Thu, 18 May 2023 18:12:29 +0800
-Subject: [PATCH 056/122] clk: starfive: Add StarFive JH7110 Video-Output clock
- driver
-
-Add driver for the StarFive JH7110 Video-Output clock controller.
-And these clock controllers should power on and enable the clocks from
-SYSCRG first before registering.
-
-Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
----
- drivers/clk/starfive/Kconfig | 11 +
- drivers/clk/starfive/Makefile | 1 +
- .../clk/starfive/clk-starfive-jh7110-vout.c | 239 ++++++++++++++++++
- 3 files changed, 251 insertions(+)
- create mode 100644 drivers/clk/starfive/clk-starfive-jh7110-vout.c
-
---- a/drivers/clk/starfive/Kconfig
-+++ b/drivers/clk/starfive/Kconfig
-@@ -73,3 +73,14 @@ config CLK_STARFIVE_JH7110_ISP
- help
- Say yes here to support the Image-Signal-Process clock controller
- on the StarFive JH7110 SoC.
-+
-+config CLK_STARFIVE_JH7110_VOUT
-+ tristate "StarFive JH7110 Video-Output clock support"
-+ depends on CLK_STARFIVE_JH7110_SYS && JH71XX_PMU
-+ select AUXILIARY_BUS
-+ select CLK_STARFIVE_JH71X0
-+ select RESET_STARFIVE_JH7110
-+ default m if ARCH_STARFIVE
-+ help
-+ Say yes here to support the Video-Output clock controller
-+ on the StarFive JH7110 SoC.
---- a/drivers/clk/starfive/Makefile
-+++ b/drivers/clk/starfive/Makefile
-@@ -9,3 +9,4 @@ obj-$(CONFIG_CLK_STARFIVE_JH7110_SYS) +=
- obj-$(CONFIG_CLK_STARFIVE_JH7110_AON) += clk-starfive-jh7110-aon.o
- obj-$(CONFIG_CLK_STARFIVE_JH7110_STG) += clk-starfive-jh7110-stg.o
- obj-$(CONFIG_CLK_STARFIVE_JH7110_ISP) += clk-starfive-jh7110-isp.o
-+obj-$(CONFIG_CLK_STARFIVE_JH7110_VOUT) += clk-starfive-jh7110-vout.o
---- /dev/null
-+++ b/drivers/clk/starfive/clk-starfive-jh7110-vout.c
-@@ -0,0 +1,239 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * StarFive JH7110 Video-Output Clock Driver
-+ *
-+ * Copyright (C) 2022-2023 StarFive Technology Co., Ltd.
-+ */
-+
-+#include <linux/clk.h>
-+#include <linux/clk-provider.h>
-+#include <linux/io.h>
-+#include <linux/platform_device.h>
-+#include <linux/pm_runtime.h>
-+#include <linux/reset.h>
-+
-+#include <dt-bindings/clock/starfive,jh7110-crg.h>
-+
-+#include "clk-starfive-jh7110.h"
-+
-+/* external clocks */
-+#define JH7110_VOUTCLK_VOUT_SRC (JH7110_VOUTCLK_END + 0)
-+#define JH7110_VOUTCLK_VOUT_TOP_AHB (JH7110_VOUTCLK_END + 1)
-+#define JH7110_VOUTCLK_VOUT_TOP_AXI (JH7110_VOUTCLK_END + 2)
-+#define JH7110_VOUTCLK_VOUT_TOP_HDMITX0_MCLK (JH7110_VOUTCLK_END + 3)
-+#define JH7110_VOUTCLK_I2STX0_BCLK (JH7110_VOUTCLK_END + 4)
-+#define JH7110_VOUTCLK_HDMITX0_PIXELCLK (JH7110_VOUTCLK_END + 5)
-+#define JH7110_VOUTCLK_EXT_END (JH7110_VOUTCLK_END + 6)
-+
-+static struct clk_bulk_data jh7110_vout_top_clks[] = {
-+ { .id = "vout_src" },
-+ { .id = "vout_top_ahb" }
-+};
-+
-+static const struct jh71x0_clk_data jh7110_voutclk_data[] = {
-+ /* divider */
-+ JH71X0__DIV(JH7110_VOUTCLK_APB, "apb", 8, JH7110_VOUTCLK_VOUT_TOP_AHB),
-+ JH71X0__DIV(JH7110_VOUTCLK_DC8200_PIX, "dc8200_pix", 63, JH7110_VOUTCLK_VOUT_SRC),
-+ JH71X0__DIV(JH7110_VOUTCLK_DSI_SYS, "dsi_sys", 31, JH7110_VOUTCLK_VOUT_SRC),
-+ JH71X0__DIV(JH7110_VOUTCLK_TX_ESC, "tx_esc", 31, JH7110_VOUTCLK_VOUT_TOP_AHB),
-+ /* dc8200 */
-+ JH71X0_GATE(JH7110_VOUTCLK_DC8200_AXI, "dc8200_axi", 0, JH7110_VOUTCLK_VOUT_TOP_AXI),
-+ JH71X0_GATE(JH7110_VOUTCLK_DC8200_CORE, "dc8200_core", 0, JH7110_VOUTCLK_VOUT_TOP_AXI),
-+ JH71X0_GATE(JH7110_VOUTCLK_DC8200_AHB, "dc8200_ahb", 0, JH7110_VOUTCLK_VOUT_TOP_AHB),
-+ JH71X0_GMUX(JH7110_VOUTCLK_DC8200_PIX0, "dc8200_pix0", 0, 2,
-+ JH7110_VOUTCLK_DC8200_PIX,
-+ JH7110_VOUTCLK_HDMITX0_PIXELCLK),
-+ JH71X0_GMUX(JH7110_VOUTCLK_DC8200_PIX1, "dc8200_pix1", 0, 2,
-+ JH7110_VOUTCLK_DC8200_PIX,
-+ JH7110_VOUTCLK_HDMITX0_PIXELCLK),
-+ /* LCD */
-+ JH71X0_GMUX(JH7110_VOUTCLK_DOM_VOUT_TOP_LCD, "dom_vout_top_lcd", 0, 2,
-+ JH7110_VOUTCLK_DC8200_PIX0,
-+ JH7110_VOUTCLK_DC8200_PIX1),
-+ /* dsiTx */
-+ JH71X0_GATE(JH7110_VOUTCLK_DSITX_APB, "dsiTx_apb", 0, JH7110_VOUTCLK_DSI_SYS),
-+ JH71X0_GATE(JH7110_VOUTCLK_DSITX_SYS, "dsiTx_sys", 0, JH7110_VOUTCLK_DSI_SYS),
-+ JH71X0_GMUX(JH7110_VOUTCLK_DSITX_DPI, "dsiTx_dpi", 0, 2,
-+ JH7110_VOUTCLK_DC8200_PIX,
-+ JH7110_VOUTCLK_HDMITX0_PIXELCLK),
-+ JH71X0_GATE(JH7110_VOUTCLK_DSITX_TXESC, "dsiTx_txesc", 0, JH7110_VOUTCLK_TX_ESC),
-+ /* mipitx DPHY */
-+ JH71X0_GATE(JH7110_VOUTCLK_MIPITX_DPHY_TXESC, "mipitx_dphy_txesc", 0,
-+ JH7110_VOUTCLK_TX_ESC),
-+ /* hdmi */
-+ JH71X0_GATE(JH7110_VOUTCLK_HDMI_TX_MCLK, "hdmi_tx_mclk", 0,
-+ JH7110_VOUTCLK_VOUT_TOP_HDMITX0_MCLK),
-+ JH71X0_GATE(JH7110_VOUTCLK_HDMI_TX_BCLK, "hdmi_tx_bclk", 0,
-+ JH7110_VOUTCLK_I2STX0_BCLK),
-+ JH71X0_GATE(JH7110_VOUTCLK_HDMI_TX_SYS, "hdmi_tx_sys", 0, JH7110_VOUTCLK_APB),
-+};
-+
-+static int jh7110_vout_top_rst_init(struct jh71x0_clk_priv *priv)
-+{
-+ struct reset_control *top_rst;
-+
-+ /* The reset should be shared and other Vout modules will use its. */
-+ top_rst = devm_reset_control_get_shared(priv->dev, NULL);
-+ if (IS_ERR(top_rst))
-+ return dev_err_probe(priv->dev, PTR_ERR(top_rst), "failed to get top reset\n");
-+
-+ return reset_control_deassert(top_rst);
-+}
-+
-+static struct clk_hw *jh7110_voutclk_get(struct of_phandle_args *clkspec, void *data)
-+{
-+ struct jh71x0_clk_priv *priv = data;
-+ unsigned int idx = clkspec->args[0];
-+
-+ if (idx < JH7110_VOUTCLK_END)
-+ return &priv->reg[idx].hw;
-+
-+ return ERR_PTR(-EINVAL);
-+}
-+
-+#ifdef CONFIG_PM
-+static int jh7110_voutcrg_suspend(struct device *dev)
-+{
-+ struct top_sysclk *top = dev_get_drvdata(dev);
-+
-+ clk_bulk_disable_unprepare(top->top_clks_num, top->top_clks);
-+
-+ return 0;
-+}
-+
-+static int jh7110_voutcrg_resume(struct device *dev)
-+{
-+ struct top_sysclk *top = dev_get_drvdata(dev);
-+
-+ return clk_bulk_prepare_enable(top->top_clks_num, top->top_clks);
-+}
-+#endif
-+
-+static const struct dev_pm_ops jh7110_voutcrg_pm_ops = {
-+ SET_RUNTIME_PM_OPS(jh7110_voutcrg_suspend, jh7110_voutcrg_resume, NULL)
-+};
-+
-+static int jh7110_voutcrg_probe(struct platform_device *pdev)
-+{
-+ struct jh71x0_clk_priv *priv;
-+ struct top_sysclk *top;
-+ unsigned int idx;
-+ int ret;
-+
-+ priv = devm_kzalloc(&pdev->dev,
-+ struct_size(priv, reg, JH7110_VOUTCLK_END),
-+ GFP_KERNEL);
-+ if (!priv)
-+ return -ENOMEM;
-+
-+ top = devm_kzalloc(&pdev->dev, sizeof(*top), GFP_KERNEL);
-+ if (!top)
-+ return -ENOMEM;
-+
-+ spin_lock_init(&priv->rmw_lock);
-+ priv->dev = &pdev->dev;
-+ priv->base = devm_platform_ioremap_resource(pdev, 0);
-+ if (IS_ERR(priv->base))
-+ return PTR_ERR(priv->base);
-+
-+ top->top_clks = jh7110_vout_top_clks;
-+ top->top_clks_num = ARRAY_SIZE(jh7110_vout_top_clks);
-+ ret = devm_clk_bulk_get(priv->dev, top->top_clks_num, top->top_clks);
-+ if (ret)
-+ return dev_err_probe(priv->dev, ret, "failed to get top clocks\n");
-+ dev_set_drvdata(priv->dev, top);
-+
-+ /* enable power domain and clocks */
-+ pm_runtime_enable(priv->dev);
-+ ret = pm_runtime_get_sync(priv->dev);
-+ if (ret < 0)
-+ return dev_err_probe(priv->dev, ret, "failed to turn on power\n");
-+
-+ ret = jh7110_vout_top_rst_init(priv);
-+ if (ret)
-+ goto err_exit;
-+
-+ for (idx = 0; idx < JH7110_VOUTCLK_END; idx++) {
-+ u32 max = jh7110_voutclk_data[idx].max;
-+ struct clk_parent_data parents[4] = {};
-+ struct clk_init_data init = {
-+ .name = jh7110_voutclk_data[idx].name,
-+ .ops = starfive_jh71x0_clk_ops(max),
-+ .parent_data = parents,
-+ .num_parents =
-+ ((max & JH71X0_CLK_MUX_MASK) >> JH71X0_CLK_MUX_SHIFT) + 1,
-+ .flags = jh7110_voutclk_data[idx].flags,
-+ };
-+ struct jh71x0_clk *clk = &priv->reg[idx];
-+ unsigned int i;
-+ const char *fw_name[JH7110_VOUTCLK_EXT_END - JH7110_VOUTCLK_END] = {
-+ "vout_src",
-+ "vout_top_ahb",
-+ "vout_top_axi",
-+ "vout_top_hdmitx0_mclk",
-+ "i2stx0_bclk",
-+ "hdmitx0_pixelclk"
-+ };
-+
-+ for (i = 0; i < init.num_parents; i++) {
-+ unsigned int pidx = jh7110_voutclk_data[idx].parents[i];
-+
-+ if (pidx < JH7110_VOUTCLK_END)
-+ parents[i].hw = &priv->reg[pidx].hw;
-+ else if (pidx < JH7110_VOUTCLK_EXT_END)
-+ parents[i].fw_name = fw_name[pidx - JH7110_VOUTCLK_END];
-+ }
-+
-+ clk->hw.init = &init;
-+ clk->idx = idx;
-+ clk->max_div = max & JH71X0_CLK_DIV_MASK;
-+
-+ ret = devm_clk_hw_register(&pdev->dev, &clk->hw);
-+ if (ret)
-+ goto err_exit;
-+ }
-+
-+ ret = devm_of_clk_add_hw_provider(&pdev->dev, jh7110_voutclk_get, priv);
-+ if (ret)
-+ goto err_exit;
-+
-+ ret = jh7110_reset_controller_register(priv, "rst-vo", 4);
-+ if (ret)
-+ goto err_exit;
-+
-+ return 0;
-+
-+err_exit:
-+ pm_runtime_put_sync(priv->dev);
-+ pm_runtime_disable(priv->dev);
-+ return ret;
-+}
-+
-+static int jh7110_voutcrg_remove(struct platform_device *pdev)
-+{
-+ pm_runtime_put_sync(&pdev->dev);
-+ pm_runtime_disable(&pdev->dev);
-+
-+ return 0;
-+}
-+
-+static const struct of_device_id jh7110_voutcrg_match[] = {
-+ { .compatible = "starfive,jh7110-voutcrg" },
-+ { /* sentinel */ }
-+};
-+MODULE_DEVICE_TABLE(of, jh7110_voutcrg_match);
-+
-+static struct platform_driver jh7110_voutcrg_driver = {
-+ .probe = jh7110_voutcrg_probe,
-+ .remove = jh7110_voutcrg_remove,
-+ .driver = {
-+ .name = "clk-starfive-jh7110-vout",
-+ .of_match_table = jh7110_voutcrg_match,
-+ .pm = &jh7110_voutcrg_pm_ops,
-+ },
-+};
-+module_platform_driver(jh7110_voutcrg_driver);
-+
-+MODULE_AUTHOR("Xingyu Wu <xingyu.wu@starfivetech.com>");
-+MODULE_DESCRIPTION("StarFive JH7110 Video-Output clock driver");
-+MODULE_LICENSE("GPL");
diff --git a/target/linux/starfive/patches-6.1/0057-reset-starfive-jh7110-Add-StarFive-STG-ISP-VOUT-rese.patch b/target/linux/starfive/patches-6.1/0057-reset-starfive-jh7110-Add-StarFive-STG-ISP-VOUT-rese.patch
deleted file mode 100644
index 197337bb70..0000000000
--- a/target/linux/starfive/patches-6.1/0057-reset-starfive-jh7110-Add-StarFive-STG-ISP-VOUT-rese.patch
+++ /dev/null
@@ -1,61 +0,0 @@
-From a04a6eb3b4d112f3600bbd783249f24a43797e7a Mon Sep 17 00:00:00 2001
-From: Xingyu Wu <xingyu.wu@starfivetech.com>
-Date: Thu, 18 May 2023 18:12:31 +0800
-Subject: [PATCH 057/122] reset: starfive: jh7110: Add StarFive STG/ISP/VOUT
- resets support
-
-Add new struct members and auxiliary_device_id of resets to support
-System-Top-Group, Image-Signal-Process and Video-Output on the StarFive
-JH7110 SoC.
-
-Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
----
- .../reset/starfive/reset-starfive-jh7110.c | 30 +++++++++++++++++++
- 1 file changed, 30 insertions(+)
-
---- a/drivers/reset/starfive/reset-starfive-jh7110.c
-+++ b/drivers/reset/starfive/reset-starfive-jh7110.c
-@@ -31,6 +31,24 @@ static const struct jh7110_reset_info jh
- .status_offset = 0x3C,
- };
-
-+static const struct jh7110_reset_info jh7110_stg_info = {
-+ .nr_resets = JH7110_STGRST_END,
-+ .assert_offset = 0x74,
-+ .status_offset = 0x78,
-+};
-+
-+static const struct jh7110_reset_info jh7110_isp_info = {
-+ .nr_resets = JH7110_ISPRST_END,
-+ .assert_offset = 0x38,
-+ .status_offset = 0x3C,
-+};
-+
-+static const struct jh7110_reset_info jh7110_vout_info = {
-+ .nr_resets = JH7110_VOUTRST_END,
-+ .assert_offset = 0x48,
-+ .status_offset = 0x4C,
-+};
-+
- static int jh7110_reset_probe(struct auxiliary_device *adev,
- const struct auxiliary_device_id *id)
- {
-@@ -58,6 +76,18 @@ static const struct auxiliary_device_id
- .name = "clk_starfive_jh7110_sys.rst-aon",
- .driver_data = (kernel_ulong_t)&jh7110_aon_info,
- },
-+ {
-+ .name = "clk_starfive_jh7110_sys.rst-stg",
-+ .driver_data = (kernel_ulong_t)&jh7110_stg_info,
-+ },
-+ {
-+ .name = "clk_starfive_jh7110_sys.rst-isp",
-+ .driver_data = (kernel_ulong_t)&jh7110_isp_info,
-+ },
-+ {
-+ .name = "clk_starfive_jh7110_sys.rst-vo",
-+ .driver_data = (kernel_ulong_t)&jh7110_vout_info,
-+ },
- { /* sentinel */ }
- };
- MODULE_DEVICE_TABLE(auxiliary, jh7110_reset_ids);
diff --git a/target/linux/starfive/patches-6.1/0058-clk-starfive-update-jh7110-PLL-clock-driver.patch b/target/linux/starfive/patches-6.1/0058-clk-starfive-update-jh7110-PLL-clock-driver.patch
deleted file mode 100644
index fc3da897a5..0000000000
--- a/target/linux/starfive/patches-6.1/0058-clk-starfive-update-jh7110-PLL-clock-driver.patch
+++ /dev/null
@@ -1,819 +0,0 @@
-From 758c8c4c30f495465f34735aef2458c0cc255a75 Mon Sep 17 00:00:00 2001
-From: "shanlong.li" <shanlong.li@starfivetech.com>
-Date: Wed, 31 May 2023 01:03:02 -0700
-Subject: [PATCH 058/122] clk: starfive: update jh7110 PLL clock driver
-
-Update the StarFive JH7110 PLL clock controller
-and they work by reading and setting syscon registers.
-
-Signed-off-by: shanlong.li <shanlong.li@starfivetech.com>
----
- .../clk/starfive/clk-starfive-jh7110-pll.c | 269 +++++-------------
- .../clk/starfive/clk-starfive-jh7110-pll.h | 264 +++++++++--------
- 2 files changed, 227 insertions(+), 306 deletions(-)
-
---- a/drivers/clk/starfive/clk-starfive-jh7110-pll.c
-+++ b/drivers/clk/starfive/clk-starfive-jh7110-pll.c
-@@ -24,11 +24,29 @@
- #include <linux/mfd/syscon.h>
- #include <linux/platform_device.h>
- #include <linux/regmap.h>
-+#include <linux/of_platform.h>
-
- #include <dt-bindings/clock/starfive,jh7110-crg.h>
-
- #include "clk-starfive-jh7110-pll.h"
-
-+struct jh7110_pll_conf_variant {
-+ unsigned int pll_nums;
-+ struct jh7110_pll_syscon_conf conf[];
-+};
-+
-+static const struct jh7110_pll_conf_variant jh7110_pll_variant = {
-+ .pll_nums = JH7110_PLLCLK_END,
-+ .conf = {
-+ JH7110_PLL(JH7110_CLK_PLL0_OUT, "pll0_out",
-+ JH7110_PLL0_FREQ_MAX, jh7110_pll0_syscon_val_preset),
-+ JH7110_PLL(JH7110_CLK_PLL1_OUT, "pll1_out",
-+ JH7110_PLL1_FREQ_MAX, jh7110_pll1_syscon_val_preset),
-+ JH7110_PLL(JH7110_CLK_PLL2_OUT, "pll2_out",
-+ JH7110_PLL2_FREQ_MAX, jh7110_pll2_syscon_val_preset),
-+ },
-+};
-+
- static struct jh7110_clk_pll_data *jh7110_pll_data_from(struct clk_hw *hw)
- {
- return container_of(hw, struct jh7110_clk_pll_data, hw);
-@@ -44,10 +62,9 @@ static unsigned long jh7110_pll_get_freq
- unsigned long parent_rate)
- {
- struct jh7110_clk_pll_priv *priv = jh7110_pll_priv_from(data);
-- struct jh7110_pll_syscon_offset *offset = &data->offset;
-- struct jh7110_pll_syscon_mask *mask = &data->mask;
-- struct jh7110_pll_syscon_shift *shift = &data->shift;
-- unsigned long freq = 0;
-+ struct jh7110_pll_syscon_offset *offset = &data->conf.offsets;
-+ struct jh7110_pll_syscon_mask *mask = &data->conf.masks;
-+ struct jh7110_pll_syscon_shift *shift = &data->conf.shifts;
- unsigned long frac_cal;
- u32 dacpd;
- u32 dsmpd;
-@@ -57,32 +74,23 @@ static unsigned long jh7110_pll_get_freq
- u32 frac;
- u32 reg_val;
-
-- if (regmap_read(priv->syscon_regmap, offset->dacpd, &reg_val))
-- goto read_error;
-+ regmap_read(priv->syscon_regmap, offset->dacpd, &reg_val);
- dacpd = (reg_val & mask->dacpd) >> shift->dacpd;
-
-- if (regmap_read(priv->syscon_regmap, offset->dsmpd, &reg_val))
-- goto read_error;
-+ regmap_read(priv->syscon_regmap, offset->dsmpd, &reg_val);
- dsmpd = (reg_val & mask->dsmpd) >> shift->dsmpd;
-
-- if (regmap_read(priv->syscon_regmap, offset->fbdiv, &reg_val))
-- goto read_error;
-+ regmap_read(priv->syscon_regmap, offset->fbdiv, &reg_val);
- fbdiv = (reg_val & mask->fbdiv) >> shift->fbdiv;
-- /* fbdiv value should be 8 to 4095 */
-- if (fbdiv < 8)
-- goto read_error;
-
-- if (regmap_read(priv->syscon_regmap, offset->prediv, &reg_val))
-- goto read_error;
-+ regmap_read(priv->syscon_regmap, offset->prediv, &reg_val);
- prediv = (reg_val & mask->prediv) >> shift->prediv;
-
-- if (regmap_read(priv->syscon_regmap, offset->postdiv1, &reg_val))
-- goto read_error;
-+ regmap_read(priv->syscon_regmap, offset->postdiv1, &reg_val);
- /* postdiv1 = 2 ^ reg_val */
- postdiv1 = 1 << ((reg_val & mask->postdiv1) >> shift->postdiv1);
-
-- if (regmap_read(priv->syscon_regmap, offset->frac, &reg_val))
-- goto read_error;
-+ regmap_read(priv->syscon_regmap, offset->frac, &reg_val);
- frac = (reg_val & mask->frac) >> shift->frac;
-
- /*
-@@ -95,14 +103,11 @@ static unsigned long jh7110_pll_get_freq
- else if (dacpd == 0 && dsmpd == 0)
- frac_cal = (unsigned long)frac * STARFIVE_PLL_FRAC_PATR_SIZE / (1 << 24);
- else
-- goto read_error;
-+ return 0;
-
- /* Fvco = Fref * (NI + NF) / M / Q1 */
-- freq = parent_rate / STARFIVE_PLL_FRAC_PATR_SIZE *
-- (fbdiv * STARFIVE_PLL_FRAC_PATR_SIZE + frac_cal) / prediv / postdiv1;
--
--read_error:
-- return freq;
-+ return (parent_rate / STARFIVE_PLL_FRAC_PATR_SIZE *
-+ (fbdiv * STARFIVE_PLL_FRAC_PATR_SIZE + frac_cal) / prediv / postdiv1);
- }
-
- static unsigned long jh7110_pll_rate_sub_fabs(unsigned long rate1, unsigned long rate2)
-@@ -114,40 +119,27 @@ static unsigned long jh7110_pll_rate_sub
- static void jh7110_pll_select_near_freq_id(struct jh7110_clk_pll_data *data,
- unsigned long rate)
- {
-- const struct starfive_pll_syscon_value *syscon_val;
-+ const struct jh7110_pll_syscon_val *val;
- unsigned int id;
-- unsigned int pll_arry_size;
- unsigned long rate_diff;
-
-- if (data->idx == JH7110_CLK_PLL0_OUT)
-- pll_arry_size = ARRAY_SIZE(jh7110_pll0_syscon_freq);
-- else if (data->idx == JH7110_CLK_PLL1_OUT)
-- pll_arry_size = ARRAY_SIZE(jh7110_pll1_syscon_freq);
-- else
-- pll_arry_size = ARRAY_SIZE(jh7110_pll2_syscon_freq);
--
- /* compare the frequency one by one from small to large in order */
-- for (id = 0; id < pll_arry_size; id++) {
-- if (data->idx == JH7110_CLK_PLL0_OUT)
-- syscon_val = &jh7110_pll0_syscon_freq[id];
-- else if (data->idx == JH7110_CLK_PLL1_OUT)
-- syscon_val = &jh7110_pll1_syscon_freq[id];
-- else
-- syscon_val = &jh7110_pll2_syscon_freq[id];
-+ for (id = 0; id < data->conf.preset_val_nums; id++) {
-+ val = &data->conf.preset_val[id];
-
-- if (rate == syscon_val->freq)
-+ if (rate == val->freq)
- goto match_end;
-
- /* select near frequency */
-- if (rate < syscon_val->freq) {
-+ if (rate < val->freq) {
- /* The last frequency is closer to the target rate than this time. */
- if (id > 0)
-- if (rate_diff < jh7110_pll_rate_sub_fabs(rate, syscon_val->freq))
-+ if (rate_diff < jh7110_pll_rate_sub_fabs(rate, val->freq))
- id--;
-
- goto match_end;
- } else {
-- rate_diff = jh7110_pll_rate_sub_fabs(rate, syscon_val->freq);
-+ rate_diff = jh7110_pll_rate_sub_fabs(rate, val->freq);
- }
- }
-
-@@ -158,54 +150,34 @@ match_end:
- static int jh7110_pll_set_freq_syscon(struct jh7110_clk_pll_data *data)
- {
- struct jh7110_clk_pll_priv *priv = jh7110_pll_priv_from(data);
-- struct jh7110_pll_syscon_offset *offset = &data->offset;
-- struct jh7110_pll_syscon_mask *mask = &data->mask;
-- struct jh7110_pll_syscon_shift *shift = &data->shift;
-- unsigned int freq_idx = data->freq_select_idx;
-- const struct starfive_pll_syscon_value *syscon_val;
-- int ret;
-+ struct jh7110_pll_syscon_offset *offset = &data->conf.offsets;
-+ struct jh7110_pll_syscon_mask *mask = &data->conf.masks;
-+ struct jh7110_pll_syscon_shift *shift = &data->conf.shifts;
-+ const struct jh7110_pll_syscon_val *val = &data->conf.preset_val[data->freq_select_idx];
-
-- if (data->idx == JH7110_CLK_PLL0_OUT)
-- syscon_val = &jh7110_pll0_syscon_freq[freq_idx];
-- else if (data->idx == JH7110_CLK_PLL1_OUT)
-- syscon_val = &jh7110_pll1_syscon_freq[freq_idx];
-- else
-- syscon_val = &jh7110_pll2_syscon_freq[freq_idx];
-+ /* frac: Integer Mode (Both 1) or Fraction Mode (Both 0) */
-+ if (val->dacpd == 0 && val->dsmpd == 0)
-+ regmap_update_bits(priv->syscon_regmap, offset->frac, mask->frac,
-+ (val->frac << shift->frac));
-+ else if (val->dacpd != val->dsmpd)
-+ return -EINVAL;
-
-- ret = regmap_update_bits(priv->syscon_regmap, offset->dacpd, mask->dacpd,
-- (syscon_val->dacpd << shift->dacpd));
-- if (ret)
-- goto set_failed;
--
-- ret = regmap_update_bits(priv->syscon_regmap, offset->dsmpd, mask->dsmpd,
-- (syscon_val->dsmpd << shift->dsmpd));
-- if (ret)
-- goto set_failed;
--
-- ret = regmap_update_bits(priv->syscon_regmap, offset->prediv, mask->prediv,
-- (syscon_val->prediv << shift->prediv));
-- if (ret)
-- goto set_failed;
--
-- ret = regmap_update_bits(priv->syscon_regmap, offset->fbdiv, mask->fbdiv,
-- (syscon_val->fbdiv << shift->fbdiv));
-- if (ret)
-- goto set_failed;
--
-- ret = regmap_update_bits(priv->syscon_regmap, offset->postdiv1, mask->postdiv1,
-- ((syscon_val->postdiv1 >> 1) << shift->postdiv1));
-- if (ret)
-- goto set_failed;
-+ /* fbdiv value should be 8 to 4095 */
-+ if (val->fbdiv < 8)
-+ return -EINVAL;
-
-- /* frac: Integer Mode (Both 1) or Fraction Mode (Both 0) */
-- if (syscon_val->dacpd == 0 && syscon_val->dsmpd == 0)
-- ret = regmap_update_bits(priv->syscon_regmap, offset->frac, mask->frac,
-- (syscon_val->frac << shift->frac));
-- else if (syscon_val->dacpd != syscon_val->dsmpd)
-- ret = -EINVAL;
-+ regmap_update_bits(priv->syscon_regmap, offset->dacpd, mask->dacpd,
-+ (val->dacpd << shift->dacpd));
-+ regmap_update_bits(priv->syscon_regmap, offset->dsmpd, mask->dsmpd,
-+ (val->dsmpd << shift->dsmpd));
-+ regmap_update_bits(priv->syscon_regmap, offset->prediv, mask->prediv,
-+ (val->prediv << shift->prediv));
-+ regmap_update_bits(priv->syscon_regmap, offset->fbdiv, mask->fbdiv,
-+ (val->fbdiv << shift->fbdiv));
-+ regmap_update_bits(priv->syscon_regmap, offset->postdiv1, mask->postdiv1,
-+ ((val->postdiv1 >> 1) << shift->postdiv1));
-
--set_failed:
-- return ret;
-+ return 0;
- }
-
- static unsigned long jh7110_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
-@@ -220,13 +192,7 @@ static int jh7110_pll_determine_rate(str
- struct jh7110_clk_pll_data *data = jh7110_pll_data_from(hw);
-
- jh7110_pll_select_near_freq_id(data, req->rate);
--
-- if (data->idx == JH7110_CLK_PLL0_OUT)
-- req->rate = jh7110_pll0_syscon_freq[data->freq_select_idx].freq;
-- else if (data->idx == JH7110_CLK_PLL1_OUT)
-- req->rate = jh7110_pll1_syscon_freq[data->freq_select_idx].freq;
-- else
-- req->rate = jh7110_pll2_syscon_freq[data->freq_select_idx].freq;
-+ req->rate = data->conf.preset_val[data->freq_select_idx].freq;
-
- return 0;
- }
-@@ -270,92 +236,12 @@ static const struct clk_ops jh7110_pll_o
- .debug_init = jh7110_pll_debug_init,
- };
-
--/* get offset, mask and shift of PLL(x) syscon */
--static int jh7110_pll_data_get(struct jh7110_clk_pll_data *data, int index)
--{
-- struct jh7110_pll_syscon_offset *offset = &data->offset;
-- struct jh7110_pll_syscon_mask *mask = &data->mask;
-- struct jh7110_pll_syscon_shift *shift = &data->shift;
--
-- if (index == JH7110_CLK_PLL0_OUT) {
-- offset->dacpd = STARFIVE_JH7110_PLL0_DACPD_OFFSET;
-- offset->dsmpd = STARFIVE_JH7110_PLL0_DSMPD_OFFSET;
-- offset->fbdiv = STARFIVE_JH7110_PLL0_FBDIV_OFFSET;
-- offset->frac = STARFIVE_JH7110_PLL0_FRAC_OFFSET;
-- offset->prediv = STARFIVE_JH7110_PLL0_PREDIV_OFFSET;
-- offset->postdiv1 = STARFIVE_JH7110_PLL0_POSTDIV1_OFFSET;
--
-- mask->dacpd = STARFIVE_JH7110_PLL0_DACPD_MASK;
-- mask->dsmpd = STARFIVE_JH7110_PLL0_DSMPD_MASK;
-- mask->fbdiv = STARFIVE_JH7110_PLL0_FBDIV_MASK;
-- mask->frac = STARFIVE_JH7110_PLL0_FRAC_MASK;
-- mask->prediv = STARFIVE_JH7110_PLL0_PREDIV_MASK;
-- mask->postdiv1 = STARFIVE_JH7110_PLL0_POSTDIV1_MASK;
--
-- shift->dacpd = STARFIVE_JH7110_PLL0_DACPD_SHIFT;
-- shift->dsmpd = STARFIVE_JH7110_PLL0_DSMPD_SHIFT;
-- shift->fbdiv = STARFIVE_JH7110_PLL0_FBDIV_SHIFT;
-- shift->frac = STARFIVE_JH7110_PLL0_FRAC_SHIFT;
-- shift->prediv = STARFIVE_JH7110_PLL0_PREDIV_SHIFT;
-- shift->postdiv1 = STARFIVE_JH7110_PLL0_POSTDIV1_SHIFT;
--
-- } else if (index == JH7110_CLK_PLL1_OUT) {
-- offset->dacpd = STARFIVE_JH7110_PLL1_DACPD_OFFSET;
-- offset->dsmpd = STARFIVE_JH7110_PLL1_DSMPD_OFFSET;
-- offset->fbdiv = STARFIVE_JH7110_PLL1_FBDIV_OFFSET;
-- offset->frac = STARFIVE_JH7110_PLL1_FRAC_OFFSET;
-- offset->prediv = STARFIVE_JH7110_PLL1_PREDIV_OFFSET;
-- offset->postdiv1 = STARFIVE_JH7110_PLL1_POSTDIV1_OFFSET;
--
-- mask->dacpd = STARFIVE_JH7110_PLL1_DACPD_MASK;
-- mask->dsmpd = STARFIVE_JH7110_PLL1_DSMPD_MASK;
-- mask->fbdiv = STARFIVE_JH7110_PLL1_FBDIV_MASK;
-- mask->frac = STARFIVE_JH7110_PLL1_FRAC_MASK;
-- mask->prediv = STARFIVE_JH7110_PLL1_PREDIV_MASK;
-- mask->postdiv1 = STARFIVE_JH7110_PLL1_POSTDIV1_MASK;
--
-- shift->dacpd = STARFIVE_JH7110_PLL1_DACPD_SHIFT;
-- shift->dsmpd = STARFIVE_JH7110_PLL1_DSMPD_SHIFT;
-- shift->fbdiv = STARFIVE_JH7110_PLL1_FBDIV_SHIFT;
-- shift->frac = STARFIVE_JH7110_PLL1_FRAC_SHIFT;
-- shift->prediv = STARFIVE_JH7110_PLL1_PREDIV_SHIFT;
-- shift->postdiv1 = STARFIVE_JH7110_PLL1_POSTDIV1_SHIFT;
--
-- } else if (index == JH7110_CLK_PLL2_OUT) {
-- offset->dacpd = STARFIVE_JH7110_PLL2_DACPD_OFFSET;
-- offset->dsmpd = STARFIVE_JH7110_PLL2_DSMPD_OFFSET;
-- offset->fbdiv = STARFIVE_JH7110_PLL2_FBDIV_OFFSET;
-- offset->frac = STARFIVE_JH7110_PLL2_FRAC_OFFSET;
-- offset->prediv = STARFIVE_JH7110_PLL2_PREDIV_OFFSET;
-- offset->postdiv1 = STARFIVE_JH7110_PLL2_POSTDIV1_OFFSET;
--
-- mask->dacpd = STARFIVE_JH7110_PLL2_DACPD_MASK;
-- mask->dsmpd = STARFIVE_JH7110_PLL2_DSMPD_MASK;
-- mask->fbdiv = STARFIVE_JH7110_PLL2_FBDIV_MASK;
-- mask->frac = STARFIVE_JH7110_PLL2_FRAC_MASK;
-- mask->prediv = STARFIVE_JH7110_PLL2_PREDIV_MASK;
-- mask->postdiv1 = STARFIVE_JH7110_PLL2_POSTDIV1_MASK;
--
-- shift->dacpd = STARFIVE_JH7110_PLL2_DACPD_SHIFT;
-- shift->dsmpd = STARFIVE_JH7110_PLL2_DSMPD_SHIFT;
-- shift->fbdiv = STARFIVE_JH7110_PLL2_FBDIV_SHIFT;
-- shift->frac = STARFIVE_JH7110_PLL2_FRAC_SHIFT;
-- shift->prediv = STARFIVE_JH7110_PLL2_PREDIV_SHIFT;
-- shift->postdiv1 = STARFIVE_JH7110_PLL2_POSTDIV1_SHIFT;
--
-- } else {
-- return -ENOENT;
-- }
--
-- return 0;
--}
--
- static struct clk_hw *jh7110_pll_get(struct of_phandle_args *clkspec, void *data)
- {
- struct jh7110_clk_pll_priv *priv = data;
- unsigned int idx = clkspec->args[0];
-
-- if (idx < JH7110_PLLCLK_END)
-+ if (idx < priv->pll_nums)
- return &priv->data[idx].hw;
-
- return ERR_PTR(-EINVAL);
-@@ -363,17 +249,17 @@ static struct clk_hw *jh7110_pll_get(str
-
- static int jh7110_pll_probe(struct platform_device *pdev)
- {
-- const char *pll_name[JH7110_PLLCLK_END] = {
-- "pll0_out",
-- "pll1_out",
-- "pll2_out"
-- };
-+ const struct jh7110_pll_conf_variant *variant;
- struct jh7110_clk_pll_priv *priv;
- struct jh7110_clk_pll_data *data;
- int ret;
- unsigned int idx;
-
-- priv = devm_kzalloc(&pdev->dev, struct_size(priv, data, JH7110_PLLCLK_END),
-+ variant = of_device_get_match_data(&pdev->dev);
-+ if (!variant)
-+ return -ENOMEM;
-+
-+ priv = devm_kzalloc(&pdev->dev, struct_size(priv, data, variant->pll_nums),
- GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
-@@ -383,12 +269,13 @@ static int jh7110_pll_probe(struct platf
- if (IS_ERR(priv->syscon_regmap))
- return PTR_ERR(priv->syscon_regmap);
-
-- for (idx = 0; idx < JH7110_PLLCLK_END; idx++) {
-+ priv->pll_nums = variant->pll_nums;
-+ for (idx = 0; idx < priv->pll_nums; idx++) {
- struct clk_parent_data parents = {
- .index = 0,
- };
- struct clk_init_data init = {
-- .name = pll_name[idx],
-+ .name = variant->conf[idx].name,
- .ops = &jh7110_pll_ops,
- .parent_data = &parents,
- .num_parents = 1,
-@@ -396,11 +283,7 @@ static int jh7110_pll_probe(struct platf
- };
-
- data = &priv->data[idx];
--
-- ret = jh7110_pll_data_get(data, idx);
-- if (ret)
-- return ret;
--
-+ data->conf = variant->conf[idx];
- data->hw.init = &init;
- data->idx = idx;
-
-@@ -413,7 +296,7 @@ static int jh7110_pll_probe(struct platf
- }
-
- static const struct of_device_id jh7110_pll_match[] = {
-- { .compatible = "starfive,jh7110-pll" },
-+ { .compatible = "starfive,jh7110-pll", .data = &jh7110_pll_variant },
- { /* sentinel */ }
- };
- MODULE_DEVICE_TABLE(of, jh7110_pll_match);
---- a/drivers/clk/starfive/clk-starfive-jh7110-pll.h
-+++ b/drivers/clk/starfive/clk-starfive-jh7110-pll.h
-@@ -13,62 +13,93 @@
- /* The decimal places are counted by expanding them by a factor of STARFIVE_PLL_FRAC_PATR_SIZE */
- #define STARFIVE_PLL_FRAC_PATR_SIZE 1000
-
--#define STARFIVE_JH7110_PLL0_DACPD_OFFSET 0x18
--#define STARFIVE_JH7110_PLL0_DACPD_SHIFT 24
--#define STARFIVE_JH7110_PLL0_DACPD_MASK BIT(24)
--#define STARFIVE_JH7110_PLL0_DSMPD_OFFSET 0x18
--#define STARFIVE_JH7110_PLL0_DSMPD_SHIFT 25
--#define STARFIVE_JH7110_PLL0_DSMPD_MASK BIT(25)
--#define STARFIVE_JH7110_PLL0_FBDIV_OFFSET 0x1c
--#define STARFIVE_JH7110_PLL0_FBDIV_SHIFT 0
--#define STARFIVE_JH7110_PLL0_FBDIV_MASK GENMASK(11, 0)
--#define STARFIVE_JH7110_PLL0_FRAC_OFFSET 0x20
--#define STARFIVE_JH7110_PLL0_FRAC_SHIFT 0
--#define STARFIVE_JH7110_PLL0_FRAC_MASK GENMASK(23, 0)
--#define STARFIVE_JH7110_PLL0_POSTDIV1_OFFSET 0x20
--#define STARFIVE_JH7110_PLL0_POSTDIV1_SHIFT 28
--#define STARFIVE_JH7110_PLL0_POSTDIV1_MASK GENMASK(29, 28)
--#define STARFIVE_JH7110_PLL0_PREDIV_OFFSET 0x24
--#define STARFIVE_JH7110_PLL0_PREDIV_SHIFT 0
--#define STARFIVE_JH7110_PLL0_PREDIV_MASK GENMASK(5, 0)
--
--#define STARFIVE_JH7110_PLL1_DACPD_OFFSET 0x24
--#define STARFIVE_JH7110_PLL1_DACPD_SHIFT 15
--#define STARFIVE_JH7110_PLL1_DACPD_MASK BIT(15)
--#define STARFIVE_JH7110_PLL1_DSMPD_OFFSET 0x24
--#define STARFIVE_JH7110_PLL1_DSMPD_SHIFT 16
--#define STARFIVE_JH7110_PLL1_DSMPD_MASK BIT(16)
--#define STARFIVE_JH7110_PLL1_FBDIV_OFFSET 0x24
--#define STARFIVE_JH7110_PLL1_FBDIV_SHIFT 17
--#define STARFIVE_JH7110_PLL1_FBDIV_MASK GENMASK(28, 17)
--#define STARFIVE_JH7110_PLL1_FRAC_OFFSET 0x28
--#define STARFIVE_JH7110_PLL1_FRAC_SHIFT 0
--#define STARFIVE_JH7110_PLL1_FRAC_MASK GENMASK(23, 0)
--#define STARFIVE_JH7110_PLL1_POSTDIV1_OFFSET 0x28
--#define STARFIVE_JH7110_PLL1_POSTDIV1_SHIFT 28
--#define STARFIVE_JH7110_PLL1_POSTDIV1_MASK GENMASK(29, 28)
--#define STARFIVE_JH7110_PLL1_PREDIV_OFFSET 0x2c
--#define STARFIVE_JH7110_PLL1_PREDIV_SHIFT 0
--#define STARFIVE_JH7110_PLL1_PREDIV_MASK GENMASK(5, 0)
--
--#define STARFIVE_JH7110_PLL2_DACPD_OFFSET 0x2c
--#define STARFIVE_JH7110_PLL2_DACPD_SHIFT 15
--#define STARFIVE_JH7110_PLL2_DACPD_MASK BIT(15)
--#define STARFIVE_JH7110_PLL2_DSMPD_OFFSET 0x2c
--#define STARFIVE_JH7110_PLL2_DSMPD_SHIFT 16
--#define STARFIVE_JH7110_PLL2_DSMPD_MASK BIT(16)
--#define STARFIVE_JH7110_PLL2_FBDIV_OFFSET 0x2c
--#define STARFIVE_JH7110_PLL2_FBDIV_SHIFT 17
--#define STARFIVE_JH7110_PLL2_FBDIV_MASK GENMASK(28, 17)
--#define STARFIVE_JH7110_PLL2_FRAC_OFFSET 0x30
--#define STARFIVE_JH7110_PLL2_FRAC_SHIFT 0
--#define STARFIVE_JH7110_PLL2_FRAC_MASK GENMASK(23, 0)
--#define STARFIVE_JH7110_PLL2_POSTDIV1_OFFSET 0x30
--#define STARFIVE_JH7110_PLL2_POSTDIV1_SHIFT 28
--#define STARFIVE_JH7110_PLL2_POSTDIV1_MASK GENMASK(29, 28)
--#define STARFIVE_JH7110_PLL2_PREDIV_OFFSET 0x34
--#define STARFIVE_JH7110_PLL2_PREDIV_SHIFT 0
--#define STARFIVE_JH7110_PLL2_PREDIV_MASK GENMASK(5, 0)
-+#define STARFIVE_JH7110_CLK_PLL0_OUT_DACPD_OFFSET 0x18
-+#define STARFIVE_JH7110_CLK_PLL0_OUT_DACPD_SHIFT 24
-+#define STARFIVE_JH7110_CLK_PLL0_OUT_DACPD_MASK BIT(24)
-+#define STARFIVE_JH7110_CLK_PLL0_OUT_DSMPD_OFFSET 0x18
-+#define STARFIVE_JH7110_CLK_PLL0_OUT_DSMPD_SHIFT 25
-+#define STARFIVE_JH7110_CLK_PLL0_OUT_DSMPD_MASK BIT(25)
-+#define STARFIVE_JH7110_CLK_PLL0_OUT_FBDIV_OFFSET 0x1c
-+#define STARFIVE_JH7110_CLK_PLL0_OUT_FBDIV_SHIFT 0
-+#define STARFIVE_JH7110_CLK_PLL0_OUT_FBDIV_MASK GENMASK(11, 0)
-+#define STARFIVE_JH7110_CLK_PLL0_OUT_FRAC_OFFSET 0x20
-+#define STARFIVE_JH7110_CLK_PLL0_OUT_FRAC_SHIFT 0
-+#define STARFIVE_JH7110_CLK_PLL0_OUT_FRAC_MASK GENMASK(23, 0)
-+#define STARFIVE_JH7110_CLK_PLL0_OUT_POSTDIV1_OFFSET 0x20
-+#define STARFIVE_JH7110_CLK_PLL0_OUT_POSTDIV1_SHIFT 28
-+#define STARFIVE_JH7110_CLK_PLL0_OUT_POSTDIV1_MASK GENMASK(29, 28)
-+#define STARFIVE_JH7110_CLK_PLL0_OUT_PREDIV_OFFSET 0x24
-+#define STARFIVE_JH7110_CLK_PLL0_OUT_PREDIV_SHIFT 0
-+#define STARFIVE_JH7110_CLK_PLL0_OUT_PREDIV_MASK GENMASK(5, 0)
-+
-+#define STARFIVE_JH7110_CLK_PLL1_OUT_DACPD_OFFSET 0x24
-+#define STARFIVE_JH7110_CLK_PLL1_OUT_DACPD_SHIFT 15
-+#define STARFIVE_JH7110_CLK_PLL1_OUT_DACPD_MASK BIT(15)
-+#define STARFIVE_JH7110_CLK_PLL1_OUT_DSMPD_OFFSET 0x24
-+#define STARFIVE_JH7110_CLK_PLL1_OUT_DSMPD_SHIFT 16
-+#define STARFIVE_JH7110_CLK_PLL1_OUT_DSMPD_MASK BIT(16)
-+#define STARFIVE_JH7110_CLK_PLL1_OUT_FBDIV_OFFSET 0x24
-+#define STARFIVE_JH7110_CLK_PLL1_OUT_FBDIV_SHIFT 17
-+#define STARFIVE_JH7110_CLK_PLL1_OUT_FBDIV_MASK GENMASK(28, 17)
-+#define STARFIVE_JH7110_CLK_PLL1_OUT_FRAC_OFFSET 0x28
-+#define STARFIVE_JH7110_CLK_PLL1_OUT_FRAC_SHIFT 0
-+#define STARFIVE_JH7110_CLK_PLL1_OUT_FRAC_MASK GENMASK(23, 0)
-+#define STARFIVE_JH7110_CLK_PLL1_OUT_POSTDIV1_OFFSET 0x28
-+#define STARFIVE_JH7110_CLK_PLL1_OUT_POSTDIV1_SHIFT 28
-+#define STARFIVE_JH7110_CLK_PLL1_OUT_POSTDIV1_MASK GENMASK(29, 28)
-+#define STARFIVE_JH7110_CLK_PLL1_OUT_PREDIV_OFFSET 0x2c
-+#define STARFIVE_JH7110_CLK_PLL1_OUT_PREDIV_SHIFT 0
-+#define STARFIVE_JH7110_CLK_PLL1_OUT_PREDIV_MASK GENMASK(5, 0)
-+
-+#define STARFIVE_JH7110_CLK_PLL2_OUT_DACPD_OFFSET 0x2c
-+#define STARFIVE_JH7110_CLK_PLL2_OUT_DACPD_SHIFT 15
-+#define STARFIVE_JH7110_CLK_PLL2_OUT_DACPD_MASK BIT(15)
-+#define STARFIVE_JH7110_CLK_PLL2_OUT_DSMPD_OFFSET 0x2c
-+#define STARFIVE_JH7110_CLK_PLL2_OUT_DSMPD_SHIFT 16
-+#define STARFIVE_JH7110_CLK_PLL2_OUT_DSMPD_MASK BIT(16)
-+#define STARFIVE_JH7110_CLK_PLL2_OUT_FBDIV_OFFSET 0x2c
-+#define STARFIVE_JH7110_CLK_PLL2_OUT_FBDIV_SHIFT 17
-+#define STARFIVE_JH7110_CLK_PLL2_OUT_FBDIV_MASK GENMASK(28, 17)
-+#define STARFIVE_JH7110_CLK_PLL2_OUT_FRAC_OFFSET 0x30
-+#define STARFIVE_JH7110_CLK_PLL2_OUT_FRAC_SHIFT 0
-+#define STARFIVE_JH7110_CLK_PLL2_OUT_FRAC_MASK GENMASK(23, 0)
-+#define STARFIVE_JH7110_CLK_PLL2_OUT_POSTDIV1_OFFSET 0x30
-+#define STARFIVE_JH7110_CLK_PLL2_OUT_POSTDIV1_SHIFT 28
-+#define STARFIVE_JH7110_CLK_PLL2_OUT_POSTDIV1_MASK GENMASK(29, 28)
-+#define STARFIVE_JH7110_CLK_PLL2_OUT_PREDIV_OFFSET 0x34
-+#define STARFIVE_JH7110_CLK_PLL2_OUT_PREDIV_SHIFT 0
-+#define STARFIVE_JH7110_CLK_PLL2_OUT_PREDIV_MASK GENMASK(5, 0)
-+
-+#define JH7110_PLL(_idx, _name, _nums, _val) \
-+[_idx] = { \
-+ .name = _name, \
-+ .offsets = { \
-+ .dacpd = STARFIVE_##_idx##_DACPD_OFFSET, \
-+ .dsmpd = STARFIVE_##_idx##_DSMPD_OFFSET, \
-+ .fbdiv = STARFIVE_##_idx##_FBDIV_OFFSET, \
-+ .frac = STARFIVE_##_idx##_FRAC_OFFSET, \
-+ .prediv = STARFIVE_##_idx##_PREDIV_OFFSET, \
-+ .postdiv1 = STARFIVE_##_idx##_POSTDIV1_OFFSET, \
-+ }, \
-+ .masks = { \
-+ .dacpd = STARFIVE_##_idx##_DACPD_MASK, \
-+ .dsmpd = STARFIVE_##_idx##_DSMPD_MASK, \
-+ .fbdiv = STARFIVE_##_idx##_FBDIV_MASK, \
-+ .frac = STARFIVE_##_idx##_FRAC_MASK, \
-+ .prediv = STARFIVE_##_idx##_PREDIV_MASK, \
-+ .postdiv1 = STARFIVE_##_idx##_POSTDIV1_MASK, \
-+ }, \
-+ .shifts = { \
-+ .dacpd = STARFIVE_##_idx##_DACPD_SHIFT, \
-+ .dsmpd = STARFIVE_##_idx##_DSMPD_SHIFT, \
-+ .fbdiv = STARFIVE_##_idx##_FBDIV_SHIFT, \
-+ .frac = STARFIVE_##_idx##_FRAC_SHIFT, \
-+ .prediv = STARFIVE_##_idx##_PREDIV_SHIFT, \
-+ .postdiv1 = STARFIVE_##_idx##_POSTDIV1_SHIFT, \
-+ }, \
-+ .preset_val_nums = _nums, \
-+ .preset_val = _val, \
-+}
-
- struct jh7110_pll_syscon_offset {
- unsigned int dacpd;
-@@ -97,23 +128,7 @@ struct jh7110_pll_syscon_shift {
- char postdiv1;
- };
-
--struct jh7110_clk_pll_data {
-- struct clk_hw hw;
-- unsigned int idx;
-- unsigned int freq_select_idx;
--
-- struct jh7110_pll_syscon_offset offset;
-- struct jh7110_pll_syscon_mask mask;
-- struct jh7110_pll_syscon_shift shift;
--};
--
--struct jh7110_clk_pll_priv {
-- struct device *dev;
-- struct regmap *syscon_regmap;
-- struct jh7110_clk_pll_data data[];
--};
--
--struct starfive_pll_syscon_value {
-+struct jh7110_pll_syscon_val {
- unsigned long freq;
- u32 prediv;
- u32 fbdiv;
-@@ -126,31 +141,54 @@ struct starfive_pll_syscon_value {
- u32 frac;
- };
-
--enum starfive_pll0_freq_index {
-- PLL0_FREQ_375 = 0,
-- PLL0_FREQ_500,
-- PLL0_FREQ_625,
-- PLL0_FREQ_750,
-- PLL0_FREQ_875,
-- PLL0_FREQ_1000,
-- PLL0_FREQ_1250,
-- PLL0_FREQ_1375,
-- PLL0_FREQ_1500,
-- PLL0_FREQ_MAX
--};
--
--enum starfive_pll1_freq_index {
-- PLL1_FREQ_1066 = 0,
-- PLL1_FREQ_1200,
-- PLL1_FREQ_1400,
-- PLL1_FREQ_1600,
-- PLL1_FREQ_MAX
--};
--
--enum starfive_pll2_freq_index {
-- PLL2_FREQ_1188 = 0,
-- PLL2_FREQ_12288,
-- PLL2_FREQ_MAX
-+struct jh7110_pll_syscon_conf {
-+ char *name;
-+ struct jh7110_pll_syscon_offset offsets;
-+ struct jh7110_pll_syscon_mask masks;
-+ struct jh7110_pll_syscon_shift shifts;
-+ unsigned int preset_val_nums;
-+ const struct jh7110_pll_syscon_val *preset_val;
-+};
-+
-+struct jh7110_clk_pll_data {
-+ struct clk_hw hw;
-+ unsigned int idx;
-+ unsigned int freq_select_idx;
-+ struct jh7110_pll_syscon_conf conf;
-+};
-+
-+struct jh7110_clk_pll_priv {
-+ unsigned int pll_nums;
-+ struct device *dev;
-+ struct regmap *syscon_regmap;
-+ struct jh7110_clk_pll_data data[];
-+};
-+
-+enum jh7110_pll0_freq_index {
-+ JH7110_PLL0_FREQ_375 = 0,
-+ JH7110_PLL0_FREQ_500,
-+ JH7110_PLL0_FREQ_625,
-+ JH7110_PLL0_FREQ_750,
-+ JH7110_PLL0_FREQ_875,
-+ JH7110_PLL0_FREQ_1000,
-+ JH7110_PLL0_FREQ_1250,
-+ JH7110_PLL0_FREQ_1375,
-+ JH7110_PLL0_FREQ_1500,
-+ JH7110_PLL0_FREQ_MAX
-+};
-+
-+enum jh7110_pll1_freq_index {
-+ JH7110_PLL1_FREQ_1066 = 0,
-+ JH7110_PLL1_FREQ_1200,
-+ JH7110_PLL1_FREQ_1400,
-+ JH7110_PLL1_FREQ_1600,
-+ JH7110_PLL1_FREQ_MAX
-+};
-+
-+enum jh7110_pll2_freq_index {
-+ JH7110_PLL2_FREQ_1188 = 0,
-+ JH7110_PLL2_FREQ_12288,
-+ JH7110_PLL2_FREQ_MAX
- };
-
- /*
-@@ -158,9 +196,9 @@ enum starfive_pll2_freq_index {
- * it cannot be set arbitrarily, so it needs a specific configuration.
- * PLL0 frequency should be multiple of 125MHz (USB frequency).
- */
--static const struct starfive_pll_syscon_value
-- jh7110_pll0_syscon_freq[PLL0_FREQ_MAX] = {
-- [PLL0_FREQ_375] = {
-+static const struct jh7110_pll_syscon_val
-+ jh7110_pll0_syscon_val_preset[] = {
-+ [JH7110_PLL0_FREQ_375] = {
- .freq = 375000000,
- .prediv = 8,
- .fbdiv = 125,
-@@ -168,7 +206,7 @@ static const struct starfive_pll_syscon_
- .dacpd = 1,
- .dsmpd = 1,
- },
-- [PLL0_FREQ_500] = {
-+ [JH7110_PLL0_FREQ_500] = {
- .freq = 500000000,
- .prediv = 6,
- .fbdiv = 125,
-@@ -176,7 +214,7 @@ static const struct starfive_pll_syscon_
- .dacpd = 1,
- .dsmpd = 1,
- },
-- [PLL0_FREQ_625] = {
-+ [JH7110_PLL0_FREQ_625] = {
- .freq = 625000000,
- .prediv = 24,
- .fbdiv = 625,
-@@ -184,7 +222,7 @@ static const struct starfive_pll_syscon_
- .dacpd = 1,
- .dsmpd = 1,
- },
-- [PLL0_FREQ_750] = {
-+ [JH7110_PLL0_FREQ_750] = {
- .freq = 750000000,
- .prediv = 4,
- .fbdiv = 125,
-@@ -192,7 +230,7 @@ static const struct starfive_pll_syscon_
- .dacpd = 1,
- .dsmpd = 1,
- },
-- [PLL0_FREQ_875] = {
-+ [JH7110_PLL0_FREQ_875] = {
- .freq = 875000000,
- .prediv = 24,
- .fbdiv = 875,
-@@ -200,7 +238,7 @@ static const struct starfive_pll_syscon_
- .dacpd = 1,
- .dsmpd = 1,
- },
-- [PLL0_FREQ_1000] = {
-+ [JH7110_PLL0_FREQ_1000] = {
- .freq = 1000000000,
- .prediv = 3,
- .fbdiv = 125,
-@@ -208,7 +246,7 @@ static const struct starfive_pll_syscon_
- .dacpd = 1,
- .dsmpd = 1,
- },
-- [PLL0_FREQ_1250] = {
-+ [JH7110_PLL0_FREQ_1250] = {
- .freq = 1250000000,
- .prediv = 12,
- .fbdiv = 625,
-@@ -216,7 +254,7 @@ static const struct starfive_pll_syscon_
- .dacpd = 1,
- .dsmpd = 1,
- },
-- [PLL0_FREQ_1375] = {
-+ [JH7110_PLL0_FREQ_1375] = {
- .freq = 1375000000,
- .prediv = 24,
- .fbdiv = 1375,
-@@ -224,7 +262,7 @@ static const struct starfive_pll_syscon_
- .dacpd = 1,
- .dsmpd = 1,
- },
-- [PLL0_FREQ_1500] = {
-+ [JH7110_PLL0_FREQ_1500] = {
- .freq = 1500000000,
- .prediv = 2,
- .fbdiv = 125,
-@@ -234,9 +272,9 @@ static const struct starfive_pll_syscon_
- },
- };
-
--static const struct starfive_pll_syscon_value
-- jh7110_pll1_syscon_freq[PLL1_FREQ_MAX] = {
-- [PLL1_FREQ_1066] = {
-+static const struct jh7110_pll_syscon_val
-+ jh7110_pll1_syscon_val_preset[] = {
-+ [JH7110_PLL1_FREQ_1066] = {
- .freq = 1066000000,
- .prediv = 12,
- .fbdiv = 533,
-@@ -244,7 +282,7 @@ static const struct starfive_pll_syscon_
- .dacpd = 1,
- .dsmpd = 1,
- },
-- [PLL1_FREQ_1200] = {
-+ [JH7110_PLL1_FREQ_1200] = {
- .freq = 1200000000,
- .prediv = 1,
- .fbdiv = 50,
-@@ -252,7 +290,7 @@ static const struct starfive_pll_syscon_
- .dacpd = 1,
- .dsmpd = 1,
- },
-- [PLL1_FREQ_1400] = {
-+ [JH7110_PLL1_FREQ_1400] = {
- .freq = 1400000000,
- .prediv = 6,
- .fbdiv = 350,
-@@ -260,7 +298,7 @@ static const struct starfive_pll_syscon_
- .dacpd = 1,
- .dsmpd = 1,
- },
-- [PLL1_FREQ_1600] = {
-+ [JH7110_PLL1_FREQ_1600] = {
- .freq = 1600000000,
- .prediv = 3,
- .fbdiv = 200,
-@@ -270,9 +308,9 @@ static const struct starfive_pll_syscon_
- },
- };
-
--static const struct starfive_pll_syscon_value
-- jh7110_pll2_syscon_freq[PLL2_FREQ_MAX] = {
-- [PLL2_FREQ_1188] = {
-+static const struct jh7110_pll_syscon_val
-+ jh7110_pll2_syscon_val_preset[] = {
-+ [JH7110_PLL2_FREQ_1188] = {
- .freq = 1188000000,
- .prediv = 2,
- .fbdiv = 99,
-@@ -280,7 +318,7 @@ static const struct starfive_pll_syscon_
- .dacpd = 1,
- .dsmpd = 1,
- },
-- [PLL2_FREQ_12288] = {
-+ [JH7110_PLL2_FREQ_12288] = {
- .freq = 1228800000,
- .prediv = 5,
- .fbdiv = 256,
diff --git a/target/linux/starfive/patches-6.1/0059-dt-bindings-timer-Add-timer-for-StarFive-JH7110-SoC.patch b/target/linux/starfive/patches-6.1/0059-dt-bindings-timer-Add-timer-for-StarFive-JH7110-SoC.patch
deleted file mode 100644
index f0b5b98610..0000000000
--- a/target/linux/starfive/patches-6.1/0059-dt-bindings-timer-Add-timer-for-StarFive-JH7110-SoC.patch
+++ /dev/null
@@ -1,113 +0,0 @@
-From 944b96d734199642e2ede978c48d754109ca334c Mon Sep 17 00:00:00 2001
-From: Xingyu Wu <xingyu.wu@starfivetech.com>
-Date: Mon, 20 Mar 2023 21:54:31 +0800
-Subject: [PATCH 059/122] dt-bindings: timer: Add timer for StarFive JH7110 SoC
-
-Add bindings for the timer on the JH7110 RISC-V SoC
-by StarFive Technology Ltd.
-
-Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
-Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
----
- .../bindings/timer/starfive,jh7110-timer.yaml | 95 +++++++++++++++++++
- 1 file changed, 95 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/timer/starfive,jh7110-timer.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/timer/starfive,jh7110-timer.yaml
-@@ -0,0 +1,95 @@
-+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/timer/starfive,jh7110-timer.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: StarFive JH7110 Timer
-+maintainers:
-+ - Xingyu Wu <xingyu.wu@starfivetech.com>
-+ - Samin Guo <samin.guo@starfivetech.com>
-+
-+description:
-+ This timer has four free-running 32 bit counters in StarFive JH7110 SoC.
-+ And each channel(counter) triggers an interrupt when timeout. They support
-+ one-shot mode and continuous-run mode.
-+
-+properties:
-+ compatible:
-+ const: starfive,jh7110-timer
-+
-+ reg:
-+ maxItems: 1
-+
-+ interrupts:
-+ items:
-+ - description: channel 0
-+ - description: channel 1
-+ - description: channel 2
-+ - description: channel 3
-+
-+ clocks:
-+ items:
-+ - description: timer APB
-+ - description: channel 0
-+ - description: channel 1
-+ - description: channel 2
-+ - description: channel 3
-+
-+ clock-names:
-+ items:
-+ - const: apb
-+ - const: ch0
-+ - const: ch1
-+ - const: ch2
-+ - const: ch3
-+
-+ resets:
-+ items:
-+ - description: timer APB
-+ - description: channel 0
-+ - description: channel 1
-+ - description: channel 2
-+ - description: channel 3
-+
-+ reset-names:
-+ items:
-+ - const: apb
-+ - const: ch0
-+ - const: ch1
-+ - const: ch2
-+ - const: ch3
-+
-+required:
-+ - compatible
-+ - reg
-+ - interrupts
-+ - clocks
-+ - clock-names
-+ - resets
-+ - reset-names
-+
-+additionalProperties: false
-+
-+examples:
-+ - |
-+ timer@13050000 {
-+ compatible = "starfive,jh7110-timer";
-+ reg = <0x13050000 0x10000>;
-+ interrupts = <69>, <70>, <71> ,<72>;
-+ clocks = <&clk 124>,
-+ <&clk 125>,
-+ <&clk 126>,
-+ <&clk 127>,
-+ <&clk 128>;
-+ clock-names = "apb", "ch0", "ch1",
-+ "ch2", "ch3";
-+ resets = <&rst 117>,
-+ <&rst 118>,
-+ <&rst 119>,
-+ <&rst 120>,
-+ <&rst 121>;
-+ reset-names = "apb", "ch0", "ch1",
-+ "ch2", "ch3";
-+ };
-+
diff --git a/target/linux/starfive/patches-6.1/0060-clocksource-Add-StarFive-timer-driver.patch b/target/linux/starfive/patches-6.1/0060-clocksource-Add-StarFive-timer-driver.patch
deleted file mode 100644
index dc6f1e0bf8..0000000000
--- a/target/linux/starfive/patches-6.1/0060-clocksource-Add-StarFive-timer-driver.patch
+++ /dev/null
@@ -1,540 +0,0 @@
-From 3fbdabd59bac0978536fb11b1b9deb81559f1c54 Mon Sep 17 00:00:00 2001
-From: Xingyu Wu <xingyu.wu@starfivetech.com>
-Date: Mon, 20 Mar 2023 21:54:32 +0800
-Subject: [PATCH 060/122] clocksource: Add StarFive timer driver
-
-Add timer driver for the StarFive JH7110 SoC.
-
-Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
----
- drivers/clocksource/Kconfig | 12 +
- drivers/clocksource/Makefile | 1 +
- drivers/clocksource/timer-starfive.c | 390 +++++++++++++++++++++++++++
- drivers/clocksource/timer-starfive.h | 96 +++++++
- 4 files changed, 499 insertions(+)
- create mode 100644 drivers/clocksource/timer-starfive.c
- create mode 100644 drivers/clocksource/timer-starfive.h
-
---- a/drivers/clocksource/Kconfig
-+++ b/drivers/clocksource/Kconfig
-@@ -630,6 +630,18 @@ config RISCV_TIMER
- is accessed via both the SBI and the rdcycle instruction. This is
- required for all RISC-V systems.
-
-+config STARFIVE_TIMER
-+ bool "Timer for the STARFIVE SoCs"
-+ depends on ARCH_STARFIVE || COMPILE_TEST
-+ select TIMER_OF
-+ select CLKSRC_MMIO
-+ default ARCH_STARFIVE
-+ help
-+ This enables the timer for StarFive SoCs. On RISC-V platform,
-+ the system has started RISCV_TIMER. But you can also use this timer
-+ to do a lot more on StarFive SoCs. This timer can provide high
-+ precision and four channels to use in JH7110 SoC.
-+
- config CLINT_TIMER
- bool "CLINT Timer for the RISC-V platform" if COMPILE_TEST
- depends on GENERIC_SCHED_CLOCK && RISCV
---- a/drivers/clocksource/Makefile
-+++ b/drivers/clocksource/Makefile
-@@ -80,6 +80,7 @@ obj-$(CONFIG_INGENIC_TIMER) += ingenic-
- obj-$(CONFIG_CLKSRC_ST_LPC) += clksrc_st_lpc.o
- obj-$(CONFIG_X86_NUMACHIP) += numachip.o
- obj-$(CONFIG_RISCV_TIMER) += timer-riscv.o
-+obj-$(CONFIG_STARFIVE_TIMER) += timer-starfive.o
- obj-$(CONFIG_CLINT_TIMER) += timer-clint.o
- obj-$(CONFIG_CSKY_MP_TIMER) += timer-mp-csky.o
- obj-$(CONFIG_GX6605S_TIMER) += timer-gx6605s.o
---- /dev/null
-+++ b/drivers/clocksource/timer-starfive.c
-@@ -0,0 +1,390 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Starfive Timer driver
-+ *
-+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
-+ *
-+ * Author:
-+ * Xingyu Wu <xingyu.wu@starfivetech.com>
-+ * Samin Guo <samin.guo@starfivetech.com>
-+ */
-+
-+#include <linux/clk.h>
-+#include <linux/clockchips.h>
-+#include <linux/clocksource.h>
-+#include <linux/err.h>
-+#include <linux/interrupt.h>
-+#include <linux/io.h>
-+#include <linux/iopoll.h>
-+#include <linux/irq.h>
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/of_device.h>
-+#include <linux/platform_device.h>
-+#include <linux/reset.h>
-+#include <linux/sched_clock.h>
-+
-+#include "timer-starfive.h"
-+
-+static const struct starfive_timer_chan_base starfive_timer_jh7110_base = {
-+ .ctrl = STARFIVE_TIMER_JH7110_CTL,
-+ .load = STARFIVE_TIMER_JH7110_LOAD,
-+ .enable = STARFIVE_TIMER_JH7110_ENABLE,
-+ .reload = STARFIVE_TIMER_JH7110_RELOAD,
-+ .value = STARFIVE_TIMER_JH7110_VALUE,
-+ .intclr = STARFIVE_TIMER_JH7110_INT_CLR,
-+ .intmask = STARFIVE_TIMER_JH7110_INT_MASK,
-+ .channel_num = STARFIVE_TIMER_CH_4,
-+ .channel_base = {STARFIVE_TIMER_CH_BASE(0), STARFIVE_TIMER_CH_BASE(1),
-+ STARFIVE_TIMER_CH_BASE(2), STARFIVE_TIMER_CH_BASE(3)},
-+};
-+
-+static inline struct starfive_clkevt *to_starfive_clkevt(struct clock_event_device *evt)
-+{
-+ return container_of(evt, struct starfive_clkevt, evt);
-+}
-+
-+/* 0:continuous-run mode, 1:single-run mode */
-+static inline void starfive_timer_set_mod(struct starfive_clkevt *clkevt, int mod)
-+{
-+ writel(mod, clkevt->ctrl);
-+}
-+
-+/* Interrupt Mask Register, 0:Unmask, 1:Mask */
-+static inline void starfive_timer_int_enable(struct starfive_clkevt *clkevt)
-+{
-+ writel(STARFIVE_TIMER_INTMASK_DIS, clkevt->intmask);
-+}
-+
-+static inline void starfive_timer_int_disable(struct starfive_clkevt *clkevt)
-+{
-+ writel(STARFIVE_TIMER_INTMASK_ENA, clkevt->intmask);
-+}
-+
-+/*
-+ * BIT(0): Read value represent channel intr status.
-+ * Write 1 to this bit to clear interrupt. Write 0 has no effects.
-+ * BIT(1): "1" means that it is clearing interrupt. BIT(0) can not be written.
-+ */
-+static inline int starfive_timer_int_clear(struct starfive_clkevt *clkevt)
-+{
-+ u32 value;
-+ int ret;
-+
-+ /* waiting interrupt can be to clearing */
-+ ret = readl_poll_timeout_atomic(clkevt->intclr, value,
-+ !(value & STARFIVE_TIMER_JH7110_INT_CLR_AVA_MASK),
-+ STARFIVE_DELAY_US, STARFIVE_TIMEOUT_US);
-+ if (!ret)
-+ writel(0x1, clkevt->intclr);
-+
-+ return ret;
-+}
-+
-+/*
-+ * The initial value to be loaded into the
-+ * counter and is also used as the reload value.
-+ * val = clock rate --> 1s
-+ */
-+static inline void starfive_timer_set_load(struct starfive_clkevt *clkevt, u32 val)
-+{
-+ writel(val, clkevt->load);
-+}
-+
-+static inline u32 starfive_timer_get_val(struct starfive_clkevt *clkevt)
-+{
-+ return readl(clkevt->value);
-+}
-+
-+/*
-+ * Write RELOAD register to reload preset value to counter.
-+ * (Write 0 and write 1 are both ok)
-+ */
-+static inline void starfive_timer_set_reload(struct starfive_clkevt *clkevt)
-+{
-+ writel(0, clkevt->reload);
-+}
-+
-+static inline void starfive_timer_enable(struct starfive_clkevt *clkevt)
-+{
-+ writel(STARFIVE_TIMER_ENA, clkevt->enable);
-+}
-+
-+static inline void starfive_timer_disable(struct starfive_clkevt *clkevt)
-+{
-+ writel(STARFIVE_TIMER_DIS, clkevt->enable);
-+}
-+
-+static int starfive_timer_int_init_enable(struct starfive_clkevt *clkevt)
-+{
-+ int ret;
-+
-+ starfive_timer_int_disable(clkevt);
-+ ret = starfive_timer_int_clear(clkevt);
-+ if (ret)
-+ return ret;
-+
-+ starfive_timer_int_enable(clkevt);
-+ starfive_timer_enable(clkevt);
-+
-+ return 0;
-+}
-+
-+static int starfive_timer_shutdown(struct clock_event_device *evt)
-+{
-+ struct starfive_clkevt *clkevt = to_starfive_clkevt(evt);
-+
-+ starfive_timer_disable(clkevt);
-+ return starfive_timer_int_clear(clkevt);
-+}
-+
-+static void starfive_timer_suspend(struct clock_event_device *evt)
-+{
-+ struct starfive_clkevt *clkevt = to_starfive_clkevt(evt);
-+
-+ clkevt->reload_val = starfive_timer_get_val(clkevt);
-+ starfive_timer_shutdown(evt);
-+}
-+
-+static void starfive_timer_resume(struct clock_event_device *evt)
-+{
-+ struct starfive_clkevt *clkevt = to_starfive_clkevt(evt);
-+
-+ starfive_timer_set_load(clkevt, clkevt->reload_val);
-+ starfive_timer_set_reload(clkevt);
-+ starfive_timer_int_enable(clkevt);
-+ starfive_timer_enable(clkevt);
-+}
-+
-+static int starfive_timer_tick_resume(struct clock_event_device *evt)
-+{
-+ starfive_timer_resume(evt);
-+
-+ return 0;
-+}
-+
-+static int starfive_clocksource_init(struct starfive_clkevt *clkevt)
-+{
-+ int ret;
-+
-+ starfive_timer_set_mod(clkevt, STARFIVE_TIMER_MOD_CONTIN);
-+ starfive_timer_set_load(clkevt, STARFIVE_TIMER_MAX_TICKS);
-+ ret = starfive_timer_int_init_enable(clkevt);
-+ if (ret)
-+ return ret;
-+
-+ return clocksource_mmio_init(clkevt->value, clkevt->name, clkevt->rate,
-+ STARFIVE_CLOCK_SOURCE_RATING, STARFIVE_VALID_BITS,
-+ clocksource_mmio_readl_down);
-+}
-+
-+/* IRQ handler for the timer */
-+static irqreturn_t starfive_timer_interrupt(int irq, void *priv)
-+{
-+ struct clock_event_device *evt = (struct clock_event_device *)priv;
-+ struct starfive_clkevt *clkevt = to_starfive_clkevt(evt);
-+
-+ if (starfive_timer_int_clear(clkevt))
-+ return IRQ_NONE;
-+
-+ if (evt->event_handler)
-+ evt->event_handler(evt);
-+
-+ return IRQ_HANDLED;
-+}
-+
-+static int starfive_timer_set_periodic(struct clock_event_device *evt)
-+{
-+ struct starfive_clkevt *clkevt = to_starfive_clkevt(evt);
-+
-+ starfive_timer_disable(clkevt);
-+ starfive_timer_set_mod(clkevt, STARFIVE_TIMER_MOD_CONTIN);
-+ starfive_timer_set_load(clkevt, clkevt->periodic);
-+
-+ return starfive_timer_int_init_enable(clkevt);
-+}
-+
-+static int starfive_timer_set_oneshot(struct clock_event_device *evt)
-+{
-+ struct starfive_clkevt *clkevt = to_starfive_clkevt(evt);
-+
-+ starfive_timer_disable(clkevt);
-+ starfive_timer_set_mod(clkevt, STARFIVE_TIMER_MOD_SINGLE);
-+ starfive_timer_set_load(clkevt, STARFIVE_TIMER_MAX_TICKS);
-+
-+ return starfive_timer_int_init_enable(clkevt);
-+}
-+
-+static int starfive_timer_set_next_event(unsigned long next,
-+ struct clock_event_device *evt)
-+{
-+ struct starfive_clkevt *clkevt = to_starfive_clkevt(evt);
-+
-+ starfive_timer_disable(clkevt);
-+ starfive_timer_set_mod(clkevt, STARFIVE_TIMER_MOD_SINGLE);
-+ starfive_timer_set_load(clkevt, next);
-+ starfive_timer_enable(clkevt);
-+
-+ return 0;
-+}
-+
-+static void starfive_set_clockevent(struct clock_event_device *evt)
-+{
-+ evt->features = CLOCK_EVT_FEAT_PERIODIC |
-+ CLOCK_EVT_FEAT_ONESHOT |
-+ CLOCK_EVT_FEAT_DYNIRQ;
-+ evt->set_state_shutdown = starfive_timer_shutdown;
-+ evt->set_state_periodic = starfive_timer_set_periodic;
-+ evt->set_state_oneshot = starfive_timer_set_oneshot;
-+ evt->set_state_oneshot_stopped = starfive_timer_shutdown;
-+ evt->tick_resume = starfive_timer_tick_resume;
-+ evt->set_next_event = starfive_timer_set_next_event;
-+ evt->suspend = starfive_timer_suspend;
-+ evt->resume = starfive_timer_resume;
-+ evt->rating = STARFIVE_CLOCKEVENT_RATING;
-+}
-+
-+static void starfive_clockevents_register(struct starfive_clkevt *clkevt)
-+{
-+ clkevt->rate = clk_get_rate(clkevt->clk);
-+ clkevt->periodic = DIV_ROUND_CLOSEST(clkevt->rate, HZ);
-+
-+ starfive_set_clockevent(&clkevt->evt);
-+ clkevt->evt.name = clkevt->name;
-+ clkevt->evt.irq = clkevt->irq;
-+ clkevt->evt.cpumask = cpu_possible_mask;
-+
-+ clockevents_config_and_register(&clkevt->evt, clkevt->rate,
-+ STARFIVE_TIMER_MIN_TICKS, STARFIVE_TIMER_MAX_TICKS);
-+}
-+
-+static void __init starfive_clkevt_base_init(const struct starfive_timer_chan_base *timer,
-+ struct starfive_clkevt *clkevt,
-+ void __iomem *base, int ch)
-+{
-+ void __iomem *channel_base;
-+
-+ channel_base = base + timer->channel_base[ch];
-+ clkevt->base = channel_base;
-+ clkevt->ctrl = channel_base + timer->ctrl;
-+ clkevt->load = channel_base + timer->load;
-+ clkevt->enable = channel_base + timer->enable;
-+ clkevt->reload = channel_base + timer->reload;
-+ clkevt->value = channel_base + timer->value;
-+ clkevt->intclr = channel_base + timer->intclr;
-+ clkevt->intmask = channel_base + timer->intmask;
-+}
-+
-+static int __init starfive_timer_probe(struct platform_device *pdev)
-+{
-+ const struct starfive_timer_chan_base *timer_base = of_device_get_match_data(&pdev->dev);
-+ char name[10];
-+ struct starfive_timer_priv *priv;
-+ struct starfive_clkevt *clkevt;
-+ struct clk *pclk;
-+ struct reset_control *rst;
-+ int ch;
-+ int ret;
-+
-+ priv = devm_kzalloc(&pdev->dev, struct_size(priv, clkevt, timer_base->channel_num),
-+ GFP_KERNEL);
-+ if (!priv)
-+ return -ENOMEM;
-+
-+ priv->base = devm_platform_ioremap_resource(pdev, 0);
-+ if (IS_ERR(priv->base))
-+ return dev_err_probe(&pdev->dev, PTR_ERR(priv->base),
-+ "failed to map registers\n");
-+
-+ rst = devm_reset_control_get_exclusive(&pdev->dev, "apb");
-+ if (IS_ERR(rst))
-+ return dev_err_probe(&pdev->dev, PTR_ERR(rst), "failed to get apb reset\n");
-+
-+ pclk = devm_clk_get_enabled(&pdev->dev, "apb");
-+ if (IS_ERR(pclk))
-+ return dev_err_probe(&pdev->dev, PTR_ERR(pclk),
-+ "failed to get & enable apb clock\n");
-+
-+ ret = reset_control_deassert(rst);
-+ if (ret)
-+ goto err;
-+
-+ priv->dev = &pdev->dev;
-+ platform_set_drvdata(pdev, priv);
-+
-+ for (ch = 0; ch < timer_base->channel_num; ch++) {
-+ clkevt = &priv->clkevt[ch];
-+ snprintf(name, sizeof(name), "ch%d", ch);
-+
-+ starfive_clkevt_base_init(timer_base, clkevt, priv->base, ch);
-+ /* Ensure timers are disabled */
-+ starfive_timer_disable(clkevt);
-+
-+ rst = devm_reset_control_get_exclusive(&pdev->dev, name);
-+ if (IS_ERR(rst)) {
-+ ret = PTR_ERR(rst);
-+ goto err;
-+ }
-+
-+ clkevt->clk = devm_clk_get_enabled(&pdev->dev, name);
-+ if (IS_ERR(clkevt->clk)) {
-+ ret = PTR_ERR(clkevt->clk);
-+ goto err;
-+ }
-+
-+ ret = reset_control_deassert(rst);
-+ if (ret)
-+ goto ch_err;
-+
-+ clkevt->irq = platform_get_irq(pdev, ch);
-+ if (clkevt->irq < 0) {
-+ ret = clkevt->irq;
-+ goto ch_err;
-+ }
-+
-+ snprintf(clkevt->name, sizeof(clkevt->name), "%s.ch%d", pdev->name, ch);
-+ starfive_clockevents_register(clkevt);
-+
-+ ret = devm_request_irq(&pdev->dev, clkevt->irq, starfive_timer_interrupt,
-+ IRQF_TIMER | IRQF_IRQPOLL,
-+ clkevt->name, &clkevt->evt);
-+ if (ret)
-+ goto ch_err;
-+
-+ ret = starfive_clocksource_init(clkevt);
-+ if (ret)
-+ goto ch_err;
-+ }
-+
-+ return 0;
-+
-+ch_err:
-+ /* Only unregister the failed channel and the rest timer channels continue to work. */
-+ clk_disable_unprepare(clkevt->clk);
-+err:
-+ /* If no other channel successfully registers, pclk should be disabled. */
-+ if (!ch)
-+ clk_disable_unprepare(pclk);
-+
-+ return ret;
-+}
-+
-+static const struct of_device_id starfive_timer_match[] = {
-+ { .compatible = "starfive,jh7110-timer", .data = &starfive_timer_jh7110_base },
-+ { /* sentinel */ }
-+};
-+MODULE_DEVICE_TABLE(of, starfive_timer_match);
-+
-+static struct platform_driver starfive_timer_driver = {
-+ .probe = starfive_timer_probe,
-+ .driver = {
-+ .name = "starfive-timer",
-+ .of_match_table = starfive_timer_match,
-+ },
-+};
-+module_platform_driver(starfive_timer_driver);
-+
-+MODULE_AUTHOR("Xingyu Wu <xingyu.wu@starfivetech.com>");
-+MODULE_DESCRIPTION("StarFive timer driver");
-+MODULE_LICENSE("GPL");
---- /dev/null
-+++ b/drivers/clocksource/timer-starfive.h
-@@ -0,0 +1,96 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+/*
-+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
-+ */
-+
-+#ifndef __STARFIVE_TIMER_H__
-+#define __STARFIVE_TIMER_H__
-+
-+/* Bias: Ch0-0x0, Ch1-0x40, Ch2-0x80, and so on. */
-+#define STARFIVE_TIMER_CH_LEN 0x40
-+#define STARFIVE_TIMER_CH_BASE(x) ((STARFIVE_TIMER_CH_##x) * STARFIVE_TIMER_CH_LEN)
-+
-+#define STARFIVE_CLOCK_SOURCE_RATING 200
-+#define STARFIVE_VALID_BITS 32
-+#define STARFIVE_DELAY_US 0
-+#define STARFIVE_TIMEOUT_US 10000
-+#define STARFIVE_CLOCKEVENT_RATING 300
-+#define STARFIVE_TIMER_MAX_TICKS 0xffffffff
-+#define STARFIVE_TIMER_MIN_TICKS 0xf
-+
-+#define STARFIVE_TIMER_JH7110_INT_STATUS 0x00 /* RO[0:4]: Interrupt Status for channel0~4 */
-+#define STARFIVE_TIMER_JH7110_CTL 0x04 /* RW[0]: 0-continuous run, 1-single run */
-+#define STARFIVE_TIMER_JH7110_LOAD 0x08 /* RW: load value to counter */
-+#define STARFIVE_TIMER_JH7110_ENABLE 0x10 /* RW[0]: timer enable register */
-+#define STARFIVE_TIMER_JH7110_RELOAD 0x14 /* RW: write 1 or 0 both reload counter */
-+#define STARFIVE_TIMER_JH7110_VALUE 0x18 /* RO: timer value register */
-+#define STARFIVE_TIMER_JH7110_INT_CLR 0x20 /* RW: timer interrupt clear register */
-+#define STARFIVE_TIMER_JH7110_INT_MASK 0x24 /* RW[0]: timer interrupt mask register */
-+#define STARFIVE_TIMER_JH7110_INT_CLR_AVA_MASK BIT(1)
-+
-+enum STARFIVE_TIMER_CH {
-+ STARFIVE_TIMER_CH_0 = 0,
-+ STARFIVE_TIMER_CH_1,
-+ STARFIVE_TIMER_CH_2,
-+ STARFIVE_TIMER_CH_3,
-+ STARFIVE_TIMER_CH_4,
-+ STARFIVE_TIMER_CH_5,
-+ STARFIVE_TIMER_CH_6,
-+ STARFIVE_TIMER_CH_7,
-+ STARFIVE_TIMER_CH_MAX
-+};
-+
-+enum STARFIVE_TIMER_INTMASK {
-+ STARFIVE_TIMER_INTMASK_DIS = 0,
-+ STARFIVE_TIMER_INTMASK_ENA = 1
-+};
-+
-+enum STARFIVE_TIMER_MOD {
-+ STARFIVE_TIMER_MOD_CONTIN = 0,
-+ STARFIVE_TIMER_MOD_SINGLE = 1
-+};
-+
-+enum STARFIVE_TIMER_CTL_EN {
-+ STARFIVE_TIMER_DIS = 0,
-+ STARFIVE_TIMER_ENA = 1
-+};
-+
-+struct starfive_timer_chan_base {
-+ /* Resgister */
-+ unsigned int ctrl;
-+ unsigned int load;
-+ unsigned int enable;
-+ unsigned int reload;
-+ unsigned int value;
-+ unsigned int intclr;
-+ unsigned int intmask;
-+
-+ unsigned int channel_num; /* timer channel numbers */
-+ unsigned int channel_base[];
-+};
-+
-+struct starfive_clkevt {
-+ struct clock_event_device evt;
-+ struct clk *clk;
-+ char name[20];
-+ int irq;
-+ u32 periodic;
-+ u32 rate;
-+ u32 reload_val;
-+ void __iomem *base;
-+ void __iomem *ctrl;
-+ void __iomem *load;
-+ void __iomem *enable;
-+ void __iomem *reload;
-+ void __iomem *value;
-+ void __iomem *intclr;
-+ void __iomem *intmask;
-+};
-+
-+struct starfive_timer_priv {
-+ struct device *dev;
-+ void __iomem *base;
-+ struct starfive_clkevt clkevt[];
-+};
-+
-+#endif /* __STARFIVE_TIMER_H__ */
diff --git a/target/linux/starfive/patches-6.1/0061-dt-bindings-net-motorcomm-Add-pad-driver-strength-cf.patch b/target/linux/starfive/patches-6.1/0061-dt-bindings-net-motorcomm-Add-pad-driver-strength-cf.patch
deleted file mode 100644
index 58f29cda8f..0000000000
--- a/target/linux/starfive/patches-6.1/0061-dt-bindings-net-motorcomm-Add-pad-driver-strength-cf.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From 16214121afaadb8ae9aaf73351e874405eb47c15 Mon Sep 17 00:00:00 2001
-From: Samin Guo <samin.guo@starfivetech.com>
-Date: Tue, 25 Apr 2023 18:51:15 +0800
-Subject: [PATCH 061/122] dt-bindings: net: motorcomm: Add pad driver strength
- cfg
-
-The motorcomm phy (YT8531) supports the ability to adjust the drive
-strength of the rx_clk/rx_data, the value range of pad driver
-strength is 0 to 7.
-
-Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
----
- .../devicetree/bindings/net/motorcomm,yt8xxx.yaml | 12 ++++++++++++
- 1 file changed, 12 insertions(+)
-
---- a/Documentation/devicetree/bindings/net/motorcomm,yt8xxx.yaml
-+++ b/Documentation/devicetree/bindings/net/motorcomm,yt8xxx.yaml
-@@ -62,6 +62,18 @@ properties:
- for a timer.
- type: boolean
-
-+ motorcomm,rx-clk-driver-strength:
-+ description: drive strength of rx_clk pad.
-+ $ref: /schemas/types.yaml#/definitions/uint32
-+ enum: [ 0, 1, 2, 3, 4, 5, 6, 7 ]
-+ default: 3
-+
-+ motorcomm,rx-data-driver-strength:
-+ description: drive strength of rx_data/rx_ctl rgmii pad.
-+ $ref: /schemas/types.yaml#/definitions/uint32
-+ enum: [ 0, 1, 2, 3, 4, 5, 6, 7 ]
-+ default: 3
-+
- motorcomm,tx-clk-adj-enabled:
- description: |
- This configuration is mainly to adapt to VF2 with JH7110 SoC.
diff --git a/target/linux/starfive/patches-6.1/0062-dt-bindings-PWM-Add-StarFive-PWM-module.patch b/target/linux/starfive/patches-6.1/0062-dt-bindings-PWM-Add-StarFive-PWM-module.patch
deleted file mode 100644
index 20546650a3..0000000000
--- a/target/linux/starfive/patches-6.1/0062-dt-bindings-PWM-Add-StarFive-PWM-module.patch
+++ /dev/null
@@ -1,71 +0,0 @@
-From 99f0bf43994dada29e33fd8718fd25484634da3a Mon Sep 17 00:00:00 2001
-From: William Qiu <william.qiu@starfivetech.com>
-Date: Tue, 21 Mar 2023 13:52:27 +0800
-Subject: [PATCH 062/122] dt-bindings: PWM: Add StarFive PWM module
-
-Add documentation to describe StarFive Pulse Width Modulation
-controller driver.
-
-Signed-off-by: William Qiu <william.qiu@starfivetech.com>
-Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
----
- .../bindings/pwm/starfive,jh7110-pwm.yaml | 53 +++++++++++++++++++
- 1 file changed, 53 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/pwm/starfive,jh7110-pwm.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/pwm/starfive,jh7110-pwm.yaml
-@@ -0,0 +1,53 @@
-+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/pwm/starfive,jh7110-pwm.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: StarFive PWM controller
-+
-+maintainers:
-+ - William Qiu <william.qiu@starfivetech.com>
-+
-+description:
-+ StarFive SoCs contain PWM and when operating in PWM mode, the PTC core generates
-+ binary signal with user-programmable low and high periods. Clock source for the
-+ PWM can be either system clockor external clock. Each PWM timer block provides 8
-+ PWM channels.
-+
-+allOf:
-+ - $ref: pwm.yaml#
-+
-+properties:
-+ compatible:
-+ const: starfive,jh7110-pwm
-+
-+ reg:
-+ maxItems: 1
-+
-+ clocks:
-+ maxItems: 1
-+
-+ resets:
-+ maxItems: 1
-+
-+ "#pwm-cells":
-+ const: 3
-+
-+required:
-+ - compatible
-+ - reg
-+ - clocks
-+ - resets
-+
-+additionalProperties: false
-+
-+examples:
-+ - |
-+ pwm@120d0000 {
-+ compatible = "starfive,jh7110-pwm";
-+ reg = <0x120d0000 0x10000>;
-+ clocks = <&syscrg 121>;
-+ resets = <&syscrg 108>;
-+ #pwm-cells = <3>;
-+ };
diff --git a/target/linux/starfive/patches-6.1/0063-pwm-starfive-Add-PWM-driver-support.patch b/target/linux/starfive/patches-6.1/0063-pwm-starfive-Add-PWM-driver-support.patch
deleted file mode 100644
index 0433160a20..0000000000
--- a/target/linux/starfive/patches-6.1/0063-pwm-starfive-Add-PWM-driver-support.patch
+++ /dev/null
@@ -1,294 +0,0 @@
-From fddea961e7ce1f26dd549e3d92ede624246690c0 Mon Sep 17 00:00:00 2001
-From: William Qiu <william.qiu@starfivetech.com>
-Date: Tue, 21 Mar 2023 13:52:28 +0800
-Subject: [PATCH 063/122] pwm: starfive: Add PWM driver support
-
-Add Pulse Width Modulation driver support for StarFive
-JH7110 soc.
-
-Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
-Signed-off-by: William Qiu <william.qiu@starfivetech.com>
----
- drivers/pwm/Kconfig | 10 ++
- drivers/pwm/Makefile | 1 +
- drivers/pwm/pwm-starfive-ptc.c | 245 +++++++++++++++++++++++++++++++++
- 3 files changed, 256 insertions(+)
- create mode 100644 drivers/pwm/pwm-starfive-ptc.c
-
---- a/drivers/pwm/Kconfig
-+++ b/drivers/pwm/Kconfig
-@@ -536,6 +536,16 @@ config PWM_SPRD
- To compile this driver as a module, choose M here: the module
- will be called pwm-sprd.
-
-+config PWM_STARFIVE_PTC
-+ tristate "StarFive PWM PTC support"
-+ depends on OF
-+ depends on COMMON_CLK
-+ help
-+ Generic PWM framework driver for StarFive SoCs.
-+
-+ To compile this driver as a module, choose M here: the module
-+ will be called pwm-starfive-ptc.
-+
- config PWM_STI
- tristate "STiH4xx PWM support"
- depends on ARCH_STI || COMPILE_TEST
---- a/drivers/pwm/Makefile
-+++ b/drivers/pwm/Makefile
-@@ -49,6 +49,7 @@ obj-$(CONFIG_PWM_SIFIVE) += pwm-sifive.o
- obj-$(CONFIG_PWM_SL28CPLD) += pwm-sl28cpld.o
- obj-$(CONFIG_PWM_SPEAR) += pwm-spear.o
- obj-$(CONFIG_PWM_SPRD) += pwm-sprd.o
-+obj-$(CONFIG_PWM_STARFIVE_PTC) += pwm-starfive-ptc.o
- obj-$(CONFIG_PWM_STI) += pwm-sti.o
- obj-$(CONFIG_PWM_STM32) += pwm-stm32.o
- obj-$(CONFIG_PWM_STM32_LP) += pwm-stm32-lp.o
---- /dev/null
-+++ b/drivers/pwm/pwm-starfive-ptc.c
-@@ -0,0 +1,245 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * PWM driver for the StarFive JH7110 SoC
-+ *
-+ * Copyright (C) 2018 StarFive Technology Co., Ltd.
-+ */
-+
-+#include <dt-bindings/pwm/pwm.h>
-+#include <linux/module.h>
-+#include <linux/platform_device.h>
-+#include <linux/pwm.h>
-+#include <linux/slab.h>
-+#include <linux/clk.h>
-+#include <linux/reset.h>
-+#include <linux/io.h>
-+
-+/* how many parameters can be transferred to ptc */
-+#define OF_PWM_N_CELLS 3
-+
-+/* PTC Register offsets */
-+#define REG_RPTC_CNTR 0x0
-+#define REG_RPTC_HRC 0x4
-+#define REG_RPTC_LRC 0x8
-+#define REG_RPTC_CTRL 0xC
-+
-+/* Bit for PWM clock */
-+#define BIT_PWM_CLOCK_EN 31
-+
-+/* Bit for clock gen soft reset */
-+#define BIT_CLK_GEN_SOFT_RESET 13
-+
-+#define NS_PER_SECOND 1000000000
-+
-+/*
-+ * Access PTC register (cntr hrc lrc and ctrl),
-+ * need to replace PWM_BASE_ADDR
-+ */
-+#define REG_PTC_BASE_ADDR_SUB(base, N) \
-+((base) + (((N) > 3) ? (((N) % 4) * 0x10 + (1 << 15)) : ((N) * 0x10)))
-+#define REG_PTC_RPTC_CNTR(base, N) (REG_PTC_BASE_ADDR_SUB(base, N))
-+#define REG_PTC_RPTC_HRC(base, N) (REG_PTC_BASE_ADDR_SUB(base, N) + 0x4)
-+#define REG_PTC_RPTC_LRC(base, N) (REG_PTC_BASE_ADDR_SUB(base, N) + 0x8)
-+#define REG_PTC_RPTC_CTRL(base, N) (REG_PTC_BASE_ADDR_SUB(base, N) + 0xC)
-+
-+/* PTC_RPTC_CTRL */
-+#define PTC_EN BIT(0)
-+#define PTC_ECLK BIT(1)
-+#define PTC_NEC BIT(2)
-+#define PTC_OE BIT(3)
-+#define PTC_SIGNLE BIT(4)
-+#define PTC_INTE BIT(5)
-+#define PTC_INT BIT(6)
-+#define PTC_CNTRRST BIT(7)
-+#define PTC_CAPTE BIT(8)
-+
-+struct starfive_pwm_ptc_device {
-+ struct pwm_chip chip;
-+ struct clk *clk;
-+ struct reset_control *rst;
-+ void __iomem *regs;
-+ int irq;
-+ unsigned int approx_freq;/*pwm apb clock frequency*/
-+};
-+
-+static inline
-+struct starfive_pwm_ptc_device *chip_to_starfive_ptc(struct pwm_chip *c)
-+{
-+ return container_of(c, struct starfive_pwm_ptc_device, chip);
-+}
-+
-+static int starfive_pwm_ptc_get_state(struct pwm_chip *chip,
-+ struct pwm_device *dev,
-+ struct pwm_state *state)
-+{
-+ struct starfive_pwm_ptc_device *pwm = chip_to_starfive_ptc(chip);
-+ u32 data_lrc, data_hrc;
-+ u32 pwm_clk_ns = 0;
-+
-+ data_lrc = ioread32(REG_PTC_RPTC_LRC(pwm->regs, dev->hwpwm));
-+ data_hrc = ioread32(REG_PTC_RPTC_HRC(pwm->regs, dev->hwpwm));
-+
-+ pwm_clk_ns = NS_PER_SECOND / pwm->approx_freq;
-+
-+ state->period = data_lrc * pwm_clk_ns;
-+ state->duty_cycle = data_hrc * pwm_clk_ns;
-+ state->polarity = PWM_POLARITY_NORMAL;
-+ state->enabled = 1;
-+
-+ return 0;
-+}
-+
-+static int starfive_pwm_ptc_apply(struct pwm_chip *chip,
-+ struct pwm_device *dev,
-+ struct pwm_state *state)
-+{
-+ struct starfive_pwm_ptc_device *pwm = chip_to_starfive_ptc(chip);
-+ u32 data_hrc = 0;
-+ u32 data_lrc = 0;
-+ u32 period_data = 0;
-+ u32 duty_data = 0;
-+ s64 multi = pwm->approx_freq;
-+ s64 div = NS_PER_SECOND;
-+ void __iomem *reg_addr;
-+
-+ if (state->duty_cycle > state->period)
-+ state->duty_cycle = state->period;
-+
-+ while (multi % 10 == 0 && div % 10 == 0 && multi > 0 && div > 0) {
-+ multi /= 10;
-+ div /= 10;
-+ }
-+
-+ period_data = (u32)(state->period * multi / div);
-+ if (abs(period_data * div / multi - state->period)
-+ > abs((period_data + 1) * div / multi - state->period) ||
-+ (state->period > 0 && period_data == 0))
-+ period_data += 1;
-+
-+ if (state->enabled) {
-+ duty_data = (u32)(state->duty_cycle * multi / div);
-+ if (abs(duty_data * div / multi - state->duty_cycle)
-+ > abs((duty_data + 1) * div / multi - state->duty_cycle) ||
-+ (state->duty_cycle > 0 && duty_data == 0))
-+ duty_data += 1;
-+ } else {
-+ duty_data = 0;
-+ }
-+
-+ if (state->polarity == PWM_POLARITY_NORMAL)
-+ data_hrc = period_data - duty_data;
-+ else
-+ data_hrc = duty_data;
-+
-+ data_lrc = period_data;
-+
-+ reg_addr = REG_PTC_RPTC_HRC(pwm->regs, dev->hwpwm);
-+ iowrite32(data_hrc, reg_addr);
-+
-+ reg_addr = REG_PTC_RPTC_LRC(pwm->regs, dev->hwpwm);
-+ iowrite32(data_lrc, reg_addr);
-+
-+ reg_addr = REG_PTC_RPTC_CNTR(pwm->regs, dev->hwpwm);
-+ iowrite32(0, reg_addr);
-+
-+ reg_addr = REG_PTC_RPTC_CTRL(pwm->regs, dev->hwpwm);
-+ iowrite32(PTC_EN | PTC_OE, reg_addr);
-+
-+ return 0;
-+}
-+
-+static const struct pwm_ops starfive_pwm_ptc_ops = {
-+ .get_state = starfive_pwm_ptc_get_state,
-+ .apply = (void *)starfive_pwm_ptc_apply,
-+ .owner = THIS_MODULE,
-+};
-+
-+static int starfive_pwm_ptc_probe(struct platform_device *pdev)
-+{
-+ struct device *dev = &pdev->dev;
-+ struct starfive_pwm_ptc_device *pwm;
-+ struct pwm_chip *chip;
-+ int ret;
-+
-+ pwm = devm_kzalloc(dev, sizeof(*pwm), GFP_KERNEL);
-+ if (!pwm)
-+ return -ENOMEM;
-+
-+ chip = &pwm->chip;
-+ chip->dev = dev;
-+ chip->ops = &starfive_pwm_ptc_ops;
-+ chip->npwm = 8;
-+
-+ chip->of_pwm_n_cells = OF_PWM_N_CELLS;
-+ chip->base = -1;
-+
-+ pwm->regs = devm_platform_ioremap_resource(pdev, 0);
-+ if (IS_ERR(pwm->regs))
-+ return dev_err_probe(dev, PTR_ERR(pwm->regs),
-+ "Unable to map IO resources\n");
-+
-+ pwm->clk = devm_clk_get(dev, NULL);
-+ if (IS_ERR(pwm->clk))
-+ return dev_err_probe(dev, PTR_ERR(pwm->clk),
-+ "Unable to get pwm clock\n");
-+
-+ pwm->rst = devm_reset_control_get_exclusive(dev, NULL);
-+ if (IS_ERR(pwm->rst))
-+ return dev_err_probe(dev, PTR_ERR(pwm->rst),
-+ "Unable to get pwm reset\n");
-+
-+ ret = clk_prepare_enable(pwm->clk);
-+ if (ret) {
-+ dev_err(dev,
-+ "Failed to enable pwm clock, %d\n", ret);
-+ return ret;
-+ }
-+
-+ reset_control_deassert(pwm->rst);
-+
-+ pwm->approx_freq = (unsigned int)clk_get_rate(pwm->clk);
-+ if (!pwm->approx_freq)
-+ dev_err(dev, "get pwm apb clock rate failed.\n");
-+
-+ ret = devm_pwmchip_add(dev, chip);
-+ if (ret < 0) {
-+ dev_err(dev, "cannot register PTC: %d\n", ret);
-+ clk_disable_unprepare(pwm->clk);
-+ return ret;
-+ }
-+
-+ platform_set_drvdata(pdev, pwm);
-+
-+ return 0;
-+}
-+
-+static int starfive_pwm_ptc_remove(struct platform_device *dev)
-+{
-+ struct starfive_pwm_ptc_device *pwm = platform_get_drvdata(dev);
-+ struct pwm_chip *chip = &pwm->chip;
-+
-+ pwmchip_remove(chip);
-+
-+ return 0;
-+}
-+
-+static const struct of_device_id starfive_pwm_ptc_of_match[] = {
-+ { .compatible = "starfive,jh7110-pwm" },
-+ {},
-+};
-+MODULE_DEVICE_TABLE(of, starfive_pwm_ptc_of_match);
-+
-+static struct platform_driver starfive_pwm_ptc_driver = {
-+ .probe = starfive_pwm_ptc_probe,
-+ .remove = starfive_pwm_ptc_remove,
-+ .driver = {
-+ .name = "pwm-starfive-ptc",
-+ .of_match_table = starfive_pwm_ptc_of_match,
-+ },
-+};
-+module_platform_driver(starfive_pwm_ptc_driver);
-+
-+MODULE_AUTHOR("Jenny Zhang <jenny.zhang@starfivetech.com>");
-+MODULE_AUTHOR("Hal Feng <hal.feng@starfivetech.com>");
-+MODULE_DESCRIPTION("StarFive PWM PTC driver");
-+MODULE_LICENSE("GPL");
diff --git a/target/linux/starfive/patches-6.1/0064-dt-bindings-crypto-Add-StarFive-crypto-module.patch b/target/linux/starfive/patches-6.1/0064-dt-bindings-crypto-Add-StarFive-crypto-module.patch
deleted file mode 100644
index 09b2dccef9..0000000000
--- a/target/linux/starfive/patches-6.1/0064-dt-bindings-crypto-Add-StarFive-crypto-module.patch
+++ /dev/null
@@ -1,90 +0,0 @@
-From 207dde3ed123613cd84c8f706a24d75cefece67c Mon Sep 17 00:00:00 2001
-From: Jia Jie Ho <jiajie.ho@starfivetech.com>
-Date: Mon, 15 May 2023 20:53:52 +0800
-Subject: [PATCH 064/122] dt-bindings: crypto: Add StarFive crypto module
-
-Add documentation to describe StarFive cryptographic engine.
-
-Co-developed-by: Huan Feng <huan.feng@starfivetech.com>
-Signed-off-by: Huan Feng <huan.feng@starfivetech.com>
-Signed-off-by: Jia Jie Ho <jiajie.ho@starfivetech.com>
-Reviewed-by: Rob Herring <robh@kernel.org>
-Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
----
- .../crypto/starfive,jh7110-crypto.yaml | 70 +++++++++++++++++++
- 1 file changed, 70 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/crypto/starfive,jh7110-crypto.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/crypto/starfive,jh7110-crypto.yaml
-@@ -0,0 +1,70 @@
-+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/crypto/starfive,jh7110-crypto.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: StarFive Cryptographic Module
-+
-+maintainers:
-+ - Jia Jie Ho <jiajie.ho@starfivetech.com>
-+ - William Qiu <william.qiu@starfivetech.com>
-+
-+properties:
-+ compatible:
-+ const: starfive,jh7110-crypto
-+
-+ reg:
-+ maxItems: 1
-+
-+ clocks:
-+ items:
-+ - description: Hardware reference clock
-+ - description: AHB reference clock
-+
-+ clock-names:
-+ items:
-+ - const: hclk
-+ - const: ahb
-+
-+ interrupts:
-+ maxItems: 1
-+
-+ resets:
-+ maxItems: 1
-+
-+ dmas:
-+ items:
-+ - description: TX DMA channel
-+ - description: RX DMA channel
-+
-+ dma-names:
-+ items:
-+ - const: tx
-+ - const: rx
-+
-+required:
-+ - compatible
-+ - reg
-+ - clocks
-+ - clock-names
-+ - resets
-+ - dmas
-+ - dma-names
-+
-+additionalProperties: false
-+
-+examples:
-+ - |
-+ crypto: crypto@16000000 {
-+ compatible = "starfive,jh7110-crypto";
-+ reg = <0x16000000 0x4000>;
-+ clocks = <&clk 15>, <&clk 16>;
-+ clock-names = "hclk", "ahb";
-+ interrupts = <28>;
-+ resets = <&reset 3>;
-+ dmas = <&dma 1 2>,
-+ <&dma 0 2>;
-+ dma-names = "tx", "rx";
-+ };
-+...
diff --git a/target/linux/starfive/patches-6.1/0065-crypto-starfive-Add-crypto-engine-support.patch b/target/linux/starfive/patches-6.1/0065-crypto-starfive-Add-crypto-engine-support.patch
deleted file mode 100644
index 5aa3bc10f6..0000000000
--- a/target/linux/starfive/patches-6.1/0065-crypto-starfive-Add-crypto-engine-support.patch
+++ /dev/null
@@ -1,337 +0,0 @@
-From 8b1069fcc1dbb524556d851f3dedf0629a71f17b Mon Sep 17 00:00:00 2001
-From: Jia Jie Ho <jiajie.ho@starfivetech.com>
-Date: Mon, 15 May 2023 20:53:53 +0800
-Subject: [PATCH 065/122] crypto: starfive - Add crypto engine support
-
-Adding device probe and DMA init for StarFive cryptographic module.
-
-Co-developed-by: Huan Feng <huan.feng@starfivetech.com>
-Signed-off-by: Huan Feng <huan.feng@starfivetech.com>
-Signed-off-by: Jia Jie Ho <jiajie.ho@starfivetech.com>
-Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
----
- drivers/crypto/Kconfig | 1 +
- drivers/crypto/Makefile | 1 +
- drivers/crypto/starfive/Kconfig | 17 +++
- drivers/crypto/starfive/Makefile | 4 +
- drivers/crypto/starfive/jh7110-cryp.c | 201 ++++++++++++++++++++++++++
- drivers/crypto/starfive/jh7110-cryp.h | 63 ++++++++
- 6 files changed, 287 insertions(+)
- create mode 100644 drivers/crypto/starfive/Kconfig
- create mode 100644 drivers/crypto/starfive/Makefile
- create mode 100644 drivers/crypto/starfive/jh7110-cryp.c
- create mode 100644 drivers/crypto/starfive/jh7110-cryp.h
-
---- a/drivers/crypto/Kconfig
-+++ b/drivers/crypto/Kconfig
-@@ -823,5 +823,6 @@ config CRYPTO_DEV_SA2UL
-
- source "drivers/crypto/keembay/Kconfig"
- source "drivers/crypto/aspeed/Kconfig"
-+source "drivers/crypto/starfive/Kconfig"
-
- endif # CRYPTO_HW
---- a/drivers/crypto/Makefile
-+++ b/drivers/crypto/Makefile
-@@ -53,3 +53,4 @@ obj-y += xilinx/
- obj-y += hisilicon/
- obj-$(CONFIG_CRYPTO_DEV_AMLOGIC_GXL) += amlogic/
- obj-y += keembay/
-+obj-y += starfive/
---- /dev/null
-+++ b/drivers/crypto/starfive/Kconfig
-@@ -0,0 +1,17 @@
-+#
-+# StarFive crypto drivers configuration
-+#
-+
-+config CRYPTO_DEV_JH7110
-+ tristate "StarFive JH7110 cryptographic engine driver"
-+ depends on SOC_STARFIVE || COMPILE_TEST
-+ select CRYPTO_ENGINE
-+ select ARM_AMBA
-+ select DMADEVICES
-+ select AMBA_PL08X
-+ help
-+ Support for StarFive JH7110 crypto hardware acceleration engine.
-+ This module provides acceleration for public key algo,
-+ skciphers, AEAD and hash functions.
-+
-+ If you choose 'M' here, this module will be called jh7110-crypto.
---- /dev/null
-+++ b/drivers/crypto/starfive/Makefile
-@@ -0,0 +1,4 @@
-+# SPDX-License-Identifier: GPL-2.0
-+
-+obj-$(CONFIG_CRYPTO_DEV_JH7110) += jh7110-crypto.o
-+jh7110-crypto-objs := jh7110-cryp.o
---- /dev/null
-+++ b/drivers/crypto/starfive/jh7110-cryp.c
-@@ -0,0 +1,201 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Cryptographic API.
-+ *
-+ * Support for StarFive hardware cryptographic engine.
-+ * Copyright (c) 2022 StarFive Technology
-+ *
-+ */
-+
-+#include <linux/clk.h>
-+#include <linux/delay.h>
-+#include <linux/interrupt.h>
-+#include <linux/iopoll.h>
-+#include <linux/module.h>
-+#include <linux/of_device.h>
-+#include <linux/platform_device.h>
-+#include <linux/pm_runtime.h>
-+#include <linux/reset.h>
-+
-+#include "jh7110-cryp.h"
-+
-+#define DRIVER_NAME "jh7110-crypto"
-+
-+struct starfive_dev_list {
-+ struct list_head dev_list;
-+ spinlock_t lock; /* protect dev_list */
-+};
-+
-+static struct starfive_dev_list dev_list = {
-+ .dev_list = LIST_HEAD_INIT(dev_list.dev_list),
-+ .lock = __SPIN_LOCK_UNLOCKED(dev_list.lock),
-+};
-+
-+struct starfive_cryp_dev *starfive_cryp_find_dev(struct starfive_cryp_ctx *ctx)
-+{
-+ struct starfive_cryp_dev *cryp = NULL, *tmp;
-+
-+ spin_lock_bh(&dev_list.lock);
-+ if (!ctx->cryp) {
-+ list_for_each_entry(tmp, &dev_list.dev_list, list) {
-+ cryp = tmp;
-+ break;
-+ }
-+ ctx->cryp = cryp;
-+ } else {
-+ cryp = ctx->cryp;
-+ }
-+
-+ spin_unlock_bh(&dev_list.lock);
-+
-+ return cryp;
-+}
-+
-+static int starfive_dma_init(struct starfive_cryp_dev *cryp)
-+{
-+ dma_cap_mask_t mask;
-+
-+ dma_cap_zero(mask);
-+ dma_cap_set(DMA_SLAVE, mask);
-+
-+ cryp->tx = dma_request_chan(cryp->dev, "tx");
-+ if (IS_ERR(cryp->tx))
-+ return dev_err_probe(cryp->dev, PTR_ERR(cryp->tx),
-+ "Error requesting tx dma channel.\n");
-+
-+ cryp->rx = dma_request_chan(cryp->dev, "rx");
-+ if (IS_ERR(cryp->rx)) {
-+ dma_release_channel(cryp->tx);
-+ return dev_err_probe(cryp->dev, PTR_ERR(cryp->rx),
-+ "Error requesting rx dma channel.\n");
-+ }
-+
-+ return 0;
-+}
-+
-+static void starfive_dma_cleanup(struct starfive_cryp_dev *cryp)
-+{
-+ dma_release_channel(cryp->tx);
-+ dma_release_channel(cryp->rx);
-+}
-+
-+static int starfive_cryp_probe(struct platform_device *pdev)
-+{
-+ struct starfive_cryp_dev *cryp;
-+ struct resource *res;
-+ int ret;
-+
-+ cryp = devm_kzalloc(&pdev->dev, sizeof(*cryp), GFP_KERNEL);
-+ if (!cryp)
-+ return -ENOMEM;
-+
-+ platform_set_drvdata(pdev, cryp);
-+ cryp->dev = &pdev->dev;
-+
-+ cryp->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
-+ if (IS_ERR(cryp->base))
-+ return dev_err_probe(&pdev->dev, PTR_ERR(cryp->base),
-+ "Error remapping memory for platform device\n");
-+
-+ cryp->phys_base = res->start;
-+ cryp->dma_maxburst = 32;
-+
-+ cryp->hclk = devm_clk_get(&pdev->dev, "hclk");
-+ if (IS_ERR(cryp->hclk))
-+ return dev_err_probe(&pdev->dev, PTR_ERR(cryp->hclk),
-+ "Error getting hardware reference clock\n");
-+
-+ cryp->ahb = devm_clk_get(&pdev->dev, "ahb");
-+ if (IS_ERR(cryp->ahb))
-+ return dev_err_probe(&pdev->dev, PTR_ERR(cryp->ahb),
-+ "Error getting ahb reference clock\n");
-+
-+ cryp->rst = devm_reset_control_get_shared(cryp->dev, NULL);
-+ if (IS_ERR(cryp->rst))
-+ return dev_err_probe(&pdev->dev, PTR_ERR(cryp->rst),
-+ "Error getting hardware reset line\n");
-+
-+ clk_prepare_enable(cryp->hclk);
-+ clk_prepare_enable(cryp->ahb);
-+ reset_control_deassert(cryp->rst);
-+
-+ spin_lock(&dev_list.lock);
-+ list_add(&cryp->list, &dev_list.dev_list);
-+ spin_unlock(&dev_list.lock);
-+
-+ ret = starfive_dma_init(cryp);
-+ if (ret) {
-+ if (ret == -EPROBE_DEFER)
-+ goto err_probe_defer;
-+ else
-+ goto err_dma_init;
-+ }
-+
-+ /* Initialize crypto engine */
-+ cryp->engine = crypto_engine_alloc_init(&pdev->dev, 1);
-+ if (!cryp->engine) {
-+ ret = -ENOMEM;
-+ goto err_engine;
-+ }
-+
-+ ret = crypto_engine_start(cryp->engine);
-+ if (ret)
-+ goto err_engine_start;
-+
-+ return 0;
-+
-+err_engine_start:
-+ crypto_engine_exit(cryp->engine);
-+err_engine:
-+ starfive_dma_cleanup(cryp);
-+err_dma_init:
-+ spin_lock(&dev_list.lock);
-+ list_del(&cryp->list);
-+ spin_unlock(&dev_list.lock);
-+
-+ clk_disable_unprepare(cryp->hclk);
-+ clk_disable_unprepare(cryp->ahb);
-+ reset_control_assert(cryp->rst);
-+err_probe_defer:
-+ return ret;
-+}
-+
-+static int starfive_cryp_remove(struct platform_device *pdev)
-+{
-+ struct starfive_cryp_dev *cryp = platform_get_drvdata(pdev);
-+
-+ crypto_engine_stop(cryp->engine);
-+ crypto_engine_exit(cryp->engine);
-+
-+ starfive_dma_cleanup(cryp);
-+
-+ spin_lock(&dev_list.lock);
-+ list_del(&cryp->list);
-+ spin_unlock(&dev_list.lock);
-+
-+ clk_disable_unprepare(cryp->hclk);
-+ clk_disable_unprepare(cryp->ahb);
-+ reset_control_assert(cryp->rst);
-+
-+ return 0;
-+}
-+
-+static const struct of_device_id starfive_dt_ids[] __maybe_unused = {
-+ { .compatible = "starfive,jh7110-crypto", .data = NULL},
-+ {},
-+};
-+MODULE_DEVICE_TABLE(of, starfive_dt_ids);
-+
-+static struct platform_driver starfive_cryp_driver = {
-+ .probe = starfive_cryp_probe,
-+ .remove = starfive_cryp_remove,
-+ .driver = {
-+ .name = DRIVER_NAME,
-+ .of_match_table = starfive_dt_ids,
-+ },
-+};
-+
-+module_platform_driver(starfive_cryp_driver);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_DESCRIPTION("StarFive JH7110 Cryptographic Module");
---- /dev/null
-+++ b/drivers/crypto/starfive/jh7110-cryp.h
-@@ -0,0 +1,63 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+#ifndef __STARFIVE_STR_H__
-+#define __STARFIVE_STR_H__
-+
-+#include <linux/delay.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/dmaengine.h>
-+
-+#include <crypto/engine.h>
-+
-+#define STARFIVE_ALG_CR_OFFSET 0x0
-+#define STARFIVE_ALG_FIFO_OFFSET 0x4
-+#define STARFIVE_IE_MASK_OFFSET 0x8
-+#define STARFIVE_IE_FLAG_OFFSET 0xc
-+#define STARFIVE_DMA_IN_LEN_OFFSET 0x10
-+#define STARFIVE_DMA_OUT_LEN_OFFSET 0x14
-+
-+#define STARFIVE_MSG_BUFFER_SIZE SZ_16K
-+
-+union starfive_alg_cr {
-+ u32 v;
-+ struct {
-+ u32 start :1;
-+ u32 aes_dma_en :1;
-+ u32 rsvd_0 :1;
-+ u32 hash_dma_en :1;
-+ u32 alg_done :1;
-+ u32 rsvd_1 :3;
-+ u32 clear :1;
-+ u32 rsvd_2 :23;
-+ };
-+};
-+
-+struct starfive_cryp_ctx {
-+ struct crypto_engine_ctx enginectx;
-+ struct starfive_cryp_dev *cryp;
-+};
-+
-+struct starfive_cryp_dev {
-+ struct list_head list;
-+ struct device *dev;
-+
-+ struct clk *hclk;
-+ struct clk *ahb;
-+ struct reset_control *rst;
-+
-+ void __iomem *base;
-+ phys_addr_t phys_base;
-+
-+ u32 dma_maxburst;
-+ struct dma_chan *tx;
-+ struct dma_chan *rx;
-+ struct dma_slave_config cfg_in;
-+ struct dma_slave_config cfg_out;
-+
-+ struct crypto_engine *engine;
-+
-+ union starfive_alg_cr alg_cr;
-+};
-+
-+struct starfive_cryp_dev *starfive_cryp_find_dev(struct starfive_cryp_ctx *ctx);
-+
-+#endif
diff --git a/target/linux/starfive/patches-6.1/0066-crypto-starfive-Fix-driver-dependencies.patch b/target/linux/starfive/patches-6.1/0066-crypto-starfive-Fix-driver-dependencies.patch
deleted file mode 100644
index fc8e86bad5..0000000000
--- a/target/linux/starfive/patches-6.1/0066-crypto-starfive-Fix-driver-dependencies.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From 0d3ee821ed469a787e8007de2d87e98a2370e087 Mon Sep 17 00:00:00 2001
-From: Jia Jie Ho <jiajie.ho@starfivetech.com>
-Date: Fri, 19 May 2023 21:42:33 +0800
-Subject: [PATCH 066/122] crypto: starfive - Fix driver dependencies
-
-Kconfig updated to depend on DMADEVICES instead of selecting it.
-
-Reported-by: kernel test robot <lkp@intel.com>
-Link: https://lore.kernel.org/oe-kbuild-all/202305191929.Eq4OVZ6D-lkp@intel.com/
-Signed-off-by: Jia Jie Ho <jiajie.ho@starfivetech.com>
-Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
----
- drivers/crypto/starfive/Kconfig | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
---- a/drivers/crypto/starfive/Kconfig
-+++ b/drivers/crypto/starfive/Kconfig
-@@ -4,10 +4,9 @@
-
- config CRYPTO_DEV_JH7110
- tristate "StarFive JH7110 cryptographic engine driver"
-- depends on SOC_STARFIVE || COMPILE_TEST
-+ depends on (SOC_STARFIVE || COMPILE_TEST) && DMADEVICES
- select CRYPTO_ENGINE
- select ARM_AMBA
-- select DMADEVICES
- select AMBA_PL08X
- help
- Support for StarFive JH7110 crypto hardware acceleration engine.
diff --git a/target/linux/starfive/patches-6.1/0067-riscv-Kconfig-Add-select-ARM_AMBA-to-SOC_STARFIVE.patch b/target/linux/starfive/patches-6.1/0067-riscv-Kconfig-Add-select-ARM_AMBA-to-SOC_STARFIVE.patch
deleted file mode 100644
index 2deca609e1..0000000000
--- a/target/linux/starfive/patches-6.1/0067-riscv-Kconfig-Add-select-ARM_AMBA-to-SOC_STARFIVE.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-From e8d070e2eb856856055566d3515072a8346446f3 Mon Sep 17 00:00:00 2001
-From: "shanlong.li" <shanlong.li@starfivetech.com>
-Date: Wed, 31 May 2023 01:37:41 -0700
-Subject: [PATCH 067/122] riscv: Kconfig: Add select ARM_AMBA to SOC_STARFIVE
-
-Selects ARM_AMBA platform support for StarFive SoCs required by spi and
-crypto dma engine.
-
-Signed-off-by: shanlong.li <shanlong.li@starfivetech.com>
----
- arch/riscv/Kconfig.socs | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/arch/riscv/Kconfig.socs
-+++ b/arch/riscv/Kconfig.socs
-@@ -4,6 +4,7 @@ config SOC_MICROCHIP_POLARFIRE
- bool "Microchip PolarFire SoCs"
- select MCHP_CLK_MPFS
- select SIFIVE_PLIC
-+ select ARM_AMBA
- help
- This enables support for Microchip PolarFire SoC platforms.
-
diff --git a/target/linux/starfive/patches-6.1/0068-ASoC-dt-bindings-Add-TDM-controller-bindings-for-Sta.patch b/target/linux/starfive/patches-6.1/0068-ASoC-dt-bindings-Add-TDM-controller-bindings-for-Sta.patch
deleted file mode 100644
index 41d0a8fe11..0000000000
--- a/target/linux/starfive/patches-6.1/0068-ASoC-dt-bindings-Add-TDM-controller-bindings-for-Sta.patch
+++ /dev/null
@@ -1,117 +0,0 @@
-From 3b90e0fb53c31c50e64d2039e30ec25c1d8a8d5c Mon Sep 17 00:00:00 2001
-From: Walker Chen <walker.chen@starfivetech.com>
-Date: Fri, 26 May 2023 22:54:00 +0800
-Subject: [PATCH 068/122] ASoC: dt-bindings: Add TDM controller bindings for
- StarFive JH7110
-
-Add bindings for TDM driver which supports multi-channel audio playback
-and capture on JH7110 platform.
-
-Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Signed-off-by: Walker Chen <walker.chen@starfivetech.com>
----
- .../bindings/sound/starfive,jh7110-tdm.yaml | 98 +++++++++++++++++++
- 1 file changed, 98 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/sound/starfive,jh7110-tdm.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/sound/starfive,jh7110-tdm.yaml
-@@ -0,0 +1,98 @@
-+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/sound/starfive,jh7110-tdm.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: StarFive JH7110 TDM Controller
-+
-+description: |
-+ The TDM Controller is a Time Division Multiplexed audio interface
-+ integrated in StarFive JH7110 SoC, allowing up to 8 channels of
-+ audio over a serial interface. The TDM controller can operate both
-+ in master and slave mode.
-+
-+maintainers:
-+ - Walker Chen <walker.chen@starfivetech.com>
-+
-+allOf:
-+ - $ref: dai-common.yaml#
-+
-+properties:
-+ compatible:
-+ enum:
-+ - starfive,jh7110-tdm
-+
-+ reg:
-+ maxItems: 1
-+
-+ clocks:
-+ items:
-+ - description: TDM AHB Clock
-+ - description: TDM APB Clock
-+ - description: TDM Internal Clock
-+ - description: TDM Clock
-+ - description: Inner MCLK
-+ - description: TDM External Clock
-+
-+ clock-names:
-+ items:
-+ - const: tdm_ahb
-+ - const: tdm_apb
-+ - const: tdm_internal
-+ - const: tdm
-+ - const: mclk_inner
-+ - const: tdm_ext
-+
-+ resets:
-+ items:
-+ - description: tdm ahb reset line
-+ - description: tdm apb reset line
-+ - description: tdm core reset line
-+
-+ dmas:
-+ items:
-+ - description: RX DMA Channel
-+ - description: TX DMA Channel
-+
-+ dma-names:
-+ items:
-+ - const: rx
-+ - const: tx
-+
-+ "#sound-dai-cells":
-+ const: 0
-+
-+required:
-+ - compatible
-+ - reg
-+ - clocks
-+ - clock-names
-+ - resets
-+ - dmas
-+ - dma-names
-+ - "#sound-dai-cells"
-+
-+additionalProperties: false
-+
-+examples:
-+ - |
-+ tdm@10090000 {
-+ compatible = "starfive,jh7110-tdm";
-+ reg = <0x10090000 0x1000>;
-+ clocks = <&syscrg 184>,
-+ <&syscrg 185>,
-+ <&syscrg 186>,
-+ <&syscrg 187>,
-+ <&syscrg 17>,
-+ <&tdm_ext>;
-+ clock-names = "tdm_ahb", "tdm_apb",
-+ "tdm_internal", "tdm",
-+ "mclk_inner", "tdm_ext";
-+ resets = <&syscrg 105>,
-+ <&syscrg 107>,
-+ <&syscrg 106>;
-+ dmas = <&dma 20>, <&dma 21>;
-+ dma-names = "rx","tx";
-+ #sound-dai-cells = <0>;
-+ };
diff --git a/target/linux/starfive/patches-6.1/0069-ASoC-starfive-Add-JH7110-TDM-driver.patch b/target/linux/starfive/patches-6.1/0069-ASoC-starfive-Add-JH7110-TDM-driver.patch
deleted file mode 100644
index 57ea99d685..0000000000
--- a/target/linux/starfive/patches-6.1/0069-ASoC-starfive-Add-JH7110-TDM-driver.patch
+++ /dev/null
@@ -1,744 +0,0 @@
-From 9d90936b0f69d891001a11d3f6c0c3728d8b6d85 Mon Sep 17 00:00:00 2001
-From: Walker Chen <walker.chen@starfivetech.com>
-Date: Fri, 26 May 2023 22:54:01 +0800
-Subject: [PATCH 069/122] ASoC: starfive: Add JH7110 TDM driver
-
-Add tdm driver support for the StarFive JH7110 SoC.
-
-Signed-off-by: Walker Chen <walker.chen@starfivetech.com>
----
- sound/soc/Kconfig | 1 +
- sound/soc/Makefile | 1 +
- sound/soc/starfive/Kconfig | 15 +
- sound/soc/starfive/Makefile | 2 +
- sound/soc/starfive/jh7110_tdm.c | 679 ++++++++++++++++++++++++++++++++
- 5 files changed, 698 insertions(+)
- create mode 100644 sound/soc/starfive/Kconfig
- create mode 100644 sound/soc/starfive/Makefile
- create mode 100644 sound/soc/starfive/jh7110_tdm.c
-
---- a/sound/soc/Kconfig
-+++ b/sound/soc/Kconfig
-@@ -91,6 +91,7 @@ source "sound/soc/sh/Kconfig"
- source "sound/soc/sof/Kconfig"
- source "sound/soc/spear/Kconfig"
- source "sound/soc/sprd/Kconfig"
-+source "sound/soc/starfive/Kconfig"
- source "sound/soc/sti/Kconfig"
- source "sound/soc/stm/Kconfig"
- source "sound/soc/sunxi/Kconfig"
---- a/sound/soc/Makefile
-+++ b/sound/soc/Makefile
-@@ -59,6 +59,7 @@ obj-$(CONFIG_SND_SOC) += sh/
- obj-$(CONFIG_SND_SOC) += sof/
- obj-$(CONFIG_SND_SOC) += spear/
- obj-$(CONFIG_SND_SOC) += sprd/
-+obj-$(CONFIG_SND_SOC) += starfive/
- obj-$(CONFIG_SND_SOC) += sti/
- obj-$(CONFIG_SND_SOC) += stm/
- obj-$(CONFIG_SND_SOC) += sunxi/
---- /dev/null
-+++ b/sound/soc/starfive/Kconfig
-@@ -0,0 +1,15 @@
-+# SPDX-License-Identifier: GPL-2.0-only
-+config SND_SOC_STARFIVE
-+ tristate "Audio support for StarFive SoC"
-+ depends on COMPILE_TEST || ARCH_STARFIVE
-+ help
-+ Say Y or M if you want to add support for codecs attached to
-+ the Starfive SoCs' Audio interfaces. You will also need to
-+ select the audio interfaces to support below.
-+
-+config SND_SOC_JH7110_TDM
-+ tristate "JH7110 TDM device driver"
-+ depends on HAVE_CLK && SND_SOC_STARFIVE
-+ select SND_SOC_GENERIC_DMAENGINE_PCM
-+ help
-+ Say Y or M if you want to add support for StarFive TDM driver.
---- /dev/null
-+++ b/sound/soc/starfive/Makefile
-@@ -0,0 +1,2 @@
-+# StarFive Platform Support
-+obj-$(CONFIG_SND_SOC_JH7110_TDM) += jh7110_tdm.o
---- /dev/null
-+++ b/sound/soc/starfive/jh7110_tdm.c
-@@ -0,0 +1,679 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * jh7110_tdm.c -- StarFive JH7110 TDM driver
-+ *
-+ * Copyright (C) 2023 StarFive Technology Co., Ltd.
-+ *
-+ * Author: Walker Chen <walker.chen@starfivetech.com>
-+ */
-+
-+#include <linux/clk.h>
-+#include <linux/device.h>
-+#include <linux/dmaengine.h>
-+#include <linux/module.h>
-+#include <linux/of_irq.h>
-+#include <linux/of_platform.h>
-+#include <linux/pm_runtime.h>
-+#include <linux/regmap.h>
-+#include <linux/reset.h>
-+#include <linux/types.h>
-+#include <sound/dmaengine_pcm.h>
-+#include <sound/initval.h>
-+#include <sound/pcm.h>
-+#include <sound/pcm_params.h>
-+#include <sound/soc.h>
-+#include <sound/soc-dai.h>
-+
-+#define TDM_PCMGBCR 0x00
-+ #define PCMGBCR_MASK 0x1e
-+ #define PCMGBCR_ENABLE BIT(0)
-+ #define PCMGBCR_TRITXEN BIT(4)
-+ #define CLKPOL_BIT 5
-+ #define TRITXEN_BIT 4
-+ #define ELM_BIT 3
-+ #define SYNCM_BIT 2
-+ #define MS_BIT 1
-+#define TDM_PCMTXCR 0x04
-+ #define PCMTXCR_TXEN BIT(0)
-+ #define IFL_BIT 11
-+ #define WL_BIT 8
-+ #define SSCALE_BIT 4
-+ #define SL_BIT 2
-+ #define LRJ_BIT 1
-+#define TDM_PCMRXCR 0x08
-+ #define PCMRXCR_RXEN BIT(0)
-+ #define PCMRXCR_RXSL_MASK 0xc
-+ #define PCMRXCR_RXSL_16BIT 0x4
-+ #define PCMRXCR_RXSL_32BIT 0x8
-+ #define PCMRXCR_SCALE_MASK 0xf0
-+ #define PCMRXCR_SCALE_1CH 0x10
-+#define TDM_PCMDIV 0x0c
-+
-+#define JH7110_TDM_FIFO 0x170c0000
-+#define JH7110_TDM_FIFO_DEPTH 32
-+
-+enum TDM_MASTER_SLAVE_MODE {
-+ TDM_AS_MASTER = 0,
-+ TDM_AS_SLAVE,
-+};
-+
-+enum TDM_CLKPOL {
-+ /* tx raising and rx falling */
-+ TDM_TX_RASING_RX_FALLING = 0,
-+ /* tx falling and rx raising */
-+ TDM_TX_FALLING_RX_RASING,
-+};
-+
-+enum TDM_ELM {
-+ /* only work while SYNCM=0 */
-+ TDM_ELM_LATE = 0,
-+ TDM_ELM_EARLY,
-+};
-+
-+enum TDM_SYNCM {
-+ /* short frame sync */
-+ TDM_SYNCM_SHORT = 0,
-+ /* long frame sync */
-+ TDM_SYNCM_LONG,
-+};
-+
-+enum TDM_IFL {
-+ /* FIFO to send or received : half-1/2, Quarter-1/4 */
-+ TDM_FIFO_HALF = 0,
-+ TDM_FIFO_QUARTER,
-+};
-+
-+enum TDM_WL {
-+ /* send or received word length */
-+ TDM_8BIT_WORD_LEN = 0,
-+ TDM_16BIT_WORD_LEN,
-+ TDM_20BIT_WORD_LEN,
-+ TDM_24BIT_WORD_LEN,
-+ TDM_32BIT_WORD_LEN,
-+};
-+
-+enum TDM_SL {
-+ /* send or received slot length */
-+ TDM_8BIT_SLOT_LEN = 0,
-+ TDM_16BIT_SLOT_LEN,
-+ TDM_32BIT_SLOT_LEN,
-+};
-+
-+enum TDM_LRJ {
-+ /* left-justify or right-justify */
-+ TDM_RIGHT_JUSTIFY = 0,
-+ TDM_LEFT_JUSTIFT,
-+};
-+
-+struct tdm_chan_cfg {
-+ enum TDM_IFL ifl;
-+ enum TDM_WL wl;
-+ unsigned char sscale;
-+ enum TDM_SL sl;
-+ enum TDM_LRJ lrj;
-+ unsigned char enable;
-+};
-+
-+struct jh7110_tdm_dev {
-+ void __iomem *tdm_base;
-+ struct device *dev;
-+ struct clk_bulk_data clks[6];
-+ struct reset_control *resets;
-+
-+ enum TDM_CLKPOL clkpolity;
-+ enum TDM_ELM elm;
-+ enum TDM_SYNCM syncm;
-+ enum TDM_MASTER_SLAVE_MODE ms_mode;
-+
-+ struct tdm_chan_cfg tx;
-+ struct tdm_chan_cfg rx;
-+
-+ u16 syncdiv;
-+ u32 samplerate;
-+ u32 pcmclk;
-+
-+ /* data related to DMA transfers b/w tdm and DMAC */
-+ struct snd_dmaengine_dai_dma_data play_dma_data;
-+ struct snd_dmaengine_dai_dma_data capture_dma_data;
-+ u32 saved_pcmgbcr;
-+ u32 saved_pcmtxcr;
-+ u32 saved_pcmrxcr;
-+ u32 saved_pcmdiv;
-+};
-+
-+static inline u32 jh7110_tdm_readl(struct jh7110_tdm_dev *tdm, u16 reg)
-+{
-+ return readl_relaxed(tdm->tdm_base + reg);
-+}
-+
-+static inline void jh7110_tdm_writel(struct jh7110_tdm_dev *tdm, u16 reg, u32 val)
-+{
-+ writel_relaxed(val, tdm->tdm_base + reg);
-+}
-+
-+static void jh7110_tdm_save_context(struct jh7110_tdm_dev *tdm,
-+ struct snd_pcm_substream *substream)
-+{
-+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-+ tdm->saved_pcmtxcr = jh7110_tdm_readl(tdm, TDM_PCMTXCR);
-+ else
-+ tdm->saved_pcmrxcr = jh7110_tdm_readl(tdm, TDM_PCMRXCR);
-+}
-+
-+static void jh7110_tdm_start(struct jh7110_tdm_dev *tdm,
-+ struct snd_pcm_substream *substream)
-+{
-+ u32 data;
-+
-+ data = jh7110_tdm_readl(tdm, TDM_PCMGBCR);
-+ jh7110_tdm_writel(tdm, TDM_PCMGBCR, data | PCMGBCR_ENABLE);
-+
-+ /* restore context */
-+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-+ jh7110_tdm_writel(tdm, TDM_PCMTXCR, tdm->saved_pcmtxcr | PCMTXCR_TXEN);
-+ else
-+ jh7110_tdm_writel(tdm, TDM_PCMRXCR, tdm->saved_pcmrxcr | PCMRXCR_RXEN);
-+}
-+
-+static void jh7110_tdm_stop(struct jh7110_tdm_dev *tdm,
-+ struct snd_pcm_substream *substream)
-+{
-+ unsigned int val;
-+
-+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-+ val = jh7110_tdm_readl(tdm, TDM_PCMTXCR);
-+ val &= ~PCMTXCR_TXEN;
-+ jh7110_tdm_writel(tdm, TDM_PCMTXCR, val);
-+ } else {
-+ val = jh7110_tdm_readl(tdm, TDM_PCMRXCR);
-+ val &= ~PCMRXCR_RXEN;
-+ jh7110_tdm_writel(tdm, TDM_PCMRXCR, val);
-+ }
-+}
-+
-+static int jh7110_tdm_syncdiv(struct jh7110_tdm_dev *tdm)
-+{
-+ u32 sl, sscale, syncdiv;
-+
-+ if (tdm->rx.sl >= tdm->tx.sl)
-+ sl = tdm->rx.sl;
-+ else
-+ sl = tdm->tx.sl;
-+
-+ if (tdm->rx.sscale >= tdm->tx.sscale)
-+ sscale = tdm->rx.sscale;
-+ else
-+ sscale = tdm->tx.sscale;
-+
-+ syncdiv = tdm->pcmclk / tdm->samplerate - 1;
-+
-+ if ((syncdiv + 1) < (sl * sscale)) {
-+ dev_err(tdm->dev, "Failed to set syncdiv!\n");
-+ return -EINVAL;
-+ }
-+
-+ if (tdm->syncm == TDM_SYNCM_LONG &&
-+ (tdm->rx.sscale <= 1 || tdm->tx.sscale <= 1) &&
-+ ((syncdiv + 1) <= sl)) {
-+ dev_err(tdm->dev, "Wrong syncdiv! It must be (syncdiv+1) > max[tx.sl, rx.sl]\n");
-+ return -EINVAL;
-+ }
-+
-+ jh7110_tdm_writel(tdm, TDM_PCMDIV, syncdiv);
-+ return 0;
-+}
-+
-+static int jh7110_tdm_config(struct jh7110_tdm_dev *tdm,
-+ struct snd_pcm_substream *substream)
-+{
-+ u32 datarx, datatx;
-+ int ret;
-+
-+ ret = jh7110_tdm_syncdiv(tdm);
-+ if (ret)
-+ return ret;
-+
-+ datarx = (tdm->rx.ifl << IFL_BIT) |
-+ (tdm->rx.wl << WL_BIT) |
-+ (tdm->rx.sscale << SSCALE_BIT) |
-+ (tdm->rx.sl << SL_BIT) |
-+ (tdm->rx.lrj << LRJ_BIT);
-+
-+ datatx = (tdm->tx.ifl << IFL_BIT) |
-+ (tdm->tx.wl << WL_BIT) |
-+ (tdm->tx.sscale << SSCALE_BIT) |
-+ (tdm->tx.sl << SL_BIT) |
-+ (tdm->tx.lrj << LRJ_BIT);
-+
-+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-+ jh7110_tdm_writel(tdm, TDM_PCMTXCR, datatx);
-+ else
-+ jh7110_tdm_writel(tdm, TDM_PCMRXCR, datarx);
-+
-+ return 0;
-+}
-+
-+static void jh7110_tdm_clk_disable(struct jh7110_tdm_dev *tdm)
-+{
-+ clk_bulk_disable_unprepare(ARRAY_SIZE(tdm->clks), tdm->clks);
-+}
-+
-+static int jh7110_tdm_clk_enable(struct jh7110_tdm_dev *tdm)
-+{
-+ int ret;
-+
-+ ret = clk_bulk_prepare_enable(ARRAY_SIZE(tdm->clks), tdm->clks);
-+ if (ret) {
-+ dev_err(tdm->dev, "Failed to enable tdm clocks\n");
-+ return ret;
-+ }
-+
-+ ret = reset_control_deassert(tdm->resets);
-+ if (ret) {
-+ dev_err(tdm->dev, "Failed to deassert tdm resets\n");
-+ goto dis_tdm_clk;
-+ }
-+
-+ /* select tdm_ext clock as the clock source for tdm */
-+ ret = clk_set_parent(tdm->clks[5].clk, tdm->clks[4].clk);
-+ if (ret) {
-+ dev_err(tdm->dev, "Can't set extern clock source for clk_tdm\n");
-+ goto dis_tdm_clk;
-+ }
-+
-+ return 0;
-+
-+dis_tdm_clk:
-+ clk_bulk_disable_unprepare(ARRAY_SIZE(tdm->clks), tdm->clks);
-+
-+ return ret;
-+}
-+
-+static int jh7110_tdm_runtime_suspend(struct device *dev)
-+{
-+ struct jh7110_tdm_dev *tdm = dev_get_drvdata(dev);
-+
-+ jh7110_tdm_clk_disable(tdm);
-+ return 0;
-+}
-+
-+static int jh7110_tdm_runtime_resume(struct device *dev)
-+{
-+ struct jh7110_tdm_dev *tdm = dev_get_drvdata(dev);
-+
-+ return jh7110_tdm_clk_enable(tdm);
-+}
-+
-+static int jh7110_tdm_system_suspend(struct device *dev)
-+{
-+ struct jh7110_tdm_dev *tdm = dev_get_drvdata(dev);
-+
-+ /* save context */
-+ tdm->saved_pcmgbcr = jh7110_tdm_readl(tdm, TDM_PCMGBCR);
-+ tdm->saved_pcmdiv = jh7110_tdm_readl(tdm, TDM_PCMDIV);
-+
-+ return pm_runtime_force_suspend(dev);
-+}
-+
-+static int jh7110_tdm_system_resume(struct device *dev)
-+{
-+ struct jh7110_tdm_dev *tdm = dev_get_drvdata(dev);
-+
-+ /* restore context */
-+ jh7110_tdm_writel(tdm, TDM_PCMGBCR, tdm->saved_pcmgbcr);
-+ jh7110_tdm_writel(tdm, TDM_PCMDIV, tdm->saved_pcmdiv);
-+
-+ return pm_runtime_force_resume(dev);
-+}
-+
-+static const struct snd_soc_component_driver jh7110_tdm_component = {
-+ .name = "jh7110-tdm",
-+};
-+
-+static int jh7110_tdm_startup(struct snd_pcm_substream *substream,
-+ struct snd_soc_dai *cpu_dai)
-+{
-+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
-+ struct snd_soc_dai_link *dai_link = rtd->dai_link;
-+
-+ dai_link->stop_dma_first = 1;
-+
-+ return 0;
-+}
-+
-+static int jh7110_tdm_hw_params(struct snd_pcm_substream *substream,
-+ struct snd_pcm_hw_params *params,
-+ struct snd_soc_dai *dai)
-+{
-+ struct jh7110_tdm_dev *tdm = snd_soc_dai_get_drvdata(dai);
-+ int chan_wl, chan_sl, chan_nr;
-+ unsigned int data_width;
-+ unsigned int dma_bus_width;
-+ struct snd_dmaengine_dai_dma_data *dma_data = NULL;
-+ int ret;
-+
-+ data_width = params_width(params);
-+
-+ tdm->samplerate = params_rate(params);
-+ tdm->pcmclk = params_channels(params) * tdm->samplerate * data_width;
-+
-+ switch (params_format(params)) {
-+ case SNDRV_PCM_FORMAT_S16_LE:
-+ chan_wl = TDM_16BIT_WORD_LEN;
-+ chan_sl = TDM_16BIT_SLOT_LEN;
-+ dma_bus_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
-+ break;
-+
-+ case SNDRV_PCM_FORMAT_S32_LE:
-+ chan_wl = TDM_32BIT_WORD_LEN;
-+ chan_sl = TDM_32BIT_SLOT_LEN;
-+ dma_bus_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
-+ break;
-+
-+ default:
-+ dev_err(tdm->dev, "tdm: unsupported PCM fmt");
-+ return -EINVAL;
-+ }
-+
-+ chan_nr = params_channels(params);
-+ switch (chan_nr) {
-+ case 1:
-+ case 2:
-+ case 4:
-+ case 6:
-+ case 8:
-+ break;
-+ default:
-+ dev_err(tdm->dev, "channel not supported\n");
-+ return -EINVAL;
-+ }
-+
-+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-+ tdm->tx.wl = chan_wl;
-+ tdm->tx.sl = chan_sl;
-+ tdm->tx.sscale = chan_nr;
-+ tdm->play_dma_data.addr_width = dma_bus_width;
-+ dma_data = &tdm->play_dma_data;
-+ } else {
-+ tdm->rx.wl = chan_wl;
-+ tdm->rx.sl = chan_sl;
-+ tdm->rx.sscale = chan_nr;
-+ tdm->capture_dma_data.addr_width = dma_bus_width;
-+ dma_data = &tdm->capture_dma_data;
-+ }
-+
-+ snd_soc_dai_set_dma_data(dai, substream, dma_data);
-+
-+ ret = jh7110_tdm_config(tdm, substream);
-+ if (ret)
-+ return ret;
-+
-+ jh7110_tdm_save_context(tdm, substream);
-+ return 0;
-+}
-+
-+static int jh7110_tdm_trigger(struct snd_pcm_substream *substream,
-+ int cmd, struct snd_soc_dai *dai)
-+{
-+ struct jh7110_tdm_dev *tdm = snd_soc_dai_get_drvdata(dai);
-+ int ret = 0;
-+
-+ switch (cmd) {
-+ case SNDRV_PCM_TRIGGER_START:
-+ case SNDRV_PCM_TRIGGER_RESUME:
-+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-+ jh7110_tdm_start(tdm, substream);
-+ break;
-+
-+ case SNDRV_PCM_TRIGGER_STOP:
-+ case SNDRV_PCM_TRIGGER_SUSPEND:
-+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-+ jh7110_tdm_stop(tdm, substream);
-+ break;
-+ default:
-+ ret = -EINVAL;
-+ break;
-+ }
-+
-+ return ret;
-+}
-+
-+static int jh7110_tdm_set_dai_fmt(struct snd_soc_dai *cpu_dai,
-+ unsigned int fmt)
-+{
-+ struct jh7110_tdm_dev *tdm = snd_soc_dai_get_drvdata(cpu_dai);
-+ unsigned int gbcr;
-+
-+ /* set master/slave audio interface */
-+ switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
-+ case SND_SOC_DAIFMT_BP_FP:
-+ /* cpu is master */
-+ tdm->ms_mode = TDM_AS_MASTER;
-+ break;
-+ case SND_SOC_DAIFMT_BC_FC:
-+ /* codec is master */
-+ tdm->ms_mode = TDM_AS_SLAVE;
-+ break;
-+ case SND_SOC_DAIFMT_BC_FP:
-+ case SND_SOC_DAIFMT_BP_FC:
-+ return -EINVAL;
-+ default:
-+ dev_dbg(tdm->dev, "dwc : Invalid clock provider format\n");
-+ return -EINVAL;
-+ }
-+
-+ gbcr = (tdm->clkpolity << CLKPOL_BIT) |
-+ (tdm->elm << ELM_BIT) |
-+ (tdm->syncm << SYNCM_BIT) |
-+ (tdm->ms_mode << MS_BIT);
-+ jh7110_tdm_writel(tdm, TDM_PCMGBCR, gbcr);
-+
-+ return 0;
-+}
-+
-+static const struct snd_soc_dai_ops jh7110_tdm_dai_ops = {
-+ .startup = jh7110_tdm_startup,
-+ .hw_params = jh7110_tdm_hw_params,
-+ .trigger = jh7110_tdm_trigger,
-+ .set_fmt = jh7110_tdm_set_dai_fmt,
-+};
-+
-+static int jh7110_tdm_dai_probe(struct snd_soc_dai *dai)
-+{
-+ struct jh7110_tdm_dev *tdm = snd_soc_dai_get_drvdata(dai);
-+
-+ snd_soc_dai_init_dma_data(dai, &tdm->play_dma_data, &tdm->capture_dma_data);
-+ snd_soc_dai_set_drvdata(dai, tdm);
-+ return 0;
-+}
-+
-+#define JH7110_TDM_RATES SNDRV_PCM_RATE_8000_48000
-+
-+#define JH7110_TDM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
-+ SNDRV_PCM_FMTBIT_S32_LE)
-+
-+static struct snd_soc_dai_driver jh7110_tdm_dai = {
-+ .name = "sf_tdm",
-+ .id = 0,
-+ .playback = {
-+ .stream_name = "Playback",
-+ .channels_min = 1,
-+ .channels_max = 8,
-+ .rates = JH7110_TDM_RATES,
-+ .formats = JH7110_TDM_FORMATS,
-+ },
-+ .capture = {
-+ .stream_name = "Capture",
-+ .channels_min = 1,
-+ .channels_max = 8,
-+ .rates = JH7110_TDM_RATES,
-+ .formats = JH7110_TDM_FORMATS,
-+ },
-+ .ops = &jh7110_tdm_dai_ops,
-+ .probe = jh7110_tdm_dai_probe,
-+ .symmetric_rate = 1,
-+};
-+
-+static const struct snd_pcm_hardware jh7110_pcm_hardware = {
-+ .info = (SNDRV_PCM_INFO_MMAP |
-+ SNDRV_PCM_INFO_MMAP_VALID |
-+ SNDRV_PCM_INFO_PAUSE |
-+ SNDRV_PCM_INFO_RESUME |
-+ SNDRV_PCM_INFO_INTERLEAVED |
-+ SNDRV_PCM_INFO_BLOCK_TRANSFER),
-+ .buffer_bytes_max = 192512,
-+ .period_bytes_min = 4096,
-+ .period_bytes_max = 32768,
-+ .periods_min = 1,
-+ .periods_max = 48,
-+ .fifo_size = 16,
-+};
-+
-+static const struct snd_dmaengine_pcm_config jh7110_dmaengine_pcm_config = {
-+ .pcm_hardware = &jh7110_pcm_hardware,
-+ .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
-+ .prealloc_buffer_size = 192512,
-+};
-+
-+static void jh7110_tdm_init_params(struct jh7110_tdm_dev *tdm)
-+{
-+ tdm->clkpolity = TDM_TX_RASING_RX_FALLING;
-+ tdm->elm = TDM_ELM_LATE;
-+ tdm->syncm = TDM_SYNCM_SHORT;
-+
-+ tdm->rx.ifl = TDM_FIFO_HALF;
-+ tdm->tx.ifl = TDM_FIFO_HALF;
-+ tdm->rx.wl = TDM_16BIT_WORD_LEN;
-+ tdm->tx.wl = TDM_16BIT_WORD_LEN;
-+ tdm->rx.sscale = 2;
-+ tdm->tx.sscale = 2;
-+ tdm->rx.lrj = TDM_LEFT_JUSTIFT;
-+ tdm->tx.lrj = TDM_LEFT_JUSTIFT;
-+
-+ tdm->play_dma_data.addr = JH7110_TDM_FIFO;
-+ tdm->play_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
-+ tdm->play_dma_data.fifo_size = JH7110_TDM_FIFO_DEPTH / 2;
-+ tdm->play_dma_data.maxburst = 16;
-+
-+ tdm->capture_dma_data.addr = JH7110_TDM_FIFO;
-+ tdm->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
-+ tdm->capture_dma_data.fifo_size = JH7110_TDM_FIFO_DEPTH / 2;
-+ tdm->capture_dma_data.maxburst = 8;
-+}
-+
-+static int jh7110_tdm_clk_reset_get(struct platform_device *pdev,
-+ struct jh7110_tdm_dev *tdm)
-+{
-+ int ret;
-+
-+ tdm->clks[0].id = "mclk_inner";
-+ tdm->clks[1].id = "tdm_ahb";
-+ tdm->clks[2].id = "tdm_apb";
-+ tdm->clks[3].id = "tdm_internal";
-+ tdm->clks[4].id = "tdm_ext";
-+ tdm->clks[5].id = "tdm";
-+
-+ ret = devm_clk_bulk_get(&pdev->dev, ARRAY_SIZE(tdm->clks), tdm->clks);
-+ if (ret) {
-+ dev_err(&pdev->dev, "Failed to get tdm clocks\n");
-+ return ret;
-+ }
-+
-+ tdm->resets = devm_reset_control_array_get_exclusive(&pdev->dev);
-+ if (IS_ERR_OR_NULL(tdm->resets)) {
-+ ret = PTR_ERR(tdm->resets);
-+ dev_err(&pdev->dev, "Failed to get tdm resets");
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+
-+static int jh7110_tdm_probe(struct platform_device *pdev)
-+{
-+ struct jh7110_tdm_dev *tdm;
-+ int ret;
-+
-+ tdm = devm_kzalloc(&pdev->dev, sizeof(*tdm), GFP_KERNEL);
-+ if (!tdm)
-+ return -ENOMEM;
-+
-+ tdm->tdm_base = devm_platform_ioremap_resource(pdev, 0);
-+ if (IS_ERR(tdm->tdm_base))
-+ return PTR_ERR(tdm->tdm_base);
-+
-+ tdm->dev = &pdev->dev;
-+
-+ ret = jh7110_tdm_clk_reset_get(pdev, tdm);
-+ if (ret) {
-+ dev_err(&pdev->dev, "Failed to enable audio-tdm clock\n");
-+ return ret;
-+ }
-+
-+ jh7110_tdm_init_params(tdm);
-+
-+ dev_set_drvdata(&pdev->dev, tdm);
-+ ret = devm_snd_soc_register_component(&pdev->dev, &jh7110_tdm_component,
-+ &jh7110_tdm_dai, 1);
-+ if (ret) {
-+ dev_err(&pdev->dev, "Failed to register dai\n");
-+ return ret;
-+ }
-+
-+ ret = devm_snd_dmaengine_pcm_register(&pdev->dev,
-+ &jh7110_dmaengine_pcm_config,
-+ SND_DMAENGINE_PCM_FLAG_COMPAT);
-+ if (ret) {
-+ dev_err(&pdev->dev, "Could not register pcm: %d\n", ret);
-+ return ret;
-+ }
-+
-+ pm_runtime_enable(&pdev->dev);
-+ if (!pm_runtime_enabled(&pdev->dev)) {
-+ ret = jh7110_tdm_runtime_resume(&pdev->dev);
-+ if (ret)
-+ goto err_pm_disable;
-+ }
-+
-+ return 0;
-+
-+err_pm_disable:
-+ pm_runtime_disable(&pdev->dev);
-+
-+ return ret;
-+}
-+
-+static int jh7110_tdm_dev_remove(struct platform_device *pdev)
-+{
-+ pm_runtime_disable(&pdev->dev);
-+ return 0;
-+}
-+
-+static const struct of_device_id jh7110_tdm_of_match[] = {
-+ { .compatible = "starfive,jh7110-tdm", },
-+ {}
-+};
-+
-+MODULE_DEVICE_TABLE(of, jh7110_tdm_of_match);
-+
-+static const struct dev_pm_ops jh7110_tdm_pm_ops = {
-+ RUNTIME_PM_OPS(jh7110_tdm_runtime_suspend,
-+ jh7110_tdm_runtime_resume, NULL)
-+ SYSTEM_SLEEP_PM_OPS(jh7110_tdm_system_suspend,
-+ jh7110_tdm_system_resume)
-+};
-+
-+static struct platform_driver jh7110_tdm_driver = {
-+ .driver = {
-+ .name = "jh7110-tdm",
-+ .of_match_table = jh7110_tdm_of_match,
-+ .pm = pm_ptr(&jh7110_tdm_pm_ops),
-+ },
-+ .probe = jh7110_tdm_probe,
-+ .remove = jh7110_tdm_dev_remove,
-+};
-+module_platform_driver(jh7110_tdm_driver);
-+
-+MODULE_DESCRIPTION("StarFive JH7110 TDM ASoC Driver");
-+MODULE_AUTHOR("Walker Chen <walker.chen@starfivetech.com>");
-+MODULE_LICENSE("GPL");
diff --git a/target/linux/starfive/patches-6.1/0070-dt-bindings-power-Add-power-domain-header-for-JH7110.patch b/target/linux/starfive/patches-6.1/0070-dt-bindings-power-Add-power-domain-header-for-JH7110.patch
deleted file mode 100644
index d8ba979f55..0000000000
--- a/target/linux/starfive/patches-6.1/0070-dt-bindings-power-Add-power-domain-header-for-JH7110.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From 598083825494088f927fa42c5a7bb2872029a7bc Mon Sep 17 00:00:00 2001
-From: Changhuang Liang <changhuang.liang@starfivetech.com>
-Date: Thu, 18 May 2023 23:01:59 -0700
-Subject: [PATCH 070/122] dt-bindings: power: Add power-domain header for
- JH7110
-
-Add power-domain header for JH7110 SoC, it can use to operate dphy
-power.
-
-Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
----
- include/dt-bindings/power/starfive,jh7110-pmu.h | 5 ++++-
- 1 file changed, 4 insertions(+), 1 deletion(-)
-
---- a/include/dt-bindings/power/starfive,jh7110-pmu.h
-+++ b/include/dt-bindings/power/starfive,jh7110-pmu.h
-@@ -1,6 +1,6 @@
- /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
- /*
-- * Copyright (C) 2022 StarFive Technology Co., Ltd.
-+ * Copyright (C) 2022-2023 StarFive Technology Co., Ltd.
- * Author: Walker Chen <walker.chen@starfivetech.com>
- */
- #ifndef __DT_BINDINGS_POWER_JH7110_POWER_H__
-@@ -14,4 +14,7 @@
- #define JH7110_PD_ISP 5
- #define JH7110_PD_VENC 6
-
-+#define JH7110_PD_DPHY_TX 0
-+#define JH7110_PD_DPHY_RX 1
-+
- #endif
diff --git a/target/linux/starfive/patches-6.1/0071-soc-starfive-Replace-SOC_STARFIVE-with-ARCH_STARFIVE.patch b/target/linux/starfive/patches-6.1/0071-soc-starfive-Replace-SOC_STARFIVE-with-ARCH_STARFIVE.patch
deleted file mode 100644
index fa0201b6ca..0000000000
--- a/target/linux/starfive/patches-6.1/0071-soc-starfive-Replace-SOC_STARFIVE-with-ARCH_STARFIVE.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From d83b51f60997365b80637f71924ab3dec91d5b77 Mon Sep 17 00:00:00 2001
-From: Changhuang Liang <changhuang.liang@starfivetech.com>
-Date: Thu, 18 May 2023 23:02:00 -0700
-Subject: [PATCH 071/122] soc: starfive: Replace SOC_STARFIVE with
- ARCH_STARFIVE
-
-Using ARCH_FOO symbol is preferred than SOC_FOO.
-
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
-Reviewed-by: Walker Chen <walker.chen@starfivetech.com>
-Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
----
- drivers/soc/starfive/Kconfig | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/soc/starfive/Kconfig
-+++ b/drivers/soc/starfive/Kconfig
-@@ -3,8 +3,8 @@
- config JH71XX_PMU
- bool "Support PMU for StarFive JH71XX Soc"
- depends on PM
-- depends on SOC_STARFIVE || COMPILE_TEST
-- default SOC_STARFIVE
-+ depends on ARCH_STARFIVE || COMPILE_TEST
-+ default ARCH_STARFIVE
- select PM_GENERIC_DOMAINS
- help
- Say 'y' here to enable support power domain support.
diff --git a/target/linux/starfive/patches-6.1/0072-soc-starfive-Extract-JH7110-pmu-private-operations.patch b/target/linux/starfive/patches-6.1/0072-soc-starfive-Extract-JH7110-pmu-private-operations.patch
deleted file mode 100644
index 5f2cb2810f..0000000000
--- a/target/linux/starfive/patches-6.1/0072-soc-starfive-Extract-JH7110-pmu-private-operations.patch
+++ /dev/null
@@ -1,175 +0,0 @@
-From 52e2ade50f3ec212468e284b1236aaa521ba5913 Mon Sep 17 00:00:00 2001
-From: Changhuang Liang <changhuang.liang@starfivetech.com>
-Date: Thu, 18 May 2023 23:02:01 -0700
-Subject: [PATCH 072/122] soc: starfive: Extract JH7110 pmu private operations
-
-Move JH7110 private operation into private data of compatible. Convenient
-to add AON PMU which would not have interrupts property.
-
-Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
-Reviewed-by: Walker Chen <walker.chen@starfivetech.com>
----
- drivers/soc/starfive/jh71xx_pmu.c | 89 +++++++++++++++++++++----------
- 1 file changed, 62 insertions(+), 27 deletions(-)
-
---- a/drivers/soc/starfive/jh71xx_pmu.c
-+++ b/drivers/soc/starfive/jh71xx_pmu.c
-@@ -51,9 +51,17 @@ struct jh71xx_domain_info {
- u8 bit;
- };
-
-+struct jh71xx_pmu;
-+struct jh71xx_pmu_dev;
-+
- struct jh71xx_pmu_match_data {
- const struct jh71xx_domain_info *domain_info;
- int num_domains;
-+ unsigned int pmu_status;
-+ int (*pmu_parse_irq)(struct platform_device *pdev,
-+ struct jh71xx_pmu *pmu);
-+ int (*pmu_set_state)(struct jh71xx_pmu_dev *pmd,
-+ u32 mask, bool on);
- };
-
- struct jh71xx_pmu {
-@@ -79,12 +87,12 @@ static int jh71xx_pmu_get_state(struct j
- if (!mask)
- return -EINVAL;
-
-- *is_on = readl(pmu->base + JH71XX_PMU_CURR_POWER_MODE) & mask;
-+ *is_on = readl(pmu->base + pmu->match_data->pmu_status) & mask;
-
- return 0;
- }
-
--static int jh71xx_pmu_set_state(struct jh71xx_pmu_dev *pmd, u32 mask, bool on)
-+static int jh7110_pmu_set_state(struct jh71xx_pmu_dev *pmd, u32 mask, bool on)
- {
- struct jh71xx_pmu *pmu = pmd->pmu;
- unsigned long flags;
-@@ -92,22 +100,8 @@ static int jh71xx_pmu_set_state(struct j
- u32 mode;
- u32 encourage_lo;
- u32 encourage_hi;
-- bool is_on;
- int ret;
-
-- ret = jh71xx_pmu_get_state(pmd, mask, &is_on);
-- if (ret) {
-- dev_dbg(pmu->dev, "unable to get current state for %s\n",
-- pmd->genpd.name);
-- return ret;
-- }
--
-- if (is_on == on) {
-- dev_dbg(pmu->dev, "pm domain [%s] is already %sable status.\n",
-- pmd->genpd.name, on ? "en" : "dis");
-- return 0;
-- }
--
- spin_lock_irqsave(&pmu->lock, flags);
-
- /*
-@@ -166,6 +160,29 @@ static int jh71xx_pmu_set_state(struct j
- return 0;
- }
-
-+static int jh71xx_pmu_set_state(struct jh71xx_pmu_dev *pmd, u32 mask, bool on)
-+{
-+ struct jh71xx_pmu *pmu = pmd->pmu;
-+ const struct jh71xx_pmu_match_data *match_data = pmu->match_data;
-+ bool is_on;
-+ int ret;
-+
-+ ret = jh71xx_pmu_get_state(pmd, mask, &is_on);
-+ if (ret) {
-+ dev_dbg(pmu->dev, "unable to get current state for %s\n",
-+ pmd->genpd.name);
-+ return ret;
-+ }
-+
-+ if (is_on == on) {
-+ dev_dbg(pmu->dev, "pm domain [%s] is already %sable status.\n",
-+ pmd->genpd.name, on ? "en" : "dis");
-+ return 0;
-+ }
-+
-+ return match_data->pmu_set_state(pmd, mask, on);
-+}
-+
- static int jh71xx_pmu_on(struct generic_pm_domain *genpd)
- {
- struct jh71xx_pmu_dev *pmd = container_of(genpd,
-@@ -226,6 +243,25 @@ static irqreturn_t jh71xx_pmu_interrupt(
- return IRQ_HANDLED;
- }
-
-+static int jh7110_pmu_parse_irq(struct platform_device *pdev, struct jh71xx_pmu *pmu)
-+{
-+ struct device *dev = &pdev->dev;
-+ int ret;
-+
-+ pmu->irq = platform_get_irq(pdev, 0);
-+ if (pmu->irq < 0)
-+ return pmu->irq;
-+
-+ ret = devm_request_irq(dev, pmu->irq, jh71xx_pmu_interrupt,
-+ 0, pdev->name, pmu);
-+ if (ret)
-+ dev_err(dev, "failed to request irq\n");
-+
-+ jh71xx_pmu_int_enable(pmu, JH71XX_PMU_INT_ALL_MASK & ~JH71XX_PMU_INT_PCH_FAIL, true);
-+
-+ return 0;
-+}
-+
- static int jh71xx_pmu_init_domain(struct jh71xx_pmu *pmu, int index)
- {
- struct jh71xx_pmu_dev *pmd;
-@@ -275,19 +311,18 @@ static int jh71xx_pmu_probe(struct platf
- if (IS_ERR(pmu->base))
- return PTR_ERR(pmu->base);
-
-- pmu->irq = platform_get_irq(pdev, 0);
-- if (pmu->irq < 0)
-- return pmu->irq;
--
-- ret = devm_request_irq(dev, pmu->irq, jh71xx_pmu_interrupt,
-- 0, pdev->name, pmu);
-- if (ret)
-- dev_err(dev, "failed to request irq\n");
-+ spin_lock_init(&pmu->lock);
-
- match_data = of_device_get_match_data(dev);
- if (!match_data)
- return -EINVAL;
-
-+ ret = match_data->pmu_parse_irq(pdev, pmu);
-+ if (ret) {
-+ dev_err(dev, "failed to parse irq\n");
-+ return ret;
-+ }
-+
- pmu->genpd = devm_kcalloc(dev, match_data->num_domains,
- sizeof(struct generic_pm_domain *),
- GFP_KERNEL);
-@@ -307,9 +342,6 @@ static int jh71xx_pmu_probe(struct platf
- }
- }
-
-- spin_lock_init(&pmu->lock);
-- jh71xx_pmu_int_enable(pmu, JH71XX_PMU_INT_ALL_MASK & ~JH71XX_PMU_INT_PCH_FAIL, true);
--
- ret = of_genpd_add_provider_onecell(np, &pmu->genpd_data);
- if (ret) {
- dev_err(dev, "failed to register genpd driver: %d\n", ret);
-@@ -357,6 +389,9 @@ static const struct jh71xx_domain_info j
- static const struct jh71xx_pmu_match_data jh7110_pmu = {
- .num_domains = ARRAY_SIZE(jh7110_power_domains),
- .domain_info = jh7110_power_domains,
-+ .pmu_status = JH71XX_PMU_CURR_POWER_MODE,
-+ .pmu_parse_irq = jh7110_pmu_parse_irq,
-+ .pmu_set_state = jh7110_pmu_set_state,
- };
-
- static const struct of_device_id jh71xx_pmu_of_match[] = {
diff --git a/target/linux/starfive/patches-6.1/0073-soc-starfive-Add-JH7110-AON-PMU-support.patch b/target/linux/starfive/patches-6.1/0073-soc-starfive-Add-JH7110-AON-PMU-support.patch
deleted file mode 100644
index ec7a476b8f..0000000000
--- a/target/linux/starfive/patches-6.1/0073-soc-starfive-Add-JH7110-AON-PMU-support.patch
+++ /dev/null
@@ -1,119 +0,0 @@
-From 3124d653318c50e20eadbb3998eafa5928ac9b63 Mon Sep 17 00:00:00 2001
-From: Changhuang Liang <changhuang.liang@starfivetech.com>
-Date: Thu, 18 May 2023 23:02:02 -0700
-Subject: [PATCH 073/122] soc: starfive: Add JH7110 AON PMU support
-
-Add AON PMU for StarFive JH7110 SoC. It can be used to turn on/off the
-dphy rx/tx power switch.
-
-Reviewed-by: Walker Chen <walker.chen@starfivetech.com>
-Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
----
- drivers/soc/starfive/jh71xx_pmu.c | 57 ++++++++++++++++++++++++++++---
- 1 file changed, 52 insertions(+), 5 deletions(-)
-
---- a/drivers/soc/starfive/jh71xx_pmu.c
-+++ b/drivers/soc/starfive/jh71xx_pmu.c
-@@ -2,7 +2,7 @@
- /*
- * StarFive JH71XX PMU (Power Management Unit) Controller Driver
- *
-- * Copyright (C) 2022 StarFive Technology Co., Ltd.
-+ * Copyright (C) 2022-2023 StarFive Technology Co., Ltd.
- */
-
- #include <linux/interrupt.h>
-@@ -24,6 +24,9 @@
- #define JH71XX_PMU_EVENT_STATUS 0x88
- #define JH71XX_PMU_INT_STATUS 0x8C
-
-+/* aon pmu register offset */
-+#define JH71XX_AON_PMU_SWITCH 0x00
-+
- /* sw encourage cfg */
- #define JH71XX_PMU_SW_ENCOURAGE_EN_LO 0x05
- #define JH71XX_PMU_SW_ENCOURAGE_EN_HI 0x50
-@@ -160,6 +163,26 @@ static int jh7110_pmu_set_state(struct j
- return 0;
- }
-
-+static int jh7110_aon_pmu_set_state(struct jh71xx_pmu_dev *pmd, u32 mask, bool on)
-+{
-+ struct jh71xx_pmu *pmu = pmd->pmu;
-+ unsigned long flags;
-+ u32 val;
-+
-+ spin_lock_irqsave(&pmu->lock, flags);
-+ val = readl(pmu->base + JH71XX_AON_PMU_SWITCH);
-+
-+ if (on)
-+ val |= mask;
-+ else
-+ val &= ~mask;
-+
-+ writel(val, pmu->base + JH71XX_AON_PMU_SWITCH);
-+ spin_unlock_irqrestore(&pmu->lock, flags);
-+
-+ return 0;
-+}
-+
- static int jh71xx_pmu_set_state(struct jh71xx_pmu_dev *pmd, u32 mask, bool on)
- {
- struct jh71xx_pmu *pmu = pmd->pmu;
-@@ -317,10 +340,12 @@ static int jh71xx_pmu_probe(struct platf
- if (!match_data)
- return -EINVAL;
-
-- ret = match_data->pmu_parse_irq(pdev, pmu);
-- if (ret) {
-- dev_err(dev, "failed to parse irq\n");
-- return ret;
-+ if (match_data->pmu_parse_irq) {
-+ ret = match_data->pmu_parse_irq(pdev, pmu);
-+ if (ret) {
-+ dev_err(dev, "failed to parse irq\n");
-+ return ret;
-+ }
- }
-
- pmu->genpd = devm_kcalloc(dev, match_data->num_domains,
-@@ -394,11 +419,32 @@ static const struct jh71xx_pmu_match_dat
- .pmu_set_state = jh7110_pmu_set_state,
- };
-
-+static const struct jh71xx_domain_info jh7110_aon_power_domains[] = {
-+ [JH7110_PD_DPHY_TX] = {
-+ .name = "DPHY-TX",
-+ .bit = 30,
-+ },
-+ [JH7110_PD_DPHY_RX] = {
-+ .name = "DPHY-RX",
-+ .bit = 31,
-+ },
-+};
-+
-+static const struct jh71xx_pmu_match_data jh7110_aon_pmu = {
-+ .num_domains = ARRAY_SIZE(jh7110_aon_power_domains),
-+ .domain_info = jh7110_aon_power_domains,
-+ .pmu_status = JH71XX_AON_PMU_SWITCH,
-+ .pmu_set_state = jh7110_aon_pmu_set_state,
-+};
-+
- static const struct of_device_id jh71xx_pmu_of_match[] = {
- {
- .compatible = "starfive,jh7110-pmu",
- .data = (void *)&jh7110_pmu,
- }, {
-+ .compatible = "starfive,jh7110-aon-syscon",
-+ .data = (void *)&jh7110_aon_pmu,
-+ }, {
- /* sentinel */
- }
- };
-@@ -414,5 +460,6 @@ static struct platform_driver jh71xx_pmu
- builtin_platform_driver(jh71xx_pmu_driver);
-
- MODULE_AUTHOR("Walker Chen <walker.chen@starfivetech.com>");
-+MODULE_AUTHOR("Changhuang Liang <changhuang.liang@starfivetech.com>");
- MODULE_DESCRIPTION("StarFive JH71XX PMU Driver");
- MODULE_LICENSE("GPL");
diff --git a/target/linux/starfive/patches-6.1/0074-dt-bindings-phy-Add-starfive-jh7110-dphy-rx.patch b/target/linux/starfive/patches-6.1/0074-dt-bindings-phy-Add-starfive-jh7110-dphy-rx.patch
deleted file mode 100644
index 6368e53d84..0000000000
--- a/target/linux/starfive/patches-6.1/0074-dt-bindings-phy-Add-starfive-jh7110-dphy-rx.patch
+++ /dev/null
@@ -1,88 +0,0 @@
-From 7492ebbdd926da258f9abea5c41a9f8c4ec48631 Mon Sep 17 00:00:00 2001
-From: Changhuang Liang <changhuang.liang@starfivetech.com>
-Date: Mon, 29 May 2023 05:15:01 -0700
-Subject: [PATCH 074/122] dt-bindings: phy: Add starfive,jh7110-dphy-rx
-
-StarFive SoCs like the jh7110 use a MIPI D-PHY RX controller based on
-a M31 IP. Add a binding for it.
-
-Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
----
- .../bindings/phy/starfive,jh7110-dphy-rx.yaml | 71 +++++++++++++++++++
- 1 file changed, 71 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/phy/starfive,jh7110-dphy-rx.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/phy/starfive,jh7110-dphy-rx.yaml
-@@ -0,0 +1,71 @@
-+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/phy/starfive,jh7110-dphy-rx.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: StarFive SoC MIPI D-PHY Rx Controller
-+
-+maintainers:
-+ - Jack Zhu <jack.zhu@starfivetech.com>
-+ - Changhuang Liang <changhuang.liang@starfivetech.com>
-+
-+description:
-+ The StarFive SoC uses the MIPI CSI D-PHY based on M31 IP to transfer
-+ CSI camera data.
-+
-+properties:
-+ compatible:
-+ const: starfive,jh7110-dphy-rx
-+
-+ reg:
-+ maxItems: 1
-+
-+ clocks:
-+ items:
-+ - description: config clock
-+ - description: reference clock
-+ - description: escape mode transmit clock
-+
-+ clock-names:
-+ items:
-+ - const: cfg
-+ - const: ref
-+ - const: tx
-+
-+ resets:
-+ items:
-+ - description: DPHY_HW reset
-+ - description: DPHY_B09_ALWAYS_ON reset
-+
-+ power-domains:
-+ maxItems: 1
-+
-+ "#phy-cells":
-+ const: 0
-+
-+required:
-+ - compatible
-+ - reg
-+ - clocks
-+ - clock-names
-+ - resets
-+ - power-domains
-+ - "#phy-cells"
-+
-+additionalProperties: false
-+
-+examples:
-+ - |
-+ phy@19820000 {
-+ compatible = "starfive,jh7110-dphy-rx";
-+ reg = <0x19820000 0x10000>;
-+ clocks = <&ispcrg 3>,
-+ <&ispcrg 4>,
-+ <&ispcrg 5>;
-+ clock-names = "cfg", "ref", "tx";
-+ resets = <&ispcrg 2>,
-+ <&ispcrg 3>;
-+ power-domains = <&dphy_pwrc 1>;
-+ #phy-cells = <0>;
-+ };
diff --git a/target/linux/starfive/patches-6.1/0075-phy-starfive-Add-mipi-dphy-rx-support.patch b/target/linux/starfive/patches-6.1/0075-phy-starfive-Add-mipi-dphy-rx-support.patch
deleted file mode 100644
index d5db36a1e6..0000000000
--- a/target/linux/starfive/patches-6.1/0075-phy-starfive-Add-mipi-dphy-rx-support.patch
+++ /dev/null
@@ -1,365 +0,0 @@
-From f6fbb431f9e3ac5c9144edf05340db9a96dffa59 Mon Sep 17 00:00:00 2001
-From: Changhuang Liang <changhuang.liang@starfivetech.com>
-Date: Mon, 29 May 2023 05:15:02 -0700
-Subject: [PATCH 075/122] phy: starfive: Add mipi dphy rx support
-
-Add mipi dphy rx support for the StarFive JH7110 SoC. It is used to
-transfer CSI camera data.
-
-Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
----
- drivers/phy/Kconfig | 1 +
- drivers/phy/Makefile | 1 +
- drivers/phy/starfive/Kconfig | 13 +
- drivers/phy/starfive/Makefile | 2 +
- drivers/phy/starfive/phy-starfive-dphy-rx.c | 301 ++++++++++++++++++++
- 5 files changed, 318 insertions(+)
- create mode 100644 drivers/phy/starfive/Kconfig
- create mode 100644 drivers/phy/starfive/Makefile
- create mode 100644 drivers/phy/starfive/phy-starfive-dphy-rx.c
-
---- a/drivers/phy/Kconfig
-+++ b/drivers/phy/Kconfig
-@@ -91,6 +91,7 @@ source "drivers/phy/rockchip/Kconfig"
- source "drivers/phy/samsung/Kconfig"
- source "drivers/phy/socionext/Kconfig"
- source "drivers/phy/st/Kconfig"
-+source "drivers/phy/starfive/Kconfig"
- source "drivers/phy/sunplus/Kconfig"
- source "drivers/phy/tegra/Kconfig"
- source "drivers/phy/ti/Kconfig"
---- a/drivers/phy/Makefile
-+++ b/drivers/phy/Makefile
-@@ -31,6 +31,7 @@ obj-y += allwinner/ \
- samsung/ \
- socionext/ \
- st/ \
-+ starfive/ \
- sunplus/ \
- tegra/ \
- ti/ \
---- /dev/null
-+++ b/drivers/phy/starfive/Kconfig
-@@ -0,0 +1,13 @@
-+# SPDX-License-Identifier: GPL-2.0-only
-+#
-+# Phy drivers for StarFive platforms
-+#
-+
-+config PHY_STARFIVE_DPHY_RX
-+ tristate "StarFive D-PHY RX Support"
-+ select GENERIC_PHY
-+ select GENERIC_PHY_MIPI_DPHY
-+ help
-+ Choose this option if you have a StarFive D-PHY in your
-+ system. If M is selected, the module will be called
-+ phy-starfive-dphy-rx.
---- /dev/null
-+++ b/drivers/phy/starfive/Makefile
-@@ -0,0 +1,2 @@
-+# SPDX-License-Identifier: GPL-2.0
-+obj-$(CONFIG_PHY_STARFIVE_DPHY_RX) += phy-starfive-dphy-rx.o
---- /dev/null
-+++ b/drivers/phy/starfive/phy-starfive-dphy-rx.c
-@@ -0,0 +1,301 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+/*
-+ * DPHY driver for the StarFive JH7110 SoC
-+ *
-+ * Copyright (C) 2023 StarFive Technology Co., Ltd.
-+ */
-+
-+#include <linux/bitfield.h>
-+#include <linux/bitops.h>
-+#include <linux/clk.h>
-+#include <linux/io.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/of_device.h>
-+#include <linux/phy/phy.h>
-+#include <linux/platform_device.h>
-+#include <linux/pm_runtime.h>
-+#include <linux/reset.h>
-+
-+#define STF_DPHY_APBCFGSAIF_SYSCFG(x) (x)
-+
-+#define STF_DPHY_DA_CDPHY_R100_CTRL0_2D1C_EFUSE_EN BIT(6)
-+#define STF_DPHY_DA_CDPHY_R100_CTRL0_2D1C_EFUSE_IN GENMASK(12, 7)
-+#define STF_DPHY_DA_CDPHY_R100_CTRL1_2D1C_EFUSE_EN BIT(19)
-+#define STF_DPHY_DA_CDPHY_R100_CTRL1_2D1C_EFUSE_IN GENMASK(25, 20)
-+
-+#define STF_DPHY_DATA_BUS16_8 BIT(8)
-+#define STF_DPHY_DEBUG_MODE_SEL GENMASK(15, 9)
-+
-+#define STF_DPHY_ENABLE_CLK BIT(6)
-+#define STF_DPHY_ENABLE_CLK1 BIT(7)
-+#define STF_DPHY_ENABLE_LAN0 BIT(8)
-+#define STF_DPHY_ENABLE_LAN1 BIT(9)
-+#define STF_DPHY_ENABLE_LAN2 BIT(10)
-+#define STF_DPHY_ENABLE_LAN3 BIT(11)
-+#define STF_DPHY_GPI_EN GENMASK(17, 12)
-+#define STF_DPHY_HS_FREQ_CHANGE_CLK BIT(18)
-+#define STF_DPHY_HS_FREQ_CHANGE_CLK1 BIT(19)
-+#define STF_DPHY_LANE_SWAP_CLK GENMASK(22, 20)
-+#define STF_DPHY_LANE_SWAP_CLK1 GENMASK(25, 23)
-+#define STF_DPHY_LANE_SWAP_LAN0 GENMASK(28, 26)
-+#define STF_DPHY_LANE_SWAP_LAN1 GENMASK(31, 29)
-+
-+#define STF_DPHY_LANE_SWAP_LAN2 GENMASK(2, 0)
-+#define STF_DPHY_LANE_SWAP_LAN3 GENMASK(5, 3)
-+#define STF_DPHY_MP_TEST_EN BIT(6)
-+#define STF_DPHY_MP_TEST_MODE_SEL GENMASK(11, 7)
-+#define STF_DPHY_PLL_CLK_SEL GENMASK(21, 12)
-+#define STF_DPHY_PRECOUNTER_IN_CLK GENMASK(29, 22)
-+
-+#define STF_DPHY_PRECOUNTER_IN_CLK1 GENMASK(7, 0)
-+#define STF_DPHY_PRECOUNTER_IN_LAN0 GENMASK(15, 8)
-+#define STF_DPHY_PRECOUNTER_IN_LAN1 GENMASK(23, 16)
-+#define STF_DPHY_PRECOUNTER_IN_LAN2 GENMASK(31, 24)
-+
-+#define STF_DPHY_PRECOUNTER_IN_LAN3 GENMASK(7, 0)
-+#define STF_DPHY_RX_1C2C_SEL BIT(8)
-+
-+#define STF_MAP_LANES_NUM 6
-+
-+struct regval {
-+ u32 addr;
-+ u32 val;
-+};
-+
-+struct stf_dphy_info {
-+ /**
-+ * @maps:
-+ *
-+ * Physical lanes and logic lanes mapping table.
-+ *
-+ * The default order is:
-+ * [clk lane0, data lane 0, data lane 1, data lane 2, date lane 3, clk lane 1]
-+ */
-+ u8 maps[STF_MAP_LANES_NUM];
-+};
-+
-+struct stf_dphy {
-+ struct device *dev;
-+ void __iomem *regs;
-+ struct clk *cfg_clk;
-+ struct clk *ref_clk;
-+ struct clk *tx_clk;
-+ struct reset_control *rstc;
-+ struct regulator *mipi_0p9;
-+ struct phy *phy;
-+ const struct stf_dphy_info *info;
-+};
-+
-+static const struct regval stf_dphy_init_list[] = {
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(4), 0x00000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(8), 0x00000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(12), 0x0000fff0 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(16), 0x00000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(20), 0x00000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(24), 0x00000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(28), 0x00000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(32), 0x00000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(36), 0x00000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(40), 0x00000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(40), 0x00000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(48), 0x24000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(52), 0x00000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(56), 0x00000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(60), 0x00000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(64), 0x00000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(68), 0x00000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(72), 0x00000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(76), 0x00000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(80), 0x00000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(84), 0x00000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(88), 0x00000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(92), 0x00000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(96), 0x00000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(100), 0x02000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(104), 0x00000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(108), 0x00000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(112), 0x00000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(116), 0x00000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(120), 0x00000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(124), 0x0000000c },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(128), 0x00000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(132), 0xcc500000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(136), 0x000000cc },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(140), 0x00000000 },
-+ { STF_DPHY_APBCFGSAIF_SYSCFG(144), 0x00000000 },
-+};
-+
-+static int stf_dphy_configure(struct phy *phy, union phy_configure_opts *opts)
-+{
-+ struct stf_dphy *dphy = phy_get_drvdata(phy);
-+ const struct stf_dphy_info *info = dphy->info;
-+ int i;
-+
-+ for (i = 0; i < ARRAY_SIZE(stf_dphy_init_list); i++)
-+ writel(stf_dphy_init_list[i].val,
-+ dphy->regs + stf_dphy_init_list[i].addr);
-+
-+ writel(FIELD_PREP(STF_DPHY_DA_CDPHY_R100_CTRL0_2D1C_EFUSE_EN, 1) |
-+ FIELD_PREP(STF_DPHY_DA_CDPHY_R100_CTRL0_2D1C_EFUSE_IN, 0x1b) |
-+ FIELD_PREP(STF_DPHY_DA_CDPHY_R100_CTRL1_2D1C_EFUSE_EN, 1) |
-+ FIELD_PREP(STF_DPHY_DA_CDPHY_R100_CTRL1_2D1C_EFUSE_IN, 0x1b),
-+ dphy->regs + STF_DPHY_APBCFGSAIF_SYSCFG(0));
-+
-+ writel(FIELD_PREP(STF_DPHY_DATA_BUS16_8, 0) |
-+ FIELD_PREP(STF_DPHY_DEBUG_MODE_SEL, 0x5a),
-+ dphy->regs + STF_DPHY_APBCFGSAIF_SYSCFG(184));
-+
-+ writel(FIELD_PREP(STF_DPHY_ENABLE_CLK, 1) |
-+ FIELD_PREP(STF_DPHY_ENABLE_CLK1, 1) |
-+ FIELD_PREP(STF_DPHY_ENABLE_LAN0, 1) |
-+ FIELD_PREP(STF_DPHY_ENABLE_LAN1, 1) |
-+ FIELD_PREP(STF_DPHY_ENABLE_LAN2, 1) |
-+ FIELD_PREP(STF_DPHY_ENABLE_LAN3, 1) |
-+ FIELD_PREP(STF_DPHY_GPI_EN, 0) |
-+ FIELD_PREP(STF_DPHY_HS_FREQ_CHANGE_CLK, 0) |
-+ FIELD_PREP(STF_DPHY_HS_FREQ_CHANGE_CLK1, 0) |
-+ FIELD_PREP(STF_DPHY_LANE_SWAP_CLK, info->maps[0]) |
-+ FIELD_PREP(STF_DPHY_LANE_SWAP_CLK1, info->maps[5]) |
-+ FIELD_PREP(STF_DPHY_LANE_SWAP_LAN0, info->maps[1]) |
-+ FIELD_PREP(STF_DPHY_LANE_SWAP_LAN1, info->maps[2]),
-+ dphy->regs + STF_DPHY_APBCFGSAIF_SYSCFG(188));
-+
-+ writel(FIELD_PREP(STF_DPHY_LANE_SWAP_LAN2, info->maps[3]) |
-+ FIELD_PREP(STF_DPHY_LANE_SWAP_LAN3, info->maps[4]) |
-+ FIELD_PREP(STF_DPHY_MP_TEST_EN, 0) |
-+ FIELD_PREP(STF_DPHY_MP_TEST_MODE_SEL, 0) |
-+ FIELD_PREP(STF_DPHY_PLL_CLK_SEL, 0x37c) |
-+ FIELD_PREP(STF_DPHY_PRECOUNTER_IN_CLK, 8),
-+ dphy->regs + STF_DPHY_APBCFGSAIF_SYSCFG(192));
-+
-+ writel(FIELD_PREP(STF_DPHY_PRECOUNTER_IN_CLK1, 8) |
-+ FIELD_PREP(STF_DPHY_PRECOUNTER_IN_LAN0, 7) |
-+ FIELD_PREP(STF_DPHY_PRECOUNTER_IN_LAN1, 7) |
-+ FIELD_PREP(STF_DPHY_PRECOUNTER_IN_LAN2, 7),
-+ dphy->regs + STF_DPHY_APBCFGSAIF_SYSCFG(196));
-+
-+ writel(FIELD_PREP(STF_DPHY_PRECOUNTER_IN_LAN3, 7) |
-+ FIELD_PREP(STF_DPHY_RX_1C2C_SEL, 0),
-+ dphy->regs + STF_DPHY_APBCFGSAIF_SYSCFG(200));
-+
-+ return 0;
-+}
-+
-+static int stf_dphy_power_on(struct phy *phy)
-+{
-+ struct stf_dphy *dphy = phy_get_drvdata(phy);
-+ int ret;
-+
-+ pm_runtime_get_sync(dphy->dev);
-+
-+ ret = regulator_enable(dphy->mipi_0p9);
-+ if (ret)
-+ return ret;
-+
-+ clk_set_rate(dphy->cfg_clk, 99000000);
-+ clk_set_rate(dphy->ref_clk, 49500000);
-+ clk_set_rate(dphy->tx_clk, 19800000);
-+ reset_control_deassert(dphy->rstc);
-+
-+ return 0;
-+}
-+
-+static int stf_dphy_power_off(struct phy *phy)
-+{
-+ struct stf_dphy *dphy = phy_get_drvdata(phy);
-+
-+ reset_control_assert(dphy->rstc);
-+
-+ regulator_disable(dphy->mipi_0p9);
-+
-+ pm_runtime_put_sync(dphy->dev);
-+
-+ return 0;
-+}
-+
-+static const struct phy_ops stf_dphy_ops = {
-+ .configure = stf_dphy_configure,
-+ .power_on = stf_dphy_power_on,
-+ .power_off = stf_dphy_power_off,
-+};
-+
-+static int stf_dphy_probe(struct platform_device *pdev)
-+{
-+ struct phy_provider *phy_provider;
-+ struct stf_dphy *dphy;
-+
-+ dphy = devm_kzalloc(&pdev->dev, sizeof(*dphy), GFP_KERNEL);
-+ if (!dphy)
-+ return -ENOMEM;
-+
-+ dphy->info = of_device_get_match_data(&pdev->dev);
-+
-+ dev_set_drvdata(&pdev->dev, dphy);
-+ dphy->dev = &pdev->dev;
-+
-+ dphy->regs = devm_platform_ioremap_resource(pdev, 0);
-+ if (IS_ERR(dphy->regs))
-+ return PTR_ERR(dphy->regs);
-+
-+ dphy->cfg_clk = devm_clk_get(&pdev->dev, "cfg");
-+ if (IS_ERR(dphy->cfg_clk))
-+ return PTR_ERR(dphy->cfg_clk);
-+
-+ dphy->ref_clk = devm_clk_get(&pdev->dev, "ref");
-+ if (IS_ERR(dphy->ref_clk))
-+ return PTR_ERR(dphy->ref_clk);
-+
-+ dphy->tx_clk = devm_clk_get(&pdev->dev, "tx");
-+ if (IS_ERR(dphy->tx_clk))
-+ return PTR_ERR(dphy->tx_clk);
-+
-+ dphy->rstc = devm_reset_control_array_get_exclusive(&pdev->dev);
-+ if (IS_ERR(dphy->rstc))
-+ return PTR_ERR(dphy->rstc);
-+
-+ dphy->mipi_0p9 = devm_regulator_get(&pdev->dev, "mipi_0p9");
-+ if (IS_ERR(dphy->mipi_0p9))
-+ return PTR_ERR(dphy->mipi_0p9);
-+
-+ dphy->phy = devm_phy_create(&pdev->dev, NULL, &stf_dphy_ops);
-+ if (IS_ERR(dphy->phy)) {
-+ dev_err(&pdev->dev, "Failed to create PHY\n");
-+ return PTR_ERR(dphy->phy);
-+ }
-+
-+ pm_runtime_enable(&pdev->dev);
-+
-+ phy_set_drvdata(dphy->phy, dphy);
-+ phy_provider = devm_of_phy_provider_register(&pdev->dev,
-+ of_phy_simple_xlate);
-+
-+ return PTR_ERR_OR_ZERO(phy_provider);
-+}
-+
-+static const struct stf_dphy_info starfive_dphy_info = {
-+ .maps = {4, 0, 1, 2, 3, 5},
-+};
-+
-+static const struct of_device_id stf_dphy_dt_ids[] = {
-+ {
-+ .compatible = "starfive,jh7110-dphy-rx",
-+ .data = &starfive_dphy_info,
-+ },
-+ { /* sentinel */ },
-+};
-+MODULE_DEVICE_TABLE(of, stf_dphy_dt_ids);
-+
-+static struct platform_driver stf_dphy_driver = {
-+ .probe = stf_dphy_probe,
-+ .driver = {
-+ .name = "starfive-dphy-rx",
-+ .of_match_table = stf_dphy_dt_ids,
-+ },
-+};
-+module_platform_driver(stf_dphy_driver);
-+
-+MODULE_AUTHOR("Jack Zhu <jack.zhu@starfivetech.com>");
-+MODULE_AUTHOR("Changhuang Liang <changhuang.liang@starfivetech.com>");
-+MODULE_DESCRIPTION("StarFive DPHY RX driver");
-+MODULE_LICENSE("GPL");
diff --git a/target/linux/starfive/patches-6.1/0076-media-dt-bindings-cadence-csi2rx-Convert-to-DT-schem.patch b/target/linux/starfive/patches-6.1/0076-media-dt-bindings-cadence-csi2rx-Convert-to-DT-schem.patch
deleted file mode 100644
index 4cabffbe53..0000000000
--- a/target/linux/starfive/patches-6.1/0076-media-dt-bindings-cadence-csi2rx-Convert-to-DT-schem.patch
+++ /dev/null
@@ -1,306 +0,0 @@
-From 243b040c3517093309a41877e3c1c6e8a7540071 Mon Sep 17 00:00:00 2001
-From: Jack Zhu <jack.zhu@starfivetech.com>
-Date: Tue, 23 May 2023 16:56:22 +0800
-Subject: [PATCH 076/122] media: dt-bindings: cadence-csi2rx: Convert to DT
- schema
-
-Convert DT bindings document for Cadence MIPI-CSI2 RX controller to
-DT schema format.
-
-For compatible, new compatibles should not be messed with conversion,
-but the original binding did not specify any SoC-specific compatible
-string, so add the StarFive compatible string.
-
-Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
-Signed-off-by: Jack Zhu <jack.zhu@starfivetech.com>
----
- .../devicetree/bindings/media/cdns,csi2rx.txt | 100 ----------
- .../bindings/media/cdns,csi2rx.yaml | 177 ++++++++++++++++++
- 2 files changed, 177 insertions(+), 100 deletions(-)
- delete mode 100644 Documentation/devicetree/bindings/media/cdns,csi2rx.txt
- create mode 100644 Documentation/devicetree/bindings/media/cdns,csi2rx.yaml
-
---- a/Documentation/devicetree/bindings/media/cdns,csi2rx.txt
-+++ /dev/null
-@@ -1,100 +0,0 @@
--Cadence MIPI-CSI2 RX controller
--===============================
--
--The Cadence MIPI-CSI2 RX controller is a CSI-2 bridge supporting up to 4 CSI
--lanes in input, and 4 different pixel streams in output.
--
--Required properties:
-- - compatible: must be set to "cdns,csi2rx" and an SoC-specific compatible
-- - reg: base address and size of the memory mapped region
-- - clocks: phandles to the clocks driving the controller
-- - clock-names: must contain:
-- * sys_clk: main clock
-- * p_clk: register bank clock
-- * pixel_if[0-3]_clk: pixel stream output clock, one for each stream
-- implemented in hardware, between 0 and 3
--
--Optional properties:
-- - phys: phandle to the external D-PHY, phy-names must be provided
-- - phy-names: must contain "dphy", if the implementation uses an
-- external D-PHY
--
--Required subnodes:
-- - ports: A ports node with one port child node per device input and output
-- port, in accordance with the video interface bindings defined in
-- Documentation/devicetree/bindings/media/video-interfaces.txt. The
-- port nodes are numbered as follows:
--
-- Port Description
-- -----------------------------
-- 0 CSI-2 input
-- 1 Stream 0 output
-- 2 Stream 1 output
-- 3 Stream 2 output
-- 4 Stream 3 output
--
-- The stream output port nodes are optional if they are not
-- connected to anything at the hardware level or implemented
-- in the design.Since there is only one endpoint per port,
-- the endpoints are not numbered.
--
--
--Example:
--
--csi2rx: csi-bridge@0d060000 {
-- compatible = "cdns,csi2rx";
-- reg = <0x0d060000 0x1000>;
-- clocks = <&byteclock>, <&byteclock>
-- <&coreclock>, <&coreclock>,
-- <&coreclock>, <&coreclock>;
-- clock-names = "sys_clk", "p_clk",
-- "pixel_if0_clk", "pixel_if1_clk",
-- "pixel_if2_clk", "pixel_if3_clk";
--
-- ports {
-- #address-cells = <1>;
-- #size-cells = <0>;
--
-- port@0 {
-- reg = <0>;
--
-- csi2rx_in_sensor: endpoint {
-- remote-endpoint = <&sensor_out_csi2rx>;
-- clock-lanes = <0>;
-- data-lanes = <1 2>;
-- };
-- };
--
-- port@1 {
-- reg = <1>;
--
-- csi2rx_out_grabber0: endpoint {
-- remote-endpoint = <&grabber0_in_csi2rx>;
-- };
-- };
--
-- port@2 {
-- reg = <2>;
--
-- csi2rx_out_grabber1: endpoint {
-- remote-endpoint = <&grabber1_in_csi2rx>;
-- };
-- };
--
-- port@3 {
-- reg = <3>;
--
-- csi2rx_out_grabber2: endpoint {
-- remote-endpoint = <&grabber2_in_csi2rx>;
-- };
-- };
--
-- port@4 {
-- reg = <4>;
--
-- csi2rx_out_grabber3: endpoint {
-- remote-endpoint = <&grabber3_in_csi2rx>;
-- };
-- };
-- };
--};
---- /dev/null
-+++ b/Documentation/devicetree/bindings/media/cdns,csi2rx.yaml
-@@ -0,0 +1,177 @@
-+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/media/cdns,csi2rx.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: Cadence MIPI-CSI2 RX controller
-+
-+maintainers:
-+ - Maxime Ripard <mripard@kernel.org>
-+
-+description:
-+ The Cadence MIPI-CSI2 RX controller is a CSI-2 bridge supporting up to 4 CSI
-+ lanes in input, and 4 different pixel streams in output.
-+
-+properties:
-+ compatible:
-+ items:
-+ - enum:
-+ - starfive,jh7110-csi2rx
-+ - const: cdns,csi2rx
-+
-+ reg:
-+ maxItems: 1
-+
-+ clocks:
-+ items:
-+ - description: CSI2Rx system clock
-+ - description: Gated Register bank clock for APB interface
-+ - description: pixel Clock for Stream interface 0
-+ - description: pixel Clock for Stream interface 1
-+ - description: pixel Clock for Stream interface 2
-+ - description: pixel Clock for Stream interface 3
-+
-+ clock-names:
-+ items:
-+ - const: sys_clk
-+ - const: p_clk
-+ - const: pixel_if0_clk
-+ - const: pixel_if1_clk
-+ - const: pixel_if2_clk
-+ - const: pixel_if3_clk
-+
-+ phys:
-+ maxItems: 1
-+ description: MIPI D-PHY
-+
-+ phy-names:
-+ items:
-+ - const: dphy
-+
-+ ports:
-+ $ref: /schemas/graph.yaml#/properties/ports
-+
-+ properties:
-+ port@0:
-+ $ref: /schemas/graph.yaml#/$defs/port-base
-+ unevaluatedProperties: false
-+ description:
-+ Input port node, single endpoint describing the CSI-2 transmitter.
-+
-+ properties:
-+ endpoint:
-+ $ref: video-interfaces.yaml#
-+ unevaluatedProperties: false
-+
-+ properties:
-+ bus-type:
-+ const: 4
-+
-+ clock-lanes:
-+ const: 0
-+
-+ data-lanes:
-+ minItems: 1
-+ maxItems: 4
-+ items:
-+ maximum: 4
-+
-+ required:
-+ - data-lanes
-+
-+ port@1:
-+ $ref: /schemas/graph.yaml#/properties/port
-+ description:
-+ Stream 0 Output port node
-+
-+ port@2:
-+ $ref: /schemas/graph.yaml#/properties/port
-+ description:
-+ Stream 1 Output port node
-+
-+ port@3:
-+ $ref: /schemas/graph.yaml#/properties/port
-+ description:
-+ Stream 2 Output port node
-+
-+ port@4:
-+ $ref: /schemas/graph.yaml#/properties/port
-+ description:
-+ Stream 3 Output port node
-+
-+ required:
-+ - port@0
-+
-+required:
-+ - compatible
-+ - reg
-+ - clocks
-+ - clock-names
-+ - ports
-+
-+additionalProperties: false
-+
-+examples:
-+ - |
-+ csi@d060000 {
-+ compatible = "starfive,jh7110-csi2rx", "cdns,csi2rx";
-+ reg = <0x0d060000 0x1000>;
-+ clocks = <&byteclock 7>, <&byteclock 6>,
-+ <&coreclock 8>, <&coreclock 9>,
-+ <&coreclock 10>, <&coreclock 11>;
-+ clock-names = "sys_clk", "p_clk",
-+ "pixel_if0_clk", "pixel_if1_clk",
-+ "pixel_if2_clk", "pixel_if3_clk";
-+ phys = <&csi_phy>;
-+ phy-names = "dphy";
-+
-+ ports {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ port@0 {
-+ reg = <0>;
-+
-+ csi2rx_in_sensor: endpoint {
-+ remote-endpoint = <&sensor_out_csi2rx>;
-+ clock-lanes = <0>;
-+ data-lanes = <1 2>;
-+ };
-+ };
-+
-+ port@1 {
-+ reg = <1>;
-+
-+ csi2rx_out_grabber0: endpoint {
-+ remote-endpoint = <&grabber0_in_csi2rx>;
-+ };
-+ };
-+
-+ port@2 {
-+ reg = <2>;
-+
-+ csi2rx_out_grabber1: endpoint {
-+ remote-endpoint = <&grabber1_in_csi2rx>;
-+ };
-+ };
-+
-+ port@3 {
-+ reg = <3>;
-+
-+ csi2rx_out_grabber2: endpoint {
-+ remote-endpoint = <&grabber2_in_csi2rx>;
-+ };
-+ };
-+
-+ port@4 {
-+ reg = <4>;
-+
-+ csi2rx_out_grabber3: endpoint {
-+ remote-endpoint = <&grabber3_in_csi2rx>;
-+ };
-+ };
-+ };
-+ };
-+
-+...
diff --git a/target/linux/starfive/patches-6.1/0077-media-dt-bindings-cadence-csi2rx-Add-resets-property.patch b/target/linux/starfive/patches-6.1/0077-media-dt-bindings-cadence-csi2rx-Add-resets-property.patch
deleted file mode 100644
index 55b3fade7d..0000000000
--- a/target/linux/starfive/patches-6.1/0077-media-dt-bindings-cadence-csi2rx-Add-resets-property.patch
+++ /dev/null
@@ -1,55 +0,0 @@
-From 60817a4e755c6e98092fdceec35fcda94d35e4b1 Mon Sep 17 00:00:00 2001
-From: Jack Zhu <jack.zhu@starfivetech.com>
-Date: Tue, 23 May 2023 16:56:23 +0800
-Subject: [PATCH 077/122] media: dt-bindings: cadence-csi2rx: Add resets
- property
-
-Add resets property for Cadence MIPI-CSI2 RX controller
-
-Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
-Signed-off-by: Jack Zhu <jack.zhu@starfivetech.com>
----
- .../bindings/media/cdns,csi2rx.yaml | 24 +++++++++++++++++++
- 1 file changed, 24 insertions(+)
-
---- a/Documentation/devicetree/bindings/media/cdns,csi2rx.yaml
-+++ b/Documentation/devicetree/bindings/media/cdns,csi2rx.yaml
-@@ -41,6 +41,24 @@ properties:
- - const: pixel_if2_clk
- - const: pixel_if3_clk
-
-+ resets:
-+ items:
-+ - description: CSI2Rx system reset
-+ - description: Gated Register bank reset for APB interface
-+ - description: pixel reset for Stream interface 0
-+ - description: pixel reset for Stream interface 1
-+ - description: pixel reset for Stream interface 2
-+ - description: pixel reset for Stream interface 3
-+
-+ reset-names:
-+ items:
-+ - const: sys
-+ - const: reg_bank
-+ - const: pixel_if0
-+ - const: pixel_if1
-+ - const: pixel_if2
-+ - const: pixel_if3
-+
- phys:
- maxItems: 1
- description: MIPI D-PHY
-@@ -123,6 +141,12 @@ examples:
- clock-names = "sys_clk", "p_clk",
- "pixel_if0_clk", "pixel_if1_clk",
- "pixel_if2_clk", "pixel_if3_clk";
-+ resets = <&bytereset 9>, <&bytereset 4>,
-+ <&corereset 5>, <&corereset 6>,
-+ <&corereset 7>, <&corereset 8>;
-+ reset-names = "sys", "reg_bank",
-+ "pixel_if0", "pixel_if1",
-+ "pixel_if2", "pixel_if3";
- phys = <&csi_phy>;
- phy-names = "dphy";
-
diff --git a/target/linux/starfive/patches-6.1/0078-media-cadence-Add-operation-on-reset.patch b/target/linux/starfive/patches-6.1/0078-media-cadence-Add-operation-on-reset.patch
deleted file mode 100644
index 2cc7b69089..0000000000
--- a/target/linux/starfive/patches-6.1/0078-media-cadence-Add-operation-on-reset.patch
+++ /dev/null
@@ -1,129 +0,0 @@
-From 2fbf4d367b25de4fa2f2d9cec57c88766c37d9de Mon Sep 17 00:00:00 2001
-From: Jack Zhu <jack.zhu@starfivetech.com>
-Date: Tue, 23 May 2023 16:56:24 +0800
-Subject: [PATCH 078/122] media: cadence: Add operation on reset
-
-Add operation on reset for Cadence MIPI-CSI2 RX Controller.
-
-Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
-Signed-off-by: Jack Zhu <jack.zhu@starfivetech.com>
----
- drivers/media/platform/cadence/cdns-csi2rx.c | 40 +++++++++++++++++---
- 1 file changed, 35 insertions(+), 5 deletions(-)
-
---- a/drivers/media/platform/cadence/cdns-csi2rx.c
-+++ b/drivers/media/platform/cadence/cdns-csi2rx.c
-@@ -13,6 +13,7 @@
- #include <linux/of_graph.h>
- #include <linux/phy/phy.h>
- #include <linux/platform_device.h>
-+#include <linux/reset.h>
- #include <linux/slab.h>
-
- #include <media/v4l2-ctrls.h>
-@@ -68,6 +69,9 @@ struct csi2rx_priv {
- struct clk *sys_clk;
- struct clk *p_clk;
- struct clk *pixel_clk[CSI2RX_STREAMS_MAX];
-+ struct reset_control *sys_rst;
-+ struct reset_control *p_rst;
-+ struct reset_control *pixel_rst[CSI2RX_STREAMS_MAX];
- struct phy *dphy;
-
- u8 lanes[CSI2RX_LANES_MAX];
-@@ -112,6 +116,7 @@ static int csi2rx_start(struct csi2rx_pr
- if (ret)
- return ret;
-
-+ reset_control_deassert(csi2rx->p_rst);
- csi2rx_reset(csi2rx);
-
- reg = csi2rx->num_lanes << 8;
-@@ -154,6 +159,8 @@ static int csi2rx_start(struct csi2rx_pr
- if (ret)
- goto err_disable_pixclk;
-
-+ reset_control_deassert(csi2rx->pixel_rst[i]);
-+
- writel(CSI2RX_STREAM_CFG_FIFO_MODE_LARGE_BUF,
- csi2rx->base + CSI2RX_STREAM_CFG_REG(i));
-
-@@ -169,13 +176,16 @@ static int csi2rx_start(struct csi2rx_pr
- if (ret)
- goto err_disable_pixclk;
-
-+ reset_control_deassert(csi2rx->sys_rst);
- clk_disable_unprepare(csi2rx->p_clk);
-
- return 0;
-
- err_disable_pixclk:
-- for (; i > 0; i--)
-+ for (; i > 0; i--) {
-+ reset_control_assert(csi2rx->pixel_rst[i - 1]);
- clk_disable_unprepare(csi2rx->pixel_clk[i - 1]);
-+ }
-
- err_disable_pclk:
- clk_disable_unprepare(csi2rx->p_clk);
-@@ -188,14 +198,17 @@ static void csi2rx_stop(struct csi2rx_pr
- unsigned int i;
-
- clk_prepare_enable(csi2rx->p_clk);
-+ reset_control_assert(csi2rx->sys_rst);
- clk_disable_unprepare(csi2rx->sys_clk);
-
- for (i = 0; i < csi2rx->max_streams; i++) {
- writel(0, csi2rx->base + CSI2RX_STREAM_CTRL_REG(i));
-
-+ reset_control_assert(csi2rx->pixel_rst[i]);
- clk_disable_unprepare(csi2rx->pixel_clk[i]);
- }
-
-+ reset_control_assert(csi2rx->p_rst);
- clk_disable_unprepare(csi2rx->p_clk);
-
- if (v4l2_subdev_call(csi2rx->source_subdev, video, s_stream, false))
-@@ -299,6 +312,16 @@ static int csi2rx_get_resources(struct c
- return PTR_ERR(csi2rx->p_clk);
- }
-
-+ csi2rx->sys_rst = devm_reset_control_get_optional_exclusive(&pdev->dev,
-+ "sys");
-+ if (IS_ERR(csi2rx->sys_rst))
-+ return PTR_ERR(csi2rx->sys_rst);
-+
-+ csi2rx->p_rst = devm_reset_control_get_optional_exclusive(&pdev->dev,
-+ "reg_bank");
-+ if (IS_ERR(csi2rx->p_rst))
-+ return PTR_ERR(csi2rx->p_rst);
-+
- csi2rx->dphy = devm_phy_optional_get(&pdev->dev, "dphy");
- if (IS_ERR(csi2rx->dphy)) {
- dev_err(&pdev->dev, "Couldn't get external D-PHY\n");
-@@ -349,14 +372,21 @@ static int csi2rx_get_resources(struct c
- }
-
- for (i = 0; i < csi2rx->max_streams; i++) {
-- char clk_name[16];
-+ char name[16];
-
-- snprintf(clk_name, sizeof(clk_name), "pixel_if%u_clk", i);
-- csi2rx->pixel_clk[i] = devm_clk_get(&pdev->dev, clk_name);
-+ snprintf(name, sizeof(name), "pixel_if%u_clk", i);
-+ csi2rx->pixel_clk[i] = devm_clk_get(&pdev->dev, name);
- if (IS_ERR(csi2rx->pixel_clk[i])) {
-- dev_err(&pdev->dev, "Couldn't get clock %s\n", clk_name);
-+ dev_err(&pdev->dev, "Couldn't get clock %s\n", name);
- return PTR_ERR(csi2rx->pixel_clk[i]);
- }
-+
-+ snprintf(name, sizeof(name), "pixel_if%u", i);
-+ csi2rx->pixel_rst[i] =
-+ devm_reset_control_get_optional_exclusive(&pdev->dev,
-+ name);
-+ if (IS_ERR(csi2rx->pixel_rst[i]))
-+ return PTR_ERR(csi2rx->pixel_rst[i]);
- }
-
- return 0;
diff --git a/target/linux/starfive/patches-6.1/0079-media-cadence-Add-support-for-external-dphy.patch b/target/linux/starfive/patches-6.1/0079-media-cadence-Add-support-for-external-dphy.patch
deleted file mode 100644
index 77e506eb47..0000000000
--- a/target/linux/starfive/patches-6.1/0079-media-cadence-Add-support-for-external-dphy.patch
+++ /dev/null
@@ -1,141 +0,0 @@
-From e97eb58b321b5b25b7d5c40880e6eb133d381581 Mon Sep 17 00:00:00 2001
-From: Jack Zhu <jack.zhu@starfivetech.com>
-Date: Tue, 23 May 2023 16:56:25 +0800
-Subject: [PATCH 079/122] media: cadence: Add support for external dphy
-
-Add support for external MIPI D-PHY.
-
-Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
-Signed-off-by: Jack Zhu <jack.zhu@starfivetech.com>
----
- drivers/media/platform/cadence/cdns-csi2rx.c | 66 +++++++++++++++++---
- 1 file changed, 56 insertions(+), 10 deletions(-)
-
---- a/drivers/media/platform/cadence/cdns-csi2rx.c
-+++ b/drivers/media/platform/cadence/cdns-csi2rx.c
-@@ -31,6 +31,12 @@
- #define CSI2RX_STATIC_CFG_DLANE_MAP(llane, plane) ((plane) << (16 + (llane) * 4))
- #define CSI2RX_STATIC_CFG_LANES_MASK GENMASK(11, 8)
-
-+#define CSI2RX_DPHY_LANE_CTRL_REG 0x40
-+#define CSI2RX_DPHY_CL_RST BIT(16)
-+#define CSI2RX_DPHY_DL_RST(i) BIT((i) + 12)
-+#define CSI2RX_DPHY_CL_EN BIT(4)
-+#define CSI2RX_DPHY_DL_EN(i) BIT(i)
-+
- #define CSI2RX_STREAM_BASE(n) (((n) + 1) * 0x100)
-
- #define CSI2RX_STREAM_CTRL_REG(n) (CSI2RX_STREAM_BASE(n) + 0x000)
-@@ -105,6 +111,24 @@ static void csi2rx_reset(struct csi2rx_p
- writel(0, csi2rx->base + CSI2RX_SOFT_RESET_REG);
- }
-
-+static int csi2rx_configure_ext_dphy(struct csi2rx_priv *csi2rx)
-+{
-+ union phy_configure_opts opts = { };
-+ int ret;
-+
-+ ret = phy_power_on(csi2rx->dphy);
-+ if (ret)
-+ return ret;
-+
-+ ret = phy_configure(csi2rx->dphy, &opts);
-+ if (ret) {
-+ phy_power_off(csi2rx->dphy);
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+
- static int csi2rx_start(struct csi2rx_priv *csi2rx)
- {
- unsigned int i;
-@@ -144,6 +168,17 @@ static int csi2rx_start(struct csi2rx_pr
- if (ret)
- goto err_disable_pclk;
-
-+ /* Enable DPHY clk and data lanes. */
-+ if (csi2rx->dphy) {
-+ reg = CSI2RX_DPHY_CL_EN | CSI2RX_DPHY_CL_RST;
-+ for (i = 0; i < csi2rx->num_lanes; i++) {
-+ reg |= CSI2RX_DPHY_DL_EN(csi2rx->lanes[i] - 1);
-+ reg |= CSI2RX_DPHY_DL_RST(csi2rx->lanes[i] - 1);
-+ }
-+
-+ writel(reg, csi2rx->base + CSI2RX_DPHY_LANE_CTRL_REG);
-+ }
-+
- /*
- * Create a static mapping between the CSI virtual channels
- * and the output stream.
-@@ -177,10 +212,22 @@ static int csi2rx_start(struct csi2rx_pr
- goto err_disable_pixclk;
-
- reset_control_deassert(csi2rx->sys_rst);
-+
-+ if (csi2rx->dphy) {
-+ ret = csi2rx_configure_ext_dphy(csi2rx);
-+ if (ret) {
-+ dev_err(csi2rx->dev,
-+ "Failed to configure external DPHY: %d\n", ret);
-+ goto err_disable_sysclk;
-+ }
-+ }
-+
- clk_disable_unprepare(csi2rx->p_clk);
-
- return 0;
-
-+err_disable_sysclk:
-+ clk_disable_unprepare(csi2rx->sys_clk);
- err_disable_pixclk:
- for (; i > 0; i--) {
- reset_control_assert(csi2rx->pixel_rst[i - 1]);
-@@ -213,6 +260,13 @@ static void csi2rx_stop(struct csi2rx_pr
-
- if (v4l2_subdev_call(csi2rx->source_subdev, video, s_stream, false))
- dev_warn(csi2rx->dev, "Couldn't disable our subdev\n");
-+
-+ if (csi2rx->dphy) {
-+ writel(0, csi2rx->base + CSI2RX_DPHY_LANE_CTRL_REG);
-+
-+ if (phy_power_off(csi2rx->dphy))
-+ dev_warn(csi2rx->dev, "Couldn't power off DPHY\n");
-+ }
- }
-
- static int csi2rx_s_stream(struct v4l2_subdev *subdev, int enable)
-@@ -328,15 +382,6 @@ static int csi2rx_get_resources(struct c
- return PTR_ERR(csi2rx->dphy);
- }
-
-- /*
-- * FIXME: Once we'll have external D-PHY support, the check
-- * will need to be removed.
-- */
-- if (csi2rx->dphy) {
-- dev_err(&pdev->dev, "External D-PHY not supported yet\n");
-- return -EINVAL;
-- }
--
- ret = clk_prepare_enable(csi2rx->p_clk);
- if (ret) {
- dev_err(&pdev->dev, "Couldn't prepare and enable P clock\n");
-@@ -366,7 +411,7 @@ static int csi2rx_get_resources(struct c
- * FIXME: Once we'll have internal D-PHY support, the check
- * will need to be removed.
- */
-- if (csi2rx->has_internal_dphy) {
-+ if (!csi2rx->dphy && csi2rx->has_internal_dphy) {
- dev_err(&pdev->dev, "Internal D-PHY not supported yet\n");
- return -EINVAL;
- }
-@@ -494,6 +539,7 @@ static int csi2rx_probe(struct platform_
- dev_info(&pdev->dev,
- "Probed CSI2RX with %u/%u lanes, %u streams, %s D-PHY\n",
- csi2rx->num_lanes, csi2rx->max_lanes, csi2rx->max_streams,
-+ csi2rx->dphy ? "external" :
- csi2rx->has_internal_dphy ? "internal" : "no");
-
- return 0;
diff --git a/target/linux/starfive/patches-6.1/0080-media-cadence-Add-support-for-JH7110-SoC.patch b/target/linux/starfive/patches-6.1/0080-media-cadence-Add-support-for-JH7110-SoC.patch
deleted file mode 100644
index f3527840b6..0000000000
--- a/target/linux/starfive/patches-6.1/0080-media-cadence-Add-support-for-JH7110-SoC.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-From d541f0ab42983dbc856f2229ee471677e80945a3 Mon Sep 17 00:00:00 2001
-From: Jack Zhu <jack.zhu@starfivetech.com>
-Date: Tue, 23 May 2023 16:56:26 +0800
-Subject: [PATCH 080/122] media: cadence: Add support for JH7110 SoC
-
-Add support for Starfive JH7110 SoC which has the cadence csi2 receiver.
-
-Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
-Signed-off-by: Jack Zhu <jack.zhu@starfivetech.com>
----
- drivers/media/platform/cadence/cdns-csi2rx.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/drivers/media/platform/cadence/cdns-csi2rx.c
-+++ b/drivers/media/platform/cadence/cdns-csi2rx.c
-@@ -565,6 +565,7 @@ static int csi2rx_remove(struct platform
- }
-
- static const struct of_device_id csi2rx_of_table[] = {
-+ { .compatible = "starfive,jh7110-csi2rx" },
- { .compatible = "cdns,csi2rx" },
- { },
- };
diff --git a/target/linux/starfive/patches-6.1/0081-media-dt-bindings-Add-JH7110-Camera-Subsystem.patch b/target/linux/starfive/patches-6.1/0081-media-dt-bindings-Add-JH7110-Camera-Subsystem.patch
deleted file mode 100644
index 0b3bf80b46..0000000000
--- a/target/linux/starfive/patches-6.1/0081-media-dt-bindings-Add-JH7110-Camera-Subsystem.patch
+++ /dev/null
@@ -1,197 +0,0 @@
-From f3195b45a3845fd3892ca932a9cc8e352942dbcd Mon Sep 17 00:00:00 2001
-From: Jack Zhu <jack.zhu@starfivetech.com>
-Date: Fri, 12 May 2023 18:28:39 +0800
-Subject: [PATCH 081/122] media: dt-bindings: Add JH7110 Camera Subsystem
-
-Add the bindings documentation for Starfive JH7110 Camera Subsystem
-which is used for handing image sensor data.
-
-Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Signed-off-by: Jack Zhu <jack.zhu@starfivetech.com>
----
- .../bindings/media/starfive,jh7110-camss.yaml | 179 ++++++++++++++++++
- 1 file changed, 179 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/media/starfive,jh7110-camss.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/media/starfive,jh7110-camss.yaml
-@@ -0,0 +1,179 @@
-+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/media/starfive,jh7110-camss.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: Starfive SoC CAMSS ISP
-+
-+maintainers:
-+ - Jack Zhu <jack.zhu@starfivetech.com>
-+ - Changhuang Liang <changhuang.liang@starfivetech.com>
-+
-+description:
-+ The Starfive CAMSS ISP is a Camera interface for Starfive JH7110 SoC. It
-+ consists of a VIN controller (Video In Controller, a top-level control until)
-+ and an ISP.
-+
-+properties:
-+ compatible:
-+ const: starfive,jh7110-camss
-+
-+ reg:
-+ maxItems: 2
-+
-+ reg-names:
-+ items:
-+ - const: syscon
-+ - const: isp
-+
-+ clocks:
-+ maxItems: 7
-+
-+ clock-names:
-+ items:
-+ - const: apb_func
-+ - const: wrapper_clk_c
-+ - const: dvp_inv
-+ - const: axiwr
-+ - const: mipi_rx0_pxl
-+ - const: ispcore_2x
-+ - const: isp_axi
-+
-+ resets:
-+ maxItems: 6
-+
-+ reset-names:
-+ items:
-+ - const: wrapper_p
-+ - const: wrapper_c
-+ - const: axird
-+ - const: axiwr
-+ - const: isp_top_n
-+ - const: isp_top_axi
-+
-+ power-domains:
-+ items:
-+ - description: JH7110 ISP Power Domain Switch Controller.
-+
-+ interrupts:
-+ maxItems: 4
-+
-+ ports:
-+ $ref: /schemas/graph.yaml#/properties/ports
-+
-+ properties:
-+ port@0:
-+ $ref: /schemas/graph.yaml#/$defs/port-base
-+ unevaluatedProperties: false
-+ description: Input port for receiving DVP data.
-+
-+ properties:
-+ endpoint:
-+ $ref: video-interfaces.yaml#
-+ unevaluatedProperties: false
-+
-+ properties:
-+ bus-type:
-+ enum: [5, 6]
-+
-+ bus-width:
-+ enum: [8, 10, 12]
-+
-+ data-shift:
-+ enum: [0, 2]
-+ default: 0
-+
-+ hsync-active:
-+ enum: [0, 1]
-+ default: 1
-+
-+ vsync-active:
-+ enum: [0, 1]
-+ default: 1
-+
-+ required:
-+ - bus-type
-+ - bus-width
-+
-+ port@1:
-+ $ref: /schemas/graph.yaml#/properties/port
-+ description: Input port for receiving CSI data.
-+
-+ required:
-+ - port@0
-+ - port@1
-+
-+required:
-+ - compatible
-+ - reg
-+ - reg-names
-+ - clocks
-+ - clock-names
-+ - resets
-+ - reset-names
-+ - power-domains
-+ - interrupts
-+ - ports
-+
-+additionalProperties: false
-+
-+examples:
-+ - |
-+ isp@19840000 {
-+ compatible = "starfive,jh7110-camss";
-+ reg = <0x19840000 0x10000>,
-+ <0x19870000 0x30000>;
-+ reg-names = "syscon", "isp";
-+ clocks = <&ispcrg 0>,
-+ <&ispcrg 13>,
-+ <&ispcrg 2>,
-+ <&ispcrg 12>,
-+ <&ispcrg 1>,
-+ <&syscrg 51>,
-+ <&syscrg 52>;
-+ clock-names = "apb_func",
-+ "wrapper_clk_c",
-+ "dvp_inv",
-+ "axiwr",
-+ "mipi_rx0_pxl",
-+ "ispcore_2x",
-+ "isp_axi";
-+ resets = <&ispcrg 0>,
-+ <&ispcrg 1>,
-+ <&ispcrg 10>,
-+ <&ispcrg 11>,
-+ <&syscrg 41>,
-+ <&syscrg 42>;
-+ reset-names = "wrapper_p",
-+ "wrapper_c",
-+ "axird",
-+ "axiwr",
-+ "isp_top_n",
-+ "isp_top_axi";
-+ power-domains = <&pwrc 5>;
-+ interrupts = <92>, <87>, <88>, <90>;
-+
-+ ports {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ port@0 {
-+ reg = <0>;
-+ vin_from_sc2235: endpoint {
-+ remote-endpoint = <&sc2235_to_vin>;
-+ bus-width = <8>;
-+ data-shift = <2>;
-+ hsync-active = <1>;
-+ vsync-active = <0>;
-+ pclk-sample = <1>;
-+ };
-+ };
-+
-+ port@1 {
-+ reg = <1>;
-+ vin_from_csi2rx: endpoint {
-+ remote-endpoint = <&csi2rx_to_vin>;
-+ };
-+ };
-+ };
-+ };
diff --git a/target/linux/starfive/patches-6.1/0082-media-admin-guide-Add-starfive_camss.rst-for-Starfiv.patch b/target/linux/starfive/patches-6.1/0082-media-admin-guide-Add-starfive_camss.rst-for-Starfiv.patch
deleted file mode 100644
index 7d59112e8e..0000000000
--- a/target/linux/starfive/patches-6.1/0082-media-admin-guide-Add-starfive_camss.rst-for-Starfiv.patch
+++ /dev/null
@@ -1,106 +0,0 @@
-From 949807343300a75b6e7c3e47463f817a7b6bc790 Mon Sep 17 00:00:00 2001
-From: Jack Zhu <jack.zhu@starfivetech.com>
-Date: Fri, 12 May 2023 18:28:40 +0800
-Subject: [PATCH 082/122] media: admin-guide: Add starfive_camss.rst for
- Starfive Camera Subsystem
-
-Add starfive_camss.rst file that documents the Starfive Camera
-Subsystem driver which is used for handing image sensor data.
-
-Signed-off-by: Jack Zhu <jack.zhu@starfivetech.com>
----
- .../admin-guide/media/starfive_camss.rst | 57 +++++++++++++++++++
- .../media/starfive_camss_graph.dot | 16 ++++++
- .../admin-guide/media/v4l-drivers.rst | 1 +
- 3 files changed, 74 insertions(+)
- create mode 100644 Documentation/admin-guide/media/starfive_camss.rst
- create mode 100644 Documentation/admin-guide/media/starfive_camss_graph.dot
-
---- /dev/null
-+++ b/Documentation/admin-guide/media/starfive_camss.rst
-@@ -0,0 +1,57 @@
-+.. SPDX-License-Identifier: GPL-2.0
-+
-+.. include:: <isonum.txt>
-+
-+================================
-+Starfive Camera Subsystem driver
-+================================
-+
-+Introduction
-+------------
-+
-+This file documents the driver for the Starfive Camera Subsystem found on
-+Starfive JH7110 SoC. The driver is located under drivers/media/platform/
-+starfive.
-+
-+The driver implements V4L2, Media controller and v4l2_subdev interfaces.
-+Camera sensor using V4L2 subdev interface in the kernel is supported.
-+
-+The driver has been successfully used on the Gstreamer 1.18.5 with
-+v4l2src plugin.
-+
-+
-+Starfive Camera Subsystem hardware
-+----------------------------------
-+
-+The Starfive Camera Subsystem hardware consists of:
-+
-+- MIPI DPHY Receiver: receives mipi data from a MIPI camera sensor.
-+- MIPI CSIRx Controller: is responsible for handling and decoding CSI2 protocol
-+ based camera sensor data stream.
-+- ISP: handles the image data streams from the MIPI CSIRx Controller.
-+- VIN(Video In): a top-level module, is responsible for controlling power
-+ and clocks to other modules, dumps the input data to memory or transfers the
-+ input data to ISP.
-+
-+
-+Topology
-+--------
-+
-+The media controller pipeline graph is as follows:
-+
-+.. _starfive_camss_graph:
-+
-+.. kernel-figure:: starfive_camss_graph.dot
-+ :alt: starfive_camss_graph.dot
-+ :align: center
-+
-+The driver has 2 video devices:
-+
-+- stf_vin0_wr_video0: capture device for images directly from the VIN module.
-+- stf_vin0_isp0_video1: capture device for images without scaling.
-+
-+The driver has 3 subdevices:
-+
-+- stf_isp0: is responsible for all the isp operations.
-+- stf_vin0_wr: used to dump RAW images to memory.
-+- stf_vin0_isp0: used to capture images for the stf_vin0_isp0_video1 device.
---- /dev/null
-+++ b/Documentation/admin-guide/media/starfive_camss_graph.dot
-@@ -0,0 +1,16 @@
-+digraph board {
-+ rankdir=TB
-+ n00000001 [label="{{<port0> 0} | stf_isp0\n/dev/v4l-subdev0 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
-+ n00000001:port1 -> n0000000d:port0
-+ n00000004 [label="{{<port0> 0} | stf_vin0_wr\n/dev/v4l-subdev1 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
-+ n00000004:port1 -> n00000007 [style=bold]
-+ n00000007 [label="stf_vin0_wr_video0\n/dev/video0", shape=box, style=filled, fillcolor=yellow]
-+ n0000000d [label="{{<port0> 0} | stf_vin0_isp0\n/dev/v4l-subdev2 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
-+ n0000000d:port1 -> n00000010 [style=bold]
-+ n00000010 [label="stf_vin0_isp0_video1\n/dev/video1", shape=box, style=filled, fillcolor=yellow]
-+ n00000018 [label="{{<port0> 0} | cdns_csi2rx.19800000.csi-bridge\n | {<port1> 1 | <port2> 2 | <port3> 3 | <port4> 4}}", shape=Mrecord, style=filled, fillcolor=green]
-+ n00000018:port1 -> n00000004:port0 [style=dashed]
-+ n00000018:port1 -> n00000001:port0
-+ n00000028 [label="{{} | imx219 6-0010\n | {<port0> 0}}", shape=Mrecord, style=filled, fillcolor=green]
-+ n00000028:port0 -> n00000018:port0 [style=bold]
-+}
---- a/Documentation/admin-guide/media/v4l-drivers.rst
-+++ b/Documentation/admin-guide/media/v4l-drivers.rst
-@@ -30,5 +30,6 @@ Video4Linux (V4L) driver-specific docume
- si470x
- si4713
- si476x
-+ starfive_camss
- vimc
- vivid
diff --git a/target/linux/starfive/patches-6.1/0083-media-starfive-Add-basic-driver.patch b/target/linux/starfive/patches-6.1/0083-media-starfive-Add-basic-driver.patch
deleted file mode 100644
index bc5141cfbc..0000000000
--- a/target/linux/starfive/patches-6.1/0083-media-starfive-Add-basic-driver.patch
+++ /dev/null
@@ -1,630 +0,0 @@
-From 0dc93c9321ba947ac429baeb58202496e4b0f219 Mon Sep 17 00:00:00 2001
-From: Jack Zhu <jack.zhu@starfivetech.com>
-Date: Fri, 12 May 2023 18:28:41 +0800
-Subject: [PATCH 083/122] media: starfive: Add basic driver
-
-Add basic platform driver for StarFive Camera Subsystem.
-
-Signed-off-by: Jack Zhu <jack.zhu@starfivetech.com>
-Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
----
- drivers/media/platform/Kconfig | 1 +
- drivers/media/platform/Makefile | 1 +
- drivers/media/platform/starfive/Kconfig | 19 +
- drivers/media/platform/starfive/Makefile | 9 +
- drivers/media/platform/starfive/stf_camss.c | 372 +++++++++++++++++++
- drivers/media/platform/starfive/stf_camss.h | 153 ++++++++
- drivers/media/platform/starfive/stf_common.h | 18 +
- 7 files changed, 573 insertions(+)
- create mode 100644 drivers/media/platform/starfive/Kconfig
- create mode 100644 drivers/media/platform/starfive/Makefile
- create mode 100644 drivers/media/platform/starfive/stf_camss.c
- create mode 100644 drivers/media/platform/starfive/stf_camss.h
- create mode 100644 drivers/media/platform/starfive/stf_common.h
-
---- a/drivers/media/platform/Kconfig
-+++ b/drivers/media/platform/Kconfig
-@@ -79,6 +79,7 @@ source "drivers/media/platform/renesas/K
- source "drivers/media/platform/rockchip/Kconfig"
- source "drivers/media/platform/samsung/Kconfig"
- source "drivers/media/platform/st/Kconfig"
-+source "drivers/media/platform/starfive/Kconfig"
- source "drivers/media/platform/sunxi/Kconfig"
- source "drivers/media/platform/ti/Kconfig"
- source "drivers/media/platform/verisilicon/Kconfig"
---- a/drivers/media/platform/Makefile
-+++ b/drivers/media/platform/Makefile
-@@ -22,6 +22,7 @@ obj-y += renesas/
- obj-y += rockchip/
- obj-y += samsung/
- obj-y += st/
-+obj-y += starfive/
- obj-y += sunxi/
- obj-y += ti/
- obj-y += verisilicon/
---- /dev/null
-+++ b/drivers/media/platform/starfive/Kconfig
-@@ -0,0 +1,19 @@
-+# SPDX-License-Identifier: GPL-2.0-only
-+
-+comment "Starfive media platform drivers"
-+
-+config VIDEO_STARFIVE_CAMSS
-+ tristate "Starfive Camera Subsystem driver"
-+ depends on V4L_PLATFORM_DRIVERS
-+ depends on VIDEO_DEV && OF
-+ depends on DMA_CMA
-+ select MEDIA_CONTROLLER
-+ select VIDEO_V4L2_SUBDEV_API
-+ select VIDEOBUF2_DMA_CONTIG
-+ select V4L2_FWNODE
-+ help
-+ Enable this to support for the Starfive Camera subsystem
-+ found on Starfive JH7110 SoC.
-+
-+ To compile this driver as a module, choose M here: the
-+ module will be called stf-camss.
---- /dev/null
-+++ b/drivers/media/platform/starfive/Makefile
-@@ -0,0 +1,9 @@
-+# SPDX-License-Identifier: GPL-2.0
-+#
-+# Makefile for StarFive camera subsystem driver.
-+#
-+
-+starfive-camss-objs += \
-+ stf_camss.o
-+
-+obj-$(CONFIG_VIDEO_STARFIVE_CAMSS) += starfive-camss.o \
---- /dev/null
-+++ b/drivers/media/platform/starfive/stf_camss.c
-@@ -0,0 +1,372 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * stf_camss.c
-+ *
-+ * Starfive Camera Subsystem driver
-+ *
-+ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
-+ */
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/of_graph.h>
-+#include <linux/platform_device.h>
-+#include <linux/pm_runtime.h>
-+#include <linux/videodev2.h>
-+#include <media/media-device.h>
-+#include <media/v4l2-async.h>
-+#include <media/v4l2-fwnode.h>
-+#include <media/v4l2-mc.h>
-+
-+#include "stf_camss.h"
-+
-+static const char * const stfcamss_clocks[] = {
-+ "clk_apb_func",
-+ "clk_wrapper_clk_c",
-+ "clk_dvp_inv",
-+ "clk_axiwr",
-+ "clk_mipi_rx0_pxl",
-+ "clk_ispcore_2x",
-+ "clk_isp_axi",
-+};
-+
-+static const char * const stfcamss_resets[] = {
-+ "rst_wrapper_p",
-+ "rst_wrapper_c",
-+ "rst_axird",
-+ "rst_axiwr",
-+ "rst_isp_top_n",
-+ "rst_isp_top_axi",
-+};
-+
-+static int stfcamss_get_mem_res(struct platform_device *pdev,
-+ struct stfcamss *stfcamss)
-+{
-+ stfcamss->syscon_base =
-+ devm_platform_ioremap_resource_byname(pdev, "syscon");
-+ if (IS_ERR(stfcamss->syscon_base))
-+ return PTR_ERR(stfcamss->syscon_base);
-+
-+ stfcamss->isp_base =
-+ devm_platform_ioremap_resource_byname(pdev, "isp");
-+ if (IS_ERR(stfcamss->isp_base))
-+ return PTR_ERR(stfcamss->isp_base);
-+
-+ return 0;
-+}
-+
-+/*
-+ * stfcamss_of_parse_endpoint_node - Parse port endpoint node
-+ * @dev: Device
-+ * @node: Device node to be parsed
-+ * @csd: Parsed data from port endpoint node
-+ *
-+ * Return 0 on success or a negative error code on failure
-+ */
-+static int stfcamss_of_parse_endpoint_node(struct device *dev,
-+ struct device_node *node,
-+ struct stfcamss_async_subdev *csd)
-+{
-+ struct v4l2_fwnode_endpoint vep = { { 0 } };
-+
-+ v4l2_fwnode_endpoint_parse(of_fwnode_handle(node), &vep);
-+ dev_dbg(dev, "vep.base.port = 0x%x, id = 0x%x\n",
-+ vep.base.port, vep.base.id);
-+
-+ csd->port = vep.base.port;
-+
-+ return 0;
-+}
-+
-+/*
-+ * stfcamss_of_parse_ports - Parse ports node
-+ * @stfcamss: STFCAMSS device
-+ *
-+ * Return number of "port" nodes found in "ports" node
-+ */
-+static int stfcamss_of_parse_ports(struct stfcamss *stfcamss)
-+{
-+ struct device *dev = stfcamss->dev;
-+ struct device_node *node = NULL;
-+ struct device_node *remote = NULL;
-+ int ret, num_subdevs = 0;
-+
-+ for_each_endpoint_of_node(dev->of_node, node) {
-+ struct stfcamss_async_subdev *csd;
-+
-+ if (!of_device_is_available(node))
-+ continue;
-+
-+ remote = of_graph_get_remote_port_parent(node);
-+ if (!remote) {
-+ dev_err(dev, "Cannot get remote parent\n");
-+ ret = -EINVAL;
-+ goto err_cleanup;
-+ }
-+
-+ csd = v4l2_async_nf_add_fwnode(&stfcamss->notifier,
-+ of_fwnode_handle(remote),
-+ struct stfcamss_async_subdev);
-+ of_node_put(remote);
-+ if (IS_ERR(csd)) {
-+ ret = PTR_ERR(csd);
-+ goto err_cleanup;
-+ }
-+
-+ ret = stfcamss_of_parse_endpoint_node(dev, node, csd);
-+ if (ret < 0)
-+ goto err_cleanup;
-+
-+ num_subdevs++;
-+ }
-+
-+ return num_subdevs;
-+
-+err_cleanup:
-+ of_node_put(node);
-+ return ret;
-+}
-+
-+static int stfcamss_subdev_notifier_bound(struct v4l2_async_notifier *async,
-+ struct v4l2_subdev *subdev,
-+ struct v4l2_async_subdev *asd)
-+{
-+ struct stfcamss *stfcamss =
-+ container_of(async, struct stfcamss, notifier);
-+ struct host_data *host_data = &stfcamss->host_data;
-+ struct media_entity *source;
-+ int i, j;
-+
-+ source = &subdev->entity;
-+
-+ for (i = 0; i < source->num_pads; i++) {
-+ if (source->pads[i].flags & MEDIA_PAD_FL_SOURCE)
-+ break;
-+ }
-+
-+ if (i == source->num_pads) {
-+ dev_err(stfcamss->dev, "No source pad in external entity\n");
-+ return -EINVAL;
-+ }
-+
-+ for (j = 0; host_data->host_entity[j] && (j < HOST_ENTITY_MAX); j++) {
-+ struct media_entity *input;
-+ int ret;
-+
-+ input = host_data->host_entity[j];
-+
-+ ret = media_create_pad_link(
-+ source,
-+ i,
-+ input,
-+ STF_PAD_SINK,
-+ source->function == MEDIA_ENT_F_CAM_SENSOR ?
-+ MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED :
-+ 0);
-+ if (ret < 0) {
-+ dev_err(stfcamss->dev,
-+ "Failed to link %s->%s entities: %d\n",
-+ source->name, input->name, ret);
-+ return ret;
-+ }
-+ }
-+
-+ return 0;
-+}
-+
-+static int stfcamss_subdev_notifier_complete(struct v4l2_async_notifier *ntf)
-+{
-+ struct stfcamss *stfcamss =
-+ container_of(ntf, struct stfcamss, notifier);
-+
-+ return v4l2_device_register_subdev_nodes(&stfcamss->v4l2_dev);
-+}
-+
-+static const struct v4l2_async_notifier_operations
-+stfcamss_subdev_notifier_ops = {
-+ .bound = stfcamss_subdev_notifier_bound,
-+ .complete = stfcamss_subdev_notifier_complete,
-+};
-+
-+static const struct media_device_ops stfcamss_media_ops = {
-+ .link_notify = v4l2_pipeline_link_notify,
-+};
-+
-+static void stfcamss_mc_init(struct platform_device *pdev,
-+ struct stfcamss *stfcamss)
-+{
-+ stfcamss->media_dev.dev = stfcamss->dev;
-+ strscpy(stfcamss->media_dev.model, "Starfive Camera Subsystem",
-+ sizeof(stfcamss->media_dev.model));
-+ snprintf(stfcamss->media_dev.bus_info,
-+ sizeof(stfcamss->media_dev.bus_info),
-+ "%s:%s", dev_bus_name(&pdev->dev), pdev->name);
-+ stfcamss->media_dev.hw_revision = 0x01;
-+ stfcamss->media_dev.ops = &stfcamss_media_ops;
-+ media_device_init(&stfcamss->media_dev);
-+
-+ stfcamss->v4l2_dev.mdev = &stfcamss->media_dev;
-+}
-+
-+/*
-+ * stfcamss_probe - Probe STFCAMSS platform device
-+ * @pdev: Pointer to STFCAMSS platform device
-+ *
-+ * Return 0 on success or a negative error code on failure
-+ */
-+static int stfcamss_probe(struct platform_device *pdev)
-+{
-+ struct stfcamss *stfcamss;
-+ struct device *dev = &pdev->dev;
-+ int ret = 0, i, num_subdevs;
-+
-+ stfcamss = devm_kzalloc(dev, sizeof(*stfcamss), GFP_KERNEL);
-+ if (!stfcamss)
-+ return -ENOMEM;
-+
-+ for (i = 0; i < ARRAY_SIZE(stfcamss->irq); ++i) {
-+ stfcamss->irq[i] = platform_get_irq(pdev, i);
-+ if (stfcamss->irq[i] < 0)
-+ return dev_err_probe(&pdev->dev, stfcamss->irq[i],
-+ "Failed to get clock%d", i);
-+ }
-+
-+ stfcamss->nclks = ARRAY_SIZE(stfcamss->sys_clk);
-+ for (i = 0; i < ARRAY_SIZE(stfcamss->sys_clk); ++i)
-+ stfcamss->sys_clk[i].id = stfcamss_clocks[i];
-+ ret = devm_clk_bulk_get(dev, stfcamss->nclks, stfcamss->sys_clk);
-+ if (ret) {
-+ dev_err(dev, "Failed to get clk controls\n");
-+ return ret;
-+ }
-+
-+ stfcamss->nrsts = ARRAY_SIZE(stfcamss->sys_rst);
-+ for (i = 0; i < ARRAY_SIZE(stfcamss->sys_rst); ++i)
-+ stfcamss->sys_rst[i].id = stfcamss_resets[i];
-+ ret = devm_reset_control_bulk_get_shared(dev, stfcamss->nrsts,
-+ stfcamss->sys_rst);
-+ if (ret) {
-+ dev_err(dev, "Failed to get reset controls\n");
-+ return ret;
-+ }
-+
-+ ret = stfcamss_get_mem_res(pdev, stfcamss);
-+ if (ret) {
-+ dev_err(dev, "Could not map registers\n");
-+ return ret;
-+ }
-+
-+ stfcamss->dev = dev;
-+ platform_set_drvdata(pdev, stfcamss);
-+
-+ v4l2_async_nf_init(&stfcamss->notifier);
-+
-+ num_subdevs = stfcamss_of_parse_ports(stfcamss);
-+ if (num_subdevs < 0) {
-+ dev_err(dev, "Failed to find subdevices\n");
-+ return -ENODEV;
-+ }
-+
-+ stfcamss_mc_init(pdev, stfcamss);
-+
-+ ret = v4l2_device_register(stfcamss->dev, &stfcamss->v4l2_dev);
-+ if (ret < 0) {
-+ dev_err(dev, "Failed to register V4L2 device: %d\n", ret);
-+ goto err_cleanup_notifier;
-+ }
-+
-+ ret = media_device_register(&stfcamss->media_dev);
-+ if (ret) {
-+ dev_err(dev, "Failed to register media device: %d\n", ret);
-+ goto err_unregister_device;
-+ }
-+
-+ stfcamss->notifier.ops = &stfcamss_subdev_notifier_ops;
-+ ret = v4l2_async_nf_register(&stfcamss->v4l2_dev, &stfcamss->notifier);
-+ if (ret) {
-+ dev_err(dev, "Failed to register async subdev nodes: %d\n",
-+ ret);
-+ goto err_unregister_media_dev;
-+ }
-+
-+ pm_runtime_enable(dev);
-+
-+ return 0;
-+
-+err_unregister_media_dev:
-+ media_device_unregister(&stfcamss->media_dev);
-+err_unregister_device:
-+ v4l2_device_unregister(&stfcamss->v4l2_dev);
-+err_cleanup_notifier:
-+ v4l2_async_nf_cleanup(&stfcamss->notifier);
-+ return ret;
-+}
-+
-+/*
-+ * stfcamss_remove - Remove STFCAMSS platform device
-+ * @pdev: Pointer to STFCAMSS platform device
-+ *
-+ * Always returns 0.
-+ */
-+static int stfcamss_remove(struct platform_device *pdev)
-+{
-+ struct stfcamss *stfcamss = platform_get_drvdata(pdev);
-+
-+ v4l2_device_unregister(&stfcamss->v4l2_dev);
-+ media_device_cleanup(&stfcamss->media_dev);
-+ pm_runtime_disable(&pdev->dev);
-+
-+ return 0;
-+}
-+
-+static const struct of_device_id stfcamss_of_match[] = {
-+ { .compatible = "starfive,jh7110-camss" },
-+ { /* sentinel */ },
-+};
-+
-+MODULE_DEVICE_TABLE(of, stfcamss_of_match);
-+
-+static int __maybe_unused stfcamss_runtime_suspend(struct device *dev)
-+{
-+ struct stfcamss *stfcamss = dev_get_drvdata(dev);
-+
-+ reset_control_assert(stfcamss->sys_rst[STF_RST_ISP_TOP_AXI].rstc);
-+ reset_control_assert(stfcamss->sys_rst[STF_RST_ISP_TOP_N].rstc);
-+ clk_disable_unprepare(stfcamss->sys_clk[STF_CLK_ISP_AXI].clk);
-+ clk_disable_unprepare(stfcamss->sys_clk[STF_CLK_ISPCORE_2X].clk);
-+
-+ return 0;
-+}
-+
-+static int __maybe_unused stfcamss_runtime_resume(struct device *dev)
-+{
-+ struct stfcamss *stfcamss = dev_get_drvdata(dev);
-+
-+ clk_prepare_enable(stfcamss->sys_clk[STF_CLK_ISPCORE_2X].clk);
-+ clk_prepare_enable(stfcamss->sys_clk[STF_CLK_ISP_AXI].clk);
-+ reset_control_deassert(stfcamss->sys_rst[STF_RST_ISP_TOP_N].rstc);
-+ reset_control_deassert(stfcamss->sys_rst[STF_RST_ISP_TOP_AXI].rstc);
-+
-+ return 0;
-+}
-+
-+static const struct dev_pm_ops stfcamss_pm_ops = {
-+ SET_RUNTIME_PM_OPS(stfcamss_runtime_suspend,
-+ stfcamss_runtime_resume,
-+ NULL)
-+};
-+
-+static struct platform_driver stfcamss_driver = {
-+ .probe = stfcamss_probe,
-+ .remove = stfcamss_remove,
-+ .driver = {
-+ .name = DRV_NAME,
-+ .pm = &stfcamss_pm_ops,
-+ .of_match_table = of_match_ptr(stfcamss_of_match),
-+ },
-+};
-+
-+module_platform_driver(stfcamss_driver);
-+
-+MODULE_AUTHOR("StarFive Corporation");
-+MODULE_DESCRIPTION("StarFive Camera Subsystem driver");
-+MODULE_LICENSE("GPL");
---- /dev/null
-+++ b/drivers/media/platform/starfive/stf_camss.h
-@@ -0,0 +1,153 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+/*
-+ * stf_camss.h
-+ *
-+ * Starfive Camera Subsystem driver
-+ *
-+ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
-+ */
-+
-+#ifndef STF_CAMSS_H
-+#define STF_CAMSS_H
-+
-+#include <linux/clk.h>
-+#include <linux/delay.h>
-+#include <linux/reset.h>
-+#include <media/v4l2-device.h>
-+
-+#include "stf_common.h"
-+
-+#define DRV_NAME "starfive-camss"
-+#define STF_DVP_NAME "stf_dvp"
-+#define STF_CSI_NAME "cdns_csi2rx"
-+#define STF_ISP_NAME "stf_isp"
-+#define STF_VIN_NAME "stf_vin"
-+
-+#define STF_PAD_SINK 0
-+#define STF_PAD_SRC 1
-+#define STF_PADS_NUM 2
-+
-+enum port_num {
-+ PORT_NUMBER_DVP_SENSOR = 0,
-+ PORT_NUMBER_CSI2RX
-+};
-+
-+enum stf_clk {
-+ STF_CLK_APB_FUNC = 0,
-+ STF_CLK_WRAPPER_CLK_C,
-+ STF_CLK_DVP_INV,
-+ STF_CLK_AXIWR,
-+ STF_CLK_MIPI_RX0_PXL,
-+ STF_CLK_ISPCORE_2X,
-+ STF_CLK_ISP_AXI,
-+ STF_CLK_NUM
-+};
-+
-+enum stf_rst {
-+ STF_RST_WRAPPER_P = 0,
-+ STF_RST_WRAPPER_C,
-+ STF_RST_AXIRD,
-+ STF_RST_AXIWR,
-+ STF_RST_ISP_TOP_N,
-+ STF_RST_ISP_TOP_AXI,
-+ STF_RST_NUM
-+};
-+
-+enum stf_irq {
-+ STF_IRQ_VINWR = 0,
-+ STF_IRQ_ISP,
-+ STF_IRQ_ISPCSIL,
-+ STF_IRQ_NUM
-+};
-+
-+#define HOST_ENTITY_MAX 2
-+
-+struct host_data {
-+ struct media_entity *host_entity[HOST_ENTITY_MAX];
-+};
-+
-+struct stfcamss {
-+ struct v4l2_device v4l2_dev;
-+ struct media_device media_dev;
-+ struct media_pipeline pipe;
-+ struct device *dev;
-+ struct v4l2_async_notifier notifier;
-+ struct host_data host_data;
-+ void __iomem *syscon_base;
-+ void __iomem *isp_base;
-+ int irq[STF_IRQ_NUM];
-+ struct clk_bulk_data sys_clk[STF_CLK_NUM];
-+ int nclks;
-+ struct reset_control_bulk_data sys_rst[STF_RST_NUM];
-+ int nrsts;
-+};
-+
-+struct stfcamss_async_subdev {
-+ struct v4l2_async_subdev asd; /* must be first */
-+ enum port_num port;
-+};
-+
-+static inline u32 stf_isp_reg_read(struct stfcamss *stfcamss, u32 reg)
-+{
-+ return ioread32(stfcamss->isp_base + reg);
-+}
-+
-+static inline void stf_isp_reg_write(struct stfcamss *stfcamss,
-+ u32 reg, u32 val)
-+{
-+ iowrite32(val, stfcamss->isp_base + reg);
-+}
-+
-+static inline void stf_isp_reg_write_delay(struct stfcamss *stfcamss,
-+ u32 reg, u32 val, u32 delay)
-+{
-+ iowrite32(val, stfcamss->isp_base + reg);
-+ usleep_range(1000 * delay, 1000 * delay + 100);
-+}
-+
-+static inline void stf_isp_reg_set_bit(struct stfcamss *stfcamss,
-+ u32 reg, u32 mask, u32 val)
-+{
-+ u32 value;
-+
-+ value = ioread32(stfcamss->isp_base + reg) & ~mask;
-+ val &= mask;
-+ val |= value;
-+ iowrite32(val, stfcamss->isp_base + reg);
-+}
-+
-+static inline void stf_isp_reg_set(struct stfcamss *stfcamss, u32 reg, u32 mask)
-+{
-+ iowrite32(ioread32(stfcamss->isp_base + reg) | mask,
-+ stfcamss->isp_base + reg);
-+}
-+
-+static inline u32 stf_syscon_reg_read(struct stfcamss *stfcamss, u32 reg)
-+{
-+ return ioread32(stfcamss->syscon_base + reg);
-+}
-+
-+static inline void stf_syscon_reg_write(struct stfcamss *stfcamss,
-+ u32 reg, u32 val)
-+{
-+ iowrite32(val, stfcamss->syscon_base + reg);
-+}
-+
-+static inline void stf_syscon_reg_set_bit(struct stfcamss *stfcamss,
-+ u32 reg, u32 bit_mask)
-+{
-+ u32 value;
-+
-+ value = ioread32(stfcamss->syscon_base + reg);
-+ iowrite32(value | bit_mask, stfcamss->syscon_base + reg);
-+}
-+
-+static inline void stf_syscon_reg_clear_bit(struct stfcamss *stfcamss,
-+ u32 reg, u32 bit_mask)
-+{
-+ u32 value;
-+
-+ value = ioread32(stfcamss->syscon_base + reg);
-+ iowrite32(value & ~bit_mask, stfcamss->syscon_base + reg);
-+}
-+#endif /* STF_CAMSS_H */
---- /dev/null
-+++ b/drivers/media/platform/starfive/stf_common.h
-@@ -0,0 +1,18 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+/*
-+ * stf_common.h
-+ *
-+ * StarFive Camera Subsystem - Common definitions
-+ *
-+ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
-+ */
-+
-+#ifndef STF_COMMON_H
-+#define STF_COMMON_H
-+
-+enum stf_subdev_type {
-+ STF_SUBDEV_TYPE_VIN,
-+ STF_SUBDEV_TYPE_ISP,
-+};
-+
-+#endif /* STF_COMMON_H */
diff --git a/target/linux/starfive/patches-6.1/0084-media-starfive-Add-video-driver.patch b/target/linux/starfive/patches-6.1/0084-media-starfive-Add-video-driver.patch
deleted file mode 100644
index f9317485a2..0000000000
--- a/target/linux/starfive/patches-6.1/0084-media-starfive-Add-video-driver.patch
+++ /dev/null
@@ -1,992 +0,0 @@
-From 70a588f7daefe34697ccd04fa6ac3a6d4b63be88 Mon Sep 17 00:00:00 2001
-From: Jack Zhu <jack.zhu@starfivetech.com>
-Date: Fri, 12 May 2023 18:28:42 +0800
-Subject: [PATCH 084/122] media: starfive: Add video driver
-
-Add video driver for StarFive Camera Subsystem.
-
-Signed-off-by: Jack Zhu <jack.zhu@starfivetech.com>
----
- drivers/media/platform/starfive/Makefile | 3 +-
- drivers/media/platform/starfive/stf_video.c | 864 ++++++++++++++++++++
- drivers/media/platform/starfive/stf_video.h | 95 +++
- 3 files changed, 961 insertions(+), 1 deletion(-)
- create mode 100644 drivers/media/platform/starfive/stf_video.c
- create mode 100644 drivers/media/platform/starfive/stf_video.h
-
---- a/drivers/media/platform/starfive/Makefile
-+++ b/drivers/media/platform/starfive/Makefile
-@@ -4,6 +4,7 @@
- #
-
- starfive-camss-objs += \
-- stf_camss.o
-+ stf_camss.o \
-+ stf_video.o
-
- obj-$(CONFIG_VIDEO_STARFIVE_CAMSS) += starfive-camss.o \
---- /dev/null
-+++ b/drivers/media/platform/starfive/stf_video.c
-@@ -0,0 +1,864 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * stf_video.c
-+ *
-+ * StarFive Camera Subsystem - V4L2 device node
-+ *
-+ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
-+ */
-+
-+#include <media/media-entity.h>
-+#include <media/v4l2-ctrls.h>
-+#include <media/v4l2-event.h>
-+#include <media/v4l2-mc.h>
-+#include <media/videobuf2-dma-contig.h>
-+
-+#include "stf_camss.h"
-+#include "stf_video.h"
-+
-+static const struct stfcamss_format_info formats_pix_wr[] = {
-+ { MEDIA_BUS_FMT_SRGGB10_1X10, V4L2_PIX_FMT_SRGGB10, 1,
-+ { { 1, 1 } }, { { 1, 1 } }, { 10 } },
-+ { MEDIA_BUS_FMT_SGRBG10_1X10, V4L2_PIX_FMT_SGRBG10, 1,
-+ { { 1, 1 } }, { { 1, 1 } }, { 10 } },
-+ { MEDIA_BUS_FMT_SGBRG10_1X10, V4L2_PIX_FMT_SGBRG10, 1,
-+ { { 1, 1 } }, { { 1, 1 } }, { 10 } },
-+ { MEDIA_BUS_FMT_SBGGR10_1X10, V4L2_PIX_FMT_SBGGR10, 1,
-+ { { 1, 1 } }, { { 1, 1 } }, { 10 } },
-+};
-+
-+static const struct stfcamss_format_info formats_pix_isp[] = {
-+ { MEDIA_BUS_FMT_Y12_1X12, V4L2_PIX_FMT_NV12, 1,
-+ { { 1, 1 } }, { { 2, 3 } }, { 8 } },
-+};
-+
-+/* -----------------------------------------------------------------------------
-+ * Helper functions
-+ */
-+
-+static int video_find_format(u32 code, u32 pixelformat,
-+ const struct stfcamss_format_info *formats,
-+ unsigned int nformats)
-+{
-+ int i;
-+
-+ for (i = 0; i < nformats; i++) {
-+ if (formats[i].code == code &&
-+ formats[i].pixelformat == pixelformat)
-+ return i;
-+ }
-+
-+ for (i = 0; i < nformats; i++)
-+ if (formats[i].code == code)
-+ return i;
-+
-+ for (i = 0; i < nformats; i++)
-+ if (formats[i].pixelformat == pixelformat)
-+ return i;
-+
-+ return -EINVAL;
-+}
-+
-+static int __video_try_fmt(struct stfcamss_video *video, struct v4l2_format *f)
-+{
-+ struct v4l2_pix_format *pix;
-+ const struct stfcamss_format_info *fi;
-+ u32 width, height;
-+ u32 bpl;
-+ int i;
-+
-+ pix = &f->fmt.pix;
-+
-+ for (i = 0; i < video->nformats; i++)
-+ if (pix->pixelformat == video->formats[i].pixelformat)
-+ break;
-+
-+ if (i == video->nformats)
-+ i = 0; /* default format */
-+
-+ fi = &video->formats[i];
-+ width = pix->width;
-+ height = pix->height;
-+
-+ memset(pix, 0, sizeof(*pix));
-+
-+ pix->pixelformat = fi->pixelformat;
-+ pix->width = clamp_t(u32, width, STFCAMSS_FRAME_MIN_WIDTH,
-+ STFCAMSS_FRAME_MAX_WIDTH);
-+ pix->height = clamp_t(u32, height, STFCAMSS_FRAME_MIN_HEIGHT,
-+ STFCAMSS_FRAME_MAX_HEIGHT);
-+ bpl = pix->width / fi->hsub[0].numerator *
-+ fi->hsub[0].denominator * fi->bpp[0] / 8;
-+ bpl = ALIGN(bpl, video->bpl_alignment);
-+ pix->bytesperline = bpl;
-+ pix->sizeimage = pix->height / fi->vsub[0].numerator *
-+ fi->vsub[0].denominator * bpl;
-+
-+ pix->field = V4L2_FIELD_NONE;
-+ pix->colorspace = V4L2_COLORSPACE_SRGB;
-+ pix->flags = 0;
-+ pix->ycbcr_enc =
-+ V4L2_MAP_YCBCR_ENC_DEFAULT(pix->colorspace);
-+ pix->quantization = V4L2_MAP_QUANTIZATION_DEFAULT(true,
-+ pix->colorspace,
-+ pix->ycbcr_enc);
-+ pix->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(pix->colorspace);
-+
-+ return 0;
-+}
-+
-+static int stf_video_init_format(struct stfcamss_video *video)
-+{
-+ int ret;
-+ struct v4l2_format format = {
-+ .type = video->type,
-+ .fmt.pix = {
-+ .width = 1920,
-+ .height = 1080,
-+ .pixelformat = V4L2_PIX_FMT_RGB565,
-+ },
-+ };
-+
-+ ret = __video_try_fmt(video, &format);
-+
-+ if (ret < 0)
-+ return ret;
-+
-+ video->active_fmt = format;
-+
-+ return 0;
-+}
-+
-+/* -----------------------------------------------------------------------------
-+ * Video queue operations
-+ */
-+
-+static int video_queue_setup(struct vb2_queue *q,
-+ unsigned int *num_buffers,
-+ unsigned int *num_planes,
-+ unsigned int sizes[],
-+ struct device *alloc_devs[])
-+{
-+ struct stfcamss_video *video = vb2_get_drv_priv(q);
-+ const struct v4l2_pix_format *format = &video->active_fmt.fmt.pix;
-+
-+ if (*num_planes) {
-+ if (*num_planes != 1)
-+ return -EINVAL;
-+
-+ if (sizes[0] < format->sizeimage)
-+ return -EINVAL;
-+ }
-+
-+ *num_planes = 1;
-+ sizes[0] = format->sizeimage;
-+ if (!sizes[0])
-+ dev_err(video->stfcamss->dev,
-+ "%s: error size is zero!!!\n", __func__);
-+
-+ dev_dbg(video->stfcamss->dev, "planes = %d, size = %d\n",
-+ *num_planes, sizes[0]);
-+
-+ return 0;
-+}
-+
-+static int video_buf_init(struct vb2_buffer *vb)
-+{
-+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
-+ struct stfcamss_video *video = vb2_get_drv_priv(vb->vb2_queue);
-+ struct stfcamss_buffer *buffer =
-+ container_of(vbuf, struct stfcamss_buffer, vb);
-+ const struct v4l2_pix_format *fmt = &video->active_fmt.fmt.pix;
-+ dma_addr_t *paddr;
-+
-+ buffer->sizeimage = 0;
-+
-+ paddr = vb2_plane_cookie(vb, 0);
-+ buffer->sizeimage = vb2_plane_size(vb, 0);
-+ buffer->addr[0] = *paddr;
-+ if (fmt->pixelformat == V4L2_PIX_FMT_NV12 ||
-+ fmt->pixelformat == V4L2_PIX_FMT_NV21 ||
-+ fmt->pixelformat == V4L2_PIX_FMT_NV16 ||
-+ fmt->pixelformat == V4L2_PIX_FMT_NV61)
-+ buffer->addr[1] =
-+ buffer->addr[0] + fmt->bytesperline * fmt->height;
-+
-+ return 0;
-+}
-+
-+static int video_buf_prepare(struct vb2_buffer *vb)
-+{
-+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
-+ struct stfcamss_video *video = vb2_get_drv_priv(vb->vb2_queue);
-+ const struct v4l2_pix_format *fmt = &video->active_fmt.fmt.pix;
-+
-+ if (fmt->sizeimage > vb2_plane_size(vb, 0)) {
-+ dev_err(video->stfcamss->dev,
-+ "sizeimage = %d, plane size = %d\n",
-+ fmt->sizeimage, (unsigned int)vb2_plane_size(vb, 0));
-+ return -EINVAL;
-+ }
-+ vb2_set_plane_payload(vb, 0, fmt->sizeimage);
-+
-+ vbuf->field = V4L2_FIELD_NONE;
-+
-+ return 0;
-+}
-+
-+static void video_buf_queue(struct vb2_buffer *vb)
-+{
-+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
-+ struct stfcamss_video *video = vb2_get_drv_priv(vb->vb2_queue);
-+ struct stfcamss_buffer *buffer =
-+ container_of(vbuf, struct stfcamss_buffer, vb);
-+
-+ video->ops->queue_buffer(video, buffer);
-+}
-+
-+/*
-+ * video_mbus_to_pix - Convert v4l2_mbus_framefmt to v4l2_pix_format
-+ * @mbus: v4l2_mbus_framefmt format (input)
-+ * @pix: v4l2_pix_format_mplane format (output)
-+ * @f: a pointer to formats array element to be used for the conversion
-+ * @alignment: bytesperline alignment value
-+ *
-+ * Fill the output pix structure with information from the input mbus format.
-+ *
-+ * Return 0 on success or a negative error code otherwise
-+ */
-+static int video_mbus_to_pix(const struct v4l2_mbus_framefmt *mbus,
-+ struct v4l2_pix_format *pix,
-+ const struct stfcamss_format_info *f,
-+ unsigned int alignment)
-+{
-+ u32 bytesperline;
-+
-+ memset(pix, 0, sizeof(*pix));
-+ v4l2_fill_pix_format(pix, mbus);
-+ pix->pixelformat = f->pixelformat;
-+ bytesperline = pix->width / f->hsub[0].numerator *
-+ f->hsub[0].denominator * f->bpp[0] / 8;
-+ bytesperline = ALIGN(bytesperline, alignment);
-+ pix->bytesperline = bytesperline;
-+ pix->sizeimage = pix->height / f->vsub[0].numerator *
-+ f->vsub[0].denominator * bytesperline;
-+ return 0;
-+}
-+
-+static struct v4l2_subdev *video_remote_subdev(struct stfcamss_video *video,
-+ u32 *pad)
-+{
-+ struct media_pad *remote;
-+
-+ remote = media_pad_remote_pad_first(&video->pad);
-+
-+ if (!remote || !is_media_entity_v4l2_subdev(remote->entity))
-+ return NULL;
-+
-+ if (pad)
-+ *pad = remote->index;
-+
-+ return media_entity_to_v4l2_subdev(remote->entity);
-+}
-+
-+static int video_get_subdev_format(struct stfcamss_video *video,
-+ struct v4l2_format *format)
-+{
-+ struct v4l2_pix_format *pix = &video->active_fmt.fmt.pix;
-+ struct v4l2_subdev_format fmt;
-+ struct v4l2_subdev *subdev;
-+ u32 pixelformat;
-+ u32 pad;
-+ int ret;
-+
-+ subdev = video_remote_subdev(video, &pad);
-+ if (!subdev)
-+ return -EPIPE;
-+
-+ fmt.pad = pad;
-+ fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
-+
-+ ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &fmt);
-+ if (ret)
-+ return ret;
-+
-+ pixelformat = pix->pixelformat;
-+ ret = video_find_format(fmt.format.code, pixelformat,
-+ video->formats, video->nformats);
-+ if (ret < 0)
-+ return ret;
-+
-+ format->type = video->type;
-+
-+ return video_mbus_to_pix(&fmt.format, &format->fmt.pix,
-+ &video->formats[ret], video->bpl_alignment);
-+}
-+
-+static int video_check_format(struct stfcamss_video *video)
-+{
-+ struct v4l2_pix_format *pix = &video->active_fmt.fmt.pix;
-+ struct v4l2_format format;
-+ struct v4l2_pix_format *sd_pix = &format.fmt.pix;
-+ int ret;
-+
-+ sd_pix->pixelformat = pix->pixelformat;
-+ ret = video_get_subdev_format(video, &format);
-+ if (ret < 0)
-+ return ret;
-+
-+ if (pix->pixelformat != sd_pix->pixelformat ||
-+ pix->height > sd_pix->height ||
-+ pix->width > sd_pix->width ||
-+ pix->field != format.fmt.pix.field) {
-+ dev_err(video->stfcamss->dev,
-+ "%s, not match:\n"
-+ "0x%x 0x%x\n0x%x 0x%x\n0x%x 0x%x\n",
-+ __func__,
-+ pix->pixelformat, sd_pix->pixelformat,
-+ pix->height, sd_pix->height,
-+ pix->field, format.fmt.pix.field);
-+ return -EPIPE;
-+ }
-+
-+ return 0;
-+}
-+
-+static int video_start_streaming(struct vb2_queue *q, unsigned int count)
-+{
-+ struct stfcamss_video *video = vb2_get_drv_priv(q);
-+ struct video_device *vdev = &video->vdev;
-+ struct media_entity *entity;
-+ struct media_pad *pad;
-+ struct v4l2_subdev *subdev;
-+ int ret;
-+
-+ ret = video_device_pipeline_start(vdev, &video->stfcamss->pipe);
-+ if (ret < 0) {
-+ dev_err(video->stfcamss->dev,
-+ "Failed to media_pipeline_start: %d\n", ret);
-+ return ret;
-+ }
-+
-+ ret = video_check_format(video);
-+ if (ret < 0)
-+ goto error;
-+ entity = &vdev->entity;
-+ while (1) {
-+ pad = &entity->pads[0];
-+ if (!(pad->flags & MEDIA_PAD_FL_SINK))
-+ break;
-+
-+ pad = media_pad_remote_pad_first(pad);
-+ if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
-+ break;
-+
-+ entity = pad->entity;
-+ subdev = media_entity_to_v4l2_subdev(entity);
-+
-+ ret = v4l2_subdev_call(subdev, video, s_stream, 1);
-+ if (ret < 0 && ret != -ENOIOCTLCMD)
-+ goto error;
-+ }
-+ return 0;
-+
-+error:
-+ video_device_pipeline_stop(vdev);
-+ video->ops->flush_buffers(video, VB2_BUF_STATE_QUEUED);
-+ return ret;
-+}
-+
-+static void video_stop_streaming(struct vb2_queue *q)
-+{
-+ struct stfcamss_video *video = vb2_get_drv_priv(q);
-+ struct video_device *vdev = &video->vdev;
-+ struct media_entity *entity;
-+ struct media_pad *pad;
-+ struct v4l2_subdev *subdev;
-+
-+ entity = &vdev->entity;
-+ while (1) {
-+ pad = &entity->pads[0];
-+ if (!(pad->flags & MEDIA_PAD_FL_SINK))
-+ break;
-+
-+ pad = media_pad_remote_pad_first(pad);
-+ if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
-+ break;
-+
-+ entity = pad->entity;
-+ subdev = media_entity_to_v4l2_subdev(entity);
-+
-+ v4l2_subdev_call(subdev, video, s_stream, 0);
-+ }
-+
-+ video_device_pipeline_stop(vdev);
-+ video->ops->flush_buffers(video, VB2_BUF_STATE_ERROR);
-+}
-+
-+static const struct vb2_ops stf_video_vb2_q_ops = {
-+ .queue_setup = video_queue_setup,
-+ .wait_prepare = vb2_ops_wait_prepare,
-+ .wait_finish = vb2_ops_wait_finish,
-+ .buf_init = video_buf_init,
-+ .buf_prepare = video_buf_prepare,
-+ .buf_queue = video_buf_queue,
-+ .start_streaming = video_start_streaming,
-+ .stop_streaming = video_stop_streaming,
-+};
-+
-+/* -----------------------------------------------------------------------------
-+ * V4L2 ioctls
-+ */
-+
-+static int video_querycap(struct file *file, void *fh,
-+ struct v4l2_capability *cap)
-+{
-+ struct stfcamss_video *video = video_drvdata(file);
-+
-+ strscpy(cap->driver, "stf camss", sizeof(cap->driver));
-+ strscpy(cap->card, "Starfive Camera Subsystem", sizeof(cap->card));
-+ snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
-+ dev_name(video->stfcamss->dev));
-+ return 0;
-+}
-+
-+static int video_get_pfmt_by_index(struct stfcamss_video *video, int ndx)
-+{
-+ int i, j, k;
-+
-+ /* find index "i" of "k"th unique pixelformat in formats array */
-+ k = -1;
-+ for (i = 0; i < video->nformats; i++) {
-+ for (j = 0; j < i; j++) {
-+ if (video->formats[i].pixelformat ==
-+ video->formats[j].pixelformat)
-+ break;
-+ }
-+
-+ if (j == i)
-+ k++;
-+
-+ if (k == ndx)
-+ return i;
-+ }
-+
-+ return -EINVAL;
-+}
-+
-+static int video_get_pfmt_by_mcode(struct stfcamss_video *video, u32 mcode)
-+{
-+ int i;
-+
-+ for (i = 0; i < video->nformats; i++) {
-+ if (video->formats[i].code == mcode)
-+ return i;
-+ }
-+
-+ return -EINVAL;
-+}
-+
-+static int video_enum_fmt(struct file *file, void *fh, struct v4l2_fmtdesc *f)
-+{
-+ struct stfcamss_video *video = video_drvdata(file);
-+ int i;
-+
-+ if (f->type != video->type)
-+ return -EINVAL;
-+ if (f->index >= video->nformats)
-+ return -EINVAL;
-+
-+ if (f->mbus_code) {
-+ /* Each entry in formats[] table has unique mbus_code */
-+ if (f->index > 0)
-+ return -EINVAL;
-+
-+ i = video_get_pfmt_by_mcode(video, f->mbus_code);
-+ } else {
-+ i = video_get_pfmt_by_index(video, f->index);
-+ }
-+
-+ if (i < 0)
-+ return -EINVAL;
-+
-+ f->pixelformat = video->formats[i].pixelformat;
-+
-+ return 0;
-+}
-+
-+static int video_enum_framesizes(struct file *file, void *fh,
-+ struct v4l2_frmsizeenum *fsize)
-+{
-+ struct stfcamss_video *video = video_drvdata(file);
-+ int i;
-+
-+ if (fsize->index)
-+ return -EINVAL;
-+
-+ for (i = 0; i < video->nformats; i++) {
-+ if (video->formats[i].pixelformat == fsize->pixel_format)
-+ break;
-+ }
-+
-+ if (i == video->nformats)
-+ return -EINVAL;
-+
-+ fsize->type = V4L2_FRMSIZE_TYPE_CONTINUOUS;
-+ fsize->stepwise.min_width = STFCAMSS_FRAME_MIN_WIDTH;
-+ fsize->stepwise.max_width = STFCAMSS_FRAME_MAX_WIDTH;
-+ fsize->stepwise.min_height = STFCAMSS_FRAME_MIN_HEIGHT;
-+ fsize->stepwise.max_height = STFCAMSS_FRAME_MAX_HEIGHT;
-+ fsize->stepwise.step_width = 1;
-+ fsize->stepwise.step_height = 1;
-+
-+ return 0;
-+}
-+
-+static int video_g_fmt(struct file *file, void *fh, struct v4l2_format *f)
-+{
-+ struct stfcamss_video *video = video_drvdata(file);
-+
-+ *f = video->active_fmt;
-+
-+ return 0;
-+}
-+
-+static int video_s_fmt(struct file *file, void *fh, struct v4l2_format *f)
-+{
-+ struct stfcamss_video *video = video_drvdata(file);
-+ int ret;
-+
-+ if (vb2_is_busy(&video->vb2_q))
-+ return -EBUSY;
-+
-+ ret = __video_try_fmt(video, f);
-+ if (ret < 0)
-+ return ret;
-+
-+ video->active_fmt = *f;
-+
-+ return 0;
-+}
-+
-+static int video_try_fmt(struct file *file, void *fh, struct v4l2_format *f)
-+{
-+ struct stfcamss_video *video = video_drvdata(file);
-+
-+ return __video_try_fmt(video, f);
-+}
-+
-+static int video_enum_input(struct file *file, void *fh,
-+ struct v4l2_input *input)
-+{
-+ if (input->index > 0)
-+ return -EINVAL;
-+
-+ strscpy(input->name, "camera", sizeof(input->name));
-+ input->type = V4L2_INPUT_TYPE_CAMERA;
-+
-+ return 0;
-+}
-+
-+static int video_g_input(struct file *file, void *fh, unsigned int *input)
-+{
-+ *input = 0;
-+
-+ return 0;
-+}
-+
-+static int video_s_input(struct file *file, void *fh, unsigned int input)
-+{
-+ return input == 0 ? 0 : -EINVAL;
-+}
-+
-+static int video_g_parm(struct file *file, void *priv,
-+ struct v4l2_streamparm *p)
-+{
-+ struct stfcamss_video *video = video_drvdata(file);
-+ struct video_device *vdev = &video->vdev;
-+ struct media_entity *entity;
-+ struct v4l2_subdev *subdev;
-+ struct media_pad *pad;
-+ int ret, is_support = 0;
-+
-+ entity = &vdev->entity;
-+ while (1) {
-+ pad = &entity->pads[0];
-+ if (!(pad->flags & MEDIA_PAD_FL_SINK))
-+ break;
-+
-+ pad = media_pad_remote_pad_first(pad);
-+ if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
-+ break;
-+
-+ entity = pad->entity;
-+ subdev = media_entity_to_v4l2_subdev(entity);
-+
-+ ret = v4l2_g_parm_cap(vdev, subdev, p);
-+ if (ret < 0 && ret != -ENOIOCTLCMD)
-+ break;
-+ if (!ret)
-+ is_support = 1;
-+ }
-+
-+ return is_support ? 0 : ret;
-+}
-+
-+static int video_s_parm(struct file *file, void *priv,
-+ struct v4l2_streamparm *p)
-+{
-+ struct stfcamss_video *video = video_drvdata(file);
-+ struct video_device *vdev = &video->vdev;
-+ struct media_entity *entity;
-+ struct v4l2_subdev *subdev;
-+ struct media_pad *pad;
-+ struct v4l2_streamparm tmp_p;
-+ int ret, is_support = 0;
-+
-+ entity = &vdev->entity;
-+ while (1) {
-+ pad = &entity->pads[0];
-+ if (!(pad->flags & MEDIA_PAD_FL_SINK))
-+ break;
-+
-+ pad = media_pad_remote_pad_first(pad);
-+ if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
-+ break;
-+
-+ entity = pad->entity;
-+ subdev = media_entity_to_v4l2_subdev(entity);
-+
-+ tmp_p = *p;
-+ ret = v4l2_s_parm_cap(vdev, subdev, &tmp_p);
-+ if (ret < 0 && ret != -ENOIOCTLCMD)
-+ break;
-+ if (!ret) {
-+ is_support = 1;
-+ *p = tmp_p;
-+ }
-+ }
-+
-+ return is_support ? 0 : ret;
-+}
-+
-+static const struct v4l2_ioctl_ops stf_vid_vin_ioctl_ops = {
-+ .vidioc_querycap = video_querycap,
-+ .vidioc_enum_fmt_vid_cap = video_enum_fmt,
-+ .vidioc_enum_fmt_vid_out = video_enum_fmt,
-+ .vidioc_enum_framesizes = video_enum_framesizes,
-+ .vidioc_g_fmt_vid_cap = video_g_fmt,
-+ .vidioc_s_fmt_vid_cap = video_s_fmt,
-+ .vidioc_try_fmt_vid_cap = video_try_fmt,
-+ .vidioc_g_fmt_vid_out = video_g_fmt,
-+ .vidioc_s_fmt_vid_out = video_s_fmt,
-+ .vidioc_try_fmt_vid_out = video_try_fmt,
-+ .vidioc_reqbufs = vb2_ioctl_reqbufs,
-+ .vidioc_querybuf = vb2_ioctl_querybuf,
-+ .vidioc_qbuf = vb2_ioctl_qbuf,
-+ .vidioc_expbuf = vb2_ioctl_expbuf,
-+ .vidioc_dqbuf = vb2_ioctl_dqbuf,
-+ .vidioc_create_bufs = vb2_ioctl_create_bufs,
-+ .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
-+ .vidioc_streamon = vb2_ioctl_streamon,
-+ .vidioc_streamoff = vb2_ioctl_streamoff,
-+ .vidioc_enum_input = video_enum_input,
-+ .vidioc_g_input = video_g_input,
-+ .vidioc_s_input = video_s_input,
-+ .vidioc_g_parm = video_g_parm,
-+ .vidioc_s_parm = video_s_parm,
-+};
-+
-+static const struct v4l2_ioctl_ops stf_vid_isp_ioctl_ops = {
-+ .vidioc_querycap = video_querycap,
-+ .vidioc_enum_fmt_vid_cap = video_enum_fmt,
-+ .vidioc_enum_fmt_vid_out = video_enum_fmt,
-+ .vidioc_enum_framesizes = video_enum_framesizes,
-+ .vidioc_g_fmt_vid_cap = video_g_fmt,
-+ .vidioc_s_fmt_vid_cap = video_s_fmt,
-+ .vidioc_try_fmt_vid_cap = video_try_fmt,
-+ .vidioc_g_fmt_vid_out = video_g_fmt,
-+ .vidioc_s_fmt_vid_out = video_s_fmt,
-+ .vidioc_try_fmt_vid_out = video_try_fmt,
-+ .vidioc_reqbufs = vb2_ioctl_reqbufs,
-+ .vidioc_querybuf = vb2_ioctl_querybuf,
-+ .vidioc_qbuf = vb2_ioctl_qbuf,
-+ .vidioc_expbuf = vb2_ioctl_expbuf,
-+ .vidioc_dqbuf = vb2_ioctl_dqbuf,
-+ .vidioc_create_bufs = vb2_ioctl_create_bufs,
-+ .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
-+ .vidioc_streamon = vb2_ioctl_streamon,
-+ .vidioc_streamoff = vb2_ioctl_streamoff,
-+ .vidioc_enum_input = video_enum_input,
-+ .vidioc_g_input = video_g_input,
-+ .vidioc_s_input = video_s_input,
-+ .vidioc_g_parm = video_g_parm,
-+ .vidioc_s_parm = video_s_parm,
-+};
-+
-+/* -----------------------------------------------------------------------------
-+ * V4L2 file operations
-+ */
-+
-+static int video_open(struct file *file)
-+{
-+ struct video_device *vdev = video_devdata(file);
-+ struct stfcamss_video *video = video_drvdata(file);
-+ struct v4l2_fh *vfh;
-+ int ret;
-+
-+ mutex_lock(&video->lock);
-+
-+ vfh = kzalloc(sizeof(*vfh), GFP_KERNEL);
-+ if (!vfh) {
-+ ret = -ENOMEM;
-+ goto error_alloc;
-+ }
-+
-+ v4l2_fh_init(vfh, vdev);
-+ v4l2_fh_add(vfh);
-+
-+ file->private_data = vfh;
-+
-+ ret = v4l2_pipeline_pm_get(&vdev->entity);
-+ if (ret < 0) {
-+ dev_err(video->stfcamss->dev,
-+ "Failed to power up pipeline: %d\n", ret);
-+ goto error_pm_use;
-+ }
-+ mutex_unlock(&video->lock);
-+
-+ return 0;
-+
-+error_pm_use:
-+ v4l2_fh_release(file);
-+error_alloc:
-+ mutex_unlock(&video->lock);
-+ return ret;
-+}
-+
-+static int video_release(struct file *file)
-+{
-+ struct video_device *vdev = video_devdata(file);
-+
-+ vb2_fop_release(file);
-+ v4l2_pipeline_pm_put(&vdev->entity);
-+ file->private_data = NULL;
-+
-+ return 0;
-+}
-+
-+static const struct v4l2_file_operations stf_vid_fops = {
-+ .owner = THIS_MODULE,
-+ .unlocked_ioctl = video_ioctl2,
-+ .open = video_open,
-+ .release = video_release,
-+ .poll = vb2_fop_poll,
-+ .mmap = vb2_fop_mmap,
-+ .read = vb2_fop_read,
-+};
-+
-+/* -----------------------------------------------------------------------------
-+ * STFCAMSS video core
-+ */
-+
-+static void stf_video_release(struct video_device *vdev)
-+{
-+ struct stfcamss_video *video = video_get_drvdata(vdev);
-+
-+ media_entity_cleanup(&vdev->entity);
-+
-+ mutex_destroy(&video->q_lock);
-+ mutex_destroy(&video->lock);
-+}
-+
-+int stf_video_register(struct stfcamss_video *video,
-+ struct v4l2_device *v4l2_dev, const char *name)
-+{
-+ struct video_device *vdev;
-+ struct vb2_queue *q;
-+ struct media_pad *pad = &video->pad;
-+ int ret;
-+
-+ vdev = &video->vdev;
-+
-+ mutex_init(&video->q_lock);
-+
-+ q = &video->vb2_q;
-+ q->drv_priv = video;
-+ q->mem_ops = &vb2_dma_contig_memops;
-+ q->ops = &stf_video_vb2_q_ops;
-+ q->type = video->type;
-+ q->io_modes = VB2_DMABUF | VB2_MMAP | VB2_READ;
-+ q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
-+ q->buf_struct_size = sizeof(struct stfcamss_buffer);
-+ q->dev = video->stfcamss->dev;
-+ q->lock = &video->q_lock;
-+ q->min_buffers_needed = STFCAMSS_MIN_BUFFERS;
-+ ret = vb2_queue_init(q);
-+ if (ret < 0) {
-+ dev_err(video->stfcamss->dev,
-+ "Failed to init vb2 queue: %d\n", ret);
-+ goto err_vb2_init;
-+ }
-+
-+ pad->flags = MEDIA_PAD_FL_SINK;
-+ ret = media_entity_pads_init(&vdev->entity, 1, pad);
-+ if (ret < 0) {
-+ dev_err(video->stfcamss->dev,
-+ "Failed to init video entity: %d\n", ret);
-+ goto err_vb2_init;
-+ }
-+
-+ mutex_init(&video->lock);
-+
-+ if (video->id == STF_V_LINE_WR) {
-+ video->formats = formats_pix_wr;
-+ video->nformats = ARRAY_SIZE(formats_pix_wr);
-+ video->bpl_alignment = STFCAMSS_FRAME_WIDTH_ALIGN_8;
-+ vdev->ioctl_ops = &stf_vid_vin_ioctl_ops;
-+ } else {
-+ video->formats = formats_pix_isp;
-+ video->nformats = ARRAY_SIZE(formats_pix_isp);
-+ video->bpl_alignment = STFCAMSS_FRAME_WIDTH_ALIGN_8;
-+ vdev->ioctl_ops = &stf_vid_isp_ioctl_ops;
-+ }
-+
-+ ret = stf_video_init_format(video);
-+ if (ret < 0) {
-+ dev_err(video->stfcamss->dev,
-+ "Failed to init format: %d\n", ret);
-+ goto err_vid_init_format;
-+ }
-+
-+ vdev->fops = &stf_vid_fops;
-+ vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE;
-+ vdev->vfl_dir = VFL_DIR_RX;
-+ vdev->device_caps |= V4L2_CAP_STREAMING | V4L2_CAP_READWRITE;
-+ vdev->release = stf_video_release;
-+ vdev->v4l2_dev = v4l2_dev;
-+ vdev->queue = &video->vb2_q;
-+ vdev->lock = &video->lock;
-+ strscpy(vdev->name, name, sizeof(vdev->name));
-+
-+ ret = video_register_device(vdev, VFL_TYPE_VIDEO, video->id);
-+ if (ret < 0) {
-+ dev_err(video->stfcamss->dev,
-+ "Failed to register video device: %d\n", ret);
-+ goto err_vid_reg;
-+ }
-+
-+ video_set_drvdata(vdev, video);
-+ return 0;
-+
-+err_vid_reg:
-+err_vid_init_format:
-+ media_entity_cleanup(&vdev->entity);
-+ mutex_destroy(&video->lock);
-+err_vb2_init:
-+ mutex_destroy(&video->q_lock);
-+ return ret;
-+}
-+
-+void stf_video_unregister(struct stfcamss_video *video)
-+{
-+ vb2_video_unregister_device(&video->vdev);
-+}
---- /dev/null
-+++ b/drivers/media/platform/starfive/stf_video.h
-@@ -0,0 +1,95 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+/*
-+ * stf_video.h
-+ *
-+ * StarFive Camera Subsystem - V4L2 device node
-+ *
-+ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
-+ */
-+
-+#ifndef STF_VIDEO_H
-+#define STF_VIDEO_H
-+
-+#include <linux/mutex.h>
-+#include <linux/videodev2.h>
-+#include <media/v4l2-dev.h>
-+#include <media/v4l2-fh.h>
-+#include <media/v4l2-ioctl.h>
-+#include <media/videobuf2-v4l2.h>
-+
-+#define STFCAMSS_FRAME_MIN_WIDTH 64
-+#define STFCAMSS_FRAME_MAX_WIDTH 1920
-+#define STFCAMSS_FRAME_MIN_HEIGHT 64
-+#define STFCAMSS_FRAME_MAX_HEIGHT 1080
-+#define STFCAMSS_FRAME_WIDTH_ALIGN_8 8
-+#define STFCAMSS_FRAME_WIDTH_ALIGN_128 128
-+#define STFCAMSS_MIN_BUFFERS 2
-+
-+#define STFCAMSS_MAX_ENTITY_NAME_LEN 27
-+
-+enum stf_v_line_id {
-+ STF_V_LINE_WR = 0,
-+ STF_V_LINE_ISP,
-+ STF_V_LINE_MAX,
-+};
-+
-+struct stfcamss_buffer {
-+ struct vb2_v4l2_buffer vb;
-+ dma_addr_t addr[3];
-+ struct list_head queue;
-+ int sizeimage;
-+};
-+
-+struct fract {
-+ u8 numerator;
-+ u8 denominator;
-+};
-+
-+/*
-+ * struct stfcamss_format_info - ISP media bus format information
-+ * @code: V4L2 media bus format code
-+ * @pixelformat: V4L2 pixel format FCC identifier
-+ * @planes: Number of planes
-+ * @hsub: Horizontal subsampling (for each plane)
-+ * @vsub: Vertical subsampling (for each plane)
-+ * @bpp: Bits per pixel when stored in memory (for each plane)
-+ */
-+struct stfcamss_format_info {
-+ u32 code;
-+ u32 pixelformat;
-+ u8 planes;
-+ struct fract hsub[3];
-+ struct fract vsub[3];
-+ u8 bpp[3];
-+};
-+
-+struct stfcamss_video {
-+ struct stfcamss *stfcamss;
-+ u8 id;
-+ struct vb2_queue vb2_q;
-+ struct video_device vdev;
-+ struct media_pad pad;
-+ struct media_pipeline pipe;
-+ struct v4l2_format active_fmt;
-+ enum v4l2_buf_type type;
-+ const struct stfcamss_video_ops *ops;
-+ struct mutex lock; /* serialize device access */
-+ struct mutex q_lock; /* protects the queue */
-+ unsigned int bpl_alignment;
-+ const struct stfcamss_format_info *formats;
-+ unsigned int nformats;
-+};
-+
-+struct stfcamss_video_ops {
-+ int (*queue_buffer)(struct stfcamss_video *vid,
-+ struct stfcamss_buffer *buf);
-+ int (*flush_buffers)(struct stfcamss_video *vid,
-+ enum vb2_buffer_state state);
-+};
-+
-+int stf_video_register(struct stfcamss_video *video,
-+ struct v4l2_device *v4l2_dev, const char *name);
-+
-+void stf_video_unregister(struct stfcamss_video *video);
-+
-+#endif /* STF_VIDEO_H */
diff --git a/target/linux/starfive/patches-6.1/0085-media-starfive-Add-ISP-driver.patch b/target/linux/starfive/patches-6.1/0085-media-starfive-Add-ISP-driver.patch
deleted file mode 100644
index 3a871b5a7f..0000000000
--- a/target/linux/starfive/patches-6.1/0085-media-starfive-Add-ISP-driver.patch
+++ /dev/null
@@ -1,1667 +0,0 @@
-From 3b814965133cd53b1f30a34e4425294726cb0087 Mon Sep 17 00:00:00 2001
-From: Jack Zhu <jack.zhu@starfivetech.com>
-Date: Fri, 12 May 2023 18:28:43 +0800
-Subject: [PATCH 085/122] media: starfive: Add ISP driver
-
-Add ISP driver for StarFive Camera Subsystem.
-
-Signed-off-by: Jack Zhu <jack.zhu@starfivetech.com>
----
- drivers/media/platform/starfive/Makefile | 2 +
- drivers/media/platform/starfive/stf_camss.c | 71 ++-
- drivers/media/platform/starfive/stf_camss.h | 2 +
- drivers/media/platform/starfive/stf_isp.c | 550 ++++++++++++++++++
- drivers/media/platform/starfive/stf_isp.h | 476 +++++++++++++++
- .../media/platform/starfive/stf_isp_hw_ops.c | 452 ++++++++++++++
- 6 files changed, 1551 insertions(+), 2 deletions(-)
- create mode 100644 drivers/media/platform/starfive/stf_isp.c
- create mode 100644 drivers/media/platform/starfive/stf_isp.h
- create mode 100644 drivers/media/platform/starfive/stf_isp_hw_ops.c
-
---- a/drivers/media/platform/starfive/Makefile
-+++ b/drivers/media/platform/starfive/Makefile
-@@ -5,6 +5,8 @@
-
- starfive-camss-objs += \
- stf_camss.o \
-+ stf_isp.o \
-+ stf_isp_hw_ops.o \
- stf_video.o
-
- obj-$(CONFIG_VIDEO_STARFIVE_CAMSS) += starfive-camss.o \
---- a/drivers/media/platform/starfive/stf_camss.c
-+++ b/drivers/media/platform/starfive/stf_camss.c
-@@ -126,16 +126,66 @@ err_cleanup:
- return ret;
- }
-
-+/*
-+ * stfcamss_init_subdevices - Initialize subdev structures and resources
-+ * @stfcamss: STFCAMSS device
-+ *
-+ * Return 0 on success or a negative error code on failure
-+ */
-+static int stfcamss_init_subdevices(struct stfcamss *stfcamss)
-+{
-+ int ret;
-+
-+ ret = stf_isp_subdev_init(stfcamss);
-+ if (ret < 0) {
-+ dev_err(stfcamss->dev, "Failed to init isp subdev: %d\n", ret);
-+ return ret;
-+ }
-+
-+ return ret;
-+}
-+
-+static int stfcamss_register_subdevices(struct stfcamss *stfcamss)
-+{
-+ int ret;
-+ struct stf_isp_dev *isp_dev = &stfcamss->isp_dev;
-+
-+ ret = stf_isp_register(isp_dev, &stfcamss->v4l2_dev);
-+ if (ret < 0) {
-+ dev_err(stfcamss->dev,
-+ "Failed to register stf isp%d entity: %d\n", 0, ret);
-+ return ret;
-+ }
-+
-+ return ret;
-+}
-+
-+static void stfcamss_unregister_subdevices(struct stfcamss *stfcamss)
-+{
-+ stf_isp_unregister(&stfcamss->isp_dev);
-+}
-+
- static int stfcamss_subdev_notifier_bound(struct v4l2_async_notifier *async,
- struct v4l2_subdev *subdev,
- struct v4l2_async_subdev *asd)
- {
- struct stfcamss *stfcamss =
- container_of(async, struct stfcamss, notifier);
-+ struct stfcamss_async_subdev *csd =
-+ container_of(asd, struct stfcamss_async_subdev, asd);
-+ enum port_num port = csd->port;
-+ struct stf_isp_dev *isp_dev = &stfcamss->isp_dev;
- struct host_data *host_data = &stfcamss->host_data;
- struct media_entity *source;
- int i, j;
-
-+ if (port == PORT_NUMBER_CSI2RX) {
-+ host_data->host_entity[1] = &isp_dev->subdev.entity;
-+ } else if (port == PORT_NUMBER_DVP_SENSOR) {
-+ dev_err(stfcamss->dev, "Not support DVP sensor\n");
-+ return -EPERM;
-+ }
-+
- source = &subdev->entity;
-
- for (i = 0; i < source->num_pads; i++) {
-@@ -266,12 +316,18 @@ static int stfcamss_probe(struct platfor
- return -ENODEV;
- }
-
-+ ret = stfcamss_init_subdevices(stfcamss);
-+ if (ret < 0) {
-+ dev_err(dev, "Failed to init subdevice: %d\n", ret);
-+ goto err_cleanup_notifier;
-+ }
-+
- stfcamss_mc_init(pdev, stfcamss);
-
- ret = v4l2_device_register(stfcamss->dev, &stfcamss->v4l2_dev);
- if (ret < 0) {
- dev_err(dev, "Failed to register V4L2 device: %d\n", ret);
-- goto err_cleanup_notifier;
-+ goto err_cleanup_media_device;
- }
-
- ret = media_device_register(&stfcamss->media_dev);
-@@ -280,22 +336,32 @@ static int stfcamss_probe(struct platfor
- goto err_unregister_device;
- }
-
-+ ret = stfcamss_register_subdevices(stfcamss);
-+ if (ret < 0) {
-+ dev_err(dev, "Failed to register subdevice: %d\n", ret);
-+ goto err_unregister_media_dev;
-+ }
-+
- stfcamss->notifier.ops = &stfcamss_subdev_notifier_ops;
- ret = v4l2_async_nf_register(&stfcamss->v4l2_dev, &stfcamss->notifier);
- if (ret) {
- dev_err(dev, "Failed to register async subdev nodes: %d\n",
- ret);
-- goto err_unregister_media_dev;
-+ goto err_unregister_subdevs;
- }
-
- pm_runtime_enable(dev);
-
- return 0;
-
-+err_unregister_subdevs:
-+ stfcamss_unregister_subdevices(stfcamss);
- err_unregister_media_dev:
- media_device_unregister(&stfcamss->media_dev);
- err_unregister_device:
- v4l2_device_unregister(&stfcamss->v4l2_dev);
-+err_cleanup_media_device:
-+ media_device_cleanup(&stfcamss->media_dev);
- err_cleanup_notifier:
- v4l2_async_nf_cleanup(&stfcamss->notifier);
- return ret;
-@@ -311,6 +377,7 @@ static int stfcamss_remove(struct platfo
- {
- struct stfcamss *stfcamss = platform_get_drvdata(pdev);
-
-+ stfcamss_unregister_subdevices(stfcamss);
- v4l2_device_unregister(&stfcamss->v4l2_dev);
- media_device_cleanup(&stfcamss->media_dev);
- pm_runtime_disable(&pdev->dev);
---- a/drivers/media/platform/starfive/stf_camss.h
-+++ b/drivers/media/platform/starfive/stf_camss.h
-@@ -16,6 +16,7 @@
- #include <media/v4l2-device.h>
-
- #include "stf_common.h"
-+#include "stf_isp.h"
-
- #define DRV_NAME "starfive-camss"
- #define STF_DVP_NAME "stf_dvp"
-@@ -71,6 +72,7 @@ struct stfcamss {
- struct media_device media_dev;
- struct media_pipeline pipe;
- struct device *dev;
-+ struct stf_isp_dev isp_dev;
- struct v4l2_async_notifier notifier;
- struct host_data host_data;
- void __iomem *syscon_base;
---- /dev/null
-+++ b/drivers/media/platform/starfive/stf_isp.c
-@@ -0,0 +1,550 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * stf_isp.c
-+ *
-+ * StarFive Camera Subsystem - ISP Module
-+ *
-+ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
-+ */
-+#include <linux/firmware.h>
-+#include <media/v4l2-event.h>
-+
-+#include "stf_camss.h"
-+
-+#define SINK_FORMATS_INDEX 0
-+#define UO_FORMATS_INDEX 1
-+
-+static int isp_set_selection(struct v4l2_subdev *sd,
-+ struct v4l2_subdev_state *state,
-+ struct v4l2_subdev_selection *sel);
-+
-+static const struct isp_format isp_formats_sink[] = {
-+ { MEDIA_BUS_FMT_SRGGB10_1X10, 10 },
-+ { MEDIA_BUS_FMT_SGRBG10_1X10, 10 },
-+ { MEDIA_BUS_FMT_SGBRG10_1X10, 10 },
-+ { MEDIA_BUS_FMT_SBGGR10_1X10, 10 },
-+};
-+
-+static const struct isp_format isp_formats_uo[] = {
-+ { MEDIA_BUS_FMT_Y12_1X12, 8 },
-+};
-+
-+static const struct isp_format_table isp_formats_st7110[] = {
-+ { isp_formats_sink, ARRAY_SIZE(isp_formats_sink) },
-+ { isp_formats_uo, ARRAY_SIZE(isp_formats_uo) },
-+};
-+
-+int stf_isp_subdev_init(struct stfcamss *stfcamss)
-+{
-+ struct stf_isp_dev *isp_dev = &stfcamss->isp_dev;
-+
-+ isp_dev->sdev_type = STF_SUBDEV_TYPE_ISP;
-+ isp_dev->stfcamss = stfcamss;
-+ isp_dev->formats = isp_formats_st7110;
-+ isp_dev->nformats = ARRAY_SIZE(isp_formats_st7110);
-+
-+ mutex_init(&isp_dev->stream_lock);
-+ mutex_init(&isp_dev->power_lock);
-+ return 0;
-+}
-+
-+static int isp_set_power(struct v4l2_subdev *sd, int on)
-+{
-+ struct stf_isp_dev *isp_dev = v4l2_get_subdevdata(sd);
-+
-+ mutex_lock(&isp_dev->power_lock);
-+ if (on) {
-+ if (isp_dev->power_count == 0)
-+ dev_dbg(isp_dev->stfcamss->dev, "turn on isp\n");
-+ isp_dev->power_count++;
-+ } else {
-+ if (isp_dev->power_count == 0)
-+ goto exit;
-+ isp_dev->power_count--;
-+ }
-+exit:
-+ mutex_unlock(&isp_dev->power_lock);
-+
-+ return 0;
-+}
-+
-+static struct v4l2_mbus_framefmt *
-+__isp_get_format(struct stf_isp_dev *isp_dev,
-+ struct v4l2_subdev_state *state,
-+ unsigned int pad,
-+ enum v4l2_subdev_format_whence which)
-+{
-+ if (which == V4L2_SUBDEV_FORMAT_TRY)
-+ return v4l2_subdev_get_try_format(&isp_dev->subdev, state, pad);
-+
-+ return &isp_dev->fmt[pad];
-+}
-+
-+static int isp_set_stream(struct v4l2_subdev *sd, int enable)
-+{
-+ struct stf_isp_dev *isp_dev = v4l2_get_subdevdata(sd);
-+ int ret = 0;
-+ struct v4l2_mbus_framefmt *fmt;
-+ struct v4l2_event src_ch = { 0 };
-+
-+ fmt = __isp_get_format(isp_dev, NULL, STF_ISP_PAD_SINK,
-+ V4L2_SUBDEV_FORMAT_ACTIVE);
-+ mutex_lock(&isp_dev->stream_lock);
-+ if (enable) {
-+ if (isp_dev->stream_count == 0) {
-+ stf_isp_clk_enable(isp_dev);
-+ stf_isp_reset(isp_dev);
-+ stf_isp_init_cfg(isp_dev);
-+ stf_isp_settings(isp_dev, isp_dev->rect, fmt->code);
-+ stf_isp_stream_set(isp_dev);
-+ }
-+ isp_dev->stream_count++;
-+ } else {
-+ if (isp_dev->stream_count == 0)
-+ goto exit;
-+
-+ if (isp_dev->stream_count == 1)
-+ stf_isp_clk_disable(isp_dev);
-+
-+ isp_dev->stream_count--;
-+ }
-+ src_ch.type = V4L2_EVENT_SOURCE_CHANGE,
-+ src_ch.u.src_change.changes = isp_dev->stream_count,
-+
-+ v4l2_subdev_notify_event(sd, &src_ch);
-+exit:
-+ mutex_unlock(&isp_dev->stream_lock);
-+
-+ return ret;
-+}
-+
-+static void isp_try_format(struct stf_isp_dev *isp_dev,
-+ struct v4l2_subdev_state *state,
-+ unsigned int pad,
-+ struct v4l2_mbus_framefmt *fmt,
-+ enum v4l2_subdev_format_whence which)
-+{
-+ const struct isp_format_table *formats;
-+ struct stf_isp_crop *rect;
-+ int i;
-+
-+ switch (pad) {
-+ case STF_ISP_PAD_SINK:
-+ /* Set format on sink pad */
-+ formats = &isp_dev->formats[SINK_FORMATS_INDEX];
-+ rect = &isp_dev->rect[SINK_FORMATS_INDEX];
-+ fmt->width = clamp_t(u32,
-+ fmt->width, STFCAMSS_FRAME_MIN_WIDTH,
-+ STFCAMSS_FRAME_MAX_WIDTH);
-+ fmt->height = clamp_t(u32,
-+ fmt->height, STFCAMSS_FRAME_MIN_HEIGHT,
-+ STFCAMSS_FRAME_MAX_HEIGHT);
-+ fmt->height &= ~0x1;
-+ fmt->field = V4L2_FIELD_NONE;
-+ fmt->colorspace = V4L2_COLORSPACE_SRGB;
-+ fmt->flags = 0;
-+ break;
-+
-+ case STF_ISP_PAD_SRC:
-+ formats = &isp_dev->formats[UO_FORMATS_INDEX];
-+ rect = &isp_dev->rect[UO_FORMATS_INDEX];
-+ *fmt = *__isp_get_format(isp_dev, state,
-+ STF_ISP_PAD_SINK, which);
-+ break;
-+ }
-+
-+ for (i = 0; i < formats->nfmts; i++) {
-+ if (fmt->code == formats->fmts[i].code)
-+ break;
-+ }
-+
-+ if (i >= formats->nfmts) {
-+ fmt->code = formats->fmts[0].code;
-+ rect->bpp = formats->fmts[0].bpp;
-+ } else {
-+ rect->bpp = formats->fmts[i].bpp;
-+ }
-+}
-+
-+static int isp_enum_mbus_code(struct v4l2_subdev *sd,
-+ struct v4l2_subdev_state *state,
-+ struct v4l2_subdev_mbus_code_enum *code)
-+{
-+ struct stf_isp_dev *isp_dev = v4l2_get_subdevdata(sd);
-+ const struct isp_format_table *formats;
-+
-+ if (code->index >= isp_dev->nformats)
-+ return -EINVAL;
-+ if (code->pad == STF_ISP_PAD_SINK) {
-+ formats = &isp_dev->formats[SINK_FORMATS_INDEX];
-+ code->code = formats->fmts[code->index].code;
-+ } else {
-+ struct v4l2_mbus_framefmt *sink_fmt;
-+
-+ sink_fmt = __isp_get_format(isp_dev, state, STF_ISP_PAD_SINK,
-+ code->which);
-+
-+ code->code = sink_fmt->code;
-+ if (!code->code)
-+ return -EINVAL;
-+ }
-+ code->flags = 0;
-+
-+ return 0;
-+}
-+
-+static int isp_enum_frame_size(struct v4l2_subdev *sd,
-+ struct v4l2_subdev_state *state,
-+ struct v4l2_subdev_frame_size_enum *fse)
-+{
-+ struct stf_isp_dev *isp_dev = v4l2_get_subdevdata(sd);
-+ struct v4l2_mbus_framefmt format;
-+
-+ if (fse->index != 0)
-+ return -EINVAL;
-+
-+ format.code = fse->code;
-+ format.width = 1;
-+ format.height = 1;
-+ isp_try_format(isp_dev, state, fse->pad, &format, fse->which);
-+ fse->min_width = format.width;
-+ fse->min_height = format.height;
-+
-+ if (format.code != fse->code)
-+ return -EINVAL;
-+
-+ format.code = fse->code;
-+ format.width = -1;
-+ format.height = -1;
-+ isp_try_format(isp_dev, state, fse->pad, &format, fse->which);
-+ fse->max_width = format.width;
-+ fse->max_height = format.height;
-+
-+ return 0;
-+}
-+
-+static int isp_get_format(struct v4l2_subdev *sd,
-+ struct v4l2_subdev_state *state,
-+ struct v4l2_subdev_format *fmt)
-+{
-+ struct stf_isp_dev *isp_dev = v4l2_get_subdevdata(sd);
-+ struct v4l2_mbus_framefmt *format;
-+
-+ format = __isp_get_format(isp_dev, state, fmt->pad, fmt->which);
-+ if (!format)
-+ return -EINVAL;
-+
-+ fmt->format = *format;
-+
-+ return 0;
-+}
-+
-+static int isp_set_format(struct v4l2_subdev *sd,
-+ struct v4l2_subdev_state *state,
-+ struct v4l2_subdev_format *fmt)
-+{
-+ struct stf_isp_dev *isp_dev = v4l2_get_subdevdata(sd);
-+ struct v4l2_mbus_framefmt *format;
-+
-+ format = __isp_get_format(isp_dev, state, fmt->pad, fmt->which);
-+ if (!format)
-+ return -EINVAL;
-+
-+ mutex_lock(&isp_dev->stream_lock);
-+
-+ isp_try_format(isp_dev, state, fmt->pad, &fmt->format, fmt->which);
-+ *format = fmt->format;
-+
-+ mutex_unlock(&isp_dev->stream_lock);
-+
-+ /* Propagate to in crop */
-+ if (fmt->pad == STF_ISP_PAD_SINK) {
-+ struct v4l2_subdev_selection sel = { 0 };
-+ int ret;
-+
-+ /* Reset sink pad compose selection */
-+ sel.which = fmt->which;
-+ sel.pad = STF_ISP_PAD_SINK;
-+ sel.target = V4L2_SEL_TGT_CROP;
-+ sel.r.width = fmt->format.width;
-+ sel.r.height = fmt->format.height;
-+ ret = isp_set_selection(sd, state, &sel);
-+ if (ret < 0)
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+
-+static struct v4l2_rect *
-+__isp_get_crop(struct stf_isp_dev *isp_dev,
-+ struct v4l2_subdev_state *state,
-+ unsigned int pad,
-+ enum v4l2_subdev_format_whence which)
-+{
-+ if (which == V4L2_SUBDEV_FORMAT_TRY)
-+ return v4l2_subdev_get_try_crop(&isp_dev->subdev, state,
-+ STF_ISP_PAD_SINK);
-+
-+ return &isp_dev->rect[pad].rect;
-+}
-+
-+static void isp_try_crop(struct stf_isp_dev *isp_dev,
-+ struct v4l2_subdev_state *state,
-+ struct v4l2_rect *rect,
-+ enum v4l2_subdev_format_whence which)
-+{
-+ struct v4l2_mbus_framefmt *fmt;
-+
-+ fmt = __isp_get_format(isp_dev, state, STF_ISP_PAD_SINK, which);
-+
-+ if (rect->width > fmt->width)
-+ rect->width = fmt->width;
-+
-+ if (rect->width + rect->left > fmt->width)
-+ rect->left = fmt->width - rect->width;
-+
-+ if (rect->height > fmt->height)
-+ rect->height = fmt->height;
-+
-+ if (rect->height + rect->top > fmt->height)
-+ rect->top = fmt->height - rect->height;
-+
-+ if (rect->width < STFCAMSS_FRAME_MIN_WIDTH) {
-+ rect->left = 0;
-+ rect->width = STFCAMSS_FRAME_MAX_WIDTH;
-+ }
-+
-+ if (rect->height < STFCAMSS_FRAME_MIN_HEIGHT) {
-+ rect->top = 0;
-+ rect->height = STFCAMSS_FRAME_MAX_HEIGHT;
-+ }
-+ rect->height &= ~0x1;
-+}
-+
-+static int isp_get_selection(struct v4l2_subdev *sd,
-+ struct v4l2_subdev_state *state,
-+ struct v4l2_subdev_selection *sel)
-+{
-+ struct stf_isp_dev *isp_dev = v4l2_get_subdevdata(sd);
-+ struct v4l2_subdev_format fmt = { 0 };
-+ struct v4l2_rect *rect;
-+ int ret;
-+
-+ switch (sel->target) {
-+ case V4L2_SEL_TGT_CROP_BOUNDS:
-+ if (sel->pad == STF_ISP_PAD_SINK) {
-+ fmt.pad = sel->pad;
-+ fmt.which = sel->which;
-+ ret = isp_get_format(sd, state, &fmt);
-+ if (ret < 0)
-+ return ret;
-+
-+ sel->r.left = 0;
-+ sel->r.top = 0;
-+ sel->r.width = fmt.format.width;
-+ sel->r.height = fmt.format.height;
-+ } else if (sel->pad == STF_ISP_PAD_SRC) {
-+ rect = __isp_get_crop(isp_dev, state,
-+ sel->pad, sel->which);
-+ sel->r = *rect;
-+ }
-+ break;
-+
-+ case V4L2_SEL_TGT_CROP:
-+ rect = __isp_get_crop(isp_dev, state, sel->pad, sel->which);
-+ if (!rect)
-+ return -EINVAL;
-+
-+ sel->r = *rect;
-+ break;
-+
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ return 0;
-+}
-+
-+static int isp_set_selection(struct v4l2_subdev *sd,
-+ struct v4l2_subdev_state *state,
-+ struct v4l2_subdev_selection *sel)
-+{
-+ struct stf_isp_dev *isp_dev = v4l2_get_subdevdata(sd);
-+ struct v4l2_rect *rect;
-+ int ret = 0;
-+
-+ if (sel->target == V4L2_SEL_TGT_CROP &&
-+ sel->pad == STF_ISP_PAD_SINK) {
-+ struct v4l2_subdev_selection crop = { 0 };
-+
-+ rect = __isp_get_crop(isp_dev, state, sel->pad, sel->which);
-+ if (!rect)
-+ return -EINVAL;
-+
-+ mutex_lock(&isp_dev->stream_lock);
-+ isp_try_crop(isp_dev, state, &sel->r, sel->which);
-+ *rect = sel->r;
-+ mutex_unlock(&isp_dev->stream_lock);
-+
-+ /* Reset source crop selection */
-+ crop.which = sel->which;
-+ crop.pad = STF_ISP_PAD_SRC;
-+ crop.target = V4L2_SEL_TGT_CROP;
-+ crop.r = *rect;
-+ ret = isp_set_selection(sd, state, &crop);
-+ } else if (sel->target == V4L2_SEL_TGT_CROP &&
-+ sel->pad == STF_ISP_PAD_SRC) {
-+ struct v4l2_subdev_format fmt = { 0 };
-+
-+ rect = __isp_get_crop(isp_dev, state, sel->pad, sel->which);
-+ if (!rect)
-+ return -EINVAL;
-+
-+ mutex_lock(&isp_dev->stream_lock);
-+ isp_try_crop(isp_dev, state, &sel->r, sel->which);
-+ *rect = sel->r;
-+ mutex_unlock(&isp_dev->stream_lock);
-+
-+ /* Reset source pad format width and height */
-+ fmt.which = sel->which;
-+ fmt.pad = STF_ISP_PAD_SRC;
-+ fmt.format.width = rect->width;
-+ fmt.format.height = rect->height;
-+ ret = isp_set_format(sd, state, &fmt);
-+ if (ret < 0)
-+ return ret;
-+ }
-+
-+ dev_dbg(isp_dev->stfcamss->dev, "pad: %d sel(%d,%d)/%dx%d\n",
-+ sel->pad, sel->r.left, sel->r.top, sel->r.width, sel->r.height);
-+
-+ return 0;
-+}
-+
-+static int isp_init_formats(struct v4l2_subdev *sd,
-+ struct v4l2_subdev_fh *fh)
-+{
-+ struct v4l2_subdev_format format = {
-+ .pad = STF_ISP_PAD_SINK,
-+ .which =
-+ fh ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE,
-+ .format = {
-+ .code = MEDIA_BUS_FMT_RGB565_2X8_LE,
-+ .width = 1920,
-+ .height = 1080
-+ }
-+ };
-+
-+ return isp_set_format(sd, fh ? fh->state : NULL, &format);
-+}
-+
-+static int isp_link_setup(struct media_entity *entity,
-+ const struct media_pad *local,
-+ const struct media_pad *remote, u32 flags)
-+{
-+ if (flags & MEDIA_LNK_FL_ENABLED)
-+ if (media_pad_remote_pad_first(local))
-+ return -EBUSY;
-+ return 0;
-+}
-+
-+static int stf_isp_subscribe_event(struct v4l2_subdev *sd,
-+ struct v4l2_fh *fh,
-+ struct v4l2_event_subscription *sub)
-+{
-+ switch (sub->type) {
-+ case V4L2_EVENT_SOURCE_CHANGE:
-+ return v4l2_src_change_event_subdev_subscribe(sd, fh, sub);
-+ default:
-+ return -EINVAL;
-+ }
-+}
-+
-+static const struct v4l2_subdev_core_ops isp_core_ops = {
-+ .s_power = isp_set_power,
-+ .subscribe_event = stf_isp_subscribe_event,
-+ .unsubscribe_event = v4l2_event_subdev_unsubscribe,
-+};
-+
-+static const struct v4l2_subdev_video_ops isp_video_ops = {
-+ .s_stream = isp_set_stream,
-+};
-+
-+static const struct v4l2_subdev_pad_ops isp_pad_ops = {
-+ .enum_mbus_code = isp_enum_mbus_code,
-+ .enum_frame_size = isp_enum_frame_size,
-+ .get_fmt = isp_get_format,
-+ .set_fmt = isp_set_format,
-+ .get_selection = isp_get_selection,
-+ .set_selection = isp_set_selection,
-+};
-+
-+static const struct v4l2_subdev_ops isp_v4l2_ops = {
-+ .core = &isp_core_ops,
-+ .video = &isp_video_ops,
-+ .pad = &isp_pad_ops,
-+};
-+
-+static const struct v4l2_subdev_internal_ops isp_v4l2_internal_ops = {
-+ .open = isp_init_formats,
-+};
-+
-+static const struct media_entity_operations isp_media_ops = {
-+ .link_setup = isp_link_setup,
-+ .link_validate = v4l2_subdev_link_validate,
-+};
-+
-+int stf_isp_register(struct stf_isp_dev *isp_dev, struct v4l2_device *v4l2_dev)
-+{
-+ struct v4l2_subdev *sd = &isp_dev->subdev;
-+ struct media_pad *pads = isp_dev->pads;
-+ int ret;
-+
-+ v4l2_subdev_init(sd, &isp_v4l2_ops);
-+ sd->internal_ops = &isp_v4l2_internal_ops;
-+ sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
-+ snprintf(sd->name, ARRAY_SIZE(sd->name), "%s%d", STF_ISP_NAME, 0);
-+ v4l2_set_subdevdata(sd, isp_dev);
-+
-+ ret = isp_init_formats(sd, NULL);
-+ if (ret < 0) {
-+ dev_err(isp_dev->stfcamss->dev, "Failed to init format: %d\n",
-+ ret);
-+ return ret;
-+ }
-+
-+ pads[STF_ISP_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
-+ pads[STF_ISP_PAD_SRC].flags = MEDIA_PAD_FL_SOURCE;
-+
-+ sd->entity.function = MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER;
-+ sd->entity.ops = &isp_media_ops;
-+ ret = media_entity_pads_init(&sd->entity, STF_ISP_PAD_MAX, pads);
-+ if (ret < 0) {
-+ dev_err(isp_dev->stfcamss->dev,
-+ "Failed to init media entity: %d\n", ret);
-+ return ret;
-+ }
-+
-+ ret = v4l2_device_register_subdev(v4l2_dev, sd);
-+ if (ret < 0) {
-+ dev_err(isp_dev->stfcamss->dev,
-+ "Failed to register subdev: %d\n", ret);
-+ goto err_sreg;
-+ }
-+
-+ return 0;
-+
-+err_sreg:
-+ media_entity_cleanup(&sd->entity);
-+ return ret;
-+}
-+
-+int stf_isp_unregister(struct stf_isp_dev *isp_dev)
-+{
-+ v4l2_device_unregister_subdev(&isp_dev->subdev);
-+ media_entity_cleanup(&isp_dev->subdev.entity);
-+ mutex_destroy(&isp_dev->stream_lock);
-+ mutex_destroy(&isp_dev->power_lock);
-+ return 0;
-+}
---- /dev/null
-+++ b/drivers/media/platform/starfive/stf_isp.h
-@@ -0,0 +1,476 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+/*
-+ * stf_isp.h
-+ *
-+ * StarFive Camera Subsystem - ISP Module
-+ *
-+ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
-+ */
-+
-+#ifndef STF_ISP_H
-+#define STF_ISP_H
-+
-+#include <media/media-entity.h>
-+#include <media/v4l2-subdev.h>
-+
-+#include "stf_video.h"
-+
-+#define ISP_RAW_DATA_BITS 12
-+#define SCALER_RATIO_MAX 1
-+#define STF_ISP_REG_OFFSET_MAX 0x0fff
-+#define STF_ISP_REG_DELAY_MAX 100
-+
-+/* isp registers */
-+#define ISP_REG_CSI_INPUT_EN_AND_STATUS 0x000
-+#define CSI_SCD_ERR BIT(6)
-+#define CSI_ITU656_ERR BIT(4)
-+#define CSI_ITU656_F BIT(3)
-+#define CSI_SCD_DONE BIT(2)
-+#define CSI_BUSY_S BIT(1)
-+#define CSI_EN_S BIT(0)
-+
-+#define ISP_REG_CSIINTS 0x008
-+#define CSI_INTS(n) ((n) << 16)
-+#define CSI_SHA_M(n) ((n) << 0)
-+#define CSI_INTS_MASK GENMASK(17, 16)
-+
-+#define ISP_REG_CSI_MODULE_CFG 0x010
-+#define CSI_DUMP_EN BIT(19)
-+#define CSI_VS_EN BIT(18)
-+#define CSI_SC_EN BIT(17)
-+#define CSI_OBA_EN BIT(16)
-+#define CSI_AWB_EN BIT(7)
-+#define CSI_LCCF_EN BIT(6)
-+#define CSI_OECFHM_EN BIT(5)
-+#define CSI_OECF_EN BIT(4)
-+#define CSI_LCBQ_EN BIT(3)
-+#define CSI_OBC_EN BIT(2)
-+#define CSI_DEC_EN BIT(1)
-+#define CSI_DC_EN BIT(0)
-+
-+#define ISP_REG_SENSOR 0x014
-+#define DVP_SYNC_POL(n) ((n) << 2)
-+#define ITU656_EN(n) ((n) << 1)
-+#define IMAGER_SEL(n) ((n) << 0)
-+
-+#define ISP_REG_RAW_FORMAT_CFG 0x018
-+#define SMY13(n) ((n) << 14)
-+#define SMY12(n) ((n) << 12)
-+#define SMY11(n) ((n) << 10)
-+#define SMY10(n) ((n) << 8)
-+#define SMY3(n) ((n) << 6)
-+#define SMY2(n) ((n) << 4)
-+#define SMY1(n) ((n) << 2)
-+#define SMY0(n) ((n) << 0)
-+
-+#define ISP_REG_PIC_CAPTURE_START_CFG 0x01c
-+#define VSTART_CAP(n) ((n) << 16)
-+#define HSTART_CAP(n) ((n) << 0)
-+
-+#define ISP_REG_PIC_CAPTURE_END_CFG 0x020
-+#define VEND_CAP(n) ((n) << 16)
-+#define HEND_CAP(n) ((n) << 0)
-+
-+#define ISP_REG_DUMP_CFG_0 0x024
-+#define ISP_REG_DUMP_CFG_1 0x028
-+#define DUMP_ID(n) ((n) << 24)
-+#define DUMP_SHT(n) ((n) << 20)
-+#define DUMP_BURST_LEN(n) ((n) << 16)
-+#define DUMP_SD(n) ((n) << 0)
-+#define DUMP_BURST_LEN_MASK GENMASK(17, 16)
-+#define DUMP_SD_MASK GENMASK(15, 0)
-+
-+#define ISP_REG_DEC_CFG 0x030
-+#define DEC_V_KEEP(n) ((n) << 24)
-+#define DEC_V_PERIOD(n) ((n) << 16)
-+#define DEC_H_KEEP(n) ((n) << 8)
-+#define DEC_H_PERIOD(n) ((n) << 0)
-+
-+#define ISP_REG_OBC_CFG 0x034
-+#define OBC_W_H(y) ((y) << 4)
-+#define OBC_W_W(x) ((x) << 0)
-+
-+#define ISP_REG_DC_CFG_1 0x044
-+#define DC_AXI_ID(n) ((n) << 0)
-+
-+#define ISP_REG_LCCF_CFG_0 0x050
-+#define Y_DISTANCE(y) ((y) << 16)
-+#define X_DISTANCE(x) ((x) << 16)
-+
-+#define ISP_REG_LCCF_CFG_1 0x058
-+#define LCCF_MAX_DIS(n) ((n) << 0)
-+
-+#define ISP_REG_LCBQ_CFG_0 0x074
-+#define H_LCBQ(y) ((y) << 12)
-+#define W_LCBQ(x) ((x) << 8)
-+
-+#define ISP_REG_LCBQ_CFG_1 0x07c
-+#define Y_COOR(y) ((y) << 16)
-+#define X_COOR(x) ((x) << 0)
-+
-+#define ISP_REG_OECF_X0_CFG0 0x100
-+#define ISP_REG_OECF_X0_CFG1 0x104
-+#define ISP_REG_OECF_X0_CFG2 0x108
-+#define ISP_REG_OECF_X0_CFG3 0x10c
-+#define ISP_REG_OECF_X0_CFG4 0x110
-+#define ISP_REG_OECF_X0_CFG5 0x114
-+#define ISP_REG_OECF_X0_CFG6 0x118
-+#define ISP_REG_OECF_X0_CFG7 0x11c
-+
-+#define ISP_REG_OECF_Y3_CFG0 0x1e0
-+#define ISP_REG_OECF_Y3_CFG1 0x1e4
-+#define ISP_REG_OECF_Y3_CFG2 0x1e8
-+#define ISP_REG_OECF_Y3_CFG3 0x1ec
-+#define ISP_REG_OECF_Y3_CFG4 0x1f0
-+#define ISP_REG_OECF_Y3_CFG5 0x1f4
-+#define ISP_REG_OECF_Y3_CFG6 0x1f8
-+#define ISP_REG_OECF_Y3_CFG7 0x1fc
-+
-+#define ISP_REG_OECF_S0_CFG0 0x200
-+#define ISP_REG_OECF_S3_CFG7 0x27c
-+#define OCEF_PAR_H(n) ((n) << 16)
-+#define OCEF_PAR_L(n) ((n) << 0)
-+
-+#define ISP_REG_AWB_X0_CFG_0 0x280
-+#define ISP_REG_AWB_X0_CFG_1 0x284
-+#define ISP_REG_AWB_X1_CFG_0 0x288
-+#define ISP_REG_AWB_X1_CFG_1 0x28c
-+#define ISP_REG_AWB_X2_CFG_0 0x290
-+#define ISP_REG_AWB_X2_CFG_1 0x294
-+#define ISP_REG_AWB_X3_CFG_0 0x298
-+#define ISP_REG_AWB_X3_CFG_1 0x29c
-+#define AWB_X_SYMBOL_H(n) ((n) << 16)
-+#define AWB_X_SYMBOL_L(n) ((n) << 0)
-+
-+#define ISP_REG_AWB_Y0_CFG_0 0x2a0
-+#define ISP_REG_AWB_Y0_CFG_1 0x2a4
-+#define ISP_REG_AWB_Y1_CFG_0 0x2a8
-+#define ISP_REG_AWB_Y1_CFG_1 0x2ac
-+#define ISP_REG_AWB_Y2_CFG_0 0x2b0
-+#define ISP_REG_AWB_Y2_CFG_1 0x2b4
-+#define ISP_REG_AWB_Y3_CFG_0 0x2b8
-+#define ISP_REG_AWB_Y3_CFG_1 0x2bc
-+#define AWB_Y_SYMBOL_H(n) ((n) << 16)
-+#define AWB_Y_SYMBOL_L(n) ((n) << 0)
-+
-+#define ISP_REG_AWB_S0_CFG_0 0x2c0
-+#define ISP_REG_AWB_S0_CFG_1 0x2c4
-+#define ISP_REG_AWB_S1_CFG_0 0x2c8
-+#define ISP_REG_AWB_S1_CFG_1 0x2cc
-+#define ISP_REG_AWB_S2_CFG_0 0x2d0
-+#define ISP_REG_AWB_S2_CFG_1 0x2d4
-+#define ISP_REG_AWB_S3_CFG_0 0x2d8
-+#define ISP_REG_AWB_S3_CFG_1 0x2dc
-+#define AWB_S_SYMBOL_H(n) ((n) << 16)
-+#define AWB_S_SYMBOL_L(n) ((n) << 0)
-+
-+#define ISP_REG_OBCG_CFG_0 0x2e0
-+#define ISP_REG_OBCG_CFG_1 0x2e4
-+#define ISP_REG_OBCG_CFG_2 0x2e8
-+#define ISP_REG_OBCG_CFG_3 0x2ec
-+#define ISP_REG_OBCO_CFG_0 0x2f0
-+#define ISP_REG_OBCO_CFG_1 0x2f4
-+#define ISP_REG_OBCO_CFG_2 0x2f8
-+#define ISP_REG_OBCO_CFG_3 0x2fc
-+#define GAIN_D_POINT(x) ((x) << 24)
-+#define GAIN_C_POINT(x) ((x) << 16)
-+#define GAIN_B_POINT(x) ((x) << 8)
-+#define GAIN_A_POINT(x) ((x) << 0)
-+#define OFFSET_D_POINT(x) ((x) << 24)
-+#define OFFSET_C_POINT(x) ((x) << 16)
-+#define OFFSET_B_POINT(x) ((x) << 8)
-+#define OFFSET_A_POINT(x) ((x) << 0)
-+
-+#define ISP_REG_ISP_CTRL_0 0xa00
-+#define ISPC_SCFEINT BIT(27)
-+#define ISPC_VSFWINT BIT(26)
-+#define ISPC_VSINT BIT(25)
-+#define ISPC_INTS BIT(24)
-+#define ISPC_ENUO BIT(20)
-+#define ISPC_ENLS BIT(17)
-+#define ISPC_ENSS1 BIT(12)
-+#define ISPC_ENSS0 BIT(11)
-+#define ISPC_RST BIT(1)
-+#define ISPC_EN BIT(0)
-+#define ISPC_RST_MASK BIT(1)
-+
-+#define ISP_REG_ISP_CTRL_1 0xa08
-+#define CTRL_SAT(n) ((n) << 28)
-+#define CTRL_DBC BIT(22)
-+#define CTRL_CTC BIT(21)
-+#define CTRL_YHIST BIT(20)
-+#define CTRL_YCURVE BIT(19)
-+#define CTRL_CTM BIT(18)
-+#define CTRL_BIYUV BIT(17)
-+#define CTRL_SCE BIT(8)
-+#define CTRL_EE BIT(7)
-+#define CTRL_CCE BIT(5)
-+#define CTRL_RGE BIT(4)
-+#define CTRL_CME BIT(3)
-+#define CTRL_AE BIT(2)
-+#define CTRL_CE BIT(1)
-+#define CTRL_SAT_MASK GENMASK(31, 28)
-+
-+#define ISP_REG_PIPELINE_XY_SIZE 0xa0c
-+#define H_ACT_CAP(n) ((n) << 16)
-+#define W_ACT_CAP(n) ((n) << 0)
-+
-+#define ISP_REG_ICTC 0xa10
-+#define GF_MODE(n) ((n) << 30)
-+#define MAXGT(n) ((n) << 16)
-+#define MINGT(n) ((n) << 0)
-+
-+#define ISP_REG_IDBC 0xa14
-+#define BADGT(n) ((n) << 16)
-+#define BADXT(n) ((n) << 0)
-+
-+#define ISP_REG_ICFAM 0xa1c
-+#define CROSS_COV(n) ((n) << 4)
-+#define HV_W(n) ((n) << 0)
-+
-+#define ISP_REG_CS_GAIN 0xa30
-+#define CMAD(n) ((n) << 16)
-+#define CMAB(n) ((n) << 0)
-+
-+#define ISP_REG_CS_THRESHOLD 0xa34
-+#define CMD(n) ((n) << 16)
-+#define CMB(n) ((n) << 0)
-+
-+#define ISP_REG_CS_OFFSET 0xa38
-+#define VOFF(n) ((n) << 16)
-+#define UOFF(n) ((n) << 0)
-+
-+#define ISP_REG_CS_HUE_F 0xa3c
-+#define SIN(n) ((n) << 16)
-+#define COS(n) ((n) << 0)
-+
-+#define ISP_REG_CS_SCALE 0xa40
-+#define CMSF(n) ((n) << 0)
-+
-+#define ISP_REG_IESHD 0xa50
-+#define SHAD_UP_M BIT(1)
-+#define SHAD_UP_EN BIT(0)
-+
-+#define ISP_REG_YADJ0 0xa54
-+#define YOIR(n) ((n) << 16)
-+#define YIMIN(n) ((n) << 0)
-+
-+#define ISP_REG_YADJ1 0xa58
-+#define YOMAX(n) ((n) << 16)
-+#define YOMIN(n) ((n) << 0)
-+
-+#define ISP_REG_Y_PLANE_START_ADDR 0xa80
-+#define ISP_REG_UV_PLANE_START_ADDR 0xa84
-+
-+#define ISP_REG_STRIDE 0xa88
-+#define IMG_STR(n) ((n) << 0)
-+
-+#define ISP_REG_ITIIWSR 0xb20
-+#define ITI_HSIZE(n) ((n) << 16)
-+#define ITI_WSIZE(n) ((n) << 0)
-+
-+#define ISP_REG_ITIDWLSR 0xb24
-+#define ITI_WSTRIDE(n) ((n) << 0)
-+
-+#define ISP_REG_ITIPDFR 0xb38
-+#define ITI_PACKAGE_FMT(n) ((n) << 0)
-+
-+#define ISP_REG_ITIDRLSR 0xb3C
-+#define ITI_STRIDE_L(n) ((n) << 0)
-+
-+#define ISP_REG_DNYUV_YSWR0 0xc00
-+#define ISP_REG_DNYUV_YSWR1 0xc04
-+#define ISP_REG_DNYUV_CSWR0 0xc08
-+#define ISP_REG_DNYUV_CSWR1 0xc0c
-+#define YUVSW5(n) ((n) << 20)
-+#define YUVSW4(n) ((n) << 16)
-+#define YUVSW3(n) ((n) << 12)
-+#define YUVSW2(n) ((n) << 8)
-+#define YUVSW1(n) ((n) << 4)
-+#define YUVSW0(n) ((n) << 0)
-+
-+#define ISP_REG_DNYUV_YDR0 0xc10
-+#define ISP_REG_DNYUV_YDR1 0xc14
-+#define ISP_REG_DNYUV_YDR2 0xc18
-+#define ISP_REG_DNYUV_CDR0 0xc1c
-+#define ISP_REG_DNYUV_CDR1 0xc20
-+#define ISP_REG_DNYUV_CDR2 0xc24
-+#define CURVE_D_H(n) ((n) << 16)
-+#define CURVE_D_L(n) ((n) << 0)
-+
-+#define ISP_REG_ICAMD_0 0xc40
-+#define DNRM_F(n) ((n) << 16)
-+#define ISP_REG_ICAMD_12 0xc70
-+#define ISP_REG_ICAMD_20 0xc90
-+#define ISP_REG_ICAMD_24 0xca0
-+#define ISP_REG_ICAMD_25 0xca4
-+#define CCM_M_DAT(n) ((n) << 0)
-+
-+#define ISP_REG_GAMMA_VAL0 0xe00
-+#define ISP_REG_GAMMA_VAL1 0xe04
-+#define ISP_REG_GAMMA_VAL2 0xe08
-+#define ISP_REG_GAMMA_VAL3 0xe0c
-+#define ISP_REG_GAMMA_VAL4 0xe10
-+#define ISP_REG_GAMMA_VAL5 0xe14
-+#define ISP_REG_GAMMA_VAL6 0xe18
-+#define ISP_REG_GAMMA_VAL7 0xe1c
-+#define ISP_REG_GAMMA_VAL8 0xe20
-+#define ISP_REG_GAMMA_VAL9 0xe24
-+#define ISP_REG_GAMMA_VAL10 0xe28
-+#define ISP_REG_GAMMA_VAL11 0xe2c
-+#define ISP_REG_GAMMA_VAL12 0xe30
-+#define ISP_REG_GAMMA_VAL13 0xe34
-+#define ISP_REG_GAMMA_VAL14 0xe38
-+#define GAMMA_S_VAL(n) ((n) << 16)
-+#define GAMMA_VAL(n) ((n) << 0)
-+
-+#define ISP_REG_R2Y_0 0xe40
-+#define ISP_REG_R2Y_1 0xe44
-+#define ISP_REG_R2Y_2 0xe48
-+#define ISP_REG_R2Y_3 0xe4c
-+#define ISP_REG_R2Y_4 0xe50
-+#define ISP_REG_R2Y_5 0xe54
-+#define ISP_REG_R2Y_6 0xe58
-+#define ISP_REG_R2Y_7 0xe5c
-+#define ISP_REG_R2Y_8 0xe60
-+#define CSC_M(n) ((n) << 0)
-+
-+#define ISP_REG_SHARPEN0 0xe80
-+#define ISP_REG_SHARPEN1 0xe84
-+#define ISP_REG_SHARPEN2 0xe88
-+#define ISP_REG_SHARPEN3 0xe8c
-+#define ISP_REG_SHARPEN4 0xe90
-+#define ISP_REG_SHARPEN5 0xe94
-+#define ISP_REG_SHARPEN6 0xe98
-+#define ISP_REG_SHARPEN7 0xe9c
-+#define ISP_REG_SHARPEN8 0xea0
-+#define ISP_REG_SHARPEN9 0xea4
-+#define ISP_REG_SHARPEN10 0xea8
-+#define ISP_REG_SHARPEN11 0xeac
-+#define ISP_REG_SHARPEN12 0xeb0
-+#define ISP_REG_SHARPEN13 0xeb4
-+#define ISP_REG_SHARPEN14 0xeb8
-+#define S_DELTA(n) ((n) << 16)
-+#define S_WEIGHT(n) ((n) << 8)
-+
-+#define ISP_REG_SHARPEN_FS0 0xebc
-+#define ISP_REG_SHARPEN_FS1 0xec0
-+#define ISP_REG_SHARPEN_FS2 0xec4
-+#define ISP_REG_SHARPEN_FS3 0xec8
-+#define ISP_REG_SHARPEN_FS4 0xecc
-+#define ISP_REG_SHARPEN_FS5 0xed0
-+#define S_FACTOR(n) ((n) << 24)
-+#define S_SLOPE(n) ((n) << 0)
-+
-+#define ISP_REG_SHARPEN_WN 0xed4
-+#define PDIRF(n) ((n) << 28)
-+#define NDIRF(n) ((n) << 24)
-+#define WSUM(n) ((n) << 0)
-+
-+#define ISP_REG_IUVS1 0xed8
-+#define UVDIFF2(n) ((n) << 16)
-+#define UVDIFF1(n) ((n) << 0)
-+
-+#define ISP_REG_IUVS2 0xedc
-+#define UVF(n) ((n) << 24)
-+#define UVSLOPE(n) ((n) << 0)
-+
-+#define ISP_REG_IUVCKS1 0xee0
-+#define UVCKDIFF2(n) ((n) << 16)
-+#define UVCKDIFF1(n) ((n) << 0)
-+
-+#define ISP_REG_IUVCKS2 0xee4
-+#define UVCKSLOPE(n) ((n) << 0)
-+
-+#define ISP_REG_ISHRPET 0xee8
-+#define TH(n) ((n) << 8)
-+#define EN(n) ((n) << 0)
-+
-+#define ISP_REG_YCURVE_0 0xf00
-+#define ISP_REG_YCURVE_63 0xffc
-+#define L_PARAM(n) ((n) << 0)
-+
-+#define IMAGE_MAX_WIDTH 1920
-+#define IMAGE_MAX_HEIGH 1080
-+
-+/* The output line of ISP */
-+enum isp_line_id {
-+ STF_ISP_LINE_INVALID = -1,
-+ STF_ISP_LINE_SRC = 1,
-+ STF_ISP_LINE_MAX = STF_ISP_LINE_SRC
-+};
-+
-+/* pad id for media framework */
-+enum isp_pad_id {
-+ STF_ISP_PAD_SINK = 0,
-+ STF_ISP_PAD_SRC,
-+ STF_ISP_PAD_MAX
-+};
-+
-+enum {
-+ EN_INT_NONE = 0,
-+ EN_INT_ISP_DONE = (0x1 << 24),
-+ EN_INT_CSI_DONE = (0x1 << 25),
-+ EN_INT_SC_DONE = (0x1 << 26),
-+ EN_INT_LINE_INT = (0x1 << 27),
-+ EN_INT_ALL = (0xF << 24),
-+};
-+
-+enum {
-+ INTERFACE_DVP = 0,
-+ INTERFACE_CSI,
-+};
-+
-+struct isp_format {
-+ u32 code;
-+ u8 bpp;
-+};
-+
-+struct isp_format_table {
-+ const struct isp_format *fmts;
-+ int nfmts;
-+};
-+
-+struct regval_t {
-+ u32 addr;
-+ u32 val;
-+ u32 delay_ms;
-+};
-+
-+struct reg_table {
-+ const struct regval_t *regval;
-+ int regval_num;
-+};
-+
-+struct stf_isp_crop {
-+ struct v4l2_rect rect;
-+ u32 bpp;
-+};
-+
-+struct stf_isp_dev {
-+ enum stf_subdev_type sdev_type; /* This member must be first */
-+ struct stfcamss *stfcamss;
-+ struct v4l2_subdev subdev;
-+ struct media_pad pads[STF_ISP_PAD_MAX];
-+ struct v4l2_mbus_framefmt fmt[STF_ISP_PAD_MAX];
-+ struct stf_isp_crop rect[STF_ISP_PAD_MAX];
-+ const struct isp_format_table *formats;
-+ unsigned int nformats;
-+ struct mutex power_lock; /* serialize power control*/
-+ int power_count;
-+ struct mutex stream_lock; /* serialize stream control */
-+ int stream_count;
-+};
-+
-+int stf_isp_clk_enable(struct stf_isp_dev *isp_dev);
-+int stf_isp_clk_disable(struct stf_isp_dev *isp_dev);
-+int stf_isp_reset(struct stf_isp_dev *isp_dev);
-+void stf_isp_init_cfg(struct stf_isp_dev *isp_dev);
-+void stf_isp_settings(struct stf_isp_dev *isp_dev,
-+ struct stf_isp_crop *crop_array, u32 mcode);
-+void stf_isp_stream_set(struct stf_isp_dev *isp_dev);
-+int stf_isp_subdev_init(struct stfcamss *stfcamss);
-+int stf_isp_register(struct stf_isp_dev *isp_dev, struct v4l2_device *v4l2_dev);
-+int stf_isp_unregister(struct stf_isp_dev *isp_dev);
-+
-+#endif /* STF_ISP_H */
---- /dev/null
-+++ b/drivers/media/platform/starfive/stf_isp_hw_ops.c
-@@ -0,0 +1,452 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * stf_isp_hw_ops.c
-+ *
-+ * Register interface file for StarFive ISP driver
-+ *
-+ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
-+ *
-+ */
-+
-+#include "stf_camss.h"
-+
-+static void stf_isp_config_obc(struct stfcamss *stfcamss)
-+{
-+ u32 reg_val, reg_add;
-+
-+ stf_isp_reg_write(stfcamss, ISP_REG_OBC_CFG, OBC_W_H(11) | OBC_W_W(11));
-+
-+ reg_val = GAIN_D_POINT(0x40) | GAIN_C_POINT(0x40) |
-+ GAIN_B_POINT(0x40) | GAIN_A_POINT(0x40);
-+ for (reg_add = ISP_REG_OBCG_CFG_0; reg_add <= ISP_REG_OBCG_CFG_3;) {
-+ stf_isp_reg_write(stfcamss, reg_add, reg_val);
-+ reg_add += 4;
-+ }
-+
-+ reg_val = OFFSET_D_POINT(0) | OFFSET_C_POINT(0) |
-+ OFFSET_B_POINT(0) | OFFSET_A_POINT(0);
-+ for (reg_add = ISP_REG_OBCO_CFG_0; reg_add <= ISP_REG_OBCO_CFG_3;) {
-+ stf_isp_reg_write(stfcamss, reg_add, reg_val);
-+ reg_add += 4;
-+ }
-+}
-+
-+static void stf_isp_config_oecf(struct stfcamss *stfcamss)
-+{
-+ u32 reg_add, par_val;
-+ u16 par_h, par_l;
-+
-+ par_h = 0x10; par_l = 0;
-+ par_val = OCEF_PAR_H(par_h) | OCEF_PAR_L(par_l);
-+ for (reg_add = ISP_REG_OECF_X0_CFG0; reg_add <= ISP_REG_OECF_Y3_CFG0;) {
-+ stf_isp_reg_write(stfcamss, reg_add, par_val);
-+ reg_add += 0x20;
-+ }
-+
-+ par_h = 0x40; par_l = 0x20;
-+ par_val = OCEF_PAR_H(par_h) | OCEF_PAR_L(par_l);
-+ for (reg_add = ISP_REG_OECF_X0_CFG1; reg_add <= ISP_REG_OECF_Y3_CFG1;) {
-+ stf_isp_reg_write(stfcamss, reg_add, par_val);
-+ reg_add += 0x20;
-+ }
-+
-+ par_h = 0x80; par_l = 0x60;
-+ par_val = OCEF_PAR_H(par_h) | OCEF_PAR_L(par_l);
-+ for (reg_add = ISP_REG_OECF_X0_CFG2; reg_add <= ISP_REG_OECF_Y3_CFG2;) {
-+ stf_isp_reg_write(stfcamss, reg_add, par_val);
-+ reg_add += 0x20;
-+ }
-+
-+ par_h = 0xc0; par_l = 0xa0;
-+ par_val = OCEF_PAR_H(par_h) | OCEF_PAR_L(par_l);
-+ for (reg_add = ISP_REG_OECF_X0_CFG3; reg_add <= ISP_REG_OECF_Y3_CFG3;) {
-+ stf_isp_reg_write(stfcamss, reg_add, par_val);
-+ reg_add += 0x20;
-+ }
-+
-+ par_h = 0x100; par_l = 0xe0;
-+ par_val = OCEF_PAR_H(par_h) | OCEF_PAR_L(par_l);
-+ for (reg_add = ISP_REG_OECF_X0_CFG4; reg_add <= ISP_REG_OECF_Y3_CFG4;) {
-+ stf_isp_reg_write(stfcamss, reg_add, par_val);
-+ reg_add += 0x20;
-+ }
-+
-+ par_h = 0x200; par_l = 0x180;
-+ par_val = OCEF_PAR_H(par_h) | OCEF_PAR_L(par_l);
-+ for (reg_add = ISP_REG_OECF_X0_CFG5; reg_add <= ISP_REG_OECF_Y3_CFG5;) {
-+ stf_isp_reg_write(stfcamss, reg_add, par_val);
-+ reg_add += 0x20;
-+ }
-+
-+ par_h = 0x300; par_l = 0x280;
-+ par_val = OCEF_PAR_H(par_h) | OCEF_PAR_L(par_l);
-+ for (reg_add = ISP_REG_OECF_X0_CFG6; reg_add <= ISP_REG_OECF_Y3_CFG6;) {
-+ stf_isp_reg_write(stfcamss, reg_add, par_val);
-+ reg_add += 0x20;
-+ }
-+
-+ par_h = 0x3fe; par_l = 0x380;
-+ par_val = OCEF_PAR_H(par_h) | OCEF_PAR_L(par_l);
-+ for (reg_add = ISP_REG_OECF_X0_CFG7; reg_add <= ISP_REG_OECF_Y3_CFG7;) {
-+ stf_isp_reg_write(stfcamss, reg_add, par_val);
-+ reg_add += 0x20;
-+ }
-+
-+ par_h = 0x80; par_l = 0x80;
-+ par_val = OCEF_PAR_H(par_h) | OCEF_PAR_L(par_l);
-+ for (reg_add = ISP_REG_OECF_S0_CFG0; reg_add <= ISP_REG_OECF_S3_CFG7;) {
-+ stf_isp_reg_write(stfcamss, reg_add, par_val);
-+ reg_add += 4;
-+ }
-+}
-+
-+static void stf_isp_config_awb(struct stfcamss *stfcamss)
-+{
-+ u32 reg_val, reg_add;
-+ u16 symbol_h, symbol_l;
-+
-+ symbol_h = 0x0; symbol_l = 0x0;
-+ reg_val = AWB_X_SYMBOL_H(symbol_h) | AWB_X_SYMBOL_L(symbol_l);
-+
-+ for (reg_add = ISP_REG_AWB_X0_CFG_0; reg_add <= ISP_REG_AWB_X3_CFG_1;) {
-+ stf_isp_reg_write(stfcamss, reg_add, reg_val);
-+ reg_add += 4;
-+ }
-+
-+ symbol_h = 0x0, symbol_l = 0x0;
-+ reg_val = AWB_Y_SYMBOL_H(symbol_h) | AWB_Y_SYMBOL_L(symbol_l);
-+
-+ for (reg_add = ISP_REG_AWB_Y0_CFG_0; reg_add <= ISP_REG_AWB_Y3_CFG_1;) {
-+ stf_isp_reg_write(stfcamss, reg_add, reg_val);
-+ reg_add += 4;
-+ }
-+
-+ symbol_h = 0x80, symbol_l = 0x80;
-+ reg_val = AWB_S_SYMBOL_H(symbol_h) | AWB_S_SYMBOL_L(symbol_l);
-+
-+ for (reg_add = ISP_REG_AWB_S0_CFG_0; reg_add <= ISP_REG_AWB_S3_CFG_1;) {
-+ stf_isp_reg_write(stfcamss, reg_add, reg_val);
-+ reg_add += 4;
-+ }
-+}
-+
-+static void stf_isp_config_grgb(struct stfcamss *stfcamss)
-+{
-+ stf_isp_reg_write(stfcamss, ISP_REG_ICTC,
-+ GF_MODE(1) | MAXGT(0x140) | MINGT(0x40));
-+ stf_isp_reg_write(stfcamss, ISP_REG_IDBC, BADGT(0x200) | BADXT(0x200));
-+}
-+
-+static void stf_isp_config_cfa(struct stfcamss *stfcamss)
-+{
-+ stf_isp_reg_write(stfcamss, ISP_REG_RAW_FORMAT_CFG,
-+ SMY13(0) | SMY12(1) | SMY11(0) | SMY10(1) | SMY3(2) |
-+ SMY2(3) | SMY1(2) | SMY0(3));
-+ stf_isp_reg_write(stfcamss, ISP_REG_ICFAM, CROSS_COV(3) | HV_W(2));
-+}
-+
-+static void stf_isp_config_ccm(struct stfcamss *stfcamss)
-+{
-+ u32 reg_add;
-+
-+ stf_isp_reg_write(stfcamss, ISP_REG_ICAMD_0, DNRM_F(6) | CCM_M_DAT(0));
-+
-+ for (reg_add = ISP_REG_ICAMD_12; reg_add <= ISP_REG_ICAMD_20;) {
-+ stf_isp_reg_write(stfcamss, reg_add, CCM_M_DAT(0x80));
-+ reg_add += 0x10;
-+ }
-+
-+ stf_isp_reg_write(stfcamss, ISP_REG_ICAMD_24, CCM_M_DAT(0x700));
-+ stf_isp_reg_write(stfcamss, ISP_REG_ICAMD_25, CCM_M_DAT(0x200));
-+}
-+
-+static void stf_isp_config_gamma(struct stfcamss *stfcamss)
-+{
-+ u32 reg_val, reg_add;
-+ u16 gamma_slope_v, gamma_v;
-+
-+ gamma_slope_v = 0x2400; gamma_v = 0x0;
-+ reg_val = GAMMA_S_VAL(gamma_slope_v) | GAMMA_VAL(gamma_v);
-+ stf_isp_reg_write(stfcamss, ISP_REG_GAMMA_VAL0, reg_val);
-+
-+ gamma_slope_v = 0x800; gamma_v = 0x20;
-+ for (reg_add = ISP_REG_GAMMA_VAL1; reg_add <= ISP_REG_GAMMA_VAL7;) {
-+ reg_val = GAMMA_S_VAL(gamma_slope_v) | GAMMA_VAL(gamma_v);
-+ stf_isp_reg_write(stfcamss, reg_add, reg_val);
-+ reg_add += 4;
-+ gamma_v += 0x20;
-+ }
-+
-+ gamma_v = 0x100;
-+ for (reg_add = ISP_REG_GAMMA_VAL8; reg_add <= ISP_REG_GAMMA_VAL13;) {
-+ reg_val = GAMMA_S_VAL(gamma_slope_v) | GAMMA_VAL(gamma_v);
-+ stf_isp_reg_write(stfcamss, reg_add, reg_val);
-+ reg_add += 4;
-+ gamma_v += 0x80;
-+ }
-+
-+ gamma_v = 0x3fe;
-+ reg_val = GAMMA_S_VAL(gamma_slope_v) | GAMMA_VAL(gamma_v);
-+ stf_isp_reg_write(stfcamss, ISP_REG_GAMMA_VAL14, reg_val);
-+}
-+
-+static void stf_isp_config_r2y(struct stfcamss *stfcamss)
-+{
-+ stf_isp_reg_write(stfcamss, ISP_REG_R2Y_0, CSC_M(0x4C));
-+ stf_isp_reg_write(stfcamss, ISP_REG_R2Y_1, CSC_M(0x97));
-+ stf_isp_reg_write(stfcamss, ISP_REG_R2Y_2, CSC_M(0x1d));
-+ stf_isp_reg_write(stfcamss, ISP_REG_R2Y_3, CSC_M(0x1d5));
-+ stf_isp_reg_write(stfcamss, ISP_REG_R2Y_4, CSC_M(0x1ac));
-+ stf_isp_reg_write(stfcamss, ISP_REG_R2Y_5, CSC_M(0x80));
-+ stf_isp_reg_write(stfcamss, ISP_REG_R2Y_6, CSC_M(0x80));
-+ stf_isp_reg_write(stfcamss, ISP_REG_R2Y_7, CSC_M(0x194));
-+ stf_isp_reg_write(stfcamss, ISP_REG_R2Y_8, CSC_M(0x1ec));
-+}
-+
-+static void stf_isp_config_y_curve(struct stfcamss *stfcamss)
-+{
-+ u32 reg_add;
-+ u16 y_curve;
-+
-+ y_curve = 0x0;
-+ for (reg_add = ISP_REG_YCURVE_0; reg_add <= ISP_REG_YCURVE_63;) {
-+ stf_isp_reg_write(stfcamss, reg_add, y_curve);
-+ reg_add += 4;
-+ y_curve += 0x10;
-+ }
-+}
-+
-+static void stf_isp_config_sharpen(struct stfcamss *sc)
-+{
-+ u32 reg_add;
-+
-+ stf_isp_reg_write(sc, ISP_REG_SHARPEN0, S_DELTA(0x7) | S_WEIGHT(0xf));
-+ stf_isp_reg_write(sc, ISP_REG_SHARPEN1, S_DELTA(0x18) | S_WEIGHT(0xf));
-+ stf_isp_reg_write(sc, ISP_REG_SHARPEN2, S_DELTA(0x80) | S_WEIGHT(0xf));
-+ stf_isp_reg_write(sc, ISP_REG_SHARPEN3, S_DELTA(0x100) | S_WEIGHT(0xf));
-+ stf_isp_reg_write(sc, ISP_REG_SHARPEN4, S_DELTA(0x10) | S_WEIGHT(0xf));
-+ stf_isp_reg_write(sc, ISP_REG_SHARPEN5, S_DELTA(0x60) | S_WEIGHT(0xf));
-+ stf_isp_reg_write(sc, ISP_REG_SHARPEN6, S_DELTA(0x100) | S_WEIGHT(0xf));
-+ stf_isp_reg_write(sc, ISP_REG_SHARPEN7, S_DELTA(0x190) | S_WEIGHT(0xf));
-+ stf_isp_reg_write(sc, ISP_REG_SHARPEN8, S_DELTA(0x0) | S_WEIGHT(0xf));
-+
-+ for (reg_add = ISP_REG_SHARPEN9; reg_add <= ISP_REG_SHARPEN14;) {
-+ stf_isp_reg_write(sc, reg_add, S_WEIGHT(0xf));
-+ reg_add += 4;
-+ }
-+
-+ for (reg_add = ISP_REG_SHARPEN_FS0; reg_add <= ISP_REG_SHARPEN_FS5;) {
-+ stf_isp_reg_write(sc, reg_add, S_FACTOR(0x10) | S_SLOPE(0x0));
-+ reg_add += 4;
-+ }
-+
-+ stf_isp_reg_write(sc, ISP_REG_SHARPEN_WN,
-+ PDIRF(0x8) | NDIRF(0x8) | WSUM(0xd7c));
-+ stf_isp_reg_write(sc, ISP_REG_IUVS1, UVDIFF2(0xC0) | UVDIFF1(0x40));
-+ stf_isp_reg_write(sc, ISP_REG_IUVS2, UVF(0xff) | UVSLOPE(0x0));
-+ stf_isp_reg_write(sc, ISP_REG_IUVCKS1,
-+ UVCKDIFF2(0xa0) | UVCKDIFF1(0x40));
-+}
-+
-+static void stf_isp_config_dnyuv(struct stfcamss *stfcamss)
-+{
-+ u32 reg_val;
-+
-+ reg_val = YUVSW5(7) | YUVSW4(7) | YUVSW3(7) | YUVSW2(7) |
-+ YUVSW1(7) | YUVSW0(7);
-+ stf_isp_reg_write(stfcamss, ISP_REG_DNYUV_YSWR0, reg_val);
-+ stf_isp_reg_write(stfcamss, ISP_REG_DNYUV_CSWR0, reg_val);
-+
-+ reg_val = YUVSW3(7) | YUVSW2(7) | YUVSW1(7) | YUVSW0(7);
-+ stf_isp_reg_write(stfcamss, ISP_REG_DNYUV_YSWR1, reg_val);
-+ stf_isp_reg_write(stfcamss, ISP_REG_DNYUV_CSWR1, reg_val);
-+
-+ reg_val = CURVE_D_H(0x60) | CURVE_D_L(0x40);
-+ stf_isp_reg_write(stfcamss, ISP_REG_DNYUV_YDR0, reg_val);
-+ stf_isp_reg_write(stfcamss, ISP_REG_DNYUV_CDR0, reg_val);
-+
-+ reg_val = CURVE_D_H(0xd8) | CURVE_D_L(0x90);
-+ stf_isp_reg_write(stfcamss, ISP_REG_DNYUV_YDR1, reg_val);
-+ stf_isp_reg_write(stfcamss, ISP_REG_DNYUV_CDR1, reg_val);
-+
-+ reg_val = CURVE_D_H(0x1e6) | CURVE_D_L(0x144);
-+ stf_isp_reg_write(stfcamss, ISP_REG_DNYUV_YDR2, reg_val);
-+ stf_isp_reg_write(stfcamss, ISP_REG_DNYUV_CDR2, reg_val);
-+}
-+
-+static void stf_isp_config_sat(struct stfcamss *stfcamss)
-+{
-+ stf_isp_reg_write(stfcamss, ISP_REG_CS_GAIN, CMAD(0x0) | CMAB(0x100));
-+ stf_isp_reg_write(stfcamss, ISP_REG_CS_THRESHOLD, CMD(0x1f) | CMB(0x1));
-+ stf_isp_reg_write(stfcamss, ISP_REG_CS_OFFSET, VOFF(0x0) | UOFF(0x0));
-+ stf_isp_reg_write(stfcamss, ISP_REG_CS_HUE_F, SIN(0x0) | COS(0x100));
-+ stf_isp_reg_write(stfcamss, ISP_REG_CS_SCALE, CMSF(0x8));
-+ stf_isp_reg_write(stfcamss, ISP_REG_YADJ0, YOIR(0x401) | YIMIN(0x1));
-+ stf_isp_reg_write(stfcamss, ISP_REG_YADJ1, YOMAX(0x3ff) | YOMIN(0x1));
-+}
-+
-+int stf_isp_clk_enable(struct stf_isp_dev *isp_dev)
-+{
-+ struct stfcamss *stfcamss = isp_dev->stfcamss;
-+
-+ clk_prepare_enable(stfcamss->sys_clk[STF_CLK_WRAPPER_CLK_C].clk);
-+ reset_control_deassert(stfcamss->sys_rst[STF_RST_WRAPPER_C].rstc);
-+ reset_control_deassert(stfcamss->sys_rst[STF_RST_WRAPPER_P].rstc);
-+
-+ return 0;
-+}
-+
-+int stf_isp_clk_disable(struct stf_isp_dev *isp_dev)
-+{
-+ struct stfcamss *stfcamss = isp_dev->stfcamss;
-+
-+ reset_control_assert(stfcamss->sys_rst[STF_RST_WRAPPER_C].rstc);
-+ reset_control_assert(stfcamss->sys_rst[STF_RST_WRAPPER_P].rstc);
-+ clk_disable_unprepare(stfcamss->sys_clk[STF_CLK_WRAPPER_CLK_C].clk);
-+
-+ return 0;
-+}
-+
-+int stf_isp_reset(struct stf_isp_dev *isp_dev)
-+{
-+ stf_isp_reg_set_bit(isp_dev->stfcamss, ISP_REG_ISP_CTRL_0,
-+ ISPC_RST_MASK, ISPC_RST);
-+ stf_isp_reg_set_bit(isp_dev->stfcamss, ISP_REG_ISP_CTRL_0,
-+ ISPC_RST_MASK, 0);
-+
-+ return 0;
-+}
-+
-+void stf_isp_init_cfg(struct stf_isp_dev *isp_dev)
-+{
-+ stf_isp_reg_write(isp_dev->stfcamss, ISP_REG_DC_CFG_1, DC_AXI_ID(0x0));
-+ stf_isp_reg_write(isp_dev->stfcamss, ISP_REG_DEC_CFG,
-+ DEC_V_KEEP(0x0) |
-+ DEC_V_PERIOD(0x0) |
-+ DEC_H_KEEP(0x0) |
-+ DEC_H_PERIOD(0x0));
-+
-+ stf_isp_config_obc(isp_dev->stfcamss);
-+ stf_isp_config_oecf(isp_dev->stfcamss);
-+ stf_isp_config_awb(isp_dev->stfcamss);
-+ stf_isp_config_grgb(isp_dev->stfcamss);
-+ stf_isp_config_cfa(isp_dev->stfcamss);
-+ stf_isp_config_ccm(isp_dev->stfcamss);
-+ stf_isp_config_gamma(isp_dev->stfcamss);
-+ stf_isp_config_r2y(isp_dev->stfcamss);
-+ stf_isp_config_y_curve(isp_dev->stfcamss);
-+ stf_isp_config_sharpen(isp_dev->stfcamss);
-+ stf_isp_config_dnyuv(isp_dev->stfcamss);
-+ stf_isp_config_sat(isp_dev->stfcamss);
-+
-+ stf_isp_reg_write(isp_dev->stfcamss, ISP_REG_CSI_MODULE_CFG,
-+ CSI_DUMP_EN | CSI_SC_EN | CSI_AWB_EN |
-+ CSI_LCCF_EN | CSI_OECF_EN | CSI_OBC_EN | CSI_DEC_EN);
-+ stf_isp_reg_write(isp_dev->stfcamss, ISP_REG_ISP_CTRL_1,
-+ CTRL_SAT(1) | CTRL_DBC | CTRL_CTC | CTRL_YHIST |
-+ CTRL_YCURVE | CTRL_BIYUV | CTRL_SCE | CTRL_EE |
-+ CTRL_CCE | CTRL_RGE | CTRL_CME | CTRL_AE | CTRL_CE);
-+}
-+
-+static void stf_isp_config_crop(struct stfcamss *stfcamss,
-+ struct stf_isp_crop *crop)
-+{
-+ struct v4l2_rect *rect = &crop[STF_ISP_PAD_SRC].rect;
-+ u32 bpp = crop[STF_ISP_PAD_SRC].bpp;
-+ u32 val;
-+
-+ val = VSTART_CAP(rect->top) | HSTART_CAP(rect->left);
-+ stf_isp_reg_write(stfcamss, ISP_REG_PIC_CAPTURE_START_CFG, val);
-+
-+ val = VEND_CAP(rect->height + rect->top - 1) |
-+ HEND_CAP(rect->width + rect->left - 1);
-+ stf_isp_reg_write(stfcamss, ISP_REG_PIC_CAPTURE_END_CFG, val);
-+
-+ val = H_ACT_CAP(rect->height) | W_ACT_CAP(rect->width);
-+ stf_isp_reg_write(stfcamss, ISP_REG_PIPELINE_XY_SIZE, val);
-+
-+ val = ALIGN(rect->width * bpp / 8, STFCAMSS_FRAME_WIDTH_ALIGN_8);
-+ stf_isp_reg_write(stfcamss, ISP_REG_STRIDE, val);
-+}
-+
-+static void stf_isp_config_raw_fmt(struct stfcamss *stfcamss, u32 mcode)
-+{
-+ u32 val, val1;
-+
-+ switch (mcode) {
-+ case MEDIA_BUS_FMT_SRGGB10_1X10:
-+ case MEDIA_BUS_FMT_SRGGB8_1X8:
-+ /* 3 2 3 2 1 0 1 0 B Gb B Gb Gr R Gr R */
-+ val = SMY13(3) | SMY12(2) | SMY11(3) | SMY10(2) |
-+ SMY3(1) | SMY2(0) | SMY1(1) | SMY0(0);
-+ val1 = CTRL_SAT(0x0);
-+ break;
-+ case MEDIA_BUS_FMT_SGRBG10_1X10:
-+ case MEDIA_BUS_FMT_SGRBG8_1X8:
-+ /* 2 3 2 3 0 1 0 1, Gb B Gb B R Gr R Gr */
-+ val = SMY13(2) | SMY12(3) | SMY11(2) | SMY10(3) |
-+ SMY3(0) | SMY2(1) | SMY1(0) | SMY0(1);
-+ val1 = CTRL_SAT(0x2);
-+ break;
-+ case MEDIA_BUS_FMT_SGBRG10_1X10:
-+ case MEDIA_BUS_FMT_SGBRG8_1X8:
-+ /* 1 0 1 0 3 2 3 2, Gr R Gr R B Gb B Gb */
-+ val = SMY13(1) | SMY12(0) | SMY11(1) | SMY10(0) |
-+ SMY3(3) | SMY2(2) | SMY1(3) | SMY0(2);
-+ val1 = CTRL_SAT(0x3);
-+ break;
-+ case MEDIA_BUS_FMT_SBGGR10_1X10:
-+ case MEDIA_BUS_FMT_SBGGR8_1X8:
-+ /* 0 1 0 1 2 3 2 3 R Gr R Gr Gb B Gb B */
-+ val = SMY13(0) | SMY12(1) | SMY11(0) | SMY10(1) |
-+ SMY3(2) | SMY2(3) | SMY1(2) | SMY0(3);
-+ val1 = CTRL_SAT(0x1);
-+ break;
-+ default:
-+ val = SMY13(0) | SMY12(1) | SMY11(0) | SMY10(1) |
-+ SMY3(2) | SMY2(3) | SMY1(2) | SMY0(3);
-+ val1 = CTRL_SAT(0x1);
-+ break;
-+ }
-+ stf_isp_reg_write(stfcamss, ISP_REG_RAW_FORMAT_CFG, val);
-+ stf_isp_reg_set_bit(stfcamss, ISP_REG_ISP_CTRL_1, CTRL_SAT_MASK, val1);
-+}
-+
-+void stf_isp_settings(struct stf_isp_dev *isp_dev,
-+ struct stf_isp_crop *crop, u32 mcode)
-+{
-+ struct stfcamss *stfcamss = isp_dev->stfcamss;
-+
-+ stf_isp_config_crop(stfcamss, crop);
-+ stf_isp_config_raw_fmt(stfcamss, mcode);
-+
-+ stf_isp_reg_set_bit(stfcamss, ISP_REG_DUMP_CFG_1,
-+ DUMP_BURST_LEN_MASK | DUMP_SD_MASK,
-+ DUMP_BURST_LEN(3));
-+
-+ stf_isp_reg_write(stfcamss, ISP_REG_ITIIWSR,
-+ ITI_HSIZE(IMAGE_MAX_HEIGH) |
-+ ITI_WSIZE(IMAGE_MAX_WIDTH));
-+ stf_isp_reg_write(stfcamss, ISP_REG_ITIDWLSR, ITI_WSTRIDE(0x960));
-+ stf_isp_reg_write(stfcamss, ISP_REG_ITIDRLSR, ITI_STRIDE_L(0x960));
-+ stf_isp_reg_write(stfcamss, ISP_REG_SENSOR, 0x1);
-+}
-+
-+void stf_isp_stream_set(struct stf_isp_dev *isp_dev)
-+{
-+ struct stfcamss *stfcamss = isp_dev->stfcamss;
-+
-+ stf_isp_reg_write_delay(stfcamss, ISP_REG_ISP_CTRL_0,
-+ ISPC_ENUO | ISPC_ENLS | ISPC_RST, 10);
-+ stf_isp_reg_write_delay(stfcamss, ISP_REG_ISP_CTRL_0,
-+ ISPC_ENUO | ISPC_ENLS, 10);
-+ stf_isp_reg_write(stfcamss, ISP_REG_IESHD, SHAD_UP_M);
-+ stf_isp_reg_write_delay(stfcamss, ISP_REG_ISP_CTRL_0,
-+ ISPC_ENUO | ISPC_ENLS | ISPC_EN, 10);
-+ stf_isp_reg_write_delay(stfcamss, ISP_REG_CSIINTS,
-+ CSI_INTS(1) | CSI_SHA_M(4), 10);
-+ stf_isp_reg_write_delay(stfcamss, ISP_REG_CSIINTS,
-+ CSI_INTS(2) | CSI_SHA_M(4), 10);
-+ stf_isp_reg_write_delay(stfcamss, ISP_REG_CSI_INPUT_EN_AND_STATUS,
-+ CSI_EN_S, 10);
-+}
diff --git a/target/linux/starfive/patches-6.1/0086-media-starfive-Add-VIN-driver.patch b/target/linux/starfive/patches-6.1/0086-media-starfive-Add-VIN-driver.patch
deleted file mode 100644
index 2ab822ae96..0000000000
--- a/target/linux/starfive/patches-6.1/0086-media-starfive-Add-VIN-driver.patch
+++ /dev/null
@@ -1,1694 +0,0 @@
-From 030f0312433a85899fab4dccada5b2cbceb3bad5 Mon Sep 17 00:00:00 2001
-From: Jack Zhu <jack.zhu@starfivetech.com>
-Date: Fri, 12 May 2023 18:28:44 +0800
-Subject: [PATCH 086/122] media: starfive: Add VIN driver
-
-Add Video In Controller driver for StarFive Camera Subsystem.
-
-Signed-off-by: Jack Zhu <jack.zhu@starfivetech.com>
----
- drivers/media/platform/starfive/Makefile | 4 +-
- drivers/media/platform/starfive/stf_camss.c | 39 +-
- drivers/media/platform/starfive/stf_camss.h | 2 +
- drivers/media/platform/starfive/stf_vin.c | 1134 +++++++++++++++++
- drivers/media/platform/starfive/stf_vin.h | 180 +++
- .../media/platform/starfive/stf_vin_hw_ops.c | 241 ++++
- 6 files changed, 1598 insertions(+), 2 deletions(-)
- create mode 100644 drivers/media/platform/starfive/stf_vin.c
- create mode 100644 drivers/media/platform/starfive/stf_vin.h
- create mode 100644 drivers/media/platform/starfive/stf_vin_hw_ops.c
-
---- a/drivers/media/platform/starfive/Makefile
-+++ b/drivers/media/platform/starfive/Makefile
-@@ -7,6 +7,8 @@ starfive-camss-objs += \
- stf_camss.o \
- stf_isp.o \
- stf_isp_hw_ops.o \
-- stf_video.o
-+ stf_video.o \
-+ stf_vin.o \
-+ stf_vin_hw_ops.o
-
- obj-$(CONFIG_VIDEO_STARFIVE_CAMSS) += starfive-camss.o \
---- a/drivers/media/platform/starfive/stf_camss.c
-+++ b/drivers/media/platform/starfive/stf_camss.c
-@@ -142,27 +142,61 @@ static int stfcamss_init_subdevices(stru
- return ret;
- }
-
-+ ret = stf_vin_subdev_init(stfcamss);
-+ if (ret < 0) {
-+ dev_err(stfcamss->dev, "Failed to init vin subdev: %d\n", ret);
-+ return ret;
-+ }
- return ret;
- }
-
- static int stfcamss_register_subdevices(struct stfcamss *stfcamss)
- {
- int ret;
-+ struct stf_vin_dev *vin_dev = &stfcamss->vin_dev;
- struct stf_isp_dev *isp_dev = &stfcamss->isp_dev;
-
- ret = stf_isp_register(isp_dev, &stfcamss->v4l2_dev);
- if (ret < 0) {
- dev_err(stfcamss->dev,
- "Failed to register stf isp%d entity: %d\n", 0, ret);
-- return ret;
-+ goto err_reg_isp;
-+ }
-+
-+ ret = stf_vin_register(vin_dev, &stfcamss->v4l2_dev);
-+ if (ret < 0) {
-+ dev_err(stfcamss->dev,
-+ "Failed to register vin entity: %d\n", ret);
-+ goto err_reg_vin;
- }
-
-+ ret = media_create_pad_link(&isp_dev->subdev.entity,
-+ STF_ISP_PAD_SRC,
-+ &vin_dev->line[VIN_LINE_ISP].subdev.entity,
-+ STF_VIN_PAD_SINK,
-+ 0);
-+ if (ret < 0) {
-+ dev_err(stfcamss->dev,
-+ "Failed to link %s->%s entities: %d\n",
-+ isp_dev->subdev.entity.name,
-+ vin_dev->line[VIN_LINE_ISP].subdev.entity.name, ret);
-+ goto err_link;
-+ }
-+
-+ return ret;
-+
-+err_link:
-+ stf_vin_unregister(&stfcamss->vin_dev);
-+err_reg_vin:
-+ stf_isp_unregister(&stfcamss->isp_dev);
-+err_reg_isp:
- return ret;
- }
-
- static void stfcamss_unregister_subdevices(struct stfcamss *stfcamss)
- {
- stf_isp_unregister(&stfcamss->isp_dev);
-+ stf_vin_unregister(&stfcamss->vin_dev);
- }
-
- static int stfcamss_subdev_notifier_bound(struct v4l2_async_notifier *async,
-@@ -175,11 +209,14 @@ static int stfcamss_subdev_notifier_boun
- container_of(asd, struct stfcamss_async_subdev, asd);
- enum port_num port = csd->port;
- struct stf_isp_dev *isp_dev = &stfcamss->isp_dev;
-+ struct stf_vin_dev *vin_dev = &stfcamss->vin_dev;
- struct host_data *host_data = &stfcamss->host_data;
- struct media_entity *source;
- int i, j;
-
- if (port == PORT_NUMBER_CSI2RX) {
-+ host_data->host_entity[0] =
-+ &vin_dev->line[VIN_LINE_WR].subdev.entity;
- host_data->host_entity[1] = &isp_dev->subdev.entity;
- } else if (port == PORT_NUMBER_DVP_SENSOR) {
- dev_err(stfcamss->dev, "Not support DVP sensor\n");
---- a/drivers/media/platform/starfive/stf_camss.h
-+++ b/drivers/media/platform/starfive/stf_camss.h
-@@ -17,6 +17,7 @@
-
- #include "stf_common.h"
- #include "stf_isp.h"
-+#include "stf_vin.h"
-
- #define DRV_NAME "starfive-camss"
- #define STF_DVP_NAME "stf_dvp"
-@@ -72,6 +73,7 @@ struct stfcamss {
- struct media_device media_dev;
- struct media_pipeline pipe;
- struct device *dev;
-+ struct stf_vin_dev vin_dev;
- struct stf_isp_dev isp_dev;
- struct v4l2_async_notifier notifier;
- struct host_data host_data;
---- /dev/null
-+++ b/drivers/media/platform/starfive/stf_vin.c
-@@ -0,0 +1,1134 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * stf_vin.c
-+ *
-+ * StarFive Camera Subsystem - VIN Module
-+ *
-+ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
-+ */
-+#include <linux/pm_runtime.h>
-+
-+#include "stf_camss.h"
-+
-+#define vin_line_array(ptr_line) \
-+ ((const struct vin_line (*)[]) &(ptr_line)[-((ptr_line)->id)])
-+
-+#define line_to_vin_dev(ptr_line) \
-+ container_of(vin_line_array(ptr_line), struct stf_vin_dev, line)
-+
-+#define VIN_FRAME_DROP_MAX_VAL 90
-+#define VIN_FRAME_DROP_MIN_VAL 4
-+#define VIN_FRAME_PER_SEC_MAX_VAL 90
-+
-+/* ISP ctrl need 1 sec to let frames become stable. */
-+#define VIN_FRAME_DROP_SEC_FOR_ISP_CTRL 1
-+
-+static const struct vin_format vin_formats_wr[] = {
-+ { MEDIA_BUS_FMT_SRGGB10_1X10, 10},
-+ { MEDIA_BUS_FMT_SGRBG10_1X10, 10},
-+ { MEDIA_BUS_FMT_SGBRG10_1X10, 10},
-+ { MEDIA_BUS_FMT_SBGGR10_1X10, 10},
-+};
-+
-+static const struct vin_format vin_formats_uo[] = {
-+ { MEDIA_BUS_FMT_Y12_1X12, 8},
-+};
-+
-+static const struct vin_format_table vin_formats_table[] = {
-+ /* VIN_LINE_WR */
-+ { vin_formats_wr, ARRAY_SIZE(vin_formats_wr) },
-+ /* VIN_LINE_ISP */
-+ { vin_formats_uo, ARRAY_SIZE(vin_formats_uo) },
-+};
-+
-+static void vin_buffer_done(struct vin_line *line);
-+static void vin_change_buffer(struct vin_line *line);
-+static struct stfcamss_buffer *vin_buf_get_pending(struct vin_output *output);
-+static void vin_output_init_addrs(struct vin_line *line);
-+static void vin_init_outputs(struct vin_line *line);
-+static struct v4l2_mbus_framefmt *
-+__vin_get_format(struct vin_line *line,
-+ struct v4l2_subdev_state *state,
-+ unsigned int pad,
-+ enum v4l2_subdev_format_whence which);
-+
-+static char *vin_get_line_subdevname(int line_id)
-+{
-+ char *name = NULL;
-+
-+ switch (line_id) {
-+ case VIN_LINE_WR:
-+ name = "wr";
-+ break;
-+ case VIN_LINE_ISP:
-+ name = "isp0";
-+ break;
-+ default:
-+ name = "unknown";
-+ break;
-+ }
-+ return name;
-+}
-+
-+static enum isp_line_id vin_map_isp_line(enum vin_line_id line)
-+{
-+ enum isp_line_id line_id;
-+
-+ if (line > VIN_LINE_WR && line < VIN_LINE_MAX)
-+ line_id = STF_ISP_LINE_SRC;
-+ else
-+ line_id = STF_ISP_LINE_INVALID;
-+
-+ return line_id;
-+}
-+
-+enum isp_pad_id stf_vin_map_isp_pad(enum vin_line_id line, enum isp_pad_id def)
-+{
-+ enum isp_pad_id pad_id;
-+
-+ if (line == VIN_LINE_WR)
-+ pad_id = STF_ISP_PAD_SINK;
-+ else if ((line > VIN_LINE_WR) && (line < VIN_LINE_MAX))
-+ pad_id = (enum isp_pad_id)vin_map_isp_line(line);
-+ else
-+ pad_id = def;
-+
-+ return pad_id;
-+}
-+
-+int stf_vin_subdev_init(struct stfcamss *stfcamss)
-+{
-+ struct device *dev = stfcamss->dev;
-+ struct stf_vin_dev *vin_dev = &stfcamss->vin_dev;
-+ int i, ret = 0;
-+
-+ vin_dev->stfcamss = stfcamss;
-+
-+ vin_dev->isr_ops = devm_kzalloc(dev, sizeof(*vin_dev->isr_ops),
-+ GFP_KERNEL);
-+ if (!vin_dev->isr_ops)
-+ return -ENOMEM;
-+ vin_dev->isr_ops->isr_buffer_done = vin_buffer_done;
-+ vin_dev->isr_ops->isr_change_buffer = vin_change_buffer;
-+
-+ atomic_set(&vin_dev->ref_count, 0);
-+
-+ ret = devm_request_irq(dev,
-+ stfcamss->irq[STF_IRQ_VINWR],
-+ stf_vin_wr_irq_handler,
-+ 0, "vin_axiwr_irq", vin_dev);
-+ if (ret) {
-+ dev_err(dev, "Failed to request irq\n");
-+ goto out;
-+ }
-+
-+ ret = devm_request_irq(dev,
-+ stfcamss->irq[STF_IRQ_ISP],
-+ stf_vin_isp_irq_handler,
-+ 0, "vin_isp_irq", vin_dev);
-+ if (ret) {
-+ dev_err(dev, "Failed to request isp irq\n");
-+ goto out;
-+ }
-+
-+ ret = devm_request_irq(dev,
-+ stfcamss->irq[STF_IRQ_ISPCSIL],
-+ stf_vin_isp_irq_csiline_handler,
-+ 0, "vin_isp_irq_csiline", vin_dev);
-+ if (ret) {
-+ dev_err(dev, "failed to request isp irq csiline\n");
-+ goto out;
-+ }
-+
-+ mutex_init(&vin_dev->power_lock);
-+ vin_dev->power_count = 0;
-+
-+ for (i = 0; i < STF_DUMMY_MODULE_NUMS; i++) {
-+ struct dummy_buffer *dummy_buffer = &vin_dev->dummy_buffer[i];
-+
-+ mutex_init(&dummy_buffer->stream_lock);
-+ dummy_buffer->nums =
-+ i == 0 ? VIN_DUMMY_BUFFER_NUMS : ISP_DUMMY_BUFFER_NUMS;
-+ dummy_buffer->stream_count = 0;
-+ dummy_buffer->buffer =
-+ devm_kzalloc(dev,
-+ dummy_buffer->nums * sizeof(struct vin_dummy_buffer),
-+ GFP_KERNEL);
-+ atomic_set(&dummy_buffer->frame_skip, 0);
-+ }
-+
-+ for (i = VIN_LINE_WR; i < STF_ISP_LINE_MAX + 1; i++) {
-+ struct vin_line *l = &vin_dev->line[i];
-+
-+ l->video_out.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-+ l->video_out.stfcamss = stfcamss;
-+ l->id = i;
-+ l->sdev_type = STF_SUBDEV_TYPE_VIN;
-+ l->formats = vin_formats_table[i].fmts;
-+ l->nformats = vin_formats_table[i].nfmts;
-+ spin_lock_init(&l->output_lock);
-+
-+ mutex_init(&l->stream_lock);
-+ l->stream_count = 0;
-+ mutex_init(&l->power_lock);
-+ l->power_count = 0;
-+ }
-+
-+ return 0;
-+out:
-+ return ret;
-+}
-+
-+static enum link vin_get_link(struct media_entity *entity)
-+{
-+ struct v4l2_subdev *subdev;
-+ struct media_pad *pad;
-+ bool isp = false;
-+
-+ while (1) {
-+ pad = &entity->pads[0];
-+ if (!(pad->flags & MEDIA_PAD_FL_SINK))
-+ return LINK_ERROR;
-+
-+ pad = media_pad_remote_pad_first(pad);
-+ if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
-+ return LINK_ERROR;
-+
-+ entity = pad->entity;
-+ subdev = media_entity_to_v4l2_subdev(entity);
-+
-+ if (!strncmp(subdev->name, STF_CSI_NAME,
-+ strlen(STF_CSI_NAME))) {
-+ if (isp)
-+ return LINK_CSI_TO_ISP;
-+ else
-+ return LINK_CSI_TO_WR;
-+ } else if (!strncmp(subdev->name, STF_DVP_NAME,
-+ strlen(STF_DVP_NAME))) {
-+ if (isp)
-+ return LINK_DVP_TO_ISP;
-+ else
-+ return LINK_DVP_TO_WR;
-+ } else if (!strncmp(subdev->name, STF_ISP_NAME,
-+ strlen(STF_ISP_NAME))) {
-+ isp = true;
-+ } else {
-+ return LINK_ERROR;
-+ }
-+ }
-+}
-+
-+static int vin_set_power(struct v4l2_subdev *sd, int on)
-+{
-+ struct vin_line *line = v4l2_get_subdevdata(sd);
-+ struct stf_vin_dev *vin_dev = line_to_vin_dev(line);
-+ struct stfcamss *stfcamss = vin_dev->stfcamss;
-+ enum link link;
-+
-+ mutex_lock(&line->power_lock);
-+ if (on) {
-+ if (line->power_count == 0)
-+ vin_init_outputs(line);
-+ line->power_count++;
-+ } else {
-+ if (line->power_count == 0) {
-+ dev_err(stfcamss->dev,
-+ "line power off on power_count = 0\n");
-+ goto exit_line;
-+ }
-+ line->power_count--;
-+ }
-+exit_line:
-+ mutex_unlock(&line->power_lock);
-+
-+ mutex_lock(&vin_dev->power_lock);
-+ link = vin_get_link(&sd->entity);
-+ if (link == LINK_ERROR)
-+ goto exit;
-+
-+ if (on) {
-+ if (vin_dev->power_count == 0) {
-+ pm_runtime_get_sync(stfcamss->dev);
-+ stf_vin_clk_enable(vin_dev, link);
-+ }
-+ vin_dev->power_count++;
-+ } else {
-+ if (vin_dev->power_count == 0) {
-+ dev_err(stfcamss->dev,
-+ "vin_dev power off on power_count=0\n");
-+ goto exit;
-+ }
-+ if (vin_dev->power_count == 1) {
-+ stf_vin_clk_disable(vin_dev, link);
-+ pm_runtime_put_sync(stfcamss->dev);
-+ }
-+ vin_dev->power_count--;
-+ }
-+exit:
-+
-+ mutex_unlock(&vin_dev->power_lock);
-+
-+ return 0;
-+}
-+
-+static int vin_enable_output(struct vin_line *line)
-+{
-+ struct vin_output *output = &line->output;
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&line->output_lock, flags);
-+
-+ output->state = VIN_OUTPUT_IDLE;
-+
-+ output->buf[0] = vin_buf_get_pending(output);
-+
-+ if (!output->buf[0] && output->buf[1]) {
-+ output->buf[0] = output->buf[1];
-+ output->buf[1] = NULL;
-+ }
-+
-+ if (output->buf[0])
-+ output->state = VIN_OUTPUT_SINGLE;
-+
-+ output->sequence = 0;
-+
-+ vin_output_init_addrs(line);
-+ spin_unlock_irqrestore(&line->output_lock, flags);
-+ return 0;
-+}
-+
-+static int vin_disable_output(struct vin_line *line)
-+{
-+ struct vin_output *output = &line->output;
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&line->output_lock, flags);
-+
-+ output->state = VIN_OUTPUT_OFF;
-+
-+ spin_unlock_irqrestore(&line->output_lock, flags);
-+ return 0;
-+}
-+
-+static u32 vin_line_to_dummy_module(struct vin_line *line)
-+{
-+ u32 dummy_module = 0;
-+
-+ switch (line->id) {
-+ case VIN_LINE_WR:
-+ dummy_module = STF_DUMMY_VIN;
-+ break;
-+ case VIN_LINE_ISP:
-+ dummy_module = STF_DUMMY_ISP;
-+ break;
-+ default:
-+ dummy_module = STF_DUMMY_VIN;
-+ break;
-+ }
-+
-+ return dummy_module;
-+}
-+
-+static int vin_alloc_dummy_buffer(struct stf_vin_dev *vin_dev,
-+ struct v4l2_mbus_framefmt *fmt,
-+ int dummy_module)
-+{
-+ struct device *dev = vin_dev->stfcamss->dev;
-+ struct dummy_buffer *dummy_buffer =
-+ &vin_dev->dummy_buffer[dummy_module];
-+ struct vin_dummy_buffer *buffer = NULL;
-+ int ret = 0, i;
-+ u32 aligns;
-+
-+ for (i = 0; i < dummy_buffer->nums; i++) {
-+ buffer = &vin_dev->dummy_buffer[dummy_module].buffer[i];
-+ buffer->width = fmt->width;
-+ buffer->height = fmt->height;
-+ buffer->mcode = fmt->code;
-+ if (i == STF_VIN_PAD_SINK) {
-+ aligns = ALIGN(fmt->width * 4,
-+ STFCAMSS_FRAME_WIDTH_ALIGN_8);
-+ buffer->buffer_size = PAGE_ALIGN(aligns * fmt->height);
-+ } else if (i == STF_ISP_PAD_SRC) {
-+ aligns = ALIGN(fmt->width,
-+ STFCAMSS_FRAME_WIDTH_ALIGN_8);
-+ buffer->buffer_size =
-+ PAGE_ALIGN(aligns * fmt->height * 3 / 2);
-+ } else {
-+ continue;
-+ }
-+
-+ buffer->vaddr = dma_alloc_coherent(dev,
-+ buffer->buffer_size,
-+ &buffer->paddr[0],
-+ GFP_DMA | GFP_KERNEL);
-+
-+ if (buffer->vaddr) {
-+ if (i == STF_ISP_PAD_SRC)
-+ buffer->paddr[1] =
-+ (dma_addr_t)(buffer->paddr[0] + aligns * fmt->height);
-+ else
-+ dev_dbg(dev, "signal plane\n");
-+ }
-+ }
-+
-+ return ret;
-+}
-+
-+static void vin_free_dummy_buffer(struct stf_vin_dev *vin_dev, int dummy_module)
-+{
-+ struct device *dev = vin_dev->stfcamss->dev;
-+ struct dummy_buffer *dummy_buffer =
-+ &vin_dev->dummy_buffer[dummy_module];
-+ struct vin_dummy_buffer *buffer = NULL;
-+ int i;
-+
-+ for (i = 0; i < dummy_buffer->nums; i++) {
-+ buffer = &dummy_buffer->buffer[i];
-+ if (buffer->vaddr)
-+ dma_free_coherent(dev, buffer->buffer_size,
-+ buffer->vaddr, buffer->paddr[0]);
-+ memset(buffer, 0, sizeof(struct vin_dummy_buffer));
-+ }
-+}
-+
-+static void vin_set_dummy_buffer(struct vin_line *line, u32 pad)
-+{
-+ struct stf_vin_dev *vin_dev = line_to_vin_dev(line);
-+ int dummy_module = vin_line_to_dummy_module(line);
-+ struct dummy_buffer *dummy_buffer =
-+ &vin_dev->dummy_buffer[dummy_module];
-+ struct vin_dummy_buffer *buffer = NULL;
-+
-+ switch (pad) {
-+ case STF_VIN_PAD_SINK:
-+ if (line->id == VIN_LINE_WR) {
-+ buffer = &dummy_buffer->buffer[STF_VIN_PAD_SINK];
-+ stf_vin_wr_set_ping_addr(vin_dev, buffer->paddr[0]);
-+ stf_vin_wr_set_pong_addr(vin_dev, buffer->paddr[0]);
-+ } else {
-+ buffer = &dummy_buffer->buffer[STF_ISP_PAD_SRC];
-+ stf_vin_isp_set_yuv_addr(vin_dev,
-+ buffer->paddr[0],
-+ buffer->paddr[1]);
-+ }
-+ break;
-+ case STF_ISP_PAD_SRC:
-+ buffer = &dummy_buffer->buffer[STF_ISP_PAD_SRC];
-+ stf_vin_isp_set_yuv_addr(vin_dev,
-+ buffer->paddr[0],
-+ buffer->paddr[1]);
-+ break;
-+ default:
-+ break;
-+ }
-+}
-+
-+static int vin_set_stream(struct v4l2_subdev *sd, int enable)
-+{
-+ struct vin_line *line = v4l2_get_subdevdata(sd);
-+ struct stf_vin_dev *vin_dev = line_to_vin_dev(line);
-+ int dummy_module = vin_line_to_dummy_module(line);
-+ struct dummy_buffer *dummy_buffer =
-+ &vin_dev->dummy_buffer[dummy_module];
-+ struct v4l2_mbus_framefmt *fmt;
-+ enum link link;
-+
-+ fmt = __vin_get_format(line, NULL,
-+ STF_VIN_PAD_SINK, V4L2_SUBDEV_FORMAT_ACTIVE);
-+ mutex_lock(&dummy_buffer->stream_lock);
-+ if (enable) {
-+ if (dummy_buffer->stream_count == 0) {
-+ vin_alloc_dummy_buffer(vin_dev, fmt, dummy_module);
-+ vin_set_dummy_buffer(line, STF_VIN_PAD_SINK);
-+ atomic_set(&dummy_buffer->frame_skip,
-+ VIN_FRAME_DROP_MIN_VAL + 30);
-+ }
-+ dummy_buffer->stream_count++;
-+ } else {
-+ if (dummy_buffer->stream_count == 1) {
-+ vin_free_dummy_buffer(vin_dev, dummy_module);
-+ /* set buffer addr to zero */
-+ vin_set_dummy_buffer(line, STF_VIN_PAD_SINK);
-+ } else {
-+ vin_set_dummy_buffer(line,
-+ stf_vin_map_isp_pad(line->id, STF_ISP_PAD_SINK));
-+ }
-+
-+ dummy_buffer->stream_count--;
-+ }
-+ mutex_unlock(&dummy_buffer->stream_lock);
-+
-+ mutex_lock(&line->stream_lock);
-+ link = vin_get_link(&sd->entity);
-+ if (link == LINK_ERROR)
-+ goto exit;
-+
-+ if (enable) {
-+ if (line->stream_count == 0) {
-+ stf_vin_stream_set(vin_dev, link);
-+ if (line->id == VIN_LINE_WR) {
-+ stf_vin_wr_irq_enable(vin_dev, 1);
-+ stf_vin_wr_stream_set(vin_dev);
-+ }
-+ }
-+ line->stream_count++;
-+ } else {
-+ if (line->stream_count == 1 && line->id == VIN_LINE_WR)
-+ stf_vin_wr_irq_enable(vin_dev, 0);
-+ line->stream_count--;
-+ }
-+exit:
-+ mutex_unlock(&line->stream_lock);
-+
-+ if (enable)
-+ vin_enable_output(line);
-+ else
-+ vin_disable_output(line);
-+
-+ return 0;
-+}
-+
-+static struct v4l2_mbus_framefmt *
-+__vin_get_format(struct vin_line *line,
-+ struct v4l2_subdev_state *state,
-+ unsigned int pad,
-+ enum v4l2_subdev_format_whence which)
-+{
-+ if (which == V4L2_SUBDEV_FORMAT_TRY)
-+ return v4l2_subdev_get_try_format(&line->subdev, state, pad);
-+ return &line->fmt[pad];
-+}
-+
-+static void vin_try_format(struct vin_line *line,
-+ struct v4l2_subdev_state *state,
-+ unsigned int pad,
-+ struct v4l2_mbus_framefmt *fmt,
-+ enum v4l2_subdev_format_whence which)
-+{
-+ unsigned int i;
-+
-+ switch (pad) {
-+ case STF_VIN_PAD_SINK:
-+ /* Set format on sink pad */
-+ for (i = 0; i < line->nformats; i++)
-+ if (fmt->code == line->formats[i].code)
-+ break;
-+
-+ /* If not found, use UYVY as default */
-+ if (i >= line->nformats)
-+ fmt->code = line->formats[0].code;
-+
-+ fmt->width = clamp_t(u32, fmt->width,
-+ STFCAMSS_FRAME_MIN_WIDTH,
-+ STFCAMSS_FRAME_MAX_WIDTH);
-+ fmt->height = clamp_t(u32, fmt->height,
-+ STFCAMSS_FRAME_MIN_HEIGHT,
-+ STFCAMSS_FRAME_MAX_HEIGHT);
-+
-+ fmt->field = V4L2_FIELD_NONE;
-+ fmt->colorspace = V4L2_COLORSPACE_SRGB;
-+ fmt->flags = 0;
-+ break;
-+
-+ case STF_VIN_PAD_SRC:
-+ /* Set and return a format same as sink pad */
-+ *fmt = *__vin_get_format(line, state, STF_VIN_PAD_SINK, which);
-+ break;
-+ }
-+
-+ fmt->colorspace = V4L2_COLORSPACE_SRGB;
-+}
-+
-+static int vin_enum_mbus_code(struct v4l2_subdev *sd,
-+ struct v4l2_subdev_state *state,
-+ struct v4l2_subdev_mbus_code_enum *code)
-+{
-+ struct vin_line *line = v4l2_get_subdevdata(sd);
-+
-+ if (code->index >= line->nformats)
-+ return -EINVAL;
-+ if (code->pad == STF_VIN_PAD_SINK) {
-+ code->code = line->formats[code->index].code;
-+ } else {
-+ struct v4l2_mbus_framefmt *sink_fmt;
-+
-+ sink_fmt = __vin_get_format(line, state, STF_VIN_PAD_SINK,
-+ code->which);
-+
-+ code->code = sink_fmt->code;
-+ if (!code->code)
-+ return -EINVAL;
-+ }
-+ code->flags = 0;
-+
-+ return 0;
-+}
-+
-+static int vin_enum_frame_size(struct v4l2_subdev *sd,
-+ struct v4l2_subdev_state *state,
-+ struct v4l2_subdev_frame_size_enum *fse)
-+{
-+ struct vin_line *line = v4l2_get_subdevdata(sd);
-+ struct v4l2_mbus_framefmt format;
-+
-+ if (fse->index != 0)
-+ return -EINVAL;
-+
-+ format.code = fse->code;
-+ format.width = 1;
-+ format.height = 1;
-+ vin_try_format(line, state, fse->pad, &format, fse->which);
-+ fse->min_width = format.width;
-+ fse->min_height = format.height;
-+
-+ if (format.code != fse->code)
-+ return -EINVAL;
-+
-+ format.code = fse->code;
-+ format.width = -1;
-+ format.height = -1;
-+ vin_try_format(line, state, fse->pad, &format, fse->which);
-+ fse->max_width = format.width;
-+ fse->max_height = format.height;
-+
-+ return 0;
-+}
-+
-+static int vin_get_format(struct v4l2_subdev *sd,
-+ struct v4l2_subdev_state *state,
-+ struct v4l2_subdev_format *fmt)
-+{
-+ struct vin_line *line = v4l2_get_subdevdata(sd);
-+ struct v4l2_mbus_framefmt *format;
-+
-+ format = __vin_get_format(line, state, fmt->pad, fmt->which);
-+ if (!format)
-+ return -EINVAL;
-+
-+ fmt->format = *format;
-+
-+ return 0;
-+}
-+
-+static int vin_set_format(struct v4l2_subdev *sd,
-+ struct v4l2_subdev_state *state,
-+ struct v4l2_subdev_format *fmt)
-+{
-+ struct vin_line *line = v4l2_get_subdevdata(sd);
-+ struct v4l2_mbus_framefmt *format;
-+
-+ format = __vin_get_format(line, state, fmt->pad, fmt->which);
-+ if (!format)
-+ return -EINVAL;
-+
-+ mutex_lock(&line->stream_lock);
-+ if (line->stream_count) {
-+ fmt->format = *format;
-+ mutex_unlock(&line->stream_lock);
-+ goto out;
-+ } else {
-+ vin_try_format(line, state, fmt->pad, &fmt->format, fmt->which);
-+ *format = fmt->format;
-+ }
-+ mutex_unlock(&line->stream_lock);
-+
-+ if (fmt->pad == STF_VIN_PAD_SINK) {
-+ /* Propagate the format from sink to source */
-+ format = __vin_get_format(line, state, STF_VIN_PAD_SRC,
-+ fmt->which);
-+
-+ *format = fmt->format;
-+ vin_try_format(line, state, STF_VIN_PAD_SRC, format,
-+ fmt->which);
-+ }
-+
-+out:
-+ return 0;
-+}
-+
-+static int vin_init_formats(struct v4l2_subdev *sd,
-+ struct v4l2_subdev_fh *fh)
-+{
-+ struct v4l2_subdev_format format = {
-+ .pad = STF_VIN_PAD_SINK,
-+ .which = fh ?
-+ V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE,
-+ .format = {
-+ .code = MEDIA_BUS_FMT_RGB565_2X8_LE,
-+ .width = 1920,
-+ .height = 1080
-+ }
-+ };
-+
-+ return vin_set_format(sd, fh ? fh->state : NULL, &format);
-+}
-+
-+static void vin_output_init_addrs(struct vin_line *line)
-+{
-+ struct vin_output *output = &line->output;
-+ struct stf_vin_dev *vin_dev = line_to_vin_dev(line);
-+ dma_addr_t ping_addr;
-+ dma_addr_t y_addr, uv_addr;
-+
-+ output->active_buf = 0;
-+
-+ if (output->buf[0]) {
-+ ping_addr = output->buf[0]->addr[0];
-+ y_addr = output->buf[0]->addr[0];
-+ uv_addr = output->buf[0]->addr[1];
-+ } else {
-+ return;
-+ }
-+
-+ switch (vin_map_isp_line(line->id)) {
-+ case STF_ISP_LINE_SRC:
-+ stf_vin_isp_set_yuv_addr(vin_dev, y_addr, uv_addr);
-+ break;
-+ default:
-+ if (line->id == VIN_LINE_WR) {
-+ stf_vin_wr_set_ping_addr(vin_dev, ping_addr);
-+ stf_vin_wr_set_pong_addr(vin_dev, ping_addr);
-+ }
-+ break;
-+ }
-+}
-+
-+static void vin_init_outputs(struct vin_line *line)
-+{
-+ struct vin_output *output = &line->output;
-+
-+ output->state = VIN_OUTPUT_OFF;
-+ output->buf[0] = NULL;
-+ output->buf[1] = NULL;
-+ output->active_buf = 0;
-+ INIT_LIST_HEAD(&output->pending_bufs);
-+ INIT_LIST_HEAD(&output->ready_bufs);
-+}
-+
-+static void vin_buf_add_ready(struct vin_output *output,
-+ struct stfcamss_buffer *buffer)
-+{
-+ INIT_LIST_HEAD(&buffer->queue);
-+ list_add_tail(&buffer->queue, &output->ready_bufs);
-+}
-+
-+static struct stfcamss_buffer *vin_buf_get_ready(struct vin_output *output)
-+{
-+ struct stfcamss_buffer *buffer = NULL;
-+
-+ if (!list_empty(&output->ready_bufs)) {
-+ buffer = list_first_entry(&output->ready_bufs,
-+ struct stfcamss_buffer,
-+ queue);
-+ list_del(&buffer->queue);
-+ }
-+
-+ return buffer;
-+}
-+
-+static void vin_buf_add_pending(struct vin_output *output,
-+ struct stfcamss_buffer *buffer)
-+{
-+ INIT_LIST_HEAD(&buffer->queue);
-+ list_add_tail(&buffer->queue, &output->pending_bufs);
-+}
-+
-+static struct stfcamss_buffer *vin_buf_get_pending(struct vin_output *output)
-+{
-+ struct stfcamss_buffer *buffer = NULL;
-+
-+ if (!list_empty(&output->pending_bufs)) {
-+ buffer = list_first_entry(&output->pending_bufs,
-+ struct stfcamss_buffer,
-+ queue);
-+ list_del(&buffer->queue);
-+ }
-+
-+ return buffer;
-+}
-+
-+static void vin_buf_update_on_last(struct vin_line *line)
-+{
-+ struct vin_output *output = &line->output;
-+
-+ switch (output->state) {
-+ case VIN_OUTPUT_CONTINUOUS:
-+ output->state = VIN_OUTPUT_SINGLE;
-+ output->active_buf = !output->active_buf;
-+ break;
-+ case VIN_OUTPUT_SINGLE:
-+ output->state = VIN_OUTPUT_STOPPING;
-+ break;
-+ default:
-+ break;
-+ }
-+}
-+
-+static void vin_buf_update_on_next(struct vin_line *line)
-+{
-+ struct vin_output *output = &line->output;
-+
-+ switch (output->state) {
-+ case VIN_OUTPUT_CONTINUOUS:
-+ output->active_buf = !output->active_buf;
-+ break;
-+ case VIN_OUTPUT_SINGLE:
-+ default:
-+ break;
-+ }
-+}
-+
-+static void vin_buf_update_on_new(struct vin_line *line,
-+ struct vin_output *output,
-+ struct stfcamss_buffer *new_buf)
-+{
-+ switch (output->state) {
-+ case VIN_OUTPUT_SINGLE:
-+ vin_buf_add_pending(output, new_buf);
-+ break;
-+ case VIN_OUTPUT_IDLE:
-+ if (!output->buf[0]) {
-+ output->buf[0] = new_buf;
-+ vin_output_init_addrs(line);
-+ output->state = VIN_OUTPUT_SINGLE;
-+ } else {
-+ vin_buf_add_pending(output, new_buf);
-+ }
-+ break;
-+ case VIN_OUTPUT_STOPPING:
-+ if (output->last_buffer) {
-+ output->buf[output->active_buf] = output->last_buffer;
-+ output->last_buffer = NULL;
-+ }
-+
-+ output->state = VIN_OUTPUT_SINGLE;
-+ vin_buf_add_pending(output, new_buf);
-+ break;
-+ case VIN_OUTPUT_CONTINUOUS:
-+ default:
-+ vin_buf_add_pending(output, new_buf);
-+ break;
-+ }
-+}
-+
-+static void vin_buf_flush(struct vin_output *output,
-+ enum vb2_buffer_state state)
-+{
-+ struct stfcamss_buffer *buf;
-+ struct stfcamss_buffer *t;
-+
-+ list_for_each_entry_safe(buf, t, &output->pending_bufs, queue) {
-+ vb2_buffer_done(&buf->vb.vb2_buf, state);
-+ list_del(&buf->queue);
-+ }
-+ list_for_each_entry_safe(buf, t, &output->ready_bufs, queue) {
-+ vb2_buffer_done(&buf->vb.vb2_buf, state);
-+ list_del(&buf->queue);
-+ }
-+}
-+
-+static void vin_buffer_done(struct vin_line *line)
-+{
-+ struct stfcamss_buffer *ready_buf;
-+ struct vin_output *output = &line->output;
-+ unsigned long flags;
-+ u64 ts = ktime_get_ns();
-+
-+ if (output->state == VIN_OUTPUT_OFF ||
-+ output->state == VIN_OUTPUT_RESERVED)
-+ return;
-+
-+ spin_lock_irqsave(&line->output_lock, flags);
-+
-+ while ((ready_buf = vin_buf_get_ready(output))) {
-+ ready_buf->vb.vb2_buf.timestamp = ts;
-+ ready_buf->vb.sequence = output->sequence++;
-+
-+ vb2_buffer_done(&ready_buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
-+ }
-+
-+ spin_unlock_irqrestore(&line->output_lock, flags);
-+}
-+
-+static void vin_change_buffer(struct vin_line *line)
-+{
-+ struct stfcamss_buffer *ready_buf;
-+ struct vin_output *output = &line->output;
-+ struct stf_vin_dev *vin_dev = line_to_vin_dev(line);
-+ dma_addr_t *new_addr;
-+ unsigned long flags;
-+ u32 active_index;
-+
-+ if (output->state == VIN_OUTPUT_OFF ||
-+ output->state == VIN_OUTPUT_STOPPING ||
-+ output->state == VIN_OUTPUT_RESERVED ||
-+ output->state == VIN_OUTPUT_IDLE)
-+ return;
-+
-+ spin_lock_irqsave(&line->output_lock, flags);
-+
-+ active_index = output->active_buf;
-+
-+ ready_buf = output->buf[active_index];
-+ if (!ready_buf) {
-+ dev_warn(vin_dev->stfcamss->dev, "Missing ready buf %d %d!\n",
-+ active_index, output->state);
-+ active_index = !active_index;
-+ ready_buf = output->buf[active_index];
-+ if (!ready_buf) {
-+ dev_err(vin_dev->stfcamss->dev,
-+ "Missing ready buf2 %d %d!\n",
-+ active_index, output->state);
-+ goto out_unlock;
-+ }
-+ }
-+
-+ /* Get next buffer */
-+ output->buf[active_index] = vin_buf_get_pending(output);
-+ if (!output->buf[active_index]) {
-+ /* No next buffer - set same address */
-+ new_addr = ready_buf->addr;
-+ vin_buf_update_on_last(line);
-+ } else {
-+ new_addr = output->buf[active_index]->addr;
-+ vin_buf_update_on_next(line);
-+ }
-+
-+ if (output->state == VIN_OUTPUT_STOPPING) {
-+ output->last_buffer = ready_buf;
-+ } else {
-+ switch (vin_map_isp_line(line->id)) {
-+ case STF_ISP_LINE_SRC:
-+ stf_vin_isp_set_yuv_addr(vin_dev,
-+ new_addr[0],
-+ new_addr[1]);
-+ break;
-+ default:
-+ if (line->id == VIN_LINE_WR) {
-+ stf_vin_wr_set_ping_addr(vin_dev, new_addr[0]);
-+ stf_vin_wr_set_pong_addr(vin_dev, new_addr[0]);
-+ }
-+ break;
-+ }
-+
-+ vin_buf_add_ready(output, ready_buf);
-+ }
-+
-+ spin_unlock_irqrestore(&line->output_lock, flags);
-+ return;
-+
-+out_unlock:
-+ spin_unlock_irqrestore(&line->output_lock, flags);
-+}
-+
-+static int vin_queue_buffer(struct stfcamss_video *vid,
-+ struct stfcamss_buffer *buf)
-+{
-+ struct vin_line *line = container_of(vid, struct vin_line, video_out);
-+ struct vin_output *output;
-+ unsigned long flags;
-+
-+ output = &line->output;
-+
-+ spin_lock_irqsave(&line->output_lock, flags);
-+
-+ vin_buf_update_on_new(line, output, buf);
-+
-+ spin_unlock_irqrestore(&line->output_lock, flags);
-+
-+ return 0;
-+}
-+
-+static int vin_flush_buffers(struct stfcamss_video *vid,
-+ enum vb2_buffer_state state)
-+{
-+ struct vin_line *line = container_of(vid, struct vin_line, video_out);
-+ struct vin_output *output = &line->output;
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&line->output_lock, flags);
-+
-+ vin_buf_flush(output, state);
-+ if (output->buf[0])
-+ vb2_buffer_done(&output->buf[0]->vb.vb2_buf, state);
-+
-+ if (output->buf[1])
-+ vb2_buffer_done(&output->buf[1]->vb.vb2_buf, state);
-+
-+ if (output->last_buffer) {
-+ vb2_buffer_done(&output->last_buffer->vb.vb2_buf, state);
-+ output->last_buffer = NULL;
-+ }
-+ output->buf[0] = NULL;
-+ output->buf[1] = NULL;
-+
-+ spin_unlock_irqrestore(&line->output_lock, flags);
-+ return 0;
-+}
-+
-+static int vin_link_setup(struct media_entity *entity,
-+ const struct media_pad *local,
-+ const struct media_pad *remote, u32 flags)
-+{
-+ if (flags & MEDIA_LNK_FL_ENABLED)
-+ if (media_pad_remote_pad_first(local))
-+ return -EBUSY;
-+ return 0;
-+}
-+
-+static const struct v4l2_subdev_core_ops vin_core_ops = {
-+ .s_power = vin_set_power,
-+};
-+
-+static const struct v4l2_subdev_video_ops vin_video_ops = {
-+ .s_stream = vin_set_stream,
-+};
-+
-+static const struct v4l2_subdev_pad_ops vin_pad_ops = {
-+ .enum_mbus_code = vin_enum_mbus_code,
-+ .enum_frame_size = vin_enum_frame_size,
-+ .get_fmt = vin_get_format,
-+ .set_fmt = vin_set_format,
-+};
-+
-+static const struct v4l2_subdev_ops vin_v4l2_ops = {
-+ .core = &vin_core_ops,
-+ .video = &vin_video_ops,
-+ .pad = &vin_pad_ops,
-+};
-+
-+static const struct v4l2_subdev_internal_ops vin_v4l2_internal_ops = {
-+ .open = vin_init_formats,
-+};
-+
-+static const struct stfcamss_video_ops stfcamss_vin_video_ops = {
-+ .queue_buffer = vin_queue_buffer,
-+ .flush_buffers = vin_flush_buffers,
-+};
-+
-+static const struct media_entity_operations vin_media_ops = {
-+ .link_setup = vin_link_setup,
-+ .link_validate = v4l2_subdev_link_validate,
-+};
-+
-+int stf_vin_register(struct stf_vin_dev *vin_dev, struct v4l2_device *v4l2_dev)
-+{
-+ struct v4l2_subdev *sd;
-+ struct stfcamss_video *video_out;
-+ struct media_pad *pads;
-+ int ret;
-+ int i;
-+
-+ for (i = 0; i < STF_ISP_LINE_MAX + 1; i++) {
-+ char name[32];
-+ char *sub_name = vin_get_line_subdevname(i);
-+
-+ sd = &vin_dev->line[i].subdev;
-+ pads = vin_dev->line[i].pads;
-+ video_out = &vin_dev->line[i].video_out;
-+ video_out->id = i;
-+
-+ v4l2_subdev_init(sd, &vin_v4l2_ops);
-+ sd->internal_ops = &vin_v4l2_internal_ops;
-+ sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
-+ snprintf(sd->name, ARRAY_SIZE(sd->name), "%s%d_%s",
-+ STF_VIN_NAME, 0, sub_name);
-+ v4l2_set_subdevdata(sd, &vin_dev->line[i]);
-+
-+ ret = vin_init_formats(sd, NULL);
-+ if (ret < 0) {
-+ dev_err(vin_dev->stfcamss->dev,
-+ "Failed to init format: %d\n", ret);
-+ goto err_init;
-+ }
-+
-+ pads[STF_VIN_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
-+ pads[STF_VIN_PAD_SRC].flags = MEDIA_PAD_FL_SOURCE;
-+
-+ sd->entity.function =
-+ MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER;
-+ sd->entity.ops = &vin_media_ops;
-+ ret = media_entity_pads_init(&sd->entity,
-+ STF_VIN_PADS_NUM, pads);
-+ if (ret < 0) {
-+ dev_err(vin_dev->stfcamss->dev,
-+ "Failed to init media entity: %d\n",
-+ ret);
-+ goto err_init;
-+ }
-+
-+ ret = v4l2_device_register_subdev(v4l2_dev, sd);
-+ if (ret < 0) {
-+ dev_err(vin_dev->stfcamss->dev,
-+ "Failed to register subdev: %d\n", ret);
-+ goto err_reg_subdev;
-+ }
-+
-+ video_out->ops = &stfcamss_vin_video_ops;
-+ video_out->bpl_alignment = 16 * 8;
-+
-+ snprintf(name, ARRAY_SIZE(name), "%s_%s%d",
-+ sd->name, "video", i);
-+ ret = stf_video_register(video_out, v4l2_dev, name);
-+ if (ret < 0) {
-+ dev_err(vin_dev->stfcamss->dev,
-+ "Failed to register video node: %d\n", ret);
-+ goto err_vid_reg;
-+ }
-+
-+ ret = media_create_pad_link(
-+ &sd->entity, STF_VIN_PAD_SRC,
-+ &video_out->vdev.entity, 0,
-+ MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED);
-+ if (ret < 0) {
-+ dev_err(vin_dev->stfcamss->dev,
-+ "Failed to link %s->%s entities: %d\n",
-+ sd->entity.name, video_out->vdev.entity.name,
-+ ret);
-+ goto err_create_link;
-+ }
-+ }
-+
-+ return 0;
-+
-+err_create_link:
-+ stf_video_unregister(video_out);
-+err_vid_reg:
-+ v4l2_device_unregister_subdev(sd);
-+err_reg_subdev:
-+ media_entity_cleanup(&sd->entity);
-+err_init:
-+ for (i--; i >= 0; i--) {
-+ sd = &vin_dev->line[i].subdev;
-+ video_out = &vin_dev->line[i].video_out;
-+
-+ stf_video_unregister(video_out);
-+ v4l2_device_unregister_subdev(sd);
-+ media_entity_cleanup(&sd->entity);
-+ }
-+ return ret;
-+}
-+
-+int stf_vin_unregister(struct stf_vin_dev *vin_dev)
-+{
-+ struct v4l2_subdev *sd;
-+ struct stfcamss_video *video_out;
-+ int i;
-+
-+ mutex_destroy(&vin_dev->power_lock);
-+ for (i = 0; i < STF_DUMMY_MODULE_NUMS; i++)
-+ mutex_destroy(&vin_dev->dummy_buffer[i].stream_lock);
-+
-+ for (i = 0; i < STF_ISP_LINE_MAX + 1; i++) {
-+ sd = &vin_dev->line[i].subdev;
-+ video_out = &vin_dev->line[i].video_out;
-+
-+ stf_video_unregister(video_out);
-+ v4l2_device_unregister_subdev(sd);
-+ media_entity_cleanup(&sd->entity);
-+ mutex_destroy(&vin_dev->line[i].stream_lock);
-+ mutex_destroy(&vin_dev->line[i].power_lock);
-+ }
-+ return 0;
-+}
---- /dev/null
-+++ b/drivers/media/platform/starfive/stf_vin.h
-@@ -0,0 +1,180 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+/*
-+ * stf_vin.h
-+ *
-+ * StarFive Camera Subsystem - VIN Module
-+ *
-+ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
-+ */
-+
-+#ifndef STF_VIN_H
-+#define STF_VIN_H
-+
-+#include <linux/interrupt.h>
-+#include <linux/spinlock_types.h>
-+#include <media/v4l2-subdev.h>
-+
-+#include "stf_video.h"
-+
-+#define SYSCONSAIF_SYSCFG(x) (x)
-+
-+/* syscon offset 0 */
-+#define U0_VIN_CNFG_AXI_DVP_EN BIT(2)
-+
-+/* syscon offset 20 */
-+#define U0_VIN_CHANNEL_SEL_MASK GENMASK(3, 0)
-+#define U0_VIN_AXIWR0_EN BIT(4)
-+#define CHANNEL(x) ((x) << 0)
-+
-+/* syscon offset 32 */
-+#define U0_VIN_INTR_CLEAN BIT(0)
-+#define U0_VIN_INTR_M BIT(1)
-+#define U0_VIN_PIX_CNT_END_MASK GENMASK(12, 2)
-+#define U0_VIN_PIX_CT_MASK GENMASK(14, 13)
-+#define U0_VIN_PIXEL_HEIGH_BIT_SEL_MAKS GENMASK(16, 15)
-+
-+#define PIX_CNT_END(x) ((x) << 2)
-+#define PIX_CT(x) ((x) << 13)
-+#define PIXEL_HEIGH_BIT_SEL(x) ((x) << 15)
-+
-+/* syscon offset 36 */
-+#define U0_VIN_CNFG_DVP_HS_POS BIT(1)
-+#define U0_VIN_CNFG_DVP_SWAP_EN BIT(2)
-+#define U0_VIN_CNFG_DVP_VS_POS BIT(3)
-+#define U0_VIN_CNFG_GEN_EN_AXIRD BIT(4)
-+#define U0_VIN_CNFG_ISP_DVP_EN0 BIT(5)
-+#define U0_VIN_MIPI_BYTE_EN_ISP0(n) ((n) << 6)
-+#define U0_VIN_MIPI_CHANNEL_SEL0(n) ((n) << 8)
-+#define U0_VIN_P_I_MIPI_HAEDER_EN0(n) ((n) << 12)
-+#define U0_VIN_PIX_NUM(n) ((n) << 13)
-+#define U0_VIN_MIPI_BYTE_EN_ISP0_MASK GENMASK(7, 6)
-+#define U0_VIN_MIPI_CHANNEL_SEL0_MASK GENMASK(11, 8)
-+#define U0_VIN_P_I_MIPI_HAEDER_EN0_MASK BIT(12)
-+#define U0_VIN_PIX_NUM_MASK GENMASK(16, 13)
-+
-+#define STF_VIN_PAD_SINK 0
-+#define STF_VIN_PAD_SRC 1
-+#define STF_VIN_PADS_NUM 2
-+
-+#define ISP_DUMMY_BUFFER_NUMS STF_ISP_PAD_MAX
-+#define VIN_DUMMY_BUFFER_NUMS 1
-+
-+enum {
-+ STF_DUMMY_VIN,
-+ STF_DUMMY_ISP,
-+ STF_DUMMY_MODULE_NUMS,
-+};
-+
-+enum link {
-+ LINK_ERROR = -1,
-+ LINK_DVP_TO_WR,
-+ LINK_DVP_TO_ISP,
-+ LINK_CSI_TO_WR,
-+ LINK_CSI_TO_ISP,
-+};
-+
-+struct vin_format {
-+ u32 code;
-+ u8 bpp;
-+};
-+
-+struct vin_format_table {
-+ const struct vin_format *fmts;
-+ int nfmts;
-+};
-+
-+enum vin_output_state {
-+ VIN_OUTPUT_OFF,
-+ VIN_OUTPUT_RESERVED,
-+ VIN_OUTPUT_SINGLE,
-+ VIN_OUTPUT_CONTINUOUS,
-+ VIN_OUTPUT_IDLE,
-+ VIN_OUTPUT_STOPPING
-+};
-+
-+struct vin_output {
-+ int active_buf;
-+ struct stfcamss_buffer *buf[2];
-+ struct stfcamss_buffer *last_buffer;
-+ struct list_head pending_bufs;
-+ struct list_head ready_bufs;
-+ enum vin_output_state state;
-+ unsigned int sequence;
-+ unsigned int frame_skip;
-+};
-+
-+/* The vin output lines */
-+enum vin_line_id {
-+ VIN_LINE_NONE = -1,
-+ VIN_LINE_WR = 0,
-+ VIN_LINE_ISP,
-+ VIN_LINE_MAX,
-+};
-+
-+struct vin_line {
-+ enum stf_subdev_type sdev_type; /* must be frist */
-+ enum vin_line_id id;
-+ struct v4l2_subdev subdev;
-+ struct media_pad pads[STF_VIN_PADS_NUM];
-+ struct v4l2_mbus_framefmt fmt[STF_VIN_PADS_NUM];
-+ struct stfcamss_video video_out;
-+ struct mutex stream_lock; /* serialize stream control */
-+ int stream_count;
-+ struct mutex power_lock; /* serialize pipeline control in power process*/
-+ int power_count;
-+ struct vin_output output; /* pipeline and stream states */
-+ spinlock_t output_lock;
-+ const struct vin_format *formats;
-+ unsigned int nformats;
-+};
-+
-+struct vin_dummy_buffer {
-+ dma_addr_t paddr[3];
-+ void *vaddr;
-+ u32 buffer_size;
-+ u32 width;
-+ u32 height;
-+ u32 mcode;
-+};
-+
-+struct dummy_buffer {
-+ struct vin_dummy_buffer *buffer;
-+ u32 nums;
-+ struct mutex stream_lock; /* protects buffer data */
-+ int stream_count;
-+ atomic_t frame_skip;
-+};
-+
-+struct vin_isr_ops {
-+ void (*isr_buffer_done)(struct vin_line *line);
-+ void (*isr_change_buffer)(struct vin_line *line);
-+};
-+
-+struct stf_vin_dev {
-+ struct stfcamss *stfcamss;
-+ struct vin_line line[VIN_LINE_MAX];
-+ struct dummy_buffer dummy_buffer[STF_DUMMY_MODULE_NUMS];
-+ struct vin_isr_ops *isr_ops;
-+ atomic_t ref_count;
-+ struct mutex power_lock; /* serialize power control*/
-+ int power_count;
-+};
-+
-+int stf_vin_clk_enable(struct stf_vin_dev *vin_dev, enum link link);
-+int stf_vin_clk_disable(struct stf_vin_dev *vin_dev, enum link link);
-+int stf_vin_wr_stream_set(struct stf_vin_dev *vin_dev);
-+int stf_vin_stream_set(struct stf_vin_dev *vin_dev, enum link link);
-+void stf_vin_wr_irq_enable(struct stf_vin_dev *vin_dev, int enable);
-+void stf_vin_wr_set_ping_addr(struct stf_vin_dev *vin_dev, dma_addr_t addr);
-+void stf_vin_wr_set_pong_addr(struct stf_vin_dev *vin_dev, dma_addr_t addr);
-+void stf_vin_isp_set_yuv_addr(struct stf_vin_dev *vin_dev,
-+ dma_addr_t y_addr, dma_addr_t uv_addr);
-+irqreturn_t stf_vin_wr_irq_handler(int irq, void *priv);
-+irqreturn_t stf_vin_isp_irq_handler(int irq, void *priv);
-+irqreturn_t stf_vin_isp_irq_csiline_handler(int irq, void *priv);
-+int stf_vin_subdev_init(struct stfcamss *stfcamss);
-+int stf_vin_register(struct stf_vin_dev *vin_dev, struct v4l2_device *v4l2_dev);
-+int stf_vin_unregister(struct stf_vin_dev *vin_dev);
-+enum isp_pad_id stf_vin_map_isp_pad(enum vin_line_id line, enum isp_pad_id def);
-+
-+#endif /* STF_VIN_H */
---- /dev/null
-+++ b/drivers/media/platform/starfive/stf_vin_hw_ops.c
-@@ -0,0 +1,241 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * stf_vin_hw_ops.c
-+ *
-+ * Register interface file for StarFive VIN module driver
-+ *
-+ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
-+ */
-+#include "stf_camss.h"
-+
-+static void vin_intr_clear(struct stfcamss *stfcamss)
-+{
-+ stf_syscon_reg_set_bit(stfcamss, SYSCONSAIF_SYSCFG(28),
-+ U0_VIN_INTR_CLEAN);
-+ stf_syscon_reg_clear_bit(stfcamss, SYSCONSAIF_SYSCFG(28),
-+ U0_VIN_INTR_CLEAN);
-+}
-+
-+irqreturn_t stf_vin_wr_irq_handler(int irq, void *priv)
-+{
-+ struct stf_vin_dev *vin_dev = priv;
-+ struct stfcamss *stfcamss = vin_dev->stfcamss;
-+ struct dummy_buffer *dummy_buffer =
-+ &vin_dev->dummy_buffer[STF_DUMMY_VIN];
-+
-+ if (atomic_dec_if_positive(&dummy_buffer->frame_skip) < 0) {
-+ vin_dev->isr_ops->isr_change_buffer(&vin_dev->line[VIN_LINE_WR]);
-+ vin_dev->isr_ops->isr_buffer_done(&vin_dev->line[VIN_LINE_WR]);
-+ }
-+
-+ vin_intr_clear(stfcamss);
-+
-+ return IRQ_HANDLED;
-+}
-+
-+irqreturn_t stf_vin_isp_irq_handler(int irq, void *priv)
-+{
-+ struct stf_vin_dev *vin_dev = priv;
-+ u32 int_status;
-+
-+ int_status = stf_isp_reg_read(vin_dev->stfcamss, ISP_REG_ISP_CTRL_0);
-+
-+ if (int_status & ISPC_INTS) {
-+ if ((int_status & ISPC_ENUO))
-+ vin_dev->isr_ops->isr_buffer_done(
-+ &vin_dev->line[VIN_LINE_ISP]);
-+
-+ /* clear interrupt */
-+ stf_isp_reg_write(vin_dev->stfcamss,
-+ ISP_REG_ISP_CTRL_0,
-+ (int_status & ~EN_INT_ALL) |
-+ EN_INT_ISP_DONE |
-+ EN_INT_CSI_DONE |
-+ EN_INT_SC_DONE);
-+ }
-+
-+ return IRQ_HANDLED;
-+}
-+
-+irqreturn_t stf_vin_isp_irq_csiline_handler(int irq, void *priv)
-+{
-+ struct stf_vin_dev *vin_dev = priv;
-+ struct stf_isp_dev *isp_dev;
-+ u32 int_status;
-+
-+ isp_dev = &vin_dev->stfcamss->isp_dev;
-+
-+ int_status = stf_isp_reg_read(vin_dev->stfcamss, ISP_REG_ISP_CTRL_0);
-+ if (int_status & ISPC_SCFEINT) {
-+ struct dummy_buffer *dummy_buffer =
-+ &vin_dev->dummy_buffer[STF_DUMMY_ISP];
-+
-+ if (atomic_dec_if_positive(&dummy_buffer->frame_skip) < 0) {
-+ if ((int_status & ISPC_ENUO))
-+ vin_dev->isr_ops->isr_change_buffer(
-+ &vin_dev->line[VIN_LINE_ISP]);
-+ }
-+
-+ stf_isp_reg_set_bit(isp_dev->stfcamss, ISP_REG_CSIINTS,
-+ CSI_INTS_MASK, CSI_INTS(0x3));
-+ stf_isp_reg_set_bit(isp_dev->stfcamss, ISP_REG_IESHD,
-+ SHAD_UP_M | SHAD_UP_EN, 0x3);
-+
-+ /* clear interrupt */
-+ stf_isp_reg_write(vin_dev->stfcamss, ISP_REG_ISP_CTRL_0,
-+ (int_status & ~EN_INT_ALL) | EN_INT_LINE_INT);
-+ }
-+
-+ return IRQ_HANDLED;
-+}
-+
-+int stf_vin_clk_enable(struct stf_vin_dev *vin_dev, enum link link)
-+{
-+ struct stfcamss *stfcamss = vin_dev->stfcamss;
-+
-+ clk_set_rate(stfcamss->sys_clk[STF_CLK_APB_FUNC].clk, 49500000);
-+
-+ switch (link) {
-+ case LINK_CSI_TO_WR:
-+ clk_set_rate(stfcamss->sys_clk[STF_CLK_MIPI_RX0_PXL].clk,
-+ 198000000);
-+ reset_control_deassert(stfcamss->sys_rst[STF_RST_AXIWR].rstc);
-+ clk_set_parent(stfcamss->sys_clk[STF_CLK_AXIWR].clk,
-+ stfcamss->sys_clk[STF_CLK_MIPI_RX0_PXL].clk);
-+ break;
-+ case LINK_CSI_TO_ISP:
-+ clk_set_rate(stfcamss->sys_clk[STF_CLK_MIPI_RX0_PXL].clk,
-+ 198000000);
-+ clk_set_parent(stfcamss->sys_clk[STF_CLK_WRAPPER_CLK_C].clk,
-+ stfcamss->sys_clk[STF_CLK_MIPI_RX0_PXL].clk);
-+ break;
-+ case LINK_DVP_TO_WR:
-+ case LINK_DVP_TO_ISP:
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ return 0;
-+}
-+
-+int stf_vin_clk_disable(struct stf_vin_dev *vin_dev, enum link link)
-+{
-+ struct stfcamss *stfcamss = vin_dev->stfcamss;
-+
-+ switch (link) {
-+ case LINK_CSI_TO_WR:
-+ reset_control_assert(stfcamss->sys_rst[STF_RST_AXIWR].rstc);
-+ break;
-+ case LINK_CSI_TO_ISP:
-+ break;
-+ case LINK_DVP_TO_WR:
-+ case LINK_DVP_TO_ISP:
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ return 0;
-+}
-+
-+int stf_vin_wr_stream_set(struct stf_vin_dev *vin_dev)
-+{
-+ struct stfcamss *stfcamss = vin_dev->stfcamss;
-+
-+ /* make the axiwr alway on */
-+ stf_syscon_reg_set_bit(stfcamss, SYSCONSAIF_SYSCFG(20),
-+ U0_VIN_AXIWR0_EN);
-+
-+ return 0;
-+}
-+
-+int stf_vin_stream_set(struct stf_vin_dev *vin_dev, enum link link)
-+{
-+ struct stfcamss *stfcamss = vin_dev->stfcamss;
-+ u32 val;
-+
-+ switch (link) {
-+ case LINK_CSI_TO_WR:
-+ val = stf_syscon_reg_read(stfcamss, SYSCONSAIF_SYSCFG(20));
-+ val &= ~U0_VIN_CHANNEL_SEL_MASK;
-+ val |= CHANNEL(0);
-+ stf_syscon_reg_write(stfcamss, SYSCONSAIF_SYSCFG(20), val);
-+
-+ val = stf_syscon_reg_read(stfcamss, SYSCONSAIF_SYSCFG(28));
-+ val &= ~U0_VIN_PIX_CT_MASK;
-+ val |= PIX_CT(1);
-+
-+ val &= ~U0_VIN_PIXEL_HEIGH_BIT_SEL_MAKS;
-+ val |= PIXEL_HEIGH_BIT_SEL(0);
-+
-+ val &= ~U0_VIN_PIX_CNT_END_MASK;
-+ val |= PIX_CNT_END(IMAGE_MAX_WIDTH / 4 - 1);
-+
-+ stf_syscon_reg_write(stfcamss, SYSCONSAIF_SYSCFG(28), val);
-+ break;
-+ case LINK_CSI_TO_ISP:
-+ val = stf_syscon_reg_read(stfcamss, SYSCONSAIF_SYSCFG(36));
-+ val &= ~U0_VIN_MIPI_BYTE_EN_ISP0_MASK;
-+ val |= U0_VIN_MIPI_BYTE_EN_ISP0(0);
-+
-+ val &= ~U0_VIN_MIPI_CHANNEL_SEL0_MASK;
-+ val |= U0_VIN_MIPI_CHANNEL_SEL0(0);
-+
-+ val &= ~U0_VIN_PIX_NUM_MASK;
-+ val |= U0_VIN_PIX_NUM(0);
-+
-+ val &= ~U0_VIN_P_I_MIPI_HAEDER_EN0_MASK;
-+ val |= U0_VIN_P_I_MIPI_HAEDER_EN0(1);
-+
-+ stf_syscon_reg_write(stfcamss, SYSCONSAIF_SYSCFG(36), val);
-+ break;
-+ case LINK_DVP_TO_WR:
-+ case LINK_DVP_TO_ISP:
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ return 0;
-+}
-+
-+void stf_vin_wr_irq_enable(struct stf_vin_dev *vin_dev, int enable)
-+{
-+ struct stfcamss *stfcamss = vin_dev->stfcamss;
-+
-+ if (enable) {
-+ stf_syscon_reg_clear_bit(stfcamss, SYSCONSAIF_SYSCFG(28),
-+ U0_VIN_INTR_M);
-+ } else {
-+ /* clear vin interrupt */
-+ stf_syscon_reg_set_bit(stfcamss, SYSCONSAIF_SYSCFG(28),
-+ U0_VIN_INTR_CLEAN);
-+ stf_syscon_reg_clear_bit(stfcamss, SYSCONSAIF_SYSCFG(28),
-+ U0_VIN_INTR_CLEAN);
-+ stf_syscon_reg_set_bit(stfcamss, SYSCONSAIF_SYSCFG(28),
-+ U0_VIN_INTR_M);
-+ }
-+}
-+
-+void stf_vin_wr_set_ping_addr(struct stf_vin_dev *vin_dev, dma_addr_t addr)
-+{
-+ struct stfcamss *stfcamss = vin_dev->stfcamss;
-+
-+ /* set the start address */
-+ stf_syscon_reg_write(stfcamss, SYSCONSAIF_SYSCFG(32), (long)addr);
-+}
-+
-+void stf_vin_wr_set_pong_addr(struct stf_vin_dev *vin_dev, dma_addr_t addr)
-+{
-+ struct stfcamss *stfcamss = vin_dev->stfcamss;
-+
-+ /* set the start address */
-+ stf_syscon_reg_write(stfcamss, SYSCONSAIF_SYSCFG(24), (long)addr);
-+}
-+
-+void stf_vin_isp_set_yuv_addr(struct stf_vin_dev *vin_dev,
-+ dma_addr_t y_addr, dma_addr_t uv_addr)
-+{
-+ stf_isp_reg_write(vin_dev->stfcamss,
-+ ISP_REG_Y_PLANE_START_ADDR, y_addr);
-+ stf_isp_reg_write(vin_dev->stfcamss,
-+ ISP_REG_UV_PLANE_START_ADDR, uv_addr);
-+}
diff --git a/target/linux/starfive/patches-6.1/0087-dt-bindings-phy-Add-StarFive-JH7110-USB-PHY.patch b/target/linux/starfive/patches-6.1/0087-dt-bindings-phy-Add-StarFive-JH7110-USB-PHY.patch
deleted file mode 100644
index 08eee9ca9e..0000000000
--- a/target/linux/starfive/patches-6.1/0087-dt-bindings-phy-Add-StarFive-JH7110-USB-PHY.patch
+++ /dev/null
@@ -1,68 +0,0 @@
-From 2ebd77fa8fb95f60b275cefb98ea7d6f4df06e55 Mon Sep 17 00:00:00 2001
-From: Minda Chen <minda.chen@starfivetech.com>
-Date: Thu, 18 May 2023 19:27:44 +0800
-Subject: [PATCH 087/122] dt-bindings: phy: Add StarFive JH7110 USB PHY
-
-Add StarFive JH7110 SoC USB 2.0 PHY dt-binding.
-
-Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
-Reviewed-by: Hal Feng <hal.feng@starfivetech.com>
-Reviewed-by: Rob Herring <robh@kernel.org>
----
- .../bindings/phy/starfive,jh7110-usb-phy.yaml | 50 +++++++++++++++++++
- 1 file changed, 50 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/phy/starfive,jh7110-usb-phy.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/phy/starfive,jh7110-usb-phy.yaml
-@@ -0,0 +1,50 @@
-+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/phy/starfive,jh7110-usb-phy.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: StarFive JH7110 USB 2.0 PHY
-+
-+maintainers:
-+ - Minda Chen <minda.chen@starfivetech.com>
-+
-+properties:
-+ compatible:
-+ const: starfive,jh7110-usb-phy
-+
-+ reg:
-+ maxItems: 1
-+
-+ "#phy-cells":
-+ const: 0
-+
-+ clocks:
-+ items:
-+ - description: PHY 125m
-+ - description: app 125m
-+
-+ clock-names:
-+ items:
-+ - const: 125m
-+ - const: app_125m
-+
-+required:
-+ - compatible
-+ - reg
-+ - clocks
-+ - clock-names
-+ - "#phy-cells"
-+
-+additionalProperties: false
-+
-+examples:
-+ - |
-+ phy@10200000 {
-+ compatible = "starfive,jh7110-usb-phy";
-+ reg = <0x10200000 0x10000>;
-+ clocks = <&syscrg 95>,
-+ <&stgcrg 6>;
-+ clock-names = "125m", "app_125m";
-+ #phy-cells = <0>;
-+ };
diff --git a/target/linux/starfive/patches-6.1/0088-dt-bindings-phy-Add-StarFive-JH7110-PCIe-PHY.patch b/target/linux/starfive/patches-6.1/0088-dt-bindings-phy-Add-StarFive-JH7110-PCIe-PHY.patch
deleted file mode 100644
index 6911bba9d2..0000000000
--- a/target/linux/starfive/patches-6.1/0088-dt-bindings-phy-Add-StarFive-JH7110-PCIe-PHY.patch
+++ /dev/null
@@ -1,77 +0,0 @@
-From d57245d420a2ced6a588cc6e03e2eaacbbf1bfb2 Mon Sep 17 00:00:00 2001
-From: Minda Chen <minda.chen@starfivetech.com>
-Date: Thu, 18 May 2023 19:27:45 +0800
-Subject: [PATCH 088/122] dt-bindings: phy: Add StarFive JH7110 PCIe PHY
-
-Add StarFive JH7110 SoC PCIe 2.0 PHY dt-binding.
-PCIe PHY0 (phy@10210000) can be used as USB 3.0 PHY.
-
-Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
-Reviewed-by: Hal Feng <hal.feng@starfivetech.com>
-Reviewed-by: Rob Herring <robh@kernel.org>
----
- .../phy/starfive,jh7110-pcie-phy.yaml | 58 +++++++++++++++++++
- 1 file changed, 58 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/phy/starfive,jh7110-pcie-phy.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/phy/starfive,jh7110-pcie-phy.yaml
-@@ -0,0 +1,58 @@
-+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/phy/starfive,jh7110-pcie-phy.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: StarFive JH7110 PCIe 2.0 PHY
-+
-+maintainers:
-+ - Minda Chen <minda.chen@starfivetech.com>
-+
-+properties:
-+ compatible:
-+ const: starfive,jh7110-pcie-phy
-+
-+ reg:
-+ maxItems: 1
-+
-+ "#phy-cells":
-+ const: 0
-+
-+ starfive,sys-syscon:
-+ $ref: /schemas/types.yaml#/definitions/phandle-array
-+ items:
-+ - items:
-+ - description: phandle to System Register Controller sys_syscon node.
-+ - description: PHY connect offset of SYS_SYSCONSAIF__SYSCFG register for USB PHY.
-+ description:
-+ The phandle to System Register Controller syscon node and the PHY connect offset
-+ of SYS_SYSCONSAIF__SYSCFG register. Connect PHY to USB3 controller.
-+
-+ starfive,stg-syscon:
-+ $ref: /schemas/types.yaml#/definitions/phandle-array
-+ items:
-+ - items:
-+ - description: phandle to System Register Controller stg_syscon node.
-+ - description: PHY mode offset of STG_SYSCONSAIF__SYSCFG register.
-+ - description: PHY enable for USB offset of STG_SYSCONSAIF__SYSCFG register.
-+ description:
-+ The phandle to System Register Controller syscon node and the offset
-+ of STG_SYSCONSAIF__SYSCFG register for PCIe PHY. Total 2 regsisters offset.
-+
-+required:
-+ - compatible
-+ - reg
-+ - "#phy-cells"
-+
-+additionalProperties: false
-+
-+examples:
-+ - |
-+ phy@10210000 {
-+ compatible = "starfive,jh7110-pcie-phy";
-+ reg = <0x10210000 0x10000>;
-+ #phy-cells = <0>;
-+ starfive,sys-syscon = <&sys_syscon 0x18>;
-+ starfive,stg-syscon = <&stg_syscon 0x148 0x1f4>;
-+ };
diff --git a/target/linux/starfive/patches-6.1/0089-phy-starfive-Add-JH7110-USB-2.0-PHY-driver.patch b/target/linux/starfive/patches-6.1/0089-phy-starfive-Add-JH7110-USB-2.0-PHY-driver.patch
deleted file mode 100644
index 0b608868c1..0000000000
--- a/target/linux/starfive/patches-6.1/0089-phy-starfive-Add-JH7110-USB-2.0-PHY-driver.patch
+++ /dev/null
@@ -1,192 +0,0 @@
-From 3d74980ca3ba91dae6e84fbc23750e702e71d41a Mon Sep 17 00:00:00 2001
-From: Minda Chen <minda.chen@starfivetech.com>
-Date: Thu, 18 May 2023 19:27:46 +0800
-Subject: [PATCH 089/122] phy: starfive: Add JH7110 USB 2.0 PHY driver
-
-Add Starfive JH7110 SoC USB 2.0 PHY driver support.
-USB 2.0 PHY default connect to Cadence USB controller.
-
-Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
----
- drivers/phy/starfive/Kconfig | 11 ++
- drivers/phy/starfive/Makefile | 1 +
- drivers/phy/starfive/phy-jh7110-usb.c | 150 ++++++++++++++++++++++++++
- 3 files changed, 162 insertions(+)
- create mode 100644 drivers/phy/starfive/phy-jh7110-usb.c
-
---- a/drivers/phy/starfive/Kconfig
-+++ b/drivers/phy/starfive/Kconfig
-@@ -11,3 +11,14 @@ config PHY_STARFIVE_DPHY_RX
- Choose this option if you have a StarFive D-PHY in your
- system. If M is selected, the module will be called
- phy-starfive-dphy-rx.
-+
-+config PHY_STARFIVE_JH7110_USB
-+ tristate "Starfive JH7110 USB 2.0 PHY support"
-+ depends on USB_SUPPORT
-+ select GENERIC_PHY
-+ select USB_PHY
-+ help
-+ Enable this to support the StarFive USB 2.0 PHY,
-+ used with the Cadence USB controller.
-+ If M is selected, the module will be called
-+ phy-jh7110-usb.ko.
---- a/drivers/phy/starfive/Makefile
-+++ b/drivers/phy/starfive/Makefile
-@@ -1,2 +1,3 @@
- # SPDX-License-Identifier: GPL-2.0
- obj-$(CONFIG_PHY_STARFIVE_DPHY_RX) += phy-starfive-dphy-rx.o
-+obj-$(CONFIG_PHY_STARFIVE_JH7110_USB) += phy-jh7110-usb.o
---- /dev/null
-+++ b/drivers/phy/starfive/phy-jh7110-usb.c
-@@ -0,0 +1,150 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+/*
-+ * StarFive JH7110 USB 2.0 PHY driver
-+ *
-+ * Copyright (C) 2023 StarFive Technology Co., Ltd.
-+ * Author: Minda Chen <minda.chen@starfivetech.com>
-+ */
-+
-+#include <linux/bits.h>
-+#include <linux/clk.h>
-+#include <linux/err.h>
-+#include <linux/io.h>
-+#include <linux/module.h>
-+#include <linux/phy/phy.h>
-+#include <linux/platform_device.h>
-+#include <linux/usb/of.h>
-+
-+#define USB_125M_CLK_RATE 125000000
-+#define USB_LS_KEEPALIVE_OFF 0x4
-+#define USB_LS_KEEPALIVE_ENABLE BIT(4)
-+
-+struct jh7110_usb2_phy {
-+ struct phy *phy;
-+ void __iomem *regs;
-+ struct clk *usb_125m_clk;
-+ struct clk *app_125m;
-+ enum phy_mode mode;
-+};
-+
-+static void jh7110_usb2_mode_set(struct jh7110_usb2_phy *phy)
-+{
-+ unsigned int val;
-+
-+ if (phy->mode != PHY_MODE_USB_HOST) {
-+ /* Enable the LS speed keep-alive signal */
-+ val = readl(phy->regs + USB_LS_KEEPALIVE_OFF);
-+ val |= USB_LS_KEEPALIVE_ENABLE;
-+ writel(val, phy->regs + USB_LS_KEEPALIVE_OFF);
-+ }
-+}
-+
-+static int jh7110_usb2_phy_set_mode(struct phy *_phy,
-+ enum phy_mode mode, int submode)
-+{
-+ struct jh7110_usb2_phy *phy = phy_get_drvdata(_phy);
-+
-+ switch (mode) {
-+ case PHY_MODE_USB_HOST:
-+ case PHY_MODE_USB_DEVICE:
-+ case PHY_MODE_USB_OTG:
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ if (mode != phy->mode) {
-+ dev_dbg(&_phy->dev, "Changing phy to %d\n", mode);
-+ phy->mode = mode;
-+ jh7110_usb2_mode_set(phy);
-+ }
-+
-+ return 0;
-+}
-+
-+static int jh7110_usb2_phy_init(struct phy *_phy)
-+{
-+ struct jh7110_usb2_phy *phy = phy_get_drvdata(_phy);
-+ int ret;
-+
-+ ret = clk_set_rate(phy->usb_125m_clk, USB_125M_CLK_RATE);
-+ if (ret)
-+ return ret;
-+
-+ ret = clk_prepare_enable(phy->app_125m);
-+ if (ret)
-+ return ret;
-+
-+ return 0;
-+}
-+
-+static int jh7110_usb2_phy_exit(struct phy *_phy)
-+{
-+ struct jh7110_usb2_phy *phy = phy_get_drvdata(_phy);
-+
-+ clk_disable_unprepare(phy->app_125m);
-+
-+ return 0;
-+}
-+
-+static const struct phy_ops jh7110_usb2_phy_ops = {
-+ .init = jh7110_usb2_phy_init,
-+ .exit = jh7110_usb2_phy_exit,
-+ .set_mode = jh7110_usb2_phy_set_mode,
-+ .owner = THIS_MODULE,
-+};
-+
-+static int jh7110_usb_phy_probe(struct platform_device *pdev)
-+{
-+ struct jh7110_usb2_phy *phy;
-+ struct device *dev = &pdev->dev;
-+ struct phy_provider *phy_provider;
-+
-+ phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL);
-+ if (!phy)
-+ return -ENOMEM;
-+
-+ phy->usb_125m_clk = devm_clk_get(dev, "125m");
-+ if (IS_ERR(phy->usb_125m_clk))
-+ return dev_err_probe(dev, PTR_ERR(phy->usb_125m_clk),
-+ "Failed to get 125m clock\n");
-+
-+ phy->app_125m = devm_clk_get(dev, "app_125m");
-+ if (IS_ERR(phy->app_125m))
-+ return dev_err_probe(dev, PTR_ERR(phy->app_125m),
-+ "Failed to get app 125m clock\n");
-+
-+ phy->regs = devm_platform_ioremap_resource(pdev, 0);
-+ if (IS_ERR(phy->regs))
-+ return dev_err_probe(dev, PTR_ERR(phy->regs),
-+ "Failed to map phy base\n");
-+
-+ phy->phy = devm_phy_create(dev, NULL, &jh7110_usb2_phy_ops);
-+ if (IS_ERR(phy->phy))
-+ return dev_err_probe(dev, PTR_ERR(phy->phy),
-+ "Failed to create phy\n");
-+
-+ phy_set_drvdata(phy->phy, phy);
-+ phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
-+
-+ return PTR_ERR_OR_ZERO(phy_provider);
-+}
-+
-+static const struct of_device_id jh7110_usb_phy_of_match[] = {
-+ { .compatible = "starfive,jh7110-usb-phy" },
-+ { /* sentinel */ },
-+};
-+MODULE_DEVICE_TABLE(of, jh7110_usb_phy_of_match);
-+
-+static struct platform_driver jh7110_usb_phy_driver = {
-+ .probe = jh7110_usb_phy_probe,
-+ .driver = {
-+ .of_match_table = jh7110_usb_phy_of_match,
-+ .name = "jh7110-usb-phy",
-+ }
-+};
-+module_platform_driver(jh7110_usb_phy_driver);
-+
-+MODULE_DESCRIPTION("StarFive JH7110 USB 2.0 PHY driver");
-+MODULE_AUTHOR("Minda Chen <minda.chen@starfivetech.com>");
-+MODULE_LICENSE("GPL");
diff --git a/target/linux/starfive/patches-6.1/0090-phy-starfive-Add-JH7110-PCIE-2.0-PHY-driver.patch b/target/linux/starfive/patches-6.1/0090-phy-starfive-Add-JH7110-PCIE-2.0-PHY-driver.patch
deleted file mode 100644
index 452ffd25c6..0000000000
--- a/target/linux/starfive/patches-6.1/0090-phy-starfive-Add-JH7110-PCIE-2.0-PHY-driver.patch
+++ /dev/null
@@ -1,250 +0,0 @@
-From d900724fdae7c41a663b31e1ed9b8ba10b998e6f Mon Sep 17 00:00:00 2001
-From: Minda Chen <minda.chen@starfivetech.com>
-Date: Thu, 18 May 2023 19:27:47 +0800
-Subject: [PATCH 090/122] phy: starfive: Add JH7110 PCIE 2.0 PHY driver
-
-Add Starfive JH7110 SoC PCIe 2.0 PHY driver support.
-PCIe 2.0 PHY default connect to PCIe controller.
-PCIe PHY can connect to USB 3.0 controller.
-
-Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
----
- drivers/phy/starfive/Kconfig | 10 ++
- drivers/phy/starfive/Makefile | 1 +
- drivers/phy/starfive/phy-jh7110-pcie.c | 204 +++++++++++++++++++++++++
- 3 files changed, 215 insertions(+)
- create mode 100644 drivers/phy/starfive/phy-jh7110-pcie.c
-
---- a/drivers/phy/starfive/Kconfig
-+++ b/drivers/phy/starfive/Kconfig
-@@ -12,6 +12,16 @@ config PHY_STARFIVE_DPHY_RX
- system. If M is selected, the module will be called
- phy-starfive-dphy-rx.
-
-+config PHY_STARFIVE_JH7110_PCIE
-+ tristate "Starfive JH7110 PCIE 2.0/USB 3.0 PHY support"
-+ select GENERIC_PHY
-+ select USB_PHY
-+ help
-+ Enable this to support the StarFive PCIe 2.0 PHY,
-+ or used as USB 3.0 PHY.
-+ If M is selected, the module will be called
-+ phy-jh7110-pcie.ko.
-+
- config PHY_STARFIVE_JH7110_USB
- tristate "Starfive JH7110 USB 2.0 PHY support"
- depends on USB_SUPPORT
---- a/drivers/phy/starfive/Makefile
-+++ b/drivers/phy/starfive/Makefile
-@@ -1,3 +1,4 @@
- # SPDX-License-Identifier: GPL-2.0
- obj-$(CONFIG_PHY_STARFIVE_DPHY_RX) += phy-starfive-dphy-rx.o
-+obj-$(CONFIG_PHY_STARFIVE_JH7110_PCIE) += phy-jh7110-pcie.o
- obj-$(CONFIG_PHY_STARFIVE_JH7110_USB) += phy-jh7110-usb.o
---- /dev/null
-+++ b/drivers/phy/starfive/phy-jh7110-pcie.c
-@@ -0,0 +1,204 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+/*
-+ * StarFive JH7110 PCIe 2.0 PHY driver
-+ *
-+ * Copyright (C) 2023 StarFive Technology Co., Ltd.
-+ * Author: Minda Chen <minda.chen@starfivetech.com>
-+ */
-+
-+#include <linux/bits.h>
-+#include <linux/clk.h>
-+#include <linux/err.h>
-+#include <linux/io.h>
-+#include <linux/module.h>
-+#include <linux/mfd/syscon.h>
-+#include <linux/phy/phy.h>
-+#include <linux/platform_device.h>
-+#include <linux/regmap.h>
-+
-+#define PCIE_KVCO_LEVEL_OFF 0x28
-+#define PCIE_USB3_PHY_PLL_CTL_OFF 0x7c
-+#define PCIE_KVCO_TUNE_SIGNAL_OFF 0x80
-+#define PCIE_USB3_PHY_ENABLE BIT(4)
-+#define PHY_KVCO_FINE_TUNE_LEVEL 0x91
-+#define PHY_KVCO_FINE_TUNE_SIGNALS 0xc
-+
-+#define USB_PDRSTN_SPLIT BIT(17)
-+
-+#define PCIE_PHY_MODE BIT(20)
-+#define PCIE_PHY_MODE_MASK GENMASK(21, 20)
-+#define PCIE_USB3_BUS_WIDTH_MASK GENMASK(3, 2)
-+#define PCIE_USB3_BUS_WIDTH BIT(3)
-+#define PCIE_USB3_RATE_MASK GENMASK(6, 5)
-+#define PCIE_USB3_RX_STANDBY_MASK BIT(7)
-+#define PCIE_USB3_PHY_ENABLE BIT(4)
-+
-+struct jh7110_pcie_phy {
-+ struct phy *phy;
-+ struct regmap *stg_syscon;
-+ struct regmap *sys_syscon;
-+ void __iomem *regs;
-+ u32 sys_phy_connect;
-+ u32 stg_pcie_mode;
-+ u32 stg_pcie_usb;
-+ enum phy_mode mode;
-+};
-+
-+static int phy_usb3_mode_set(struct jh7110_pcie_phy *data)
-+{
-+ if (!data->stg_syscon || !data->sys_syscon) {
-+ dev_err(&data->phy->dev, "doesn't support usb3 mode\n");
-+ return -EINVAL;
-+ }
-+
-+ regmap_update_bits(data->stg_syscon, data->stg_pcie_mode,
-+ PCIE_PHY_MODE_MASK, PCIE_PHY_MODE);
-+ regmap_update_bits(data->stg_syscon, data->stg_pcie_usb,
-+ PCIE_USB3_BUS_WIDTH_MASK, 0);
-+ regmap_update_bits(data->stg_syscon, data->stg_pcie_usb,
-+ PCIE_USB3_PHY_ENABLE, PCIE_USB3_PHY_ENABLE);
-+
-+ /* Connect usb 3.0 phy mode */
-+ regmap_update_bits(data->sys_syscon, data->sys_phy_connect,
-+ USB_PDRSTN_SPLIT, 0);
-+
-+ /* Configuare spread-spectrum mode: down-spread-spectrum */
-+ writel(PCIE_USB3_PHY_ENABLE, data->regs + PCIE_USB3_PHY_PLL_CTL_OFF);
-+
-+ return 0;
-+}
-+
-+static void phy_pcie_mode_set(struct jh7110_pcie_phy *data)
-+{
-+ u32 val;
-+
-+ /* default is PCIe mode */
-+ if (!data->stg_syscon || !data->sys_syscon)
-+ return;
-+
-+ regmap_update_bits(data->stg_syscon, data->stg_pcie_mode,
-+ PCIE_PHY_MODE_MASK, 0);
-+ regmap_update_bits(data->stg_syscon, data->stg_pcie_usb,
-+ PCIE_USB3_BUS_WIDTH_MASK,
-+ PCIE_USB3_BUS_WIDTH);
-+ regmap_update_bits(data->stg_syscon, data->stg_pcie_usb,
-+ PCIE_USB3_PHY_ENABLE, 0);
-+
-+ regmap_update_bits(data->sys_syscon, data->sys_phy_connect,
-+ USB_PDRSTN_SPLIT, 0);
-+
-+ val = readl(data->regs + PCIE_USB3_PHY_PLL_CTL_OFF);
-+ val &= ~PCIE_USB3_PHY_ENABLE;
-+ writel(val, data->regs + PCIE_USB3_PHY_PLL_CTL_OFF);
-+}
-+
-+static void phy_kvco_gain_set(struct jh7110_pcie_phy *phy)
-+{
-+ /* PCIe Multi-PHY PLL KVCO Gain fine tune settings: */
-+ writel(PHY_KVCO_FINE_TUNE_LEVEL, phy->regs + PCIE_KVCO_LEVEL_OFF);
-+ writel(PHY_KVCO_FINE_TUNE_SIGNALS, phy->regs + PCIE_KVCO_TUNE_SIGNAL_OFF);
-+}
-+
-+static int jh7110_pcie_phy_set_mode(struct phy *_phy,
-+ enum phy_mode mode, int submode)
-+{
-+ struct jh7110_pcie_phy *phy = phy_get_drvdata(_phy);
-+ int ret;
-+
-+ if (mode == phy->mode)
-+ return 0;
-+
-+ switch (mode) {
-+ case PHY_MODE_USB_HOST:
-+ case PHY_MODE_USB_DEVICE:
-+ case PHY_MODE_USB_OTG:
-+ ret = phy_usb3_mode_set(phy);
-+ if (ret)
-+ return ret;
-+ break;
-+ case PHY_MODE_PCIE:
-+ phy_pcie_mode_set(phy);
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ dev_dbg(&_phy->dev, "Changing phy mode to %d\n", mode);
-+ phy->mode = mode;
-+
-+ return 0;
-+}
-+
-+static const struct phy_ops jh7110_pcie_phy_ops = {
-+ .set_mode = jh7110_pcie_phy_set_mode,
-+ .owner = THIS_MODULE,
-+};
-+
-+static int jh7110_pcie_phy_probe(struct platform_device *pdev)
-+{
-+ struct jh7110_pcie_phy *phy;
-+ struct device *dev = &pdev->dev;
-+ struct phy_provider *phy_provider;
-+ u32 args[2];
-+
-+ phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL);
-+ if (!phy)
-+ return -ENOMEM;
-+
-+ phy->regs = devm_platform_ioremap_resource(pdev, 0);
-+ if (IS_ERR(phy->regs))
-+ return PTR_ERR(phy->regs);
-+
-+ phy->phy = devm_phy_create(dev, NULL, &jh7110_pcie_phy_ops);
-+ if (IS_ERR(phy->phy))
-+ return dev_err_probe(dev, PTR_ERR(phy->regs),
-+ "Failed to map phy base\n");
-+
-+ phy->sys_syscon =
-+ syscon_regmap_lookup_by_phandle_args(pdev->dev.of_node,
-+ "starfive,sys-syscon",
-+ 1, args);
-+
-+ if (!IS_ERR_OR_NULL(phy->sys_syscon))
-+ phy->sys_phy_connect = args[0];
-+ else
-+ phy->sys_syscon = NULL;
-+
-+ phy->stg_syscon =
-+ syscon_regmap_lookup_by_phandle_args(pdev->dev.of_node,
-+ "starfive,stg-syscon",
-+ 2, args);
-+
-+ if (!IS_ERR_OR_NULL(phy->stg_syscon)) {
-+ phy->stg_pcie_mode = args[0];
-+ phy->stg_pcie_usb = args[1];
-+ } else {
-+ phy->stg_syscon = NULL;
-+ }
-+
-+ phy_kvco_gain_set(phy);
-+
-+ phy_set_drvdata(phy->phy, phy);
-+ phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
-+
-+ return PTR_ERR_OR_ZERO(phy_provider);
-+}
-+
-+static const struct of_device_id jh7110_pcie_phy_of_match[] = {
-+ { .compatible = "starfive,jh7110-pcie-phy" },
-+ { /* sentinel */ },
-+};
-+MODULE_DEVICE_TABLE(of, jh7110_pcie_phy_of_match);
-+
-+static struct platform_driver jh7110_pcie_phy_driver = {
-+ .probe = jh7110_pcie_phy_probe,
-+ .driver = {
-+ .of_match_table = jh7110_pcie_phy_of_match,
-+ .name = "jh7110-pcie-phy",
-+ }
-+};
-+module_platform_driver(jh7110_pcie_phy_driver);
-+
-+MODULE_DESCRIPTION("StarFive JH7110 PCIe 2.0 PHY driver");
-+MODULE_AUTHOR("Minda Chen <minda.chen@starfivetech.com>");
-+MODULE_LICENSE("GPL");
diff --git a/target/linux/starfive/patches-6.1/0091-dt-bindings-usb-Add-StarFive-JH7110-USB-controller.patch b/target/linux/starfive/patches-6.1/0091-dt-bindings-usb-Add-StarFive-JH7110-USB-controller.patch
deleted file mode 100644
index 8a7575094c..0000000000
--- a/target/linux/starfive/patches-6.1/0091-dt-bindings-usb-Add-StarFive-JH7110-USB-controller.patch
+++ /dev/null
@@ -1,135 +0,0 @@
-From 6a2392c96041d0599d33799a9aedbcdbfb4030b6 Mon Sep 17 00:00:00 2001
-From: Minda Chen <minda.chen@starfivetech.com>
-Date: Thu, 18 May 2023 19:27:48 +0800
-Subject: [PATCH 091/122] dt-bindings: usb: Add StarFive JH7110 USB controller
-
-StarFive JH7110 platforms USB have a wrapper module around
-the Cadence USBSS-DRD controller. Add binding information doc
-for that.
-
-Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
-Reviewed-by: Peter Chen <peter.chen@kernel.org>
-Reviewed-by: Hal Feng <hal.feng@starfivetech.com>
----
- .../bindings/usb/starfive,jh7110-usb.yaml | 115 ++++++++++++++++++
- 1 file changed, 115 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/usb/starfive,jh7110-usb.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/usb/starfive,jh7110-usb.yaml
-@@ -0,0 +1,115 @@
-+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/usb/starfive,jh7110-usb.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: StarFive JH7110 wrapper module for the Cadence USBSS-DRD controller
-+
-+maintainers:
-+ - Minda Chen <minda.chen@starfivetech.com>
-+
-+properties:
-+ compatible:
-+ const: starfive,jh7110-usb
-+
-+ ranges: true
-+
-+ starfive,stg-syscon:
-+ $ref: /schemas/types.yaml#/definitions/phandle-array
-+ items:
-+ - items:
-+ - description: phandle to System Register Controller stg_syscon node.
-+ - description: dr mode register offset of STG_SYSCONSAIF__SYSCFG register for USB.
-+ description:
-+ The phandle to System Register Controller syscon node and the offset
-+ of STG_SYSCONSAIF__SYSCFG register for USB.
-+
-+ dr_mode:
-+ enum: [host, otg, peripheral]
-+
-+ "#address-cells":
-+ enum: [1, 2]
-+
-+ "#size-cells":
-+ enum: [1, 2]
-+
-+ clocks:
-+ items:
-+ - description: link power management clock
-+ - description: standby clock
-+ - description: APB clock
-+ - description: AXI clock
-+ - description: UTMI APB clock
-+
-+ clock-names:
-+ items:
-+ - const: lpm
-+ - const: stb
-+ - const: apb
-+ - const: axi
-+ - const: utmi_apb
-+
-+ resets:
-+ items:
-+ - description: Power up reset
-+ - description: APB clock reset
-+ - description: AXI clock reset
-+ - description: UTMI APB clock reset
-+
-+ reset-names:
-+ items:
-+ - const: pwrup
-+ - const: apb
-+ - const: axi
-+ - const: utmi_apb
-+
-+patternProperties:
-+ "^usb@[0-9a-f]+$":
-+ $ref: cdns,usb3.yaml#
-+ description: Required child node
-+
-+required:
-+ - compatible
-+ - ranges
-+ - starfive,stg-syscon
-+ - '#address-cells'
-+ - '#size-cells'
-+ - dr_mode
-+ - clocks
-+ - resets
-+
-+additionalProperties: false
-+
-+examples:
-+ - |
-+ usb@10100000 {
-+ compatible = "starfive,jh7110-usb";
-+ ranges = <0x0 0x10100000 0x100000>;
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+ starfive,stg-syscon = <&stg_syscon 0x4>;
-+ clocks = <&syscrg 4>,
-+ <&stgcrg 5>,
-+ <&stgcrg 1>,
-+ <&stgcrg 3>,
-+ <&stgcrg 2>;
-+ clock-names = "lpm", "stb", "apb", "axi", "utmi_apb";
-+ resets = <&stgcrg 10>,
-+ <&stgcrg 8>,
-+ <&stgcrg 7>,
-+ <&stgcrg 9>;
-+ reset-names = "pwrup", "apb", "axi", "utmi_apb";
-+ dr_mode = "host";
-+
-+ usb@0 {
-+ compatible = "cdns,usb3";
-+ reg = <0x0 0x10000>,
-+ <0x10000 0x10000>,
-+ <0x20000 0x10000>;
-+ reg-names = "otg", "xhci", "dev";
-+ interrupts = <100>, <108>, <110>;
-+ interrupt-names = "host", "peripheral", "otg";
-+ maximum-speed = "super-speed";
-+ };
-+ };
diff --git a/target/linux/starfive/patches-6.1/0092-dt-bindings-qspi-cdns-qspi-nor-constrain-minItems-ma.patch b/target/linux/starfive/patches-6.1/0092-dt-bindings-qspi-cdns-qspi-nor-constrain-minItems-ma.patch
deleted file mode 100644
index 650545cf3c..0000000000
--- a/target/linux/starfive/patches-6.1/0092-dt-bindings-qspi-cdns-qspi-nor-constrain-minItems-ma.patch
+++ /dev/null
@@ -1,78 +0,0 @@
-From 464fa29e8f3fb2c209647efbb365470b35daec38 Mon Sep 17 00:00:00 2001
-From: William Qiu <william.qiu@starfivetech.com>
-Date: Thu, 2 Mar 2023 18:52:20 +0800
-Subject: [PATCH 092/122] dt-bindings: qspi: cdns,qspi-nor: constrain
- minItems/maxItems of resets
-
-The QSPI controller needs three reset items to work properly on JH7110 SoC,
-so there is need to change the maxItems's value to 3 and add minItems
-whose value is equal to 2. Other platforms do not have this constraint.
-
-Signed-off-by: William Qiu <william.qiu@starfivetech.com>
----
- .../bindings/spi/cdns,qspi-nor.yaml | 37 +++++++++++++++++--
- 1 file changed, 33 insertions(+), 4 deletions(-)
-
---- a/Documentation/devicetree/bindings/spi/cdns,qspi-nor.yaml
-+++ b/Documentation/devicetree/bindings/spi/cdns,qspi-nor.yaml
-@@ -19,6 +19,33 @@ allOf:
- then:
- required:
- - power-domains
-+ - if:
-+ properties:
-+ compatible:
-+ contains:
-+ const: starfive,jh7110-qspi
-+ then:
-+ properties:
-+ resets:
-+ minItems: 2
-+ maxItems: 3
-+
-+ reset-names:
-+ minItems: 2
-+ maxItems: 3
-+ items:
-+ enum: [ qspi, qspi-ocp, rstc_ref ]
-+
-+ else:
-+ properties:
-+ resets:
-+ maxItems: 2
-+
-+ reset-names:
-+ minItems: 1
-+ maxItems: 2
-+ items:
-+ enum: [ qspi, qspi-ocp ]
-
- properties:
- compatible:
-@@ -30,6 +57,7 @@ properties:
- - intel,lgm-qspi
- - xlnx,versal-ospi-1.0
- - intel,socfpga-qspi
-+ - starfive,jh7110-qspi
- - const: cdns,qspi-nor
- - const: cdns,qspi-nor
-
-@@ -79,13 +107,14 @@ properties:
- maxItems: 1
-
- resets:
-- maxItems: 2
-+ minItems: 2
-+ maxItems: 3
-
- reset-names:
-- minItems: 1
-- maxItems: 2
-+ minItems: 2
-+ maxItems: 3
- items:
-- enum: [ qspi, qspi-ocp ]
-+ enum: [ qspi, qspi-ocp, rstc_ref ]
-
- required:
- - compatible
diff --git a/target/linux/starfive/patches-6.1/0093-usb-cdns3-Add-StarFive-JH7110-USB-driver.patch b/target/linux/starfive/patches-6.1/0093-usb-cdns3-Add-StarFive-JH7110-USB-driver.patch
deleted file mode 100644
index 2431dc45dd..0000000000
--- a/target/linux/starfive/patches-6.1/0093-usb-cdns3-Add-StarFive-JH7110-USB-driver.patch
+++ /dev/null
@@ -1,298 +0,0 @@
-From 27c75f360a76084ee6a249876483cfa8d0bedd65 Mon Sep 17 00:00:00 2001
-From: Minda Chen <minda.chen@starfivetech.com>
-Date: Thu, 18 May 2023 19:27:49 +0800
-Subject: [PATCH 093/122] usb: cdns3: Add StarFive JH7110 USB driver
-
-Adds Specific Glue layer to support USB peripherals on
-StarFive JH7110 SoC.
-There is a Cadence USB3 core for JH7110 SoCs, the cdns
-core is the child of this USB wrapper module device.
-
-Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
-Acked-by: Peter Chen <peter.chen@kernel.org>
----
- drivers/usb/cdns3/Kconfig | 11 ++
- drivers/usb/cdns3/Makefile | 1 +
- drivers/usb/cdns3/cdns3-starfive.c | 246 +++++++++++++++++++++++++++++
- 3 files changed, 258 insertions(+)
- create mode 100644 drivers/usb/cdns3/cdns3-starfive.c
-
---- a/drivers/usb/cdns3/Kconfig
-+++ b/drivers/usb/cdns3/Kconfig
-@@ -78,6 +78,17 @@ config USB_CDNS3_IMX
-
- For example, imx8qm and imx8qxp.
-
-+config USB_CDNS3_STARFIVE
-+ tristate "Cadence USB3 support on StarFive SoC platforms"
-+ depends on ARCH_STARFIVE || COMPILE_TEST
-+ help
-+ Say 'Y' or 'M' here if you are building for StarFive SoCs
-+ platforms that contain Cadence USB3 controller core.
-+
-+ e.g. JH7110.
-+
-+ If you choose to build this driver as module it will
-+ be dynamically linked and module will be called cdns3-starfive.ko
- endif
-
- if USB_CDNS_SUPPORT
---- a/drivers/usb/cdns3/Makefile
-+++ b/drivers/usb/cdns3/Makefile
-@@ -24,6 +24,7 @@ endif
- obj-$(CONFIG_USB_CDNS3_PCI_WRAP) += cdns3-pci-wrap.o
- obj-$(CONFIG_USB_CDNS3_TI) += cdns3-ti.o
- obj-$(CONFIG_USB_CDNS3_IMX) += cdns3-imx.o
-+obj-$(CONFIG_USB_CDNS3_STARFIVE) += cdns3-starfive.o
-
- cdnsp-udc-pci-y := cdnsp-pci.o
-
---- /dev/null
-+++ b/drivers/usb/cdns3/cdns3-starfive.c
-@@ -0,0 +1,246 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/**
-+ * cdns3-starfive.c - StarFive specific Glue layer for Cadence USB Controller
-+ *
-+ * Copyright (C) 2023 StarFive Technology Co., Ltd.
-+ *
-+ * Author: Minda Chen <minda.chen@starfivetech.com>
-+ */
-+
-+#include <linux/bits.h>
-+#include <linux/clk.h>
-+#include <linux/module.h>
-+#include <linux/mfd/syscon.h>
-+#include <linux/kernel.h>
-+#include <linux/platform_device.h>
-+#include <linux/io.h>
-+#include <linux/of_platform.h>
-+#include <linux/reset.h>
-+#include <linux/regmap.h>
-+#include <linux/usb/otg.h>
-+#include "core.h"
-+
-+#define USB_STRAP_HOST BIT(17)
-+#define USB_STRAP_DEVICE BIT(18)
-+#define USB_STRAP_MASK GENMASK(18, 16)
-+
-+#define USB_SUSPENDM_HOST BIT(19)
-+#define USB_SUSPENDM_MASK BIT(19)
-+
-+#define USB_MISC_CFG_MASK GENMASK(23, 20)
-+#define USB_SUSPENDM_BYPS BIT(20)
-+#define USB_PLL_EN BIT(22)
-+#define USB_REFCLK_MODE BIT(23)
-+
-+struct cdns_starfive {
-+ struct device *dev;
-+ struct regmap *stg_syscon;
-+ struct reset_control *resets;
-+ struct clk_bulk_data *clks;
-+ int num_clks;
-+ u32 stg_usb_mode;
-+};
-+
-+static void cdns_mode_init(struct platform_device *pdev,
-+ struct cdns_starfive *data)
-+{
-+ enum usb_dr_mode mode;
-+
-+ regmap_update_bits(data->stg_syscon, data->stg_usb_mode,
-+ USB_MISC_CFG_MASK,
-+ USB_SUSPENDM_BYPS | USB_PLL_EN | USB_REFCLK_MODE);
-+
-+ /* dr mode setting */
-+ mode = usb_get_dr_mode(&pdev->dev);
-+
-+ switch (mode) {
-+ case USB_DR_MODE_HOST:
-+ regmap_update_bits(data->stg_syscon,
-+ data->stg_usb_mode,
-+ USB_STRAP_MASK,
-+ USB_STRAP_HOST);
-+ regmap_update_bits(data->stg_syscon,
-+ data->stg_usb_mode,
-+ USB_SUSPENDM_MASK,
-+ USB_SUSPENDM_HOST);
-+ break;
-+
-+ case USB_DR_MODE_PERIPHERAL:
-+ regmap_update_bits(data->stg_syscon, data->stg_usb_mode,
-+ USB_STRAP_MASK, USB_STRAP_DEVICE);
-+ regmap_update_bits(data->stg_syscon, data->stg_usb_mode,
-+ USB_SUSPENDM_MASK, 0);
-+ break;
-+ default:
-+ break;
-+ }
-+}
-+
-+static int cdns_clk_rst_init(struct cdns_starfive *data)
-+{
-+ int ret;
-+
-+ ret = clk_bulk_prepare_enable(data->num_clks, data->clks);
-+ if (ret)
-+ return dev_err_probe(data->dev, ret,
-+ "failed to enable clocks\n");
-+
-+ ret = reset_control_deassert(data->resets);
-+ if (ret) {
-+ dev_err(data->dev, "failed to reset clocks\n");
-+ goto err_clk_init;
-+ }
-+
-+ return ret;
-+
-+err_clk_init:
-+ clk_bulk_disable_unprepare(data->num_clks, data->clks);
-+ return ret;
-+}
-+
-+static void cdns_clk_rst_deinit(struct cdns_starfive *data)
-+{
-+ reset_control_assert(data->resets);
-+ clk_bulk_disable_unprepare(data->num_clks, data->clks);
-+}
-+
-+static int cdns_starfive_probe(struct platform_device *pdev)
-+{
-+ struct device *dev = &pdev->dev;
-+ struct cdns_starfive *data;
-+ unsigned int args;
-+ int ret;
-+
-+ data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
-+ if (!data)
-+ return -ENOMEM;
-+
-+ data->dev = dev;
-+
-+ data->stg_syscon =
-+ syscon_regmap_lookup_by_phandle_args(pdev->dev.of_node,
-+ "starfive,stg-syscon", 1, &args);
-+
-+ if (IS_ERR(data->stg_syscon))
-+ return dev_err_probe(dev, PTR_ERR(data->stg_syscon),
-+ "Failed to parse starfive,stg-syscon\n");
-+
-+ data->stg_usb_mode = args;
-+
-+ data->num_clks = devm_clk_bulk_get_all(data->dev, &data->clks);
-+ if (data->num_clks < 0)
-+ return dev_err_probe(data->dev, -ENODEV,
-+ "Failed to get clocks\n");
-+
-+ data->resets = devm_reset_control_array_get_exclusive(data->dev);
-+ if (IS_ERR(data->resets))
-+ return dev_err_probe(data->dev, PTR_ERR(data->resets),
-+ "Failed to get resets");
-+
-+ cdns_mode_init(pdev, data);
-+ ret = cdns_clk_rst_init(data);
-+ if (ret)
-+ return ret;
-+
-+ ret = of_platform_populate(dev->of_node, NULL, NULL, dev);
-+ if (ret) {
-+ dev_err(dev, "Failed to create children\n");
-+ cdns_clk_rst_deinit(data);
-+ return ret;
-+ }
-+
-+ device_set_wakeup_capable(dev, true);
-+ pm_runtime_set_active(dev);
-+ pm_runtime_enable(dev);
-+ platform_set_drvdata(pdev, data);
-+
-+ return 0;
-+}
-+
-+static int cdns_starfive_remove_core(struct device *dev, void *c)
-+{
-+ struct platform_device *pdev = to_platform_device(dev);
-+
-+ platform_device_unregister(pdev);
-+
-+ return 0;
-+}
-+
-+static int cdns_starfive_remove(struct platform_device *pdev)
-+{
-+ struct device *dev = &pdev->dev;
-+ struct cdns_starfive *data = dev_get_drvdata(dev);
-+
-+ pm_runtime_get_sync(dev);
-+ device_for_each_child(dev, NULL, cdns_starfive_remove_core);
-+
-+ pm_runtime_disable(dev);
-+ pm_runtime_put_noidle(dev);
-+ cdns_clk_rst_deinit(data);
-+ platform_set_drvdata(pdev, NULL);
-+
-+ return 0;
-+}
-+
-+#ifdef CONFIG_PM
-+static int cdns_starfive_runtime_resume(struct device *dev)
-+{
-+ struct cdns_starfive *data = dev_get_drvdata(dev);
-+
-+ return clk_bulk_prepare_enable(data->num_clks, data->clks);
-+}
-+
-+static int cdns_starfive_runtime_suspend(struct device *dev)
-+{
-+ struct cdns_starfive *data = dev_get_drvdata(dev);
-+
-+ clk_bulk_disable_unprepare(data->num_clks, data->clks);
-+
-+ return 0;
-+}
-+
-+#ifdef CONFIG_PM_SLEEP
-+static int cdns_starfive_resume(struct device *dev)
-+{
-+ struct cdns_starfive *data = dev_get_drvdata(dev);
-+
-+ return cdns_clk_rst_init(data);
-+}
-+
-+static int cdns_starfive_suspend(struct device *dev)
-+{
-+ struct cdns_starfive *data = dev_get_drvdata(dev);
-+
-+ cdns_clk_rst_deinit(data);
-+
-+ return 0;
-+}
-+#endif
-+#endif
-+
-+static const struct dev_pm_ops cdns_starfive_pm_ops = {
-+ SET_RUNTIME_PM_OPS(cdns_starfive_runtime_suspend,
-+ cdns_starfive_runtime_resume, NULL)
-+ SET_SYSTEM_SLEEP_PM_OPS(cdns_starfive_suspend, cdns_starfive_resume)
-+};
-+
-+static const struct of_device_id cdns_starfive_of_match[] = {
-+ { .compatible = "starfive,jh7110-usb", },
-+ { /* sentinel */ }
-+};
-+MODULE_DEVICE_TABLE(of, cdns_starfive_of_match);
-+
-+static struct platform_driver cdns_starfive_driver = {
-+ .probe = cdns_starfive_probe,
-+ .remove = cdns_starfive_remove,
-+ .driver = {
-+ .name = "cdns3-starfive",
-+ .of_match_table = cdns_starfive_of_match,
-+ .pm = &cdns_starfive_pm_ops,
-+ },
-+};
-+module_platform_driver(cdns_starfive_driver);
-+
-+MODULE_ALIAS("platform:cdns3-starfive");
-+MODULE_LICENSE("GPL v2");
-+MODULE_DESCRIPTION("Cadence USB3 StarFive Glue Layer");
diff --git a/target/linux/starfive/patches-6.1/0094-dt-binding-pci-add-JH7110-PCIe-dt-binding-documents.patch b/target/linux/starfive/patches-6.1/0094-dt-binding-pci-add-JH7110-PCIe-dt-binding-documents.patch
deleted file mode 100644
index 150fef8eb4..0000000000
--- a/target/linux/starfive/patches-6.1/0094-dt-binding-pci-add-JH7110-PCIe-dt-binding-documents.patch
+++ /dev/null
@@ -1,181 +0,0 @@
-From 3d555cfd72df1a02849565f281149d321e0f8425 Mon Sep 17 00:00:00 2001
-From: Minda Chen <minda.chen@starfivetech.com>
-Date: Thu, 6 Apr 2023 19:11:40 +0800
-Subject: [PATCH 094/122] dt-binding: pci: add JH7110 PCIe dt-binding
- documents.
-
-Add PCIe controller driver dt-binding documents
-for StarFive JH7110 SoC platform.
-
-Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
----
- .../bindings/pci/starfive,jh7110-pcie.yaml | 163 ++++++++++++++++++
- 1 file changed, 163 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/pci/starfive,jh7110-pcie.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/pci/starfive,jh7110-pcie.yaml
-@@ -0,0 +1,163 @@
-+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/pci/starfive,jh7110-pcie.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: StarFive JH7110 PCIe 2.0 host controller
-+
-+maintainers:
-+ - Minda Chen <minda.chen@starfivetech.com>
-+
-+allOf:
-+ - $ref: /schemas/pci/pci-bus.yaml#
-+ - $ref: /schemas/interrupt-controller/msi-controller.yaml#
-+
-+properties:
-+ compatible:
-+ const: starfive,jh7110-pcie
-+
-+ reg:
-+ maxItems: 2
-+
-+ reg-names:
-+ items:
-+ - const: reg
-+ - const: config
-+
-+ msi-parent: true
-+
-+ interrupts:
-+ maxItems: 1
-+
-+ clocks:
-+ maxItems: 4
-+
-+ clock-names:
-+ items:
-+ - const: noc
-+ - const: tl
-+ - const: axi_mst0
-+ - const: apb
-+
-+ resets:
-+ items:
-+ - description: AXI MST0 reset
-+ - description: AXI SLAVE reset
-+ - description: AXI SLAVE0 reset
-+ - description: PCIE BRIDGE reset
-+ - description: PCIE CORE reset
-+ - description: PCIE APB reset
-+
-+ reset-names:
-+ items:
-+ - const: mst0
-+ - const: slv0
-+ - const: slv
-+ - const: brg
-+ - const: core
-+ - const: apb
-+
-+ starfive,stg-syscon:
-+ $ref: /schemas/types.yaml#/definitions/phandle-array
-+ items:
-+ items:
-+ - description: phandle to System Register Controller stg_syscon node.
-+ - description: register0 offset of STG_SYSCONSAIF__SYSCFG register for PCIe.
-+ - description: register1 offset of STG_SYSCONSAIF__SYSCFG register for PCIe.
-+ - description: register2 offset of STG_SYSCONSAIF__SYSCFG register for PCIe.
-+ - description: register3 offset of STG_SYSCONSAIF__SYSCFG register for PCIe.
-+ description:
-+ The phandle to System Register Controller syscon node and the offset
-+ of STG_SYSCONSAIF__SYSCFG register for PCIe. Total 4 regsisters offset
-+ for PCIe.
-+
-+ pwren-gpios:
-+ description: Should specify the GPIO for controlling the PCI bus device power on.
-+ maxItems: 1
-+
-+ reset-gpios:
-+ maxItems: 1
-+
-+ phys:
-+ maxItems: 1
-+
-+ interrupt-controller:
-+ type: object
-+ properties:
-+ '#address-cells':
-+ const: 0
-+
-+ '#interrupt-cells':
-+ const: 1
-+
-+ interrupt-controller: true
-+
-+ required:
-+ - '#address-cells'
-+ - '#interrupt-cells'
-+ - interrupt-controller
-+
-+ additionalProperties: false
-+
-+required:
-+ - reg
-+ - reg-names
-+ - "#interrupt-cells"
-+ - interrupts
-+ - interrupt-map-mask
-+ - interrupt-map
-+ - clocks
-+ - clock-names
-+ - resets
-+ - msi-controller
-+
-+unevaluatedProperties: false
-+
-+examples:
-+ - |
-+ bus {
-+ #address-cells = <2>;
-+ #size-cells = <2>;
-+
-+ pcie0: pcie@2B000000 {
-+ compatible = "starfive,jh7110-pcie";
-+ #address-cells = <3>;
-+ #size-cells = <2>;
-+ #interrupt-cells = <1>;
-+ reg = <0x0 0x2B000000 0x0 0x1000000>,
-+ <0x9 0x40000000 0x0 0x10000000>;
-+ reg-names = "reg", "config";
-+ device_type = "pci";
-+ starfive,stg-syscon = <&stg_syscon 0xc0 0xc4 0x130 0x1b8>;
-+ bus-range = <0x0 0xff>;
-+ ranges = <0x82000000 0x0 0x30000000 0x0 0x30000000 0x0 0x08000000>,
-+ <0xc3000000 0x9 0x00000000 0x9 0x00000000 0x0 0x40000000>;
-+ interrupt-parent = <&plic>;
-+ interrupts = <56>;
-+ interrupt-map-mask = <0x0 0x0 0x0 0x7>;
-+ interrupt-map = <0x0 0x0 0x0 0x1 &pcie_intc0 0x1>,
-+ <0x0 0x0 0x0 0x2 &pcie_intc0 0x2>,
-+ <0x0 0x0 0x0 0x3 &pcie_intc0 0x3>,
-+ <0x0 0x0 0x0 0x4 &pcie_intc0 0x4>;
-+ msi-parent = <&pcie0>;
-+ msi-controller;
-+ clocks = <&syscrg 86>,
-+ <&stgcrg 10>,
-+ <&stgcrg 8>,
-+ <&stgcrg 9>;
-+ clock-names = "noc", "tl", "axi_mst0", "apb";
-+ resets = <&stgcrg 11>,
-+ <&stgcrg 12>,
-+ <&stgcrg 13>,
-+ <&stgcrg 14>,
-+ <&stgcrg 15>,
-+ <&stgcrg 16>;
-+
-+ pcie_intc0: interrupt-controller {
-+ #address-cells = <0>;
-+ #interrupt-cells = <1>;
-+ interrupt-controller;
-+ };
-+ };
-+ };
diff --git a/target/linux/starfive/patches-6.1/0095-spi-cadence-quadspi-Add-support-for-StarFive-JH7110-.patch b/target/linux/starfive/patches-6.1/0095-spi-cadence-quadspi-Add-support-for-StarFive-JH7110-.patch
deleted file mode 100644
index de701baaa9..0000000000
--- a/target/linux/starfive/patches-6.1/0095-spi-cadence-quadspi-Add-support-for-StarFive-JH7110-.patch
+++ /dev/null
@@ -1,79 +0,0 @@
-From a3749d68d81488ae07878393485278eab24a5818 Mon Sep 17 00:00:00 2001
-From: William Qiu <william.qiu@starfivetech.com>
-Date: Thu, 2 Mar 2023 18:52:21 +0800
-Subject: [PATCH 095/122] spi: cadence-quadspi: Add support for StarFive JH7110
- QSPI
-
-Add QSPI reset operation in device probe and add RISCV support to
-QUAD SPI Kconfig.
-
-Co-developed-by: Ziv Xu <ziv.xu@starfivetech.com>
-Signed-off-by: Ziv Xu <ziv.xu@starfivetech.com>
-Signed-off-by: William Qiu <william.qiu@starfivetech.com>
----
- drivers/spi/Kconfig | 2 +-
- drivers/spi/spi-cadence-quadspi.c | 21 ++++++++++++++++++++-
- 2 files changed, 21 insertions(+), 2 deletions(-)
-
---- a/drivers/spi/Kconfig
-+++ b/drivers/spi/Kconfig
-@@ -230,7 +230,7 @@ config SPI_CADENCE
-
- config SPI_CADENCE_QUADSPI
- tristate "Cadence Quad SPI controller"
-- depends on OF && (ARM || ARM64 || X86 || COMPILE_TEST)
-+ depends on OF && (ARM || ARM64 || X86 || RISCV || COMPILE_TEST)
- help
- Enable support for the Cadence Quad SPI Flash controller.
-
---- a/drivers/spi/spi-cadence-quadspi.c
-+++ b/drivers/spi/spi-cadence-quadspi.c
-@@ -1575,7 +1575,7 @@ static int cqspi_setup_flash(struct cqsp
- static int cqspi_probe(struct platform_device *pdev)
- {
- const struct cqspi_driver_platdata *ddata;
-- struct reset_control *rstc, *rstc_ocp;
-+ struct reset_control *rstc, *rstc_ocp, *rstc_ref;
- struct device *dev = &pdev->dev;
- struct spi_master *master;
- struct resource *res_ahb;
-@@ -1668,6 +1668,17 @@ static int cqspi_probe(struct platform_d
- goto probe_reset_failed;
- }
-
-+ if (of_device_is_compatible(pdev->dev.of_node, "starfive,jh7110-qspi")) {
-+ rstc_ref = devm_reset_control_get_optional_exclusive(dev, "rstc_ref");
-+ if (IS_ERR(rstc_ref)) {
-+ ret = PTR_ERR(rstc_ref);
-+ dev_err(dev, "Cannot get QSPI REF reset.\n");
-+ goto probe_reset_failed;
-+ }
-+ reset_control_assert(rstc_ref);
-+ reset_control_deassert(rstc_ref);
-+ }
-+
- reset_control_assert(rstc);
- reset_control_deassert(rstc);
-
-@@ -1827,6 +1838,10 @@ static const struct cqspi_driver_platdat
- .get_dma_status = cqspi_get_versal_dma_status,
- };
-
-+static const struct cqspi_driver_platdata jh7110_qspi = {
-+ .quirks = CQSPI_DISABLE_DAC_MODE,
-+};
-+
- static const struct of_device_id cqspi_dt_ids[] = {
- {
- .compatible = "cdns,qspi-nor",
-@@ -1852,6 +1867,10 @@ static const struct of_device_id cqspi_d
- .compatible = "intel,socfpga-qspi",
- .data = &socfpga_qspi,
- },
-+ {
-+ .compatible = "starfive,jh7110-qspi",
-+ .data = &jh7110_qspi,
-+ },
- { /* end of table */ }
- };
-
diff --git a/target/linux/starfive/patches-6.1/0096-pcie-starfive-add-StarFive-JH7110-PCIe-driver.patch b/target/linux/starfive/patches-6.1/0096-pcie-starfive-add-StarFive-JH7110-PCIe-driver.patch
deleted file mode 100644
index ffd413c088..0000000000
--- a/target/linux/starfive/patches-6.1/0096-pcie-starfive-add-StarFive-JH7110-PCIe-driver.patch
+++ /dev/null
@@ -1,1004 +0,0 @@
-From e0cd43bcbc9b74343e529fde66a3ec20b533ac61 Mon Sep 17 00:00:00 2001
-From: Minda Chen <minda.chen@starfivetech.com>
-Date: Thu, 6 Apr 2023 19:11:41 +0800
-Subject: [PATCH 096/122] pcie: starfive: add StarFive JH7110 PCIe driver.
-
-Add PCIe controller driver for StarFive JH7110
-SoC platform. The PCIe controller is PCIe 2.0, single lane.
-
-Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
----
- drivers/pci/controller/Kconfig | 8 +
- drivers/pci/controller/Makefile | 1 +
- drivers/pci/controller/pcie-starfive.c | 958 +++++++++++++++++++++++++
- 3 files changed, 967 insertions(+)
- create mode 100644 drivers/pci/controller/pcie-starfive.c
-
---- a/drivers/pci/controller/Kconfig
-+++ b/drivers/pci/controller/Kconfig
-@@ -343,6 +343,14 @@ config PCIE_MT7621
- help
- This selects a driver for the MediaTek MT7621 PCIe Controller.
-
-+config PCIE_STARFIVE
-+ tristate "StarFive JH7110 PCIe controller"
-+ depends on PCI_MSI && OF
-+ select PCI_MSI_IRQ_DOMAIN
-+ help
-+ Say 'Y' here if you want kernel to support the StarFive JH7110
-+ PCIe Host driver.
-+
- source "drivers/pci/controller/dwc/Kconfig"
- source "drivers/pci/controller/mobiveil/Kconfig"
- source "drivers/pci/controller/cadence/Kconfig"
---- a/drivers/pci/controller/Makefile
-+++ b/drivers/pci/controller/Makefile
-@@ -39,6 +39,7 @@ obj-$(CONFIG_PCI_LOONGSON) += pci-loongs
- obj-$(CONFIG_PCIE_HISI_ERR) += pcie-hisi-error.o
- obj-$(CONFIG_PCIE_APPLE) += pcie-apple.o
- obj-$(CONFIG_PCIE_MT7621) += pcie-mt7621.o
-+obj-$(CONFIG_PCIE_STARFIVE) += pcie-starfive.o
-
- # pcie-hisi.o quirks are needed even without CONFIG_PCIE_DW
- obj-y += dwc/
---- /dev/null
-+++ b/drivers/pci/controller/pcie-starfive.c
-@@ -0,0 +1,958 @@
-+// SPDX-License-Identifier: GPL-2.0+
-+/*
-+ * PCIe host controller driver for Starfive JH7110 Soc.
-+ *
-+ * Based on pcie-altera.c, pcie-altera-msi.c.
-+ *
-+ * Copyright (C) StarFive Technology Co., Ltd.
-+ */
-+
-+#include <linux/clk.h>
-+#include <linux/delay.h>
-+#include <linux/gpio/consumer.h>
-+#include <linux/interrupt.h>
-+#include <linux/irqchip/chained_irq.h>
-+#include <linux/mfd/syscon.h>
-+#include <linux/module.h>
-+#include <linux/msi.h>
-+#include <linux/of_address.h>
-+#include <linux/of_irq.h>
-+#include <linux/of_pci.h>
-+#include <linux/pci.h>
-+#include <linux/pci-ecam.h>
-+#include <linux/phy/phy.h>
-+#include <linux/pinctrl/consumer.h>
-+#include <linux/pinctrl/pinctrl.h>
-+#include <linux/platform_device.h>
-+#include <linux/pm_runtime.h>
-+#include <linux/regmap.h>
-+#include <linux/reset.h>
-+#include <linux/slab.h>
-+#include "../pci.h"
-+
-+#define IMASK_LOCAL 0x180
-+#define ISTATUS_LOCAL 0x184
-+#define IMSI_ADDR 0x190
-+#define ISTATUS_MSI 0x194
-+#define GEN_SETTINGS 0x80
-+#define PCIE_PCI_IDS 0x9C
-+#define PCIE_WINROM 0xFC
-+#define PMSG_SUPPORT_RX 0x3F0
-+
-+#define PCI_MISC 0xB4
-+
-+#define RP_ENABLE 1
-+
-+#define IDS_CLASS_CODE_SHIFT 16
-+
-+#define DATA_LINK_ACTIVE BIT(5)
-+#define PREF_MEM_WIN_64_SUPPORT BIT(3)
-+#define PMSG_LTR_SUPPORT BIT(2)
-+#define LINK_SPEED_GEN2 BIT(12)
-+#define PHY_FUNCTION_DIS BIT(15)
-+#define PCIE_FUNC_NUM 4
-+#define PHY_FUNC_SHIFT 9
-+
-+#define XR3PCI_ATR_AXI4_SLV0 0x800
-+#define XR3PCI_ATR_SRC_ADDR_LOW 0x0
-+#define XR3PCI_ATR_SRC_ADDR_HIGH 0x4
-+#define XR3PCI_ATR_TRSL_ADDR_LOW 0x8
-+#define XR3PCI_ATR_TRSL_ADDR_HIGH 0xc
-+#define XR3PCI_ATR_TRSL_PARAM 0x10
-+#define XR3PCI_ATR_TABLE_OFFSET 0x20
-+#define XR3PCI_ATR_MAX_TABLE_NUM 8
-+
-+#define XR3PCI_ATR_SRC_WIN_SIZE_SHIFT 1
-+#define XR3PCI_ATR_SRC_ADDR_MASK GENMASK(31, 12)
-+#define XR3PCI_ATR_TRSL_ADDR_MASK GENMASK(31, 12)
-+#define XR3PCI_ECAM_SIZE BIT(28)
-+#define XR3PCI_ATR_TRSL_DIR BIT(22)
-+/* IDs used in the XR3PCI_ATR_TRSL_PARAM */
-+#define XR3PCI_ATR_TRSLID_PCIE_MEMORY 0x0
-+#define XR3PCI_ATR_TRSLID_PCIE_CONFIG 0x1
-+
-+#define INT_AXI_POST_ERROR BIT(16)
-+#define INT_AXI_FETCH_ERROR BIT(17)
-+#define INT_AXI_DISCARD_ERROR BIT(18)
-+#define INT_PCIE_POST_ERROR BIT(20)
-+#define INT_PCIE_FETCH_ERROR BIT(21)
-+#define INT_PCIE_DISCARD_ERROR BIT(22)
-+#define INT_ERRORS (INT_AXI_POST_ERROR | INT_AXI_FETCH_ERROR | \
-+ INT_AXI_DISCARD_ERROR | INT_PCIE_POST_ERROR | \
-+ INT_PCIE_FETCH_ERROR | INT_PCIE_DISCARD_ERROR)
-+
-+#define INTA_OFFSET 24
-+#define INTA BIT(24)
-+#define INTB BIT(25)
-+#define INTC BIT(26)
-+#define INTD BIT(27)
-+#define INT_MSI BIT(28)
-+#define INT_INTX_MASK (INTA | INTB | INTC | INTD)
-+#define INT_MASK (INT_INTX_MASK | INT_MSI | INT_ERRORS)
-+
-+#define INT_PCI_MSI_NR 32
-+
-+/* system control */
-+#define STG_SYSCON_K_RP_NEP BIT(8)
-+#define STG_SYSCON_AXI4_SLVL_ARFUNC_MASK GENMASK(22, 8)
-+#define STG_SYSCON_AXI4_SLVL_ARFUNC_SHIFT 8
-+#define STG_SYSCON_AXI4_SLVL_AWFUNC_MASK GENMASK(14, 0)
-+#define STG_SYSCON_CLKREQ BIT(22)
-+#define STG_SYSCON_CKREF_SRC_SHIFT 18
-+#define STG_SYSCON_CKREF_SRC_MASK GENMASK(19, 18)
-+
-+/* MSI information */
-+struct jh7110_pcie_msi {
-+ DECLARE_BITMAP(used, INT_PCI_MSI_NR);
-+ struct irq_domain *msi_domain;
-+ struct irq_domain *inner_domain;
-+ /* Protect bitmap variable */
-+ struct mutex lock;
-+};
-+
-+struct starfive_jh7110_pcie {
-+ struct platform_device *pdev;
-+ void __iomem *reg_base;
-+ void __iomem *config_base;
-+ phys_addr_t config_phyaddr;
-+ struct regmap *reg_syscon;
-+ struct phy *phy;
-+ u32 stg_arfun;
-+ u32 stg_awfun;
-+ u32 stg_rp_nep;
-+ u32 stg_lnksta;
-+ int irq;
-+ struct irq_domain *legacy_irq_domain;
-+ struct pci_host_bridge *bridge;
-+ struct jh7110_pcie_msi msi;
-+ struct reset_control *resets;
-+ struct clk_bulk_data *clks;
-+ int num_clks;
-+ int atr_table_num;
-+ struct gpio_desc *power_gpio;
-+ struct gpio_desc *reset_gpio;
-+};
-+
-+/*
-+ * StarFive PCIe port uses BAR0-BAR1 of RC's configuration space as
-+ * the translation from PCI bus to native BUS. Entire DDR region
-+ * is mapped into PCIe space using these registers, so it can be
-+ * reached by DMA from EP devices. The BAR0/1 of bridge should be
-+ * hidden during enumeration to avoid the sizing and resource allocation
-+ * by PCIe core.
-+ */
-+static bool starfive_pcie_hide_rc_bar(struct pci_bus *bus, unsigned int devfn,
-+ int offset)
-+{
-+ if (pci_is_root_bus(bus) && (devfn == 0)
-+ && ((offset == PCI_BASE_ADDRESS_0)
-+ || (offset == PCI_BASE_ADDRESS_1)))
-+ return true;
-+
-+ return false;
-+}
-+
-+void __iomem *starfive_pcie_map_bus(struct pci_bus *bus, unsigned int devfn,
-+ int where)
-+{
-+ struct starfive_jh7110_pcie *pcie = bus->sysdata;
-+
-+ return pcie->config_base + PCIE_ECAM_OFFSET(bus->number, devfn, where);
-+}
-+
-+int starfive_pcie_config_write(struct pci_bus *bus, unsigned int devfn,
-+ int where, int size, u32 value)
-+{
-+ if (starfive_pcie_hide_rc_bar(bus, devfn, where))
-+ return PCIBIOS_BAD_REGISTER_NUMBER;
-+
-+ return pci_generic_config_write(bus, devfn, where, size, value);
-+}
-+
-+static void starfive_pcie_handle_msi_irq(struct starfive_jh7110_pcie *pcie)
-+{
-+ struct jh7110_pcie_msi *msi = &pcie->msi;
-+ u32 bit;
-+ u32 virq;
-+ unsigned long status = readl(pcie->reg_base + ISTATUS_MSI);
-+
-+ for_each_set_bit(bit, &status, INT_PCI_MSI_NR) {
-+ /* Clear interrupts */
-+ writel(1 << bit, pcie->reg_base + ISTATUS_MSI);
-+ virq = irq_find_mapping(msi->inner_domain, bit);
-+ if (virq) {
-+ if (test_bit(bit, msi->used))
-+ generic_handle_irq(virq);
-+ else
-+ dev_err(&pcie->pdev->dev,
-+ "Unhandled MSI, MSI%d virq %d\n", bit,
-+ virq);
-+ } else
-+ dev_err(&pcie->pdev->dev, "Unexpected MSI, MSI%d\n",
-+ bit);
-+ }
-+ writel(INT_MSI, pcie->reg_base + ISTATUS_LOCAL);
-+}
-+
-+static void starfive_pcie_handle_intx_irq(struct starfive_jh7110_pcie *pcie,
-+ unsigned long status)
-+{
-+ u32 bit;
-+ u32 virq;
-+
-+ status >>= INTA_OFFSET;
-+
-+ for_each_set_bit(bit, &status, PCI_NUM_INTX) {
-+ /* Clear interrupts */
-+ writel(1 << (bit + INTA_OFFSET), pcie->reg_base + ISTATUS_LOCAL);
-+
-+ virq = irq_find_mapping(pcie->legacy_irq_domain, bit);
-+ if (virq)
-+ generic_handle_irq(virq);
-+ else
-+ dev_err(&pcie->pdev->dev,
-+ "unexpected IRQ, INT%d\n", bit);
-+ }
-+}
-+
-+static void starfive_pcie_handle_errors_irq(struct starfive_jh7110_pcie *pcie, u32 status)
-+{
-+ if (status & INT_AXI_POST_ERROR)
-+ dev_err(&pcie->pdev->dev, "AXI post error\n");
-+ if (status & INT_AXI_FETCH_ERROR)
-+ dev_err(&pcie->pdev->dev, "AXI fetch error\n");
-+ if (status & INT_AXI_DISCARD_ERROR)
-+ dev_err(&pcie->pdev->dev, "AXI discard error\n");
-+ if (status & INT_PCIE_POST_ERROR)
-+ dev_err(&pcie->pdev->dev, "PCIe post error\n");
-+ if (status & INT_PCIE_FETCH_ERROR)
-+ dev_err(&pcie->pdev->dev, "PCIe fetch error\n");
-+ if (status & INT_PCIE_DISCARD_ERROR)
-+ dev_err(&pcie->pdev->dev, "PCIe discard error\n");
-+
-+ writel(INT_ERRORS, pcie->reg_base + ISTATUS_LOCAL);
-+}
-+
-+static void starfive_pcie_isr(struct irq_desc *desc)
-+{
-+ struct irq_chip *chip = irq_desc_get_chip(desc);
-+ struct starfive_jh7110_pcie *pcie;
-+ u32 status;
-+
-+ chained_irq_enter(chip, desc);
-+ pcie = irq_desc_get_handler_data(desc);
-+
-+ status = readl(pcie->reg_base + ISTATUS_LOCAL);
-+ while ((status = (readl(pcie->reg_base + ISTATUS_LOCAL) & INT_MASK))) {
-+ if (status & INT_INTX_MASK)
-+ starfive_pcie_handle_intx_irq(pcie, status);
-+
-+ if (status & INT_MSI)
-+ starfive_pcie_handle_msi_irq(pcie);
-+
-+ if (status & INT_ERRORS)
-+ starfive_pcie_handle_errors_irq(pcie, status);
-+ }
-+
-+ chained_irq_exit(chip, desc);
-+}
-+
-+#ifdef CONFIG_PCI_MSI
-+static struct irq_chip starfive_pcie_msi_irq_chip = {
-+ .name = "StarFive PCIe MSI",
-+ .irq_mask = pci_msi_mask_irq,
-+ .irq_unmask = pci_msi_unmask_irq,
-+};
-+
-+static struct msi_domain_info starfive_pcie_msi_domain_info = {
-+ .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
-+ MSI_FLAG_PCI_MSIX),
-+ .chip = &starfive_pcie_msi_irq_chip,
-+};
-+#endif
-+
-+static void starfive_pcie_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
-+{
-+ struct starfive_jh7110_pcie *pcie = irq_data_get_irq_chip_data(data);
-+ phys_addr_t msi_addr = readl(pcie->reg_base + IMSI_ADDR);
-+
-+ msg->address_lo = lower_32_bits(msi_addr);
-+ msg->address_hi = upper_32_bits(msi_addr);
-+ msg->data = data->hwirq;
-+
-+ dev_info(&pcie->pdev->dev, "msi#%d address_hi %#x address_lo %#x\n",
-+ (int)data->hwirq, msg->address_hi, msg->address_lo);
-+}
-+
-+static int starfive_pcie_msi_set_affinity(struct irq_data *irq_data,
-+ const struct cpumask *mask, bool force)
-+{
-+ return -EINVAL;
-+}
-+
-+static struct irq_chip starfive_irq_chip = {
-+ .name = "StarFive MSI",
-+ .irq_compose_msi_msg = starfive_pcie_compose_msi_msg,
-+ .irq_set_affinity = starfive_pcie_msi_set_affinity,
-+};
-+
-+static int starfive_pcie_msi_alloc(struct irq_domain *domain, unsigned int virq,
-+ unsigned int nr_irqs, void *args)
-+{
-+ struct starfive_jh7110_pcie *pcie = domain->host_data;
-+ struct jh7110_pcie_msi *msi = &pcie->msi;
-+ int bit;
-+
-+ WARN_ON(nr_irqs != 1);
-+ mutex_lock(&msi->lock);
-+
-+ bit = find_first_zero_bit(msi->used, INT_PCI_MSI_NR);
-+ if (bit >= INT_PCI_MSI_NR) {
-+ mutex_unlock(&msi->lock);
-+ return -ENOSPC;
-+ }
-+
-+ set_bit(bit, msi->used);
-+
-+ irq_domain_set_info(domain, virq, bit, &starfive_irq_chip,
-+ domain->host_data, handle_simple_irq,
-+ NULL, NULL);
-+ mutex_unlock(&msi->lock);
-+
-+ return 0;
-+}
-+
-+static void starfive_pcie_msi_free(struct irq_domain *domain, unsigned int virq,
-+ unsigned int nr_irqs)
-+{
-+ struct irq_data *data = irq_domain_get_irq_data(domain, virq);
-+ struct starfive_jh7110_pcie *pcie = irq_data_get_irq_chip_data(data);
-+ struct jh7110_pcie_msi *msi = &pcie->msi;
-+
-+ mutex_lock(&msi->lock);
-+
-+ if (!test_bit(data->hwirq, msi->used))
-+ dev_err(&pcie->pdev->dev, "Trying to free unused MSI#%lu\n",
-+ data->hwirq);
-+ else
-+ __clear_bit(data->hwirq, msi->used);
-+
-+ writel(0xffffffff, pcie->reg_base + ISTATUS_MSI);
-+ mutex_unlock(&msi->lock);
-+}
-+
-+static const struct irq_domain_ops dev_msi_domain_ops = {
-+ .alloc = starfive_pcie_msi_alloc,
-+ .free = starfive_pcie_msi_free,
-+};
-+
-+static void starfive_pcie_msi_free_irq_domain(struct starfive_jh7110_pcie *pcie)
-+{
-+#ifdef CONFIG_PCI_MSI
-+ struct jh7110_pcie_msi *msi = &pcie->msi;
-+ u32 irq;
-+ int i;
-+
-+ for (i = 0; i < INT_PCI_MSI_NR; i++) {
-+ irq = irq_find_mapping(msi->inner_domain, i);
-+ if (irq > 0)
-+ irq_dispose_mapping(irq);
-+ }
-+
-+ if (msi->msi_domain)
-+ irq_domain_remove(msi->msi_domain);
-+
-+ if (msi->inner_domain)
-+ irq_domain_remove(msi->inner_domain);
-+#endif
-+}
-+
-+static void starfive_pcie_free_irq_domain(struct starfive_jh7110_pcie *pcie)
-+{
-+ int i;
-+ u32 irq;
-+
-+ /* Disable all interrupts */
-+ writel(0, pcie->reg_base + IMASK_LOCAL);
-+
-+ if (pcie->legacy_irq_domain) {
-+ for (i = 0; i < PCI_NUM_INTX; i++) {
-+ irq = irq_find_mapping(pcie->legacy_irq_domain, i);
-+ if (irq > 0)
-+ irq_dispose_mapping(irq);
-+ }
-+ irq_domain_remove(pcie->legacy_irq_domain);
-+ }
-+
-+ if (pci_msi_enabled())
-+ starfive_pcie_msi_free_irq_domain(pcie);
-+ irq_set_chained_handler_and_data(pcie->irq, NULL, NULL);
-+}
-+
-+static int starfive_pcie_init_msi_irq_domain(struct starfive_jh7110_pcie *pcie)
-+{
-+#ifdef CONFIG_PCI_MSI
-+ struct fwnode_handle *fwn = of_node_to_fwnode(pcie->pdev->dev.of_node);
-+ struct jh7110_pcie_msi *msi = &pcie->msi;
-+
-+ msi->inner_domain = irq_domain_add_linear(NULL, INT_PCI_MSI_NR,
-+ &dev_msi_domain_ops, pcie);
-+ if (!msi->inner_domain) {
-+ dev_err(&pcie->pdev->dev, "Failed to create dev IRQ domain\n");
-+ return -ENOMEM;
-+ }
-+ msi->msi_domain = pci_msi_create_irq_domain(fwn, &starfive_pcie_msi_domain_info,
-+ msi->inner_domain);
-+ if (!msi->msi_domain) {
-+ dev_err(&pcie->pdev->dev, "Failed to create msi IRQ domain\n");
-+ irq_domain_remove(msi->inner_domain);
-+ return -ENOMEM;
-+ }
-+#endif
-+ return 0;
-+}
-+
-+static int starfive_pcie_enable_msi(struct starfive_jh7110_pcie *pcie, struct pci_bus *bus)
-+{
-+ struct jh7110_pcie_msi *msi = &pcie->msi;
-+ u32 reg;
-+
-+ mutex_init(&msi->lock);
-+
-+ /* Enable MSI */
-+ reg = readl(pcie->reg_base + IMASK_LOCAL);
-+ reg |= INT_MSI;
-+ writel(reg, pcie->reg_base + IMASK_LOCAL);
-+ return 0;
-+}
-+
-+static int starfive_pcie_intx_map(struct irq_domain *domain, unsigned int irq,
-+ irq_hw_number_t hwirq)
-+{
-+ irq_set_chip_and_handler(irq, &dummy_irq_chip, handle_simple_irq);
-+ irq_set_chip_data(irq, domain->host_data);
-+
-+ return 0;
-+}
-+
-+static const struct irq_domain_ops intx_domain_ops = {
-+ .map = starfive_pcie_intx_map,
-+ .xlate = pci_irqd_intx_xlate,
-+};
-+
-+static int starfive_pcie_init_irq_domain(struct starfive_jh7110_pcie *pcie)
-+{
-+ struct device *dev = &pcie->pdev->dev;
-+ struct device_node *node = dev->of_node;
-+ int ret;
-+
-+ if (pci_msi_enabled()) {
-+ ret = starfive_pcie_init_msi_irq_domain(pcie);
-+ if (ret != 0)
-+ return -ENOMEM;
-+ }
-+
-+ /* Setup INTx */
-+ pcie->legacy_irq_domain = irq_domain_add_linear(node, PCI_NUM_INTX,
-+ &intx_domain_ops, pcie);
-+
-+ if (!pcie->legacy_irq_domain) {
-+ dev_err(dev, "Failed to get a INTx IRQ domain\n");
-+ return -ENOMEM;
-+ }
-+
-+ irq_set_chained_handler_and_data(pcie->irq, starfive_pcie_isr, pcie);
-+
-+ return 0;
-+}
-+
-+static int starfive_pcie_parse_dt(struct starfive_jh7110_pcie *pcie)
-+{
-+ struct resource *cfg_res;
-+ struct platform_device *pdev = pcie->pdev;
-+ unsigned int args[4];
-+
-+ pcie->reg_base =
-+ devm_platform_ioremap_resource_byname(pdev, "reg");
-+
-+ if (IS_ERR(pcie->reg_base))
-+ return dev_err_probe(&pdev->dev, PTR_ERR(pcie->reg_base),
-+ "Failed to map reg memory\n");
-+
-+ cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config");
-+ if (!cfg_res)
-+ return dev_err_probe(&pdev->dev, -ENODEV,
-+ "Failed to get config memory\n");
-+
-+ pcie->config_base = devm_ioremap_resource(&pdev->dev, cfg_res);
-+ if (IS_ERR(pcie->config_base))
-+ return dev_err_probe(&pdev->dev, PTR_ERR(pcie->config_base),
-+ "Failed to map config memory\n");
-+
-+ pcie->config_phyaddr = cfg_res->start;
-+
-+ pcie->phy = devm_phy_optional_get(&pdev->dev, NULL);
-+ if (IS_ERR(pcie->phy))
-+ return dev_err_probe(&pdev->dev, PTR_ERR(pcie->phy),
-+ "Failed to get pcie phy\n");
-+
-+ pcie->irq = platform_get_irq(pdev, 0);
-+ if (pcie->irq < 0)
-+ return dev_err_probe(&pdev->dev, -EINVAL,
-+ "Failed to get IRQ: %d\n", pcie->irq);
-+
-+ pcie->reg_syscon = syscon_regmap_lookup_by_phandle_args(pdev->dev.of_node,
-+ "starfive,stg-syscon", 4, args);
-+
-+ if (IS_ERR(pcie->reg_syscon))
-+ return dev_err_probe(&pdev->dev, PTR_ERR(pcie->reg_syscon),
-+ "Failed to parse starfive,stg-syscon\n");
-+
-+ pcie->stg_arfun = args[0];
-+ pcie->stg_awfun = args[1];
-+ pcie->stg_rp_nep = args[2];
-+ pcie->stg_lnksta = args[3];
-+
-+ /* Clear all interrupts */
-+ writel(0xffffffff, pcie->reg_base + ISTATUS_LOCAL);
-+ writel(INT_INTX_MASK | INT_ERRORS, pcie->reg_base + IMASK_LOCAL);
-+
-+ return 0;
-+}
-+
-+static struct pci_ops starfive_pcie_ops = {
-+ .map_bus = starfive_pcie_map_bus,
-+ .read = pci_generic_config_read,
-+ .write = starfive_pcie_config_write,
-+};
-+
-+static void starfive_pcie_set_atr_entry(struct starfive_jh7110_pcie *pcie,
-+ phys_addr_t src_addr, phys_addr_t trsl_addr,
-+ size_t window_size, int trsl_param)
-+{
-+ void __iomem *base =
-+ pcie->reg_base + XR3PCI_ATR_AXI4_SLV0;
-+
-+ /* Support AXI4 Slave 0 Address Translation Tables 0-7. */
-+ if (pcie->atr_table_num >= XR3PCI_ATR_MAX_TABLE_NUM)
-+ pcie->atr_table_num = XR3PCI_ATR_MAX_TABLE_NUM - 1;
-+ base += XR3PCI_ATR_TABLE_OFFSET * pcie->atr_table_num;
-+ pcie->atr_table_num++;
-+
-+ /*
-+ * X3PCI_ATR_SRC_ADDR_LOW:
-+ * - bit 0: enable entry,
-+ * - bits 1-6: ATR window size: total size in bytes: 2^(ATR_WSIZE + 1)
-+ * - bits 7-11: reserved
-+ * - bits 12-31: start of source address
-+ */
-+ writel((lower_32_bits(src_addr) & XR3PCI_ATR_SRC_ADDR_MASK) |
-+ (fls(window_size) - 1) << XR3PCI_ATR_SRC_WIN_SIZE_SHIFT | 1,
-+ base + XR3PCI_ATR_SRC_ADDR_LOW);
-+ writel(upper_32_bits(src_addr), base + XR3PCI_ATR_SRC_ADDR_HIGH);
-+ writel((lower_32_bits(trsl_addr) & XR3PCI_ATR_TRSL_ADDR_MASK),
-+ base + XR3PCI_ATR_TRSL_ADDR_LOW);
-+ writel(upper_32_bits(trsl_addr), base + XR3PCI_ATR_TRSL_ADDR_HIGH);
-+ writel(trsl_param, base + XR3PCI_ATR_TRSL_PARAM);
-+
-+ dev_info(&pcie->pdev->dev, "ATR entry: 0x%010llx %s 0x%010llx [0x%010llx] (param: 0x%06x)\n",
-+ src_addr, (trsl_param & XR3PCI_ATR_TRSL_DIR) ? "<-" : "->",
-+ trsl_addr, (u64)window_size, trsl_param);
-+}
-+
-+static int starfive_pcie_setup_windows(struct starfive_jh7110_pcie *pcie)
-+{
-+ struct pci_host_bridge *bridge = pcie->bridge;
-+ struct resource_entry *entry;
-+ u64 pci_addr;
-+
-+ resource_list_for_each_entry(entry, &bridge->windows) {
-+ if (resource_type(entry->res) == IORESOURCE_MEM) {
-+ pci_addr = entry->res->start - entry->offset;
-+ starfive_pcie_set_atr_entry(pcie,
-+ entry->res->start, pci_addr,
-+ resource_size(entry->res),
-+ XR3PCI_ATR_TRSLID_PCIE_MEMORY);
-+ }
-+ }
-+
-+ return 0;
-+}
-+
-+static int starfive_pcie_clk_rst_init(struct starfive_jh7110_pcie *pcie)
-+{
-+ int ret;
-+ struct device *dev = &pcie->pdev->dev;
-+
-+ pcie->num_clks = devm_clk_bulk_get_all(dev, &pcie->clks);
-+ if (pcie->num_clks < 0)
-+ return dev_err_probe(dev, -ENODEV,
-+ "Failed to get pcie clocks\n");
-+
-+ ret = clk_bulk_prepare_enable(pcie->num_clks, pcie->clks);
-+ if (ret)
-+ return dev_err_probe(&pcie->pdev->dev, ret,
-+ "Failed to enable clocks\n");
-+
-+ pcie->resets = devm_reset_control_array_get_exclusive(dev);
-+ if (IS_ERR(pcie->resets)) {
-+ clk_bulk_disable_unprepare(pcie->num_clks, pcie->clks);
-+ return dev_err_probe(dev, PTR_ERR(pcie->resets),
-+ "Failed to get pcie resets");
-+ }
-+
-+ return reset_control_deassert(pcie->resets);
-+}
-+
-+static void starfive_pcie_clk_rst_deinit(struct starfive_jh7110_pcie *pcie)
-+{
-+ reset_control_assert(pcie->resets);
-+ clk_bulk_disable_unprepare(pcie->num_clks, pcie->clks);
-+}
-+
-+int starfive_pcie_gpio_init(struct starfive_jh7110_pcie *pcie)
-+{
-+ struct device *dev = &pcie->pdev->dev;
-+
-+ pcie->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
-+ if (IS_ERR_OR_NULL(pcie->reset_gpio)) {
-+ dev_warn(dev, "Failed to get reset-gpio.\n");
-+ return -EINVAL;
-+ }
-+
-+ pcie->power_gpio = devm_gpiod_get_optional(dev, "power", GPIOD_OUT_LOW);
-+ if (IS_ERR_OR_NULL(pcie->power_gpio))
-+ pcie->power_gpio = NULL;
-+
-+ return 0;
-+}
-+
-+static void starfive_pcie_hw_init(struct starfive_jh7110_pcie *pcie)
-+{
-+ unsigned int value;
-+ int i;
-+
-+ if (pcie->power_gpio)
-+ gpiod_set_value_cansleep(pcie->power_gpio, 1);
-+
-+ if (pcie->reset_gpio)
-+ gpiod_set_value_cansleep(pcie->reset_gpio, 1);
-+
-+ /* Disable physical functions except #0 */
-+ for (i = 1; i < PCIE_FUNC_NUM; i++) {
-+ regmap_update_bits(pcie->reg_syscon,
-+ pcie->stg_arfun,
-+ STG_SYSCON_AXI4_SLVL_ARFUNC_MASK,
-+ (i << PHY_FUNC_SHIFT) <<
-+ STG_SYSCON_AXI4_SLVL_ARFUNC_SHIFT);
-+ regmap_update_bits(pcie->reg_syscon,
-+ pcie->stg_awfun,
-+ STG_SYSCON_AXI4_SLVL_AWFUNC_MASK,
-+ i << PHY_FUNC_SHIFT);
-+
-+ value = readl(pcie->reg_base + PCI_MISC);
-+ value |= PHY_FUNCTION_DIS;
-+ writel(value, pcie->reg_base + PCI_MISC);
-+ }
-+
-+
-+ regmap_update_bits(pcie->reg_syscon,
-+ pcie->stg_arfun,
-+ STG_SYSCON_AXI4_SLVL_ARFUNC_MASK,
-+ 0);
-+ regmap_update_bits(pcie->reg_syscon,
-+ pcie->stg_awfun,
-+ STG_SYSCON_AXI4_SLVL_AWFUNC_MASK,
-+ 0);
-+
-+ /* Enable root port */
-+ value = readl(pcie->reg_base + GEN_SETTINGS);
-+ value |= RP_ENABLE;
-+ writel(value, pcie->reg_base + GEN_SETTINGS);
-+
-+ /* PCIe PCI Standard Configuration Identification Settings. */
-+ value = (PCI_CLASS_BRIDGE_PCI << IDS_CLASS_CODE_SHIFT);
-+ writel(value, pcie->reg_base + PCIE_PCI_IDS);
-+
-+ /*
-+ * The LTR message forwarding of PCIe Message Reception was set by core
-+ * as default, but the forward id & addr are also need to be reset.
-+ * If we do not disable LTR message forwarding here, or set a legal
-+ * forwarding address, the kernel will get stuck after this driver probe.
-+ * To workaround, disable the LTR message forwarding support on
-+ * PCIe Message Reception.
-+ */
-+ value = readl(pcie->reg_base + PMSG_SUPPORT_RX);
-+ value &= ~PMSG_LTR_SUPPORT;
-+ writel(value, pcie->reg_base + PMSG_SUPPORT_RX);
-+
-+ /* Prefetchable memory window 64-bit addressing support */
-+ value = readl(pcie->reg_base + PCIE_WINROM);
-+ value |= PREF_MEM_WIN_64_SUPPORT;
-+ writel(value, pcie->reg_base + PCIE_WINROM);
-+
-+ /*
-+ * As the two host bridges in JH7110 soc have the same default
-+ * address translation table, this cause the second root port can't
-+ * access it's host bridge config space correctly.
-+ * To workaround, config the ATR of host bridge config space by SW.
-+ */
-+ starfive_pcie_set_atr_entry(pcie,
-+ pcie->config_phyaddr, 0,
-+ XR3PCI_ECAM_SIZE,
-+ XR3PCI_ATR_TRSLID_PCIE_CONFIG);
-+
-+ starfive_pcie_setup_windows(pcie);
-+
-+ /* Ensure that PERST has been asserted for at least 100 ms */
-+ msleep(300);
-+ if (pcie->reset_gpio)
-+ gpiod_set_value_cansleep(pcie->reset_gpio, 0);
-+}
-+
-+static bool starfive_pcie_is_link_up(struct starfive_jh7110_pcie *pcie)
-+{
-+ struct device *dev = &pcie->pdev->dev;
-+ int ret;
-+ u32 stg_reg_val;
-+
-+ /* 100ms timeout value should be enough for Gen1/2 training */
-+ ret = regmap_read_poll_timeout(pcie->reg_syscon,
-+ pcie->stg_lnksta,
-+ stg_reg_val,
-+ stg_reg_val & DATA_LINK_ACTIVE,
-+ 10 * 1000, 100 * 1000);
-+
-+ /* If the link is down (no device in slot), then exit. */
-+ if (ret == -ETIMEDOUT) {
-+ dev_info(dev, "Port link down, exit.\n");
-+ return false;
-+ } else if (ret == 0) {
-+ dev_info(dev, "Port link up.\n");
-+ return true;
-+ }
-+
-+ dev_warn(dev, "Read stg_linksta failed.\n");
-+
-+ return false;
-+}
-+
-+static int starfive_pcie_enable_phy(struct device *dev,
-+ struct starfive_jh7110_pcie *pcie)
-+{
-+ int ret;
-+
-+ if (!pcie->phy)
-+ return 0;
-+
-+ ret = phy_init(pcie->phy);
-+ if (ret)
-+ return dev_err_probe(dev, ret,
-+ "failed to initialize pcie phy\n");
-+
-+ ret = phy_set_mode(pcie->phy, PHY_MODE_PCIE);
-+ if (ret) {
-+ ret = dev_err_probe(dev, ret,
-+ "failed to set pcie mode\n");
-+ goto err_phy_on;
-+ }
-+
-+ ret = phy_power_on(pcie->phy);
-+ if (ret) {
-+ ret = dev_err_probe(dev, ret, "failed to power on pcie phy\n");
-+ goto err_phy_on;
-+ }
-+
-+ return 0;
-+
-+err_phy_on:
-+ phy_exit(pcie->phy);
-+ return ret;
-+}
-+
-+static void starfive_pcie_disable_phy(struct starfive_jh7110_pcie *pcie)
-+{
-+ phy_power_off(pcie->phy);
-+ phy_exit(pcie->phy);
-+}
-+
-+static int starfive_pcie_probe(struct platform_device *pdev)
-+{
-+ struct device *dev = &pdev->dev;
-+ struct starfive_jh7110_pcie *pcie;
-+ struct pci_bus *bus;
-+ struct pci_host_bridge *bridge;
-+ int ret;
-+
-+ pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
-+ if (!pcie)
-+ return -ENOMEM;
-+
-+ pcie->pdev = pdev;
-+ pcie->atr_table_num = 0;
-+
-+ ret = starfive_pcie_parse_dt(pcie);
-+ if (ret)
-+ return ret;
-+
-+ platform_set_drvdata(pdev, pcie);
-+
-+ ret = starfive_pcie_gpio_init(pcie);
-+ if (ret)
-+ return ret;
-+
-+ regmap_update_bits(pcie->reg_syscon,
-+ pcie->stg_rp_nep,
-+ STG_SYSCON_K_RP_NEP,
-+ STG_SYSCON_K_RP_NEP);
-+
-+ regmap_update_bits(pcie->reg_syscon,
-+ pcie->stg_awfun,
-+ STG_SYSCON_CKREF_SRC_MASK,
-+ 2 << STG_SYSCON_CKREF_SRC_SHIFT);
-+
-+ regmap_update_bits(pcie->reg_syscon,
-+ pcie->stg_awfun,
-+ STG_SYSCON_CLKREQ,
-+ STG_SYSCON_CLKREQ);
-+
-+ ret = starfive_pcie_clk_rst_init(pcie);
-+ if (ret)
-+ return ret;
-+
-+ ret = starfive_pcie_init_irq_domain(pcie);
-+ if (ret)
-+ return ret;
-+
-+ bridge = devm_pci_alloc_host_bridge(dev, 0);
-+ if (!bridge)
-+ return -ENOMEM;
-+
-+ pm_runtime_enable(&pdev->dev);
-+ pm_runtime_get_sync(&pdev->dev);
-+
-+ /* Set default bus ops */
-+ bridge->ops = &starfive_pcie_ops;
-+ bridge->sysdata = pcie;
-+ pcie->bridge = bridge;
-+
-+ starfive_pcie_hw_init(pcie);
-+
-+ if (starfive_pcie_is_link_up(pcie) == false)
-+ goto release;
-+
-+ if (IS_ENABLED(CONFIG_PCI_MSI)) {
-+ ret = starfive_pcie_enable_msi(pcie, bus);
-+ if (ret < 0) {
-+ dev_err(dev, "Failed to enable MSI support: %d\n", ret);
-+ goto release;
-+ }
-+ }
-+
-+ ret = starfive_pcie_enable_phy(dev, pcie);
-+ if (ret)
-+ goto release;
-+
-+ ret = pci_host_probe(bridge);
-+ if (ret < 0) {
-+ dev_err_probe(dev, ret, "Failed to pci host probe: %d\n", ret);
-+ goto err_phy_on;
-+ }
-+
-+ return ret;
-+
-+err_phy_on:
-+ starfive_pcie_disable_phy(pcie);
-+release:
-+ if (pcie->power_gpio)
-+ gpiod_set_value_cansleep(pcie->power_gpio, 0);
-+
-+ starfive_pcie_clk_rst_deinit(pcie);
-+
-+ pm_runtime_put_sync(&pdev->dev);
-+ pm_runtime_disable(&pdev->dev);
-+
-+ pci_free_host_bridge(pcie->bridge);
-+ platform_set_drvdata(pdev, NULL);
-+
-+ return ret;
-+}
-+
-+static int starfive_pcie_remove(struct platform_device *pdev)
-+{
-+ struct starfive_jh7110_pcie *pcie = platform_get_drvdata(pdev);
-+
-+ starfive_pcie_disable_phy(pcie);
-+ if (pcie->power_gpio)
-+ gpiod_set_value_cansleep(pcie->power_gpio, 0);
-+ starfive_pcie_free_irq_domain(pcie);
-+ starfive_pcie_clk_rst_deinit(pcie);
-+ platform_set_drvdata(pdev, NULL);
-+
-+ return 0;
-+}
-+
-+#ifdef CONFIG_PM_SLEEP
-+static int __maybe_unused starfive_pcie_suspend_noirq(struct device *dev)
-+{
-+ struct starfive_jh7110_pcie *pcie = dev_get_drvdata(dev);
-+
-+ if (!pcie)
-+ return 0;
-+
-+ starfive_pcie_disable_phy(pcie);
-+ clk_bulk_disable_unprepare(pcie->num_clks, pcie->clks);
-+
-+ return 0;
-+}
-+
-+static int __maybe_unused starfive_pcie_resume_noirq(struct device *dev)
-+{
-+ struct starfive_jh7110_pcie *pcie = dev_get_drvdata(dev);
-+ int ret;
-+
-+ if (!pcie)
-+ return 0;
-+
-+ ret = clk_bulk_prepare_enable(pcie->num_clks, pcie->clks);
-+ if (ret)
-+ return dev_err_probe(dev, ret,
-+ "Failed to enable clocks\n");
-+
-+ ret = starfive_pcie_enable_phy(dev, pcie);
-+ if (ret)
-+ clk_bulk_disable_unprepare(pcie->num_clks, pcie->clks);
-+
-+ return ret;
-+}
-+
-+static const struct dev_pm_ops starfive_pcie_pm_ops = {
-+ SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(starfive_pcie_suspend_noirq,
-+ starfive_pcie_resume_noirq)
-+};
-+#endif
-+
-+static const struct of_device_id starfive_pcie_of_match[] = {
-+ { .compatible = "starfive,jh7110-pcie"},
-+ { /* sentinel */ }
-+};
-+MODULE_DEVICE_TABLE(of, starfive_pcie_of_match);
-+
-+static struct platform_driver starfive_pcie_driver = {
-+ .driver = {
-+ .name = "pcie-starfive",
-+ .of_match_table = of_match_ptr(starfive_pcie_of_match),
-+#ifdef CONFIG_PM_SLEEP
-+ .pm = &starfive_pcie_pm_ops,
-+#endif
-+ },
-+ .probe = starfive_pcie_probe,
-+ .remove = starfive_pcie_remove,
-+};
-+module_platform_driver(starfive_pcie_driver);
-+
-+MODULE_DESCRIPTION("StarFive JH7110 PCIe host driver");
-+MODULE_AUTHOR("Mason Huo <mason.huo@starfivetech.com>");
-+MODULE_AUTHOR("Kevin Xie <kevin.xie@starfivetech.com>");
-+MODULE_AUTHOR("Minda Chen <minda.chen@starfivetech.com>");
-+MODULE_LICENSE("GPL v2");
diff --git a/target/linux/starfive/patches-6.1/0097-cpufreq-dt-platdev-Add-JH7110-SOC-to-the-allowlist.patch b/target/linux/starfive/patches-6.1/0097-cpufreq-dt-platdev-Add-JH7110-SOC-to-the-allowlist.patch
deleted file mode 100644
index cc629f06d2..0000000000
--- a/target/linux/starfive/patches-6.1/0097-cpufreq-dt-platdev-Add-JH7110-SOC-to-the-allowlist.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-From 214c40d5393cdf08c8b0746224e76bfd2a8d9cf7 Mon Sep 17 00:00:00 2001
-From: Mason Huo <mason.huo@starfivetech.com>
-Date: Fri, 21 Apr 2023 11:14:30 +0800
-Subject: [PATCH 097/122] cpufreq: dt-platdev: Add JH7110 SOC to the allowlist
-
-Add the compatible strings for supporting the generic
-cpufreq driver on the StarFive JH7110 SoC.
-
-Signed-off-by: Mason Huo <mason.huo@starfivetech.com>
----
- drivers/cpufreq/cpufreq-dt-platdev.c | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/drivers/cpufreq/cpufreq-dt-platdev.c
-+++ b/drivers/cpufreq/cpufreq-dt-platdev.c
-@@ -86,6 +86,8 @@ static const struct of_device_id allowli
- { .compatible = "st-ericsson,u9500", },
- { .compatible = "st-ericsson,u9540", },
-
-+ { .compatible = "starfive,jh7110", },
-+
- { .compatible = "ti,omap2", },
- { .compatible = "ti,omap4", },
- { .compatible = "ti,omap5", },
diff --git a/target/linux/starfive/patches-6.1/0098-riscv-dts-starfive-Add-full-support-for-JH7110-and-V.patch b/target/linux/starfive/patches-6.1/0098-riscv-dts-starfive-Add-full-support-for-JH7110-and-V.patch
deleted file mode 100644
index 168782a280..0000000000
--- a/target/linux/starfive/patches-6.1/0098-riscv-dts-starfive-Add-full-support-for-JH7110-and-V.patch
+++ /dev/null
@@ -1,1034 +0,0 @@
-From 16e358dcf5e072c82f643d11add5b7e55b36a6f8 Mon Sep 17 00:00:00 2001
-From: "shanlong.li" <shanlong.li@starfivetech.com>
-Date: Wed, 31 May 2023 01:53:31 -0700
-Subject: [PATCH 098/122] riscv: dts: starfive: Add full support for JH7110 and
- VisionFive 2 board
-
-Merge all StarFive dts patches together.
-
-Signed-off-by: shanlong.li <shanlong.li@starfivetech.com>
----
- .../jh7110-starfive-visionfive-2-v1.3b.dts | 8 +-
- .../jh7110-starfive-visionfive-2.dtsi | 338 ++++++++++++
- arch/riscv/boot/dts/starfive/jh7110.dtsi | 506 +++++++++++++++++-
- 3 files changed, 847 insertions(+), 5 deletions(-)
-
---- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-v1.3b.dts
-+++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-v1.3b.dts
-@@ -28,8 +28,8 @@
- motorcomm,tx-clk-adj-enabled;
- motorcomm,tx-clk-100-inverted;
- motorcomm,tx-clk-1000-inverted;
-- rx-clk-driver-strength = <0x6>;
-- rx-data-driver-strength = <0x3>;
-+ motorcomm,rx-clk-driver-strength = <0x6>;
-+ motorcomm,rx-data-driver-strength = <0x3>;
- rx-internal-delay-ps = <1500>;
- tx-internal-delay-ps = <1500>;
- };
-@@ -37,8 +37,8 @@
- &phy1 {
- motorcomm,tx-clk-adj-enabled;
- motorcomm,tx-clk-100-inverted;
-- rx-clk-driver-strength = <0x6>;
-- rx-data-driver-strength = <0x3>;
-+ motorcomm,rx-clk-driver-strength = <0x6>;
-+ motorcomm,rx-data-driver-strength = <0x3>;
- rx-internal-delay-ps = <300>;
- tx-internal-delay-ps = <0>;
- };
---- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
-+++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
-@@ -33,11 +33,64 @@
- reg = <0x0 0x40000000 0x1 0x0>;
- };
-
-+ reserved-memory {
-+ #address-cells = <2>;
-+ #size-cells = <2>;
-+ ranges;
-+
-+ linux,cma {
-+ compatible = "shared-dma-pool";
-+ reusable;
-+ size = <0x0 0x20000000>;
-+ alignment = <0x0 0x1000>;
-+ alloc-ranges = <0x0 0x80000000 0x0 0x20000000>;
-+ linux,cma-default;
-+ };
-+ };
-+
-+ thermal-zones {
-+ cpu-thermal {
-+ polling-delay-passive = <250>;
-+ polling-delay = <15000>;
-+
-+ thermal-sensors = <&sfctemp>;
-+
-+ cooling-maps {
-+ };
-+
-+ trips {
-+ cpu_alert0: cpu_alert0 {
-+ /* milliCelsius */
-+ temperature = <75000>;
-+ hysteresis = <2000>;
-+ type = "passive";
-+ };
-+
-+ cpu_crit: cpu_crit {
-+ /* milliCelsius */
-+ temperature = <90000>;
-+ hysteresis = <2000>;
-+ type = "critical";
-+ };
-+ };
-+ };
-+ };
-+
- gpio-restart {
- compatible = "gpio-restart";
- gpios = <&sysgpio 35 GPIO_ACTIVE_HIGH>;
- priority = <224>;
- };
-+
-+ clk_ext_camera: clk_ext_camera {
-+ compatible = "fixed-clock";
-+ #clock-cells = <0>;
-+ clock-frequency = <24000000>;
-+ };
-+};
-+
-+&dvp_clk {
-+ clock-frequency = <74250000>;
- };
-
- &gmac0_rgmii_rxin {
-@@ -56,6 +109,10 @@
- clock-frequency = <50000000>;
- };
-
-+&hdmitx0_pixelclk {
-+ clock-frequency = <297000000>;
-+};
-+
- &i2srx_bclk_ext {
- clock-frequency = <12288000>;
- };
-@@ -88,6 +145,39 @@
- clock-frequency = <49152000>;
- };
-
-+&csi2rx {
-+ status = "okay";
-+
-+ assigned-clocks = <&ispcrg JH7110_ISPCLK_VIN_SYS>;
-+ assigned-clock-rates = <297000000>;
-+
-+ ports {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ port@0 {
-+ reg = <0>;
-+
-+ csi2rx_from_imx219: endpoint {
-+ remote-endpoint = <&imx219_to_csi2rx>;
-+ bus-type = <4>;
-+ clock-lanes = <0>;
-+ data-lanes = <1 2>;
-+ status = "okay";
-+ };
-+ };
-+
-+ port@1 {
-+ reg = <1>;
-+
-+ csi2rx_to_vin: endpoint {
-+ remote-endpoint = <&vin_from_csi2rx>;
-+ status = "okay";
-+ };
-+ };
-+ };
-+};
-+
- &gmac0 {
- phy-handle = <&phy0>;
- phy-mode = "rgmii-id";
-@@ -148,6 +238,20 @@
- pinctrl-names = "default";
- pinctrl-0 = <&i2c5_pins>;
- status = "okay";
-+
-+ axp15060: pmic@36 {
-+ compatible = "x-powers,axp15060";
-+ reg = <0x36>;
-+
-+ regulators {
-+ vdd_cpu: dcdc2 {
-+ regulator-always-on;
-+ regulator-min-microvolt = <500000>;
-+ regulator-max-microvolt = <1540000>;
-+ regulator-name = "vdd-cpu";
-+ };
-+ };
-+ };
- };
-
- &i2c6 {
-@@ -158,6 +262,121 @@
- pinctrl-names = "default";
- pinctrl-0 = <&i2c6_pins>;
- status = "okay";
-+
-+ imx219: imx219@10 {
-+ compatible = "sony,imx219";
-+ reg = <0x10>;
-+ clocks = <&clk_ext_camera>;
-+ reset-gpio = <&sysgpio 18 0>;
-+ rotation = <0>;
-+ orientation = <1>;
-+
-+ port {
-+ imx219_to_csi2rx: endpoint {
-+ remote-endpoint = <&csi2rx_from_imx219>;
-+ bus-type = <4>;
-+ clock-lanes = <0>;
-+ data-lanes = <1 2>;
-+ link-frequencies = /bits/ 64 <456000000>;
-+ };
-+ };
-+ };
-+};
-+
-+&mmc0 {
-+ max-frequency = <100000000>;
-+ bus-width = <8>;
-+ cap-mmc-highspeed;
-+ mmc-ddr-1_8v;
-+ mmc-hs200-1_8v;
-+ non-removable;
-+ cap-mmc-hw-reset;
-+ post-power-on-delay-ms = <200>;
-+ status = "okay";
-+};
-+
-+&mmc1 {
-+ max-frequency = <100000000>;
-+ bus-width = <4>;
-+ no-sdio;
-+ no-mmc;
-+ broken-cd;
-+ cap-sd-highspeed;
-+ post-power-on-delay-ms = <200>;
-+ status = "okay";
-+};
-+
-+&pcie0 {
-+ pinctrl-names = "default";
-+ reset-gpios = <&sysgpio 26 GPIO_ACTIVE_LOW>;
-+ phys = <&pciephy0>;
-+ status = "okay";
-+};
-+
-+&pcie1 {
-+ pinctrl-names = "default";
-+ reset-gpios = <&sysgpio 28 GPIO_ACTIVE_LOW>;
-+ phys = <&pciephy1>;
-+ status = "okay";
-+};
-+
-+&ptc {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&pwm_pins>;
-+ status = "okay";
-+};
-+
-+&qspi {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ nor_flash: flash@0 {
-+ compatible = "jedec,spi-nor";
-+ reg=<0>;
-+ cdns,read-delay = <5>;
-+ spi-max-frequency = <12000000>;
-+ cdns,tshsl-ns = <1>;
-+ cdns,tsd2d-ns = <1>;
-+ cdns,tchsh-ns = <1>;
-+ cdns,tslch-ns = <1>;
-+
-+ partitions {
-+ compatible = "fixed-partitions";
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ spl@0 {
-+ reg = <0x0 0x20000>;
-+ };
-+ uboot@100000 {
-+ reg = <0x100000 0x300000>;
-+ };
-+ data@f00000 {
-+ reg = <0xf00000 0x100000>;
-+ };
-+ };
-+ };
-+};
-+
-+&stfcamss {
-+ status = "okay";
-+
-+ ports {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ port@1 {
-+ reg = <1>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ vin_from_csi2rx: endpoint@1 {
-+ reg = <1>;
-+ remote-endpoint = <&csi2rx_to_vin>;
-+ status = "okay";
-+ };
-+ };
-+ };
- };
-
- &sysgpio {
-@@ -217,6 +436,98 @@
- };
- };
-
-+ pcie0_wake_default: pcie0_wake_default {
-+ wake-pins {
-+ pinmux = <GPIOMUX(32, GPOUT_HIGH, GPOEN_ENABLE, GPI_NONE)>;
-+ bias-disable;
-+ drive-strength = <2>;
-+ input-enable;
-+ input-schmitt-disable;
-+ slew-rate = <0>;
-+ };
-+ };
-+
-+ pcie0_clkreq_default: pcie0_clkreq_default {
-+ clkreq-pins {
-+ bias-disable;
-+ pinmux = <GPIOMUX(27, GPOUT_HIGH, GPOEN_ENABLE, GPI_NONE)>;
-+ drive-strength = <2>;
-+ input-enable;
-+ input-schmitt-disable;
-+ slew-rate = <0>;
-+ };
-+ };
-+
-+ pcie1_wake_default: pcie1_wake_default {
-+ wake-pins {
-+ bias-disable;
-+ pinmux = <GPIOMUX(21, GPOUT_HIGH, GPOEN_ENABLE, GPI_NONE)>;
-+ drive-strength = <2>;
-+ input-enable;
-+ input-schmitt-disable;
-+ slew-rate = <0>;
-+ };
-+ };
-+
-+ pcie1_clkreq_default: pcie1_clkreq_default {
-+ clkreq-pins {
-+ bias-disable;
-+ pinmux = <GPIOMUX(29, GPOUT_HIGH, GPOEN_ENABLE, GPI_NONE)>;
-+ drive-strength = <2>;
-+ input-enable;
-+ input-schmitt-disable;
-+ slew-rate = <0>;
-+ };
-+ };
-+
-+ pwm_pins: pwm-0 {
-+ pwm-pins {
-+ pinmux = <GPIOMUX(46, GPOUT_SYS_PWM_CHANNEL0,
-+ GPOEN_SYS_PWM0_CHANNEL0, GPI_NONE)>,
-+ <GPIOMUX(59, GPOUT_SYS_PWM_CHANNEL1,
-+ GPOEN_SYS_PWM0_CHANNEL1, GPI_NONE)>;
-+ bias-disable;
-+ drive-strength = <12>;
-+ input-disable;
-+ input-schmitt-disable;
-+ slew-rate = <0>;
-+ };
-+ };
-+
-+ tdm0_pins: tdm0-pins {
-+ tdm0-pins-tx {
-+ pinmux = <GPIOMUX(44, GPOUT_SYS_TDM_TXD,
-+ GPOEN_ENABLE,
-+ GPI_NONE)>;
-+ bias-pull-up;
-+ drive-strength = <2>;
-+ input-disable;
-+ input-schmitt-disable;
-+ slew-rate = <0>;
-+ };
-+
-+ tdm0-pins-rx {
-+ pinmux = <GPIOMUX(61, GPOUT_HIGH,
-+ GPOEN_DISABLE,
-+ GPI_SYS_TDM_RXD)>;
-+ input-enable;
-+ };
-+
-+ tdm0-pins-sync {
-+ pinmux = <GPIOMUX(63, GPOUT_HIGH,
-+ GPOEN_DISABLE,
-+ GPI_SYS_TDM_SYNC)>;
-+ input-enable;
-+ };
-+
-+ tdm0-pins-pcmclk {
-+ pinmux = <GPIOMUX(38, GPOUT_HIGH,
-+ GPOEN_DISABLE,
-+ GPI_SYS_TDM_CLK)>;
-+ input-enable;
-+ };
-+ };
-+
- uart0_pins: uart0-0 {
- tx-pins {
- pinmux = <GPIOMUX(5, GPOUT_SYS_UART0_TX,
-@@ -242,8 +553,35 @@
- };
- };
-
-+&tdm {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&tdm0_pins>;
-+ status = "okay";
-+};
-+
- &uart0 {
- pinctrl-names = "default";
- pinctrl-0 = <&uart0_pins>;
- status = "okay";
- };
-+
-+&usb0 {
-+ dr_mode = "peripheral";
-+ status = "okay";
-+};
-+
-+&U74_1 {
-+ cpu-supply = <&vdd_cpu>;
-+};
-+
-+&U74_2 {
-+ cpu-supply = <&vdd_cpu>;
-+};
-+
-+&U74_3 {
-+ cpu-supply = <&vdd_cpu>;
-+};
-+
-+&U74_4 {
-+ cpu-supply = <&vdd_cpu>;
-+};
---- a/arch/riscv/boot/dts/starfive/jh7110.dtsi
-+++ b/arch/riscv/boot/dts/starfive/jh7110.dtsi
-@@ -6,6 +6,7 @@
-
- /dts-v1/;
- #include <dt-bindings/clock/starfive,jh7110-crg.h>
-+#include <dt-bindings/power/starfive,jh7110-pmu.h>
- #include <dt-bindings/reset/starfive,jh7110-crg.h>
-
- / {
-@@ -53,6 +54,9 @@
- next-level-cache = <&ccache>;
- riscv,isa = "rv64imafdc_zba_zbb";
- tlb-split;
-+ operating-points-v2 = <&cpu_opp>;
-+ clocks = <&syscrg JH7110_SYSCLK_CPU_CORE>;
-+ clock-names = "cpu";
-
- cpu1_intc: interrupt-controller {
- compatible = "riscv,cpu-intc";
-@@ -79,6 +83,9 @@
- next-level-cache = <&ccache>;
- riscv,isa = "rv64imafdc_zba_zbb";
- tlb-split;
-+ operating-points-v2 = <&cpu_opp>;
-+ clocks = <&syscrg JH7110_SYSCLK_CPU_CORE>;
-+ clock-names = "cpu";
-
- cpu2_intc: interrupt-controller {
- compatible = "riscv,cpu-intc";
-@@ -105,6 +112,9 @@
- next-level-cache = <&ccache>;
- riscv,isa = "rv64imafdc_zba_zbb";
- tlb-split;
-+ operating-points-v2 = <&cpu_opp>;
-+ clocks = <&syscrg JH7110_SYSCLK_CPU_CORE>;
-+ clock-names = "cpu";
-
- cpu3_intc: interrupt-controller {
- compatible = "riscv,cpu-intc";
-@@ -131,6 +141,9 @@
- next-level-cache = <&ccache>;
- riscv,isa = "rv64imafdc_zba_zbb";
- tlb-split;
-+ operating-points-v2 = <&cpu_opp>;
-+ clocks = <&syscrg JH7110_SYSCLK_CPU_CORE>;
-+ clock-names = "cpu";
-
- cpu4_intc: interrupt-controller {
- compatible = "riscv,cpu-intc";
-@@ -164,6 +177,33 @@
- };
- };
-
-+ cpu_opp: opp-table-0 {
-+ compatible = "operating-points-v2";
-+ opp-shared;
-+ opp-375000000 {
-+ opp-hz = /bits/ 64 <375000000>;
-+ opp-microvolt = <800000>;
-+ };
-+ opp-500000000 {
-+ opp-hz = /bits/ 64 <500000000>;
-+ opp-microvolt = <800000>;
-+ };
-+ opp-750000000 {
-+ opp-hz = /bits/ 64 <750000000>;
-+ opp-microvolt = <800000>;
-+ };
-+ opp-1500000000 {
-+ opp-hz = /bits/ 64 <1500000000>;
-+ opp-microvolt = <1040000>;
-+ };
-+ };
-+
-+ dvp_clk: dvp-clock {
-+ compatible = "fixed-clock";
-+ clock-output-names = "dvp_clk";
-+ #clock-cells = <0>;
-+ };
-+
- gmac0_rgmii_rxin: gmac0-rgmii-rxin-clock {
- compatible = "fixed-clock";
- clock-output-names = "gmac0_rgmii_rxin";
-@@ -188,6 +228,12 @@
- #clock-cells = <0>;
- };
-
-+ hdmitx0_pixelclk: hdmitx0-pixel-clock {
-+ compatible = "fixed-clock";
-+ clock-output-names = "hdmitx0_pixelclk";
-+ #clock-cells = <0>;
-+ };
-+
- i2srx_bclk_ext: i2srx-bclk-ext-clock {
- compatible = "fixed-clock";
- clock-output-names = "i2srx_bclk_ext";
-@@ -360,6 +406,99 @@
- status = "disabled";
- };
-
-+ tdm: tdm@10090000 {
-+ compatible = "starfive,jh7110-tdm";
-+ reg = <0x0 0x10090000 0x0 0x1000>;
-+ clocks = <&syscrg JH7110_SYSCLK_TDM_AHB>,
-+ <&syscrg JH7110_SYSCLK_TDM_APB>,
-+ <&syscrg JH7110_SYSCLK_TDM_INTERNAL>,
-+ <&syscrg JH7110_SYSCLK_TDM_TDM>,
-+ <&syscrg JH7110_SYSCLK_MCLK_INNER>,
-+ <&tdm_ext>;
-+ clock-names = "tdm_ahb", "tdm_apb",
-+ "tdm_internal", "tdm",
-+ "mclk_inner", "tdm_ext";
-+ resets = <&syscrg JH7110_SYSRST_TDM_AHB>,
-+ <&syscrg JH7110_SYSRST_TDM_APB>,
-+ <&syscrg JH7110_SYSRST_TDM_CORE>;
-+ dmas = <&dma 20>, <&dma 21>;
-+ dma-names = "rx","tx";
-+ #sound-dai-cells = <0>;
-+ status = "disabled";
-+ };
-+
-+ usb0: usb@10100000 {
-+ compatible = "starfive,jh7110-usb";
-+ ranges = <0x0 0x0 0x10100000 0x100000>;
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+ starfive,stg-syscon = <&stg_syscon 0x4>;
-+ clocks = <&stgcrg JH7110_STGCLK_USB0_LPM>,
-+ <&stgcrg JH7110_STGCLK_USB0_STB>,
-+ <&stgcrg JH7110_STGCLK_USB0_APB>,
-+ <&stgcrg JH7110_STGCLK_USB0_AXI>,
-+ <&stgcrg JH7110_STGCLK_USB0_UTMI_APB>;
-+ clock-names = "lpm", "stb", "apb", "axi", "utmi_apb";
-+ resets = <&stgcrg JH7110_STGRST_USB0_PWRUP>,
-+ <&stgcrg JH7110_STGRST_USB0_APB>,
-+ <&stgcrg JH7110_STGRST_USB0_AXI>,
-+ <&stgcrg JH7110_STGRST_USB0_UTMI_APB>;
-+ reset-names = "pwrup", "apb", "axi", "utmi_apb";
-+ status = "disabled";
-+
-+ usb_cdns3: usb@0 {
-+ compatible = "cdns,usb3";
-+ reg = <0x0 0x10000>,
-+ <0x10000 0x10000>,
-+ <0x20000 0x10000>;
-+ reg-names = "otg", "xhci", "dev";
-+ interrupts = <100>, <108>, <110>;
-+ interrupt-names = "host", "peripheral", "otg";
-+ phys = <&usbphy0>;
-+ phy-names = "cdns3,usb2-phy";
-+ };
-+ };
-+
-+ usbphy0: phy@10200000 {
-+ compatible = "starfive,jh7110-usb-phy";
-+ reg = <0x0 0x10200000 0x0 0x10000>;
-+ clocks = <&syscrg JH7110_SYSCLK_USB_125M>,
-+ <&stgcrg JH7110_STGCLK_USB0_APP_125>;
-+ clock-names = "125m", "app_125m";
-+ #phy-cells = <0>;
-+ };
-+
-+ pciephy0: phy@10210000 {
-+ compatible = "starfive,jh7110-pcie-phy";
-+ reg = <0x0 0x10210000 0x0 0x10000>;
-+ #phy-cells = <0>;
-+ };
-+
-+ pciephy1: phy@10220000 {
-+ compatible = "starfive,jh7110-pcie-phy";
-+ reg = <0x0 0x10220000 0x0 0x10000>;
-+ #phy-cells = <0>;
-+ };
-+
-+ stgcrg: clock-controller@10230000 {
-+ compatible = "starfive,jh7110-stgcrg";
-+ reg = <0x0 0x10230000 0x0 0x10000>;
-+ clocks = <&osc>,
-+ <&syscrg JH7110_SYSCLK_HIFI4_CORE>,
-+ <&syscrg JH7110_SYSCLK_STG_AXIAHB>,
-+ <&syscrg JH7110_SYSCLK_USB_125M>,
-+ <&syscrg JH7110_SYSCLK_CPU_BUS>,
-+ <&syscrg JH7110_SYSCLK_HIFI4_AXI>,
-+ <&syscrg JH7110_SYSCLK_NOCSTG_BUS>,
-+ <&syscrg JH7110_SYSCLK_APB_BUS>;
-+ clock-names = "osc", "hifi4_core",
-+ "stg_axiahb", "usb_125m",
-+ "cpu_bus", "hifi4_axi",
-+ "nocstg_bus", "apb_bus";
-+ #clock-cells = <1>;
-+ #reset-cells = <1>;
-+ };
-+
- stg_syscon: syscon@10240000 {
- compatible = "starfive,jh7110-stg-syscon", "syscon";
- reg = <0x0 0x10240000 0x0 0x1000>;
-@@ -452,6 +591,45 @@
- status = "disabled";
- };
-
-+ ptc: pwm@120d0000 {
-+ compatible = "starfive,jh7110-pwm";
-+ reg = <0x0 0x120d0000 0x0 0x10000>;
-+ clocks = <&syscrg JH7110_SYSCLK_PWM_APB>;
-+ resets = <&syscrg JH7110_SYSRST_PWM_APB>;
-+ #pwm-cells=<3>;
-+ status = "disabled";
-+ };
-+
-+ sfctemp: temperature-sensor@120e0000 {
-+ compatible = "starfive,jh7110-temp";
-+ reg = <0x0 0x120e0000 0x0 0x10000>;
-+ clocks = <&syscrg JH7110_SYSCLK_TEMP_CORE>,
-+ <&syscrg JH7110_SYSCLK_TEMP_APB>;
-+ clock-names = "sense", "bus";
-+ resets = <&syscrg JH7110_SYSRST_TEMP_CORE>,
-+ <&syscrg JH7110_SYSRST_TEMP_APB>;
-+ reset-names = "sense", "bus";
-+ #thermal-sensor-cells = <0>;
-+ };
-+
-+ qspi: spi@13010000 {
-+ compatible = "starfive,jh7110-qspi", "cdns,qspi-nor";
-+ reg = <0x0 0x13010000 0x0 0x10000
-+ 0x0 0x21000000 0x0 0x400000>;
-+ interrupts = <25>;
-+ clocks = <&syscrg JH7110_SYSCLK_QSPI_REF>,
-+ <&syscrg JH7110_SYSCLK_QSPI_AHB>,
-+ <&syscrg JH7110_SYSCLK_QSPI_APB>;
-+ clock-names = "qspi-ref", "qspi-ahb", "qspi-apb";
-+ resets = <&syscrg JH7110_SYSRST_QSPI_APB>,
-+ <&syscrg JH7110_SYSRST_QSPI_AHB>,
-+ <&syscrg JH7110_SYSRST_QSPI_REF>;
-+ reset-names = "qspi", "qspi-ocp", "rstc_ref";
-+ cdns,fifo-depth = <256>;
-+ cdns,fifo-width = <4>;
-+ cdns,trigger-address = <0x0>;
-+ };
-+
- syscrg: clock-controller@13020000 {
- compatible = "starfive,jh7110-syscrg";
- reg = <0x0 0x13020000 0x0 0x10000>;
-@@ -496,6 +674,107 @@
- #gpio-cells = <2>;
- };
-
-+ timer@13050000 {
-+ compatible = "starfive,jh7110-timer";
-+ reg = <0x0 0x13050000 0x0 0x10000>;
-+ interrupts = <69>, <70>, <71> ,<72>;
-+ clocks = <&syscrg JH7110_SYSCLK_TIMER_APB>,
-+ <&syscrg JH7110_SYSCLK_TIMER0>,
-+ <&syscrg JH7110_SYSCLK_TIMER1>,
-+ <&syscrg JH7110_SYSCLK_TIMER2>,
-+ <&syscrg JH7110_SYSCLK_TIMER3>;
-+ clock-names = "apb", "ch0", "ch1",
-+ "ch2", "ch3";
-+ resets = <&syscrg JH7110_SYSRST_TIMER_APB>,
-+ <&syscrg JH7110_SYSRST_TIMER0>,
-+ <&syscrg JH7110_SYSRST_TIMER1>,
-+ <&syscrg JH7110_SYSRST_TIMER2>,
-+ <&syscrg JH7110_SYSRST_TIMER3>;
-+ reset-names = "apb", "ch0", "ch1",
-+ "ch2", "ch3";
-+ };
-+
-+ watchdog@13070000 {
-+ compatible = "starfive,jh7110-wdt";
-+ reg = <0x0 0x13070000 0x0 0x10000>;
-+ clocks = <&syscrg JH7110_SYSCLK_WDT_APB>,
-+ <&syscrg JH7110_SYSCLK_WDT_CORE>;
-+ clock-names = "apb", "core";
-+ resets = <&syscrg JH7110_SYSRST_WDT_APB>,
-+ <&syscrg JH7110_SYSRST_WDT_CORE>;
-+ };
-+
-+ crypto: crypto@16000000 {
-+ compatible = "starfive,jh7110-crypto";
-+ reg = <0x0 0x16000000 0x0 0x4000>;
-+ clocks = <&stgcrg JH7110_STGCLK_SEC_AHB>,
-+ <&stgcrg JH7110_STGCLK_SEC_MISC_AHB>;
-+ clock-names = "hclk", "ahb";
-+ interrupts = <28>;
-+ resets = <&stgcrg JH7110_STGRST_SEC_AHB>;
-+ dmas = <&sdma 1 2>, <&sdma 0 2>;
-+ dma-names = "tx", "rx";
-+ status = "disabled";
-+ };
-+
-+ sdma: dma@16008000 {
-+ compatible = "arm,pl080", "arm,primecell";
-+ arm,primecell-periphid = <0x00041080>;
-+ reg = <0x0 0x16008000 0x0 0x4000>;
-+ interrupts = <29>;
-+ clocks = <&stgcrg JH7110_STGCLK_SEC_AHB>,
-+ <&stgcrg JH7110_STGCLK_SEC_MISC_AHB>;
-+ clock-names = "hclk", "apb_pclk";
-+ resets = <&stgcrg JH7110_STGRST_SEC_AHB>;
-+ lli-bus-interface-ahb1;
-+ mem-bus-interface-ahb1;
-+ memcpy-burst-size = <256>;
-+ memcpy-bus-width = <32>;
-+ #dma-cells = <2>;
-+ };
-+
-+ rng: rng@1600c000 {
-+ compatible = "starfive,jh7110-trng";
-+ reg = <0x0 0x1600C000 0x0 0x4000>;
-+ clocks = <&stgcrg JH7110_STGCLK_SEC_AHB>,
-+ <&stgcrg JH7110_STGCLK_SEC_MISC_AHB>;
-+ clock-names = "hclk", "ahb";
-+ resets = <&stgcrg JH7110_STGRST_SEC_AHB>;
-+ interrupts = <30>;
-+ };
-+
-+ mmc0: mmc@16010000 {
-+ compatible = "starfive,jh7110-mmc";
-+ reg = <0x0 0x16010000 0x0 0x10000>;
-+ clocks = <&syscrg JH7110_SYSCLK_SDIO0_AHB>,
-+ <&syscrg JH7110_SYSCLK_SDIO0_SDCARD>;
-+ clock-names = "biu","ciu";
-+ resets = <&syscrg JH7110_SYSRST_SDIO0_AHB>;
-+ reset-names = "reset";
-+ interrupts = <74>;
-+ fifo-depth = <32>;
-+ fifo-watermark-aligned;
-+ data-addr = <0>;
-+ starfive,sysreg = <&sys_syscon 0x14 0x1a 0x7c000000>;
-+ status = "disabled";
-+ };
-+
-+ mmc1: mmc@16020000 {
-+ compatible = "starfive,jh7110-mmc";
-+ reg = <0x0 0x16020000 0x0 0x10000>;
-+ clocks = <&syscrg JH7110_SYSCLK_SDIO1_AHB>,
-+ <&syscrg JH7110_SYSCLK_SDIO1_SDCARD>;
-+ clock-names = "biu","ciu";
-+ resets = <&syscrg JH7110_SYSRST_SDIO1_AHB>;
-+ reset-names = "reset";
-+ interrupts = <75>;
-+ fifo-depth = <32>;
-+ fifo-watermark-aligned;
-+ data-addr = <0>;
-+ starfive,sysreg = <&sys_syscon 0x9c 0x1 0x3e>;
-+ status = "disabled";
-+ };
-+
- gmac0: ethernet@16030000 {
- compatible = "starfive,jh7110-dwmac", "snps,dwmac-5.20";
- reg = <0x0 0x16030000 0x0 0x10000>;
-@@ -558,6 +837,24 @@
- status = "disabled";
- };
-
-+ dma: dma-controller@16050000 {
-+ compatible = "starfive,jh7110-axi-dma";
-+ reg = <0x0 0x16050000 0x0 0x10000>;
-+ clocks = <&stgcrg JH7110_STGCLK_DMA1P_AXI>,
-+ <&stgcrg JH7110_STGCLK_DMA1P_AHB>;
-+ clock-names = "core-clk", "cfgr-clk";
-+ resets = <&stgcrg JH7110_STGRST_DMA1P_AXI>,
-+ <&stgcrg JH7110_STGRST_DMA1P_AHB>;
-+ interrupts = <73>;
-+ #dma-cells = <1>;
-+ dma-channels = <4>;
-+ snps,dma-masters = <1>;
-+ snps,data-width = <3>;
-+ snps,block-size = <65536 65536 65536 65536>;
-+ snps,priority = <0 1 2 3>;
-+ snps,axi-max-burst-len = <16>;
-+ };
-+
- aoncrg: clock-controller@17000000 {
- compatible = "starfive,jh7110-aoncrg";
- reg = <0x0 0x17000000 0x0 0x10000>;
-@@ -576,8 +873,9 @@
- };
-
- aon_syscon: syscon@17010000 {
-- compatible = "starfive,jh7110-aon-syscon", "syscon", "simple-mfd";
-+ compatible = "starfive,jh7110-aon-syscon", "syscon";
- reg = <0x0 0x17010000 0x0 0x1000>;
-+ #power-domain-cells = <1>;
- };
-
- aongpio: pinctrl@17020000 {
-@@ -590,5 +888,211 @@
- gpio-controller;
- #gpio-cells = <2>;
- };
-+
-+ pwrc: power-controller@17030000 {
-+ compatible = "starfive,jh7110-pmu";
-+ reg = <0x0 0x17030000 0x0 0x10000>;
-+ interrupts = <111>;
-+ #power-domain-cells = <1>;
-+ };
-+
-+ csi2rx: csi-bridge@19800000 {
-+ compatible = "starfive,jh7110-csi2rx";
-+ reg = <0x0 0x19800000 0x0 0x10000>;
-+ clocks = <&ispcrg JH7110_ISPCLK_VIN_SYS>,
-+ <&ispcrg JH7110_ISPCLK_VIN_APB>,
-+ <&ispcrg JH7110_ISPCLK_VIN_PIXEL_IF0>,
-+ <&ispcrg JH7110_ISPCLK_VIN_PIXEL_IF1>,
-+ <&ispcrg JH7110_ISPCLK_VIN_PIXEL_IF2>,
-+ <&ispcrg JH7110_ISPCLK_VIN_PIXEL_IF3>;
-+ clock-names = "sys_clk", "p_clk",
-+ "pixel_if0_clk", "pixel_if1_clk",
-+ "pixel_if2_clk", "pixel_if3_clk";
-+ resets = <&ispcrg JH7110_ISPRST_VIN_SYS>,
-+ <&ispcrg JH7110_ISPRST_VIN_APB>,
-+ <&ispcrg JH7110_ISPRST_VIN_PIXEL_IF0>,
-+ <&ispcrg JH7110_ISPRST_VIN_PIXEL_IF1>,
-+ <&ispcrg JH7110_ISPRST_VIN_PIXEL_IF2>,
-+ <&ispcrg JH7110_ISPRST_VIN_PIXEL_IF3>;
-+ reset-names = "sys", "reg_bank",
-+ "pixel_if0", "pixel_if1",
-+ "pixel_if2", "pixel_if3";
-+ phys = <&csi_phy>;
-+ phy-names = "dphy";
-+ status = "disabled";
-+ };
-+
-+ ispcrg: clock-controller@19810000 {
-+ compatible = "starfive,jh7110-ispcrg";
-+ reg = <0x0 0x19810000 0x0 0x10000>;
-+ clocks = <&syscrg JH7110_SYSCLK_ISP_TOP_CORE>,
-+ <&syscrg JH7110_SYSCLK_ISP_TOP_AXI>,
-+ <&syscrg JH7110_SYSCLK_NOC_BUS_ISP_AXI>,
-+ <&dvp_clk>;
-+ clock-names = "isp_top_core", "isp_top_axi",
-+ "noc_bus_isp_axi", "dvp_clk";
-+ resets = <&syscrg JH7110_SYSRST_ISP_TOP>,
-+ <&syscrg JH7110_SYSRST_ISP_TOP_AXI>,
-+ <&syscrg JH7110_SYSRST_NOC_BUS_ISP_AXI>;
-+ #clock-cells = <1>;
-+ #reset-cells = <1>;
-+ power-domains = <&pwrc JH7110_PD_ISP>;
-+ };
-+
-+ csi_phy: phy@19820000 {
-+ compatible = "starfive,jh7110-dphy-rx";
-+ reg = <0x0 0x19820000 0x0 0x10000>;
-+ clocks = <&ispcrg JH7110_ISPCLK_M31DPHY_CFG_IN>,
-+ <&ispcrg JH7110_ISPCLK_M31DPHY_REF_IN>,
-+ <&ispcrg JH7110_ISPCLK_M31DPHY_TX_ESC_LAN0>;
-+ clock-names = "cfg", "ref", "tx";
-+ resets = <&ispcrg JH7110_ISPRST_M31DPHY_HW>,
-+ <&ispcrg JH7110_ISPRST_M31DPHY_B09_AON>;
-+ power-domains = <&aon_syscon JH7110_PD_DPHY_RX>;
-+ #phy-cells = <0>;
-+ };
-+
-+ stfcamss: camss@19840000 {
-+ compatible = "starfive,jh7110-camss";
-+ reg = <0x0 0x19840000 0x0 0x10000>,
-+ <0x0 0x19870000 0x0 0x30000>;
-+ reg-names = "syscon", "isp";
-+ clocks = <&ispcrg JH7110_ISPCLK_DOM4_APB_FUNC>,
-+ <&ispcrg JH7110_ISPCLK_ISPV2_TOP_WRAPPER_C>,
-+ <&ispcrg JH7110_ISPCLK_DVP_INV>,
-+ <&ispcrg JH7110_ISPCLK_VIN_P_AXI_WR>,
-+ <&ispcrg JH7110_ISPCLK_MIPI_RX0_PXL>,
-+ <&syscrg JH7110_SYSCLK_ISP_TOP_CORE>,
-+ <&syscrg JH7110_SYSCLK_ISP_TOP_AXI>;
-+ clock-names = "clk_apb_func",
-+ "clk_wrapper_clk_c",
-+ "clk_dvp_inv",
-+ "clk_axiwr",
-+ "clk_mipi_rx0_pxl",
-+ "clk_ispcore_2x",
-+ "clk_isp_axi";
-+ resets = <&ispcrg JH7110_ISPRST_ISPV2_TOP_WRAPPER_P>,
-+ <&ispcrg JH7110_ISPRST_ISPV2_TOP_WRAPPER_C>,
-+ <&ispcrg JH7110_ISPRST_VIN_P_AXI_RD>,
-+ <&ispcrg JH7110_ISPRST_VIN_P_AXI_WR>,
-+ <&syscrg JH7110_SYSRST_ISP_TOP>,
-+ <&syscrg JH7110_SYSRST_ISP_TOP_AXI>;
-+ reset-names = "rst_wrapper_p",
-+ "rst_wrapper_c",
-+ "rst_axird",
-+ "rst_axiwr",
-+ "rst_isp_top_n",
-+ "rst_isp_top_axi";
-+ power-domains = <&pwrc JH7110_PD_ISP>;
-+ /* irq nr: vin, isp, isp_csi, isp_csiline */
-+ interrupts = <92>, <87>, <90>;
-+ status = "disabled";
-+ };
-+
-+ voutcrg: clock-controller@295c0000 {
-+ compatible = "starfive,jh7110-voutcrg";
-+ reg = <0x0 0x295c0000 0x0 0x10000>;
-+ clocks = <&syscrg JH7110_SYSCLK_VOUT_SRC>,
-+ <&syscrg JH7110_SYSCLK_VOUT_TOP_AHB>,
-+ <&syscrg JH7110_SYSCLK_VOUT_TOP_AXI>,
-+ <&syscrg JH7110_SYSCLK_VOUT_TOP_HDMITX0_MCLK>,
-+ <&syscrg JH7110_SYSCLK_I2STX0_BCLK>,
-+ <&hdmitx0_pixelclk>;
-+ clock-names = "vout_src", "vout_top_ahb",
-+ "vout_top_axi", "vout_top_hdmitx0_mclk",
-+ "i2stx0_bclk", "hdmitx0_pixelclk";
-+ resets = <&syscrg JH7110_SYSRST_VOUT_TOP_SRC>;
-+ #clock-cells = <1>;
-+ #reset-cells = <1>;
-+ power-domains = <&pwrc JH7110_PD_VOUT>;
-+ };
-+
-+ pcie0: pcie@2B000000 {
-+ compatible = "starfive,jh7110-pcie";
-+ #address-cells = <3>;
-+ #size-cells = <2>;
-+ #interrupt-cells = <1>;
-+ reg = <0x0 0x2B000000 0x0 0x1000000
-+ 0x9 0x40000000 0x0 0x10000000>;
-+ reg-names = "reg", "config";
-+ device_type = "pci";
-+ starfive,stg-syscon = <&stg_syscon 0xc0 0xc4 0x130 0x1b8>;
-+ bus-range = <0x0 0xff>;
-+ ranges = <0x82000000 0x0 0x30000000 0x0 0x30000000 0x0 0x08000000>,
-+ <0xc3000000 0x9 0x00000000 0x9 0x00000000 0x0 0x40000000>;
-+ interrupts = <56>;
-+ interrupt-parent = <&plic>;
-+ interrupt-map-mask = <0x0 0x0 0x0 0x7>;
-+ interrupt-map = <0x0 0x0 0x0 0x1 &pcie_intc0 0x1>,
-+ <0x0 0x0 0x0 0x2 &pcie_intc0 0x2>,
-+ <0x0 0x0 0x0 0x3 &pcie_intc0 0x3>,
-+ <0x0 0x0 0x0 0x4 &pcie_intc0 0x4>;
-+ msi-parent = <&pcie0>;
-+ msi-controller;
-+ clocks = <&syscrg JH7110_SYSCLK_NOC_BUS_STG_AXI>,
-+ <&stgcrg JH7110_STGCLK_PCIE0_TL>,
-+ <&stgcrg JH7110_STGCLK_PCIE0_AXI_MST0>,
-+ <&stgcrg JH7110_STGCLK_PCIE0_APB>;
-+ clock-names = "noc", "tl", "axi_mst0", "apb";
-+ resets = <&stgcrg JH7110_STGRST_PCIE0_AXI_MST0>,
-+ <&stgcrg JH7110_STGRST_PCIE0_AXI_SLV0>,
-+ <&stgcrg JH7110_STGRST_PCIE0_AXI_SLV>,
-+ <&stgcrg JH7110_STGRST_PCIE0_BRG>,
-+ <&stgcrg JH7110_STGRST_PCIE0_CORE>,
-+ <&stgcrg JH7110_STGRST_PCIE0_APB>;
-+ reset-names = "mst0", "slv0", "slv", "brg",
-+ "core", "apb";
-+ status = "disabled";
-+
-+ pcie_intc0: interrupt-controller {
-+ #address-cells = <0>;
-+ #interrupt-cells = <1>;
-+ interrupt-controller;
-+ };
-+ };
-+
-+ pcie1: pcie@2C000000 {
-+ compatible = "starfive,jh7110-pcie";
-+ #address-cells = <3>;
-+ #size-cells = <2>;
-+ #interrupt-cells = <1>;
-+ reg = <0x0 0x2C000000 0x0 0x1000000
-+ 0x9 0xc0000000 0x0 0x10000000>;
-+ reg-names = "reg", "config";
-+ device_type = "pci";
-+ starfive,stg-syscon = <&stg_syscon 0x270 0x274 0x2e0 0x368>;
-+ bus-range = <0x0 0xff>;
-+ ranges = <0x82000000 0x0 0x38000000 0x0 0x38000000 0x0 0x08000000>,
-+ <0xc3000000 0x9 0x80000000 0x9 0x80000000 0x0 0x40000000>;
-+ interrupts = <57>;
-+ interrupt-parent = <&plic>;
-+ interrupt-map-mask = <0x0 0x0 0x0 0x7>;
-+ interrupt-map = <0x0 0x0 0x0 0x1 &pcie_intc1 0x1>,
-+ <0x0 0x0 0x0 0x2 &pcie_intc1 0x2>,
-+ <0x0 0x0 0x0 0x3 &pcie_intc1 0x3>,
-+ <0x0 0x0 0x0 0x4 &pcie_intc1 0x4>;
-+ msi-parent = <&pcie1>;
-+ msi-controller;
-+ clocks = <&syscrg JH7110_SYSCLK_NOC_BUS_STG_AXI>,
-+ <&stgcrg JH7110_STGCLK_PCIE1_TL>,
-+ <&stgcrg JH7110_STGCLK_PCIE1_AXI_MST0>,
-+ <&stgcrg JH7110_STGCLK_PCIE1_APB>;
-+ clock-names = "noc", "tl", "axi_mst0", "apb";
-+ resets = <&stgcrg JH7110_STGRST_PCIE1_AXI_MST0>,
-+ <&stgcrg JH7110_STGRST_PCIE1_AXI_SLV0>,
-+ <&stgcrg JH7110_STGRST_PCIE1_AXI_SLV>,
-+ <&stgcrg JH7110_STGRST_PCIE1_BRG>,
-+ <&stgcrg JH7110_STGRST_PCIE1_CORE>,
-+ <&stgcrg JH7110_STGRST_PCIE1_APB>;
-+ reset-names = "mst0", "slv0", "slv", "brg",
-+ "core", "apb";
-+ status = "disabled";
-+
-+ pcie_intc1: interrupt-controller {
-+ #address-cells = <0>;
-+ #interrupt-cells = <1>;
-+ interrupt-controller;
-+ };
-+ };
- };
- };
diff --git a/target/linux/starfive/patches-6.1/0099-update-jh7110_defconfig-for-test.patch b/target/linux/starfive/patches-6.1/0099-update-jh7110_defconfig-for-test.patch
deleted file mode 100644
index d63efb93dd..0000000000
--- a/target/linux/starfive/patches-6.1/0099-update-jh7110_defconfig-for-test.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From d91e8a78ce8d6a1f60a3f5c16b4f7c013ba40257 Mon Sep 17 00:00:00 2001
-From: "shanlong.li" <shanlong.li@starfivetech.com>
-Date: Wed, 31 May 2023 01:56:22 -0700
-Subject: [PATCH 099/122] update jh7110_defconfig for test
-
-Signed-off-by: shanlong.li <shanlong.li@starfivetech.com>
----
- arch/riscv/configs/jh7110_defconfig | 15 ++++++++++++++-
- 1 file changed, 14 insertions(+), 1 deletion(-)
-
---- a/arch/riscv/configs/jh7110_defconfig
-+++ b/arch/riscv/configs/jh7110_defconfig
-@@ -106,7 +106,6 @@ CONFIG_MMC=y
- # CONFIG_PWRSEQ_SIMPLE is not set
- CONFIG_MMC_DW=y
- # CONFIG_VIRTIO_MENU is not set
--CONFIG_CLK_STARFIVE_JH7110_AON=y
- # CONFIG_VHOST_MENU is not set
- # CONFIG_IOMMU_SUPPORT is not set
- CONFIG_BTRFS_FS=y
-@@ -160,6 +159,19 @@ CONFIG_PCI=y
- CONFIG_USB_CDNS3_STARFIVE=y
- CONFIG_PHY_STARFIVE_JH7110_PCIE=y
- CONFIG_PHY_STARFIVE_JH7110_USB=y
-+CONFIG_USB_XHCI_HCD=y
-+CONFIG_USB_EHCI_HCD=y
-+CONFIG_USB_EHCI_HCD_PLATFORM=y
-+CONFIG_USB_OHCI_HCD=y
-+CONFIG_USB_OHCI_HCD_PLATFORM=y
-+CONFIG_SCSI=y
-+CONFIG_USB_STORAGE=y
-+CONFIG_USB_UAS=y
-+CONFIG_USB_CDNS3_GADGET=y
-+CONFIG_USB_CDNS3_HOST=y
-+CONFIG_USB_GADGET=y
-+CONFIG_USB_CONFIGFS=y
-+CONFIG_USB_CONFIGFS_F_FS=y
- CONFIG_USB_CDNS_SUPPORT=y
- CONFIG_USB_CDNS3=y
- CONFIG_USB=y
-@@ -177,6 +189,7 @@ CONFIG_CRYPTO_HW=y
- CONFIG_CRYPTO=y
- CONFIG_SND_SOC_JH7110_TDM=y
- CONFIG_SND_SOC_STARFIVE=y
-+CONFIG_SND_SIMPLE_CARD=y
- CONFIG_SND_SOC=y
- CONFIG_SND=y
- CONFIG_SOUND=y
diff --git a/target/linux/starfive/patches-6.1/0100-Add-readme.patch b/target/linux/starfive/patches-6.1/0100-Add-readme.patch
deleted file mode 100644
index 82db368796..0000000000
--- a/target/linux/starfive/patches-6.1/0100-Add-readme.patch
+++ /dev/null
@@ -1,75 +0,0 @@
-From 13c570f2350f59a7994c26a51f749a50fa9b4726 Mon Sep 17 00:00:00 2001
-From: Hal Feng <87058983+hal-feng@users.noreply.github.com>
-Date: Tue, 20 Dec 2022 16:18:35 +0800
-Subject: [PATCH 100/122] Add readme
-
----
- README.md | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 62 insertions(+)
- create mode 100644 README.md
-
---- /dev/null
-+++ b/README.md
-@@ -0,0 +1,62 @@
-+## JH7110 Upstream Status ##
-+
-+To get the latest status of each upstreaming patch series, please visit
-+our RVspace.
-+
-+https://rvspace.org/en/project/JH7110_Upstream_Plan
-+
-+## Build Instructions ##
-+
-+1. Configure Kconfig options
-+
-+```shell
-+# Use default selections
-+make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- defconfig
-+```
-+
-+or
-+
-+```shell
-+# Select options manually
-+make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- nconfig
-+```
-+
-+To boot up the VisionFive 2 board, please make sure **SOC_STARFIVE**,
-+**CLK_STARFIVE_JH7110_SYS**, **PINCTRL_STARFIVE_JH7110_SYS**,
-+**SERIAL_8250_DW** are selected.
-+> If you need MMC and GMAC drivers, you should also select
-+**MMC_DW_STARFIVE** and **DWMAC_STARFIVE**.
-+
-+2. Build
-+```shell
-+make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu-
-+```
-+
-+## How to Run on VisionFive 2 Board via Network ##
-+
-+1. Power on, enter u-boot and set enviroment parameters
-+```
-+setenv fdt_high 0xffffffffffffffff; setenv initrd_high 0xffffffffffffffff;
-+setenv scriptaddr 0x88100000; setenv script_offset_f 0x1fff000; setenv script_size_f 0x1000;
-+setenv kernel_addr_r 0x84000000; setenv kernel_comp_addr_r 0x90000000; setenv kernel_comp_size 0x10000000;
-+setenv fdt_addr_r 0x88000000; setenv ramdisk_addr_r 0x88300000;
-+```
-+2. Set IP addresses for the board and your tftp server
-+```
-+setenv serverip 192.168.w.x; setenv gatewayip 192.168.w.y; setenv ipaddr 192.168.w.z; setenv hostname starfive; setenv netdev eth0;
-+```
-+3. Upload dtb, image and file system to DDR from your tftp server
-+```
-+tftpboot ${fdt_addr_r} jh7110-starfive-visionfive-2-v1.3b.dtb; tftpboot ${kernel_addr_r} Image.gz; tftpboot ${ramdisk_addr_r} initramfs.cpio.gz;
-+```
-+> If your VisionFive 2 is v1.2A, you should upload jh7110-starfive-visionfive-2-v1.2a.dtb instead.
-+4. Load and boot the kernel
-+```
-+booti ${kernel_addr_r} ${ramdisk_addr_r}:${filesize} ${fdt_addr_r};
-+```
-+When you see the message "buildroot login:", the launch was successful.
-+You can just input the following accout and password, then continue.
-+```
-+buildroot login: root
-+Password: starfive
-+```
diff --git a/target/linux/starfive/patches-6.1/0101-dt-bindings-rng-Add-StarFive-TRNG-module.patch b/target/linux/starfive/patches-6.1/0101-dt-bindings-rng-Add-StarFive-TRNG-module.patch
deleted file mode 100644
index 60cb6cc433..0000000000
--- a/target/linux/starfive/patches-6.1/0101-dt-bindings-rng-Add-StarFive-TRNG-module.patch
+++ /dev/null
@@ -1,76 +0,0 @@
-From 0b99a4626c7e148df128c6a8cb686d500431189b Mon Sep 17 00:00:00 2001
-From: Jia Jie Ho <jiajie.ho@starfivetech.com>
-Date: Tue, 17 Jan 2023 09:54:43 +0800
-Subject: [PATCH 101/122] dt-bindings: rng: Add StarFive TRNG module
-
-Add documentation to describe Starfive true random number generator
-module.
-
-Co-developed-by: Jenny Zhang <jenny.zhang@starfivetech.com>
-Signed-off-by: Jenny Zhang <jenny.zhang@starfivetech.com>
-Signed-off-by: Jia Jie Ho <jiajie.ho@starfivetech.com>
-Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
----
- .../bindings/rng/starfive,jh7110-trng.yaml | 55 +++++++++++++++++++
- 1 file changed, 55 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/rng/starfive,jh7110-trng.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/rng/starfive,jh7110-trng.yaml
-@@ -0,0 +1,55 @@
-+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/rng/starfive,jh7110-trng.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: StarFive SoC TRNG Module
-+
-+maintainers:
-+ - Jia Jie Ho <jiajie.ho@starfivetech.com>
-+
-+properties:
-+ compatible:
-+ const: starfive,jh7110-trng
-+
-+ reg:
-+ maxItems: 1
-+
-+ clocks:
-+ items:
-+ - description: Hardware reference clock
-+ - description: AHB reference clock
-+
-+ clock-names:
-+ items:
-+ - const: hclk
-+ - const: ahb
-+
-+ resets:
-+ maxItems: 1
-+
-+ interrupts:
-+ maxItems: 1
-+
-+required:
-+ - compatible
-+ - reg
-+ - clocks
-+ - clock-names
-+ - resets
-+ - interrupts
-+
-+additionalProperties: false
-+
-+examples:
-+ - |
-+ rng: rng@1600C000 {
-+ compatible = "starfive,jh7110-trng";
-+ reg = <0x1600C000 0x4000>;
-+ clocks = <&clk 15>, <&clk 16>;
-+ clock-names = "hclk", "ahb";
-+ resets = <&reset 3>;
-+ interrupts = <30>;
-+ };
-+...
diff --git a/target/linux/starfive/patches-6.1/0102-hwrng-starfive-Add-TRNG-driver-for-StarFive-SoC.patch b/target/linux/starfive/patches-6.1/0102-hwrng-starfive-Add-TRNG-driver-for-StarFive-SoC.patch
deleted file mode 100644
index 1ab18838e6..0000000000
--- a/target/linux/starfive/patches-6.1/0102-hwrng-starfive-Add-TRNG-driver-for-StarFive-SoC.patch
+++ /dev/null
@@ -1,457 +0,0 @@
-From 99a7ca1d1320288efc5b4532ce4ea637d622aa00 Mon Sep 17 00:00:00 2001
-From: Jia Jie Ho <jiajie.ho@starfivetech.com>
-Date: Tue, 17 Jan 2023 09:54:44 +0800
-Subject: [PATCH 102/122] hwrng: starfive - Add TRNG driver for StarFive SoC
-
-This adds driver support for the hardware random number generator in
-Starfive SoCs and adds StarFive TRNG entry to MAINTAINERS.
-
-Co-developed-by: Jenny Zhang <jenny.zhang@starfivetech.com>
-Signed-off-by: Jenny Zhang <jenny.zhang@starfivetech.com>
-Signed-off-by: Jia Jie Ho <jiajie.ho@starfivetech.com>
----
- MAINTAINERS | 6 +
- drivers/char/hw_random/Kconfig | 11 +
- drivers/char/hw_random/Makefile | 1 +
- drivers/char/hw_random/jh7110-trng.c | 393 +++++++++++++++++++++++++++
- 4 files changed, 411 insertions(+)
- create mode 100644 drivers/char/hw_random/jh7110-trng.c
-
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -19716,6 +19716,12 @@ F: Documentation/devicetree/bindings/pow
- F: drivers/soc/starfive/jh71xx_pmu.c
- F: include/dt-bindings/power/starfive,jh7110-pmu.h
-
-+STARFIVE TRNG DRIVER
-+M: Jia Jie Ho <jiajie.ho@starfivetech.com>
-+S: Supported
-+F: Documentation/devicetree/bindings/rng/starfive*
-+F: drivers/char/hw_random/starfive-trng.c
-+
- STATIC BRANCH/CALL
- M: Peter Zijlstra <peterz@infradead.org>
- M: Josh Poimboeuf <jpoimboe@kernel.org>
---- a/drivers/char/hw_random/Kconfig
-+++ b/drivers/char/hw_random/Kconfig
-@@ -549,6 +549,17 @@ config HW_RANDOM_CN10K
- To compile this driver as a module, choose M here.
- The module will be called cn10k_rng. If unsure, say Y.
-
-+config HW_RANDOM_JH7110
-+ tristate "StarFive JH7110 Random Number Generator support"
-+ depends on SOC_STARFIVE
-+ depends on HW_RANDOM
-+ help
-+ This driver provides support for the True Random Number
-+ Generator in StarFive JH7110 SoCs.
-+
-+ To compile this driver as a module, choose M here.
-+ The module will be called jh7110-trng.
-+
- endif # HW_RANDOM
-
- config UML_RANDOM
---- a/drivers/char/hw_random/Makefile
-+++ b/drivers/char/hw_random/Makefile
-@@ -47,3 +47,4 @@ obj-$(CONFIG_HW_RANDOM_XIPHERA) += xiphe
- obj-$(CONFIG_HW_RANDOM_ARM_SMCCC_TRNG) += arm_smccc_trng.o
- obj-$(CONFIG_HW_RANDOM_CN10K) += cn10k-rng.o
- obj-$(CONFIG_HW_RANDOM_POLARFIRE_SOC) += mpfs-rng.o
-+obj-$(CONFIG_HW_RANDOM_JH7110) += jh7110-trng.o
---- /dev/null
-+++ b/drivers/char/hw_random/jh7110-trng.c
-@@ -0,0 +1,393 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * TRNG driver for the StarFive JH7110 SoC
-+ *
-+ * Copyright (C) 2022 StarFive Technology Co.
-+ */
-+
-+#include <linux/clk.h>
-+#include <linux/completion.h>
-+#include <linux/delay.h>
-+#include <linux/err.h>
-+#include <linux/hw_random.h>
-+#include <linux/interrupt.h>
-+#include <linux/io.h>
-+#include <linux/iopoll.h>
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/platform_device.h>
-+#include <linux/pm_runtime.h>
-+#include <linux/random.h>
-+#include <linux/reset.h>
-+
-+/* trng register offset */
-+#define STARFIVE_CTRL 0x00
-+#define STARFIVE_STAT 0x04
-+#define STARFIVE_MODE 0x08
-+#define STARFIVE_SMODE 0x0C
-+#define STARFIVE_IE 0x10
-+#define STARFIVE_ISTAT 0x14
-+#define STARFIVE_RAND0 0x20
-+#define STARFIVE_RAND1 0x24
-+#define STARFIVE_RAND2 0x28
-+#define STARFIVE_RAND3 0x2C
-+#define STARFIVE_RAND4 0x30
-+#define STARFIVE_RAND5 0x34
-+#define STARFIVE_RAND6 0x38
-+#define STARFIVE_RAND7 0x3C
-+#define STARFIVE_AUTO_RQSTS 0x60
-+#define STARFIVE_AUTO_AGE 0x64
-+
-+/* CTRL CMD */
-+#define STARFIVE_CTRL_EXEC_NOP 0x0
-+#define STARFIVE_CTRL_GENE_RANDNUM 0x1
-+#define STARFIVE_CTRL_EXEC_RANDRESEED 0x2
-+
-+/* STAT */
-+#define STARFIVE_STAT_NONCE_MODE BIT(2)
-+#define STARFIVE_STAT_R256 BIT(3)
-+#define STARFIVE_STAT_MISSION_MODE BIT(8)
-+#define STARFIVE_STAT_SEEDED BIT(9)
-+#define STARFIVE_STAT_LAST_RESEED(x) ((x) << 16)
-+#define STARFIVE_STAT_SRVC_RQST BIT(27)
-+#define STARFIVE_STAT_RAND_GENERATING BIT(30)
-+#define STARFIVE_STAT_RAND_SEEDING BIT(31)
-+
-+/* MODE */
-+#define STARFIVE_MODE_R256 BIT(3)
-+
-+/* SMODE */
-+#define STARFIVE_SMODE_NONCE_MODE BIT(2)
-+#define STARFIVE_SMODE_MISSION_MODE BIT(8)
-+#define STARFIVE_SMODE_MAX_REJECTS(x) ((x) << 16)
-+
-+/* IE */
-+#define STARFIVE_IE_RAND_RDY_EN BIT(0)
-+#define STARFIVE_IE_SEED_DONE_EN BIT(1)
-+#define STARFIVE_IE_LFSR_LOCKUP_EN BIT(4)
-+#define STARFIVE_IE_GLBL_EN BIT(31)
-+
-+#define STARFIVE_IE_ALL (STARFIVE_IE_GLBL_EN | \
-+ STARFIVE_IE_RAND_RDY_EN | \
-+ STARFIVE_IE_SEED_DONE_EN | \
-+ STARFIVE_IE_LFSR_LOCKUP_EN)
-+
-+/* ISTAT */
-+#define STARFIVE_ISTAT_RAND_RDY BIT(0)
-+#define STARFIVE_ISTAT_SEED_DONE BIT(1)
-+#define STARFIVE_ISTAT_LFSR_LOCKUP BIT(4)
-+
-+#define STARFIVE_RAND_LEN sizeof(u32)
-+
-+#define to_trng(p) container_of(p, struct starfive_trng, rng)
-+
-+enum reseed {
-+ RANDOM_RESEED,
-+ NONCE_RESEED,
-+};
-+
-+enum mode {
-+ PRNG_128BIT,
-+ PRNG_256BIT,
-+};
-+
-+struct starfive_trng {
-+ struct device *dev;
-+ void __iomem *base;
-+ struct clk *hclk;
-+ struct clk *ahb;
-+ struct reset_control *rst;
-+ struct hwrng rng;
-+ struct completion random_done;
-+ struct completion reseed_done;
-+ u32 mode;
-+ u32 mission;
-+ u32 reseed;
-+ /* protects against concurrent write to ctrl register */
-+ spinlock_t write_lock;
-+};
-+
-+static u16 autoreq;
-+module_param(autoreq, ushort, 0);
-+MODULE_PARM_DESC(autoreq, "Auto-reseeding after random number requests by host reaches specified counter:\n"
-+ " 0 - disable counter\n"
-+ " other - reload value for internal counter");
-+
-+static u16 autoage;
-+module_param(autoage, ushort, 0);
-+MODULE_PARM_DESC(autoage, "Auto-reseeding after specified timer countdowns to 0:\n"
-+ " 0 - disable timer\n"
-+ " other - reload value for internal timer");
-+
-+static inline int starfive_trng_wait_idle(struct starfive_trng *trng)
-+{
-+ u32 stat;
-+
-+ return readl_relaxed_poll_timeout(trng->base + STARFIVE_STAT, stat,
-+ !(stat & (STARFIVE_STAT_RAND_GENERATING |
-+ STARFIVE_STAT_RAND_SEEDING)),
-+ 10, 100000);
-+}
-+
-+static inline void starfive_trng_irq_mask_clear(struct starfive_trng *trng)
-+{
-+ /* clear register: ISTAT */
-+ u32 data = readl(trng->base + STARFIVE_ISTAT);
-+
-+ writel(data, trng->base + STARFIVE_ISTAT);
-+}
-+
-+static int starfive_trng_cmd(struct starfive_trng *trng, u32 cmd, bool wait)
-+{
-+ int wait_time = 1000;
-+
-+ /* allow up to 40 us for wait == 0 */
-+ if (!wait)
-+ wait_time = 40;
-+
-+ switch (cmd) {
-+ case STARFIVE_CTRL_GENE_RANDNUM:
-+ reinit_completion(&trng->random_done);
-+ spin_lock_irq(&trng->write_lock);
-+ writel(cmd, trng->base + STARFIVE_CTRL);
-+ spin_unlock_irq(&trng->write_lock);
-+ if (!wait_for_completion_timeout(&trng->random_done, usecs_to_jiffies(wait_time)))
-+ return -ETIMEDOUT;
-+ break;
-+ case STARFIVE_CTRL_EXEC_RANDRESEED:
-+ reinit_completion(&trng->reseed_done);
-+ spin_lock_irq(&trng->write_lock);
-+ writel(cmd, trng->base + STARFIVE_CTRL);
-+ spin_unlock_irq(&trng->write_lock);
-+ if (!wait_for_completion_timeout(&trng->reseed_done, usecs_to_jiffies(wait_time)))
-+ return -ETIMEDOUT;
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ return 0;
-+}
-+
-+static int starfive_trng_init(struct hwrng *rng)
-+{
-+ struct starfive_trng *trng = to_trng(rng);
-+ u32 mode, intr = 0;
-+
-+ /* setup Auto Request/Age register */
-+ writel(autoage, trng->base + STARFIVE_AUTO_AGE);
-+ writel(autoreq, trng->base + STARFIVE_AUTO_RQSTS);
-+
-+ /* clear register: ISTAT */
-+ starfive_trng_irq_mask_clear(trng);
-+
-+ intr |= STARFIVE_IE_ALL;
-+ writel(intr, trng->base + STARFIVE_IE);
-+
-+ mode = readl(trng->base + STARFIVE_MODE);
-+
-+ switch (trng->mode) {
-+ case PRNG_128BIT:
-+ mode &= ~STARFIVE_MODE_R256;
-+ break;
-+ case PRNG_256BIT:
-+ mode |= STARFIVE_MODE_R256;
-+ break;
-+ default:
-+ mode |= STARFIVE_MODE_R256;
-+ break;
-+ }
-+
-+ writel(mode, trng->base + STARFIVE_MODE);
-+
-+ return starfive_trng_cmd(trng, STARFIVE_CTRL_EXEC_RANDRESEED, 1);
-+}
-+
-+static irqreturn_t starfive_trng_irq(int irq, void *priv)
-+{
-+ u32 status;
-+ struct starfive_trng *trng = (struct starfive_trng *)priv;
-+
-+ status = readl(trng->base + STARFIVE_ISTAT);
-+ if (status & STARFIVE_ISTAT_RAND_RDY) {
-+ writel(STARFIVE_ISTAT_RAND_RDY, trng->base + STARFIVE_ISTAT);
-+ complete(&trng->random_done);
-+ }
-+
-+ if (status & STARFIVE_ISTAT_SEED_DONE) {
-+ writel(STARFIVE_ISTAT_SEED_DONE, trng->base + STARFIVE_ISTAT);
-+ complete(&trng->reseed_done);
-+ }
-+
-+ if (status & STARFIVE_ISTAT_LFSR_LOCKUP) {
-+ writel(STARFIVE_ISTAT_LFSR_LOCKUP, trng->base + STARFIVE_ISTAT);
-+ /* SEU occurred, reseeding required*/
-+ spin_lock(&trng->write_lock);
-+ writel(STARFIVE_CTRL_EXEC_RANDRESEED, trng->base + STARFIVE_CTRL);
-+ spin_unlock(&trng->write_lock);
-+ }
-+
-+ return IRQ_HANDLED;
-+}
-+
-+static void starfive_trng_cleanup(struct hwrng *rng)
-+{
-+ struct starfive_trng *trng = to_trng(rng);
-+
-+ writel(0, trng->base + STARFIVE_CTRL);
-+
-+ reset_control_assert(trng->rst);
-+ clk_disable_unprepare(trng->hclk);
-+ clk_disable_unprepare(trng->ahb);
-+}
-+
-+static int starfive_trng_read(struct hwrng *rng, void *buf, size_t max, bool wait)
-+{
-+ struct starfive_trng *trng = to_trng(rng);
-+ int ret;
-+
-+ pm_runtime_get_sync(trng->dev);
-+
-+ if (trng->mode == PRNG_256BIT)
-+ max = min_t(size_t, max, (STARFIVE_RAND_LEN * 8));
-+ else
-+ max = min_t(size_t, max, (STARFIVE_RAND_LEN * 4));
-+
-+ if (wait) {
-+ ret = starfive_trng_wait_idle(trng);
-+ if (ret)
-+ return -ETIMEDOUT;
-+ }
-+
-+ ret = starfive_trng_cmd(trng, STARFIVE_CTRL_GENE_RANDNUM, wait);
-+ if (ret)
-+ return ret;
-+
-+ memcpy_fromio(buf, trng->base + STARFIVE_RAND0, max);
-+
-+ pm_runtime_put_sync_autosuspend(trng->dev);
-+
-+ return max;
-+}
-+
-+static int starfive_trng_probe(struct platform_device *pdev)
-+{
-+ int ret;
-+ int irq;
-+ struct starfive_trng *trng;
-+
-+ trng = devm_kzalloc(&pdev->dev, sizeof(*trng), GFP_KERNEL);
-+ if (!trng)
-+ return -ENOMEM;
-+
-+ platform_set_drvdata(pdev, trng);
-+ trng->dev = &pdev->dev;
-+
-+ trng->base = devm_platform_ioremap_resource(pdev, 0);
-+ if (IS_ERR(trng->base))
-+ return dev_err_probe(&pdev->dev, PTR_ERR(trng->base),
-+ "Error remapping memory for platform device.\n");
-+
-+ irq = platform_get_irq(pdev, 0);
-+ if (irq < 0)
-+ return irq;
-+
-+ init_completion(&trng->random_done);
-+ init_completion(&trng->reseed_done);
-+ spin_lock_init(&trng->write_lock);
-+
-+ ret = devm_request_irq(&pdev->dev, irq, starfive_trng_irq, 0, pdev->name,
-+ (void *)trng);
-+ if (ret)
-+ return dev_err_probe(&pdev->dev, irq,
-+ "Failed to register interrupt handler\n");
-+
-+ trng->hclk = devm_clk_get(&pdev->dev, "hclk");
-+ if (IS_ERR(trng->hclk))
-+ return dev_err_probe(&pdev->dev, PTR_ERR(trng->hclk),
-+ "Error getting hardware reference clock\n");
-+
-+ trng->ahb = devm_clk_get(&pdev->dev, "ahb");
-+ if (IS_ERR(trng->ahb))
-+ return dev_err_probe(&pdev->dev, PTR_ERR(trng->ahb),
-+ "Error getting ahb reference clock\n");
-+
-+ trng->rst = devm_reset_control_get_shared(&pdev->dev, NULL);
-+ if (IS_ERR(trng->rst))
-+ return dev_err_probe(&pdev->dev, PTR_ERR(trng->rst),
-+ "Error getting hardware reset line\n");
-+
-+ clk_prepare_enable(trng->hclk);
-+ clk_prepare_enable(trng->ahb);
-+ reset_control_deassert(trng->rst);
-+
-+ trng->rng.name = dev_driver_string(&pdev->dev);
-+ trng->rng.init = starfive_trng_init;
-+ trng->rng.cleanup = starfive_trng_cleanup;
-+ trng->rng.read = starfive_trng_read;
-+
-+ trng->mode = PRNG_256BIT;
-+ trng->mission = 1;
-+ trng->reseed = RANDOM_RESEED;
-+
-+ pm_runtime_use_autosuspend(&pdev->dev);
-+ pm_runtime_set_autosuspend_delay(&pdev->dev, 100);
-+ pm_runtime_enable(&pdev->dev);
-+
-+ ret = devm_hwrng_register(&pdev->dev, &trng->rng);
-+ if (ret) {
-+ pm_runtime_disable(&pdev->dev);
-+
-+ reset_control_assert(trng->rst);
-+ clk_disable_unprepare(trng->ahb);
-+ clk_disable_unprepare(trng->hclk);
-+
-+ return dev_err_probe(&pdev->dev, ret, "Failed to register hwrng\n");
-+ }
-+
-+ return 0;
-+}
-+
-+static int __maybe_unused starfive_trng_suspend(struct device *dev)
-+{
-+ struct starfive_trng *trng = dev_get_drvdata(dev);
-+
-+ clk_disable_unprepare(trng->hclk);
-+ clk_disable_unprepare(trng->ahb);
-+
-+ return 0;
-+}
-+
-+static int __maybe_unused starfive_trng_resume(struct device *dev)
-+{
-+ struct starfive_trng *trng = dev_get_drvdata(dev);
-+
-+ clk_prepare_enable(trng->hclk);
-+ clk_prepare_enable(trng->ahb);
-+
-+ return 0;
-+}
-+
-+static DEFINE_SIMPLE_DEV_PM_OPS(starfive_trng_pm_ops, starfive_trng_suspend,
-+ starfive_trng_resume);
-+
-+static const struct of_device_id trng_dt_ids[] __maybe_unused = {
-+ { .compatible = "starfive,jh7110-trng" },
-+ { }
-+};
-+MODULE_DEVICE_TABLE(of, trng_dt_ids);
-+
-+static struct platform_driver starfive_trng_driver = {
-+ .probe = starfive_trng_probe,
-+ .driver = {
-+ .name = "jh7110-trng",
-+ .pm = &starfive_trng_pm_ops,
-+ .of_match_table = of_match_ptr(trng_dt_ids),
-+ },
-+};
-+
-+module_platform_driver(starfive_trng_driver);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_DESCRIPTION("StarFive True Random Number Generator");
diff --git a/target/linux/starfive/patches-6.1/0103-hwrng-starfive-Enable-compile-testing.patch b/target/linux/starfive/patches-6.1/0103-hwrng-starfive-Enable-compile-testing.patch
deleted file mode 100644
index 39b4bc6ad9..0000000000
--- a/target/linux/starfive/patches-6.1/0103-hwrng-starfive-Enable-compile-testing.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From 4b02d00911c2e6bd31d8160b0337174dd55dc644 Mon Sep 17 00:00:00 2001
-From: Herbert Xu <herbert@gondor.apana.org.au>
-Date: Fri, 27 Jan 2023 19:03:21 +0800
-Subject: [PATCH 103/122] hwrng: starfive - Enable compile testing
-
-Enable compile testing for jh7110. Also remove the dependency on
-HW_RANDOM.
-
-Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
-Reviewed-by: Jia Jie Ho <jiajie.ho@starfivetech.com>
-Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
----
- drivers/char/hw_random/Kconfig | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
---- a/drivers/char/hw_random/Kconfig
-+++ b/drivers/char/hw_random/Kconfig
-@@ -551,8 +551,7 @@ config HW_RANDOM_CN10K
-
- config HW_RANDOM_JH7110
- tristate "StarFive JH7110 Random Number Generator support"
-- depends on SOC_STARFIVE
-- depends on HW_RANDOM
-+ depends on SOC_STARFIVE || COMPILE_TEST
- help
- This driver provides support for the True Random Number
- Generator in StarFive JH7110 SoCs.
diff --git a/target/linux/starfive/patches-6.1/0104-dt-bindings-watchdog-Add-watchdog-for-StarFive-JH710.patch b/target/linux/starfive/patches-6.1/0104-dt-bindings-watchdog-Add-watchdog-for-StarFive-JH710.patch
deleted file mode 100644
index f68232f035..0000000000
--- a/target/linux/starfive/patches-6.1/0104-dt-bindings-watchdog-Add-watchdog-for-StarFive-JH710.patch
+++ /dev/null
@@ -1,91 +0,0 @@
-From 8559b2db6aecbee62cf9e02c17349379d72edcfb Mon Sep 17 00:00:00 2001
-From: Xingyu Wu <xingyu.wu@starfivetech.com>
-Date: Tue, 14 Mar 2023 21:24:35 +0800
-Subject: [PATCH 104/122] dt-bindings: watchdog: Add watchdog for StarFive
- JH7100 and JH7110
-
-Add bindings to describe the watchdog for the StarFive JH7100/JH7110 SoC.
-And Use JH7100 as first StarFive SoC with watchdog.
-
-Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
-Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Reviewed-by: Guenter Roeck <linux@roeck-us.net>
----
- .../watchdog/starfive,jh7100-wdt.yaml | 71 +++++++++++++++++++
- 1 file changed, 71 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/watchdog/starfive,jh7100-wdt.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/watchdog/starfive,jh7100-wdt.yaml
-@@ -0,0 +1,71 @@
-+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/watchdog/starfive,jh7100-wdt.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: StarFive Watchdog for JH7100 and JH7110 SoC
-+
-+maintainers:
-+ - Xingyu Wu <xingyu.wu@starfivetech.com>
-+ - Samin Guo <samin.guo@starfivetech.com>
-+
-+description:
-+ The JH7100 and JH7110 watchdog both are 32 bit counters. JH7100 watchdog
-+ has only one timeout phase and reboots. And JH7110 watchdog has two
-+ timeout phases. At the first phase, the signal of watchdog interrupt
-+ output(WDOGINT) will rise when counter is 0. The counter will reload
-+ the timeout value. And then, if counter decreases to 0 again and WDOGINT
-+ isn't cleared, the watchdog will reset the system unless the watchdog
-+ reset is disabled.
-+
-+allOf:
-+ - $ref: watchdog.yaml#
-+
-+properties:
-+ compatible:
-+ enum:
-+ - starfive,jh7100-wdt
-+ - starfive,jh7110-wdt
-+
-+ reg:
-+ maxItems: 1
-+
-+ interrupts:
-+ maxItems: 1
-+
-+ clocks:
-+ items:
-+ - description: APB clock
-+ - description: Core clock
-+
-+ clock-names:
-+ items:
-+ - const: apb
-+ - const: core
-+
-+ resets:
-+ items:
-+ - description: APB reset
-+ - description: Core reset
-+
-+required:
-+ - compatible
-+ - reg
-+ - clocks
-+ - clock-names
-+ - resets
-+
-+unevaluatedProperties: false
-+
-+examples:
-+ - |
-+ watchdog@12480000 {
-+ compatible = "starfive,jh7100-wdt";
-+ reg = <0x12480000 0x10000>;
-+ clocks = <&clk 171>,
-+ <&clk 172>;
-+ clock-names = "apb", "core";
-+ resets = <&rst 99>,
-+ <&rst 100>;
-+ };
diff --git a/target/linux/starfive/patches-6.1/0105-drivers-watchdog-Add-StarFive-Watchdog-driver.patch b/target/linux/starfive/patches-6.1/0105-drivers-watchdog-Add-StarFive-Watchdog-driver.patch
deleted file mode 100644
index d7113de0ec..0000000000
--- a/target/linux/starfive/patches-6.1/0105-drivers-watchdog-Add-StarFive-Watchdog-driver.patch
+++ /dev/null
@@ -1,675 +0,0 @@
-From e835861823130ae47665db5e8039a7097ede14e4 Mon Sep 17 00:00:00 2001
-From: Xingyu Wu <xingyu.wu@starfivetech.com>
-Date: Tue, 14 Mar 2023 21:24:36 +0800
-Subject: [PATCH 105/122] drivers: watchdog: Add StarFive Watchdog driver
-
-Add watchdog driver for the StarFive JH7100 and JH7110 SoC.
-
-Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
-Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
-Reviewed-by: Guenter Roeck <linux@roeck-us.net>
----
- MAINTAINERS | 7 +
- drivers/watchdog/Kconfig | 11 +
- drivers/watchdog/Makefile | 3 +
- drivers/watchdog/starfive-wdt.c | 606 ++++++++++++++++++++++++++++++++
- 4 files changed, 627 insertions(+)
- create mode 100644 drivers/watchdog/starfive-wdt.c
-
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -19722,6 +19722,13 @@ S: Supported
- F: Documentation/devicetree/bindings/rng/starfive*
- F: drivers/char/hw_random/starfive-trng.c
-
-+STARFIVE WATCHDOG DRIVER
-+M: Xingyu Wu <xingyu.wu@starfivetech.com>
-+M: Samin Guo <samin.guo@starfivetech.com>
-+S: Supported
-+F: Documentation/devicetree/bindings/watchdog/starfive*
-+F: drivers/watchdog/starfive-wdt.c
-+
- STATIC BRANCH/CALL
- M: Peter Zijlstra <peterz@infradead.org>
- M: Josh Poimboeuf <jpoimboe@kernel.org>
---- a/drivers/watchdog/Kconfig
-+++ b/drivers/watchdog/Kconfig
-@@ -1991,6 +1991,17 @@ config WATCHDOG_RTAS
- To compile this driver as a module, choose M here. The module
- will be called wdrtas.
-
-+# RISC-V Architecture
-+
-+config STARFIVE_WATCHDOG
-+ tristate "StarFive Watchdog support"
-+ depends on ARCH_STARFIVE || COMPILE_TEST
-+ select WATCHDOG_CORE
-+ default ARCH_STARFIVE
-+ help
-+ Say Y here to support the watchdog of StarFive JH7100 and JH7110
-+ SoC. This driver can also be built as a module if choose M.
-+
- # S390 Architecture
-
- config DIAG288_WATCHDOG
---- a/drivers/watchdog/Makefile
-+++ b/drivers/watchdog/Makefile
-@@ -191,6 +191,9 @@ obj-$(CONFIG_MEN_A21_WDT) += mena21_wdt.
- obj-$(CONFIG_PSERIES_WDT) += pseries-wdt.o
- obj-$(CONFIG_WATCHDOG_RTAS) += wdrtas.o
-
-+# RISC-V Architecture
-+obj-$(CONFIG_STARFIVE_WATCHDOG) += starfive-wdt.o
-+
- # S390 Architecture
- obj-$(CONFIG_DIAG288_WATCHDOG) += diag288_wdt.o
-
---- /dev/null
-+++ b/drivers/watchdog/starfive-wdt.c
-@@ -0,0 +1,606 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Starfive Watchdog driver
-+ *
-+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
-+ */
-+
-+#include <linux/clk.h>
-+#include <linux/iopoll.h>
-+#include <linux/module.h>
-+#include <linux/of_device.h>
-+#include <linux/pm_runtime.h>
-+#include <linux/reset.h>
-+#include <linux/watchdog.h>
-+
-+/* JH7100 Watchdog register define */
-+#define STARFIVE_WDT_JH7100_INTSTAUS 0x000
-+#define STARFIVE_WDT_JH7100_CONTROL 0x104
-+#define STARFIVE_WDT_JH7100_LOAD 0x108
-+#define STARFIVE_WDT_JH7100_EN 0x110
-+#define STARFIVE_WDT_JH7100_RELOAD 0x114 /* Write 0 or 1 to reload preset value */
-+#define STARFIVE_WDT_JH7100_VALUE 0x118
-+#define STARFIVE_WDT_JH7100_INTCLR 0x120 /*
-+ * [0]: Write 1 to clear interrupt
-+ * [1]: 1 mean clearing and 0 mean complete
-+ * [31:2]: reserved.
-+ */
-+#define STARFIVE_WDT_JH7100_LOCK 0x13c /* write 0x378f0765 to unlock */
-+
-+/* JH7110 Watchdog register define */
-+#define STARFIVE_WDT_JH7110_LOAD 0x000
-+#define STARFIVE_WDT_JH7110_VALUE 0x004
-+#define STARFIVE_WDT_JH7110_CONTROL 0x008 /*
-+ * [0]: reset enable;
-+ * [1]: interrupt enable && watchdog enable
-+ * [31:2]: reserved.
-+ */
-+#define STARFIVE_WDT_JH7110_INTCLR 0x00c /* clear intterupt and reload the counter */
-+#define STARFIVE_WDT_JH7110_IMS 0x014
-+#define STARFIVE_WDT_JH7110_LOCK 0xc00 /* write 0x1ACCE551 to unlock */
-+
-+/* WDOGCONTROL */
-+#define STARFIVE_WDT_ENABLE 0x1
-+#define STARFIVE_WDT_EN_SHIFT 0
-+#define STARFIVE_WDT_RESET_EN 0x1
-+#define STARFIVE_WDT_JH7100_RST_EN_SHIFT 0
-+#define STARFIVE_WDT_JH7110_RST_EN_SHIFT 1
-+
-+/* WDOGLOCK */
-+#define STARFIVE_WDT_JH7100_UNLOCK_KEY 0x378f0765
-+#define STARFIVE_WDT_JH7110_UNLOCK_KEY 0x1acce551
-+
-+/* WDOGINTCLR */
-+#define STARFIVE_WDT_INTCLR 0x1
-+#define STARFIVE_WDT_JH7100_INTCLR_AVA_SHIFT 1 /* Watchdog can clear interrupt when 0 */
-+
-+#define STARFIVE_WDT_MAXCNT 0xffffffff
-+#define STARFIVE_WDT_DEFAULT_TIME (15)
-+#define STARFIVE_WDT_DELAY_US 0
-+#define STARFIVE_WDT_TIMEOUT_US 10000
-+
-+/* module parameter */
-+#define STARFIVE_WDT_EARLY_ENA 0
-+
-+static bool nowayout = WATCHDOG_NOWAYOUT;
-+static int heartbeat;
-+static bool early_enable = STARFIVE_WDT_EARLY_ENA;
-+
-+module_param(heartbeat, int, 0);
-+module_param(early_enable, bool, 0);
-+module_param(nowayout, bool, 0);
-+
-+MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (default="
-+ __MODULE_STRING(STARFIVE_WDT_DEFAULT_TIME) ")");
-+MODULE_PARM_DESC(early_enable,
-+ "Watchdog is started at boot time if set to 1, default="
-+ __MODULE_STRING(STARFIVE_WDT_EARLY_ENA));
-+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
-+ __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
-+
-+struct starfive_wdt_variant {
-+ unsigned int control; /* Watchdog Control Resgister for reset enable */
-+ unsigned int load; /* Watchdog Load register */
-+ unsigned int reload; /* Watchdog Reload Control register */
-+ unsigned int enable; /* Watchdog Enable Register */
-+ unsigned int value; /* Watchdog Counter Value Register */
-+ unsigned int int_clr; /* Watchdog Interrupt Clear Register */
-+ unsigned int unlock; /* Watchdog Lock Register */
-+ unsigned int int_status; /* Watchdog Interrupt Status Register */
-+
-+ u32 unlock_key;
-+ char enrst_shift;
-+ char en_shift;
-+ bool intclr_check; /* whether need to check it before clearing interrupt */
-+ char intclr_ava_shift;
-+ bool double_timeout; /* The watchdog need twice timeout to reboot */
-+};
-+
-+struct starfive_wdt {
-+ struct watchdog_device wdd;
-+ spinlock_t lock; /* spinlock for register handling */
-+ void __iomem *base;
-+ struct clk *core_clk;
-+ struct clk *apb_clk;
-+ const struct starfive_wdt_variant *variant;
-+ unsigned long freq;
-+ u32 count; /* count of timeout */
-+ u32 reload; /* restore the count */
-+};
-+
-+/* Register layout and configuration for the JH7100 */
-+static const struct starfive_wdt_variant starfive_wdt_jh7100_variant = {
-+ .control = STARFIVE_WDT_JH7100_CONTROL,
-+ .load = STARFIVE_WDT_JH7100_LOAD,
-+ .reload = STARFIVE_WDT_JH7100_RELOAD,
-+ .enable = STARFIVE_WDT_JH7100_EN,
-+ .value = STARFIVE_WDT_JH7100_VALUE,
-+ .int_clr = STARFIVE_WDT_JH7100_INTCLR,
-+ .unlock = STARFIVE_WDT_JH7100_LOCK,
-+ .unlock_key = STARFIVE_WDT_JH7100_UNLOCK_KEY,
-+ .int_status = STARFIVE_WDT_JH7100_INTSTAUS,
-+ .enrst_shift = STARFIVE_WDT_JH7100_RST_EN_SHIFT,
-+ .en_shift = STARFIVE_WDT_EN_SHIFT,
-+ .intclr_check = true,
-+ .intclr_ava_shift = STARFIVE_WDT_JH7100_INTCLR_AVA_SHIFT,
-+ .double_timeout = false,
-+};
-+
-+/* Register layout and configuration for the JH7110 */
-+static const struct starfive_wdt_variant starfive_wdt_jh7110_variant = {
-+ .control = STARFIVE_WDT_JH7110_CONTROL,
-+ .load = STARFIVE_WDT_JH7110_LOAD,
-+ .enable = STARFIVE_WDT_JH7110_CONTROL,
-+ .value = STARFIVE_WDT_JH7110_VALUE,
-+ .int_clr = STARFIVE_WDT_JH7110_INTCLR,
-+ .unlock = STARFIVE_WDT_JH7110_LOCK,
-+ .unlock_key = STARFIVE_WDT_JH7110_UNLOCK_KEY,
-+ .int_status = STARFIVE_WDT_JH7110_IMS,
-+ .enrst_shift = STARFIVE_WDT_JH7110_RST_EN_SHIFT,
-+ .en_shift = STARFIVE_WDT_EN_SHIFT,
-+ .intclr_check = false,
-+ .double_timeout = true,
-+};
-+
-+static int starfive_wdt_enable_clock(struct starfive_wdt *wdt)
-+{
-+ int ret;
-+
-+ ret = clk_prepare_enable(wdt->apb_clk);
-+ if (ret)
-+ return dev_err_probe(wdt->wdd.parent, ret, "failed to enable apb clock\n");
-+
-+ ret = clk_prepare_enable(wdt->core_clk);
-+ if (ret)
-+ return dev_err_probe(wdt->wdd.parent, ret, "failed to enable core clock\n");
-+
-+ return 0;
-+}
-+
-+static void starfive_wdt_disable_clock(struct starfive_wdt *wdt)
-+{
-+ clk_disable_unprepare(wdt->core_clk);
-+ clk_disable_unprepare(wdt->apb_clk);
-+}
-+
-+static inline int starfive_wdt_get_clock(struct starfive_wdt *wdt)
-+{
-+ struct device *dev = wdt->wdd.parent;
-+
-+ wdt->apb_clk = devm_clk_get(dev, "apb");
-+ if (IS_ERR(wdt->apb_clk))
-+ return dev_err_probe(dev, PTR_ERR(wdt->apb_clk), "failed to get apb clock\n");
-+
-+ wdt->core_clk = devm_clk_get(dev, "core");
-+ if (IS_ERR(wdt->core_clk))
-+ return dev_err_probe(dev, PTR_ERR(wdt->core_clk), "failed to get core clock\n");
-+
-+ return 0;
-+}
-+
-+static inline int starfive_wdt_reset_init(struct device *dev)
-+{
-+ struct reset_control *rsts;
-+ int ret;
-+
-+ rsts = devm_reset_control_array_get_exclusive(dev);
-+ if (IS_ERR(rsts))
-+ return dev_err_probe(dev, PTR_ERR(rsts), "failed to get resets\n");
-+
-+ ret = reset_control_deassert(rsts);
-+ if (ret)
-+ return dev_err_probe(dev, ret, "failed to deassert resets\n");
-+
-+ return 0;
-+}
-+
-+static u32 starfive_wdt_ticks_to_sec(struct starfive_wdt *wdt, u32 ticks)
-+{
-+ return DIV_ROUND_CLOSEST(ticks, wdt->freq);
-+}
-+
-+/* Write unlock-key to unlock. Write other value to lock. */
-+static void starfive_wdt_unlock(struct starfive_wdt *wdt)
-+{
-+ spin_lock(&wdt->lock);
-+ writel(wdt->variant->unlock_key, wdt->base + wdt->variant->unlock);
-+}
-+
-+static void starfive_wdt_lock(struct starfive_wdt *wdt)
-+{
-+ writel(~wdt->variant->unlock_key, wdt->base + wdt->variant->unlock);
-+ spin_unlock(&wdt->lock);
-+}
-+
-+/* enable watchdog interrupt to reset/reboot */
-+static void starfive_wdt_enable_reset(struct starfive_wdt *wdt)
-+{
-+ u32 val;
-+
-+ val = readl(wdt->base + wdt->variant->control);
-+ val |= STARFIVE_WDT_RESET_EN << wdt->variant->enrst_shift;
-+ writel(val, wdt->base + wdt->variant->control);
-+}
-+
-+/* interrupt status whether has been raised from the counter */
-+static bool starfive_wdt_raise_irq_status(struct starfive_wdt *wdt)
-+{
-+ return !!readl(wdt->base + wdt->variant->int_status);
-+}
-+
-+/* waiting interrupt can be free to clear */
-+static int starfive_wdt_wait_int_free(struct starfive_wdt *wdt)
-+{
-+ u32 value;
-+
-+ return readl_poll_timeout_atomic(wdt->base + wdt->variant->int_clr, value,
-+ !(value & BIT(wdt->variant->intclr_ava_shift)),
-+ STARFIVE_WDT_DELAY_US, STARFIVE_WDT_TIMEOUT_US);
-+}
-+
-+/* clear interrupt signal before initialization or reload */
-+static int starfive_wdt_int_clr(struct starfive_wdt *wdt)
-+{
-+ int ret;
-+
-+ if (wdt->variant->intclr_check) {
-+ ret = starfive_wdt_wait_int_free(wdt);
-+ if (ret)
-+ return dev_err_probe(wdt->wdd.parent, ret,
-+ "watchdog is not ready to clear interrupt.\n");
-+ }
-+ writel(STARFIVE_WDT_INTCLR, wdt->base + wdt->variant->int_clr);
-+
-+ return 0;
-+}
-+
-+static inline void starfive_wdt_set_count(struct starfive_wdt *wdt, u32 val)
-+{
-+ writel(val, wdt->base + wdt->variant->load);
-+}
-+
-+static inline u32 starfive_wdt_get_count(struct starfive_wdt *wdt)
-+{
-+ return readl(wdt->base + wdt->variant->value);
-+}
-+
-+/* enable watchdog */
-+static inline void starfive_wdt_enable(struct starfive_wdt *wdt)
-+{
-+ u32 val;
-+
-+ val = readl(wdt->base + wdt->variant->enable);
-+ val |= STARFIVE_WDT_ENABLE << wdt->variant->en_shift;
-+ writel(val, wdt->base + wdt->variant->enable);
-+}
-+
-+/* disable watchdog */
-+static inline void starfive_wdt_disable(struct starfive_wdt *wdt)
-+{
-+ u32 val;
-+
-+ val = readl(wdt->base + wdt->variant->enable);
-+ val &= ~(STARFIVE_WDT_ENABLE << wdt->variant->en_shift);
-+ writel(val, wdt->base + wdt->variant->enable);
-+}
-+
-+static inline void starfive_wdt_set_reload_count(struct starfive_wdt *wdt, u32 count)
-+{
-+ starfive_wdt_set_count(wdt, count);
-+
-+ /* 7100 need set any value to reload register and could reload value to counter */
-+ if (wdt->variant->reload)
-+ writel(0x1, wdt->base + wdt->variant->reload);
-+}
-+
-+static unsigned int starfive_wdt_max_timeout(struct starfive_wdt *wdt)
-+{
-+ if (wdt->variant->double_timeout)
-+ return DIV_ROUND_UP(STARFIVE_WDT_MAXCNT, (wdt->freq / 2)) - 1;
-+
-+ return DIV_ROUND_UP(STARFIVE_WDT_MAXCNT, wdt->freq) - 1;
-+}
-+
-+static unsigned int starfive_wdt_get_timeleft(struct watchdog_device *wdd)
-+{
-+ struct starfive_wdt *wdt = watchdog_get_drvdata(wdd);
-+ u32 count;
-+
-+ /*
-+ * If the watchdog takes twice timeout and set half count value,
-+ * timeleft value should add the count value before first timeout.
-+ */
-+ count = starfive_wdt_get_count(wdt);
-+ if (wdt->variant->double_timeout && !starfive_wdt_raise_irq_status(wdt))
-+ count += wdt->count;
-+
-+ return starfive_wdt_ticks_to_sec(wdt, count);
-+}
-+
-+static int starfive_wdt_keepalive(struct watchdog_device *wdd)
-+{
-+ struct starfive_wdt *wdt = watchdog_get_drvdata(wdd);
-+ int ret;
-+
-+ starfive_wdt_unlock(wdt);
-+ ret = starfive_wdt_int_clr(wdt);
-+ if (ret)
-+ goto exit;
-+
-+ starfive_wdt_set_reload_count(wdt, wdt->count);
-+
-+exit:
-+ /* exit with releasing spinlock and locking registers */
-+ starfive_wdt_lock(wdt);
-+ return ret;
-+}
-+
-+static int starfive_wdt_start(struct starfive_wdt *wdt)
-+{
-+ int ret;
-+
-+ starfive_wdt_unlock(wdt);
-+ /* disable watchdog, to be safe */
-+ starfive_wdt_disable(wdt);
-+
-+ starfive_wdt_enable_reset(wdt);
-+ ret = starfive_wdt_int_clr(wdt);
-+ if (ret)
-+ goto exit;
-+
-+ starfive_wdt_set_count(wdt, wdt->count);
-+ starfive_wdt_enable(wdt);
-+
-+exit:
-+ starfive_wdt_lock(wdt);
-+ return ret;
-+}
-+
-+static void starfive_wdt_stop(struct starfive_wdt *wdt)
-+{
-+ starfive_wdt_unlock(wdt);
-+ starfive_wdt_disable(wdt);
-+ starfive_wdt_lock(wdt);
-+}
-+
-+static int starfive_wdt_pm_start(struct watchdog_device *wdd)
-+{
-+ struct starfive_wdt *wdt = watchdog_get_drvdata(wdd);
-+ int ret = pm_runtime_get_sync(wdd->parent);
-+
-+ if (ret < 0)
-+ return ret;
-+
-+ return starfive_wdt_start(wdt);
-+}
-+
-+static int starfive_wdt_pm_stop(struct watchdog_device *wdd)
-+{
-+ struct starfive_wdt *wdt = watchdog_get_drvdata(wdd);
-+
-+ starfive_wdt_stop(wdt);
-+ return pm_runtime_put_sync(wdd->parent);
-+}
-+
-+static int starfive_wdt_set_timeout(struct watchdog_device *wdd,
-+ unsigned int timeout)
-+{
-+ struct starfive_wdt *wdt = watchdog_get_drvdata(wdd);
-+ unsigned long count = timeout * wdt->freq;
-+
-+ /* some watchdogs take two timeouts to reset */
-+ if (wdt->variant->double_timeout)
-+ count /= 2;
-+
-+ wdt->count = count;
-+ wdd->timeout = timeout;
-+
-+ starfive_wdt_unlock(wdt);
-+ starfive_wdt_disable(wdt);
-+ starfive_wdt_set_reload_count(wdt, wdt->count);
-+ starfive_wdt_enable(wdt);
-+ starfive_wdt_lock(wdt);
-+
-+ return 0;
-+}
-+
-+#define STARFIVE_WDT_OPTIONS (WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE)
-+
-+static const struct watchdog_info starfive_wdt_info = {
-+ .options = STARFIVE_WDT_OPTIONS,
-+ .identity = "StarFive Watchdog",
-+};
-+
-+static const struct watchdog_ops starfive_wdt_ops = {
-+ .owner = THIS_MODULE,
-+ .start = starfive_wdt_pm_start,
-+ .stop = starfive_wdt_pm_stop,
-+ .ping = starfive_wdt_keepalive,
-+ .set_timeout = starfive_wdt_set_timeout,
-+ .get_timeleft = starfive_wdt_get_timeleft,
-+};
-+
-+static int starfive_wdt_probe(struct platform_device *pdev)
-+{
-+ struct starfive_wdt *wdt;
-+ int ret;
-+
-+ wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
-+ if (!wdt)
-+ return -ENOMEM;
-+
-+ wdt->base = devm_platform_ioremap_resource(pdev, 0);
-+ if (IS_ERR(wdt->base))
-+ return dev_err_probe(&pdev->dev, PTR_ERR(wdt->base), "error mapping registers\n");
-+
-+ wdt->wdd.parent = &pdev->dev;
-+ ret = starfive_wdt_get_clock(wdt);
-+ if (ret)
-+ return ret;
-+
-+ platform_set_drvdata(pdev, wdt);
-+ pm_runtime_enable(&pdev->dev);
-+ if (pm_runtime_enabled(&pdev->dev)) {
-+ ret = pm_runtime_get_sync(&pdev->dev);
-+ if (ret < 0)
-+ return ret;
-+ } else {
-+ /* runtime PM is disabled but clocks need to be enabled */
-+ ret = starfive_wdt_enable_clock(wdt);
-+ if (ret)
-+ return ret;
-+ }
-+
-+ ret = starfive_wdt_reset_init(&pdev->dev);
-+ if (ret)
-+ goto err_exit;
-+
-+ watchdog_set_drvdata(&wdt->wdd, wdt);
-+ wdt->wdd.info = &starfive_wdt_info;
-+ wdt->wdd.ops = &starfive_wdt_ops;
-+ wdt->variant = of_device_get_match_data(&pdev->dev);
-+ spin_lock_init(&wdt->lock);
-+
-+ wdt->freq = clk_get_rate(wdt->core_clk);
-+ if (!wdt->freq) {
-+ dev_err(&pdev->dev, "get clock rate failed.\n");
-+ ret = -EINVAL;
-+ goto err_exit;
-+ }
-+
-+ wdt->wdd.min_timeout = 1;
-+ wdt->wdd.max_timeout = starfive_wdt_max_timeout(wdt);
-+ wdt->wdd.timeout = STARFIVE_WDT_DEFAULT_TIME;
-+ watchdog_init_timeout(&wdt->wdd, heartbeat, &pdev->dev);
-+ starfive_wdt_set_timeout(&wdt->wdd, wdt->wdd.timeout);
-+
-+ watchdog_set_nowayout(&wdt->wdd, nowayout);
-+ watchdog_stop_on_reboot(&wdt->wdd);
-+ watchdog_stop_on_unregister(&wdt->wdd);
-+
-+ if (early_enable) {
-+ ret = starfive_wdt_start(wdt);
-+ if (ret)
-+ goto err_exit;
-+ set_bit(WDOG_HW_RUNNING, &wdt->wdd.status);
-+ } else {
-+ starfive_wdt_stop(wdt);
-+ }
-+
-+ ret = watchdog_register_device(&wdt->wdd);
-+ if (ret)
-+ goto err_exit;
-+
-+ if (!early_enable)
-+ return pm_runtime_put_sync(&pdev->dev);
-+
-+ return 0;
-+
-+err_exit:
-+ starfive_wdt_disable_clock(wdt);
-+ pm_runtime_disable(&pdev->dev);
-+
-+ return ret;
-+}
-+
-+static int starfive_wdt_remove(struct platform_device *pdev)
-+{
-+ struct starfive_wdt *wdt = platform_get_drvdata(pdev);
-+
-+ starfive_wdt_stop(wdt);
-+ watchdog_unregister_device(&wdt->wdd);
-+
-+ if (pm_runtime_enabled(&pdev->dev))
-+ pm_runtime_disable(&pdev->dev);
-+ else
-+ /* disable clock without PM */
-+ starfive_wdt_disable_clock(wdt);
-+
-+ return 0;
-+}
-+
-+static void starfive_wdt_shutdown(struct platform_device *pdev)
-+{
-+ struct starfive_wdt *wdt = platform_get_drvdata(pdev);
-+
-+ starfive_wdt_pm_stop(&wdt->wdd);
-+}
-+
-+#ifdef CONFIG_PM_SLEEP
-+static int starfive_wdt_suspend(struct device *dev)
-+{
-+ struct starfive_wdt *wdt = dev_get_drvdata(dev);
-+
-+ /* Save watchdog state, and turn it off. */
-+ wdt->reload = starfive_wdt_get_count(wdt);
-+
-+ /* Note that WTCNT doesn't need to be saved. */
-+ starfive_wdt_stop(wdt);
-+
-+ return pm_runtime_force_suspend(dev);
-+}
-+
-+static int starfive_wdt_resume(struct device *dev)
-+{
-+ struct starfive_wdt *wdt = dev_get_drvdata(dev);
-+ int ret;
-+
-+ ret = pm_runtime_force_resume(dev);
-+ if (ret)
-+ return ret;
-+
-+ starfive_wdt_unlock(wdt);
-+ /* Restore watchdog state. */
-+ starfive_wdt_set_reload_count(wdt, wdt->reload);
-+ starfive_wdt_lock(wdt);
-+
-+ return starfive_wdt_start(wdt);
-+}
-+#endif /* CONFIG_PM_SLEEP */
-+
-+#ifdef CONFIG_PM
-+static int starfive_wdt_runtime_suspend(struct device *dev)
-+{
-+ struct starfive_wdt *wdt = dev_get_drvdata(dev);
-+
-+ starfive_wdt_disable_clock(wdt);
-+
-+ return 0;
-+}
-+
-+static int starfive_wdt_runtime_resume(struct device *dev)
-+{
-+ struct starfive_wdt *wdt = dev_get_drvdata(dev);
-+
-+ return starfive_wdt_enable_clock(wdt);
-+}
-+#endif /* CONFIG_PM */
-+
-+static const struct dev_pm_ops starfive_wdt_pm_ops = {
-+ SET_RUNTIME_PM_OPS(starfive_wdt_runtime_suspend, starfive_wdt_runtime_resume, NULL)
-+ SET_SYSTEM_SLEEP_PM_OPS(starfive_wdt_suspend, starfive_wdt_resume)
-+};
-+
-+static const struct of_device_id starfive_wdt_match[] = {
-+ { .compatible = "starfive,jh7100-wdt", .data = &starfive_wdt_jh7100_variant },
-+ { .compatible = "starfive,jh7110-wdt", .data = &starfive_wdt_jh7110_variant },
-+ { /* sentinel */ }
-+};
-+MODULE_DEVICE_TABLE(of, starfive_wdt_match);
-+
-+static struct platform_driver starfive_wdt_driver = {
-+ .probe = starfive_wdt_probe,
-+ .remove = starfive_wdt_remove,
-+ .shutdown = starfive_wdt_shutdown,
-+ .driver = {
-+ .name = "starfive-wdt",
-+ .pm = &starfive_wdt_pm_ops,
-+ .of_match_table = of_match_ptr(starfive_wdt_match),
-+ },
-+};
-+module_platform_driver(starfive_wdt_driver);
-+
-+MODULE_AUTHOR("Xingyu Wu <xingyu.wu@starfivetech.com>");
-+MODULE_AUTHOR("Samin Guo <samin.guo@starfivetech.com>");
-+MODULE_DESCRIPTION("StarFive Watchdog Device Driver");
-+MODULE_LICENSE("GPL");
diff --git a/target/linux/starfive/patches-6.1/0106-riscv-dts-starfive-jh7100-Add-watchdog-node.patch b/target/linux/starfive/patches-6.1/0106-riscv-dts-starfive-jh7100-Add-watchdog-node.patch
deleted file mode 100644
index a7b7bd88db..0000000000
--- a/target/linux/starfive/patches-6.1/0106-riscv-dts-starfive-jh7100-Add-watchdog-node.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From b085b6233065b1e5145fbf93d75264b2042c0eb5 Mon Sep 17 00:00:00 2001
-From: Xingyu Wu <xingyu.wu@starfivetech.com>
-Date: Tue, 14 Mar 2023 21:24:37 +0800
-Subject: [PATCH 106/122] riscv: dts: starfive: jh7100: Add watchdog node
-
-Add watchdog node for the StarFive JH7100 RISC-V SoC.
-
-Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
-Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
----
- arch/riscv/boot/dts/starfive/jh7100.dtsi | 10 ++++++++++
- 1 file changed, 10 insertions(+)
-
---- a/arch/riscv/boot/dts/starfive/jh7100.dtsi
-+++ b/arch/riscv/boot/dts/starfive/jh7100.dtsi
-@@ -238,5 +238,15 @@
- #size-cells = <0>;
- status = "disabled";
- };
-+
-+ watchdog@12480000 {
-+ compatible = "starfive,jh7100-wdt";
-+ reg = <0x0 0x12480000 0x0 0x10000>;
-+ clocks = <&clkgen JH7100_CLK_WDTIMER_APB>,
-+ <&clkgen JH7100_CLK_WDT_CORE>;
-+ clock-names = "apb", "core";
-+ resets = <&rstgen JH7100_RSTN_WDTIMER_APB>,
-+ <&rstgen JH7100_RSTN_WDT>;
-+ };
- };
- };
diff --git a/target/linux/starfive/patches-6.1/0107-dt-bindings-mmc-Add-StarFive-MMC-module.patch b/target/linux/starfive/patches-6.1/0107-dt-bindings-mmc-Add-StarFive-MMC-module.patch
deleted file mode 100644
index 39844b5b77..0000000000
--- a/target/linux/starfive/patches-6.1/0107-dt-bindings-mmc-Add-StarFive-MMC-module.patch
+++ /dev/null
@@ -1,95 +0,0 @@
-From fc157f3d411ac570e8261e4238c6e6aac74a6cc6 Mon Sep 17 00:00:00 2001
-From: William Qiu <william.qiu@starfivetech.com>
-Date: Wed, 15 Feb 2023 19:32:46 +0800
-Subject: [PATCH 107/122] dt-bindings: mmc: Add StarFive MMC module
-
-Add documentation to describe StarFive designware mobile storage
-host controller driver.
-
-Signed-off-by: William Qiu <william.qiu@starfivetech.com>
-Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
----
- .../bindings/mmc/starfive,jh7110-mmc.yaml | 77 +++++++++++++++++++
- 1 file changed, 77 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/mmc/starfive,jh7110-mmc.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/mmc/starfive,jh7110-mmc.yaml
-@@ -0,0 +1,77 @@
-+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/mmc/starfive,jh7110-mmc.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: StarFive Designware Mobile Storage Host Controller
-+
-+description:
-+ StarFive uses the Synopsys designware mobile storage host controller
-+ to interface a SoC with storage medium such as eMMC or SD/MMC cards.
-+
-+allOf:
-+ - $ref: synopsys-dw-mshc-common.yaml#
-+
-+maintainers:
-+ - William Qiu <william.qiu@starfivetech.com>
-+
-+properties:
-+ compatible:
-+ const: starfive,jh7110-mmc
-+
-+ reg:
-+ maxItems: 1
-+
-+ clocks:
-+ items:
-+ - description: biu clock
-+ - description: ciu clock
-+
-+ clock-names:
-+ items:
-+ - const: biu
-+ - const: ciu
-+
-+ interrupts:
-+ maxItems: 1
-+
-+ starfive,sysreg:
-+ $ref: /schemas/types.yaml#/definitions/phandle-array
-+ items:
-+ - items:
-+ - description: phandle to System Register Controller syscon node
-+ - description: offset of SYS_SYSCONSAIF__SYSCFG register for MMC controller
-+ - description: shift of SYS_SYSCONSAIF__SYSCFG register for MMC controller
-+ - description: mask of SYS_SYSCONSAIF__SYSCFG register for MMC controller
-+ description:
-+ Should be four parameters, the phandle to System Register Controller
-+ syscon node and the offset/shift/mask of SYS_SYSCONSAIF__SYSCFG register
-+ for MMC controller.
-+
-+required:
-+ - compatible
-+ - reg
-+ - clocks
-+ - clock-names
-+ - interrupts
-+ - starfive,sysreg
-+
-+unevaluatedProperties: false
-+
-+examples:
-+ - |
-+ mmc@16010000 {
-+ compatible = "starfive,jh7110-mmc";
-+ reg = <0x16010000 0x10000>;
-+ clocks = <&syscrg 91>,
-+ <&syscrg 93>;
-+ clock-names = "biu","ciu";
-+ resets = <&syscrg 64>;
-+ reset-names = "reset";
-+ interrupts = <74>;
-+ fifo-depth = <32>;
-+ fifo-watermark-aligned;
-+ data-addr = <0>;
-+ starfive,sysreg = <&sys_syscon 0x14 0x1a 0x7c000000>;
-+ };
diff --git a/target/linux/starfive/patches-6.1/0108-mmc-starfive-Add-sdio-emmc-driver-support.patch b/target/linux/starfive/patches-6.1/0108-mmc-starfive-Add-sdio-emmc-driver-support.patch
deleted file mode 100644
index fecad30928..0000000000
--- a/target/linux/starfive/patches-6.1/0108-mmc-starfive-Add-sdio-emmc-driver-support.patch
+++ /dev/null
@@ -1,250 +0,0 @@
-From ee990c664fad993275b2615d0ff06af5d04922f0 Mon Sep 17 00:00:00 2001
-From: William Qiu <william.qiu@starfivetech.com>
-Date: Wed, 15 Feb 2023 19:32:47 +0800
-Subject: [PATCH 108/122] mmc: starfive: Add sdio/emmc driver support
-
-Add sdio/emmc driver support for StarFive JH7110 soc.
-
-Tested-by: Conor Dooley <conor.dooley@microchip.com>
-Signed-off-by: William Qiu <william.qiu@starfivetech.com>
----
- MAINTAINERS | 6 +
- drivers/mmc/host/Kconfig | 10 ++
- drivers/mmc/host/Makefile | 1 +
- drivers/mmc/host/dw_mmc-starfive.c | 186 +++++++++++++++++++++++++++++
- 4 files changed, 203 insertions(+)
- create mode 100644 drivers/mmc/host/dw_mmc-starfive.c
-
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -19664,6 +19664,12 @@ S: Maintained
- F: Documentation/devicetree/bindings/net/starfive,jh7110-dwmac.yaml
- F: drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c
-
-+STARFIVE JH7110 MMC/SD/SDIO DRIVER
-+M: William Qiu <william.qiu@starfivetech.com>
-+S: Supported
-+F: Documentation/devicetree/bindings/mmc/starfive*
-+F: drivers/mmc/host/dw_mmc-starfive.c
-+
- STARFIVE JH7110 PLL CLOCK DRIVER
- M: Xingyu Wu <xingyu.wu@starfivetech.com>
- S: Supported
---- a/drivers/mmc/host/Kconfig
-+++ b/drivers/mmc/host/Kconfig
-@@ -872,6 +872,16 @@ config MMC_DW_ROCKCHIP
- Synopsys DesignWare Memory Card Interface driver. Select this option
- for platforms based on RK3066, RK3188 and RK3288 SoC's.
-
-+config MMC_DW_STARFIVE
-+ tristate "StarFive specific extensions for Synopsys DW Memory Card Interface"
-+ depends on SOC_STARFIVE
-+ depends on MMC_DW
-+ select MMC_DW_PLTFM
-+ help
-+ This selects support for StarFive JH7110 SoC specific extensions to the
-+ Synopsys DesignWare Memory Card Interface driver. Select this option
-+ for platforms based on StarFive JH7110 SoC.
-+
- config MMC_SH_MMCIF
- tristate "SuperH Internal MMCIF support"
- depends on SUPERH || ARCH_RENESAS || COMPILE_TEST
---- a/drivers/mmc/host/Makefile
-+++ b/drivers/mmc/host/Makefile
-@@ -56,6 +56,7 @@ obj-$(CONFIG_MMC_DW_HI3798CV200) += dw_m
- obj-$(CONFIG_MMC_DW_K3) += dw_mmc-k3.o
- obj-$(CONFIG_MMC_DW_PCI) += dw_mmc-pci.o
- obj-$(CONFIG_MMC_DW_ROCKCHIP) += dw_mmc-rockchip.o
-+obj-$(CONFIG_MMC_DW_STARFIVE) += dw_mmc-starfive.o
- obj-$(CONFIG_MMC_SH_MMCIF) += sh_mmcif.o
- obj-$(CONFIG_MMC_JZ4740) += jz4740_mmc.o
- obj-$(CONFIG_MMC_VUB300) += vub300.o
---- /dev/null
-+++ b/drivers/mmc/host/dw_mmc-starfive.c
-@@ -0,0 +1,186 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * StarFive Designware Mobile Storage Host Controller Driver
-+ *
-+ * Copyright (c) 2022 StarFive Technology Co., Ltd.
-+ */
-+
-+#include <linux/clk.h>
-+#include <linux/delay.h>
-+#include <linux/mfd/syscon.h>
-+#include <linux/mmc/host.h>
-+#include <linux/module.h>
-+#include <linux/of_address.h>
-+#include <linux/platform_device.h>
-+#include <linux/regmap.h>
-+
-+#include "dw_mmc.h"
-+#include "dw_mmc-pltfm.h"
-+
-+#define ALL_INT_CLR 0x1ffff
-+#define MAX_DELAY_CHAIN 32
-+
-+struct starfive_priv {
-+ struct device *dev;
-+ struct regmap *reg_syscon;
-+ u32 syscon_offset;
-+ u32 syscon_shift;
-+ u32 syscon_mask;
-+};
-+
-+static void dw_mci_starfive_set_ios(struct dw_mci *host, struct mmc_ios *ios)
-+{
-+ int ret;
-+ unsigned int clock;
-+
-+ if (ios->timing == MMC_TIMING_MMC_DDR52 || ios->timing == MMC_TIMING_UHS_DDR50) {
-+ clock = (ios->clock > 50000000 && ios->clock <= 52000000) ? 100000000 : ios->clock;
-+ ret = clk_set_rate(host->ciu_clk, clock);
-+ if (ret)
-+ dev_dbg(host->dev, "Use an external frequency divider %uHz\n", ios->clock);
-+ host->bus_hz = clk_get_rate(host->ciu_clk);
-+ } else {
-+ dev_dbg(host->dev, "Using the internal divider\n");
-+ }
-+}
-+
-+static int dw_mci_starfive_execute_tuning(struct dw_mci_slot *slot,
-+ u32 opcode)
-+{
-+ static const int grade = MAX_DELAY_CHAIN;
-+ struct dw_mci *host = slot->host;
-+ struct starfive_priv *priv = host->priv;
-+ int rise_point = -1, fall_point = -1;
-+ int err, prev_err;
-+ int i;
-+ bool found = 0;
-+ u32 regval;
-+
-+ /*
-+ * Use grade as the max delay chain, and use the rise_point and
-+ * fall_point to ensure the best sampling point of a data input
-+ * signals.
-+ */
-+ for (i = 0; i < grade; i++) {
-+ regval = i << priv->syscon_shift;
-+ err = regmap_update_bits(priv->reg_syscon, priv->syscon_offset,
-+ priv->syscon_mask, regval);
-+ if (err)
-+ return err;
-+ mci_writel(host, RINTSTS, ALL_INT_CLR);
-+
-+ err = mmc_send_tuning(slot->mmc, opcode, NULL);
-+ if (!err)
-+ found = 1;
-+
-+ if (i > 0) {
-+ if (err && !prev_err)
-+ fall_point = i - 1;
-+ if (!err && prev_err)
-+ rise_point = i;
-+ }
-+
-+ if (rise_point != -1 && fall_point != -1)
-+ goto tuning_out;
-+
-+ prev_err = err;
-+ err = 0;
-+ }
-+
-+tuning_out:
-+ if (found) {
-+ if (rise_point == -1)
-+ rise_point = 0;
-+ if (fall_point == -1)
-+ fall_point = grade - 1;
-+ if (fall_point < rise_point) {
-+ if ((rise_point + fall_point) >
-+ (grade - 1))
-+ i = fall_point / 2;
-+ else
-+ i = (rise_point + grade - 1) / 2;
-+ } else {
-+ i = (rise_point + fall_point) / 2;
-+ }
-+
-+ regval = i << priv->syscon_shift;
-+ err = regmap_update_bits(priv->reg_syscon, priv->syscon_offset,
-+ priv->syscon_mask, regval);
-+ if (err)
-+ return err;
-+ mci_writel(host, RINTSTS, ALL_INT_CLR);
-+
-+ dev_info(host->dev, "Found valid delay chain! use it [delay=%d]\n", i);
-+ } else {
-+ dev_err(host->dev, "No valid delay chain! use default\n");
-+ err = -EINVAL;
-+ }
-+
-+ mci_writel(host, RINTSTS, ALL_INT_CLR);
-+ return err;
-+}
-+
-+static int dw_mci_starfive_parse_dt(struct dw_mci *host)
-+{
-+ struct of_phandle_args args;
-+ struct starfive_priv *priv;
-+ int ret;
-+
-+ priv = devm_kzalloc(host->dev, sizeof(*priv), GFP_KERNEL);
-+ if (!priv)
-+ return -ENOMEM;
-+
-+ ret = of_parse_phandle_with_fixed_args(host->dev->of_node,
-+ "starfive,sysreg", 3, 0, &args);
-+ if (ret) {
-+ dev_err(host->dev, "Failed to parse starfive,sysreg\n");
-+ return -EINVAL;
-+ }
-+
-+ priv->reg_syscon = syscon_node_to_regmap(args.np);
-+ of_node_put(args.np);
-+ if (IS_ERR(priv->reg_syscon))
-+ return PTR_ERR(priv->reg_syscon);
-+
-+ priv->syscon_offset = args.args[0];
-+ priv->syscon_shift = args.args[1];
-+ priv->syscon_mask = args.args[2];
-+
-+ host->priv = priv;
-+
-+ return 0;
-+}
-+
-+static const struct dw_mci_drv_data starfive_data = {
-+ .common_caps = MMC_CAP_CMD23,
-+ .set_ios = dw_mci_starfive_set_ios,
-+ .parse_dt = dw_mci_starfive_parse_dt,
-+ .execute_tuning = dw_mci_starfive_execute_tuning,
-+};
-+
-+static const struct of_device_id dw_mci_starfive_match[] = {
-+ { .compatible = "starfive,jh7110-mmc",
-+ .data = &starfive_data },
-+ {},
-+};
-+MODULE_DEVICE_TABLE(of, dw_mci_starfive_match);
-+
-+static int dw_mci_starfive_probe(struct platform_device *pdev)
-+{
-+ return dw_mci_pltfm_register(pdev, &starfive_data);
-+}
-+
-+static struct platform_driver dw_mci_starfive_driver = {
-+ .probe = dw_mci_starfive_probe,
-+ .remove = dw_mci_pltfm_remove,
-+ .driver = {
-+ .name = "dwmmc_starfive",
-+ .probe_type = PROBE_PREFER_ASYNCHRONOUS,
-+ .of_match_table = dw_mci_starfive_match,
-+ },
-+};
-+module_platform_driver(dw_mci_starfive_driver);
-+
-+MODULE_DESCRIPTION("StarFive JH7110 Specific DW-MSHC Driver Extension");
-+MODULE_LICENSE("GPL");
-+MODULE_ALIAS("platform:dwmmc_starfive");
diff --git a/target/linux/starfive/patches-6.1/0109-dt-bindings-hwmon-Add-starfive-jh71x0-temp.patch b/target/linux/starfive/patches-6.1/0109-dt-bindings-hwmon-Add-starfive-jh71x0-temp.patch
deleted file mode 100644
index 9f6c4128f3..0000000000
--- a/target/linux/starfive/patches-6.1/0109-dt-bindings-hwmon-Add-starfive-jh71x0-temp.patch
+++ /dev/null
@@ -1,89 +0,0 @@
-From a0f2b48b5433d2fbcf87e4edf52e5cc26d0c29c8 Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Tue, 21 Mar 2023 10:26:43 +0800
-Subject: [PATCH 109/122] dt-bindings: hwmon: Add starfive,jh71x0-temp
-
-Add bindings for the temperature sensor on the StarFive JH7100 and
-JH7110 SoCs.
-
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
-Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
-Reviewed-by: Rob Herring <robh@kernel.org>
----
- .../bindings/hwmon/starfive,jh71x0-temp.yaml | 70 +++++++++++++++++++
- 1 file changed, 70 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/hwmon/starfive,jh71x0-temp.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/hwmon/starfive,jh71x0-temp.yaml
-@@ -0,0 +1,70 @@
-+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/hwmon/starfive,jh71x0-temp.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: StarFive JH71x0 Temperature Sensor
-+
-+maintainers:
-+ - Emil Renner Berthing <kernel@esmil.dk>
-+
-+description: |
-+ StarFive Technology Co. JH71x0 embedded temperature sensor
-+
-+properties:
-+ compatible:
-+ enum:
-+ - starfive,jh7100-temp
-+ - starfive,jh7110-temp
-+
-+ reg:
-+ maxItems: 1
-+
-+ clocks:
-+ minItems: 2
-+ maxItems: 2
-+
-+ clock-names:
-+ items:
-+ - const: "sense"
-+ - const: "bus"
-+
-+ '#thermal-sensor-cells':
-+ const: 0
-+
-+ resets:
-+ minItems: 2
-+ maxItems: 2
-+
-+ reset-names:
-+ items:
-+ - const: "sense"
-+ - const: "bus"
-+
-+required:
-+ - compatible
-+ - reg
-+ - clocks
-+ - clock-names
-+ - resets
-+ - reset-names
-+
-+additionalProperties: false
-+
-+examples:
-+ - |
-+ #include <dt-bindings/clock/starfive-jh7100.h>
-+ #include <dt-bindings/reset/starfive-jh7100.h>
-+
-+ temperature-sensor@124a0000 {
-+ compatible = "starfive,jh7100-temp";
-+ reg = <0x124a0000 0x10000>;
-+ clocks = <&clkgen JH7100_CLK_TEMP_SENSE>,
-+ <&clkgen JH7100_CLK_TEMP_APB>;
-+ clock-names = "sense", "bus";
-+ #thermal-sensor-cells = <0>;
-+ resets = <&rstgen JH7100_RSTN_TEMP_SENSE>,
-+ <&rstgen JH7100_RSTN_TEMP_APB>;
-+ reset-names = "sense", "bus";
-+ };
diff --git a/target/linux/starfive/patches-6.1/0110-hwmon-sfctemp-Add-StarFive-JH71x0-temperature-sensor.patch b/target/linux/starfive/patches-6.1/0110-hwmon-sfctemp-Add-StarFive-JH71x0-temperature-sensor.patch
deleted file mode 100644
index aa062021ac..0000000000
--- a/target/linux/starfive/patches-6.1/0110-hwmon-sfctemp-Add-StarFive-JH71x0-temperature-sensor.patch
+++ /dev/null
@@ -1,451 +0,0 @@
-From 3f68f5d0a8c598a09d26a3908cbbff7312b31487 Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Tue, 21 Mar 2023 10:26:44 +0800
-Subject: [PATCH 110/122] hwmon: (sfctemp) Add StarFive JH71x0 temperature
- sensor
-
-Add driver for the StarFive JH71x0 temperature sensor. You
-can enable/disable it and read temperature in milli Celcius
-through sysfs.
-
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
-Co-developed-by: Samin Guo <samin.guo@starfivetech.com>
-Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
-Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
----
- Documentation/hwmon/index.rst | 1 +
- Documentation/hwmon/sfctemp.rst | 33 ++++
- MAINTAINERS | 8 +
- drivers/hwmon/Kconfig | 10 +
- drivers/hwmon/Makefile | 1 +
- drivers/hwmon/sfctemp.c | 331 ++++++++++++++++++++++++++++++++
- 6 files changed, 384 insertions(+)
- create mode 100644 Documentation/hwmon/sfctemp.rst
- create mode 100644 drivers/hwmon/sfctemp.c
-
---- a/Documentation/hwmon/index.rst
-+++ b/Documentation/hwmon/index.rst
-@@ -179,6 +179,7 @@ Hardware Monitoring Kernel Drivers
- sch5627
- sch5636
- scpi-hwmon
-+ sfctemp
- sht15
- sht21
- sht3x
---- /dev/null
-+++ b/Documentation/hwmon/sfctemp.rst
-@@ -0,0 +1,33 @@
-+.. SPDX-License-Identifier: GPL-2.0
-+
-+Kernel driver sfctemp
-+=====================
-+
-+Supported chips:
-+ - StarFive JH7100
-+ - StarFive JH7110
-+
-+Authors:
-+ - Emil Renner Berthing <kernel@esmil.dk>
-+
-+Description
-+-----------
-+
-+This driver adds support for reading the built-in temperature sensor on the
-+JH7100 and JH7110 RISC-V SoCs by StarFive Technology Co. Ltd.
-+
-+``sysfs`` interface
-+-------------------
-+
-+The temperature sensor can be enabled, disabled and queried via the standard
-+hwmon interface in sysfs under ``/sys/class/hwmon/hwmonX`` for some value of
-+``X``:
-+
-+================ ==== =============================================
-+Name Perm Description
-+================ ==== =============================================
-+temp1_enable RW Enable or disable temperature sensor.
-+ Automatically enabled by the driver,
-+ but may be disabled to save power.
-+temp1_input RO Temperature reading in milli-degrees Celsius.
-+================ ==== =============================================
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -18686,6 +18686,14 @@ L: netdev@vger.kernel.org
- S: Supported
- F: drivers/net/ethernet/sfc/
-
-+SFCTEMP HWMON DRIVER
-+M: Emil Renner Berthing <kernel@esmil.dk>
-+L: linux-hwmon@vger.kernel.org
-+S: Maintained
-+F: Documentation/devicetree/bindings/hwmon/starfive,jh71x0-temp.yaml
-+F: Documentation/hwmon/sfctemp.rst
-+F: drivers/hwmon/sfctemp.c
-+
- SFF/SFP/SFP+ MODULE SUPPORT
- M: Russell King <linux@armlinux.org.uk>
- L: netdev@vger.kernel.org
---- a/drivers/hwmon/Kconfig
-+++ b/drivers/hwmon/Kconfig
-@@ -1911,6 +1911,16 @@ config SENSORS_STTS751
- This driver can also be built as a module. If so, the module
- will be called stts751.
-
-+config SENSORS_SFCTEMP
-+ tristate "Starfive JH71x0 temperature sensor"
-+ depends on ARCH_STARFIVE || COMPILE_TEST
-+ help
-+ If you say yes here you get support for temperature sensor
-+ on the Starfive JH71x0 SoCs.
-+
-+ This driver can also be built as a module. If so, the module
-+ will be called sfctemp.
-+
- config SENSORS_SMM665
- tristate "Summit Microelectronics SMM665"
- depends on I2C
---- a/drivers/hwmon/Makefile
-+++ b/drivers/hwmon/Makefile
-@@ -179,6 +179,7 @@ obj-$(CONFIG_SENSORS_SBRMI) += sbrmi.o
- obj-$(CONFIG_SENSORS_SCH56XX_COMMON)+= sch56xx-common.o
- obj-$(CONFIG_SENSORS_SCH5627) += sch5627.o
- obj-$(CONFIG_SENSORS_SCH5636) += sch5636.o
-+obj-$(CONFIG_SENSORS_SFCTEMP) += sfctemp.o
- obj-$(CONFIG_SENSORS_SL28CPLD) += sl28cpld-hwmon.o
- obj-$(CONFIG_SENSORS_SHT15) += sht15.o
- obj-$(CONFIG_SENSORS_SHT21) += sht21.o
---- /dev/null
-+++ b/drivers/hwmon/sfctemp.c
-@@ -0,0 +1,331 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
-+ * Copyright (C) 2021 Samin Guo <samin.guo@starfivetech.com>
-+ */
-+
-+#include <linux/bits.h>
-+#include <linux/clk.h>
-+#include <linux/delay.h>
-+#include <linux/hwmon.h>
-+#include <linux/io.h>
-+#include <linux/module.h>
-+#include <linux/mutex.h>
-+#include <linux/of.h>
-+#include <linux/platform_device.h>
-+#include <linux/reset.h>
-+
-+/*
-+ * TempSensor reset. The RSTN can be de-asserted once the analog core has
-+ * powered up. Trst(min 100ns)
-+ * 0:reset 1:de-assert
-+ */
-+#define SFCTEMP_RSTN BIT(0)
-+
-+/*
-+ * TempSensor analog core power down. The analog core will be powered up
-+ * Tpu(min 50us) after PD is de-asserted. RSTN should be held low until the
-+ * analog core is powered up.
-+ * 0:power up 1:power down
-+ */
-+#define SFCTEMP_PD BIT(1)
-+
-+/*
-+ * TempSensor start conversion enable.
-+ * 0:disable 1:enable
-+ */
-+#define SFCTEMP_RUN BIT(2)
-+
-+/*
-+ * TempSensor conversion value output.
-+ * Temp(C)=DOUT*Y/4094 - K
-+ */
-+#define SFCTEMP_DOUT_POS 16
-+#define SFCTEMP_DOUT_MSK GENMASK(27, 16)
-+
-+/* DOUT to Celcius conversion constants */
-+#define SFCTEMP_Y1000 237500L
-+#define SFCTEMP_Z 4094L
-+#define SFCTEMP_K1000 81100L
-+
-+struct sfctemp {
-+ /* serialize access to hardware register and enabled below */
-+ struct mutex lock;
-+ void __iomem *regs;
-+ struct clk *clk_sense;
-+ struct clk *clk_bus;
-+ struct reset_control *rst_sense;
-+ struct reset_control *rst_bus;
-+ bool enabled;
-+};
-+
-+static void sfctemp_power_up(struct sfctemp *sfctemp)
-+{
-+ /* make sure we're powered down first */
-+ writel(SFCTEMP_PD, sfctemp->regs);
-+ udelay(1);
-+
-+ writel(0, sfctemp->regs);
-+ /* wait t_pu(50us) + t_rst(100ns) */
-+ usleep_range(60, 200);
-+
-+ /* de-assert reset */
-+ writel(SFCTEMP_RSTN, sfctemp->regs);
-+ udelay(1); /* wait t_su(500ps) */
-+}
-+
-+static void sfctemp_power_down(struct sfctemp *sfctemp)
-+{
-+ writel(SFCTEMP_PD, sfctemp->regs);
-+}
-+
-+static void sfctemp_run(struct sfctemp *sfctemp)
-+{
-+ writel(SFCTEMP_RSTN | SFCTEMP_RUN, sfctemp->regs);
-+ udelay(1);
-+}
-+
-+static void sfctemp_stop(struct sfctemp *sfctemp)
-+{
-+ writel(SFCTEMP_RSTN, sfctemp->regs);
-+}
-+
-+static int sfctemp_enable(struct sfctemp *sfctemp)
-+{
-+ int ret = 0;
-+
-+ mutex_lock(&sfctemp->lock);
-+ if (sfctemp->enabled)
-+ goto done;
-+
-+ ret = clk_prepare_enable(sfctemp->clk_bus);
-+ if (ret)
-+ goto err;
-+ ret = reset_control_deassert(sfctemp->rst_bus);
-+ if (ret)
-+ goto err_disable_bus;
-+
-+ ret = clk_prepare_enable(sfctemp->clk_sense);
-+ if (ret)
-+ goto err_assert_bus;
-+ ret = reset_control_deassert(sfctemp->rst_sense);
-+ if (ret)
-+ goto err_disable_sense;
-+
-+ sfctemp_power_up(sfctemp);
-+ sfctemp_run(sfctemp);
-+ sfctemp->enabled = true;
-+done:
-+ mutex_unlock(&sfctemp->lock);
-+ return ret;
-+
-+err_disable_sense:
-+ clk_disable_unprepare(sfctemp->clk_sense);
-+err_assert_bus:
-+ reset_control_assert(sfctemp->rst_bus);
-+err_disable_bus:
-+ clk_disable_unprepare(sfctemp->clk_bus);
-+err:
-+ mutex_unlock(&sfctemp->lock);
-+ return ret;
-+}
-+
-+static int sfctemp_disable(struct sfctemp *sfctemp)
-+{
-+ mutex_lock(&sfctemp->lock);
-+ if (!sfctemp->enabled)
-+ goto done;
-+
-+ sfctemp_stop(sfctemp);
-+ sfctemp_power_down(sfctemp);
-+ reset_control_assert(sfctemp->rst_sense);
-+ clk_disable_unprepare(sfctemp->clk_sense);
-+ reset_control_assert(sfctemp->rst_bus);
-+ clk_disable_unprepare(sfctemp->clk_bus);
-+ sfctemp->enabled = false;
-+done:
-+ mutex_unlock(&sfctemp->lock);
-+ return 0;
-+}
-+
-+static void sfctemp_disable_action(void *data)
-+{
-+ sfctemp_disable(data);
-+}
-+
-+static int sfctemp_convert(struct sfctemp *sfctemp, long *val)
-+{
-+ int ret;
-+
-+ mutex_lock(&sfctemp->lock);
-+ if (!sfctemp->enabled) {
-+ ret = -ENODATA;
-+ goto out;
-+ }
-+
-+ /* calculate temperature in milli Celcius */
-+ *val = (long)((readl(sfctemp->regs) & SFCTEMP_DOUT_MSK) >> SFCTEMP_DOUT_POS)
-+ * SFCTEMP_Y1000 / SFCTEMP_Z - SFCTEMP_K1000;
-+
-+ ret = 0;
-+out:
-+ mutex_unlock(&sfctemp->lock);
-+ return ret;
-+}
-+
-+static umode_t sfctemp_is_visible(const void *data, enum hwmon_sensor_types type,
-+ u32 attr, int channel)
-+{
-+ switch (type) {
-+ case hwmon_temp:
-+ switch (attr) {
-+ case hwmon_temp_enable:
-+ return 0644;
-+ case hwmon_temp_input:
-+ return 0444;
-+ default:
-+ return 0;
-+ }
-+ default:
-+ return 0;
-+ }
-+}
-+
-+static int sfctemp_read(struct device *dev, enum hwmon_sensor_types type,
-+ u32 attr, int channel, long *val)
-+{
-+ struct sfctemp *sfctemp = dev_get_drvdata(dev);
-+
-+ switch (type) {
-+ case hwmon_temp:
-+ switch (attr) {
-+ case hwmon_temp_enable:
-+ *val = sfctemp->enabled;
-+ return 0;
-+ case hwmon_temp_input:
-+ return sfctemp_convert(sfctemp, val);
-+ default:
-+ return -EINVAL;
-+ }
-+ default:
-+ return -EINVAL;
-+ }
-+}
-+
-+static int sfctemp_write(struct device *dev, enum hwmon_sensor_types type,
-+ u32 attr, int channel, long val)
-+{
-+ struct sfctemp *sfctemp = dev_get_drvdata(dev);
-+
-+ switch (type) {
-+ case hwmon_temp:
-+ switch (attr) {
-+ case hwmon_temp_enable:
-+ if (val == 0)
-+ return sfctemp_disable(sfctemp);
-+ if (val == 1)
-+ return sfctemp_enable(sfctemp);
-+ return -EINVAL;
-+ default:
-+ return -EINVAL;
-+ }
-+ default:
-+ return -EINVAL;
-+ }
-+}
-+
-+static const struct hwmon_channel_info *sfctemp_info[] = {
-+ HWMON_CHANNEL_INFO(chip, HWMON_C_REGISTER_TZ),
-+ HWMON_CHANNEL_INFO(temp, HWMON_T_ENABLE | HWMON_T_INPUT),
-+ NULL
-+};
-+
-+static const struct hwmon_ops sfctemp_hwmon_ops = {
-+ .is_visible = sfctemp_is_visible,
-+ .read = sfctemp_read,
-+ .write = sfctemp_write,
-+};
-+
-+static const struct hwmon_chip_info sfctemp_chip_info = {
-+ .ops = &sfctemp_hwmon_ops,
-+ .info = sfctemp_info,
-+};
-+
-+static int sfctemp_probe(struct platform_device *pdev)
-+{
-+ struct device *dev = &pdev->dev;
-+ struct device *hwmon_dev;
-+ struct sfctemp *sfctemp;
-+ int ret;
-+
-+ sfctemp = devm_kzalloc(dev, sizeof(*sfctemp), GFP_KERNEL);
-+ if (!sfctemp)
-+ return -ENOMEM;
-+
-+ dev_set_drvdata(dev, sfctemp);
-+ mutex_init(&sfctemp->lock);
-+
-+ sfctemp->regs = devm_platform_ioremap_resource(pdev, 0);
-+ if (IS_ERR(sfctemp->regs))
-+ return PTR_ERR(sfctemp->regs);
-+
-+ sfctemp->clk_sense = devm_clk_get(dev, "sense");
-+ if (IS_ERR(sfctemp->clk_sense))
-+ return dev_err_probe(dev, PTR_ERR(sfctemp->clk_sense),
-+ "error getting sense clock\n");
-+
-+ sfctemp->clk_bus = devm_clk_get(dev, "bus");
-+ if (IS_ERR(sfctemp->clk_bus))
-+ return dev_err_probe(dev, PTR_ERR(sfctemp->clk_bus),
-+ "error getting bus clock\n");
-+
-+ sfctemp->rst_sense = devm_reset_control_get_exclusive(dev, "sense");
-+ if (IS_ERR(sfctemp->rst_sense))
-+ return dev_err_probe(dev, PTR_ERR(sfctemp->rst_sense),
-+ "error getting sense reset\n");
-+
-+ sfctemp->rst_bus = devm_reset_control_get_exclusive(dev, "bus");
-+ if (IS_ERR(sfctemp->rst_bus))
-+ return dev_err_probe(dev, PTR_ERR(sfctemp->rst_bus),
-+ "error getting busreset\n");
-+
-+ ret = reset_control_assert(sfctemp->rst_sense);
-+ if (ret)
-+ return dev_err_probe(dev, ret, "error asserting sense reset\n");
-+
-+ ret = reset_control_assert(sfctemp->rst_bus);
-+ if (ret)
-+ return dev_err_probe(dev, ret, "error asserting bus reset\n");
-+
-+ ret = devm_add_action(dev, sfctemp_disable_action, sfctemp);
-+ if (ret)
-+ return ret;
-+
-+ ret = sfctemp_enable(sfctemp);
-+ if (ret)
-+ return dev_err_probe(dev, ret, "error enabling temperature sensor: %d\n", ret);
-+
-+ hwmon_dev = devm_hwmon_device_register_with_info(dev, "sfctemp", sfctemp,
-+ &sfctemp_chip_info, NULL);
-+ return PTR_ERR_OR_ZERO(hwmon_dev);
-+}
-+
-+static const struct of_device_id sfctemp_of_match[] = {
-+ { .compatible = "starfive,jh7100-temp" },
-+ { .compatible = "starfive,jh7110-temp" },
-+ { /* sentinel */ }
-+};
-+MODULE_DEVICE_TABLE(of, sfctemp_of_match);
-+
-+static struct platform_driver sfctemp_driver = {
-+ .probe = sfctemp_probe,
-+ .driver = {
-+ .name = "sfctemp",
-+ .of_match_table = sfctemp_of_match,
-+ },
-+};
-+module_platform_driver(sfctemp_driver);
-+
-+MODULE_AUTHOR("Emil Renner Berthing");
-+MODULE_DESCRIPTION("StarFive JH71x0 temperature sensor driver");
-+MODULE_LICENSE("GPL");
diff --git a/target/linux/starfive/patches-6.1/0111-dt-bindings-dma-snps-dw-axi-dmac-constrain-the-items.patch b/target/linux/starfive/patches-6.1/0111-dt-bindings-dma-snps-dw-axi-dmac-constrain-the-items.patch
deleted file mode 100644
index 860c6c0885..0000000000
--- a/target/linux/starfive/patches-6.1/0111-dt-bindings-dma-snps-dw-axi-dmac-constrain-the-items.patch
+++ /dev/null
@@ -1,62 +0,0 @@
-From c2f59eeeee68bb66a3db8555474fe94e73b65b02 Mon Sep 17 00:00:00 2001
-From: Walker Chen <walker.chen@starfivetech.com>
-Date: Wed, 22 Mar 2023 17:48:17 +0800
-Subject: [PATCH 111/122] dt-bindings: dma: snps,dw-axi-dmac: constrain the
- items of resets for JH7110 dma
-
-The DMA controller needs two reset items to work properly on JH7110 SoC,
-so there is need to constrain the items' value to 2, other platforms
-have 1 reset item at most.
-
-Reviewed-by: Rob Herring <robh@kernel.org>
-Signed-off-by: Walker Chen <walker.chen@starfivetech.com>
----
- .../bindings/dma/snps,dw-axi-dmac.yaml | 23 ++++++++++++++++++-
- 1 file changed, 22 insertions(+), 1 deletion(-)
-
---- a/Documentation/devicetree/bindings/dma/snps,dw-axi-dmac.yaml
-+++ b/Documentation/devicetree/bindings/dma/snps,dw-axi-dmac.yaml
-@@ -21,6 +21,7 @@ properties:
- enum:
- - snps,axi-dma-1.01a
- - intel,kmb-axi-dma
-+ - starfive,jh7110-axi-dma
-
- reg:
- minItems: 1
-@@ -59,7 +60,8 @@ properties:
- maximum: 8
-
- resets:
-- maxItems: 1
-+ minItems: 1
-+ maxItems: 2
-
- snps,dma-masters:
- description: |
-@@ -110,6 +112,25 @@ required:
- - snps,priority
- - snps,block-size
-
-+if:
-+ properties:
-+ compatible:
-+ contains:
-+ enum:
-+ - starfive,jh7110-axi-dma
-+then:
-+ properties:
-+ resets:
-+ minItems: 2
-+ items:
-+ - description: AXI reset line
-+ - description: AHB reset line
-+ - description: module reset
-+else:
-+ properties:
-+ resets:
-+ maxItems: 1
-+
- additionalProperties: false
-
- examples:
diff --git a/target/linux/starfive/patches-6.1/0112-dmaengine-dw-axi-dmac-Add-support-for-StarFive-JH711.patch b/target/linux/starfive/patches-6.1/0112-dmaengine-dw-axi-dmac-Add-support-for-StarFive-JH711.patch
deleted file mode 100644
index a8cc23bf10..0000000000
--- a/target/linux/starfive/patches-6.1/0112-dmaengine-dw-axi-dmac-Add-support-for-StarFive-JH711.patch
+++ /dev/null
@@ -1,122 +0,0 @@
-From 69ed990fda6795039a2b5b37d8ad5df785f4d97b Mon Sep 17 00:00:00 2001
-From: Walker Chen <walker.chen@starfivetech.com>
-Date: Wed, 22 Mar 2023 17:48:18 +0800
-Subject: [PATCH 112/122] dmaengine: dw-axi-dmac: Add support for StarFive
- JH7110 DMA
-
-Add DMA reset operation in device probe and use different configuration
-on CH_CFG registers according to match data. Update all uses of
-of_device_is_compatible with of_device_get_match_data.
-
-Signed-off-by: Walker Chen <walker.chen@starfivetech.com>
-Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
----
- .../dma/dw-axi-dmac/dw-axi-dmac-platform.c | 38 ++++++++++++++++---
- drivers/dma/dw-axi-dmac/dw-axi-dmac.h | 1 +
- 2 files changed, 34 insertions(+), 5 deletions(-)
-
---- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
-+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
-@@ -21,10 +21,12 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/of.h>
-+#include <linux/of_device.h>
- #include <linux/of_dma.h>
- #include <linux/platform_device.h>
- #include <linux/pm_runtime.h>
- #include <linux/property.h>
-+#include <linux/reset.h>
- #include <linux/slab.h>
- #include <linux/types.h>
-
-@@ -46,6 +48,10 @@
- DMA_SLAVE_BUSWIDTH_32_BYTES | \
- DMA_SLAVE_BUSWIDTH_64_BYTES)
-
-+#define AXI_DMA_FLAG_HAS_APB_REGS BIT(0)
-+#define AXI_DMA_FLAG_HAS_RESETS BIT(1)
-+#define AXI_DMA_FLAG_USE_CFG2 BIT(2)
-+
- static inline void
- axi_dma_iowrite32(struct axi_dma_chip *chip, u32 reg, u32 val)
- {
-@@ -86,7 +92,8 @@ static inline void axi_chan_config_write
-
- cfg_lo = (config->dst_multblk_type << CH_CFG_L_DST_MULTBLK_TYPE_POS |
- config->src_multblk_type << CH_CFG_L_SRC_MULTBLK_TYPE_POS);
-- if (chan->chip->dw->hdata->reg_map_8_channels) {
-+ if (chan->chip->dw->hdata->reg_map_8_channels &&
-+ !chan->chip->dw->hdata->use_cfg2) {
- cfg_hi = config->tt_fc << CH_CFG_H_TT_FC_POS |
- config->hs_sel_src << CH_CFG_H_HS_SEL_SRC_POS |
- config->hs_sel_dst << CH_CFG_H_HS_SEL_DST_POS |
-@@ -1365,11 +1372,12 @@ static int parse_device_properties(struc
-
- static int dw_probe(struct platform_device *pdev)
- {
-- struct device_node *node = pdev->dev.of_node;
- struct axi_dma_chip *chip;
- struct resource *mem;
- struct dw_axi_dma *dw;
- struct dw_axi_dma_hcfg *hdata;
-+ struct reset_control *resets;
-+ unsigned int flags;
- u32 i;
- int ret;
-
-@@ -1398,12 +1406,25 @@ static int dw_probe(struct platform_devi
- if (IS_ERR(chip->regs))
- return PTR_ERR(chip->regs);
-
-- if (of_device_is_compatible(node, "intel,kmb-axi-dma")) {
-+ flags = (uintptr_t)of_device_get_match_data(&pdev->dev);
-+ if (flags & AXI_DMA_FLAG_HAS_APB_REGS) {
- chip->apb_regs = devm_platform_ioremap_resource(pdev, 1);
- if (IS_ERR(chip->apb_regs))
- return PTR_ERR(chip->apb_regs);
- }
-
-+ if (flags & AXI_DMA_FLAG_HAS_RESETS) {
-+ resets = devm_reset_control_array_get_exclusive(&pdev->dev);
-+ if (IS_ERR(resets))
-+ return PTR_ERR(resets);
-+
-+ ret = reset_control_deassert(resets);
-+ if (ret)
-+ return ret;
-+ }
-+
-+ chip->dw->hdata->use_cfg2 = !!(flags & AXI_DMA_FLAG_USE_CFG2);
-+
- chip->core_clk = devm_clk_get(chip->dev, "core-clk");
- if (IS_ERR(chip->core_clk))
- return PTR_ERR(chip->core_clk);
-@@ -1554,8 +1575,15 @@ static const struct dev_pm_ops dw_axi_dm
- };
-
- static const struct of_device_id dw_dma_of_id_table[] = {
-- { .compatible = "snps,axi-dma-1.01a" },
-- { .compatible = "intel,kmb-axi-dma" },
-+ {
-+ .compatible = "snps,axi-dma-1.01a"
-+ }, {
-+ .compatible = "intel,kmb-axi-dma",
-+ .data = (void *)AXI_DMA_FLAG_HAS_APB_REGS,
-+ }, {
-+ .compatible = "starfive,jh7110-axi-dma",
-+ .data = (void *)(AXI_DMA_FLAG_HAS_RESETS | AXI_DMA_FLAG_USE_CFG2),
-+ },
- {}
- };
- MODULE_DEVICE_TABLE(of, dw_dma_of_id_table);
---- a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
-+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
-@@ -33,6 +33,7 @@ struct dw_axi_dma_hcfg {
- /* Register map for DMAX_NUM_CHANNELS <= 8 */
- bool reg_map_8_channels;
- bool restrict_axi_burst_len;
-+ bool use_cfg2;
- };
-
- struct axi_dma_chan {
diff --git a/target/linux/starfive/patches-6.1/0113-dmaengine-dw-axi-dmac-Increase-polling-time-to-DMA-t.patch b/target/linux/starfive/patches-6.1/0113-dmaengine-dw-axi-dmac-Increase-polling-time-to-DMA-t.patch
deleted file mode 100644
index 30f4abd798..0000000000
--- a/target/linux/starfive/patches-6.1/0113-dmaengine-dw-axi-dmac-Increase-polling-time-to-DMA-t.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From 92c2dc96af79b2f181cc97157ce3ef2be5b48f4c Mon Sep 17 00:00:00 2001
-From: Walker Chen <walker.chen@starfivetech.com>
-Date: Wed, 22 Mar 2023 17:48:19 +0800
-Subject: [PATCH 113/122] dmaengine: dw-axi-dmac: Increase polling time to DMA
- transmission completion status
-
-The bit DMAC_CHEN[0] is automatically cleared by hardware to disable the
-channel after the last AMBA transfer of the DMA transfer to the
-destination has completed. Software can therefore poll this bit to
-determine when this channel is free for a new DMA transfer.
-This time requires at least 40 milliseconds on JH7110 SoC, otherwise an
-error message 'failed to stop' will be reported.
-
-Signed-off-by: Walker Chen <walker.chen@starfivetech.com>
----
- drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
-+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
-@@ -1145,7 +1145,7 @@ static int dma_chan_terminate_all(struct
- axi_chan_disable(chan);
-
- ret = readl_poll_timeout_atomic(chan->chip->regs + DMAC_CHEN, val,
-- !(val & chan_active), 1000, 10000);
-+ !(val & chan_active), 1000, 50000);
- if (ret == -ETIMEDOUT)
- dev_warn(dchan2dev(dchan),
- "%s failed to stop\n", axi_chan_name(chan));
diff --git a/target/linux/starfive/patches-6.1/0114-RISC-V-Change-suspend_save_csrs-and-suspend_restore_.patch b/target/linux/starfive/patches-6.1/0114-RISC-V-Change-suspend_save_csrs-and-suspend_restore_.patch
deleted file mode 100644
index 6c4745462a..0000000000
--- a/target/linux/starfive/patches-6.1/0114-RISC-V-Change-suspend_save_csrs-and-suspend_restore_.patch
+++ /dev/null
@@ -1,50 +0,0 @@
-From ba1b6ccbf68183b0d9e633ef930c7974144c7b56 Mon Sep 17 00:00:00 2001
-From: Sia Jee Heng <jeeheng.sia@starfivetech.com>
-Date: Thu, 30 Mar 2023 14:43:18 +0800
-Subject: [PATCH 114/122] RISC-V: Change suspend_save_csrs and
- suspend_restore_csrs to public function
-
-Currently suspend_save_csrs() and suspend_restore_csrs() functions are
-statically defined in the suspend.c. Change the function's attribute
-to public so that the functions can be used by hibernation as well.
-
-Signed-off-by: Sia Jee Heng <jeeheng.sia@starfivetech.com>
-Reviewed-by: Ley Foon Tan <leyfoon.tan@starfivetech.com>
-Reviewed-by: Mason Huo <mason.huo@starfivetech.com>
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
-Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
----
- arch/riscv/include/asm/suspend.h | 3 +++
- arch/riscv/kernel/suspend.c | 4 ++--
- 2 files changed, 5 insertions(+), 2 deletions(-)
-
---- a/arch/riscv/include/asm/suspend.h
-+++ b/arch/riscv/include/asm/suspend.h
-@@ -33,4 +33,7 @@ int cpu_suspend(unsigned long arg,
- /* Low-level CPU resume entry function */
- int __cpu_resume_enter(unsigned long hartid, unsigned long context);
-
-+/* Used to save and restore the CSRs */
-+void suspend_save_csrs(struct suspend_context *context);
-+void suspend_restore_csrs(struct suspend_context *context);
- #endif
---- a/arch/riscv/kernel/suspend.c
-+++ b/arch/riscv/kernel/suspend.c
-@@ -8,7 +8,7 @@
- #include <asm/csr.h>
- #include <asm/suspend.h>
-
--static void suspend_save_csrs(struct suspend_context *context)
-+void suspend_save_csrs(struct suspend_context *context)
- {
- context->scratch = csr_read(CSR_SCRATCH);
- context->tvec = csr_read(CSR_TVEC);
-@@ -29,7 +29,7 @@ static void suspend_save_csrs(struct sus
- #endif
- }
-
--static void suspend_restore_csrs(struct suspend_context *context)
-+void suspend_restore_csrs(struct suspend_context *context)
- {
- csr_write(CSR_SCRATCH, context->scratch);
- csr_write(CSR_TVEC, context->tvec);
diff --git a/target/linux/starfive/patches-6.1/0115-RISC-V-Factor-out-common-code-of-__cpu_resume_enter.patch b/target/linux/starfive/patches-6.1/0115-RISC-V-Factor-out-common-code-of-__cpu_resume_enter.patch
deleted file mode 100644
index ccdb77b05c..0000000000
--- a/target/linux/starfive/patches-6.1/0115-RISC-V-Factor-out-common-code-of-__cpu_resume_enter.patch
+++ /dev/null
@@ -1,136 +0,0 @@
-From f0e2b8f9bb240d7391d3eeca55534160fd385ea8 Mon Sep 17 00:00:00 2001
-From: Sia Jee Heng <jeeheng.sia@starfivetech.com>
-Date: Thu, 30 Mar 2023 14:43:19 +0800
-Subject: [PATCH 115/122] RISC-V: Factor out common code of
- __cpu_resume_enter()
-
-The cpu_resume() function is very similar for the suspend to disk and
-suspend to ram cases. Factor out the common code into suspend_restore_csrs
-macro and suspend_restore_regs macro.
-
-Signed-off-by: Sia Jee Heng <jeeheng.sia@starfivetech.com>
-Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
----
- arch/riscv/include/asm/assembler.h | 62 ++++++++++++++++++++++++++++++
- arch/riscv/kernel/suspend_entry.S | 34 ++--------------
- 2 files changed, 65 insertions(+), 31 deletions(-)
- create mode 100644 arch/riscv/include/asm/assembler.h
-
---- /dev/null
-+++ b/arch/riscv/include/asm/assembler.h
-@@ -0,0 +1,62 @@
-+/* SPDX-License-Identifier: GPL-2.0-only */
-+/*
-+ * Copyright (C) 2023 StarFive Technology Co., Ltd.
-+ *
-+ * Author: Jee Heng Sia <jeeheng.sia@starfivetech.com>
-+ */
-+
-+#ifndef __ASSEMBLY__
-+#error "Only include this from assembly code"
-+#endif
-+
-+#ifndef __ASM_ASSEMBLER_H
-+#define __ASM_ASSEMBLER_H
-+
-+#include <asm/asm.h>
-+#include <asm/asm-offsets.h>
-+#include <asm/csr.h>
-+
-+/*
-+ * suspend_restore_csrs - restore CSRs
-+ */
-+ .macro suspend_restore_csrs
-+ REG_L t0, (SUSPEND_CONTEXT_REGS + PT_EPC)(a0)
-+ csrw CSR_EPC, t0
-+ REG_L t0, (SUSPEND_CONTEXT_REGS + PT_STATUS)(a0)
-+ csrw CSR_STATUS, t0
-+ REG_L t0, (SUSPEND_CONTEXT_REGS + PT_BADADDR)(a0)
-+ csrw CSR_TVAL, t0
-+ REG_L t0, (SUSPEND_CONTEXT_REGS + PT_CAUSE)(a0)
-+ csrw CSR_CAUSE, t0
-+ .endm
-+
-+/*
-+ * suspend_restore_regs - Restore registers (except A0 and T0-T6)
-+ */
-+ .macro suspend_restore_regs
-+ REG_L ra, (SUSPEND_CONTEXT_REGS + PT_RA)(a0)
-+ REG_L sp, (SUSPEND_CONTEXT_REGS + PT_SP)(a0)
-+ REG_L gp, (SUSPEND_CONTEXT_REGS + PT_GP)(a0)
-+ REG_L tp, (SUSPEND_CONTEXT_REGS + PT_TP)(a0)
-+ REG_L s0, (SUSPEND_CONTEXT_REGS + PT_S0)(a0)
-+ REG_L s1, (SUSPEND_CONTEXT_REGS + PT_S1)(a0)
-+ REG_L a1, (SUSPEND_CONTEXT_REGS + PT_A1)(a0)
-+ REG_L a2, (SUSPEND_CONTEXT_REGS + PT_A2)(a0)
-+ REG_L a3, (SUSPEND_CONTEXT_REGS + PT_A3)(a0)
-+ REG_L a4, (SUSPEND_CONTEXT_REGS + PT_A4)(a0)
-+ REG_L a5, (SUSPEND_CONTEXT_REGS + PT_A5)(a0)
-+ REG_L a6, (SUSPEND_CONTEXT_REGS + PT_A6)(a0)
-+ REG_L a7, (SUSPEND_CONTEXT_REGS + PT_A7)(a0)
-+ REG_L s2, (SUSPEND_CONTEXT_REGS + PT_S2)(a0)
-+ REG_L s3, (SUSPEND_CONTEXT_REGS + PT_S3)(a0)
-+ REG_L s4, (SUSPEND_CONTEXT_REGS + PT_S4)(a0)
-+ REG_L s5, (SUSPEND_CONTEXT_REGS + PT_S5)(a0)
-+ REG_L s6, (SUSPEND_CONTEXT_REGS + PT_S6)(a0)
-+ REG_L s7, (SUSPEND_CONTEXT_REGS + PT_S7)(a0)
-+ REG_L s8, (SUSPEND_CONTEXT_REGS + PT_S8)(a0)
-+ REG_L s9, (SUSPEND_CONTEXT_REGS + PT_S9)(a0)
-+ REG_L s10, (SUSPEND_CONTEXT_REGS + PT_S10)(a0)
-+ REG_L s11, (SUSPEND_CONTEXT_REGS + PT_S11)(a0)
-+ .endm
-+
-+#endif /* __ASM_ASSEMBLER_H */
---- a/arch/riscv/kernel/suspend_entry.S
-+++ b/arch/riscv/kernel/suspend_entry.S
-@@ -7,6 +7,7 @@
- #include <linux/linkage.h>
- #include <asm/asm.h>
- #include <asm/asm-offsets.h>
-+#include <asm/assembler.h>
- #include <asm/csr.h>
- #include <asm/xip_fixup.h>
-
-@@ -83,39 +84,10 @@ ENTRY(__cpu_resume_enter)
- add a0, a1, zero
-
- /* Restore CSRs */
-- REG_L t0, (SUSPEND_CONTEXT_REGS + PT_EPC)(a0)
-- csrw CSR_EPC, t0
-- REG_L t0, (SUSPEND_CONTEXT_REGS + PT_STATUS)(a0)
-- csrw CSR_STATUS, t0
-- REG_L t0, (SUSPEND_CONTEXT_REGS + PT_BADADDR)(a0)
-- csrw CSR_TVAL, t0
-- REG_L t0, (SUSPEND_CONTEXT_REGS + PT_CAUSE)(a0)
-- csrw CSR_CAUSE, t0
-+ suspend_restore_csrs
-
- /* Restore registers (except A0 and T0-T6) */
-- REG_L ra, (SUSPEND_CONTEXT_REGS + PT_RA)(a0)
-- REG_L sp, (SUSPEND_CONTEXT_REGS + PT_SP)(a0)
-- REG_L gp, (SUSPEND_CONTEXT_REGS + PT_GP)(a0)
-- REG_L tp, (SUSPEND_CONTEXT_REGS + PT_TP)(a0)
-- REG_L s0, (SUSPEND_CONTEXT_REGS + PT_S0)(a0)
-- REG_L s1, (SUSPEND_CONTEXT_REGS + PT_S1)(a0)
-- REG_L a1, (SUSPEND_CONTEXT_REGS + PT_A1)(a0)
-- REG_L a2, (SUSPEND_CONTEXT_REGS + PT_A2)(a0)
-- REG_L a3, (SUSPEND_CONTEXT_REGS + PT_A3)(a0)
-- REG_L a4, (SUSPEND_CONTEXT_REGS + PT_A4)(a0)
-- REG_L a5, (SUSPEND_CONTEXT_REGS + PT_A5)(a0)
-- REG_L a6, (SUSPEND_CONTEXT_REGS + PT_A6)(a0)
-- REG_L a7, (SUSPEND_CONTEXT_REGS + PT_A7)(a0)
-- REG_L s2, (SUSPEND_CONTEXT_REGS + PT_S2)(a0)
-- REG_L s3, (SUSPEND_CONTEXT_REGS + PT_S3)(a0)
-- REG_L s4, (SUSPEND_CONTEXT_REGS + PT_S4)(a0)
-- REG_L s5, (SUSPEND_CONTEXT_REGS + PT_S5)(a0)
-- REG_L s6, (SUSPEND_CONTEXT_REGS + PT_S6)(a0)
-- REG_L s7, (SUSPEND_CONTEXT_REGS + PT_S7)(a0)
-- REG_L s8, (SUSPEND_CONTEXT_REGS + PT_S8)(a0)
-- REG_L s9, (SUSPEND_CONTEXT_REGS + PT_S9)(a0)
-- REG_L s10, (SUSPEND_CONTEXT_REGS + PT_S10)(a0)
-- REG_L s11, (SUSPEND_CONTEXT_REGS + PT_S11)(a0)
-+ suspend_restore_regs
-
- /* Return zero value */
- add a0, zero, zero
diff --git a/target/linux/starfive/patches-6.1/0116-RISC-V-Add-arch-functions-to-support-hibernation-sus.patch b/target/linux/starfive/patches-6.1/0116-RISC-V-Add-arch-functions-to-support-hibernation-sus.patch
deleted file mode 100644
index a47c49d968..0000000000
--- a/target/linux/starfive/patches-6.1/0116-RISC-V-Add-arch-functions-to-support-hibernation-sus.patch
+++ /dev/null
@@ -1,673 +0,0 @@
-From 06f1d699e923c3f09869439cdb603e36302c2611 Mon Sep 17 00:00:00 2001
-From: Sia Jee Heng <jeeheng.sia@starfivetech.com>
-Date: Thu, 30 Mar 2023 14:43:21 +0800
-Subject: [PATCH 116/122] RISC-V: Add arch functions to support
- hibernation/suspend-to-disk
-
-Low level Arch functions were created to support hibernation.
-swsusp_arch_suspend() relies code from __cpu_suspend_enter() to write
-cpu state onto the stack, then calling swsusp_save() to save the memory
-image.
-
-Arch specific hibernation header is implemented and is utilized by the
-arch_hibernation_header_restore() and arch_hibernation_header_save()
-functions. The arch specific hibernation header consists of satp, hartid,
-and the cpu_resume address. The kernel built version is also need to be
-saved into the hibernation image header to making sure only the same
-kernel is restore when resume.
-
-swsusp_arch_resume() creates a temporary page table that covering only
-the linear map. It copies the restore code to a 'safe' page, then start
-to restore the memory image. Once completed, it restores the original
-kernel's page table. It then calls into __hibernate_cpu_resume()
-to restore the CPU context. Finally, it follows the normal hibernation
-path back to the hibernation core.
-
-To enable hibernation/suspend to disk into RISCV, the below config
-need to be enabled:
-- CONFIG_HIBERNATION
-- CONFIG_ARCH_HIBERNATION_HEADER
-- CONFIG_ARCH_HIBERNATION_POSSIBLE
-
-Signed-off-by: Sia Jee Heng <jeeheng.sia@starfivetech.com>
-Reviewed-by: Ley Foon Tan <leyfoon.tan@starfivetech.com>
-Reviewed-by: Mason Huo <mason.huo@starfivetech.com>
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
-Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
----
- arch/riscv/Kconfig | 8 +-
- arch/riscv/include/asm/assembler.h | 20 ++
- arch/riscv/include/asm/suspend.h | 19 ++
- arch/riscv/kernel/Makefile | 1 +
- arch/riscv/kernel/asm-offsets.c | 5 +
- arch/riscv/kernel/hibernate-asm.S | 77 ++++++
- arch/riscv/kernel/hibernate.c | 427 +++++++++++++++++++++++++++++
- 7 files changed, 556 insertions(+), 1 deletion(-)
- create mode 100644 arch/riscv/kernel/hibernate-asm.S
- create mode 100644 arch/riscv/kernel/hibernate.c
-
---- a/arch/riscv/Kconfig
-+++ b/arch/riscv/Kconfig
-@@ -52,7 +52,7 @@ config RISCV
- select CLONE_BACKWARDS
- select CLINT_TIMER if !MMU
- select COMMON_CLK
-- select CPU_PM if CPU_IDLE
-+ select CPU_PM if CPU_IDLE || HIBERNATION
- select EDAC_SUPPORT
- select GENERIC_ARCH_TOPOLOGY
- select GENERIC_ATOMIC64 if !64BIT
-@@ -715,6 +715,12 @@ menu "Power management options"
-
- source "kernel/power/Kconfig"
-
-+config ARCH_HIBERNATION_POSSIBLE
-+ def_bool y
-+
-+config ARCH_HIBERNATION_HEADER
-+ def_bool HIBERNATION
-+
- endmenu # "Power management options"
-
- menu "CPU Power Management"
---- a/arch/riscv/include/asm/assembler.h
-+++ b/arch/riscv/include/asm/assembler.h
-@@ -59,4 +59,24 @@
- REG_L s11, (SUSPEND_CONTEXT_REGS + PT_S11)(a0)
- .endm
-
-+/*
-+ * copy_page - copy 1 page (4KB) of data from source to destination
-+ * @a0 - destination
-+ * @a1 - source
-+ */
-+ .macro copy_page a0, a1
-+ lui a2, 0x1
-+ add a2, a2, a0
-+1 :
-+ REG_L t0, 0(a1)
-+ REG_L t1, SZREG(a1)
-+
-+ REG_S t0, 0(a0)
-+ REG_S t1, SZREG(a0)
-+
-+ addi a0, a0, 2 * SZREG
-+ addi a1, a1, 2 * SZREG
-+ bne a2, a0, 1b
-+ .endm
-+
- #endif /* __ASM_ASSEMBLER_H */
---- a/arch/riscv/include/asm/suspend.h
-+++ b/arch/riscv/include/asm/suspend.h
-@@ -21,6 +21,11 @@ struct suspend_context {
- #endif
- };
-
-+/*
-+ * Used by hibernation core and cleared during resume sequence
-+ */
-+extern int in_suspend;
-+
- /* Low-level CPU suspend entry function */
- int __cpu_suspend_enter(struct suspend_context *context);
-
-@@ -36,4 +41,18 @@ int __cpu_resume_enter(unsigned long har
- /* Used to save and restore the CSRs */
- void suspend_save_csrs(struct suspend_context *context);
- void suspend_restore_csrs(struct suspend_context *context);
-+
-+/* Low-level API to support hibernation */
-+int swsusp_arch_suspend(void);
-+int swsusp_arch_resume(void);
-+int arch_hibernation_header_save(void *addr, unsigned int max_size);
-+int arch_hibernation_header_restore(void *addr);
-+int __hibernate_cpu_resume(void);
-+
-+/* Used to resume on the CPU we hibernated on */
-+int hibernate_resume_nonboot_cpu_disable(void);
-+
-+asmlinkage void hibernate_restore_image(unsigned long resume_satp, unsigned long satp_temp,
-+ unsigned long cpu_resume);
-+asmlinkage int hibernate_core_restore_code(void);
- #endif
---- a/arch/riscv/kernel/Makefile
-+++ b/arch/riscv/kernel/Makefile
-@@ -67,6 +67,7 @@ obj-$(CONFIG_MODULES) += module.o
- obj-$(CONFIG_MODULE_SECTIONS) += module-sections.o
-
- obj-$(CONFIG_CPU_PM) += suspend_entry.o suspend.o
-+obj-$(CONFIG_HIBERNATION) += hibernate.o hibernate-asm.o
-
- obj-$(CONFIG_FUNCTION_TRACER) += mcount.o ftrace.o
- obj-$(CONFIG_DYNAMIC_FTRACE) += mcount-dyn.o
---- a/arch/riscv/kernel/asm-offsets.c
-+++ b/arch/riscv/kernel/asm-offsets.c
-@@ -9,6 +9,7 @@
- #include <linux/kbuild.h>
- #include <linux/mm.h>
- #include <linux/sched.h>
-+#include <linux/suspend.h>
- #include <asm/kvm_host.h>
- #include <asm/thread_info.h>
- #include <asm/ptrace.h>
-@@ -116,6 +117,10 @@ void asm_offsets(void)
-
- OFFSET(SUSPEND_CONTEXT_REGS, suspend_context, regs);
-
-+ OFFSET(HIBERN_PBE_ADDR, pbe, address);
-+ OFFSET(HIBERN_PBE_ORIG, pbe, orig_address);
-+ OFFSET(HIBERN_PBE_NEXT, pbe, next);
-+
- OFFSET(KVM_ARCH_GUEST_ZERO, kvm_vcpu_arch, guest_context.zero);
- OFFSET(KVM_ARCH_GUEST_RA, kvm_vcpu_arch, guest_context.ra);
- OFFSET(KVM_ARCH_GUEST_SP, kvm_vcpu_arch, guest_context.sp);
---- /dev/null
-+++ b/arch/riscv/kernel/hibernate-asm.S
-@@ -0,0 +1,77 @@
-+/* SPDX-License-Identifier: GPL-2.0-only */
-+/*
-+ * Hibernation low level support for RISCV.
-+ *
-+ * Copyright (C) 2023 StarFive Technology Co., Ltd.
-+ *
-+ * Author: Jee Heng Sia <jeeheng.sia@starfivetech.com>
-+ */
-+
-+#include <asm/asm.h>
-+#include <asm/asm-offsets.h>
-+#include <asm/assembler.h>
-+#include <asm/csr.h>
-+
-+#include <linux/linkage.h>
-+
-+/*
-+ * int __hibernate_cpu_resume(void)
-+ * Switch back to the hibernated image's page table prior to restoring the CPU
-+ * context.
-+ *
-+ * Always returns 0
-+ */
-+ENTRY(__hibernate_cpu_resume)
-+ /* switch to hibernated image's page table. */
-+ csrw CSR_SATP, s0
-+ sfence.vma
-+
-+ REG_L a0, hibernate_cpu_context
-+
-+ suspend_restore_csrs
-+ suspend_restore_regs
-+
-+ /* Return zero value. */
-+ mv a0, zero
-+
-+ ret
-+END(__hibernate_cpu_resume)
-+
-+/*
-+ * Prepare to restore the image.
-+ * a0: satp of saved page tables.
-+ * a1: satp of temporary page tables.
-+ * a2: cpu_resume.
-+ */
-+ENTRY(hibernate_restore_image)
-+ mv s0, a0
-+ mv s1, a1
-+ mv s2, a2
-+ REG_L s4, restore_pblist
-+ REG_L a1, relocated_restore_code
-+
-+ jalr a1
-+END(hibernate_restore_image)
-+
-+/*
-+ * The below code will be executed from a 'safe' page.
-+ * It first switches to the temporary page table, then starts to copy the pages
-+ * back to the original memory location. Finally, it jumps to __hibernate_cpu_resume()
-+ * to restore the CPU context.
-+ */
-+ENTRY(hibernate_core_restore_code)
-+ /* switch to temp page table. */
-+ csrw satp, s1
-+ sfence.vma
-+.Lcopy:
-+ /* The below code will restore the hibernated image. */
-+ REG_L a1, HIBERN_PBE_ADDR(s4)
-+ REG_L a0, HIBERN_PBE_ORIG(s4)
-+
-+ copy_page a0, a1
-+
-+ REG_L s4, HIBERN_PBE_NEXT(s4)
-+ bnez s4, .Lcopy
-+
-+ jalr s2
-+END(hibernate_core_restore_code)
---- /dev/null
-+++ b/arch/riscv/kernel/hibernate.c
-@@ -0,0 +1,427 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+/*
-+ * Hibernation support for RISCV
-+ *
-+ * Copyright (C) 2023 StarFive Technology Co., Ltd.
-+ *
-+ * Author: Jee Heng Sia <jeeheng.sia@starfivetech.com>
-+ */
-+
-+#include <asm/barrier.h>
-+#include <asm/cacheflush.h>
-+#include <asm/mmu_context.h>
-+#include <asm/page.h>
-+#include <asm/pgalloc.h>
-+#include <asm/pgtable.h>
-+#include <asm/sections.h>
-+#include <asm/set_memory.h>
-+#include <asm/smp.h>
-+#include <asm/suspend.h>
-+
-+#include <linux/cpu.h>
-+#include <linux/memblock.h>
-+#include <linux/pm.h>
-+#include <linux/sched.h>
-+#include <linux/suspend.h>
-+#include <linux/utsname.h>
-+
-+/* The logical cpu number we should resume on, initialised to a non-cpu number. */
-+static int sleep_cpu = -EINVAL;
-+
-+/* Pointer to the temporary resume page table. */
-+static pgd_t *resume_pg_dir;
-+
-+/* CPU context to be saved. */
-+struct suspend_context *hibernate_cpu_context;
-+EXPORT_SYMBOL_GPL(hibernate_cpu_context);
-+
-+unsigned long relocated_restore_code;
-+EXPORT_SYMBOL_GPL(relocated_restore_code);
-+
-+/**
-+ * struct arch_hibernate_hdr_invariants - container to store kernel build version.
-+ * @uts_version: to save the build number and date so that we do not resume with
-+ * a different kernel.
-+ */
-+struct arch_hibernate_hdr_invariants {
-+ char uts_version[__NEW_UTS_LEN + 1];
-+};
-+
-+/**
-+ * struct arch_hibernate_hdr - helper parameters that help us to restore the image.
-+ * @invariants: container to store kernel build version.
-+ * @hartid: to make sure same boot_cpu executes the hibernate/restore code.
-+ * @saved_satp: original page table used by the hibernated image.
-+ * @restore_cpu_addr: the kernel's image address to restore the CPU context.
-+ */
-+static struct arch_hibernate_hdr {
-+ struct arch_hibernate_hdr_invariants invariants;
-+ unsigned long hartid;
-+ unsigned long saved_satp;
-+ unsigned long restore_cpu_addr;
-+} resume_hdr;
-+
-+static void arch_hdr_invariants(struct arch_hibernate_hdr_invariants *i)
-+{
-+ memset(i, 0, sizeof(*i));
-+ memcpy(i->uts_version, init_utsname()->version, sizeof(i->uts_version));
-+}
-+
-+/*
-+ * Check if the given pfn is in the 'nosave' section.
-+ */
-+int pfn_is_nosave(unsigned long pfn)
-+{
-+ unsigned long nosave_begin_pfn = sym_to_pfn(&__nosave_begin);
-+ unsigned long nosave_end_pfn = sym_to_pfn(&__nosave_end - 1);
-+
-+ return ((pfn >= nosave_begin_pfn) && (pfn <= nosave_end_pfn));
-+}
-+
-+void notrace save_processor_state(void)
-+{
-+ WARN_ON(num_online_cpus() != 1);
-+}
-+
-+void notrace restore_processor_state(void)
-+{
-+}
-+
-+/*
-+ * Helper parameters need to be saved to the hibernation image header.
-+ */
-+int arch_hibernation_header_save(void *addr, unsigned int max_size)
-+{
-+ struct arch_hibernate_hdr *hdr = addr;
-+
-+ if (max_size < sizeof(*hdr))
-+ return -EOVERFLOW;
-+
-+ arch_hdr_invariants(&hdr->invariants);
-+
-+ hdr->hartid = cpuid_to_hartid_map(sleep_cpu);
-+ hdr->saved_satp = csr_read(CSR_SATP);
-+ hdr->restore_cpu_addr = (unsigned long)__hibernate_cpu_resume;
-+
-+ return 0;
-+}
-+EXPORT_SYMBOL_GPL(arch_hibernation_header_save);
-+
-+/*
-+ * Retrieve the helper parameters from the hibernation image header.
-+ */
-+int arch_hibernation_header_restore(void *addr)
-+{
-+ struct arch_hibernate_hdr_invariants invariants;
-+ struct arch_hibernate_hdr *hdr = addr;
-+ int ret = 0;
-+
-+ arch_hdr_invariants(&invariants);
-+
-+ if (memcmp(&hdr->invariants, &invariants, sizeof(invariants))) {
-+ pr_crit("Hibernate image not generated by this kernel!\n");
-+ return -EINVAL;
-+ }
-+
-+ sleep_cpu = riscv_hartid_to_cpuid(hdr->hartid);
-+ if (sleep_cpu < 0) {
-+ pr_crit("Hibernated on a CPU not known to this kernel!\n");
-+ sleep_cpu = -EINVAL;
-+ return -EINVAL;
-+ }
-+
-+#ifdef CONFIG_SMP
-+ ret = bringup_hibernate_cpu(sleep_cpu);
-+ if (ret) {
-+ sleep_cpu = -EINVAL;
-+ return ret;
-+ }
-+#endif
-+ resume_hdr = *hdr;
-+
-+ return ret;
-+}
-+EXPORT_SYMBOL_GPL(arch_hibernation_header_restore);
-+
-+int swsusp_arch_suspend(void)
-+{
-+ int ret = 0;
-+
-+ if (__cpu_suspend_enter(hibernate_cpu_context)) {
-+ sleep_cpu = smp_processor_id();
-+ suspend_save_csrs(hibernate_cpu_context);
-+ ret = swsusp_save();
-+ } else {
-+ suspend_restore_csrs(hibernate_cpu_context);
-+ flush_tlb_all();
-+ flush_icache_all();
-+
-+ /*
-+ * Tell the hibernation core that we've just restored the memory.
-+ */
-+ in_suspend = 0;
-+ sleep_cpu = -EINVAL;
-+ }
-+
-+ return ret;
-+}
-+
-+static int temp_pgtable_map_pte(pmd_t *dst_pmdp, pmd_t *src_pmdp, unsigned long start,
-+ unsigned long end, pgprot_t prot)
-+{
-+ pte_t *src_ptep;
-+ pte_t *dst_ptep;
-+
-+ if (pmd_none(READ_ONCE(*dst_pmdp))) {
-+ dst_ptep = (pte_t *)get_safe_page(GFP_ATOMIC);
-+ if (!dst_ptep)
-+ return -ENOMEM;
-+
-+ pmd_populate_kernel(NULL, dst_pmdp, dst_ptep);
-+ }
-+
-+ dst_ptep = pte_offset_kernel(dst_pmdp, start);
-+ src_ptep = pte_offset_kernel(src_pmdp, start);
-+
-+ do {
-+ pte_t pte = READ_ONCE(*src_ptep);
-+
-+ if (pte_present(pte))
-+ set_pte(dst_ptep, __pte(pte_val(pte) | pgprot_val(prot)));
-+ } while (dst_ptep++, src_ptep++, start += PAGE_SIZE, start < end);
-+
-+ return 0;
-+}
-+
-+static int temp_pgtable_map_pmd(pud_t *dst_pudp, pud_t *src_pudp, unsigned long start,
-+ unsigned long end, pgprot_t prot)
-+{
-+ unsigned long next;
-+ unsigned long ret;
-+ pmd_t *src_pmdp;
-+ pmd_t *dst_pmdp;
-+
-+ if (pud_none(READ_ONCE(*dst_pudp))) {
-+ dst_pmdp = (pmd_t *)get_safe_page(GFP_ATOMIC);
-+ if (!dst_pmdp)
-+ return -ENOMEM;
-+
-+ pud_populate(NULL, dst_pudp, dst_pmdp);
-+ }
-+
-+ dst_pmdp = pmd_offset(dst_pudp, start);
-+ src_pmdp = pmd_offset(src_pudp, start);
-+
-+ do {
-+ pmd_t pmd = READ_ONCE(*src_pmdp);
-+
-+ next = pmd_addr_end(start, end);
-+
-+ if (pmd_none(pmd))
-+ continue;
-+
-+ if (pmd_leaf(pmd)) {
-+ set_pmd(dst_pmdp, __pmd(pmd_val(pmd) | pgprot_val(prot)));
-+ } else {
-+ ret = temp_pgtable_map_pte(dst_pmdp, src_pmdp, start, next, prot);
-+ if (ret)
-+ return -ENOMEM;
-+ }
-+ } while (dst_pmdp++, src_pmdp++, start = next, start != end);
-+
-+ return 0;
-+}
-+
-+static int temp_pgtable_map_pud(p4d_t *dst_p4dp, p4d_t *src_p4dp, unsigned long start,
-+ unsigned long end, pgprot_t prot)
-+{
-+ unsigned long next;
-+ unsigned long ret;
-+ pud_t *dst_pudp;
-+ pud_t *src_pudp;
-+
-+ if (p4d_none(READ_ONCE(*dst_p4dp))) {
-+ dst_pudp = (pud_t *)get_safe_page(GFP_ATOMIC);
-+ if (!dst_pudp)
-+ return -ENOMEM;
-+
-+ p4d_populate(NULL, dst_p4dp, dst_pudp);
-+ }
-+
-+ dst_pudp = pud_offset(dst_p4dp, start);
-+ src_pudp = pud_offset(src_p4dp, start);
-+
-+ do {
-+ pud_t pud = READ_ONCE(*src_pudp);
-+
-+ next = pud_addr_end(start, end);
-+
-+ if (pud_none(pud))
-+ continue;
-+
-+ if (pud_leaf(pud)) {
-+ set_pud(dst_pudp, __pud(pud_val(pud) | pgprot_val(prot)));
-+ } else {
-+ ret = temp_pgtable_map_pmd(dst_pudp, src_pudp, start, next, prot);
-+ if (ret)
-+ return -ENOMEM;
-+ }
-+ } while (dst_pudp++, src_pudp++, start = next, start != end);
-+
-+ return 0;
-+}
-+
-+static int temp_pgtable_map_p4d(pgd_t *dst_pgdp, pgd_t *src_pgdp, unsigned long start,
-+ unsigned long end, pgprot_t prot)
-+{
-+ unsigned long next;
-+ unsigned long ret;
-+ p4d_t *dst_p4dp;
-+ p4d_t *src_p4dp;
-+
-+ if (pgd_none(READ_ONCE(*dst_pgdp))) {
-+ dst_p4dp = (p4d_t *)get_safe_page(GFP_ATOMIC);
-+ if (!dst_p4dp)
-+ return -ENOMEM;
-+
-+ pgd_populate(NULL, dst_pgdp, dst_p4dp);
-+ }
-+
-+ dst_p4dp = p4d_offset(dst_pgdp, start);
-+ src_p4dp = p4d_offset(src_pgdp, start);
-+
-+ do {
-+ p4d_t p4d = READ_ONCE(*src_p4dp);
-+
-+ next = p4d_addr_end(start, end);
-+
-+ if (p4d_none(p4d))
-+ continue;
-+
-+ if (p4d_leaf(p4d)) {
-+ set_p4d(dst_p4dp, __p4d(p4d_val(p4d) | pgprot_val(prot)));
-+ } else {
-+ ret = temp_pgtable_map_pud(dst_p4dp, src_p4dp, start, next, prot);
-+ if (ret)
-+ return -ENOMEM;
-+ }
-+ } while (dst_p4dp++, src_p4dp++, start = next, start != end);
-+
-+ return 0;
-+}
-+
-+static int temp_pgtable_mapping(pgd_t *pgdp, unsigned long start, unsigned long end, pgprot_t prot)
-+{
-+ pgd_t *dst_pgdp = pgd_offset_pgd(pgdp, start);
-+ pgd_t *src_pgdp = pgd_offset_k(start);
-+ unsigned long next;
-+ unsigned long ret;
-+
-+ do {
-+ pgd_t pgd = READ_ONCE(*src_pgdp);
-+
-+ next = pgd_addr_end(start, end);
-+
-+ if (pgd_none(pgd))
-+ continue;
-+
-+ if (pgd_leaf(pgd)) {
-+ set_pgd(dst_pgdp, __pgd(pgd_val(pgd) | pgprot_val(prot)));
-+ } else {
-+ ret = temp_pgtable_map_p4d(dst_pgdp, src_pgdp, start, next, prot);
-+ if (ret)
-+ return -ENOMEM;
-+ }
-+ } while (dst_pgdp++, src_pgdp++, start = next, start != end);
-+
-+ return 0;
-+}
-+
-+static unsigned long relocate_restore_code(void)
-+{
-+ void *page = (void *)get_safe_page(GFP_ATOMIC);
-+
-+ if (!page)
-+ return -ENOMEM;
-+
-+ copy_page(page, hibernate_core_restore_code);
-+
-+ /* Make the page containing the relocated code executable. */
-+ set_memory_x((unsigned long)page, 1);
-+
-+ return (unsigned long)page;
-+}
-+
-+int swsusp_arch_resume(void)
-+{
-+ unsigned long end = (unsigned long)pfn_to_virt(max_low_pfn);
-+ unsigned long start = PAGE_OFFSET;
-+ int ret;
-+
-+ /*
-+ * Memory allocated by get_safe_page() will be dealt with by the hibernation core,
-+ * we don't need to free it here.
-+ */
-+ resume_pg_dir = (pgd_t *)get_safe_page(GFP_ATOMIC);
-+ if (!resume_pg_dir)
-+ return -ENOMEM;
-+
-+ /*
-+ * Create a temporary page table and map the whole linear region as executable and
-+ * writable.
-+ */
-+ ret = temp_pgtable_mapping(resume_pg_dir, start, end, __pgprot(_PAGE_WRITE | _PAGE_EXEC));
-+ if (ret)
-+ return ret;
-+
-+ /* Move the restore code to a new page so that it doesn't get overwritten by itself. */
-+ relocated_restore_code = relocate_restore_code();
-+ if (relocated_restore_code == -ENOMEM)
-+ return -ENOMEM;
-+
-+ /*
-+ * Map the __hibernate_cpu_resume() address to the temporary page table so that the
-+ * restore code can jumps to it after finished restore the image. The next execution
-+ * code doesn't find itself in a different address space after switching over to the
-+ * original page table used by the hibernated image.
-+ * The __hibernate_cpu_resume() mapping is unnecessary for RV32 since the kernel and
-+ * linear addresses are identical, but different for RV64. To ensure consistency, we
-+ * map it for both RV32 and RV64 kernels.
-+ * Additionally, we should ensure that the page is writable before restoring the image.
-+ */
-+ start = (unsigned long)resume_hdr.restore_cpu_addr;
-+ end = start + PAGE_SIZE;
-+
-+ ret = temp_pgtable_mapping(resume_pg_dir, start, end, __pgprot(_PAGE_WRITE));
-+ if (ret)
-+ return ret;
-+
-+ hibernate_restore_image(resume_hdr.saved_satp, (PFN_DOWN(__pa(resume_pg_dir)) | satp_mode),
-+ resume_hdr.restore_cpu_addr);
-+
-+ return 0;
-+}
-+
-+#ifdef CONFIG_PM_SLEEP_SMP
-+int hibernate_resume_nonboot_cpu_disable(void)
-+{
-+ if (sleep_cpu < 0) {
-+ pr_err("Failing to resume from hibernate on an unknown CPU\n");
-+ return -ENODEV;
-+ }
-+
-+ return freeze_secondary_cpus(sleep_cpu);
-+}
-+#endif
-+
-+static int __init riscv_hibernate_init(void)
-+{
-+ hibernate_cpu_context = kzalloc(sizeof(*hibernate_cpu_context), GFP_KERNEL);
-+
-+ if (WARN_ON(!hibernate_cpu_context))
-+ return -ENOMEM;
-+
-+ return 0;
-+}
-+
-+early_initcall(riscv_hibernate_init);
diff --git a/target/linux/starfive/patches-6.1/0119-riscv-dts-visionfive2-add-EEPROM-node.patch b/target/linux/starfive/patches-6.1/0119-riscv-dts-visionfive2-add-EEPROM-node.patch
deleted file mode 100644
index 8aec7fb7e5..0000000000
--- a/target/linux/starfive/patches-6.1/0119-riscv-dts-visionfive2-add-EEPROM-node.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From 6d91484ec63526def63be4097c28790f25d647b8 Mon Sep 17 00:00:00 2001
-From: Zoltan HERPAI <wigyori@uid0.hu>
-Date: Thu, 10 Aug 2023 23:23:15 +0200
-Subject: [PATCH 119/122] riscv: dts: visionfive2: add EEPROM node
-
-Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
----
- .../boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi | 6 ++++++
- 1 file changed, 6 insertions(+)
-
---- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
-+++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
-@@ -239,6 +239,12 @@
- pinctrl-0 = <&i2c5_pins>;
- status = "okay";
-
-+ eeprom@50 {
-+ compatible = "atmel,24c04";
-+ reg = <0x50>;
-+ pagesize = <16>;
-+ };
-+
- axp15060: pmic@36 {
- compatible = "x-powers,axp15060";
- reg = <0x36>;
diff --git a/target/linux/starfive/patches-6.1/0120-riscv-dts-visionfive2-add-mmc-aliases.patch b/target/linux/starfive/patches-6.1/0120-riscv-dts-visionfive2-add-mmc-aliases.patch
deleted file mode 100644
index e8067e1dcb..0000000000
--- a/target/linux/starfive/patches-6.1/0120-riscv-dts-visionfive2-add-mmc-aliases.patch
+++ /dev/null
@@ -1,21 +0,0 @@
-From aa5fcd525c1a01ca07a6fdb631dbd304e22c9669 Mon Sep 17 00:00:00 2001
-From: Zoltan HERPAI <wigyori@uid0.hu>
-Date: Thu, 10 Aug 2023 23:23:45 +0200
-Subject: [PATCH 120/122] riscv: dts: visionfive2: add mmc aliases
-
-Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
----
- arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
-+++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
-@@ -13,6 +13,8 @@
- aliases {
- ethernet0 = &gmac0;
- ethernet1 = &gmac1;
-+ mmc0 = &mmc0;
-+ mmc1 = &mmc1;
- i2c0 = &i2c0;
- i2c2 = &i2c2;
- i2c5 = &i2c5;
diff --git a/target/linux/starfive/patches-6.1/0121-drivers-include-cpufreq-Kconfig-for-riscv.patch b/target/linux/starfive/patches-6.1/0121-drivers-include-cpufreq-Kconfig-for-riscv.patch
deleted file mode 100644
index 231a844b41..0000000000
--- a/target/linux/starfive/patches-6.1/0121-drivers-include-cpufreq-Kconfig-for-riscv.patch
+++ /dev/null
@@ -1,21 +0,0 @@
-From 22b82c89dac3fadaa8c50760c25be7c78a2782a3 Mon Sep 17 00:00:00 2001
-From: Zoltan HERPAI <wigyori@uid0.hu>
-Date: Thu, 10 Aug 2023 23:42:13 +0200
-Subject: [PATCH] drivers: include cpufreq/Kconfig for riscv
-
-Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
----
- drivers/Kconfig | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/drivers/Kconfig
-+++ b/drivers/Kconfig
-@@ -237,6 +237,8 @@ source "drivers/most/Kconfig"
-
- source "drivers/peci/Kconfig"
-
-+source "drivers/cpufreq/Kconfig"
-+
- source "drivers/hte/Kconfig"
-
- endmenu
diff --git a/target/linux/starfive/patches-6.1/0126-clk-starfive-jh7110-sys-Fix-lower-rate-of-CPUfreq-by.patch b/target/linux/starfive/patches-6.1/0126-clk-starfive-jh7110-sys-Fix-lower-rate-of-CPUfreq-by.patch
deleted file mode 100644
index d057797bb2..0000000000
--- a/target/linux/starfive/patches-6.1/0126-clk-starfive-jh7110-sys-Fix-lower-rate-of-CPUfreq-by.patch
+++ /dev/null
@@ -1,92 +0,0 @@
-From 8a2d9c6decdbd042b3475d5ab69c1a79f0fd54aa Mon Sep 17 00:00:00 2001
-From: Xingyu Wu <xingyu.wu@starfivetech.com>
-Date: Mon, 21 Aug 2023 23:29:15 +0800
-Subject: [PATCH] clk: starfive: jh7110-sys: Fix lower rate of CPUfreq by
- setting PLL0 rate to 1.5GHz
-
-CPUfreq supports 4 cpu frequency loads on 375/500/750/1500MHz.
-But now PLL0 rate is 1GHz and the cpu frequency loads become
-333/500/500/1000MHz in fact.
-
-So PLL0 rate should be set to 1.5GHz. Change the parent of cpu_root clock
-and the divider of cpu_core before the setting.
-
-Reviewed-by: Hal Feng <hal.feng@starfivetech.com>
-Fixes: e2c510d6d630 ("riscv: dts: starfive: Add cpu scaling for JH7110 SoC")
-Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
----
- .../clk/starfive/clk-starfive-jh7110-sys.c | 49 ++++++++++++++++++-
- 1 file changed, 48 insertions(+), 1 deletion(-)
-
---- a/drivers/clk/starfive/clk-starfive-jh7110-sys.c
-+++ b/drivers/clk/starfive/clk-starfive-jh7110-sys.c
-@@ -7,6 +7,7 @@
- */
-
- #include <linux/auxiliary_bus.h>
-+#include <linux/clk.h>
- #include <linux/clk-provider.h>
- #include <linux/init.h>
- #include <linux/io.h>
-@@ -389,6 +390,7 @@ static int __init jh7110_syscrg_probe(st
- struct jh71x0_clk_priv *priv;
- unsigned int idx;
- int ret;
-+ struct clk *pllclk;
-
- priv = devm_kzalloc(&pdev->dev,
- struct_size(priv, reg, JH7110_SYSCLK_END),
-@@ -462,7 +464,52 @@ static int __init jh7110_syscrg_probe(st
- if (ret)
- return ret;
-
-- return jh7110_reset_controller_register(priv, "rst-sys", 0);
-+ ret = jh7110_reset_controller_register(priv, "rst-sys", 0);
-+ if (ret)
-+ return ret;
-+
-+ /*
-+ * Set PLL0 rate to 1.5GHz
-+ * In order to not affect the cpu when the PLL0 rate is changing,
-+ * we need to switch the parent of cpu_root clock to osc clock first,
-+ * and then switch back after setting the PLL0 rate.
-+ */
-+ pllclk = clk_get(priv->dev, "pll0_out");
-+ if (!IS_ERR(pllclk)) {
-+ struct clk *osc = clk_get(&pdev->dev, "osc");
-+ struct clk *cpu_root = priv->reg[JH7110_SYSCLK_CPU_ROOT].hw.clk;
-+ struct clk *cpu_core = priv->reg[JH7110_SYSCLK_CPU_CORE].hw.clk;
-+
-+ if (IS_ERR(osc)) {
-+ clk_put(pllclk);
-+ return PTR_ERR(osc);
-+ }
-+
-+ /*
-+ * CPU need voltage regulation by CPUfreq if set 1.5GHz.
-+ * So in this driver, cpu_core need to be set the divider to be 2 first
-+ * and will be 750M after setting parent.
-+ */
-+ ret = clk_set_rate(cpu_core, clk_get_rate(cpu_core) / 2);
-+ if (ret)
-+ goto failed_set;
-+
-+ ret = clk_set_parent(cpu_root, osc);
-+ if (ret)
-+ goto failed_set;
-+
-+ ret = clk_set_rate(pllclk, 1500000000);
-+ if (ret)
-+ goto failed_set;
-+
-+ ret = clk_set_parent(cpu_root, pllclk);
-+
-+failed_set:
-+ clk_put(pllclk);
-+ clk_put(osc);
-+ }
-+
-+ return ret;
- }
-
- static const struct of_device_id jh7110_syscrg_match[] = {
diff --git a/target/linux/starfive/patches-6.1/1000-net-stmmac-dwmac-starfive-Add-JH7100-support.patch b/target/linux/starfive/patches-6.1/1000-net-stmmac-dwmac-starfive-Add-JH7100-support.patch
deleted file mode 100644
index d009d375ca..0000000000
--- a/target/linux/starfive/patches-6.1/1000-net-stmmac-dwmac-starfive-Add-JH7100-support.patch
+++ /dev/null
@@ -1,63 +0,0 @@
-From 22885637d0976473b04d4bae191fcf88e28b3df5 Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Wed, 29 Sep 2021 20:50:22 +0200
-Subject: [PATCH 1000/1024] net: stmmac: dwmac-starfive: Add JH7100 support
-
-This adds support for setting the phy interface and delay chains on the
-StarFive JH7100 SoC.
-
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
----
- .../net/ethernet/stmicro/stmmac/dwmac-starfive.c | 13 +++++++++++++
- 1 file changed, 13 insertions(+)
-
---- a/drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c
-@@ -17,6 +17,10 @@
- #define STARFIVE_DWMAC_PHY_INFT_RMII 0x4
- #define STARFIVE_DWMAC_PHY_INFT_FIELD 0x7U
-
-+#define JH7100_SYSMAIN_REGISTER28 0x70
-+/* The value below is not a typo, just really bad naming by StarFive ¯\_(ツ)_/¯ */
-+#define JH7100_SYSMAIN_REGISTER49 0xc8
-+
- struct starfive_dwmac {
- struct device *dev;
- struct clk *clk_tx;
-@@ -56,6 +60,7 @@ static int starfive_dwmac_set_mode(struc
- struct regmap *regmap;
- unsigned int args[2];
- unsigned int mode;
-+ u32 gtxclk_dlychain;
- int err;
-
- switch (plat_dat->interface) {
-@@ -65,6 +70,7 @@ static int starfive_dwmac_set_mode(struc
-
- case PHY_INTERFACE_MODE_RGMII:
- case PHY_INTERFACE_MODE_RGMII_ID:
-+ case PHY_INTERFACE_MODE_RGMII_TXID:
- mode = STARFIVE_DWMAC_PHY_INFT_RGMII;
- break;
-
-@@ -87,6 +93,12 @@ static int starfive_dwmac_set_mode(struc
- if (err)
- return dev_err_probe(dwmac->dev, err, "error setting phy mode\n");
-
-+ if (!of_property_read_u32(dwmac->dev->of_node, "starfive,gtxclk-dlychain", &gtxclk_dlychain)) {
-+ err = regmap_write(regmap, JH7100_SYSMAIN_REGISTER49, gtxclk_dlychain);
-+ if (err)
-+ return dev_err_probe(dwmac->dev, err, "error selecting gtxclk delay chain\n");
-+ }
-+
- return 0;
- }
-
-@@ -149,6 +161,7 @@ static int starfive_dwmac_probe(struct p
- }
-
- static const struct of_device_id starfive_dwmac_match[] = {
-+ { .compatible = "starfive,jh7100-dwmac" },
- { .compatible = "starfive,jh7110-dwmac" },
- { /* sentinel */ }
- };
diff --git a/target/linux/starfive/patches-6.1/1001-dt-bindings-mfd-syscon-Add-StarFive-JH7100-sysmain-c.patch b/target/linux/starfive/patches-6.1/1001-dt-bindings-mfd-syscon-Add-StarFive-JH7100-sysmain-c.patch
deleted file mode 100644
index 5d46eab3f7..0000000000
--- a/target/linux/starfive/patches-6.1/1001-dt-bindings-mfd-syscon-Add-StarFive-JH7100-sysmain-c.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-From a5f12fe4b640281c04a9b8b6ad676df9eeba9aa6 Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Wed, 6 Oct 2021 20:42:34 +0200
-Subject: [PATCH 1001/1024] dt-bindings: mfd: syscon: Add StarFive JH7100
- sysmain compatible
-
-Document StarFive JH7100 SoC compatible for sysmain registers.
-
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
----
- Documentation/devicetree/bindings/mfd/syscon.yaml | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/Documentation/devicetree/bindings/mfd/syscon.yaml
-+++ b/Documentation/devicetree/bindings/mfd/syscon.yaml
-@@ -69,6 +69,7 @@ properties:
- - samsung,exynos5433-sysreg
- - samsung,exynos850-sysreg
- - samsung,exynosautov9-sysreg
-+ - starfive,jh7100-sysmain
-
- - const: syscon
-
diff --git a/target/linux/starfive/patches-6.1/1002-serial-8250_dw-Add-starfive-jh7100-hsuart-compatible.patch b/target/linux/starfive/patches-6.1/1002-serial-8250_dw-Add-starfive-jh7100-hsuart-compatible.patch
deleted file mode 100644
index 4a68ebdff8..0000000000
--- a/target/linux/starfive/patches-6.1/1002-serial-8250_dw-Add-starfive-jh7100-hsuart-compatible.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From a3e9dc73758c378dd471fb6b1458f39592b020fe Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Thu, 14 Oct 2021 20:56:54 +0200
-Subject: [PATCH 1002/1024] serial: 8250_dw: Add starfive,jh7100-hsuart
- compatible
-
-This adds a compatible for the high speed UARTs on the StarFive JH7100
-RISC-V SoC. Just like the regular uarts we also need to keep the input
-clocks at their default rate and rely only on the divisor in the UART.
-
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
----
- drivers/tty/serial/8250/8250_dw.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/drivers/tty/serial/8250/8250_dw.c
-+++ b/drivers/tty/serial/8250/8250_dw.c
-@@ -780,6 +780,7 @@ static const struct of_device_id dw8250_
- { .compatible = "cavium,octeon-3860-uart", .data = &dw8250_octeon_3860_data },
- { .compatible = "marvell,armada-38x-uart", .data = &dw8250_armada_38x_data },
- { .compatible = "renesas,rzn1-uart", .data = &dw8250_renesas_rzn1_data },
-+ { .compatible = "starfive,jh7100-hsuart", .data = &dw8250_starfive_jh7100_data },
- { .compatible = "starfive,jh7100-uart", .data = &dw8250_starfive_jh7100_data },
- { /* Sentinel */ }
- };
diff --git a/target/linux/starfive/patches-6.1/1003-riscv-dts-starfive-Group-tuples-in-interrupt-propert.patch b/target/linux/starfive/patches-6.1/1003-riscv-dts-starfive-Group-tuples-in-interrupt-propert.patch
deleted file mode 100644
index a202950455..0000000000
--- a/target/linux/starfive/patches-6.1/1003-riscv-dts-starfive-Group-tuples-in-interrupt-propert.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From 790e1157753b4dcc9bad4521987fe09aa6657876 Mon Sep 17 00:00:00 2001
-From: Geert Uytterhoeven <geert@linux-m68k.org>
-Date: Thu, 25 Nov 2021 14:21:18 +0100
-Subject: [PATCH 1003/1024] riscv: dts: starfive: Group tuples in interrupt
- properties
-
-To improve human readability and enable automatic validation, the tuples
-in the various properties containing interrupt specifiers should be
-grouped.
-
-Fix this by grouping the tuples of "interrupts-extended" properties
-using angle brackets.
-
-Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
----
- arch/riscv/boot/dts/starfive/jh7100.dtsi | 8 ++++----
- 1 file changed, 4 insertions(+), 4 deletions(-)
-
---- a/arch/riscv/boot/dts/starfive/jh7100.dtsi
-+++ b/arch/riscv/boot/dts/starfive/jh7100.dtsi
-@@ -118,15 +118,15 @@
- clint: clint@2000000 {
- compatible = "starfive,jh7100-clint", "sifive,clint0";
- reg = <0x0 0x2000000 0x0 0x10000>;
-- interrupts-extended = <&cpu0_intc 3 &cpu0_intc 7
-- &cpu1_intc 3 &cpu1_intc 7>;
-+ interrupts-extended = <&cpu0_intc 3>, <&cpu0_intc 7>,
-+ <&cpu1_intc 3>, <&cpu1_intc 7>;
- };
-
- plic: interrupt-controller@c000000 {
- compatible = "starfive,jh7100-plic", "sifive,plic-1.0.0";
- reg = <0x0 0xc000000 0x0 0x4000000>;
-- interrupts-extended = <&cpu0_intc 11 &cpu0_intc 9
-- &cpu1_intc 11 &cpu1_intc 9>;
-+ interrupts-extended = <&cpu0_intc 11>, <&cpu0_intc 9>,
-+ <&cpu1_intc 11>, <&cpu1_intc 9>;
- interrupt-controller;
- #address-cells = <0>;
- #interrupt-cells = <1>;
diff --git a/target/linux/starfive/patches-6.1/1004-RISC-V-Add-StarFive-JH7100-audio-clock-node.patch b/target/linux/starfive/patches-6.1/1004-RISC-V-Add-StarFive-JH7100-audio-clock-node.patch
deleted file mode 100644
index b57ec9121e..0000000000
--- a/target/linux/starfive/patches-6.1/1004-RISC-V-Add-StarFive-JH7100-audio-clock-node.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From 6a9196186f9630006c3db022bcc0bd5796f4fae5 Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Sat, 20 Nov 2021 17:13:22 +0100
-Subject: [PATCH 1004/1024] RISC-V: Add StarFive JH7100 audio clock node
-
-Add device tree node for the audio clocks on the StarFive JH7100 RISC-V
-SoC.
-
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
----
- arch/riscv/boot/dts/starfive/jh7100.dtsi | 10 ++++++++++
- 1 file changed, 10 insertions(+)
-
---- a/arch/riscv/boot/dts/starfive/jh7100.dtsi
-+++ b/arch/riscv/boot/dts/starfive/jh7100.dtsi
-@@ -133,6 +133,16 @@
- riscv,ndev = <133>;
- };
-
-+ audclk: clock-controller@10480000 {
-+ compatible = "starfive,jh7100-audclk";
-+ reg = <0x0 0x10480000 0x0 0x10000>;
-+ clocks = <&clkgen JH7100_CLK_AUDIO_SRC>,
-+ <&clkgen JH7100_CLK_AUDIO_12288>,
-+ <&clkgen JH7100_CLK_DOM7AHB_BUS>;
-+ clock-names = "audio_src", "audio_12288", "dom7ahb_bus";
-+ #clock-cells = <1>;
-+ };
-+
- clkgen: clock-controller@11800000 {
- compatible = "starfive,jh7100-clkgen";
- reg = <0x0 0x11800000 0x0 0x10000>;
diff --git a/target/linux/starfive/patches-6.1/1005-RISC-V-Mark-StarFive-JH7100-as-having-non-coherent-D.patch b/target/linux/starfive/patches-6.1/1005-RISC-V-Mark-StarFive-JH7100-as-having-non-coherent-D.patch
deleted file mode 100644
index 11fa1155d6..0000000000
--- a/target/linux/starfive/patches-6.1/1005-RISC-V-Mark-StarFive-JH7100-as-having-non-coherent-D.patch
+++ /dev/null
@@ -1,21 +0,0 @@
-From a22e1110a6ffcc2cf4b3b598f037879cbd0915d3 Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Wed, 31 Aug 2022 22:54:07 +0200
-Subject: [PATCH 1005/1024] RISC-V: Mark StarFive JH7100 as having non-coherent
- DMAs
-
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
----
- arch/riscv/boot/dts/starfive/jh7100.dtsi | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/arch/riscv/boot/dts/starfive/jh7100.dtsi
-+++ b/arch/riscv/boot/dts/starfive/jh7100.dtsi
-@@ -111,6 +111,7 @@
- soc {
- compatible = "simple-bus";
- interrupt-parent = <&plic>;
-+ dma-noncoherent;
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
diff --git a/target/linux/starfive/patches-6.1/1006-drivers-tty-serial-8250-update-driver-for-JH7100.patch b/target/linux/starfive/patches-6.1/1006-drivers-tty-serial-8250-update-driver-for-JH7100.patch
deleted file mode 100644
index feb52591b3..0000000000
--- a/target/linux/starfive/patches-6.1/1006-drivers-tty-serial-8250-update-driver-for-JH7100.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From d0c1660c9e88748c9eba81ff3839de54dffba6ad Mon Sep 17 00:00:00 2001
-From: Samin Guo <samin.guo@starfivetech.com>
-Date: Fri, 8 Jan 2021 03:11:04 +0800
-Subject: [PATCH 1006/1024] drivers/tty/serial/8250: update driver for JH7100
-
----
- drivers/tty/serial/8250/8250_port.c | 8 ++++++++
- 1 file changed, 8 insertions(+)
-
---- a/drivers/tty/serial/8250/8250_port.c
-+++ b/drivers/tty/serial/8250/8250_port.c
-@@ -72,8 +72,16 @@ static const struct serial8250_config ua
- },
- [PORT_16550] = {
- .name = "16550",
-+#ifdef CONFIG_SOC_STARFIVE
-+ .fifo_size = 16,
-+ .tx_loadsz = 16,
-+ .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_00,
-+ .rxtrig_bytes = {1, 4, 8, 14},
-+ .flags = UART_CAP_FIFO,
-+#else
- .fifo_size = 1,
- .tx_loadsz = 1,
-+#endif
- },
- [PORT_16550A] = {
- .name = "16550A",
diff --git a/target/linux/starfive/patches-6.1/1007-dmaengine-dw-axi-dmac-Handle-xfer-start-while-non-id.patch b/target/linux/starfive/patches-6.1/1007-dmaengine-dw-axi-dmac-Handle-xfer-start-while-non-id.patch
deleted file mode 100644
index 2c0b1938ce..0000000000
--- a/target/linux/starfive/patches-6.1/1007-dmaengine-dw-axi-dmac-Handle-xfer-start-while-non-id.patch
+++ /dev/null
@@ -1,55 +0,0 @@
-From 5fdd2623dd3eed156fa1ec65b2096da735bb0cde Mon Sep 17 00:00:00 2001
-From: Samin Guo <samin.guo@starfivetech.com>
-Date: Wed, 17 Nov 2021 14:50:45 +0800
-Subject: [PATCH 1007/1024] dmaengine: dw-axi-dmac: Handle xfer start while
- non-idle
-
-Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
-Signed-off-by: Curry Zhang <curry.zhang@starfivetech.com>
----
- drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 12 +++++++++++-
- drivers/dma/dw-axi-dmac/dw-axi-dmac.h | 1 +
- 2 files changed, 12 insertions(+), 1 deletion(-)
-
---- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
-+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
-@@ -383,11 +383,13 @@ static void axi_chan_block_xfer_start(st
- u32 irq_mask;
- u8 lms = 0; /* Select AXI0 master for LLI fetching */
-
-+ chan->is_err = false;
- if (unlikely(axi_chan_is_hw_enable(chan))) {
- dev_err(chan2dev(chan), "%s is non-idle!\n",
- axi_chan_name(chan));
-
-- return;
-+ axi_chan_disable(chan);
-+ chan->is_err = true;
- }
-
- axi_dma_enable(chan->chip);
-@@ -1029,6 +1031,14 @@ static noinline void axi_chan_handle_err
- axi_chan_name(chan));
- goto out;
- }
-+ if (chan->is_err) {
-+ struct axi_dma_desc *desc = vd_to_axi_desc(vd);
-+
-+ axi_chan_block_xfer_start(chan, desc);
-+ chan->is_err = false;
-+ goto out;
-+ }
-+
- /* Remove the completed descriptor from issued list */
- list_del(&vd->node);
-
---- a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
-+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
-@@ -50,6 +50,7 @@ struct axi_dma_chan {
- struct dma_slave_config config;
- enum dma_transfer_direction direction;
- bool cyclic;
-+ bool is_err;
- /* these other elements are all protected by vc.lock */
- bool is_paused;
- };
diff --git a/target/linux/starfive/patches-6.1/1008-dmaengine-dw-axi-dmac-Add-StarFive-JH7100-support.patch b/target/linux/starfive/patches-6.1/1008-dmaengine-dw-axi-dmac-Add-StarFive-JH7100-support.patch
deleted file mode 100644
index 854e739bab..0000000000
--- a/target/linux/starfive/patches-6.1/1008-dmaengine-dw-axi-dmac-Add-StarFive-JH7100-support.patch
+++ /dev/null
@@ -1,64 +0,0 @@
-From c06352c09ce55999d41036e593293a3aaf0cf70c Mon Sep 17 00:00:00 2001
-From: Samin Guo <samin.guo@starfivetech.com>
-Date: Wed, 17 Nov 2021 14:50:45 +0800
-Subject: [PATCH 1008/1024] dmaengine: dw-axi-dmac: Add StarFive JH7100 support
-
-Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
----
- drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 12 ++++++++++++
- drivers/dma/dw-axi-dmac/dw-axi-dmac.h | 4 ++++
- 2 files changed, 16 insertions(+)
-
---- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
-+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
-@@ -678,8 +678,13 @@ static int dw_axi_dma_set_hw_desc(struct
-
- hw_desc->lli->block_ts_lo = cpu_to_le32(block_ts - 1);
-
-+#ifdef CONFIG_SOC_STARFIVE
-+ ctllo |= DWAXIDMAC_BURST_TRANS_LEN_16 << CH_CTL_L_DST_MSIZE_POS |
-+ DWAXIDMAC_BURST_TRANS_LEN_16 << CH_CTL_L_SRC_MSIZE_POS;
-+#else
- ctllo |= DWAXIDMAC_BURST_TRANS_LEN_4 << CH_CTL_L_DST_MSIZE_POS |
- DWAXIDMAC_BURST_TRANS_LEN_4 << CH_CTL_L_SRC_MSIZE_POS;
-+#endif
- hw_desc->lli->ctl_lo = cpu_to_le32(ctllo);
-
- set_desc_src_master(hw_desc);
-@@ -1506,7 +1511,11 @@ static int dw_probe(struct platform_devi
- * Therefore, set constraint to 1024 * 4.
- */
- dw->dma.dev->dma_parms = &dw->dma_parms;
-+#ifdef CONFIG_SOC_STARFIVE
-+ dma_set_max_seg_size(&pdev->dev, DMAC_MAX_BLK_SIZE);
-+#else
- dma_set_max_seg_size(&pdev->dev, MAX_BLOCK_SIZE);
-+#endif
- platform_set_drvdata(pdev, chip);
-
- pm_runtime_enable(chip->dev);
-@@ -1591,6 +1600,9 @@ static const struct of_device_id dw_dma_
- .compatible = "intel,kmb-axi-dma",
- .data = (void *)AXI_DMA_FLAG_HAS_APB_REGS,
- }, {
-+ .compatible = "starfive,jh7100-axi-dma",
-+ .data = (void *)(AXI_DMA_FLAG_HAS_RESETS | AXI_DMA_FLAG_USE_CFG2),
-+ }, {
- .compatible = "starfive,jh7110-axi-dma",
- .data = (void *)(AXI_DMA_FLAG_HAS_RESETS | AXI_DMA_FLAG_USE_CFG2),
- },
---- a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
-+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
-@@ -284,7 +284,11 @@ enum {
- #define CH_CTL_L_SRC_MAST BIT(0)
-
- /* CH_CFG_H */
-+#ifdef CONFIG_SOC_STARFIVE
-+#define CH_CFG_H_PRIORITY_POS 15
-+#else
- #define CH_CFG_H_PRIORITY_POS 17
-+#endif
- #define CH_CFG_H_DST_PER_POS 12
- #define CH_CFG_H_SRC_PER_POS 7
- #define CH_CFG_H_HS_SEL_DST_POS 4
diff --git a/target/linux/starfive/patches-6.1/1009-pinctrl-starfive-Reset-pinmux-settings.patch b/target/linux/starfive/patches-6.1/1009-pinctrl-starfive-Reset-pinmux-settings.patch
deleted file mode 100644
index d2873ff968..0000000000
--- a/target/linux/starfive/patches-6.1/1009-pinctrl-starfive-Reset-pinmux-settings.patch
+++ /dev/null
@@ -1,127 +0,0 @@
-From 89c86fda8cee5b93ce213dcc46b2cf27e5ee3312 Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Sat, 17 Jul 2021 21:50:38 +0200
-Subject: [PATCH 1009/1024] pinctrl: starfive: Reset pinmux settings
-
-Current u-boot doesn't seem to take into account that some GPIOs are
-configured as inputs/outputs of certain peripherals on power-up. This
-means it ends up configuring some GPIOs as inputs to more than one
-peripheral which the documentation explicitly says is illegal. Similarly
-it also ends up configuring more than one GPIO as output of the same
-peripheral. While not explicitly mentioned by the documentation this
-also seems like a bad idea.
-
-The easiest way to remedy this mess is to just disconnect all GPIOs from
-peripherals and have our pinmux configuration set everything up
-properly. This, however, means that we'd disconnect the serial console
-from its pins for a while, so add a device tree property to keep
-certain GPIOs from being reset.
-
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
----
- .../pinctrl/starfive,jh7100-pinctrl.yaml | 4 ++
- .../starfive/pinctrl-starfive-jh7100.c | 66 +++++++++++++++++++
- 2 files changed, 70 insertions(+)
-
---- a/Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml
-+++ b/Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml
-@@ -88,6 +88,10 @@ properties:
- $ref: /schemas/types.yaml#/definitions/uint32
- enum: [0, 1, 2, 3, 4, 5, 6]
-
-+ starfive,keep-gpiomux:
-+ description: Keep pinmux for these GPIOs from being reset at boot.
-+ $ref: /schemas/types.yaml#/definitions/uint32-array
-+
- required:
- - compatible
- - reg
---- a/drivers/pinctrl/starfive/pinctrl-starfive-jh7100.c
-+++ b/drivers/pinctrl/starfive/pinctrl-starfive-jh7100.c
-@@ -200,6 +200,10 @@ static u16 starfive_drive_strength_from_
- return (clamp(i, 14U, 63U) - 14) / 7;
- }
-
-+static bool keepmux;
-+module_param(keepmux, bool, 0644);
-+MODULE_PARM_DESC(keepmux, "Keep pinmux settings from previous boot stage");
-+
- struct starfive_pinctrl {
- struct gpio_chip gc;
- struct pinctrl_gpio_range gpios;
-@@ -1222,6 +1226,65 @@ static void starfive_disable_clock(void
- clk_disable_unprepare(data);
- }
-
-+#define GPI_END (GPI_USB_OVER_CURRENT + 1)
-+static void starfive_pinmux_reset(struct starfive_pinctrl *sfp)
-+{
-+ static const DECLARE_BITMAP(defaults, GPI_END) = {
-+ BIT_MASK(GPI_I2C0_PAD_SCK_IN) |
-+ BIT_MASK(GPI_I2C0_PAD_SDA_IN) |
-+ BIT_MASK(GPI_I2C1_PAD_SCK_IN) |
-+ BIT_MASK(GPI_I2C1_PAD_SDA_IN) |
-+ BIT_MASK(GPI_I2C2_PAD_SCK_IN) |
-+ BIT_MASK(GPI_I2C2_PAD_SDA_IN) |
-+ BIT_MASK(GPI_I2C3_PAD_SCK_IN) |
-+ BIT_MASK(GPI_I2C3_PAD_SDA_IN) |
-+ BIT_MASK(GPI_SDIO0_PAD_CARD_DETECT_N) |
-+
-+ BIT_MASK(GPI_SDIO1_PAD_CARD_DETECT_N) |
-+ BIT_MASK(GPI_SPI0_PAD_SS_IN_N) |
-+ BIT_MASK(GPI_SPI1_PAD_SS_IN_N) |
-+ BIT_MASK(GPI_SPI2_PAD_SS_IN_N) |
-+ BIT_MASK(GPI_SPI2AHB_PAD_SS_N) |
-+ BIT_MASK(GPI_SPI3_PAD_SS_IN_N),
-+
-+ BIT_MASK(GPI_UART0_PAD_SIN) |
-+ BIT_MASK(GPI_UART1_PAD_SIN) |
-+ BIT_MASK(GPI_UART2_PAD_SIN) |
-+ BIT_MASK(GPI_UART3_PAD_SIN) |
-+ BIT_MASK(GPI_USB_OVER_CURRENT)
-+ };
-+ DECLARE_BITMAP(keep, NR_GPIOS) = {};
-+ struct device_node *np = sfp->gc.parent->of_node;
-+ int len = of_property_count_u32_elems(np, "starfive,keep-gpiomux");
-+ int i;
-+
-+ for (i = 0; i < len; i++) {
-+ u32 gpio;
-+
-+ of_property_read_u32_index(np, "starfive,keep-gpiomux", i, &gpio);
-+ if (gpio < NR_GPIOS)
-+ set_bit(gpio, keep);
-+ }
-+
-+ for (i = 0; i < NR_GPIOS; i++) {
-+ if (test_bit(i, keep))
-+ continue;
-+
-+ writel_relaxed(GPO_DISABLE, sfp->base + GPON_DOEN_CFG + 8 * i);
-+ writel_relaxed(GPO_LOW, sfp->base + GPON_DOUT_CFG + 8 * i);
-+ }
-+
-+ for (i = 0; i < GPI_END; i++) {
-+ void __iomem *reg = sfp->base + GPI_CFG_OFFSET + 4 * i;
-+ u32 din = readl_relaxed(reg);
-+
-+ if (din >= 2 && din < (NR_GPIOS + 2) && test_bit(din - 2, keep))
-+ continue;
-+
-+ writel_relaxed(test_bit(i, defaults), reg);
-+ }
-+}
-+
- static int starfive_probe(struct platform_device *pdev)
- {
- struct device *dev = &pdev->dev;
-@@ -1283,6 +1346,9 @@ static int starfive_probe(struct platfor
- writel(value, sfp->padctl + IO_PADSHARE_SEL);
- }
-
-+ if (!keepmux)
-+ starfive_pinmux_reset(sfp);
-+
- value = readl(sfp->padctl + IO_PADSHARE_SEL);
- switch (value) {
- case 0:
diff --git a/target/linux/starfive/patches-6.1/1010-clk-starfive-Add-flags-argument-to-JH71X0__MUX-macro.patch b/target/linux/starfive/patches-6.1/1010-clk-starfive-Add-flags-argument-to-JH71X0__MUX-macro.patch
deleted file mode 100644
index a12be8b979..0000000000
--- a/target/linux/starfive/patches-6.1/1010-clk-starfive-Add-flags-argument-to-JH71X0__MUX-macro.patch
+++ /dev/null
@@ -1,302 +0,0 @@
-From f6c0c8639c7424f915f2f2f18cf86b6b97c7d32a Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <emil.renner.berthing@canonical.com>
-Date: Sat, 25 Mar 2023 22:57:06 +0100
-Subject: [PATCH 1010/1024] clk: starfive: Add flags argument to JH71X0__MUX
- macro
-
-This flag is needed to add the CLK_SET_RATE_PARENT flag on the gmac_tx
-clock on the JH7100, which in turn is needed by the dwmac-starfive
-driver to set the clock properly for 1000, 100 and 10 Mbps links.
-
-This change was mostly made using coccinelle:
-
-@ match @
-expression idx, name, nparents;
-@@
- JH71X0__MUX(
--idx, name, nparents,
-+idx, name, 0, nparents,
- ...)
-
-Signed-off-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
----
- .../clk/starfive/clk-starfive-jh7100-audio.c | 2 +-
- drivers/clk/starfive/clk-starfive-jh7100.c | 32 +++++++++----------
- .../clk/starfive/clk-starfive-jh7110-aon.c | 6 ++--
- .../clk/starfive/clk-starfive-jh7110-isp.c | 2 +-
- .../clk/starfive/clk-starfive-jh7110-sys.c | 26 +++++++--------
- drivers/clk/starfive/clk-starfive-jh71x0.h | 4 +--
- 6 files changed, 36 insertions(+), 36 deletions(-)
-
---- a/drivers/clk/starfive/clk-starfive-jh7100-audio.c
-+++ b/drivers/clk/starfive/clk-starfive-jh7100-audio.c
-@@ -80,7 +80,7 @@ static const struct jh71x0_clk_data jh71
- JH71X0_GDIV(JH7100_AUDCLK_USB_LPM, "usb_lpm", CLK_IGNORE_UNUSED, 4, JH7100_AUDCLK_USB_APB),
- JH71X0_GDIV(JH7100_AUDCLK_USB_STB, "usb_stb", CLK_IGNORE_UNUSED, 3, JH7100_AUDCLK_USB_APB),
- JH71X0__DIV(JH7100_AUDCLK_APB_EN, "apb_en", 8, JH7100_AUDCLK_DOM7AHB_BUS),
-- JH71X0__MUX(JH7100_AUDCLK_VAD_MEM, "vad_mem", 2,
-+ JH71X0__MUX(JH7100_AUDCLK_VAD_MEM, "vad_mem", 0, 2,
- JH7100_AUDCLK_VAD_INTMEM,
- JH7100_AUDCLK_AUDIO_12288),
- };
---- a/drivers/clk/starfive/clk-starfive-jh7100.c
-+++ b/drivers/clk/starfive/clk-starfive-jh7100.c
-@@ -24,48 +24,48 @@
- #define JH7100_CLK_GMAC_GR_MII_RX (JH7100_CLK_END + 3)
-
- static const struct jh71x0_clk_data jh7100_clk_data[] __initconst = {
-- JH71X0__MUX(JH7100_CLK_CPUNDBUS_ROOT, "cpundbus_root", 4,
-+ JH71X0__MUX(JH7100_CLK_CPUNDBUS_ROOT, "cpundbus_root", 0, 4,
- JH7100_CLK_OSC_SYS,
- JH7100_CLK_PLL0_OUT,
- JH7100_CLK_PLL1_OUT,
- JH7100_CLK_PLL2_OUT),
-- JH71X0__MUX(JH7100_CLK_DLA_ROOT, "dla_root", 3,
-+ JH71X0__MUX(JH7100_CLK_DLA_ROOT, "dla_root", 0, 3,
- JH7100_CLK_OSC_SYS,
- JH7100_CLK_PLL1_OUT,
- JH7100_CLK_PLL2_OUT),
-- JH71X0__MUX(JH7100_CLK_DSP_ROOT, "dsp_root", 4,
-+ JH71X0__MUX(JH7100_CLK_DSP_ROOT, "dsp_root", 0, 4,
- JH7100_CLK_OSC_SYS,
- JH7100_CLK_PLL0_OUT,
- JH7100_CLK_PLL1_OUT,
- JH7100_CLK_PLL2_OUT),
-- JH71X0__MUX(JH7100_CLK_GMACUSB_ROOT, "gmacusb_root", 3,
-+ JH71X0__MUX(JH7100_CLK_GMACUSB_ROOT, "gmacusb_root", 0, 3,
- JH7100_CLK_OSC_SYS,
- JH7100_CLK_PLL0_OUT,
- JH7100_CLK_PLL2_OUT),
-- JH71X0__MUX(JH7100_CLK_PERH0_ROOT, "perh0_root", 2,
-+ JH71X0__MUX(JH7100_CLK_PERH0_ROOT, "perh0_root", 0, 2,
- JH7100_CLK_OSC_SYS,
- JH7100_CLK_PLL0_OUT),
-- JH71X0__MUX(JH7100_CLK_PERH1_ROOT, "perh1_root", 2,
-+ JH71X0__MUX(JH7100_CLK_PERH1_ROOT, "perh1_root", 0, 2,
- JH7100_CLK_OSC_SYS,
- JH7100_CLK_PLL2_OUT),
-- JH71X0__MUX(JH7100_CLK_VIN_ROOT, "vin_root", 3,
-+ JH71X0__MUX(JH7100_CLK_VIN_ROOT, "vin_root", 0, 3,
- JH7100_CLK_OSC_SYS,
- JH7100_CLK_PLL1_OUT,
- JH7100_CLK_PLL2_OUT),
-- JH71X0__MUX(JH7100_CLK_VOUT_ROOT, "vout_root", 3,
-+ JH71X0__MUX(JH7100_CLK_VOUT_ROOT, "vout_root", 0, 3,
- JH7100_CLK_OSC_AUD,
- JH7100_CLK_PLL0_OUT,
- JH7100_CLK_PLL2_OUT),
- JH71X0_GDIV(JH7100_CLK_AUDIO_ROOT, "audio_root", 0, 8, JH7100_CLK_PLL0_OUT),
-- JH71X0__MUX(JH7100_CLK_CDECHIFI4_ROOT, "cdechifi4_root", 3,
-+ JH71X0__MUX(JH7100_CLK_CDECHIFI4_ROOT, "cdechifi4_root", 0, 3,
- JH7100_CLK_OSC_SYS,
- JH7100_CLK_PLL1_OUT,
- JH7100_CLK_PLL2_OUT),
-- JH71X0__MUX(JH7100_CLK_CDEC_ROOT, "cdec_root", 3,
-+ JH71X0__MUX(JH7100_CLK_CDEC_ROOT, "cdec_root", 0, 3,
- JH7100_CLK_OSC_SYS,
- JH7100_CLK_PLL0_OUT,
- JH7100_CLK_PLL1_OUT),
-- JH71X0__MUX(JH7100_CLK_VOUTBUS_ROOT, "voutbus_root", 3,
-+ JH71X0__MUX(JH7100_CLK_VOUTBUS_ROOT, "voutbus_root", 0, 3,
- JH7100_CLK_OSC_AUD,
- JH7100_CLK_PLL0_OUT,
- JH7100_CLK_PLL2_OUT),
-@@ -76,7 +76,7 @@ static const struct jh71x0_clk_data jh71
- JH71X0_GDIV(JH7100_CLK_PLL0_TESTOUT, "pll0_testout", 0, 31, JH7100_CLK_PERH0_SRC),
- JH71X0_GDIV(JH7100_CLK_PLL1_TESTOUT, "pll1_testout", 0, 31, JH7100_CLK_DLA_ROOT),
- JH71X0_GDIV(JH7100_CLK_PLL2_TESTOUT, "pll2_testout", 0, 31, JH7100_CLK_PERH1_SRC),
-- JH71X0__MUX(JH7100_CLK_PLL2_REF, "pll2_refclk", 2,
-+ JH71X0__MUX(JH7100_CLK_PLL2_REF, "pll2_refclk", 0, 2,
- JH7100_CLK_OSC_SYS,
- JH7100_CLK_OSC_AUD),
- JH71X0__DIV(JH7100_CLK_CPU_CORE, "cpu_core", 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
-@@ -142,7 +142,7 @@ static const struct jh71x0_clk_data jh71
- JH71X0__DIV(JH7100_CLK_NOC_COG, "noc_cog", 8, JH7100_CLK_DLA_ROOT),
- JH71X0_GATE(JH7100_CLK_NNE_AHB, "nne_ahb", 0, JH7100_CLK_AHB_BUS),
- JH71X0__DIV(JH7100_CLK_NNEBUS_SRC1, "nnebus_src1", 4, JH7100_CLK_DSP_ROOT),
-- JH71X0__MUX(JH7100_CLK_NNE_BUS, "nne_bus", 2,
-+ JH71X0__MUX(JH7100_CLK_NNE_BUS, "nne_bus", 0, 2,
- JH7100_CLK_CPU_AXI,
- JH7100_CLK_NNEBUS_SRC1),
- JH71X0_GATE(JH7100_CLK_NNE_AXI, "nne_axi", 0, JH7100_CLK_NNE_BUS),
-@@ -166,7 +166,7 @@ static const struct jh71x0_clk_data jh71
- JH71X0_GDIV(JH7100_CLK_USBPHY_125M, "usbphy_125m", 0, 8, JH7100_CLK_USBPHY_ROOTDIV),
- JH71X0_GDIV(JH7100_CLK_USBPHY_PLLDIV25M, "usbphy_plldiv25m", 0, 32,
- JH7100_CLK_USBPHY_ROOTDIV),
-- JH71X0__MUX(JH7100_CLK_USBPHY_25M, "usbphy_25m", 2,
-+ JH71X0__MUX(JH7100_CLK_USBPHY_25M, "usbphy_25m", 0, 2,
- JH7100_CLK_OSC_SYS,
- JH7100_CLK_USBPHY_PLLDIV25M),
- JH71X0_FDIV(JH7100_CLK_AUDIO_DIV, "audio_div", JH7100_CLK_AUDIO_ROOT),
-@@ -200,12 +200,12 @@ static const struct jh71x0_clk_data jh71
- JH71X0_GDIV(JH7100_CLK_GMAC_GTX, "gmac_gtxclk", 0, 255, JH7100_CLK_GMAC_ROOT_DIV),
- JH71X0_GDIV(JH7100_CLK_GMAC_RMII_TX, "gmac_rmii_txclk", 0, 8, JH7100_CLK_GMAC_RMII_REF),
- JH71X0_GDIV(JH7100_CLK_GMAC_RMII_RX, "gmac_rmii_rxclk", 0, 8, JH7100_CLK_GMAC_RMII_REF),
-- JH71X0__MUX(JH7100_CLK_GMAC_TX, "gmac_tx", 3,
-+ JH71X0__MUX(JH7100_CLK_GMAC_TX, "gmac_tx", 0, 3,
- JH7100_CLK_GMAC_GTX,
- JH7100_CLK_GMAC_TX_INV,
- JH7100_CLK_GMAC_RMII_TX),
- JH71X0__INV(JH7100_CLK_GMAC_TX_INV, "gmac_tx_inv", JH7100_CLK_GMAC_TX),
-- JH71X0__MUX(JH7100_CLK_GMAC_RX_PRE, "gmac_rx_pre", 2,
-+ JH71X0__MUX(JH7100_CLK_GMAC_RX_PRE, "gmac_rx_pre", 0, 2,
- JH7100_CLK_GMAC_GR_MII_RX,
- JH7100_CLK_GMAC_RMII_RX),
- JH71X0__INV(JH7100_CLK_GMAC_RX_INV, "gmac_rx_inv", JH7100_CLK_GMAC_RX_PRE),
---- a/drivers/clk/starfive/clk-starfive-jh7110-aon.c
-+++ b/drivers/clk/starfive/clk-starfive-jh7110-aon.c
-@@ -26,7 +26,7 @@
- static const struct jh71x0_clk_data jh7110_aonclk_data[] = {
- /* source */
- JH71X0__DIV(JH7110_AONCLK_OSC_DIV4, "osc_div4", 4, JH7110_AONCLK_OSC),
-- JH71X0__MUX(JH7110_AONCLK_APB_FUNC, "apb_func", 2,
-+ JH71X0__MUX(JH7110_AONCLK_APB_FUNC, "apb_func", 0, 2,
- JH7110_AONCLK_OSC_DIV4,
- JH7110_AONCLK_OSC),
- /* gmac0 */
-@@ -39,7 +39,7 @@ static const struct jh71x0_clk_data jh71
- JH7110_AONCLK_GMAC0_GTXCLK,
- JH7110_AONCLK_GMAC0_RMII_RTX),
- JH71X0__INV(JH7110_AONCLK_GMAC0_TX_INV, "gmac0_tx_inv", JH7110_AONCLK_GMAC0_TX),
-- JH71X0__MUX(JH7110_AONCLK_GMAC0_RX, "gmac0_rx", 2,
-+ JH71X0__MUX(JH7110_AONCLK_GMAC0_RX, "gmac0_rx", 0, 2,
- JH7110_AONCLK_GMAC0_RGMII_RXIN,
- JH7110_AONCLK_GMAC0_RMII_RTX),
- JH71X0__INV(JH7110_AONCLK_GMAC0_RX_INV, "gmac0_rx_inv", JH7110_AONCLK_GMAC0_RX),
-@@ -48,7 +48,7 @@ static const struct jh71x0_clk_data jh71
- /* rtc */
- JH71X0_GATE(JH7110_AONCLK_RTC_APB, "rtc_apb", 0, JH7110_AONCLK_APB_BUS),
- JH71X0__DIV(JH7110_AONCLK_RTC_INTERNAL, "rtc_internal", 1022, JH7110_AONCLK_OSC),
-- JH71X0__MUX(JH7110_AONCLK_RTC_32K, "rtc_32k", 2,
-+ JH71X0__MUX(JH7110_AONCLK_RTC_32K, "rtc_32k", 0, 2,
- JH7110_AONCLK_RTC_OSC,
- JH7110_AONCLK_RTC_INTERNAL),
- JH71X0_GATE(JH7110_AONCLK_RTC_CAL, "rtc_cal", 0, JH7110_AONCLK_OSC),
---- a/drivers/clk/starfive/clk-starfive-jh7110-isp.c
-+++ b/drivers/clk/starfive/clk-starfive-jh7110-isp.c
-@@ -53,7 +53,7 @@ static const struct jh71x0_clk_data jh71
- JH7110_ISPCLK_MIPI_RX0_PXL),
- JH71X0_GATE(JH7110_ISPCLK_VIN_PIXEL_IF3, "vin_pixel_if3", 0,
- JH7110_ISPCLK_MIPI_RX0_PXL),
-- JH71X0__MUX(JH7110_ISPCLK_VIN_P_AXI_WR, "vin_p_axi_wr", 2,
-+ JH71X0__MUX(JH7110_ISPCLK_VIN_P_AXI_WR, "vin_p_axi_wr", 0, 2,
- JH7110_ISPCLK_MIPI_RX0_PXL,
- JH7110_ISPCLK_DVP_INV),
- /* ispv2_top_wrapper */
---- a/drivers/clk/starfive/clk-starfive-jh7110-sys.c
-+++ b/drivers/clk/starfive/clk-starfive-jh7110-sys.c
-@@ -36,18 +36,18 @@
-
- static const struct jh71x0_clk_data jh7110_sysclk_data[] __initconst = {
- /* root */
-- JH71X0__MUX(JH7110_SYSCLK_CPU_ROOT, "cpu_root", 2,
-+ JH71X0__MUX(JH7110_SYSCLK_CPU_ROOT, "cpu_root", 0, 2,
- JH7110_SYSCLK_OSC,
- JH7110_SYSCLK_PLL0_OUT),
- JH71X0__DIV(JH7110_SYSCLK_CPU_CORE, "cpu_core", 7, JH7110_SYSCLK_CPU_ROOT),
- JH71X0__DIV(JH7110_SYSCLK_CPU_BUS, "cpu_bus", 2, JH7110_SYSCLK_CPU_CORE),
-- JH71X0__MUX(JH7110_SYSCLK_GPU_ROOT, "gpu_root", 2,
-+ JH71X0__MUX(JH7110_SYSCLK_GPU_ROOT, "gpu_root", 0, 2,
- JH7110_SYSCLK_PLL2_OUT,
- JH7110_SYSCLK_PLL1_OUT),
- JH71X0_MDIV(JH7110_SYSCLK_PERH_ROOT, "perh_root", 2, 2,
- JH7110_SYSCLK_PLL0_OUT,
- JH7110_SYSCLK_PLL2_OUT),
-- JH71X0__MUX(JH7110_SYSCLK_BUS_ROOT, "bus_root", 2,
-+ JH71X0__MUX(JH7110_SYSCLK_BUS_ROOT, "bus_root", 0, 2,
- JH7110_SYSCLK_OSC,
- JH7110_SYSCLK_PLL2_OUT),
- JH71X0__DIV(JH7110_SYSCLK_NOCSTG_BUS, "nocstg_bus", 3, JH7110_SYSCLK_BUS_ROOT),
-@@ -62,7 +62,7 @@ static const struct jh71x0_clk_data jh71
- JH71X0__DIV(JH7110_SYSCLK_PLL2_DIV2, "pll2_div2", 2, JH7110_SYSCLK_PLL2_OUT),
- JH71X0__DIV(JH7110_SYSCLK_AUDIO_ROOT, "audio_root", 8, JH7110_SYSCLK_PLL2_OUT),
- JH71X0__DIV(JH7110_SYSCLK_MCLK_INNER, "mclk_inner", 64, JH7110_SYSCLK_AUDIO_ROOT),
-- JH71X0__MUX(JH7110_SYSCLK_MCLK, "mclk", 2,
-+ JH71X0__MUX(JH7110_SYSCLK_MCLK, "mclk", 0, 2,
- JH7110_SYSCLK_MCLK_INNER,
- JH7110_SYSCLK_MCLK_EXT),
- JH71X0_GATE(JH7110_SYSCLK_MCLK_OUT, "mclk_out", 0, JH7110_SYSCLK_MCLK_INNER),
-@@ -96,7 +96,7 @@ static const struct jh71x0_clk_data jh71
- JH71X0__DIV(JH7110_SYSCLK_OSC_DIV2, "osc_div2", 2, JH7110_SYSCLK_OSC),
- JH71X0__DIV(JH7110_SYSCLK_PLL1_DIV4, "pll1_div4", 2, JH7110_SYSCLK_PLL1_DIV2),
- JH71X0__DIV(JH7110_SYSCLK_PLL1_DIV8, "pll1_div8", 2, JH7110_SYSCLK_PLL1_DIV4),
-- JH71X0__MUX(JH7110_SYSCLK_DDR_BUS, "ddr_bus", 4,
-+ JH71X0__MUX(JH7110_SYSCLK_DDR_BUS, "ddr_bus", 0, 4,
- JH7110_SYSCLK_OSC_DIV2,
- JH7110_SYSCLK_PLL1_DIV2,
- JH7110_SYSCLK_PLL1_DIV4,
-@@ -186,7 +186,7 @@ static const struct jh71x0_clk_data jh71
- JH71X0__DIV(JH7110_SYSCLK_GMAC1_RMII_RTX, "gmac1_rmii_rtx", 30,
- JH7110_SYSCLK_GMAC1_RMII_REFIN),
- JH71X0_GDIV(JH7110_SYSCLK_GMAC1_PTP, "gmac1_ptp", 0, 31, JH7110_SYSCLK_GMAC_SRC),
-- JH71X0__MUX(JH7110_SYSCLK_GMAC1_RX, "gmac1_rx", 2,
-+ JH71X0__MUX(JH7110_SYSCLK_GMAC1_RX, "gmac1_rx", 0, 2,
- JH7110_SYSCLK_GMAC1_RGMII_RXIN,
- JH7110_SYSCLK_GMAC1_RMII_RTX),
- JH71X0__INV(JH7110_SYSCLK_GMAC1_RX_INV, "gmac1_rx_inv", JH7110_SYSCLK_GMAC1_RX),
-@@ -270,11 +270,11 @@ static const struct jh71x0_clk_data jh71
- JH71X0_MDIV(JH7110_SYSCLK_I2STX0_LRCK_MST, "i2stx0_lrck_mst", 64, 2,
- JH7110_SYSCLK_I2STX0_BCLK_MST_INV,
- JH7110_SYSCLK_I2STX0_BCLK_MST),
-- JH71X0__MUX(JH7110_SYSCLK_I2STX0_BCLK, "i2stx0_bclk", 2,
-+ JH71X0__MUX(JH7110_SYSCLK_I2STX0_BCLK, "i2stx0_bclk", 0, 2,
- JH7110_SYSCLK_I2STX0_BCLK_MST,
- JH7110_SYSCLK_I2STX_BCLK_EXT),
- JH71X0__INV(JH7110_SYSCLK_I2STX0_BCLK_INV, "i2stx0_bclk_inv", JH7110_SYSCLK_I2STX0_BCLK),
-- JH71X0__MUX(JH7110_SYSCLK_I2STX0_LRCK, "i2stx0_lrck", 2,
-+ JH71X0__MUX(JH7110_SYSCLK_I2STX0_LRCK, "i2stx0_lrck", 0, 2,
- JH7110_SYSCLK_I2STX0_LRCK_MST,
- JH7110_SYSCLK_I2STX_LRCK_EXT),
- /* i2stx1 */
-@@ -285,11 +285,11 @@ static const struct jh71x0_clk_data jh71
- JH71X0_MDIV(JH7110_SYSCLK_I2STX1_LRCK_MST, "i2stx1_lrck_mst", 64, 2,
- JH7110_SYSCLK_I2STX1_BCLK_MST_INV,
- JH7110_SYSCLK_I2STX1_BCLK_MST),
-- JH71X0__MUX(JH7110_SYSCLK_I2STX1_BCLK, "i2stx1_bclk", 2,
-+ JH71X0__MUX(JH7110_SYSCLK_I2STX1_BCLK, "i2stx1_bclk", 0, 2,
- JH7110_SYSCLK_I2STX1_BCLK_MST,
- JH7110_SYSCLK_I2STX_BCLK_EXT),
- JH71X0__INV(JH7110_SYSCLK_I2STX1_BCLK_INV, "i2stx1_bclk_inv", JH7110_SYSCLK_I2STX1_BCLK),
-- JH71X0__MUX(JH7110_SYSCLK_I2STX1_LRCK, "i2stx1_lrck", 2,
-+ JH71X0__MUX(JH7110_SYSCLK_I2STX1_LRCK, "i2stx1_lrck", 0, 2,
- JH7110_SYSCLK_I2STX1_LRCK_MST,
- JH7110_SYSCLK_I2STX_LRCK_EXT),
- /* i2srx */
-@@ -300,11 +300,11 @@ static const struct jh71x0_clk_data jh71
- JH71X0_MDIV(JH7110_SYSCLK_I2SRX_LRCK_MST, "i2srx_lrck_mst", 64, 2,
- JH7110_SYSCLK_I2SRX_BCLK_MST_INV,
- JH7110_SYSCLK_I2SRX_BCLK_MST),
-- JH71X0__MUX(JH7110_SYSCLK_I2SRX_BCLK, "i2srx_bclk", 2,
-+ JH71X0__MUX(JH7110_SYSCLK_I2SRX_BCLK, "i2srx_bclk", 0, 2,
- JH7110_SYSCLK_I2SRX_BCLK_MST,
- JH7110_SYSCLK_I2SRX_BCLK_EXT),
- JH71X0__INV(JH7110_SYSCLK_I2SRX_BCLK_INV, "i2srx_bclk_inv", JH7110_SYSCLK_I2SRX_BCLK),
-- JH71X0__MUX(JH7110_SYSCLK_I2SRX_LRCK, "i2srx_lrck", 2,
-+ JH71X0__MUX(JH7110_SYSCLK_I2SRX_LRCK, "i2srx_lrck", 0, 2,
- JH7110_SYSCLK_I2SRX_LRCK_MST,
- JH7110_SYSCLK_I2SRX_LRCK_EXT),
- /* pdm */
-@@ -314,7 +314,7 @@ static const struct jh71x0_clk_data jh71
- JH71X0_GATE(JH7110_SYSCLK_TDM_AHB, "tdm_ahb", 0, JH7110_SYSCLK_AHB0),
- JH71X0_GATE(JH7110_SYSCLK_TDM_APB, "tdm_apb", 0, JH7110_SYSCLK_APB0),
- JH71X0_GDIV(JH7110_SYSCLK_TDM_INTERNAL, "tdm_internal", 0, 64, JH7110_SYSCLK_MCLK),
-- JH71X0__MUX(JH7110_SYSCLK_TDM_TDM, "tdm_tdm", 2,
-+ JH71X0__MUX(JH7110_SYSCLK_TDM_TDM, "tdm_tdm", 0, 2,
- JH7110_SYSCLK_TDM_INTERNAL,
- JH7110_SYSCLK_TDM_EXT),
- JH71X0__INV(JH7110_SYSCLK_TDM_TDM_INV, "tdm_tdm_inv", JH7110_SYSCLK_TDM_TDM),
---- a/drivers/clk/starfive/clk-starfive-jh71x0.h
-+++ b/drivers/clk/starfive/clk-starfive-jh71x0.h
-@@ -61,10 +61,10 @@ struct jh71x0_clk_data {
- .parents = { [0] = _parent }, \
- }
-
--#define JH71X0__MUX(_idx, _name, _nparents, ...) \
-+#define JH71X0__MUX(_idx, _name, _flags, _nparents, ...) \
- [_idx] = { \
- .name = _name, \
-- .flags = 0, \
-+ .flags = _flags, \
- .max = ((_nparents) - 1) << JH71X0_CLK_MUX_SHIFT, \
- .parents = { __VA_ARGS__ }, \
- }
diff --git a/target/linux/starfive/patches-6.1/1011-clk-starfive-jh7100-Add-CLK_SET_RATE_PARENT-to-gmac_.patch b/target/linux/starfive/patches-6.1/1011-clk-starfive-jh7100-Add-CLK_SET_RATE_PARENT-to-gmac_.patch
deleted file mode 100644
index e5e750820e..0000000000
--- a/target/linux/starfive/patches-6.1/1011-clk-starfive-jh7100-Add-CLK_SET_RATE_PARENT-to-gmac_.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From 38d50c243d2d4176b88ad732f4948cca9629251b Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <emil.renner.berthing@canonical.com>
-Date: Sat, 25 Mar 2023 23:04:31 +0100
-Subject: [PATCH 1011/1024] clk: starfive: jh7100: Add CLK_SET_RATE_PARENT to
- gmac_tx
-
-This is needed by the dwmac-starfive ethernet driver to set the clock
-for 1000, 100 and 10 Mbps links properly.
-
-Signed-off-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
----
- drivers/clk/starfive/clk-starfive-jh7100.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/clk/starfive/clk-starfive-jh7100.c
-+++ b/drivers/clk/starfive/clk-starfive-jh7100.c
-@@ -200,7 +200,7 @@ static const struct jh71x0_clk_data jh71
- JH71X0_GDIV(JH7100_CLK_GMAC_GTX, "gmac_gtxclk", 0, 255, JH7100_CLK_GMAC_ROOT_DIV),
- JH71X0_GDIV(JH7100_CLK_GMAC_RMII_TX, "gmac_rmii_txclk", 0, 8, JH7100_CLK_GMAC_RMII_REF),
- JH71X0_GDIV(JH7100_CLK_GMAC_RMII_RX, "gmac_rmii_rxclk", 0, 8, JH7100_CLK_GMAC_RMII_REF),
-- JH71X0__MUX(JH7100_CLK_GMAC_TX, "gmac_tx", 0, 3,
-+ JH71X0__MUX(JH7100_CLK_GMAC_TX, "gmac_tx", CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, 3,
- JH7100_CLK_GMAC_GTX,
- JH7100_CLK_GMAC_TX_INV,
- JH7100_CLK_GMAC_RMII_TX),
diff --git a/target/linux/starfive/patches-6.1/1012-clk-starfive-jh7100-Keep-more-clocks-alive.patch b/target/linux/starfive/patches-6.1/1012-clk-starfive-jh7100-Keep-more-clocks-alive.patch
deleted file mode 100644
index 3afdf1d9a6..0000000000
--- a/target/linux/starfive/patches-6.1/1012-clk-starfive-jh7100-Keep-more-clocks-alive.patch
+++ /dev/null
@@ -1,94 +0,0 @@
-From 3e73731c113fbe6f319403d5e2e64a656fcb17ce Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Thu, 14 Oct 2021 20:35:43 +0200
-Subject: [PATCH 1012/1024] clk: starfive: jh7100: Keep more clocks alive
-
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
----
- drivers/clk/starfive/clk-starfive-jh7100.c | 37 +++++++++++-----------
- 1 file changed, 19 insertions(+), 18 deletions(-)
-
---- a/drivers/clk/starfive/clk-starfive-jh7100.c
-+++ b/drivers/clk/starfive/clk-starfive-jh7100.c
-@@ -94,9 +94,9 @@ static const struct jh71x0_clk_data jh71
- JH71X0_GATE(JH7100_CLK_DMA2PNOC_AXI, "dma2pnoc_axi", 0, JH7100_CLK_CPU_AXI),
- JH71X0_GATE(JH7100_CLK_SGDMA2P_AHB, "sgdma2p_ahb", 0, JH7100_CLK_AHB_BUS),
- JH71X0__DIV(JH7100_CLK_DLA_BUS, "dla_bus", 4, JH7100_CLK_DLA_ROOT),
-- JH71X0_GATE(JH7100_CLK_DLA_AXI, "dla_axi", 0, JH7100_CLK_DLA_BUS),
-- JH71X0_GATE(JH7100_CLK_DLANOC_AXI, "dlanoc_axi", 0, JH7100_CLK_DLA_BUS),
-- JH71X0_GATE(JH7100_CLK_DLA_APB, "dla_apb", 0, JH7100_CLK_APB1_BUS),
-+ JH71X0_GATE(JH7100_CLK_DLA_AXI, "dla_axi", CLK_IGNORE_UNUSED, JH7100_CLK_DLA_BUS),
-+ JH71X0_GATE(JH7100_CLK_DLANOC_AXI, "dlanoc_axi", CLK_IGNORE_UNUSED, JH7100_CLK_DLA_BUS),
-+ JH71X0_GATE(JH7100_CLK_DLA_APB, "dla_apb", CLK_IGNORE_UNUSED, JH7100_CLK_APB1_BUS),
- JH71X0_GDIV(JH7100_CLK_VP6_CORE, "vp6_core", 0, 4, JH7100_CLK_DSP_ROOT_DIV),
- JH71X0__DIV(JH7100_CLK_VP6BUS_SRC, "vp6bus_src", 4, JH7100_CLK_DSP_ROOT),
- JH71X0_GDIV(JH7100_CLK_VP6_AXI, "vp6_axi", 0, 4, JH7100_CLK_VP6BUS_SRC),
-@@ -160,11 +160,12 @@ static const struct jh71x0_clk_data jh71
- JH71X0_GATE(JH7100_CLK_DMA1P_AXI, "dma1p_axi", 0, JH7100_CLK_SGDMA1P_BUS),
- JH71X0_GDIV(JH7100_CLK_X2C_AXI, "x2c_axi", CLK_IS_CRITICAL, 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
- JH71X0__DIV(JH7100_CLK_USB_BUS, "usb_bus", 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
-- JH71X0_GATE(JH7100_CLK_USB_AXI, "usb_axi", 0, JH7100_CLK_USB_BUS),
-- JH71X0_GATE(JH7100_CLK_USBNOC_AXI, "usbnoc_axi", 0, JH7100_CLK_USB_BUS),
-+ JH71X0_GATE(JH7100_CLK_USB_AXI, "usb_axi", CLK_IGNORE_UNUSED, JH7100_CLK_USB_BUS),
-+ JH71X0_GATE(JH7100_CLK_USBNOC_AXI, "usbnoc_axi", CLK_IGNORE_UNUSED, JH7100_CLK_USB_BUS),
- JH71X0__DIV(JH7100_CLK_USBPHY_ROOTDIV, "usbphy_rootdiv", 4, JH7100_CLK_GMACUSB_ROOT),
-- JH71X0_GDIV(JH7100_CLK_USBPHY_125M, "usbphy_125m", 0, 8, JH7100_CLK_USBPHY_ROOTDIV),
-- JH71X0_GDIV(JH7100_CLK_USBPHY_PLLDIV25M, "usbphy_plldiv25m", 0, 32,
-+ JH71X0_GDIV(JH7100_CLK_USBPHY_125M, "usbphy_125m", CLK_IGNORE_UNUSED, 8,
-+ JH7100_CLK_USBPHY_ROOTDIV),
-+ JH71X0_GDIV(JH7100_CLK_USBPHY_PLLDIV25M, "usbphy_plldiv25m", CLK_IGNORE_UNUSED, 32,
- JH7100_CLK_USBPHY_ROOTDIV),
- JH71X0__MUX(JH7100_CLK_USBPHY_25M, "usbphy_25m", 0, 2,
- JH7100_CLK_OSC_SYS,
-@@ -183,23 +184,23 @@ static const struct jh71x0_clk_data jh71
- JH71X0__DIV(JH7100_CLK_VIN_BUS, "vin_bus", 8, JH7100_CLK_VIN_SRC),
- JH71X0_GATE(JH7100_CLK_VIN_AXI, "vin_axi", 0, JH7100_CLK_VIN_BUS),
- JH71X0_GATE(JH7100_CLK_VINNOC_AXI, "vinnoc_axi", 0, JH7100_CLK_VIN_BUS),
-- JH71X0_GDIV(JH7100_CLK_VOUT_SRC, "vout_src", 0, 4, JH7100_CLK_VOUT_ROOT),
-+ JH71X0_GDIV(JH7100_CLK_VOUT_SRC, "vout_src", CLK_IGNORE_UNUSED, 4, JH7100_CLK_VOUT_ROOT),
- JH71X0__DIV(JH7100_CLK_DISPBUS_SRC, "dispbus_src", 4, JH7100_CLK_VOUTBUS_ROOT),
- JH71X0__DIV(JH7100_CLK_DISP_BUS, "disp_bus", 4, JH7100_CLK_DISPBUS_SRC),
-- JH71X0_GATE(JH7100_CLK_DISP_AXI, "disp_axi", 0, JH7100_CLK_DISP_BUS),
-- JH71X0_GATE(JH7100_CLK_DISPNOC_AXI, "dispnoc_axi", 0, JH7100_CLK_DISP_BUS),
-+ JH71X0_GATE(JH7100_CLK_DISP_AXI, "disp_axi", CLK_IGNORE_UNUSED, JH7100_CLK_DISP_BUS),
-+ JH71X0_GATE(JH7100_CLK_DISPNOC_AXI, "dispnoc_axi", CLK_IGNORE_UNUSED, JH7100_CLK_DISP_BUS),
- JH71X0_GATE(JH7100_CLK_SDIO0_AHB, "sdio0_ahb", 0, JH7100_CLK_AHB_BUS),
- JH71X0_GDIV(JH7100_CLK_SDIO0_CCLKINT, "sdio0_cclkint", 0, 24, JH7100_CLK_PERH0_SRC),
- JH71X0__INV(JH7100_CLK_SDIO0_CCLKINT_INV, "sdio0_cclkint_inv", JH7100_CLK_SDIO0_CCLKINT),
- JH71X0_GATE(JH7100_CLK_SDIO1_AHB, "sdio1_ahb", 0, JH7100_CLK_AHB_BUS),
- JH71X0_GDIV(JH7100_CLK_SDIO1_CCLKINT, "sdio1_cclkint", 0, 24, JH7100_CLK_PERH1_SRC),
- JH71X0__INV(JH7100_CLK_SDIO1_CCLKINT_INV, "sdio1_cclkint_inv", JH7100_CLK_SDIO1_CCLKINT),
-- JH71X0_GATE(JH7100_CLK_GMAC_AHB, "gmac_ahb", 0, JH7100_CLK_AHB_BUS),
-+ JH71X0_GATE(JH7100_CLK_GMAC_AHB, "gmac_ahb", CLK_IGNORE_UNUSED, JH7100_CLK_AHB_BUS),
- JH71X0__DIV(JH7100_CLK_GMAC_ROOT_DIV, "gmac_root_div", 8, JH7100_CLK_GMACUSB_ROOT),
-- JH71X0_GDIV(JH7100_CLK_GMAC_PTP_REF, "gmac_ptp_refclk", 0, 31, JH7100_CLK_GMAC_ROOT_DIV),
-- JH71X0_GDIV(JH7100_CLK_GMAC_GTX, "gmac_gtxclk", 0, 255, JH7100_CLK_GMAC_ROOT_DIV),
-- JH71X0_GDIV(JH7100_CLK_GMAC_RMII_TX, "gmac_rmii_txclk", 0, 8, JH7100_CLK_GMAC_RMII_REF),
-- JH71X0_GDIV(JH7100_CLK_GMAC_RMII_RX, "gmac_rmii_rxclk", 0, 8, JH7100_CLK_GMAC_RMII_REF),
-+ JH71X0_GDIV(JH7100_CLK_GMAC_PTP_REF, "gmac_ptp_refclk", CLK_IGNORE_UNUSED, 31, JH7100_CLK_GMAC_ROOT_DIV),
-+ JH71X0_GDIV(JH7100_CLK_GMAC_GTX, "gmac_gtxclk", CLK_IGNORE_UNUSED, 255, JH7100_CLK_GMAC_ROOT_DIV),
-+ JH71X0_GDIV(JH7100_CLK_GMAC_RMII_TX, "gmac_rmii_txclk", CLK_IGNORE_UNUSED, 8, JH7100_CLK_GMAC_RMII_REF),
-+ JH71X0_GDIV(JH7100_CLK_GMAC_RMII_RX, "gmac_rmii_rxclk", CLK_IGNORE_UNUSED, 8, JH7100_CLK_GMAC_RMII_REF),
- JH71X0__MUX(JH7100_CLK_GMAC_TX, "gmac_tx", CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, 3,
- JH7100_CLK_GMAC_GTX,
- JH7100_CLK_GMAC_TX_INV,
-@@ -209,8 +210,8 @@ static const struct jh71x0_clk_data jh71
- JH7100_CLK_GMAC_GR_MII_RX,
- JH7100_CLK_GMAC_RMII_RX),
- JH71X0__INV(JH7100_CLK_GMAC_RX_INV, "gmac_rx_inv", JH7100_CLK_GMAC_RX_PRE),
-- JH71X0_GATE(JH7100_CLK_GMAC_RMII, "gmac_rmii", 0, JH7100_CLK_GMAC_RMII_REF),
-- JH71X0_GDIV(JH7100_CLK_GMAC_TOPHYREF, "gmac_tophyref", 0, 127, JH7100_CLK_GMAC_ROOT_DIV),
-+ JH71X0_GATE(JH7100_CLK_GMAC_RMII, "gmac_rmii", CLK_IGNORE_UNUSED, JH7100_CLK_GMAC_RMII_REF),
-+ JH71X0_GDIV(JH7100_CLK_GMAC_TOPHYREF, "gmac_tophyref", CLK_IGNORE_UNUSED, 127, JH7100_CLK_GMAC_ROOT_DIV),
- JH71X0_GATE(JH7100_CLK_SPI2AHB_AHB, "spi2ahb_ahb", 0, JH7100_CLK_AHB_BUS),
- JH71X0_GDIV(JH7100_CLK_SPI2AHB_CORE, "spi2ahb_core", 0, 31, JH7100_CLK_PERH0_SRC),
- JH71X0_GATE(JH7100_CLK_EZMASTER_AHB, "ezmaster_ahb", 0, JH7100_CLK_AHB_BUS),
-@@ -223,7 +224,7 @@ static const struct jh71x0_clk_data jh71
- JH71X0_GATE(JH7100_CLK_AES, "aes_clk", 0, JH7100_CLK_SEC_AHB),
- JH71X0_GATE(JH7100_CLK_SHA, "sha_clk", 0, JH7100_CLK_SEC_AHB),
- JH71X0_GATE(JH7100_CLK_PKA, "pka_clk", 0, JH7100_CLK_SEC_AHB),
-- JH71X0_GATE(JH7100_CLK_TRNG_APB, "trng_apb", 0, JH7100_CLK_APB1_BUS),
-+ JH71X0_GATE(JH7100_CLK_TRNG_APB, "trng_apb", CLK_IGNORE_UNUSED, JH7100_CLK_APB1_BUS),
- JH71X0_GATE(JH7100_CLK_OTP_APB, "otp_apb", 0, JH7100_CLK_APB1_BUS),
- JH71X0_GATE(JH7100_CLK_UART0_APB, "uart0_apb", 0, JH7100_CLK_APB1_BUS),
- JH71X0_GDIV(JH7100_CLK_UART0_CORE, "uart0_core", 0, 63, JH7100_CLK_PERH1_SRC),
diff --git a/target/linux/starfive/patches-6.1/1013-net-stmmac-use-GFP_DMA32.patch b/target/linux/starfive/patches-6.1/1013-net-stmmac-use-GFP_DMA32.patch
deleted file mode 100644
index 5bbb4cc4c5..0000000000
--- a/target/linux/starfive/patches-6.1/1013-net-stmmac-use-GFP_DMA32.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 1889527687432bd63942c86dbebf8686b6515aad Mon Sep 17 00:00:00 2001
-From: Matteo Croce <technoboy85@gmail.com>
-Date: Fri, 21 May 2021 03:26:38 +0200
-Subject: [PATCH 1013/1024] net: stmmac: use GFP_DMA32
-
-Signed-off-by: Matteo Croce <mcroce@microsoft.com>
----
- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
-@@ -1436,7 +1436,7 @@ static int stmmac_init_rx_buffers(struct
- {
- struct stmmac_rx_queue *rx_q = &dma_conf->rx_queue[queue];
- struct stmmac_rx_buffer *buf = &rx_q->buf_pool[i];
-- gfp_t gfp = (GFP_ATOMIC | __GFP_NOWARN);
-+ gfp_t gfp = (GFP_ATOMIC | __GFP_NOWARN | GFP_DMA32);
-
- if (priv->dma_cap.host_dma_width <= 32)
- gfp |= GFP_DMA32;
-@@ -4615,7 +4615,7 @@ static inline void stmmac_rx_refill(stru
- struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue];
- int dirty = stmmac_rx_dirty(priv, queue);
- unsigned int entry = rx_q->dirty_rx;
-- gfp_t gfp = (GFP_ATOMIC | __GFP_NOWARN);
-+ gfp_t gfp = (GFP_ATOMIC | __GFP_NOWARN | GFP_DMA32);
-
- if (priv->dma_cap.host_dma_width <= 32)
- gfp |= GFP_DMA32;
diff --git a/target/linux/starfive/patches-6.1/1014-hwrng-Add-StarFive-JH7100-Random-Number-Generator-dr.patch b/target/linux/starfive/patches-6.1/1014-hwrng-Add-StarFive-JH7100-Random-Number-Generator-dr.patch
deleted file mode 100644
index 86d3b1d839..0000000000
--- a/target/linux/starfive/patches-6.1/1014-hwrng-Add-StarFive-JH7100-Random-Number-Generator-dr.patch
+++ /dev/null
@@ -1,477 +0,0 @@
-From 919bcebc58044a266e953ac302c8e068e255e2a6 Mon Sep 17 00:00:00 2001
-From: Huan Feng <huan.feng@starfivetech.com>
-Date: Fri, 8 Jan 2021 03:35:42 +0800
-Subject: [PATCH 1014/1024] hwrng: Add StarFive JH7100 Random Number Generator
- driver
-
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
----
- drivers/char/hw_random/Kconfig | 13 ++
- drivers/char/hw_random/Makefile | 1 +
- drivers/char/hw_random/starfive-vic-rng.c | 256 ++++++++++++++++++++++
- drivers/char/hw_random/starfive-vic-rng.h | 167 ++++++++++++++
- 4 files changed, 437 insertions(+)
- create mode 100644 drivers/char/hw_random/starfive-vic-rng.c
- create mode 100644 drivers/char/hw_random/starfive-vic-rng.h
-
---- a/drivers/char/hw_random/Kconfig
-+++ b/drivers/char/hw_random/Kconfig
-@@ -322,6 +322,19 @@ config HW_RANDOM_POWERNV
-
- If unsure, say Y.
-
-+config HW_RANDOM_STARFIVE_VIC
-+ tristate "Starfive VIC Random Number Generator support"
-+ depends on HW_RANDOM && (SOC_STARFIVE || COMPILE_TEST)
-+ default SOC_STARFIVE
-+ help
-+ This driver provides kernel-side support for the Random Number
-+ Generator hardware found on Starfive VIC SoC.
-+
-+ To compile this driver as a module, choose M here: the
-+ module will be called starfive-vic-rng.
-+
-+ If unsure, say Y.
-+
- config HW_RANDOM_HISI
- tristate "Hisilicon Random Number Generator support"
- depends on HW_RANDOM && ARCH_HISI
---- a/drivers/char/hw_random/Makefile
-+++ b/drivers/char/hw_random/Makefile
-@@ -28,6 +28,7 @@ obj-$(CONFIG_HW_RANDOM_OCTEON) += octeon
- obj-$(CONFIG_HW_RANDOM_NOMADIK) += nomadik-rng.o
- obj-$(CONFIG_HW_RANDOM_PSERIES) += pseries-rng.o
- obj-$(CONFIG_HW_RANDOM_POWERNV) += powernv-rng.o
-+obj-$(CONFIG_HW_RANDOM_STARFIVE_VIC) += starfive-vic-rng.o
- obj-$(CONFIG_HW_RANDOM_HISI) += hisi-rng.o
- obj-$(CONFIG_HW_RANDOM_BCM2835) += bcm2835-rng.o
- obj-$(CONFIG_HW_RANDOM_IPROC_RNG200) += iproc-rng200.o
---- /dev/null
-+++ b/drivers/char/hw_random/starfive-vic-rng.c
-@@ -0,0 +1,256 @@
-+/*
-+ ******************************************************************************
-+ * @file starfive-vic-rng.c
-+ * @author StarFive Technology
-+ * @version V1.0
-+ * @date 08/13/2020
-+ * @brief
-+ ******************************************************************************
-+ * @copy
-+ *
-+ * THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
-+ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
-+ * TIME. AS A RESULT, STARFIVE SHALL NOT BE HELD LIABLE FOR ANY
-+ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
-+ * FROM THE CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
-+ * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
-+ *
-+ * COPYRIGHT 2020 Shanghai StarFive Technology Co., Ltd.
-+ */
-+#include <linux/err.h>
-+#include <linux/kernel.h>
-+#include <linux/hw_random.h>
-+#include <linux/io.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/platform_device.h>
-+#include <linux/interrupt.h>
-+#include <linux/random.h>
-+
-+#include "starfive-vic-rng.h"
-+
-+#define to_vic_rng(p) container_of(p, struct vic_rng, rng)
-+
-+struct vic_rng {
-+ struct device *dev;
-+ void __iomem *base;
-+ struct hwrng rng;
-+};
-+
-+static inline void vic_wait_till_idle(struct vic_rng *hrng)
-+{
-+ while(readl(hrng->base + VIC_STAT) & VIC_STAT_BUSY)
-+ ;
-+}
-+
-+static inline void vic_rng_irq_mask_clear(struct vic_rng *hrng)
-+{
-+ // clear register: ISTAT
-+ u32 data = readl(hrng->base + VIC_ISTAT);
-+ writel(data, hrng->base + VIC_ISTAT);
-+ writel(0, hrng->base + VIC_ALARM);
-+}
-+
-+static int vic_trng_cmd(struct vic_rng *hrng, u32 cmd) {
-+ int res = 0;
-+ // wait till idle
-+ vic_wait_till_idle(hrng);
-+ switch (cmd) {
-+ case VIC_CTRL_CMD_NOP:
-+ case VIC_CTRL_CMD_GEN_NOISE:
-+ case VIC_CTRL_CMD_GEN_NONCE:
-+ case VIC_CTRL_CMD_CREATE_STATE:
-+ case VIC_CTRL_CMD_RENEW_STATE:
-+ case VIC_CTRL_CMD_REFRESH_ADDIN:
-+ case VIC_CTRL_CMD_GEN_RANDOM:
-+ case VIC_CTRL_CMD_ADVANCE_STATE:
-+ case VIC_CTRL_CMD_KAT:
-+ case VIC_CTRL_CMD_ZEROIZE:
-+ writel(cmd, hrng->base + VIC_CTRL);
-+ break;
-+ default:
-+ res = -1;
-+ break;
-+ }
-+
-+ return res;
-+}
-+
-+static int vic_rng_init(struct hwrng *rng)
-+{
-+ struct vic_rng *hrng = to_vic_rng(rng);
-+
-+ // wait till idle
-+
-+ // clear register: ISTAT
-+ vic_rng_irq_mask_clear(hrng);
-+
-+ // set mission mode
-+ writel(VIC_SMODE_SECURE_EN(1), hrng->base + VIC_SMODE);
-+
-+ vic_trng_cmd(hrng, VIC_CTRL_CMD_GEN_NOISE);
-+ vic_wait_till_idle(hrng);
-+
-+ // set interrupt
-+ writel(VIC_IE_ALL, hrng->base + VIC_IE);
-+
-+ // zeroize
-+ vic_trng_cmd(hrng, VIC_CTRL_CMD_ZEROIZE);
-+
-+ vic_wait_till_idle(hrng);
-+
-+ return 0;
-+}
-+
-+static irqreturn_t vic_rng_irq(int irq, void *priv)
-+{
-+ u32 status, val;
-+ struct vic_rng *hrng = (struct vic_rng *)priv;
-+
-+ /*
-+ * clearing the interrupt will also clear the error register
-+ * read error and status before clearing
-+ */
-+ status = readl(hrng->base + VIC_ISTAT);
-+
-+ if (status & VIC_ISTAT_ALARMS) {
-+ writel(VIC_ISTAT_ALARMS, hrng->base + VIC_ISTAT);
-+ val = readl(hrng->base + VIC_ALARM);
-+ if (val & VIC_ALARM_ILLEGAL_CMD_SEQ) {
-+ writel(VIC_ALARM_ILLEGAL_CMD_SEQ, hrng->base + VIC_ALARM);
-+ //dev_info(hrng->dev, "ILLEGAL CMD SEQ: LAST_CMD=0x%x\r\n",
-+ //VIC_STAT_LAST_CMD(readl(hrng->base + VIC_STAT)));
-+ } else {
-+ dev_info(hrng->dev, "Failed test: %x\r\n", val);
-+ }
-+ }
-+
-+ if (status & VIC_ISTAT_ZEROIZE) {
-+ writel(VIC_ISTAT_ZEROIZE, hrng->base + VIC_ISTAT);
-+ //dev_info(hrng->dev, "zeroized\r\n");
-+ }
-+
-+ if (status & VIC_ISTAT_KAT_COMPLETE) {
-+ writel(VIC_ISTAT_KAT_COMPLETE, hrng->base + VIC_ISTAT);
-+ //dev_info(hrng->dev, "kat_completed\r\n");
-+ }
-+
-+ if (status & VIC_ISTAT_NOISE_RDY) {
-+ writel(VIC_ISTAT_NOISE_RDY, hrng->base + VIC_ISTAT);
-+ //dev_info(hrng->dev, "noise_rdy\r\n");
-+ }
-+
-+ if (status & VIC_ISTAT_DONE) {
-+ writel(VIC_ISTAT_DONE, hrng->base + VIC_ISTAT);
-+ //dev_info(hrng->dev, "done\r\n");
-+ /*
-+ if (VIC_STAT_LAST_CMD(readl(hrng->base + VIC_STAT)) ==
-+ VIC_CTRL_CMD_GEN_RANDOM) {
-+ dev_info(hrng->dev, "Need Update Buffer\r\n");
-+ }
-+ */
-+ }
-+ vic_rng_irq_mask_clear(hrng);
-+
-+ return IRQ_HANDLED;
-+}
-+
-+static void vic_rng_cleanup(struct hwrng *rng)
-+{
-+ struct vic_rng *hrng = to_vic_rng(rng);
-+
-+ writel(0, hrng->base + VIC_CTRL);
-+}
-+
-+static int vic_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait)
-+{
-+ struct vic_rng *hrng = to_vic_rng(rng);
-+
-+ vic_trng_cmd(hrng, VIC_CTRL_CMD_ZEROIZE);
-+ vic_trng_cmd(hrng, VIC_CTRL_CMD_GEN_NOISE);
-+ vic_trng_cmd(hrng, VIC_CTRL_CMD_CREATE_STATE);
-+
-+ vic_wait_till_idle(hrng);
-+ max = min_t(size_t, max, (VIC_RAND_LEN * 4));
-+
-+ writel(0x0, hrng->base + VIC_MODE);
-+ vic_trng_cmd(hrng, VIC_CTRL_CMD_GEN_RANDOM);
-+
-+ vic_wait_till_idle(hrng);
-+ memcpy_fromio(buf, hrng->base + VIC_RAND0, max);
-+ vic_trng_cmd(hrng, VIC_CTRL_CMD_ZEROIZE);
-+
-+ vic_wait_till_idle(hrng);
-+ return max;
-+}
-+
-+static int vic_rng_probe(struct platform_device *pdev)
-+{
-+ int ret;
-+ int irq;
-+ struct vic_rng *rng;
-+ struct resource *res;
-+
-+ rng = devm_kzalloc(&pdev->dev, sizeof(*rng), GFP_KERNEL);
-+ if (!rng){
-+ return -ENOMEM;
-+ }
-+
-+ platform_set_drvdata(pdev, rng);
-+
-+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+ rng->base = devm_ioremap_resource(&pdev->dev, res);
-+ if (IS_ERR(rng->base)){
-+ return PTR_ERR(rng->base);
-+ }
-+
-+ irq = platform_get_irq(pdev, 0);
-+ if (irq <= 0) {
-+ dev_err(&pdev->dev, "Couldn't get irq %d\n", irq);
-+ return irq;
-+ }
-+
-+ ret = devm_request_irq(&pdev->dev, irq, vic_rng_irq, 0, pdev->name,
-+ (void *)rng);
-+ if (ret) {
-+ dev_err(&pdev->dev, "Can't get interrupt working.\n");
-+ return ret;
-+ }
-+
-+ rng->rng.name = pdev->name;
-+ rng->rng.init = vic_rng_init;
-+ rng->rng.cleanup = vic_rng_cleanup;
-+ rng->rng.read = vic_rng_read;
-+
-+ rng->dev = &pdev->dev;
-+
-+ ret = devm_hwrng_register(&pdev->dev, &rng->rng);
-+ if (ret) {
-+ dev_err(&pdev->dev, "failed to register hwrng\n");
-+ return ret;
-+ }
-+
-+ dev_info(&pdev->dev, "Initialized\n");
-+
-+ return 0;
-+}
-+
-+static const struct of_device_id vic_rng_dt_ids[] = {
-+ { .compatible = "starfive,vic-rng" },
-+ { }
-+};
-+MODULE_DEVICE_TABLE(of, vic_rng_dt_ids);
-+
-+static struct platform_driver vic_rng_driver = {
-+ .probe = vic_rng_probe,
-+ .driver = {
-+ .name = "vic-rng",
-+ .of_match_table = vic_rng_dt_ids,
-+ },
-+};
-+
-+module_platform_driver(vic_rng_driver);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Huan Feng <huan.feng@starfivetech.com>");
-+MODULE_DESCRIPTION("Starfive VIC random number generator driver");
---- /dev/null
-+++ b/drivers/char/hw_random/starfive-vic-rng.h
-@@ -0,0 +1,167 @@
-+/*
-+ ******************************************************************************
-+ * @file starfive-vic-rng.h
-+ * @author StarFive Technology
-+ * @version V1.0
-+ * @date 08/13/2020
-+ * @brief
-+ ******************************************************************************
-+ * @copy
-+ *
-+ * THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
-+ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
-+ * TIME. AS A RESULT, STARFIVE SHALL NOT BE HELD LIABLE FOR ANY
-+ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
-+ * FROM THE CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
-+ * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
-+ *
-+ * COPYRIGHT 2020 Shanghai StarFive Technology Co., Ltd.
-+ */
-+
-+#define VIC_CTRL 0x00
-+#define VIC_MODE 0x04
-+#define VIC_SMODE 0x08
-+#define VIC_STAT 0x0C
-+#define VIC_IE 0x10
-+#define VIC_ISTAT 0x14
-+#define VIC_ALARM 0x18
-+#define VIC_BUILD_ID 0x1C
-+#define VIC_FEATURES 0x20
-+#define VIC_RAND0 0x24
-+#define VIC_NPA_DATA0 0x34
-+#define VIC_SEED0 0x74
-+#define VIC_IA_RDATA 0xA4
-+#define VIC_IA_WDATA 0xA8
-+#define VIC_IA_ADDR 0xAC
-+#define VIC_IA_CMD 0xB0
-+
-+/* CTRL */
-+#define VIC_CTRL_CMD_NOP 0
-+#define VIC_CTRL_CMD_GEN_NOISE 1
-+#define VIC_CTRL_CMD_GEN_NONCE 2
-+#define VIC_CTRL_CMD_CREATE_STATE 3
-+#define VIC_CTRL_CMD_RENEW_STATE 4
-+#define VIC_CTRL_CMD_REFRESH_ADDIN 5
-+#define VIC_CTRL_CMD_GEN_RANDOM 6
-+#define VIC_CTRL_CMD_ADVANCE_STATE 7
-+#define VIC_CTRL_CMD_KAT 8
-+#define VIC_CTRL_CMD_ZEROIZE 15
-+
-+/* MODE */
-+#define _VIC_MODE_ADDIN_PRESENT 4
-+#define _VIC_MODE_PRED_RESIST 3
-+#define _VIC_MODE_KAT_SEL 2
-+#define _VIC_MODE_KAT_VEC 1
-+#define _VIC_MODE_SEC_ALG 0
-+
-+#define VIC_MODE_ADDIN_PRESENT (1UL << _VIC_MODE_ADDIN_PRESENT)
-+#define VIC_MODE_PRED_RESIST (1UL << _VIC_MODE_PRED_RESIST)
-+#define VIC_MODE_KAT_SEL (1UL << _VIC_MODE_KAT_SEL)
-+#define VIC_MODE_KAT_VEC (1UL << _VIC_MODE_KAT_VEC)
-+#define VIC_MODE_SEC_ALG (1UL << _VIC_MODE_SEC_ALG)
-+
-+/* SMODE */
-+#define _VIC_SMODE_MAX_REJECTS 2
-+#define _VIC_SMODE_SECURE_EN 1
-+#define _VIC_SMODE_NONCE 0
-+
-+#define VIC_SMODE_MAX_REJECTS(x) ((x) << _VIC_SMODE_MAX_REJECTS)
-+#define VIC_SMODE_SECURE_EN(x) ((x) << _VIC_SMODE_SECURE_EN)
-+#define VIC_SMODE_NONCE (1UL << _VIC_SMODE_NONCE)
-+
-+/* STAT */
-+#define _VIC_STAT_BUSY 31
-+#define _VIC_STAT_DRBG_STATE 7
-+#define _VIC_STAT_SECURE 6
-+#define _VIC_STAT_NONCE_MODE 5
-+#define _VIC_STAT_SEC_ALG 4
-+#define _VIC_STAT_LAST_CMD 0
-+
-+#define VIC_STAT_BUSY (1UL << _VIC_STAT_BUSY)
-+#define VIC_STAT_DRBG_STATE (1UL << _VIC_STAT_DRBG_STATE)
-+#define VIC_STAT_SECURE (1UL << _VIC_STAT_SECURE)
-+#define VIC_STAT_NONCE_MODE (1UL << _VIC_STAT_NONCE_MODE)
-+#define VIC_STAT_SEC_ALG (1UL << _VIC_STAT_SEC_ALG)
-+#define VIC_STAT_LAST_CMD(x) (((x) >> _VIC_STAT_LAST_CMD) & 0xF)
-+
-+/* IE */
-+#define _VIC_IE_GLBL 31
-+#define _VIC_IE_DONE 4
-+#define _VIC_IE_ALARMS 3
-+#define _VIC_IE_NOISE_RDY 2
-+#define _VIC_IE_KAT_COMPLETE 1
-+#define _VIC_IE_ZEROIZE 0
-+
-+#define VIC_IE_GLBL (1UL << _VIC_IE_GLBL)
-+#define VIC_IE_DONE (1UL << _VIC_IE_DONE)
-+#define VIC_IE_ALARMS (1UL << _VIC_IE_ALARMS)
-+#define VIC_IE_NOISE_RDY (1UL << _VIC_IE_NOISE_RDY)
-+#define VIC_IE_KAT_COMPLETE (1UL << _VIC_IE_KAT_COMPLETE)
-+#define VIC_IE_ZEROIZE (1UL << _VIC_IE_ZEROIZE)
-+#define VIC_IE_ALL (VIC_IE_GLBL | VIC_IE_DONE | VIC_IE_ALARMS | \
-+ VIC_IE_NOISE_RDY | VIC_IE_KAT_COMPLETE | VIC_IE_ZEROIZE)
-+
-+/* ISTAT */
-+#define _VIC_ISTAT_DONE 4
-+#define _VIC_ISTAT_ALARMS 3
-+#define _VIC_ISTAT_NOISE_RDY 2
-+#define _VIC_ISTAT_KAT_COMPLETE 1
-+#define _VIC_ISTAT_ZEROIZE 0
-+
-+#define VIC_ISTAT_DONE (1UL << _VIC_ISTAT_DONE)
-+#define VIC_ISTAT_ALARMS (1UL << _VIC_ISTAT_ALARMS)
-+#define VIC_ISTAT_NOISE_RDY (1UL << _VIC_ISTAT_NOISE_RDY)
-+#define VIC_ISTAT_KAT_COMPLETE (1UL << _VIC_ISTAT_KAT_COMPLETE)
-+#define VIC_ISTAT_ZEROIZE (1UL << _VIC_ISTAT_ZEROIZE)
-+
-+/* ALARMS */
-+#define VIC_ALARM_ILLEGAL_CMD_SEQ (1UL << 4)
-+#define VIC_ALARM_FAILED_TEST_ID_OK 0
-+#define VIC_ALARM_FAILED_TEST_ID_KAT_STAT 1
-+#define VIC_ALARM_FAILED_TEST_ID_KAT 2
-+#define VIC_ALARM_FAILED_TEST_ID_MONOBIT 3
-+#define VIC_ALARM_FAILED_TEST_ID_RUN 4
-+#define VIC_ALARM_FAILED_TEST_ID_LONGRUN 5
-+#define VIC_ALARM_FAILED_TEST_ID_AUTOCORRELATION 6
-+#define VIC_ALARM_FAILED_TEST_ID_POKER 7
-+#define VIC_ALARM_FAILED_TEST_ID_REPETITION_COUNT 8
-+#define VIC_ALARM_FAILED_TEST_ID_ADAPATIVE_PROPORTION 9
-+
-+/* BUILD_ID */
-+#define VIC_BUILD_ID_STEPPING(x) (((x) >> 28) & 0xF)
-+#define VIC_BUILD_ID_EPN(x) ((x) & 0xFFFF)
-+
-+/* FEATURES */
-+#define VIC_FEATURES_AES_256(x) (((x) >> 9) & 1)
-+#define VIC_FEATURES_EXTRA_PS_PRESENT(x) (((x) >> 8) & 1)
-+#define VIC_FEATURES_DIAG_LEVEL_NS(x) (((x) >> 7) & 1)
-+#define VIC_FEATURES_DIAG_LEVEL_CLP800(x) (((x) >> 4) & 7)
-+#define VIC_FEATURES_DIAG_LEVEL_ST_HLT(x) (((x) >> 1) & 7)
-+#define VIC_FEATURES_SECURE_RST_STATE(x) ((x) & 1)
-+
-+/* IA_CMD */
-+#define VIC_IA_CMD_GO (1UL << 31)
-+#define VIC_IA_CMD_WR (1)
-+
-+#define _VIC_SMODE_MAX_REJECTS_MASK 255UL
-+#define _VIC_SMODE_SECURE_EN_MASK 1UL
-+#define _VIC_SMODE_NONCE_MASK 1UL
-+#define _VIC_MODE_SEC_ALG_MASK 1UL
-+#define _VIC_MODE_ADDIN_PRESENT_MASK 1UL
-+#define _VIC_MODE_PRED_RESIST_MASK 1UL
-+
-+#define VIC_SMODE_SET_MAX_REJECTS(y, x) (((y) & ~(_VIC_SMODE_MAX_REJECTS_MASK << _VIC_SMODE_MAX_REJECTS)) | ((x) << _VIC_SMODE_MAX_REJECTS))
-+#define VIC_SMODE_SET_SECURE_EN(y, x) (((y) & ~(_VIC_SMODE_SECURE_EN_MASK << _VIC_SMODE_SECURE_EN)) | ((x) << _VIC_SMODE_SECURE_EN))
-+#define VIC_SMODE_SET_NONCE(y, x) (((y) & ~(_VIC_SMODE_NONCE_MASK << _VIC_SMODE_NONCE)) | ((x) << _VIC_SMODE_NONCE))
-+#define VIC_SMODE_GET_MAX_REJECTS(x) (((x) >> _VIC_SMODE_MAX_REJECTS) & _VIC_SMODE_MAX_REJECTS_MASK)
-+#define VIC_SMODE_GET_SECURE_EN(x) (((x) >> _VIC_SMODE_SECURE_EN) & _VIC_SMODE_SECURE_EN_MASK)
-+#define VIC_SMODE_GET_NONCE(x) (((x) >> _VIC_SMODE_NONCE) & _VIC_SMODE_NONCE_MASK)
-+
-+#define VIC_MODE_SET_SEC_ALG(y, x) (((y) & ~(_VIC_MODE_SEC_ALG_MASK << _VIC_MODE_SEC_ALG)) | ((x) << _VIC_MODE_SEC_ALG))
-+#define VIC_MODE_SET_PRED_RESIST(y, x) (((y) & ~(_VIC_MODE_PRED_RESIST_MASK << _VIC_MODE_PRED_RESIST)) | ((x) << _VIC_MODE_PRED_RESIST))
-+#define VIC_MODE_SET_ADDIN_PRESENT(y, x) (((y) & ~(_VIC_MODE_ADDIN_PRESENT_MASK << _VIC_MODE_ADDIN_PRESENT)) | ((x) << _VIC_MODE_ADDIN_PRESENT))
-+#define VIC_MODE_GET_SEC_ALG(x) (((x) >> _VIC_MODE_SEC_ALG) & _VIC_MODE_SEC_ALG_MASK)
-+#define VIC_MODE_GET_PRED_RESIST(x) (((x) >> _VIC_MODE_PRED_RESIST) & _VIC_MODE_PRED_RESIST_MASK)
-+#define VIC_MODE_GET_ADDIN_PRESENT(x) (((x) >> _VIC_MODE_ADDIN_PRESENT) & _VIC_MODE_ADDIN_PRESENT_MASK)
-+
-+#define VIC_RAND_LEN 4
diff --git a/target/linux/starfive/patches-6.1/1015-pwm-sifive-ptc-Add-SiFive-PWM-PTC-driver.patch b/target/linux/starfive/patches-6.1/1015-pwm-sifive-ptc-Add-SiFive-PWM-PTC-driver.patch
deleted file mode 100644
index 7f47f31fc2..0000000000
--- a/target/linux/starfive/patches-6.1/1015-pwm-sifive-ptc-Add-SiFive-PWM-PTC-driver.patch
+++ /dev/null
@@ -1,309 +0,0 @@
-From 8b3a02992094b5995d5a3e0d6d575aa852961c61 Mon Sep 17 00:00:00 2001
-From: Chenjieqin <Jessica.Chen@starfivetech.com>
-Date: Fri, 8 Jan 2021 03:56:54 +0800
-Subject: [PATCH 1015/1024] pwm: sifive-ptc: Add SiFive PWM PTC driver
-
-yiming.li: clear CNTR of PWM after setting period & duty_cycle
-Emil: cleanups, clock, reset and div_u64
-
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
----
- drivers/pwm/Kconfig | 11 ++
- drivers/pwm/Makefile | 1 +
- drivers/pwm/pwm-sifive-ptc.c | 260 +++++++++++++++++++++++++++++++++++
- 3 files changed, 272 insertions(+)
- create mode 100644 drivers/pwm/pwm-sifive-ptc.c
-
---- a/drivers/pwm/Kconfig
-+++ b/drivers/pwm/Kconfig
-@@ -504,6 +504,17 @@ config PWM_SIFIVE
- To compile this driver as a module, choose M here: the module
- will be called pwm-sifive.
-
-+config PWM_SIFIVE_PTC
-+ tristate "SiFive PWM PTC support"
-+ depends on SOC_SIFIVE || SOC_STARFIVE || COMPILE_TEST
-+ depends on OF
-+ depends on COMMON_CLK
-+ help
-+ Generic PWM framework driver for SiFive SoCs.
-+
-+ To compile this driver as a module, choose M here: the module
-+ will be called pwm-sifive-ptc.
-+
- config PWM_SL28CPLD
- tristate "Kontron sl28cpld PWM support"
- depends on MFD_SL28CPLD || COMPILE_TEST
---- a/drivers/pwm/Makefile
-+++ b/drivers/pwm/Makefile
-@@ -46,6 +46,7 @@ obj-$(CONFIG_PWM_RENESAS_TPU) += pwm-ren
- obj-$(CONFIG_PWM_ROCKCHIP) += pwm-rockchip.o
- obj-$(CONFIG_PWM_SAMSUNG) += pwm-samsung.o
- obj-$(CONFIG_PWM_SIFIVE) += pwm-sifive.o
-+obj-$(CONFIG_PWM_SIFIVE_PTC) += pwm-sifive-ptc.o
- obj-$(CONFIG_PWM_SL28CPLD) += pwm-sl28cpld.o
- obj-$(CONFIG_PWM_SPEAR) += pwm-spear.o
- obj-$(CONFIG_PWM_SPRD) += pwm-sprd.o
---- /dev/null
-+++ b/drivers/pwm/pwm-sifive-ptc.c
-@@ -0,0 +1,260 @@
-+/*
-+ * Copyright (C) 2018 SiFive, Inc
-+ *
-+ * 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.
-+ */
-+
-+#include <linux/clk.h>
-+#include <linux/io.h>
-+#include <linux/math64.h>
-+#include <linux/module.h>
-+#include <linux/platform_device.h>
-+#include <linux/pwm.h>
-+#include <linux/reset.h>
-+
-+#include <dt-bindings/pwm/pwm.h>
-+
-+/* max channel of pwm */
-+#define MAX_PWM 8
-+
-+/* PTC Register offsets */
-+#define REG_RPTC_CNTR 0x0
-+#define REG_RPTC_HRC 0x4
-+#define REG_RPTC_LRC 0x8
-+#define REG_RPTC_CTRL 0xC
-+
-+/* Bit for PWM clock */
-+#define BIT_PWM_CLOCK_EN 31
-+
-+/* Bit for clock gen soft reset */
-+#define BIT_CLK_GEN_SOFT_RESET 13
-+
-+#define NS_1 1000000000U
-+
-+/* Access PTC register (cntr hrc lrc and ctrl), need to replace PWM_BASE_ADDR */
-+#define REG_PTC_BASE_ADDR_SUB(base, N) \
-+ ((base) + (((N) > 3) ? (((N) - 4) * 0x10 + (1 << 15)) : ((N) * 0x10)))
-+#define REG_PTC_RPTC_CNTR(base, N) (REG_PTC_BASE_ADDR_SUB(base, N))
-+#define REG_PTC_RPTC_HRC(base, N) (REG_PTC_BASE_ADDR_SUB(base, N) + 0x4)
-+#define REG_PTC_RPTC_LRC(base, N) (REG_PTC_BASE_ADDR_SUB(base, N) + 0x8)
-+#define REG_PTC_RPTC_CTRL(base, N) (REG_PTC_BASE_ADDR_SUB(base, N) + 0xC)
-+
-+/* pwm ptc device */
-+struct sifive_pwm_ptc_device {
-+ struct pwm_chip chip;
-+ struct clk *clk;
-+ void __iomem *regs;
-+};
-+
-+static inline struct sifive_pwm_ptc_device *chip_to_sifive_ptc(struct pwm_chip *c)
-+{
-+ return container_of(c, struct sifive_pwm_ptc_device, chip);
-+}
-+
-+static int sifive_pwm_ptc_get_state(struct pwm_chip *chip, struct pwm_device *dev,
-+ struct pwm_state *state)
-+{
-+ struct sifive_pwm_ptc_device *pwm = chip_to_sifive_ptc(chip);
-+ u32 data_lrc;
-+ u32 data_hrc;
-+ u32 pwm_clk_ns = 0;
-+
-+ /* get lrc and hrc data from registe */
-+ data_lrc = ioread32(REG_PTC_RPTC_LRC(pwm->regs, dev->hwpwm));
-+ data_hrc = ioread32(REG_PTC_RPTC_HRC(pwm->regs, dev->hwpwm));
-+
-+ /* how many ns does apb clock elapse */
-+ pwm_clk_ns = NS_1 / clk_get_rate(pwm->clk);
-+
-+ /* pwm period(ns) */
-+ state->period = data_lrc * pwm_clk_ns;
-+
-+ /* duty cycle(ns) means high level eclapse ns if it is normal polarity */
-+ state->duty_cycle = data_hrc * pwm_clk_ns;
-+
-+ /* polarity, we don't use it now because it is not in dts */
-+ state->polarity = PWM_POLARITY_NORMAL;
-+
-+ /* enabled or not */
-+ state->enabled = 1;
-+
-+ dev_dbg(pwm->chip.dev, "%s: no:%d\n", __func__, dev->hwpwm);
-+ dev_dbg(pwm->chip.dev, "data_hrc:0x%x 0x%x\n", data_hrc, data_lrc);
-+ dev_dbg(pwm->chip.dev, "period:%llu\n", state->period);
-+ dev_dbg(pwm->chip.dev, "duty_cycle:%llu\n", state->duty_cycle);
-+ dev_dbg(pwm->chip.dev, "polarity:%d\n", state->polarity);
-+ dev_dbg(pwm->chip.dev, "enabled:%d\n", state->enabled);
-+
-+ return 0;
-+}
-+
-+static int sifive_pwm_ptc_apply(struct pwm_chip *chip, struct pwm_device *dev,
-+ const struct pwm_state *state)
-+{
-+ struct sifive_pwm_ptc_device *pwm = chip_to_sifive_ptc(chip);
-+ void __iomem *reg_addr;
-+ u32 pwm_clk_ns = 0;
-+ u32 data_hrc = 0;
-+ u32 data_lrc = 0;
-+ u32 period_data = 0;
-+ u32 duty_data = 0;
-+
-+ dev_dbg(pwm->chip.dev, "%s: no:%d\n", __func__, dev->hwpwm);
-+ dev_dbg(pwm->chip.dev, "period:%llu\n", state->period);
-+ dev_dbg(pwm->chip.dev, "duty_cycle:%llu\n", state->duty_cycle);
-+ dev_dbg(pwm->chip.dev, "polarity:%d\n", state->polarity);
-+ dev_dbg(pwm->chip.dev, "enabled:%d\n", state->enabled);
-+
-+ /* duty_cycle should be less or equal than period */
-+ if (state->duty_cycle > state->period)
-+ return -EINVAL;
-+
-+ /* calculate pwm real period (ns) */
-+ pwm_clk_ns = NS_1 / clk_get_rate(pwm->clk);
-+
-+ dev_dbg(pwm->chip.dev, "pwm_clk_ns:%u\n", pwm_clk_ns);
-+
-+ /* calculate period count */
-+ period_data = div_u64(state->period, pwm_clk_ns);
-+
-+ if (!state->enabled)
-+ /* if disabled, just set duty_data to 0, which means low level always */
-+ duty_data = 0;
-+ else
-+ /* calculate duty count */
-+ duty_data = div_u64(state->duty_cycle, pwm_clk_ns);
-+
-+ dev_dbg(pwm->chip.dev, "period_data:%u, duty_data:%u\n",
-+ period_data, duty_data);
-+
-+ if (state->polarity == PWM_POLARITY_NORMAL)
-+ /* calculate data_hrc */
-+ data_hrc = period_data - duty_data;
-+ else
-+ /* calculate data_hrc */
-+ data_hrc = duty_data;
-+
-+ data_lrc = period_data;
-+
-+ /* set hrc */
-+ reg_addr = REG_PTC_RPTC_HRC(pwm->regs, dev->hwpwm);
-+ dev_dbg(pwm->chip.dev, "%s: reg_addr:%p, data:%u\n",
-+ __func__, reg_addr, data_hrc);
-+
-+ iowrite32(data_hrc, reg_addr);
-+
-+ dev_dbg(pwm->chip.dev, "%s: hrc ok\n", __func__);
-+
-+ /* set lrc */
-+ reg_addr = REG_PTC_RPTC_LRC(pwm->regs, dev->hwpwm);
-+ dev_dbg(pwm->chip.dev, "%s: reg_addr:%p, data:%u\n",
-+ __func__, reg_addr, data_lrc);
-+
-+ iowrite32(data_lrc, reg_addr);
-+ dev_dbg(pwm->chip.dev, "%s: lrc ok\n", __func__);
-+
-+ /* Clear REG_RPTC_CNTR after setting period & duty_cycle */
-+ reg_addr = REG_PTC_RPTC_CNTR(pwm->regs, dev->hwpwm);
-+ iowrite32(0, reg_addr);
-+ return 0;
-+}
-+
-+static const struct pwm_ops sifive_pwm_ptc_ops = {
-+ .get_state = sifive_pwm_ptc_get_state,
-+ .apply = sifive_pwm_ptc_apply,
-+ .owner = THIS_MODULE,
-+};
-+
-+static void sifive_pwm_ptc_disable_action(void *data)
-+{
-+ clk_disable_unprepare(data);
-+}
-+
-+static int sifive_pwm_ptc_probe(struct platform_device *pdev)
-+{
-+ struct device *dev = &pdev->dev;
-+ struct device_node *node = pdev->dev.of_node;
-+ struct sifive_pwm_ptc_device *pwm;
-+ struct pwm_chip *chip;
-+ struct reset_control *rst;
-+ int ret;
-+
-+ pwm = devm_kzalloc(dev, sizeof(*pwm), GFP_KERNEL);
-+ if (!pwm)
-+ return -ENOMEM;
-+
-+ platform_set_drvdata(pdev, pwm);
-+
-+ chip = &pwm->chip;
-+ chip->dev = dev;
-+ chip->ops = &sifive_pwm_ptc_ops;
-+
-+ /* how many parameters can be transferred to ptc, need to fix */
-+ chip->of_pwm_n_cells = 3;
-+ chip->base = -1;
-+
-+ /* get pwm channels count, max value is 8 */
-+ ret = of_property_read_u32(node, "starfive,npwm", &chip->npwm);
-+ if (ret < 0 || chip->npwm > MAX_PWM)
-+ chip->npwm = MAX_PWM;
-+
-+ dev_dbg(dev, "%s: npwm:0x%x\n", __func__, chip->npwm);
-+
-+ /* get IO base address */
-+ pwm->regs = devm_platform_ioremap_resource(pdev, 0);
-+ if (IS_ERR(pwm->regs))
-+ return dev_err_probe(dev, PTR_ERR(pwm->regs),
-+ "Unable to map IO resources\n");
-+
-+ pwm->clk = devm_clk_get(dev, NULL);
-+ if (IS_ERR(pwm->clk))
-+ return dev_err_probe(dev, PTR_ERR(pwm->clk),
-+ "Unable to get controller clock\n");
-+
-+ ret = clk_prepare_enable(pwm->clk);
-+ if (ret)
-+ return dev_err_probe(dev, ret, "Unable to enable clock\n");
-+
-+ ret = devm_add_action_or_reset(dev, sifive_pwm_ptc_disable_action, pwm->clk);
-+ if (ret)
-+ return ret;
-+
-+ rst = devm_reset_control_get_exclusive(dev, NULL);
-+ if (IS_ERR(rst))
-+ return dev_err_probe(dev, PTR_ERR(rst), "Unable to get reset\n");
-+
-+ ret = reset_control_deassert(rst);
-+ if (ret)
-+ return dev_err_probe(dev, ret, "Unable to deassert reset\n");
-+
-+ /*
-+ * after pwmchip_add it will show up as /sys/class/pwm/pwmchip0,
-+ * 0 is chip->base, pwm0 can be seen after running echo 0 > export
-+ */
-+ ret = devm_pwmchip_add(dev, chip);
-+ if (ret)
-+ return dev_err_probe(dev, ret, "cannot register PTC: %d\n", ret);
-+
-+ dev_dbg(dev, "SiFive PWM PTC chip registered %d PWMs\n", chip->npwm);
-+ return 0;
-+}
-+
-+static const struct of_device_id sifive_pwm_ptc_of_match[] = {
-+ { .compatible = "starfive,pwm0" },
-+ { /* sentinel */ }
-+};
-+MODULE_DEVICE_TABLE(of, sifive_pwm_ptc_of_match);
-+
-+static struct platform_driver sifive_pwm_ptc_driver = {
-+ .probe = sifive_pwm_ptc_probe,
-+ .driver = {
-+ .name = "pwm-sifive-ptc",
-+ .of_match_table = sifive_pwm_ptc_of_match,
-+ },
-+};
-+module_platform_driver(sifive_pwm_ptc_driver);
-+
-+MODULE_DESCRIPTION("SiFive PWM PTC driver");
-+MODULE_LICENSE("GPL v2");
diff --git a/target/linux/starfive/patches-6.1/1016-riscv-Implement-non-coherent-DMA-support-via-SiFive-.patch b/target/linux/starfive/patches-6.1/1016-riscv-Implement-non-coherent-DMA-support-via-SiFive-.patch
deleted file mode 100644
index d8a2befe64..0000000000
--- a/target/linux/starfive/patches-6.1/1016-riscv-Implement-non-coherent-DMA-support-via-SiFive-.patch
+++ /dev/null
@@ -1,105 +0,0 @@
-From d30b864417ea3ad1bc4fcf675ea072cb19011930 Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Sat, 12 Jun 2021 16:48:31 -0700
-Subject: [PATCH 1016/1024] riscv: Implement non-coherent DMA support via
- SiFive cache flushing
-
-This variant is used on the StarFive JH7100 SoC.
-
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
----
- arch/riscv/Kconfig | 6 ++++--
- arch/riscv/mm/dma-noncoherent.c | 37 +++++++++++++++++++++++++++++++--
- 2 files changed, 39 insertions(+), 4 deletions(-)
-
---- a/arch/riscv/Kconfig
-+++ b/arch/riscv/Kconfig
-@@ -225,12 +225,14 @@ config LOCKDEP_SUPPORT
- def_bool y
-
- config RISCV_DMA_NONCOHERENT
-- bool
-+ bool "Support non-coherent DMA"
-+ default SOC_STARFIVE
- select ARCH_HAS_DMA_PREP_COHERENT
-+ select ARCH_HAS_DMA_SET_UNCACHED
-+ select ARCH_HAS_DMA_CLEAR_UNCACHED
- select ARCH_HAS_SYNC_DMA_FOR_DEVICE
- select ARCH_HAS_SYNC_DMA_FOR_CPU
- select ARCH_HAS_SETUP_DMA_OPS
-- select DMA_DIRECT_REMAP
-
- config AS_HAS_INSN
- def_bool $(as-instr,.insn r 51$(comma) 0$(comma) 0$(comma) t0$(comma) t0$(comma) zero)
---- a/arch/riscv/mm/dma-noncoherent.c
-+++ b/arch/riscv/mm/dma-noncoherent.c
-@@ -9,14 +9,21 @@
- #include <linux/dma-map-ops.h>
- #include <linux/mm.h>
- #include <asm/cacheflush.h>
-+#include <soc/sifive/sifive_ccache.h>
-
- static bool noncoherent_supported;
-
- void arch_sync_dma_for_device(phys_addr_t paddr, size_t size,
- enum dma_data_direction dir)
- {
-- void *vaddr = phys_to_virt(paddr);
-+ void *vaddr;
-
-+ if (sifive_ccache_handle_noncoherent()) {
-+ sifive_ccache_flush_range(paddr, size);
-+ return;
-+ }
-+
-+ vaddr = phys_to_virt(paddr);
- switch (dir) {
- case DMA_TO_DEVICE:
- ALT_CMO_OP(clean, vaddr, size, riscv_cbom_block_size);
-@@ -35,8 +42,14 @@ void arch_sync_dma_for_device(phys_addr_
- void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size,
- enum dma_data_direction dir)
- {
-- void *vaddr = phys_to_virt(paddr);
-+ void *vaddr;
-+
-+ if (sifive_ccache_handle_noncoherent()) {
-+ sifive_ccache_flush_range(paddr, size);
-+ return;
-+ }
-
-+ vaddr = phys_to_virt(paddr);
- switch (dir) {
- case DMA_TO_DEVICE:
- break;
-@@ -49,10 +62,30 @@ void arch_sync_dma_for_cpu(phys_addr_t p
- }
- }
-
-+void *arch_dma_set_uncached(void *addr, size_t size)
-+{
-+ if (sifive_ccache_handle_noncoherent())
-+ return sifive_ccache_set_uncached(addr, size);
-+
-+ return addr;
-+}
-+
-+void arch_dma_clear_uncached(void *addr, size_t size)
-+{
-+ if (sifive_ccache_handle_noncoherent())
-+ sifive_ccache_clear_uncached(addr, size);
-+}
-+
- void arch_dma_prep_coherent(struct page *page, size_t size)
- {
- void *flush_addr = page_address(page);
-
-+ if (sifive_ccache_handle_noncoherent()) {
-+ memset(flush_addr, 0, size);
-+ sifive_ccache_flush_range(__pa(flush_addr), size);
-+ return;
-+ }
-+
- ALT_CMO_OP(flush, flush_addr, size, riscv_cbom_block_size);
- }
-
diff --git a/target/linux/starfive/patches-6.1/1017-dt-bindings-riscv-sifive-ccache-Add-uncached-offset-.patch b/target/linux/starfive/patches-6.1/1017-dt-bindings-riscv-sifive-ccache-Add-uncached-offset-.patch
deleted file mode 100644
index 7de04411ed..0000000000
--- a/target/linux/starfive/patches-6.1/1017-dt-bindings-riscv-sifive-ccache-Add-uncached-offset-.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 3b83b32e16fa431c76a5da1ac59c268ca2fecbb5 Mon Sep 17 00:00:00 2001
-From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
-Date: Sat, 11 Feb 2023 05:18:11 +0200
-Subject: [PATCH 1017/1024] dt-bindings: riscv: sifive-ccache: Add
- 'uncached-offset' property
-
-Add the 'uncached-offset' property to be used for specifying the
-uncached memory offset required for handling non-coherent DMA
-transactions.
-
-Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
-Link: https://lore.kernel.org/r/20230211031821.976408-3-cristian.ciocaltea@collabora.com
----
- Documentation/devicetree/bindings/riscv/sifive,ccache0.yaml | 5 +++++
- 1 file changed, 5 insertions(+)
-
---- a/Documentation/devicetree/bindings/riscv/sifive,ccache0.yaml
-+++ b/Documentation/devicetree/bindings/riscv/sifive,ccache0.yaml
-@@ -70,6 +70,11 @@ properties:
-
- next-level-cache: true
-
-+ uncached-offset:
-+ $ref: /schemas/types.yaml#/definitions/uint64
-+ description: |
-+ Uncached memory offset for handling non-coherent DMA transactions.
-+
- memory-region:
- maxItems: 1
- description: |
diff --git a/target/linux/starfive/patches-6.1/1018-soc-sifive-ccache-Add-StarFive-JH71x0-support.patch b/target/linux/starfive/patches-6.1/1018-soc-sifive-ccache-Add-StarFive-JH71x0-support.patch
deleted file mode 100644
index 04d1e5aa1e..0000000000
--- a/target/linux/starfive/patches-6.1/1018-soc-sifive-ccache-Add-StarFive-JH71x0-support.patch
+++ /dev/null
@@ -1,77 +0,0 @@
-From cde57aebfd86b3b062ce0bcf71395d735d05b2f6 Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Wed, 6 Apr 2022 00:38:05 +0200
-Subject: [PATCH 1018/1024] soc: sifive: ccache: Add StarFive JH71x0 support
-
-This adds support for the StarFive JH7100 and JH7110 SoCs which also
-feature this SiFive cache controller.
-
-Unfortunately the interrupt for uncorrected data is broken on the JH7100
-and fires continuously, so add a quirk to not register a handler for it.
-
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
----
- arch/riscv/Kconfig.socs | 1 +
- drivers/soc/sifive/Kconfig | 2 +-
- drivers/soc/sifive/sifive_ccache.c | 12 +++++++++++-
- 3 files changed, 13 insertions(+), 2 deletions(-)
-
---- a/arch/riscv/Kconfig.socs
-+++ b/arch/riscv/Kconfig.socs
-@@ -28,6 +28,7 @@ config SOC_STARFIVE
- bool "StarFive SoCs"
- select PINCTRL
- select RESET_CONTROLLER
-+ select SIFIVE_CCACHE
- select SIFIVE_PLIC
- select ARM_AMBA
- help
---- a/drivers/soc/sifive/Kconfig
-+++ b/drivers/soc/sifive/Kconfig
-@@ -1,6 +1,6 @@
- # SPDX-License-Identifier: GPL-2.0
-
--if SOC_SIFIVE
-+if SOC_SIFIVE || SOC_STARFIVE
-
- config SIFIVE_CCACHE
- bool "Sifive Composable Cache controller"
---- a/drivers/soc/sifive/sifive_ccache.c
-+++ b/drivers/soc/sifive/sifive_ccache.c
-@@ -106,6 +106,8 @@ static void ccache_config_read(void)
- static const struct of_device_id sifive_ccache_ids[] = {
- { .compatible = "sifive,fu540-c000-ccache" },
- { .compatible = "sifive,fu740-c000-ccache" },
-+ { .compatible = "starfive,jh7100-ccache", .data = (void *)BIT(DATA_UNCORR) },
-+ { .compatible = "starfive,jh7110-ccache" },
- { .compatible = "sifive,ccache0" },
- { /* end of table */ }
- };
-@@ -210,11 +212,15 @@ static int __init sifive_ccache_init(voi
- struct device_node *np;
- struct resource res;
- int i, rc, intr_num;
-+ const struct of_device_id *match;
-+ unsigned long broken_irqs;
-
-- np = of_find_matching_node(NULL, sifive_ccache_ids);
-+ np = of_find_matching_node_and_match(NULL, sifive_ccache_ids, &match);
- if (!np)
- return -ENODEV;
-
-+ broken_irqs = (uintptr_t)match->data;
-+
- if (of_address_to_resource(np, 0, &res)) {
- rc = -ENODEV;
- goto err_node_put;
-@@ -240,6 +246,10 @@ static int __init sifive_ccache_init(voi
-
- for (i = 0; i < intr_num; i++) {
- g_irq[i] = irq_of_parse_and_map(np, i);
-+
-+ if (broken_irqs & BIT(i))
-+ continue;
-+
- rc = request_irq(g_irq[i], ccache_int_handler, 0, "ccache_ecc",
- NULL);
- if (rc) {
diff --git a/target/linux/starfive/patches-6.1/1019-soc-sifive-ccache-Add-non-coherent-DMA-handling.patch b/target/linux/starfive/patches-6.1/1019-soc-sifive-ccache-Add-non-coherent-DMA-handling.patch
deleted file mode 100644
index 0713739b5f..0000000000
--- a/target/linux/starfive/patches-6.1/1019-soc-sifive-ccache-Add-non-coherent-DMA-handling.patch
+++ /dev/null
@@ -1,159 +0,0 @@
-From 335c32d2653f2415e042c8ad1ae2a6b33019b96f Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Sat, 12 Jun 2021 16:48:31 -0700
-Subject: [PATCH 1019/1024] soc: sifive: ccache: Add non-coherent DMA handling
-
-Add functions to flush the caches and handle non-coherent DMA.
-
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
----
- drivers/soc/sifive/sifive_ccache.c | 60 +++++++++++++++++++++++++++++-
- include/soc/sifive/sifive_ccache.h | 21 +++++++++++
- 2 files changed, 80 insertions(+), 1 deletion(-)
-
---- a/drivers/soc/sifive/sifive_ccache.c
-+++ b/drivers/soc/sifive/sifive_ccache.c
-@@ -8,13 +8,16 @@
-
- #define pr_fmt(fmt) "CCACHE: " fmt
-
-+#include <linux/align.h>
- #include <linux/debugfs.h>
- #include <linux/interrupt.h>
- #include <linux/of_irq.h>
- #include <linux/of_address.h>
- #include <linux/device.h>
- #include <linux/bitfield.h>
-+#include <asm/cacheflush.h>
- #include <asm/cacheinfo.h>
-+#include <asm/page.h>
- #include <soc/sifive/sifive_ccache.h>
-
- #define SIFIVE_CCACHE_DIRECCFIX_LOW 0x100
-@@ -39,10 +42,14 @@
- #define SIFIVE_CCACHE_CONFIG_SETS_MASK GENMASK_ULL(23, 16)
- #define SIFIVE_CCACHE_CONFIG_BLKS_MASK GENMASK_ULL(31, 24)
-
-+#define SIFIVE_CCACHE_FLUSH64 0x200
-+#define SIFIVE_CCACHE_FLUSH32 0x240
-+
- #define SIFIVE_CCACHE_WAYENABLE 0x08
- #define SIFIVE_CCACHE_ECCINJECTERR 0x40
-
- #define SIFIVE_CCACHE_MAX_ECCINTR 4
-+#define SIFIVE_CCACHE_LINE_SIZE 64
-
- static void __iomem *ccache_base;
- static int g_irq[SIFIVE_CCACHE_MAX_ECCINTR];
-@@ -126,6 +133,47 @@ int unregister_sifive_ccache_error_notif
- }
- EXPORT_SYMBOL_GPL(unregister_sifive_ccache_error_notifier);
-
-+#ifdef CONFIG_RISCV_DMA_NONCOHERENT
-+static phys_addr_t uncached_offset;
-+DEFINE_STATIC_KEY_FALSE(sifive_ccache_handle_noncoherent_key);
-+
-+void sifive_ccache_flush_range(phys_addr_t start, size_t len)
-+{
-+ phys_addr_t end = start + len;
-+ phys_addr_t line;
-+
-+ if (!len)
-+ return;
-+
-+ mb();
-+ for (line = ALIGN_DOWN(start, SIFIVE_CCACHE_LINE_SIZE); line < end;
-+ line += SIFIVE_CCACHE_LINE_SIZE) {
-+#ifdef CONFIG_32BIT
-+ writel(line >> 4, ccache_base + SIFIVE_CCACHE_FLUSH32);
-+#else
-+ writeq(line, ccache_base + SIFIVE_CCACHE_FLUSH64);
-+#endif
-+ mb();
-+ }
-+}
-+EXPORT_SYMBOL_GPL(sifive_ccache_flush_range);
-+
-+void *sifive_ccache_set_uncached(void *addr, size_t size)
-+{
-+ phys_addr_t phys_addr = __pa(addr) + uncached_offset;
-+ void *mem_base;
-+
-+ mem_base = memremap(phys_addr, size, MEMREMAP_WT);
-+ if (!mem_base) {
-+ pr_err("%s memremap failed for addr %p\n", __func__, addr);
-+ return ERR_PTR(-EINVAL);
-+ }
-+
-+ return mem_base;
-+}
-+EXPORT_SYMBOL_GPL(sifive_ccache_set_uncached);
-+#endif /* CONFIG_RISCV_DMA_NONCOHERENT */
-+
- static int ccache_largest_wayenabled(void)
- {
- return readl(ccache_base + SIFIVE_CCACHE_WAYENABLE) & 0xFF;
-@@ -214,6 +262,7 @@ static int __init sifive_ccache_init(voi
- int i, rc, intr_num;
- const struct of_device_id *match;
- unsigned long broken_irqs;
-+ u64 __maybe_unused offset;
-
- np = of_find_matching_node_and_match(NULL, sifive_ccache_ids, &match);
- if (!np)
-@@ -259,6 +308,15 @@ static int __init sifive_ccache_init(voi
- }
- of_node_put(np);
-
-+#ifdef CONFIG_RISCV_DMA_NONCOHERENT
-+ if (!of_property_read_u64(np, "uncached-offset", &offset)) {
-+ uncached_offset = offset;
-+ static_branch_enable(&sifive_ccache_handle_noncoherent_key);
-+ riscv_cbom_block_size = SIFIVE_CCACHE_LINE_SIZE;
-+ riscv_noncoherent_supported();
-+ }
-+#endif
-+
- ccache_config_read();
-
- ccache_cache_ops.get_priv_group = ccache_get_priv_group;
-@@ -279,4 +337,4 @@ err_node_put:
- return rc;
- }
-
--device_initcall(sifive_ccache_init);
-+arch_initcall(sifive_ccache_init);
---- a/include/soc/sifive/sifive_ccache.h
-+++ b/include/soc/sifive/sifive_ccache.h
-@@ -7,10 +7,31 @@
- #ifndef __SOC_SIFIVE_CCACHE_H
- #define __SOC_SIFIVE_CCACHE_H
-
-+#include <linux/io.h>
-+#include <linux/jump_label.h>
-+
- extern int register_sifive_ccache_error_notifier(struct notifier_block *nb);
- extern int unregister_sifive_ccache_error_notifier(struct notifier_block *nb);
-
- #define SIFIVE_CCACHE_ERR_TYPE_CE 0
- #define SIFIVE_CCACHE_ERR_TYPE_UE 1
-
-+DECLARE_STATIC_KEY_FALSE(sifive_ccache_handle_noncoherent_key);
-+
-+static inline bool sifive_ccache_handle_noncoherent(void)
-+{
-+#ifdef CONFIG_SIFIVE_CCACHE
-+ return static_branch_unlikely(&sifive_ccache_handle_noncoherent_key);
-+#else
-+ return false;
-+#endif
-+}
-+
-+void sifive_ccache_flush_range(phys_addr_t start, size_t len);
-+void *sifive_ccache_set_uncached(void *addr, size_t size);
-+static inline void sifive_ccache_clear_uncached(void *addr, size_t size)
-+{
-+ memunmap(addr);
-+}
-+
- #endif /* __SOC_SIFIVE_CCACHE_H */
diff --git a/target/linux/starfive/patches-6.1/1020-dt-bindings-reset-Add-StarFive-JH7100-audio-reset-de.patch b/target/linux/starfive/patches-6.1/1020-dt-bindings-reset-Add-StarFive-JH7100-audio-reset-de.patch
deleted file mode 100644
index 7641c559d5..0000000000
--- a/target/linux/starfive/patches-6.1/1020-dt-bindings-reset-Add-StarFive-JH7100-audio-reset-de.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From f684a12dac29522c6ce9d504522f75dcf024fc5f Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Sat, 20 Nov 2021 19:29:25 +0100
-Subject: [PATCH 1020/1024] dt-bindings: reset: Add StarFive JH7100 audio reset
- definitions
-
-Add all resets for the StarFive JH7100 audio reset controller.
-
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
----
- .../dt-bindings/reset/starfive-jh7100-audio.h | 31 +++++++++++++++++++
- 1 file changed, 31 insertions(+)
- create mode 100644 include/dt-bindings/reset/starfive-jh7100-audio.h
-
---- /dev/null
-+++ b/include/dt-bindings/reset/starfive-jh7100-audio.h
-@@ -0,0 +1,31 @@
-+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
-+/*
-+ * Copyright (C) 2021 Emil Renner Berthing
-+ */
-+
-+#ifndef __DT_BINDINGS_RESET_STARFIVE_JH7100_AUDIO_H__
-+#define __DT_BINDINGS_RESET_STARFIVE_JH7100_AUDIO_H__
-+
-+#define JH7100_AUDRSTN_APB_BUS 0
-+#define JH7100_AUDRSTN_I2SADC_APB 1
-+#define JH7100_AUDRSTN_I2SADC_SRST 2
-+#define JH7100_AUDRSTN_PDM_APB 3
-+#define JH7100_AUDRSTN_I2SVAD_APB 4
-+#define JH7100_AUDRSTN_I2SVAD_SRST 5
-+#define JH7100_AUDRSTN_SPDIF_APB 6
-+#define JH7100_AUDRSTN_PWMDAC_APB 7
-+#define JH7100_AUDRSTN_I2SDAC_APB 8
-+#define JH7100_AUDRSTN_I2SDAC_SRST 9
-+#define JH7100_AUDRSTN_I2S1_APB 10
-+#define JH7100_AUDRSTN_I2S1_SRST 11
-+#define JH7100_AUDRSTN_I2SDAC16K_APB 12
-+#define JH7100_AUDRSTN_I2SDAC16K_SRST 13
-+#define JH7100_AUDRSTN_DMA1P_AHB 14
-+#define JH7100_AUDRSTN_USB_APB 15
-+#define JH7100_AUDRST_USB_AXI 16
-+#define JH7100_AUDRST_USB_PWRUP_RST_N 17
-+#define JH7100_AUDRST_USB_PONRST 18
-+
-+#define JH7100_AUDRSTN_END 19
-+
-+#endif /* __DT_BINDINGS_RESET_STARFIVE_JH7100_AUDIO_H__ */
diff --git a/target/linux/starfive/patches-6.1/1021-dt-bindings-reset-Add-starfive-jh7100-audrst-binding.patch b/target/linux/starfive/patches-6.1/1021-dt-bindings-reset-Add-starfive-jh7100-audrst-binding.patch
deleted file mode 100644
index 413833707a..0000000000
--- a/target/linux/starfive/patches-6.1/1021-dt-bindings-reset-Add-starfive-jh7100-audrst-binding.patch
+++ /dev/null
@@ -1,56 +0,0 @@
-From 9220294c675a111651ff12b2389a81f0935553fd Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Tue, 7 Dec 2021 21:48:51 +0100
-Subject: [PATCH 1021/1024] dt-bindings: reset: Add starfive,jh7100-audrst
- bindings
-
-Add bindings for the audio reset controller on the StarFive JH7100
-RISC-V SoC.
-
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
----
- .../reset/starfive,jh7100-audrst.yaml | 38 +++++++++++++++++++
- 1 file changed, 38 insertions(+)
- create mode 100644 Documentation/devicetree/bindings/reset/starfive,jh7100-audrst.yaml
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/reset/starfive,jh7100-audrst.yaml
-@@ -0,0 +1,38 @@
-+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/reset/starfive,jh7100-audrst.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: StarFive JH7100 SoC Audio Reset Controller Device Tree Bindings
-+
-+maintainers:
-+ - Emil Renner Berthing <kernel@esmil.dk>
-+
-+properties:
-+ compatible:
-+ enum:
-+ - starfive,jh7100-audrst
-+
-+ reg:
-+ maxItems: 1
-+
-+ "#reset-cells":
-+ const: 1
-+
-+required:
-+ - compatible
-+ - reg
-+ - "#reset-cells"
-+
-+additionalProperties: false
-+
-+examples:
-+ - |
-+ reset-controller@10490000 {
-+ compatible = "starfive,jh7100-audrst";
-+ reg = <0x10490000 0x10000>;
-+ #reset-cells = <1>;
-+ };
-+
-+...
diff --git a/target/linux/starfive/patches-6.1/1022-reset-starfive-Add-JH7100-audio-reset-driver.patch b/target/linux/starfive/patches-6.1/1022-reset-starfive-Add-JH7100-audio-reset-driver.patch
deleted file mode 100644
index bf3eff0157..0000000000
--- a/target/linux/starfive/patches-6.1/1022-reset-starfive-Add-JH7100-audio-reset-driver.patch
+++ /dev/null
@@ -1,144 +0,0 @@
-From ff806bda9b04bcf73350e319f3efde5cd049b77a Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Sat, 20 Nov 2021 19:30:49 +0100
-Subject: [PATCH 1022/1024] reset: starfive: Add JH7100 audio reset driver
-
-The audio resets are almost identical to the system resets, there are
-just fewer of them. So factor out and export a generic probe function,
-so most of the reset controller implementation can be shared.
-
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
----
- MAINTAINERS | 2 +-
- drivers/reset/starfive/Kconfig | 7 ++
- drivers/reset/starfive/Makefile | 2 +
- .../starfive/reset-starfive-jh7100-audio.c | 66 +++++++++++++++++++
- .../reset/starfive/reset-starfive-jh7100.h | 16 +++++
- 5 files changed, 92 insertions(+), 1 deletion(-)
- create mode 100644 drivers/reset/starfive/reset-starfive-jh7100-audio.c
- create mode 100644 drivers/reset/starfive/reset-starfive-jh7100.h
-
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -19711,7 +19711,7 @@ STARFIVE JH71X0 RESET CONTROLLER DRIVERS
- M: Emil Renner Berthing <kernel@esmil.dk>
- M: Hal Feng <hal.feng@starfivetech.com>
- S: Maintained
--F: Documentation/devicetree/bindings/reset/starfive,jh7100-reset.yaml
-+F: Documentation/devicetree/bindings/reset/starfive,jh7100-*.yaml
- F: drivers/reset/starfive/reset-starfive-jh71*
- F: include/dt-bindings/reset/starfive?jh71*.h
-
---- a/drivers/reset/starfive/Kconfig
-+++ b/drivers/reset/starfive/Kconfig
-@@ -11,6 +11,13 @@ config RESET_STARFIVE_JH7100
- help
- This enables the reset controller driver for the StarFive JH7100 SoC.
-
-+config RESET_STARFIVE_JH7100_AUDIO
-+ tristate "StarFive JH7100 Audio Reset Driver"
-+ depends on RESET_STARFIVE_JH7100
-+ default m if SOC_STARFIVE
-+ help
-+ This enables the audio reset driver for the StarFive JH7100 SoC.
-+
- config RESET_STARFIVE_JH7110
- bool "StarFive JH7110 Reset Driver"
- depends on AUXILIARY_BUS && CLK_STARFIVE_JH7110_SYS
---- a/drivers/reset/starfive/Makefile
-+++ b/drivers/reset/starfive/Makefile
-@@ -2,4 +2,6 @@
- obj-$(CONFIG_RESET_STARFIVE_JH71X0) += reset-starfive-jh71x0.o
-
- obj-$(CONFIG_RESET_STARFIVE_JH7100) += reset-starfive-jh7100.o
-+obj-$(CONFIG_RESET_STARFIVE_JH7100_AUDIO) += reset-starfive-jh7100-audio.o
-+
- obj-$(CONFIG_RESET_STARFIVE_JH7110) += reset-starfive-jh7110.o
---- /dev/null
-+++ b/drivers/reset/starfive/reset-starfive-jh7100-audio.c
-@@ -0,0 +1,66 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later
-+/*
-+ * Audio reset driver for the StarFive JH7100 SoC
-+ *
-+ * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
-+ */
-+
-+#include <linux/mod_devicetable.h>
-+#include <linux/module.h>
-+#include <linux/platform_device.h>
-+
-+#include "reset-starfive-jh71x0.h"
-+
-+#include <dt-bindings/reset/starfive-jh7100-audio.h>
-+
-+/* register offsets */
-+#define JH7100_AUDRST_ASSERT0 0x00
-+#define JH7100_AUDRST_STATUS0 0x04
-+
-+/*
-+ * Writing a 1 to the n'th bit of the ASSERT register asserts
-+ * line n, and writing a 0 deasserts the same line.
-+ * Most reset lines have their status inverted so a 0 bit in the STATUS
-+ * register means the line is asserted and a 1 means it's deasserted. A few
-+ * lines don't though, so store the expected value of the status registers when
-+ * all lines are asserted.
-+ */
-+static const u32 jh7100_audrst_asserted[1] = {
-+ BIT(JH7100_AUDRST_USB_AXI) |
-+ BIT(JH7100_AUDRST_USB_PWRUP_RST_N) |
-+ BIT(JH7100_AUDRST_USB_PONRST)
-+};
-+
-+static int jh7100_audrst_probe(struct platform_device *pdev)
-+{
-+ void __iomem *base = devm_platform_ioremap_resource(pdev, 0);
-+
-+ if (IS_ERR(base))
-+ return PTR_ERR(base);
-+
-+ return reset_starfive_jh71x0_register(&pdev->dev, pdev->dev.of_node,
-+ base + JH7100_AUDRST_ASSERT0,
-+ base + JH7100_AUDRST_STATUS0,
-+ jh7100_audrst_asserted,
-+ JH7100_AUDRSTN_END,
-+ THIS_MODULE);
-+}
-+
-+static const struct of_device_id jh7100_audrst_dt_ids[] = {
-+ { .compatible = "starfive,jh7100-audrst" },
-+ { /* sentinel */ }
-+};
-+MODULE_DEVICE_TABLE(of, jh7100_audrst_dt_ids);
-+
-+static struct platform_driver jh7100_audrst_driver = {
-+ .probe = jh7100_audrst_probe,
-+ .driver = {
-+ .name = "jh7100-reset-audio",
-+ .of_match_table = jh7100_audrst_dt_ids,
-+ },
-+};
-+module_platform_driver(jh7100_audrst_driver);
-+
-+MODULE_AUTHOR("Emil Renner Berthing");
-+MODULE_DESCRIPTION("StarFive JH7100 audio reset driver");
-+MODULE_LICENSE("GPL");
---- /dev/null
-+++ b/drivers/reset/starfive/reset-starfive-jh7100.h
-@@ -0,0 +1,16 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later
-+/*
-+ * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
-+ */
-+
-+#ifndef _RESET_STARFIVE_JH7100_H_
-+#define _RESET_STARFIVE_JH7100_H_
-+
-+#include <linux/platform_device.h>
-+
-+int reset_starfive_jh7100_generic_probe(struct platform_device *pdev,
-+ const u32 *asserted,
-+ unsigned int status_offset,
-+ unsigned int nr_resets);
-+
-+#endif
diff --git a/target/linux/starfive/patches-6.1/1023-RISC-V-Add-StarFive-JH7100-audio-reset-node.patch b/target/linux/starfive/patches-6.1/1023-RISC-V-Add-StarFive-JH7100-audio-reset-node.patch
deleted file mode 100644
index 0ef6fa485e..0000000000
--- a/target/linux/starfive/patches-6.1/1023-RISC-V-Add-StarFive-JH7100-audio-reset-node.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From f7ab709727e845ffdfc428ec2f236d0c1997b153 Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Sat, 20 Nov 2021 21:33:08 +0100
-Subject: [PATCH 1023/1024] RISC-V: Add StarFive JH7100 audio reset node
-
-Add device tree node for the audio resets on the StarFive JH7100 RISC-V
-SoC.
-
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
----
- arch/riscv/boot/dts/starfive/jh7100.dtsi | 6 ++++++
- 1 file changed, 6 insertions(+)
-
---- a/arch/riscv/boot/dts/starfive/jh7100.dtsi
-+++ b/arch/riscv/boot/dts/starfive/jh7100.dtsi
-@@ -144,6 +144,12 @@
- #clock-cells = <1>;
- };
-
-+ audrst: reset-controller@10490000 {
-+ compatible = "starfive,jh7100-audrst";
-+ reg = <0x0 0x10490000 0x0 0x10000>;
-+ #reset-cells = <1>;
-+ };
-+
- clkgen: clock-controller@11800000 {
- compatible = "starfive,jh7100-clkgen";
- reg = <0x0 0x11800000 0x0 0x10000>;
diff --git a/target/linux/starfive/patches-6.1/1024-riscv-dts-Add-full-JH7100-Starlight-and-VisionFive-s.patch b/target/linux/starfive/patches-6.1/1024-riscv-dts-Add-full-JH7100-Starlight-and-VisionFive-s.patch
deleted file mode 100644
index 92176679de..0000000000
--- a/target/linux/starfive/patches-6.1/1024-riscv-dts-Add-full-JH7100-Starlight-and-VisionFive-s.patch
+++ /dev/null
@@ -1,1265 +0,0 @@
-From 9912cdc9038c40fbcb1f121445519efb55dec046 Mon Sep 17 00:00:00 2001
-From: Emil Renner Berthing <kernel@esmil.dk>
-Date: Sun, 31 Oct 2021 17:15:58 +0100
-Subject: [PATCH 1024/1024] riscv: dts: Add full JH7100, Starlight and
- VisionFive support
-
-Based on the device tree in https://github.com/starfive-tech/u-boot/
-with contributions from:
-yanhong.wang <yanhong.wang@starfivetech.com>
-Huan.Feng <huan.feng@starfivetech.com>
-ke.zhu <ke.zhu@starfivetech.com>
-yiming.li <yiming.li@starfivetech.com>
-jack.zhu <jack.zhu@starfivetech.com>
-Samin Guo <samin.guo@starfivetech.com>
-Chenjieqin <Jessica.Chen@starfivetech.com>
-bo.li <bo.li@starfivetech.com>
-
-Rearranged, cleanups, fixes, pins and resets added by Emil.
-Cleanups, fixes, clocks added by Geert.
-Cleanups and GPIO fixes from Drew.
-Thermal zone added by Stephen.
-PWM pins added by Jianlong.
-cpu-map added by Jonas.
-
-Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
-Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
-Signed-off-by: Stephen L Arnold <nerdboy@gentoo.org>
-Signed-off-by: Drew Fustini <drew@beagleboard.org>
-Signed-off-by: Jianlong Huang <jianlong.huang@starfivetech.com>
-Signed-off-by: Jonas Hahnfeld <hahnjo@hahnjo.de>
----
- arch/riscv/boot/dts/starfive/Makefile | 1 +
- .../starfive/jh7100-beaglev-starlight-a1.dts | 30 +
- .../dts/starfive/jh7100-beaglev-starlight.dts | 16 +
- .../boot/dts/starfive/jh7100-common.dtsi | 434 ++++++++++++++
- .../jh7100-starfive-visionfive-v1.dts | 19 +
- arch/riscv/boot/dts/starfive/jh7100.dtsi | 561 ++++++++++++++++++
- 6 files changed, 1061 insertions(+)
- create mode 100644 arch/riscv/boot/dts/starfive/jh7100-beaglev-starlight-a1.dts
-
---- a/arch/riscv/boot/dts/starfive/Makefile
-+++ b/arch/riscv/boot/dts/starfive/Makefile
-@@ -1,4 +1,5 @@
- # SPDX-License-Identifier: GPL-2.0
-+dtb-$(CONFIG_ARCH_STARFIVE) += jh7100-beaglev-starlight-a1.dtb
- dtb-$(CONFIG_ARCH_STARFIVE) += jh7100-beaglev-starlight.dtb
- dtb-$(CONFIG_ARCH_STARFIVE) += jh7100-starfive-visionfive-v1.dtb
-
---- /dev/null
-+++ b/arch/riscv/boot/dts/starfive/jh7100-beaglev-starlight-a1.dts
-@@ -0,0 +1,30 @@
-+// SPDX-License-Identifier: GPL-2.0 OR MIT
-+/*
-+ * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
-+ */
-+
-+/dts-v1/;
-+#include "jh7100-common.dtsi"
-+#include <dt-bindings/gpio/gpio.h>
-+
-+/ {
-+ model = "BeagleV Starlight Beta A1";
-+ compatible = "beagle,beaglev-starlight-jh7100-a1", "starfive,jh7100";
-+
-+ gpio-restart {
-+ compatible = "gpio-restart";
-+ gpios = <&gpio 63 GPIO_ACTIVE_HIGH>;
-+ priority = <224>;
-+ };
-+};
-+
-+&gpio {
-+ /* don't reset gpio mux for serial console and reset gpio */
-+ starfive,keep-gpiomux = <13 14 63>;
-+};
-+
-+&mdio {
-+ phy: ethernet-phy@7 {
-+ reg = <7>;
-+ };
-+};
---- a/arch/riscv/boot/dts/starfive/jh7100-beaglev-starlight.dts
-+++ b/arch/riscv/boot/dts/starfive/jh7100-beaglev-starlight.dts
-@@ -6,8 +6,24 @@
-
- /dts-v1/;
- #include "jh7100-common.dtsi"
-+#include <dt-bindings/gpio/gpio.h>
-
- / {
- model = "BeagleV Starlight Beta";
- compatible = "beagle,beaglev-starlight-jh7100-r0", "starfive,jh7100";
- };
-+
-+&gmac {
-+ snps,reset-gpios = <&gpio 63 GPIO_ACTIVE_LOW>;
-+};
-+
-+&gpio {
-+ /* don't reset gpio mux for serial console on uart3 */
-+ starfive,keep-gpiomux = <13 14>;
-+};
-+
-+&mdio {
-+ phy: ethernet-phy@7 {
-+ reg = <7>;
-+ };
-+};
---- a/arch/riscv/boot/dts/starfive/jh7100-common.dtsi
-+++ b/arch/riscv/boot/dts/starfive/jh7100-common.dtsi
-@@ -12,7 +12,10 @@
-
- / {
- aliases {
-+ mmc0 = &sdio0;
-+ mmc1 = &sdio1;
- serial0 = &uart3;
-+ serial1 = &uart0;
- };
-
- chosen {
-@@ -39,9 +42,174 @@
- label = "ack";
- };
- };
-+
-+ reserved-memory {
-+ #address-cells = <2>;
-+ #size-cells = <2>;
-+ ranges;
-+
-+ linux,cma {
-+ compatible = "shared-dma-pool";
-+ reusable;
-+ size = <0x0 0x28000000>;
-+ alignment = <0x0 0x1000>;
-+ alloc-ranges = <0x0 0xa0000000 0x0 0x28000000>;
-+ linux,cma-default;
-+ };
-+
-+ jpu_reserved: framebuffer@c9000000 {
-+ reg = <0x0 0xc9000000 0x0 0x4000000>;
-+ };
-+
-+ nvdla_reserved: framebuffer@d0000000 {
-+ no-map;
-+ reg = <0x0 0xd0000000 0x0 0x28000000>;
-+ };
-+
-+ vin_reserved: framebuffer@f9000000 {
-+ compatible = "shared-dma-pool";
-+ no-map;
-+ reg = <0x0 0xf9000000 0x0 0x1000000>;
-+ };
-+
-+ sffb_reserved: framebuffer@fb000000 {
-+ compatible = "shared-dma-pool";
-+ no-map;
-+ reg = <0x0 0xfb000000 0x0 0x2000000>;
-+ };
-+ };
-+
-+ wifi_pwrseq: wifi-pwrseq {
-+ compatible = "mmc-pwrseq-simple";
-+ reset-gpios = <&gpio 37 GPIO_ACTIVE_LOW>;
-+ };
-+};
-+
-+&display {
-+ memory-region = <&sffb_reserved>;
-+ status = "okay";
-+};
-+
-+&crtc {
-+ ddr-format = <4>; //<WIN_FMT_RGB565>;
-+ status = "okay";
-+
-+ port: port@0 {
-+ reg = <0>;
-+
-+ crtc_0_out: endpoint {
-+ remote-endpoint = <&hdmi_input0>;
-+ };
-+ };
-+};
-+
-+&encoder {
-+ encoder-type = <2>; // 2-TMDS, 3-LVDS, 6-DSI, 8-DPI
-+ status = "okay";
-+
-+ ports {
-+ port@0 {
-+ hdmi_out: endpoint {
-+ remote-endpoint = <&tda998x_0_input>;
-+ };
-+ };
-+
-+ port@1 {
-+ hdmi_input0: endpoint {
-+ remote-endpoint = <&crtc_0_out>;
-+ };
-+ };
-+
-+ };
-+};
-+
-+&gmac {
-+ starfive,gtxclk-dlychain = <4>;
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&gmac_pins>;
-+ phy-mode = "rgmii-txid";
-+ phy-handle = <&phy>;
-+ status = "okay";
-+
-+ mdio: mdio {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ compatible = "snps,dwmac-mdio";
-+ };
- };
-
- &gpio {
-+ gmac_pins: gmac-0 {
-+ gtxclk-pins {
-+ pins = <PAD_FUNC_SHARE(115)>;
-+ bias-pull-up;
-+ drive-strength = <35>;
-+ input-enable;
-+ input-schmitt-enable;
-+ slew-rate = <0>;
-+ };
-+ miitxclk-pins {
-+ pins = <PAD_FUNC_SHARE(116)>;
-+ bias-pull-up;
-+ drive-strength = <14>;
-+ input-enable;
-+ input-schmitt-disable;
-+ slew-rate = <0>;
-+ };
-+ tx-pins {
-+ pins = <PAD_FUNC_SHARE(117)>,
-+ <PAD_FUNC_SHARE(119)>,
-+ <PAD_FUNC_SHARE(120)>,
-+ <PAD_FUNC_SHARE(121)>,
-+ <PAD_FUNC_SHARE(122)>,
-+ <PAD_FUNC_SHARE(123)>,
-+ <PAD_FUNC_SHARE(124)>,
-+ <PAD_FUNC_SHARE(125)>,
-+ <PAD_FUNC_SHARE(126)>;
-+ bias-pull-up;
-+ drive-strength = <35>;
-+ input-disable;
-+ input-schmitt-disable;
-+ slew-rate = <0>;
-+ };
-+ rxclk-pins {
-+ pins = <PAD_FUNC_SHARE(127)>;
-+ bias-pull-up;
-+ drive-strength = <14>;
-+ input-enable;
-+ input-schmitt-disable;
-+ slew-rate = <6>;
-+ };
-+ rxer-pins {
-+ pins = <PAD_FUNC_SHARE(129)>;
-+ bias-pull-up;
-+ drive-strength = <14>;
-+ input-enable;
-+ input-schmitt-disable;
-+ slew-rate = <0>;
-+ };
-+ rx-pins {
-+ pins = <PAD_FUNC_SHARE(128)>,
-+ <PAD_FUNC_SHARE(130)>,
-+ <PAD_FUNC_SHARE(131)>,
-+ <PAD_FUNC_SHARE(132)>,
-+ <PAD_FUNC_SHARE(133)>,
-+ <PAD_FUNC_SHARE(134)>,
-+ <PAD_FUNC_SHARE(135)>,
-+ <PAD_FUNC_SHARE(136)>,
-+ <PAD_FUNC_SHARE(137)>,
-+ <PAD_FUNC_SHARE(138)>,
-+ <PAD_FUNC_SHARE(139)>,
-+ <PAD_FUNC_SHARE(140)>,
-+ <PAD_FUNC_SHARE(141)>;
-+ bias-pull-up;
-+ drive-strength = <14>;
-+ input-enable;
-+ input-schmitt-enable;
-+ slew-rate = <0>;
-+ };
-+ };
-+
- i2c0_pins: i2c0-0 {
- i2c-pins {
- pinmux = <GPIOMUX(62, GPO_LOW,
-@@ -84,6 +252,166 @@
- };
- };
-
-+ pwmdac_pins: pwmdac-0 {
-+ pwmdac-pins {
-+ pinmux = <GPIOMUX(23, GPO_PWMDAC_LEFT_OUT,
-+ GPO_ENABLE, GPI_NONE)>,
-+ <GPIOMUX(24, GPO_PWMDAC_RIGHT_OUT,
-+ GPO_ENABLE, GPI_NONE)>;
-+ bias-disable;
-+ drive-strength = <35>;
-+ input-disable;
-+ input-schmitt-disable;
-+ slew-rate = <0>;
-+ };
-+ };
-+
-+ pwm_pins: pwm-0 {
-+ pwm-pins {
-+ pinmux = <GPIOMUX(7,
-+ GPO_PWM_PAD_OUT_BIT0,
-+ GPO_PWM_PAD_OE_N_BIT0,
-+ GPI_NONE)>,
-+ <GPIOMUX(5,
-+ GPO_PWM_PAD_OUT_BIT1,
-+ GPO_PWM_PAD_OE_N_BIT1,
-+ GPI_NONE)>;
-+ bias-disable;
-+ drive-strength = <35>;
-+ input-disable;
-+ input-schmitt-disable;
-+ slew-rate = <0>;
-+ };
-+ };
-+
-+ sdio0_pins: sdio0-0 {
-+ clk-pins {
-+ pinmux = <GPIOMUX(54, GPO_SDIO0_PAD_CCLK_OUT,
-+ GPO_ENABLE, GPI_NONE)>;
-+ bias-disable;
-+ input-disable;
-+ input-schmitt-disable;
-+ };
-+ sdio-pins {
-+ pinmux = <GPIOMUX(55, GPO_LOW, GPO_DISABLE,
-+ GPI_SDIO0_PAD_CARD_DETECT_N)>,
-+ <GPIOMUX(53,
-+ GPO_SDIO0_PAD_CCMD_OUT,
-+ GPO_SDIO0_PAD_CCMD_OEN,
-+ GPI_SDIO0_PAD_CCMD_IN)>,
-+ <GPIOMUX(49,
-+ GPO_SDIO0_PAD_CDATA_OUT_BIT0,
-+ GPO_SDIO0_PAD_CDATA_OEN_BIT0,
-+ GPI_SDIO0_PAD_CDATA_IN_BIT0)>,
-+ <GPIOMUX(50,
-+ GPO_SDIO0_PAD_CDATA_OUT_BIT1,
-+ GPO_SDIO0_PAD_CDATA_OEN_BIT1,
-+ GPI_SDIO0_PAD_CDATA_IN_BIT1)>,
-+ <GPIOMUX(51,
-+ GPO_SDIO0_PAD_CDATA_OUT_BIT2,
-+ GPO_SDIO0_PAD_CDATA_OEN_BIT2,
-+ GPI_SDIO0_PAD_CDATA_IN_BIT2)>,
-+ <GPIOMUX(52,
-+ GPO_SDIO0_PAD_CDATA_OUT_BIT3,
-+ GPO_SDIO0_PAD_CDATA_OEN_BIT3,
-+ GPI_SDIO0_PAD_CDATA_IN_BIT3)>;
-+ bias-pull-up;
-+ input-enable;
-+ input-schmitt-enable;
-+ };
-+ };
-+
-+ sdio1_pins: sdio1-0 {
-+ clk-pins {
-+ pinmux = <GPIOMUX(33, GPO_SDIO1_PAD_CCLK_OUT,
-+ GPO_ENABLE, GPI_NONE)>;
-+ bias-disable;
-+ input-disable;
-+ input-schmitt-disable;
-+ };
-+ sdio-pins {
-+ pinmux = <GPIOMUX(29,
-+ GPO_SDIO1_PAD_CCMD_OUT,
-+ GPO_SDIO1_PAD_CCMD_OEN,
-+ GPI_SDIO1_PAD_CCMD_IN)>,
-+ <GPIOMUX(36,
-+ GPO_SDIO1_PAD_CDATA_OUT_BIT0,
-+ GPO_SDIO1_PAD_CDATA_OEN_BIT0,
-+ GPI_SDIO1_PAD_CDATA_IN_BIT0)>,
-+ <GPIOMUX(30,
-+ GPO_SDIO1_PAD_CDATA_OUT_BIT1,
-+ GPO_SDIO1_PAD_CDATA_OEN_BIT1,
-+ GPI_SDIO1_PAD_CDATA_IN_BIT1)>,
-+ <GPIOMUX(34,
-+ GPO_SDIO1_PAD_CDATA_OUT_BIT2,
-+ GPO_SDIO1_PAD_CDATA_OEN_BIT2,
-+ GPI_SDIO1_PAD_CDATA_IN_BIT2)>,
-+ <GPIOMUX(31,
-+ GPO_SDIO1_PAD_CDATA_OUT_BIT3,
-+ GPO_SDIO1_PAD_CDATA_OEN_BIT3,
-+ GPI_SDIO1_PAD_CDATA_IN_BIT3)>;
-+ bias-pull-up;
-+ input-enable;
-+ input-schmitt-enable;
-+ };
-+ };
-+
-+ spi2_pins: spi2-0 {
-+ mosi-pins {
-+ pinmux = <GPIOMUX(18, GPO_SPI2_PAD_TXD,
-+ GPO_ENABLE, GPI_NONE)>;
-+ bias-disable;
-+ input-disable;
-+ input-schmitt-disable;
-+ };
-+ miso-pins {
-+ pinmux = <GPIOMUX(16, GPO_LOW, GPO_DISABLE,
-+ GPI_SPI2_PAD_RXD)>;
-+ bias-pull-up;
-+ input-enable;
-+ input-schmitt-enable;
-+ };
-+ sck-pins {
-+ pinmux = <GPIOMUX(12, GPO_SPI2_PAD_SCK_OUT,
-+ GPO_ENABLE, GPI_NONE)>;
-+ bias-disable;
-+ input-disable;
-+ input-schmitt-disable;
-+ };
-+ ss-pins {
-+ pinmux = <GPIOMUX(15, GPO_SPI2_PAD_SS_0_N,
-+ GPO_ENABLE, GPI_NONE)>,
-+ <GPIOMUX(11, GPO_SPI2_PAD_SS_1_N,
-+ GPO_ENABLE, GPI_NONE)>;
-+ bias-disable;
-+ input-disable;
-+ input-schmitt-disable;
-+ };
-+ };
-+
-+ uart0_pins: uart0-0 {
-+ rx-pins {
-+ pinmux = <GPIOMUX(40, GPO_LOW, GPO_DISABLE,
-+ GPI_UART0_PAD_SIN)>,
-+ <GPIOMUX(39, GPO_LOW, GPO_DISABLE,
-+ GPI_UART0_PAD_CTSN)>;
-+ bias-pull-up;
-+ drive-strength = <14>;
-+ input-enable;
-+ input-schmitt-enable;
-+ };
-+ tx-pins {
-+ pinmux = <GPIOMUX(41, GPO_UART0_PAD_SOUT,
-+ GPO_ENABLE, GPI_NONE)>,
-+ <GPIOMUX(42, GPO_UART0_PAD_RTSN,
-+ GPO_ENABLE, GPI_NONE)>;
-+ bias-disable;
-+ drive-strength = <35>;
-+ input-disable;
-+ input-schmitt-disable;
-+ };
-+ };
-+
- uart3_pins: uart3-0 {
- rx-pins {
- pinmux = <GPIOMUX(13, GPO_LOW, GPO_DISABLE,
-@@ -124,6 +452,17 @@
- regulators {
- };
- };
-+
-+ tda998x@70 {
-+ compatible = "nxp,tda998x";
-+ reg = <0x70>;
-+
-+ port {
-+ tda998x_0_input: endpoint {
-+ remote-endpoint = <&hdmi_out>;
-+ };
-+ };
-+ };
- };
-
- &i2c1 {
-@@ -154,8 +493,103 @@
- clock-frequency = <27000000>;
- };
-
-+&ptc {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&pwm_pins>;
-+ status = "okay";
-+};
-+
-+&pwmdac {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&pwmdac_pins>;
-+ status = "okay";
-+};
-+
-+&qspi {
-+ nor_flash: nor-flash@0 {
-+ compatible = "spi-flash";
-+ reg = <0>;
-+ spi-max-frequency = <31250000>;
-+ page-size = <256>;
-+ block-size = <16>;
-+ cdns,read-delay = <4>;
-+ cdns,tshsl-ns = <1>;
-+ cdns,tsd2d-ns = <1>;
-+ cdns,tchsh-ns = <1>;
-+ cdns,tslch-ns = <1>;
-+ spi-tx-bus-width = <1>;
-+ spi-rx-bus-width = <1>;
-+ };
-+
-+ nand_flash: nand-flash@1 {
-+ compatible = "spi-flash-nand";
-+ reg = <1>;
-+ spi-max-frequency = <31250000>;
-+ page-size = <2048>;
-+ block-size = <17>;
-+ cdns,read-delay = <4>;
-+ cdns,tshsl-ns = <1>;
-+ cdns,tsd2d-ns = <1>;
-+ cdns,tchsh-ns = <1>;
-+ cdns,tslch-ns = <1>;
-+ spi-tx-bus-width = <1>;
-+ spi-rx-bus-width = <1>;
-+ };
-+};
-+
-+&sdio0 {
-+ broken-cd;
-+ bus-width = <4>;
-+ cap-sd-highspeed;
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&sdio0_pins>;
-+ status = "okay";
-+};
-+
-+&sdio1 {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ bus-width = <4>;
-+ cap-sd-highspeed;
-+ cap-sdio-irq;
-+ cap-power-off-card;
-+ mmc-pwrseq = <&wifi_pwrseq>;
-+ non-removable;
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&sdio1_pins>;
-+ status = "okay";
-+
-+ wifi@1 {
-+ compatible = "brcm,bcm4329-fmac";
-+ reg = <1>;
-+ };
-+};
-+
-+&spi2 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&spi2_pins>;
-+ status = "okay";
-+
-+ spi_dev0: spi@0 {
-+ compatible = "rohm,dh2228fv";
-+ spi-max-frequency = <10000000>;
-+ reg = <0>;
-+ };
-+};
-+
-+&uart0 {
-+ pinctrl-names = "default";
-+ pinctrl-0 = <&uart0_pins>;
-+ status = "okay";
-+};
-+
- &uart3 {
- pinctrl-names = "default";
- pinctrl-0 = <&uart3_pins>;
- status = "okay";
- };
-+
-+&usb3 {
-+ dr_mode = "host";
-+ status = "okay";
-+};
---- a/arch/riscv/boot/dts/starfive/jh7100-starfive-visionfive-v1.dts
-+++ b/arch/riscv/boot/dts/starfive/jh7100-starfive-visionfive-v1.dts
-@@ -18,3 +18,22 @@
- priority = <224>;
- };
- };
-+
-+&gpio {
-+ /* don't reset gpio mux for serial console and reset gpio */
-+ starfive,keep-gpiomux = <13 14 63>;
-+};
-+
-+&i2c0 {
-+ eeprom@50 {
-+ compatible = "atmel,24c04";
-+ reg = <0x50>;
-+ pagesize = <16>;
-+ };
-+};
-+
-+&mdio {
-+ phy: ethernet-phy@0 {
-+ reg = <0>;
-+ };
-+};
---- a/arch/riscv/boot/dts/starfive/jh7100.dtsi
-+++ b/arch/riscv/boot/dts/starfive/jh7100.dtsi
-@@ -6,7 +6,9 @@
-
- /dts-v1/;
- #include <dt-bindings/clock/starfive-jh7100.h>
-+#include <dt-bindings/clock/starfive-jh7100-audio.h>
- #include <dt-bindings/reset/starfive-jh7100.h>
-+#include <dt-bindings/reset/starfive-jh7100-audio.h>
-
- / {
- compatible = "starfive,jh7100";
-@@ -32,7 +34,9 @@
- i-tlb-sets = <1>;
- i-tlb-size = <32>;
- mmu-type = "riscv,sv39";
-+ next-level-cache = <&ccache>;
- riscv,isa = "rv64imafdc";
-+ starfive,itim = <&itim0>;
- tlb-split;
-
- cpu0_intc: interrupt-controller {
-@@ -57,7 +61,9 @@
- i-tlb-sets = <1>;
- i-tlb-size = <32>;
- mmu-type = "riscv,sv39";
-+ next-level-cache = <&ccache>;
- riscv,isa = "rv64imafdc";
-+ starfive,itim = <&itim1>;
- tlb-split;
-
- cpu1_intc: interrupt-controller {
-@@ -108,6 +114,13 @@
- clock-frequency = <0>;
- };
-
-+ /* gmac device configuration */
-+ stmmac_axi_setup: stmmac-axi-config {
-+ snps,wr_osr_lmt = <0xf>;
-+ snps,rd_osr_lmt = <0xf>;
-+ snps,blen = <256 128 64 32 0 0 0>;
-+ };
-+
- soc {
- compatible = "simple-bus";
- interrupt-parent = <&plic>;
-@@ -116,6 +129,24 @@
- #size-cells = <2>;
- ranges;
-
-+ dtim: dtim@1000000 {
-+ compatible = "starfive,dtim0";
-+ reg = <0x0 0x1000000 0x0 0x2000>;
-+ reg-names = "mem";
-+ };
-+
-+ itim0: itim@1808000 {
-+ compatible = "starfive,itim0";
-+ reg = <0x0 0x1808000 0x0 0x8000>;
-+ reg-names = "mem";
-+ };
-+
-+ itim1: itim@1820000 {
-+ compatible = "starfive,itim0";
-+ reg = <0x0 0x1820000 0x0 0x8000>;
-+ reg-names = "mem";
-+ };
-+
- clint: clint@2000000 {
- compatible = "starfive,jh7100-clint", "sifive,clint0";
- reg = <0x0 0x2000000 0x0 0x10000>;
-@@ -123,6 +154,21 @@
- <&cpu1_intc 3>, <&cpu1_intc 7>;
- };
-
-+ ccache: cache-controller@2010000 {
-+ compatible = "starfive,jh7100-ccache", "cache";
-+ reg = <0x0 0x2010000 0x0 0x1000>,
-+ <0x0 0x8000000 0x0 0x2000000>;
-+ reg-names = "control", "sideband";
-+ interrupts = <128>, <130>, <131>, <129>;
-+ cache-block-size = <64>;
-+ cache-level = <2>;
-+ cache-sets = <2048>;
-+ cache-size = <2097152>;
-+ cache-unified;
-+ /*next-level-cache = <&L40 &L36>;*/
-+ uncached-offset = <0xf 0x80000000>;
-+ };
-+
- plic: interrupt-controller@c000000 {
- compatible = "starfive,jh7100-plic", "sifive,plic-1.0.0";
- reg = <0x0 0xc000000 0x0 0x4000000>;
-@@ -134,6 +180,177 @@
- riscv,ndev = <133>;
- };
-
-+ sdio0: mmc@10000000 {
-+ compatible = "snps,dw-mshc";
-+ reg = <0x0 0x10000000 0x0 0x10000>;
-+ clocks = <&clkgen JH7100_CLK_SDIO0_AHB>,
-+ <&clkgen JH7100_CLK_SDIO0_CCLKINT_INV>;
-+ clock-names = "biu", "ciu";
-+ interrupts = <4>;
-+ data-addr = <0>;
-+ fifo-depth = <32>;
-+ fifo-watermark-aligned;
-+ status = "disabled";
-+ };
-+
-+ sdio1: mmc@10010000 {
-+ compatible = "snps,dw-mshc";
-+ reg = <0x0 0x10010000 0x0 0x10000>;
-+ clocks = <&clkgen JH7100_CLK_SDIO1_AHB>,
-+ <&clkgen JH7100_CLK_SDIO1_CCLKINT_INV>;
-+ clock-names = "biu", "ciu";
-+ interrupts = <5>;
-+ data-addr = <0>;
-+ fifo-depth = <32>;
-+ fifo-watermark-aligned;
-+ status = "disabled";
-+ };
-+
-+ gmac: ethernet@10020000 {
-+ compatible = "starfive,jh7100-dwmac", "snps,dwmac";
-+ reg = <0x0 0x10020000 0x0 0x10000>;
-+ clocks = <&clkgen JH7100_CLK_GMAC_ROOT_DIV>,
-+ <&clkgen JH7100_CLK_GMAC_AHB>,
-+ <&clkgen JH7100_CLK_GMAC_PTP_REF>,
-+ <&clkgen JH7100_CLK_GMAC_TX_INV>,
-+ <&clkgen JH7100_CLK_GMAC_GTX>;
-+ clock-names = "stmmaceth", "pclk", "ptp_ref", "tx", "gtx";
-+ resets = <&rstgen JH7100_RSTN_GMAC_AHB>;
-+ reset-names = "ahb";
-+ interrupts = <6>, <7>;
-+ interrupt-names = "macirq", "eth_wake_irq";
-+ max-frame-size = <9000>;
-+ snps,multicast-filter-bins = <0>;
-+ snps,perfect-filter-entries = <128>;
-+ starfive,syscon = <&sysmain 0x70 0>;
-+ rx-fifo-depth = <32768>;
-+ tx-fifo-depth = <16384>;
-+ snps,axi-config = <&stmmac_axi_setup>;
-+ snps,fixed-burst;
-+ /*snps,force_sf_dma_mode;*/
-+ snps,force_thresh_dma_mode;
-+ snps,no-pbl-x8;
-+ status = "disabled";
-+ };
-+
-+ dma2p: dma-controller@100b0000 {
-+ compatible = "starfive,jh7100-axi-dma";
-+ reg = <0x0 0x100b0000 0x0 0x10000>;
-+ clocks = <&clkgen JH7100_CLK_SGDMA2P_AXI>,
-+ <&clkgen JH7100_CLK_SGDMA2P_AHB>;
-+ clock-names = "core-clk", "cfgr-clk";
-+ resets = <&rstgen JH7100_RSTN_SGDMA2P_AXI>,
-+ <&rstgen JH7100_RSTN_SGDMA2P_AHB>;
-+ reset-names = "axi", "ahb";
-+ interrupts = <2>;
-+ #dma-cells = <1>;
-+ dma-channels = <4>;
-+ snps,dma-masters = <1>;
-+ snps,data-width = <4>;
-+ snps,block-size = <4096 4096 4096 4096>;
-+ snps,priority = <0 1 2 3>;
-+ snps,axi-max-burst-len = <128>;
-+ dma-coherent;
-+ };
-+
-+ crypto: crypto@100d0000 {
-+ compatible = "starfive,vic-sec";
-+ reg = <0x0 0x100d0000 0x0 0x20000>,
-+ <0x0 0x11800234 0x0 0xc>;
-+ reg-names = "secmem", "secclk";
-+ clocks = <&clkgen JH7100_CLK_SEC_AHB>;
-+ interrupts = <31>;
-+ };
-+
-+ i2sadc0: i2sadc0@10400000 {
-+ compatible = "snps,designware-i2sadc0";
-+ reg = <0x0 0x10400000 0x0 0x1000>;
-+ clocks = <&clkgen JH7100_CLK_APB1_BUS>;
-+ clock-names = "i2sclk";
-+ interrupt-parent = <&plic>;
-+ #sound-dai-cells = <0>;
-+ dmas = <&dma2p 28>;
-+ dma-names = "rx";
-+ };
-+
-+ i2svad: i2svad@10420000 {
-+ compatible = "starfive,sf-i2svad";
-+ reg = <0x0 0x10420000 0x0 0x1000> ;
-+ clocks = <&audclk JH7100_AUDCLK_I2SVAD_APB>;
-+ clock-names = "i2svad_apb";
-+ resets = <&audrst JH7100_AUDRSTN_I2SVAD_APB>,
-+ <&audrst JH7100_AUDRSTN_I2SVAD_SRST>;
-+ reset-names = "apb_i2svad", "i2svad_srst";
-+ interrupts = <60>, <61>;
-+ interrupt-names = "spintr", "slintr";
-+ #sound-dai-cells = <0>;
-+ };
-+
-+ pwmdac: pwmdac@10440000 {
-+ compatible = "starfive,pwmdac";
-+ reg = <0x0 0x10440000 0x0 0x1000>;
-+ clocks = <&clkgen JH7100_CLK_AUDIO_ROOT>,
-+ <&clkgen JH7100_CLK_AUDIO_SRC>,
-+ <&clkgen JH7100_CLK_AUDIO_12288>,
-+ <&audclk JH7100_AUDCLK_DMA1P_AHB>,
-+ <&audclk JH7100_AUDCLK_PWMDAC_APB>,
-+ <&audclk JH7100_AUDCLK_DAC_MCLK>;
-+ clock-names = "audio_root",
-+ "audio_src",
-+ "audio_12288",
-+ "dma1p_ahb",
-+ "pwmdac_apb",
-+ "dac_mclk";
-+ resets = <&audrst JH7100_AUDRSTN_APB_BUS>,
-+ <&audrst JH7100_AUDRSTN_DMA1P_AHB>,
-+ <&audrst JH7100_AUDRSTN_PWMDAC_APB>;
-+ reset-names = "apb_bus", "dma1p_ahb", "apb_pwmdac";
-+ dmas = <&dma2p 23>;
-+ dma-names = "tx";
-+ #sound-dai-cells = <0>;
-+ };
-+
-+ i2sdac0: i2sdac0@10450000 {
-+ compatible = "snps,designware-i2sdac0";
-+ reg = <0x0 0x10450000 0x0 0x1000>;
-+ clocks = <&audclk JH7100_AUDCLK_DAC_MCLK>,
-+ <&audclk JH7100_AUDCLK_I2SDAC_BCLK>,
-+ <&audclk JH7100_AUDCLK_I2SDAC_LRCLK>,
-+ <&audclk JH7100_AUDCLK_I2SDAC_APB>;
-+ clock-names = "dac_mclk", "i2sdac0_bclk", "i2sdac0_lrclk", "i2sdac_apb";
-+ resets = <&audrst JH7100_AUDRSTN_I2SDAC_APB>,
-+ <&audrst JH7100_AUDRSTN_I2SDAC_SRST>;
-+ reset-names = "apb_i2sdac", "i2sdac_srst";
-+ #sound-dai-cells = <0>;
-+ dmas = <&dma2p 30>;
-+ dma-names = "tx";
-+ };
-+
-+ i2sdac1: i2sdac1@10460000 {
-+ compatible = "snps,designware-i2sdac1";
-+ reg = <0x0 0x10460000 0x0 0x1000>;
-+ clocks = <&audclk JH7100_AUDCLK_DAC_MCLK>,
-+ <&audclk JH7100_AUDCLK_I2S1_BCLK>,
-+ <&audclk JH7100_AUDCLK_I2S1_LRCLK>,
-+ <&audclk JH7100_AUDCLK_I2S1_APB>;
-+ clock-names = "dac_mclk", "i2sdac1_bclk", "i2sdac1_lrclk", "i2s1_apb";
-+ resets = <&audrst JH7100_AUDRSTN_I2S1_APB>,
-+ <&audrst JH7100_AUDRSTN_I2S1_SRST>;
-+ #sound-dai-cells = <0>;
-+ dmas = <&dma2p 31>;
-+ dma-names = "tx";
-+ };
-+
-+ i2sdac16k: i2sdac16k@10470000 {
-+ compatible = "snps,designware-i2sdac16k";
-+ reg = <0x0 0x10470000 0x0 0x1000>;
-+ clocks = <&clkgen JH7100_CLK_APB1_BUS>;
-+ clock-names = "i2sclk";
-+ #sound-dai-cells = <0>;
-+ dmas = <&dma2p 29>;
-+ dma-names = "tx";
-+ };
-+
- audclk: clock-controller@10480000 {
- compatible = "starfive,jh7100-audclk";
- reg = <0x0 0x10480000 0x0 0x10000>;
-@@ -150,6 +367,82 @@
- #reset-cells = <1>;
- };
-
-+ spdif_transmitter: spdif-transmitter {
-+ compatible = "linux,spdif-dit";
-+ #sound-dai-cells = <0>;
-+ };
-+
-+ spdif_receiver: spdif-receiver {
-+ compatible = "linux,spdif-dir";
-+ #sound-dai-cells = <0>;
-+ };
-+
-+ pwmdac_codec: pwmdac-transmitter {
-+ compatible = "linux,pwmdac-dit";
-+ #sound-dai-cells = <0>;
-+ };
-+
-+ dmic_codec: dmic {
-+ compatible = "dmic-codec";
-+ #sound-dai-cells = <0>;
-+ };
-+
-+ sound: snd-card {
-+ compatible = "simple-audio-card";
-+ simple-audio-card,name = "Starfive-Multi-Sound-Card";
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+
-+ /* pwmdac */
-+ simple-audio-card,dai-link@0 {
-+ reg = <0>;
-+ status = "okay";
-+ format = "left_j";
-+ bitclock-master = <&sndcpu0>;
-+ frame-master = <&sndcpu0>;
-+
-+ sndcpu0: cpu {
-+ sound-dai = <&pwmdac>;
-+ };
-+
-+ codec {
-+ sound-dai = <&pwmdac_codec>;
-+ };
-+ };
-+ };
-+
-+ usb3: usb@104c0000 {
-+ compatible = "cdns,usb3";
-+ reg = <0x0 0x104c0000 0x0 0x10000>, // memory area for HOST registers
-+ <0x0 0x104d0000 0x0 0x10000>, // memory area for DEVICE registers
-+ <0x0 0x104e0000 0x0 0x10000>; // memory area for OTG/DRD registers
-+ reg-names = "otg", "xhci", "dev";
-+ interrupts = <44>, <52>, <43>;
-+ interrupt-names = "host", "peripheral", "otg";
-+ phy-names = "cdns3,usb3-phy", "cdns3,usb2-phy";
-+ maximum-speed = "super-speed";
-+ status = "disabled";
-+ };
-+
-+ dma1p: dma-controller@10500000 {
-+ compatible = "starfive,jh7100-axi-dma";
-+ reg = <0x0 0x10500000 0x0 0x10000>;
-+ clocks = <&clkgen JH7100_CLK_SGDMA1P_AXI>,
-+ <&clkgen JH7100_CLK_SGDMA1P_BUS>;
-+ clock-names = "core-clk", "cfgr-clk";
-+ resets = <&rstgen JH7100_RSTN_DMA1P_AXI>,
-+ <&rstgen JH7100_RSTN_SGDMA1P_AXI>;
-+ reset-names = "axi", "ahb";
-+ interrupts = <1>;
-+ #dma-cells = <1>;
-+ dma-channels = <16>;
-+ snps,dma-masters = <1>;
-+ snps,data-width = <3>;
-+ snps,block-size = <4096 4096 4096 4096 4096 4096 4096 4096 4096 4096 4096 4096 4096 4096 4096 4096>;
-+ snps,priority = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15>;
-+ snps,axi-max-burst-len = <64>;
-+ };
-+
- clkgen: clock-controller@11800000 {
- compatible = "starfive,jh7100-clkgen";
- reg = <0x0 0x11800000 0x0 0x10000>;
-@@ -158,12 +451,93 @@
- #clock-cells = <1>;
- };
-
-+ otp: otp@11810000 {
-+ compatible = "starfive,fu740-otp";
-+ reg = <0x0 0x11810000 0x0 0x10000>;
-+ clocks = <&clkgen JH7100_CLK_OTP_APB>;
-+ fuse-count = <0x200>;
-+ };
-+
- rstgen: reset-controller@11840000 {
- compatible = "starfive,jh7100-reset";
- reg = <0x0 0x11840000 0x0 0x10000>;
- #reset-cells = <1>;
- };
-
-+ sysmain: syscon@11850000 {
-+ compatible = "starfive,jh7100-sysmain", "syscon";
-+ reg = <0x0 0x11850000 0x0 0x10000>;
-+ };
-+
-+ qspi: spi@11860000 {
-+ compatible = "cdns,qspi-nor";
-+ reg = <0x0 0x11860000 0x0 0x10000>,
-+ <0x0 0x20000000 0x0 0x20000000>;
-+ clocks = <&clkgen JH7100_CLK_QSPI_AHB>;
-+ interrupts = <3>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ cdns,fifo-depth = <256>;
-+ cdns,fifo-width = <4>;
-+ cdns,trigger-address = <0x0>;
-+ spi-max-frequency = <250000000>;
-+ status = "disabled";
-+ };
-+
-+ uart0: serial@11870000 {
-+ compatible = "starfive,jh7100-hsuart", "snps,dw-apb-uart";
-+ reg = <0x0 0x11870000 0x0 0x10000>;
-+ clocks = <&clkgen JH7100_CLK_UART0_CORE>,
-+ <&clkgen JH7100_CLK_UART0_APB>;
-+ clock-names = "baudclk", "apb_pclk";
-+ resets = <&rstgen JH7100_RSTN_UART0_APB>;
-+ interrupts = <92>;
-+ reg-io-width = <4>;
-+ reg-shift = <2>;
-+ status = "disabled";
-+ };
-+
-+ uart1: serial@11880000 {
-+ compatible = "starfive,jh7100-hsuart", "snps,dw-apb-uart";
-+ reg = <0x0 0x11880000 0x0 0x10000>;
-+ clocks = <&clkgen JH7100_CLK_UART1_CORE>,
-+ <&clkgen JH7100_CLK_UART1_APB>;
-+ clock-names = "baudclk", "apb_pclk";
-+ resets = <&rstgen JH7100_RSTN_UART1_APB>;
-+ interrupts = <93>;
-+ reg-io-width = <4>;
-+ reg-shift = <2>;
-+ status = "disabled";
-+ };
-+
-+ spi0: spi@11890000 {
-+ compatible = "snps,dw-apb-ssi";
-+ reg = <0x0 0x11890000 0x0 0x10000>;
-+ clocks = <&clkgen JH7100_CLK_SPI0_CORE>,
-+ <&clkgen JH7100_CLK_SPI0_APB>;
-+ clock-names = "ssi_clk", "pclk";
-+ resets = <&rstgen JH7100_RSTN_SPI0_APB>;
-+ reset-names = "spi";
-+ interrupts = <94>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ status = "disabled";
-+ };
-+
-+ spi1: spi@118a0000 {
-+ compatible = "snps,dw-apb-ssi";
-+ reg = <0x0 0x118a0000 0x0 0x10000>;
-+ clocks = <&clkgen JH7100_CLK_SPI1_CORE>,
-+ <&clkgen JH7100_CLK_SPI1_APB>;
-+ clock-names = "ssi_clk", "pclk";
-+ resets = <&rstgen JH7100_RSTN_SPI1_APB>;
-+ reset-names = "spi";
-+ interrupts = <95>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ status = "disabled";
-+ };
-+
- i2c0: i2c@118b0000 {
- compatible = "snps,designware-i2c";
- reg = <0x0 0x118b0000 0x0 0x10000>;
-@@ -190,6 +564,41 @@
- status = "disabled";
- };
-
-+ trng: trng@118d0000 {
-+ compatible = "starfive,vic-rng";
-+ reg = <0x0 0x118d0000 0x0 0x10000>;
-+ clocks = <&clkgen JH7100_CLK_TRNG_APB>;
-+ interrupts = <98>;
-+ };
-+
-+ vpu_enc: vpu_enc@118e0000 {
-+ compatible = "cm,cm521-vpu";
-+ reg = <0x0 0x118e0000 0x0 0x4000>;
-+ reg-names = "control";
-+ clocks = <&clkgen JH7100_CLK_VP6_CORE>;
-+ clock-names = "vcodec";
-+ interrupts = <26>;
-+ };
-+
-+ vpu_dec: vpu_dec@118f0000 {
-+ compatible = "c&m,cm511-vpu";
-+ reg = <0 0x118f0000 0 0x10000>;
-+ clocks = <&clkgen JH7100_CLK_VP6_CORE>;
-+ clock-names = "vcodec";
-+ interrupts = <23>;
-+ //memory-region = <&vpu_reserved>;
-+ };
-+
-+ jpu: coadj12@11900000 {
-+ compatible = "cm,codaj12-jpu-1";
-+ reg = <0x0 0x11900000 0x0 0x300>;
-+ reg-names = "control";
-+ clocks = <&clkgen JH7100_CLK_JPEG_APB>;
-+ clock-names = "jpege";
-+ interrupts = <24>;
-+ memory-region = <&jpu_reserved>;
-+ };
-+
- gpio: pinctrl@11910000 {
- compatible = "starfive,jh7100-pinctrl";
- reg = <0x0 0x11910000 0x0 0x10000>,
-@@ -204,6 +613,86 @@
- #interrupt-cells = <2>;
- };
-
-+ nvdla@11940000 {
-+ compatible = "nvidia,nvdla_os_initial";
-+ interrupts = <22>;
-+ memory-region = <&nvdla_reserved>;
-+ reg = <0x0 0x11940000 0x0 0x40000>;
-+ status = "okay";
-+ };
-+
-+ display: display-subsystem {
-+ compatible = "starfive,display-subsystem";
-+ dma-coherent;
-+ status = "disabled";
-+ };
-+
-+ encoder: display-encoder {
-+ compatible = "starfive,display-encoder";
-+ status = "disabled";
-+ };
-+
-+ crtc: crtc@12000000 {
-+ compatible = "starfive,jh7100-crtc";
-+ reg = <0x0 0x12000000 0x0 0x10000>,
-+ <0x0 0x12040000 0x0 0x10000>,
-+ <0x0 0x12080000 0x0 0x10000>,
-+ <0x0 0x120c0000 0x0 0x10000>,
-+ <0x0 0x12240000 0x0 0x10000>,
-+ <0x0 0x12250000 0x0 0x10000>,
-+ <0x0 0x12260000 0x0 0x10000>;
-+ reg-names = "lcdc", "vpp0", "vpp1", "vpp2", "clk", "rst", "sys";
-+ clocks = <&clkgen JH7100_CLK_DISP_AXI>, <&clkgen JH7100_CLK_VOUT_SRC>;
-+ clock-names = "disp_axi", "vout_src";
-+ resets = <&rstgen JH7100_RSTN_DISP_AXI>, <&rstgen JH7100_RSTN_VOUT_SRC>;
-+ reset-names = "disp_axi", "vout_src";
-+ interrupts = <101>, <103>;
-+ interrupt-names = "lcdc_irq", "vpp1_irq";
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ status = "disabled";
-+
-+ pp1 {
-+ pp-id = <1>;
-+ fifo-out;
-+ //sys-bus-out;
-+ src-format = <11>; //<COLOR_RGB565>;
-+ src-width = <1920>;
-+ src-height = <1080>;
-+ dst-format = <7>; //<COLOR_RGB888_ARGB>;
-+ dst-width = <1920>;
-+ dst-height = <1080>;
-+ };
-+ };
-+
-+ spi2: spi@12410000 {
-+ compatible = "snps,dw-apb-ssi";
-+ reg = <0x0 0x12410000 0x0 0x10000>;
-+ clocks = <&clkgen JH7100_CLK_SPI2_CORE>,
-+ <&clkgen JH7100_CLK_SPI2_APB>;
-+ clock-names = "ssi_clk", "pclk";
-+ resets = <&rstgen JH7100_RSTN_SPI2_APB>;
-+ reset-names = "spi";
-+ interrupts = <70>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ status = "disabled";
-+ };
-+
-+ spi3: spi@12420000 {
-+ compatible = "snps,dw-apb-ssi";
-+ reg = <0x0 0x12420000 0x0 0x10000>;
-+ clocks = <&clkgen JH7100_CLK_SPI3_CORE>,
-+ <&clkgen JH7100_CLK_SPI3_APB>;
-+ clock-names = "ssi_clk", "pclk";
-+ resets = <&rstgen JH7100_RSTN_SPI3_APB>;
-+ reset-names = "spi";
-+ interrupts = <71>;
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ status = "disabled";
-+ };
-+
- uart2: serial@12430000 {
- compatible = "starfive,jh7100-uart", "snps,dw-apb-uart";
- reg = <0x0 0x12430000 0x0 0x10000>;
-@@ -265,5 +754,77 @@
- resets = <&rstgen JH7100_RSTN_WDTIMER_APB>,
- <&rstgen JH7100_RSTN_WDT>;
- };
-+
-+ ptc: pwm@12490000 {
-+ compatible = "starfive,pwm0";
-+ reg = <0x0 0x12490000 0x0 0x10000>;
-+ clocks = <&clkgen JH7100_CLK_PWM_APB>;
-+ resets = <&rstgen JH7100_RSTN_PWM_APB>;
-+ #pwm-cells = <3>;
-+ sifive,npwm = <8>;
-+ status = "disabled";
-+ };
-+
-+ sfctemp: tmon@124a0000 {
-+ compatible = "starfive,jh7100-temp";
-+ reg = <0x0 0x124a0000 0x0 0x10000>;
-+ clocks = <&clkgen JH7100_CLK_TEMP_SENSE>,
-+ <&clkgen JH7100_CLK_TEMP_APB>;
-+ clock-names = "sense", "bus";
-+ resets = <&rstgen JH7100_RSTN_TEMP_SENSE>,
-+ <&rstgen JH7100_RSTN_TEMP_APB>;
-+ reset-names = "sense", "bus";
-+ interrupts = <122>;
-+ #thermal-sensor-cells = <0>;
-+ };
-+
-+ thermal-zones {
-+ cpu-thermal {
-+ polling-delay-passive = <250>;
-+ polling-delay = <15000>;
-+
-+ thermal-sensors = <&sfctemp>;
-+
-+ cooling-maps {
-+ };
-+
-+ trips {
-+ cpu_alert0: cpu_alert0 {
-+ /* milliCelsius */
-+ temperature = <75000>;
-+ hysteresis = <2000>;
-+ type = "passive";
-+ };
-+
-+ cpu_crit: cpu_crit {
-+ /* milliCelsius */
-+ temperature = <90000>;
-+ hysteresis = <2000>;
-+ type = "critical";
-+ };
-+ };
-+ };
-+ };
-+
-+ xrp@f0000000 {
-+ compatible = "cdns,xrp";
-+ reg = <0x0 0xf0000000 0x0 0x01ffffff>,
-+ <0x10 0x72000000 0x0 0x00001000>,
-+ <0x10 0x72001000 0x0 0x00fff000>,
-+ <0x0 0x124b0000 0x0 0x00010000>;
-+ clocks = <&clkgen JH7100_CLK_VP6_CORE>;
-+ interrupts = <27>, <28>;
-+ firmware-name = "vp6_elf";
-+ dsp-irq = <19 20>;
-+ dsp-irq-src = <0x20 0x21>;
-+ intc-irq-mode = <1>;
-+ intc-irq = <0 1>;
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+ ranges = <0x40000000 0x0 0x40000000 0x01000000>,
-+ <0xb0000000 0x10 0x70000000 0x3000000>;
-+ dsp@0 {
-+ };
-+ };
- };
- };
diff --git a/target/linux/starfive/patches-6.1/1025-riscv-dts-visionfive1-enable-QSPI.patch b/target/linux/starfive/patches-6.1/1025-riscv-dts-visionfive1-enable-QSPI.patch
deleted file mode 100644
index 7d190a5fc0..0000000000
--- a/target/linux/starfive/patches-6.1/1025-riscv-dts-visionfive1-enable-QSPI.patch
+++ /dev/null
@@ -1,20 +0,0 @@
-From 21e0e009b1bffea86890fcbf6e1be4c4121258ef Mon Sep 17 00:00:00 2001
-From: Zoltan HERPAI <wigyori@uid0.hu>
-Date: Fri, 11 Aug 2023 11:28:27 +0200
-Subject: [PATCH 1025/1025] riscv: dts: visionfive1: enable QSPI
-
-Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
----
- .../riscv/boot/dts/starfive/jh7100-starfive-visionfive-v1.dts | 4 ++++
- 1 file changed, 4 insertions(+)
-
---- a/arch/riscv/boot/dts/starfive/jh7100-starfive-visionfive-v1.dts
-+++ b/arch/riscv/boot/dts/starfive/jh7100-starfive-visionfive-v1.dts
-@@ -37,3 +37,7 @@
- reg = <0>;
- };
- };
-+
-+&qspi {
-+ status = "okay";
-+};
diff --git a/target/linux/starfive/patches-6.6/0001-clk-starfive-jh7110-sys-Fix-lower-rate-of-CPUfreq-by.patch b/target/linux/starfive/patches-6.6/0001-clk-starfive-jh7110-sys-Fix-lower-rate-of-CPUfreq-by.patch
new file mode 100644
index 0000000000..d21f5efebb
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0001-clk-starfive-jh7110-sys-Fix-lower-rate-of-CPUfreq-by.patch
@@ -0,0 +1,76 @@
+From 69275b667bd930cf5d5f577ba0ab1987c9d13987 Mon Sep 17 00:00:00 2001
+From: Xingyu Wu <xingyu.wu@starfivetech.com>
+Date: Mon, 21 Aug 2023 23:29:15 +0800
+Subject: [PATCH 001/116] clk: starfive: jh7110-sys: Fix lower rate of CPUfreq
+ by setting PLL0 rate to 1.5GHz
+
+CPUfreq supports 4 cpu frequency loads on 375/500/750/1500MHz.
+But now PLL0 rate is 1GHz and the cpu frequency loads become
+333/500/500/1000MHz in fact.
+
+So PLL0 rate should be set to 1.5GHz. Change the parent of cpu_root clock
+and the divider of cpu_core before the setting.
+
+Reviewed-by: Hal Feng <hal.feng@starfivetech.com>
+Fixes: e2c510d6d630 ("riscv: dts: starfive: Add cpu scaling for JH7110 SoC")
+Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
+---
+ .../clk/starfive/clk-starfive-jh7110-sys.c | 47 ++++++++++++++++++-
+ 1 file changed, 46 insertions(+), 1 deletion(-)
+
+--- a/drivers/clk/starfive/clk-starfive-jh7110-sys.c
++++ b/drivers/clk/starfive/clk-starfive-jh7110-sys.c
+@@ -501,7 +501,52 @@ static int __init jh7110_syscrg_probe(st
+ if (ret)
+ return ret;
+
+- return jh7110_reset_controller_register(priv, "rst-sys", 0);
++ ret = jh7110_reset_controller_register(priv, "rst-sys", 0);
++ if (ret)
++ return ret;
++
++ /*
++ * Set PLL0 rate to 1.5GHz
++ * In order to not affect the cpu when the PLL0 rate is changing,
++ * we need to switch the parent of cpu_root clock to osc clock first,
++ * and then switch back after setting the PLL0 rate.
++ */
++ pllclk = clk_get(priv->dev, "pll0_out");
++ if (!IS_ERR(pllclk)) {
++ struct clk *osc = clk_get(&pdev->dev, "osc");
++ struct clk *cpu_root = priv->reg[JH7110_SYSCLK_CPU_ROOT].hw.clk;
++ struct clk *cpu_core = priv->reg[JH7110_SYSCLK_CPU_CORE].hw.clk;
++
++ if (IS_ERR(osc)) {
++ clk_put(pllclk);
++ return PTR_ERR(osc);
++ }
++
++ /*
++ * CPU need voltage regulation by CPUfreq if set 1.5GHz.
++ * So in this driver, cpu_core need to be set the divider to be 2 first
++ * and will be 750M after setting parent.
++ */
++ ret = clk_set_rate(cpu_core, clk_get_rate(cpu_core) / 2);
++ if (ret)
++ goto failed_set;
++
++ ret = clk_set_parent(cpu_root, osc);
++ if (ret)
++ goto failed_set;
++
++ ret = clk_set_rate(pllclk, 1500000000);
++ if (ret)
++ goto failed_set;
++
++ ret = clk_set_parent(cpu_root, pllclk);
++
++failed_set:
++ clk_put(pllclk);
++ clk_put(osc);
++ }
++
++ return ret;
+ }
+
+ static const struct of_device_id jh7110_syscrg_match[] = {
diff --git a/target/linux/starfive/patches-6.6/0002-dt-bindings-timer-Add-timer-for-StarFive-JH7110-SoC.patch b/target/linux/starfive/patches-6.6/0002-dt-bindings-timer-Add-timer-for-StarFive-JH7110-SoC.patch
new file mode 100644
index 0000000000..2b5318bb44
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0002-dt-bindings-timer-Add-timer-for-StarFive-JH7110-SoC.patch
@@ -0,0 +1,114 @@
+From 7d0dbcbc079e4f72b69f53442b7759da6ebc4f87 Mon Sep 17 00:00:00 2001
+From: Xingyu Wu <xingyu.wu@starfivetech.com>
+Date: Thu, 19 Oct 2023 13:34:59 +0800
+Subject: [PATCH 002/116] dt-bindings: timer: Add timer for StarFive JH7110 SoC
+
+Add bindings for the timer on the JH7110 RISC-V SoC
+by StarFive Technology Ltd.
+
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
+---
+ .../bindings/timer/starfive,jh7110-timer.yaml | 96 +++++++++++++++++++
+ 1 file changed, 96 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/timer/starfive,jh7110-timer.yaml
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/timer/starfive,jh7110-timer.yaml
+@@ -0,0 +1,96 @@
++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/timer/starfive,jh7110-timer.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: StarFive JH7110 Timer
++
++maintainers:
++ - Xingyu Wu <xingyu.wu@starfivetech.com>
++ - Samin Guo <samin.guo@starfivetech.com>
++
++description:
++ This timer has four free-running 32 bit counters in StarFive JH7110 SoC.
++ And each channel(counter) triggers an interrupt when timeout. They support
++ one-shot mode and continuous-run mode.
++
++properties:
++ compatible:
++ const: starfive,jh7110-timer
++
++ reg:
++ maxItems: 1
++
++ interrupts:
++ items:
++ - description: channel 0
++ - description: channel 1
++ - description: channel 2
++ - description: channel 3
++
++ clocks:
++ items:
++ - description: timer APB
++ - description: channel 0
++ - description: channel 1
++ - description: channel 2
++ - description: channel 3
++
++ clock-names:
++ items:
++ - const: apb
++ - const: ch0
++ - const: ch1
++ - const: ch2
++ - const: ch3
++
++ resets:
++ items:
++ - description: timer APB
++ - description: channel 0
++ - description: channel 1
++ - description: channel 2
++ - description: channel 3
++
++ reset-names:
++ items:
++ - const: apb
++ - const: ch0
++ - const: ch1
++ - const: ch2
++ - const: ch3
++
++required:
++ - compatible
++ - reg
++ - interrupts
++ - clocks
++ - clock-names
++ - resets
++ - reset-names
++
++additionalProperties: false
++
++examples:
++ - |
++ timer@13050000 {
++ compatible = "starfive,jh7110-timer";
++ reg = <0x13050000 0x10000>;
++ interrupts = <69>, <70>, <71> ,<72>;
++ clocks = <&clk 124>,
++ <&clk 125>,
++ <&clk 126>,
++ <&clk 127>,
++ <&clk 128>;
++ clock-names = "apb", "ch0", "ch1",
++ "ch2", "ch3";
++ resets = <&rst 117>,
++ <&rst 118>,
++ <&rst 119>,
++ <&rst 120>,
++ <&rst 121>;
++ reset-names = "apb", "ch0", "ch1",
++ "ch2", "ch3";
++ };
++
diff --git a/target/linux/starfive/patches-6.6/0003-clocksource-Add-JH7110-timer-driver.patch b/target/linux/starfive/patches-6.6/0003-clocksource-Add-JH7110-timer-driver.patch
new file mode 100644
index 0000000000..68b9c38d5b
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0003-clocksource-Add-JH7110-timer-driver.patch
@@ -0,0 +1,428 @@
+From 7cb47848f8a10aed6e050c0ea483b4bb5eaa62a4 Mon Sep 17 00:00:00 2001
+From: Xingyu Wu <xingyu.wu@starfivetech.com>
+Date: Thu, 19 Oct 2023 13:35:00 +0800
+Subject: [PATCH 003/116] clocksource: Add JH7110 timer driver
+
+Add timer driver for the StarFive JH7110 SoC.
+
+Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
+---
+ drivers/clocksource/Kconfig | 11 +
+ drivers/clocksource/Makefile | 1 +
+ drivers/clocksource/timer-jh7110.c | 380 +++++++++++++++++++++++++++++
+ 3 files changed, 392 insertions(+)
+ create mode 100644 drivers/clocksource/timer-jh7110.c
+
+--- a/drivers/clocksource/Kconfig
++++ b/drivers/clocksource/Kconfig
+@@ -641,6 +641,17 @@ config RISCV_TIMER
+ is accessed via both the SBI and the rdcycle instruction. This is
+ required for all RISC-V systems.
+
++config STARFIVE_JH7110_TIMER
++ bool "Timer for the STARFIVE JH7110 SoC"
++ depends on ARCH_STARFIVE || COMPILE_TEST
++ select TIMER_OF
++ select CLKSRC_MMIO
++ default ARCH_STARFIVE
++ help
++ This enables the timer for StarFive JH7110 SoC. On RISC-V platform,
++ the system has started RISCV_TIMER, but you can also use this timer
++ which can provide four channels to do a lot more things on JH7110 SoC.
++
+ config CLINT_TIMER
+ bool "CLINT Timer for the RISC-V platform" if COMPILE_TEST
+ depends on GENERIC_SCHED_CLOCK && RISCV
+--- a/drivers/clocksource/Makefile
++++ b/drivers/clocksource/Makefile
+@@ -80,6 +80,7 @@ obj-$(CONFIG_INGENIC_TIMER) += ingenic-
+ obj-$(CONFIG_CLKSRC_ST_LPC) += clksrc_st_lpc.o
+ obj-$(CONFIG_X86_NUMACHIP) += numachip.o
+ obj-$(CONFIG_RISCV_TIMER) += timer-riscv.o
++obj-$(CONFIG_STARFIVE_JH7110_TIMER) += timer-jh7110.o
+ obj-$(CONFIG_CLINT_TIMER) += timer-clint.o
+ obj-$(CONFIG_CSKY_MP_TIMER) += timer-mp-csky.o
+ obj-$(CONFIG_GX6605S_TIMER) += timer-gx6605s.o
+--- /dev/null
++++ b/drivers/clocksource/timer-jh7110.c
+@@ -0,0 +1,380 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Starfive JH7110 Timer driver
++ *
++ * Copyright (C) 2022-2023 StarFive Technology Co., Ltd.
++ *
++ * Author:
++ * Xingyu Wu <xingyu.wu@starfivetech.com>
++ * Samin Guo <samin.guo@starfivetech.com>
++ */
++
++#include <linux/clk.h>
++#include <linux/clockchips.h>
++#include <linux/clocksource.h>
++#include <linux/err.h>
++#include <linux/interrupt.h>
++#include <linux/io.h>
++#include <linux/iopoll.h>
++#include <linux/irq.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/of_device.h>
++#include <linux/platform_device.h>
++#include <linux/reset.h>
++#include <linux/sched_clock.h>
++
++/* Bias: Ch0-0x0, Ch1-0x40, Ch2-0x80, and so on. */
++#define JH7110_TIMER_CH_LEN 0x40
++#define JH7110_TIMER_CH_BASE(x) ((x) * JH7110_TIMER_CH_LEN)
++#define JH7110_TIMER_CH_MAX 4
++
++#define JH7110_CLOCK_SOURCE_RATING 200
++#define JH7110_VALID_BITS 32
++#define JH7110_DELAY_US 0
++#define JH7110_TIMEOUT_US 10000
++#define JH7110_CLOCKEVENT_RATING 300
++#define JH7110_TIMER_MAX_TICKS 0xffffffff
++#define JH7110_TIMER_MIN_TICKS 0xf
++#define JH7110_TIMER_RELOAD_VALUE 0
++
++#define JH7110_TIMER_INT_STATUS 0x00 /* RO[0:4]: Interrupt Status for channel0~4 */
++#define JH7110_TIMER_CTL 0x04 /* RW[0]: 0-continuous run, 1-single run */
++#define JH7110_TIMER_LOAD 0x08 /* RW: load value to counter */
++#define JH7110_TIMER_ENABLE 0x10 /* RW[0]: timer enable register */
++#define JH7110_TIMER_RELOAD 0x14 /* RW: write 1 or 0 both reload counter */
++#define JH7110_TIMER_VALUE 0x18 /* RO: timer value register */
++#define JH7110_TIMER_INT_CLR 0x20 /* RW: timer interrupt clear register */
++#define JH7110_TIMER_INT_MASK 0x24 /* RW[0]: timer interrupt mask register */
++
++#define JH7110_TIMER_INT_CLR_ENA BIT(0)
++#define JH7110_TIMER_INT_CLR_AVA_MASK BIT(1)
++
++struct jh7110_clkevt {
++ struct clock_event_device evt;
++ struct clocksource cs;
++ bool cs_is_valid;
++ struct clk *clk;
++ struct reset_control *rst;
++ u32 rate;
++ u32 reload_val;
++ void __iomem *base;
++ char name[sizeof("jh7110-timer.chX")];
++};
++
++struct jh7110_timer_priv {
++ struct clk *pclk;
++ struct reset_control *prst;
++ struct jh7110_clkevt clkevt[JH7110_TIMER_CH_MAX];
++};
++
++/* 0:continuous-run mode, 1:single-run mode */
++enum jh7110_timer_mode {
++ JH7110_TIMER_MODE_CONTIN,
++ JH7110_TIMER_MODE_SINGLE,
++};
++
++/* Interrupt Mask, 0:Unmask, 1:Mask */
++enum jh7110_timer_int_mask {
++ JH7110_TIMER_INT_ENA,
++ JH7110_TIMER_INT_DIS,
++};
++
++enum jh7110_timer_enable {
++ JH7110_TIMER_DIS,
++ JH7110_TIMER_ENA,
++};
++
++static inline struct jh7110_clkevt *to_jh7110_clkevt(struct clock_event_device *evt)
++{
++ return container_of(evt, struct jh7110_clkevt, evt);
++}
++
++/*
++ * BIT(0): Read value represent channel int status.
++ * Write 1 to this bit to clear interrupt. Write 0 has no effects.
++ * BIT(1): "1" means that it is clearing interrupt. BIT(0) can not be written.
++ */
++static inline int jh7110_timer_int_clear(struct jh7110_clkevt *clkevt)
++{
++ u32 value;
++ int ret;
++
++ /* Waiting interrupt can be cleared */
++ ret = readl_poll_timeout_atomic(clkevt->base + JH7110_TIMER_INT_CLR, value,
++ !(value & JH7110_TIMER_INT_CLR_AVA_MASK),
++ JH7110_DELAY_US, JH7110_TIMEOUT_US);
++ if (!ret)
++ writel(JH7110_TIMER_INT_CLR_ENA, clkevt->base + JH7110_TIMER_INT_CLR);
++
++ return ret;
++}
++
++static int jh7110_timer_start(struct jh7110_clkevt *clkevt)
++{
++ int ret;
++
++ /* Disable and clear interrupt first */
++ writel(JH7110_TIMER_INT_DIS, clkevt->base + JH7110_TIMER_INT_MASK);
++ ret = jh7110_timer_int_clear(clkevt);
++ if (ret)
++ return ret;
++
++ writel(JH7110_TIMER_INT_ENA, clkevt->base + JH7110_TIMER_INT_MASK);
++ writel(JH7110_TIMER_ENA, clkevt->base + JH7110_TIMER_ENABLE);
++
++ return 0;
++}
++
++static int jh7110_timer_shutdown(struct clock_event_device *evt)
++{
++ struct jh7110_clkevt *clkevt = to_jh7110_clkevt(evt);
++
++ writel(JH7110_TIMER_DIS, clkevt->base + JH7110_TIMER_ENABLE);
++ return jh7110_timer_int_clear(clkevt);
++}
++
++static void jh7110_timer_suspend(struct clock_event_device *evt)
++{
++ struct jh7110_clkevt *clkevt = to_jh7110_clkevt(evt);
++
++ clkevt->reload_val = readl(clkevt->base + JH7110_TIMER_LOAD);
++ jh7110_timer_shutdown(evt);
++}
++
++static void jh7110_timer_resume(struct clock_event_device *evt)
++{
++ struct jh7110_clkevt *clkevt = to_jh7110_clkevt(evt);
++
++ writel(clkevt->reload_val, clkevt->base + JH7110_TIMER_LOAD);
++ writel(JH7110_TIMER_RELOAD_VALUE, clkevt->base + JH7110_TIMER_RELOAD);
++ jh7110_timer_start(clkevt);
++}
++
++static int jh7110_timer_tick_resume(struct clock_event_device *evt)
++{
++ jh7110_timer_resume(evt);
++
++ return 0;
++}
++
++/* IRQ handler for the timer */
++static irqreturn_t jh7110_timer_interrupt(int irq, void *priv)
++{
++ struct clock_event_device *evt = (struct clock_event_device *)priv;
++ struct jh7110_clkevt *clkevt = to_jh7110_clkevt(evt);
++
++ if (jh7110_timer_int_clear(clkevt))
++ return IRQ_NONE;
++
++ if (evt->event_handler)
++ evt->event_handler(evt);
++
++ return IRQ_HANDLED;
++}
++
++static int jh7110_timer_set_periodic(struct clock_event_device *evt)
++{
++ struct jh7110_clkevt *clkevt = to_jh7110_clkevt(evt);
++ u32 periodic = DIV_ROUND_CLOSEST(clkevt->rate, HZ);
++
++ writel(JH7110_TIMER_MODE_CONTIN, clkevt->base + JH7110_TIMER_CTL);
++ writel(periodic, clkevt->base + JH7110_TIMER_LOAD);
++
++ return jh7110_timer_start(clkevt);
++}
++
++static int jh7110_timer_set_oneshot(struct clock_event_device *evt)
++{
++ struct jh7110_clkevt *clkevt = to_jh7110_clkevt(evt);
++
++ writel(JH7110_TIMER_MODE_SINGLE, clkevt->base + JH7110_TIMER_CTL);
++ writel(JH7110_TIMER_MAX_TICKS, clkevt->base + JH7110_TIMER_LOAD);
++
++ return jh7110_timer_start(clkevt);
++}
++
++static int jh7110_timer_set_next_event(unsigned long next,
++ struct clock_event_device *evt)
++{
++ struct jh7110_clkevt *clkevt = to_jh7110_clkevt(evt);
++
++ writel(JH7110_TIMER_MODE_SINGLE, clkevt->base + JH7110_TIMER_CTL);
++ writel(next, clkevt->base + JH7110_TIMER_LOAD);
++
++ return jh7110_timer_start(clkevt);
++}
++
++static void jh7110_set_clockevent(struct clock_event_device *evt)
++{
++ evt->features = CLOCK_EVT_FEAT_PERIODIC |
++ CLOCK_EVT_FEAT_ONESHOT |
++ CLOCK_EVT_FEAT_DYNIRQ;
++ evt->set_state_shutdown = jh7110_timer_shutdown;
++ evt->set_state_periodic = jh7110_timer_set_periodic;
++ evt->set_state_oneshot = jh7110_timer_set_oneshot;
++ evt->set_state_oneshot_stopped = jh7110_timer_shutdown;
++ evt->tick_resume = jh7110_timer_tick_resume;
++ evt->set_next_event = jh7110_timer_set_next_event;
++ evt->suspend = jh7110_timer_suspend;
++ evt->resume = jh7110_timer_resume;
++ evt->rating = JH7110_CLOCKEVENT_RATING;
++}
++
++static u64 jh7110_timer_clocksource_read(struct clocksource *cs)
++{
++ struct jh7110_clkevt *clkevt = container_of(cs, struct jh7110_clkevt, cs);
++
++ return (u64)readl(clkevt->base + JH7110_TIMER_VALUE);
++}
++
++static int jh7110_clocksource_init(struct jh7110_clkevt *clkevt)
++{
++ int ret;
++
++ clkevt->cs.name = clkevt->name;
++ clkevt->cs.rating = JH7110_CLOCK_SOURCE_RATING;
++ clkevt->cs.read = jh7110_timer_clocksource_read;
++ clkevt->cs.mask = CLOCKSOURCE_MASK(JH7110_VALID_BITS);
++ clkevt->cs.flags = CLOCK_SOURCE_IS_CONTINUOUS;
++
++ ret = clocksource_register_hz(&clkevt->cs, clkevt->rate);
++ if (ret)
++ return ret;
++
++ clkevt->cs_is_valid = true; /* clocksource register done */
++ writel(JH7110_TIMER_MODE_CONTIN, clkevt->base + JH7110_TIMER_CTL);
++ writel(JH7110_TIMER_MAX_TICKS, clkevt->base + JH7110_TIMER_LOAD);
++
++ return jh7110_timer_start(clkevt);
++}
++
++static void jh7110_clockevents_register(struct jh7110_clkevt *clkevt)
++{
++ clkevt->rate = clk_get_rate(clkevt->clk);
++
++ jh7110_set_clockevent(&clkevt->evt);
++ clkevt->evt.name = clkevt->name;
++ clkevt->evt.cpumask = cpu_possible_mask;
++
++ clockevents_config_and_register(&clkevt->evt, clkevt->rate,
++ JH7110_TIMER_MIN_TICKS, JH7110_TIMER_MAX_TICKS);
++}
++
++static void jh7110_timer_release(void *data)
++{
++ struct jh7110_timer_priv *priv = data;
++ int i;
++
++ for (i = 0; i < JH7110_TIMER_CH_MAX; i++) {
++ /* Disable each channel of timer */
++ if (priv->clkevt[i].base)
++ writel(JH7110_TIMER_DIS, priv->clkevt[i].base + JH7110_TIMER_ENABLE);
++
++ /* Avoid no initialization in the loop of the probe */
++ if (!IS_ERR_OR_NULL(priv->clkevt[i].rst))
++ reset_control_assert(priv->clkevt[i].rst);
++
++ if (priv->clkevt[i].cs_is_valid)
++ clocksource_unregister(&priv->clkevt[i].cs);
++ }
++
++ reset_control_assert(priv->prst);
++}
++
++static int jh7110_timer_probe(struct platform_device *pdev)
++{
++ struct jh7110_timer_priv *priv;
++ struct jh7110_clkevt *clkevt;
++ char name[sizeof("chX")];
++ int ch;
++ int ret;
++ void __iomem *base;
++
++ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++
++ base = devm_platform_ioremap_resource(pdev, 0);
++ if (IS_ERR(base))
++ return dev_err_probe(&pdev->dev, PTR_ERR(base),
++ "failed to map registers\n");
++
++ priv->prst = devm_reset_control_get_exclusive(&pdev->dev, "apb");
++ if (IS_ERR(priv->prst))
++ return dev_err_probe(&pdev->dev, PTR_ERR(priv->prst),
++ "failed to get apb reset\n");
++
++ priv->pclk = devm_clk_get_enabled(&pdev->dev, "apb");
++ if (IS_ERR(priv->pclk))
++ return dev_err_probe(&pdev->dev, PTR_ERR(priv->pclk),
++ "failed to get & enable apb clock\n");
++
++ ret = reset_control_deassert(priv->prst);
++ if (ret)
++ return dev_err_probe(&pdev->dev, ret, "failed to deassert apb reset\n");
++
++ ret = devm_add_action_or_reset(&pdev->dev, jh7110_timer_release, priv);
++ if (ret)
++ return ret;
++
++ for (ch = 0; ch < JH7110_TIMER_CH_MAX; ch++) {
++ clkevt = &priv->clkevt[ch];
++ snprintf(name, sizeof(name), "ch%d", ch);
++
++ clkevt->base = base + JH7110_TIMER_CH_BASE(ch);
++ /* Ensure timer is disabled */
++ writel(JH7110_TIMER_DIS, clkevt->base + JH7110_TIMER_ENABLE);
++
++ clkevt->rst = devm_reset_control_get_exclusive(&pdev->dev, name);
++ if (IS_ERR(clkevt->rst))
++ return PTR_ERR(clkevt->rst);
++
++ clkevt->clk = devm_clk_get_enabled(&pdev->dev, name);
++ if (IS_ERR(clkevt->clk))
++ return PTR_ERR(clkevt->clk);
++
++ ret = reset_control_deassert(clkevt->rst);
++ if (ret)
++ return ret;
++
++ clkevt->evt.irq = platform_get_irq(pdev, ch);
++ if (clkevt->evt.irq < 0)
++ return clkevt->evt.irq;
++
++ snprintf(clkevt->name, sizeof(clkevt->name), "jh7110-timer.ch%d", ch);
++ jh7110_clockevents_register(clkevt);
++
++ ret = devm_request_irq(&pdev->dev, clkevt->evt.irq, jh7110_timer_interrupt,
++ IRQF_TIMER | IRQF_IRQPOLL,
++ clkevt->name, &clkevt->evt);
++ if (ret)
++ return ret;
++
++ ret = jh7110_clocksource_init(clkevt);
++ if (ret)
++ return ret;
++ }
++
++ return 0;
++}
++
++static const struct of_device_id jh7110_timer_match[] = {
++ { .compatible = "starfive,jh7110-timer", },
++ { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, jh7110_timer_match);
++
++static struct platform_driver jh7110_timer_driver = {
++ .probe = jh7110_timer_probe,
++ .driver = {
++ .name = "jh7110-timer",
++ .of_match_table = jh7110_timer_match,
++ },
++};
++module_platform_driver(jh7110_timer_driver);
++
++MODULE_AUTHOR("Xingyu Wu <xingyu.wu@starfivetech.com>");
++MODULE_DESCRIPTION("StarFive JH7110 timer driver");
++MODULE_LICENSE("GPL");
diff --git a/target/linux/starfive/patches-6.6/0004-dt-bindings-mmc-starfive-Remove-properties-from-requ.patch b/target/linux/starfive/patches-6.6/0004-dt-bindings-mmc-starfive-Remove-properties-from-requ.patch
new file mode 100644
index 0000000000..9c1e78b29b
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0004-dt-bindings-mmc-starfive-Remove-properties-from-requ.patch
@@ -0,0 +1,34 @@
+From b513eb2cabee212ba1a23839f18c0026a21e653e Mon Sep 17 00:00:00 2001
+From: William Qiu <william.qiu@starfivetech.com>
+Date: Fri, 22 Sep 2023 14:28:32 +0800
+Subject: [PATCH 004/116] dt-bindings: mmc: starfive: Remove properties from
+ required
+
+Due to the change of tuning implementation, it's no longer necessary to
+use the "starfive,sysreg" property in dts, so remove it from required.
+
+Signed-off-by: William Qiu <william.qiu@starfivetech.com>
+Acked-by: Conor Dooley <conor.dooley@microchip.com>
+Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
+Link: https://lore.kernel.org/r/20230922062834.39212-2-william.qiu@starfivetech.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+---
+ Documentation/devicetree/bindings/mmc/starfive,jh7110-mmc.yaml | 2 --
+ 1 file changed, 2 deletions(-)
+
+--- a/Documentation/devicetree/bindings/mmc/starfive,jh7110-mmc.yaml
++++ b/Documentation/devicetree/bindings/mmc/starfive,jh7110-mmc.yaml
+@@ -55,7 +55,6 @@ required:
+ - clocks
+ - clock-names
+ - interrupts
+- - starfive,sysreg
+
+ unevaluatedProperties: false
+
+@@ -73,5 +72,4 @@ examples:
+ fifo-depth = <32>;
+ fifo-watermark-aligned;
+ data-addr = <0>;
+- starfive,sysreg = <&sys_syscon 0x14 0x1a 0x7c000000>;
+ };
diff --git a/target/linux/starfive/patches-6.6/0005-mmc-starfive-Change-tuning-implementation.patch b/target/linux/starfive/patches-6.6/0005-mmc-starfive-Change-tuning-implementation.patch
new file mode 100644
index 0000000000..b8ea96f3c8
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0005-mmc-starfive-Change-tuning-implementation.patch
@@ -0,0 +1,199 @@
+From 3ae8cec8fd28e18847edb67dfea04718c2f3369f Mon Sep 17 00:00:00 2001
+From: William Qiu <william.qiu@starfivetech.com>
+Date: Fri, 22 Sep 2023 14:28:33 +0800
+Subject: [PATCH 005/116] mmc: starfive: Change tuning implementation
+
+Before, we used syscon to achieve tuning, but the actual measurement
+showed little effect, so the tuning implementation was modified here,
+and it was realized by reading and writing the UHS_REG_EXT register.
+
+Signed-off-by: William Qiu <william.qiu@starfivetech.com>
+Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
+Link: https://lore.kernel.org/r/20230922062834.39212-3-william.qiu@starfivetech.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+---
+ drivers/mmc/host/dw_mmc-starfive.c | 137 +++++++++--------------------
+ 1 file changed, 40 insertions(+), 97 deletions(-)
+
+--- a/drivers/mmc/host/dw_mmc-starfive.c
++++ b/drivers/mmc/host/dw_mmc-starfive.c
+@@ -5,6 +5,7 @@
+ * Copyright (c) 2022 StarFive Technology Co., Ltd.
+ */
+
++#include <linux/bitfield.h>
+ #include <linux/clk.h>
+ #include <linux/delay.h>
+ #include <linux/mfd/syscon.h>
+@@ -20,13 +21,7 @@
+ #define ALL_INT_CLR 0x1ffff
+ #define MAX_DELAY_CHAIN 32
+
+-struct starfive_priv {
+- struct device *dev;
+- struct regmap *reg_syscon;
+- u32 syscon_offset;
+- u32 syscon_shift;
+- u32 syscon_mask;
+-};
++#define STARFIVE_SMPL_PHASE GENMASK(20, 16)
+
+ static void dw_mci_starfive_set_ios(struct dw_mci *host, struct mmc_ios *ios)
+ {
+@@ -44,117 +39,65 @@ static void dw_mci_starfive_set_ios(stru
+ }
+ }
+
++static void dw_mci_starfive_set_sample_phase(struct dw_mci *host, u32 smpl_phase)
++{
++ /* change driver phase and sample phase */
++ u32 reg_value = mci_readl(host, UHS_REG_EXT);
++
++ /* In UHS_REG_EXT, only 5 bits valid in DRV_PHASE and SMPL_PHASE */
++ reg_value &= ~STARFIVE_SMPL_PHASE;
++ reg_value |= FIELD_PREP(STARFIVE_SMPL_PHASE, smpl_phase);
++ mci_writel(host, UHS_REG_EXT, reg_value);
++
++ /* We should delay 1ms wait for timing setting finished. */
++ mdelay(1);
++}
++
+ static int dw_mci_starfive_execute_tuning(struct dw_mci_slot *slot,
+ u32 opcode)
+ {
+ static const int grade = MAX_DELAY_CHAIN;
+ struct dw_mci *host = slot->host;
+- struct starfive_priv *priv = host->priv;
+- int rise_point = -1, fall_point = -1;
+- int err, prev_err = 0;
+- int i;
+- bool found = 0;
+- u32 regval;
+-
+- /*
+- * Use grade as the max delay chain, and use the rise_point and
+- * fall_point to ensure the best sampling point of a data input
+- * signals.
+- */
+- for (i = 0; i < grade; i++) {
+- regval = i << priv->syscon_shift;
+- err = regmap_update_bits(priv->reg_syscon, priv->syscon_offset,
+- priv->syscon_mask, regval);
+- if (err)
+- return err;
+- mci_writel(host, RINTSTS, ALL_INT_CLR);
+-
+- err = mmc_send_tuning(slot->mmc, opcode, NULL);
+- if (!err)
+- found = 1;
+-
+- if (i > 0) {
+- if (err && !prev_err)
+- fall_point = i - 1;
+- if (!err && prev_err)
+- rise_point = i;
+- }
++ int smpl_phase, smpl_raise = -1, smpl_fall = -1;
++ int ret;
+
+- if (rise_point != -1 && fall_point != -1)
+- goto tuning_out;
++ for (smpl_phase = 0; smpl_phase < grade; smpl_phase++) {
++ dw_mci_starfive_set_sample_phase(host, smpl_phase);
++ mci_writel(host, RINTSTS, ALL_INT_CLR);
+
+- prev_err = err;
+- err = 0;
+- }
++ ret = mmc_send_tuning(slot->mmc, opcode, NULL);
+
+-tuning_out:
+- if (found) {
+- if (rise_point == -1)
+- rise_point = 0;
+- if (fall_point == -1)
+- fall_point = grade - 1;
+- if (fall_point < rise_point) {
+- if ((rise_point + fall_point) >
+- (grade - 1))
+- i = fall_point / 2;
+- else
+- i = (rise_point + grade - 1) / 2;
+- } else {
+- i = (rise_point + fall_point) / 2;
++ if (!ret && smpl_raise < 0) {
++ smpl_raise = smpl_phase;
++ } else if (ret && smpl_raise >= 0) {
++ smpl_fall = smpl_phase - 1;
++ break;
+ }
+-
+- regval = i << priv->syscon_shift;
+- err = regmap_update_bits(priv->reg_syscon, priv->syscon_offset,
+- priv->syscon_mask, regval);
+- if (err)
+- return err;
+- mci_writel(host, RINTSTS, ALL_INT_CLR);
+-
+- dev_info(host->dev, "Found valid delay chain! use it [delay=%d]\n", i);
+- } else {
+- dev_err(host->dev, "No valid delay chain! use default\n");
+- err = -EINVAL;
+ }
+
+- mci_writel(host, RINTSTS, ALL_INT_CLR);
+- return err;
+-}
+-
+-static int dw_mci_starfive_parse_dt(struct dw_mci *host)
+-{
+- struct of_phandle_args args;
+- struct starfive_priv *priv;
+- int ret;
++ if (smpl_phase >= grade)
++ smpl_fall = grade - 1;
+
+- priv = devm_kzalloc(host->dev, sizeof(*priv), GFP_KERNEL);
+- if (!priv)
+- return -ENOMEM;
+-
+- ret = of_parse_phandle_with_fixed_args(host->dev->of_node,
+- "starfive,sysreg", 3, 0, &args);
+- if (ret) {
+- dev_err(host->dev, "Failed to parse starfive,sysreg\n");
+- return -EINVAL;
++ if (smpl_raise < 0) {
++ smpl_phase = 0;
++ dev_err(host->dev, "No valid delay chain! use default\n");
++ ret = -EINVAL;
++ goto out;
+ }
+
+- priv->reg_syscon = syscon_node_to_regmap(args.np);
+- of_node_put(args.np);
+- if (IS_ERR(priv->reg_syscon))
+- return PTR_ERR(priv->reg_syscon);
+-
+- priv->syscon_offset = args.args[0];
+- priv->syscon_shift = args.args[1];
+- priv->syscon_mask = args.args[2];
+-
+- host->priv = priv;
++ smpl_phase = (smpl_raise + smpl_fall) / 2;
++ dev_dbg(host->dev, "Found valid delay chain! use it [delay=%d]\n", smpl_phase);
++ ret = 0;
+
+- return 0;
++out:
++ dw_mci_starfive_set_sample_phase(host, smpl_phase);
++ mci_writel(host, RINTSTS, ALL_INT_CLR);
++ return ret;
+ }
+
+ static const struct dw_mci_drv_data starfive_data = {
+ .common_caps = MMC_CAP_CMD23,
+ .set_ios = dw_mci_starfive_set_ios,
+- .parse_dt = dw_mci_starfive_parse_dt,
+ .execute_tuning = dw_mci_starfive_execute_tuning,
+ };
+
diff --git a/target/linux/starfive/patches-6.6/0006-dt-bindings-pwm-Add-bindings-for-OpenCores-PWM-Contr.patch b/target/linux/starfive/patches-6.6/0006-dt-bindings-pwm-Add-bindings-for-OpenCores-PWM-Contr.patch
new file mode 100644
index 0000000000..aafbee5d42
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0006-dt-bindings-pwm-Add-bindings-for-OpenCores-PWM-Contr.patch
@@ -0,0 +1,79 @@
+From e366df2ff64e9f93a5b35eea6a198b005d5a0911 Mon Sep 17 00:00:00 2001
+From: William Qiu <william.qiu@starfivetech.com>
+Date: Fri, 22 Dec 2023 17:45:45 +0800
+Subject: [PATCH 006/116] dt-bindings: pwm: Add bindings for OpenCores PWM
+ Controller
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add bindings for OpenCores PWM Controller.
+
+Signed-off-by: William Qiu <william.qiu@starfivetech.com>
+Reviewed-by: Hal Feng <hal.feng@starfivetech.com>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+Reviewed-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Acked-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+---
+ .../bindings/pwm/opencores,pwm.yaml | 55 +++++++++++++++++++
+ 1 file changed, 55 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/pwm/opencores,pwm.yaml
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/pwm/opencores,pwm.yaml
+@@ -0,0 +1,55 @@
++# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/pwm/opencores,pwm.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: OpenCores PWM controller
++
++maintainers:
++ - William Qiu <william.qiu@starfivetech.com>
++
++description:
++ The OpenCores PTC ip core contains a PWM controller. When operating in PWM
++ mode, the PTC core generates binary signal with user-programmable low and
++ high periods. All PTC counters and registers are 32-bit.
++
++allOf:
++ - $ref: pwm.yaml#
++
++properties:
++ compatible:
++ items:
++ - enum:
++ - starfive,jh7100-pwm
++ - starfive,jh7110-pwm
++ - const: opencores,pwm-v1
++
++ reg:
++ maxItems: 1
++
++ clocks:
++ maxItems: 1
++
++ resets:
++ maxItems: 1
++
++ "#pwm-cells":
++ const: 3
++
++required:
++ - compatible
++ - reg
++ - clocks
++
++additionalProperties: false
++
++examples:
++ - |
++ pwm@12490000 {
++ compatible = "starfive,jh7110-pwm", "opencores,pwm-v1";
++ reg = <0x12490000 0x10000>;
++ clocks = <&clkgen 181>;
++ resets = <&rstgen 109>;
++ #pwm-cells = <3>;
++ };
diff --git a/target/linux/starfive/patches-6.6/0007-pwm-opencores-Add-PWM-driver-support.patch b/target/linux/starfive/patches-6.6/0007-pwm-opencores-Add-PWM-driver-support.patch
new file mode 100644
index 0000000000..27e510d86a
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0007-pwm-opencores-Add-PWM-driver-support.patch
@@ -0,0 +1,285 @@
+From 644bfe581dde9b762460a4916da4d71c148be06e Mon Sep 17 00:00:00 2001
+From: William Qiu <william.qiu@starfivetech.com>
+Date: Fri, 22 Dec 2023 17:45:46 +0800
+Subject: [PATCH 007/116] pwm: opencores: Add PWM driver support
+
+Add driver for OpenCores PWM Controller. And add compatibility code
+which based on StarFive SoC.
+
+Co-developed-by: Hal Feng <hal.feng@starfivetech.com>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+Signed-off-by: William Qiu <william.qiu@starfivetech.com>
+---
+ drivers/pwm/Kconfig | 12 ++
+ drivers/pwm/Makefile | 1 +
+ drivers/pwm/pwm-ocores.c | 233 +++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 246 insertions(+)
+ create mode 100644 drivers/pwm/pwm-ocores.c
+
+--- a/drivers/pwm/Kconfig
++++ b/drivers/pwm/Kconfig
+@@ -434,6 +434,18 @@ config PWM_NTXEC
+ controller found in certain e-book readers designed by the original
+ design manufacturer Netronix.
+
++config PWM_OCORES
++ tristate "OpenCores PWM support"
++ depends on HAS_IOMEM && OF
++ depends on COMMON_CLK
++ depends on ARCH_STARFIVE || COMPILE_TEST
++ help
++ If you say yes to this option, support will be included for the
++ OpenCores PWM. For details see https://opencores.org/projects/ptc.
++
++ To compile this driver as a module, choose M here: the module
++ will be called pwm-ocores.
++
+ config PWM_OMAP_DMTIMER
+ tristate "OMAP Dual-Mode Timer PWM support"
+ depends on OF
+--- a/drivers/pwm/Makefile
++++ b/drivers/pwm/Makefile
+@@ -39,6 +39,7 @@ obj-$(CONFIG_PWM_MICROCHIP_CORE) += pwm-
+ obj-$(CONFIG_PWM_MTK_DISP) += pwm-mtk-disp.o
+ obj-$(CONFIG_PWM_MXS) += pwm-mxs.o
+ obj-$(CONFIG_PWM_NTXEC) += pwm-ntxec.o
++obj-$(CONFIG_PWM_OCORES) += pwm-ocores.o
+ obj-$(CONFIG_PWM_OMAP_DMTIMER) += pwm-omap-dmtimer.o
+ obj-$(CONFIG_PWM_PCA9685) += pwm-pca9685.o
+ obj-$(CONFIG_PWM_PXA) += pwm-pxa.o
+--- /dev/null
++++ b/drivers/pwm/pwm-ocores.c
+@@ -0,0 +1,233 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * OpenCores PWM Driver
++ *
++ * https://opencores.org/projects/ptc
++ *
++ * Copyright (C) 2018-2023 StarFive Technology Co., Ltd.
++ *
++ * Limitations:
++ * - The hardware only do inverted polarity.
++ * - The hardware minimum period / duty_cycle is (1 / pwm_apb clock frequency) ns.
++ * - The hardware maximum period / duty_cycle is (U32_MAX / pwm_apb clock frequency) ns.
++ */
++
++#include <linux/clk.h>
++#include <linux/io.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/of_device.h>
++#include <linux/platform_device.h>
++#include <linux/pwm.h>
++#include <linux/reset.h>
++#include <linux/slab.h>
++
++/* OCPWM_CTRL register bits*/
++#define REG_OCPWM_EN BIT(0)
++#define REG_OCPWM_ECLK BIT(1)
++#define REG_OCPWM_NEC BIT(2)
++#define REG_OCPWM_OE BIT(3)
++#define REG_OCPWM_SIGNLE BIT(4)
++#define REG_OCPWM_INTE BIT(5)
++#define REG_OCPWM_INT BIT(6)
++#define REG_OCPWM_CNTRRST BIT(7)
++#define REG_OCPWM_CAPTE BIT(8)
++
++struct ocores_pwm_device {
++ struct pwm_chip chip;
++ struct clk *clk;
++ struct reset_control *rst;
++ const struct ocores_pwm_data *data;
++ void __iomem *regs;
++ u32 clk_rate; /* PWM APB clock frequency */
++};
++
++struct ocores_pwm_data {
++ void __iomem *(*get_ch_base)(void __iomem *base, unsigned int channel);
++};
++
++static inline u32 ocores_readl(struct ocores_pwm_device *ddata,
++ unsigned int channel,
++ unsigned int offset)
++{
++ void __iomem *base = ddata->data->get_ch_base ?
++ ddata->data->get_ch_base(ddata->regs, channel) : ddata->regs;
++
++ return readl(base + offset);
++}
++
++static inline void ocores_writel(struct ocores_pwm_device *ddata,
++ unsigned int channel,
++ unsigned int offset, u32 val)
++{
++ void __iomem *base = ddata->data->get_ch_base ?
++ ddata->data->get_ch_base(ddata->regs, channel) : ddata->regs;
++
++ writel(val, base + offset);
++}
++
++static inline struct ocores_pwm_device *chip_to_ocores(struct pwm_chip *chip)
++{
++ return container_of(chip, struct ocores_pwm_device, chip);
++}
++
++static void __iomem *starfive_jh71x0_get_ch_base(void __iomem *base,
++ unsigned int channel)
++{
++ unsigned int offset = (channel > 3 ? 1 << 15 : 0) + (channel & 3) * 0x10;
++
++ return base + offset;
++}
++
++static int ocores_pwm_get_state(struct pwm_chip *chip,
++ struct pwm_device *pwm,
++ struct pwm_state *state)
++{
++ struct ocores_pwm_device *ddata = chip_to_ocores(chip);
++ u32 period_data, duty_data, ctrl_data;
++
++ period_data = ocores_readl(ddata, pwm->hwpwm, 0x8);
++ duty_data = ocores_readl(ddata, pwm->hwpwm, 0x4);
++ ctrl_data = ocores_readl(ddata, pwm->hwpwm, 0xC);
++
++ state->period = DIV_ROUND_UP_ULL((u64)period_data * NSEC_PER_SEC, ddata->clk_rate);
++ state->duty_cycle = DIV_ROUND_UP_ULL((u64)duty_data * NSEC_PER_SEC, ddata->clk_rate);
++ state->polarity = PWM_POLARITY_INVERSED;
++ state->enabled = (ctrl_data & REG_OCPWM_EN) ? true : false;
++
++ return 0;
++}
++
++static int ocores_pwm_apply(struct pwm_chip *chip,
++ struct pwm_device *pwm,
++ const struct pwm_state *state)
++{
++ struct ocores_pwm_device *ddata = chip_to_ocores(chip);
++ u32 ctrl_data = 0;
++ u64 period_data, duty_data;
++
++ if (state->polarity != PWM_POLARITY_INVERSED)
++ return -EINVAL;
++
++ ctrl_data = ocores_readl(ddata, pwm->hwpwm, 0xC);
++ ocores_writel(ddata, pwm->hwpwm, 0xC, 0);
++
++ period_data = DIV_ROUND_DOWN_ULL(state->period * ddata->clk_rate, NSEC_PER_SEC);
++ if (period_data <= U32_MAX)
++ ocores_writel(ddata, pwm->hwpwm, 0x8, (u32)period_data);
++ else
++ return -EINVAL;
++
++ duty_data = DIV_ROUND_DOWN_ULL(state->duty_cycle * ddata->clk_rate, NSEC_PER_SEC);
++ if (duty_data <= U32_MAX)
++ ocores_writel(ddata, pwm->hwpwm, 0x4, (u32)duty_data);
++ else
++ return -EINVAL;
++
++ ocores_writel(ddata, pwm->hwpwm, 0xC, 0);
++
++ if (state->enabled) {
++ ctrl_data = ocores_readl(ddata, pwm->hwpwm, 0xC);
++ ocores_writel(ddata, pwm->hwpwm, 0xC, ctrl_data | REG_OCPWM_EN | REG_OCPWM_OE);
++ }
++
++ return 0;
++}
++
++static const struct pwm_ops ocores_pwm_ops = {
++ .get_state = ocores_pwm_get_state,
++ .apply = ocores_pwm_apply,
++};
++
++static const struct ocores_pwm_data jh7100_pwm_data = {
++ .get_ch_base = starfive_jh71x0_get_ch_base,
++};
++
++static const struct ocores_pwm_data jh7110_pwm_data = {
++ .get_ch_base = starfive_jh71x0_get_ch_base,
++};
++
++static const struct of_device_id ocores_pwm_of_match[] = {
++ { .compatible = "opencores,pwm-v1" },
++ { .compatible = "starfive,jh7100-pwm", .data = &jh7100_pwm_data},
++ { .compatible = "starfive,jh7110-pwm", .data = &jh7110_pwm_data},
++ { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, ocores_pwm_of_match);
++
++static void ocores_reset_control_assert(void *data)
++{
++ reset_control_assert(data);
++}
++
++static int ocores_pwm_probe(struct platform_device *pdev)
++{
++ const struct of_device_id *id;
++ struct device *dev = &pdev->dev;
++ struct ocores_pwm_device *ddata;
++ struct pwm_chip *chip;
++ int ret;
++
++ id = of_match_device(ocores_pwm_of_match, dev);
++ if (!id)
++ return -EINVAL;
++
++ ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL);
++ if (!ddata)
++ return -ENOMEM;
++
++ ddata->data = id->data;
++ chip = &ddata->chip;
++ chip->dev = dev;
++ chip->ops = &ocores_pwm_ops;
++ chip->npwm = 8;
++ chip->of_pwm_n_cells = 3;
++
++ ddata->regs = devm_platform_ioremap_resource(pdev, 0);
++ if (IS_ERR(ddata->regs))
++ return dev_err_probe(dev, PTR_ERR(ddata->regs),
++ "Unable to map IO resources\n");
++
++ ddata->clk = devm_clk_get_enabled(dev, NULL);
++ if (IS_ERR(ddata->clk))
++ return dev_err_probe(dev, PTR_ERR(ddata->clk),
++ "Unable to get pwm's clock\n");
++
++ ddata->rst = devm_reset_control_get_optional_exclusive(dev, NULL);
++ if (IS_ERR(ddata->rst))
++ return dev_err_probe(dev, PTR_ERR(ddata->rst),
++ "Unable to get pwm's reset\n");
++
++ reset_control_deassert(ddata->rst);
++
++ ret = devm_add_action_or_reset(dev, ocores_reset_control_assert, ddata->rst);
++ if (ret)
++ return ret;
++
++ ddata->clk_rate = clk_get_rate(ddata->clk);
++ if (ddata->clk_rate <= 0)
++ return dev_err_probe(dev, ddata->clk_rate,
++ "Unable to get clock's rate\n");
++
++ ret = devm_pwmchip_add(dev, chip);
++ if (ret < 0)
++ return dev_err_probe(dev, ret, "Could not register PWM chip\n");
++
++ platform_set_drvdata(pdev, ddata);
++
++ return ret;
++}
++
++static struct platform_driver ocores_pwm_driver = {
++ .probe = ocores_pwm_probe,
++ .driver = {
++ .name = "ocores-pwm",
++ .of_match_table = ocores_pwm_of_match,
++ },
++};
++module_platform_driver(ocores_pwm_driver);
++
++MODULE_AUTHOR("Jieqin Chen");
++MODULE_AUTHOR("Hal Feng <hal.feng@starfivetech.com>");
++MODULE_DESCRIPTION("OpenCores PWM PTC driver");
++MODULE_LICENSE("GPL");
diff --git a/target/linux/starfive/patches-6.6/0008-crypto-starfive-remove-unnecessary-alignmask-for-aha.patch b/target/linux/starfive/patches-6.6/0008-crypto-starfive-remove-unnecessary-alignmask-for-aha.patch
new file mode 100644
index 0000000000..a6ede31342
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0008-crypto-starfive-remove-unnecessary-alignmask-for-aha.patch
@@ -0,0 +1,117 @@
+From 7d9521cad6474d45e9056176982e6da54d40bc19 Mon Sep 17 00:00:00 2001
+From: Eric Biggers <ebiggers@google.com>
+Date: Sun, 22 Oct 2023 01:10:42 -0700
+Subject: [PATCH 008/116] crypto: starfive - remove unnecessary alignmask for
+ ahashes
+
+The crypto API's support for alignmasks for ahash algorithms is nearly
+useless, as its only effect is to cause the API to align the key and
+result buffers. The drivers that happen to be specifying an alignmask
+for ahash rarely actually need it. When they do, it's easily fixable,
+especially considering that these buffers cannot be used for DMA.
+
+In preparation for removing alignmask support from ahash, this patch
+makes the starfive driver no longer use it. This driver did actually
+rely on it, but only for storing to the result buffer using int stores
+in starfive_hash_copy_hash(). This patch makes
+starfive_hash_copy_hash() use put_unaligned() instead. (It really
+should use a specific endianness, but that's an existing bug.)
+
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+---
+ drivers/crypto/starfive/jh7110-hash.c | 13 ++-----------
+ 1 file changed, 2 insertions(+), 11 deletions(-)
+
+--- a/drivers/crypto/starfive/jh7110-hash.c
++++ b/drivers/crypto/starfive/jh7110-hash.c
+@@ -209,7 +209,8 @@ static int starfive_hash_copy_hash(struc
+ data = (u32 *)req->result;
+
+ for (count = 0; count < mlen; count++)
+- data[count] = readl(ctx->cryp->base + STARFIVE_HASH_SHARDR);
++ put_unaligned(readl(ctx->cryp->base + STARFIVE_HASH_SHARDR),
++ &data[count]);
+
+ return 0;
+ }
+@@ -628,7 +629,6 @@ static struct ahash_engine_alg algs_sha2
+ CRYPTO_ALG_NEED_FALLBACK,
+ .cra_blocksize = SHA224_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct starfive_cryp_ctx),
+- .cra_alignmask = 3,
+ .cra_module = THIS_MODULE,
+ }
+ },
+@@ -658,7 +658,6 @@ static struct ahash_engine_alg algs_sha2
+ CRYPTO_ALG_NEED_FALLBACK,
+ .cra_blocksize = SHA224_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct starfive_cryp_ctx),
+- .cra_alignmask = 3,
+ .cra_module = THIS_MODULE,
+ }
+ },
+@@ -687,7 +686,6 @@ static struct ahash_engine_alg algs_sha2
+ CRYPTO_ALG_NEED_FALLBACK,
+ .cra_blocksize = SHA256_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct starfive_cryp_ctx),
+- .cra_alignmask = 3,
+ .cra_module = THIS_MODULE,
+ }
+ },
+@@ -717,7 +715,6 @@ static struct ahash_engine_alg algs_sha2
+ CRYPTO_ALG_NEED_FALLBACK,
+ .cra_blocksize = SHA256_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct starfive_cryp_ctx),
+- .cra_alignmask = 3,
+ .cra_module = THIS_MODULE,
+ }
+ },
+@@ -746,7 +743,6 @@ static struct ahash_engine_alg algs_sha2
+ CRYPTO_ALG_NEED_FALLBACK,
+ .cra_blocksize = SHA384_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct starfive_cryp_ctx),
+- .cra_alignmask = 3,
+ .cra_module = THIS_MODULE,
+ }
+ },
+@@ -776,7 +772,6 @@ static struct ahash_engine_alg algs_sha2
+ CRYPTO_ALG_NEED_FALLBACK,
+ .cra_blocksize = SHA384_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct starfive_cryp_ctx),
+- .cra_alignmask = 3,
+ .cra_module = THIS_MODULE,
+ }
+ },
+@@ -805,7 +800,6 @@ static struct ahash_engine_alg algs_sha2
+ CRYPTO_ALG_NEED_FALLBACK,
+ .cra_blocksize = SHA512_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct starfive_cryp_ctx),
+- .cra_alignmask = 3,
+ .cra_module = THIS_MODULE,
+ }
+ },
+@@ -835,7 +829,6 @@ static struct ahash_engine_alg algs_sha2
+ CRYPTO_ALG_NEED_FALLBACK,
+ .cra_blocksize = SHA512_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct starfive_cryp_ctx),
+- .cra_alignmask = 3,
+ .cra_module = THIS_MODULE,
+ }
+ },
+@@ -864,7 +857,6 @@ static struct ahash_engine_alg algs_sha2
+ CRYPTO_ALG_NEED_FALLBACK,
+ .cra_blocksize = SM3_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct starfive_cryp_ctx),
+- .cra_alignmask = 3,
+ .cra_module = THIS_MODULE,
+ }
+ },
+@@ -894,7 +886,6 @@ static struct ahash_engine_alg algs_sha2
+ CRYPTO_ALG_NEED_FALLBACK,
+ .cra_blocksize = SM3_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct starfive_cryp_ctx),
+- .cra_alignmask = 3,
+ .cra_module = THIS_MODULE,
+ }
+ },
diff --git a/target/linux/starfive/patches-6.6/0009-crypto-starfive-Update-driver-dependencies.patch b/target/linux/starfive/patches-6.6/0009-crypto-starfive-Update-driver-dependencies.patch
new file mode 100644
index 0000000000..145c01377d
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0009-crypto-starfive-Update-driver-dependencies.patch
@@ -0,0 +1,25 @@
+From 52de0270ed6453727936b5a793dc367d75280e84 Mon Sep 17 00:00:00 2001
+From: Jia Jie Ho <jiajie.ho@starfivetech.com>
+Date: Wed, 15 Nov 2023 01:12:13 +0800
+Subject: [PATCH 009/116] crypto: starfive - Update driver dependencies
+
+Change AMBA_PL08X to required dependency as the hash ops depends on it
+for data transfer.
+
+Signed-off-by: Jia Jie Ho <jiajie.ho@starfivetech.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+---
+ drivers/crypto/starfive/Kconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/crypto/starfive/Kconfig
++++ b/drivers/crypto/starfive/Kconfig
+@@ -4,7 +4,7 @@
+
+ config CRYPTO_DEV_JH7110
+ tristate "StarFive JH7110 cryptographic engine driver"
+- depends on SOC_STARFIVE || AMBA_PL08X || COMPILE_TEST
++ depends on (SOC_STARFIVE && AMBA_PL08X) || COMPILE_TEST
+ depends on HAS_DMA
+ select CRYPTO_ENGINE
+ select CRYPTO_HMAC
diff --git a/target/linux/starfive/patches-6.6/0010-crypto-starfive-RSA-poll-csr-for-done-status.patch b/target/linux/starfive/patches-6.6/0010-crypto-starfive-RSA-poll-csr-for-done-status.patch
new file mode 100644
index 0000000000..c94009d4ff
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0010-crypto-starfive-RSA-poll-csr-for-done-status.patch
@@ -0,0 +1,200 @@
+From 68a1bbb99455fd5ea80b7e21ec726f369abc9572 Mon Sep 17 00:00:00 2001
+From: Jia Jie Ho <jiajie.ho@starfivetech.com>
+Date: Wed, 15 Nov 2023 01:12:14 +0800
+Subject: [PATCH 010/116] crypto: starfive - RSA poll csr for done status
+
+Hardware could not clear irq status without resetting the entire module.
+Driver receives irq immediately when mask bit is cleared causing
+intermittent errors in RSA calculations. Switch to use csr polling for
+done status instead.
+
+Signed-off-by: Jia Jie Ho <jiajie.ho@starfivetech.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+---
+ drivers/crypto/starfive/jh7110-cryp.c | 8 -----
+ drivers/crypto/starfive/jh7110-cryp.h | 10 +++++-
+ drivers/crypto/starfive/jh7110-rsa.c | 49 +++++++--------------------
+ 3 files changed, 22 insertions(+), 45 deletions(-)
+
+--- a/drivers/crypto/starfive/jh7110-cryp.c
++++ b/drivers/crypto/starfive/jh7110-cryp.c
+@@ -109,12 +109,6 @@ static irqreturn_t starfive_cryp_irq(int
+ tasklet_schedule(&cryp->hash_done);
+ }
+
+- if (status & STARFIVE_IE_FLAG_PKA_DONE) {
+- mask |= STARFIVE_IE_MASK_PKA_DONE;
+- writel(mask, cryp->base + STARFIVE_IE_MASK_OFFSET);
+- complete(&cryp->pka_done);
+- }
+-
+ return IRQ_HANDLED;
+ }
+
+@@ -159,8 +153,6 @@ static int starfive_cryp_probe(struct pl
+ return dev_err_probe(&pdev->dev, PTR_ERR(cryp->rst),
+ "Error getting hardware reset line\n");
+
+- init_completion(&cryp->pka_done);
+-
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0)
+ return irq;
+--- a/drivers/crypto/starfive/jh7110-cryp.h
++++ b/drivers/crypto/starfive/jh7110-cryp.h
+@@ -125,6 +125,15 @@ union starfive_pka_cacr {
+ };
+ };
+
++union starfive_pka_casr {
++ u32 v;
++ struct {
++#define STARFIVE_PKA_DONE BIT(0)
++ u32 done :1;
++ u32 rsvd_0 :31;
++ };
++};
++
+ struct starfive_rsa_key {
+ u8 *n;
+ u8 *e;
+@@ -183,7 +192,6 @@ struct starfive_cryp_dev {
+ struct crypto_engine *engine;
+ struct tasklet_struct aes_done;
+ struct tasklet_struct hash_done;
+- struct completion pka_done;
+ size_t assoclen;
+ size_t total_in;
+ size_t total_out;
+--- a/drivers/crypto/starfive/jh7110-rsa.c
++++ b/drivers/crypto/starfive/jh7110-rsa.c
+@@ -6,13 +6,7 @@
+ */
+
+ #include <linux/crypto.h>
+-#include <linux/delay.h>
+-#include <linux/device.h>
+-#include <linux/dma-direct.h>
+-#include <linux/interrupt.h>
+ #include <linux/iopoll.h>
+-#include <linux/io.h>
+-#include <linux/mod_devicetable.h>
+ #include <crypto/akcipher.h>
+ #include <crypto/algapi.h>
+ #include <crypto/internal/akcipher.h>
+@@ -28,13 +22,13 @@
+ #define STARFIVE_PKA_CAER_OFFSET (STARFIVE_PKA_REGS_OFFSET + 0x108)
+ #define STARFIVE_PKA_CANR_OFFSET (STARFIVE_PKA_REGS_OFFSET + 0x208)
+
+-// R^2 mod N and N0'
++/* R ^ 2 mod N and N0' */
+ #define CRYPTO_CMD_PRE 0x0
+-// A * R mod N ==> A
++/* A * R mod N ==> A */
+ #define CRYPTO_CMD_ARN 0x5
+-// A * E * R mod N ==> A
++/* A * E * R mod N ==> A */
+ #define CRYPTO_CMD_AERN 0x6
+-// A * A * R mod N ==> A
++/* A * A * R mod N ==> A */
+ #define CRYPTO_CMD_AARN 0x7
+
+ #define STARFIVE_RSA_MAX_KEYSZ 256
+@@ -43,21 +37,10 @@
+ static inline int starfive_pka_wait_done(struct starfive_cryp_ctx *ctx)
+ {
+ struct starfive_cryp_dev *cryp = ctx->cryp;
++ u32 status;
+
+- return wait_for_completion_timeout(&cryp->pka_done,
+- usecs_to_jiffies(100000));
+-}
+-
+-static inline void starfive_pka_irq_mask_clear(struct starfive_cryp_ctx *ctx)
+-{
+- struct starfive_cryp_dev *cryp = ctx->cryp;
+- u32 stat;
+-
+- stat = readl(cryp->base + STARFIVE_IE_MASK_OFFSET);
+- stat &= ~STARFIVE_IE_MASK_PKA_DONE;
+- writel(stat, cryp->base + STARFIVE_IE_MASK_OFFSET);
+-
+- reinit_completion(&cryp->pka_done);
++ return readl_relaxed_poll_timeout(cryp->base + STARFIVE_PKA_CASR_OFFSET, status,
++ status & STARFIVE_PKA_DONE, 10, 100000);
+ }
+
+ static void starfive_rsa_free_key(struct starfive_rsa_key *key)
+@@ -114,10 +97,9 @@ static int starfive_rsa_montgomery_form(
+ rctx->csr.pka.not_r2 = 1;
+ rctx->csr.pka.ie = 1;
+
+- starfive_pka_irq_mask_clear(ctx);
+ writel(rctx->csr.pka.v, cryp->base + STARFIVE_PKA_CACR_OFFSET);
+
+- if (!starfive_pka_wait_done(ctx))
++ if (starfive_pka_wait_done(ctx))
+ return -ETIMEDOUT;
+
+ for (loop = 0; loop <= opsize; loop++)
+@@ -136,10 +118,9 @@ static int starfive_rsa_montgomery_form(
+ rctx->csr.pka.start = 1;
+ rctx->csr.pka.ie = 1;
+
+- starfive_pka_irq_mask_clear(ctx);
+ writel(rctx->csr.pka.v, cryp->base + STARFIVE_PKA_CACR_OFFSET);
+
+- if (!starfive_pka_wait_done(ctx))
++ if (starfive_pka_wait_done(ctx))
+ return -ETIMEDOUT;
+ } else {
+ rctx->csr.pka.v = 0;
+@@ -151,10 +132,9 @@ static int starfive_rsa_montgomery_form(
+ rctx->csr.pka.pre_expf = 1;
+ rctx->csr.pka.ie = 1;
+
+- starfive_pka_irq_mask_clear(ctx);
+ writel(rctx->csr.pka.v, cryp->base + STARFIVE_PKA_CACR_OFFSET);
+
+- if (!starfive_pka_wait_done(ctx))
++ if (starfive_pka_wait_done(ctx))
+ return -ETIMEDOUT;
+
+ for (loop = 0; loop <= count; loop++)
+@@ -172,10 +152,9 @@ static int starfive_rsa_montgomery_form(
+ rctx->csr.pka.start = 1;
+ rctx->csr.pka.ie = 1;
+
+- starfive_pka_irq_mask_clear(ctx);
+ writel(rctx->csr.pka.v, cryp->base + STARFIVE_PKA_CACR_OFFSET);
+
+- if (!starfive_pka_wait_done(ctx))
++ if (starfive_pka_wait_done(ctx))
+ return -ETIMEDOUT;
+ }
+
+@@ -226,11 +205,10 @@ static int starfive_rsa_cpu_start(struct
+ rctx->csr.pka.start = 1;
+ rctx->csr.pka.ie = 1;
+
+- starfive_pka_irq_mask_clear(ctx);
+ writel(rctx->csr.pka.v, cryp->base + STARFIVE_PKA_CACR_OFFSET);
+
+ ret = -ETIMEDOUT;
+- if (!starfive_pka_wait_done(ctx))
++ if (starfive_pka_wait_done(ctx))
+ goto rsa_err;
+
+ if (mlen) {
+@@ -242,10 +220,9 @@ static int starfive_rsa_cpu_start(struct
+ rctx->csr.pka.start = 1;
+ rctx->csr.pka.ie = 1;
+
+- starfive_pka_irq_mask_clear(ctx);
+ writel(rctx->csr.pka.v, cryp->base + STARFIVE_PKA_CACR_OFFSET);
+
+- if (!starfive_pka_wait_done(ctx))
++ if (starfive_pka_wait_done(ctx))
+ goto rsa_err;
+ }
+ }
diff --git a/target/linux/starfive/patches-6.6/0011-crypto-starfive-Pad-adata-with-zeroes.patch b/target/linux/starfive/patches-6.6/0011-crypto-starfive-Pad-adata-with-zeroes.patch
new file mode 100644
index 0000000000..268e4055e0
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0011-crypto-starfive-Pad-adata-with-zeroes.patch
@@ -0,0 +1,46 @@
+From eea9f2c55cf944bbd5cdd43eb655416a867846af Mon Sep 17 00:00:00 2001
+From: Jia Jie Ho <jiajie.ho@starfivetech.com>
+Date: Mon, 20 Nov 2023 11:12:42 +0800
+Subject: [PATCH 011/116] crypto: starfive - Pad adata with zeroes
+
+Aad requires padding with zeroes up to 15 bytes in some cases. This
+patch increases the allocated buffer size for aad and prevents the
+driver accessing uninitialized memory region.
+
+v1->v2: Specify reason for alloc size change in descriptions.
+
+Signed-off-by: Jia Jie Ho <jiajie.ho@starfivetech.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+---
+ drivers/crypto/starfive/jh7110-aes.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/crypto/starfive/jh7110-aes.c
++++ b/drivers/crypto/starfive/jh7110-aes.c
+@@ -500,7 +500,7 @@ static int starfive_aes_prepare_req(stru
+ scatterwalk_start(&cryp->out_walk, rctx->out_sg);
+
+ if (cryp->assoclen) {
+- rctx->adata = kzalloc(ALIGN(cryp->assoclen, AES_BLOCK_SIZE), GFP_KERNEL);
++ rctx->adata = kzalloc(cryp->assoclen + AES_BLOCK_SIZE, GFP_KERNEL);
+ if (!rctx->adata)
+ return dev_err_probe(cryp->dev, -ENOMEM,
+ "Failed to alloc memory for adata");
+@@ -569,7 +569,7 @@ static int starfive_aes_aead_do_one_req(
+ struct starfive_cryp_ctx *ctx =
+ crypto_aead_ctx(crypto_aead_reqtfm(req));
+ struct starfive_cryp_dev *cryp = ctx->cryp;
+- struct starfive_cryp_request_ctx *rctx = ctx->rctx;
++ struct starfive_cryp_request_ctx *rctx;
+ u32 block[AES_BLOCK_32];
+ u32 stat;
+ int err;
+@@ -579,6 +579,8 @@ static int starfive_aes_aead_do_one_req(
+ if (err)
+ return err;
+
++ rctx = ctx->rctx;
++
+ if (!cryp->assoclen)
+ goto write_text;
+
diff --git a/target/linux/starfive/patches-6.6/0012-crypto-starfive-Remove-cfb-and-ofb.patch b/target/linux/starfive/patches-6.6/0012-crypto-starfive-Remove-cfb-and-ofb.patch
new file mode 100644
index 0000000000..f376edb60e
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0012-crypto-starfive-Remove-cfb-and-ofb.patch
@@ -0,0 +1,125 @@
+From 922b213ad22f93fb2788ce119084622ab3d25bf8 Mon Sep 17 00:00:00 2001
+From: Herbert Xu <herbert@gondor.apana.org.au>
+Date: Thu, 30 Nov 2023 18:12:55 +0800
+Subject: [PATCH 012/116] crypto: starfive - Remove cfb and ofb
+
+Remove the unused CFB/OFB implementation.
+
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+---
+ drivers/crypto/starfive/jh7110-aes.c | 71 +--------------------------
+ drivers/crypto/starfive/jh7110-cryp.h | 2 -
+ 2 files changed, 1 insertion(+), 72 deletions(-)
+
+--- a/drivers/crypto/starfive/jh7110-aes.c
++++ b/drivers/crypto/starfive/jh7110-aes.c
+@@ -262,12 +262,7 @@ static int starfive_aes_hw_init(struct s
+ rctx->csr.aes.mode = hw_mode;
+ rctx->csr.aes.cmode = !is_encrypt(cryp);
+ rctx->csr.aes.ie = 1;
+-
+- if (hw_mode == STARFIVE_AES_MODE_CFB ||
+- hw_mode == STARFIVE_AES_MODE_OFB)
+- rctx->csr.aes.stmode = STARFIVE_AES_MODE_XFB_128;
+- else
+- rctx->csr.aes.stmode = STARFIVE_AES_MODE_XFB_1;
++ rctx->csr.aes.stmode = STARFIVE_AES_MODE_XFB_1;
+
+ if (cryp->side_chan) {
+ rctx->csr.aes.delay_aes = 1;
+@@ -294,8 +289,6 @@ static int starfive_aes_hw_init(struct s
+ starfive_aes_ccm_init(ctx);
+ starfive_aes_aead_hw_start(ctx, hw_mode);
+ break;
+- case STARFIVE_AES_MODE_OFB:
+- case STARFIVE_AES_MODE_CFB:
+ case STARFIVE_AES_MODE_CBC:
+ case STARFIVE_AES_MODE_CTR:
+ starfive_aes_write_iv(ctx, (void *)cryp->req.sreq->iv);
+@@ -785,26 +778,6 @@ static int starfive_aes_cbc_decrypt(stru
+ return starfive_aes_crypt(req, STARFIVE_AES_MODE_CBC);
+ }
+
+-static int starfive_aes_cfb_encrypt(struct skcipher_request *req)
+-{
+- return starfive_aes_crypt(req, STARFIVE_AES_MODE_CFB | FLG_ENCRYPT);
+-}
+-
+-static int starfive_aes_cfb_decrypt(struct skcipher_request *req)
+-{
+- return starfive_aes_crypt(req, STARFIVE_AES_MODE_CFB);
+-}
+-
+-static int starfive_aes_ofb_encrypt(struct skcipher_request *req)
+-{
+- return starfive_aes_crypt(req, STARFIVE_AES_MODE_OFB | FLG_ENCRYPT);
+-}
+-
+-static int starfive_aes_ofb_decrypt(struct skcipher_request *req)
+-{
+- return starfive_aes_crypt(req, STARFIVE_AES_MODE_OFB);
+-}
+-
+ static int starfive_aes_ctr_encrypt(struct skcipher_request *req)
+ {
+ return starfive_aes_crypt(req, STARFIVE_AES_MODE_CTR | FLG_ENCRYPT);
+@@ -903,48 +876,6 @@ static struct skcipher_engine_alg skciph
+ .cra_priority = 200,
+ .cra_flags = CRYPTO_ALG_ASYNC,
+ .cra_blocksize = 1,
+- .cra_ctxsize = sizeof(struct starfive_cryp_ctx),
+- .cra_alignmask = 0xf,
+- .cra_module = THIS_MODULE,
+- },
+- .op = {
+- .do_one_request = starfive_aes_do_one_req,
+- },
+-}, {
+- .base.init = starfive_aes_init_tfm,
+- .base.setkey = starfive_aes_setkey,
+- .base.encrypt = starfive_aes_cfb_encrypt,
+- .base.decrypt = starfive_aes_cfb_decrypt,
+- .base.min_keysize = AES_MIN_KEY_SIZE,
+- .base.max_keysize = AES_MAX_KEY_SIZE,
+- .base.ivsize = AES_BLOCK_SIZE,
+- .base.base = {
+- .cra_name = "cfb(aes)",
+- .cra_driver_name = "starfive-cfb-aes",
+- .cra_priority = 200,
+- .cra_flags = CRYPTO_ALG_ASYNC,
+- .cra_blocksize = 1,
+- .cra_ctxsize = sizeof(struct starfive_cryp_ctx),
+- .cra_alignmask = 0xf,
+- .cra_module = THIS_MODULE,
+- },
+- .op = {
+- .do_one_request = starfive_aes_do_one_req,
+- },
+-}, {
+- .base.init = starfive_aes_init_tfm,
+- .base.setkey = starfive_aes_setkey,
+- .base.encrypt = starfive_aes_ofb_encrypt,
+- .base.decrypt = starfive_aes_ofb_decrypt,
+- .base.min_keysize = AES_MIN_KEY_SIZE,
+- .base.max_keysize = AES_MAX_KEY_SIZE,
+- .base.ivsize = AES_BLOCK_SIZE,
+- .base.base = {
+- .cra_name = "ofb(aes)",
+- .cra_driver_name = "starfive-ofb-aes",
+- .cra_priority = 200,
+- .cra_flags = CRYPTO_ALG_ASYNC,
+- .cra_blocksize = 1,
+ .cra_ctxsize = sizeof(struct starfive_cryp_ctx),
+ .cra_alignmask = 0xf,
+ .cra_module = THIS_MODULE,
+--- a/drivers/crypto/starfive/jh7110-cryp.h
++++ b/drivers/crypto/starfive/jh7110-cryp.h
+@@ -50,8 +50,6 @@ union starfive_aes_csr {
+ u32 ccm_start :1;
+ #define STARFIVE_AES_MODE_ECB 0x0
+ #define STARFIVE_AES_MODE_CBC 0x1
+-#define STARFIVE_AES_MODE_CFB 0x2
+-#define STARFIVE_AES_MODE_OFB 0x3
+ #define STARFIVE_AES_MODE_CTR 0x4
+ #define STARFIVE_AES_MODE_CCM 0x5
+ #define STARFIVE_AES_MODE_GCM 0x6
diff --git a/target/linux/starfive/patches-6.6/0013-crypto-starfive-Remove-unneeded-NULL-checks.patch b/target/linux/starfive/patches-6.6/0013-crypto-starfive-Remove-unneeded-NULL-checks.patch
new file mode 100644
index 0000000000..2044b72a35
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0013-crypto-starfive-Remove-unneeded-NULL-checks.patch
@@ -0,0 +1,33 @@
+From 0dbdc763f10c5cfa968dffc290a7c060ee740172 Mon Sep 17 00:00:00 2001
+From: Jia Jie Ho <jiajie.ho@starfivetech.com>
+Date: Mon, 4 Dec 2023 11:02:39 +0800
+Subject: [PATCH 013/116] crypto: starfive - Remove unneeded NULL checks
+
+NULL check before kfree_sensitive function is not needed.
+
+Signed-off-by: Jia Jie Ho <jiajie.ho@starfivetech.com>
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202311301702.LxswfETY-lkp@intel.com/
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+---
+ drivers/crypto/starfive/jh7110-rsa.c | 9 +++------
+ 1 file changed, 3 insertions(+), 6 deletions(-)
+
+--- a/drivers/crypto/starfive/jh7110-rsa.c
++++ b/drivers/crypto/starfive/jh7110-rsa.c
+@@ -45,12 +45,9 @@ static inline int starfive_pka_wait_done
+
+ static void starfive_rsa_free_key(struct starfive_rsa_key *key)
+ {
+- if (key->d)
+- kfree_sensitive(key->d);
+- if (key->e)
+- kfree_sensitive(key->e);
+- if (key->n)
+- kfree_sensitive(key->n);
++ kfree_sensitive(key->d);
++ kfree_sensitive(key->e);
++ kfree_sensitive(key->n);
+ memset(key, 0, sizeof(*key));
+ }
+
diff --git a/target/linux/starfive/patches-6.6/0014-dt-bindings-PCI-Add-PLDA-XpressRICH-PCIe-host-common.patch b/target/linux/starfive/patches-6.6/0014-dt-bindings-PCI-Add-PLDA-XpressRICH-PCIe-host-common.patch
new file mode 100644
index 0000000000..430571565a
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0014-dt-bindings-PCI-Add-PLDA-XpressRICH-PCIe-host-common.patch
@@ -0,0 +1,183 @@
+From 708695ebf1a779de9a1fd2f72f7938afa6c14ada Mon Sep 17 00:00:00 2001
+From: Minda Chen <minda.chen@starfivetech.com>
+Date: Mon, 8 Jan 2024 19:05:51 +0800
+Subject: [PATCH 014/116] dt-bindings: PCI: Add PLDA XpressRICH PCIe host
+ common properties
+
+Add PLDA XpressRICH PCIe host common properties dt-binding doc.
+PolarFire PCIe host using PLDA IP. Move common properties from Microchip
+PolarFire PCIe host to PLDA files.
+
+Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
+Reviewed-by: Hal Feng <hal.feng@starfivetech.com>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+Reviewed-by: Rob Herring <robh@kernel.org>
+Tested-by: John Clark <inindev@gmail.com>
+---
+ .../bindings/pci/microchip,pcie-host.yaml | 55 +-------------
+ .../pci/plda,xpressrich3-axi-common.yaml | 75 +++++++++++++++++++
+ 2 files changed, 76 insertions(+), 54 deletions(-)
+ create mode 100644 Documentation/devicetree/bindings/pci/plda,xpressrich3-axi-common.yaml
+
+--- a/Documentation/devicetree/bindings/pci/microchip,pcie-host.yaml
++++ b/Documentation/devicetree/bindings/pci/microchip,pcie-host.yaml
+@@ -10,21 +10,13 @@ maintainers:
+ - Daire McNamara <daire.mcnamara@microchip.com>
+
+ allOf:
+- - $ref: /schemas/pci/pci-bus.yaml#
++ - $ref: plda,xpressrich3-axi-common.yaml#
+ - $ref: /schemas/interrupt-controller/msi-controller.yaml#
+
+ properties:
+ compatible:
+ const: microchip,pcie-host-1.0 # PolarFire
+
+- reg:
+- maxItems: 2
+-
+- reg-names:
+- items:
+- - const: cfg
+- - const: apb
+-
+ clocks:
+ description:
+ Fabric Interface Controllers, FICs, are the interface between the FPGA
+@@ -52,18 +44,6 @@ properties:
+ items:
+ pattern: '^fic[0-3]$'
+
+- interrupts:
+- minItems: 1
+- items:
+- - description: PCIe host controller
+- - description: builtin MSI controller
+-
+- interrupt-names:
+- minItems: 1
+- items:
+- - const: pcie
+- - const: msi
+-
+ ranges:
+ maxItems: 1
+
+@@ -71,39 +51,6 @@ properties:
+ minItems: 1
+ maxItems: 6
+
+- msi-controller:
+- description: Identifies the node as an MSI controller.
+-
+- msi-parent:
+- description: MSI controller the device is capable of using.
+-
+- interrupt-controller:
+- type: object
+- properties:
+- '#address-cells':
+- const: 0
+-
+- '#interrupt-cells':
+- const: 1
+-
+- interrupt-controller: true
+-
+- required:
+- - '#address-cells'
+- - '#interrupt-cells'
+- - interrupt-controller
+-
+- additionalProperties: false
+-
+-required:
+- - reg
+- - reg-names
+- - "#interrupt-cells"
+- - interrupts
+- - interrupt-map-mask
+- - interrupt-map
+- - msi-controller
+-
+ unevaluatedProperties: false
+
+ examples:
+--- /dev/null
++++ b/Documentation/devicetree/bindings/pci/plda,xpressrich3-axi-common.yaml
+@@ -0,0 +1,75 @@
++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/pci/plda,xpressrich3-axi-common.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: PLDA XpressRICH PCIe host common properties
++
++maintainers:
++ - Daire McNamara <daire.mcnamara@microchip.com>
++ - Kevin Xie <kevin.xie@starfivetech.com>
++
++description:
++ Generic PLDA XpressRICH PCIe host common properties.
++
++allOf:
++ - $ref: /schemas/pci/pci-bus.yaml#
++
++properties:
++ reg:
++ maxItems: 2
++
++ reg-names:
++ items:
++ - const: cfg
++ - const: apb
++
++ interrupts:
++ minItems: 1
++ items:
++ - description: PCIe host controller
++ - description: builtin MSI controller
++
++ interrupt-names:
++ minItems: 1
++ items:
++ - const: pcie
++ - const: msi
++
++ msi-controller:
++ description: Identifies the node as an MSI controller.
++
++ msi-parent:
++ description: MSI controller the device is capable of using.
++
++ interrupt-controller:
++ type: object
++ properties:
++ '#address-cells':
++ const: 0
++
++ '#interrupt-cells':
++ const: 1
++
++ interrupt-controller: true
++
++ required:
++ - '#address-cells'
++ - '#interrupt-cells'
++ - interrupt-controller
++
++ additionalProperties: false
++
++required:
++ - reg
++ - reg-names
++ - interrupts
++ - msi-controller
++ - "#interrupt-cells"
++ - interrupt-map-mask
++ - interrupt-map
++
++additionalProperties: true
++
++...
diff --git a/target/linux/starfive/patches-6.6/0015-PCI-microchip-Move-pcie-microchip-host.c-to-plda-dir.patch b/target/linux/starfive/patches-6.6/0015-PCI-microchip-Move-pcie-microchip-host.c-to-plda-dir.patch
new file mode 100644
index 0000000000..9e7717fa5d
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0015-PCI-microchip-Move-pcie-microchip-host.c-to-plda-dir.patch
@@ -0,0 +1,2523 @@
+From df67154aa92efdc774a8536ece6f431e7850aca2 Mon Sep 17 00:00:00 2001
+From: Minda Chen <minda.chen@starfivetech.com>
+Date: Mon, 8 Jan 2024 19:05:52 +0800
+Subject: [PATCH 015/116] PCI: microchip: Move pcie-microchip-host.c to plda
+ directory
+
+For Microchip Polarfire PCIe host is PLDA XpressRich IP, move to plda
+directory. Prepare for refactoring the codes.
+
+Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+---
+ drivers/pci/controller/Kconfig | 9 +--------
+ drivers/pci/controller/Makefile | 2 +-
+ drivers/pci/controller/plda/Kconfig | 14 ++++++++++++++
+ drivers/pci/controller/plda/Makefile | 2 ++
+ .../controller/{ => plda}/pcie-microchip-host.c | 2 +-
+ 5 files changed, 19 insertions(+), 10 deletions(-)
+ create mode 100644 drivers/pci/controller/plda/Kconfig
+ create mode 100644 drivers/pci/controller/plda/Makefile
+ rename drivers/pci/controller/{ => plda}/pcie-microchip-host.c (99%)
+
+--- a/drivers/pci/controller/Kconfig
++++ b/drivers/pci/controller/Kconfig
+@@ -215,14 +215,6 @@ config PCIE_MT7621
+ help
+ This selects a driver for the MediaTek MT7621 PCIe Controller.
+
+-config PCIE_MICROCHIP_HOST
+- tristate "Microchip AXI PCIe controller"
+- depends on PCI_MSI && OF
+- select PCI_HOST_COMMON
+- help
+- Say Y here if you want kernel to support the Microchip AXI PCIe
+- Host Bridge driver.
+-
+ config PCI_HYPERV_INTERFACE
+ tristate "Microsoft Hyper-V PCI Interface"
+ depends on ((X86 && X86_64) || ARM64) && HYPERV && PCI_MSI
+@@ -345,4 +337,5 @@ config PCIE_XILINX_CPM
+ source "drivers/pci/controller/cadence/Kconfig"
+ source "drivers/pci/controller/dwc/Kconfig"
+ source "drivers/pci/controller/mobiveil/Kconfig"
++source "drivers/pci/controller/plda/Kconfig"
+ endmenu
+--- a/drivers/pci/controller/Makefile
++++ b/drivers/pci/controller/Makefile
+@@ -32,7 +32,6 @@ obj-$(CONFIG_PCIE_ROCKCHIP_EP) += pcie-r
+ obj-$(CONFIG_PCIE_ROCKCHIP_HOST) += pcie-rockchip-host.o
+ obj-$(CONFIG_PCIE_MEDIATEK) += pcie-mediatek.o
+ obj-$(CONFIG_PCIE_MEDIATEK_GEN3) += pcie-mediatek-gen3.o
+-obj-$(CONFIG_PCIE_MICROCHIP_HOST) += pcie-microchip-host.o
+ obj-$(CONFIG_VMD) += vmd.o
+ obj-$(CONFIG_PCIE_BRCMSTB) += pcie-brcmstb.o
+ obj-$(CONFIG_PCI_LOONGSON) += pci-loongson.o
+@@ -43,6 +42,7 @@ obj-$(CONFIG_PCIE_MT7621) += pcie-mt7621
+ # pcie-hisi.o quirks are needed even without CONFIG_PCIE_DW
+ obj-y += dwc/
+ obj-y += mobiveil/
++obj-y += plda/
+
+
+ # The following drivers are for devices that use the generic ACPI
+--- /dev/null
++++ b/drivers/pci/controller/plda/Kconfig
+@@ -0,0 +1,14 @@
++# SPDX-License-Identifier: GPL-2.0
++
++menu "PLDA-based PCIe controllers"
++ depends on PCI
++
++config PCIE_MICROCHIP_HOST
++ tristate "Microchip AXI PCIe controller"
++ depends on PCI_MSI && OF
++ select PCI_HOST_COMMON
++ help
++ Say Y here if you want kernel to support the Microchip AXI PCIe
++ Host Bridge driver.
++
++endmenu
+--- /dev/null
++++ b/drivers/pci/controller/plda/Makefile
+@@ -0,0 +1,2 @@
++# SPDX-License-Identifier: GPL-2.0
++obj-$(CONFIG_PCIE_MICROCHIP_HOST) += pcie-microchip-host.o
+--- a/drivers/pci/controller/pcie-microchip-host.c
++++ /dev/null
+@@ -1,1216 +0,0 @@
+-// SPDX-License-Identifier: GPL-2.0
+-/*
+- * Microchip AXI PCIe Bridge host controller driver
+- *
+- * Copyright (c) 2018 - 2020 Microchip Corporation. All rights reserved.
+- *
+- * Author: Daire McNamara <daire.mcnamara@microchip.com>
+- */
+-
+-#include <linux/bitfield.h>
+-#include <linux/clk.h>
+-#include <linux/irqchip/chained_irq.h>
+-#include <linux/irqdomain.h>
+-#include <linux/module.h>
+-#include <linux/msi.h>
+-#include <linux/of_address.h>
+-#include <linux/of_pci.h>
+-#include <linux/pci-ecam.h>
+-#include <linux/platform_device.h>
+-
+-#include "../pci.h"
+-
+-/* Number of MSI IRQs */
+-#define MC_MAX_NUM_MSI_IRQS 32
+-
+-/* PCIe Bridge Phy and Controller Phy offsets */
+-#define MC_PCIE1_BRIDGE_ADDR 0x00008000u
+-#define MC_PCIE1_CTRL_ADDR 0x0000a000u
+-
+-#define MC_PCIE_BRIDGE_ADDR (MC_PCIE1_BRIDGE_ADDR)
+-#define MC_PCIE_CTRL_ADDR (MC_PCIE1_CTRL_ADDR)
+-
+-/* PCIe Bridge Phy Regs */
+-#define PCIE_PCI_IRQ_DW0 0xa8
+-#define MSIX_CAP_MASK BIT(31)
+-#define NUM_MSI_MSGS_MASK GENMASK(6, 4)
+-#define NUM_MSI_MSGS_SHIFT 4
+-
+-#define IMASK_LOCAL 0x180
+-#define DMA_END_ENGINE_0_MASK 0x00000000u
+-#define DMA_END_ENGINE_0_SHIFT 0
+-#define DMA_END_ENGINE_1_MASK 0x00000000u
+-#define DMA_END_ENGINE_1_SHIFT 1
+-#define DMA_ERROR_ENGINE_0_MASK 0x00000100u
+-#define DMA_ERROR_ENGINE_0_SHIFT 8
+-#define DMA_ERROR_ENGINE_1_MASK 0x00000200u
+-#define DMA_ERROR_ENGINE_1_SHIFT 9
+-#define A_ATR_EVT_POST_ERR_MASK 0x00010000u
+-#define A_ATR_EVT_POST_ERR_SHIFT 16
+-#define A_ATR_EVT_FETCH_ERR_MASK 0x00020000u
+-#define A_ATR_EVT_FETCH_ERR_SHIFT 17
+-#define A_ATR_EVT_DISCARD_ERR_MASK 0x00040000u
+-#define A_ATR_EVT_DISCARD_ERR_SHIFT 18
+-#define A_ATR_EVT_DOORBELL_MASK 0x00000000u
+-#define A_ATR_EVT_DOORBELL_SHIFT 19
+-#define P_ATR_EVT_POST_ERR_MASK 0x00100000u
+-#define P_ATR_EVT_POST_ERR_SHIFT 20
+-#define P_ATR_EVT_FETCH_ERR_MASK 0x00200000u
+-#define P_ATR_EVT_FETCH_ERR_SHIFT 21
+-#define P_ATR_EVT_DISCARD_ERR_MASK 0x00400000u
+-#define P_ATR_EVT_DISCARD_ERR_SHIFT 22
+-#define P_ATR_EVT_DOORBELL_MASK 0x00000000u
+-#define P_ATR_EVT_DOORBELL_SHIFT 23
+-#define PM_MSI_INT_INTA_MASK 0x01000000u
+-#define PM_MSI_INT_INTA_SHIFT 24
+-#define PM_MSI_INT_INTB_MASK 0x02000000u
+-#define PM_MSI_INT_INTB_SHIFT 25
+-#define PM_MSI_INT_INTC_MASK 0x04000000u
+-#define PM_MSI_INT_INTC_SHIFT 26
+-#define PM_MSI_INT_INTD_MASK 0x08000000u
+-#define PM_MSI_INT_INTD_SHIFT 27
+-#define PM_MSI_INT_INTX_MASK 0x0f000000u
+-#define PM_MSI_INT_INTX_SHIFT 24
+-#define PM_MSI_INT_MSI_MASK 0x10000000u
+-#define PM_MSI_INT_MSI_SHIFT 28
+-#define PM_MSI_INT_AER_EVT_MASK 0x20000000u
+-#define PM_MSI_INT_AER_EVT_SHIFT 29
+-#define PM_MSI_INT_EVENTS_MASK 0x40000000u
+-#define PM_MSI_INT_EVENTS_SHIFT 30
+-#define PM_MSI_INT_SYS_ERR_MASK 0x80000000u
+-#define PM_MSI_INT_SYS_ERR_SHIFT 31
+-#define NUM_LOCAL_EVENTS 15
+-#define ISTATUS_LOCAL 0x184
+-#define IMASK_HOST 0x188
+-#define ISTATUS_HOST 0x18c
+-#define IMSI_ADDR 0x190
+-#define ISTATUS_MSI 0x194
+-
+-/* PCIe Master table init defines */
+-#define ATR0_PCIE_WIN0_SRCADDR_PARAM 0x600u
+-#define ATR0_PCIE_ATR_SIZE 0x25
+-#define ATR0_PCIE_ATR_SIZE_SHIFT 1
+-#define ATR0_PCIE_WIN0_SRC_ADDR 0x604u
+-#define ATR0_PCIE_WIN0_TRSL_ADDR_LSB 0x608u
+-#define ATR0_PCIE_WIN0_TRSL_ADDR_UDW 0x60cu
+-#define ATR0_PCIE_WIN0_TRSL_PARAM 0x610u
+-
+-/* PCIe AXI slave table init defines */
+-#define ATR0_AXI4_SLV0_SRCADDR_PARAM 0x800u
+-#define ATR_SIZE_SHIFT 1
+-#define ATR_IMPL_ENABLE 1
+-#define ATR0_AXI4_SLV0_SRC_ADDR 0x804u
+-#define ATR0_AXI4_SLV0_TRSL_ADDR_LSB 0x808u
+-#define ATR0_AXI4_SLV0_TRSL_ADDR_UDW 0x80cu
+-#define ATR0_AXI4_SLV0_TRSL_PARAM 0x810u
+-#define PCIE_TX_RX_INTERFACE 0x00000000u
+-#define PCIE_CONFIG_INTERFACE 0x00000001u
+-
+-#define ATR_ENTRY_SIZE 32
+-
+-/* PCIe Controller Phy Regs */
+-#define SEC_ERROR_EVENT_CNT 0x20
+-#define DED_ERROR_EVENT_CNT 0x24
+-#define SEC_ERROR_INT 0x28
+-#define SEC_ERROR_INT_TX_RAM_SEC_ERR_INT GENMASK(3, 0)
+-#define SEC_ERROR_INT_RX_RAM_SEC_ERR_INT GENMASK(7, 4)
+-#define SEC_ERROR_INT_PCIE2AXI_RAM_SEC_ERR_INT GENMASK(11, 8)
+-#define SEC_ERROR_INT_AXI2PCIE_RAM_SEC_ERR_INT GENMASK(15, 12)
+-#define SEC_ERROR_INT_ALL_RAM_SEC_ERR_INT GENMASK(15, 0)
+-#define NUM_SEC_ERROR_INTS (4)
+-#define SEC_ERROR_INT_MASK 0x2c
+-#define DED_ERROR_INT 0x30
+-#define DED_ERROR_INT_TX_RAM_DED_ERR_INT GENMASK(3, 0)
+-#define DED_ERROR_INT_RX_RAM_DED_ERR_INT GENMASK(7, 4)
+-#define DED_ERROR_INT_PCIE2AXI_RAM_DED_ERR_INT GENMASK(11, 8)
+-#define DED_ERROR_INT_AXI2PCIE_RAM_DED_ERR_INT GENMASK(15, 12)
+-#define DED_ERROR_INT_ALL_RAM_DED_ERR_INT GENMASK(15, 0)
+-#define NUM_DED_ERROR_INTS (4)
+-#define DED_ERROR_INT_MASK 0x34
+-#define ECC_CONTROL 0x38
+-#define ECC_CONTROL_TX_RAM_INJ_ERROR_0 BIT(0)
+-#define ECC_CONTROL_TX_RAM_INJ_ERROR_1 BIT(1)
+-#define ECC_CONTROL_TX_RAM_INJ_ERROR_2 BIT(2)
+-#define ECC_CONTROL_TX_RAM_INJ_ERROR_3 BIT(3)
+-#define ECC_CONTROL_RX_RAM_INJ_ERROR_0 BIT(4)
+-#define ECC_CONTROL_RX_RAM_INJ_ERROR_1 BIT(5)
+-#define ECC_CONTROL_RX_RAM_INJ_ERROR_2 BIT(6)
+-#define ECC_CONTROL_RX_RAM_INJ_ERROR_3 BIT(7)
+-#define ECC_CONTROL_PCIE2AXI_RAM_INJ_ERROR_0 BIT(8)
+-#define ECC_CONTROL_PCIE2AXI_RAM_INJ_ERROR_1 BIT(9)
+-#define ECC_CONTROL_PCIE2AXI_RAM_INJ_ERROR_2 BIT(10)
+-#define ECC_CONTROL_PCIE2AXI_RAM_INJ_ERROR_3 BIT(11)
+-#define ECC_CONTROL_AXI2PCIE_RAM_INJ_ERROR_0 BIT(12)
+-#define ECC_CONTROL_AXI2PCIE_RAM_INJ_ERROR_1 BIT(13)
+-#define ECC_CONTROL_AXI2PCIE_RAM_INJ_ERROR_2 BIT(14)
+-#define ECC_CONTROL_AXI2PCIE_RAM_INJ_ERROR_3 BIT(15)
+-#define ECC_CONTROL_TX_RAM_ECC_BYPASS BIT(24)
+-#define ECC_CONTROL_RX_RAM_ECC_BYPASS BIT(25)
+-#define ECC_CONTROL_PCIE2AXI_RAM_ECC_BYPASS BIT(26)
+-#define ECC_CONTROL_AXI2PCIE_RAM_ECC_BYPASS BIT(27)
+-#define PCIE_EVENT_INT 0x14c
+-#define PCIE_EVENT_INT_L2_EXIT_INT BIT(0)
+-#define PCIE_EVENT_INT_HOTRST_EXIT_INT BIT(1)
+-#define PCIE_EVENT_INT_DLUP_EXIT_INT BIT(2)
+-#define PCIE_EVENT_INT_MASK GENMASK(2, 0)
+-#define PCIE_EVENT_INT_L2_EXIT_INT_MASK BIT(16)
+-#define PCIE_EVENT_INT_HOTRST_EXIT_INT_MASK BIT(17)
+-#define PCIE_EVENT_INT_DLUP_EXIT_INT_MASK BIT(18)
+-#define PCIE_EVENT_INT_ENB_MASK GENMASK(18, 16)
+-#define PCIE_EVENT_INT_ENB_SHIFT 16
+-#define NUM_PCIE_EVENTS (3)
+-
+-/* PCIe Config space MSI capability structure */
+-#define MC_MSI_CAP_CTRL_OFFSET 0xe0u
+-
+-/* Events */
+-#define EVENT_PCIE_L2_EXIT 0
+-#define EVENT_PCIE_HOTRST_EXIT 1
+-#define EVENT_PCIE_DLUP_EXIT 2
+-#define EVENT_SEC_TX_RAM_SEC_ERR 3
+-#define EVENT_SEC_RX_RAM_SEC_ERR 4
+-#define EVENT_SEC_PCIE2AXI_RAM_SEC_ERR 5
+-#define EVENT_SEC_AXI2PCIE_RAM_SEC_ERR 6
+-#define EVENT_DED_TX_RAM_DED_ERR 7
+-#define EVENT_DED_RX_RAM_DED_ERR 8
+-#define EVENT_DED_PCIE2AXI_RAM_DED_ERR 9
+-#define EVENT_DED_AXI2PCIE_RAM_DED_ERR 10
+-#define EVENT_LOCAL_DMA_END_ENGINE_0 11
+-#define EVENT_LOCAL_DMA_END_ENGINE_1 12
+-#define EVENT_LOCAL_DMA_ERROR_ENGINE_0 13
+-#define EVENT_LOCAL_DMA_ERROR_ENGINE_1 14
+-#define EVENT_LOCAL_A_ATR_EVT_POST_ERR 15
+-#define EVENT_LOCAL_A_ATR_EVT_FETCH_ERR 16
+-#define EVENT_LOCAL_A_ATR_EVT_DISCARD_ERR 17
+-#define EVENT_LOCAL_A_ATR_EVT_DOORBELL 18
+-#define EVENT_LOCAL_P_ATR_EVT_POST_ERR 19
+-#define EVENT_LOCAL_P_ATR_EVT_FETCH_ERR 20
+-#define EVENT_LOCAL_P_ATR_EVT_DISCARD_ERR 21
+-#define EVENT_LOCAL_P_ATR_EVT_DOORBELL 22
+-#define EVENT_LOCAL_PM_MSI_INT_INTX 23
+-#define EVENT_LOCAL_PM_MSI_INT_MSI 24
+-#define EVENT_LOCAL_PM_MSI_INT_AER_EVT 25
+-#define EVENT_LOCAL_PM_MSI_INT_EVENTS 26
+-#define EVENT_LOCAL_PM_MSI_INT_SYS_ERR 27
+-#define NUM_EVENTS 28
+-
+-#define PCIE_EVENT_CAUSE(x, s) \
+- [EVENT_PCIE_ ## x] = { __stringify(x), s }
+-
+-#define SEC_ERROR_CAUSE(x, s) \
+- [EVENT_SEC_ ## x] = { __stringify(x), s }
+-
+-#define DED_ERROR_CAUSE(x, s) \
+- [EVENT_DED_ ## x] = { __stringify(x), s }
+-
+-#define LOCAL_EVENT_CAUSE(x, s) \
+- [EVENT_LOCAL_ ## x] = { __stringify(x), s }
+-
+-#define PCIE_EVENT(x) \
+- .base = MC_PCIE_CTRL_ADDR, \
+- .offset = PCIE_EVENT_INT, \
+- .mask_offset = PCIE_EVENT_INT, \
+- .mask_high = 1, \
+- .mask = PCIE_EVENT_INT_ ## x ## _INT, \
+- .enb_mask = PCIE_EVENT_INT_ENB_MASK
+-
+-#define SEC_EVENT(x) \
+- .base = MC_PCIE_CTRL_ADDR, \
+- .offset = SEC_ERROR_INT, \
+- .mask_offset = SEC_ERROR_INT_MASK, \
+- .mask = SEC_ERROR_INT_ ## x ## _INT, \
+- .mask_high = 1, \
+- .enb_mask = 0
+-
+-#define DED_EVENT(x) \
+- .base = MC_PCIE_CTRL_ADDR, \
+- .offset = DED_ERROR_INT, \
+- .mask_offset = DED_ERROR_INT_MASK, \
+- .mask_high = 1, \
+- .mask = DED_ERROR_INT_ ## x ## _INT, \
+- .enb_mask = 0
+-
+-#define LOCAL_EVENT(x) \
+- .base = MC_PCIE_BRIDGE_ADDR, \
+- .offset = ISTATUS_LOCAL, \
+- .mask_offset = IMASK_LOCAL, \
+- .mask_high = 0, \
+- .mask = x ## _MASK, \
+- .enb_mask = 0
+-
+-#define PCIE_EVENT_TO_EVENT_MAP(x) \
+- { PCIE_EVENT_INT_ ## x ## _INT, EVENT_PCIE_ ## x }
+-
+-#define SEC_ERROR_TO_EVENT_MAP(x) \
+- { SEC_ERROR_INT_ ## x ## _INT, EVENT_SEC_ ## x }
+-
+-#define DED_ERROR_TO_EVENT_MAP(x) \
+- { DED_ERROR_INT_ ## x ## _INT, EVENT_DED_ ## x }
+-
+-#define LOCAL_STATUS_TO_EVENT_MAP(x) \
+- { x ## _MASK, EVENT_LOCAL_ ## x }
+-
+-struct event_map {
+- u32 reg_mask;
+- u32 event_bit;
+-};
+-
+-struct mc_msi {
+- struct mutex lock; /* Protect used bitmap */
+- struct irq_domain *msi_domain;
+- struct irq_domain *dev_domain;
+- u32 num_vectors;
+- u64 vector_phy;
+- DECLARE_BITMAP(used, MC_MAX_NUM_MSI_IRQS);
+-};
+-
+-struct mc_pcie {
+- void __iomem *axi_base_addr;
+- struct device *dev;
+- struct irq_domain *intx_domain;
+- struct irq_domain *event_domain;
+- raw_spinlock_t lock;
+- struct mc_msi msi;
+-};
+-
+-struct cause {
+- const char *sym;
+- const char *str;
+-};
+-
+-static const struct cause event_cause[NUM_EVENTS] = {
+- PCIE_EVENT_CAUSE(L2_EXIT, "L2 exit event"),
+- PCIE_EVENT_CAUSE(HOTRST_EXIT, "Hot reset exit event"),
+- PCIE_EVENT_CAUSE(DLUP_EXIT, "DLUP exit event"),
+- SEC_ERROR_CAUSE(TX_RAM_SEC_ERR, "sec error in tx buffer"),
+- SEC_ERROR_CAUSE(RX_RAM_SEC_ERR, "sec error in rx buffer"),
+- SEC_ERROR_CAUSE(PCIE2AXI_RAM_SEC_ERR, "sec error in pcie2axi buffer"),
+- SEC_ERROR_CAUSE(AXI2PCIE_RAM_SEC_ERR, "sec error in axi2pcie buffer"),
+- DED_ERROR_CAUSE(TX_RAM_DED_ERR, "ded error in tx buffer"),
+- DED_ERROR_CAUSE(RX_RAM_DED_ERR, "ded error in rx buffer"),
+- DED_ERROR_CAUSE(PCIE2AXI_RAM_DED_ERR, "ded error in pcie2axi buffer"),
+- DED_ERROR_CAUSE(AXI2PCIE_RAM_DED_ERR, "ded error in axi2pcie buffer"),
+- LOCAL_EVENT_CAUSE(DMA_ERROR_ENGINE_0, "dma engine 0 error"),
+- LOCAL_EVENT_CAUSE(DMA_ERROR_ENGINE_1, "dma engine 1 error"),
+- LOCAL_EVENT_CAUSE(A_ATR_EVT_POST_ERR, "axi write request error"),
+- LOCAL_EVENT_CAUSE(A_ATR_EVT_FETCH_ERR, "axi read request error"),
+- LOCAL_EVENT_CAUSE(A_ATR_EVT_DISCARD_ERR, "axi read timeout"),
+- LOCAL_EVENT_CAUSE(P_ATR_EVT_POST_ERR, "pcie write request error"),
+- LOCAL_EVENT_CAUSE(P_ATR_EVT_FETCH_ERR, "pcie read request error"),
+- LOCAL_EVENT_CAUSE(P_ATR_EVT_DISCARD_ERR, "pcie read timeout"),
+- LOCAL_EVENT_CAUSE(PM_MSI_INT_AER_EVT, "aer event"),
+- LOCAL_EVENT_CAUSE(PM_MSI_INT_EVENTS, "pm/ltr/hotplug event"),
+- LOCAL_EVENT_CAUSE(PM_MSI_INT_SYS_ERR, "system error"),
+-};
+-
+-static struct event_map pcie_event_to_event[] = {
+- PCIE_EVENT_TO_EVENT_MAP(L2_EXIT),
+- PCIE_EVENT_TO_EVENT_MAP(HOTRST_EXIT),
+- PCIE_EVENT_TO_EVENT_MAP(DLUP_EXIT),
+-};
+-
+-static struct event_map sec_error_to_event[] = {
+- SEC_ERROR_TO_EVENT_MAP(TX_RAM_SEC_ERR),
+- SEC_ERROR_TO_EVENT_MAP(RX_RAM_SEC_ERR),
+- SEC_ERROR_TO_EVENT_MAP(PCIE2AXI_RAM_SEC_ERR),
+- SEC_ERROR_TO_EVENT_MAP(AXI2PCIE_RAM_SEC_ERR),
+-};
+-
+-static struct event_map ded_error_to_event[] = {
+- DED_ERROR_TO_EVENT_MAP(TX_RAM_DED_ERR),
+- DED_ERROR_TO_EVENT_MAP(RX_RAM_DED_ERR),
+- DED_ERROR_TO_EVENT_MAP(PCIE2AXI_RAM_DED_ERR),
+- DED_ERROR_TO_EVENT_MAP(AXI2PCIE_RAM_DED_ERR),
+-};
+-
+-static struct event_map local_status_to_event[] = {
+- LOCAL_STATUS_TO_EVENT_MAP(DMA_END_ENGINE_0),
+- LOCAL_STATUS_TO_EVENT_MAP(DMA_END_ENGINE_1),
+- LOCAL_STATUS_TO_EVENT_MAP(DMA_ERROR_ENGINE_0),
+- LOCAL_STATUS_TO_EVENT_MAP(DMA_ERROR_ENGINE_1),
+- LOCAL_STATUS_TO_EVENT_MAP(A_ATR_EVT_POST_ERR),
+- LOCAL_STATUS_TO_EVENT_MAP(A_ATR_EVT_FETCH_ERR),
+- LOCAL_STATUS_TO_EVENT_MAP(A_ATR_EVT_DISCARD_ERR),
+- LOCAL_STATUS_TO_EVENT_MAP(A_ATR_EVT_DOORBELL),
+- LOCAL_STATUS_TO_EVENT_MAP(P_ATR_EVT_POST_ERR),
+- LOCAL_STATUS_TO_EVENT_MAP(P_ATR_EVT_FETCH_ERR),
+- LOCAL_STATUS_TO_EVENT_MAP(P_ATR_EVT_DISCARD_ERR),
+- LOCAL_STATUS_TO_EVENT_MAP(P_ATR_EVT_DOORBELL),
+- LOCAL_STATUS_TO_EVENT_MAP(PM_MSI_INT_INTX),
+- LOCAL_STATUS_TO_EVENT_MAP(PM_MSI_INT_MSI),
+- LOCAL_STATUS_TO_EVENT_MAP(PM_MSI_INT_AER_EVT),
+- LOCAL_STATUS_TO_EVENT_MAP(PM_MSI_INT_EVENTS),
+- LOCAL_STATUS_TO_EVENT_MAP(PM_MSI_INT_SYS_ERR),
+-};
+-
+-static struct {
+- u32 base;
+- u32 offset;
+- u32 mask;
+- u32 shift;
+- u32 enb_mask;
+- u32 mask_high;
+- u32 mask_offset;
+-} event_descs[] = {
+- { PCIE_EVENT(L2_EXIT) },
+- { PCIE_EVENT(HOTRST_EXIT) },
+- { PCIE_EVENT(DLUP_EXIT) },
+- { SEC_EVENT(TX_RAM_SEC_ERR) },
+- { SEC_EVENT(RX_RAM_SEC_ERR) },
+- { SEC_EVENT(PCIE2AXI_RAM_SEC_ERR) },
+- { SEC_EVENT(AXI2PCIE_RAM_SEC_ERR) },
+- { DED_EVENT(TX_RAM_DED_ERR) },
+- { DED_EVENT(RX_RAM_DED_ERR) },
+- { DED_EVENT(PCIE2AXI_RAM_DED_ERR) },
+- { DED_EVENT(AXI2PCIE_RAM_DED_ERR) },
+- { LOCAL_EVENT(DMA_END_ENGINE_0) },
+- { LOCAL_EVENT(DMA_END_ENGINE_1) },
+- { LOCAL_EVENT(DMA_ERROR_ENGINE_0) },
+- { LOCAL_EVENT(DMA_ERROR_ENGINE_1) },
+- { LOCAL_EVENT(A_ATR_EVT_POST_ERR) },
+- { LOCAL_EVENT(A_ATR_EVT_FETCH_ERR) },
+- { LOCAL_EVENT(A_ATR_EVT_DISCARD_ERR) },
+- { LOCAL_EVENT(A_ATR_EVT_DOORBELL) },
+- { LOCAL_EVENT(P_ATR_EVT_POST_ERR) },
+- { LOCAL_EVENT(P_ATR_EVT_FETCH_ERR) },
+- { LOCAL_EVENT(P_ATR_EVT_DISCARD_ERR) },
+- { LOCAL_EVENT(P_ATR_EVT_DOORBELL) },
+- { LOCAL_EVENT(PM_MSI_INT_INTX) },
+- { LOCAL_EVENT(PM_MSI_INT_MSI) },
+- { LOCAL_EVENT(PM_MSI_INT_AER_EVT) },
+- { LOCAL_EVENT(PM_MSI_INT_EVENTS) },
+- { LOCAL_EVENT(PM_MSI_INT_SYS_ERR) },
+-};
+-
+-static char poss_clks[][5] = { "fic0", "fic1", "fic2", "fic3" };
+-
+-static struct mc_pcie *port;
+-
+-static void mc_pcie_enable_msi(struct mc_pcie *port, void __iomem *ecam)
+-{
+- struct mc_msi *msi = &port->msi;
+- u16 reg;
+- u8 queue_size;
+-
+- /* Fixup MSI enable flag */
+- reg = readw_relaxed(ecam + MC_MSI_CAP_CTRL_OFFSET + PCI_MSI_FLAGS);
+- reg |= PCI_MSI_FLAGS_ENABLE;
+- writew_relaxed(reg, ecam + MC_MSI_CAP_CTRL_OFFSET + PCI_MSI_FLAGS);
+-
+- /* Fixup PCI MSI queue flags */
+- queue_size = FIELD_GET(PCI_MSI_FLAGS_QMASK, reg);
+- reg |= FIELD_PREP(PCI_MSI_FLAGS_QSIZE, queue_size);
+- writew_relaxed(reg, ecam + MC_MSI_CAP_CTRL_OFFSET + PCI_MSI_FLAGS);
+-
+- /* Fixup MSI addr fields */
+- writel_relaxed(lower_32_bits(msi->vector_phy),
+- ecam + MC_MSI_CAP_CTRL_OFFSET + PCI_MSI_ADDRESS_LO);
+- writel_relaxed(upper_32_bits(msi->vector_phy),
+- ecam + MC_MSI_CAP_CTRL_OFFSET + PCI_MSI_ADDRESS_HI);
+-}
+-
+-static void mc_handle_msi(struct irq_desc *desc)
+-{
+- struct mc_pcie *port = irq_desc_get_handler_data(desc);
+- struct irq_chip *chip = irq_desc_get_chip(desc);
+- struct device *dev = port->dev;
+- struct mc_msi *msi = &port->msi;
+- void __iomem *bridge_base_addr =
+- port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
+- unsigned long status;
+- u32 bit;
+- int ret;
+-
+- chained_irq_enter(chip, desc);
+-
+- status = readl_relaxed(bridge_base_addr + ISTATUS_LOCAL);
+- if (status & PM_MSI_INT_MSI_MASK) {
+- writel_relaxed(status & PM_MSI_INT_MSI_MASK, bridge_base_addr + ISTATUS_LOCAL);
+- status = readl_relaxed(bridge_base_addr + ISTATUS_MSI);
+- for_each_set_bit(bit, &status, msi->num_vectors) {
+- ret = generic_handle_domain_irq(msi->dev_domain, bit);
+- if (ret)
+- dev_err_ratelimited(dev, "bad MSI IRQ %d\n",
+- bit);
+- }
+- }
+-
+- chained_irq_exit(chip, desc);
+-}
+-
+-static void mc_msi_bottom_irq_ack(struct irq_data *data)
+-{
+- struct mc_pcie *port = irq_data_get_irq_chip_data(data);
+- void __iomem *bridge_base_addr =
+- port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
+- u32 bitpos = data->hwirq;
+-
+- writel_relaxed(BIT(bitpos), bridge_base_addr + ISTATUS_MSI);
+-}
+-
+-static void mc_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
+-{
+- struct mc_pcie *port = irq_data_get_irq_chip_data(data);
+- phys_addr_t addr = port->msi.vector_phy;
+-
+- msg->address_lo = lower_32_bits(addr);
+- msg->address_hi = upper_32_bits(addr);
+- msg->data = data->hwirq;
+-
+- dev_dbg(port->dev, "msi#%x address_hi %#x address_lo %#x\n",
+- (int)data->hwirq, msg->address_hi, msg->address_lo);
+-}
+-
+-static int mc_msi_set_affinity(struct irq_data *irq_data,
+- const struct cpumask *mask, bool force)
+-{
+- return -EINVAL;
+-}
+-
+-static struct irq_chip mc_msi_bottom_irq_chip = {
+- .name = "Microchip MSI",
+- .irq_ack = mc_msi_bottom_irq_ack,
+- .irq_compose_msi_msg = mc_compose_msi_msg,
+- .irq_set_affinity = mc_msi_set_affinity,
+-};
+-
+-static int mc_irq_msi_domain_alloc(struct irq_domain *domain, unsigned int virq,
+- unsigned int nr_irqs, void *args)
+-{
+- struct mc_pcie *port = domain->host_data;
+- struct mc_msi *msi = &port->msi;
+- unsigned long bit;
+-
+- mutex_lock(&msi->lock);
+- bit = find_first_zero_bit(msi->used, msi->num_vectors);
+- if (bit >= msi->num_vectors) {
+- mutex_unlock(&msi->lock);
+- return -ENOSPC;
+- }
+-
+- set_bit(bit, msi->used);
+-
+- irq_domain_set_info(domain, virq, bit, &mc_msi_bottom_irq_chip,
+- domain->host_data, handle_edge_irq, NULL, NULL);
+-
+- mutex_unlock(&msi->lock);
+-
+- return 0;
+-}
+-
+-static void mc_irq_msi_domain_free(struct irq_domain *domain, unsigned int virq,
+- unsigned int nr_irqs)
+-{
+- struct irq_data *d = irq_domain_get_irq_data(domain, virq);
+- struct mc_pcie *port = irq_data_get_irq_chip_data(d);
+- struct mc_msi *msi = &port->msi;
+-
+- mutex_lock(&msi->lock);
+-
+- if (test_bit(d->hwirq, msi->used))
+- __clear_bit(d->hwirq, msi->used);
+- else
+- dev_err(port->dev, "trying to free unused MSI%lu\n", d->hwirq);
+-
+- mutex_unlock(&msi->lock);
+-}
+-
+-static const struct irq_domain_ops msi_domain_ops = {
+- .alloc = mc_irq_msi_domain_alloc,
+- .free = mc_irq_msi_domain_free,
+-};
+-
+-static struct irq_chip mc_msi_irq_chip = {
+- .name = "Microchip PCIe MSI",
+- .irq_ack = irq_chip_ack_parent,
+- .irq_mask = pci_msi_mask_irq,
+- .irq_unmask = pci_msi_unmask_irq,
+-};
+-
+-static struct msi_domain_info mc_msi_domain_info = {
+- .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
+- MSI_FLAG_PCI_MSIX),
+- .chip = &mc_msi_irq_chip,
+-};
+-
+-static int mc_allocate_msi_domains(struct mc_pcie *port)
+-{
+- struct device *dev = port->dev;
+- struct fwnode_handle *fwnode = of_node_to_fwnode(dev->of_node);
+- struct mc_msi *msi = &port->msi;
+-
+- mutex_init(&port->msi.lock);
+-
+- msi->dev_domain = irq_domain_add_linear(NULL, msi->num_vectors,
+- &msi_domain_ops, port);
+- if (!msi->dev_domain) {
+- dev_err(dev, "failed to create IRQ domain\n");
+- return -ENOMEM;
+- }
+-
+- msi->msi_domain = pci_msi_create_irq_domain(fwnode, &mc_msi_domain_info,
+- msi->dev_domain);
+- if (!msi->msi_domain) {
+- dev_err(dev, "failed to create MSI domain\n");
+- irq_domain_remove(msi->dev_domain);
+- return -ENOMEM;
+- }
+-
+- return 0;
+-}
+-
+-static void mc_handle_intx(struct irq_desc *desc)
+-{
+- struct mc_pcie *port = irq_desc_get_handler_data(desc);
+- struct irq_chip *chip = irq_desc_get_chip(desc);
+- struct device *dev = port->dev;
+- void __iomem *bridge_base_addr =
+- port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
+- unsigned long status;
+- u32 bit;
+- int ret;
+-
+- chained_irq_enter(chip, desc);
+-
+- status = readl_relaxed(bridge_base_addr + ISTATUS_LOCAL);
+- if (status & PM_MSI_INT_INTX_MASK) {
+- status &= PM_MSI_INT_INTX_MASK;
+- status >>= PM_MSI_INT_INTX_SHIFT;
+- for_each_set_bit(bit, &status, PCI_NUM_INTX) {
+- ret = generic_handle_domain_irq(port->intx_domain, bit);
+- if (ret)
+- dev_err_ratelimited(dev, "bad INTx IRQ %d\n",
+- bit);
+- }
+- }
+-
+- chained_irq_exit(chip, desc);
+-}
+-
+-static void mc_ack_intx_irq(struct irq_data *data)
+-{
+- struct mc_pcie *port = irq_data_get_irq_chip_data(data);
+- void __iomem *bridge_base_addr =
+- port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
+- u32 mask = BIT(data->hwirq + PM_MSI_INT_INTX_SHIFT);
+-
+- writel_relaxed(mask, bridge_base_addr + ISTATUS_LOCAL);
+-}
+-
+-static void mc_mask_intx_irq(struct irq_data *data)
+-{
+- struct mc_pcie *port = irq_data_get_irq_chip_data(data);
+- void __iomem *bridge_base_addr =
+- port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
+- unsigned long flags;
+- u32 mask = BIT(data->hwirq + PM_MSI_INT_INTX_SHIFT);
+- u32 val;
+-
+- raw_spin_lock_irqsave(&port->lock, flags);
+- val = readl_relaxed(bridge_base_addr + IMASK_LOCAL);
+- val &= ~mask;
+- writel_relaxed(val, bridge_base_addr + IMASK_LOCAL);
+- raw_spin_unlock_irqrestore(&port->lock, flags);
+-}
+-
+-static void mc_unmask_intx_irq(struct irq_data *data)
+-{
+- struct mc_pcie *port = irq_data_get_irq_chip_data(data);
+- void __iomem *bridge_base_addr =
+- port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
+- unsigned long flags;
+- u32 mask = BIT(data->hwirq + PM_MSI_INT_INTX_SHIFT);
+- u32 val;
+-
+- raw_spin_lock_irqsave(&port->lock, flags);
+- val = readl_relaxed(bridge_base_addr + IMASK_LOCAL);
+- val |= mask;
+- writel_relaxed(val, bridge_base_addr + IMASK_LOCAL);
+- raw_spin_unlock_irqrestore(&port->lock, flags);
+-}
+-
+-static struct irq_chip mc_intx_irq_chip = {
+- .name = "Microchip PCIe INTx",
+- .irq_ack = mc_ack_intx_irq,
+- .irq_mask = mc_mask_intx_irq,
+- .irq_unmask = mc_unmask_intx_irq,
+-};
+-
+-static int mc_pcie_intx_map(struct irq_domain *domain, unsigned int irq,
+- irq_hw_number_t hwirq)
+-{
+- irq_set_chip_and_handler(irq, &mc_intx_irq_chip, handle_level_irq);
+- irq_set_chip_data(irq, domain->host_data);
+-
+- return 0;
+-}
+-
+-static const struct irq_domain_ops intx_domain_ops = {
+- .map = mc_pcie_intx_map,
+-};
+-
+-static inline u32 reg_to_event(u32 reg, struct event_map field)
+-{
+- return (reg & field.reg_mask) ? BIT(field.event_bit) : 0;
+-}
+-
+-static u32 pcie_events(struct mc_pcie *port)
+-{
+- void __iomem *ctrl_base_addr = port->axi_base_addr + MC_PCIE_CTRL_ADDR;
+- u32 reg = readl_relaxed(ctrl_base_addr + PCIE_EVENT_INT);
+- u32 val = 0;
+- int i;
+-
+- for (i = 0; i < ARRAY_SIZE(pcie_event_to_event); i++)
+- val |= reg_to_event(reg, pcie_event_to_event[i]);
+-
+- return val;
+-}
+-
+-static u32 sec_errors(struct mc_pcie *port)
+-{
+- void __iomem *ctrl_base_addr = port->axi_base_addr + MC_PCIE_CTRL_ADDR;
+- u32 reg = readl_relaxed(ctrl_base_addr + SEC_ERROR_INT);
+- u32 val = 0;
+- int i;
+-
+- for (i = 0; i < ARRAY_SIZE(sec_error_to_event); i++)
+- val |= reg_to_event(reg, sec_error_to_event[i]);
+-
+- return val;
+-}
+-
+-static u32 ded_errors(struct mc_pcie *port)
+-{
+- void __iomem *ctrl_base_addr = port->axi_base_addr + MC_PCIE_CTRL_ADDR;
+- u32 reg = readl_relaxed(ctrl_base_addr + DED_ERROR_INT);
+- u32 val = 0;
+- int i;
+-
+- for (i = 0; i < ARRAY_SIZE(ded_error_to_event); i++)
+- val |= reg_to_event(reg, ded_error_to_event[i]);
+-
+- return val;
+-}
+-
+-static u32 local_events(struct mc_pcie *port)
+-{
+- void __iomem *bridge_base_addr = port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
+- u32 reg = readl_relaxed(bridge_base_addr + ISTATUS_LOCAL);
+- u32 val = 0;
+- int i;
+-
+- for (i = 0; i < ARRAY_SIZE(local_status_to_event); i++)
+- val |= reg_to_event(reg, local_status_to_event[i]);
+-
+- return val;
+-}
+-
+-static u32 get_events(struct mc_pcie *port)
+-{
+- u32 events = 0;
+-
+- events |= pcie_events(port);
+- events |= sec_errors(port);
+- events |= ded_errors(port);
+- events |= local_events(port);
+-
+- return events;
+-}
+-
+-static irqreturn_t mc_event_handler(int irq, void *dev_id)
+-{
+- struct mc_pcie *port = dev_id;
+- struct device *dev = port->dev;
+- struct irq_data *data;
+-
+- data = irq_domain_get_irq_data(port->event_domain, irq);
+-
+- if (event_cause[data->hwirq].str)
+- dev_err_ratelimited(dev, "%s\n", event_cause[data->hwirq].str);
+- else
+- dev_err_ratelimited(dev, "bad event IRQ %ld\n", data->hwirq);
+-
+- return IRQ_HANDLED;
+-}
+-
+-static void mc_handle_event(struct irq_desc *desc)
+-{
+- struct mc_pcie *port = irq_desc_get_handler_data(desc);
+- unsigned long events;
+- u32 bit;
+- struct irq_chip *chip = irq_desc_get_chip(desc);
+-
+- chained_irq_enter(chip, desc);
+-
+- events = get_events(port);
+-
+- for_each_set_bit(bit, &events, NUM_EVENTS)
+- generic_handle_domain_irq(port->event_domain, bit);
+-
+- chained_irq_exit(chip, desc);
+-}
+-
+-static void mc_ack_event_irq(struct irq_data *data)
+-{
+- struct mc_pcie *port = irq_data_get_irq_chip_data(data);
+- u32 event = data->hwirq;
+- void __iomem *addr;
+- u32 mask;
+-
+- addr = port->axi_base_addr + event_descs[event].base +
+- event_descs[event].offset;
+- mask = event_descs[event].mask;
+- mask |= event_descs[event].enb_mask;
+-
+- writel_relaxed(mask, addr);
+-}
+-
+-static void mc_mask_event_irq(struct irq_data *data)
+-{
+- struct mc_pcie *port = irq_data_get_irq_chip_data(data);
+- u32 event = data->hwirq;
+- void __iomem *addr;
+- u32 mask;
+- u32 val;
+-
+- addr = port->axi_base_addr + event_descs[event].base +
+- event_descs[event].mask_offset;
+- mask = event_descs[event].mask;
+- if (event_descs[event].enb_mask) {
+- mask <<= PCIE_EVENT_INT_ENB_SHIFT;
+- mask &= PCIE_EVENT_INT_ENB_MASK;
+- }
+-
+- if (!event_descs[event].mask_high)
+- mask = ~mask;
+-
+- raw_spin_lock(&port->lock);
+- val = readl_relaxed(addr);
+- if (event_descs[event].mask_high)
+- val |= mask;
+- else
+- val &= mask;
+-
+- writel_relaxed(val, addr);
+- raw_spin_unlock(&port->lock);
+-}
+-
+-static void mc_unmask_event_irq(struct irq_data *data)
+-{
+- struct mc_pcie *port = irq_data_get_irq_chip_data(data);
+- u32 event = data->hwirq;
+- void __iomem *addr;
+- u32 mask;
+- u32 val;
+-
+- addr = port->axi_base_addr + event_descs[event].base +
+- event_descs[event].mask_offset;
+- mask = event_descs[event].mask;
+-
+- if (event_descs[event].enb_mask)
+- mask <<= PCIE_EVENT_INT_ENB_SHIFT;
+-
+- if (event_descs[event].mask_high)
+- mask = ~mask;
+-
+- if (event_descs[event].enb_mask)
+- mask &= PCIE_EVENT_INT_ENB_MASK;
+-
+- raw_spin_lock(&port->lock);
+- val = readl_relaxed(addr);
+- if (event_descs[event].mask_high)
+- val &= mask;
+- else
+- val |= mask;
+- writel_relaxed(val, addr);
+- raw_spin_unlock(&port->lock);
+-}
+-
+-static struct irq_chip mc_event_irq_chip = {
+- .name = "Microchip PCIe EVENT",
+- .irq_ack = mc_ack_event_irq,
+- .irq_mask = mc_mask_event_irq,
+- .irq_unmask = mc_unmask_event_irq,
+-};
+-
+-static int mc_pcie_event_map(struct irq_domain *domain, unsigned int irq,
+- irq_hw_number_t hwirq)
+-{
+- irq_set_chip_and_handler(irq, &mc_event_irq_chip, handle_level_irq);
+- irq_set_chip_data(irq, domain->host_data);
+-
+- return 0;
+-}
+-
+-static const struct irq_domain_ops event_domain_ops = {
+- .map = mc_pcie_event_map,
+-};
+-
+-static inline void mc_pcie_deinit_clk(void *data)
+-{
+- struct clk *clk = data;
+-
+- clk_disable_unprepare(clk);
+-}
+-
+-static inline struct clk *mc_pcie_init_clk(struct device *dev, const char *id)
+-{
+- struct clk *clk;
+- int ret;
+-
+- clk = devm_clk_get_optional(dev, id);
+- if (IS_ERR(clk))
+- return clk;
+- if (!clk)
+- return clk;
+-
+- ret = clk_prepare_enable(clk);
+- if (ret)
+- return ERR_PTR(ret);
+-
+- devm_add_action_or_reset(dev, mc_pcie_deinit_clk, clk);
+-
+- return clk;
+-}
+-
+-static int mc_pcie_init_clks(struct device *dev)
+-{
+- int i;
+- struct clk *fic;
+-
+- /*
+- * PCIe may be clocked via Fabric Interface using between 1 and 4
+- * clocks. Scan DT for clocks and enable them if present
+- */
+- for (i = 0; i < ARRAY_SIZE(poss_clks); i++) {
+- fic = mc_pcie_init_clk(dev, poss_clks[i]);
+- if (IS_ERR(fic))
+- return PTR_ERR(fic);
+- }
+-
+- return 0;
+-}
+-
+-static int mc_pcie_init_irq_domains(struct mc_pcie *port)
+-{
+- struct device *dev = port->dev;
+- struct device_node *node = dev->of_node;
+- struct device_node *pcie_intc_node;
+-
+- /* Setup INTx */
+- pcie_intc_node = of_get_next_child(node, NULL);
+- if (!pcie_intc_node) {
+- dev_err(dev, "failed to find PCIe Intc node\n");
+- return -EINVAL;
+- }
+-
+- port->event_domain = irq_domain_add_linear(pcie_intc_node, NUM_EVENTS,
+- &event_domain_ops, port);
+- if (!port->event_domain) {
+- dev_err(dev, "failed to get event domain\n");
+- of_node_put(pcie_intc_node);
+- return -ENOMEM;
+- }
+-
+- irq_domain_update_bus_token(port->event_domain, DOMAIN_BUS_NEXUS);
+-
+- port->intx_domain = irq_domain_add_linear(pcie_intc_node, PCI_NUM_INTX,
+- &intx_domain_ops, port);
+- if (!port->intx_domain) {
+- dev_err(dev, "failed to get an INTx IRQ domain\n");
+- of_node_put(pcie_intc_node);
+- return -ENOMEM;
+- }
+-
+- irq_domain_update_bus_token(port->intx_domain, DOMAIN_BUS_WIRED);
+-
+- of_node_put(pcie_intc_node);
+- raw_spin_lock_init(&port->lock);
+-
+- return mc_allocate_msi_domains(port);
+-}
+-
+-static void mc_pcie_setup_window(void __iomem *bridge_base_addr, u32 index,
+- phys_addr_t axi_addr, phys_addr_t pci_addr,
+- size_t size)
+-{
+- u32 atr_sz = ilog2(size) - 1;
+- u32 val;
+-
+- if (index == 0)
+- val = PCIE_CONFIG_INTERFACE;
+- else
+- val = PCIE_TX_RX_INTERFACE;
+-
+- writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +
+- ATR0_AXI4_SLV0_TRSL_PARAM);
+-
+- val = lower_32_bits(axi_addr) | (atr_sz << ATR_SIZE_SHIFT) |
+- ATR_IMPL_ENABLE;
+- writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +
+- ATR0_AXI4_SLV0_SRCADDR_PARAM);
+-
+- val = upper_32_bits(axi_addr);
+- writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +
+- ATR0_AXI4_SLV0_SRC_ADDR);
+-
+- val = lower_32_bits(pci_addr);
+- writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +
+- ATR0_AXI4_SLV0_TRSL_ADDR_LSB);
+-
+- val = upper_32_bits(pci_addr);
+- writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +
+- ATR0_AXI4_SLV0_TRSL_ADDR_UDW);
+-
+- val = readl(bridge_base_addr + ATR0_PCIE_WIN0_SRCADDR_PARAM);
+- val |= (ATR0_PCIE_ATR_SIZE << ATR0_PCIE_ATR_SIZE_SHIFT);
+- writel(val, bridge_base_addr + ATR0_PCIE_WIN0_SRCADDR_PARAM);
+- writel(0, bridge_base_addr + ATR0_PCIE_WIN0_SRC_ADDR);
+-}
+-
+-static int mc_pcie_setup_windows(struct platform_device *pdev,
+- struct mc_pcie *port)
+-{
+- void __iomem *bridge_base_addr =
+- port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
+- struct pci_host_bridge *bridge = platform_get_drvdata(pdev);
+- struct resource_entry *entry;
+- u64 pci_addr;
+- u32 index = 1;
+-
+- resource_list_for_each_entry(entry, &bridge->windows) {
+- if (resource_type(entry->res) == IORESOURCE_MEM) {
+- pci_addr = entry->res->start - entry->offset;
+- mc_pcie_setup_window(bridge_base_addr, index,
+- entry->res->start, pci_addr,
+- resource_size(entry->res));
+- index++;
+- }
+- }
+-
+- return 0;
+-}
+-
+-static inline void mc_clear_secs(struct mc_pcie *port)
+-{
+- void __iomem *ctrl_base_addr = port->axi_base_addr + MC_PCIE_CTRL_ADDR;
+-
+- writel_relaxed(SEC_ERROR_INT_ALL_RAM_SEC_ERR_INT, ctrl_base_addr +
+- SEC_ERROR_INT);
+- writel_relaxed(0, ctrl_base_addr + SEC_ERROR_EVENT_CNT);
+-}
+-
+-static inline void mc_clear_deds(struct mc_pcie *port)
+-{
+- void __iomem *ctrl_base_addr = port->axi_base_addr + MC_PCIE_CTRL_ADDR;
+-
+- writel_relaxed(DED_ERROR_INT_ALL_RAM_DED_ERR_INT, ctrl_base_addr +
+- DED_ERROR_INT);
+- writel_relaxed(0, ctrl_base_addr + DED_ERROR_EVENT_CNT);
+-}
+-
+-static void mc_disable_interrupts(struct mc_pcie *port)
+-{
+- void __iomem *bridge_base_addr = port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
+- void __iomem *ctrl_base_addr = port->axi_base_addr + MC_PCIE_CTRL_ADDR;
+- u32 val;
+-
+- /* Ensure ECC bypass is enabled */
+- val = ECC_CONTROL_TX_RAM_ECC_BYPASS |
+- ECC_CONTROL_RX_RAM_ECC_BYPASS |
+- ECC_CONTROL_PCIE2AXI_RAM_ECC_BYPASS |
+- ECC_CONTROL_AXI2PCIE_RAM_ECC_BYPASS;
+- writel_relaxed(val, ctrl_base_addr + ECC_CONTROL);
+-
+- /* Disable SEC errors and clear any outstanding */
+- writel_relaxed(SEC_ERROR_INT_ALL_RAM_SEC_ERR_INT, ctrl_base_addr +
+- SEC_ERROR_INT_MASK);
+- mc_clear_secs(port);
+-
+- /* Disable DED errors and clear any outstanding */
+- writel_relaxed(DED_ERROR_INT_ALL_RAM_DED_ERR_INT, ctrl_base_addr +
+- DED_ERROR_INT_MASK);
+- mc_clear_deds(port);
+-
+- /* Disable local interrupts and clear any outstanding */
+- writel_relaxed(0, bridge_base_addr + IMASK_LOCAL);
+- writel_relaxed(GENMASK(31, 0), bridge_base_addr + ISTATUS_LOCAL);
+- writel_relaxed(GENMASK(31, 0), bridge_base_addr + ISTATUS_MSI);
+-
+- /* Disable PCIe events and clear any outstanding */
+- val = PCIE_EVENT_INT_L2_EXIT_INT |
+- PCIE_EVENT_INT_HOTRST_EXIT_INT |
+- PCIE_EVENT_INT_DLUP_EXIT_INT |
+- PCIE_EVENT_INT_L2_EXIT_INT_MASK |
+- PCIE_EVENT_INT_HOTRST_EXIT_INT_MASK |
+- PCIE_EVENT_INT_DLUP_EXIT_INT_MASK;
+- writel_relaxed(val, ctrl_base_addr + PCIE_EVENT_INT);
+-
+- /* Disable host interrupts and clear any outstanding */
+- writel_relaxed(0, bridge_base_addr + IMASK_HOST);
+- writel_relaxed(GENMASK(31, 0), bridge_base_addr + ISTATUS_HOST);
+-}
+-
+-static int mc_init_interrupts(struct platform_device *pdev, struct mc_pcie *port)
+-{
+- struct device *dev = &pdev->dev;
+- int irq;
+- int i, intx_irq, msi_irq, event_irq;
+- int ret;
+-
+- ret = mc_pcie_init_irq_domains(port);
+- if (ret) {
+- dev_err(dev, "failed creating IRQ domains\n");
+- return ret;
+- }
+-
+- irq = platform_get_irq(pdev, 0);
+- if (irq < 0)
+- return -ENODEV;
+-
+- for (i = 0; i < NUM_EVENTS; i++) {
+- event_irq = irq_create_mapping(port->event_domain, i);
+- if (!event_irq) {
+- dev_err(dev, "failed to map hwirq %d\n", i);
+- return -ENXIO;
+- }
+-
+- ret = devm_request_irq(dev, event_irq, mc_event_handler,
+- 0, event_cause[i].sym, port);
+- if (ret) {
+- dev_err(dev, "failed to request IRQ %d\n", event_irq);
+- return ret;
+- }
+- }
+-
+- intx_irq = irq_create_mapping(port->event_domain,
+- EVENT_LOCAL_PM_MSI_INT_INTX);
+- if (!intx_irq) {
+- dev_err(dev, "failed to map INTx interrupt\n");
+- return -ENXIO;
+- }
+-
+- /* Plug the INTx chained handler */
+- irq_set_chained_handler_and_data(intx_irq, mc_handle_intx, port);
+-
+- msi_irq = irq_create_mapping(port->event_domain,
+- EVENT_LOCAL_PM_MSI_INT_MSI);
+- if (!msi_irq)
+- return -ENXIO;
+-
+- /* Plug the MSI chained handler */
+- irq_set_chained_handler_and_data(msi_irq, mc_handle_msi, port);
+-
+- /* Plug the main event chained handler */
+- irq_set_chained_handler_and_data(irq, mc_handle_event, port);
+-
+- return 0;
+-}
+-
+-static int mc_platform_init(struct pci_config_window *cfg)
+-{
+- struct device *dev = cfg->parent;
+- struct platform_device *pdev = to_platform_device(dev);
+- void __iomem *bridge_base_addr =
+- port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
+- int ret;
+-
+- /* Configure address translation table 0 for PCIe config space */
+- mc_pcie_setup_window(bridge_base_addr, 0, cfg->res.start,
+- cfg->res.start,
+- resource_size(&cfg->res));
+-
+- /* Need some fixups in config space */
+- mc_pcie_enable_msi(port, cfg->win);
+-
+- /* Configure non-config space outbound ranges */
+- ret = mc_pcie_setup_windows(pdev, port);
+- if (ret)
+- return ret;
+-
+- /* Address translation is up; safe to enable interrupts */
+- ret = mc_init_interrupts(pdev, port);
+- if (ret)
+- return ret;
+-
+- return 0;
+-}
+-
+-static int mc_host_probe(struct platform_device *pdev)
+-{
+- struct device *dev = &pdev->dev;
+- void __iomem *bridge_base_addr;
+- int ret;
+- u32 val;
+-
+- port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL);
+- if (!port)
+- return -ENOMEM;
+-
+- port->dev = dev;
+-
+- port->axi_base_addr = devm_platform_ioremap_resource(pdev, 1);
+- if (IS_ERR(port->axi_base_addr))
+- return PTR_ERR(port->axi_base_addr);
+-
+- mc_disable_interrupts(port);
+-
+- bridge_base_addr = port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
+-
+- /* Allow enabling MSI by disabling MSI-X */
+- val = readl(bridge_base_addr + PCIE_PCI_IRQ_DW0);
+- val &= ~MSIX_CAP_MASK;
+- writel(val, bridge_base_addr + PCIE_PCI_IRQ_DW0);
+-
+- /* Pick num vectors from bitfile programmed onto FPGA fabric */
+- val = readl(bridge_base_addr + PCIE_PCI_IRQ_DW0);
+- val &= NUM_MSI_MSGS_MASK;
+- val >>= NUM_MSI_MSGS_SHIFT;
+-
+- port->msi.num_vectors = 1 << val;
+-
+- /* Pick vector address from design */
+- port->msi.vector_phy = readl_relaxed(bridge_base_addr + IMSI_ADDR);
+-
+- ret = mc_pcie_init_clks(dev);
+- if (ret) {
+- dev_err(dev, "failed to get clock resources, error %d\n", ret);
+- return -ENODEV;
+- }
+-
+- return pci_host_common_probe(pdev);
+-}
+-
+-static const struct pci_ecam_ops mc_ecam_ops = {
+- .init = mc_platform_init,
+- .pci_ops = {
+- .map_bus = pci_ecam_map_bus,
+- .read = pci_generic_config_read,
+- .write = pci_generic_config_write,
+- }
+-};
+-
+-static const struct of_device_id mc_pcie_of_match[] = {
+- {
+- .compatible = "microchip,pcie-host-1.0",
+- .data = &mc_ecam_ops,
+- },
+- {},
+-};
+-
+-MODULE_DEVICE_TABLE(of, mc_pcie_of_match);
+-
+-static struct platform_driver mc_pcie_driver = {
+- .probe = mc_host_probe,
+- .driver = {
+- .name = "microchip-pcie",
+- .of_match_table = mc_pcie_of_match,
+- .suppress_bind_attrs = true,
+- },
+-};
+-
+-builtin_platform_driver(mc_pcie_driver);
+-MODULE_LICENSE("GPL");
+-MODULE_DESCRIPTION("Microchip PCIe host controller driver");
+-MODULE_AUTHOR("Daire McNamara <daire.mcnamara@microchip.com>");
+--- /dev/null
++++ b/drivers/pci/controller/plda/pcie-microchip-host.c
+@@ -0,0 +1,1216 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Microchip AXI PCIe Bridge host controller driver
++ *
++ * Copyright (c) 2018 - 2020 Microchip Corporation. All rights reserved.
++ *
++ * Author: Daire McNamara <daire.mcnamara@microchip.com>
++ */
++
++#include <linux/bitfield.h>
++#include <linux/clk.h>
++#include <linux/irqchip/chained_irq.h>
++#include <linux/irqdomain.h>
++#include <linux/module.h>
++#include <linux/msi.h>
++#include <linux/of_address.h>
++#include <linux/of_pci.h>
++#include <linux/pci-ecam.h>
++#include <linux/platform_device.h>
++
++#include "../../pci.h"
++
++/* Number of MSI IRQs */
++#define MC_MAX_NUM_MSI_IRQS 32
++
++/* PCIe Bridge Phy and Controller Phy offsets */
++#define MC_PCIE1_BRIDGE_ADDR 0x00008000u
++#define MC_PCIE1_CTRL_ADDR 0x0000a000u
++
++#define MC_PCIE_BRIDGE_ADDR (MC_PCIE1_BRIDGE_ADDR)
++#define MC_PCIE_CTRL_ADDR (MC_PCIE1_CTRL_ADDR)
++
++/* PCIe Bridge Phy Regs */
++#define PCIE_PCI_IRQ_DW0 0xa8
++#define MSIX_CAP_MASK BIT(31)
++#define NUM_MSI_MSGS_MASK GENMASK(6, 4)
++#define NUM_MSI_MSGS_SHIFT 4
++
++#define IMASK_LOCAL 0x180
++#define DMA_END_ENGINE_0_MASK 0x00000000u
++#define DMA_END_ENGINE_0_SHIFT 0
++#define DMA_END_ENGINE_1_MASK 0x00000000u
++#define DMA_END_ENGINE_1_SHIFT 1
++#define DMA_ERROR_ENGINE_0_MASK 0x00000100u
++#define DMA_ERROR_ENGINE_0_SHIFT 8
++#define DMA_ERROR_ENGINE_1_MASK 0x00000200u
++#define DMA_ERROR_ENGINE_1_SHIFT 9
++#define A_ATR_EVT_POST_ERR_MASK 0x00010000u
++#define A_ATR_EVT_POST_ERR_SHIFT 16
++#define A_ATR_EVT_FETCH_ERR_MASK 0x00020000u
++#define A_ATR_EVT_FETCH_ERR_SHIFT 17
++#define A_ATR_EVT_DISCARD_ERR_MASK 0x00040000u
++#define A_ATR_EVT_DISCARD_ERR_SHIFT 18
++#define A_ATR_EVT_DOORBELL_MASK 0x00000000u
++#define A_ATR_EVT_DOORBELL_SHIFT 19
++#define P_ATR_EVT_POST_ERR_MASK 0x00100000u
++#define P_ATR_EVT_POST_ERR_SHIFT 20
++#define P_ATR_EVT_FETCH_ERR_MASK 0x00200000u
++#define P_ATR_EVT_FETCH_ERR_SHIFT 21
++#define P_ATR_EVT_DISCARD_ERR_MASK 0x00400000u
++#define P_ATR_EVT_DISCARD_ERR_SHIFT 22
++#define P_ATR_EVT_DOORBELL_MASK 0x00000000u
++#define P_ATR_EVT_DOORBELL_SHIFT 23
++#define PM_MSI_INT_INTA_MASK 0x01000000u
++#define PM_MSI_INT_INTA_SHIFT 24
++#define PM_MSI_INT_INTB_MASK 0x02000000u
++#define PM_MSI_INT_INTB_SHIFT 25
++#define PM_MSI_INT_INTC_MASK 0x04000000u
++#define PM_MSI_INT_INTC_SHIFT 26
++#define PM_MSI_INT_INTD_MASK 0x08000000u
++#define PM_MSI_INT_INTD_SHIFT 27
++#define PM_MSI_INT_INTX_MASK 0x0f000000u
++#define PM_MSI_INT_INTX_SHIFT 24
++#define PM_MSI_INT_MSI_MASK 0x10000000u
++#define PM_MSI_INT_MSI_SHIFT 28
++#define PM_MSI_INT_AER_EVT_MASK 0x20000000u
++#define PM_MSI_INT_AER_EVT_SHIFT 29
++#define PM_MSI_INT_EVENTS_MASK 0x40000000u
++#define PM_MSI_INT_EVENTS_SHIFT 30
++#define PM_MSI_INT_SYS_ERR_MASK 0x80000000u
++#define PM_MSI_INT_SYS_ERR_SHIFT 31
++#define NUM_LOCAL_EVENTS 15
++#define ISTATUS_LOCAL 0x184
++#define IMASK_HOST 0x188
++#define ISTATUS_HOST 0x18c
++#define IMSI_ADDR 0x190
++#define ISTATUS_MSI 0x194
++
++/* PCIe Master table init defines */
++#define ATR0_PCIE_WIN0_SRCADDR_PARAM 0x600u
++#define ATR0_PCIE_ATR_SIZE 0x25
++#define ATR0_PCIE_ATR_SIZE_SHIFT 1
++#define ATR0_PCIE_WIN0_SRC_ADDR 0x604u
++#define ATR0_PCIE_WIN0_TRSL_ADDR_LSB 0x608u
++#define ATR0_PCIE_WIN0_TRSL_ADDR_UDW 0x60cu
++#define ATR0_PCIE_WIN0_TRSL_PARAM 0x610u
++
++/* PCIe AXI slave table init defines */
++#define ATR0_AXI4_SLV0_SRCADDR_PARAM 0x800u
++#define ATR_SIZE_SHIFT 1
++#define ATR_IMPL_ENABLE 1
++#define ATR0_AXI4_SLV0_SRC_ADDR 0x804u
++#define ATR0_AXI4_SLV0_TRSL_ADDR_LSB 0x808u
++#define ATR0_AXI4_SLV0_TRSL_ADDR_UDW 0x80cu
++#define ATR0_AXI4_SLV0_TRSL_PARAM 0x810u
++#define PCIE_TX_RX_INTERFACE 0x00000000u
++#define PCIE_CONFIG_INTERFACE 0x00000001u
++
++#define ATR_ENTRY_SIZE 32
++
++/* PCIe Controller Phy Regs */
++#define SEC_ERROR_EVENT_CNT 0x20
++#define DED_ERROR_EVENT_CNT 0x24
++#define SEC_ERROR_INT 0x28
++#define SEC_ERROR_INT_TX_RAM_SEC_ERR_INT GENMASK(3, 0)
++#define SEC_ERROR_INT_RX_RAM_SEC_ERR_INT GENMASK(7, 4)
++#define SEC_ERROR_INT_PCIE2AXI_RAM_SEC_ERR_INT GENMASK(11, 8)
++#define SEC_ERROR_INT_AXI2PCIE_RAM_SEC_ERR_INT GENMASK(15, 12)
++#define SEC_ERROR_INT_ALL_RAM_SEC_ERR_INT GENMASK(15, 0)
++#define NUM_SEC_ERROR_INTS (4)
++#define SEC_ERROR_INT_MASK 0x2c
++#define DED_ERROR_INT 0x30
++#define DED_ERROR_INT_TX_RAM_DED_ERR_INT GENMASK(3, 0)
++#define DED_ERROR_INT_RX_RAM_DED_ERR_INT GENMASK(7, 4)
++#define DED_ERROR_INT_PCIE2AXI_RAM_DED_ERR_INT GENMASK(11, 8)
++#define DED_ERROR_INT_AXI2PCIE_RAM_DED_ERR_INT GENMASK(15, 12)
++#define DED_ERROR_INT_ALL_RAM_DED_ERR_INT GENMASK(15, 0)
++#define NUM_DED_ERROR_INTS (4)
++#define DED_ERROR_INT_MASK 0x34
++#define ECC_CONTROL 0x38
++#define ECC_CONTROL_TX_RAM_INJ_ERROR_0 BIT(0)
++#define ECC_CONTROL_TX_RAM_INJ_ERROR_1 BIT(1)
++#define ECC_CONTROL_TX_RAM_INJ_ERROR_2 BIT(2)
++#define ECC_CONTROL_TX_RAM_INJ_ERROR_3 BIT(3)
++#define ECC_CONTROL_RX_RAM_INJ_ERROR_0 BIT(4)
++#define ECC_CONTROL_RX_RAM_INJ_ERROR_1 BIT(5)
++#define ECC_CONTROL_RX_RAM_INJ_ERROR_2 BIT(6)
++#define ECC_CONTROL_RX_RAM_INJ_ERROR_3 BIT(7)
++#define ECC_CONTROL_PCIE2AXI_RAM_INJ_ERROR_0 BIT(8)
++#define ECC_CONTROL_PCIE2AXI_RAM_INJ_ERROR_1 BIT(9)
++#define ECC_CONTROL_PCIE2AXI_RAM_INJ_ERROR_2 BIT(10)
++#define ECC_CONTROL_PCIE2AXI_RAM_INJ_ERROR_3 BIT(11)
++#define ECC_CONTROL_AXI2PCIE_RAM_INJ_ERROR_0 BIT(12)
++#define ECC_CONTROL_AXI2PCIE_RAM_INJ_ERROR_1 BIT(13)
++#define ECC_CONTROL_AXI2PCIE_RAM_INJ_ERROR_2 BIT(14)
++#define ECC_CONTROL_AXI2PCIE_RAM_INJ_ERROR_3 BIT(15)
++#define ECC_CONTROL_TX_RAM_ECC_BYPASS BIT(24)
++#define ECC_CONTROL_RX_RAM_ECC_BYPASS BIT(25)
++#define ECC_CONTROL_PCIE2AXI_RAM_ECC_BYPASS BIT(26)
++#define ECC_CONTROL_AXI2PCIE_RAM_ECC_BYPASS BIT(27)
++#define PCIE_EVENT_INT 0x14c
++#define PCIE_EVENT_INT_L2_EXIT_INT BIT(0)
++#define PCIE_EVENT_INT_HOTRST_EXIT_INT BIT(1)
++#define PCIE_EVENT_INT_DLUP_EXIT_INT BIT(2)
++#define PCIE_EVENT_INT_MASK GENMASK(2, 0)
++#define PCIE_EVENT_INT_L2_EXIT_INT_MASK BIT(16)
++#define PCIE_EVENT_INT_HOTRST_EXIT_INT_MASK BIT(17)
++#define PCIE_EVENT_INT_DLUP_EXIT_INT_MASK BIT(18)
++#define PCIE_EVENT_INT_ENB_MASK GENMASK(18, 16)
++#define PCIE_EVENT_INT_ENB_SHIFT 16
++#define NUM_PCIE_EVENTS (3)
++
++/* PCIe Config space MSI capability structure */
++#define MC_MSI_CAP_CTRL_OFFSET 0xe0u
++
++/* Events */
++#define EVENT_PCIE_L2_EXIT 0
++#define EVENT_PCIE_HOTRST_EXIT 1
++#define EVENT_PCIE_DLUP_EXIT 2
++#define EVENT_SEC_TX_RAM_SEC_ERR 3
++#define EVENT_SEC_RX_RAM_SEC_ERR 4
++#define EVENT_SEC_PCIE2AXI_RAM_SEC_ERR 5
++#define EVENT_SEC_AXI2PCIE_RAM_SEC_ERR 6
++#define EVENT_DED_TX_RAM_DED_ERR 7
++#define EVENT_DED_RX_RAM_DED_ERR 8
++#define EVENT_DED_PCIE2AXI_RAM_DED_ERR 9
++#define EVENT_DED_AXI2PCIE_RAM_DED_ERR 10
++#define EVENT_LOCAL_DMA_END_ENGINE_0 11
++#define EVENT_LOCAL_DMA_END_ENGINE_1 12
++#define EVENT_LOCAL_DMA_ERROR_ENGINE_0 13
++#define EVENT_LOCAL_DMA_ERROR_ENGINE_1 14
++#define EVENT_LOCAL_A_ATR_EVT_POST_ERR 15
++#define EVENT_LOCAL_A_ATR_EVT_FETCH_ERR 16
++#define EVENT_LOCAL_A_ATR_EVT_DISCARD_ERR 17
++#define EVENT_LOCAL_A_ATR_EVT_DOORBELL 18
++#define EVENT_LOCAL_P_ATR_EVT_POST_ERR 19
++#define EVENT_LOCAL_P_ATR_EVT_FETCH_ERR 20
++#define EVENT_LOCAL_P_ATR_EVT_DISCARD_ERR 21
++#define EVENT_LOCAL_P_ATR_EVT_DOORBELL 22
++#define EVENT_LOCAL_PM_MSI_INT_INTX 23
++#define EVENT_LOCAL_PM_MSI_INT_MSI 24
++#define EVENT_LOCAL_PM_MSI_INT_AER_EVT 25
++#define EVENT_LOCAL_PM_MSI_INT_EVENTS 26
++#define EVENT_LOCAL_PM_MSI_INT_SYS_ERR 27
++#define NUM_EVENTS 28
++
++#define PCIE_EVENT_CAUSE(x, s) \
++ [EVENT_PCIE_ ## x] = { __stringify(x), s }
++
++#define SEC_ERROR_CAUSE(x, s) \
++ [EVENT_SEC_ ## x] = { __stringify(x), s }
++
++#define DED_ERROR_CAUSE(x, s) \
++ [EVENT_DED_ ## x] = { __stringify(x), s }
++
++#define LOCAL_EVENT_CAUSE(x, s) \
++ [EVENT_LOCAL_ ## x] = { __stringify(x), s }
++
++#define PCIE_EVENT(x) \
++ .base = MC_PCIE_CTRL_ADDR, \
++ .offset = PCIE_EVENT_INT, \
++ .mask_offset = PCIE_EVENT_INT, \
++ .mask_high = 1, \
++ .mask = PCIE_EVENT_INT_ ## x ## _INT, \
++ .enb_mask = PCIE_EVENT_INT_ENB_MASK
++
++#define SEC_EVENT(x) \
++ .base = MC_PCIE_CTRL_ADDR, \
++ .offset = SEC_ERROR_INT, \
++ .mask_offset = SEC_ERROR_INT_MASK, \
++ .mask = SEC_ERROR_INT_ ## x ## _INT, \
++ .mask_high = 1, \
++ .enb_mask = 0
++
++#define DED_EVENT(x) \
++ .base = MC_PCIE_CTRL_ADDR, \
++ .offset = DED_ERROR_INT, \
++ .mask_offset = DED_ERROR_INT_MASK, \
++ .mask_high = 1, \
++ .mask = DED_ERROR_INT_ ## x ## _INT, \
++ .enb_mask = 0
++
++#define LOCAL_EVENT(x) \
++ .base = MC_PCIE_BRIDGE_ADDR, \
++ .offset = ISTATUS_LOCAL, \
++ .mask_offset = IMASK_LOCAL, \
++ .mask_high = 0, \
++ .mask = x ## _MASK, \
++ .enb_mask = 0
++
++#define PCIE_EVENT_TO_EVENT_MAP(x) \
++ { PCIE_EVENT_INT_ ## x ## _INT, EVENT_PCIE_ ## x }
++
++#define SEC_ERROR_TO_EVENT_MAP(x) \
++ { SEC_ERROR_INT_ ## x ## _INT, EVENT_SEC_ ## x }
++
++#define DED_ERROR_TO_EVENT_MAP(x) \
++ { DED_ERROR_INT_ ## x ## _INT, EVENT_DED_ ## x }
++
++#define LOCAL_STATUS_TO_EVENT_MAP(x) \
++ { x ## _MASK, EVENT_LOCAL_ ## x }
++
++struct event_map {
++ u32 reg_mask;
++ u32 event_bit;
++};
++
++struct mc_msi {
++ struct mutex lock; /* Protect used bitmap */
++ struct irq_domain *msi_domain;
++ struct irq_domain *dev_domain;
++ u32 num_vectors;
++ u64 vector_phy;
++ DECLARE_BITMAP(used, MC_MAX_NUM_MSI_IRQS);
++};
++
++struct mc_pcie {
++ void __iomem *axi_base_addr;
++ struct device *dev;
++ struct irq_domain *intx_domain;
++ struct irq_domain *event_domain;
++ raw_spinlock_t lock;
++ struct mc_msi msi;
++};
++
++struct cause {
++ const char *sym;
++ const char *str;
++};
++
++static const struct cause event_cause[NUM_EVENTS] = {
++ PCIE_EVENT_CAUSE(L2_EXIT, "L2 exit event"),
++ PCIE_EVENT_CAUSE(HOTRST_EXIT, "Hot reset exit event"),
++ PCIE_EVENT_CAUSE(DLUP_EXIT, "DLUP exit event"),
++ SEC_ERROR_CAUSE(TX_RAM_SEC_ERR, "sec error in tx buffer"),
++ SEC_ERROR_CAUSE(RX_RAM_SEC_ERR, "sec error in rx buffer"),
++ SEC_ERROR_CAUSE(PCIE2AXI_RAM_SEC_ERR, "sec error in pcie2axi buffer"),
++ SEC_ERROR_CAUSE(AXI2PCIE_RAM_SEC_ERR, "sec error in axi2pcie buffer"),
++ DED_ERROR_CAUSE(TX_RAM_DED_ERR, "ded error in tx buffer"),
++ DED_ERROR_CAUSE(RX_RAM_DED_ERR, "ded error in rx buffer"),
++ DED_ERROR_CAUSE(PCIE2AXI_RAM_DED_ERR, "ded error in pcie2axi buffer"),
++ DED_ERROR_CAUSE(AXI2PCIE_RAM_DED_ERR, "ded error in axi2pcie buffer"),
++ LOCAL_EVENT_CAUSE(DMA_ERROR_ENGINE_0, "dma engine 0 error"),
++ LOCAL_EVENT_CAUSE(DMA_ERROR_ENGINE_1, "dma engine 1 error"),
++ LOCAL_EVENT_CAUSE(A_ATR_EVT_POST_ERR, "axi write request error"),
++ LOCAL_EVENT_CAUSE(A_ATR_EVT_FETCH_ERR, "axi read request error"),
++ LOCAL_EVENT_CAUSE(A_ATR_EVT_DISCARD_ERR, "axi read timeout"),
++ LOCAL_EVENT_CAUSE(P_ATR_EVT_POST_ERR, "pcie write request error"),
++ LOCAL_EVENT_CAUSE(P_ATR_EVT_FETCH_ERR, "pcie read request error"),
++ LOCAL_EVENT_CAUSE(P_ATR_EVT_DISCARD_ERR, "pcie read timeout"),
++ LOCAL_EVENT_CAUSE(PM_MSI_INT_AER_EVT, "aer event"),
++ LOCAL_EVENT_CAUSE(PM_MSI_INT_EVENTS, "pm/ltr/hotplug event"),
++ LOCAL_EVENT_CAUSE(PM_MSI_INT_SYS_ERR, "system error"),
++};
++
++static struct event_map pcie_event_to_event[] = {
++ PCIE_EVENT_TO_EVENT_MAP(L2_EXIT),
++ PCIE_EVENT_TO_EVENT_MAP(HOTRST_EXIT),
++ PCIE_EVENT_TO_EVENT_MAP(DLUP_EXIT),
++};
++
++static struct event_map sec_error_to_event[] = {
++ SEC_ERROR_TO_EVENT_MAP(TX_RAM_SEC_ERR),
++ SEC_ERROR_TO_EVENT_MAP(RX_RAM_SEC_ERR),
++ SEC_ERROR_TO_EVENT_MAP(PCIE2AXI_RAM_SEC_ERR),
++ SEC_ERROR_TO_EVENT_MAP(AXI2PCIE_RAM_SEC_ERR),
++};
++
++static struct event_map ded_error_to_event[] = {
++ DED_ERROR_TO_EVENT_MAP(TX_RAM_DED_ERR),
++ DED_ERROR_TO_EVENT_MAP(RX_RAM_DED_ERR),
++ DED_ERROR_TO_EVENT_MAP(PCIE2AXI_RAM_DED_ERR),
++ DED_ERROR_TO_EVENT_MAP(AXI2PCIE_RAM_DED_ERR),
++};
++
++static struct event_map local_status_to_event[] = {
++ LOCAL_STATUS_TO_EVENT_MAP(DMA_END_ENGINE_0),
++ LOCAL_STATUS_TO_EVENT_MAP(DMA_END_ENGINE_1),
++ LOCAL_STATUS_TO_EVENT_MAP(DMA_ERROR_ENGINE_0),
++ LOCAL_STATUS_TO_EVENT_MAP(DMA_ERROR_ENGINE_1),
++ LOCAL_STATUS_TO_EVENT_MAP(A_ATR_EVT_POST_ERR),
++ LOCAL_STATUS_TO_EVENT_MAP(A_ATR_EVT_FETCH_ERR),
++ LOCAL_STATUS_TO_EVENT_MAP(A_ATR_EVT_DISCARD_ERR),
++ LOCAL_STATUS_TO_EVENT_MAP(A_ATR_EVT_DOORBELL),
++ LOCAL_STATUS_TO_EVENT_MAP(P_ATR_EVT_POST_ERR),
++ LOCAL_STATUS_TO_EVENT_MAP(P_ATR_EVT_FETCH_ERR),
++ LOCAL_STATUS_TO_EVENT_MAP(P_ATR_EVT_DISCARD_ERR),
++ LOCAL_STATUS_TO_EVENT_MAP(P_ATR_EVT_DOORBELL),
++ LOCAL_STATUS_TO_EVENT_MAP(PM_MSI_INT_INTX),
++ LOCAL_STATUS_TO_EVENT_MAP(PM_MSI_INT_MSI),
++ LOCAL_STATUS_TO_EVENT_MAP(PM_MSI_INT_AER_EVT),
++ LOCAL_STATUS_TO_EVENT_MAP(PM_MSI_INT_EVENTS),
++ LOCAL_STATUS_TO_EVENT_MAP(PM_MSI_INT_SYS_ERR),
++};
++
++static struct {
++ u32 base;
++ u32 offset;
++ u32 mask;
++ u32 shift;
++ u32 enb_mask;
++ u32 mask_high;
++ u32 mask_offset;
++} event_descs[] = {
++ { PCIE_EVENT(L2_EXIT) },
++ { PCIE_EVENT(HOTRST_EXIT) },
++ { PCIE_EVENT(DLUP_EXIT) },
++ { SEC_EVENT(TX_RAM_SEC_ERR) },
++ { SEC_EVENT(RX_RAM_SEC_ERR) },
++ { SEC_EVENT(PCIE2AXI_RAM_SEC_ERR) },
++ { SEC_EVENT(AXI2PCIE_RAM_SEC_ERR) },
++ { DED_EVENT(TX_RAM_DED_ERR) },
++ { DED_EVENT(RX_RAM_DED_ERR) },
++ { DED_EVENT(PCIE2AXI_RAM_DED_ERR) },
++ { DED_EVENT(AXI2PCIE_RAM_DED_ERR) },
++ { LOCAL_EVENT(DMA_END_ENGINE_0) },
++ { LOCAL_EVENT(DMA_END_ENGINE_1) },
++ { LOCAL_EVENT(DMA_ERROR_ENGINE_0) },
++ { LOCAL_EVENT(DMA_ERROR_ENGINE_1) },
++ { LOCAL_EVENT(A_ATR_EVT_POST_ERR) },
++ { LOCAL_EVENT(A_ATR_EVT_FETCH_ERR) },
++ { LOCAL_EVENT(A_ATR_EVT_DISCARD_ERR) },
++ { LOCAL_EVENT(A_ATR_EVT_DOORBELL) },
++ { LOCAL_EVENT(P_ATR_EVT_POST_ERR) },
++ { LOCAL_EVENT(P_ATR_EVT_FETCH_ERR) },
++ { LOCAL_EVENT(P_ATR_EVT_DISCARD_ERR) },
++ { LOCAL_EVENT(P_ATR_EVT_DOORBELL) },
++ { LOCAL_EVENT(PM_MSI_INT_INTX) },
++ { LOCAL_EVENT(PM_MSI_INT_MSI) },
++ { LOCAL_EVENT(PM_MSI_INT_AER_EVT) },
++ { LOCAL_EVENT(PM_MSI_INT_EVENTS) },
++ { LOCAL_EVENT(PM_MSI_INT_SYS_ERR) },
++};
++
++static char poss_clks[][5] = { "fic0", "fic1", "fic2", "fic3" };
++
++static struct mc_pcie *port;
++
++static void mc_pcie_enable_msi(struct mc_pcie *port, void __iomem *ecam)
++{
++ struct mc_msi *msi = &port->msi;
++ u16 reg;
++ u8 queue_size;
++
++ /* Fixup MSI enable flag */
++ reg = readw_relaxed(ecam + MC_MSI_CAP_CTRL_OFFSET + PCI_MSI_FLAGS);
++ reg |= PCI_MSI_FLAGS_ENABLE;
++ writew_relaxed(reg, ecam + MC_MSI_CAP_CTRL_OFFSET + PCI_MSI_FLAGS);
++
++ /* Fixup PCI MSI queue flags */
++ queue_size = FIELD_GET(PCI_MSI_FLAGS_QMASK, reg);
++ reg |= FIELD_PREP(PCI_MSI_FLAGS_QSIZE, queue_size);
++ writew_relaxed(reg, ecam + MC_MSI_CAP_CTRL_OFFSET + PCI_MSI_FLAGS);
++
++ /* Fixup MSI addr fields */
++ writel_relaxed(lower_32_bits(msi->vector_phy),
++ ecam + MC_MSI_CAP_CTRL_OFFSET + PCI_MSI_ADDRESS_LO);
++ writel_relaxed(upper_32_bits(msi->vector_phy),
++ ecam + MC_MSI_CAP_CTRL_OFFSET + PCI_MSI_ADDRESS_HI);
++}
++
++static void mc_handle_msi(struct irq_desc *desc)
++{
++ struct mc_pcie *port = irq_desc_get_handler_data(desc);
++ struct irq_chip *chip = irq_desc_get_chip(desc);
++ struct device *dev = port->dev;
++ struct mc_msi *msi = &port->msi;
++ void __iomem *bridge_base_addr =
++ port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
++ unsigned long status;
++ u32 bit;
++ int ret;
++
++ chained_irq_enter(chip, desc);
++
++ status = readl_relaxed(bridge_base_addr + ISTATUS_LOCAL);
++ if (status & PM_MSI_INT_MSI_MASK) {
++ writel_relaxed(status & PM_MSI_INT_MSI_MASK, bridge_base_addr + ISTATUS_LOCAL);
++ status = readl_relaxed(bridge_base_addr + ISTATUS_MSI);
++ for_each_set_bit(bit, &status, msi->num_vectors) {
++ ret = generic_handle_domain_irq(msi->dev_domain, bit);
++ if (ret)
++ dev_err_ratelimited(dev, "bad MSI IRQ %d\n",
++ bit);
++ }
++ }
++
++ chained_irq_exit(chip, desc);
++}
++
++static void mc_msi_bottom_irq_ack(struct irq_data *data)
++{
++ struct mc_pcie *port = irq_data_get_irq_chip_data(data);
++ void __iomem *bridge_base_addr =
++ port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
++ u32 bitpos = data->hwirq;
++
++ writel_relaxed(BIT(bitpos), bridge_base_addr + ISTATUS_MSI);
++}
++
++static void mc_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
++{
++ struct mc_pcie *port = irq_data_get_irq_chip_data(data);
++ phys_addr_t addr = port->msi.vector_phy;
++
++ msg->address_lo = lower_32_bits(addr);
++ msg->address_hi = upper_32_bits(addr);
++ msg->data = data->hwirq;
++
++ dev_dbg(port->dev, "msi#%x address_hi %#x address_lo %#x\n",
++ (int)data->hwirq, msg->address_hi, msg->address_lo);
++}
++
++static int mc_msi_set_affinity(struct irq_data *irq_data,
++ const struct cpumask *mask, bool force)
++{
++ return -EINVAL;
++}
++
++static struct irq_chip mc_msi_bottom_irq_chip = {
++ .name = "Microchip MSI",
++ .irq_ack = mc_msi_bottom_irq_ack,
++ .irq_compose_msi_msg = mc_compose_msi_msg,
++ .irq_set_affinity = mc_msi_set_affinity,
++};
++
++static int mc_irq_msi_domain_alloc(struct irq_domain *domain, unsigned int virq,
++ unsigned int nr_irqs, void *args)
++{
++ struct mc_pcie *port = domain->host_data;
++ struct mc_msi *msi = &port->msi;
++ unsigned long bit;
++
++ mutex_lock(&msi->lock);
++ bit = find_first_zero_bit(msi->used, msi->num_vectors);
++ if (bit >= msi->num_vectors) {
++ mutex_unlock(&msi->lock);
++ return -ENOSPC;
++ }
++
++ set_bit(bit, msi->used);
++
++ irq_domain_set_info(domain, virq, bit, &mc_msi_bottom_irq_chip,
++ domain->host_data, handle_edge_irq, NULL, NULL);
++
++ mutex_unlock(&msi->lock);
++
++ return 0;
++}
++
++static void mc_irq_msi_domain_free(struct irq_domain *domain, unsigned int virq,
++ unsigned int nr_irqs)
++{
++ struct irq_data *d = irq_domain_get_irq_data(domain, virq);
++ struct mc_pcie *port = irq_data_get_irq_chip_data(d);
++ struct mc_msi *msi = &port->msi;
++
++ mutex_lock(&msi->lock);
++
++ if (test_bit(d->hwirq, msi->used))
++ __clear_bit(d->hwirq, msi->used);
++ else
++ dev_err(port->dev, "trying to free unused MSI%lu\n", d->hwirq);
++
++ mutex_unlock(&msi->lock);
++}
++
++static const struct irq_domain_ops msi_domain_ops = {
++ .alloc = mc_irq_msi_domain_alloc,
++ .free = mc_irq_msi_domain_free,
++};
++
++static struct irq_chip mc_msi_irq_chip = {
++ .name = "Microchip PCIe MSI",
++ .irq_ack = irq_chip_ack_parent,
++ .irq_mask = pci_msi_mask_irq,
++ .irq_unmask = pci_msi_unmask_irq,
++};
++
++static struct msi_domain_info mc_msi_domain_info = {
++ .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
++ MSI_FLAG_PCI_MSIX),
++ .chip = &mc_msi_irq_chip,
++};
++
++static int mc_allocate_msi_domains(struct mc_pcie *port)
++{
++ struct device *dev = port->dev;
++ struct fwnode_handle *fwnode = of_node_to_fwnode(dev->of_node);
++ struct mc_msi *msi = &port->msi;
++
++ mutex_init(&port->msi.lock);
++
++ msi->dev_domain = irq_domain_add_linear(NULL, msi->num_vectors,
++ &msi_domain_ops, port);
++ if (!msi->dev_domain) {
++ dev_err(dev, "failed to create IRQ domain\n");
++ return -ENOMEM;
++ }
++
++ msi->msi_domain = pci_msi_create_irq_domain(fwnode, &mc_msi_domain_info,
++ msi->dev_domain);
++ if (!msi->msi_domain) {
++ dev_err(dev, "failed to create MSI domain\n");
++ irq_domain_remove(msi->dev_domain);
++ return -ENOMEM;
++ }
++
++ return 0;
++}
++
++static void mc_handle_intx(struct irq_desc *desc)
++{
++ struct mc_pcie *port = irq_desc_get_handler_data(desc);
++ struct irq_chip *chip = irq_desc_get_chip(desc);
++ struct device *dev = port->dev;
++ void __iomem *bridge_base_addr =
++ port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
++ unsigned long status;
++ u32 bit;
++ int ret;
++
++ chained_irq_enter(chip, desc);
++
++ status = readl_relaxed(bridge_base_addr + ISTATUS_LOCAL);
++ if (status & PM_MSI_INT_INTX_MASK) {
++ status &= PM_MSI_INT_INTX_MASK;
++ status >>= PM_MSI_INT_INTX_SHIFT;
++ for_each_set_bit(bit, &status, PCI_NUM_INTX) {
++ ret = generic_handle_domain_irq(port->intx_domain, bit);
++ if (ret)
++ dev_err_ratelimited(dev, "bad INTx IRQ %d\n",
++ bit);
++ }
++ }
++
++ chained_irq_exit(chip, desc);
++}
++
++static void mc_ack_intx_irq(struct irq_data *data)
++{
++ struct mc_pcie *port = irq_data_get_irq_chip_data(data);
++ void __iomem *bridge_base_addr =
++ port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
++ u32 mask = BIT(data->hwirq + PM_MSI_INT_INTX_SHIFT);
++
++ writel_relaxed(mask, bridge_base_addr + ISTATUS_LOCAL);
++}
++
++static void mc_mask_intx_irq(struct irq_data *data)
++{
++ struct mc_pcie *port = irq_data_get_irq_chip_data(data);
++ void __iomem *bridge_base_addr =
++ port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
++ unsigned long flags;
++ u32 mask = BIT(data->hwirq + PM_MSI_INT_INTX_SHIFT);
++ u32 val;
++
++ raw_spin_lock_irqsave(&port->lock, flags);
++ val = readl_relaxed(bridge_base_addr + IMASK_LOCAL);
++ val &= ~mask;
++ writel_relaxed(val, bridge_base_addr + IMASK_LOCAL);
++ raw_spin_unlock_irqrestore(&port->lock, flags);
++}
++
++static void mc_unmask_intx_irq(struct irq_data *data)
++{
++ struct mc_pcie *port = irq_data_get_irq_chip_data(data);
++ void __iomem *bridge_base_addr =
++ port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
++ unsigned long flags;
++ u32 mask = BIT(data->hwirq + PM_MSI_INT_INTX_SHIFT);
++ u32 val;
++
++ raw_spin_lock_irqsave(&port->lock, flags);
++ val = readl_relaxed(bridge_base_addr + IMASK_LOCAL);
++ val |= mask;
++ writel_relaxed(val, bridge_base_addr + IMASK_LOCAL);
++ raw_spin_unlock_irqrestore(&port->lock, flags);
++}
++
++static struct irq_chip mc_intx_irq_chip = {
++ .name = "Microchip PCIe INTx",
++ .irq_ack = mc_ack_intx_irq,
++ .irq_mask = mc_mask_intx_irq,
++ .irq_unmask = mc_unmask_intx_irq,
++};
++
++static int mc_pcie_intx_map(struct irq_domain *domain, unsigned int irq,
++ irq_hw_number_t hwirq)
++{
++ irq_set_chip_and_handler(irq, &mc_intx_irq_chip, handle_level_irq);
++ irq_set_chip_data(irq, domain->host_data);
++
++ return 0;
++}
++
++static const struct irq_domain_ops intx_domain_ops = {
++ .map = mc_pcie_intx_map,
++};
++
++static inline u32 reg_to_event(u32 reg, struct event_map field)
++{
++ return (reg & field.reg_mask) ? BIT(field.event_bit) : 0;
++}
++
++static u32 pcie_events(struct mc_pcie *port)
++{
++ void __iomem *ctrl_base_addr = port->axi_base_addr + MC_PCIE_CTRL_ADDR;
++ u32 reg = readl_relaxed(ctrl_base_addr + PCIE_EVENT_INT);
++ u32 val = 0;
++ int i;
++
++ for (i = 0; i < ARRAY_SIZE(pcie_event_to_event); i++)
++ val |= reg_to_event(reg, pcie_event_to_event[i]);
++
++ return val;
++}
++
++static u32 sec_errors(struct mc_pcie *port)
++{
++ void __iomem *ctrl_base_addr = port->axi_base_addr + MC_PCIE_CTRL_ADDR;
++ u32 reg = readl_relaxed(ctrl_base_addr + SEC_ERROR_INT);
++ u32 val = 0;
++ int i;
++
++ for (i = 0; i < ARRAY_SIZE(sec_error_to_event); i++)
++ val |= reg_to_event(reg, sec_error_to_event[i]);
++
++ return val;
++}
++
++static u32 ded_errors(struct mc_pcie *port)
++{
++ void __iomem *ctrl_base_addr = port->axi_base_addr + MC_PCIE_CTRL_ADDR;
++ u32 reg = readl_relaxed(ctrl_base_addr + DED_ERROR_INT);
++ u32 val = 0;
++ int i;
++
++ for (i = 0; i < ARRAY_SIZE(ded_error_to_event); i++)
++ val |= reg_to_event(reg, ded_error_to_event[i]);
++
++ return val;
++}
++
++static u32 local_events(struct mc_pcie *port)
++{
++ void __iomem *bridge_base_addr = port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
++ u32 reg = readl_relaxed(bridge_base_addr + ISTATUS_LOCAL);
++ u32 val = 0;
++ int i;
++
++ for (i = 0; i < ARRAY_SIZE(local_status_to_event); i++)
++ val |= reg_to_event(reg, local_status_to_event[i]);
++
++ return val;
++}
++
++static u32 get_events(struct mc_pcie *port)
++{
++ u32 events = 0;
++
++ events |= pcie_events(port);
++ events |= sec_errors(port);
++ events |= ded_errors(port);
++ events |= local_events(port);
++
++ return events;
++}
++
++static irqreturn_t mc_event_handler(int irq, void *dev_id)
++{
++ struct mc_pcie *port = dev_id;
++ struct device *dev = port->dev;
++ struct irq_data *data;
++
++ data = irq_domain_get_irq_data(port->event_domain, irq);
++
++ if (event_cause[data->hwirq].str)
++ dev_err_ratelimited(dev, "%s\n", event_cause[data->hwirq].str);
++ else
++ dev_err_ratelimited(dev, "bad event IRQ %ld\n", data->hwirq);
++
++ return IRQ_HANDLED;
++}
++
++static void mc_handle_event(struct irq_desc *desc)
++{
++ struct mc_pcie *port = irq_desc_get_handler_data(desc);
++ unsigned long events;
++ u32 bit;
++ struct irq_chip *chip = irq_desc_get_chip(desc);
++
++ chained_irq_enter(chip, desc);
++
++ events = get_events(port);
++
++ for_each_set_bit(bit, &events, NUM_EVENTS)
++ generic_handle_domain_irq(port->event_domain, bit);
++
++ chained_irq_exit(chip, desc);
++}
++
++static void mc_ack_event_irq(struct irq_data *data)
++{
++ struct mc_pcie *port = irq_data_get_irq_chip_data(data);
++ u32 event = data->hwirq;
++ void __iomem *addr;
++ u32 mask;
++
++ addr = port->axi_base_addr + event_descs[event].base +
++ event_descs[event].offset;
++ mask = event_descs[event].mask;
++ mask |= event_descs[event].enb_mask;
++
++ writel_relaxed(mask, addr);
++}
++
++static void mc_mask_event_irq(struct irq_data *data)
++{
++ struct mc_pcie *port = irq_data_get_irq_chip_data(data);
++ u32 event = data->hwirq;
++ void __iomem *addr;
++ u32 mask;
++ u32 val;
++
++ addr = port->axi_base_addr + event_descs[event].base +
++ event_descs[event].mask_offset;
++ mask = event_descs[event].mask;
++ if (event_descs[event].enb_mask) {
++ mask <<= PCIE_EVENT_INT_ENB_SHIFT;
++ mask &= PCIE_EVENT_INT_ENB_MASK;
++ }
++
++ if (!event_descs[event].mask_high)
++ mask = ~mask;
++
++ raw_spin_lock(&port->lock);
++ val = readl_relaxed(addr);
++ if (event_descs[event].mask_high)
++ val |= mask;
++ else
++ val &= mask;
++
++ writel_relaxed(val, addr);
++ raw_spin_unlock(&port->lock);
++}
++
++static void mc_unmask_event_irq(struct irq_data *data)
++{
++ struct mc_pcie *port = irq_data_get_irq_chip_data(data);
++ u32 event = data->hwirq;
++ void __iomem *addr;
++ u32 mask;
++ u32 val;
++
++ addr = port->axi_base_addr + event_descs[event].base +
++ event_descs[event].mask_offset;
++ mask = event_descs[event].mask;
++
++ if (event_descs[event].enb_mask)
++ mask <<= PCIE_EVENT_INT_ENB_SHIFT;
++
++ if (event_descs[event].mask_high)
++ mask = ~mask;
++
++ if (event_descs[event].enb_mask)
++ mask &= PCIE_EVENT_INT_ENB_MASK;
++
++ raw_spin_lock(&port->lock);
++ val = readl_relaxed(addr);
++ if (event_descs[event].mask_high)
++ val &= mask;
++ else
++ val |= mask;
++ writel_relaxed(val, addr);
++ raw_spin_unlock(&port->lock);
++}
++
++static struct irq_chip mc_event_irq_chip = {
++ .name = "Microchip PCIe EVENT",
++ .irq_ack = mc_ack_event_irq,
++ .irq_mask = mc_mask_event_irq,
++ .irq_unmask = mc_unmask_event_irq,
++};
++
++static int mc_pcie_event_map(struct irq_domain *domain, unsigned int irq,
++ irq_hw_number_t hwirq)
++{
++ irq_set_chip_and_handler(irq, &mc_event_irq_chip, handle_level_irq);
++ irq_set_chip_data(irq, domain->host_data);
++
++ return 0;
++}
++
++static const struct irq_domain_ops event_domain_ops = {
++ .map = mc_pcie_event_map,
++};
++
++static inline void mc_pcie_deinit_clk(void *data)
++{
++ struct clk *clk = data;
++
++ clk_disable_unprepare(clk);
++}
++
++static inline struct clk *mc_pcie_init_clk(struct device *dev, const char *id)
++{
++ struct clk *clk;
++ int ret;
++
++ clk = devm_clk_get_optional(dev, id);
++ if (IS_ERR(clk))
++ return clk;
++ if (!clk)
++ return clk;
++
++ ret = clk_prepare_enable(clk);
++ if (ret)
++ return ERR_PTR(ret);
++
++ devm_add_action_or_reset(dev, mc_pcie_deinit_clk, clk);
++
++ return clk;
++}
++
++static int mc_pcie_init_clks(struct device *dev)
++{
++ int i;
++ struct clk *fic;
++
++ /*
++ * PCIe may be clocked via Fabric Interface using between 1 and 4
++ * clocks. Scan DT for clocks and enable them if present
++ */
++ for (i = 0; i < ARRAY_SIZE(poss_clks); i++) {
++ fic = mc_pcie_init_clk(dev, poss_clks[i]);
++ if (IS_ERR(fic))
++ return PTR_ERR(fic);
++ }
++
++ return 0;
++}
++
++static int mc_pcie_init_irq_domains(struct mc_pcie *port)
++{
++ struct device *dev = port->dev;
++ struct device_node *node = dev->of_node;
++ struct device_node *pcie_intc_node;
++
++ /* Setup INTx */
++ pcie_intc_node = of_get_next_child(node, NULL);
++ if (!pcie_intc_node) {
++ dev_err(dev, "failed to find PCIe Intc node\n");
++ return -EINVAL;
++ }
++
++ port->event_domain = irq_domain_add_linear(pcie_intc_node, NUM_EVENTS,
++ &event_domain_ops, port);
++ if (!port->event_domain) {
++ dev_err(dev, "failed to get event domain\n");
++ of_node_put(pcie_intc_node);
++ return -ENOMEM;
++ }
++
++ irq_domain_update_bus_token(port->event_domain, DOMAIN_BUS_NEXUS);
++
++ port->intx_domain = irq_domain_add_linear(pcie_intc_node, PCI_NUM_INTX,
++ &intx_domain_ops, port);
++ if (!port->intx_domain) {
++ dev_err(dev, "failed to get an INTx IRQ domain\n");
++ of_node_put(pcie_intc_node);
++ return -ENOMEM;
++ }
++
++ irq_domain_update_bus_token(port->intx_domain, DOMAIN_BUS_WIRED);
++
++ of_node_put(pcie_intc_node);
++ raw_spin_lock_init(&port->lock);
++
++ return mc_allocate_msi_domains(port);
++}
++
++static void mc_pcie_setup_window(void __iomem *bridge_base_addr, u32 index,
++ phys_addr_t axi_addr, phys_addr_t pci_addr,
++ size_t size)
++{
++ u32 atr_sz = ilog2(size) - 1;
++ u32 val;
++
++ if (index == 0)
++ val = PCIE_CONFIG_INTERFACE;
++ else
++ val = PCIE_TX_RX_INTERFACE;
++
++ writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +
++ ATR0_AXI4_SLV0_TRSL_PARAM);
++
++ val = lower_32_bits(axi_addr) | (atr_sz << ATR_SIZE_SHIFT) |
++ ATR_IMPL_ENABLE;
++ writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +
++ ATR0_AXI4_SLV0_SRCADDR_PARAM);
++
++ val = upper_32_bits(axi_addr);
++ writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +
++ ATR0_AXI4_SLV0_SRC_ADDR);
++
++ val = lower_32_bits(pci_addr);
++ writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +
++ ATR0_AXI4_SLV0_TRSL_ADDR_LSB);
++
++ val = upper_32_bits(pci_addr);
++ writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +
++ ATR0_AXI4_SLV0_TRSL_ADDR_UDW);
++
++ val = readl(bridge_base_addr + ATR0_PCIE_WIN0_SRCADDR_PARAM);
++ val |= (ATR0_PCIE_ATR_SIZE << ATR0_PCIE_ATR_SIZE_SHIFT);
++ writel(val, bridge_base_addr + ATR0_PCIE_WIN0_SRCADDR_PARAM);
++ writel(0, bridge_base_addr + ATR0_PCIE_WIN0_SRC_ADDR);
++}
++
++static int mc_pcie_setup_windows(struct platform_device *pdev,
++ struct mc_pcie *port)
++{
++ void __iomem *bridge_base_addr =
++ port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
++ struct pci_host_bridge *bridge = platform_get_drvdata(pdev);
++ struct resource_entry *entry;
++ u64 pci_addr;
++ u32 index = 1;
++
++ resource_list_for_each_entry(entry, &bridge->windows) {
++ if (resource_type(entry->res) == IORESOURCE_MEM) {
++ pci_addr = entry->res->start - entry->offset;
++ mc_pcie_setup_window(bridge_base_addr, index,
++ entry->res->start, pci_addr,
++ resource_size(entry->res));
++ index++;
++ }
++ }
++
++ return 0;
++}
++
++static inline void mc_clear_secs(struct mc_pcie *port)
++{
++ void __iomem *ctrl_base_addr = port->axi_base_addr + MC_PCIE_CTRL_ADDR;
++
++ writel_relaxed(SEC_ERROR_INT_ALL_RAM_SEC_ERR_INT, ctrl_base_addr +
++ SEC_ERROR_INT);
++ writel_relaxed(0, ctrl_base_addr + SEC_ERROR_EVENT_CNT);
++}
++
++static inline void mc_clear_deds(struct mc_pcie *port)
++{
++ void __iomem *ctrl_base_addr = port->axi_base_addr + MC_PCIE_CTRL_ADDR;
++
++ writel_relaxed(DED_ERROR_INT_ALL_RAM_DED_ERR_INT, ctrl_base_addr +
++ DED_ERROR_INT);
++ writel_relaxed(0, ctrl_base_addr + DED_ERROR_EVENT_CNT);
++}
++
++static void mc_disable_interrupts(struct mc_pcie *port)
++{
++ void __iomem *bridge_base_addr = port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
++ void __iomem *ctrl_base_addr = port->axi_base_addr + MC_PCIE_CTRL_ADDR;
++ u32 val;
++
++ /* Ensure ECC bypass is enabled */
++ val = ECC_CONTROL_TX_RAM_ECC_BYPASS |
++ ECC_CONTROL_RX_RAM_ECC_BYPASS |
++ ECC_CONTROL_PCIE2AXI_RAM_ECC_BYPASS |
++ ECC_CONTROL_AXI2PCIE_RAM_ECC_BYPASS;
++ writel_relaxed(val, ctrl_base_addr + ECC_CONTROL);
++
++ /* Disable SEC errors and clear any outstanding */
++ writel_relaxed(SEC_ERROR_INT_ALL_RAM_SEC_ERR_INT, ctrl_base_addr +
++ SEC_ERROR_INT_MASK);
++ mc_clear_secs(port);
++
++ /* Disable DED errors and clear any outstanding */
++ writel_relaxed(DED_ERROR_INT_ALL_RAM_DED_ERR_INT, ctrl_base_addr +
++ DED_ERROR_INT_MASK);
++ mc_clear_deds(port);
++
++ /* Disable local interrupts and clear any outstanding */
++ writel_relaxed(0, bridge_base_addr + IMASK_LOCAL);
++ writel_relaxed(GENMASK(31, 0), bridge_base_addr + ISTATUS_LOCAL);
++ writel_relaxed(GENMASK(31, 0), bridge_base_addr + ISTATUS_MSI);
++
++ /* Disable PCIe events and clear any outstanding */
++ val = PCIE_EVENT_INT_L2_EXIT_INT |
++ PCIE_EVENT_INT_HOTRST_EXIT_INT |
++ PCIE_EVENT_INT_DLUP_EXIT_INT |
++ PCIE_EVENT_INT_L2_EXIT_INT_MASK |
++ PCIE_EVENT_INT_HOTRST_EXIT_INT_MASK |
++ PCIE_EVENT_INT_DLUP_EXIT_INT_MASK;
++ writel_relaxed(val, ctrl_base_addr + PCIE_EVENT_INT);
++
++ /* Disable host interrupts and clear any outstanding */
++ writel_relaxed(0, bridge_base_addr + IMASK_HOST);
++ writel_relaxed(GENMASK(31, 0), bridge_base_addr + ISTATUS_HOST);
++}
++
++static int mc_init_interrupts(struct platform_device *pdev, struct mc_pcie *port)
++{
++ struct device *dev = &pdev->dev;
++ int irq;
++ int i, intx_irq, msi_irq, event_irq;
++ int ret;
++
++ ret = mc_pcie_init_irq_domains(port);
++ if (ret) {
++ dev_err(dev, "failed creating IRQ domains\n");
++ return ret;
++ }
++
++ irq = platform_get_irq(pdev, 0);
++ if (irq < 0)
++ return -ENODEV;
++
++ for (i = 0; i < NUM_EVENTS; i++) {
++ event_irq = irq_create_mapping(port->event_domain, i);
++ if (!event_irq) {
++ dev_err(dev, "failed to map hwirq %d\n", i);
++ return -ENXIO;
++ }
++
++ ret = devm_request_irq(dev, event_irq, mc_event_handler,
++ 0, event_cause[i].sym, port);
++ if (ret) {
++ dev_err(dev, "failed to request IRQ %d\n", event_irq);
++ return ret;
++ }
++ }
++
++ intx_irq = irq_create_mapping(port->event_domain,
++ EVENT_LOCAL_PM_MSI_INT_INTX);
++ if (!intx_irq) {
++ dev_err(dev, "failed to map INTx interrupt\n");
++ return -ENXIO;
++ }
++
++ /* Plug the INTx chained handler */
++ irq_set_chained_handler_and_data(intx_irq, mc_handle_intx, port);
++
++ msi_irq = irq_create_mapping(port->event_domain,
++ EVENT_LOCAL_PM_MSI_INT_MSI);
++ if (!msi_irq)
++ return -ENXIO;
++
++ /* Plug the MSI chained handler */
++ irq_set_chained_handler_and_data(msi_irq, mc_handle_msi, port);
++
++ /* Plug the main event chained handler */
++ irq_set_chained_handler_and_data(irq, mc_handle_event, port);
++
++ return 0;
++}
++
++static int mc_platform_init(struct pci_config_window *cfg)
++{
++ struct device *dev = cfg->parent;
++ struct platform_device *pdev = to_platform_device(dev);
++ void __iomem *bridge_base_addr =
++ port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
++ int ret;
++
++ /* Configure address translation table 0 for PCIe config space */
++ mc_pcie_setup_window(bridge_base_addr, 0, cfg->res.start,
++ cfg->res.start,
++ resource_size(&cfg->res));
++
++ /* Need some fixups in config space */
++ mc_pcie_enable_msi(port, cfg->win);
++
++ /* Configure non-config space outbound ranges */
++ ret = mc_pcie_setup_windows(pdev, port);
++ if (ret)
++ return ret;
++
++ /* Address translation is up; safe to enable interrupts */
++ ret = mc_init_interrupts(pdev, port);
++ if (ret)
++ return ret;
++
++ return 0;
++}
++
++static int mc_host_probe(struct platform_device *pdev)
++{
++ struct device *dev = &pdev->dev;
++ void __iomem *bridge_base_addr;
++ int ret;
++ u32 val;
++
++ port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL);
++ if (!port)
++ return -ENOMEM;
++
++ port->dev = dev;
++
++ port->axi_base_addr = devm_platform_ioremap_resource(pdev, 1);
++ if (IS_ERR(port->axi_base_addr))
++ return PTR_ERR(port->axi_base_addr);
++
++ mc_disable_interrupts(port);
++
++ bridge_base_addr = port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
++
++ /* Allow enabling MSI by disabling MSI-X */
++ val = readl(bridge_base_addr + PCIE_PCI_IRQ_DW0);
++ val &= ~MSIX_CAP_MASK;
++ writel(val, bridge_base_addr + PCIE_PCI_IRQ_DW0);
++
++ /* Pick num vectors from bitfile programmed onto FPGA fabric */
++ val = readl(bridge_base_addr + PCIE_PCI_IRQ_DW0);
++ val &= NUM_MSI_MSGS_MASK;
++ val >>= NUM_MSI_MSGS_SHIFT;
++
++ port->msi.num_vectors = 1 << val;
++
++ /* Pick vector address from design */
++ port->msi.vector_phy = readl_relaxed(bridge_base_addr + IMSI_ADDR);
++
++ ret = mc_pcie_init_clks(dev);
++ if (ret) {
++ dev_err(dev, "failed to get clock resources, error %d\n", ret);
++ return -ENODEV;
++ }
++
++ return pci_host_common_probe(pdev);
++}
++
++static const struct pci_ecam_ops mc_ecam_ops = {
++ .init = mc_platform_init,
++ .pci_ops = {
++ .map_bus = pci_ecam_map_bus,
++ .read = pci_generic_config_read,
++ .write = pci_generic_config_write,
++ }
++};
++
++static const struct of_device_id mc_pcie_of_match[] = {
++ {
++ .compatible = "microchip,pcie-host-1.0",
++ .data = &mc_ecam_ops,
++ },
++ {},
++};
++
++MODULE_DEVICE_TABLE(of, mc_pcie_of_match);
++
++static struct platform_driver mc_pcie_driver = {
++ .probe = mc_host_probe,
++ .driver = {
++ .name = "microchip-pcie",
++ .of_match_table = mc_pcie_of_match,
++ .suppress_bind_attrs = true,
++ },
++};
++
++builtin_platform_driver(mc_pcie_driver);
++MODULE_LICENSE("GPL");
++MODULE_DESCRIPTION("Microchip PCIe host controller driver");
++MODULE_AUTHOR("Daire McNamara <daire.mcnamara@microchip.com>");
diff --git a/target/linux/starfive/patches-6.6/0016-PCI-microchip-Move-PLDA-IP-register-macros-to-pcie-p.patch b/target/linux/starfive/patches-6.6/0016-PCI-microchip-Move-PLDA-IP-register-macros-to-pcie-p.patch
new file mode 100644
index 0000000000..0aacec2769
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0016-PCI-microchip-Move-PLDA-IP-register-macros-to-pcie-p.patch
@@ -0,0 +1,259 @@
+From eca1b864bb2d4e8d9811506979560a89351c2e37 Mon Sep 17 00:00:00 2001
+From: Minda Chen <minda.chen@starfivetech.com>
+Date: Mon, 8 Jan 2024 19:05:53 +0800
+Subject: [PATCH 016/116] PCI: microchip: Move PLDA IP register macros to
+ pcie-plda.h
+
+Move PLDA PCIe host controller IP registers macros to pcie-plda.h,
+including bridge registers and local IRQ event number.
+
+Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+---
+ .../pci/controller/plda/pcie-microchip-host.c | 108 +++---------------
+ drivers/pci/controller/plda/pcie-plda.h | 108 ++++++++++++++++++
+ 2 files changed, 124 insertions(+), 92 deletions(-)
+ create mode 100644 drivers/pci/controller/plda/pcie-plda.h
+
+--- a/drivers/pci/controller/plda/pcie-microchip-host.c
++++ b/drivers/pci/controller/plda/pcie-microchip-host.c
+@@ -19,6 +19,7 @@
+ #include <linux/platform_device.h>
+
+ #include "../../pci.h"
++#include "pcie-plda.h"
+
+ /* Number of MSI IRQs */
+ #define MC_MAX_NUM_MSI_IRQS 32
+@@ -30,84 +31,6 @@
+ #define MC_PCIE_BRIDGE_ADDR (MC_PCIE1_BRIDGE_ADDR)
+ #define MC_PCIE_CTRL_ADDR (MC_PCIE1_CTRL_ADDR)
+
+-/* PCIe Bridge Phy Regs */
+-#define PCIE_PCI_IRQ_DW0 0xa8
+-#define MSIX_CAP_MASK BIT(31)
+-#define NUM_MSI_MSGS_MASK GENMASK(6, 4)
+-#define NUM_MSI_MSGS_SHIFT 4
+-
+-#define IMASK_LOCAL 0x180
+-#define DMA_END_ENGINE_0_MASK 0x00000000u
+-#define DMA_END_ENGINE_0_SHIFT 0
+-#define DMA_END_ENGINE_1_MASK 0x00000000u
+-#define DMA_END_ENGINE_1_SHIFT 1
+-#define DMA_ERROR_ENGINE_0_MASK 0x00000100u
+-#define DMA_ERROR_ENGINE_0_SHIFT 8
+-#define DMA_ERROR_ENGINE_1_MASK 0x00000200u
+-#define DMA_ERROR_ENGINE_1_SHIFT 9
+-#define A_ATR_EVT_POST_ERR_MASK 0x00010000u
+-#define A_ATR_EVT_POST_ERR_SHIFT 16
+-#define A_ATR_EVT_FETCH_ERR_MASK 0x00020000u
+-#define A_ATR_EVT_FETCH_ERR_SHIFT 17
+-#define A_ATR_EVT_DISCARD_ERR_MASK 0x00040000u
+-#define A_ATR_EVT_DISCARD_ERR_SHIFT 18
+-#define A_ATR_EVT_DOORBELL_MASK 0x00000000u
+-#define A_ATR_EVT_DOORBELL_SHIFT 19
+-#define P_ATR_EVT_POST_ERR_MASK 0x00100000u
+-#define P_ATR_EVT_POST_ERR_SHIFT 20
+-#define P_ATR_EVT_FETCH_ERR_MASK 0x00200000u
+-#define P_ATR_EVT_FETCH_ERR_SHIFT 21
+-#define P_ATR_EVT_DISCARD_ERR_MASK 0x00400000u
+-#define P_ATR_EVT_DISCARD_ERR_SHIFT 22
+-#define P_ATR_EVT_DOORBELL_MASK 0x00000000u
+-#define P_ATR_EVT_DOORBELL_SHIFT 23
+-#define PM_MSI_INT_INTA_MASK 0x01000000u
+-#define PM_MSI_INT_INTA_SHIFT 24
+-#define PM_MSI_INT_INTB_MASK 0x02000000u
+-#define PM_MSI_INT_INTB_SHIFT 25
+-#define PM_MSI_INT_INTC_MASK 0x04000000u
+-#define PM_MSI_INT_INTC_SHIFT 26
+-#define PM_MSI_INT_INTD_MASK 0x08000000u
+-#define PM_MSI_INT_INTD_SHIFT 27
+-#define PM_MSI_INT_INTX_MASK 0x0f000000u
+-#define PM_MSI_INT_INTX_SHIFT 24
+-#define PM_MSI_INT_MSI_MASK 0x10000000u
+-#define PM_MSI_INT_MSI_SHIFT 28
+-#define PM_MSI_INT_AER_EVT_MASK 0x20000000u
+-#define PM_MSI_INT_AER_EVT_SHIFT 29
+-#define PM_MSI_INT_EVENTS_MASK 0x40000000u
+-#define PM_MSI_INT_EVENTS_SHIFT 30
+-#define PM_MSI_INT_SYS_ERR_MASK 0x80000000u
+-#define PM_MSI_INT_SYS_ERR_SHIFT 31
+-#define NUM_LOCAL_EVENTS 15
+-#define ISTATUS_LOCAL 0x184
+-#define IMASK_HOST 0x188
+-#define ISTATUS_HOST 0x18c
+-#define IMSI_ADDR 0x190
+-#define ISTATUS_MSI 0x194
+-
+-/* PCIe Master table init defines */
+-#define ATR0_PCIE_WIN0_SRCADDR_PARAM 0x600u
+-#define ATR0_PCIE_ATR_SIZE 0x25
+-#define ATR0_PCIE_ATR_SIZE_SHIFT 1
+-#define ATR0_PCIE_WIN0_SRC_ADDR 0x604u
+-#define ATR0_PCIE_WIN0_TRSL_ADDR_LSB 0x608u
+-#define ATR0_PCIE_WIN0_TRSL_ADDR_UDW 0x60cu
+-#define ATR0_PCIE_WIN0_TRSL_PARAM 0x610u
+-
+-/* PCIe AXI slave table init defines */
+-#define ATR0_AXI4_SLV0_SRCADDR_PARAM 0x800u
+-#define ATR_SIZE_SHIFT 1
+-#define ATR_IMPL_ENABLE 1
+-#define ATR0_AXI4_SLV0_SRC_ADDR 0x804u
+-#define ATR0_AXI4_SLV0_TRSL_ADDR_LSB 0x808u
+-#define ATR0_AXI4_SLV0_TRSL_ADDR_UDW 0x80cu
+-#define ATR0_AXI4_SLV0_TRSL_PARAM 0x810u
+-#define PCIE_TX_RX_INTERFACE 0x00000000u
+-#define PCIE_CONFIG_INTERFACE 0x00000001u
+-
+-#define ATR_ENTRY_SIZE 32
+-
+ /* PCIe Controller Phy Regs */
+ #define SEC_ERROR_EVENT_CNT 0x20
+ #define DED_ERROR_EVENT_CNT 0x24
+@@ -179,20 +102,21 @@
+ #define EVENT_LOCAL_DMA_END_ENGINE_1 12
+ #define EVENT_LOCAL_DMA_ERROR_ENGINE_0 13
+ #define EVENT_LOCAL_DMA_ERROR_ENGINE_1 14
+-#define EVENT_LOCAL_A_ATR_EVT_POST_ERR 15
+-#define EVENT_LOCAL_A_ATR_EVT_FETCH_ERR 16
+-#define EVENT_LOCAL_A_ATR_EVT_DISCARD_ERR 17
+-#define EVENT_LOCAL_A_ATR_EVT_DOORBELL 18
+-#define EVENT_LOCAL_P_ATR_EVT_POST_ERR 19
+-#define EVENT_LOCAL_P_ATR_EVT_FETCH_ERR 20
+-#define EVENT_LOCAL_P_ATR_EVT_DISCARD_ERR 21
+-#define EVENT_LOCAL_P_ATR_EVT_DOORBELL 22
+-#define EVENT_LOCAL_PM_MSI_INT_INTX 23
+-#define EVENT_LOCAL_PM_MSI_INT_MSI 24
+-#define EVENT_LOCAL_PM_MSI_INT_AER_EVT 25
+-#define EVENT_LOCAL_PM_MSI_INT_EVENTS 26
+-#define EVENT_LOCAL_PM_MSI_INT_SYS_ERR 27
+-#define NUM_EVENTS 28
++#define NUM_MC_EVENTS 15
++#define EVENT_LOCAL_A_ATR_EVT_POST_ERR (NUM_MC_EVENTS + PLDA_AXI_POST_ERR)
++#define EVENT_LOCAL_A_ATR_EVT_FETCH_ERR (NUM_MC_EVENTS + PLDA_AXI_FETCH_ERR)
++#define EVENT_LOCAL_A_ATR_EVT_DISCARD_ERR (NUM_MC_EVENTS + PLDA_AXI_DISCARD_ERR)
++#define EVENT_LOCAL_A_ATR_EVT_DOORBELL (NUM_MC_EVENTS + PLDA_AXI_DOORBELL)
++#define EVENT_LOCAL_P_ATR_EVT_POST_ERR (NUM_MC_EVENTS + PLDA_PCIE_POST_ERR)
++#define EVENT_LOCAL_P_ATR_EVT_FETCH_ERR (NUM_MC_EVENTS + PLDA_PCIE_FETCH_ERR)
++#define EVENT_LOCAL_P_ATR_EVT_DISCARD_ERR (NUM_MC_EVENTS + PLDA_PCIE_DISCARD_ERR)
++#define EVENT_LOCAL_P_ATR_EVT_DOORBELL (NUM_MC_EVENTS + PLDA_PCIE_DOORBELL)
++#define EVENT_LOCAL_PM_MSI_INT_INTX (NUM_MC_EVENTS + PLDA_INTX)
++#define EVENT_LOCAL_PM_MSI_INT_MSI (NUM_MC_EVENTS + PLDA_MSI)
++#define EVENT_LOCAL_PM_MSI_INT_AER_EVT (NUM_MC_EVENTS + PLDA_AER_EVENT)
++#define EVENT_LOCAL_PM_MSI_INT_EVENTS (NUM_MC_EVENTS + PLDA_MISC_EVENTS)
++#define EVENT_LOCAL_PM_MSI_INT_SYS_ERR (NUM_MC_EVENTS + PLDA_SYS_ERR)
++#define NUM_EVENTS (NUM_MC_EVENTS + PLDA_INT_EVENT_NUM)
+
+ #define PCIE_EVENT_CAUSE(x, s) \
+ [EVENT_PCIE_ ## x] = { __stringify(x), s }
+--- /dev/null
++++ b/drivers/pci/controller/plda/pcie-plda.h
+@@ -0,0 +1,108 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++/*
++ * PLDA PCIe host controller driver
++ */
++
++#ifndef _PCIE_PLDA_H
++#define _PCIE_PLDA_H
++
++/* PCIe Bridge Phy Regs */
++#define PCIE_PCI_IRQ_DW0 0xa8
++#define MSIX_CAP_MASK BIT(31)
++#define NUM_MSI_MSGS_MASK GENMASK(6, 4)
++#define NUM_MSI_MSGS_SHIFT 4
++
++#define IMASK_LOCAL 0x180
++#define DMA_END_ENGINE_0_MASK 0x00000000u
++#define DMA_END_ENGINE_0_SHIFT 0
++#define DMA_END_ENGINE_1_MASK 0x00000000u
++#define DMA_END_ENGINE_1_SHIFT 1
++#define DMA_ERROR_ENGINE_0_MASK 0x00000100u
++#define DMA_ERROR_ENGINE_0_SHIFT 8
++#define DMA_ERROR_ENGINE_1_MASK 0x00000200u
++#define DMA_ERROR_ENGINE_1_SHIFT 9
++#define A_ATR_EVT_POST_ERR_MASK 0x00010000u
++#define A_ATR_EVT_POST_ERR_SHIFT 16
++#define A_ATR_EVT_FETCH_ERR_MASK 0x00020000u
++#define A_ATR_EVT_FETCH_ERR_SHIFT 17
++#define A_ATR_EVT_DISCARD_ERR_MASK 0x00040000u
++#define A_ATR_EVT_DISCARD_ERR_SHIFT 18
++#define A_ATR_EVT_DOORBELL_MASK 0x00000000u
++#define A_ATR_EVT_DOORBELL_SHIFT 19
++#define P_ATR_EVT_POST_ERR_MASK 0x00100000u
++#define P_ATR_EVT_POST_ERR_SHIFT 20
++#define P_ATR_EVT_FETCH_ERR_MASK 0x00200000u
++#define P_ATR_EVT_FETCH_ERR_SHIFT 21
++#define P_ATR_EVT_DISCARD_ERR_MASK 0x00400000u
++#define P_ATR_EVT_DISCARD_ERR_SHIFT 22
++#define P_ATR_EVT_DOORBELL_MASK 0x00000000u
++#define P_ATR_EVT_DOORBELL_SHIFT 23
++#define PM_MSI_INT_INTA_MASK 0x01000000u
++#define PM_MSI_INT_INTA_SHIFT 24
++#define PM_MSI_INT_INTB_MASK 0x02000000u
++#define PM_MSI_INT_INTB_SHIFT 25
++#define PM_MSI_INT_INTC_MASK 0x04000000u
++#define PM_MSI_INT_INTC_SHIFT 26
++#define PM_MSI_INT_INTD_MASK 0x08000000u
++#define PM_MSI_INT_INTD_SHIFT 27
++#define PM_MSI_INT_INTX_MASK 0x0f000000u
++#define PM_MSI_INT_INTX_SHIFT 24
++#define PM_MSI_INT_MSI_MASK 0x10000000u
++#define PM_MSI_INT_MSI_SHIFT 28
++#define PM_MSI_INT_AER_EVT_MASK 0x20000000u
++#define PM_MSI_INT_AER_EVT_SHIFT 29
++#define PM_MSI_INT_EVENTS_MASK 0x40000000u
++#define PM_MSI_INT_EVENTS_SHIFT 30
++#define PM_MSI_INT_SYS_ERR_MASK 0x80000000u
++#define PM_MSI_INT_SYS_ERR_SHIFT 31
++#define NUM_LOCAL_EVENTS 15
++#define ISTATUS_LOCAL 0x184
++#define IMASK_HOST 0x188
++#define ISTATUS_HOST 0x18c
++#define IMSI_ADDR 0x190
++#define ISTATUS_MSI 0x194
++
++/* PCIe Master table init defines */
++#define ATR0_PCIE_WIN0_SRCADDR_PARAM 0x600u
++#define ATR0_PCIE_ATR_SIZE 0x25
++#define ATR0_PCIE_ATR_SIZE_SHIFT 1
++#define ATR0_PCIE_WIN0_SRC_ADDR 0x604u
++#define ATR0_PCIE_WIN0_TRSL_ADDR_LSB 0x608u
++#define ATR0_PCIE_WIN0_TRSL_ADDR_UDW 0x60cu
++#define ATR0_PCIE_WIN0_TRSL_PARAM 0x610u
++
++/* PCIe AXI slave table init defines */
++#define ATR0_AXI4_SLV0_SRCADDR_PARAM 0x800u
++#define ATR_SIZE_SHIFT 1
++#define ATR_IMPL_ENABLE 1
++#define ATR0_AXI4_SLV0_SRC_ADDR 0x804u
++#define ATR0_AXI4_SLV0_TRSL_ADDR_LSB 0x808u
++#define ATR0_AXI4_SLV0_TRSL_ADDR_UDW 0x80cu
++#define ATR0_AXI4_SLV0_TRSL_PARAM 0x810u
++#define PCIE_TX_RX_INTERFACE 0x00000000u
++#define PCIE_CONFIG_INTERFACE 0x00000001u
++
++#define ATR_ENTRY_SIZE 32
++
++enum plda_int_event {
++ PLDA_AXI_POST_ERR,
++ PLDA_AXI_FETCH_ERR,
++ PLDA_AXI_DISCARD_ERR,
++ PLDA_AXI_DOORBELL,
++ PLDA_PCIE_POST_ERR,
++ PLDA_PCIE_FETCH_ERR,
++ PLDA_PCIE_DISCARD_ERR,
++ PLDA_PCIE_DOORBELL,
++ PLDA_INTX,
++ PLDA_MSI,
++ PLDA_AER_EVENT,
++ PLDA_MISC_EVENTS,
++ PLDA_SYS_ERR,
++ PLDA_INT_EVENT_NUM
++};
++
++#define PLDA_NUM_DMA_EVENTS 16
++
++#define PLDA_MAX_INT_NUM (PLDA_NUM_DMA_EVENTS + PLDA_INT_EVENT_NUM)
++
++#endif
diff --git a/target/linux/starfive/patches-6.6/0017-PCI-microchip-Add-bridge_addr-field-to-struct-mc_pci.patch b/target/linux/starfive/patches-6.6/0017-PCI-microchip-Add-bridge_addr-field-to-struct-mc_pci.patch
new file mode 100644
index 0000000000..bc3f909116
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0017-PCI-microchip-Add-bridge_addr-field-to-struct-mc_pci.patch
@@ -0,0 +1,107 @@
+From 6ee4d4568314425079ae88229bb9abbff9b92b8b Mon Sep 17 00:00:00 2001
+From: Minda Chen <minda.chen@starfivetech.com>
+Date: Mon, 8 Jan 2024 19:05:54 +0800
+Subject: [PATCH 017/116] PCI: microchip: Add bridge_addr field to struct
+ mc_pcie
+
+For bridge address base is common PLDA field, Add this to struct mc_pcie
+first.
+
+INTx and MSI codes interrupts codes will get the bridge base address from
+port->bridge_addr. These codes will be changed to common codes.
+axi_base_addr is Microchip its own data.
+
+Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+---
+ .../pci/controller/plda/pcie-microchip-host.c | 23 ++++++++-----------
+ 1 file changed, 9 insertions(+), 14 deletions(-)
+
+--- a/drivers/pci/controller/plda/pcie-microchip-host.c
++++ b/drivers/pci/controller/plda/pcie-microchip-host.c
+@@ -195,6 +195,7 @@ struct mc_pcie {
+ struct irq_domain *event_domain;
+ raw_spinlock_t lock;
+ struct mc_msi msi;
++ void __iomem *bridge_addr;
+ };
+
+ struct cause {
+@@ -339,8 +340,7 @@ static void mc_handle_msi(struct irq_des
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+ struct device *dev = port->dev;
+ struct mc_msi *msi = &port->msi;
+- void __iomem *bridge_base_addr =
+- port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
++ void __iomem *bridge_base_addr = port->bridge_addr;
+ unsigned long status;
+ u32 bit;
+ int ret;
+@@ -365,8 +365,7 @@ static void mc_handle_msi(struct irq_des
+ static void mc_msi_bottom_irq_ack(struct irq_data *data)
+ {
+ struct mc_pcie *port = irq_data_get_irq_chip_data(data);
+- void __iomem *bridge_base_addr =
+- port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
++ void __iomem *bridge_base_addr = port->bridge_addr;
+ u32 bitpos = data->hwirq;
+
+ writel_relaxed(BIT(bitpos), bridge_base_addr + ISTATUS_MSI);
+@@ -488,8 +487,7 @@ static void mc_handle_intx(struct irq_de
+ struct mc_pcie *port = irq_desc_get_handler_data(desc);
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+ struct device *dev = port->dev;
+- void __iomem *bridge_base_addr =
+- port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
++ void __iomem *bridge_base_addr = port->bridge_addr;
+ unsigned long status;
+ u32 bit;
+ int ret;
+@@ -514,8 +512,7 @@ static void mc_handle_intx(struct irq_de
+ static void mc_ack_intx_irq(struct irq_data *data)
+ {
+ struct mc_pcie *port = irq_data_get_irq_chip_data(data);
+- void __iomem *bridge_base_addr =
+- port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
++ void __iomem *bridge_base_addr = port->bridge_addr;
+ u32 mask = BIT(data->hwirq + PM_MSI_INT_INTX_SHIFT);
+
+ writel_relaxed(mask, bridge_base_addr + ISTATUS_LOCAL);
+@@ -524,8 +521,7 @@ static void mc_ack_intx_irq(struct irq_d
+ static void mc_mask_intx_irq(struct irq_data *data)
+ {
+ struct mc_pcie *port = irq_data_get_irq_chip_data(data);
+- void __iomem *bridge_base_addr =
+- port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
++ void __iomem *bridge_base_addr = port->bridge_addr;
+ unsigned long flags;
+ u32 mask = BIT(data->hwirq + PM_MSI_INT_INTX_SHIFT);
+ u32 val;
+@@ -540,8 +536,7 @@ static void mc_mask_intx_irq(struct irq_
+ static void mc_unmask_intx_irq(struct irq_data *data)
+ {
+ struct mc_pcie *port = irq_data_get_irq_chip_data(data);
+- void __iomem *bridge_base_addr =
+- port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
++ void __iomem *bridge_base_addr = port->bridge_addr;
+ unsigned long flags;
+ u32 mask = BIT(data->hwirq + PM_MSI_INT_INTX_SHIFT);
+ u32 val;
+@@ -896,8 +891,7 @@ static void mc_pcie_setup_window(void __
+ static int mc_pcie_setup_windows(struct platform_device *pdev,
+ struct mc_pcie *port)
+ {
+- void __iomem *bridge_base_addr =
+- port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
++ void __iomem *bridge_base_addr = port->bridge_addr;
+ struct pci_host_bridge *bridge = platform_get_drvdata(pdev);
+ struct resource_entry *entry;
+ u64 pci_addr;
+@@ -1081,6 +1075,7 @@ static int mc_host_probe(struct platform
+ mc_disable_interrupts(port);
+
+ bridge_base_addr = port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
++ port->bridge_addr = bridge_base_addr;
+
+ /* Allow enabling MSI by disabling MSI-X */
+ val = readl(bridge_base_addr + PCIE_PCI_IRQ_DW0);
diff --git a/target/linux/starfive/patches-6.6/0018-PCI-microchip-Rename-two-PCIe-data-structures.patch b/target/linux/starfive/patches-6.6/0018-PCI-microchip-Rename-two-PCIe-data-structures.patch
new file mode 100644
index 0000000000..a9e7b8975b
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0018-PCI-microchip-Rename-two-PCIe-data-structures.patch
@@ -0,0 +1,347 @@
+From 7c1c679bdd0b6b727248edbee77836024c935f91 Mon Sep 17 00:00:00 2001
+From: Minda Chen <minda.chen@starfivetech.com>
+Date: Mon, 8 Jan 2024 19:05:55 +0800
+Subject: [PATCH 018/116] PCI: microchip: Rename two PCIe data structures
+
+Add PLDA PCIe related data structures by rename data structure name from
+mc_* to plda_*.
+
+axi_base_addr is stayed in struct mc_pcie for it's microchip its own data.
+
+The event interrupt codes is still using struct mc_pcie because the event
+interrupt codes can not be re-used.
+
+Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+---
+ .../pci/controller/plda/pcie-microchip-host.c | 96 ++++++++++---------
+ 1 file changed, 53 insertions(+), 43 deletions(-)
+
+--- a/drivers/pci/controller/plda/pcie-microchip-host.c
++++ b/drivers/pci/controller/plda/pcie-microchip-host.c
+@@ -22,7 +22,7 @@
+ #include "pcie-plda.h"
+
+ /* Number of MSI IRQs */
+-#define MC_MAX_NUM_MSI_IRQS 32
++#define PLDA_MAX_NUM_MSI_IRQS 32
+
+ /* PCIe Bridge Phy and Controller Phy offsets */
+ #define MC_PCIE1_BRIDGE_ADDR 0x00008000u
+@@ -179,25 +179,29 @@ struct event_map {
+ u32 event_bit;
+ };
+
+-struct mc_msi {
++struct plda_msi {
+ struct mutex lock; /* Protect used bitmap */
+ struct irq_domain *msi_domain;
+ struct irq_domain *dev_domain;
+ u32 num_vectors;
+ u64 vector_phy;
+- DECLARE_BITMAP(used, MC_MAX_NUM_MSI_IRQS);
++ DECLARE_BITMAP(used, PLDA_MAX_NUM_MSI_IRQS);
+ };
+
+-struct mc_pcie {
+- void __iomem *axi_base_addr;
++struct plda_pcie_rp {
+ struct device *dev;
+ struct irq_domain *intx_domain;
+ struct irq_domain *event_domain;
+ raw_spinlock_t lock;
+- struct mc_msi msi;
++ struct plda_msi msi;
+ void __iomem *bridge_addr;
+ };
+
++struct mc_pcie {
++ struct plda_pcie_rp plda;
++ void __iomem *axi_base_addr;
++};
++
+ struct cause {
+ const char *sym;
+ const char *str;
+@@ -313,7 +317,7 @@ static struct mc_pcie *port;
+
+ static void mc_pcie_enable_msi(struct mc_pcie *port, void __iomem *ecam)
+ {
+- struct mc_msi *msi = &port->msi;
++ struct plda_msi *msi = &port->plda.msi;
+ u16 reg;
+ u8 queue_size;
+
+@@ -336,10 +340,10 @@ static void mc_pcie_enable_msi(struct mc
+
+ static void mc_handle_msi(struct irq_desc *desc)
+ {
+- struct mc_pcie *port = irq_desc_get_handler_data(desc);
++ struct plda_pcie_rp *port = irq_desc_get_handler_data(desc);
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+ struct device *dev = port->dev;
+- struct mc_msi *msi = &port->msi;
++ struct plda_msi *msi = &port->msi;
+ void __iomem *bridge_base_addr = port->bridge_addr;
+ unsigned long status;
+ u32 bit;
+@@ -364,7 +368,7 @@ static void mc_handle_msi(struct irq_des
+
+ static void mc_msi_bottom_irq_ack(struct irq_data *data)
+ {
+- struct mc_pcie *port = irq_data_get_irq_chip_data(data);
++ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
+ void __iomem *bridge_base_addr = port->bridge_addr;
+ u32 bitpos = data->hwirq;
+
+@@ -373,7 +377,7 @@ static void mc_msi_bottom_irq_ack(struct
+
+ static void mc_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
+ {
+- struct mc_pcie *port = irq_data_get_irq_chip_data(data);
++ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
+ phys_addr_t addr = port->msi.vector_phy;
+
+ msg->address_lo = lower_32_bits(addr);
+@@ -400,8 +404,8 @@ static struct irq_chip mc_msi_bottom_irq
+ static int mc_irq_msi_domain_alloc(struct irq_domain *domain, unsigned int virq,
+ unsigned int nr_irqs, void *args)
+ {
+- struct mc_pcie *port = domain->host_data;
+- struct mc_msi *msi = &port->msi;
++ struct plda_pcie_rp *port = domain->host_data;
++ struct plda_msi *msi = &port->msi;
+ unsigned long bit;
+
+ mutex_lock(&msi->lock);
+@@ -425,8 +429,8 @@ static void mc_irq_msi_domain_free(struc
+ unsigned int nr_irqs)
+ {
+ struct irq_data *d = irq_domain_get_irq_data(domain, virq);
+- struct mc_pcie *port = irq_data_get_irq_chip_data(d);
+- struct mc_msi *msi = &port->msi;
++ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(d);
++ struct plda_msi *msi = &port->msi;
+
+ mutex_lock(&msi->lock);
+
+@@ -456,11 +460,11 @@ static struct msi_domain_info mc_msi_dom
+ .chip = &mc_msi_irq_chip,
+ };
+
+-static int mc_allocate_msi_domains(struct mc_pcie *port)
++static int mc_allocate_msi_domains(struct plda_pcie_rp *port)
+ {
+ struct device *dev = port->dev;
+ struct fwnode_handle *fwnode = of_node_to_fwnode(dev->of_node);
+- struct mc_msi *msi = &port->msi;
++ struct plda_msi *msi = &port->msi;
+
+ mutex_init(&port->msi.lock);
+
+@@ -484,7 +488,7 @@ static int mc_allocate_msi_domains(struc
+
+ static void mc_handle_intx(struct irq_desc *desc)
+ {
+- struct mc_pcie *port = irq_desc_get_handler_data(desc);
++ struct plda_pcie_rp *port = irq_desc_get_handler_data(desc);
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+ struct device *dev = port->dev;
+ void __iomem *bridge_base_addr = port->bridge_addr;
+@@ -511,7 +515,7 @@ static void mc_handle_intx(struct irq_de
+
+ static void mc_ack_intx_irq(struct irq_data *data)
+ {
+- struct mc_pcie *port = irq_data_get_irq_chip_data(data);
++ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
+ void __iomem *bridge_base_addr = port->bridge_addr;
+ u32 mask = BIT(data->hwirq + PM_MSI_INT_INTX_SHIFT);
+
+@@ -520,7 +524,7 @@ static void mc_ack_intx_irq(struct irq_d
+
+ static void mc_mask_intx_irq(struct irq_data *data)
+ {
+- struct mc_pcie *port = irq_data_get_irq_chip_data(data);
++ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
+ void __iomem *bridge_base_addr = port->bridge_addr;
+ unsigned long flags;
+ u32 mask = BIT(data->hwirq + PM_MSI_INT_INTX_SHIFT);
+@@ -535,7 +539,7 @@ static void mc_mask_intx_irq(struct irq_
+
+ static void mc_unmask_intx_irq(struct irq_data *data)
+ {
+- struct mc_pcie *port = irq_data_get_irq_chip_data(data);
++ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
+ void __iomem *bridge_base_addr = port->bridge_addr;
+ unsigned long flags;
+ u32 mask = BIT(data->hwirq + PM_MSI_INT_INTX_SHIFT);
+@@ -625,21 +629,22 @@ static u32 local_events(struct mc_pcie *
+ return val;
+ }
+
+-static u32 get_events(struct mc_pcie *port)
++static u32 get_events(struct plda_pcie_rp *port)
+ {
++ struct mc_pcie *mc_port = container_of(port, struct mc_pcie, plda);
+ u32 events = 0;
+
+- events |= pcie_events(port);
+- events |= sec_errors(port);
+- events |= ded_errors(port);
+- events |= local_events(port);
++ events |= pcie_events(mc_port);
++ events |= sec_errors(mc_port);
++ events |= ded_errors(mc_port);
++ events |= local_events(mc_port);
+
+ return events;
+ }
+
+ static irqreturn_t mc_event_handler(int irq, void *dev_id)
+ {
+- struct mc_pcie *port = dev_id;
++ struct plda_pcie_rp *port = dev_id;
+ struct device *dev = port->dev;
+ struct irq_data *data;
+
+@@ -655,7 +660,7 @@ static irqreturn_t mc_event_handler(int
+
+ static void mc_handle_event(struct irq_desc *desc)
+ {
+- struct mc_pcie *port = irq_desc_get_handler_data(desc);
++ struct plda_pcie_rp *port = irq_desc_get_handler_data(desc);
+ unsigned long events;
+ u32 bit;
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+@@ -672,12 +677,13 @@ static void mc_handle_event(struct irq_d
+
+ static void mc_ack_event_irq(struct irq_data *data)
+ {
+- struct mc_pcie *port = irq_data_get_irq_chip_data(data);
++ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
++ struct mc_pcie *mc_port = container_of(port, struct mc_pcie, plda);
+ u32 event = data->hwirq;
+ void __iomem *addr;
+ u32 mask;
+
+- addr = port->axi_base_addr + event_descs[event].base +
++ addr = mc_port->axi_base_addr + event_descs[event].base +
+ event_descs[event].offset;
+ mask = event_descs[event].mask;
+ mask |= event_descs[event].enb_mask;
+@@ -687,13 +693,14 @@ static void mc_ack_event_irq(struct irq_
+
+ static void mc_mask_event_irq(struct irq_data *data)
+ {
+- struct mc_pcie *port = irq_data_get_irq_chip_data(data);
++ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
++ struct mc_pcie *mc_port = container_of(port, struct mc_pcie, plda);
+ u32 event = data->hwirq;
+ void __iomem *addr;
+ u32 mask;
+ u32 val;
+
+- addr = port->axi_base_addr + event_descs[event].base +
++ addr = mc_port->axi_base_addr + event_descs[event].base +
+ event_descs[event].mask_offset;
+ mask = event_descs[event].mask;
+ if (event_descs[event].enb_mask) {
+@@ -717,13 +724,14 @@ static void mc_mask_event_irq(struct irq
+
+ static void mc_unmask_event_irq(struct irq_data *data)
+ {
+- struct mc_pcie *port = irq_data_get_irq_chip_data(data);
++ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
++ struct mc_pcie *mc_port = container_of(port, struct mc_pcie, plda);
+ u32 event = data->hwirq;
+ void __iomem *addr;
+ u32 mask;
+ u32 val;
+
+- addr = port->axi_base_addr + event_descs[event].base +
++ addr = mc_port->axi_base_addr + event_descs[event].base +
+ event_descs[event].mask_offset;
+ mask = event_descs[event].mask;
+
+@@ -811,7 +819,7 @@ static int mc_pcie_init_clks(struct devi
+ return 0;
+ }
+
+-static int mc_pcie_init_irq_domains(struct mc_pcie *port)
++static int mc_pcie_init_irq_domains(struct plda_pcie_rp *port)
+ {
+ struct device *dev = port->dev;
+ struct device_node *node = dev->of_node;
+@@ -889,7 +897,7 @@ static void mc_pcie_setup_window(void __
+ }
+
+ static int mc_pcie_setup_windows(struct platform_device *pdev,
+- struct mc_pcie *port)
++ struct plda_pcie_rp *port)
+ {
+ void __iomem *bridge_base_addr = port->bridge_addr;
+ struct pci_host_bridge *bridge = platform_get_drvdata(pdev);
+@@ -970,7 +978,7 @@ static void mc_disable_interrupts(struct
+ writel_relaxed(GENMASK(31, 0), bridge_base_addr + ISTATUS_HOST);
+ }
+
+-static int mc_init_interrupts(struct platform_device *pdev, struct mc_pcie *port)
++static int mc_init_interrupts(struct platform_device *pdev, struct plda_pcie_rp *port)
+ {
+ struct device *dev = &pdev->dev;
+ int irq;
+@@ -1043,12 +1051,12 @@ static int mc_platform_init(struct pci_c
+ mc_pcie_enable_msi(port, cfg->win);
+
+ /* Configure non-config space outbound ranges */
+- ret = mc_pcie_setup_windows(pdev, port);
++ ret = mc_pcie_setup_windows(pdev, &port->plda);
+ if (ret)
+ return ret;
+
+ /* Address translation is up; safe to enable interrupts */
+- ret = mc_init_interrupts(pdev, port);
++ ret = mc_init_interrupts(pdev, &port->plda);
+ if (ret)
+ return ret;
+
+@@ -1059,6 +1067,7 @@ static int mc_host_probe(struct platform
+ {
+ struct device *dev = &pdev->dev;
+ void __iomem *bridge_base_addr;
++ struct plda_pcie_rp *plda;
+ int ret;
+ u32 val;
+
+@@ -1066,7 +1075,8 @@ static int mc_host_probe(struct platform
+ if (!port)
+ return -ENOMEM;
+
+- port->dev = dev;
++ plda = &port->plda;
++ plda->dev = dev;
+
+ port->axi_base_addr = devm_platform_ioremap_resource(pdev, 1);
+ if (IS_ERR(port->axi_base_addr))
+@@ -1075,7 +1085,7 @@ static int mc_host_probe(struct platform
+ mc_disable_interrupts(port);
+
+ bridge_base_addr = port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
+- port->bridge_addr = bridge_base_addr;
++ plda->bridge_addr = bridge_base_addr;
+
+ /* Allow enabling MSI by disabling MSI-X */
+ val = readl(bridge_base_addr + PCIE_PCI_IRQ_DW0);
+@@ -1087,10 +1097,10 @@ static int mc_host_probe(struct platform
+ val &= NUM_MSI_MSGS_MASK;
+ val >>= NUM_MSI_MSGS_SHIFT;
+
+- port->msi.num_vectors = 1 << val;
++ plda->msi.num_vectors = 1 << val;
+
+ /* Pick vector address from design */
+- port->msi.vector_phy = readl_relaxed(bridge_base_addr + IMSI_ADDR);
++ plda->msi.vector_phy = readl_relaxed(bridge_base_addr + IMSI_ADDR);
+
+ ret = mc_pcie_init_clks(dev);
+ if (ret) {
diff --git a/target/linux/starfive/patches-6.6/0019-PCI-microchip-Move-PCIe-host-data-structures-to-plda.patch b/target/linux/starfive/patches-6.6/0019-PCI-microchip-Move-PCIe-host-data-structures-to-plda.patch
new file mode 100644
index 0000000000..0823502cfd
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0019-PCI-microchip-Move-PCIe-host-data-structures-to-plda.patch
@@ -0,0 +1,87 @@
+From a53cf9b237dd53c9538b51a8df592888935c8411 Mon Sep 17 00:00:00 2001
+From: Minda Chen <minda.chen@starfivetech.com>
+Date: Mon, 8 Jan 2024 19:05:56 +0800
+Subject: [PATCH 019/116] PCI: microchip: Move PCIe host data structures to
+ plda-pcie.h
+
+Move the common data structures definition to head file for these two data
+structures can be re-used.
+
+Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+---
+ .../pci/controller/plda/pcie-microchip-host.c | 20 ------------------
+ drivers/pci/controller/plda/pcie-plda.h | 21 +++++++++++++++++++
+ 2 files changed, 21 insertions(+), 20 deletions(-)
+
+--- a/drivers/pci/controller/plda/pcie-microchip-host.c
++++ b/drivers/pci/controller/plda/pcie-microchip-host.c
+@@ -21,9 +21,6 @@
+ #include "../../pci.h"
+ #include "pcie-plda.h"
+
+-/* Number of MSI IRQs */
+-#define PLDA_MAX_NUM_MSI_IRQS 32
+-
+ /* PCIe Bridge Phy and Controller Phy offsets */
+ #define MC_PCIE1_BRIDGE_ADDR 0x00008000u
+ #define MC_PCIE1_CTRL_ADDR 0x0000a000u
+@@ -179,23 +176,6 @@ struct event_map {
+ u32 event_bit;
+ };
+
+-struct plda_msi {
+- struct mutex lock; /* Protect used bitmap */
+- struct irq_domain *msi_domain;
+- struct irq_domain *dev_domain;
+- u32 num_vectors;
+- u64 vector_phy;
+- DECLARE_BITMAP(used, PLDA_MAX_NUM_MSI_IRQS);
+-};
+-
+-struct plda_pcie_rp {
+- struct device *dev;
+- struct irq_domain *intx_domain;
+- struct irq_domain *event_domain;
+- raw_spinlock_t lock;
+- struct plda_msi msi;
+- void __iomem *bridge_addr;
+-};
+
+ struct mc_pcie {
+ struct plda_pcie_rp plda;
+--- a/drivers/pci/controller/plda/pcie-plda.h
++++ b/drivers/pci/controller/plda/pcie-plda.h
+@@ -6,6 +6,9 @@
+ #ifndef _PCIE_PLDA_H
+ #define _PCIE_PLDA_H
+
++/* Number of MSI IRQs */
++#define PLDA_MAX_NUM_MSI_IRQS 32
++
+ /* PCIe Bridge Phy Regs */
+ #define PCIE_PCI_IRQ_DW0 0xa8
+ #define MSIX_CAP_MASK BIT(31)
+@@ -105,4 +108,22 @@ enum plda_int_event {
+
+ #define PLDA_MAX_INT_NUM (PLDA_NUM_DMA_EVENTS + PLDA_INT_EVENT_NUM)
+
++struct plda_msi {
++ struct mutex lock; /* Protect used bitmap */
++ struct irq_domain *msi_domain;
++ struct irq_domain *dev_domain;
++ u32 num_vectors;
++ u64 vector_phy;
++ DECLARE_BITMAP(used, PLDA_MAX_NUM_MSI_IRQS);
++};
++
++struct plda_pcie_rp {
++ struct device *dev;
++ struct irq_domain *intx_domain;
++ struct irq_domain *event_domain;
++ raw_spinlock_t lock;
++ struct plda_msi msi;
++ void __iomem *bridge_addr;
++};
++
+ #endif
diff --git a/target/linux/starfive/patches-6.6/0020-PCI-microchip-Rename-two-setup-functions.patch b/target/linux/starfive/patches-6.6/0020-PCI-microchip-Rename-two-setup-functions.patch
new file mode 100644
index 0000000000..2bed600216
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0020-PCI-microchip-Rename-two-setup-functions.patch
@@ -0,0 +1,76 @@
+From d0e56d1ef7398bbf76be6e48d77943cbf644688e Mon Sep 17 00:00:00 2001
+From: Minda Chen <minda.chen@starfivetech.com>
+Date: Mon, 8 Jan 2024 19:05:57 +0800
+Subject: [PATCH 020/116] PCI: microchip: Rename two setup functions
+
+Rename two setup functions to plda prefix. Prepare to re-use these two
+setup function.
+
+For two setup functions names are similar, rename mc_pcie_setup_windows()
+to plda_pcie_setup_iomems().
+
+Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+---
+ .../pci/controller/plda/pcie-microchip-host.c | 24 +++++++++----------
+ 1 file changed, 12 insertions(+), 12 deletions(-)
+
+--- a/drivers/pci/controller/plda/pcie-microchip-host.c
++++ b/drivers/pci/controller/plda/pcie-microchip-host.c
+@@ -838,9 +838,9 @@ static int mc_pcie_init_irq_domains(stru
+ return mc_allocate_msi_domains(port);
+ }
+
+-static void mc_pcie_setup_window(void __iomem *bridge_base_addr, u32 index,
+- phys_addr_t axi_addr, phys_addr_t pci_addr,
+- size_t size)
++static void plda_pcie_setup_window(void __iomem *bridge_base_addr, u32 index,
++ phys_addr_t axi_addr, phys_addr_t pci_addr,
++ size_t size)
+ {
+ u32 atr_sz = ilog2(size) - 1;
+ u32 val;
+@@ -876,8 +876,8 @@ static void mc_pcie_setup_window(void __
+ writel(0, bridge_base_addr + ATR0_PCIE_WIN0_SRC_ADDR);
+ }
+
+-static int mc_pcie_setup_windows(struct platform_device *pdev,
+- struct plda_pcie_rp *port)
++static int plda_pcie_setup_iomems(struct platform_device *pdev,
++ struct plda_pcie_rp *port)
+ {
+ void __iomem *bridge_base_addr = port->bridge_addr;
+ struct pci_host_bridge *bridge = platform_get_drvdata(pdev);
+@@ -888,9 +888,9 @@ static int mc_pcie_setup_windows(struct
+ resource_list_for_each_entry(entry, &bridge->windows) {
+ if (resource_type(entry->res) == IORESOURCE_MEM) {
+ pci_addr = entry->res->start - entry->offset;
+- mc_pcie_setup_window(bridge_base_addr, index,
+- entry->res->start, pci_addr,
+- resource_size(entry->res));
++ plda_pcie_setup_window(bridge_base_addr, index,
++ entry->res->start, pci_addr,
++ resource_size(entry->res));
+ index++;
+ }
+ }
+@@ -1023,15 +1023,15 @@ static int mc_platform_init(struct pci_c
+ int ret;
+
+ /* Configure address translation table 0 for PCIe config space */
+- mc_pcie_setup_window(bridge_base_addr, 0, cfg->res.start,
+- cfg->res.start,
+- resource_size(&cfg->res));
++ plda_pcie_setup_window(bridge_base_addr, 0, cfg->res.start,
++ cfg->res.start,
++ resource_size(&cfg->res));
+
+ /* Need some fixups in config space */
+ mc_pcie_enable_msi(port, cfg->win);
+
+ /* Configure non-config space outbound ranges */
+- ret = mc_pcie_setup_windows(pdev, &port->plda);
++ ret = plda_pcie_setup_iomems(pdev, &port->plda);
+ if (ret)
+ return ret;
+
diff --git a/target/linux/starfive/patches-6.6/0021-PCI-microchip-Change-the-argument-of-plda_pcie_setup.patch b/target/linux/starfive/patches-6.6/0021-PCI-microchip-Change-the-argument-of-plda_pcie_setup.patch
new file mode 100644
index 0000000000..de6868b9f6
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0021-PCI-microchip-Change-the-argument-of-plda_pcie_setup.patch
@@ -0,0 +1,49 @@
+From 2fd7c88ef318fd39023ce1eb73f37a29fbd25d74 Mon Sep 17 00:00:00 2001
+From: Minda Chen <minda.chen@starfivetech.com>
+Date: Mon, 8 Jan 2024 19:05:58 +0800
+Subject: [PATCH 021/116] PCI: microchip: Change the argument of
+ plda_pcie_setup_iomems()
+
+If other vendor do not select PCI_HOST_COMMON, the driver data is not
+struct pci_host_bridge.
+
+Move calling platform_get_drvdata() to mc_platform_init().
+
+Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+---
+ drivers/pci/controller/plda/pcie-microchip-host.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/pci/controller/plda/pcie-microchip-host.c
++++ b/drivers/pci/controller/plda/pcie-microchip-host.c
+@@ -876,11 +876,10 @@ static void plda_pcie_setup_window(void
+ writel(0, bridge_base_addr + ATR0_PCIE_WIN0_SRC_ADDR);
+ }
+
+-static int plda_pcie_setup_iomems(struct platform_device *pdev,
++static int plda_pcie_setup_iomems(struct pci_host_bridge *bridge,
+ struct plda_pcie_rp *port)
+ {
+ void __iomem *bridge_base_addr = port->bridge_addr;
+- struct pci_host_bridge *bridge = platform_get_drvdata(pdev);
+ struct resource_entry *entry;
+ u64 pci_addr;
+ u32 index = 1;
+@@ -1018,6 +1017,7 @@ static int mc_platform_init(struct pci_c
+ {
+ struct device *dev = cfg->parent;
+ struct platform_device *pdev = to_platform_device(dev);
++ struct pci_host_bridge *bridge = platform_get_drvdata(pdev);
+ void __iomem *bridge_base_addr =
+ port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
+ int ret;
+@@ -1031,7 +1031,7 @@ static int mc_platform_init(struct pci_c
+ mc_pcie_enable_msi(port, cfg->win);
+
+ /* Configure non-config space outbound ranges */
+- ret = plda_pcie_setup_iomems(pdev, &port->plda);
++ ret = plda_pcie_setup_iomems(bridge, &port->plda);
+ if (ret)
+ return ret;
+
diff --git a/target/linux/starfive/patches-6.6/0022-PCI-microchip-Move-setup-functions-to-pcie-plda-host.patch b/target/linux/starfive/patches-6.6/0022-PCI-microchip-Move-setup-functions-to-pcie-plda-host.patch
new file mode 100644
index 0000000000..62f458be4a
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0022-PCI-microchip-Move-setup-functions-to-pcie-plda-host.patch
@@ -0,0 +1,200 @@
+From 201ce99897ff5fff2612cb633406e90c1b2acbcf Mon Sep 17 00:00:00 2001
+From: Minda Chen <minda.chen@starfivetech.com>
+Date: Mon, 8 Jan 2024 19:05:59 +0800
+Subject: [PATCH 022/116] PCI: microchip: Move setup functions to
+ pcie-plda-host.c
+
+Move setup functions to common pcie-plda-host.c. So these two functions
+can be re-used.
+
+Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+---
+ drivers/pci/controller/plda/Kconfig | 4 +
+ drivers/pci/controller/plda/Makefile | 1 +
+ .../pci/controller/plda/pcie-microchip-host.c | 59 ---------------
+ drivers/pci/controller/plda/pcie-plda-host.c | 74 +++++++++++++++++++
+ drivers/pci/controller/plda/pcie-plda.h | 5 ++
+ 5 files changed, 84 insertions(+), 59 deletions(-)
+ create mode 100644 drivers/pci/controller/plda/pcie-plda-host.c
+
+--- a/drivers/pci/controller/plda/Kconfig
++++ b/drivers/pci/controller/plda/Kconfig
+@@ -3,10 +3,14 @@
+ menu "PLDA-based PCIe controllers"
+ depends on PCI
+
++config PCIE_PLDA_HOST
++ bool
++
+ config PCIE_MICROCHIP_HOST
+ tristate "Microchip AXI PCIe controller"
+ depends on PCI_MSI && OF
+ select PCI_HOST_COMMON
++ select PCIE_PLDA_HOST
+ help
+ Say Y here if you want kernel to support the Microchip AXI PCIe
+ Host Bridge driver.
+--- a/drivers/pci/controller/plda/Makefile
++++ b/drivers/pci/controller/plda/Makefile
+@@ -1,2 +1,3 @@
+ # SPDX-License-Identifier: GPL-2.0
++obj-$(CONFIG_PCIE_PLDA_HOST) += pcie-plda-host.o
+ obj-$(CONFIG_PCIE_MICROCHIP_HOST) += pcie-microchip-host.o
+--- a/drivers/pci/controller/plda/pcie-microchip-host.c
++++ b/drivers/pci/controller/plda/pcie-microchip-host.c
+@@ -838,65 +838,6 @@ static int mc_pcie_init_irq_domains(stru
+ return mc_allocate_msi_domains(port);
+ }
+
+-static void plda_pcie_setup_window(void __iomem *bridge_base_addr, u32 index,
+- phys_addr_t axi_addr, phys_addr_t pci_addr,
+- size_t size)
+-{
+- u32 atr_sz = ilog2(size) - 1;
+- u32 val;
+-
+- if (index == 0)
+- val = PCIE_CONFIG_INTERFACE;
+- else
+- val = PCIE_TX_RX_INTERFACE;
+-
+- writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +
+- ATR0_AXI4_SLV0_TRSL_PARAM);
+-
+- val = lower_32_bits(axi_addr) | (atr_sz << ATR_SIZE_SHIFT) |
+- ATR_IMPL_ENABLE;
+- writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +
+- ATR0_AXI4_SLV0_SRCADDR_PARAM);
+-
+- val = upper_32_bits(axi_addr);
+- writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +
+- ATR0_AXI4_SLV0_SRC_ADDR);
+-
+- val = lower_32_bits(pci_addr);
+- writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +
+- ATR0_AXI4_SLV0_TRSL_ADDR_LSB);
+-
+- val = upper_32_bits(pci_addr);
+- writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +
+- ATR0_AXI4_SLV0_TRSL_ADDR_UDW);
+-
+- val = readl(bridge_base_addr + ATR0_PCIE_WIN0_SRCADDR_PARAM);
+- val |= (ATR0_PCIE_ATR_SIZE << ATR0_PCIE_ATR_SIZE_SHIFT);
+- writel(val, bridge_base_addr + ATR0_PCIE_WIN0_SRCADDR_PARAM);
+- writel(0, bridge_base_addr + ATR0_PCIE_WIN0_SRC_ADDR);
+-}
+-
+-static int plda_pcie_setup_iomems(struct pci_host_bridge *bridge,
+- struct plda_pcie_rp *port)
+-{
+- void __iomem *bridge_base_addr = port->bridge_addr;
+- struct resource_entry *entry;
+- u64 pci_addr;
+- u32 index = 1;
+-
+- resource_list_for_each_entry(entry, &bridge->windows) {
+- if (resource_type(entry->res) == IORESOURCE_MEM) {
+- pci_addr = entry->res->start - entry->offset;
+- plda_pcie_setup_window(bridge_base_addr, index,
+- entry->res->start, pci_addr,
+- resource_size(entry->res));
+- index++;
+- }
+- }
+-
+- return 0;
+-}
+-
+ static inline void mc_clear_secs(struct mc_pcie *port)
+ {
+ void __iomem *ctrl_base_addr = port->axi_base_addr + MC_PCIE_CTRL_ADDR;
+--- /dev/null
++++ b/drivers/pci/controller/plda/pcie-plda-host.c
+@@ -0,0 +1,74 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * PLDA PCIe XpressRich host controller driver
++ *
++ * Copyright (C) 2023 Microchip Co. Ltd
++ *
++ * Author: Daire McNamara <daire.mcnamara@microchip.com>
++ */
++
++#include <linux/pci_regs.h>
++#include <linux/pci-ecam.h>
++
++#include "pcie-plda.h"
++
++void plda_pcie_setup_window(void __iomem *bridge_base_addr, u32 index,
++ phys_addr_t axi_addr, phys_addr_t pci_addr,
++ size_t size)
++{
++ u32 atr_sz = ilog2(size) - 1;
++ u32 val;
++
++ if (index == 0)
++ val = PCIE_CONFIG_INTERFACE;
++ else
++ val = PCIE_TX_RX_INTERFACE;
++
++ writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +
++ ATR0_AXI4_SLV0_TRSL_PARAM);
++
++ val = lower_32_bits(axi_addr) | (atr_sz << ATR_SIZE_SHIFT) |
++ ATR_IMPL_ENABLE;
++ writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +
++ ATR0_AXI4_SLV0_SRCADDR_PARAM);
++
++ val = upper_32_bits(axi_addr);
++ writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +
++ ATR0_AXI4_SLV0_SRC_ADDR);
++
++ val = lower_32_bits(pci_addr);
++ writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +
++ ATR0_AXI4_SLV0_TRSL_ADDR_LSB);
++
++ val = upper_32_bits(pci_addr);
++ writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +
++ ATR0_AXI4_SLV0_TRSL_ADDR_UDW);
++
++ val = readl(bridge_base_addr + ATR0_PCIE_WIN0_SRCADDR_PARAM);
++ val |= (ATR0_PCIE_ATR_SIZE << ATR0_PCIE_ATR_SIZE_SHIFT);
++ writel(val, bridge_base_addr + ATR0_PCIE_WIN0_SRCADDR_PARAM);
++ writel(0, bridge_base_addr + ATR0_PCIE_WIN0_SRC_ADDR);
++}
++EXPORT_SYMBOL_GPL(plda_pcie_setup_window);
++
++int plda_pcie_setup_iomems(struct pci_host_bridge *bridge,
++ struct plda_pcie_rp *port)
++{
++ void __iomem *bridge_base_addr = port->bridge_addr;
++ struct resource_entry *entry;
++ u64 pci_addr;
++ u32 index = 1;
++
++ resource_list_for_each_entry(entry, &bridge->windows) {
++ if (resource_type(entry->res) == IORESOURCE_MEM) {
++ pci_addr = entry->res->start - entry->offset;
++ plda_pcie_setup_window(bridge_base_addr, index,
++ entry->res->start, pci_addr,
++ resource_size(entry->res));
++ index++;
++ }
++ }
++
++ return 0;
++}
++EXPORT_SYMBOL_GPL(plda_pcie_setup_iomems);
+--- a/drivers/pci/controller/plda/pcie-plda.h
++++ b/drivers/pci/controller/plda/pcie-plda.h
+@@ -126,4 +126,9 @@ struct plda_pcie_rp {
+ void __iomem *bridge_addr;
+ };
+
++void plda_pcie_setup_window(void __iomem *bridge_base_addr, u32 index,
++ phys_addr_t axi_addr, phys_addr_t pci_addr,
++ size_t size);
++int plda_pcie_setup_iomems(struct pci_host_bridge *bridge,
++ struct plda_pcie_rp *port);
+ #endif
diff --git a/target/linux/starfive/patches-6.6/0023-PCI-microchip-Rename-interrupt-related-functions.patch b/target/linux/starfive/patches-6.6/0023-PCI-microchip-Rename-interrupt-related-functions.patch
new file mode 100644
index 0000000000..09c1633b6f
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0023-PCI-microchip-Rename-interrupt-related-functions.patch
@@ -0,0 +1,336 @@
+From 2a48bc45dcf8cbe736b594d013cfa9d682214c43 Mon Sep 17 00:00:00 2001
+From: Minda Chen <minda.chen@starfivetech.com>
+Date: Mon, 8 Jan 2024 19:06:00 +0800
+Subject: [PATCH 023/116] PCI: microchip: Rename interrupt related functions
+
+Rename mc_* to plda_* for IRQ functions and related IRQ domain ops data
+instances.
+
+MSI, INTx interrupt code and IRQ init code are all can be re-used.
+
+Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
+Acked-by: Conor Dooley <conor.dooley@microchip.com>
+---
+ .../pci/controller/plda/pcie-microchip-host.c | 109 +++++++++---------
+ 1 file changed, 57 insertions(+), 52 deletions(-)
+
+--- a/drivers/pci/controller/plda/pcie-microchip-host.c
++++ b/drivers/pci/controller/plda/pcie-microchip-host.c
+@@ -318,7 +318,7 @@ static void mc_pcie_enable_msi(struct mc
+ ecam + MC_MSI_CAP_CTRL_OFFSET + PCI_MSI_ADDRESS_HI);
+ }
+
+-static void mc_handle_msi(struct irq_desc *desc)
++static void plda_handle_msi(struct irq_desc *desc)
+ {
+ struct plda_pcie_rp *port = irq_desc_get_handler_data(desc);
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+@@ -346,7 +346,7 @@ static void mc_handle_msi(struct irq_des
+ chained_irq_exit(chip, desc);
+ }
+
+-static void mc_msi_bottom_irq_ack(struct irq_data *data)
++static void plda_msi_bottom_irq_ack(struct irq_data *data)
+ {
+ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
+ void __iomem *bridge_base_addr = port->bridge_addr;
+@@ -355,7 +355,7 @@ static void mc_msi_bottom_irq_ack(struct
+ writel_relaxed(BIT(bitpos), bridge_base_addr + ISTATUS_MSI);
+ }
+
+-static void mc_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
++static void plda_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
+ {
+ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
+ phys_addr_t addr = port->msi.vector_phy;
+@@ -368,21 +368,23 @@ static void mc_compose_msi_msg(struct ir
+ (int)data->hwirq, msg->address_hi, msg->address_lo);
+ }
+
+-static int mc_msi_set_affinity(struct irq_data *irq_data,
+- const struct cpumask *mask, bool force)
++static int plda_msi_set_affinity(struct irq_data *irq_data,
++ const struct cpumask *mask, bool force)
+ {
+ return -EINVAL;
+ }
+
+-static struct irq_chip mc_msi_bottom_irq_chip = {
+- .name = "Microchip MSI",
+- .irq_ack = mc_msi_bottom_irq_ack,
+- .irq_compose_msi_msg = mc_compose_msi_msg,
+- .irq_set_affinity = mc_msi_set_affinity,
++static struct irq_chip plda_msi_bottom_irq_chip = {
++ .name = "PLDA MSI",
++ .irq_ack = plda_msi_bottom_irq_ack,
++ .irq_compose_msi_msg = plda_compose_msi_msg,
++ .irq_set_affinity = plda_msi_set_affinity,
+ };
+
+-static int mc_irq_msi_domain_alloc(struct irq_domain *domain, unsigned int virq,
+- unsigned int nr_irqs, void *args)
++static int plda_irq_msi_domain_alloc(struct irq_domain *domain,
++ unsigned int virq,
++ unsigned int nr_irqs,
++ void *args)
+ {
+ struct plda_pcie_rp *port = domain->host_data;
+ struct plda_msi *msi = &port->msi;
+@@ -397,7 +399,7 @@ static int mc_irq_msi_domain_alloc(struc
+
+ set_bit(bit, msi->used);
+
+- irq_domain_set_info(domain, virq, bit, &mc_msi_bottom_irq_chip,
++ irq_domain_set_info(domain, virq, bit, &plda_msi_bottom_irq_chip,
+ domain->host_data, handle_edge_irq, NULL, NULL);
+
+ mutex_unlock(&msi->lock);
+@@ -405,8 +407,9 @@ static int mc_irq_msi_domain_alloc(struc
+ return 0;
+ }
+
+-static void mc_irq_msi_domain_free(struct irq_domain *domain, unsigned int virq,
+- unsigned int nr_irqs)
++static void plda_irq_msi_domain_free(struct irq_domain *domain,
++ unsigned int virq,
++ unsigned int nr_irqs)
+ {
+ struct irq_data *d = irq_domain_get_irq_data(domain, virq);
+ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(d);
+@@ -423,24 +426,24 @@ static void mc_irq_msi_domain_free(struc
+ }
+
+ static const struct irq_domain_ops msi_domain_ops = {
+- .alloc = mc_irq_msi_domain_alloc,
+- .free = mc_irq_msi_domain_free,
++ .alloc = plda_irq_msi_domain_alloc,
++ .free = plda_irq_msi_domain_free,
+ };
+
+-static struct irq_chip mc_msi_irq_chip = {
+- .name = "Microchip PCIe MSI",
++static struct irq_chip plda_msi_irq_chip = {
++ .name = "PLDA PCIe MSI",
+ .irq_ack = irq_chip_ack_parent,
+ .irq_mask = pci_msi_mask_irq,
+ .irq_unmask = pci_msi_unmask_irq,
+ };
+
+-static struct msi_domain_info mc_msi_domain_info = {
++static struct msi_domain_info plda_msi_domain_info = {
+ .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
+ MSI_FLAG_PCI_MSIX),
+- .chip = &mc_msi_irq_chip,
++ .chip = &plda_msi_irq_chip,
+ };
+
+-static int mc_allocate_msi_domains(struct plda_pcie_rp *port)
++static int plda_allocate_msi_domains(struct plda_pcie_rp *port)
+ {
+ struct device *dev = port->dev;
+ struct fwnode_handle *fwnode = of_node_to_fwnode(dev->of_node);
+@@ -455,7 +458,8 @@ static int mc_allocate_msi_domains(struc
+ return -ENOMEM;
+ }
+
+- msi->msi_domain = pci_msi_create_irq_domain(fwnode, &mc_msi_domain_info,
++ msi->msi_domain = pci_msi_create_irq_domain(fwnode,
++ &plda_msi_domain_info,
+ msi->dev_domain);
+ if (!msi->msi_domain) {
+ dev_err(dev, "failed to create MSI domain\n");
+@@ -466,7 +470,7 @@ static int mc_allocate_msi_domains(struc
+ return 0;
+ }
+
+-static void mc_handle_intx(struct irq_desc *desc)
++static void plda_handle_intx(struct irq_desc *desc)
+ {
+ struct plda_pcie_rp *port = irq_desc_get_handler_data(desc);
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+@@ -493,7 +497,7 @@ static void mc_handle_intx(struct irq_de
+ chained_irq_exit(chip, desc);
+ }
+
+-static void mc_ack_intx_irq(struct irq_data *data)
++static void plda_ack_intx_irq(struct irq_data *data)
+ {
+ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
+ void __iomem *bridge_base_addr = port->bridge_addr;
+@@ -502,7 +506,7 @@ static void mc_ack_intx_irq(struct irq_d
+ writel_relaxed(mask, bridge_base_addr + ISTATUS_LOCAL);
+ }
+
+-static void mc_mask_intx_irq(struct irq_data *data)
++static void plda_mask_intx_irq(struct irq_data *data)
+ {
+ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
+ void __iomem *bridge_base_addr = port->bridge_addr;
+@@ -517,7 +521,7 @@ static void mc_mask_intx_irq(struct irq_
+ raw_spin_unlock_irqrestore(&port->lock, flags);
+ }
+
+-static void mc_unmask_intx_irq(struct irq_data *data)
++static void plda_unmask_intx_irq(struct irq_data *data)
+ {
+ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
+ void __iomem *bridge_base_addr = port->bridge_addr;
+@@ -532,24 +536,24 @@ static void mc_unmask_intx_irq(struct ir
+ raw_spin_unlock_irqrestore(&port->lock, flags);
+ }
+
+-static struct irq_chip mc_intx_irq_chip = {
+- .name = "Microchip PCIe INTx",
+- .irq_ack = mc_ack_intx_irq,
+- .irq_mask = mc_mask_intx_irq,
+- .irq_unmask = mc_unmask_intx_irq,
++static struct irq_chip plda_intx_irq_chip = {
++ .name = "PLDA PCIe INTx",
++ .irq_ack = plda_ack_intx_irq,
++ .irq_mask = plda_mask_intx_irq,
++ .irq_unmask = plda_unmask_intx_irq,
+ };
+
+-static int mc_pcie_intx_map(struct irq_domain *domain, unsigned int irq,
+- irq_hw_number_t hwirq)
++static int plda_pcie_intx_map(struct irq_domain *domain, unsigned int irq,
++ irq_hw_number_t hwirq)
+ {
+- irq_set_chip_and_handler(irq, &mc_intx_irq_chip, handle_level_irq);
++ irq_set_chip_and_handler(irq, &plda_intx_irq_chip, handle_level_irq);
+ irq_set_chip_data(irq, domain->host_data);
+
+ return 0;
+ }
+
+ static const struct irq_domain_ops intx_domain_ops = {
+- .map = mc_pcie_intx_map,
++ .map = plda_pcie_intx_map,
+ };
+
+ static inline u32 reg_to_event(u32 reg, struct event_map field)
+@@ -609,7 +613,7 @@ static u32 local_events(struct mc_pcie *
+ return val;
+ }
+
+-static u32 get_events(struct plda_pcie_rp *port)
++static u32 mc_get_events(struct plda_pcie_rp *port)
+ {
+ struct mc_pcie *mc_port = container_of(port, struct mc_pcie, plda);
+ u32 events = 0;
+@@ -638,7 +642,7 @@ static irqreturn_t mc_event_handler(int
+ return IRQ_HANDLED;
+ }
+
+-static void mc_handle_event(struct irq_desc *desc)
++static void plda_handle_event(struct irq_desc *desc)
+ {
+ struct plda_pcie_rp *port = irq_desc_get_handler_data(desc);
+ unsigned long events;
+@@ -647,7 +651,7 @@ static void mc_handle_event(struct irq_d
+
+ chained_irq_enter(chip, desc);
+
+- events = get_events(port);
++ events = mc_get_events(port);
+
+ for_each_set_bit(bit, &events, NUM_EVENTS)
+ generic_handle_domain_irq(port->event_domain, bit);
+@@ -741,8 +745,8 @@ static struct irq_chip mc_event_irq_chip
+ .irq_unmask = mc_unmask_event_irq,
+ };
+
+-static int mc_pcie_event_map(struct irq_domain *domain, unsigned int irq,
+- irq_hw_number_t hwirq)
++static int plda_pcie_event_map(struct irq_domain *domain, unsigned int irq,
++ irq_hw_number_t hwirq)
+ {
+ irq_set_chip_and_handler(irq, &mc_event_irq_chip, handle_level_irq);
+ irq_set_chip_data(irq, domain->host_data);
+@@ -750,8 +754,8 @@ static int mc_pcie_event_map(struct irq_
+ return 0;
+ }
+
+-static const struct irq_domain_ops event_domain_ops = {
+- .map = mc_pcie_event_map,
++static const struct irq_domain_ops plda_event_domain_ops = {
++ .map = plda_pcie_event_map,
+ };
+
+ static inline void mc_pcie_deinit_clk(void *data)
+@@ -799,7 +803,7 @@ static int mc_pcie_init_clks(struct devi
+ return 0;
+ }
+
+-static int mc_pcie_init_irq_domains(struct plda_pcie_rp *port)
++static int plda_pcie_init_irq_domains(struct plda_pcie_rp *port)
+ {
+ struct device *dev = port->dev;
+ struct device_node *node = dev->of_node;
+@@ -813,7 +817,8 @@ static int mc_pcie_init_irq_domains(stru
+ }
+
+ port->event_domain = irq_domain_add_linear(pcie_intc_node, NUM_EVENTS,
+- &event_domain_ops, port);
++ &plda_event_domain_ops,
++ port);
+ if (!port->event_domain) {
+ dev_err(dev, "failed to get event domain\n");
+ of_node_put(pcie_intc_node);
+@@ -835,7 +840,7 @@ static int mc_pcie_init_irq_domains(stru
+ of_node_put(pcie_intc_node);
+ raw_spin_lock_init(&port->lock);
+
+- return mc_allocate_msi_domains(port);
++ return plda_allocate_msi_domains(port);
+ }
+
+ static inline void mc_clear_secs(struct mc_pcie *port)
+@@ -898,14 +903,14 @@ static void mc_disable_interrupts(struct
+ writel_relaxed(GENMASK(31, 0), bridge_base_addr + ISTATUS_HOST);
+ }
+
+-static int mc_init_interrupts(struct platform_device *pdev, struct plda_pcie_rp *port)
++static int plda_init_interrupts(struct platform_device *pdev, struct plda_pcie_rp *port)
+ {
+ struct device *dev = &pdev->dev;
+ int irq;
+ int i, intx_irq, msi_irq, event_irq;
+ int ret;
+
+- ret = mc_pcie_init_irq_domains(port);
++ ret = plda_pcie_init_irq_domains(port);
+ if (ret) {
+ dev_err(dev, "failed creating IRQ domains\n");
+ return ret;
+@@ -938,7 +943,7 @@ static int mc_init_interrupts(struct pla
+ }
+
+ /* Plug the INTx chained handler */
+- irq_set_chained_handler_and_data(intx_irq, mc_handle_intx, port);
++ irq_set_chained_handler_and_data(intx_irq, plda_handle_intx, port);
+
+ msi_irq = irq_create_mapping(port->event_domain,
+ EVENT_LOCAL_PM_MSI_INT_MSI);
+@@ -946,10 +951,10 @@ static int mc_init_interrupts(struct pla
+ return -ENXIO;
+
+ /* Plug the MSI chained handler */
+- irq_set_chained_handler_and_data(msi_irq, mc_handle_msi, port);
++ irq_set_chained_handler_and_data(msi_irq, plda_handle_msi, port);
+
+ /* Plug the main event chained handler */
+- irq_set_chained_handler_and_data(irq, mc_handle_event, port);
++ irq_set_chained_handler_and_data(irq, plda_handle_event, port);
+
+ return 0;
+ }
+@@ -977,7 +982,7 @@ static int mc_platform_init(struct pci_c
+ return ret;
+
+ /* Address translation is up; safe to enable interrupts */
+- ret = mc_init_interrupts(pdev, &port->plda);
++ ret = plda_init_interrupts(pdev, &port->plda);
+ if (ret)
+ return ret;
+
diff --git a/target/linux/starfive/patches-6.6/0024-PCI-microchip-Add-num_events-field-to-struct-plda_pc.patch b/target/linux/starfive/patches-6.6/0024-PCI-microchip-Add-num_events-field-to-struct-plda_pc.patch
new file mode 100644
index 0000000000..4071feb1b5
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0024-PCI-microchip-Add-num_events-field-to-struct-plda_pc.patch
@@ -0,0 +1,65 @@
+From ab04dadb45a4150c9fd55b97fdd7397f4739a629 Mon Sep 17 00:00:00 2001
+From: Minda Chen <minda.chen@starfivetech.com>
+Date: Mon, 8 Jan 2024 19:06:01 +0800
+Subject: [PATCH 024/116] PCI: microchip: Add num_events field to struct
+ plda_pcie_rp
+
+The number of events is different across platforms. In order to share
+interrupt processing code, add a variable that defines the number of
+events so that it can be set per-platform instead of hardcoding it.
+
+Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+---
+ drivers/pci/controller/plda/pcie-microchip-host.c | 8 +++++---
+ drivers/pci/controller/plda/pcie-plda.h | 1 +
+ 2 files changed, 6 insertions(+), 3 deletions(-)
+
+--- a/drivers/pci/controller/plda/pcie-microchip-host.c
++++ b/drivers/pci/controller/plda/pcie-microchip-host.c
+@@ -653,7 +653,7 @@ static void plda_handle_event(struct irq
+
+ events = mc_get_events(port);
+
+- for_each_set_bit(bit, &events, NUM_EVENTS)
++ for_each_set_bit(bit, &events, port->num_events)
+ generic_handle_domain_irq(port->event_domain, bit);
+
+ chained_irq_exit(chip, desc);
+@@ -816,7 +816,8 @@ static int plda_pcie_init_irq_domains(st
+ return -EINVAL;
+ }
+
+- port->event_domain = irq_domain_add_linear(pcie_intc_node, NUM_EVENTS,
++ port->event_domain = irq_domain_add_linear(pcie_intc_node,
++ port->num_events,
+ &plda_event_domain_ops,
+ port);
+ if (!port->event_domain) {
+@@ -920,7 +921,7 @@ static int plda_init_interrupts(struct p
+ if (irq < 0)
+ return -ENODEV;
+
+- for (i = 0; i < NUM_EVENTS; i++) {
++ for (i = 0; i < port->num_events; i++) {
+ event_irq = irq_create_mapping(port->event_domain, i);
+ if (!event_irq) {
+ dev_err(dev, "failed to map hwirq %d\n", i);
+@@ -1012,6 +1013,7 @@ static int mc_host_probe(struct platform
+
+ bridge_base_addr = port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
+ plda->bridge_addr = bridge_base_addr;
++ plda->num_events = NUM_EVENTS;
+
+ /* Allow enabling MSI by disabling MSI-X */
+ val = readl(bridge_base_addr + PCIE_PCI_IRQ_DW0);
+--- a/drivers/pci/controller/plda/pcie-plda.h
++++ b/drivers/pci/controller/plda/pcie-plda.h
+@@ -124,6 +124,7 @@ struct plda_pcie_rp {
+ raw_spinlock_t lock;
+ struct plda_msi msi;
+ void __iomem *bridge_addr;
++ int num_events;
+ };
+
+ void plda_pcie_setup_window(void __iomem *bridge_base_addr, u32 index,
diff --git a/target/linux/starfive/patches-6.6/0025-PCI-microchip-Add-request_event_irq-callback-functio.patch b/target/linux/starfive/patches-6.6/0025-PCI-microchip-Add-request_event_irq-callback-functio.patch
new file mode 100644
index 0000000000..2b299e01e9
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0025-PCI-microchip-Add-request_event_irq-callback-functio.patch
@@ -0,0 +1,114 @@
+From 9f202f211cc79eefecbb03715c884e54eb95a62c Mon Sep 17 00:00:00 2001
+From: Minda Chen <minda.chen@starfivetech.com>
+Date: Mon, 8 Jan 2024 19:06:02 +0800
+Subject: [PATCH 025/116] PCI: microchip: Add request_event_irq() callback
+ function
+
+As PLDA dts binding doc(Documentation/devicetree/bindings/pci/
+plda,xpressrich3-axi-common.yaml) showes, PLDA PCIe contains an interrupt
+controller. Microchip Polarfire PCIe add some PCIe interrupts base on
+PLDA IP interrupt controller.
+
+Microchip Polarfire PCIe additional intrerrupts:
+EVENT_PCIE_L2_EXIT
+EVENT_PCIE_HOTRST_EXIT
+EVENT_PCIE_DLUP_EXIT
+EVENT_SEC_TX_RAM_SEC_ERR
+EVENT_SEC_RX_RAM_SEC_ERR
+....
+
+Both codes of register interrupts and mc_event_handler() contain
+additional interrupts symbol names, these can not be re-used. So add a
+new plda_event_handler() functions, which implements PLDA interrupt
+defalt handler. Add request_event_irq() callback function to
+compat Microchip Polorfire PCIe additional interrupts.
+
+Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
+Acked-by: Conor Dooley <conor.dooley@microchip.com>
+---
+ .../pci/controller/plda/pcie-microchip-host.c | 31 ++++++++++++++++---
+ drivers/pci/controller/plda/pcie-plda.h | 5 +++
+ 2 files changed, 32 insertions(+), 4 deletions(-)
+
+--- a/drivers/pci/controller/plda/pcie-microchip-host.c
++++ b/drivers/pci/controller/plda/pcie-microchip-host.c
+@@ -642,6 +642,11 @@ static irqreturn_t mc_event_handler(int
+ return IRQ_HANDLED;
+ }
+
++static irqreturn_t plda_event_handler(int irq, void *dev_id)
++{
++ return IRQ_HANDLED;
++}
++
+ static void plda_handle_event(struct irq_desc *desc)
+ {
+ struct plda_pcie_rp *port = irq_desc_get_handler_data(desc);
+@@ -803,6 +808,17 @@ static int mc_pcie_init_clks(struct devi
+ return 0;
+ }
+
++static int mc_request_event_irq(struct plda_pcie_rp *plda, int event_irq,
++ int event)
++{
++ return devm_request_irq(plda->dev, event_irq, mc_event_handler,
++ 0, event_cause[event].sym, plda);
++}
++
++static const struct plda_event mc_event = {
++ .request_event_irq = mc_request_event_irq,
++};
++
+ static int plda_pcie_init_irq_domains(struct plda_pcie_rp *port)
+ {
+ struct device *dev = port->dev;
+@@ -904,7 +920,9 @@ static void mc_disable_interrupts(struct
+ writel_relaxed(GENMASK(31, 0), bridge_base_addr + ISTATUS_HOST);
+ }
+
+-static int plda_init_interrupts(struct platform_device *pdev, struct plda_pcie_rp *port)
++static int plda_init_interrupts(struct platform_device *pdev,
++ struct plda_pcie_rp *port,
++ const struct plda_event *event)
+ {
+ struct device *dev = &pdev->dev;
+ int irq;
+@@ -928,8 +946,13 @@ static int plda_init_interrupts(struct p
+ return -ENXIO;
+ }
+
+- ret = devm_request_irq(dev, event_irq, mc_event_handler,
+- 0, event_cause[i].sym, port);
++ if (event->request_event_irq)
++ ret = event->request_event_irq(port, event_irq, i);
++ else
++ ret = devm_request_irq(dev, event_irq,
++ plda_event_handler,
++ 0, NULL, port);
++
+ if (ret) {
+ dev_err(dev, "failed to request IRQ %d\n", event_irq);
+ return ret;
+@@ -983,7 +1006,7 @@ static int mc_platform_init(struct pci_c
+ return ret;
+
+ /* Address translation is up; safe to enable interrupts */
+- ret = plda_init_interrupts(pdev, &port->plda);
++ ret = plda_init_interrupts(pdev, &port->plda, &mc_event);
+ if (ret)
+ return ret;
+
+--- a/drivers/pci/controller/plda/pcie-plda.h
++++ b/drivers/pci/controller/plda/pcie-plda.h
+@@ -127,6 +127,11 @@ struct plda_pcie_rp {
+ int num_events;
+ };
+
++struct plda_event {
++ int (*request_event_irq)(struct plda_pcie_rp *pcie,
++ int event_irq, int event);
++};
++
+ void plda_pcie_setup_window(void __iomem *bridge_base_addr, u32 index,
+ phys_addr_t axi_addr, phys_addr_t pci_addr,
+ size_t size);
diff --git a/target/linux/starfive/patches-6.6/0026-PCI-microchip-Add-INTx-and-MSI-event-num-to-struct-p.patch b/target/linux/starfive/patches-6.6/0026-PCI-microchip-Add-INTx-and-MSI-event-num-to-struct-p.patch
new file mode 100644
index 0000000000..85b8143268
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0026-PCI-microchip-Add-INTx-and-MSI-event-num-to-struct-p.patch
@@ -0,0 +1,56 @@
+From 3cdc20d9cc029ba9444be111bf4e55fd5331ccbe Mon Sep 17 00:00:00 2001
+From: Minda Chen <minda.chen@starfivetech.com>
+Date: Mon, 8 Jan 2024 19:06:03 +0800
+Subject: [PATCH 026/116] PCI: microchip: Add INTx and MSI event num to struct
+ plda_event
+
+The INTx and MSI interrupt event num is different in Microchip and
+StarFive platform.
+
+Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
+Acked-by: Conor Dooley <conor.dooley@microchip.com>
+---
+ drivers/pci/controller/plda/pcie-microchip-host.c | 6 ++++--
+ drivers/pci/controller/plda/pcie-plda.h | 2 ++
+ 2 files changed, 6 insertions(+), 2 deletions(-)
+
+--- a/drivers/pci/controller/plda/pcie-microchip-host.c
++++ b/drivers/pci/controller/plda/pcie-microchip-host.c
+@@ -817,6 +817,8 @@ static int mc_request_event_irq(struct p
+
+ static const struct plda_event mc_event = {
+ .request_event_irq = mc_request_event_irq,
++ .intx_event = EVENT_LOCAL_PM_MSI_INT_INTX,
++ .msi_event = EVENT_LOCAL_PM_MSI_INT_MSI,
+ };
+
+ static int plda_pcie_init_irq_domains(struct plda_pcie_rp *port)
+@@ -960,7 +962,7 @@ static int plda_init_interrupts(struct p
+ }
+
+ intx_irq = irq_create_mapping(port->event_domain,
+- EVENT_LOCAL_PM_MSI_INT_INTX);
++ event->intx_event);
+ if (!intx_irq) {
+ dev_err(dev, "failed to map INTx interrupt\n");
+ return -ENXIO;
+@@ -970,7 +972,7 @@ static int plda_init_interrupts(struct p
+ irq_set_chained_handler_and_data(intx_irq, plda_handle_intx, port);
+
+ msi_irq = irq_create_mapping(port->event_domain,
+- EVENT_LOCAL_PM_MSI_INT_MSI);
++ event->msi_event);
+ if (!msi_irq)
+ return -ENXIO;
+
+--- a/drivers/pci/controller/plda/pcie-plda.h
++++ b/drivers/pci/controller/plda/pcie-plda.h
+@@ -130,6 +130,8 @@ struct plda_pcie_rp {
+ struct plda_event {
+ int (*request_event_irq)(struct plda_pcie_rp *pcie,
+ int event_irq, int event);
++ int intx_event;
++ int msi_event;
+ };
+
+ void plda_pcie_setup_window(void __iomem *bridge_base_addr, u32 index,
diff --git a/target/linux/starfive/patches-6.6/0027-PCI-microchip-Add-get_events-callback-and-add-PLDA-g.patch b/target/linux/starfive/patches-6.6/0027-PCI-microchip-Add-get_events-callback-and-add-PLDA-g.patch
new file mode 100644
index 0000000000..a0cb4789b8
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0027-PCI-microchip-Add-get_events-callback-and-add-PLDA-g.patch
@@ -0,0 +1,167 @@
+From b4a38ef87661f21fe2fb3e085ae98f25f78aaf99 Mon Sep 17 00:00:00 2001
+From: Minda Chen <minda.chen@starfivetech.com>
+Date: Mon, 8 Jan 2024 19:06:04 +0800
+Subject: [PATCH 027/116] PCI: microchip: Add get_events() callback and add
+ PLDA get_event()
+
+As PLDA dts binding doc(Documentation/devicetree/bindings/pci/
+plda,xpressrich3-axi-common.yaml) showes, PLDA PCIe contains an interrupt
+controller.
+
+PolarFire implements its own PCIe interrupts, additional to the regular
+PCIe interrupts, due to lack of an MSI controller, so the interrupt to
+event number mapping is different to the PLDA regular interrupts,
+necessitating a custom get_events() implementation.
+
+Microchip Polarfire PCIe additional intrerrupts:
+EVENT_PCIE_L2_EXIT
+EVENT_PCIE_HOTRST_EXIT
+EVENT_PCIE_DLUP_EXIT
+EVENT_SEC_TX_RAM_SEC_ERR
+EVENT_SEC_RX_RAM_SEC_ERR
+....
+
+plda_get_events() adds interrupt register to PLDA local event num mapping
+codes. All The PLDA interrupts can be seen in new added graph.
+
+Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
+Acked-by: Conor Dooley <conor.dooley@microchip.com>
+---
+ .../pci/controller/plda/pcie-microchip-host.c | 35 ++++++++++++++++++-
+ drivers/pci/controller/plda/pcie-plda.h | 32 +++++++++++++++++
+ 2 files changed, 66 insertions(+), 1 deletion(-)
+
+--- a/drivers/pci/controller/plda/pcie-microchip-host.c
++++ b/drivers/pci/controller/plda/pcie-microchip-host.c
+@@ -626,6 +626,26 @@ static u32 mc_get_events(struct plda_pci
+ return events;
+ }
+
++static u32 plda_get_events(struct plda_pcie_rp *port)
++{
++ u32 events, val, origin;
++
++ origin = readl_relaxed(port->bridge_addr + ISTATUS_LOCAL);
++
++ /* MSI event and sys events */
++ val = (origin & SYS_AND_MSI_MASK) >> PM_MSI_INT_MSI_SHIFT;
++ events = val << (PM_MSI_INT_MSI_SHIFT - PCI_NUM_INTX + 1);
++
++ /* INTx events */
++ if (origin & PM_MSI_INT_INTX_MASK)
++ events |= BIT(PM_MSI_INT_INTX_SHIFT);
++
++ /* remains are same with register */
++ events |= origin & GENMASK(P_ATR_EVT_DOORBELL_SHIFT, 0);
++
++ return events;
++}
++
+ static irqreturn_t mc_event_handler(int irq, void *dev_id)
+ {
+ struct plda_pcie_rp *port = dev_id;
+@@ -656,7 +676,7 @@ static void plda_handle_event(struct irq
+
+ chained_irq_enter(chip, desc);
+
+- events = mc_get_events(port);
++ events = port->event_ops->get_events(port);
+
+ for_each_set_bit(bit, &events, port->num_events)
+ generic_handle_domain_irq(port->event_domain, bit);
+@@ -750,6 +770,10 @@ static struct irq_chip mc_event_irq_chip
+ .irq_unmask = mc_unmask_event_irq,
+ };
+
++static const struct plda_event_ops plda_event_ops = {
++ .get_events = plda_get_events,
++};
++
+ static int plda_pcie_event_map(struct irq_domain *domain, unsigned int irq,
+ irq_hw_number_t hwirq)
+ {
+@@ -815,6 +839,10 @@ static int mc_request_event_irq(struct p
+ 0, event_cause[event].sym, plda);
+ }
+
++static const struct plda_event_ops mc_event_ops = {
++ .get_events = mc_get_events,
++};
++
+ static const struct plda_event mc_event = {
+ .request_event_irq = mc_request_event_irq,
+ .intx_event = EVENT_LOCAL_PM_MSI_INT_INTX,
+@@ -931,6 +959,9 @@ static int plda_init_interrupts(struct p
+ int i, intx_irq, msi_irq, event_irq;
+ int ret;
+
++ if (!port->event_ops)
++ port->event_ops = &plda_event_ops;
++
+ ret = plda_pcie_init_irq_domains(port);
+ if (ret) {
+ dev_err(dev, "failed creating IRQ domains\n");
+@@ -1007,6 +1038,8 @@ static int mc_platform_init(struct pci_c
+ if (ret)
+ return ret;
+
++ port->plda.event_ops = &mc_event_ops;
++
+ /* Address translation is up; safe to enable interrupts */
+ ret = plda_init_interrupts(pdev, &port->plda, &mc_event);
+ if (ret)
+--- a/drivers/pci/controller/plda/pcie-plda.h
++++ b/drivers/pci/controller/plda/pcie-plda.h
+@@ -58,6 +58,7 @@
+ #define PM_MSI_INT_EVENTS_SHIFT 30
+ #define PM_MSI_INT_SYS_ERR_MASK 0x80000000u
+ #define PM_MSI_INT_SYS_ERR_SHIFT 31
++#define SYS_AND_MSI_MASK GENMASK(31, 28)
+ #define NUM_LOCAL_EVENTS 15
+ #define ISTATUS_LOCAL 0x184
+ #define IMASK_HOST 0x188
+@@ -108,6 +109,36 @@ enum plda_int_event {
+
+ #define PLDA_MAX_INT_NUM (PLDA_NUM_DMA_EVENTS + PLDA_INT_EVENT_NUM)
+
++/*
++ * PLDA interrupt register
++ *
++ * 31 27 23 15 7 0
++ * +--+--+--+-+------+-+-+-+-+-+-+-+-+-----------+-----------+
++ * |12|11|10|9| intx |7|6|5|4|3|2|1|0| DMA error | DMA end |
++ * +--+--+--+-+------+-+-+-+-+-+-+-+-+-----------+-----------+
++ * bit 0-7 DMA interrupt end : reserved for vendor implement
++ * bit 8-15 DMA error : reserved for vendor implement
++ * 0: AXI post error (PLDA_AXI_POST_ERR)
++ * 1: AXI fetch error (PLDA_AXI_FETCH_ERR)
++ * 2: AXI discard error (PLDA_AXI_DISCARD_ERR)
++ * 3: AXI doorbell (PLDA_PCIE_DOORBELL)
++ * 4: PCIe post error (PLDA_PCIE_POST_ERR)
++ * 5: PCIe fetch error (PLDA_PCIE_FETCH_ERR)
++ * 6: PCIe discard error (PLDA_PCIE_DISCARD_ERR)
++ * 7: PCIe doorbell (PLDA_PCIE_DOORBELL)
++ * 8: 4 INTx interruts (PLDA_INTX)
++ * 9: MSI interrupt (PLDA_MSI)
++ * 10: AER event (PLDA_AER_EVENT)
++ * 11: PM/LTR/Hotplug (PLDA_MISC_EVENTS)
++ * 12: System error (PLDA_SYS_ERR)
++ */
++
++struct plda_pcie_rp;
++
++struct plda_event_ops {
++ u32 (*get_events)(struct plda_pcie_rp *pcie);
++};
++
+ struct plda_msi {
+ struct mutex lock; /* Protect used bitmap */
+ struct irq_domain *msi_domain;
+@@ -123,6 +154,7 @@ struct plda_pcie_rp {
+ struct irq_domain *event_domain;
+ raw_spinlock_t lock;
+ struct plda_msi msi;
++ const struct plda_event_ops *event_ops;
+ void __iomem *bridge_addr;
+ int num_events;
+ };
diff --git a/target/linux/starfive/patches-6.6/0028-PCI-microchip-Add-event-irqchip-field-to-host-port-a.patch b/target/linux/starfive/patches-6.6/0028-PCI-microchip-Add-event-irqchip-field-to-host-port-a.patch
new file mode 100644
index 0000000000..9ed8119b1e
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0028-PCI-microchip-Add-event-irqchip-field-to-host-port-a.patch
@@ -0,0 +1,144 @@
+From 229ea8e7b674eb5c9bc4f70d43df1bd02a79862a Mon Sep 17 00:00:00 2001
+From: Minda Chen <minda.chen@starfivetech.com>
+Date: Mon, 8 Jan 2024 19:06:05 +0800
+Subject: [PATCH 028/116] PCI: microchip: Add event irqchip field to host port
+ and add PLDA irqchip
+
+As PLDA dts binding doc(Documentation/devicetree/bindings/pci/
+plda,xpressrich3-axi-common.yaml) showes, PLDA PCIe contains an interrupt
+controller.
+
+Microchip PolarFire PCIE event IRQs includes PLDA interrupts and
+Polarfire their own interrupts. The interrupt irqchip ops includes
+ack/mask/unmask interrupt ops, which will write correct registers.
+Microchip Polarfire PCIe additional interrupts require to write Polarfire
+SoC self-defined registers. So Microchip PCIe event irqchip ops can not
+be re-used.
+
+To support PLDA its own event IRQ process, implements PLDA irqchip ops and
+add event irqchip field to struct pcie_plda_rp.
+
+Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
+Acked-by: Conor Dooley <conor.dooley@microchip.com>
+---
+ .../pci/controller/plda/pcie-microchip-host.c | 66 ++++++++++++++++++-
+ drivers/pci/controller/plda/pcie-plda.h | 5 +-
+ 2 files changed, 69 insertions(+), 2 deletions(-)
+
+--- a/drivers/pci/controller/plda/pcie-microchip-host.c
++++ b/drivers/pci/controller/plda/pcie-microchip-host.c
+@@ -770,6 +770,64 @@ static struct irq_chip mc_event_irq_chip
+ .irq_unmask = mc_unmask_event_irq,
+ };
+
++static u32 plda_hwirq_to_mask(int hwirq)
++{
++ u32 mask;
++
++ /* hwirq 23 - 0 are the same with register */
++ if (hwirq < EVENT_PM_MSI_INT_INTX)
++ mask = BIT(hwirq);
++ else if (hwirq == EVENT_PM_MSI_INT_INTX)
++ mask = PM_MSI_INT_INTX_MASK;
++ else
++ mask = BIT(hwirq + PCI_NUM_INTX - 1);
++
++ return mask;
++}
++
++static void plda_ack_event_irq(struct irq_data *data)
++{
++ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
++
++ writel_relaxed(plda_hwirq_to_mask(data->hwirq),
++ port->bridge_addr + ISTATUS_LOCAL);
++}
++
++static void plda_mask_event_irq(struct irq_data *data)
++{
++ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
++ u32 mask, val;
++
++ mask = plda_hwirq_to_mask(data->hwirq);
++
++ raw_spin_lock(&port->lock);
++ val = readl_relaxed(port->bridge_addr + IMASK_LOCAL);
++ val &= ~mask;
++ writel_relaxed(val, port->bridge_addr + IMASK_LOCAL);
++ raw_spin_unlock(&port->lock);
++}
++
++static void plda_unmask_event_irq(struct irq_data *data)
++{
++ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
++ u32 mask, val;
++
++ mask = plda_hwirq_to_mask(data->hwirq);
++
++ raw_spin_lock(&port->lock);
++ val = readl_relaxed(port->bridge_addr + IMASK_LOCAL);
++ val |= mask;
++ writel_relaxed(val, port->bridge_addr + IMASK_LOCAL);
++ raw_spin_unlock(&port->lock);
++}
++
++static struct irq_chip plda_event_irq_chip = {
++ .name = "PLDA PCIe EVENT",
++ .irq_ack = plda_ack_event_irq,
++ .irq_mask = plda_mask_event_irq,
++ .irq_unmask = plda_unmask_event_irq,
++};
++
+ static const struct plda_event_ops plda_event_ops = {
+ .get_events = plda_get_events,
+ };
+@@ -777,7 +835,9 @@ static const struct plda_event_ops plda_
+ static int plda_pcie_event_map(struct irq_domain *domain, unsigned int irq,
+ irq_hw_number_t hwirq)
+ {
+- irq_set_chip_and_handler(irq, &mc_event_irq_chip, handle_level_irq);
++ struct plda_pcie_rp *port = (void *)domain->host_data;
++
++ irq_set_chip_and_handler(irq, port->event_irq_chip, handle_level_irq);
+ irq_set_chip_data(irq, domain->host_data);
+
+ return 0;
+@@ -962,6 +1022,9 @@ static int plda_init_interrupts(struct p
+ if (!port->event_ops)
+ port->event_ops = &plda_event_ops;
+
++ if (!port->event_irq_chip)
++ port->event_irq_chip = &plda_event_irq_chip;
++
+ ret = plda_pcie_init_irq_domains(port);
+ if (ret) {
+ dev_err(dev, "failed creating IRQ domains\n");
+@@ -1039,6 +1102,7 @@ static int mc_platform_init(struct pci_c
+ return ret;
+
+ port->plda.event_ops = &mc_event_ops;
++ port->plda.event_irq_chip = &mc_event_irq_chip;
+
+ /* Address translation is up; safe to enable interrupts */
+ ret = plda_init_interrupts(pdev, &port->plda, &mc_event);
+--- a/drivers/pci/controller/plda/pcie-plda.h
++++ b/drivers/pci/controller/plda/pcie-plda.h
+@@ -107,7 +107,9 @@ enum plda_int_event {
+
+ #define PLDA_NUM_DMA_EVENTS 16
+
+-#define PLDA_MAX_INT_NUM (PLDA_NUM_DMA_EVENTS + PLDA_INT_EVENT_NUM)
++#define EVENT_PM_MSI_INT_INTX (PLDA_NUM_DMA_EVENTS + PLDA_INTX)
++#define EVENT_PM_MSI_INT_MSI (PLDA_NUM_DMA_EVENTS + PLDA_MSI)
++#define PLDA_MAX_EVENT_NUM (PLDA_NUM_DMA_EVENTS + PLDA_INT_EVENT_NUM)
+
+ /*
+ * PLDA interrupt register
+@@ -155,6 +157,7 @@ struct plda_pcie_rp {
+ raw_spinlock_t lock;
+ struct plda_msi msi;
+ const struct plda_event_ops *event_ops;
++ const struct irq_chip *event_irq_chip;
+ void __iomem *bridge_addr;
+ int num_events;
+ };
diff --git a/target/linux/starfive/patches-6.6/0029-PCI-microchip-Move-IRQ-functions-to-pcie-plda-host.c.patch b/target/linux/starfive/patches-6.6/0029-PCI-microchip-Move-IRQ-functions-to-pcie-plda-host.c.patch
new file mode 100644
index 0000000000..840e334d20
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0029-PCI-microchip-Move-IRQ-functions-to-pcie-plda-host.c.patch
@@ -0,0 +1,1028 @@
+From 6be452d8e61594790ae57b282a612ec0df473e61 Mon Sep 17 00:00:00 2001
+From: Minda Chen <minda.chen@starfivetech.com>
+Date: Mon, 8 Jan 2024 19:06:06 +0800
+Subject: [PATCH 029/116] PCI: microchip: Move IRQ functions to
+ pcie-plda-host.c
+
+Move IRQ related functions to pcie-plda-host.c for re-use these codes.
+Now Refactoring codes complete.
+
+Including MSI, INTx, event interrupts and IRQ init functions.
+
+Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
+Acked-by: Conor Dooley <conor.dooley@microchip.com>
+---
+ .../pci/controller/plda/pcie-microchip-host.c | 467 -----------------
+ drivers/pci/controller/plda/pcie-plda-host.c | 472 ++++++++++++++++++
+ drivers/pci/controller/plda/pcie-plda.h | 3 +
+ 3 files changed, 475 insertions(+), 467 deletions(-)
+
+--- a/drivers/pci/controller/plda/pcie-microchip-host.c
++++ b/drivers/pci/controller/plda/pcie-microchip-host.c
+@@ -318,244 +318,6 @@ static void mc_pcie_enable_msi(struct mc
+ ecam + MC_MSI_CAP_CTRL_OFFSET + PCI_MSI_ADDRESS_HI);
+ }
+
+-static void plda_handle_msi(struct irq_desc *desc)
+-{
+- struct plda_pcie_rp *port = irq_desc_get_handler_data(desc);
+- struct irq_chip *chip = irq_desc_get_chip(desc);
+- struct device *dev = port->dev;
+- struct plda_msi *msi = &port->msi;
+- void __iomem *bridge_base_addr = port->bridge_addr;
+- unsigned long status;
+- u32 bit;
+- int ret;
+-
+- chained_irq_enter(chip, desc);
+-
+- status = readl_relaxed(bridge_base_addr + ISTATUS_LOCAL);
+- if (status & PM_MSI_INT_MSI_MASK) {
+- writel_relaxed(status & PM_MSI_INT_MSI_MASK, bridge_base_addr + ISTATUS_LOCAL);
+- status = readl_relaxed(bridge_base_addr + ISTATUS_MSI);
+- for_each_set_bit(bit, &status, msi->num_vectors) {
+- ret = generic_handle_domain_irq(msi->dev_domain, bit);
+- if (ret)
+- dev_err_ratelimited(dev, "bad MSI IRQ %d\n",
+- bit);
+- }
+- }
+-
+- chained_irq_exit(chip, desc);
+-}
+-
+-static void plda_msi_bottom_irq_ack(struct irq_data *data)
+-{
+- struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
+- void __iomem *bridge_base_addr = port->bridge_addr;
+- u32 bitpos = data->hwirq;
+-
+- writel_relaxed(BIT(bitpos), bridge_base_addr + ISTATUS_MSI);
+-}
+-
+-static void plda_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
+-{
+- struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
+- phys_addr_t addr = port->msi.vector_phy;
+-
+- msg->address_lo = lower_32_bits(addr);
+- msg->address_hi = upper_32_bits(addr);
+- msg->data = data->hwirq;
+-
+- dev_dbg(port->dev, "msi#%x address_hi %#x address_lo %#x\n",
+- (int)data->hwirq, msg->address_hi, msg->address_lo);
+-}
+-
+-static int plda_msi_set_affinity(struct irq_data *irq_data,
+- const struct cpumask *mask, bool force)
+-{
+- return -EINVAL;
+-}
+-
+-static struct irq_chip plda_msi_bottom_irq_chip = {
+- .name = "PLDA MSI",
+- .irq_ack = plda_msi_bottom_irq_ack,
+- .irq_compose_msi_msg = plda_compose_msi_msg,
+- .irq_set_affinity = plda_msi_set_affinity,
+-};
+-
+-static int plda_irq_msi_domain_alloc(struct irq_domain *domain,
+- unsigned int virq,
+- unsigned int nr_irqs,
+- void *args)
+-{
+- struct plda_pcie_rp *port = domain->host_data;
+- struct plda_msi *msi = &port->msi;
+- unsigned long bit;
+-
+- mutex_lock(&msi->lock);
+- bit = find_first_zero_bit(msi->used, msi->num_vectors);
+- if (bit >= msi->num_vectors) {
+- mutex_unlock(&msi->lock);
+- return -ENOSPC;
+- }
+-
+- set_bit(bit, msi->used);
+-
+- irq_domain_set_info(domain, virq, bit, &plda_msi_bottom_irq_chip,
+- domain->host_data, handle_edge_irq, NULL, NULL);
+-
+- mutex_unlock(&msi->lock);
+-
+- return 0;
+-}
+-
+-static void plda_irq_msi_domain_free(struct irq_domain *domain,
+- unsigned int virq,
+- unsigned int nr_irqs)
+-{
+- struct irq_data *d = irq_domain_get_irq_data(domain, virq);
+- struct plda_pcie_rp *port = irq_data_get_irq_chip_data(d);
+- struct plda_msi *msi = &port->msi;
+-
+- mutex_lock(&msi->lock);
+-
+- if (test_bit(d->hwirq, msi->used))
+- __clear_bit(d->hwirq, msi->used);
+- else
+- dev_err(port->dev, "trying to free unused MSI%lu\n", d->hwirq);
+-
+- mutex_unlock(&msi->lock);
+-}
+-
+-static const struct irq_domain_ops msi_domain_ops = {
+- .alloc = plda_irq_msi_domain_alloc,
+- .free = plda_irq_msi_domain_free,
+-};
+-
+-static struct irq_chip plda_msi_irq_chip = {
+- .name = "PLDA PCIe MSI",
+- .irq_ack = irq_chip_ack_parent,
+- .irq_mask = pci_msi_mask_irq,
+- .irq_unmask = pci_msi_unmask_irq,
+-};
+-
+-static struct msi_domain_info plda_msi_domain_info = {
+- .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
+- MSI_FLAG_PCI_MSIX),
+- .chip = &plda_msi_irq_chip,
+-};
+-
+-static int plda_allocate_msi_domains(struct plda_pcie_rp *port)
+-{
+- struct device *dev = port->dev;
+- struct fwnode_handle *fwnode = of_node_to_fwnode(dev->of_node);
+- struct plda_msi *msi = &port->msi;
+-
+- mutex_init(&port->msi.lock);
+-
+- msi->dev_domain = irq_domain_add_linear(NULL, msi->num_vectors,
+- &msi_domain_ops, port);
+- if (!msi->dev_domain) {
+- dev_err(dev, "failed to create IRQ domain\n");
+- return -ENOMEM;
+- }
+-
+- msi->msi_domain = pci_msi_create_irq_domain(fwnode,
+- &plda_msi_domain_info,
+- msi->dev_domain);
+- if (!msi->msi_domain) {
+- dev_err(dev, "failed to create MSI domain\n");
+- irq_domain_remove(msi->dev_domain);
+- return -ENOMEM;
+- }
+-
+- return 0;
+-}
+-
+-static void plda_handle_intx(struct irq_desc *desc)
+-{
+- struct plda_pcie_rp *port = irq_desc_get_handler_data(desc);
+- struct irq_chip *chip = irq_desc_get_chip(desc);
+- struct device *dev = port->dev;
+- void __iomem *bridge_base_addr = port->bridge_addr;
+- unsigned long status;
+- u32 bit;
+- int ret;
+-
+- chained_irq_enter(chip, desc);
+-
+- status = readl_relaxed(bridge_base_addr + ISTATUS_LOCAL);
+- if (status & PM_MSI_INT_INTX_MASK) {
+- status &= PM_MSI_INT_INTX_MASK;
+- status >>= PM_MSI_INT_INTX_SHIFT;
+- for_each_set_bit(bit, &status, PCI_NUM_INTX) {
+- ret = generic_handle_domain_irq(port->intx_domain, bit);
+- if (ret)
+- dev_err_ratelimited(dev, "bad INTx IRQ %d\n",
+- bit);
+- }
+- }
+-
+- chained_irq_exit(chip, desc);
+-}
+-
+-static void plda_ack_intx_irq(struct irq_data *data)
+-{
+- struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
+- void __iomem *bridge_base_addr = port->bridge_addr;
+- u32 mask = BIT(data->hwirq + PM_MSI_INT_INTX_SHIFT);
+-
+- writel_relaxed(mask, bridge_base_addr + ISTATUS_LOCAL);
+-}
+-
+-static void plda_mask_intx_irq(struct irq_data *data)
+-{
+- struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
+- void __iomem *bridge_base_addr = port->bridge_addr;
+- unsigned long flags;
+- u32 mask = BIT(data->hwirq + PM_MSI_INT_INTX_SHIFT);
+- u32 val;
+-
+- raw_spin_lock_irqsave(&port->lock, flags);
+- val = readl_relaxed(bridge_base_addr + IMASK_LOCAL);
+- val &= ~mask;
+- writel_relaxed(val, bridge_base_addr + IMASK_LOCAL);
+- raw_spin_unlock_irqrestore(&port->lock, flags);
+-}
+-
+-static void plda_unmask_intx_irq(struct irq_data *data)
+-{
+- struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
+- void __iomem *bridge_base_addr = port->bridge_addr;
+- unsigned long flags;
+- u32 mask = BIT(data->hwirq + PM_MSI_INT_INTX_SHIFT);
+- u32 val;
+-
+- raw_spin_lock_irqsave(&port->lock, flags);
+- val = readl_relaxed(bridge_base_addr + IMASK_LOCAL);
+- val |= mask;
+- writel_relaxed(val, bridge_base_addr + IMASK_LOCAL);
+- raw_spin_unlock_irqrestore(&port->lock, flags);
+-}
+-
+-static struct irq_chip plda_intx_irq_chip = {
+- .name = "PLDA PCIe INTx",
+- .irq_ack = plda_ack_intx_irq,
+- .irq_mask = plda_mask_intx_irq,
+- .irq_unmask = plda_unmask_intx_irq,
+-};
+-
+-static int plda_pcie_intx_map(struct irq_domain *domain, unsigned int irq,
+- irq_hw_number_t hwirq)
+-{
+- irq_set_chip_and_handler(irq, &plda_intx_irq_chip, handle_level_irq);
+- irq_set_chip_data(irq, domain->host_data);
+-
+- return 0;
+-}
+-
+-static const struct irq_domain_ops intx_domain_ops = {
+- .map = plda_pcie_intx_map,
+-};
+-
+ static inline u32 reg_to_event(u32 reg, struct event_map field)
+ {
+ return (reg & field.reg_mask) ? BIT(field.event_bit) : 0;
+@@ -626,26 +388,6 @@ static u32 mc_get_events(struct plda_pci
+ return events;
+ }
+
+-static u32 plda_get_events(struct plda_pcie_rp *port)
+-{
+- u32 events, val, origin;
+-
+- origin = readl_relaxed(port->bridge_addr + ISTATUS_LOCAL);
+-
+- /* MSI event and sys events */
+- val = (origin & SYS_AND_MSI_MASK) >> PM_MSI_INT_MSI_SHIFT;
+- events = val << (PM_MSI_INT_MSI_SHIFT - PCI_NUM_INTX + 1);
+-
+- /* INTx events */
+- if (origin & PM_MSI_INT_INTX_MASK)
+- events |= BIT(PM_MSI_INT_INTX_SHIFT);
+-
+- /* remains are same with register */
+- events |= origin & GENMASK(P_ATR_EVT_DOORBELL_SHIFT, 0);
+-
+- return events;
+-}
+-
+ static irqreturn_t mc_event_handler(int irq, void *dev_id)
+ {
+ struct plda_pcie_rp *port = dev_id;
+@@ -662,28 +404,6 @@ static irqreturn_t mc_event_handler(int
+ return IRQ_HANDLED;
+ }
+
+-static irqreturn_t plda_event_handler(int irq, void *dev_id)
+-{
+- return IRQ_HANDLED;
+-}
+-
+-static void plda_handle_event(struct irq_desc *desc)
+-{
+- struct plda_pcie_rp *port = irq_desc_get_handler_data(desc);
+- unsigned long events;
+- u32 bit;
+- struct irq_chip *chip = irq_desc_get_chip(desc);
+-
+- chained_irq_enter(chip, desc);
+-
+- events = port->event_ops->get_events(port);
+-
+- for_each_set_bit(bit, &events, port->num_events)
+- generic_handle_domain_irq(port->event_domain, bit);
+-
+- chained_irq_exit(chip, desc);
+-}
+-
+ static void mc_ack_event_irq(struct irq_data *data)
+ {
+ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
+@@ -770,83 +490,6 @@ static struct irq_chip mc_event_irq_chip
+ .irq_unmask = mc_unmask_event_irq,
+ };
+
+-static u32 plda_hwirq_to_mask(int hwirq)
+-{
+- u32 mask;
+-
+- /* hwirq 23 - 0 are the same with register */
+- if (hwirq < EVENT_PM_MSI_INT_INTX)
+- mask = BIT(hwirq);
+- else if (hwirq == EVENT_PM_MSI_INT_INTX)
+- mask = PM_MSI_INT_INTX_MASK;
+- else
+- mask = BIT(hwirq + PCI_NUM_INTX - 1);
+-
+- return mask;
+-}
+-
+-static void plda_ack_event_irq(struct irq_data *data)
+-{
+- struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
+-
+- writel_relaxed(plda_hwirq_to_mask(data->hwirq),
+- port->bridge_addr + ISTATUS_LOCAL);
+-}
+-
+-static void plda_mask_event_irq(struct irq_data *data)
+-{
+- struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
+- u32 mask, val;
+-
+- mask = plda_hwirq_to_mask(data->hwirq);
+-
+- raw_spin_lock(&port->lock);
+- val = readl_relaxed(port->bridge_addr + IMASK_LOCAL);
+- val &= ~mask;
+- writel_relaxed(val, port->bridge_addr + IMASK_LOCAL);
+- raw_spin_unlock(&port->lock);
+-}
+-
+-static void plda_unmask_event_irq(struct irq_data *data)
+-{
+- struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
+- u32 mask, val;
+-
+- mask = plda_hwirq_to_mask(data->hwirq);
+-
+- raw_spin_lock(&port->lock);
+- val = readl_relaxed(port->bridge_addr + IMASK_LOCAL);
+- val |= mask;
+- writel_relaxed(val, port->bridge_addr + IMASK_LOCAL);
+- raw_spin_unlock(&port->lock);
+-}
+-
+-static struct irq_chip plda_event_irq_chip = {
+- .name = "PLDA PCIe EVENT",
+- .irq_ack = plda_ack_event_irq,
+- .irq_mask = plda_mask_event_irq,
+- .irq_unmask = plda_unmask_event_irq,
+-};
+-
+-static const struct plda_event_ops plda_event_ops = {
+- .get_events = plda_get_events,
+-};
+-
+-static int plda_pcie_event_map(struct irq_domain *domain, unsigned int irq,
+- irq_hw_number_t hwirq)
+-{
+- struct plda_pcie_rp *port = (void *)domain->host_data;
+-
+- irq_set_chip_and_handler(irq, port->event_irq_chip, handle_level_irq);
+- irq_set_chip_data(irq, domain->host_data);
+-
+- return 0;
+-}
+-
+-static const struct irq_domain_ops plda_event_domain_ops = {
+- .map = plda_pcie_event_map,
+-};
+-
+ static inline void mc_pcie_deinit_clk(void *data)
+ {
+ struct clk *clk = data;
+@@ -909,47 +552,6 @@ static const struct plda_event mc_event
+ .msi_event = EVENT_LOCAL_PM_MSI_INT_MSI,
+ };
+
+-static int plda_pcie_init_irq_domains(struct plda_pcie_rp *port)
+-{
+- struct device *dev = port->dev;
+- struct device_node *node = dev->of_node;
+- struct device_node *pcie_intc_node;
+-
+- /* Setup INTx */
+- pcie_intc_node = of_get_next_child(node, NULL);
+- if (!pcie_intc_node) {
+- dev_err(dev, "failed to find PCIe Intc node\n");
+- return -EINVAL;
+- }
+-
+- port->event_domain = irq_domain_add_linear(pcie_intc_node,
+- port->num_events,
+- &plda_event_domain_ops,
+- port);
+- if (!port->event_domain) {
+- dev_err(dev, "failed to get event domain\n");
+- of_node_put(pcie_intc_node);
+- return -ENOMEM;
+- }
+-
+- irq_domain_update_bus_token(port->event_domain, DOMAIN_BUS_NEXUS);
+-
+- port->intx_domain = irq_domain_add_linear(pcie_intc_node, PCI_NUM_INTX,
+- &intx_domain_ops, port);
+- if (!port->intx_domain) {
+- dev_err(dev, "failed to get an INTx IRQ domain\n");
+- of_node_put(pcie_intc_node);
+- return -ENOMEM;
+- }
+-
+- irq_domain_update_bus_token(port->intx_domain, DOMAIN_BUS_WIRED);
+-
+- of_node_put(pcie_intc_node);
+- raw_spin_lock_init(&port->lock);
+-
+- return plda_allocate_msi_domains(port);
+-}
+-
+ static inline void mc_clear_secs(struct mc_pcie *port)
+ {
+ void __iomem *ctrl_base_addr = port->axi_base_addr + MC_PCIE_CTRL_ADDR;
+@@ -1010,75 +612,6 @@ static void mc_disable_interrupts(struct
+ writel_relaxed(GENMASK(31, 0), bridge_base_addr + ISTATUS_HOST);
+ }
+
+-static int plda_init_interrupts(struct platform_device *pdev,
+- struct plda_pcie_rp *port,
+- const struct plda_event *event)
+-{
+- struct device *dev = &pdev->dev;
+- int irq;
+- int i, intx_irq, msi_irq, event_irq;
+- int ret;
+-
+- if (!port->event_ops)
+- port->event_ops = &plda_event_ops;
+-
+- if (!port->event_irq_chip)
+- port->event_irq_chip = &plda_event_irq_chip;
+-
+- ret = plda_pcie_init_irq_domains(port);
+- if (ret) {
+- dev_err(dev, "failed creating IRQ domains\n");
+- return ret;
+- }
+-
+- irq = platform_get_irq(pdev, 0);
+- if (irq < 0)
+- return -ENODEV;
+-
+- for (i = 0; i < port->num_events; i++) {
+- event_irq = irq_create_mapping(port->event_domain, i);
+- if (!event_irq) {
+- dev_err(dev, "failed to map hwirq %d\n", i);
+- return -ENXIO;
+- }
+-
+- if (event->request_event_irq)
+- ret = event->request_event_irq(port, event_irq, i);
+- else
+- ret = devm_request_irq(dev, event_irq,
+- plda_event_handler,
+- 0, NULL, port);
+-
+- if (ret) {
+- dev_err(dev, "failed to request IRQ %d\n", event_irq);
+- return ret;
+- }
+- }
+-
+- intx_irq = irq_create_mapping(port->event_domain,
+- event->intx_event);
+- if (!intx_irq) {
+- dev_err(dev, "failed to map INTx interrupt\n");
+- return -ENXIO;
+- }
+-
+- /* Plug the INTx chained handler */
+- irq_set_chained_handler_and_data(intx_irq, plda_handle_intx, port);
+-
+- msi_irq = irq_create_mapping(port->event_domain,
+- event->msi_event);
+- if (!msi_irq)
+- return -ENXIO;
+-
+- /* Plug the MSI chained handler */
+- irq_set_chained_handler_and_data(msi_irq, plda_handle_msi, port);
+-
+- /* Plug the main event chained handler */
+- irq_set_chained_handler_and_data(irq, plda_handle_event, port);
+-
+- return 0;
+-}
+-
+ static int mc_platform_init(struct pci_config_window *cfg)
+ {
+ struct device *dev = cfg->parent;
+--- a/drivers/pci/controller/plda/pcie-plda-host.c
++++ b/drivers/pci/controller/plda/pcie-plda-host.c
+@@ -7,11 +7,483 @@
+ * Author: Daire McNamara <daire.mcnamara@microchip.com>
+ */
+
++#include <linux/irqchip/chained_irq.h>
++#include <linux/irqdomain.h>
++#include <linux/msi.h>
+ #include <linux/pci_regs.h>
+ #include <linux/pci-ecam.h>
+
+ #include "pcie-plda.h"
+
++static void plda_handle_msi(struct irq_desc *desc)
++{
++ struct plda_pcie_rp *port = irq_desc_get_handler_data(desc);
++ struct irq_chip *chip = irq_desc_get_chip(desc);
++ struct device *dev = port->dev;
++ struct plda_msi *msi = &port->msi;
++ void __iomem *bridge_base_addr = port->bridge_addr;
++ unsigned long status;
++ u32 bit;
++ int ret;
++
++ chained_irq_enter(chip, desc);
++
++ status = readl_relaxed(bridge_base_addr + ISTATUS_LOCAL);
++ if (status & PM_MSI_INT_MSI_MASK) {
++ writel_relaxed(status & PM_MSI_INT_MSI_MASK,
++ bridge_base_addr + ISTATUS_LOCAL);
++ status = readl_relaxed(bridge_base_addr + ISTATUS_MSI);
++ for_each_set_bit(bit, &status, msi->num_vectors) {
++ ret = generic_handle_domain_irq(msi->dev_domain, bit);
++ if (ret)
++ dev_err_ratelimited(dev, "bad MSI IRQ %d\n",
++ bit);
++ }
++ }
++
++ chained_irq_exit(chip, desc);
++}
++
++static void plda_msi_bottom_irq_ack(struct irq_data *data)
++{
++ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
++ void __iomem *bridge_base_addr = port->bridge_addr;
++ u32 bitpos = data->hwirq;
++
++ writel_relaxed(BIT(bitpos), bridge_base_addr + ISTATUS_MSI);
++}
++
++static void plda_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
++{
++ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
++ phys_addr_t addr = port->msi.vector_phy;
++
++ msg->address_lo = lower_32_bits(addr);
++ msg->address_hi = upper_32_bits(addr);
++ msg->data = data->hwirq;
++
++ dev_dbg(port->dev, "msi#%x address_hi %#x address_lo %#x\n",
++ (int)data->hwirq, msg->address_hi, msg->address_lo);
++}
++
++static int plda_msi_set_affinity(struct irq_data *irq_data,
++ const struct cpumask *mask, bool force)
++{
++ return -EINVAL;
++}
++
++static struct irq_chip plda_msi_bottom_irq_chip = {
++ .name = "PLDA MSI",
++ .irq_ack = plda_msi_bottom_irq_ack,
++ .irq_compose_msi_msg = plda_compose_msi_msg,
++ .irq_set_affinity = plda_msi_set_affinity,
++};
++
++static int plda_irq_msi_domain_alloc(struct irq_domain *domain,
++ unsigned int virq,
++ unsigned int nr_irqs,
++ void *args)
++{
++ struct plda_pcie_rp *port = domain->host_data;
++ struct plda_msi *msi = &port->msi;
++ unsigned long bit;
++
++ mutex_lock(&msi->lock);
++ bit = find_first_zero_bit(msi->used, msi->num_vectors);
++ if (bit >= msi->num_vectors) {
++ mutex_unlock(&msi->lock);
++ return -ENOSPC;
++ }
++
++ set_bit(bit, msi->used);
++
++ irq_domain_set_info(domain, virq, bit, &plda_msi_bottom_irq_chip,
++ domain->host_data, handle_edge_irq, NULL, NULL);
++
++ mutex_unlock(&msi->lock);
++
++ return 0;
++}
++
++static void plda_irq_msi_domain_free(struct irq_domain *domain,
++ unsigned int virq,
++ unsigned int nr_irqs)
++{
++ struct irq_data *d = irq_domain_get_irq_data(domain, virq);
++ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(d);
++ struct plda_msi *msi = &port->msi;
++
++ mutex_lock(&msi->lock);
++
++ if (test_bit(d->hwirq, msi->used))
++ __clear_bit(d->hwirq, msi->used);
++ else
++ dev_err(port->dev, "trying to free unused MSI%lu\n", d->hwirq);
++
++ mutex_unlock(&msi->lock);
++}
++
++static const struct irq_domain_ops msi_domain_ops = {
++ .alloc = plda_irq_msi_domain_alloc,
++ .free = plda_irq_msi_domain_free,
++};
++
++static struct irq_chip plda_msi_irq_chip = {
++ .name = "PLDA PCIe MSI",
++ .irq_ack = irq_chip_ack_parent,
++ .irq_mask = pci_msi_mask_irq,
++ .irq_unmask = pci_msi_unmask_irq,
++};
++
++static struct msi_domain_info plda_msi_domain_info = {
++ .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
++ MSI_FLAG_PCI_MSIX),
++ .chip = &plda_msi_irq_chip,
++};
++
++static int plda_allocate_msi_domains(struct plda_pcie_rp *port)
++{
++ struct device *dev = port->dev;
++ struct fwnode_handle *fwnode = of_node_to_fwnode(dev->of_node);
++ struct plda_msi *msi = &port->msi;
++
++ mutex_init(&port->msi.lock);
++
++ msi->dev_domain = irq_domain_add_linear(NULL, msi->num_vectors,
++ &msi_domain_ops, port);
++ if (!msi->dev_domain) {
++ dev_err(dev, "failed to create IRQ domain\n");
++ return -ENOMEM;
++ }
++
++ msi->msi_domain = pci_msi_create_irq_domain(fwnode,
++ &plda_msi_domain_info,
++ msi->dev_domain);
++ if (!msi->msi_domain) {
++ dev_err(dev, "failed to create MSI domain\n");
++ irq_domain_remove(msi->dev_domain);
++ return -ENOMEM;
++ }
++
++ return 0;
++}
++
++static void plda_handle_intx(struct irq_desc *desc)
++{
++ struct plda_pcie_rp *port = irq_desc_get_handler_data(desc);
++ struct irq_chip *chip = irq_desc_get_chip(desc);
++ struct device *dev = port->dev;
++ void __iomem *bridge_base_addr = port->bridge_addr;
++ unsigned long status;
++ u32 bit;
++ int ret;
++
++ chained_irq_enter(chip, desc);
++
++ status = readl_relaxed(bridge_base_addr + ISTATUS_LOCAL);
++ if (status & PM_MSI_INT_INTX_MASK) {
++ status &= PM_MSI_INT_INTX_MASK;
++ status >>= PM_MSI_INT_INTX_SHIFT;
++ for_each_set_bit(bit, &status, PCI_NUM_INTX) {
++ ret = generic_handle_domain_irq(port->intx_domain, bit);
++ if (ret)
++ dev_err_ratelimited(dev, "bad INTx IRQ %d\n",
++ bit);
++ }
++ }
++
++ chained_irq_exit(chip, desc);
++}
++
++static void plda_ack_intx_irq(struct irq_data *data)
++{
++ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
++ void __iomem *bridge_base_addr = port->bridge_addr;
++ u32 mask = BIT(data->hwirq + PM_MSI_INT_INTX_SHIFT);
++
++ writel_relaxed(mask, bridge_base_addr + ISTATUS_LOCAL);
++}
++
++static void plda_mask_intx_irq(struct irq_data *data)
++{
++ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
++ void __iomem *bridge_base_addr = port->bridge_addr;
++ unsigned long flags;
++ u32 mask = BIT(data->hwirq + PM_MSI_INT_INTX_SHIFT);
++ u32 val;
++
++ raw_spin_lock_irqsave(&port->lock, flags);
++ val = readl_relaxed(bridge_base_addr + IMASK_LOCAL);
++ val &= ~mask;
++ writel_relaxed(val, bridge_base_addr + IMASK_LOCAL);
++ raw_spin_unlock_irqrestore(&port->lock, flags);
++}
++
++static void plda_unmask_intx_irq(struct irq_data *data)
++{
++ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
++ void __iomem *bridge_base_addr = port->bridge_addr;
++ unsigned long flags;
++ u32 mask = BIT(data->hwirq + PM_MSI_INT_INTX_SHIFT);
++ u32 val;
++
++ raw_spin_lock_irqsave(&port->lock, flags);
++ val = readl_relaxed(bridge_base_addr + IMASK_LOCAL);
++ val |= mask;
++ writel_relaxed(val, bridge_base_addr + IMASK_LOCAL);
++ raw_spin_unlock_irqrestore(&port->lock, flags);
++}
++
++static struct irq_chip plda_intx_irq_chip = {
++ .name = "PLDA PCIe INTx",
++ .irq_ack = plda_ack_intx_irq,
++ .irq_mask = plda_mask_intx_irq,
++ .irq_unmask = plda_unmask_intx_irq,
++};
++
++static int plda_pcie_intx_map(struct irq_domain *domain, unsigned int irq,
++ irq_hw_number_t hwirq)
++{
++ irq_set_chip_and_handler(irq, &plda_intx_irq_chip, handle_level_irq);
++ irq_set_chip_data(irq, domain->host_data);
++
++ return 0;
++}
++
++static const struct irq_domain_ops intx_domain_ops = {
++ .map = plda_pcie_intx_map,
++};
++
++static u32 plda_get_events(struct plda_pcie_rp *port)
++{
++ u32 events, val, origin;
++
++ origin = readl_relaxed(port->bridge_addr + ISTATUS_LOCAL);
++
++ /* MSI event and sys events */
++ val = (origin & SYS_AND_MSI_MASK) >> PM_MSI_INT_MSI_SHIFT;
++ events = val << (PM_MSI_INT_MSI_SHIFT - PCI_NUM_INTX + 1);
++
++ /* INTx events */
++ if (origin & PM_MSI_INT_INTX_MASK)
++ events |= BIT(PM_MSI_INT_INTX_SHIFT);
++
++ /* remains are same with register */
++ events |= origin & GENMASK(P_ATR_EVT_DOORBELL_SHIFT, 0);
++
++ return events;
++}
++
++static irqreturn_t plda_event_handler(int irq, void *dev_id)
++{
++ return IRQ_HANDLED;
++}
++
++static void plda_handle_event(struct irq_desc *desc)
++{
++ struct plda_pcie_rp *port = irq_desc_get_handler_data(desc);
++ unsigned long events;
++ u32 bit;
++ struct irq_chip *chip = irq_desc_get_chip(desc);
++
++ chained_irq_enter(chip, desc);
++
++ events = port->event_ops->get_events(port);
++
++ for_each_set_bit(bit, &events, port->num_events)
++ generic_handle_domain_irq(port->event_domain, bit);
++
++ chained_irq_exit(chip, desc);
++}
++
++static u32 plda_hwirq_to_mask(int hwirq)
++{
++ u32 mask;
++
++ /* hwirq 23 - 0 are the same with register */
++ if (hwirq < EVENT_PM_MSI_INT_INTX)
++ mask = BIT(hwirq);
++ else if (hwirq == EVENT_PM_MSI_INT_INTX)
++ mask = PM_MSI_INT_INTX_MASK;
++ else
++ mask = BIT(hwirq + PCI_NUM_INTX - 1);
++
++ return mask;
++}
++
++static void plda_ack_event_irq(struct irq_data *data)
++{
++ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
++
++ writel_relaxed(plda_hwirq_to_mask(data->hwirq),
++ port->bridge_addr + ISTATUS_LOCAL);
++}
++
++static void plda_mask_event_irq(struct irq_data *data)
++{
++ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
++ u32 mask, val;
++
++ mask = plda_hwirq_to_mask(data->hwirq);
++
++ raw_spin_lock(&port->lock);
++ val = readl_relaxed(port->bridge_addr + IMASK_LOCAL);
++ val &= ~mask;
++ writel_relaxed(val, port->bridge_addr + IMASK_LOCAL);
++ raw_spin_unlock(&port->lock);
++}
++
++static void plda_unmask_event_irq(struct irq_data *data)
++{
++ struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);
++ u32 mask, val;
++
++ mask = plda_hwirq_to_mask(data->hwirq);
++
++ raw_spin_lock(&port->lock);
++ val = readl_relaxed(port->bridge_addr + IMASK_LOCAL);
++ val |= mask;
++ writel_relaxed(val, port->bridge_addr + IMASK_LOCAL);
++ raw_spin_unlock(&port->lock);
++}
++
++static struct irq_chip plda_event_irq_chip = {
++ .name = "PLDA PCIe EVENT",
++ .irq_ack = plda_ack_event_irq,
++ .irq_mask = plda_mask_event_irq,
++ .irq_unmask = plda_unmask_event_irq,
++};
++
++static const struct plda_event_ops plda_event_ops = {
++ .get_events = plda_get_events,
++};
++
++static int plda_pcie_event_map(struct irq_domain *domain, unsigned int irq,
++ irq_hw_number_t hwirq)
++{
++ struct plda_pcie_rp *port = (void *)domain->host_data;
++
++ irq_set_chip_and_handler(irq, port->event_irq_chip, handle_level_irq);
++ irq_set_chip_data(irq, domain->host_data);
++
++ return 0;
++}
++
++static const struct irq_domain_ops plda_event_domain_ops = {
++ .map = plda_pcie_event_map,
++};
++
++static int plda_pcie_init_irq_domains(struct plda_pcie_rp *port)
++{
++ struct device *dev = port->dev;
++ struct device_node *node = dev->of_node;
++ struct device_node *pcie_intc_node;
++
++ /* Setup INTx */
++ pcie_intc_node = of_get_next_child(node, NULL);
++ if (!pcie_intc_node) {
++ dev_err(dev, "failed to find PCIe Intc node\n");
++ return -EINVAL;
++ }
++
++ port->event_domain = irq_domain_add_linear(pcie_intc_node,
++ port->num_events,
++ &plda_event_domain_ops,
++ port);
++ if (!port->event_domain) {
++ dev_err(dev, "failed to get event domain\n");
++ of_node_put(pcie_intc_node);
++ return -ENOMEM;
++ }
++
++ irq_domain_update_bus_token(port->event_domain, DOMAIN_BUS_NEXUS);
++
++ port->intx_domain = irq_domain_add_linear(pcie_intc_node, PCI_NUM_INTX,
++ &intx_domain_ops, port);
++ if (!port->intx_domain) {
++ dev_err(dev, "failed to get an INTx IRQ domain\n");
++ of_node_put(pcie_intc_node);
++ return -ENOMEM;
++ }
++
++ irq_domain_update_bus_token(port->intx_domain, DOMAIN_BUS_WIRED);
++
++ of_node_put(pcie_intc_node);
++ raw_spin_lock_init(&port->lock);
++
++ return plda_allocate_msi_domains(port);
++}
++
++int plda_init_interrupts(struct platform_device *pdev,
++ struct plda_pcie_rp *port,
++ const struct plda_event *event)
++{
++ struct device *dev = &pdev->dev;
++ int irq;
++ int i, intx_irq, msi_irq, event_irq;
++ int ret;
++
++ if (!port->event_ops)
++ port->event_ops = &plda_event_ops;
++
++ if (!port->event_irq_chip)
++ port->event_irq_chip = &plda_event_irq_chip;
++
++ ret = plda_pcie_init_irq_domains(port);
++ if (ret) {
++ dev_err(dev, "failed creating IRQ domains\n");
++ return ret;
++ }
++
++ irq = platform_get_irq(pdev, 0);
++ if (irq < 0)
++ return -ENODEV;
++
++ for (i = 0; i < port->num_events; i++) {
++ event_irq = irq_create_mapping(port->event_domain, i);
++ if (!event_irq) {
++ dev_err(dev, "failed to map hwirq %d\n", i);
++ return -ENXIO;
++ }
++
++ if (event->request_event_irq)
++ ret = event->request_event_irq(port, event_irq, i);
++ else
++ ret = devm_request_irq(dev, event_irq,
++ plda_event_handler,
++ 0, NULL, port);
++
++ if (ret) {
++ dev_err(dev, "failed to request IRQ %d\n", event_irq);
++ return ret;
++ }
++ }
++
++ intx_irq = irq_create_mapping(port->event_domain,
++ event->intx_event);
++ if (!intx_irq) {
++ dev_err(dev, "failed to map INTx interrupt\n");
++ return -ENXIO;
++ }
++
++ /* Plug the INTx chained handler */
++ irq_set_chained_handler_and_data(intx_irq, plda_handle_intx, port);
++
++ msi_irq = irq_create_mapping(port->event_domain,
++ event->msi_event);
++ if (!msi_irq)
++ return -ENXIO;
++
++ /* Plug the MSI chained handler */
++ irq_set_chained_handler_and_data(msi_irq, plda_handle_msi, port);
++
++ /* Plug the main event chained handler */
++ irq_set_chained_handler_and_data(irq, plda_handle_event, port);
++
++ return 0;
++}
++EXPORT_SYMBOL_GPL(plda_init_interrupts);
++
+ void plda_pcie_setup_window(void __iomem *bridge_base_addr, u32 index,
+ phys_addr_t axi_addr, phys_addr_t pci_addr,
+ size_t size)
+--- a/drivers/pci/controller/plda/pcie-plda.h
++++ b/drivers/pci/controller/plda/pcie-plda.h
+@@ -169,6 +169,9 @@ struct plda_event {
+ int msi_event;
+ };
+
++int plda_init_interrupts(struct platform_device *pdev,
++ struct plda_pcie_rp *port,
++ const struct plda_event *event);
+ void plda_pcie_setup_window(void __iomem *bridge_base_addr, u32 index,
+ phys_addr_t axi_addr, phys_addr_t pci_addr,
+ size_t size);
diff --git a/target/linux/starfive/patches-6.6/0030-pci-plda-Add-event-bitmap-field-to-struct-plda_pcie_.patch b/target/linux/starfive/patches-6.6/0030-pci-plda-Add-event-bitmap-field-to-struct-plda_pcie_.patch
new file mode 100644
index 0000000000..dcd2310e5e
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0030-pci-plda-Add-event-bitmap-field-to-struct-plda_pcie_.patch
@@ -0,0 +1,67 @@
+From 142fc300fd7511a217783dcfa342031d8ad70188 Mon Sep 17 00:00:00 2001
+From: Minda Chen <minda.chen@starfivetech.com>
+Date: Mon, 8 Jan 2024 19:06:07 +0800
+Subject: [PATCH 030/116] pci: plda: Add event bitmap field to struct
+ plda_pcie_rp
+
+For PLDA DMA interrupts are not all implemented. The non-implemented
+interrupts should be masked. So add a bitmap field to mask the non-
+implemented interrupts.
+
+Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
+---
+ drivers/pci/controller/plda/pcie-microchip-host.c | 1 +
+ drivers/pci/controller/plda/pcie-plda-host.c | 6 ++++--
+ drivers/pci/controller/plda/pcie-plda.h | 1 +
+ 3 files changed, 6 insertions(+), 2 deletions(-)
+
+--- a/drivers/pci/controller/plda/pcie-microchip-host.c
++++ b/drivers/pci/controller/plda/pcie-microchip-host.c
+@@ -636,6 +636,7 @@ static int mc_platform_init(struct pci_c
+
+ port->plda.event_ops = &mc_event_ops;
+ port->plda.event_irq_chip = &mc_event_irq_chip;
++ port->plda.events_bitmap = GENMASK(NUM_EVENTS - 1, 0);
+
+ /* Address translation is up; safe to enable interrupts */
+ ret = plda_init_interrupts(pdev, &port->plda, &mc_event);
+--- a/drivers/pci/controller/plda/pcie-plda-host.c
++++ b/drivers/pci/controller/plda/pcie-plda-host.c
+@@ -290,6 +290,7 @@ static void plda_handle_event(struct irq
+
+ events = port->event_ops->get_events(port);
+
++ events &= port->events_bitmap;
+ for_each_set_bit(bit, &events, port->num_events)
+ generic_handle_domain_irq(port->event_domain, bit);
+
+@@ -420,8 +421,9 @@ int plda_init_interrupts(struct platform
+ {
+ struct device *dev = &pdev->dev;
+ int irq;
+- int i, intx_irq, msi_irq, event_irq;
++ int intx_irq, msi_irq, event_irq;
+ int ret;
++ u32 i;
+
+ if (!port->event_ops)
+ port->event_ops = &plda_event_ops;
+@@ -439,7 +441,7 @@ int plda_init_interrupts(struct platform
+ if (irq < 0)
+ return -ENODEV;
+
+- for (i = 0; i < port->num_events; i++) {
++ for_each_set_bit(i, &port->events_bitmap, port->num_events) {
+ event_irq = irq_create_mapping(port->event_domain, i);
+ if (!event_irq) {
+ dev_err(dev, "failed to map hwirq %d\n", i);
+--- a/drivers/pci/controller/plda/pcie-plda.h
++++ b/drivers/pci/controller/plda/pcie-plda.h
+@@ -159,6 +159,7 @@ struct plda_pcie_rp {
+ const struct plda_event_ops *event_ops;
+ const struct irq_chip *event_irq_chip;
+ void __iomem *bridge_addr;
++ unsigned long events_bitmap;
+ int num_events;
+ };
+
diff --git a/target/linux/starfive/patches-6.6/0031-PCI-plda-Add-host-init-deinit-and-map-bus-functions.patch b/target/linux/starfive/patches-6.6/0031-PCI-plda-Add-host-init-deinit-and-map-bus-functions.patch
new file mode 100644
index 0000000000..eb22849da6
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0031-PCI-plda-Add-host-init-deinit-and-map-bus-functions.patch
@@ -0,0 +1,256 @@
+From 3b9991438094dc472dacb4555603bdc379653411 Mon Sep 17 00:00:00 2001
+From: Minda Chen <minda.chen@starfivetech.com>
+Date: Mon, 8 Jan 2024 19:06:08 +0800
+Subject: [PATCH 031/116] PCI: plda: Add host init/deinit and map bus functions
+
+Add PLDA host plda_pcie_host_init()/plda_pcie_host_deinit() and map bus
+function. So vendor can use it to init PLDA PCIe host core.
+
+Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
+Reviewed-by: Mason Huo <mason.huo@starfivetech.com>
+---
+ drivers/pci/controller/plda/pcie-plda-host.c | 131 +++++++++++++++++--
+ drivers/pci/controller/plda/pcie-plda.h | 22 ++++
+ 2 files changed, 139 insertions(+), 14 deletions(-)
+
+--- a/drivers/pci/controller/plda/pcie-plda-host.c
++++ b/drivers/pci/controller/plda/pcie-plda-host.c
+@@ -3,6 +3,7 @@
+ * PLDA PCIe XpressRich host controller driver
+ *
+ * Copyright (C) 2023 Microchip Co. Ltd
++ * StarFive Co. Ltd
+ *
+ * Author: Daire McNamara <daire.mcnamara@microchip.com>
+ */
+@@ -15,6 +16,15 @@
+
+ #include "pcie-plda.h"
+
++void __iomem *plda_pcie_map_bus(struct pci_bus *bus, unsigned int devfn,
++ int where)
++{
++ struct plda_pcie_rp *pcie = bus->sysdata;
++
++ return pcie->config_base + PCIE_ECAM_OFFSET(bus->number, devfn, where);
++}
++EXPORT_SYMBOL_GPL(plda_pcie_map_bus);
++
+ static void plda_handle_msi(struct irq_desc *desc)
+ {
+ struct plda_pcie_rp *port = irq_desc_get_handler_data(desc);
+@@ -420,9 +430,7 @@ int plda_init_interrupts(struct platform
+ const struct plda_event *event)
+ {
+ struct device *dev = &pdev->dev;
+- int irq;
+- int intx_irq, msi_irq, event_irq;
+- int ret;
++ int event_irq, ret;
+ u32 i;
+
+ if (!port->event_ops)
+@@ -437,8 +445,8 @@ int plda_init_interrupts(struct platform
+ return ret;
+ }
+
+- irq = platform_get_irq(pdev, 0);
+- if (irq < 0)
++ port->irq = platform_get_irq(pdev, 0);
++ if (port->irq < 0)
+ return -ENODEV;
+
+ for_each_set_bit(i, &port->events_bitmap, port->num_events) {
+@@ -461,26 +469,26 @@ int plda_init_interrupts(struct platform
+ }
+ }
+
+- intx_irq = irq_create_mapping(port->event_domain,
+- event->intx_event);
+- if (!intx_irq) {
++ port->intx_irq = irq_create_mapping(port->event_domain,
++ event->intx_event);
++ if (!port->intx_irq) {
+ dev_err(dev, "failed to map INTx interrupt\n");
+ return -ENXIO;
+ }
+
+ /* Plug the INTx chained handler */
+- irq_set_chained_handler_and_data(intx_irq, plda_handle_intx, port);
++ irq_set_chained_handler_and_data(port->intx_irq, plda_handle_intx, port);
+
+- msi_irq = irq_create_mapping(port->event_domain,
+- event->msi_event);
+- if (!msi_irq)
++ port->msi_irq = irq_create_mapping(port->event_domain,
++ event->msi_event);
++ if (!port->msi_irq)
+ return -ENXIO;
+
+ /* Plug the MSI chained handler */
+- irq_set_chained_handler_and_data(msi_irq, plda_handle_msi, port);
++ irq_set_chained_handler_and_data(port->msi_irq, plda_handle_msi, port);
+
+ /* Plug the main event chained handler */
+- irq_set_chained_handler_and_data(irq, plda_handle_event, port);
++ irq_set_chained_handler_and_data(port->irq, plda_handle_event, port);
+
+ return 0;
+ }
+@@ -546,3 +554,98 @@ int plda_pcie_setup_iomems(struct pci_ho
+ return 0;
+ }
+ EXPORT_SYMBOL_GPL(plda_pcie_setup_iomems);
++
++static void plda_pcie_irq_domain_deinit(struct plda_pcie_rp *pcie)
++{
++ irq_set_chained_handler_and_data(pcie->irq, NULL, NULL);
++ irq_set_chained_handler_and_data(pcie->msi_irq, NULL, NULL);
++ irq_set_chained_handler_and_data(pcie->intx_irq, NULL, NULL);
++
++ irq_domain_remove(pcie->msi.msi_domain);
++ irq_domain_remove(pcie->msi.dev_domain);
++
++ irq_domain_remove(pcie->intx_domain);
++ irq_domain_remove(pcie->event_domain);
++}
++
++int plda_pcie_host_init(struct plda_pcie_rp *port, struct pci_ops *ops,
++ const struct plda_event *plda_event)
++{
++ struct device *dev = port->dev;
++ struct pci_host_bridge *bridge;
++ struct platform_device *pdev = to_platform_device(dev);
++ struct resource *cfg_res;
++ int ret;
++
++ pdev = to_platform_device(dev);
++
++ port->bridge_addr =
++ devm_platform_ioremap_resource_byname(pdev, "apb");
++
++ if (IS_ERR(port->bridge_addr))
++ return dev_err_probe(dev, PTR_ERR(port->bridge_addr),
++ "failed to map reg memory\n");
++
++ cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg");
++ if (!cfg_res)
++ return dev_err_probe(dev, -ENODEV,
++ "failed to get config memory\n");
++
++ port->config_base = devm_ioremap_resource(dev, cfg_res);
++ if (IS_ERR(port->config_base))
++ return dev_err_probe(dev, PTR_ERR(port->config_base),
++ "failed to map config memory\n");
++
++ bridge = devm_pci_alloc_host_bridge(dev, 0);
++ if (!bridge)
++ return dev_err_probe(dev, -ENOMEM,
++ "failed to alloc bridge\n");
++
++ if (port->host_ops && port->host_ops->host_init) {
++ ret = port->host_ops->host_init(port);
++ if (ret)
++ return ret;
++ }
++
++ port->bridge = bridge;
++ plda_pcie_setup_window(port->bridge_addr, 0, cfg_res->start, 0,
++ resource_size(cfg_res));
++ plda_pcie_setup_iomems(bridge, port);
++ plda_set_default_msi(&port->msi);
++ ret = plda_init_interrupts(pdev, port, plda_event);
++ if (ret)
++ goto err_host;
++
++ /* Set default bus ops */
++ bridge->ops = ops;
++ bridge->sysdata = port;
++
++ ret = pci_host_probe(bridge);
++ if (ret < 0) {
++ dev_err_probe(dev, ret, "failed to probe pci host\n");
++ goto err_probe;
++ }
++
++ return ret;
++
++err_probe:
++ plda_pcie_irq_domain_deinit(port);
++err_host:
++ if (port->host_ops && port->host_ops->host_deinit)
++ port->host_ops->host_deinit(port);
++
++ return ret;
++}
++EXPORT_SYMBOL_GPL(plda_pcie_host_init);
++
++void plda_pcie_host_deinit(struct plda_pcie_rp *port)
++{
++ pci_stop_root_bus(port->bridge->bus);
++ pci_remove_root_bus(port->bridge->bus);
++
++ plda_pcie_irq_domain_deinit(port);
++
++ if (port->host_ops && port->host_ops->host_deinit)
++ port->host_ops->host_deinit(port);
++}
++EXPORT_SYMBOL_GPL(plda_pcie_host_deinit);
+--- a/drivers/pci/controller/plda/pcie-plda.h
++++ b/drivers/pci/controller/plda/pcie-plda.h
+@@ -141,6 +141,11 @@ struct plda_event_ops {
+ u32 (*get_events)(struct plda_pcie_rp *pcie);
+ };
+
++struct plda_pcie_host_ops {
++ int (*host_init)(struct plda_pcie_rp *pcie);
++ void (*host_deinit)(struct plda_pcie_rp *pcie);
++};
++
+ struct plda_msi {
+ struct mutex lock; /* Protect used bitmap */
+ struct irq_domain *msi_domain;
+@@ -152,14 +157,20 @@ struct plda_msi {
+
+ struct plda_pcie_rp {
+ struct device *dev;
++ struct pci_host_bridge *bridge;
+ struct irq_domain *intx_domain;
+ struct irq_domain *event_domain;
+ raw_spinlock_t lock;
+ struct plda_msi msi;
+ const struct plda_event_ops *event_ops;
+ const struct irq_chip *event_irq_chip;
++ const struct plda_pcie_host_ops *host_ops;
+ void __iomem *bridge_addr;
++ void __iomem *config_base;
+ unsigned long events_bitmap;
++ int irq;
++ int msi_irq;
++ int intx_irq;
+ int num_events;
+ };
+
+@@ -170,6 +181,8 @@ struct plda_event {
+ int msi_event;
+ };
+
++void __iomem *plda_pcie_map_bus(struct pci_bus *bus, unsigned int devfn,
++ int where);
+ int plda_init_interrupts(struct platform_device *pdev,
+ struct plda_pcie_rp *port,
+ const struct plda_event *event);
+@@ -178,4 +191,13 @@ void plda_pcie_setup_window(void __iomem
+ size_t size);
+ int plda_pcie_setup_iomems(struct pci_host_bridge *bridge,
+ struct plda_pcie_rp *port);
++int plda_pcie_host_init(struct plda_pcie_rp *port, struct pci_ops *ops,
++ const struct plda_event *plda_event);
++void plda_pcie_host_deinit(struct plda_pcie_rp *pcie);
++
++static inline void plda_set_default_msi(struct plda_msi *msi)
++{
++ msi->vector_phy = IMSI_ADDR;
++ msi->num_vectors = PLDA_MAX_NUM_MSI_IRQS;
++}
+ #endif
diff --git a/target/linux/starfive/patches-6.6/0032-dt-bindings-PCI-Add-StarFive-JH7110-PCIe-controller.patch b/target/linux/starfive/patches-6.6/0032-dt-bindings-PCI-Add-StarFive-JH7110-PCIe-controller.patch
new file mode 100644
index 0000000000..9e33f7d68a
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0032-dt-bindings-PCI-Add-StarFive-JH7110-PCIe-controller.patch
@@ -0,0 +1,140 @@
+From bc3f8207d9f0af3cb96a7eae232074a644a175f6 Mon Sep 17 00:00:00 2001
+From: Minda Chen <minda.chen@starfivetech.com>
+Date: Mon, 8 Jan 2024 19:06:09 +0800
+Subject: [PATCH 032/116] dt-bindings: PCI: Add StarFive JH7110 PCIe controller
+
+Add StarFive JH7110 SoC PCIe controller dt-bindings. JH7110 using PLDA
+XpressRICH PCIe host controller IP.
+
+Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
+Reviewed-by: Hal Feng <hal.feng@starfivetech.com>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+Reviewed-by: Rob Herring <robh@kernel.org>
+---
+ .../bindings/pci/starfive,jh7110-pcie.yaml | 120 ++++++++++++++++++
+ 1 file changed, 120 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/pci/starfive,jh7110-pcie.yaml
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/pci/starfive,jh7110-pcie.yaml
+@@ -0,0 +1,120 @@
++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/pci/starfive,jh7110-pcie.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: StarFive JH7110 PCIe host controller
++
++maintainers:
++ - Kevin Xie <kevin.xie@starfivetech.com>
++
++allOf:
++ - $ref: plda,xpressrich3-axi-common.yaml#
++
++properties:
++ compatible:
++ const: starfive,jh7110-pcie
++
++ clocks:
++ items:
++ - description: NOC bus clock
++ - description: Transport layer clock
++ - description: AXI MST0 clock
++ - description: APB clock
++
++ clock-names:
++ items:
++ - const: noc
++ - const: tl
++ - const: axi_mst0
++ - const: apb
++
++ resets:
++ items:
++ - description: AXI MST0 reset
++ - description: AXI SLAVE0 reset
++ - description: AXI SLAVE reset
++ - description: PCIE BRIDGE reset
++ - description: PCIE CORE reset
++ - description: PCIE APB reset
++
++ reset-names:
++ items:
++ - const: mst0
++ - const: slv0
++ - const: slv
++ - const: brg
++ - const: core
++ - const: apb
++
++ starfive,stg-syscon:
++ $ref: /schemas/types.yaml#/definitions/phandle-array
++ description:
++ The phandle to System Register Controller syscon node.
++
++ perst-gpios:
++ description: GPIO controlled connection to PERST# signal
++ maxItems: 1
++
++ phys:
++ description:
++ Specified PHY is attached to PCIe controller.
++ maxItems: 1
++
++required:
++ - clocks
++ - resets
++ - starfive,stg-syscon
++
++unevaluatedProperties: false
++
++examples:
++ - |
++ #include <dt-bindings/gpio/gpio.h>
++ soc {
++ #address-cells = <2>;
++ #size-cells = <2>;
++
++ pcie@940000000 {
++ compatible = "starfive,jh7110-pcie";
++ reg = <0x9 0x40000000 0x0 0x10000000>,
++ <0x0 0x2b000000 0x0 0x1000000>;
++ reg-names = "cfg", "apb";
++ #address-cells = <3>;
++ #size-cells = <2>;
++ #interrupt-cells = <1>;
++ device_type = "pci";
++ ranges = <0x82000000 0x0 0x30000000 0x0 0x30000000 0x0 0x08000000>,
++ <0xc3000000 0x9 0x00000000 0x9 0x00000000 0x0 0x40000000>;
++ starfive,stg-syscon = <&stg_syscon>;
++ bus-range = <0x0 0xff>;
++ interrupt-parent = <&plic>;
++ interrupts = <56>;
++ interrupt-map-mask = <0x0 0x0 0x0 0x7>;
++ interrupt-map = <0x0 0x0 0x0 0x1 &pcie_intc0 0x1>,
++ <0x0 0x0 0x0 0x2 &pcie_intc0 0x2>,
++ <0x0 0x0 0x0 0x3 &pcie_intc0 0x3>,
++ <0x0 0x0 0x0 0x4 &pcie_intc0 0x4>;
++ msi-controller;
++ clocks = <&syscrg 86>,
++ <&stgcrg 10>,
++ <&stgcrg 8>,
++ <&stgcrg 9>;
++ clock-names = "noc", "tl", "axi_mst0", "apb";
++ resets = <&stgcrg 11>,
++ <&stgcrg 12>,
++ <&stgcrg 13>,
++ <&stgcrg 14>,
++ <&stgcrg 15>,
++ <&stgcrg 16>;
++ perst-gpios = <&gpios 26 GPIO_ACTIVE_LOW>;
++ phys = <&pciephy0>;
++
++ pcie_intc0: interrupt-controller {
++ #address-cells = <0>;
++ #interrupt-cells = <1>;
++ interrupt-controller;
++ };
++ };
++ };
diff --git a/target/linux/starfive/patches-6.6/0033-PCI-Add-PCIE_RESET_CONFIG_DEVICE_WAIT_MS-waiting-tim.patch b/target/linux/starfive/patches-6.6/0033-PCI-Add-PCIE_RESET_CONFIG_DEVICE_WAIT_MS-waiting-tim.patch
new file mode 100644
index 0000000000..cc50dfe68e
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0033-PCI-Add-PCIE_RESET_CONFIG_DEVICE_WAIT_MS-waiting-tim.patch
@@ -0,0 +1,55 @@
+From abb20b7b8f5e3a7f36dbd6264e6d346275434154 Mon Sep 17 00:00:00 2001
+From: Kevin Xie <kevin.xie@starfivetech.com>
+Date: Mon, 8 Jan 2024 19:06:10 +0800
+Subject: [PATCH 033/116] PCI: Add PCIE_RESET_CONFIG_DEVICE_WAIT_MS waiting
+ time value
+
+Add the PCIE_RESET_CONFIG_DEVICE_WAIT_MS macro to define the minimum
+waiting time between exit from a conventional reset and sending the
+first configuration request to the device.
+
+As described in PCI base specification r6.0, section 6.6.1 <Conventional
+Reset>, there are two different use cases of the value:
+
+ - "With a Downstream Port that does not support Link speeds greater
+ than 5.0 GT/s, software must wait a minimum of 100 ms following exit
+ from a Conventional Reset before sending a Configuration Request to
+ the device immediately below that Port."
+
+ - "With a Downstream Port that supports Link speeds greater than
+ 5.0 GT/s, software must wait a minimum of 100 ms after Link training
+ completes before sending a Configuration Request to the device
+ immediately below that Port."
+
+Signed-off-by: Kevin Xie <kevin.xie@starfivetech.com>
+Reviewed-by: Mason Huo <mason.huo@starfivetech.com>
+Acked-by: Bjorn Helgaas <bhelgaas@google.com>
+---
+ drivers/pci/pci.h | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+--- a/drivers/pci/pci.h
++++ b/drivers/pci/pci.h
+@@ -19,6 +19,22 @@
+ */
+ #define PCIE_PME_TO_L2_TIMEOUT_US 10000
+
++/*
++ * As described in PCI base specification r6.0, section 6.6.1 <Conventional
++ * Reset>, there are two different use cases of the value:
++ *
++ * - "With a Downstream Port that does not support Link speeds greater
++ * than 5.0 GT/s, software must wait a minimum of 100 ms following exit
++ * from a Conventional Reset before sending a Configuration Request to
++ * the device immediately below that Port."
++ *
++ * - "With a Downstream Port that supports Link speeds greater than
++ * 5.0 GT/s, software must wait a minimum of 100 ms after Link training
++ * completes before sending a Configuration Request to the device
++ * immediately below that Port."
++ */
++#define PCIE_RESET_CONFIG_DEVICE_WAIT_MS 100
++
+ extern const unsigned char pcie_link_speed[];
+ extern bool pci_early_dump;
+
diff --git a/target/linux/starfive/patches-6.6/0034-PCI-starfive-Add-JH7110-PCIe-controller.patch b/target/linux/starfive/patches-6.6/0034-PCI-starfive-Add-JH7110-PCIe-controller.patch
new file mode 100644
index 0000000000..45a549f489
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0034-PCI-starfive-Add-JH7110-PCIe-controller.patch
@@ -0,0 +1,623 @@
+From 323aedef34315b758dc30ba23e2cabca259bb4b2 Mon Sep 17 00:00:00 2001
+From: Minda Chen <minda.chen@starfivetech.com>
+Date: Mon, 8 Jan 2024 19:06:11 +0800
+Subject: [PATCH 034/116] PCI: starfive: Add JH7110 PCIe controller
+
+Add StarFive JH7110 SoC PCIe controller platform driver codes, JH7110
+with PLDA host PCIe core.
+
+Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
+Co-developed-by: Kevin Xie <kevin.xie@starfivetech.com>
+Reviewed-by: Mason Huo <mason.huo@starfivetech.com>
+---
+ drivers/pci/controller/plda/Kconfig | 12 +
+ drivers/pci/controller/plda/Makefile | 1 +
+ drivers/pci/controller/plda/pcie-plda.h | 71 ++-
+ drivers/pci/controller/plda/pcie-starfive.c | 473 ++++++++++++++++++++
+ 4 files changed, 556 insertions(+), 1 deletion(-)
+ create mode 100644 drivers/pci/controller/plda/pcie-starfive.c
+
+--- a/drivers/pci/controller/plda/Kconfig
++++ b/drivers/pci/controller/plda/Kconfig
+@@ -15,4 +15,16 @@ config PCIE_MICROCHIP_HOST
+ Say Y here if you want kernel to support the Microchip AXI PCIe
+ Host Bridge driver.
+
++config PCIE_STARFIVE_HOST
++ tristate "StarFive PCIe host controller"
++ depends on PCI_MSI && OF
++ depends on ARCH_STARFIVE || COMPILE_TEST
++ select PCIE_PLDA_HOST
++ help
++ Say Y here if you want to support the StarFive PCIe controller in
++ host mode. StarFive PCIe controller uses PLDA PCIe core.
++
++ If you choose to build this driver as module it will be dynamically
++ linked and module will be called pcie-starfive.ko.
++
+ endmenu
+--- a/drivers/pci/controller/plda/Makefile
++++ b/drivers/pci/controller/plda/Makefile
+@@ -1,3 +1,4 @@
+ # SPDX-License-Identifier: GPL-2.0
+ obj-$(CONFIG_PCIE_PLDA_HOST) += pcie-plda-host.o
+ obj-$(CONFIG_PCIE_MICROCHIP_HOST) += pcie-microchip-host.o
++obj-$(CONFIG_PCIE_STARFIVE_HOST) += pcie-starfive.o
+--- a/drivers/pci/controller/plda/pcie-plda.h
++++ b/drivers/pci/controller/plda/pcie-plda.h
+@@ -10,10 +10,20 @@
+ #define PLDA_MAX_NUM_MSI_IRQS 32
+
+ /* PCIe Bridge Phy Regs */
++#define GEN_SETTINGS 0x80
++#define RP_ENABLE 1
++#define PCIE_PCI_IDS_DW1 0x9c
++#define IDS_CLASS_CODE_SHIFT 16
++#define REVISION_ID_MASK GENMASK(7, 0)
++#define CLASS_CODE_ID_MASK GENMASK(31, 8)
+ #define PCIE_PCI_IRQ_DW0 0xa8
+ #define MSIX_CAP_MASK BIT(31)
+ #define NUM_MSI_MSGS_MASK GENMASK(6, 4)
+ #define NUM_MSI_MSGS_SHIFT 4
++#define PCI_MISC 0xb4
++#define PHY_FUNCTION_DIS BIT(15)
++#define PCIE_WINROM 0xfc
++#define PREF_MEM_WIN_64_SUPPORT BIT(3)
+
+ #define IMASK_LOCAL 0x180
+ #define DMA_END_ENGINE_0_MASK 0x00000000u
+@@ -65,6 +75,8 @@
+ #define ISTATUS_HOST 0x18c
+ #define IMSI_ADDR 0x190
+ #define ISTATUS_MSI 0x194
++#define PMSG_SUPPORT_RX 0x3f0
++#define PMSG_LTR_SUPPORT BIT(2)
+
+ /* PCIe Master table init defines */
+ #define ATR0_PCIE_WIN0_SRCADDR_PARAM 0x600u
+@@ -86,6 +98,8 @@
+ #define PCIE_TX_RX_INTERFACE 0x00000000u
+ #define PCIE_CONFIG_INTERFACE 0x00000001u
+
++#define CONFIG_SPACE_ADDR_OFFSET 0x1000u
++
+ #define ATR_ENTRY_SIZE 32
+
+ enum plda_int_event {
+@@ -200,4 +214,59 @@ static inline void plda_set_default_msi(
+ msi->vector_phy = IMSI_ADDR;
+ msi->num_vectors = PLDA_MAX_NUM_MSI_IRQS;
+ }
+-#endif
++
++static inline void plda_pcie_enable_root_port(struct plda_pcie_rp *plda)
++{
++ u32 value;
++
++ value = readl_relaxed(plda->bridge_addr + GEN_SETTINGS);
++ value |= RP_ENABLE;
++ writel_relaxed(value, plda->bridge_addr + GEN_SETTINGS);
++}
++
++static inline void plda_pcie_set_standard_class(struct plda_pcie_rp *plda)
++{
++ u32 value;
++
++ /* set class code and reserve revision id */
++ value = readl_relaxed(plda->bridge_addr + PCIE_PCI_IDS_DW1);
++ value &= REVISION_ID_MASK;
++ value |= (PCI_CLASS_BRIDGE_PCI << IDS_CLASS_CODE_SHIFT);
++ writel_relaxed(value, plda->bridge_addr + PCIE_PCI_IDS_DW1);
++}
++
++static inline void plda_pcie_set_pref_win_64bit(struct plda_pcie_rp *plda)
++{
++ u32 value;
++
++ value = readl_relaxed(plda->bridge_addr + PCIE_WINROM);
++ value |= PREF_MEM_WIN_64_SUPPORT;
++ writel_relaxed(value, plda->bridge_addr + PCIE_WINROM);
++}
++
++static inline void plda_pcie_disable_ltr(struct plda_pcie_rp *plda)
++{
++ u32 value;
++
++ value = readl_relaxed(plda->bridge_addr + PMSG_SUPPORT_RX);
++ value &= ~PMSG_LTR_SUPPORT;
++ writel_relaxed(value, plda->bridge_addr + PMSG_SUPPORT_RX);
++}
++
++static inline void plda_pcie_disable_func(struct plda_pcie_rp *plda)
++{
++ u32 value;
++
++ value = readl_relaxed(plda->bridge_addr + PCI_MISC);
++ value |= PHY_FUNCTION_DIS;
++ writel_relaxed(value, plda->bridge_addr + PCI_MISC);
++}
++
++static inline void plda_pcie_write_rc_bar(struct plda_pcie_rp *plda, u64 val)
++{
++ void __iomem *addr = plda->bridge_addr + CONFIG_SPACE_ADDR_OFFSET;
++
++ writel_relaxed(lower_32_bits(val), addr + PCI_BASE_ADDRESS_0);
++ writel_relaxed(upper_32_bits(val), addr + PCI_BASE_ADDRESS_1);
++}
++#endif /* _PCIE_PLDA_H */
+--- /dev/null
++++ b/drivers/pci/controller/plda/pcie-starfive.c
+@@ -0,0 +1,473 @@
++// SPDX-License-Identifier: GPL-2.0+
++/*
++ * PCIe host controller driver for StarFive JH7110 Soc.
++ *
++ * Copyright (C) 2023 StarFive Technology Co., Ltd.
++ */
++
++#include <linux/bitfield.h>
++#include <linux/clk.h>
++#include <linux/delay.h>
++#include <linux/gpio/consumer.h>
++#include <linux/interrupt.h>
++#include <linux/kernel.h>
++#include <linux/mfd/syscon.h>
++#include <linux/module.h>
++#include <linux/of_address.h>
++#include <linux/of_irq.h>
++#include <linux/of_pci.h>
++#include <linux/pci.h>
++#include <linux/phy/phy.h>
++#include <linux/platform_device.h>
++#include <linux/pm_runtime.h>
++#include <linux/regmap.h>
++#include <linux/reset.h>
++#include "../../pci.h"
++
++#include "pcie-plda.h"
++
++#define PCIE_FUNC_NUM 4
++
++/* system control */
++#define STG_SYSCON_PCIE0_BASE 0x48
++#define STG_SYSCON_PCIE1_BASE 0x1f8
++
++#define STG_SYSCON_AR_OFFSET 0x78
++#define STG_SYSCON_AXI4_SLVL_AR_MASK GENMASK(22, 8)
++#define STG_SYSCON_AXI4_SLVL_PHY_AR(x) FIELD_PREP(GENMASK(20, 17), x)
++#define STG_SYSCON_AW_OFFSET 0x7c
++#define STG_SYSCON_AXI4_SLVL_AW_MASK GENMASK(14, 0)
++#define STG_SYSCON_AXI4_SLVL_PHY_AW(x) FIELD_PREP(GENMASK(12, 9), x)
++#define STG_SYSCON_CLKREQ BIT(22)
++#define STG_SYSCON_CKREF_SRC_MASK GENMASK(19, 18)
++#define STG_SYSCON_RP_NEP_OFFSET 0xe8
++#define STG_SYSCON_K_RP_NEP BIT(8)
++#define STG_SYSCON_LNKSTA_OFFSET 0x170
++#define DATA_LINK_ACTIVE BIT(5)
++
++/* Parameters for the waiting for link up routine */
++#define LINK_WAIT_MAX_RETRIES 10
++#define LINK_WAIT_USLEEP_MIN 90000
++#define LINK_WAIT_USLEEP_MAX 100000
++
++struct starfive_jh7110_pcie {
++ struct plda_pcie_rp plda;
++ struct reset_control *resets;
++ struct clk_bulk_data *clks;
++ struct regmap *reg_syscon;
++ struct gpio_desc *power_gpio;
++ struct gpio_desc *reset_gpio;
++ struct phy *phy;
++
++ unsigned int stg_pcie_base;
++ int num_clks;
++};
++
++/*
++ * The BAR0/1 of bridge should be hidden during enumeration to
++ * avoid the sizing and resource allocation by PCIe core.
++ */
++static bool starfive_pcie_hide_rc_bar(struct pci_bus *bus, unsigned int devfn,
++ int offset)
++{
++ if (pci_is_root_bus(bus) && !devfn &&
++ (offset == PCI_BASE_ADDRESS_0 || offset == PCI_BASE_ADDRESS_1))
++ return true;
++
++ return false;
++}
++
++static int starfive_pcie_config_write(struct pci_bus *bus, unsigned int devfn,
++ int where, int size, u32 value)
++{
++ if (starfive_pcie_hide_rc_bar(bus, devfn, where))
++ return PCIBIOS_SUCCESSFUL;
++
++ return pci_generic_config_write(bus, devfn, where, size, value);
++}
++
++static int starfive_pcie_config_read(struct pci_bus *bus, unsigned int devfn,
++ int where, int size, u32 *value)
++{
++ if (starfive_pcie_hide_rc_bar(bus, devfn, where)) {
++ *value = 0;
++ return PCIBIOS_SUCCESSFUL;
++ }
++
++ return pci_generic_config_read(bus, devfn, where, size, value);
++}
++
++static int starfive_pcie_parse_dt(struct starfive_jh7110_pcie *pcie,
++ struct device *dev)
++{
++ int domain_nr;
++
++ pcie->num_clks = devm_clk_bulk_get_all(dev, &pcie->clks);
++ if (pcie->num_clks < 0)
++ return dev_err_probe(dev, pcie->num_clks,
++ "failed to get pcie clocks\n");
++
++ pcie->resets = devm_reset_control_array_get_exclusive(dev);
++ if (IS_ERR(pcie->resets))
++ return dev_err_probe(dev, PTR_ERR(pcie->resets),
++ "failed to get pcie resets");
++
++ pcie->reg_syscon =
++ syscon_regmap_lookup_by_phandle(dev->of_node,
++ "starfive,stg-syscon");
++
++ if (IS_ERR(pcie->reg_syscon))
++ return dev_err_probe(dev, PTR_ERR(pcie->reg_syscon),
++ "failed to parse starfive,stg-syscon\n");
++
++ pcie->phy = devm_phy_optional_get(dev, NULL);
++ if (IS_ERR(pcie->phy))
++ return dev_err_probe(dev, PTR_ERR(pcie->phy),
++ "failed to get pcie phy\n");
++
++ domain_nr = of_get_pci_domain_nr(dev->of_node);
++
++ if (domain_nr < 0 || domain_nr > 1)
++ return dev_err_probe(dev, -ENODEV,
++ "failed to get valid pcie domain\n");
++
++ if (domain_nr == 0)
++ pcie->stg_pcie_base = STG_SYSCON_PCIE0_BASE;
++ else
++ pcie->stg_pcie_base = STG_SYSCON_PCIE1_BASE;
++
++ pcie->reset_gpio = devm_gpiod_get_optional(dev, "perst",
++ GPIOD_OUT_HIGH);
++ if (IS_ERR(pcie->reset_gpio))
++ return dev_err_probe(dev, PTR_ERR(pcie->reset_gpio),
++ "failed to get perst-gpio\n");
++
++ pcie->power_gpio = devm_gpiod_get_optional(dev, "enable",
++ GPIOD_OUT_LOW);
++ if (IS_ERR(pcie->power_gpio))
++ return dev_err_probe(dev, PTR_ERR(pcie->power_gpio),
++ "failed to get power-gpio\n");
++
++ return 0;
++}
++
++static struct pci_ops starfive_pcie_ops = {
++ .map_bus = plda_pcie_map_bus,
++ .read = starfive_pcie_config_read,
++ .write = starfive_pcie_config_write,
++};
++
++static int starfive_pcie_clk_rst_init(struct starfive_jh7110_pcie *pcie)
++{
++ struct device *dev = pcie->plda.dev;
++ int ret;
++
++ ret = clk_bulk_prepare_enable(pcie->num_clks, pcie->clks);
++ if (ret)
++ return dev_err_probe(dev, ret, "failed to enable clocks\n");
++
++ ret = reset_control_deassert(pcie->resets);
++ if (ret) {
++ clk_bulk_disable_unprepare(pcie->num_clks, pcie->clks);
++ dev_err_probe(dev, ret, "failed to deassert resets\n");
++ }
++
++ return ret;
++}
++
++static void starfive_pcie_clk_rst_deinit(struct starfive_jh7110_pcie *pcie)
++{
++ reset_control_assert(pcie->resets);
++ clk_bulk_disable_unprepare(pcie->num_clks, pcie->clks);
++}
++
++static bool starfive_pcie_link_up(struct plda_pcie_rp *plda)
++{
++ struct starfive_jh7110_pcie *pcie =
++ container_of(plda, struct starfive_jh7110_pcie, plda);
++ int ret;
++ u32 stg_reg_val;
++
++ ret = regmap_read(pcie->reg_syscon,
++ pcie->stg_pcie_base + STG_SYSCON_LNKSTA_OFFSET,
++ &stg_reg_val);
++ if (ret) {
++ dev_err(pcie->plda.dev, "failed to read link status\n");
++ return false;
++ }
++
++ return !!(stg_reg_val & DATA_LINK_ACTIVE);
++}
++
++static int starfive_pcie_host_wait_for_link(struct starfive_jh7110_pcie *pcie)
++{
++ int retries;
++
++ /* Check if the link is up or not */
++ for (retries = 0; retries < LINK_WAIT_MAX_RETRIES; retries++) {
++ if (starfive_pcie_link_up(&pcie->plda)) {
++ dev_info(pcie->plda.dev, "port link up\n");
++ return 0;
++ }
++ usleep_range(LINK_WAIT_USLEEP_MIN, LINK_WAIT_USLEEP_MAX);
++ }
++
++ return -ETIMEDOUT;
++}
++
++static int starfive_pcie_enable_phy(struct device *dev,
++ struct starfive_jh7110_pcie *pcie)
++{
++ int ret;
++
++ if (!pcie->phy)
++ return 0;
++
++ ret = phy_init(pcie->phy);
++ if (ret)
++ return dev_err_probe(dev, ret,
++ "failed to initialize pcie phy\n");
++
++ ret = phy_set_mode(pcie->phy, PHY_MODE_PCIE);
++ if (ret) {
++ dev_err_probe(dev, ret, "failed to set pcie mode\n");
++ goto err_phy_on;
++ }
++
++ ret = phy_power_on(pcie->phy);
++ if (ret) {
++ dev_err_probe(dev, ret, "failed to power on pcie phy\n");
++ goto err_phy_on;
++ }
++
++ return 0;
++
++err_phy_on:
++ phy_exit(pcie->phy);
++ return ret;
++}
++
++static void starfive_pcie_disable_phy(struct starfive_jh7110_pcie *pcie)
++{
++ phy_power_off(pcie->phy);
++ phy_exit(pcie->phy);
++}
++
++static void starfive_pcie_host_deinit(struct plda_pcie_rp *plda)
++{
++ struct starfive_jh7110_pcie *pcie =
++ container_of(plda, struct starfive_jh7110_pcie, plda);
++
++ starfive_pcie_clk_rst_deinit(pcie);
++ if (pcie->power_gpio)
++ gpiod_set_value_cansleep(pcie->power_gpio, 0);
++ starfive_pcie_disable_phy(pcie);
++}
++
++static int starfive_pcie_host_init(struct plda_pcie_rp *plda)
++{
++ struct starfive_jh7110_pcie *pcie =
++ container_of(plda, struct starfive_jh7110_pcie, plda);
++ struct device *dev = plda->dev;
++ int ret;
++ int i;
++
++ ret = starfive_pcie_enable_phy(dev, pcie);
++ if (ret)
++ return ret;
++
++ regmap_update_bits(pcie->reg_syscon,
++ pcie->stg_pcie_base + STG_SYSCON_RP_NEP_OFFSET,
++ STG_SYSCON_K_RP_NEP, STG_SYSCON_K_RP_NEP);
++
++ regmap_update_bits(pcie->reg_syscon,
++ pcie->stg_pcie_base + STG_SYSCON_AW_OFFSET,
++ STG_SYSCON_CKREF_SRC_MASK,
++ FIELD_PREP(STG_SYSCON_CKREF_SRC_MASK, 2));
++
++ regmap_update_bits(pcie->reg_syscon,
++ pcie->stg_pcie_base + STG_SYSCON_AW_OFFSET,
++ STG_SYSCON_CLKREQ, STG_SYSCON_CLKREQ);
++
++ ret = starfive_pcie_clk_rst_init(pcie);
++ if (ret)
++ return ret;
++
++ if (pcie->power_gpio)
++ gpiod_set_value_cansleep(pcie->power_gpio, 1);
++
++ if (pcie->reset_gpio)
++ gpiod_set_value_cansleep(pcie->reset_gpio, 1);
++
++ /* Disable physical functions except #0 */
++ for (i = 1; i < PCIE_FUNC_NUM; i++) {
++ regmap_update_bits(pcie->reg_syscon,
++ pcie->stg_pcie_base + STG_SYSCON_AR_OFFSET,
++ STG_SYSCON_AXI4_SLVL_AR_MASK,
++ STG_SYSCON_AXI4_SLVL_PHY_AR(i));
++
++ regmap_update_bits(pcie->reg_syscon,
++ pcie->stg_pcie_base + STG_SYSCON_AW_OFFSET,
++ STG_SYSCON_AXI4_SLVL_AW_MASK,
++ STG_SYSCON_AXI4_SLVL_PHY_AW(i));
++
++ plda_pcie_disable_func(plda);
++ }
++
++ regmap_update_bits(pcie->reg_syscon,
++ pcie->stg_pcie_base + STG_SYSCON_AR_OFFSET,
++ STG_SYSCON_AXI4_SLVL_AR_MASK, 0);
++ regmap_update_bits(pcie->reg_syscon,
++ pcie->stg_pcie_base + STG_SYSCON_AW_OFFSET,
++ STG_SYSCON_AXI4_SLVL_AW_MASK, 0);
++
++ plda_pcie_enable_root_port(plda);
++ plda_pcie_write_rc_bar(plda, 0);
++
++ /* PCIe PCI Standard Configuration Identification Settings. */
++ plda_pcie_set_standard_class(plda);
++
++ /*
++ * The LTR message forwarding of PCIe Message Reception was set by core
++ * as default, but the forward id & addr are also need to be reset.
++ * If we do not disable LTR message forwarding here, or set a legal
++ * forwarding address, the kernel will get stuck after the driver probe.
++ * To workaround, disable the LTR message forwarding support on
++ * PCIe Message Reception.
++ */
++ plda_pcie_disable_ltr(plda);
++
++ /* Prefetchable memory window 64-bit addressing support */
++ plda_pcie_set_pref_win_64bit(plda);
++
++ /*
++ * Ensure that PERST has been asserted for at least 100 ms,
++ * the sleep value is T_PVPERL from PCIe CEM spec r2.0 (Table 2-4)
++ */
++ msleep(100);
++ if (pcie->reset_gpio)
++ gpiod_set_value_cansleep(pcie->reset_gpio, 0);
++
++ /*
++ * With a Downstream Port (<=5GT/s), software must wait a minimum
++ * of 100ms following exit from a conventional reset before
++ * sending a configuration request to the device.
++ */
++ msleep(PCIE_RESET_CONFIG_DEVICE_WAIT_MS);
++
++ if (starfive_pcie_host_wait_for_link(pcie))
++ dev_info(dev, "port link down\n");
++
++ return 0;
++}
++
++static const struct plda_pcie_host_ops sf_host_ops = {
++ .host_init = starfive_pcie_host_init,
++ .host_deinit = starfive_pcie_host_deinit,
++};
++
++static const struct plda_event stf_pcie_event = {
++ .intx_event = EVENT_PM_MSI_INT_INTX,
++ .msi_event = EVENT_PM_MSI_INT_MSI
++};
++
++static int starfive_pcie_probe(struct platform_device *pdev)
++{
++ struct starfive_jh7110_pcie *pcie;
++ struct device *dev = &pdev->dev;
++ struct plda_pcie_rp *plda;
++ int ret;
++
++ pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
++ if (!pcie)
++ return -ENOMEM;
++
++ plda = &pcie->plda;
++ plda->dev = dev;
++
++ ret = starfive_pcie_parse_dt(pcie, dev);
++ if (ret)
++ return ret;
++
++ plda->host_ops = &sf_host_ops;
++ plda->num_events = PLDA_MAX_EVENT_NUM;
++ /* mask doorbell event */
++ plda->events_bitmap = GENMASK(PLDA_INT_EVENT_NUM - 1, 0)
++ & ~BIT(PLDA_AXI_DOORBELL)
++ & ~BIT(PLDA_PCIE_DOORBELL);
++ plda->events_bitmap <<= PLDA_NUM_DMA_EVENTS;
++ ret = plda_pcie_host_init(&pcie->plda, &starfive_pcie_ops,
++ &stf_pcie_event);
++ if (ret)
++ return ret;
++
++ pm_runtime_enable(&pdev->dev);
++ pm_runtime_get_sync(&pdev->dev);
++ platform_set_drvdata(pdev, pcie);
++
++ return 0;
++}
++
++static void starfive_pcie_remove(struct platform_device *pdev)
++{
++ struct starfive_jh7110_pcie *pcie = platform_get_drvdata(pdev);
++
++ pm_runtime_put(&pdev->dev);
++ pm_runtime_disable(&pdev->dev);
++ plda_pcie_host_deinit(&pcie->plda);
++ platform_set_drvdata(pdev, NULL);
++}
++
++static int starfive_pcie_suspend_noirq(struct device *dev)
++{
++ struct starfive_jh7110_pcie *pcie = dev_get_drvdata(dev);
++
++ clk_bulk_disable_unprepare(pcie->num_clks, pcie->clks);
++ starfive_pcie_disable_phy(pcie);
++
++ return 0;
++}
++
++static int starfive_pcie_resume_noirq(struct device *dev)
++{
++ struct starfive_jh7110_pcie *pcie = dev_get_drvdata(dev);
++ int ret;
++
++ ret = starfive_pcie_enable_phy(dev, pcie);
++ if (ret)
++ return ret;
++
++ ret = clk_bulk_prepare_enable(pcie->num_clks, pcie->clks);
++ if (ret) {
++ dev_err(dev, "failed to enable clocks\n");
++ starfive_pcie_disable_phy(pcie);
++ return ret;
++ }
++
++ return 0;
++}
++
++static const struct dev_pm_ops starfive_pcie_pm_ops = {
++ NOIRQ_SYSTEM_SLEEP_PM_OPS(starfive_pcie_suspend_noirq,
++ starfive_pcie_resume_noirq)
++};
++
++static const struct of_device_id starfive_pcie_of_match[] = {
++ { .compatible = "starfive,jh7110-pcie", },
++ { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, starfive_pcie_of_match);
++
++static struct platform_driver starfive_pcie_driver = {
++ .driver = {
++ .name = "pcie-starfive",
++ .of_match_table = of_match_ptr(starfive_pcie_of_match),
++ .pm = pm_sleep_ptr(&starfive_pcie_pm_ops),
++ },
++ .probe = starfive_pcie_probe,
++ .remove_new = starfive_pcie_remove,
++};
++module_platform_driver(starfive_pcie_driver);
++
++MODULE_DESCRIPTION("StarFive JH7110 PCIe host driver");
++MODULE_LICENSE("GPL v2");
diff --git a/target/linux/starfive/patches-6.6/0035-ASoC-dt-bindings-Add-StarFive-JH7110-PWM-DAC-control.patch b/target/linux/starfive/patches-6.6/0035-ASoC-dt-bindings-Add-StarFive-JH7110-PWM-DAC-control.patch
new file mode 100644
index 0000000000..cf14242f4a
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0035-ASoC-dt-bindings-Add-StarFive-JH7110-PWM-DAC-control.patch
@@ -0,0 +1,97 @@
+From a306724fd4f32808d1e27efbd87019d56f60db20 Mon Sep 17 00:00:00 2001
+From: Hal Feng <hal.feng@starfivetech.com>
+Date: Mon, 14 Aug 2023 16:06:16 +0800
+Subject: [PATCH 035/116] ASoC: dt-bindings: Add StarFive JH7110 PWM-DAC
+ controller
+
+Add bindings for the PWM-DAC controller on the JH7110
+RISC-V SoC by StarFive Ltd.
+
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+Link: https://lore.kernel.org/r/20230814080618.10036-2-hal.feng@starfivetech.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+---
+ .../sound/starfive,jh7110-pwmdac.yaml | 76 +++++++++++++++++++
+ 1 file changed, 76 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/sound/starfive,jh7110-pwmdac.yaml
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/sound/starfive,jh7110-pwmdac.yaml
+@@ -0,0 +1,76 @@
++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/sound/starfive,jh7110-pwmdac.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: StarFive JH7110 PWM-DAC Controller
++
++description:
++ The PWM-DAC Controller uses PWM square wave generators plus RC filters to
++ form a DAC for audio play in StarFive JH7110 SoC. This audio play controller
++ supports 16 bit audio format, up to 48K sampling frequency, up to left and
++ right dual channels.
++
++maintainers:
++ - Hal Feng <hal.feng@starfivetech.com>
++
++allOf:
++ - $ref: dai-common.yaml#
++
++properties:
++ compatible:
++ const: starfive,jh7110-pwmdac
++
++ reg:
++ maxItems: 1
++
++ clocks:
++ items:
++ - description: PWMDAC APB
++ - description: PWMDAC CORE
++
++ clock-names:
++ items:
++ - const: apb
++ - const: core
++
++ resets:
++ maxItems: 1
++ description: PWMDAC APB
++
++ dmas:
++ maxItems: 1
++ description: TX DMA Channel
++
++ dma-names:
++ const: tx
++
++ "#sound-dai-cells":
++ const: 0
++
++required:
++ - compatible
++ - reg
++ - clocks
++ - clock-names
++ - resets
++ - dmas
++ - dma-names
++ - "#sound-dai-cells"
++
++additionalProperties: false
++
++examples:
++ - |
++ pwmdac@100b0000 {
++ compatible = "starfive,jh7110-pwmdac";
++ reg = <0x100b0000 0x1000>;
++ clocks = <&syscrg 157>,
++ <&syscrg 158>;
++ clock-names = "apb", "core";
++ resets = <&syscrg 96>;
++ dmas = <&dma 22>;
++ dma-names = "tx";
++ #sound-dai-cells = <0>;
++ };
diff --git a/target/linux/starfive/patches-6.6/0036-ASoC-starfive-Add-JH7110-PWM-DAC-driver.patch b/target/linux/starfive/patches-6.6/0036-ASoC-starfive-Add-JH7110-PWM-DAC-driver.patch
new file mode 100644
index 0000000000..acc859317b
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0036-ASoC-starfive-Add-JH7110-PWM-DAC-driver.patch
@@ -0,0 +1,574 @@
+From a79d2ec524012e35e32a2c4ae2401d0aa763697d Mon Sep 17 00:00:00 2001
+From: Hal Feng <hal.feng@starfivetech.com>
+Date: Mon, 14 Aug 2023 16:06:17 +0800
+Subject: [PATCH 036/116] ASoC: starfive: Add JH7110 PWM-DAC driver
+
+Add PWM-DAC driver support for the StarFive JH7110 SoC.
+
+Reviewed-by: Walker Chen <walker.chen@starfivetech.com>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+Link: https://lore.kernel.org/r/20230814080618.10036-3-hal.feng@starfivetech.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+---
+ sound/soc/starfive/Kconfig | 9 +
+ sound/soc/starfive/Makefile | 1 +
+ sound/soc/starfive/jh7110_pwmdac.c | 529 +++++++++++++++++++++++++++++
+ 3 files changed, 539 insertions(+)
+ create mode 100644 sound/soc/starfive/jh7110_pwmdac.c
+
+--- a/sound/soc/starfive/Kconfig
++++ b/sound/soc/starfive/Kconfig
+@@ -7,6 +7,15 @@ config SND_SOC_STARFIVE
+ the Starfive SoCs' Audio interfaces. You will also need to
+ select the audio interfaces to support below.
+
++config SND_SOC_JH7110_PWMDAC
++ tristate "JH7110 PWM-DAC device driver"
++ depends on HAVE_CLK && SND_SOC_STARFIVE
++ select SND_SOC_GENERIC_DMAENGINE_PCM
++ select SND_SOC_SPDIF
++ help
++ Say Y or M if you want to add support for StarFive JH7110
++ PWM-DAC driver.
++
+ config SND_SOC_JH7110_TDM
+ tristate "JH7110 TDM device driver"
+ depends on HAVE_CLK && SND_SOC_STARFIVE
+--- a/sound/soc/starfive/Makefile
++++ b/sound/soc/starfive/Makefile
+@@ -1,2 +1,3 @@
+ # StarFive Platform Support
++obj-$(CONFIG_SND_SOC_JH7110_PWMDAC) += jh7110_pwmdac.o
+ obj-$(CONFIG_SND_SOC_JH7110_TDM) += jh7110_tdm.o
+--- /dev/null
++++ b/sound/soc/starfive/jh7110_pwmdac.c
+@@ -0,0 +1,529 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * jh7110_pwmdac.c -- StarFive JH7110 PWM-DAC driver
++ *
++ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
++ *
++ * Authors: Jenny Zhang
++ * Curry Zhang
++ * Xingyu Wu <xingyu.wu@starfivetech.com>
++ * Hal Feng <hal.feng@starfivetech.com>
++ */
++
++#include <linux/clk.h>
++#include <linux/device.h>
++#include <linux/init.h>
++#include <linux/interrupt.h>
++#include <linux/io.h>
++#include <linux/module.h>
++#include <linux/pm_runtime.h>
++#include <linux/reset.h>
++#include <linux/slab.h>
++#include <linux/types.h>
++#include <sound/dmaengine_pcm.h>
++#include <sound/pcm.h>
++#include <sound/pcm_params.h>
++#include <sound/soc.h>
++
++#define JH7110_PWMDAC_WDATA 0x00
++#define JH7110_PWMDAC_CTRL 0x04
++ #define JH7110_PWMDAC_ENABLE BIT(0)
++ #define JH7110_PWMDAC_SHIFT BIT(1)
++ #define JH7110_PWMDAC_DUTY_CYCLE_SHIFT 2
++ #define JH7110_PWMDAC_DUTY_CYCLE_MASK GENMASK(3, 2)
++ #define JH7110_PWMDAC_CNT_N_SHIFT 4
++ #define JH7110_PWMDAC_CNT_N_MASK GENMASK(12, 4)
++ #define JH7110_PWMDAC_DATA_CHANGE BIT(13)
++ #define JH7110_PWMDAC_DATA_MODE BIT(14)
++ #define JH7110_PWMDAC_DATA_SHIFT_SHIFT 15
++ #define JH7110_PWMDAC_DATA_SHIFT_MASK GENMASK(17, 15)
++
++enum JH7110_PWMDAC_SHIFT_VAL {
++ PWMDAC_SHIFT_8 = 0,
++ PWMDAC_SHIFT_10,
++};
++
++enum JH7110_PWMDAC_DUTY_CYCLE_VAL {
++ PWMDAC_CYCLE_LEFT = 0,
++ PWMDAC_CYCLE_RIGHT,
++ PWMDAC_CYCLE_CENTER,
++};
++
++enum JH7110_PWMDAC_CNT_N_VAL {
++ PWMDAC_SAMPLE_CNT_1 = 1,
++ PWMDAC_SAMPLE_CNT_2,
++ PWMDAC_SAMPLE_CNT_3,
++ PWMDAC_SAMPLE_CNT_512 = 512, /* max */
++};
++
++enum JH7110_PWMDAC_DATA_CHANGE_VAL {
++ NO_CHANGE = 0,
++ CHANGE,
++};
++
++enum JH7110_PWMDAC_DATA_MODE_VAL {
++ UNSIGNED_DATA = 0,
++ INVERTER_DATA_MSB,
++};
++
++enum JH7110_PWMDAC_DATA_SHIFT_VAL {
++ PWMDAC_DATA_LEFT_SHIFT_BIT_0 = 0,
++ PWMDAC_DATA_LEFT_SHIFT_BIT_1,
++ PWMDAC_DATA_LEFT_SHIFT_BIT_2,
++ PWMDAC_DATA_LEFT_SHIFT_BIT_3,
++ PWMDAC_DATA_LEFT_SHIFT_BIT_4,
++ PWMDAC_DATA_LEFT_SHIFT_BIT_5,
++ PWMDAC_DATA_LEFT_SHIFT_BIT_6,
++ PWMDAC_DATA_LEFT_SHIFT_BIT_7,
++};
++
++struct jh7110_pwmdac_cfg {
++ enum JH7110_PWMDAC_SHIFT_VAL shift;
++ enum JH7110_PWMDAC_DUTY_CYCLE_VAL duty_cycle;
++ u16 cnt_n;
++ enum JH7110_PWMDAC_DATA_CHANGE_VAL data_change;
++ enum JH7110_PWMDAC_DATA_MODE_VAL data_mode;
++ enum JH7110_PWMDAC_DATA_SHIFT_VAL data_shift;
++};
++
++struct jh7110_pwmdac_dev {
++ void __iomem *base;
++ resource_size_t mapbase;
++ struct jh7110_pwmdac_cfg cfg;
++
++ struct clk_bulk_data clks[2];
++ struct reset_control *rst_apb;
++ struct device *dev;
++ struct snd_dmaengine_dai_dma_data play_dma_data;
++ u32 saved_ctrl;
++};
++
++static inline void jh7110_pwmdac_write_reg(void __iomem *io_base, int reg, u32 val)
++{
++ writel(val, io_base + reg);
++}
++
++static inline u32 jh7110_pwmdac_read_reg(void __iomem *io_base, int reg)
++{
++ return readl(io_base + reg);
++}
++
++static void jh7110_pwmdac_set_enable(struct jh7110_pwmdac_dev *dev, bool enable)
++{
++ u32 value;
++
++ value = jh7110_pwmdac_read_reg(dev->base, JH7110_PWMDAC_CTRL);
++ if (enable)
++ value |= JH7110_PWMDAC_ENABLE;
++ else
++ value &= ~JH7110_PWMDAC_ENABLE;
++
++ jh7110_pwmdac_write_reg(dev->base, JH7110_PWMDAC_CTRL, value);
++}
++
++static void jh7110_pwmdac_set_shift(struct jh7110_pwmdac_dev *dev)
++{
++ u32 value;
++
++ value = jh7110_pwmdac_read_reg(dev->base, JH7110_PWMDAC_CTRL);
++ if (dev->cfg.shift == PWMDAC_SHIFT_8)
++ value &= ~JH7110_PWMDAC_SHIFT;
++ else if (dev->cfg.shift == PWMDAC_SHIFT_10)
++ value |= JH7110_PWMDAC_SHIFT;
++
++ jh7110_pwmdac_write_reg(dev->base, JH7110_PWMDAC_CTRL, value);
++}
++
++static void jh7110_pwmdac_set_duty_cycle(struct jh7110_pwmdac_dev *dev)
++{
++ u32 value;
++
++ value = jh7110_pwmdac_read_reg(dev->base, JH7110_PWMDAC_CTRL);
++ value &= ~JH7110_PWMDAC_DUTY_CYCLE_MASK;
++ value |= (dev->cfg.duty_cycle & 0x3) << JH7110_PWMDAC_DUTY_CYCLE_SHIFT;
++
++ jh7110_pwmdac_write_reg(dev->base, JH7110_PWMDAC_CTRL, value);
++}
++
++static void jh7110_pwmdac_set_cnt_n(struct jh7110_pwmdac_dev *dev)
++{
++ u32 value;
++
++ value = jh7110_pwmdac_read_reg(dev->base, JH7110_PWMDAC_CTRL);
++ value &= ~JH7110_PWMDAC_CNT_N_MASK;
++ value |= ((dev->cfg.cnt_n - 1) & 0x1ff) << JH7110_PWMDAC_CNT_N_SHIFT;
++
++ jh7110_pwmdac_write_reg(dev->base, JH7110_PWMDAC_CTRL, value);
++}
++
++static void jh7110_pwmdac_set_data_change(struct jh7110_pwmdac_dev *dev)
++{
++ u32 value;
++
++ value = jh7110_pwmdac_read_reg(dev->base, JH7110_PWMDAC_CTRL);
++ if (dev->cfg.data_change == NO_CHANGE)
++ value &= ~JH7110_PWMDAC_DATA_CHANGE;
++ else if (dev->cfg.data_change == CHANGE)
++ value |= JH7110_PWMDAC_DATA_CHANGE;
++
++ jh7110_pwmdac_write_reg(dev->base, JH7110_PWMDAC_CTRL, value);
++}
++
++static void jh7110_pwmdac_set_data_mode(struct jh7110_pwmdac_dev *dev)
++{
++ u32 value;
++
++ value = jh7110_pwmdac_read_reg(dev->base, JH7110_PWMDAC_CTRL);
++ if (dev->cfg.data_mode == UNSIGNED_DATA)
++ value &= ~JH7110_PWMDAC_DATA_MODE;
++ else if (dev->cfg.data_mode == INVERTER_DATA_MSB)
++ value |= JH7110_PWMDAC_DATA_MODE;
++
++ jh7110_pwmdac_write_reg(dev->base, JH7110_PWMDAC_CTRL, value);
++}
++
++static void jh7110_pwmdac_set_data_shift(struct jh7110_pwmdac_dev *dev)
++{
++ u32 value;
++
++ value = jh7110_pwmdac_read_reg(dev->base, JH7110_PWMDAC_CTRL);
++ value &= ~JH7110_PWMDAC_DATA_SHIFT_MASK;
++ value |= (dev->cfg.data_shift & 0x7) << JH7110_PWMDAC_DATA_SHIFT_SHIFT;
++
++ jh7110_pwmdac_write_reg(dev->base, JH7110_PWMDAC_CTRL, value);
++}
++
++static void jh7110_pwmdac_set(struct jh7110_pwmdac_dev *dev)
++{
++ jh7110_pwmdac_set_shift(dev);
++ jh7110_pwmdac_set_duty_cycle(dev);
++ jh7110_pwmdac_set_cnt_n(dev);
++ jh7110_pwmdac_set_enable(dev, true);
++
++ jh7110_pwmdac_set_data_change(dev);
++ jh7110_pwmdac_set_data_mode(dev);
++ jh7110_pwmdac_set_data_shift(dev);
++}
++
++static void jh7110_pwmdac_stop(struct jh7110_pwmdac_dev *dev)
++{
++ jh7110_pwmdac_set_enable(dev, false);
++}
++
++static int jh7110_pwmdac_startup(struct snd_pcm_substream *substream,
++ struct snd_soc_dai *dai)
++{
++ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
++ struct snd_soc_dai_link *dai_link = rtd->dai_link;
++
++ dai_link->trigger_stop = SND_SOC_TRIGGER_ORDER_LDC;
++
++ return 0;
++}
++
++static int jh7110_pwmdac_hw_params(struct snd_pcm_substream *substream,
++ struct snd_pcm_hw_params *params,
++ struct snd_soc_dai *dai)
++{
++ struct jh7110_pwmdac_dev *dev = dev_get_drvdata(dai->dev);
++ unsigned long core_clk_rate;
++ int ret;
++
++ switch (params_rate(params)) {
++ case 8000:
++ dev->cfg.cnt_n = PWMDAC_SAMPLE_CNT_3;
++ core_clk_rate = 6144000;
++ break;
++ case 11025:
++ dev->cfg.cnt_n = PWMDAC_SAMPLE_CNT_2;
++ core_clk_rate = 5644800;
++ break;
++ case 16000:
++ dev->cfg.cnt_n = PWMDAC_SAMPLE_CNT_3;
++ core_clk_rate = 12288000;
++ break;
++ case 22050:
++ dev->cfg.cnt_n = PWMDAC_SAMPLE_CNT_1;
++ core_clk_rate = 5644800;
++ break;
++ case 32000:
++ dev->cfg.cnt_n = PWMDAC_SAMPLE_CNT_1;
++ core_clk_rate = 8192000;
++ break;
++ case 44100:
++ dev->cfg.cnt_n = PWMDAC_SAMPLE_CNT_1;
++ core_clk_rate = 11289600;
++ break;
++ case 48000:
++ dev->cfg.cnt_n = PWMDAC_SAMPLE_CNT_1;
++ core_clk_rate = 12288000;
++ break;
++ default:
++ dev_err(dai->dev, "%d rate not supported\n",
++ params_rate(params));
++ return -EINVAL;
++ }
++
++ switch (params_channels(params)) {
++ case 1:
++ dev->play_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
++ break;
++ case 2:
++ dev->play_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
++ break;
++ default:
++ dev_err(dai->dev, "%d channels not supported\n",
++ params_channels(params));
++ return -EINVAL;
++ }
++
++ /*
++ * The clock rate always rounds down when using clk_set_rate()
++ * so increase the rate a bit
++ */
++ core_clk_rate += 64;
++ jh7110_pwmdac_set(dev);
++
++ ret = clk_set_rate(dev->clks[1].clk, core_clk_rate);
++ if (ret)
++ return dev_err_probe(dai->dev, ret,
++ "failed to set rate %lu for core clock\n",
++ core_clk_rate);
++
++ return 0;
++}
++
++static int jh7110_pwmdac_trigger(struct snd_pcm_substream *substream, int cmd,
++ struct snd_soc_dai *dai)
++{
++ struct jh7110_pwmdac_dev *dev = snd_soc_dai_get_drvdata(dai);
++ int ret = 0;
++
++ switch (cmd) {
++ case SNDRV_PCM_TRIGGER_START:
++ case SNDRV_PCM_TRIGGER_RESUME:
++ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
++ jh7110_pwmdac_set(dev);
++ break;
++
++ case SNDRV_PCM_TRIGGER_STOP:
++ case SNDRV_PCM_TRIGGER_SUSPEND:
++ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
++ jh7110_pwmdac_stop(dev);
++ break;
++ default:
++ ret = -EINVAL;
++ break;
++ }
++
++ return ret;
++}
++
++static int jh7110_pwmdac_crg_enable(struct jh7110_pwmdac_dev *dev, bool enable)
++{
++ int ret;
++
++ if (enable) {
++ ret = clk_bulk_prepare_enable(ARRAY_SIZE(dev->clks), dev->clks);
++ if (ret)
++ return dev_err_probe(dev->dev, ret,
++ "failed to enable pwmdac clocks\n");
++
++ ret = reset_control_deassert(dev->rst_apb);
++ if (ret) {
++ dev_err(dev->dev, "failed to deassert pwmdac apb reset\n");
++ goto err_rst_apb;
++ }
++ } else {
++ clk_bulk_disable_unprepare(ARRAY_SIZE(dev->clks), dev->clks);
++ }
++
++ return 0;
++
++err_rst_apb:
++ clk_bulk_disable_unprepare(ARRAY_SIZE(dev->clks), dev->clks);
++
++ return ret;
++}
++
++static int jh7110_pwmdac_dai_probe(struct snd_soc_dai *dai)
++{
++ struct jh7110_pwmdac_dev *dev = dev_get_drvdata(dai->dev);
++
++ snd_soc_dai_init_dma_data(dai, &dev->play_dma_data, NULL);
++ snd_soc_dai_set_drvdata(dai, dev);
++
++ return 0;
++}
++
++static const struct snd_soc_dai_ops jh7110_pwmdac_dai_ops = {
++ .startup = jh7110_pwmdac_startup,
++ .hw_params = jh7110_pwmdac_hw_params,
++ .trigger = jh7110_pwmdac_trigger,
++};
++
++static const struct snd_soc_component_driver jh7110_pwmdac_component = {
++ .name = "jh7110-pwmdac",
++};
++
++static struct snd_soc_dai_driver jh7110_pwmdac_dai = {
++ .name = "jh7110-pwmdac",
++ .id = 0,
++ .probe = jh7110_pwmdac_dai_probe,
++ .playback = {
++ .channels_min = 1,
++ .channels_max = 2,
++ .rates = SNDRV_PCM_RATE_8000_48000,
++ .formats = SNDRV_PCM_FMTBIT_S16_LE,
++ },
++ .ops = &jh7110_pwmdac_dai_ops,
++};
++
++static int jh7110_pwmdac_runtime_suspend(struct device *dev)
++{
++ struct jh7110_pwmdac_dev *pwmdac = dev_get_drvdata(dev);
++
++ return jh7110_pwmdac_crg_enable(pwmdac, false);
++}
++
++static int jh7110_pwmdac_runtime_resume(struct device *dev)
++{
++ struct jh7110_pwmdac_dev *pwmdac = dev_get_drvdata(dev);
++
++ return jh7110_pwmdac_crg_enable(pwmdac, true);
++}
++
++static int jh7110_pwmdac_system_suspend(struct device *dev)
++{
++ struct jh7110_pwmdac_dev *pwmdac = dev_get_drvdata(dev);
++
++ /* save the CTRL register value */
++ pwmdac->saved_ctrl = jh7110_pwmdac_read_reg(pwmdac->base,
++ JH7110_PWMDAC_CTRL);
++ return pm_runtime_force_suspend(dev);
++}
++
++static int jh7110_pwmdac_system_resume(struct device *dev)
++{
++ struct jh7110_pwmdac_dev *pwmdac = dev_get_drvdata(dev);
++ int ret;
++
++ ret = pm_runtime_force_resume(dev);
++ if (ret)
++ return ret;
++
++ /* restore the CTRL register value */
++ jh7110_pwmdac_write_reg(pwmdac->base, JH7110_PWMDAC_CTRL,
++ pwmdac->saved_ctrl);
++ return 0;
++}
++
++static const struct dev_pm_ops jh7110_pwmdac_pm_ops = {
++ RUNTIME_PM_OPS(jh7110_pwmdac_runtime_suspend,
++ jh7110_pwmdac_runtime_resume, NULL)
++ SYSTEM_SLEEP_PM_OPS(jh7110_pwmdac_system_suspend,
++ jh7110_pwmdac_system_resume)
++};
++
++static void jh7110_pwmdac_init_params(struct jh7110_pwmdac_dev *dev)
++{
++ dev->cfg.shift = PWMDAC_SHIFT_8;
++ dev->cfg.duty_cycle = PWMDAC_CYCLE_CENTER;
++ dev->cfg.cnt_n = PWMDAC_SAMPLE_CNT_1;
++ dev->cfg.data_change = NO_CHANGE;
++ dev->cfg.data_mode = INVERTER_DATA_MSB;
++ dev->cfg.data_shift = PWMDAC_DATA_LEFT_SHIFT_BIT_0;
++
++ dev->play_dma_data.addr = dev->mapbase + JH7110_PWMDAC_WDATA;
++ dev->play_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
++ dev->play_dma_data.fifo_size = 1;
++ dev->play_dma_data.maxburst = 16;
++}
++
++static int jh7110_pwmdac_probe(struct platform_device *pdev)
++{
++ struct jh7110_pwmdac_dev *dev;
++ struct resource *res;
++ int ret;
++
++ dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
++ if (!dev)
++ return -ENOMEM;
++
++ dev->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
++ if (IS_ERR(dev->base))
++ return PTR_ERR(dev->base);
++
++ dev->mapbase = res->start;
++
++ dev->clks[0].id = "apb";
++ dev->clks[1].id = "core";
++
++ ret = devm_clk_bulk_get(&pdev->dev, ARRAY_SIZE(dev->clks), dev->clks);
++ if (ret)
++ return dev_err_probe(&pdev->dev, ret,
++ "failed to get pwmdac clocks\n");
++
++ dev->rst_apb = devm_reset_control_get_exclusive(&pdev->dev, NULL);
++ if (IS_ERR(dev->rst_apb))
++ return dev_err_probe(&pdev->dev, PTR_ERR(dev->rst_apb),
++ "failed to get pwmdac apb reset\n");
++
++ jh7110_pwmdac_init_params(dev);
++
++ dev->dev = &pdev->dev;
++ dev_set_drvdata(&pdev->dev, dev);
++ ret = devm_snd_soc_register_component(&pdev->dev,
++ &jh7110_pwmdac_component,
++ &jh7110_pwmdac_dai, 1);
++ if (ret)
++ return dev_err_probe(&pdev->dev, ret, "failed to register dai\n");
++
++ ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
++ if (ret)
++ return dev_err_probe(&pdev->dev, ret, "failed to register pcm\n");
++
++ pm_runtime_enable(dev->dev);
++ if (!pm_runtime_enabled(&pdev->dev)) {
++ ret = jh7110_pwmdac_runtime_resume(&pdev->dev);
++ if (ret)
++ goto err_pm_disable;
++ }
++
++ return 0;
++
++err_pm_disable:
++ pm_runtime_disable(&pdev->dev);
++
++ return ret;
++}
++
++static int jh7110_pwmdac_remove(struct platform_device *pdev)
++{
++ pm_runtime_disable(&pdev->dev);
++ return 0;
++}
++
++static const struct of_device_id jh7110_pwmdac_of_match[] = {
++ { .compatible = "starfive,jh7110-pwmdac" },
++ { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, jh7110_pwmdac_of_match);
++
++static struct platform_driver jh7110_pwmdac_driver = {
++ .driver = {
++ .name = "jh7110-pwmdac",
++ .of_match_table = jh7110_pwmdac_of_match,
++ .pm = pm_ptr(&jh7110_pwmdac_pm_ops),
++ },
++ .probe = jh7110_pwmdac_probe,
++ .remove = jh7110_pwmdac_remove,
++};
++module_platform_driver(jh7110_pwmdac_driver);
++
++MODULE_AUTHOR("Jenny Zhang");
++MODULE_AUTHOR("Curry Zhang");
++MODULE_AUTHOR("Xingyu Wu <xingyu.wu@starfivetech.com>");
++MODULE_AUTHOR("Hal Feng <hal.feng@starfivetech.com>");
++MODULE_DESCRIPTION("StarFive JH7110 PWM-DAC driver");
++MODULE_LICENSE("GPL");
diff --git a/target/linux/starfive/patches-6.6/0037-ASoC-Update-jh7110-PWM-DAC-for-ops-move.patch b/target/linux/starfive/patches-6.6/0037-ASoC-Update-jh7110-PWM-DAC-for-ops-move.patch
new file mode 100644
index 0000000000..4833067bac
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0037-ASoC-Update-jh7110-PWM-DAC-for-ops-move.patch
@@ -0,0 +1,32 @@
+From c6b693f990e1f89ab5af0a139da31401b8cda74f Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie@kernel.org>
+Date: Mon, 11 Sep 2023 23:48:39 +0100
+Subject: [PATCH 037/116] ASoC: Update jh7110 PWM DAC for ops move
+
+For some reason the JH7110 PWM DAC driver made it through build testing
+in spite of not being updated for the move of probe() to the ops struct.
+Make the required update.
+
+Signed-off-by: Mark Brown <broonie@kernel.org>
+---
+ sound/soc/starfive/jh7110_pwmdac.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/sound/soc/starfive/jh7110_pwmdac.c
++++ b/sound/soc/starfive/jh7110_pwmdac.c
+@@ -357,6 +357,7 @@ static int jh7110_pwmdac_dai_probe(struc
+ }
+
+ static const struct snd_soc_dai_ops jh7110_pwmdac_dai_ops = {
++ .probe = jh7110_pwmdac_dai_probe,
+ .startup = jh7110_pwmdac_startup,
+ .hw_params = jh7110_pwmdac_hw_params,
+ .trigger = jh7110_pwmdac_trigger,
+@@ -369,7 +370,6 @@ static const struct snd_soc_component_dr
+ static struct snd_soc_dai_driver jh7110_pwmdac_dai = {
+ .name = "jh7110-pwmdac",
+ .id = 0,
+- .probe = jh7110_pwmdac_dai_probe,
+ .playback = {
+ .channels_min = 1,
+ .channels_max = 2,
diff --git a/target/linux/starfive/patches-6.6/0038-ASoC-starfive-jh7110-pwmdac-Convert-to-platform-remo.patch b/target/linux/starfive/patches-6.6/0038-ASoC-starfive-jh7110-pwmdac-Convert-to-platform-remo.patch
new file mode 100644
index 0000000000..9b5f553f8c
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0038-ASoC-starfive-jh7110-pwmdac-Convert-to-platform-remo.patch
@@ -0,0 +1,52 @@
+From 312c3c407c363f0ec7417d2d389cbe936c503729 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= <u.kleine-koenig@pengutronix.de>
+Date: Sat, 14 Oct 2023 00:19:49 +0200
+Subject: [PATCH 038/116] ASoC: starfive/jh7110-pwmdac: Convert to platform
+ remove callback returning void
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The .remove() callback for a platform driver returns an int which makes
+many driver authors wrongly assume it's possible to do error handling by
+returning an error code. However the value returned is ignored (apart
+from emitting a warning) and this typically results in resource leaks.
+
+To improve here there is a quest to make the remove callback return
+void. In the first step of this quest all drivers are converted to
+.remove_new(), which already returns void. Eventually after all drivers
+are converted, .remove_new() will be renamed to .remove().
+
+Trivially convert this driver from always returning zero in the remove
+callback to the void returning variant.
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Link: https://lore.kernel.org/r/20231013221945.1489203-12-u.kleine-koenig@pengutronix.de
+Signed-off-by: Mark Brown <broonie@kernel.org>
+---
+ sound/soc/starfive/jh7110_pwmdac.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+--- a/sound/soc/starfive/jh7110_pwmdac.c
++++ b/sound/soc/starfive/jh7110_pwmdac.c
+@@ -498,10 +498,9 @@ err_pm_disable:
+ return ret;
+ }
+
+-static int jh7110_pwmdac_remove(struct platform_device *pdev)
++static void jh7110_pwmdac_remove(struct platform_device *pdev)
+ {
+ pm_runtime_disable(&pdev->dev);
+- return 0;
+ }
+
+ static const struct of_device_id jh7110_pwmdac_of_match[] = {
+@@ -517,7 +516,7 @@ static struct platform_driver jh7110_pwm
+ .pm = pm_ptr(&jh7110_pwmdac_pm_ops),
+ },
+ .probe = jh7110_pwmdac_probe,
+- .remove = jh7110_pwmdac_remove,
++ .remove_new = jh7110_pwmdac_remove,
+ };
+ module_platform_driver(jh7110_pwmdac_driver);
+
diff --git a/target/linux/starfive/patches-6.6/0039-dt-bindings-power-Add-power-domain-header-for-JH7110.patch b/target/linux/starfive/patches-6.6/0039-dt-bindings-power-Add-power-domain-header-for-JH7110.patch
new file mode 100644
index 0000000000..bcc9af2d2c
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0039-dt-bindings-power-Add-power-domain-header-for-JH7110.patch
@@ -0,0 +1,35 @@
+From 8d84bac6d7471ba2e29b33d19a2ef887822e9cce Mon Sep 17 00:00:00 2001
+From: Changhuang Liang <changhuang.liang@starfivetech.com>
+Date: Wed, 13 Sep 2023 14:54:25 +0100
+Subject: [PATCH 039/116] dt-bindings: power: Add power-domain header for
+ JH7110
+
+Add power-domain header for JH7110 SoC, it can use to operate dphy
+power.
+
+Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
+Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
+Link: https://lore.kernel.org/r/20230913-grumbly-rewrite-34c85539f2ed@spud
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+---
+ include/dt-bindings/power/starfive,jh7110-pmu.h | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/include/dt-bindings/power/starfive,jh7110-pmu.h
++++ b/include/dt-bindings/power/starfive,jh7110-pmu.h
+@@ -1,6 +1,6 @@
+ /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+ /*
+- * Copyright (C) 2022 StarFive Technology Co., Ltd.
++ * Copyright (C) 2022-2023 StarFive Technology Co., Ltd.
+ * Author: Walker Chen <walker.chen@starfivetech.com>
+ */
+ #ifndef __DT_BINDINGS_POWER_JH7110_POWER_H__
+@@ -14,4 +14,7 @@
+ #define JH7110_PD_ISP 5
+ #define JH7110_PD_VENC 6
+
++#define JH7110_PD_DPHY_TX 0
++#define JH7110_PD_DPHY_RX 1
++
+ #endif
diff --git a/target/linux/starfive/patches-6.6/0040-pmdomain-starfive-Replace-SOC_STARFIVE-with-ARCH_STA.patch b/target/linux/starfive/patches-6.6/0040-pmdomain-starfive-Replace-SOC_STARFIVE-with-ARCH_STA.patch
new file mode 100644
index 0000000000..335193fbb6
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0040-pmdomain-starfive-Replace-SOC_STARFIVE-with-ARCH_STA.patch
@@ -0,0 +1,31 @@
+From 0ac8e8b0e65d242f455401df0cc6c6d4772216e6 Mon Sep 17 00:00:00 2001
+From: Changhuang Liang <changhuang.liang@starfivetech.com>
+Date: Wed, 13 Sep 2023 14:54:26 +0100
+Subject: [PATCH 040/116] pmdomain: starfive: Replace SOC_STARFIVE with
+ ARCH_STARFIVE
+
+Using ARCH_FOO symbol is preferred than SOC_FOO.
+
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+Reviewed-by: Walker Chen <walker.chen@starfivetech.com>
+Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
+Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
+Link: https://lore.kernel.org/r/20230913-legibly-treachery-567cffcb5604@spud
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+---
+ drivers/soc/starfive/Kconfig | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/soc/starfive/Kconfig
++++ b/drivers/soc/starfive/Kconfig
+@@ -3,8 +3,8 @@
+ config JH71XX_PMU
+ bool "Support PMU for StarFive JH71XX Soc"
+ depends on PM
+- depends on SOC_STARFIVE || COMPILE_TEST
+- default SOC_STARFIVE
++ depends on ARCH_STARFIVE || COMPILE_TEST
++ default ARCH_STARFIVE
+ select PM_GENERIC_DOMAINS
+ help
+ Say 'y' here to enable support power domain support.
diff --git a/target/linux/starfive/patches-6.6/0041-pmdomain-starfive-Extract-JH7110-pmu-private-operati.patch b/target/linux/starfive/patches-6.6/0041-pmdomain-starfive-Extract-JH7110-pmu-private-operati.patch
new file mode 100644
index 0000000000..7425dd6dbb
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0041-pmdomain-starfive-Extract-JH7110-pmu-private-operati.patch
@@ -0,0 +1,179 @@
+From a1ba60e35ca7f1b85243054556ecde2e259619e1 Mon Sep 17 00:00:00 2001
+From: Changhuang Liang <changhuang.liang@starfivetech.com>
+Date: Wed, 13 Sep 2023 14:54:27 +0100
+Subject: [PATCH 041/116] pmdomain: starfive: Extract JH7110 pmu private
+ operations
+
+Move JH7110 private operation into private data of compatible. Convenient
+to add AON PMU which would not have interrupts property.
+
+Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
+Reviewed-by: Walker Chen <walker.chen@starfivetech.com>
+Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
+Link: https://lore.kernel.org/r/20230913-slideshow-luckiness-38ff17de84c6@spud
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+---
+ drivers/pmdomain/starfive/jh71xx-pmu.c | 89 ++++++++++++++++++--------
+ 1 file changed, 62 insertions(+), 27 deletions(-)
+
+--- a/drivers/pmdomain/starfive/jh71xx-pmu.c
++++ b/drivers/pmdomain/starfive/jh71xx-pmu.c
+@@ -51,9 +51,17 @@ struct jh71xx_domain_info {
+ u8 bit;
+ };
+
++struct jh71xx_pmu;
++struct jh71xx_pmu_dev;
++
+ struct jh71xx_pmu_match_data {
+ const struct jh71xx_domain_info *domain_info;
+ int num_domains;
++ unsigned int pmu_status;
++ int (*pmu_parse_irq)(struct platform_device *pdev,
++ struct jh71xx_pmu *pmu);
++ int (*pmu_set_state)(struct jh71xx_pmu_dev *pmd,
++ u32 mask, bool on);
+ };
+
+ struct jh71xx_pmu {
+@@ -79,12 +87,12 @@ static int jh71xx_pmu_get_state(struct j
+ if (!mask)
+ return -EINVAL;
+
+- *is_on = readl(pmu->base + JH71XX_PMU_CURR_POWER_MODE) & mask;
++ *is_on = readl(pmu->base + pmu->match_data->pmu_status) & mask;
+
+ return 0;
+ }
+
+-static int jh71xx_pmu_set_state(struct jh71xx_pmu_dev *pmd, u32 mask, bool on)
++static int jh7110_pmu_set_state(struct jh71xx_pmu_dev *pmd, u32 mask, bool on)
+ {
+ struct jh71xx_pmu *pmu = pmd->pmu;
+ unsigned long flags;
+@@ -92,22 +100,8 @@ static int jh71xx_pmu_set_state(struct j
+ u32 mode;
+ u32 encourage_lo;
+ u32 encourage_hi;
+- bool is_on;
+ int ret;
+
+- ret = jh71xx_pmu_get_state(pmd, mask, &is_on);
+- if (ret) {
+- dev_dbg(pmu->dev, "unable to get current state for %s\n",
+- pmd->genpd.name);
+- return ret;
+- }
+-
+- if (is_on == on) {
+- dev_dbg(pmu->dev, "pm domain [%s] is already %sable status.\n",
+- pmd->genpd.name, on ? "en" : "dis");
+- return 0;
+- }
+-
+ spin_lock_irqsave(&pmu->lock, flags);
+
+ /*
+@@ -166,6 +160,29 @@ static int jh71xx_pmu_set_state(struct j
+ return 0;
+ }
+
++static int jh71xx_pmu_set_state(struct jh71xx_pmu_dev *pmd, u32 mask, bool on)
++{
++ struct jh71xx_pmu *pmu = pmd->pmu;
++ const struct jh71xx_pmu_match_data *match_data = pmu->match_data;
++ bool is_on;
++ int ret;
++
++ ret = jh71xx_pmu_get_state(pmd, mask, &is_on);
++ if (ret) {
++ dev_dbg(pmu->dev, "unable to get current state for %s\n",
++ pmd->genpd.name);
++ return ret;
++ }
++
++ if (is_on == on) {
++ dev_dbg(pmu->dev, "pm domain [%s] is already %sable status.\n",
++ pmd->genpd.name, on ? "en" : "dis");
++ return 0;
++ }
++
++ return match_data->pmu_set_state(pmd, mask, on);
++}
++
+ static int jh71xx_pmu_on(struct generic_pm_domain *genpd)
+ {
+ struct jh71xx_pmu_dev *pmd = container_of(genpd,
+@@ -226,6 +243,25 @@ static irqreturn_t jh71xx_pmu_interrupt(
+ return IRQ_HANDLED;
+ }
+
++static int jh7110_pmu_parse_irq(struct platform_device *pdev, struct jh71xx_pmu *pmu)
++{
++ struct device *dev = &pdev->dev;
++ int ret;
++
++ pmu->irq = platform_get_irq(pdev, 0);
++ if (pmu->irq < 0)
++ return pmu->irq;
++
++ ret = devm_request_irq(dev, pmu->irq, jh71xx_pmu_interrupt,
++ 0, pdev->name, pmu);
++ if (ret)
++ dev_err(dev, "failed to request irq\n");
++
++ jh71xx_pmu_int_enable(pmu, JH71XX_PMU_INT_ALL_MASK & ~JH71XX_PMU_INT_PCH_FAIL, true);
++
++ return 0;
++}
++
+ static int jh71xx_pmu_init_domain(struct jh71xx_pmu *pmu, int index)
+ {
+ struct jh71xx_pmu_dev *pmd;
+@@ -275,19 +311,18 @@ static int jh71xx_pmu_probe(struct platf
+ if (IS_ERR(pmu->base))
+ return PTR_ERR(pmu->base);
+
+- pmu->irq = platform_get_irq(pdev, 0);
+- if (pmu->irq < 0)
+- return pmu->irq;
+-
+- ret = devm_request_irq(dev, pmu->irq, jh71xx_pmu_interrupt,
+- 0, pdev->name, pmu);
+- if (ret)
+- dev_err(dev, "failed to request irq\n");
++ spin_lock_init(&pmu->lock);
+
+ match_data = of_device_get_match_data(dev);
+ if (!match_data)
+ return -EINVAL;
+
++ ret = match_data->pmu_parse_irq(pdev, pmu);
++ if (ret) {
++ dev_err(dev, "failed to parse irq\n");
++ return ret;
++ }
++
+ pmu->genpd = devm_kcalloc(dev, match_data->num_domains,
+ sizeof(struct generic_pm_domain *),
+ GFP_KERNEL);
+@@ -307,9 +342,6 @@ static int jh71xx_pmu_probe(struct platf
+ }
+ }
+
+- spin_lock_init(&pmu->lock);
+- jh71xx_pmu_int_enable(pmu, JH71XX_PMU_INT_ALL_MASK & ~JH71XX_PMU_INT_PCH_FAIL, true);
+-
+ ret = of_genpd_add_provider_onecell(np, &pmu->genpd_data);
+ if (ret) {
+ dev_err(dev, "failed to register genpd driver: %d\n", ret);
+@@ -357,6 +389,9 @@ static const struct jh71xx_domain_info j
+ static const struct jh71xx_pmu_match_data jh7110_pmu = {
+ .num_domains = ARRAY_SIZE(jh7110_power_domains),
+ .domain_info = jh7110_power_domains,
++ .pmu_status = JH71XX_PMU_CURR_POWER_MODE,
++ .pmu_parse_irq = jh7110_pmu_parse_irq,
++ .pmu_set_state = jh7110_pmu_set_state,
+ };
+
+ static const struct of_device_id jh71xx_pmu_of_match[] = {
diff --git a/target/linux/starfive/patches-6.6/0042-pmdomain-starfive-Add-JH7110-AON-PMU-support.patch b/target/linux/starfive/patches-6.6/0042-pmdomain-starfive-Add-JH7110-AON-PMU-support.patch
new file mode 100644
index 0000000000..2563d5421c
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0042-pmdomain-starfive-Add-JH7110-AON-PMU-support.patch
@@ -0,0 +1,122 @@
+From 1bf849b606d0b4cae643f96685d3d3981643683d Mon Sep 17 00:00:00 2001
+From: Changhuang Liang <changhuang.liang@starfivetech.com>
+Date: Wed, 13 Sep 2023 14:54:28 +0100
+Subject: [PATCH 042/116] pmdomain: starfive: Add JH7110 AON PMU support
+
+Add AON PMU for StarFive JH7110 SoC. It can be used to turn on/off the
+dphy rx/tx power switch.
+
+Reviewed-by: Walker Chen <walker.chen@starfivetech.com>
+Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
+Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
+Link: https://lore.kernel.org/r/20230913-dude-imprecise-fc32622bc947@spud
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+---
+ drivers/pmdomain/starfive/jh71xx-pmu.c | 57 +++++++++++++++++++++++---
+ 1 file changed, 52 insertions(+), 5 deletions(-)
+
+--- a/drivers/pmdomain/starfive/jh71xx-pmu.c
++++ b/drivers/pmdomain/starfive/jh71xx-pmu.c
+@@ -2,7 +2,7 @@
+ /*
+ * StarFive JH71XX PMU (Power Management Unit) Controller Driver
+ *
+- * Copyright (C) 2022 StarFive Technology Co., Ltd.
++ * Copyright (C) 2022-2023 StarFive Technology Co., Ltd.
+ */
+
+ #include <linux/interrupt.h>
+@@ -24,6 +24,9 @@
+ #define JH71XX_PMU_EVENT_STATUS 0x88
+ #define JH71XX_PMU_INT_STATUS 0x8C
+
++/* aon pmu register offset */
++#define JH71XX_AON_PMU_SWITCH 0x00
++
+ /* sw encourage cfg */
+ #define JH71XX_PMU_SW_ENCOURAGE_EN_LO 0x05
+ #define JH71XX_PMU_SW_ENCOURAGE_EN_HI 0x50
+@@ -160,6 +163,26 @@ static int jh7110_pmu_set_state(struct j
+ return 0;
+ }
+
++static int jh7110_aon_pmu_set_state(struct jh71xx_pmu_dev *pmd, u32 mask, bool on)
++{
++ struct jh71xx_pmu *pmu = pmd->pmu;
++ unsigned long flags;
++ u32 val;
++
++ spin_lock_irqsave(&pmu->lock, flags);
++ val = readl(pmu->base + JH71XX_AON_PMU_SWITCH);
++
++ if (on)
++ val |= mask;
++ else
++ val &= ~mask;
++
++ writel(val, pmu->base + JH71XX_AON_PMU_SWITCH);
++ spin_unlock_irqrestore(&pmu->lock, flags);
++
++ return 0;
++}
++
+ static int jh71xx_pmu_set_state(struct jh71xx_pmu_dev *pmd, u32 mask, bool on)
+ {
+ struct jh71xx_pmu *pmu = pmd->pmu;
+@@ -317,10 +340,12 @@ static int jh71xx_pmu_probe(struct platf
+ if (!match_data)
+ return -EINVAL;
+
+- ret = match_data->pmu_parse_irq(pdev, pmu);
+- if (ret) {
+- dev_err(dev, "failed to parse irq\n");
+- return ret;
++ if (match_data->pmu_parse_irq) {
++ ret = match_data->pmu_parse_irq(pdev, pmu);
++ if (ret) {
++ dev_err(dev, "failed to parse irq\n");
++ return ret;
++ }
+ }
+
+ pmu->genpd = devm_kcalloc(dev, match_data->num_domains,
+@@ -394,11 +419,32 @@ static const struct jh71xx_pmu_match_dat
+ .pmu_set_state = jh7110_pmu_set_state,
+ };
+
++static const struct jh71xx_domain_info jh7110_aon_power_domains[] = {
++ [JH7110_PD_DPHY_TX] = {
++ .name = "DPHY-TX",
++ .bit = 30,
++ },
++ [JH7110_PD_DPHY_RX] = {
++ .name = "DPHY-RX",
++ .bit = 31,
++ },
++};
++
++static const struct jh71xx_pmu_match_data jh7110_aon_pmu = {
++ .num_domains = ARRAY_SIZE(jh7110_aon_power_domains),
++ .domain_info = jh7110_aon_power_domains,
++ .pmu_status = JH71XX_AON_PMU_SWITCH,
++ .pmu_set_state = jh7110_aon_pmu_set_state,
++};
++
+ static const struct of_device_id jh71xx_pmu_of_match[] = {
+ {
+ .compatible = "starfive,jh7110-pmu",
+ .data = (void *)&jh7110_pmu,
+ }, {
++ .compatible = "starfive,jh7110-aon-syscon",
++ .data = (void *)&jh7110_aon_pmu,
++ }, {
+ /* sentinel */
+ }
+ };
+@@ -414,5 +460,6 @@ static struct platform_driver jh71xx_pmu
+ builtin_platform_driver(jh71xx_pmu_driver);
+
+ MODULE_AUTHOR("Walker Chen <walker.chen@starfivetech.com>");
++MODULE_AUTHOR("Changhuang Liang <changhuang.liang@starfivetech.com>");
+ MODULE_DESCRIPTION("StarFive JH71XX PMU Driver");
+ MODULE_LICENSE("GPL");
diff --git a/target/linux/starfive/patches-6.6/0043-pmdomain-Prepare-to-move-Kconfig-files-into-the-pmdo.patch b/target/linux/starfive/patches-6.6/0043-pmdomain-Prepare-to-move-Kconfig-files-into-the-pmdo.patch
new file mode 100644
index 0000000000..52be89f29e
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0043-pmdomain-Prepare-to-move-Kconfig-files-into-the-pmdo.patch
@@ -0,0 +1,36 @@
+From dff6605dcd1fc1e2af1437e59187a6f71ce389cd Mon Sep 17 00:00:00 2001
+From: Ulf Hansson <ulf.hansson@linaro.org>
+Date: Mon, 11 Sep 2023 17:22:15 +0200
+Subject: [PATCH 043/116] pmdomain: Prepare to move Kconfig files into the
+ pmdomain subsystem
+
+Rather than having the various Kconfig files for the genpd providers
+sprinkled across subsystems, let's prepare to move them into the pmdomain
+subsystem along with the implementations.
+
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+---
+ drivers/Kconfig | 2 ++
+ drivers/pmdomain/Kconfig | 4 ++++
+ 2 files changed, 6 insertions(+)
+ create mode 100644 drivers/pmdomain/Kconfig
+
+--- a/drivers/Kconfig
++++ b/drivers/Kconfig
+@@ -175,6 +175,8 @@ source "drivers/soundwire/Kconfig"
+
+ source "drivers/soc/Kconfig"
+
++source "drivers/pmdomain/Kconfig"
++
+ source "drivers/devfreq/Kconfig"
+
+ source "drivers/extcon/Kconfig"
+--- /dev/null
++++ b/drivers/pmdomain/Kconfig
+@@ -0,0 +1,4 @@
++# SPDX-License-Identifier: GPL-2.0-only
++menu "PM Domains"
++
++endmenu
diff --git a/target/linux/starfive/patches-6.6/0044-pmdomain-starfive-Move-Kconfig-file-to-the-pmdomain-.patch b/target/linux/starfive/patches-6.6/0044-pmdomain-starfive-Move-Kconfig-file-to-the-pmdomain-.patch
new file mode 100644
index 0000000000..909f4cc63a
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0044-pmdomain-starfive-Move-Kconfig-file-to-the-pmdomain-.patch
@@ -0,0 +1,69 @@
+From de12fe43dbd0ea9fa980ffa05822bd7fd5eed330 Mon Sep 17 00:00:00 2001
+From: Ulf Hansson <ulf.hansson@linaro.org>
+Date: Tue, 12 Sep 2023 13:31:44 +0200
+Subject: [PATCH 044/116] pmdomain: starfive: Move Kconfig file to the pmdomain
+ subsystem
+
+The Kconfig belongs closer to the corresponding implementation, hence let's
+move it from the soc subsystem to the pmdomain subsystem.
+
+Cc: Walker Chen <walker.chen@starfivetech.com>
+Cc: Conor Dooley <conor@kernel.org>
+Acked-by: Conor Dooley <conor.dooley@microchip.com>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+---
+ drivers/pmdomain/Kconfig | 2 ++
+ drivers/{soc => pmdomain}/starfive/Kconfig | 0
+ drivers/soc/Kconfig | 1 -
+ 3 files changed, 2 insertions(+), 1 deletion(-)
+ rename drivers/{soc => pmdomain}/starfive/Kconfig (100%)
+
+--- a/drivers/pmdomain/Kconfig
++++ b/drivers/pmdomain/Kconfig
+@@ -1,4 +1,6 @@
+ # SPDX-License-Identifier: GPL-2.0-only
+ menu "PM Domains"
+
++source "drivers/pmdomain/starfive/Kconfig"
++
+ endmenu
+--- a/drivers/soc/Kconfig
++++ b/drivers/soc/Kconfig
+@@ -24,7 +24,6 @@ source "drivers/soc/renesas/Kconfig"
+ source "drivers/soc/rockchip/Kconfig"
+ source "drivers/soc/samsung/Kconfig"
+ source "drivers/soc/sifive/Kconfig"
+-source "drivers/soc/starfive/Kconfig"
+ source "drivers/soc/sunxi/Kconfig"
+ source "drivers/soc/tegra/Kconfig"
+ source "drivers/soc/ti/Kconfig"
+--- /dev/null
++++ b/drivers/pmdomain/starfive/Kconfig
+@@ -0,0 +1,12 @@
++# SPDX-License-Identifier: GPL-2.0
++
++config JH71XX_PMU
++ bool "Support PMU for StarFive JH71XX Soc"
++ depends on PM
++ depends on ARCH_STARFIVE || COMPILE_TEST
++ default ARCH_STARFIVE
++ select PM_GENERIC_DOMAINS
++ help
++ Say 'y' here to enable support power domain support.
++ In order to meet low power requirements, a Power Management Unit (PMU)
++ is designed for controlling power resources in StarFive JH71XX SoCs.
+--- a/drivers/soc/starfive/Kconfig
++++ /dev/null
+@@ -1,12 +0,0 @@
+-# SPDX-License-Identifier: GPL-2.0
+-
+-config JH71XX_PMU
+- bool "Support PMU for StarFive JH71XX Soc"
+- depends on PM
+- depends on ARCH_STARFIVE || COMPILE_TEST
+- default ARCH_STARFIVE
+- select PM_GENERIC_DOMAINS
+- help
+- Say 'y' here to enable support power domain support.
+- In order to meet low power requirements, a Power Management Unit (PMU)
+- is designed for controlling power resources in StarFive JH71XX SoCs.
diff --git a/target/linux/starfive/patches-6.6/0045-dt-bindings-power-Update-prefixes-for-AON-power-doma.patch b/target/linux/starfive/patches-6.6/0045-dt-bindings-power-Update-prefixes-for-AON-power-doma.patch
new file mode 100644
index 0000000000..c6e0012528
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0045-dt-bindings-power-Update-prefixes-for-AON-power-doma.patch
@@ -0,0 +1,31 @@
+From cac9ce9c7f388a741389b1ec47af65420254db55 Mon Sep 17 00:00:00 2001
+From: Changhuang Liang <changhuang.liang@starfivetech.com>
+Date: Wed, 27 Sep 2023 06:07:33 -0700
+Subject: [PATCH 045/116] dt-bindings: power: Update prefixes for AON power
+ domain
+
+Use "JH7110_AON_PD_" prefix for AON power domain for JH7110 SoC.
+
+Reviewed-by: Walker Chen <walker.chen@starfivetech.com>
+Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
+Acked-by: Conor Dooley <conor.dooley@microchip.com>
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Link: https://lore.kernel.org/r/20230927130734.9921-2-changhuang.liang@starfivetech.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+---
+ include/dt-bindings/power/starfive,jh7110-pmu.h | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/include/dt-bindings/power/starfive,jh7110-pmu.h
++++ b/include/dt-bindings/power/starfive,jh7110-pmu.h
+@@ -14,7 +14,8 @@
+ #define JH7110_PD_ISP 5
+ #define JH7110_PD_VENC 6
+
+-#define JH7110_PD_DPHY_TX 0
+-#define JH7110_PD_DPHY_RX 1
++/* AON Power Domain */
++#define JH7110_AON_PD_DPHY_TX 0
++#define JH7110_AON_PD_DPHY_RX 1
+
+ #endif
diff --git a/target/linux/starfive/patches-6.6/0046-pmdomain-starfive-Update-prefixes-for-AON-power-doma.patch b/target/linux/starfive/patches-6.6/0046-pmdomain-starfive-Update-prefixes-for-AON-power-doma.patch
new file mode 100644
index 0000000000..5cb89ae052
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0046-pmdomain-starfive-Update-prefixes-for-AON-power-doma.patch
@@ -0,0 +1,32 @@
+From 3ea89ffbd6cc5a15acca6bc2130572f8bd85b9d4 Mon Sep 17 00:00:00 2001
+From: Changhuang Liang <changhuang.liang@starfivetech.com>
+Date: Wed, 27 Sep 2023 06:07:34 -0700
+Subject: [PATCH 046/116] pmdomain: starfive: Update prefixes for AON power
+ domain
+
+Use "JH7110_AON_PD_" prefix for AON power doamin for JH7110 SoC.
+
+Reviewed-by: Walker Chen <walker.chen@starfivetech.com>
+Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
+Link: https://lore.kernel.org/r/20230927130734.9921-3-changhuang.liang@starfivetech.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+---
+ drivers/pmdomain/starfive/jh71xx-pmu.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/pmdomain/starfive/jh71xx-pmu.c
++++ b/drivers/pmdomain/starfive/jh71xx-pmu.c
+@@ -420,11 +420,11 @@ static const struct jh71xx_pmu_match_dat
+ };
+
+ static const struct jh71xx_domain_info jh7110_aon_power_domains[] = {
+- [JH7110_PD_DPHY_TX] = {
++ [JH7110_AON_PD_DPHY_TX] = {
+ .name = "DPHY-TX",
+ .bit = 30,
+ },
+- [JH7110_PD_DPHY_RX] = {
++ [JH7110_AON_PD_DPHY_RX] = {
+ .name = "DPHY-RX",
+ .bit = 31,
+ },
diff --git a/target/linux/starfive/patches-6.6/0047-riscv-dts-starfive-pinfunc-Fix-the-pins-name-of-I2ST.patch b/target/linux/starfive/patches-6.6/0047-riscv-dts-starfive-pinfunc-Fix-the-pins-name-of-I2ST.patch
new file mode 100644
index 0000000000..782e71a0eb
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0047-riscv-dts-starfive-pinfunc-Fix-the-pins-name-of-I2ST.patch
@@ -0,0 +1,30 @@
+From e7e3d62b7a470ddf15e30574232b52b2e23ba606 Mon Sep 17 00:00:00 2001
+From: Xingyu Wu <xingyu.wu@starfivetech.com>
+Date: Mon, 21 Aug 2023 22:41:50 +0800
+Subject: [PATCH 047/116] riscv: dts: starfive: pinfunc: Fix the pins name of
+ I2STX1
+
+These pins are actually I2STX1 clock input, not I2STX0,
+so their names should be changed.
+
+Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
+Reviewed-by: Walker Chen <walker.chen@starfivetech.com>
+Acked-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
+---
+ arch/riscv/boot/dts/starfive/jh7110-pinfunc.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/arch/riscv/boot/dts/starfive/jh7110-pinfunc.h
++++ b/arch/riscv/boot/dts/starfive/jh7110-pinfunc.h
+@@ -240,8 +240,8 @@
+ #define GPI_SYS_MCLK_EXT 30
+ #define GPI_SYS_I2SRX_BCLK 31
+ #define GPI_SYS_I2SRX_LRCK 32
+-#define GPI_SYS_I2STX0_BCLK 33
+-#define GPI_SYS_I2STX0_LRCK 34
++#define GPI_SYS_I2STX1_BCLK 33
++#define GPI_SYS_I2STX1_LRCK 34
+ #define GPI_SYS_TDM_CLK 35
+ #define GPI_SYS_TDM_RXD 36
+ #define GPI_SYS_TDM_SYNC 37
diff --git a/target/linux/starfive/patches-6.6/0048-riscv-dts-starfive-Add-full-support-except-VIN-and-V.patch b/target/linux/starfive/patches-6.6/0048-riscv-dts-starfive-Add-full-support-except-VIN-and-V.patch
new file mode 100644
index 0000000000..ad6626cd79
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0048-riscv-dts-starfive-Add-full-support-except-VIN-and-V.patch
@@ -0,0 +1,549 @@
+From a3d3f611f31fa2dca3deefa7cd443abca02e03fa Mon Sep 17 00:00:00 2001
+From: Hal Feng <hal.feng@starfivetech.com>
+Date: Tue, 11 Apr 2023 16:31:15 +0800
+Subject: [PATCH 048/116] riscv: dts: starfive: Add full support (except VIN
+ and VOUT) for JH7110 and VisionFive 2 board
+
+Merge all StarFive dts patches together except VIN and VOUT.
+
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ .../jh7110-starfive-visionfive-2.dtsi | 199 +++++++++++++++
+ arch/riscv/boot/dts/starfive/jh7110.dtsi | 233 ++++++++++++++++++
+ 2 files changed, 432 insertions(+)
+
+--- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
+@@ -19,6 +19,8 @@
+ i2c6 = &i2c6;
+ mmc0 = &mmc0;
+ mmc1 = &mmc1;
++ pcie0 = &pcie0;
++ pcie1 = &pcie1;
+ serial0 = &uart0;
+ };
+
+@@ -40,6 +42,33 @@
+ gpios = <&sysgpio 35 GPIO_ACTIVE_HIGH>;
+ priority = <224>;
+ };
++
++ pwmdac_codec: pwmdac-codec {
++ compatible = "linux,spdif-dit";
++ #sound-dai-cells = <0>;
++ };
++
++ sound-pwmdac {
++ compatible = "simple-audio-card";
++ simple-audio-card,name = "StarFive-PWMDAC-Sound-Card";
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ simple-audio-card,dai-link@0 {
++ reg = <0>;
++ format = "left_j";
++ bitclock-master = <&sndcpu0>;
++ frame-master = <&sndcpu0>;
++
++ sndcpu0: cpu {
++ sound-dai = <&pwmdac>;
++ };
++
++ codec {
++ sound-dai = <&pwmdac_codec>;
++ };
++ };
++ };
+ };
+
+ &dvp_clk {
+@@ -202,8 +231,28 @@
+ status = "okay";
+ };
+
++&i2srx {
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2srx_pins>;
++ status = "okay";
++};
++
++&i2stx0 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&mclk_ext_pins>;
++ status = "okay";
++};
++
++&i2stx1 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2stx1_pins>;
++ status = "okay";
++};
++
+ &mmc0 {
+ max-frequency = <100000000>;
++ assigned-clocks = <&syscrg JH7110_SYSCLK_SDIO0_SDCARD>;
++ assigned-clock-rates = <50000000>;
+ bus-width = <8>;
+ cap-mmc-highspeed;
+ mmc-ddr-1_8v;
+@@ -220,6 +269,8 @@
+
+ &mmc1 {
+ max-frequency = <100000000>;
++ assigned-clocks = <&syscrg JH7110_SYSCLK_SDIO1_SDCARD>;
++ assigned-clock-rates = <50000000>;
+ bus-width = <4>;
+ no-sdio;
+ no-mmc;
+@@ -231,6 +282,34 @@
+ status = "okay";
+ };
+
++&pcie0 {
++ perst-gpios = <&sysgpio 26 GPIO_ACTIVE_LOW>;
++ phys = <&pciephy0>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&pcie0_pins>;
++ status = "okay";
++};
++
++&pcie1 {
++ perst-gpios = <&sysgpio 28 GPIO_ACTIVE_LOW>;
++ phys = <&pciephy1>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&pcie1_pins>;
++ status = "okay";
++};
++
++&pwm {
++ pinctrl-names = "default";
++ pinctrl-0 = <&pwm_pins>;
++ status = "okay";
++};
++
++&pwmdac {
++ pinctrl-names = "default";
++ pinctrl-0 = <&pwmdac_pins>;
++ status = "okay";
++};
++
+ &qspi {
+ #address-cells = <1>;
+ #size-cells = <0>;
+@@ -336,6 +415,46 @@
+ };
+ };
+
++ i2srx_pins: i2srx-0 {
++ clk-sd-pins {
++ pinmux = <GPIOMUX(38, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_I2SRX_BCLK)>,
++ <GPIOMUX(63, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_I2SRX_LRCK)>,
++ <GPIOMUX(38, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_I2STX1_BCLK)>,
++ <GPIOMUX(63, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_I2STX1_LRCK)>,
++ <GPIOMUX(61, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_I2SRX_SDIN0)>;
++ input-enable;
++ };
++ };
++
++ i2stx1_pins: i2stx1-0 {
++ sd-pins {
++ pinmux = <GPIOMUX(44, GPOUT_SYS_I2STX1_SDO0,
++ GPOEN_ENABLE,
++ GPI_NONE)>;
++ bias-disable;
++ input-disable;
++ };
++ };
++
++ mclk_ext_pins: mclk-ext-0 {
++ mclk-ext-pins {
++ pinmux = <GPIOMUX(4, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_MCLK_EXT)>;
++ input-enable;
++ };
++ };
++
+ mmc0_pins: mmc0-0 {
+ rst-pins {
+ pinmux = <GPIOMUX(62, GPOUT_SYS_SDIO0_RST,
+@@ -400,6 +519,86 @@
+ slew-rate = <0>;
+ };
+ };
++
++ pcie0_pins: pcie0-0 {
++ clkreq-pins {
++ pinmux = <GPIOMUX(27, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_NONE)>;
++ bias-pull-down;
++ drive-strength = <2>;
++ input-enable;
++ input-schmitt-disable;
++ slew-rate = <0>;
++ };
++
++ wake-pins {
++ pinmux = <GPIOMUX(32, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_NONE)>;
++ bias-pull-up;
++ drive-strength = <2>;
++ input-enable;
++ input-schmitt-disable;
++ slew-rate = <0>;
++ };
++ };
++
++ pcie1_pins: pcie1-0 {
++ clkreq-pins {
++ pinmux = <GPIOMUX(29, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_NONE)>;
++ bias-pull-down;
++ drive-strength = <2>;
++ input-enable;
++ input-schmitt-disable;
++ slew-rate = <0>;
++ };
++
++ wake-pins {
++ pinmux = <GPIOMUX(21, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_NONE)>;
++ bias-pull-up;
++ drive-strength = <2>;
++ input-enable;
++ input-schmitt-disable;
++ slew-rate = <0>;
++ };
++ };
++
++ pwm_pins: pwm-0 {
++ pwm-pins {
++ pinmux = <GPIOMUX(46, GPOUT_SYS_PWM_CHANNEL0,
++ GPOEN_SYS_PWM0_CHANNEL0,
++ GPI_NONE)>,
++ <GPIOMUX(59, GPOUT_SYS_PWM_CHANNEL1,
++ GPOEN_SYS_PWM0_CHANNEL1,
++ GPI_NONE)>;
++ bias-disable;
++ drive-strength = <12>;
++ input-disable;
++ input-schmitt-disable;
++ slew-rate = <0>;
++ };
++ };
++
++ pwmdac_pins: pwmdac-0 {
++ pwmdac-pins {
++ pinmux = <GPIOMUX(33, GPOUT_SYS_PWMDAC_LEFT,
++ GPOEN_ENABLE,
++ GPI_NONE)>,
++ <GPIOMUX(34, GPOUT_SYS_PWMDAC_RIGHT,
++ GPOEN_ENABLE,
++ GPI_NONE)>;
++ bias-disable;
++ drive-strength = <2>;
++ input-disable;
++ input-schmitt-disable;
++ slew-rate = <0>;
++ };
++ };
+
+ spi0_pins: spi0-0 {
+ mosi-pins {
+--- a/arch/riscv/boot/dts/starfive/jh7110.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7110.dtsi
+@@ -244,6 +244,7 @@
+ clock-output-names = "dvp_clk";
+ #clock-cells = <0>;
+ };
++
+ gmac0_rgmii_rxin: gmac0-rgmii-rxin-clock {
+ compatible = "fixed-clock";
+ clock-output-names = "gmac0_rgmii_rxin";
+@@ -512,6 +513,43 @@
+ status = "disabled";
+ };
+
++ pwmdac: pwmdac@100b0000 {
++ compatible = "starfive,jh7110-pwmdac";
++ reg = <0x0 0x100b0000 0x0 0x1000>;
++ clocks = <&syscrg JH7110_SYSCLK_PWMDAC_APB>,
++ <&syscrg JH7110_SYSCLK_PWMDAC_CORE>;
++ clock-names = "apb", "core";
++ resets = <&syscrg JH7110_SYSRST_PWMDAC_APB>;
++ dmas = <&dma 22>;
++ dma-names = "tx";
++ #sound-dai-cells = <0>;
++ status = "disabled";
++ };
++
++ i2srx: i2s@100e0000 {
++ compatible = "starfive,jh7110-i2srx";
++ reg = <0x0 0x100e0000 0x0 0x1000>;
++ clocks = <&syscrg JH7110_SYSCLK_I2SRX_BCLK_MST>,
++ <&syscrg JH7110_SYSCLK_I2SRX_APB>,
++ <&syscrg JH7110_SYSCLK_MCLK>,
++ <&syscrg JH7110_SYSCLK_MCLK_INNER>,
++ <&mclk_ext>,
++ <&syscrg JH7110_SYSCLK_I2SRX_BCLK>,
++ <&syscrg JH7110_SYSCLK_I2SRX_LRCK>,
++ <&i2srx_bclk_ext>,
++ <&i2srx_lrck_ext>;
++ clock-names = "i2sclk", "apb", "mclk",
++ "mclk_inner", "mclk_ext", "bclk",
++ "lrck", "bclk_ext", "lrck_ext";
++ resets = <&syscrg JH7110_SYSRST_I2SRX_APB>,
++ <&syscrg JH7110_SYSRST_I2SRX_BCLK>;
++ dmas = <0>, <&dma 24>;
++ dma-names = "tx", "rx";
++ starfive,syscon = <&sys_syscon 0x18 0x2>;
++ #sound-dai-cells = <0>;
++ status = "disabled";
++ };
++
+ usb0: usb@10100000 {
+ compatible = "starfive,jh7110-usb";
+ ranges = <0x0 0x0 0x10100000 0x100000>;
+@@ -736,6 +774,56 @@
+ status = "disabled";
+ };
+
++ i2stx0: i2s@120b0000 {
++ compatible = "starfive,jh7110-i2stx0";
++ reg = <0x0 0x120b0000 0x0 0x1000>;
++ clocks = <&syscrg JH7110_SYSCLK_I2STX0_BCLK_MST>,
++ <&syscrg JH7110_SYSCLK_I2STX0_APB>,
++ <&syscrg JH7110_SYSCLK_MCLK>,
++ <&syscrg JH7110_SYSCLK_MCLK_INNER>,
++ <&mclk_ext>;
++ clock-names = "i2sclk", "apb", "mclk",
++ "mclk_inner","mclk_ext";
++ resets = <&syscrg JH7110_SYSRST_I2STX0_APB>,
++ <&syscrg JH7110_SYSRST_I2STX0_BCLK>;
++ dmas = <&dma 47>;
++ dma-names = "tx";
++ #sound-dai-cells = <0>;
++ status = "disabled";
++ };
++
++ i2stx1: i2s@120c0000 {
++ compatible = "starfive,jh7110-i2stx1";
++ reg = <0x0 0x120c0000 0x0 0x1000>;
++ clocks = <&syscrg JH7110_SYSCLK_I2STX1_BCLK_MST>,
++ <&syscrg JH7110_SYSCLK_I2STX1_APB>,
++ <&syscrg JH7110_SYSCLK_MCLK>,
++ <&syscrg JH7110_SYSCLK_MCLK_INNER>,
++ <&mclk_ext>,
++ <&syscrg JH7110_SYSCLK_I2STX1_BCLK>,
++ <&syscrg JH7110_SYSCLK_I2STX1_LRCK>,
++ <&i2stx_bclk_ext>,
++ <&i2stx_lrck_ext>;
++ clock-names = "i2sclk", "apb", "mclk",
++ "mclk_inner", "mclk_ext", "bclk",
++ "lrck", "bclk_ext", "lrck_ext";
++ resets = <&syscrg JH7110_SYSRST_I2STX1_APB>,
++ <&syscrg JH7110_SYSRST_I2STX1_BCLK>;
++ dmas = <&dma 48>;
++ dma-names = "tx";
++ #sound-dai-cells = <0>;
++ status = "disabled";
++ };
++
++ pwm: pwm@120d0000 {
++ compatible = "starfive,jh7110-pwm", "opencores,pwm-v1";
++ reg = <0x0 0x120d0000 0x0 0x10000>;
++ clocks = <&syscrg JH7110_SYSCLK_PWM_APB>;
++ resets = <&syscrg JH7110_SYSRST_PWM_APB>;
++ #pwm-cells = <3>;
++ status = "disabled";
++ };
++
+ sfctemp: temperature-sensor@120e0000 {
+ compatible = "starfive,jh7110-temp";
+ reg = <0x0 0x120e0000 0x0 0x10000>;
+@@ -811,6 +899,26 @@
+ #gpio-cells = <2>;
+ };
+
++ timer@13050000 {
++ compatible = "starfive,jh7110-timer";
++ reg = <0x0 0x13050000 0x0 0x10000>;
++ interrupts = <69>, <70>, <71>, <72>;
++ clocks = <&syscrg JH7110_SYSCLK_TIMER_APB>,
++ <&syscrg JH7110_SYSCLK_TIMER0>,
++ <&syscrg JH7110_SYSCLK_TIMER1>,
++ <&syscrg JH7110_SYSCLK_TIMER2>,
++ <&syscrg JH7110_SYSCLK_TIMER3>;
++ clock-names = "apb", "ch0", "ch1",
++ "ch2", "ch3";
++ resets = <&syscrg JH7110_SYSRST_TIMER_APB>,
++ <&syscrg JH7110_SYSRST_TIMER0>,
++ <&syscrg JH7110_SYSRST_TIMER1>,
++ <&syscrg JH7110_SYSRST_TIMER2>,
++ <&syscrg JH7110_SYSRST_TIMER3>;
++ reset-names = "apb", "ch0", "ch1",
++ "ch2", "ch3";
++ };
++
+ watchdog@13070000 {
+ compatible = "starfive,jh7110-wdt";
+ reg = <0x0 0x13070000 0x0 0x10000>;
+@@ -1011,6 +1119,32 @@
+ #power-domain-cells = <1>;
+ };
+
++ csi2rx: csi-bridge@19800000 {
++ compatible = "starfive,jh7110-csi2rx";
++ reg = <0x0 0x19800000 0x0 0x10000>;
++ clocks = <&ispcrg JH7110_ISPCLK_VIN_SYS>,
++ <&ispcrg JH7110_ISPCLK_VIN_APB>,
++ <&ispcrg JH7110_ISPCLK_VIN_PIXEL_IF0>,
++ <&ispcrg JH7110_ISPCLK_VIN_PIXEL_IF1>,
++ <&ispcrg JH7110_ISPCLK_VIN_PIXEL_IF2>,
++ <&ispcrg JH7110_ISPCLK_VIN_PIXEL_IF3>;
++ clock-names = "sys_clk", "p_clk",
++ "pixel_if0_clk", "pixel_if1_clk",
++ "pixel_if2_clk", "pixel_if3_clk";
++ resets = <&ispcrg JH7110_ISPRST_VIN_SYS>,
++ <&ispcrg JH7110_ISPRST_VIN_APB>,
++ <&ispcrg JH7110_ISPRST_VIN_PIXEL_IF0>,
++ <&ispcrg JH7110_ISPRST_VIN_PIXEL_IF1>,
++ <&ispcrg JH7110_ISPRST_VIN_PIXEL_IF2>,
++ <&ispcrg JH7110_ISPRST_VIN_PIXEL_IF3>;
++ reset-names = "sys", "reg_bank",
++ "pixel_if0", "pixel_if1",
++ "pixel_if2", "pixel_if3";
++ phys = <&csi_phy>;
++ phy-names = "dphy";
++ status = "disabled";
++ };
++
+ ispcrg: clock-controller@19810000 {
+ compatible = "starfive,jh7110-ispcrg";
+ reg = <0x0 0x19810000 0x0 0x10000>;
+@@ -1028,6 +1162,19 @@
+ power-domains = <&pwrc JH7110_PD_ISP>;
+ };
+
++ csi_phy: phy@19820000 {
++ compatible = "starfive,jh7110-dphy-rx";
++ reg = <0x0 0x19820000 0x0 0x10000>;
++ clocks = <&ispcrg JH7110_ISPCLK_M31DPHY_CFG_IN>,
++ <&ispcrg JH7110_ISPCLK_M31DPHY_REF_IN>,
++ <&ispcrg JH7110_ISPCLK_M31DPHY_TX_ESC_LAN0>;
++ clock-names = "cfg", "ref", "tx";
++ resets = <&ispcrg JH7110_ISPRST_M31DPHY_HW>,
++ <&ispcrg JH7110_ISPRST_M31DPHY_B09_AON>;
++ power-domains = <&aon_syscon JH7110_AON_PD_DPHY_RX>;
++ #phy-cells = <0>;
++ };
++
+ voutcrg: clock-controller@295c0000 {
+ compatible = "starfive,jh7110-voutcrg";
+ reg = <0x0 0x295c0000 0x0 0x10000>;
+@@ -1045,5 +1192,91 @@
+ #reset-cells = <1>;
+ power-domains = <&pwrc JH7110_PD_VOUT>;
+ };
++
++ pcie0: pcie@940000000 {
++ compatible = "starfive,jh7110-pcie";
++ reg = <0x9 0x40000000 0x0 0x1000000>,
++ <0x0 0x2b000000 0x0 0x100000>;
++ reg-names = "cfg", "apb";
++ linux,pci-domain = <0>;
++ #address-cells = <3>;
++ #size-cells = <2>;
++ #interrupt-cells = <1>;
++ ranges = <0x82000000 0x0 0x30000000 0x0 0x30000000 0x0 0x08000000>,
++ <0xc3000000 0x9 0x00000000 0x9 0x00000000 0x0 0x40000000>;
++ interrupts = <56>;
++ interrupt-map-mask = <0x0 0x0 0x0 0x7>;
++ interrupt-map = <0x0 0x0 0x0 0x1 &pcie_intc0 0x1>,
++ <0x0 0x0 0x0 0x2 &pcie_intc0 0x2>,
++ <0x0 0x0 0x0 0x3 &pcie_intc0 0x3>,
++ <0x0 0x0 0x0 0x4 &pcie_intc0 0x4>;
++ msi-controller;
++ device_type = "pci";
++ starfive,stg-syscon = <&stg_syscon>;
++ bus-range = <0x0 0xff>;
++ clocks = <&syscrg JH7110_SYSCLK_NOC_BUS_STG_AXI>,
++ <&stgcrg JH7110_STGCLK_PCIE0_TL>,
++ <&stgcrg JH7110_STGCLK_PCIE0_AXI_MST0>,
++ <&stgcrg JH7110_STGCLK_PCIE0_APB>;
++ clock-names = "noc", "tl", "axi_mst0", "apb";
++ resets = <&stgcrg JH7110_STGRST_PCIE0_AXI_MST0>,
++ <&stgcrg JH7110_STGRST_PCIE0_AXI_SLV0>,
++ <&stgcrg JH7110_STGRST_PCIE0_AXI_SLV>,
++ <&stgcrg JH7110_STGRST_PCIE0_BRG>,
++ <&stgcrg JH7110_STGRST_PCIE0_CORE>,
++ <&stgcrg JH7110_STGRST_PCIE0_APB>;
++ reset-names = "mst0", "slv0", "slv", "brg",
++ "core", "apb";
++ status = "disabled";
++
++ pcie_intc0: interrupt-controller {
++ #address-cells = <0>;
++ #interrupt-cells = <1>;
++ interrupt-controller;
++ };
++ };
++
++ pcie1: pcie@9c0000000 {
++ compatible = "starfive,jh7110-pcie";
++ reg = <0x9 0xc0000000 0x0 0x1000000>,
++ <0x0 0x2c000000 0x0 0x100000>;
++ reg-names = "cfg", "apb";
++ linux,pci-domain = <1>;
++ #address-cells = <3>;
++ #size-cells = <2>;
++ #interrupt-cells = <1>;
++ ranges = <0x82000000 0x0 0x38000000 0x0 0x38000000 0x0 0x08000000>,
++ <0xc3000000 0x9 0x80000000 0x9 0x80000000 0x0 0x40000000>;
++ interrupts = <57>;
++ interrupt-map-mask = <0x0 0x0 0x0 0x7>;
++ interrupt-map = <0x0 0x0 0x0 0x1 &pcie_intc1 0x1>,
++ <0x0 0x0 0x0 0x2 &pcie_intc1 0x2>,
++ <0x0 0x0 0x0 0x3 &pcie_intc1 0x3>,
++ <0x0 0x0 0x0 0x4 &pcie_intc1 0x4>;
++ msi-controller;
++ device_type = "pci";
++ starfive,stg-syscon = <&stg_syscon>;
++ bus-range = <0x0 0xff>;
++ clocks = <&syscrg JH7110_SYSCLK_NOC_BUS_STG_AXI>,
++ <&stgcrg JH7110_STGCLK_PCIE1_TL>,
++ <&stgcrg JH7110_STGCLK_PCIE1_AXI_MST0>,
++ <&stgcrg JH7110_STGCLK_PCIE1_APB>;
++ clock-names = "noc", "tl", "axi_mst0", "apb";
++ resets = <&stgcrg JH7110_STGRST_PCIE1_AXI_MST0>,
++ <&stgcrg JH7110_STGRST_PCIE1_AXI_SLV0>,
++ <&stgcrg JH7110_STGRST_PCIE1_AXI_SLV>,
++ <&stgcrg JH7110_STGRST_PCIE1_BRG>,
++ <&stgcrg JH7110_STGRST_PCIE1_CORE>,
++ <&stgcrg JH7110_STGRST_PCIE1_APB>;
++ reset-names = "mst0", "slv0", "slv", "brg",
++ "core", "apb";
++ status = "disabled";
++
++ pcie_intc1: interrupt-controller {
++ #address-cells = <0>;
++ #interrupt-cells = <1>;
++ interrupt-controller;
++ };
++ };
+ };
+ };
diff --git a/target/linux/starfive/patches-6.6/0049-MAINTAINERS-Update-all-StarFive-entries.patch b/target/linux/starfive/patches-6.6/0049-MAINTAINERS-Update-all-StarFive-entries.patch
new file mode 100644
index 0000000000..a7a832dce2
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0049-MAINTAINERS-Update-all-StarFive-entries.patch
@@ -0,0 +1,147 @@
+From ae7b57a0c69953f5ec06a378aedeed4c86637998 Mon Sep 17 00:00:00 2001
+From: Hal Feng <hal.feng@starfivetech.com>
+Date: Tue, 11 Apr 2023 16:25:57 +0800
+Subject: [PATCH 049/116] MAINTAINERS: Update all StarFive entries
+
+Merge all StarFive maintainers changes together.
+
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ MAINTAINERS | 61 +++++++++++++++++++++++++++++++++++++++++++++++++----
+ 1 file changed, 57 insertions(+), 4 deletions(-)
+
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -7053,6 +7053,14 @@ T: git git://anongit.freedesktop.org/drm
+ F: Documentation/devicetree/bindings/display/rockchip/
+ F: drivers/gpu/drm/rockchip/
+
++DRM DRIVERS FOR STARFIVE
++M: Keith Zhao <keith.zhao@starfivetech.com>
++L: dri-devel@lists.freedesktop.org
++S: Maintained
++T: git git://anongit.freedesktop.org/drm/drm-misc
++F: Documentation/devicetree/bindings/display/starfive/
++F: drivers/gpu/drm/verisilicon/
++
+ DRM DRIVERS FOR STI
+ M: Alain Volmat <alain.volmat@foss.st.com>
+ L: dri-devel@lists.freedesktop.org
+@@ -16016,6 +16024,13 @@ F: Documentation/i2c/busses/i2c-ocores.r
+ F: drivers/i2c/busses/i2c-ocores.c
+ F: include/linux/platform_data/i2c-ocores.h
+
++OPENCORES PWM DRIVER
++M: William Qiu <william.qiu@starfivetech.com>
++M: Hal Feng <hal.feng@starfivetech.com>
++S: Supported
++F: Documentation/devicetree/bindings/pwm/opencores,pwm.yaml
++F: drivers/pwm/pwm-ocores.c
++
+ OPENRISC ARCHITECTURE
+ M: Jonas Bonn <jonas@southpole.se>
+ M: Stefan Kristiansson <stefan.kristiansson@saunalahti.fi>
+@@ -16427,6 +16442,14 @@ S: Maintained
+ F: Documentation/devicetree/bindings/pci/layerscape-pcie-gen4.txt
+ F: drivers/pci/controller/mobiveil/pcie-layerscape-gen4.c
+
++PCI DRIVER FOR PLDA PCIE IP
++M: Daire McNamara <daire.mcnamara@microchip.com>
++M: Kevin Xie <kevin.xie@starfivetech.com>
++L: linux-pci@vger.kernel.org
++S: Maintained
++F: Documentation/devicetree/bindings/pci/plda,*
++F: drivers/pci/controller/plda/*plda*
++
+ PCI DRIVER FOR RENESAS R-CAR
+ M: Marek Vasut <marek.vasut+renesas@gmail.com>
+ M: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
+@@ -16658,7 +16681,7 @@ M: Daire McNamara <daire.mcnamara@microc
+ L: linux-pci@vger.kernel.org
+ S: Supported
+ F: Documentation/devicetree/bindings/pci/microchip*
+-F: drivers/pci/controller/*microchip*
++F: drivers/pci/controller/plda/*microchip*
+
+ PCIE DRIVER FOR QUALCOMM MSM
+ M: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+@@ -16682,6 +16705,13 @@ S: Maintained
+ F: Documentation/devicetree/bindings/pci/socionext,uniphier-pcie*
+ F: drivers/pci/controller/dwc/pcie-uniphier*
+
++PCIE DRIVER FOR STARFIVE JH71x0
++M: Kevin Xie <kevin.xie@starfivetech.com>
++L: linux-pci@vger.kernel.org
++S: Maintained
++F: Documentation/devicetree/bindings/pci/starfive*
++F: drivers/pci/controller/plda/pcie-starfive.c
++
+ PCIE DRIVER FOR ST SPEAR13XX
+ M: Pratyush Anand <pratyush.anand@gmail.com>
+ L: linux-pci@vger.kernel.org
+@@ -18454,7 +18484,7 @@ F: drivers/char/hw_random/mpfs-rng.c
+ F: drivers/clk/microchip/clk-mpfs*.c
+ F: drivers/i2c/busses/i2c-microchip-corei2c.c
+ F: drivers/mailbox/mailbox-mpfs.c
+-F: drivers/pci/controller/pcie-microchip-host.c
++F: drivers/pci/controller/plda/pcie-microchip-host.c
+ F: drivers/pwm/pwm-microchip-core.c
+ F: drivers/reset/reset-mpfs.c
+ F: drivers/rtc/rtc-mpfs.c
+@@ -20435,6 +20465,15 @@ M: Ion Badulescu <ionut@badula.org>
+ S: Odd Fixes
+ F: drivers/net/ethernet/adaptec/starfire*
+
++STARFIVE CAMERA SUBSYSTEM DRIVER
++M: Jack Zhu <jack.zhu@starfivetech.com>
++M: Changhuang Liang <changhuang.liang@starfivetech.com>
++L: linux-media@vger.kernel.org
++S: Maintained
++F: Documentation/admin-guide/media/starfive_camss.rst
++F: Documentation/devicetree/bindings/media/starfive,jh7110-camss.yaml
++F: drivers/staging/media/starfive/camss
++
+ STARFIVE CRYPTO DRIVER
+ M: Jia Jie Ho <jiajie.ho@starfivetech.com>
+ M: William Qiu <william.qiu@starfivetech.com>
+@@ -20473,6 +20512,13 @@ S: Supported
+ F: Documentation/devicetree/bindings/clock/starfive,jh7110-pll.yaml
+ F: drivers/clk/starfive/clk-starfive-jh7110-pll.c
+
++STARFIVE JH7110 PWMDAC DRIVER
++M: Hal Feng <hal.feng@starfivetech.com>
++M: Xingyu Wu <xingyu.wu@starfivetech.com>
++S: Supported
++F: Documentation/devicetree/bindings/sound/starfive,jh7110-pwmdac.yaml
++F: sound/soc/starfive/jh7110_pwmdac.c
++
+ STARFIVE JH7110 SYSCON
+ M: William Qiu <william.qiu@starfivetech.com>
+ M: Xingyu Wu <xingyu.wu@starfivetech.com>
+@@ -20520,9 +20566,10 @@ F: drivers/usb/cdns3/cdns3-starfive.c
+
+ STARFIVE JH71XX PMU CONTROLLER DRIVER
+ M: Walker Chen <walker.chen@starfivetech.com>
++M: Changhuang Liang <changhuang.liang@starfivetech.com>
+ S: Supported
+ F: Documentation/devicetree/bindings/power/starfive*
+-F: drivers/pmdomain/starfive/jh71xx-pmu.c
++F: drivers/pmdomain/starfive/
+ F: include/dt-bindings/power/starfive,jh7110-pmu.h
+
+ STARFIVE SOC DRIVERS
+@@ -20530,7 +20577,13 @@ M: Conor Dooley <conor@kernel.org>
+ S: Maintained
+ T: git https://git.kernel.org/pub/scm/linux/kernel/git/conor/linux.git/
+ F: Documentation/devicetree/bindings/soc/starfive/
+-F: drivers/soc/starfive/
++
++STARFIVE JH7110 TIMER DRIVER
++M: Samin Guo <samin.guo@starfivetech.com>
++M: Xingyu Wu <xingyu.wu@starfivetech.com>
++S: Supported
++F: Documentation/devicetree/bindings/timer/starfive,jh7110-timer.yaml
++F: drivers/clocksource/timer-jh7110.c
+
+ STARFIVE TRNG DRIVER
+ M: Jia Jie Ho <jiajie.ho@starfivetech.com>
diff --git a/target/linux/starfive/patches-6.6/0050-mmc-starfive-Change-the-voltage-to-adapt-to-JH7110-E.patch b/target/linux/starfive/patches-6.6/0050-mmc-starfive-Change-the-voltage-to-adapt-to-JH7110-E.patch
new file mode 100644
index 0000000000..a38a885894
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0050-mmc-starfive-Change-the-voltage-to-adapt-to-JH7110-E.patch
@@ -0,0 +1,64 @@
+From e394195396995456ef98f52ac123c0cb64687748 Mon Sep 17 00:00:00 2001
+From: William Qiu <william.qiu@starfivetech.com>
+Date: Mon, 9 Oct 2023 10:59:03 +0800
+Subject: [PATCH 050/116] mmc: starfive: Change the voltage to adapt to JH7110
+ EVB
+
+Change the voltage, so the driver can adapt to JH7110 EVB.
+
+Signed-off-by: William Qiu <william.qiu@starfivetech.com>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ drivers/mmc/host/dw_mmc-starfive.c | 30 ++++++++++++++++++++++++++++++
+ 1 file changed, 30 insertions(+)
+
+--- a/drivers/mmc/host/dw_mmc-starfive.c
++++ b/drivers/mmc/host/dw_mmc-starfive.c
+@@ -8,6 +8,7 @@
+ #include <linux/bitfield.h>
+ #include <linux/clk.h>
+ #include <linux/delay.h>
++#include <linux/gpio.h>
+ #include <linux/mfd/syscon.h>
+ #include <linux/mmc/host.h>
+ #include <linux/module.h>
+@@ -95,10 +96,39 @@ out:
+ return ret;
+ }
+
++static int dw_mci_starfive_switch_voltage(struct mmc_host *mmc, struct mmc_ios *ios)
++{
++
++ struct dw_mci_slot *slot = mmc_priv(mmc);
++ struct dw_mci *host = slot->host;
++ u32 ret;
++
++ if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330)
++ ret = gpio_direction_output(25, 0);
++ else if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180)
++ ret = gpio_direction_output(25, 1);
++ if (ret)
++ return ret;
++
++ if (!IS_ERR(mmc->supply.vqmmc)) {
++ ret = mmc_regulator_set_vqmmc(mmc, ios);
++ if (ret < 0) {
++ dev_err(host->dev, "Regulator set error %d\n", ret);
++ return ret;
++ }
++ }
++
++ /* We should delay 20ms wait for timing setting finished. */
++ mdelay(20);
++
++ return 0;
++}
++
+ static const struct dw_mci_drv_data starfive_data = {
+ .common_caps = MMC_CAP_CMD23,
+ .set_ios = dw_mci_starfive_set_ios,
+ .execute_tuning = dw_mci_starfive_execute_tuning,
++ .switch_voltage = dw_mci_starfive_switch_voltage,
+ };
+
+ static const struct of_device_id dw_mci_starfive_match[] = {
diff --git a/target/linux/starfive/patches-6.6/0051-spi-spl022-Get-and-deassert-reset-in-probe.patch b/target/linux/starfive/patches-6.6/0051-spi-spl022-Get-and-deassert-reset-in-probe.patch
new file mode 100644
index 0000000000..485ab0d9e1
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0051-spi-spl022-Get-and-deassert-reset-in-probe.patch
@@ -0,0 +1,60 @@
+From 2cd3e51cb76d49d8db6274ebdc1ba1eb5c872f10 Mon Sep 17 00:00:00 2001
+From: "ziv.xu" <ziv.xu@starfivetech.com>
+Date: Sun, 4 Feb 2024 10:35:24 +0800
+Subject: [PATCH 051/116] spi: spl022: Get and deassert reset in probe()
+
+This fix spi1~6 communication time out.
+
+Signed-off-by: ziv.xu <ziv.xu@starfivetech.com>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ drivers/spi/spi-pl022.c | 17 +++++++++++++++++
+ 1 file changed, 17 insertions(+)
+
+--- a/drivers/spi/spi-pl022.c
++++ b/drivers/spi/spi-pl022.c
+@@ -33,6 +33,7 @@
+ #include <linux/pm_runtime.h>
+ #include <linux/of.h>
+ #include <linux/pinctrl/consumer.h>
++#include <linux/reset.h>
+
+ /*
+ * This macro is used to define some register default values.
+@@ -370,6 +371,7 @@ struct pl022 {
+ resource_size_t phybase;
+ void __iomem *virtbase;
+ struct clk *clk;
++ struct reset_control *rst;
+ struct spi_controller *host;
+ struct pl022_ssp_controller *host_info;
+ /* Message per-transfer pump */
+@@ -2181,6 +2183,19 @@ static int pl022_probe(struct amba_devic
+ goto err_no_clk_en;
+ }
+
++ pl022->rst = devm_reset_control_get(&adev->dev, NULL);
++ if (IS_ERR(pl022->rst)) {
++ status = PTR_ERR(pl022->rst);
++ dev_err(&adev->dev, "could not retrieve SSP/SPI bus reset\n");
++ goto err_no_rst;
++ }
++
++ status = reset_control_deassert(pl022->rst);
++ if (status) {
++ dev_err(&adev->dev, "could not deassert SSP/SPI bus reset\n");
++ goto err_no_rst_de;
++ }
++
+ /* Initialize transfer pump */
+ tasklet_init(&pl022->pump_transfers, pump_transfers,
+ (unsigned long)pl022);
+@@ -2240,6 +2255,8 @@ static int pl022_probe(struct amba_devic
+ if (platform_info->enable_dma)
+ pl022_dma_remove(pl022);
+ err_no_irq:
++ err_no_rst_de:
++ err_no_rst:
+ clk_disable_unprepare(pl022->clk);
+ err_no_clk_en:
+ err_no_clk:
diff --git a/target/linux/starfive/patches-6.6/0052-ASoC-dwc-i2s-Fix-getting-platform-data-error-for-Sta.patch b/target/linux/starfive/patches-6.6/0052-ASoC-dwc-i2s-Fix-getting-platform-data-error-for-Sta.patch
new file mode 100644
index 0000000000..e274e84a25
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0052-ASoC-dwc-i2s-Fix-getting-platform-data-error-for-Sta.patch
@@ -0,0 +1,30 @@
+From 9cc8de0cdc1600f460f618e342e1f524adad07c4 Mon Sep 17 00:00:00 2001
+From: Xingyu Wu <xingyu.wu@starfivetech.com>
+Date: Wed, 21 Feb 2024 10:23:48 +0800
+Subject: [PATCH 052/116] ASoC: dwc: i2s: Fix getting platform data error for
+ StarFive JH7110
+
+JH7110 need to use a DT specific function to get the platform data,
+otherwise, it fails in probe().
+
+Fixes: 9c97790a07dc ("ASoC: dwc: Fix non-DT instantiation")
+Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ sound/soc/dwc/dwc-i2s.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/sound/soc/dwc/dwc-i2s.c
++++ b/sound/soc/dwc/dwc-i2s.c
+@@ -917,7 +917,11 @@ static int jh7110_i2stx0_clk_cfg(struct
+
+ static int dw_i2s_probe(struct platform_device *pdev)
+ {
++#ifdef CONFIG_OF
++ const struct i2s_platform_data *pdata = of_device_get_match_data(&pdev->dev);
++#else
+ const struct i2s_platform_data *pdata = pdev->dev.platform_data;
++#endif
+ struct dw_i2s_dev *dev;
+ struct resource *res;
+ int ret, irq;
diff --git a/target/linux/starfive/patches-6.6/0053-ASoC-dwc-i2s-Add-RX-master-support-for-StarFive-JH71.patch b/target/linux/starfive/patches-6.6/0053-ASoC-dwc-i2s-Add-RX-master-support-for-StarFive-JH71.patch
new file mode 100644
index 0000000000..8203beca52
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0053-ASoC-dwc-i2s-Add-RX-master-support-for-StarFive-JH71.patch
@@ -0,0 +1,67 @@
+From 1be9bd37fdb5f50162dba0158e1fee295ebca9aa Mon Sep 17 00:00:00 2001
+From: Xingyu Wu <xingyu.wu@starfivetech.com>
+Date: Tue, 17 Oct 2023 17:22:52 +0800
+Subject: [PATCH 053/116] ASoC: dwc: i2s: Add RX master support for StarFive
+ JH7110 SoC
+
+Add JH7110 I2S RX master support, so the PDM can work on JH7110
+EVB board.
+
+Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ sound/soc/dwc/dwc-i2s.c | 31 +++++++++++++++++++++++++++++++
+ 1 file changed, 31 insertions(+)
+
+--- a/sound/soc/dwc/dwc-i2s.c
++++ b/sound/soc/dwc/dwc-i2s.c
+@@ -906,6 +906,27 @@ static int jh7110_i2srx_crg_init(struct
+ return jh7110_i2s_crg_slave_init(dev);
+ }
+
++/* Special syscon initialization about RX channel with master mode on JH7110 SoC */
++static int jh7110_i2srx_mst_crg_init(struct dw_i2s_dev *dev)
++{
++ struct regmap *regmap;
++ unsigned int args[5];
++
++ regmap = syscon_regmap_lookup_by_phandle_args(dev->dev->of_node,
++ "starfive,syscon",
++ 5, args);
++ if (IS_ERR(regmap))
++ return dev_err_probe(dev->dev, PTR_ERR(regmap), "getting the regmap failed\n");
++
++ /* Enable I2Srx with syscon register, args[0]: offset, args[1]: mask */
++ regmap_update_bits(regmap, args[0], args[1], args[1]);
++
++ /* Change I2Srx source (PDM) with syscon register, args[0]: offset, args[1]: mask */
++ regmap_update_bits(regmap, args[2], args[3], args[4]);
++
++ return jh7110_i2s_crg_master_init(dev);
++}
++
+ static int jh7110_i2stx0_clk_cfg(struct i2s_clk_config_data *config)
+ {
+ struct dw_i2s_dev *dev = container_of(config, struct dw_i2s_dev, config);
+@@ -1086,11 +1107,21 @@ static const struct i2s_platform_data jh
+ .i2s_pd_init = jh7110_i2srx_crg_init,
+ };
+
++static const struct i2s_platform_data jh7110_i2srx_mst_data = {
++ .cap = DWC_I2S_RECORD | DW_I2S_MASTER,
++ .channel = TWO_CHANNEL_SUPPORT,
++ .snd_fmts = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
++ .snd_rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000,
++ .i2s_clk_cfg = jh7110_i2stx0_clk_cfg,
++ .i2s_pd_init = jh7110_i2srx_mst_crg_init,
++};
++
+ static const struct of_device_id dw_i2s_of_match[] = {
+ { .compatible = "snps,designware-i2s", },
+ { .compatible = "starfive,jh7110-i2stx0", .data = &jh7110_i2stx0_data, },
+ { .compatible = "starfive,jh7110-i2stx1", .data = &jh7110_i2stx1_data,},
+ { .compatible = "starfive,jh7110-i2srx", .data = &jh7110_i2srx_data,},
++ { .compatible = "starfive,jh7110-i2srx-master", .data = &jh7110_i2srx_mst_data,},
+ {},
+ };
+
diff --git a/target/linux/starfive/patches-6.6/0054-pinctrl-starfive-jh7110-Unset-.strict-in-pinmux_ops.patch b/target/linux/starfive/patches-6.6/0054-pinctrl-starfive-jh7110-Unset-.strict-in-pinmux_ops.patch
new file mode 100644
index 0000000000..51976c656e
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0054-pinctrl-starfive-jh7110-Unset-.strict-in-pinmux_ops.patch
@@ -0,0 +1,24 @@
+From 1ec26ba377d8ae59cd09811ec78623a750a9c150 Mon Sep 17 00:00:00 2001
+From: Hal Feng <hal.feng@starfivetech.com>
+Date: Mon, 26 Feb 2024 11:35:44 +0800
+Subject: [PATCH 054/116] pinctrl: starfive: jh7110: Unset .strict in
+ pinmux_ops
+
+Allow simultaneous use of the same pin for GPIO and another function.
+This feature is used in HDMI hot plug detect.
+
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ drivers/pinctrl/starfive/pinctrl-starfive-jh7110.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/drivers/pinctrl/starfive/pinctrl-starfive-jh7110.c
++++ b/drivers/pinctrl/starfive/pinctrl-starfive-jh7110.c
+@@ -327,7 +327,6 @@ static const struct pinmux_ops jh7110_pi
+ .get_function_name = pinmux_generic_get_function_name,
+ .get_function_groups = pinmux_generic_get_function_groups,
+ .set_mux = jh7110_set_mux,
+- .strict = true,
+ };
+
+ static const u8 jh7110_drive_strength_mA[4] = { 2, 4, 8, 12 };
diff --git a/target/linux/starfive/patches-6.6/0055-mm-pgtable-generic.c-Export-symbol-__pte_offset_map.patch b/target/linux/starfive/patches-6.6/0055-mm-pgtable-generic.c-Export-symbol-__pte_offset_map.patch
new file mode 100644
index 0000000000..39699e8b97
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0055-mm-pgtable-generic.c-Export-symbol-__pte_offset_map.patch
@@ -0,0 +1,22 @@
+From 005549a2bd839335b0e3dc4152f00f642b524f07 Mon Sep 17 00:00:00 2001
+From: Hal Feng <hal.feng@starfivetech.com>
+Date: Sat, 7 Oct 2023 18:10:20 +0800
+Subject: [PATCH 055/116] mm/pgtable-generic.c: Export symbol __pte_offset_map
+
+So JH7110 vdec can call pte_offset_map() when it is built as a module.
+
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ mm/pgtable-generic.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/mm/pgtable-generic.c
++++ b/mm/pgtable-generic.c
+@@ -304,6 +304,7 @@ nomap:
+ rcu_read_unlock();
+ return NULL;
+ }
++EXPORT_SYMBOL(__pte_offset_map);
+
+ pte_t *pte_offset_map_nolock(struct mm_struct *mm, pmd_t *pmd,
+ unsigned long addr, spinlock_t **ptlp)
diff --git a/target/linux/starfive/patches-6.6/0056-riscv-dts-starfive-Add-JH7110-EVB-device-tree.patch b/target/linux/starfive/patches-6.6/0056-riscv-dts-starfive-Add-JH7110-EVB-device-tree.patch
new file mode 100644
index 0000000000..7b803d3997
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0056-riscv-dts-starfive-Add-JH7110-EVB-device-tree.patch
@@ -0,0 +1,2623 @@
+From 9f46b0d43f8945ff3a8b81ddc6567df370b60911 Mon Sep 17 00:00:00 2001
+From: Hal Feng <hal.feng@starfivetech.com>
+Date: Fri, 28 Jul 2023 17:19:12 +0800
+Subject: [PATCH 056/116] riscv: dts: starfive: Add JH7110 EVB device tree
+
+Add JH7110 evaluation board device tree.
+The code is ported from tag JH7110_SDK_6.1_v5.11.3
+
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ arch/riscv/boot/dts/starfive/Makefile | 3 +
+ arch/riscv/boot/dts/starfive/jh7110-clk.dtsi | 80 ++
+ .../boot/dts/starfive/jh7110-evb-pinctrl.dtsi | 997 ++++++++++++++++++
+ arch/riscv/boot/dts/starfive/jh7110-evb.dts | 35 +
+ arch/riscv/boot/dts/starfive/jh7110-evb.dtsi | 854 +++++++++++++++
+ arch/riscv/boot/dts/starfive/jh7110.dtsi | 482 ++++++++-
+ 6 files changed, 2444 insertions(+), 7 deletions(-)
+ create mode 100644 arch/riscv/boot/dts/starfive/jh7110-clk.dtsi
+ create mode 100644 arch/riscv/boot/dts/starfive/jh7110-evb-pinctrl.dtsi
+ create mode 100644 arch/riscv/boot/dts/starfive/jh7110-evb.dts
+ create mode 100644 arch/riscv/boot/dts/starfive/jh7110-evb.dtsi
+
+--- a/arch/riscv/boot/dts/starfive/Makefile
++++ b/arch/riscv/boot/dts/starfive/Makefile
+@@ -4,9 +4,12 @@ DTC_FLAGS_jh7100-beaglev-starlight := -@
+ DTC_FLAGS_jh7100-starfive-visionfive-v1 := -@
+ DTC_FLAGS_jh7110-starfive-visionfive-2-v1.2a := -@
+ DTC_FLAGS_jh7110-starfive-visionfive-2-v1.3b := -@
++DTC_FLAGS_jh7110-evb := -@
+
+ dtb-$(CONFIG_ARCH_STARFIVE) += jh7100-beaglev-starlight.dtb
+ dtb-$(CONFIG_ARCH_STARFIVE) += jh7100-starfive-visionfive-v1.dtb
+
+ dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-starfive-visionfive-2-v1.2a.dtb
+ dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-starfive-visionfive-2-v1.3b.dtb
++
++dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-evb.dtb
+--- /dev/null
++++ b/arch/riscv/boot/dts/starfive/jh7110-clk.dtsi
+@@ -0,0 +1,80 @@
++// SPDX-License-Identifier: GPL-2.0 OR MIT
++/*
++ * Copyright (C) 2023 StarFive Technology Co., Ltd.
++ */
++
++/ {
++ ac108_mclk: ac108_mclk {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <24000000>;
++ };
++
++ clk_ext_camera: clk-ext-camera {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <24000000>;
++ };
++
++ wm8960_mclk: wm8960_mclk {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <24576000>;
++ };
++};
++
++&dvp_clk {
++ clock-frequency = <74250000>;
++};
++
++&gmac0_rgmii_rxin {
++ clock-frequency = <125000000>;
++};
++
++&gmac0_rmii_refin {
++ clock-frequency = <50000000>;
++};
++
++&gmac1_rgmii_rxin {
++ clock-frequency = <125000000>;
++};
++
++&gmac1_rmii_refin {
++ clock-frequency = <50000000>;
++};
++
++&hdmitx0_pixelclk {
++ clock-frequency = <297000000>;
++};
++
++&i2srx_bclk_ext {
++ clock-frequency = <12288000>;
++};
++
++&i2srx_lrck_ext {
++ clock-frequency = <192000>;
++};
++
++&i2stx_bclk_ext {
++ clock-frequency = <12288000>;
++};
++
++&i2stx_lrck_ext {
++ clock-frequency = <192000>;
++};
++
++&mclk_ext {
++ clock-frequency = <12288000>;
++};
++
++&osc {
++ clock-frequency = <24000000>;
++};
++
++&rtc_osc {
++ clock-frequency = <32768>;
++};
++
++&tdm_ext {
++ clock-frequency = <49152000>;
++};
+--- /dev/null
++++ b/arch/riscv/boot/dts/starfive/jh7110-evb-pinctrl.dtsi
+@@ -0,0 +1,997 @@
++// SPDX-License-Identifier: GPL-2.0 OR MIT
++/*
++ * Copyright (C) 2023 StarFive Technology Co., Ltd.
++ * Author: Hal Feng <hal.feng@starfivetech.com>
++ */
++
++#include "jh7110-pinfunc.h"
++
++&sysgpio {
++ can0_pins: can0-0 {
++ can-pins {
++ pinmux = <GPIOMUX(30, GPOUT_SYS_CAN0_TXD,
++ GPOEN_ENABLE,
++ GPI_NONE)>,
++ <GPIOMUX(31, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_CAN0_RXD)>,
++ <GPIOMUX(32, GPOUT_SYS_CAN0_STBY,
++ GPOEN_ENABLE,
++ GPI_NONE)>;
++ input-enable;
++ };
++ };
++
++ can1_pins: can1-0 {
++ can-pins {
++ pinmux = <GPIOMUX(29, GPOUT_SYS_CAN1_TXD,
++ GPOEN_ENABLE,
++ GPI_NONE)>,
++ <GPIOMUX(27, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_CAN1_RXD)>,
++ <GPIOMUX(45, GPOUT_SYS_CAN1_STBY,
++ GPOEN_ENABLE,
++ GPI_NONE)>;
++ drive-strength = <12>;
++ input-enable;
++ };
++ };
++
++ dvp_pins: dvp-0 {
++ dvp-pins{
++ pinmux = <PINMUX(21, 2)>,
++ <PINMUX(22, 2)>,
++ <PINMUX(23, 2)>,
++ <PINMUX(24, 2)>,
++ <PINMUX(25, 2)>,
++ <PINMUX(26, 2)>,
++ <PINMUX(27, 2)>,
++ <PINMUX(28, 2)>,
++ <PINMUX(29, 2)>,
++ <PINMUX(30, 2)>,
++ <PINMUX(31, 2)>,
++ <PINMUX(32, 2)>,
++ <PINMUX(33, 2)>,
++ <PINMUX(34, 2)>,
++ <PINMUX(35, 2)>;
++ input-enable;
++ };
++ };
++
++ emmc0_pins: emmc0-0 {
++ emmc-pins {
++ pinmux = <GPIOMUX(22, GPOUT_SYS_SDIO0_RST,
++ GPOEN_ENABLE,
++ GPI_NONE)>,
++ <PINMUX(64, 0)>,
++ <PINMUX(65, 0)>,
++ <PINMUX(66, 0)>,
++ <PINMUX(67, 0)>,
++ <PINMUX(68, 0)>,
++ <PINMUX(69, 0)>,
++ <PINMUX(70, 0)>,
++ <PINMUX(71, 0)>,
++ <PINMUX(72, 0)>,
++ <PINMUX(73, 0)>;
++ bias-pull-up;
++ drive-strength = <12>;
++ input-enable;
++ slew-rate = <1>;
++ };
++ };
++
++ emmc1_pins: emmc1-0 {
++ emmc-pins {
++ pinmux = <GPIOMUX(51, GPOUT_SYS_SDIO1_RST,
++ GPOEN_ENABLE,
++ GPI_NONE)>,
++ <GPIOMUX(38, GPOUT_SYS_SDIO1_CLK,
++ GPOEN_ENABLE,
++ GPI_NONE)>,
++ <GPIOMUX(36, GPOUT_SYS_SDIO1_CMD,
++ GPOEN_SYS_SDIO1_CMD,
++ GPI_SYS_SDIO1_CMD)>,
++ <GPIOMUX(43, GPOUT_SYS_SDIO1_DATA0,
++ GPOEN_SYS_SDIO1_DATA0,
++ GPI_SYS_SDIO1_DATA0)>,
++ <GPIOMUX(48, GPOUT_SYS_SDIO1_DATA1,
++ GPOEN_SYS_SDIO1_DATA1,
++ GPI_SYS_SDIO1_DATA1)>,
++ <GPIOMUX(53, GPOUT_SYS_SDIO1_DATA2,
++ GPOEN_SYS_SDIO1_DATA2,
++ GPI_SYS_SDIO1_DATA2)>,
++ <GPIOMUX(63, GPOUT_SYS_SDIO1_DATA3,
++ GPOEN_SYS_SDIO1_DATA3,
++ GPI_SYS_SDIO1_DATA3)>,
++ <GPIOMUX(52, GPOUT_SYS_SDIO1_DATA4,
++ GPOEN_SYS_SDIO1_DATA4,
++ GPI_SYS_SDIO1_DATA4)>,
++ <GPIOMUX(39, GPOUT_SYS_SDIO1_DATA5,
++ GPOEN_SYS_SDIO1_DATA5,
++ GPI_SYS_SDIO1_DATA5)>,
++ <GPIOMUX(46, GPOUT_SYS_SDIO1_DATA6,
++ GPOEN_SYS_SDIO1_DATA6,
++ GPI_SYS_SDIO1_DATA6)>,
++ <GPIOMUX(47, GPOUT_SYS_SDIO1_DATA7,
++ GPOEN_SYS_SDIO1_DATA7,
++ GPI_SYS_SDIO1_DATA7)>;
++ bias-pull-up;
++ input-enable;
++ };
++ };
++
++ gmac0_pins: gmac0-0 {
++ reset-pins {
++ pinmux = <GPIOMUX(13, GPOUT_HIGH,
++ GPOEN_ENABLE,
++ GPI_NONE)>;
++ bias-pull-up;
++ };
++ };
++
++ gmac1_pins: gmac1-0 {
++ mdc-pins {
++ pinmux = <PINMUX(75, 0)>;
++ };
++ };
++
++ hdmi_pins: hdmi-0 {
++ scl-pins {
++ pinmux = <GPIOMUX(7, GPOUT_SYS_HDMI_DDC_SCL,
++ GPOEN_SYS_HDMI_DDC_SCL,
++ GPI_SYS_HDMI_DDC_SCL)>;
++ bias-pull-up;
++ input-enable;
++ };
++
++ sda-pins {
++ pinmux = <GPIOMUX(8, GPOUT_SYS_HDMI_DDC_SDA,
++ GPOEN_SYS_HDMI_DDC_SDA,
++ GPI_SYS_HDMI_DDC_SDA)>;
++ bias-pull-up;
++ input-enable;
++ };
++
++ cec-pins {
++ pinmux = <GPIOMUX(14, GPOUT_SYS_HDMI_CEC_SDA,
++ GPOEN_SYS_HDMI_CEC_SDA,
++ GPI_SYS_HDMI_CEC_SDA)>;
++ bias-pull-up;
++ input-enable;
++ };
++
++ hpd-pins {
++ pinmux = <GPIOMUX(15, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_HDMI_HPD)>;
++ bias-disable; /* external pull-up */
++ input-enable;
++ };
++ };
++
++ i2c0_pins: i2c0-0 {
++ i2c-pins {
++ pinmux = <GPIOMUX(57, GPOUT_LOW,
++ GPOEN_SYS_I2C0_CLK,
++ GPI_SYS_I2C0_CLK)>,
++ <GPIOMUX(58, GPOUT_LOW,
++ GPOEN_SYS_I2C0_DATA,
++ GPI_SYS_I2C0_DATA)>;
++ bias-pull-up;
++ input-enable;
++ input-schmitt-enable;
++ };
++ };
++
++ i2c1_pins: i2c1-0 {
++ i2c-pins {
++ pinmux = <GPIOMUX(49, GPOUT_LOW,
++ GPOEN_SYS_I2C1_CLK,
++ GPI_SYS_I2C1_CLK)>,
++ <GPIOMUX(50, GPOUT_LOW,
++ GPOEN_SYS_I2C1_DATA,
++ GPI_SYS_I2C1_DATA)>;
++ bias-pull-up;
++ input-enable;
++ input-schmitt-enable;
++ };
++ };
++
++ i2c2_pins: i2c2-0 {
++ i2c-pins {
++ pinmux = <GPIOMUX(11, GPOUT_LOW,
++ GPOEN_SYS_I2C2_CLK,
++ GPI_SYS_I2C2_CLK)>,
++ <GPIOMUX(9, GPOUT_LOW,
++ GPOEN_SYS_I2C2_DATA,
++ GPI_SYS_I2C2_DATA)>;
++ bias-pull-up;
++ input-enable;
++ input-schmitt-enable;
++ };
++ };
++
++ i2c3_pins: i2c3-0 {
++ i2c-pins {
++ pinmux = <GPIOMUX(51, GPOUT_LOW,
++ GPOEN_SYS_I2C3_CLK,
++ GPI_SYS_I2C3_CLK)>,
++ <GPIOMUX(52, GPOUT_LOW,
++ GPOEN_SYS_I2C3_DATA,
++ GPI_SYS_I2C3_DATA)>;
++ bias-pull-up;
++ input-enable;
++ input-schmitt-enable;
++ };
++ };
++
++ i2c4_pins: i2c4-0 {
++ i2c-pins {
++ pinmux = <GPIOMUX(18, GPOUT_LOW,
++ GPOEN_SYS_I2C4_CLK,
++ GPI_SYS_I2C4_CLK)>,
++ <GPIOMUX(12, GPOUT_LOW,
++ GPOEN_SYS_I2C4_DATA,
++ GPI_SYS_I2C4_DATA)>;
++ bias-pull-up;
++ input-enable;
++ input-schmitt-enable;
++ };
++ };
++
++ i2c5_pins: i2c5-0 {
++ i2c-pins {
++ pinmux = <GPIOMUX(19, GPOUT_LOW,
++ GPOEN_SYS_I2C5_CLK,
++ GPI_SYS_I2C5_CLK)>,
++ <GPIOMUX(20, GPOUT_LOW,
++ GPOEN_SYS_I2C5_DATA,
++ GPI_SYS_I2C5_DATA)>;
++ bias-pull-up;
++ input-enable;
++ input-schmitt-enable;
++ };
++ };
++
++ i2c6_pins: i2c6-0 {
++ i2c-pins {
++ pinmux = <GPIOMUX(16, GPOUT_LOW,
++ GPOEN_SYS_I2C6_CLK,
++ GPI_SYS_I2C6_CLK)>,
++ <GPIOMUX(17, GPOUT_LOW,
++ GPOEN_SYS_I2C6_DATA,
++ GPI_SYS_I2C6_DATA)>;
++ bias-pull-up;
++ input-enable;
++ input-schmitt-enable;
++ };
++ };
++
++ i2s_clk_pins: i2s-clk-0 {
++ bclk-lrck-pins {
++ pinmux = <GPIOMUX(38, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_I2STX1_BCLK)>,
++ <GPIOMUX(38, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_I2SRX_BCLK)>,
++ <GPIOMUX(63, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_I2STX1_LRCK)>,
++ <GPIOMUX(63, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_I2SRX_LRCK)>;
++ input-enable;
++ };
++ };
++
++ i2srx_clk_pins: i2srx-clk-0 {
++ mclk-pins {
++ pinmux = <GPIOMUX(58, GPOUT_SYS_MCLK,
++ GPOEN_ENABLE,
++ GPI_NONE)>;
++ input-enable;
++ };
++ };
++
++ i2srx_pins: i2srx-0 {
++ i2srx-pins {
++ pinmux = <GPIOMUX(61, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_I2SRX_SDIN0)>;
++ input-enable;
++ };
++ };
++
++ i2stx_pins: i2stx-0 {
++ i2stx-pins {
++ pinmux = <GPIOMUX(44, GPOUT_SYS_I2STX1_SDO0,
++ GPOEN_ENABLE,
++ GPI_NONE)>;
++ input-enable;
++ };
++ };
++
++ mclk_ext_pins: mclk-ext-0 {
++ mclk-ext-pins {
++ pinmux = <GPIOMUX(4, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_MCLK_EXT)>;
++ input-enable;
++ };
++ };
++
++ pdm_pins: pdm-0 {
++ pdm-pins {
++ pinmux = <GPIOMUX(54, GPOUT_SYS_PDM_MCLK,
++ GPOEN_ENABLE,
++ GPI_NONE)>,
++ <GPIOMUX(60, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_PDM_DMIC0)>;
++ input-enable;
++ };
++ };
++
++ pwm_ch0to3_pins: pwm-ch0to3-0 {
++ pwm-pins {
++ pinmux = <GPIOMUX(45, GPOUT_SYS_PWM_CHANNEL0,
++ GPOEN_SYS_PWM0_CHANNEL0,
++ GPI_NONE)>,
++ <GPIOMUX(46, GPOUT_SYS_PWM_CHANNEL1,
++ GPOEN_SYS_PWM0_CHANNEL1,
++ GPI_NONE)>,
++ <GPIOMUX(47, GPOUT_SYS_PWM_CHANNEL2,
++ GPOEN_SYS_PWM0_CHANNEL2,
++ GPI_NONE)>,
++ <GPIOMUX(48, GPOUT_SYS_PWM_CHANNEL3,
++ GPOEN_SYS_PWM0_CHANNEL3,
++ GPI_NONE)>;
++ drive-strength = <12>;
++ };
++ };
++
++ pwmdac_pins: pwmdac-0 {
++ pwmdac-pins {
++ pinmux = <GPIOMUX(57, GPOUT_SYS_PWMDAC_LEFT,
++ GPOEN_ENABLE,
++ GPI_NONE)>,
++ <GPIOMUX(42, GPOUT_SYS_PWMDAC_RIGHT,
++ GPOEN_ENABLE,
++ GPI_NONE)>;
++ };
++ };
++
++ rgb_pad_pins: rgb-pad-pins {
++ rgb-0-pins {
++ pinmux = <PINMUX(36, 1)>;
++ drive-strength = <12>;
++ input-disable;
++ slew-rate = <1>;
++ };
++
++ rgb-pins {
++ pinmux = <PINMUX(37, 1)>,
++ <PINMUX(38, 1)>,
++ <PINMUX(39, 1)>,
++ <PINMUX(40, 1)>,
++ <PINMUX(41, 1)>,
++ <PINMUX(42, 1)>,
++ <PINMUX(43, 1)>,
++ <PINMUX(44, 1)>,
++ <PINMUX(45, 1)>,
++ <PINMUX(46, 1)>,
++ <PINMUX(47, 1)>,
++ <PINMUX(48, 1)>,
++ <PINMUX(49, 1)>,
++ <PINMUX(50, 1)>,
++ <PINMUX(51, 1)>,
++ <PINMUX(52, 1)>,
++ <PINMUX(53, 1)>,
++ <PINMUX(54, 1)>,
++ <PINMUX(55, 1)>,
++ <PINMUX(56, 1)>,
++ <PINMUX(57, 1)>,
++ <PINMUX(58, 1)>,
++ <PINMUX(59, 1)>,
++ <PINMUX(60, 1)>,
++ <PINMUX(61, 1)>,
++ <PINMUX(62, 1)>,
++ <PINMUX(63, 1)>;
++ drive-strength = <12>;
++ input-disable;
++ };
++ };
++
++ sdcard0_pins: sdcard0-0 {
++ sdcard-pins {
++ pinmux = <GPIOMUX(24, GPOUT_SYS_SDIO0_RST,
++ GPOEN_ENABLE,
++ GPI_NONE)>,
++ <PINMUX(64, 0)>,
++ <PINMUX(65, 0)>,
++ <PINMUX(66, 0)>,
++ <PINMUX(67, 0)>,
++ <PINMUX(68, 0)>,
++ <PINMUX(69, 0)>;
++ bias-pull-up;
++ drive-strength = <12>;
++ input-enable;
++ slew-rate = <1>;
++ };
++ };
++
++ sdcard1_pins: sdcard1-0 {
++ sdcard-pins {
++ pinmux = <GPIOMUX(56, GPOUT_SYS_SDIO1_CLK,
++ GPOEN_ENABLE,
++ GPI_NONE)>,
++ <GPIOMUX(50, GPOUT_SYS_SDIO1_CMD,
++ GPOEN_SYS_SDIO1_CMD,
++ GPI_SYS_SDIO1_CMD)>,
++ <GPIOMUX(49, GPOUT_SYS_SDIO1_DATA0,
++ GPOEN_SYS_SDIO1_DATA0,
++ GPI_SYS_SDIO1_DATA0)>,
++ <GPIOMUX(45, GPOUT_SYS_SDIO1_DATA1,
++ GPOEN_SYS_SDIO1_DATA1,
++ GPI_SYS_SDIO1_DATA1)>,
++ <GPIOMUX(62, GPOUT_SYS_SDIO1_DATA2,
++ GPOEN_SYS_SDIO1_DATA2,
++ GPI_SYS_SDIO1_DATA2)>,
++ <GPIOMUX(40, GPOUT_SYS_SDIO1_DATA3,
++ GPOEN_SYS_SDIO1_DATA3,
++ GPI_SYS_SDIO1_DATA3)>;
++ bias-pull-up;
++ input-enable;
++ };
++ };
++
++ spdif_pins: spdif-0 {
++ spdif-pins {
++ pinmux = <GPIOMUX(57, GPOUT_SYS_SPDIF,
++ GPOEN_ENABLE,
++ GPI_NONE)>;
++ bias-pull-up;
++ input-enable;
++ };
++ };
++
++ spi0_pins: spi0-0 {
++ mosi-pins {
++ pinmux = <GPIOMUX(38, GPOUT_SYS_SPI0_TXD,
++ GPOEN_ENABLE,
++ GPI_NONE)>;
++ bias-disable;
++ input-disable;
++ input-schmitt-disable;
++ };
++
++ miso-pins {
++ pinmux = <GPIOMUX(39, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_SPI0_RXD)>;
++ bias-pull-up;
++ input-enable;
++ input-schmitt-enable;
++ };
++
++ sck-pins {
++ pinmux = <GPIOMUX(36, GPOUT_SYS_SPI0_CLK,
++ GPOEN_ENABLE,
++ GPI_SYS_SPI0_CLK)>;
++ bias-disable;
++ input-disable;
++ input-schmitt-disable;
++ };
++
++ ss-pins {
++ pinmux = <GPIOMUX(37, GPOUT_SYS_SPI0_FSS,
++ GPOEN_ENABLE,
++ GPI_SYS_SPI0_FSS)>;
++ bias-disable;
++ input-disable;
++ input-schmitt-disable;
++ };
++ };
++
++ spi1_pins: spi1-0 {
++ mosi-pins {
++ pinmux = <GPIOMUX(42, GPOUT_SYS_SPI1_TXD,
++ GPOEN_ENABLE,
++ GPI_NONE)>;
++ bias-disable;
++ input-disable;
++ input-schmitt-disable;
++ };
++
++ miso-pins {
++ pinmux = <GPIOMUX(43, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_SPI1_RXD)>;
++ bias-pull-up;
++ input-enable;
++ input-schmitt-enable;
++ };
++
++ sck-pins {
++ pinmux = <GPIOMUX(40, GPOUT_SYS_SPI1_CLK,
++ GPOEN_ENABLE,
++ GPI_SYS_SPI1_CLK)>;
++ bias-disable;
++ input-disable;
++ input-schmitt-disable;
++ };
++
++ ss-pins {
++ pinmux = <GPIOMUX(41, GPOUT_SYS_SPI1_FSS,
++ GPOEN_ENABLE,
++ GPI_SYS_SPI1_FSS)>;
++ bias-disable;
++ input-disable;
++ input-schmitt-disable;
++ };
++ };
++
++ spi2_pins: spi2-0 {
++ mosi-pins {
++ pinmux = <GPIOMUX(46, GPOUT_SYS_SPI2_TXD,
++ GPOEN_ENABLE,
++ GPI_NONE)>;
++ bias-disable;
++ input-disable;
++ input-schmitt-disable;
++ };
++
++ miso-pins {
++ pinmux = <GPIOMUX(47, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_SPI2_RXD)>;
++ bias-pull-up;
++ input-enable;
++ input-schmitt-enable;
++ };
++
++ sck-pins {
++ pinmux = <GPIOMUX(44, GPOUT_SYS_SPI2_CLK,
++ GPOEN_ENABLE,
++ GPI_SYS_SPI2_CLK)>;
++ bias-disable;
++ input-disable;
++ input-schmitt-disable;
++ };
++
++ ss-pins {
++ pinmux = <GPIOMUX(45, GPOUT_SYS_SPI2_FSS,
++ GPOEN_ENABLE,
++ GPI_SYS_SPI2_FSS)>;
++ bias-disable;
++ input-disable;
++ input-schmitt-disable;
++ };
++ };
++
++ spi3_pins: spi3-0 {
++ mosi-pins {
++ pinmux = <GPIOMUX(50, GPOUT_SYS_SPI3_TXD,
++ GPOEN_ENABLE,
++ GPI_NONE)>;
++ bias-disable;
++ input-disable;
++ input-schmitt-disable;
++ };
++
++ miso-pins {
++ pinmux = <GPIOMUX(51, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_SPI3_RXD)>;
++ bias-pull-up;
++ input-enable;
++ input-schmitt-enable;
++ };
++
++ sck-pins {
++ pinmux = <GPIOMUX(48, GPOUT_SYS_SPI3_CLK,
++ GPOEN_ENABLE,
++ GPI_SYS_SPI3_CLK)>;
++ bias-disable;
++ input-disable;
++ input-schmitt-disable;
++ };
++
++ ss-pins {
++ pinmux = <GPIOMUX(49, GPOUT_SYS_SPI3_FSS,
++ GPOEN_ENABLE,
++ GPI_SYS_SPI3_FSS)>;
++ bias-disable;
++ input-disable;
++ input-schmitt-disable;
++ };
++ };
++
++ spi4_pins: spi4-0 {
++ mosi-pins {
++ pinmux = <GPIOMUX(54, GPOUT_SYS_SPI4_TXD,
++ GPOEN_ENABLE,
++ GPI_NONE)>;
++ bias-disable;
++ input-disable;
++ input-schmitt-disable;
++ };
++
++ miso-pins {
++ pinmux = <GPIOMUX(55, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_SPI4_RXD)>;
++ bias-pull-up;
++ input-enable;
++ input-schmitt-enable;
++ };
++
++ sck-pins {
++ pinmux = <GPIOMUX(52, GPOUT_SYS_SPI4_CLK,
++ GPOEN_ENABLE,
++ GPI_SYS_SPI4_CLK)>;
++ bias-disable;
++ input-disable;
++ input-schmitt-disable;
++ };
++
++ ss-pins {
++ pinmux = <GPIOMUX(53, GPOUT_SYS_SPI4_FSS,
++ GPOEN_ENABLE,
++ GPI_SYS_SPI4_FSS)>;
++ bias-disable;
++ input-disable;
++ input-schmitt-disable;
++ };
++ };
++
++ spi5_pins: spi5-0 {
++ mosi-pins {
++ pinmux = <GPIOMUX(58, GPOUT_SYS_SPI5_TXD,
++ GPOEN_ENABLE,
++ GPI_NONE)>;
++ bias-disable;
++ input-disable;
++ input-schmitt-disable;
++ };
++
++ miso-pins {
++ pinmux = <GPIOMUX(59, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_SPI5_RXD)>;
++ bias-pull-up;
++ input-enable;
++ input-schmitt-enable;
++ };
++
++ sck-pins {
++ pinmux = <GPIOMUX(56, GPOUT_SYS_SPI5_CLK,
++ GPOEN_ENABLE,
++ GPI_SYS_SPI5_CLK)>;
++ bias-disable;
++ input-disable;
++ input-schmitt-disable;
++ };
++
++ ss-pins {
++ pinmux = <GPIOMUX(57, GPOUT_SYS_SPI5_FSS,
++ GPOEN_ENABLE,
++ GPI_SYS_SPI5_FSS)>;
++ bias-disable;
++ input-disable;
++ input-schmitt-disable;
++ };
++ };
++
++ spi6_pins: spi6-0 {
++ mosi-pins {
++ pinmux = <GPIOMUX(62, GPOUT_SYS_SPI6_TXD,
++ GPOEN_ENABLE,
++ GPI_NONE)>;
++ bias-disable;
++ input-disable;
++ input-schmitt-disable;
++ };
++
++ miso-pins {
++ pinmux = <GPIOMUX(63, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_SPI6_RXD)>;
++ bias-pull-up;
++ input-enable;
++ input-schmitt-enable;
++ };
++
++ sck-pins {
++ pinmux = <GPIOMUX(60, GPOUT_SYS_SPI6_CLK,
++ GPOEN_ENABLE,
++ GPI_SYS_SPI6_CLK)>;
++ bias-disable;
++ input-disable;
++ input-schmitt-disable;
++ };
++
++ ss-pins {
++ pinmux = <GPIOMUX(61, GPOUT_SYS_SPI6_FSS,
++ GPOEN_ENABLE,
++ GPI_SYS_SPI6_FSS)>;
++ bias-disable;
++ input-disable;
++ input-schmitt-disable;
++ };
++ };
++
++ tdm_pins: tdm-0 {
++ tx-pins {
++ pinmux = <GPIOMUX(44, GPOUT_SYS_TDM_TXD,
++ GPOEN_ENABLE,
++ GPI_NONE)>;
++ bias-pull-up;
++ drive-strength = <2>;
++ input-disable;
++ input-schmitt-disable;
++ slew-rate = <0>;
++ };
++
++ rx-pins {
++ pinmux = <GPIOMUX(61, GPOUT_HIGH,
++ GPOEN_DISABLE,
++ GPI_SYS_TDM_RXD)>;
++ input-enable;
++ };
++
++ sync-pins {
++ pinmux = <GPIOMUX(63, GPOUT_HIGH,
++ GPOEN_DISABLE,
++ GPI_SYS_TDM_SYNC)>;
++ input-enable;
++ };
++
++ pcmclk-pins {
++ pinmux = <GPIOMUX(38, GPOUT_HIGH,
++ GPOEN_DISABLE,
++ GPI_SYS_TDM_CLK)>;
++ input-enable;
++ };
++ };
++
++ uart0_pins: uart0-0 {
++ tx-pins {
++ pinmux = <GPIOMUX(5, GPOUT_SYS_UART0_TX,
++ GPOEN_ENABLE,
++ GPI_NONE)>;
++ bias-disable;
++ drive-strength = <12>;
++ input-disable;
++ input-schmitt-disable;
++ slew-rate = <0>;
++ };
++
++ rx-pins {
++ pinmux = <GPIOMUX(6, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_UART0_RX)>;
++ bias-pull-up;
++ drive-strength = <2>;
++ input-enable;
++ input-schmitt-enable;
++ slew-rate = <0>;
++ };
++ };
++
++ uart1_pins: uart1-0 {
++ tx-pins {
++ pinmux = <GPIOMUX(30, GPOUT_SYS_UART1_TX,
++ GPOEN_ENABLE,
++ GPI_NONE)>;
++ bias-disable;
++ drive-strength = <12>;
++ input-disable;
++ input-schmitt-disable;
++ slew-rate = <0>;
++ };
++
++ rx-pins {
++ pinmux = <GPIOMUX(31, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_UART1_RX)>;
++ bias-pull-up;
++ drive-strength = <2>;
++ input-enable;
++ input-schmitt-enable;
++ slew-rate = <0>;
++ };
++
++ cts-pins {
++ pinmux = <GPIOMUX(29, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_UART1_CTS)>;
++ input-enable;
++ };
++
++ rts-pins {
++ pinmux = <GPIOMUX(27, GPOUT_SYS_UART1_RTS,
++ GPOEN_ENABLE,
++ GPI_NONE)>;
++ input-enable;
++ };
++ };
++
++ uart2_pins: uart2-0 {
++ tx-pins {
++ pinmux = <GPIOMUX(30, GPOUT_SYS_UART2_TX,
++ GPOEN_ENABLE,
++ GPI_NONE)>;
++ bias-disable;
++ drive-strength = <12>;
++ input-disable;
++ input-schmitt-disable;
++ slew-rate = <0>;
++ };
++
++ rx-pins {
++ pinmux = <GPIOMUX(31, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_UART2_RX)>;
++ bias-pull-up;
++ drive-strength = <2>;
++ input-enable;
++ input-schmitt-enable;
++ slew-rate = <0>;
++ };
++
++ cts-pins {
++ pinmux = <GPIOMUX(29, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_UART2_CTS)>;
++ input-enable;
++ };
++
++ rts-pins {
++ pinmux = <GPIOMUX(27, GPOUT_SYS_UART2_RTS,
++ GPOEN_ENABLE,
++ GPI_NONE)>;
++ input-enable;
++ };
++ };
++
++ uart3_pins: uart3-0 {
++ tx-pins {
++ pinmux = <GPIOMUX(30, GPOUT_SYS_UART3_TX,
++ GPOEN_ENABLE,
++ GPI_NONE)>;
++ bias-disable;
++ drive-strength = <12>;
++ input-disable;
++ input-schmitt-disable;
++ slew-rate = <0>;
++ };
++
++ rx-pins {
++ pinmux = <GPIOMUX(31, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_UART3_RX)>;
++ bias-pull-up;
++ drive-strength = <2>;
++ input-enable;
++ input-schmitt-enable;
++ slew-rate = <0>;
++ };
++ };
++
++ uart4_pins: uart4-0 {
++ tx-pins {
++ pinmux = <GPIOMUX(30, GPOUT_SYS_UART4_TX,
++ GPOEN_ENABLE,
++ GPI_NONE)>;
++ bias-disable;
++ drive-strength = <12>;
++ input-disable;
++ input-schmitt-disable;
++ slew-rate = <0>;
++ };
++
++ rx-pins {
++ pinmux = <GPIOMUX(31, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_UART4_RX)>;
++ bias-pull-up;
++ drive-strength = <2>;
++ input-enable;
++ input-schmitt-enable;
++ slew-rate = <0>;
++ };
++
++ cts-pins {
++ pinmux = <GPIOMUX(29, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_UART4_CTS)>;
++ input-enable;
++ };
++
++ rts-pins {
++ pinmux = <GPIOMUX(27, GPOUT_SYS_UART4_RTS,
++ GPOEN_ENABLE,
++ GPI_NONE)>;
++ input-enable;
++ };
++ };
++
++ uart5_pins: uart5-0 {
++ tx-pins {
++ pinmux = <GPIOMUX(30, GPOUT_SYS_UART5_TX,
++ GPOEN_ENABLE,
++ GPI_NONE)>;
++ bias-disable;
++ drive-strength = <12>;
++ input-disable;
++ input-schmitt-disable;
++ slew-rate = <0>;
++ };
++
++ rx-pins {
++ pinmux = <GPIOMUX(31, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_UART5_RX)>;
++ bias-pull-up;
++ drive-strength = <2>;
++ input-enable;
++ input-schmitt-enable;
++ slew-rate = <0>;
++ };
++
++ cts-pins {
++ pinmux = <GPIOMUX(29, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_UART5_CTS)>;
++ input-enable;
++ };
++
++ rts-pins {
++ pinmux = <GPIOMUX(27, GPOUT_SYS_UART5_RTS,
++ GPOEN_ENABLE,
++ GPI_NONE)>;
++ input-enable;
++ };
++ };
++
++ usb_pins: usb-0 {
++ usb-pins {
++ pinmux = <GPIOMUX(33, GPOUT_HIGH,
++ GPOEN_ENABLE,
++ GPI_NONE)>,
++ <GPIOMUX(34, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_USB_OVERCURRENT)>;
++ input-enable;
++ };
++ };
++};
++
++&aongpio {
++ pwm_ch4to5_pins: pwm-ch4to5-0 {
++ pwm-pins {
++ pinmux = <GPIOMUX(1, GPOUT_AON_PTC0_PWM4, /* PAD_RGPIO0 */
++ GPOEN_AON_PTC0_OE_N_4,
++ GPI_NONE)>,
++ <GPIOMUX(2, GPOUT_AON_PTC0_PWM5, /* PAD_RGPIO1 */
++ GPOEN_AON_PTC0_OE_N_5,
++ GPI_NONE)>;
++ drive-strength = <12>;
++ };
++ };
++
++ pwm_ch6to7_pins: pwm-ch6to7-0 {
++ pwm-pins {
++ pinmux = <GPIOMUX(1, GPOUT_AON_PTC0_PWM6, /* PAD_RGPIO0 */
++ GPOEN_AON_PTC0_OE_N_6,
++ GPI_NONE)>,
++ <GPIOMUX(2, GPOUT_AON_PTC0_PWM7, /* PAD_RGPIO1 */
++ GPOEN_AON_PTC0_OE_N_7,
++ GPI_NONE)>;
++ drive-strength = <12>;
++ };
++ };
++};
+--- /dev/null
++++ b/arch/riscv/boot/dts/starfive/jh7110-evb.dts
+@@ -0,0 +1,35 @@
++// SPDX-License-Identifier: GPL-2.0 OR MIT
++/*
++ * Copyright (C) 2023 StarFive Technology Co., Ltd.
++ */
++
++/dts-v1/;
++#include "jh7110-evb.dtsi"
++
++/ {
++ model = "StarFive JH7110 EVB";
++ compatible = "starfive,jh7110-evb", "starfive,jh7110";
++};
++
++&mmc0 {
++ assigned-clocks = <&syscrg JH7110_SYSCLK_SDIO0_SDCARD>;
++ assigned-clock-rates = <50000000>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdcard0_pins>;
++ max-frequency = <100000000>;
++ card-detect-delay = <300>;
++ bus-width = <4>;
++ no-sdio;
++ no-mmc;
++ broken-cd;
++ post-power-on-delay-ms = <200>;
++ status = "okay";
++};
++
++&pcie1 {
++ status = "okay";
++};
++
++&usb0 {
++ status = "okay";
++};
+--- /dev/null
++++ b/arch/riscv/boot/dts/starfive/jh7110-evb.dtsi
+@@ -0,0 +1,854 @@
++// SPDX-License-Identifier: GPL-2.0 OR MIT
++/*
++ * Copyright (C) 2023 StarFive Technology Co., Ltd.
++ */
++
++/dts-v1/;
++#include "jh7110.dtsi"
++#include "jh7110-clk.dtsi"
++#include "jh7110-evb-pinctrl.dtsi"
++#include <dt-bindings/gpio/gpio.h>
++
++/ {
++ aliases {
++ ethernet0 = &gmac0;
++ ethernet1 = &gmac1;
++ i2c0 = &i2c0;
++ i2c1 = &i2c1;
++ i2c2 = &i2c2;
++ i2c3 = &i2c3;
++ i2c4 = &i2c4;
++ i2c5 = &i2c5;
++ i2c6 = &i2c6;
++ pcie0 = &pcie0;
++ pcie1 = &pcie1;
++ serial0 = &uart0;
++ serial3 = &uart3;
++ };
++
++ chosen {
++ stdout-path = "serial0:115200n8";
++ };
++
++ cpus {
++ timebase-frequency = <4000000>;
++ };
++
++ memory@40000000 {
++ device_type = "memory";
++ reg = <0x0 0x40000000 0x1 0x0>;
++ };
++
++ reserved-memory {
++ #address-cells = <2>;
++ #size-cells = <2>;
++ ranges;
++
++ linux,cma {
++ compatible = "shared-dma-pool";
++ reusable;
++ size = <0x0 0x20000000>;
++ alignment = <0x0 0x1000>;
++ alloc-ranges = <0x0 0x70000000 0x0 0x20000000>;
++ linux,cma-default;
++ };
++
++ e24_mem: e24@c0000000 {
++ reg = <0x0 0x6ce00000 0x0 0x1600000>;
++ };
++
++ xrp_reserved: xrpbuffer@f0000000 {
++ reg = <0x0 0x69c00000 0x0 0x01ffffff
++ 0x0 0x6bc00000 0x0 0x00001000
++ 0x0 0x6bc01000 0x0 0x00fff000
++ 0x0 0x6cc00000 0x0 0x00001000>;
++ };
++ };
++
++ /* i2s + hdmi */
++ sound1: snd-card1 {
++ compatible = "simple-audio-card";
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ simple-audio-card,name = "StarFive-HDMI-Sound-Card";
++ simple-audio-card,dai-link@0 {
++ reg = <0>;
++ format = "i2s";
++ bitclock-master = <&sndi2s0>;
++ frame-master = <&sndi2s0>;
++ mclk-fs = <256>;
++ status = "okay";
++
++ sndi2s0: cpu {
++ sound-dai = <&i2stx0>;
++ };
++
++ codec {
++ sound-dai = <&hdmi>;
++ };
++ };
++ };
++};
++
++&U74_1 {
++ /delete-property/ clocks;
++ /delete-property/ clock-names;
++};
++
++&U74_2 {
++ /delete-property/ clocks;
++ /delete-property/ clock-names;
++};
++
++&U74_3 {
++ /delete-property/ clocks;
++ /delete-property/ clock-names;
++};
++
++&U74_4 {
++ /delete-property/ clocks;
++ /delete-property/ clock-names;
++};
++
++&can0 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&can0_pins>;
++ status = "disabled";
++};
++
++&can1 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&can1_pins>;
++ status = "disabled";
++};
++
++&co_process {
++ memory-region = <&e24_mem>;
++ status = "okay";
++};
++
++&dc8200 {
++ status = "okay";
++
++ dc_out: port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ dc_out_dpi0: endpoint@0 {
++ reg = <0>;
++ remote-endpoint = <&hdmi_input0>;
++ };
++ dc_out_dpi1: endpoint@1 {
++ reg = <1>;
++ remote-endpoint = <&hdmi_in_lcdc>;
++ };
++ dc_out_dpi2: endpoint@2 {
++ reg = <2>;
++ remote-endpoint = <&mipi_in>;
++ };
++ };
++};
++
++&display {
++ ports = <&dc_out_dpi0>;
++ status = "okay";
++};
++
++&dsi_output {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ reg = <0>;
++ mipi_in: endpoint {
++ remote-endpoint = <&dc_out_dpi2>;
++ };
++ };
++
++ port@1 {
++ reg = <1>;
++ mipi_out: endpoint {
++ remote-endpoint = <&dsi_in_port>;
++ };
++ };
++ };
++};
++
++&gmac0 {
++ phy-handle = <&phy0>;
++ phy-mode = "rgmii-id";
++ status = "okay";
++
++ mdio {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ compatible = "snps,dwmac-mdio";
++
++ phy0: ethernet-phy@0 {
++ reg = <0>;
++ rx-internal-delay-ps = <1900>;
++ tx-internal-delay-ps = <1650>;
++ };
++ };
++};
++
++&gmac1 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "okay";
++
++ phy1: ethernet-phy@1 {
++ reg = <0>;
++ rxc-skew-ps = <1060>;
++ txc-skew-ps = <1800>;
++ };
++};
++
++&gpu {
++ status = "okay";
++};
++
++&hdmi {
++ status = "okay";
++ pinctrl-names = "default";
++ pinctrl-0 = <&hdmi_pins>;
++ hpd-gpio = <&sysgpio 15 GPIO_ACTIVE_HIGH>;
++
++ hdmi_in: port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ hdmi_in_lcdc: endpoint@0 {
++ reg = <0>;
++ remote-endpoint = <&dc_out_dpi1>;
++ };
++ };
++};
++
++&i2c0 {
++ clock-frequency = <100000>;
++ i2c-sda-hold-time-ns = <300>;
++ i2c-sda-falling-time-ns = <510>;
++ i2c-scl-falling-time-ns = <510>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2c0_pins>;
++ status = "disabled";
++
++ wm8960: codec@1a {
++ compatible = "wlf,wm8960";
++ reg = <0x1a>;
++ wlf,shared-lrclk;
++ #sound-dai-cells = <0>;
++ };
++
++ ac108: ac108@3b {
++ compatible = "x-power,ac108_0";
++ reg = <0x3b>;
++ #sound-dai-cells = <0>;
++ data-protocol = <0>;
++ };
++};
++
++&i2c1 {
++ clock-frequency = <100000>;
++ i2c-sda-hold-time-ns = <300>;
++ i2c-sda-falling-time-ns = <510>;
++ i2c-scl-falling-time-ns = <510>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2c1_pins>;
++ status = "disabled";
++};
++
++&i2c2 {
++ clock-frequency = <100000>;
++ i2c-sda-hold-time-ns = <300>;
++ i2c-sda-falling-time-ns = <510>;
++ i2c-scl-falling-time-ns = <510>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2c2_pins>;
++ status = "okay";
++
++ tinker_ft5406: tinker_ft5406@38 {
++ compatible = "tinker_ft5406";
++ reg = <0x38>;
++ };
++
++ seeed_plane_i2c@45 {
++ compatible = "seeed_panel";
++ reg = <0x45>;
++
++ port {
++ panel_dsi_port: endpoint {
++ remote-endpoint = <&dsi_out_port>;
++ };
++ };
++ };
++};
++
++&i2c3 {
++ clock-frequency = <100000>;
++ i2c-sda-hold-time-ns = <300>;
++ i2c-sda-falling-time-ns = <510>;
++ i2c-scl-falling-time-ns = <510>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2c3_pins>;
++ status = "disabled";
++};
++
++&i2c4 {
++ clock-frequency = <100000>;
++ i2c-sda-hold-time-ns = <300>;
++ i2c-sda-falling-time-ns = <510>;
++ i2c-scl-falling-time-ns = <510>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2c4_pins>;
++ status = "okay";
++
++ sc2235: sc2235@30 {
++ compatible = "smartsens,sc2235";
++ reg = <0x30>;
++ clocks = <&clk_ext_camera>;
++ clock-names = "xclk";
++
++ port {
++ /* Parallel bus endpoint */
++ sc2235_to_parallel: endpoint {
++ remote-endpoint = <&parallel_from_sc2235>;
++ bus-type = <5>; /* Parallel */
++ bus-width = <8>;
++ data-shift = <2>; /* lines 13:6 are used */
++ hsync-active = <1>;
++ vsync-active = <1>;
++ pclk-sample = <1>;
++ };
++ };
++ };
++
++ tda998x@70 {
++ compatible = "nxp,tda998x";
++ reg = <0x70>;
++
++ port {
++ tda998x_0_input: endpoint {
++ remote-endpoint = <&hdmi_out>;
++ };
++ };
++ };
++};
++
++&i2c5 {
++ clock-frequency = <100000>;
++ i2c-sda-hold-time-ns = <300>;
++ i2c-sda-falling-time-ns = <510>;
++ i2c-scl-falling-time-ns = <510>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2c5_pins>;
++ status = "okay";
++
++ pmic: jh7110_evb_reg@50 {
++ compatible = "starfive,jh7110-evb-regulator";
++ reg = <0x50>;
++
++ regulators {
++ hdmi_1p8: LDO_REG1 {
++ regulator-name = "hdmi_1p8";
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ };
++ mipitx_1p8: LDO_REG2 {
++ regulator-name = "mipitx_1p8";
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ };
++ mipirx_1p8: LDO_REG3 {
++ regulator-name = "mipirx_1p8";
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ };
++ hdmi_0p9: LDO_REG4 {
++ regulator-name = "hdmi_0p9";
++ regulator-min-microvolt = <900000>;
++ regulator-max-microvolt = <900000>;
++ };
++ mipitx_0p9: LDO_REG5 {
++ regulator-name = "mipitx_0p9";
++ regulator-min-microvolt = <900000>;
++ regulator-max-microvolt = <900000>;
++ };
++ mipirx_0p9: LDO_REG6 {
++ regulator-name = "mipirx_0p9";
++ regulator-min-microvolt = <900000>;
++ regulator-max-microvolt = <900000>;
++ };
++ sdio_vdd: LDO_REG7 {
++ regulator-name = "sdio_vdd";
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <3300000>;
++ };
++ };
++ };
++};
++
++&i2c6 {
++ clock-frequency = <100000>;
++ i2c-sda-hold-time-ns = <300>;
++ i2c-sda-falling-time-ns = <510>;
++ i2c-scl-falling-time-ns = <510>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2c6_pins>;
++ status = "okay";
++
++ ov4689: ov4689@36 {
++ compatible = "ovti,ov4689";
++ reg = <0x36>;
++ clocks = <&clk_ext_camera>;
++ clock-names = "xclk";
++ //reset-gpio = <&sysgpio 18 0>;
++ rotation = <180>;
++
++ port {
++ /* Parallel bus endpoint */
++ ov4689_to_csi2rx0: endpoint {
++ remote-endpoint = <&csi2rx0_from_ov4689>;
++ bus-type = <4>; /* MIPI CSI-2 D-PHY */
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ };
++ };
++ };
++
++ imx219: imx219@10 {
++ compatible = "sony,imx219";
++ reg = <0x10>;
++ clocks = <&clk_ext_camera>;
++ clock-names = "xclk";
++ reset-gpio = <&sysgpio 10 0>;
++ //DOVDD-supply = <&v2v8>;
++ rotation = <0>;
++ orientation = <1>; //CAMERA_ORIENTATION_BACK
++
++ port {
++ /* CSI2 bus endpoint */
++ imx219_to_csi2rx0: endpoint {
++ remote-endpoint = <&csi2rx0_from_imx219>;
++ bus-type = <4>; /* MIPI CSI-2 D-PHY */
++ clock-lanes = <0>;
++ data-lanes = <2 1>;
++ lane-polarities = <1 1 1>;
++ link-frequencies = /bits/ 64 <456000000>;
++ };
++ };
++ };
++
++ imx708: imx708@1a {
++ compatible = "sony,imx708";
++ reg = <0x1a>;
++ clocks = <&clk_ext_camera>;
++ reset-gpio = <&sysgpio 10 0>;
++
++ port {
++ imx708_to_csi2rx0: endpoint {
++ remote-endpoint = <&csi2rx0_from_imx708>;
++ data-lanes = <1 2>;
++ clock-noncontinuous;
++ link-frequencies = /bits/ 64 <450000000>;
++ };
++ };
++ };
++};
++
++&i2srx {
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2s_clk_pins &i2srx_pins>;
++};
++
++&i2srx_mst {
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2srx_clk_pins>;
++};
++
++&i2stx0 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&mclk_ext_pins>;
++ status = "okay";
++};
++
++&i2stx1 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&i2stx_pins>;
++};
++
++&jpu {
++ status = "okay";
++};
++
++&mailbox_contrl0 {
++ status = "okay";
++};
++
++&mailbox_client0 {
++ status = "okay";
++};
++
++&mipi_dphy {
++ status = "okay";
++};
++
++&mipi_dsi {
++ status = "okay";
++
++ port {
++ dsi_out_port: endpoint@0 {
++ remote-endpoint = <&panel_dsi_port>;
++ };
++ dsi_in_port: endpoint@1 {
++ remote-endpoint = <&mipi_out>;
++ };
++ };
++
++ mipi_panel: panel@0 {
++ /*compatible = "";*/
++ status = "okay";
++ };
++};
++
++&pcie0 {
++ enable-gpios = <&sysgpio 32 GPIO_ACTIVE_HIGH>;
++ perst-gpios = <&sysgpio 26 GPIO_ACTIVE_LOW>;
++ phys = <&pciephy0>;
++ status = "disabled";
++};
++
++&pcie1 {
++ enable-gpios = <&sysgpio 21 GPIO_ACTIVE_HIGH>;
++ perst-gpios = <&sysgpio 28 GPIO_ACTIVE_LOW>;
++ phys = <&pciephy1>;
++ status = "disabled";
++};
++
++&pciephy0 {
++ starfive,sys-syscon = <&sys_syscon 0x18>;
++ starfive,stg-syscon = <&stg_syscon 0x148 0x1f4>;
++};
++
++&pdm {
++ pinctrl-names = "default";
++ pinctrl-0 = <&pdm_pins>;
++ status = "disabled";
++};
++
++&pwmdac {
++ pinctrl-names = "default";
++ pinctrl-0 = <&pwmdac_pins>;
++};
++
++&qspi {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "okay";
++
++ nor_flash: flash@0 {
++ compatible = "jedec,spi-nor";
++ reg=<0>;
++ cdns,read-delay = <5>;
++ spi-max-frequency = <4687500>;
++ cdns,tshsl-ns = <1>;
++ cdns,tsd2d-ns = <1>;
++ cdns,tchsh-ns = <1>;
++ cdns,tslch-ns = <1>;
++
++ partitions {
++ compatible = "fixed-partitions";
++ #address-cells = <1>;
++ #size-cells = <1>;
++
++ spl@0 {
++ reg = <0x0 0x40000>;
++ };
++ uboot@100000 {
++ reg = <0x100000 0x300000>;
++ };
++ data@f00000 {
++ reg = <0xf00000 0x100000>;
++ };
++ };
++ };
++};
++
++&rgb_output {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0>;
++
++ hdmi_input0:endpoint@0 {
++ reg = <0>;
++ remote-endpoint = <&dc_out_dpi0>;
++ };
++ };
++
++ port@1 {
++ reg = <1>;
++
++ hdmi_out:endpoint {
++ remote-endpoint = <&tda998x_0_input>;
++ };
++ };
++ };
++};
++
++&spdif {
++ pinctrl-names = "default";
++ pinctrl-0 = <&spdif_pins>;
++};
++
++&spi0 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&spi0_pins>;
++ status = "disabled";
++
++ spi_dev0: spi_dev@0 {
++ compatible = "rohm,dh2228fv";
++ reg = <0>;
++ pl022,com-mode = <1>;
++ spi-max-frequency = <10000000>;
++ };
++};
++
++&spi1 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&spi1_pins>;
++ status = "disabled";
++
++ spi_dev1: spi_dev@0 {
++ compatible = "rohm,dh2228fv";
++ reg = <0>;
++ pl022,com-mode = <1>;
++ spi-max-frequency = <10000000>;
++ };
++};
++
++&spi2 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&spi2_pins>;
++ status = "disabled";
++
++ spi_dev2: spi_dev@0 {
++ compatible = "rohm,dh2228fv";
++ reg = <0>;
++ pl022,com-mode = <1>;
++ spi-max-frequency = <10000000>;
++ };
++};
++
++&spi3 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&spi3_pins>;
++ status = "disabled";
++
++ spi_dev3: spi_dev@0 {
++ compatible = "rohm,dh2228fv";
++ reg = <0>;
++ pl022,com-mode = <1>;
++ spi-max-frequency = <10000000>;
++ };
++};
++
++&spi4 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&spi4_pins>;
++ status = "disabled";
++
++ spi_dev4: spi_dev@0 {
++ compatible = "rohm,dh2228fv";
++ reg = <0>;
++ pl022,com-mode = <1>;
++ spi-max-frequency = <10000000>;
++ };
++};
++
++&spi5 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&spi5_pins>;
++ status = "disabled";
++
++ spi_dev5: spi_dev@0 {
++ compatible = "rohm,dh2228fv";
++ reg = <0>;
++ pl022,com-mode = <1>;
++ spi-max-frequency = <10000000>;
++ };
++};
++
++&spi6 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&spi6_pins>;
++ status = "disabled";
++
++ spi_dev6: spi_dev@0 {
++ compatible = "rohm,dh2228fv";
++ reg = <0>;
++ pl022,com-mode = <1>;
++ spi-max-frequency = <10000000>;
++ };
++};
++
++&tda988x_pin {
++ pinctrl-names = "default";
++ pinctrl-0 = <&rgb_pad_pins>;
++ status = "disabled";
++};
++
++&tdm {
++ pinctrl-names = "default";
++ pinctrl-0 = <&tdm_pins>;
++ status = "disabled";
++};
++
++&uart0 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&uart0_pins>;
++ status = "okay";
++};
++
++&uart1 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&uart1_pins>;
++ status = "disabled";
++};
++
++&uart2 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&uart2_pins>;
++ status = "disabled";
++};
++
++&uart3 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&uart3_pins>;
++ status = "disabled";
++};
++
++&uart4 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&uart4_pins>;
++ status = "disabled";
++};
++
++&uart5 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&uart5_pins>;
++ status = "disabled";
++};
++
++&usb0 {
++ clocks = <&stgcrg JH7110_STGCLK_USB0_LPM>,
++ <&stgcrg JH7110_STGCLK_USB0_STB>,
++ <&stgcrg JH7110_STGCLK_USB0_APB>,
++ <&stgcrg JH7110_STGCLK_USB0_AXI>,
++ <&stgcrg JH7110_STGCLK_USB0_UTMI_APB>,
++ <&stgcrg JH7110_STGCLK_PCIE0_APB>;
++ clock-names = "lpm", "stb", "apb", "axi", "utmi_apb", "phy";
++ resets = <&stgcrg JH7110_STGRST_USB0_PWRUP>,
++ <&stgcrg JH7110_STGRST_USB0_APB>,
++ <&stgcrg JH7110_STGRST_USB0_AXI>,
++ <&stgcrg JH7110_STGRST_USB0_UTMI_APB>,
++ <&stgcrg JH7110_STGRST_PCIE0_APB>;
++ reset-names = "pwrup", "apb", "axi", "utmi_apb", "phy";
++ pinctrl-names = "default";
++ pinctrl-0 = <&usb_pins>;
++ dr_mode = "host"; /* host or peripheral */
++ status = "disabled";
++};
++
++&usb_cdns3 {
++ phys = <&usbphy0>, <&pciephy0>;
++ phy-names = "cdns3,usb2-phy", "cdns3,usb3-phy";
++};
++
++&vin_sysctl {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ reg = <0>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ /* Parallel bus endpoint */
++ parallel_from_sc2235: endpoint@0 {
++ reg = <0>;
++ remote-endpoint = <&sc2235_to_parallel>;
++ bus-type = <5>; /* Parallel */
++ bus-width = <8>;
++ data-shift = <2>; /* lines 9:2 are used */
++ hsync-active = <1>;
++ vsync-active = <0>;
++ pclk-sample = <1>;
++ status = "okay";
++ };
++ };
++
++ port@1 {
++ reg = <1>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ /* CSI2 bus endpoint */
++ csi2rx0_from_ov4689: endpoint@0 {
++ reg = <0>;
++ remote-endpoint = <&ov4689_to_csi2rx0>;
++ bus-type = <4>; /* MIPI CSI-2 D-PHY */
++ clock-lanes = <0>;
++ data-lanes = <1 2 3 4>;
++ status = "okay";
++ };
++
++ /* CSI2 bus endpoint */
++ csi2rx0_from_imx219: endpoint@1 {
++ reg = <1>;
++ remote-endpoint = <&imx219_to_csi2rx0>;
++ bus-type = <4>; /* MIPI CSI-2 D-PHY */
++ clock-lanes = <0>;
++ data-lanes = <2 1>;
++ lane-polarities = <1 1 1>;
++ status = "okay";
++ };
++
++ csi2rx0_from_imx708: endpoint@2 {
++ reg = <2>;
++ remote-endpoint = <&imx708_to_csi2rx0>;
++ bus-type = <4>; /* MIPI CSI-2 D-PHY */
++ clock-lanes = <0>;
++ data-lanes = <2 1>;
++ lane-polarities = <1 1 1>;
++ status = "okay";
++ };
++ };
++ };
++};
++
++&vpu_dec {
++ status = "okay";
++};
++
++&vpu_enc {
++ status = "okay";
++};
++
++&xrp {
++ memory-region = <&xrp_reserved>;
++ status = "okay";
++};
+--- a/arch/riscv/boot/dts/starfive/jh7110.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7110.dtsi
+@@ -196,11 +196,60 @@
+ opp-750000000 {
+ opp-hz = /bits/ 64 <750000000>;
+ opp-microvolt = <800000>;
++ opp-suspend;
+ };
+ opp-1500000000 {
+ opp-hz = /bits/ 64 <1500000000>;
+ opp-microvolt = <1040000>;
+ };
++ /* CPU opp table for 1.25GHz */
++ opp-312500000 {
++ opp-hz = /bits/ 64 <312500000>;
++ opp-microvolt = <800000>;
++ };
++ opp-417000000 {
++ opp-hz = /bits/ 64 <417000000>;
++ opp-microvolt = <800000>;
++ };
++ opp-625000000 {
++ opp-hz = /bits/ 64 <625000000>;
++ opp-microvolt = <800000>;
++ opp-suspend;
++ };
++ opp-1250000000 {
++ opp-hz = /bits/ 64 <1250000000>;
++ opp-microvolt = <1000000>;
++ };
++ };
++
++ display: display-subsystem {
++ compatible = "starfive,jh7110-display","verisilicon,display-subsystem";
++ status = "disabled";
++ };
++
++ dsi_output: dsi-output {
++ compatible = "starfive,jh7110-display-encoder","verisilicon,dsi-encoder";
++ status = "disabled";
++ };
++
++ mailbox_client0: mailbox_client {
++ compatible = "starfive,mailbox-test";
++ mbox-names = "rx", "tx";
++ mboxes = <&mailbox_contrl0 0 1>,<&mailbox_contrl0 1 0>;
++ status = "disabled";
++ };
++
++ rgb_output: rgb-output {
++ compatible = "starfive,jh7110-rgb_output","verisilicon,rgb-encoder";
++ //verisilicon,dss-syscon = <&dssctrl>;
++ //verisilicon,mux-mask = <0x70 0x380>;
++ //verisilicon,mux-val = <0x40 0x280>;
++ status = "disabled";
++ };
++
++ tda988x_pin: tda988x_pin {
++ compatible = "starfive,tda998x_rgb_pin";
++ status = "disabled";
+ };
+
+ thermal-zones {
+@@ -349,7 +398,9 @@
+
+ ccache: cache-controller@2010000 {
+ compatible = "starfive,jh7110-ccache", "sifive,ccache0", "cache";
+- reg = <0x0 0x2010000 0x0 0x4000>;
++ reg = <0x0 0x2010000 0x0 0x4000>,
++ <0x0 0x8000000 0x0 0x2000000>,
++ <0x0 0xa000000 0x0 0x2000000>;
+ interrupts = <1>, <3>, <4>, <2>;
+ cache-block-size = <64>;
+ cache-level = <2>;
+@@ -378,7 +429,8 @@
+ clocks = <&syscrg JH7110_SYSCLK_UART0_CORE>,
+ <&syscrg JH7110_SYSCLK_UART0_APB>;
+ clock-names = "baudclk", "apb_pclk";
+- resets = <&syscrg JH7110_SYSRST_UART0_APB>;
++ resets = <&syscrg JH7110_SYSRST_UART0_APB>,
++ <&syscrg JH7110_SYSRST_UART0_CORE>;
+ interrupts = <32>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+@@ -391,7 +443,8 @@
+ clocks = <&syscrg JH7110_SYSCLK_UART1_CORE>,
+ <&syscrg JH7110_SYSCLK_UART1_APB>;
+ clock-names = "baudclk", "apb_pclk";
+- resets = <&syscrg JH7110_SYSRST_UART1_APB>;
++ resets = <&syscrg JH7110_SYSRST_UART1_APB>,
++ <&syscrg JH7110_SYSRST_UART1_CORE>;
+ interrupts = <33>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+@@ -404,7 +457,8 @@
+ clocks = <&syscrg JH7110_SYSCLK_UART2_CORE>,
+ <&syscrg JH7110_SYSCLK_UART2_APB>;
+ clock-names = "baudclk", "apb_pclk";
+- resets = <&syscrg JH7110_SYSRST_UART2_APB>;
++ resets = <&syscrg JH7110_SYSRST_UART2_APB>,
++ <&syscrg JH7110_SYSRST_UART2_CORE>;
+ interrupts = <34>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+@@ -513,6 +567,25 @@
+ status = "disabled";
+ };
+
++ spdif: spdif@100a0000 {
++ compatible = "starfive,jh7110-spdif";
++ reg = <0x0 0x100a0000 0x0 0x1000>;
++ clocks = <&syscrg JH7110_SYSCLK_SPDIF_APB>,
++ <&syscrg JH7110_SYSCLK_SPDIF_CORE>,
++ <&syscrg JH7110_SYSCLK_AUDIO_ROOT>,
++ <&syscrg JH7110_SYSCLK_MCLK_INNER>,
++ <&mclk_ext>, <&syscrg JH7110_SYSCLK_MCLK>;
++ clock-names = "apb", "core",
++ "audroot", "mclk_inner",
++ "mclk_ext", "mclk";
++ resets = <&syscrg JH7110_SYSRST_SPDIF_APB>;
++ reset-names = "apb";
++ interrupts = <84>;
++ interrupt-names = "tx";
++ #sound-dai-cells = <0>;
++ status = "disabled";
++ };
++
+ pwmdac: pwmdac@100b0000 {
+ compatible = "starfive,jh7110-pwmdac";
+ reg = <0x0 0x100b0000 0x0 0x1000>;
+@@ -526,6 +599,42 @@
+ status = "disabled";
+ };
+
++ pdm: pdm@100d0000 {
++ compatible = "starfive,jh7110-pdm";
++ reg = <0x0 0x100d0000 0x0 0x1000>;
++ reg-names = "pdm";
++ clocks = <&syscrg JH7110_SYSCLK_PDM_DMIC>,
++ <&syscrg JH7110_SYSCLK_PDM_APB>,
++ <&syscrg JH7110_SYSCLK_MCLK>,
++ <&mclk_ext>;
++ clock-names = "pdm_mclk", "pdm_apb",
++ "clk_mclk", "mclk_ext";
++ resets = <&syscrg JH7110_SYSRST_PDM_DMIC>,
++ <&syscrg JH7110_SYSRST_PDM_APB>;
++ reset-names = "pdm_dmic", "pdm_apb";
++ #sound-dai-cells = <0>;
++ status = "disabled";
++ };
++
++ i2srx_mst: i2srx_mst@100e0000 {
++ compatible = "starfive,jh7110-i2srx-master";
++ reg = <0x0 0x100e0000 0x0 0x1000>;
++ clocks = <&syscrg JH7110_SYSCLK_I2SRX_BCLK_MST>,
++ <&syscrg JH7110_SYSCLK_I2SRX_APB>,
++ <&syscrg JH7110_SYSCLK_MCLK>,
++ <&syscrg JH7110_SYSCLK_MCLK_INNER>,
++ <&mclk_ext>;
++ clock-names = "i2sclk", "apb", "mclk",
++ "mclk_inner","mclk_ext";
++ resets = <&syscrg JH7110_SYSRST_I2SRX_APB>,
++ <&syscrg JH7110_SYSRST_I2SRX_BCLK>;
++ dmas = <&dma 24>;
++ dma-names = "rx";
++ starfive,syscon = <&sys_syscon 0x18 0x2 0x34 0x3FC00 0x24400>;
++ #sound-dai-cells = <0>;
++ status = "disabled";
++ };
++
+ i2srx: i2s@100e0000 {
+ compatible = "starfive,jh7110-i2srx";
+ reg = <0x0 0x100e0000 0x0 0x1000>;
+@@ -622,6 +731,26 @@
+ #reset-cells = <1>;
+ };
+
++ xrp: xrp@10230000 {
++ compatible = "cdns,xrp";
++ dma-coherent;
++ reg = <0x0 0x10230000 0x0 0x00010000
++ 0x0 0x10240000 0x0 0x00010000>;
++ clocks = <&stgcrg JH7110_STGCLK_HIFI4_CLK_CORE>;
++ clock-names = "core_clk";
++ resets = <&stgcrg JH7110_STGRST_HIFI4_CORE>,
++ <&stgcrg JH7110_STGRST_HIFI4_AXI>;
++ reset-names = "rst_core","rst_axi";
++ starfive,stg-syscon = <&stg_syscon>;
++ firmware-name = "hifi4_elf";
++ #address-cells = <1>;
++ #size-cells = <1>;
++ ranges = <0x40000000 0x0 0x20000000 0x040000
++ 0x69c00000 0x0 0x69c00000 0x03000000>;
++ status = "disabled";
++ dsp@0 {};
++ };
++
+ stg_syscon: syscon@10240000 {
+ compatible = "starfive,jh7110-stg-syscon", "syscon";
+ reg = <0x0 0x10240000 0x0 0x1000>;
+@@ -633,7 +762,8 @@
+ clocks = <&syscrg JH7110_SYSCLK_UART3_CORE>,
+ <&syscrg JH7110_SYSCLK_UART3_APB>;
+ clock-names = "baudclk", "apb_pclk";
+- resets = <&syscrg JH7110_SYSRST_UART3_APB>;
++ resets = <&syscrg JH7110_SYSRST_UART3_APB>,
++ <&syscrg JH7110_SYSRST_UART3_CORE>;
+ interrupts = <45>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+@@ -646,7 +776,8 @@
+ clocks = <&syscrg JH7110_SYSCLK_UART4_CORE>,
+ <&syscrg JH7110_SYSCLK_UART4_APB>;
+ clock-names = "baudclk", "apb_pclk";
+- resets = <&syscrg JH7110_SYSRST_UART4_APB>;
++ resets = <&syscrg JH7110_SYSRST_UART4_APB>,
++ <&syscrg JH7110_SYSRST_UART4_CORE>;
+ interrupts = <46>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+@@ -659,7 +790,8 @@
+ clocks = <&syscrg JH7110_SYSCLK_UART5_CORE>,
+ <&syscrg JH7110_SYSCLK_UART5_APB>;
+ clock-names = "baudclk", "apb_pclk";
+- resets = <&syscrg JH7110_SYSRST_UART5_APB>;
++ resets = <&syscrg JH7110_SYSRST_UART5_APB>,
++ <&syscrg JH7110_SYSRST_UART5_CORE>;
+ interrupts = <47>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+@@ -919,6 +1051,18 @@
+ "ch2", "ch3";
+ };
+
++ mailbox_contrl0: mailbox@13060000 {
++ compatible = "starfive,mail_box";
++ reg = <0x0 0x13060000 0x0 0x0001000>;
++ clocks = <&syscrg JH7110_SYSCLK_MAILBOX_APB>;
++ clock-names = "clk_apb";
++ resets = <&syscrg JH7110_SYSRST_MAILBOX_APB>;
++ reset-names = "mbx_rre";
++ interrupts = <26 27>;
++ #mbox-cells = <2>;
++ status = "disabled";
++ };
++
+ watchdog@13070000 {
+ compatible = "starfive,jh7110-wdt";
+ reg = <0x0 0x13070000 0x0 0x10000>;
+@@ -929,6 +1073,112 @@
+ <&syscrg JH7110_SYSRST_WDT_CORE>;
+ };
+
++ jpu: jpu@13090000 {
++ compatible = "starfive,jpu";
++ dma-coherent;
++ reg = <0x0 0x13090000 0x0 0x300>;
++ interrupts = <14>;
++ clocks = <&syscrg JH7110_SYSCLK_CODAJ12_AXI>,
++ <&syscrg JH7110_SYSCLK_CODAJ12_CORE>,
++ <&syscrg JH7110_SYSCLK_CODAJ12_APB>,
++ <&syscrg JH7110_SYSCLK_NOC_BUS_VDEC_AXI>,
++ <&syscrg JH7110_SYSCLK_VDEC_MAIN>,
++ <&syscrg JH7110_SYSCLK_VDEC_JPG>;
++ clock-names = "axi_clk", "core_clk", "apb_clk",
++ "noc_bus", "main_clk", "dec_clk";
++ resets = <&syscrg JH7110_SYSRST_CODAJ12_AXI>,
++ <&syscrg JH7110_SYSRST_CODAJ12_CORE>,
++ <&syscrg JH7110_SYSRST_CODAJ12_APB>;
++ reset-names = "rst_axi", "rst_core", "rst_apb";
++ power-domains = <&pwrc JH7110_PD_VDEC>;
++ status = "disabled";
++ };
++
++ vpu_dec: vpu_dec@130a0000 {
++ compatible = "starfive,vdec";
++ dma-coherent;
++ reg = <0x0 0x130a0000 0x0 0x10000>;
++ interrupts = <13>;
++ clocks = <&syscrg JH7110_SYSCLK_WAVE511_AXI>,
++ <&syscrg JH7110_SYSCLK_WAVE511_BPU>,
++ <&syscrg JH7110_SYSCLK_WAVE511_VCE>,
++ <&syscrg JH7110_SYSCLK_WAVE511_APB>,
++ <&syscrg JH7110_SYSCLK_NOC_BUS_VDEC_AXI>,
++ <&syscrg JH7110_SYSCLK_VDEC_MAIN>;
++ clock-names = "axi_clk", "bpu_clk", "vce_clk",
++ "apb_clk", "noc_bus", "main_clk";
++ resets = <&syscrg JH7110_SYSRST_WAVE511_AXI>,
++ <&syscrg JH7110_SYSRST_WAVE511_BPU>,
++ <&syscrg JH7110_SYSRST_WAVE511_VCE>,
++ <&syscrg JH7110_SYSRST_WAVE511_APB>,
++ <&syscrg JH7110_SYSRST_AXIMEM0_AXI>;
++ reset-names = "rst_axi", "rst_bpu", "rst_vce",
++ "rst_apb", "rst_sram";
++ starfive,vdec_noc_ctrl;
++ power-domains = <&pwrc JH7110_PD_VDEC>;
++ status = "disabled";
++ };
++
++ vpu_enc: vpu_enc@130b0000 {
++ compatible = "starfive,venc";
++ dma-coherent;
++ reg = <0x0 0x130b0000 0x0 0x10000>;
++ interrupts = <15>;
++ clocks = <&syscrg JH7110_SYSCLK_WAVE420L_AXI>,
++ <&syscrg JH7110_SYSCLK_WAVE420L_BPU>,
++ <&syscrg JH7110_SYSCLK_WAVE420L_VCE>,
++ <&syscrg JH7110_SYSCLK_WAVE420L_APB>,
++ <&syscrg JH7110_SYSCLK_NOC_BUS_VENC_AXI>;
++ clock-names = "axi_clk", "bpu_clk", "vce_clk",
++ "apb_clk", "noc_bus";
++ resets = <&syscrg JH7110_SYSRST_WAVE420L_AXI>,
++ <&syscrg JH7110_SYSRST_WAVE420L_BPU>,
++ <&syscrg JH7110_SYSRST_WAVE420L_VCE>,
++ <&syscrg JH7110_SYSRST_WAVE420L_APB>,
++ <&syscrg JH7110_SYSRST_AXIMEM1_AXI>;
++ reset-names = "rst_axi", "rst_bpu", "rst_vce",
++ "rst_apb", "rst_sram";
++ starfive,venc_noc_ctrl;
++ power-domains = <&pwrc JH7110_PD_VENC>;
++ status = "disabled";
++ };
++
++ can0: can@130d0000 {
++ compatible = "starfive,jh7110-can", "ipms,can";
++ reg = <0x0 0x130d0000 0x0 0x1000>;
++ interrupts = <112>;
++ clocks = <&syscrg JH7110_SYSCLK_CAN0_APB>,
++ <&syscrg JH7110_SYSCLK_CAN0_CAN>,
++ <&syscrg JH7110_SYSCLK_CAN0_TIMER>;
++ clock-names = "apb_clk", "core_clk", "timer_clk";
++ resets = <&syscrg JH7110_SYSRST_CAN0_APB>,
++ <&syscrg JH7110_SYSRST_CAN0_CORE>,
++ <&syscrg JH7110_SYSRST_CAN0_TIMER>;
++ reset-names = "rst_apb", "rst_core", "rst_timer";
++ frequency = <40000000>;
++ starfive,sys-syscon = <&sys_syscon 0x10 0x3 0x8>;
++ syscon,can_or_canfd = <0>;
++ status = "disabled";
++ };
++
++ can1: can@130e0000 {
++ compatible = "starfive,jh7110-can", "ipms,can";
++ reg = <0x0 0x130e0000 0x0 0x1000>;
++ interrupts = <113>;
++ clocks = <&syscrg JH7110_SYSCLK_CAN1_APB>,
++ <&syscrg JH7110_SYSCLK_CAN1_CAN>,
++ <&syscrg JH7110_SYSCLK_CAN1_TIMER>;
++ clock-names = "apb_clk", "core_clk", "timer_clk";
++ resets = <&syscrg JH7110_SYSRST_CAN1_APB>,
++ <&syscrg JH7110_SYSRST_CAN1_CORE>,
++ <&syscrg JH7110_SYSRST_CAN1_TIMER>;
++ reset-names = "rst_apb", "rst_core", "rst_timer";
++ frequency = <40000000>;
++ starfive,sys-syscon = <&sys_syscon 0x88 0x12 0x40000>;
++ syscon,can_or_canfd = <0>;
++ status = "disabled";
++ };
++
+ crypto: crypto@16000000 {
+ compatible = "starfive,jh7110-crypto";
+ reg = <0x0 0x16000000 0x0 0x4000>;
+@@ -1119,6 +1369,42 @@
+ #power-domain-cells = <1>;
+ };
+
++ rtc: rtc@17040000 {
++ compatible = "starfive,jh7110-rtc";
++ reg = <0x0 0x17040000 0x0 0x10000>;
++ interrupts = <10>, <11>, <12>;
++ interrupt-names = "rtc_ms_pulse", "rtc_sec_pulse", "rtc";
++ clocks = <&aoncrg JH7110_AONCLK_RTC_APB>,
++ <&aoncrg JH7110_AONCLK_RTC_CAL>;
++ clock-names = "pclk", "cal_clk";
++ resets = <&aoncrg JH7110_AONRST_RTC_32K>,
++ <&aoncrg JH7110_AONRST_RTC_APB>,
++ <&aoncrg JH7110_AONRST_RTC_CAL>;
++ reset-names = "rst_osc", "rst_apb", "rst_cal";
++ rtc,cal-clock-freq = <1000000>;
++ };
++
++ gpu: gpu@18000000 {
++ compatible = "img-gpu";
++ reg = <0x0 0x18000000 0x0 0x100000>,
++ <0x0 0x130C000 0x0 0x10000>;
++ clocks = <&syscrg JH7110_SYSCLK_GPU_CORE>,
++ <&syscrg JH7110_SYSCLK_GPU_APB>,
++ <&syscrg JH7110_SYSCLK_GPU_RTC_TOGGLE>,
++ <&syscrg JH7110_SYSCLK_GPU_CORE_CLK>,
++ <&syscrg JH7110_SYSCLK_GPU_SYS_CLK>,
++ <&syscrg JH7110_SYSCLK_NOC_BUS_GPU_AXI>;
++ clock-names = "clk_bv", "clk_apb", "clk_rtc",
++ "clk_core", "clk_sys", "clk_axi";
++ resets = <&syscrg JH7110_SYSRST_GPU_APB>,
++ <&syscrg JH7110_SYSRST_GPU_DOMA>;
++ reset-names = "rst_apb", "rst_doma";
++ power-domains = <&pwrc JH7110_PD_GPUA>;
++ interrupts = <82>;
++ current-clock = <8000000>;
++ status = "disabled";
++ };
++
+ csi2rx: csi-bridge@19800000 {
+ compatible = "starfive,jh7110-csi2rx";
+ reg = <0x0 0x19800000 0x0 0x10000>;
+@@ -1145,6 +1431,67 @@
+ status = "disabled";
+ };
+
++ vin_sysctl: vin_sysctl@19800000 {
++ compatible = "starfive,jh7110-vin";
++ reg = <0x0 0x19800000 0x0 0x10000>,
++ <0x0 0x19810000 0x0 0x10000>,
++ <0x0 0x19820000 0x0 0x10000>,
++ <0x0 0x19840000 0x0 0x10000>,
++ <0x0 0x19870000 0x0 0x30000>,
++ <0x0 0x11840000 0x0 0x10000>,
++ <0x0 0x17030000 0x0 0x10000>,
++ <0x0 0x13020000 0x0 0x10000>;
++ reg-names = "csi2rx", "vclk", "vrst", "sctrl",
++ "isp", "trst", "pmu", "syscrg";
++ clocks = <&ispcrg JH7110_ISPCLK_DOM4_APB_FUNC>,
++ <&ispcrg JH7110_ISPCLK_VIN_APB>,
++ <&ispcrg JH7110_ISPCLK_VIN_SYS>,
++ <&ispcrg JH7110_ISPCLK_ISPV2_TOP_WRAPPER_C>,
++ <&ispcrg JH7110_ISPCLK_DVP_INV>,
++ <&ispcrg JH7110_ISPCLK_VIN_P_AXI_WR>,
++ <&ispcrg JH7110_ISPCLK_MIPI_RX0_PXL>,
++ <&ispcrg JH7110_ISPCLK_VIN_PIXEL_IF0>,
++ <&ispcrg JH7110_ISPCLK_VIN_PIXEL_IF1>,
++ <&ispcrg JH7110_ISPCLK_VIN_PIXEL_IF2>,
++ <&ispcrg JH7110_ISPCLK_VIN_PIXEL_IF3>,
++ <&ispcrg JH7110_ISPCLK_M31DPHY_CFG_IN>,
++ <&ispcrg JH7110_ISPCLK_M31DPHY_REF_IN>,
++ <&ispcrg JH7110_ISPCLK_M31DPHY_TX_ESC_LAN0>,
++ <&syscrg JH7110_SYSCLK_ISP_TOP_CORE>,
++ <&syscrg JH7110_SYSCLK_ISP_TOP_AXI>;
++ clock-names = "clk_apb_func", "clk_pclk", "clk_sys_clk",
++ "clk_wrapper_clk_c", "clk_dvp_inv", "clk_axiwr",
++ "clk_mipi_rx0_pxl", "clk_pixel_clk_if0",
++ "clk_pixel_clk_if1", "clk_pixel_clk_if2",
++ "clk_pixel_clk_if3", "clk_m31dphy_cfgclk_in",
++ "clk_m31dphy_refclk_in", "clk_m31dphy_txclkesc_lan0",
++ "clk_ispcore_2x", "clk_isp_axi";
++ resets = <&ispcrg JH7110_ISPRST_ISPV2_TOP_WRAPPER_P>,
++ <&ispcrg JH7110_ISPRST_ISPV2_TOP_WRAPPER_C>,
++ <&ispcrg JH7110_ISPRST_VIN_APB>,
++ <&ispcrg JH7110_ISPRST_VIN_SYS>,
++ <&ispcrg JH7110_ISPRST_VIN_P_AXI_RD>,
++ <&ispcrg JH7110_ISPRST_VIN_P_AXI_WR>,
++ <&ispcrg JH7110_ISPRST_VIN_PIXEL_IF0>,
++ <&ispcrg JH7110_ISPRST_VIN_PIXEL_IF1>,
++ <&ispcrg JH7110_ISPRST_VIN_PIXEL_IF2>,
++ <&ispcrg JH7110_ISPRST_VIN_PIXEL_IF3>,
++ <&ispcrg JH7110_ISPRST_M31DPHY_HW>,
++ <&ispcrg JH7110_ISPRST_M31DPHY_B09_AON>,
++ <&syscrg JH7110_SYSRST_ISP_TOP>,
++ <&syscrg JH7110_SYSRST_ISP_TOP_AXI>;
++ reset-names = "rst_wrapper_p", "rst_wrapper_c", "rst_pclk",
++ "rst_sys_clk", "rst_axird", "rst_axiwr", "rst_pixel_clk_if0",
++ "rst_pixel_clk_if1", "rst_pixel_clk_if2", "rst_pixel_clk_if3",
++ "rst_m31dphy_hw", "rst_m31dphy_b09_always_on",
++ "rst_isp_top_n", "rst_isp_top_axi";
++ starfive,aon-syscon = <&aon_syscon 0x00>;
++ power-domains = <&pwrc JH7110_PD_ISP>;
++ /* irq nr: vin, isp, isp_csi, isp_scd, isp_csiline */
++ interrupts = <92 87 88 89 90>;
++ status = "disabled";
++ };
++
+ ispcrg: clock-controller@19810000 {
+ compatible = "starfive,jh7110-ispcrg";
+ reg = <0x0 0x19810000 0x0 0x10000>;
+@@ -1175,6 +1522,66 @@
+ #phy-cells = <0>;
+ };
+
++ dc8200: dc8200@29400000 {
++ compatible = "starfive,jh7110-dc8200","verisilicon,dc8200";
++ verisilicon,dss-syscon = <&dssctrl>;//20220624 panel syscon
++ reg = <0x0 0x29400000 0x0 0x100>,
++ <0x0 0x29400800 0x0 0x2000>,
++ <0x0 0x17030000 0x0 0x1000>;
++ interrupts = <95>;
++ clocks = <&syscrg JH7110_SYSCLK_NOC_BUS_DISP_AXI>,
++ <&syscrg JH7110_SYSCLK_VOUT_SRC>,
++ <&syscrg JH7110_SYSCLK_VOUT_TOP_AXI>,
++ <&syscrg JH7110_SYSCLK_VOUT_TOP_AHB>,
++ <&voutcrg JH7110_VOUTCLK_DC8200_PIX0>,
++ <&voutcrg JH7110_VOUTCLK_DC8200_PIX1>,
++ <&voutcrg JH7110_VOUTCLK_DC8200_AXI>,
++ <&voutcrg JH7110_VOUTCLK_DC8200_CORE>,
++ <&voutcrg JH7110_VOUTCLK_DC8200_AHB>,
++ <&syscrg JH7110_SYSCLK_VOUT_TOP_AXI>,
++ <&voutcrg JH7110_VOUTCLK_DOM_VOUT_TOP_LCD>,
++ <&hdmitx0_pixelclk>,
++ <&voutcrg JH7110_VOUTCLK_DC8200_PIX>;
++ clock-names = "noc_disp","vout_src",
++ "top_vout_axi","top_vout_ahb",
++ "pix_clk","vout_pix1",
++ "axi_clk","core_clk","vout_ahb",
++ "vout_top_axi","vout_top_lcd","hdmitx0_pixelclk","dc8200_pix0";
++ resets = <&syscrg JH7110_SYSRST_VOUT_TOP_SRC>,
++ <&voutcrg JH7110_VOUTRST_DC8200_AXI>,
++ <&voutcrg JH7110_VOUTRST_DC8200_AHB>,
++ <&voutcrg JH7110_VOUTRST_DC8200_CORE>,
++ <&syscrg JH7110_SYSRST_NOC_BUS_DISP_AXI>;
++ reset-names = "rst_vout_src","rst_axi","rst_ahb","rst_core",
++ "rst_noc_disp";
++ status = "disabled";
++ };
++
++ hdmi: hdmi@29590000 {
++ compatible = "starfive,jh7110-hdmi","inno,hdmi";
++ reg = <0x0 0x29590000 0x0 0x4000>;
++ interrupts = <99>;
++ /*interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;*/
++ /*clocks = <&cru PCLK_HDMI>;*/
++ /*clock-names = "pclk";*/
++ /*pinctrl-names = "default";*/
++ /*pinctrl-0 = <&hdmi_ctl>;*/
++ clocks = <&voutcrg JH7110_VOUTCLK_HDMI_TX_SYS>,
++ <&voutcrg JH7110_VOUTCLK_HDMI_TX_MCLK>,
++ <&voutcrg JH7110_VOUTCLK_HDMI_TX_BCLK>,
++ <&hdmitx0_pixelclk>;
++ clock-names = "sysclk", "mclk","bclk","pclk";
++ resets = <&voutcrg JH7110_VOUTRST_HDMI_TX_HDMI>;
++ reset-names = "hdmi_tx";
++ #sound-dai-cells = <0>;
++ status = "disabled";
++ };
++
++ dssctrl: dssctrl@295B0000 {
++ compatible = "starfive,jh7110-dssctrl","verisilicon,dss-ctrl", "syscon";
++ reg = <0 0x295B0000 0 0x90>;
++ };
++
+ voutcrg: clock-controller@295c0000 {
+ compatible = "starfive,jh7110-voutcrg";
+ reg = <0x0 0x295c0000 0x0 0x10000>;
+@@ -1193,6 +1600,67 @@
+ power-domains = <&pwrc JH7110_PD_VOUT>;
+ };
+
++ mipi_dsi: mipi@295d0000 {
++ compatible = "starfive,jh7110-mipi_dsi","cdns,dsi";
++ reg = <0x0 0x295d0000 0x0 0x10000>;
++ interrupts = <98>;
++ reg-names = "dsi";
++ clocks = <&voutcrg JH7110_VOUTCLK_DSITX_SYS>,
++ <&voutcrg JH7110_VOUTCLK_DSITX_APB>,
++ <&voutcrg JH7110_VOUTCLK_DSITX_TXESC>,
++ <&voutcrg JH7110_VOUTCLK_DSITX_DPI>;
++ clock-names = "dpi", "apb", "txesc", "sys";
++ resets = <&voutcrg JH7110_VOUTRST_DSITX_DPI>,
++ <&voutcrg JH7110_VOUTRST_DSITX_APB>,
++ <&voutcrg JH7110_VOUTRST_DSITX_RXESC>,
++ <&voutcrg JH7110_VOUTRST_DSITX_SYS>,
++ <&voutcrg JH7110_VOUTRST_DSITX_TXBYTEHS>,
++ <&voutcrg JH7110_VOUTRST_DSITX_TXESC>;
++ reset-names = "dsi_dpi", "dsi_apb", "dsi_rxesc",
++ "dsi_sys", "dsi_txbytehs", "dsi_txesc";
++ phys = <&mipi_dphy>;
++ phy-names = "dphy";
++ status = "disabled";
++ };
++
++ mipi_dphy: mipi-dphy@295e0000{
++ compatible = "starfive,jh7110-mipi-dphy-tx","m31,mipi-dphy-tx";
++ reg = <0x0 0x295e0000 0x0 0x10000>;
++ clocks = <&voutcrg JH7110_VOUTCLK_MIPITX_DPHY_TXESC>;
++ clock-names = "dphy_txesc";
++ resets = <&voutcrg JH7110_VOUTRST_MIPITX_DPHY_SYS>,
++ <&voutcrg JH7110_VOUTRST_MIPITX_DPHY_TXBYTEHS>;
++ reset-names = "dphy_sys", "dphy_txbytehs";
++ #phy-cells = <0>;
++ status = "disabled";
++ };
++
++ co_process: e24@6e210000 {
++ compatible = "starfive,e24";
++ dma-coherent;
++ reg = <0x0 0x6e210000 0x0 0x00001000>,
++ <0x0 0x6e211000 0x0 0x0003f000>;
++ reg-names = "ecmd", "espace";
++ clocks = <&stgcrg JH7110_STGCLK_E2_RTC>,
++ <&stgcrg JH7110_STGCLK_E2_CORE>,
++ <&stgcrg JH7110_STGCLK_E2_DBG>;
++ clock-names = "clk_rtc", "clk_core", "clk_dbg";
++ resets = <&stgcrg JH7110_STGRST_E24_CORE>;
++ reset-names = "e24_core";
++ starfive,stg-syscon = <&stg_syscon>;
++ interrupt-parent = <&plic>;
++ firmware-name = "e24_elf";
++ irq-mode = <1>;
++ mbox-names = "tx", "rx";
++ mboxes = <&mailbox_contrl0 0 2>,
++ <&mailbox_contrl0 2 0>;
++ #address-cells = <1>;
++ #size-cells = <1>;
++ ranges = <0x6ce00000 0x0 0x6ce00000 0x1600000>;
++ status = "disabled";
++ dsp@0 {};
++ };
++
+ pcie0: pcie@940000000 {
+ compatible = "starfive,jh7110-pcie";
+ reg = <0x9 0x40000000 0x0 0x1000000>,
diff --git a/target/linux/starfive/patches-6.6/0057-riscv-dts-starfive-Add-JH7110-EVB-expanded-device-tr.patch b/target/linux/starfive/patches-6.6/0057-riscv-dts-starfive-Add-JH7110-EVB-expanded-device-tr.patch
new file mode 100644
index 0000000000..7a23bf931b
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0057-riscv-dts-starfive-Add-JH7110-EVB-expanded-device-tr.patch
@@ -0,0 +1,728 @@
+From cae7550054ca0cd940bbc1501ae5611f5d2957e6 Mon Sep 17 00:00:00 2001
+From: Hal Feng <hal.feng@starfivetech.com>
+Date: Wed, 20 Sep 2023 14:53:22 +0800
+Subject: [PATCH 057/116] riscv: dts: starfive: Add JH7110 EVB expanded device
+ tree
+
+Add JH7110 EVB expanded device tree.
+The code is ported from tag JH7110_SDK_6.1_v5.11.3
+
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ arch/riscv/boot/dts/starfive/Makefile | 11 +-
+ .../starfive/jh7110-evb-can-pdm-pwmdac.dts | 102 ++++++++++++++++
+ .../dts/starfive/jh7110-evb-dvp-rgb2hdmi.dts | 37 ++++++
+ .../dts/starfive/jh7110-evb-i2s-ac108.dts | 72 ++++++++++++
+ .../dts/starfive/jh7110-evb-pcie-i2s-sd.dts | 111 ++++++++++++++++++
+ .../dts/starfive/jh7110-evb-spi-uart2.dts | 65 ++++++++++
+ .../starfive/jh7110-evb-uart1-rgb2hdmi.dts | 57 +++++++++
+ .../starfive/jh7110-evb-uart4-emmc-spdif.dts | 78 ++++++++++++
+ .../starfive/jh7110-evb-uart5-pwm-i2c-tdm.dts | 95 +++++++++++++++
+ .../dts/starfive/jh7110-evb-usbdevice.dts | 35 ++++++
+ 10 files changed, 662 insertions(+), 1 deletion(-)
+ create mode 100644 arch/riscv/boot/dts/starfive/jh7110-evb-can-pdm-pwmdac.dts
+ create mode 100644 arch/riscv/boot/dts/starfive/jh7110-evb-dvp-rgb2hdmi.dts
+ create mode 100644 arch/riscv/boot/dts/starfive/jh7110-evb-i2s-ac108.dts
+ create mode 100644 arch/riscv/boot/dts/starfive/jh7110-evb-pcie-i2s-sd.dts
+ create mode 100644 arch/riscv/boot/dts/starfive/jh7110-evb-spi-uart2.dts
+ create mode 100644 arch/riscv/boot/dts/starfive/jh7110-evb-uart1-rgb2hdmi.dts
+ create mode 100644 arch/riscv/boot/dts/starfive/jh7110-evb-uart4-emmc-spdif.dts
+ create mode 100644 arch/riscv/boot/dts/starfive/jh7110-evb-uart5-pwm-i2c-tdm.dts
+ create mode 100644 arch/riscv/boot/dts/starfive/jh7110-evb-usbdevice.dts
+
+--- a/arch/riscv/boot/dts/starfive/Makefile
++++ b/arch/riscv/boot/dts/starfive/Makefile
+@@ -12,4 +12,13 @@ dtb-$(CONFIG_ARCH_STARFIVE) += jh7100-st
+ dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-starfive-visionfive-2-v1.2a.dtb
+ dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-starfive-visionfive-2-v1.3b.dtb
+
+-dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-evb.dtb
++dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-evb.dtb \
++ jh7110-evb-pcie-i2s-sd.dtb \
++ jh7110-evb-spi-uart2.dtb \
++ jh7110-evb-uart4-emmc-spdif.dtb \
++ jh7110-evb-uart5-pwm-i2c-tdm.dtb \
++ jh7110-evb-dvp-rgb2hdmi.dtb \
++ jh7110-evb-can-pdm-pwmdac.dtb \
++ jh7110-evb-i2s-ac108.dtb \
++ jh7110-evb-usbdevice.dtb \
++ jh7110-evb-uart1-rgb2hdmi.dtb
+--- /dev/null
++++ b/arch/riscv/boot/dts/starfive/jh7110-evb-can-pdm-pwmdac.dts
+@@ -0,0 +1,102 @@
++// SPDX-License-Identifier: GPL-2.0 OR MIT
++/*
++ * Copyright (C) 2022 StarFive Technology Co., Ltd.
++ */
++
++/dts-v1/;
++#include "jh7110-evb.dtsi"
++
++/ {
++ model = "StarFive JH7110 EVB";
++ compatible = "starfive,jh7110-evb", "starfive,jh7110";
++
++ sound2: snd-card2 {
++ compatible = "simple-audio-card";
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ simple-audio-card,name = "StarFive-PDM-Sound-Card";
++ simple-audio-card,dai-link@0 {
++ reg = <0>;
++ format = "i2s";
++ bitclock-master = <&dailink_master>;
++ frame-master = <&dailink_master>;
++
++ dailink_master:cpu {
++ sound-dai = <&i2srx_mst>;
++ };
++
++ dailink_slave:codec {
++ sound-dai = <&pdm>;
++ };
++ };
++ };
++
++ pwmdac_codec: pwmdac-codec {
++ compatible = "linux,spdif-dit";
++ #sound-dai-cells = <0>;
++ };
++
++ sound3: snd-card3 {
++ compatible = "simple-audio-card";
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ simple-audio-card,name = "StarFive-PWMDAC-Sound-Card";
++ simple-audio-card,dai-link@0 {
++ reg = <0>;
++ format = "left_j";
++ bitclock-master = <&sndcpu0>;
++ frame-master = <&sndcpu0>;
++
++ sndcpu0: cpu {
++ sound-dai = <&pwmdac>;
++ };
++
++ codec {
++ sound-dai = <&pwmdac_codec>;
++ };
++ };
++ };
++};
++
++&mmc0 {
++ assigned-clocks = <&syscrg JH7110_SYSCLK_SDIO0_SDCARD>;
++ assigned-clock-rates = <50000000>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdcard0_pins>;
++ max-frequency = <100000000>;
++ card-detect-delay = <300>;
++ bus-width = <4>;
++ broken-cd;
++ post-power-on-delay-ms = <200>;
++ status = "okay";
++};
++
++&usb0 {
++ status = "okay";
++};
++
++&pcie1 {
++ status = "okay";
++};
++
++&can0 {
++ status = "okay";
++};
++
++&can1 {
++ status = "okay";
++};
++
++&i2srx_mst {
++ status = "okay";
++};
++
++&pwmdac {
++ status = "okay";
++};
++
++&pdm {
++ status = "okay";
++};
+--- /dev/null
++++ b/arch/riscv/boot/dts/starfive/jh7110-evb-dvp-rgb2hdmi.dts
+@@ -0,0 +1,37 @@
++// SPDX-License-Identifier: GPL-2.0 OR MIT
++/*
++ * Copyright (C) 2022 StarFive Technology Co., Ltd.
++ */
++
++/dts-v1/;
++#include "jh7110-evb.dtsi"
++
++/ {
++ model = "StarFive JH7110 EVB";
++ compatible = "starfive,jh7110-evb", "starfive,jh7110";
++};
++
++&vin_sysctl {
++ pinctrl-names = "default";
++ pinctrl-0 = <&dvp_pins>;
++};
++
++&rgb_output {
++ status = "okay";
++};
++
++&tda988x_pin {
++ status = "okay";
++};
++
++&dsi_output {
++ status = "disabled";
++};
++
++&mipi_dsi {
++ status = "disabled";
++};
++
++&mipi_dphy {
++ status = "disabled";
++};
+--- /dev/null
++++ b/arch/riscv/boot/dts/starfive/jh7110-evb-i2s-ac108.dts
+@@ -0,0 +1,72 @@
++// SPDX-License-Identifier: GPL-2.0 OR MIT
++/*
++ * Copyright (C) 2022 StarFive Technology Co., Ltd.
++ */
++
++/dts-v1/;
++#include "jh7110-evb.dtsi"
++
++/ {
++ model = "StarFive JH7110 EVB";
++ compatible = "starfive,jh7110-evb", "starfive,jh7110";
++
++ /* i2s + ac108 */
++ sound0: snd-card0 {
++ compatible = "simple-audio-card";
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ simple-audio-card,name = "StarFive-AC108-Sound-Card";
++ simple-audio-card,dai-link@0 {
++ reg = <0>;
++ format = "i2s";
++ bitclock-master = <&sndcodec1>;
++ frame-master = <&sndcodec1>;
++
++ widgets = "Microphone", "Mic Jack",
++ "Line", "Line In",
++ "Line", "Line Out",
++ "Speaker", "Speaker",
++ "Headphone", "Headphone Jack";
++ routing = "Headphone Jack", "HP_L",
++ "Headphone Jack", "HP_R",
++ "Speaker", "SPK_LP",
++ "Speaker", "SPK_LN",
++ "LINPUT1", "Mic Jack",
++ "LINPUT3", "Mic Jack",
++ "RINPUT1", "Mic Jack",
++ "RINPUT2", "Mic Jack";
++
++ cpu {
++ sound-dai = <&i2srx>;
++ };
++
++ sndcodec1: codec {
++ sound-dai = <&ac108>;
++ clocks = <&ac108_mclk>;
++ clock-names = "mclk";
++ };
++ };
++ };
++};
++
++&mmc0 {
++ assigned-clocks = <&syscrg JH7110_SYSCLK_SDIO0_SDCARD>;
++ assigned-clock-rates = <50000000>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdcard0_pins>;
++ max-frequency = <100000000>;
++ card-detect-delay = <300>;
++ bus-width = <4>;
++ broken-cd;
++ post-power-on-delay-ms = <200>;
++ status = "okay";
++};
++
++&i2c0 {
++ status = "okay";
++};
++
++&i2srx {
++ status = "okay";
++};
+--- /dev/null
++++ b/arch/riscv/boot/dts/starfive/jh7110-evb-pcie-i2s-sd.dts
+@@ -0,0 +1,111 @@
++// SPDX-License-Identifier: GPL-2.0 OR MIT
++/*
++ * Copyright (C) 2022 StarFive Technology Co., Ltd.
++ */
++
++/dts-v1/;
++#include "jh7110-evb.dtsi"
++
++/ {
++ model = "StarFive JH7110 EVB";
++ compatible = "starfive,jh7110-evb", "starfive,jh7110";
++
++ /* i2s + wm8960 */
++ sound6: snd-card6 {
++ compatible = "simple-audio-card";
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ simple-audio-card,name = "StarFive-WM8960-Sound-Card";
++ simple-audio-card,dai-link@0 {
++ reg = <0>;
++ status = "okay";
++ format = "i2s";
++ bitclock-master = <&sndcodec1>;
++ frame-master = <&sndcodec1>;
++
++ widgets = "Microphone", "Mic Jack",
++ "Line", "Line In",
++ "Line", "Line Out",
++ "Speaker", "Speaker",
++ "Headphone", "Headphone Jack";
++ routing = "Headphone Jack", "HP_L",
++ "Headphone Jack", "HP_R",
++ "Speaker", "SPK_LP",
++ "Speaker", "SPK_LN",
++ "LINPUT1", "Mic Jack",
++ "LINPUT3", "Mic Jack",
++ "RINPUT1", "Mic Jack",
++ "RINPUT2", "Mic Jack";
++ cpu0 {
++ sound-dai = <&i2srx>;
++ };
++ cpu1 {
++ sound-dai = <&i2stx1>;
++ };
++
++ sndcodec1:codec {
++ sound-dai = <&wm8960>;
++ clocks = <&wm8960_mclk>;
++ clock-names = "mclk";
++ };
++ };
++ };
++};
++
++&mmc0 {
++ assigned-clocks = <&syscrg JH7110_SYSCLK_SDIO0_SDCARD>;
++ assigned-clock-rates = <50000000>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdcard0_pins>;
++ max-frequency = <100000000>;
++ card-detect-delay = <300>;
++ bus-width = <4>;
++ broken-cd;
++ post-power-on-delay-ms = <200>;
++ status = "okay";
++};
++
++&pcie1 {
++ status = "okay";
++};
++
++&pcie0 {
++ status = "okay";
++};
++
++&uart3 {
++ status = "okay";
++};
++
++&i2c0 {
++ status = "okay";
++};
++
++&usb0 {
++ clocks = <&stgcrg JH7110_STGCLK_USB0_LPM>,
++ <&stgcrg JH7110_STGCLK_USB0_STB>,
++ <&stgcrg JH7110_STGCLK_USB0_APB>,
++ <&stgcrg JH7110_STGCLK_USB0_AXI>,
++ <&stgcrg JH7110_STGCLK_USB0_UTMI_APB>;
++ clock-names = "lpm", "stb", "apb", "axi", "utmi_apb";
++ resets = <&stgcrg JH7110_STGRST_USB0_PWRUP>,
++ <&stgcrg JH7110_STGRST_USB0_APB>,
++ <&stgcrg JH7110_STGRST_USB0_AXI>,
++ <&stgcrg JH7110_STGRST_USB0_UTMI_APB>;
++ reset-names = "pwrup", "apb", "axi", "utmi_apb";
++ dr_mode = "host"; /*host or peripheral*/
++ starfive,usb2-only;
++ pinctrl-names = "default";
++ pinctrl-0 = <&usb_pins>;
++ status = "okay";
++};
++
++&i2srx {
++ status = "okay";
++};
++
++&i2stx1 {
++ status = "okay";
++};
++
+--- /dev/null
++++ b/arch/riscv/boot/dts/starfive/jh7110-evb-spi-uart2.dts
+@@ -0,0 +1,65 @@
++// SPDX-License-Identifier: GPL-2.0 OR MIT
++/*
++ * Copyright (C) 2022 StarFive Technology Co., Ltd.
++ */
++
++/dts-v1/;
++#include "jh7110-evb.dtsi"
++
++/ {
++ model = "StarFive JH7110 EVB";
++ compatible = "starfive,jh7110-evb", "starfive,jh7110";
++};
++
++&mmc0 {
++ assigned-clocks = <&syscrg JH7110_SYSCLK_SDIO0_SDCARD>;
++ assigned-clock-rates = <50000000>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdcard0_pins>;
++ max-frequency = <100000000>;
++ card-detect-delay = <300>;
++ bus-width = <4>;
++ broken-cd;
++ post-power-on-delay-ms = <200>;
++ status = "okay";
++};
++
++&usb0 {
++ status = "okay";
++};
++
++&pcie1 {
++ status = "okay";
++};
++
++&uart2 {
++ status = "okay";
++};
++
++&spi0 {
++ status = "okay";
++};
++
++&spi1 {
++ status = "okay";
++};
++
++&spi2 {
++ status = "okay";
++};
++
++&spi3 {
++ status = "okay";
++};
++
++&spi4 {
++ status = "okay";
++};
++
++&spi5 {
++ status = "okay";
++};
++
++&spi6 {
++ status = "okay";
++};
+--- /dev/null
++++ b/arch/riscv/boot/dts/starfive/jh7110-evb-uart1-rgb2hdmi.dts
+@@ -0,0 +1,57 @@
++// SPDX-License-Identifier: GPL-2.0 OR MIT
++/*
++ * Copyright (C) 2022 StarFive Technology Co., Ltd.
++ */
++
++/dts-v1/;
++#include "jh7110-evb.dtsi"
++
++/ {
++ model = "StarFive JH7110 EVB";
++ compatible = "starfive,jh7110-evb", "starfive,jh7110";
++};
++
++&mmc0 {
++ assigned-clocks = <&syscrg JH7110_SYSCLK_SDIO0_SDCARD>;
++ assigned-clock-rates = <50000000>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdcard0_pins>;
++ max-frequency = <100000000>;
++ card-detect-delay = <300>;
++ bus-width = <4>;
++ broken-cd;
++ post-power-on-delay-ms = <200>;
++ status = "okay";
++};
++
++&usb0 {
++ status = "okay";
++};
++
++&pcie1 {
++ status = "okay";
++};
++
++&uart1 {
++ status = "okay";
++};
++
++&rgb_output {
++ status = "okay";
++};
++
++&tda988x_pin {
++ status = "okay";
++};
++
++&dsi_output {
++ status = "disabled";
++};
++
++&mipi_dsi {
++ status = "disabled";
++};
++
++&mipi_dphy {
++ status = "disabled";
++};
+--- /dev/null
++++ b/arch/riscv/boot/dts/starfive/jh7110-evb-uart4-emmc-spdif.dts
+@@ -0,0 +1,78 @@
++// SPDX-License-Identifier: GPL-2.0 OR MIT
++/*
++ * Copyright (C) 2022 StarFive Technology Co., Ltd.
++ */
++
++/dts-v1/;
++#include "jh7110-evb.dtsi"
++
++/ {
++ model = "StarFive JH7110 EVB";
++ compatible = "starfive,jh7110-evb", "starfive,jh7110";
++
++ spdif_transmitter: spdif_transmitter {
++ compatible = "linux,spdif-dit";
++ #sound-dai-cells = <0>;
++ };
++
++ sound4: snd-card4 {
++ compatible = "simple-audio-card";
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ simple-audio-card,name = "StarFive-SPDIF-Sound-Card";
++ simple-audio-card,dai-link@0 {
++ reg = <0>;
++ format = "left_j";
++ bitclock-master = <&sndcpu0>;
++ frame-master = <&sndcpu0>;
++
++ sndcpu0: cpu {
++ sound-dai = <&spdif>;
++ };
++
++ codec {
++ sound-dai = <&spdif_transmitter>;
++ };
++ };
++ };
++};
++
++&usb0 {
++ status = "okay";
++};
++
++&pcie1 {
++ status = "okay";
++};
++
++&uart4 {
++ status = "okay";
++};
++
++&mmc0 {
++ assigned-clocks = <&syscrg JH7110_SYSCLK_SDIO0_SDCARD>;
++ assigned-clock-rates = <50000000>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&emmc0_pins>;
++ max-frequency = <100000000>;
++ card-detect-delay = <300>;
++ bus-width = <8>;
++ cap-mmc-highspeed;
++ mmc-hs200-1_8v;
++ non-removable;
++ cap-mmc-hw-reset;
++ board-is-evb;
++ post-power-on-delay-ms = <200>;
++ status = "okay";
++};
++
++&pwm {
++ pinctrl-names = "default";
++ pinctrl-0 = <&pwm_ch6to7_pins>;
++ status = "okay";
++};
++
++&spdif {
++ status = "okay";
++};
+--- /dev/null
++++ b/arch/riscv/boot/dts/starfive/jh7110-evb-uart5-pwm-i2c-tdm.dts
+@@ -0,0 +1,95 @@
++// SPDX-License-Identifier: GPL-2.0 OR MIT
++/*
++ * Copyright (C) 2022 StarFive Technology Co., Ltd.
++ */
++
++/dts-v1/;
++#include "jh7110-evb.dtsi"
++
++/ {
++ model = "StarFive JH7110 EVB";
++ compatible = "starfive,jh7110-evb", "starfive,jh7110";
++
++ sound5: snd-card5 {
++ compatible = "simple-audio-card";
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ simple-audio-card,name = "StarFive-TDM-Sound-Card";
++ simple-audio-card,widgets = "Microphone", "Mic Jack",
++ "Line", "Line In",
++ "Line", "Line Out",
++ "Speaker", "Speaker",
++ "Headphone", "Headphone Jack";
++ simple-audio-card,routing = "Headphone Jack", "HP_L",
++ "Headphone Jack", "HP_R",
++ "Speaker", "SPK_LP",
++ "Speaker", "SPK_LN",
++ "LINPUT1", "Mic Jack",
++ "LINPUT3", "Mic Jack",
++ "RINPUT1", "Mic Jack",
++ "RINPUT2", "Mic Jack";
++
++ simple-audio-card,dai-link@0 {
++ reg = <0>;
++ format = "dsp_a";
++ bitclock-master = <&dailink_master>;
++ frame-master = <&dailink_master>;
++
++ cpu {
++ sound-dai = <&tdm>;
++ };
++ dailink_master: codec {
++ sound-dai = <&wm8960>;
++ clocks = <&wm8960_mclk>;
++ };
++ };
++ };
++};
++
++&mmc0 {
++ assigned-clocks = <&syscrg JH7110_SYSCLK_SDIO0_SDCARD>;
++ assigned-clock-rates = <50000000>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdcard0_pins>;
++ max-frequency = <100000000>;
++ card-detect-delay = <300>;
++ bus-width = <4>;
++ broken-cd;
++ post-power-on-delay-ms = <200>;
++ status = "okay";
++};
++
++&usb0 {
++ status = "okay";
++};
++
++&pcie1 {
++ status = "okay";
++};
++
++&uart5 {
++ status = "okay";
++};
++
++&pwm {
++ pinctrl-names = "default";
++ pinctrl-0 = <&pwm_ch0to3_pins &pwm_ch4to5_pins>;
++ status = "okay";
++};
++
++&tdm {
++ status = "okay";
++};
++
++&i2c0 {
++ status = "okay";
++};
++
++&i2c1 {
++ status = "okay";
++};
++
++&i2c3 {
++ status = "okay";
++};
+--- /dev/null
++++ b/arch/riscv/boot/dts/starfive/jh7110-evb-usbdevice.dts
+@@ -0,0 +1,35 @@
++// SPDX-License-Identifier: GPL-2.0 OR MIT
++/*
++ * Copyright (C) 2022 StarFive Technology Co., Ltd.
++ */
++
++/dts-v1/;
++#include "jh7110-evb.dtsi"
++
++/ {
++ model = "StarFive JH7110 EVB";
++ compatible = "starfive,jh7110-evb", "starfive,jh7110";
++};
++
++/* default sd card */
++&mmc0 {
++ assigned-clocks = <&syscrg JH7110_SYSCLK_SDIO0_SDCARD>;
++ assigned-clock-rates = <50000000>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdcard0_pins>;
++ max-frequency = <100000000>;
++ card-detect-delay = <300>;
++ bus-width = <4>;
++ broken-cd;
++ post-power-on-delay-ms = <200>;
++ status = "okay";
++};
++
++&usb0 {
++ dr_mode = "peripheral"; /*host or peripheral*/
++ status = "okay";
++};
++
++&pcie1 {
++ status = "okay";
++};
diff --git a/target/linux/starfive/patches-6.6/0058-riscv-dts-starfive-Add-evb-overlay-dtso-subdir.patch b/target/linux/starfive/patches-6.6/0058-riscv-dts-starfive-Add-evb-overlay-dtso-subdir.patch
new file mode 100644
index 0000000000..a75ffc2aff
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0058-riscv-dts-starfive-Add-evb-overlay-dtso-subdir.patch
@@ -0,0 +1,485 @@
+From e9122ceaf2d8767753e2a126c14b29b78280446d Mon Sep 17 00:00:00 2001
+From: Hal Feng <hal.feng@starfivetech.com>
+Date: Tue, 19 Sep 2023 21:35:39 +0800
+Subject: [PATCH 058/116] riscv: dts: starfive: Add evb-overlay dtso subdir
+
+Create subdir evb-overlay/ and add overlay .dtso for JH7110 EVB.
+The code is ported from tag JH7110_SDK_6.1_v5.11.3
+
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ arch/riscv/boot/dts/starfive/Makefile | 1 +
+ .../boot/dts/starfive/evb-overlay/Makefile | 7 +
+ .../evb-overlay/jh7110-evb-overlay-can.dtso | 24 ++++
+ .../jh7110-evb-overlay-rgb2hdmi.dtso | 24 ++++
+ .../evb-overlay/jh7110-evb-overlay-sdio.dtso | 78 +++++++++++
+ .../evb-overlay/jh7110-evb-overlay-spi.dtso | 72 ++++++++++
+ .../jh7110-evb-overlay-uart4-emmc.dtso | 130 ++++++++++++++++++
+ .../jh7110-evb-overlay-uart5-pwm.dtso | 92 +++++++++++++
+ 8 files changed, 428 insertions(+)
+ create mode 100644 arch/riscv/boot/dts/starfive/evb-overlay/Makefile
+ create mode 100644 arch/riscv/boot/dts/starfive/evb-overlay/jh7110-evb-overlay-can.dtso
+ create mode 100644 arch/riscv/boot/dts/starfive/evb-overlay/jh7110-evb-overlay-rgb2hdmi.dtso
+ create mode 100644 arch/riscv/boot/dts/starfive/evb-overlay/jh7110-evb-overlay-sdio.dtso
+ create mode 100644 arch/riscv/boot/dts/starfive/evb-overlay/jh7110-evb-overlay-spi.dtso
+ create mode 100644 arch/riscv/boot/dts/starfive/evb-overlay/jh7110-evb-overlay-uart4-emmc.dtso
+ create mode 100644 arch/riscv/boot/dts/starfive/evb-overlay/jh7110-evb-overlay-uart5-pwm.dtso
+
+--- a/arch/riscv/boot/dts/starfive/Makefile
++++ b/arch/riscv/boot/dts/starfive/Makefile
+@@ -12,6 +12,7 @@ dtb-$(CONFIG_ARCH_STARFIVE) += jh7100-st
+ dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-starfive-visionfive-2-v1.2a.dtb
+ dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-starfive-visionfive-2-v1.3b.dtb
+
++subdir-y += evb-overlay
+ dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-evb.dtb \
+ jh7110-evb-pcie-i2s-sd.dtb \
+ jh7110-evb-spi-uart2.dtb \
+--- /dev/null
++++ b/arch/riscv/boot/dts/starfive/evb-overlay/Makefile
+@@ -0,0 +1,7 @@
++# SPDX-License-Identifier: GPL-2.0
++dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-evb-overlay-can.dtbo \
++ jh7110-evb-overlay-sdio.dtbo \
++ jh7110-evb-overlay-spi.dtbo \
++ jh7110-evb-overlay-uart4-emmc.dtbo \
++ jh7110-evb-overlay-uart5-pwm.dtbo \
++ jh7110-evb-overlay-rgb2hdmi.dtbo
+--- /dev/null
++++ b/arch/riscv/boot/dts/starfive/evb-overlay/jh7110-evb-overlay-can.dtso
+@@ -0,0 +1,24 @@
++/dts-v1/;
++/plugin/;
++#include <dt-bindings/gpio/gpio.h>
++#include "../jh7110-pinfunc.h"
++/ {
++ compatible = "starfive,jh7110";
++
++ //can0
++ fragment@0 {
++ target-path = "/soc/can@130d0000";
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ //can1
++ fragment@1 {
++ target-path = "/soc/can@130e0000";
++ __overlay__ {
++ status = "okay";
++ };
++ };
++};
++
+--- /dev/null
++++ b/arch/riscv/boot/dts/starfive/evb-overlay/jh7110-evb-overlay-rgb2hdmi.dtso
+@@ -0,0 +1,24 @@
++/dts-v1/;
++/plugin/;
++#include <dt-bindings/gpio/gpio.h>
++#include "../jh7110-pinfunc.h"
++/ {
++ compatible = "starfive,jh7110";
++
++ //hdmi_output
++ fragment@0 {
++ target-path = "/tda988x_pin";
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ //uart1
++ fragment@1 {
++ target-path = "/soc/serial@10010000";
++ __overlay__ {
++ status = "okay";
++ };
++ };
++};
++
+--- /dev/null
++++ b/arch/riscv/boot/dts/starfive/evb-overlay/jh7110-evb-overlay-sdio.dtso
+@@ -0,0 +1,78 @@
++/dts-v1/;
++/plugin/;
++#include <dt-bindings/gpio/gpio.h>
++#include "../jh7110-pinfunc.h"
++/ {
++ compatible = "starfive,jh7110";
++
++ //sysgpio
++ fragment@0 {
++ target-path = "/soc/pinctrl@13040000";
++ __overlay__ {
++ dt_sdcard1_pins: dt-sdcard1-0 {
++ sdcard-pins {
++ pinmux = <GPIOMUX(56, GPOUT_SYS_SDIO1_CLK,
++ GPOEN_ENABLE,
++ GPI_NONE)>,
++ <GPIOMUX(50, GPOUT_SYS_SDIO1_CMD,
++ GPOEN_SYS_SDIO1_CMD,
++ GPI_SYS_SDIO1_CMD)>,
++ <GPIOMUX(49, GPOUT_SYS_SDIO1_DATA0,
++ GPOEN_SYS_SDIO1_DATA0,
++ GPI_SYS_SDIO1_DATA0)>,
++ <GPIOMUX(45, GPOUT_SYS_SDIO1_DATA1,
++ GPOEN_SYS_SDIO1_DATA1,
++ GPI_SYS_SDIO1_DATA1)>,
++ <GPIOMUX(62, GPOUT_SYS_SDIO1_DATA2,
++ GPOEN_SYS_SDIO1_DATA2,
++ GPI_SYS_SDIO1_DATA2)>,
++ <GPIOMUX(40, GPOUT_SYS_SDIO1_DATA3,
++ GPOEN_SYS_SDIO1_DATA3,
++ GPI_SYS_SDIO1_DATA3)>;
++ bias-pull-up;
++ input-enable;
++ };
++ };
++ };
++ };
++
++ //uart3
++ fragment@1 {
++ target-path = "/soc/serial@12000000";
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ //i2c0
++ fragment@2 {
++ target-path = "/soc/i2c@10030000";
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ //mmc1
++ fragment@3 {
++ target-path = "/soc/mmc@16020000";
++ __overlay__ {
++ max-frequency = <100000000>;
++ card-detect-delay = <300>;
++ bus-width = <4>;
++ no-sdio;
++ no-mmc;
++ broken-cd;
++ sd-uhs-sdr12;
++ sd-uhs-sdr25;
++ sd-uhs-sdr50;
++ sd-uhs-sdr104;
++ sd-uhs-ddr50;
++ cap-sd-highspeed;
++ post-power-on-delay-ms = <200>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&dt_sdcard1_pins>;
++ status = "okay";
++ };
++ };
++};
++
+--- /dev/null
++++ b/arch/riscv/boot/dts/starfive/evb-overlay/jh7110-evb-overlay-spi.dtso
+@@ -0,0 +1,72 @@
++/dts-v1/;
++/plugin/;
++#include <dt-bindings/gpio/gpio.h>
++#include "../jh7110-pinfunc.h"
++/ {
++ compatible = "starfive,jh7110";
++
++ //spi0
++ fragment@0 {
++ target-path = "/soc/spi@10060000";
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ //spi1
++ fragment@1 {
++ target-path = "/soc/spi@10070000";
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ //spi2
++ fragment@2 {
++ target-path = "/soc/spi@10080000";
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ //spi3
++ fragment@3 {
++ target-path = "/soc/spi@12070000";
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ //spi4
++ fragment@4 {
++ target-path = "/soc/spi@12080000";
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ //spi5
++ fragment@5 {
++ target-path = "/soc/spi@12090000";
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ //spi6
++ fragment@6 {
++ target-path = "/soc/spi@120a0000";
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ //uart2
++ fragment@7 {
++ target-path = "/soc/serial@10020000";
++ __overlay__ {
++ status = "okay";
++ };
++ };
++};
++
+--- /dev/null
++++ b/arch/riscv/boot/dts/starfive/evb-overlay/jh7110-evb-overlay-uart4-emmc.dtso
+@@ -0,0 +1,130 @@
++/dts-v1/;
++/plugin/;
++#include <dt-bindings/gpio/gpio.h>
++#include "../jh7110-pinfunc.h"
++/ {
++ compatible = "starfive,jh7110";
++
++ //sysgpio
++ fragment@0 {
++ target-path = "/soc/pinctrl@13040000";
++ __overlay__ {
++ dt_emmc0_pins: dt-emmc0-0 {
++ emmc-pins {
++ pinmux = <GPIOMUX(22, GPOUT_SYS_SDIO0_RST,
++ GPOEN_ENABLE,
++ GPI_NONE)>,
++ <PINMUX(64, 0)>,
++ <PINMUX(65, 0)>,
++ <PINMUX(66, 0)>,
++ <PINMUX(67, 0)>,
++ <PINMUX(68, 0)>,
++ <PINMUX(69, 0)>,
++ <PINMUX(70, 0)>,
++ <PINMUX(71, 0)>,
++ <PINMUX(72, 0)>,
++ <PINMUX(73, 0)>;
++ bias-pull-up;
++ drive-strength = <12>;
++ input-enable;
++ slew-rate = <1>;
++ };
++ };
++
++ dt_emmc1_pins: dt-emmc1-0 {
++ emmc-pins {
++ pinmux = <GPIOMUX(51, GPOUT_SYS_SDIO1_RST,
++ GPOEN_ENABLE,
++ GPI_NONE)>,
++ <GPIOMUX(38, GPOUT_SYS_SDIO1_CLK,
++ GPOEN_ENABLE,
++ GPI_NONE)>,
++ <GPIOMUX(36, GPOUT_SYS_SDIO1_CMD,
++ GPOEN_SYS_SDIO1_CMD,
++ GPI_SYS_SDIO1_CMD)>,
++ <GPIOMUX(43, GPOUT_SYS_SDIO1_DATA0,
++ GPOEN_SYS_SDIO1_DATA0,
++ GPI_SYS_SDIO1_DATA0)>,
++ <GPIOMUX(48, GPOUT_SYS_SDIO1_DATA1,
++ GPOEN_SYS_SDIO1_DATA1,
++ GPI_SYS_SDIO1_DATA1)>,
++ <GPIOMUX(53, GPOUT_SYS_SDIO1_DATA2,
++ GPOEN_SYS_SDIO1_DATA2,
++ GPI_SYS_SDIO1_DATA2)>,
++ <GPIOMUX(63, GPOUT_SYS_SDIO1_DATA3,
++ GPOEN_SYS_SDIO1_DATA3,
++ GPI_SYS_SDIO1_DATA3)>,
++ <GPIOMUX(52, GPOUT_SYS_SDIO1_DATA4,
++ GPOEN_SYS_SDIO1_DATA4,
++ GPI_SYS_SDIO1_DATA4)>,
++ <GPIOMUX(39, GPOUT_SYS_SDIO1_DATA5,
++ GPOEN_SYS_SDIO1_DATA5,
++ GPI_SYS_SDIO1_DATA5)>,
++ <GPIOMUX(46, GPOUT_SYS_SDIO1_DATA6,
++ GPOEN_SYS_SDIO1_DATA6,
++ GPI_SYS_SDIO1_DATA6)>,
++ <GPIOMUX(47, GPOUT_SYS_SDIO1_DATA7,
++ GPOEN_SYS_SDIO1_DATA7,
++ GPI_SYS_SDIO1_DATA7)>;
++ bias-pull-up;
++ input-enable;
++ };
++ };
++ };
++ };
++
++ //aongpio
++ fragment@1 {
++ target-path = "/soc/pinctrl@17020000";
++ __overlay__ {
++ dt_pwm_ch6to7_pins: dt-pwm-ch6to7-0 {
++ pwm-pins {
++ pinmux = <GPIOMUX(1, GPOUT_AON_PTC0_PWM6, /* PAD_RGPIO0 */
++ GPOEN_AON_PTC0_OE_N_6,
++ GPI_NONE)>,
++ <GPIOMUX(2, GPOUT_AON_PTC0_PWM7, /* PAD_RGPIO1 */
++ GPOEN_AON_PTC0_OE_N_7,
++ GPI_NONE)>;
++ drive-strength = <12>;
++ };
++ };
++ };
++ };
++
++ //uart4
++ fragment@2 {
++ target-path = "/soc/serial@12010000";
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ //mmc1
++ fragment@3 {
++ target-path = "/soc/mmc@16020000";
++ __overlay__ {
++ clock-frequency = <102400000>;
++ max-frequency = <100000000>;
++ card-detect-delay = <300>;
++ bus-width = <8>;
++ cap-mmc-hw-reset;
++ non-removable;
++ cap-mmc-highspeed;
++ post-power-on-delay-ms = <200>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&dt_emmc1_pins>;
++ status = "okay";
++ };
++ };
++
++ //ptc
++ fragment@4 {
++ target-path = "/soc/pwm@120d0000";
++ __overlay__ {
++ pinctrl-names = "default";
++ pinctrl-0 = <&dt_pwm_ch6to7_pins>;
++ status = "okay";
++ };
++ };
++};
++
+--- /dev/null
++++ b/arch/riscv/boot/dts/starfive/evb-overlay/jh7110-evb-overlay-uart5-pwm.dtso
+@@ -0,0 +1,92 @@
++/dts-v1/;
++/plugin/;
++#include <dt-bindings/gpio/gpio.h>
++#include "../jh7110-pinfunc.h"
++/ {
++ compatible = "starfive,jh7110";
++
++ //sysgpio
++ fragment@0 {
++ target-path = "/soc/pinctrl@13040000";
++ __overlay__ {
++ dt_pwm_ch0to3_pins: dt-pwm-ch0to3-0 {
++ pwm-pins {
++ pinmux = <GPIOMUX(45, GPOUT_SYS_PWM_CHANNEL0,
++ GPOEN_SYS_PWM0_CHANNEL0,
++ GPI_NONE)>,
++ <GPIOMUX(46, GPOUT_SYS_PWM_CHANNEL1,
++ GPOEN_SYS_PWM0_CHANNEL1,
++ GPI_NONE)>,
++ <GPIOMUX(47, GPOUT_SYS_PWM_CHANNEL2,
++ GPOEN_SYS_PWM0_CHANNEL2,
++ GPI_NONE)>,
++ <GPIOMUX(48, GPOUT_SYS_PWM_CHANNEL3,
++ GPOEN_SYS_PWM0_CHANNEL3,
++ GPI_NONE)>;
++ drive-strength = <12>;
++ };
++ };
++ };
++ };
++
++ //aongpio
++ fragment@1 {
++ target-path = "/soc/pinctrl@17020000";
++ __overlay__ {
++ dt_pwm_ch4to5_pins: dt-pwm-ch4to5-0 {
++ pwm-pins {
++ pinmux = <GPIOMUX(1, GPOUT_AON_PTC0_PWM4, /* PAD_RGPIO0 */
++ GPOEN_AON_PTC0_OE_N_4,
++ GPI_NONE)>,
++ <GPIOMUX(2, GPOUT_AON_PTC0_PWM5, /* PAD_RGPIO1 */
++ GPOEN_AON_PTC0_OE_N_5,
++ GPI_NONE)>;
++ drive-strength = <12>;
++ };
++ };
++ };
++ };
++
++ //uart5
++ fragment@2 {
++ target-path = "/soc/serial@12020000";
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ //ptc
++ fragment@3 {
++ target-path = "/soc/pwm@120d0000";
++ __overlay__ {
++ pinctrl-names = "default";
++ pinctrl-0 = <&dt_pwm_ch0to3_pins &dt_pwm_ch4to5_pins>;
++ status = "okay";
++ };
++ };
++
++ //i2c0
++ fragment@4 {
++ target-path = "/soc/i2c@10030000";
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ //i2c1
++ fragment@5 {
++ target-path = "/soc/i2c@10040000";
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ //i2c3
++ fragment@6 {
++ target-path = "/soc/i2c@12030000";
++ __overlay__ {
++ status = "okay";
++ };
++ };
++};
++
diff --git a/target/linux/starfive/patches-6.6/0059-riscv-configs-Add-starfive_jh7110_defconfig.patch b/target/linux/starfive/patches-6.6/0059-riscv-configs-Add-starfive_jh7110_defconfig.patch
new file mode 100644
index 0000000000..ddf72454eb
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0059-riscv-configs-Add-starfive_jh7110_defconfig.patch
@@ -0,0 +1,385 @@
+From 5c888fa081caf5d9473e733931d1c7b3d4b61e61 Mon Sep 17 00:00:00 2001
+From: Hal Feng <hal.feng@starfivetech.com>
+Date: Fri, 28 Jul 2023 18:42:55 +0800
+Subject: [PATCH 059/116] riscv: configs: Add starfive_jh7110_defconfig
+
+Add starfive_jh7110_defconfig for JH7110 EVB.
+The code is ported from tag JH7110_SDK_6.1_v5.11.3
+
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ arch/riscv/configs/starfive_jh7110_defconfig | 368 +++++++++++++++++++
+ 1 file changed, 368 insertions(+)
+ create mode 100644 arch/riscv/configs/starfive_jh7110_defconfig
+
+--- /dev/null
++++ b/arch/riscv/configs/starfive_jh7110_defconfig
+@@ -0,0 +1,368 @@
++CONFIG_COMPILE_TEST=y
++# CONFIG_WERROR is not set
++CONFIG_DEFAULT_HOSTNAME="StarFive"
++CONFIG_SYSVIPC=y
++CONFIG_POSIX_MQUEUE=y
++CONFIG_USELIB=y
++CONFIG_NO_HZ_IDLE=y
++CONFIG_HIGH_RES_TIMERS=y
++CONFIG_BPF_SYSCALL=y
++CONFIG_IKCONFIG=y
++CONFIG_IKCONFIG_PROC=y
++CONFIG_CGROUPS=y
++CONFIG_MEMCG=y
++CONFIG_CGROUP_SCHED=y
++CONFIG_CFS_BANDWIDTH=y
++CONFIG_RT_GROUP_SCHED=y
++CONFIG_CGROUP_PIDS=y
++CONFIG_CGROUP_FREEZER=y
++CONFIG_CGROUP_HUGETLB=y
++CONFIG_CPUSETS=y
++CONFIG_CGROUP_DEVICE=y
++CONFIG_CGROUP_CPUACCT=y
++CONFIG_CGROUP_PERF=y
++CONFIG_CGROUP_BPF=y
++CONFIG_NAMESPACES=y
++CONFIG_USER_NS=y
++CONFIG_CHECKPOINT_RESTORE=y
++CONFIG_BLK_DEV_INITRD=y
++CONFIG_EXPERT=y
++# CONFIG_SYSFS_SYSCALL is not set
++CONFIG_PROFILING=y
++CONFIG_SOC_MICROCHIP_POLARFIRE=y
++CONFIG_SOC_STARFIVE=y
++CONFIG_SOC_VIRT=y
++CONFIG_ERRATA_SIFIVE=y
++CONFIG_NONPORTABLE=y
++CONFIG_SMP=y
++CONFIG_RISCV_SBI_V01=y
++# CONFIG_RISCV_BOOT_SPINWAIT is not set
++CONFIG_HIBERNATION=y
++CONFIG_PM_STD_PARTITION="PARTLABEL=hibernation"
++CONFIG_PM_DEBUG=y
++CONFIG_PM_ADVANCED_DEBUG=y
++CONFIG_PM_TEST_SUSPEND=y
++CONFIG_ENERGY_MODEL=y
++CONFIG_CPU_IDLE=y
++CONFIG_CPU_FREQ=y
++CONFIG_CPU_FREQ_STAT=y
++CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
++CONFIG_CPU_FREQ_GOV_POWERSAVE=y
++CONFIG_CPU_FREQ_GOV_USERSPACE=y
++CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
++CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
++CONFIG_CPUFREQ_DT=y
++CONFIG_VIRTUALIZATION=y
++CONFIG_KVM=m
++CONFIG_JUMP_LABEL=y
++CONFIG_MODULES=y
++CONFIG_MODULE_UNLOAD=y
++CONFIG_BINFMT_MISC=y
++CONFIG_CMA=y
++CONFIG_NET=y
++CONFIG_PACKET=y
++CONFIG_XFRM_USER=m
++CONFIG_IP_MULTICAST=y
++CONFIG_IP_ADVANCED_ROUTER=y
++CONFIG_IP_MULTIPLE_TABLES=y
++CONFIG_IP_PNP=y
++CONFIG_IP_PNP_DHCP=y
++CONFIG_IP_PNP_BOOTP=y
++CONFIG_IP_PNP_RARP=y
++CONFIG_INET_ESP=m
++CONFIG_NETFILTER=y
++CONFIG_BRIDGE_NETFILTER=m
++CONFIG_NF_CONNTRACK=m
++CONFIG_NF_CONNTRACK_FTP=m
++CONFIG_NF_CONNTRACK_TFTP=m
++CONFIG_NETFILTER_XT_MARK=m
++CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m
++CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
++CONFIG_NETFILTER_XT_MATCH_IPVS=m
++CONFIG_IP_VS=m
++CONFIG_IP_VS_PROTO_TCP=y
++CONFIG_IP_VS_PROTO_UDP=y
++CONFIG_IP_VS_RR=m
++CONFIG_IP_VS_NFCT=y
++CONFIG_NF_LOG_ARP=m
++CONFIG_NF_LOG_IPV4=m
++CONFIG_IP_NF_IPTABLES=m
++CONFIG_IP_NF_FILTER=m
++CONFIG_IP_NF_TARGET_REJECT=m
++CONFIG_IP_NF_NAT=m
++CONFIG_IP_NF_TARGET_MASQUERADE=m
++CONFIG_IP_NF_TARGET_REDIRECT=m
++CONFIG_IP_NF_MANGLE=m
++CONFIG_NF_LOG_IPV6=m
++CONFIG_IP6_NF_IPTABLES=m
++CONFIG_IP6_NF_MATCH_IPV6HEADER=m
++CONFIG_IP6_NF_FILTER=m
++CONFIG_IP6_NF_TARGET_REJECT=m
++CONFIG_IP6_NF_MANGLE=m
++CONFIG_BRIDGE=m
++CONFIG_BRIDGE_VLAN_FILTERING=y
++CONFIG_VLAN_8021Q=m
++CONFIG_NET_SCHED=y
++CONFIG_NET_CLS_CGROUP=m
++CONFIG_NETLINK_DIAG=y
++CONFIG_CGROUP_NET_PRIO=y
++CONFIG_CAN=y
++CONFIG_BT=y
++CONFIG_BT_RFCOMM=y
++CONFIG_BT_RFCOMM_TTY=y
++CONFIG_BT_BNEP=y
++CONFIG_BT_BNEP_MC_FILTER=y
++CONFIG_BT_BNEP_PROTO_FILTER=y
++CONFIG_BT_HCIUART=y
++CONFIG_BT_HCIUART_H4=y
++CONFIG_CFG80211=y
++CONFIG_MAC80211=y
++CONFIG_RFKILL=y
++CONFIG_NET_9P=y
++CONFIG_NET_9P_VIRTIO=y
++CONFIG_PCI=y
++CONFIG_PCIEPORTBUS=y
++# CONFIG_PCIEASPM is not set
++CONFIG_PCI_HOST_GENERIC=y
++CONFIG_PCIE_FU740=y
++CONFIG_PCIE_STARFIVE_HOST=y
++CONFIG_DEVTMPFS=y
++CONFIG_DEVTMPFS_MOUNT=y
++CONFIG_MTD=y
++CONFIG_MTD_BLOCK=y
++CONFIG_MTD_SPI_NOR=y
++CONFIG_OF_CONFIGFS=y
++CONFIG_BLK_DEV_LOOP=y
++CONFIG_VIRTIO_BLK=y
++CONFIG_BLK_DEV_NVME=y
++CONFIG_BLK_DEV_SD=y
++CONFIG_BLK_DEV_SR=y
++CONFIG_SCSI_VIRTIO=y
++CONFIG_ATA=y
++CONFIG_SATA_AHCI=y
++CONFIG_SATA_AHCI_PLATFORM=y
++CONFIG_MD=y
++CONFIG_BLK_DEV_DM=m
++CONFIG_DM_THIN_PROVISIONING=m
++CONFIG_NETDEVICES=y
++CONFIG_DUMMY=m
++CONFIG_MACVLAN=m
++CONFIG_IPVLAN=m
++CONFIG_VXLAN=m
++CONFIG_VETH=m
++CONFIG_VIRTIO_NET=y
++CONFIG_MACB=y
++CONFIG_E1000E=y
++CONFIG_R8169=y
++CONFIG_STMMAC_ETH=y
++CONFIG_DWMAC_DWC_QOS_ETH=y
++# CONFIG_DWMAC_GENERIC is not set
++CONFIG_DWMAC_STARFIVE=y
++CONFIG_MARVELL_PHY=y
++CONFIG_MICREL_PHY=y
++CONFIG_MICROCHIP_PHY=y
++CONFIG_MICROSEMI_PHY=y
++CONFIG_MOTORCOMM_PHY=y
++CONFIG_IPMS_CAN=y
++CONFIG_IWLWIFI=y
++CONFIG_IWLDVM=y
++CONFIG_IWLMVM=y
++CONFIG_INPUT_MOUSEDEV=y
++CONFIG_INPUT_EVDEV=y
++CONFIG_INPUT_TOUCHSCREEN=y
++CONFIG_TOUCHSCREEN_TINKER_FT5406=y
++CONFIG_SERIAL_8250=y
++CONFIG_SERIAL_8250_CONSOLE=y
++CONFIG_SERIAL_8250_NR_UARTS=6
++CONFIG_SERIAL_8250_RUNTIME_UARTS=6
++CONFIG_SERIAL_8250_EXTENDED=y
++CONFIG_SERIAL_8250_MANY_PORTS=y
++CONFIG_SERIAL_8250_DW=y
++CONFIG_SERIAL_OF_PLATFORM=y
++CONFIG_SERIAL_EARLYCON_RISCV_SBI=y
++CONFIG_TTY_PRINTK=y
++CONFIG_VIRTIO_CONSOLE=y
++CONFIG_HW_RANDOM=y
++CONFIG_HW_RANDOM_VIRTIO=y
++CONFIG_HW_RANDOM_JH7110=y
++CONFIG_I2C_CHARDEV=y
++CONFIG_I2C_DESIGNWARE_PLATFORM=y
++CONFIG_SPI=y
++CONFIG_SPI_CADENCE_QUADSPI=y
++CONFIG_SPI_PL022=y
++CONFIG_SPI_SIFIVE=y
++CONFIG_SPI_SPIDEV=y
++# CONFIG_PTP_1588_CLOCK is not set
++CONFIG_GPIO_SYSFS=y
++CONFIG_GPIO_SIFIVE=y
++CONFIG_SENSORS_SFCTEMP=y
++CONFIG_THERMAL=y
++CONFIG_THERMAL_WRITABLE_TRIPS=y
++CONFIG_CPU_THERMAL=y
++CONFIG_THERMAL_EMULATION=y
++CONFIG_WATCHDOG=y
++CONFIG_WATCHDOG_SYSFS=y
++CONFIG_MFD_AXP20X_I2C=y
++CONFIG_REGULATOR=y
++CONFIG_REGULATOR_AXP20X=y
++CONFIG_REGULATOR_STARFIVE_JH7110=y
++# CONFIG_MEDIA_CEC_SUPPORT is not set
++CONFIG_MEDIA_SUPPORT=y
++CONFIG_MEDIA_USB_SUPPORT=y
++CONFIG_USB_VIDEO_CLASS=y
++CONFIG_V4L_PLATFORM_DRIVERS=y
++CONFIG_V4L_MEM2MEM_DRIVERS=y
++CONFIG_VIDEO_WAVE_VPU=m
++CONFIG_VIN_SENSOR_SC2235=y
++CONFIG_VIN_SENSOR_OV4689=y
++CONFIG_VIN_SENSOR_IMX219=y
++CONFIG_VIDEO_STF_VIN=y
++CONFIG_VIDEO_IMX708=y
++CONFIG_DRM_I2C_NXP_TDA998X=y
++CONFIG_DRM_I2C_NXP_TDA9950=y
++CONFIG_DRM_RADEON=m
++CONFIG_DRM_VIRTIO_GPU=m
++CONFIG_DRM_VERISILICON=y
++CONFIG_STARFIVE_INNO_HDMI=y
++CONFIG_STARFIVE_DSI=y
++CONFIG_DRM_IMG_ROGUE=y
++CONFIG_DRM_LEGACY=y
++CONFIG_FB=y
++CONFIG_SOUND=y
++CONFIG_SND=y
++CONFIG_SND_USB_AUDIO=y
++CONFIG_SND_SOC=y
++CONFIG_SND_DESIGNWARE_I2S=y
++# CONFIG_SND_SOC_INTEL_SST_TOPLEVEL is not set
++CONFIG_SND_SOC_STARFIVE=y
++CONFIG_SND_SOC_JH7110_PDM=y
++CONFIG_SND_SOC_JH7110_PWMDAC=y
++CONFIG_SND_SOC_JH7110_SPDIF=y
++CONFIG_SND_SOC_JH7110_TDM=y
++CONFIG_SND_SOC_AC108=y
++CONFIG_SND_SOC_WM8960=y
++CONFIG_SND_SIMPLE_CARD=y
++CONFIG_USB=y
++CONFIG_USB_XHCI_HCD=y
++CONFIG_USB_EHCI_HCD=y
++CONFIG_USB_EHCI_HCD_PLATFORM=y
++CONFIG_USB_OHCI_HCD=y
++CONFIG_USB_OHCI_HCD_PLATFORM=y
++CONFIG_USB_STORAGE=y
++CONFIG_USB_UAS=y
++CONFIG_USB_CDNS_SUPPORT=y
++CONFIG_USB_CDNS3=y
++CONFIG_USB_CDNS3_GADGET=y
++CONFIG_USB_CDNS3_HOST=y
++CONFIG_USB_CDNS3_STARFIVE=y
++CONFIG_USB_GADGET=y
++CONFIG_USB_CONFIGFS=y
++CONFIG_USB_CONFIGFS_MASS_STORAGE=y
++CONFIG_USB_CONFIGFS_F_FS=y
++CONFIG_MMC=y
++CONFIG_MMC_SDHCI=y
++CONFIG_MMC_SDHCI_PLTFM=y
++CONFIG_MMC_SDHCI_CADENCE=y
++CONFIG_MMC_SPI=y
++CONFIG_MMC_DW=y
++CONFIG_MMC_DW_STARFIVE=y
++CONFIG_RTC_CLASS=y
++# CONFIG_RTC_DRV_SPEAR is not set
++CONFIG_RTC_DRV_STARFIVE=y
++CONFIG_DMADEVICES=y
++CONFIG_AMBA_PL08X=y
++CONFIG_DW_AXI_DMAC=y
++# CONFIG_SH_DMAE_BASE is not set
++# CONFIG_TI_EDMA is not set
++# CONFIG_DMA_OMAP is not set
++CONFIG_DMATEST=y
++CONFIG_VIRTIO_PCI=y
++CONFIG_VIRTIO_BALLOON=y
++CONFIG_VIRTIO_INPUT=y
++CONFIG_VIRTIO_MMIO=y
++CONFIG_STAGING=y
++CONFIG_STAGING_MEDIA=y
++CONFIG_CLK_STARFIVE_JH7110_AON=y
++CONFIG_CLK_STARFIVE_JH7110_STG=y
++CONFIG_CLK_STARFIVE_JH7110_ISP=y
++CONFIG_CLK_STARFIVE_JH7110_VOUT=y
++CONFIG_MAILBOX=y
++CONFIG_STARFIVE_MBOX=m
++CONFIG_STARFIVE_MBOX_TEST=m
++CONFIG_RPMSG_CHAR=y
++CONFIG_RPMSG_CTRL=y
++CONFIG_RPMSG_VIRTIO=y
++CONFIG_SIFIVE_CCACHE=y
++CONFIG_PWM=y
++CONFIG_PWM_OCORES=y
++CONFIG_PHY_STARFIVE_JH7110_PCIE=y
++CONFIG_PHY_STARFIVE_JH7110_USB=y
++CONFIG_PHY_M31_DPHY_RX0=y
++CONFIG_EXT4_FS=y
++CONFIG_EXT4_FS_POSIX_ACL=y
++CONFIG_EXT4_FS_SECURITY=y
++CONFIG_BTRFS_FS=m
++CONFIG_BTRFS_FS_POSIX_ACL=y
++CONFIG_AUTOFS_FS=y
++CONFIG_FUSE_FS=y
++CONFIG_OVERLAY_FS=y
++CONFIG_OVERLAY_FS_INDEX=y
++CONFIG_OVERLAY_FS_XINO_AUTO=y
++CONFIG_OVERLAY_FS_METACOPY=y
++CONFIG_ISO9660_FS=y
++CONFIG_JOLIET=y
++CONFIG_ZISOFS=y
++CONFIG_MSDOS_FS=y
++CONFIG_VFAT_FS=y
++CONFIG_EXFAT_FS=y
++CONFIG_TMPFS=y
++CONFIG_TMPFS_POSIX_ACL=y
++CONFIG_HUGETLBFS=y
++CONFIG_JFFS2_FS=y
++CONFIG_NFS_FS=y
++CONFIG_NFS_V4=y
++CONFIG_NFS_V4_1=y
++CONFIG_NFS_V4_2=y
++CONFIG_ROOT_NFS=y
++CONFIG_9P_FS=y
++CONFIG_NLS_CODEPAGE_437=y
++CONFIG_NLS_ISO8859_1=m
++CONFIG_SECURITY=y
++CONFIG_SECURITY_SELINUX=y
++CONFIG_SECURITY_APPARMOR=y
++CONFIG_DEFAULT_SECURITY_DAC=y
++CONFIG_LSM=""
++CONFIG_INIT_STACK_NONE=y
++CONFIG_CRYPTO_USER=y
++CONFIG_CRYPTO_ZSTD=y
++CONFIG_CRYPTO_USER_API_HASH=y
++CONFIG_CRYPTO_USER_API_SKCIPHER=y
++CONFIG_CRYPTO_USER_API_AEAD=y
++CONFIG_CRYPTO_STATS=y
++CONFIG_CRYPTO_DEV_VIRTIO=y
++CONFIG_CRYPTO_DEV_JH7110=y
++CONFIG_DMA_CMA=y
++CONFIG_PRINTK_TIME=y
++CONFIG_DEBUG_FS=y
++CONFIG_DEBUG_PAGEALLOC=y
++CONFIG_SCHED_STACK_END_CHECK=y
++CONFIG_DEBUG_VM=y
++CONFIG_DEBUG_VM_PGFLAGS=y
++CONFIG_DEBUG_MEMORY_INIT=y
++CONFIG_DEBUG_PER_CPU_MAPS=y
++CONFIG_SOFTLOCKUP_DETECTOR=y
++CONFIG_WQ_WATCHDOG=y
++CONFIG_DEBUG_TIMEKEEPING=y
++CONFIG_DEBUG_RT_MUTEXES=y
++CONFIG_DEBUG_SPINLOCK=y
++CONFIG_DEBUG_MUTEXES=y
++CONFIG_DEBUG_RWSEMS=y
++CONFIG_DEBUG_LIST=y
++CONFIG_DEBUG_PLIST=y
++CONFIG_DEBUG_SG=y
++CONFIG_RCU_CPU_STALL_TIMEOUT=60
++# CONFIG_RCU_TRACE is not set
++CONFIG_RCU_EQS_DEBUG=y
++# CONFIG_FTRACE is not set
++# CONFIG_RUNTIME_TESTING_MENU is not set
++CONFIG_MEMTEST=y
diff --git a/target/linux/starfive/patches-6.6/0060-of-configfs-Add-configfs-function.patch b/target/linux/starfive/patches-6.6/0060-of-configfs-Add-configfs-function.patch
new file mode 100644
index 0000000000..68deb70c9b
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0060-of-configfs-Add-configfs-function.patch
@@ -0,0 +1,318 @@
+From 95c702022f5e4cb786719fcf90170334b1e562cc Mon Sep 17 00:00:00 2001
+From: Jianlong Huang <jianlong.huang@starfivetech.com>
+Date: Thu, 16 Jun 2022 17:13:57 +0800
+Subject: [PATCH 060/116] of: configfs: Add configfs function
+
+Signed-off-by: Jianlong Huang <jianlong.huang@starfivetech.com>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ drivers/of/Kconfig | 7 ++
+ drivers/of/Makefile | 1 +
+ drivers/of/configfs.c | 277 ++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 285 insertions(+)
+ create mode 100644 drivers/of/configfs.c
+
+--- a/drivers/of/Kconfig
++++ b/drivers/of/Kconfig
+@@ -102,4 +102,11 @@ config OF_OVERLAY
+ config OF_NUMA
+ bool
+
++config OF_CONFIGFS
++ bool "Device Tree Overlay ConfigFS interface"
++ select CONFIGFS_FS
++ select OF_OVERLAY
++ help
++ Enable a simple user-space driven DT overlay interface.
++
+ endif # OF
+--- a/drivers/of/Makefile
++++ b/drivers/of/Makefile
+@@ -11,6 +11,7 @@ obj-$(CONFIG_OF_UNITTEST) += unittest.o
+ obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o
+ obj-$(CONFIG_OF_RESOLVE) += resolver.o
+ obj-$(CONFIG_OF_OVERLAY) += overlay.o
++obj-$(CONFIG_OF_CONFIGFS) += configfs.o
+ obj-$(CONFIG_OF_NUMA) += of_numa.o
+
+ ifdef CONFIG_KEXEC_FILE
+--- /dev/null
++++ b/drivers/of/configfs.c
+@@ -0,0 +1,277 @@
++/*
++ * Configfs entries for device-tree
++ *
++ * Copyright (C) 2013 - Pantelis Antoniou <panto@antoniou-consulting.com>
++ *
++ * 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 <linux/ctype.h>
++#include <linux/cpu.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/of_fdt.h>
++#include <linux/spinlock.h>
++#include <linux/slab.h>
++#include <linux/proc_fs.h>
++#include <linux/configfs.h>
++#include <linux/types.h>
++#include <linux/stat.h>
++#include <linux/limits.h>
++#include <linux/file.h>
++#include <linux/vmalloc.h>
++#include <linux/firmware.h>
++#include <linux/sizes.h>
++
++#include "of_private.h"
++
++struct cfs_overlay_item {
++ struct config_item item;
++
++ char path[PATH_MAX];
++
++ const struct firmware *fw;
++ struct device_node *overlay;
++ int ov_id;
++
++ void *dtbo;
++ int dtbo_size;
++};
++
++static inline struct cfs_overlay_item *to_cfs_overlay_item(
++ struct config_item *item)
++{
++ return item ? container_of(item, struct cfs_overlay_item, item) : NULL;
++}
++
++static ssize_t cfs_overlay_item_path_show(struct config_item *item,
++ char *page)
++{
++ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item);
++ return sprintf(page, "%s\n", overlay->path);
++}
++
++static ssize_t cfs_overlay_item_path_store(struct config_item *item,
++ const char *page, size_t count)
++{
++ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item);
++ const char *p = page;
++ char *s;
++ int err;
++
++ /* if it's set do not allow changes */
++ if (overlay->path[0] != '\0' || overlay->dtbo_size > 0)
++ return -EPERM;
++
++ /* copy to path buffer (and make sure it's always zero terminated */
++ count = snprintf(overlay->path, sizeof(overlay->path) - 1, "%s", p);
++ overlay->path[sizeof(overlay->path) - 1] = '\0';
++
++ /* strip trailing newlines */
++ s = overlay->path + strlen(overlay->path);
++ while (s > overlay->path && *--s == '\n')
++ *s = '\0';
++
++ pr_debug("%s: path is '%s'\n", __func__, overlay->path);
++
++ err = request_firmware(&overlay->fw, overlay->path, NULL);
++ if (err != 0)
++ return err;
++
++ err = of_overlay_fdt_apply((void *)overlay->fw->data,
++ (u32)overlay->fw->size, &overlay->ov_id, NULL);
++ if (err != 0)
++ goto out_err;
++
++ return count;
++
++out_err:
++
++ release_firmware(overlay->fw);
++ overlay->fw = NULL;
++
++ overlay->path[0] = '\0';
++ return err;
++}
++
++static ssize_t cfs_overlay_item_status_show(struct config_item *item,
++ char *page)
++{
++ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item);
++
++ return sprintf(page, "%s\n",
++ overlay->ov_id > 0 ? "applied" : "unapplied");
++}
++
++CONFIGFS_ATTR(cfs_overlay_item_, path);
++CONFIGFS_ATTR_RO(cfs_overlay_item_, status);
++
++static struct configfs_attribute *cfs_overlay_attrs[] = {
++ &cfs_overlay_item_attr_path,
++ &cfs_overlay_item_attr_status,
++ NULL,
++};
++
++ssize_t cfs_overlay_item_dtbo_read(struct config_item *item,
++ void *buf, size_t max_count)
++{
++ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item);
++
++ pr_debug("%s: buf=%p max_count=%zu\n", __func__,
++ buf, max_count);
++
++ if (overlay->dtbo == NULL)
++ return 0;
++
++ /* copy if buffer provided */
++ if (buf != NULL) {
++ /* the buffer must be large enough */
++ if (overlay->dtbo_size > max_count)
++ return -ENOSPC;
++
++ memcpy(buf, overlay->dtbo, overlay->dtbo_size);
++ }
++
++ return overlay->dtbo_size;
++}
++
++ssize_t cfs_overlay_item_dtbo_write(struct config_item *item,
++ const void *buf, size_t count)
++{
++ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item);
++ int err;
++
++ /* if it's set do not allow changes */
++ if (overlay->path[0] != '\0' || overlay->dtbo_size > 0)
++ return -EPERM;
++
++ /* copy the contents */
++ overlay->dtbo = kmemdup(buf, count, GFP_KERNEL);
++ if (overlay->dtbo == NULL)
++ return -ENOMEM;
++
++ overlay->dtbo_size = count;
++
++ err = of_overlay_fdt_apply(overlay->dtbo, overlay->dtbo_size,
++ &overlay->ov_id, NULL);
++ if (err != 0)
++ goto out_err;
++
++ return count;
++
++out_err:
++ kfree(overlay->dtbo);
++ overlay->dtbo = NULL;
++ overlay->dtbo_size = 0;
++ overlay->ov_id = 0;
++
++ return err;
++}
++
++CONFIGFS_BIN_ATTR(cfs_overlay_item_, dtbo, NULL, SZ_1M);
++
++static struct configfs_bin_attribute *cfs_overlay_bin_attrs[] = {
++ &cfs_overlay_item_attr_dtbo,
++ NULL,
++};
++
++static void cfs_overlay_release(struct config_item *item)
++{
++ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item);
++
++ if (overlay->ov_id > 0)
++ of_overlay_remove(&overlay->ov_id);
++ if (overlay->fw)
++ release_firmware(overlay->fw);
++ /* kfree with NULL is safe */
++ kfree(overlay->dtbo);
++ kfree(overlay);
++}
++
++static struct configfs_item_operations cfs_overlay_item_ops = {
++ .release = cfs_overlay_release,
++};
++
++static struct config_item_type cfs_overlay_type = {
++ .ct_item_ops = &cfs_overlay_item_ops,
++ .ct_attrs = cfs_overlay_attrs,
++ .ct_bin_attrs = cfs_overlay_bin_attrs,
++ .ct_owner = THIS_MODULE,
++};
++
++static struct config_item *cfs_overlay_group_make_item(
++ struct config_group *group, const char *name)
++{
++ struct cfs_overlay_item *overlay;
++
++ overlay = kzalloc(sizeof(*overlay), GFP_KERNEL);
++ if (!overlay)
++ return ERR_PTR(-ENOMEM);
++
++ config_item_init_type_name(&overlay->item, name, &cfs_overlay_type);
++ return &overlay->item;
++}
++
++static void cfs_overlay_group_drop_item(struct config_group *group,
++ struct config_item *item)
++{
++ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item);
++
++ config_item_put(&overlay->item);
++}
++
++static struct configfs_group_operations overlays_ops = {
++ .make_item = cfs_overlay_group_make_item,
++ .drop_item = cfs_overlay_group_drop_item,
++};
++
++static struct config_item_type overlays_type = {
++ .ct_group_ops = &overlays_ops,
++ .ct_owner = THIS_MODULE,
++};
++
++static struct configfs_group_operations of_cfs_ops = {
++ /* empty - we don't allow anything to be created */
++};
++
++static struct config_item_type of_cfs_type = {
++ .ct_group_ops = &of_cfs_ops,
++ .ct_owner = THIS_MODULE,
++};
++
++struct config_group of_cfs_overlay_group;
++
++static struct configfs_subsystem of_cfs_subsys = {
++ .su_group = {
++ .cg_item = {
++ .ci_namebuf = "device-tree",
++ .ci_type = &of_cfs_type,
++ },
++ },
++ .su_mutex = __MUTEX_INITIALIZER(of_cfs_subsys.su_mutex),
++};
++
++static int __init of_cfs_init(void)
++{
++ int ret;
++
++ pr_info("%s\n", __func__);
++
++ config_group_init(&of_cfs_subsys.su_group);
++ config_group_init_type_name(&of_cfs_overlay_group, "overlays",
++ &overlays_type);
++ configfs_add_default_group(&of_cfs_overlay_group,
++ &of_cfs_subsys.su_group);
++
++ ret = configfs_register_subsystem(&of_cfs_subsys);
++ if (ret != 0) {
++ pr_err("%s: failed to register subsys\n", __func__);
++ goto out;
++ }
++ pr_info("%s: OK\n", __func__);
++out:
++ return ret;
++}
++late_initcall(of_cfs_init);
diff --git a/target/linux/starfive/patches-6.6/0061-usr-Add-gen_initramfs_list.sh.patch b/target/linux/starfive/patches-6.6/0061-usr-Add-gen_initramfs_list.sh.patch
new file mode 100644
index 0000000000..ade0f467a0
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0061-usr-Add-gen_initramfs_list.sh.patch
@@ -0,0 +1,344 @@
+From 7891826f8c2de9ee0f6459cf969f7b082e29b154 Mon Sep 17 00:00:00 2001
+From: Hal Feng <hal.feng@starfivetech.com>
+Date: Thu, 1 Jun 2023 23:10:09 -0700
+Subject: [PATCH 061/116] usr: Add gen_initramfs_list.sh
+
+Add gen_initramfs_list.sh
+
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ usr/gen_initramfs_list.sh | 328 ++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 328 insertions(+)
+ create mode 100644 usr/gen_initramfs_list.sh
+
+--- /dev/null
++++ b/usr/gen_initramfs_list.sh
+@@ -0,0 +1,328 @@
++#!/bin/sh
++# Copyright (C) Martin Schlemmer <azarah@nosferatu.za.org>
++# Copyright (C) 2006 Sam Ravnborg <sam@ravnborg.org>
++#
++# Released under the terms of the GNU GPL
++#
++# Generate a cpio packed initramfs. It uses gen_init_cpio to generate
++# the cpio archive, and then compresses it.
++# The script may also be used to generate the inputfile used for gen_init_cpio
++# This script assumes that gen_init_cpio is located in usr/ directory
++
++# error out on errors
++set -e
++
++usage() {
++cat << EOF
++Usage:
++$0 [-o <file>] [-u <uid>] [-g <gid>] {-d | <cpio_source>} ...
++ -o <file> Create compressed initramfs file named <file> using
++ gen_init_cpio and compressor depending on the extension
++ -u <uid> User ID to map to user ID 0 (root).
++ <uid> is only meaningful if <cpio_source> is a
++ directory. "squash" forces all files to uid 0.
++ -g <gid> Group ID to map to group ID 0 (root).
++ <gid> is only meaningful if <cpio_source> is a
++ directory. "squash" forces all files to gid 0.
++ <cpio_source> File list or directory for cpio archive.
++ If <cpio_source> is a .cpio file it will be used
++ as direct input to initramfs.
++ -d Output the default cpio list.
++
++All options except -o and -l may be repeated and are interpreted
++sequentially and immediately. -u and -g states are preserved across
++<cpio_source> options so an explicit "-u 0 -g 0" is required
++to reset the root/group mapping.
++EOF
++}
++
++# awk style field access
++# $1 - field number; rest is argument string
++field() {
++ shift $1 ; echo $1
++}
++
++list_default_initramfs() {
++ # echo usr/kinit/kinit
++ :
++}
++
++default_initramfs() {
++ cat <<-EOF >> ${output}
++ # This is a very simple, default initramfs
++
++ dir /dev 0755 0 0
++ nod /dev/console 0600 0 0 c 5 1
++ dir /root 0700 0 0
++ # file /kinit usr/kinit/kinit 0755 0 0
++ # slink /init kinit 0755 0 0
++ EOF
++}
++
++filetype() {
++ local argv1="$1"
++
++ # symlink test must come before file test
++ if [ -L "${argv1}" ]; then
++ echo "slink"
++ elif [ -f "${argv1}" ]; then
++ echo "file"
++ elif [ -d "${argv1}" ]; then
++ echo "dir"
++ elif [ -b "${argv1}" -o -c "${argv1}" ]; then
++ echo "nod"
++ elif [ -p "${argv1}" ]; then
++ echo "pipe"
++ elif [ -S "${argv1}" ]; then
++ echo "sock"
++ else
++ echo "invalid"
++ fi
++ return 0
++}
++
++list_print_mtime() {
++ :
++}
++
++print_mtime() {
++ local my_mtime="0"
++
++ if [ -e "$1" ]; then
++ my_mtime=$(find "$1" -printf "%T@\n" | sort -r | head -n 1)
++ fi
++
++ echo "# Last modified: ${my_mtime}" >> ${output}
++ echo "" >> ${output}
++}
++
++list_parse() {
++ if [ -L "$1" ]; then
++ return
++ fi
++ echo "$1" | sed 's/:/\\:/g; s/$/ \\/'
++}
++
++# for each file print a line in following format
++# <filetype> <name> <path to file> <octal mode> <uid> <gid>
++# for links, devices etc the format differs. See gen_init_cpio for details
++parse() {
++ local location="$1"
++ local name="/${location#${srcdir}}"
++ # change '//' into '/'
++ name=$(echo "$name" | sed -e 's://*:/:g')
++ local mode="$2"
++ local uid="$3"
++ local gid="$4"
++ local ftype=$(filetype "${location}")
++ # remap uid/gid to 0 if necessary
++ [ "$root_uid" = "squash" ] && uid=0 || [ "$uid" -eq "$root_uid" ] && uid=0
++ [ "$root_gid" = "squash" ] && gid=0 || [ "$gid" -eq "$root_gid" ] && gid=0
++ local str="${mode} ${uid} ${gid}"
++
++ [ "${ftype}" = "invalid" ] && return 0
++ [ "${location}" = "${srcdir}" ] && return 0
++
++ case "${ftype}" in
++ "file")
++ str="${ftype} ${name} ${location} ${str}"
++ ;;
++ "nod")
++ local dev=`LC_ALL=C ls -l "${location}"`
++ local maj=`field 5 ${dev}`
++ local min=`field 6 ${dev}`
++ maj=${maj%,}
++
++ [ -b "${location}" ] && dev="b" || dev="c"
++
++ str="${ftype} ${name} ${str} ${dev} ${maj} ${min}"
++ ;;
++ "slink")
++ local target=`readlink "${location}"`
++ str="${ftype} ${name} ${target} ${str}"
++ ;;
++ *)
++ str="${ftype} ${name} ${str}"
++ ;;
++ esac
++
++ echo "${str}" >> ${output}
++
++ return 0
++}
++
++unknown_option() {
++ printf "ERROR: unknown option \"$arg\"\n" >&2
++ printf "If the filename validly begins with '-', " >&2
++ printf "then it must be prefixed\n" >&2
++ printf "by './' so that it won't be interpreted as an option." >&2
++ printf "\n" >&2
++ usage >&2
++ exit 1
++}
++
++list_header() {
++ :
++}
++
++header() {
++ printf "\n#####################\n# $1\n" >> ${output}
++}
++
++# process one directory (incl sub-directories)
++dir_filelist() {
++ ${dep_list}header "$1"
++
++ srcdir=$(echo "$1" | sed -e 's://*:/:g')
++ dirlist=$(find "${srcdir}" -printf "%p %m %U %G\n" | LANG=C sort)
++
++ # If $dirlist is only one line, then the directory is empty
++ if [ "$(echo "${dirlist}" | wc -l)" -gt 1 ]; then
++ ${dep_list}print_mtime "$1"
++
++ echo "${dirlist}" | \
++ while read x; do
++ ${dep_list}parse ${x}
++ done
++ fi
++}
++
++# if only one file is specified and it is .cpio file then use it direct as fs
++# if a directory is specified then add all files in given direcotry to fs
++# if a regular file is specified assume it is in gen_initramfs format
++input_file() {
++ source="$1"
++ if [ -f "$1" ]; then
++ ${dep_list}header "$1"
++ is_cpio="$(echo "$1" | sed 's/^.*\.cpio\(\..*\)\{0,1\}/cpio/')"
++ if [ $2 -eq 0 -a ${is_cpio} = "cpio" ]; then
++ cpio_file=$1
++ echo "$1" | grep -q '^.*\.cpio\..*' && is_cpio_compressed="compressed"
++ [ ! -z ${dep_list} ] && echo "$1"
++ return 0
++ fi
++ if [ -z ${dep_list} ]; then
++ print_mtime "$1" >> ${output}
++ cat "$1" >> ${output}
++ else
++ echo "$1 \\"
++ cat "$1" | while read type dir file perm ; do
++ if [ "$type" = "file" ]; then
++ echo "$file \\";
++ fi
++ done
++ fi
++ elif [ -d "$1" ]; then
++ dir_filelist "$1"
++ else
++ echo " ${prog}: Cannot open '$1'" >&2
++ exit 1
++ fi
++}
++
++prog=$0
++root_uid=0
++root_gid=0
++dep_list=
++cpio_file=
++cpio_list=
++output="/dev/stdout"
++output_file=""
++is_cpio_compressed=
++compr="gzip -n -9 -f"
++
++arg="$1"
++case "$arg" in
++ "-l") # files included in initramfs - used by kbuild
++ dep_list="list_"
++ echo "deps_initramfs := $0 \\"
++ shift
++ ;;
++ "-o") # generate compressed cpio image named $1
++ shift
++ output_file="$1"
++ cpio_list="$(mktemp ${TMPDIR:-/tmp}/cpiolist.XXXXXX)"
++ output=${cpio_list}
++ echo "$output_file" | grep -q "\.gz$" \
++ && [ -x "`which gzip 2> /dev/null`" ] \
++ && compr="gzip -n -9 -f"
++ echo "$output_file" | grep -q "\.bz2$" \
++ && [ -x "`which bzip2 2> /dev/null`" ] \
++ && compr="bzip2 -9 -f"
++ echo "$output_file" | grep -q "\.lzma$" \
++ && [ -x "`which lzma 2> /dev/null`" ] \
++ && compr="lzma -9 -f"
++ echo "$output_file" | grep -q "\.xz$" \
++ && [ -x "`which xz 2> /dev/null`" ] \
++ && compr="xz --check=crc32 --lzma2=dict=1MiB"
++ echo "$output_file" | grep -q "\.lzo$" \
++ && [ -x "`which lzop 2> /dev/null`" ] \
++ && compr="lzop -9 -f"
++ echo "$output_file" | grep -q "\.lz4$" \
++ && [ -x "`which lz4 2> /dev/null`" ] \
++ && compr="lz4 -l -9 -f"
++ echo "$output_file" | grep -q "\.cpio$" && compr="cat"
++ shift
++ ;;
++esac
++while [ $# -gt 0 ]; do
++ arg="$1"
++ shift
++ case "$arg" in
++ "-u") # map $1 to uid=0 (root)
++ root_uid="$1"
++ [ "$root_uid" = "-1" ] && root_uid=$(id -u || echo 0)
++ shift
++ ;;
++ "-g") # map $1 to gid=0 (root)
++ root_gid="$1"
++ [ "$root_gid" = "-1" ] && root_gid=$(id -g || echo 0)
++ shift
++ ;;
++ "-d") # display default initramfs list
++ default_list="$arg"
++ ${dep_list}default_initramfs
++ ;;
++ "-h")
++ usage
++ exit 0
++ ;;
++ *)
++ case "$arg" in
++ "-"*)
++ unknown_option
++ ;;
++ *) # input file/dir - process it
++ input_file "$arg" "$#"
++ ;;
++ esac
++ ;;
++ esac
++done
++
++# If output_file is set we will generate cpio archive and compress it
++# we are careful to delete tmp files
++if [ ! -z ${output_file} ]; then
++ if [ -z ${cpio_file} ]; then
++ timestamp=
++ if test -n "$KBUILD_BUILD_TIMESTAMP"; then
++ timestamp="$(date -d"$KBUILD_BUILD_TIMESTAMP" +%s || :)"
++ if test -n "$timestamp"; then
++ timestamp="-t $timestamp"
++ fi
++ fi
++ cpio_tfile="$(mktemp ${TMPDIR:-/tmp}/cpiofile.XXXXXX)"
++ usr/gen_init_cpio $timestamp ${cpio_list} > ${cpio_tfile}
++ else
++ cpio_tfile=${cpio_file}
++ fi
++ rm ${cpio_list}
++ if [ "${is_cpio_compressed}" = "compressed" ]; then
++ cat ${cpio_tfile} > ${output_file}
++ else
++ (cat ${cpio_tfile} | ${compr} - > ${output_file}) \
++ || (rm -f ${output_file} ; false)
++ fi
++ [ -z ${cpio_file} ] && rm ${cpio_tfile}
++fi
++exit 0
diff --git a/target/linux/starfive/patches-6.6/0062-i2c-designware-Delete-SMBus-functionalities.patch b/target/linux/starfive/patches-6.6/0062-i2c-designware-Delete-SMBus-functionalities.patch
new file mode 100644
index 0000000000..05561f1c51
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0062-i2c-designware-Delete-SMBus-functionalities.patch
@@ -0,0 +1,33 @@
+From dcc2827ed6e701a65731c05b0297745559837217 Mon Sep 17 00:00:00 2001
+From: Hal Feng <hal.feng@starfivetech.com>
+Date: Fri, 12 May 2023 17:33:20 +0800
+Subject: [PATCH 062/116] i2c: designware: Delete SMBus functionalities
+
+The driver didn't implement the smbus interface,
+so replace the SMBus functionalities with
+I2C_FUNC_SMBUS_EMUL.
+
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ drivers/i2c/busses/i2c-designware-core.h | 10 ++++------
+ 1 file changed, 4 insertions(+), 6 deletions(-)
+
+--- a/drivers/i2c/busses/i2c-designware-core.h
++++ b/drivers/i2c/busses/i2c-designware-core.h
+@@ -18,12 +18,10 @@
+ #include <linux/regmap.h>
+ #include <linux/types.h>
+
+-#define DW_IC_DEFAULT_FUNCTIONALITY (I2C_FUNC_I2C | \
+- I2C_FUNC_SMBUS_BYTE | \
+- I2C_FUNC_SMBUS_BYTE_DATA | \
+- I2C_FUNC_SMBUS_WORD_DATA | \
+- I2C_FUNC_SMBUS_BLOCK_DATA | \
+- I2C_FUNC_SMBUS_I2C_BLOCK)
++#define DW_IC_DEFAULT_FUNCTIONALITY (I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL \
++ & ~I2C_FUNC_SMBUS_QUICK \
++ & ~I2C_FUNC_SMBUS_PROC_CALL \
++ & ~I2C_FUNC_SMBUS_PEC))
+
+ #define DW_IC_CON_MASTER BIT(0)
+ #define DW_IC_CON_SPEED_STD (1 << 1)
diff --git a/target/linux/starfive/patches-6.6/0063-drivers-mtd-gigadevice-add-gd25lq256d-32M-flash-supp.patch b/target/linux/starfive/patches-6.6/0063-drivers-mtd-gigadevice-add-gd25lq256d-32M-flash-supp.patch
new file mode 100644
index 0000000000..43a7e5ba0d
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0063-drivers-mtd-gigadevice-add-gd25lq256d-32M-flash-supp.patch
@@ -0,0 +1,26 @@
+From b61cefc6c785aa8a7177a0b535db746fd0047bd8 Mon Sep 17 00:00:00 2001
+From: Ziv Xu <ziv.xu@starfivetech.com>
+Date: Fri, 19 Jan 2024 15:22:55 +0800
+Subject: [PATCH 063/116] drivers: mtd: gigadevice: add gd25lq256d 32M flash
+ support
+
+add gd25lq256d 32M flash support
+
+Signed-off-by: Ziv Xu <ziv.xu@starfivetech.com>
+---
+ drivers/mtd/spi-nor/gigadevice.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/mtd/spi-nor/gigadevice.c
++++ b/drivers/mtd/spi-nor/gigadevice.c
+@@ -66,6 +66,10 @@ static const struct flash_info gigadevic
+ FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
+ NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
+ SPI_NOR_QUAD_READ) },
++ { "gd25lq256d", INFO(0xc86019, 0, 64 * 1024, 512)
++ FLAGS( SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_QUAD_PP)
++ NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
++ SPI_NOR_QUAD_READ) },
+ { "gd25q256", INFO(0xc84019, 0, 64 * 1024, 512)
+ PARSE_SFDP
+ FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_TB_SR_BIT6)
diff --git a/target/linux/starfive/patches-6.6/0064-driver-mailbox-Add-mailbox-driver.patch b/target/linux/starfive/patches-6.6/0064-driver-mailbox-Add-mailbox-driver.patch
new file mode 100644
index 0000000000..b733110f7d
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0064-driver-mailbox-Add-mailbox-driver.patch
@@ -0,0 +1,808 @@
+From 76bc13aa12bd111f5da01e107f8d487b20b5a40c Mon Sep 17 00:00:00 2001
+From: "shanlong.li" <shanlong.li@starfivetech.com>
+Date: Thu, 8 Jun 2023 00:07:15 -0700
+Subject: [PATCH 064/116] driver: mailbox: Add mailbox driver
+
+Add mailbox driver.
+
+Signed-off-by: shanlong.li <shanlong.li@starfivetech.com>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ drivers/mailbox/Kconfig | 13 +
+ drivers/mailbox/Makefile | 4 +
+ drivers/mailbox/starfive_mailbox-test.c | 407 ++++++++++++++++++++++++
+ drivers/mailbox/starfive_mailbox.c | 347 ++++++++++++++++++++
+ 4 files changed, 771 insertions(+)
+ create mode 100644 drivers/mailbox/starfive_mailbox-test.c
+ create mode 100644 drivers/mailbox/starfive_mailbox.c
+
+--- a/drivers/mailbox/Kconfig
++++ b/drivers/mailbox/Kconfig
+@@ -295,4 +295,17 @@ config QCOM_IPCC
+ acts as an interrupt controller for receiving interrupts from clients.
+ Say Y here if you want to build this driver.
+
++config STARFIVE_MBOX
++ tristate "Platform Starfive Mailbox"
++ depends on OF
++ help
++ Say Y here if you want to build a platform specific variant RISCV
++ controller driver.
++
++config STARFIVE_MBOX_TEST
++ tristate "Starfive Mailbox Test Client"
++ depends on OF
++ depends on HAS_IOMEM
++ help
++ Test client to help with testing new Controller driver implementations.
+ endif
+--- a/drivers/mailbox/Makefile
++++ b/drivers/mailbox/Makefile
+@@ -62,3 +62,7 @@ obj-$(CONFIG_SPRD_MBOX) += sprd-mailbox
+ obj-$(CONFIG_QCOM_IPCC) += qcom-ipcc.o
+
+ obj-$(CONFIG_APPLE_MAILBOX) += apple-mailbox.o
++
++obj-$(CONFIG_STARFIVE_MBOX) += starfive_mailbox.o
++
++obj-$(CONFIG_STARFIVE_MBOX_TEST) += starfive_mailbox-test.o
+--- /dev/null
++++ b/drivers/mailbox/starfive_mailbox-test.c
+@@ -0,0 +1,407 @@
++// SPDX-License-Identifier: GPL-2.0-or-later
++/*
++ * Copyright (C) 2015 ST Microelectronics
++ *
++ * Author: Lee Jones <lee.jones@linaro.org>
++ */
++
++#include <linux/debugfs.h>
++#include <linux/err.h>
++#include <linux/fs.h>
++#include <linux/io.h>
++#include <linux/kernel.h>
++#include <linux/mailbox_client.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/platform_device.h>
++#include <linux/poll.h>
++#include <linux/slab.h>
++#include <linux/uaccess.h>
++#include <linux/sched/signal.h>
++
++#include <linux/mailbox_controller.h>
++
++#define MBOX_MAX_SIG_LEN 8
++#define MBOX_MAX_MSG_LEN 16
++#define MBOX_BYTES_PER_LINE 16
++#define MBOX_HEXDUMP_LINE_LEN ((MBOX_BYTES_PER_LINE * 4) + 2)
++#define MBOX_HEXDUMP_MAX_LEN (MBOX_HEXDUMP_LINE_LEN * (MBOX_MAX_MSG_LEN / MBOX_BYTES_PER_LINE))
++
++static bool mbox_data_ready;
++
++struct mbox_test_device {
++ struct device *dev;
++ void __iomem *tx_mmio;
++ void __iomem *rx_mmio;
++ struct mbox_chan *tx_channel;
++ struct mbox_chan *rx_channel;
++ char *rx_buffer;
++ char *signal;
++ char *message;
++ spinlock_t lock;
++ wait_queue_head_t waitq;
++ struct fasync_struct *async_queue;
++ struct dentry *root_debugfs_dir;
++};
++
++static ssize_t mbox_test_signal_write(struct file *filp,
++ const char __user *userbuf,
++ size_t count, loff_t *ppos)
++{
++ struct mbox_test_device *tdev = filp->private_data;
++
++ if (!tdev->tx_channel) {
++ dev_err(tdev->dev, "Channel cannot do Tx\n");
++ return -EINVAL;
++ }
++
++ if (count > MBOX_MAX_SIG_LEN) {
++ dev_err(tdev->dev,
++ "Signal length %zd greater than max allowed %d\n",
++ count, MBOX_MAX_SIG_LEN);
++ return -EINVAL;
++ }
++
++ /* Only allocate memory if we need to */
++ if (!tdev->signal) {
++ tdev->signal = kzalloc(MBOX_MAX_SIG_LEN, GFP_KERNEL);
++ if (!tdev->signal)
++ return -ENOMEM;
++ }
++
++ if (copy_from_user(tdev->signal, userbuf, count)) {
++ kfree(tdev->signal);
++ tdev->signal = NULL;
++ return -EFAULT;
++ }
++
++ return count;
++}
++
++static const struct file_operations mbox_test_signal_ops = {
++ .write = mbox_test_signal_write,
++ .open = simple_open,
++ .llseek = generic_file_llseek,
++};
++
++static int mbox_test_message_fasync(int fd, struct file *filp, int on)
++{
++ struct mbox_test_device *tdev = filp->private_data;
++
++ return fasync_helper(fd, filp, on, &tdev->async_queue);
++}
++
++static ssize_t mbox_test_message_write(struct file *filp,
++ const char __user *userbuf,
++ size_t count, loff_t *ppos)
++{
++ struct mbox_test_device *tdev = filp->private_data;
++ void *data;
++ int ret;
++
++ if (!tdev->tx_channel) {
++ dev_err(tdev->dev, "Channel cannot do Tx\n");
++ return -EINVAL;
++ }
++
++ if (count > MBOX_MAX_MSG_LEN) {
++ dev_err(tdev->dev,
++ "Message length %zd greater than max allowed %d\n",
++ count, MBOX_MAX_MSG_LEN);
++ return -EINVAL;
++ }
++
++ tdev->message = kzalloc(MBOX_MAX_MSG_LEN, GFP_KERNEL);
++ if (!tdev->message)
++ return -ENOMEM;
++
++ ret = copy_from_user(tdev->message, userbuf, count);
++ if (ret) {
++ ret = -EFAULT;
++ goto out;
++ }
++
++ if (tdev->tx_mmio && tdev->signal) {
++ print_hex_dump_bytes("Client: Sending: Signal: ", DUMP_PREFIX_ADDRESS,
++ tdev->signal, MBOX_MAX_SIG_LEN);
++
++ data = tdev->signal;
++ } else
++ data = tdev->message;
++
++ print_hex_dump_bytes("Client: Sending: Message: ", DUMP_PREFIX_ADDRESS,
++ tdev->message, MBOX_MAX_MSG_LEN);
++
++ ret = mbox_send_message(tdev->tx_channel, data);
++ mbox_chan_txdone(tdev->tx_channel, ret);
++ if (ret < 0)
++ dev_err(tdev->dev, "Failed to send message via mailbox\n");
++
++out:
++ kfree(tdev->signal);
++ kfree(tdev->message);
++ tdev->signal = NULL;
++
++ return ret < 0 ? ret : count;
++}
++
++static bool mbox_test_message_data_ready(struct mbox_test_device *tdev)
++{
++ bool data_ready;
++ unsigned long flags;
++
++ spin_lock_irqsave(&tdev->lock, flags);
++ data_ready = mbox_data_ready;
++ spin_unlock_irqrestore(&tdev->lock, flags);
++
++ return data_ready;
++}
++
++static ssize_t mbox_test_message_read(struct file *filp, char __user *userbuf,
++ size_t count, loff_t *ppos)
++{
++ struct mbox_test_device *tdev = filp->private_data;
++ unsigned long flags;
++ char *touser, *ptr;
++ int ret;
++
++ touser = kzalloc(MBOX_HEXDUMP_MAX_LEN + 1, GFP_KERNEL);
++ if (!touser)
++ return -ENOMEM;
++
++ if (!tdev->rx_channel) {
++ ret = snprintf(touser, 20, "<NO RX CAPABILITY>\n");
++ ret = simple_read_from_buffer(userbuf, count, ppos,
++ touser, ret);
++ goto kfree_err;
++ }
++
++ do {
++ if (mbox_test_message_data_ready(tdev))
++ break;
++
++ if (filp->f_flags & O_NONBLOCK) {
++ ret = -EAGAIN;
++ goto waitq_err;
++ }
++
++ if (signal_pending(current)) {
++ ret = -ERESTARTSYS;
++ goto waitq_err;
++ }
++ schedule();
++
++ } while (1);
++
++ spin_lock_irqsave(&tdev->lock, flags);
++
++ ptr = tdev->rx_buffer;
++
++ mbox_data_ready = false;
++
++ spin_unlock_irqrestore(&tdev->lock, flags);
++ if (copy_to_user((void __user *)userbuf, ptr, 4))
++ ret = -EFAULT;
++
++waitq_err:
++ __set_current_state(TASK_RUNNING);
++kfree_err:
++ kfree(touser);
++ return ret;
++}
++
++static __poll_t
++mbox_test_message_poll(struct file *filp, struct poll_table_struct *wait)
++{
++ struct mbox_test_device *tdev = filp->private_data;
++
++ poll_wait(filp, &tdev->waitq, wait);
++
++ if (mbox_test_message_data_ready(tdev))
++ return EPOLLIN | EPOLLRDNORM;
++ return 0;
++}
++
++static const struct file_operations mbox_test_message_ops = {
++ .write = mbox_test_message_write,
++ .read = mbox_test_message_read,
++ .fasync = mbox_test_message_fasync,
++ .poll = mbox_test_message_poll,
++ .open = simple_open,
++ .llseek = generic_file_llseek,
++};
++
++static int mbox_test_add_debugfs(struct platform_device *pdev,
++ struct mbox_test_device *tdev)
++{
++ if (!debugfs_initialized())
++ return 0;
++
++ tdev->root_debugfs_dir = debugfs_create_dir(dev_name(&pdev->dev), NULL);
++ if (!tdev->root_debugfs_dir) {
++ dev_err(&pdev->dev, "Failed to create Mailbox debugfs\n");
++ return -EINVAL;
++ }
++
++ debugfs_create_file("message", 0600, tdev->root_debugfs_dir,
++ tdev, &mbox_test_message_ops);
++
++ debugfs_create_file("signal", 0200, tdev->root_debugfs_dir,
++ tdev, &mbox_test_signal_ops);
++
++ return 0;
++}
++
++static void mbox_test_receive_message(struct mbox_client *client, void *message)
++{
++ struct mbox_test_device *tdev = dev_get_drvdata(client->dev);
++ unsigned long flags;
++
++ spin_lock_irqsave(&tdev->lock, flags);
++ if (tdev->rx_mmio) {
++ memcpy_fromio(tdev->rx_buffer, tdev->rx_mmio, MBOX_MAX_MSG_LEN);
++ print_hex_dump_bytes("Client: Received [MMIO]: ", DUMP_PREFIX_ADDRESS,
++ tdev->rx_buffer, MBOX_MAX_MSG_LEN);
++ } else if (message) {
++ print_hex_dump_bytes("Client: Received [API]: ", DUMP_PREFIX_ADDRESS,
++ message, MBOX_MAX_MSG_LEN);
++ memcpy(tdev->rx_buffer, message, MBOX_MAX_MSG_LEN);
++ }
++ mbox_data_ready = true;
++ spin_unlock_irqrestore(&tdev->lock, flags);
++}
++
++static void mbox_test_prepare_message(struct mbox_client *client, void *message)
++{
++ struct mbox_test_device *tdev = dev_get_drvdata(client->dev);
++
++ if (tdev->tx_mmio) {
++ if (tdev->signal)
++ memcpy_toio(tdev->tx_mmio, tdev->message, MBOX_MAX_MSG_LEN);
++ else
++ memcpy_toio(tdev->tx_mmio, message, MBOX_MAX_MSG_LEN);
++ }
++}
++
++static struct mbox_chan *
++mbox_test_request_channel(struct platform_device *pdev, const char *name)
++{
++ struct mbox_client *client;
++ struct mbox_chan *channel;
++
++ client = devm_kzalloc(&pdev->dev, sizeof(*client), GFP_KERNEL);
++ if (!client)
++ return ERR_PTR(-ENOMEM);
++
++ client->dev = &pdev->dev;
++ client->rx_callback = mbox_test_receive_message;
++ client->tx_prepare = mbox_test_prepare_message;
++ client->tx_block = false;
++ client->knows_txdone = false;
++ client->tx_tout = 500;
++
++ channel = mbox_request_channel_byname(client, name);
++ if (IS_ERR(channel)) {
++ dev_warn(&pdev->dev, "Failed to request %s channel\n", name);
++ return NULL;
++ }
++
++ return channel;
++}
++
++static int mbox_test_probe(struct platform_device *pdev)
++{
++ struct mbox_test_device *tdev;
++ struct resource *res;
++ resource_size_t size;
++ int ret;
++
++ tdev = devm_kzalloc(&pdev->dev, sizeof(*tdev), GFP_KERNEL);
++ if (!tdev)
++ return -ENOMEM;
++
++ /* It's okay for MMIO to be NULL */
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ tdev->tx_mmio = devm_ioremap_resource(&pdev->dev, res);
++ if (PTR_ERR(tdev->tx_mmio) == -EBUSY) {
++ /* if reserved area in SRAM, try just ioremap */
++ size = resource_size(res);
++ tdev->tx_mmio = devm_ioremap(&pdev->dev, res->start, size);
++ } else if (IS_ERR(tdev->tx_mmio)) {
++ tdev->tx_mmio = NULL;
++ }
++
++ /* If specified, second reg entry is Rx MMIO */
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
++ tdev->rx_mmio = devm_ioremap_resource(&pdev->dev, res);
++ if (PTR_ERR(tdev->rx_mmio) == -EBUSY) {
++ size = resource_size(res);
++ tdev->rx_mmio = devm_ioremap(&pdev->dev, res->start, size);
++ } else if (IS_ERR(tdev->rx_mmio)) {
++ tdev->rx_mmio = tdev->tx_mmio;
++ }
++
++ tdev->tx_channel = mbox_test_request_channel(pdev, "tx");
++ tdev->rx_channel = mbox_test_request_channel(pdev, "rx");
++
++ if (!tdev->tx_channel && !tdev->rx_channel)
++ return -EPROBE_DEFER;
++
++ /* If Rx is not specified but has Rx MMIO, then Rx = Tx */
++ if (!tdev->rx_channel && (tdev->rx_mmio != tdev->tx_mmio))
++ tdev->rx_channel = tdev->tx_channel;
++
++ tdev->dev = &pdev->dev;
++ platform_set_drvdata(pdev, tdev);
++
++ spin_lock_init(&tdev->lock);
++
++ if (tdev->rx_channel) {
++ tdev->rx_buffer = devm_kzalloc(&pdev->dev,
++ MBOX_MAX_MSG_LEN, GFP_KERNEL);
++ if (!tdev->rx_buffer)
++ return -ENOMEM;
++ }
++
++ ret = mbox_test_add_debugfs(pdev, tdev);
++ if (ret)
++ return ret;
++
++ dev_info(&pdev->dev, "Successfully registered\n");
++
++ return 0;
++}
++
++static int mbox_test_remove(struct platform_device *pdev)
++{
++ struct mbox_test_device *tdev = platform_get_drvdata(pdev);
++
++ debugfs_remove_recursive(tdev->root_debugfs_dir);
++
++ if (tdev->tx_channel)
++ mbox_free_channel(tdev->tx_channel);
++ if (tdev->rx_channel)
++ mbox_free_channel(tdev->rx_channel);
++
++ return 0;
++}
++
++static const struct of_device_id mbox_test_match[] = {
++ { .compatible = "starfive,mailbox-test" },
++ {},
++};
++MODULE_DEVICE_TABLE(of, mbox_test_match);
++
++static struct platform_driver mbox_test_driver = {
++ .driver = {
++ .name = "mailbox_test",
++ .of_match_table = mbox_test_match,
++ },
++ .probe = mbox_test_probe,
++ .remove = mbox_test_remove,
++};
++module_platform_driver(mbox_test_driver);
++
++MODULE_DESCRIPTION("Generic Mailbox Testing Facility");
++MODULE_AUTHOR("Lee Jones <lee.jones@linaro.org");
++MODULE_LICENSE("GPL v2");
+--- /dev/null
++++ b/drivers/mailbox/starfive_mailbox.c
+@@ -0,0 +1,347 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * mailbox driver for StarFive JH7110 SoC
++ *
++ * Copyright (c) 2021 StarFive Technology Co., Ltd.
++ * Author: Shanlong Li <shanlong.li@starfivetech.com>
++ */
++
++#include <linux/bitops.h>
++#include <linux/delay.h>
++#include <linux/device.h>
++#include <linux/err.h>
++#include <linux/interrupt.h>
++#include <linux/io.h>
++#include <linux/iopoll.h>
++#include <linux/mailbox_controller.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/slab.h>
++#include <linux/clk.h>
++#include <linux/reset.h>
++#include <linux/pm_runtime.h>
++
++#include "mailbox.h"
++
++#define MBOX_CHAN_MAX 4
++
++#define MBOX_BASE(mbox, ch) ((mbox)->base + ((ch) * 0x10))
++#define MBOX_IRQ_REG 0x00
++#define MBOX_SET_REG 0x04
++#define MBOX_CLR_REG 0x08
++#define MBOX_CMD_REG 0x0c
++#define MBC_PEND_SMRY 0x100
++
++typedef enum {
++ MAILBOX_CORE_U7 = 0,
++ MAILBOX_CORE_HIFI4,
++ MAILBOX_CORE_E2,
++ MAILBOX_CORE_RSVD0,
++ MAILBOX_CORE_NUM,
++} mailbox_core_t;
++
++struct mailbox_irq_name_c{
++ int id;
++ char name[16];
++};
++
++static const struct mailbox_irq_name_c irq_peer_name[MBOX_CHAN_MAX] = {
++ {MAILBOX_CORE_U7, "u74_core"},
++ {MAILBOX_CORE_HIFI4, "hifi4_core"},
++ {MAILBOX_CORE_E2, "e24_core"},
++ {MAILBOX_CORE_RSVD0, "" },
++};
++
++/**
++ * starfive mailbox channel information
++ *
++ * A channel can be used for TX or RX, it can trigger remote
++ * processor interrupt to notify remote processor and can receive
++ * interrupt if has incoming message.
++ *
++ * @dst_irq: Interrupt vector for remote processor
++ * @core_id: id for remote processor
++ */
++struct starfive_chan_info {
++ unsigned int dst_irq;
++ mailbox_core_t core_id;
++};
++
++/**
++ * starfive mailbox controller data
++ *
++ * Mailbox controller includes 4 channels and can allocate
++ * channel for message transferring.
++ *
++ * @dev: Device to which it is attached
++ * @base: Base address of the register mapping region
++ * @chan: Representation of channels in mailbox controller
++ * @mchan: Representation of channel info
++ * @controller: Representation of a communication channel controller
++ */
++struct starfive_mbox {
++ struct device *dev;
++ void __iomem *base;
++ struct mbox_chan chan[MBOX_CHAN_MAX];
++ struct starfive_chan_info mchan[MBOX_CHAN_MAX];
++ struct mbox_controller controller;
++ struct clk *clk;
++ struct reset_control *rst_rresetn;
++};
++
++static struct starfive_mbox *to_starfive_mbox(struct mbox_controller *mbox)
++{
++ return container_of(mbox, struct starfive_mbox, controller);
++}
++
++static struct mbox_chan *
++starfive_of_mbox_index_xlate(struct mbox_controller *mbox,
++ const struct of_phandle_args *sp)
++{
++ struct starfive_mbox *sbox;
++
++ int ind = sp->args[0];
++ int core_id = sp->args[1];
++
++ if (ind >= mbox->num_chans || core_id >= MAILBOX_CORE_NUM)
++ return ERR_PTR(-EINVAL);
++
++ sbox = to_starfive_mbox(mbox);
++
++ sbox->mchan[ind].core_id = core_id;
++
++ return &mbox->chans[ind];
++}
++
++static irqreturn_t starfive_rx_irq_handler(int irq, void *p)
++{
++ struct mbox_chan *chan = p;
++ unsigned long ch = (unsigned long)chan->con_priv;
++ struct starfive_mbox *mbox = to_starfive_mbox(chan->mbox);
++ void __iomem *base = MBOX_BASE(mbox, ch);
++ u32 val;
++
++ val = readl(base + MBOX_CMD_REG);
++ if (!val)
++ return IRQ_NONE;
++
++ mbox_chan_received_data(chan, (void *)&val);
++ writel(val, base + MBOX_CLR_REG);
++ return IRQ_HANDLED;
++}
++
++static int starfive_mbox_check_state(struct mbox_chan *chan)
++{
++ unsigned long ch = (unsigned long)chan->con_priv;
++ struct starfive_mbox *mbox = to_starfive_mbox(chan->mbox);
++ unsigned long irq_flag = IRQF_SHARED;
++ long ret = 0;
++
++ pm_runtime_get_sync(mbox->dev);
++ /* MAILBOX should be with IRQF_NO_SUSPEND set */
++ if (!mbox->dev->pm_domain)
++ irq_flag |= IRQF_NO_SUSPEND;
++
++ /* Mailbox is idle so directly bail out */
++ if (readl(mbox->base + MBC_PEND_SMRY) & BIT(ch))
++ return -EBUSY;
++
++ if (mbox->mchan[ch].dst_irq > 0) {
++ dev_dbg(mbox->dev, "%s: host IRQ = %d, ch:%ld", __func__, mbox->mchan[ch].dst_irq, ch);
++ ret = devm_request_irq(mbox->dev, mbox->mchan[ch].dst_irq, starfive_rx_irq_handler,
++ irq_flag, irq_peer_name[ch].name, chan);
++ if (ret < 0)
++ dev_err(mbox->dev, "request_irq %d failed\n", mbox->mchan[ch].dst_irq);
++ }
++
++ return ret;
++}
++
++static int starfive_mbox_startup(struct mbox_chan *chan)
++{
++ return starfive_mbox_check_state(chan);
++}
++
++static void starfive_mbox_shutdown(struct mbox_chan *chan)
++{
++ struct starfive_mbox *mbox = to_starfive_mbox(chan->mbox);
++ unsigned long ch = (unsigned long)chan->con_priv;
++ void __iomem *base = MBOX_BASE(mbox, ch);
++
++ writel(0x0, base + MBOX_IRQ_REG);
++ writel(0x0, base + MBOX_CLR_REG);
++
++ if (mbox->mchan[ch].dst_irq > 0)
++ devm_free_irq(mbox->dev, mbox->mchan[ch].dst_irq, chan);
++ pm_runtime_put_sync(mbox->dev);
++}
++
++static int starfive_mbox_send_data(struct mbox_chan *chan, void *msg)
++{
++ unsigned long ch = (unsigned long)chan->con_priv;
++ struct starfive_mbox *mbox = to_starfive_mbox(chan->mbox);
++ struct starfive_chan_info *mchan = &mbox->mchan[ch];
++ void __iomem *base = MBOX_BASE(mbox, ch);
++ u32 *buf = msg;
++
++ /* Ensure channel is released */
++ if (readl(mbox->base + MBC_PEND_SMRY) & BIT(ch)) {
++ pr_debug("%s:%d. busy\n", __func__, __LINE__);
++ return -EBUSY;
++ }
++
++ /* Clear mask for destination interrupt */
++ writel(BIT(mchan->core_id), base + MBOX_IRQ_REG);
++
++ /* Fill message data */
++ writel(*buf, base + MBOX_SET_REG);
++ return 0;
++}
++
++static struct mbox_chan_ops starfive_mbox_ops = {
++ .startup = starfive_mbox_startup,
++ .send_data = starfive_mbox_send_data,
++ .shutdown = starfive_mbox_shutdown,
++};
++
++static const struct of_device_id starfive_mbox_of_match[] = {
++ { .compatible = "starfive,mail_box",},
++ {},
++};
++
++MODULE_DEVICE_TABLE(of, starfive_mbox_of_match);
++
++void starfive_mailbox_init(struct starfive_mbox *mbox)
++{
++ mbox->clk = devm_clk_get_optional(mbox->dev, "clk_apb");
++ if (IS_ERR(mbox->clk)) {
++ dev_err(mbox->dev, "failed to get mailbox\n");
++ return;
++ }
++
++ mbox->rst_rresetn = devm_reset_control_get_exclusive(mbox->dev, "mbx_rre");
++ if (IS_ERR(mbox->rst_rresetn)) {
++ dev_err(mbox->dev, "failed to get mailbox reset\n");
++ return;
++ }
++
++ clk_prepare_enable(mbox->clk);
++ reset_control_deassert(mbox->rst_rresetn);
++}
++
++static int starfive_mbox_probe(struct platform_device *pdev)
++{
++ struct device *dev = &pdev->dev;
++ struct starfive_mbox *mbox;
++ struct mbox_chan *chan;
++ struct resource *res;
++ unsigned long ch;
++ int err;
++
++ mbox = devm_kzalloc(dev, sizeof(*mbox), GFP_KERNEL);
++ if (!mbox)
++ return -ENOMEM;
++
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ mbox->base = devm_ioremap_resource(dev, res);
++ mbox->dev = dev;
++
++ if (IS_ERR(mbox->base))
++ return PTR_ERR(mbox->base);
++
++ starfive_mailbox_init(mbox);
++
++ mbox->controller.dev = dev;
++ mbox->controller.chans = mbox->chan;
++ mbox->controller.num_chans = MBOX_CHAN_MAX;
++ mbox->controller.ops = &starfive_mbox_ops;
++ mbox->controller.of_xlate = starfive_of_mbox_index_xlate;
++ mbox->controller.txdone_irq = true;
++ mbox->controller.txdone_poll = false;
++
++ /* Initialize mailbox channel data */
++ chan = mbox->chan;
++ for (ch = 0; ch < MBOX_CHAN_MAX; ch++) {
++ mbox->mchan[ch].dst_irq = 0;
++ mbox->mchan[ch].core_id = (mailbox_core_t)ch;
++ chan[ch].con_priv = (void *)ch;
++ }
++ mbox->mchan[MAILBOX_CORE_HIFI4].dst_irq = platform_get_irq(pdev, 0);
++ mbox->mchan[MAILBOX_CORE_E2].dst_irq = platform_get_irq(pdev, 1);
++
++ err = mbox_controller_register(&mbox->controller);
++ if (err) {
++ dev_err(dev, "Failed to register mailbox %d\n", err);
++ return err;
++ }
++
++ platform_set_drvdata(pdev, mbox);
++ dev_info(dev, "Mailbox enabled\n");
++ pm_runtime_set_active(dev);
++ pm_runtime_enable(dev);
++
++ return 0;
++}
++
++static int starfive_mbox_remove(struct platform_device *pdev)
++{
++ struct starfive_mbox *mbox = platform_get_drvdata(pdev);
++
++ mbox_controller_unregister(&mbox->controller);
++ devm_clk_put(mbox->dev, mbox->clk);
++ pm_runtime_disable(mbox->dev);
++
++ return 0;
++}
++
++static int __maybe_unused starfive_mbox_suspend(struct device *dev)
++{
++ struct starfive_mbox *mbox = dev_get_drvdata(dev);
++
++ clk_disable_unprepare(mbox->clk);
++
++ return 0;
++}
++
++static int __maybe_unused starfive_mbox_resume(struct device *dev)
++{
++ struct starfive_mbox *mbox = dev_get_drvdata(dev);
++ int ret;
++
++ ret = clk_prepare_enable(mbox->clk);
++ if (ret)
++ dev_err(dev, "failed to enable clock\n");
++
++ return ret;
++}
++
++static const struct dev_pm_ops starfive_mbox_pm_ops = {
++ .suspend = starfive_mbox_suspend,
++ .resume = starfive_mbox_resume,
++ SET_RUNTIME_PM_OPS(starfive_mbox_suspend, starfive_mbox_resume, NULL)
++};
++static struct platform_driver starfive_mbox_driver = {
++ .probe = starfive_mbox_probe,
++ .remove = starfive_mbox_remove,
++ .driver = {
++ .name = "mailbox",
++ .of_match_table = starfive_mbox_of_match,
++ .pm = &starfive_mbox_pm_ops,
++ },
++};
++
++static int __init starfive_mbox_init(void)
++{
++ return platform_driver_register(&starfive_mbox_driver);
++}
++core_initcall(starfive_mbox_init);
++
++static void __exit starfive_mbox_exit(void)
++{
++ platform_driver_unregister(&starfive_mbox_driver);
++}
++module_exit(starfive_mbox_exit);
++
++MODULE_DESCRIPTION("StarFive Mailbox Controller driver");
++MODULE_AUTHOR("Shanlong Li <shanlong.li@starfivetech.com>");
++MODULE_LICENSE("GPL");
diff --git a/target/linux/starfive/patches-6.6/0065-driver-rtc-Add-StarFive-JH7110-rtc-driver.patch b/target/linux/starfive/patches-6.6/0065-driver-rtc-Add-StarFive-JH7110-rtc-driver.patch
new file mode 100644
index 0000000000..0257cb004b
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0065-driver-rtc-Add-StarFive-JH7110-rtc-driver.patch
@@ -0,0 +1,789 @@
+From 0f44bd6bec708782f38bba4d03deecf927d1c83d Mon Sep 17 00:00:00 2001
+From: "ziv.xu" <ziv.xu@starfivetech.com>
+Date: Fri, 9 Jun 2023 15:31:53 +0800
+Subject: [PATCH 065/116] driver: rtc: Add StarFive JH7110 rtc driver
+
+Add RTC driver and support for StarFive JH7110 SoC.
+
+Signed-off-by: ziv.xu <ziv.xu@starfivetech.com>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ drivers/rtc/Kconfig | 8 +
+ drivers/rtc/Makefile | 1 +
+ drivers/rtc/rtc-starfive.c | 743 +++++++++++++++++++++++++++++++++++++
+ 3 files changed, 752 insertions(+)
+ create mode 100644 drivers/rtc/rtc-starfive.c
+
+--- a/drivers/rtc/Kconfig
++++ b/drivers/rtc/Kconfig
+@@ -1327,6 +1327,14 @@ config RTC_DRV_NTXEC
+ embedded controller found in certain e-book readers designed by the
+ original design manufacturer Netronix.
+
++config RTC_DRV_STARFIVE
++ tristate "StarFive 32.768k-RTC"
++ depends on ARCH_STARFIVE
++ depends on OF
++ help
++ If you say Y here you will get support for the RTC found on
++ StarFive SOCS.
++
+ comment "on-CPU RTC drivers"
+
+ config RTC_DRV_ASM9260
+--- a/drivers/rtc/Makefile
++++ b/drivers/rtc/Makefile
+@@ -163,6 +163,7 @@ obj-$(CONFIG_RTC_DRV_SH) += rtc-sh.o
+ obj-$(CONFIG_RTC_DRV_SNVS) += rtc-snvs.o
+ obj-$(CONFIG_RTC_DRV_SPEAR) += rtc-spear.o
+ obj-$(CONFIG_RTC_DRV_STARFIRE) += rtc-starfire.o
++obj-$(CONFIG_RTC_DRV_STARFIVE) += rtc-starfive.o
+ obj-$(CONFIG_RTC_DRV_STK17TA8) += rtc-stk17ta8.o
+ obj-$(CONFIG_RTC_DRV_ST_LPC) += rtc-st-lpc.o
+ obj-$(CONFIG_RTC_DRV_STM32) += rtc-stm32.o
+--- /dev/null
++++ b/drivers/rtc/rtc-starfive.c
+@@ -0,0 +1,743 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * RTC driver for the StarFive JH7110 SoC
++ *
++ * Copyright (C) 2021 StarFive Technology Co., Ltd.
++ */
++
++#include <asm/delay.h>
++#include <linux/bcd.h>
++#include <linux/bitfield.h>
++#include <linux/clk.h>
++#include <linux/reset.h>
++#include <linux/completion.h>
++#include <linux/interrupt.h>
++#include <linux/io.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/of_irq.h>
++#include <linux/iopoll.h>
++#include <linux/platform_device.h>
++#include <linux/rtc.h>
++
++/* Registers */
++#define SFT_RTC_CFG 0x00
++#define SFT_RTC_SW_CAL_VALUE 0x04
++#define SFT_RTC_HW_CAL_CFG 0x08
++#define SFT_RTC_CMP_CFG 0x0C
++#define SFT_RTC_IRQ_EN 0x10
++#define SFT_RTC_IRQ_EVEVT 0x14
++#define SFT_RTC_IRQ_STATUS 0x18
++#define SFT_RTC_CAL_VALUE 0x24
++#define SFT_RTC_CFG_TIME 0x28
++#define SFT_RTC_CFG_DATE 0x2C
++#define SFT_RTC_ACT_TIME 0x34
++#define SFT_RTC_ACT_DATE 0x38
++#define SFT_RTC_TIME 0x3C
++#define SFT_RTC_DATE 0x40
++#define SFT_RTC_TIME_LATCH 0x44
++#define SFT_RTC_DATE_LATCH 0x48
++
++/* RTC_CFG */
++#define RTC_CFG_ENABLE_SHIFT 0 /* RW: RTC Enable. */
++#define RTC_CFG_CAL_EN_HW_SHIFT 1 /* RW: Enable of hardware calibretion. */
++#define RTC_CFG_CAL_SEL_SHIFT 2 /* RW: select the hw/sw calibretion mode.*/
++#define RTC_CFG_HOUR_MODE_SHIFT 3 /* RW: time hour mode. 24h|12h */
++
++/* RTC_SW_CAL_VALUE */
++#define RTC_SW_CAL_VALUE_MASK GENMASK(15, 0)
++#define RTC_SW_CAL_MAX RTC_SW_CAL_VALUE_MASK
++#define RTC_SW_CAL_MIN 0
++#define RTC_TICKS_PER_SEC 32768 /* Number of ticks per second */
++#define RTC_PPB_MULT 1000000000LL /* Multiplier for ppb conversions */
++
++/* RTC_HW_CAL_CFG */
++#define RTC_HW_CAL_REF_SEL_SHIFT 0
++#define RTC_HW_CAL_FRQ_SEL_SHIFT 1
++
++/* IRQ_EN/IRQ_EVEVT/IRQ_STATUS */
++#define RTC_IRQ_CAL_START BIT(0)
++#define RTC_IRQ_CAL_FINISH BIT(1)
++#define RTC_IRQ_CMP BIT(2)
++#define RTC_IRQ_1SEC BIT(3)
++#define RTC_IRQ_ALAEM BIT(4)
++#define RTC_IRQ_EVT_UPDATE_PSE BIT(31) /* WO: Enable of update time&&date, IRQ_EVEVT only */
++#define RTC_IRQ_ALL (RTC_IRQ_CAL_START \
++ | RTC_IRQ_CAL_FINISH \
++ | RTC_IRQ_CMP \
++ | RTC_IRQ_1SEC \
++ | RTC_IRQ_ALAEM)
++
++/* CAL_VALUE */
++#define RTC_CAL_VALUE_MASK GENMASK(15, 0)
++
++/* CFG_TIME/ACT_TIME/RTC_TIME */
++#define TIME_SEC_MASK GENMASK(6, 0)
++#define TIME_MIN_MASK GENMASK(13, 7)
++#define TIME_HOUR_MASK GENMASK(20, 14)
++
++/* CFG_DATE/ACT_DATE/RTC_DATE */
++#define DATE_DAY_MASK GENMASK(5, 0)
++#define DATE_MON_MASK GENMASK(10, 6)
++#define DATE_YEAR_MASK GENMASK(18, 11)
++
++#define INT_TIMEOUT_US 180
++
++enum RTC_HOUR_MODE {
++ RTC_HOUR_MODE_12H = 0,
++ RTC_HOUR_MODE_24H = 1
++};
++
++enum RTC_CAL_MODE {
++ RTC_CAL_MODE_SW = 0,
++ RTC_CAL_MODE_HW = 1
++};
++
++enum RTC_HW_CAL_REF_MODE {
++ RTC_CAL_CLK_REF = 0,
++ RTC_CAL_CLK_MARK = 1
++};
++
++static const unsigned long refclk_list[] = {
++ 1000000,
++ 2000000,
++ 4000000,
++ 5927000,
++ 6000000,
++ 7200000,
++ 8000000,
++ 10250000,
++ 11059200,
++ 12000000,
++ 12288000,
++ 13560000,
++ 16000000,
++ 19200000,
++ 20000000,
++ 22118000,
++ 24000000,
++ 24567000,
++ 25000000,
++ 26000000,
++ 27000000,
++ 30000000,
++ 32000000,
++ 33868800,
++ 36000000,
++ 36860000,
++ 40000000,
++ 44000000,
++ 50000000,
++ 54000000,
++ 28224000,
++ 28000000,
++};
++
++struct sft_rtc {
++ struct rtc_device *rtc_dev;
++ struct completion cal_done;
++ struct completion onesec_done;
++ struct clk *pclk;
++ struct clk *cal_clk;
++ struct reset_control *rst_array;
++ int hw_cal_map;
++ void __iomem *regs;
++ int rtc_irq;
++ int ms_pulse_irq;
++ int one_sec_pulse_irq;
++};
++
++static inline void sft_rtc_set_enabled(struct sft_rtc *srtc, bool enabled)
++{
++ u32 val;
++
++ if (enabled) {
++ val = readl(srtc->regs + SFT_RTC_CFG);
++ val |= BIT(RTC_CFG_ENABLE_SHIFT);
++ writel(val, srtc->regs + SFT_RTC_CFG);
++ } else {
++ val = readl(srtc->regs + SFT_RTC_CFG);
++ val &= ~BIT(RTC_CFG_ENABLE_SHIFT);
++ writel(val, srtc->regs + SFT_RTC_CFG);
++ }
++}
++
++static inline bool sft_rtc_get_enabled(struct sft_rtc *srtc)
++{
++ return !!(readl(srtc->regs + SFT_RTC_CFG) & BIT(RTC_CFG_ENABLE_SHIFT));
++}
++
++static inline void sft_rtc_set_mode(struct sft_rtc *srtc, enum RTC_HOUR_MODE mode)
++{
++ u32 val;
++
++ val = readl(srtc->regs + SFT_RTC_CFG);
++ val |= mode << RTC_CFG_HOUR_MODE_SHIFT;
++ writel(val, srtc->regs + SFT_RTC_CFG);
++}
++
++static inline int sft_rtc_irq_enable(struct sft_rtc *srtc, u32 irq, bool enable)
++{
++ u32 val;
++
++ if (!(irq & RTC_IRQ_ALL))
++ return -EINVAL;
++
++ if (enable) {
++ val = readl(srtc->regs + SFT_RTC_IRQ_EN);
++ val |= irq;
++ writel(val, srtc->regs + SFT_RTC_IRQ_EN);
++ } else {
++ val = readl(srtc->regs + SFT_RTC_IRQ_EN);
++ val &= ~irq;
++ writel(val, srtc->regs + SFT_RTC_IRQ_EN);
++ }
++ return 0;
++}
++
++static inline void
++sft_rtc_set_cal_hw_enable(struct sft_rtc *srtc, bool enable)
++{
++ u32 val;
++
++ if (enable) {
++ val = readl(srtc->regs + SFT_RTC_CFG);
++ val |= BIT(RTC_CFG_CAL_EN_HW_SHIFT);
++ writel(val, srtc->regs + SFT_RTC_CFG);
++ } else {
++ val = readl(srtc->regs + SFT_RTC_CFG);
++ val &= ~BIT(RTC_CFG_CAL_EN_HW_SHIFT);
++ writel(val, srtc->regs + SFT_RTC_CFG);
++ }
++}
++
++static inline void
++sft_rtc_set_cal_mode(struct sft_rtc *srtc, enum RTC_CAL_MODE mode)
++{
++ u32 val;
++
++ val = readl(srtc->regs + SFT_RTC_CFG);
++ val |= mode << RTC_CFG_CAL_SEL_SHIFT;
++ writel(val, srtc->regs + SFT_RTC_CFG);
++}
++
++static int sft_rtc_get_hw_calclk(struct device *dev, unsigned long freq)
++{
++ int i;
++
++ for (i = 0; i < ARRAY_SIZE(refclk_list); i++)
++ if (refclk_list[i] == freq)
++ return i;
++
++ dev_err(dev, "refclk: %ldHz do not support.\n", freq);
++ return -EINVAL;
++}
++
++static inline void sft_rtc_reg2time(struct rtc_time *tm, u32 reg)
++{
++ tm->tm_hour = bcd2bin(FIELD_GET(TIME_HOUR_MASK, reg));
++ tm->tm_min = bcd2bin(FIELD_GET(TIME_MIN_MASK, reg));
++ tm->tm_sec = bcd2bin(FIELD_GET(TIME_SEC_MASK, reg));
++}
++
++static inline void sft_rtc_reg2date(struct rtc_time *tm, u32 reg)
++{
++ tm->tm_year = bcd2bin(FIELD_GET(DATE_YEAR_MASK, reg)) + 100;
++ tm->tm_mon = bcd2bin(FIELD_GET(DATE_MON_MASK, reg)) - 1;
++ tm->tm_mday = bcd2bin(FIELD_GET(DATE_DAY_MASK, reg));
++}
++
++static inline u32 sft_rtc_time2reg(struct rtc_time *tm)
++{
++ return FIELD_PREP(TIME_HOUR_MASK, bin2bcd(tm->tm_hour)) |
++ FIELD_PREP(TIME_MIN_MASK, bin2bcd(tm->tm_min)) |
++ FIELD_PREP(TIME_SEC_MASK, bin2bcd(tm->tm_sec));
++}
++
++static inline u32 sft_rtc_date2reg(struct rtc_time *tm)
++{
++ return FIELD_PREP(DATE_YEAR_MASK, bin2bcd(tm->tm_year - 100)) |
++ FIELD_PREP(DATE_MON_MASK, bin2bcd(tm->tm_mon + 1)) |
++ FIELD_PREP(DATE_DAY_MASK, bin2bcd(tm->tm_mday));
++}
++
++static inline void sft_rtc_update_pulse(struct sft_rtc *srtc)
++{
++ u32 val;
++
++ val = readl(srtc->regs + SFT_RTC_IRQ_EVEVT);
++ val |= RTC_IRQ_EVT_UPDATE_PSE;
++ writel(val, srtc->regs + SFT_RTC_IRQ_EVEVT);
++}
++
++static irqreturn_t sft_rtc_irq_handler(int irq, void *data)
++{
++ struct sft_rtc *srtc = data;
++ struct timerqueue_node *next;
++ u32 irq_flags = 0;
++ u32 irq_mask = 0;
++ u32 val;
++ int ret = 0;
++
++ val = readl(srtc->regs + SFT_RTC_IRQ_EVEVT);
++ if (val & RTC_IRQ_CAL_START)
++ irq_mask |= RTC_IRQ_CAL_START;
++
++ if (val & RTC_IRQ_CAL_FINISH) {
++ irq_mask |= RTC_IRQ_CAL_FINISH;
++ complete(&srtc->cal_done);
++ }
++
++ if (val & RTC_IRQ_CMP)
++ irq_mask |= RTC_IRQ_CMP;
++
++ if (val & RTC_IRQ_1SEC) {
++ irq_flags |= RTC_PF;
++ irq_mask |= RTC_IRQ_1SEC;
++ complete(&srtc->onesec_done);
++ }
++
++ if (val & RTC_IRQ_ALAEM) {
++ irq_flags |= RTC_AF;
++ irq_mask |= RTC_IRQ_ALAEM;
++
++ next = timerqueue_getnext(&srtc->rtc_dev->timerqueue);
++ if (next == &srtc->rtc_dev->aie_timer.node)
++ dev_info(&srtc->rtc_dev->dev, "alarm expires");
++ }
++
++ writel(irq_mask, srtc->regs + SFT_RTC_IRQ_EVEVT);
++
++ /* Wait interrupt flag clear */
++ ret = readl_poll_timeout_atomic(srtc->regs + SFT_RTC_IRQ_EVEVT, val,
++ (val & irq_mask) == 0, 0, INT_TIMEOUT_US);
++ if (ret)
++ dev_warn(&srtc->rtc_dev->dev, "fail to clear rtc interrupt flag\n");
++
++ if (irq_flags)
++ rtc_update_irq(srtc->rtc_dev, 1, irq_flags | RTC_IRQF);
++
++ return IRQ_HANDLED;
++}
++
++static int sft_rtc_read_time(struct device *dev, struct rtc_time *tm)
++{
++ struct sft_rtc *srtc = dev_get_drvdata(dev);
++ u32 val;
++ int irq_1sec_state_start, irq_1sec_state_end;
++
++ /* If the RTC is disabled, assume the values are invalid */
++ if (!sft_rtc_get_enabled(srtc))
++ return -EINVAL;
++
++ irq_1sec_state_start =
++ (readl(srtc->regs + SFT_RTC_IRQ_STATUS) & RTC_IRQ_1SEC) == 0 ? 0 : 1;
++
++read_again:
++ val = readl(srtc->regs + SFT_RTC_TIME);
++ sft_rtc_reg2time(tm, val);
++
++ val = readl(srtc->regs + SFT_RTC_DATE);
++ sft_rtc_reg2date(tm, val);
++
++ if (irq_1sec_state_start == 0) {
++ irq_1sec_state_end =
++ (readl(srtc->regs + SFT_RTC_IRQ_STATUS) & RTC_IRQ_1SEC) == 0 ? 0 : 1;
++ if (irq_1sec_state_end == 1) {
++ irq_1sec_state_start = 1;
++ goto read_again;
++ }
++ }
++
++ return 0;
++}
++
++static int sft_rtc_set_time(struct device *dev, struct rtc_time *tm)
++{
++ struct sft_rtc *srtc = dev_get_drvdata(dev);
++ u32 val;
++ int ret;
++
++ val = sft_rtc_time2reg(tm);
++ writel(val, srtc->regs + SFT_RTC_CFG_TIME);
++
++ val = sft_rtc_date2reg(tm);
++ writel(val, srtc->regs + SFT_RTC_CFG_DATE);
++
++ /* Update pulse */
++ sft_rtc_update_pulse(srtc);
++
++ /* Ensure that data is fully written */
++ ret = wait_for_completion_interruptible_timeout(&srtc->onesec_done,
++ usecs_to_jiffies(120));
++ if (ret) {
++ dev_warn(dev,
++ "rtc wait for completion interruptible timeout.\n");
++ }
++ return 0;
++}
++
++static int sft_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
++{
++ struct sft_rtc *srtc = dev_get_drvdata(dev);
++
++ return sft_rtc_irq_enable(srtc, RTC_IRQ_ALAEM, enabled);
++}
++
++static int sft_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
++{
++ struct sft_rtc *srtc = dev_get_drvdata(dev);
++ u32 val;
++
++ val = readl(srtc->regs + SFT_RTC_ACT_TIME);
++ sft_rtc_reg2time(&alarm->time, val);
++
++ val = readl(srtc->regs + SFT_RTC_ACT_DATE);
++ sft_rtc_reg2date(&alarm->time, val);
++
++ return 0;
++}
++
++static int sft_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
++{
++ struct sft_rtc *srtc = dev_get_drvdata(dev);
++ u32 val;
++
++ sft_rtc_alarm_irq_enable(dev, 0);
++
++ val = sft_rtc_time2reg(&alarm->time);
++ writel(val, srtc->regs + SFT_RTC_ACT_TIME);
++
++ val = sft_rtc_date2reg(&alarm->time);
++ writel(val, srtc->regs + SFT_RTC_ACT_DATE);
++
++ sft_rtc_alarm_irq_enable(dev, alarm->enabled);
++
++ return 0;
++}
++
++static int sft_rtc_get_offset(struct device *dev, long *offset)
++{
++ struct sft_rtc *srtc = dev_get_drvdata(dev);
++ s64 tmp;
++ u32 val;
++
++ val = readl(srtc->regs + SFT_RTC_CAL_VALUE)
++ & RTC_SW_CAL_VALUE_MASK;
++ val += 1;
++ /*
++ * the adjust val range is [0x0000-0xffff],
++ * the default val is 0x7fff (32768-1),mapping offset=0 ;
++ */
++ tmp = (s64)val - RTC_TICKS_PER_SEC;
++ tmp *= RTC_PPB_MULT;
++ tmp = div_s64(tmp, RTC_TICKS_PER_SEC);
++
++ /* Offset value operates in negative way, so swap sign */
++ *offset = -tmp;
++
++ return 0;
++}
++
++static int sft_rtc_set_offset(struct device *dev, long offset)
++{
++ struct sft_rtc *srtc = dev_get_drvdata(dev);
++ s64 tmp;
++ u32 val;
++
++ tmp = offset * RTC_TICKS_PER_SEC;
++ tmp = div_s64(tmp, RTC_PPB_MULT);
++
++ tmp = RTC_TICKS_PER_SEC - tmp;
++ tmp -= 1;
++ if (tmp > RTC_SW_CAL_MAX || tmp < RTC_SW_CAL_MIN) {
++ dev_err(dev, "offset is out of range.\n");
++ return -EINVAL;
++ }
++
++ val = tmp & RTC_SW_CAL_VALUE_MASK;
++ /* set software calibration value */
++ writel(val, srtc->regs + SFT_RTC_SW_CAL_VALUE);
++
++ /* set CFG_RTC-cal_sel to select calibretion by software. */
++ sft_rtc_set_cal_mode(srtc, RTC_CAL_MODE_SW);
++
++ return 0;
++}
++
++static __maybe_unused int
++sft_rtc_hw_adjustment(struct device *dev, unsigned int enable)
++{
++ struct sft_rtc *srtc = dev_get_drvdata(dev);
++ u32 val;
++
++ if (srtc->hw_cal_map <= 0) {
++ dev_err(dev, "fail to get cal-clock-freq.\n");
++ return -EFAULT;
++ }
++
++ if (enable) {
++ sft_rtc_irq_enable(srtc, RTC_IRQ_CAL_FINISH, true);
++
++ /* Set reference clock frequency value */
++ val = readl(srtc->regs + SFT_RTC_HW_CAL_CFG);
++ val |= (srtc->hw_cal_map << RTC_HW_CAL_FRQ_SEL_SHIFT);
++ writel(val, srtc->regs + SFT_RTC_HW_CAL_CFG);
++
++ /* Set CFG_RTC-cal_sel to select calibretion by hardware. */
++ sft_rtc_set_cal_mode(srtc, RTC_CAL_MODE_HW);
++
++ /* Set CFG_RTC-cal_en_hw to launch hardware calibretion.*/
++ sft_rtc_set_cal_hw_enable(srtc, true);
++
++ wait_for_completion_interruptible_timeout(&srtc->cal_done,
++ usecs_to_jiffies(100));
++
++ sft_rtc_irq_enable(srtc, RTC_IRQ_CAL_FINISH, false);
++ } else {
++ sft_rtc_set_cal_mode(srtc, RTC_CAL_MODE_SW);
++ sft_rtc_set_cal_hw_enable(srtc, false);
++ }
++
++ return 0;
++}
++
++static int sft_rtc_get_cal_clk(struct device *dev, struct sft_rtc *srtc)
++{
++ struct device_node *np = dev->of_node;
++ unsigned long cal_clk_freq;
++ u32 freq;
++ int ret;
++
++ srtc->cal_clk = devm_clk_get(dev, "cal_clk");
++ if (IS_ERR(srtc->cal_clk))
++ return PTR_ERR(srtc->cal_clk);
++
++ clk_prepare_enable(srtc->cal_clk);
++
++ cal_clk_freq = clk_get_rate(srtc->cal_clk);
++ if (!cal_clk_freq) {
++ dev_warn(dev,
++ "get rate failed, next try to get from dts.\n");
++ ret = of_property_read_u32(np, "rtc,cal-clock-freq", &freq);
++ if (!ret) {
++ cal_clk_freq = (u64)freq;
++ } else {
++ dev_err(dev,
++ "Need rtc,cal-clock-freq define in dts.\n");
++ goto err_disable_cal_clk;
++ }
++ }
++
++ srtc->hw_cal_map = sft_rtc_get_hw_calclk(dev, cal_clk_freq);
++ if (srtc->hw_cal_map < 0) {
++ ret = srtc->hw_cal_map;
++ goto err_disable_cal_clk;
++ }
++
++ return 0;
++
++err_disable_cal_clk:
++ clk_disable_unprepare(srtc->cal_clk);
++
++ return ret;
++}
++
++static int sft_rtc_get_irq(struct platform_device *pdev, struct sft_rtc *srtc)
++{
++ int ret;
++
++ srtc->rtc_irq = platform_get_irq_byname(pdev, "rtc");
++ if (srtc->rtc_irq < 0)
++ return -EINVAL;
++
++ ret = devm_request_irq(&pdev->dev, srtc->rtc_irq,
++ sft_rtc_irq_handler, 0,
++ KBUILD_MODNAME, srtc);
++ if (ret)
++ dev_err(&pdev->dev, "Failed to request interrupt, %d\n", ret);
++
++ return ret;
++}
++
++static const struct rtc_class_ops starfive_rtc_ops = {
++ .read_time = sft_rtc_read_time,
++ .set_time = sft_rtc_set_time,
++ .read_alarm = sft_rtc_read_alarm,
++ .set_alarm = sft_rtc_set_alarm,
++ .alarm_irq_enable = sft_rtc_alarm_irq_enable,
++ .set_offset = sft_rtc_set_offset,
++ .read_offset = sft_rtc_get_offset,
++};
++
++static int sft_rtc_probe(struct platform_device *pdev)
++{
++ struct device *dev = &pdev->dev;
++ struct sft_rtc *srtc;
++ struct rtc_time tm;
++ struct irq_desc *desc;
++ int ret;
++
++ srtc = devm_kzalloc(dev, sizeof(*srtc), GFP_KERNEL);
++ if (!srtc)
++ return -ENOMEM;
++
++ srtc->regs = devm_platform_ioremap_resource(pdev, 0);
++ if (IS_ERR(srtc->regs))
++ return PTR_ERR(srtc->regs);
++
++ srtc->pclk = devm_clk_get(dev, "pclk");
++ if (IS_ERR(srtc->pclk)) {
++ ret = PTR_ERR(srtc->pclk);
++ dev_err(dev,
++ "Failed to retrieve the peripheral clock, %d\n", ret);
++ return ret;
++ }
++
++ srtc->rst_array = devm_reset_control_array_get_exclusive(dev);
++ if (IS_ERR(srtc->rst_array)) {
++ ret = PTR_ERR(srtc->rst_array);
++ dev_err(dev,
++ "Failed to retrieve the rtc reset, %d\n", ret);
++ return ret;
++ }
++
++ init_completion(&srtc->cal_done);
++ init_completion(&srtc->onesec_done);
++
++ ret = clk_prepare_enable(srtc->pclk);
++ if (ret) {
++ dev_err(dev,
++ "Failed to enable the peripheral clock, %d\n", ret);
++ return ret;
++ }
++
++ ret = sft_rtc_get_cal_clk(dev, srtc);
++ if (ret)
++ goto err_disable_pclk;
++
++ ret = reset_control_deassert(srtc->rst_array);
++ if (ret) {
++ dev_err(dev,
++ "Failed to deassert rtc resets, %d\n", ret);
++ goto err_disable_cal_clk;
++ }
++
++ ret = sft_rtc_get_irq(pdev, srtc);
++ if (ret)
++ goto err_disable_cal_clk;
++
++ srtc->rtc_dev = devm_rtc_allocate_device(dev);
++ if (IS_ERR(srtc->rtc_dev))
++ return PTR_ERR(srtc->rtc_dev);
++
++ platform_set_drvdata(pdev, srtc);
++
++ /* The RTC supports 01.01.2001 - 31.12.2099 */
++ srtc->rtc_dev->range_min = mktime64(2001, 1, 1, 0, 0, 0);
++ srtc->rtc_dev->range_max = mktime64(2099, 12, 31, 23, 59, 59);
++
++ srtc->rtc_dev->ops = &starfive_rtc_ops;
++ device_init_wakeup(dev, true);
++
++ desc = irq_to_desc(srtc->rtc_irq);
++ irq_desc_get_chip(desc)->flags = IRQCHIP_SKIP_SET_WAKE;
++
++ /* Always use 24-hour mode and keep the RTC values */
++ sft_rtc_set_mode(srtc, RTC_HOUR_MODE_24H);
++
++ sft_rtc_set_enabled(srtc, true);
++
++ if (device_property_read_bool(dev, "rtc,hw-adjustment"))
++ sft_rtc_hw_adjustment(dev, true);
++
++ /*
++ * If rtc time is out of supported range, reset it to the minimum time.
++ * notice that, actual year = 1900 + tm.tm_year
++ * actual month = 1 + tm.tm_mon
++ */
++ sft_rtc_read_time(dev, &tm);
++ if (tm.tm_year < 101 || tm.tm_year > 199 || tm.tm_mon < 0 || tm.tm_mon > 11 ||
++ tm.tm_mday < 1 || tm.tm_mday > 31 || tm.tm_hour < 0 || tm.tm_hour > 23 ||
++ tm.tm_min < 0 || tm.tm_min > 59 || tm.tm_sec < 0 || tm.tm_sec > 59) {
++ rtc_time64_to_tm(srtc->rtc_dev->range_min, &tm);
++ sft_rtc_set_time(dev, &tm);
++ }
++
++ ret = devm_rtc_register_device(srtc->rtc_dev);
++ if (ret)
++ goto err_disable_wakeup;
++
++ return 0;
++
++err_disable_wakeup:
++ device_init_wakeup(dev, false);
++
++err_disable_cal_clk:
++ clk_disable_unprepare(srtc->cal_clk);
++
++err_disable_pclk:
++ clk_disable_unprepare(srtc->pclk);
++
++ return ret;
++}
++
++static int sft_rtc_remove(struct platform_device *pdev)
++{
++ struct sft_rtc *srtc = platform_get_drvdata(pdev);
++
++ sft_rtc_alarm_irq_enable(&pdev->dev, 0);
++ device_init_wakeup(&pdev->dev, 0);
++
++ clk_disable_unprepare(srtc->pclk);
++ clk_disable_unprepare(srtc->cal_clk);
++
++ return 0;
++}
++
++#ifdef CONFIG_PM_SLEEP
++static int sft_rtc_suspend(struct device *dev)
++{
++ struct sft_rtc *srtc = dev_get_drvdata(dev);
++
++ if (device_may_wakeup(dev))
++ enable_irq_wake(srtc->rtc_irq);
++
++ return 0;
++}
++
++static int sft_rtc_resume(struct device *dev)
++{
++ struct sft_rtc *srtc = dev_get_drvdata(dev);
++
++ if (device_may_wakeup(dev))
++ disable_irq_wake(srtc->rtc_irq);
++
++ return 0;
++}
++#endif
++
++static SIMPLE_DEV_PM_OPS(sft_rtc_pm_ops, sft_rtc_suspend, sft_rtc_resume);
++
++static const struct of_device_id sft_rtc_of_match[] = {
++ { .compatible = "starfive,jh7110-rtc" },
++ { },
++};
++MODULE_DEVICE_TABLE(of, sft_rtc_of_match);
++
++static struct platform_driver starfive_rtc_driver = {
++ .driver = {
++ .name = "starfive-rtc",
++ .of_match_table = sft_rtc_of_match,
++ .pm = &sft_rtc_pm_ops,
++ },
++ .probe = sft_rtc_probe,
++ .remove = sft_rtc_remove,
++};
++module_platform_driver(starfive_rtc_driver);
++
++MODULE_AUTHOR("Samin Guo <samin.guo@starfivetech.com>");
++MODULE_AUTHOR("Hal Feng <hal.feng@starfivetech.com>");
++MODULE_DESCRIPTION("StarFive RTC driver");
++MODULE_LICENSE("GPL v2");
++MODULE_ALIAS("platform:starfive-rtc");
diff --git a/target/linux/starfive/patches-6.6/0066-uart-8250-Add-dw-auto-flow-ctrl-support.patch b/target/linux/starfive/patches-6.6/0066-uart-8250-Add-dw-auto-flow-ctrl-support.patch
new file mode 100644
index 0000000000..c88008a604
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0066-uart-8250-Add-dw-auto-flow-ctrl-support.patch
@@ -0,0 +1,96 @@
+From 552114b8cbbd956ad8466261b5f11b059eba82ca Mon Sep 17 00:00:00 2001
+From: Minda Chen <minda.chen@starfivetech.com>
+Date: Sun, 25 Jun 2023 09:40:29 +0800
+Subject: [PATCH 066/116] uart: 8250: Add dw auto flow ctrl support
+
+Add designeware 8250 auto flow ctrl support. Enable
+it by add auto-flow-control in dts.
+
+Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
+---
+ drivers/tty/serial/8250/8250_core.c | 2 ++
+ drivers/tty/serial/8250/8250_dw.c | 3 +++
+ drivers/tty/serial/8250/8250_port.c | 14 +++++++++++++-
+ include/linux/serial_8250.h | 1 +
+ include/uapi/linux/serial_core.h | 2 ++
+ 5 files changed, 21 insertions(+), 1 deletion(-)
+
+--- a/drivers/tty/serial/8250/8250_core.c
++++ b/drivers/tty/serial/8250/8250_core.c
+@@ -1129,6 +1129,8 @@ int serial8250_register_8250_port(const
+ uart->dl_read = up->dl_read;
+ if (up->dl_write)
+ uart->dl_write = up->dl_write;
++ if (up->probe)
++ uart->probe = up->probe;
+
+ if (uart->port.type != PORT_8250_CIR) {
+ if (serial8250_isa_config != NULL)
+--- a/drivers/tty/serial/8250/8250_dw.c
++++ b/drivers/tty/serial/8250/8250_dw.c
+@@ -612,6 +612,9 @@ static int dw8250_probe(struct platform_
+ data->msr_mask_off |= UART_MSR_TERI;
+ }
+
++ if (device_property_read_bool(dev, "auto-flow-control"))
++ up->probe |= UART_PROBE_AFE;
++
+ /* If there is separate baudclk, get the rate from it. */
+ data->clk = devm_clk_get_optional(dev, "baudclk");
+ if (data->clk == NULL)
+--- a/drivers/tty/serial/8250/8250_port.c
++++ b/drivers/tty/serial/8250/8250_port.c
+@@ -330,6 +330,14 @@ static const struct serial8250_config ua
+ .rxtrig_bytes = {1, 8, 16, 30},
+ .flags = UART_CAP_FIFO | UART_CAP_AFE,
+ },
++ [PORT_16550A_AFE] = {
++ .name = "16550A_AFE",
++ .fifo_size = 16,
++ .tx_loadsz = 16,
++ .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
++ .rxtrig_bytes = {1, 4, 8, 14},
++ .flags = UART_CAP_FIFO | UART_CAP_AFE,
++ },
+ };
+
+ /* Uart divisor latch read */
+@@ -1143,6 +1151,11 @@ static void autoconfig_16550a(struct uar
+ up->port.type = PORT_U6_16550A;
+ up->capabilities |= UART_CAP_AFE;
+ }
++
++ if ((up->port.type == PORT_16550A) && (up->probe & UART_PROBE_AFE)) {
++ up->port.type = PORT_16550A_AFE;
++ up->capabilities |= UART_CAP_AFE;
++ }
+ }
+
+ /*
+@@ -2813,7 +2826,6 @@ serial8250_do_set_termios(struct uart_po
+ if (termios->c_cflag & CRTSCTS)
+ up->mcr |= UART_MCR_AFE;
+ }
+-
+ /*
+ * Update the per-port timeout.
+ */
+--- a/include/linux/serial_8250.h
++++ b/include/linux/serial_8250.h
+@@ -141,6 +141,7 @@ struct uart_8250_port {
+ unsigned char probe;
+ struct mctrl_gpios *gpios;
+ #define UART_PROBE_RSA (1 << 0)
++#define UART_PROBE_AFE (1 << 1)
+
+ /*
+ * Some bits in registers are cleared on a read, so they must
+--- a/include/uapi/linux/serial_core.h
++++ b/include/uapi/linux/serial_core.h
+@@ -245,4 +245,6 @@
+ /* Sunplus UART */
+ #define PORT_SUNPLUS 123
+
++#define PORT_16550A_AFE 124
++
+ #endif /* _UAPILINUX_SERIAL_CORE_H */
diff --git a/target/linux/starfive/patches-6.6/0067-driver-uart-fix-up-uart-communicate-fail.patch b/target/linux/starfive/patches-6.6/0067-driver-uart-fix-up-uart-communicate-fail.patch
new file mode 100644
index 0000000000..18d735b92d
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0067-driver-uart-fix-up-uart-communicate-fail.patch
@@ -0,0 +1,29 @@
+From 6edee93a89254f30c3387c88231e7ecec06ba84a Mon Sep 17 00:00:00 2001
+From: "shanlong.li" <shanlong.li@starfivetech.com>
+Date: Mon, 10 Jul 2023 03:07:57 -0700
+Subject: [PATCH 067/116] driver:uart: fix up uart communicate fail
+
+fix up uart communicate fail
+
+Signed-off-by: shanlong.li <shanlong.li@starfivetech.com>
+---
+ drivers/tty/serial/8250/8250_dw.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/tty/serial/8250/8250_dw.c
++++ b/drivers/tty/serial/8250/8250_dw.c
+@@ -652,10 +652,10 @@ static int dw8250_probe(struct platform_
+ if (err)
+ return err;
+
+- data->rst = devm_reset_control_get_optional_exclusive(dev, NULL);
+- if (IS_ERR(data->rst))
+- return PTR_ERR(data->rst);
+-
++ data->rst = devm_reset_control_array_get_exclusive(dev);
++ if (IS_ERR(data->rst)) {
++ err = PTR_ERR(data->rst);
++ }
+ reset_control_deassert(data->rst);
+
+ err = devm_add_action_or_reset(dev, dw8250_reset_control_assert, data->rst);
diff --git a/target/linux/starfive/patches-6.6/0068-uart-8250-add-reset-operation-in-runtime-PM.patch b/target/linux/starfive/patches-6.6/0068-uart-8250-add-reset-operation-in-runtime-PM.patch
new file mode 100644
index 0000000000..56efebda6c
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0068-uart-8250-add-reset-operation-in-runtime-PM.patch
@@ -0,0 +1,32 @@
+From 777d288f03a0b350f6c2d4367b01a80d9f25cd6e Mon Sep 17 00:00:00 2001
+From: William Qiu <william.qiu@starfivetech.com>
+Date: Wed, 20 Sep 2023 17:19:59 +0800
+Subject: [PATCH 068/116] uart: 8250: add reset operation in runtime PM
+
+add reset operation in runtime PM
+
+Signed-off-by: William Qiu <william.qiu@starfivetech.com>
+---
+ drivers/tty/serial/8250/8250_dw.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/tty/serial/8250/8250_dw.c
++++ b/drivers/tty/serial/8250/8250_dw.c
+@@ -745,6 +745,8 @@ static int dw8250_runtime_suspend(struct
+ {
+ struct dw8250_data *data = dev_get_drvdata(dev);
+
++ reset_control_assert(data->rst);
++
+ clk_disable_unprepare(data->clk);
+
+ clk_disable_unprepare(data->pclk);
+@@ -760,6 +762,8 @@ static int dw8250_runtime_resume(struct
+
+ clk_prepare_enable(data->clk);
+
++ reset_control_deassert(data->rst);
++
+ return 0;
+ }
+
diff --git a/target/linux/starfive/patches-6.6/0069-dt-bindings-CAN-Add-StarFive-CAN-module.patch b/target/linux/starfive/patches-6.6/0069-dt-bindings-CAN-Add-StarFive-CAN-module.patch
new file mode 100644
index 0000000000..eb46a96314
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0069-dt-bindings-CAN-Add-StarFive-CAN-module.patch
@@ -0,0 +1,113 @@
+From 5eda2331a252436756fb40861f01a7a38b1502c7 Mon Sep 17 00:00:00 2001
+From: William Qiu <william.qiu@starfivetech.com>
+Date: Thu, 15 Jun 2023 20:14:22 +0800
+Subject: [PATCH 069/116] dt-bindings: CAN: Add StarFive CAN module
+
+Add documentation to describe StarFive CAN engine.
+
+Signed-off-by: William Qiu <william.qiu@starfivetech.com>
+---
+ .../devicetree/bindings/net/can/ipms-can.yaml | 97 +++++++++++++++++++
+ 1 file changed, 97 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/net/can/ipms-can.yaml
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/net/can/ipms-can.yaml
+@@ -0,0 +1,97 @@
++# SPDX-License-Identifier: GPL-2.0
++%YAML 1.2
++---
++#$id: http://devicetree.org/schemas/net/can/ipms-can.yaml#
++#$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: IPMS CAN/CANFD controller Device Tree Bindings
++
++properties:
++ compatible:
++ const:ipms,can
++
++ reg:
++ maxItems: 1
++ items:
++ - description:CAN controller registers
++
++ interrupts:
++ maxItems: 1
++
++ clocks:
++ minItems: 1
++ items:
++ - description:apb_clk clock
++ - description:core_clk clock
++ - description:timer_clk clock
++
++ clock-names:
++ minItems: 1
++ items:
++ - const:apb_clk
++ - const:core_clk
++ - const:timer_clk
++ resets:
++ minItems: 1
++ items:
++ - description:apb_clk reset
++ - description:core_clk reset
++ - description:timer_clk reset
++ reset-names:
++ minItems: 1
++ items:
++ - const:rst_apb
++ - const:rst_core
++ - const:rst_timer
++ starfive,sys-syscon:
++ format:
++ starfive,sys-syscon = <&arg0 arg1 arg2 arg3>
++ description:
++ arg0:arg0 is sys_syscon.
++ arg1:arg1 is syscon register offset, used to enable can2.0/canfd function, can0 is 0x10, can1 is 0x88.
++ arg2:arg2 is used to enable the register shift of the can2.0/canfd function, can0 is 0x3, can1 is 0x12.
++ arg3:arg3 is used to enable the register mask of the can2.0/canfd function, can0 is 0x8, can1 is 0x40000
++
++ syscon,can_or_canfd:
++ description:
++ IPMS CAN-CTRL core is a serial communications controller that performs serial communication according to the CAN protocol.
++ This CAN bus interface uses the basic CAN principle and meets all constraints of the CAN-specification 2.0B active.
++ Furthermore this CAN core can be configured to meet the specification of CAN with flexible data rate CAN FD.
++ When syscon,can_or_canfd is set to 0, use CAN2.0B.
++ when syscon,can_or_canfd is set to 1, use CAN FD.
++required:
++ - compatible
++ - reg
++ - interrupts
++ - clocks
++ - clock-names
++ - resets
++ - reset-names
++ - starfive,sys-syscon
++ - syscon,can_or_canfd
++additionalProperties:false
++
++examples:
++ - |
++ can0: can@130d0000{
++ compatible = "ipms,can";
++ reg = <0x0 0x130d0000 0x0 0x1000>;
++ interrupts = <112>;
++ interrupt-parent = <&plic>;
++ clocks = <&clkgen JH7110_CAN0_CTRL_CLK_APB>,
++ <&clkgen JH7110_CAN0_CTRL_CLK_CAN>,
++ <&clkgen JH7110_CAN0_CTRL_CLK_TIMER>;
++ clock-names = "apb_clk",
++ "core_clk",
++ "timer_clk";
++ resets = <&rstgen RSTN_U0_CAN_CTRL_APB>,
++ <&rstgen RSTN_U0_CAN_CTRL_CORE>,
++ <&rstgen RSTN_U0_CAN_CTRL_TIMER>;
++ reset-names = "rst_apb",
++ "rst_core",
++ "rst_timer";
++ starfive,sys-syscon = <&sys_syscon, 0x10 0x3 0x8>;
++ syscon,can_or_canfd = <0>;
++ };
++
++...
diff --git a/target/linux/starfive/patches-6.6/0070-CAN-starfive-Add-CAN-engine-support.patch b/target/linux/starfive/patches-6.6/0070-CAN-starfive-Add-CAN-engine-support.patch
new file mode 100644
index 0000000000..1bb41dd079
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0070-CAN-starfive-Add-CAN-engine-support.patch
@@ -0,0 +1,1317 @@
+From b1fbe15b87be654b1b280a76ec1470917d79f720 Mon Sep 17 00:00:00 2001
+From: William Qiu <william.qiu@starfivetech.com>
+Date: Thu, 15 Jun 2023 20:15:25 +0800
+Subject: [PATCH 070/116] CAN: starfive - Add CAN engine support
+
+Adding device probe StarFive CAN module.
+
+Signed-off-by: William Qiu <william.qiu@starfivetech.com>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ drivers/net/can/Kconfig | 5 +
+ drivers/net/can/Makefile | 1 +
+ drivers/net/can/ipms_canfd.c | 1275 ++++++++++++++++++++++++++++++++++
+ 3 files changed, 1281 insertions(+)
+ create mode 100644 drivers/net/can/ipms_canfd.c
+
+--- a/drivers/net/can/Kconfig
++++ b/drivers/net/can/Kconfig
+@@ -214,6 +214,11 @@ config CAN_XILINXCAN
+ Xilinx CAN driver. This driver supports both soft AXI CAN IP and
+ Zynq CANPS IP.
+
++config IPMS_CAN
++ tristate "IPMS CAN"
++ help
++ IPMS CANFD driver. This driver supports IPMS CANFD IP.
++
+ source "drivers/net/can/c_can/Kconfig"
+ source "drivers/net/can/cc770/Kconfig"
+ source "drivers/net/can/ctucanfd/Kconfig"
+--- a/drivers/net/can/Makefile
++++ b/drivers/net/can/Makefile
+@@ -31,5 +31,6 @@ obj-$(CONFIG_CAN_SJA1000) += sja1000/
+ obj-$(CONFIG_CAN_SUN4I) += sun4i_can.o
+ obj-$(CONFIG_CAN_TI_HECC) += ti_hecc.o
+ obj-$(CONFIG_CAN_XILINXCAN) += xilinx_can.o
++obj-$(CONFIG_IPMS_CAN) += ipms_canfd.o
+
+ subdir-ccflags-$(CONFIG_CAN_DEBUG_DEVICES) += -DDEBUG
+--- /dev/null
++++ b/drivers/net/can/ipms_canfd.c
+@@ -0,0 +1,1275 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * StarFive Controller Area Network Host Controller Driver
++ *
++ * Copyright (c) 2022 StarFive Technology Co., Ltd.
++ */
++
++#include <linux/clk.h>
++#include <linux/reset.h>
++#include <linux/errno.h>
++#include <linux/init.h>
++#include <linux/interrupt.h>
++#include <linux/io.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/netdevice.h>
++#include <linux/of.h>
++#include <linux/platform_device.h>
++#include <linux/skbuff.h>
++#include <linux/string.h>
++#include <linux/types.h>
++#include <linux/can/dev.h>
++#include <linux/can/error.h>
++#include <linux/pm_runtime.h>
++#include <linux/of_device.h>
++#include <linux/mfd/syscon.h>
++#include <linux/regmap.h>
++
++#define DRIVER_NAME "ipms_canfd"
++
++/* CAN registers set */
++enum canfd_device_reg {
++ CANFD_RUBF_OFFSET = 0x00, /* Receive Buffer Registers 0x00-0x4f */
++ CANFD_RUBF_ID_OFFSET = 0x00,
++ CANFD_RBUF_CTL_OFFSET = 0x04,
++ CANFD_RBUF_DATA_OFFSET = 0x08,
++ CANFD_TBUF_OFFSET = 0x50, /* Transmit Buffer Registers 0x50-0x97 */
++ CANFD_TBUF_ID_OFFSET = 0x50,
++ CANFD_TBUF_CTL_OFFSET = 0x54,
++ CANFD_TBUF_DATA_OFFSET = 0x58,
++ CANFD_TTS_OFFSET = 0x98, /* Transmission Time Stamp 0x98-0x9f */
++ CANFD_CFG_STAT_OFFSET = 0xa0,
++ CANFD_TCMD_OFFSET = 0xa1,
++ CANFD_TCTRL_OFFSET = 0xa2,
++ CANFD_RCTRL_OFFSET = 0xa3,
++ CANFD_RTIE_OFFSET = 0xa4,
++ CANFD_RTIF_OFFSET = 0xa5,
++ CANFD_ERRINT_OFFSET = 0xa6,
++ CANFD_LIMIT_OFFSET = 0xa7,
++ CANFD_S_SEG_1_OFFSET = 0xa8,
++ CANFD_S_SEG_2_OFFSET = 0xa9,
++ CANFD_S_SJW_OFFSET = 0xaa,
++ CANFD_S_PRESC_OFFSET = 0xab,
++ CANFD_F_SEG_1_OFFSET = 0xac,
++ CANFD_F_SEG_2_OFFSET = 0xad,
++ CANFD_F_SJW_OFFSET = 0xae,
++ CANFD_F_PRESC_OFFSET = 0xaf,
++ CANFD_EALCAP_OFFSET = 0xb0,
++ CANFD_RECNT_OFFSET = 0xb2,
++ CANFD_TECNT_OFFSET = 0xb3,
++};
++
++enum canfd_reg_bitchange {
++ CAN_FD_SET_RST_MASK = 0x80, /* Set Reset Bit */
++ CAN_FD_OFF_RST_MASK = 0x7f, /* Reset Off Bit */
++ CAN_FD_SET_FULLCAN_MASK = 0x10, /* set TTTBM as 1->full TTCAN mode */
++ CAN_FD_OFF_FULLCAN_MASK = 0xef, /* set TTTBM as 0->separate PTB and STB mode */
++ CAN_FD_SET_FIFO_MASK = 0x20, /* set TSMODE as 1->FIFO mode */
++ CAN_FD_OFF_FIFO_MASK = 0xdf, /* set TSMODE as 0->Priority mode */
++ CAN_FD_SET_TSONE_MASK = 0x04,
++ CAN_FD_OFF_TSONE_MASK = 0xfb,
++ CAN_FD_SET_TSALL_MASK = 0x02,
++ CAN_FD_OFF_TSALL_MASK = 0xfd,
++ CAN_FD_LBMEMOD_MASK = 0x40, /* set loop back mode, external */
++ CAN_FD_LBMIMOD_MASK = 0x20, /* set loopback internal mode */
++ CAN_FD_SET_BUSOFF_MASK = 0x01,
++ CAN_FD_OFF_BUSOFF_MASK = 0xfe,
++ CAN_FD_SET_TTSEN_MASK = 0x80, /* set ttsen, tts update enable */
++ CAN_FD_SET_BRS_MASK = 0x10, /* can fd Bit Rate Switch mask */
++ CAN_FD_OFF_BRS_MASK = 0xef,
++ CAN_FD_SET_EDL_MASK = 0x20, /* Extended Data Length */
++ CAN_FD_OFF_EDL_MASK = 0xdf,
++ CAN_FD_SET_DLC_MASK = 0x0f,
++ CAN_FD_SET_TENEXT_MASK = 0x40,
++ CAN_FD_SET_IDE_MASK = 0x80,
++ CAN_FD_OFF_IDE_MASK = 0x7f,
++ CAN_FD_SET_RTR_MASK = 0x40,
++ CAN_FD_OFF_RTR_MASK = 0xbf,
++ CAN_FD_INTR_ALL_MASK = 0xff, /* all interrupts enable mask */
++ CAN_FD_SET_RIE_MASK = 0x80,
++ CAN_FD_OFF_RIE_MASK = 0x7f,
++ CAN_FD_SET_RFIE_MASK = 0x20,
++ CAN_FD_OFF_RFIE_MASK = 0xdf,
++ CAN_FD_SET_RAFIE_MASK = 0x10,
++ CAN_FD_OFF_RAFIE_MASK = 0xef,
++ CAN_FD_SET_EIE_MASK = 0x02,
++ CAN_FD_OFF_EIE_MASK = 0xfd,
++ CAN_FD_TASCTIVE_MASK = 0x02,
++ CAN_FD_RASCTIVE_MASK = 0x04,
++ CAN_FD_SET_TBSEL_MASK = 0x80, /* message writen in STB */
++ CAN_FD_OFF_TBSEL_MASK = 0x7f, /* message writen in PTB */
++ CAN_FD_SET_STBY_MASK = 0x20,
++ CAN_FD_OFF_STBY_MASK = 0xdf,
++ CAN_FD_SET_TPE_MASK = 0x10, /* Transmit primary enable */
++ CAN_FD_SET_TPA_MASK = 0x08,
++ CAN_FD_SET_SACK_MASK = 0x80,
++ CAN_FD_SET_RREL_MASK = 0x10,
++ CAN_FD_RSTAT_NOT_EMPTY_MASK = 0x03,
++ CAN_FD_SET_RIF_MASK = 0x80,
++ CAN_FD_OFF_RIF_MASK = 0x7f,
++ CAN_FD_SET_RAFIF_MASK = 0x10,
++ CAN_FD_SET_RFIF_MASK = 0x20,
++ CAN_FD_SET_TPIF_MASK = 0x08, /* Transmission Primary Interrupt Flag */
++ CAN_FD_SET_TSIF_MASK = 0x04,
++ CAN_FD_SET_EIF_MASK = 0x02,
++ CAN_FD_SET_AIF_MASK = 0x01,
++ CAN_FD_SET_EWARN_MASK = 0x80,
++ CAN_FD_SET_EPASS_MASK = 0x40,
++ CAN_FD_SET_EPIE_MASK = 0x20,
++ CAN_FD_SET_EPIF_MASK = 0x10,
++ CAN_FD_SET_ALIE_MASK = 0x08,
++ CAN_FD_SET_ALIF_MASK = 0x04,
++ CAN_FD_SET_BEIE_MASK = 0x02,
++ CAN_FD_SET_BEIF_MASK = 0x01,
++ CAN_FD_OFF_EPIE_MASK = 0xdf,
++ CAN_FD_OFF_BEIE_MASK = 0xfd,
++ CAN_FD_SET_AFWL_MASK = 0x40,
++ CAN_FD_SET_EWL_MASK = 0x0b,
++ CAN_FD_SET_KOER_MASK = 0xe0,
++ CAN_FD_SET_BIT_ERROR_MASK = 0x20,
++ CAN_FD_SET_FORM_ERROR_MASK = 0x40,
++ CAN_FD_SET_STUFF_ERROR_MASK = 0x60,
++ CAN_FD_SET_ACK_ERROR_MASK = 0x80,
++ CAN_FD_SET_CRC_ERROR_MASK = 0xa0,
++ CAN_FD_SET_OTH_ERROR_MASK = 0xc0,
++};
++
++/* seg1,seg2,sjw,prescaler all have 8 bits */
++#define BITS_OF_BITTIMING_REG 8
++
++/* in can_bittiming strucure every field has 32 bits---->u32 */
++#define FBITS_IN_BITTIMING_STR 32
++#define SEG_1_SHIFT 0
++#define SEG_2_SHIFT 8
++#define SJW_SHIFT 16
++#define PRESC_SHIFT 24
++
++/* TTSEN bit used for 32 bit register read or write */
++#define TTSEN_8_32_SHIFT 24
++#define RTR_32_8_SHIFT 24
++
++/* transmit mode */
++#define XMIT_FULL 0
++#define XMIT_SEP_FIFO 1
++#define XMIT_SEP_PRIO 2
++#define XMIT_PTB_MODE 3
++
++enum IPMS_CAN_TYPE {
++ IPMS_CAN_TYPY_CAN = 0,
++ IPMS_CAN_TYPE_CANFD,
++};
++
++struct ipms_canfd_priv {
++ struct can_priv can;
++ struct napi_struct napi;
++ struct device *dev;
++ struct regmap *reg_syscon;
++ void __iomem *reg_base;
++ u32 (*read_reg)(const struct ipms_canfd_priv *priv, enum canfd_device_reg reg);
++ void (*write_reg)(const struct ipms_canfd_priv *priv, enum canfd_device_reg reg, u32 val);
++ struct clk *can_clk;
++ u32 tx_mode;
++ struct reset_control *resets;
++ struct clk_bulk_data *clks;
++ int nr_clks;
++ u32 can_or_canfd;
++};
++
++static struct can_bittiming_const canfd_bittiming_const = {
++ .name = DRIVER_NAME,
++ .tseg1_min = 2,
++ .tseg1_max = 16,
++ .tseg2_min = 2,
++ .tseg2_max = 8,
++ .sjw_max = 4,
++ .brp_min = 1,
++ .brp_max = 512,
++ .brp_inc = 1,
++
++};
++
++static struct can_bittiming_const canfd_data_bittiming_const = {
++ .name = DRIVER_NAME,
++ .tseg1_min = 1,
++ .tseg1_max = 16,
++ .tseg2_min = 2,
++ .tseg2_max = 8,
++ .sjw_max = 8,
++ .brp_min = 1,
++ .brp_max = 512,
++ .brp_inc = 1,
++};
++
++static void canfd_write_reg_le(const struct ipms_canfd_priv *priv,
++ enum canfd_device_reg reg, u32 val)
++{
++ iowrite32(val, priv->reg_base + reg);
++}
++
++static u32 canfd_read_reg_le(const struct ipms_canfd_priv *priv,
++ enum canfd_device_reg reg)
++{
++ return ioread32(priv->reg_base + reg);
++}
++
++static inline unsigned char can_ioread8(const void *addr)
++{
++ void *addr_down;
++ union val {
++ u8 val_8[4];
++ u32 val_32;
++ } val;
++ u32 offset = 0;
++
++ addr_down = (void *)ALIGN_DOWN((unsigned long)addr, 4);
++ offset = addr - addr_down;
++ val.val_32 = ioread32(addr_down);
++ return val.val_8[offset];
++}
++
++static inline void can_iowrite8(unsigned char value, void *addr)
++{
++ void *addr_down;
++ union val {
++ u8 val_8[4];
++ u32 val_32;
++ } val;
++ u8 offset = 0;
++
++ addr_down = (void *)ALIGN_DOWN((unsigned long)addr, 4);
++ offset = addr - addr_down;
++ val.val_32 = ioread32(addr_down);
++ val.val_8[offset] = value;
++ iowrite32(val.val_32, addr_down);
++}
++
++static void canfd_reigister_set_bit(const struct ipms_canfd_priv *priv,
++ enum canfd_device_reg reg,
++ enum canfd_reg_bitchange set_mask)
++{
++ void *addr_down;
++ union val {
++ u8 val_8[4];
++ u32 val_32;
++ } val;
++ u8 offset = 0;
++
++ addr_down = (void *)ALIGN_DOWN((unsigned long)(priv->reg_base + reg), 4);
++ offset = (priv->reg_base + reg) - addr_down;
++ val.val_32 = ioread32(addr_down);
++ val.val_8[offset] |= set_mask;
++ iowrite32(val.val_32, addr_down);
++}
++
++static void canfd_reigister_off_bit(const struct ipms_canfd_priv *priv,
++ enum canfd_device_reg reg,
++ enum canfd_reg_bitchange set_mask)
++{
++ void *addr_down;
++ union val {
++ u8 val_8[4];
++ u32 val_32;
++ } val;
++ u8 offset = 0;
++
++ addr_down = (void *)ALIGN_DOWN((unsigned long)(priv->reg_base + reg), 4);
++ offset = (priv->reg_base + reg) - addr_down;
++ val.val_32 = ioread32(addr_down);
++ val.val_8[offset] &= set_mask;
++ iowrite32(val.val_32, addr_down);
++}
++
++static int canfd_device_driver_bittime_configuration(struct net_device *ndev)
++{
++ struct ipms_canfd_priv *priv = netdev_priv(ndev);
++ struct can_bittiming *bt = &priv->can.bittiming;
++ struct can_bittiming *dbt = &priv->can.data_bittiming;
++ u32 reset_test, bittiming_temp, dat_bittiming;
++
++ reset_test = can_ioread8(priv->reg_base + CANFD_CFG_STAT_OFFSET);
++
++ if (!(reset_test & CAN_FD_SET_RST_MASK)) {
++ netdev_alert(ndev, "Not in reset mode, cannot set bit timing\n");
++ return -EPERM;
++ }
++
++ bittiming_temp = ((bt->phase_seg1 + bt->prop_seg + 1 - 2) << SEG_1_SHIFT) |
++ ((bt->phase_seg2 - 1) << SEG_2_SHIFT) |
++ ((bt->sjw - 1) << SJW_SHIFT) |
++ ((bt->brp - 1) << PRESC_SHIFT);
++
++ /* Check the bittime parameter */
++ if ((((int)(bt->phase_seg1 + bt->prop_seg + 1) - 2) < 0) ||
++ (((int)(bt->phase_seg2) - 1) < 0) ||
++ (((int)(bt->sjw) - 1) < 0) ||
++ (((int)(bt->brp) - 1) < 0))
++ return -EINVAL;
++
++ priv->write_reg(priv, CANFD_S_SEG_1_OFFSET, bittiming_temp);
++
++ if (priv->can_or_canfd == IPMS_CAN_TYPE_CANFD) {
++ dat_bittiming = ((dbt->phase_seg1 + dbt->prop_seg + 1 - 2) << SEG_1_SHIFT) |
++ ((dbt->phase_seg2 - 1) << SEG_2_SHIFT) |
++ ((dbt->sjw - 1) << SJW_SHIFT) |
++ ((dbt->brp - 1) << PRESC_SHIFT);
++
++ if ((((int)(dbt->phase_seg1 + dbt->prop_seg + 1) - 2) < 0) ||
++ (((int)(dbt->phase_seg2) - 1) < 0) ||
++ (((int)(dbt->sjw) - 1) < 0) ||
++ (((int)(dbt->brp) - 1) < 0))
++ return -EINVAL;
++
++ priv->write_reg(priv, CANFD_F_SEG_1_OFFSET, dat_bittiming);
++ }
++
++ canfd_reigister_off_bit(priv, CANFD_CFG_STAT_OFFSET, CAN_FD_OFF_RST_MASK);
++
++ netdev_dbg(ndev, "Slow bit rate: %08x\n", priv->read_reg(priv, CANFD_S_SEG_1_OFFSET));
++ netdev_dbg(ndev, "Fast bit rate: %08x\n", priv->read_reg(priv, CANFD_F_SEG_1_OFFSET));
++
++ return 0;
++}
++
++int canfd_get_freebuffer(struct ipms_canfd_priv *priv)
++{
++ /* Get next transmit buffer */
++ canfd_reigister_set_bit(priv, CANFD_TCTRL_OFFSET, CAN_FD_SET_TENEXT_MASK);
++
++ if (can_ioread8(priv->reg_base + CANFD_TCTRL_OFFSET) & CAN_FD_SET_TENEXT_MASK)
++ return -1;
++
++ return 0;
++}
++
++static void canfd_tx_interrupt(struct net_device *ndev, u8 isr)
++{
++ struct ipms_canfd_priv *priv = netdev_priv(ndev);
++
++ /* wait till transmission of the PTB or STB finished */
++ while (isr & (CAN_FD_SET_TPIF_MASK | CAN_FD_SET_TSIF_MASK)) {
++ if (isr & CAN_FD_SET_TPIF_MASK)
++ canfd_reigister_set_bit(priv, CANFD_RTIF_OFFSET, CAN_FD_SET_TPIF_MASK);
++
++ if (isr & CAN_FD_SET_TSIF_MASK)
++ canfd_reigister_set_bit(priv, CANFD_RTIF_OFFSET, CAN_FD_SET_TSIF_MASK);
++
++ isr = can_ioread8(priv->reg_base + CANFD_RTIF_OFFSET);
++ }
++ netif_wake_queue(ndev);
++}
++
++static int can_rx(struct net_device *ndev)
++{
++ struct ipms_canfd_priv *priv = netdev_priv(ndev);
++ struct net_device_stats *stats = &ndev->stats;
++ struct can_frame *cf;
++ struct sk_buff *skb;
++ u32 can_id;
++ u8 dlc, control, rx_status;
++
++ rx_status = can_ioread8(priv->reg_base + CANFD_RCTRL_OFFSET);
++
++ if (!(rx_status & CAN_FD_RSTAT_NOT_EMPTY_MASK))
++ return 0;
++ control = can_ioread8(priv->reg_base + CANFD_RBUF_CTL_OFFSET);
++ can_id = priv->read_reg(priv, CANFD_RUBF_ID_OFFSET);
++ dlc = can_ioread8(priv->reg_base + CANFD_RBUF_CTL_OFFSET) & CAN_FD_SET_DLC_MASK;
++
++ skb = alloc_can_skb(ndev, (struct can_frame **)&cf);
++ if (!skb) {
++ stats->rx_dropped++;
++ return 0;
++ }
++ cf->can_dlc = can_cc_dlc2len(dlc);
++
++ /* change the CANFD id into socketcan id format */
++ if (control & CAN_FD_SET_IDE_MASK) {
++ cf->can_id = can_id;
++ cf->can_id |= CAN_EFF_FLAG;
++ } else {
++ cf->can_id = can_id;
++ cf->can_id &= (~CAN_EFF_FLAG);
++ }
++
++ if (control & CAN_FD_SET_RTR_MASK)
++ cf->can_id |= CAN_RTR_FLAG;
++
++ if (!(control & CAN_FD_SET_RTR_MASK)) {
++ *((u32 *)(cf->data + 0)) = priv->read_reg(priv, CANFD_RBUF_DATA_OFFSET);
++ *((u32 *)(cf->data + 4)) = priv->read_reg(priv, CANFD_RBUF_DATA_OFFSET + 4);
++ }
++
++ canfd_reigister_set_bit(priv, CANFD_RCTRL_OFFSET, CAN_FD_SET_RREL_MASK);
++ stats->rx_bytes += can_fd_dlc2len(cf->can_dlc);
++ stats->rx_packets++;
++ netif_receive_skb(skb);
++
++ return 1;
++}
++
++static int canfd_rx(struct net_device *ndev)
++{
++ struct ipms_canfd_priv *priv = netdev_priv(ndev);
++ struct net_device_stats *stats = &ndev->stats;
++ struct canfd_frame *cf;
++ struct sk_buff *skb;
++ u32 can_id;
++ u8 dlc, control, rx_status;
++ int i;
++
++ rx_status = can_ioread8(priv->reg_base + CANFD_RCTRL_OFFSET);
++
++ if (!(rx_status & CAN_FD_RSTAT_NOT_EMPTY_MASK))
++ return 0;
++ control = can_ioread8(priv->reg_base + CANFD_RBUF_CTL_OFFSET);
++ can_id = priv->read_reg(priv, CANFD_RUBF_ID_OFFSET);
++ dlc = can_ioread8(priv->reg_base + CANFD_RBUF_CTL_OFFSET) & CAN_FD_SET_DLC_MASK;
++
++ if (control & CAN_FD_SET_EDL_MASK)
++ /* allocate sk_buffer for canfd frame */
++ skb = alloc_canfd_skb(ndev, &cf);
++ else
++ /* allocate sk_buffer for can frame */
++ skb = alloc_can_skb(ndev, (struct can_frame **)&cf);
++
++ if (!skb) {
++ stats->rx_dropped++;
++ return 0;
++ }
++
++ /* change the CANFD or CAN2.0 data into socketcan data format */
++ if (control & CAN_FD_SET_EDL_MASK)
++ cf->len = can_fd_dlc2len(dlc);
++ else
++ cf->len = can_cc_dlc2len(dlc);
++
++ /* change the CANFD id into socketcan id format */
++ if (control & CAN_FD_SET_EDL_MASK) {
++ cf->can_id = can_id;
++ if (control & CAN_FD_SET_IDE_MASK)
++ cf->can_id |= CAN_EFF_FLAG;
++ else
++ cf->can_id &= (~CAN_EFF_FLAG);
++ } else {
++ cf->can_id = can_id;
++ if (control & CAN_FD_SET_IDE_MASK)
++ cf->can_id |= CAN_EFF_FLAG;
++ else
++ cf->can_id &= (~CAN_EFF_FLAG);
++
++ if (control & CAN_FD_SET_RTR_MASK)
++ cf->can_id |= CAN_RTR_FLAG;
++ }
++
++ /* CANFD frames handed over to SKB */
++ if (control & CAN_FD_SET_EDL_MASK) {
++ for (i = 0; i < cf->len; i += 4)
++ *((u32 *)(cf->data + i)) = priv->read_reg(priv, CANFD_RBUF_DATA_OFFSET + i);
++ } else {
++ /* skb reads the received datas, if the RTR bit not set */
++ if (!(control & CAN_FD_SET_RTR_MASK)) {
++ *((u32 *)(cf->data + 0)) = priv->read_reg(priv, CANFD_RBUF_DATA_OFFSET);
++ *((u32 *)(cf->data + 4)) = priv->read_reg(priv, CANFD_RBUF_DATA_OFFSET + 4);
++ }
++ }
++
++ canfd_reigister_set_bit(priv, CANFD_RCTRL_OFFSET, CAN_FD_SET_RREL_MASK);
++
++ stats->rx_bytes += cf->len;
++ stats->rx_packets++;
++ netif_receive_skb(skb);
++
++ return 1;
++}
++
++static int canfd_rx_poll(struct napi_struct *napi, int quota)
++{
++ struct net_device *ndev = napi->dev;
++ struct ipms_canfd_priv *priv = netdev_priv(ndev);
++ int work_done = 0;
++ u8 rx_status = 0, control = 0;
++
++ control = can_ioread8(priv->reg_base + CANFD_RBUF_CTL_OFFSET);
++ rx_status = can_ioread8(priv->reg_base + CANFD_RCTRL_OFFSET);
++
++ /* clear receive interrupt and deal with all the received frames */
++ while ((rx_status & CAN_FD_RSTAT_NOT_EMPTY_MASK) && (work_done < quota)) {
++ (control & CAN_FD_SET_EDL_MASK) ? (work_done += canfd_rx(ndev)) : (work_done += can_rx(ndev));
++
++ control = can_ioread8(priv->reg_base + CANFD_RBUF_CTL_OFFSET);
++ rx_status = can_ioread8(priv->reg_base + CANFD_RCTRL_OFFSET);
++ }
++ napi_complete(napi);
++ canfd_reigister_set_bit(priv, CANFD_RTIE_OFFSET, CAN_FD_SET_RIE_MASK);
++ return work_done;
++}
++
++static void canfd_rxfull_interrupt(struct net_device *ndev, u8 isr)
++{
++ struct ipms_canfd_priv *priv = netdev_priv(ndev);
++
++ if (isr & CAN_FD_SET_RAFIF_MASK)
++ canfd_reigister_set_bit(priv, CANFD_RTIF_OFFSET, CAN_FD_SET_RAFIF_MASK);
++
++ if (isr & (CAN_FD_SET_RAFIF_MASK | CAN_FD_SET_RFIF_MASK))
++ canfd_reigister_set_bit(priv, CANFD_RTIF_OFFSET,
++ (CAN_FD_SET_RAFIF_MASK | CAN_FD_SET_RFIF_MASK));
++}
++
++static int set_canfd_xmit_mode(struct net_device *ndev)
++{
++ struct ipms_canfd_priv *priv = netdev_priv(ndev);
++
++ switch (priv->tx_mode) {
++ case XMIT_FULL:
++ canfd_reigister_set_bit(priv, CANFD_TCTRL_OFFSET, CAN_FD_SET_FULLCAN_MASK);
++ break;
++ case XMIT_SEP_FIFO:
++ canfd_reigister_off_bit(priv, CANFD_TCTRL_OFFSET, CAN_FD_OFF_FULLCAN_MASK);
++ canfd_reigister_set_bit(priv, CANFD_TCTRL_OFFSET, CAN_FD_SET_FIFO_MASK);
++ canfd_reigister_off_bit(priv, CANFD_TCMD_OFFSET, CAN_FD_SET_TBSEL_MASK);
++ break;
++ case XMIT_SEP_PRIO:
++ canfd_reigister_off_bit(priv, CANFD_TCTRL_OFFSET, CAN_FD_OFF_FULLCAN_MASK);
++ canfd_reigister_off_bit(priv, CANFD_TCTRL_OFFSET, CAN_FD_OFF_FIFO_MASK);
++ canfd_reigister_off_bit(priv, CANFD_TCMD_OFFSET, CAN_FD_SET_TBSEL_MASK);
++ break;
++ case XMIT_PTB_MODE:
++ canfd_reigister_off_bit(priv, CANFD_TCMD_OFFSET, CAN_FD_OFF_TBSEL_MASK);
++ break;
++ default:
++ break;
++ }
++ return 0;
++}
++
++static netdev_tx_t canfd_driver_start_xmit(struct sk_buff *skb, struct net_device *ndev)
++{
++ struct ipms_canfd_priv *priv = netdev_priv(ndev);
++ struct canfd_frame *cf = (struct canfd_frame *)skb->data;
++ struct net_device_stats *stats = &ndev->stats;
++ u32 ttsen, id, ctl, addr_off;
++ int i;
++
++ priv->tx_mode = XMIT_PTB_MODE;
++
++ if (can_dropped_invalid_skb(ndev, skb))
++ return NETDEV_TX_OK;
++
++ switch (priv->tx_mode) {
++ case XMIT_FULL:
++ return NETDEV_TX_BUSY;
++ case XMIT_PTB_MODE:
++ set_canfd_xmit_mode(ndev);
++ canfd_reigister_off_bit(priv, CANFD_TCMD_OFFSET, CAN_FD_OFF_STBY_MASK);
++
++ if (cf->can_id & CAN_EFF_FLAG) {
++ id = (cf->can_id & CAN_EFF_MASK);
++ ttsen = 0 << TTSEN_8_32_SHIFT;
++ id |= ttsen;
++ } else {
++ id = (cf->can_id & CAN_SFF_MASK);
++ ttsen = 0 << TTSEN_8_32_SHIFT;
++ id |= ttsen;
++ }
++
++ ctl = can_fd_len2dlc(cf->len);
++
++ /* transmit can fd frame */
++ if (priv->can_or_canfd == IPMS_CAN_TYPE_CANFD) {
++ if (can_is_canfd_skb(skb)) {
++ if (cf->can_id & CAN_EFF_FLAG)
++ ctl |= CAN_FD_SET_IDE_MASK;
++ else
++ ctl &= CAN_FD_OFF_IDE_MASK;
++
++ if (cf->flags & CANFD_BRS)
++ ctl |= CAN_FD_SET_BRS_MASK;
++
++ ctl |= CAN_FD_SET_EDL_MASK;
++
++ addr_off = CANFD_TBUF_DATA_OFFSET;
++
++ for (i = 0; i < cf->len; i += 4) {
++ priv->write_reg(priv, addr_off,
++ *((u32 *)(cf->data + i)));
++ addr_off += 4;
++ }
++ } else {
++ ctl &= CAN_FD_OFF_EDL_MASK;
++ ctl &= CAN_FD_OFF_BRS_MASK;
++
++ if (cf->can_id & CAN_EFF_FLAG)
++ ctl |= CAN_FD_SET_IDE_MASK;
++ else
++ ctl &= CAN_FD_OFF_IDE_MASK;
++
++ if (cf->can_id & CAN_RTR_FLAG) {
++ ctl |= CAN_FD_SET_RTR_MASK;
++ priv->write_reg(priv,
++ CANFD_TBUF_ID_OFFSET, id);
++ priv->write_reg(priv,
++ CANFD_TBUF_CTL_OFFSET, ctl);
++ } else {
++ ctl &= CAN_FD_OFF_RTR_MASK;
++ addr_off = CANFD_TBUF_DATA_OFFSET;
++ priv->write_reg(priv, addr_off,
++ *((u32 *)(cf->data + 0)));
++ priv->write_reg(priv, addr_off + 4,
++ *((u32 *)(cf->data + 4)));
++ }
++ }
++ priv->write_reg(priv, CANFD_TBUF_ID_OFFSET, id);
++ priv->write_reg(priv, CANFD_TBUF_CTL_OFFSET, ctl);
++ addr_off = CANFD_TBUF_DATA_OFFSET;
++ } else {
++ ctl &= CAN_FD_OFF_EDL_MASK;
++ ctl &= CAN_FD_OFF_BRS_MASK;
++
++ if (cf->can_id & CAN_EFF_FLAG)
++ ctl |= CAN_FD_SET_IDE_MASK;
++ else
++ ctl &= CAN_FD_OFF_IDE_MASK;
++
++ if (cf->can_id & CAN_RTR_FLAG) {
++ ctl |= CAN_FD_SET_RTR_MASK;
++ priv->write_reg(priv, CANFD_TBUF_ID_OFFSET, id);
++ priv->write_reg(priv, CANFD_TBUF_CTL_OFFSET, ctl);
++ } else {
++ ctl &= CAN_FD_OFF_RTR_MASK;
++ priv->write_reg(priv, CANFD_TBUF_ID_OFFSET, id);
++ priv->write_reg(priv, CANFD_TBUF_CTL_OFFSET, ctl);
++ addr_off = CANFD_TBUF_DATA_OFFSET;
++ priv->write_reg(priv, addr_off,
++ *((u32 *)(cf->data + 0)));
++ priv->write_reg(priv, addr_off + 4,
++ *((u32 *)(cf->data + 4)));
++ }
++ }
++ canfd_reigister_set_bit(priv, CANFD_TCMD_OFFSET, CAN_FD_SET_TPE_MASK);
++ stats->tx_bytes += cf->len;
++ break;
++ default:
++ break;
++ }
++
++ /*Due to cache blocking, we need call dev_kfree_skb() here to free the socket
++ buffer and return NETDEV_TX_OK */
++ dev_kfree_skb(skb);
++
++ return NETDEV_TX_OK;
++}
++
++static int set_reset_mode(struct net_device *ndev)
++{
++ struct ipms_canfd_priv *priv = netdev_priv(ndev);
++ u8 ret;
++
++ ret = can_ioread8(priv->reg_base + CANFD_CFG_STAT_OFFSET);
++ ret |= CAN_FD_SET_RST_MASK;
++ can_iowrite8(ret, priv->reg_base + CANFD_CFG_STAT_OFFSET);
++
++ return 0;
++}
++
++static void canfd_driver_stop(struct net_device *ndev)
++{
++ struct ipms_canfd_priv *priv = netdev_priv(ndev);
++ int ret;
++
++ ret = set_reset_mode(ndev);
++ if (ret)
++ netdev_err(ndev, "Mode Resetting Failed!\n");
++
++ priv->can.state = CAN_STATE_STOPPED;
++}
++
++static int canfd_driver_close(struct net_device *ndev)
++{
++ struct ipms_canfd_priv *priv = netdev_priv(ndev);
++
++ netif_stop_queue(ndev);
++ napi_disable(&priv->napi);
++ canfd_driver_stop(ndev);
++
++ free_irq(ndev->irq, ndev);
++ close_candev(ndev);
++
++ pm_runtime_put(priv->dev);
++
++ return 0;
++}
++
++static enum can_state get_of_chip_status(struct net_device *ndev)
++{
++ struct ipms_canfd_priv *priv = netdev_priv(ndev);
++ u8 can_stat, eir;
++
++ can_stat = can_ioread8(priv->reg_base + CANFD_CFG_STAT_OFFSET);
++ eir = can_ioread8(priv->reg_base + CANFD_ERRINT_OFFSET);
++
++ if (can_stat & CAN_FD_SET_BUSOFF_MASK)
++ return CAN_STATE_BUS_OFF;
++
++ if ((eir & CAN_FD_SET_EPASS_MASK) && ~(can_stat & CAN_FD_SET_BUSOFF_MASK))
++ return CAN_STATE_ERROR_PASSIVE;
++
++ if (eir & CAN_FD_SET_EWARN_MASK && ~(eir & CAN_FD_SET_EPASS_MASK))
++ return CAN_STATE_ERROR_WARNING;
++
++ if (~(eir & CAN_FD_SET_EPASS_MASK))
++ return CAN_STATE_ERROR_ACTIVE;
++
++ return CAN_STATE_ERROR_ACTIVE;
++}
++
++static void canfd_error_interrupt(struct net_device *ndev, u8 isr, u8 eir)
++{
++ struct ipms_canfd_priv *priv = netdev_priv(ndev);
++ struct net_device_stats *stats = &ndev->stats;
++ struct can_frame *cf;
++ struct sk_buff *skb;
++ u8 koer, recnt = 0, tecnt = 0, can_stat = 0;
++
++ skb = alloc_can_err_skb(ndev, &cf);
++
++ koer = can_ioread8(priv->reg_base + CANFD_EALCAP_OFFSET) & CAN_FD_SET_KOER_MASK;
++ recnt = can_ioread8(priv->reg_base + CANFD_RECNT_OFFSET);
++ tecnt = can_ioread8(priv->reg_base + CANFD_TECNT_OFFSET);
++
++ /*Read can status*/
++ can_stat = can_ioread8(priv->reg_base + CANFD_CFG_STAT_OFFSET);
++
++ /* Bus off --->active error mode */
++ if ((isr & CAN_FD_SET_EIF_MASK) && priv->can.state == CAN_STATE_BUS_OFF)
++ priv->can.state = get_of_chip_status(ndev);
++
++ /* State selection */
++ if (can_stat & CAN_FD_SET_BUSOFF_MASK) {
++ priv->can.state = get_of_chip_status(ndev);
++ priv->can.can_stats.bus_off++;
++ canfd_reigister_set_bit(priv, CANFD_CFG_STAT_OFFSET, CAN_FD_SET_BUSOFF_MASK);
++ can_bus_off(ndev);
++ if (skb)
++ cf->can_id |= CAN_ERR_BUSOFF;
++
++ } else if ((eir & CAN_FD_SET_EPASS_MASK) && ~(can_stat & CAN_FD_SET_BUSOFF_MASK)) {
++ priv->can.state = get_of_chip_status(ndev);
++ priv->can.can_stats.error_passive++;
++ if (skb) {
++ cf->can_id |= CAN_ERR_CRTL;
++ cf->data[1] |= (recnt > 127) ? CAN_ERR_CRTL_RX_PASSIVE : 0;
++ cf->data[1] |= (tecnt > 127) ? CAN_ERR_CRTL_TX_PASSIVE : 0;
++ cf->data[6] = tecnt;
++ cf->data[7] = recnt;
++ }
++ } else if (eir & CAN_FD_SET_EWARN_MASK && ~(eir & CAN_FD_SET_EPASS_MASK)) {
++ priv->can.state = get_of_chip_status(ndev);
++ priv->can.can_stats.error_warning++;
++ if (skb) {
++ cf->can_id |= CAN_ERR_CRTL;
++ cf->data[1] |= (recnt > 95) ? CAN_ERR_CRTL_RX_WARNING : 0;
++ cf->data[1] |= (tecnt > 95) ? CAN_ERR_CRTL_TX_WARNING : 0;
++ cf->data[6] = tecnt;
++ cf->data[7] = recnt;
++ }
++ }
++
++ /* Check for in protocol defined error interrupt */
++ if (eir & CAN_FD_SET_BEIF_MASK) {
++ if (skb)
++ cf->can_id |= CAN_ERR_BUSERROR | CAN_ERR_PROT;
++
++ /* bit error interrupt */
++ if (koer == CAN_FD_SET_BIT_ERROR_MASK) {
++ stats->tx_errors++;
++ if (skb) {
++ cf->can_id |= CAN_ERR_PROT;
++ cf->data[2] = CAN_ERR_PROT_BIT;
++ }
++ }
++ /* format error interrupt */
++ if (koer == CAN_FD_SET_FORM_ERROR_MASK) {
++ stats->rx_errors++;
++ if (skb) {
++ cf->can_id |= CAN_ERR_PROT;
++ cf->data[2] = CAN_ERR_PROT_FORM;
++ }
++ }
++ /* stuffing error interrupt */
++ if (koer == CAN_FD_SET_STUFF_ERROR_MASK) {
++ stats->rx_errors++;
++ if (skb) {
++ cf->can_id |= CAN_ERR_PROT;
++ cf->data[3] = CAN_ERR_PROT_STUFF;
++ }
++ }
++ /* ack error interrupt */
++ if (koer == CAN_FD_SET_ACK_ERROR_MASK) {
++ stats->tx_errors++;
++ if (skb) {
++ cf->can_id |= CAN_ERR_PROT;
++ cf->data[2] = CAN_ERR_PROT_LOC_ACK;
++ }
++ }
++ /* crc error interrupt */
++ if (koer == CAN_FD_SET_CRC_ERROR_MASK) {
++ stats->rx_errors++;
++ if (skb) {
++ cf->can_id |= CAN_ERR_PROT;
++ cf->data[2] = CAN_ERR_PROT_LOC_CRC_SEQ;
++ }
++ }
++ priv->can.can_stats.bus_error++;
++ }
++ if (skb) {
++ stats->rx_packets++;
++ stats->rx_bytes += cf->can_dlc;
++ netif_rx(skb);
++ }
++
++ netdev_dbg(ndev, "Recnt is 0x%02x", can_ioread8(priv->reg_base + CANFD_RECNT_OFFSET));
++ netdev_dbg(ndev, "Tecnt is 0x%02x", can_ioread8(priv->reg_base + CANFD_TECNT_OFFSET));
++}
++
++static irqreturn_t canfd_interrupt(int irq, void *dev_id)
++{
++ struct net_device *ndev = (struct net_device *)dev_id;
++ struct ipms_canfd_priv *priv = netdev_priv(ndev);
++ u8 isr, eir;
++ u8 isr_handled = 0, eir_handled = 0;
++
++ /* read the value of interrupt status register */
++ isr = can_ioread8(priv->reg_base + CANFD_RTIF_OFFSET);
++
++ /* read the value of error interrupt register */
++ eir = can_ioread8(priv->reg_base + CANFD_ERRINT_OFFSET);
++
++ /* Check for Tx interrupt and Processing it */
++ if (isr & (CAN_FD_SET_TPIF_MASK | CAN_FD_SET_TSIF_MASK)) {
++ canfd_tx_interrupt(ndev, isr);
++ isr_handled |= (CAN_FD_SET_TPIF_MASK | CAN_FD_SET_TSIF_MASK);
++ }
++ if (isr & (CAN_FD_SET_RAFIF_MASK | CAN_FD_SET_RFIF_MASK)) {
++ canfd_rxfull_interrupt(ndev, isr);
++ isr_handled |= (CAN_FD_SET_RAFIF_MASK | CAN_FD_SET_RFIF_MASK);
++ }
++ /* Check Rx interrupt and Processing the receive interrupt routine */
++ if (isr & CAN_FD_SET_RIF_MASK) {
++ canfd_reigister_off_bit(priv, CANFD_RTIE_OFFSET, CAN_FD_OFF_RIE_MASK);
++ canfd_reigister_set_bit(priv, CANFD_RTIF_OFFSET, CAN_FD_SET_RIF_MASK);
++
++ napi_schedule(&priv->napi);
++ isr_handled |= CAN_FD_SET_RIF_MASK;
++ }
++ if ((isr & CAN_FD_SET_EIF_MASK) | (eir & (CAN_FD_SET_EPIF_MASK | CAN_FD_SET_BEIF_MASK))) {
++ /* reset EPIF and BEIF. Reset EIF */
++ canfd_reigister_set_bit(priv, CANFD_ERRINT_OFFSET,
++ eir & (CAN_FD_SET_EPIF_MASK | CAN_FD_SET_BEIF_MASK));
++ canfd_reigister_set_bit(priv, CANFD_RTIF_OFFSET,
++ isr & CAN_FD_SET_EIF_MASK);
++
++ canfd_error_interrupt(ndev, isr, eir);
++
++ isr_handled |= CAN_FD_SET_EIF_MASK;
++ eir_handled |= (CAN_FD_SET_EPIF_MASK | CAN_FD_SET_BEIF_MASK);
++ }
++ if ((isr_handled == 0) && (eir_handled == 0)) {
++ netdev_err(ndev, "Unhandled interrupt!\n");
++ return IRQ_NONE;
++ }
++
++ return IRQ_HANDLED;
++}
++
++static int canfd_chip_start(struct net_device *ndev)
++{
++ struct ipms_canfd_priv *priv = netdev_priv(ndev);
++ int err;
++ u8 ret;
++
++ err = set_reset_mode(ndev);
++ if (err) {
++ netdev_err(ndev, "Mode Resetting Failed!\n");
++ return err;
++ }
++
++ err = canfd_device_driver_bittime_configuration(ndev);
++ if (err) {
++ netdev_err(ndev, "Bittime Setting Failed!\n");
++ return err;
++ }
++
++ /* Set Almost Full Warning Limit */
++ canfd_reigister_set_bit(priv, CANFD_LIMIT_OFFSET, CAN_FD_SET_AFWL_MASK);
++
++ /* Programmable Error Warning Limit = (EWL+1)*8. Set EWL=11->Error Warning=96 */
++ canfd_reigister_set_bit(priv, CANFD_LIMIT_OFFSET, CAN_FD_SET_EWL_MASK);
++
++ /* Interrupts enable */
++ can_iowrite8(CAN_FD_INTR_ALL_MASK, priv->reg_base + CANFD_RTIE_OFFSET);
++
++ /* Error Interrupts enable(Error Passive and Bus Error) */
++ canfd_reigister_set_bit(priv, CANFD_ERRINT_OFFSET, CAN_FD_SET_EPIE_MASK);
++
++ ret = can_ioread8(priv->reg_base + CANFD_CFG_STAT_OFFSET);
++
++ /* Check whether it is loopback mode or normal mode */
++ if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) {
++ ret |= CAN_FD_LBMIMOD_MASK;
++ } else {
++ ret &= ~CAN_FD_LBMEMOD_MASK;
++ ret &= ~CAN_FD_LBMIMOD_MASK;
++ }
++
++ can_iowrite8(ret, priv->reg_base + CANFD_CFG_STAT_OFFSET);
++
++ priv->can.state = CAN_STATE_ERROR_ACTIVE;
++
++ return 0;
++}
++
++static int canfd_do_set_mode(struct net_device *ndev, enum can_mode mode)
++{
++ int ret;
++
++ switch (mode) {
++ case CAN_MODE_START:
++ ret = canfd_chip_start(ndev);
++ if (ret) {
++ netdev_err(ndev, "Could Not Start CAN device !!\n");
++ return ret;
++ }
++ netif_wake_queue(ndev);
++ break;
++ default:
++ ret = -EOPNOTSUPP;
++ break;
++ }
++
++ return ret;
++}
++
++static int canfd_driver_open(struct net_device *ndev)
++{
++ struct ipms_canfd_priv *priv = netdev_priv(ndev);
++ int ret;
++
++ ret = pm_runtime_get_sync(priv->dev);
++ if (ret < 0) {
++ netdev_err(ndev, "%s: pm_runtime_get failed(%d)\n",
++ __func__, ret);
++ goto err;
++ }
++
++ /* Set chip into reset mode */
++ ret = set_reset_mode(ndev);
++ if (ret) {
++ netdev_err(ndev, "Mode Resetting Failed!\n");
++ return ret;
++ }
++
++ /* Common open */
++ ret = open_candev(ndev);
++ if (ret)
++ return ret;
++
++ /* Register interrupt handler */
++ ret = request_irq(ndev->irq, canfd_interrupt, IRQF_SHARED, ndev->name, ndev);
++ if (ret) {
++ netdev_err(ndev, "Request_irq err: %d\n", ret);
++ goto exit_irq;
++ }
++
++ ret = canfd_chip_start(ndev);
++ if (ret) {
++ netdev_err(ndev, "Could Not Start CAN device !\n");
++ goto exit_can_start;
++ }
++
++ napi_enable(&priv->napi);
++ netif_start_queue(ndev);
++
++ return 0;
++
++exit_can_start:
++ free_irq(ndev->irq, ndev);
++err:
++ pm_runtime_put(priv->dev);
++exit_irq:
++ close_candev(ndev);
++ return ret;
++}
++
++static int canfd_control_parse_dt(struct ipms_canfd_priv *priv)
++{
++ struct of_phandle_args args;
++ u32 syscon_mask, syscon_shift;
++ u32 can_or_canfd;
++ u32 syscon_offset, regval;
++ int ret;
++
++ ret = of_parse_phandle_with_fixed_args(priv->dev->of_node,
++ "starfive,sys-syscon", 3, 0, &args);
++ if (ret) {
++ dev_err(priv->dev, "Failed to parse starfive,sys-syscon\n");
++ return -EINVAL;
++ }
++
++ priv->reg_syscon = syscon_node_to_regmap(args.np);
++ of_node_put(args.np);
++ if (IS_ERR(priv->reg_syscon))
++ return PTR_ERR(priv->reg_syscon);
++
++ syscon_offset = args.args[0];
++ syscon_shift = args.args[1];
++ syscon_mask = args.args[2];
++
++ ret = device_property_read_u32(priv->dev, "syscon,can_or_canfd", &can_or_canfd);
++ if (ret)
++ goto exit_parse;
++
++ priv->can_or_canfd = can_or_canfd;
++
++ /* enable can2.0/canfd function */
++ regval = can_or_canfd << syscon_shift;
++ ret = regmap_update_bits(priv->reg_syscon, syscon_offset, syscon_mask, regval);
++ if (ret)
++ return ret;
++ return 0;
++exit_parse:
++ return ret;
++}
++
++static const struct net_device_ops canfd_netdev_ops = {
++ .ndo_open = canfd_driver_open,
++ .ndo_stop = canfd_driver_close,
++ .ndo_start_xmit = canfd_driver_start_xmit,
++ .ndo_change_mtu = can_change_mtu,
++};
++
++static int canfd_driver_probe(struct platform_device *pdev)
++{
++ struct net_device *ndev;
++ struct ipms_canfd_priv *priv;
++ void __iomem *addr;
++ int ret;
++ u32 frq;
++
++ addr = devm_platform_ioremap_resource(pdev, 0);
++ if (IS_ERR(addr)) {
++ ret = PTR_ERR(addr);
++ goto exit;
++ }
++
++ ndev = alloc_candev(sizeof(struct ipms_canfd_priv), 1);
++ if (!ndev) {
++ ret = -ENOMEM;
++ goto exit;
++ }
++
++ priv = netdev_priv(ndev);
++ priv->dev = &pdev->dev;
++
++ ret = canfd_control_parse_dt(priv);
++ if (ret)
++ goto free_exit;
++
++ priv->nr_clks = devm_clk_bulk_get_all(priv->dev, &priv->clks);
++ if (priv->nr_clks < 0) {
++ dev_err(priv->dev, "Failed to get can clocks\n");
++ ret = -ENODEV;
++ goto free_exit;
++ }
++
++ ret = clk_bulk_prepare_enable(priv->nr_clks, priv->clks);
++ if (ret) {
++ dev_err(priv->dev, "Failed to enable clocks\n");
++ goto free_exit;
++ }
++
++ priv->resets = devm_reset_control_array_get_exclusive(priv->dev);
++ if (IS_ERR(priv->resets)) {
++ ret = PTR_ERR(priv->resets);
++ dev_err(priv->dev, "Failed to get can resets");
++ goto clk_exit;
++ }
++
++ ret = reset_control_deassert(priv->resets);
++ if (ret)
++ goto clk_exit;
++ priv->can.bittiming_const = &canfd_bittiming_const;
++ priv->can.data_bittiming_const = &canfd_data_bittiming_const;
++ priv->can.do_set_mode = canfd_do_set_mode;
++
++ /* in user space the execution mode can be chosen */
++ if (priv->can_or_canfd == IPMS_CAN_TYPE_CANFD)
++ priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK | CAN_CTRLMODE_FD;
++ else
++ priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK;
++ priv->reg_base = addr;
++ priv->write_reg = canfd_write_reg_le;
++ priv->read_reg = canfd_read_reg_le;
++
++ pm_runtime_enable(&pdev->dev);
++
++ priv->can_clk = devm_clk_get(&pdev->dev, "core_clk");
++ if (IS_ERR(priv->can_clk)) {
++ dev_err(&pdev->dev, "Device clock not found.\n");
++ ret = PTR_ERR(priv->can_clk);
++ goto reset_exit;
++ }
++
++ device_property_read_u32(priv->dev, "frequency", &frq);
++ clk_set_rate(priv->can_clk, frq);
++
++ priv->can.clock.freq = clk_get_rate(priv->can_clk);
++ ndev->irq = platform_get_irq(pdev, 0);
++
++ /* we support local echo */
++ ndev->flags |= IFF_ECHO;
++ ndev->netdev_ops = &canfd_netdev_ops;
++
++ platform_set_drvdata(pdev, ndev);
++ SET_NETDEV_DEV(ndev, &pdev->dev);
++
++ netif_napi_add(ndev, &priv->napi, canfd_rx_poll);
++ ret = register_candev(ndev);
++ if (ret) {
++ dev_err(&pdev->dev, "Fail to register failed (err=%d)\n", ret);
++ goto reset_exit;
++ }
++
++ dev_dbg(&pdev->dev, "Driver registered: regs=%p, irp=%d, clock=%d\n",
++ priv->reg_base, ndev->irq, priv->can.clock.freq);
++
++ return 0;
++
++reset_exit:
++ reset_control_assert(priv->resets);
++clk_exit:
++ clk_bulk_disable_unprepare(priv->nr_clks, priv->clks);
++free_exit:
++ free_candev(ndev);
++exit:
++ return ret;
++}
++
++static int canfd_driver_remove(struct platform_device *pdev)
++{
++ struct net_device *ndev = platform_get_drvdata(pdev);
++ struct ipms_canfd_priv *priv = netdev_priv(ndev);
++
++ reset_control_assert(priv->resets);
++ clk_bulk_disable_unprepare(priv->nr_clks, priv->clks);
++ pm_runtime_disable(&pdev->dev);
++
++ unregister_candev(ndev);
++ netif_napi_del(&priv->napi);
++ free_candev(ndev);
++
++ return 0;
++}
++
++#ifdef CONFIG_PM_SLEEP
++static int __maybe_unused canfd_suspend(struct device *dev)
++{
++ struct net_device *ndev = dev_get_drvdata(dev);
++
++ if (netif_running(ndev)) {
++ netif_stop_queue(ndev);
++ netif_device_detach(ndev);
++ canfd_driver_stop(ndev);
++ }
++
++ return pm_runtime_force_suspend(dev);
++}
++
++static int __maybe_unused canfd_resume(struct device *dev)
++{
++ struct net_device *ndev = dev_get_drvdata(dev);
++ int ret;
++
++ ret = pm_runtime_force_resume(dev);
++ if (ret) {
++ dev_err(dev, "pm_runtime_force_resume failed on resume\n");
++ return ret;
++ }
++
++ if (netif_running(ndev)) {
++ ret = canfd_chip_start(ndev);
++ if (ret) {
++ dev_err(dev, "canfd_chip_start failed on resume\n");
++ return ret;
++ }
++
++ netif_device_attach(ndev);
++ netif_start_queue(ndev);
++ }
++
++ return 0;
++}
++#endif
++
++#ifdef CONFIG_PM
++static int canfd_runtime_suspend(struct device *dev)
++{
++ struct net_device *ndev = dev_get_drvdata(dev);
++ struct ipms_canfd_priv *priv = netdev_priv(ndev);
++
++ reset_control_assert(priv->resets);
++ clk_bulk_disable_unprepare(priv->nr_clks, priv->clks);
++
++ return 0;
++}
++
++static int canfd_runtime_resume(struct device *dev)
++{
++ struct net_device *ndev = dev_get_drvdata(dev);
++ struct ipms_canfd_priv *priv = netdev_priv(ndev);
++ int ret;
++
++ ret = clk_bulk_prepare_enable(priv->nr_clks, priv->clks);
++ if (ret) {
++ dev_err(dev, "Failed to prepare_enable clk\n");
++ return ret;
++ }
++
++ ret = reset_control_deassert(priv->resets);
++ if (ret) {
++ dev_err(dev, "Failed to deassert reset\n");
++ return ret;
++ }
++
++ return 0;
++}
++#endif
++
++static const struct dev_pm_ops canfd_pm_ops = {
++ SET_SYSTEM_SLEEP_PM_OPS(canfd_suspend, canfd_resume)
++ SET_RUNTIME_PM_OPS(canfd_runtime_suspend,
++ canfd_runtime_resume, NULL)
++};
++
++static const struct of_device_id canfd_of_match[] = {
++ { .compatible = "ipms,can" },
++ { }
++};
++MODULE_DEVICE_TABLE(of, canfd_of_match);
++
++static struct platform_driver can_driver = {
++ .probe = canfd_driver_probe,
++ .remove = canfd_driver_remove,
++ .driver = {
++ .name = DRIVER_NAME,
++ .pm = &canfd_pm_ops,
++ .of_match_table = canfd_of_match,
++ },
++};
++
++module_platform_driver(can_driver);
++
++MODULE_DESCRIPTION("ipms can controller driver for StarFive jh7110 SoC");
++MODULE_AUTHOR("William Qiu<william.qiu@starfivetech.com");
++MODULE_LICENSE("GPL");
diff --git a/target/linux/starfive/patches-6.6/0071-regulator-starfive-jh7110-Add-regulator-support-for-.patch b/target/linux/starfive/patches-6.6/0071-regulator-starfive-jh7110-Add-regulator-support-for-.patch
new file mode 100644
index 0000000000..cf1e62386d
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0071-regulator-starfive-jh7110-Add-regulator-support-for-.patch
@@ -0,0 +1,204 @@
+From b12213d474966fbf47e7afa36a6655b5b241cf36 Mon Sep 17 00:00:00 2001
+From: "Kevin.xie" <kevin.xie@starfivetech.com>
+Date: Fri, 9 Jun 2023 14:57:13 +0800
+Subject: [PATCH 071/116] regulator: starfive-jh7110: Add regulator support for
+ JH7110 A type EVB.
+
+Add 7 regulators base on regulator framework for
+JH7110 evb HW design.
+
+Signed-off-by: Kevin.xie <kevin.xie@starfivetech.com>
+---
+ drivers/regulator/Kconfig | 10 ++
+ drivers/regulator/Makefile | 1 +
+ drivers/regulator/starfive-jh7110-regulator.c | 126 ++++++++++++++++++
+ include/linux/regulator/jh7110.h | 24 ++++
+ 4 files changed, 161 insertions(+)
+ create mode 100644 drivers/regulator/starfive-jh7110-regulator.c
+ create mode 100644 include/linux/regulator/jh7110.h
+
+--- a/drivers/regulator/Kconfig
++++ b/drivers/regulator/Kconfig
+@@ -1335,6 +1335,16 @@ config REGULATOR_SM5703
+ This driver provides support for voltage regulators of SM5703
+ multi-function device.
+
++config REGULATOR_STARFIVE_JH7110
++ tristate "Starfive JH7110 PMIC"
++ depends on I2C
++ select REGMAP_I2C
++ help
++ Say y here to select this option to enable the power regulator of
++ Starfive JH7110 PMIC.
++ This driver supports the control of different power rails of device
++ through regulator interface.
++
+ config REGULATOR_STM32_BOOSTER
+ tristate "STMicroelectronics STM32 BOOSTER"
+ depends on ARCH_STM32 || COMPILE_TEST
+--- a/drivers/regulator/Makefile
++++ b/drivers/regulator/Makefile
+@@ -156,6 +156,7 @@ obj-$(CONFIG_REGULATOR_SC2731) += sc2731
+ obj-$(CONFIG_REGULATOR_SKY81452) += sky81452-regulator.o
+ obj-$(CONFIG_REGULATOR_SLG51000) += slg51000-regulator.o
+ obj-$(CONFIG_REGULATOR_SM5703) += sm5703-regulator.o
++obj-$(CONFIG_REGULATOR_STARFIVE_JH7110) += starfive-jh7110-regulator.o
+ obj-$(CONFIG_REGULATOR_STM32_BOOSTER) += stm32-booster.o
+ obj-$(CONFIG_REGULATOR_STM32_VREFBUF) += stm32-vrefbuf.o
+ obj-$(CONFIG_REGULATOR_STM32_PWR) += stm32-pwr.o
+--- /dev/null
++++ b/drivers/regulator/starfive-jh7110-regulator.c
+@@ -0,0 +1,126 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (c) 2022 Starfive Technology Co., Ltd.
++ * Author: Mason Huo <mason.huo@starfivetech.com>
++ */
++
++#include <linux/err.h>
++#include <linux/gpio.h>
++#include <linux/i2c.h>
++#include <linux/init.h>
++#include <linux/interrupt.h>
++#include <linux/module.h>
++#include <linux/regmap.h>
++#include <linux/regulator/driver.h>
++#include <linux/regulator/machine.h>
++#include <linux/regulator/of_regulator.h>
++#include <linux/regulator/jh7110.h>
++#include <linux/slab.h>
++
++#define JH7110_PM_POWER_SW_0 0x80
++#define JH7110_PM_POWER_SW_1 0x81
++#define ENABLE_MASK(id) BIT(id)
++
++
++static const struct regmap_config jh7110_regmap_config = {
++ .reg_bits = 8,
++ .val_bits = 8,
++ .max_register = JH7110_PM_POWER_SW_1,
++ .cache_type = REGCACHE_FLAT,
++};
++
++static const struct regulator_ops jh7110_ldo_ops = {
++ .enable = regulator_enable_regmap,
++ .disable = regulator_disable_regmap,
++ .is_enabled = regulator_is_enabled_regmap,
++};
++
++#define JH7110_LDO(_id, _name, en_reg, en_mask) \
++{\
++ .name = (_name),\
++ .ops = &jh7110_ldo_ops,\
++ .of_match = of_match_ptr(_name),\
++ .regulators_node = of_match_ptr("regulators"),\
++ .type = REGULATOR_VOLTAGE,\
++ .id = JH7110_ID_##_id,\
++ .owner = THIS_MODULE,\
++ .enable_reg = JH7110_PM_POWER_SW_##en_reg,\
++ .enable_mask = ENABLE_MASK(en_mask),\
++}
++
++static const struct regulator_desc jh7110_regulators[] = {
++ JH7110_LDO(LDO_REG1, "hdmi_1p8", 0, 0),
++ JH7110_LDO(LDO_REG2, "mipitx_1p8", 0, 1),
++ JH7110_LDO(LDO_REG3, "mipirx_1p8", 0, 2),
++ JH7110_LDO(LDO_REG4, "hdmi_0p9", 0, 3),
++ JH7110_LDO(LDO_REG5, "mipitx_0p9", 0, 4),
++ JH7110_LDO(LDO_REG6, "mipirx_0p9", 0, 5),
++ JH7110_LDO(LDO_REG7, "sdio_vdd", 1, 0),
++};
++
++static int jh7110_i2c_probe(struct i2c_client *i2c)
++{
++ struct regulator_config config = { };
++ struct regulator_dev *rdev;
++ struct regulator_init_data *init_data;
++ struct regmap *regmap;
++ int i, ret;
++
++ regmap = devm_regmap_init_i2c(i2c, &jh7110_regmap_config);
++ if (IS_ERR(regmap)) {
++ ret = PTR_ERR(regmap);
++ dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
++ ret);
++ return ret;
++ }
++
++ init_data = of_get_regulator_init_data(&i2c->dev, i2c->dev.of_node, NULL);
++ if (!init_data)
++ return -ENOMEM;
++ config.init_data = init_data;
++
++ for (i = 0; i < JH7110_MAX_REGULATORS; i++) {
++ config.dev = &i2c->dev;
++ config.regmap = regmap;
++
++ rdev = devm_regulator_register(&i2c->dev,
++ &jh7110_regulators[i], &config);
++ if (IS_ERR(rdev)) {
++ dev_err(&i2c->dev,
++ "Failed to register JH7110 regulator\n");
++ return PTR_ERR(rdev);
++ }
++ }
++
++ return 0;
++}
++
++static const struct i2c_device_id jh7110_i2c_id[] = {
++ {"jh7110_evb_reg", 0},
++ {},
++};
++MODULE_DEVICE_TABLE(i2c, jh7110_i2c_id);
++
++#ifdef CONFIG_OF
++static const struct of_device_id jh7110_dt_ids[] = {
++ { .compatible = "starfive,jh7110-evb-regulator",
++ .data = &jh7110_i2c_id[0] },
++ {},
++};
++MODULE_DEVICE_TABLE(of, jh7110_dt_ids);
++#endif
++
++static struct i2c_driver jh7110_regulator_driver = {
++ .driver = {
++ .name = "jh7110-evb-regulator",
++ .of_match_table = of_match_ptr(jh7110_dt_ids),
++ },
++ .probe = jh7110_i2c_probe,
++ .id_table = jh7110_i2c_id,
++};
++
++module_i2c_driver(jh7110_regulator_driver);
++
++MODULE_AUTHOR("Mason Huo <mason.huo@starfivetech.com>");
++MODULE_DESCRIPTION("Regulator device driver for Starfive JH7110");
++MODULE_LICENSE("GPL v2");
+--- /dev/null
++++ b/include/linux/regulator/jh7110.h
+@@ -0,0 +1,24 @@
++/* SPDX-License-Identifier: GPL-2.0-only */
++/*
++ * Copyright (c) 2022 Starfive Technology Co., Ltd.
++ * Author: Mason Huo <mason.huo@starfivetech.com>
++ */
++
++#ifndef __LINUX_REGULATOR_JH7110_H
++#define __LINUX_REGULATOR_JH7110_H
++
++#define JH7110_MAX_REGULATORS 7
++
++
++enum jh7110_reg_id {
++ JH7110_ID_LDO_REG1 = 0,
++ JH7110_ID_LDO_REG2,
++ JH7110_ID_LDO_REG3,
++ JH7110_ID_LDO_REG4,
++ JH7110_ID_LDO_REG5,
++ JH7110_ID_LDO_REG6,
++ JH7110_ID_LDO_REG7,
++};
++
++
++#endif /* __LINUX_REGULATOR_JH7110_H */
diff --git a/target/linux/starfive/patches-6.6/0072-drivers-nvme-Add-precheck-and-delay-for-CQE-pending-.patch b/target/linux/starfive/patches-6.6/0072-drivers-nvme-Add-precheck-and-delay-for-CQE-pending-.patch
new file mode 100644
index 0000000000..d602df9e4c
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0072-drivers-nvme-Add-precheck-and-delay-for-CQE-pending-.patch
@@ -0,0 +1,40 @@
+From f0b4cffe4d1813305f783d208f260747ecc56c50 Mon Sep 17 00:00:00 2001
+From: "Kevin.xie" <kevin.xie@starfivetech.com>
+Date: Thu, 24 Nov 2022 16:59:12 +0800
+Subject: [PATCH 072/116] drivers: nvme: Add precheck and delay for CQE pending
+ status.
+
+To workaroud the NVMe I/O timeout problem in bootup S10udev case
+which caused by the CQE update lantancy.
+
+Signed-off-by: Kevin.xie <kevin.xie@starfivetech.com>
+---
+ drivers/nvme/host/pci.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+--- a/drivers/nvme/host/pci.c
++++ b/drivers/nvme/host/pci.c
+@@ -28,6 +28,7 @@
+ #include <linux/io-64-nonatomic-hi-lo.h>
+ #include <linux/sed-opal.h>
+ #include <linux/pci-p2pdma.h>
++#include <linux/delay.h>
+
+ #include "trace.h"
+ #include "nvme.h"
+@@ -1062,6 +1063,15 @@ static inline int nvme_poll_cq(struct nv
+ {
+ int found = 0;
+
++ /*
++ * In some cases, such as udev trigger, cqe status may update
++ * a little bit later than MSI, which cause an irq handle missing.
++ * To workaound, here we will prefetch the status first, and wait
++ * 1us if we get nothing.
++ */
++ if (!nvme_cqe_pending(nvmeq))
++ udelay(1);
++
+ while (nvme_cqe_pending(nvmeq)) {
+ found++;
+ /*
diff --git a/target/linux/starfive/patches-6.6/0073-RISC-V-Create-unique-identification-for-SoC-PMU.patch b/target/linux/starfive/patches-6.6/0073-RISC-V-Create-unique-identification-for-SoC-PMU.patch
new file mode 100644
index 0000000000..fff01c4c8f
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0073-RISC-V-Create-unique-identification-for-SoC-PMU.patch
@@ -0,0 +1,93 @@
+From eb294df4b9fab46bc5dbf676edf51e28e06d1968 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Jo=C3=A3o=20M=C3=A1rio=20Domingos?=
+ <joao.mario@tecnico.ulisboa.pt>
+Date: Tue, 16 Nov 2021 15:48:09 +0000
+Subject: [PATCH 073/116] RISC-V: Create unique identification for SoC PMU
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The SBI PMU platform driver did not provide any identification for
+perf events matching. This patch introduces a new sysfs file inside the
+platform device (soc:pmu/id) for pmu identification.
+
+The identification is a 64-bit value generated as:
+[63-32]: mvendorid;
+[31]: marchid[MSB];
+[30-16]: marchid[15-0];
+[15-0]: mimpid[15MSBs];
+
+The CSRs are detailed in the RISC-V privileged spec [1].
+The marchid is split in MSB + 15LSBs, due to the MSB being used for
+open-source architecture identification.
+
+[1] https://github.com/riscv/riscv-isa-manual
+
+Signed-off-by: João Mário Domingos <joao.mario@tecnico.ulisboa.pt>
+---
+ drivers/perf/riscv_pmu_sbi.c | 47 ++++++++++++++++++++++++++++++++++++
+ 1 file changed, 47 insertions(+)
+
+--- a/drivers/perf/riscv_pmu_sbi.c
++++ b/drivers/perf/riscv_pmu_sbi.c
+@@ -1019,6 +1019,46 @@ static struct ctl_table sbi_pmu_sysctl_t
+ { }
+ };
+
++static uint64_t pmu_sbi_get_pmu_id(void)
++{
++ union sbi_pmu_id {
++ uint64_t value;
++ struct {
++ uint16_t imp:16;
++ uint16_t arch:16;
++ uint32_t vendor:32;
++ };
++ } pmuid;
++
++ pmuid.value = 0;
++ pmuid.vendor = (uint32_t) sbi_get_mvendorid();
++ pmuid.arch = (sbi_get_marchid() >> (63 - 15) & (1 << 15)) | (sbi_get_marchid() & 0x7FFF);
++ pmuid.imp = (sbi_get_mimpid() >> 16);
++
++ return pmuid.value;
++}
++
++static ssize_t pmu_sbi_id_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ int len;
++
++ len = sprintf(buf, "0x%llx\n", pmu_sbi_get_pmu_id());
++ if (len <= 0)
++ dev_err(dev, "mydrv: Invalid sprintf len: %dn", len);
++
++ return len;
++}
++
++static DEVICE_ATTR(id, S_IRUGO | S_IWUSR, pmu_sbi_id_show, 0);
++
++static struct attribute *pmu_sbi_attrs[] = {
++ &dev_attr_id.attr,
++ NULL
++};
++
++ATTRIBUTE_GROUPS(pmu_sbi);
++
+ static int pmu_sbi_device_probe(struct platform_device *pdev)
+ {
+ struct riscv_pmu *pmu = NULL;
+@@ -1067,6 +1107,13 @@ static int pmu_sbi_device_probe(struct p
+ pmu->event_unmapped = pmu_sbi_event_unmapped;
+ pmu->csr_index = pmu_sbi_csr_index;
+
++ ret = sysfs_create_group(&pdev->dev.kobj, &pmu_sbi_group);
++ if (ret) {
++ dev_err(&pdev->dev, "sysfs creation failed\n");
++ return ret;
++ }
++ pdev->dev.groups = pmu_sbi_groups;
++
+ ret = cpuhp_state_add_instance(CPUHP_AP_PERF_RISCV_STARTING, &pmu->node);
+ if (ret)
+ return ret;
diff --git a/target/linux/starfive/patches-6.6/0074-RISC-V-Support-CPUID-for-risc-v-in-perf.patch b/target/linux/starfive/patches-6.6/0074-RISC-V-Support-CPUID-for-risc-v-in-perf.patch
new file mode 100644
index 0000000000..177b3b32d8
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0074-RISC-V-Support-CPUID-for-risc-v-in-perf.patch
@@ -0,0 +1,55 @@
+From 1dc069ffadf4ce7817a716f9df2f480254e9b01d Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Jo=C3=A3o=20M=C3=A1rio=20Domingos?=
+ <joao.mario@tecnico.ulisboa.pt>
+Date: Tue, 16 Nov 2021 15:48:10 +0000
+Subject: [PATCH 074/116] RISC-V: Support CPUID for risc-v in perf
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This patch creates the header.c file for the risc-v architecture and introduces support for
+PMU identification through sysfs.
+It is now possible to configure pmu-events in risc-v.
+
+Depends on patch [1], that introduces the id sysfs file.
+
+Signed-off-by: João Mário Domingos <joao.mario@tecnico.ulisboa.pt>
+Signed-off-by: minda.chen <minda.chen@starfivetech.com>
+---
+ drivers/perf/riscv_pmu.c | 18 ++++++++++++++++++
+ 1 file changed, 18 insertions(+)
+
+--- a/drivers/perf/riscv_pmu.c
++++ b/drivers/perf/riscv_pmu.c
+@@ -18,6 +18,23 @@
+
+ #include <asm/sbi.h>
+
++PMU_FORMAT_ATTR(event, "config:0-63");
++
++static struct attribute *riscv_arch_formats_attr[] = {
++ &format_attr_event.attr,
++ NULL,
++};
++
++static struct attribute_group riscv_pmu_format_group = {
++ .name = "format",
++ .attrs = riscv_arch_formats_attr,
++};
++
++static const struct attribute_group *riscv_pmu_attr_groups[] = {
++ &riscv_pmu_format_group,
++ NULL,
++};
++
+ static bool riscv_perf_user_access(struct perf_event *event)
+ {
+ return ((event->attr.type == PERF_TYPE_HARDWARE) ||
+@@ -410,6 +427,7 @@ struct riscv_pmu *riscv_pmu_alloc(void)
+ cpuc->events[i] = NULL;
+ }
+ pmu->pmu = (struct pmu) {
++ .attr_groups = riscv_pmu_attr_groups,
+ .event_init = riscv_pmu_event_init,
+ .event_mapped = riscv_pmu_event_mapped,
+ .event_unmapped = riscv_pmu_event_unmapped,
diff --git a/target/linux/starfive/patches-6.6/0075-RISC-V-Added-generic-pmu-events-mapfile.patch b/target/linux/starfive/patches-6.6/0075-RISC-V-Added-generic-pmu-events-mapfile.patch
new file mode 100644
index 0000000000..01bb4f19ca
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0075-RISC-V-Added-generic-pmu-events-mapfile.patch
@@ -0,0 +1,42 @@
+From 3e6ea12dda276c01a756764fcafa315b19860c33 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Jo=C3=A3o=20M=C3=A1rio=20Domingos?=
+ <joao.mario@tecnico.ulisboa.pt>
+Date: Tue, 16 Nov 2021 15:48:11 +0000
+Subject: [PATCH 075/116] RISC-V: Added generic pmu-events mapfile
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The pmu-events now supports custom events for RISC-V, plus the cycle,
+time and instret events were defined.
+
+Signed-off-by: João Mário Domingos <joao.mario@tecnico.ulisboa.pt>
+---
+ .../pmu-events/arch/riscv/riscv-generic.json | 20 +++++++++++++++++++
+ 1 file changed, 20 insertions(+)
+ create mode 100644 tools/perf/pmu-events/arch/riscv/riscv-generic.json
+
+--- /dev/null
++++ b/tools/perf/pmu-events/arch/riscv/riscv-generic.json
+@@ -0,0 +1,20 @@
++[
++ {
++ "PublicDescription": "CPU Cycles",
++ "EventCode": "0x00",
++ "EventName": "riscv_cycles",
++ "BriefDescription": "CPU cycles RISC-V generic counter"
++ },
++ {
++ "PublicDescription": "CPU Time",
++ "EventCode": "0x01",
++ "EventName": "riscv_time",
++ "BriefDescription": "CPU time RISC-V generic counter"
++ },
++ {
++ "PublicDescription": "CPU Instructions",
++ "EventCode": "0x02",
++ "EventName": "riscv_instret",
++ "BriefDescription": "CPU retired instructions RISC-V generic counter"
++ }
++]
+\ No newline at end of file
diff --git a/target/linux/starfive/patches-6.6/0076-perf-sbi-disable-cpu-hotplug-callback.patch b/target/linux/starfive/patches-6.6/0076-perf-sbi-disable-cpu-hotplug-callback.patch
new file mode 100644
index 0000000000..152a60cfda
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0076-perf-sbi-disable-cpu-hotplug-callback.patch
@@ -0,0 +1,30 @@
+From 30e0cdcf9e05faa65ecde4ed8b70039568fdb660 Mon Sep 17 00:00:00 2001
+From: Minda Chen <minda.chen@starfivetech.com>
+Date: Thu, 2 Mar 2023 17:16:01 +0800
+Subject: [PATCH 076/116] perf: sbi: disable cpu hotplug callback.
+
+register cpu hotplug callback will cause dhrystone
+and coremark benchmark reduce the scores. this CPU
+hotplug ops will do in sbi cpu/on and off. So disable
+this no side effect.
+
+Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ drivers/perf/riscv_pmu_sbi.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/perf/riscv_pmu_sbi.c
++++ b/drivers/perf/riscv_pmu_sbi.c
+@@ -1114,9 +1114,11 @@ static int pmu_sbi_device_probe(struct p
+ }
+ pdev->dev.groups = pmu_sbi_groups;
+
++#ifndef CONFIG_ARCH_STARFIVE
+ ret = cpuhp_state_add_instance(CPUHP_AP_PERF_RISCV_STARTING, &pmu->node);
+ if (ret)
+ return ret;
++#endif
+
+ ret = riscv_pm_pmu_register(pmu);
+ if (ret)
diff --git a/target/linux/starfive/patches-6.6/0077-dmaengine-dw-axi-dmac-Drop-unused-print-message.patch b/target/linux/starfive/patches-6.6/0077-dmaengine-dw-axi-dmac-Drop-unused-print-message.patch
new file mode 100644
index 0000000000..cdc6e4ec26
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0077-dmaengine-dw-axi-dmac-Drop-unused-print-message.patch
@@ -0,0 +1,24 @@
+From fc4b5c7c27e1b56b1f848e50511c4fd081b1b6c5 Mon Sep 17 00:00:00 2001
+From: Walker Chen <walker.chen@starfivetech.com>
+Date: Mon, 12 Jun 2023 21:21:45 +0800
+Subject: [PATCH 077/116] dmaengine: dw-axi-dmac: Drop unused print message
+
+Removed printing information which is not related to StarFive
+platform.
+
+Signed-off-by: Walker Chen <walker.chen@starfivetech.com>
+---
+ drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
++++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+@@ -523,7 +523,7 @@ static void dw_axi_dma_set_hw_channel(st
+ unsigned long reg_value, val;
+
+ if (!chip->apb_regs) {
+- dev_err(chip->dev, "apb_regs not initialized\n");
++ dev_dbg(chip->dev, "apb_regs not initialized\n");
+ return;
+ }
+
diff --git a/target/linux/starfive/patches-6.6/0079-ASoC-codecs-Add-AC108-Codec-driver.patch b/target/linux/starfive/patches-6.6/0079-ASoC-codecs-Add-AC108-Codec-driver.patch
new file mode 100644
index 0000000000..2a828974ce
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0079-ASoC-codecs-Add-AC108-Codec-driver.patch
@@ -0,0 +1,4748 @@
+From cd2254c6be9441ebacaa35693ecb5ce116b90622 Mon Sep 17 00:00:00 2001
+From: Xingyu Wu <xingyu.wu@starfivetech.com>
+Date: Fri, 16 Jun 2023 16:27:46 +0800
+Subject: [PATCH 079/116] ASoC: codecs: Add AC108 Codec driver
+
+Add AC108 Codec driver and AC101 driver for AC10x.
+
+Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ sound/soc/codecs/Kconfig | 5 +
+ sound/soc/codecs/Makefile | 2 +
+ sound/soc/codecs/ac101.c | 1716 +++++++++++++++++++++++++++++++++
+ sound/soc/codecs/ac101_regs.h | 431 +++++++++
+ sound/soc/codecs/ac108.c | 1622 +++++++++++++++++++++++++++++++
+ sound/soc/codecs/ac108.h | 749 ++++++++++++++
+ sound/soc/codecs/ac10x.h | 152 +++
+ 7 files changed, 4677 insertions(+)
+ create mode 100644 sound/soc/codecs/ac101.c
+ create mode 100644 sound/soc/codecs/ac101_regs.h
+ create mode 100644 sound/soc/codecs/ac108.c
+ create mode 100644 sound/soc/codecs/ac108.h
+ create mode 100644 sound/soc/codecs/ac10x.h
+
+--- a/sound/soc/codecs/Kconfig
++++ b/sound/soc/codecs/Kconfig
+@@ -16,6 +16,7 @@ config SND_SOC_ALL_CODECS
+ depends on COMPILE_TEST
+ imply SND_SOC_88PM860X
+ imply SND_SOC_AB8500_CODEC
++ imply SND_SOC_AC108
+ imply SND_SOC_AC97_CODEC
+ imply SND_SOC_AD1836
+ imply SND_SOC_AD193X_SPI
+@@ -397,6 +398,10 @@ config SND_SOC_AB8500_CODEC
+ tristate
+ depends on ABX500_CORE
+
++config SND_SOC_AC108
++ tristate "AC108"
++ depends on I2C
++
+ config SND_SOC_AC97_CODEC
+ tristate "Build generic ASoC AC97 CODEC driver"
+ select SND_AC97_CODEC
+--- a/sound/soc/codecs/Makefile
++++ b/sound/soc/codecs/Makefile
+@@ -2,6 +2,7 @@
+ snd-soc-88pm860x-objs := 88pm860x-codec.o
+ snd-soc-ab8500-codec-objs := ab8500-codec.o
+ snd-soc-ac97-objs := ac97.o
++snd-soc-ac108-objs := ac108.o ac101.o
+ snd-soc-ad1836-objs := ad1836.o
+ snd-soc-ad193x-objs := ad193x.o
+ snd-soc-ad193x-spi-objs := ad193x-spi.o
+@@ -386,6 +387,7 @@ snd-soc-simple-mux-objs := simple-mux.o
+
+ obj-$(CONFIG_SND_SOC_88PM860X) += snd-soc-88pm860x.o
+ obj-$(CONFIG_SND_SOC_AB8500_CODEC) += snd-soc-ab8500-codec.o
++obj-$(CONFIG_SND_SOC_AC108) += snd-soc-ac108.o
+ obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o
+ obj-$(CONFIG_SND_SOC_AD1836) += snd-soc-ad1836.o
+ obj-$(CONFIG_SND_SOC_AD193X) += snd-soc-ad193x.o
+--- /dev/null
++++ b/sound/soc/codecs/ac101.c
+@@ -0,0 +1,1716 @@
++/*
++ * ac101.c
++ *
++ * (C) Copyright 2017-2018
++ * Seeed Technology Co., Ltd. <www.seeedstudio.com>
++ *
++ * PeterYang <linsheng.yang@seeed.cc>
++ *
++ * (C) Copyright 2014-2017
++ * Reuuimlla Technology Co., Ltd. <www.reuuimllatech.com>
++ *
++ * huangxin <huangxin@Reuuimllatech.com>
++ * liushaohua <liushaohua@allwinnertech.com>
++ *
++ * X-Powers AC101 codec driver
++ *
++ * 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 <linux/clk.h>
++#include <linux/delay.h>
++#include <linux/gpio/consumer.h>
++#include <linux/i2c.h>
++#include <linux/input.h>
++#include <linux/irq.h>
++#include <linux/module.h>
++#include <linux/regmap.h>
++#include <sound/tlv.h>
++#include <linux/workqueue.h>
++#include <sound/pcm.h>
++#include <sound/pcm_params.h>
++#include <sound/soc.h>
++#include <sound/soc-dapm.h>
++
++#include "ac101_regs.h"
++#include "ac10x.h"
++
++/* #undef AC101_DEBG
++ * use 'make DEBUG=1' to enable debugging
++ */
++
++/*
++ * *** To sync channels ***
++ *
++ * 1. disable clock in codec hw_params()
++ * 2. clear fifo in bcm2835 hw_params()
++ * 3. clear fifo in bcm2385 prepare()
++ * 4. enable RX in bcm2835 trigger()
++ * 5. enable clock in machine trigger()
++ */
++
++/*Default initialize configuration*/
++static bool speaker_double_used = 1;
++static int double_speaker_val = 0x1B;
++static int single_speaker_val = 0x19;
++static int headset_val = 0x3B;
++static int mainmic_val = 0x4;
++static int headsetmic_val = 0x4;
++static bool dmic_used = 0;
++static int adc_digital_val = 0xb0b0;
++static bool drc_used = false;
++
++#define AC101_RATES (SNDRV_PCM_RATE_8000_96000 & \
++ ~(SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_64000 | \
++ SNDRV_PCM_RATE_88200))
++#define AC101_FORMATS (/*SNDRV_PCM_FMTBIT_S16_LE | \
++ SNDRV_PCM_FMTBIT_S24_LE |*/ \
++ SNDRV_PCM_FMTBIT_S32_LE | \
++ 0)
++
++static struct ac10x_priv* static_ac10x;
++
++
++int ac101_read(struct snd_soc_codec *codec, unsigned reg) {
++ struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
++ int r, v = 0;
++
++ if ((r = regmap_read(ac10x->regmap101, reg, &v)) < 0) {
++ dev_err(codec->dev, "read reg %02X fail\n",
++ reg);
++ return r;
++ }
++ return v;
++}
++
++int ac101_write(struct snd_soc_codec *codec, unsigned reg, unsigned val) {
++ struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
++ int v;
++
++ v = regmap_write(ac10x->regmap101, reg, val);
++ return v;
++}
++
++int ac101_update_bits(struct snd_soc_codec *codec, unsigned reg,
++ unsigned mask, unsigned value
++) {
++ struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
++ int v;
++
++ v = regmap_update_bits(ac10x->regmap101, reg, mask, value);
++ return v;
++}
++
++
++
++#ifdef CONFIG_AC101_SWITCH_DETECT
++/******************************************************************************/
++/********************************switch****************************************/
++/******************************************************************************/
++#define KEY_HEADSETHOOK 226 /* key define */
++#define HEADSET_FILTER_CNT (10)
++
++/*
++ * switch_hw_config:config the 53 codec register
++ */
++static void switch_hw_config(struct snd_soc_codec *codec)
++{
++ int r;
++
++ AC101_DBG();
++
++ /*HMIC/MMIC BIAS voltage level select:2.5v*/
++ ac101_update_bits(codec, OMIXER_BST1_CTRL, (0xf<<BIASVOLTAGE), (0xf<<BIASVOLTAGE));
++ /*debounce when Key down or keyup*/
++ ac101_update_bits(codec, HMIC_CTRL1, (0xf<<HMIC_M), (0x0<<HMIC_M));
++ /*debounce when earphone plugin or pullout*/
++ ac101_update_bits(codec, HMIC_CTRL1, (0xf<<HMIC_N), (0x0<<HMIC_N));
++ /*Down Sample Setting Select: Downby 4,32Hz*/
++ ac101_update_bits(codec, HMIC_CTRL2, (0x3<<HMIC_SAMPLE_SELECT),
++ (0x02<<HMIC_SAMPLE_SELECT));
++ /*Hmic_th2 for detecting Keydown or Keyup.*/
++ ac101_update_bits(codec, HMIC_CTRL2, (0x1f<<HMIC_TH2), (0x8<<HMIC_TH2));
++ /*Hmic_th1[4:0],detecting eraphone plugin or pullout*/
++ ac101_update_bits(codec, HMIC_CTRL2, (0x1f<<HMIC_TH1), (0x1<<HMIC_TH1));
++ /*Headset microphone BIAS working mode: when HBIASEN = 1 */
++ ac101_update_bits(codec, ADC_APC_CTRL, (0x1<<HBIASMOD), (0x1<<HBIASMOD));
++ /*Headset microphone BIAS Enable*/
++ ac101_update_bits(codec, ADC_APC_CTRL, (0x1<<HBIASEN), (0x1<<HBIASEN));
++ /*Headset microphone BIAS Current sensor & ADC Enable*/
++ ac101_update_bits(codec, ADC_APC_CTRL, (0x1<<HBIASADCEN), (0x1<<HBIASADCEN));
++ /*Earphone Plugin/out Irq Enable*/
++ ac101_update_bits(codec, HMIC_CTRL1, (0x1<<HMIC_PULLOUT_IRQ), (0x1<<HMIC_PULLOUT_IRQ));
++ ac101_update_bits(codec, HMIC_CTRL1, (0x1<<HMIC_PLUGIN_IRQ), (0x1<<HMIC_PLUGIN_IRQ));
++
++ /*Hmic KeyUp/key down Irq Enable*/
++ ac101_update_bits(codec, HMIC_CTRL1, (0x1<<HMIC_KEYDOWN_IRQ), (0x1<<HMIC_KEYDOWN_IRQ));
++ ac101_update_bits(codec, HMIC_CTRL1, (0x1<<HMIC_KEYUP_IRQ), (0x1<<HMIC_KEYUP_IRQ));
++
++ /*headphone calibration clock frequency select*/
++ ac101_update_bits(codec, SPKOUT_CTRL, (0x7<<HPCALICKS), (0x7<<HPCALICKS));
++
++ /*clear hmic interrupt */
++ r = HMIC_PEND_ALL;
++ ac101_write(codec, HMIC_STS, r);
++
++ return;
++}
++
++/*
++ * switch_status_update: update the switch state.
++ */
++static void switch_status_update(struct ac10x_priv *ac10x)
++{
++ AC101_DBG("ac10x->state:%d\n", ac10x->state);
++
++ input_report_switch(ac10x->inpdev, SW_HEADPHONE_INSERT, ac10x->state);
++ input_sync(ac10x->inpdev);
++ return;
++}
++
++/*
++ * work_cb_clear_irq: clear audiocodec pending and Record the interrupt.
++ */
++static void work_cb_clear_irq(struct work_struct *work)
++{
++ int reg_val = 0;
++ struct ac10x_priv *ac10x = container_of(work, struct ac10x_priv, work_clear_irq);
++ struct snd_soc_codec *codec = ac10x->codec;
++
++ ac10x->irq_cntr++;
++
++ reg_val = ac101_read(codec, HMIC_STS);
++ if (BIT(HMIC_PULLOUT_PEND) & reg_val) {
++ ac10x->pullout_cntr++;
++ AC101_DBG("ac10x->pullout_cntr: %d\n", ac10x->pullout_cntr);
++ }
++
++ reg_val |= HMIC_PEND_ALL;
++ ac101_write(codec, HMIC_STS, reg_val);
++
++ reg_val = ac101_read(codec, HMIC_STS);
++ if ((reg_val & HMIC_PEND_ALL) != 0){
++ reg_val |= HMIC_PEND_ALL;
++ ac101_write(codec, HMIC_STS, reg_val);
++ }
++
++ if (cancel_work_sync(&ac10x->work_switch) != 0) {
++ ac10x->irq_cntr--;
++ }
++
++ if (0 == schedule_work(&ac10x->work_switch)) {
++ ac10x->irq_cntr--;
++ AC101_DBG("[work_cb_clear_irq] add work struct failed!\n");
++ }
++}
++
++enum {
++ HBIAS_LEVEL_1 = 0x02,
++ HBIAS_LEVEL_2 = 0x0B,
++ HBIAS_LEVEL_3 = 0x13,
++ HBIAS_LEVEL_4 = 0x17,
++ HBIAS_LEVEL_5 = 0x19,
++};
++
++static int __ac101_get_hmic_data(struct snd_soc_codec *codec) {
++ #ifdef AC101_DEBG
++ static long counter;
++ #endif
++ int r, d;
++
++ d = GET_HMIC_DATA(ac101_read(codec, HMIC_STS));
++
++ r = 0x1 << HMIC_DATA_PEND;
++ ac101_write(codec, HMIC_STS, r);
++
++ /* prevent i2c accessing too frequently */
++ usleep_range(1500, 3000);
++
++ AC101_DBG("HMIC_DATA(%3ld): %02X\n", counter++, d);
++ return d;
++}
++
++/*
++ * work_cb_earphone_switch: judge the status of the headphone
++ */
++static void work_cb_earphone_switch(struct work_struct *work)
++{
++ struct ac10x_priv *ac10x = container_of(work, struct ac10x_priv, work_switch);
++ struct snd_soc_codec *codec = ac10x->codec;
++
++ static int hook_flag1 = 0, hook_flag2 = 0;
++ static int KEY_VOLUME_FLAG = 0;
++
++ unsigned filter_buf = 0;
++ int filt_index = 0;
++ int t = 0;
++
++ ac10x->irq_cntr--;
++
++ /* read HMIC_DATA */
++ t = __ac101_get_hmic_data(codec);
++
++ if ((t >= HBIAS_LEVEL_2) && (ac10x->mode == FOUR_HEADPHONE_PLUGIN)) {
++ t = __ac101_get_hmic_data(codec);
++
++ if (t >= HBIAS_LEVEL_5){
++ msleep(150);
++ t = __ac101_get_hmic_data(codec);
++ if (((t < HBIAS_LEVEL_2 && t >= HBIAS_LEVEL_1 - 1) || t >= HBIAS_LEVEL_5)
++ && (ac10x->pullout_cntr == 0)) {
++ input_report_key(ac10x->inpdev, KEY_HEADSETHOOK, 1);
++ input_sync(ac10x->inpdev);
++
++ AC101_DBG("KEY_HEADSETHOOK1\n");
++
++ if (hook_flag1 != hook_flag2)
++ hook_flag1 = hook_flag2 = 0;
++ hook_flag1++;
++ }
++ if (ac10x->pullout_cntr)
++ ac10x->pullout_cntr--;
++ } else if (t >= HBIAS_LEVEL_4) {
++ msleep(80);
++ t = __ac101_get_hmic_data(codec);
++ if (t < HBIAS_LEVEL_5 && t >= HBIAS_LEVEL_4 && (ac10x->pullout_cntr == 0)) {
++ KEY_VOLUME_FLAG = 1;
++ input_report_key(ac10x->inpdev, KEY_VOLUMEUP, 1);
++ input_sync(ac10x->inpdev);
++ input_report_key(ac10x->inpdev, KEY_VOLUMEUP, 0);
++ input_sync(ac10x->inpdev);
++
++ AC101_DBG("HMIC_DATA: %d KEY_VOLUMEUP\n", t);
++ }
++ if (ac10x->pullout_cntr)
++ ac10x->pullout_cntr--;
++ } else if (t >= HBIAS_LEVEL_3){
++ msleep(80);
++ t = __ac101_get_hmic_data(codec);
++ if (t < HBIAS_LEVEL_4 && t >= HBIAS_LEVEL_3 && (ac10x->pullout_cntr == 0)) {
++ KEY_VOLUME_FLAG = 1;
++ input_report_key(ac10x->inpdev, KEY_VOLUMEDOWN, 1);
++ input_sync(ac10x->inpdev);
++ input_report_key(ac10x->inpdev, KEY_VOLUMEDOWN, 0);
++ input_sync(ac10x->inpdev);
++ AC101_DBG("KEY_VOLUMEDOWN\n");
++ }
++ if (ac10x->pullout_cntr)
++ ac10x->pullout_cntr--;
++ }
++ } else if ((t < HBIAS_LEVEL_2 && t >= HBIAS_LEVEL_1) &&
++ (ac10x->mode == FOUR_HEADPHONE_PLUGIN)) {
++ t = __ac101_get_hmic_data(codec);
++ if (t < HBIAS_LEVEL_2 && t >= HBIAS_LEVEL_1) {
++ if (KEY_VOLUME_FLAG) {
++ KEY_VOLUME_FLAG = 0;
++ }
++ if (hook_flag1 == (++hook_flag2)) {
++ hook_flag1 = hook_flag2 = 0;
++ input_report_key(ac10x->inpdev, KEY_HEADSETHOOK, 0);
++ input_sync(ac10x->inpdev);
++
++ AC101_DBG("KEY_HEADSETHOOK0\n");
++ }
++ }
++ } else {
++ while (ac10x->irq_cntr == 0 && ac10x->irq != 0) {
++ msleep(20);
++
++ t = __ac101_get_hmic_data(codec);
++
++ if (filt_index <= HEADSET_FILTER_CNT) {
++ if (filt_index++ == 0) {
++ filter_buf = t;
++ } else if (filter_buf != t) {
++ filt_index = 0;
++ }
++ continue;
++ }
++
++ filt_index = 0;
++ if (filter_buf >= HBIAS_LEVEL_2) {
++ ac10x->mode = THREE_HEADPHONE_PLUGIN;
++ ac10x->state = 2;
++ } else if (filter_buf >= HBIAS_LEVEL_1 - 1) {
++ ac10x->mode = FOUR_HEADPHONE_PLUGIN;
++ ac10x->state = 1;
++ } else {
++ ac10x->mode = HEADPHONE_IDLE;
++ ac10x->state = 0;
++ }
++ switch_status_update(ac10x);
++ ac10x->pullout_cntr = 0;
++ break;
++ }
++ }
++}
++
++/*
++ * audio_hmic_irq: the interrupt handlers
++ */
++static irqreturn_t audio_hmic_irq(int irq, void *para)
++{
++ struct ac10x_priv *ac10x = (struct ac10x_priv *)para;
++ if (ac10x == NULL) {
++ return -EINVAL;
++ }
++
++ if (0 == schedule_work(&ac10x->work_clear_irq)){
++ AC101_DBG("[audio_hmic_irq] work already in queue_codec_irq, adding failed!\n");
++ }
++ return IRQ_HANDLED;
++}
++
++static int ac101_switch_probe(struct ac10x_priv *ac10x) {
++ struct i2c_client *i2c = ac10x->i2c101;
++ long ret;
++
++ ac10x->gpiod_irq = devm_gpiod_get_optional(&i2c->dev, "switch-irq", GPIOD_IN);
++ if (IS_ERR(ac10x->gpiod_irq)) {
++ ac10x->gpiod_irq = NULL;
++ dev_err(&i2c->dev, "failed get switch-irq in device tree\n");
++ goto _err_irq;
++ }
++
++ gpiod_direction_input(ac10x->gpiod_irq);
++
++ ac10x->irq = gpiod_to_irq(ac10x->gpiod_irq);
++ if (IS_ERR_VALUE(ac10x->irq)) {
++ pr_info("[ac101] map gpio to irq failed, errno = %ld\n", ac10x->irq);
++ ac10x->irq = 0;
++ goto _err_irq;
++ }
++
++ /* request irq, set irq type to falling edge trigger */
++ ret = devm_request_irq(ac10x->codec->dev, ac10x->irq, audio_hmic_irq,
++ IRQF_TRIGGER_FALLING, "SWTICH_EINT", ac10x);
++ if (IS_ERR_VALUE(ret)) {
++ pr_info("[ac101] request virq %ld failed, errno = %ld\n", ac10x->irq, ret);
++ goto _err_irq;
++ }
++
++ ac10x->mode = HEADPHONE_IDLE;
++ ac10x->state = -1;
++
++ /*use for judge the state of switch*/
++ INIT_WORK(&ac10x->work_switch, work_cb_earphone_switch);
++ INIT_WORK(&ac10x->work_clear_irq, work_cb_clear_irq);
++
++ /********************create input device************************/
++ ac10x->inpdev = devm_input_allocate_device(ac10x->codec->dev);
++ if (!ac10x->inpdev) {
++ AC101_DBG("input_allocate_device: not enough memory for input device\n");
++ ret = -ENOMEM;
++ goto _err_input_allocate_device;
++ }
++
++ ac10x->inpdev->name = "seed-voicecard-headset";
++ ac10x->inpdev->phys = dev_name(ac10x->codec->dev);
++ ac10x->inpdev->id.bustype = BUS_I2C;
++ ac10x->inpdev->dev.parent = ac10x->codec->dev;
++ input_set_drvdata(ac10x->inpdev, ac10x->codec);
++
++ ac10x->inpdev->evbit[0] = BIT_MASK(EV_KEY) | BIT(EV_SW);
++
++ set_bit(KEY_HEADSETHOOK, ac10x->inpdev->keybit);
++ set_bit(KEY_VOLUMEUP, ac10x->inpdev->keybit);
++ set_bit(KEY_VOLUMEDOWN, ac10x->inpdev->keybit);
++ input_set_capability(ac10x->inpdev, EV_SW, SW_HEADPHONE_INSERT);
++
++ ret = input_register_device(ac10x->inpdev);
++ if (ret) {
++ AC101_DBG("input_register_device: input_register_device failed\n");
++ goto _err_input_register_device;
++ }
++
++ /* the first headset state checking */
++ switch_hw_config(ac10x->codec);
++ ac10x->irq_cntr = 1;
++ schedule_work(&ac10x->work_switch);
++
++ return 0;
++
++_err_input_register_device:
++_err_input_allocate_device:
++
++ if (ac10x->irq) {
++ devm_free_irq(&i2c->dev, ac10x->irq, ac10x);
++ ac10x->irq = 0;
++ }
++_err_irq:
++ return ret;
++}
++/******************************************************************************/
++/********************************switch****************************************/
++/******************************************************************************/
++#endif
++
++
++
++void drc_config(struct snd_soc_codec *codec)
++{
++ int reg_val;
++ reg_val = ac101_read(codec, 0xa3);
++ reg_val &= ~(0x7ff<<0);
++ reg_val |= 1<<0;
++ ac101_write(codec, 0xa3, reg_val);
++ ac101_write(codec, 0xa4, 0x2baf);
++
++ reg_val = ac101_read(codec, 0xa5);
++ reg_val &= ~(0x7ff<<0);
++ reg_val |= 1<<0;
++ ac101_write(codec, 0xa5, reg_val);
++ ac101_write(codec, 0xa6, 0x2baf);
++
++ reg_val = ac101_read(codec, 0xa7);
++ reg_val &= ~(0x7ff<<0);
++ ac101_write(codec, 0xa7, reg_val);
++ ac101_write(codec, 0xa8, 0x44a);
++
++ reg_val = ac101_read(codec, 0xa9);
++ reg_val &= ~(0x7ff<<0);
++ ac101_write(codec, 0xa9, reg_val);
++ ac101_write(codec, 0xaa, 0x1e06);
++
++ reg_val = ac101_read(codec, 0xab);
++ reg_val &= ~(0x7ff<<0);
++ reg_val |= (0x352<<0);
++ ac101_write(codec, 0xab, reg_val);
++ ac101_write(codec, 0xac, 0x6910);
++
++ reg_val = ac101_read(codec, 0xad);
++ reg_val &= ~(0x7ff<<0);
++ reg_val |= (0x77a<<0);
++ ac101_write(codec, 0xad, reg_val);
++ ac101_write(codec, 0xae, 0xaaaa);
++
++ reg_val = ac101_read(codec, 0xaf);
++ reg_val &= ~(0x7ff<<0);
++ reg_val |= (0x2de<<0);
++ ac101_write(codec, 0xaf, reg_val);
++ ac101_write(codec, 0xb0, 0xc982);
++
++ ac101_write(codec, 0x16, 0x9f9f);
++
++}
++
++void drc_enable(struct snd_soc_codec *codec,bool on)
++{
++ int reg_val;
++ if (on) {
++ ac101_write(codec, 0xb5, 0xA080);
++ reg_val = ac101_read(codec, MOD_CLK_ENA);
++ reg_val |= (0x1<<6);
++ ac101_write(codec, MOD_CLK_ENA, reg_val);
++ reg_val = ac101_read(codec, MOD_RST_CTRL);
++ reg_val |= (0x1<<6);
++ ac101_write(codec, MOD_RST_CTRL, reg_val);
++
++ reg_val = ac101_read(codec, 0xa0);
++ reg_val |= (0x7<<0);
++ ac101_write(codec, 0xa0, reg_val);
++ } else {
++ ac101_write(codec, 0xb5, 0x0);
++ reg_val = ac101_read(codec, MOD_CLK_ENA);
++ reg_val &= ~(0x1<<6);
++ ac101_write(codec, MOD_CLK_ENA, reg_val);
++ reg_val = ac101_read(codec, MOD_RST_CTRL);
++ reg_val &= ~(0x1<<6);
++ ac101_write(codec, MOD_RST_CTRL, reg_val);
++
++ reg_val = ac101_read(codec, 0xa0);
++ reg_val &= ~(0x7<<0);
++ ac101_write(codec, 0xa0, reg_val);
++ }
++}
++
++void set_configuration(struct snd_soc_codec *codec)
++{
++ if (speaker_double_used) {
++ ac101_update_bits(codec, SPKOUT_CTRL, (0x1f<<SPK_VOL),
++ (double_speaker_val<<SPK_VOL));
++ } else {
++ ac101_update_bits(codec, SPKOUT_CTRL, (0x1f<<SPK_VOL),
++ (single_speaker_val<<SPK_VOL));
++ }
++ ac101_update_bits(codec, HPOUT_CTRL, (0x3f<<HP_VOL), (headset_val<<HP_VOL));
++ ac101_update_bits(codec, ADC_SRCBST_CTRL, (0x7<<ADC_MIC1G), (mainmic_val<<ADC_MIC1G));
++ ac101_update_bits(codec, ADC_SRCBST_CTRL, (0x7<<ADC_MIC2G), (headsetmic_val<<ADC_MIC2G));
++ if (dmic_used) {
++ ac101_write(codec, ADC_VOL_CTRL, adc_digital_val);
++ }
++ if (drc_used) {
++ drc_config(codec);
++ }
++ /*headphone calibration clock frequency select*/
++ ac101_update_bits(codec, SPKOUT_CTRL, (0x7<<HPCALICKS), (0x7<<HPCALICKS));
++
++ /* I2S1 DAC Timeslot 0 data <- I2S1 DAC channel 0 */
++ // "AIF1IN0L Mux" <= "AIF1DACL"
++ // "AIF1IN0R Mux" <= "AIF1DACR"
++ ac101_update_bits(codec, AIF1_DACDAT_CTRL, 0x3 << AIF1_DA0L_SRC, 0x0 << AIF1_DA0L_SRC);
++ ac101_update_bits(codec, AIF1_DACDAT_CTRL, 0x3 << AIF1_DA0R_SRC, 0x0 << AIF1_DA0R_SRC);
++ /* Timeslot 0 Left & Right Channel enable */
++ ac101_update_bits(codec, AIF1_DACDAT_CTRL, 0x3 << AIF1_DA0R_ENA, 0x3 << AIF1_DA0R_ENA);
++
++ /* DAC Digital Mixer Source Select <- I2S1 DA0 */
++ // "DACL Mixer" += "AIF1IN0L Mux"
++ // "DACR Mixer" += "AIF1IN0R Mux"
++ ac101_update_bits(codec, DAC_MXR_SRC, 0xF << DACL_MXR_ADCL, 0x8 << DACL_MXR_ADCL);
++ ac101_update_bits(codec, DAC_MXR_SRC, 0xF << DACR_MXR_ADCR, 0x8 << DACR_MXR_ADCR);
++ /* Internal DAC Analog Left & Right Channel enable */
++ ac101_update_bits(codec, OMIXER_DACA_CTRL, 0x3 << DACALEN, 0x3 << DACALEN);
++
++ /* Output Mixer Source Select */
++ // "Left Output Mixer" += "DACL Mixer"
++ // "Right Output Mixer" += "DACR Mixer"
++ ac101_update_bits(codec, OMIXER_SR, 0x1 << LMIXMUTEDACL, 0x1 << LMIXMUTEDACL);
++ ac101_update_bits(codec, OMIXER_SR, 0x1 << RMIXMUTEDACR, 0x1 << RMIXMUTEDACR);
++ /* Left & Right Analog Output Mixer enable */
++ ac101_update_bits(codec, OMIXER_DACA_CTRL, 0x3 << LMIXEN, 0x3 << LMIXEN);
++
++ /* Headphone Ouput Control */
++ // "HP_R Mux" <= "DACR Mixer"
++ // "HP_L Mux" <= "DACL Mixer"
++ ac101_update_bits(codec, HPOUT_CTRL, 0x1 << LHPS, 0x0 << LHPS);
++ ac101_update_bits(codec, HPOUT_CTRL, 0x1 << RHPS, 0x0 << RHPS);
++
++ /* Speaker Output Control */
++ // "SPK_L Mux" <= "SPK_LR Adder"
++ // "SPK_R Mux" <= "SPK_LR Adder"
++ ac101_update_bits(codec, SPKOUT_CTRL, (0x1 << LSPKS) | (0x1 << RSPKS),
++ (0x1 << LSPKS) | (0x1 << RSPKS));
++ /* Enable Left & Right Speaker */
++ ac101_update_bits(codec, SPKOUT_CTRL, (0x1 << LSPK_EN) | (0x1 << RSPK_EN),
++ (0x1 << LSPK_EN) | (0x1 << RSPK_EN));
++ return;
++}
++
++static int late_enable_dac(struct snd_soc_codec* codec, int event) {
++ struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
++
++ mutex_lock(&ac10x->dac_mutex);
++ switch (event) {
++ case SND_SOC_DAPM_PRE_PMU:
++ AC101_DBG();
++ if (ac10x->dac_enable == 0){
++ /*enable dac module clk*/
++ ac101_update_bits(codec, MOD_CLK_ENA, (0x1<<MOD_CLK_DAC_DIG),
++ (0x1<<MOD_CLK_DAC_DIG));
++ ac101_update_bits(codec, MOD_RST_CTRL, (0x1<<MOD_RESET_DAC_DIG),
++ (0x1<<MOD_RESET_DAC_DIG));
++ ac101_update_bits(codec, DAC_DIG_CTRL, (0x1<<ENDA), (0x1<<ENDA));
++ ac101_update_bits(codec, DAC_DIG_CTRL, (0x1<<ENHPF),(0x1<<ENHPF));
++ }
++ ac10x->dac_enable++;
++ break;
++ case SND_SOC_DAPM_POST_PMD:
++ if (ac10x->dac_enable != 0){
++ ac10x->dac_enable = 0;
++
++ ac101_update_bits(codec, DAC_DIG_CTRL, (0x1<<ENHPF),(0x0<<ENHPF));
++ ac101_update_bits(codec, DAC_DIG_CTRL, (0x1<<ENDA), (0x0<<ENDA));
++ /*disable dac module clk*/
++ ac101_update_bits(codec, MOD_CLK_ENA, (0x1<<MOD_CLK_DAC_DIG),
++ (0x0<<MOD_CLK_DAC_DIG));
++ ac101_update_bits(codec, MOD_RST_CTRL, (0x1<<MOD_RESET_DAC_DIG),
++ (0x0<<MOD_RESET_DAC_DIG));
++ }
++ break;
++ }
++ mutex_unlock(&ac10x->dac_mutex);
++ return 0;
++}
++
++static int ac101_headphone_event(struct snd_soc_codec* codec, int event) {
++ switch (event) {
++ case SND_SOC_DAPM_POST_PMU:
++ /*open*/
++ AC101_DBG("post:open\n");
++ ac101_update_bits(codec, OMIXER_DACA_CTRL, (0xf<<HPOUTPUTENABLE),
++ (0xf<<HPOUTPUTENABLE));
++ msleep(10);
++ ac101_update_bits(codec, HPOUT_CTRL, (0x1<<HPPA_EN), (0x1<<HPPA_EN));
++ ac101_update_bits(codec, HPOUT_CTRL, (0x3<<LHPPA_MUTE), (0x3<<LHPPA_MUTE));
++ break;
++ case SND_SOC_DAPM_PRE_PMD:
++ /*close*/
++ AC101_DBG("pre:close\n");
++ ac101_update_bits(codec, HPOUT_CTRL, (0x3<<LHPPA_MUTE), (0x0<<LHPPA_MUTE));
++ msleep(10);
++ ac101_update_bits(codec, OMIXER_DACA_CTRL, (0xf<<HPOUTPUTENABLE),
++ (0x0<<HPOUTPUTENABLE));
++ ac101_update_bits(codec, HPOUT_CTRL, (0x1<<HPPA_EN), (0x0<<HPPA_EN));
++ break;
++ }
++ return 0;
++}
++
++static int ac101_sysclk_started(void) {
++ int reg_val;
++
++ reg_val = ac101_read(static_ac10x->codec, SYSCLK_CTRL);
++ return (reg_val & (0x1<<SYSCLK_ENA));
++}
++
++static int ac101_aif1clk(struct snd_soc_codec* codec, int event, int quick) {
++ struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
++ int ret = 0;
++
++ switch (event) {
++ case SND_SOC_DAPM_PRE_PMU:
++ if (ac10x->aif1_clken == 0){
++ ret = ac101_update_bits(codec, SYSCLK_CTRL, (0x1<<AIF1CLK_ENA),
++ (0x1<<AIF1CLK_ENA));
++ if(!quick || _MASTER_MULTI_CODEC != _MASTER_AC101) {
++ /* enable aif1clk & sysclk */
++ ret = ret || ac101_update_bits(codec, MOD_CLK_ENA,
++ (0x1<<MOD_CLK_AIF1),
++ (0x1<<MOD_CLK_AIF1));
++ ret = ret || ac101_update_bits(codec, MOD_RST_CTRL,
++ (0x1<<MOD_RESET_AIF1),
++ (0x1<<MOD_RESET_AIF1));
++ }
++ ret = ret || ac101_update_bits(codec, SYSCLK_CTRL, (0x1<<SYSCLK_ENA),
++ (0x1<<SYSCLK_ENA));
++
++ if (ret) {
++ AC101_DBG("start sysclk failed\n");
++ } else {
++ AC101_DBG("hw sysclk enable\n");
++ ac10x->aif1_clken++;
++ }
++ }
++ break;
++ case SND_SOC_DAPM_POST_PMD:
++ if (ac10x->aif1_clken != 0) {
++ /* disable aif1clk & sysclk */
++ ret = ac101_update_bits(codec, SYSCLK_CTRL, (0x1<<AIF1CLK_ENA),
++ (0x0<<AIF1CLK_ENA));
++ ret = ret || ac101_update_bits(codec, MOD_CLK_ENA, (0x1<<MOD_CLK_AIF1),
++ (0x0<<MOD_CLK_AIF1));
++ ret = ret || ac101_update_bits(codec, MOD_RST_CTRL, (0x1<<MOD_RESET_AIF1),
++ (0x0<<MOD_RESET_AIF1));
++ ret = ret || ac101_update_bits(codec, SYSCLK_CTRL, (0x1<<SYSCLK_ENA),
++ (0x0<<SYSCLK_ENA));
++
++ if (ret) {
++ AC101_DBG("stop sysclk failed\n");
++ } else {
++ AC101_DBG("hw sysclk disable\n");
++ ac10x->aif1_clken = 0;
++ }
++ break;
++ }
++ }
++
++ AC101_DBG("event=%d pre_up/%d post_down/%d\n", event, SND_SOC_DAPM_PRE_PMU,
++ SND_SOC_DAPM_POST_PMD);
++
++ return ret;
++}
++
++/**
++ * snd_ac101_get_volsw - single mixer get callback
++ * @kcontrol: mixer control
++ * @ucontrol: control element information
++ *
++ * Callback to get the value of a single mixer control, or a double mixer
++ * control that spans 2 registers.
++ *
++ * Returns 0 for success.
++ */
++static int snd_ac101_get_volsw(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol
++){
++ struct soc_mixer_control *mc =
++ (struct soc_mixer_control *)kcontrol->private_value;
++ unsigned int val, mask = (1 << fls(mc->max)) - 1;
++ unsigned int invert = mc->invert;
++ int ret;
++
++ if ((ret = ac101_read(static_ac10x->codec, mc->reg)) < 0)
++ return ret;
++
++ val = (ret >> mc->shift) & mask;
++ ucontrol->value.integer.value[0] = val - mc->min;
++ if (invert) {
++ ucontrol->value.integer.value[0] =
++ mc->max - ucontrol->value.integer.value[0];
++ }
++
++ if (snd_soc_volsw_is_stereo(mc)) {
++ val = (ret >> mc->rshift) & mask;
++ ucontrol->value.integer.value[1] = val - mc->min;
++ if (invert) {
++ ucontrol->value.integer.value[1] =
++ mc->max - ucontrol->value.integer.value[1];
++ }
++ }
++ return 0;
++}
++
++/**
++ * snd_ac101_put_volsw - single mixer put callback
++ * @kcontrol: mixer control
++ * @ucontrol: control element information
++ *
++ * Callback to set the value of a single mixer control, or a double mixer
++ * control that spans 2 registers.
++ *
++ * Returns 0 for success.
++ */
++static int snd_ac101_put_volsw(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol
++){
++ struct soc_mixer_control *mc =
++ (struct soc_mixer_control *)kcontrol->private_value;
++ unsigned int sign_bit = mc->sign_bit;
++ unsigned int val, mask = (1 << fls(mc->max)) - 1;
++ unsigned int invert = mc->invert;
++ int ret;
++
++ if (sign_bit)
++ mask = BIT(sign_bit + 1) - 1;
++
++ val = ((ucontrol->value.integer.value[0] + mc->min) & mask);
++ if (invert) {
++ val = mc->max - val;
++ }
++
++ ret = ac101_update_bits(static_ac10x->codec, mc->reg, mask << mc->shift, val << mc->shift);
++
++ if (! snd_soc_volsw_is_stereo(mc)) {
++ return ret;
++ }
++ val = ((ucontrol->value.integer.value[1] + mc->min) & mask);
++ if (invert) {
++ val = mc->max - val;
++ }
++
++ ret = ac101_update_bits(static_ac10x->codec, mc->reg, mask << mc->rshift,
++ val << mc->rshift);
++ return ret;
++}
++
++
++static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -11925, 75, 0);
++static const DECLARE_TLV_DB_SCALE(dac_mix_vol_tlv, -600, 600, 0);
++static const DECLARE_TLV_DB_SCALE(dig_vol_tlv, -7308, 116, 0);
++static const DECLARE_TLV_DB_SCALE(speaker_vol_tlv, -4800, 150, 0);
++static const DECLARE_TLV_DB_SCALE(headphone_vol_tlv, -6300, 100, 0);
++
++static struct snd_kcontrol_new ac101_controls[] = {
++ /*DAC*/
++ SOC_DOUBLE_TLV("DAC volume", DAC_VOL_CTRL, DAC_VOL_L, DAC_VOL_R, 0xff, 0, dac_vol_tlv),
++ SOC_DOUBLE_TLV("DAC mixer gain", DAC_MXR_GAIN, DACL_MXR_GAIN, DACR_MXR_GAIN,
++ 0xf, 0, dac_mix_vol_tlv),
++ SOC_SINGLE_TLV("digital volume", DAC_DBG_CTRL, DVC, 0x3f, 1, dig_vol_tlv),
++ SOC_SINGLE_TLV("speaker volume", SPKOUT_CTRL, SPK_VOL, 0x1f, 0, speaker_vol_tlv),
++ SOC_SINGLE_TLV("headphone volume", HPOUT_CTRL, HP_VOL, 0x3f, 0, headphone_vol_tlv),
++};
++
++/* PLL divisors */
++struct pll_div {
++ unsigned int pll_in;
++ unsigned int pll_out;
++ int m;
++ int n_i;
++ int n_f;
++};
++
++struct aif1_fs {
++ unsigned samp_rate;
++ int bclk_div;
++ int srbit;
++ #define _SERIES_24_576K 0
++ #define _SERIES_22_579K 1
++ int series;
++};
++
++struct kv_map {
++ int val;
++ int bit;
++};
++
++/*
++ * Note : pll code from original tdm/i2s driver.
++ * freq_out = freq_in * N/(M*(2k+1)) , k=1,N=N_i+N_f,N_f=factor*0.2;
++ * N_i[0,1023], N_f_factor[0,7], m[1,64]=REG_VAL[1-63,0]
++ */
++static const struct pll_div codec_pll_div[] = {
++ {128000, _FREQ_22_579K, 1, 529, 1},
++ {192000, _FREQ_22_579K, 1, 352, 4},
++ {256000, _FREQ_22_579K, 1, 264, 3},
++ {384000, _FREQ_22_579K, 1, 176, 2}, /*((176+2*0.2)*6000000)/(38*(2*1+1))*/
++ {1411200, _FREQ_22_579K, 1, 48, 0},
++ {2822400, _FREQ_22_579K, 1, 24, 0}, /* accurate, 11025 * 256 */
++ {5644800, _FREQ_22_579K, 1, 12, 0}, /* accurate, 22050 * 256 */
++ {6000000, _FREQ_22_579K, 38, 429, 0}, /*((429+0*0.2)*6000000)/(38*(2*1+1))*/
++ {11289600, _FREQ_22_579K, 1, 6, 0}, /* accurate, 44100 * 256 */
++ {13000000, _FREQ_22_579K, 19, 99, 0},
++ {19200000, _FREQ_22_579K, 25, 88, 1},
++ {24000000, _FREQ_22_579K, 63, 177, 4}, /* 22577778 Hz */
++
++ {128000, _FREQ_24_576K, 1, 576, 0},
++ {192000, _FREQ_24_576K, 1, 384, 0},
++ {256000, _FREQ_24_576K, 1, 288, 0},
++ {384000, _FREQ_24_576K, 1, 192, 0},
++ {2048000, _FREQ_24_576K, 1, 36, 0}, /* accurate, 8000 * 256 */
++ {3072000, _FREQ_24_576K, 1, 24, 0}, /* accurate, 12000 * 256 */
++ {4096000, _FREQ_24_576K, 1, 18, 0}, /* accurate, 16000 * 256 */
++ {6000000, _FREQ_24_576K, 25, 307, 1},
++ {6144000, _FREQ_24_576K, 4, 48, 0}, /* accurate, 24000 * 256 */
++ {12288000, _FREQ_24_576K, 8, 48, 0}, /* accurate, 48000 * 256 */
++ {13000000, _FREQ_24_576K, 42, 238, 1},
++ {19200000, _FREQ_24_576K, 25, 96, 0},
++ {24000000, _FREQ_24_576K, 25, 76, 4}, /* accurate */
++
++ {_FREQ_22_579K, _FREQ_22_579K, 8, 24, 0}, /* accurate, 88200 * 256 */
++ {_FREQ_24_576K, _FREQ_24_576K, 8, 24, 0}, /* accurate, 96000 * 256 */
++};
++
++static const struct aif1_fs codec_aif1_fs[] = {
++ {8000, 12, 0},
++ {11025, 8, 1, _SERIES_22_579K},
++ {12000, 8, 2},
++ {16000, 6, 3},
++ {22050, 4, 4, _SERIES_22_579K},
++ {24000, 4, 5},
++ /* {32000, 3, 6}, dividing by 3 is not support */
++ {44100, 2, 7, _SERIES_22_579K},
++ {48000, 2, 8},
++ {96000, 1, 9},
++};
++
++static const struct kv_map codec_aif1_lrck[] = {
++ {16, 0},
++ {32, 1},
++ {64, 2},
++ {128, 3},
++ {256, 4},
++};
++
++static const struct kv_map codec_aif1_wsize[] = {
++ {8, 0},
++ {16, 1},
++ {20, 2},
++ {24, 3},
++ {32, 3},
++};
++
++static const unsigned ac101_bclkdivs[] = {
++ 1, 2, 4, 6,
++ 8, 12, 16, 24,
++ 32, 48, 64, 96,
++ 128, 192, 0, 0,
++};
++
++static int ac101_aif_play(struct ac10x_priv* ac10x) {
++ struct snd_soc_codec * codec = ac10x->codec;
++
++ late_enable_dac(codec, SND_SOC_DAPM_PRE_PMU);
++ ac101_headphone_event(codec, SND_SOC_DAPM_POST_PMU);
++ if (drc_used) {
++ drc_enable(codec, 1);
++ }
++
++ /* Enable Left & Right Speaker */
++ ac101_update_bits(codec, SPKOUT_CTRL, (0x1 << LSPK_EN) | (0x1 << RSPK_EN),
++ (0x1 << LSPK_EN) | (0x1 << RSPK_EN));
++ if (ac10x->gpiod_spk_amp_gate) {
++ gpiod_set_value(ac10x->gpiod_spk_amp_gate, 1);
++ }
++ return 0;
++}
++
++static void ac10x_work_aif_play(struct work_struct *work) {
++ struct ac10x_priv *ac10x = container_of(work, struct ac10x_priv, dlywork.work);
++
++ ac101_aif_play(ac10x);
++ return;
++}
++
++int ac101_aif_mute(struct snd_soc_dai *codec_dai, int mute)
++{
++ struct snd_soc_codec *codec = codec_dai->codec;
++ struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
++
++ AC101_DBG("mute=%d\n", mute);
++
++ ac101_write(codec, DAC_VOL_CTRL, mute? 0: 0xA0A0);
++
++ if (!mute) {
++ #if _MASTER_MULTI_CODEC != _MASTER_AC101
++ /* enable global clock */
++ ac10x->aif1_clken = 0;
++ ac101_aif1clk(codec, SND_SOC_DAPM_PRE_PMU, 0);
++ ac101_aif_play(ac10x);
++ #else
++ schedule_delayed_work(&ac10x->dlywork, msecs_to_jiffies(50));
++ #endif
++ } else {
++ #if _MASTER_MULTI_CODEC == _MASTER_AC101
++ cancel_delayed_work_sync(&ac10x->dlywork);
++ #endif
++
++ if (ac10x->gpiod_spk_amp_gate) {
++ gpiod_set_value(ac10x->gpiod_spk_amp_gate, 0);
++ }
++ /* Disable Left & Right Speaker */
++ ac101_update_bits(codec, SPKOUT_CTRL, (0x1 << LSPK_EN) | (0x1 << RSPK_EN),
++ (0x0 << LSPK_EN) | (0x0 << RSPK_EN));
++ if (drc_used) {
++ drc_enable(codec, 0);
++ }
++ ac101_headphone_event(codec, SND_SOC_DAPM_PRE_PMD);
++ late_enable_dac(codec, SND_SOC_DAPM_POST_PMD);
++
++ #if _MASTER_MULTI_CODEC != _MASTER_AC101
++ ac10x->aif1_clken = 1;
++ ac101_aif1clk(codec, SND_SOC_DAPM_POST_PMD, 0);
++ #endif
++ }
++ return 0;
++}
++
++void ac101_aif_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *codec_dai)
++{
++ struct snd_soc_codec *codec = codec_dai->codec;
++ struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
++
++ AC101_DBG("stream = %s, play: %d, capt: %d, active: %d\n",
++ snd_pcm_stream_str(substream),
++ codec_dai->stream[SNDRV_PCM_STREAM_PLAYBACK].active,
++ codec_dai->stream[SNDRV_PCM_STREAM_CAPTURE].active,
++ snd_soc_dai_active(codec_dai));
++
++ if (!snd_soc_dai_active(codec_dai)) {
++ ac10x->aif1_clken = 1;
++ ac101_aif1clk(codec, SND_SOC_DAPM_POST_PMD, 0);
++ } else {
++ ac101_aif1clk(codec, SND_SOC_DAPM_PRE_PMU, 0);
++ }
++}
++
++static int ac101_set_pll(struct snd_soc_dai *codec_dai, int pll_id, int source,
++ unsigned int freq_in, unsigned int freq_out)
++{
++ struct snd_soc_codec *codec = codec_dai->codec;
++ int i, m, n_i, n_f;
++
++ AC101_DBG("pll_id:%d\n", pll_id);
++
++ /* clear volatile reserved bits*/
++ ac101_update_bits(codec, SYSCLK_CTRL, 0xFF & ~(0x1 << SYSCLK_ENA), 0x0);
++
++ /* select aif1 clk srouce from mclk1 */
++ ac101_update_bits(codec, SYSCLK_CTRL, (0x3<<AIF1CLK_SRC), (0x0<<AIF1CLK_SRC));
++ /* disable pll */
++ ac101_update_bits(codec, PLL_CTRL2, (0x1<<PLL_EN), (0<<PLL_EN));
++
++ if (!freq_out)
++ return 0;
++ if ((freq_in < 128000) || (freq_in > _FREQ_24_576K)) {
++ return -EINVAL;
++ } else if ((freq_in == _FREQ_24_576K) || (freq_in == _FREQ_22_579K)) {
++ if (pll_id == AC101_MCLK1) {
++ /*select aif1 clk source from mclk1*/
++ ac101_update_bits(codec, SYSCLK_CTRL, (0x3<<AIF1CLK_SRC),
++ (0x0<<AIF1CLK_SRC));
++ return 0;
++ }
++ }
++
++ switch (pll_id) {
++ case AC101_MCLK1:
++ /*pll source from MCLK1*/
++ ac101_update_bits(codec, SYSCLK_CTRL, (0x3<<PLLCLK_SRC), (0x0<<PLLCLK_SRC));
++ break;
++ case AC101_BCLK1:
++ /*pll source from BCLK1*/
++ ac101_update_bits(codec, SYSCLK_CTRL, (0x3<<PLLCLK_SRC), (0x2<<PLLCLK_SRC));
++ break;
++ default:
++ return -EINVAL;
++ }
++
++ /* freq_out = freq_in * n/(m*(2k+1)) , k=1,N=N_i+N_f */
++ for (i = m = n_i = n_f = 0; i < ARRAY_SIZE(codec_pll_div); i++) {
++ if ((codec_pll_div[i].pll_in == freq_in) &&
++ (codec_pll_div[i].pll_out == freq_out)) {
++ m = codec_pll_div[i].m;
++ n_i = codec_pll_div[i].n_i;
++ n_f = codec_pll_div[i].n_f;
++ break;
++ }
++ }
++ /* config pll m */
++ if (m == 64) m = 0;
++ ac101_update_bits(codec, PLL_CTRL1, (0x3f<<PLL_POSTDIV_M), (m<<PLL_POSTDIV_M));
++ /* config pll n */
++ ac101_update_bits(codec, PLL_CTRL2, (0x3ff<<PLL_PREDIV_NI), (n_i<<PLL_PREDIV_NI));
++ ac101_update_bits(codec, PLL_CTRL2, (0x7<<PLL_POSTDIV_NF), (n_f<<PLL_POSTDIV_NF));
++ /* enable pll */
++ ac101_update_bits(codec, PLL_CTRL2, (0x1<<PLL_EN), (1<<PLL_EN));
++ ac101_update_bits(codec, SYSCLK_CTRL, (0x1<<PLLCLK_ENA), (0x1<<PLLCLK_ENA));
++ ac101_update_bits(codec, SYSCLK_CTRL, (0x3<<AIF1CLK_SRC), (0x3<<AIF1CLK_SRC));
++
++ return 0;
++}
++
++int ac101_hw_params(struct snd_pcm_substream *substream,
++ struct snd_pcm_hw_params *params,
++ struct snd_soc_dai *codec_dai)
++{
++ int i = 0;
++ int AIF_CLK_CTRL = AIF1_CLK_CTRL;
++ int aif1_word_size = 24;
++ int aif1_slot_size = 32;
++ int aif1_lrck_div;
++ struct snd_soc_codec *codec = codec_dai->codec;
++ struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
++ int reg_val, freq_out;
++ unsigned channels;
++
++ AC101_DBG("+++\n");
++
++ if (_MASTER_MULTI_CODEC == _MASTER_AC101 && ac101_sysclk_started()) {
++ /* not configure hw_param twice if stream is playback, tell the caller it's started */
++ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
++ return 1;
++ }
++ }
++
++ /* get channels count & slot size */
++ channels = params_channels(params);
++
++ switch (params_format(params)) {
++ case SNDRV_PCM_FORMAT_S24_LE:
++ case SNDRV_PCM_FORMAT_S32_LE:
++ aif1_slot_size = 32;
++ break;
++ case SNDRV_PCM_FORMAT_S16_LE:
++ default:
++ aif1_slot_size = 16;
++ break;
++ }
++
++ /* set LRCK/BCLK ratio */
++ aif1_lrck_div = aif1_slot_size * channels;
++ for (i = 0; i < ARRAY_SIZE(codec_aif1_lrck); i++) {
++ if (codec_aif1_lrck[i].val == aif1_lrck_div) {
++ break;
++ }
++ }
++ ac101_update_bits(codec, AIF_CLK_CTRL, (0x7 << AIF1_LRCK_DIV),
++ codec_aif1_lrck[i].bit << AIF1_LRCK_DIV);
++
++ /* set PLL output freq */
++ freq_out = _FREQ_24_576K;
++ for (i = 0; i < ARRAY_SIZE(codec_aif1_fs); i++) {
++ if (codec_aif1_fs[i].samp_rate == params_rate(params)) {
++ if (codec_dai->stream[SNDRV_PCM_STREAM_CAPTURE].active && dmic_used &&
++ codec_aif1_fs[i].samp_rate == 44100) {
++ ac101_update_bits(codec, AIF_SR_CTRL, (0xf<<AIF1_FS),
++ (0x4<<AIF1_FS));
++ } else {
++ ac101_update_bits(codec, AIF_SR_CTRL, (0xf<<AIF1_FS),
++ ((codec_aif1_fs[i].srbit)<<AIF1_FS));
++ }
++ if (codec_aif1_fs[i].series == _SERIES_22_579K)
++ freq_out = _FREQ_22_579K;
++ break;
++ }
++ }
++
++ /* set I2S word size */
++ for (i = 0; i < ARRAY_SIZE(codec_aif1_wsize); i++) {
++ if (codec_aif1_wsize[i].val == aif1_word_size) {
++ break;
++ }
++ }
++ ac101_update_bits(codec, AIF_CLK_CTRL, (0x3<<AIF1_WORK_SIZ),
++ ((codec_aif1_wsize[i].bit)<<AIF1_WORK_SIZ));
++
++ /* set TDM slot size */
++ if ((reg_val = codec_aif1_wsize[i].bit) > 2) reg_val = 2;
++ ac101_update_bits(codec, AIF1_ADCDAT_CTRL, 0x3 << AIF1_SLOT_SIZ, reg_val << AIF1_SLOT_SIZ);
++
++ /* setting pll if it's master mode */
++ reg_val = ac101_read(codec, AIF_CLK_CTRL);
++ if ((reg_val & (0x1 << AIF1_MSTR_MOD)) == 0) {
++ unsigned bclkdiv;
++
++ ac101_set_pll(codec_dai, AC101_MCLK1, 0, ac10x->sysclk, freq_out);
++
++ bclkdiv = freq_out / (aif1_lrck_div * params_rate(params));
++ for (i = 0; i < ARRAY_SIZE(ac101_bclkdivs) - 1; i++) {
++ if (ac101_bclkdivs[i] >= bclkdiv) {
++ break;
++ }
++ }
++ ac101_update_bits(codec, AIF_CLK_CTRL, (0xf<<AIF1_BCLK_DIV), i<<AIF1_BCLK_DIV);
++ } else {
++ /* set pll clock source to BCLK if slave mode */
++ ac101_set_pll(codec_dai, AC101_BCLK1, 0, aif1_lrck_div * params_rate(params),
++ freq_out);
++ }
++
++ #if _MASTER_MULTI_CODEC == _MASTER_AC101
++ /* Master mode, to clear cpu_dai fifos, disable output bclk & lrck */
++ ac101_aif1clk(codec, SND_SOC_DAPM_POST_PMD, 0);
++ #endif
++
++ AC101_DBG("rate: %d , channels: %d , samp_res: %d",
++ params_rate(params), channels, aif1_slot_size);
++
++ AC101_DBG("---\n");
++ return 0;
++}
++
++int ac101_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
++{
++ int reg_val;
++ int AIF_CLK_CTRL = AIF1_CLK_CTRL;
++ struct snd_soc_codec *codec = codec_dai->codec;
++
++ AC101_DBG();
++
++ /*
++ * master or slave selection
++ * 0 = Master mode
++ * 1 = Slave mode
++ */
++ reg_val = ac101_read(codec, AIF_CLK_CTRL);
++ reg_val &= ~(0x1<<AIF1_MSTR_MOD);
++ switch(fmt & SND_SOC_DAIFMT_MASTER_MASK) {
++ case SND_SOC_DAIFMT_CBM_CFM: /* codec clk & frm master, ap is slave*/
++ #if _MASTER_MULTI_CODEC == _MASTER_AC101
++ pr_warn("AC101 as Master\n");
++ reg_val |= (0x0<<AIF1_MSTR_MOD);
++ break;
++ #else
++ pr_warn("AC108 as Master\n");
++ #endif
++ case SND_SOC_DAIFMT_CBS_CFS: /* codec clk & frm slave, ap is master*/
++ pr_warn("AC101 as Slave\n");
++ reg_val |= (0x1<<AIF1_MSTR_MOD);
++ break;
++ default:
++ pr_err("unknwon master/slave format\n");
++ return -EINVAL;
++ }
++
++ /*
++ * Enable TDM mode
++ */
++ reg_val |= (0x1 << AIF1_TDMM_ENA);
++ ac101_write(codec, AIF_CLK_CTRL, reg_val);
++
++ /* i2s mode selection */
++ reg_val = ac101_read(codec, AIF_CLK_CTRL);
++ reg_val&=~(3<<AIF1_DATA_FMT);
++ switch(fmt & SND_SOC_DAIFMT_FORMAT_MASK){
++ case SND_SOC_DAIFMT_I2S: /* I2S1 mode */
++ reg_val |= (0x0<<AIF1_DATA_FMT);
++ break;
++ case SND_SOC_DAIFMT_RIGHT_J: /* Right Justified mode */
++ reg_val |= (0x2<<AIF1_DATA_FMT);
++ break;
++ case SND_SOC_DAIFMT_LEFT_J: /* Left Justified mode */
++ reg_val |= (0x1<<AIF1_DATA_FMT);
++ break;
++ case SND_SOC_DAIFMT_DSP_A: /* L reg_val msb after FRM LRC */
++ reg_val |= (0x3<<AIF1_DATA_FMT);
++ break;
++ case SND_SOC_DAIFMT_DSP_B:
++ /* TODO: data offset set to 0 */
++ reg_val |= (0x3<<AIF1_DATA_FMT);
++ break;
++ default:
++ pr_err("%s, line:%d\n", __func__, __LINE__);
++ return -EINVAL;
++ }
++ ac101_write(codec, AIF_CLK_CTRL, reg_val);
++
++ /* DAI signal inversions */
++ reg_val = ac101_read(codec, AIF_CLK_CTRL);
++ switch(fmt & SND_SOC_DAIFMT_INV_MASK){
++ case SND_SOC_DAIFMT_NB_NF: /* normal bit clock + nor frame */
++ reg_val &= ~(0x1<<AIF1_LRCK_INV);
++ reg_val &= ~(0x1<<AIF1_BCLK_INV);
++ break;
++ case SND_SOC_DAIFMT_NB_IF: /* normal bclk + inv frm */
++ reg_val |= (0x1<<AIF1_LRCK_INV);
++ reg_val &= ~(0x1<<AIF1_BCLK_INV);
++ break;
++ case SND_SOC_DAIFMT_IB_NF: /* invert bclk + nor frm */
++ reg_val &= ~(0x1<<AIF1_LRCK_INV);
++ reg_val |= (0x1<<AIF1_BCLK_INV);
++ break;
++ case SND_SOC_DAIFMT_IB_IF: /* invert bclk + inv frm */
++ reg_val |= (0x1<<AIF1_LRCK_INV);
++ reg_val |= (0x1<<AIF1_BCLK_INV);
++ break;
++ }
++ ac101_write(codec, AIF_CLK_CTRL, reg_val);
++
++ return 0;
++}
++
++int ac101_audio_startup(struct snd_pcm_substream *substream,
++ struct snd_soc_dai *codec_dai)
++{
++ // struct snd_soc_codec *codec = codec_dai->codec;
++
++ AC101_DBG("\n\n\n");
++
++ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
++ }
++ return 0;
++}
++
++int ac101_trigger(struct snd_pcm_substream *substream, int cmd,
++ struct snd_soc_dai *dai)
++{
++ struct snd_soc_codec *codec = dai->codec;
++ struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
++ int ret = 0;
++
++ AC101_DBG("stream=%s cmd=%d\n",
++ snd_pcm_stream_str(substream),
++ cmd);
++
++ switch (cmd) {
++ case SNDRV_PCM_TRIGGER_START:
++ case SNDRV_PCM_TRIGGER_RESUME:
++ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
++ #if _MASTER_MULTI_CODEC == _MASTER_AC101
++ if (ac10x->aif1_clken == 0){
++ /*
++ * enable aif1clk, it' here due to reduce time between 'AC108 Sysclk Enable' and 'AC101 Sysclk Enable'
++ * Or else the two AC108 chips lost the sync.
++ */
++ ret = 0;
++ ret = ret || ac101_update_bits(codec, MOD_CLK_ENA,
++ (0x1<<MOD_CLK_AIF1), (0x1<<MOD_CLK_AIF1));
++ ret = ret || ac101_update_bits(codec, MOD_RST_CTRL, (0x1<<MOD_RESET_AIF1),
++ (0x1<<MOD_RESET_AIF1));
++ }
++ #endif
++ break;
++ case SNDRV_PCM_TRIGGER_STOP:
++ case SNDRV_PCM_TRIGGER_SUSPEND:
++ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
++ break;
++ default:
++ ret = -EINVAL;
++ }
++ return ret;
++}
++
++#if 0
++static int ac101_set_dai_sysclk(struct snd_soc_dai *codec_dai,
++ int clk_id, unsigned int freq, int dir)
++{
++ struct snd_soc_codec *codec = codec_dai->codec;
++ struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
++
++ AC101_DBG("id=%d freq=%d, dir=%d\n",
++ clk_id, freq, dir);
++
++ ac10x->sysclk = freq;
++
++ return 0;
++}
++
++static const struct snd_soc_dai_ops ac101_aif1_dai_ops = {
++ //.startup = ac101_audio_startup,
++ //.shutdown = ac101_aif_shutdown,
++ //.set_sysclk = ac101_set_dai_sysclk,
++ //.set_pll = ac101_set_pll,
++ //.set_fmt = ac101_set_dai_fmt,
++ //.hw_params = ac101_hw_params,
++ //.trigger = ac101_trigger,
++ //.digital_mute = ac101_aif_mute,
++};
++
++static struct snd_soc_dai_driver ac101_dai[] = {
++ {
++ .name = "ac10x-aif1",
++ .id = AIF1_CLK,
++ .playback = {
++ .stream_name = "Playback",
++ .channels_min = 1,
++ .channels_max = 8,
++ .rates = AC101_RATES,
++ .formats = AC101_FORMATS,
++ },
++ #if 0
++ .capture = {
++ .stream_name = "Capture",
++ .channels_min = 1,
++ .channels_max = 8,
++ .rates = AC101_RATES,
++ .formats = AC101_FORMATS,
++ },
++ #endif
++ .ops = &ac101_aif1_dai_ops,
++ }
++};
++#endif
++
++static void codec_resume_work(struct work_struct *work)
++{
++ struct ac10x_priv *ac10x = container_of(work, struct ac10x_priv, codec_resume);
++ struct snd_soc_codec *codec = ac10x->codec;
++
++ AC101_DBG("+++\n");
++
++ set_configuration(codec);
++ if (drc_used) {
++ drc_config(codec);
++ }
++ /*enable this bit to prevent leakage from ldoin*/
++ ac101_update_bits(codec, ADDA_TUNE3, (0x1<<OSCEN), (0x1<<OSCEN));
++
++ AC101_DBG("---\n");
++ return;
++}
++
++int ac101_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level)
++{
++ switch (level) {
++ case SND_SOC_BIAS_ON:
++ AC101_DBG("SND_SOC_BIAS_ON\n");
++ break;
++ case SND_SOC_BIAS_PREPARE:
++ AC101_DBG("SND_SOC_BIAS_PREPARE\n");
++ break;
++ case SND_SOC_BIAS_STANDBY:
++ AC101_DBG("SND_SOC_BIAS_STANDBY\n");
++ #ifdef CONFIG_AC101_SWITCH_DETECT
++ switch_hw_config(codec);
++ #endif
++ break;
++ case SND_SOC_BIAS_OFF:
++ #ifdef CONFIG_AC101_SWITCH_DETECT
++ ac101_update_bits(codec, ADC_APC_CTRL, (0x1<<HBIASEN), (0<<HBIASEN));
++ ac101_update_bits(codec, ADC_APC_CTRL, (0x1<<HBIASADCEN), (0<<HBIASADCEN));
++ #endif
++ ac101_update_bits(codec, OMIXER_DACA_CTRL, (0xf<<HPOUTPUTENABLE),
++ (0<<HPOUTPUTENABLE));
++ ac101_update_bits(codec, ADDA_TUNE3, (0x1<<OSCEN), (0<<OSCEN));
++ AC101_DBG("SND_SOC_BIAS_OFF\n");
++ break;
++ }
++ snd_soc_codec_get_dapm(codec)->bias_level = level;
++ return 0;
++}
++
++int ac101_codec_probe(struct snd_soc_codec *codec)
++{
++ int ret = 0;
++ struct ac10x_priv *ac10x;
++
++ ac10x = dev_get_drvdata(codec->dev);
++ if (ac10x == NULL) {
++ AC101_DBG("not set client data!\n");
++ return -ENOMEM;
++ }
++ ac10x->codec = codec;
++
++ INIT_DELAYED_WORK(&ac10x->dlywork, ac10x_work_aif_play);
++ INIT_WORK(&ac10x->codec_resume, codec_resume_work);
++ ac10x->dac_enable = 0;
++ ac10x->aif1_clken = 0;
++ mutex_init(&ac10x->dac_mutex);
++
++ set_configuration(ac10x->codec);
++
++ /*enable this bit to prevent leakage from ldoin*/
++ ac101_update_bits(codec, ADDA_TUNE3, (0x1<<OSCEN), (0x1<<OSCEN));
++ ac101_write(codec, DAC_VOL_CTRL, 0);
++
++ /* customized get/put inteface */
++ for (ret = 0; ret < ARRAY_SIZE(ac101_controls); ret++) {
++ struct snd_kcontrol_new* skn = &ac101_controls[ret];
++
++ skn->get = snd_ac101_get_volsw;
++ skn->put = snd_ac101_put_volsw;
++ }
++ ret = snd_soc_add_codec_controls(codec, ac101_controls, ARRAY_SIZE(ac101_controls));
++ if (ret) {
++ pr_err("[ac10x] Failed to register audio mode control, "
++ "will continue without it.\n");
++ }
++
++ #ifdef CONFIG_AC101_SWITCH_DETECT
++ ret = ac101_switch_probe(ac10x);
++ if (ret) {
++ // not care the switch return value
++ }
++ #endif
++
++ return 0;
++}
++
++/* power down chip */
++int ac101_codec_remove(struct snd_soc_codec *codec)
++{
++ #ifdef CONFIG_AC101_SWITCH_DETECT
++ struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
++
++ if (ac10x->irq) {
++ devm_free_irq(codec->dev, ac10x->irq, ac10x);
++ ac10x->irq = 0;
++ }
++
++ if (cancel_work_sync(&ac10x->work_switch) != 0) {
++ }
++
++ if (cancel_work_sync(&ac10x->work_clear_irq) != 0) {
++ }
++
++ if (ac10x->inpdev) {
++ input_unregister_device(ac10x->inpdev);
++ ac10x->inpdev = NULL;
++ }
++ #endif
++
++ return 0;
++}
++
++int ac101_codec_suspend(struct snd_soc_codec *codec)
++{
++ struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
++
++ AC101_DBG("[codec]:suspend\n");
++ regcache_cache_only(ac10x->regmap101, true);
++ return 0;
++}
++
++int ac101_codec_resume(struct snd_soc_codec *codec)
++{
++ struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
++ int ret;
++
++ AC101_DBG("[codec]:resume");
++
++ /* Sync reg_cache with the hardware */
++ regcache_cache_only(ac10x->regmap101, false);
++ ret = regcache_sync(ac10x->regmap101);
++ if (ret != 0) {
++ dev_err(codec->dev, "Failed to sync register cache: %d\n", ret);
++ regcache_cache_only(ac10x->regmap101, true);
++ return ret;
++ }
++
++ #ifdef CONFIG_AC101_SWITCH_DETECT
++ ac10x->mode = HEADPHONE_IDLE;
++ ac10x->state = -1;
++ #endif
++
++ ac101_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
++ schedule_work(&ac10x->codec_resume);
++ return 0;
++}
++
++/***************************************************************************/
++static ssize_t ac101_debug_store(struct device *dev,
++ struct device_attribute *attr, const char *buf, size_t count)
++{
++ struct ac10x_priv *ac10x = dev_get_drvdata(dev);
++ int val = 0, flag = 0;
++ u16 value_w, value_r;
++ u8 reg, num, i=0;
++
++ val = simple_strtol(buf, NULL, 16);
++ flag = (val >> 24) & 0xF;
++ if (flag) {
++ reg = (val >> 16) & 0xFF;
++ value_w = val & 0xFFFF;
++ ac101_write(ac10x->codec, reg, value_w);
++ printk("write 0x%x to reg:0x%x\n", value_w, reg);
++ } else {
++ reg = (val >> 8) & 0xFF;
++ num = val & 0xff;
++ printk("\n");
++ printk("read:start add:0x%x,count:0x%x\n", reg, num);
++
++ regcache_cache_bypass(ac10x->regmap101, true);
++ do {
++ value_r = ac101_read(ac10x->codec, reg);
++ printk("0x%x: 0x%04x ", reg++, value_r);
++ if (++i % 4 == 0 || i == num)
++ printk("\n");
++ } while (i < num);
++ regcache_cache_bypass(ac10x->regmap101, false);
++ }
++ return count;
++}
++static ssize_t ac101_debug_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ printk("echo flag|reg|val > ac10x\n");
++ printk("eg read star addres=0x06,count 0x10:echo 0610 >ac10x\n");
++ printk("eg write value:0x13fe to address:0x06 :echo 10613fe > ac10x\n");
++ return 0;
++}
++static DEVICE_ATTR(ac10x, 0644, ac101_debug_show, ac101_debug_store);
++
++static struct attribute *audio_debug_attrs[] = {
++ &dev_attr_ac10x.attr,
++ NULL,
++};
++
++static struct attribute_group audio_debug_attr_group = {
++ .name = "ac101_debug",
++ .attrs = audio_debug_attrs,
++};
++/***************************************************************************/
++
++/************************************************************/
++static bool ac101_volatile_reg(struct device *dev, unsigned int reg)
++{
++ switch (reg) {
++ case PLL_CTRL2:
++ case HMIC_STS:
++ return true;
++ }
++ return false;
++}
++
++static const struct regmap_config ac101_regmap = {
++ .reg_bits = 8,
++ .val_bits = 16,
++ .reg_stride = 1,
++ .max_register = 0xB5,
++ .cache_type = REGCACHE_FLAT,
++ .volatile_reg = ac101_volatile_reg,
++};
++
++/* Sync reg_cache from the hardware */
++int ac10x_fill_regcache(struct device* dev, struct regmap* map) {
++ int r, i, n;
++ int v;
++
++ n = regmap_get_max_register(map);
++ for (i = 0; i < n; i++) {
++ regcache_cache_bypass(map, true);
++ r = regmap_read(map, i, &v);
++ if (r) {
++ dev_dbg(dev, "failed to read register %d\n", i);
++ continue;
++ }
++ regcache_cache_bypass(map, false);
++
++ regcache_cache_only(map, true);
++ r = regmap_write(map, i, v);
++ regcache_cache_only(map, false);
++ }
++ regcache_cache_bypass(map, false);
++ regcache_cache_only(map, false);
++
++ return 0;
++}
++
++int ac101_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
++{
++ struct ac10x_priv *ac10x = i2c_get_clientdata(i2c);
++ int ret = 0;
++ unsigned v = 0;
++
++ AC101_DBG();
++
++ static_ac10x = ac10x;
++
++ ac10x->regmap101 = devm_regmap_init_i2c(i2c, &ac101_regmap);
++ if (IS_ERR(ac10x->regmap101)) {
++ ret = PTR_ERR(ac10x->regmap101);
++ dev_err(&i2c->dev, "Fail to initialize I/O: %d\n", ret);
++ return ret;
++ }
++
++ /* Chip reset */
++ regcache_cache_only(ac10x->regmap101, false);
++ ret = regmap_write(ac10x->regmap101, CHIP_AUDIO_RST, 0);
++ msleep(50);
++
++ /* sync regcache for FLAT type */
++ ac10x_fill_regcache(&i2c->dev, ac10x->regmap101);
++
++ ret = regmap_read(ac10x->regmap101, CHIP_AUDIO_RST, &v);
++ if (ret < 0) {
++ dev_err(&i2c->dev, "failed to read vendor ID: %d\n", ret);
++ return ret;
++ }
++
++ if (v != AC101_CHIP_ID) {
++ dev_err(&i2c->dev, "chip is not AC101 (%X)\n", v);
++ dev_err(&i2c->dev, "Expected %X\n", AC101_CHIP_ID);
++ return -ENODEV;
++ }
++
++ ret = sysfs_create_group(&i2c->dev.kobj, &audio_debug_attr_group);
++ if (ret) {
++ pr_err("failed to create attr group\n");
++ }
++
++ ac10x->gpiod_spk_amp_gate = devm_gpiod_get_optional(&i2c->dev, "spk-amp-switch",
++ GPIOD_OUT_LOW);
++ if (IS_ERR(ac10x->gpiod_spk_amp_gate)) {
++ ac10x->gpiod_spk_amp_gate = NULL;
++ dev_err(&i2c->dev, "failed get spk-amp-switch in device tree\n");
++ }
++
++ return 0;
++}
++
++void ac101_shutdown(struct i2c_client *i2c)
++{
++ struct ac10x_priv *ac10x = i2c_get_clientdata(i2c);
++ struct snd_soc_codec *codec = ac10x->codec;
++ int reg_val;
++
++ if (codec == NULL) {
++ pr_err(": no sound card.\n");
++ return;
++ }
++
++ /*set headphone volume to 0*/
++ reg_val = ac101_read(codec, HPOUT_CTRL);
++ reg_val &= ~(0x3f<<HP_VOL);
++ ac101_write(codec, HPOUT_CTRL, reg_val);
++
++ /*disable pa*/
++ reg_val = ac101_read(codec, HPOUT_CTRL);
++ reg_val &= ~(0x1<<HPPA_EN);
++ ac101_write(codec, HPOUT_CTRL, reg_val);
++
++ /*hardware xzh support*/
++ reg_val = ac101_read(codec, OMIXER_DACA_CTRL);
++ reg_val &= ~(0xf<<HPOUTPUTENABLE);
++ ac101_write(codec, OMIXER_DACA_CTRL, reg_val);
++
++ /*unmute l/r headphone pa*/
++ reg_val = ac101_read(codec, HPOUT_CTRL);
++ reg_val &= ~((0x1<<RHPPA_MUTE)|(0x1<<LHPPA_MUTE));
++ ac101_write(codec, HPOUT_CTRL, reg_val);
++ return;
++}
++
++int ac101_remove(struct i2c_client *i2c)
++{
++ sysfs_remove_group(&i2c->dev.kobj, &audio_debug_attr_group);
++ return 0;
++}
++
++MODULE_DESCRIPTION("ASoC ac10x driver");
++MODULE_AUTHOR("huangxin,liushaohua");
++MODULE_AUTHOR("PeterYang<linsheng.yang@seeed.cc>");
+--- /dev/null
++++ b/sound/soc/codecs/ac101_regs.h
+@@ -0,0 +1,431 @@
++/*
++ * ac101_regs.h
++ *
++ * (C) Copyright 2017-2018
++ * Seeed Technology Co., Ltd. <www.seeedstudio.com>
++ *
++ * PeterYang <linsheng.yang@seeed.cc>
++ *
++ * (C) Copyright 2010-2017
++ * Reuuimlla Technology Co., Ltd. <www.reuuimllatech.com>
++ * huangxin <huangxin@reuuimllatech.com>
++ *
++ * some simple description for this code
++ *
++ * 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 __AC101_REGS_H__
++#define __AC101_REGS_H__
++
++/*pll source*/
++#define AC101_MCLK1 1
++#define AC101_MCLK2 2
++#define AC101_BCLK1 3
++#define AC101_BCLK2 4
++
++#define AIF1_CLK 1
++#define AIF2_CLK 2
++
++#define CHIP_AUDIO_RST 0x0
++#define PLL_CTRL1 0x1
++#define PLL_CTRL2 0x2
++#define SYSCLK_CTRL 0x3
++#define MOD_CLK_ENA 0x4
++#define MOD_RST_CTRL 0x5
++#define AIF_SR_CTRL 0x6
++
++#define AIF1_CLK_CTRL 0x10
++#define AIF1_ADCDAT_CTRL 0x11
++#define AIF1_DACDAT_CTRL 0x12
++#define AIF1_MXR_SRC 0x13
++#define AIF1_VOL_CTRL1 0x14
++#define AIF1_VOL_CTRL2 0x15
++#define AIF1_VOL_CTRL3 0x16
++#define AIF1_VOL_CTRL4 0x17
++#define AIF1_MXR_GAIN 0x18
++#define AIF1_RXD_CTRL 0x19
++#define ADC_DIG_CTRL 0x40
++#define ADC_VOL_CTRL 0x41
++#define ADC_DBG_CTRL 0x42
++
++#define HMIC_CTRL1 0x44
++#define HMIC_CTRL2 0x45
++#define HMIC_STS 0x46
++
++#define DAC_DIG_CTRL 0x48
++#define DAC_VOL_CTRL 0x49
++#define DAC_DBG_CTRL 0x4a
++#define DAC_MXR_SRC 0x4c
++#define DAC_MXR_GAIN 0x4d
++
++#define ADC_APC_CTRL 0x50
++#define ADC_SRC 0x51
++#define ADC_SRCBST_CTRL 0x52
++#define OMIXER_DACA_CTRL 0x53
++#define OMIXER_SR 0x54
++#define OMIXER_BST1_CTRL 0x55
++#define HPOUT_CTRL 0x56
++#define ESPKOUT_CTRL 0x57
++#define SPKOUT_CTRL 0x58
++#define LOUT_CTRL 0x59
++#define ADDA_TUNE1 0x5a
++#define ADDA_TUNE2 0x5b
++#define ADDA_TUNE3 0x5c
++#define HPOUT_STR 0x5d
++
++/*CHIP_AUDIO_RST*/
++#define AC101_CHIP_ID 0x0101
++
++/*PLL_CTRL1*/
++#define DPLL_DAC_BIAS 14
++#define PLL_POSTDIV_M 8
++#define CLOSE_LOOP 6
++#define INT 0
++
++/*PLL_CTRL2*/
++#define PLL_EN 15
++#define PLL_LOCK_STATUS 14
++#define PLL_PREDIV_NI 4
++#define PLL_POSTDIV_NF 0
++
++/*SYSCLK_CTRL*/
++#define PLLCLK_ENA 15
++#define PLLCLK_SRC 12
++#define AIF1CLK_ENA 11
++#define AIF1CLK_SRC 8
++#define AIF2CLK_ENA 7
++#define AIF2CLK_SRC 4
++#define SYSCLK_ENA 3
++#define SYSCLK_SRC 0
++
++/*MOD_CLK_ENA*/
++#define MOD_CLK_AIF1 15
++#define MOD_CLK_AIF2 14
++#define MOD_CLK_AIF3 13
++#define MOD_CLK_SRC1 11
++#define MOD_CLK_SRC2 10
++#define MOD_CLK_HPF_AGC 7
++#define MOD_CLK_HPF_DRC 6
++#define MOD_CLK_ADC_DIG 3
++#define MOD_CLK_DAC_DIG 2
++
++/*MOD_RST_CTRL*/
++#define MOD_RESET_CTL 0
++#define MOD_RESET_AIF1 15
++#define MOD_RESET_AIF2 14
++#define MOD_RESET_AIF3 13
++#define MOD_RESET_SRC1 11
++#define MOD_RESET_SRC2 10
++#define MOD_RESET_HPF_AGC 7
++#define MOD_RESET_HPF_DRC 6
++#define MOD_RESET_ADC_DIG 3
++#define MOD_RESET_DAC_DIG 2
++
++/*AIF_SR_CTRL*/
++#define AIF1_FS 12 //AIF1 Sample Rate
++#define AIF2_FS 8 //AIF2 Sample Rate
++#define SRC1_ENA 3
++#define SRC1_SRC 2
++#define SRC2_ENA 1
++#define SRC2_SRC 0
++
++/*AIF1LCK_CTRL*/
++#define AIF1_MSTR_MOD 15
++#define AIF1_BCLK_INV 14
++#define AIF1_LRCK_INV 13
++#define AIF1_BCLK_DIV 9
++#define AIF1_LRCK_DIV 6
++#define AIF1_WORK_SIZ 4
++#define AIF1_DATA_FMT 2
++#define DSP_MONO_PCM 1
++#define AIF1_TDMM_ENA 0
++
++/*AIF1_ADCDAT_CTRL*/
++#define AIF1_AD0L_ENA 15
++#define AIF1_AD0R_ENA 14
++#define AIF1_AD1L_ENA 13
++#define AIF1_AD1R_ENA 12
++#define AIF1_AD0L_SRC 10
++#define AIF1_AD0R_SRC 8
++#define AIF1_AD1L_SRC 6
++#define AIF1_AD1R_SRC 4
++#define AIF1_ADCP_ENA 3
++#define AIF1_ADUL_ENA 2
++#define AIF1_SLOT_SIZ 0
++
++/*AIF1_DACDAT_CTRL*/
++#define AIF1_DA0L_ENA 15
++#define AIF1_DA0R_ENA 14
++#define AIF1_DA1L_ENA 13
++#define AIF1_DA1R_ENA 12
++#define AIF1_DA0L_SRC 10
++#define AIF1_DA0R_SRC 8
++#define AIF1_DA1L_SRC 6
++#define AIF1_DA1R_SRC 4
++#define AIF1_DACP_ENA 3
++#define AIF1_DAUL_ENA 2
++#define AIF1_SLOT_SIZ 0
++
++/*AIF1_MXR_SRC*/
++#define AIF1_AD0L_AIF1_DA0L_MXR 15
++#define AIF1_AD0L_AIF2_DACL_MXR 14
++#define AIF1_AD0L_ADCL_MXR 13
++#define AIF1_AD0L_AIF2_DACR_MXR 12
++#define AIF1_AD0R_AIF1_DA0R_MXR 11
++#define AIF1_AD0R_AIF2_DACR_MXR 10
++#define AIF1_AD0R_ADCR_MXR 9
++#define AIF1_AD0R_AIF2_DACL_MXR 8
++#define AIF1_AD1L_AIF2_DACL_MXR 7
++#define AIF1_AD1L_ADCL_MXR 6
++#define AIF1_AD1L_MXR_SRC 6
++#define AIF1_AD1R_AIF2_DACR_MXR 3
++#define AIF1_AD1R_ADCR_MXR 2
++#define AIF1_AD1R_MXR_SRC 2
++
++/*AIF1_VOL_CTRL1*/
++#define AIF1_AD0L_VOL 8
++#define AIF1_AD0R_VOL 0
++
++/*AIF1_VOL_CTRL2*/
++#define AIF1_AD1L_VOL 8
++#define AIF1_AD1R_VOL 0
++
++/*AIF1_VOL_CTRL3*/
++#define AIF1_DA0L_VOL 8
++#define AIF1_DA0R_VOL 0
++
++/*AIF1_VOL_CTRL4*/
++#define AIF1_DA1L_VOL 8
++#define AIF1_DA1R_VOL 0
++
++/*AIF1_MXR_GAIN*/
++#define AIF1_AD0L_MXR_GAIN 12
++#define AIF1_AD0R_MXR_GAIN 8
++#define AIF1_AD1L_MXR_GAIN 6
++#define AIF1_AD1R_MXR_GAIN 2
++
++/*AIF1_RXD_CTRL*/
++#define AIF1_N_DATA_DISCARD 8
++
++/*ADC_DIG_CTRL*/
++#define ENAD 15
++#define ENDM 14
++#define ADFIR32 13
++#define ADOUT_DTS 2
++#define ADOUT_DLY 1
++
++/*ADC_VOL_CTRL*/
++#define ADC_VOL_L 8
++#define ADC_VOL_R 0
++
++/*ADC_DBG_CTRL*/
++#define ADSW 15
++#define DMIC_CLK_PIN_CTRL 12
++
++/*HMIC_CTRL1*/
++#define HMIC_M 12
++#define HMIC_N 8
++#define HMIC_DATA_IRQ_MODE 7
++#define HMIC_TH1_HYSTERESIS 5
++#define HMIC_PULLOUT_IRQ 4
++#define HMIC_PLUGIN_IRQ 3
++#define HMIC_KEYUP_IRQ 2
++#define HMIC_KEYDOWN_IRQ 1
++#define HMIC_DATA_IRQ_EN 0
++
++/*HMIC_CTRL2*/
++#define HMIC_SAMPLE_SELECT 14
++#define HMIC_TH2_HYSTERESIS 13
++#define HMIC_TH2 8
++#define HMIC_SF 6
++#define KEYUP_CLEAR 5
++#define HMIC_TH1 0
++
++/*HMIC_STS*/
++#define HMIC_DATA 8
++#define GET_HMIC_DATA(r) (((r) >> HMIC_DATA) & 0x1F)
++#define HMIC_PULLOUT_PEND 4
++#define HMIC_PLUGIN_PEND 3
++#define HMIC_KEYUP_PEND 2
++#define HMKC_KEYDOWN_PEND 1
++#define HMIC_DATA_PEND 0
++#define HMIC_PEND_ALL (0x1F)
++
++/*DAC_DIG_CTRL*/
++#define ENDA 15
++#define ENHPF 14
++#define DAFIR32 13
++#define MODQU 8
++
++/*DAC_VOL_CTRL*/
++#define DAC_VOL_L 8
++#define DAC_VOL_R 0
++
++/*DAC_DBG_CTRL*/
++#define DASW 15
++#define ENDWA_N 14
++#define DAC_MOD_DBG 13
++#define DAC_PTN_SEL 6
++#define DVC 0
++
++/*DAC_MXR_SRC*/
++#define DACL_MXR_AIF1_DA0L 15
++#define DACL_MXR_AIF1_DA1L 14
++#define DACL_MXR_AIF2_DACL 13
++#define DACL_MXR_ADCL 12
++#define DACL_MXR_SRC 12
++#define DACR_MXR_AIF1_DA0R 11
++#define DACR_MXR_AIF1_DA1R 10
++#define DACR_MXR_AIF2_DACR 9
++#define DACR_MXR_ADCR 8
++#define DACR_MXR_SRC 8
++
++/*DAC_MXR_GAIN*/
++#define DACL_MXR_GAIN 12
++#define DACR_MXR_GAIN 8
++
++/*ADC_APC_CTRL*/
++#define ADCREN 15
++#define ADCRG 12
++#define ADCLEN 11
++#define ADCLG 8
++#define MBIASEN 7
++#define MMIC_BIAS_CHOP_EN 6
++#define MMIC_BIAS_CHOP_CKS 4
++#define HBIASMOD 2
++#define HBIASEN 1
++#define HBIASADCEN 0
++
++/*ADC_SRC*/
++#define RADCMIXMUTEMIC1BOOST (13)
++#define RADCMIXMUTEMIC2BOOST (12)
++#define RADCMIXMUTELINEINLR (11)
++#define RADCMIXMUTELINEINR (10)
++#define RADCMIXMUTEAUXINR (9)
++#define RADCMIXMUTEROUTPUT (8)
++#define RADCMIXMUTELOUTPUT (7)
++#define LADCMIXMUTEMIC1BOOST (6)
++#define LADCMIXMUTEMIC2BOOST (5)
++#define LADCMIXMUTELINEINLR (4)
++#define LADCMIXMUTELINEINL (3)
++#define LADCMIXMUTEAUXINL (2)
++#define LADCMIXMUTELOUTPUT (1)
++#define LADCMIXMUTEROUTPUT (0)
++
++/*ADC_SRCBST_CTRL*/
++#define MIC1AMPEN 15
++#define ADC_MIC1G 12
++#define MIC2AMPEN 11
++#define ADC_MIC2G 8
++#define MIC2SLT 7
++#define LINEIN_PREG 4
++#define AUXI_PREG 0
++
++/*OMIXER_DACA_CTRL*/
++#define DACAREN 15
++#define DACALEN 14
++#define RMIXEN 13
++#define LMIXEN 12
++#define HPOUTPUTENABLE 8
++
++/*OMIXER_SR*/
++#define RMIXMUTEMIC1BOOST (13)
++#define RMIXMUTEMIC2BOOST (12)
++#define RMIXMUTELINEINLR (11)
++#define RMIXMUTELINEINR (10)
++#define RMIXMUTEAUXINR (9)
++#define RMIXMUTEDACR (8)
++#define RMIXMUTEDACL (7)
++#define LMIXMUTEMIC1BOOST (6)
++#define LMIXMUTEMIC2BOOST (5)
++#define LMIXMUTELINEINLR (4)
++#define LMIXMUTELINEINL (3)
++#define LMIXMUTEAUXINL (2)
++#define LMIXMUTEDACL (1)
++#define LMIXMUTEDACR (0)
++
++/*OMIXER_BST1_CTRL*/
++#define BIASVOLTAGE 12
++#define AXG 9
++#define OMIXER_MIC1G 6
++#define OMIXER_MIC2G 3
++#define LINEING 0
++
++/*HPOUT_CTRL*/
++#define RHPS 15
++#define LHPS 14
++#define RHPPA_MUTE 13
++#define LHPPA_MUTE 12
++#define HPPA_EN 11
++#define HP_VOL 4
++#define HPPA_DEL 2
++#define HPPA_IS 0
++
++/*ESPKOUT_CTRL*/
++#define EAR_RAMP_TIME 11
++#define ESPA_OUT_CURRENT 9
++#define ESPSR 7
++#define ESPPA_MUTE 6
++#define ESPPA_EN 5
++#define ESP_VOL 0
++
++/*SPKOUT_CTRL*/
++#define HPCALICKS 13
++#define RSPKS 12
++#define RSPKINVEN 11
++#define RSPK_EN 9
++#define LSPKS 8
++#define LSPKINVEN 7
++#define LSPK_EN 5
++#define SPK_VOL 0
++
++/*LOUT_CTRL*/
++#define LINEOUTG 5
++#define LINEOUTEN 4
++#define LINEOUTS0 3
++#define LINEOUTS1 2
++#define LINEOUTS2 1
++#define LINEOUTS3 0
++
++/*ADDA_TUNE1*/
++#define CURRENT_TEST_SELECT 14
++#define BIHE_CTRL 12
++#define DITHER 11
++#define DITHER_CLK 9
++#define ZERO_CROSSOVER_EN 8
++#define ZERO_CROSSOVER_TIME 7
++#define EAR_SPEED_SELECT 6
++#define REF_CHOPPEN_CKS 4
++#define OPMIC_BIAS_CUR 0
++
++/*ADDA_TUNE2*/
++#define OPDAC_BIAS_CUR 14
++#define OPDRV_BIAS_CUR 12
++#define OPMIX_BIAS_CUR 10
++#define OPEAR_BIAS_CUR 8
++#define OPVR_BIAS_CUR 6
++#define OPAAF_BIAS_CUR 4
++#define OPADC1_BIAS_CUR 2
++#define OPADC2_BIAS_CUR 0
++
++/*ADDA_TUNE3*/
++#define LDOEN 15
++#define LDO_SEL 12
++#define BIASCALIVERIFY 11
++#define BIASMODE 10
++#define BIASCALIDATA 9
++#define OSCS 1
++#define OSCEN 0
++
++/*HPOUT_STR*/
++#define HPVL_SOFT_MOD 14
++#define HPVL_STEP_CTRL 8
++#define DACA_CHND_ENA 7
++#define HPPA_MXRD_ENA 6
++#define HPVL_CTRL_OUT 0
++
++#endif//__AC101_REGS_H__
+--- /dev/null
++++ b/sound/soc/codecs/ac108.c
+@@ -0,0 +1,1622 @@
++/*
++ * ac10x.c -- ac10x ALSA SoC Audio driver
++ *
++ *
++ * Author: Baozhu Zuo<zuobaozhu@gmail.com>
++ *
++ * 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.
++ */
++#include <linux/clk.h>
++#include <linux/delay.h>
++#include <linux/gpio/consumer.h>
++#include <linux/i2c.h>
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/pm.h>
++#include <linux/regmap.h>
++#include <linux/slab.h>
++#include <linux/workqueue.h>
++#include <sound/core.h>
++#include <sound/initval.h>
++#include <sound/pcm.h>
++#include <sound/pcm_params.h>
++#include <sound/soc.h>
++#include <sound/tlv.h>
++
++#include "ac108.h"
++#include "ac10x.h"
++
++#define _USE_CAPTURE 1
++#define _MASTER_INDEX 0
++
++/* #undef DEBUG
++ * use 'make DEBUG=1' to enable debugging
++ */
++
++/**
++ * TODO:
++ * 1, add PM API: ac108_suspend,ac108_resume
++ * 2,0x65-0x6a
++ * 3,0x76-0x79 high 4bit
++ */
++struct pll_div {
++ unsigned int freq_in;
++ unsigned int freq_out;
++ unsigned int m1;
++ unsigned int m2;
++ unsigned int n;
++ unsigned int k1;
++ unsigned int k2;
++};
++
++static struct ac10x_priv *ac10x;
++
++struct real_val_to_reg_val {
++ unsigned int real_val;
++ unsigned int reg_val;
++};
++
++static const struct real_val_to_reg_val ac108_sample_rate[] = {
++ { 8000, 0 },
++ { 11025, 1 },
++ { 12000, 2 },
++ { 16000, 3 },
++ { 22050, 4 },
++ { 24000, 5 },
++ { 32000, 6 },
++ { 44100, 7 },
++ { 48000, 8 },
++ { 96000, 9 },
++};
++
++/* Sample resolution */
++static const struct real_val_to_reg_val ac108_samp_res[] = {
++ { 8, 1 },
++ { 12, 2 },
++ { 16, 3 },
++ { 20, 4 },
++ { 24, 5 },
++ { 28, 6 },
++ { 32, 7 },
++};
++
++static const unsigned int ac108_bclkdivs[] = {
++ 0, 1, 2, 4,
++ 6, 8, 12, 16,
++ 24, 32, 48, 64,
++ 96, 128, 176, 192,
++};
++
++/* FOUT =(FIN * N) / [(M1+1) * (M2+1)*(K1+1)*(K2+1)] ; M1[0,31], M2[0,1], N[0,1023], K1[0,31], K2[0,1] */
++static const struct pll_div ac108_pll_div_list[] = {
++ { 400000, _FREQ_24_576K, 0, 0, 614, 4, 1 },
++ { 512000, _FREQ_24_576K, 0, 0, 960, 9, 1 }, /* _FREQ_24_576K/48 */
++ { 768000, _FREQ_24_576K, 0, 0, 640, 9, 1 }, /* _FREQ_24_576K/32 */
++ { 800000, _FREQ_24_576K, 0, 0, 614, 9, 1 },
++ { 1024000, _FREQ_24_576K, 0, 0, 480, 9, 1 }, /* _FREQ_24_576K/24 */
++ { 1600000, _FREQ_24_576K, 0, 0, 307, 9, 1 },
++ { 2048000, _FREQ_24_576K, 0, 0, 240, 9, 1 }, /* accurate, 8000 * 256 */
++ { 3072000, _FREQ_24_576K, 0, 0, 160, 9, 1 }, /* accurate, 12000 * 256 */
++ { 4096000, _FREQ_24_576K, 2, 0, 360, 9, 1 }, /* accurate, 16000 * 256 */
++ { 6000000, _FREQ_24_576K, 4, 0, 410, 9, 1 },
++ { 12000000, _FREQ_24_576K, 9, 0, 410, 9, 1 },
++ { 13000000, _FREQ_24_576K, 8, 0, 340, 9, 1 },
++ { 15360000, _FREQ_24_576K, 12, 0, 415, 9, 1 },
++ { 16000000, _FREQ_24_576K, 12, 0, 400, 9, 1 },
++ { 19200000, _FREQ_24_576K, 15, 0, 410, 9, 1 },
++ { 19680000, _FREQ_24_576K, 15, 0, 400, 9, 1 },
++ { 24000000, _FREQ_24_576K, 9, 0, 256,24, 0 }, /* accurate, 24M -> 24.576M */
++
++ { 400000, _FREQ_22_579K, 0, 0, 566, 4, 1 },
++ { 512000, _FREQ_22_579K, 0, 0, 880, 9, 1 },
++ { 768000, _FREQ_22_579K, 0, 0, 587, 9, 1 },
++ { 800000, _FREQ_22_579K, 0, 0, 567, 9, 1 },
++ { 1024000, _FREQ_22_579K, 0, 0, 440, 9, 1 },
++ { 1600000, _FREQ_22_579K, 1, 0, 567, 9, 1 },
++ { 2048000, _FREQ_22_579K, 0, 0, 220, 9, 1 },
++ { 3072000, _FREQ_22_579K, 0, 0, 148, 9, 1 },
++ { 4096000, _FREQ_22_579K, 2, 0, 330, 9, 1 },
++ { 6000000, _FREQ_22_579K, 2, 0, 227, 9, 1 },
++ { 12000000, _FREQ_22_579K, 8, 0, 340, 9, 1 },
++ { 13000000, _FREQ_22_579K, 9, 0, 350, 9, 1 },
++ { 15360000, _FREQ_22_579K, 10, 0, 325, 9, 1 },
++ { 16000000, _FREQ_22_579K, 11, 0, 340, 9, 1 },
++ { 19200000, _FREQ_22_579K, 13, 0, 330, 9, 1 },
++ { 19680000, _FREQ_22_579K, 14, 0, 345, 9, 1 },
++ { 24000000, _FREQ_22_579K, 24, 0, 588,24, 0 }, /* accurate, 24M -> 22.5792M */
++
++
++ { _FREQ_24_576K / 1, _FREQ_24_576K, 9, 0, 200, 9, 1 }, /* _FREQ_24_576K */
++ { _FREQ_24_576K / 2, _FREQ_24_576K, 9, 0, 400, 9, 1 }, /* 12288000,accurate, 48000 * 256 */
++ { _FREQ_24_576K / 4, _FREQ_24_576K, 4, 0, 400, 9, 1 }, /* 6144000, accurate, 24000 * 256 */
++ { _FREQ_24_576K / 16, _FREQ_24_576K, 0, 0, 320, 9, 1 }, /* 1536000 */
++ { _FREQ_24_576K / 64, _FREQ_24_576K, 0, 0, 640, 4, 1 }, /* 384000 */
++ { _FREQ_24_576K / 96, _FREQ_24_576K, 0, 0, 960, 4, 1 }, /* 256000 */
++ { _FREQ_24_576K / 128, _FREQ_24_576K, 0, 0, 512, 1, 1 }, /* 192000 */
++ { _FREQ_24_576K / 176, _FREQ_24_576K, 0, 0, 880, 4, 0 }, /* 140000 */
++ { _FREQ_24_576K / 192, _FREQ_24_576K, 0, 0, 960, 4, 0 }, /* 128000 */
++
++ { _FREQ_22_579K / 1, _FREQ_22_579K, 9, 0, 200, 9, 1 }, /* _FREQ_22_579K */
++ { _FREQ_22_579K / 2, _FREQ_22_579K, 9, 0, 400, 9, 1 }, /* 11289600,accurate, 44100 * 256 */
++ { _FREQ_22_579K / 4, _FREQ_22_579K, 4, 0, 400, 9, 1 }, /* 5644800, accurate, 22050 * 256 */
++ { _FREQ_22_579K / 16, _FREQ_22_579K, 0, 0, 320, 9, 1 }, /* 1411200 */
++ { _FREQ_22_579K / 64, _FREQ_22_579K, 0, 0, 640, 4, 1 }, /* 352800 */
++ { _FREQ_22_579K / 96, _FREQ_22_579K, 0, 0, 960, 4, 1 }, /* 235200 */
++ { _FREQ_22_579K / 128, _FREQ_22_579K, 0, 0, 512, 1, 1 }, /* 176400 */
++ { _FREQ_22_579K / 176, _FREQ_22_579K, 0, 0, 880, 4, 0 }, /* 128290 */
++ { _FREQ_22_579K / 192, _FREQ_22_579K, 0, 0, 960, 4, 0 }, /* 117600 */
++
++ { _FREQ_22_579K / 6, _FREQ_22_579K, 2, 0, 360, 9, 1 }, /* 3763200 */
++ { _FREQ_22_579K / 8, _FREQ_22_579K, 0, 0, 160, 9, 1 }, /* 2822400, accurate, 11025 * 256 */
++ { _FREQ_22_579K / 12, _FREQ_22_579K, 0, 0, 240, 9, 1 }, /* 1881600 */
++ { _FREQ_22_579K / 24, _FREQ_22_579K, 0, 0, 480, 9, 1 }, /* 940800 */
++ { _FREQ_22_579K / 32, _FREQ_22_579K, 0, 0, 640, 9, 1 }, /* 705600 */
++ { _FREQ_22_579K / 48, _FREQ_22_579K, 0, 0, 960, 9, 1 }, /* 470400 */
++};
++
++
++/* AC108 definition */
++#define AC108_CHANNELS_MAX 8 /* range[1, 16] */
++#define AC108_RATES (SNDRV_PCM_RATE_8000_96000 & \
++ ~(SNDRV_PCM_RATE_64000 | \
++ SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000))
++#define AC108_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
++ /*SNDRV_PCM_FMTBIT_S20_3LE | \
++ SNDRV_PCM_FMTBIT_S24_LE |*/ \
++ SNDRV_PCM_FMTBIT_S32_LE)
++
++static const DECLARE_TLV_DB_SCALE(tlv_adc_pga_gain, 0, 100, 0);
++static const DECLARE_TLV_DB_SCALE(tlv_ch_digital_vol, -11925, 75, 0);
++
++int ac10x_read(u8 reg, u8* rt_val, struct regmap* i2cm)
++{
++ int r, v = 0;
++
++ if ((r = regmap_read(i2cm, reg, &v)) < 0)
++ pr_info("ac10x_read info->[REG-0x%02x]\n", reg);
++ else
++ *rt_val = v;
++ return r;
++}
++
++int ac10x_write(u8 reg, u8 val, struct regmap* i2cm)
++{
++ int r;
++
++ if ((r = regmap_write(i2cm, reg, val)) < 0)
++ pr_info("ac10x_write info->[REG-0x%02x,val-0x%02x]\n", reg, val);
++ return r;
++}
++
++int ac10x_update_bits(u8 reg, u8 mask, u8 val, struct regmap* i2cm)
++{
++ int r;
++
++ if ((r = regmap_update_bits(i2cm, reg, mask, val)) < 0)
++ pr_info("%s() info->[REG-0x%02x,val-0x%02x]\n", __func__, reg, val);
++ return r;
++}
++
++/**
++ * snd_ac108_get_volsw - single mixer get callback
++ * @kcontrol: mixer control
++ * @ucontrol: control element information
++ *
++ * Callback to get the value of a single mixer control, or a double mixer
++ * control that spans 2 registers.
++ *
++ * Returns 0 for success.
++ */
++static int snd_ac108_get_volsw(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
++{
++ struct soc_mixer_control *mc =
++ (struct soc_mixer_control *)kcontrol->private_value;
++ unsigned int mask = (1 << fls(mc->max)) - 1;
++ unsigned int invert = mc->invert;
++ int ret, chip = mc->autodisable;
++ u8 val;
++
++ if ((ret = ac10x_read(mc->reg, &val, ac10x->i2cmap[chip])) < 0)
++ return ret;
++
++ val = ((val >> mc->shift) & mask) - mc->min;
++ if (invert) {
++ val = mc->max - val;
++ }
++ ucontrol->value.integer.value[0] = val;
++ return 0;
++}
++
++/**
++ * snd_ac108_put_volsw - single mixer put callback
++ * @kcontrol: mixer control
++ * @ucontrol: control element information
++ *
++ * Callback to set the value of a single mixer control, or a double mixer
++ * control that spans 2 registers.
++ *
++ * Returns 0 for success.
++ */
++static int snd_ac108_put_volsw(struct snd_kcontrol *kcontrol,
++ struct snd_ctl_elem_value *ucontrol)
++{
++ struct soc_mixer_control *mc =
++ (struct soc_mixer_control *)kcontrol->private_value;
++ unsigned int sign_bit = mc->sign_bit;
++ unsigned int val, mask = (1 << fls(mc->max)) - 1;
++ unsigned int invert = mc->invert;
++ int ret, chip = mc->autodisable;
++
++ if (sign_bit)
++ mask = BIT(sign_bit + 1) - 1;
++
++ val = ((ucontrol->value.integer.value[0] + mc->min) & mask);
++ if (invert) {
++ val = mc->max - val;
++ }
++
++ mask = mask << mc->shift;
++ val = val << mc->shift;
++
++ ret = ac10x_update_bits(mc->reg, mask, val, ac10x->i2cmap[chip]);
++ return ret;
++}
++
++#define SOC_AC108_SINGLE_TLV(xname, reg, shift, max, invert, chip, tlv_array) \
++{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
++ .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
++ SNDRV_CTL_ELEM_ACCESS_READWRITE,\
++ .tlv.p = (tlv_array), \
++ .info = snd_soc_info_volsw, .get = snd_ac108_get_volsw,\
++ .put = snd_ac108_put_volsw, \
++ .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert, chip) }
++
++/* single ac108 */
++static const struct snd_kcontrol_new ac108_snd_controls[] = {
++ /* ### chip 0 ### */
++ /*0x70: ADC1 Digital Channel Volume Control Register*/
++ SOC_AC108_SINGLE_TLV("CH1 digital volume", ADC1_DVOL_CTRL,
++ 0, 0xff, 0, 0, tlv_ch_digital_vol),
++ /*0x71: ADC2 Digital Channel Volume Control Register*/
++ SOC_AC108_SINGLE_TLV("CH2 digital volume", ADC2_DVOL_CTRL,
++ 0, 0xff, 0, 0, tlv_ch_digital_vol),
++ /*0x72: ADC3 Digital Channel Volume Control Register*/
++ SOC_AC108_SINGLE_TLV("CH3 digital volume", ADC3_DVOL_CTRL,
++ 0, 0xff, 0, 0, tlv_ch_digital_vol),
++ /*0x73: ADC4 Digital Channel Volume Control Register*/
++ SOC_AC108_SINGLE_TLV("CH4 digital volume", ADC4_DVOL_CTRL,
++ 0, 0xff, 0, 0, tlv_ch_digital_vol),
++
++ /*0x90: Analog PGA1 Control Register*/
++ SOC_AC108_SINGLE_TLV("ADC1 PGA gain", ANA_PGA1_CTRL,
++ ADC1_ANALOG_PGA, 0x1f, 0, 0, tlv_adc_pga_gain),
++ /*0x91: Analog PGA2 Control Register*/
++ SOC_AC108_SINGLE_TLV("ADC2 PGA gain", ANA_PGA2_CTRL,
++ ADC2_ANALOG_PGA, 0x1f, 0, 0, tlv_adc_pga_gain),
++ /*0x92: Analog PGA3 Control Register*/
++ SOC_AC108_SINGLE_TLV("ADC3 PGA gain", ANA_PGA3_CTRL,
++ ADC3_ANALOG_PGA, 0x1f, 0, 0, tlv_adc_pga_gain),
++ /*0x93: Analog PGA4 Control Register*/
++ SOC_AC108_SINGLE_TLV("ADC4 PGA gain", ANA_PGA4_CTRL,
++ ADC4_ANALOG_PGA, 0x1f, 0, 0, tlv_adc_pga_gain),
++};
++/* multiple ac108s */
++static const struct snd_kcontrol_new ac108tdm_snd_controls[] = {
++ /* ### chip 1 ### */
++ /*0x70: ADC1 Digital Channel Volume Control Register*/
++ SOC_AC108_SINGLE_TLV("CH1 digital volume", ADC1_DVOL_CTRL,
++ 0, 0xff, 0, 1, tlv_ch_digital_vol),
++ /*0x71: ADC2 Digital Channel Volume Control Register*/
++ SOC_AC108_SINGLE_TLV("CH2 digital volume", ADC2_DVOL_CTRL,
++ 0, 0xff, 0, 1, tlv_ch_digital_vol),
++ /*0x72: ADC3 Digital Channel Volume Control Register*/
++ SOC_AC108_SINGLE_TLV("CH3 digital volume", ADC3_DVOL_CTRL,
++ 0, 0xff, 0, 1, tlv_ch_digital_vol),
++ /*0x73: ADC4 Digital Channel Volume Control Register*/
++ SOC_AC108_SINGLE_TLV("CH4 digital volume", ADC4_DVOL_CTRL,
++ 0, 0xff, 0, 1, tlv_ch_digital_vol),
++
++ /*0x90: Analog PGA1 Control Register*/
++ SOC_AC108_SINGLE_TLV("ADC1 PGA gain", ANA_PGA1_CTRL,
++ ADC1_ANALOG_PGA, 0x1f, 0, 1, tlv_adc_pga_gain),
++ /*0x91: Analog PGA2 Control Register*/
++ SOC_AC108_SINGLE_TLV("ADC2 PGA gain", ANA_PGA2_CTRL,
++ ADC2_ANALOG_PGA, 0x1f, 0, 1, tlv_adc_pga_gain),
++ /*0x92: Analog PGA3 Control Register*/
++ SOC_AC108_SINGLE_TLV("ADC3 PGA gain", ANA_PGA3_CTRL,
++ ADC3_ANALOG_PGA, 0x1f, 0, 1, tlv_adc_pga_gain),
++ /*0x93: Analog PGA4 Control Register*/
++ SOC_AC108_SINGLE_TLV("ADC4 PGA gain", ANA_PGA4_CTRL,
++ ADC4_ANALOG_PGA, 0x1f, 0, 1, tlv_adc_pga_gain),
++
++ /* ### chip 0 ### */
++ /*0x70: ADC1 Digital Channel Volume Control Register*/
++ SOC_AC108_SINGLE_TLV("CH5 digital volume", ADC1_DVOL_CTRL,
++ 0, 0xff, 0, 0, tlv_ch_digital_vol),
++ /*0x71: ADC2 Digital Channel Volume Control Register*/
++ SOC_AC108_SINGLE_TLV("CH6 digital volume", ADC2_DVOL_CTRL,
++ 0, 0xff, 0, 0, tlv_ch_digital_vol),
++ /*0x72: ADC3 Digital Channel Volume Control Register*/
++ SOC_AC108_SINGLE_TLV("CH7 digital volume", ADC3_DVOL_CTRL,
++ 0, 0xff, 0, 0, tlv_ch_digital_vol),
++ /*0x73: ADC4 Digital Channel Volume Control Register*/
++ SOC_AC108_SINGLE_TLV("CH8 digital volume", ADC4_DVOL_CTRL,
++ 0, 0xff, 0, 0, tlv_ch_digital_vol),
++
++ /*0x90: Analog PGA1 Control Register*/
++ SOC_AC108_SINGLE_TLV("ADC5 PGA gain", ANA_PGA1_CTRL,
++ ADC1_ANALOG_PGA, 0x1f, 0, 0, tlv_adc_pga_gain),
++ /*0x91: Analog PGA2 Control Register*/
++ SOC_AC108_SINGLE_TLV("ADC6 PGA gain", ANA_PGA2_CTRL,
++ ADC2_ANALOG_PGA, 0x1f, 0, 0, tlv_adc_pga_gain),
++ /*0x92: Analog PGA3 Control Register*/
++ SOC_AC108_SINGLE_TLV("ADC7 PGA gain", ANA_PGA3_CTRL,
++ ADC3_ANALOG_PGA, 0x1f, 0, 0, tlv_adc_pga_gain),
++ /*0x93: Analog PGA4 Control Register*/
++ SOC_AC108_SINGLE_TLV("ADC8 PGA gain", ANA_PGA4_CTRL,
++ ADC4_ANALOG_PGA, 0x1f, 0, 0, tlv_adc_pga_gain),
++};
++
++
++static const struct snd_soc_dapm_widget ac108_dapm_widgets[] = {
++ /* input widgets */
++ SND_SOC_DAPM_INPUT("MIC1P"),
++ SND_SOC_DAPM_INPUT("MIC1N"),
++
++ SND_SOC_DAPM_INPUT("MIC2P"),
++ SND_SOC_DAPM_INPUT("MIC2N"),
++
++ SND_SOC_DAPM_INPUT("MIC3P"),
++ SND_SOC_DAPM_INPUT("MIC3N"),
++
++ SND_SOC_DAPM_INPUT("MIC4P"),
++ SND_SOC_DAPM_INPUT("MIC4N"),
++
++ SND_SOC_DAPM_INPUT("DMIC1"),
++ SND_SOC_DAPM_INPUT("DMIC2"),
++
++ /*0xa0: ADC1 Analog Control 1 Register*/
++ /*0xa1-0xa6:use the defualt value*/
++ SND_SOC_DAPM_AIF_IN("Channel 1 AAF", "Capture", 0, ANA_ADC1_CTRL1, ADC1_DSM_ENABLE, 1),
++ SND_SOC_DAPM_SUPPLY("Channel 1 EN", ANA_ADC1_CTRL1, ADC1_PGA_ENABLE, 1, NULL, 0),
++ SND_SOC_DAPM_MICBIAS("MIC1BIAS", ANA_ADC1_CTRL1, ADC1_MICBIAS_EN, 1),
++
++ /*0xa7: ADC2 Analog Control 1 Register*/
++ /*0xa8-0xad:use the defualt value*/
++ SND_SOC_DAPM_AIF_IN("Channel 2 AAF", "Capture", 0, ANA_ADC2_CTRL1, ADC2_DSM_ENABLE, 1),
++ SND_SOC_DAPM_SUPPLY("Channel 2 EN", ANA_ADC2_CTRL1, ADC2_PGA_ENABLE, 1, NULL, 0),
++ SND_SOC_DAPM_MICBIAS("MIC2BIAS", ANA_ADC2_CTRL1, ADC2_MICBIAS_EN, 1),
++
++ /*0xae: ADC3 Analog Control 1 Register*/
++ /*0xaf-0xb4:use the defualt value*/
++ SND_SOC_DAPM_AIF_IN("Channel 3 AAF", "Capture", 0, ANA_ADC3_CTRL1, ADC3_DSM_ENABLE, 1),
++ SND_SOC_DAPM_SUPPLY("Channel 3 EN", ANA_ADC3_CTRL1, ADC3_PGA_ENABLE, 1, NULL, 0),
++ SND_SOC_DAPM_MICBIAS("MIC3BIAS", ANA_ADC3_CTRL1, ADC3_MICBIAS_EN, 1),
++
++ /*0xb5: ADC4 Analog Control 1 Register*/
++ /*0xb6-0xbb:use the defualt value*/
++ SND_SOC_DAPM_AIF_IN("Channel 4 AAF", "Capture", 0, ANA_ADC4_CTRL1, ADC4_DSM_ENABLE, 1),
++ SND_SOC_DAPM_SUPPLY("Channel 4 EN", ANA_ADC4_CTRL1, ADC4_PGA_ENABLE, 1, NULL, 0),
++ SND_SOC_DAPM_MICBIAS("MIC4BIAS", ANA_ADC4_CTRL1, ADC4_MICBIAS_EN, 1),
++
++
++ /*0x61: ADC Digital Part Enable Register*/
++ SND_SOC_DAPM_SUPPLY("ADC EN", ADC_DIG_EN, 4, 1, NULL, 0),
++ SND_SOC_DAPM_ADC("ADC1", "Capture", ADC_DIG_EN, 0, 1),
++ SND_SOC_DAPM_ADC("ADC2", "Capture", ADC_DIG_EN, 1, 1),
++ SND_SOC_DAPM_ADC("ADC3", "Capture", ADC_DIG_EN, 2, 1),
++ SND_SOC_DAPM_ADC("ADC4", "Capture", ADC_DIG_EN, 3, 1),
++
++ SND_SOC_DAPM_SUPPLY("ADC1 CLK", ANA_ADC4_CTRL7, ADC1_CLK_GATING, 1, NULL, 0),
++ SND_SOC_DAPM_SUPPLY("ADC2 CLK", ANA_ADC4_CTRL7, ADC2_CLK_GATING, 1, NULL, 0),
++ SND_SOC_DAPM_SUPPLY("ADC3 CLK", ANA_ADC4_CTRL7, ADC3_CLK_GATING, 1, NULL, 0),
++ SND_SOC_DAPM_SUPPLY("ADC4 CLK", ANA_ADC4_CTRL7, ADC4_CLK_GATING, 1, NULL, 0),
++
++ SND_SOC_DAPM_SUPPLY("DSM EN", ANA_ADC4_CTRL6, DSM_DEMOFF, 1, NULL, 0),
++
++ /*0x62:Digital MIC Enable Register*/
++ SND_SOC_DAPM_MICBIAS("DMIC1 enable", DMIC_EN, 0, 0),
++ SND_SOC_DAPM_MICBIAS("DMIC2 enable", DMIC_EN, 1, 0),
++};
++
++static const struct snd_soc_dapm_route ac108_dapm_routes[] = {
++
++ { "ADC1", NULL, "Channel 1 AAF" },
++ { "ADC2", NULL, "Channel 2 AAF" },
++ { "ADC3", NULL, "Channel 3 AAF" },
++ { "ADC4", NULL, "Channel 4 AAF" },
++
++ { "Channel 1 AAF", NULL, "MIC1BIAS" },
++ { "Channel 2 AAF", NULL, "MIC2BIAS" },
++ { "Channel 3 AAF", NULL, "MIC3BIAS" },
++ { "Channel 4 AAF", NULL, "MIC4BIAS" },
++
++ { "MIC1BIAS", NULL, "ADC1 CLK" },
++ { "MIC2BIAS", NULL, "ADC2 CLK" },
++ { "MIC3BIAS", NULL, "ADC3 CLK" },
++ { "MIC4BIAS", NULL, "ADC4 CLK" },
++
++
++ { "ADC1 CLK", NULL, "DSM EN" },
++ { "ADC2 CLK", NULL, "DSM EN" },
++ { "ADC3 CLK", NULL, "DSM EN" },
++ { "ADC4 CLK", NULL, "DSM EN" },
++
++
++ { "DSM EN", NULL, "ADC EN" },
++
++ { "Channel 1 EN", NULL, "DSM EN" },
++ { "Channel 2 EN", NULL, "DSM EN" },
++ { "Channel 3 EN", NULL, "DSM EN" },
++ { "Channel 4 EN", NULL, "DSM EN" },
++
++
++ { "MIC1P", NULL, "Channel 1 EN" },
++ { "MIC1N", NULL, "Channel 1 EN" },
++
++ { "MIC2P", NULL, "Channel 2 EN" },
++ { "MIC2N", NULL, "Channel 2 EN" },
++
++ { "MIC3P", NULL, "Channel 3 EN" },
++ { "MIC3N", NULL, "Channel 3 EN" },
++
++ { "MIC4P", NULL, "Channel 4 EN" },
++ { "MIC4N", NULL, "Channel 4 EN" },
++
++};
++
++static int ac108_multi_write(u8 reg, u8 val, struct ac10x_priv *ac10x)
++{
++ u8 i;
++ for (i = 0; i < ac10x->codec_cnt; i++)
++ ac10x_write(reg, val, ac10x->i2cmap[i]);
++ return 0;
++}
++
++static int ac108_multi_update_bits(u8 reg, u8 mask, u8 val, struct ac10x_priv *ac10x)
++{
++ int r = 0;
++ u8 i;
++ for (i = 0; i < ac10x->codec_cnt; i++)
++ r |= ac10x_update_bits(reg, mask, val, ac10x->i2cmap[i]);
++ return r;
++}
++
++static unsigned int ac108_codec_read(struct snd_soc_codec *codec, unsigned int reg)
++{
++ unsigned char val_r;
++ struct ac10x_priv *ac10x = dev_get_drvdata(codec->dev);
++ /*read one chip is fine*/
++ ac10x_read(reg, &val_r, ac10x->i2cmap[_MASTER_INDEX]);
++ return val_r;
++}
++
++static int ac108_codec_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int val)
++{
++ struct ac10x_priv *ac10x = dev_get_drvdata(codec->dev);
++ ac108_multi_write(reg, val, ac10x);
++ return 0;
++}
++
++/**
++ * The Power management related registers are Reg01h~Reg09h
++ * 0x01-0x05,0x08,use the default value
++ * @author baozhu (17-6-21)
++ *
++ * @param ac10x
++ */
++static void ac108_configure_power(struct ac10x_priv *ac10x)
++{
++ /**
++ * 0x06:Enable Analog LDO
++ */
++ ac108_multi_update_bits(PWR_CTRL6, 0x01 << LDO33ANA_ENABLE, 0x01 << LDO33ANA_ENABLE, ac10x);
++ /**
++ * 0x07:
++ * Control VREF output and micbias voltage ?
++ * REF faststart disable, enable Enable VREF (needed for Analog
++ * LDO and MICBIAS)
++ */
++ ac108_multi_update_bits(PWR_CTRL7,
++ 0x1f << VREF_SEL | 0x01 << VREF_FASTSTART_ENABLE |
++ 0x01 << VREF_ENABLE,
++ 0x13 << VREF_SEL | 0x00 << VREF_FASTSTART_ENABLE |
++ 0x01 << VREF_ENABLE,
++ ac10x);
++ /**
++ * 0x09:
++ * Disable fast-start circuit on VREFP
++ * VREFP_RESCTRL=00=1 MOhm
++ * IGEN_TRIM=100=+25%
++ * Enable VREFP (needed by all audio input channels)
++ */
++ ac108_multi_update_bits(PWR_CTRL9,
++ 0x01 << VREFP_FASTSTART_ENABLE | 0x03 << VREFP_RESCTRL |
++ 0x07 << IGEN_TRIM | 0x01 << VREFP_ENABLE,
++ 0x00 << VREFP_FASTSTART_ENABLE | 0x00 << VREFP_RESCTRL |
++ 0x04 << IGEN_TRIM | 0x01 << VREFP_ENABLE,
++ ac10x);
++}
++
++/**
++ * The clock management related registers are Reg20h~Reg25h
++ * The PLL management related registers are Reg10h~Reg18h.
++ * @author baozhu (17-6-20)
++ *
++ * @param ac10x
++ * @param rate : sample rate
++ *
++ * @return int : fail or success
++ */
++static int ac108_config_pll(struct ac10x_priv *ac10x, unsigned rate, unsigned lrck_ratio)
++{
++ unsigned int i = 0;
++ struct pll_div ac108_pll_div = { 0 };
++
++ if (ac10x->clk_id == SYSCLK_SRC_PLL) {
++ unsigned pll_src, pll_freq_in;
++
++ if (lrck_ratio == 0) {
++ /* PLL clock source from MCLK */
++ pll_freq_in = ac10x->sysclk;
++ pll_src = 0x0;
++ } else {
++ /* PLL clock source from BCLK */
++ pll_freq_in = rate * lrck_ratio;
++ pll_src = 0x1;
++ }
++
++ /* FOUT =(FIN * N) / [(M1+1) * (M2+1)*(K1+1)*(K2+1)] */
++ for (i = 0; i < ARRAY_SIZE(ac108_pll_div_list); i++) {
++ if (ac108_pll_div_list[i].freq_in == pll_freq_in &&
++ ac108_pll_div_list[i].freq_out % rate == 0) {
++ ac108_pll_div = ac108_pll_div_list[i];
++ dev_info(&ac10x->i2c[_MASTER_INDEX]->dev,
++ "AC108 PLL freq_in match:%u, freq_out:%u\n\n",
++ ac108_pll_div.freq_in, ac108_pll_div.freq_out);
++ break;
++ }
++ }
++ /* 0x11,0x12,0x13,0x14: Config PLL DIV param M1/M2/N/K1/K2 */
++ ac108_multi_update_bits(PLL_CTRL5,
++ 0x1f << PLL_POSTDIV1 | 0x01 << PLL_POSTDIV2,
++ ac108_pll_div.k1 << PLL_POSTDIV1 |
++ ac108_pll_div.k2 << PLL_POSTDIV2, ac10x);
++ ac108_multi_update_bits(PLL_CTRL4, 0xff << PLL_LOOPDIV_LSB,
++ (unsigned char)ac108_pll_div.n << PLL_LOOPDIV_LSB, ac10x);
++ ac108_multi_update_bits(PLL_CTRL3, 0x03 << PLL_LOOPDIV_MSB,
++ (ac108_pll_div.n >> 8) << PLL_LOOPDIV_MSB, ac10x);
++ ac108_multi_update_bits(PLL_CTRL2, 0x1f << PLL_PREDIV1 | 0x01 << PLL_PREDIV2,
++ ac108_pll_div.m1 << PLL_PREDIV1 |
++ ac108_pll_div.m2 << PLL_PREDIV2, ac10x);
++
++ /*0x18: PLL clk lock enable*/
++ ac108_multi_update_bits(PLL_LOCK_CTRL, 0x1 << PLL_LOCK_EN,
++ 0x1 << PLL_LOCK_EN, ac10x);
++
++ /**
++ * 0x20: enable pll, pll source from mclk/bclk, sysclk source from pll, enable sysclk
++ */
++ ac108_multi_update_bits(SYSCLK_CTRL,
++ 0x01 << PLLCLK_EN | 0x03 << PLLCLK_SRC |
++ 0x01 << SYSCLK_SRC | 0x01 << SYSCLK_EN,
++ 0x01 << PLLCLK_EN | pll_src << PLLCLK_SRC |
++ 0x01 << SYSCLK_SRC | 0x01 << SYSCLK_EN, ac10x);
++ ac10x->mclk = ac108_pll_div.freq_out;
++ }
++ if (ac10x->clk_id == SYSCLK_SRC_MCLK) {
++ /**
++ *0x20: sysclk source from mclk, enable sysclk
++ */
++ ac108_multi_update_bits(SYSCLK_CTRL,
++ 0x01 << PLLCLK_EN | 0x01 << SYSCLK_SRC | 0x01 << SYSCLK_EN,
++ 0x00 << PLLCLK_EN | 0x00 << SYSCLK_SRC | 0x01 << SYSCLK_EN,
++ ac10x);
++ ac10x->mclk = ac10x->sysclk;
++ }
++
++ return 0;
++}
++
++/*
++ * support no more than 16 slots.
++ */
++static int ac108_multi_chips_slots(struct ac10x_priv *ac, int slots)
++{
++ int i;
++
++ /*
++ * codec0 enable slots 2,3,0,1 when 1 codec
++ *
++ * codec0 enable slots 6,7,0,1 when 2 codec
++ * codec1 enable slots 2,3,4,5
++ *
++ * ...
++ */
++ for (i = 0; i < ac->codec_cnt; i++) {
++ /* rotate map, due to channels rotated by CPU_DAI */
++ const unsigned vec_mask[] = {
++ 0x3 << 6 | 0x3, // slots 6,7,0,1
++ 0xF << 2, // slots 2,3,4,5
++ 0,
++ 0,
++ };
++ const unsigned vec_maps[] = {
++ /*
++ * chip 0,
++ * mic 0 sample -> slot 6
++ * mic 1 sample -> slot 7
++ * mic 2 sample -> slot 0
++ * mic 3 sample -> slot 1
++ */
++ 0x0 << 12 | 0x1 << 14 | 0x2 << 0 | 0x3 << 2,
++ /*
++ * chip 1,
++ * mic 0 sample -> slot 2
++ * mic 1 sample -> slot 3
++ * mic 2 sample -> slot 4
++ * mic 3 sample -> slot 5
++ */
++ 0x0 << 4 | 0x1 << 6 | 0x2 << 8 | 0x3 << 10,
++ 0,
++ 0,
++ };
++ unsigned vec;
++
++ /* 0x38-0x3A I2S_TX1_CTRLx */
++ if (ac->codec_cnt == 1) {
++ vec = 0xFUL;
++ } else {
++ vec = vec_mask[i];
++ }
++ ac10x_write(I2S_TX1_CTRL1, slots - 1, ac->i2cmap[i]);
++ ac10x_write(I2S_TX1_CTRL2, (vec >> 0) & 0xFF, ac->i2cmap[i]);
++ ac10x_write(I2S_TX1_CTRL3, (vec >> 8) & 0xFF, ac->i2cmap[i]);
++
++ /* 0x3C-0x3F I2S_TX1_CHMP_CTRLx */
++ if (ac->codec_cnt == 1) {
++ vec = (0x2 << 0 | 0x3 << 2 | 0x0 << 4 | 0x1 << 6);
++ } else if (ac->codec_cnt == 2) {
++ vec = vec_maps[i];
++ }
++
++ ac10x_write(I2S_TX1_CHMP_CTRL1, (vec >> 0) & 0xFF, ac->i2cmap[i]);
++ ac10x_write(I2S_TX1_CHMP_CTRL2, (vec >> 8) & 0xFF, ac->i2cmap[i]);
++ ac10x_write(I2S_TX1_CHMP_CTRL3, (vec >> 16) & 0xFF, ac->i2cmap[i]);
++ ac10x_write(I2S_TX1_CHMP_CTRL4, (vec >> 24) & 0xFF, ac->i2cmap[i]);
++ }
++ return 0;
++}
++
++static int ac108_hw_params(struct snd_pcm_substream *substream,
++ struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
++{
++ unsigned int i, channels, samp_res, rate;
++ struct snd_soc_codec *codec = dai->codec;
++ struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
++ unsigned bclkdiv;
++ int ret = 0;
++ u8 v;
++
++ dev_dbg(dai->dev, "%s() stream=%s play:%d capt:%d +++\n", __func__,
++ snd_pcm_stream_str(substream),
++ dai->stream[SNDRV_PCM_STREAM_PLAYBACK].active,
++ dai->stream[SNDRV_PCM_STREAM_CAPTURE].active);
++
++ if (ac10x->i2c101) {
++ ret = ac101_hw_params(substream, params, dai);
++ if (ret > 0) {
++ dev_dbg(dai->dev, "%s() L%d returned\n", __func__, __LINE__);
++ /* not configure hw_param twice */
++ return 0;
++ }
++ }
++
++ if ((substream->stream == SNDRV_PCM_STREAM_CAPTURE &&
++ dai->stream[SNDRV_PCM_STREAM_PLAYBACK].active)
++ || (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
++ dai->stream[SNDRV_PCM_STREAM_CAPTURE].active)) {
++ /* not configure hw_param twice */
++ /* return 0; */
++ }
++
++ channels = params_channels(params);
++
++ /* Master mode, to clear cpu_dai fifos, output bclk without lrck */
++ ac10x_read(I2S_CTRL, &v, ac10x->i2cmap[_MASTER_INDEX]);
++ if (v & (0x01 << BCLK_IOEN)) {
++ ac10x_update_bits(I2S_CTRL, 0x1 << LRCK_IOEN,
++ 0x0 << LRCK_IOEN, ac10x->i2cmap[_MASTER_INDEX]);
++ }
++
++ switch (params_format(params)) {
++ case SNDRV_PCM_FORMAT_S8:
++ samp_res = 0;
++ break;
++ case SNDRV_PCM_FORMAT_S16_LE:
++ samp_res = 2;
++ break;
++ case SNDRV_PCM_FORMAT_S20_3LE:
++ samp_res = 3;
++ break;
++ case SNDRV_PCM_FORMAT_S24_LE:
++ samp_res = 4;
++ break;
++ case SNDRV_PCM_FORMAT_S32_LE:
++ samp_res = 6;
++ break;
++ default:
++ dev_err(dai->dev, "AC108 don't supported the sample resolution: %u\n",
++ params_format(params));
++ return -EINVAL;
++ }
++
++ for (i = 0; i < ARRAY_SIZE(ac108_sample_rate); i++) {
++ if (ac108_sample_rate[i].real_val == params_rate(params) /
++ (ac10x->data_protocol + 1UL)) {
++ rate = i;
++ break;
++ }
++ }
++ if (i >= ARRAY_SIZE(ac108_sample_rate)) {
++ return -EINVAL;
++ }
++
++ if (channels == 8 && ac108_sample_rate[rate].real_val == 96000) {
++ /* 24.576M bit clock is not support by ac108 */
++ return -EINVAL;
++ }
++
++ dev_dbg(dai->dev, "rate: %d , channels: %d , samp_res: %d",
++ ac108_sample_rate[rate].real_val,
++ channels,
++ ac108_samp_res[samp_res].real_val);
++
++ /**
++ * 0x33:
++ * The 8-Low bit of LRCK period value. It is used to program
++ * the number of BCLKs per channel of sample frame. This value
++ * is interpreted as follow:
++ * The 8-Low bit of LRCK period value. It is used to program
++ * the number of BCLKs per channel of sample frame. This value
++ * is interpreted as follow: PCM mode: Number of BCLKs within
++ * (Left + Right) channel width I2S / Left-Justified /
++ * Right-Justified mode: Number of BCLKs within each individual
++ * channel width (Left or Right) N+1
++ * For example:
++ * n = 7: 8 BCLK width
++ * …
++ * n = 1023: 1024 BCLKs width
++ * 0X32[0:1]:
++ * The 2-High bit of LRCK period value.
++ */
++ if (ac10x->i2s_mode != PCM_FORMAT) {
++ if (ac10x->data_protocol) {
++ ac108_multi_write(I2S_LRCK_CTRL2, ac108_samp_res[samp_res].real_val - 1,
++ ac10x);
++ /*encoding mode, the max LRCK period value < 32,so the 2-High bit is zero*/
++ ac108_multi_update_bits(I2S_LRCK_CTRL1, 0x03 << 0, 0x00, ac10x);
++ } else {
++ /*TDM mode or normal mode*/
++ //ac108_multi_update_bits(I2S_LRCK_CTRL1, 0x03 << 0, 0x00, ac10x);
++ ac108_multi_write(I2S_LRCK_CTRL2, ac108_samp_res[samp_res].real_val - 1,
++ ac10x);
++ ac108_multi_update_bits(I2S_LRCK_CTRL1, 0x03 << 0, 0x00, ac10x);
++ }
++ } else {
++ unsigned div;
++
++ /*TDM mode or normal mode*/
++ div = ac108_samp_res[samp_res].real_val * channels - 1;
++ ac108_multi_write(I2S_LRCK_CTRL2, (div & 0xFF), ac10x);
++ ac108_multi_update_bits(I2S_LRCK_CTRL1, 0x03 << 0, (div >> 8) << 0, ac10x);
++ }
++
++ /**
++ * 0x35:
++ * TX Encoding mode will add 4bits to mark channel number
++ * TODO: need a chat to explain this
++ */
++ ac108_multi_update_bits(I2S_FMT_CTRL2, 0x07 << SAMPLE_RESOLUTION | 0x07 << SLOT_WIDTH_SEL,
++ ac108_samp_res[samp_res].reg_val << SAMPLE_RESOLUTION |
++ ac108_samp_res[samp_res].reg_val << SLOT_WIDTH_SEL, ac10x);
++
++ /**
++ * 0x60:
++ * ADC Sample Rate synchronised with I2S1 clock zone
++ */
++ ac108_multi_update_bits(ADC_SPRC, 0x0f << ADC_FS_I2S1,
++ ac108_sample_rate[rate].reg_val << ADC_FS_I2S1, ac10x);
++ ac108_multi_write(HPF_EN, 0x0F, ac10x);
++
++ if (ac10x->i2c101 && _MASTER_MULTI_CODEC == _MASTER_AC101) {
++ ac108_config_pll(ac10x, ac108_sample_rate[rate].real_val,
++ ac108_samp_res[samp_res].real_val * channels);
++ } else {
++ ac108_config_pll(ac10x, ac108_sample_rate[rate].real_val, 0);
++ }
++
++ /*
++ * master mode only
++ */
++ bclkdiv = ac10x->mclk / (ac108_sample_rate[rate].real_val * channels *
++ ac108_samp_res[samp_res].real_val);
++ for (i = 0; i < ARRAY_SIZE(ac108_bclkdivs) - 1; i++) {
++ if (ac108_bclkdivs[i] >= bclkdiv) {
++ break;
++ }
++ }
++ ac108_multi_update_bits(I2S_BCLK_CTRL, 0x0F << BCLKDIV, i << BCLKDIV, ac10x);
++
++ /*
++ * slots allocation for each chip
++ */
++ ac108_multi_chips_slots(ac10x, channels);
++
++ /*0x21: Module clock enable<I2S, ADC digital, MIC offset Calibration, ADC analog>*/
++ ac108_multi_write(MOD_CLK_EN, 1 << I2S | 1 << ADC_DIGITAL |
++ 1 << MIC_OFFSET_CALIBRATION | 1 << ADC_ANALOG, ac10x);
++ /*0x22: Module reset de-asserted<I2S, ADC digital, MIC offset Calibration, ADC analog>*/
++ ac108_multi_write(MOD_RST_CTRL, 1 << I2S | 1 << ADC_DIGITAL |
++ 1 << MIC_OFFSET_CALIBRATION | 1 << ADC_ANALOG, ac10x);
++
++ ac108_multi_write(I2S_TX1_CHMP_CTRL1, 0xE4, ac10x);
++ ac108_multi_write(I2S_TX1_CHMP_CTRL2, 0xE4, ac10x);
++ ac108_multi_write(I2S_TX1_CHMP_CTRL3, 0xE4, ac10x);
++ ac108_multi_write(I2S_TX1_CHMP_CTRL4, 0xE4, ac10x);
++
++ ac108_multi_write(I2S_TX2_CHMP_CTRL1, 0xE4, ac10x);
++ ac108_multi_write(I2S_TX2_CHMP_CTRL2, 0xE4, ac10x);
++ ac108_multi_write(I2S_TX2_CHMP_CTRL3, 0xE4, ac10x);
++ ac108_multi_write(I2S_TX2_CHMP_CTRL4, 0xE4, ac10x);
++
++ dev_dbg(dai->dev, "%s() stream=%s ---\n", __func__,
++ snd_pcm_stream_str(substream));
++
++ return 0;
++}
++
++static int ac108_set_sysclk(struct snd_soc_dai *dai, int clk_id, unsigned int freq, int dir)
++{
++
++ struct ac10x_priv *ac10x = snd_soc_dai_get_drvdata(dai);
++
++ freq = 24000000;
++ clk_id = SYSCLK_SRC_PLL;
++
++ switch (clk_id) {
++ case SYSCLK_SRC_MCLK:
++ ac108_multi_update_bits(SYSCLK_CTRL, 0x1 << SYSCLK_SRC,
++ SYSCLK_SRC_MCLK << SYSCLK_SRC, ac10x);
++ break;
++ case SYSCLK_SRC_PLL:
++ ac108_multi_update_bits(SYSCLK_CTRL, 0x1 << SYSCLK_SRC,
++ SYSCLK_SRC_PLL << SYSCLK_SRC, ac10x);
++ break;
++ default:
++ return -EINVAL;
++ }
++ ac10x->sysclk = freq;
++ ac10x->clk_id = clk_id;
++
++ return 0;
++}
++
++/**
++ * The i2s format management related registers are Reg
++ * 30h~Reg36h
++ * 33h,35h will be set in ac108_hw_params, It's BCLK width and
++ * Sample Resolution.
++ * @author baozhu (17-6-20)
++ *
++ * @param dai
++ * @param fmt
++ *
++ * @return int
++ */
++static int ac108_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
++{
++ unsigned char tx_offset, lrck_polarity, brck_polarity;
++ struct ac10x_priv *ac10x = dev_get_drvdata(dai->dev);
++
++ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
++ case SND_SOC_DAIFMT_CBM_CFM: /* AC108 Master */
++ if (! ac10x->i2c101 || _MASTER_MULTI_CODEC == _MASTER_AC108) {
++ /**
++ * 0x30:chip is master mode ,BCLK & LRCK output
++ */
++ ac108_multi_update_bits(I2S_CTRL,
++ 0x03 << LRCK_IOEN | 0x03 << SDO1_EN |
++ 0x1 << TXEN | 0x1 << GEN,
++ 0x03 << LRCK_IOEN | 0x01 << SDO1_EN |
++ 0x1 << TXEN | 0x1 << GEN, ac10x);
++ /* multi_chips: only one chip set as Master, and the others also need to set as Slave */
++ ac10x_update_bits(I2S_CTRL, 0x3 << LRCK_IOEN, 0x01 << BCLK_IOEN,
++ ac10x->i2cmap[_MASTER_INDEX]);
++ } else {
++ /* TODO: Both cpu_dai and codec_dai(AC108) be set as slave in DTS */
++ dev_err(dai->dev, "used as slave when AC101 is master\n");
++ }
++ break;
++ case SND_SOC_DAIFMT_CBS_CFS: /* AC108 Slave */
++ /**
++ * 0x30:chip is slave mode, BCLK & LRCK input,enable SDO1_EN and
++ * SDO2_EN, Transmitter Block Enable, Globe Enable
++ */
++ ac108_multi_update_bits(I2S_CTRL,
++ 0x03 << LRCK_IOEN | 0x03 << SDO1_EN |
++ 0x1 << TXEN | 0x1 << GEN,
++ 0x00 << LRCK_IOEN | 0x03 << SDO1_EN |
++ 0x0 << TXEN | 0x0 << GEN, ac10x);
++ break;
++ default:
++ dev_err(dai->dev, "AC108 Master/Slave mode config error:%u\n\n",
++ (fmt & SND_SOC_DAIFMT_MASTER_MASK) >> 12);
++ return -EINVAL;
++ }
++
++ /*AC108 config I2S/LJ/RJ/PCM format*/
++ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
++ case SND_SOC_DAIFMT_I2S:
++ ac10x->i2s_mode = LEFT_JUSTIFIED_FORMAT;
++ tx_offset = 1;
++ break;
++ case SND_SOC_DAIFMT_RIGHT_J:
++ ac10x->i2s_mode = RIGHT_JUSTIFIED_FORMAT;
++ tx_offset = 0;
++ break;
++ case SND_SOC_DAIFMT_LEFT_J:
++ ac10x->i2s_mode = LEFT_JUSTIFIED_FORMAT;
++ tx_offset = 0;
++ break;
++ case SND_SOC_DAIFMT_DSP_A:
++ ac10x->i2s_mode = PCM_FORMAT;
++ tx_offset = 1;
++ break;
++ case SND_SOC_DAIFMT_DSP_B:
++ ac10x->i2s_mode = PCM_FORMAT;
++ tx_offset = 0;
++ break;
++ default:
++ dev_err(dai->dev, "AC108 I2S format config error:%u\n\n",
++ fmt & SND_SOC_DAIFMT_FORMAT_MASK);
++ return -EINVAL;
++ }
++
++ /*AC108 config BCLK&LRCK polarity*/
++ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
++ case SND_SOC_DAIFMT_NB_NF:
++ brck_polarity = BCLK_NORMAL_DRIVE_N_SAMPLE_P;
++ lrck_polarity = LRCK_LEFT_HIGH_RIGHT_LOW;
++ break;
++ case SND_SOC_DAIFMT_NB_IF:
++ brck_polarity = BCLK_NORMAL_DRIVE_N_SAMPLE_P;
++ lrck_polarity = LRCK_LEFT_LOW_RIGHT_HIGH;
++ break;
++ case SND_SOC_DAIFMT_IB_NF:
++ brck_polarity = BCLK_INVERT_DRIVE_P_SAMPLE_N;
++ lrck_polarity = LRCK_LEFT_HIGH_RIGHT_LOW;
++ break;
++ case SND_SOC_DAIFMT_IB_IF:
++ brck_polarity = BCLK_INVERT_DRIVE_P_SAMPLE_N;
++ lrck_polarity = LRCK_LEFT_LOW_RIGHT_HIGH;
++ break;
++ default:
++ dev_err(dai->dev, "AC108 config BCLK/LRCLK polarity error:%u\n\n",
++ (fmt & SND_SOC_DAIFMT_INV_MASK) >> 8);
++ return -EINVAL;
++ }
++
++ ac108_configure_power(ac10x);
++
++ /**
++ *0x31: 0: normal mode, negative edge drive and positive edge sample
++ 1: invert mode, positive edge drive and negative edge sample
++ */
++ ac108_multi_update_bits(I2S_BCLK_CTRL, 0x01 << BCLK_POLARITY,
++ brck_polarity << BCLK_POLARITY, ac10x);
++ /**
++ * 0x32: same as 0x31
++ */
++ ac108_multi_update_bits(I2S_LRCK_CTRL1, 0x01 << LRCK_POLARITY,
++ lrck_polarity << LRCK_POLARITY, ac10x);
++ /**
++ * 0x34:Encoding Mode Selection,Mode
++ * Selection,data is offset by 1 BCLKs to LRCK
++ * normal mode for the last half cycle of BCLK in the slot ?
++ * turn to hi-z state (TDM) when not transferring slot ?
++ */
++ ac108_multi_update_bits(I2S_FMT_CTRL1,
++ 0x01 << ENCD_SEL | 0x03 << MODE_SEL | 0x01 << TX2_OFFSET |
++ 0x01 << TX1_OFFSET | 0x01 << TX_SLOT_HIZ | 0x01 << TX_STATE,
++ ac10x->data_protocol << ENCD_SEL | ac10x->i2s_mode << MODE_SEL |
++ tx_offset << TX2_OFFSET | tx_offset << TX1_OFFSET |
++ 0x00 << TX_SLOT_HIZ | 0x01 << TX_STATE, ac10x);
++
++ /**
++ * 0x60:
++ * MSB / LSB First Select: This driver only support MSB First Select .
++ * OUT2_MUTE,OUT1_MUTE shoule be set in widget.
++ * LRCK = 1 BCLK width
++ * Linear PCM
++ *
++ * TODO:pcm mode, bit[0:1] and bit[2] is special
++ */
++ ac108_multi_update_bits(I2S_FMT_CTRL3,
++ 0x01 << TX_MLS | 0x03 << SEXT |
++ 0x01 << LRCK_WIDTH | 0x03 << TX_PDM,
++ 0x00 << TX_MLS | 0x03 << SEXT |
++ 0x00 << LRCK_WIDTH | 0x00 << TX_PDM, ac10x);
++
++ ac108_multi_write(HPF_EN, 0x00, ac10x);
++
++ if (ac10x->i2c101) {
++ return ac101_set_dai_fmt(dai, fmt);
++ }
++ return 0;
++}
++
++/*
++ * due to miss channels order in cpu_dai, we meed defer the clock starting.
++ */
++static int ac108_set_clock(int y_start_n_stop)
++{
++ u8 reg;
++ int ret = 0;
++
++ dev_dbg(ac10x->codec->dev, "%s() L%d cmd:%d\n", __func__, __LINE__, y_start_n_stop);
++
++ /* spin_lock move to machine trigger */
++
++ if (y_start_n_stop && ac10x->sysclk_en == 0) {
++ /* enable lrck clock */
++ ac10x_read(I2S_CTRL, &reg, ac10x->i2cmap[_MASTER_INDEX]);
++ if (reg & (0x01 << BCLK_IOEN)) {
++ ret = ret || ac10x_update_bits(I2S_CTRL, 0x03 << LRCK_IOEN,
++ 0x03 << LRCK_IOEN,
++ ac10x->i2cmap[_MASTER_INDEX]);
++ }
++
++ /*0x10: PLL Common voltage enable, PLL enable */
++ ret = ret || ac108_multi_update_bits(PLL_CTRL1,
++ 0x01 << PLL_EN | 0x01 << PLL_COM_EN,
++ 0x01 << PLL_EN | 0x01 << PLL_COM_EN, ac10x);
++ /* enable global clock */
++ ret = ret || ac108_multi_update_bits(I2S_CTRL, 0x1 << TXEN | 0x1 << GEN,
++ 0x1 << TXEN | 0x1 << GEN, ac10x);
++
++ ac10x->sysclk_en = 1UL;
++ } else if (!y_start_n_stop && ac10x->sysclk_en != 0) {
++ /* disable global clock */
++ ret = ret || ac108_multi_update_bits(I2S_CTRL, 0x1 << TXEN | 0x1 << GEN,
++ 0x0 << TXEN | 0x0 << GEN, ac10x);
++
++ /*0x10: PLL Common voltage disable, PLL disable */
++ ret = ret || ac108_multi_update_bits(PLL_CTRL1, 0x01 << PLL_EN | 0x01 << PLL_COM_EN,
++ 0x00 << PLL_EN | 0x00 << PLL_COM_EN, ac10x);
++
++ /* disable lrck clock if it's enabled */
++ ac10x_read(I2S_CTRL, &reg, ac10x->i2cmap[_MASTER_INDEX]);
++ if (reg & (0x01 << LRCK_IOEN)) {
++ ret = ret || ac10x_update_bits(I2S_CTRL, 0x03 << LRCK_IOEN,
++ 0x01 << BCLK_IOEN,
++ ac10x->i2cmap[_MASTER_INDEX]);
++ }
++ if (!ret) {
++ ac10x->sysclk_en = 0UL;
++ }
++ }
++
++ return ret;
++}
++
++static int ac108_prepare(struct snd_pcm_substream *substream,
++ struct snd_soc_dai *dai)
++{
++ u8 r;
++
++ dev_dbg(dai->dev, "%s() stream=%s\n",
++ __func__,
++ snd_pcm_stream_str(substream));
++
++ if (ac10x->i2c101 && _MASTER_MULTI_CODEC == _MASTER_AC101) {
++ ac101_trigger(substream, SNDRV_PCM_TRIGGER_START, dai);
++ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
++ return 0;
++ }
++ }
++
++ ac10x_read(I2S_CTRL, &r, ac10x->i2cmap[_MASTER_INDEX]);
++ if ((r & (0x01 << BCLK_IOEN)) && (r & (0x01 << LRCK_IOEN)) == 0) {
++ /* disable global clock */
++ ac108_multi_update_bits(I2S_CTRL, 0x1 << TXEN | 0x1 << GEN,
++ 0x0 << TXEN | 0x0 << GEN, ac10x);
++ }
++
++ /* delayed clock starting, move to machine trigger() */
++ ac108_set_clock(1);
++
++ return 0;
++}
++
++int ac108_audio_startup(struct snd_pcm_substream *substream,
++ struct snd_soc_dai *dai)
++{
++ struct snd_soc_codec *codec = dai->codec;
++ struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
++
++ if (ac10x->i2c101) {
++ return ac101_audio_startup(substream, dai);
++ }
++ return 0;
++}
++
++void ac108_aif_shutdown(struct snd_pcm_substream *substream,
++ struct snd_soc_dai *dai)
++{
++ struct snd_soc_codec *codec = dai->codec;
++ struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
++
++ ac108_set_clock(0);
++
++ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
++ /*0x21: Module clock disable <I2S, ADC digital, MIC offset Calibration, ADC analog>*/
++ ac108_multi_write(MOD_CLK_EN, 0x0, ac10x);
++ /*0x22: Module reset asserted <I2S, ADC digital, MIC offset Calibration, ADC analog>*/
++ ac108_multi_write(MOD_RST_CTRL, 0x0, ac10x);
++ }
++
++ if (ac10x->i2c101) {
++ ac101_aif_shutdown(substream, dai);
++ }
++}
++
++int ac108_aif_mute(struct snd_soc_dai *dai, int mute, int stream)
++{
++ struct snd_soc_codec *codec = dai->codec;
++ struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
++
++ if (ac10x->i2c101) {
++ return ac101_aif_mute(dai, mute);
++ }
++ return 0;
++}
++
++static const struct snd_soc_dai_ops ac108_dai_ops = {
++ .startup = ac108_audio_startup,
++ .shutdown = ac108_aif_shutdown,
++
++ /*DAI clocking configuration*/
++ .set_sysclk = ac108_set_sysclk,
++
++ /*ALSA PCM audio operations*/
++ .hw_params = ac108_hw_params,
++ .prepare = ac108_prepare,
++ .mute_stream = ac108_aif_mute,
++
++ /*DAI format configuration*/
++ .set_fmt = ac108_set_fmt,
++};
++
++static struct snd_soc_dai_driver ac108_dai0 = {
++ .name = "ac10x-codec0",
++ #if _USE_CAPTURE
++ .playback = {
++ .stream_name = "Playback",
++ .channels_min = 1,
++ .channels_max = AC108_CHANNELS_MAX,
++ .rates = AC108_RATES,
++ .formats = AC108_FORMATS,
++ },
++ #endif
++ .capture = {
++ .stream_name = "Capture",
++ .channels_min = 1,
++ .channels_max = AC108_CHANNELS_MAX,
++ .rates = AC108_RATES,
++ .formats = AC108_FORMATS,
++ },
++ .ops = &ac108_dai_ops,
++};
++
++static struct snd_soc_dai_driver ac108_dai1 = {
++ .name = "ac10x-codec1",
++ #if _USE_CAPTURE
++ .playback = {
++ .stream_name = "Playback",
++ .channels_min = 1,
++ .channels_max = AC108_CHANNELS_MAX,
++ .rates = AC108_RATES,
++ .formats = AC108_FORMATS,
++ },
++ #endif
++ .capture = {
++ .stream_name = "Capture",
++ .channels_min = 1,
++ .channels_max = AC108_CHANNELS_MAX,
++ .rates = AC108_RATES,
++ .formats = AC108_FORMATS,
++ },
++ .ops = &ac108_dai_ops,
++};
++
++static struct snd_soc_dai_driver *ac108_dai[] = {
++ &ac108_dai0,
++ &ac108_dai1,
++};
++
++static int ac108_add_widgets(struct snd_soc_codec *codec)
++{
++ struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
++ struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
++ const struct snd_kcontrol_new* snd_kcntl = ac108_snd_controls;
++ int ctrl_cnt = ARRAY_SIZE(ac108_snd_controls);
++
++ /* only register controls correspond to exist chips */
++ if (ac10x->tdm_chips_cnt >= 2) {
++ snd_kcntl = ac108tdm_snd_controls;
++ ctrl_cnt = ARRAY_SIZE(ac108tdm_snd_controls);
++ }
++ snd_soc_add_codec_controls(codec, snd_kcntl, ctrl_cnt);
++
++ snd_soc_dapm_new_controls(dapm, ac108_dapm_widgets,ARRAY_SIZE(ac108_dapm_widgets));
++ snd_soc_dapm_add_routes(dapm, ac108_dapm_routes, ARRAY_SIZE(ac108_dapm_routes));
++
++ return 0;
++}
++
++static int ac108_codec_probe(struct snd_soc_codec *codec)
++{
++ spin_lock_init(&ac10x->lock);
++
++ ac10x->codec = codec;
++ dev_set_drvdata(codec->dev, ac10x);
++ ac108_add_widgets(codec);
++
++ if (ac10x->i2c101) {
++ ac101_codec_probe(codec);
++ }
++
++ /* change default volume */
++ ac108_multi_update_bits(ADC1_DVOL_CTRL, 0xff, 0xc8, ac10x);
++ ac108_multi_update_bits(ADC2_DVOL_CTRL, 0xff, 0xc8, ac10x);
++ ac108_multi_update_bits(ADC3_DVOL_CTRL, 0xff, 0xc8, ac10x);
++ ac108_multi_update_bits(ADC4_DVOL_CTRL, 0xff, 0xc8, ac10x);
++
++ return 0;
++}
++
++static int ac108_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level)
++{
++ struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
++
++ dev_dbg(codec->dev, "AC108 level:%d\n", level);
++
++ switch (level) {
++ case SND_SOC_BIAS_ON:
++ ac108_multi_update_bits(ANA_ADC1_CTRL1, 0x01 << ADC1_MICBIAS_EN,
++ 0x01 << ADC1_MICBIAS_EN, ac10x);
++ ac108_multi_update_bits(ANA_ADC2_CTRL1, 0x01 << ADC2_MICBIAS_EN,
++ 0x01 << ADC2_MICBIAS_EN, ac10x);
++ ac108_multi_update_bits(ANA_ADC3_CTRL1, 0x01 << ADC3_MICBIAS_EN,
++ 0x01 << ADC3_MICBIAS_EN, ac10x);
++ ac108_multi_update_bits(ANA_ADC4_CTRL1, 0x01 << ADC4_MICBIAS_EN,
++ 0x01 << ADC4_MICBIAS_EN, ac10x);
++ break;
++
++ case SND_SOC_BIAS_PREPARE:
++ /* Put the MICBIASes into regulating mode */
++ break;
++
++ case SND_SOC_BIAS_STANDBY:
++ break;
++
++ case SND_SOC_BIAS_OFF:
++ ac108_multi_update_bits(ANA_ADC1_CTRL1, 0x01 << ADC1_MICBIAS_EN,
++ 0x00 << ADC1_MICBIAS_EN, ac10x);
++ ac108_multi_update_bits(ANA_ADC2_CTRL1, 0x01 << ADC2_MICBIAS_EN,
++ 0x00 << ADC2_MICBIAS_EN, ac10x);
++ ac108_multi_update_bits(ANA_ADC3_CTRL1, 0x01 << ADC3_MICBIAS_EN,
++ 0x00 << ADC3_MICBIAS_EN, ac10x);
++ ac108_multi_update_bits(ANA_ADC4_CTRL1, 0x01 << ADC4_MICBIAS_EN,
++ 0x00 << ADC4_MICBIAS_EN, ac10x);
++ break;
++ }
++
++ if (ac10x->i2c101) {
++ ac101_set_bias_level(codec, level);
++ }
++ return 0;
++}
++
++int ac108_codec_remove(struct snd_soc_codec *codec) {
++ struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
++
++ if (! ac10x->i2c101) {
++ return 0;
++ }
++ return ac101_codec_remove(codec);
++}
++#if __NO_SND_SOC_CODEC_DRV
++void ac108_codec_remove_void(struct snd_soc_codec *codec)
++{
++ ac108_codec_remove(codec);
++}
++#define ac108_codec_remove ac108_codec_remove_void
++#endif
++
++int ac108_codec_suspend(struct snd_soc_codec *codec)
++{
++ struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
++ int i;
++
++ for (i = 0; i < ac10x->codec_cnt; i++) {
++ regcache_cache_only(ac10x->i2cmap[i], true);
++ }
++
++ if (! ac10x->i2c101) {
++ return 0;
++ }
++ return ac101_codec_suspend(codec);
++}
++
++int ac108_codec_resume(struct snd_soc_codec *codec)
++{
++ struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
++ int i, ret;
++
++ /* Sync reg_cache with the hardware */
++ for (i = 0; i < ac10x->codec_cnt; i++) {
++ regcache_cache_only(ac10x->i2cmap[i], false);
++ ret = regcache_sync(ac10x->i2cmap[i]);
++ if (ret != 0) {
++ dev_err(codec->dev, "Failed to sync i2cmap%d register cache: %d\n",
++ i, ret);
++ regcache_cache_only(ac10x->i2cmap[i], true);
++ }
++ }
++
++ if (! ac10x->i2c101) {
++ return 0;
++ }
++ return ac101_codec_resume(codec);
++}
++
++static struct snd_soc_codec_driver ac10x_soc_codec_driver = {
++ .probe = ac108_codec_probe,
++ .remove = ac108_codec_remove,
++ .suspend = ac108_codec_suspend,
++ .resume = ac108_codec_resume,
++ .set_bias_level = ac108_set_bias_level,
++ .read = ac108_codec_read,
++ .write = ac108_codec_write,
++};
++
++static ssize_t ac108_store(struct device *dev, struct device_attribute *attr,
++ const char *buf, size_t count)
++{
++ int val = 0, flag = 0;
++ u8 i = 0, reg, num, value_w, value_r[4];
++
++ val = simple_strtol(buf, NULL, 16);
++ flag = (val >> 16) & 0xF;
++
++ if (flag) {
++ reg = (val >> 8) & 0xFF;
++ value_w = val & 0xFF;
++ ac108_multi_write(reg, value_w, ac10x);
++ dev_info(dev, "Write 0x%02x to REG:0x%02x\n", value_w, reg);
++ } else {
++ int k;
++
++ reg = (val >> 8) & 0xFF;
++ num = val & 0xff;
++ dev_info(dev, "\nRead: start REG:0x%02x,count:0x%02x\n", reg, num);
++
++ for (k = 0; k < ac10x->codec_cnt; k++)
++ regcache_cache_bypass(ac10x->i2cmap[k], true);
++
++ do {
++ memset(value_r, 0, sizeof value_r);
++
++ for (k = 0; k < ac10x->codec_cnt; k++)
++ ac10x_read(reg, &value_r[k], ac10x->i2cmap[k]);
++
++ if (ac10x->codec_cnt >= 2)
++ dev_info(dev, "REG[0x%02x]: 0x%02x 0x%02x", reg,
++ value_r[0], value_r[1]);
++ else
++ dev_info(dev, "REG[0x%02x]: 0x%02x", reg, value_r[0]);
++ reg++;
++
++ if ((++i == num) || (i % 4 == 0))
++ dev_info(dev, "\n");
++ } while (i < num);
++
++ for (k = 0; k < ac10x->codec_cnt; k++)
++ regcache_cache_bypass(ac10x->i2cmap[k], false);
++ }
++
++ return count;
++}
++
++static ssize_t ac108_show(struct device *dev, struct device_attribute *attr, char *buf)
++{
++ dev_info(dev, "echo flag|reg|val > ac108\n");
++ dev_info(dev, "eg read star addres=0x06,count 0x10:echo 0610 >ac108\n");
++ dev_info(dev, "eg write value:0xfe to address:0x06 :echo 106fe > ac108\n");
++ return 0;
++}
++
++static DEVICE_ATTR(ac108, 0644, ac108_show, ac108_store);
++static struct attribute *ac108_debug_attrs[] = {
++ &dev_attr_ac108.attr,
++ NULL,
++};
++static struct attribute_group ac108_debug_attr_group = {
++ .name = "ac108_debug",
++ .attrs = ac108_debug_attrs,
++};
++
++static const struct i2c_device_id ac108_i2c_id[] = {
++ { "ac108_0", 0 },
++ { "ac108_1", 1 },
++ { "ac108_2", 2 },
++ { "ac108_3", 3 },
++ { "ac101", AC101_I2C_ID },
++ { }
++};
++MODULE_DEVICE_TABLE(i2c, ac108_i2c_id);
++
++static const struct regmap_config ac108_regmap = {
++ .reg_bits = 8,
++ .val_bits = 8,
++ .reg_stride = 1,
++ .max_register = 0xDF,
++ .cache_type = REGCACHE_FLAT,
++};
++static int ac108_i2c_probe(struct i2c_client *i2c)
++{
++ struct device_node *np = i2c->dev.of_node;
++ const struct i2c_device_id *i2c_id;
++ unsigned int val = 0;
++ int ret = 0, index;
++
++ if (ac10x == NULL) {
++ ac10x = kzalloc(sizeof(struct ac10x_priv), GFP_KERNEL);
++ if (ac10x == NULL) {
++ dev_err(&i2c->dev, "Unable to allocate ac10x private data\n");
++ return -ENOMEM;
++ }
++ }
++
++ i2c_id = i2c_match_id(ac108_i2c_id, i2c);
++ index = (int)i2c_id->driver_data;
++ if (index == AC101_I2C_ID) {
++ ac10x->i2c101 = i2c;
++ i2c_set_clientdata(i2c, ac10x);
++ ret = ac101_probe(i2c, i2c_id);
++ if (ret) {
++ ac10x->i2c101 = NULL;
++ return ret;
++ }
++ goto __ret;
++ }
++
++ ret = of_property_read_u32(np, "data-protocol", &val);
++ if (ret) {
++ dev_err(&i2c->dev, "Please set data-protocol.\n");
++ return -EINVAL;
++ }
++ ac10x->data_protocol = val;
++
++ if (of_property_read_u32(np, "tdm-chips-count", &val)) val = 1;
++ ac10x->tdm_chips_cnt = val;
++
++ dev_info(&i2c->dev, " ac10x i2c_id number: %d\n", index);
++ dev_info(&i2c->dev, " ac10x data protocol: %d\n", ac10x->data_protocol);
++
++ ac10x->i2c[index] = i2c;
++ ac10x->i2cmap[index] = devm_regmap_init_i2c(i2c, &ac108_regmap);
++ if (IS_ERR(ac10x->i2cmap[index])) {
++ ret = PTR_ERR(ac10x->i2cmap[index]);
++ dev_err(&i2c->dev, "Fail to initialize i2cmap%d I/O: %d\n", index, ret);
++ return ret;
++ }
++
++ /*
++ * Writing this register with 0x12
++ * will resets all register to their default state.
++ */
++ regcache_cache_only(ac10x->i2cmap[index], false);
++
++ ret = regmap_write(ac10x->i2cmap[index], CHIP_RST, CHIP_RST_VAL);
++ msleep(1);
++
++ /* sync regcache for FLAT type */
++ ac10x_fill_regcache(&i2c->dev, ac10x->i2cmap[index]);
++
++ ac10x->codec_cnt++;
++ dev_info(&i2c->dev, " ac10x codec count : %d\n", ac10x->codec_cnt);
++
++ ret = sysfs_create_group(&i2c->dev.kobj, &ac108_debug_attr_group);
++ if (ret) {
++ dev_err(&i2c->dev, "failed to create attr group\n");
++ }
++
++__ret:
++ /* It's time to bind codec to i2c[_MASTER_INDEX] when all i2c are ready */
++ if ((ac10x->codec_cnt != 0 && ac10x->tdm_chips_cnt < 2)
++ || (ac10x->i2c[0] && ac10x->i2c[1] && ac10x->i2c101)) {
++ /* no playback stream */
++ if (! ac10x->i2c101) {
++ memset(&ac108_dai[_MASTER_INDEX]->playback, '\0',
++ sizeof ac108_dai[_MASTER_INDEX]->playback);
++ }
++ ret = snd_soc_register_codec(&ac10x->i2c[_MASTER_INDEX]->dev,
++ &ac10x_soc_codec_driver,
++ ac108_dai[_MASTER_INDEX], 1);
++ if (ret < 0) {
++ dev_err(&i2c->dev, "Failed to register ac10x codec: %d\n", ret);
++ }
++ }
++ return ret;
++}
++
++static void ac108_i2c_remove(struct i2c_client *i2c)
++{
++ if (ac10x->codec != NULL) {
++ snd_soc_unregister_codec(&ac10x->i2c[_MASTER_INDEX]->dev);
++ ac10x->codec = NULL;
++ }
++ if (i2c == ac10x->i2c101) {
++ ac101_remove(ac10x->i2c101);
++ ac10x->i2c101 = NULL;
++ goto __ret;
++ }
++
++ if (i2c == ac10x->i2c[0]) {
++ ac10x->i2c[0] = NULL;
++ }
++ if (i2c == ac10x->i2c[1]) {
++ ac10x->i2c[1] = NULL;
++ }
++
++ sysfs_remove_group(&i2c->dev.kobj, &ac108_debug_attr_group);
++
++__ret:
++ if (!ac10x->i2c[0] && !ac10x->i2c[1] && !ac10x->i2c101) {
++ kfree(ac10x);
++ ac10x = NULL;
++ }
++}
++
++static const struct of_device_id ac108_of_match[] = {
++ { .compatible = "x-power,ac108_0", },
++ { .compatible = "x-power,ac108_1", },
++ { .compatible = "x-power,ac108_2", },
++ { .compatible = "x-power,ac108_3", },
++ { .compatible = "x-power,ac101", },
++ { }
++};
++MODULE_DEVICE_TABLE(of, ac108_of_match);
++
++static struct i2c_driver ac108_i2c_driver = {
++ .driver = {
++ .name = "ac10x-codec",
++ .of_match_table = ac108_of_match,
++ },
++ .probe = ac108_i2c_probe,
++ .remove = ac108_i2c_remove,
++ .id_table = ac108_i2c_id,
++};
++
++module_i2c_driver(ac108_i2c_driver);
++
++MODULE_DESCRIPTION("ASoC AC108 driver");
++MODULE_AUTHOR("Baozhu Zuo<zuobaozhu@gmail.com>");
++MODULE_LICENSE("GPL");
+--- /dev/null
++++ b/sound/soc/codecs/ac108.h
+@@ -0,0 +1,749 @@
++/*
++ * ac108.h -- ac108 ALSA Soc Audio driver
++ *
++ * Author: panjunwen
++ *
++ * 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.
++ *
++ */
++
++#ifndef _AC108_H
++#define _AC108_H
++
++/*** AC108 Codec Register Define***/
++
++//Chip Reset
++#define CHIP_RST 0x00
++#define CHIP_RST_VAL 0x12
++
++//Power Control
++#define PWR_CTRL1 0x01
++#define PWR_CTRL2 0x02
++#define PWR_CTRL3 0x03
++#define PWR_CTRL4 0x04
++#define PWR_CTRL5 0x05
++#define PWR_CTRL6 0x06
++#define PWR_CTRL7 0x07
++#define PWR_CTRL8 0x08
++#define PWR_CTRL9 0x09
++
++//PLL Configure Control
++#define PLL_CTRL1 0x10
++#define PLL_CTRL2 0x11
++#define PLL_CTRL3 0x12
++#define PLL_CTRL4 0x13
++#define PLL_CTRL5 0x14
++#define PLL_CTRL6 0x16
++#define PLL_CTRL7 0x17
++#define PLL_LOCK_CTRL 0x18
++
++//System Clock Control
++#define SYSCLK_CTRL 0x20
++#define MOD_CLK_EN 0x21
++#define MOD_RST_CTRL 0x22
++#define DSM_CLK_CTRL 0x25
++
++//I2S Common Control
++#define I2S_CTRL 0x30
++#define I2S_BCLK_CTRL 0x31
++#define I2S_LRCK_CTRL1 0x32
++#define I2S_LRCK_CTRL2 0x33
++#define I2S_FMT_CTRL1 0x34
++#define I2S_FMT_CTRL2 0x35
++#define I2S_FMT_CTRL3 0x36
++
++//I2S TX1 Control
++#define I2S_TX1_CTRL1 0x38
++#define I2S_TX1_CTRL2 0x39
++#define I2S_TX1_CTRL3 0x3A
++#define I2S_TX1_CHMP_CTRL1 0x3C
++#define I2S_TX1_CHMP_CTRL2 0x3D
++#define I2S_TX1_CHMP_CTRL3 0x3E
++#define I2S_TX1_CHMP_CTRL4 0x3F
++
++//I2S TX2 Control
++#define I2S_TX2_CTRL1 0x40
++#define I2S_TX2_CTRL2 0x41
++#define I2S_TX2_CTRL3 0x42
++#define I2S_TX2_CHMP_CTRL1 0x44
++#define I2S_TX2_CHMP_CTRL2 0x45
++#define I2S_TX2_CHMP_CTRL3 0x46
++#define I2S_TX2_CHMP_CTRL4 0x47
++
++//I2S RX1 Control
++#define I2S_RX1_CTRL1 0x50
++#define I2S_RX1_CHMP_CTRL1 0x54
++#define I2S_RX1_CHMP_CTRL2 0x55
++#define I2S_RX1_CHMP_CTRL3 0x56
++#define I2S_RX1_CHMP_CTRL4 0x57
++
++//I2S Loopback Debug
++#define I2S_LPB_DEBUG 0x58
++
++//ADC Common Control
++#define ADC_SPRC 0x60
++#define ADC_DIG_EN 0x61
++#define DMIC_EN 0x62
++#define ADC_DSR 0x63
++#define ADC_FIR 0x64
++#define ADC_DDT_CTRL 0x65
++
++//HPF Control
++#define HPF_EN 0x66
++#define HPF_COEF_REGH1 0x67
++#define HPF_COEF_REGH2 0x68
++#define HPF_COEF_REGL1 0x69
++#define HPF_COEF_REGL2 0x6A
++#define HPF_GAIN_REGH1 0x6B
++#define HPF_GAIN_REGH2 0x6C
++#define HPF_GAIN_REGL1 0x6D
++#define HPF_GAIN_REGL2 0x6E
++
++//ADC Digital Channel Volume Control
++#define ADC1_DVOL_CTRL 0x70
++#define ADC2_DVOL_CTRL 0x71
++#define ADC3_DVOL_CTRL 0x72
++#define ADC4_DVOL_CTRL 0x73
++
++//ADC Digital Mixer Source and Gain Control
++#define ADC1_DMIX_SRC 0x76
++#define ADC2_DMIX_SRC 0x77
++#define ADC3_DMIX_SRC 0x78
++#define ADC4_DMIX_SRC 0x79
++
++//ADC Digital Debug Control
++#define ADC_DIG_DEBUG 0x7F
++
++//I2S Pad Drive Control
++#define I2S_DAT_PADDRV_CTRL 0x80
++#define I2S_CLK_PADDRV_CTRL 0x81
++
++//Analog PGA Control
++#define ANA_PGA1_CTRL 0x90
++#define ANA_PGA2_CTRL 0x91
++#define ANA_PGA3_CTRL 0x92
++#define ANA_PGA4_CTRL 0x93
++
++//MIC Offset Control
++#define MIC_OFFSET_CTRL1 0x96
++#define MIC_OFFSET_CTRL2 0x97
++#define MIC1_OFFSET_STATU1 0x98
++#define MIC1_OFFSET_STATU2 0x99
++#define MIC2_OFFSET_STATU1 0x9A
++#define MIC2_OFFSET_STATU2 0x9B
++#define MIC3_OFFSET_STATU1 0x9C
++#define MIC3_OFFSET_STATU2 0x9D
++#define MIC4_OFFSET_STATU1 0x9E
++#define MIC4_OFFSET_STATU2 0x9F
++
++//ADC1 Analog Control
++#define ANA_ADC1_CTRL1 0xA0
++#define ANA_ADC1_CTRL2 0xA1
++#define ANA_ADC1_CTRL3 0xA2
++#define ANA_ADC1_CTRL4 0xA3
++#define ANA_ADC1_CTRL5 0xA4
++#define ANA_ADC1_CTRL6 0xA5
++#define ANA_ADC1_CTRL7 0xA6
++
++//ADC2 Analog Control
++#define ANA_ADC2_CTRL1 0xA7
++#define ANA_ADC2_CTRL2 0xA8
++#define ANA_ADC2_CTRL3 0xA9
++#define ANA_ADC2_CTRL4 0xAA
++#define ANA_ADC2_CTRL5 0xAB
++#define ANA_ADC2_CTRL6 0xAC
++#define ANA_ADC2_CTRL7 0xAD
++
++//ADC3 Analog Control
++#define ANA_ADC3_CTRL1 0xAE
++#define ANA_ADC3_CTRL2 0xAF
++#define ANA_ADC3_CTRL3 0xB0
++#define ANA_ADC3_CTRL4 0xB1
++#define ANA_ADC3_CTRL5 0xB2
++#define ANA_ADC3_CTRL6 0xB3
++#define ANA_ADC3_CTRL7 0xB4
++
++//ADC4 Analog Control
++#define ANA_ADC4_CTRL1 0xB5
++#define ANA_ADC4_CTRL2 0xB6
++#define ANA_ADC4_CTRL3 0xB7
++#define ANA_ADC4_CTRL4 0xB8
++#define ANA_ADC4_CTRL5 0xB9
++#define ANA_ADC4_CTRL6 0xBA
++#define ANA_ADC4_CTRL7 0xBB
++
++//GPIO Configure
++#define GPIO_CFG1 0xC0
++#define GPIO_CFG2 0xC1
++#define GPIO_DAT 0xC2
++#define GPIO_DRV 0xC3
++#define GPIO_PULL 0xC4
++#define GPIO_INT_CFG 0xC5
++#define GPIO_INT_EN 0xC6
++#define GPIO_INT_STATUS 0xC7
++
++//Misc
++#define BGTC_DAT 0xD1
++#define BGVC_DAT 0xD2
++#define PRNG_CLK_CTRL 0xDF
++
++/*** AC108 Codec Register Bit Define***/
++
++/*PWR_CTRL1*/
++#define CP12_CTRL 4
++#define CP12_SENSE_SELECT 3
++
++/*PWR_CTRL2*/
++#define CP12_SENSE_FILT 6
++#define CP12_COMP_FF_EN 3
++#define CP12_FORCE_ENABLE 2
++#define CP12_FORCE_RSTB 1
++
++/*PWR_CTRL3*/
++#define LDO33DIG_CTRL 0
++
++/*PWR_CTRL6*/
++#define LDO33ANA_2XHDRM 2
++#define LDO33ANA_ENABLE 0
++
++/*PWR_CTRL7*/
++#define VREF_SEL 3
++#define VREF_FASTSTART_ENABLE 1
++#define VREF_ENABLE 0
++
++/*PWR_CTRL9*/
++#define VREFP_FASTSTART_ENABLE 7
++#define VREFP_RESCTRL 5
++#define VREFP_LPMODE 4
++#define IGEN_TRIM 1
++#define VREFP_ENABLE 0
++
++/*PLL_CTRL1*/
++#define PLL_IBIAS 4
++#define PLL_NDET 3
++#define PLL_LOCKED_STATUS 2
++#define PLL_COM_EN 1
++#define PLL_EN 0
++
++/*PLL_CTRL2*/
++#define PLL_PREDIV2 5
++#define PLL_PREDIV1 0
++
++/*PLL_CTRL3*/
++#define PLL_LOOPDIV_MSB 0
++
++/*PLL_CTRL4*/
++#define PLL_LOOPDIV_LSB 0
++
++/*PLL_CTRL5*/
++#define PLL_POSTDIV2 5
++#define PLL_POSTDIV1 0
++
++/*PLL_CTRL6*/
++#define PLL_LDO 6
++#define PLL_CP 0
++
++/*PLL_CTRL7*/
++#define PLL_CAP 6
++#define PLL_RES 4
++#define PLL_TEST_EN 0
++
++/*PLL_LOCK_CTRL*/
++#define LOCK_LEVEL1 2
++#define LOCK_LEVEL2 1
++#define PLL_LOCK_EN 0
++
++/*SYSCLK_CTRL*/
++#define PLLCLK_EN 7
++#define PLLCLK_SRC 4
++#define SYSCLK_SRC 3
++#define SYSCLK_EN 0
++
++/*MOD_CLK_EN & MOD_RST_CTRL*/
++#define I2S 7
++#define ADC_DIGITAL 4
++#define MIC_OFFSET_CALIBRATION 1
++#define ADC_ANALOG 0
++
++/*DSM_CLK_CTRL*/
++#define MIC_OFFSET_DIV 4
++#define DSM_CLK_SEL 0
++
++/*I2S_CTRL*/
++#define BCLK_IOEN 7
++#define LRCK_IOEN 6
++#define SDO2_EN 5
++#define SDO1_EN 4
++#define TXEN 2
++#define RXEN 1
++#define GEN 0
++
++/*I2S_BCLK_CTRL*/
++#define EDGE_TRANSFER 5
++#define BCLK_POLARITY 4
++#define BCLKDIV 0
++
++/*I2S_LRCK_CTRL1*/
++#define LRCK_POLARITY 4
++#define LRCK_PERIODH 0
++
++/*I2S_LRCK_CTRL2*/
++#define LRCK_PERIODL 0
++
++/*I2S_FMT_CTRL1*/
++#define ENCD_SEL 6
++#define MODE_SEL 4
++#define TX2_OFFSET 3
++#define TX1_OFFSET 2
++#define TX_SLOT_HIZ 1
++#define TX_STATE 0
++
++/*I2S_FMT_CTRL2*/
++#define SLOT_WIDTH_SEL 4
++#define SAMPLE_RESOLUTION 0
++
++/*I2S_FMT_CTRL3*/
++#define TX_MLS 7
++#define SEXT 5
++#define OUT2_MUTE 4
++#define OUT1_MUTE 3
++#define LRCK_WIDTH 2
++#define TX_PDM 0
++
++/*I2S_TX1_CTRL1*/
++#define TX1_CHSEL 0
++
++/*I2S_TX1_CTRL2*/
++#define TX1_CH8_EN 7
++#define TX1_CH7_EN 6
++#define TX1_CH6_EN 5
++#define TX1_CH5_EN 4
++#define TX1_CH4_EN 3
++#define TX1_CH3_EN 2
++#define TX1_CH2_EN 1
++#define TX1_CH1_EN 0
++
++/*I2S_TX1_CTRL3*/
++#define TX1_CH16_EN 7
++#define TX1_CH15_EN 6
++#define TX1_CH14_EN 5
++#define TX1_CH13_EN 4
++#define TX1_CH12_EN 3
++#define TX1_CH11_EN 2
++#define TX1_CH10_EN 1
++#define TX1_CH9_EN 0
++
++/*I2S_TX1_CHMP_CTRL1*/
++#define TX1_CH4_MAP 6
++#define TX1_CH3_MAP 4
++#define TX1_CH2_MAP 2
++#define TX1_CH1_MAP 0
++
++/*I2S_TX1_CHMP_CTRL2*/
++#define TX1_CH8_MAP 6
++#define TX1_CH7_MAP 4
++#define TX1_CH6_MAP 2
++#define TX1_CH5_MAP 0
++
++/*I2S_TX1_CHMP_CTRL3*/
++#define TX1_CH12_MAP 6
++#define TX1_CH11_MAP 4
++#define TX1_CH10_MAP 2
++#define TX1_CH9_MAP 0
++
++/*I2S_TX1_CHMP_CTRL4*/
++#define TX1_CH16_MAP 6
++#define TX1_CH15_MAP 4
++#define TX1_CH14_MAP 2
++#define TX1_CH13_MAP 0
++
++/*I2S_TX2_CTRL1*/
++#define TX2_CHSEL 0
++
++/*I2S_TX2_CHMP_CTRL1*/
++#define TX2_CH4_MAP 6
++#define TX2_CH3_MAP 4
++#define TX2_CH2_MAP 2
++#define TX2_CH1_MAP 0
++
++/*I2S_TX2_CHMP_CTRL2*/
++#define TX2_CH8_MAP 6
++#define TX2_CH7_MAP 4
++#define TX2_CH6_MAP 2
++#define TX2_CH5_MAP 0
++
++/*I2S_TX2_CHMP_CTRL3*/
++#define TX2_CH12_MAP 6
++#define TX2_CH11_MAP 4
++#define TX2_CH10_MAP 2
++#define TX2_CH9_MAP 0
++
++/*I2S_TX2_CHMP_CTRL4*/
++#define TX2_CH16_MAP 6
++#define TX2_CH15_MAP 4
++#define TX2_CH14_MAP 2
++#define TX2_CH13_MAP 0
++
++/*I2S_RX1_CTRL1*/
++#define RX1_CHSEL 0
++
++/*I2S_RX1_CHMP_CTRL1*/
++#define RX1_CH4_MAP 6
++#define RX1_CH3_MAP 4
++#define RX1_CH2_MAP 2
++#define RX1_CH1_MAP 0
++
++/*I2S_RX1_CHMP_CTRL2*/
++#define RX1_CH8_MAP 6
++#define RX1_CH7_MAP 4
++#define RX1_CH6_MAP 2
++#define RX1_CH5_MAP 0
++
++/*I2S_RX1_CHMP_CTRL3*/
++#define RX1_CH12_MAP 6
++#define RX1_CH11_MAP 4
++#define RX1_CH10_MAP 2
++#define RX1_CH9_MAP 0
++
++/*I2S_RX1_CHMP_CTRL4*/
++#define RX1_CH16_MAP 6
++#define RX1_CH15_MAP 4
++#define RX1_CH14_MAP 2
++#define RX1_CH13_MAP 0
++
++/*I2S_LPB_DEBUG*/
++#define I2S_LPB_DEBUG_EN 0
++
++/*ADC_SPRC*/
++#define ADC_FS_I2S1 0
++
++/*ADC_DIG_EN*/
++#define DG_EN 4
++#define ENAD4 3
++#define ENAD3 2
++#define ENAD2 1
++#define ENAD1 0
++
++/*DMIC_EN*/
++#define DMIC2_EN 1
++#define DMIC1_EN 0
++
++/*ADC_DSR*/
++#define DIG_ADC4_SRS 6
++#define DIG_ADC3_SRS 4
++#define DIG_ADC2_SRS 2
++#define DIG_ADC1_SRS 0
++
++/*ADC_DDT_CTRL*/
++#define ADOUT_DLY_EN 2
++#define ADOUT_DTS 0
++
++/*HPF_EN*/
++#define DIG_ADC4_HPF_EN 3
++#define DIG_ADC3_HPF_EN 2
++#define DIG_ADC2_HPF_EN 1
++#define DIG_ADC1_HPF_EN 0
++
++/*ADC1_DMIX_SRC*/
++#define ADC1_ADC4_DMXL_GC 7
++#define ADC1_ADC3_DMXL_GC 6
++#define ADC1_ADC2_DMXL_GC 5
++#define ADC1_ADC1_DMXL_GC 4
++#define ADC1_ADC4_DMXL_SRC 3
++#define ADC1_ADC3_DMXL_SRC 2
++#define ADC1_ADC2_DMXL_SRC 1
++#define ADC1_ADC1_DMXL_SRC 0
++
++/*ADC2_DMIX_SRC*/
++#define ADC2_ADC4_DMXL_GC 7
++#define ADC2_ADC3_DMXL_GC 6
++#define ADC2_ADC2_DMXL_GC 5
++#define ADC2_ADC1_DMXL_GC 4
++#define ADC2_ADC4_DMXL_SRC 3
++#define ADC2_ADC3_DMXL_SRC 2
++#define ADC2_ADC2_DMXL_SRC 1
++#define ADC2_ADC1_DMXL_SRC 0
++
++/*ADC3_DMIX_SRC*/
++#define ADC3_ADC4_DMXL_GC 7
++#define ADC3_ADC3_DMXL_GC 6
++#define ADC3_ADC2_DMXL_GC 5
++#define ADC3_ADC1_DMXL_GC 4
++#define ADC3_ADC4_DMXL_SRC 3
++#define ADC3_ADC3_DMXL_SRC 2
++#define ADC3_ADC2_DMXL_SRC 1
++#define ADC3_ADC1_DMXL_SRC 0
++
++/*ADC4_DMIX_SRC*/
++#define ADC4_ADC4_DMXL_GC 7
++#define ADC4_ADC3_DMXL_GC 6
++#define ADC4_ADC2_DMXL_GC 5
++#define ADC4_ADC1_DMXL_GC 4
++#define ADC4_ADC4_DMXL_SRC 3
++#define ADC4_ADC3_DMXL_SRC 2
++#define ADC4_ADC2_DMXL_SRC 1
++#define ADC4_ADC1_DMXL_SRC 0
++
++/*ADC_DIG_DEBUG*/
++#define ADC_PTN_SEL 0
++
++/*I2S_DAT_PADDRV_CTRL*/
++#define TX2_DAT_DRV 4
++#define TX1_DAT_DRV 0
++
++/*I2S_CLK_PADDRV_CTRL*/
++#define LRCK_DRV 4
++#define BCLK_DRV 0
++
++/*ANA_PGA1_CTRL*/
++#define ADC1_ANALOG_PGA 1
++#define ADC1_ANALOG_PGA_STEP 0
++
++/*ANA_PGA2_CTRL*/
++#define ADC2_ANALOG_PGA 1
++#define ADC2_ANALOG_PGA_STEP 0
++
++/*ANA_PGA3_CTRL*/
++#define ADC3_ANALOG_PGA 1
++#define ADC3_ANALOG_PGA_STEP 0
++
++/*ANA_PGA4_CTRL*/
++#define ADC4_ANALOG_PGA 1
++#define ADC4_ANALOG_PGA_STEP 0
++
++
++/*MIC_OFFSET_CTRL1*/
++#define MIC_OFFSET_CAL_EN4 3
++#define MIC_OFFSET_CAL_EN3 2
++#define MIC_OFFSET_CAL_EN2 1
++#define MIC_OFFSET_CAL_EN1 0
++
++/*MIC_OFFSET_CTRL2*/
++#define MIC_OFFSET_CAL_GAIN 3
++#define MIC_OFFSET_CAL_CHANNEL 1
++#define MIC_OFFSET_CAL_EN_ONCE 0
++
++/*MIC1_OFFSET_STATU1*/
++#define MIC1_OFFSET_CAL_DONE 7
++#define MIC1_OFFSET_CAL_RUN_STA 6
++#define MIC1_OFFSET_MSB 0
++
++/*MIC1_OFFSET_STATU2*/
++#define MIC1_OFFSET_LSB 0
++
++/*MIC2_OFFSET_STATU1*/
++#define MIC2_OFFSET_CAL_DONE 7
++#define MIC2_OFFSET_CAL_RUN_STA 6
++#define MIC2_OFFSET_MSB 0
++
++/*MIC2_OFFSET_STATU2*/
++#define MIC2_OFFSET_LSB 0
++
++/*MIC3_OFFSET_STATU1*/
++#define MIC3_OFFSET_CAL_DONE 7
++#define MIC3_OFFSET_CAL_RUN_STA 6
++#define MIC3_OFFSET_MSB 0
++
++/*MIC3_OFFSET_STATU2*/
++#define MIC3_OFFSET_LSB 0
++
++/*MIC4_OFFSET_STATU1*/
++#define MIC4_OFFSET_CAL_DONE 7
++#define MIC4_OFFSET_CAL_RUN_STA 6
++#define MIC4_OFFSET_MSB 0
++
++/*MIC4_OFFSET_STATU2*/
++#define MIC4_OFFSET_LSB 0
++
++/*ANA_ADC1_CTRL1*/
++#define ADC1_PGA_BYPASS 7
++#define ADC1_PGA_BYP_RCM 6
++#define ADC1_PGA_CTRL_RCM 4
++#define ADC1_PGA_MUTE 3
++#define ADC1_DSM_ENABLE 2
++#define ADC1_PGA_ENABLE 1
++#define ADC1_MICBIAS_EN 0
++
++/*ANA_ADC1_CTRL3*/
++#define ADC1_ANA_CAL_EN 5
++#define ADC1_SEL_OUT_EDGE 3
++#define ADC1_DSM_DISABLE 2
++#define ADC1_VREFP_DISABLE 1
++#define ADC1_AAF_DISABLE 0
++
++/*ANA_ADC1_CTRL6*/
++#define PGA_CTRL_TC 6
++#define PGA_CTRL_RC 4
++#define PGA_CTRL_I_LIN 2
++#define PGA_CTRL_I_IN 0
++
++/*ANA_ADC1_CTRL7*/
++#define PGA_CTRL_HI_Z 7
++#define PGA_CTRL_SHORT_RF 6
++#define PGA_CTRL_VCM_VG 4
++#define PGA_CTRL_VCM_IN 0
++
++/*ANA_ADC2_CTRL1*/
++#define ADC2_PGA_BYPASS 7
++#define ADC2_PGA_BYP_RCM 6
++#define ADC2_PGA_CTRL_RCM 4
++#define ADC2_PGA_MUTE 3
++#define ADC2_DSM_ENABLE 2
++#define ADC2_PGA_ENABLE 1
++#define ADC2_MICBIAS_EN 0
++
++/*ANA_ADC2_CTRL3*/
++#define ADC2_ANA_CAL_EN 5
++#define ADC2_SEL_OUT_EDGE 3
++#define ADC2_DSM_DISABLE 2
++#define ADC2_VREFP_DISABLE 1
++#define ADC2_AAF_DISABLE 0
++
++/*ANA_ADC2_CTRL6*/
++#define PGA_CTRL_IBOOST 7
++#define PGA_CTRL_IQCTRL 6
++#define PGA_CTRL_OABIAS 4
++#define PGA_CTRL_CMLP_DIS 3
++#define PGA_CTRL_PDB_RIN 2
++#define PGA_CTRL_PEAKDET 0
++
++/*ANA_ADC2_CTRL7*/
++#define AAF_LPMODE_EN 7
++#define AAF_STG2_IB_SEL 4
++#define AAFDSM_IB_DIV2 3
++#define AAF_STG1_IB_SEL 0
++
++/*ANA_ADC3_CTRL1*/
++#define ADC3_PGA_BYPASS 7
++#define ADC3_PGA_BYP_RCM 6
++#define ADC3_PGA_CTRL_RCM 4
++#define ADC3_PGA_MUTE 3
++#define ADC3_DSM_ENABLE 2
++#define ADC3_PGA_ENABLE 1
++#define ADC3_MICBIAS_EN 0
++
++/*ANA_ADC3_CTRL3*/
++#define ADC3_ANA_CAL_EN 5
++#define ADC3_INVERT_CLK 4
++#define ADC3_SEL_OUT_EDGE 3
++#define ADC3_DSM_DISABLE 2
++#define ADC3_VREFP_DISABLE 1
++#define ADC3_AAF_DISABLE 0
++
++/*ANA_ADC3_CTRL7*/
++#define DSM_COMP_IB_SEL 6
++#define DSM_OTA_CTRL 4
++#define DSM_LPMODE 3
++#define DSM_OTA_IB_SEL 0
++
++/*ANA_ADC4_CTRL1*/
++#define ADC4_PGA_BYPASS 7
++#define ADC4_PGA_BYP_RCM 6
++#define ADC4_PGA_CTRL_RCM 4
++#define ADC4_PGA_MUTE 3
++#define ADC4_DSM_ENABLE 2
++#define ADC4_PGA_ENABLE 1
++#define ADC4_MICBIAS_EN 0
++
++/*ANA_ADC4_CTRL3*/
++#define ADC4_ANA_CAL_EN 5
++#define ADC4_SEL_OUT_EDGE 3
++#define ADC4_DSM_DISABLE 2
++#define ADC4_VREFP_DISABLE 1
++#define ADC4_AAF_DISABLE 0
++
++/*ANA_ADC4_CTRL6*/
++#define DSM_DEMOFF 5
++#define DSM_EN_DITHER 4
++#define DSM_VREFP_LPMODE 2
++#define DSM_VREFP_OUTCTRL 0
++
++/*ANA_ADC4_CTRL7*/
++#define CK8M_EN 5
++#define OSC_EN 4
++#define ADC4_CLK_GATING 3
++#define ADC3_CLK_GATING 2
++#define ADC2_CLK_GATING 1
++#define ADC1_CLK_GATING 0
++
++/*GPIO_CFG1*/
++#define GPIO2_SELECT 4
++#define GPIO1_SELECT 0
++
++/*GPIO_CFG2*/
++#define GPIO4_SELECT 4
++#define GPIO3_SELECT 0
++
++/*GPIO_DAT*///order???
++#define GPIO4_DAT 3
++#define GPIO3_DAT 2
++#define GPIO2_DAT 1
++#define GPIO1_DAT 0
++
++/*GPIO_DRV*/
++#define GPIO4_DRV 6
++#define GPIO3_DRV 4
++#define GPIO2_DRV 2
++#define GPIO1_DRV 0
++
++/*GPIO_PULL*/
++#define GPIO4_PULL 6
++#define GPIO3_PULL 4
++#define GPIO2_PULL 2
++#define GPIO1_PULL 0
++
++/*GPIO_INT_CFG*/
++#define GPIO4_EINT_CFG 6
++#define GPIO3_EINT_CFG 4
++#define GPIO2_EINT_CFG 2
++#define GPIO1_EINT_CFG 0
++
++/*GPIO_INT_EN*///order???
++#define GPIO4_EINT_EN 3
++#define GPIO3_EINT_EN 2
++#define GPIO2_EINT_EN 1
++#define GPIO1_EINT_EN 0
++
++/*GPIO_INT_STATUS*///order???
++#define GPIO4_EINT_STA 3
++#define GPIO3_EINT_STA 2
++#define GPIO2_EINT_STA 1
++#define GPIO1_EINT_STA 0
++
++/*PRNG_CLK_CTRL*/
++#define PRNG_CLK_EN 1
++#define PRNG_CLK_POS 0
++
++/*** Some Config Value ***/
++
++//[SYSCLK_CTRL]: PLLCLK_SRC
++#define PLLCLK_SRC_MCLK 0
++#define PLLCLK_SRC_BCLK 1
++#define PLLCLK_SRC_GPIO2 2
++#define PLLCLK_SRC_GPIO3 3
++
++//[SYSCLK_CTRL]: SYSCLK_SRC
++#define SYSCLK_SRC_MCLK 0
++#define SYSCLK_SRC_PLL 1
++
++//I2S BCLK POLARITY Control
++#define BCLK_NORMAL_DRIVE_N_SAMPLE_P 0
++#define BCLK_INVERT_DRIVE_P_SAMPLE_N 1
++
++//I2S LRCK POLARITY Control
++#define LRCK_LEFT_LOW_RIGHT_HIGH 0
++#define LRCK_LEFT_HIGH_RIGHT_LOW 1
++
++//I2S Format Selection
++#define PCM_FORMAT 0
++#define LEFT_JUSTIFIED_FORMAT 1
++#define RIGHT_JUSTIFIED_FORMAT 2
++
++//I2S data protocol types
++
++#define IS_ENCODING_MODE 0
++
++#endif
++
+--- /dev/null
++++ b/sound/soc/codecs/ac10x.h
+@@ -0,0 +1,152 @@
++/*
++ * ac10x.h
++ *
++ * (C) Copyright 2017-2018
++ * Seeed Technology Co., Ltd. <www.seeedstudio.com>
++ *
++ * PeterYang <linsheng.yang@seeed.cc>
++ *
++ * (C) Copyright 2010-2017
++ * Reuuimlla Technology Co., Ltd. <www.reuuimllatech.com>
++ * huangxin <huangxin@reuuimllatech.com>
++ *
++ * some simple description for this code
++ *
++ * 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 __AC10X_H__
++#define __AC10X_H__
++
++#define AC101_I2C_ID 4
++#define _MASTER_AC108 0
++#define _MASTER_AC101 1
++#define _MASTER_MULTI_CODEC _MASTER_AC101
++
++/* enable headset detecting & headset button pressing */
++#define CONFIG_AC101_SWITCH_DETECT
++
++/* obsolete */
++#define CONFIG_AC10X_TRIG_LOCK 0
++
++#ifdef AC101_DEBG
++ #define AC101_DBG(format,args...) printk("[AC101] %s() L%d " format, __func__, __LINE__, ##args)
++#else
++ #define AC101_DBG(...)
++#endif
++
++#include <linux/version.h>
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,18,0)
++#define __NO_SND_SOC_CODEC_DRV 1
++#else
++#define __NO_SND_SOC_CODEC_DRV 0
++#endif
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(5,4,0)
++#if __has_attribute(__fallthrough__)
++# define fallthrough __attribute__((__fallthrough__))
++#else
++# define fallthrough do {} while (0) /* fallthrough */
++#endif
++#endif
++
++#if __NO_SND_SOC_CODEC_DRV
++#define codec component
++#define snd_soc_codec snd_soc_component
++#define snd_soc_codec_driver snd_soc_component_driver
++#define snd_soc_codec_get_drvdata snd_soc_component_get_drvdata
++#define snd_soc_codec_get_dapm snd_soc_component_get_dapm
++#define snd_soc_codec_get_bias_level snd_soc_component_get_bias_level
++#define snd_soc_kcontrol_codec snd_soc_kcontrol_component
++#define snd_soc_read snd_soc_component_read32
++#define snd_soc_register_codec snd_soc_register_component
++#define snd_soc_unregister_codec snd_soc_unregister_component
++#define snd_soc_update_bits snd_soc_component_update_bits
++#define snd_soc_write snd_soc_component_write
++#define snd_soc_add_codec_controls snd_soc_add_component_controls
++#endif
++
++
++#ifdef CONFIG_AC101_SWITCH_DETECT
++enum headphone_mode_u {
++ HEADPHONE_IDLE,
++ FOUR_HEADPHONE_PLUGIN,
++ THREE_HEADPHONE_PLUGIN,
++};
++#endif
++
++struct ac10x_priv {
++ struct i2c_client *i2c[4];
++ struct regmap* i2cmap[4];
++ int codec_cnt;
++ unsigned sysclk;
++#define _FREQ_24_576K 24576000
++#define _FREQ_22_579K 22579200
++ unsigned mclk; /* master clock or aif_clock/aclk */
++ int clk_id;
++ unsigned char i2s_mode;
++ unsigned char data_protocol;
++ struct delayed_work dlywork;
++ int tdm_chips_cnt;
++ int sysclk_en;
++
++ /* member for ac101 .begin */
++ struct snd_soc_codec *codec;
++ struct i2c_client *i2c101;
++ struct regmap* regmap101;
++
++ struct mutex dac_mutex;
++ u8 dac_enable;
++ spinlock_t lock;
++ u8 aif1_clken;
++
++ struct work_struct codec_resume;
++ struct gpio_desc* gpiod_spk_amp_gate;
++
++ #ifdef CONFIG_AC101_SWITCH_DETECT
++ struct gpio_desc* gpiod_irq;
++ long irq;
++ volatile int irq_cntr;
++ volatile int pullout_cntr;
++ volatile int state;
++
++ enum headphone_mode_u mode;
++ struct work_struct work_switch;
++ struct work_struct work_clear_irq;
++
++ struct input_dev* inpdev;
++ #endif
++ /* member for ac101 .end */
++};
++
++
++/* AC101 DAI operations */
++int ac101_audio_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *codec_dai);
++void ac101_aif_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *codec_dai);
++int ac101_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt);
++int ac101_hw_params(struct snd_pcm_substream *substream,
++ struct snd_pcm_hw_params *params,
++ struct snd_soc_dai *codec_dai);
++int ac101_trigger(struct snd_pcm_substream *substream, int cmd,
++ struct snd_soc_dai *dai);
++int ac101_aif_mute(struct snd_soc_dai *codec_dai, int mute);
++
++/* codec driver specific */
++int ac101_codec_probe(struct snd_soc_codec *codec);
++int ac101_codec_remove(struct snd_soc_codec *codec);
++int ac101_codec_suspend(struct snd_soc_codec *codec);
++int ac101_codec_resume(struct snd_soc_codec *codec);
++int ac101_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level);
++
++/* i2c device specific */
++int ac101_probe(struct i2c_client *i2c, const struct i2c_device_id *id);
++void ac101_shutdown(struct i2c_client *i2c);
++int ac101_remove(struct i2c_client *i2c);
++
++int ac10x_fill_regcache(struct device* dev, struct regmap* map);
++
++#endif//__AC10X_H__
diff --git a/target/linux/starfive/patches-6.6/0080-ASoC-starfive-Add-SPDIF-and-PCM-driver.patch b/target/linux/starfive/patches-6.6/0080-ASoC-starfive-Add-SPDIF-and-PCM-driver.patch
new file mode 100644
index 0000000000..f2fb206947
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0080-ASoC-starfive-Add-SPDIF-and-PCM-driver.patch
@@ -0,0 +1,1169 @@
+From f03b7c834baef87e4f740e10a8bbcbfc57bd985a Mon Sep 17 00:00:00 2001
+From: Xingyu Wu <xingyu.wu@starfivetech.com>
+Date: Thu, 15 Jun 2023 11:32:50 +0800
+Subject: [PATCH 080/116] ASoC: starfive: Add SPDIF and PCM driver
+
+Add SPDIF and SPDIF-PCM driver for StarFive JH7110.
+
+Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ sound/soc/starfive/Kconfig | 17 +
+ sound/soc/starfive/Makefile | 5 +
+ sound/soc/starfive/jh7110_spdif.c | 568 ++++++++++++++++++++++++++
+ sound/soc/starfive/jh7110_spdif.h | 196 +++++++++
+ sound/soc/starfive/jh7110_spdif_pcm.c | 339 +++++++++++++++
+ 5 files changed, 1125 insertions(+)
+ create mode 100644 sound/soc/starfive/jh7110_spdif.c
+ create mode 100644 sound/soc/starfive/jh7110_spdif.h
+ create mode 100644 sound/soc/starfive/jh7110_spdif_pcm.c
+
+--- a/sound/soc/starfive/Kconfig
++++ b/sound/soc/starfive/Kconfig
+@@ -16,6 +16,23 @@ config SND_SOC_JH7110_PWMDAC
+ Say Y or M if you want to add support for StarFive JH7110
+ PWM-DAC driver.
+
++config SND_SOC_JH7110_SPDIF
++ tristate "JH7110 SPDIF module"
++ depends on HAVE_CLK && SND_SOC_STARFIVE
++ select SND_SOC_GENERIC_DMAENGINE_PCM
++ select REGMAP_MMIO
++ help
++ Say Y or M if you want to add support for SPDIF driver of StarFive
++ JH7110 SoC.
++
++config SND_SOC_JH7110_SPDIF_PCM
++ bool "PCM PIO extension for JH7110 SPDIF"
++ depends on SND_SOC_JH7110_SPDIF
++ default y if SND_SOC_JH7110_SPDIF
++ help
++ Say Y or N if you want to add a custom ALSA extension that registers
++ a PCM and uses PIO to transfer data.
++
+ config SND_SOC_JH7110_TDM
+ tristate "JH7110 TDM device driver"
+ depends on HAVE_CLK && SND_SOC_STARFIVE
+--- a/sound/soc/starfive/Makefile
++++ b/sound/soc/starfive/Makefile
+@@ -1,3 +1,8 @@
+ # StarFive Platform Support
+ obj-$(CONFIG_SND_SOC_JH7110_PWMDAC) += jh7110_pwmdac.o
++
++obj-$(CONFIG_SND_SOC_JH7110_SPDIF) += spdif.o
++spdif-y := jh7110_spdif.o
++spdif-$(CONFIG_SND_SOC_JH7110_SPDIF_PCM) += jh7110_spdif_pcm.o
++
+ obj-$(CONFIG_SND_SOC_JH7110_TDM) += jh7110_tdm.o
+--- /dev/null
++++ b/sound/soc/starfive/jh7110_spdif.c
+@@ -0,0 +1,568 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * SPDIF driver for the StarFive JH7110 SoC
++ *
++ * Copyright (C) 2022 StarFive Technology Co., Ltd.
++ */
++
++#include <linux/clk.h>
++#include <linux/init.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/platform_device.h>
++#include <linux/pm_runtime.h>
++#include <linux/regmap.h>
++#include <linux/reset.h>
++#include <linux/slab.h>
++#include <sound/core.h>
++#include <sound/dmaengine_pcm.h>
++#include <sound/initval.h>
++#include <sound/pcm.h>
++#include <sound/pcm_params.h>
++#include <sound/soc.h>
++
++#include "jh7110_spdif.h"
++
++static irqreturn_t spdif_irq_handler(int irq, void *dev_id)
++{
++ struct sf_spdif_dev *dev = dev_id;
++ bool irq_valid = false;
++ unsigned int intr;
++ unsigned int stat;
++
++ regmap_read(dev->regmap, SPDIF_INT_REG, &intr);
++ regmap_read(dev->regmap, SPDIF_STAT_REG, &stat);
++ regmap_update_bits(dev->regmap, SPDIF_CTRL, SPDIF_MASK_ENABLE, 0);
++ regmap_update_bits(dev->regmap, SPDIF_INT_REG, SPDIF_INT_REG_BIT, 0);
++
++ if ((stat & SPDIF_EMPTY_FLAG) || (stat & SPDIF_AEMPTY_FLAG)) {
++ sf_spdif_pcm_push_tx(dev);
++ irq_valid = true;
++ }
++
++ if ((stat & SPDIF_FULL_FLAG) || (stat & SPDIF_AFULL_FLAG)) {
++ sf_spdif_pcm_pop_rx(dev);
++ irq_valid = true;
++ }
++
++ if (stat & SPDIF_PARITY_FLAG)
++ irq_valid = true;
++
++ if (stat & SPDIF_UNDERR_FLAG)
++ irq_valid = true;
++
++ if (stat & SPDIF_OVRERR_FLAG)
++ irq_valid = true;
++
++ if (stat & SPDIF_SYNCERR_FLAG)
++ irq_valid = true;
++
++ if (stat & SPDIF_LOCK_FLAG)
++ irq_valid = true;
++
++ if (stat & SPDIF_BEGIN_FLAG)
++ irq_valid = true;
++
++ if (stat & SPDIF_RIGHT_LEFT)
++ irq_valid = true;
++
++ regmap_update_bits(dev->regmap, SPDIF_CTRL,
++ SPDIF_MASK_ENABLE, SPDIF_MASK_ENABLE);
++
++ if (irq_valid)
++ return IRQ_HANDLED;
++ else
++ return IRQ_NONE;
++}
++
++static int sf_spdif_trigger(struct snd_pcm_substream *substream, int cmd,
++ struct snd_soc_dai *dai)
++{
++ struct sf_spdif_dev *spdif = snd_soc_dai_get_drvdata(dai);
++ bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
++
++ if (tx) {
++ /* tx mode */
++ regmap_update_bits(spdif->regmap, SPDIF_CTRL,
++ SPDIF_TR_MODE, SPDIF_TR_MODE);
++
++ regmap_update_bits(spdif->regmap, SPDIF_CTRL,
++ SPDIF_MASK_FIFO, SPDIF_EMPTY_MASK | SPDIF_AEMPTY_MASK);
++ } else {
++ /* rx mode */
++ regmap_update_bits(spdif->regmap, SPDIF_CTRL,
++ SPDIF_TR_MODE, 0);
++
++ regmap_update_bits(spdif->regmap, SPDIF_CTRL,
++ SPDIF_MASK_FIFO, SPDIF_FULL_MASK | SPDIF_AFULL_MASK);
++ }
++
++ switch (cmd) {
++ case SNDRV_PCM_TRIGGER_START:
++ case SNDRV_PCM_TRIGGER_RESUME:
++ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
++ /* clock recovery form the SPDIF data stream 0:clk_enable */
++ regmap_update_bits(spdif->regmap, SPDIF_CTRL,
++ SPDIF_CLK_ENABLE, 0);
++
++ regmap_update_bits(spdif->regmap, SPDIF_CTRL,
++ SPDIF_ENABLE, SPDIF_ENABLE);
++ break;
++ case SNDRV_PCM_TRIGGER_STOP:
++ case SNDRV_PCM_TRIGGER_SUSPEND:
++ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
++ /* clock recovery form the SPDIF data stream 1:power save mode */
++ regmap_update_bits(spdif->regmap, SPDIF_CTRL,
++ SPDIF_CLK_ENABLE, SPDIF_CLK_ENABLE);
++ regmap_update_bits(spdif->regmap, SPDIF_CTRL,
++ SPDIF_ENABLE, 0);
++ break;
++ default:
++ dev_err(dai->dev, "%s L.%d cmd:%d\n", __func__, __LINE__, cmd);
++ return -EINVAL;
++ }
++
++ return 0;
++}
++
++static int sf_spdif_hw_params(struct snd_pcm_substream *substream,
++ struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
++{
++ struct sf_spdif_dev *spdif = snd_soc_dai_get_drvdata(dai);
++ unsigned int channels = params_channels(params);
++ unsigned int rate = params_rate(params);
++ unsigned int format = params_format(params);
++ unsigned int tsamplerate;
++ unsigned int mclk;
++ unsigned int audio_root;
++ int ret;
++
++ switch (channels) {
++ case 1:
++ regmap_update_bits(spdif->regmap, SPDIF_CTRL,
++ SPDIF_CHANNEL_MODE, SPDIF_CHANNEL_MODE);
++ regmap_update_bits(spdif->regmap, SPDIF_CTRL,
++ SPDIF_DUPLICATE, SPDIF_DUPLICATE);
++ spdif->channels = false;
++ break;
++ case 2:
++ regmap_update_bits(spdif->regmap, SPDIF_CTRL,
++ SPDIF_CHANNEL_MODE, 0);
++ spdif->channels = true;
++ break;
++ default:
++ dev_err(dai->dev, "invalid channels number\n");
++ return -EINVAL;
++ }
++
++ switch (format) {
++ case SNDRV_PCM_FORMAT_S16_LE:
++ case SNDRV_PCM_FORMAT_S24_LE:
++ case SNDRV_PCM_FORMAT_S24_3LE:
++ case SNDRV_PCM_FORMAT_S32_LE:
++ break;
++ default:
++ dev_err(dai->dev, "invalid format\n");
++ return -EINVAL;
++ }
++
++ switch (rate) {
++ case 8000:
++ break;
++ case 11025:
++ audio_root = 148500000;
++ /* 11025 * 512 = 5644800 */
++ /* But now pll2 is 1188m and mclk should be 5711539 closely. */
++ mclk = 5711539;
++ break;
++ case 16000:
++ break;
++ case 22050:
++ audio_root = 148500000;
++ mclk = 11423077;
++ break;
++ default:
++ dev_err(dai->dev, "channel:%d sample rate:%d\n", channels, rate);
++ return -EINVAL;
++ }
++
++ /* use mclk_inner clock from 1188m PLL2 will be better about 11k and 22k*/
++ if ((rate == 11025) || (rate == 22050)) {
++ ret = clk_set_parent(spdif->mclk, spdif->mclk_inner);
++ if (ret) {
++ dev_err(dai->dev,
++ "failed to set parent to mclk_inner ret=%d\n", ret);
++ goto fail_ext;
++ }
++
++ ret = clk_set_rate(spdif->audio_root, audio_root);
++ if (ret) {
++ dev_err(dai->dev, "failed to set audio_root rate :%d\n", ret);
++ goto fail_ext;
++ }
++
++ ret = clk_set_rate(spdif->mclk_inner, mclk);
++ if (ret) {
++ dev_err(dai->dev, "failed to set mclk_inner rate :%d\n", ret);
++ goto fail_ext;
++ }
++
++ mclk = clk_get_rate(spdif->mclk_inner);
++ } else {
++ ret = clk_set_parent(spdif->mclk, spdif->mclk_ext);
++ if (ret) {
++ dev_err(dai->dev,
++ "failed to set parent to mclk_ext ret=%d\n", ret);
++ goto fail_ext;
++ }
++
++ mclk = clk_get_rate(spdif->mclk_ext);
++ }
++
++ /* (FCLK)4096000/128=32000 */
++ tsamplerate = (mclk / 128 + rate / 2) / rate - 1;
++ if (tsamplerate < 3)
++ tsamplerate = 3;
++
++ /* transmission sample rate */
++ regmap_update_bits(spdif->regmap, SPDIF_CTRL, 0xFF, tsamplerate);
++
++ return 0;
++
++fail_ext:
++ return ret;
++}
++
++static int sf_spdif_clks_get(struct platform_device *pdev,
++ struct sf_spdif_dev *spdif)
++{
++ static struct clk_bulk_data clks[] = {
++ { .id = "apb" }, /* clock-names in dts file */
++ { .id = "core" },
++ { .id = "audroot" },
++ { .id = "mclk_inner"},
++ { .id = "mclk_ext"},
++ { .id = "mclk"},
++ };
++ int ret = devm_clk_bulk_get(&pdev->dev, ARRAY_SIZE(clks), clks);
++
++ spdif->spdif_apb = clks[0].clk;
++ spdif->spdif_core = clks[1].clk;
++ spdif->audio_root = clks[2].clk;
++ spdif->mclk_inner = clks[3].clk;
++ spdif->mclk_ext = clks[4].clk;
++ spdif->mclk = clks[5].clk;
++
++ return ret;
++}
++
++static int sf_spdif_resets_get(struct platform_device *pdev,
++ struct sf_spdif_dev *spdif)
++{
++ struct reset_control_bulk_data resets[] = {
++ { .id = "apb" },
++ };
++ int ret = devm_reset_control_bulk_get_exclusive(&pdev->dev, ARRAY_SIZE(resets), resets);
++
++ if (ret)
++ return ret;
++
++ spdif->rst_apb = resets[0].rstc;
++
++ return 0;
++}
++
++static int starfive_spdif_crg_enable(struct sf_spdif_dev *spdif, bool enable)
++{
++ int ret;
++
++ dev_dbg(spdif->dev, "starfive_spdif clk&rst %sable.\n", enable ? "en":"dis");
++ if (enable) {
++ ret = clk_prepare_enable(spdif->spdif_apb);
++ if (ret) {
++ dev_err(spdif->dev, "failed to prepare enable spdif_apb\n");
++ goto failed_apb_clk;
++ }
++
++ ret = clk_prepare_enable(spdif->spdif_core);
++ if (ret) {
++ dev_err(spdif->dev, "failed to prepare enable spdif_core\n");
++ goto failed_core_clk;
++ }
++
++ ret = reset_control_deassert(spdif->rst_apb);
++ if (ret) {
++ dev_err(spdif->dev, "failed to deassert apb\n");
++ goto failed_rst;
++ }
++ } else {
++ clk_disable_unprepare(spdif->spdif_core);
++ clk_disable_unprepare(spdif->spdif_apb);
++ }
++
++ return 0;
++
++failed_rst:
++ clk_disable_unprepare(spdif->spdif_core);
++failed_core_clk:
++ clk_disable_unprepare(spdif->spdif_apb);
++failed_apb_clk:
++ return ret;
++}
++
++static int sf_spdif_dai_probe(struct snd_soc_dai *dai)
++{
++ struct sf_spdif_dev *spdif = snd_soc_dai_get_drvdata(dai);
++
++ pm_runtime_get_sync(spdif->dev);
++
++ /* reset */
++ regmap_update_bits(spdif->regmap, SPDIF_CTRL,
++ SPDIF_ENABLE | SPDIF_SFR_ENABLE | SPDIF_FIFO_ENABLE, 0);
++
++ /* clear irq */
++ regmap_update_bits(spdif->regmap, SPDIF_INT_REG,
++ SPDIF_INT_REG_BIT, 0);
++
++ /* power save mode */
++ regmap_update_bits(spdif->regmap, SPDIF_CTRL,
++ SPDIF_CLK_ENABLE, SPDIF_CLK_ENABLE);
++
++ /* power save mode */
++ regmap_update_bits(spdif->regmap, SPDIF_CTRL,
++ SPDIF_CLK_ENABLE, SPDIF_CLK_ENABLE);
++
++ regmap_update_bits(spdif->regmap, SPDIF_CTRL,
++ SPDIF_PARITCHECK|SPDIF_VALIDITYCHECK|SPDIF_DUPLICATE,
++ SPDIF_PARITCHECK|SPDIF_VALIDITYCHECK|SPDIF_DUPLICATE);
++
++ regmap_update_bits(spdif->regmap, SPDIF_CTRL,
++ SPDIF_SETPREAMBB, SPDIF_SETPREAMBB);
++
++ regmap_update_bits(spdif->regmap, SPDIF_INT_REG,
++ BIT8TO20MASK<<SPDIF_PREAMBLEDEL, 0x3<<SPDIF_PREAMBLEDEL);
++
++ regmap_update_bits(spdif->regmap, SPDIF_FIFO_CTRL,
++ ALLBITMASK, 0x20|(0x20<<SPDIF_AFULL_THRESHOLD));
++
++ regmap_update_bits(spdif->regmap, SPDIF_CTRL,
++ SPDIF_PARITYGEN, SPDIF_PARITYGEN);
++
++ regmap_update_bits(spdif->regmap, SPDIF_CTRL,
++ SPDIF_MASK_ENABLE, SPDIF_MASK_ENABLE);
++
++ /* APB access to FIFO enable, disable if use DMA/FIFO */
++ regmap_update_bits(spdif->regmap, SPDIF_CTRL,
++ SPDIF_USE_FIFO_IF, 0);
++
++ /* two channel */
++ regmap_update_bits(spdif->regmap, SPDIF_CTRL,
++ SPDIF_CHANNEL_MODE, 0);
++
++ pm_runtime_put_sync(spdif->dev);
++ return 0;
++}
++
++static const struct snd_soc_dai_ops sf_spdif_dai_ops = {
++ .probe = sf_spdif_dai_probe,
++ .trigger = sf_spdif_trigger,
++ .hw_params = sf_spdif_hw_params,
++};
++
++#ifdef CONFIG_PM_SLEEP
++static int spdif_system_suspend(struct device *dev)
++{
++ struct sf_spdif_dev *spdif = dev_get_drvdata(dev);
++
++ /* save the register value */
++ regmap_read(spdif->regmap, SPDIF_CTRL, &spdif->reg_spdif_ctrl);
++ regmap_read(spdif->regmap, SPDIF_INT_REG, &spdif->reg_spdif_int);
++ regmap_read(spdif->regmap, SPDIF_FIFO_CTRL, &spdif->reg_spdif_fifo_ctrl);
++
++ return pm_runtime_force_suspend(dev);
++}
++
++static int spdif_system_resume(struct device *dev)
++{
++ struct sf_spdif_dev *spdif = dev_get_drvdata(dev);
++ int ret = pm_runtime_force_resume(dev);
++
++ if (ret)
++ return ret;
++
++ /* restore the register value */
++ regmap_update_bits(spdif->regmap, SPDIF_CTRL,
++ ALLBITMASK, spdif->reg_spdif_ctrl);
++ regmap_update_bits(spdif->regmap, SPDIF_INT_REG,
++ ALLBITMASK, spdif->reg_spdif_int);
++ regmap_update_bits(spdif->regmap, SPDIF_FIFO_CTRL,
++ ALLBITMASK, spdif->reg_spdif_fifo_ctrl);
++
++ return 0;
++}
++#endif
++
++#ifdef CONFIG_PM
++static int spdif_runtime_suspend(struct device *dev)
++{
++ struct sf_spdif_dev *spdif = dev_get_drvdata(dev);
++
++ return starfive_spdif_crg_enable(spdif, false);
++}
++
++static int spdif_runtime_resume(struct device *dev)
++{
++ struct sf_spdif_dev *spdif = dev_get_drvdata(dev);
++
++ return starfive_spdif_crg_enable(spdif, true);
++}
++#endif
++
++static const struct dev_pm_ops spdif_pm_ops = {
++ SET_RUNTIME_PM_OPS(spdif_runtime_suspend, spdif_runtime_resume, NULL)
++ SET_SYSTEM_SLEEP_PM_OPS(spdif_system_suspend, spdif_system_resume)
++};
++
++#define SF_PCM_RATE_44100_192000 (SNDRV_PCM_RATE_44100 | \
++ SNDRV_PCM_RATE_48000 | \
++ SNDRV_PCM_RATE_96000 | \
++ SNDRV_PCM_RATE_192000)
++
++#define SF_PCM_RATE_8000_22050 (SNDRV_PCM_RATE_8000 | \
++ SNDRV_PCM_RATE_11025 | \
++ SNDRV_PCM_RATE_16000 | \
++ SNDRV_PCM_RATE_22050)
++
++static struct snd_soc_dai_driver sf_spdif_dai = {
++ .name = "spdif",
++ .id = 0,
++ .playback = {
++ .stream_name = "Playback",
++ .channels_min = 1,
++ .channels_max = 2,
++ .rates = SF_PCM_RATE_8000_22050,
++ .formats = SNDRV_PCM_FMTBIT_S16_LE |
++ SNDRV_PCM_FMTBIT_S24_LE |
++ SNDRV_PCM_FMTBIT_S24_3LE |
++ SNDRV_PCM_FMTBIT_S32_LE,
++ },
++ .ops = &sf_spdif_dai_ops,
++ .symmetric_rate = 1,
++};
++
++static const struct snd_soc_component_driver sf_spdif_component = {
++ .name = "starfive-spdif",
++};
++
++static const struct regmap_config sf_spdif_regmap_config = {
++ .reg_bits = 32,
++ .reg_stride = 4,
++ .val_bits = 32,
++ .max_register = 0x200,
++};
++
++static int sf_spdif_probe(struct platform_device *pdev)
++{
++ struct sf_spdif_dev *spdif;
++ struct resource *res;
++ void __iomem *base;
++ int ret;
++ int irq;
++
++ spdif = devm_kzalloc(&pdev->dev, sizeof(*spdif), GFP_KERNEL);
++ if (!spdif)
++ return -ENOMEM;
++
++ platform_set_drvdata(pdev, spdif);
++
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ base = devm_ioremap_resource(&pdev->dev, res);
++ if (IS_ERR(base))
++ return PTR_ERR(base);
++
++ spdif->spdif_base = base;
++ spdif->regmap = devm_regmap_init_mmio(&pdev->dev, spdif->spdif_base,
++ &sf_spdif_regmap_config);
++ if (IS_ERR(spdif->regmap))
++ return PTR_ERR(spdif->regmap);
++
++ spdif->dev = &pdev->dev;
++
++ ret = sf_spdif_clks_get(pdev, spdif);
++ if (ret) {
++ dev_err(&pdev->dev, "failed to get audio clock\n");
++ return ret;
++ }
++
++ ret = sf_spdif_resets_get(pdev, spdif);
++ if (ret) {
++ dev_err(&pdev->dev, "failed to get audio reset controls\n");
++ return ret;
++ }
++
++ ret = starfive_spdif_crg_enable(spdif, true);
++ if (ret) {
++ dev_err(&pdev->dev, "failed to enable audio clock\n");
++ return ret;
++ }
++
++ spdif->fifo_th = 16;
++
++ irq = platform_get_irq(pdev, 0);
++ if (irq >= 0) {
++ ret = devm_request_irq(&pdev->dev, irq, spdif_irq_handler, 0,
++ pdev->name, spdif);
++ if (ret < 0) {
++ dev_err(&pdev->dev, "failed to request irq\n");
++ return ret;
++ }
++ }
++
++ ret = devm_snd_soc_register_component(&pdev->dev, &sf_spdif_component,
++ &sf_spdif_dai, 1);
++ if (ret)
++ goto err_clk_disable;
++
++ if (irq >= 0) {
++ ret = sf_spdif_pcm_register(pdev);
++ spdif->use_pio = true;
++ } else {
++ ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL,
++ 0);
++ spdif->use_pio = false;
++ }
++
++ if (ret)
++ goto err_clk_disable;
++
++ starfive_spdif_crg_enable(spdif, false);
++ pm_runtime_enable(&pdev->dev);
++ dev_dbg(&pdev->dev, "spdif register done.\n");
++
++ return 0;
++
++err_clk_disable:
++ return ret;
++}
++
++static const struct of_device_id sf_spdif_of_match[] = {
++ { .compatible = "starfive,jh7110-spdif", },
++ {},
++};
++MODULE_DEVICE_TABLE(of, sf_spdif_of_match);
++
++static struct platform_driver sf_spdif_driver = {
++ .driver = {
++ .name = "starfive-spdif",
++ .of_match_table = sf_spdif_of_match,
++ .pm = &spdif_pm_ops,
++ },
++ .probe = sf_spdif_probe,
++};
++module_platform_driver(sf_spdif_driver);
++
++MODULE_AUTHOR("curry.zhang <curry.zhang@starfive.com>");
++MODULE_AUTHOR("Xingyu Wu <xingyu.wu@starfivetech.com>");
++MODULE_DESCRIPTION("starfive SPDIF driver");
++MODULE_LICENSE("GPL v2");
+--- /dev/null
++++ b/sound/soc/starfive/jh7110_spdif.h
+@@ -0,0 +1,196 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++/*
++ * SPDIF driver for the StarFive JH7110 SoC
++ *
++ * Copyright (C) 2022 StarFive Technology Co., Ltd.
++ */
++
++#ifndef __SND_SOC_JH7110_SPDIF_H
++#define __SND_SOC_JH7110_SPDIF_H
++
++#include <linux/clk.h>
++#include <linux/device.h>
++#include <linux/dmaengine.h>
++#include <linux/types.h>
++#include <sound/dmaengine_pcm.h>
++#include <sound/pcm.h>
++
++#define SPDIF_CTRL 0x0
++#define SPDIF_INT_REG 0x4
++#define SPDIF_FIFO_CTRL 0x8
++#define SPDIF_STAT_REG 0xC
++
++#define SPDIF_FIFO_ADDR 0x100
++#define DMAC_SPDIF_POLLING_LEN 256
++
++/* ctrl: sampled on the rising clock edge */
++#define SPDIF_TSAMPLERATE 0 /* [SRATEW-1:0] */
++/* 0:SFR reg reset to defualt value; auto set back to '1' after reset */
++#define SPDIF_SFR_ENABLE (1<<8)
++/* 0:reset of SPDIF block, SRF bits are unchanged; 1:enables SPDIF module */
++#define SPDIF_ENABLE (1<<9)
++/* 0:FIFO pointers are reset to zero,threshold levels for FIFO are unchaned; auto set back to 1 */
++#define SPDIF_FIFO_ENABLE (1<<10)
++/* 1:blocked and the modules are in power save mode; 0:block feeds the modules */
++#define SPDIF_CLK_ENABLE (1<<11)
++#define SPDIF_TR_MODE (1<<12) /* 0:rx; 1:tx */
++/* 0:party bit rx in a sub-frame is repeated on the parity; 1:check on a parity error */
++#define SPDIF_PARITCHECK (1<<13)
++/*
++ * 0:parity bit from FIFO is transmitted in sub-frame;
++ * 1:parity bit generated inside the core and added to a transmitted sub-frame
++ */
++#define SPDIF_PARITYGEN (1<<14)
++/* 0:validity bit in frame isn't checked and all frame are written; 1:validity bit rx is checked */
++#define SPDIF_VALIDITYCHECK (1<<15)
++#define SPDIF_CHANNEL_MODE (1<<16) /* 0:two-channel; 1:single-channel */
++/* only tx -single-channel mode; 0:secondary channel; 1: left(primary) channel */
++#define SPDIF_DUPLICATE (1<<17)
++/*
++ * only tx;
++ * 0:first preamble B after reset tx valid sub-frame;
++ * 1:first preamble B is tx after preambleddel(INT_REG)
++ */
++#define SPDIF_SETPREAMBB (1<<18)
++/* 0:FIFO disabled ,APB accese FIFO; 1:FIFO enable, APB access to FIFO disable; */
++#define SPDIF_USE_FIFO_IF (1<<19)
++#define SPDIF_PARITY_MASK (1<<21)
++#define SPDIF_UNDERR_MASK (1<<22)
++#define SPDIF_OVRERR_MASK (1<<23)
++#define SPDIF_EMPTY_MASK (1<<24)
++#define SPDIF_AEMPTY_MASK (1<<25)
++#define SPDIF_FULL_MASK (1<<26)
++#define SPDIF_AFULL_MASK (1<<27)
++#define SPDIF_SYNCERR_MASK (1<<28)
++#define SPDIF_LOCK_MASK (1<<29)
++#define SPDIF_BEGIN_MASK (1<<30)
++#define SPDIF_INTEREQ_MAKS (1<<31)
++
++#define SPDIF_MASK_ENABLE (SPDIF_PARITY_MASK | SPDIF_UNDERR_MASK | \
++ SPDIF_OVRERR_MASK | SPDIF_EMPTY_MASK | \
++ SPDIF_AEMPTY_MASK | SPDIF_FULL_MASK | \
++ SPDIF_AFULL_MASK | SPDIF_SYNCERR_MASK | \
++ SPDIF_LOCK_MASK | SPDIF_BEGIN_MASK | \
++ SPDIF_INTEREQ_MAKS)
++
++#define SPDIF_MASK_FIFO (SPDIF_EMPTY_MASK | SPDIF_AEMPTY_MASK | \
++ SPDIF_FULL_MASK | SPDIF_AFULL_MASK)
++
++/* INT_REG */
++#define SPDIF_RSAMPLERATE 0 /* [SRATEW-1:0] */
++#define SPDIF_PREAMBLEDEL 8 /* [PDELAYW+7:8] first B delay */
++#define SPDIF_PARITYO (1<<21) /* 0:clear parity error */
++#define SPDIF_TDATA_UNDERR (1<<22) /* tx data underrun error;0:clear */
++#define SPDIF_RDATA_OVRERR (1<<23) /* rx data overrun error; 0:clear */
++#define SPDIF_FIFO_EMPTY (1<<24) /* empty; 0:clear */
++#define SPDIF_FIOF_AEMPTY (1<<25) /* almost empty; 0:clear */
++#define SPDIF_FIFO_FULL (1<<26) /* FIFO full; 0:clear */
++#define SPDIF_FIFO_AFULL (1<<27) /* FIFO almost full; 0:clear */
++#define SPDIF_SYNCERR (1<<28) /* sync error; 0:clear */
++#define SPDIF_LOCK (1<<29) /* sync; 0:clear */
++#define SPDIF_BLOCK_BEGIN (1<<30) /* new start block rx data */
++
++#define SPDIF_INT_REG_BIT (SPDIF_PARITYO | SPDIF_TDATA_UNDERR | \
++ SPDIF_RDATA_OVRERR | SPDIF_FIFO_EMPTY | \
++ SPDIF_FIOF_AEMPTY | SPDIF_FIFO_FULL | \
++ SPDIF_FIFO_AFULL | SPDIF_SYNCERR | \
++ SPDIF_LOCK | SPDIF_BLOCK_BEGIN)
++
++#define SPDIF_ERROR_INT_STATUS (SPDIF_PARITYO | \
++ SPDIF_TDATA_UNDERR | SPDIF_RDATA_OVRERR)
++#define SPDIF_FIFO_INT_STATUS (SPDIF_FIFO_EMPTY | SPDIF_FIOF_AEMPTY | \
++ SPDIF_FIFO_FULL | SPDIF_FIFO_AFULL)
++
++#define SPDIF_INT_PARITY_ERROR (-1)
++#define SPDIF_INT_TDATA_UNDERR (-2)
++#define SPDIF_INT_RDATA_OVRERR (-3)
++#define SPDIF_INT_FIFO_EMPTY 1
++#define SPDIF_INT_FIFO_AEMPTY 2
++#define SPDIF_INT_FIFO_FULL 3
++#define SPDIF_INT_FIFO_AFULL 4
++#define SPDIF_INT_SYNCERR (-4)
++#define SPDIF_INT_LOCK 5 /* reciever has become synchronized with input data stream */
++#define SPDIF_INT_BLOCK_BEGIN 6 /* start a new block in recieve data, written into FIFO */
++
++/* FIFO_CTRL */
++#define SPDIF_AEMPTY_THRESHOLD 0 /* [depth-1:0] */
++#define SPDIF_AFULL_THRESHOLD 16 /* [depth+15:16] */
++
++/* STAT_REG */
++#define SPDIF_FIFO_LEVEL (1<<0)
++#define SPDIF_PARITY_FLAG (1<<21) /* 1:error; 0:repeated */
++#define SPDIF_UNDERR_FLAG (1<<22) /* 1:error */
++#define SPDIF_OVRERR_FLAG (1<<23) /* 1:error */
++#define SPDIF_EMPTY_FLAG (1<<24) /* 1:fifo empty */
++#define SPDIF_AEMPTY_FLAG (1<<25) /* 1:fifo almost empty */
++#define SPDIF_FULL_FLAG (1<<26) /* 1:fifo full */
++#define SPDIF_AFULL_FLAG (1<<27) /* 1:fifo almost full */
++#define SPDIF_SYNCERR_FLAG (1<<28) /* 1:rx sync error */
++#define SPDIF_LOCK_FLAG (1<<29) /* 1:RX sync */
++#define SPDIF_BEGIN_FLAG (1<<30) /* 1:start a new block */
++/* 1:left channel received and tx into FIFO; 0:right channel received and tx into FIFO */
++#define SPDIF_RIGHT_LEFT (1<<31)
++
++#define BIT8TO20MASK 0x1FFF
++#define ALLBITMASK 0xFFFFFFFF
++
++#define SPDIF_STAT (SPDIF_PARITY_FLAG | SPDIF_UNDERR_FLAG | \
++ SPDIF_OVRERR_FLAG | SPDIF_EMPTY_FLAG | \
++ SPDIF_AEMPTY_FLAG | SPDIF_FULL_FLAG | \
++ SPDIF_AFULL_FLAG | SPDIF_SYNCERR_FLAG | \
++ SPDIF_LOCK_FLAG | SPDIF_BEGIN_FLAG | \
++ SPDIF_RIGHT_LEFT)
++struct sf_spdif_dev {
++ void __iomem *spdif_base;
++ struct regmap *regmap;
++ struct device *dev;
++ u32 fifo_th;
++ int active;
++
++ /* data related to DMA transfers b/w i2s and DMAC */
++ struct snd_dmaengine_dai_dma_data play_dma_data;
++ struct snd_dmaengine_dai_dma_data capture_dma_data;
++
++ bool use_pio;
++ struct snd_pcm_substream __rcu *tx_substream;
++ struct snd_pcm_substream __rcu *rx_substream;
++
++ unsigned int (*tx_fn)(struct sf_spdif_dev *dev,
++ struct snd_pcm_runtime *runtime, unsigned int tx_ptr,
++ bool *period_elapsed, snd_pcm_format_t format);
++ unsigned int (*rx_fn)(struct sf_spdif_dev *dev,
++ struct snd_pcm_runtime *runtime, unsigned int rx_ptr,
++ bool *period_elapsed, snd_pcm_format_t format);
++
++ snd_pcm_format_t format;
++ bool channels;
++ unsigned int tx_ptr;
++ unsigned int rx_ptr;
++ struct clk *spdif_apb;
++ struct clk *spdif_core;
++ struct clk *audio_root;
++ struct clk *mclk_inner;
++ struct clk *mclk;
++ struct clk *mclk_ext;
++ struct reset_control *rst_apb;
++ unsigned int reg_spdif_ctrl;
++ unsigned int reg_spdif_int;
++ unsigned int reg_spdif_fifo_ctrl;
++
++ struct snd_dmaengine_dai_dma_data dma_data;
++};
++
++#if IS_ENABLED(CONFIG_SND_SOC_JH7110_SPDIF_PCM)
++void sf_spdif_pcm_push_tx(struct sf_spdif_dev *dev);
++void sf_spdif_pcm_pop_rx(struct sf_spdif_dev *dev);
++int sf_spdif_pcm_register(struct platform_device *pdev);
++#else
++void sf_spdif_pcm_push_tx(struct sf_spdif_dev *dev) { }
++void sf_spdif_pcm_pop_rx(struct sf_spdif_dev *dev) { }
++int sf_spdif_pcm_register(struct platform_device *pdev)
++{
++ return -EINVAL;
++}
++#endif
++
++#endif /* __SND_SOC_JH7110_SPDIF_H */
+--- /dev/null
++++ b/sound/soc/starfive/jh7110_spdif_pcm.c
+@@ -0,0 +1,339 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * SPDIF PCM driver for the StarFive JH7110 SoC
++ *
++ * Copyright (C) 2022 StarFive Technology Co., Ltd.
++ */
++
++#include <linux/io.h>
++#include <linux/rcupdate.h>
++#include <sound/pcm.h>
++#include <sound/pcm_params.h>
++
++#include "jh7110_spdif.h"
++
++#define BUFFER_BYTES_MAX (3 * 2 * 8 * PERIOD_BYTES_MIN)
++#define PERIOD_BYTES_MIN 4096
++#define PERIODS_MIN 2
++
++static unsigned int sf_spdif_pcm_tx(struct sf_spdif_dev *dev,
++ struct snd_pcm_runtime *runtime, unsigned int tx_ptr,
++ bool *period_elapsed, snd_pcm_format_t format)
++{
++ unsigned int period_pos = tx_ptr % runtime->period_size;
++ u32 data[2];
++ int i;
++
++ /* two- channel and signal-channel mode */
++ if (dev->channels) {
++ const u16 (*p16)[2] = (void *)runtime->dma_area;
++ const u32 (*p32)[2] = (void *)runtime->dma_area;
++
++ for (i = 0; i < dev->fifo_th; i++) {
++ if (format == SNDRV_PCM_FORMAT_S16_LE) {
++ data[0] = p16[tx_ptr][0];
++ data[0] = data[0]<<8;
++ data[0] &= 0x00ffff00;
++ data[1] = p16[tx_ptr][1];
++ data[1] = data[1]<<8;
++ data[1] &= 0x00ffff00;
++ } else if (format == SNDRV_PCM_FORMAT_S24_LE) {
++ data[0] = p32[tx_ptr][0];
++ data[1] = p32[tx_ptr][1];
++
++ /*
++ * To adapt S24_3LE and ALSA pass parameter of S24_LE.
++ * operation of S24_LE should be same to S24_3LE.
++ * So it would wrong when playback S24_LE file.
++ * when want to playback S24_LE file, should add in there:
++ * data[0] = data[0]>>8;
++ * data[1] = data[1]>>8;
++ */
++
++ data[0] &= 0x00ffffff;
++ data[1] &= 0x00ffffff;
++ } else if (format == SNDRV_PCM_FORMAT_S24_3LE) {
++ data[0] = p32[tx_ptr][0];
++ data[1] = p32[tx_ptr][1];
++ data[0] &= 0x00ffffff;
++ data[1] &= 0x00ffffff;
++ } else if (format == SNDRV_PCM_FORMAT_S32_LE) {
++ data[0] = p32[tx_ptr][0];
++ data[0] = data[0]>>8;
++ data[1] = p32[tx_ptr][1];
++ data[1] = data[1]>>8;
++ }
++
++ iowrite32(data[0], dev->spdif_base + SPDIF_FIFO_ADDR);
++ iowrite32(data[1], dev->spdif_base + SPDIF_FIFO_ADDR);
++ period_pos++;
++ if (++tx_ptr >= runtime->buffer_size)
++ tx_ptr = 0;
++ }
++ } else {
++ const u16 (*p16) = (void *)runtime->dma_area;
++ const u32 (*p32) = (void *)runtime->dma_area;
++
++ for (i = 0; i < dev->fifo_th; i++) {
++ if (format == SNDRV_PCM_FORMAT_S16_LE) {
++ data[0] = p16[tx_ptr];
++ data[0] = data[0]<<8;
++ data[0] &= 0x00ffff00;
++ } else if (format == SNDRV_PCM_FORMAT_S24_LE ||
++ format == SNDRV_PCM_FORMAT_S24_3LE) {
++ data[0] = p32[tx_ptr];
++ data[0] &= 0x00ffffff;
++ } else if (format == SNDRV_PCM_FORMAT_S32_LE) {
++ data[0] = p32[tx_ptr];
++ data[0] = data[0]>>8;
++ }
++
++ iowrite32(data[0], dev->spdif_base + SPDIF_FIFO_ADDR);
++ period_pos++;
++ if (++tx_ptr >= runtime->buffer_size)
++ tx_ptr = 0;
++ }
++ }
++
++ *period_elapsed = period_pos >= runtime->period_size;
++ return tx_ptr;
++}
++
++static unsigned int sf_spdif_pcm_rx(struct sf_spdif_dev *dev,
++ struct snd_pcm_runtime *runtime, unsigned int rx_ptr,
++ bool *period_elapsed, snd_pcm_format_t format)
++{
++ u16 (*p16)[2] = (void *)runtime->dma_area;
++ u32 (*p32)[2] = (void *)runtime->dma_area;
++ unsigned int period_pos = rx_ptr % runtime->period_size;
++ u32 data[2];
++ int i;
++
++ for (i = 0; i < dev->fifo_th; i++) {
++ data[0] = ioread32(dev->spdif_base + SPDIF_FIFO_ADDR);
++ data[1] = ioread32(dev->spdif_base + SPDIF_FIFO_ADDR);
++ if (format == SNDRV_PCM_FORMAT_S16_LE) {
++ p16[rx_ptr][0] = data[0]>>8;
++ p16[rx_ptr][1] = data[1]>>8;
++ } else if (format == SNDRV_PCM_FORMAT_S24_LE) {
++ p32[rx_ptr][0] = data[0];
++ p32[rx_ptr][1] = data[1];
++ } else if (format == SNDRV_PCM_FORMAT_S32_LE) {
++ p32[rx_ptr][0] = data[0]<<8;
++ p32[rx_ptr][1] = data[1]<<8;
++ }
++
++ period_pos++;
++ if (++rx_ptr >= runtime->buffer_size)
++ rx_ptr = 0;
++ }
++
++ *period_elapsed = period_pos >= runtime->period_size;
++ return rx_ptr;
++}
++
++static const struct snd_pcm_hardware sf_pcm_hardware = {
++ .info = SNDRV_PCM_INFO_INTERLEAVED |
++ SNDRV_PCM_INFO_MMAP |
++ SNDRV_PCM_INFO_MMAP_VALID |
++ SNDRV_PCM_INFO_BLOCK_TRANSFER |
++ SNDRV_PCM_INFO_PAUSE |
++ SNDRV_PCM_INFO_RESUME,
++ .rates = SNDRV_PCM_RATE_8000 |
++ SNDRV_PCM_RATE_11025 |
++ SNDRV_PCM_RATE_16000 |
++ SNDRV_PCM_RATE_22050 |
++ SNDRV_PCM_RATE_32000 |
++ SNDRV_PCM_RATE_44100 |
++ SNDRV_PCM_RATE_48000,
++ .rate_min = 8000,
++ .rate_max = 48000,
++ .formats = SNDRV_PCM_FMTBIT_S16_LE |
++ SNDRV_PCM_FMTBIT_S24_LE |
++ SNDRV_PCM_FMTBIT_S24_3LE |
++ SNDRV_PCM_FMTBIT_S32_LE,
++ .channels_min = 1,
++ .channels_max = 2,
++ .buffer_bytes_max = BUFFER_BYTES_MAX,
++ .period_bytes_min = PERIOD_BYTES_MIN,
++ .period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN,
++ .periods_min = PERIODS_MIN,
++ .periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN,
++ .fifo_size = 16,
++};
++
++static void sf_spdif_pcm_transfer(struct sf_spdif_dev *dev, bool push)
++{
++ struct snd_pcm_substream *substream;
++ bool active, period_elapsed;
++
++ rcu_read_lock();
++ if (push)
++ substream = rcu_dereference(dev->tx_substream);
++ else
++ substream = rcu_dereference(dev->rx_substream);
++
++ active = substream && snd_pcm_running(substream);
++ if (active) {
++ unsigned int ptr;
++ unsigned int new_ptr;
++
++ if (push) {
++ ptr = READ_ONCE(dev->tx_ptr);
++ new_ptr = dev->tx_fn(dev, substream->runtime, ptr,
++ &period_elapsed, dev->format);
++ cmpxchg(&dev->tx_ptr, ptr, new_ptr);
++ } else {
++ ptr = READ_ONCE(dev->rx_ptr);
++ new_ptr = dev->rx_fn(dev, substream->runtime, ptr,
++ &period_elapsed, dev->format);
++ cmpxchg(&dev->rx_ptr, ptr, new_ptr);
++ }
++
++ if (period_elapsed)
++ snd_pcm_period_elapsed(substream);
++ }
++ rcu_read_unlock();
++}
++
++void sf_spdif_pcm_push_tx(struct sf_spdif_dev *dev)
++{
++ sf_spdif_pcm_transfer(dev, true);
++}
++
++void sf_spdif_pcm_pop_rx(struct sf_spdif_dev *dev)
++{
++ sf_spdif_pcm_transfer(dev, false);
++}
++
++static int sf_pcm_open(struct snd_soc_component *component,
++ struct snd_pcm_substream *substream)
++{
++ struct snd_pcm_runtime *runtime = substream->runtime;
++ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
++ struct sf_spdif_dev *dev = snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0));
++
++ snd_soc_set_runtime_hwparams(substream, &sf_pcm_hardware);
++ snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
++ runtime->private_data = dev;
++
++ return 0;
++}
++
++static int sf_pcm_close(struct snd_soc_component *component,
++ struct snd_pcm_substream *substream)
++{
++ synchronize_rcu();
++ return 0;
++}
++
++static int sf_pcm_hw_params(struct snd_soc_component *component,
++ struct snd_pcm_substream *substream,
++ struct snd_pcm_hw_params *hw_params)
++{
++ struct snd_pcm_runtime *runtime = substream->runtime;
++ struct sf_spdif_dev *dev = runtime->private_data;
++
++ switch (params_channels(hw_params)) {
++ case 1:
++ case 2:
++ break;
++ default:
++ dev_err(dev->dev, "invalid channels number\n");
++ return -EINVAL;
++ }
++
++ dev->format = params_format(hw_params);
++ switch (dev->format) {
++ case SNDRV_PCM_FORMAT_S16_LE:
++ case SNDRV_PCM_FORMAT_S24_LE:
++ case SNDRV_PCM_FORMAT_S24_3LE:
++ case SNDRV_PCM_FORMAT_S32_LE:
++ break;
++ default:
++ dev_err(dev->dev, "invalid format\n");
++ return -EINVAL;
++ }
++
++ dev->tx_fn = sf_spdif_pcm_tx;
++ dev->rx_fn = sf_spdif_pcm_rx;
++
++ return 0;
++}
++
++static int sf_pcm_trigger(struct snd_soc_component *component,
++ struct snd_pcm_substream *substream, int cmd)
++{
++ struct snd_pcm_runtime *runtime = substream->runtime;
++ struct sf_spdif_dev *dev = runtime->private_data;
++ int ret = 0;
++
++ switch (cmd) {
++ case SNDRV_PCM_TRIGGER_START:
++ case SNDRV_PCM_TRIGGER_RESUME:
++ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
++ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
++ WRITE_ONCE(dev->tx_ptr, 0);
++ rcu_assign_pointer(dev->tx_substream, substream);
++ } else {
++ WRITE_ONCE(dev->rx_ptr, 0);
++ rcu_assign_pointer(dev->rx_substream, substream);
++ }
++ break;
++ case SNDRV_PCM_TRIGGER_STOP:
++ case SNDRV_PCM_TRIGGER_SUSPEND:
++ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
++ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
++ rcu_assign_pointer(dev->tx_substream, NULL);
++ else
++ rcu_assign_pointer(dev->rx_substream, NULL);
++ break;
++ default:
++ ret = -EINVAL;
++ break;
++ }
++
++ return ret;
++}
++
++static snd_pcm_uframes_t sf_pcm_pointer(struct snd_soc_component *component,
++ struct snd_pcm_substream *substream)
++{
++ struct snd_pcm_runtime *runtime = substream->runtime;
++ struct sf_spdif_dev *dev = runtime->private_data;
++ snd_pcm_uframes_t pos;
++
++ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
++ pos = READ_ONCE(dev->tx_ptr);
++ else
++ pos = READ_ONCE(dev->rx_ptr);
++
++ return pos < runtime->buffer_size ? pos : 0;
++}
++
++static int sf_pcm_new(struct snd_soc_component *component,
++ struct snd_soc_pcm_runtime *rtd)
++{
++ size_t size = sf_pcm_hardware.buffer_bytes_max;
++
++ snd_pcm_set_managed_buffer_all(rtd->pcm,
++ SNDRV_DMA_TYPE_CONTINUOUS,
++ NULL, size, size);
++
++ return 0;
++}
++
++static const struct snd_soc_component_driver sf_pcm_component = {
++ .open = sf_pcm_open,
++ .close = sf_pcm_close,
++ .hw_params = sf_pcm_hw_params,
++ .trigger = sf_pcm_trigger,
++ .pointer = sf_pcm_pointer,
++ .pcm_construct = sf_pcm_new,
++};
++
++int sf_spdif_pcm_register(struct platform_device *pdev)
++{
++ return devm_snd_soc_register_component(&pdev->dev, &sf_pcm_component,
++ NULL, 0);
++}
diff --git a/target/linux/starfive/patches-6.6/0081-ASoC-starfive-Add-JH7110-PDM-driver.patch b/target/linux/starfive/patches-6.6/0081-ASoC-starfive-Add-JH7110-PDM-driver.patch
new file mode 100644
index 0000000000..006760d754
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0081-ASoC-starfive-Add-JH7110-PDM-driver.patch
@@ -0,0 +1,537 @@
+From 9c4858f9fe4d8f8fe5cf347b3ca727016b7ba492 Mon Sep 17 00:00:00 2001
+From: Walker Chen <walker.chen@starfivetech.com>
+Date: Tue, 20 Jun 2023 15:57:53 +0800
+Subject: [PATCH 081/116] ASoC: starfive: Add JH7110 PDM driver
+
+Add pdm driver support for the StarFive JH7110 SoC.
+
+Signed-off-by: Walker Chen <walker.chen@starfivetech.com>
+---
+ sound/soc/starfive/Kconfig | 8 +
+ sound/soc/starfive/Makefile | 2 +
+ sound/soc/starfive/jh7110_pdm.c | 493 ++++++++++++++++++++++++++++++++
+ 3 files changed, 503 insertions(+)
+ create mode 100644 sound/soc/starfive/jh7110_pdm.c
+
+--- a/sound/soc/starfive/Kconfig
++++ b/sound/soc/starfive/Kconfig
+@@ -7,6 +7,14 @@ config SND_SOC_STARFIVE
+ the Starfive SoCs' Audio interfaces. You will also need to
+ select the audio interfaces to support below.
+
++config SND_SOC_JH7110_PDM
++ tristate "JH7110 PDM device driver"
++ depends on HAVE_CLK && SND_SOC_STARFIVE
++ select SND_SOC_JH7110_I2S
++ select REGMAP_MMIO
++ help
++ Say Y or M if you want to add support for StarFive pdm driver.
++
+ config SND_SOC_JH7110_PWMDAC
+ tristate "JH7110 PWM-DAC device driver"
+ depends on HAVE_CLK && SND_SOC_STARFIVE
+--- a/sound/soc/starfive/Makefile
++++ b/sound/soc/starfive/Makefile
+@@ -1,4 +1,6 @@
+ # StarFive Platform Support
++obj-$(CONFIG_SND_SOC_JH7110_PDM) += jh7110_pdm.o
++
+ obj-$(CONFIG_SND_SOC_JH7110_PWMDAC) += jh7110_pwmdac.o
+
+ obj-$(CONFIG_SND_SOC_JH7110_SPDIF) += spdif.o
+--- /dev/null
++++ b/sound/soc/starfive/jh7110_pdm.c
+@@ -0,0 +1,493 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * PDM driver for the StarFive JH7110 SoC
++ *
++ * Copyright (C) 2022 StarFive Technology Co., Ltd.
++ */
++#include <linux/clk.h>
++#include <linux/device.h>
++#include <linux/dmaengine.h>
++#include <linux/reset.h>
++#include <linux/module.h>
++#include <linux/of_irq.h>
++#include <linux/of_platform.h>
++#include <linux/regmap.h>
++#include <linux/pm_runtime.h>
++#include <linux/types.h>
++#include <sound/dmaengine_pcm.h>
++#include <sound/initval.h>
++#include <sound/pcm.h>
++#include <sound/pcm_params.h>
++#include <sound/soc.h>
++#include <sound/soc-dai.h>
++#include <sound/tlv.h>
++
++#define PDM_DMIC_CTRL0 0x00
++#define PDM_DC_SCALE0 0x04
++#define PDM_DMIC_CTRL1 0x10
++#define PDM_DC_SCALE1 0x14
++
++/* PDM CTRL OFFSET */
++#define PDM_DMIC_MSB_SHIFT 1
++#define PDM_DMIC_MSB_MASK (0x7 << PDM_DMIC_MSB_SHIFT)
++#define PDM_DMIC_VOL_SHIFT 16
++#define PDM_DMIC_VOL_MASK (0x3f << PDM_DMIC_VOL_SHIFT)
++#define PDM_VOL_DB_MUTE (0x3f << PDM_DMIC_VOL_SHIFT)
++#define PDM_VOL_DB_MAX 0
++
++#define PDM_DMIC_RVOL_MASK BIT(22)
++#define PDM_DMIC_LVOL_MASK BIT(23)
++#define PDM_DMIC_I2S_SLAVE BIT(24)
++#define PDM_DMIC_HPF_EN BIT(28)
++#define PDM_DMIC_FASTMODE_MASK BIT(29)
++#define PDM_DMIC_DC_BYPASS_MASK BIT(30)
++#define PDM_SW_RST_MASK BIT(31)
++#define PDM_SW_RST_RELEASE BIT(31)
++
++/* PDM SCALE OFFSET */
++#define DMIC_DCOFF3_SHIFT 24
++#define DMIC_DCOFF2_SHIFT 16
++#define DMIC_DCOFF1_SHIFT 8
++
++#define DMIC_DCOFF3_MASK (0xf << DMIC_DCOFF3_SHIFT)
++#define DMIC_DCOFF3_VAL (0xc << DMIC_DCOFF3_SHIFT)
++#define DMIC_DCOFF1_MASK (0xff << DMIC_DCOFF1_SHIFT)
++#define DMIC_DCOFF1_VAL (0x5 << DMIC_DCOFF1_SHIFT)
++#define DMIC_SCALE_MASK 0x3f
++#define DMIC_SCALE_DEF_VAL 0x8
++
++enum PDM_MSB_SHIFT {
++ PDM_MSB_SHIFT_NONE = 0,
++ PDM_MSB_SHIFT_1,
++ PDM_MSB_SHIFT_2,
++ PDM_MSB_SHIFT_3,
++ PDM_MSB_SHIFT_4,
++ PDM_MSB_SHIFT_5,
++ PDM_MSB_SHIFT_6,
++ PDM_MSB_SHIFT_7,
++};
++
++struct sf_pdm {
++ struct regmap *pdm_map;
++ struct device *dev;
++ struct clk *clk_pdm_apb;
++ struct clk *clk_pdm_mclk;
++ struct clk *clk_mclk;
++ struct clk *clk_mclk_ext;
++ struct reset_control *rst_pdm_dmic;
++ struct reset_control *rst_pdm_apb;
++ unsigned char flag_first;
++ unsigned int saved_ctrl0;
++ unsigned int saved_scale0;
++};
++
++static const DECLARE_TLV_DB_SCALE(volume_tlv, -9450, 150, 0);
++
++static const struct snd_kcontrol_new sf_pdm_snd_controls[] = {
++ SOC_SINGLE("DC compensation Control", PDM_DMIC_CTRL0, 30, 1, 0),
++ SOC_SINGLE("High Pass Filter Control", PDM_DMIC_CTRL0, 28, 1, 0),
++ SOC_SINGLE("Left Channel Volume Control", PDM_DMIC_CTRL0, 23, 1, 0),
++ SOC_SINGLE("Right Channel Volume Control", PDM_DMIC_CTRL0, 22, 1, 0),
++ SOC_SINGLE_TLV("Volume", PDM_DMIC_CTRL0, 16, 0x3F, 1, volume_tlv),
++ SOC_SINGLE("Data MSB Shift", PDM_DMIC_CTRL0, 1, 7, 0),
++ SOC_SINGLE("SCALE", PDM_DC_SCALE0, 0, 0x3F, 0),
++ SOC_SINGLE("DC offset", PDM_DC_SCALE0, 8, 0xFFFFF, 0),
++};
++
++static void sf_pdm_enable(struct regmap *map)
++{
++ /* Left and Right Channel Volume Control Enable */
++ regmap_update_bits(map, PDM_DMIC_CTRL0, PDM_DMIC_RVOL_MASK, 0);
++ regmap_update_bits(map, PDM_DMIC_CTRL0, PDM_DMIC_LVOL_MASK, 0);
++}
++
++static void sf_pdm_disable(struct regmap *map)
++{
++ /* Left and Right Channel Volume Control Disable */
++ regmap_update_bits(map, PDM_DMIC_CTRL0,
++ PDM_DMIC_RVOL_MASK, PDM_DMIC_RVOL_MASK);
++ regmap_update_bits(map, PDM_DMIC_CTRL0,
++ PDM_DMIC_LVOL_MASK, PDM_DMIC_LVOL_MASK);
++}
++
++static int sf_pdm_trigger(struct snd_pcm_substream *substream, int cmd,
++ struct snd_soc_dai *dai)
++{
++ struct sf_pdm *priv = snd_soc_dai_get_drvdata(dai);
++
++ switch (cmd) {
++ case SNDRV_PCM_TRIGGER_START:
++ case SNDRV_PCM_TRIGGER_RESUME:
++ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
++ if (priv->flag_first) {
++ priv->flag_first = 0;
++ mdelay(200);
++ }
++
++ sf_pdm_enable(priv->pdm_map);
++ return 0;
++
++ case SNDRV_PCM_TRIGGER_STOP:
++ case SNDRV_PCM_TRIGGER_SUSPEND:
++ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
++ sf_pdm_disable(priv->pdm_map);
++ return 0;
++
++ default:
++ return -EINVAL;
++ }
++}
++
++static int sf_pdm_hw_params(struct snd_pcm_substream *substream,
++ struct snd_pcm_hw_params *params,
++ struct snd_soc_dai *dai)
++{
++ struct sf_pdm *priv = snd_soc_dai_get_drvdata(dai);
++ unsigned int sample_rate;
++ unsigned int data_width;
++ int ret;
++ const int pdm_mul = 128;
++
++ sample_rate = params_rate(params);
++ switch (sample_rate) {
++ case 8000:
++ case 11025:
++ case 16000:
++ break;
++ default:
++ dev_err(priv->dev, "can't support sample rate:%d\n", sample_rate);
++ return -EINVAL;
++ }
++
++ data_width = params_width(params);
++ switch (data_width) {
++ case 16:
++ case 32:
++ break;
++ default:
++ dev_err(priv->dev, "can't support bit width %d\n", data_width);
++ return -EINVAL;
++ }
++
++ /* set pdm_mclk, PDM MCLK = 128 * LRCLK */
++ ret = clk_set_rate(priv->clk_pdm_mclk, pdm_mul * sample_rate);
++ if (ret) {
++ dev_err(priv->dev, "Can't set pdm_mclk: %d\n", ret);
++ return ret;
++ }
++
++ return 0;
++}
++
++static const struct snd_soc_dai_ops sf_pdm_dai_ops = {
++ .trigger = sf_pdm_trigger,
++ .hw_params = sf_pdm_hw_params,
++};
++
++static void sf_pdm_module_init(struct sf_pdm *priv)
++{
++ /* Reset */
++ regmap_update_bits(priv->pdm_map, PDM_DMIC_CTRL0,
++ PDM_SW_RST_MASK, 0x00);
++ regmap_update_bits(priv->pdm_map, PDM_DMIC_CTRL0,
++ PDM_SW_RST_MASK, PDM_SW_RST_RELEASE);
++
++ /* Make sure the device is initially disabled */
++ sf_pdm_disable(priv->pdm_map);
++
++ /* MUTE */
++ regmap_update_bits(priv->pdm_map, PDM_DMIC_CTRL0,
++ PDM_DMIC_VOL_MASK, PDM_VOL_DB_MUTE);
++
++ /* UNMUTE */
++ regmap_update_bits(priv->pdm_map, PDM_DMIC_CTRL0,
++ PDM_DMIC_VOL_MASK, PDM_VOL_DB_MAX);
++
++ /* enable high pass filter */
++ regmap_update_bits(priv->pdm_map, PDM_DMIC_CTRL0,
++ PDM_DMIC_HPF_EN, PDM_DMIC_HPF_EN);
++
++ /* PDM work as slave mode */
++ regmap_update_bits(priv->pdm_map, PDM_DMIC_CTRL0,
++ PDM_DMIC_I2S_SLAVE, PDM_DMIC_I2S_SLAVE);
++
++ /* disable fast mode */
++ regmap_update_bits(priv->pdm_map, PDM_DMIC_CTRL0,
++ PDM_DMIC_FASTMODE_MASK, 0);
++
++ /* dmic msb shift 0 */
++ regmap_update_bits(priv->pdm_map, PDM_DMIC_CTRL0,
++ PDM_DMIC_MSB_MASK, 0);
++
++ /* scale: 0x8 */
++ regmap_update_bits(priv->pdm_map, PDM_DC_SCALE0,
++ DMIC_SCALE_MASK, DMIC_SCALE_DEF_VAL);
++
++ regmap_update_bits(priv->pdm_map, PDM_DC_SCALE0,
++ DMIC_DCOFF1_MASK, DMIC_DCOFF1_VAL);
++
++ regmap_update_bits(priv->pdm_map, PDM_DC_SCALE0,
++ DMIC_DCOFF3_MASK, DMIC_DCOFF3_VAL);
++
++ /* scale: 0x3f */
++ regmap_update_bits(priv->pdm_map, PDM_DC_SCALE0,
++ DMIC_SCALE_MASK, DMIC_SCALE_MASK);
++
++ /* dmic msb shift 2 */
++ regmap_update_bits(priv->pdm_map, PDM_DMIC_CTRL0,
++ PDM_DMIC_MSB_MASK, PDM_MSB_SHIFT_4);
++}
++
++#define SF_PDM_RATES (SNDRV_PCM_RATE_8000 | \
++ SNDRV_PCM_RATE_11025 | \
++ SNDRV_PCM_RATE_16000)
++
++#define SF_PDM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
++ SNDRV_PCM_FMTBIT_S32_LE)
++
++static struct snd_soc_dai_driver sf_pdm_dai_drv = {
++ .name = "PDM",
++ .id = 0,
++ .capture = {
++ .stream_name = "Capture",
++ .channels_min = 2,
++ .channels_max = 2,
++ .rates = SF_PDM_RATES,
++ .formats = SF_PDM_FORMATS,
++ },
++ .ops = &sf_pdm_dai_ops,
++ .symmetric_rate = 1,
++};
++
++static int sf_pdm_component_probe(struct snd_soc_component *component)
++{
++ struct sf_pdm *priv = snd_soc_component_get_drvdata(component);
++
++ snd_soc_component_init_regmap(component, priv->pdm_map);
++ snd_soc_add_component_controls(component, sf_pdm_snd_controls,
++ ARRAY_SIZE(sf_pdm_snd_controls));
++
++ return 0;
++}
++
++static int sf_pdm_clock_enable(struct sf_pdm *priv)
++{
++ int ret;
++
++ ret = clk_prepare_enable(priv->clk_pdm_mclk);
++ if (ret) {
++ dev_err(priv->dev, "failed to prepare enable clk_pdm_mclk\n");
++ return ret;
++ }
++
++ ret = clk_prepare_enable(priv->clk_pdm_apb);
++ if (ret) {
++ dev_err(priv->dev, "failed to prepare enable clk_pdm_apb\n");
++ goto disable_pdm_mclk;
++ }
++
++ ret = reset_control_deassert(priv->rst_pdm_dmic);
++ if (ret) {
++ dev_err(priv->dev, "failed to deassert pdm_dmic\n");
++ goto disable_pdm_apb;
++ }
++
++ ret = reset_control_deassert(priv->rst_pdm_apb);
++ if (ret) {
++ dev_err(priv->dev, "failed to deassert pdm_apb\n");
++ goto disable_pdm_apb;
++ }
++
++ ret = clk_set_parent(priv->clk_mclk, priv->clk_mclk_ext);
++ if (ret) {
++ dev_err(priv->dev, "failed to set parent clk_mclk ret=%d\n", ret);
++ goto disable_pdm_apb;
++ }
++
++ return 0;
++
++disable_pdm_apb:
++ clk_disable_unprepare(priv->clk_pdm_apb);
++disable_pdm_mclk:
++ clk_disable_unprepare(priv->clk_pdm_mclk);
++
++ return ret;
++}
++
++#ifdef CONFIG_PM
++static int sf_pdm_runtime_suspend(struct device *dev)
++{
++ struct sf_pdm *priv = dev_get_drvdata(dev);
++
++ clk_disable_unprepare(priv->clk_pdm_apb);
++ clk_disable_unprepare(priv->clk_pdm_mclk);
++
++ return 0;
++}
++
++static int sf_pdm_runtime_resume(struct device *dev)
++{
++ struct sf_pdm *priv = dev_get_drvdata(dev);
++ int ret;
++
++ ret = sf_pdm_clock_enable(priv);
++ if (!ret)
++ sf_pdm_module_init(priv);
++
++ return ret;
++}
++#endif
++
++#ifdef CONFIG_PM_SLEEP
++static int sf_pdm_suspend(struct snd_soc_component *component)
++{
++ return pm_runtime_force_suspend(component->dev);
++}
++
++static int sf_pdm_resume(struct snd_soc_component *component)
++{
++ return pm_runtime_force_resume(component->dev);
++}
++
++#else
++#define sf_pdm_suspend NULL
++#define sf_pdm_resume NULL
++#endif
++
++static const struct snd_soc_component_driver sf_pdm_component_drv = {
++ .name = "jh7110-pdm",
++ .probe = sf_pdm_component_probe,
++ .suspend = sf_pdm_suspend,
++ .resume = sf_pdm_resume,
++};
++
++static const struct regmap_config sf_pdm_regmap_cfg = {
++ .reg_bits = 32,
++ .val_bits = 32,
++ .reg_stride = 4,
++ .max_register = 0x20,
++};
++
++static int sf_pdm_clock_get(struct platform_device *pdev, struct sf_pdm *priv)
++{
++ int ret;
++
++ static struct clk_bulk_data clks[] = {
++ { .id = "pdm_mclk" },
++ { .id = "pdm_apb" },
++ { .id = "clk_mclk" },
++ { .id = "mclk_ext" },
++ };
++
++ ret = devm_clk_bulk_get(&pdev->dev, ARRAY_SIZE(clks), clks);
++ if (ret) {
++ dev_err(&pdev->dev, "failed to get pdm clocks\n");
++ goto exit;
++ }
++
++ priv->clk_pdm_mclk = clks[0].clk;
++ priv->clk_pdm_apb = clks[1].clk;
++ priv->clk_mclk = clks[2].clk;
++ priv->clk_mclk_ext = clks[3].clk;
++
++ priv->rst_pdm_dmic = devm_reset_control_get_exclusive(&pdev->dev, "pdm_dmic");
++ if (IS_ERR(priv->rst_pdm_dmic)) {
++ dev_err(&pdev->dev, "failed to get pdm_dmic reset control\n");
++ ret = PTR_ERR(priv->rst_pdm_dmic);
++ goto exit;
++ }
++
++ priv->rst_pdm_apb = devm_reset_control_get_exclusive(&pdev->dev, "pdm_apb");
++ if (IS_ERR(priv->rst_pdm_apb)) {
++ dev_err(&pdev->dev, "failed to get pdm_apb reset control\n");
++ ret = PTR_ERR(priv->rst_pdm_apb);
++ goto exit;
++ }
++
++ /*
++ * pdm clock must always be enabled as hardware issue that
++ * no data in the first 4 seconds of the first recording
++ */
++ ret = sf_pdm_clock_enable(priv);
++
++exit:
++ return ret;
++}
++
++static int sf_pdm_probe(struct platform_device *pdev)
++{
++ struct sf_pdm *priv;
++ struct resource *res;
++ void __iomem *regs;
++ int ret;
++
++ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
++ if (!priv)
++ return -ENOMEM;
++ platform_set_drvdata(pdev, priv);
++
++ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pdm");
++ regs = devm_ioremap_resource(&pdev->dev, res);
++ if (IS_ERR(regs))
++ return PTR_ERR(regs);
++
++ priv->pdm_map = devm_regmap_init_mmio(&pdev->dev, regs, &sf_pdm_regmap_cfg);
++ if (IS_ERR(priv->pdm_map)) {
++ dev_err(&pdev->dev, "failed to init regmap: %ld\n",
++ PTR_ERR(priv->pdm_map));
++ return PTR_ERR(priv->pdm_map);
++ }
++
++ priv->dev = &pdev->dev;
++ priv->flag_first = 1;
++
++ ret = sf_pdm_clock_get(pdev, priv);
++ if (ret) {
++ dev_err(&pdev->dev, "failed to enable audio-pdm clock\n");
++ return ret;
++ }
++
++ dev_set_drvdata(&pdev->dev, priv);
++
++ ret = devm_snd_soc_register_component(&pdev->dev, &sf_pdm_component_drv,
++ &sf_pdm_dai_drv, 1);
++ if (ret) {
++ dev_err(&pdev->dev, "failed to register pdm dai\n");
++ return ret;
++ }
++ pm_runtime_enable(&pdev->dev);
++
++ return 0;
++}
++
++static int sf_pdm_dev_remove(struct platform_device *pdev)
++{
++ pm_runtime_disable(&pdev->dev);
++ return 0;
++}
++
++static const struct of_device_id sf_pdm_of_match[] = {
++ {.compatible = "starfive,jh7110-pdm",},
++ {}
++};
++MODULE_DEVICE_TABLE(of, sf_pdm_of_match);
++
++static const struct dev_pm_ops sf_pdm_pm_ops = {
++ SET_RUNTIME_PM_OPS(sf_pdm_runtime_suspend,
++ sf_pdm_runtime_resume, NULL)
++};
++
++static struct platform_driver sf_pdm_driver = {
++ .driver = {
++ .name = "jh7110-pdm",
++ .of_match_table = sf_pdm_of_match,
++ .pm = &sf_pdm_pm_ops,
++ },
++ .probe = sf_pdm_probe,
++ .remove = sf_pdm_dev_remove,
++};
++module_platform_driver(sf_pdm_driver);
++
++MODULE_AUTHOR("Walker Chen <walker.chen@starfivetech.com>");
++MODULE_DESCRIPTION("Starfive PDM Controller Driver");
++MODULE_LICENSE("GPL v2");
diff --git a/target/linux/starfive/patches-6.6/0082-dt-binding-input-Add-tink_ft5406.patch b/target/linux/starfive/patches-6.6/0082-dt-binding-input-Add-tink_ft5406.patch
new file mode 100644
index 0000000000..ed8a3af308
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0082-dt-binding-input-Add-tink_ft5406.patch
@@ -0,0 +1,55 @@
+From 59cbdfeee0fc1ad382a0bc8f7fa897a9f5d03df0 Mon Sep 17 00:00:00 2001
+From: Changhuang Liang <changhuang.liang@starfivetech.com>
+Date: Fri, 9 Jun 2023 16:54:36 +0800
+Subject: [PATCH 082/116] dt-binding: input: Add tink_ft5406
+
+Add tink_ft5406.
+
+Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
+---
+ .../bindings/input/tinker_ft5406.yaml | 39 +++++++++++++++++++
+ 1 file changed, 39 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/input/tinker_ft5406.yaml
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/input/tinker_ft5406.yaml
+@@ -0,0 +1,39 @@
++# SPDX-License-Identifier: GPL-2.0
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/input/touchscreen/goodix.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: Tinker FT5406 touchscreen controller Bindings
++
++maintainers:
++ - Changhuang Liang <changhuang.liang@starfivetech.com>
++
++allOf:
++ - $ref: touchscreen.yaml#
++
++properties:
++ compatible:
++ const: tinker_ft5406
++
++ reg:
++ const: 0x38
++
++additionalProperties: false
++
++required:
++ - compatible
++ - reg
++
++examples:
++ - |
++ i2c {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ tinker_ft5406@38 {
++ compatible = "tinker_ft5406";
++ reg = <0x38>;
++ };
++ };
++
++...
diff --git a/target/linux/starfive/patches-6.6/0083-input-touchscreen-Add-tinker_ft5406-driver-support.patch b/target/linux/starfive/patches-6.6/0083-input-touchscreen-Add-tinker_ft5406-driver-support.patch
new file mode 100644
index 0000000000..f45085f495
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0083-input-touchscreen-Add-tinker_ft5406-driver-support.patch
@@ -0,0 +1,444 @@
+From 4800b6e0f2190d991cd4e5352167a9422841f195 Mon Sep 17 00:00:00 2001
+From: Changhuang Liang <changhuang.liang@starfivetech.com>
+Date: Wed, 21 Dec 2022 16:20:04 +0800
+Subject: [PATCH 083/116] input: touchscreen: Add tinker_ft5406 driver support
+
+Add tinker_ft5406 driver support
+
+Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
+---
+ drivers/input/touchscreen/Kconfig | 6 +
+ drivers/input/touchscreen/Makefile | 1 +
+ drivers/input/touchscreen/tinker_ft5406.c | 406 ++++++++++++++++++++++
+ 3 files changed, 413 insertions(+)
+ create mode 100644 drivers/input/touchscreen/tinker_ft5406.c
+
+--- a/drivers/input/touchscreen/Kconfig
++++ b/drivers/input/touchscreen/Kconfig
+@@ -1399,4 +1399,10 @@ config TOUCHSCREEN_HIMAX_HX83112B
+ To compile this driver as a module, choose M here: the
+ module will be called himax_hx83112b.
+
++config TOUCHSCREEN_TINKER_FT5406
++ tristate "tinker ft5406"
++ depends on I2C
++ help
++ Control ft5406 touch ic.
++
+ endif
+--- a/drivers/input/touchscreen/Makefile
++++ b/drivers/input/touchscreen/Makefile
+@@ -118,3 +118,4 @@ obj-$(CONFIG_TOUCHSCREEN_IQS5XX) += iqs5
+ obj-$(CONFIG_TOUCHSCREEN_IQS7211) += iqs7211.o
+ obj-$(CONFIG_TOUCHSCREEN_ZINITIX) += zinitix.o
+ obj-$(CONFIG_TOUCHSCREEN_HIMAX_HX83112B) += himax_hx83112b.o
++obj-$(CONFIG_TOUCHSCREEN_TINKER_FT5406) += tinker_ft5406.o
+--- /dev/null
++++ b/drivers/input/touchscreen/tinker_ft5406.c
+@@ -0,0 +1,406 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ *
++ * TINKER BOARD FT5406 touch driver.
++ *
++ * Copyright (c) 2016 ASUSTek Computer Inc.
++ * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
++ *
++ * This software is licensed under the terms of the GNU General Public
++ * License version 2, as published by the Free Software Foundation, and
++ * may be copied, distributed, and modified under those terms.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ */
++
++#include <linux/module.h>
++#include <linux/slab.h>
++#include <linux/delay.h>
++#include <linux/i2c.h>
++#include <linux/input.h>
++#include <linux/input/mt.h>
++#include <linux/module.h>
++#include <linux/workqueue.h>
++
++#define RETRY_COUNT 10
++#define FT_ONE_TCH_LEN 6
++
++#define FT_REG_FW_VER 0xA6
++#define FT_REG_FW_MIN_VER 0xB2
++#define FT_REG_FW_SUB_MIN_VER 0xB3
++
++#define VALID_TD_STATUS_VAL 10
++#define MAX_TOUCH_POINTS 5
++
++#define FT_PRESS 0x7F
++#define FT_MAX_ID 0x0F
++
++#define FT_TOUCH_X_H 0
++#define FT_TOUCH_X_L 1
++#define FT_TOUCH_Y_H 2
++#define FT_TOUCH_Y_L 3
++#define FT_TOUCH_EVENT 0
++#define FT_TOUCH_ID 2
++
++#define FT_TOUCH_X_H_REG 3
++#define FT_TOUCH_X_L_REG 4
++#define FT_TOUCH_Y_H_REG 5
++#define FT_TOUCH_Y_L_REG 6
++#define FT_TD_STATUS_REG 2
++#define FT_TOUCH_EVENT_REG 3
++#define FT_TOUCH_ID_REG 5
++
++#define FT_TOUCH_DOWN 0
++#define FT_TOUCH_CONTACT 2
++
++struct ts_event {
++ u16 au16_x[MAX_TOUCH_POINTS]; /*x coordinate */
++ u16 au16_y[MAX_TOUCH_POINTS]; /*y coordinate */
++ u8 au8_touch_event[MAX_TOUCH_POINTS]; /*touch event: 0:down; 1:up; 2:contact */
++ u8 au8_finger_id[MAX_TOUCH_POINTS]; /*touch ID */
++ u16 pressure;
++ u8 touch_point;
++ u8 point_num;
++};
++
++struct tinker_ft5406_data {
++ struct device *dev;
++ struct i2c_client *client;
++ struct input_dev *input_dev;
++ struct ts_event event;
++ struct work_struct ft5406_work;
++
++ int screen_width;
++ int screen_height;
++ int xy_reverse;
++ int known_ids;
++ int retry_count;
++ bool finish_work;
++};
++
++struct tinker_ft5406_data *g_ts_data;
++
++static int fts_i2c_read(struct i2c_client *client, char *writebuf,
++ int writelen, char *readbuf, int readlen)
++{
++ int ret;
++
++ if (writelen > 0) {
++ struct i2c_msg msgs[] = {
++ {
++ .addr = client->addr,
++ .flags = 0,
++ .len = writelen,
++ .buf = writebuf,
++ },
++ {
++ .addr = client->addr,
++ .flags = I2C_M_RD,
++ .len = readlen,
++ .buf = readbuf,
++ },
++ };
++ ret = i2c_transfer(client->adapter, msgs, 2);
++ if (ret < 0)
++ dev_err(&client->dev, "i2c read error, %d\n", ret);
++ } else {
++ struct i2c_msg msgs[] = {
++ {
++ .addr = client->addr,
++ .flags = I2C_M_RD,
++ .len = readlen,
++ .buf = readbuf,
++ },
++ };
++ ret = i2c_transfer(client->adapter, msgs, 1);
++ if (ret < 0)
++ dev_err(&client->dev, "i2c read error, %d\n", ret);
++ }
++
++ return ret;
++}
++
++static int fts_read_reg(struct i2c_client *client, u8 addr, u8 *val)
++{
++ return fts_i2c_read(client, &addr, 1, val, 1);
++}
++
++static int fts_check_fw_ver(struct i2c_client *client)
++{
++ u8 reg_addr, fw_ver[3];
++ int ret;
++
++ reg_addr = FT_REG_FW_VER;
++ ret = fts_i2c_read(client, &reg_addr, 1, &fw_ver[0], 1);
++ if (ret < 0)
++ goto error;
++
++ reg_addr = FT_REG_FW_MIN_VER;
++ ret = fts_i2c_read(client, &reg_addr, 1, &fw_ver[1], 1);
++ if (ret < 0)
++ goto error;
++
++ reg_addr = FT_REG_FW_SUB_MIN_VER;
++ ret = fts_i2c_read(client, &reg_addr, 1, &fw_ver[2], 1);
++ if (ret < 0)
++ goto error;
++
++ dev_info(&client->dev, "Firmware version = %d.%d.%d\n",
++ fw_ver[0], fw_ver[1], fw_ver[2]);
++ return 0;
++
++error:
++ return ret;
++}
++
++static int fts_read_td_status(struct tinker_ft5406_data *ts_data)
++{
++ u8 td_status;
++ int ret = -1;
++
++ ret = fts_read_reg(ts_data->client, FT_TD_STATUS_REG, &td_status);
++ if (ret < 0) {
++ dev_err(&ts_data->client->dev,
++ "Get reg td_status failed, %d\n", ret);
++ return ret;
++ }
++ return (int)td_status;
++}
++
++static int fts_read_touchdata(struct tinker_ft5406_data *ts_data)
++{
++ struct ts_event *event = &ts_data->event;
++ int ret = -1, i;
++ u8 buf[FT_ONE_TCH_LEN-2] = { 0 };
++ u8 reg_addr, pointid = FT_MAX_ID;
++
++ for (i = 0; i < event->touch_point && i < MAX_TOUCH_POINTS; i++) {
++ reg_addr = FT_TOUCH_X_H_REG + (i * FT_ONE_TCH_LEN);
++ ret = fts_i2c_read(ts_data->client, &reg_addr, 1, buf, FT_ONE_TCH_LEN-2);
++ if (ret < 0) {
++ dev_err(&ts_data->client->dev, "Read touchdata failed.\n");
++ return ret;
++ }
++
++ pointid = (buf[FT_TOUCH_ID]) >> 4;
++ if (pointid >= MAX_TOUCH_POINTS)
++ break;
++ event->au8_finger_id[i] = pointid;
++ event->au16_x[i] = (s16) (buf[FT_TOUCH_X_H] & 0x0F) << 8 | (s16) buf[FT_TOUCH_X_L];
++ event->au16_y[i] = (s16) (buf[FT_TOUCH_Y_H] & 0x0F) << 8 | (s16) buf[FT_TOUCH_Y_L];
++ event->au8_touch_event[i] = buf[FT_TOUCH_EVENT] >> 6;
++
++ if (ts_data->xy_reverse) {
++ event->au16_x[i] = ts_data->screen_width - event->au16_x[i] - 1;
++ event->au16_y[i] = ts_data->screen_height - event->au16_y[i] - 1;
++ }
++ }
++ event->pressure = FT_PRESS;
++
++ return 0;
++}
++
++static void fts_report_value(struct tinker_ft5406_data *ts_data)
++{
++ struct ts_event *event = &ts_data->event;
++ int i, modified_ids = 0, released_ids;
++
++ for (i = 0; i < event->touch_point && i < MAX_TOUCH_POINTS; i++) {
++ if (event->au8_touch_event[i] == FT_TOUCH_DOWN ||
++ event->au8_touch_event[i] == FT_TOUCH_CONTACT) {
++ modified_ids |= 1 << event->au8_finger_id[i];
++ input_mt_slot(ts_data->input_dev, event->au8_finger_id[i]);
++ input_mt_report_slot_state(ts_data->input_dev, MT_TOOL_FINGER,
++ true);
++ input_report_abs(ts_data->input_dev, ABS_MT_TOUCH_MAJOR,
++ event->pressure);
++ input_report_abs(ts_data->input_dev, ABS_MT_POSITION_X,
++ event->au16_x[i]);
++ input_report_abs(ts_data->input_dev, ABS_MT_POSITION_Y,
++ event->au16_y[i]);
++
++ if (!((1 << event->au8_finger_id[i]) & ts_data->known_ids))
++ dev_dbg(&ts_data->client->dev, "Touch id-%d: x = %d, y = %d\n",
++ event->au8_finger_id[i],
++ event->au16_x[i],
++ event->au16_y[i]);
++ }
++ }
++
++ released_ids = ts_data->known_ids & ~modified_ids;
++ for (i = 0; released_ids && i < MAX_TOUCH_POINTS; i++) {
++ if (released_ids & (1<<i)) {
++ dev_dbg(&ts_data->client->dev, "Release id-%d, known = %x modified = %x\n",
++ i, ts_data->known_ids, modified_ids);
++ input_mt_slot(ts_data->input_dev, i);
++ input_mt_report_slot_state(ts_data->input_dev, MT_TOOL_FINGER, false);
++ modified_ids &= ~(1 << i);
++ }
++ }
++ ts_data->known_ids = modified_ids;
++ input_mt_report_pointer_emulation(ts_data->input_dev, true);
++ input_sync(ts_data->input_dev);
++}
++
++static void fts_retry_clear(struct tinker_ft5406_data *ts_data)
++{
++ if (ts_data->retry_count != 0)
++ ts_data->retry_count = 0;
++}
++
++static int fts_retry_wait(struct tinker_ft5406_data *ts_data)
++{
++ if (ts_data->retry_count < RETRY_COUNT) {
++ dev_info(&ts_data->client->dev,
++ "Wait and retry, count = %d\n", ts_data->retry_count);
++ ts_data->retry_count++;
++ msleep(1000);
++ return 1;
++ }
++ dev_err(&ts_data->client->dev, "Attach retry count\n");
++ return 0;
++}
++
++static void tinker_ft5406_work(struct work_struct *work)
++{
++ struct ts_event *event = &g_ts_data->event;
++ int ret = 0, td_status;
++
++ /* polling 60fps */
++ while (!g_ts_data->finish_work) {
++ td_status = fts_read_td_status(g_ts_data);
++ if (td_status < 0) {
++ ret = fts_retry_wait(g_ts_data);
++ if (ret == 0) {
++ dev_err(&g_ts_data->client->dev, "Stop touch polling\n");
++ break;
++ }
++ } else if (td_status < VALID_TD_STATUS_VAL + 1 &&
++ (td_status > 0 || g_ts_data->known_ids != 0)) {
++ fts_retry_clear(g_ts_data);
++ memset(event, -1, sizeof(struct ts_event));
++ event->touch_point = td_status;
++ ret = fts_read_touchdata(g_ts_data);
++ if (ret == 0)
++ fts_report_value(g_ts_data);
++ }
++ msleep_interruptible(17);
++ }
++}
++
++static int tinker_ft5406_open(struct input_dev *dev)
++{
++ schedule_work(&g_ts_data->ft5406_work);
++ return 0;
++}
++
++static void tinker_ft5406_close(struct input_dev *dev)
++{
++ g_ts_data->finish_work = true;
++ cancel_work_sync(&g_ts_data->ft5406_work);
++ g_ts_data->finish_work = false;
++}
++
++static int tinker_ft5406_probe(struct i2c_client *client)
++{
++ struct input_dev *input_dev;
++ int ret = 0;
++
++ dev_info(&client->dev, "Address = 0x%x\n", client->addr);
++
++ g_ts_data = kzalloc(sizeof(struct tinker_ft5406_data), GFP_KERNEL);
++ if (g_ts_data == NULL) {
++ dev_err(&client->dev, "No memory for device\n");
++ return -ENOMEM;
++ }
++
++ g_ts_data->client = client;
++ i2c_set_clientdata(client, g_ts_data);
++
++ g_ts_data->screen_width = 800;
++ g_ts_data->screen_height = 480;
++ g_ts_data->xy_reverse = 1;
++
++ dev_info(&client->dev, "width = %d, height = %d, reverse = %d\n",
++ g_ts_data->screen_width, g_ts_data->screen_height, g_ts_data->xy_reverse);
++
++ ret = fts_check_fw_ver(g_ts_data->client);
++ if (ret) {
++ dev_err(&client->dev, "Checking touch ic failed\n");
++ goto check_fw_err;
++ }
++
++ input_dev = input_allocate_device();
++ if (!input_dev) {
++ dev_err(&client->dev, "Failed to allocate input device\n");
++ goto input_allocate_failed;
++ }
++ input_dev->name = "fts_ts";
++ input_dev->id.bustype = BUS_I2C;
++ input_dev->dev.parent = &g_ts_data->client->dev;
++ input_dev->open = tinker_ft5406_open;
++ input_dev->close = tinker_ft5406_close;
++
++ g_ts_data->input_dev = input_dev;
++ input_set_drvdata(input_dev, g_ts_data);
++
++ __set_bit(EV_SYN, input_dev->evbit);
++ __set_bit(EV_KEY, input_dev->evbit);
++ __set_bit(EV_ABS, input_dev->evbit);
++ __set_bit(BTN_TOUCH, input_dev->keybit);
++
++ input_mt_init_slots(input_dev, MAX_TOUCH_POINTS, 0);
++ input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, g_ts_data->screen_width, 0, 0);
++ input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, g_ts_data->screen_height, 0, 0);
++
++ ret = input_register_device(input_dev);
++ if (ret) {
++ dev_err(&client->dev, "Input device registration failed\n");
++ goto input_register_failed;
++ }
++
++ INIT_WORK(&g_ts_data->ft5406_work, tinker_ft5406_work);
++
++ return 0;
++
++input_register_failed:
++ input_free_device(input_dev);
++input_allocate_failed:
++check_fw_err:
++ kfree(g_ts_data);
++ g_ts_data = NULL;
++ return ret;
++}
++
++static void tinker_ft5406_remove(struct i2c_client *client)
++{
++ cancel_work_sync(&g_ts_data->ft5406_work);
++ if (g_ts_data->input_dev) {
++ input_unregister_device(g_ts_data->input_dev);
++ input_free_device(g_ts_data->input_dev);
++ }
++ kfree(g_ts_data);
++ g_ts_data = NULL;
++}
++
++static const struct i2c_device_id tinker_ft5406_id[] = {
++ {"tinker_ft5406", 0},
++ {},
++};
++
++static struct i2c_driver tinker_ft5406_driver = {
++ .driver = {
++ .name = "tinker_ft5406",
++ },
++ .probe = tinker_ft5406_probe,
++ .remove = tinker_ft5406_remove,
++ .id_table = tinker_ft5406_id,
++};
++module_i2c_driver(tinker_ft5406_driver);
++
++MODULE_DESCRIPTION("TINKER BOARD FT5406 Touch driver");
++MODULE_LICENSE("GPL v2");
diff --git a/target/linux/starfive/patches-6.6/0084-dt-binding-media-Add-JH7110-Camera-Subsystem.patch b/target/linux/starfive/patches-6.6/0084-dt-binding-media-Add-JH7110-Camera-Subsystem.patch
new file mode 100644
index 0000000000..69d7c7f494
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0084-dt-binding-media-Add-JH7110-Camera-Subsystem.patch
@@ -0,0 +1,246 @@
+From b477a1a53553336edcfeb83be1b35817928daed8 Mon Sep 17 00:00:00 2001
+From: Changhuang Liang <changhuang.liang@starfivetech.com>
+Date: Mon, 5 Jun 2023 14:46:16 +0800
+Subject: [PATCH 084/116] dt-binding: media: Add JH7110 Camera Subsystem.
+
+Add the bindings documentation for Starfive JH7110 Camera Subsystem
+which is used for handing image sensor data.
+
+Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
+Signed-off-by: Jack Zhu <jack.zhu@starfivetech.com>
+---
+ .../bindings/media/starfive,jh7110-camss.yaml | 228 ++++++++++++++++++
+ 1 file changed, 228 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/media/starfive,jh7110-camss.yaml
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/media/starfive,jh7110-camss.yaml
+@@ -0,0 +1,228 @@
++# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/media/starfive,jh7110-camss.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: Starfive SoC CAMSS ISP
++
++maintainers:
++ - Jack Zhu <jack.zhu@starfivetech.com>
++ - Changhuang Liang <changhuang.liang@starfivetech.com>
++
++description:
++ The Starfive CAMSS ISP is a Camera interface for Starfive JH7110 SoC. It
++ consists of a VIN controller (Video In Controller, a top-level control unit)
++ and an ISP.
++
++properties:
++ compatible:
++ const: starfive,jh7110-vin
++
++ reg:
++ maxItems: 8
++
++ reg-names:
++ items:
++ - const: csi2rx
++ - const: vclk
++ - const: vrst
++ - const: sctrl
++ - const: isp
++ - const: trst
++ - const: pmu
++ - const: syscrg
++
++ clocks:
++ maxItems: 16
++
++ clock-names:
++ items:
++ - const: clk_apb_func
++ - const: clk_pclk
++ - const: clk_sys_clk
++ - const: clk_wrapper_clk_c
++ - const: clk_dvp_inv
++ - const: clk_axiwr
++ - const: clk_mipi_rx0_pxl
++ - const: clk_pixel_clk_if0
++ - const: clk_pixel_clk_if1
++ - const: clk_pixel_clk_if2
++ - const: clk_pixel_clk_if3
++ - const: clk_m31dphy_cfgclk_in
++ - const: clk_m31dphy_refclk_in
++ - const: clk_m31dphy_txclkesc_lan0
++ - const: clk_ispcore_2x
++ - const: clk_isp_axi
++
++ resets:
++ maxItems: 14
++
++ reset-names:
++ items:
++ - const: rst_wrapper_p
++ - const: rst_wrapper_c
++ - const: rst_pclk
++ - const: rst_sys_clk
++ - const: rst_axird
++ - const: rst_axiwr
++ - const: rst_pixel_clk_if0
++ - const: rst_pixel_clk_if1
++ - const: rst_pixel_clk_if2
++ - const: rst_pixel_clk_if3
++ - const: rst_m31dphy_hw
++ - const: rst_m31dphy_b09_always_on
++ - const: rst_isp_top_n
++ - const: rst_isp_top_axi
++
++ power-domains:
++ items:
++ - description: JH7110 ISP Power Domain Switch Controller.
++
++ interrupts:
++ maxItems: 5
++
++ ports:
++ $ref: /schemas/graph.yaml#/properties/ports
++
++ properties:
++ port@0:
++ $ref: /schemas/graph.yaml#/$defs/port-base
++ unevaluatedProperties: false
++ description: Input port for receiving DVP data.
++
++ properties:
++ endpoint:
++ $ref: video-interfaces.yaml#
++ unevaluatedProperties: false
++
++ properties:
++ bus-type:
++ enum: [5, 6]
++
++ bus-width:
++ enum: [8, 10, 12]
++
++ data-shift:
++ enum: [0, 2]
++ default: 0
++
++ hsync-active:
++ enum: [0, 1]
++ default: 1
++
++ vsync-active:
++ enum: [0, 1]
++ default: 1
++
++ required:
++ - bus-type
++ - bus-width
++
++ port@1:
++ $ref: /schemas/graph.yaml#/properties/port
++ description: Input port for receiving CSI data.
++
++ required:
++ - port@0
++ - port@1
++
++required:
++ - compatible
++ - reg
++ - reg-names
++ - clocks
++ - clock-names
++ - resets
++ - reset-names
++ - power-domains
++ - interrupts
++ - ports
++
++additionalProperties: false
++
++examples:
++ - |
++ vin_sysctl: vin_sysctl@19800000 {
++ compatible = "starfive,jh7110-vin";
++ reg = <0x0 0x19800000 0x0 0x10000>,
++ <0x0 0x19810000 0x0 0x10000>,
++ <0x0 0x19820000 0x0 0x10000>,
++ <0x0 0x19840000 0x0 0x10000>,
++ <0x0 0x19870000 0x0 0x30000>,
++ <0x0 0x11840000 0x0 0x10000>,
++ <0x0 0x17030000 0x0 0x10000>,
++ <0x0 0x13020000 0x0 0x10000>;
++ reg-names = "csi2rx", "vclk", "vrst", "sctrl",
++ "isp", "trst", "pmu", "syscrg";
++ clocks = <&clkisp JH7110_DOM4_APB_FUNC>,
++ <&clkisp JH7110_U0_VIN_PCLK>,
++ <&clkisp JH7110_U0_VIN_SYS_CLK>,
++ <&clkisp JH7110_U0_ISPV2_TOP_WRAPPER_CLK_C>,
++ <&clkisp JH7110_DVP_INV>,
++ <&clkisp JH7110_U0_VIN_CLK_P_AXIWR>,
++ <&clkisp JH7110_MIPI_RX0_PXL>,
++ <&clkisp JH7110_U0_VIN_PIXEL_CLK_IF0>,
++ <&clkisp JH7110_U0_VIN_PIXEL_CLK_IF1>,
++ <&clkisp JH7110_U0_VIN_PIXEL_CLK_IF2>,
++ <&clkisp JH7110_U0_VIN_PIXEL_CLK_IF3>,
++ <&clkisp JH7110_U0_M31DPHY_CFGCLK_IN>,
++ <&clkisp JH7110_U0_M31DPHY_REFCLK_IN>,
++ <&clkisp JH7110_U0_M31DPHY_TXCLKESC_LAN0>,
++ <&clkgen JH7110_ISP_TOP_CLK_ISPCORE_2X>,
++ <&clkgen JH7110_ISP_TOP_CLK_ISP_AXI>;
++ clock-names = "clk_apb_func", "clk_pclk", "clk_sys_clk",
++ "clk_wrapper_clk_c", "clk_dvp_inv", "clk_axiwr",
++ "clk_mipi_rx0_pxl", "clk_pixel_clk_if0",
++ "clk_pixel_clk_if1", "clk_pixel_clk_if2",
++ "clk_pixel_clk_if3", "clk_m31dphy_cfgclk_in",
++ "clk_m31dphy_refclk_in", "clk_m31dphy_txclkesc_lan0",
++ "clk_ispcore_2x", "clk_isp_axi";
++ resets = <&rstgen RSTN_U0_ISPV2_TOP_WRAPPER_P>,
++ <&rstgen RSTN_U0_ISPV2_TOP_WRAPPER_C>,
++ <&rstgen RSTN_U0_VIN_N_PCLK>,
++ <&rstgen RSTN_U0_VIN_N_SYS_CLK>,
++ <&rstgen RSTN_U0_VIN_P_AXIRD>,
++ <&rstgen RSTN_U0_VIN_P_AXIWR>,
++ <&rstgen RSTN_U0_VIN_N_PIXEL_CLK_IF0>,
++ <&rstgen RSTN_U0_VIN_N_PIXEL_CLK_IF1>,
++ <&rstgen RSTN_U0_VIN_N_PIXEL_CLK_IF2>,
++ <&rstgen RSTN_U0_VIN_N_PIXEL_CLK_IF3>,
++ <&rstgen RSTN_U0_M31DPHY_HW>,
++ <&rstgen RSTN_U0_M31DPHY_B09_ALWAYS_ON>,
++ <&rstgen RSTN_U0_DOM_ISP_TOP_N>,
++ <&rstgen RSTN_U0_DOM_ISP_TOP_AXI>;
++ reset-names = "rst_wrapper_p", "rst_wrapper_c", "rst_pclk",
++ "rst_sys_clk", "rst_axird", "rst_axiwr", "rst_pixel_clk_if0",
++ "rst_pixel_clk_if1", "rst_pixel_clk_if2", "rst_pixel_clk_if3",
++ "rst_m31dphy_hw", "rst_m31dphy_b09_always_on",
++ "rst_isp_top_n", "rst_isp_top_axi";
++ starfive,aon-syscon = <&aon_syscon 0x00>;
++ power-domains = <&pwrc JH7110_PD_ISP>;
++ /* irq nr: vin, isp, isp_csi, isp_scd, isp_csiline */
++ interrupts = <92>, <87>, <88>, <89>, <90>;
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ port@0 {
++ reg = <0>;
++ vin_from_sc2235: endpoint {
++ remote-endpoint = <&sc2235_to_vin>;
++ bus-type = <5>;
++ bus-width = <8>;
++ data-shift = <2>;
++ hsync-active = <1>;
++ vsync-active = <0>;
++ pclk-sample = <1>;
++ };
++ };
++
++ port@1 {
++ reg = <1>;
++ vin_from_csi2rx: endpoint {
++ remote-endpoint = <&csi2rx_to_vin>;
++ };
++ };
++ };
++ };
diff --git a/target/linux/starfive/patches-6.6/0085-media-starfive-Add-vin-driver-support.patch b/target/linux/starfive/patches-6.6/0085-media-starfive-Add-vin-driver-support.patch
new file mode 100644
index 0000000000..b5d5f73f9d
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0085-media-starfive-Add-vin-driver-support.patch
@@ -0,0 +1,24014 @@
+From 908b10ebc95eb29caae8c4737b23a29af5c6298f Mon Sep 17 00:00:00 2001
+From: Changhuang Liang <changhuang.liang@starfivetech.com>
+Date: Mon, 5 Jun 2023 13:54:16 +0800
+Subject: [PATCH 085/116] media: starfive: Add vin driver support
+
+Add vin driver support.
+
+Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
+---
+ drivers/media/platform/Kconfig | 1 +
+ drivers/media/platform/Makefile | 1 +
+ drivers/media/platform/starfive/Kconfig | 56 +
+ drivers/media/platform/starfive/Makefile | 24 +
+ .../platform/starfive/v4l2_driver/Readme.txt | 11 +
+ .../starfive/v4l2_driver/imx219_mipi.c | 1583 ++++++++
+ .../starfive/v4l2_driver/ov13850_mipi.c | 1921 ++++++++++
+ .../starfive/v4l2_driver/ov4689_mipi.c | 2975 +++++++++++++++
+ .../platform/starfive/v4l2_driver/ov5640.c | 3227 +++++++++++++++++
+ .../platform/starfive/v4l2_driver/sc2235.c | 1914 ++++++++++
+ .../starfive/v4l2_driver/stf_common.h | 185 +
+ .../platform/starfive/v4l2_driver/stf_csi.c | 465 +++
+ .../platform/starfive/v4l2_driver/stf_csi.h | 61 +
+ .../starfive/v4l2_driver/stf_csi_hw_ops.c | 310 ++
+ .../starfive/v4l2_driver/stf_csiphy.c | 357 ++
+ .../starfive/v4l2_driver/stf_csiphy.h | 188 +
+ .../starfive/v4l2_driver/stf_csiphy_hw_ops.c | 335 ++
+ .../starfive/v4l2_driver/stf_dmabuf.c | 123 +
+ .../starfive/v4l2_driver/stf_dmabuf.h | 12 +
+ .../platform/starfive/v4l2_driver/stf_dvp.c | 385 ++
+ .../platform/starfive/v4l2_driver/stf_dvp.h | 67 +
+ .../starfive/v4l2_driver/stf_dvp_hw_ops.c | 187 +
+ .../platform/starfive/v4l2_driver/stf_event.c | 36 +
+ .../platform/starfive/v4l2_driver/stf_isp.c | 1521 ++++++++
+ .../platform/starfive/v4l2_driver/stf_isp.h | 222 ++
+ .../starfive/v4l2_driver/stf_isp_hw_ops.c | 1550 ++++++++
+ .../starfive/v4l2_driver/stf_isp_ioctl.h | 133 +
+ .../platform/starfive/v4l2_driver/stf_video.c | 1552 ++++++++
+ .../platform/starfive/v4l2_driver/stf_video.h | 83 +
+ .../platform/starfive/v4l2_driver/stf_vin.c | 1515 ++++++++
+ .../platform/starfive/v4l2_driver/stf_vin.h | 182 +
+ .../starfive/v4l2_driver/stf_vin_hw_ops.c | 433 +++
+ .../platform/starfive/v4l2_driver/stfcamss.c | 1369 +++++++
+ .../platform/starfive/v4l2_driver/stfcamss.h | 117 +
+ include/uapi/linux/jh7110-isp.h | 253 ++
+ include/uapi/linux/v4l2-controls.h | 6 +
+ include/video/stf-vin.h | 443 +++
+ 37 files changed, 23803 insertions(+)
+ create mode 100644 drivers/media/platform/starfive/Kconfig
+ create mode 100644 drivers/media/platform/starfive/Makefile
+ create mode 100644 drivers/media/platform/starfive/v4l2_driver/Readme.txt
+ create mode 100644 drivers/media/platform/starfive/v4l2_driver/imx219_mipi.c
+ create mode 100644 drivers/media/platform/starfive/v4l2_driver/ov13850_mipi.c
+ create mode 100644 drivers/media/platform/starfive/v4l2_driver/ov4689_mipi.c
+ create mode 100644 drivers/media/platform/starfive/v4l2_driver/ov5640.c
+ create mode 100644 drivers/media/platform/starfive/v4l2_driver/sc2235.c
+ create mode 100644 drivers/media/platform/starfive/v4l2_driver/stf_common.h
+ create mode 100644 drivers/media/platform/starfive/v4l2_driver/stf_csi.c
+ create mode 100644 drivers/media/platform/starfive/v4l2_driver/stf_csi.h
+ create mode 100644 drivers/media/platform/starfive/v4l2_driver/stf_csi_hw_ops.c
+ create mode 100644 drivers/media/platform/starfive/v4l2_driver/stf_csiphy.c
+ create mode 100644 drivers/media/platform/starfive/v4l2_driver/stf_csiphy.h
+ create mode 100644 drivers/media/platform/starfive/v4l2_driver/stf_csiphy_hw_ops.c
+ create mode 100644 drivers/media/platform/starfive/v4l2_driver/stf_dmabuf.c
+ create mode 100644 drivers/media/platform/starfive/v4l2_driver/stf_dmabuf.h
+ create mode 100644 drivers/media/platform/starfive/v4l2_driver/stf_dvp.c
+ create mode 100644 drivers/media/platform/starfive/v4l2_driver/stf_dvp.h
+ create mode 100644 drivers/media/platform/starfive/v4l2_driver/stf_dvp_hw_ops.c
+ create mode 100644 drivers/media/platform/starfive/v4l2_driver/stf_event.c
+ create mode 100644 drivers/media/platform/starfive/v4l2_driver/stf_isp.c
+ create mode 100644 drivers/media/platform/starfive/v4l2_driver/stf_isp.h
+ create mode 100644 drivers/media/platform/starfive/v4l2_driver/stf_isp_hw_ops.c
+ create mode 100644 drivers/media/platform/starfive/v4l2_driver/stf_isp_ioctl.h
+ create mode 100644 drivers/media/platform/starfive/v4l2_driver/stf_video.c
+ create mode 100644 drivers/media/platform/starfive/v4l2_driver/stf_video.h
+ create mode 100644 drivers/media/platform/starfive/v4l2_driver/stf_vin.c
+ create mode 100644 drivers/media/platform/starfive/v4l2_driver/stf_vin.h
+ create mode 100644 drivers/media/platform/starfive/v4l2_driver/stf_vin_hw_ops.c
+ create mode 100644 drivers/media/platform/starfive/v4l2_driver/stfcamss.c
+ create mode 100644 drivers/media/platform/starfive/v4l2_driver/stfcamss.h
+ create mode 100644 include/uapi/linux/jh7110-isp.h
+ create mode 100644 include/video/stf-vin.h
+
+--- a/drivers/media/platform/Kconfig
++++ b/drivers/media/platform/Kconfig
+@@ -80,6 +80,7 @@ source "drivers/media/platform/renesas/K
+ source "drivers/media/platform/rockchip/Kconfig"
+ source "drivers/media/platform/samsung/Kconfig"
+ source "drivers/media/platform/st/Kconfig"
++source "drivers/media/platform/starfive/Kconfig"
+ source "drivers/media/platform/sunxi/Kconfig"
+ source "drivers/media/platform/ti/Kconfig"
+ source "drivers/media/platform/verisilicon/Kconfig"
+--- a/drivers/media/platform/Makefile
++++ b/drivers/media/platform/Makefile
+@@ -23,6 +23,7 @@ obj-y += renesas/
+ obj-y += rockchip/
+ obj-y += samsung/
+ obj-y += st/
++obj-y += starfive/
+ obj-y += sunxi/
+ obj-y += ti/
+ obj-y += verisilicon/
+--- /dev/null
++++ b/drivers/media/platform/starfive/Kconfig
+@@ -0,0 +1,56 @@
++# SPDX-License-Identifier: GPL-2.0-only
++
++comment "Starfive media platform drivers"
++
++config VIN_SENSOR_OV5640
++ tristate "VIN SENSOR support OV5640"
++ depends on VIDEO_STF_VIN
++ select V4L2_FWNODE
++ default n
++ help
++ Say Y here if you want to have support for VIN sensor OV5640
++
++config VIN_SENSOR_SC2235
++ tristate "VIN SENSOR support SC2235"
++ depends on VIDEO_STF_VIN
++ select V4L2_FWNODE
++ default n
++ help
++ Say Y here if you want to have support for VIN sensor SC2235
++
++config VIN_SENSOR_OV4689
++ tristate "VIN SENSOR support OV4689"
++ depends on VIDEO_STF_VIN
++ select V4L2_FWNODE
++ default n
++
++ help
++ Say Y here if you want to have support for VIN sensor OV4689
++
++config VIN_SENSOR_OV13850
++ bool "VIN SENSOR support OV13850"
++ depends on VIDEO_STF_VIN
++ select V4L2_FWNODE
++ default n
++ help
++ Say Y here if you want to have support for VIN sensor OV13850
++
++config VIN_SENSOR_IMX219
++ tristate "VIN SENSOR support IMX219"
++ depends on VIDEO_STF_VIN
++ select V4L2_FWNODE
++ default n
++ help
++ Say Y here if you want to have support for VIN sensor IMX219
++
++config VIDEO_STF_VIN
++ tristate "starfive VIC video in support"
++ depends on V4L_PLATFORM_DRIVERS
++ depends on VIDEO_DEV
++ select MEDIA_CONTROLLER
++ select VIDEOBUF2_DMA_CONTIG
++ select VIDEO_V4L2_SUBDEV_API
++ select V4L2_FWNODE
++ help
++ To compile this driver as a module, choose M here: the module
++ will be called stf-vin.
+--- /dev/null
++++ b/drivers/media/platform/starfive/Makefile
+@@ -0,0 +1,24 @@
++# SPDX-License-Identifier: GPL-2.0
++
++obj-$(CONFIG_VIN_SENSOR_OV5640) += v4l2_driver/ov5640.o
++obj-$(CONFIG_VIN_SENSOR_SC2235) += v4l2_driver/sc2235.o
++obj-$(CONFIG_VIN_SENSOR_OV4689) += v4l2_driver/ov4689_mipi.o
++obj-$(CONFIG_VIN_SENSOR_OV13850) += v4l2_driver/ov13850_mipi.o
++obj-$(CONFIG_VIN_SENSOR_IMX219) += v4l2_driver/imx219_mipi.o
++
++starfivecamss-objs += v4l2_driver/stfcamss.o \
++ v4l2_driver/stf_event.o \
++ v4l2_driver/stf_dvp.o \
++ v4l2_driver/stf_csi.o \
++ v4l2_driver/stf_csiphy.o \
++ v4l2_driver/stf_isp.o \
++ v4l2_driver/stf_video.o \
++ v4l2_driver/stf_vin.o \
++ v4l2_driver/stf_vin_hw_ops.o \
++ v4l2_driver/stf_csi_hw_ops.o \
++ v4l2_driver/stf_csiphy_hw_ops.o \
++ v4l2_driver/stf_isp_hw_ops.o \
++ v4l2_driver/stf_dvp_hw_ops.o \
++ v4l2_driver/stf_dmabuf.o
++
++obj-$(CONFIG_VIDEO_STF_VIN) += starfivecamss.o \
+--- /dev/null
++++ b/drivers/media/platform/starfive/v4l2_driver/Readme.txt
+@@ -0,0 +1,11 @@
++
++/dev/video0: Output the camera data directly.
++/dev/video1: Output the data of the camera converted by isp.
++
++ensure linux/arch/riscv/configs/starfive_jh7110_defconfig:
++CONFIG_VIDEO_STF_VIN=y
++CONFIG_VIN_SENSOR_SC2235=y
++CONFIG_VIN_SENSOR_OV4689=y
++
++Only support the lane0/lane5 of dphy as clock lane, lane1/lane2/lane3/lane4
++as data lane.
+--- /dev/null
++++ b/drivers/media/platform/starfive/v4l2_driver/imx219_mipi.c
+@@ -0,0 +1,1583 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * A V4L2 driver for Sony IMX219 cameras.
++ * Copyright (C) 2019, Raspberry Pi (Trading) Ltd
++ *
++ * Based on Sony imx258 camera driver
++ * Copyright (C) 2018 Intel Corporation
++ *
++ * DT / fwnode changes, and regulator / GPIO control taken from imx214 driver
++ * Copyright 2018 Qtechnology A/S
++ *
++ * Flip handling taken from the Sony IMX319 driver.
++ * Copyright (C) 2018 Intel Corporation
++ *
++ */
++
++#include <linux/clk.h>
++#include <linux/delay.h>
++#include <linux/gpio/consumer.h>
++#include <linux/i2c.h>
++#include <linux/module.h>
++#include <linux/pm_runtime.h>
++#include <linux/regulator/consumer.h>
++#include <media/v4l2-ctrls.h>
++#include <media/v4l2-device.h>
++#include <media/v4l2-event.h>
++#include <media/v4l2-fwnode.h>
++#include <media/v4l2-mediabus.h>
++#include <asm/unaligned.h>
++
++#define IMX219_REG_VALUE_08BIT 1
++#define IMX219_REG_VALUE_16BIT 2
++
++#define IMX219_REG_MODE_SELECT 0x0100
++#define IMX219_MODE_STANDBY 0x00
++#define IMX219_MODE_STREAMING 0x01
++
++/* Chip ID */
++#define IMX219_REG_CHIP_ID 0x0000
++#define IMX219_CHIP_ID 0x0219
++
++/* External clock frequency is 24.0M */
++#define IMX219_XCLK_FREQ 24000000
++
++/* Pixel rate is fixed at 182.4M for all the modes */
++#define IMX219_PIXEL_RATE 182400000
++
++#define IMX219_DEFAULT_LINK_FREQ 456000000
++
++/* V_TIMING internal */
++#define IMX219_REG_VTS 0x0160
++#define IMX219_VTS_15FPS 0x0dc6
++#define IMX219_VTS_30FPS_1080P 0x06e3
++#define IMX219_VTS_30FPS_BINNED 0x06e3
++#define IMX219_VTS_30FPS_1280x720 0x06e3
++#define IMX219_VTS_30FPS_640x480 0x06e3
++#define IMX219_VTS_MAX 0xffff
++
++#define IMX219_VBLANK_MIN 4
++
++/*Frame Length Line*/
++#define IMX219_FLL_MIN 0x08a6
++#define IMX219_FLL_MAX 0xffff
++#define IMX219_FLL_STEP 1
++#define IMX219_FLL_DEFAULT 0x0c98
++
++/* HBLANK control - read only */
++#define IMX219_PPL_DEFAULT 3448
++
++/* Exposure control */
++#define IMX219_REG_EXPOSURE 0x015a
++#define IMX219_EXPOSURE_MIN 4
++#define IMX219_EXPOSURE_STEP 1
++#define IMX219_EXPOSURE_DEFAULT 0x640
++#define IMX219_EXPOSURE_MAX 65535
++
++/* Analog gain control */
++#define IMX219_REG_ANALOG_GAIN 0x0157
++#define IMX219_ANA_GAIN_MIN 0
++#define IMX219_ANA_GAIN_MAX 232
++#define IMX219_ANA_GAIN_STEP 1
++#define IMX219_ANA_GAIN_DEFAULT 0xd0
++
++/* Digital gain control */
++#define IMX219_REG_DIGITAL_GAIN 0x0158
++#define IMX219_DGTL_GAIN_MIN 0x0100
++#define IMX219_DGTL_GAIN_MAX 0x0fff
++#define IMX219_DGTL_GAIN_DEFAULT 0x0100
++#define IMX219_DGTL_GAIN_STEP 1
++
++#define IMX219_REG_ORIENTATION 0x0172
++
++/* Test Pattern Control */
++#define IMX219_REG_TEST_PATTERN 0x0600
++#define IMX219_TEST_PATTERN_DISABLE 0
++#define IMX219_TEST_PATTERN_SOLID_COLOR 1
++#define IMX219_TEST_PATTERN_COLOR_BARS 2
++#define IMX219_TEST_PATTERN_GREY_COLOR 3
++#define IMX219_TEST_PATTERN_PN9 4
++
++/* Test pattern colour components */
++#define IMX219_REG_TESTP_RED 0x0602
++#define IMX219_REG_TESTP_GREENR 0x0604
++#define IMX219_REG_TESTP_BLUE 0x0606
++#define IMX219_REG_TESTP_GREENB 0x0608
++#define IMX219_TESTP_COLOUR_MIN 0
++#define IMX219_TESTP_COLOUR_MAX 0x03ff
++#define IMX219_TESTP_COLOUR_STEP 1
++#define IMX219_TESTP_RED_DEFAULT IMX219_TESTP_COLOUR_MAX
++#define IMX219_TESTP_GREENR_DEFAULT 0
++#define IMX219_TESTP_BLUE_DEFAULT 0
++#define IMX219_TESTP_GREENB_DEFAULT 0
++
++/* IMX219 native and active pixel array size. */
++#define IMX219_NATIVE_WIDTH 3296U
++#define IMX219_NATIVE_HEIGHT 2480U
++#define IMX219_PIXEL_ARRAY_LEFT 8U
++#define IMX219_PIXEL_ARRAY_TOP 8U
++#define IMX219_PIXEL_ARRAY_WIDTH 3280U
++#define IMX219_PIXEL_ARRAY_HEIGHT 2464U
++
++struct imx219_reg {
++ u16 address;
++ u8 val;
++};
++
++struct imx219_reg_list {
++ unsigned int num_of_regs;
++ const struct imx219_reg *regs;
++};
++
++/* Mode : resolution and related config&values */
++struct imx219_mode {
++ /* Frame width */
++ unsigned int width;
++ /* Frame height */
++ unsigned int height;
++
++ unsigned int fps;
++
++ /* Analog crop rectangle. */
++ struct v4l2_rect crop;
++
++ /* V-timing */
++ unsigned int vts_def;
++
++ /* Default register values */
++ struct imx219_reg_list reg_list;
++};
++
++/*
++ * Register sets lifted off the i2C interface from the Raspberry Pi firmware
++ * driver.
++ * 3280x2464 = mode 2, 1920x1080 = mode 1, 1640x1232 = mode 4, 640x480 = mode 7.
++ */
++
++static const struct imx219_reg mode_1920_1080_regs[] = {
++ {0x0100, 0x00},
++ {0x30eb, 0x05},
++ {0x30eb, 0x0c},
++ {0x300a, 0xff},
++ {0x300b, 0xff},
++ {0x30eb, 0x05},
++ {0x30eb, 0x09},
++ {0x0114, 0x01},
++ {0x0128, 0x00},
++ {0x012a, 0x18},
++ {0x012b, 0x00},
++ {0x0162, 0x0d},
++ {0x0163, 0x78},
++ {0x0164, 0x02},
++ {0x0165, 0xa8},
++ {0x0166, 0x0a},
++ {0x0167, 0x27},
++ {0x0168, 0x02},
++ {0x0169, 0xb4},
++ {0x016a, 0x06},
++ {0x016b, 0xeb},
++ {0x016c, 0x07},
++ {0x016d, 0x80},
++ {0x016e, 0x04},
++ {0x016f, 0x38},
++ {0x0170, 0x01},
++ {0x0171, 0x01},
++ {0x0174, 0x00},
++ {0x0175, 0x00},
++ {0x0301, 0x05},
++ {0x0303, 0x01},
++ {0x0304, 0x03},
++ {0x0305, 0x03},
++ {0x0306, 0x00},
++ {0x0307, 0x39},
++ {0x030b, 0x01},
++ {0x030c, 0x00},
++ {0x030d, 0x72},
++ {0x0624, 0x07},
++ {0x0625, 0x80},
++ {0x0626, 0x04},
++ {0x0627, 0x38},
++ {0x455e, 0x00},
++ {0x471e, 0x4b},
++ {0x4767, 0x0f},
++ {0x4750, 0x14},
++ {0x4540, 0x00},
++ {0x47b4, 0x14},
++ {0x4713, 0x30},
++ {0x478b, 0x10},
++ {0x478f, 0x10},
++ {0x4793, 0x10},
++ {0x4797, 0x0e},
++ {0x479b, 0x0e},
++};
++
++static const struct imx219_reg mode_1280_720_regs[] = {
++ {0x0100, 0x00},
++ {0x30eb, 0x05},
++ {0x30eb, 0x0c},
++ {0x300a, 0xff},
++ {0x300b, 0xff},
++ {0x30eb, 0x05},
++ {0x30eb, 0x09},
++ {0x0114, 0x01},
++ {0x0128, 0x00},
++ {0x012a, 0x18},
++ {0x012b, 0x00},
++ {0x0162, 0x0d},
++ {0x0163, 0x78},
++ {0x0164, 0x01},
++ {0x0165, 0x68},
++ {0x0166, 0x0b},
++ {0x0167, 0x67},
++ {0x0168, 0x02},
++ {0x0169, 0x00},
++ {0x016a, 0x07},
++ {0x016b, 0x9f},
++ {0x016c, 0x05},
++ {0x016d, 0x00},
++ {0x016e, 0x02},
++ {0x016f, 0xd0},
++ {0x0170, 0x01},
++ {0x0171, 0x01},
++ {0x0174, 0x01},
++ {0x0175, 0x01},
++ {0x0301, 0x05},
++ {0x0303, 0x01},
++ {0x0304, 0x03},
++ {0x0305, 0x03},
++ {0x0306, 0x00},
++ {0x0307, 0x39},
++ {0x030b, 0x01},
++ {0x030c, 0x00},
++ {0x030d, 0x72},
++ {0x0624, 0x06},
++ {0x0625, 0x68},
++ {0x0626, 0x04},
++ {0x0627, 0xd0},
++ {0x455e, 0x00},
++ {0x471e, 0x4b},
++ {0x4767, 0x0f},
++ {0x4750, 0x14},
++ {0x4540, 0x00},
++ {0x47b4, 0x14},
++ {0x4713, 0x30},
++ {0x478b, 0x10},
++ {0x478f, 0x10},
++ {0x4793, 0x10},
++ {0x4797, 0x0e},
++ {0x479b, 0x0e},
++};
++
++static const struct imx219_reg mode_640_480_regs[] = {
++ {0x0100, 0x00},
++ {0x30eb, 0x05},
++ {0x30eb, 0x0c},
++ {0x300a, 0xff},
++ {0x300b, 0xff},
++ {0x30eb, 0x05},
++ {0x30eb, 0x09},
++ {0x0114, 0x01},
++ {0x0128, 0x00},
++ {0x012a, 0x18},
++ {0x012b, 0x00},
++ {0x0162, 0x0d},
++ {0x0163, 0x78},
++ {0x0164, 0x03},
++ {0x0165, 0xe8},
++ {0x0166, 0x08},
++ {0x0167, 0xe7},
++ {0x0168, 0x02},
++ {0x0169, 0xf0},
++ {0x016a, 0x06},
++ {0x016b, 0xaf},
++ {0x016c, 0x02},
++ {0x016d, 0x80},
++ {0x016e, 0x01},
++ {0x016f, 0xe0},
++ {0x0170, 0x01},
++ {0x0171, 0x01},
++ {0x0174, 0x03},
++ {0x0175, 0x03},
++ {0x0301, 0x05},
++ {0x0303, 0x01},
++ {0x0304, 0x03},
++ {0x0305, 0x03},
++ {0x0306, 0x00},
++ {0x0307, 0x39},
++ {0x030b, 0x01},
++ {0x030c, 0x00},
++ {0x030d, 0x72},
++ {0x0624, 0x06},
++ {0x0625, 0x68},
++ {0x0626, 0x04},
++ {0x0627, 0xd0},
++ {0x455e, 0x00},
++ {0x471e, 0x4b},
++ {0x4767, 0x0f},
++ {0x4750, 0x14},
++ {0x4540, 0x00},
++ {0x47b4, 0x14},
++ {0x4713, 0x30},
++ {0x478b, 0x10},
++ {0x478f, 0x10},
++ {0x4793, 0x10},
++ {0x4797, 0x0e},
++ {0x479b, 0x0e},
++};
++
++static const struct imx219_reg raw8_framefmt_regs[] = {
++ {0x018c, 0x08},
++ {0x018d, 0x08},
++ {0x0309, 0x08},
++};
++
++static const struct imx219_reg raw10_framefmt_regs[] = {
++ {0x018c, 0x0a},
++ {0x018d, 0x0a},
++ {0x0309, 0x0a},
++};
++
++static const s64 imx219_link_freq_menu[] = {
++ IMX219_DEFAULT_LINK_FREQ,
++};
++
++static const char * const imx219_test_pattern_menu[] = {
++ "Disabled",
++ "Color Bars",
++ "Solid Color",
++ "Grey Color Bars",
++ "PN9"
++};
++
++static const int imx219_test_pattern_val[] = {
++ IMX219_TEST_PATTERN_DISABLE,
++ IMX219_TEST_PATTERN_COLOR_BARS,
++ IMX219_TEST_PATTERN_SOLID_COLOR,
++ IMX219_TEST_PATTERN_GREY_COLOR,
++ IMX219_TEST_PATTERN_PN9,
++};
++
++/* regulator supplies */
++static const char * const imx219_supply_name[] = {
++ /* Supplies can be enabled in any order */
++ "VANA", /* Analog (2.8V) supply */
++ "VDIG", /* Digital Core (1.8V) supply */
++ "VDDL", /* IF (1.2V) supply */
++};
++
++#define IMX219_NUM_SUPPLIES ARRAY_SIZE(imx219_supply_name)
++
++/*
++ * 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[] = {
++ MEDIA_BUS_FMT_SRGGB10_1X10,
++ MEDIA_BUS_FMT_SGRBG10_1X10,
++ MEDIA_BUS_FMT_SGBRG10_1X10,
++ MEDIA_BUS_FMT_SBGGR10_1X10,
++
++ MEDIA_BUS_FMT_SRGGB8_1X8,
++ MEDIA_BUS_FMT_SGRBG8_1X8,
++ MEDIA_BUS_FMT_SGBRG8_1X8,
++ MEDIA_BUS_FMT_SBGGR8_1X8,
++};
++
++/*
++ * Initialisation delay between XCLR low->high and the moment when the sensor
++ * can start capture (i.e. can leave software stanby) must be not less than:
++ * t4 + max(t5, t6 + <time to initialize the sensor register over I2C>)
++ * where
++ * t4 is fixed, and is max 200uS,
++ * t5 is fixed, and is 6000uS,
++ * t6 depends on the sensor external clock, and is max 32000 clock periods.
++ * As per sensor datasheet, the external clock must be from 6MHz to 27MHz.
++ * So for any acceptable external clock t6 is always within the range of
++ * 1185 to 5333 uS, and is always less than t5.
++ * For this reason this is always safe to wait (t4 + t5) = 6200 uS, then
++ * initialize the sensor over I2C, and then exit the software standby.
++ *
++ * This start-up time can be optimized a bit more, if we start the writes
++ * over I2C after (t4+t6), but before (t4+t5) expires. But then sensor
++ * initialization over I2C may complete before (t4+t5) expires, and we must
++ * ensure that capture is not started before (t4+t5).
++ *
++ * This delay doesn't account for the power supply startup time. If needed,
++ * this should be taken care of via the regulator framework. E.g. in the
++ * case of DT for regulator-fixed one should define the startup-delay-us
++ * property.
++ */
++#define IMX219_XCLR_MIN_DELAY_US 6200
++#define IMX219_XCLR_DELAY_RANGE_US 1000
++
++/* Mode configs */
++static const struct imx219_mode supported_modes[] = {
++ {
++ /* 1080P 30fps cropped */
++ .width = 1920,
++ .height = 1080,
++ .fps = 30,
++ .crop = {
++ .left = 688,
++ .top = 700,
++ .width = 1920,
++ .height = 1080
++ },
++ .vts_def = IMX219_VTS_30FPS_1080P,
++ .reg_list = {
++ .num_of_regs = ARRAY_SIZE(mode_1920_1080_regs),
++ .regs = mode_1920_1080_regs,
++ },
++ },
++ {
++ /* 1280x720 30fps mode */
++ .width = 1280,
++ .height = 720,
++ .fps = 30,
++ .crop = {
++ .left = 360,
++ .top = 512,
++ .width = 2560,
++ .height = 1440
++ },
++ .vts_def = IMX219_VTS_30FPS_1280x720,
++ .reg_list = {
++ .num_of_regs = ARRAY_SIZE(mode_1280_720_regs),
++ .regs = mode_1280_720_regs,
++ },
++ },
++ {
++ /* 640x480 30fps mode */
++ .width = 640,
++ .height = 480,
++ .fps = 30,
++ .crop = {
++ .left = 1008,
++ .top = 760,
++ .width = 1280,
++ .height = 960
++ },
++ .vts_def = IMX219_VTS_30FPS_640x480,
++ .reg_list = {
++ .num_of_regs = ARRAY_SIZE(mode_640_480_regs),
++ .regs = mode_640_480_regs,
++ },
++ },
++};
++
++struct imx219 {
++ struct v4l2_subdev sd;
++ struct media_pad pad;
++ //struct v4l2_fwnode_endpoint ep; /* the parsed DT endpoint info */
++
++ struct v4l2_mbus_framefmt fmt;
++
++ struct clk *xclk; /* system clock to IMX219 */
++ u32 xclk_freq;
++
++ struct gpio_desc *reset_gpio;
++ struct regulator_bulk_data supplies[IMX219_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 imx219_mode *mode;
++ struct v4l2_fract frame_interval;
++
++ /*
++ * Mutex for serialized access:
++ * Protect sensor module set pad format and start/stop streaming safely.
++ */
++ struct mutex mutex;
++
++ /* Streaming on/off */
++ int streaming;
++};
++
++static inline struct imx219 *to_imx219(struct v4l2_subdev *_sd)
++{
++ return container_of(_sd, struct imx219, sd);
++}
++
++/* Read registers up to 2 at a time */
++static int imx219_read_reg(struct imx219 *imx219, u16 reg, u32 len, u32 *val)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd);
++ struct i2c_msg msgs[2];
++ u8 addr_buf[2] = { reg >> 8, reg & 0xff };
++ u8 data_buf[4] = { 0, };
++ int ret;
++
++ if (len > 4)
++ return -EINVAL;
++
++ /* Write register address */
++ msgs[0].addr = client->addr;
++ msgs[0].flags = 0;
++ msgs[0].len = ARRAY_SIZE(addr_buf);
++ msgs[0].buf = addr_buf;
++
++ /* Read data from register */
++ msgs[1].addr = client->addr;
++ msgs[1].flags = I2C_M_RD;
++ msgs[1].len = len;
++ msgs[1].buf = &data_buf[4 - len];
++
++ ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
++ if (ret != ARRAY_SIZE(msgs))
++ return -EIO;
++
++ *val = get_unaligned_be32(data_buf);
++
++ return 0;
++}
++
++/* Write registers up to 2 at a time */
++static int imx219_write_reg(struct imx219 *imx219, u16 reg, u32 len, u32 val)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd);
++ u8 buf[6];
++
++ if (len > 4)
++ return -EINVAL;
++
++ put_unaligned_be16(reg, buf);
++ put_unaligned_be32(val << (8 * (4 - len)), buf + 2);
++ if (i2c_master_send(client, buf, len + 2) != len + 2)
++ return -EIO;
++
++ return 0;
++}
++
++/* Write a list of registers */
++static int imx219_write_regs(struct imx219 *imx219,
++ const struct imx219_reg *regs, u32 len)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd);
++ unsigned int i;
++ int ret;
++
++ for (i = 0; i < len; i++) {
++ ret = imx219_write_reg(imx219, regs[i].address, 1, regs[i].val);
++ if (ret) {
++ dev_err_ratelimited(&client->dev,
++ "Failed to write reg 0x%4.4x. error = %d\n",
++ regs[i].address, ret);
++
++ return ret;
++ }
++ }
++
++ return 0;
++}
++
++/* Get bayer order based on flip setting. */
++static u32 imx219_get_format_code(struct imx219 *imx219, u32 code)
++{
++ unsigned int i;
++
++ lockdep_assert_held(&imx219->mutex);
++
++ for (i = 0; i < ARRAY_SIZE(codes); i++)
++ if (codes[i] == code)
++ break;
++
++ if (i >= ARRAY_SIZE(codes))
++ i = 0;
++
++ i = (i & ~3) | (imx219->vflip->val ? 2 : 0) |
++ (imx219->hflip->val ? 1 : 0);
++
++ return codes[i];
++}
++
++static void imx219_set_default_format(struct imx219 *imx219)
++{
++ struct v4l2_mbus_framefmt *fmt;
++
++ fmt = &imx219->fmt;
++ fmt->code = MEDIA_BUS_FMT_SRGGB10_1X10;
++ fmt->colorspace = V4L2_COLORSPACE_SRGB;
++ fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->colorspace);
++ fmt->quantization = V4L2_MAP_QUANTIZATION_DEFAULT(true,
++ fmt->colorspace, fmt->ycbcr_enc);
++ fmt->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(fmt->colorspace);
++ fmt->width = supported_modes[0].width;
++ fmt->height = supported_modes[0].height;
++ fmt->field = V4L2_FIELD_NONE;
++}
++
++static int imx219_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
++{
++ struct imx219 *imx219 = to_imx219(sd);
++ struct v4l2_mbus_framefmt *try_fmt =
++ v4l2_subdev_get_try_format(sd, fh->state, 0);
++ struct v4l2_rect *try_crop;
++
++ mutex_lock(&imx219->mutex);
++
++ /* Initialize try_fmt */
++ try_fmt->width = supported_modes[0].width;
++ try_fmt->height = supported_modes[0].height;
++ try_fmt->code = imx219_get_format_code(imx219, MEDIA_BUS_FMT_SRGGB10_1X10);
++ try_fmt->field = V4L2_FIELD_NONE;
++
++ /* Initialize try_crop rectangle. */
++ try_crop = v4l2_subdev_get_try_crop(sd, fh->state, 0);
++ try_crop->top = IMX219_PIXEL_ARRAY_TOP;
++ try_crop->left = IMX219_PIXEL_ARRAY_LEFT;
++ try_crop->width = IMX219_PIXEL_ARRAY_WIDTH;
++ try_crop->height = IMX219_PIXEL_ARRAY_HEIGHT;
++
++ mutex_unlock(&imx219->mutex);
++
++ return 0;
++}
++
++static int imx219_set_ctrl(struct v4l2_ctrl *ctrl)
++{
++ struct imx219 *imx219 =
++ container_of(ctrl->handler, struct imx219, ctrl_handler);
++ struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd);
++ int ret;
++
++ if (ctrl->id == V4L2_CID_VBLANK) {
++ int exposure_max, exposure_def;
++
++ /* Update max exposure while meeting expected vblanking */
++ exposure_max = imx219->mode->height + ctrl->val - 4;
++ exposure_def = (exposure_max < IMX219_EXPOSURE_DEFAULT) ?
++ exposure_max : IMX219_EXPOSURE_DEFAULT;
++ __v4l2_ctrl_modify_range(imx219->exposure, imx219->exposure->minimum,
++ exposure_max, imx219->exposure->step, exposure_def);
++ }
++
++ /*
++ * 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 = imx219_write_reg(imx219, IMX219_REG_ANALOG_GAIN,
++ IMX219_REG_VALUE_08BIT, ctrl->val);
++ break;
++ case V4L2_CID_EXPOSURE:
++ ret = imx219_write_reg(imx219, IMX219_REG_EXPOSURE,
++ IMX219_REG_VALUE_16BIT, ctrl->val);
++ break;
++ case V4L2_CID_DIGITAL_GAIN:
++ ret = imx219_write_reg(imx219, IMX219_REG_DIGITAL_GAIN,
++ IMX219_REG_VALUE_16BIT, ctrl->val);
++ break;
++ case V4L2_CID_TEST_PATTERN:
++ ret = imx219_write_reg(imx219, IMX219_REG_TEST_PATTERN,
++ IMX219_REG_VALUE_16BIT, imx219_test_pattern_val[ctrl->val]);
++ break;
++ case V4L2_CID_HFLIP:
++ case V4L2_CID_VFLIP:
++ ret = imx219_write_reg(imx219, IMX219_REG_ORIENTATION, 1,
++ imx219->hflip->val | imx219->vflip->val << 1);
++ break;
++ case V4L2_CID_VBLANK:
++ ret = imx219_write_reg(imx219, IMX219_REG_VTS, IMX219_REG_VALUE_16BIT,
++ imx219->mode->height + ctrl->val);
++ break;
++ case V4L2_CID_TEST_PATTERN_RED:
++ ret = imx219_write_reg(imx219, IMX219_REG_TESTP_RED,
++ IMX219_REG_VALUE_16BIT, ctrl->val);
++ break;
++ case V4L2_CID_TEST_PATTERN_GREENR:
++ ret = imx219_write_reg(imx219, IMX219_REG_TESTP_GREENR,
++ IMX219_REG_VALUE_16BIT, ctrl->val);
++ break;
++ case V4L2_CID_TEST_PATTERN_BLUE:
++ ret = imx219_write_reg(imx219, IMX219_REG_TESTP_BLUE,
++ IMX219_REG_VALUE_16BIT, ctrl->val);
++ break;
++ case V4L2_CID_TEST_PATTERN_GREENB:
++ ret = imx219_write_reg(imx219, IMX219_REG_TESTP_GREENB,
++ IMX219_REG_VALUE_16BIT, ctrl->val);
++ 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_put(&client->dev);
++
++ return ret;
++}
++
++static const struct v4l2_ctrl_ops imx219_ctrl_ops = {
++ .s_ctrl = imx219_set_ctrl,
++};
++
++static int imx219_enum_mbus_code(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_mbus_code_enum *code)
++{
++ struct imx219 *imx219 = to_imx219(sd);
++
++ if (code->index >= (ARRAY_SIZE(codes) / 4))
++ return -EINVAL;
++
++ mutex_lock(&imx219->mutex);
++ code->code = imx219_get_format_code(imx219, codes[code->index * 4]);
++ mutex_unlock(&imx219->mutex);
++
++ return 0;
++}
++
++static int imx219_enum_frame_size(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_frame_size_enum *fse)
++{
++ struct imx219 *imx219 = to_imx219(sd);
++ u32 code;
++
++ if (fse->index >= ARRAY_SIZE(supported_modes))
++ return -EINVAL;
++
++ mutex_lock(&imx219->mutex);
++ code = imx219_get_format_code(imx219, fse->code);
++ mutex_unlock(&imx219->mutex);
++ if (fse->code != code)
++ return -EINVAL;
++
++ fse->min_width = supported_modes[fse->index].width;
++ fse->max_width = fse->min_width;
++ fse->min_height = supported_modes[fse->index].height;
++ fse->max_height = fse->min_height;
++
++ return 0;
++}
++
++static int imx219_try_frame_interval(struct imx219 *imx219,
++ struct v4l2_fract *fi,
++ u32 w, u32 h)
++{
++ const struct imx219_mode *mode;
++
++ mode = v4l2_find_nearest_size(supported_modes, ARRAY_SIZE(supported_modes),
++ width, height, w, h);
++ if (!mode || (mode->width != w || mode->height != h))
++ return -EINVAL;
++
++ fi->numerator = 1;
++ fi->denominator = mode->fps;
++
++ return mode->fps;
++}
++
++static int imx219_enum_frame_interval(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_frame_interval_enum *fie)
++{
++ struct imx219 *imx219 = to_imx219(sd);
++ struct v4l2_fract tpf;
++ u32 code;
++ int ret;
++
++ if (fie->index >= ARRAY_SIZE(supported_modes))
++ return -EINVAL;
++
++ mutex_lock(&imx219->mutex);
++ code = imx219_get_format_code(imx219, fie->code);
++ if (fie->code != code) {
++ ret = -EINVAL;
++ goto out;
++ }
++
++ ret = imx219_try_frame_interval(imx219, &tpf,
++ fie->width, fie->height);
++ if (ret < 0) {
++ ret = -EINVAL;
++ goto out;
++ }
++
++ mutex_unlock(&imx219->mutex);
++ fie->interval = tpf;
++
++ return 0;
++
++out:
++ mutex_unlock(&imx219->mutex);
++ return ret;
++}
++
++static int imx219_g_frame_interval(struct v4l2_subdev *sd,
++ struct v4l2_subdev_frame_interval *fi)
++{
++ struct imx219 *imx219 = to_imx219(sd);
++
++ mutex_lock(&imx219->mutex);
++ fi->interval = imx219->frame_interval;
++ mutex_unlock(&imx219->mutex);
++
++ return 0;
++}
++
++static int imx219_s_frame_interval(struct v4l2_subdev *sd,
++ struct v4l2_subdev_frame_interval *fi)
++{
++ struct imx219 *imx219 = to_imx219(sd);
++ const struct imx219_mode *mode = imx219->mode;
++ int frame_rate, ret = 0;
++
++ if (fi->pad != 0)
++ return -EINVAL;
++
++ mutex_lock(&imx219->mutex);
++
++ if (imx219->streaming) {
++ ret = -EBUSY;
++ goto out;
++ }
++
++ frame_rate = imx219_try_frame_interval(imx219, &fi->interval,
++ mode->width, mode->height);
++ if (frame_rate < 0) {
++ ret = -EINVAL;
++ goto out;
++ }
++
++ imx219->frame_interval = fi->interval;
++
++out:
++ mutex_unlock(&imx219->mutex);
++ return ret;
++}
++
++static void imx219_reset_colorspace(struct v4l2_mbus_framefmt *fmt)
++{
++ fmt->colorspace = V4L2_COLORSPACE_SRGB;
++ fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->colorspace);
++ fmt->quantization = V4L2_MAP_QUANTIZATION_DEFAULT(true,
++ fmt->colorspace, fmt->ycbcr_enc);
++ fmt->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(fmt->colorspace);
++}
++
++static void imx219_update_pad_format(struct imx219 *imx219,
++ const struct imx219_mode *mode,
++ struct v4l2_subdev_format *fmt)
++{
++ fmt->format.width = mode->width;
++ fmt->format.height = mode->height;
++ fmt->format.field = V4L2_FIELD_NONE;
++ imx219_reset_colorspace(&fmt->format);
++}
++
++static int __imx219_get_pad_format(struct imx219 *imx219,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_format *fmt)
++{
++ if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
++ struct v4l2_mbus_framefmt *try_fmt =
++ v4l2_subdev_get_try_format(&imx219->sd, state, fmt->pad);
++ /* update the code which could change due to vflip or hflip: */
++ try_fmt->code = imx219_get_format_code(imx219, try_fmt->code);
++ fmt->format = *try_fmt;
++ } else {
++ imx219_update_pad_format(imx219, imx219->mode, fmt);
++ fmt->format.code = imx219_get_format_code(imx219, imx219->fmt.code);
++ }
++
++ return 0;
++}
++
++static int imx219_get_pad_format(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_format *fmt)
++{
++ struct imx219 *imx219 = to_imx219(sd);
++ int ret;
++
++ mutex_lock(&imx219->mutex);
++ ret = __imx219_get_pad_format(imx219, state, fmt);
++ mutex_unlock(&imx219->mutex);
++
++ return ret;
++}
++
++static int imx219_set_pad_format(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_format *fmt)
++{
++ struct imx219 *imx219 = to_imx219(sd);
++ const struct imx219_mode *mode;
++ struct v4l2_mbus_framefmt *framefmt;
++ int exposure_max, exposure_def, hblank;
++ unsigned int i;
++
++ mutex_lock(&imx219->mutex);
++
++ for (i = 0; i < ARRAY_SIZE(codes); i++)
++ if (codes[i] == fmt->format.code)
++ break;
++ if (i >= ARRAY_SIZE(codes))
++ i = 0;
++
++ /* Bayer order varies with flips */
++ fmt->format.code = imx219_get_format_code(imx219, codes[i]);
++
++ mode = v4l2_find_nearest_size(supported_modes, ARRAY_SIZE(supported_modes),
++ width, height, fmt->format.width, fmt->format.height);
++ imx219_update_pad_format(imx219, mode, fmt);
++ if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
++ framefmt = v4l2_subdev_get_try_format(sd, state, fmt->pad);
++ *framefmt = fmt->format;
++ } else if (imx219->mode != mode ||
++ imx219->fmt.code != fmt->format.code) {
++ imx219->fmt = fmt->format;
++ imx219->mode = mode;
++ /* Update limits and set FPS to default */
++ __v4l2_ctrl_modify_range(imx219->vblank, IMX219_VBLANK_MIN,
++ IMX219_VTS_MAX - mode->height, 1,
++ mode->vts_def - mode->height);
++ __v4l2_ctrl_s_ctrl(imx219->vblank, mode->vts_def - mode->height);
++ /* Update max exposure while meeting expected vblanking */
++ exposure_max = mode->vts_def - 4;
++ exposure_def = (exposure_max < IMX219_EXPOSURE_DEFAULT) ?
++ exposure_max : IMX219_EXPOSURE_DEFAULT;
++ __v4l2_ctrl_modify_range(imx219->exposure, imx219->exposure->minimum,
++ exposure_max, imx219->exposure->step, exposure_def);
++ /*
++ * Currently PPL is fixed to IMX219_PPL_DEFAULT, so hblank
++ * depends on mode->width only, and is not changeble in any
++ * way other than changing the mode.
++ */
++ hblank = IMX219_PPL_DEFAULT - mode->width;
++ __v4l2_ctrl_modify_range(imx219->hblank, hblank, hblank, 1, hblank);
++ }
++
++ mutex_unlock(&imx219->mutex);
++
++ return 0;
++}
++
++static int imx219_set_framefmt(struct imx219 *imx219)
++{
++ switch (imx219->fmt.code) {
++ case MEDIA_BUS_FMT_SRGGB8_1X8:
++ case MEDIA_BUS_FMT_SGRBG8_1X8:
++ case MEDIA_BUS_FMT_SGBRG8_1X8:
++ case MEDIA_BUS_FMT_SBGGR8_1X8:
++ return imx219_write_regs(imx219, raw8_framefmt_regs,
++ ARRAY_SIZE(raw8_framefmt_regs));
++
++ case MEDIA_BUS_FMT_SRGGB10_1X10:
++ case MEDIA_BUS_FMT_SGRBG10_1X10:
++ case MEDIA_BUS_FMT_SGBRG10_1X10:
++ case MEDIA_BUS_FMT_SBGGR10_1X10:
++ return imx219_write_regs(imx219, raw10_framefmt_regs,
++ ARRAY_SIZE(raw10_framefmt_regs));
++ }
++
++ return -EINVAL;
++}
++
++static const struct v4l2_rect *
++__imx219_get_pad_crop(struct imx219 *imx219, struct v4l2_subdev_state *state,
++ unsigned int pad, enum v4l2_subdev_format_whence which)
++{
++ switch (which) {
++ case V4L2_SUBDEV_FORMAT_TRY:
++ return v4l2_subdev_get_try_crop(&imx219->sd, state, pad);
++ case V4L2_SUBDEV_FORMAT_ACTIVE:
++ return &imx219->mode->crop;
++ }
++
++ return NULL;
++}
++
++static int imx219_get_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_selection *sel)
++{
++ switch (sel->target) {
++ case V4L2_SEL_TGT_CROP: {
++ struct imx219 *imx219 = to_imx219(sd);
++
++ mutex_lock(&imx219->mutex);
++ sel->r = *__imx219_get_pad_crop(imx219, state, sel->pad, sel->which);
++ mutex_unlock(&imx219->mutex);
++ return 0;
++ }
++
++ case V4L2_SEL_TGT_NATIVE_SIZE:
++ sel->r.top = 0;
++ sel->r.left = 0;
++ sel->r.width = IMX219_NATIVE_WIDTH;
++ sel->r.height = IMX219_NATIVE_HEIGHT;
++ return 0;
++
++ case V4L2_SEL_TGT_CROP_DEFAULT:
++ case V4L2_SEL_TGT_CROP_BOUNDS:
++ sel->r.top = IMX219_PIXEL_ARRAY_TOP;
++ sel->r.left = IMX219_PIXEL_ARRAY_LEFT;
++ sel->r.width = IMX219_PIXEL_ARRAY_WIDTH;
++ sel->r.height = IMX219_PIXEL_ARRAY_HEIGHT;
++ return 0;
++ }
++
++ return -EINVAL;
++}
++
++static int imx219_start_streaming(struct imx219 *imx219)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd);
++ const struct imx219_reg_list *reg_list;
++ int ret;
++
++ /* Apply default values of current mode */
++ reg_list = &imx219->mode->reg_list;
++ ret = imx219_write_regs(imx219, reg_list->regs, reg_list->num_of_regs);
++ if (ret) {
++ dev_err(&client->dev, "%s failed to set mode\n", __func__);
++ goto err;
++ }
++
++ ret = imx219_set_framefmt(imx219);
++ if (ret) {
++ dev_err(&client->dev, "%s failed to set frame format: %d\n",
++ __func__, ret);
++ goto err;
++ }
++
++ /* Apply customized values from user */
++ ret = __v4l2_ctrl_handler_setup(imx219->sd.ctrl_handler);
++ if (ret)
++ goto err;
++
++ /* set stream on register */
++ ret = imx219_write_reg(imx219, IMX219_REG_MODE_SELECT,
++ IMX219_REG_VALUE_08BIT, IMX219_MODE_STREAMING);
++ if (ret)
++ goto err;
++
++ /* vflip and hflip cannot change during streaming */
++ __v4l2_ctrl_grab(imx219->vflip, true);
++ __v4l2_ctrl_grab(imx219->hflip, true);
++
++ return 0;
++
++err:
++ return ret;
++}
++
++static void imx219_stop_streaming(struct imx219 *imx219)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd);
++ int ret;
++
++ /* set stream off register */
++ ret = imx219_write_reg(imx219, IMX219_REG_MODE_SELECT,
++ IMX219_REG_VALUE_08BIT, IMX219_MODE_STANDBY);
++ if (ret)
++ dev_err(&client->dev, "%s failed to set stream\n", __func__);
++
++ __v4l2_ctrl_grab(imx219->vflip, false);
++ __v4l2_ctrl_grab(imx219->hflip, false);
++}
++
++static int imx219_set_stream(struct v4l2_subdev *sd, int enable)
++{
++ struct imx219 *imx219 = to_imx219(sd);
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ int ret = 0;
++
++ mutex_lock(&imx219->mutex);
++
++ if (enable) {
++ ret = pm_runtime_get_sync(&client->dev);
++ if (ret < 0) {
++ pm_runtime_put_noidle(&client->dev);
++ mutex_unlock(&imx219->mutex);
++ return ret;
++ }
++
++ if (imx219->streaming)
++ goto unlock;
++
++ /*
++ * Apply default & customized values
++ * and then start streaming.
++ */
++ ret = imx219_start_streaming(imx219);
++ if (ret)
++ goto err_unlock;
++ } else {
++ imx219_stop_streaming(imx219);
++ pm_runtime_put(&client->dev);
++ }
++
++unlock:
++ imx219->streaming += enable ? 1 : -1;
++ WARN_ON(imx219->streaming < 0);
++
++ mutex_unlock(&imx219->mutex);
++
++ return ret;
++
++err_unlock:
++ pm_runtime_put(&client->dev);
++ mutex_unlock(&imx219->mutex);
++
++ return ret;
++}
++
++/* Power/clock management functions */
++static int imx219_power_on(struct device *dev)
++{
++ struct v4l2_subdev *sd = dev_get_drvdata(dev);
++ struct imx219 *imx219 = to_imx219(sd);
++ int ret;
++
++ ret = regulator_bulk_enable(IMX219_NUM_SUPPLIES, imx219->supplies);
++ if (ret) {
++ dev_err(dev, "%s: failed to enable regulators\n",
++ __func__);
++ return ret;
++ }
++
++ ret = clk_prepare_enable(imx219->xclk);
++ if (ret) {
++ dev_err(dev, "%s: failed to enable clock\n", __func__);
++ goto reg_off;
++ }
++
++ gpiod_set_value_cansleep(imx219->reset_gpio, 1);
++ usleep_range(IMX219_XCLR_MIN_DELAY_US,
++ IMX219_XCLR_MIN_DELAY_US + IMX219_XCLR_DELAY_RANGE_US);
++
++ return 0;
++
++reg_off:
++ regulator_bulk_disable(IMX219_NUM_SUPPLIES, imx219->supplies);
++
++ return ret;
++}
++
++static int imx219_power_off(struct device *dev)
++{
++ struct v4l2_subdev *sd = dev_get_drvdata(dev);
++ struct imx219 *imx219 = to_imx219(sd);
++
++ gpiod_set_value_cansleep(imx219->reset_gpio, 0);
++ regulator_bulk_disable(IMX219_NUM_SUPPLIES, imx219->supplies);
++ clk_disable_unprepare(imx219->xclk);
++
++ return 0;
++}
++
++static int imx219_get_regulators(struct imx219 *imx219)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd);
++ unsigned int i;
++
++ for (i = 0; i < IMX219_NUM_SUPPLIES; i++)
++ imx219->supplies[i].supply = imx219_supply_name[i];
++
++ return devm_regulator_bulk_get(&client->dev,
++ IMX219_NUM_SUPPLIES, imx219->supplies);
++}
++
++/* Verify chip ID */
++static int imx219_identify_module(struct imx219 *imx219)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd);
++ int ret;
++ u32 val;
++
++ ret = imx219_read_reg(imx219, IMX219_REG_CHIP_ID,
++ IMX219_REG_VALUE_16BIT, &val);
++ if (ret) {
++ dev_err(&client->dev, "failed to read chip id %x\n",
++ IMX219_CHIP_ID);
++ return ret;
++ }
++
++ if (val != IMX219_CHIP_ID) {
++ dev_err(&client->dev, "chip id mismatch: %x!=%x\n",
++ IMX219_CHIP_ID, val);
++ return -EIO;
++ }
++
++ dev_err(&client->dev, "%s: chip identifier, got 0x%x\n",
++ __func__, IMX219_CHIP_ID);
++
++ return 0;
++}
++
++static const struct v4l2_subdev_core_ops imx219_core_ops = {
++ .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
++ .unsubscribe_event = v4l2_event_subdev_unsubscribe,
++};
++
++static const struct v4l2_subdev_video_ops imx219_video_ops = {
++ .g_frame_interval = imx219_g_frame_interval,
++ .s_frame_interval = imx219_s_frame_interval,
++ .s_stream = imx219_set_stream,
++};
++
++static const struct v4l2_subdev_pad_ops imx219_pad_ops = {
++ .enum_mbus_code = imx219_enum_mbus_code,
++ .get_fmt = imx219_get_pad_format,
++ .set_fmt = imx219_set_pad_format,
++ .get_selection = imx219_get_selection,
++ .enum_frame_size = imx219_enum_frame_size,
++ .enum_frame_interval = imx219_enum_frame_interval,
++};
++
++static const struct v4l2_subdev_ops imx219_subdev_ops = {
++ .core = &imx219_core_ops,
++ .video = &imx219_video_ops,
++ .pad = &imx219_pad_ops,
++};
++
++static const struct v4l2_subdev_internal_ops imx219_internal_ops = {
++ .open = imx219_open,
++};
++
++/* Initialize control handlers */
++static int imx219_init_controls(struct imx219 *imx219)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd);
++ struct v4l2_ctrl_handler *ctrl_hdlr;
++ unsigned int height = imx219->mode->height;
++ struct v4l2_fwnode_device_properties props;
++ int exposure_max, exposure_def, hblank;
++ int i, ret;
++
++ ctrl_hdlr = &imx219->ctrl_handler;
++ ret = v4l2_ctrl_handler_init(ctrl_hdlr, 12);
++ if (ret)
++ return ret;
++
++ mutex_init(&imx219->mutex);
++ ctrl_hdlr->lock = &imx219->mutex;
++
++ /* By default, PIXEL_RATE is read only */
++ imx219->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops,
++ V4L2_CID_PIXEL_RATE, IMX219_PIXEL_RATE,
++ IMX219_PIXEL_RATE, 1, IMX219_PIXEL_RATE);
++
++ imx219->link_freq =
++ v4l2_ctrl_new_int_menu(ctrl_hdlr, &imx219_ctrl_ops, V4L2_CID_LINK_FREQ,
++ ARRAY_SIZE(imx219_link_freq_menu) - 1, 0, imx219_link_freq_menu);
++ if (imx219->link_freq)
++ imx219->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
++
++ /* Initial vblank/hblank/exposure parameters based on current mode */
++ imx219->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops,
++ V4L2_CID_VBLANK, IMX219_VBLANK_MIN,
++ IMX219_VTS_MAX - height, 1,
++ imx219->mode->vts_def - height);
++ hblank = IMX219_PPL_DEFAULT - imx219->mode->width;
++ imx219->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops,
++ V4L2_CID_HBLANK, hblank, hblank, 1, hblank);
++ if (imx219->hblank)
++ imx219->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
++ exposure_max = imx219->mode->vts_def - 4;
++ exposure_def = (exposure_max < IMX219_EXPOSURE_DEFAULT) ?
++ exposure_max : IMX219_EXPOSURE_DEFAULT;
++ imx219->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops,
++ V4L2_CID_EXPOSURE, IMX219_EXPOSURE_MIN, exposure_max,
++ IMX219_EXPOSURE_STEP, exposure_def);
++
++ v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, V4L2_CID_ANALOGUE_GAIN,
++ IMX219_ANA_GAIN_MIN, IMX219_ANA_GAIN_MAX,
++ IMX219_ANA_GAIN_STEP, IMX219_ANA_GAIN_DEFAULT);
++
++ v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, V4L2_CID_DIGITAL_GAIN,
++ IMX219_DGTL_GAIN_MIN, IMX219_DGTL_GAIN_MAX,
++ IMX219_DGTL_GAIN_STEP, IMX219_DGTL_GAIN_DEFAULT);
++
++ imx219->hflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops,
++ V4L2_CID_HFLIP, 0, 1, 1, 0);
++ if (imx219->hflip)
++ imx219->hflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
++
++ imx219->vflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops,
++ V4L2_CID_VFLIP, 0, 1, 1, 0);
++ if (imx219->vflip)
++ imx219->vflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
++
++ v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &imx219_ctrl_ops, V4L2_CID_TEST_PATTERN,
++ ARRAY_SIZE(imx219_test_pattern_menu) - 1,
++ 0, 0, imx219_test_pattern_menu);
++ for (i = 0; i < 4; i++) {
++ /*
++ * The assumption is that
++ * V4L2_CID_TEST_PATTERN_GREENR == V4L2_CID_TEST_PATTERN_RED + 1
++ * V4L2_CID_TEST_PATTERN_BLUE == V4L2_CID_TEST_PATTERN_RED + 2
++ * V4L2_CID_TEST_PATTERN_GREENB == V4L2_CID_TEST_PATTERN_RED + 3
++ */
++ v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops,
++ V4L2_CID_TEST_PATTERN_RED + i,
++ IMX219_TESTP_COLOUR_MIN,
++ IMX219_TESTP_COLOUR_MAX,
++ IMX219_TESTP_COLOUR_STEP,
++ IMX219_TESTP_COLOUR_MAX);
++ /* The "Solid color" pattern is white by default */
++ }
++
++ 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, &imx219_ctrl_ops, &props);
++ if (ret)
++ goto error;
++
++ imx219->sd.ctrl_handler = ctrl_hdlr;
++
++ return 0;
++
++error:
++ v4l2_ctrl_handler_free(ctrl_hdlr);
++ mutex_destroy(&imx219->mutex);
++
++ return ret;
++}
++
++static void imx219_free_controls(struct imx219 *imx219)
++{
++ v4l2_ctrl_handler_free(imx219->sd.ctrl_handler);
++ mutex_destroy(&imx219->mutex);
++}
++
++static int imx219_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] != IMX219_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 imx219_probe(struct i2c_client *client)
++{
++ struct device *dev = &client->dev;
++ struct imx219 *imx219;
++ int ret;
++
++ imx219 = devm_kzalloc(&client->dev, sizeof(*imx219), GFP_KERNEL);
++ if (!imx219)
++ return -ENOMEM;
++
++ v4l2_i2c_subdev_init(&imx219->sd, client, &imx219_subdev_ops);
++
++ /* Check the hardware configuration in device tree */
++ if (imx219_check_hwcfg(dev))
++ return -EINVAL;
++
++ /* Get system clock (xclk) */
++ imx219->xclk = devm_clk_get(dev, NULL);
++ if (IS_ERR(imx219->xclk)) {
++ dev_err(dev, "failed to get xclk\n");
++ return PTR_ERR(imx219->xclk);
++ }
++
++ imx219->xclk_freq = clk_get_rate(imx219->xclk);
++ if (imx219->xclk_freq != IMX219_XCLK_FREQ) {
++ dev_err(dev, "xclk frequency not supported: %d Hz\n",
++ imx219->xclk_freq);
++ return -EINVAL;
++ }
++
++ ret = imx219_get_regulators(imx219);
++ if (ret) {
++ dev_err(dev, "failed to get regulators\n");
++ return ret;
++ }
++
++ /* Request optional enable pin */
++ imx219->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
++ usleep_range(IMX219_XCLR_MIN_DELAY_US,
++ IMX219_XCLR_MIN_DELAY_US + IMX219_XCLR_DELAY_RANGE_US);
++
++ /*
++ * The sensor must be powered for imx219_identify_module()
++ * to be able to read the CHIP_ID register
++ */
++ ret = imx219_power_on(dev);
++ if (ret)
++ return ret;
++
++ ret = imx219_identify_module(imx219);
++ if (ret)
++ goto error_power_off;
++
++ /* Set default mode to max resolution */
++ imx219->mode = &supported_modes[0];
++ imx219->frame_interval.numerator = 1;
++ imx219->frame_interval.denominator = supported_modes[0].fps;
++
++ /* sensor doesn't enter LP-11 state upon power up until and unless
++ * streaming is started, so upon power up switch the modes to:
++ * streaming -> standby
++ */
++ ret = imx219_write_reg(imx219, IMX219_REG_MODE_SELECT,
++ IMX219_REG_VALUE_08BIT, IMX219_MODE_STREAMING);
++ if (ret < 0)
++ goto error_power_off;
++ usleep_range(100, 110);
++
++ /* put sensor back to standby mode */
++ ret = imx219_write_reg(imx219, IMX219_REG_MODE_SELECT,
++ IMX219_REG_VALUE_08BIT, IMX219_MODE_STANDBY);
++ if (ret < 0)
++ goto error_power_off;
++ usleep_range(100, 110);
++
++ ret = imx219_init_controls(imx219);
++ if (ret)
++ goto error_power_off;
++
++ /* Initialize subdev */
++ imx219->sd.internal_ops = &imx219_internal_ops;
++ imx219->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
++ imx219->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
++
++ /* Initialize source pad */
++ imx219->pad.flags = MEDIA_PAD_FL_SOURCE;
++
++ /* Initialize default format */
++ imx219_set_default_format(imx219);
++
++ ret = media_entity_pads_init(&imx219->sd.entity, 1, &imx219->pad);
++ if (ret) {
++ dev_err(dev, "failed to init entity pads: %d\n", ret);
++ goto error_handler_free;
++ }
++
++ ret = v4l2_async_register_subdev_sensor(&imx219->sd);
++ if (ret < 0) {
++ dev_err(dev, "failed to register sensor sub-device: %d\n", ret);
++ goto error_media_entity;
++ }
++
++ /* Enable runtime PM and turn off the device */
++ pm_runtime_set_active(dev);
++ pm_runtime_enable(dev);
++ pm_runtime_idle(dev);
++
++ return 0;
++
++error_media_entity:
++ media_entity_cleanup(&imx219->sd.entity);
++
++error_handler_free:
++ imx219_free_controls(imx219);
++
++error_power_off:
++ imx219_power_off(dev);
++
++ return ret;
++}
++
++static void imx219_remove(struct i2c_client *client)
++{
++ struct v4l2_subdev *sd = i2c_get_clientdata(client);
++ struct imx219 *imx219 = to_imx219(sd);
++
++ v4l2_async_unregister_subdev(sd);
++ media_entity_cleanup(&sd->entity);
++ imx219_free_controls(imx219);
++
++ pm_runtime_disable(&client->dev);
++ if (!pm_runtime_status_suspended(&client->dev))
++ imx219_power_off(&client->dev);
++ pm_runtime_set_suspended(&client->dev);
++}
++
++static const struct of_device_id imx219_dt_ids[] = {
++ { .compatible = "sony,imx219" },
++ { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, imx219_dt_ids);
++
++static const struct dev_pm_ops imx219_pm_ops = {
++ SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume)
++ SET_RUNTIME_PM_OPS(imx219_power_off, imx219_power_on, NULL)
++};
++
++static struct i2c_driver imx219_i2c_driver = {
++ .driver = {
++ .name = "imx219",
++ .of_match_table = imx219_dt_ids,
++ .pm = &imx219_pm_ops,
++ },
++ .probe = imx219_probe,
++ .remove = imx219_remove,
++};
++
++module_i2c_driver(imx219_i2c_driver);
++
++MODULE_AUTHOR("Dave Stevenson <dave.stevenson@raspberrypi.com");
++MODULE_DESCRIPTION("Sony IMX219 sensor driver");
++MODULE_LICENSE("GPL v2");
+--- /dev/null
++++ b/drivers/media/platform/starfive/v4l2_driver/ov13850_mipi.c
+@@ -0,0 +1,1921 @@
++// SPDX-License-Identifier: GPL-2.0-or-later
++/*
++ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
++ *
++ */
++
++#include <linux/clk.h>
++#include <linux/clk-provider.h>
++#include <linux/clkdev.h>
++#include <linux/ctype.h>
++#include <linux/delay.h>
++#include <linux/device.h>
++#include <linux/gpio/consumer.h>
++#include <linux/i2c.h>
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/of_device.h>
++#include <linux/regulator/consumer.h>
++#include <linux/slab.h>
++#include <linux/types.h>
++#include <media/v4l2-async.h>
++#include <media/v4l2-ctrls.h>
++#include <media/v4l2-device.h>
++#include <media/v4l2-event.h>
++#include <media/v4l2-fwnode.h>
++#include <media/v4l2-subdev.h>
++#include "stfcamss.h"
++
++#define OV13850_XCLK_MIN 6000000
++#define OV13850_XCLK_MAX 54000000
++
++#define OV13850_LINK_FREQ_500MHZ 500000000LL
++
++/**
++ *OV13850 PLL
++ *
++ *PLL1:
++ *
++ *REF_CLK -> /PREDIVP[0] -> /PREDIV[2:0] -> *DIVP[9:8,7:0] -> /DIVM[3:0] -> /DIV_MIPI[1:0] -> PCLK
++ *(6-64M) 0x030A 0x0300 0x0301,0x302 0x0303 0x0304
++ * `-> MIPI_PHY_CLK
++ *
++ *
++ *PLL2:
++ * 000: 1
++ * 001: 1.5
++ * 010: 2
++ * 011: 2.5
++ * 100: 3
++ * 101: 4
++ * 0: /1 110: 6
++ * 1: /2 111: 8
++ *REF_CLK -> /PREDIVP[3] -> /PREDIV[2:0] -> /DIVP[9:0] -> /DIVDAC[3:0] -> DAC_CLK =
++ *(6~64M) 0x3611
++ * -> /DIVSP[3:0] -> /DIVS[2:0] -> SCLK
++ *
++ * -> /(1+DIVSRAM[3:0]) -> SRAM_CLK
++ */
++
++// PREDIVP
++#define OV13850_REG_PLL1_PREDIVP 0x030a
++#define OV13850_PREDIVP_1 0
++#define OV13850_PREDIVP_2 1
++
++// PREDIV
++#define OV13850_REG_PLL1_PREDIV 0x0300
++#define OV13850_PREDIV_1 0
++#define OV13850_PREDIV_1_5 1
++#define OV13850_PREDIV_2 2
++#define OV13850_PREDIV_2_5 3
++#define OV13850_PREDIV_3 4
++#define OV13850_PREDIV_4 5
++#define OV13850_PREDIV_6 6
++#define OV13850_PREDIV_8 7
++
++// DIVP
++#define OV13850_REG_PLL1_DIVP_H 0x0301
++#define OV13850_REG_PLL1_DIVP_L 0x0302
++#define OV13850_REG_PLL1_DIVP OV13850_REG_PLL1_DIVP_H
++
++// DIVM
++#define OV13850_REG_PLL1_DIVM 0x0303
++#define OV13850_DIVM(n) ((n)-1) // n=1~16
++
++// DIV_MIPI
++#define OV13850_REG_PLL1_DIV_MIPI 0x0304
++#define OV13850_DIV_MIPI_4 0
++#define OV13850_DIV_MIPI_5 1
++#define OV13850_DIV_MIPI_6 2
++#define OV13850_DIV_MIPI_8 3
++
++// system control
++#define OV13850_STREAM_CTRL 0x0100
++#define OV13850_REG_MIPI_SC 0x300f
++#define OV13850_MIPI_SC_8_BIT 0x0
++#define OV13850_MIPI_SC_10_BIT 0x1
++#define OV13850_MIPI_SC_12_BIT 0x2
++#define OV13850_GET_MIPI_SC_MIPI_BIT(v) ((v) & 0x3)
++#define OV13850_REG_MIPI_SC_CTRL0 0x3012
++#define OV13850_GET_MIPI_SC_CTRL0_LANE_NUM(v) ((v)>>4 & 0xf)
++
++// timing
++#define OV13850_REG_H_CROP_START_H 0x3800
++#define OV13850_REG_H_CROP_START_L 0x3801
++#define OV13850_REG_H_CROP_START OV13850_REG_H_CROP_START_H
++#define OV13850_REG_V_CROP_START_H 0x3802
++#define OV13850_REG_V_CROP_START_L 0x3803
++#define OV13850_REG_V_CROP_START OV13850_REG_V_CROP_START_H
++
++#define OV13850_REG_H_CROP_END_H 0x3804
++#define OV13850_REG_H_CROP_END_L 0x3805
++#define OV13850_REG_H_CROP_END OV13850_REG_H_CROP_END_H
++#define OV13850_REG_V_CROP_END_H 0x3806
++#define OV13850_REG_V_CROP_END_L 0x3807
++#define OV13850_REG_V_CROP_END OV13850_REG_V_CROP_END_H
++
++#define OV13850_REG_H_OUTPUT_SIZE_H 0x3808
++#define OV13850_REG_H_OUTPUT_SIZE_L 0x3809
++#define OV13850_REG_H_OUTPUT_SIZE OV13850_REG_H_OUTPUT_SIZE_H
++#define OV13850_REG_V_OUTPUT_SIZE_H 0x380a
++#define OV13850_REG_V_OUTPUT_SIZE_L 0x380b
++#define OV13850_REG_V_OUTPUT_SIZE OV13850_REG_V_OUTPUT_SIZE_H
++
++#define OV13850_REG_TIMING_HTS_H 0x380c
++#define OV13850_REG_TIMING_HTS_L 0x380d
++#define OV13850_REG_TIMING_HTS OV13850_REG_TIMING_HTS_H
++#define OV13850_REG_TIMING_VTS_H 0x380e
++#define OV13850_REG_TIMING_VTS_L 0x380f
++#define OV13850_REG_TIMING_VTS OV13850_REG_TIMING_VTS_H
++
++
++#define OV13850_REG_H_WIN_OFF_H 0x3810
++#define OV13850_REG_H_WIN_OFF_L 0x3811
++#define OV13850_REG_V_WIN_OFF_H 0x3812
++#define OV13850_REG_V_WIN_OFF_L 0x3813
++
++#define OV13850_REG_H_INC 0x3814
++#define OV13850_REG_V_INC 0x3815
++
++enum ov13850_mode_id {
++ OV13850_MODE_1080P_1920_1080 = 0,
++ OV13850_NUM_MODES,
++};
++
++enum ov13850_frame_rate {
++ OV13850_15_FPS = 0,
++ OV13850_30_FPS,
++ OV13850_60_FPS,
++ OV13850_NUM_FRAMERATES,
++};
++
++static const int ov13850_framerates[] = {
++ [OV13850_15_FPS] = 15,
++ [OV13850_30_FPS] = 30,
++ [OV13850_60_FPS] = 60,
++};
++
++struct ov13850_pixfmt {
++ u32 code;
++ u32 colorspace;
++};
++
++static const struct ov13850_pixfmt ov13850_formats[] = {
++ { MEDIA_BUS_FMT_SBGGR10_1X10, V4L2_COLORSPACE_SRGB, },
++ { MEDIA_BUS_FMT_SGBRG10_1X10, V4L2_COLORSPACE_SRGB, },
++ { MEDIA_BUS_FMT_SGRBG10_1X10, V4L2_COLORSPACE_SRGB, },
++ { MEDIA_BUS_FMT_SRGGB10_1X10, V4L2_COLORSPACE_SRGB, },
++};
++
++/* regulator supplies */
++static const char * const ov13850_supply_name[] = {
++ "DOVDD", /* Digital I/O (1.8V) supply */
++ "AVDD", /* Analog (2.8V) supply */
++ "DVDD", /* Digital Core (1.5V) supply */
++};
++
++#define OV13850_NUM_SUPPLIES ARRAY_SIZE(ov13850_supply_name)
++
++/*
++ * Image size under 1280 * 960 are SUBSAMPLING
++ * Image size upper 1280 * 960 are SCALING
++ */
++enum ov13850_downsize_mode {
++ SUBSAMPLING,
++ SCALING,
++};
++
++struct reg_value {
++ u16 reg_addr;
++ u8 val;
++ u8 mask;
++ u32 delay_ms;
++};
++
++struct ov13850_mode_info {
++ enum ov13850_mode_id id;
++ enum ov13850_downsize_mode dn_mode;
++ u32 hact;
++ u32 htot;
++ u32 vact;
++ u32 vtot;
++ const struct reg_value *reg_data;
++ u32 reg_data_size;
++ u32 max_fps;
++};
++
++struct ov13850_ctrls {
++ struct v4l2_ctrl_handler handler;
++ struct v4l2_ctrl *pixel_rate;
++ struct {
++ struct v4l2_ctrl *exposure;
++ };
++ struct {
++ struct v4l2_ctrl *auto_wb;
++ struct v4l2_ctrl *blue_balance;
++ struct v4l2_ctrl *red_balance;
++ };
++ struct {
++ struct v4l2_ctrl *anal_gain;
++ };
++ struct v4l2_ctrl *brightness;
++ struct v4l2_ctrl *light_freq;
++ struct v4l2_ctrl *link_freq;
++ struct v4l2_ctrl *saturation;
++ struct v4l2_ctrl *contrast;
++ struct v4l2_ctrl *hue;
++ struct v4l2_ctrl *test_pattern;
++ struct v4l2_ctrl *hflip;
++ struct v4l2_ctrl *vflip;
++};
++
++struct ov13850_dev {
++ struct i2c_client *i2c_client;
++ struct v4l2_subdev sd;
++ struct media_pad pad;
++ struct v4l2_fwnode_endpoint ep; /* the parsed DT endpoint info */
++ struct clk *xclk; /* system clock to OV13850 */
++ u32 xclk_freq;
++
++ struct regulator_bulk_data supplies[OV13850_NUM_SUPPLIES];
++ struct gpio_desc *reset_gpio;
++ struct gpio_desc *pwdn_gpio;
++ bool upside_down;
++
++ /* lock to protect all members below */
++ struct mutex lock;
++
++ int power_count;
++
++ struct v4l2_mbus_framefmt fmt;
++ bool pending_fmt_change;
++
++ const struct ov13850_mode_info *current_mode;
++ const struct ov13850_mode_info *last_mode;
++ enum ov13850_frame_rate current_fr;
++ struct v4l2_fract frame_interval;
++
++ struct ov13850_ctrls ctrls;
++
++ u32 prev_sysclk, prev_hts;
++ u32 ae_low, ae_high, ae_target;
++
++ bool pending_mode_change;
++ bool streaming;
++};
++
++static inline struct ov13850_dev *to_ov13850_dev(struct v4l2_subdev *sd)
++{
++ return container_of(sd, struct ov13850_dev, sd);
++}
++
++static inline struct v4l2_subdev *ctrl_to_sd(struct v4l2_ctrl *ctrl)
++{
++ return &container_of(ctrl->handler, struct ov13850_dev,
++ ctrls.handler)->sd;
++}
++
++/* ov13850 initial register */
++static const struct reg_value ov13850_init_setting_30fps_1080P[] = {
++
++};
++
++static const struct reg_value ov13850_setting_1080P_1920_1080[] = {
++//;XVCLK=24Mhz, SCLK=4x120Mhz, MIPI 640Mbps, DACCLK=240Mhz
++/*
++ * using quarter size to scale down
++ */
++ {0x0103, 0x01, 0, 0}, // ; software reset
++
++ {0x0300, 0x01, 0, 0}, //; PLL
++ {0x0301, 0x00, 0, 0}, //; PLL1_DIVP_hi
++ {0x0302, 0x28, 0, 0}, //; PLL1_DIVP_lo
++ {0x0303, 0x00, 0, 0}, // ; PLL
++ {0x030a, 0x00, 0, 0}, // ; PLL
++ //{0xffff, 20, 0, 0},
++ {0x300f, 0x11, 0, 0}, // SFC modified, MIPI_SRC, [1:0] 00-8bit, 01-10bit, 10-12bit
++ {0x3010, 0x01, 0, 0}, // ; MIPI PHY
++ {0x3011, 0x76, 0, 0}, // ; MIPI PHY
++ {0x3012, 0x41, 0, 0}, // ; MIPI 4 lane
++ {0x3013, 0x12, 0, 0}, // ; MIPI control
++ {0x3014, 0x11, 0, 0}, // ; MIPI control
++ {0x301f, 0x03, 0, 0}, //
++ {0x3106, 0x00, 0, 0}, //
++ {0x3210, 0x47, 0, 0}, //
++ {0x3500, 0x00, 0, 0}, // ; exposure HH
++ {0x3501, 0x67, 0, 0}, // ; exposure H
++ {0x3502, 0x80, 0, 0}, // ; exposure L
++ {0x3506, 0x00, 0, 0}, // ; short exposure HH
++ {0x3507, 0x02, 0, 0}, // ; short exposure H
++ {0x3508, 0x00, 0, 0}, // ; shour exposure L
++ {0x3509, 0x10, 0, 0},//00},//8},
++ {0x350a, 0x00, 0, 0}, // ; gain H
++ {0x350b, 0x10, 0, 0}, // ; gain L
++ {0x350e, 0x00, 0, 0}, // ; short gain H
++ {0x350f, 0x10, 0, 0}, // ; short gain L
++ {0x3600, 0x40, 0, 0}, // ; analog control
++ {0x3601, 0xfc, 0, 0}, // ; analog control
++ {0x3602, 0x02, 0, 0}, // ; analog control
++ {0x3603, 0x48, 0, 0}, // ; analog control
++ {0x3604, 0xa5, 0, 0}, // ; analog control
++ {0x3605, 0x9f, 0, 0}, // ; analog control
++ {0x3607, 0x00, 0, 0}, // ; analog control
++ {0x360a, 0x40, 0, 0}, // ; analog control
++ {0x360b, 0x91, 0, 0}, // ; analog control
++ {0x360c, 0x49, 0, 0}, // ; analog control
++ {0x360f, 0x8a, 0, 0}, //
++ {0x3611, 0x10, 0, 0}, // ; PLL2
++ //{0x3612, 0x23, 0, 0}, // ; PLL2
++ {0x3612, 0x13, 0, 0}, // ; PLL2
++ //{0x3613, 0x33, 0, 0}, // ; PLL2
++ {0x3613, 0x22, 0, 0}, // ; PLL2
++ //{0xffff, 50, 0, 0},
++ {0x3614, 0x28, 0, 0}, //[7:0] PLL2_DIVP lo
++ {0x3615, 0x08, 0, 0}, //[7:6] Debug mode, [5:4] N_pump clock div, [3:2] P_pump clock div, [1:0] PLL2_DIVP hi
++ {0x3641, 0x02, 0, 0},
++ {0x3660, 0x82, 0, 0},
++ {0x3668, 0x54, 0, 0},
++ {0x3669, 0x40, 0, 0},
++ {0x3667, 0xa0, 0, 0},
++ {0x3702, 0x40, 0, 0},
++ {0x3703, 0x44, 0, 0},
++ {0x3704, 0x2c, 0, 0},
++ {0x3705, 0x24, 0, 0},
++ {0x3706, 0x50, 0, 0},
++ {0x3707, 0x44, 0, 0},
++ {0x3708, 0x3c, 0, 0},
++ {0x3709, 0x1f, 0, 0},
++ {0x370a, 0x26, 0, 0},
++ {0x370b, 0x3c, 0, 0},
++ {0x3720, 0x66, 0, 0},
++ {0x3722, 0x84, 0, 0},
++ {0x3728, 0x40, 0, 0},
++ {0x372a, 0x00, 0, 0},
++ {0x372f, 0x90, 0, 0},
++ {0x3710, 0x28, 0, 0},
++ {0x3716, 0x03, 0, 0},
++ {0x3718, 0x10, 0, 0},
++ {0x3719, 0x08, 0, 0},
++ {0x371c, 0xfc, 0, 0},
++ {0x3760, 0x13, 0, 0},
++ {0x3761, 0x34, 0, 0},
++ {0x3767, 0x24, 0, 0},
++ {0x3768, 0x06, 0, 0},
++ {0x3769, 0x45, 0, 0},
++ {0x376c, 0x23, 0, 0},
++ {0x3d84, 0x00, 0, 0}, // ; OTP program disable
++ {0x3d85, 0x17, 0, 0}, // ; OTP power up load data enable, power load setting enable, software load setting
++ {0x3d8c, 0x73, 0, 0}, // ; OTP start address H
++ {0x3d8d, 0xbf, 0, 0}, // ; OTP start address L
++ {0x3800, 0x00, 0, 0}, // ; H crop start H
++ {0x3801, 0x08, 0, 0}, // ; H crop start L
++ {0x3802, 0x00, 0, 0}, // ; V crop start H
++ {0x3803, 0x04, 0, 0}, // ; V crop start L
++ {0x3804, 0x10, 0, 0}, // ; H crop end H
++ {0x3805, 0x97, 0, 0}, // ; H crop end L
++ {0x3806, 0x0c, 0, 0}, // ; V crop end H
++ {0x3807, 0x4b, 0, 0}, // ; V crop end L
++ {0x3808, 0x08, 0, 0}, // ; H output size H
++ {0x3809, 0x40, 0, 0}, // ; H output size L
++ {0x380a, 0x06, 0, 0}, // ; V output size H
++ {0x380b, 0x20, 0, 0}, // ; V output size L
++ {0x380c, 0x25, 0, 0}, // ; HTS H
++ {0x380d, 0x80, 0, 0}, // ; HTS L
++ {0x380e, 0x06, 0, 0}, // ; VTS H
++ {0x380f, 0x80, 0, 0}, // ; VTS L
++ {0x3810, 0x00, 0, 0}, // ; H win off H
++ {0x3811, 0x04, 0, 0}, // ; H win off L
++ {0x3812, 0x00, 0, 0}, // ; V win off H
++ {0x3813, 0x02, 0, 0}, // ; V win off L
++ {0x3814, 0x31, 0, 0}, // ; H inc
++ {0x3815, 0x31, 0, 0}, // ; V inc
++ {0x3820, 0x02, 0, 0}, // ; V flip off, V bin on
++ {0x3821, 0x05, 0, 0}, // ; H mirror on, H bin on
++ {0x3834, 0x00, 0, 0}, //
++ {0x3835, 0x1c, 0, 0}, // ; cut_en, vts_auto, blk_col_dis
++ {0x3836, 0x08, 0, 0}, //
++ {0x3837, 0x02, 0, 0}, //
++ {0x4000, 0xf1, 0, 0},//c1}, // ; BLC offset trig en, format change trig en, gain trig en, exp trig en, median en
++ {0x4001, 0x00, 0, 0}, // ; BLC
++ {0x400b, 0x0c, 0, 0}, // ; BLC
++ {0x4011, 0x00, 0, 0}, // ; BLC
++ {0x401a, 0x00, 0, 0}, // ; BLC
++ {0x401b, 0x00, 0, 0}, // ; BLC
++ {0x401c, 0x00, 0, 0}, // ; BLC
++ {0x401d, 0x00, 0, 0}, // ; BLC
++ {0x4020, 0x00, 0, 0}, // ; BLC
++ {0x4021, 0xe4, 0, 0}, // ; BLC
++ {0x4022, 0x07, 0, 0}, // ; BLC
++ {0x4023, 0x5f, 0, 0}, // ; BLC
++ {0x4024, 0x08, 0, 0}, // ; BLC
++ {0x4025, 0x44, 0, 0}, // ; BLC
++ {0x4026, 0x08, 0, 0}, // ; BLC
++ {0x4027, 0x47, 0, 0}, // ; BLC
++ {0x4028, 0x00, 0, 0}, // ; BLC
++ {0x4029, 0x02, 0, 0}, // ; BLC
++ {0x402a, 0x04, 0, 0}, // ; BLC
++ {0x402b, 0x08, 0, 0}, // ; BLC
++ {0x402c, 0x02, 0, 0}, // ; BLC
++ {0x402d, 0x02, 0, 0}, // ; BLC
++ {0x402e, 0x0c, 0, 0}, // ; BLC
++ {0x402f, 0x08, 0, 0}, // ; BLC
++ {0x403d, 0x2c, 0, 0}, //
++ {0x403f, 0x7f, 0, 0}, //
++ {0x4500, 0x82, 0, 0}, // ; BLC
++ {0x4501, 0x38, 0, 0}, // ; BLC
++ {0x4601, 0x04, 0, 0}, //
++ {0x4602, 0x22, 0, 0}, //
++ {0x4603, 0x01, 0, 0}, //; VFIFO
++ {0x4837, 0x19, 0, 0}, //; MIPI global timing
++ {0x4d00, 0x04, 0, 0}, // ; temperature monitor
++ {0x4d01, 0x42, 0, 0}, // ; temperature monitor
++ {0x4d02, 0xd1, 0, 0}, // ; temperature monitor
++ {0x4d03, 0x90, 0, 0}, // ; temperature monitor
++ {0x4d04, 0x66, 0, 0}, // ; temperature monitor
++ {0x4d05, 0x65, 0, 0}, // ; temperature monitor
++ {0x5000, 0x0e, 0, 0}, // ; windowing enable, BPC on, WPC on, Lenc on
++ {0x5001, 0x03, 0, 0}, // ; BLC enable, MWB on
++ {0x5002, 0x07, 0, 0}, //
++ {0x5013, 0x40, 0, 0},
++ {0x501c, 0x00, 0, 0},
++ {0x501d, 0x10, 0, 0},
++ //{0x5057, 0x56, 0, 0},//add
++ {0x5056, 0x08, 0, 0},
++ {0x5058, 0x08, 0, 0},
++ {0x505a, 0x08, 0, 0},
++ {0x5242, 0x00, 0, 0},
++ {0x5243, 0xb8, 0, 0},
++ {0x5244, 0x00, 0, 0},
++ {0x5245, 0xf9, 0, 0},
++ {0x5246, 0x00, 0, 0},
++ {0x5247, 0xf6, 0, 0},
++ {0x5248, 0x00, 0, 0},
++ {0x5249, 0xa6, 0, 0},
++ {0x5300, 0xfc, 0, 0},
++ {0x5301, 0xdf, 0, 0},
++ {0x5302, 0x3f, 0, 0},
++ {0x5303, 0x08, 0, 0},
++ {0x5304, 0x0c, 0, 0},
++ {0x5305, 0x10, 0, 0},
++ {0x5306, 0x20, 0, 0},
++ {0x5307, 0x40, 0, 0},
++ {0x5308, 0x08, 0, 0},
++ {0x5309, 0x08, 0, 0},
++ {0x530a, 0x02, 0, 0},
++ {0x530b, 0x01, 0, 0},
++ {0x530c, 0x01, 0, 0},
++ {0x530d, 0x0c, 0, 0},
++ {0x530e, 0x02, 0, 0},
++ {0x530f, 0x01, 0, 0},
++ {0x5310, 0x01, 0, 0},
++ {0x5400, 0x00, 0, 0},
++ {0x5401, 0x61, 0, 0},
++ {0x5402, 0x00, 0, 0},
++ {0x5403, 0x00, 0, 0},
++ {0x5404, 0x00, 0, 0},
++ {0x5405, 0x40, 0, 0},
++ {0x540c, 0x05, 0, 0},
++ {0x5b00, 0x00, 0, 0},
++ {0x5b01, 0x00, 0, 0},
++ {0x5b02, 0x01, 0, 0},
++ {0x5b03, 0xff, 0, 0},
++ {0x5b04, 0x02, 0, 0},
++ {0x5b05, 0x6c, 0, 0},
++ {0x5b09, 0x02, 0, 0}, //
++ //{0x5e00, 0x00, 0, 0}, // ; test pattern disable
++ //{0x5e00, 0x80, 0, 0}, // ; test pattern enable
++ {0x5e10, 0x1c, 0, 0}, // ; ISP test disable
++
++ //{0x0300, 0x01, 0, 0},// ; PLL
++ //{0x0302, 0x28, 0, 0},// ; PLL
++ //{0xffff, 50, 0, 0},
++ {0x3501, 0x67, 0, 0},// ; Exposure H
++ {0x370a, 0x26, 0, 0},//
++ {0x372a, 0x00, 0, 0},
++ {0x372f, 0x90, 0, 0},
++ {0x3801, 0x08, 0, 0}, //; H crop start L
++ {0x3803, 0x04, 0, 0}, //; V crop start L
++ {0x3805, 0x97, 0, 0}, //; H crop end L
++ {0x3807, 0x4b, 0, 0}, //; V crop end L
++ {0x3808, 0x08, 0, 0}, //; H output size H
++ {0x3809, 0x40, 0, 0}, //; H output size L
++ {0x380a, 0x06, 0, 0}, //; V output size H
++ {0x380b, 0x20, 0, 0}, //; V output size L
++ {0x380c, 0x25, 0, 0}, //; HTS H
++ {0x380d, 0x80, 0, 0}, //; HTS L
++ {0x380e, 0x0a, 0, 0},//6}, //; VTS H
++ {0x380f, 0x80, 0, 0}, //; VTS L
++ {0x3813, 0x02, 0, 0}, //; V win off
++ {0x3814, 0x31, 0, 0}, //; H inc
++ {0x3815, 0x31, 0, 0}, //; V inc
++ {0x3820, 0x02, 0, 0}, //; V flip off, V bin on
++ {0x3821, 0x05, 0, 0}, //; H mirror on, H bin on
++ {0x3836, 0x08, 0, 0}, //
++ {0x3837, 0x02, 0, 0}, //
++ {0x4020, 0x00, 0, 0}, //
++ {0x4021, 0xe4, 0, 0}, //
++ {0x4022, 0x07, 0, 0}, //
++ {0x4023, 0x5f, 0, 0}, //
++ {0x4024, 0x08, 0, 0}, //
++ {0x4025, 0x44, 0, 0}, //
++ {0x4026, 0x08, 0, 0}, //
++ {0x4027, 0x47, 0, 0}, //
++ {0x4603, 0x01, 0, 0}, //; VFIFO
++ {0x4837, 0x19, 0, 0}, //; MIPI global timing
++ {0x4802, 0x42, 0, 0}, //default 0x00
++ {0x481a, 0x00, 0, 0},
++ {0x481b, 0x1c, 0, 0}, //default 0x3c prepare
++ {0x4826, 0x12, 0, 0}, //default 0x32 trail
++ {0x5401, 0x61, 0, 0}, //
++ {0x5405, 0x40, 0, 0}, //
++
++ //{0xffff, 200, 0, 0},
++ //{0xffff, 200, 0, 0},
++ //{0xffff, 200, 0, 0},
++
++ //{0x0100, 0x01, 0, 0}, //; wake up, streaming
++};
++
++/* power-on sensor init reg table */
++static const struct ov13850_mode_info ov13850_mode_init_data = {
++ OV13850_MODE_1080P_1920_1080, SCALING,
++ 1920, 0x6e0, 1080, 0x470,
++ ov13850_init_setting_30fps_1080P,
++ ARRAY_SIZE(ov13850_init_setting_30fps_1080P),
++ OV13850_30_FPS,
++};
++
++static const struct ov13850_mode_info
++ov13850_mode_data[OV13850_NUM_MODES] = {
++ {OV13850_MODE_1080P_1920_1080, SCALING,
++ 1920, 0x6e0, 1080, 0x470,
++ ov13850_setting_1080P_1920_1080,
++ ARRAY_SIZE(ov13850_setting_1080P_1920_1080),
++ OV13850_30_FPS},
++};
++
++static int ov13850_write_reg(struct ov13850_dev *sensor, u16 reg, u8 val)
++{
++ struct i2c_client *client = sensor->i2c_client;
++ struct i2c_msg msg;
++ u8 buf[3];
++ int ret;
++
++ buf[0] = reg >> 8;
++ buf[1] = reg & 0xff;
++ buf[2] = val;
++
++ msg.addr = client->addr;
++ msg.flags = client->flags;
++ msg.buf = buf;
++ msg.len = sizeof(buf);
++
++ ret = i2c_transfer(client->adapter, &msg, 1);
++ if (ret < 0) {
++ dev_err(&client->dev, "%s: error: reg=%x, val=%x\n",
++ __func__, reg, val);
++ return ret;
++ }
++
++ return 0;
++}
++
++static int ov13850_read_reg(struct ov13850_dev *sensor, u16 reg, u8 *val)
++{
++ struct i2c_client *client = sensor->i2c_client;
++ struct i2c_msg msg[2];
++ u8 buf[2];
++ int ret;
++
++ buf[0] = reg >> 8;
++ buf[1] = reg & 0xff;
++
++ msg[0].addr = client->addr;
++ msg[0].flags = client->flags;
++ msg[0].buf = buf;
++ msg[0].len = sizeof(buf);
++
++ msg[1].addr = client->addr;
++ msg[1].flags = client->flags | I2C_M_RD;
++ msg[1].buf = buf;
++ msg[1].len = 1;
++
++ ret = i2c_transfer(client->adapter, msg, 2);
++ if (ret < 0) {
++ dev_err(&client->dev, "%s: error: reg=%x\n",
++ __func__, reg);
++ return ret;
++ }
++
++ *val = buf[0];
++ return 0;
++}
++
++static int ov13850_read_reg16(struct ov13850_dev *sensor, u16 reg, u16 *val)
++{
++ u8 hi, lo;
++ int ret;
++
++ ret = ov13850_read_reg(sensor, reg, &hi);
++ if (ret)
++ return ret;
++ ret = ov13850_read_reg(sensor, reg + 1, &lo);
++ if (ret)
++ return ret;
++
++ *val = ((u16)hi << 8) | (u16)lo;
++ return 0;
++}
++
++static int ov13850_write_reg16(struct ov13850_dev *sensor, u16 reg, u16 val)
++{
++ int ret;
++
++ ret = ov13850_write_reg(sensor, reg, val >> 8);
++ if (ret)
++ return ret;
++
++ return ov13850_write_reg(sensor, reg + 1, val & 0xff);
++}
++
++static int ov13850_mod_reg(struct ov13850_dev *sensor, u16 reg,
++ u8 mask, u8 val)
++{
++ u8 readval;
++ int ret;
++
++ ret = ov13850_read_reg(sensor, reg, &readval);
++ if (ret)
++ return ret;
++
++ readval &= ~mask;
++ val &= mask;
++ val |= readval;
++
++ return ov13850_write_reg(sensor, reg, val);
++}
++
++static int ov13850_set_timings(struct ov13850_dev *sensor,
++ const struct ov13850_mode_info *mode)
++{
++ int ret;
++
++ ret = ov13850_write_reg16(sensor, OV13850_REG_H_OUTPUT_SIZE, mode->hact);
++ if (ret < 0)
++ return ret;
++
++ ret = ov13850_write_reg16(sensor, OV13850_REG_V_OUTPUT_SIZE, mode->vact);
++ if (ret < 0)
++ return ret;
++
++ return 0;
++}
++
++static int ov13850_load_regs(struct ov13850_dev *sensor,
++ const struct ov13850_mode_info *mode)
++{
++ const struct reg_value *regs = mode->reg_data;
++ unsigned int i;
++ u32 delay_ms;
++ u16 reg_addr;
++ u8 mask, val;
++ int ret = 0;
++
++ st_info(ST_SENSOR, "%s, mode = 0x%x\n", __func__, mode->id);
++ for (i = 0; i < mode->reg_data_size; ++i, ++regs) {
++ delay_ms = regs->delay_ms;
++ reg_addr = regs->reg_addr;
++ val = regs->val;
++ mask = regs->mask;
++
++ if (mask)
++ ret = ov13850_mod_reg(sensor, reg_addr, mask, val);
++ else
++ ret = ov13850_write_reg(sensor, reg_addr, val);
++ if (ret)
++ break;
++
++ if (delay_ms)
++ usleep_range(1000 * delay_ms, 1000 * delay_ms + 100);
++ }
++
++ return ov13850_set_timings(sensor, mode);
++}
++
++
++
++static int ov13850_get_gain(struct ov13850_dev *sensor)
++{
++ u32 gain = 0;
++ return gain;
++}
++
++static int ov13850_set_gain(struct ov13850_dev *sensor, int gain)
++{
++ return 0;
++}
++
++static int ov13850_set_stream_mipi(struct ov13850_dev *sensor, bool on)
++{
++ return 0;
++}
++
++static int ov13850_get_sysclk(struct ov13850_dev *sensor)
++{
++ return 0;
++}
++
++static int ov13850_set_night_mode(struct ov13850_dev *sensor)
++{
++ return 0;
++}
++
++static int ov13850_get_hts(struct ov13850_dev *sensor)
++{
++ /* read HTS from register settings */
++ u16 hts;
++ int ret;
++
++ ret = ov13850_read_reg16(sensor, OV13850_REG_TIMING_HTS, &hts);
++ if (ret)
++ return ret;
++ return hts;
++}
++
++static int ov13850_set_hts(struct ov13850_dev *sensor, int hts)
++{
++ return ov13850_write_reg16(sensor, OV13850_REG_TIMING_HTS, hts);
++}
++
++
++static int ov13850_get_vts(struct ov13850_dev *sensor)
++{
++ u16 vts;
++ int ret;
++
++ ret = ov13850_read_reg16(sensor, OV13850_REG_TIMING_VTS, &vts);
++ if (ret)
++ return ret;
++ return vts;
++}
++
++static int ov13850_set_vts(struct ov13850_dev *sensor, int vts)
++{
++ return ov13850_write_reg16(sensor, OV13850_REG_TIMING_VTS, vts);
++}
++
++static int ov13850_get_light_freq(struct ov13850_dev *sensor)
++{
++ return 0;
++}
++
++static int ov13850_set_bandingfilter(struct ov13850_dev *sensor)
++{
++ return 0;
++}
++
++static int ov13850_set_ae_target(struct ov13850_dev *sensor, int target)
++{
++ return 0;
++}
++
++static int ov13850_get_binning(struct ov13850_dev *sensor)
++{
++ return 0;
++}
++
++static int ov13850_set_binning(struct ov13850_dev *sensor, bool enable)
++{
++ return 0;
++}
++
++static const struct ov13850_mode_info *
++ov13850_find_mode(struct ov13850_dev *sensor, enum ov13850_frame_rate fr,
++ int width, int height, bool nearest)
++{
++ const struct ov13850_mode_info *mode;
++
++ mode = v4l2_find_nearest_size(ov13850_mode_data,
++ ARRAY_SIZE(ov13850_mode_data),
++ hact, vact,
++ width, height);
++
++ if (!mode ||
++ (!nearest && (mode->hact != width || mode->vact != height)))
++ return NULL;
++
++ /* Check to see if the current mode exceeds the max frame rate */
++ if (ov13850_framerates[fr] > ov13850_framerates[mode->max_fps])
++ return NULL;
++
++ return mode;
++}
++
++static u64 ov13850_calc_pixel_rate(struct ov13850_dev *sensor)
++{
++ u64 rate;
++
++ rate = sensor->current_mode->vact * sensor->current_mode->hact;
++ rate *= ov13850_framerates[sensor->current_fr];
++
++ return rate;
++}
++
++/*
++ * After trying the various combinations, reading various
++ * documentations spread around the net, and from the various
++ * feedback, the clock tree is probably as follows:
++ *
++ * +--------------+
++ * | Ext. Clock |
++ * +-+------------+
++ * | +----------+
++ * +->| PLL1 | - reg 0x030a, bit0 for the pre-dividerp
++ * +-+--------+ - reg 0x0300, bits 0-2 for the pre-divider
++ * +-+--------+ - reg 0x0301~0x0302, for the multiplier
++ * | +--------------+
++ * +->| MIPI Divider | - reg 0x0303, bits 0-3 for the pre-divider
++ * | +---------> MIPI PHY CLK
++ * | +-----+
++ * | +->| PLL1_DIV_MIPI | - reg 0x0304, bits 0-1 for the divider
++ * | +----------------> PCLK
++ * | +-----+
++ *
++ * +--------------+
++ * | Ext. Clock |
++ * +-+------------+
++ * | +----------+
++ * +->| PLL2 | - reg 0x0311, bit0 for the pre-dividerp
++ * +-+--------+ - reg 0x030b, bits 0-2 for the pre-divider
++ * +-+--------+ - reg 0x030c~0x030d, for the multiplier
++ * | +--------------+
++ * +->| SCLK Divider | - reg 0x030F, bits 0-3 for the pre-divider
++ * +-+--------+ - reg 0x030E, bits 0-2 for the divider
++ * | +---------> SCLK
++ *
++ * | +-----+
++ * +->| DAC Divider | - reg 0x0312, bits 0-3 for the divider
++ * | +----------------> DACCLK
++ **
++ */
++
++/*
++ * ov13850_set_mipi_pclk() - Calculate the clock tree configuration values
++ * for the MIPI CSI-2 output.
++ *
++ * @rate: The requested bandwidth per lane in bytes per second.
++ * 'Bandwidth Per Lane' is calculated as:
++ * bpl = HTOT * VTOT * FPS * bpp / num_lanes;
++ *
++ * This function use the requested bandwidth to calculate:
++ *
++ * - mipi_pclk = bpl / 2; ( / 2 is for CSI-2 DDR)
++ * - mipi_phy_clk = mipi_pclk * PLL1_DIV_MIPI;
++ *
++ * with these fixed parameters:
++ * PLL1_PREDIVP = 1;
++ * PLL1_PREDIV = 1; (MIPI_BIT_MODE == 8 ? 2 : 2,5);
++ * PLL1_DIVM = 1;
++ * PLL1_DIV_MIPI = 4;
++ *
++ * FIXME: this have been tested with 10-bit raw and 2 lanes setup only.
++ * MIPI_DIV is fixed to value 2, but it -might- be changed according to the
++ * above formula for setups with 1 lane or image formats with different bpp.
++ *
++ * FIXME: this deviates from the sensor manual documentation which is quite
++ * thin on the MIPI clock tree generation part.
++ */
++
++
++
++static int ov13850_set_mipi_pclk(struct ov13850_dev *sensor,
++ unsigned long rate)
++{
++
++ return 0;
++}
++
++/*
++ * if sensor changes inside scaling or subsampling
++ * change mode directly
++ */
++static int ov13850_set_mode_direct(struct ov13850_dev *sensor,
++ const struct ov13850_mode_info *mode)
++{
++ if (!mode->reg_data)
++ return -EINVAL;
++
++ /* Write capture setting */
++ return ov13850_load_regs(sensor, mode);
++}
++
++static int ov13850_set_mode(struct ov13850_dev *sensor)
++{
++ const struct ov13850_mode_info *mode = sensor->current_mode;
++ const struct ov13850_mode_info *orig_mode = sensor->last_mode;
++ int ret = 0;
++
++ ret = ov13850_set_mode_direct(sensor, mode);
++ if (ret < 0)
++ return ret;
++
++ /*
++ * we support have 10 bits raw RGB(mipi)
++ */
++ if (sensor->ep.bus_type == V4L2_MBUS_CSI2_DPHY)
++ ret = ov13850_set_mipi_pclk(sensor, 0);
++
++ if (ret < 0)
++ return 0;
++
++ sensor->pending_mode_change = false;
++ sensor->last_mode = mode;
++ return 0;
++}
++
++static int ov13850_set_framefmt(struct ov13850_dev *sensor,
++ struct v4l2_mbus_framefmt *format);
++
++/* restore the last set video mode after chip power-on */
++static int ov13850_restore_mode(struct ov13850_dev *sensor)
++{
++ int ret;
++
++ /* first load the initial register values */
++ ret = ov13850_load_regs(sensor, &ov13850_mode_init_data);
++ if (ret < 0)
++ return ret;
++ sensor->last_mode = &ov13850_mode_init_data;
++
++ /* now restore the last capture mode */
++ ret = ov13850_set_mode(sensor);
++ if (ret < 0)
++ return ret;
++
++ return ov13850_set_framefmt(sensor, &sensor->fmt);
++}
++
++static void ov13850_power(struct ov13850_dev *sensor, bool enable)
++{
++ if (!sensor->pwdn_gpio)
++ return;
++ if (enable) {
++ gpiod_set_value_cansleep(sensor->pwdn_gpio, 0);
++ gpiod_set_value_cansleep(sensor->pwdn_gpio, 1);
++ } else {
++ gpiod_set_value_cansleep(sensor->pwdn_gpio, 0);
++ }
++
++ mdelay(100);
++}
++
++static void ov13850_reset(struct ov13850_dev *sensor)
++{
++ if (!sensor->reset_gpio)
++ return;
++
++ gpiod_set_value_cansleep(sensor->reset_gpio, 0);
++ gpiod_set_value_cansleep(sensor->reset_gpio, 1);
++ mdelay(100);
++}
++
++static int ov13850_set_power_on(struct ov13850_dev *sensor)
++{
++ struct i2c_client *client = sensor->i2c_client;
++ int ret;
++
++ ret = clk_prepare_enable(sensor->xclk);
++ if (ret) {
++ dev_err(&client->dev, "%s: failed to enable clock\n",
++ __func__);
++ return ret;
++ }
++
++ ret = regulator_bulk_enable(OV13850_NUM_SUPPLIES,
++ sensor->supplies);
++ if (ret) {
++ dev_err(&client->dev, "%s: failed to enable regulators\n",
++ __func__);
++ goto xclk_off;
++ }
++
++ ov13850_reset(sensor);
++ ov13850_power(sensor, true);
++
++ return 0;
++
++xclk_off:
++ clk_disable_unprepare(sensor->xclk);
++ return ret;
++}
++
++static void ov13850_set_power_off(struct ov13850_dev *sensor)
++{
++ ov13850_power(sensor, false);
++ regulator_bulk_disable(OV13850_NUM_SUPPLIES, sensor->supplies);
++ clk_disable_unprepare(sensor->xclk);
++}
++
++static int ov13850_set_power_mipi(struct ov13850_dev *sensor, bool on)
++{
++ return 0;
++}
++
++static int ov13850_set_power(struct ov13850_dev *sensor, bool on)
++{
++ int ret = 0;
++ u16 chip_id;
++
++ if (on) {
++ ret = ov13850_set_power_on(sensor);
++ if (ret)
++ return ret;
++
++#ifdef UNUSED_CODE
++ ret = ov13850_read_reg16(sensor, OV13850_REG_CHIP_ID, &chip_id);
++ if (ret) {
++ dev_err(&sensor->i2c_client->dev, "%s: failed to read chip identifier\n",
++ __func__);
++ ret = -ENODEV;
++ goto power_off;
++ }
++
++ if (chip_id != OV13850_CHIP_ID) {
++ dev_err(&sensor->i2c_client->dev,
++ "%s: wrong chip identifier, expected 0x%x, got 0x%x\n",
++ __func__, OV13850_CHIP_ID, chip_id);
++ ret = -ENXIO;
++ goto power_off;
++ }
++ dev_err(&sensor->i2c_client->dev, "%s: chip identifier, got 0x%x\n",
++ __func__, chip_id);
++#endif
++
++ ret = ov13850_restore_mode(sensor);
++ if (ret)
++ goto power_off;
++ }
++
++ if (sensor->ep.bus_type == V4L2_MBUS_CSI2_DPHY)
++ ret = ov13850_set_power_mipi(sensor, on);
++ if (ret)
++ goto power_off;
++
++ if (!on)
++ ov13850_set_power_off(sensor);
++
++ return 0;
++
++power_off:
++ ov13850_set_power_off(sensor);
++ return ret;
++}
++
++static int ov13850_s_power(struct v4l2_subdev *sd, int on)
++{
++ struct ov13850_dev *sensor = to_ov13850_dev(sd);
++ int ret = 0;
++
++ mutex_lock(&sensor->lock);
++
++ /*
++ * If the power count is modified from 0 to != 0 or from != 0 to 0,
++ * update the power state.
++ */
++ if (sensor->power_count == !on) {
++ ret = ov13850_set_power(sensor, !!on);
++ if (ret)
++ goto out;
++ }
++
++ /* Update the power count. */
++ sensor->power_count += on ? 1 : -1;
++ WARN_ON(sensor->power_count < 0);
++out:
++ mutex_unlock(&sensor->lock);
++
++ if (on && !ret && sensor->power_count == 1) {
++ /* restore controls */
++ ret = v4l2_ctrl_handler_setup(&sensor->ctrls.handler);
++ }
++
++ return ret;
++}
++
++static int ov13850_try_frame_interval(struct ov13850_dev *sensor,
++ struct v4l2_fract *fi,
++ u32 width, u32 height)
++{
++ const struct ov13850_mode_info *mode;
++ enum ov13850_frame_rate rate = OV13850_15_FPS;
++ int minfps, maxfps, best_fps, fps;
++ int i;
++
++ minfps = ov13850_framerates[OV13850_15_FPS];
++ maxfps = ov13850_framerates[OV13850_NUM_FRAMERATES - 1];
++
++ if (fi->numerator == 0) {
++ fi->denominator = maxfps;
++ fi->numerator = 1;
++ rate = OV13850_60_FPS;
++ goto find_mode;
++ }
++
++ fps = clamp_val(DIV_ROUND_CLOSEST(fi->denominator, fi->numerator),
++ minfps, maxfps);
++
++ best_fps = minfps;
++ for (i = 0; i < ARRAY_SIZE(ov13850_framerates); i++) {
++ int curr_fps = ov13850_framerates[i];
++
++ if (abs(curr_fps - fps) < abs(best_fps - fps)) {
++ best_fps = curr_fps;
++ rate = i;
++ }
++ }
++ st_info(ST_SENSOR, "best_fps = %d, fps = %d\n", best_fps, fps);
++
++ fi->numerator = 1;
++ fi->denominator = best_fps;
++
++find_mode:
++ mode = ov13850_find_mode(sensor, rate, width, height, false);
++ return mode ? rate : -EINVAL;
++}
++
++static int ov13850_enum_mbus_code(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_mbus_code_enum *code)
++{
++ if (code->pad != 0)
++ return -EINVAL;
++
++ if (code->index >= ARRAY_SIZE(ov13850_formats))
++ return -EINVAL;
++
++ code->code = ov13850_formats[code->index].code;
++ return 0;
++}
++
++static int ov13850_get_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_format *format)
++{
++ struct ov13850_dev *sensor = to_ov13850_dev(sd);
++ struct v4l2_mbus_framefmt *fmt;
++
++ if (format->pad != 0)
++ return -EINVAL;
++
++ mutex_lock(&sensor->lock);
++
++ if (format->which == V4L2_SUBDEV_FORMAT_TRY)
++ fmt = v4l2_subdev_get_try_format(&sensor->sd, state,
++ format->pad);
++ else
++ fmt = &sensor->fmt;
++
++ format->format = *fmt;
++
++ mutex_unlock(&sensor->lock);
++
++ return 0;
++}
++
++static int ov13850_try_fmt_internal(struct v4l2_subdev *sd,
++ struct v4l2_mbus_framefmt *fmt,
++ enum ov13850_frame_rate fr,
++ const struct ov13850_mode_info **new_mode)
++{
++ struct ov13850_dev *sensor = to_ov13850_dev(sd);
++ const struct ov13850_mode_info *mode;
++ int i;
++
++ mode = ov13850_find_mode(sensor, fr, fmt->width, fmt->height, true);
++ if (!mode)
++ return -EINVAL;
++ fmt->width = mode->hact;
++ fmt->height = mode->vact;
++
++ if (new_mode)
++ *new_mode = mode;
++
++ for (i = 0; i < ARRAY_SIZE(ov13850_formats); i++)
++ if (ov13850_formats[i].code == fmt->code)
++ break;
++ if (i >= ARRAY_SIZE(ov13850_formats))
++ i = 0;
++
++ fmt->code = ov13850_formats[i].code;
++ fmt->colorspace = ov13850_formats[i].colorspace;
++ fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->colorspace);
++ fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE;
++ fmt->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(fmt->colorspace);
++
++ return 0;
++}
++
++static int ov13850_set_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_format *format)
++{
++ struct ov13850_dev *sensor = to_ov13850_dev(sd);
++ const struct ov13850_mode_info *new_mode;
++ struct v4l2_mbus_framefmt *mbus_fmt = &format->format;
++ struct v4l2_mbus_framefmt *fmt;
++ int ret;
++
++ if (format->pad != 0)
++ return -EINVAL;
++
++ mutex_lock(&sensor->lock);
++
++ if (sensor->streaming) {
++ ret = -EBUSY;
++ goto out;
++ }
++
++ ret = ov13850_try_fmt_internal(sd, mbus_fmt, 0, &new_mode);
++ if (ret)
++ goto out;
++
++ if (format->which == V4L2_SUBDEV_FORMAT_TRY)
++ fmt = v4l2_subdev_get_try_format(sd, state, 0);
++ else
++ fmt = &sensor->fmt;
++
++ if (mbus_fmt->code != sensor->fmt.code)
++ sensor->pending_fmt_change = true;
++
++ *fmt = *mbus_fmt;
++
++ if (new_mode != sensor->current_mode) {
++ sensor->current_mode = new_mode;
++ sensor->pending_mode_change = true;
++ }
++
++ if (new_mode->max_fps < sensor->current_fr) {
++ sensor->current_fr = new_mode->max_fps;
++ sensor->frame_interval.numerator = 1;
++ sensor->frame_interval.denominator =
++ ov13850_framerates[sensor->current_fr];
++ sensor->current_mode = new_mode;
++ sensor->pending_mode_change = true;
++ }
++
++ __v4l2_ctrl_s_ctrl_int64(sensor->ctrls.pixel_rate,
++ ov13850_calc_pixel_rate(sensor));
++out:
++ mutex_unlock(&sensor->lock);
++ return ret;
++}
++
++static int ov13850_set_framefmt(struct ov13850_dev *sensor,
++ struct v4l2_mbus_framefmt *format)
++{
++ u8 fmt;
++
++ switch (format->code) {
++ /* Raw, BGBG... / GRGR... */
++ case MEDIA_BUS_FMT_SBGGR8_1X8:
++ case MEDIA_BUS_FMT_SGBRG8_1X8:
++ case MEDIA_BUS_FMT_SGRBG8_1X8:
++ case MEDIA_BUS_FMT_SRGGB8_1X8:
++ fmt = 0x0;
++ break;
++ case MEDIA_BUS_FMT_SBGGR10_1X10:
++ case MEDIA_BUS_FMT_SGBRG10_1X10:
++ case MEDIA_BUS_FMT_SGRBG10_1X10:
++ case MEDIA_BUS_FMT_SRGGB10_1X10:
++ fmt = 0x1;
++ case MEDIA_BUS_FMT_SBGGR12_1X12:
++ case MEDIA_BUS_FMT_SGBRG12_1X12:
++ case MEDIA_BUS_FMT_SGRBG12_1X12:
++ case MEDIA_BUS_FMT_SRGGB12_1X12:
++ fmt = 0x2;
++ default:
++ return -EINVAL;
++ }
++
++ return ov13850_mod_reg(sensor, OV13850_REG_MIPI_SC,
++ BIT(1) | BIT(0), fmt);
++}
++
++/*
++ * Sensor Controls.
++ */
++
++static int ov13850_set_ctrl_hue(struct ov13850_dev *sensor, int value)
++{
++ int ret = 0;
++
++ return ret;
++}
++
++static int ov13850_set_ctrl_contrast(struct ov13850_dev *sensor, int value)
++{
++ int ret = 0;
++
++ return ret;
++}
++
++static int ov13850_set_ctrl_saturation(struct ov13850_dev *sensor, int value)
++{
++ int ret = 0;
++
++ return ret;
++}
++
++static int ov13850_set_ctrl_white_balance(struct ov13850_dev *sensor, int awb)
++{
++ struct ov13850_ctrls *ctrls = &sensor->ctrls;
++ int ret = 0;
++
++ return ret;
++}
++
++static int ov13850_set_ctrl_exposure(struct ov13850_dev *sensor,
++ enum v4l2_exposure_auto_type auto_exposure)
++{
++ struct ov13850_ctrls *ctrls = &sensor->ctrls;
++ int ret = 0;
++
++ return ret;
++}
++
++static const s64 link_freq_menu_items[] = {
++ OV13850_LINK_FREQ_500MHZ
++};
++
++static const char * const test_pattern_menu[] = {
++ "Disabled",
++ "Color bars",
++ "Color bars w/ rolling bar",
++ "Color squares",
++ "Color squares w/ rolling bar",
++};
++
++static int ov13850_set_ctrl_test_pattern(struct ov13850_dev *sensor, int value)
++{
++ return 0;
++}
++
++static int ov13850_set_ctrl_light_freq(struct ov13850_dev *sensor, int value)
++{
++ return 0;
++}
++
++static int ov13850_set_ctrl_hflip(struct ov13850_dev *sensor, int value)
++{
++ return 0;
++}
++
++static int ov13850_set_ctrl_vflip(struct ov13850_dev *sensor, int value)
++{
++ return 0;
++}
++
++static int ov13850_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
++{
++ struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
++ struct ov13850_dev *sensor = to_ov13850_dev(sd);
++ int val;
++
++ /* v4l2_ctrl_lock() locks our own mutex */
++
++ switch (ctrl->id) {
++ case V4L2_CID_ANALOGUE_GAIN:
++ val = ov13850_get_gain(sensor);
++ break;
++ }
++
++ return 0;
++}
++
++static int ov13850_s_ctrl(struct v4l2_ctrl *ctrl)
++{
++ struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
++ struct ov13850_dev *sensor = to_ov13850_dev(sd);
++ int ret;
++
++ /* v4l2_ctrl_lock() locks our own mutex */
++
++ /*
++ * If the device is not powered up by the host driver do
++ * not apply any controls to H/W at this time. Instead
++ * the controls will be restored right after power-up.
++ */
++ if (sensor->power_count == 0)
++ return 0;
++
++ switch (ctrl->id) {
++ case V4L2_CID_ANALOGUE_GAIN:
++ ret = ov13850_set_gain(sensor, ctrl->val);
++ break;
++ case V4L2_CID_EXPOSURE:
++ ret = ov13850_set_ctrl_exposure(sensor, V4L2_EXPOSURE_MANUAL);
++ break;
++ case V4L2_CID_AUTO_WHITE_BALANCE:
++ ret = ov13850_set_ctrl_white_balance(sensor, ctrl->val);
++ break;
++ case V4L2_CID_HUE:
++ ret = ov13850_set_ctrl_hue(sensor, ctrl->val);
++ break;
++ case V4L2_CID_CONTRAST:
++ ret = ov13850_set_ctrl_contrast(sensor, ctrl->val);
++ break;
++ case V4L2_CID_SATURATION:
++ ret = ov13850_set_ctrl_saturation(sensor, ctrl->val);
++ break;
++ case V4L2_CID_TEST_PATTERN:
++ ret = ov13850_set_ctrl_test_pattern(sensor, ctrl->val);
++ break;
++ case V4L2_CID_POWER_LINE_FREQUENCY:
++ ret = ov13850_set_ctrl_light_freq(sensor, ctrl->val);
++ break;
++ case V4L2_CID_HFLIP:
++ ret = ov13850_set_ctrl_hflip(sensor, ctrl->val);
++ break;
++ case V4L2_CID_VFLIP:
++ ret = ov13850_set_ctrl_vflip(sensor, ctrl->val);
++ break;
++ default:
++ ret = -EINVAL;
++ break;
++ }
++
++ return ret;
++}
++
++static const struct v4l2_ctrl_ops ov13850_ctrl_ops = {
++ .g_volatile_ctrl = ov13850_g_volatile_ctrl,
++ .s_ctrl = ov13850_s_ctrl,
++};
++
++static int ov13850_init_controls(struct ov13850_dev *sensor)
++{
++ const struct v4l2_ctrl_ops *ops = &ov13850_ctrl_ops;
++ struct ov13850_ctrls *ctrls = &sensor->ctrls;
++ struct v4l2_ctrl_handler *hdl = &ctrls->handler;
++ int ret;
++
++ v4l2_ctrl_handler_init(hdl, 32);
++
++ /* we can use our own mutex for the ctrl lock */
++ hdl->lock = &sensor->lock;
++
++ /* Clock related controls */
++ ctrls->pixel_rate = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_PIXEL_RATE,
++ 0, INT_MAX, 1,
++ ov13850_calc_pixel_rate(sensor));
++
++ /* Auto/manual white balance */
++ ctrls->auto_wb = v4l2_ctrl_new_std(hdl, ops,
++ V4L2_CID_AUTO_WHITE_BALANCE,
++ 0, 1, 1, 0);
++ ctrls->blue_balance = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_BLUE_BALANCE,
++ 0, 4095, 1, 1024);
++ ctrls->red_balance = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_RED_BALANCE,
++ 0, 4095, 1, 1024);
++
++ ctrls->exposure = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_EXPOSURE,
++ 4, 0xfff8, 1, 0x4c00);
++ ctrls->anal_gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_ANALOGUE_GAIN,
++ 0x10, 0xfff8, 1, 0x0080);
++ ctrls->test_pattern =
++ v4l2_ctrl_new_std_menu_items(hdl, ops, V4L2_CID_TEST_PATTERN,
++ ARRAY_SIZE(test_pattern_menu) - 1,
++ 0, 0, test_pattern_menu);
++ ctrls->hflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_HFLIP,
++ 0, 1, 1, 0);
++ ctrls->vflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_VFLIP,
++ 0, 1, 1, 0);
++ ctrls->light_freq =
++ v4l2_ctrl_new_std_menu(hdl, ops,
++ V4L2_CID_POWER_LINE_FREQUENCY,
++ V4L2_CID_POWER_LINE_FREQUENCY_AUTO, 0,
++ V4L2_CID_POWER_LINE_FREQUENCY_50HZ);
++ ctrls->link_freq = v4l2_ctrl_new_int_menu(hdl, ops, V4L2_CID_LINK_FREQ,
++ 0, 0, link_freq_menu_items);
++ if (hdl->error) {
++ ret = hdl->error;
++ goto free_ctrls;
++ }
++
++ ctrls->pixel_rate->flags |= V4L2_CTRL_FLAG_READ_ONLY;
++ ctrls->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
++ // ctrls->exposure->flags |= V4L2_CTRL_FLAG_VOLATILE;
++ // ctrls->anal_gain->flags |= V4L2_CTRL_FLAG_VOLATILE;
++
++ v4l2_ctrl_auto_cluster(3, &ctrls->auto_wb, 0, false);
++
++ sensor->sd.ctrl_handler = hdl;
++ return 0;
++
++free_ctrls:
++ v4l2_ctrl_handler_free(hdl);
++ return ret;
++}
++
++static int ov13850_enum_frame_size(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_frame_size_enum *fse)
++{
++ if (fse->pad != 0)
++ return -EINVAL;
++ if (fse->index >= OV13850_NUM_MODES)
++ return -EINVAL;
++
++ fse->min_width =
++ ov13850_mode_data[fse->index].hact;
++ fse->max_width = fse->min_width;
++ fse->min_height =
++ ov13850_mode_data[fse->index].vact;
++ fse->max_height = fse->min_height;
++
++ return 0;
++}
++
++static int ov13850_enum_frame_interval(
++ struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_frame_interval_enum *fie)
++{
++ struct ov13850_dev *sensor = to_ov13850_dev(sd);
++ struct v4l2_fract tpf;
++ int ret;
++
++ if (fie->pad != 0)
++ return -EINVAL;
++ if (fie->index >= OV13850_NUM_FRAMERATES)
++ return -EINVAL;
++
++ tpf.numerator = 1;
++ tpf.denominator = ov13850_framerates[fie->index];
++
++/* ret = ov13850_try_frame_interval(sensor, &tpf,
++ * fie->width, fie->height);
++ * if (ret < 0)
++ * return -EINVAL;
++ */
++ fie->interval = tpf;
++
++ return 0;
++}
++
++static int ov13850_g_frame_interval(struct v4l2_subdev *sd,
++ struct v4l2_subdev_frame_interval *fi)
++{
++ struct ov13850_dev *sensor = to_ov13850_dev(sd);
++
++ mutex_lock(&sensor->lock);
++ fi->interval = sensor->frame_interval;
++ mutex_unlock(&sensor->lock);
++
++ return 0;
++}
++
++static int ov13850_s_frame_interval(struct v4l2_subdev *sd,
++ struct v4l2_subdev_frame_interval *fi)
++{
++ struct ov13850_dev *sensor = to_ov13850_dev(sd);
++ const struct ov13850_mode_info *mode;
++ int frame_rate, ret = 0;
++
++ if (fi->pad != 0)
++ return -EINVAL;
++
++ mutex_lock(&sensor->lock);
++
++ if (sensor->streaming) {
++ ret = -EBUSY;
++ goto out;
++ }
++
++ mode = sensor->current_mode;
++
++ frame_rate = ov13850_try_frame_interval(sensor, &fi->interval,
++ mode->hact, mode->vact);
++ if (frame_rate < 0) {
++ /* Always return a valid frame interval value */
++ fi->interval = sensor->frame_interval;
++ goto out;
++ }
++
++ mode = ov13850_find_mode(sensor, frame_rate, mode->hact,
++ mode->vact, true);
++ if (!mode) {
++ ret = -EINVAL;
++ goto out;
++ }
++
++ if (mode != sensor->current_mode ||
++ frame_rate != sensor->current_fr) {
++ sensor->current_fr = frame_rate;
++ sensor->frame_interval = fi->interval;
++ sensor->current_mode = mode;
++ sensor->pending_mode_change = true;
++
++ __v4l2_ctrl_s_ctrl_int64(sensor->ctrls.pixel_rate,
++ ov13850_calc_pixel_rate(sensor));
++ }
++out:
++ mutex_unlock(&sensor->lock);
++ return ret;
++}
++
++static int ov13850_stream_start(struct ov13850_dev *sensor, int enable)
++{
++ int ret;
++
++ if (enable) { //stream on
++ mdelay(1000);
++ ret = ov13850_write_reg(sensor, OV13850_STREAM_CTRL, enable);
++ } else { //stream off
++ ret = ov13850_write_reg(sensor, OV13850_STREAM_CTRL, enable);
++ mdelay(100);
++ }
++
++ return ret;
++}
++
++static int ov13850_s_stream(struct v4l2_subdev *sd, int enable)
++{
++ struct ov13850_dev *sensor = to_ov13850_dev(sd);
++ int ret = 0;
++
++ mutex_lock(&sensor->lock);
++
++ if (sensor->streaming == !enable) {
++ if (enable && sensor->pending_mode_change) {
++ ret = ov13850_set_mode(sensor);
++ if (ret)
++ goto out;
++ }
++
++ if (enable && sensor->pending_fmt_change) {
++ ret = ov13850_set_framefmt(sensor, &sensor->fmt);
++ if (ret)
++ goto out;
++ sensor->pending_fmt_change = false;
++ }
++
++ if (sensor->ep.bus_type == V4L2_MBUS_CSI2_DPHY)
++ ret = ov13850_set_stream_mipi(sensor, enable);
++
++ ret = ov13850_stream_start(sensor, enable);
++
++ if (!ret)
++ sensor->streaming = enable;
++ }
++out:
++ mutex_unlock(&sensor->lock);
++ return ret;
++}
++
++static const struct v4l2_subdev_core_ops ov13850_core_ops = {
++ .s_power = ov13850_s_power,
++ .log_status = v4l2_ctrl_subdev_log_status,
++ .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
++ .unsubscribe_event = v4l2_event_subdev_unsubscribe,
++};
++
++static const struct v4l2_subdev_video_ops ov13850_video_ops = {
++ .g_frame_interval = ov13850_g_frame_interval,
++ .s_frame_interval = ov13850_s_frame_interval,
++ .s_stream = ov13850_s_stream,
++};
++
++static const struct v4l2_subdev_pad_ops ov13850_pad_ops = {
++ .enum_mbus_code = ov13850_enum_mbus_code,
++ .get_fmt = ov13850_get_fmt,
++ .set_fmt = ov13850_set_fmt,
++ .enum_frame_size = ov13850_enum_frame_size,
++ .enum_frame_interval = ov13850_enum_frame_interval,
++};
++
++static const struct v4l2_subdev_ops ov13850_subdev_ops = {
++ .core = &ov13850_core_ops,
++ .video = &ov13850_video_ops,
++ .pad = &ov13850_pad_ops,
++};
++
++static int ov13850_get_regulators(struct ov13850_dev *sensor)
++{
++ int i;
++
++ for (i = 0; i < OV13850_NUM_SUPPLIES; i++)
++ sensor->supplies[i].supply = ov13850_supply_name[i];
++
++ return devm_regulator_bulk_get(&sensor->i2c_client->dev,
++ OV13850_NUM_SUPPLIES,
++ sensor->supplies);
++}
++
++static int ov13850_check_chip_id(struct ov13850_dev *sensor)
++{
++ struct i2c_client *client = sensor->i2c_client;
++ int ret = 0;
++ u16 chip_id;
++
++ ret = ov13850_set_power_on(sensor);
++ if (ret)
++ return ret;
++
++#ifdef UNUSED_CODE
++ ret = ov13850_read_reg16(sensor, OV13850_REG_CHIP_ID, &chip_id);
++ if (ret) {
++ dev_err(&client->dev, "%s: failed to read chip identifier\n",
++ __func__);
++ goto power_off;
++ }
++
++ if (chip_id != OV13850_CHIP_ID) {
++ dev_err(&client->dev, "%s: wrong chip identifier, expected 0x%x, got 0x%x\n",
++ __func__, OV13850_CHIP_ID, chip_id);
++ ret = -ENXIO;
++ }
++ dev_err(&client->dev, "%s: chip identifier, got 0x%x\n",
++ __func__, chip_id);
++#endif
++
++power_off:
++ ov13850_set_power_off(sensor);
++ return ret;
++}
++
++static int ov13850_probe(struct i2c_client *client)
++{
++ struct device *dev = &client->dev;
++ struct fwnode_handle *endpoint;
++ struct ov13850_dev *sensor;
++ struct v4l2_mbus_framefmt *fmt;
++ u32 rotation;
++ int ret;
++ u8 chip_id_high, chip_id_low;
++
++ sensor = devm_kzalloc(dev, sizeof(*sensor), GFP_KERNEL);
++ if (!sensor)
++ return -ENOMEM;
++
++ sensor->i2c_client = client;
++
++ fmt = &sensor->fmt;
++ fmt->code = MEDIA_BUS_FMT_SBGGR10_1X10;
++ fmt->colorspace = V4L2_COLORSPACE_SRGB;
++ fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->colorspace);
++ fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE;
++ fmt->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(fmt->colorspace);
++ fmt->width = 1920;
++ fmt->height = 1080;
++ fmt->field = V4L2_FIELD_NONE;
++ sensor->frame_interval.numerator = 1;
++ sensor->frame_interval.denominator = ov13850_framerates[OV13850_30_FPS];
++ sensor->current_fr = OV13850_30_FPS;
++ sensor->current_mode =
++ &ov13850_mode_data[OV13850_MODE_1080P_1920_1080];
++ sensor->last_mode = sensor->current_mode;
++
++ sensor->ae_target = 52;
++
++ /* optional indication of physical rotation of sensor */
++ ret = fwnode_property_read_u32(dev_fwnode(&client->dev), "rotation",
++ &rotation);
++ if (!ret) {
++ switch (rotation) {
++ case 180:
++ sensor->upside_down = true;
++ fallthrough;
++ case 0:
++ break;
++ default:
++ dev_warn(dev, "%u degrees rotation is not supported, ignoring...\n",
++ rotation);
++ }
++ }
++
++ endpoint = fwnode_graph_get_next_endpoint(dev_fwnode(&client->dev),
++ NULL);
++ if (!endpoint) {
++ dev_err(dev, "endpoint node not found\n");
++ return -EINVAL;
++ }
++
++ ret = v4l2_fwnode_endpoint_parse(endpoint, &sensor->ep);
++ fwnode_handle_put(endpoint);
++ if (ret) {
++ dev_err(dev, "Could not parse endpoint\n");
++ return ret;
++ }
++
++ if (sensor->ep.bus_type != V4L2_MBUS_PARALLEL &&
++ sensor->ep.bus_type != V4L2_MBUS_CSI2_DPHY &&
++ sensor->ep.bus_type != V4L2_MBUS_BT656) {
++ dev_err(dev, "Unsupported bus type %d\n", sensor->ep.bus_type);
++ return -EINVAL;
++ }
++
++ /* get system clock (xclk) */
++ sensor->xclk = devm_clk_get(dev, "xclk");
++ if (IS_ERR(sensor->xclk)) {
++ dev_err(dev, "failed to get xclk\n");
++ return PTR_ERR(sensor->xclk);
++ }
++
++ sensor->xclk_freq = clk_get_rate(sensor->xclk);
++ if (sensor->xclk_freq < OV13850_XCLK_MIN ||
++ sensor->xclk_freq > OV13850_XCLK_MAX) {
++ dev_err(dev, "xclk frequency out of range: %d Hz\n",
++ sensor->xclk_freq);
++ return -EINVAL;
++ }
++
++ /* request optional power down pin */
++ sensor->pwdn_gpio = devm_gpiod_get_optional(dev, "powerdown",
++ GPIOD_OUT_HIGH);
++ if (IS_ERR(sensor->pwdn_gpio))
++ return PTR_ERR(sensor->pwdn_gpio);
++
++ /* request optional reset pin */
++ sensor->reset_gpio = devm_gpiod_get_optional(dev, "reset",
++ GPIOD_OUT_HIGH);
++ if (IS_ERR(sensor->reset_gpio))
++ return PTR_ERR(sensor->reset_gpio);
++
++ v4l2_i2c_subdev_init(&sensor->sd, client, &ov13850_subdev_ops);
++
++ sensor->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
++ V4L2_SUBDEV_FL_HAS_EVENTS;
++ sensor->pad.flags = MEDIA_PAD_FL_SOURCE;
++ sensor->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
++ ret = media_entity_pads_init(&sensor->sd.entity, 1, &sensor->pad);
++ if (ret)
++ return ret;
++
++ ret = ov13850_get_regulators(sensor);
++ if (ret)
++ return ret;
++
++ mutex_init(&sensor->lock);
++
++ ret = ov13850_check_chip_id(sensor);
++ if (ret)
++ goto entity_cleanup;
++
++ ret = ov13850_init_controls(sensor);
++ if (ret)
++ goto entity_cleanup;
++
++ ret = v4l2_async_register_subdev_sensor(&sensor->sd);
++ if (ret)
++ goto free_ctrls;
++
++ return 0;
++
++free_ctrls:
++ v4l2_ctrl_handler_free(&sensor->ctrls.handler);
++entity_cleanup:
++ media_entity_cleanup(&sensor->sd.entity);
++ mutex_destroy(&sensor->lock);
++ return ret;
++}
++
++static int ov13850_remove(struct i2c_client *client)
++{
++ struct v4l2_subdev *sd = i2c_get_clientdata(client);
++ struct ov13850_dev *sensor = to_ov13850_dev(sd);
++
++ v4l2_async_unregister_subdev(&sensor->sd);
++ media_entity_cleanup(&sensor->sd.entity);
++ v4l2_ctrl_handler_free(&sensor->ctrls.handler);
++ mutex_destroy(&sensor->lock);
++
++ return 0;
++}
++
++static const struct i2c_device_id ov13850_id[] = {
++ {"ov13850", 0},
++ {},
++};
++MODULE_DEVICE_TABLE(i2c, ov13850_id);
++
++static const struct of_device_id ov13850_dt_ids[] = {
++ { .compatible = "ovti,ov13850" },
++ { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, ov13850_dt_ids);
++
++static struct i2c_driver ov13850_i2c_driver = {
++ .driver = {
++ .name = "ov13850",
++ .of_match_table = ov13850_dt_ids,
++ },
++ .id_table = ov13850_id,
++ .probe_new = ov13850_probe,
++ .remove = ov13850_remove,
++};
++
++module_i2c_driver(ov13850_i2c_driver);
++
++MODULE_DESCRIPTION("OV13850 MIPI Camera Subdev Driver");
++MODULE_LICENSE("GPL");
+--- /dev/null
++++ b/drivers/media/platform/starfive/v4l2_driver/ov4689_mipi.c
+@@ -0,0 +1,2975 @@
++// SPDX-License-Identifier: GPL-2.0-or-later
++/*
++ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
++ *
++ */
++
++#include <linux/clk.h>
++#include <linux/clk-provider.h>
++#include <linux/clkdev.h>
++#include <linux/ctype.h>
++#include <linux/delay.h>
++#include <linux/device.h>
++#include <linux/gpio/consumer.h>
++#include <linux/i2c.h>
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/pm_runtime.h>
++#include <linux/of_device.h>
++#include <linux/regulator/consumer.h>
++#include <linux/slab.h>
++#include <linux/types.h>
++#include <media/v4l2-async.h>
++#include <media/v4l2-ctrls.h>
++#include <media/v4l2-device.h>
++#include <media/v4l2-event.h>
++#include <media/v4l2-fwnode.h>
++#include <media/v4l2-subdev.h>
++#include "stfcamss.h"
++
++
++#define OV4689_LANES 4
++
++#define OV4689_LINK_FREQ_500MHZ 500000000LL
++
++/* min/typical/max system clock (xclk) frequencies */
++#define OV4689_XCLK_MIN 6000000
++#define OV4689_XCLK_MAX 64000000
++
++#define OV4689_CHIP_ID (0x4688)
++
++#define OV4689_CHIP_ID_HIGH_BYTE 0x300a // max should be 0x46
++#define OV4689_CHIP_ID_LOW_BYTE 0x300b // max should be 0x88
++#define OV4689_REG_CHIP_ID 0x300a
++
++#define OV4689_REG_H_OUTPUT_SIZE 0x3808
++#define OV4689_REG_V_OUTPUT_SIZE 0x380a
++#define OV4689_REG_TIMING_HTS 0x380c
++#define OV4689_REG_TIMING_VTS 0x380e
++
++#define OV4689_REG_EXPOSURE_HI 0x3500
++#define OV4689_REG_EXPOSURE_MED 0x3501
++#define OV4689_REG_EXPOSURE_LO 0x3502
++#define OV4689_REG_GAIN_H 0x3507
++#define OV4689_REG_GAIN_M 0x3508
++#define OV4689_REG_GAIN_L 0x3509
++#define OV4689_REG_TEST_PATTERN 0x5040
++#define OV4689_REG_TIMING_TC_REG20 0x3820
++#define OV4689_REG_TIMING_TC_REG21 0x3821
++
++#define OV4689_REG_AWB_R_GAIN 0x500C
++#define OV4689_REG_AWB_B_GAIN 0x5010
++#define OV4689_REG_STREAM_ON 0x0100
++
++#define OV4689_REG_MIPI_SC_CTRL_HI 0x3018
++#define OV4689_REG_MIPI_SC_CTRL_LOW 0x3019
++
++enum ov4689_mode_id {
++ //OV4689_MODE_720P_1280_720 = 0,
++ OV4689_MODE_1080P_1920_1080 = 0,
++ //OV4689_MODE_4M_2688_1520,
++ OV4689_NUM_MODES,
++};
++
++enum ov4689_frame_rate {
++ OV4689_15_FPS = 0,
++ OV4689_30_FPS,
++ OV4689_45_FPS,
++ OV4689_60_FPS,
++ OV4689_90_FPS,
++ OV4689_120_FPS,
++ OV4689_150_FPS,
++ OV4689_180_FPS,
++ OV4689_330_FPS,
++ OV4689_NUM_FRAMERATES,
++};
++
++enum ov4689_format_mux {
++ OV4689_FMT_MUX_RAW,
++};
++
++static const int ov4689_framerates[] = {
++ [OV4689_15_FPS] = 15,
++ [OV4689_30_FPS] = 30,
++ [OV4689_45_FPS] = 45,
++ [OV4689_60_FPS] = 60,
++ [OV4689_90_FPS] = 90,
++ [OV4689_120_FPS] = 120,
++ [OV4689_150_FPS] = 150,
++ [OV4689_180_FPS] = 180,
++ [OV4689_330_FPS] = 330,
++};
++
++/* regulator supplies */
++static const char * const ov4689_supply_name[] = {
++ "DOVDD", /* Digital I/O (1.8V) supply */
++ "AVDD", /* Analog (2.8V) supply */
++ "DVDD", /* Digital Core (1.5V) supply */
++};
++
++#define OV4689_NUM_SUPPLIES ARRAY_SIZE(ov4689_supply_name)
++
++/*
++ * Image size under 1280 * 960 are SUBSAMPLING
++ * Image size upper 1280 * 960 are SCALING
++ */
++enum ov4689_downsize_mode {
++ SUBSAMPLING,
++ SCALING,
++};
++
++struct reg_value {
++ u16 reg_addr;
++ u8 val;
++ u8 mask;
++ u32 delay_ms;
++};
++
++struct ov4689_mode_info {
++ enum ov4689_mode_id id;
++ enum ov4689_downsize_mode dn_mode;
++ u32 hact;
++ u32 htot;
++ u32 vact;
++ u32 vtot;
++ const struct reg_value *reg_data;
++ u32 reg_data_size;
++ u32 max_fps;
++};
++
++struct ov4689_ctrls {
++ struct v4l2_ctrl_handler handler;
++ struct v4l2_ctrl *pixel_rate;
++ struct {
++ struct v4l2_ctrl *exposure;
++ };
++ struct {
++ struct v4l2_ctrl *auto_wb;
++ struct v4l2_ctrl *blue_balance;
++ struct v4l2_ctrl *red_balance;
++ };
++ struct {
++ struct v4l2_ctrl *anal_gain;
++ };
++ struct v4l2_ctrl *brightness;
++ struct v4l2_ctrl *light_freq;
++ struct v4l2_ctrl *link_freq;
++ struct v4l2_ctrl *saturation;
++ struct v4l2_ctrl *contrast;
++ struct v4l2_ctrl *hue;
++ struct v4l2_ctrl *test_pattern;
++ struct v4l2_ctrl *hflip;
++ struct v4l2_ctrl *vflip;
++};
++
++struct ov4689_dev {
++ struct i2c_client *i2c_client;
++ struct v4l2_subdev sd;
++ struct media_pad pad;
++ struct v4l2_fwnode_endpoint ep; /* the parsed DT endpoint info */
++ struct clk *xclk; /* system clock to OV4689 */
++ u32 xclk_freq;
++
++ struct regulator_bulk_data supplies[OV4689_NUM_SUPPLIES];
++ struct gpio_desc *reset_gpio;
++ struct gpio_desc *pwdn_gpio;
++ bool upside_down;
++
++ /* lock to protect all members below */
++ struct mutex lock;
++
++ struct v4l2_mbus_framefmt fmt;
++
++ const struct ov4689_mode_info *current_mode;
++ const struct ov4689_mode_info *last_mode;
++ enum ov4689_frame_rate current_fr;
++ struct v4l2_fract frame_interval;
++
++ struct ov4689_ctrls ctrls;
++
++ bool pending_mode_change;
++ int streaming;
++};
++
++static inline struct ov4689_dev *to_ov4689_dev(struct v4l2_subdev *sd)
++{
++ return container_of(sd, struct ov4689_dev, sd);
++}
++
++static inline struct v4l2_subdev *ctrl_to_sd(struct v4l2_ctrl *ctrl)
++{
++ return &container_of(ctrl->handler, struct ov4689_dev,
++ ctrls.handler)->sd;
++}
++
++/* ov4689 initial register */
++static const struct reg_value ov4689_init_setting_30fps_1080P[] = {
++/* ov4689_1080p_30fps_4d */
++ {0x0103, 0x01, 0, 0},
++ {0x3638, 0x00, 0, 0},
++ {0x0300, 0x02, 0, 0},
++ {0x0302, 0x32, 0, 0},
++ {0x0303, 0x00, 0, 0},
++ {0x0304, 0x03, 0, 0},
++ {0x030b, 0x00, 0, 0},
++ {0x030d, 0x1e, 0, 0},
++ {0x030e, 0x04, 0, 0},
++ {0x030f, 0x01, 0, 0},
++ {0x0312, 0x01, 0, 0},
++ {0x031e, 0x00, 0, 0},
++ {0x3000, 0x20, 0, 0},
++ {0x3002, 0x00, 0, 0},
++ {0x3020, 0x93, 0, 0},
++ {0x3021, 0x03, 0, 0},
++ {0x3022, 0x01, 0, 0},
++ {0x3031, 0x0a, 0, 0},
++ {0x3305, 0xf1, 0, 0},
++ {0x3307, 0x04, 0, 0},
++ {0x3309, 0x29, 0, 0},
++ {0x3500, 0x00, 0, 0},
++ {0x3501, 0x4c, 0, 0},
++ {0x3502, 0x00, 0, 0},
++ {0x3503, 0x04, 0, 0},
++ {0x3504, 0x00, 0, 0},
++ {0x3505, 0x00, 0, 0},
++ {0x3506, 0x00, 0, 0},
++ {0x3507, 0x00, 0, 0},
++ {0x3508, 0x00, 0, 0},
++ {0x3509, 0x80, 0, 0},
++ {0x350a, 0x00, 0, 0},
++ {0x350b, 0x00, 0, 0},
++ {0x350c, 0x00, 0, 0},
++ {0x350d, 0x00, 0, 0},
++ {0x350e, 0x00, 0, 0},
++ {0x350f, 0x80, 0, 0},
++ {0x3510, 0x00, 0, 0},
++ {0x3511, 0x00, 0, 0},
++ {0x3512, 0x00, 0, 0},
++ {0x3513, 0x00, 0, 0},
++ {0x3514, 0x00, 0, 0},
++ {0x3515, 0x80, 0, 0},
++ {0x3516, 0x00, 0, 0},
++ {0x3517, 0x00, 0, 0},
++ {0x3518, 0x00, 0, 0},
++ {0x3519, 0x00, 0, 0},
++ {0x351a, 0x00, 0, 0},
++ {0x351b, 0x80, 0, 0},
++ {0x351c, 0x00, 0, 0},
++ {0x351d, 0x00, 0, 0},
++ {0x351e, 0x00, 0, 0},
++ {0x351f, 0x00, 0, 0},
++ {0x3520, 0x00, 0, 0},
++ {0x3521, 0x80, 0, 0},
++ {0x3522, 0x08, 0, 0},
++ {0x3524, 0x08, 0, 0},
++ {0x3526, 0x08, 0, 0},
++ {0x3528, 0x08, 0, 0},
++ {0x352a, 0x08, 0, 0},
++ {0x3602, 0x00, 0, 0},
++ {0x3603, 0x40, 0, 0},
++ {0x3604, 0x02, 0, 0},
++ {0x3605, 0x00, 0, 0},
++ {0x3606, 0x00, 0, 0},
++ {0x3607, 0x00, 0, 0},
++ {0x3609, 0x12, 0, 0},
++ {0x360a, 0x40, 0, 0},
++ {0x360c, 0x08, 0, 0},
++ {0x360f, 0xe5, 0, 0},
++ {0x3608, 0x8f, 0, 0},
++ {0x3611, 0x00, 0, 0},
++ {0x3613, 0xf7, 0, 0},
++ {0x3616, 0x58, 0, 0},
++ {0x3619, 0x99, 0, 0},
++ {0x361b, 0x60, 0, 0},
++ {0x361c, 0x7a, 0, 0},
++ {0x361e, 0x79, 0, 0},
++ {0x361f, 0x02, 0, 0},
++ {0x3632, 0x00, 0, 0},
++ {0x3633, 0x10, 0, 0},
++ {0x3634, 0x10, 0, 0},
++ {0x3635, 0x10, 0, 0},
++ {0x3636, 0x15, 0, 0},
++ {0x3646, 0x86, 0, 0},
++ {0x364a, 0x0b, 0, 0},
++ {0x3700, 0x17, 0, 0},
++ {0x3701, 0x22, 0, 0},
++ {0x3703, 0x10, 0, 0},
++ {0x370a, 0x37, 0, 0},
++ {0x3705, 0x00, 0, 0},
++ {0x3706, 0x63, 0, 0},
++ {0x3709, 0x3c, 0, 0},
++ {0x370b, 0x01, 0, 0},
++ {0x370c, 0x30, 0, 0},
++ {0x3710, 0x24, 0, 0},
++ {0x3711, 0x0c, 0, 0},
++ {0x3716, 0x00, 0, 0},
++ {0x3720, 0x28, 0, 0},
++ {0x3729, 0x7b, 0, 0},
++ {0x372a, 0x84, 0, 0},
++ {0x372b, 0xbd, 0, 0},
++ {0x372c, 0xbc, 0, 0},
++ {0x372e, 0x52, 0, 0},
++ {0x373c, 0x0e, 0, 0},
++ {0x373e, 0x33, 0, 0},
++ {0x3743, 0x10, 0, 0},
++ {0x3744, 0x88, 0, 0},
++ {0x3745, 0xc0, 0, 0},
++ {0x374a, 0x43, 0, 0},
++ {0x374c, 0x00, 0, 0},
++ {0x374e, 0x23, 0, 0},
++ {0x3751, 0x7b, 0, 0},
++ {0x3752, 0x84, 0, 0},
++ {0x3753, 0xbd, 0, 0},
++ {0x3754, 0xbc, 0, 0},
++ {0x3756, 0x52, 0, 0},
++ {0x375c, 0x00, 0, 0},
++ {0x3760, 0x00, 0, 0},
++ {0x3761, 0x00, 0, 0},
++ {0x3762, 0x00, 0, 0},
++ {0x3763, 0x00, 0, 0},
++ {0x3764, 0x00, 0, 0},
++ {0x3767, 0x04, 0, 0},
++ {0x3768, 0x04, 0, 0},
++ {0x3769, 0x08, 0, 0},
++ {0x376a, 0x08, 0, 0},
++ {0x376b, 0x20, 0, 0},
++ {0x376c, 0x00, 0, 0},
++ {0x376d, 0x00, 0, 0},
++ {0x376e, 0x00, 0, 0},
++ {0x3773, 0x00, 0, 0},
++ {0x3774, 0x51, 0, 0},
++ {0x3776, 0xbd, 0, 0},
++ {0x3777, 0xbd, 0, 0},
++ {0x3781, 0x18, 0, 0},
++ {0x3783, 0x25, 0, 0},
++ {0x3798, 0x1b, 0, 0},
++ {0x3800, 0x01, 0, 0},
++ {0x3801, 0x88, 0, 0},
++ {0x3802, 0x00, 0, 0},
++ {0x3803, 0xe0, 0, 0},
++ {0x3804, 0x09, 0, 0},
++ {0x3805, 0x17, 0, 0},
++ {0x3806, 0x05, 0, 0},
++ {0x3807, 0x1f, 0, 0},
++ {0x3808, 0x07, 0, 0},
++ {0x3809, 0x80, 0, 0},
++ {0x380a, 0x04, 0, 0},
++ {0x380b, 0x38, 0, 0},
++ {0x380c, 0x0d, 0, 0},
++ {0x380d, 0x70, 0, 0},
++ {0x380e, 0x04, 0, 0},
++ {0x380f, 0x8A, 0, 0},
++ {0x3810, 0x00, 0, 0},
++ {0x3811, 0x08, 0, 0},
++ {0x3812, 0x00, 0, 0},
++ {0x3813, 0x04, 0, 0},
++ {0x3814, 0x01, 0, 0},
++ {0x3815, 0x01, 0, 0},
++ {0x3819, 0x01, 0, 0},
++ {0x3820, 0x06, 0, 0},
++ {0x3821, 0x00, 0, 0},
++ {0x3829, 0x00, 0, 0},
++ {0x382a, 0x01, 0, 0},
++ {0x382b, 0x01, 0, 0},
++ {0x382d, 0x7f, 0, 0},
++ {0x3830, 0x04, 0, 0},
++ {0x3836, 0x01, 0, 0},
++ {0x3837, 0x00, 0, 0},
++ {0x3841, 0x02, 0, 0},
++ {0x3846, 0x08, 0, 0},
++ {0x3847, 0x07, 0, 0},
++ {0x3d85, 0x36, 0, 0},
++ {0x3d8c, 0x71, 0, 0},
++ {0x3d8d, 0xcb, 0, 0},
++ {0x3f0a, 0x00, 0, 0},
++ {0x4000, 0xf1, 0, 0},
++ {0x4001, 0x40, 0, 0},
++ {0x4002, 0x04, 0, 0},
++ {0x4003, 0x14, 0, 0},
++ {0x400e, 0x00, 0, 0},
++ {0x4011, 0x00, 0, 0},
++ {0x401a, 0x00, 0, 0},
++ {0x401b, 0x00, 0, 0},
++ {0x401c, 0x00, 0, 0},
++ {0x401d, 0x00, 0, 0},
++ {0x401f, 0x00, 0, 0},
++ {0x4020, 0x00, 0, 0},
++ {0x4021, 0x10, 0, 0},
++ {0x4022, 0x06, 0, 0},
++ {0x4023, 0x13, 0, 0},
++ {0x4024, 0x07, 0, 0},
++ {0x4025, 0x40, 0, 0},
++ {0x4026, 0x07, 0, 0},
++ {0x4027, 0x50, 0, 0},
++ {0x4028, 0x00, 0, 0},
++ {0x4029, 0x02, 0, 0},
++ {0x402a, 0x06, 0, 0},
++ {0x402b, 0x04, 0, 0},
++ {0x402c, 0x02, 0, 0},
++ {0x402d, 0x02, 0, 0},
++ {0x402e, 0x0e, 0, 0},
++ {0x402f, 0x04, 0, 0},
++ {0x4302, 0xff, 0, 0},
++ {0x4303, 0xff, 0, 0},
++ {0x4304, 0x00, 0, 0},
++ {0x4305, 0x00, 0, 0},
++ {0x4306, 0x00, 0, 0},
++ {0x4308, 0x02, 0, 0},
++ {0x4500, 0x6c, 0, 0},
++ {0x4501, 0xc4, 0, 0},
++ {0x4502, 0x40, 0, 0},
++ {0x4503, 0x01, 0, 0},
++ {0x4601, 0x77, 0, 0},
++ {0x4800, 0x04, 0, 0},
++ {0x4813, 0x08, 0, 0},
++ {0x481f, 0x40, 0, 0},
++ {0x4829, 0x78, 0, 0},
++ {0x4837, 0x10, 0, 0},
++ {0x4b00, 0x2a, 0, 0},
++ {0x4b0d, 0x00, 0, 0},
++ {0x4d00, 0x04, 0, 0},
++ {0x4d01, 0x42, 0, 0},
++ {0x4d02, 0xd1, 0, 0},
++ {0x4d03, 0x93, 0, 0},
++ {0x4d04, 0xf5, 0, 0},
++ {0x4d05, 0xc1, 0, 0},
++ {0x5000, 0xf3, 0, 0},
++ {0x5001, 0x11, 0, 0},
++ {0x5004, 0x00, 0, 0},
++ {0x500a, 0x00, 0, 0},
++ {0x500b, 0x00, 0, 0},
++ {0x5032, 0x00, 0, 0},
++ {0x5040, 0x00, 0, 0},
++ {0x5050, 0x0c, 0, 0},
++ {0x5500, 0x00, 0, 0},
++ {0x5501, 0x10, 0, 0},
++ {0x5502, 0x01, 0, 0},
++ {0x5503, 0x0f, 0, 0},
++ {0x8000, 0x00, 0, 0},
++ {0x8001, 0x00, 0, 0},
++ {0x8002, 0x00, 0, 0},
++ {0x8003, 0x00, 0, 0},
++ {0x8004, 0x00, 0, 0},
++ {0x8005, 0x00, 0, 0},
++ {0x8006, 0x00, 0, 0},
++ {0x8007, 0x00, 0, 0},
++ {0x8008, 0x00, 0, 0},
++ {0x3638, 0x00, 0, 0},
++};
++
++static const struct reg_value ov4689_setting_VGA_640_480[] = {
++ //@@ RES_640x480_2x_Bin_330fps_816Mbps
++ //OV4689_AM01B_640x480_24M_2lane_816Mbps_330fps_20140210.txt
++ {0x0103, 0x01, 0, 0},
++ {0x3638, 0x00, 0, 0},
++ {0x0300, 0x00, 0, 0}, // 00
++ {0x0302, 0x22, 0, 0}, // 816Mbps 5a ; 64 ; 5a ; 78 ; 78 ; 2a
++ {0x0303, 0x00, 0, 0}, // 03 ; 01 ; 02 ;
++ {0x0304, 0x03, 0, 0},
++ {0x030b, 0x00, 0, 0},
++ {0x030d, 0x1e, 0, 0},
++ {0x030e, 0x04, 0, 0},
++ {0x030f, 0x01, 0, 0},
++ {0x0312, 0x01, 0, 0},
++ {0x031e, 0x00, 0, 0},
++ {0x3000, 0x20, 0, 0},
++ {0x3002, 0x00, 0, 0},
++ {0x3020, 0x93, 0, 0},
++ {0x3021, 0x03, 0, 0},
++ {0x3022, 0x01, 0, 0},
++ {0x3031, 0x0a, 0, 0},
++ {0x303f, 0x0c, 0, 0},
++ {0x3305, 0xf1, 0, 0},
++ {0x3307, 0x04, 0, 0},
++ {0x3309, 0x29, 0, 0},
++ {0x3500, 0x00, 0, 0},
++ {0x3501, 0x4c, 0, 0},
++ {0x3502, 0x00, 0, 0},
++ {0x3503, 0x04, 0, 0},
++ {0x3504, 0x00, 0, 0},
++ {0x3505, 0x00, 0, 0},
++ {0x3506, 0x00, 0, 0},
++ {0x3507, 0x00, 0, 0},
++ {0x3508, 0x00, 0, 0},
++ {0x3509, 0x80, 0, 0}, // 8X
++ {0x350a, 0x00, 0, 0},
++ {0x350b, 0x00, 0, 0},
++ {0x350c, 0x00, 0, 0},
++ {0x350d, 0x00, 0, 0},
++ {0x350e, 0x00, 0, 0},
++ {0x350f, 0x80, 0, 0},
++ {0x3510, 0x00, 0, 0},
++ {0x3511, 0x00, 0, 0},
++ {0x3512, 0x00, 0, 0},
++ {0x3513, 0x00, 0, 0},
++ {0x3514, 0x00, 0, 0},
++ {0x3515, 0x80, 0, 0},
++ {0x3516, 0x00, 0, 0},
++ {0x3517, 0x00, 0, 0},
++ {0x3518, 0x00, 0, 0},
++ {0x3519, 0x00, 0, 0},
++ {0x351a, 0x00, 0, 0},
++ {0x351b, 0x80, 0, 0},
++ {0x351c, 0x00, 0, 0},
++ {0x351d, 0x00, 0, 0},
++ {0x351e, 0x00, 0, 0},
++ {0x351f, 0x00, 0, 0},
++ {0x3520, 0x00, 0, 0},
++ {0x3521, 0x80, 0, 0},
++ {0x3522, 0x08, 0, 0},
++ {0x3524, 0x08, 0, 0},
++ {0x3526, 0x08, 0, 0},
++ {0x3528, 0x08, 0, 0},
++ {0x352a, 0x08, 0, 0},
++ {0x3602, 0x00, 0, 0},
++ {0x3603, 0x40, 0, 0},
++ {0x3604, 0x02, 0, 0},
++ {0x3605, 0x00, 0, 0},
++ {0x3606, 0x00, 0, 0},
++ {0x3607, 0x00, 0, 0},
++ {0x3609, 0x12, 0, 0},
++ {0x360a, 0x40, 0, 0},
++ {0x360c, 0x08, 0, 0},
++ {0x360f, 0xe5, 0, 0},
++ {0x3608, 0x8f, 0, 0},
++ {0x3611, 0x00, 0, 0},
++ {0x3613, 0xf7, 0, 0},
++ {0x3616, 0x58, 0, 0},
++ {0x3619, 0x99, 0, 0},
++ {0x361b, 0x60, 0, 0},
++ {0x361c, 0x7a, 0, 0},
++ {0x361e, 0x79, 0, 0},
++ {0x361f, 0x02, 0, 0},
++ {0x3632, 0x05, 0, 0},
++ {0x3633, 0x10, 0, 0},
++ {0x3634, 0x10, 0, 0},
++ {0x3635, 0x10, 0, 0},
++ {0x3636, 0x15, 0, 0},
++ {0x3646, 0x86, 0, 0},
++ {0x364a, 0x0b, 0, 0},
++ {0x3700, 0x17, 0, 0},
++ {0x3701, 0x22, 0, 0},
++ {0x3703, 0x10, 0, 0},
++ {0x370a, 0x37, 0, 0},
++ {0x3705, 0x00, 0, 0},
++ {0x3706, 0x63, 0, 0},
++ {0x3709, 0x3c, 0, 0},
++ {0x370b, 0x01, 0, 0},
++ {0x370c, 0x30, 0, 0},
++ {0x3710, 0x24, 0, 0},
++ {0x3711, 0x0c, 0, 0},
++ {0x3716, 0x00, 0, 0},
++ {0x3720, 0x28, 0, 0},
++ {0x3729, 0x7b, 0, 0},
++ {0x372a, 0x84, 0, 0},
++ {0x372b, 0xbd, 0, 0},
++ {0x372c, 0xbc, 0, 0},
++ {0x372e, 0x52, 0, 0},
++ {0x373c, 0x0e, 0, 0},
++ {0x373e, 0x33, 0, 0},
++ {0x3743, 0x10, 0, 0},
++ {0x3744, 0x88, 0, 0},
++ {0x3745, 0xc0, 0, 0},
++ {0x374a, 0x43, 0, 0},
++ {0x374c, 0x00, 0, 0},
++ {0x374e, 0x23, 0, 0},
++ {0x3751, 0x7b, 0, 0},
++ {0x3752, 0x84, 0, 0},
++ {0x3753, 0xbd, 0, 0},
++ {0x3754, 0xbc, 0, 0},
++ {0x3756, 0x52, 0, 0},
++ {0x375c, 0x00, 0, 0},
++ {0x3760, 0x00, 0, 0},
++ {0x3761, 0x00, 0, 0},
++ {0x3762, 0x00, 0, 0},
++ {0x3763, 0x00, 0, 0},
++ {0x3764, 0x00, 0, 0},
++ {0x3767, 0x04, 0, 0},
++ {0x3768, 0x04, 0, 0},
++ {0x3769, 0x08, 0, 0},
++ {0x376a, 0x08, 0, 0},
++ {0x376b, 0x40, 0, 0},
++ {0x376c, 0x00, 0, 0},
++ {0x376d, 0x00, 0, 0},
++ {0x376e, 0x00, 0, 0},
++ {0x3773, 0x00, 0, 0},
++ {0x3774, 0x51, 0, 0},
++ {0x3776, 0xbd, 0, 0},
++ {0x3777, 0xbd, 0, 0},
++ {0x3781, 0x18, 0, 0},
++ {0x3783, 0x25, 0, 0},
++ {0x3798, 0x1b, 0, 0},
++ {0x3800, 0x00, 0, 0},
++ {0x3801, 0x48, 0, 0},
++ {0x3802, 0x00, 0, 0},
++ {0x3803, 0x2C, 0, 0},
++ {0x3804, 0x0a, 0, 0},
++ {0x3805, 0x57, 0, 0},
++ {0x3806, 0x05, 0, 0},
++ {0x3807, 0xD3, 0, 0},
++ {0x3808, 0x02, 0, 0},
++ {0x3809, 0x80, 0, 0},
++ {0x380a, 0x01, 0, 0},
++ {0x380b, 0xe0, 0, 0},
++
++ {0x380c, 0x02, 0, 0}, // 0a ; 03
++ {0x380d, 0x04, 0, 0}, // 1c ; 5C
++
++ {0x380e, 0x03, 0, 0},
++ {0x380f, 0x05, 0, 0},
++ {0x3810, 0x00, 0, 0},
++ {0x3811, 0x04, 0, 0},
++ {0x3812, 0x00, 0, 0},
++ {0x3813, 0x02, 0, 0},
++ {0x3814, 0x03, 0, 0},
++ {0x3815, 0x01, 0, 0},
++ {0x3819, 0x01, 0, 0},
++ {0x3820, 0x06, 0, 0},
++ {0x3821, 0x00, 0, 0},
++ {0x3829, 0x00, 0, 0},
++ {0x382a, 0x03, 0, 0},
++ {0x382b, 0x01, 0, 0},
++ {0x382d, 0x7f, 0, 0},
++ {0x3830, 0x08, 0, 0},
++ {0x3836, 0x02, 0, 0},
++ {0x3837, 0x00, 0, 0},
++ {0x3841, 0x02, 0, 0},
++ {0x3846, 0x08, 0, 0},
++ {0x3847, 0x07, 0, 0},
++ {0x3d85, 0x36, 0, 0},
++ {0x3d8c, 0x71, 0, 0},
++ {0x3d8d, 0xcb, 0, 0},
++ {0x3f0a, 0x00, 0, 0},
++ {0x4000, 0x71, 0, 0},
++ {0x4001, 0x50, 0, 0},
++ {0x4002, 0x04, 0, 0},
++ {0x4003, 0x14, 0, 0},
++ {0x400e, 0x00, 0, 0},
++ {0x4011, 0x00, 0, 0},
++ {0x401a, 0x00, 0, 0},
++ {0x401b, 0x00, 0, 0},
++ {0x401c, 0x00, 0, 0},
++ {0x401d, 0x00, 0, 0},
++ {0x401f, 0x00, 0, 0},
++ {0x4020, 0x00, 0, 0},
++ {0x4021, 0x10, 0, 0},
++ {0x4022, 0x03, 0, 0},
++ {0x4023, 0x93, 0, 0},
++ {0x4024, 0x04, 0, 0},
++ {0x4025, 0xC0, 0, 0},
++ {0x4026, 0x04, 0, 0},
++ {0x4027, 0xD0, 0, 0},
++ {0x4028, 0x00, 0, 0},
++ {0x4029, 0x02, 0, 0},
++ {0x402a, 0x06, 0, 0},
++ {0x402b, 0x04, 0, 0},
++ {0x402c, 0x02, 0, 0},
++ {0x402d, 0x02, 0, 0},
++ {0x402e, 0x0e, 0, 0},
++ {0x402f, 0x04, 0, 0},
++ {0x4302, 0xff, 0, 0},
++ {0x4303, 0xff, 0, 0},
++ {0x4304, 0x00, 0, 0},
++ {0x4305, 0x00, 0, 0},
++ {0x4306, 0x00, 0, 0},
++ {0x4308, 0x02, 0, 0},
++ {0x4500, 0x6c, 0, 0},
++ {0x4501, 0xc4, 0, 0},
++ {0x4502, 0x44, 0, 0},
++ {0x4503, 0x01, 0, 0},
++ {0x4600, 0x00, 0, 0},
++ {0x4601, 0x4F, 0, 0},
++ {0x4800, 0x04, 0, 0},
++ {0x4813, 0x08, 0, 0},
++ {0x481f, 0x40, 0, 0},
++ {0x4829, 0x78, 0, 0},
++ {0x4837, 0x10, 0, 0}, // 20 ; 10
++ {0x4b00, 0x2a, 0, 0},
++ {0x4b0d, 0x00, 0, 0},
++ {0x4d00, 0x04, 0, 0},
++ {0x4d01, 0x42, 0, 0},
++ {0x4d02, 0xd1, 0, 0},
++ {0x4d03, 0x93, 0, 0},
++ {0x4d04, 0xf5, 0, 0},
++ {0x4d05, 0xc1, 0, 0},
++ {0x5000, 0xf3, 0, 0},
++ {0x5001, 0x11, 0, 0},
++ {0x5004, 0x00, 0, 0},
++ {0x500a, 0x00, 0, 0},
++ {0x500b, 0x00, 0, 0},
++ {0x5032, 0x00, 0, 0},
++ {0x5040, 0x00, 0, 0},
++ {0x5050, 0x3c, 0, 0},
++ {0x5500, 0x00, 0, 0},
++ {0x5501, 0x10, 0, 0},
++ {0x5502, 0x01, 0, 0},
++ {0x5503, 0x0f, 0, 0},
++ {0x8000, 0x00, 0, 0},
++ {0x8001, 0x00, 0, 0},
++ {0x8002, 0x00, 0, 0},
++ {0x8003, 0x00, 0, 0},
++ {0x8004, 0x00, 0, 0},
++ {0x8005, 0x00, 0, 0},
++ {0x8006, 0x00, 0, 0},
++ {0x8007, 0x00, 0, 0},
++ {0x8008, 0x00, 0, 0},
++ {0x3638, 0x00, 0, 0},
++};
++
++static const struct reg_value ov4689_setting_720P_1280_720[] = {
++ //@@ RES_1280x720_2x_Bin_150fps_816Mbps
++ //OV4689_AM01B_1280x720_24M_2lane_816Mbps_150fps_20140210.txt
++ {0x0103, 0x01, 0, 0},
++ {0x3638, 0x00, 0, 0},
++ {0x0300, 0x00, 0, 0}, // 00
++ {0x0302, 0x22, 0, 0}, // 816Mbps 5a ; 64 ; 5a ; 78 ; 78 ; 2a
++ {0x0303, 0x00, 0, 0}, // 03 ; 01 ; 02 ;
++ {0x0304, 0x03, 0, 0},
++ {0x030b, 0x00, 0, 0},
++ {0x030d, 0x1e, 0, 0},
++ {0x030e, 0x04, 0, 0},
++ {0x030f, 0x01, 0, 0},
++ {0x0312, 0x01, 0, 0},
++ {0x031e, 0x00, 0, 0},
++ {0x3000, 0x20, 0, 0},
++ {0x3002, 0x00, 0, 0},
++ {0x3020, 0x93, 0, 0},
++ {0x3021, 0x03, 0, 0},
++ {0x3022, 0x01, 0, 0},
++ {0x3031, 0x0a, 0, 0},
++ {0x303f, 0x0c, 0, 0},
++ {0x3305, 0xf1, 0, 0},
++ {0x3307, 0x04, 0, 0},
++ {0x3309, 0x29, 0, 0},
++ {0x3500, 0x00, 0, 0},
++ {0x3501, 0x30, 0, 0},
++ {0x3502, 0x00, 0, 0},
++ {0x3503, 0x04, 0, 0},
++ {0x3504, 0x00, 0, 0},
++ {0x3505, 0x00, 0, 0},
++ {0x3506, 0x00, 0, 0},
++ {0x3507, 0x00, 0, 0},
++ {0x3508, 0x07, 0, 0},
++ {0x3509, 0x78, 0, 0}, // 8X
++ {0x350a, 0x00, 0, 0},
++ {0x350b, 0x00, 0, 0},
++ {0x350c, 0x00, 0, 0},
++ {0x350d, 0x00, 0, 0},
++ {0x350e, 0x00, 0, 0},
++ {0x350f, 0x80, 0, 0},
++ {0x3510, 0x00, 0, 0},
++ {0x3511, 0x00, 0, 0},
++ {0x3512, 0x00, 0, 0},
++ {0x3513, 0x00, 0, 0},
++ {0x3514, 0x00, 0, 0},
++ {0x3515, 0x80, 0, 0},
++ {0x3516, 0x00, 0, 0},
++ {0x3517, 0x00, 0, 0},
++ {0x3518, 0x00, 0, 0},
++ {0x3519, 0x00, 0, 0},
++ {0x351a, 0x00, 0, 0},
++ {0x351b, 0x80, 0, 0},
++ {0x351c, 0x00, 0, 0},
++ {0x351d, 0x00, 0, 0},
++ {0x351e, 0x00, 0, 0},
++ {0x351f, 0x00, 0, 0},
++ {0x3520, 0x00, 0, 0},
++ {0x3521, 0x80, 0, 0},
++ {0x3522, 0x08, 0, 0},
++ {0x3524, 0x08, 0, 0},
++ {0x3526, 0x08, 0, 0},
++ {0x3528, 0x08, 0, 0},
++ {0x352a, 0x08, 0, 0},
++ {0x3602, 0x00, 0, 0},
++ {0x3603, 0x40, 0, 0},
++ {0x3604, 0x02, 0, 0},
++ {0x3605, 0x00, 0, 0},
++ {0x3606, 0x00, 0, 0},
++ {0x3607, 0x00, 0, 0},
++ {0x3609, 0x12, 0, 0},
++ {0x360a, 0x40, 0, 0},
++ {0x360c, 0x08, 0, 0},
++ {0x360f, 0xe5, 0, 0},
++ {0x3608, 0x8f, 0, 0},
++ {0x3611, 0x00, 0, 0},
++ {0x3613, 0xf7, 0, 0},
++ {0x3616, 0x58, 0, 0},
++ {0x3619, 0x99, 0, 0},
++ {0x361b, 0x60, 0, 0},
++ {0x361c, 0x7a, 0, 0},
++ {0x361e, 0x79, 0, 0},
++ {0x361f, 0x02, 0, 0},
++ {0x3632, 0x05, 0, 0},
++ {0x3633, 0x10, 0, 0},
++ {0x3634, 0x10, 0, 0},
++ {0x3635, 0x10, 0, 0},
++ {0x3636, 0x15, 0, 0},
++ {0x3646, 0x86, 0, 0},
++ {0x364a, 0x0b, 0, 0},
++ {0x3700, 0x17, 0, 0},
++ {0x3701, 0x22, 0, 0},
++ {0x3703, 0x10, 0, 0},
++ {0x370a, 0x37, 0, 0},
++ {0x3705, 0x00, 0, 0},
++ {0x3706, 0x63, 0, 0},
++ {0x3709, 0x3c, 0, 0},
++ {0x370b, 0x01, 0, 0},
++ {0x370c, 0x30, 0, 0},
++ {0x3710, 0x24, 0, 0},
++ {0x3711, 0x0c, 0, 0},
++ {0x3716, 0x00, 0, 0},
++ {0x3720, 0x28, 0, 0},
++ {0x3729, 0x7b, 0, 0},
++ {0x372a, 0x84, 0, 0},
++ {0x372b, 0xbd, 0, 0},
++ {0x372c, 0xbc, 0, 0},
++ {0x372e, 0x52, 0, 0},
++ {0x373c, 0x0e, 0, 0},
++ {0x373e, 0x33, 0, 0},
++ {0x3743, 0x10, 0, 0},
++ {0x3744, 0x88, 0, 0},
++ {0x3745, 0xc0, 0, 0},
++ {0x374a, 0x43, 0, 0},
++ {0x374c, 0x00, 0, 0},
++ {0x374e, 0x23, 0, 0},
++ {0x3751, 0x7b, 0, 0},
++ {0x3752, 0x84, 0, 0},
++ {0x3753, 0xbd, 0, 0},
++ {0x3754, 0xbc, 0, 0},
++ {0x3756, 0x52, 0, 0},
++ {0x375c, 0x00, 0, 0},
++ {0x3760, 0x00, 0, 0},
++ {0x3761, 0x00, 0, 0},
++ {0x3762, 0x00, 0, 0},
++ {0x3763, 0x00, 0, 0},
++ {0x3764, 0x00, 0, 0},
++ {0x3767, 0x04, 0, 0},
++ {0x3768, 0x04, 0, 0},
++ {0x3769, 0x08, 0, 0},
++ {0x376a, 0x08, 0, 0},
++ {0x376b, 0x40, 0, 0},
++ {0x376c, 0x00, 0, 0},
++ {0x376d, 0x00, 0, 0},
++ {0x376e, 0x00, 0, 0},
++ {0x3773, 0x00, 0, 0},
++ {0x3774, 0x51, 0, 0},
++ {0x3776, 0xbd, 0, 0},
++ {0x3777, 0xbd, 0, 0},
++ {0x3781, 0x18, 0, 0},
++ {0x3783, 0x25, 0, 0},
++ {0x3798, 0x1b, 0, 0},
++ {0x3800, 0x00, 0, 0},
++ {0x3801, 0x48, 0, 0},
++ {0x3802, 0x00, 0, 0},
++ {0x3803, 0x2C, 0, 0},
++ {0x3804, 0x0a, 0, 0},
++ {0x3805, 0x57, 0, 0},
++ {0x3806, 0x05, 0, 0},
++ {0x3807, 0xD3, 0, 0},
++ {0x3808, 0x05, 0, 0},
++ {0x3809, 0x00, 0, 0},
++ {0x380a, 0x02, 0, 0},
++ {0x380b, 0xD0, 0, 0},
++#ifndef UNUSED_CODE
++ {0x380c, 0x04, 0, 0}, // 0a ; 03
++ {0x380d, 0x08, 0, 0}, // 1c ; 5C
++#else
++ {0x380c, 0x05, 0, 0}, // 120fps
++ {0x380d, 0x0A, 0, 0},
++#endif
++ {0x380e, 0x03, 0, 0},
++ {0x380f, 0x05, 0, 0},
++ {0x3810, 0x00, 0, 0},
++ {0x3811, 0x04, 0, 0},
++ {0x3812, 0x00, 0, 0},
++ {0x3813, 0x02, 0, 0},
++ {0x3814, 0x03, 0, 0},
++ {0x3815, 0x01, 0, 0},
++ {0x3819, 0x01, 0, 0},
++ {0x3820, 0x06, 0, 0},
++ {0x3821, 0x00, 0, 0},
++ {0x3829, 0x00, 0, 0},
++ {0x382a, 0x03, 0, 0},
++ {0x382b, 0x01, 0, 0},
++ {0x382d, 0x7f, 0, 0},
++ {0x3830, 0x08, 0, 0},
++ {0x3836, 0x02, 0, 0},
++ {0x3837, 0x00, 0, 0},
++ {0x3841, 0x02, 0, 0},
++ {0x3846, 0x08, 0, 0},
++ {0x3847, 0x07, 0, 0},
++ {0x3d85, 0x36, 0, 0},
++ {0x3d8c, 0x71, 0, 0},
++ {0x3d8d, 0xcb, 0, 0},
++ {0x3f0a, 0x00, 0, 0},
++ {0x4000, 0x71, 0, 0},
++ {0x4001, 0x50, 0, 0},
++ {0x4002, 0x04, 0, 0},
++ {0x4003, 0x14, 0, 0},
++ {0x400e, 0x00, 0, 0},
++ {0x4011, 0x00, 0, 0},
++ {0x401a, 0x00, 0, 0},
++ {0x401b, 0x00, 0, 0},
++ {0x401c, 0x00, 0, 0},
++ {0x401d, 0x00, 0, 0},
++ {0x401f, 0x00, 0, 0},
++ {0x4020, 0x00, 0, 0},
++ {0x4021, 0x10, 0, 0},
++ {0x4022, 0x03, 0, 0},
++ {0x4023, 0x93, 0, 0},
++ {0x4024, 0x04, 0, 0},
++ {0x4025, 0xC0, 0, 0},
++ {0x4026, 0x04, 0, 0},
++ {0x4027, 0xD0, 0, 0},
++ {0x4028, 0x00, 0, 0},
++ {0x4029, 0x02, 0, 0},
++ {0x402a, 0x06, 0, 0},
++ {0x402b, 0x04, 0, 0},
++ {0x402c, 0x02, 0, 0},
++ {0x402d, 0x02, 0, 0},
++ {0x402e, 0x0e, 0, 0},
++ {0x402f, 0x04, 0, 0},
++ {0x4302, 0xff, 0, 0},
++ {0x4303, 0xff, 0, 0},
++ {0x4304, 0x00, 0, 0},
++ {0x4305, 0x00, 0, 0},
++ {0x4306, 0x00, 0, 0},
++ {0x4308, 0x02, 0, 0},
++ {0x4500, 0x6c, 0, 0},
++ {0x4501, 0xc4, 0, 0},
++ {0x4502, 0x44, 0, 0},
++ {0x4503, 0x01, 0, 0},
++ {0x4600, 0x00, 0, 0},
++ {0x4601, 0x4F, 0, 0},
++ {0x4800, 0x04, 0, 0},
++ {0x4813, 0x08, 0, 0},
++ {0x481f, 0x40, 0, 0},
++ {0x4829, 0x78, 0, 0},
++ {0x4837, 0x10, 0, 0}, // 20 ; 10
++ {0x4b00, 0x2a, 0, 0},
++ {0x4b0d, 0x00, 0, 0},
++ {0x4d00, 0x04, 0, 0},
++ {0x4d01, 0x42, 0, 0},
++ {0x4d02, 0xd1, 0, 0},
++ {0x4d03, 0x93, 0, 0},
++ {0x4d04, 0xf5, 0, 0},
++ {0x4d05, 0xc1, 0, 0},
++ {0x5000, 0xf3, 0, 0},
++ {0x5001, 0x11, 0, 0},
++ {0x5004, 0x00, 0, 0},
++ {0x500a, 0x00, 0, 0},
++ {0x500b, 0x00, 0, 0},
++ {0x5032, 0x00, 0, 0},
++ {0x5040, 0x00, 0, 0},
++ {0x5050, 0x3c, 0, 0},
++ {0x5500, 0x00, 0, 0},
++ {0x5501, 0x10, 0, 0},
++ {0x5502, 0x01, 0, 0},
++ {0x5503, 0x0f, 0, 0},
++ {0x8000, 0x00, 0, 0},
++ {0x8001, 0x00, 0, 0},
++ {0x8002, 0x00, 0, 0},
++ {0x8003, 0x00, 0, 0},
++ {0x8004, 0x00, 0, 0},
++ {0x8005, 0x00, 0, 0},
++ {0x8006, 0x00, 0, 0},
++ {0x8007, 0x00, 0, 0},
++ {0x8008, 0x00, 0, 0},
++ {0x3638, 0x00, 0, 0},
++};
++
++static const struct reg_value ov4689_setting_1080P_1920_1080[] = {
++ //@@ RES_1920x1080_60fps_816Mbps 2lanes
++ {0x0103, 0x01, 0, 0},
++ {0x3638, 0x00, 0, 0},
++ {0x0300, 0x00, 0, 0}, // clk
++ {0x0302, 0x22, 0, 0},
++ {0x0303, 0x00, 0, 0},
++ {0x0304, 0x03, 0, 0},
++ {0x030b, 0x00, 0, 0},
++ {0x030d, 0x1e, 0, 0},
++ {0x030e, 0x04, 0, 0},
++ {0x030f, 0x01, 0, 0},
++ {0x0312, 0x01, 0, 0},
++ {0x031e, 0x00, 0, 0},
++ {0x3000, 0x20, 0, 0},
++ {0x3002, 0x00, 0, 0},
++ {0x3020, 0x93, 0, 0},
++ {0x3021, 0x03, 0, 0},
++ {0x3022, 0x01, 0, 0},
++ {0x3031, 0x0a, 0, 0},
++ {0x303f, 0x0c, 0, 0},
++ {0x3305, 0xf1, 0, 0},
++ {0x3307, 0x04, 0, 0},
++ {0x3309, 0x29, 0, 0},
++ {0x3500, 0x00, 0, 0}, // AEC
++ {0x3501, 0x4c, 0, 0},
++ {0x3502, 0x00, 0, 0},
++ {0x3503, 0x04, 0, 0},
++ {0x3504, 0x00, 0, 0},
++ {0x3505, 0x00, 0, 0},
++ {0x3506, 0x00, 0, 0},
++ {0x3507, 0x00, 0, 0},
++ {0x3508, 0x00, 0, 0},
++ {0x3509, 0x80, 0, 0},
++ {0x350a, 0x00, 0, 0},
++ {0x350b, 0x00, 0, 0},
++ {0x350c, 0x00, 0, 0},
++ {0x350d, 0x00, 0, 0},
++ {0x350e, 0x00, 0, 0},
++ {0x350f, 0x80, 0, 0},
++ {0x3510, 0x00, 0, 0},
++ {0x3511, 0x00, 0, 0},
++ {0x3512, 0x00, 0, 0},
++ {0x3513, 0x00, 0, 0},
++ {0x3514, 0x00, 0, 0},
++ {0x3515, 0x80, 0, 0},
++ {0x3516, 0x00, 0, 0},
++ {0x3517, 0x00, 0, 0},
++ {0x3518, 0x00, 0, 0},
++ {0x3519, 0x00, 0, 0},
++ {0x351a, 0x00, 0, 0},
++ {0x351b, 0x80, 0, 0},
++ {0x351c, 0x00, 0, 0},
++ {0x351d, 0x00, 0, 0},
++ {0x351e, 0x00, 0, 0},
++ {0x351f, 0x00, 0, 0},
++ {0x3520, 0x00, 0, 0},
++ {0x3521, 0x80, 0, 0},
++ {0x3522, 0x08, 0, 0},
++ {0x3524, 0x08, 0, 0},
++ {0x3526, 0x08, 0, 0},
++ {0x3528, 0x08, 0, 0},
++ {0x352a, 0x08, 0, 0},
++ {0x3602, 0x00, 0, 0},
++ {0x3603, 0x40, 0, 0},
++ {0x3604, 0x02, 0, 0},
++ {0x3605, 0x00, 0, 0},
++ {0x3606, 0x00, 0, 0},
++ {0x3607, 0x00, 0, 0},
++ {0x3609, 0x12, 0, 0},
++ {0x360a, 0x40, 0, 0},
++ {0x360c, 0x08, 0, 0},
++ {0x360f, 0xe5, 0, 0},
++ {0x3608, 0x8f, 0, 0},
++ {0x3611, 0x00, 0, 0},
++ {0x3613, 0xf7, 0, 0},
++ {0x3616, 0x58, 0, 0},
++ {0x3619, 0x99, 0, 0},
++ {0x361b, 0x60, 0, 0},
++ {0x361c, 0x7a, 0, 0},
++ {0x361e, 0x79, 0, 0},
++ {0x361f, 0x02, 0, 0},
++ {0x3632, 0x00, 0, 0},
++ {0x3633, 0x10, 0, 0},
++ {0x3634, 0x10, 0, 0},
++ {0x3635, 0x10, 0, 0},
++ {0x3636, 0x15, 0, 0},
++ {0x3646, 0x86, 0, 0},
++ {0x364a, 0x0b, 0, 0},
++ {0x3700, 0x17, 0, 0},
++ {0x3701, 0x22, 0, 0},
++ {0x3703, 0x10, 0, 0},
++ {0x370a, 0x37, 0, 0},
++ {0x3705, 0x00, 0, 0},
++ {0x3706, 0x63, 0, 0},
++ {0x3709, 0x3c, 0, 0},
++ {0x370b, 0x01, 0, 0},
++ {0x370c, 0x30, 0, 0},
++ {0x3710, 0x24, 0, 0},
++ {0x3711, 0x0c, 0, 0},
++ {0x3716, 0x00, 0, 0},
++ {0x3720, 0x28, 0, 0},
++ {0x3729, 0x7b, 0, 0},
++ {0x372a, 0x84, 0, 0},
++ {0x372b, 0xbd, 0, 0},
++ {0x372c, 0xbc, 0, 0},
++ {0x372e, 0x52, 0, 0},
++ {0x373c, 0x0e, 0, 0},
++ {0x373e, 0x33, 0, 0},
++ {0x3743, 0x10, 0, 0},
++ {0x3744, 0x88, 0, 0},
++ {0x3745, 0xc0, 0, 0},
++ {0x374a, 0x43, 0, 0},
++ {0x374c, 0x00, 0, 0},
++ {0x374e, 0x23, 0, 0},
++ {0x3751, 0x7b, 0, 0},
++ {0x3752, 0x84, 0, 0},
++ {0x3753, 0xbd, 0, 0},
++ {0x3754, 0xbc, 0, 0},
++ {0x3756, 0x52, 0, 0},
++ {0x375c, 0x00, 0, 0},
++ {0x3760, 0x00, 0, 0},
++ {0x3761, 0x00, 0, 0},
++ {0x3762, 0x00, 0, 0},
++ {0x3763, 0x00, 0, 0},
++ {0x3764, 0x00, 0, 0},
++ {0x3767, 0x04, 0, 0},
++ {0x3768, 0x04, 0, 0},
++ {0x3769, 0x08, 0, 0},
++ {0x376a, 0x08, 0, 0},
++ {0x376b, 0x20, 0, 0},
++ {0x376c, 0x00, 0, 0},
++ {0x376d, 0x00, 0, 0},
++ {0x376e, 0x00, 0, 0},
++ {0x3773, 0x00, 0, 0},
++ {0x3774, 0x51, 0, 0},
++ {0x3776, 0xbd, 0, 0},
++ {0x3777, 0xbd, 0, 0},
++ {0x3781, 0x18, 0, 0},
++ {0x3783, 0x25, 0, 0},
++ {0x3798, 0x1b, 0, 0},
++ {0x3800, 0x01, 0, 0}, // timings
++ {0x3801, 0x88, 0, 0},
++ {0x3802, 0x00, 0, 0},
++ {0x3803, 0xe0, 0, 0},
++ {0x3804, 0x09, 0, 0},
++ {0x3805, 0x17, 0, 0},
++ {0x3806, 0x05, 0, 0},
++ {0x3807, 0x1f, 0, 0},
++ {0x3808, 0x07, 0, 0},
++ {0x3809, 0x80, 0, 0},
++ {0x380a, 0x04, 0, 0},
++ {0x380b, 0x38, 0, 0},
++ {0x380c, 0x06, 0, 0},
++ {0x380d, 0xe0, 0, 0},
++ {0x380e, 0x04, 0, 0},
++ {0x380f, 0x70, 0, 0},
++ {0x3810, 0x00, 0, 0},
++ {0x3811, 0x08, 0, 0},
++ {0x3812, 0x00, 0, 0},
++ {0x3813, 0x04, 0, 0},
++ {0x3814, 0x01, 0, 0},
++ {0x3815, 0x01, 0, 0},
++ {0x3819, 0x01, 0, 0},
++ {0x3820, 0x06, 0, 0},
++ {0x3821, 0x00, 0, 0},
++ {0x3829, 0x00, 0, 0},
++ {0x382a, 0x01, 0, 0},
++ {0x382b, 0x01, 0, 0},
++ {0x382d, 0x7f, 0, 0},
++ {0x3830, 0x04, 0, 0},
++ {0x3836, 0x01, 0, 0},
++ {0x3837, 0x00, 0, 0},
++ {0x3841, 0x02, 0, 0},
++ {0x3846, 0x08, 0, 0},
++ {0x3847, 0x07, 0, 0},
++ {0x3d85, 0x36, 0, 0},
++ {0x3d8c, 0x71, 0, 0},
++ {0x3d8d, 0xcb, 0, 0},
++ {0x3f0a, 0x00, 0, 0},
++ {0x4000, 0xf1, 0, 0},
++ {0x4001, 0x40, 0, 0},
++ {0x4002, 0x04, 0, 0},
++ {0x4003, 0x14, 0, 0},
++ {0x400e, 0x00, 0, 0},
++ {0x4011, 0x00, 0, 0},
++ {0x401a, 0x00, 0, 0},
++ {0x401b, 0x00, 0, 0},
++ {0x401c, 0x00, 0, 0},
++ {0x401d, 0x00, 0, 0},
++ {0x401f, 0x00, 0, 0},
++ {0x4020, 0x00, 0, 0},
++ {0x4021, 0x10, 0, 0},
++ {0x4022, 0x06, 0, 0},
++ {0x4023, 0x13, 0, 0},
++ {0x4024, 0x07, 0, 0},
++ {0x4025, 0x40, 0, 0},
++ {0x4026, 0x07, 0, 0},
++ {0x4027, 0x50, 0, 0},
++ {0x4028, 0x00, 0, 0},
++ {0x4029, 0x02, 0, 0},
++ {0x402a, 0x06, 0, 0},
++ {0x402b, 0x04, 0, 0},
++ {0x402c, 0x02, 0, 0},
++ {0x402d, 0x02, 0, 0},
++ {0x402e, 0x0e, 0, 0},
++ {0x402f, 0x04, 0, 0},
++ {0x4302, 0xff, 0, 0},
++ {0x4303, 0xff, 0, 0},
++ {0x4304, 0x00, 0, 0},
++ {0x4305, 0x00, 0, 0},
++ {0x4306, 0x00, 0, 0},
++ {0x4308, 0x02, 0, 0},
++ {0x4500, 0x6c, 0, 0},
++ {0x4501, 0xc4, 0, 0},
++ {0x4502, 0x40, 0, 0},
++ {0x4503, 0x01, 0, 0},
++ {0x4601, 0x77, 0, 0},
++ {0x4800, 0x04, 0, 0},
++ {0x4813, 0x08, 0, 0},
++ {0x481f, 0x40, 0, 0},
++ {0x4829, 0x78, 0, 0},
++ {0x4837, 0x10, 0, 0},
++ {0x4b00, 0x2a, 0, 0},
++ {0x4b0d, 0x00, 0, 0},
++ {0x4d00, 0x04, 0, 0},
++ {0x4d01, 0x42, 0, 0},
++ {0x4d02, 0xd1, 0, 0},
++ {0x4d03, 0x93, 0, 0},
++ {0x4d04, 0xf5, 0, 0},
++ {0x4d05, 0xc1, 0, 0},
++ {0x5000, 0xf3, 0, 0},
++ {0x5001, 0x11, 0, 0},
++ {0x5004, 0x00, 0, 0},
++ {0x500a, 0x00, 0, 0},
++ {0x500b, 0x00, 0, 0},
++ {0x5032, 0x00, 0, 0},
++ {0x5040, 0x00, 0, 0},
++ {0x5050, 0x0c, 0, 0},
++ {0x5500, 0x00, 0, 0},
++ {0x5501, 0x10, 0, 0},
++ {0x5502, 0x01, 0, 0},
++ {0x5503, 0x0f, 0, 0},
++ {0x8000, 0x00, 0, 0},
++ {0x8001, 0x00, 0, 0},
++ {0x8002, 0x00, 0, 0},
++ {0x8003, 0x00, 0, 0},
++ {0x8004, 0x00, 0, 0},
++ {0x8005, 0x00, 0, 0},
++ {0x8006, 0x00, 0, 0},
++ {0x8007, 0x00, 0, 0},
++ {0x8008, 0x00, 0, 0},
++ {0x3638, 0x00, 0, 0},
++};
++
++static const struct reg_value ov4689_setting_4M_2688_1520[] = {
++ //@@ 0 10 RES_2688x1520_default(60fps)
++ //102 2630 960
++ {0x0103, 0x01, 0, 0},
++ {0x3638, 0x00, 0, 0},
++ {0x0300, 0x00, 0, 0},
++ {0x0302, 0x22, 0, 0}, // 2a ;1008Mbps,23 ;; 840Mbps
++ {0x0304, 0x03, 0, 0},
++ {0x030b, 0x00, 0, 0},
++ {0x030d, 0x1e, 0, 0},
++ {0x030e, 0x04, 0, 0},
++ {0x030f, 0x01, 0, 0},
++ {0x0312, 0x01, 0, 0},
++ {0x031e, 0x00, 0, 0},
++ {0x3000, 0x20, 0, 0},
++ {0x3002, 0x00, 0, 0},
++ {0x3020, 0x93, 0, 0},
++ {0x3021, 0x03, 0, 0},
++ {0x3022, 0x01, 0, 0},
++ {0x3031, 0x0a, 0, 0},
++ {0x303f, 0x0c, 0, 0},
++ {0x3305, 0xf1, 0, 0},
++ {0x3307, 0x04, 0, 0},
++ {0x3309, 0x29, 0, 0},
++ {0x3500, 0x00, 0, 0},
++ {0x3501, 0x60, 0, 0},
++ {0x3502, 0x00, 0, 0},
++ {0x3503, 0x04, 0, 0},
++ {0x3504, 0x00, 0, 0},
++ {0x3505, 0x00, 0, 0},
++ {0x3506, 0x00, 0, 0},
++ {0x3507, 0x00, 0, 0},
++ {0x3508, 0x00, 0, 0},
++ {0x3509, 0x80, 0, 0},
++ {0x350a, 0x00, 0, 0},
++ {0x350b, 0x00, 0, 0},
++ {0x350c, 0x00, 0, 0},
++ {0x350d, 0x00, 0, 0},
++ {0x350e, 0x00, 0, 0},
++ {0x350f, 0x80, 0, 0},
++ {0x3510, 0x00, 0, 0},
++ {0x3511, 0x00, 0, 0},
++ {0x3512, 0x00, 0, 0},
++ {0x3513, 0x00, 0, 0},
++ {0x3514, 0x00, 0, 0},
++ {0x3515, 0x80, 0, 0},
++ {0x3516, 0x00, 0, 0},
++ {0x3517, 0x00, 0, 0},
++ {0x3518, 0x00, 0, 0},
++ {0x3519, 0x00, 0, 0},
++ {0x351a, 0x00, 0, 0},
++ {0x351b, 0x80, 0, 0},
++ {0x351c, 0x00, 0, 0},
++ {0x351d, 0x00, 0, 0},
++ {0x351e, 0x00, 0, 0},
++ {0x351f, 0x00, 0, 0},
++ {0x3520, 0x00, 0, 0},
++ {0x3521, 0x80, 0, 0},
++ {0x3522, 0x08, 0, 0},
++ {0x3524, 0x08, 0, 0},
++ {0x3526, 0x08, 0, 0},
++ {0x3528, 0x08, 0, 0},
++ {0x352a, 0x08, 0, 0},
++ {0x3602, 0x00, 0, 0},
++ {0x3603, 0x40, 0, 0},
++ {0x3604, 0x02, 0, 0},
++ {0x3605, 0x00, 0, 0},
++ {0x3606, 0x00, 0, 0},
++ {0x3607, 0x00, 0, 0},
++ {0x3609, 0x12, 0, 0},
++ {0x360a, 0x40, 0, 0},
++ {0x360c, 0x08, 0, 0},
++ {0x360f, 0xe5, 0, 0},
++ {0x3608, 0x8f, 0, 0},
++ {0x3611, 0x00, 0, 0},
++ {0x3613, 0xf7, 0, 0},
++ {0x3616, 0x58, 0, 0},
++ {0x3619, 0x99, 0, 0},
++ {0x361b, 0x60, 0, 0},
++ {0x361c, 0x7a, 0, 0},
++ {0x361e, 0x79, 0, 0},
++ {0x361f, 0x02, 0, 0},
++ {0x3632, 0x00, 0, 0},
++ {0x3633, 0x10, 0, 0},
++ {0x3634, 0x10, 0, 0},
++ {0x3635, 0x10, 0, 0},
++ {0x3636, 0x15, 0, 0},
++ {0x3646, 0x86, 0, 0},
++ {0x364a, 0x0b, 0, 0},
++ {0x3700, 0x17, 0, 0},
++ {0x3701, 0x22, 0, 0},
++ {0x3703, 0x10, 0, 0},
++ {0x370a, 0x37, 0, 0},
++ {0x3705, 0x00, 0, 0},
++ {0x3706, 0x63, 0, 0},
++ {0x3709, 0x3c, 0, 0},
++ {0x370b, 0x01, 0, 0},
++ {0x370c, 0x30, 0, 0},
++ {0x3710, 0x24, 0, 0},
++ {0x3711, 0x0c, 0, 0},
++ {0x3716, 0x00, 0, 0},
++ {0x3720, 0x28, 0, 0},
++ {0x3729, 0x7b, 0, 0},
++ {0x372a, 0x84, 0, 0},
++ {0x372b, 0xbd, 0, 0},
++ {0x372c, 0xbc, 0, 0},
++ {0x372e, 0x52, 0, 0},
++ {0x373c, 0x0e, 0, 0},
++ {0x373e, 0x33, 0, 0},
++ {0x3743, 0x10, 0, 0},
++ {0x3744, 0x88, 0, 0},
++ {0x3745, 0xc0, 0, 0},
++ {0x374a, 0x43, 0, 0},
++ {0x374c, 0x00, 0, 0},
++ {0x374e, 0x23, 0, 0},
++ {0x3751, 0x7b, 0, 0},
++ {0x3752, 0x84, 0, 0},
++ {0x3753, 0xbd, 0, 0},
++ {0x3754, 0xbc, 0, 0},
++ {0x3756, 0x52, 0, 0},
++ {0x375c, 0x00, 0, 0},
++ {0x3760, 0x00, 0, 0},
++ {0x3761, 0x00, 0, 0},
++ {0x3762, 0x00, 0, 0},
++ {0x3763, 0x00, 0, 0},
++ {0x3764, 0x00, 0, 0},
++ {0x3767, 0x04, 0, 0},
++ {0x3768, 0x04, 0, 0},
++ {0x3769, 0x08, 0, 0},
++ {0x376a, 0x08, 0, 0},
++ {0x376b, 0x20, 0, 0},
++ {0x376c, 0x00, 0, 0},
++ {0x376d, 0x00, 0, 0},
++ {0x376e, 0x00, 0, 0},
++ {0x3773, 0x00, 0, 0},
++ {0x3774, 0x51, 0, 0},
++ {0x3776, 0xbd, 0, 0},
++ {0x3777, 0xbd, 0, 0},
++ {0x3781, 0x18, 0, 0},
++ {0x3783, 0x25, 0, 0},
++ {0x3798, 0x1b, 0, 0},
++ {0x3800, 0x00, 0, 0},
++ {0x3801, 0x08, 0, 0},
++ {0x3802, 0x00, 0, 0},
++ {0x3803, 0x04, 0, 0},
++ {0x3804, 0x0a, 0, 0},
++ {0x3805, 0x97, 0, 0},
++ {0x3806, 0x05, 0, 0},
++ {0x3807, 0xfb, 0, 0},
++ {0x3808, 0x0a, 0, 0},
++ {0x3809, 0x80, 0, 0},
++ {0x380a, 0x05, 0, 0},
++ {0x380b, 0xf0, 0, 0},
++ {0x380c, 0x03, 0, 0},
++ {0x380d, 0x5c, 0, 0},
++ {0x380e, 0x06, 0, 0},
++ {0x380f, 0x12, 0, 0},
++ {0x3810, 0x00, 0, 0},
++ {0x3811, 0x08, 0, 0},
++ {0x3812, 0x00, 0, 0},
++ {0x3813, 0x04, 0, 0},
++ {0x3814, 0x01, 0, 0},
++ {0x3815, 0x01, 0, 0},
++ {0x3819, 0x01, 0, 0},
++ {0x3820, 0x00, 0, 0},
++ {0x3821, 0x06, 0, 0},
++ {0x3829, 0x00, 0, 0},
++ {0x382a, 0x01, 0, 0},
++ {0x382b, 0x01, 0, 0},
++ {0x382d, 0x7f, 0, 0},
++ {0x3830, 0x04, 0, 0},
++ {0x3836, 0x01, 0, 0},
++ {0x3837, 0x00, 0, 0},
++ {0x3841, 0x02, 0, 0},
++ {0x3846, 0x08, 0, 0},
++ {0x3847, 0x07, 0, 0},
++ {0x3d85, 0x36, 0, 0},
++ {0x3d8c, 0x71, 0, 0},
++ {0x3d8d, 0xcb, 0, 0},
++ {0x3f0a, 0x00, 0, 0},
++ {0x4000, 0x71, 0, 0},
++ {0x4001, 0x40, 0, 0},
++ {0x4002, 0x04, 0, 0},
++ {0x4003, 0x14, 0, 0},
++ {0x400e, 0x00, 0, 0},
++ {0x4011, 0x00, 0, 0},
++ {0x401a, 0x00, 0, 0},
++ {0x401b, 0x00, 0, 0},
++ {0x401c, 0x00, 0, 0},
++ {0x401d, 0x00, 0, 0},
++ {0x401f, 0x00, 0, 0},
++ {0x4020, 0x00, 0, 0},
++ {0x4021, 0x10, 0, 0},
++ {0x4022, 0x07, 0, 0},
++ {0x4023, 0xcf, 0, 0},
++ {0x4024, 0x09, 0, 0},
++ {0x4025, 0x60, 0, 0},
++ {0x4026, 0x09, 0, 0},
++ {0x4027, 0x6f, 0, 0},
++ {0x4028, 0x00, 0, 0},
++ {0x4029, 0x02, 0, 0},
++ {0x402a, 0x06, 0, 0},
++ {0x402b, 0x04, 0, 0},
++ {0x402c, 0x02, 0, 0},
++ {0x402d, 0x02, 0, 0},
++ {0x402e, 0x0e, 0, 0},
++ {0x402f, 0x04, 0, 0},
++ {0x4302, 0xff, 0, 0},
++ {0x4303, 0xff, 0, 0},
++ {0x4304, 0x00, 0, 0},
++ {0x4305, 0x00, 0, 0},
++ {0x4306, 0x00, 0, 0},
++ {0x4308, 0x02, 0, 0},
++ {0x4500, 0x6c, 0, 0},
++ {0x4501, 0xc4, 0, 0},
++ {0x4502, 0x40, 0, 0},
++ {0x4503, 0x01, 0, 0},
++ {0x4601, 0x04, 0, 0},
++ {0x4800, 0x04, 0, 0},
++ {0x4813, 0x08, 0, 0},
++ {0x481f, 0x40, 0, 0},
++ {0x4829, 0x78, 0, 0},
++ {0x4837, 0x14, 0, 0}, // 10
++ {0x4b00, 0x2a, 0, 0},
++ {0x4b0d, 0x00, 0, 0},
++ {0x4d00, 0x04, 0, 0},
++ {0x4d01, 0x42, 0, 0},
++ {0x4d02, 0xd1, 0, 0},
++ {0x4d03, 0x93, 0, 0},
++ {0x4d04, 0xf5, 0, 0},
++ {0x4d05, 0xc1, 0, 0},
++ {0x5000, 0xf3, 0, 0},
++ {0x5001, 0x11, 0, 0},
++ {0x5004, 0x00, 0, 0},
++ {0x500a, 0x00, 0, 0},
++ {0x500b, 0x00, 0, 0},
++ {0x5032, 0x00, 0, 0},
++ {0x5040, 0x00, 0, 0},
++ {0x5050, 0x0c, 0, 0},
++ {0x5500, 0x00, 0, 0},
++ {0x5501, 0x10, 0, 0},
++ {0x5502, 0x01, 0, 0},
++ {0x5503, 0x0f, 0, 0},
++ {0x8000, 0x00, 0, 0},
++ {0x8001, 0x00, 0, 0},
++ {0x8002, 0x00, 0, 0},
++ {0x8003, 0x00, 0, 0},
++ {0x8004, 0x00, 0, 0},
++ {0x8005, 0x00, 0, 0},
++ {0x8006, 0x00, 0, 0},
++ {0x8007, 0x00, 0, 0},
++ {0x8008, 0x00, 0, 0},
++ {0x3638, 0x00, 0, 0},
++// {0x0100, 0x01, 0, 0},
++
++// {0x0100, 0x00, 0, 0},
++ {0x380c, 0x0A, 0, 0}, // 05
++ {0x380d, 0x0A, 0, 0}, // 10
++ {0x380e, 0x06, 0, 0},
++ {0x380f, 0x12, 0, 0},
++// {0x0100, 0x01, 0, 0},
++ {0x3105, 0x31, 0, 0},
++ {0x301a, 0xf9, 0, 0},
++ {0x3508, 0x07, 0, 0},
++ {0x484b, 0x05, 0, 0},
++ {0x4805, 0x03, 0, 0},
++ {0x3601, 0x01, 0, 0},
++ {0x3745, 0xc0, 0, 0},
++ {0x3798, 0x1b, 0, 0},
++// {0x0100, 0x01, 0, 0},
++ {0xffff, 0x0a, 0, 0},
++ {0x3105, 0x11, 0, 0},
++ {0x301a, 0xf1, 0, 0},
++ {0x4805, 0x00, 0, 0},
++ {0x301a, 0xf0, 0, 0},
++ {0x3208, 0x00, 0, 0},
++ {0x302a, 0x00, 0, 0},
++ {0x302a, 0x00, 0, 0},
++ {0x302a, 0x00, 0, 0},
++ {0x302a, 0x00, 0, 0},
++ {0x302a, 0x00, 0, 0},
++ {0x3601, 0x00, 0, 0},
++ {0x3638, 0x00, 0, 0},
++ {0x3208, 0x10, 0, 0},
++ {0x3208, 0xa0, 0, 0},
++};
++
++/* power-on sensor init reg table */
++static const struct ov4689_mode_info ov4689_mode_init_data = {
++
++};
++
++static const struct ov4689_mode_info
++ov4689_mode_data[OV4689_NUM_MODES] = {
++ // {OV4689_MODE_720P_1280_720, SUBSAMPLING,
++ // 1280, 0x408, 720, 0x305,
++ // ov4689_setting_720P_1280_720,
++ // ARRAY_SIZE(ov4689_setting_720P_1280_720),
++ // OV4689_150_FPS},
++ // {OV4689_MODE_1080P_1920_1080, SCALING,
++ // 1920, 0x6e0, 1080, 0x470,
++ // ov4689_setting_1080P_1920_1080,
++ // ARRAY_SIZE(ov4689_setting_1080P_1920_1080),
++ // OV4689_60_FPS},
++ // {OV4689_MODE_4M_2688_1520, SCALING,
++ // 2688, 0xa0a, 1520, 0x612,
++ // ov4689_setting_4M_2688_1520,
++ // ARRAY_SIZE(ov4689_setting_4M_2688_1520),
++ // OV4689_60_FPS},
++
++ {OV4689_MODE_1080P_1920_1080, SCALING,
++ 1920, 0x6e0, 1080, 0x470,
++ ov4689_init_setting_30fps_1080P,
++ ARRAY_SIZE(ov4689_init_setting_30fps_1080P),
++ OV4689_60_FPS},
++};
++
++static int ov4689_write_reg(struct ov4689_dev *sensor, u16 reg, u8 val)
++{
++ struct i2c_client *client = sensor->i2c_client;
++ struct i2c_msg msg;
++ u8 buf[3];
++ int ret;
++
++ buf[0] = reg >> 8;
++ buf[1] = reg & 0xff;
++ buf[2] = val;
++
++ msg.addr = client->addr;
++ msg.flags = client->flags;
++ msg.buf = buf;
++ msg.len = sizeof(buf);
++
++ ret = i2c_transfer(client->adapter, &msg, 1);
++ if (ret < 0) {
++ dev_err(&client->dev, "%s: error: reg=%x, val=%x\n",
++ __func__, reg, val);
++ return ret;
++ }
++
++ return 0;
++}
++
++static int ov4689_read_reg(struct ov4689_dev *sensor, u16 reg, u8 *val)
++{
++ struct i2c_client *client = sensor->i2c_client;
++ struct i2c_msg msg[2];
++ u8 buf[2];
++ int ret;
++
++ buf[0] = reg >> 8;
++ buf[1] = reg & 0xff;
++
++ msg[0].addr = client->addr;
++ msg[0].flags = client->flags;
++ msg[0].buf = buf;
++ msg[0].len = sizeof(buf);
++
++ msg[1].addr = client->addr;
++ msg[1].flags = client->flags | I2C_M_RD;
++ msg[1].buf = buf;
++ msg[1].len = 1;
++
++ ret = i2c_transfer(client->adapter, msg, 2);
++ if (ret < 0) {
++ dev_err(&client->dev, "%s: error: reg=%x\n",
++ __func__, reg);
++ return ret;
++ }
++
++ *val = buf[0];
++ return 0;
++}
++
++static int ov4689_read_reg16(struct ov4689_dev *sensor, u16 reg, u16 *val)
++{
++ u8 hi, lo;
++ int ret;
++
++ ret = ov4689_read_reg(sensor, reg, &hi);
++ if (ret)
++ return ret;
++ ret = ov4689_read_reg(sensor, reg + 1, &lo);
++ if (ret)
++ return ret;
++
++ *val = ((u16)hi << 8) | (u16)lo;
++ return 0;
++}
++
++static int ov4689_write_reg16(struct ov4689_dev *sensor, u16 reg, u16 val)
++{
++ int ret;
++
++ ret = ov4689_write_reg(sensor, reg, val >> 8);
++ if (ret)
++ return ret;
++
++ return ov4689_write_reg(sensor, reg + 1, val & 0xff);
++}
++
++static int ov4689_mod_reg(struct ov4689_dev *sensor, u16 reg,
++ u8 mask, u8 val)
++{
++ u8 readval;
++ int ret;
++
++ ret = ov4689_read_reg(sensor, reg, &readval);
++ if (ret)
++ return ret;
++
++ readval &= ~mask;
++ val &= mask;
++ val |= readval;
++
++ return ov4689_write_reg(sensor, reg, val);
++}
++
++static int ov4689_set_timings(struct ov4689_dev *sensor,
++ const struct ov4689_mode_info *mode)
++{
++ return 0;
++}
++
++static int ov4689_load_regs(struct ov4689_dev *sensor,
++ const struct ov4689_mode_info *mode)
++{
++ const struct reg_value *regs = mode->reg_data;
++ unsigned int i;
++ u32 delay_ms;
++ u16 reg_addr;
++ u8 mask, val;
++ int ret = 0;
++
++ st_info(ST_SENSOR, "%s, mode = 0x%x\n", __func__, mode->id);
++ for (i = 0; i < mode->reg_data_size; ++i, ++regs) {
++ delay_ms = regs->delay_ms;
++ reg_addr = regs->reg_addr;
++ val = regs->val;
++ mask = regs->mask;
++
++ if (mask)
++ ret = ov4689_mod_reg(sensor, reg_addr, mask, val);
++ else
++ ret = ov4689_write_reg(sensor, reg_addr, val);
++ if (ret)
++ break;
++
++ if (delay_ms)
++ usleep_range(1000 * delay_ms, 1000 * delay_ms + 100);
++ }
++
++ return ov4689_set_timings(sensor, mode);
++}
++
++#ifdef UNUSED_CODE
++static int ov4689_get_exposure(struct ov4689_dev *sensor)
++{
++ int exp, ret;
++ u8 temp;
++
++ ret = ov4689_read_reg(sensor, OV4689_REG_EXPOSURE_HI, &temp);
++ if (ret)
++ return ret;
++ exp = ((int)temp & 0x0f) << 16;
++ ret = ov4689_read_reg(sensor, OV4689_REG_EXPOSURE_MED, &temp);
++ if (ret)
++ return ret;
++ exp |= ((int)temp << 8);
++ ret = ov4689_read_reg(sensor, OV4689_REG_EXPOSURE_LO, &temp);
++ if (ret)
++ return ret;
++ exp |= (int)temp;
++
++ return exp >> 4;
++}
++#endif
++
++static int ov4689_set_exposure(struct ov4689_dev *sensor, u32 exposure)
++{
++ int ret;
++
++ st_info(ST_SENSOR, "%s, exposure = 0x%x\n", __func__, exposure);
++ exposure <<= 4;
++
++ ret = ov4689_write_reg(sensor,
++ OV4689_REG_EXPOSURE_LO,
++ exposure & 0xff);
++ if (ret)
++ return ret;
++ ret = ov4689_write_reg(sensor,
++ OV4689_REG_EXPOSURE_MED,
++ (exposure >> 8) & 0xff);
++ if (ret)
++ return ret;
++ return ov4689_write_reg(sensor,
++ OV4689_REG_EXPOSURE_HI,
++ (exposure >> 16) & 0x0f);
++}
++
++static int ov4689_get_gain(struct ov4689_dev *sensor)
++{
++ u32 gain = 0;
++ u8 val;
++
++ ov4689_read_reg(sensor, OV4689_REG_GAIN_H, &val);
++ gain = (val & 0x3) << 16;
++ ov4689_read_reg(sensor, OV4689_REG_GAIN_M, &val);
++ gain |= val << 8;
++ ov4689_read_reg(sensor, OV4689_REG_GAIN_L, &val);
++ gain |= val;
++
++ return gain;
++}
++
++static int ov4689_set_gain(struct ov4689_dev *sensor, int gain)
++{
++ ov4689_write_reg(sensor, OV4689_REG_GAIN_H,
++ (gain >> 16) & 0x3);
++ ov4689_write_reg(sensor, OV4689_REG_GAIN_M,
++ (gain >> 8) & 0xff);
++ ov4689_write_reg(sensor, OV4689_REG_GAIN_L,
++ gain & 0xff);
++ return 0;
++}
++
++#ifdef UNUSED_CODE
++static int ov4689_get_sysclk(struct ov4689_dev *sensor)
++{
++ return 0;
++}
++
++static int ov4689_set_night_mode(struct ov4689_dev *sensor)
++{
++ return 0;
++}
++
++static int ov4689_get_hts(struct ov4689_dev *sensor)
++{
++ /* read HTS from register settings */
++ u16 hts;
++ int ret;
++
++ ret = ov4689_read_reg16(sensor, OV4689_REG_TIMING_HTS, &hts);
++ if (ret)
++ return ret;
++ return hts;
++}
++#endif
++
++static int ov4689_get_vts(struct ov4689_dev *sensor)
++{
++ u16 vts;
++ int ret;
++
++ ret = ov4689_read_reg16(sensor, OV4689_REG_TIMING_VTS, &vts);
++ if (ret)
++ return ret;
++ return vts;
++}
++
++#ifdef UNUSED_CODE
++static int ov4689_set_vts(struct ov4689_dev *sensor, int vts)
++{
++ return ov4689_write_reg16(sensor, OV4689_REG_TIMING_VTS, vts);
++}
++
++static int ov4689_get_light_freq(struct ov4689_dev *sensor)
++{
++ return 0;
++}
++
++static int ov4689_set_bandingfilter(struct ov4689_dev *sensor)
++{
++ return 0;
++}
++
++static int ov4689_set_ae_target(struct ov4689_dev *sensor, int target)
++{
++ return 0;
++}
++
++static int ov4689_get_binning(struct ov4689_dev *sensor)
++{
++ return 0;
++}
++
++static int ov4689_set_binning(struct ov4689_dev *sensor, bool enable)
++{
++ return 0;
++}
++#endif
++
++static const struct ov4689_mode_info *
++ov4689_find_mode(struct ov4689_dev *sensor, enum ov4689_frame_rate fr,
++ int width, int height, bool nearest)
++{
++ const struct ov4689_mode_info *mode;
++
++ mode = v4l2_find_nearest_size(ov4689_mode_data,
++ ARRAY_SIZE(ov4689_mode_data),
++ hact, vact,
++ width, height);
++
++ if (!mode ||
++ (!nearest && (mode->hact != width || mode->vact != height)))
++ return NULL;
++
++ /* Check to see if the current mode exceeds the max frame rate */
++ if (ov4689_framerates[fr] > ov4689_framerates[mode->max_fps])
++ return NULL;
++
++ return mode;
++}
++
++static u64 ov4689_calc_pixel_rate(struct ov4689_dev *sensor)
++{
++ u64 rate;
++
++ rate = sensor->current_mode->vact * sensor->current_mode->hact;
++ rate *= ov4689_framerates[sensor->current_fr];
++
++ return rate;
++}
++
++/*
++ * After trying the various combinations, reading various
++ * documentations spread around the net, and from the various
++ * feedback, the clock tree is probably as follows:
++ *
++ * +--------------+
++ * | Ext. Clock |
++ * +-+------------+
++ * | +----------+
++ * +->| PLL1 | - reg 0x030a, bit0 for the pre-dividerp
++ * +-+--------+ - reg 0x0300, bits 0-2 for the pre-divider
++ * +-+--------+ - reg 0x0301~0x0302, for the multiplier
++ * | +--------------+
++ * +->| MIPI Divider | - reg 0x0303, bits 0-3 for the pre-divider
++ * | +---------> MIPI PHY CLK
++ * | +-----+
++ * | +->| PLL1_DIV_MIPI | - reg 0x0304, bits 0-1 for the divider
++ * | +----------------> PCLK
++ * | +-----+
++ *
++ * +--------------+
++ * | Ext. Clock |
++ * +-+------------+
++ * | +----------+
++ * +->| PLL2 | - reg 0x0311, bit0 for the pre-dividerp
++ * +-+--------+ - reg 0x030b, bits 0-2 for the pre-divider
++ * +-+--------+ - reg 0x030c~0x030d, for the multiplier
++ * | +--------------+
++ * +->| SCLK Divider | - reg 0x030F, bits 0-3 for the pre-divider
++ * +-+--------+ - reg 0x030E, bits 0-2 for the divider
++ * | +---------> SCLK
++ *
++ * | +-----+
++ * +->| DAC Divider | - reg 0x0312, bits 0-3 for the divider
++ * | +----------------> DACCLK
++ **
++ */
++
++/*
++ * ov4689_set_mipi_pclk() - Calculate the clock tree configuration values
++ * for the MIPI CSI-2 output.
++ *
++ * @rate: The requested bandwidth per lane in bytes per second.
++ * 'Bandwidth Per Lane' is calculated as:
++ * bpl = HTOT * VTOT * FPS * bpp / num_lanes;
++ *
++ * This function use the requested bandwidth to calculate:
++ *
++ * - mipi_pclk = bpl / 2; ( / 2 is for CSI-2 DDR)
++ * - mipi_phy_clk = mipi_pclk * PLL1_DIV_MIPI;
++ *
++ * with these fixed parameters:
++ * PLL1_PREDIVP = 1;
++ * PLL1_PREDIV = 1; (MIPI_BIT_MODE == 8 ? 2 : 2,5);
++ * PLL1_DIVM = 1;
++ * PLL1_DIV_MIPI = 4;
++ *
++ * FIXME: this have been tested with 10-bit raw and 2 lanes setup only.
++ * MIPI_DIV is fixed to value 2, but it -might- be changed according to the
++ * above formula for setups with 1 lane or image formats with different bpp.
++ *
++ * FIXME: this deviates from the sensor manual documentation which is quite
++ * thin on the MIPI clock tree generation part.
++ */
++
++#define PLL1_PREDIVP 1 // bypass
++#define PLL1_PREDIV 1 // bypass
++#define PLL1_DIVM 1 // bypass
++#define PLL1_DIV_MIPI 3 // div
++#define PLL1_DIV_MIPI_BASE 1 // div
++
++#define PLL1_DIVSP 1 // no use
++#define PLL1_DIVS 1 // no use
++
++#define PLL2_PREDIVP 0
++#define PLL2_PREDIV 0
++#define PLL2_DIVSP 1
++#define PLL2_DIVS 4
++#define PLL2_DIVDAC 1
++
++#define OV4689_PLL1_PREDIVP 0x030a // bits[0]
++#define OV4689_PLL1_PREDIV 0x0300 // bits[2:0]
++#define OV4689_PLL1_MULTIPLIER 0x0301 // bits[9:8] 0x0302 bits[7:0]
++#define OV4689_PLL1_DIVM 0x0303 // bits[3:0]
++#define OV4689_PLL1_DIV_MIPI 0x0304 // bits[1:0]
++
++#define OV4689_PLL1_DIVSP 0x0305 //bits[1:0]
++#define OV4689_PLL1_DIVS 0x0306 // bits[0]
++
++#define OV4689_PLL2_PREDIVP 0x0311 // bits[0]
++#define OV4689_PLL2_PREDIV 0x030b // bits[2:0]
++#define OV4689_PLL2_MULTIPLIER 0x030c // bits[9:8] 0x030d bits[7:0]
++#define OV4689_PLL2_DIVSP 0x030f // bits[3:0]
++#define OV4689_PLL2_DIVS 0x030e // bits[2:0]
++#define OV4689_PLL2_DIVDAC 0x0312 // bits[3:0]
++
++static int ov4689_set_mipi_pclk(struct ov4689_dev *sensor,
++ unsigned long rate)
++{
++ const struct ov4689_mode_info *mode = sensor->current_mode;
++ //const struct ov4689_mode_info *orig_mode = sensor->last_mode;
++ u8 val;
++ int ret = 0;
++ int fps = ov4689_framerates[sensor->current_fr];
++ u16 htot, val16;
++
++ htot = mode->htot * ov4689_framerates[mode->max_fps] / fps;
++
++ ret = ov4689_write_reg16(sensor, OV4689_REG_TIMING_HTS, htot);
++
++ ret = ov4689_read_reg(sensor, OV4689_REG_TIMING_HTS, &val);
++ val16 = val << 8;
++ ret = ov4689_read_reg(sensor, OV4689_REG_TIMING_HTS + 1, &val);
++ val16 |= val;
++
++ st_info(ST_SENSOR, "fps = %d, max_fps = %d\n", fps, mode->max_fps);
++ st_info(ST_SENSOR, "mode->htot = 0x%x, htot = 0x%x\n", mode->htot,
++ htot);
++ st_info(ST_SENSOR, "reg: 0x%x = 0x%x\n", OV4689_REG_TIMING_HTS, val16);
++
++ return 0;
++}
++
++/*
++ * if sensor changes inside scaling or subsampling
++ * change mode directly
++ */
++static int ov4689_set_mode_direct(struct ov4689_dev *sensor,
++ const struct ov4689_mode_info *mode)
++{
++ if (!mode->reg_data)
++ return -EINVAL;
++
++ /* Write capture setting */
++ return ov4689_load_regs(sensor, mode);
++}
++
++static int ov4689_set_mode(struct ov4689_dev *sensor)
++{
++ const struct ov4689_mode_info *mode = sensor->current_mode;
++
++ int ret = 0;
++
++ ret = ov4689_set_mode_direct(sensor, mode);
++ if (ret < 0)
++ return ret;
++
++ ret = ov4689_set_mipi_pclk(sensor, 0);
++ if (ret < 0)
++ return 0;
++
++ sensor->pending_mode_change = false;
++ sensor->last_mode = mode;
++ return 0;
++}
++
++/* restore the last set video mode after chip power-on */
++static int ov4689_restore_mode(struct ov4689_dev *sensor)
++{
++ int ret;
++
++ /* first load the initial register values */
++ ret = ov4689_load_regs(sensor, &ov4689_mode_init_data);
++ if (ret < 0)
++ return ret;
++ sensor->last_mode = &ov4689_mode_init_data;
++
++ /* now restore the last capture mode */
++ ret = ov4689_set_mode(sensor);
++ if (ret < 0)
++ return ret;
++
++ return ret;
++}
++
++static void ov4689_power(struct ov4689_dev *sensor, bool enable)
++{
++ if (!sensor->pwdn_gpio)
++ return;
++ gpiod_set_value_cansleep(sensor->pwdn_gpio, enable ? 0 : 1);
++}
++
++static void ov4689_reset(struct ov4689_dev *sensor)
++{
++ if (!sensor->reset_gpio)
++ return;
++
++ gpiod_set_value_cansleep(sensor->reset_gpio, 0);
++
++ usleep_range(5000, 25000);
++
++ gpiod_set_value_cansleep(sensor->reset_gpio, 1);
++ usleep_range(1000, 2000);
++}
++
++static int ov4689_set_power_on(struct device *dev)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ struct v4l2_subdev *sd = i2c_get_clientdata(client);
++ struct ov4689_dev *sensor = to_ov4689_dev(sd);
++ int ret;
++
++ ret = clk_prepare_enable(sensor->xclk);
++ if (ret) {
++ dev_err(&client->dev, "%s: failed to enable clock\n",
++ __func__);
++ return ret;
++ }
++
++ ret = regulator_bulk_enable(OV4689_NUM_SUPPLIES,
++ sensor->supplies);
++ if (ret) {
++ dev_err(&client->dev, "%s: failed to enable regulators\n",
++ __func__);
++ goto xclk_off;
++ }
++
++ ov4689_reset(sensor);
++ ov4689_power(sensor, true);
++
++ return 0;
++
++xclk_off:
++ clk_disable_unprepare(sensor->xclk);
++ return ret;
++}
++
++static int ov4689_set_power_off(struct device *dev)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ struct v4l2_subdev *sd = i2c_get_clientdata(client);
++ struct ov4689_dev *sensor = to_ov4689_dev(sd);
++
++ ov4689_power(sensor, false);
++ regulator_bulk_disable(OV4689_NUM_SUPPLIES, sensor->supplies);
++ clk_disable_unprepare(sensor->xclk);
++
++ return 0;
++}
++
++static int ov4689_try_frame_interval(struct ov4689_dev *sensor,
++ struct v4l2_fract *fi,
++ u32 width, u32 height)
++{
++ const struct ov4689_mode_info *mode;
++ enum ov4689_frame_rate rate = OV4689_15_FPS;
++ int minfps, maxfps, best_fps, fps;
++ int i;
++
++ minfps = ov4689_framerates[OV4689_15_FPS];
++ maxfps = ov4689_framerates[OV4689_NUM_FRAMERATES - 1];
++
++ if (fi->numerator == 0) {
++ fi->denominator = maxfps;
++ fi->numerator = 1;
++ rate = OV4689_60_FPS;
++ goto find_mode;
++ }
++
++ fps = clamp_val(DIV_ROUND_CLOSEST(fi->denominator, fi->numerator),
++ minfps, maxfps);
++
++ best_fps = minfps;
++ for (i = 0; i < ARRAY_SIZE(ov4689_framerates); i++) {
++ int curr_fps = ov4689_framerates[i];
++
++ if (abs(curr_fps - fps) < abs(best_fps - fps)) {
++ best_fps = curr_fps;
++ rate = i;
++ }
++ }
++ st_info(ST_SENSOR, "best_fps = %d, fps = %d\n", best_fps, fps);
++
++ fi->numerator = 1;
++ fi->denominator = best_fps;
++
++find_mode:
++ mode = ov4689_find_mode(sensor, rate, width, height, false);
++ return mode ? rate : -EINVAL;
++}
++
++static int ov4689_enum_mbus_code(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_mbus_code_enum *code)
++{
++ if (code->pad != 0)
++ return -EINVAL;
++
++ if (code->index)
++ return -EINVAL;
++
++ code->code = MEDIA_BUS_FMT_SBGGR10_1X10;
++ return 0;
++}
++
++static int ov4689_get_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_format *format)
++{
++ struct ov4689_dev *sensor = to_ov4689_dev(sd);
++ struct v4l2_mbus_framefmt *fmt;
++
++ if (format->pad != 0)
++ return -EINVAL;
++
++ mutex_lock(&sensor->lock);
++
++ if (format->which == V4L2_SUBDEV_FORMAT_TRY)
++ fmt = v4l2_subdev_get_try_format(&sensor->sd, state,
++ format->pad);
++ else
++ fmt = &sensor->fmt;
++
++ format->format = *fmt;
++
++ mutex_unlock(&sensor->lock);
++
++ return 0;
++}
++
++static int ov4689_try_fmt_internal(struct v4l2_subdev *sd,
++ struct v4l2_mbus_framefmt *fmt,
++ enum ov4689_frame_rate fr,
++ const struct ov4689_mode_info **new_mode)
++{
++ struct ov4689_dev *sensor = to_ov4689_dev(sd);
++ const struct ov4689_mode_info *mode;
++
++ mode = ov4689_find_mode(sensor, fr, fmt->width, fmt->height, true);
++ if (!mode)
++ return -EINVAL;
++ fmt->width = mode->hact;
++ fmt->height = mode->vact;
++
++ if (new_mode)
++ *new_mode = mode;
++
++ fmt->code = MEDIA_BUS_FMT_SBGGR10_1X10;
++
++ return 0;
++}
++
++static int ov4689_set_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_format *format)
++{
++ struct ov4689_dev *sensor = to_ov4689_dev(sd);
++ const struct ov4689_mode_info *new_mode;
++ struct v4l2_mbus_framefmt *mbus_fmt = &format->format;
++ struct v4l2_mbus_framefmt *fmt;
++ int ret;
++
++ if (format->pad != 0)
++ return -EINVAL;
++
++ mutex_lock(&sensor->lock);
++
++ if (sensor->streaming) {
++ ret = -EBUSY;
++ goto out;
++ }
++
++ ret = ov4689_try_fmt_internal(sd, mbus_fmt, 0, &new_mode);
++ if (ret)
++ goto out;
++
++ if (format->which == V4L2_SUBDEV_FORMAT_TRY)
++ fmt = v4l2_subdev_get_try_format(sd, state, 0);
++ else
++ fmt = &sensor->fmt;
++
++ *fmt = *mbus_fmt;
++
++ if (new_mode != sensor->current_mode) {
++ sensor->current_mode = new_mode;
++ sensor->pending_mode_change = true;
++ }
++ if (new_mode->max_fps < sensor->current_fr) {
++ sensor->current_fr = new_mode->max_fps;
++ sensor->frame_interval.numerator = 1;
++ sensor->frame_interval.denominator =
++ ov4689_framerates[sensor->current_fr];
++ sensor->current_mode = new_mode;
++ sensor->pending_mode_change = true;
++ }
++
++ __v4l2_ctrl_s_ctrl_int64(sensor->ctrls.pixel_rate,
++ ov4689_calc_pixel_rate(sensor));
++out:
++ mutex_unlock(&sensor->lock);
++ return ret;
++}
++
++/*
++ * Sensor Controls.
++ */
++
++static int ov4689_set_ctrl_hue(struct ov4689_dev *sensor, int value)
++{
++ int ret = 0;
++
++ return ret;
++}
++
++static int ov4689_set_ctrl_contrast(struct ov4689_dev *sensor, int value)
++{
++ int ret = 0;
++
++ return ret;
++}
++
++static int ov4689_set_ctrl_saturation(struct ov4689_dev *sensor, int value)
++{
++ int ret = 0;
++
++ return ret;
++}
++
++static int ov4689_set_ctrl_white_balance(struct ov4689_dev *sensor, int awb)
++{
++ struct ov4689_ctrls *ctrls = &sensor->ctrls;
++ int ret = 0;
++
++ if (!awb && (ctrls->red_balance->is_new
++ || ctrls->blue_balance->is_new)) {
++ u16 red = (u16)ctrls->red_balance->val;
++ u16 blue = (u16)ctrls->blue_balance->val;
++
++ st_info(ST_SENSOR, "red = 0x%x, blue = 0x%x\n", red, blue);
++ ret = ov4689_write_reg16(sensor, OV4689_REG_AWB_R_GAIN, red);
++ if (ret)
++ return ret;
++ ret = ov4689_write_reg16(sensor, OV4689_REG_AWB_B_GAIN, blue);
++ }
++ return ret;
++}
++
++static int ov4689_set_ctrl_exposure(struct ov4689_dev *sensor,
++ enum v4l2_exposure_auto_type auto_exposure)
++{
++ struct ov4689_ctrls *ctrls = &sensor->ctrls;
++ bool auto_exp = (auto_exposure == V4L2_EXPOSURE_AUTO);
++ int ret = 0;
++
++ if (!auto_exp && ctrls->exposure->is_new) {
++ u16 max_exp = 0;
++
++ ret = ov4689_read_reg16(sensor, OV4689_REG_V_OUTPUT_SIZE,
++ &max_exp);
++
++ ret = ov4689_get_vts(sensor);
++ if (ret < 0)
++ return ret;
++ max_exp += ret;
++ ret = 0;
++
++ st_info(ST_SENSOR, "%s, max_exp = 0x%x\n", __func__, max_exp);
++ if (ctrls->exposure->val < max_exp)
++ ret = ov4689_set_exposure(sensor, ctrls->exposure->val);
++ }
++
++ return ret;
++}
++
++static const s64 link_freq_menu_items[] = {
++ OV4689_LINK_FREQ_500MHZ
++};
++
++static const char * const test_pattern_menu[] = {
++ "Disabled",
++ "Color bars",
++ "Color bars w/ rolling bar",
++ "Color squares",
++ "Color squares w/ rolling bar",
++};
++
++#define OV4689_TEST_ENABLE BIT(7)
++#define OV4689_TEST_ROLLING BIT(6) /* rolling horizontal bar */
++#define OV4689_TEST_TRANSPARENT BIT(5)
++#define OV4689_TEST_SQUARE_BW BIT(4) /* black & white squares */
++#define OV4689_TEST_BAR_STANDARD (0 << 2)
++#define OV4689_TEST_BAR_DARKER_1 (1 << 2)
++#define OV4689_TEST_BAR_DARKER_2 (2 << 2)
++#define OV4689_TEST_BAR_DARKER_3 (3 << 2)
++#define OV4689_TEST_BAR (0 << 0)
++#define OV4689_TEST_RANDOM (1 << 0)
++#define OV4689_TEST_SQUARE (2 << 0)
++#define OV4689_TEST_BLACK (3 << 0)
++
++static const u8 test_pattern_val[] = {
++ 0,
++ OV4689_TEST_ENABLE | OV4689_TEST_BAR_STANDARD |
++ OV4689_TEST_BAR,
++ OV4689_TEST_ENABLE | OV4689_TEST_ROLLING |
++ OV4689_TEST_BAR_DARKER_1 | OV4689_TEST_BAR,
++ OV4689_TEST_ENABLE | OV4689_TEST_SQUARE,
++ OV4689_TEST_ENABLE | OV4689_TEST_ROLLING | OV4689_TEST_SQUARE,
++};
++
++static int ov4689_set_ctrl_test_pattern(struct ov4689_dev *sensor, int value)
++{
++ return ov4689_write_reg(sensor, OV4689_REG_TEST_PATTERN,
++ test_pattern_val[value]);
++}
++
++static int ov4689_set_ctrl_light_freq(struct ov4689_dev *sensor, int value)
++{
++ return 0;
++}
++
++static int ov4689_set_ctrl_hflip(struct ov4689_dev *sensor, int value)
++{
++ /*
++ * TIMING TC REG21:
++ * - [2]: Digital mirror
++ * - [1]: Array mirror
++ */
++ return ov4689_mod_reg(sensor, OV4689_REG_TIMING_TC_REG21,
++ BIT(2) | BIT(1),
++ (!(value ^ sensor->upside_down)) ?
++ (BIT(2) | BIT(1)) : 0);
++}
++
++static int ov4689_set_ctrl_vflip(struct ov4689_dev *sensor, int value)
++{
++ /*
++ * TIMING TC REG20:
++ * - [2]: Digital vflip
++ * - [1]: Array vflip
++ */
++ return ov4689_mod_reg(sensor, OV4689_REG_TIMING_TC_REG20,
++ BIT(2) | BIT(1),
++ (value ^ sensor->upside_down) ?
++ (BIT(2) | BIT(1)) : 0);
++}
++
++static int ov4689_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
++{
++ struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
++ struct ov4689_dev *sensor = to_ov4689_dev(sd);
++ int val;
++
++ /* v4l2_ctrl_lock() locks our own mutex */
++
++ if (!pm_runtime_get_if_in_use(&sensor->i2c_client->dev))
++ return 0;
++
++ switch (ctrl->id) {
++ case V4L2_CID_ANALOGUE_GAIN:
++ val = ov4689_get_gain(sensor);
++ break;
++ }
++
++ pm_runtime_put(&sensor->i2c_client->dev);
++
++ return 0;
++}
++
++static int ov4689_s_ctrl(struct v4l2_ctrl *ctrl)
++{
++ struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
++ struct ov4689_dev *sensor = to_ov4689_dev(sd);
++ int ret;
++
++ /* v4l2_ctrl_lock() locks our own mutex */
++
++ /*
++ * If the device is not powered up by the host driver do
++ * not apply any controls to H/W at this time. Instead
++ * the controls will be restored at start streaming time.
++ */
++ if (!pm_runtime_get_if_in_use(&sensor->i2c_client->dev))
++ return 0;
++
++ switch (ctrl->id) {
++ case V4L2_CID_ANALOGUE_GAIN:
++ ret = ov4689_set_gain(sensor, ctrl->val);
++ break;
++ case V4L2_CID_EXPOSURE:
++ ret = ov4689_set_ctrl_exposure(sensor, V4L2_EXPOSURE_MANUAL);
++ break;
++ case V4L2_CID_AUTO_WHITE_BALANCE:
++ ret = ov4689_set_ctrl_white_balance(sensor, ctrl->val);
++ break;
++ case V4L2_CID_HUE:
++ ret = ov4689_set_ctrl_hue(sensor, ctrl->val);
++ break;
++ case V4L2_CID_CONTRAST:
++ ret = ov4689_set_ctrl_contrast(sensor, ctrl->val);
++ break;
++ case V4L2_CID_SATURATION:
++ ret = ov4689_set_ctrl_saturation(sensor, ctrl->val);
++ break;
++ case V4L2_CID_TEST_PATTERN:
++ ret = ov4689_set_ctrl_test_pattern(sensor, ctrl->val);
++ break;
++ case V4L2_CID_POWER_LINE_FREQUENCY:
++ ret = ov4689_set_ctrl_light_freq(sensor, ctrl->val);
++ break;
++ case V4L2_CID_HFLIP:
++ ret = ov4689_set_ctrl_hflip(sensor, ctrl->val);
++ break;
++ case V4L2_CID_VFLIP:
++ ret = ov4689_set_ctrl_vflip(sensor, ctrl->val);
++ break;
++ default:
++ ret = -EINVAL;
++ break;
++ }
++
++ pm_runtime_put(&sensor->i2c_client->dev);
++
++ return ret;
++}
++
++static const struct v4l2_ctrl_ops ov4689_ctrl_ops = {
++ .g_volatile_ctrl = ov4689_g_volatile_ctrl,
++ .s_ctrl = ov4689_s_ctrl,
++};
++
++static int ov4689_init_controls(struct ov4689_dev *sensor)
++{
++ const struct v4l2_ctrl_ops *ops = &ov4689_ctrl_ops;
++ struct ov4689_ctrls *ctrls = &sensor->ctrls;
++ struct v4l2_ctrl_handler *hdl = &ctrls->handler;
++ int ret;
++
++ v4l2_ctrl_handler_init(hdl, 32);
++
++ /* we can use our own mutex for the ctrl lock */
++ hdl->lock = &sensor->lock;
++
++ /* Clock related controls */
++ ctrls->pixel_rate = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_PIXEL_RATE,
++ 0, INT_MAX, 1,
++ ov4689_calc_pixel_rate(sensor));
++
++ /* Auto/manual white balance */
++ ctrls->auto_wb = v4l2_ctrl_new_std(hdl, ops,
++ V4L2_CID_AUTO_WHITE_BALANCE,
++ 0, 1, 1, 0);
++ ctrls->blue_balance = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_BLUE_BALANCE,
++ 0, 4095, 1, 1024);
++ ctrls->red_balance = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_RED_BALANCE,
++ 0, 4095, 1, 1024);
++
++ ctrls->exposure = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_EXPOSURE,
++ 4, 0xfff8, 1, 0x4c00);
++ ctrls->anal_gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_ANALOGUE_GAIN,
++ 0x10, 0xfff8, 1, 0x0080);
++ ctrls->test_pattern =
++ v4l2_ctrl_new_std_menu_items(hdl, ops, V4L2_CID_TEST_PATTERN,
++ ARRAY_SIZE(test_pattern_menu) - 1,
++ 0, 0, test_pattern_menu);
++ ctrls->hflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_HFLIP,
++ 0, 1, 1, 0);
++ ctrls->vflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_VFLIP,
++ 0, 1, 1, 0);
++ ctrls->light_freq =
++ v4l2_ctrl_new_std_menu(hdl, ops,
++ V4L2_CID_POWER_LINE_FREQUENCY,
++ V4L2_CID_POWER_LINE_FREQUENCY_AUTO, 0,
++ V4L2_CID_POWER_LINE_FREQUENCY_50HZ);
++ ctrls->link_freq = v4l2_ctrl_new_int_menu(hdl, ops, V4L2_CID_LINK_FREQ,
++ 0, 0, link_freq_menu_items);
++ if (hdl->error) {
++ ret = hdl->error;
++ goto free_ctrls;
++ }
++
++ ctrls->pixel_rate->flags |= V4L2_CTRL_FLAG_READ_ONLY;
++ ctrls->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
++ // ctrls->exposure->flags |= V4L2_CTRL_FLAG_VOLATILE;
++ // ctrls->anal_gain->flags |= V4L2_CTRL_FLAG_VOLATILE;
++
++ v4l2_ctrl_auto_cluster(3, &ctrls->auto_wb, 0, false);
++
++ sensor->sd.ctrl_handler = hdl;
++ return 0;
++
++free_ctrls:
++ v4l2_ctrl_handler_free(hdl);
++ return ret;
++}
++
++static int ov4689_enum_frame_size(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_frame_size_enum *fse)
++{
++ if (fse->pad != 0)
++ return -EINVAL;
++ if (fse->index >= OV4689_NUM_MODES)
++ return -EINVAL;
++
++ fse->min_width =
++ ov4689_mode_data[fse->index].hact;
++ fse->max_width = fse->min_width;
++ fse->min_height =
++ ov4689_mode_data[fse->index].vact;
++ fse->max_height = fse->min_height;
++
++ return 0;
++}
++
++static int ov4689_enum_frame_interval(
++ struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_frame_interval_enum *fie)
++{
++ //struct ov4689_dev *sensor = to_ov4689_dev(sd);
++ struct v4l2_fract tpf;
++ int i = 0;
++
++ if (fie->pad != 0)
++ return -EINVAL;
++ if (fie->index >= OV4689_NUM_FRAMERATES)
++ return -EINVAL;
++
++ tpf.numerator = 1;
++ tpf.denominator = ov4689_framerates[fie->index];
++
++ // ret = ov4689_try_frame_interval(sensor, &tpf,
++ // fie->width, fie->height);
++ // if (ret < 0)
++ // return -EINVAL;
++
++ pr_debug("fie->width = %d, fie->height = %d\n", fie->width, fie->height);
++ for (i = 0; i < OV4689_NUM_MODES; i++) {
++ if (fie->width == ov4689_mode_data[i].hact &&
++ fie->height == ov4689_mode_data[i].vact)
++ break;
++ }
++ if (i == OV4689_NUM_MODES)
++ return -ENOTTY;
++
++ fie->interval = tpf;
++ fie->width = ov4689_mode_data[i].hact;
++ fie->height = ov4689_mode_data[i].vact;
++
++ return 0;
++}
++
++static int ov4689_g_frame_interval(struct v4l2_subdev *sd,
++ struct v4l2_subdev_frame_interval *fi)
++{
++ struct ov4689_dev *sensor = to_ov4689_dev(sd);
++
++ mutex_lock(&sensor->lock);
++ fi->interval = sensor->frame_interval;
++ mutex_unlock(&sensor->lock);
++
++ return 0;
++}
++
++static int ov4689_s_frame_interval(struct v4l2_subdev *sd,
++ struct v4l2_subdev_frame_interval *fi)
++{
++ struct ov4689_dev *sensor = to_ov4689_dev(sd);
++ const struct ov4689_mode_info *mode;
++ int frame_rate, ret = 0;
++
++ if (fi->pad != 0)
++ return -EINVAL;
++
++ mutex_lock(&sensor->lock);
++
++ if (sensor->streaming) {
++ ret = -EBUSY;
++ goto out;
++ }
++
++ mode = sensor->current_mode;
++
++ frame_rate = ov4689_try_frame_interval(sensor, &fi->interval,
++ mode->hact, mode->vact);
++ if (frame_rate < 0) {
++ /* Always return a valid frame interval value */
++ fi->interval = sensor->frame_interval;
++ goto out;
++ }
++
++ mode = ov4689_find_mode(sensor, frame_rate, mode->hact,
++ mode->vact, true);
++ if (!mode) {
++ ret = -EINVAL;
++ goto out;
++ }
++
++ if (mode != sensor->current_mode ||
++ frame_rate != sensor->current_fr) {
++ sensor->current_fr = frame_rate;
++ sensor->frame_interval = fi->interval;
++ sensor->current_mode = mode;
++ sensor->pending_mode_change = true;
++
++ __v4l2_ctrl_s_ctrl_int64(sensor->ctrls.pixel_rate,
++ ov4689_calc_pixel_rate(sensor));
++ }
++out:
++ mutex_unlock(&sensor->lock);
++ return ret;
++}
++
++static int ov4689_stream_start(struct ov4689_dev *sensor, int enable)
++{
++ return ov4689_write_reg(sensor, OV4689_REG_STREAM_ON, enable);
++}
++
++static int ov4689_s_stream(struct v4l2_subdev *sd, int enable)
++{
++ struct ov4689_dev *sensor = to_ov4689_dev(sd);
++ int ret = 0;
++
++ if (enable) {
++ pm_runtime_get_sync(&sensor->i2c_client->dev);
++
++ ret = v4l2_ctrl_handler_setup(&sensor->ctrls.handler);
++ if (ret) {
++ pm_runtime_put_sync(&sensor->i2c_client->dev);
++ return ret;
++ }
++ }
++
++ mutex_lock(&sensor->lock);
++
++ if (sensor->streaming == !enable) {
++ if (enable) {
++ ret = ov4689_restore_mode(sensor);
++ if (ret)
++ goto out;
++ }
++
++ if (enable && sensor->pending_mode_change) {
++ ret = ov4689_set_mode(sensor);
++ if (ret)
++ goto out;
++ }
++
++ if (sensor->ep.bus.mipi_csi2.num_data_lanes == 2) {
++ ov4689_write_reg(sensor, OV4689_REG_MIPI_SC_CTRL_HI, 0x32);
++ ov4689_write_reg(sensor, OV4689_REG_MIPI_SC_CTRL_LOW, 0x0c);
++ } else if (sensor->ep.bus.mipi_csi2.num_data_lanes == 4) {
++ ov4689_write_reg(sensor, OV4689_REG_MIPI_SC_CTRL_HI, 0x72);
++ ov4689_write_reg(sensor, OV4689_REG_MIPI_SC_CTRL_LOW, 0x00);
++ } else {
++ dev_err(&sensor->i2c_client->dev, "Unsupport lane num\n");
++ }
++
++ ret = ov4689_stream_start(sensor, enable);
++ if (ret)
++ goto out;
++ }
++ sensor->streaming += enable ? 1 : -1;
++ WARN_ON(sensor->streaming < 0);
++out:
++ mutex_unlock(&sensor->lock);
++
++ if (!enable || ret)
++ pm_runtime_put_sync(&sensor->i2c_client->dev);
++
++ return ret;
++}
++
++static const struct v4l2_subdev_core_ops ov4689_core_ops = {
++ .log_status = v4l2_ctrl_subdev_log_status,
++ .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
++ .unsubscribe_event = v4l2_event_subdev_unsubscribe,
++};
++
++static const struct v4l2_subdev_video_ops ov4689_video_ops = {
++ .g_frame_interval = ov4689_g_frame_interval,
++ .s_frame_interval = ov4689_s_frame_interval,
++ .s_stream = ov4689_s_stream,
++};
++
++static const struct v4l2_subdev_pad_ops ov4689_pad_ops = {
++ .enum_mbus_code = ov4689_enum_mbus_code,
++ .get_fmt = ov4689_get_fmt,
++ .set_fmt = ov4689_set_fmt,
++ .enum_frame_size = ov4689_enum_frame_size,
++ .enum_frame_interval = ov4689_enum_frame_interval,
++};
++
++static const struct v4l2_subdev_ops ov4689_subdev_ops = {
++ .core = &ov4689_core_ops,
++ .video = &ov4689_video_ops,
++ .pad = &ov4689_pad_ops,
++};
++
++static int ov4689_get_regulators(struct ov4689_dev *sensor)
++{
++ int i;
++
++ for (i = 0; i < OV4689_NUM_SUPPLIES; i++)
++ sensor->supplies[i].supply = ov4689_supply_name[i];
++
++ return devm_regulator_bulk_get(&sensor->i2c_client->dev,
++ OV4689_NUM_SUPPLIES,
++ sensor->supplies);
++}
++
++static int ov4689_check_chip_id(struct ov4689_dev *sensor)
++{
++ struct i2c_client *client = sensor->i2c_client;
++ int ret = 0;
++ u16 chip_id;
++
++ ret = ov4689_read_reg16(sensor, OV4689_REG_CHIP_ID, &chip_id);
++ if (ret) {
++ dev_err(&client->dev, "%s: failed to read chip identifier\n",
++ __func__);
++ return ret;
++ }
++
++ if (chip_id != OV4689_CHIP_ID) {
++ dev_err(&client->dev, "%s: wrong chip identifier, expected 0x%x, got 0x%x\n",
++ __func__, OV4689_CHIP_ID, chip_id);
++ return -ENXIO;
++ }
++ dev_err(&client->dev, "%s: chip identifier, got 0x%x\n",
++ __func__, chip_id);
++
++ return 0;
++}
++
++static int ov4689_probe(struct i2c_client *client)
++{
++ struct device *dev = &client->dev;
++ struct fwnode_handle *endpoint;
++ struct ov4689_dev *sensor;
++ struct v4l2_mbus_framefmt *fmt;
++ u32 rotation;
++ int ret;
++
++ sensor = devm_kzalloc(dev, sizeof(*sensor), GFP_KERNEL);
++ if (!sensor)
++ return -ENOMEM;
++
++ sensor->i2c_client = client;
++
++ fmt = &sensor->fmt;
++ fmt->code = MEDIA_BUS_FMT_SBGGR10_1X10;
++ fmt->colorspace = V4L2_COLORSPACE_SRGB;
++ fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->colorspace);
++ fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE;
++ fmt->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(fmt->colorspace);
++ fmt->width = 1920;
++ fmt->height = 1080;
++ fmt->field = V4L2_FIELD_NONE;
++ sensor->frame_interval.numerator = 1;
++ sensor->frame_interval.denominator = ov4689_framerates[OV4689_30_FPS];
++ sensor->current_fr = OV4689_30_FPS;
++ sensor->current_mode =
++ &ov4689_mode_data[OV4689_MODE_1080P_1920_1080];
++ sensor->last_mode = sensor->current_mode;
++
++
++ /* optional indication of physical rotation of sensor */
++ ret = fwnode_property_read_u32(dev_fwnode(&client->dev), "rotation",
++ &rotation);
++ if (!ret) {
++ switch (rotation) {
++ case 180:
++ sensor->upside_down = true;
++ fallthrough;
++ case 0:
++ break;
++ default:
++ dev_warn(dev, "%u degrees rotation is not supported, ignoring...\n",
++ rotation);
++ }
++ }
++
++ endpoint = fwnode_graph_get_next_endpoint(dev_fwnode(&client->dev),
++ NULL);
++ if (!endpoint) {
++ dev_err(dev, "endpoint node not found\n");
++ return -EINVAL;
++ }
++
++ ret = v4l2_fwnode_endpoint_parse(endpoint, &sensor->ep);
++ fwnode_handle_put(endpoint);
++ if (ret) {
++ dev_err(dev, "Could not parse endpoint\n");
++ return ret;
++ }
++
++ if (sensor->ep.bus_type != V4L2_MBUS_CSI2_DPHY) {
++ dev_err(dev, "Unsupported bus type %d\n", sensor->ep.bus_type);
++ return -EINVAL;
++ }
++
++ /* get system clock (xclk) */
++ sensor->xclk = devm_clk_get(dev, "xclk");
++ if (IS_ERR(sensor->xclk)) {
++ dev_err(dev, "failed to get xclk\n");
++ return PTR_ERR(sensor->xclk);
++ }
++
++ sensor->xclk_freq = clk_get_rate(sensor->xclk);
++ if (sensor->xclk_freq < OV4689_XCLK_MIN ||
++ sensor->xclk_freq > OV4689_XCLK_MAX) {
++ dev_err(dev, "xclk frequency out of range: %d Hz\n",
++ sensor->xclk_freq);
++ return -EINVAL;
++ }
++
++ /* request optional power down pin */
++ sensor->pwdn_gpio = devm_gpiod_get_optional(dev, "powerdown",
++ GPIOD_OUT_HIGH);
++ if (IS_ERR(sensor->pwdn_gpio))
++ return PTR_ERR(sensor->pwdn_gpio);
++
++ /* request optional reset pin */
++ sensor->reset_gpio = devm_gpiod_get_optional(dev, "reset",
++ GPIOD_OUT_HIGH);
++ if (IS_ERR(sensor->reset_gpio))
++ return PTR_ERR(sensor->reset_gpio);
++
++ v4l2_i2c_subdev_init(&sensor->sd, client, &ov4689_subdev_ops);
++
++ sensor->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
++ V4L2_SUBDEV_FL_HAS_EVENTS;
++ sensor->pad.flags = MEDIA_PAD_FL_SOURCE;
++ sensor->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
++ ret = media_entity_pads_init(&sensor->sd.entity, 1, &sensor->pad);
++ if (ret)
++ return ret;
++
++ ret = ov4689_get_regulators(sensor);
++ if (ret)
++ return ret;
++
++ mutex_init(&sensor->lock);
++
++ ret = ov4689_set_power_on(dev);
++ if (ret) {
++ dev_err(dev, "failed to power on\n");
++ goto entity_cleanup;
++ }
++
++ ret = ov4689_check_chip_id(sensor);
++ if (ret)
++ goto error_power_off;
++
++ ret = ov4689_init_controls(sensor);
++ if (ret)
++ goto error_power_off;
++
++ ret = v4l2_async_register_subdev_sensor(&sensor->sd);
++ if (ret)
++ goto free_ctrls;
++
++ pm_runtime_set_active(dev);
++ pm_runtime_enable(dev);
++
++ return 0;
++
++free_ctrls:
++ v4l2_ctrl_handler_free(&sensor->ctrls.handler);
++error_power_off:
++ ov4689_set_power_off(dev);
++entity_cleanup:
++ media_entity_cleanup(&sensor->sd.entity);
++ mutex_destroy(&sensor->lock);
++ return ret;
++}
++
++static void ov4689_remove(struct i2c_client *client)
++{
++ struct v4l2_subdev *sd = i2c_get_clientdata(client);
++ struct ov4689_dev *sensor = to_ov4689_dev(sd);
++
++ v4l2_async_unregister_subdev(&sensor->sd);
++ media_entity_cleanup(&sensor->sd.entity);
++ v4l2_ctrl_handler_free(&sensor->ctrls.handler);
++ mutex_destroy(&sensor->lock);
++
++ pm_runtime_disable(&client->dev);
++ if (!pm_runtime_status_suspended(&client->dev))
++ ov4689_set_power_off(&client->dev);
++ pm_runtime_set_suspended(&client->dev);
++}
++
++static const struct i2c_device_id ov4689_id[] = {
++ { "ov4689", 0 },
++ {},
++};
++MODULE_DEVICE_TABLE(i2c, ov4689_id);
++
++static const struct of_device_id ov4689_dt_ids[] = {
++ { .compatible = "ovti,ov4689" },
++ { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, ov4689_dt_ids);
++
++static const struct dev_pm_ops ov4689_pm_ops = {
++ SET_RUNTIME_PM_OPS(ov4689_set_power_off, ov4689_set_power_on, NULL)
++};
++
++static struct i2c_driver ov4689_i2c_driver = {
++ .driver = {
++ .name = "ov4689",
++ .of_match_table = ov4689_dt_ids,
++ .pm = &ov4689_pm_ops,
++ },
++ .id_table = ov4689_id,
++ .probe = ov4689_probe,
++ .remove = ov4689_remove,
++};
++
++module_i2c_driver(ov4689_i2c_driver);
++
++MODULE_DESCRIPTION("OV4689 MIPI Camera Subdev Driver");
++MODULE_LICENSE("GPL");
+--- /dev/null
++++ b/drivers/media/platform/starfive/v4l2_driver/ov5640.c
+@@ -0,0 +1,3227 @@
++// SPDX-License-Identifier: GPL-2.0-or-later
++/*
++ * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
++ * Copyright (C) 2014-2017 Mentor Graphics Inc.
++ *
++ */
++
++#include <linux/clk.h>
++#include <linux/clk-provider.h>
++#include <linux/clkdev.h>
++#include <linux/ctype.h>
++#include <linux/delay.h>
++#include <linux/device.h>
++#include <linux/gpio/consumer.h>
++#include <linux/i2c.h>
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/of_device.h>
++#include <linux/regulator/consumer.h>
++#include <linux/slab.h>
++#include <linux/types.h>
++#include <media/v4l2-async.h>
++#include <media/v4l2-ctrls.h>
++#include <media/v4l2-device.h>
++#include <media/v4l2-event.h>
++#include <media/v4l2-fwnode.h>
++#include <media/v4l2-subdev.h>
++#include "stfcamss.h"
++
++/* min/typical/max system clock (xclk) frequencies */
++#define OV5640_XCLK_MIN 6000000
++#define OV5640_XCLK_MAX 54000000
++
++#define OV5640_SKIP_FRAMES 4
++
++#define OV5640_CHIP_ID 0x5640
++#define OV5640_DEFAULT_SLAVE_ID 0x3c
++
++#define OV5640_REG_SYS_RESET02 0x3002
++#define OV5640_REG_SYS_CLOCK_ENABLE02 0x3006
++#define OV5640_REG_SYS_CTRL0 0x3008
++#define OV5640_REG_SYS_CTRL0_SW_PWDN 0x42
++#define OV5640_REG_SYS_CTRL0_SW_PWUP 0x02
++#define OV5640_REG_CHIP_ID 0x300a
++#define OV5640_REG_IO_MIPI_CTRL00 0x300e
++#define OV5640_REG_PAD_OUTPUT_ENABLE01 0x3017
++#define OV5640_REG_PAD_OUTPUT_ENABLE02 0x3018
++#define OV5640_REG_PAD_OUTPUT00 0x3019
++#define OV5640_REG_SYSTEM_CONTROL1 0x302e
++#define OV5640_REG_SC_PLL_CTRL0 0x3034
++#define OV5640_REG_SC_PLL_CTRL1 0x3035
++#define OV5640_REG_SC_PLL_CTRL2 0x3036
++#define OV5640_REG_SC_PLL_CTRL3 0x3037
++#define OV5640_REG_SLAVE_ID 0x3100
++#define OV5640_REG_SCCB_SYS_CTRL1 0x3103
++#define OV5640_REG_SYS_ROOT_DIVIDER 0x3108
++#define OV5640_REG_AWB_R_GAIN 0x3400
++#define OV5640_REG_AWB_G_GAIN 0x3402
++#define OV5640_REG_AWB_B_GAIN 0x3404
++#define OV5640_REG_AWB_MANUAL_CTRL 0x3406
++#define OV5640_REG_AEC_PK_EXPOSURE_HI 0x3500
++#define OV5640_REG_AEC_PK_EXPOSURE_MED 0x3501
++#define OV5640_REG_AEC_PK_EXPOSURE_LO 0x3502
++#define OV5640_REG_AEC_PK_MANUAL 0x3503
++#define OV5640_REG_AEC_PK_REAL_GAIN 0x350a
++#define OV5640_REG_AEC_PK_VTS 0x350c
++#define OV5640_REG_TIMING_DVPHO 0x3808
++#define OV5640_REG_TIMING_DVPVO 0x380a
++#define OV5640_REG_TIMING_HTS 0x380c
++#define OV5640_REG_TIMING_VTS 0x380e
++#define OV5640_REG_TIMING_TC_REG20 0x3820
++#define OV5640_REG_TIMING_TC_REG21 0x3821
++#define OV5640_REG_AEC_CTRL00 0x3a00
++#define OV5640_REG_AEC_B50_STEP 0x3a08
++#define OV5640_REG_AEC_B60_STEP 0x3a0a
++#define OV5640_REG_AEC_CTRL0D 0x3a0d
++#define OV5640_REG_AEC_CTRL0E 0x3a0e
++#define OV5640_REG_AEC_CTRL0F 0x3a0f
++#define OV5640_REG_AEC_CTRL10 0x3a10
++#define OV5640_REG_AEC_CTRL11 0x3a11
++#define OV5640_REG_AEC_CTRL1B 0x3a1b
++#define OV5640_REG_AEC_CTRL1E 0x3a1e
++#define OV5640_REG_AEC_CTRL1F 0x3a1f
++#define OV5640_REG_HZ5060_CTRL00 0x3c00
++#define OV5640_REG_HZ5060_CTRL01 0x3c01
++#define OV5640_REG_SIGMADELTA_CTRL0C 0x3c0c
++#define OV5640_REG_FRAME_CTRL01 0x4202
++#define OV5640_REG_FORMAT_CONTROL00 0x4300
++#define OV5640_REG_VFIFO_HSIZE 0x4602
++#define OV5640_REG_VFIFO_VSIZE 0x4604
++#define OV5640_REG_JPG_MODE_SELECT 0x4713
++#define OV5640_REG_CCIR656_CTRL00 0x4730
++#define OV5640_REG_POLARITY_CTRL00 0x4740
++#define OV5640_REG_MIPI_CTRL00 0x4800
++#define OV5640_REG_DEBUG_MODE 0x4814
++#define OV5640_REG_ISP_FORMAT_MUX_CTRL 0x501f
++#define OV5640_REG_PRE_ISP_TEST_SET1 0x503d
++#define OV5640_REG_SDE_CTRL0 0x5580
++#define OV5640_REG_SDE_CTRL1 0x5581
++#define OV5640_REG_SDE_CTRL3 0x5583
++#define OV5640_REG_SDE_CTRL4 0x5584
++#define OV5640_REG_SDE_CTRL5 0x5585
++#define OV5640_REG_AVG_READOUT 0x56a1
++
++enum ov5640_mode_id {
++ OV5640_MODE_QCIF_176_144 = 0,
++ OV5640_MODE_QVGA_320_240,
++ OV5640_MODE_VGA_640_480,
++ OV5640_MODE_NTSC_720_480,
++ OV5640_MODE_PAL_720_576,
++ OV5640_MODE_XGA_1024_768,
++ OV5640_MODE_720P_1280_720,
++ OV5640_MODE_1080P_1920_1080,
++ OV5640_MODE_QSXGA_2592_1944,
++ OV5640_NUM_MODES,
++};
++
++enum ov5640_frame_rate {
++ OV5640_15_FPS = 0,
++ OV5640_30_FPS,
++ OV5640_60_FPS,
++ OV5640_NUM_FRAMERATES,
++};
++
++enum ov5640_format_mux {
++ OV5640_FMT_MUX_YUV422 = 0,
++ OV5640_FMT_MUX_RGB,
++ OV5640_FMT_MUX_DITHER,
++ OV5640_FMT_MUX_RAW_DPC,
++ OV5640_FMT_MUX_SNR_RAW,
++ OV5640_FMT_MUX_RAW_CIP,
++};
++
++struct ov5640_pixfmt {
++ u32 code;
++ u32 colorspace;
++};
++
++static const struct ov5640_pixfmt ov5640_formats[] = {
++ { MEDIA_BUS_FMT_JPEG_1X8, V4L2_COLORSPACE_JPEG, },
++ { MEDIA_BUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_SRGB, },
++ { MEDIA_BUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_SRGB, },
++ { MEDIA_BUS_FMT_RGB565_2X8_LE, V4L2_COLORSPACE_SRGB, },
++ { MEDIA_BUS_FMT_RGB565_2X8_BE, V4L2_COLORSPACE_SRGB, },
++ { MEDIA_BUS_FMT_SBGGR8_1X8, V4L2_COLORSPACE_SRGB, },
++ { MEDIA_BUS_FMT_SGBRG8_1X8, V4L2_COLORSPACE_SRGB, },
++ { MEDIA_BUS_FMT_SGRBG8_1X8, V4L2_COLORSPACE_SRGB, },
++ { MEDIA_BUS_FMT_SRGGB8_1X8, V4L2_COLORSPACE_SRGB, },
++};
++
++/*
++ * FIXME: remove this when a subdev API becomes available
++ * to set the MIPI CSI-2 virtual channel.
++ */
++static unsigned int virtual_channel;
++module_param(virtual_channel, uint, 0444);
++MODULE_PARM_DESC(virtual_channel,
++ "MIPI CSI-2 virtual channel (0..3), default 0");
++
++static const int ov5640_framerates[] = {
++ [OV5640_15_FPS] = 15,
++ [OV5640_30_FPS] = 30,
++ [OV5640_60_FPS] = 60,
++};
++
++/* regulator supplies */
++static const char * const ov5640_supply_name[] = {
++ "DOVDD", /* Digital I/O (1.8V) supply */
++ "AVDD", /* Analog (2.8V) supply */
++ "DVDD", /* Digital Core (1.5V) supply */
++};
++
++#define OV5640_NUM_SUPPLIES ARRAY_SIZE(ov5640_supply_name)
++
++/*
++ * Image size under 1280 * 960 are SUBSAMPLING
++ * Image size upper 1280 * 960 are SCALING
++ */
++enum ov5640_downsize_mode {
++ SUBSAMPLING,
++ SCALING,
++};
++
++struct reg_value {
++ u16 reg_addr;
++ u8 val;
++ u8 mask;
++ u32 delay_ms;
++};
++
++struct ov5640_mode_info {
++ enum ov5640_mode_id id;
++ enum ov5640_downsize_mode dn_mode;
++ u32 hact;
++ u32 htot;
++ u32 vact;
++ u32 vtot;
++ const struct reg_value *reg_data;
++ u32 reg_data_size;
++ u32 max_fps;
++};
++
++struct ov5640_ctrls {
++ struct v4l2_ctrl_handler handler;
++ struct v4l2_ctrl *pixel_rate;
++ struct {
++ struct v4l2_ctrl *auto_exp;
++ struct v4l2_ctrl *exposure;
++ };
++ struct {
++ struct v4l2_ctrl *auto_wb;
++ struct v4l2_ctrl *blue_balance;
++ struct v4l2_ctrl *red_balance;
++ };
++ struct {
++ struct v4l2_ctrl *auto_gain;
++ struct v4l2_ctrl *gain;
++ };
++ struct v4l2_ctrl *brightness;
++ struct v4l2_ctrl *light_freq;
++ struct v4l2_ctrl *saturation;
++ struct v4l2_ctrl *contrast;
++ struct v4l2_ctrl *hue;
++ struct v4l2_ctrl *test_pattern;
++ struct v4l2_ctrl *hflip;
++ struct v4l2_ctrl *vflip;
++};
++
++struct ov5640_dev {
++ struct i2c_client *i2c_client;
++ struct v4l2_subdev sd;
++ struct media_pad pad;
++ struct v4l2_fwnode_endpoint ep; /* the parsed DT endpoint info */
++ struct clk *xclk; /* system clock to OV5640 */
++ u32 xclk_freq;
++
++ struct regulator_bulk_data supplies[OV5640_NUM_SUPPLIES];
++ struct gpio_desc *reset_gpio;
++ struct gpio_desc *pwdn_gpio;
++ bool upside_down;
++
++ /* lock to protect all members below */
++ struct mutex lock;
++
++ int power_count;
++
++ struct v4l2_mbus_framefmt fmt;
++ bool pending_fmt_change;
++
++ const struct ov5640_mode_info *current_mode;
++ const struct ov5640_mode_info *last_mode;
++ enum ov5640_frame_rate current_fr;
++ struct v4l2_fract frame_interval;
++
++ struct ov5640_ctrls ctrls;
++
++ u32 prev_sysclk, prev_hts;
++ u32 ae_low, ae_high, ae_target;
++
++ bool pending_mode_change;
++ int streaming;
++};
++
++static inline struct ov5640_dev *to_ov5640_dev(struct v4l2_subdev *sd)
++{
++ return container_of(sd, struct ov5640_dev, sd);
++}
++
++static inline struct v4l2_subdev *ctrl_to_sd(struct v4l2_ctrl *ctrl)
++{
++ return &container_of(ctrl->handler, struct ov5640_dev,
++ ctrls.handler)->sd;
++}
++
++/*
++ * FIXME: all of these register tables are likely filled with
++ * entries that set the register to their power-on default values,
++ * and which are otherwise not touched by this driver. Those entries
++ * should be identified and removed to speed register load time
++ * over i2c.
++ */
++/* YUV422 UYVY VGA@30fps */
++static const struct reg_value ov5640_init_setting_30fps_VGA[] = {
++ {0x3103, 0x11, 0, 0}, {0x3008, 0x82, 0, 5}, {0x3008, 0x42, 0, 0},
++ {0x3103, 0x03, 0, 0}, {0x3630, 0x36, 0, 0},
++ {0x3631, 0x0e, 0, 0}, {0x3632, 0xe2, 0, 0}, {0x3633, 0x12, 0, 0},
++ {0x3621, 0xe0, 0, 0}, {0x3704, 0xa0, 0, 0}, {0x3703, 0x5a, 0, 0},
++ {0x3715, 0x78, 0, 0}, {0x3717, 0x01, 0, 0}, {0x370b, 0x60, 0, 0},
++ {0x3705, 0x1a, 0, 0}, {0x3905, 0x02, 0, 0}, {0x3906, 0x10, 0, 0},
++ {0x3901, 0x0a, 0, 0}, {0x3731, 0x12, 0, 0}, {0x3600, 0x08, 0, 0},
++ {0x3601, 0x33, 0, 0}, {0x302d, 0x60, 0, 0}, {0x3620, 0x52, 0, 0},
++ {0x371b, 0x20, 0, 0}, {0x471c, 0x50, 0, 0}, {0x3a13, 0x43, 0, 0},
++ {0x3a18, 0x00, 0, 0}, {0x3a19, 0xf8, 0, 0}, {0x3635, 0x13, 0, 0},
++ {0x3636, 0x03, 0, 0}, {0x3634, 0x40, 0, 0}, {0x3622, 0x01, 0, 0},
++ {0x3c01, 0xa4, 0, 0}, {0x3c04, 0x28, 0, 0}, {0x3c05, 0x98, 0, 0},
++ {0x3c06, 0x00, 0, 0}, {0x3c07, 0x08, 0, 0}, {0x3c08, 0x00, 0, 0},
++ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
++ {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
++ {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
++ {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
++ {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
++ {0x3810, 0x00, 0, 0},
++ {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
++ {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
++ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
++ {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
++ {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
++ {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
++ {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x3000, 0x00, 0, 0},
++ {0x3002, 0x1c, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3006, 0xc3, 0, 0},
++ {0x302e, 0x08, 0, 0}, {0x4300, 0x3f, 0, 0},
++ {0x501f, 0x00, 0, 0}, {0x4407, 0x04, 0, 0},
++ {0x440e, 0x00, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
++ {0x4837, 0x0a, 0, 0}, {0x3824, 0x02, 0, 0},
++ {0x5000, 0xa7, 0, 0}, {0x5001, 0xa3, 0, 0}, {0x5180, 0xff, 0, 0},
++ {0x5181, 0xf2, 0, 0}, {0x5182, 0x00, 0, 0}, {0x5183, 0x14, 0, 0},
++ {0x5184, 0x25, 0, 0}, {0x5185, 0x24, 0, 0}, {0x5186, 0x09, 0, 0},
++ {0x5187, 0x09, 0, 0}, {0x5188, 0x09, 0, 0}, {0x5189, 0x88, 0, 0},
++ {0x518a, 0x54, 0, 0}, {0x518b, 0xee, 0, 0}, {0x518c, 0xb2, 0, 0},
++ {0x518d, 0x50, 0, 0}, {0x518e, 0x34, 0, 0}, {0x518f, 0x6b, 0, 0},
++ {0x5190, 0x46, 0, 0}, {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0},
++ {0x5193, 0x70, 0, 0}, {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0},
++ {0x5196, 0x03, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0},
++ {0x5199, 0x6c, 0, 0}, {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0},
++ {0x519c, 0x09, 0, 0}, {0x519d, 0x2b, 0, 0}, {0x519e, 0x38, 0, 0},
++ {0x5381, 0x1e, 0, 0}, {0x5382, 0x5b, 0, 0}, {0x5383, 0x08, 0, 0},
++ {0x5384, 0x0a, 0, 0}, {0x5385, 0x7e, 0, 0}, {0x5386, 0x88, 0, 0},
++ {0x5387, 0x7c, 0, 0}, {0x5388, 0x6c, 0, 0}, {0x5389, 0x10, 0, 0},
++ {0x538a, 0x01, 0, 0}, {0x538b, 0x98, 0, 0}, {0x5300, 0x08, 0, 0},
++ {0x5301, 0x30, 0, 0}, {0x5302, 0x10, 0, 0}, {0x5303, 0x00, 0, 0},
++ {0x5304, 0x08, 0, 0}, {0x5305, 0x30, 0, 0}, {0x5306, 0x08, 0, 0},
++ {0x5307, 0x16, 0, 0}, {0x5309, 0x08, 0, 0}, {0x530a, 0x30, 0, 0},
++ {0x530b, 0x04, 0, 0}, {0x530c, 0x06, 0, 0}, {0x5480, 0x01, 0, 0},
++ {0x5481, 0x08, 0, 0}, {0x5482, 0x14, 0, 0}, {0x5483, 0x28, 0, 0},
++ {0x5484, 0x51, 0, 0}, {0x5485, 0x65, 0, 0}, {0x5486, 0x71, 0, 0},
++ {0x5487, 0x7d, 0, 0}, {0x5488, 0x87, 0, 0}, {0x5489, 0x91, 0, 0},
++ {0x548a, 0x9a, 0, 0}, {0x548b, 0xaa, 0, 0}, {0x548c, 0xb8, 0, 0},
++ {0x548d, 0xcd, 0, 0}, {0x548e, 0xdd, 0, 0}, {0x548f, 0xea, 0, 0},
++ {0x5490, 0x1d, 0, 0}, {0x5580, 0x02, 0, 0}, {0x5583, 0x40, 0, 0},
++ {0x5584, 0x10, 0, 0}, {0x5589, 0x10, 0, 0}, {0x558a, 0x00, 0, 0},
++ {0x558b, 0xf8, 0, 0}, {0x5800, 0x23, 0, 0}, {0x5801, 0x14, 0, 0},
++ {0x5802, 0x0f, 0, 0}, {0x5803, 0x0f, 0, 0}, {0x5804, 0x12, 0, 0},
++ {0x5805, 0x26, 0, 0}, {0x5806, 0x0c, 0, 0}, {0x5807, 0x08, 0, 0},
++ {0x5808, 0x05, 0, 0}, {0x5809, 0x05, 0, 0}, {0x580a, 0x08, 0, 0},
++ {0x580b, 0x0d, 0, 0}, {0x580c, 0x08, 0, 0}, {0x580d, 0x03, 0, 0},
++ {0x580e, 0x00, 0, 0}, {0x580f, 0x00, 0, 0}, {0x5810, 0x03, 0, 0},
++ {0x5811, 0x09, 0, 0}, {0x5812, 0x07, 0, 0}, {0x5813, 0x03, 0, 0},
++ {0x5814, 0x00, 0, 0}, {0x5815, 0x01, 0, 0}, {0x5816, 0x03, 0, 0},
++ {0x5817, 0x08, 0, 0}, {0x5818, 0x0d, 0, 0}, {0x5819, 0x08, 0, 0},
++ {0x581a, 0x05, 0, 0}, {0x581b, 0x06, 0, 0}, {0x581c, 0x08, 0, 0},
++ {0x581d, 0x0e, 0, 0}, {0x581e, 0x29, 0, 0}, {0x581f, 0x17, 0, 0},
++ {0x5820, 0x11, 0, 0}, {0x5821, 0x11, 0, 0}, {0x5822, 0x15, 0, 0},
++ {0x5823, 0x28, 0, 0}, {0x5824, 0x46, 0, 0}, {0x5825, 0x26, 0, 0},
++ {0x5826, 0x08, 0, 0}, {0x5827, 0x26, 0, 0}, {0x5828, 0x64, 0, 0},
++ {0x5829, 0x26, 0, 0}, {0x582a, 0x24, 0, 0}, {0x582b, 0x22, 0, 0},
++ {0x582c, 0x24, 0, 0}, {0x582d, 0x24, 0, 0}, {0x582e, 0x06, 0, 0},
++ {0x582f, 0x22, 0, 0}, {0x5830, 0x40, 0, 0}, {0x5831, 0x42, 0, 0},
++ {0x5832, 0x24, 0, 0}, {0x5833, 0x26, 0, 0}, {0x5834, 0x24, 0, 0},
++ {0x5835, 0x22, 0, 0}, {0x5836, 0x22, 0, 0}, {0x5837, 0x26, 0, 0},
++ {0x5838, 0x44, 0, 0}, {0x5839, 0x24, 0, 0}, {0x583a, 0x26, 0, 0},
++ {0x583b, 0x28, 0, 0}, {0x583c, 0x42, 0, 0}, {0x583d, 0xce, 0, 0},
++ {0x5025, 0x00, 0, 0}, {0x3a0f, 0x30, 0, 0}, {0x3a10, 0x28, 0, 0},
++ {0x3a1b, 0x30, 0, 0}, {0x3a1e, 0x26, 0, 0}, {0x3a11, 0x60, 0, 0},
++ {0x3a1f, 0x14, 0, 0}, {0x3008, 0x02, 0, 0}, {0x3c00, 0x04, 0, 300},
++};
++
++static const struct reg_value ov5640_setting_VGA_640_480[] = {
++ {0x3c07, 0x08, 0, 0},
++ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
++ {0x3814, 0x31, 0, 0},
++ {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
++ {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
++ {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
++ {0x3810, 0x00, 0, 0},
++ {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
++ {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
++ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
++ {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
++ {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
++ {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
++ {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0},
++ {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
++ {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
++};
++
++static const struct reg_value ov5640_setting_XGA_1024_768[] = {
++ {0x3c07, 0x08, 0, 0},
++ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
++ {0x3814, 0x31, 0, 0},
++ {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
++ {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
++ {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
++ {0x3810, 0x00, 0, 0},
++ {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
++ {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
++ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
++ {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
++ {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
++ {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
++ {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0},
++ {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
++ {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
++};
++
++static const struct reg_value ov5640_setting_QVGA_320_240[] = {
++ {0x3c07, 0x08, 0, 0},
++ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
++ {0x3814, 0x31, 0, 0},
++ {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
++ {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
++ {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
++ {0x3810, 0x00, 0, 0},
++ {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
++ {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
++ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
++ {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
++ {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
++ {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
++ {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0},
++ {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
++ {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
++};
++
++static const struct reg_value ov5640_setting_QCIF_176_144[] = {
++ {0x3c07, 0x08, 0, 0},
++ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
++ {0x3814, 0x31, 0, 0},
++ {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
++ {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
++ {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
++ {0x3810, 0x00, 0, 0},
++ {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
++ {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
++ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
++ {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
++ {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
++ {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
++ {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0},
++ {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
++ {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
++};
++
++static const struct reg_value ov5640_setting_NTSC_720_480[] = {
++ {0x3c07, 0x08, 0, 0},
++ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
++ {0x3814, 0x31, 0, 0},
++ {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
++ {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
++ {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
++ {0x3810, 0x00, 0, 0},
++ {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x3c, 0, 0},
++ {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
++ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
++ {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
++ {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
++ {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
++ {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0},
++ {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
++ {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
++};
++
++static const struct reg_value ov5640_setting_PAL_720_576[] = {
++ {0x3c07, 0x08, 0, 0},
++ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
++ {0x3814, 0x31, 0, 0},
++ {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
++ {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
++ {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
++ {0x3810, 0x00, 0, 0},
++ {0x3811, 0x38, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
++ {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
++ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
++ {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
++ {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
++ {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
++ {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0},
++ {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
++ {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0},
++};
++
++static const struct reg_value ov5640_setting_720P_1280_720[] = {
++ {0x3c07, 0x07, 0, 0},
++ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
++ {0x3814, 0x31, 0, 0},
++ {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
++ {0x3802, 0x00, 0, 0}, {0x3803, 0xfa, 0, 0}, {0x3804, 0x0a, 0, 0},
++ {0x3805, 0x3f, 0, 0}, {0x3806, 0x06, 0, 0}, {0x3807, 0xa9, 0, 0},
++ {0x3810, 0x00, 0, 0},
++ {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x04, 0, 0},
++ {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
++ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x02, 0, 0},
++ {0x3a03, 0xe4, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0xbc, 0, 0},
++ {0x3a0a, 0x01, 0, 0}, {0x3a0b, 0x72, 0, 0}, {0x3a0e, 0x01, 0, 0},
++ {0x3a0d, 0x02, 0, 0}, {0x3a14, 0x02, 0, 0}, {0x3a15, 0xe4, 0, 0},
++ {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0},
++ {0x4407, 0x04, 0, 0}, {0x460b, 0x37, 0, 0}, {0x460c, 0x20, 0, 0},
++ {0x3824, 0x04, 0, 0}, {0x5001, 0x83, 0, 0},
++};
++
++static const struct reg_value ov5640_setting_1080P_1920_1080[] = {
++ {0x3c07, 0x08, 0, 0},
++ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
++ {0x3814, 0x11, 0, 0},
++ {0x3815, 0x11, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
++ {0x3802, 0x00, 0, 0}, {0x3803, 0x00, 0, 0}, {0x3804, 0x0a, 0, 0},
++ {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9f, 0, 0},
++ {0x3810, 0x00, 0, 0},
++ {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x04, 0, 0},
++ {0x3618, 0x04, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x21, 0, 0},
++ {0x3709, 0x12, 0, 0}, {0x370c, 0x00, 0, 0}, {0x3a02, 0x03, 0, 0},
++ {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
++ {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
++ {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
++ {0x4001, 0x02, 0, 0}, {0x4004, 0x06, 0, 0},
++ {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
++ {0x3824, 0x02, 0, 0}, {0x5001, 0x83, 0, 0},
++ {0x3c07, 0x07, 0, 0}, {0x3c08, 0x00, 0, 0},
++ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
++ {0x3800, 0x01, 0, 0}, {0x3801, 0x50, 0, 0}, {0x3802, 0x01, 0, 0},
++ {0x3803, 0xb2, 0, 0}, {0x3804, 0x08, 0, 0}, {0x3805, 0xef, 0, 0},
++ {0x3806, 0x05, 0, 0}, {0x3807, 0xf1, 0, 0},
++ {0x3612, 0x2b, 0, 0}, {0x3708, 0x64, 0, 0},
++ {0x3a02, 0x04, 0, 0}, {0x3a03, 0x60, 0, 0}, {0x3a08, 0x01, 0, 0},
++ {0x3a09, 0x50, 0, 0}, {0x3a0a, 0x01, 0, 0}, {0x3a0b, 0x18, 0, 0},
++ {0x3a0e, 0x03, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x04, 0, 0},
++ {0x3a15, 0x60, 0, 0}, {0x4407, 0x04, 0, 0},
++ {0x460b, 0x37, 0, 0}, {0x460c, 0x20, 0, 0}, {0x3824, 0x04, 0, 0},
++ {0x4005, 0x1a, 0, 0},
++};
++
++static const struct reg_value ov5640_setting_QSXGA_2592_1944[] = {
++ {0x3c07, 0x08, 0, 0},
++ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
++ {0x3814, 0x11, 0, 0},
++ {0x3815, 0x11, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
++ {0x3802, 0x00, 0, 0}, {0x3803, 0x00, 0, 0}, {0x3804, 0x0a, 0, 0},
++ {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9f, 0, 0},
++ {0x3810, 0x00, 0, 0},
++ {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x04, 0, 0},
++ {0x3618, 0x04, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x21, 0, 0},
++ {0x3709, 0x12, 0, 0}, {0x370c, 0x00, 0, 0}, {0x3a02, 0x03, 0, 0},
++ {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
++ {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
++ {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
++ {0x4001, 0x02, 0, 0}, {0x4004, 0x06, 0, 0},
++ {0x4407, 0x04, 0, 0}, {0x460b, 0x37, 0, 0}, {0x460c, 0x20, 0, 0},
++ {0x3824, 0x04, 0, 0}, {0x5001, 0x83, 0, 70},
++};
++
++/* power-on sensor init reg table */
++static const struct ov5640_mode_info ov5640_mode_init_data = {
++ 0, SUBSAMPLING, 640, 1896, 480, 984,
++ ov5640_init_setting_30fps_VGA,
++ ARRAY_SIZE(ov5640_init_setting_30fps_VGA),
++ OV5640_30_FPS,
++};
++
++static const struct ov5640_mode_info
++ov5640_mode_data[OV5640_NUM_MODES] = {
++ {OV5640_MODE_QCIF_176_144, SUBSAMPLING,
++ 176, 1896, 144, 984,
++ ov5640_setting_QCIF_176_144,
++ ARRAY_SIZE(ov5640_setting_QCIF_176_144),
++ OV5640_30_FPS},
++ {OV5640_MODE_QVGA_320_240, SUBSAMPLING,
++ 320, 1896, 240, 984,
++ ov5640_setting_QVGA_320_240,
++ ARRAY_SIZE(ov5640_setting_QVGA_320_240),
++ OV5640_30_FPS},
++ {OV5640_MODE_VGA_640_480, SUBSAMPLING,
++ 640, 1896, 480, 1080,
++ ov5640_setting_VGA_640_480,
++ ARRAY_SIZE(ov5640_setting_VGA_640_480),
++ OV5640_60_FPS},
++ {OV5640_MODE_NTSC_720_480, SUBSAMPLING,
++ 720, 1896, 480, 984,
++ ov5640_setting_NTSC_720_480,
++ ARRAY_SIZE(ov5640_setting_NTSC_720_480),
++ OV5640_30_FPS},
++ {OV5640_MODE_PAL_720_576, SUBSAMPLING,
++ 720, 1896, 576, 984,
++ ov5640_setting_PAL_720_576,
++ ARRAY_SIZE(ov5640_setting_PAL_720_576),
++ OV5640_30_FPS},
++ {OV5640_MODE_XGA_1024_768, SUBSAMPLING,
++ 1024, 1896, 768, 1080,
++ ov5640_setting_XGA_1024_768,
++ ARRAY_SIZE(ov5640_setting_XGA_1024_768),
++ OV5640_30_FPS},
++ {OV5640_MODE_720P_1280_720, SUBSAMPLING,
++ 1280, 1892, 720, 740,
++ ov5640_setting_720P_1280_720,
++ ARRAY_SIZE(ov5640_setting_720P_1280_720),
++ OV5640_30_FPS},
++ {OV5640_MODE_1080P_1920_1080, SCALING,
++ 1920, 2500, 1080, 1120,
++ ov5640_setting_1080P_1920_1080,
++ ARRAY_SIZE(ov5640_setting_1080P_1920_1080),
++ OV5640_30_FPS},
++ {OV5640_MODE_QSXGA_2592_1944, SCALING,
++ 2592, 2844, 1944, 1968,
++ ov5640_setting_QSXGA_2592_1944,
++ ARRAY_SIZE(ov5640_setting_QSXGA_2592_1944),
++ OV5640_15_FPS},
++};
++
++static int ov5640_init_slave_id(struct ov5640_dev *sensor)
++{
++ struct i2c_client *client = sensor->i2c_client;
++ struct i2c_msg msg;
++ u8 buf[3];
++ int ret;
++
++ if (client->addr == OV5640_DEFAULT_SLAVE_ID)
++ return 0;
++
++ buf[0] = OV5640_REG_SLAVE_ID >> 8;
++ buf[1] = OV5640_REG_SLAVE_ID & 0xff;
++ buf[2] = client->addr << 1;
++
++ msg.addr = OV5640_DEFAULT_SLAVE_ID;
++ msg.flags = 0;
++ msg.buf = buf;
++ msg.len = sizeof(buf);
++
++ ret = i2c_transfer(client->adapter, &msg, 1);
++ if (ret < 0) {
++ dev_err(&client->dev, "%s: failed with %d\n", __func__, ret);
++ return ret;
++ }
++
++ return 0;
++}
++
++static int ov5640_write_reg(struct ov5640_dev *sensor, u16 reg, u8 val)
++{
++ struct i2c_client *client = sensor->i2c_client;
++ struct i2c_msg msg;
++ u8 buf[3];
++ int ret;
++
++ buf[0] = reg >> 8;
++ buf[1] = reg & 0xff;
++ buf[2] = val;
++
++ msg.addr = client->addr;
++ msg.flags = client->flags;
++ msg.buf = buf;
++ msg.len = sizeof(buf);
++
++ ret = i2c_transfer(client->adapter, &msg, 1);
++ if (ret < 0) {
++ dev_err(&client->dev, "%s: error: reg=%x, val=%x\n",
++ __func__, reg, val);
++ return ret;
++ }
++
++ return 0;
++}
++
++static int ov5640_read_reg(struct ov5640_dev *sensor, u16 reg, u8 *val)
++{
++ struct i2c_client *client = sensor->i2c_client;
++ struct i2c_msg msg[2];
++ u8 buf[2];
++ int ret;
++
++ buf[0] = reg >> 8;
++ buf[1] = reg & 0xff;
++
++ msg[0].addr = client->addr;
++ msg[0].flags = client->flags;
++ msg[0].buf = buf;
++ msg[0].len = sizeof(buf);
++
++ msg[1].addr = client->addr;
++ msg[1].flags = client->flags | I2C_M_RD;
++ msg[1].buf = buf;
++ msg[1].len = 1;
++
++ ret = i2c_transfer(client->adapter, msg, 2);
++ if (ret < 0) {
++ dev_err(&client->dev, "%s: error: reg=%x\n",
++ __func__, reg);
++ return ret;
++ }
++
++ *val = buf[0];
++ return 0;
++}
++
++static int ov5640_read_reg16(struct ov5640_dev *sensor, u16 reg, u16 *val)
++{
++ u8 hi, lo;
++ int ret;
++
++ ret = ov5640_read_reg(sensor, reg, &hi);
++ if (ret)
++ return ret;
++ ret = ov5640_read_reg(sensor, reg + 1, &lo);
++ if (ret)
++ return ret;
++
++ *val = ((u16)hi << 8) | (u16)lo;
++ return 0;
++}
++
++static int ov5640_write_reg16(struct ov5640_dev *sensor, u16 reg, u16 val)
++{
++ int ret;
++
++ ret = ov5640_write_reg(sensor, reg, val >> 8);
++ if (ret)
++ return ret;
++
++ return ov5640_write_reg(sensor, reg + 1, val & 0xff);
++}
++
++static int ov5640_mod_reg(struct ov5640_dev *sensor, u16 reg,
++ u8 mask, u8 val)
++{
++ u8 readval;
++ int ret;
++
++ ret = ov5640_read_reg(sensor, reg, &readval);
++ if (ret)
++ return ret;
++
++ readval &= ~mask;
++ val &= mask;
++ val |= readval;
++
++ return ov5640_write_reg(sensor, reg, val);
++}
++
++/*
++ * After trying the various combinations, reading various
++ * documentations spread around the net, and from the various
++ * feedback, the clock tree is probably as follows:
++ *
++ * +--------------+
++ * | Ext. Clock |
++ * +-+------------+
++ * | +----------+
++ * +->| PLL1 | - reg 0x3036, for the multiplier
++ * +-+--------+ - reg 0x3037, bits 0-3 for the pre-divider
++ * | +--------------+
++ * +->| System Clock | - reg 0x3035, bits 4-7
++ * +-+------------+
++ * | +--------------+
++ * +->| MIPI Divider | - reg 0x3035, bits 0-3
++ * | +-+------------+
++ * | +----------------> MIPI SCLK
++ * | + +-----+
++ * | +->| / 2 |-------> MIPI BIT CLK
++ * | +-----+
++ * | +--------------+
++ * +->| PLL Root Div | - reg 0x3037, bit 4
++ * +-+------------+
++ * | +---------+
++ * +->| Bit Div | - reg 0x3034, bits 0-3
++ * +-+-------+
++ * | +-------------+
++ * +->| SCLK Div | - reg 0x3108, bits 0-1
++ * | +-+-----------+
++ * | +---------------> SCLK
++ * | +-------------+
++ * +->| SCLK 2X Div | - reg 0x3108, bits 2-3
++ * | +-+-----------+
++ * | +---------------> SCLK 2X
++ * | +-------------+
++ * +->| PCLK Div | - reg 0x3108, bits 4-5
++ * ++------------+
++ * + +-----------+
++ * +->| P_DIV | - reg 0x3035, bits 0-3
++ * +-----+-----+
++ * +------------> PCLK
++ *
++ * This is deviating from the datasheet at least for the register
++ * 0x3108, since it's said here that the PCLK would be clocked from
++ * the PLL.
++ *
++ * There seems to be also (unverified) constraints:
++ * - the PLL pre-divider output rate should be in the 4-27MHz range
++ * - the PLL multiplier output rate should be in the 500-1000MHz range
++ * - PCLK >= SCLK * 2 in YUV, >= SCLK in Raw or JPEG
++ *
++ * In the two latter cases, these constraints are met since our
++ * factors are hardcoded. If we were to change that, we would need to
++ * take this into account. The only varying parts are the PLL
++ * multiplier and the system clock divider, which are shared between
++ * all these clocks so won't cause any issue.
++ */
++
++/*
++ * This is supposed to be ranging from 1 to 8, but the value is always
++ * set to 3 in the vendor kernels.
++ */
++#define OV5640_PLL_PREDIV 3
++
++#define OV5640_PLL_MULT_MIN 4
++#define OV5640_PLL_MULT_MAX 252
++
++/*
++ * This is supposed to be ranging from 1 to 16, but the value is
++ * always set to either 1 or 2 in the vendor kernels.
++ */
++#define OV5640_SYSDIV_MIN 1
++#define OV5640_SYSDIV_MAX 16
++
++/*
++ * Hardcode these values for scaler and non-scaler modes.
++ * FIXME: to be re-calcualted for 1 data lanes setups
++ */
++#define OV5640_MIPI_DIV_PCLK 2
++#define OV5640_MIPI_DIV_SCLK 1
++
++/*
++ * This is supposed to be ranging from 1 to 2, but the value is always
++ * set to 2 in the vendor kernels.
++ */
++#define OV5640_PLL_ROOT_DIV 2
++#define OV5640_PLL_CTRL3_PLL_ROOT_DIV_2 BIT(4)
++
++/*
++ * We only supports 8-bit formats at the moment
++ */
++#define OV5640_BIT_DIV 2
++#define OV5640_PLL_CTRL0_MIPI_MODE_8BIT 0x08
++
++/*
++ * This is supposed to be ranging from 1 to 8, but the value is always
++ * set to 2 in the vendor kernels.
++ */
++#define OV5640_SCLK_ROOT_DIV 2
++
++/*
++ * This is hardcoded so that the consistency is maintained between SCLK and
++ * SCLK 2x.
++ */
++#define OV5640_SCLK2X_ROOT_DIV (OV5640_SCLK_ROOT_DIV / 2)
++
++/*
++ * This is supposed to be ranging from 1 to 8, but the value is always
++ * set to 1 in the vendor kernels.
++ */
++#define OV5640_PCLK_ROOT_DIV 1
++#define OV5640_PLL_SYS_ROOT_DIVIDER_BYPASS 0x00
++
++static unsigned long ov5640_compute_sys_clk(struct ov5640_dev *sensor,
++ u8 pll_prediv, u8 pll_mult,
++ u8 sysdiv)
++{
++ unsigned long sysclk = sensor->xclk_freq / pll_prediv * pll_mult;
++
++ /* PLL1 output cannot exceed 1GHz. */
++ if (sysclk / 1000000 > 1000)
++ return 0;
++
++ return sysclk / sysdiv;
++}
++
++static unsigned long ov5640_calc_sys_clk(struct ov5640_dev *sensor,
++ unsigned long rate,
++ u8 *pll_prediv, u8 *pll_mult,
++ u8 *sysdiv)
++{
++ unsigned long best = ~0;
++ u8 best_sysdiv = 1, best_mult = 1;
++ u8 _sysdiv, _pll_mult;
++
++ for (_sysdiv = OV5640_SYSDIV_MIN;
++ _sysdiv <= OV5640_SYSDIV_MAX;
++ _sysdiv++) {
++ for (_pll_mult = OV5640_PLL_MULT_MIN;
++ _pll_mult <= OV5640_PLL_MULT_MAX;
++ _pll_mult++) {
++ unsigned long _rate;
++
++ /*
++ * The PLL multiplier cannot be odd if above
++ * 127.
++ */
++ if (_pll_mult > 127 && (_pll_mult % 2))
++ continue;
++
++ _rate = ov5640_compute_sys_clk(sensor,
++ OV5640_PLL_PREDIV,
++ _pll_mult, _sysdiv);
++
++ /*
++ * We have reached the maximum allowed PLL1 output,
++ * increase sysdiv.
++ */
++ if (!_rate)
++ break;
++
++ /*
++ * Prefer rates above the expected clock rate than
++ * below, even if that means being less precise.
++ */
++ if (_rate < rate)
++ continue;
++
++ if (abs(rate - _rate) < abs(rate - best)) {
++ best = _rate;
++ best_sysdiv = _sysdiv;
++ best_mult = _pll_mult;
++ }
++
++ if (_rate == rate)
++ goto out;
++ }
++ }
++
++out:
++ *sysdiv = best_sysdiv;
++ *pll_prediv = OV5640_PLL_PREDIV;
++ *pll_mult = best_mult;
++
++ return best;
++}
++
++/*
++ * ov5640_set_mipi_pclk() - Calculate the clock tree configuration values
++ * for the MIPI CSI-2 output.
++ *
++ * @rate: The requested bandwidth per lane in bytes per second.
++ * 'Bandwidth Per Lane' is calculated as:
++ * bpl = HTOT * VTOT * FPS * bpp / num_lanes;
++ *
++ * This function use the requested bandwidth to calculate:
++ * - sample_rate = bpl / (bpp / num_lanes);
++ * = bpl / (PLL_RDIV * BIT_DIV * PCLK_DIV * MIPI_DIV / num_lanes);
++ *
++ * - mipi_sclk = bpl / MIPI_DIV / 2; ( / 2 is for CSI-2 DDR)
++ *
++ * with these fixed parameters:
++ * PLL_RDIV = 2;
++ * BIT_DIVIDER = 2; (MIPI_BIT_MODE == 8 ? 2 : 2,5);
++ * PCLK_DIV = 1;
++ *
++ * The MIPI clock generation differs for modes that use the scaler and modes
++ * that do not. In case the scaler is in use, the MIPI_SCLK generates the MIPI
++ * BIT CLk, and thus:
++ *
++ * - mipi_sclk = bpl / MIPI_DIV / 2;
++ * MIPI_DIV = 1;
++ *
++ * For modes that do not go through the scaler, the MIPI BIT CLOCK is generated
++ * from the pixel clock, and thus:
++ *
++ * - sample_rate = bpl / (bpp / num_lanes);
++ * = bpl / (2 * 2 * 1 * MIPI_DIV / num_lanes);
++ * = bpl / (4 * MIPI_DIV / num_lanes);
++ * - MIPI_DIV = bpp / (4 * num_lanes);
++ *
++ * FIXME: this have been tested with 16bpp and 2 lanes setup only.
++ * MIPI_DIV is fixed to value 2, but it -might- be changed according to the
++ * above formula for setups with 1 lane or image formats with different bpp.
++ *
++ * FIXME: this deviates from the sensor manual documentation which is quite
++ * thin on the MIPI clock tree generation part.
++ */
++static int ov5640_set_mipi_pclk(struct ov5640_dev *sensor,
++ unsigned long rate)
++{
++ const struct ov5640_mode_info *mode = sensor->current_mode;
++ u8 prediv, mult, sysdiv;
++ u8 mipi_div;
++ int ret;
++
++ /*
++ * 1280x720 is reported to use 'SUBSAMPLING' only,
++ * but according to the sensor manual it goes through the
++ * scaler before subsampling.
++ */
++ if (mode->dn_mode == SCALING ||
++ (mode->id == OV5640_MODE_720P_1280_720))
++ mipi_div = OV5640_MIPI_DIV_SCLK;
++ else
++ mipi_div = OV5640_MIPI_DIV_PCLK;
++
++ ov5640_calc_sys_clk(sensor, rate, &prediv, &mult, &sysdiv);
++
++ ret = ov5640_mod_reg(sensor, OV5640_REG_SC_PLL_CTRL0,
++ 0x0f, OV5640_PLL_CTRL0_MIPI_MODE_8BIT);
++
++ ret = ov5640_mod_reg(sensor, OV5640_REG_SC_PLL_CTRL1,
++ 0xff, sysdiv << 4 | mipi_div);
++ if (ret)
++ return ret;
++
++ ret = ov5640_mod_reg(sensor, OV5640_REG_SC_PLL_CTRL2, 0xff, mult);
++ if (ret)
++ return ret;
++
++ ret = ov5640_mod_reg(sensor, OV5640_REG_SC_PLL_CTRL3,
++ 0x1f, OV5640_PLL_CTRL3_PLL_ROOT_DIV_2 | prediv);
++ if (ret)
++ return ret;
++
++ return ov5640_mod_reg(sensor, OV5640_REG_SYS_ROOT_DIVIDER,
++ 0x30, OV5640_PLL_SYS_ROOT_DIVIDER_BYPASS);
++}
++
++static unsigned long ov5640_calc_pclk(struct ov5640_dev *sensor,
++ unsigned long rate,
++ u8 *pll_prediv, u8 *pll_mult, u8 *sysdiv,
++ u8 *pll_rdiv, u8 *bit_div, u8 *pclk_div)
++{
++ unsigned long _rate = rate * OV5640_PLL_ROOT_DIV * OV5640_BIT_DIV *
++ OV5640_PCLK_ROOT_DIV;
++
++ _rate = ov5640_calc_sys_clk(sensor, _rate, pll_prediv, pll_mult,
++ sysdiv);
++ *pll_rdiv = OV5640_PLL_ROOT_DIV;
++ *bit_div = OV5640_BIT_DIV;
++ *pclk_div = OV5640_PCLK_ROOT_DIV;
++
++ return _rate / *pll_rdiv / *bit_div / *pclk_div;
++}
++
++static int ov5640_set_dvp_pclk(struct ov5640_dev *sensor, unsigned long rate)
++{
++ u8 prediv, mult, sysdiv, pll_rdiv, bit_div, pclk_div;
++ int ret;
++
++ ov5640_calc_pclk(sensor, rate, &prediv, &mult, &sysdiv, &pll_rdiv,
++ &bit_div, &pclk_div);
++
++#ifndef CONFIG_VIN_SENSOR_OV5640
++ if (bit_div == 2)
++ bit_div = 8;
++#else
++ bit_div = 0xa;
++#endif
++ ret = ov5640_mod_reg(sensor, OV5640_REG_SC_PLL_CTRL0,
++ 0x0f, bit_div);
++ if (ret)
++ return ret;
++
++ /*
++ * We need to set sysdiv according to the clock, and to clear
++ * the MIPI divider.
++ */
++ ret = ov5640_mod_reg(sensor, OV5640_REG_SC_PLL_CTRL1,
++ 0xff, sysdiv << 4);
++ if (ret)
++ return ret;
++
++ ret = ov5640_mod_reg(sensor, OV5640_REG_SC_PLL_CTRL2,
++ 0xff, mult);
++ if (ret)
++ return ret;
++
++ ret = ov5640_mod_reg(sensor, OV5640_REG_SC_PLL_CTRL3,
++ 0x1f, prediv | ((pll_rdiv - 1) << 4));
++ if (ret)
++ return ret;
++
++ return ov5640_mod_reg(sensor, OV5640_REG_SYS_ROOT_DIVIDER, 0x30,
++ (ilog2(pclk_div) << 4));
++}
++
++/* set JPEG framing sizes */
++static int ov5640_set_jpeg_timings(struct ov5640_dev *sensor,
++ const struct ov5640_mode_info *mode)
++{
++ int ret;
++
++ /*
++ * compression mode 3 timing
++ *
++ * Data is transmitted with programmable width (VFIFO_HSIZE).
++ * No padding done. Last line may have less data. Varying
++ * number of lines per frame, depending on amount of data.
++ */
++ ret = ov5640_mod_reg(sensor, OV5640_REG_JPG_MODE_SELECT, 0x7, 0x3);
++ if (ret < 0)
++ return ret;
++
++ ret = ov5640_write_reg16(sensor, OV5640_REG_VFIFO_HSIZE, mode->hact);
++ if (ret < 0)
++ return ret;
++
++ return ov5640_write_reg16(sensor, OV5640_REG_VFIFO_VSIZE, mode->vact);
++}
++
++/* download ov5640 settings to sensor through i2c */
++static int ov5640_set_timings(struct ov5640_dev *sensor,
++ const struct ov5640_mode_info *mode)
++{
++ int ret;
++
++ if (sensor->fmt.code == MEDIA_BUS_FMT_JPEG_1X8) {
++ ret = ov5640_set_jpeg_timings(sensor, mode);
++ if (ret < 0)
++ return ret;
++ }
++
++ ret = ov5640_write_reg16(sensor, OV5640_REG_TIMING_DVPHO, mode->hact);
++ if (ret < 0)
++ return ret;
++
++ ret = ov5640_write_reg16(sensor, OV5640_REG_TIMING_DVPVO, mode->vact);
++ if (ret < 0)
++ return ret;
++
++ ret = ov5640_write_reg16(sensor, OV5640_REG_TIMING_HTS, mode->htot);
++ if (ret < 0)
++ return ret;
++
++ return ov5640_write_reg16(sensor, OV5640_REG_TIMING_VTS, mode->vtot);
++}
++
++static int ov5640_load_regs(struct ov5640_dev *sensor,
++ const struct ov5640_mode_info *mode)
++{
++ const struct reg_value *regs = mode->reg_data;
++ unsigned int i;
++ u32 delay_ms;
++ u16 reg_addr;
++ u8 mask, val;
++ int ret = 0;
++
++ st_info(ST_SENSOR, "%s, mode = 0x%x\n", __func__, mode->id);
++ for (i = 0; i < mode->reg_data_size; ++i, ++regs) {
++ delay_ms = regs->delay_ms;
++ reg_addr = regs->reg_addr;
++ val = regs->val;
++ mask = regs->mask;
++
++ /* remain in power down mode for DVP */
++ if (regs->reg_addr == OV5640_REG_SYS_CTRL0 &&
++ val == OV5640_REG_SYS_CTRL0_SW_PWUP &&
++ sensor->ep.bus_type != V4L2_MBUS_CSI2_DPHY)
++ continue;
++
++ if (mask)
++ ret = ov5640_mod_reg(sensor, reg_addr, mask, val);
++ else
++ ret = ov5640_write_reg(sensor, reg_addr, val);
++ if (ret)
++ break;
++
++ if (delay_ms)
++ usleep_range(1000 * delay_ms, 1000 * delay_ms + 100);
++ }
++
++ return ov5640_set_timings(sensor, mode);
++}
++
++static int ov5640_set_autoexposure(struct ov5640_dev *sensor, bool on)
++{
++ return ov5640_mod_reg(sensor, OV5640_REG_AEC_PK_MANUAL,
++ BIT(0), on ? 0 : BIT(0));
++}
++
++/* read exposure, in number of line periods */
++static int ov5640_get_exposure(struct ov5640_dev *sensor)
++{
++ int exp, ret;
++ u8 temp;
++
++ ret = ov5640_read_reg(sensor, OV5640_REG_AEC_PK_EXPOSURE_HI, &temp);
++ if (ret)
++ return ret;
++ exp = ((int)temp & 0x0f) << 16;
++ ret = ov5640_read_reg(sensor, OV5640_REG_AEC_PK_EXPOSURE_MED, &temp);
++ if (ret)
++ return ret;
++ exp |= ((int)temp << 8);
++ ret = ov5640_read_reg(sensor, OV5640_REG_AEC_PK_EXPOSURE_LO, &temp);
++ if (ret)
++ return ret;
++ exp |= (int)temp;
++
++ return exp >> 4;
++}
++
++/* write exposure, given number of line periods */
++static int ov5640_set_exposure(struct ov5640_dev *sensor, u32 exposure)
++{
++ int ret;
++
++ exposure <<= 4;
++
++ ret = ov5640_write_reg(sensor,
++ OV5640_REG_AEC_PK_EXPOSURE_LO,
++ exposure & 0xff);
++ if (ret)
++ return ret;
++ ret = ov5640_write_reg(sensor,
++ OV5640_REG_AEC_PK_EXPOSURE_MED,
++ (exposure >> 8) & 0xff);
++ if (ret)
++ return ret;
++ return ov5640_write_reg(sensor,
++ OV5640_REG_AEC_PK_EXPOSURE_HI,
++ (exposure >> 16) & 0x0f);
++}
++
++static int ov5640_get_gain(struct ov5640_dev *sensor)
++{
++ u16 gain;
++ int ret;
++
++ ret = ov5640_read_reg16(sensor, OV5640_REG_AEC_PK_REAL_GAIN, &gain);
++ if (ret)
++ return ret;
++
++ return gain & 0x3ff;
++}
++
++static int ov5640_set_gain(struct ov5640_dev *sensor, int gain)
++{
++ return ov5640_write_reg16(sensor, OV5640_REG_AEC_PK_REAL_GAIN,
++ (u16)gain & 0x3ff);
++}
++
++static int ov5640_set_autogain(struct ov5640_dev *sensor, bool on)
++{
++ return ov5640_mod_reg(sensor, OV5640_REG_AEC_PK_MANUAL,
++ BIT(1), on ? 0 : BIT(1));
++}
++
++static int ov5640_set_stream_dvp(struct ov5640_dev *sensor, bool on)
++{
++ return ov5640_write_reg(sensor, OV5640_REG_SYS_CTRL0, on ?
++ OV5640_REG_SYS_CTRL0_SW_PWUP :
++ OV5640_REG_SYS_CTRL0_SW_PWDN);
++}
++
++static int ov5640_set_stream_mipi(struct ov5640_dev *sensor, bool on)
++{
++ int ret;
++
++ /*
++ * Enable/disable the MIPI interface
++ *
++ * 0x300e = on ? 0x45 : 0x40
++ *
++ * FIXME: the sensor manual (version 2.03) reports
++ * [7:5] = 000 : 1 data lane mode
++ * [7:5] = 001 : 2 data lanes mode
++ * But this settings do not work, while the following ones
++ * have been validated for 2 data lanes mode.
++ *
++ * [7:5] = 010 : 2 data lanes mode
++ * [4] = 0 : Power up MIPI HS Tx
++ * [3] = 0 : Power up MIPI LS Rx
++ * [2] = 1/0 : MIPI interface enable/disable
++ * [1:0] = 01/00: FIXME: 'debug'
++ */
++ ret = ov5640_write_reg(sensor, OV5640_REG_IO_MIPI_CTRL00,
++ on ? 0x45 : 0x40);
++ if (ret)
++ return ret;
++
++ return ov5640_write_reg(sensor, OV5640_REG_FRAME_CTRL01,
++ on ? 0x00 : 0x0f);
++}
++
++static int ov5640_get_sysclk(struct ov5640_dev *sensor)
++{
++ /* calculate sysclk */
++ u32 xvclk = sensor->xclk_freq / 10000;
++ u32 multiplier, prediv, VCO, sysdiv, pll_rdiv;
++ u32 sclk_rdiv_map[] = {1, 2, 4, 8};
++ u32 bit_div2x = 1, sclk_rdiv, sysclk;
++ u8 temp1, temp2;
++ int ret;
++
++ ret = ov5640_read_reg(sensor, OV5640_REG_SC_PLL_CTRL0, &temp1);
++ if (ret)
++ return ret;
++ temp2 = temp1 & 0x0f;
++ if (temp2 == 8 || temp2 == 10)
++ bit_div2x = temp2 / 2;
++
++ ret = ov5640_read_reg(sensor, OV5640_REG_SC_PLL_CTRL1, &temp1);
++ if (ret)
++ return ret;
++ sysdiv = temp1 >> 4;
++ if (sysdiv == 0)
++ sysdiv = 16;
++
++ ret = ov5640_read_reg(sensor, OV5640_REG_SC_PLL_CTRL2, &temp1);
++ if (ret)
++ return ret;
++ multiplier = temp1;
++
++ ret = ov5640_read_reg(sensor, OV5640_REG_SC_PLL_CTRL3, &temp1);
++ if (ret)
++ return ret;
++ prediv = temp1 & 0x0f;
++ pll_rdiv = ((temp1 >> 4) & 0x01) + 1;
++
++ ret = ov5640_read_reg(sensor, OV5640_REG_SYS_ROOT_DIVIDER, &temp1);
++ if (ret)
++ return ret;
++ temp2 = temp1 & 0x03;
++ sclk_rdiv = sclk_rdiv_map[temp2];
++
++ if (!prediv || !sysdiv || !pll_rdiv || !bit_div2x)
++ return -EINVAL;
++
++ VCO = xvclk * multiplier / prediv;
++
++ sysclk = VCO / sysdiv / pll_rdiv * 2 / bit_div2x / sclk_rdiv;
++
++ return sysclk;
++}
++
++static int ov5640_set_night_mode(struct ov5640_dev *sensor)
++{
++ /* read HTS from register settings */
++ u8 mode;
++ int ret;
++
++ ret = ov5640_read_reg(sensor, OV5640_REG_AEC_CTRL00, &mode);
++ if (ret)
++ return ret;
++ mode &= 0xfb;
++ return ov5640_write_reg(sensor, OV5640_REG_AEC_CTRL00, mode);
++}
++
++static int ov5640_get_hts(struct ov5640_dev *sensor)
++{
++ /* read HTS from register settings */
++ u16 hts;
++ int ret;
++
++ ret = ov5640_read_reg16(sensor, OV5640_REG_TIMING_HTS, &hts);
++ if (ret)
++ return ret;
++ return hts;
++}
++
++static int ov5640_get_vts(struct ov5640_dev *sensor)
++{
++ u16 vts;
++ int ret;
++
++ ret = ov5640_read_reg16(sensor, OV5640_REG_TIMING_VTS, &vts);
++ if (ret)
++ return ret;
++ return vts;
++}
++
++static int ov5640_set_vts(struct ov5640_dev *sensor, int vts)
++{
++ return ov5640_write_reg16(sensor, OV5640_REG_TIMING_VTS, vts);
++}
++
++static int ov5640_get_light_freq(struct ov5640_dev *sensor)
++{
++ /* get banding filter value */
++ int ret, light_freq = 0;
++ u8 temp, temp1;
++
++ ret = ov5640_read_reg(sensor, OV5640_REG_HZ5060_CTRL01, &temp);
++ if (ret)
++ return ret;
++
++ if (temp & 0x80) {
++ /* manual */
++ ret = ov5640_read_reg(sensor, OV5640_REG_HZ5060_CTRL00,
++ &temp1);
++ if (ret)
++ return ret;
++ if (temp1 & 0x04) {
++ /* 50Hz */
++ light_freq = 50;
++ } else {
++ /* 60Hz */
++ light_freq = 60;
++ }
++ } else {
++ /* auto */
++ ret = ov5640_read_reg(sensor, OV5640_REG_SIGMADELTA_CTRL0C,
++ &temp1);
++ if (ret)
++ return ret;
++
++ if (temp1 & 0x01) {
++ /* 50Hz */
++ light_freq = 50;
++ } else {
++ /* 60Hz */
++ }
++ }
++
++ return light_freq;
++}
++
++static int ov5640_set_bandingfilter(struct ov5640_dev *sensor)
++{
++ u32 band_step60, max_band60, band_step50, max_band50, prev_vts;
++ int ret;
++
++ /* read preview PCLK */
++ ret = ov5640_get_sysclk(sensor);
++ if (ret < 0)
++ return ret;
++ if (ret == 0)
++ return -EINVAL;
++ sensor->prev_sysclk = ret;
++ /* read preview HTS */
++ ret = ov5640_get_hts(sensor);
++ if (ret < 0)
++ return ret;
++ if (ret == 0)
++ return -EINVAL;
++ sensor->prev_hts = ret;
++
++ /* read preview VTS */
++ ret = ov5640_get_vts(sensor);
++ if (ret < 0)
++ return ret;
++ prev_vts = ret;
++
++ /* calculate banding filter */
++ /* 60Hz */
++ band_step60 = sensor->prev_sysclk * 100 / sensor->prev_hts * 100 / 120;
++ ret = ov5640_write_reg16(sensor, OV5640_REG_AEC_B60_STEP, band_step60);
++ if (ret)
++ return ret;
++ if (!band_step60)
++ return -EINVAL;
++ max_band60 = (int)((prev_vts - 4) / band_step60);
++ ret = ov5640_write_reg(sensor, OV5640_REG_AEC_CTRL0D, max_band60);
++ if (ret)
++ return ret;
++
++ /* 50Hz */
++ band_step50 = sensor->prev_sysclk * 100 / sensor->prev_hts;
++ ret = ov5640_write_reg16(sensor, OV5640_REG_AEC_B50_STEP, band_step50);
++ if (ret)
++ return ret;
++ if (!band_step50)
++ return -EINVAL;
++ max_band50 = (int)((prev_vts - 4) / band_step50);
++ return ov5640_write_reg(sensor, OV5640_REG_AEC_CTRL0E, max_band50);
++}
++
++static int ov5640_set_ae_target(struct ov5640_dev *sensor, int target)
++{
++ /* stable in high */
++ u32 fast_high, fast_low;
++ int ret;
++
++ sensor->ae_low = target * 23 / 25; /* 0.92 */
++ sensor->ae_high = target * 27 / 25; /* 1.08 */
++
++ fast_high = sensor->ae_high << 1;
++ if (fast_high > 255)
++ fast_high = 255;
++
++ fast_low = sensor->ae_low >> 1;
++
++ ret = ov5640_write_reg(sensor, OV5640_REG_AEC_CTRL0F, sensor->ae_high);
++ if (ret)
++ return ret;
++ ret = ov5640_write_reg(sensor, OV5640_REG_AEC_CTRL10, sensor->ae_low);
++ if (ret)
++ return ret;
++ ret = ov5640_write_reg(sensor, OV5640_REG_AEC_CTRL1B, sensor->ae_high);
++ if (ret)
++ return ret;
++ ret = ov5640_write_reg(sensor, OV5640_REG_AEC_CTRL1E, sensor->ae_low);
++ if (ret)
++ return ret;
++ ret = ov5640_write_reg(sensor, OV5640_REG_AEC_CTRL11, fast_high);
++ if (ret)
++ return ret;
++ return ov5640_write_reg(sensor, OV5640_REG_AEC_CTRL1F, fast_low);
++}
++
++static int ov5640_get_binning(struct ov5640_dev *sensor)
++{
++ u8 temp;
++ int ret;
++
++ ret = ov5640_read_reg(sensor, OV5640_REG_TIMING_TC_REG21, &temp);
++ if (ret)
++ return ret;
++
++ return temp & BIT(0);
++}
++
++static int ov5640_set_binning(struct ov5640_dev *sensor, bool enable)
++{
++ int ret;
++
++ /*
++ * TIMING TC REG21:
++ * - [0]: Horizontal binning enable
++ */
++ ret = ov5640_mod_reg(sensor, OV5640_REG_TIMING_TC_REG21,
++ BIT(0), enable ? BIT(0) : 0);
++ if (ret)
++ return ret;
++ /*
++ * TIMING TC REG20:
++ * - [0]: Undocumented, but hardcoded init sequences
++ * are always setting REG21/REG20 bit 0 to same value...
++ */
++ return ov5640_mod_reg(sensor, OV5640_REG_TIMING_TC_REG20,
++ BIT(0), enable ? BIT(0) : 0);
++}
++
++static int ov5640_set_virtual_channel(struct ov5640_dev *sensor)
++{
++ struct i2c_client *client = sensor->i2c_client;
++ u8 temp, channel = virtual_channel;
++ int ret;
++
++ if (channel > 3) {
++ dev_err(&client->dev,
++ "%s: wrong virtual_channel parameter, expected (0..3), got %d\n",
++ __func__, channel);
++ return -EINVAL;
++ }
++
++ ret = ov5640_read_reg(sensor, OV5640_REG_DEBUG_MODE, &temp);
++ if (ret)
++ return ret;
++ temp &= ~(3 << 6);
++ temp |= (channel << 6);
++ return ov5640_write_reg(sensor, OV5640_REG_DEBUG_MODE, temp);
++}
++
++static const struct ov5640_mode_info *
++ov5640_find_mode(struct ov5640_dev *sensor, enum ov5640_frame_rate fr,
++ int width, int height, bool nearest)
++{
++ const struct ov5640_mode_info *mode;
++
++ mode = v4l2_find_nearest_size(ov5640_mode_data,
++ ARRAY_SIZE(ov5640_mode_data),
++ hact, vact,
++ width, height);
++
++ if (!mode ||
++ (!nearest && (mode->hact != width || mode->vact != height)))
++ return NULL;
++
++ /* Check to see if the current mode exceeds the max frame rate */
++ if (ov5640_framerates[fr] > ov5640_framerates[mode->max_fps])
++ return NULL;
++
++ return mode;
++}
++
++static u64 ov5640_calc_pixel_rate(struct ov5640_dev *sensor)
++{
++ u64 rate;
++
++ rate = sensor->current_mode->vtot * sensor->current_mode->htot;
++ rate *= ov5640_framerates[sensor->current_fr];
++
++ return rate;
++}
++
++/*
++ * sensor changes between scaling and subsampling, go through
++ * exposure calculation
++ */
++static int ov5640_set_mode_exposure_calc(struct ov5640_dev *sensor,
++ const struct ov5640_mode_info *mode)
++{
++ u32 prev_shutter, prev_gain16;
++ u32 cap_shutter, cap_gain16;
++ u32 cap_sysclk, cap_hts, cap_vts;
++ u32 light_freq, cap_bandfilt, cap_maxband;
++ u32 cap_gain16_shutter;
++ u8 average;
++ int ret;
++
++ if (!mode->reg_data)
++ return -EINVAL;
++
++ /* read preview shutter */
++ ret = ov5640_get_exposure(sensor);
++ if (ret < 0)
++ return ret;
++ prev_shutter = ret;
++ ret = ov5640_get_binning(sensor);
++ if (ret < 0)
++ return ret;
++ if (ret && mode->id != OV5640_MODE_720P_1280_720 &&
++ mode->id != OV5640_MODE_1080P_1920_1080)
++ prev_shutter *= 2;
++
++ /* read preview gain */
++ ret = ov5640_get_gain(sensor);
++ if (ret < 0)
++ return ret;
++ prev_gain16 = ret;
++
++ /* get average */
++ ret = ov5640_read_reg(sensor, OV5640_REG_AVG_READOUT, &average);
++ if (ret)
++ return ret;
++
++ /* turn off night mode for capture */
++ ret = ov5640_set_night_mode(sensor);
++ if (ret < 0)
++ return ret;
++
++ /* Write capture setting */
++ ret = ov5640_load_regs(sensor, mode);
++ if (ret < 0)
++ return ret;
++
++ /* read capture VTS */
++ ret = ov5640_get_vts(sensor);
++ if (ret < 0)
++ return ret;
++ cap_vts = ret;
++ ret = ov5640_get_hts(sensor);
++ if (ret < 0)
++ return ret;
++ if (ret == 0)
++ return -EINVAL;
++ cap_hts = ret;
++
++ ret = ov5640_get_sysclk(sensor);
++ if (ret < 0)
++ return ret;
++ if (ret == 0)
++ return -EINVAL;
++ cap_sysclk = ret;
++
++ /* calculate capture banding filter */
++ ret = ov5640_get_light_freq(sensor);
++ if (ret < 0)
++ return ret;
++ light_freq = ret;
++
++ if (light_freq == 60) {
++ /* 60Hz */
++ cap_bandfilt = cap_sysclk * 100 / cap_hts * 100 / 120;
++ } else {
++ /* 50Hz */
++ cap_bandfilt = cap_sysclk * 100 / cap_hts;
++ }
++
++ if (!sensor->prev_sysclk) {
++ ret = ov5640_get_sysclk(sensor);
++ if (ret < 0)
++ return ret;
++ if (ret == 0)
++ return -EINVAL;
++ sensor->prev_sysclk = ret;
++ }
++
++ if (!cap_bandfilt)
++ return -EINVAL;
++
++ cap_maxband = (int)((cap_vts - 4) / cap_bandfilt);
++
++ /* calculate capture shutter/gain16 */
++ if (average > sensor->ae_low && average < sensor->ae_high) {
++ /* in stable range */
++ cap_gain16_shutter =
++ prev_gain16 * prev_shutter *
++ cap_sysclk / sensor->prev_sysclk *
++ sensor->prev_hts / cap_hts *
++ sensor->ae_target / average;
++ } else {
++ cap_gain16_shutter =
++ prev_gain16 * prev_shutter *
++ cap_sysclk / sensor->prev_sysclk *
++ sensor->prev_hts / cap_hts;
++ }
++
++ /* gain to shutter */
++ if (cap_gain16_shutter < (cap_bandfilt * 16)) {
++ /* shutter < 1/100 */
++ cap_shutter = cap_gain16_shutter / 16;
++ if (cap_shutter < 1)
++ cap_shutter = 1;
++
++ cap_gain16 = cap_gain16_shutter / cap_shutter;
++ if (cap_gain16 < 16)
++ cap_gain16 = 16;
++ } else {
++ if (cap_gain16_shutter > (cap_bandfilt * cap_maxband * 16)) {
++ /* exposure reach max */
++ cap_shutter = cap_bandfilt * cap_maxband;
++ if (!cap_shutter)
++ return -EINVAL;
++
++ cap_gain16 = cap_gain16_shutter / cap_shutter;
++ } else {
++ /* 1/100 < (cap_shutter = n/100) =< max */
++ cap_shutter =
++ ((int)(cap_gain16_shutter / 16 / cap_bandfilt))
++ * cap_bandfilt;
++ if (!cap_shutter)
++ return -EINVAL;
++
++ cap_gain16 = cap_gain16_shutter / cap_shutter;
++ }
++ }
++
++ /* set capture gain */
++ ret = ov5640_set_gain(sensor, cap_gain16);
++ if (ret)
++ return ret;
++
++ /* write capture shutter */
++ if (cap_shutter > (cap_vts - 4)) {
++ cap_vts = cap_shutter + 4;
++ ret = ov5640_set_vts(sensor, cap_vts);
++ if (ret < 0)
++ return ret;
++ }
++
++ /* set exposure */
++ return ov5640_set_exposure(sensor, cap_shutter);
++}
++
++/*
++ * if sensor changes inside scaling or subsampling
++ * change mode directly
++ */
++static int ov5640_set_mode_direct(struct ov5640_dev *sensor,
++ const struct ov5640_mode_info *mode)
++{
++ if (!mode->reg_data)
++ return -EINVAL;
++
++ /* Write capture setting */
++ return ov5640_load_regs(sensor, mode);
++}
++
++static int ov5640_set_mode(struct ov5640_dev *sensor)
++{
++ const struct ov5640_mode_info *mode = sensor->current_mode;
++ const struct ov5640_mode_info *orig_mode = sensor->last_mode;
++ enum ov5640_downsize_mode dn_mode, orig_dn_mode;
++ bool auto_gain = sensor->ctrls.auto_gain->val == 1;
++ bool auto_exp = sensor->ctrls.auto_exp->val == V4L2_EXPOSURE_AUTO;
++ unsigned long rate;
++ int ret;
++
++ dn_mode = mode->dn_mode;
++ orig_dn_mode = orig_mode->dn_mode;
++
++ /* auto gain and exposure must be turned off when changing modes */
++ if (auto_gain) {
++ ret = ov5640_set_autogain(sensor, false);
++ if (ret)
++ return ret;
++ }
++
++ if (auto_exp) {
++ ret = ov5640_set_autoexposure(sensor, false);
++ if (ret)
++ goto restore_auto_gain;
++ }
++
++ /*
++ * All the formats we support have 16 bits per pixel, seems to require
++ * the same rate than YUV, so we can just use 16 bpp all the time.
++ */
++ rate = ov5640_calc_pixel_rate(sensor) * 16;
++ if (sensor->ep.bus_type == V4L2_MBUS_CSI2_DPHY) {
++ rate = rate / sensor->ep.bus.mipi_csi2.num_data_lanes;
++ ret = ov5640_set_mipi_pclk(sensor, rate);
++ } else {
++ rate = rate / sensor->ep.bus.parallel.bus_width;
++ ret = ov5640_set_dvp_pclk(sensor, rate);
++ }
++
++ if (ret < 0)
++ return 0;
++
++ if ((dn_mode == SUBSAMPLING && orig_dn_mode == SCALING) ||
++ (dn_mode == SCALING && orig_dn_mode == SUBSAMPLING)) {
++ /*
++ * change between subsampling and scaling
++ * go through exposure calculation
++ */
++ ret = ov5640_set_mode_exposure_calc(sensor, mode);
++ } else {
++ /*
++ * change inside subsampling or scaling
++ * download firmware directly
++ */
++ ret = ov5640_set_mode_direct(sensor, mode);
++ }
++ if (ret < 0)
++ goto restore_auto_exp_gain;
++
++ /* restore auto gain and exposure */
++ if (auto_gain)
++ ov5640_set_autogain(sensor, true);
++ if (auto_exp)
++ ov5640_set_autoexposure(sensor, true);
++
++ ret = ov5640_set_binning(sensor, dn_mode != SCALING);
++ if (ret < 0)
++ return ret;
++ ret = ov5640_set_ae_target(sensor, sensor->ae_target);
++ if (ret < 0)
++ return ret;
++ ret = ov5640_get_light_freq(sensor);
++ if (ret < 0)
++ return ret;
++ ret = ov5640_set_bandingfilter(sensor);
++ if (ret < 0)
++ return ret;
++ ret = ov5640_set_virtual_channel(sensor);
++ if (ret < 0)
++ return ret;
++
++ sensor->pending_mode_change = false;
++ sensor->last_mode = mode;
++
++ return 0;
++
++restore_auto_exp_gain:
++ if (auto_exp)
++ ov5640_set_autoexposure(sensor, true);
++restore_auto_gain:
++ if (auto_gain)
++ ov5640_set_autogain(sensor, true);
++
++ return ret;
++}
++
++static int ov5640_set_framefmt(struct ov5640_dev *sensor,
++ struct v4l2_mbus_framefmt *format);
++
++/* restore the last set video mode after chip power-on */
++static int ov5640_restore_mode(struct ov5640_dev *sensor)
++{
++ int ret;
++
++ /* first load the initial register values */
++ ret = ov5640_load_regs(sensor, &ov5640_mode_init_data);
++ if (ret < 0)
++ return ret;
++ sensor->last_mode = &ov5640_mode_init_data;
++
++ ret = ov5640_mod_reg(sensor, OV5640_REG_SYS_ROOT_DIVIDER, 0x3f,
++ (ilog2(OV5640_SCLK2X_ROOT_DIV) << 2) |
++ ilog2(OV5640_SCLK_ROOT_DIV));
++ if (ret)
++ return ret;
++
++ /* now restore the last capture mode */
++ ret = ov5640_set_mode(sensor);
++ if (ret < 0)
++ return ret;
++
++ return ov5640_set_framefmt(sensor, &sensor->fmt);
++}
++
++static void ov5640_power(struct ov5640_dev *sensor, bool enable)
++{
++ if (!sensor->pwdn_gpio)
++ return;
++ gpiod_set_value_cansleep(sensor->pwdn_gpio, enable ? 0 : 1);
++}
++
++static void ov5640_reset(struct ov5640_dev *sensor)
++{
++ if (!sensor->reset_gpio)
++ return;
++
++ gpiod_set_value_cansleep(sensor->reset_gpio, 0);
++
++ /* camera power cycle */
++ ov5640_power(sensor, false);
++ usleep_range(5000, 10000);
++ ov5640_power(sensor, true);
++ usleep_range(5000, 10000);
++
++ gpiod_set_value_cansleep(sensor->reset_gpio, 1);
++ usleep_range(1000, 2000);
++
++ gpiod_set_value_cansleep(sensor->reset_gpio, 0);
++ usleep_range(20000, 25000);
++}
++
++static int ov5640_set_power_on(struct ov5640_dev *sensor)
++{
++ struct i2c_client *client = sensor->i2c_client;
++ int ret;
++
++ ret = clk_prepare_enable(sensor->xclk);
++ if (ret) {
++ dev_err(&client->dev, "%s: failed to enable clock\n",
++ __func__);
++ return ret;
++ }
++
++ ret = regulator_bulk_enable(OV5640_NUM_SUPPLIES,
++ sensor->supplies);
++ if (ret) {
++ dev_err(&client->dev, "%s: failed to enable regulators\n",
++ __func__);
++ goto xclk_off;
++ }
++
++ ov5640_reset(sensor);
++ ov5640_power(sensor, true);
++
++ ret = ov5640_init_slave_id(sensor);
++ if (ret)
++ goto power_off;
++
++ return 0;
++
++power_off:
++ ov5640_power(sensor, false);
++ regulator_bulk_disable(OV5640_NUM_SUPPLIES, sensor->supplies);
++xclk_off:
++ clk_disable_unprepare(sensor->xclk);
++ return ret;
++}
++
++static void ov5640_set_power_off(struct ov5640_dev *sensor)
++{
++ ov5640_power(sensor, false);
++ regulator_bulk_disable(OV5640_NUM_SUPPLIES, sensor->supplies);
++ clk_disable_unprepare(sensor->xclk);
++}
++
++static int ov5640_set_power_mipi(struct ov5640_dev *sensor, bool on)
++{
++ int ret;
++
++ if (!on) {
++ /* Reset MIPI bus settings to their default values. */
++ ov5640_write_reg(sensor, OV5640_REG_IO_MIPI_CTRL00, 0x58);
++ ov5640_write_reg(sensor, OV5640_REG_MIPI_CTRL00, 0x04);
++ ov5640_write_reg(sensor, OV5640_REG_PAD_OUTPUT00, 0x00);
++ return 0;
++ }
++
++ /*
++ * Power up MIPI HS Tx and LS Rx; 2 data lanes mode
++ *
++ * 0x300e = 0x40
++ * [7:5] = 010 : 2 data lanes mode (see FIXME note in
++ * "ov5640_set_stream_mipi()")
++ * [4] = 0 : Power up MIPI HS Tx
++ * [3] = 0 : Power up MIPI LS Rx
++ * [2] = 0 : MIPI interface disabled
++ */
++ ret = ov5640_write_reg(sensor, OV5640_REG_IO_MIPI_CTRL00, 0x40);
++ if (ret)
++ return ret;
++
++ /*
++ * Gate clock and set LP11 in 'no packets mode' (idle)
++ *
++ * 0x4800 = 0x24
++ * [5] = 1 : Gate clock when 'no packets'
++ * [2] = 1 : MIPI bus in LP11 when 'no packets'
++ */
++ ret = ov5640_write_reg(sensor, OV5640_REG_MIPI_CTRL00, 0x24);
++ if (ret)
++ return ret;
++
++ /*
++ * Set data lanes and clock in LP11 when 'sleeping'
++ *
++ * 0x3019 = 0x70
++ * [6] = 1 : MIPI data lane 2 in LP11 when 'sleeping'
++ * [5] = 1 : MIPI data lane 1 in LP11 when 'sleeping'
++ * [4] = 1 : MIPI clock lane in LP11 when 'sleeping'
++ */
++ ret = ov5640_write_reg(sensor, OV5640_REG_PAD_OUTPUT00, 0x70);
++ if (ret)
++ return ret;
++
++ /* Give lanes some time to coax into LP11 state. */
++ usleep_range(500, 1000);
++
++ return 0;
++}
++
++static int ov5640_set_power_dvp(struct ov5640_dev *sensor, bool on)
++{
++ unsigned int flags = sensor->ep.bus.parallel.flags;
++ bool bt656 = sensor->ep.bus_type == V4L2_MBUS_BT656;
++ u8 polarities = 0;
++ int ret;
++
++ if (!on) {
++ /* Reset settings to their default values. */
++ ov5640_write_reg(sensor, OV5640_REG_CCIR656_CTRL00, 0x00);
++ ov5640_write_reg(sensor, OV5640_REG_IO_MIPI_CTRL00, 0x58);
++ ov5640_write_reg(sensor, OV5640_REG_POLARITY_CTRL00, 0x20);
++ ov5640_write_reg(sensor, OV5640_REG_PAD_OUTPUT_ENABLE01, 0x00);
++ ov5640_write_reg(sensor, OV5640_REG_PAD_OUTPUT_ENABLE02, 0x00);
++ return 0;
++ }
++
++ /*
++ * Note about parallel port configuration.
++ *
++ * When configured in parallel mode, the OV5640 will
++ * output 10 bits data on DVP data lines [9:0].
++ * If only 8 bits data are wanted, the 8 bits data lines
++ * of the camera interface must be physically connected
++ * on the DVP data lines [9:2].
++ *
++ * Control lines polarity can be configured through
++ * devicetree endpoint control lines properties.
++ * If no endpoint control lines properties are set,
++ * polarity will be as below:
++ * - VSYNC: active high
++ * - HREF: active low
++ * - PCLK: active low
++ *
++ * VSYNC & HREF are not configured if BT656 bus mode is selected
++ */
++
++ /*
++ * BT656 embedded synchronization configuration
++ *
++ * CCIR656 CTRL00
++ * - [7]: SYNC code selection (0: auto generate sync code,
++ * 1: sync code from regs 0x4732-0x4735)
++ * - [6]: f value in CCIR656 SYNC code when fixed f value
++ * - [5]: Fixed f value
++ * - [4:3]: Blank toggle data options (00: data=1'h040/1'h200,
++ * 01: data from regs 0x4736-0x4738, 10: always keep 0)
++ * - [1]: Clip data disable
++ * - [0]: CCIR656 mode enable
++ *
++ * Default CCIR656 SAV/EAV mode with default codes
++ * SAV=0xff000080 & EAV=0xff00009d is enabled here with settings:
++ * - CCIR656 mode enable
++ * - auto generation of sync codes
++ * - blank toggle data 1'h040/1'h200
++ * - clip reserved data (0x00 & 0xff changed to 0x01 & 0xfe)
++ */
++ ret = ov5640_write_reg(sensor, OV5640_REG_CCIR656_CTRL00,
++ bt656 ? 0x01 : 0x00);
++ if (ret)
++ return ret;
++
++ /*
++ * configure parallel port control lines polarity
++ *
++ * POLARITY CTRL0
++ * - [5]: PCLK polarity (0: active low, 1: active high)
++ * - [1]: HREF polarity (0: active low, 1: active high)
++ * - [0]: VSYNC polarity (mismatch here between
++ * datasheet and hardware, 0 is active high
++ * and 1 is active low...)
++ */
++ if (!bt656) {
++ if (flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH)
++ polarities |= BIT(1);
++ if (flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
++ polarities |= BIT(0);
++ }
++ if (flags & V4L2_MBUS_PCLK_SAMPLE_RISING)
++ polarities |= BIT(5);
++
++ ret = ov5640_write_reg(sensor, OV5640_REG_POLARITY_CTRL00, polarities);
++ if (ret)
++ return ret;
++
++ /*
++ * powerdown MIPI TX/RX PHY & enable DVP
++ *
++ * MIPI CONTROL 00
++ * [4] = 1 : Power down MIPI HS Tx
++ * [3] = 1 : Power down MIPI LS Rx
++ * [2] = 0 : DVP enable (MIPI disable)
++ */
++ ret = ov5640_write_reg(sensor, OV5640_REG_IO_MIPI_CTRL00, 0x58);
++ if (ret)
++ return ret;
++
++ /*
++ * enable VSYNC/HREF/PCLK DVP control lines
++ * & D[9:6] DVP data lines
++ *
++ * PAD OUTPUT ENABLE 01
++ * - 6: VSYNC output enable
++ * - 5: HREF output enable
++ * - 4: PCLK output enable
++ * - [3:0]: D[9:6] output enable
++ */
++ ret = ov5640_write_reg(sensor, OV5640_REG_PAD_OUTPUT_ENABLE01,
++ bt656 ? 0x1f : 0x7f);
++ if (ret)
++ return ret;
++
++ /*
++ * enable D[5:0] DVP data lines
++ *
++ * PAD OUTPUT ENABLE 02
++ * - [7:2]: D[5:0] output enable
++ */
++ return ov5640_write_reg(sensor, OV5640_REG_PAD_OUTPUT_ENABLE02, 0xfc);
++}
++
++static int ov5640_set_power(struct ov5640_dev *sensor, bool on)
++{
++ int ret = 0;
++
++ if (on) {
++ ret = ov5640_set_power_on(sensor);
++ if (ret)
++ return ret;
++
++ ret = ov5640_restore_mode(sensor);
++ if (ret)
++ goto power_off;
++ }
++
++ if (sensor->ep.bus_type == V4L2_MBUS_CSI2_DPHY)
++ ret = ov5640_set_power_mipi(sensor, on);
++ else
++ ret = ov5640_set_power_dvp(sensor, on);
++ if (ret)
++ goto power_off;
++
++ if (!on)
++ ov5640_set_power_off(sensor);
++
++ return 0;
++
++power_off:
++ ov5640_set_power_off(sensor);
++ return ret;
++}
++
++/* --------------- Subdev Operations --------------- */
++
++static int ov5640_s_power(struct v4l2_subdev *sd, int on)
++{
++ struct ov5640_dev *sensor = to_ov5640_dev(sd);
++ int ret = 0;
++
++ mutex_lock(&sensor->lock);
++
++ /*
++ * If the power count is modified from 0 to != 0 or from != 0 to 0,
++ * update the power state.
++ */
++ if (sensor->power_count == !on) {
++ ret = ov5640_set_power(sensor, !!on);
++ if (ret)
++ goto out;
++ }
++
++ /* Update the power count. */
++ sensor->power_count += on ? 1 : -1;
++ WARN_ON(sensor->power_count < 0);
++out:
++ mutex_unlock(&sensor->lock);
++
++ if (on && !ret && sensor->power_count == 1) {
++ /* restore controls */
++ ret = v4l2_ctrl_handler_setup(&sensor->ctrls.handler);
++ }
++
++ return ret;
++}
++
++static int ov5640_try_frame_interval(struct ov5640_dev *sensor,
++ struct v4l2_fract *fi,
++ u32 width, u32 height)
++{
++ const struct ov5640_mode_info *mode;
++ enum ov5640_frame_rate rate = OV5640_15_FPS;
++ int minfps, maxfps, best_fps, fps;
++ int i;
++
++ minfps = ov5640_framerates[OV5640_15_FPS];
++ maxfps = ov5640_framerates[OV5640_60_FPS];
++
++ if (fi->numerator == 0) {
++ fi->denominator = maxfps;
++ fi->numerator = 1;
++ rate = OV5640_60_FPS;
++ goto find_mode;
++ }
++
++ fps = clamp_val(DIV_ROUND_CLOSEST(fi->denominator, fi->numerator),
++ minfps, maxfps);
++
++ best_fps = minfps;
++ for (i = 0; i < ARRAY_SIZE(ov5640_framerates); i++) {
++ int curr_fps = ov5640_framerates[i];
++
++ if (abs(curr_fps - fps) < abs(best_fps - fps)) {
++ best_fps = curr_fps;
++ rate = i;
++ }
++ }
++
++ fi->numerator = 1;
++ fi->denominator = best_fps;
++
++find_mode:
++ mode = ov5640_find_mode(sensor, rate, width, height, false);
++ return mode ? rate : -EINVAL;
++}
++
++static int ov5640_get_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_format *format)
++{
++ struct ov5640_dev *sensor = to_ov5640_dev(sd);
++ struct v4l2_mbus_framefmt *fmt;
++
++ if (format->pad != 0)
++ return -EINVAL;
++
++ mutex_lock(&sensor->lock);
++
++ if (format->which == V4L2_SUBDEV_FORMAT_TRY)
++ fmt = v4l2_subdev_get_try_format(&sensor->sd, state,
++ format->pad);
++ else
++ fmt = &sensor->fmt;
++
++ format->format = *fmt;
++
++ mutex_unlock(&sensor->lock);
++
++ return 0;
++}
++
++static int ov5640_try_fmt_internal(struct v4l2_subdev *sd,
++ struct v4l2_mbus_framefmt *fmt,
++ enum ov5640_frame_rate fr,
++ const struct ov5640_mode_info **new_mode)
++{
++ struct ov5640_dev *sensor = to_ov5640_dev(sd);
++ const struct ov5640_mode_info *mode;
++ int i;
++
++ mode = ov5640_find_mode(sensor, fr, fmt->width, fmt->height, true);
++ if (!mode)
++ return -EINVAL;
++ fmt->width = mode->hact;
++ fmt->height = mode->vact;
++
++ if (new_mode)
++ *new_mode = mode;
++
++ for (i = 0; i < ARRAY_SIZE(ov5640_formats); i++)
++ if (ov5640_formats[i].code == fmt->code)
++ break;
++ if (i >= ARRAY_SIZE(ov5640_formats))
++ i = 0;
++
++ fmt->code = ov5640_formats[i].code;
++ fmt->colorspace = ov5640_formats[i].colorspace;
++ fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->colorspace);
++ fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE;
++ fmt->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(fmt->colorspace);
++
++ return 0;
++}
++
++static int ov5640_set_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_format *format)
++{
++ struct ov5640_dev *sensor = to_ov5640_dev(sd);
++ const struct ov5640_mode_info *new_mode;
++ struct v4l2_mbus_framefmt *mbus_fmt = &format->format;
++ struct v4l2_mbus_framefmt *fmt;
++ int ret;
++
++ if (format->pad != 0)
++ return -EINVAL;
++
++ mutex_lock(&sensor->lock);
++
++ if (sensor->streaming) {
++ ret = -EBUSY;
++ goto out;
++ }
++
++ ret = ov5640_try_fmt_internal(sd, mbus_fmt, 0, &new_mode);
++ if (ret)
++ goto out;
++
++ if (format->which == V4L2_SUBDEV_FORMAT_TRY)
++ fmt = v4l2_subdev_get_try_format(sd, state, 0);
++ else
++ fmt = &sensor->fmt;
++
++ if (mbus_fmt->code != sensor->fmt.code)
++ sensor->pending_fmt_change = true;
++
++ *fmt = *mbus_fmt;
++
++ if (new_mode != sensor->current_mode) {
++ sensor->current_mode = new_mode;
++ sensor->pending_mode_change = true;
++ }
++ if (new_mode->max_fps < sensor->current_fr) {
++ sensor->current_fr = new_mode->max_fps;
++ sensor->frame_interval.numerator = 1;
++ sensor->frame_interval.denominator =
++ ov5640_framerates[sensor->current_fr];
++ sensor->current_mode = new_mode;
++ sensor->pending_mode_change = true;
++ }
++
++ __v4l2_ctrl_s_ctrl_int64(sensor->ctrls.pixel_rate,
++ ov5640_calc_pixel_rate(sensor));
++out:
++ mutex_unlock(&sensor->lock);
++ return ret;
++}
++
++static int ov5640_set_framefmt(struct ov5640_dev *sensor,
++ struct v4l2_mbus_framefmt *format)
++{
++ int ret = 0;
++ bool is_jpeg = false;
++ u8 fmt, mux;
++
++ switch (format->code) {
++ case MEDIA_BUS_FMT_UYVY8_2X8:
++ /* YUV422, UYVY */
++ fmt = 0x3f;
++ mux = OV5640_FMT_MUX_YUV422;
++ break;
++ case MEDIA_BUS_FMT_YUYV8_2X8:
++ /* YUV422, YUYV */
++ fmt = 0x30;
++ mux = OV5640_FMT_MUX_YUV422;
++ break;
++ case MEDIA_BUS_FMT_RGB565_2X8_LE:
++ /* RGB565 {g[2:0],b[4:0]},{r[4:0],g[5:3]} */
++ fmt = 0x6F;
++ mux = OV5640_FMT_MUX_RGB;
++ break;
++ case MEDIA_BUS_FMT_RGB565_2X8_BE:
++ /* RGB565 {r[4:0],g[5:3]},{g[2:0],b[4:0]} */
++ fmt = 0x61;
++ mux = OV5640_FMT_MUX_RGB;
++ break;
++ case MEDIA_BUS_FMT_JPEG_1X8:
++ /* YUV422, YUYV */
++ fmt = 0x30;
++ mux = OV5640_FMT_MUX_YUV422;
++ is_jpeg = true;
++ break;
++ case MEDIA_BUS_FMT_SBGGR8_1X8:
++ /* Raw, BGBG... / GRGR... */
++ fmt = 0x00;
++ mux = OV5640_FMT_MUX_RAW_DPC;
++ break;
++ case MEDIA_BUS_FMT_SGBRG8_1X8:
++ /* Raw bayer, GBGB... / RGRG... */
++ fmt = 0x01;
++ mux = OV5640_FMT_MUX_RAW_DPC;
++ break;
++ case MEDIA_BUS_FMT_SGRBG8_1X8:
++ /* Raw bayer, GRGR... / BGBG... */
++ fmt = 0x02;
++ mux = OV5640_FMT_MUX_RAW_DPC;
++ break;
++ case MEDIA_BUS_FMT_SRGGB8_1X8:
++ /* Raw bayer, RGRG... / GBGB... */
++ fmt = 0x03;
++ mux = OV5640_FMT_MUX_RAW_DPC;
++ break;
++ default:
++ return -EINVAL;
++ }
++
++ /* FORMAT CONTROL00: YUV and RGB formatting */
++ ret = ov5640_write_reg(sensor, OV5640_REG_FORMAT_CONTROL00, fmt);
++ if (ret)
++ return ret;
++
++ /* FORMAT MUX CONTROL: ISP YUV or RGB */
++ ret = ov5640_write_reg(sensor, OV5640_REG_ISP_FORMAT_MUX_CTRL, mux);
++ if (ret)
++ return ret;
++
++ /*
++ * TIMING TC REG21:
++ * - [5]: JPEG enable
++ */
++ ret = ov5640_mod_reg(sensor, OV5640_REG_TIMING_TC_REG21,
++ BIT(5), is_jpeg ? BIT(5) : 0);
++ if (ret)
++ return ret;
++
++ /*
++ * SYSTEM RESET02:
++ * - [4]: Reset JFIFO
++ * - [3]: Reset SFIFO
++ * - [2]: Reset JPEG
++ */
++ ret = ov5640_mod_reg(sensor, OV5640_REG_SYS_RESET02,
++ BIT(4) | BIT(3) | BIT(2),
++ is_jpeg ? 0 : (BIT(4) | BIT(3) | BIT(2)));
++ if (ret)
++ return ret;
++
++ /*
++ * CLOCK ENABLE02:
++ * - [5]: Enable JPEG 2x clock
++ * - [3]: Enable JPEG clock
++ */
++ return ov5640_mod_reg(sensor, OV5640_REG_SYS_CLOCK_ENABLE02,
++ BIT(5) | BIT(3),
++ is_jpeg ? (BIT(5) | BIT(3)) : 0);
++}
++
++/*
++ * Sensor Controls.
++ */
++
++static int ov5640_set_ctrl_hue(struct ov5640_dev *sensor, int value)
++{
++ int ret;
++
++ if (value) {
++ ret = ov5640_mod_reg(sensor, OV5640_REG_SDE_CTRL0,
++ BIT(0), BIT(0));
++ if (ret)
++ return ret;
++ ret = ov5640_write_reg16(sensor, OV5640_REG_SDE_CTRL1, value);
++ } else {
++ ret = ov5640_mod_reg(sensor, OV5640_REG_SDE_CTRL0, BIT(0), 0);
++ }
++
++ return ret;
++}
++
++static int ov5640_set_ctrl_contrast(struct ov5640_dev *sensor, int value)
++{
++ int ret;
++
++ if (value) {
++ ret = ov5640_mod_reg(sensor, OV5640_REG_SDE_CTRL0,
++ BIT(2), BIT(2));
++ if (ret)
++ return ret;
++ ret = ov5640_write_reg(sensor, OV5640_REG_SDE_CTRL5,
++ value & 0xff);
++ } else {
++ ret = ov5640_mod_reg(sensor, OV5640_REG_SDE_CTRL0, BIT(2), 0);
++ }
++
++ return ret;
++}
++
++static int ov5640_set_ctrl_saturation(struct ov5640_dev *sensor, int value)
++{
++ int ret;
++
++ if (value) {
++ ret = ov5640_mod_reg(sensor, OV5640_REG_SDE_CTRL0,
++ BIT(1), BIT(1));
++ if (ret)
++ return ret;
++ ret = ov5640_write_reg(sensor, OV5640_REG_SDE_CTRL3,
++ value & 0xff);
++ if (ret)
++ return ret;
++ ret = ov5640_write_reg(sensor, OV5640_REG_SDE_CTRL4,
++ value & 0xff);
++ } else {
++ ret = ov5640_mod_reg(sensor, OV5640_REG_SDE_CTRL0, BIT(1), 0);
++ }
++
++ return ret;
++}
++
++static int ov5640_set_ctrl_white_balance(struct ov5640_dev *sensor, int awb)
++{
++ int ret;
++
++ ret = ov5640_mod_reg(sensor, OV5640_REG_AWB_MANUAL_CTRL,
++ BIT(0), awb ? 0 : 1);
++ if (ret)
++ return ret;
++
++ if (!awb) {
++ u16 red = (u16)sensor->ctrls.red_balance->val;
++ u16 blue = (u16)sensor->ctrls.blue_balance->val;
++
++ ret = ov5640_write_reg16(sensor, OV5640_REG_AWB_R_GAIN, red);
++ if (ret)
++ return ret;
++ ret = ov5640_write_reg16(sensor, OV5640_REG_AWB_B_GAIN, blue);
++ }
++
++ return ret;
++}
++
++static int ov5640_set_ctrl_exposure(struct ov5640_dev *sensor,
++ enum v4l2_exposure_auto_type auto_exposure)
++{
++ struct ov5640_ctrls *ctrls = &sensor->ctrls;
++ bool auto_exp = (auto_exposure == V4L2_EXPOSURE_AUTO);
++ int ret = 0;
++
++ if (ctrls->auto_exp->is_new) {
++ ret = ov5640_set_autoexposure(sensor, auto_exp);
++ if (ret)
++ return ret;
++ }
++
++ if (!auto_exp && ctrls->exposure->is_new) {
++ u16 max_exp;
++
++ ret = ov5640_read_reg16(sensor, OV5640_REG_AEC_PK_VTS,
++ &max_exp);
++ if (ret)
++ return ret;
++ ret = ov5640_get_vts(sensor);
++ if (ret < 0)
++ return ret;
++ max_exp += ret;
++ ret = 0;
++
++ if (ctrls->exposure->val < max_exp)
++ ret = ov5640_set_exposure(sensor, ctrls->exposure->val);
++ }
++
++ return ret;
++}
++
++static int ov5640_set_ctrl_gain(struct ov5640_dev *sensor, bool auto_gain)
++{
++ struct ov5640_ctrls *ctrls = &sensor->ctrls;
++ int ret = 0;
++
++ if (ctrls->auto_gain->is_new) {
++ ret = ov5640_set_autogain(sensor, auto_gain);
++ if (ret)
++ return ret;
++ }
++
++ if (!auto_gain && ctrls->gain->is_new)
++ ret = ov5640_set_gain(sensor, ctrls->gain->val);
++
++ return ret;
++}
++
++static const char * const test_pattern_menu[] = {
++ "Disabled",
++ "Color bars",
++ "Color bars w/ rolling bar",
++ "Color squares",
++ "Color squares w/ rolling bar",
++};
++
++#define OV5640_TEST_ENABLE BIT(7)
++#define OV5640_TEST_ROLLING BIT(6) /* rolling horizontal bar */
++#define OV5640_TEST_TRANSPARENT BIT(5)
++#define OV5640_TEST_SQUARE_BW BIT(4) /* black & white squares */
++#define OV5640_TEST_BAR_STANDARD (0 << 2)
++#define OV5640_TEST_BAR_VERT_CHANGE_1 (1 << 2)
++#define OV5640_TEST_BAR_HOR_CHANGE (2 << 2)
++#define OV5640_TEST_BAR_VERT_CHANGE_2 (3 << 2)
++#define OV5640_TEST_BAR (0 << 0)
++#define OV5640_TEST_RANDOM (1 << 0)
++#define OV5640_TEST_SQUARE (2 << 0)
++#define OV5640_TEST_BLACK (3 << 0)
++
++static const u8 test_pattern_val[] = {
++ 0,
++ OV5640_TEST_ENABLE | OV5640_TEST_BAR_VERT_CHANGE_1 |
++ OV5640_TEST_BAR,
++ OV5640_TEST_ENABLE | OV5640_TEST_ROLLING |
++ OV5640_TEST_BAR_VERT_CHANGE_1 | OV5640_TEST_BAR,
++ OV5640_TEST_ENABLE | OV5640_TEST_SQUARE,
++ OV5640_TEST_ENABLE | OV5640_TEST_ROLLING | OV5640_TEST_SQUARE,
++};
++
++static int ov5640_set_ctrl_test_pattern(struct ov5640_dev *sensor, int value)
++{
++ return ov5640_write_reg(sensor, OV5640_REG_PRE_ISP_TEST_SET1,
++ test_pattern_val[value]);
++}
++
++static int ov5640_set_ctrl_light_freq(struct ov5640_dev *sensor, int value)
++{
++ int ret;
++
++ ret = ov5640_mod_reg(sensor, OV5640_REG_HZ5060_CTRL01, BIT(7),
++ (value == V4L2_CID_POWER_LINE_FREQUENCY_AUTO) ?
++ 0 : BIT(7));
++ if (ret)
++ return ret;
++
++ return ov5640_mod_reg(sensor, OV5640_REG_HZ5060_CTRL00, BIT(2),
++ (value == V4L2_CID_POWER_LINE_FREQUENCY_50HZ) ?
++ BIT(2) : 0);
++}
++
++static int ov5640_set_ctrl_hflip(struct ov5640_dev *sensor, int value)
++{
++ /*
++ * If sensor is mounted upside down, mirror logic is inversed.
++ *
++ * Sensor is a BSI (Back Side Illuminated) one,
++ * so image captured is physically mirrored.
++ * This is why mirror logic is inversed in
++ * order to cancel this mirror effect.
++ */
++
++ /*
++ * TIMING TC REG21:
++ * - [2]: ISP mirror
++ * - [1]: Sensor mirror
++ */
++ return ov5640_mod_reg(sensor, OV5640_REG_TIMING_TC_REG21,
++ BIT(2) | BIT(1),
++ (!(value ^ sensor->upside_down)) ?
++ (BIT(2) | BIT(1)) : 0);
++}
++
++static int ov5640_set_ctrl_vflip(struct ov5640_dev *sensor, int value)
++{
++ /* If sensor is mounted upside down, flip logic is inversed */
++
++ /*
++ * TIMING TC REG20:
++ * - [2]: ISP vflip
++ * - [1]: Sensor vflip
++ */
++ return ov5640_mod_reg(sensor, OV5640_REG_TIMING_TC_REG20,
++ BIT(2) | BIT(1),
++ (value ^ sensor->upside_down) ?
++ (BIT(2) | BIT(1)) : 0);
++}
++
++static int ov5640_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
++{
++ struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
++ struct ov5640_dev *sensor = to_ov5640_dev(sd);
++ int val;
++
++ /* v4l2_ctrl_lock() locks our own mutex */
++
++ switch (ctrl->id) {
++ case V4L2_CID_AUTOGAIN:
++ val = ov5640_get_gain(sensor);
++ if (val < 0)
++ return val;
++ sensor->ctrls.gain->val = val;
++ break;
++ case V4L2_CID_EXPOSURE_AUTO:
++ val = ov5640_get_exposure(sensor);
++ if (val < 0)
++ return val;
++ sensor->ctrls.exposure->val = val;
++ break;
++ }
++
++ return 0;
++}
++
++static int ov5640_s_ctrl(struct v4l2_ctrl *ctrl)
++{
++ struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
++ struct ov5640_dev *sensor = to_ov5640_dev(sd);
++ int ret;
++
++ /* v4l2_ctrl_lock() locks our own mutex */
++
++ /*
++ * If the device is not powered up by the host driver do
++ * not apply any controls to H/W at this time. Instead
++ * the controls will be restored right after power-up.
++ */
++ if (sensor->power_count == 0)
++ return 0;
++
++ switch (ctrl->id) {
++ case V4L2_CID_AUTOGAIN:
++ ret = ov5640_set_ctrl_gain(sensor, ctrl->val);
++ break;
++ case V4L2_CID_EXPOSURE_AUTO:
++ ret = ov5640_set_ctrl_exposure(sensor, ctrl->val);
++ break;
++ case V4L2_CID_AUTO_WHITE_BALANCE:
++ ret = ov5640_set_ctrl_white_balance(sensor, ctrl->val);
++ break;
++ case V4L2_CID_HUE:
++ ret = ov5640_set_ctrl_hue(sensor, ctrl->val);
++ break;
++ case V4L2_CID_CONTRAST:
++ ret = ov5640_set_ctrl_contrast(sensor, ctrl->val);
++ break;
++ case V4L2_CID_SATURATION:
++ ret = ov5640_set_ctrl_saturation(sensor, ctrl->val);
++ break;
++ case V4L2_CID_TEST_PATTERN:
++ ret = ov5640_set_ctrl_test_pattern(sensor, ctrl->val);
++ break;
++ case V4L2_CID_POWER_LINE_FREQUENCY:
++ ret = ov5640_set_ctrl_light_freq(sensor, ctrl->val);
++ break;
++ case V4L2_CID_HFLIP:
++ ret = ov5640_set_ctrl_hflip(sensor, ctrl->val);
++ break;
++ case V4L2_CID_VFLIP:
++ ret = ov5640_set_ctrl_vflip(sensor, ctrl->val);
++ break;
++ default:
++ ret = -EINVAL;
++ break;
++ }
++
++ return ret;
++}
++
++static const struct v4l2_ctrl_ops ov5640_ctrl_ops = {
++ .g_volatile_ctrl = ov5640_g_volatile_ctrl,
++ .s_ctrl = ov5640_s_ctrl,
++};
++
++static int ov5640_init_controls(struct ov5640_dev *sensor)
++{
++ const struct v4l2_ctrl_ops *ops = &ov5640_ctrl_ops;
++ struct ov5640_ctrls *ctrls = &sensor->ctrls;
++ struct v4l2_ctrl_handler *hdl = &ctrls->handler;
++ int ret;
++
++ v4l2_ctrl_handler_init(hdl, 32);
++
++ /* we can use our own mutex for the ctrl lock */
++ hdl->lock = &sensor->lock;
++
++ /* Clock related controls */
++ ctrls->pixel_rate = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_PIXEL_RATE,
++ 0, INT_MAX, 1,
++ ov5640_calc_pixel_rate(sensor));
++
++ /* Auto/manual white balance */
++ ctrls->auto_wb = v4l2_ctrl_new_std(hdl, ops,
++ V4L2_CID_AUTO_WHITE_BALANCE,
++ 0, 1, 1, 1);
++ ctrls->blue_balance = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_BLUE_BALANCE,
++ 0, 4095, 1, 0);
++ ctrls->red_balance = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_RED_BALANCE,
++ 0, 4095, 1, 0);
++ /* Auto/manual exposure */
++ ctrls->auto_exp = v4l2_ctrl_new_std_menu(hdl, ops,
++ V4L2_CID_EXPOSURE_AUTO,
++ V4L2_EXPOSURE_MANUAL, 0,
++ V4L2_EXPOSURE_AUTO);
++ ctrls->exposure = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_EXPOSURE,
++ 0, 65535, 1, 0);
++ /* Auto/manual gain */
++ ctrls->auto_gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_AUTOGAIN,
++ 0, 1, 1, 1);
++ ctrls->gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAIN,
++ 0, 1023, 1, 0);
++
++ ctrls->saturation = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_SATURATION,
++ 0, 255, 1, 64);
++ ctrls->hue = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_HUE,
++ 0, 359, 1, 0);
++ ctrls->contrast = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_CONTRAST,
++ 0, 255, 1, 0);
++ ctrls->test_pattern =
++ v4l2_ctrl_new_std_menu_items(hdl, ops, V4L2_CID_TEST_PATTERN,
++ ARRAY_SIZE(test_pattern_menu) - 1,
++ 0, 0, test_pattern_menu);
++ ctrls->hflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_HFLIP,
++ 0, 1, 1, 0);
++ ctrls->vflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_VFLIP,
++ 0, 1, 1, 0);
++
++ ctrls->light_freq =
++ v4l2_ctrl_new_std_menu(hdl, ops,
++ V4L2_CID_POWER_LINE_FREQUENCY,
++ V4L2_CID_POWER_LINE_FREQUENCY_AUTO, 0,
++ V4L2_CID_POWER_LINE_FREQUENCY_50HZ);
++
++ if (hdl->error) {
++ ret = hdl->error;
++ goto free_ctrls;
++ }
++
++ ctrls->pixel_rate->flags |= V4L2_CTRL_FLAG_READ_ONLY;
++ ctrls->gain->flags |= V4L2_CTRL_FLAG_VOLATILE;
++ ctrls->exposure->flags |= V4L2_CTRL_FLAG_VOLATILE;
++
++ v4l2_ctrl_auto_cluster(3, &ctrls->auto_wb, 0, false);
++ v4l2_ctrl_auto_cluster(2, &ctrls->auto_gain, 0, true);
++ v4l2_ctrl_auto_cluster(2, &ctrls->auto_exp, 1, true);
++
++ sensor->sd.ctrl_handler = hdl;
++ return 0;
++
++free_ctrls:
++ v4l2_ctrl_handler_free(hdl);
++ return ret;
++}
++
++static int ov5640_enum_frame_size(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_frame_size_enum *fse)
++{
++ if (fse->pad != 0)
++ return -EINVAL;
++ if (fse->index >= OV5640_NUM_MODES)
++ return -EINVAL;
++
++ fse->min_width =
++ ov5640_mode_data[fse->index].hact;
++ fse->max_width = fse->min_width;
++ fse->min_height =
++ ov5640_mode_data[fse->index].vact;
++ fse->max_height = fse->min_height;
++
++ return 0;
++}
++
++static int ov5640_enum_frame_interval(
++ struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_frame_interval_enum *fie)
++{
++ struct ov5640_dev *sensor = to_ov5640_dev(sd);
++ struct v4l2_fract tpf;
++ int ret;
++
++ if (fie->pad != 0)
++ return -EINVAL;
++ if (fie->index >= OV5640_NUM_FRAMERATES)
++ return -EINVAL;
++
++ tpf.numerator = 1;
++ tpf.denominator = ov5640_framerates[fie->index];
++
++ ret = ov5640_try_frame_interval(sensor, &tpf,
++ fie->width, fie->height);
++ if (ret < 0)
++ return -EINVAL;
++
++ fie->interval = tpf;
++ return 0;
++}
++
++static int ov5640_g_frame_interval(struct v4l2_subdev *sd,
++ struct v4l2_subdev_frame_interval *fi)
++{
++ struct ov5640_dev *sensor = to_ov5640_dev(sd);
++
++ mutex_lock(&sensor->lock);
++ fi->interval = sensor->frame_interval;
++ mutex_unlock(&sensor->lock);
++
++ return 0;
++}
++
++static int ov5640_s_frame_interval(struct v4l2_subdev *sd,
++ struct v4l2_subdev_frame_interval *fi)
++{
++ struct ov5640_dev *sensor = to_ov5640_dev(sd);
++ const struct ov5640_mode_info *mode;
++ int frame_rate, ret = 0;
++
++ if (fi->pad != 0)
++ return -EINVAL;
++
++ mutex_lock(&sensor->lock);
++
++ if (sensor->streaming) {
++ ret = -EBUSY;
++ goto out;
++ }
++
++ mode = sensor->current_mode;
++
++ frame_rate = ov5640_try_frame_interval(sensor, &fi->interval,
++ mode->hact, mode->vact);
++ if (frame_rate < 0) {
++ /* Always return a valid frame interval value */
++ fi->interval = sensor->frame_interval;
++ goto out;
++ }
++
++ mode = ov5640_find_mode(sensor, frame_rate, mode->hact,
++ mode->vact, true);
++ if (!mode) {
++ ret = -EINVAL;
++ goto out;
++ }
++
++ if (mode != sensor->current_mode ||
++ frame_rate != sensor->current_fr) {
++ sensor->current_fr = frame_rate;
++ sensor->frame_interval = fi->interval;
++ sensor->current_mode = mode;
++ sensor->pending_mode_change = true;
++
++ __v4l2_ctrl_s_ctrl_int64(sensor->ctrls.pixel_rate,
++ ov5640_calc_pixel_rate(sensor));
++ }
++out:
++ mutex_unlock(&sensor->lock);
++ return ret;
++}
++
++static int ov5640_enum_mbus_code(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_mbus_code_enum *code)
++{
++ if (code->pad != 0)
++ return -EINVAL;
++ if (code->index >= ARRAY_SIZE(ov5640_formats))
++ return -EINVAL;
++
++ code->code = ov5640_formats[code->index].code;
++ return 0;
++}
++
++static int ov5640_s_stream(struct v4l2_subdev *sd, int enable)
++{
++ struct ov5640_dev *sensor = to_ov5640_dev(sd);
++ int ret = 0;
++
++ mutex_lock(&sensor->lock);
++
++ if (sensor->streaming == !enable) {
++ if (enable && sensor->pending_mode_change) {
++ ret = ov5640_set_mode(sensor);
++ if (ret)
++ goto out;
++ }
++
++ if (enable && sensor->pending_fmt_change) {
++ ret = ov5640_set_framefmt(sensor, &sensor->fmt);
++ if (ret)
++ goto out;
++ sensor->pending_fmt_change = false;
++ }
++
++ if (sensor->ep.bus_type == V4L2_MBUS_CSI2_DPHY)
++ ret = ov5640_set_stream_mipi(sensor, enable);
++ else
++ ret = ov5640_set_stream_dvp(sensor, enable);
++
++ if (ret)
++ goto out;
++ }
++ sensor->streaming += enable ? 1 : -1;
++ WARN_ON(sensor->streaming < 0);
++out:
++ mutex_unlock(&sensor->lock);
++ return ret;
++}
++
++int ov5640_skip_frames(struct v4l2_subdev *sd, u32 *frames)
++{
++ *frames = OV5640_SKIP_FRAMES;
++ return 0;
++}
++
++static const struct v4l2_subdev_core_ops ov5640_core_ops = {
++ .s_power = ov5640_s_power,
++ .log_status = v4l2_ctrl_subdev_log_status,
++ .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
++ .unsubscribe_event = v4l2_event_subdev_unsubscribe,
++};
++
++static const struct v4l2_subdev_video_ops ov5640_video_ops = {
++ .g_frame_interval = ov5640_g_frame_interval,
++ .s_frame_interval = ov5640_s_frame_interval,
++ .s_stream = ov5640_s_stream,
++};
++
++static const struct v4l2_subdev_pad_ops ov5640_pad_ops = {
++ .enum_mbus_code = ov5640_enum_mbus_code,
++ .get_fmt = ov5640_get_fmt,
++ .set_fmt = ov5640_set_fmt,
++ .enum_frame_size = ov5640_enum_frame_size,
++ .enum_frame_interval = ov5640_enum_frame_interval,
++};
++
++static const struct v4l2_subdev_sensor_ops ov5640_sensor_ops = {
++ .g_skip_frames = ov5640_skip_frames,
++};
++
++static const struct v4l2_subdev_ops ov5640_subdev_ops = {
++ .core = &ov5640_core_ops,
++ .video = &ov5640_video_ops,
++ .pad = &ov5640_pad_ops,
++ .sensor = &ov5640_sensor_ops,
++};
++
++static int ov5640_get_regulators(struct ov5640_dev *sensor)
++{
++ int i;
++
++ for (i = 0; i < OV5640_NUM_SUPPLIES; i++)
++ sensor->supplies[i].supply = ov5640_supply_name[i];
++
++ return devm_regulator_bulk_get(&sensor->i2c_client->dev,
++ OV5640_NUM_SUPPLIES,
++ sensor->supplies);
++}
++
++static int ov5640_check_chip_id(struct ov5640_dev *sensor)
++{
++ struct i2c_client *client = sensor->i2c_client;
++ int ret = 0;
++ u16 chip_id;
++
++ ret = ov5640_set_power_on(sensor);
++ if (ret)
++ return ret;
++
++ ret = ov5640_read_reg16(sensor, OV5640_REG_CHIP_ID, &chip_id);
++ if (ret) {
++ dev_err(&client->dev, "%s: failed to read chip identifier\n",
++ __func__);
++ goto power_off;
++ }
++
++ if (chip_id != OV5640_CHIP_ID) {
++ dev_err(&client->dev, "%s: wrong chip identifier, expected 0x%x, got 0x%x\n",
++ __func__, OV5640_CHIP_ID, chip_id);
++ ret = -ENXIO;
++ }
++ dev_err(&client->dev, "%s: chip identifier, got 0x%x\n",
++ __func__, chip_id);
++
++power_off:
++ ov5640_set_power_off(sensor);
++ return ret;
++}
++
++static int ov5640_probe(struct i2c_client *client)
++{
++ struct device *dev = &client->dev;
++ struct fwnode_handle *endpoint;
++ struct ov5640_dev *sensor;
++ struct v4l2_mbus_framefmt *fmt;
++ u32 rotation;
++ int ret;
++
++ sensor = devm_kzalloc(dev, sizeof(*sensor), GFP_KERNEL);
++ if (!sensor)
++ return -ENOMEM;
++
++ sensor->i2c_client = client;
++
++ /*
++ * default init sequence initialize sensor to
++ * YUV422 UYVY VGA@30fps
++ */
++ fmt = &sensor->fmt;
++ fmt->code = MEDIA_BUS_FMT_UYVY8_2X8;
++ fmt->colorspace = V4L2_COLORSPACE_SRGB;
++ fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->colorspace);
++ fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE;
++ fmt->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(fmt->colorspace);
++ fmt->width = 640;
++ fmt->height = 480;
++ fmt->field = V4L2_FIELD_NONE;
++ sensor->frame_interval.numerator = 1;
++ sensor->frame_interval.denominator = ov5640_framerates[OV5640_30_FPS];
++ sensor->current_fr = OV5640_30_FPS;
++ sensor->current_mode =
++ &ov5640_mode_data[OV5640_MODE_VGA_640_480];
++ sensor->last_mode = sensor->current_mode;
++
++ sensor->ae_target = 52;
++
++ /* optional indication of physical rotation of sensor */
++ ret = fwnode_property_read_u32(dev_fwnode(&client->dev), "rotation",
++ &rotation);
++ if (!ret) {
++ switch (rotation) {
++ case 180:
++ sensor->upside_down = true;
++ fallthrough;
++ case 0:
++ break;
++ default:
++ dev_warn(dev, "%u degrees rotation is not supported, ignoring...\n",
++ rotation);
++ }
++ }
++
++ endpoint = fwnode_graph_get_next_endpoint(dev_fwnode(&client->dev),
++ NULL);
++ if (!endpoint) {
++ dev_err(dev, "endpoint node not found\n");
++ return -EINVAL;
++ }
++
++ ret = v4l2_fwnode_endpoint_parse(endpoint, &sensor->ep);
++ fwnode_handle_put(endpoint);
++ if (ret) {
++ dev_err(dev, "Could not parse endpoint\n");
++ return ret;
++ }
++
++ if (sensor->ep.bus_type != V4L2_MBUS_PARALLEL &&
++ sensor->ep.bus_type != V4L2_MBUS_CSI2_DPHY &&
++ sensor->ep.bus_type != V4L2_MBUS_BT656) {
++ dev_err(dev, "Unsupported bus type %d\n", sensor->ep.bus_type);
++ return -EINVAL;
++ }
++
++ /* get system clock (xclk) */
++ sensor->xclk = devm_clk_get(dev, "xclk");
++ if (IS_ERR(sensor->xclk)) {
++ dev_err(dev, "failed to get xclk\n");
++ return PTR_ERR(sensor->xclk);
++ }
++
++ sensor->xclk_freq = clk_get_rate(sensor->xclk);
++ if (sensor->xclk_freq < OV5640_XCLK_MIN ||
++ sensor->xclk_freq > OV5640_XCLK_MAX) {
++ dev_err(dev, "xclk frequency out of range: %d Hz\n",
++ sensor->xclk_freq);
++ return -EINVAL;
++ }
++
++ /* request optional power down pin */
++ sensor->pwdn_gpio = devm_gpiod_get_optional(dev, "powerdown",
++ GPIOD_OUT_HIGH);
++ if (IS_ERR(sensor->pwdn_gpio))
++ return PTR_ERR(sensor->pwdn_gpio);
++
++ /* request optional reset pin */
++ sensor->reset_gpio = devm_gpiod_get_optional(dev, "reset",
++ GPIOD_OUT_HIGH);
++ if (IS_ERR(sensor->reset_gpio))
++ return PTR_ERR(sensor->reset_gpio);
++
++ v4l2_i2c_subdev_init(&sensor->sd, client, &ov5640_subdev_ops);
++
++ sensor->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
++ V4L2_SUBDEV_FL_HAS_EVENTS;
++ sensor->pad.flags = MEDIA_PAD_FL_SOURCE;
++ sensor->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
++ ret = media_entity_pads_init(&sensor->sd.entity, 1, &sensor->pad);
++ if (ret)
++ return ret;
++
++ ret = ov5640_get_regulators(sensor);
++ if (ret)
++ return ret;
++
++ mutex_init(&sensor->lock);
++
++ ret = ov5640_check_chip_id(sensor);
++ if (ret)
++ goto entity_cleanup;
++
++ ret = ov5640_init_controls(sensor);
++ if (ret)
++ goto entity_cleanup;
++
++ ret = v4l2_async_register_subdev_sensor(&sensor->sd);
++ if (ret)
++ goto free_ctrls;
++
++ return 0;
++
++free_ctrls:
++ v4l2_ctrl_handler_free(&sensor->ctrls.handler);
++entity_cleanup:
++ media_entity_cleanup(&sensor->sd.entity);
++ mutex_destroy(&sensor->lock);
++ return ret;
++}
++
++static int ov5640_remove(struct i2c_client *client)
++{
++ struct v4l2_subdev *sd = i2c_get_clientdata(client);
++ struct ov5640_dev *sensor = to_ov5640_dev(sd);
++
++ v4l2_async_unregister_subdev(&sensor->sd);
++ media_entity_cleanup(&sensor->sd.entity);
++ v4l2_ctrl_handler_free(&sensor->ctrls.handler);
++ mutex_destroy(&sensor->lock);
++
++ return 0;
++}
++
++static const struct i2c_device_id ov5640_id[] = {
++ {"ov5640", 0},
++ {},
++};
++MODULE_DEVICE_TABLE(i2c, ov5640_id);
++
++static const struct of_device_id ov5640_dt_ids[] = {
++ { .compatible = "ovti,ov5640" },
++ { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, ov5640_dt_ids);
++
++static struct i2c_driver ov5640_i2c_driver = {
++ .driver = {
++ .name = "ov5640",
++ .of_match_table = ov5640_dt_ids,
++ },
++ .id_table = ov5640_id,
++ .probe_new = ov5640_probe,
++ .remove = ov5640_remove,
++};
++
++module_i2c_driver(ov5640_i2c_driver);
++
++MODULE_DESCRIPTION("OV5640 MIPI Camera Subdev Driver");
++MODULE_LICENSE("GPL");
+--- /dev/null
++++ b/drivers/media/platform/starfive/v4l2_driver/sc2235.c
+@@ -0,0 +1,1914 @@
++// SPDX-License-Identifier: GPL-2.0-or-later
++/*
++ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
++ *
++ */
++
++#include <linux/clk.h>
++#include <linux/clk-provider.h>
++#include <linux/clkdev.h>
++#include <linux/ctype.h>
++#include <linux/delay.h>
++#include <linux/device.h>
++#include <linux/gpio/consumer.h>
++#include <linux/i2c.h>
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/pm_runtime.h>
++#include <linux/of_device.h>
++#include <linux/regulator/consumer.h>
++#include <linux/slab.h>
++#include <linux/types.h>
++#include <media/v4l2-async.h>
++#include <media/v4l2-ctrls.h>
++#include <media/v4l2-device.h>
++#include <media/v4l2-event.h>
++#include <media/v4l2-fwnode.h>
++#include <media/v4l2-subdev.h>
++#include "stfcamss.h"
++
++/* min/typical/max system clock (xclk) frequencies */
++#define SC2235_XCLK_MIN 6000000
++#define SC2235_XCLK_MAX 27000000
++
++#define SC2235_CHIP_ID (0x2235)
++
++#define SC2235_REG_CHIP_ID 0x3107
++#define SC2235_REG_AEC_PK_MANUAL 0x3e03
++#define SC2235_REG_AEC_PK_EXPOSURE_HI 0x3e01
++#define SC2235_REG_AEC_PK_EXPOSURE_LO 0x3e02
++#define SC2235_REG_AEC_PK_REAL_GAIN 0x3e08
++#define SC2235_REG_TIMING_HTS 0x320c
++#define SC2235_REG_TIMING_VTS 0x320e
++#define SC2235_REG_TEST_SET0 0x4501
++#define SC2235_REG_TEST_SET1 0x3902
++#define SC2235_REG_TIMING_TC_REG21 0x3221
++#define SC2235_REG_SC_PLL_CTRL0 0x3039
++#define SC2235_REG_SC_PLL_CTRL1 0x303a
++#define SC2235_REG_STREAM_ON 0x0100
++
++enum sc2235_mode_id {
++ SC2235_MODE_1080P_1920_1080 = 0,
++ SC2235_NUM_MODES,
++};
++
++enum sc2235_frame_rate {
++ SC2235_15_FPS = 0,
++ SC2235_30_FPS,
++ SC2235_NUM_FRAMERATES,
++};
++
++struct sc2235_pixfmt {
++ u32 code;
++ u32 colorspace;
++};
++
++static const struct sc2235_pixfmt sc2235_formats[] = {
++ { MEDIA_BUS_FMT_SBGGR10_1X10, V4L2_COLORSPACE_SRGB, },
++};
++
++static const int sc2235_framerates[] = {
++ [SC2235_15_FPS] = 15,
++ [SC2235_30_FPS] = 30,
++};
++
++/* regulator supplies */
++static const char * const sc2235_supply_name[] = {
++ "DOVDD", /* Digital I/O (1.8V) supply */
++ "AVDD", /* Analog (2.8V) supply */
++ "DVDD", /* Digital Core (1.5V) supply */
++};
++
++#define SC2235_NUM_SUPPLIES ARRAY_SIZE(sc2235_supply_name)
++
++struct reg_value {
++ u16 reg_addr;
++ u8 val;
++ u8 mask;
++ u32 delay_ms;
++};
++
++struct sc2235_mode_info {
++ enum sc2235_mode_id id;
++ u32 hact;
++ u32 htot;
++ u32 vact;
++ u32 vtot;
++ const struct reg_value *reg_data;
++ u32 reg_data_size;
++ u32 max_fps;
++};
++
++struct sc2235_ctrls {
++ struct v4l2_ctrl_handler handler;
++ struct v4l2_ctrl *pixel_rate;
++ struct {
++ struct v4l2_ctrl *auto_exp;
++ struct v4l2_ctrl *exposure;
++ };
++ struct {
++ struct v4l2_ctrl *auto_wb;
++ struct v4l2_ctrl *blue_balance;
++ struct v4l2_ctrl *red_balance;
++ };
++ struct {
++ struct v4l2_ctrl *auto_gain;
++ struct v4l2_ctrl *gain;
++ };
++ struct v4l2_ctrl *brightness;
++ struct v4l2_ctrl *light_freq;
++ struct v4l2_ctrl *saturation;
++ struct v4l2_ctrl *contrast;
++ struct v4l2_ctrl *hue;
++ struct v4l2_ctrl *test_pattern;
++ struct v4l2_ctrl *hflip;
++ struct v4l2_ctrl *vflip;
++};
++
++struct sc2235_dev {
++ struct i2c_client *i2c_client;
++ struct v4l2_subdev sd;
++ struct media_pad pad;
++ struct v4l2_fwnode_endpoint ep; /* the parsed DT endpoint info */
++ struct clk *xclk; /* system clock to SC2235 */
++ u32 xclk_freq;
++
++ struct regulator_bulk_data supplies[SC2235_NUM_SUPPLIES];
++ struct gpio_desc *reset_gpio;
++ struct gpio_desc *pwdn_gpio;
++ bool upside_down;
++
++ /* lock to protect all members below */
++ struct mutex lock;
++
++ struct v4l2_mbus_framefmt fmt;
++ bool pending_fmt_change;
++
++ const struct sc2235_mode_info *current_mode;
++ const struct sc2235_mode_info *last_mode;
++ enum sc2235_frame_rate current_fr;
++ struct v4l2_fract frame_interval;
++
++ struct sc2235_ctrls ctrls;
++
++ bool pending_mode_change;
++ int streaming;
++};
++
++static inline struct sc2235_dev *to_sc2235_dev(struct v4l2_subdev *sd)
++{
++ return container_of(sd, struct sc2235_dev, sd);
++}
++
++static inline struct v4l2_subdev *ctrl_to_sd(struct v4l2_ctrl *ctrl)
++{
++ return &container_of(ctrl->handler, struct sc2235_dev,
++ ctrls.handler)->sd;
++}
++
++/* sc2235 initial register 30fps*/
++static struct reg_value sc2235_init_regs_tbl_1080[] = {
++ {0x0103, 0x01, 0, 50},
++ {0x0100, 0x00, 0, 0},
++ {0x3039, 0x80, 0, 0},
++ {0x3621, 0x28, 0, 0},
++
++ {0x3309, 0x60, 0, 0},
++ {0x331f, 0x4d, 0, 0},
++ {0x3321, 0x4f, 0, 0},
++ {0x33b5, 0x10, 0, 0},
++
++ {0x3303, 0x20, 0, 0},
++ {0x331e, 0x0d, 0, 0},
++ {0x3320, 0x0f, 0, 0},
++
++ {0x3622, 0x02, 0, 0},
++ {0x3633, 0x42, 0, 0},
++ {0x3634, 0x42, 0, 0},
++
++ {0x3306, 0x66, 0, 0},
++ {0x330b, 0xd1, 0, 0},
++
++ {0x3301, 0x0e, 0, 0},
++
++ {0x320c, 0x08, 0, 0},
++ {0x320d, 0x98, 0, 0},
++
++ {0x3364, 0x05, 0, 0}, // [2] 1: write at sampling ending
++
++ {0x363c, 0x28, 0, 0}, //bypass nvdd
++ {0x363b, 0x0a, 0, 0}, //HVDD
++ {0x3635, 0xa0, 0, 0}, //TXVDD
++
++ {0x4500, 0x59, 0, 0},
++ {0x3d08, 0x00, 0, 0},
++ {0x3908, 0x11, 0, 0},
++
++ {0x363c, 0x08, 0, 0},
++
++ {0x3e03, 0x03, 0, 0},
++ {0x3e01, 0x46, 0, 0},
++
++ //0703
++ {0x3381, 0x0a, 0, 0},
++ {0x3348, 0x09, 0, 0},
++ {0x3349, 0x50, 0, 0},
++ {0x334a, 0x02, 0, 0},
++ {0x334b, 0x60, 0, 0},
++
++ {0x3380, 0x04, 0, 0},
++ {0x3340, 0x06, 0, 0},
++ {0x3341, 0x50, 0, 0},
++ {0x3342, 0x02, 0, 0},
++ {0x3343, 0x60, 0, 0},
++
++ //0707
++
++ {0x3632, 0x88, 0, 0}, //anti sm
++ {0x3309, 0xa0, 0, 0},
++ {0x331f, 0x8d, 0, 0},
++ {0x3321, 0x8f, 0, 0},
++
++ {0x335e, 0x01, 0, 0}, //ana dithering
++ {0x335f, 0x03, 0, 0},
++ {0x337c, 0x04, 0, 0},
++ {0x337d, 0x06, 0, 0},
++ {0x33a0, 0x05, 0, 0},
++ {0x3301, 0x05, 0, 0},
++
++ {0x337f, 0x03, 0, 0},
++ {0x3368, 0x02, 0, 0},
++ {0x3369, 0x00, 0, 0},
++ {0x336a, 0x00, 0, 0},
++ {0x336b, 0x00, 0, 0},
++ {0x3367, 0x08, 0, 0},
++ {0x330e, 0x30, 0, 0},
++
++ {0x3366, 0x7c, 0, 0}, // div_rst gap
++
++ {0x3635, 0xc1, 0, 0},
++ {0x363b, 0x09, 0, 0},
++ {0x363c, 0x07, 0, 0},
++
++ {0x391e, 0x00, 0, 0},
++
++ {0x3637, 0x14, 0, 0}, //fullwell 7K
++
++ {0x3306, 0x54, 0, 0},
++ {0x330b, 0xd8, 0, 0},
++ {0x366e, 0x08, 0, 0}, // ofs auto en [3]
++ {0x366f, 0x2f, 0, 0},
++
++ {0x3631, 0x84, 0, 0},
++ {0x3630, 0x48, 0, 0},
++ {0x3622, 0x06, 0, 0},
++
++ //ramp by sc
++ {0x3638, 0x1f, 0, 0},
++ {0x3625, 0x02, 0, 0},
++ {0x3636, 0x24, 0, 0},
++
++ //0714
++ {0x3348, 0x08, 0, 0},
++ {0x3e03, 0x0b, 0, 0},
++
++ //7.17 fpn
++ {0x3342, 0x03, 0, 0},
++ {0x3343, 0xa0, 0, 0},
++ {0x334a, 0x03, 0, 0},
++ {0x334b, 0xa0, 0, 0},
++
++ //0718
++ {0x3343, 0xb0, 0, 0},
++ {0x334b, 0xb0, 0, 0},
++
++ //0720
++ //digital ctrl
++ {0x3802, 0x01, 0, 0},
++ {0x3235, 0x04, 0, 0},
++ {0x3236, 0x63, 0, 0}, // vts-2
++
++ //fpn
++ {0x3343, 0xd0, 0, 0},
++ {0x334b, 0xd0, 0, 0},
++ {0x3348, 0x07, 0, 0},
++ {0x3349, 0x80, 0, 0},
++
++ //0724
++ {0x391b, 0x4d, 0, 0},
++
++ {0x3342, 0x04, 0, 0},
++ {0x3343, 0x20, 0, 0},
++ {0x334a, 0x04, 0, 0},
++ {0x334b, 0x20, 0, 0},
++
++ //0804
++ {0x3222, 0x29, 0, 0},
++ {0x3901, 0x02, 0, 0},
++
++ //0808
++
++ // auto blc
++ {0x3900, 0xD5, 0, 0}, // Bit[0]: blc_enable
++ {0x3902, 0x45, 0, 0}, // Bit[6]: blc_auto_en
++
++ // blc target
++ {0x3907, 0x00, 0, 0},
++ {0x3908, 0x00, 0, 0},
++
++ // auto dpc
++ {0x5000, 0x00, 0, 0}, // Bit[2]: white dead pixel cancel enable, Bit[1]: black dead pixel cancel enable
++
++ //digital ctrl
++ {0x3f00, 0x07, 0, 0}, // bit[2] = 1
++ {0x3f04, 0x08, 0, 0},
++ {0x3f05, 0x74, 0, 0}, // hts - { 0x24
++
++ //0809
++ {0x330b, 0xc8, 0, 0},
++
++ //0817
++ {0x3306, 0x4a, 0, 0},
++ {0x330b, 0xca, 0, 0},
++ {0x3639, 0x09, 0, 0},
++
++ //manual DPC
++ {0x5780, 0xff, 0, 0},
++ {0x5781, 0x04, 0, 0},
++ {0x5785, 0x18, 0, 0},
++
++ //0822
++ {0x3039, 0x35, 0, 0}, //fps
++ {0x303a, 0x2e, 0, 0},
++ {0x3034, 0x05, 0, 0},
++ {0x3035, 0x2a, 0, 0},
++
++ {0x320c, 0x08, 0, 0},
++ {0x320d, 0xca, 0, 0},
++ {0x320e, 0x04, 0, 0},
++ {0x320f, 0xb0, 0, 0},
++
++ {0x3f04, 0x08, 0, 0},
++ {0x3f05, 0xa6, 0, 0}, // hts - { 0x24
++
++ {0x3235, 0x04, 0, 0},
++ {0x3236, 0xae, 0, 0}, // vts-2
++
++ //0825
++ {0x3313, 0x05, 0, 0},
++ {0x3678, 0x42, 0, 0},
++
++ //for AE control per frame
++ {0x3670, 0x00, 0, 0},
++ {0x3633, 0x42, 0, 0},
++
++ {0x3802, 0x00, 0, 0},
++
++ //20180126
++ {0x3677, 0x3f, 0, 0},
++ {0x3306, 0x44, 0, 0}, //20180126[3c },4a]
++ {0x330b, 0xca, 0, 0}, //20180126[c2 },d3]
++
++ //20180202
++ {0x3237, 0x08, 0, 0},
++ {0x3238, 0x9a, 0, 0}, //hts-0x30
++
++ //20180417
++ {0x3640, 0x01, 0, 0},
++ {0x3641, 0x02, 0, 0},
++
++ {0x3301, 0x12, 0, 0}, //[8 },15]20180126
++ {0x3631, 0x84, 0, 0},
++ {0x366f, 0x2f, 0, 0},
++ {0x3622, 0xc6, 0, 0}, //20180117
++
++ {0x3e03, 0x03, 0, 0}, // Bit[3]: AGC table mapping method, Bit[1]: AGC manual, BIt[0]: AEC manual
++
++ // {0x0100, 0x00, 0, 0},
++ // {0x4501, 0xc8, 0, 0}, //bar testing
++ // {0x3902, 0x45, 0, 0},
++};
++
++static struct reg_value sc2235_setting_1080P_1920_1080[] = {
++
++};
++
++/* power-on sensor init reg table */
++static const struct sc2235_mode_info sc2235_mode_init_data = {
++ SC2235_MODE_1080P_1920_1080,
++ 1920, 0x8ca, 1080, 0x4b0,
++ sc2235_init_regs_tbl_1080,
++ ARRAY_SIZE(sc2235_init_regs_tbl_1080),
++ SC2235_30_FPS,
++};
++
++static const struct sc2235_mode_info
++sc2235_mode_data[SC2235_NUM_MODES] = {
++ {SC2235_MODE_1080P_1920_1080,
++ 1920, 0x8ca, 1080, 0x4b0,
++ sc2235_setting_1080P_1920_1080,
++ ARRAY_SIZE(sc2235_setting_1080P_1920_1080),
++ SC2235_30_FPS},
++};
++
++static int sc2235_write_reg(struct sc2235_dev *sensor, u16 reg, u8 val)
++{
++ struct i2c_client *client = sensor->i2c_client;
++ struct i2c_msg msg;
++ u8 buf[3];
++ int ret;
++
++ buf[0] = reg >> 8;
++ buf[1] = reg & 0xff;
++ buf[2] = val;
++
++ msg.addr = client->addr;
++ msg.flags = client->flags;
++ msg.buf = buf;
++ msg.len = sizeof(buf);
++
++ ret = i2c_transfer(client->adapter, &msg, 1);
++ if (ret < 0) {
++ dev_err(&client->dev, "%s: error: reg=%x, val=%x\n",
++ __func__, reg, val);
++ return ret;
++ }
++
++ return 0;
++}
++
++static int sc2235_read_reg(struct sc2235_dev *sensor, u16 reg, u8 *val)
++{
++ struct i2c_client *client = sensor->i2c_client;
++ struct i2c_msg msg[2];
++ u8 buf[2];
++ int ret;
++
++ buf[0] = reg >> 8;
++ buf[1] = reg & 0xff;
++
++ msg[0].addr = client->addr;
++ msg[0].flags = client->flags;
++ msg[0].buf = buf;
++ msg[0].len = sizeof(buf);
++
++ msg[1].addr = client->addr;
++ msg[1].flags = client->flags | I2C_M_RD;
++ msg[1].buf = buf;
++ msg[1].len = 1;
++
++ ret = i2c_transfer(client->adapter, msg, 2);
++ if (ret < 0) {
++ dev_err(&client->dev, "%s: error: reg=%x\n",
++ __func__, reg);
++ return ret;
++ }
++
++ *val = buf[0];
++ return 0;
++}
++
++static int sc2235_read_reg16(struct sc2235_dev *sensor, u16 reg, u16 *val)
++{
++ u8 hi, lo;
++ int ret;
++
++ ret = sc2235_read_reg(sensor, reg, &hi);
++ if (ret)
++ return ret;
++ ret = sc2235_read_reg(sensor, reg + 1, &lo);
++ if (ret)
++ return ret;
++
++ *val = ((u16)hi << 8) | (u16)lo;
++ return 0;
++}
++
++static int sc2235_write_reg16(struct sc2235_dev *sensor, u16 reg, u16 val)
++{
++ int ret;
++
++ ret = sc2235_write_reg(sensor, reg, val >> 8);
++ if (ret)
++ return ret;
++
++ return sc2235_write_reg(sensor, reg + 1, val & 0xff);
++}
++
++static int sc2235_mod_reg(struct sc2235_dev *sensor, u16 reg,
++ u8 mask, u8 val)
++{
++ u8 readval;
++ int ret;
++
++ ret = sc2235_read_reg(sensor, reg, &readval);
++ if (ret)
++ return ret;
++
++ readval &= ~mask;
++ val &= mask;
++ val |= readval;
++
++ return sc2235_write_reg(sensor, reg, val);
++}
++
++#define SC2235_PLL_PREDIV 3
++
++#define SC2235_SYSDIV_MIN 0
++#define SC2235_SYSDIV_MAX 7
++
++#define SC2235_PLL_MULT_MIN 0
++#define SC2235_PLL_MULT_MAX 63
++
++#ifdef UNUSED_CODE
++static unsigned long sc2235_compute_sys_clk(struct sc2235_dev *sensor,
++ u8 pll_pre, u8 pll_mult,
++ u8 sysdiv)
++{
++ unsigned long sysclk =
++ sensor->xclk_freq * (64 - pll_mult) / (pll_pre * (sysdiv + 1));
++
++ /* PLL1 output cannot exceed 1GHz. */
++ if (sysclk / 1000000 > 1000)
++ return 0;
++
++ return sysclk;
++}
++
++static unsigned long sc2235_calc_sys_clk(struct sc2235_dev *sensor,
++ unsigned long rate,
++ u8 *pll_prediv, u8 *pll_mult,
++ u8 *sysdiv)
++{
++ unsigned long best = ~0;
++ u8 best_sysdiv = 1, best_mult = 1;
++ u8 _sysdiv, _pll_mult;
++
++ for (_sysdiv = SC2235_SYSDIV_MIN;
++ _sysdiv <= SC2235_SYSDIV_MAX;
++ _sysdiv++) {
++ for (_pll_mult = SC2235_PLL_MULT_MIN;
++ _pll_mult <= SC2235_PLL_MULT_MAX;
++ _pll_mult++) {
++ unsigned long _rate;
++
++ _rate = sc2235_compute_sys_clk(sensor,
++ SC2235_PLL_PREDIV,
++ _pll_mult, _sysdiv);
++
++ /*
++ * We have reached the maximum allowed PLL1 output,
++ * increase sysdiv.
++ */
++ if (!_rate)
++ break;
++
++ /*
++ * Prefer rates above the expected clock rate than
++ * below, even if that means being less precise.
++ */
++ if (_rate < rate)
++ continue;
++
++ if (abs(rate - _rate) < abs(rate - best)) {
++ best = _rate;
++ best_sysdiv = _sysdiv;
++ best_mult = _pll_mult;
++ }
++
++ if (_rate == rate)
++ goto out;
++ }
++ }
++
++out:
++ *sysdiv = best_sysdiv;
++ *pll_prediv = SC2235_PLL_PREDIV;
++ *pll_mult = best_mult;
++
++ return best;
++}
++#endif
++
++static int sc2235_set_timings(struct sc2235_dev *sensor,
++ const struct sc2235_mode_info *mode)
++{
++ int ret = 0;
++
++ return ret;
++}
++
++static int sc2235_load_regs(struct sc2235_dev *sensor,
++ const struct sc2235_mode_info *mode)
++{
++ const struct reg_value *regs = mode->reg_data;
++ unsigned int i;
++ u32 delay_ms;
++ u16 reg_addr;
++ u8 mask, val;
++ int ret = 0;
++
++ for (i = 0; i < mode->reg_data_size; ++i, ++regs) {
++ delay_ms = regs->delay_ms;
++ reg_addr = regs->reg_addr;
++ val = regs->val;
++ mask = regs->mask;
++
++ if (mask)
++ ret = sc2235_mod_reg(sensor, reg_addr, mask, val);
++ else
++ ret = sc2235_write_reg(sensor, reg_addr, val);
++ if (ret)
++ break;
++
++ if (delay_ms)
++ usleep_range(1000 * delay_ms, 1000 * delay_ms + 100);
++ }
++
++ return sc2235_set_timings(sensor, mode);
++}
++
++static int sc2235_set_autoexposure(struct sc2235_dev *sensor, bool on)
++{
++ return sc2235_mod_reg(sensor, SC2235_REG_AEC_PK_MANUAL,
++ BIT(0), on ? 0 : BIT(0));
++}
++
++static int sc2235_get_exposure(struct sc2235_dev *sensor)
++{
++ int exp = 0, ret = 0;
++ u8 temp;
++
++ ret = sc2235_read_reg(sensor, SC2235_REG_AEC_PK_EXPOSURE_HI, &temp);
++ if (ret)
++ return ret;
++ exp |= (int)temp << 8;
++ ret = sc2235_read_reg(sensor, SC2235_REG_AEC_PK_EXPOSURE_LO, &temp);
++ if (ret)
++ return ret;
++ exp |= (int)temp;
++
++ return exp >> 4;
++}
++
++static int sc2235_set_exposure(struct sc2235_dev *sensor, u32 exposure)
++{
++ int ret;
++
++ exposure <<= 4;
++
++ ret = sc2235_write_reg(sensor,
++ SC2235_REG_AEC_PK_EXPOSURE_LO,
++ exposure & 0xff);
++ if (ret)
++ return ret;
++ return sc2235_write_reg(sensor,
++ SC2235_REG_AEC_PK_EXPOSURE_HI,
++ (exposure >> 8) & 0xff);
++}
++
++static int sc2235_get_gain(struct sc2235_dev *sensor)
++{
++ u16 gain;
++ int ret;
++
++ ret = sc2235_read_reg16(sensor, SC2235_REG_AEC_PK_REAL_GAIN, &gain);
++ if (ret)
++ return ret;
++
++ return gain & 0x1fff;
++}
++
++static int sc2235_set_gain(struct sc2235_dev *sensor, int gain)
++{
++ return sc2235_write_reg16(sensor, SC2235_REG_AEC_PK_REAL_GAIN,
++ (u16)gain & 0x1fff);
++}
++
++static int sc2235_set_autogain(struct sc2235_dev *sensor, bool on)
++{
++ return sc2235_mod_reg(sensor, SC2235_REG_AEC_PK_MANUAL,
++ BIT(1), on ? 0 : BIT(1));
++}
++
++#ifdef UNUSED_CODE
++static int sc2235_get_sysclk(struct sc2235_dev *sensor)
++{
++ return 0;
++}
++
++static int sc2235_set_night_mode(struct sc2235_dev *sensor)
++{
++ return 0;
++}
++
++static int sc2235_get_hts(struct sc2235_dev *sensor)
++{
++ u16 hts;
++ int ret;
++
++ ret = sc2235_read_reg16(sensor, SC2235_REG_TIMING_HTS, &hts);
++ if (ret)
++ return ret;
++ return hts;
++}
++#endif
++
++static int sc2235_get_vts(struct sc2235_dev *sensor)
++{
++ u16 vts;
++ int ret;
++
++ ret = sc2235_read_reg16(sensor, SC2235_REG_TIMING_VTS, &vts);
++ if (ret)
++ return ret;
++ return vts;
++}
++
++#ifdef UNUSED_CODE
++static int sc2235_set_vts(struct sc2235_dev *sensor, int vts)
++{
++ return sc2235_write_reg16(sensor, SC2235_REG_TIMING_VTS, vts);
++}
++
++static int sc2235_get_light_freq(struct sc2235_dev *sensor)
++{
++ return 0;
++}
++
++static int sc2235_set_bandingfilter(struct sc2235_dev *sensor)
++{
++ return 0;
++}
++
++static int sc2235_set_ae_target(struct sc2235_dev *sensor, int target)
++{
++ return 0;
++}
++
++static int sc2235_get_binning(struct sc2235_dev *sensor)
++{
++ return 0;
++}
++
++static int sc2235_set_binning(struct sc2235_dev *sensor, bool enable)
++{
++ return 0;
++}
++
++#endif
++
++static const struct sc2235_mode_info *
++sc2235_find_mode(struct sc2235_dev *sensor, enum sc2235_frame_rate fr,
++ int width, int height, bool nearest)
++{
++ const struct sc2235_mode_info *mode;
++
++ mode = v4l2_find_nearest_size(sc2235_mode_data,
++ ARRAY_SIZE(sc2235_mode_data),
++ hact, vact,
++ width, height);
++
++ if (!mode ||
++ (!nearest && (mode->hact != width || mode->vact != height)))
++ return NULL;
++
++ /* Check to see if the current mode exceeds the max frame rate */
++ if (sc2235_framerates[fr] > sc2235_framerates[mode->max_fps])
++ return NULL;
++
++ return mode;
++}
++
++static u64 sc2235_calc_pixel_rate(struct sc2235_dev *sensor)
++{
++ u64 rate;
++
++ rate = sensor->current_mode->vtot * sensor->current_mode->htot;
++ rate *= sc2235_framerates[sensor->current_fr];
++
++ return rate;
++}
++
++#ifdef UNUSED_CODE
++/*
++ * sc2235_set_dvp_pclk() - Calculate the clock tree configuration values
++ * for the dvp output.
++ *
++ * @rate: The requested bandwidth per lane in bytes per second.
++ * 'Bandwidth Per Lane' is calculated as:
++ * rate = HTOT * VTOT * FPS;
++ *
++ * This function use the requested bandwidth to calculate:
++ * - rate = xclk * (64 - M) / (N * (S + 1));
++ *
++ */
++
++#define PLL_PREDIV 1
++#define PLL_SYSEL 0
++
++static int sc2235_set_dvp_pclk(struct sc2235_dev *sensor,
++ unsigned long rate)
++{
++ u8 prediv, mult, sysdiv;
++ int ret = 0;
++
++ sc2235_calc_sys_clk(sensor, rate, &prediv, &mult,
++ &sysdiv);
++
++
++ return ret;
++}
++
++/*
++ * if sensor changes inside scaling or subsampling
++ * change mode directly
++ */
++static int sc2235_set_mode_direct(struct sc2235_dev *sensor,
++ const struct sc2235_mode_info *mode)
++{
++ if (!mode->reg_data)
++ return -EINVAL;
++
++ /* Write capture setting */
++ return sc2235_load_regs(sensor, mode);
++}
++#endif
++
++static int sc2235_set_mode(struct sc2235_dev *sensor)
++{
++#ifdef UNUSED_CODE
++ bool auto_exp = sensor->ctrls.auto_exp->val == V4L2_EXPOSURE_AUTO;
++ const struct sc2235_mode_info *mode = sensor->current_mode;
++#endif
++ bool auto_gain = sensor->ctrls.auto_gain->val == 1;
++ int ret = 0;
++
++ /* auto gain and exposure must be turned off when changing modes */
++ if (auto_gain) {
++ ret = sc2235_set_autogain(sensor, false);
++ if (ret)
++ return ret;
++ }
++#ifdef UNUSED_CODE
++ /* This issue will be addressed in the EVB board*/
++ /* This action will result in poor image display 2021 1111*/
++ if (auto_exp) {
++ ret = sc2235_set_autoexposure(sensor, false);
++ if (ret)
++ goto restore_auto_gain;
++ }
++
++ rate = sc2235_calc_pixel_rate(sensor);
++
++ ret = sc2235_set_dvp_pclk(sensor, rate);
++ if (ret < 0)
++ return 0;
++
++ ret = sc2235_set_mode_direct(sensor, mode);
++ if (ret < 0)
++ goto restore_auto_exp_gain;
++
++ /* restore auto gain and exposure */
++ if (auto_gain)
++ sc2235_set_autogain(sensor, true);
++ if (auto_exp)
++ sc2235_set_autoexposure(sensor, true);
++
++
++ sensor->pending_mode_change = false;
++ sensor->last_mode = mode;
++ return 0;
++
++restore_auto_exp_gain:
++ if (auto_exp)
++ sc2235_set_autoexposure(sensor, true);
++restore_auto_gain:
++ if (auto_gain)
++ sc2235_set_autogain(sensor, true);
++#endif
++ return ret;
++}
++
++static int sc2235_set_framefmt(struct sc2235_dev *sensor,
++ struct v4l2_mbus_framefmt *format);
++
++/* restore the last set video mode after chip power-on */
++static int sc2235_restore_mode(struct sc2235_dev *sensor)
++{
++ int ret;
++
++ /* first load the initial register values */
++ ret = sc2235_load_regs(sensor, &sc2235_mode_init_data);
++ if (ret < 0)
++ return ret;
++ sensor->last_mode = &sc2235_mode_init_data;
++ /* now restore the last capture mode */
++ ret = sc2235_set_mode(sensor);
++ if (ret < 0)
++ return ret;
++
++ return sc2235_set_framefmt(sensor, &sensor->fmt);
++}
++
++static void sc2235_power(struct sc2235_dev *sensor, bool enable)
++{
++ if (!sensor->pwdn_gpio)
++ return;
++ gpiod_set_value_cansleep(sensor->pwdn_gpio, enable ? 0 : 1);
++}
++
++static void sc2235_reset(struct sc2235_dev *sensor)
++{
++ if (!sensor->reset_gpio)
++ return;
++
++ gpiod_set_value_cansleep(sensor->reset_gpio, 0);
++
++ /* camera power cycle */
++ sc2235_power(sensor, false);
++ usleep_range(5000, 10000);
++ sc2235_power(sensor, true);
++ usleep_range(5000, 10000);
++
++ gpiod_set_value_cansleep(sensor->reset_gpio, 1);
++ usleep_range(1000, 2000);
++
++ gpiod_set_value_cansleep(sensor->reset_gpio, 0);
++ usleep_range(20000, 25000);
++}
++
++static int sc2235_set_power_on(struct device *dev)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ struct v4l2_subdev *sd = i2c_get_clientdata(client);
++ struct sc2235_dev *sensor = to_sc2235_dev(sd);
++ int ret;
++
++ ret = clk_prepare_enable(sensor->xclk);
++ if (ret) {
++ dev_err(&client->dev, "%s: failed to enable clock\n",
++ __func__);
++ return ret;
++ }
++
++ ret = regulator_bulk_enable(SC2235_NUM_SUPPLIES,
++ sensor->supplies);
++ if (ret) {
++ dev_err(&client->dev, "%s: failed to enable regulators\n",
++ __func__);
++ goto xclk_off;
++ }
++
++ sc2235_reset(sensor);
++ sc2235_power(sensor, true);
++
++ return 0;
++
++xclk_off:
++ clk_disable_unprepare(sensor->xclk);
++ return ret;
++}
++
++static int sc2235_set_power_off(struct device *dev)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ struct v4l2_subdev *sd = i2c_get_clientdata(client);
++ struct sc2235_dev *sensor = to_sc2235_dev(sd);
++
++ sc2235_power(sensor, false);
++ regulator_bulk_disable(SC2235_NUM_SUPPLIES, sensor->supplies);
++ clk_disable_unprepare(sensor->xclk);
++
++ return 0;
++}
++
++static int sc2235_set_power(struct sc2235_dev *sensor, bool on)
++{
++ int ret = 0;
++
++ if (on) {
++ pm_runtime_get_sync(&sensor->i2c_client->dev);
++
++ ret = sc2235_restore_mode(sensor);
++ if (ret)
++ goto power_off;
++ }
++
++ if (!on)
++ pm_runtime_put_sync(&sensor->i2c_client->dev);
++
++ return 0;
++
++power_off:
++ pm_runtime_put_sync(&sensor->i2c_client->dev);
++
++ return ret;
++}
++
++static int sc2235_s_power(struct v4l2_subdev *sd, int on)
++{
++ struct sc2235_dev *sensor = to_sc2235_dev(sd);
++ int ret = 0;
++
++ mutex_lock(&sensor->lock);
++
++ ret = sc2235_set_power(sensor, !!on);
++ if (ret)
++ goto out;
++
++ mutex_unlock(&sensor->lock);
++ return 0;
++
++out:
++ mutex_unlock(&sensor->lock);
++ return ret;
++}
++
++static int sc2235_try_frame_interval(struct sc2235_dev *sensor,
++ struct v4l2_fract *fi,
++ u32 width, u32 height)
++{
++ const struct sc2235_mode_info *mode;
++ enum sc2235_frame_rate rate = SC2235_15_FPS;
++ int minfps, maxfps, best_fps, fps;
++ int i;
++
++ minfps = sc2235_framerates[SC2235_15_FPS];
++ maxfps = sc2235_framerates[SC2235_30_FPS];
++
++ if (fi->numerator == 0) {
++ fi->denominator = maxfps;
++ fi->numerator = 1;
++ rate = SC2235_30_FPS;
++ goto find_mode;
++ }
++
++ fps = clamp_val(DIV_ROUND_CLOSEST(fi->denominator, fi->numerator),
++ minfps, maxfps);
++
++ best_fps = minfps;
++ for (i = 0; i < ARRAY_SIZE(sc2235_framerates); i++) {
++ int curr_fps = sc2235_framerates[i];
++
++ if (abs(curr_fps - fps) < abs(best_fps - fps)) {
++ best_fps = curr_fps;
++ rate = i;
++ }
++ }
++
++ fi->numerator = 1;
++ fi->denominator = best_fps;
++
++find_mode:
++ mode = sc2235_find_mode(sensor, rate, width, height, false);
++ return mode ? rate : -EINVAL;
++}
++
++static int sc2235_get_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_format *format)
++{
++ struct sc2235_dev *sensor = to_sc2235_dev(sd);
++ struct v4l2_mbus_framefmt *fmt;
++
++ if (format->pad != 0)
++ return -EINVAL;
++
++ mutex_lock(&sensor->lock);
++
++ if (format->which == V4L2_SUBDEV_FORMAT_TRY)
++ fmt = v4l2_subdev_get_try_format(&sensor->sd, state,
++ format->pad);
++ else
++ fmt = &sensor->fmt;
++
++ format->format = *fmt;
++
++ mutex_unlock(&sensor->lock);
++
++ return 0;
++}
++
++static int sc2235_try_fmt_internal(struct v4l2_subdev *sd,
++ struct v4l2_mbus_framefmt *fmt,
++ enum sc2235_frame_rate fr,
++ const struct sc2235_mode_info **new_mode)
++{
++ struct sc2235_dev *sensor = to_sc2235_dev(sd);
++ const struct sc2235_mode_info *mode;
++ int i;
++
++ mode = sc2235_find_mode(sensor, fr, fmt->width, fmt->height, true);
++ if (!mode)
++ return -EINVAL;
++ fmt->width = mode->hact;
++ fmt->height = mode->vact;
++
++ if (new_mode)
++ *new_mode = mode;
++
++ for (i = 0; i < ARRAY_SIZE(sc2235_formats); i++)
++ if (sc2235_formats[i].code == fmt->code)
++ break;
++ if (i >= ARRAY_SIZE(sc2235_formats))
++ i = 0;
++
++ fmt->code = sc2235_formats[i].code;
++ fmt->colorspace = sc2235_formats[i].colorspace;
++ fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->colorspace);
++ fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE;
++ fmt->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(fmt->colorspace);
++
++ return 0;
++}
++
++static int sc2235_set_fmt(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_format *format)
++{
++ struct sc2235_dev *sensor = to_sc2235_dev(sd);
++ const struct sc2235_mode_info *new_mode;
++ struct v4l2_mbus_framefmt *mbus_fmt = &format->format;
++ struct v4l2_mbus_framefmt *fmt;
++ int ret;
++
++ if (format->pad != 0)
++ return -EINVAL;
++ mutex_lock(&sensor->lock);
++
++ if (sensor->streaming) {
++ ret = -EBUSY;
++ goto out;
++ }
++
++ ret = sc2235_try_fmt_internal(sd, mbus_fmt, 0, &new_mode);
++ if (ret)
++ goto out;
++
++ if (format->which == V4L2_SUBDEV_FORMAT_TRY)
++ fmt = v4l2_subdev_get_try_format(sd, state, 0);
++ else
++ fmt = &sensor->fmt;
++
++ if (mbus_fmt->code != sensor->fmt.code)
++ sensor->pending_fmt_change = true;
++
++ *fmt = *mbus_fmt;
++
++ if (new_mode != sensor->current_mode) {
++ sensor->current_mode = new_mode;
++ sensor->pending_mode_change = true;
++ }
++ if (new_mode->max_fps < sensor->current_fr) {
++ sensor->current_fr = new_mode->max_fps;
++ sensor->frame_interval.numerator = 1;
++ sensor->frame_interval.denominator =
++ sc2235_framerates[sensor->current_fr];
++ sensor->current_mode = new_mode;
++ sensor->pending_mode_change = true;
++ }
++
++ __v4l2_ctrl_s_ctrl_int64(sensor->ctrls.pixel_rate,
++ sc2235_calc_pixel_rate(sensor));
++out:
++ mutex_unlock(&sensor->lock);
++ return ret;
++}
++
++static int sc2235_set_framefmt(struct sc2235_dev *sensor,
++ struct v4l2_mbus_framefmt *format)
++{
++ int ret = 0;
++
++ switch (format->code) {
++ default:
++ return ret;
++ }
++ return ret;
++}
++
++/*
++ * Sensor Controls.
++ */
++
++static int sc2235_set_ctrl_hue(struct sc2235_dev *sensor, int value)
++{
++ int ret = 0;
++ return ret;
++}
++
++static int sc2235_set_ctrl_contrast(struct sc2235_dev *sensor, int value)
++{
++ int ret = 0;
++ return ret;
++}
++
++static int sc2235_set_ctrl_saturation(struct sc2235_dev *sensor, int value)
++{
++ int ret = 0;
++ return ret;
++}
++
++static int sc2235_set_ctrl_white_balance(struct sc2235_dev *sensor, int awb)
++{
++ int ret = 0;
++ return ret;
++}
++
++static int sc2235_set_ctrl_exposure(struct sc2235_dev *sensor,
++ enum v4l2_exposure_auto_type auto_exposure)
++{
++ struct sc2235_ctrls *ctrls = &sensor->ctrls;
++ bool auto_exp = (auto_exposure == V4L2_EXPOSURE_AUTO);
++ int ret = 0;
++
++ if (ctrls->auto_exp->is_new) {
++ ret = sc2235_set_autoexposure(sensor, auto_exp);
++ if (ret)
++ return ret;
++ }
++
++ if (!auto_exp && ctrls->exposure->is_new) {
++ u16 max_exp = 0;
++
++ ret = sc2235_get_vts(sensor);
++ if (ret < 0)
++ return ret;
++ max_exp += ret - 4;
++ ret = 0;
++
++ if (ctrls->exposure->val < max_exp)
++ ret = sc2235_set_exposure(sensor, ctrls->exposure->val);
++ }
++
++ return ret;
++}
++
++static int sc2235_set_ctrl_gain(struct sc2235_dev *sensor, bool auto_gain)
++{
++ struct sc2235_ctrls *ctrls = &sensor->ctrls;
++ int ret = 0;
++
++ if (ctrls->auto_gain->is_new) {
++ ret = sc2235_set_autogain(sensor, auto_gain);
++ if (ret)
++ return ret;
++ }
++
++ if (!auto_gain && ctrls->gain->is_new)
++ ret = sc2235_set_gain(sensor, ctrls->gain->val);
++
++ return ret;
++}
++
++static const char * const test_pattern_menu[] = {
++ "Disabled",
++ "Black bars",
++ "Auto Black bars",
++};
++
++#define SC2235_TEST_ENABLE BIT(3)
++#define SC2235_TEST_BLACK (3 << 0)
++
++static int sc2235_set_ctrl_test_pattern(struct sc2235_dev *sensor, int value)
++{
++ int ret = 0;
++ /*
++ *For 7110 platform, refer to 1125 FW code configuration. This operation will cause the image to be white.
++ */
++#ifdef UNUSED_CODE
++ ret = sc2235_mod_reg(sensor, SC2235_REG_TEST_SET0, BIT(3),
++ !!value << 3);
++
++ ret |= sc2235_mod_reg(sensor, SC2235_REG_TEST_SET1, BIT(6),
++ (value >> 1) << 6);
++#endif
++ return ret;
++}
++
++static int sc2235_set_ctrl_light_freq(struct sc2235_dev *sensor, int value)
++{
++ return 0;
++}
++
++static int sc2235_set_ctrl_hflip(struct sc2235_dev *sensor, int value)
++{
++ return sc2235_mod_reg(sensor, SC2235_REG_TIMING_TC_REG21,
++ BIT(2) | BIT(1),
++ (!(value ^ sensor->upside_down)) ?
++ (BIT(2) | BIT(1)) : 0);
++}
++
++static int sc2235_set_ctrl_vflip(struct sc2235_dev *sensor, int value)
++{
++ return sc2235_mod_reg(sensor, SC2235_REG_TIMING_TC_REG21,
++ BIT(6) | BIT(5),
++ (value ^ sensor->upside_down) ?
++ (BIT(6) | BIT(5)) : 0);
++}
++
++static int sc2235_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
++{
++ struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
++ struct sc2235_dev *sensor = to_sc2235_dev(sd);
++ int val;
++
++ /* v4l2_ctrl_lock() locks our own mutex */
++
++ if (!pm_runtime_get_if_in_use(&sensor->i2c_client->dev))
++ return 0;
++
++ switch (ctrl->id) {
++ case V4L2_CID_AUTOGAIN:
++ val = sc2235_get_gain(sensor);
++ if (val < 0)
++ return val;
++ sensor->ctrls.gain->val = val;
++ break;
++ case V4L2_CID_EXPOSURE_AUTO:
++ val = sc2235_get_exposure(sensor);
++ if (val < 0)
++ return val;
++ sensor->ctrls.exposure->val = val;
++ break;
++ }
++
++ pm_runtime_put(&sensor->i2c_client->dev);
++
++ return 0;
++}
++
++static int sc2235_s_ctrl(struct v4l2_ctrl *ctrl)
++{
++ struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
++ struct sc2235_dev *sensor = to_sc2235_dev(sd);
++ int ret;
++
++ /* v4l2_ctrl_lock() locks our own mutex */
++
++ /*
++ * If the device is not powered up by the host driver do
++ * not apply any controls to H/W at this time. Instead
++ * the controls will be restored at start streaming time.
++ */
++ if (!pm_runtime_get_if_in_use(&sensor->i2c_client->dev))
++ return 0;
++
++ switch (ctrl->id) {
++ case V4L2_CID_AUTOGAIN:
++ ret = sc2235_set_ctrl_gain(sensor, ctrl->val);
++ break;
++ case V4L2_CID_EXPOSURE_AUTO:
++ ret = sc2235_set_ctrl_exposure(sensor, ctrl->val);
++ break;
++ case V4L2_CID_AUTO_WHITE_BALANCE:
++ ret = sc2235_set_ctrl_white_balance(sensor, ctrl->val);
++ break;
++ case V4L2_CID_HUE:
++ ret = sc2235_set_ctrl_hue(sensor, ctrl->val);
++ break;
++ case V4L2_CID_CONTRAST:
++ ret = sc2235_set_ctrl_contrast(sensor, ctrl->val);
++ break;
++ case V4L2_CID_SATURATION:
++ ret = sc2235_set_ctrl_saturation(sensor, ctrl->val);
++ break;
++ case V4L2_CID_TEST_PATTERN:
++ ret = sc2235_set_ctrl_test_pattern(sensor, ctrl->val);
++ break;
++ case V4L2_CID_POWER_LINE_FREQUENCY:
++ ret = sc2235_set_ctrl_light_freq(sensor, ctrl->val);
++ break;
++ case V4L2_CID_HFLIP:
++ ret = sc2235_set_ctrl_hflip(sensor, ctrl->val);
++ break;
++ case V4L2_CID_VFLIP:
++ ret = sc2235_set_ctrl_vflip(sensor, ctrl->val);
++ break;
++ default:
++ ret = -EINVAL;
++ break;
++ }
++
++ pm_runtime_put(&sensor->i2c_client->dev);
++
++ return ret;
++}
++
++static const struct v4l2_ctrl_ops sc2235_ctrl_ops = {
++ .g_volatile_ctrl = sc2235_g_volatile_ctrl,
++ .s_ctrl = sc2235_s_ctrl,
++};
++
++static int sc2235_init_controls(struct sc2235_dev *sensor)
++{
++ const struct v4l2_ctrl_ops *ops = &sc2235_ctrl_ops;
++ struct sc2235_ctrls *ctrls = &sensor->ctrls;
++ struct v4l2_ctrl_handler *hdl = &ctrls->handler;
++ int ret;
++
++ v4l2_ctrl_handler_init(hdl, 32);
++
++ /* we can use our own mutex for the ctrl lock */
++ hdl->lock = &sensor->lock;
++
++ /* Clock related controls */
++ ctrls->pixel_rate = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_PIXEL_RATE,
++ 0, INT_MAX, 1,
++ sc2235_calc_pixel_rate(sensor));
++
++ /* Auto/manual white balance */
++ ctrls->auto_wb = v4l2_ctrl_new_std(hdl, ops,
++ V4L2_CID_AUTO_WHITE_BALANCE,
++ 0, 1, 1, 1);
++ ctrls->blue_balance = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_BLUE_BALANCE,
++ 0, 4095, 1, 0);
++ ctrls->red_balance = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_RED_BALANCE,
++ 0, 4095, 1, 0);
++ /* Auto/manual exposure */
++#ifdef UNUSED_CODE
++ /*
++ *For 7110 platform, This operation will cause the image to be white.
++ */
++ ctrls->auto_exp = v4l2_ctrl_new_std_menu(hdl, ops,
++ V4L2_CID_EXPOSURE_AUTO,
++ V4L2_EXPOSURE_MANUAL, 0,
++ V4L2_EXPOSURE_AUTO);
++ ctrls->exposure = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_EXPOSURE,
++ 0, 65535, 1, 0);
++ /* Auto/manual gain */
++ ctrls->auto_gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_AUTOGAIN,
++ 0, 1, 1, 1);
++ ctrls->gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAIN,
++ 0, 1023, 1, 0);
++#else
++ ctrls->auto_exp = v4l2_ctrl_new_std_menu(hdl, ops,
++ V4L2_CID_EXPOSURE_AUTO,
++ V4L2_EXPOSURE_MANUAL, 0,
++ 1);
++ ctrls->exposure = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_EXPOSURE,
++ 0, 65535, 1, 720);
++ /* Auto/manual gain */
++ ctrls->auto_gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_AUTOGAIN,
++ 0, 1, 1, 0);
++ ctrls->gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAIN,
++ 0, 1023, 1, 0x10);
++#endif
++ ctrls->saturation = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_SATURATION,
++ 0, 255, 1, 64);
++ ctrls->hue = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_HUE,
++ 0, 359, 1, 0);
++ ctrls->contrast = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_CONTRAST,
++ 0, 255, 1, 0);
++ ctrls->test_pattern =
++ v4l2_ctrl_new_std_menu_items(hdl, ops, V4L2_CID_TEST_PATTERN,
++ ARRAY_SIZE(test_pattern_menu) - 1,
++ 0, 0, test_pattern_menu); //0x02
++ ctrls->hflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_HFLIP,
++ 0, 1, 1, 1);
++ ctrls->vflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_VFLIP,
++ 0, 1, 1, 0);
++
++ ctrls->light_freq =
++ v4l2_ctrl_new_std_menu(hdl, ops,
++ V4L2_CID_POWER_LINE_FREQUENCY,
++ V4L2_CID_POWER_LINE_FREQUENCY_AUTO, 0,
++ V4L2_CID_POWER_LINE_FREQUENCY_50HZ);
++
++ if (hdl->error) {
++ ret = hdl->error;
++ goto free_ctrls;
++ }
++
++ ctrls->pixel_rate->flags |= V4L2_CTRL_FLAG_READ_ONLY;
++ ctrls->gain->flags |= V4L2_CTRL_FLAG_VOLATILE;
++ ctrls->exposure->flags |= V4L2_CTRL_FLAG_VOLATILE;
++
++ v4l2_ctrl_auto_cluster(3, &ctrls->auto_wb, 0, false);
++ v4l2_ctrl_auto_cluster(2, &ctrls->auto_gain, 0, true);
++ v4l2_ctrl_auto_cluster(2, &ctrls->auto_exp, 1, true);
++
++ sensor->sd.ctrl_handler = hdl;
++ return 0;
++
++free_ctrls:
++ v4l2_ctrl_handler_free(hdl);
++ return ret;
++}
++
++static int sc2235_enum_frame_size(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_frame_size_enum *fse)
++{
++ if (fse->pad != 0)
++ return -EINVAL;
++ if (fse->index >= SC2235_NUM_MODES)
++ return -EINVAL;
++
++ fse->min_width =
++ sc2235_mode_data[fse->index].hact;
++ fse->max_width = fse->min_width;
++ fse->min_height =
++ sc2235_mode_data[fse->index].vact;
++ fse->max_height = fse->min_height;
++
++ return 0;
++}
++
++static int sc2235_enum_frame_interval(
++ struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_frame_interval_enum *fie)
++{
++ struct v4l2_fract tpf;
++ int i;
++
++ if (fie->pad != 0)
++ return -EINVAL;
++
++ if (fie->index >= SC2235_NUM_FRAMERATES)
++ return -EINVAL;
++
++ tpf.numerator = 1;
++ tpf.denominator = sc2235_framerates[fie->index];
++
++ for (i = 0; i < SC2235_NUM_MODES; i++) {
++ if (fie->width == sc2235_mode_data[i].hact &&
++ fie->height == sc2235_mode_data[i].vact)
++ break;
++ }
++ if (i == SC2235_NUM_MODES)
++ return -ENOTTY;
++
++ fie->interval = tpf;
++ return 0;
++}
++
++static int sc2235_g_frame_interval(struct v4l2_subdev *sd,
++ struct v4l2_subdev_frame_interval *fi)
++{
++ struct sc2235_dev *sensor = to_sc2235_dev(sd);
++
++ mutex_lock(&sensor->lock);
++ fi->interval = sensor->frame_interval;
++ mutex_unlock(&sensor->lock);
++
++ return 0;
++}
++
++static int sc2235_s_frame_interval(struct v4l2_subdev *sd,
++ struct v4l2_subdev_frame_interval *fi)
++{
++ struct sc2235_dev *sensor = to_sc2235_dev(sd);
++ const struct sc2235_mode_info *mode;
++ int frame_rate, ret = 0;
++
++ if (fi->pad != 0)
++ return -EINVAL;
++
++ mutex_lock(&sensor->lock);
++
++ if (sensor->streaming) {
++ ret = -EBUSY;
++ goto out;
++ }
++
++ mode = sensor->current_mode;
++
++ frame_rate = sc2235_try_frame_interval(sensor, &fi->interval,
++ mode->hact, mode->vact);
++ if (frame_rate < 0) {
++ /* Always return a valid frame interval value */
++ fi->interval = sensor->frame_interval;
++ goto out;
++ }
++
++ mode = sc2235_find_mode(sensor, frame_rate, mode->hact,
++ mode->vact, true);
++ if (!mode) {
++ ret = -EINVAL;
++ goto out;
++ }
++
++ if (mode != sensor->current_mode ||
++ frame_rate != sensor->current_fr) {
++ sensor->current_fr = frame_rate;
++ sensor->frame_interval = fi->interval;
++ sensor->current_mode = mode;
++ sensor->pending_mode_change = true;
++
++ __v4l2_ctrl_s_ctrl_int64(sensor->ctrls.pixel_rate,
++ sc2235_calc_pixel_rate(sensor));
++ }
++out:
++ mutex_unlock(&sensor->lock);
++ return ret;
++}
++
++static int sc2235_enum_mbus_code(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_mbus_code_enum *code)
++{
++ if (code->pad != 0)
++ return -EINVAL;
++ if (code->index >= ARRAY_SIZE(sc2235_formats))
++ return -EINVAL;
++
++ code->code = sc2235_formats[code->index].code;
++ return 0;
++}
++
++static int sc2235_stream_start(struct sc2235_dev *sensor, int enable)
++{
++ return sc2235_mod_reg(sensor, SC2235_REG_STREAM_ON, BIT(0), !!enable);
++}
++
++static int sc2235_s_stream(struct v4l2_subdev *sd, int enable)
++{
++ struct sc2235_dev *sensor = to_sc2235_dev(sd);
++ int ret = 0;
++
++ if (enable) {
++ ret = v4l2_ctrl_handler_setup(&sensor->ctrls.handler);
++ if (ret)
++ return ret;
++ }
++
++ mutex_lock(&sensor->lock);
++
++ if (sensor->streaming == !enable) {
++ if (enable && sensor->pending_mode_change) {
++ ret = sc2235_set_mode(sensor);
++ if (ret)
++ goto out;
++ }
++
++ if (enable && sensor->pending_fmt_change) {
++ ret = sc2235_set_framefmt(sensor, &sensor->fmt);
++ if (ret)
++ goto out;
++ sensor->pending_fmt_change = false;
++ }
++
++ ret = sc2235_stream_start(sensor, enable);
++ if (ret)
++ goto out;
++ }
++ sensor->streaming += enable ? 1 : -1;
++ WARN_ON(sensor->streaming < 0);
++out:
++ mutex_unlock(&sensor->lock);
++
++ return ret;
++}
++
++static const struct v4l2_subdev_core_ops sc2235_core_ops = {
++ .s_power = sc2235_s_power,
++ .log_status = v4l2_ctrl_subdev_log_status,
++ .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
++ .unsubscribe_event = v4l2_event_subdev_unsubscribe,
++};
++
++static const struct v4l2_subdev_video_ops sc2235_video_ops = {
++ .g_frame_interval = sc2235_g_frame_interval,
++ .s_frame_interval = sc2235_s_frame_interval,
++ .s_stream = sc2235_s_stream,
++};
++
++static const struct v4l2_subdev_pad_ops sc2235_pad_ops = {
++ .enum_mbus_code = sc2235_enum_mbus_code,
++ .get_fmt = sc2235_get_fmt,
++ .set_fmt = sc2235_set_fmt,
++ .enum_frame_size = sc2235_enum_frame_size,
++ .enum_frame_interval = sc2235_enum_frame_interval,
++};
++
++static const struct v4l2_subdev_ops sc2235_subdev_ops = {
++ .core = &sc2235_core_ops,
++ .video = &sc2235_video_ops,
++ .pad = &sc2235_pad_ops,
++};
++
++static int sc2235_get_regulators(struct sc2235_dev *sensor)
++{
++ int i;
++
++ for (i = 0; i < SC2235_NUM_SUPPLIES; i++)
++ sensor->supplies[i].supply = sc2235_supply_name[i];
++
++ return devm_regulator_bulk_get(&sensor->i2c_client->dev,
++ SC2235_NUM_SUPPLIES,
++ sensor->supplies);
++}
++
++static int sc2235_check_chip_id(struct sc2235_dev *sensor)
++{
++ struct i2c_client *client = sensor->i2c_client;
++ int ret = 0;
++ u16 chip_id;
++
++ ret = sc2235_read_reg16(sensor, SC2235_REG_CHIP_ID, &chip_id);
++ if (ret) {
++ dev_err(&client->dev, "%s: failed to read chip identifier\n",
++ __func__);
++ return ret;
++ }
++
++ if (chip_id != SC2235_CHIP_ID) {
++ dev_err(&client->dev, "%s: wrong chip identifier, expected 0x%x, got 0x%x\n",
++ __func__, SC2235_CHIP_ID, chip_id);
++ return -ENXIO;
++ }
++ dev_err(&client->dev, "%s: chip identifier, got 0x%x\n",
++ __func__, chip_id);
++
++ return 0;
++}
++
++static int sc2235_probe(struct i2c_client *client)
++{
++ struct device *dev = &client->dev;
++ struct fwnode_handle *endpoint;
++ struct sc2235_dev *sensor;
++ struct v4l2_mbus_framefmt *fmt;
++ u32 rotation;
++ int ret;
++
++ sensor = devm_kzalloc(dev, sizeof(*sensor), GFP_KERNEL);
++ if (!sensor)
++ return -ENOMEM;
++
++ sensor->i2c_client = client;
++
++ fmt = &sensor->fmt;
++ fmt->code = MEDIA_BUS_FMT_SBGGR10_1X10;
++ fmt->colorspace = V4L2_COLORSPACE_SRGB;
++ fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->colorspace);
++ fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE;
++ fmt->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(fmt->colorspace);
++ fmt->width = 1920;
++ fmt->height = 1080;
++ fmt->field = V4L2_FIELD_NONE;
++ sensor->frame_interval.numerator = 1;
++ sensor->frame_interval.denominator = sc2235_framerates[SC2235_30_FPS];
++ sensor->current_fr = SC2235_30_FPS;
++ sensor->current_mode =
++ &sc2235_mode_data[SC2235_MODE_1080P_1920_1080];
++ sensor->last_mode = sensor->current_mode;
++
++ /* optional indication of physical rotation of sensor */
++ ret = fwnode_property_read_u32(dev_fwnode(&client->dev), "rotation",
++ &rotation);
++ if (!ret) {
++ switch (rotation) {
++ case 180:
++ sensor->upside_down = true;
++ fallthrough;
++ case 0:
++ break;
++ default:
++ dev_warn(dev, "%u degrees rotation is not supported, ignoring...\n",
++ rotation);
++ }
++ }
++
++ endpoint = fwnode_graph_get_next_endpoint(dev_fwnode(&client->dev),
++ NULL);
++ if (!endpoint) {
++ dev_err(dev, "endpoint node not found\n");
++ return -EINVAL;
++ }
++
++ ret = v4l2_fwnode_endpoint_parse(endpoint, &sensor->ep);
++ fwnode_handle_put(endpoint);
++ if (ret) {
++ dev_err(dev, "Could not parse endpoint\n");
++ return ret;
++ }
++
++ if (sensor->ep.bus_type != V4L2_MBUS_PARALLEL) {
++ dev_err(dev, "Unsupported bus type %d\n", sensor->ep.bus_type);
++ return -EINVAL;
++ }
++
++ /* get system clock (xclk) */
++ sensor->xclk = devm_clk_get(dev, "xclk");
++ if (IS_ERR(sensor->xclk)) {
++ dev_err(dev, "failed to get xclk\n");
++ return PTR_ERR(sensor->xclk);
++ }
++
++ sensor->xclk_freq = clk_get_rate(sensor->xclk);
++ if (sensor->xclk_freq < SC2235_XCLK_MIN ||
++ sensor->xclk_freq > SC2235_XCLK_MAX) {
++ dev_err(dev, "xclk frequency out of range: %d Hz\n",
++ sensor->xclk_freq);
++ return -EINVAL;
++ }
++
++ sensor->pwdn_gpio = devm_gpiod_get_optional(dev, "powerdown",
++ GPIOD_OUT_HIGH);
++ if (IS_ERR(sensor->pwdn_gpio))
++ return PTR_ERR(sensor->pwdn_gpio);
++
++ sensor->reset_gpio = devm_gpiod_get_optional(dev, "reset",
++ GPIOD_OUT_HIGH);
++ if (IS_ERR(sensor->reset_gpio))
++ return PTR_ERR(sensor->reset_gpio);
++
++ v4l2_i2c_subdev_init(&sensor->sd, client, &sc2235_subdev_ops);
++
++ sensor->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
++ V4L2_SUBDEV_FL_HAS_EVENTS;
++ sensor->pad.flags = MEDIA_PAD_FL_SOURCE;
++ sensor->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
++ ret = media_entity_pads_init(&sensor->sd.entity, 1, &sensor->pad);
++ if (ret)
++ return ret;
++
++ ret = sc2235_get_regulators(sensor);
++ if (ret)
++ return ret;
++ mutex_init(&sensor->lock);
++
++ ret = sc2235_set_power_on(dev);
++ if (ret) {
++ dev_err(dev, "failed to power on\n");
++ goto entity_cleanup;
++ }
++
++ ret = sc2235_check_chip_id(sensor);
++ if (ret)
++ goto entity_power_off;
++
++ ret = sc2235_init_controls(sensor);
++ if (ret)
++ goto entity_power_off;
++
++ ret = v4l2_async_register_subdev_sensor(&sensor->sd);
++ if (ret)
++ goto free_ctrls;
++
++ pm_runtime_set_active(dev);
++ pm_runtime_enable(dev);
++
++ return 0;
++
++free_ctrls:
++ v4l2_ctrl_handler_free(&sensor->ctrls.handler);
++entity_power_off:
++ sc2235_set_power_off(dev);
++entity_cleanup:
++ media_entity_cleanup(&sensor->sd.entity);
++ mutex_destroy(&sensor->lock);
++ return ret;
++}
++
++static void sc2235_remove(struct i2c_client *client)
++{
++ struct v4l2_subdev *sd = i2c_get_clientdata(client);
++ struct sc2235_dev *sensor = to_sc2235_dev(sd);
++
++ v4l2_async_unregister_subdev(&sensor->sd);
++ media_entity_cleanup(&sensor->sd.entity);
++ v4l2_ctrl_handler_free(&sensor->ctrls.handler);
++ mutex_destroy(&sensor->lock);
++
++ pm_runtime_disable(&client->dev);
++ if (!pm_runtime_status_suspended(&client->dev))
++ sc2235_set_power_off(&client->dev);
++ pm_runtime_set_suspended(&client->dev);
++}
++
++static const struct i2c_device_id sc2235_id[] = {
++ { "sc2235", 0 },
++ {},
++};
++MODULE_DEVICE_TABLE(i2c, sc2235_id);
++
++static const struct of_device_id sc2235_dt_ids[] = {
++ { .compatible = "smartsens,sc2235" },
++ { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, sc2235_dt_ids);
++
++static const struct dev_pm_ops sc2235_pm_ops = {
++ SET_RUNTIME_PM_OPS(sc2235_set_power_off, sc2235_set_power_on, NULL)
++};
++
++static struct i2c_driver sc2235_i2c_driver = {
++ .driver = {
++ .name = "sc2235",
++ .of_match_table = sc2235_dt_ids,
++ .pm = &sc2235_pm_ops,
++ },
++ .id_table = sc2235_id,
++ .probe = sc2235_probe,
++ .remove = sc2235_remove,
++};
++
++module_i2c_driver(sc2235_i2c_driver);
++
++MODULE_DESCRIPTION("SC2235 Camera Subdev Driver");
++MODULE_LICENSE("GPL");
+--- /dev/null
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_common.h
+@@ -0,0 +1,185 @@
++/* SPDX-License-Identifier: GPL-2.0
++ *
++ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
++ *
++ */
++
++#ifndef STF_COMMON_H
++#define STF_COMMON_H
++
++#include <linux/kern_levels.h>
++
++// #define STF_DEBUG
++
++// #define USE_CSIDPHY_ONE_CLK_MODE 1
++
++enum {
++ ST_DVP = 0x0001,
++ ST_CSIPHY = 0x0002,
++ ST_CSI = 0x0004,
++ ST_ISP = 0x0008,
++ ST_VIN = 0x0010,
++ ST_VIDEO = 0x0020,
++ ST_CAMSS = 0x0040,
++ ST_SENSOR = 0x0080,
++};
++
++enum {
++ ST_NONE = 0x00,
++ ST_ERR = 0x01,
++ ST_WARN = 0x02,
++ ST_INFO = 0x03,
++ ST_DEBUG = 0x04,
++};
++
++extern unsigned int stdbg_level;
++extern unsigned int stdbg_mask;
++
++#define ST_MODULE2STRING(__module) ({ \
++ char *__str; \
++ \
++ switch (__module) { \
++ case ST_DVP: \
++ __str = "st_dvp"; \
++ break; \
++ case ST_CSIPHY: \
++ __str = "st_csiphy"; \
++ break; \
++ case ST_CSI: \
++ __str = "st_csi"; \
++ break; \
++ case ST_ISP: \
++ __str = "st_isp"; \
++ break; \
++ case ST_VIN: \
++ __str = "st_vin"; \
++ break; \
++ case ST_VIDEO: \
++ __str = "st_video"; \
++ break; \
++ case ST_CAMSS: \
++ __str = "st_camss"; \
++ break; \
++ case ST_SENSOR: \
++ __str = "st_sensor"; \
++ break; \
++ default: \
++ __str = "unknow"; \
++ break; \
++ } \
++ \
++ __str; \
++ })
++
++#define st_debug(module, __fmt, arg...) \
++ do { \
++ if (stdbg_level > ST_INFO) { \
++ if (stdbg_mask & module) \
++ pr_err("[%s] debug: " __fmt, \
++ ST_MODULE2STRING(module), \
++ ## arg); \
++ } \
++ } while (0)
++
++#define st_info(module, __fmt, arg...) \
++ do { \
++ if (stdbg_level > ST_WARN) { \
++ if (stdbg_mask & module) \
++ pr_err("[%s] info: " __fmt, \
++ ST_MODULE2STRING(module), \
++ ## arg); \
++ } \
++ } while (0)
++
++#define st_warn(module, __fmt, arg...) \
++ do { \
++ if (stdbg_level > ST_ERR) { \
++ if (stdbg_mask & module) \
++ pr_err("[%s] warn: " __fmt, \
++ ST_MODULE2STRING(module), \
++ ## arg); \
++ } \
++ } while (0)
++
++#define st_err(module, __fmt, arg...) \
++ do { \
++ if (stdbg_level > ST_NONE) { \
++ if (stdbg_mask & module) \
++ pr_err("[%s] error: " __fmt, \
++ ST_MODULE2STRING(module), \
++ ## arg); \
++ } \
++ } while (0)
++
++#define st_err_ratelimited(module, fmt, ...) \
++ do { \
++ static DEFINE_RATELIMIT_STATE(_rs, \
++ DEFAULT_RATELIMIT_INTERVAL, \
++ DEFAULT_RATELIMIT_BURST); \
++ if (__ratelimit(&_rs) && (stdbg_level > ST_NONE)) { \
++ if (stdbg_mask & module) \
++ pr_err("[%s] error: " fmt, \
++ ST_MODULE2STRING(module), \
++ ##__VA_ARGS__); \
++ } \
++ } while (0)
++
++#define set_bits(p, v, b, m) (((p) & ~(m)) | ((v) << (b)))
++
++static inline u32 reg_read(void __iomem *base, u32 reg)
++{
++ return ioread32(base + reg);
++}
++
++static inline void reg_write(void __iomem *base, u32 reg, u32 val)
++{
++ iowrite32(val, base + reg);
++}
++
++static inline void reg_set_bit(void __iomem *base, u32 reg, u32 mask, u32 val)
++{
++ u32 value;
++
++ value = ioread32(base + reg) & ~mask;
++ val &= mask;
++ val |= value;
++ iowrite32(val, base + reg);
++}
++
++static inline void reg_set(void __iomem *base, u32 reg, u32 mask)
++{
++ iowrite32(ioread32(base + reg) | mask, base + reg);
++}
++
++static inline void reg_clear(void __iomem *base, u32 reg, u32 mask)
++{
++ iowrite32(ioread32(base + reg) & ~mask, base + reg);
++}
++
++static inline void reg_set_highest_bit(void __iomem *base, u32 reg)
++{
++ u32 val;
++
++ val = ioread32(base + reg);
++ val &= ~(0x1 << 31);
++ val |= (0x1 & 0x1) << 31;
++ iowrite32(val, base + reg);
++}
++
++static inline void reg_clr_highest_bit(void __iomem *base, u32 reg)
++{
++ u32 val;
++
++ val = ioread32(base + reg);
++ val &= ~(0x1 << 31);
++ val |= (0x0 & 0x1) << 31;
++ iowrite32(val, base + reg);
++}
++
++static inline void print_reg(unsigned int module, void __iomem *base, u32 reg)
++{
++ //st_debug(module, "REG 0x%x = 0x%x\n",
++ // base + reg, ioread32(base + reg));
++}
++
++#endif /* STF_COMMON_H */
+--- /dev/null
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_csi.c
+@@ -0,0 +1,465 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
++ *
++ */
++
++#include "stfcamss.h"
++#include <media/v4l2-async.h>
++#include <media/v4l2-ctrls.h>
++#include <media/v4l2-device.h>
++#include <media/v4l2-event.h>
++#include <media/v4l2-fwnode.h>
++#include <media/v4l2-subdev.h>
++
++static const struct csi_format csi_formats_sink[] = {
++ { MEDIA_BUS_FMT_UYVY8_2X8, 16},
++ { MEDIA_BUS_FMT_SRGGB10_1X10, 10},
++ { MEDIA_BUS_FMT_SGRBG10_1X10, 10},
++ { MEDIA_BUS_FMT_SGBRG10_1X10, 10},
++ { MEDIA_BUS_FMT_SBGGR10_1X10, 10},
++};
++
++/* this bpp need see csi controllor */
++static const struct csi_format csi_formats_src[] = {
++ { MEDIA_BUS_FMT_AYUV8_1X32, 32},
++ { MEDIA_BUS_FMT_SRGGB10_1X10, 16},
++ { MEDIA_BUS_FMT_SGRBG10_1X10, 16},
++ { MEDIA_BUS_FMT_SGBRG10_1X10, 16},
++ { MEDIA_BUS_FMT_SBGGR10_1X10, 16},
++};
++
++static int csi_find_format(u32 code,
++ const struct csi_format *formats,
++ unsigned int nformats)
++{
++ int i;
++
++ for (i = 0; i < nformats; i++)
++ if (formats[i].code == code)
++ return i;
++ return -EINVAL;
++}
++
++int stf_csi_subdev_init(struct stfcamss *stfcamss)
++{
++ struct stf_csi_dev *csi_dev = stfcamss->csi_dev;
++
++ csi_dev->s_type = SENSOR_VIN;
++ csi_dev->hw_ops = &csi_ops;
++ csi_dev->stfcamss = stfcamss;
++ csi_dev->formats_sink = csi_formats_sink;
++ csi_dev->nformats_sink = ARRAY_SIZE(csi_formats_sink);
++ csi_dev->formats_src = csi_formats_src;
++ csi_dev->nformats_src = ARRAY_SIZE(csi_formats_src);
++ mutex_init(&csi_dev->stream_lock);
++ return 0;
++}
++
++static int csi_set_power(struct v4l2_subdev *sd, int on)
++{
++ struct stf_csi_dev *csi_dev = v4l2_get_subdevdata(sd);
++
++ csi_dev->hw_ops->csi_power_on(csi_dev, (u8)on);
++ return 0;
++}
++
++static struct v4l2_mbus_framefmt *
++__csi_get_format(struct stf_csi_dev *csi_dev,
++ struct v4l2_subdev_state *state,
++ unsigned int pad,
++ enum v4l2_subdev_format_whence which)
++{
++ if (which == V4L2_SUBDEV_FORMAT_TRY)
++ return v4l2_subdev_get_try_format(&csi_dev->subdev, state, pad);
++
++ return &csi_dev->fmt[pad];
++}
++
++static u32 code_to_data_type(int code)
++{
++ switch (code) {
++ case MEDIA_BUS_FMT_SRGGB10_1X10:
++ case MEDIA_BUS_FMT_SGRBG10_1X10:
++ case MEDIA_BUS_FMT_SGBRG10_1X10:
++ case MEDIA_BUS_FMT_SBGGR10_1X10:
++ return 0x2b;
++ case MEDIA_BUS_FMT_UYVY8_2X8:
++ return 0x1E;
++ default:
++ return 0x2b;
++ }
++}
++
++static int csi_set_stream(struct v4l2_subdev *sd, int enable)
++{
++ struct stf_csi_dev *csi_dev = v4l2_get_subdevdata(sd);
++ struct v4l2_mbus_framefmt *format;
++ int ret = 0;
++ u32 code, width, dt;
++ u8 bpp;
++
++ format = __csi_get_format(csi_dev, NULL, STF_CSI_PAD_SINK,
++ V4L2_SUBDEV_FORMAT_ACTIVE);
++ if (format == NULL)
++ return -EINVAL;
++
++ width = format->width;
++
++ ret = csi_find_format(format->code,
++ csi_dev->formats_sink,
++ csi_dev->nformats_sink);
++ if (ret < 0)
++ return ret;
++
++ code = csi_dev->formats_sink[ret].code;
++ bpp = csi_dev->formats_src[ret].bpp;
++ dt = code_to_data_type(code);
++
++ mutex_lock(&csi_dev->stream_lock);
++ if (enable) {
++ if (csi_dev->stream_count == 0) {
++ csi_dev->hw_ops->csi_clk_enable(csi_dev);
++ csi_dev->hw_ops->csi_stream_set(csi_dev, enable, dt, width, bpp);
++ }
++ csi_dev->stream_count++;
++ } else {
++ if (csi_dev->stream_count == 0)
++ goto exit;
++ if (csi_dev->stream_count == 1) {
++ csi_dev->hw_ops->csi_stream_set(csi_dev, enable, dt, width, bpp);
++ csi_dev->hw_ops->csi_clk_disable(csi_dev);
++ }
++ csi_dev->stream_count--;
++ }
++exit:
++ mutex_unlock(&csi_dev->stream_lock);
++ return 0;
++}
++
++static void csi_try_format(struct stf_csi_dev *csi_dev,
++ struct v4l2_subdev_state *state,
++ unsigned int pad,
++ struct v4l2_mbus_framefmt *fmt,
++ enum v4l2_subdev_format_whence which)
++{
++ unsigned int i;
++
++ switch (pad) {
++ case STF_CSI_PAD_SINK:
++ /* Set format on sink pad */
++
++ for (i = 0; i < csi_dev->nformats_sink; i++)
++ if (fmt->code == csi_dev->formats_sink[i].code)
++ break;
++
++ if (i >= csi_dev->nformats_sink)
++ fmt->code = csi_dev->formats_sink[0].code;
++
++ fmt->width = clamp_t(u32,
++ fmt->width,
++ STFCAMSS_FRAME_MIN_WIDTH,
++ STFCAMSS_FRAME_MAX_WIDTH);
++ fmt->height = clamp_t(u32,
++ fmt->height,
++ STFCAMSS_FRAME_MIN_HEIGHT,
++ STFCAMSS_FRAME_MAX_HEIGHT);
++
++
++ fmt->field = V4L2_FIELD_NONE;
++ fmt->colorspace = V4L2_COLORSPACE_SRGB;
++ fmt->flags = 0;
++
++ break;
++
++ case STF_CSI_PAD_SRC:
++ /* Set format on src pad */
++
++ for (i = 0; i < csi_dev->nformats_src; i++)
++ if (fmt->code == csi_dev->formats_src[i].code)
++ break;
++
++ if (i >= csi_dev->nformats_src)
++ fmt->code = csi_dev->formats_src[0].code;
++
++ fmt->width = clamp_t(u32,
++ fmt->width,
++ STFCAMSS_FRAME_MIN_WIDTH,
++ STFCAMSS_FRAME_MAX_WIDTH);
++ fmt->height = clamp_t(u32,
++ fmt->height,
++ STFCAMSS_FRAME_MIN_HEIGHT,
++ STFCAMSS_FRAME_MAX_HEIGHT);
++
++ fmt->field = V4L2_FIELD_NONE;
++ fmt->colorspace = V4L2_COLORSPACE_SRGB;
++ fmt->flags = 0;
++
++ break;
++ }
++}
++
++static int csi_enum_mbus_code(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_mbus_code_enum *code)
++{
++ struct stf_csi_dev *csi_dev = v4l2_get_subdevdata(sd);
++
++ if (code->index >= csi_dev->nformats_sink)
++ return -EINVAL;
++ if (code->pad == STF_CSI_PAD_SINK) {
++ code->code = csi_dev->formats_sink[code->index].code;
++ } else {
++ struct v4l2_mbus_framefmt *sink_fmt;
++
++ sink_fmt = __csi_get_format(csi_dev, state, STF_CSI_PAD_SINK,
++ code->which);
++
++ code->code = sink_fmt->code;
++ if (!code->code)
++ return -EINVAL;
++ }
++ code->flags = 0;
++
++ return 0;
++}
++
++static int csi_enum_frame_size(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_frame_size_enum *fse)
++{
++ struct stf_csi_dev *csi_dev = v4l2_get_subdevdata(sd);
++ struct v4l2_mbus_framefmt format;
++
++ if (fse->index != 0)
++ return -EINVAL;
++
++ format.code = fse->code;
++ format.width = 1;
++ format.height = 1;
++ csi_try_format(csi_dev, state, fse->pad, &format, fse->which);
++ fse->min_width = format.width;
++ fse->min_height = format.height;
++
++ if (format.code != fse->code)
++ return -EINVAL;
++
++ format.code = fse->code;
++ format.width = -1;
++ format.height = -1;
++ csi_try_format(csi_dev, state, fse->pad, &format, fse->which);
++ fse->max_width = format.width;
++ fse->max_height = format.height;
++
++ return 0;
++}
++
++static int csi_get_format(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_format *fmt)
++{
++ struct stf_csi_dev *csi_dev = v4l2_get_subdevdata(sd);
++ struct v4l2_mbus_framefmt *format;
++
++ format = __csi_get_format(csi_dev, state, fmt->pad, fmt->which);
++ if (format == NULL)
++ return -EINVAL;
++
++ fmt->format = *format;
++
++ return 0;
++}
++
++static int csi_set_format(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_format *fmt)
++{
++ struct stf_csi_dev *csi_dev = v4l2_get_subdevdata(sd);
++ struct v4l2_mbus_framefmt *format;
++ struct v4l2_mbus_framefmt *format_src;
++ int ret;
++
++ format = __csi_get_format(csi_dev, state, fmt->pad, fmt->which);
++ if (format == NULL)
++ return -EINVAL;
++
++ mutex_lock(&csi_dev->stream_lock);
++ if (csi_dev->stream_count) {
++ fmt->format = *format;
++ mutex_unlock(&csi_dev->stream_lock);
++ goto out;
++ } else {
++ csi_try_format(csi_dev, state, fmt->pad, &fmt->format, fmt->which);
++ *format = fmt->format;
++ }
++ mutex_unlock(&csi_dev->stream_lock);
++
++ if (fmt->pad == STF_CSI_PAD_SINK) {
++ format_src = __csi_get_format(csi_dev, state, STF_DVP_PAD_SRC,
++ fmt->which);
++
++ ret = csi_find_format(format->code, csi_dev->formats_sink,
++ csi_dev->nformats_sink);
++ if (ret < 0)
++ return ret;
++
++ format_src->code = csi_dev->formats_src[ret].code;
++ csi_try_format(csi_dev, state, STF_DVP_PAD_SRC, format_src,
++ fmt->which);
++ }
++out:
++ return 0;
++}
++
++static int csi_init_formats(struct v4l2_subdev *sd,
++ struct v4l2_subdev_fh *fh)
++{
++ struct v4l2_subdev_format format = {
++ .pad = STF_CSI_PAD_SINK,
++ .which = fh ? V4L2_SUBDEV_FORMAT_TRY :
++ V4L2_SUBDEV_FORMAT_ACTIVE,
++ .format = {
++ .code = MEDIA_BUS_FMT_RGB565_2X8_LE,
++ .width = 1920,
++ .height = 1080
++ }
++ };
++
++ return csi_set_format(sd, fh ? fh->state : NULL, &format);
++}
++
++static int csi_link_setup(struct media_entity *entity,
++ const struct media_pad *local,
++ const struct media_pad *remote, u32 flags)
++{
++ if ((local->flags & MEDIA_PAD_FL_SOURCE) &&
++ (flags & MEDIA_LNK_FL_ENABLED)) {
++ struct v4l2_subdev *sd;
++ struct stf_csi_dev *csi_dev;
++ struct vin_line *line;
++
++ if (media_pad_remote_pad_first(local))
++ return -EBUSY;
++
++ sd = media_entity_to_v4l2_subdev(entity);
++ csi_dev = v4l2_get_subdevdata(sd);
++
++ sd = media_entity_to_v4l2_subdev(remote->entity);
++ line = v4l2_get_subdevdata(sd);
++ if (line->sdev_type == VIN_DEV_TYPE)
++ csi_dev->s_type = SENSOR_VIN;
++ if (line->sdev_type == ISP_DEV_TYPE)
++ csi_dev->s_type = SENSOR_ISP;
++ st_info(ST_CSI, "CSI device sensor type: %d\n", csi_dev->s_type);
++ }
++
++ if ((local->flags & MEDIA_PAD_FL_SINK) &&
++ (flags & MEDIA_LNK_FL_ENABLED)) {
++ struct v4l2_subdev *sd;
++ struct stf_csi_dev *csi_dev;
++ struct stf_csiphy_dev *csiphy_dev;
++
++ if (media_pad_remote_pad_first(local))
++ return -EBUSY;
++
++ sd = media_entity_to_v4l2_subdev(entity);
++ csi_dev = v4l2_get_subdevdata(sd);
++
++ sd = media_entity_to_v4l2_subdev(remote->entity);
++ csiphy_dev = v4l2_get_subdevdata(sd);
++
++ st_info(ST_CSI, "CSI0 link to csiphy0\n");
++ }
++
++ return 0;
++}
++
++static const struct v4l2_subdev_core_ops csi_core_ops = {
++ .s_power = csi_set_power,
++};
++
++static const struct v4l2_subdev_video_ops csi_video_ops = {
++ .s_stream = csi_set_stream,
++};
++
++static const struct v4l2_subdev_pad_ops csi_pad_ops = {
++ .enum_mbus_code = csi_enum_mbus_code,
++ .enum_frame_size = csi_enum_frame_size,
++ .get_fmt = csi_get_format,
++ .set_fmt = csi_set_format,
++};
++
++static const struct v4l2_subdev_ops csi_v4l2_ops = {
++ .core = &csi_core_ops,
++ .video = &csi_video_ops,
++ .pad = &csi_pad_ops,
++};
++
++static const struct v4l2_subdev_internal_ops csi_v4l2_internal_ops = {
++ .open = csi_init_formats,
++};
++
++static const struct media_entity_operations csi_media_ops = {
++ .link_setup = csi_link_setup,
++ .link_validate = v4l2_subdev_link_validate,
++};
++
++int stf_csi_register(struct stf_csi_dev *csi_dev, struct v4l2_device *v4l2_dev)
++{
++ struct v4l2_subdev *sd = &csi_dev->subdev;
++ struct device *dev = csi_dev->stfcamss->dev;
++ struct media_pad *pads = csi_dev->pads;
++ int ret;
++
++ csi_dev->mipirx_1p8 = devm_regulator_get(dev, "mipirx_1p8");
++ if (IS_ERR(csi_dev->mipirx_1p8))
++ return PTR_ERR(csi_dev->mipirx_1p8);
++
++ csi_dev->mipirx_0p9 = devm_regulator_get(dev, "mipirx_0p9");
++ if (IS_ERR(csi_dev->mipirx_0p9))
++ return PTR_ERR(csi_dev->mipirx_0p9);
++
++ v4l2_subdev_init(sd, &csi_v4l2_ops);
++ sd->internal_ops = &csi_v4l2_internal_ops;
++ sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
++ snprintf(sd->name, ARRAY_SIZE(sd->name), "%s%d",
++ STF_CSI_NAME, 0);
++ v4l2_set_subdevdata(sd, csi_dev);
++
++ ret = csi_init_formats(sd, NULL);
++ if (ret < 0) {
++ dev_err(dev, "Failed to init format: %d\n", ret);
++ return ret;
++ }
++
++ pads[STF_CSI_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
++ pads[STF_CSI_PAD_SRC].flags = MEDIA_PAD_FL_SOURCE;
++
++ sd->entity.function = MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER;
++ sd->entity.ops = &csi_media_ops;
++ ret = media_entity_pads_init(&sd->entity, STF_CSI_PADS_NUM, pads);
++ if (ret < 0) {
++ dev_err(dev, "Failed to init media entity: %d\n", ret);
++ return ret;
++ }
++
++ ret = v4l2_device_register_subdev(v4l2_dev, sd);
++ if (ret < 0) {
++ dev_err(dev, "Failed to register subdev: %d\n", ret);
++ goto err_sreg;
++ }
++
++ return 0;
++
++err_sreg:
++ media_entity_cleanup(&sd->entity);
++ return ret;
++}
++
++int stf_csi_unregister(struct stf_csi_dev *csi_dev)
++{
++ v4l2_device_unregister_subdev(&csi_dev->subdev);
++ media_entity_cleanup(&csi_dev->subdev.entity);
++ mutex_destroy(&csi_dev->stream_lock);
++ return 0;
++}
+--- /dev/null
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_csi.h
+@@ -0,0 +1,61 @@
++/* SPDX-License-Identifier: GPL-2.0
++ *
++ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
++ *
++ */
++
++#ifndef STF_CSI_H
++#define STF_CSI_H
++
++#include <linux/regulator/consumer.h>
++#include <media/v4l2-subdev.h>
++#include <media/v4l2-device.h>
++#include <media/media-entity.h>
++#include <video/stf-vin.h>
++
++#define STF_CSI_NAME "stf_csi"
++
++#define STF_CSI_PAD_SINK 0
++#define STF_CSI_PAD_SRC 1
++#define STF_CSI_PADS_NUM 2
++
++struct csi_format {
++ u32 code;
++ u8 bpp;
++};
++
++struct stf_csi_dev;
++
++struct csi_hw_ops {
++ int (*csi_power_on)(struct stf_csi_dev *csi_dev, u8 on);
++ int (*csi_clk_enable)(struct stf_csi_dev *csi_dev);
++ int (*csi_clk_disable)(struct stf_csi_dev *csi_dev);
++ int (*csi_stream_set)(struct stf_csi_dev *csi_dev, int on,
++ u32 dt, u32 width, u8 bpp);
++};
++
++struct stf_csi_dev {
++ struct stfcamss *stfcamss;
++ enum sensor_type s_type;
++ struct v4l2_subdev subdev;
++ struct media_pad pads[STF_CSI_PADS_NUM];
++ struct v4l2_mbus_framefmt fmt[STF_CSI_PADS_NUM];
++ const struct csi_format *formats_sink;
++ unsigned int nformats_sink;
++ const struct csi_format *formats_src;
++ unsigned int nformats_src;
++ struct csi_hw_ops *hw_ops;
++ struct mutex stream_lock;
++ int stream_count;
++ struct regulator *mipirx_1p8;
++ struct regulator *mipirx_0p9;
++};
++
++extern int stf_csi_subdev_init(struct stfcamss *stfcamss);
++extern int stf_csi_register(struct stf_csi_dev *csi_dev,
++ struct v4l2_device *v4l2_dev);
++extern int stf_csi_unregister(struct stf_csi_dev *csi_dev);
++extern struct csi_hw_ops csi_ops;
++extern void dump_csi_reg(void *__iomem csibase);
++
++#endif /* STF_CSI_H */
+--- /dev/null
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_csi_hw_ops.c
+@@ -0,0 +1,310 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
++ *
++ */
++
++#include "stfcamss.h"
++#include <linux/regmap.h>
++
++#define CSI2RX_DEVICE_CFG_REG 0x000
++
++#define CSI2RX_SOFT_RESET_REG 0x004
++#define CSI2RX_SOFT_RESET_PROTOCOL BIT(1)
++#define CSI2RX_SOFT_RESET_FRONT BIT(0)
++
++#define CSI2RX_DPHY_LANE_CONTROL 0x040
++
++#define CSI2RX_STATIC_CFG_REG 0x008
++#define CSI2RX_STATIC_CFG_DLANE_MAP(llane, plane) \
++ ((plane) << (16 + (llane) * 4))
++#define CSI2RX_STATIC_CFG_LANES_MASK GENMASK(11, 8)
++
++#define CSI2RX_STREAM_BASE(n) (((n) + 1) * 0x100)
++
++#define CSI2RX_STREAM_CTRL_REG(n) (CSI2RX_STREAM_BASE(n) + 0x000)
++#define CSI2RX_STREAM_CTRL_START BIT(0)
++
++#define CSI2RX_STREAM_DATA_CFG_REG(n) (CSI2RX_STREAM_BASE(n) + 0x008)
++#define CSI2RX_STREAM_DATA_CFG_EN_VC_SELECT BIT(31)
++#define CSI2RX_STREAM_DATA_CFG_EN_DATA_TYPE_0 BIT(7)
++#define CSI2RX_STREAM_DATA_CFG_VC_SELECT(n) BIT((n) + 16)
++
++#define CSI2RX_STREAM_CFG_REG(n) (CSI2RX_STREAM_BASE(n) + 0x00c)
++#define CSI2RX_STREAM_CFG_FIFO_MODE_LARGE_BUF (1 << 8)
++
++#define CSI2RX_LANES_MAX 4
++#define CSI2RX_STREAMS_MAX 4
++
++static int stf_csi_power_on(struct stf_csi_dev *csi_dev, u8 on)
++{
++ struct stfcamss *stfcamss = csi_dev->stfcamss;
++ int ret;
++
++ if (on) {
++ ret = regulator_enable(csi_dev->mipirx_1p8);
++ if (ret) {
++ st_err(ST_CSI, "Cannot enable mipirx_1p8 regulator\n");
++ goto err_1p8;
++ }
++
++ ret = regulator_enable(csi_dev->mipirx_0p9);
++ if (ret) {
++ st_err(ST_CSI, "Cannot enable mipirx_0p9 regulator\n");
++ goto err_0p9;
++ }
++ } else {
++ regulator_disable(csi_dev->mipirx_1p8);
++ regulator_disable(csi_dev->mipirx_0p9);
++ }
++
++ regmap_update_bits(stfcamss->stf_aon_syscon, stfcamss->aon_gp_reg,
++ BIT(31), BIT(31));
++
++ return 0;
++
++err_0p9:
++ regulator_disable(csi_dev->mipirx_1p8);
++err_1p8:
++ return ret;
++
++}
++
++static int stf_csi_clk_enable(struct stf_csi_dev *csi_dev)
++{
++ struct stfcamss *stfcamss = csi_dev->stfcamss;
++
++ clk_set_rate(stfcamss->sys_clk[STFCLK_MIPI_RX0_PXL].clk, 198000000);
++ clk_prepare_enable(stfcamss->sys_clk[STFCLK_PIXEL_CLK_IF0].clk);
++ clk_prepare_enable(stfcamss->sys_clk[STFCLK_PIXEL_CLK_IF1].clk);
++ clk_prepare_enable(stfcamss->sys_clk[STFCLK_PIXEL_CLK_IF2].clk);
++ clk_prepare_enable(stfcamss->sys_clk[STFCLK_PIXEL_CLK_IF3].clk);
++
++ reset_control_deassert(stfcamss->sys_rst[STFRST_PIXEL_CLK_IF0].rstc);
++ reset_control_deassert(stfcamss->sys_rst[STFRST_PIXEL_CLK_IF1].rstc);
++ reset_control_deassert(stfcamss->sys_rst[STFRST_PIXEL_CLK_IF2].rstc);
++ reset_control_deassert(stfcamss->sys_rst[STFRST_PIXEL_CLK_IF3].rstc);
++
++ switch (csi_dev->s_type) {
++ case SENSOR_VIN:
++ reset_control_deassert(stfcamss->sys_rst[STFRST_AXIWR].rstc);
++ clk_set_parent(stfcamss->sys_clk[STFCLK_AXIWR].clk,
++ stfcamss->sys_clk[STFCLK_MIPI_RX0_PXL].clk);
++ break;
++ case SENSOR_ISP:
++ clk_set_parent(stfcamss->sys_clk[STFCLK_WRAPPER_CLK_C].clk,
++ stfcamss->sys_clk[STFCLK_MIPI_RX0_PXL].clk);
++ break;
++ }
++
++ return 0;
++}
++
++static int stf_csi_clk_disable(struct stf_csi_dev *csi_dev)
++{
++ struct stfcamss *stfcamss = csi_dev->stfcamss;
++
++ switch (csi_dev->s_type) {
++ case SENSOR_VIN:
++ reset_control_assert(stfcamss->sys_rst[STFRST_AXIWR].rstc);
++ break;
++ case SENSOR_ISP:
++ break;
++ }
++
++ reset_control_assert(stfcamss->sys_rst[STFRST_PIXEL_CLK_IF3].rstc);
++ reset_control_assert(stfcamss->sys_rst[STFRST_PIXEL_CLK_IF2].rstc);
++ reset_control_assert(stfcamss->sys_rst[STFRST_PIXEL_CLK_IF1].rstc);
++ reset_control_assert(stfcamss->sys_rst[STFRST_PIXEL_CLK_IF0].rstc);
++
++ clk_disable_unprepare(stfcamss->sys_clk[STFCLK_PIXEL_CLK_IF3].clk);
++ clk_disable_unprepare(stfcamss->sys_clk[STFCLK_PIXEL_CLK_IF2].clk);
++ clk_disable_unprepare(stfcamss->sys_clk[STFCLK_PIXEL_CLK_IF1].clk);
++ clk_disable_unprepare(stfcamss->sys_clk[STFCLK_PIXEL_CLK_IF0].clk);
++
++ return 0;
++}
++
++static void csi2rx_reset(void *reg_base)
++{
++ writel(CSI2RX_SOFT_RESET_PROTOCOL | CSI2RX_SOFT_RESET_FRONT,
++ reg_base + CSI2RX_SOFT_RESET_REG);
++
++ udelay(10);
++
++ writel(0, reg_base + CSI2RX_SOFT_RESET_REG);
++}
++
++static int csi2rx_start(struct stf_csi_dev *csi_dev, void *reg_base, u32 dt)
++{
++ struct stfcamss *stfcamss = csi_dev->stfcamss;
++ struct csi2phy_cfg *csiphy =
++ stfcamss->csiphy_dev->csiphy;
++ unsigned int i;
++ unsigned long lanes_used = 0;
++ u32 reg;
++
++ if (!csiphy) {
++ st_err(ST_CSI, "csiphy0 config not exist\n");
++ return -EINVAL;
++ }
++
++ csi2rx_reset(reg_base);
++
++ reg = csiphy->num_data_lanes << 8;
++ for (i = 0; i < csiphy->num_data_lanes; i++) {
++#ifndef USE_CSIDPHY_ONE_CLK_MODE
++ reg |= CSI2RX_STATIC_CFG_DLANE_MAP(i, csiphy->data_lanes[i]);
++ set_bit(csiphy->data_lanes[i] - 1, &lanes_used);
++#else
++ reg |= CSI2RX_STATIC_CFG_DLANE_MAP(i, i + 1);
++ set_bit(i, &lanes_used);
++#endif
++ }
++
++ /*
++ * Even the unused lanes need to be mapped. In order to avoid
++ * to map twice to the same physical lane, keep the lanes used
++ * in the previous loop, and only map unused physical lanes to
++ * the rest of our logical lanes.
++ */
++ for (i = csiphy->num_data_lanes; i < CSI2RX_LANES_MAX; i++) {
++ unsigned int idx = find_first_zero_bit(&lanes_used,
++ CSI2RX_LANES_MAX);
++
++ set_bit(idx, &lanes_used);
++ reg |= CSI2RX_STATIC_CFG_DLANE_MAP(i, idx + 1);
++ }
++
++ writel(reg, reg_base + CSI2RX_STATIC_CFG_REG);
++
++ // 0x40 DPHY_LANE_CONTROL
++ reg = 0;
++#ifndef USE_CSIDPHY_ONE_CLK_MODE
++ for (i = 0; i < csiphy->num_data_lanes; i++)
++ reg |= 1 << (csiphy->data_lanes[i] - 1)
++ | 1 << (csiphy->data_lanes[i] + 11);
++#else
++ for (i = 0; i < csiphy->num_data_lanes; i++)
++ reg |= 1 << i | 1 << (i + 12); //data_clane
++#endif
++
++ reg |= 1 << 4 | 1 << 16; //clk_lane
++ writel(reg, reg_base + CSI2RX_DPHY_LANE_CONTROL);
++
++ /*
++ * Create a static mapping between the CSI virtual channels
++ * and the output stream.
++ *
++ * This should be enhanced, but v4l2 lacks the support for
++ * changing that mapping dynamically.
++ *
++ * We also cannot enable and disable independent streams here,
++ * hence the reference counting.
++ */
++ for (i = 0; i < CSI2RX_STREAMS_MAX; i++) {
++ writel(CSI2RX_STREAM_CFG_FIFO_MODE_LARGE_BUF,
++ reg_base + CSI2RX_STREAM_CFG_REG(i));
++
++ writel(CSI2RX_STREAM_DATA_CFG_EN_VC_SELECT |
++ CSI2RX_STREAM_DATA_CFG_VC_SELECT(i) |
++ CSI2RX_STREAM_DATA_CFG_EN_DATA_TYPE_0 | dt,
++ reg_base + CSI2RX_STREAM_DATA_CFG_REG(i));
++
++ writel(CSI2RX_STREAM_CTRL_START,
++ reg_base + CSI2RX_STREAM_CTRL_REG(i));
++ }
++
++ return 0;
++}
++
++static void csi2rx_stop(struct stf_csi_dev *csi_dev, void *reg_base)
++{
++ unsigned int i;
++
++ for (i = 0; i < CSI2RX_STREAMS_MAX; i++)
++ writel(0, reg_base + CSI2RX_STREAM_CTRL_REG(i));
++}
++
++static void csi_set_vin_axiwr_pix(struct stf_csi_dev *csi_dev, u32 width, u8 bpp)
++{
++ struct stf_vin_dev *vin = csi_dev->stfcamss->vin;
++ u32 value = 0;
++ int cnfg_axiwr_pix_ct = 64 / bpp;
++
++ if (cnfg_axiwr_pix_ct == 2)
++ value = 0;
++ else if (cnfg_axiwr_pix_ct == 4)
++ value = 1;
++ else if (cnfg_axiwr_pix_ct == 8)
++ value = 2;
++
++ reg_set_bit(vin->sysctrl_base, SYSCONSAIF_SYSCFG_28,
++ BIT(14)|BIT(13), value << 13); //u0_vin_cnfg_axiwr0_pix_ct
++ reg_set_bit(vin->sysctrl_base, SYSCONSAIF_SYSCFG_28,
++ BIT(12)|BIT(11)|BIT(10)|BIT(9)|BIT(8)|BIT(7)|BIT(6)|BIT(5)|BIT(4)|BIT(3)|BIT(2),
++ (width / cnfg_axiwr_pix_ct - 1)<<2); //u0_vin_cnfg_axiwr0_pix_cnt_end
++}
++
++static int stf_csi_stream_set(struct stf_csi_dev *csi_dev,
++ int on, u32 dt, u32 width, u8 bpp)
++{
++ struct stf_vin_dev *vin = csi_dev->stfcamss->vin;
++ void __iomem *reg_base = vin->csi2rx_base;
++
++ switch (csi_dev->s_type) {
++ case SENSOR_VIN:
++ reg_set_bit(vin->sysctrl_base, SYSCONSAIF_SYSCFG_20,
++ BIT(3)|BIT(2)|BIT(1)|BIT(0),
++ 0<<0); //u0_vin_cnfg_axiwr0_channel_sel
++ reg_set_bit(vin->sysctrl_base, SYSCONSAIF_SYSCFG_28,
++ BIT(16)|BIT(15),
++ 0<<15); //u0_vin_cnfg_axiwr0_pixel_high_bit_sel
++ csi_set_vin_axiwr_pix(csi_dev, width, bpp);
++ break;
++ case SENSOR_ISP:
++ reg_set_bit(vin->sysctrl_base, SYSCONSAIF_SYSCFG_36,
++ BIT(7)|BIT(6),
++ 0<<6); //u0_vin_cnfg_mipi_byte_en_isp
++ reg_set_bit(vin->sysctrl_base, SYSCONSAIF_SYSCFG_36,
++ BIT(11)|BIT(10)|BIT(9)|BIT(8),
++ 0<<8); //u0_vin_cnfg_mipi_channel_sel0
++ reg_set_bit(vin->sysctrl_base, SYSCONSAIF_SYSCFG_36,
++ BIT(16)|BIT(15)|BIT(14)|BIT(13),
++ 0<<13); //u0_vin_cnfg_pix_num
++
++ if (dt == 0x2b)
++ reg_set_bit(vin->sysctrl_base, SYSCONSAIF_SYSCFG_36,
++ BIT(12),
++ 1<<12); //u0_vin_cnfg_p_i_mipi_header_en0
++ break;
++ }
++
++ if (on)
++ csi2rx_start(csi_dev, reg_base, dt);
++ else
++ csi2rx_stop(csi_dev, reg_base);
++
++ return 0;
++}
++
++void dump_csi_reg(void *__iomem csibase)
++{
++ st_info(ST_CSI, "DUMP CSI register:\n");
++ print_reg(ST_CSI, csibase, 0x00);
++ print_reg(ST_CSI, csibase, 0x04);
++ print_reg(ST_CSI, csibase, 0x08);
++ print_reg(ST_CSI, csibase, 0x10);
++
++ print_reg(ST_CSI, csibase, 0x40);
++ print_reg(ST_CSI, csibase, 0x48);
++ print_reg(ST_CSI, csibase, 0x4c);
++ print_reg(ST_CSI, csibase, 0x50);
++}
++
++struct csi_hw_ops csi_ops = {
++ .csi_power_on = stf_csi_power_on,
++ .csi_clk_enable = stf_csi_clk_enable,
++ .csi_clk_disable = stf_csi_clk_disable,
++ .csi_stream_set = stf_csi_stream_set,
++};
+--- /dev/null
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_csiphy.c
+@@ -0,0 +1,357 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
++ *
++ */
++
++#include "stfcamss.h"
++#include <media/v4l2-async.h>
++#include <media/v4l2-ctrls.h>
++#include <media/v4l2-device.h>
++#include <media/v4l2-event.h>
++#include <media/v4l2-fwnode.h>
++#include <media/v4l2-subdev.h>
++
++static const struct csiphy_format csiphy_formats_st7110[] = {
++ { MEDIA_BUS_FMT_UYVY8_2X8, 16},
++ { MEDIA_BUS_FMT_SRGGB10_1X10, 10},
++ { MEDIA_BUS_FMT_SGRBG10_1X10, 10},
++ { MEDIA_BUS_FMT_SGBRG10_1X10, 10},
++ { MEDIA_BUS_FMT_SBGGR10_1X10, 10},
++};
++
++int stf_csiphy_subdev_init(struct stfcamss *stfcamss)
++{
++ struct stf_csiphy_dev *csiphy_dev = stfcamss->csiphy_dev;
++
++ csiphy_dev->hw_ops = &csiphy_ops;
++ csiphy_dev->stfcamss = stfcamss;
++ csiphy_dev->formats = csiphy_formats_st7110;
++ csiphy_dev->nformats = ARRAY_SIZE(csiphy_formats_st7110);
++ mutex_init(&csiphy_dev->stream_lock);
++ return 0;
++}
++
++static int csiphy_set_power(struct v4l2_subdev *sd, int on)
++{
++ return 0;
++}
++
++static int csiphy_set_stream(struct v4l2_subdev *sd, int enable)
++{
++ struct stf_csiphy_dev *csiphy_dev = v4l2_get_subdevdata(sd);
++
++ mutex_lock(&csiphy_dev->stream_lock);
++ if (enable) {
++ if (csiphy_dev->stream_count == 0) {
++ csiphy_dev->hw_ops->csiphy_clk_enable(csiphy_dev);
++ csiphy_dev->hw_ops->csiphy_config_set(csiphy_dev);
++ csiphy_dev->hw_ops->csiphy_stream_set(csiphy_dev, 1);
++ }
++ csiphy_dev->stream_count++;
++ } else {
++ if (csiphy_dev->stream_count == 0)
++ goto exit;
++ if (csiphy_dev->stream_count == 1) {
++ csiphy_dev->hw_ops->csiphy_clk_disable(csiphy_dev);
++ csiphy_dev->hw_ops->csiphy_stream_set(csiphy_dev, 0);
++ }
++ csiphy_dev->stream_count--;
++ }
++exit:
++ mutex_unlock(&csiphy_dev->stream_lock);
++
++ return 0;
++}
++
++static struct v4l2_mbus_framefmt *
++__csiphy_get_format(struct stf_csiphy_dev *csiphy_dev,
++ struct v4l2_subdev_state *state,
++ unsigned int pad,
++ enum v4l2_subdev_format_whence which)
++{
++ if (which == V4L2_SUBDEV_FORMAT_TRY)
++ return v4l2_subdev_get_try_format(
++ &csiphy_dev->subdev,
++ state,
++ pad);
++
++ return &csiphy_dev->fmt[pad];
++}
++
++static void csiphy_try_format(struct stf_csiphy_dev *csiphy_dev,
++ struct v4l2_subdev_state *state,
++ unsigned int pad,
++ struct v4l2_mbus_framefmt *fmt,
++ enum v4l2_subdev_format_whence which)
++{
++ unsigned int i;
++
++ switch (pad) {
++ case STF_CSIPHY_PAD_SINK:
++ /* Set format on sink pad */
++
++ for (i = 0; i < csiphy_dev->nformats; i++)
++ if (fmt->code == csiphy_dev->formats[i].code)
++ break;
++
++ if (i >= csiphy_dev->nformats)
++ fmt->code = csiphy_dev->formats[0].code;
++
++ fmt->width = clamp_t(u32,
++ fmt->width,
++ STFCAMSS_FRAME_MIN_WIDTH,
++ STFCAMSS_FRAME_MAX_WIDTH);
++ fmt->height = clamp_t(u32,
++ fmt->height,
++ STFCAMSS_FRAME_MIN_HEIGHT,
++ STFCAMSS_FRAME_MAX_HEIGHT);
++
++ fmt->field = V4L2_FIELD_NONE;
++ fmt->colorspace = V4L2_COLORSPACE_SRGB;
++ fmt->flags = 0;
++
++ break;
++
++ case STF_CSIPHY_PAD_SRC:
++
++ *fmt = *__csiphy_get_format(csiphy_dev,
++ state,
++ STF_CSIPHY_PAD_SINK, which);
++
++ break;
++ }
++}
++
++static int csiphy_enum_mbus_code(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_mbus_code_enum *code)
++{
++ struct stf_csiphy_dev *csiphy_dev = v4l2_get_subdevdata(sd);
++
++ if (code->index >= csiphy_dev->nformats)
++ return -EINVAL;
++
++ if (code->pad == STF_CSIPHY_PAD_SINK) {
++ code->code = csiphy_dev->formats[code->index].code;
++ } else {
++ struct v4l2_mbus_framefmt *sink_fmt;
++
++ sink_fmt = __csiphy_get_format(csiphy_dev, state,
++ STF_CSIPHY_PAD_SINK,
++ code->which);
++
++ code->code = sink_fmt->code;
++ if (!code->code)
++ return -EINVAL;
++ }
++ code->flags = 0;
++ return 0;
++}
++
++static int csiphy_enum_frame_size(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_frame_size_enum *fse)
++{
++ struct stf_csiphy_dev *csiphy_dev = v4l2_get_subdevdata(sd);
++ struct v4l2_mbus_framefmt format;
++
++ if (fse->index != 0)
++ return -EINVAL;
++
++ format.code = fse->code;
++ format.width = 1;
++ format.height = 1;
++ csiphy_try_format(csiphy_dev, state, fse->pad, &format, fse->which);
++ fse->min_width = format.width;
++ fse->min_height = format.height;
++
++ if (format.code != fse->code)
++ return -EINVAL;
++
++ format.code = fse->code;
++ format.width = -1;
++ format.height = -1;
++ csiphy_try_format(csiphy_dev, state, fse->pad, &format, fse->which);
++ fse->max_width = format.width;
++ fse->max_height = format.height;
++
++ return 0;
++}
++
++static int csiphy_get_format(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_format *fmt)
++{
++ struct stf_csiphy_dev *csiphy_dev = v4l2_get_subdevdata(sd);
++ struct v4l2_mbus_framefmt *format;
++
++ format = __csiphy_get_format(csiphy_dev, state, fmt->pad, fmt->which);
++ if (format == NULL)
++ return -EINVAL;
++
++ fmt->format = *format;
++
++ return 0;
++}
++
++static int csiphy_set_format(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_format *fmt)
++{
++ struct stf_csiphy_dev *csiphy_dev = v4l2_get_subdevdata(sd);
++ struct v4l2_mbus_framefmt *format;
++
++ format = __csiphy_get_format(csiphy_dev, state, fmt->pad, fmt->which);
++ if (format == NULL)
++ return -EINVAL;
++
++ mutex_lock(&csiphy_dev->stream_lock);
++ if (csiphy_dev->stream_count) {
++ fmt->format = *format;
++ mutex_unlock(&csiphy_dev->stream_lock);
++ goto out;
++ } else {
++ csiphy_try_format(csiphy_dev, state, fmt->pad, &fmt->format, fmt->which);
++ *format = fmt->format;
++ }
++ mutex_unlock(&csiphy_dev->stream_lock);
++
++ /* Propagate the format from sink to source */
++ if (fmt->pad == STF_CSIPHY_PAD_SINK) {
++ format = __csiphy_get_format(csiphy_dev,
++ state,
++ STF_CSIPHY_PAD_SRC,
++ fmt->which);
++
++ *format = fmt->format;
++ csiphy_try_format(csiphy_dev, state, STF_CSIPHY_PAD_SRC, format,
++ fmt->which);
++ }
++out:
++ return 0;
++}
++
++static int csiphy_init_formats(struct v4l2_subdev *sd,
++ struct v4l2_subdev_fh *fh)
++{
++ struct v4l2_subdev_format format = {
++ .pad = STF_CSIPHY_PAD_SINK,
++ .which = fh ? V4L2_SUBDEV_FORMAT_TRY :
++ V4L2_SUBDEV_FORMAT_ACTIVE,
++ .format = {
++ .code = MEDIA_BUS_FMT_RGB565_2X8_LE,
++ .width = 1920,
++ .height = 1080
++ }
++ };
++
++ return csiphy_set_format(sd, fh ? fh->state : NULL, &format);
++}
++
++static int csiphy_link_setup(struct media_entity *entity,
++ const struct media_pad *local,
++ const struct media_pad *remote, u32 flags)
++{
++ if ((local->flags & MEDIA_PAD_FL_SOURCE) &&
++ (flags & MEDIA_LNK_FL_ENABLED)) {
++ struct v4l2_subdev *sd;
++ struct stf_csiphy_dev *csiphy_dev;
++ struct stf_csi_dev *csi_dev;
++
++ if (media_pad_remote_pad_first(local))
++ return -EBUSY;
++
++ sd = media_entity_to_v4l2_subdev(entity);
++ csiphy_dev = v4l2_get_subdevdata(sd);
++
++ sd = media_entity_to_v4l2_subdev(remote->entity);
++ csi_dev = v4l2_get_subdevdata(sd);
++ st_info(ST_CSIPHY, "CSIPHY0 link to CSI0\n");
++ }
++
++ return 0;
++}
++
++static const struct v4l2_subdev_core_ops csiphy_core_ops = {
++ .s_power = csiphy_set_power,
++};
++
++static const struct v4l2_subdev_video_ops csiphy_video_ops = {
++ .s_stream = csiphy_set_stream,
++};
++
++static const struct v4l2_subdev_pad_ops csiphy_pad_ops = {
++ .enum_mbus_code = csiphy_enum_mbus_code,
++ .enum_frame_size = csiphy_enum_frame_size,
++ .get_fmt = csiphy_get_format,
++ .set_fmt = csiphy_set_format,
++};
++
++static const struct v4l2_subdev_ops csiphy_v4l2_ops = {
++ .core = &csiphy_core_ops,
++ .video = &csiphy_video_ops,
++ .pad = &csiphy_pad_ops,
++};
++
++static const struct v4l2_subdev_internal_ops csiphy_v4l2_internal_ops = {
++ .open = csiphy_init_formats,
++};
++
++static const struct media_entity_operations csiphy_media_ops = {
++ .link_setup = csiphy_link_setup,
++ .link_validate = v4l2_subdev_link_validate,
++};
++
++int stf_csiphy_register(struct stf_csiphy_dev *csiphy_dev,
++ struct v4l2_device *v4l2_dev)
++{
++ struct v4l2_subdev *sd = &csiphy_dev->subdev;
++ struct device *dev = csiphy_dev->stfcamss->dev;
++ struct media_pad *pads = csiphy_dev->pads;
++ int ret;
++
++ v4l2_subdev_init(sd, &csiphy_v4l2_ops);
++ sd->internal_ops = &csiphy_v4l2_internal_ops;
++ sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
++ snprintf(sd->name, ARRAY_SIZE(sd->name), "%s%d",
++ STF_CSIPHY_NAME, 0);
++ v4l2_set_subdevdata(sd, csiphy_dev);
++
++ ret = csiphy_init_formats(sd, NULL);
++ if (ret < 0) {
++ dev_err(dev, "Failed to init format: %d\n", ret);
++ return ret;
++ }
++
++ pads[STF_CSIPHY_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
++ pads[STF_CSIPHY_PAD_SRC].flags = MEDIA_PAD_FL_SOURCE;
++
++ sd->entity.function = MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER;
++ sd->entity.ops = &csiphy_media_ops;
++ ret = media_entity_pads_init(&sd->entity, STF_CSIPHY_PADS_NUM, pads);
++ if (ret < 0) {
++ dev_err(dev, "Failed to init media entity: %d\n", ret);
++ return ret;
++ }
++
++ ret = v4l2_device_register_subdev(v4l2_dev, sd);
++ if (ret < 0) {
++ dev_err(dev, "Failed to register subdev: %d\n", ret);
++ goto err_sreg;
++ }
++
++ return 0;
++
++err_sreg:
++ media_entity_cleanup(&sd->entity);
++ return ret;
++}
++
++int stf_csiphy_unregister(struct stf_csiphy_dev *csiphy_dev)
++{
++ v4l2_device_unregister_subdev(&csiphy_dev->subdev);
++ media_entity_cleanup(&csiphy_dev->subdev.entity);
++ mutex_destroy(&csiphy_dev->stream_lock);
++ return 0;
++}
+--- /dev/null
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_csiphy.h
+@@ -0,0 +1,188 @@
++/* SPDX-License-Identifier: GPL-2.0
++ *
++ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
++ *
++ */
++
++#ifndef STF_CSIPHY_H
++#define STF_CSIPHY_H
++
++#include <media/v4l2-subdev.h>
++#include <media/v4l2-device.h>
++#include <media/media-entity.h>
++#include <video/stf-vin.h>
++
++#define STF_CSIPHY_NAME "stf_csiphy"
++
++#define STF_CSIPHY_PAD_SINK 0
++#define STF_CSIPHY_PAD_SRC 1
++#define STF_CSIPHY_PADS_NUM 2
++
++#define STF_CSI2_MAX_DATA_LANES 4
++
++union static_config {
++ u32 raw;
++ struct {
++ u32 sel : 2;
++ u32 rsvd_6 : 2;
++ u32 v2p0_support_enable : 1;
++ u32 rsvd_5 : 3;
++ u32 lane_nb : 3;
++ u32 rsvd_4 : 5;
++ u32 dl0_map : 3;
++ u32 rsvd_3 : 1;
++ u32 dl1_map : 3;
++ u32 rsvd_2 : 1;
++ u32 dl2_map : 3;
++ u32 rsvd_1 : 1;
++ u32 dl3_map : 3;
++ u32 rsvd_0 : 1;
++ } bits;
++};
++
++union error_bypass_cfg {
++ u32 value;
++ struct {
++ u32 crc : 1;
++ u32 ecc : 1;
++ u32 data_id : 1;
++ u32 rsvd_0 : 29;
++ };
++};
++
++union stream_monitor_ctrl {
++ u32 value;
++ struct {
++ u32 lb_vc : 4;
++ u32 lb_en : 1;
++ u32 timer_vc : 4;
++ u32 timer_en : 1;
++ u32 timer_eof : 1;
++ u32 frame_mon_vc : 4;
++ u32 frame_mon_en : 1;
++ u32 frame_length : 16;
++ };
++};
++
++union stream_cfg {
++ u32 value;
++ struct {
++ u32 interface_mode : 1;
++ u32 ls_le_mode : 1;
++ u32 rsvd_3 : 2;
++ u32 num_pixels : 2;
++ u32 rsvd_2 : 2;
++ u32 fifo_mode : 2;
++ u32 rsvd_1 : 2;
++ u32 bpp_bypass : 3;
++ u32 rsvd_0 : 1;
++ u32 fifo_fill : 16;
++ };
++};
++
++union dphy_lane_ctrl {
++ u32 raw;
++ struct {
++ u32 dl0_en : 1;
++ u32 dl1_en : 1;
++ u32 dl2_en : 1;
++ u32 dl3_en : 1;
++ u32 cl_en : 1;
++ u32 rsvd_1 : 7;
++ u32 dl0_reset : 1;
++ u32 dl1_reset : 1;
++ u32 dl2_reset : 1;
++ u32 dl3_reset : 1;
++ u32 cl_reset : 1;
++ u32 rsvd_0 : 15;
++ } bits;
++};
++
++union dphy_lane_swap {
++ u32 raw;
++ struct {
++ u32 rx_1c2c_sel : 1;
++ u32 lane_swap_clk : 3;
++ u32 lane_swap_clk1 : 3;
++ u32 lane_swap_lan0 : 3;
++ u32 lane_swap_lan1 : 3;
++ u32 lane_swap_lan2 : 3;
++ u32 lane_swap_lan3 : 3;
++ u32 dpdn_swap_clk : 1;
++ u32 dpdn_swap_clk1 : 1;
++ u32 dpdn_swap_lan0 : 1;
++ u32 dpdn_swap_lan1 : 1;
++ u32 dpdn_swap_lan2 : 1;
++ u32 dpdn_swap_lan3 : 1;
++ u32 hs_freq_chang_clk0 : 1;
++ u32 hs_freq_chang_clk1 : 1;
++ u32 reserved : 5;
++ } bits;
++};
++
++union dphy_lane_en {
++ u32 raw;
++ struct {
++ u32 gpio_en : 6;
++ u32 mp_test_mode_sel : 5;
++ u32 mp_test_en : 1;
++ u32 dphy_enable_lan0 : 1;
++ u32 dphy_enable_lan1 : 1;
++ u32 dphy_enable_lan2 : 1;
++ u32 dphy_enable_lan3 : 1;
++ u32 rsvd_0 : 16;
++ } bits;
++};
++
++struct csiphy_format {
++ u32 code;
++ u8 bpp;
++};
++
++struct csi2phy_cfg {
++ unsigned int flags;
++ unsigned char data_lanes[STF_CSI2_MAX_DATA_LANES];
++ unsigned char clock_lane;
++ unsigned char num_data_lanes;
++ bool lane_polarities[1 + STF_CSI2_MAX_DATA_LANES];
++};
++
++struct csi2phy_cfg2 {
++ unsigned char data_lanes[STF_CSI2_MAX_DATA_LANES];
++ unsigned char num_data_lanes;
++ unsigned char num_clks;
++ unsigned char clock_lane;
++ unsigned char clock1_lane;
++ bool lane_polarities[2 + STF_CSI2_MAX_DATA_LANES];
++};
++
++struct stf_csiphy_dev;
++
++struct csiphy_hw_ops {
++ int (*csiphy_clk_enable)(struct stf_csiphy_dev *csiphy_dev);
++ int (*csiphy_clk_disable)(struct stf_csiphy_dev *csiphy_dev);
++ int (*csiphy_config_set)(struct stf_csiphy_dev *csiphy_dev);
++ int (*csiphy_stream_set)(struct stf_csiphy_dev *csiphy_dev, int on);
++};
++
++struct stf_csiphy_dev {
++ struct stfcamss *stfcamss;
++ struct csi2phy_cfg *csiphy;
++ struct v4l2_subdev subdev;
++ struct media_pad pads[STF_CSIPHY_PADS_NUM];
++ struct v4l2_mbus_framefmt fmt[STF_CSIPHY_PADS_NUM];
++ const struct csiphy_format *formats;
++ unsigned int nformats;
++ struct csiphy_hw_ops *hw_ops;
++ struct mutex stream_lock;
++ int stream_count;
++};
++
++extern int stf_csiphy_subdev_init(struct stfcamss *stfcamss);
++extern int stf_csiphy_register(struct stf_csiphy_dev *csiphy_dev,
++ struct v4l2_device *v4l2_dev);
++extern int stf_csiphy_unregister(struct stf_csiphy_dev *csiphy_dev);
++
++extern struct csiphy_hw_ops csiphy_ops;
++
++#endif /* STF_CSIPHY_H */
+--- /dev/null
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_csiphy_hw_ops.c
+@@ -0,0 +1,335 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
++ *
++ */
++
++#include "stfcamss.h"
++#include <linux/sort.h>
++
++static int stf_csiphy_clk_set(struct stf_csiphy_dev *csiphy_dev, int on)
++{
++ struct stfcamss *stfcamss = csiphy_dev->stfcamss;
++ static int init_flag;
++ static struct mutex count_lock;
++ static int count;
++
++ if (!init_flag) {
++ init_flag = 1;
++ mutex_init(&count_lock);
++ }
++ mutex_lock(&count_lock);
++ if (on) {
++ clk_set_rate(stfcamss->sys_clk[STFCLK_M31DPHY_CFGCLK_IN].clk,
++ 99000000);
++ clk_set_rate(stfcamss->sys_clk[STFCLK_M31DPHY_REFCLK_IN].clk,
++ 49500000);
++ clk_set_rate(stfcamss->sys_clk[STFCLK_M31DPHY_TXCLKESC_LAN0].clk,
++ 19800000);
++
++ reset_control_deassert(stfcamss->sys_rst[STFRST_M31DPHY_HW].rstc);
++ reset_control_deassert(stfcamss->sys_rst[STFRST_M31DPHY_B09_ALWAYS_ON].rstc);
++
++ count++;
++ } else {
++ if (count == 0)
++ goto exit;
++ if (count == 1) {
++ reset_control_assert(stfcamss->sys_rst[STFRST_M31DPHY_HW].rstc);
++ reset_control_assert(stfcamss->sys_rst[STFRST_M31DPHY_B09_ALWAYS_ON].rstc);
++ }
++ count--;
++ }
++exit:
++ mutex_unlock(&count_lock);
++ return 0;
++}
++
++static int stf_csiphy_clk_enable(struct stf_csiphy_dev *csiphy_dev)
++{
++ return stf_csiphy_clk_set(csiphy_dev, 1);
++}
++
++static int stf_csiphy_clk_disable(struct stf_csiphy_dev *csiphy_dev)
++{
++ return stf_csiphy_clk_set(csiphy_dev, 0);
++}
++
++#ifndef USE_CSIDPHY_ONE_CLK_MODE
++static int cmp_func(const void *x1, const void *x2)
++{
++ return *((unsigned char *)x1) - *((unsigned char *)x2);
++}
++#endif
++
++int try_cfg(struct csi2phy_cfg2 *cfg, struct csi2phy_cfg *cfg0,
++ struct csi2phy_cfg *cfg1)
++{
++ int i = 0;
++
++ cfg->clock_lane = 0;
++ cfg->clock1_lane = 5;
++ cfg->data_lanes[0] = 1;
++ cfg->data_lanes[1] = 2;
++ cfg->data_lanes[2] = 3;
++ cfg->data_lanes[3] = 4;
++
++ if (cfg0 && cfg1) {
++ st_debug(ST_CSIPHY, "CSIPHY use 2 clk mode\n");
++ cfg->num_clks = 2;
++ cfg->num_data_lanes =
++ cfg1->num_data_lanes + cfg0->num_data_lanes;
++ if (cfg->num_data_lanes > STF_CSI2_MAX_DATA_LANES)
++ return -EINVAL;
++ cfg->clock_lane = cfg0->clock_lane;
++ cfg->lane_polarities[0] = cfg0->lane_polarities[0];
++ cfg->clock1_lane = cfg1->clock_lane;
++ cfg->lane_polarities[1] = cfg1->lane_polarities[0];
++ for (i = 0; i < cfg0->num_data_lanes; i++) {
++ cfg->data_lanes[i] = cfg0->data_lanes[i];
++ cfg->lane_polarities[i + 2] =
++ cfg0->lane_polarities[i + 1];
++ }
++
++ for (i = cfg0->num_data_lanes; i < cfg->num_data_lanes; i++) {
++ cfg->data_lanes[i] =
++ cfg1->data_lanes[i - cfg0->num_data_lanes];
++ cfg->lane_polarities[i + 2] =
++ cfg1->lane_polarities[i - cfg0->num_data_lanes + 1];
++ }
++ } else if (cfg0 && !cfg1) {
++ st_debug(ST_CSIPHY, "CSIPHY cfg0 use 1 clk mode\n");
++ cfg->num_clks = 1;
++ cfg->num_data_lanes = cfg0->num_data_lanes;
++ cfg->clock_lane = cfg->clock1_lane = cfg0->clock_lane;
++ cfg->lane_polarities[0] = cfg->lane_polarities[1] =
++ cfg0->lane_polarities[0];
++ for (i = 0; i < cfg0->num_data_lanes; i++) {
++ cfg->data_lanes[i] = cfg0->data_lanes[i];
++ cfg->lane_polarities[i + 2] = cfg0->lane_polarities[i + 1];
++ }
++ } else if (!cfg0 && cfg1) {
++ st_debug(ST_CSIPHY, "CSIPHY cfg1 use 1 clk mode\n");
++ cfg->num_clks = 1;
++ cfg->num_data_lanes = cfg1->num_data_lanes;
++ cfg->clock_lane = cfg->clock1_lane = cfg1->clock_lane;
++ cfg->lane_polarities[0] = cfg->lane_polarities[1] =
++ cfg1->lane_polarities[0];
++ for (i = 0; i < cfg1->num_data_lanes; i++) {
++ cfg->data_lanes[i] = cfg1->data_lanes[i];
++ cfg->lane_polarities[i + 2] = cfg1->lane_polarities[i + 1];
++ }
++ } else {
++ return -EINVAL;
++ }
++
++#ifndef USE_CSIDPHY_ONE_CLK_MODE
++ sort(cfg->data_lanes, cfg->num_data_lanes,
++ sizeof(cfg->data_lanes[0]), cmp_func, NULL);
++#endif
++ for (i = 0; i < cfg->num_data_lanes; i++)
++ st_debug(ST_CSIPHY, "%d: %d\n", i, cfg->data_lanes[i]);
++ return 0;
++}
++
++static int csi2rx_dphy_config(struct stf_vin_dev *vin,
++ struct stf_csiphy_dev *csiphy_dev)
++{
++ struct csi2phy_cfg2 cfg2 = {0};
++ struct csi2phy_cfg2 *cfg = &cfg2;
++ struct csi2phy_cfg *phycfg = csiphy_dev->csiphy;
++
++ if (!phycfg)
++ return -EINVAL;
++
++ if (try_cfg(cfg, phycfg, NULL))
++ return -EINVAL;
++
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_4, 0x0);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_8, 0x0);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_12, 0xfff0);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_16, 0x0);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_20, 0x0);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_24, 0x0);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_28, 0x0);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_32, 0x0);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_36, 0x0);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_40, 0x0);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_44, 0x0);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_48, 0x24000000);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_52, 0x0);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_56, 0x0);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_60, 0x0);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_64, 0x0);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_68, 0x0);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_72, 0x0);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_76, 0x0);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_80, 0x0);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_84, 0x0);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_88, 0x0);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_92, 0x0);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_96, 0x0);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_100, 0x02000000);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_104, 0x0);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_108, 0x0);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_112, 0x0);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_116, 0x0);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_120, 0x0);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_124, 0xc);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_128, 0x0);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_132, 0xcc500000);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_136, 0xcc);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_140, 0x0);
++ reg_write(vin->rstgen_base, M31DPHY_APBCFGSAIF__SYSCFG_144, 0x0);
++
++ reg_set_bit(vin->rstgen_base, //r100_ctrl0_2d1c_efuse_en
++ M31DPHY_APBCFGSAIF__SYSCFG_0,
++ BIT(6), 1<<6);
++ reg_set_bit(vin->rstgen_base, //r100_ctrl0_2d1c_efuse_in
++ M31DPHY_APBCFGSAIF__SYSCFG_0,
++ BIT(12)|BIT(11)|BIT(10)|BIT(9)|BIT(8)|BIT(7), 0x1b<<7);
++ reg_set_bit(vin->rstgen_base, //r100_ctrl1_2d1c_efuse_en
++ M31DPHY_APBCFGSAIF__SYSCFG_0,
++ BIT(13), 1<<13);
++ reg_set_bit(vin->rstgen_base, //r100_ctrl1_2d1c_efuse_in
++ M31DPHY_APBCFGSAIF__SYSCFG_0,
++ BIT(19)|BIT(18)|BIT(17)|BIT(16)|BIT(15)|BIT(14), 0x1b<<14);
++
++ reg_set_bit(vin->rstgen_base, //data_bus16_8
++ M31DPHY_APBCFGSAIF__SYSCFG_184,
++ BIT(8), 0<<8);
++
++ reg_set_bit(vin->rstgen_base, //debug_mode_sel
++ M31DPHY_APBCFGSAIF__SYSCFG_184,
++ BIT(15)|BIT(14)|BIT(13)|BIT(12)|BIT(11)|BIT(10)|BIT(9), 0x5a<<9);
++
++ reg_set_bit(vin->rstgen_base, //dpdn_swap_clk0
++ M31DPHY_APBCFGSAIF__SYSCFG_188,
++ BIT(0), cfg->lane_polarities[0]<<0);
++ reg_set_bit(vin->rstgen_base, //dpdn_swap_clk1
++ M31DPHY_APBCFGSAIF__SYSCFG_188,
++ BIT(1), cfg->lane_polarities[1]<<1);
++ reg_set_bit(vin->rstgen_base, //dpdn_swap_lan0
++ M31DPHY_APBCFGSAIF__SYSCFG_188,
++ BIT(2), cfg->lane_polarities[2]<<2);
++ reg_set_bit(vin->rstgen_base, //dpdn_swap_lan1
++ M31DPHY_APBCFGSAIF__SYSCFG_188,
++ BIT(3), cfg->lane_polarities[3]<<3);
++ reg_set_bit(vin->rstgen_base, //dpdn_swap_lan2
++ M31DPHY_APBCFGSAIF__SYSCFG_188,
++ BIT(4), cfg->lane_polarities[4]<<4);
++ reg_set_bit(vin->rstgen_base, //dpdn_swap_lan3
++ M31DPHY_APBCFGSAIF__SYSCFG_188,
++ BIT(5), cfg->lane_polarities[5]<<5);
++ reg_set_bit(vin->rstgen_base, //enable clk0
++ M31DPHY_APBCFGSAIF__SYSCFG_188,
++ BIT(6), 1<<6);
++ reg_set_bit(vin->rstgen_base, //enable clk1
++ M31DPHY_APBCFGSAIF__SYSCFG_188,
++ BIT(7), 1<<7);
++ reg_set_bit(vin->rstgen_base, //enable lan0
++ M31DPHY_APBCFGSAIF__SYSCFG_188,
++ BIT(8), 1<<8);
++ reg_set_bit(vin->rstgen_base, //enable lan1
++ M31DPHY_APBCFGSAIF__SYSCFG_188,
++ BIT(9), 1<<9);
++ reg_set_bit(vin->rstgen_base, //enable lan2
++ M31DPHY_APBCFGSAIF__SYSCFG_188,
++ BIT(10), 1<<10);
++ reg_set_bit(vin->rstgen_base, //enable lan3
++ M31DPHY_APBCFGSAIF__SYSCFG_188,
++ BIT(11), 1<<11);
++ reg_set_bit(vin->rstgen_base, //gpi_en
++ M31DPHY_APBCFGSAIF__SYSCFG_188,
++ BIT(17)|BIT(16)|BIT(15)|BIT(14)|BIT(13)|BIT(12),
++ 0<<12);
++ reg_set_bit(vin->rstgen_base, //hs_freq_change_clk0
++ M31DPHY_APBCFGSAIF__SYSCFG_188,
++ BIT(18), 0<<18);
++ reg_set_bit(vin->rstgen_base, //hs_freq_change_clk1
++ M31DPHY_APBCFGSAIF__SYSCFG_188,
++ BIT(19), 0<<19);
++
++ reg_set_bit(vin->rstgen_base,
++ M31DPHY_APBCFGSAIF__SYSCFG_188,
++ BIT(22)|BIT(21)|BIT(20), cfg->clock_lane<<20); //clock lane 0
++ reg_set_bit(vin->rstgen_base,
++ M31DPHY_APBCFGSAIF__SYSCFG_188,
++ BIT(25)|BIT(24)|BIT(23), cfg->clock1_lane<<23); //clock lane 1
++
++ reg_set_bit(vin->rstgen_base,
++ M31DPHY_APBCFGSAIF__SYSCFG_188,
++ BIT(28)|BIT(27)|BIT(26), cfg->data_lanes[0]<<26); //data lane 0
++ reg_set_bit(vin->rstgen_base,
++ M31DPHY_APBCFGSAIF__SYSCFG_188,
++ BIT(31)|BIT(30)|BIT(29), cfg->data_lanes[1]<<29); //data lane 1
++ reg_set_bit(vin->rstgen_base,
++ M31DPHY_APBCFGSAIF__SYSCFG_192,
++ BIT(2)|BIT(1)|BIT(0), cfg->data_lanes[2]<<0); //data lane 2
++ reg_set_bit(vin->rstgen_base,
++ M31DPHY_APBCFGSAIF__SYSCFG_192,
++ BIT(5)|BIT(4)|BIT(3), cfg->data_lanes[3]<<3); //data lane 3
++
++ reg_set_bit(vin->rstgen_base, //mp_test_en
++ M31DPHY_APBCFGSAIF__SYSCFG_192,
++ BIT(6), 0<<6);
++ reg_set_bit(vin->rstgen_base, //mp_test_mode_sel
++ M31DPHY_APBCFGSAIF__SYSCFG_192,
++ BIT(11)|BIT(10)|BIT(9)|BIT(8)|BIT(7), 0<<7);
++
++ reg_set_bit(vin->rstgen_base, //pll_clk_sel
++ M31DPHY_APBCFGSAIF__SYSCFG_192,
++ BIT(20)|BIT(19)|BIT(18)|BIT(17)|BIT(16)|BIT(15)|BIT(14)|BIT(13)|BIT(12),
++ 0x37c<<12);
++
++ reg_set_bit(vin->rstgen_base, //rx_1c2c_sel
++ M31DPHY_APBCFGSAIF__SYSCFG_200,
++ BIT(8), 0<<8);
++
++ reg_set_bit(vin->rstgen_base, //precounter in clk0
++ M31DPHY_APBCFGSAIF__SYSCFG_192,
++ BIT(29)|BIT(28)|BIT(27)|BIT(26)|BIT(25)|BIT(24)|BIT(23)|BIT(22),
++ 8<<22);
++ reg_set_bit(vin->rstgen_base, //precounter in clk1
++ M31DPHY_APBCFGSAIF__SYSCFG_196,
++ BIT(7)|BIT(6)|BIT(5)|BIT(4)|BIT(3)|BIT(2)|BIT(1)|BIT(0),
++ 8<<0);
++ reg_set_bit(vin->rstgen_base, //precounter in lan0
++ M31DPHY_APBCFGSAIF__SYSCFG_196,
++ BIT(15)|BIT(14)|BIT(13)|BIT(12)|BIT(11)|BIT(10)|BIT(9)|BIT(8),
++ 7<<8);
++ reg_set_bit(vin->rstgen_base, //precounter in lan1
++ M31DPHY_APBCFGSAIF__SYSCFG_196,
++ BIT(23)|BIT(22)|BIT(21)|BIT(20)|BIT(19)|BIT(18)|BIT(17)|BIT(16),
++ 7<<16);
++ reg_set_bit(vin->rstgen_base, //precounter in lan2
++ M31DPHY_APBCFGSAIF__SYSCFG_196,
++ BIT(31)|BIT(30)|BIT(29)|BIT(28)|BIT(27)|BIT(26)|BIT(25)|BIT(24),
++ 7<<24);
++ reg_set_bit(vin->rstgen_base, //precounter in lan3
++ M31DPHY_APBCFGSAIF__SYSCFG_200,
++ BIT(7)|BIT(6)|BIT(5)|BIT(4)|BIT(3)|BIT(2)|BIT(1)|BIT(0),
++ 7<<0);
++
++ return 0;
++}
++
++static int stf_csiphy_config_set(struct stf_csiphy_dev *csiphy_dev)
++{
++ struct stf_vin_dev *vin = csiphy_dev->stfcamss->vin;
++
++ csi2rx_dphy_config(vin, csiphy_dev);
++ return 0;
++}
++
++static int stf_csiphy_stream_set(struct stf_csiphy_dev *csiphy_dev, int on)
++{
++ return 0;
++}
++
++struct csiphy_hw_ops csiphy_ops = {
++ .csiphy_clk_enable = stf_csiphy_clk_enable,
++ .csiphy_clk_disable = stf_csiphy_clk_disable,
++ .csiphy_config_set = stf_csiphy_config_set,
++ .csiphy_stream_set = stf_csiphy_stream_set,
++};
+--- /dev/null
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_dmabuf.c
+@@ -0,0 +1,123 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
++ *
++ */
++
++#include <linux/dma-buf.h>
++#include <media/v4l2-subdev.h>
++#include <media/videobuf2-dma-contig.h>
++
++#include "stf_isp_ioctl.h"
++#include "stf_dmabuf.h"
++
++#define TOTAL_SIZE_LIMIT (64 * 1024 * 1024)
++
++static size_t total_size;
++static struct vb2_queue vb2_queue = {
++ .dma_attrs = 0,
++ .gfp_flags = 0,
++ .dma_dir = DMA_TO_DEVICE,
++};
++static struct vb2_buffer vb = {
++ .vb2_queue = &vb2_queue,
++};
++
++static int dmabuf_create(struct device *dev,
++ struct dmabuf_create *head)
++{
++ struct dma_buf *dmabuf = NULL;
++ void *mem_priv = NULL;
++ dma_addr_t *paddr = NULL;
++ int ret = 0;
++
++ mem_priv = vb2_dma_contig_memops.alloc(&vb, dev, head->size);
++ if (IS_ERR_OR_NULL(mem_priv)) {
++ if (mem_priv)
++ ret = PTR_ERR(mem_priv);
++ goto exit;
++ }
++
++ dmabuf = vb2_dma_contig_memops.get_dmabuf(&vb, mem_priv, O_RDWR);
++ if (IS_ERR(dmabuf)) {
++ ret = PTR_ERR(dmabuf);
++ goto free;
++ }
++
++ head->fd = dma_buf_fd(dmabuf, O_CLOEXEC);
++ if (head->fd < 0) {
++ dma_buf_put(dmabuf);
++ ret = head->fd;
++ goto free;
++ }
++
++ paddr = vb2_dma_contig_memops.cookie(&vb, mem_priv);
++ head->paddr = *paddr;
++ return 0;
++free:
++ vb2_dma_contig_memops.put(mem_priv);
++exit:
++ return ret;
++}
++
++int stf_dmabuf_ioctl_alloc(struct device *dev, void *arg)
++{
++ struct dmabuf_create *head = arg;
++ int ret = -EINVAL;
++
++ if (IS_ERR_OR_NULL(head))
++ return -EFAULT;
++
++ head->size = PAGE_ALIGN(head->size);
++ if (!head->size)
++ return -EINVAL;
++ if ((head->size + total_size) > TOTAL_SIZE_LIMIT)
++ return -ENOMEM;
++
++ ret = dmabuf_create(dev, head);
++ if (ret)
++ return -EFAULT;
++
++ total_size += head->size;
++ return ret;
++}
++
++int stf_dmabuf_ioctl_free(struct device *dev, void *arg)
++{
++ struct dmabuf_create *head = arg;
++ struct dma_buf *dmabuf = NULL;
++ int ret = 0;
++
++ if (IS_ERR_OR_NULL(head))
++ return -EFAULT;
++ if (head->size != PAGE_ALIGN(head->size))
++ return -EINVAL;
++ if (head->size > total_size)
++ return -EINVAL;
++
++ dmabuf = dma_buf_get(head->fd);
++ if (IS_ERR_OR_NULL(dmabuf))
++ return -EINVAL;
++
++ dma_buf_put(dmabuf);
++ vb2_dma_contig_memops.put(dmabuf->priv);
++ total_size -= head->size;
++ return ret;
++}
++
++int stf_dmabuf_ioctl(struct device *dev, unsigned int cmd, void *arg)
++{
++ int ret = -ENOIOCTLCMD;
++
++ switch (cmd) {
++ case VIDIOC_STF_DMABUF_ALLOC:
++ ret = stf_dmabuf_ioctl_alloc(dev, arg);
++ break;
++ case VIDIOC_STF_DMABUF_FREE:
++ ret = stf_dmabuf_ioctl_free(dev, arg);
++ break;
++ default:
++ break;
++ }
++ return ret;
++}
+--- /dev/null
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_dmabuf.h
+@@ -0,0 +1,12 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++/*
++ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
++ *
++ */
++
++#ifndef STF_DMABUF_H
++#define STF_DMABUF_H
++
++extern int stf_dmabuf_ioctl(struct device *dev, unsigned int cmd, void *arg);
++
++#endif /* STF_DMABUF_H */
+--- /dev/null
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_dvp.c
+@@ -0,0 +1,385 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
++ *
++ */
++
++#include "stfcamss.h"
++#include <media/v4l2-async.h>
++#include <media/v4l2-ctrls.h>
++#include <media/v4l2-device.h>
++#include <media/v4l2-event.h>
++#include <media/v4l2-fwnode.h>
++#include <media/v4l2-subdev.h>
++
++static const struct dvp_format dvp_formats_st7110[] = {
++ { MEDIA_BUS_FMT_YUYV8_2X8, 8},
++ { MEDIA_BUS_FMT_RGB565_2X8_LE, 8},
++ { MEDIA_BUS_FMT_SRGGB8_1X8, 8},
++ { MEDIA_BUS_FMT_SGRBG8_1X8, 8},
++ { MEDIA_BUS_FMT_SGBRG8_1X8, 8},
++ { MEDIA_BUS_FMT_SBGGR8_1X8, 8},
++ { MEDIA_BUS_FMT_SRGGB10_1X10, 8},
++ { MEDIA_BUS_FMT_SGRBG10_1X10, 8},
++ { MEDIA_BUS_FMT_SGBRG10_1X10, 8},
++ { MEDIA_BUS_FMT_SBGGR10_1X10, 8},
++};
++
++static int dvp_find_format(u32 code,
++ const struct dvp_format *formats,
++ unsigned int nformats)
++{
++ int i;
++
++ for (i = 0; i < nformats; i++)
++ if (formats[i].code == code)
++ return i;
++ return -EINVAL;
++}
++
++int stf_dvp_subdev_init(struct stfcamss *stfcamss)
++{
++ struct stf_dvp_dev *dvp_dev = stfcamss->dvp_dev;
++
++ dvp_dev->s_type = SENSOR_VIN;
++ dvp_dev->hw_ops = &dvp_ops;
++ dvp_dev->stfcamss = stfcamss;
++ dvp_dev->formats = dvp_formats_st7110;
++ dvp_dev->nformats = ARRAY_SIZE(dvp_formats_st7110);
++ mutex_init(&dvp_dev->stream_lock);
++ dvp_dev->stream_count = 0;
++ return 0;
++}
++
++static int dvp_set_power(struct v4l2_subdev *sd, int on)
++{
++ return 0;
++}
++
++static struct v4l2_mbus_framefmt *
++__dvp_get_format(struct stf_dvp_dev *dvp_dev,
++ struct v4l2_subdev_state *state,
++ unsigned int pad,
++ enum v4l2_subdev_format_whence which)
++{
++
++ if (which == V4L2_SUBDEV_FORMAT_TRY)
++ return v4l2_subdev_get_try_format(
++ &dvp_dev->subdev, state, pad);
++ return &dvp_dev->fmt[pad];
++}
++
++static int dvp_set_stream(struct v4l2_subdev *sd, int enable)
++{
++ struct stf_dvp_dev *dvp_dev = v4l2_get_subdevdata(sd);
++ struct v4l2_mbus_framefmt *format;
++ int ret = 0;
++
++ format = __dvp_get_format(dvp_dev, NULL, STF_DVP_PAD_SRC,
++ V4L2_SUBDEV_FORMAT_ACTIVE);
++ if (format == NULL)
++ return -EINVAL;
++ ret = dvp_find_format(format->code,
++ dvp_dev->formats,
++ dvp_dev->nformats);
++ if (ret < 0)
++ return ret;
++
++ mutex_lock(&dvp_dev->stream_lock);
++ if (enable) {
++ if (dvp_dev->stream_count == 0) {
++ dvp_dev->hw_ops->dvp_clk_enable(dvp_dev);
++ dvp_dev->hw_ops->dvp_config_set(dvp_dev);
++ dvp_dev->hw_ops->dvp_set_format(dvp_dev,
++ format->width, dvp_dev->formats[ret].bpp);
++ dvp_dev->hw_ops->dvp_stream_set(dvp_dev, 1);
++ }
++ dvp_dev->stream_count++;
++ } else {
++ if (dvp_dev->stream_count == 0)
++ goto exit;
++ if (dvp_dev->stream_count == 1) {
++ dvp_dev->hw_ops->dvp_stream_set(dvp_dev, 0);
++ dvp_dev->hw_ops->dvp_clk_disable(dvp_dev);
++ }
++ dvp_dev->stream_count--;
++ }
++exit:
++ mutex_unlock(&dvp_dev->stream_lock);
++ return 0;
++}
++
++static void dvp_try_format(struct stf_dvp_dev *dvp_dev,
++ struct v4l2_subdev_state *state,
++ unsigned int pad,
++ struct v4l2_mbus_framefmt *fmt,
++ enum v4l2_subdev_format_whence which)
++{
++ unsigned int i;
++
++ switch (pad) {
++ case STF_DVP_PAD_SINK:
++ /* Set format on sink pad */
++
++ for (i = 0; i < dvp_dev->nformats; i++)
++ if (fmt->code == dvp_dev->formats[i].code)
++ break;
++
++ if (i >= dvp_dev->nformats)
++ fmt->code = dvp_dev->formats[0].code;
++
++ fmt->width = clamp_t(u32,
++ fmt->width, STFCAMSS_FRAME_MIN_WIDTH,
++ STFCAMSS_FRAME_MAX_WIDTH);
++ fmt->height = clamp_t(u32,
++ fmt->height, STFCAMSS_FRAME_MIN_HEIGHT,
++ STFCAMSS_FRAME_MAX_HEIGHT);
++
++ fmt->field = V4L2_FIELD_NONE;
++ fmt->colorspace = V4L2_COLORSPACE_SRGB;
++ fmt->flags = 0;
++
++ break;
++
++ case STF_DVP_PAD_SRC:
++
++ *fmt = *__dvp_get_format(dvp_dev, state, STF_DVP_PAD_SINK, which);
++
++ break;
++ }
++}
++
++static int dvp_enum_mbus_code(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_mbus_code_enum *code)
++{
++ struct stf_dvp_dev *dvp_dev = v4l2_get_subdevdata(sd);
++
++ if (code->index >= dvp_dev->nformats)
++ return -EINVAL;
++
++ if (code->pad == STF_DVP_PAD_SINK) {
++ code->code = dvp_dev->formats[code->index].code;
++ } else {
++ struct v4l2_mbus_framefmt *sink_fmt;
++
++ sink_fmt = __dvp_get_format(dvp_dev, state, STF_DVP_PAD_SINK,
++ code->which);
++
++ code->code = sink_fmt->code;
++ if (!code->code)
++ return -EINVAL;
++ }
++ code->flags = 0;
++
++ return 0;
++}
++
++static int dvp_enum_frame_size(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_frame_size_enum *fse)
++{
++ struct stf_dvp_dev *dvp_dev = v4l2_get_subdevdata(sd);
++ struct v4l2_mbus_framefmt format;
++
++ if (fse->index != 0)
++ return -EINVAL;
++
++ format.code = fse->code;
++ format.width = 1;
++ format.height = 1;
++ dvp_try_format(dvp_dev, state, fse->pad, &format, fse->which);
++ fse->min_width = format.width;
++ fse->min_height = format.height;
++
++ if (format.code != fse->code)
++ return -EINVAL;
++
++ format.code = fse->code;
++ format.width = -1;
++ format.height = -1;
++ dvp_try_format(dvp_dev, state, fse->pad, &format, fse->which);
++ fse->max_width = format.width;
++ fse->max_height = format.height;
++
++ return 0;
++}
++
++static int dvp_get_format(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_format *fmt)
++{
++ struct stf_dvp_dev *dvp_dev = v4l2_get_subdevdata(sd);
++ struct v4l2_mbus_framefmt *format;
++
++ format = __dvp_get_format(dvp_dev, state, fmt->pad, fmt->which);
++ if (format == NULL)
++ return -EINVAL;
++
++ fmt->format = *format;
++
++ return 0;
++}
++
++static int dvp_set_format(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_format *fmt)
++{
++ struct stf_dvp_dev *dvp_dev = v4l2_get_subdevdata(sd);
++ struct v4l2_mbus_framefmt *format;
++
++ format = __dvp_get_format(dvp_dev, state, fmt->pad, fmt->which);
++ if (format == NULL)
++ return -EINVAL;
++
++ mutex_lock(&dvp_dev->stream_lock);
++ if (dvp_dev->stream_count) {
++ fmt->format = *format;
++ mutex_unlock(&dvp_dev->stream_lock);
++ goto out;
++ } else {
++ dvp_try_format(dvp_dev, state, fmt->pad, &fmt->format, fmt->which);
++ *format = fmt->format;
++ }
++ mutex_unlock(&dvp_dev->stream_lock);
++
++ /* Propagate the format from sink to source */
++ if (fmt->pad == STF_DVP_PAD_SINK) {
++ format = __dvp_get_format(dvp_dev, state, STF_DVP_PAD_SRC,
++ fmt->which);
++
++ *format = fmt->format;
++ dvp_try_format(dvp_dev, state, STF_DVP_PAD_SRC, format,
++ fmt->which);
++ }
++
++out:
++ return 0;
++}
++
++static int dvp_init_formats(struct v4l2_subdev *sd,
++ struct v4l2_subdev_fh *fh)
++{
++ struct v4l2_subdev_format format = {
++ .pad = STF_DVP_PAD_SINK,
++ .which = fh ? V4L2_SUBDEV_FORMAT_TRY :
++ V4L2_SUBDEV_FORMAT_ACTIVE,
++ .format = {
++ .code = MEDIA_BUS_FMT_RGB565_2X8_LE,
++ .width = 1920,
++ .height = 1080
++ }
++ };
++
++ return dvp_set_format(sd, fh ? fh->state : NULL, &format);
++}
++
++static int dvp_link_setup(struct media_entity *entity,
++ const struct media_pad *local,
++ const struct media_pad *remote, u32 flags)
++{
++ if ((local->flags & MEDIA_PAD_FL_SOURCE) &&
++ (flags & MEDIA_LNK_FL_ENABLED)) {
++ struct v4l2_subdev *sd;
++ struct stf_dvp_dev *dvp_dev;
++ struct vin_line *line;
++
++ if (media_pad_remote_pad_first(local))
++ return -EBUSY;
++
++ sd = media_entity_to_v4l2_subdev(entity);
++ dvp_dev = v4l2_get_subdevdata(sd);
++
++ sd = media_entity_to_v4l2_subdev(remote->entity);
++ line = v4l2_get_subdevdata(sd);
++ if (line->sdev_type == VIN_DEV_TYPE)
++ dvp_dev->s_type = SENSOR_VIN;
++ if (line->sdev_type == ISP_DEV_TYPE)
++ dvp_dev->s_type = SENSOR_ISP;
++ st_info(ST_DVP, "DVP device sensor type: %d\n", dvp_dev->s_type);
++ }
++
++ return 0;
++}
++
++static const struct v4l2_subdev_core_ops dvp_core_ops = {
++ .s_power = dvp_set_power,
++};
++
++static const struct v4l2_subdev_video_ops dvp_video_ops = {
++ .s_stream = dvp_set_stream,
++};
++
++static const struct v4l2_subdev_pad_ops dvp_pad_ops = {
++ .enum_mbus_code = dvp_enum_mbus_code,
++ .enum_frame_size = dvp_enum_frame_size,
++ .get_fmt = dvp_get_format,
++ .set_fmt = dvp_set_format,
++};
++
++static const struct v4l2_subdev_ops dvp_v4l2_ops = {
++ .core = &dvp_core_ops,
++ .video = &dvp_video_ops,
++ .pad = &dvp_pad_ops,
++};
++
++static const struct v4l2_subdev_internal_ops dvp_v4l2_internal_ops = {
++ .open = dvp_init_formats,
++};
++
++static const struct media_entity_operations dvp_media_ops = {
++ .link_setup = dvp_link_setup,
++ .link_validate = v4l2_subdev_link_validate,
++};
++
++int stf_dvp_register(struct stf_dvp_dev *dvp_dev,
++ struct v4l2_device *v4l2_dev)
++{
++ struct v4l2_subdev *sd = &dvp_dev->subdev;
++ struct media_pad *pads = dvp_dev->pads;
++ int ret;
++
++ v4l2_subdev_init(sd, &dvp_v4l2_ops);
++ sd->internal_ops = &dvp_v4l2_internal_ops;
++ sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
++ snprintf(sd->name, ARRAY_SIZE(sd->name), "%s%d",
++ STF_DVP_NAME, 0);
++ v4l2_set_subdevdata(sd, dvp_dev);
++
++ ret = dvp_init_formats(sd, NULL);
++ if (ret < 0) {
++ st_err(ST_DVP, "Failed to init format: %d\n", ret);
++ return ret;
++ }
++
++ pads[STF_DVP_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
++ pads[STF_DVP_PAD_SRC].flags = MEDIA_PAD_FL_SOURCE;
++
++ sd->entity.function = MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER;
++ sd->entity.ops = &dvp_media_ops;
++ ret = media_entity_pads_init(&sd->entity, STF_DVP_PADS_NUM, pads);
++ if (ret < 0) {
++ st_err(ST_DVP, "Failed to init media entity: %d\n", ret);
++ return ret;
++ }
++
++ ret = v4l2_device_register_subdev(v4l2_dev, sd);
++ if (ret < 0) {
++ st_err(ST_DVP, "Failed to register subdev: %d\n", ret);
++ goto err_sreg;
++ }
++
++ return 0;
++
++err_sreg:
++ media_entity_cleanup(&sd->entity);
++ return ret;
++}
++
++int stf_dvp_unregister(struct stf_dvp_dev *dvp_dev)
++{
++ v4l2_device_unregister_subdev(&dvp_dev->subdev);
++ media_entity_cleanup(&dvp_dev->subdev.entity);
++ mutex_destroy(&dvp_dev->stream_lock);
++ return 0;
++}
+--- /dev/null
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_dvp.h
+@@ -0,0 +1,67 @@
++/* SPDX-License-Identifier: GPL-2.0
++ *
++ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
++ *
++ */
++
++#ifndef STF_DVP_H
++#define STF_DVP_H
++
++#include <media/v4l2-subdev.h>
++#include <media/v4l2-device.h>
++#include <media/media-entity.h>
++#include <video/stf-vin.h>
++
++#define STF_DVP_NAME "stf_dvp"
++
++#define STF_DVP_PAD_SINK 0
++#define STF_DVP_PAD_SRC 1
++#define STF_DVP_PADS_NUM 2
++
++struct dvp_format {
++ u32 code;
++ u8 bpp;
++};
++
++enum sensor_type;
++enum subdev_type;
++
++struct dvp_cfg {
++ unsigned int flags;
++ unsigned char bus_width;
++ unsigned char data_shift;
++};
++
++struct stf_dvp_dev;
++
++struct dvp_hw_ops {
++ int (*dvp_clk_enable)(struct stf_dvp_dev *dvp_dev);
++ int (*dvp_clk_disable)(struct stf_dvp_dev *dvp_dev);
++ int (*dvp_config_set)(struct stf_dvp_dev *dvp_dev);
++ int (*dvp_set_format)(struct stf_dvp_dev *dvp_dev,
++ u32 pix_width, u8 bpp);
++ int (*dvp_stream_set)(struct stf_dvp_dev *dvp_dev, int on);
++};
++
++struct stf_dvp_dev {
++ struct stfcamss *stfcamss;
++ struct dvp_cfg *dvp;
++ enum sensor_type s_type;
++ struct v4l2_subdev subdev;
++ struct media_pad pads[STF_DVP_PADS_NUM];
++ struct v4l2_mbus_framefmt fmt[STF_DVP_PADS_NUM];
++ const struct dvp_format *formats;
++ unsigned int nformats;
++ struct dvp_hw_ops *hw_ops;
++ struct mutex stream_lock;
++ int stream_count;
++};
++
++extern int stf_dvp_subdev_init(struct stfcamss *stfcamss);
++extern int stf_dvp_register(struct stf_dvp_dev *dvp_dev,
++ struct v4l2_device *v4l2_dev);
++extern int stf_dvp_unregister(struct stf_dvp_dev *dvp_dev);
++
++extern struct dvp_hw_ops dvp_ops;
++
++#endif /* STF_DVP_H */
+--- /dev/null
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_dvp_hw_ops.c
+@@ -0,0 +1,187 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
++ *
++ */
++
++#include "stfcamss.h"
++
++static int stf_dvp_clk_enable(struct stf_dvp_dev *dvp_dev)
++{
++ struct stfcamss *stfcamss = dvp_dev->stfcamss;
++
++ switch (dvp_dev->s_type) {
++ case SENSOR_VIN:
++ reset_control_deassert(stfcamss->sys_rst[STFRST_AXIWR].rstc);
++ clk_set_phase(stfcamss->sys_clk[STFCLK_DVP_INV].clk, 0);
++ clk_set_parent(stfcamss->sys_clk[STFCLK_AXIWR].clk,
++ stfcamss->sys_clk[STFCLK_DVP_INV].clk);
++ break;
++ case SENSOR_ISP:
++ clk_set_phase(stfcamss->sys_clk[STFCLK_DVP_INV].clk, 0);
++ clk_set_parent(stfcamss->sys_clk[STFCLK_WRAPPER_CLK_C].clk,
++ stfcamss->sys_clk[STFCLK_DVP_INV].clk);
++ break;
++ }
++
++ return 0;
++}
++
++static int stf_dvp_clk_disable(struct stf_dvp_dev *dvp_dev)
++{
++ struct stfcamss *stfcamss = dvp_dev->stfcamss;
++
++ switch (dvp_dev->s_type) {
++ case SENSOR_VIN:
++ clk_set_parent(stfcamss->sys_clk[STFCLK_AXIWR].clk,
++ stfcamss->sys_clk[STFCLK_MIPI_RX0_PXL].clk);
++ reset_control_assert(stfcamss->sys_rst[STFRST_AXIWR].rstc);
++ break;
++ case SENSOR_ISP:
++ clk_set_parent(stfcamss->sys_clk[STFCLK_WRAPPER_CLK_C].clk,
++ stfcamss->sys_clk[STFCLK_MIPI_RX0_PXL].clk);
++ break;
++ }
++
++ return 0;
++}
++
++static int stf_dvp_config_set(struct stf_dvp_dev *dvp_dev)
++{
++
++ struct stf_vin_dev *vin = dvp_dev->stfcamss->vin;
++ unsigned int flags = 0;
++ unsigned char data_shift = 0;
++ u32 polarities = 0;
++
++ if (!dvp_dev->dvp)
++ return -EINVAL;
++
++ flags = dvp_dev->dvp->flags;
++ data_shift = dvp_dev->dvp->data_shift;
++ st_info(ST_DVP, "%s, polarities = 0x%x, flags = 0x%x\n",
++ __func__, polarities, flags);
++
++ if (flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH)
++ polarities |= BIT(1);
++ if (flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH)
++ polarities |= BIT(3);
++ print_reg(ST_DVP, vin->sysctrl_base, SYSCONSAIF_SYSCFG_36);
++ reg_set_bit(vin->sysctrl_base, SYSCONSAIF_SYSCFG_36,
++ U0_VIN_CNFG_DVP_HS_POS
++ | U0_VIN_CNFG_DVP_VS_POS,
++ polarities);
++ print_reg(ST_DVP, vin->sysctrl_base, SYSCONSAIF_SYSCFG_36);
++
++ switch (data_shift) {
++ case 0:
++ data_shift = 0;
++ break;
++ case 2:
++ data_shift = 1;
++ break;
++ case 4:
++ data_shift = 2;
++ break;
++ case 6:
++ data_shift = 3;
++ break;
++ default:
++ data_shift = 0;
++ break;
++ };
++ print_reg(ST_DVP, vin->sysctrl_base, SYSCONSAIF_SYSCFG_28);
++ reg_set_bit(vin->sysctrl_base, SYSCONSAIF_SYSCFG_28,
++ UO_VIN_CNFG_AXIWR0_PIXEL_HEIGH_BIT_SEL,
++ data_shift << 15);
++ print_reg(ST_DVP, vin->sysctrl_base, SYSCONSAIF_SYSCFG_28);
++
++ return 0;
++}
++
++static int set_vin_axiwr_pix_ct(struct stf_vin_dev *vin, u8 bpp)
++{
++ u32 value = 0;
++ int cnfg_axiwr_pix_ct = 64 / bpp;
++
++ // need check
++ if (cnfg_axiwr_pix_ct == 2)
++ value = 1;
++ else if (cnfg_axiwr_pix_ct == 4)
++ value = 1;
++ else if (cnfg_axiwr_pix_ct == 8)
++ value = 0;
++ else
++ return 0;
++
++ print_reg(ST_DVP, vin->sysctrl_base, SYSCONSAIF_SYSCFG_28);
++ reg_set_bit(vin->sysctrl_base,
++ SYSCONSAIF_SYSCFG_28,
++ U0_VIN_CNFG_AXIWR0_PIX_CT,
++ value<<13);
++ print_reg(ST_DVP, vin->sysctrl_base, SYSCONSAIF_SYSCFG_28);
++
++ return cnfg_axiwr_pix_ct;
++
++}
++
++static int stf_dvp_set_format(struct stf_dvp_dev *dvp_dev,
++ u32 pix_width, u8 bpp)
++{
++ struct stf_vin_dev *vin = dvp_dev->stfcamss->vin;
++ int val, pix_ct;
++
++ if (dvp_dev->s_type == SENSOR_VIN) {
++ pix_ct = set_vin_axiwr_pix_ct(vin, bpp);
++ val = (pix_width / pix_ct) - 1;
++ print_reg(ST_DVP, vin->sysctrl_base, SYSCTRL_VIN_WR_PIX_TOTAL);
++ reg_set_bit(vin->sysctrl_base,
++ SYSCONSAIF_SYSCFG_28,
++ U0_VIN_CNFG_AXIWR0_PIX_CNT_END,
++ val << 2);
++ print_reg(ST_DVP, vin->sysctrl_base, SYSCTRL_VIN_WR_PIX_TOTAL);
++
++ }
++
++ return 0;
++}
++
++static int stf_dvp_stream_set(struct stf_dvp_dev *dvp_dev, int on)
++{
++ struct stf_vin_dev *vin = dvp_dev->stfcamss->vin;
++
++ switch (dvp_dev->s_type) {
++ case SENSOR_VIN:
++ reg_set_bit(vin->sysctrl_base, SYSCONSAIF_SYSCFG_36,
++ U0_VIN_CNFG_ISP_DVP_EN0,
++ 0);
++ reg_set_bit(vin->sysctrl_base, SYSCONSAIF_SYSCFG_0,
++ U0_VIN_CNFG_AXI_DVP_EN,
++ !!on<<2);
++ break;
++ case SENSOR_ISP:
++ reg_set_bit(vin->sysctrl_base, SYSCONSAIF_SYSCFG_36,
++ U0_VIN_CNFG_ISP_DVP_EN0,
++ !!on<<5);
++ reg_set_bit(vin->sysctrl_base, SYSCONSAIF_SYSCFG_0,
++ U0_VIN_CNFG_AXI_DVP_EN,
++ 0);
++ reg_set_bit(vin->sysctrl_base, SYSCONSAIF_SYSCFG_36,
++ U0_VIN_CNFG_DVP_SWAP_EN,
++ 0);
++ reg_set_bit(vin->sysctrl_base, SYSCONSAIF_SYSCFG_36,
++ U0_VIN_CNFG_GEN_EN_AXIRD,
++ 0);
++ break;
++ }
++
++ return 0;
++}
++
++struct dvp_hw_ops dvp_ops = {
++ .dvp_clk_enable = stf_dvp_clk_enable,
++ .dvp_clk_disable = stf_dvp_clk_disable,
++ .dvp_config_set = stf_dvp_config_set,
++ .dvp_set_format = stf_dvp_set_format,
++ .dvp_stream_set = stf_dvp_stream_set,
++};
+--- /dev/null
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_event.c
+@@ -0,0 +1,36 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
++ *
++ */
++
++#include <linux/notifier.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/kernel.h>
++#include <linux/fs.h>
++
++static ATOMIC_NOTIFIER_HEAD(vin_notifier_list);
++
++int vin_notifier_register(struct notifier_block *nb)
++{
++ return atomic_notifier_chain_register(&vin_notifier_list, nb);
++}
++EXPORT_SYMBOL_GPL(vin_notifier_register);
++
++void vin_notifier_unregister(struct notifier_block *nb)
++{
++ atomic_notifier_chain_unregister(&vin_notifier_list, nb);
++}
++EXPORT_SYMBOL_GPL(vin_notifier_unregister);
++
++int vin_notifier_call(unsigned long e, void *v)
++{
++ return atomic_notifier_call_chain(&vin_notifier_list, e, v);
++}
++EXPORT_SYMBOL_GPL(vin_notifier_call);
++
++MODULE_AUTHOR("StarFive Technology Co., Ltd.");
++MODULE_DESCRIPTION("Starfive VIC video in notifier");
++MODULE_LICENSE("GPL");
++//MODULE_SUPPORTED_DEVICE("video");
+--- /dev/null
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_isp.c
+@@ -0,0 +1,1521 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
++ *
++ */
++
++#include "stfcamss.h"
++#include <media/v4l2-async.h>
++#include <media/v4l2-ctrls.h>
++#include <media/v4l2-device.h>
++#include <media/v4l2-event.h>
++#include <media/v4l2-fwnode.h>
++#include <media/v4l2-subdev.h>
++#include <linux/firmware.h>
++#include <linux/jh7110-isp.h>
++#include "stf_isp_ioctl.h"
++#include "stf_dmabuf.h"
++
++static int user_config_isp;
++static int isp_set_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_selection *sel);
++
++static struct v4l2_rect *
++__isp_get_compose(struct stf_isp_dev *isp_dev,
++ struct v4l2_subdev_state *state,
++ enum v4l2_subdev_format_whence which);
++
++static struct v4l2_rect *
++__isp_get_crop(struct stf_isp_dev *isp_dev,
++ struct v4l2_subdev_state *state,
++ enum v4l2_subdev_format_whence which);
++
++static struct v4l2_rect *
++__isp_get_scale(struct stf_isp_dev *isp_dev,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_selection *sel);
++
++static struct v4l2_rect *
++__isp_get_itiws(struct stf_isp_dev *isp_dev,
++ struct v4l2_subdev_state *state,
++ enum v4l2_subdev_format_whence which);
++
++// sink format and raw format must one by one
++static const struct isp_format isp_formats_st7110_sink[] = {
++ { MEDIA_BUS_FMT_SRGGB10_1X10, 10},
++ { MEDIA_BUS_FMT_SGRBG10_1X10, 10},
++ { MEDIA_BUS_FMT_SGBRG10_1X10, 10},
++ { MEDIA_BUS_FMT_SBGGR10_1X10, 10},
++};
++
++static const struct isp_format isp_formats_st7110_raw[] = {
++ { MEDIA_BUS_FMT_SRGGB12_1X12, 12},
++ { MEDIA_BUS_FMT_SGRBG12_1X12, 12},
++ { MEDIA_BUS_FMT_SGBRG12_1X12, 12},
++ { MEDIA_BUS_FMT_SBGGR12_1X12, 12},
++};
++
++static const struct isp_format isp_formats_st7110_compat_10bit_raw[] = {
++ { MEDIA_BUS_FMT_SRGGB10_1X10, 10},
++ { MEDIA_BUS_FMT_SGRBG10_1X10, 10},
++ { MEDIA_BUS_FMT_SGBRG10_1X10, 10},
++ { MEDIA_BUS_FMT_SBGGR10_1X10, 10},
++};
++
++static const struct isp_format isp_formats_st7110_compat_8bit_raw[] = {
++ { MEDIA_BUS_FMT_SRGGB8_1X8, 8},
++ { MEDIA_BUS_FMT_SGRBG8_1X8, 8},
++ { MEDIA_BUS_FMT_SGBRG8_1X8, 8},
++ { MEDIA_BUS_FMT_SBGGR8_1X8, 8},
++};
++
++static const struct isp_format isp_formats_st7110_uo[] = {
++ { MEDIA_BUS_FMT_Y12_1X12, 8},
++};
++
++static const struct isp_format isp_formats_st7110_iti[] = {
++ { MEDIA_BUS_FMT_SRGGB10_1X10, 10},
++ { MEDIA_BUS_FMT_SGRBG10_1X10, 10},
++ { MEDIA_BUS_FMT_SGBRG10_1X10, 10},
++ { MEDIA_BUS_FMT_SBGGR10_1X10, 10},
++ { MEDIA_BUS_FMT_SRGGB12_1X12, 12},
++ { MEDIA_BUS_FMT_SGRBG12_1X12, 12},
++ { MEDIA_BUS_FMT_SGBRG12_1X12, 12},
++ { MEDIA_BUS_FMT_SBGGR12_1X12, 12},
++ { MEDIA_BUS_FMT_Y12_1X12, 8},
++ { MEDIA_BUS_FMT_YUV8_1X24, 8},
++};
++
++static const struct isp_format_table isp_formats_st7110[] = {
++ { isp_formats_st7110_sink, ARRAY_SIZE(isp_formats_st7110_sink) }, /* pad 0 */
++ { isp_formats_st7110_uo, ARRAY_SIZE(isp_formats_st7110_uo) }, /* pad 1 */
++ { isp_formats_st7110_uo, ARRAY_SIZE(isp_formats_st7110_uo) }, /* pad 2 */
++ { isp_formats_st7110_uo, ARRAY_SIZE(isp_formats_st7110_uo) }, /* pad 3 */
++ { isp_formats_st7110_iti, ARRAY_SIZE(isp_formats_st7110_iti) }, /* pad 4 */
++ { isp_formats_st7110_iti, ARRAY_SIZE(isp_formats_st7110_iti) }, /* pad 5 */
++ { isp_formats_st7110_raw, ARRAY_SIZE(isp_formats_st7110_raw) }, /* pad 6 */
++ { isp_formats_st7110_raw, ARRAY_SIZE(isp_formats_st7110_raw) }, /* pad 7 */
++};
++
++int stf_isp_subdev_init(struct stfcamss *stfcamss)
++{
++ struct stf_isp_dev *isp_dev = stfcamss->isp_dev;
++
++ isp_dev->sdev_type = ISP_DEV_TYPE;
++ isp_dev->hw_ops = &isp_ops;
++ isp_dev->stfcamss = stfcamss;
++ isp_dev->formats = isp_formats_st7110;
++ isp_dev->nformats = ARRAY_SIZE(isp_formats_st7110);
++ mutex_init(&isp_dev->stream_lock);
++ mutex_init(&isp_dev->power_lock);
++ mutex_init(&isp_dev->setfile_lock);
++ atomic_set(&isp_dev->shadow_count, 0);
++ return 0;
++}
++
++/*
++ * ISP Controls.
++ */
++
++static inline struct v4l2_subdev *ctrl_to_sd(struct v4l2_ctrl *ctrl)
++{
++ return &container_of(ctrl->handler, struct stf_isp_dev,
++ ctrls.handler)->subdev;
++}
++
++static u64 isp_calc_pixel_rate(struct stf_isp_dev *isp_dev)
++{
++ u64 rate = 0;
++
++ return rate;
++}
++
++static int isp_set_ctrl_hue(struct stf_isp_dev *isp_dev, int value)
++{
++ int ret = 0;
++
++ return ret;
++}
++
++static int isp_set_ctrl_contrast(struct stf_isp_dev *isp_dev, int value)
++{
++ int ret = 0;
++
++ return ret;
++}
++
++static int isp_set_ctrl_saturation(struct stf_isp_dev *isp_dev, int value)
++{
++ int ret = 0;
++
++ return ret;
++}
++
++static int isp_set_ctrl_white_balance(struct stf_isp_dev *isp_dev, int awb)
++{
++ struct isp_ctrls *ctrls = &isp_dev->ctrls;
++ int ret = 0;
++
++ if (!awb && (ctrls->red_balance->is_new
++ || ctrls->blue_balance->is_new)) {
++ u16 red = (u16)ctrls->red_balance->val;
++ u16 blue = (u16)ctrls->blue_balance->val;
++
++ st_debug(ST_ISP, "red = 0x%x, blue = 0x%x\n", red, blue);
++ //isp_dev->hw_ops->isp_set_awb_r_gain(isp_dev, red);
++ //if (ret)
++ // return ret;
++ //isp_dev->hw_ops->isp_set_awb_b_gain(isp_dev, blue);
++ }
++
++ return ret;
++}
++
++static int isp_set_ctrl_exposure(struct stf_isp_dev *isp_dev,
++ enum v4l2_exposure_auto_type auto_exposure)
++{
++ int ret = 0;
++
++ return ret;
++}
++
++static int isp_set_ctrl_gain(struct stf_isp_dev *isp_dev, bool auto_gain)
++{
++ int ret = 0;
++
++ return ret;
++}
++
++static const char * const test_pattern_menu[] = {
++ "Disabled",
++ "Color bars",
++ "Color bars w/ rolling bar",
++ "Color squares",
++ "Color squares w/ rolling bar",
++};
++
++#define ISP_TEST_ENABLE BIT(7)
++#define ISP_TEST_ROLLING BIT(6) /* rolling horizontal bar */
++#define ISP_TEST_TRANSPARENT BIT(5)
++#define ISP_TEST_SQUARE_BW BIT(4) /* black & white squares */
++#define ISP_TEST_BAR_STANDARD (0 << 2)
++#define ISP_TEST_BAR_VERT_CHANGE_1 (1 << 2)
++#define ISP_TEST_BAR_HOR_CHANGE (2 << 2)
++#define ISP_TEST_BAR_VERT_CHANGE_2 (3 << 2)
++#define ISP_TEST_BAR (0 << 0)
++#define ISP_TEST_RANDOM (1 << 0)
++#define ISP_TEST_SQUARE (2 << 0)
++#define ISP_TEST_BLACK (3 << 0)
++
++static const u8 test_pattern_val[] = {
++ 0,
++ ISP_TEST_ENABLE | ISP_TEST_BAR_VERT_CHANGE_1 |
++ ISP_TEST_BAR,
++ ISP_TEST_ENABLE | ISP_TEST_ROLLING |
++ ISP_TEST_BAR_VERT_CHANGE_1 | ISP_TEST_BAR,
++ ISP_TEST_ENABLE | ISP_TEST_SQUARE,
++ ISP_TEST_ENABLE | ISP_TEST_ROLLING | ISP_TEST_SQUARE,
++};
++
++static int isp_set_ctrl_test_pattern(struct stf_isp_dev *isp_dev, int value)
++{
++ int ret = 0;
++
++ // return isp_write_reg(isp_dev, ISP_REG_PRE_ISP_TEST_SET1,
++ // test_pattern_val[value]);
++ return ret;
++}
++
++static int isp_set_ctrl_light_freq(struct stf_isp_dev *isp_dev, int value)
++{
++ int ret = 0;
++
++ return ret;
++}
++
++static int isp_set_ctrl_hflip(struct stf_isp_dev *isp_dev, int value)
++{
++ int ret = 0;
++
++ return ret;
++}
++
++static int isp_set_ctrl_vflip(struct stf_isp_dev *isp_dev, int value)
++{
++ int ret = 0;
++
++ return ret;
++}
++
++static int isp_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
++{
++ switch (ctrl->id) {
++ case V4L2_CID_AUTOGAIN:
++ break;
++ case V4L2_CID_EXPOSURE_AUTO:
++ break;
++ }
++
++ return 0;
++}
++
++static int isp_s_ctrl(struct v4l2_ctrl *ctrl)
++{
++ struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
++ struct stf_isp_dev *isp_dev = v4l2_get_subdevdata(sd);
++ int ret = 0;
++
++ /*
++ * If the device is not powered up by the host driver do
++ * not apply any controls to H/W at this time. Instead
++ * the controls will be restored right after power-up.
++ */
++ mutex_lock(&isp_dev->power_lock);
++ if (isp_dev->power_count == 0) {
++ mutex_unlock(&isp_dev->power_lock);
++ return 0;
++ }
++ mutex_unlock(&isp_dev->power_lock);
++
++ switch (ctrl->id) {
++ case V4L2_CID_AUTOGAIN:
++ ret = isp_set_ctrl_gain(isp_dev, ctrl->val);
++ break;
++ case V4L2_CID_EXPOSURE_AUTO:
++ ret = isp_set_ctrl_exposure(isp_dev, ctrl->val);
++ break;
++ case V4L2_CID_AUTO_WHITE_BALANCE:
++ ret = isp_set_ctrl_white_balance(isp_dev, ctrl->val);
++ break;
++ case V4L2_CID_HUE:
++ ret = isp_set_ctrl_hue(isp_dev, ctrl->val);
++ break;
++ case V4L2_CID_CONTRAST:
++ ret = isp_set_ctrl_contrast(isp_dev, ctrl->val);
++ break;
++ case V4L2_CID_SATURATION:
++ ret = isp_set_ctrl_saturation(isp_dev, ctrl->val);
++ break;
++ case V4L2_CID_TEST_PATTERN:
++ ret = isp_set_ctrl_test_pattern(isp_dev, ctrl->val);
++ break;
++ case V4L2_CID_POWER_LINE_FREQUENCY:
++ ret = isp_set_ctrl_light_freq(isp_dev, ctrl->val);
++ break;
++ case V4L2_CID_HFLIP:
++ ret = isp_set_ctrl_hflip(isp_dev, ctrl->val);
++ break;
++ case V4L2_CID_VFLIP:
++ ret = isp_set_ctrl_vflip(isp_dev, ctrl->val);
++ break;
++ case V4L2_CID_USER_JH7110_ISP_WB_SETTING:
++ break;
++ case V4L2_CID_USER_JH7110_ISP_CAR_SETTING:
++ break;
++ case V4L2_CID_USER_JH7110_ISP_CCM_SETTING:
++ break;
++ default:
++ ret = -EINVAL;
++ break;
++ }
++
++ return ret;
++}
++
++static const struct v4l2_ctrl_ops isp_ctrl_ops = {
++ .g_volatile_ctrl = isp_g_volatile_ctrl,
++ .s_ctrl = isp_s_ctrl,
++};
++
++struct v4l2_ctrl_config isp_ctrl[] = {
++ [0] = {
++ .ops = &isp_ctrl_ops,
++ .type = V4L2_CTRL_TYPE_U8,
++ .def = 0,
++ .min = 0x00,
++ .max = 0xff,
++ .step = 1,
++ .name = "WB Setting",
++ .id = V4L2_CID_USER_JH7110_ISP_WB_SETTING,
++ .dims[0] = sizeof(struct jh7110_isp_wb_setting),
++ .flags = 0,
++ },
++ [1] = {
++ .ops = &isp_ctrl_ops,
++ .type = V4L2_CTRL_TYPE_U8,
++ .def = 0,
++ .min = 0x00,
++ .max = 0xff,
++ .step = 1,
++ .name = "Car Setting",
++ .id = V4L2_CID_USER_JH7110_ISP_CAR_SETTING,
++ .dims[0] = sizeof(struct jh7110_isp_car_setting),
++ .flags = 0,
++ },
++ [2] = {
++ .ops = &isp_ctrl_ops,
++ .type = V4L2_CTRL_TYPE_U8,
++ .def = 0,
++ .min = 0x00,
++ .max = 0xff,
++ .step = 1,
++ .name = "CCM Setting",
++ .id = V4L2_CID_USER_JH7110_ISP_CCM_SETTING,
++ .dims[0] = sizeof(struct jh7110_isp_ccm_setting),
++ .flags = 0,
++ },
++};
++
++static int isp_init_controls(struct stf_isp_dev *isp_dev)
++{
++ const struct v4l2_ctrl_ops *ops = &isp_ctrl_ops;
++ struct isp_ctrls *ctrls = &isp_dev->ctrls;
++ struct v4l2_ctrl_handler *hdl = &ctrls->handler;
++ int ret;
++ int i;
++
++ v4l2_ctrl_handler_init(hdl, 32);
++
++ /* Clock related controls */
++ ctrls->pixel_rate = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_PIXEL_RATE,
++ 0, INT_MAX, 1,
++ isp_calc_pixel_rate(isp_dev));
++
++ /* Auto/manual white balance */
++ ctrls->auto_wb = v4l2_ctrl_new_std(hdl, ops,
++ V4L2_CID_AUTO_WHITE_BALANCE,
++ 0, 1, 1, 1);
++ ctrls->blue_balance = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_BLUE_BALANCE,
++ 0, 4095, 1, 0);
++ ctrls->red_balance = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_RED_BALANCE,
++ 0, 4095, 1, 0);
++ /* Auto/manual exposure */
++ ctrls->auto_exp = v4l2_ctrl_new_std_menu(hdl, ops,
++ V4L2_CID_EXPOSURE_AUTO,
++ V4L2_EXPOSURE_MANUAL, 0,
++ V4L2_EXPOSURE_AUTO);
++ ctrls->exposure = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_EXPOSURE,
++ 0, 65535, 1, 0);
++ /* Auto/manual gain */
++ ctrls->auto_gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_AUTOGAIN,
++ 0, 1, 1, 1);
++ ctrls->gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAIN,
++ 0, 1023, 1, 0);
++
++ ctrls->saturation = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_SATURATION,
++ 0, 255, 1, 64);
++ ctrls->hue = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_HUE,
++ 0, 359, 1, 0);
++ ctrls->contrast = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_CONTRAST,
++ 0, 255, 1, 0);
++ ctrls->test_pattern =
++ v4l2_ctrl_new_std_menu_items(hdl, ops, V4L2_CID_TEST_PATTERN,
++ ARRAY_SIZE(test_pattern_menu) - 1,
++ 0, 0, test_pattern_menu);
++ ctrls->hflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_HFLIP,
++ 0, 1, 1, 0);
++ ctrls->vflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_VFLIP,
++ 0, 1, 1, 0);
++
++ ctrls->light_freq =
++ v4l2_ctrl_new_std_menu(hdl, ops,
++ V4L2_CID_POWER_LINE_FREQUENCY,
++ V4L2_CID_POWER_LINE_FREQUENCY_AUTO, 0,
++ V4L2_CID_POWER_LINE_FREQUENCY_50HZ);
++
++ for (i = 0; i < ARRAY_SIZE(isp_ctrl); i++)
++ v4l2_ctrl_new_custom(hdl, &isp_ctrl[i], NULL);
++
++
++ if (hdl->error) {
++ ret = hdl->error;
++ goto free_ctrls;
++ }
++
++ ctrls->pixel_rate->flags |= V4L2_CTRL_FLAG_READ_ONLY;
++ ctrls->gain->flags |= V4L2_CTRL_FLAG_VOLATILE;
++ ctrls->exposure->flags |= V4L2_CTRL_FLAG_VOLATILE;
++
++ v4l2_ctrl_auto_cluster(3, &ctrls->auto_wb, 0, false);
++ v4l2_ctrl_auto_cluster(2, &ctrls->auto_gain, 0, true);
++ v4l2_ctrl_auto_cluster(2, &ctrls->auto_exp, 1, true);
++
++ isp_dev->subdev.ctrl_handler = hdl;
++ return 0;
++
++free_ctrls:
++ v4l2_ctrl_handler_free(hdl);
++ return ret;
++}
++
++static int isp_set_power(struct v4l2_subdev *sd, int on)
++{
++ struct stf_isp_dev *isp_dev = v4l2_get_subdevdata(sd);
++
++ st_debug(ST_ISP, "%s, %d\n", __func__, __LINE__);
++ mutex_lock(&isp_dev->power_lock);
++ if (on) {
++ if (isp_dev->power_count == 0)
++ st_debug(ST_ISP, "turn on isp\n");
++ isp_dev->power_count++;
++ } else {
++ if (isp_dev->power_count == 0)
++ goto exit;
++ isp_dev->power_count--;
++ }
++exit:
++ mutex_unlock(&isp_dev->power_lock);
++
++ return 0;
++}
++
++static struct v4l2_mbus_framefmt *
++__isp_get_format(struct stf_isp_dev *isp_dev,
++ struct v4l2_subdev_state *state,
++ unsigned int pad,
++ enum v4l2_subdev_format_whence which)
++{
++
++ if (which == V4L2_SUBDEV_FORMAT_TRY)
++ return v4l2_subdev_get_try_format(&isp_dev->subdev, state, pad);
++
++ return &isp_dev->fmt[pad];
++}
++
++static int isp_get_interface_type(struct media_entity *entity)
++{
++ struct v4l2_subdev *subdev;
++ struct media_pad *pad = &entity->pads[0];
++
++ if (!(pad->flags & MEDIA_PAD_FL_SINK))
++ return -EINVAL;
++
++ pad = media_pad_remote_pad_first(pad);
++ if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
++ return -EINVAL;
++
++ subdev = media_entity_to_v4l2_subdev(pad->entity);
++
++ st_debug(ST_ISP, "interface subdev name %s\n", subdev->name);
++ if (!strncmp(subdev->name, STF_CSI_NAME, strlen(STF_CSI_NAME)))
++ return CSI_SENSOR;
++ if (!strncmp(subdev->name, STF_DVP_NAME, strlen(STF_DVP_NAME)))
++ return DVP_SENSOR;
++ return -EINVAL;
++}
++
++static int isp_set_stream(struct v4l2_subdev *sd, int enable)
++{
++ struct stf_isp_dev *isp_dev = v4l2_get_subdevdata(sd);
++ int ret = 0, interface_type;
++ struct v4l2_mbus_framefmt *fmt;
++ struct v4l2_event src_ch = { 0 };
++
++ fmt = __isp_get_format(isp_dev, NULL, STF_ISP_PAD_SINK, V4L2_SUBDEV_FORMAT_ACTIVE);
++ mutex_lock(&isp_dev->stream_lock);
++ if (enable) {
++ if (isp_dev->stream_count == 0) {
++ isp_dev->hw_ops->isp_clk_enable(isp_dev);
++ if (!user_config_isp)
++ isp_dev->hw_ops->isp_config_set(isp_dev);
++ interface_type = isp_get_interface_type(&sd->entity);
++ if (interface_type < 0) {
++ st_err(ST_ISP, "%s, pipeline not config\n", __func__);
++ goto exit;
++ }
++ isp_dev->hw_ops->isp_set_format(isp_dev,
++ isp_dev->rect, fmt->code, interface_type);
++ isp_dev->hw_ops->isp_reset(isp_dev);
++ isp_dev->hw_ops->isp_stream_set(isp_dev, enable);
++ user_config_isp = 0;
++ }
++ isp_dev->stream_count++;
++ } else {
++ if (isp_dev->stream_count == 0)
++ goto exit;
++ if (isp_dev->stream_count == 1) {
++ isp_dev->hw_ops->isp_stream_set(isp_dev, enable);
++ isp_dev->hw_ops->isp_clk_disable(isp_dev);
++ }
++ isp_dev->stream_count--;
++ }
++ src_ch.type = V4L2_EVENT_SOURCE_CHANGE,
++ src_ch.u.src_change.changes = isp_dev->stream_count,
++
++ v4l2_subdev_notify_event(sd, &src_ch);
++exit:
++ mutex_unlock(&isp_dev->stream_lock);
++
++ mutex_lock(&isp_dev->power_lock);
++ /* restore controls */
++ if (enable && isp_dev->power_count == 1) {
++ mutex_unlock(&isp_dev->power_lock);
++ ret = v4l2_ctrl_handler_setup(&isp_dev->ctrls.handler);
++ } else
++ mutex_unlock(&isp_dev->power_lock);
++
++ return ret;
++}
++
++/*Try to match sensor format with sink, and then get the index as default.*/
++static int isp_match_sensor_format_get_index(struct stf_isp_dev *isp_dev)
++{
++ int ret, idx;
++ struct media_entity *sensor;
++ struct v4l2_subdev *subdev;
++ struct v4l2_subdev_format fmt;
++ const struct isp_format_table *formats;
++
++ if (!isp_dev)
++ return -EINVAL;
++
++ sensor = stfcamss_find_sensor(&isp_dev->subdev.entity);
++ if (!sensor)
++ return -EINVAL;
++
++ subdev = media_entity_to_v4l2_subdev(sensor);
++ st_debug(ST_ISP, "Found sensor = %s\n", sensor->name);
++
++ fmt.pad = 0;
++ fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
++ ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &fmt);
++ if (ret) {
++ st_warn(ST_ISP, "Sonser get format failed !!\n");
++ return -EINVAL;
++ }
++
++ st_debug(ST_ISP, "Got sensor format 0x%x !!\n", fmt.format.code);
++
++ formats = &isp_dev->formats[0]; /* isp sink format */
++ for (idx = 0; idx < formats->nfmts; idx++) {
++ if (formats->fmts[idx].code == fmt.format.code) {
++ st_info(ST_ISP,
++ "Match sensor format to isp_formats_st7110_sink index %d !!\n",
++ idx);
++ return idx;
++ }
++ }
++ return -ERANGE;
++}
++
++static int isp_match_format_get_index(const struct isp_format_table *f_table,
++ __u32 mbus_code,
++ unsigned int pad)
++{
++ int i;
++
++ for (i = 0; i < f_table->nfmts; i++) {
++ if (mbus_code == f_table->fmts[i].code) {
++ break;
++ } else {
++ if (pad == STF_ISP_PAD_SRC_RAW || pad == STF_ISP_PAD_SRC_SCD_Y) {
++ if (mbus_code == (isp_formats_st7110_compat_10bit_raw[i].code ||
++ isp_formats_st7110_compat_8bit_raw[i].code))
++ break;
++ }
++ }
++ }
++
++ return i;
++}
++
++static void isp_try_format(struct stf_isp_dev *isp_dev,
++ struct v4l2_subdev_state *state,
++ unsigned int pad,
++ struct v4l2_mbus_framefmt *fmt,
++ enum v4l2_subdev_format_whence which)
++{
++ const struct isp_format_table *formats;
++ unsigned int i;
++ u32 code = fmt->code;
++ u32 bpp;
++
++ if (pad == STF_ISP_PAD_SINK) {
++ /* Set format on sink pad */
++
++ formats = &isp_dev->formats[pad];
++ fmt->width = clamp_t(u32,
++ fmt->width, STFCAMSS_FRAME_MIN_WIDTH,
++ STFCAMSS_FRAME_MAX_WIDTH);
++ fmt->height = clamp_t(u32,
++ fmt->height, STFCAMSS_FRAME_MIN_HEIGHT,
++ STFCAMSS_FRAME_MAX_HEIGHT);
++ fmt->height &= ~0x1;
++
++ fmt->field = V4L2_FIELD_NONE;
++ fmt->colorspace = V4L2_COLORSPACE_SRGB;
++ fmt->flags = 0;
++ } else {
++ formats = &isp_dev->formats[pad];
++ }
++
++ i = isp_match_format_get_index(formats, fmt->code, pad);
++ st_debug(ST_ISP, "%s pad=%d, code=%x isp_match_format_get_index = %d\n",
++ __func__, pad, code, i);
++
++ if (i >= formats->nfmts &&
++ (pad == STF_ISP_PAD_SRC_RAW || pad == STF_ISP_PAD_SRC_SCD_Y)) {
++ int sensor_idx;
++
++ sensor_idx = isp_match_sensor_format_get_index(isp_dev);
++ if (sensor_idx)
++ i = sensor_idx;
++ }
++
++ if (pad != STF_ISP_PAD_SINK)
++ *fmt = *__isp_get_format(isp_dev, state, STF_ISP_PAD_SINK, which);
++
++ if (i >= formats->nfmts) {
++ fmt->code = formats->fmts[0].code;
++ bpp = formats->fmts[0].bpp;
++ st_info(ST_ISP, "Use default index 0 format = 0x%x\n", fmt->code);
++ } else {
++ // sink format and raw format must one by one
++ if (pad == STF_ISP_PAD_SRC_RAW || pad == STF_ISP_PAD_SRC_SCD_Y) {
++ fmt->code = formats->fmts[i].code;
++ bpp = formats->fmts[i].bpp;
++ st_info(ST_ISP, "Use mapping format from sink index %d = 0x%x\n",
++ i, fmt->code);
++ } else {
++ fmt->code = code;
++ bpp = formats->fmts[i].bpp;
++ st_info(ST_ISP, "Use input format = 0x%x\n", fmt->code);
++ }
++ }
++
++ switch (pad) {
++ case STF_ISP_PAD_SINK:
++ break;
++ case STF_ISP_PAD_SRC:
++ isp_dev->rect[ISP_COMPOSE].bpp = bpp;
++ break;
++ case STF_ISP_PAD_SRC_SS0:
++ isp_dev->rect[ISP_SCALE_SS0].bpp = bpp;
++ break;
++ case STF_ISP_PAD_SRC_SS1:
++ isp_dev->rect[ISP_SCALE_SS1].bpp = bpp;
++ break;
++ case STF_ISP_PAD_SRC_ITIW:
++ case STF_ISP_PAD_SRC_ITIR:
++ isp_dev->rect[ISP_ITIWS].bpp = bpp;
++ break;
++ case STF_ISP_PAD_SRC_RAW:
++ isp_dev->rect[ISP_CROP].bpp = bpp;
++ break;
++ case STF_ISP_PAD_SRC_SCD_Y:
++ break;
++ }
++}
++
++static int isp_enum_mbus_code(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_mbus_code_enum *code)
++{
++ struct stf_isp_dev *isp_dev = v4l2_get_subdevdata(sd);
++ const struct isp_format_table *formats;
++
++ if (code->index >= isp_dev->formats[code->pad].nfmts)
++ return -EINVAL;
++
++ formats = &isp_dev->formats[code->pad];
++ code->code = formats->fmts[code->index].code;
++ code->flags = 0;
++
++ return 0;
++}
++
++static int isp_enum_frame_size(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_frame_size_enum *fse)
++{
++ struct stf_isp_dev *isp_dev = v4l2_get_subdevdata(sd);
++ struct v4l2_mbus_framefmt format;
++
++ if (fse->index != 0)
++ return -EINVAL;
++
++ format.code = fse->code;
++ format.width = 1;
++ format.height = 1;
++ isp_try_format(isp_dev, state, fse->pad, &format, fse->which);
++ fse->min_width = format.width;
++ fse->min_height = format.height;
++
++ if (format.code != fse->code)
++ return -EINVAL;
++
++ format.code = fse->code;
++ format.width = -1;
++ format.height = -1;
++ isp_try_format(isp_dev, state, fse->pad, &format, fse->which);
++ fse->max_width = format.width;
++ fse->max_height = format.height;
++
++ return 0;
++}
++
++static int isp_get_format(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_format *fmt)
++{
++ struct stf_isp_dev *isp_dev = v4l2_get_subdevdata(sd);
++ struct v4l2_mbus_framefmt *format;
++
++ format = __isp_get_format(isp_dev, state, fmt->pad, fmt->which);
++ if (format == NULL)
++ return -EINVAL;
++
++ fmt->format = *format;
++
++ return 0;
++}
++
++static int isp_set_format(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_format *fmt)
++{
++ struct stf_isp_dev *isp_dev = v4l2_get_subdevdata(sd);
++ struct v4l2_mbus_framefmt *format;
++ struct v4l2_subdev_selection sel = { 0 };
++ struct v4l2_rect *rect = NULL;
++ int ret;
++
++ st_debug(ST_ISP, "%s pad=%d, code=%x, which=%d\n",
++ __func__, fmt->reserved[0], fmt->format.code, fmt->which);
++ format = __isp_get_format(isp_dev, state, fmt->pad, fmt->which);
++ if (format == NULL)
++ return -EINVAL;
++
++ mutex_lock(&isp_dev->stream_lock);
++ if (isp_dev->stream_count) {
++ fmt->format = *format;
++ if (fmt->reserved[0] != 0) {
++ sel.which = fmt->which;
++ sel.pad = fmt->reserved[0];
++
++ switch (fmt->reserved[0]) {
++ case STF_ISP_PAD_SRC:
++ rect = __isp_get_compose(isp_dev, state, fmt->which);
++ break;
++ case STF_ISP_PAD_SRC_SS0:
++ case STF_ISP_PAD_SRC_SS1:
++ rect = __isp_get_scale(isp_dev, state, &sel);
++ break;
++ case STF_ISP_PAD_SRC_ITIW:
++ case STF_ISP_PAD_SRC_ITIR:
++ rect = __isp_get_itiws(isp_dev, state, fmt->which);
++ break;
++ case STF_ISP_PAD_SRC_RAW:
++ case STF_ISP_PAD_SRC_SCD_Y:
++ rect = __isp_get_crop(isp_dev, state, fmt->which);
++ break;
++ default:
++ break;
++ }
++ if (rect != NULL) {
++ fmt->format.width = rect->width;
++ fmt->format.height = rect->height;
++ }
++ }
++ mutex_unlock(&isp_dev->stream_lock);
++ goto out;
++ } else {
++ isp_try_format(isp_dev, state, fmt->pad, &fmt->format, fmt->which);
++ *format = fmt->format;
++ }
++ mutex_unlock(&isp_dev->stream_lock);
++
++ /* Propagate the format from sink to source */
++ if (fmt->pad == STF_ISP_PAD_SINK) {
++ /* Reset sink pad compose selection */
++ sel.which = fmt->which;
++ sel.pad = STF_ISP_PAD_SINK;
++ sel.target = V4L2_SEL_TGT_CROP;
++ sel.r.width = fmt->format.width;
++ sel.r.height = fmt->format.height;
++ ret = isp_set_selection(sd, state, &sel);
++ if (ret < 0)
++ return ret;
++ }
++
++out:
++ return 0;
++}
++
++static struct v4l2_rect *
++__isp_get_compose(struct stf_isp_dev *isp_dev,
++ struct v4l2_subdev_state *state,
++ enum v4l2_subdev_format_whence which)
++{
++ if (which == V4L2_SUBDEV_FORMAT_TRY)
++ return v4l2_subdev_get_try_compose(&isp_dev->subdev, state,
++ STF_ISP_PAD_SINK);
++
++
++ return &isp_dev->rect[ISP_COMPOSE].rect;
++}
++
++static struct v4l2_rect *
++__isp_get_crop(struct stf_isp_dev *isp_dev,
++ struct v4l2_subdev_state *state,
++ enum v4l2_subdev_format_whence which)
++{
++ if (which == V4L2_SUBDEV_FORMAT_TRY)
++ return v4l2_subdev_get_try_crop(&isp_dev->subdev, state,
++ STF_ISP_PAD_SINK);
++
++ return &isp_dev->rect[ISP_CROP].rect;
++}
++
++static struct v4l2_rect *
++__isp_get_scale(struct stf_isp_dev *isp_dev,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_selection *sel)
++{
++ int pad;
++
++ if (sel->which == V4L2_SUBDEV_FORMAT_TRY)
++ return v4l2_subdev_get_try_compose(&isp_dev->subdev, state,
++ STF_ISP_PAD_SINK);
++ if (sel->pad != STF_ISP_PAD_SRC_SS0 && sel->pad != STF_ISP_PAD_SRC_SS1)
++ return NULL;
++
++ pad = sel->pad == STF_ISP_PAD_SRC_SS0 ? ISP_SCALE_SS0 : ISP_SCALE_SS1;
++ return &isp_dev->rect[pad].rect;
++}
++
++static struct v4l2_rect *
++__isp_get_itiws(struct stf_isp_dev *isp_dev,
++ struct v4l2_subdev_state *state,
++ enum v4l2_subdev_format_whence which)
++{
++ if (which == V4L2_SUBDEV_FORMAT_TRY)
++ return v4l2_subdev_get_try_crop(&isp_dev->subdev, state, STF_ISP_PAD_SINK);
++
++ return &isp_dev->rect[ISP_ITIWS].rect;
++}
++
++static void isp_try_crop(struct stf_isp_dev *isp_dev,
++ struct v4l2_subdev_state *state,
++ struct v4l2_rect *rect,
++ enum v4l2_subdev_format_whence which)
++{
++ struct v4l2_mbus_framefmt *fmt;
++
++ fmt = __isp_get_format(isp_dev, state, STF_ISP_PAD_SINK, which);
++
++ if (rect->width > fmt->width)
++ rect->width = fmt->width;
++
++ if (rect->width + rect->left > fmt->width)
++ rect->left = fmt->width - rect->width;
++
++ if (rect->height > fmt->height)
++ rect->height = fmt->height;
++
++ if (rect->height + rect->top > fmt->height)
++ rect->top = fmt->height - rect->height;
++
++ if (rect->width < STFCAMSS_FRAME_MIN_WIDTH) {
++ rect->left = 0;
++ rect->width = STFCAMSS_FRAME_MIN_WIDTH;
++ }
++
++ if (rect->height < STFCAMSS_FRAME_MIN_HEIGHT) {
++ rect->top = 0;
++ rect->height = STFCAMSS_FRAME_MIN_HEIGHT;
++ }
++ rect->height &= ~0x1;
++}
++
++static void isp_try_compose(struct stf_isp_dev *isp_dev,
++ struct v4l2_subdev_state *state,
++ struct v4l2_rect *rect,
++ enum v4l2_subdev_format_whence which)
++{
++ struct v4l2_rect *crop;
++
++ crop = __isp_get_crop(isp_dev, state, which);
++
++ if (rect->width > crop->width)
++ rect->width = crop->width;
++
++ if (rect->height > crop->height)
++ rect->height = crop->height;
++
++ if (crop->width > rect->width * SCALER_RATIO_MAX)
++ rect->width = (crop->width + SCALER_RATIO_MAX - 1) /
++ SCALER_RATIO_MAX;
++
++ if (crop->height > rect->height * SCALER_RATIO_MAX)
++ rect->height = (crop->height + SCALER_RATIO_MAX - 1) /
++ SCALER_RATIO_MAX;
++
++ if (rect->width < STFCAMSS_FRAME_MIN_WIDTH)
++ rect->width = STFCAMSS_FRAME_MIN_WIDTH;
++
++ if (rect->height < STFCAMSS_FRAME_MIN_HEIGHT)
++ rect->height = STFCAMSS_FRAME_MIN_HEIGHT;
++ rect->height &= ~0x1;
++}
++
++static void isp_try_scale(struct stf_isp_dev *isp_dev,
++ struct v4l2_subdev_state *state,
++ struct v4l2_rect *rect,
++ enum v4l2_subdev_format_whence which)
++{
++ struct v4l2_rect *compose;
++
++ compose = __isp_get_compose(isp_dev, state, which);
++
++ if (rect->width > compose->width)
++ rect->width = compose->width;
++
++ if (rect->width + rect->left > compose->width)
++ rect->left = compose->width - rect->width;
++
++ if (rect->height > compose->height)
++ rect->height = compose->height;
++
++ if (rect->height + rect->top > compose->height)
++ rect->top = compose->height - rect->height;
++
++ if (rect->width < STFCAMSS_FRAME_MIN_WIDTH) {
++ rect->left = 0;
++ rect->width = STFCAMSS_FRAME_MIN_WIDTH;
++ }
++
++ if (rect->height < STFCAMSS_FRAME_MIN_HEIGHT) {
++ rect->top = 0;
++ rect->height = STFCAMSS_FRAME_MIN_HEIGHT;
++ }
++ rect->height &= ~0x1;
++}
++
++static void isp_try_itiws(struct stf_isp_dev *isp_dev,
++ struct v4l2_subdev_state *state,
++ struct v4l2_rect *rect,
++ enum v4l2_subdev_format_whence which)
++{
++ struct v4l2_rect *crop;
++
++ crop = __isp_get_crop(isp_dev, state, which);
++
++ if (rect->width > crop->width)
++ rect->width = crop->width;
++
++ if (rect->width + rect->left > crop->width)
++ rect->left = crop->width - rect->width;
++
++ if (rect->height > crop->height)
++ rect->height = crop->height;
++
++ if (rect->height + rect->top > crop->height)
++ rect->top = crop->height - rect->height;
++
++ if (rect->width < STFCAMSS_FRAME_MIN_WIDTH) {
++ rect->left = 0;
++ rect->width = STFCAMSS_FRAME_MIN_WIDTH;
++ }
++
++ if (rect->height < STFCAMSS_FRAME_MIN_HEIGHT) {
++ rect->top = 0;
++ rect->height = STFCAMSS_FRAME_MIN_HEIGHT;
++ }
++ rect->height &= ~0x1;
++}
++
++static int isp_get_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_selection *sel)
++{
++ struct stf_isp_dev *isp_dev = v4l2_get_subdevdata(sd);
++ struct v4l2_subdev_format fmt = { 0 };
++ struct v4l2_rect *rect;
++ int ret;
++
++ switch (sel->target) {
++ case V4L2_SEL_TGT_CROP_BOUNDS:
++ case V4L2_SEL_TGT_CROP_DEFAULT:
++ fmt.pad = sel->pad;
++ fmt.which = sel->which;
++ ret = isp_get_format(sd, state, &fmt);
++ if (ret < 0)
++ return ret;
++
++ sel->r.left = 0;
++ sel->r.top = 0;
++ sel->r.width = fmt.format.width;
++ sel->r.height = fmt.format.height;
++ break;
++ case V4L2_SEL_TGT_CROP:
++ rect = __isp_get_crop(isp_dev, state, sel->which);
++ if (rect == NULL)
++ return -EINVAL;
++
++ sel->r = *rect;
++ break;
++ case V4L2_SEL_TGT_COMPOSE_BOUNDS:
++ case V4L2_SEL_TGT_COMPOSE_DEFAULT:
++ if (sel->pad > STF_ISP_PAD_SRC_ITIR)
++ return -EINVAL;
++ rect = __isp_get_crop(isp_dev, state, sel->which);
++ if (rect == NULL)
++ return -EINVAL;
++
++ sel->r.left = rect->left;
++ sel->r.top = rect->top;
++ sel->r.width = rect->width;
++ sel->r.height = rect->height;
++ break;
++ case V4L2_SEL_TGT_COMPOSE:
++ if (sel->pad > STF_ISP_PAD_SRC_ITIR)
++ return -EINVAL;
++ if (sel->pad == STF_ISP_PAD_SRC_SS0
++ || sel->pad == STF_ISP_PAD_SRC_SS1) {
++ rect = __isp_get_scale(isp_dev, state, sel);
++ if (rect == NULL)
++ return -EINVAL;
++ } else if (sel->pad == STF_ISP_PAD_SRC_ITIW
++ || sel->pad == STF_ISP_PAD_SRC_ITIR) {
++ rect = __isp_get_itiws(isp_dev, state, sel->which);
++ if (rect == NULL)
++ return -EINVAL;
++ } else {
++ rect = __isp_get_compose(isp_dev, state, sel->which);
++ if (rect == NULL)
++ return -EINVAL;
++ }
++ sel->r = *rect;
++ break;
++ default:
++ return -EINVAL;
++ }
++
++ st_info(ST_ISP, "%s pad = %d, left = %d, %d, %d, %d\n",
++ __func__, sel->pad, sel->r.left, sel->r.top, sel->r.width, sel->r.height);
++ return 0;
++}
++
++static int isp_set_selection(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_selection *sel)
++{
++ struct stf_isp_dev *isp_dev = v4l2_get_subdevdata(sd);
++ struct v4l2_rect *rect;
++ int ret = 0;
++
++ if (sel->target == V4L2_SEL_TGT_COMPOSE &&
++ ((sel->pad == STF_ISP_PAD_SINK)
++ || (sel->pad == STF_ISP_PAD_SRC))) {
++ struct v4l2_subdev_format fmt = { 0 };
++ int i;
++
++ rect = __isp_get_compose(isp_dev, state, sel->which);
++ if (rect == NULL)
++ return -EINVAL;
++
++ mutex_lock(&isp_dev->stream_lock);
++ if (isp_dev->stream_count) {
++ sel->r = *rect;
++ mutex_unlock(&isp_dev->stream_lock);
++ ret = 0;
++ goto out;
++ } else {
++ isp_try_compose(isp_dev, state, &sel->r, sel->which);
++ *rect = sel->r;
++ }
++ mutex_unlock(&isp_dev->stream_lock);
++
++ /* Reset source pad format width and height */
++ fmt.which = sel->which;
++ fmt.pad = STF_ISP_PAD_SRC;
++ ret = isp_get_format(sd, state, &fmt);
++ if (ret < 0)
++ return ret;
++
++ fmt.format.width = rect->width;
++ fmt.format.height = rect->height;
++ ret = isp_set_format(sd, state, &fmt);
++
++ /* Reset scale */
++ for (i = STF_ISP_PAD_SRC_SS0; i <= STF_ISP_PAD_SRC_ITIR; i++) {
++ struct v4l2_subdev_selection scale = { 0 };
++
++ scale.which = sel->which;
++ scale.target = V4L2_SEL_TGT_COMPOSE;
++ scale.r = *rect;
++ scale.pad = i;
++ ret = isp_set_selection(sd, state, &scale);
++ }
++ } else if (sel->target == V4L2_SEL_TGT_COMPOSE
++ && ((sel->pad == STF_ISP_PAD_SRC_SS0)
++ || (sel->pad == STF_ISP_PAD_SRC_SS1))) {
++ struct v4l2_subdev_format fmt = { 0 };
++
++ rect = __isp_get_scale(isp_dev, state, sel);
++ if (rect == NULL)
++ return -EINVAL;
++
++ mutex_lock(&isp_dev->stream_lock);
++ if (isp_dev->stream_count) {
++ sel->r = *rect;
++ mutex_unlock(&isp_dev->stream_lock);
++ ret = 0;
++ goto out;
++ } else {
++ isp_try_scale(isp_dev, state, &sel->r, sel->which);
++ *rect = sel->r;
++ }
++ mutex_unlock(&isp_dev->stream_lock);
++
++ /* Reset source pad format width and height */
++ fmt.which = sel->which;
++ fmt.pad = sel->pad;
++ ret = isp_get_format(sd, state, &fmt);
++ if (ret < 0)
++ return ret;
++
++ fmt.format.width = rect->width;
++ fmt.format.height = rect->height;
++ ret = isp_set_format(sd, state, &fmt);
++ } else if (sel->target == V4L2_SEL_TGT_COMPOSE
++ && ((sel->pad == STF_ISP_PAD_SRC_ITIW)
++ || (sel->pad == STF_ISP_PAD_SRC_ITIR))) {
++ struct v4l2_subdev_format fmt = { 0 };
++
++ rect = __isp_get_itiws(isp_dev, state, sel->which);
++ if (rect == NULL)
++ return -EINVAL;
++
++ mutex_lock(&isp_dev->stream_lock);
++ if (isp_dev->stream_count) {
++ sel->r = *rect;
++ mutex_unlock(&isp_dev->stream_lock);
++ ret = 0;
++ goto out;
++ } else {
++ isp_try_itiws(isp_dev, state, &sel->r, sel->which);
++ *rect = sel->r;
++ }
++ mutex_unlock(&isp_dev->stream_lock);
++
++ /* Reset source pad format width and height */
++ fmt.which = sel->which;
++ fmt.pad = sel->pad;
++ ret = isp_get_format(sd, state, &fmt);
++ if (ret < 0)
++ return ret;
++
++ fmt.format.width = rect->width;
++ fmt.format.height = rect->height;
++ ret = isp_set_format(sd, state, &fmt);
++ } else if (sel->target == V4L2_SEL_TGT_CROP) {
++ struct v4l2_subdev_selection compose = { 0 };
++ int i;
++
++ rect = __isp_get_crop(isp_dev, state, sel->which);
++ if (rect == NULL)
++ return -EINVAL;
++
++ mutex_lock(&isp_dev->stream_lock);
++ if (isp_dev->stream_count) {
++ sel->r = *rect;
++ mutex_unlock(&isp_dev->stream_lock);
++ ret = 0;
++ goto out;
++ } else {
++ isp_try_crop(isp_dev, state, &sel->r, sel->which);
++ *rect = sel->r;
++ }
++ mutex_unlock(&isp_dev->stream_lock);
++
++ /* Reset source compose selection */
++ compose.which = sel->which;
++ compose.target = V4L2_SEL_TGT_COMPOSE;
++ compose.r.width = rect->width;
++ compose.r.height = rect->height;
++ compose.pad = STF_ISP_PAD_SINK;
++ ret = isp_set_selection(sd, state, &compose);
++
++ /* Reset source pad format width and height */
++ for (i = STF_ISP_PAD_SRC_RAW; i < STF_ISP_PAD_MAX; i++) {
++ struct v4l2_subdev_format fmt = { 0 };
++
++ fmt.which = sel->which;
++ fmt.pad = i;
++ ret = isp_get_format(sd, state, &fmt);
++ if (ret < 0)
++ return ret;
++
++ fmt.format.width = rect->width;
++ fmt.format.height = rect->height;
++ ret = isp_set_format(sd, state, &fmt);
++ }
++ } else {
++ ret = -EINVAL;
++ }
++
++ st_info(ST_ISP, "%s pad = %d, left = %d, %d, %d, %d\n",
++ __func__, sel->pad, sel->r.left, sel->r.top, sel->r.width, sel->r.height);
++out:
++ return ret;
++}
++
++static int isp_init_formats(struct v4l2_subdev *sd,
++ struct v4l2_subdev_fh *fh)
++{
++ struct v4l2_subdev_format format = {
++ .pad = STF_ISP_PAD_SINK,
++ .which = fh ? V4L2_SUBDEV_FORMAT_TRY :
++ V4L2_SUBDEV_FORMAT_ACTIVE,
++ .format = {
++ .code = MEDIA_BUS_FMT_RGB565_2X8_LE,
++ .width = 1920,
++ .height = 1080
++ }
++ };
++
++ return isp_set_format(sd, fh ? fh->state : NULL, &format);
++}
++
++static int isp_link_setup(struct media_entity *entity,
++ const struct media_pad *local,
++ const struct media_pad *remote, u32 flags)
++{
++ if (flags & MEDIA_LNK_FL_ENABLED)
++ if (media_pad_remote_pad_first(local))
++ return -EBUSY;
++ return 0;
++}
++
++static int stf_isp_load_setfile(struct stf_isp_dev *isp_dev, char *file_name)
++{
++ struct device *dev = isp_dev->stfcamss->dev;
++ const struct firmware *fw;
++ u8 *buf = NULL;
++ int *regval_num;
++ int ret;
++
++ st_debug(ST_ISP, "%s, file_name %s\n", __func__, file_name);
++ ret = request_firmware(&fw, file_name, dev);
++ if (ret < 0) {
++ st_err(ST_ISP, "firmware request failed (%d)\n", ret);
++ return ret;
++ }
++ buf = devm_kzalloc(dev, fw->size, GFP_KERNEL);
++ if (!buf)
++ return -ENOMEM;
++ memcpy(buf, fw->data, fw->size);
++
++ mutex_lock(&isp_dev->setfile_lock);
++ if (isp_dev->setfile.state == 1)
++ devm_kfree(dev, isp_dev->setfile.data);
++ isp_dev->setfile.data = buf;
++ isp_dev->setfile.size = fw->size;
++ isp_dev->setfile.state = 1;
++ regval_num = (int *)&buf[fw->size - sizeof(unsigned int)];
++ isp_dev->setfile.settings.regval_num = *regval_num;
++ isp_dev->setfile.settings.regval = (struct regval_t *)buf;
++ mutex_unlock(&isp_dev->setfile_lock);
++
++ st_debug(ST_ISP, "stf_isp setfile loaded size: %zu B, reg_nul: %d\n",
++ fw->size, isp_dev->setfile.settings.regval_num);
++
++ release_firmware(fw);
++ return ret;
++}
++
++static long stf_isp_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
++{
++ struct stf_isp_dev *isp_dev = v4l2_get_subdevdata(sd);
++ struct device *dev = isp_dev->stfcamss->dev;
++ int ret = -ENOIOCTLCMD;
++
++ switch (cmd) {
++ case VIDIOC_STFISP_LOAD_FW: {
++ struct stfisp_fw_info *fw_info = arg;
++
++ if (IS_ERR(fw_info)) {
++ st_err(ST_ISP, "fw_info failed, params invaild\n");
++ return -EINVAL;
++ }
++
++ ret = stf_isp_load_setfile(isp_dev, fw_info->filename);
++ break;
++ }
++ case VIDIOC_STF_DMABUF_ALLOC:
++ case VIDIOC_STF_DMABUF_FREE:
++ ret = stf_dmabuf_ioctl(dev, cmd, arg);
++ break;
++ case VIDIOC_STFISP_GET_REG:
++ ret = isp_dev->hw_ops->isp_reg_read(isp_dev, arg);
++ break;
++ case VIDIOC_STFISP_SET_REG:
++ ret = isp_dev->hw_ops->isp_reg_write(isp_dev, arg);
++ break;
++ case VIDIOC_STFISP_SHADOW_LOCK:
++ if (atomic_add_unless(&isp_dev->shadow_count, 1, 1))
++ ret = 0;
++ else
++ ret = -EBUSY;
++ st_debug(ST_ISP, "%s, %d, ret = %d\n", __func__, __LINE__, ret);
++ break;
++ case VIDIOC_STFISP_SHADOW_UNLOCK:
++ if (atomic_dec_if_positive(&isp_dev->shadow_count) < 0)
++ ret = -EINVAL;
++ else
++ ret = 0;
++ st_debug(ST_ISP, "%s, %d, ret = %d\n", __func__, __LINE__, ret);
++ break;
++ case VIDIOC_STFISP_SHADOW_UNLOCK_N_TRIGGER:
++ {
++ isp_dev->hw_ops->isp_shadow_trigger(isp_dev);
++ if (atomic_dec_if_positive(&isp_dev->shadow_count) < 0)
++ ret = -EINVAL;
++ else
++ ret = 0;
++ st_debug(ST_ISP, "%s, %d, ret = %d\n", __func__, __LINE__, ret);
++ }
++ break;
++ case VIDIOC_STFISP_SET_USER_CONFIG_ISP:
++ st_debug(ST_ISP, "%s, %d set user_config_isp\n", __func__, __LINE__);
++ user_config_isp = 1;
++ break;
++ default:
++ break;
++ }
++ return ret;
++}
++
++int isp_close(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
++{
++ struct stf_isp_dev *isp_dev = v4l2_get_subdevdata(sd);
++
++ st_debug(ST_ISP, "%s, %d\n", __func__, __LINE__);
++ while (atomic_dec_if_positive(&isp_dev->shadow_count) > 0)
++ st_warn(ST_ISP, "user not unlocked the shadow lock, driver unlock it!\n");
++
++ return 0;
++}
++
++static int stf_isp_subscribe_event(struct v4l2_subdev *sd,
++ struct v4l2_fh *fh,
++ struct v4l2_event_subscription *sub)
++{
++ switch (sub->type) {
++ case V4L2_EVENT_SOURCE_CHANGE:
++ return v4l2_src_change_event_subdev_subscribe(sd, fh, sub);
++ case V4L2_EVENT_CTRL:
++ return v4l2_ctrl_subdev_subscribe_event(sd, fh, sub);
++ default:
++ st_debug(ST_ISP, "unspport subscribe_event\n");
++ return -EINVAL;
++ }
++}
++
++static const struct v4l2_subdev_core_ops isp_core_ops = {
++ .s_power = isp_set_power,
++ .ioctl = stf_isp_ioctl,
++ .log_status = v4l2_ctrl_subdev_log_status,
++ // .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
++ .subscribe_event = stf_isp_subscribe_event,
++ .unsubscribe_event = v4l2_event_subdev_unsubscribe,
++};
++
++static const struct v4l2_subdev_video_ops isp_video_ops = {
++ .s_stream = isp_set_stream,
++};
++
++static const struct v4l2_subdev_pad_ops isp_pad_ops = {
++ .enum_mbus_code = isp_enum_mbus_code,
++ .enum_frame_size = isp_enum_frame_size,
++ .get_fmt = isp_get_format,
++ .set_fmt = isp_set_format,
++ .get_selection = isp_get_selection,
++ .set_selection = isp_set_selection,
++};
++
++static const struct v4l2_subdev_ops isp_v4l2_ops = {
++ .core = &isp_core_ops,
++ .video = &isp_video_ops,
++ .pad = &isp_pad_ops,
++};
++
++static const struct v4l2_subdev_internal_ops isp_v4l2_internal_ops = {
++ .open = isp_init_formats,
++ .close = isp_close,
++};
++
++static const struct media_entity_operations isp_media_ops = {
++ .link_setup = isp_link_setup,
++ .link_validate = v4l2_subdev_link_validate,
++};
++
++int stf_isp_register(struct stf_isp_dev *isp_dev,
++ struct v4l2_device *v4l2_dev)
++{
++ struct v4l2_subdev *sd = &isp_dev->subdev;
++ struct media_pad *pads = isp_dev->pads;
++ int ret;
++
++ v4l2_subdev_init(sd, &isp_v4l2_ops);
++ sd->internal_ops = &isp_v4l2_internal_ops;
++ sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
++ snprintf(sd->name, ARRAY_SIZE(sd->name), "%s%d",
++ STF_ISP_NAME, 0);
++ v4l2_set_subdevdata(sd, isp_dev);
++
++ ret = isp_init_formats(sd, NULL);
++ if (ret < 0) {
++ st_err(ST_ISP, "Failed to init format: %d\n", ret);
++ return ret;
++ }
++
++ pads[STF_ISP_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
++ pads[STF_ISP_PAD_SRC].flags = MEDIA_PAD_FL_SOURCE;
++ pads[STF_ISP_PAD_SRC_SS0].flags = MEDIA_PAD_FL_SOURCE;
++ pads[STF_ISP_PAD_SRC_SS1].flags = MEDIA_PAD_FL_SOURCE;
++ pads[STF_ISP_PAD_SRC_ITIW].flags = MEDIA_PAD_FL_SOURCE;
++ pads[STF_ISP_PAD_SRC_ITIR].flags = MEDIA_PAD_FL_SOURCE;
++ pads[STF_ISP_PAD_SRC_RAW].flags = MEDIA_PAD_FL_SOURCE;
++ pads[STF_ISP_PAD_SRC_SCD_Y].flags = MEDIA_PAD_FL_SOURCE;
++
++ sd->entity.function = MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER;
++ sd->entity.ops = &isp_media_ops;
++ ret = media_entity_pads_init(&sd->entity, STF_ISP_PAD_MAX, pads);
++ if (ret < 0) {
++ st_err(ST_ISP, "Failed to init media entity: %d\n", ret);
++ return ret;
++ }
++
++ ret = isp_init_controls(isp_dev);
++ if (ret)
++ goto err_sreg;
++
++ ret = v4l2_device_register_subdev(v4l2_dev, sd);
++ if (ret < 0) {
++ st_err(ST_ISP, "Failed to register subdev: %d\n", ret);
++ goto free_ctrls;
++ }
++
++ return 0;
++
++free_ctrls:
++ v4l2_ctrl_handler_free(&isp_dev->ctrls.handler);
++err_sreg:
++ media_entity_cleanup(&sd->entity);
++ return ret;
++}
++
++int stf_isp_unregister(struct stf_isp_dev *isp_dev)
++{
++ v4l2_device_unregister_subdev(&isp_dev->subdev);
++ media_entity_cleanup(&isp_dev->subdev.entity);
++ v4l2_ctrl_handler_free(&isp_dev->ctrls.handler);
++ mutex_destroy(&isp_dev->stream_lock);
++ mutex_destroy(&isp_dev->power_lock);
++ mutex_destroy(&isp_dev->setfile_lock);
++ return 0;
++}
+--- /dev/null
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_isp.h
+@@ -0,0 +1,222 @@
++/* SPDX-License-Identifier: GPL-2.0
++ *
++ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
++ *
++ */
++
++#ifndef STF_ISP_H
++#define STF_ISP_H
++
++#include <media/v4l2-subdev.h>
++#include <media/v4l2-ctrls.h>
++#include <media/v4l2-device.h>
++#include <media/media-entity.h>
++#include <video/stf-vin.h>
++
++#define STF_ISP_NAME "stf_isp"
++#define STF_ISP_SETFILE "stf_isp0_fw.bin"
++
++#define ISP_SCD_BUFFER_SIZE (19 * 256 * 4) // align 128
++#define ISP_YHIST_BUFFER_SIZE (64 * 4)
++#define ISP_SCD_Y_BUFFER_SIZE (ISP_SCD_BUFFER_SIZE + ISP_YHIST_BUFFER_SIZE)
++#define ISP_RAW_DATA_BITS 12
++#define SCALER_RATIO_MAX 1 // no compose function
++#define STF_ISP_REG_OFFSET_MAX 0x0FFF
++#define STF_ISP_REG_DELAY_MAX 100
++
++#define ISP_REG_CSIINTS_ADDR 0x00000008
++#define ISP_REG_SENSOR 0x00000014
++#define ISP_REG_DUMP_CFG_0 0x00000024
++#define ISP_REG_DUMP_CFG_1 0x00000028
++#define ISP_REG_SCD_CFG_0 0x00000098
++#define ISP_REG_SCD_CFG_1 0x0000009C
++#define ISP_REG_SC_CFG_1 0x000000BC
++#define ISP_REG_IESHD_ADDR 0x00000A50
++#define ISP_REG_SS0AY 0x00000A94
++#define ISP_REG_SS0AUV 0x00000A98
++#define ISP_REG_SS0S 0x00000A9C
++#define ISP_REG_SS0IW 0x00000AA8
++#define ISP_REG_SS1AY 0x00000AAC
++#define ISP_REG_SS1AUV 0x00000AB0
++#define ISP_REG_SS1S 0x00000AB4
++#define ISP_REG_SS1IW 0x00000AC0
++#define ISP_REG_YHIST_CFG_4 0x00000CD8
++#define ISP_REG_ITIIWSR 0x00000B20
++#define ISP_REG_ITIDWLSR 0x00000B24
++#define ISP_REG_ITIDWYSAR 0x00000B28
++#define ISP_REG_ITIDWUSAR 0x00000B2C
++#define ISP_REG_ITIDRYSAR 0x00000B30
++#define ISP_REG_ITIDRUSAR 0x00000B34
++#define ISP_REG_ITIPDFR 0x00000B38
++#define ISP_REG_ITIDRLSR 0x00000B3C
++#define ISP_REG_ITIBSR 0x00000B40
++#define ISP_REG_ITIAIR 0x00000B44
++#define ISP_REG_ITIDPSR 0x00000B48
++
++/* The output line of a isp controller */
++enum isp_line_id {
++ STF_ISP_LINE_INVALID = -1,
++ STF_ISP_LINE_SRC = 1,
++ STF_ISP_LINE_SRC_SS0 = 2,
++ STF_ISP_LINE_SRC_SS1 = 3,
++ STF_ISP_LINE_SRC_ITIW = 4,
++ STF_ISP_LINE_SRC_ITIR = 5,
++ STF_ISP_LINE_SRC_RAW = 6,
++ STF_ISP_LINE_SRC_SCD_Y = 7,
++ STF_ISP_LINE_MAX = STF_ISP_LINE_SRC_SCD_Y
++};
++
++/* pad id for media framework */
++enum isp_pad_id {
++ STF_ISP_PAD_SINK = 0,
++ STF_ISP_PAD_SRC = 1,
++ STF_ISP_PAD_SRC_SS0 = 2,
++ STF_ISP_PAD_SRC_SS1 = 3,
++ STF_ISP_PAD_SRC_ITIW = 4,
++ STF_ISP_PAD_SRC_ITIR = 5,
++ STF_ISP_PAD_SRC_RAW = 6,
++ STF_ISP_PAD_SRC_SCD_Y = 7,
++ STF_ISP_PAD_MAX = 8
++};
++
++enum {
++ EN_INT_NONE = 0,
++ EN_INT_ISP_DONE = (0x1 << 24),
++ EN_INT_CSI_DONE = (0x1 << 25),
++ EN_INT_SC_DONE = (0x1 << 26),
++ EN_INT_LINE_INT = (0x1 << 27),
++ EN_INT_ALL = (0xF << 24),
++};
++
++enum {
++ DVP_SENSOR = 0,
++ CSI_SENSOR,
++};
++
++#define ISP_AWB_OECF_SKIP_FRAME 0
++// 0x0BC [31:30] SEL - sc0 input mux for sc awb
++// 00 : after DEC, 01 : after OBC, 10 : after OECF, 11 : after AWB
++enum scd_type {
++ DEC_TYPE = 0,
++ OBC_TYPE,
++ OECF_TYPE,
++ AWB_TYPE
++};
++
++struct isp_format {
++ u32 code;
++ u8 bpp;
++};
++
++struct isp_format_table {
++ const struct isp_format *fmts;
++ int nfmts;
++};
++
++struct regval_t {
++ u32 addr;
++ u32 val;
++ u32 mask;
++ u32 delay_ms;
++};
++
++struct reg_table {
++ struct regval_t *regval;
++ int regval_num;
++};
++
++struct isp_stream_format {
++ struct v4l2_rect rect;
++ u32 bpp;
++};
++
++struct stf_isp_dev;
++enum subdev_type;
++
++struct isp_hw_ops {
++ int (*isp_clk_enable)(struct stf_isp_dev *isp_dev);
++ int (*isp_clk_disable)(struct stf_isp_dev *isp_dev);
++ int (*isp_reset)(struct stf_isp_dev *isp_dev);
++ int (*isp_config_set)(struct stf_isp_dev *isp_dev);
++ int (*isp_set_format)(struct stf_isp_dev *isp_dev,
++ struct isp_stream_format *crop, u32 mcode,
++ int type);
++ // u32 width, u32 height);
++ int (*isp_stream_set)(struct stf_isp_dev *isp_dev, int on);
++ int (*isp_reg_read)(struct stf_isp_dev *isp_dev, void *arg);
++ int (*isp_reg_write)(struct stf_isp_dev *isp_dev, void *arg);
++ int (*isp_shadow_trigger)(struct stf_isp_dev *isp_dev);
++};
++
++struct isp_ctrls {
++ struct v4l2_ctrl_handler handler;
++ struct v4l2_ctrl *pixel_rate;
++ struct {
++ struct v4l2_ctrl *auto_exp;
++ struct v4l2_ctrl *exposure;
++ };
++ struct {
++ struct v4l2_ctrl *auto_wb;
++ struct v4l2_ctrl *blue_balance;
++ struct v4l2_ctrl *red_balance;
++ };
++ struct {
++ struct v4l2_ctrl *auto_gain;
++ struct v4l2_ctrl *gain;
++ };
++ struct v4l2_ctrl *brightness;
++ struct v4l2_ctrl *light_freq;
++ struct v4l2_ctrl *saturation;
++ struct v4l2_ctrl *contrast;
++ struct v4l2_ctrl *hue;
++ struct v4l2_ctrl *test_pattern;
++ struct v4l2_ctrl *hflip;
++ struct v4l2_ctrl *vflip;
++};
++
++struct isp_setfile {
++ struct reg_table settings;
++ const u8 *data;
++ unsigned int size;
++ unsigned int state;
++};
++
++enum {
++ ISP_CROP = 0,
++ ISP_COMPOSE,
++ ISP_SCALE_SS0,
++ ISP_SCALE_SS1,
++ ISP_ITIWS,
++ ISP_RECT_MAX
++};
++
++struct stf_isp_dev {
++ enum subdev_type sdev_type; // must be frist
++ struct stfcamss *stfcamss;
++ struct v4l2_subdev subdev;
++ struct media_pad pads[STF_ISP_PAD_MAX];
++ struct v4l2_mbus_framefmt fmt[STF_ISP_PAD_MAX];
++ struct isp_stream_format rect[ISP_RECT_MAX];
++ const struct isp_format_table *formats;
++ unsigned int nformats;
++ struct isp_hw_ops *hw_ops;
++ struct mutex power_lock;
++ int power_count;
++ struct mutex stream_lock;
++ int stream_count;
++ atomic_t shadow_count;
++
++ struct isp_ctrls ctrls;
++ struct mutex setfile_lock;
++ struct isp_setfile setfile;
++ struct reg_table *context_regs;
++};
++
++extern int stf_isp_subdev_init(struct stfcamss *stfcamss);
++extern int stf_isp_register(struct stf_isp_dev *isp_dev,
++ struct v4l2_device *v4l2_dev);
++extern int stf_isp_unregister(struct stf_isp_dev *isp_dev);
++extern struct isp_hw_ops isp_ops;
++extern void dump_isp_reg(void *__iomem ispbase);
++
++#endif /* STF_ISP_H */
+--- /dev/null
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_isp_hw_ops.c
+@@ -0,0 +1,1550 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
++ *
++ */
++
++#include "stfcamss.h"
++#include <linux/io.h>
++#include <linux/fb.h>
++#include <linux/module.h>
++#include <video/stf-vin.h>
++#include "stf_isp_ioctl.h"
++#include "stf_isp.h"
++#include <linux/delay.h>
++#include <linux/clk.h>
++#define USE_NEW_CONFIG_SETTING
++
++static struct regval_t isp_reg_init_config_list[] = {
++ /* config DC(0040H~0044H) */
++ {0x00000044, 0x00000000, 0, 0},
++ /* config DEC(0030H) */
++ {0x00000030, 0x00000000, 0, 0},
++ /* config OBC(0034H, 02E0H~02FCH) */
++ {0x00000034, 0x000000BB, 0, 0},
++ {0x000002E0, 0x40404040, 0, 0},
++ {0x000002E4, 0x40404040, 0, 0},
++ {0x000002E8, 0x40404040, 0, 0},
++ {0x000002EC, 0x40404040, 0, 0},
++ {0x000002F0, 0x00000000, 0, 0},
++ {0x000002F4, 0x00000000, 0, 0},
++ {0x000002F8, 0x00000000, 0, 0},
++ {0x000002FC, 0x00000000, 0, 0},
++ /* config LCBQ(0074H, 007CH, 0300H~039FH, and 0400H~049FH) */
++ {0x00000074, 0x00009900, 0, 0},
++ {0x0000007C, 0x01E40040, 0, 0},
++ {0x00000300, 0x01000100, 0, 0},
++ {0x00000304, 0x01000100, 0, 0},
++ {0x00000308, 0x01000100, 0, 0},
++ {0x0000030C, 0x01000100, 0, 0},
++ {0x00000310, 0x01000100, 0, 0},
++ {0x00000314, 0x01000100, 0, 0},
++ {0x00000318, 0x01000100, 0, 0},
++ {0x0000031C, 0x01000100, 0, 0},
++ {0x00000320, 0x01000100, 0, 0},
++ {0x00000324, 0x01000100, 0, 0},
++ {0x00000328, 0x01000100, 0, 0},
++ {0x0000032C, 0x01000100, 0, 0},
++ {0x00000330, 0x00000100, 0, 0},
++ {0x00000334, 0x01000100, 0, 0},
++ {0x00000338, 0x01000100, 0, 0},
++ {0x0000033C, 0x01000100, 0, 0},
++ {0x00000340, 0x01000100, 0, 0},
++ {0x00000344, 0x01000100, 0, 0},
++ {0x00000348, 0x01000100, 0, 0},
++ {0x0000034C, 0x01000100, 0, 0},
++ {0x00000350, 0x01000100, 0, 0},
++ {0x00000354, 0x01000100, 0, 0},
++ {0x00000358, 0x01000100, 0, 0},
++ {0x0000035C, 0x01000100, 0, 0},
++ {0x00000360, 0x01000100, 0, 0},
++ {0x00000364, 0x00000100, 0, 0},
++ {0x00000368, 0x01000100, 0, 0},
++ {0x0000036C, 0x01000100, 0, 0},
++ {0x00000370, 0x01000100, 0, 0},
++ {0x00000374, 0x01000100, 0, 0},
++ {0x00000378, 0x01000100, 0, 0},
++ {0x0000037C, 0x01000100, 0, 0},
++ {0x00000380, 0x01000100, 0, 0},
++ {0x00000384, 0x01000100, 0, 0},
++ {0x00000388, 0x01000100, 0, 0},
++ {0x0000038C, 0x01000100, 0, 0},
++ {0x00000390, 0x01000100, 0, 0},
++ {0x00000394, 0x01000100, 0, 0},
++ {0x00000398, 0x00000100, 0, 0},
++ {0x0000039C, 0x01000100, 0, 0},
++ {0x000003A0, 0x01000100, 0, 0},
++ {0x000003A4, 0x01000100, 0, 0},
++ {0x000003A8, 0x01000100, 0, 0},
++ {0x000003AC, 0x01000100, 0, 0},
++ {0x000003B0, 0x01000100, 0, 0},
++ {0x000003B4, 0x01000100, 0, 0},
++ {0x000003B8, 0x01000100, 0, 0},
++ {0x000003BC, 0x01000100, 0, 0},
++ {0x000003C0, 0x01000100, 0, 0},
++ {0x000003C4, 0x01000100, 0, 0},
++ {0x000003C8, 0x01000100, 0, 0},
++ {0x000003CC, 0x00000100, 0, 0},
++ {0x00000400, 0x00000000, 0, 0},
++ {0x00000404, 0x00000000, 0, 0},
++ {0x00000408, 0x00000000, 0, 0},
++ {0x0000040C, 0x00000000, 0, 0},
++ {0x00000410, 0x00000000, 0, 0},
++ {0x00000414, 0x00000000, 0, 0},
++ {0x00000418, 0x00000000, 0, 0},
++ {0x0000041C, 0x00000000, 0, 0},
++ {0x00000420, 0x00000000, 0, 0},
++ {0x00000424, 0x00000000, 0, 0},
++ {0x00000428, 0x00000000, 0, 0},
++ {0x0000042C, 0x00000000, 0, 0},
++ {0x00000430, 0x00000000, 0, 0},
++ {0x00000434, 0x00000000, 0, 0},
++ {0x00000438, 0x00000000, 0, 0},
++ {0x0000043C, 0x00000000, 0, 0},
++ {0x00000440, 0x00000000, 0, 0},
++ {0x00000444, 0x00000000, 0, 0},
++ {0x00000448, 0x00000000, 0, 0},
++ {0x0000044C, 0x00000000, 0, 0},
++ {0x00000450, 0x00000000, 0, 0},
++ {0x00000454, 0x00000000, 0, 0},
++ {0x00000458, 0x00000000, 0, 0},
++ {0x0000045C, 0x00000000, 0, 0},
++ {0x00000460, 0x00000000, 0, 0},
++ {0x00000464, 0x00000000, 0, 0},
++ {0x00000468, 0x00000000, 0, 0},
++ {0x0000046C, 0x00000000, 0, 0},
++ {0x00000470, 0x00000000, 0, 0},
++ {0x00000474, 0x00000000, 0, 0},
++ {0x00000478, 0x00000000, 0, 0},
++ {0x0000047C, 0x00000000, 0, 0},
++ {0x00000480, 0x00000000, 0, 0},
++ {0x00000484, 0x00000000, 0, 0},
++ {0x00000488, 0x00000000, 0, 0},
++ {0x0000048C, 0x00000000, 0, 0},
++ {0x00000490, 0x00000000, 0, 0},
++ {0x00000494, 0x00000000, 0, 0},
++ {0x00000498, 0x00000000, 0, 0},
++ {0x0000049C, 0x00000000, 0, 0},
++ {0x000004A0, 0x00000000, 0, 0},
++ {0x000004A4, 0x00000000, 0, 0},
++ {0x000004A8, 0x00000000, 0, 0},
++ {0x000004AC, 0x00000000, 0, 0},
++ {0x000004B0, 0x00000000, 0, 0},
++ {0x000004B4, 0x00000000, 0, 0},
++ {0x000004B8, 0x00000000, 0, 0},
++ {0x000004BC, 0x00000000, 0, 0},
++ {0x000004C0, 0x00000000, 0, 0},
++ {0x000004C4, 0x00000000, 0, 0},
++ {0x000004C8, 0x00000000, 0, 0},
++ {0x000004CC, 0x00000000, 0, 0},
++ /* config OECF(0100H~027CH) */
++ {0x00000100, 0x00100000, 0, 0},
++ {0x00000104, 0x00400020, 0, 0},
++ {0x00000108, 0x00800060, 0, 0},
++ {0x0000010C, 0x00C000A0, 0, 0},
++ {0x00000110, 0x010000E0, 0, 0},
++ {0x00000114, 0x02000180, 0, 0},
++ {0x00000118, 0x03000280, 0, 0},
++ {0x0000011C, 0x03FE0380, 0, 0},
++ {0x00000120, 0x00100000, 0, 0},
++ {0x00000124, 0x00400020, 0, 0},
++ {0x00000128, 0x00800060, 0, 0},
++ {0x0000012C, 0x00C000A0, 0, 0},
++ {0x00000130, 0x010000E0, 0, 0},
++ {0x00000134, 0x02000180, 0, 0},
++ {0x00000138, 0x03000280, 0, 0},
++ {0x0000013C, 0x03FE0380, 0, 0},
++ {0x00000140, 0x00100000, 0, 0},
++ {0x00000144, 0x00400020, 0, 0},
++ {0x00000148, 0x00800060, 0, 0},
++ {0x0000014C, 0x00C000A0, 0, 0},
++ {0x00000150, 0x010000E0, 0, 0},
++ {0x00000154, 0x02000180, 0, 0},
++ {0x00000158, 0x03000280, 0, 0},
++ {0x0000015C, 0x03FE0380, 0, 0},
++ {0x00000160, 0x00100000, 0, 0},
++ {0x00000164, 0x00400020, 0, 0},
++ {0x00000168, 0x00800060, 0, 0},
++ {0x0000016C, 0x00C000A0, 0, 0},
++ {0x00000170, 0x010000E0, 0, 0},
++ {0x00000174, 0x02000180, 0, 0},
++ {0x00000178, 0x03000280, 0, 0},
++ {0x0000017C, 0x03FE0380, 0, 0},
++ {0x00000180, 0x00100000, 0, 0},
++ {0x00000184, 0x00400020, 0, 0},
++ {0x00000188, 0x00800060, 0, 0},
++ {0x0000018C, 0x00C000A0, 0, 0},
++ {0x00000190, 0x010000E0, 0, 0},
++ {0x00000194, 0x02000180, 0, 0},
++ {0x00000198, 0x03000280, 0, 0},
++ {0x0000019C, 0x03FE0380, 0, 0},
++ {0x000001A0, 0x00100000, 0, 0},
++ {0x000001A4, 0x00400020, 0, 0},
++ {0x000001A8, 0x00800060, 0, 0},
++ {0x000001AC, 0x00C000A0, 0, 0},
++ {0x000001B0, 0x010000E0, 0, 0},
++ {0x000001B4, 0x02000180, 0, 0},
++ {0x000001B8, 0x03000280, 0, 0},
++ {0x000001BC, 0x03FE0380, 0, 0},
++ {0x000001C0, 0x00100000, 0, 0},
++ {0x000001C4, 0x00400020, 0, 0},
++ {0x000001C8, 0x00800060, 0, 0},
++ {0x000001CC, 0x00C000A0, 0, 0},
++ {0x000001D0, 0x010000E0, 0, 0},
++ {0x000001D4, 0x02000180, 0, 0},
++ {0x000001D8, 0x03000280, 0, 0},
++ {0x000001DC, 0x03FE0380, 0, 0},
++ {0x000001E0, 0x00100000, 0, 0},
++ {0x000001E4, 0x00400020, 0, 0},
++ {0x000001E8, 0x00800060, 0, 0},
++ {0x000001EC, 0x00C000A0, 0, 0},
++ {0x000001F0, 0x010000E0, 0, 0},
++ {0x000001F4, 0x02000180, 0, 0},
++ {0x000001F8, 0x03000280, 0, 0},
++ {0x000001FC, 0x03FE0380, 0, 0},
++ {0x00000200, 0x00800080, 0, 0},
++ {0x00000204, 0x00800080, 0, 0},
++ {0x00000208, 0x00800080, 0, 0},
++ {0x0000020C, 0x00800080, 0, 0},
++ {0x00000210, 0x00800080, 0, 0},
++ {0x00000214, 0x00800080, 0, 0},
++ {0x00000218, 0x00800080, 0, 0},
++ {0x0000021C, 0x00800080, 0, 0},
++ {0x00000220, 0x00800080, 0, 0},
++ {0x00000224, 0x00800080, 0, 0},
++ {0x00000228, 0x00800080, 0, 0},
++ {0x0000022C, 0x00800080, 0, 0},
++ {0x00000230, 0x00800080, 0, 0},
++ {0x00000234, 0x00800080, 0, 0},
++ {0x00000238, 0x00800080, 0, 0},
++ {0x0000023C, 0x00800080, 0, 0},
++ {0x00000240, 0x00800080, 0, 0},
++ {0x00000244, 0x00800080, 0, 0},
++ {0x00000248, 0x00800080, 0, 0},
++ {0x0000024C, 0x00800080, 0, 0},
++ {0x00000250, 0x00800080, 0, 0},
++ {0x00000254, 0x00800080, 0, 0},
++ {0x00000258, 0x00800080, 0, 0},
++ {0x0000025C, 0x00800080, 0, 0},
++ {0x00000260, 0x00800080, 0, 0},
++ {0x00000264, 0x00800080, 0, 0},
++ {0x00000268, 0x00800080, 0, 0},
++ {0x0000026C, 0x00800080, 0, 0},
++ {0x00000270, 0x00800080, 0, 0},
++ {0x00000274, 0x00800080, 0, 0},
++ {0x00000278, 0x00800080, 0, 0},
++ {0x0000027C, 0x00800080, 0, 0},
++ /* config OECFHM(03D0H~03E4H) */
++ {0x000003D0, 0x04000000, 0, 0},
++ {0x000003D4, 0x0C000800, 0, 0},
++ {0x000003D8, 0x00000FFF, 0, 0},
++ {0x000003DC, 0x08000800, 0, 0},
++ {0x000003E0, 0x08000800, 0, 0},
++ {0x000003E4, 0x00000800, 0, 0},
++ /* config LCCF(0050H, 0058H, 00E0H~00ECH) */
++ {0x00000050, 0x021C03C0, 0, 0},
++ {0x00000058, 0x0000000B, 0, 0},
++ {0x000000E0, 0x00000000, 0, 0},
++ {0x000000E4, 0x00000000, 0, 0},
++ {0x000000E8, 0x00000000, 0, 0},
++ {0x000000EC, 0x00000000, 0, 0},
++ /* config AWB(0280H~02DCH) */
++ {0x00000280, 0x00000000, 0, 0},
++ {0x00000284, 0x00000000, 0, 0},
++ {0x00000288, 0x00000000, 0, 0},
++ {0x0000028C, 0x00000000, 0, 0},
++ {0x00000290, 0x00000000, 0, 0},
++ {0x00000294, 0x00000000, 0, 0},
++ {0x00000298, 0x00000000, 0, 0},
++ {0x0000029C, 0x00000000, 0, 0},
++ {0x000002A0, 0x00000000, 0, 0},
++ {0x000002A4, 0x00000000, 0, 0},
++ {0x000002A8, 0x00000000, 0, 0},
++ {0x000002AC, 0x00000000, 0, 0},
++ {0x000002B0, 0x00000000, 0, 0},
++ {0x000002B4, 0x00000000, 0, 0},
++ {0x000002B8, 0x00000000, 0, 0},
++ {0x000002BC, 0x00000000, 0, 0},
++ {0x000002C0, 0x00800080, 0, 0},
++ {0x000002C4, 0x00800080, 0, 0},
++ {0x000002C8, 0x00800080, 0, 0},
++ {0x000002CC, 0x00800080, 0, 0},
++ {0x000002D0, 0x00800080, 0, 0},
++ {0x000002D4, 0x00800080, 0, 0},
++ {0x000002D8, 0x00800080, 0, 0},
++ {0x000002DC, 0x00800080, 0, 0},
++ /* config CTC(0A10H) and DBC(0A14H) filter */
++ {0x00000A10, 0x41400040, 0, 0},
++ {0x00000A14, 0x02000200, 0, 0},
++ /* config CFA(0018H, 0A1CH) */
++ {0x00000018, 0x000011BB, 0, 0},
++ {0x00000A1C, 0x00000032, 0, 0},
++ /* config CCM(0C40H~0CA4H) */
++ {0x00000C40, 0x00060000, 0, 0},
++ {0x00000C44, 0x00000000, 0, 0},
++ {0x00000C48, 0x00000000, 0, 0},
++ {0x00000C4C, 0x00000000, 0, 0},
++ {0x00000C50, 0x00000000, 0, 0},
++ {0x00000C54, 0x00000000, 0, 0},
++ {0x00000C58, 0x00000000, 0, 0},
++ {0x00000C5C, 0x00000000, 0, 0},
++ {0x00000C60, 0x00000000, 0, 0},
++ {0x00000C64, 0x00000000, 0, 0},
++ {0x00000C68, 0x00000000, 0, 0},
++ {0x00000C6C, 0x00000000, 0, 0},
++ {0x00000C70, 0x00000080, 0, 0},
++ {0x00000C74, 0x00000000, 0, 0},
++ {0x00000C78, 0x00000000, 0, 0},
++ {0x00000C7C, 0x00000000, 0, 0},
++ {0x00000C80, 0x00000080, 0, 0},
++ {0x00000C84, 0x00000000, 0, 0},
++ {0x00000C88, 0x00000000, 0, 0},
++ {0x00000C8C, 0x00000000, 0, 0},
++ {0x00000C90, 0x00000080, 0, 0},
++ {0x00000C94, 0x00000000, 0, 0},
++ {0x00000C98, 0x00000000, 0, 0},
++ {0x00000C9C, 0x00000000, 0, 0},
++ {0x00000CA0, 0x00000700, 0, 0},
++ {0x00000CA4, 0x00000200, 0, 0},
++ /* config GMARGB(0E00H~0E38H) */
++ {0x00000E00, 0x24000000, 0, 0},
++ {0x00000E04, 0x08000020, 0, 0},
++ {0x00000E08, 0x08000040, 0, 0},
++ {0x00000E0C, 0x08000060, 0, 0},
++ {0x00000E10, 0x08000080, 0, 0},
++ {0x00000E14, 0x080000A0, 0, 0},
++ {0x00000E18, 0x080000C0, 0, 0},
++ {0x00000E1C, 0x080000E0, 0, 0},
++ {0x00000E20, 0x08000100, 0, 0},
++ {0x00000E24, 0x08000180, 0, 0},
++ {0x00000E28, 0x08000200, 0, 0},
++ {0x00000E2C, 0x08000280, 0, 0},
++ {0x00000E30, 0x08000300, 0, 0},
++ {0x00000E34, 0x08000380, 0, 0},
++ {0x00000E38, 0x080003FE, 0, 0},
++ /* config R2Y(0E40H~0E60H) */
++ {0x00000E40, 0x0000004C, 0, 0},
++ {0x00000E44, 0x00000097, 0, 0},
++ {0x00000E48, 0x0000001D, 0, 0},
++ {0x00000E4C, 0x000001D5, 0, 0},
++ {0x00000E50, 0x000001AC, 0, 0},
++ {0x00000E54, 0x00000080, 0, 0},
++ {0x00000E58, 0x00000080, 0, 0},
++ {0x00000E5C, 0x00000194, 0, 0},
++ {0x00000E60, 0x000001EC, 0, 0},
++ /* config YCRV(0F00H~0FFCH) */
++ {0x00000F00, 0x00000000, 0, 0},
++ {0x00000F04, 0x00000010, 0, 0},
++ {0x00000F08, 0x00000020, 0, 0},
++ {0x00000F0C, 0x00000030, 0, 0},
++ {0x00000F10, 0x00000040, 0, 0},
++ {0x00000F14, 0x00000050, 0, 0},
++ {0x00000F18, 0x00000060, 0, 0},
++ {0x00000F1C, 0x00000070, 0, 0},
++ {0x00000F20, 0x00000080, 0, 0},
++ {0x00000F24, 0x00000090, 0, 0},
++ {0x00000F28, 0x000000A0, 0, 0},
++ {0x00000F2C, 0x000000B0, 0, 0},
++ {0x00000F30, 0x000000C0, 0, 0},
++ {0x00000F34, 0x000000D0, 0, 0},
++ {0x00000F38, 0x000000E0, 0, 0},
++ {0x00000F3C, 0x000000F0, 0, 0},
++ {0x00000F40, 0x00000100, 0, 0},
++ {0x00000F44, 0x00000110, 0, 0},
++ {0x00000F48, 0x00000120, 0, 0},
++ {0x00000F4C, 0x00000130, 0, 0},
++ {0x00000F50, 0x00000140, 0, 0},
++ {0x00000F54, 0x00000150, 0, 0},
++ {0x00000F58, 0x00000160, 0, 0},
++ {0x00000F5C, 0x00000170, 0, 0},
++ {0x00000F60, 0x00000180, 0, 0},
++ {0x00000F64, 0x00000190, 0, 0},
++ {0x00000F68, 0x000001A0, 0, 0},
++ {0x00000F6C, 0x000001B0, 0, 0},
++ {0x00000F70, 0x000001C0, 0, 0},
++ {0x00000F74, 0x000001D0, 0, 0},
++ {0x00000F78, 0x000001E0, 0, 0},
++ {0x00000F7C, 0x000001F0, 0, 0},
++ {0x00000F80, 0x00000200, 0, 0},
++ {0x00000F84, 0x00000210, 0, 0},
++ {0x00000F88, 0x00000220, 0, 0},
++ {0x00000F8C, 0x00000230, 0, 0},
++ {0x00000F90, 0x00000240, 0, 0},
++ {0x00000F94, 0x00000250, 0, 0},
++ {0x00000F98, 0x00000260, 0, 0},
++ {0x00000F9C, 0x00000270, 0, 0},
++ {0x00000FA0, 0x00000280, 0, 0},
++ {0x00000FA4, 0x00000290, 0, 0},
++ {0x00000FA8, 0x000002A0, 0, 0},
++ {0x00000FAC, 0x000002B0, 0, 0},
++ {0x00000FB0, 0x000002C0, 0, 0},
++ {0x00000FB4, 0x000002D0, 0, 0},
++ {0x00000FB8, 0x000002E0, 0, 0},
++ {0x00000FBC, 0x000002F0, 0, 0},
++ {0x00000FC0, 0x00000300, 0, 0},
++ {0x00000FC4, 0x00000310, 0, 0},
++ {0x00000FC8, 0x00000320, 0, 0},
++ {0x00000FCC, 0x00000330, 0, 0},
++ {0x00000FD0, 0x00000340, 0, 0},
++ {0x00000FD4, 0x00000350, 0, 0},
++ {0x00000FD8, 0x00000360, 0, 0},
++ {0x00000FDC, 0x00000370, 0, 0},
++ {0x00000FE0, 0x00000380, 0, 0},
++ {0x00000FE4, 0x00000390, 0, 0},
++ {0x00000FE8, 0x000003A0, 0, 0},
++ {0x00000FEC, 0x000003B0, 0, 0},
++ {0x00000FF0, 0x000003C0, 0, 0},
++ {0x00000FF4, 0x000003D0, 0, 0},
++ {0x00000FF8, 0x000003E0, 0, 0},
++ {0x00000FFC, 0x000003F0, 0, 0},
++ /* config Shrp(0E80H~0EE8H) */
++ {0x00000E80, 0x00070F00, 0, 0},
++ {0x00000E84, 0x00180F00, 0, 0},
++ {0x00000E88, 0x00800F00, 0, 0},
++ {0x00000E8C, 0x01000F00, 0, 0},
++ {0x00000E90, 0x00100F00, 0, 0},
++ {0x00000E94, 0x00600F00, 0, 0},
++ {0x00000E98, 0x01000F00, 0, 0},
++ {0x00000E9C, 0x01900F00, 0, 0},
++ {0x00000EA0, 0x00000F00, 0, 0},
++ {0x00000EA4, 0x00000F00, 0, 0},
++ {0x00000EA8, 0x00000F00, 0, 0},
++ {0x00000EAC, 0x00000F00, 0, 0},
++ {0x00000EB0, 0x00000F00, 0, 0},
++ {0x00000EB4, 0x00000F00, 0, 0},
++ {0x00000EB8, 0x00000F00, 0, 0},
++ {0x00000EBC, 0x10000000, 0, 0},
++ {0x00000EC0, 0x10000000, 0, 0},
++ {0x00000EC4, 0x10000000, 0, 0},
++ {0x00000EC8, 0x10000000, 0, 0},
++ {0x00000ECC, 0x10000000, 0, 0},
++ {0x00000ED0, 0x10000000, 0, 0},
++ {0x00000ED4, 0x88000D7C, 0, 0},
++ {0x00000ED8, 0x00C00040, 0, 0},
++ {0x00000EDC, 0xFF000000, 0, 0},
++ {0x00000EE0, 0x00A00040, 0, 0},
++ {0x00000EE4, 0x00000000, 0, 0},
++ {0x00000EE8, 0x00000000, 0, 0},
++ /* config DNYUV(0C00H~0C24H) */
++ {0x00000C00, 0x00777777, 0, 0},
++ {0x00000C04, 0x00007777, 0, 0},
++ {0x00000C08, 0x00777777, 0, 0},
++ {0x00000C0C, 0x00007777, 0, 0},
++ {0x00000C10, 0x00600040, 0, 0},
++ {0x00000C14, 0x00D80090, 0, 0},
++ {0x00000C18, 0x01E60144, 0, 0},
++ {0x00000C1C, 0x00600040, 0, 0},
++ {0x00000C20, 0x00D80090, 0, 0},
++ {0x00000C24, 0x01E60144, 0, 0},
++ /* config SAT(0A30H~0A40H, 0A54H~0A58H) */
++ {0x00000A30, 0x00000100, 0, 0},
++ {0x00000A34, 0x001F0001, 0, 0},
++ {0x00000A38, 0x00000000, 0, 0},
++ {0x00000A3C, 0x00000100, 0, 0},
++ {0x00000A40, 0x00000008, 0, 0},
++ {0x00000A54, 0x04010001, 0, 0},
++ {0x00000A58, 0x03FF0001, 0, 0},
++ /* config OBA(0090H~0094H) */
++ {0x00000090, 0x04380000, 0, 0},
++ {0x00000094, 0x04390780, 0, 0},
++ /* config SC(0098H~009CH, 00B8H~00BCH,
++ * 00C0H, 0C4H~0D4H, 04D0H~054CH, 5D0H~5D4H)
++ */
++ {0x0000009C, 0x01000000, 0, 0},
++ {0x000000B8, 0x000C0000, 0, 0},
++ {0x000000BC, 0xC010151D, 0, 0},
++ {0x000000C0, 0x01F1BF08, 0, 0},
++ {0x000000C4, 0xFF00FF00, 0, 0},
++ {0x000000C8, 0xFF00FF00, 0, 0},
++ {0x000000CC, 0xFFFF0000, 0, 0},
++ {0x000000D0, 0xFFFF0000, 0, 0},
++ {0x000000D4, 0xFFFF0000, 0, 0},
++ {0x000000D8, 0x01050107, 0, 0},
++ {0x000004D0, 0x00000000, 0, 0},
++ {0x000004D4, 0x00000000, 0, 0},
++ {0x000004D8, 0x00000000, 0, 0},
++ {0x000004DC, 0x00000000, 0, 0},
++ {0x000004E0, 0x00000000, 0, 0},
++ {0x000004E4, 0x00000000, 0, 0},
++ {0x000004E8, 0x00000000, 0, 0},
++ {0x000004EC, 0x00000000, 0, 0},
++ {0x000004F0, 0x00100000, 0, 0},
++ {0x000004F4, 0x00000000, 0, 0},
++ {0x000004F8, 0x03D20000, 0, 0},
++ {0x000004FC, 0x00000000, 0, 0},
++ {0x00000500, 0x00950000, 0, 0},
++ {0x00000504, 0x00000000, 0, 0},
++ {0x00000508, 0x00253000, 0, 0},
++ {0x0000050C, 0x00000000, 0, 0},
++ {0x00000510, 0x00000000, 0, 0},
++ {0x00000514, 0x00000000, 0, 0},
++ {0x00000518, 0x00000000, 0, 0},
++ {0x0000051C, 0x00000000, 0, 0},
++ {0x00000520, 0x00000000, 0, 0},
++ {0x00000524, 0x00000000, 0, 0},
++ {0x00000528, 0x00000000, 0, 0},
++ {0x0000052C, 0x00000000, 0, 0},
++ {0x00000530, 0x00000000, 0, 0},
++ {0x00000534, 0x00000000, 0, 0},
++ {0x00000538, 0xFFFFFFF0, 0, 0},
++ {0x0000053C, 0x8FFFFFFF, 0, 0},
++ {0x00000540, 0x0000001E, 0, 0},
++ {0x00000544, 0x00000000, 0, 0},
++ {0x00000548, 0x00000000, 0, 0},
++ {0x0000054C, 0xF0F20000, 0, 0},
++ {0x000005D0, 0xFF00FF00, 0, 0},
++ {0x000005D4, 0xFF00FF00, 0, 0},
++ /* config YHIST(0CC8H~0CD8H) */
++ {0x00000CC8, 0x00000000, 0, 0},
++ {0x00000CCC, 0x0437077F, 0, 0},
++ {0x00000CD0, 0x00010002, 0, 0},
++ {0x00000CD4, 0x00000000, 0, 0},
++ /* config CBAR(0600H-0653H) */
++ {0x00000600, 0x043E0782, 0, 0},
++ {0x00000604, 0x00000000, 0, 0},
++ {0x00000608, 0x0437077F, 0, 0},
++ {0x0000060C, 0x00443150, 0, 0},
++ {0x00000610, 0x00000000, 0, 0},
++ {0x00000614, 0x08880888, 0, 0},
++ {0x00000618, 0x02220222, 0, 0},
++ {0x0000061C, 0x04440444, 0, 0},
++ {0x00000620, 0x08880888, 0, 0},
++ {0x00000624, 0x0AAA0AAA, 0, 0},
++ {0x00000628, 0x0CCC0CCC, 0, 0},
++ {0x0000062C, 0x0EEE0EEE, 0, 0},
++ {0x00000630, 0x0FFF0FFF, 0, 0},
++ {0x00000634, 0x08880888, 0, 0},
++ {0x00000638, 0x02220222, 0, 0},
++ {0x0000063C, 0x04440444, 0, 0},
++ {0x00000640, 0x08880888, 0, 0},
++ {0x00000644, 0x0AAA0AAA, 0, 0},
++ {0x00000648, 0x0CCC0CCC, 0, 0},
++ {0x0000064C, 0x0EEE0EEE, 0, 0},
++ {0x00000650, 0x0FFF0FFF, 0, 0},
++ /* config sensor(0014H) */
++ {0x00000014, 0x0000000c, 0, 0},
++ /* config CROP(001CH, 0020H) */
++ {0x0000001C, 0x00000000, 0, 0},
++ {0x00000020, 0x0437077F, 0, 0},
++ /* config isp pileline X/Y size(A0CH) */
++ {0x00000A0C, 0x04380780, 0, 0},
++ /* config CSI dump (24H/28H) */
++ {0x00000028, 0x00030B80, 0, 0},
++ /* Video Output */
++ /* config UO(0A80H~0A90H) */
++ {0x00000A88, 0x00000780, 0, 0},
++ /* NV12 */
++ {0x00000A8C, 0x00000000, 0, 0},
++ /* NV21
++ *{0x00000A8C, 0x00000020, 0, 0},
++ */
++ {0x00000A90, 0x00000000, 0, 0},
++ {0x00000A9C, 0x00000780, 0, 0},
++ {0x00000AA0, 0x00000002, 0, 0},
++ {0x00000AA4, 0x00000002, 0, 0},
++ {0x00000AA8, 0x07800438, 0, 0},
++ {0x00000AB4, 0x00000780, 0, 0},
++ {0x00000AB8, 0x00000002, 0, 0},
++ {0x00000ABC, 0x00000002, 0, 0},
++ {0x00000AC0, 0x07800438, 0, 0},
++ {0x00000AC4, 0x00000000, 0, 0},
++ /* config TIL(0B20H~0B48H) */
++ {0x00000B20, 0x04380780, 0, 0},
++ {0x00000B24, 0x00000960, 0, 0},
++ {0x00000B38, 0x00030003, 0, 0},
++ {0x00000B3C, 0x00000960, 0, 0},
++ {0x00000B44, 0x00000000, 0, 0},
++ {0x00000B48, 0x00000000, 0, 0},
++ /* Enable DEC/OBC/OECF/LCCF/AWB/SC/DUMP */
++ {0x00000010, 0x000A00D6, 0x00000000, 0x00},
++ /* Enable CFA/CAR/CCM/GMARGB/R2Y/SHRP/SAT/DNYUV/YCRV/YHIST/CTC/DBC */
++ {0x00000A08, 0x107A01BE, 0x00000000, 0x00},
++};
++
++const struct reg_table isp_reg_init_settings[] = {
++ {isp_reg_init_config_list,
++ ARRAY_SIZE(isp_reg_init_config_list)},
++};
++
++static struct regval_t isp_reg_start_config_list[] = {
++#if defined(ENABLE_SS0_SS1)
++ /* ENABLE UO/SS0/SS1/Multi-Frame and Reset ISP */
++ {0x00000A00, 0x00121802, 0x00000000, 0x0A},
++ /* ENABLE UO/SS0/SS1/Multi-Frame and Leave ISP reset */
++ {0x00000A00, 0x00121800, 0x00000000, 0x0A},
++#else
++ /* ENABLE UO/Multi-Frame and Reset ISP */
++ {0x00000A00, 0x00120002, 0x00000000, 0x0A},
++ /* ENABLE UO/Multi-Frame and Leave ISP reset */
++ {0x00000A00, 0x00120000, 0x00000000, 0x0A},
++#endif
++ /* Config ISP shadow mode as next-vsync */
++ {0x00000A50, 0x00000002, 0x00000000, 0x00},
++#if defined(ENABLE_SS0_SS1)
++ /* ENABLE UO/SS0/SS1/Multi-Frame and Enable ISP */
++ {0x00000A00, 0x00121801, 0x00000000, 0x0A},
++#else
++ /* ENABLE UO/Multi-Frame and Enable ISP */
++ {0x00000A00, 0x00120001, 0x00000000, 0x0A},
++#endif
++ /* Config CSI shadow mode as immediate to fetch current setting */
++ {0x00000008, 0x00010004, 0x00000000, 0x0A},
++ /* Config CSI shadow mode as next-vsync */
++ {0x00000008, 0x00020004, 0x00000000, 0x00},
++ /* Enable CSI */
++ {0x00000000, 0x00000001, 0x00000000, 0x0A},
++};
++
++const struct reg_table isp_reg_start_settings[] = {
++ {isp_reg_start_config_list,
++ ARRAY_SIZE(isp_reg_start_config_list)},
++};
++
++static struct regval_t isp_imx_219_reg_config_list[] = {
++ /* MIPI sensor */
++ {0x00000014, 0x0000000D, 0, 0},
++ /* config CFA(0018H, 0A1CH) */
++ {0x00000A1C, 0x00000032, 0, 0},
++ {0x00000A8C, 0x00000000, 0, 0},
++ {0x00000A90, 0x00000000, 0, 0},
++ /* config R2Y(0E40H~0E60H) */
++ {0x00000E40, 0x0000004C, 0, 0},
++ {0x00000E44, 0x00000097, 0, 0},
++ {0x00000E48, 0x0000001D, 0, 0},
++ {0x00000E4C, 0x000001D5, 0, 0},
++ {0x00000E50, 0x000001AC, 0, 0},
++ {0x00000E54, 0x00000080, 0, 0},
++ {0x00000E58, 0x00000080, 0, 0},
++ {0x00000E5C, 0x00000194, 0, 0},
++ {0x00000E60, 0x000001EC, 0, 0},
++ /* Config AWB(0280H~02DCH). Fixed WB gain for IMX-219 sensor. */
++ {0x00000280, 0x00000000, 0, 0},
++ {0x00000284, 0x00000000, 0, 0},
++ {0x00000288, 0x00000000, 0, 0},
++ {0x0000028C, 0x00000000, 0, 0},
++ {0x00000290, 0x00000000, 0, 0},
++ {0x00000294, 0x00000000, 0, 0},
++ {0x00000298, 0x00000000, 0, 0},
++ {0x0000029C, 0x00000000, 0, 0},
++ {0x000002A0, 0x00000000, 0, 0},
++ {0x000002A4, 0x00000000, 0, 0},
++ {0x000002A8, 0x00000000, 0, 0},
++ {0x000002AC, 0x00000000, 0, 0},
++ {0x000002B0, 0x00000000, 0, 0},
++ {0x000002B4, 0x00000000, 0, 0},
++ {0x000002B8, 0x00000000, 0, 0},
++ {0x000002BC, 0x00000000, 0, 0},
++ {0x000002C0, 0x00F000F0, 0, 0},
++ {0x000002C4, 0x00F000F0, 0, 0},
++ {0x000002C8, 0x00800080, 0, 0},
++ {0x000002CC, 0x00800080, 0, 0},
++ {0x000002D0, 0x00800080, 0, 0},
++ {0x000002D4, 0x00800080, 0, 0},
++ {0x000002D8, 0x00B000B0, 0, 0},
++ {0x000002DC, 0x00B000B0, 0, 0},
++ /* config GMARGB(0E00H~0E38H)
++ * Gamma RGB 1.9 for IMX-219 sensor
++ */
++ {0x00000E00, 0x24000000, 0, 0},
++ {0x00000E04, 0x159500A5, 0, 0},
++ {0x00000E08, 0x0F9900EE, 0, 0},
++ {0x00000E0C, 0x0CE40127, 0, 0},
++ {0x00000E10, 0x0B410157, 0, 0},
++ {0x00000E14, 0x0A210181, 0, 0},
++ {0x00000E18, 0x094B01A8, 0, 0},
++ {0x00000E1C, 0x08A401CC, 0, 0},
++ {0x00000E20, 0x081D01EE, 0, 0},
++ {0x00000E24, 0x06B20263, 0, 0},
++ {0x00000E28, 0x05D802C7, 0, 0},
++ {0x00000E2C, 0x05420320, 0, 0},
++ {0x00000E30, 0x04D30370, 0, 0},
++ {0x00000E34, 0x047C03BB, 0, 0},
++ {0x00000E38, 0x043703FF, 0, 0},
++ {0x00000010, 0x00000080, 0, 0},
++ /* Enable CFA/GMARGB/R2Y */
++ {0x00000A08, 0x10000032, 0x0FFFFFFF, 0x00},
++ {0x00000A00, 0x00120002, 0, 0},
++ {0x00000A00, 0x00120000, 0, 0},
++ {0x00000A50, 0x00000002, 0, 0},
++ {0x00000008, 0x00010000, 0, 0},
++ {0x00000008, 0x0002000A, 0, 0},
++ {0x00000000, 0x00000001, 0, 0},
++};
++
++const struct reg_table isp_imx_219_settings[] = {
++ {isp_imx_219_reg_config_list,
++ ARRAY_SIZE(isp_imx_219_reg_config_list)},
++};
++
++static struct regval_t isp_format_reg_list[] = {
++ {0x0000001C, 0x00000000, 0x00000000, 0},
++ {0x00000020, 0x0437077F, 0x00000000, 0},
++ {0x00000A0C, 0x04380780, 0x00000000, 0},
++ {0x00000A88, 0x00000780, 0x00000000, 0},
++ {0x00000018, 0x000011BB, 0x00000000, 0},
++ {0x00000A08, 0x10000000, 0xF0000000, 0},
++ {0x00000028, 0x00030B80, 0x0003FFFF, 0},
++ {0x00000AA8, 0x07800438, 0x00000000, 0},
++ {0x00000A9C, 0x00000780, 0x00000000, 0},
++ {0x00000AC0, 0x07800438, 0x00000000, 0},
++ {0x00000AB4, 0x00000780, 0x00000000, 0},
++ {0x00000B20, 0x04380780, 0x00000000, 0},
++ {0x00000B24, 0x00000960, 0x00000000, 0},
++ {0x00000B3C, 0x00000960, 0x00000000, 0},
++ {0x00000014, 0x00000008, 0x00000000, 0},
++};
++
++const struct reg_table isp_format_settings[] = {
++ {isp_format_reg_list,
++ ARRAY_SIZE(isp_format_reg_list)},
++};
++
++#if defined(USE_NEW_CONFIG_SETTING)
++#else
++static struct reg_table *isp_settings = (struct reg_table *)isp_imx_219_settings;
++#endif
++
++static void isp_load_regs(void __iomem *ispbase, const struct reg_table *table)
++{
++ int j;
++ u32 delay_ms, reg_addr, mask, val;
++
++ for (j = 0; j < table->regval_num; j++) {
++ delay_ms = table->regval[j].delay_ms;
++ reg_addr = table->regval[j].addr;
++ val = table->regval[j].val;
++ mask = table->regval[j].mask;
++
++ if (reg_addr % 4
++ || reg_addr > STF_ISP_REG_OFFSET_MAX
++ || delay_ms > STF_ISP_REG_DELAY_MAX)
++ continue;
++
++ if (mask)
++ reg_set_bit(ispbase, reg_addr, mask, val);
++ else
++ reg_write(ispbase, reg_addr, val);
++ if (delay_ms)
++ usleep_range(1000 * delay_ms, 1000 * delay_ms + 100);
++ }
++}
++
++static void isp_load_regs_exclude_csi_isp_enable(
++ void __iomem *ispbase,
++ const struct reg_table *table)
++{
++ int j;
++ u32 delay_ms, reg_addr, mask, val;
++
++ for (j = 0; j < table->regval_num; j++) {
++ delay_ms = table->regval[j].delay_ms;
++ reg_addr = table->regval[j].addr;
++ val = table->regval[j].val;
++ mask = table->regval[j].mask;
++
++ if (reg_addr % 4
++ || reg_addr > STF_ISP_REG_OFFSET_MAX
++ || delay_ms > STF_ISP_REG_DELAY_MAX
++ || ((reg_addr == ISP_REG_CSI_INPUT_EN_AND_STATUS) && (val & 0x01))
++ || ((reg_addr == ISP_REG_ISP_CTRL_0) && (val & 0x01)))
++ continue;
++
++ if (mask)
++ reg_set_bit(ispbase, reg_addr, mask, val);
++ else
++ reg_write(ispbase, reg_addr, val);
++ if (delay_ms)
++ usleep_range(1000 * delay_ms, 1000 * delay_ms + 100);
++ }
++}
++
++static int stf_isp_clk_enable(struct stf_isp_dev *isp_dev)
++{
++ struct stfcamss *stfcamss = isp_dev->stfcamss;
++
++ clk_prepare_enable(stfcamss->sys_clk[STFCLK_WRAPPER_CLK_C].clk);
++ reset_control_deassert(stfcamss->sys_rst[STFRST_WRAPPER_C].rstc);
++ reset_control_deassert(stfcamss->sys_rst[STFRST_WRAPPER_P].rstc);
++
++ return 0;
++}
++
++static int stf_isp_clk_disable(struct stf_isp_dev *isp_dev)
++{
++ struct stfcamss *stfcamss = isp_dev->stfcamss;
++
++ reset_control_assert(stfcamss->sys_rst[STFRST_WRAPPER_C].rstc);
++ reset_control_assert(stfcamss->sys_rst[STFRST_WRAPPER_P].rstc);
++ clk_disable_unprepare(stfcamss->sys_clk[STFCLK_WRAPPER_CLK_C].clk);
++
++ return 0;
++}
++
++static void __iomem *stf_isp_get_ispbase(struct stf_vin_dev *vin)
++{
++ void __iomem *base = vin->isp_base;
++
++ return base;
++}
++
++static int stf_isp_save_ctx_regs(struct stf_isp_dev *isp_dev)
++{
++ int j;
++ u32 addr, val;
++ void __iomem *ispbase;
++ struct device *dev = isp_dev->stfcamss->dev;
++ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
++
++ ispbase = stf_isp_get_ispbase(vin);
++
++ if (!isp_dev->context_regs) {
++ int regs_size =
++ sizeof(struct regval_t) * isp_reg_init_settings->regval_num;
++ isp_dev->context_regs =
++ devm_kzalloc(dev, sizeof(struct reg_table), GFP_KERNEL);
++ isp_dev->context_regs->regval =
++ devm_kzalloc(dev, regs_size, GFP_KERNEL);
++ isp_dev->context_regs->regval_num = isp_reg_init_settings->regval_num;
++ }
++
++ if (!isp_dev->context_regs || !isp_dev->context_regs->regval)
++ return -ENOMEM;
++
++ st_debug(ST_ISP, "Saving ISP context registers\n");
++ for (j = 0; j < isp_reg_init_settings->regval_num; j++) {
++ addr = isp_reg_init_settings->regval[j].addr;
++ val = ioread32(ispbase + addr);
++ isp_dev->context_regs->regval[j].addr = addr;
++ isp_dev->context_regs->regval[j].val = val;
++ }
++ st_debug(ST_ISP, "ISP context registers have been saved\n");
++
++ return 0;
++};
++
++static int stf_isp_restore_ctx_regs(struct stf_isp_dev *isp_dev)
++{
++ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
++ void __iomem *ispbase;
++
++ ispbase = stf_isp_get_ispbase(vin);
++
++ if (isp_dev->context_regs) {
++ isp_load_regs(ispbase, isp_dev->context_regs);
++ st_debug(ST_ISP, "Restored ISP register: isp_reg_init_settings.\n");
++ }
++
++ return 0;
++}
++
++static int stf_isp_reset(struct stf_isp_dev *isp_dev)
++{
++ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
++ void __iomem *ispbase;
++
++ ispbase = stf_isp_get_ispbase(vin);
++
++ reg_set_bit(ispbase, ISP_REG_ISP_CTRL_0, BIT(1), BIT(1));
++ reg_set_bit(ispbase, ISP_REG_ISP_CTRL_0, BIT(1), 0);
++
++ return 0;
++}
++
++static int stf_isp_config_set(struct stf_isp_dev *isp_dev)
++{
++ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
++ void __iomem *ispbase;
++
++ ispbase = stf_isp_get_ispbase(vin);
++
++ st_debug(ST_ISP, "%s\n", __func__);
++
++#if defined(USE_NEW_CONFIG_SETTING)
++ mutex_lock(&isp_dev->setfile_lock);
++
++ if (isp_dev->context_regs) {
++ stf_isp_restore_ctx_regs(isp_dev);
++ st_debug(ST_ISP, "%s context regs restore done\n", __func__);
++ } else {
++ isp_load_regs(ispbase, isp_reg_init_settings);
++ st_debug(ST_ISP, "%s isp_reg_init_settings done\n", __func__);
++ }
++ if (isp_dev->setfile.state) {
++ st_info(ST_ISP, "%s, Program extra ISP setting!\n", __func__);
++ isp_load_regs_exclude_csi_isp_enable(ispbase,
++ &isp_dev->setfile.settings);
++ }
++
++ mutex_unlock(&isp_dev->setfile_lock);
++#else
++ mutex_lock(&isp_dev->setfile_lock);
++ if (isp_dev->setfile.state)
++ isp_load_regs(ispbase, &isp_dev->setfile.settings);
++ else
++ isp_load_regs(ispbase, isp_settings);
++ mutex_unlock(&isp_dev->setfile_lock);
++
++ st_debug(ST_ISP, "config 0x%x = 0x%x\n",
++ isp_format_reg_list[0].addr,
++ isp_format_reg_list[0].val);
++ st_debug(ST_ISP, "config 0x%x = 0x%x\n",
++ isp_format_reg_list[1].addr,
++ isp_format_reg_list[1].val);
++ st_debug(ST_ISP, "config 0x%x = 0x%x\n",
++ isp_format_reg_list[2].addr,
++ isp_format_reg_list[2].val);
++ st_debug(ST_ISP, "config 0x%x = 0x%x\n",
++ isp_format_reg_list[3].addr,
++ isp_format_reg_list[3].val);
++#endif
++
++ return 0;
++}
++
++static int stf_isp_set_format(struct stf_isp_dev *isp_dev,
++ struct isp_stream_format *crop_array, u32 mcode,
++ int type)
++{
++ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
++ struct stf_dvp_dev *dvp_dev = isp_dev->stfcamss->dvp_dev;
++ struct v4l2_rect *crop = &crop_array[ISP_COMPOSE].rect;
++ u32 bpp = crop_array[ISP_COMPOSE].bpp;
++ void __iomem *ispbase;
++ u32 val, val1;
++
++ ispbase = stf_isp_get_ispbase(vin);
++
++ st_debug(ST_ISP, "interface type is %d(%s)\n",
++ type, type == CSI_SENSOR ? "CSI" : "DVP");
++
++ if (type == DVP_SENSOR) {
++ unsigned int flags = dvp_dev->dvp->flags;
++
++ st_debug(ST_ISP, "dvp flags = 0x%x, hsync active is %s, vsync active is %s\n",
++ flags, flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH ? "high" : "low",
++ flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH ? "high" : "low");
++ }
++
++ val = crop->left + (crop->top << 16);
++ isp_format_reg_list[0].addr = ISP_REG_PIC_CAPTURE_START_CFG;
++ isp_format_reg_list[0].val = val;
++
++ val = (crop->width + crop->left - 1)
++ + ((crop->height + crop->top - 1) << 16);
++ isp_format_reg_list[1].addr = ISP_REG_PIC_CAPTURE_END_CFG;
++ isp_format_reg_list[1].val = val;
++
++ val = crop->width + (crop->height << 16);
++ isp_format_reg_list[2].addr = ISP_REG_PIPELINE_XY_SIZE;
++ isp_format_reg_list[2].val = val;
++
++ isp_format_reg_list[3].addr = ISP_REG_STRIDE;
++ isp_format_reg_list[3].val = ALIGN(crop->width * bpp / 8, STFCAMSS_FRAME_WIDTH_ALIGN_8);
++
++ switch (mcode) {
++ case MEDIA_BUS_FMT_SRGGB10_1X10:
++ case MEDIA_BUS_FMT_SRGGB8_1X8:
++ // 3 2 3 2 1 0 1 0 B Gb B Gb Gr R Gr R
++ val = 0x0000EE44;
++ val1 = 0x00000000;
++ break;
++ case MEDIA_BUS_FMT_SGRBG10_1X10:
++ case MEDIA_BUS_FMT_SGRBG8_1X8:
++ // 2 3 2 3 0 1 0 1, Gb B Gb B R Gr R Gr
++ val = 0x0000BB11;
++ val1 = 0x20000000;
++ break;
++ case MEDIA_BUS_FMT_SGBRG10_1X10:
++ case MEDIA_BUS_FMT_SGBRG8_1X8:
++ // 1 0 1 0 3 2 3 2, Gr R Gr R B Gb B Gb
++ val = 0x000044EE;
++ val1 = 0x30000000;
++ break;
++ case MEDIA_BUS_FMT_SBGGR10_1X10:
++ case MEDIA_BUS_FMT_SBGGR8_1X8:
++ // 0 1 0 1 2 3 2 3 R Gr R Gr Gb B Gb B
++ val = 0x000011BB;
++ val1 = 0x10000000;
++ break;
++ default:
++ st_err(ST_ISP, "UNKNOW format\n");
++ val = 0x000011BB;
++ val1 = 0x10000000;
++ break;
++ }
++
++ isp_format_reg_list[4].addr = ISP_REG_RAW_FORMAT_CFG;
++ isp_format_reg_list[4].val = val;
++
++ isp_format_reg_list[5].addr = ISP_REG_ISP_CTRL_1;
++ isp_format_reg_list[5].val = val1;
++ isp_format_reg_list[5].mask = 0xF0000000;
++
++ st_info(ST_ISP, "src left: %d, top: %d, width = %d, height = %d, bpp = %d\n",
++ crop->left, crop->top, crop->width, crop->height, bpp);
++
++ crop = &crop_array[ISP_CROP].rect;
++ bpp = crop_array[ISP_CROP].bpp;
++ val = ALIGN(crop->width * bpp / 8, STFCAMSS_FRAME_WIDTH_ALIGN_128);
++ isp_format_reg_list[6].addr = ISP_REG_DUMP_CFG_1;
++ isp_format_reg_list[6].val = val | 3 << 16;
++ isp_format_reg_list[6].mask = 0x0003FFFF;
++
++ st_info(ST_ISP, "raw left: %d, top: %d, width = %d, height = %d, bpp = %d\n",
++ crop->left, crop->top, crop->width, crop->height, bpp);
++
++ crop = &crop_array[ISP_SCALE_SS0].rect;
++ bpp = crop_array[ISP_SCALE_SS0].bpp;
++ isp_format_reg_list[7].addr = ISP_REG_SS0IW;
++ isp_format_reg_list[7].val = (crop->width << 16) + crop->height;
++ isp_format_reg_list[8].addr = ISP_REG_SS0S;
++ isp_format_reg_list[8].val = ALIGN(crop->width * bpp / 8, STFCAMSS_FRAME_WIDTH_ALIGN_8);
++
++ st_info(ST_ISP, "ss0 left: %d, top: %d, width = %d, height = %d, bpp = %d\n",
++ crop->left, crop->top, crop->width, crop->height, bpp);
++
++ crop = &crop_array[ISP_SCALE_SS1].rect;
++ bpp = crop_array[ISP_SCALE_SS1].bpp;
++ isp_format_reg_list[9].addr = ISP_REG_SS1IW;
++ isp_format_reg_list[9].val = (crop->width << 16) + crop->height;
++ isp_format_reg_list[10].addr = ISP_REG_SS1S;
++ isp_format_reg_list[10].val = ALIGN(crop->width * bpp / 8, STFCAMSS_FRAME_WIDTH_ALIGN_8);
++
++ crop = &crop_array[ISP_ITIWS].rect;
++ bpp = crop_array[ISP_ITIWS].bpp;
++ isp_format_reg_list[11].addr = ISP_REG_ITIIWSR;
++ isp_format_reg_list[11].val = (crop->height << 16) + crop->width;
++ isp_format_reg_list[12].addr = ISP_REG_ITIDWLSR;
++ isp_format_reg_list[12].val = ALIGN(crop->width * bpp / 8, STFCAMSS_FRAME_WIDTH_ALIGN_8);
++ isp_format_reg_list[13].addr = ISP_REG_ITIDRLSR;
++ isp_format_reg_list[13].val = ALIGN(crop->width * bpp / 8, STFCAMSS_FRAME_WIDTH_ALIGN_8);
++
++ st_info(ST_ISP, "iti left: %d, top: %d, width = %d, height = %d, bpp = %d\n",
++ crop->left, crop->top, crop->width, crop->height, bpp);
++
++ isp_format_reg_list[14].addr = ISP_REG_SENSOR;
++ isp_format_reg_list[14].val = 0x00000000;
++ if (type == DVP_SENSOR) {
++ unsigned int flags = dvp_dev->dvp->flags;
++
++ if (flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH)
++ isp_format_reg_list[14].val |= 0x08;
++ if (flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH)
++ isp_format_reg_list[14].val |= 0x04;
++ } else {
++ isp_format_reg_list[14].val |= 0x01;
++ }
++
++ isp_load_regs(ispbase, isp_format_settings);
++ return 0;
++}
++
++static int stf_isp_stream_set(struct stf_isp_dev *isp_dev, int on)
++{
++ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
++
++ void __iomem *ispbase;
++
++ ispbase = stf_isp_get_ispbase(vin);
++
++ if (on) {
++#if defined(USE_NEW_CONFIG_SETTING)
++ isp_load_regs(ispbase, isp_reg_start_settings);
++#else
++ reg_set_bit(ispbase, ISP_REG_CSIINTS_ADDR, 0x3FFFF, 0x3000a);
++ reg_set_bit(ispbase, ISP_REG_IESHD_ADDR, BIT(1) | BIT(0), 0x3);
++ reg_set_bit(ispbase, ISP_REG_ISP_CTRL_0, BIT(0), 1);
++#endif //#if defined(USE_NEW_CONFIG_SETTING)
++ } else {
++ /* NOTE: Clear bit 0 of ISP_REG_ISP_CTRL_0 here will get crash. */
++ stf_isp_save_ctx_regs(isp_dev);
++ }
++
++ return 0;
++}
++
++static union reg_buf reg_buf;
++static int stf_isp_reg_read(struct stf_isp_dev *isp_dev, void *arg)
++{
++ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
++ void __iomem *ispbase;
++ struct isp_reg_param *reg_param = arg;
++ u32 size;
++ unsigned long r;
++
++ if (reg_param->reg_buf == NULL) {
++ st_err(ST_ISP, "Failed to access register. The pointer is NULL!!!\n");
++ return -EINVAL;
++ }
++
++ ispbase = stf_isp_get_ispbase(vin);
++
++ size = 0;
++ switch (reg_param->reg_info.method) {
++ case STF_ISP_REG_METHOD_ONE_REG:
++ break;
++
++ case STF_ISP_REG_METHOD_SERIES:
++ if (reg_param->reg_info.length > STF_ISP_REG_BUF_SIZE) {
++ st_err(ST_ISP, "Failed to access register. \
++ The (length=0x%08X > 0x%08X) is out of size!!!\n",
++ reg_param->reg_info.length, STF_ISP_REG_BUF_SIZE);
++ return -EINVAL;
++ }
++ break;
++
++ case STF_ISP_REG_METHOD_MODULE:
++ /* This mode is not supported in the V4L2 version. */
++ st_err(ST_ISP, "Reg Read - Failed to access register. The method = \
++ STF_ISP_REG_METHOD_MODULE is not supported!!!\n");
++ return -ENOTTY;
++
++ case STF_ISP_REG_METHOD_TABLE:
++ if (reg_param->reg_info.length > STF_ISP_REG_TBL_BUF_SIZE) {
++ st_err(ST_ISP, "Failed to access register. \
++ The (length=0x%08X > 0x%08X) is out of size!!!\n",
++ reg_param->reg_info.length, STF_ISP_REG_TBL_BUF_SIZE);
++ return -EINVAL;
++ }
++ size = sizeof(u32) * reg_param->reg_info.length * 2;
++ break;
++
++ case STF_ISP_REG_METHOD_TABLE_2:
++ if (reg_param->reg_info.length > STF_ISP_REG_TBL_2_BUF_SIZE) {
++ st_err(ST_ISP, "Failed to access register. \
++ The (length=0x%08X > 0x%08X) is out of size!!!\n",
++ reg_param->reg_info.length, STF_ISP_REG_TBL_2_BUF_SIZE);
++ return -EINVAL;
++ }
++ size = sizeof(u32) * reg_param->reg_info.length * 3;
++ break;
++
++ case STF_ISP_REG_METHOD_TABLE_3:
++ if (reg_param->reg_info.length > STF_ISP_REG_TBL_3_BUF_SIZE) {
++ st_err(ST_ISP, "Failed to access register. \
++ The (length=0x%08X > 0x%08X) is out of size!!!\n",
++ reg_param->reg_info.length, STF_ISP_REG_TBL_3_BUF_SIZE);
++ return -EINVAL;
++ }
++ size = sizeof(u32) * reg_param->reg_info.length * 4;
++ break;
++
++ case STF_ISP_REG_METHOD_SMPL_PACK:
++ st_err(ST_ISP, "Reg Read - Failed to access register. The method = \
++ STF_ISP_REG_METHOD_SMPL_PACK is not supported!!!\n");
++ return -ENOTTY;
++
++ case STF_ISP_REG_METHOD_SOFT_RDMA:
++ // This mode is not supported in the V4L2 version.
++ st_err(ST_ISP, "Reg Read - Failed to access register. The method = \
++ STF_ISP_REG_METHOD_SOFT_RDMA is not supported!!!\n");
++ return -ENOTTY;
++
++ default:
++ st_err(ST_ISP, "Failed to access register. The method=%d \
++ is not supported!!!\n", reg_param->reg_info.method);
++ return -ENOTTY;
++ }
++
++ memset(&reg_buf, 0, sizeof(union reg_buf));
++ if (size) {
++ r = copy_from_user((u8 *)reg_buf.buffer,
++ (u8 *)reg_param->reg_buf->buffer, size);
++ if (r) {
++ st_err(ST_ISP, "Failed to call copy_from_user for the \
++ reg_param->reg_buf value\n");
++ return -EIO;
++ }
++ }
++
++ size = 0;
++ switch (reg_param->reg_info.method) {
++ case STF_ISP_REG_METHOD_ONE_REG:
++ reg_buf.buffer[0] = reg_read(ispbase, reg_param->reg_info.offset);
++ size = sizeof(u32);
++ break;
++
++ case STF_ISP_REG_METHOD_SERIES:
++ for (r = 0; r < reg_param->reg_info.length; r++) {
++ reg_buf.buffer[r] = reg_read(ispbase,
++ reg_param->reg_info.offset + (r * 4));
++ }
++ size = sizeof(u32) * reg_param->reg_info.length;
++ break;
++
++ case STF_ISP_REG_METHOD_MODULE:
++ break;
++
++ case STF_ISP_REG_METHOD_TABLE:
++ for (r = 0; r < reg_param->reg_info.length; r++) {
++ reg_buf.reg_tbl[r].value = reg_read(ispbase,
++ reg_buf.reg_tbl[r].offset);
++ }
++ size = sizeof(u32) * reg_param->reg_info.length * 2;
++ break;
++
++ case STF_ISP_REG_METHOD_TABLE_2:
++ for (r = 0; r < reg_param->reg_info.length; r++) {
++ if (reg_buf.reg_tbl2[r].mask) {
++ reg_buf.reg_tbl2[r].value = (reg_read(ispbase,
++ reg_buf.reg_tbl2[r].offset)
++ & reg_buf.reg_tbl2[r].mask);
++ } else {
++ reg_buf.reg_tbl2[r].value = reg_read(ispbase,
++ reg_buf.reg_tbl2[r].offset);
++ }
++ }
++ size = sizeof(u32) * reg_param->reg_info.length * 3;
++ break;
++
++ case STF_ISP_REG_METHOD_TABLE_3:
++ for (r = 0; r < reg_param->reg_info.length; r++) {
++ if (reg_buf.reg_tbl3[r].mask) {
++ reg_buf.reg_tbl3[r].value = (reg_read(ispbase,
++ reg_buf.reg_tbl3[r].offset)
++ & reg_buf.reg_tbl3[r].mask);
++ } else {
++ reg_buf.reg_tbl3[r].value = reg_read(ispbase,
++ reg_buf.reg_tbl3[r].offset);
++ }
++ if (reg_buf.reg_tbl3[r].delay_ms) {
++ usleep_range(1000 * reg_buf.reg_tbl3[r].delay_ms,
++ 1000 * reg_buf.reg_tbl3[r].delay_ms + 100);
++ }
++ }
++ size = sizeof(u32) * reg_param->reg_info.length * 4;
++ break;
++
++ case STF_ISP_REG_METHOD_SMPL_PACK:
++ break;
++
++ case STF_ISP_REG_METHOD_SOFT_RDMA:
++ break;
++
++ default:
++ break;
++ }
++
++ r = copy_to_user((u8 *)reg_param->reg_buf->buffer, (u8 *)reg_buf.buffer,
++ size);
++ if (r) {
++ st_err(ST_ISP, "Failed to call copy_to_user for the \
++ reg_param->buffer value\n");
++ return -EIO;
++ }
++
++ return 0;
++}
++
++static int stf_isp_soft_rdma(struct stf_isp_dev *isp_dev, u32 rdma_addr)
++{
++ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
++ void __iomem *ispbase;
++ struct isp_rdma_info *rdma_info = NULL;
++ s32 len;
++ u32 offset;
++ int ret = 0;
++
++ ispbase = stf_isp_get_ispbase(vin);
++
++ rdma_info = phys_to_virt(rdma_addr);
++ while (1) {
++ if (rdma_info->tag == RDMA_WR_ONE) {
++ reg_write(ispbase, rdma_info->offset, rdma_info->param);
++ rdma_info++;
++ } else if (rdma_info->tag == RDMA_WR_SRL) {
++ offset = rdma_info->offset;
++ len = rdma_info->param;
++ rdma_info++;
++ while (len > 0) {
++ reg_write(ispbase, offset, rdma_info->param);
++ offset += 4;
++ len--;
++ if (len > 0) {
++ reg_write(ispbase, offset, rdma_info->value);
++ len--;
++ }
++ offset += 4;
++ rdma_info++;
++ }
++ } else if (rdma_info->tag == RDMA_LINK) {
++ rdma_info = phys_to_virt(rdma_info->param);
++ } else if (rdma_info->tag == RDMA_SINT) {
++ /* Software not support this command. */
++ rdma_info++;
++ } else if (rdma_info->tag == RDMA_END) {
++ break;
++ } else
++ rdma_info++;
++ }
++
++ return ret;
++}
++
++static int stf_isp_reg_write(struct stf_isp_dev *isp_dev, void *arg)
++{
++ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
++ void __iomem *ispbase;
++ struct isp_reg_param *reg_param = arg;
++ struct isp_rdma_info *rdma_info = NULL;
++ s32 len;
++ u32 offset;
++ u32 size;
++ unsigned long r;
++ int ret = 0;
++
++ if ((reg_param->reg_buf == NULL)
++ && (reg_param->reg_info.method != STF_ISP_REG_METHOD_SOFT_RDMA)) {
++ st_err(ST_ISP, "Failed to access register. \
++ The register buffer pointer is NULL!!!\n");
++ return -EINVAL;
++ }
++
++ ispbase = stf_isp_get_ispbase(vin);
++
++ size = 0;
++ switch (reg_param->reg_info.method) {
++ case STF_ISP_REG_METHOD_ONE_REG:
++ size = sizeof(u32);
++ break;
++
++ case STF_ISP_REG_METHOD_SERIES:
++ if (reg_param->reg_info.length > STF_ISP_REG_BUF_SIZE) {
++ st_err(ST_ISP, "Failed to access register. \
++ The (length=0x%08X > 0x%08X) is out of size!!!\n",
++ reg_param->reg_info.length, STF_ISP_REG_BUF_SIZE);
++ return -EINVAL;
++ }
++ size = sizeof(u32) * reg_param->reg_info.length;
++ break;
++
++ case STF_ISP_REG_METHOD_MODULE:
++ // This mode is not supported in the V4L2 version.
++ st_err(ST_ISP, "Reg Write - Failed to access register. \
++ The method = STF_ISP_REG_METHOD_MODULE is not supported!!!\n");
++ return -ENOTTY;
++
++ case STF_ISP_REG_METHOD_TABLE:
++ if (reg_param->reg_info.length > STF_ISP_REG_TBL_BUF_SIZE) {
++ st_err(ST_ISP, "Failed to access register. \
++ The (length=0x%08X > 0x%08X) is out of size!!!\n",
++ reg_param->reg_info.length, STF_ISP_REG_TBL_BUF_SIZE);
++ return -EINVAL;
++ }
++ size = sizeof(u32) * reg_param->reg_info.length * 2;
++ break;
++
++ case STF_ISP_REG_METHOD_TABLE_2:
++ if (reg_param->reg_info.length > STF_ISP_REG_TBL_2_BUF_SIZE) {
++ st_err(ST_ISP, "Failed to access register. \
++ The (length=0x%08X > 0x%08X) is out of size!!!\n",
++ reg_param->reg_info.length, STF_ISP_REG_TBL_2_BUF_SIZE);
++ return -EINVAL;
++ }
++ size = sizeof(u32) * reg_param->reg_info.length * 3;
++ break;
++
++ case STF_ISP_REG_METHOD_TABLE_3:
++ if (reg_param->reg_info.length > STF_ISP_REG_TBL_3_BUF_SIZE) {
++ st_err(ST_ISP, "Failed to access register. \
++ The (length=0x%08X > 0x%08X) is out of size!!!\n",
++ reg_param->reg_info.length, STF_ISP_REG_TBL_3_BUF_SIZE);
++ return -EINVAL;
++ }
++ size = sizeof(u32) * reg_param->reg_info.length * 4;
++ break;
++
++ case STF_ISP_REG_METHOD_SMPL_PACK:
++ if (reg_param->reg_info.length > STF_ISP_REG_SMPL_PACK_BUF_SIZE) {
++ st_err(ST_ISP, "Failed to access register. \
++ The (length=0x%08X > 0x%08X) is out of size!!!\n",
++ reg_param->reg_info.length, STF_ISP_REG_SMPL_PACK_BUF_SIZE);
++ return -EINVAL;
++ }
++ size = sizeof(u32) * reg_param->reg_info.length * 2;
++ break;
++
++ case STF_ISP_REG_METHOD_SOFT_RDMA:
++ break;
++
++ default:
++ st_err(ST_ISP, "Failed to access register. The method=%d \
++ is not supported!!!\n", reg_param->reg_info.method);
++ return -ENOTTY;
++ }
++
++ memset(&reg_buf, 0, sizeof(union reg_buf));
++ if (size) {
++ r = copy_from_user((u8 *)reg_buf.buffer,
++ (u8 *)reg_param->reg_buf->buffer, size);
++ if (r) {
++ st_err(ST_ISP, "Failed to call copy_from_user for the \
++ reg_param->reg_buf value\n");
++ return -EIO;
++ }
++ }
++
++ switch (reg_param->reg_info.method) {
++ case STF_ISP_REG_METHOD_ONE_REG:
++ reg_write(ispbase, reg_param->reg_info.offset, reg_buf.buffer[0]);
++ break;
++
++ case STF_ISP_REG_METHOD_SERIES:
++ for (r = 0; r < reg_param->reg_info.length; r++) {
++ reg_write(ispbase, reg_param->reg_info.offset + (r * 4),
++ reg_buf.buffer[r]);
++ }
++ break;
++
++ case STF_ISP_REG_METHOD_MODULE:
++ /* This mode is not supported in the V4L2 version. */
++ break;
++
++ case STF_ISP_REG_METHOD_TABLE:
++ for (r = 0; r < reg_param->reg_info.length; r++) {
++ reg_write(ispbase, reg_buf.reg_tbl[r].offset,
++ reg_buf.reg_tbl[r].value);
++ }
++ break;
++
++ case STF_ISP_REG_METHOD_TABLE_2:
++ for (r = 0; r < reg_param->reg_info.length; r++) {
++ if (reg_buf.reg_tbl2[r].mask) {
++ reg_set_bit(ispbase, reg_buf.reg_tbl2[r].offset,
++ reg_buf.reg_tbl2[r].mask, reg_buf.reg_tbl2[r].value);
++ } else {
++ reg_write(ispbase, reg_buf.reg_tbl2[r].offset,
++ reg_buf.reg_tbl2[r].value);
++ }
++ }
++ break;
++
++ case STF_ISP_REG_METHOD_TABLE_3:
++ for (r = 0; r < reg_param->reg_info.length; r++) {
++ if (reg_buf.reg_tbl3[r].mask) {
++ reg_set_bit(ispbase, reg_buf.reg_tbl3[r].offset,
++ reg_buf.reg_tbl3[r].mask, reg_buf.reg_tbl3[r].value);
++ } else {
++ reg_write(ispbase, reg_buf.reg_tbl3[r].offset,
++ reg_buf.reg_tbl3[r].value);
++ }
++ if (reg_buf.reg_tbl3[r].delay_ms) {
++ usleep_range(1000 * reg_buf.reg_tbl3[r].delay_ms,
++ 1000 * reg_buf.reg_tbl3[r].delay_ms + 100);
++ }
++ }
++ break;
++
++ case STF_ISP_REG_METHOD_SMPL_PACK:
++ size = reg_param->reg_info.length;
++ rdma_info = &reg_buf.rdma_cmd[0];
++ while (size) {
++ if (rdma_info->tag == RDMA_WR_ONE) {
++ reg_write(ispbase, rdma_info->offset, rdma_info->param);
++ rdma_info++;
++ size--;
++ } else if (rdma_info->tag == RDMA_WR_SRL) {
++ offset = rdma_info->offset;
++ len = rdma_info->param;
++ rdma_info++;
++ size--;
++ while (size && (len > 0)) {
++ reg_write(ispbase, offset, rdma_info->param);
++ offset += 4;
++ len--;
++ if (len > 0) {
++ reg_write(ispbase, offset, rdma_info->value);
++ len--;
++ }
++ offset += 4;
++ rdma_info++;
++ size--;
++ }
++ } else if (rdma_info->tag == RDMA_END) {
++ break;
++ } else {
++ rdma_info++;
++ size--;
++ }
++ }
++ break;
++
++ case STF_ISP_REG_METHOD_SOFT_RDMA:
++ /*
++ * Simulation the hardware RDMA behavior to debug and verify
++ * the RDMA chain.
++ */
++ ret = stf_isp_soft_rdma(isp_dev, reg_param->reg_info.offset);
++ break;
++
++ default:
++ break;
++ }
++
++ return ret;
++}
++
++static int stf_isp_shadow_trigger(struct stf_isp_dev *isp_dev)
++{
++ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
++ void __iomem *ispbase;
++
++ ispbase = stf_isp_get_ispbase(vin);
++
++ // shadow update
++ reg_set_bit(ispbase, ISP_REG_CSIINTS_ADDR, (BIT(17) | BIT(16)), 0x30000);
++ reg_set_bit(ispbase, ISP_REG_IESHD_ADDR, (BIT(1) | BIT(0)), 0x3);
++ return 0;
++}
++
++void dump_isp_reg(void *__iomem ispbase)
++{
++ int j;
++ u32 addr, val;
++
++ st_debug(ST_ISP, "DUMP ISP register:\n -- isp_reg_init_settings --\n");
++ for (j = 0; j < isp_reg_init_settings->regval_num; j++) {
++ addr = isp_reg_init_settings->regval[j].addr;
++ val = ioread32(ispbase + addr);
++ st_debug(ST_ISP, "{0x%08x, 0x%08x}\n", addr, val);
++ }
++
++ st_debug(ST_ISP, " --- isp_format_settings ---\n");
++ for (j = 0; j < isp_format_settings->regval_num; j++) {
++ addr = isp_format_settings->regval[j].addr;
++ val = ioread32(ispbase + addr);
++ st_debug(ST_ISP, "{0x%08x, 0x%08x}\n", addr, val);
++ }
++
++ val = ioread32(ispbase + ISP_REG_Y_PLANE_START_ADDR);
++ st_debug(ST_ISP, "-- ISP_REG_Y_PLANE_START_ADDR --\n {0x%08x, 0x%08x}\n",
++ ISP_REG_Y_PLANE_START_ADDR, val);
++ val = ioread32(ispbase + ISP_REG_UV_PLANE_START_ADDR);
++ st_debug(ST_ISP, "-- ISP_REG_UV_PLANE_START_ADDR --\n {0x%08x, 0x%08x}\n",
++ ISP_REG_UV_PLANE_START_ADDR, val);
++ val = ioread32(ispbase + ISP_REG_DUMP_CFG_0);
++ st_debug(ST_ISP, "-- ISP_REG_DUMP_CFG_0 --\n {0x%08x, 0x%08x}\n",
++ ISP_REG_DUMP_CFG_0, val);
++ val = ioread32(ispbase + ISP_REG_DUMP_CFG_1);
++ st_debug(ST_ISP, " --- ISP_REG_DUMP_CFG_1 ---\n {0x%08x, 0x%08x}\n",
++ ISP_REG_DUMP_CFG_1, val);
++
++ st_debug(ST_ISP, " --- isp_reg_start_settings ---\n");
++ for (j = 0; j < isp_reg_start_settings->regval_num; j++) {
++ addr = isp_reg_start_settings->regval[j].addr;
++ val = ioread32(ispbase + addr);
++ st_debug(ST_ISP, "{0x%08x, 0x%08x}\n", addr, val);
++ }
++}
++
++struct isp_hw_ops isp_ops = {
++ .isp_clk_enable = stf_isp_clk_enable,
++ .isp_clk_disable = stf_isp_clk_disable,
++ .isp_reset = stf_isp_reset,
++ .isp_config_set = stf_isp_config_set,
++ .isp_set_format = stf_isp_set_format,
++ .isp_stream_set = stf_isp_stream_set,
++ .isp_reg_read = stf_isp_reg_read,
++ .isp_reg_write = stf_isp_reg_write,
++ .isp_shadow_trigger = stf_isp_shadow_trigger,
++};
+--- /dev/null
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_isp_ioctl.h
+@@ -0,0 +1,133 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++/*
++ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
++ *
++ */
++
++#ifndef STF_ISP_IOCTL_H
++#define STF_ISP_IOCTL_H
++
++
++#include <media/v4l2-ctrls.h>
++
++
++#define FILENAME_MAX_LEN 30
++
++#define ISP_IOC ('V')
++#define STF_ISP_REG_BUF_SIZE (768)
++#define STF_ISP_REG_TBL_BUF_SIZE (STF_ISP_REG_BUF_SIZE / 2)
++#define STF_ISP_REG_TBL_2_BUF_SIZE (STF_ISP_REG_BUF_SIZE / 3)
++#define STF_ISP_REG_TBL_3_BUF_SIZE (STF_ISP_REG_BUF_SIZE / 4)
++#define STF_ISP_REG_SMPL_PACK_BUF_SIZE (STF_ISP_REG_BUF_SIZE / 2)
++#define RDMA_WR_ONE (0xA0)
++#define RDMA_WR_SRL (0xA1)
++#define RDMA_LINK (0xA2)
++#define RDMA_SINT (0xA3)
++#define RDMA_END (0xAF)
++#define ENABLE_SS0_SS1
++
++enum _STF_ISP_IOCTL {
++ STF_ISP_IOCTL_LOAD_FW = BASE_VIDIOC_PRIVATE + 1,
++ STF_ISP_IOCTL_DMABUF_ALLOC,
++ STF_ISP_IOCTL_DMABUF_FREE,
++ STF_ISP_IOCTL_GET_HW_VER,
++ STF_ISP_IOCTL_REG,
++ STF_ISP_IOCTL_SHADOW_LOCK,
++ STF_ISP_IOCTL_SHADOW_UNLOCK,
++ STF_ISP_IOCTL_SHADOW_UNLOCK_N_TRIGGER,
++ STF_ISP_IOCTL_SET_USER_CONFIG_ISP,
++ STF_ISP_IOCTL_MAX
++};
++
++enum _STF_ISP_REG_METHOD {
++ STF_ISP_REG_METHOD_ONE_REG = 0,
++ STF_ISP_REG_METHOD_SERIES,
++ STF_ISP_REG_METHOD_MODULE,
++ STF_ISP_REG_METHOD_TABLE,
++ STF_ISP_REG_METHOD_TABLE_2,
++ STF_ISP_REG_METHOD_TABLE_3,
++ STF_ISP_REG_METHOD_SMPL_PACK,
++ STF_ISP_REG_METHOD_SOFT_RDMA,
++ STF_ISP_REG_METHOD_MAX
++};
++
++
++struct stfisp_fw_info {
++ char __user filename[FILENAME_MAX_LEN];
++};
++
++struct dmabuf_create {
++ __u32 fd;
++ __u32 size;
++ __u32 paddr;
++};
++
++struct isp_rdma_info {
++ u32 param;
++ union {
++ u32 value;
++ struct {
++ u32 offset : 24;
++ u32 tag : 8;
++ };
++ };
++};
++
++struct isp_reg_info {
++ /** @brief [in] access method of register */
++ u8 method;
++ /** @brief [in] offset indicated which register will be read/write */
++ u32 offset;
++ /** @brief [in] length for indicated how much register will be read/write */
++ u32 length;
++};
++
++union reg_buf {
++ u32 buffer[STF_ISP_REG_BUF_SIZE];
++ struct {
++ u32 offset;
++ u32 value;
++ } reg_tbl[STF_ISP_REG_TBL_BUF_SIZE];
++ struct {
++ u32 offset;
++ u32 value;
++ u32 mask;
++ } reg_tbl2[STF_ISP_REG_TBL_2_BUF_SIZE];
++ struct {
++ u32 offset;
++ u32 value;
++ u32 mask;
++ u32 delay_ms;
++ } reg_tbl3[STF_ISP_REG_TBL_3_BUF_SIZE];
++ struct isp_rdma_info rdma_cmd[STF_ISP_REG_SMPL_PACK_BUF_SIZE];
++};
++
++struct isp_reg_param {
++ /** @brief [in, out] register read/write information */
++ struct isp_reg_info reg_info;
++ /** @brief [in, out] buffer */
++ union reg_buf *reg_buf;
++};
++
++
++#define VIDIOC_STFISP_LOAD_FW \
++ _IOW(ISP_IOC, STF_ISP_IOCTL_LOAD_FW, struct stfisp_fw_info)
++#define VIDIOC_STF_DMABUF_ALLOC \
++ _IOWR(ISP_IOC, STF_ISP_IOCTL_DMABUF_ALLOC, struct dmabuf_create)
++#define VIDIOC_STF_DMABUF_FREE \
++ _IOWR(ISP_IOC, STF_ISP_IOCTL_DMABUF_FREE, struct dmabuf_create)
++#define VIDIOC_STFISP_GET_REG \
++ _IOWR(ISP_IOC, STF_ISP_IOCTL_REG, struct isp_reg_param)
++#define VIDIOC_STFISP_SET_REG \
++ _IOW(ISP_IOC, STF_ISP_IOCTL_REG, struct isp_reg_param)
++#define VIDIOC_STFISP_SHADOW_LOCK \
++ _IO(ISP_IOC, STF_ISP_IOCTL_SHADOW_LOCK)
++#define VIDIOC_STFISP_SHADOW_UNLOCK \
++ _IO(ISP_IOC, STF_ISP_IOCTL_SHADOW_UNLOCK)
++#define VIDIOC_STFISP_SHADOW_UNLOCK_N_TRIGGER \
++ _IO(ISP_IOC, STF_ISP_IOCTL_SHADOW_UNLOCK_N_TRIGGER)
++#define VIDIOC_STFISP_SET_USER_CONFIG_ISP \
++ _IO(ISP_IOC, STF_ISP_IOCTL_SET_USER_CONFIG_ISP)
++
++
++#endif /* STF_ISP_IOCTL_H */
+--- /dev/null
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_video.c
+@@ -0,0 +1,1552 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
++ *
++ */
++
++#include "stfcamss.h"
++#include "stf_video.h"
++#include <media/media-entity.h>
++#include <media/v4l2-event.h>
++#include <media/v4l2-mc.h>
++#include <media/videobuf2-dma-sg.h>
++#include <media/videobuf2-vmalloc.h>
++#include <media/videobuf2-dma-contig.h>
++
++static const struct stfcamss_format_info formats_pix_st7110_wr[] = {
++ { MEDIA_BUS_FMT_AYUV8_1X32, V4L2_PIX_FMT_AYUV32, 1,
++ { { 1, 1 } }, { { 1, 1 } }, { 32 } },
++ { MEDIA_BUS_FMT_YUYV8_2X8, V4L2_PIX_FMT_YUYV, 1,
++ { { 1, 1 } }, { { 1, 1 } }, { 16 } },
++ { MEDIA_BUS_FMT_RGB565_2X8_LE, V4L2_PIX_FMT_RGB565, 1,
++ { { 1, 1 } }, { { 1, 1 } }, { 16 } },
++ { MEDIA_BUS_FMT_SRGGB8_1X8, V4L2_PIX_FMT_SRGGB8, 1,
++ { { 1, 1 } }, { { 1, 1 } }, { 8 } },
++ { MEDIA_BUS_FMT_SGRBG8_1X8, V4L2_PIX_FMT_SGRBG8, 1,
++ { { 1, 1 } }, { { 1, 1 } }, { 8 } },
++ { MEDIA_BUS_FMT_SGBRG8_1X8, V4L2_PIX_FMT_SGBRG8, 1,
++ { { 1, 1 } }, { { 1, 1 } }, { 8 } },
++ { MEDIA_BUS_FMT_SBGGR8_1X8, V4L2_PIX_FMT_SBGGR8, 1,
++ { { 1, 1 } }, { { 1, 1 } }, { 8 } },
++ { MEDIA_BUS_FMT_SRGGB10_1X10, V4L2_PIX_FMT_SRGGB10, 1,
++ { { 1, 1 } }, { { 1, 1 } }, { 10 } },
++ { MEDIA_BUS_FMT_SGRBG10_1X10, V4L2_PIX_FMT_SGRBG10, 1,
++ { { 1, 1 } }, { { 1, 1 } }, { 10 } },
++ { MEDIA_BUS_FMT_SGBRG10_1X10, V4L2_PIX_FMT_SGBRG10, 1,
++ { { 1, 1 } }, { { 1, 1 } }, { 10 } },
++ { MEDIA_BUS_FMT_SBGGR10_1X10, V4L2_PIX_FMT_SBGGR10, 1,
++ { { 1, 1 } }, { { 1, 1 } }, { 10 } },
++};
++
++static const struct stfcamss_format_info formats_raw_st7110_isp[] = {
++ { MEDIA_BUS_FMT_SBGGR12_1X12, V4L2_PIX_FMT_SBGGR12, 1,
++ { { 1, 1 } }, { { 1, 1 } }, { 12 } },
++ { MEDIA_BUS_FMT_SRGGB12_1X12, V4L2_PIX_FMT_SRGGB12, 1,
++ { { 1, 1 } }, { { 1, 1 } }, { 12 } },
++ { MEDIA_BUS_FMT_SGRBG12_1X12, V4L2_PIX_FMT_SGRBG12, 1,
++ { { 1, 1 } }, { { 1, 1 } }, { 12 } },
++ { MEDIA_BUS_FMT_SGBRG12_1X12, V4L2_PIX_FMT_SGBRG12, 1,
++ { { 1, 1 } }, { { 1, 1 } }, { 12 } },
++};
++
++static const struct stfcamss_format_info formats_pix_st7110_isp[] = {
++ // { MEDIA_BUS_FMT_YUYV12_2X12, V4L2_PIX_FMT_NV12M, 2,
++ // { { 1, 1 }, { 1, 1 } }, { { 1, 1 }, { 1, 1 } }, { 8 , 4 } },
++ { MEDIA_BUS_FMT_Y12_1X12, V4L2_PIX_FMT_NV12, 1,
++ { { 1, 1 } }, { { 2, 3 } }, { 8 } },
++ { MEDIA_BUS_FMT_Y12_1X12, V4L2_PIX_FMT_NV21, 1,
++ { { 1, 1 } }, { { 2, 3 } }, { 8 } },
++};
++
++static const struct stfcamss_format_info formats_st7110_isp_iti[] = {
++ // raw format
++ { MEDIA_BUS_FMT_SRGGB10_1X10, V4L2_PIX_FMT_SRGGB10, 1,
++ { { 1, 1 } }, { { 1, 1 } }, { 10 } },
++ { MEDIA_BUS_FMT_SGRBG10_1X10, V4L2_PIX_FMT_SGRBG10, 1,
++ { { 1, 1 } }, { { 1, 1 } }, { 10 } },
++ { MEDIA_BUS_FMT_SGBRG10_1X10, V4L2_PIX_FMT_SGBRG10, 1,
++ { { 1, 1 } }, { { 1, 1 } }, { 10 } },
++ { MEDIA_BUS_FMT_SBGGR10_1X10, V4L2_PIX_FMT_SBGGR10, 1,
++ { { 1, 1 } }, { { 1, 1 } }, { 10 } },
++ { MEDIA_BUS_FMT_SRGGB12_1X12, V4L2_PIX_FMT_SRGGB12, 1,
++ { { 1, 1 } }, { { 1, 1 } }, { 12 } },
++ { MEDIA_BUS_FMT_SGRBG12_1X12, V4L2_PIX_FMT_SGRBG12, 1,
++ { { 1, 1 } }, { { 1, 1 } }, { 12 } },
++ { MEDIA_BUS_FMT_SGBRG12_1X12, V4L2_PIX_FMT_SGBRG12, 1,
++ { { 1, 1 } }, { { 1, 1 } }, { 12 } },
++ { MEDIA_BUS_FMT_SBGGR12_1X12, V4L2_PIX_FMT_SBGGR12, 1,
++ { { 1, 1 } }, { { 1, 1 } }, { 12 } },
++
++ // YUV420
++ { MEDIA_BUS_FMT_Y12_1X12, V4L2_PIX_FMT_NV12, 1,
++ { { 1, 1 } }, { { 2, 3 } }, { 8 } },
++ { MEDIA_BUS_FMT_Y12_1X12, V4L2_PIX_FMT_NV21, 1,
++ { { 1, 1 } }, { { 2, 3 } }, { 8 } },
++
++ // YUV444
++ { MEDIA_BUS_FMT_YUV8_1X24, V4L2_PIX_FMT_NV24, 1,
++ { { 1, 1 } }, { { 1, 3 } }, { 8 } },
++ { MEDIA_BUS_FMT_VUY8_1X24, V4L2_PIX_FMT_NV42, 1,
++ { { 1, 1 } }, { { 1, 3 } }, { 8 } },
++};
++
++static int video_find_format(u32 code, u32 pixelformat,
++ const struct stfcamss_format_info *formats,
++ unsigned int nformats)
++{
++ int i;
++
++ for (i = 0; i < nformats; i++) {
++ if (formats[i].code == code &&
++ formats[i].pixelformat == pixelformat)
++ return i;
++ }
++
++ for (i = 0; i < nformats; i++)
++ if (formats[i].code == code)
++ return i;
++
++ for (i = 0; i < nformats; i++)
++ if (formats[i].pixelformat == pixelformat)
++ return i;
++
++ return -EINVAL;
++}
++
++static int __video_try_fmt(struct stfcamss_video *video,
++ struct v4l2_format *f, int is_mp)
++{
++ struct v4l2_pix_format *pix;
++ struct v4l2_pix_format_mplane *pix_mp;
++ const struct stfcamss_format_info *fi;
++ u32 width, height;
++ u32 bpl;
++ int i, j;
++
++ st_debug(ST_VIDEO, "%s, fmt.type = 0x%x\n", __func__, f->type);
++ pix = &f->fmt.pix;
++ pix_mp = &f->fmt.pix_mp;
++
++ if (is_mp) {
++ for (i = 0; i < video->nformats; i++)
++ if (pix_mp->pixelformat
++ == video->formats[i].pixelformat)
++ break;
++
++ if (i == video->nformats)
++ i = 0; /* default format */
++
++ fi = &video->formats[i];
++ width = pix_mp->width;
++ height = pix_mp->height;
++
++ memset(pix_mp, 0, sizeof(*pix_mp));
++
++ pix_mp->pixelformat = fi->pixelformat;
++ pix_mp->width = clamp_t(u32, width, STFCAMSS_FRAME_MIN_WIDTH,
++ STFCAMSS_FRAME_MAX_WIDTH);
++ pix_mp->height = clamp_t(u32, height, STFCAMSS_FRAME_MIN_HEIGHT,
++ STFCAMSS_FRAME_MAX_HEIGHT);
++ pix_mp->num_planes = fi->planes;
++ for (j = 0; j < pix_mp->num_planes; j++) {
++ bpl = pix_mp->width / fi->hsub[j].numerator *
++ fi->hsub[j].denominator * fi->bpp[j] / 8;
++ bpl = ALIGN(bpl, video->bpl_alignment);
++ pix_mp->plane_fmt[j].bytesperline = bpl;
++ pix_mp->plane_fmt[j].sizeimage = pix_mp->height /
++ fi->vsub[j].numerator
++ * fi->vsub[j].denominator * bpl;
++ }
++
++ pix_mp->field = V4L2_FIELD_NONE;
++ pix_mp->colorspace = V4L2_COLORSPACE_SRGB;
++ pix_mp->flags = 0;
++ pix_mp->ycbcr_enc =
++ V4L2_MAP_YCBCR_ENC_DEFAULT(pix_mp->colorspace);
++ pix_mp->quantization =
++ V4L2_MAP_QUANTIZATION_DEFAULT(true,
++ pix_mp->colorspace, pix_mp->ycbcr_enc);
++ pix_mp->xfer_func =
++ V4L2_MAP_XFER_FUNC_DEFAULT(pix_mp->colorspace);
++
++ st_info(ST_VIDEO, "w, h = %d, %d, bpp = %d\n", pix_mp->width,
++ pix_mp->height, fi->bpp[0]);
++ st_info(ST_VIDEO, "i = %d, p = %d, s = 0x%x\n", i,
++ pix_mp->num_planes, pix_mp->plane_fmt[0].sizeimage);
++
++ } else {
++ for (i = 0; i < video->nformats; i++)
++ if (pix->pixelformat == video->formats[i].pixelformat)
++ break;
++
++ if (i == video->nformats)
++ i = 0; /* default format */
++
++ fi = &video->formats[i];
++ width = pix->width;
++ height = pix->height;
++
++ memset(pix, 0, sizeof(*pix));
++
++ pix->pixelformat = fi->pixelformat;
++ pix->width = clamp_t(u32, width, STFCAMSS_FRAME_MIN_WIDTH,
++ STFCAMSS_FRAME_MAX_WIDTH);
++ pix->height = clamp_t(u32, height, STFCAMSS_FRAME_MIN_HEIGHT,
++ STFCAMSS_FRAME_MAX_HEIGHT);
++ bpl = pix->width / fi->hsub[0].numerator *
++ fi->hsub[0].denominator * fi->bpp[0] / 8;
++ bpl = ALIGN(bpl, video->bpl_alignment);
++ pix->bytesperline = bpl;
++ pix->sizeimage = pix->height /
++ fi->vsub[0].numerator
++ * fi->vsub[0].denominator * bpl;
++
++ pix->field = V4L2_FIELD_NONE;
++ pix->colorspace = V4L2_COLORSPACE_SRGB;
++ pix->flags = 0;
++ pix->ycbcr_enc =
++ V4L2_MAP_YCBCR_ENC_DEFAULT(pix->colorspace);
++ pix->quantization =
++ V4L2_MAP_QUANTIZATION_DEFAULT(true,
++ pix->colorspace, pix->ycbcr_enc);
++ pix->xfer_func =
++ V4L2_MAP_XFER_FUNC_DEFAULT(pix->colorspace);
++
++ st_info(ST_VIDEO, "w, h = %d, %d, bpp = %d\n", pix->width,
++ pix->height, fi->bpp[0]);
++ st_info(ST_VIDEO, "i = %d, s = 0x%x\n", i, pix->sizeimage);
++ }
++ return 0;
++}
++
++static int stf_video_init_format(struct stfcamss_video *video, int is_mp)
++{
++ int ret;
++ struct v4l2_format format = {
++ .type = video->type,
++ .fmt.pix = {
++ .width = 1920,
++ .height = 1080,
++ .pixelformat = V4L2_PIX_FMT_RGB565,
++ },
++ };
++
++ ret = __video_try_fmt(video, &format, is_mp);
++
++ if (ret < 0)
++ return ret;
++
++ video->active_fmt = format;
++
++ return 0;
++}
++
++static int video_queue_setup(struct vb2_queue *q,
++ unsigned int *num_buffers, unsigned int *num_planes,
++ unsigned int sizes[], struct device *alloc_devs[])
++{
++ struct stfcamss_video *video = vb2_get_drv_priv(q);
++ const struct v4l2_pix_format *format =
++ &video->active_fmt.fmt.pix;
++ const struct v4l2_pix_format_mplane *format_mp =
++ &video->active_fmt.fmt.pix_mp;
++ unsigned int i;
++
++ st_debug(ST_VIDEO, "%s, planes = %d\n", __func__, *num_planes);
++
++ if (video->is_mp) {
++ if (*num_planes) {
++ if (*num_planes != format_mp->num_planes)
++ return -EINVAL;
++
++ for (i = 0; i < *num_planes; i++)
++ if (sizes[i] <
++ format_mp->plane_fmt[i].sizeimage)
++ return -EINVAL;
++
++ return 0;
++ }
++
++ *num_planes = format_mp->num_planes;
++
++ for (i = 0; i < *num_planes; i++)
++ sizes[i] = format_mp->plane_fmt[i].sizeimage;
++ } else {
++ if (*num_planes) {
++ if (*num_planes != 1)
++ return -EINVAL;
++
++ if (sizes[0] < format->sizeimage)
++ return -EINVAL;
++ }
++
++ *num_planes = 1;
++ sizes[0] = format->sizeimage;
++ if (!sizes[0])
++ st_err(ST_VIDEO, "%s: error size is zero!!!\n", __func__);
++ }
++ if ((stf_vin_map_isp_pad(video->id, STF_ISP_PAD_SRC)
++ == STF_ISP_PAD_SRC_SCD_Y) &&
++ sizes[0] < ISP_SCD_Y_BUFFER_SIZE) {
++ sizes[0] = ISP_SCD_Y_BUFFER_SIZE;
++ }
++
++ st_info(ST_VIDEO, "%s, planes = %d, size = %d\n",
++ __func__, *num_planes, sizes[0]);
++ return 0;
++}
++
++static int video_buf_init(struct vb2_buffer *vb)
++{
++ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
++ struct stfcamss_video *video = vb2_get_drv_priv(vb->vb2_queue);
++ struct stfcamss_buffer *buffer =
++ container_of(vbuf, struct stfcamss_buffer, vb);
++ const struct v4l2_pix_format *fmt = &video->active_fmt.fmt.pix;
++ const struct v4l2_pix_format_mplane *fmt_mp =
++ &video->active_fmt.fmt.pix_mp;
++ //struct sg_table *sgt;
++ dma_addr_t *paddr;
++ unsigned int i;
++
++ buffer->sizeimage = 0;
++
++ if (video->is_mp) {
++ for (i = 0; i < fmt_mp->num_planes; i++) {
++ paddr = vb2_plane_cookie(vb, i);
++ buffer->addr[i] = *paddr;
++ buffer->sizeimage += vb2_plane_size(vb, i);
++ }
++
++ if (fmt_mp->num_planes == 1
++ && (fmt_mp->pixelformat == V4L2_PIX_FMT_NV12
++ || fmt_mp->pixelformat == V4L2_PIX_FMT_NV21
++ || fmt_mp->pixelformat == V4L2_PIX_FMT_NV16
++ || fmt_mp->pixelformat == V4L2_PIX_FMT_NV61))
++ buffer->addr[1] = buffer->addr[0] +
++ fmt_mp->plane_fmt[0].bytesperline *
++ fmt_mp->height;
++ } else {
++ paddr = vb2_plane_cookie(vb, 0);
++ buffer->sizeimage = vb2_plane_size(vb, 0);
++ buffer->addr[0] = *paddr;
++ if (fmt->pixelformat == V4L2_PIX_FMT_NV12
++ || fmt->pixelformat == V4L2_PIX_FMT_NV21
++ || fmt->pixelformat == V4L2_PIX_FMT_NV16
++ || fmt->pixelformat == V4L2_PIX_FMT_NV61)
++ buffer->addr[1] = buffer->addr[0] +
++ fmt->bytesperline *
++ fmt->height;
++ }
++
++ if (stf_vin_map_isp_pad(video->id, STF_ISP_PAD_SRC)
++ == STF_ISP_PAD_SRC_SCD_Y) {
++ buffer->addr[1] = buffer->addr[0] + ISP_YHIST_BUFFER_SIZE;
++ buffer->vaddr_sc = vb2_plane_vaddr(vb, 0);
++ }
++
++ return 0;
++}
++
++static int video_buf_prepare(struct vb2_buffer *vb)
++{
++ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
++ struct stfcamss_video *video = vb2_get_drv_priv(vb->vb2_queue);
++ const struct v4l2_pix_format *fmt = &video->active_fmt.fmt.pix;
++ const struct v4l2_pix_format_mplane *fmt_mp =
++ &video->active_fmt.fmt.pix_mp;
++ unsigned int i;
++
++ if (video->is_mp) {
++ for (i = 0; i < fmt_mp->num_planes; i++) {
++ if (fmt_mp->plane_fmt[i].sizeimage
++ > vb2_plane_size(vb, i))
++ return -EINVAL;
++
++ vb2_set_plane_payload(vb, i,
++ fmt_mp->plane_fmt[i].sizeimage);
++ }
++ } else {
++ if (fmt->sizeimage > vb2_plane_size(vb, 0)) {
++ st_err(ST_VIDEO, "sizeimage = %d, plane size = %d\n",
++ fmt->sizeimage, (unsigned int)vb2_plane_size(vb, 0));
++ return -EINVAL;
++ }
++ vb2_set_plane_payload(vb, 0, fmt->sizeimage);
++ }
++
++ vbuf->field = V4L2_FIELD_NONE;
++
++ return 0;
++}
++
++static void video_buf_queue(struct vb2_buffer *vb)
++{
++ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
++ struct stfcamss_video *video = vb2_get_drv_priv(vb->vb2_queue);
++ struct stfcamss_buffer *buffer =
++ container_of(vbuf, struct stfcamss_buffer, vb);
++
++ video->ops->queue_buffer(video, buffer);
++}
++
++static int video_mbus_to_pix_mp(const struct v4l2_mbus_framefmt *mbus,
++ struct v4l2_pix_format_mplane *pix,
++ const struct stfcamss_format_info *f,
++ unsigned int alignment)
++{
++ unsigned int i;
++ u32 bytesperline;
++
++ memset(pix, 0, sizeof(*pix));
++ v4l2_fill_pix_format_mplane(pix, mbus);
++ pix->pixelformat = f->pixelformat;
++ pix->num_planes = f->planes;
++ for (i = 0; i < pix->num_planes; i++) {
++ bytesperline = pix->width / f->hsub[i].numerator *
++ f->hsub[i].denominator * f->bpp[i] / 8;
++ bytesperline = ALIGN(bytesperline, alignment);
++ pix->plane_fmt[i].bytesperline = bytesperline;
++ pix->plane_fmt[i].sizeimage = pix->height /
++ f->vsub[i].numerator * f->vsub[i].denominator *
++ bytesperline;
++ }
++
++ return 0;
++}
++
++static int video_mbus_to_pix(const struct v4l2_mbus_framefmt *mbus,
++ struct v4l2_pix_format *pix,
++ const struct stfcamss_format_info *f,
++ unsigned int alignment)
++{
++ u32 bytesperline;
++
++ memset(pix, 0, sizeof(*pix));
++ v4l2_fill_pix_format(pix, mbus);
++ pix->pixelformat = f->pixelformat;
++ bytesperline = pix->width / f->hsub[0].numerator *
++ f->hsub[0].denominator * f->bpp[0] / 8;
++ bytesperline = ALIGN(bytesperline, alignment);
++ pix->bytesperline = bytesperline;
++ pix->sizeimage = pix->height /
++ f->vsub[0].numerator * f->vsub[0].denominator *
++ bytesperline;
++ return 0;
++}
++
++static struct v4l2_subdev *video_remote_subdev(
++ struct stfcamss_video *video, u32 *pad)
++{
++ struct media_pad *remote;
++
++ remote = media_pad_remote_pad_first(&video->pad);
++
++ if (!remote || !is_media_entity_v4l2_subdev(remote->entity))
++ return NULL;
++
++ if (pad)
++ *pad = remote->index;
++
++ return media_entity_to_v4l2_subdev(remote->entity);
++}
++
++static int video_get_subdev_format(struct stfcamss_video *video,
++ struct v4l2_format *format)
++{
++ struct v4l2_pix_format *pix = &video->active_fmt.fmt.pix;
++ struct v4l2_pix_format_mplane *pix_mp =
++ &video->active_fmt.fmt.pix_mp;
++ struct v4l2_subdev_format fmt;
++ struct v4l2_subdev *subdev;
++ u32 pixelformat;
++ u32 pad;
++ int ret;
++
++ subdev = video_remote_subdev(video, &pad);
++ if (subdev == NULL)
++ return -EPIPE;
++
++ fmt.pad = pad;
++ fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
++
++ ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &fmt);
++ if (ret)
++ return ret;
++
++ if (video->is_mp)
++ pixelformat = pix_mp->pixelformat;
++ else
++ pixelformat = pix->pixelformat;
++ ret = video_find_format(fmt.format.code, pixelformat,
++ video->formats, video->nformats);
++ if (ret < 0)
++ return ret;
++
++ format->type = video->type;
++
++ if (video->is_mp)
++ return video_mbus_to_pix_mp(&fmt.format, &format->fmt.pix_mp,
++ &video->formats[ret], video->bpl_alignment);
++ else
++ return video_mbus_to_pix(&fmt.format, &format->fmt.pix,
++ &video->formats[ret], video->bpl_alignment);
++}
++
++static int video_check_format(struct stfcamss_video *video)
++{
++ struct v4l2_pix_format *pix = &video->active_fmt.fmt.pix;
++ struct v4l2_pix_format_mplane *pix_mp =
++ &video->active_fmt.fmt.pix_mp;
++ struct v4l2_format format;
++ struct v4l2_pix_format *sd_pix = &format.fmt.pix;
++ struct v4l2_pix_format_mplane *sd_pix_mp = &format.fmt.pix_mp;
++ int ret;
++
++ if (video->is_mp) {
++ sd_pix_mp->pixelformat = pix_mp->pixelformat;
++ ret = video_get_subdev_format(video, &format);
++ if (ret < 0)
++ return ret;
++
++ if (pix_mp->pixelformat != sd_pix_mp->pixelformat ||
++ pix_mp->height > sd_pix_mp->height ||
++ pix_mp->width > sd_pix_mp->width ||
++ pix_mp->num_planes != sd_pix_mp->num_planes ||
++ pix_mp->field != format.fmt.pix_mp.field) {
++ st_err(ST_VIDEO,
++ "%s, not match:\n"
++ "0x%x 0x%x\n0x%x 0x%x\n0x%x 0x%x\n",
++ __func__,
++ pix_mp->pixelformat, sd_pix_mp->pixelformat,
++ pix_mp->height, sd_pix_mp->height,
++ pix_mp->field, format.fmt.pix_mp.field);
++ return -EPIPE;
++ }
++
++ } else {
++ sd_pix->pixelformat = pix->pixelformat;
++ ret = video_get_subdev_format(video, &format);
++ if (ret < 0)
++ return ret;
++
++ if (pix->pixelformat != sd_pix->pixelformat ||
++ pix->height > sd_pix->height ||
++ pix->width > sd_pix->width ||
++ pix->field != format.fmt.pix.field) {
++ st_err(ST_VIDEO,
++ "%s, not match:\n"
++ "0x%x 0x%x\n0x%x 0x%x\n0x%x 0x%x\n",
++ __func__,
++ pix->pixelformat, sd_pix->pixelformat,
++ pix->height, sd_pix->height,
++ pix->field, format.fmt.pix.field);
++ return -EPIPE;
++ }
++ }
++ return 0;
++}
++
++static int video_start_streaming(struct vb2_queue *q, unsigned int count)
++{
++ struct stfcamss_video *video = vb2_get_drv_priv(q);
++ struct video_device *vdev = &video->vdev;
++ struct media_entity *entity;
++ struct media_pad *pad;
++ struct v4l2_subdev *subdev;
++ int ret;
++
++ ret = video_device_pipeline_start(vdev, &video->stfcamss->pipe);
++ if (ret < 0) {
++ st_err(ST_VIDEO,
++ "Failed to video_device_pipeline_start: %d\n", ret);
++ return ret;
++ }
++
++ ret = video_check_format(video);
++ if (ret < 0)
++ goto error;
++ entity = &vdev->entity;
++ while (1) {
++ pad = &entity->pads[0];
++ if (!(pad->flags & MEDIA_PAD_FL_SINK))
++ break;
++
++ pad = media_pad_remote_pad_first(pad);
++ if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
++ break;
++
++ entity = pad->entity;
++ subdev = media_entity_to_v4l2_subdev(entity);
++
++ ret = v4l2_subdev_call(subdev, video, s_stream, 1);
++ if (ret < 0 && ret != -ENOIOCTLCMD)
++ goto error;
++ }
++ return 0;
++
++error:
++ video_device_pipeline_stop(vdev);
++ video->ops->flush_buffers(video, VB2_BUF_STATE_QUEUED);
++ return ret;
++}
++
++static void video_stop_streaming(struct vb2_queue *q)
++{
++ struct stfcamss_video *video = vb2_get_drv_priv(q);
++ struct video_device *vdev = &video->vdev;
++ struct media_entity *entity;
++ struct media_pad *pad;
++ struct v4l2_subdev *subdev;
++
++ entity = &vdev->entity;
++ while (1) {
++ pad = &entity->pads[0];
++ if (!(pad->flags & MEDIA_PAD_FL_SINK))
++ break;
++
++ pad = media_pad_remote_pad_first(pad);
++ if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
++ break;
++
++ entity = pad->entity;
++ subdev = media_entity_to_v4l2_subdev(entity);
++
++ v4l2_subdev_call(subdev, video, s_stream, 0);
++ }
++
++ video_device_pipeline_stop(vdev);
++ video->ops->flush_buffers(video, VB2_BUF_STATE_ERROR);
++}
++
++static const struct vb2_ops stf_video_vb2_q_ops = {
++ .queue_setup = video_queue_setup,
++ .wait_prepare = vb2_ops_wait_prepare,
++ .wait_finish = vb2_ops_wait_finish,
++ .buf_init = video_buf_init,
++ .buf_prepare = video_buf_prepare,
++ .buf_queue = video_buf_queue,
++ .start_streaming = video_start_streaming,
++ .stop_streaming = video_stop_streaming,
++};
++
++/* -----------------------------------------------------
++ * V4L2 ioctls
++ */
++
++static int getcrop_pad_id(int video_id)
++{
++ return stf_vin_map_isp_pad(video_id, STF_ISP_PAD_SRC);
++}
++
++static int video_querycap(struct file *file, void *fh,
++ struct v4l2_capability *cap)
++{
++ struct stfcamss_video *video = video_drvdata(file);
++
++ strscpy(cap->driver, "stf camss", sizeof(cap->driver));
++ strscpy(cap->card, "Starfive Camera Subsystem", sizeof(cap->card));
++ snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
++ dev_name(video->stfcamss->dev));
++ return 0;
++}
++
++static int video_get_unique_pixelformat_by_index(struct stfcamss_video *video,
++ int ndx)
++{
++ int i, j, k;
++
++ /* find index "i" of "k"th unique pixelformat in formats array */
++ k = -1;
++ for (i = 0; i < video->nformats; i++) {
++ for (j = 0; j < i; j++) {
++ if (video->formats[i].pixelformat ==
++ video->formats[j].pixelformat)
++ break;
++ }
++
++ if (j == i)
++ k++;
++
++ if (k == ndx)
++ return i;
++ }
++
++ return -EINVAL;
++}
++
++static int video_get_pixelformat_by_mbus_code(struct stfcamss_video *video,
++ u32 mcode)
++{
++ int i;
++
++ for (i = 0; i < video->nformats; i++) {
++ if (video->formats[i].code == mcode)
++ return i;
++ }
++
++ return -EINVAL;
++}
++
++static int video_enum_fmt(struct file *file, void *fh, struct v4l2_fmtdesc *f)
++{
++ struct stfcamss_video *video = video_drvdata(file);
++ int i;
++
++ st_debug(ST_VIDEO, "%s:\n0x%x 0x%x\n 0x%x, 0x%x\n0x%x\n",
++ __func__,
++ f->type, video->type,
++ f->index, video->nformats,
++ f->mbus_code);
++
++ if (f->type != video->type)
++ return -EINVAL;
++ if (f->index >= video->nformats)
++ return -EINVAL;
++
++ if (f->mbus_code) {
++ /* Each entry in formats[] table has unique mbus_code */
++ if (f->index > 0)
++ return -EINVAL;
++
++ i = video_get_pixelformat_by_mbus_code(video, f->mbus_code);
++ } else {
++ i = video_get_unique_pixelformat_by_index(video, f->index);
++ }
++
++ if (i < 0)
++ return -EINVAL;
++
++ f->pixelformat = video->formats[i].pixelformat;
++
++ return 0;
++}
++
++static int video_enum_framesizes(struct file *file, void *fh,
++ struct v4l2_frmsizeenum *fsize)
++{
++ struct v4l2_subdev_frame_size_enum fse = {0};
++ struct v4l2_subdev_mbus_code_enum code = {0};
++ struct stfcamss_video *video = video_drvdata(file);
++ struct video_device *vdev = &video->vdev;
++ struct media_entity *entity = &vdev->entity;
++ struct media_entity *sensor;
++ struct v4l2_subdev *subdev;
++ struct media_pad *pad;
++ bool support_selection = false;
++ int i;
++ int ret;
++
++ for (i = 0; i < video->nformats; i++) {
++ if (video->formats[i].pixelformat == fsize->pixel_format)
++ break;
++ }
++
++ if (i == video->nformats)
++ return -EINVAL;
++
++ entity = &vdev->entity;
++ while (1) {
++ pad = &entity->pads[0];
++ if (!(pad->flags & MEDIA_PAD_FL_SINK))
++ break;
++
++ pad = media_pad_remote_pad_first(pad);
++ if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
++ break;
++
++ entity = pad->entity;
++ subdev = media_entity_to_v4l2_subdev(entity);
++
++ if (subdev->ops->pad->set_selection) {
++ support_selection = true;
++ break;
++ }
++ }
++
++ if (support_selection) {
++ if (fsize->index)
++ return -EINVAL;
++ fsize->type = V4L2_FRMSIZE_TYPE_CONTINUOUS;
++ fsize->stepwise.min_width = STFCAMSS_FRAME_MIN_WIDTH;
++ fsize->stepwise.max_width = STFCAMSS_FRAME_MAX_WIDTH;
++ fsize->stepwise.min_height = STFCAMSS_FRAME_MIN_HEIGHT;
++ fsize->stepwise.max_height = STFCAMSS_FRAME_MAX_HEIGHT;
++ fsize->stepwise.step_width = 1;
++ fsize->stepwise.step_height = 1;
++ } else {
++ entity = &vdev->entity;
++ sensor = stfcamss_find_sensor(entity);
++ if (!sensor)
++ return -ENOTTY;
++
++ subdev = media_entity_to_v4l2_subdev(sensor);
++ code.index = 0;
++ code.which = V4L2_SUBDEV_FORMAT_ACTIVE;
++ ret = v4l2_subdev_call(subdev, pad, enum_mbus_code, NULL, &code);
++ if (ret < 0)
++ return -EINVAL;
++ fse.index = fsize->index;
++ fse.code = code.code;
++ fse.which = V4L2_SUBDEV_FORMAT_ACTIVE;
++ ret = v4l2_subdev_call(subdev, pad, enum_frame_size, NULL, &fse);
++ if (ret < 0)
++ return -EINVAL;
++ fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
++ fsize->discrete.width = fse.min_width;
++ fsize->discrete.height = fse.min_height;
++ }
++
++ return 0;
++}
++
++static int video_enum_frameintervals(struct file *file, void *fh,
++ struct v4l2_frmivalenum *fival)
++{
++ int ret = 0;
++ struct stfcamss_video *video = video_drvdata(file);
++ struct video_device *vdev = &video->vdev;
++ struct media_entity *entity = &vdev->entity;
++ struct media_entity *sensor;
++ struct v4l2_subdev *subdev;
++ struct v4l2_subdev_mbus_code_enum code = {0};
++ struct v4l2_subdev_frame_interval_enum fie = {0};
++
++ sensor = stfcamss_find_sensor(entity);
++ if (!sensor)
++ return -ENOTTY;
++ fie.index = fival->index;
++ fie.width = fival->width;
++ fie.height = fival->height;
++ fie.which = V4L2_SUBDEV_FORMAT_ACTIVE;
++ subdev = media_entity_to_v4l2_subdev(sensor);
++
++ code.index = 0;
++ code.which = V4L2_SUBDEV_FORMAT_ACTIVE;
++
++ /* Don't care about the code, just find by pixelformat */
++ ret = video_find_format(0, fival->pixel_format,
++ video->formats, video->nformats);
++ if (ret < 0)
++ return -EINVAL;
++
++ ret = v4l2_subdev_call(subdev, pad, enum_mbus_code, NULL, &code);
++ if (ret < 0)
++ return -EINVAL;
++
++ fie.code = code.code;
++ ret = v4l2_subdev_call(subdev, pad, enum_frame_interval, NULL, &fie);
++ if (ret < 0)
++ return ret;
++
++ fival->type = V4L2_FRMSIZE_TYPE_DISCRETE;
++ fival->discrete = fie.interval;
++
++ return 0;
++}
++
++static int video_g_fmt(struct file *file, void *fh, struct v4l2_format *f)
++{
++ struct stfcamss_video *video = video_drvdata(file);
++
++ st_debug(ST_VIDEO, "%s, fmt.type = 0x%x\n", __func__, f->type);
++ st_debug(ST_VIDEO, "%s, active_fmt.type = 0x%x,0x%x\n",
++ __func__, video->active_fmt.type,
++ video->active_fmt.fmt.pix.pixelformat);
++ *f = video->active_fmt;
++ return 0;
++}
++
++static int video_g_fmt_mp(struct file *file, void *fh, struct v4l2_format *f)
++{
++ struct stfcamss_video *video = video_drvdata(file);
++
++ st_debug(ST_VIDEO, "%s, fmt.type = 0x%x\n", __func__, f->type);
++ st_debug(ST_VIDEO, "%s, active_fmt.type = 0x%x\n",
++ __func__, video->active_fmt.type);
++ *f = video->active_fmt;
++ return 0;
++}
++
++static int video_entity_s_fmt(struct stfcamss_video *video,
++ struct media_entity *entity,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_format *fmt)
++{
++ struct v4l2_subdev *subdev;
++ struct media_pad *pad;
++ struct v4l2_mbus_framefmt *mf = &fmt->format;
++ struct v4l2_subdev_format fmt_src = {
++ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
++ };
++ u32 width, height, code;
++ int ret, index = 0;
++
++ code = mf->code;
++ width = mf->width;
++ height = mf->height;
++ subdev = media_entity_to_v4l2_subdev(entity);
++ while (1) {
++ if (index >= entity->num_pads)
++ break;
++ pad = &entity->pads[index];
++ pad = media_pad_remote_pad_first(pad);
++ if (pad && is_media_entity_v4l2_subdev(pad->entity)) {
++ fmt->pad = index;
++ ret = v4l2_subdev_call(subdev, pad, set_fmt, state, fmt);
++ if (mf->code != code ||
++ mf->width != width || mf->height != height) {
++ st_warn(ST_VIDEO,
++ "\"%s\":%d pad fmt has been"
++ " changed to 0x%x %ux%u\n",
++ subdev->name, fmt->pad, mf->code,
++ mf->width, mf->height);
++ }
++ if (index) {
++ fmt_src.pad = index;
++ ret = v4l2_subdev_call(subdev, pad, get_fmt, state, &fmt_src);
++ if (ret)
++ return ret;
++
++ fmt->format.code = fmt_src.format.code;
++ ret = video_entity_s_fmt(video, pad->entity, state, fmt);
++ }
++ }
++
++ if (ret < 0 && ret != -ENOIOCTLCMD)
++ break;
++ index++;
++ }
++ return ret;
++}
++
++static int video_pipeline_s_fmt(struct stfcamss_video *video,
++ struct v4l2_subdev_state *state,
++ struct v4l2_format *f)
++{
++ struct video_device *vdev = &video->vdev;
++ struct media_entity *entity = &vdev->entity;
++ struct v4l2_subdev *subdev;
++ int ret, index;
++ struct v4l2_subdev_format fmt = {
++ .pad = 0,
++ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
++ .reserved = {getcrop_pad_id(video->id)}
++ };
++ struct v4l2_mbus_framefmt *mf = &fmt.format;
++ struct v4l2_pix_format *pix = &f->fmt.pix;
++ struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
++ struct media_entity *sensor;
++ u32 width, height;
++ struct media_pad *pad;
++
++ /* pix to mbus format */
++ if (video->is_mp) {
++ index = video_find_format(mf->code,
++ pix_mp->pixelformat,
++ video->formats, video->nformats);
++ if (index < 0)
++ return index;
++ v4l2_fill_mbus_format_mplane(mf, pix_mp);
++ mf->code = video->formats[index].code;
++ } else {
++ index = video_find_format(mf->code,
++ pix->pixelformat,
++ video->formats, video->nformats);
++ if (index < 0)
++ return index;
++ v4l2_fill_mbus_format(mf, pix, video->formats[index].code);
++ }
++
++ width = mf->width;
++ height = mf->height;
++
++ sensor = stfcamss_find_sensor(entity);
++ if (!sensor) {
++ st_err(ST_VIDEO, "Can't find sensor\n");
++ return -ENOTTY;
++ }
++
++ subdev = media_entity_to_v4l2_subdev(sensor);
++ ret = v4l2_subdev_call(subdev, pad, get_fmt, state, &fmt);
++ if (ret)
++ return ret;
++
++ /*
++ * Starting from sensor subdevice, walk within
++ * pipeline and set format on each subdevice
++ */
++ pad = media_pad_remote_pad_first(&sensor->pads[0]);
++ ret = video_entity_s_fmt(video, pad->entity, state, &fmt);
++ if (ret < 0 && ret != -ENOIOCTLCMD)
++ return ret;
++
++ index = video_find_format(mf->code,
++ video->formats[index].pixelformat,
++ video->formats, video->nformats);
++ st_debug(ST_VIDEO, "%s, code=%x, index=%d\n",
++ __func__, mf->code, index);
++
++ if (index < 0)
++ return index;
++
++ if (video->is_mp)
++ video_mbus_to_pix_mp(mf, pix_mp,
++ &video->formats[index], video->bpl_alignment);
++ else
++ video_mbus_to_pix(mf, pix,
++ &video->formats[index], video->bpl_alignment);
++
++ ret = __video_try_fmt(video, f, video->is_mp);
++ if (ret < 0)
++ return ret;
++
++ return 0;
++}
++
++static int video_s_fmt(struct file *file, void *fh, struct v4l2_format *f)
++{
++ struct stfcamss_video *video = video_drvdata(file);
++ int ret;
++
++ st_debug(ST_VIDEO, "%s, fmt.type = 0x%x, v4l2fmt=%x\n",
++ __func__, f->type, f->fmt.pix.pixelformat);
++
++ if (vb2_is_busy(&video->vb2_q))
++ return -EBUSY;
++
++ ret = __video_try_fmt(video, f, false);
++ if (ret < 0)
++ return ret;
++
++ ret = video_pipeline_s_fmt(video, NULL, f);
++
++ st_debug(ST_VIDEO, "%s, pixelformat=0x%x, ret=%d\n",
++ __func__, f->fmt.pix.pixelformat, ret);
++ if (ret < 0)
++ return ret;
++
++ video->active_fmt = *f;
++
++ return 0;
++}
++
++static int video_s_fmt_mp(struct file *file, void *fh, struct v4l2_format *f)
++{
++ struct stfcamss_video *video = video_drvdata(file);
++ int ret;
++
++ st_debug(ST_VIDEO, "%s, fmt.type = 0x%x\n", __func__, f->type);
++ if (vb2_is_busy(&video->vb2_q))
++ return -EBUSY;
++
++ ret = __video_try_fmt(video, f, true);
++ if (ret < 0)
++ return ret;
++
++ ret = video_pipeline_s_fmt(video, NULL, f);
++ if (ret < 0)
++ return ret;
++
++ video->active_fmt = *f;
++
++ return 0;
++}
++
++static int video_try_fmt(struct file *file,
++ void *fh, struct v4l2_format *f)
++{
++ struct stfcamss_video *video = video_drvdata(file);
++
++ return __video_try_fmt(video, f, false);
++}
++
++static int video_try_fmt_mp(struct file *file,
++ void *fh, struct v4l2_format *f)
++{
++ struct stfcamss_video *video = video_drvdata(file);
++
++ return __video_try_fmt(video, f, true);
++}
++
++static int video_enum_input(struct file *file, void *fh,
++ struct v4l2_input *input)
++{
++ if (input->index > 0)
++ return -EINVAL;
++
++ strscpy(input->name, "camera", sizeof(input->name));
++ input->type = V4L2_INPUT_TYPE_CAMERA;
++
++ return 0;
++}
++
++static int video_g_input(struct file *file, void *fh, unsigned int *input)
++{
++ *input = 0;
++
++ return 0;
++}
++
++static int video_s_input(struct file *file, void *fh, unsigned int input)
++{
++ return input == 0 ? 0 : -EINVAL;
++}
++
++static int video_g_parm(struct file *file, void *priv,
++ struct v4l2_streamparm *p)
++{
++ struct stfcamss_video *video = video_drvdata(file);
++ struct video_device *vdev = &video->vdev;
++ struct media_entity *entity;
++ struct v4l2_subdev *subdev;
++ struct media_pad *pad;
++ int ret, is_support = 0;
++
++ entity = &vdev->entity;
++ while (1) {
++ pad = &entity->pads[0];
++ if (!(pad->flags & MEDIA_PAD_FL_SINK))
++ break;
++
++ pad = media_pad_remote_pad_first(pad);
++ if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
++ break;
++
++ entity = pad->entity;
++ subdev = media_entity_to_v4l2_subdev(entity);
++
++ ret = v4l2_g_parm_cap(vdev, subdev, p);
++ if (ret < 0 && ret != -ENOIOCTLCMD)
++ break;
++ if (!ret)
++ is_support = 1;
++ }
++
++ return is_support ? 0 : ret;
++}
++
++static int video_s_parm(struct file *file, void *priv,
++ struct v4l2_streamparm *p)
++{
++ struct stfcamss_video *video = video_drvdata(file);
++ struct video_device *vdev = &video->vdev;
++ struct media_entity *entity;
++ struct v4l2_subdev *subdev;
++ struct media_pad *pad;
++ struct v4l2_streamparm tmp_p;
++ int ret, is_support = 0;
++
++ entity = &vdev->entity;
++ while (1) {
++ pad = &entity->pads[0];
++ if (!(pad->flags & MEDIA_PAD_FL_SINK))
++ break;
++
++ pad = media_pad_remote_pad_first(pad);
++ if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
++ break;
++
++ entity = pad->entity;
++ subdev = media_entity_to_v4l2_subdev(entity);
++
++ tmp_p = *p;
++ ret = v4l2_s_parm_cap(vdev, subdev, &tmp_p);
++ if (ret < 0 && ret != -ENOIOCTLCMD)
++ break;
++ if (!ret) {
++ is_support = 1;
++ *p = tmp_p;
++ }
++ }
++
++ return is_support ? 0 : ret;
++}
++
++/* Crop ioctls */
++int video_g_pixelaspect(struct file *file, void *fh,
++ int buf_type, struct v4l2_fract *aspect)
++{
++ return 0;
++}
++
++int video_g_selection(struct file *file, void *fh,
++ struct v4l2_selection *s)
++{
++ struct stfcamss_video *video = video_drvdata(file);
++ struct video_device *vdev = &video->vdev;
++ struct media_entity *entity;
++ struct v4l2_subdev *subdev;
++ struct media_pad *pad;
++ struct v4l2_subdev_selection sel = {
++ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
++ .pad = getcrop_pad_id(video->id),
++ .target = s->target,
++ .r = s->r,
++ .flags = s->flags,
++ };
++ int ret;
++
++ st_debug(ST_VIDEO, "%s, target = 0x%x, 0x%x\n",
++ __func__, sel.target, s->target);
++ if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE
++ && s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
++ return -EINVAL;
++
++ entity = &vdev->entity;
++ while (1) {
++ pad = &entity->pads[0];
++ if (!(pad->flags & MEDIA_PAD_FL_SINK))
++ break;
++
++ pad = media_pad_remote_pad_first(pad);
++ if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
++ break;
++
++ entity = pad->entity;
++ subdev = media_entity_to_v4l2_subdev(entity);
++
++ ret = v4l2_subdev_call(subdev, pad, get_selection, NULL, &sel);
++ if (!ret) {
++ s->r = sel.r;
++ s->flags = sel.flags;
++ break;
++ }
++ if (ret != -ENOIOCTLCMD)
++ break;
++ }
++
++ return ret;
++}
++
++int video_s_selection(struct file *file, void *fh,
++ struct v4l2_selection *s)
++{
++ struct stfcamss_video *video = video_drvdata(file);
++ struct video_device *vdev = &video->vdev;
++ struct media_entity *entity;
++ struct v4l2_subdev *subdev;
++ struct media_pad *pad;
++ struct v4l2_subdev_selection sel = {
++ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
++ .pad = getcrop_pad_id(video->id),
++ .target = s->target,
++ .r = s->r,
++ .flags = s->flags,
++ };
++ struct v4l2_pix_format *format = &video->active_fmt.fmt.pix;
++ struct v4l2_pix_format_mplane *format_mp =
++ &video->active_fmt.fmt.pix_mp;
++ int ret;
++
++ st_debug(ST_VIDEO, "%s, target = 0x%x, 0x%x\n",
++ __func__, sel.target, s->target);
++ if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE
++ && s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
++ return -EINVAL;
++
++ entity = &vdev->entity;
++ while (1) {
++ pad = &entity->pads[0];
++ if (!(pad->flags & MEDIA_PAD_FL_SINK))
++ break;
++
++ pad = media_pad_remote_pad_first(pad);
++ if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
++ break;
++
++ entity = pad->entity;
++ subdev = media_entity_to_v4l2_subdev(entity);
++
++ ret = v4l2_subdev_call(subdev, pad, set_selection, NULL, &sel);
++ if (!ret) {
++ s->r = sel.r;
++ s->flags = sel.flags;
++ format->width = s->r.width;
++ format->height = s->r.height;
++ format_mp->width = s->r.width;
++ format_mp->height = s->r.height;
++ ret = __video_try_fmt(video, &video->active_fmt,
++ video->is_mp);
++ if (ret < 0)
++ return ret;
++ break;
++ }
++ if (ret != -ENOIOCTLCMD)
++ break;
++ }
++
++ st_debug(ST_VIDEO, "ret = 0x%x, -EINVAL = 0x%x\n", ret, -EINVAL);
++
++ return ret;
++}
++
++static const struct v4l2_ioctl_ops stf_vid_ioctl_ops = {
++ .vidioc_querycap = video_querycap,
++ .vidioc_enum_fmt_vid_cap = video_enum_fmt,
++ .vidioc_enum_framesizes = video_enum_framesizes,
++ .vidioc_enum_frameintervals = video_enum_frameintervals,
++ .vidioc_g_fmt_vid_cap = video_g_fmt,
++ .vidioc_s_fmt_vid_cap = video_s_fmt,
++ .vidioc_try_fmt_vid_cap = video_try_fmt,
++ .vidioc_reqbufs = vb2_ioctl_reqbufs,
++ .vidioc_querybuf = vb2_ioctl_querybuf,
++ .vidioc_qbuf = vb2_ioctl_qbuf,
++ .vidioc_expbuf = vb2_ioctl_expbuf,
++ .vidioc_dqbuf = vb2_ioctl_dqbuf,
++ .vidioc_create_bufs = vb2_ioctl_create_bufs,
++ .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
++ .vidioc_streamon = vb2_ioctl_streamon,
++ .vidioc_streamoff = vb2_ioctl_streamoff,
++ .vidioc_enum_input = video_enum_input,
++ .vidioc_g_input = video_g_input,
++ .vidioc_s_input = video_s_input,
++ .vidioc_g_parm = video_g_parm,
++ .vidioc_s_parm = video_s_parm,
++ .vidioc_s_selection = video_s_selection,
++ .vidioc_g_selection = video_g_selection,
++};
++
++static const struct v4l2_ioctl_ops stf_vid_ioctl_ops_mp = {
++ .vidioc_querycap = video_querycap,
++ .vidioc_enum_fmt_vid_cap = video_enum_fmt,
++ .vidioc_enum_framesizes = video_enum_framesizes,
++ .vidioc_enum_frameintervals = video_enum_frameintervals,
++ .vidioc_g_fmt_vid_cap_mplane = video_g_fmt_mp,
++ .vidioc_s_fmt_vid_cap_mplane = video_s_fmt_mp,
++ .vidioc_try_fmt_vid_cap_mplane = video_try_fmt_mp,
++ .vidioc_reqbufs = vb2_ioctl_reqbufs,
++ .vidioc_querybuf = vb2_ioctl_querybuf,
++ .vidioc_qbuf = vb2_ioctl_qbuf,
++ .vidioc_expbuf = vb2_ioctl_expbuf,
++ .vidioc_dqbuf = vb2_ioctl_dqbuf,
++ .vidioc_create_bufs = vb2_ioctl_create_bufs,
++ .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
++ .vidioc_streamon = vb2_ioctl_streamon,
++ .vidioc_streamoff = vb2_ioctl_streamoff,
++ .vidioc_enum_input = video_enum_input,
++ .vidioc_g_input = video_g_input,
++ .vidioc_s_input = video_s_input,
++ .vidioc_g_parm = video_g_parm,
++ .vidioc_s_parm = video_s_parm,
++ .vidioc_s_selection = video_s_selection,
++ .vidioc_g_selection = video_g_selection,
++};
++
++static const struct v4l2_ioctl_ops stf_vid_ioctl_ops_out = {
++ .vidioc_querycap = video_querycap,
++ .vidioc_enum_fmt_vid_out = video_enum_fmt,
++ .vidioc_enum_framesizes = video_enum_framesizes,
++ .vidioc_enum_frameintervals = video_enum_frameintervals,
++ .vidioc_g_fmt_vid_out = video_g_fmt,
++ .vidioc_s_fmt_vid_out = video_s_fmt,
++ .vidioc_try_fmt_vid_out = video_try_fmt,
++ .vidioc_reqbufs = vb2_ioctl_reqbufs,
++ .vidioc_querybuf = vb2_ioctl_querybuf,
++ .vidioc_qbuf = vb2_ioctl_qbuf,
++ .vidioc_expbuf = vb2_ioctl_expbuf,
++ .vidioc_dqbuf = vb2_ioctl_dqbuf,
++ .vidioc_create_bufs = vb2_ioctl_create_bufs,
++ .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
++ .vidioc_streamon = vb2_ioctl_streamon,
++ .vidioc_streamoff = vb2_ioctl_streamoff,
++};
++
++static int video_open(struct file *file)
++{
++ struct video_device *vdev = video_devdata(file);
++ struct stfcamss_video *video = video_drvdata(file);
++ struct v4l2_fh *vfh;
++ int ret;
++
++ mutex_lock(&video->lock);
++
++ vfh = kzalloc(sizeof(*vfh), GFP_KERNEL);
++ if (vfh == NULL) {
++ ret = -ENOMEM;
++ goto error_alloc;
++ }
++
++ v4l2_fh_init(vfh, vdev);
++ v4l2_fh_add(vfh);
++
++ file->private_data = vfh;
++
++ if (!video->pm_count) {
++ ret = v4l2_pipeline_pm_get(&vdev->entity);
++ if (ret < 0) {
++ st_err(ST_VIDEO,
++ "Failed to power up pipeline: %d\n", ret);
++ goto error_pm_use;
++ }
++ }
++
++ video->pm_count++;
++
++ mutex_unlock(&video->lock);
++
++ return 0;
++
++error_pm_use:
++ v4l2_fh_release(file);
++error_alloc:
++ mutex_unlock(&video->lock);
++ return ret;
++}
++
++static int video_release(struct file *file)
++{
++ struct video_device *vdev = video_devdata(file);
++ struct stfcamss_video *video = video_drvdata(file);
++
++ vb2_fop_release(file);
++
++ video->pm_count--;
++
++ if (!video->pm_count)
++ v4l2_pipeline_pm_put(&vdev->entity);
++
++ file->private_data = NULL;
++
++ return 0;
++}
++
++static const struct v4l2_file_operations stf_vid_fops = {
++ .owner = THIS_MODULE,
++ .unlocked_ioctl = video_ioctl2,
++ .open = video_open,
++ .release = video_release,
++ .poll = vb2_fop_poll,
++ .mmap = vb2_fop_mmap,
++ .read = vb2_fop_read,
++};
++
++static void stf_video_release(struct video_device *vdev)
++{
++ struct stfcamss_video *video = video_get_drvdata(vdev);
++
++ media_entity_cleanup(&vdev->entity);
++
++ mutex_destroy(&video->q_lock);
++ mutex_destroy(&video->lock);
++}
++
++int stf_video_register(struct stfcamss_video *video,
++ struct v4l2_device *v4l2_dev,
++ const char *name, int is_mp)
++{
++ struct video_device *vdev;
++ struct vb2_queue *q;
++ struct media_pad *pad = &video->pad;
++ int ret;
++ enum isp_pad_id isp_pad;
++
++ vdev = &video->vdev;
++
++ mutex_init(&video->q_lock);
++
++ q = &video->vb2_q;
++ q->drv_priv = video;
++ q->mem_ops = &vb2_dma_contig_memops;
++ q->ops = &stf_video_vb2_q_ops;
++ //q->type = is_mp ? V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE :
++ // V4L2_BUF_TYPE_VIDEO_CAPTURE;
++ q->type = video->type;
++ q->io_modes = VB2_DMABUF | VB2_MMAP | VB2_READ;
++ q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
++ q->buf_struct_size = sizeof(struct stfcamss_buffer);
++ q->dev = video->stfcamss->dev;
++ q->lock = &video->q_lock;
++ q->min_buffers_needed = STFCAMSS_MIN_BUFFERS;
++ ret = vb2_queue_init(q);
++ if (ret < 0) {
++ st_err(ST_VIDEO,
++ "Failed to init vb2 queue: %d\n", ret);
++ goto err_vb2_init;
++ }
++
++ pad->flags = MEDIA_PAD_FL_SINK;
++ ret = media_entity_pads_init(&vdev->entity, 1, pad);
++ if (ret < 0) {
++ st_err(ST_VIDEO,
++ "Failed to init video entity: %d\n",
++ ret);
++ goto err_vb2_init;
++ }
++
++ mutex_init(&video->lock);
++
++ isp_pad = stf_vin_map_isp_pad(video->id, STF_ISP_PAD_SRC);
++ if (video->id == VIN_LINE_WR) {
++ video->formats = formats_pix_st7110_wr;
++ video->nformats = ARRAY_SIZE(formats_pix_st7110_wr);
++ video->bpl_alignment = STFCAMSS_FRAME_WIDTH_ALIGN_8;
++ } else if (isp_pad == STF_ISP_PAD_SRC
++ || isp_pad == STF_ISP_PAD_SRC_SS0
++ || isp_pad == STF_ISP_PAD_SRC_SS1) {
++ video->formats = formats_pix_st7110_isp;
++ video->nformats = ARRAY_SIZE(formats_pix_st7110_isp);
++ video->bpl_alignment = STFCAMSS_FRAME_WIDTH_ALIGN_8;
++ } else if (isp_pad == STF_ISP_PAD_SRC_ITIW
++ || isp_pad == STF_ISP_PAD_SRC_ITIR) {
++ video->formats = formats_st7110_isp_iti;
++ video->nformats = ARRAY_SIZE(formats_st7110_isp_iti);
++ video->bpl_alignment = STFCAMSS_FRAME_WIDTH_ALIGN_8;
++ } else { // raw/scdump/yhist
++ video->formats = formats_raw_st7110_isp;
++ video->nformats = ARRAY_SIZE(formats_raw_st7110_isp);
++ video->bpl_alignment = STFCAMSS_FRAME_WIDTH_ALIGN_128;
++ }
++ video->is_mp = is_mp;
++
++ ret = stf_video_init_format(video, is_mp);
++ if (ret < 0) {
++ st_err(ST_VIDEO, "Failed to init format: %d\n", ret);
++ goto err_vid_init_format;
++ }
++
++ vdev->fops = &stf_vid_fops;
++ if (isp_pad == STF_ISP_PAD_SRC_ITIR) {
++ vdev->device_caps = V4L2_CAP_VIDEO_OUTPUT;
++ vdev->vfl_dir = VFL_DIR_TX;
++ } else {
++ vdev->device_caps = is_mp ? V4L2_CAP_VIDEO_CAPTURE_MPLANE :
++ V4L2_CAP_VIDEO_CAPTURE;
++ vdev->vfl_dir = VFL_DIR_RX;
++ }
++ vdev->device_caps |= V4L2_CAP_STREAMING | V4L2_CAP_READWRITE | V4L2_CAP_IO_MC;
++ if (video->type == V4L2_CAP_VIDEO_OUTPUT)
++ vdev->ioctl_ops = &stf_vid_ioctl_ops_out;
++ else
++ vdev->ioctl_ops = is_mp ? &stf_vid_ioctl_ops_mp : &stf_vid_ioctl_ops;
++ vdev->release = stf_video_release;
++ vdev->v4l2_dev = v4l2_dev;
++ vdev->queue = &video->vb2_q;
++ vdev->lock = &video->lock;
++ //strlcpy(vdev->name, name, sizeof(vdev->name));
++ strscpy(vdev->name, name, sizeof(vdev->name));
++
++ ret = video_register_device(vdev, VFL_TYPE_VIDEO, video->id);
++ if (ret < 0) {
++ st_err(ST_VIDEO,
++ "Failed to register video device: %d\n",
++ ret);
++ goto err_vid_reg;
++ }
++
++ video_set_drvdata(vdev, video);
++ return 0;
++
++err_vid_reg:
++err_vid_init_format:
++ media_entity_cleanup(&vdev->entity);
++ mutex_destroy(&video->lock);
++err_vb2_init:
++ mutex_destroy(&video->q_lock);
++ return ret;
++}
++
++void stf_video_unregister(struct stfcamss_video *video)
++{
++ vb2_video_unregister_device(&video->vdev);
++}
+--- /dev/null
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_video.h
+@@ -0,0 +1,83 @@
++/* SPDX-License-Identifier: GPL-2.0
++ *
++ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
++ *
++ */
++
++#ifndef STF_VIDEO_H
++#define STF_VIDEO_H
++
++#include <linux/mutex.h>
++#include <media/videobuf2-v4l2.h>
++#include <linux/videodev2.h>
++#include <media/v4l2-dev.h>
++#include <media/v4l2-device.h>
++#include <media/v4l2-fh.h>
++#include <media/v4l2-ioctl.h>
++
++#define STFCAMSS_FRAME_MIN_WIDTH 64
++#define STFCAMSS_FRAME_MAX_WIDTH 1920
++#define STFCAMSS_FRAME_MIN_HEIGHT 64
++#define STFCAMSS_FRAME_MAX_HEIGHT 1080
++#define STFCAMSS_FRAME_WIDTH_ALIGN_8 8
++#define STFCAMSS_FRAME_WIDTH_ALIGN_128 128
++#define STFCAMSS_MIN_BUFFERS 2
++
++#define STFCAMSS_MAX_ENTITY_NAME_LEN 27
++
++struct stfcamss_buffer {
++ struct vb2_v4l2_buffer vb;
++ dma_addr_t addr[3];
++ void *vaddr_sc; /* Use for isp sc data */
++ struct list_head queue;
++ int sizeimage;
++};
++
++struct stfcamss_video;
++
++struct stfcamss_video_ops {
++ int (*queue_buffer)(struct stfcamss_video *vid,
++ struct stfcamss_buffer *buf);
++ int (*flush_buffers)(struct stfcamss_video *vid,
++ enum vb2_buffer_state state);
++};
++
++struct fract {
++ u8 numerator;
++ u8 denominator;
++};
++
++struct stfcamss_format_info {
++ u32 code;
++ u32 pixelformat;
++ u8 planes;
++ struct fract hsub[3];
++ struct fract vsub[3];
++ u8 bpp[3];
++};
++
++struct stfcamss_video {
++ struct stfcamss *stfcamss;
++ u8 id;
++ struct vb2_queue vb2_q;
++ struct video_device vdev;
++ struct media_pad pad;
++ struct media_pipeline pipe;
++ struct v4l2_format active_fmt;
++ enum v4l2_buf_type type;
++ const struct stfcamss_video_ops *ops;
++ struct mutex lock;
++ struct mutex q_lock;
++ unsigned int bpl_alignment;
++ const struct stfcamss_format_info *formats;
++ unsigned int nformats;
++ unsigned int is_mp;
++ unsigned int pm_count;
++};
++
++int stf_video_register(struct stfcamss_video *video,
++ struct v4l2_device *v4l2_dev, const char *name, int is_mp);
++
++void stf_video_unregister(struct stfcamss_video *video);
++
++#endif /* STF_VIDEO_H */
+--- /dev/null
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_vin.c
+@@ -0,0 +1,1515 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
++ *
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/interrupt.h>
++#include <linux/dma-mapping.h>
++#include <linux/pm_runtime.h>
++#include <media/v4l2-event.h>
++
++#include "stfcamss.h"
++
++#define vin_line_array(ptr_line) \
++ ((const struct vin_line (*)[]) &(ptr_line[-(ptr_line->id)]))
++
++#define line_to_vin2_dev(ptr_line) \
++ container_of(vin_line_array(ptr_line), struct stf_vin2_dev, line)
++
++#define VIN_FRAME_DROP_MAX_VAL 90
++#define VIN_FRAME_DROP_MIN_VAL 4
++#define VIN_FRAME_PER_SEC_MAX_VAL 90
++
++/* ISP ctrl need 1 sec to let frames become stable. */
++#define VIN_FRAME_DROP_SEC_FOR_ISP_CTRL 1
++
++
++// #define VIN_TWO_BUFFER
++
++static const struct vin2_format vin2_formats_st7110[] = {
++ { MEDIA_BUS_FMT_YUYV8_2X8, 16},
++ { MEDIA_BUS_FMT_RGB565_2X8_LE, 16},
++ { MEDIA_BUS_FMT_SRGGB8_1X8, 8},
++ { MEDIA_BUS_FMT_SGRBG8_1X8, 8},
++ { MEDIA_BUS_FMT_SGBRG8_1X8, 8},
++ { MEDIA_BUS_FMT_SBGGR8_1X8, 8},
++ { MEDIA_BUS_FMT_SRGGB10_1X10, 10},
++ { MEDIA_BUS_FMT_SGRBG10_1X10, 10},
++ { MEDIA_BUS_FMT_SGBRG10_1X10, 10},
++ { MEDIA_BUS_FMT_SBGGR10_1X10, 10},
++ { MEDIA_BUS_FMT_SRGGB12_1X12, 12},
++ { MEDIA_BUS_FMT_SGRBG12_1X12, 12},
++ { MEDIA_BUS_FMT_SGBRG12_1X12, 12},
++ { MEDIA_BUS_FMT_SBGGR12_1X12, 12},
++ { MEDIA_BUS_FMT_Y12_1X12, 8},
++ { MEDIA_BUS_FMT_YUV8_1X24, 8},
++ { MEDIA_BUS_FMT_AYUV8_1X32, 32},
++};
++
++static const struct vin2_format isp_formats_st7110_raw[] = {
++ { MEDIA_BUS_FMT_SBGGR12_1X12, 12},
++ { MEDIA_BUS_FMT_SRGGB12_1X12, 12},
++ { MEDIA_BUS_FMT_SGRBG12_1X12, 12},
++ { MEDIA_BUS_FMT_SGBRG12_1X12, 12},
++};
++
++static const struct vin2_format isp_formats_st7110_uo[] = {
++ { MEDIA_BUS_FMT_Y12_1X12, 8},
++};
++
++static const struct vin2_format isp_formats_st7110_iti[] = {
++ { MEDIA_BUS_FMT_SRGGB10_1X10, 10},
++ { MEDIA_BUS_FMT_SGRBG10_1X10, 10},
++ { MEDIA_BUS_FMT_SGBRG10_1X10, 10},
++ { MEDIA_BUS_FMT_SBGGR10_1X10, 10},
++ { MEDIA_BUS_FMT_SRGGB12_1X12, 12},
++ { MEDIA_BUS_FMT_SGRBG12_1X12, 12},
++ { MEDIA_BUS_FMT_SGBRG12_1X12, 12},
++ { MEDIA_BUS_FMT_SBGGR12_1X12, 12},
++ { MEDIA_BUS_FMT_Y12_1X12, 8},
++ { MEDIA_BUS_FMT_YUV8_1X24, 8},
++};
++
++static const struct vin2_format_table vin2_formats_table[] = {
++ /* VIN_LINE_WR */
++ { vin2_formats_st7110, ARRAY_SIZE(vin2_formats_st7110) },
++ /* VIN_LINE_ISP */
++ { isp_formats_st7110_uo, ARRAY_SIZE(isp_formats_st7110_uo) },
++ /* VIN_LINE_ISP_SS0 */
++ { isp_formats_st7110_uo, ARRAY_SIZE(isp_formats_st7110_uo) },
++ /* VIN_LINE_ISP_SS1 */
++ { isp_formats_st7110_uo, ARRAY_SIZE(isp_formats_st7110_uo) },
++ /* VIN_LINE_ISP_ITIW */
++ { isp_formats_st7110_iti, ARRAY_SIZE(isp_formats_st7110_iti) },
++ /* VIN_LINE_ISP_ITIR */
++ { isp_formats_st7110_iti, ARRAY_SIZE(isp_formats_st7110_iti) },
++ /* VIN_LINE_ISP_RAW */
++ { isp_formats_st7110_raw, ARRAY_SIZE(isp_formats_st7110_raw) },
++ /* VIN_LINE_ISP_SCD_Y */
++ { isp_formats_st7110_raw, ARRAY_SIZE(isp_formats_st7110_raw) },
++};
++
++static void vin_buffer_done(struct vin_line *line, struct vin_params *params);
++static void vin_change_buffer(struct vin_line *line);
++static struct stfcamss_buffer *vin_buf_get_pending(struct vin_output *output);
++static void vin_output_init_addrs(struct vin_line *line);
++static void vin_init_outputs(struct vin_line *line);
++static struct v4l2_mbus_framefmt *
++__vin_get_format(struct vin_line *line,
++ struct v4l2_subdev_state *state,
++ unsigned int pad,
++ enum v4l2_subdev_format_whence which);
++
++static char *get_line_subdevname(int line_id)
++{
++ char *name = NULL;
++
++ switch (line_id) {
++ case VIN_LINE_WR:
++ name = "wr";
++ break;
++ case VIN_LINE_ISP:
++ name = "isp0";
++ break;
++ case VIN_LINE_ISP_SS0:
++ name = "isp0_ss0";
++ break;
++ case VIN_LINE_ISP_SS1:
++ name = "isp0_ss1";
++ break;
++ case VIN_LINE_ISP_ITIW:
++ name = "isp0_itiw";
++ break;
++ case VIN_LINE_ISP_ITIR:
++ name = "isp0_itir";
++ break;
++ case VIN_LINE_ISP_RAW:
++ name = "isp0_raw";
++ break;
++ case VIN_LINE_ISP_SCD_Y:
++ name = "isp0_scd_y";
++ break;
++ default:
++ name = "unknow";
++ break;
++ }
++ return name;
++}
++
++static enum isp_line_id stf_vin_map_isp_line(enum vin_line_id line)
++{
++ enum isp_line_id line_id;
++
++ if ((line > VIN_LINE_WR) && (line < VIN_LINE_MAX)) {
++ line_id = line % STF_ISP_LINE_MAX;
++ if (line_id == 0)
++ line_id = STF_ISP_LINE_SRC_SCD_Y;
++ } else
++ line_id = STF_ISP_LINE_INVALID;
++
++ return line_id;
++}
++
++enum isp_pad_id stf_vin_map_isp_pad(enum vin_line_id line, enum isp_pad_id def)
++{
++ enum isp_pad_id pad_id;
++
++ if (line == VIN_LINE_WR)
++ pad_id = STF_ISP_PAD_SINK;
++ else if ((line > VIN_LINE_WR) && (line < VIN_LINE_MAX))
++ pad_id = stf_vin_map_isp_line(line);
++ else
++ pad_id = def;
++
++ return pad_id;
++}
++
++int stf_vin_subdev_init(struct stfcamss *stfcamss)
++{
++ struct stf_vin_dev *vin;
++ struct device *dev = stfcamss->dev;
++ struct stf_vin2_dev *vin_dev = stfcamss->vin_dev;
++ int i, ret = 0;
++
++ vin_dev->stfcamss = stfcamss;
++ vin_dev->hw_ops = &vin_ops;
++ vin_dev->hw_ops->isr_buffer_done = vin_buffer_done;
++ vin_dev->hw_ops->isr_change_buffer = vin_change_buffer;
++
++ vin = stfcamss->vin;
++ atomic_set(&vin_dev->ref_count, 0);
++
++ ret = devm_request_irq(dev,
++ vin->irq, vin_dev->hw_ops->vin_wr_irq_handler,
++ 0, "vin_axiwr_irq", vin_dev);
++ if (ret) {
++ st_err(ST_VIN, "failed to request irq\n");
++ goto out;
++ }
++
++ ret = devm_request_irq(dev,
++ vin->isp_irq, vin_dev->hw_ops->vin_isp_irq_handler,
++ 0, "vin_isp_irq", vin_dev);
++ if (ret) {
++ st_err(ST_VIN, "failed to request isp irq\n");
++ goto out;
++ }
++
++ st_info(ST_CAMSS, "%s, %d!\n", __func__, __LINE__);
++#ifdef ISP_USE_CSI_AND_SC_DONE_INTERRUPT
++ ret = devm_request_irq(dev,
++ vin->isp_csi_irq, vin_dev->hw_ops->vin_isp_csi_irq_handler,
++ 0, "vin_isp_csi_irq", vin_dev);
++ if (ret) {
++ st_err(ST_VIN, "failed to request isp raw irq\n");
++ goto out;
++ }
++
++ ret = devm_request_irq(dev,
++ vin->isp_scd_irq, vin_dev->hw_ops->vin_isp_scd_irq_handler,
++ 0, "vin_isp_scd_irq", vin_dev);
++ if (ret) {
++ st_err(ST_VIN, "failed to request isp scd irq\n");
++ goto out;
++ }
++#endif
++
++ ret = devm_request_irq(dev,
++ vin->isp_irq_csiline, vin_dev->hw_ops->vin_isp_irq_csiline_handler,
++ 0, "vin_isp_irq_csiline", vin_dev);
++ if (ret) {
++ st_err(ST_VIN, "failed to request isp irq csiline\n");
++ goto out;
++ }
++
++ mutex_init(&vin_dev->power_lock);
++ vin_dev->power_count = 0;
++
++ for (i = 0; i < STF_DUMMY_MODULE_NUMS; i++) {
++ struct dummy_buffer *dummy_buffer = &vin_dev->dummy_buffer[i];
++
++ mutex_init(&dummy_buffer->stream_lock);
++ dummy_buffer->nums = i == 0 ? VIN_DUMMY_BUFFER_NUMS : ISP_DUMMY_BUFFER_NUMS;
++ dummy_buffer->stream_count = 0;
++ dummy_buffer->buffer = devm_kzalloc(dev,
++ dummy_buffer->nums * sizeof(struct vin_dummy_buffer), GFP_KERNEL);
++ atomic_set(&dummy_buffer->frame_skip, 0);
++ }
++
++ for (i = VIN_LINE_WR;
++ i < STF_ISP_LINE_MAX + 1; i++) {
++ struct vin_line *l = &vin_dev->line[i];
++ int is_mp;
++
++ is_mp = i == VIN_LINE_WR ? false : true;
++ is_mp = false;
++ if (stf_vin_map_isp_line(i) == STF_ISP_LINE_SRC_ITIR)
++ l->video_out.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
++ else
++ l->video_out.type = is_mp ? V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE :
++ V4L2_BUF_TYPE_VIDEO_CAPTURE;
++ l->video_out.stfcamss = stfcamss;
++ l->id = i;
++ l->sdev_type = VIN_DEV_TYPE;
++ l->formats = vin2_formats_table[i].fmts;
++ l->nformats = vin2_formats_table[i].nfmts;
++ spin_lock_init(&l->output_lock);
++
++ mutex_init(&l->stream_lock);
++ l->stream_count = 0;
++ mutex_init(&l->power_lock);
++ l->power_count = 0;
++ }
++
++ return 0;
++out:
++ return ret;
++}
++
++static int vin_set_power(struct v4l2_subdev *sd, int on)
++{
++ struct vin_line *line = v4l2_get_subdevdata(sd);
++ struct stf_vin2_dev *vin_dev = line_to_vin2_dev(line);
++ struct stfcamss *stfcamss = vin_dev->stfcamss;
++
++ mutex_lock(&line->power_lock);
++ if (on) {
++ if (line->power_count == 0)
++ vin_init_outputs(line);
++ line->power_count++;
++ } else {
++ if (line->power_count == 0) {
++ st_err(ST_VIN,
++ "line power off on power_count == 0\n");
++ goto exit_line;
++ }
++ line->power_count--;
++ }
++exit_line:
++ mutex_unlock(&line->power_lock);
++
++ mutex_lock(&vin_dev->power_lock);
++ if (on) {
++ if (vin_dev->power_count == 0) {
++ pm_runtime_get_sync(stfcamss->dev);
++ vin_dev->hw_ops->vin_clk_enable(vin_dev);
++ vin_dev->hw_ops->vin_config_set(vin_dev);
++ }
++ vin_dev->power_count++;
++ } else {
++ if (vin_dev->power_count == 0) {
++ st_err(ST_VIN,
++ "vin_dev power off on power_count == 0\n");
++ goto exit;
++ }
++ if (vin_dev->power_count == 1) {
++ vin_dev->hw_ops->vin_clk_disable(vin_dev);
++ pm_runtime_put_sync(stfcamss->dev);
++ }
++ vin_dev->power_count--;
++ }
++exit:
++
++ mutex_unlock(&vin_dev->power_lock);
++
++ return 0;
++}
++
++static unsigned int get_frame_skip(struct vin_line *line)
++{
++ unsigned int frame_skip = 0;
++ unsigned int isp_ctrl_skip_frames = 0;
++ struct media_entity *sensor;
++ struct v4l2_subdev_frame_interval fi;
++
++ sensor = stfcamss_find_sensor(&line->subdev.entity);
++ if (sensor) {
++ int fps = 0;
++ struct v4l2_subdev *subdev =
++ media_entity_to_v4l2_subdev(sensor);
++
++ if (subdev->ops->video->g_frame_interval) {
++ if (!subdev->ops->video->g_frame_interval(subdev, &fi))
++ fps = fi.interval.denominator;
++
++ if (fps > 0 && fps <= 90)
++ isp_ctrl_skip_frames = fps * VIN_FRAME_DROP_SEC_FOR_ISP_CTRL;
++ }
++ if (!fps)
++ st_debug(ST_VIN, "%s, Failed to get sensor fps !\n", __func__);
++
++ if (isp_ctrl_skip_frames <= VIN_FRAME_DROP_MIN_VAL)
++ isp_ctrl_skip_frames = VIN_FRAME_DROP_MIN_VAL;
++
++ v4l2_subdev_call(subdev, sensor, g_skip_frames, &frame_skip);
++
++ frame_skip += isp_ctrl_skip_frames;
++
++ if (frame_skip > VIN_FRAME_DROP_MAX_VAL)
++ frame_skip = VIN_FRAME_DROP_MAX_VAL;
++ st_debug(ST_VIN, "%s, frame_skip %d\n", __func__, frame_skip);
++ }
++
++ return frame_skip;
++}
++
++static void vin_buf_l2cache_flush(struct vin_output *output)
++{
++ struct stfcamss_buffer *buffer = NULL;
++
++ if (!list_empty(&output->pending_bufs)) {
++ list_for_each_entry(buffer, &output->pending_bufs, queue) {
++ sifive_l2_flush64_range(buffer->addr[0], buffer->sizeimage);
++ }
++ }
++}
++
++static int vin_enable_output(struct vin_line *line)
++{
++ struct vin_output *output = &line->output;
++ unsigned long flags;
++
++ spin_lock_irqsave(&line->output_lock, flags);
++
++ output->state = VIN_OUTPUT_IDLE;
++
++ vin_buf_l2cache_flush(output);
++
++ output->buf[0] = vin_buf_get_pending(output);
++#ifdef VIN_TWO_BUFFER
++ if (line->id == VIN_LINE_WR)
++ output->buf[1] = vin_buf_get_pending(output);
++#endif
++ if (!output->buf[0] && output->buf[1]) {
++ output->buf[0] = output->buf[1];
++ output->buf[1] = NULL;
++ }
++
++ if (output->buf[0])
++ output->state = VIN_OUTPUT_SINGLE;
++
++#ifdef VIN_TWO_BUFFER
++ if (output->buf[1] && line->id == VIN_LINE_WR)
++ output->state = VIN_OUTPUT_CONTINUOUS;
++#endif
++ output->sequence = 0;
++
++ vin_output_init_addrs(line);
++ spin_unlock_irqrestore(&line->output_lock, flags);
++ return 0;
++}
++
++static int vin_disable_output(struct vin_line *line)
++{
++ struct vin_output *output = &line->output;
++ unsigned long flags;
++
++ spin_lock_irqsave(&line->output_lock, flags);
++
++ output->state = VIN_OUTPUT_OFF;
++
++ spin_unlock_irqrestore(&line->output_lock, flags);
++ return 0;
++}
++
++static u32 line_to_dummy_module(struct vin_line *line)
++{
++ u32 dummy_module = 0;
++
++ switch (line->id) {
++ case VIN_LINE_WR:
++ dummy_module = STF_DUMMY_VIN;
++ break;
++ case VIN_LINE_ISP:
++ case VIN_LINE_ISP_SS0:
++ case VIN_LINE_ISP_SS1:
++ case VIN_LINE_ISP_ITIW:
++ case VIN_LINE_ISP_ITIR:
++ case VIN_LINE_ISP_RAW:
++ case VIN_LINE_ISP_SCD_Y:
++ dummy_module = STF_DUMMY_ISP;
++ break;
++ default:
++ dummy_module = STF_DUMMY_VIN;
++ break;
++ }
++
++ return dummy_module;
++}
++
++static int vin_alloc_dummy_buffer(struct stf_vin2_dev *vin_dev,
++ struct v4l2_mbus_framefmt *fmt, int dummy_module)
++{
++ struct device *dev = vin_dev->stfcamss->dev;
++ struct dummy_buffer *dummy_buffer = &vin_dev->dummy_buffer[dummy_module];
++ struct vin_dummy_buffer *buffer = NULL;
++ int ret = 0, i;
++ u32 aligns;
++
++ for (i = 0; i < dummy_buffer->nums; i++) {
++ buffer = &vin_dev->dummy_buffer[dummy_module].buffer[i];
++ buffer->width = fmt->width;
++ buffer->height = fmt->height;
++ buffer->mcode = fmt->code;
++ if (i == STF_VIN_PAD_SINK) {
++ aligns = ALIGN(fmt->width * 4, STFCAMSS_FRAME_WIDTH_ALIGN_8);
++ buffer->buffer_size = PAGE_ALIGN(aligns * fmt->height);
++ } else if (i == STF_ISP_PAD_SRC
++ || i == STF_ISP_PAD_SRC_SS0
++ || i == STF_ISP_PAD_SRC_SS1) {
++ aligns = ALIGN(fmt->width, STFCAMSS_FRAME_WIDTH_ALIGN_8);
++ buffer->buffer_size = PAGE_ALIGN(aligns * fmt->height * 3 / 2);
++ } else if (i == STF_ISP_PAD_SRC_ITIW
++ || i == STF_ISP_PAD_SRC_ITIR) {
++ aligns = ALIGN(fmt->width, STFCAMSS_FRAME_WIDTH_ALIGN_8);
++ buffer->buffer_size = PAGE_ALIGN(aligns * fmt->height * 3);
++ } else if (i == STF_ISP_PAD_SRC_RAW) {
++ aligns = ALIGN(fmt->width * ISP_RAW_DATA_BITS / 8,
++ STFCAMSS_FRAME_WIDTH_ALIGN_128);
++ buffer->buffer_size = PAGE_ALIGN(aligns * fmt->height);
++ } else if (i == STF_ISP_PAD_SRC_SCD_Y)
++ buffer->buffer_size = PAGE_ALIGN(ISP_SCD_Y_BUFFER_SIZE);
++ else
++ continue;
++
++ buffer->vaddr = dma_alloc_coherent(dev, buffer->buffer_size,
++ &buffer->paddr[0], GFP_DMA | GFP_KERNEL);
++
++ if (buffer->vaddr) {
++ if (i == STF_ISP_PAD_SRC
++ || i == STF_ISP_PAD_SRC_SS0
++ || i == STF_ISP_PAD_SRC_SS1
++ || i == STF_ISP_PAD_SRC_ITIW
++ || i == STF_ISP_PAD_SRC_ITIR)
++ buffer->paddr[1] = (dma_addr_t)(buffer->paddr[0] +
++ aligns * fmt->height);
++ else if (i == STF_ISP_PAD_SRC_SCD_Y)
++ buffer->paddr[1] = (dma_addr_t)(buffer->paddr[0] +
++ ISP_YHIST_BUFFER_SIZE);
++ else
++ st_debug(ST_VIN, "signal plane\n");
++ }
++ {
++ char szPadName[][32] = {
++ "VIN_PAD_SINK",
++ "ISP_PAD_SRC",
++ "ISP_PAD_SRC_SS0",
++ "ISP_PAD_SRC_SS1",
++ "ISP_PAD_SRC_ITIW",
++ "ISP_PAD_SRC_ITIR",
++ "ISP_PAD_SRC_RAW",
++ "ISP_PAD_SRC_SCD_Y",
++ "Unknown Pad"
++ };
++
++ st_debug(ST_VIN, "%s: i = %d(%s) addr[0] = %llx, addr[1] = %llx, size = %u bytes\n",
++ __func__,
++ i,
++ szPadName[i],
++ buffer->paddr[0],
++ buffer->paddr[1],
++ buffer->buffer_size
++ );
++ }
++ }
++
++ return ret;
++}
++
++static void vin_free_dummy_buffer(struct stf_vin2_dev *vin_dev, int dummy_module)
++{
++ struct device *dev = vin_dev->stfcamss->dev;
++ struct dummy_buffer *dummy_buffer = &vin_dev->dummy_buffer[dummy_module];
++ struct vin_dummy_buffer *buffer = NULL;
++ int i;
++
++ for (i = 0; i < dummy_buffer->nums; i++) {
++ buffer = &dummy_buffer->buffer[i];
++ if (buffer->vaddr)
++ dma_free_coherent(dev, buffer->buffer_size,
++ buffer->vaddr, buffer->paddr[0]);
++ memset(buffer, 0, sizeof(struct vin_dummy_buffer));
++ }
++}
++
++static void vin_set_dummy_buffer(struct vin_line *line, u32 pad)
++{
++ struct stf_vin2_dev *vin_dev = line_to_vin2_dev(line);
++ int dummy_module = line_to_dummy_module(line);
++ struct dummy_buffer *dummy_buffer = &vin_dev->dummy_buffer[dummy_module];
++ struct vin_dummy_buffer *buffer = NULL;
++
++ switch (pad) {
++ case STF_VIN_PAD_SINK:
++ if (line->id == VIN_LINE_WR) {
++ buffer = &dummy_buffer->buffer[STF_VIN_PAD_SINK];
++ vin_dev->hw_ops->vin_wr_set_ping_addr(vin_dev, buffer->paddr[0]);
++ vin_dev->hw_ops->vin_wr_set_pong_addr(vin_dev, buffer->paddr[0]);
++ } else {
++ buffer = &dummy_buffer->buffer[STF_ISP_PAD_SRC];
++ vin_dev->hw_ops->vin_isp_set_yuv_addr(vin_dev,
++ buffer->paddr[0], buffer->paddr[1]);
++
++ buffer = &dummy_buffer->buffer[STF_ISP_PAD_SRC_SS0];
++ vin_dev->hw_ops->vin_isp_set_ss0_addr(vin_dev,
++ buffer->paddr[0], buffer->paddr[1]);
++
++ buffer = &dummy_buffer->buffer[STF_ISP_PAD_SRC_SS1];
++ vin_dev->hw_ops->vin_isp_set_ss1_addr(vin_dev,
++ buffer->paddr[0], buffer->paddr[1]);
++
++ buffer = &dummy_buffer->buffer[STF_ISP_PAD_SRC_ITIW];
++ vin_dev->hw_ops->vin_isp_set_itiw_addr(vin_dev,
++ buffer->paddr[0], buffer->paddr[1]);
++
++ buffer = &dummy_buffer->buffer[STF_ISP_PAD_SRC_ITIR];
++ vin_dev->hw_ops->vin_isp_set_itir_addr(vin_dev,
++ buffer->paddr[0], buffer->paddr[1]);
++
++ buffer = &dummy_buffer->buffer[STF_ISP_PAD_SRC_RAW];
++ vin_dev->hw_ops->vin_isp_set_raw_addr(vin_dev, buffer->paddr[0]);
++
++ buffer = &dummy_buffer->buffer[STF_ISP_PAD_SRC_SCD_Y];
++ vin_dev->hw_ops->vin_isp_set_scd_addr(vin_dev,
++ buffer->paddr[0], buffer->paddr[1], AWB_TYPE);
++ }
++ break;
++ case STF_ISP_PAD_SRC:
++ buffer = &dummy_buffer->buffer[STF_ISP_PAD_SRC];
++ vin_dev->hw_ops->vin_isp_set_yuv_addr(vin_dev,
++ buffer->paddr[0], buffer->paddr[1]);
++ break;
++ case STF_ISP_PAD_SRC_SS0:
++ buffer = &dummy_buffer->buffer[STF_ISP_PAD_SRC_SS0];
++ vin_dev->hw_ops->vin_isp_set_ss0_addr(vin_dev,
++ buffer->paddr[0], buffer->paddr[1]);
++ break;
++ case STF_ISP_PAD_SRC_SS1:
++ buffer = &dummy_buffer->buffer[STF_ISP_PAD_SRC_SS1];
++ vin_dev->hw_ops->vin_isp_set_ss1_addr(vin_dev,
++ buffer->paddr[0], buffer->paddr[1]);
++ break;
++ case STF_ISP_PAD_SRC_ITIW:
++ buffer = &dummy_buffer->buffer[STF_ISP_PAD_SRC_ITIW];
++ vin_dev->hw_ops->vin_isp_set_itiw_addr(vin_dev,
++ buffer->paddr[0], buffer->paddr[1]);
++ break;
++ case STF_ISP_PAD_SRC_ITIR:
++ buffer = &dummy_buffer->buffer[STF_ISP_PAD_SRC_ITIR];
++ vin_dev->hw_ops->vin_isp_set_itir_addr(vin_dev,
++ buffer->paddr[0], buffer->paddr[1]);
++ break;
++ case STF_ISP_PAD_SRC_RAW:
++ buffer = &dummy_buffer->buffer[STF_ISP_PAD_SRC_RAW];
++ vin_dev->hw_ops->vin_isp_set_raw_addr(vin_dev, buffer->paddr[0]);
++ break;
++ case STF_ISP_PAD_SRC_SCD_Y:
++ buffer = &dummy_buffer->buffer[STF_ISP_PAD_SRC_SCD_Y];
++ vin_dev->hw_ops->vin_isp_set_scd_addr(vin_dev,
++ buffer->paddr[0], buffer->paddr[1], AWB_TYPE);
++ break;
++ default:
++ break;
++ }
++}
++
++static int vin_set_stream(struct v4l2_subdev *sd, int enable)
++{
++ struct vin_line *line = v4l2_get_subdevdata(sd);
++ struct stf_vin2_dev *vin_dev = line_to_vin2_dev(line);
++ int dummy_module = line_to_dummy_module(line);
++ struct dummy_buffer *dummy_buffer = &vin_dev->dummy_buffer[dummy_module];
++ struct v4l2_mbus_framefmt *fmt;
++
++ st_debug(ST_VIN, "%s, %d\n", __func__, __LINE__);
++ fmt = __vin_get_format(line, NULL, STF_VIN_PAD_SINK, V4L2_SUBDEV_FORMAT_ACTIVE);
++ mutex_lock(&dummy_buffer->stream_lock);
++ if (enable) {
++ if (dummy_buffer->stream_count == 0) {
++ vin_alloc_dummy_buffer(vin_dev, fmt, dummy_module);
++ vin_set_dummy_buffer(line, STF_VIN_PAD_SINK);
++ atomic_set(&dummy_buffer->frame_skip, get_frame_skip(line));
++ }
++ dummy_buffer->stream_count++;
++ } else {
++ if (dummy_buffer->stream_count == 1) {
++ vin_free_dummy_buffer(vin_dev, dummy_module);
++ // set buffer addr to zero
++ vin_set_dummy_buffer(line, STF_VIN_PAD_SINK);
++ } else
++ vin_set_dummy_buffer(line,
++ stf_vin_map_isp_pad(line->id, STF_ISP_PAD_SINK));
++
++ dummy_buffer->stream_count--;
++ }
++ mutex_unlock(&dummy_buffer->stream_lock);
++
++ mutex_lock(&line->stream_lock);
++ if (enable) {
++ if (line->stream_count == 0) {
++ if (line->id == VIN_LINE_WR) {
++ vin_dev->hw_ops->vin_wr_irq_enable(vin_dev, 1);
++ vin_dev->hw_ops->vin_wr_stream_set(vin_dev, 1);
++ }
++ }
++ line->stream_count++;
++ } else {
++ if (line->stream_count == 1) {
++ if (line->id == VIN_LINE_WR) {
++ vin_dev->hw_ops->vin_wr_irq_enable(vin_dev, 0);
++ vin_dev->hw_ops->vin_wr_stream_set(vin_dev, 0);
++ }
++ }
++ line->stream_count--;
++ }
++ mutex_unlock(&line->stream_lock);
++
++ if (enable)
++ vin_enable_output(line);
++ else
++ vin_disable_output(line);
++
++ return 0;
++}
++
++static struct v4l2_mbus_framefmt *
++__vin_get_format(struct vin_line *line,
++ struct v4l2_subdev_state *state,
++ unsigned int pad,
++ enum v4l2_subdev_format_whence which)
++{
++ if (which == V4L2_SUBDEV_FORMAT_TRY)
++ return v4l2_subdev_get_try_format(&line->subdev, state, pad);
++ return &line->fmt[pad];
++}
++
++static void vin_try_format(struct vin_line *line,
++ struct v4l2_subdev_state *state,
++ unsigned int pad,
++ struct v4l2_mbus_framefmt *fmt,
++ enum v4l2_subdev_format_whence which)
++{
++ unsigned int i;
++
++ switch (pad) {
++ case STF_VIN_PAD_SINK:
++ /* Set format on sink pad */
++
++ for (i = 0; i < line->nformats; i++)
++ if (fmt->code == line->formats[i].code)
++ break;
++
++ /* If not found, use UYVY as default */
++ if (i >= line->nformats)
++ fmt->code = line->formats[0].code;
++
++ fmt->width = clamp_t(u32,
++ fmt->width, STFCAMSS_FRAME_MIN_WIDTH, STFCAMSS_FRAME_MAX_WIDTH);
++ fmt->height = clamp_t(u32,
++ fmt->height, STFCAMSS_FRAME_MIN_HEIGHT, STFCAMSS_FRAME_MAX_HEIGHT);
++
++ fmt->field = V4L2_FIELD_NONE;
++ fmt->colorspace = V4L2_COLORSPACE_SRGB;
++ fmt->flags = 0;
++
++ break;
++
++ case STF_VIN_PAD_SRC:
++ /* Set and return a format same as sink pad */
++ *fmt = *__vin_get_format(line, state, STF_VIN_PAD_SINK, which);
++ break;
++ }
++
++ fmt->colorspace = V4L2_COLORSPACE_SRGB;
++}
++
++static int vin_enum_mbus_code(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_mbus_code_enum *code)
++{
++ struct vin_line *line = v4l2_get_subdevdata(sd);
++
++ if (code->index >= line->nformats)
++ return -EINVAL;
++ if (code->pad == STF_VIN_PAD_SINK) {
++ code->code = line->formats[code->index].code;
++ } else {
++ struct v4l2_mbus_framefmt *sink_fmt;
++
++ sink_fmt = __vin_get_format(line, state, STF_VIN_PAD_SINK,
++ code->which);
++
++ code->code = sink_fmt->code;
++ if (!code->code)
++ return -EINVAL;
++ }
++ code->flags = 0;
++
++ return 0;
++}
++
++static int vin_enum_frame_size(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_frame_size_enum *fse)
++{
++ struct vin_line *line = v4l2_get_subdevdata(sd);
++ struct v4l2_mbus_framefmt format;
++
++ if (fse->index != 0)
++ return -EINVAL;
++
++ format.code = fse->code;
++ format.width = 1;
++ format.height = 1;
++ vin_try_format(line, state, fse->pad, &format, fse->which);
++ fse->min_width = format.width;
++ fse->min_height = format.height;
++
++ if (format.code != fse->code)
++ return -EINVAL;
++
++ format.code = fse->code;
++ format.width = -1;
++ format.height = -1;
++ vin_try_format(line, state, fse->pad, &format, fse->which);
++ fse->max_width = format.width;
++ fse->max_height = format.height;
++
++ return 0;
++}
++
++static int vin_get_format(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_format *fmt)
++{
++ struct vin_line *line = v4l2_get_subdevdata(sd);
++ struct v4l2_mbus_framefmt *format;
++
++ format = __vin_get_format(line, state, fmt->pad, fmt->which);
++ if (format == NULL)
++ return -EINVAL;
++
++ fmt->format = *format;
++
++ return 0;
++}
++
++static int vin_set_format(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *state,
++ struct v4l2_subdev_format *fmt)
++{
++ struct vin_line *line = v4l2_get_subdevdata(sd);
++ struct v4l2_mbus_framefmt *format;
++
++ st_debug(ST_VIDEO, "%s, pad %d, fmt code %x\n",
++ __func__, fmt->pad, fmt->format.code);
++
++ format = __vin_get_format(line, state, fmt->pad, fmt->which);
++ if (format == NULL)
++ return -EINVAL;
++
++ mutex_lock(&line->stream_lock);
++ if (line->stream_count) {
++ fmt->format = *format;
++ mutex_unlock(&line->stream_lock);
++ goto out;
++ } else {
++ vin_try_format(line, state, fmt->pad, &fmt->format, fmt->which);
++ *format = fmt->format;
++ }
++ mutex_unlock(&line->stream_lock);
++
++ if (fmt->pad == STF_VIN_PAD_SINK) {
++ /* Propagate the format from sink to source */
++ format = __vin_get_format(line, state, STF_VIN_PAD_SRC,
++ fmt->which);
++
++ *format = fmt->format;
++ vin_try_format(line, state, STF_VIN_PAD_SRC, format,
++ fmt->which);
++ }
++
++out:
++ return 0;
++}
++
++static int vin_init_formats(struct v4l2_subdev *sd,
++ struct v4l2_subdev_fh *fh)
++{
++ struct v4l2_subdev_format format = {
++ .pad = STF_VIN_PAD_SINK,
++ .which = fh ? V4L2_SUBDEV_FORMAT_TRY :
++ V4L2_SUBDEV_FORMAT_ACTIVE,
++ .format = {
++ .code = MEDIA_BUS_FMT_RGB565_2X8_LE,
++ .width = 1920,
++ .height = 1080
++ }
++ };
++
++ return vin_set_format(sd, fh ? fh->state : NULL, &format);
++}
++
++static void vin_output_init_addrs(struct vin_line *line)
++{
++ struct vin_output *output = &line->output;
++ struct stf_vin2_dev *vin_dev = line_to_vin2_dev(line);
++ dma_addr_t ping_addr;
++ dma_addr_t pong_addr;
++ dma_addr_t y_addr, uv_addr;
++
++ output->active_buf = 0;
++
++ if (output->buf[0]) {
++ ping_addr = output->buf[0]->addr[0];
++ y_addr = output->buf[0]->addr[0];
++ uv_addr = output->buf[0]->addr[1];
++ } else
++ return;
++
++ if (output->buf[1])
++ pong_addr = output->buf[1]->addr[0];
++ else
++ pong_addr = ping_addr;
++
++ switch (stf_vin_map_isp_line(line->id)) {
++ case STF_ISP_LINE_SRC:
++ vin_dev->hw_ops->vin_isp_set_yuv_addr(vin_dev,
++ y_addr, uv_addr);
++ break;
++ case STF_ISP_LINE_SRC_SS0:
++ vin_dev->hw_ops->vin_isp_set_ss0_addr(vin_dev,
++ y_addr, uv_addr);
++ break;
++ case STF_ISP_LINE_SRC_SS1:
++ vin_dev->hw_ops->vin_isp_set_ss1_addr(vin_dev,
++ y_addr, uv_addr);
++ break;
++ case STF_ISP_LINE_SRC_ITIW:
++ vin_dev->hw_ops->vin_isp_set_itiw_addr(vin_dev,
++ y_addr, uv_addr);
++ break;
++ case STF_ISP_LINE_SRC_ITIR:
++ vin_dev->hw_ops->vin_isp_set_itir_addr(vin_dev,
++ y_addr, uv_addr);
++ break;
++ case STF_ISP_LINE_SRC_RAW:
++ vin_dev->hw_ops->vin_isp_set_raw_addr(vin_dev, y_addr);
++ break;
++ case STF_ISP_LINE_SRC_SCD_Y:
++ output->frame_skip = ISP_AWB_OECF_SKIP_FRAME;
++ vin_dev->hw_ops->vin_isp_set_scd_addr(vin_dev,
++ y_addr, uv_addr, AWB_TYPE);
++ break;
++ default:
++ if (line->id == VIN_LINE_WR) {
++ vin_dev->hw_ops->vin_wr_set_ping_addr(vin_dev, ping_addr);
++#ifdef VIN_TWO_BUFFER
++ vin_dev->hw_ops->vin_wr_set_pong_addr(vin_dev, pong_addr);
++#else
++ vin_dev->hw_ops->vin_wr_set_pong_addr(vin_dev, ping_addr);
++#endif
++ }
++ break;
++ }
++}
++
++static void vin_init_outputs(struct vin_line *line)
++{
++ struct vin_output *output = &line->output;
++
++ output->state = VIN_OUTPUT_OFF;
++ output->buf[0] = NULL;
++ output->buf[1] = NULL;
++ output->active_buf = 0;
++ INIT_LIST_HEAD(&output->pending_bufs);
++ INIT_LIST_HEAD(&output->ready_bufs);
++}
++
++static void vin_buf_add_ready(struct vin_output *output,
++ struct stfcamss_buffer *buffer)
++{
++ INIT_LIST_HEAD(&buffer->queue);
++ list_add_tail(&buffer->queue, &output->ready_bufs);
++}
++
++static struct stfcamss_buffer *vin_buf_get_ready(struct vin_output *output)
++{
++ struct stfcamss_buffer *buffer = NULL;
++
++ if (!list_empty(&output->ready_bufs)) {
++ buffer = list_first_entry(&output->ready_bufs,
++ struct stfcamss_buffer,
++ queue);
++ list_del(&buffer->queue);
++ }
++
++ return buffer;
++}
++
++static void vin_buf_add_pending(struct vin_output *output,
++ struct stfcamss_buffer *buffer)
++{
++ INIT_LIST_HEAD(&buffer->queue);
++ list_add_tail(&buffer->queue, &output->pending_bufs);
++}
++
++static struct stfcamss_buffer *vin_buf_get_pending(struct vin_output *output)
++{
++ struct stfcamss_buffer *buffer = NULL;
++
++ if (!list_empty(&output->pending_bufs)) {
++ buffer = list_first_entry(&output->pending_bufs,
++ struct stfcamss_buffer,
++ queue);
++ list_del(&buffer->queue);
++ }
++
++ return buffer;
++}
++
++#ifdef UNUSED_CODE
++static void vin_output_checkpending(struct vin_line *line)
++{
++ struct vin_output *output = &line->output;
++
++ if (output->state == VIN_OUTPUT_STOPPING) {
++ /* Release last buffer when hw is idle */
++ if (output->last_buffer) {
++ // vb2_buffer_done(&output->last_buffer->vb.vb2_buf,
++ // VB2_BUF_STATE_DONE);
++ vin_buf_add_pending(output, output->last_buffer);
++ output->last_buffer = NULL;
++ }
++ output->state = VIN_OUTPUT_IDLE;
++
++ /* Buffers received in stopping state are queued in */
++ /* dma pending queue, start next capture here */
++ output->buf[0] = vin_buf_get_pending(output);
++#ifdef VIN_TWO_BUFFER
++ if (line->id == VIN_LINE_WR)
++ output->buf[1] = vin_buf_get_pending(output);
++#endif
++
++ if (!output->buf[0] && output->buf[1]) {
++ output->buf[0] = output->buf[1];
++ output->buf[1] = NULL;
++ }
++
++ if (output->buf[0])
++ output->state = VIN_OUTPUT_SINGLE;
++
++#ifdef VIN_TWO_BUFFER
++ if (output->buf[1] && line->id == VIN_LINE_WR)
++ output->state = VIN_OUTPUT_CONTINUOUS;
++#endif
++ vin_output_init_addrs(line);
++ }
++}
++#endif
++
++static void vin_buf_update_on_last(struct vin_line *line)
++{
++ struct vin_output *output = &line->output;
++
++ switch (output->state) {
++ case VIN_OUTPUT_CONTINUOUS:
++ output->state = VIN_OUTPUT_SINGLE;
++ output->active_buf = !output->active_buf;
++ break;
++ case VIN_OUTPUT_SINGLE:
++ output->state = VIN_OUTPUT_STOPPING;
++ break;
++ default:
++ st_err_ratelimited(ST_VIN,
++ "Last buff in wrong state! %d\n",
++ output->state);
++ break;
++ }
++}
++
++static void vin_buf_update_on_next(struct vin_line *line)
++{
++ struct vin_output *output = &line->output;
++
++ switch (output->state) {
++ case VIN_OUTPUT_CONTINUOUS:
++ output->active_buf = !output->active_buf;
++ break;
++ case VIN_OUTPUT_SINGLE:
++ default:
++#ifdef VIN_TWO_BUFFER
++ if (line->id == VIN_LINE_WR)
++ st_err_ratelimited(ST_VIN,
++ "Next buf in wrong state! %d\n",
++ output->state);
++#endif
++ break;
++ }
++}
++
++static void vin_buf_update_on_new(struct vin_line *line,
++ struct vin_output *output,
++ struct stfcamss_buffer *new_buf)
++{
++#ifdef VIN_TWO_BUFFER
++ struct stf_vin2_dev *vin_dev = line_to_vin2_dev(line);
++ int inactive_idx;
++#endif
++
++ switch (output->state) {
++ case VIN_OUTPUT_SINGLE:
++#ifdef VIN_TWO_BUFFER
++ int inactive_idx = !output->active_buf;
++
++ if (!output->buf[inactive_idx] && line->id == VIN_LINE_WR) {
++ output->buf[inactive_idx] = new_buf;
++ if (inactive_idx)
++ vin_dev->hw_ops->vin_wr_set_pong_addr(vin_dev,
++ output->buf[1]->addr[0]);
++ else
++ vin_dev->hw_ops->vin_wr_set_ping_addr(vin_dev,
++ output->buf[0]->addr[0]);
++ output->state = VIN_OUTPUT_CONTINUOUS;
++
++ } else {
++ vin_buf_add_pending(output, new_buf);
++ if (line->id == VIN_LINE_WR)
++ st_warn(ST_VIN, "Inactive buffer is busy\n");
++ }
++#else
++ vin_buf_add_pending(output, new_buf);
++#endif
++ break;
++ case VIN_OUTPUT_IDLE:
++ st_warn(ST_VIN, "Output idle buffer set!\n");
++ if (!output->buf[0]) {
++ output->buf[0] = new_buf;
++ vin_output_init_addrs(line);
++ output->state = VIN_OUTPUT_SINGLE;
++ } else {
++ vin_buf_add_pending(output, new_buf);
++ st_warn(ST_VIN, "Output idle with buffer set!\n");
++ }
++ break;
++ case VIN_OUTPUT_STOPPING:
++ if (output->last_buffer) {
++ output->buf[output->active_buf] = output->last_buffer;
++ output->last_buffer = NULL;
++ } else
++ st_err(ST_VIN, "stop state lost lastbuffer!\n");
++ output->state = VIN_OUTPUT_SINGLE;
++ // vin_output_checkpending(line);
++ vin_buf_add_pending(output, new_buf);
++ break;
++ case VIN_OUTPUT_CONTINUOUS:
++ default:
++ vin_buf_add_pending(output, new_buf);
++ break;
++ }
++}
++
++static void vin_buf_flush(struct vin_output *output,
++ enum vb2_buffer_state state)
++{
++ struct stfcamss_buffer *buf;
++ struct stfcamss_buffer *t;
++
++ list_for_each_entry_safe(buf, t, &output->pending_bufs, queue) {
++ vb2_buffer_done(&buf->vb.vb2_buf, state);
++ list_del(&buf->queue);
++ }
++ list_for_each_entry_safe(buf, t, &output->ready_bufs, queue) {
++ vb2_buffer_done(&buf->vb.vb2_buf, state);
++ list_del(&buf->queue);
++ }
++}
++
++static void vin_buffer_done(struct vin_line *line, struct vin_params *params)
++{
++ struct stfcamss_buffer *ready_buf;
++ struct vin_output *output = &line->output;
++ unsigned long flags;
++ u64 ts = ktime_get_ns();
++ struct v4l2_event event = {
++ .type = V4L2_EVENT_FRAME_SYNC,
++ };
++
++ if (output->state == VIN_OUTPUT_OFF
++ || output->state == VIN_OUTPUT_RESERVED)
++ return;
++
++ spin_lock_irqsave(&line->output_lock, flags);
++
++ while ((ready_buf = vin_buf_get_ready(output))) {
++ if (line->id >= VIN_LINE_ISP && line->id <= VIN_LINE_ISP_SS1) {
++ event.u.frame_sync.frame_sequence = output->sequence;
++ v4l2_event_queue(line->subdev.devnode, &event);
++ }
++
++ ready_buf->vb.vb2_buf.timestamp = ts;
++ ready_buf->vb.sequence = output->sequence++;
++
++ /* The stf_isp_ctrl currently buffered with mmap,
++ * which will not update cache by default.
++ * Flush L2 cache to make sure data is updated.
++ */
++ if (ready_buf->vb.vb2_buf.memory == VB2_MEMORY_MMAP)
++ sifive_l2_flush64_range(ready_buf->addr[0], ready_buf->sizeimage);
++
++ vb2_buffer_done(&ready_buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
++ }
++
++ spin_unlock_irqrestore(&line->output_lock, flags);
++}
++
++static void vin_change_buffer(struct vin_line *line)
++{
++ struct stfcamss_buffer *ready_buf;
++ struct vin_output *output = &line->output;
++ struct stf_vin2_dev *vin_dev = line_to_vin2_dev(line);
++ dma_addr_t *new_addr;
++ unsigned long flags;
++ u32 active_index;
++ int scd_type;
++
++ if (output->state == VIN_OUTPUT_OFF
++ || output->state == VIN_OUTPUT_STOPPING
++ || output->state == VIN_OUTPUT_RESERVED
++ || output->state == VIN_OUTPUT_IDLE)
++ return;
++
++ spin_lock_irqsave(&line->output_lock, flags);
++
++ active_index = output->active_buf;
++
++ ready_buf = output->buf[active_index];
++ if (!ready_buf) {
++ st_err_ratelimited(ST_VIN,
++ "Missing ready buf %d %d!\n",
++ active_index, output->state);
++ active_index = !active_index;
++ ready_buf = output->buf[active_index];
++ if (!ready_buf) {
++ st_err_ratelimited(ST_VIN,
++ "Missing ready buf 2 %d %d!\n",
++ active_index, output->state);
++ goto out_unlock;
++ }
++ }
++
++ /* Get next buffer */
++ output->buf[active_index] = vin_buf_get_pending(output);
++ if (!output->buf[active_index]) {
++ /* No next buffer - set same address */
++ new_addr = ready_buf->addr;
++ vin_buf_update_on_last(line);
++ } else {
++ new_addr = output->buf[active_index]->addr;
++ vin_buf_update_on_next(line);
++ }
++
++ if (output->state == VIN_OUTPUT_STOPPING)
++ output->last_buffer = ready_buf;
++ else {
++ switch (stf_vin_map_isp_line(line->id)) {
++ case STF_ISP_LINE_SRC:
++ vin_dev->hw_ops->vin_isp_set_yuv_addr(vin_dev,
++ new_addr[0], new_addr[1]);
++ break;
++ case STF_ISP_LINE_SRC_SS0:
++ vin_dev->hw_ops->vin_isp_set_ss0_addr(vin_dev,
++ new_addr[0], new_addr[1]);
++ break;
++ case STF_ISP_LINE_SRC_SS1:
++ vin_dev->hw_ops->vin_isp_set_ss1_addr(vin_dev,
++ new_addr[0], new_addr[1]);
++ break;
++ case STF_ISP_LINE_SRC_ITIW:
++ vin_dev->hw_ops->vin_isp_set_itiw_addr(vin_dev,
++ new_addr[0], new_addr[1]);
++ break;
++ case STF_ISP_LINE_SRC_ITIR:
++ vin_dev->hw_ops->vin_isp_set_itir_addr(vin_dev,
++ new_addr[0], new_addr[1]);
++ break;
++ case STF_ISP_LINE_SRC_RAW:
++ vin_dev->hw_ops->vin_isp_set_raw_addr(vin_dev, new_addr[0]);
++ break;
++ case STF_ISP_LINE_SRC_SCD_Y:
++ scd_type = vin_dev->hw_ops->vin_isp_get_scd_type(vin_dev);
++ ready_buf->vb.flags &= ~(V4L2_BUF_FLAG_PFRAME | V4L2_BUF_FLAG_BFRAME);
++ if (scd_type == AWB_TYPE)
++ ready_buf->vb.flags |= V4L2_BUF_FLAG_PFRAME;
++ else
++ ready_buf->vb.flags |= V4L2_BUF_FLAG_BFRAME;
++ if (!output->frame_skip) {
++ output->frame_skip = ISP_AWB_OECF_SKIP_FRAME;
++ scd_type = scd_type == AWB_TYPE ? OECF_TYPE : AWB_TYPE;
++ } else {
++ output->frame_skip--;
++ scd_type = scd_type == AWB_TYPE ? AWB_TYPE : OECF_TYPE;
++ }
++ vin_dev->hw_ops->vin_isp_set_scd_addr(vin_dev,
++ new_addr[0], new_addr[1], scd_type);
++ break;
++ default:
++ if (line->id == VIN_LINE_WR) {
++#ifdef VIN_TWO_BUFFER
++ if (active_index)
++ vin_dev->hw_ops->vin_wr_set_pong_addr(vin_dev,
++ new_addr[0]);
++ else
++ vin_dev->hw_ops->vin_wr_set_ping_addr(vin_dev,
++ new_addr[0]);
++#else
++ vin_dev->hw_ops->vin_wr_set_ping_addr(vin_dev,
++ new_addr[0]);
++ vin_dev->hw_ops->vin_wr_set_pong_addr(vin_dev,
++ new_addr[0]);
++#endif
++ }
++ break;
++ }
++
++ vin_buf_add_ready(output, ready_buf);
++ }
++
++ spin_unlock_irqrestore(&line->output_lock, flags);
++ return;
++
++out_unlock:
++ spin_unlock_irqrestore(&line->output_lock, flags);
++}
++
++static int vin_queue_buffer(struct stfcamss_video *vid,
++ struct stfcamss_buffer *buf)
++{
++ struct vin_line *line = container_of(vid, struct vin_line, video_out);
++ struct vin_output *output;
++ unsigned long flags;
++
++
++ output = &line->output;
++
++ spin_lock_irqsave(&line->output_lock, flags);
++
++ vin_buf_update_on_new(line, output, buf);
++
++ spin_unlock_irqrestore(&line->output_lock, flags);
++
++ return 0;
++}
++
++static int vin_flush_buffers(struct stfcamss_video *vid,
++ enum vb2_buffer_state state)
++{
++ struct vin_line *line = container_of(vid, struct vin_line, video_out);
++ struct vin_output *output = &line->output;
++ unsigned long flags;
++
++ spin_lock_irqsave(&line->output_lock, flags);
++
++ vin_buf_flush(output, state);
++ if (output->buf[0])
++ vb2_buffer_done(&output->buf[0]->vb.vb2_buf, state);
++
++ if (output->buf[1])
++ vb2_buffer_done(&output->buf[1]->vb.vb2_buf, state);
++
++ if (output->last_buffer) {
++ vb2_buffer_done(&output->last_buffer->vb.vb2_buf, state);
++ output->last_buffer = NULL;
++ }
++ output->buf[0] = output->buf[1] = NULL;
++
++ spin_unlock_irqrestore(&line->output_lock, flags);
++ return 0;
++}
++
++static int vin_link_setup(struct media_entity *entity,
++ const struct media_pad *local,
++ const struct media_pad *remote, u32 flags)
++{
++ if (flags & MEDIA_LNK_FL_ENABLED)
++ if (media_pad_remote_pad_first(local))
++ return -EBUSY;
++ return 0;
++}
++
++static int stf_vin_subscribe_event(struct v4l2_subdev *sd,
++ struct v4l2_fh *fh,
++ struct v4l2_event_subscription *sub)
++{
++ switch (sub->type) {
++ case V4L2_EVENT_FRAME_SYNC:
++ return v4l2_event_subscribe(fh, sub, 0, NULL);
++ default:
++ st_debug(ST_VIN, "unsupport subscribe_event\n");
++ return -EINVAL;
++ }
++}
++
++static const struct v4l2_subdev_core_ops vin_core_ops = {
++ .s_power = vin_set_power,
++ .subscribe_event = stf_vin_subscribe_event,
++ .unsubscribe_event = v4l2_event_subdev_unsubscribe,
++};
++
++static const struct v4l2_subdev_video_ops vin_video_ops = {
++ .s_stream = vin_set_stream,
++};
++
++static const struct v4l2_subdev_pad_ops vin_pad_ops = {
++ .enum_mbus_code = vin_enum_mbus_code,
++ .enum_frame_size = vin_enum_frame_size,
++ .get_fmt = vin_get_format,
++ .set_fmt = vin_set_format,
++};
++
++static const struct v4l2_subdev_ops vin_v4l2_ops = {
++ .core = &vin_core_ops,
++ .video = &vin_video_ops,
++ .pad = &vin_pad_ops,
++};
++
++static const struct v4l2_subdev_internal_ops vin_v4l2_internal_ops = {
++ .open = vin_init_formats,
++};
++
++static const struct stfcamss_video_ops stfcamss_vin_video_ops = {
++ .queue_buffer = vin_queue_buffer,
++ .flush_buffers = vin_flush_buffers,
++};
++
++static const struct media_entity_operations vin_media_ops = {
++ .link_setup = vin_link_setup,
++ .link_validate = v4l2_subdev_link_validate,
++};
++
++int stf_vin_register(struct stf_vin2_dev *vin_dev, struct v4l2_device *v4l2_dev)
++{
++ struct v4l2_subdev *sd;
++ struct stfcamss_video *video_out;
++ struct media_pad *pads;
++ int ret;
++ int i;
++
++ for (i = 0; i < STF_ISP_LINE_MAX + 1; i++) {
++ char name[32];
++ char *sub_name = get_line_subdevname(i);
++ int is_mp;
++
++#ifdef STF_CAMSS_SKIP_ITI
++ if ((stf_vin_map_isp_line(i) == STF_ISP_LINE_SRC_ITIW) ||
++ (stf_vin_map_isp_line(i) == STF_ISP_LINE_SRC_ITIR))
++ continue;
++#endif
++ is_mp = (stf_vin_map_isp_line(i) == STF_ISP_LINE_SRC) ? true : false;
++ is_mp = false;
++ sd = &vin_dev->line[i].subdev;
++ pads = vin_dev->line[i].pads;
++ video_out = &vin_dev->line[i].video_out;
++ video_out->id = i;
++
++ v4l2_subdev_init(sd, &vin_v4l2_ops);
++ sd->internal_ops = &vin_v4l2_internal_ops;
++ sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
++ snprintf(sd->name, ARRAY_SIZE(sd->name), "%s%d_%s",
++ STF_VIN_NAME, 0, sub_name);
++ v4l2_set_subdevdata(sd, &vin_dev->line[i]);
++
++ ret = vin_init_formats(sd, NULL);
++ if (ret < 0) {
++ st_err(ST_VIN, "Failed to init format: %d\n", ret);
++ goto err_init;
++ }
++
++ pads[STF_VIN_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
++ pads[STF_VIN_PAD_SRC].flags = MEDIA_PAD_FL_SOURCE;
++
++ sd->entity.function =
++ MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER;
++ sd->entity.ops = &vin_media_ops;
++ ret = media_entity_pads_init(&sd->entity,
++ STF_VIN_PADS_NUM, pads);
++ if (ret < 0) {
++ st_err(ST_VIN, "Failed to init media entity: %d\n", ret);
++ goto err_init;
++ }
++
++ ret = v4l2_device_register_subdev(v4l2_dev, sd);
++ if (ret < 0) {
++ st_err(ST_VIN, "Failed to register subdev: %d\n", ret);
++ goto err_reg_subdev;
++ }
++
++ video_out->ops = &stfcamss_vin_video_ops;
++ video_out->bpl_alignment = 16 * 8;
++
++ snprintf(name, ARRAY_SIZE(name), "%s_%s%d",
++ sd->name, "video", i);
++ ret = stf_video_register(video_out, v4l2_dev, name, is_mp);
++ if (ret < 0) {
++ st_err(ST_VIN, "Failed to register video node: %d\n",
++ ret);
++ goto err_vid_reg;
++ }
++
++ ret = media_create_pad_link(
++ &sd->entity, STF_VIN_PAD_SRC,
++ &video_out->vdev.entity, 0,
++ MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED);
++ if (ret < 0) {
++ st_err(ST_VIN, "Failed to link %s->%s entities: %d\n",
++ sd->entity.name, video_out->vdev.entity.name,
++ ret);
++ goto err_create_link;
++ }
++ }
++
++ return 0;
++
++err_create_link:
++ stf_video_unregister(video_out);
++err_vid_reg:
++ v4l2_device_unregister_subdev(sd);
++err_reg_subdev:
++ media_entity_cleanup(&sd->entity);
++err_init:
++ for (i--; i >= 0; i--) {
++ sd = &vin_dev->line[i].subdev;
++ video_out = &vin_dev->line[i].video_out;
++
++ stf_video_unregister(video_out);
++ v4l2_device_unregister_subdev(sd);
++ media_entity_cleanup(&sd->entity);
++ }
++ return ret;
++}
++
++int stf_vin_unregister(struct stf_vin2_dev *vin_dev)
++{
++ struct v4l2_subdev *sd;
++ struct stfcamss_video *video_out;
++ int i;
++
++ mutex_destroy(&vin_dev->power_lock);
++ for (i = 0; i < STF_DUMMY_MODULE_NUMS; i++)
++ mutex_destroy(&vin_dev->dummy_buffer[i].stream_lock);
++
++ for (i = 0; i < STF_ISP_LINE_MAX + 1; i++) {
++ sd = &vin_dev->line[i].subdev;
++ video_out = &vin_dev->line[i].video_out;
++
++ stf_video_unregister(video_out);
++ v4l2_device_unregister_subdev(sd);
++ media_entity_cleanup(&sd->entity);
++ mutex_destroy(&vin_dev->line[i].stream_lock);
++ mutex_destroy(&vin_dev->line[i].power_lock);
++ }
++ return 0;
++}
+--- /dev/null
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_vin.h
+@@ -0,0 +1,182 @@
++/* SPDX-License-Identifier: GPL-2.0
++ *
++ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
++ *
++ */
++
++#ifndef STF_VIN_H
++#define STF_VIN_H
++
++#include <media/v4l2-device.h>
++#include <media/v4l2-subdev.h>
++#include <linux/spinlock_types.h>
++#include <video/stf-vin.h>
++#include <linux/platform_device.h>
++
++#include "stf_video.h"
++
++#define STF_VIN_NAME "stf_vin"
++
++#define STF_VIN_PAD_SINK 0
++#define STF_VIN_PAD_SRC 1
++#define STF_VIN_PADS_NUM 2
++
++struct vin2_format {
++ u32 code;
++ u8 bpp;
++};
++
++struct vin2_format_table {
++ const struct vin2_format *fmts;
++ int nfmts;
++};
++
++enum vin_output_state {
++ VIN_OUTPUT_OFF,
++ VIN_OUTPUT_RESERVED,
++ VIN_OUTPUT_SINGLE,
++ VIN_OUTPUT_CONTINUOUS,
++ VIN_OUTPUT_IDLE,
++ VIN_OUTPUT_STOPPING
++};
++
++struct vin_output {
++ int active_buf;
++ struct stfcamss_buffer *buf[2];
++ struct stfcamss_buffer *last_buffer;
++ struct list_head pending_bufs;
++ struct list_head ready_bufs;
++ enum vin_output_state state;
++ unsigned int sequence;
++ unsigned int frame_skip;
++};
++
++/* The vin output lines include all isp controller lines,
++ * and one vin_wr output line.
++ */
++enum vin_line_id {
++ VIN_LINE_NONE = -1,
++ VIN_LINE_WR = 0,
++ VIN_LINE_ISP = 1,
++ VIN_LINE_ISP_SS0 = 2,
++ VIN_LINE_ISP_SS1 = 3,
++ VIN_LINE_ISP_ITIW = 4,
++ VIN_LINE_ISP_ITIR = 5,
++ VIN_LINE_ISP_RAW = 6,
++ VIN_LINE_ISP_SCD_Y = 7,
++ VIN_LINE_MAX = 8,
++};
++
++enum subdev_type;
++
++struct vin_line {
++ enum subdev_type sdev_type; // must be frist
++ enum vin_line_id id;
++ struct v4l2_subdev subdev;
++ struct media_pad pads[STF_VIN_PADS_NUM];
++ struct v4l2_mbus_framefmt fmt[STF_VIN_PADS_NUM];
++ struct stfcamss_video video_out;
++ struct mutex stream_lock;
++ int stream_count;
++ struct mutex power_lock;
++ int power_count;
++ struct vin_output output;
++ spinlock_t output_lock;
++ const struct vin2_format *formats;
++ unsigned int nformats;
++#ifdef CONFIG_PM_SLEEP
++ int pm_stream_count;
++ int pm_power_count;
++#endif
++};
++
++struct stf_vin2_dev;
++
++struct vin_hw_ops {
++ int (*vin_clk_enable)(struct stf_vin2_dev *vin_dev);
++ int (*vin_clk_disable)(struct stf_vin2_dev *vin_dev);
++ int (*vin_config_set)(struct stf_vin2_dev *vin_dev);
++ int (*vin_wr_stream_set)(struct stf_vin2_dev *vin_dev, int on);
++ void (*vin_wr_irq_enable)(struct stf_vin2_dev *vin_dev, int enable);
++ void (*vin_power_on)(struct stf_vin2_dev *vin_dev, int on);
++ void (*wr_rd_set_addr)(struct stf_vin2_dev *vin_dev,
++ dma_addr_t wr_addr, dma_addr_t rd_addr);
++ void (*vin_wr_set_ping_addr)(struct stf_vin2_dev *vin_dev,
++ dma_addr_t addr);
++ void (*vin_wr_set_pong_addr)(struct stf_vin2_dev *vin_dev,
++ dma_addr_t addr);
++ void (*vin_wr_get_ping_pong_status)(struct stf_vin2_dev *vin_dev);
++ void (*vin_isp_set_yuv_addr)(struct stf_vin2_dev *vin_dev,
++ dma_addr_t y_addr, dma_addr_t uv_addr);
++ void (*vin_isp_set_raw_addr)(struct stf_vin2_dev *vin_dev,
++ dma_addr_t raw_addr);
++ void (*vin_isp_set_ss0_addr)(struct stf_vin2_dev *vin_dev,
++ dma_addr_t y_addr, dma_addr_t uv_addr);
++ void (*vin_isp_set_ss1_addr)(struct stf_vin2_dev *vin_dev,
++ dma_addr_t y_addr, dma_addr_t uv_addr);
++ void (*vin_isp_set_itiw_addr)(struct stf_vin2_dev *vin_dev,
++ dma_addr_t y_addr, dma_addr_t uv_addr);
++ void (*vin_isp_set_itir_addr)(struct stf_vin2_dev *vin_dev,
++ dma_addr_t y_addr, dma_addr_t uv_addr);
++ void (*vin_isp_set_scd_addr)(struct stf_vin2_dev *vin_dev,
++ dma_addr_t yhist_addr,
++ dma_addr_t scd_addr, int scd_type);
++ int (*vin_isp_get_scd_type)(struct stf_vin2_dev *vin_dev);
++ irqreturn_t (*vin_wr_irq_handler)(int irq, void *priv);
++ irqreturn_t (*vin_isp_irq_handler)(int irq, void *priv);
++ irqreturn_t (*vin_isp_csi_irq_handler)(int irq, void *priv);
++ irqreturn_t (*vin_isp_scd_irq_handler)(int irq, void *priv);
++ irqreturn_t (*vin_isp_irq_csiline_handler)(int irq, void *priv);
++ void (*isr_buffer_done)(struct vin_line *line,
++ struct vin_params *params);
++ void (*isr_change_buffer)(struct vin_line *line);
++};
++
++#define ISP_DUMMY_BUFFER_NUMS STF_ISP_PAD_MAX
++#define VIN_DUMMY_BUFFER_NUMS 1
++
++enum {
++ STF_DUMMY_VIN,
++ STF_DUMMY_ISP,
++ STF_DUMMY_MODULE_NUMS,
++};
++
++struct vin_dummy_buffer {
++ dma_addr_t paddr[3];
++ void *vaddr;
++ u32 buffer_size;
++ u32 width;
++ u32 height;
++ u32 mcode;
++};
++
++struct dummy_buffer {
++ struct vin_dummy_buffer *buffer;
++ u32 nums;
++ struct mutex stream_lock;
++ int stream_count;
++ atomic_t frame_skip;
++};
++
++struct stf_vin2_dev {
++ struct stfcamss *stfcamss;
++ struct vin_line line[VIN_LINE_MAX];
++ struct dummy_buffer dummy_buffer[STF_DUMMY_MODULE_NUMS];
++ struct vin_hw_ops *hw_ops;
++ atomic_t ref_count;
++ struct mutex power_lock;
++ int power_count;
++};
++
++extern void sifive_l2_flush64_range(unsigned long start, unsigned long len);
++extern int stf_vin_subdev_init(struct stfcamss *stfcamss);
++extern int stf_vin_register(struct stf_vin2_dev *vin_dev,
++ struct v4l2_device *v4l2_dev);
++extern int stf_vin_unregister(struct stf_vin2_dev *vin_dev);
++
++extern struct vin_hw_ops vin_ops;
++extern void dump_vin_reg(void *__iomem regbase);
++extern enum isp_pad_id stf_vin_map_isp_pad(enum vin_line_id line,
++ enum isp_pad_id def);
++
++#endif /* STF_VIN_H */
+--- /dev/null
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_vin_hw_ops.c
+@@ -0,0 +1,433 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
++ *
++ */
++
++#include "stfcamss.h"
++#include <linux/of_graph.h>
++#include <media/v4l2-async.h>
++#include <media/v4l2-fwnode.h>
++#include <media/v4l2-subdev.h>
++
++static void vin_intr_clear(void __iomem *sysctrl_base)
++{
++ reg_set_bit(sysctrl_base, SYSCONSAIF_SYSCFG_28,
++ U0_VIN_CNFG_AXIWR0_INTR_CLEAN,
++ 0x1);
++ reg_set_bit(sysctrl_base, SYSCONSAIF_SYSCFG_28,
++ U0_VIN_CNFG_AXIWR0_INTR_CLEAN,
++ 0x0);
++}
++
++static irqreturn_t stf_vin_wr_irq_handler(int irq, void *priv)
++{
++ static struct vin_params params;
++ struct stf_vin2_dev *vin_dev = priv;
++ struct stf_vin_dev *vin = vin_dev->stfcamss->vin;
++ struct dummy_buffer *dummy_buffer =
++ &vin_dev->dummy_buffer[STF_DUMMY_VIN];
++
++ if (atomic_dec_if_positive(&dummy_buffer->frame_skip) < 0) {
++ vin_dev->hw_ops->isr_change_buffer(&vin_dev->line[VIN_LINE_WR]);
++ vin_dev->hw_ops->isr_buffer_done(&vin_dev->line[VIN_LINE_WR], &params);
++ }
++
++ vin_intr_clear(vin->sysctrl_base);
++
++ return IRQ_HANDLED;
++}
++
++static void __iomem *stf_vin_get_ispbase(struct stf_vin_dev *vin)
++{
++ void __iomem *base = vin->isp_base;
++
++ return base;
++}
++
++static irqreturn_t stf_vin_isp_irq_handler(int irq, void *priv)
++{
++ static struct vin_params params;
++ struct stf_vin2_dev *vin_dev = priv;
++ struct stf_vin_dev *vin = vin_dev->stfcamss->vin;
++ void __iomem *ispbase;
++ u32 int_status, value;
++
++ ispbase = stf_vin_get_ispbase(vin);
++
++ int_status = reg_read(ispbase, ISP_REG_ISP_CTRL_0);
++
++ if (int_status & BIT(24)) {
++ if ((int_status & BIT(11)))
++ vin_dev->hw_ops->isr_buffer_done(
++ &vin_dev->line[VIN_LINE_ISP_SS0], &params);
++
++ if ((int_status & BIT(12)))
++ vin_dev->hw_ops->isr_buffer_done(
++ &vin_dev->line[VIN_LINE_ISP_SS1], &params);
++
++ if ((int_status & BIT(20)))
++ vin_dev->hw_ops->isr_buffer_done(
++ &vin_dev->line[VIN_LINE_ISP], &params);
++
++ value = reg_read(ispbase, ISP_REG_ITIDPSR);
++ if ((value & BIT(17)))
++ vin_dev->hw_ops->isr_buffer_done(
++ &vin_dev->line[VIN_LINE_ISP_ITIW], &params);
++ if ((value & BIT(16)))
++ vin_dev->hw_ops->isr_buffer_done(
++ &vin_dev->line[VIN_LINE_ISP_ITIR], &params);
++
++#ifndef ISP_USE_CSI_AND_SC_DONE_INTERRUPT
++ if (int_status & BIT(25))
++ vin_dev->hw_ops->isr_buffer_done(
++ &vin_dev->line[VIN_LINE_ISP_RAW], &params);
++
++ if (int_status & BIT(26))
++ vin_dev->hw_ops->isr_buffer_done(
++ &vin_dev->line[VIN_LINE_ISP_SCD_Y], &params);
++
++ /* clear interrupt */
++ reg_write(ispbase, ISP_REG_ISP_CTRL_0, (int_status & ~EN_INT_ALL)
++ | EN_INT_ISP_DONE | EN_INT_CSI_DONE | EN_INT_SC_DONE);
++#else
++ /* clear interrupt */
++ reg_write(ispbase, ISP_REG_ISP_CTRL_0,
++ (int_status & ~EN_INT_ALL) | EN_INT_ISP_DONE);
++#endif
++ } else
++ st_debug(ST_VIN, "%s, Unknown interrupt!!!\n", __func__);
++
++ return IRQ_HANDLED;
++}
++
++static irqreturn_t stf_vin_isp_csi_irq_handler(int irq, void *priv)
++{
++ static struct vin_params params;
++ struct stf_vin2_dev *vin_dev = priv;
++ struct stf_vin_dev *vin = vin_dev->stfcamss->vin;
++ void __iomem *ispbase;
++ u32 int_status;
++
++ ispbase = stf_vin_get_ispbase(vin);
++
++ int_status = reg_read(ispbase, ISP_REG_ISP_CTRL_0);
++
++ if (int_status & BIT(25)) {
++ vin_dev->hw_ops->isr_buffer_done(
++ &vin_dev->line[VIN_LINE_ISP_RAW], &params);
++
++ /* clear interrupt */
++ reg_write(ispbase, ISP_REG_ISP_CTRL_0,
++ (int_status & ~EN_INT_ALL) | EN_INT_CSI_DONE);
++ } else
++ st_debug(ST_VIN, "%s, Unknown interrupt!!!\n", __func__);
++
++ return IRQ_HANDLED;
++}
++
++static irqreturn_t stf_vin_isp_scd_irq_handler(int irq, void *priv)
++{
++ static struct vin_params params;
++ struct stf_vin2_dev *vin_dev = priv;
++ struct stf_vin_dev *vin = vin_dev->stfcamss->vin;
++ void __iomem *ispbase;
++ u32 int_status;
++
++ ispbase = stf_vin_get_ispbase(vin);
++
++ int_status = reg_read(ispbase, ISP_REG_ISP_CTRL_0);
++
++ if (int_status & BIT(26)) {
++ vin_dev->hw_ops->isr_buffer_done(
++ &vin_dev->line[VIN_LINE_ISP_SCD_Y], &params);
++
++ /* clear interrupt */
++ reg_write(ispbase, ISP_REG_ISP_CTRL_0, (int_status & ~EN_INT_ALL) | EN_INT_SC_DONE);
++ } else
++ st_debug(ST_VIN, "%s, Unknown interrupt!!!\n", __func__);
++
++ return IRQ_HANDLED;
++}
++
++static irqreturn_t stf_vin_isp_irq_csiline_handler(int irq, void *priv)
++{
++ struct stf_vin2_dev *vin_dev = priv;
++ struct stf_vin_dev *vin = vin_dev->stfcamss->vin;
++ struct stf_isp_dev *isp_dev;
++ void __iomem *ispbase;
++ u32 int_status, value;
++
++ ispbase = stf_vin_get_ispbase(vin);
++
++ isp_dev = vin_dev->stfcamss->isp_dev;
++
++ int_status = reg_read(ispbase, ISP_REG_ISP_CTRL_0);
++ if (int_status & BIT(27)) {
++ struct dummy_buffer *dummy_buffer =
++ &vin_dev->dummy_buffer[STF_DUMMY_ISP];
++
++ if (!atomic_read(&isp_dev->shadow_count)) {
++ if (atomic_dec_if_positive(&dummy_buffer->frame_skip) < 0) {
++ if ((int_status & BIT(11)))
++ vin_dev->hw_ops->isr_change_buffer(
++ &vin_dev->line[VIN_LINE_ISP_SS0]);
++ if ((int_status & BIT(12)))
++ vin_dev->hw_ops->isr_change_buffer(
++ &vin_dev->line[VIN_LINE_ISP_SS1]);
++ if ((int_status & BIT(20)))
++ vin_dev->hw_ops->isr_change_buffer(
++ &vin_dev->line[VIN_LINE_ISP]);
++
++ value = reg_read(ispbase, ISP_REG_ITIDPSR);
++ if ((value & BIT(17)))
++ vin_dev->hw_ops->isr_change_buffer(
++ &vin_dev->line[VIN_LINE_ISP_ITIW]);
++ if ((value & BIT(16)))
++ vin_dev->hw_ops->isr_change_buffer(
++ &vin_dev->line[VIN_LINE_ISP_ITIR]);
++
++ value = reg_read(ispbase, ISP_REG_CSI_MODULE_CFG);
++ if ((value & BIT(19)))
++ vin_dev->hw_ops->isr_change_buffer(
++ &vin_dev->line[VIN_LINE_ISP_RAW]);
++ if ((value & BIT(17)))
++ vin_dev->hw_ops->isr_change_buffer(
++ &vin_dev->line[VIN_LINE_ISP_SCD_Y]);
++ }
++
++ // shadow update
++ reg_set_bit(ispbase, ISP_REG_CSIINTS_ADDR, 0x30000, 0x30000);
++ reg_set_bit(ispbase, ISP_REG_IESHD_ADDR, BIT(1) | BIT(0), 0x3);
++ } else {
++ st_warn(ST_VIN, "isp shadow_lock locked. skip this frame\n");
++ }
++
++ /* clear interrupt */
++ reg_write(ispbase, ISP_REG_ISP_CTRL_0,
++ (int_status & ~EN_INT_ALL) | EN_INT_LINE_INT);
++ } else
++ st_debug(ST_VIN, "%s, Unknown interrupt!!!\n", __func__);
++
++ return IRQ_HANDLED;
++}
++
++static int stf_vin_clk_enable(struct stf_vin2_dev *vin_dev)
++{
++ struct stfcamss *stfcamss = vin_dev->stfcamss;
++
++ clk_prepare_enable(stfcamss->sys_clk[STFCLK_PCLK].clk);
++ clk_set_rate(stfcamss->sys_clk[STFCLK_APB_FUNC].clk, 49500000);
++ clk_set_rate(stfcamss->sys_clk[STFCLK_SYS_CLK].clk, 297000000);
++
++ reset_control_deassert(stfcamss->sys_rst[STFRST_PCLK].rstc);
++ reset_control_deassert(stfcamss->sys_rst[STFRST_SYS_CLK].rstc);
++
++ return 0;
++}
++
++
++static int stf_vin_clk_disable(struct stf_vin2_dev *vin_dev)
++{
++ struct stfcamss *stfcamss = vin_dev->stfcamss;
++
++ reset_control_assert(stfcamss->sys_rst[STFRST_PCLK].rstc);
++ reset_control_assert(stfcamss->sys_rst[STFRST_SYS_CLK].rstc);
++
++ clk_disable_unprepare(stfcamss->sys_clk[STFCLK_PCLK].clk);
++
++ return 0;
++}
++
++static int stf_vin_config_set(struct stf_vin2_dev *vin_dev)
++{
++ return 0;
++}
++
++static int stf_vin_wr_stream_set(struct stf_vin2_dev *vin_dev, int on)
++{
++ struct stf_vin_dev *vin = vin_dev->stfcamss->vin;
++
++ //make the axiwr alway on
++ if (on)
++ reg_set(vin->sysctrl_base, SYSCONSAIF_SYSCFG_20, U0_VIN_CNFG_AXIWR0_EN);
++
++ return 0;
++}
++
++static void stf_vin_wr_irq_enable(struct stf_vin2_dev *vin_dev,
++ int enable)
++{
++ struct stf_vin_dev *vin = vin_dev->stfcamss->vin;
++ unsigned int value = 0;
++
++ if (enable) {
++ value = ~(0x1 << 1);
++ reg_set_bit(vin->sysctrl_base, SYSCONSAIF_SYSCFG_28,
++ U0_VIN_CNFG_AXIWR0_MASK,
++ value);
++ } else {
++ /* clear vin interrupt */
++ value = 0x1 << 1;
++ reg_set_bit(vin->sysctrl_base, SYSCONSAIF_SYSCFG_28,
++ U0_VIN_CNFG_AXIWR0_INTR_CLEAN,
++ 0x1);
++ reg_set_bit(vin->sysctrl_base, SYSCONSAIF_SYSCFG_28,
++ U0_VIN_CNFG_AXIWR0_INTR_CLEAN,
++ 0x0);
++ reg_set_bit(vin->sysctrl_base, SYSCONSAIF_SYSCFG_28,
++ U0_VIN_CNFG_AXIWR0_MASK,
++ value);
++ }
++}
++
++static void stf_vin_wr_rd_set_addr(struct stf_vin2_dev *vin_dev,
++ dma_addr_t wr_addr, dma_addr_t rd_addr)
++{
++#ifdef UNUSED_CODE
++ struct stf_vin_dev *vin = vin_dev->stfcamss->vin;
++
++ /* set the start address*/
++ reg_write(vin->sysctrl_base,
++ SYSCTRL_VIN_WR_START_ADDR, (long)wr_addr);
++ reg_write(vin->sysctrl_base,
++ SYSCTRL_VIN_RD_END_ADDR, (long)rd_addr);
++#endif
++}
++
++void stf_vin_wr_set_ping_addr(struct stf_vin2_dev *vin_dev,
++ dma_addr_t addr)
++{
++ struct stf_vin_dev *vin = vin_dev->stfcamss->vin;
++
++ /* set the start address */
++ reg_write(vin->sysctrl_base, SYSCONSAIF_SYSCFG_24, (long)addr);
++}
++
++void stf_vin_wr_set_pong_addr(struct stf_vin2_dev *vin_dev, dma_addr_t addr)
++{
++ struct stf_vin_dev *vin = vin_dev->stfcamss->vin;
++
++ /* set the start address */
++ reg_write(vin->sysctrl_base, SYSCONSAIF_SYSCFG_32, (long)addr);
++}
++
++void stf_vin_isp_set_yuv_addr(struct stf_vin2_dev *vin_dev,
++ dma_addr_t y_addr, dma_addr_t uv_addr)
++{
++
++ struct stf_vin_dev *vin = vin_dev->stfcamss->vin;
++ void __iomem *ispbase = stf_vin_get_ispbase(vin);
++
++ reg_write(ispbase, ISP_REG_Y_PLANE_START_ADDR, y_addr);
++ reg_write(ispbase, ISP_REG_UV_PLANE_START_ADDR, uv_addr);
++ // reg_set_bit(ispbase, ISP_REG_ISP_CTRL_0, BIT(0), 1);
++}
++
++void stf_vin_isp_set_raw_addr(struct stf_vin2_dev *vin_dev,
++ dma_addr_t raw_addr)
++{
++ struct stf_vin_dev *vin = vin_dev->stfcamss->vin;
++ void __iomem *ispbase = stf_vin_get_ispbase(vin);
++
++ reg_write(ispbase, ISP_REG_DUMP_CFG_0, raw_addr);
++}
++
++void stf_vin_isp_set_ss0_addr(struct stf_vin2_dev *vin_dev,
++ dma_addr_t y_addr, dma_addr_t uv_addr)
++{
++ struct stf_vin_dev *vin = vin_dev->stfcamss->vin;
++ void __iomem *ispbase = stf_vin_get_ispbase(vin);
++
++ reg_write(ispbase, ISP_REG_SS0AY, y_addr);
++ reg_write(ispbase, ISP_REG_SS0AUV, uv_addr);
++}
++
++void stf_vin_isp_set_ss1_addr(struct stf_vin2_dev *vin_dev,
++ dma_addr_t y_addr, dma_addr_t uv_addr)
++{
++ struct stf_vin_dev *vin = vin_dev->stfcamss->vin;
++ void __iomem *ispbase = stf_vin_get_ispbase(vin);
++
++ reg_write(ispbase, ISP_REG_SS1AY, y_addr);
++ reg_write(ispbase, ISP_REG_SS1AUV, uv_addr);
++}
++
++void stf_vin_isp_set_itiw_addr(struct stf_vin2_dev *vin_dev,
++ dma_addr_t y_addr, dma_addr_t uv_addr)
++{
++ struct stf_vin_dev *vin = vin_dev->stfcamss->vin;
++ void __iomem *ispbase = stf_vin_get_ispbase(vin);
++
++ reg_write(ispbase, ISP_REG_ITIDWYSAR, y_addr);
++ reg_write(ispbase, ISP_REG_ITIDWUSAR, uv_addr);
++}
++
++void stf_vin_isp_set_itir_addr(struct stf_vin2_dev *vin_dev,
++ dma_addr_t y_addr, dma_addr_t uv_addr)
++{
++ struct stf_vin_dev *vin = vin_dev->stfcamss->vin;
++ void __iomem *ispbase = stf_vin_get_ispbase(vin);
++
++ reg_write(ispbase, ISP_REG_ITIDRYSAR, y_addr);
++ reg_write(ispbase, ISP_REG_ITIDRUSAR, uv_addr);
++}
++
++int stf_vin_isp_get_scd_type(struct stf_vin2_dev *vin_dev)
++{
++ struct stf_vin_dev *vin = vin_dev->stfcamss->vin;
++ void __iomem *ispbase = stf_vin_get_ispbase(vin);
++
++ return (reg_read(ispbase, ISP_REG_SC_CFG_1) & (0x3 << 30)) >> 30;
++}
++
++void stf_vin_isp_set_scd_addr(struct stf_vin2_dev *vin_dev,
++ dma_addr_t yhist_addr, dma_addr_t scd_addr, int scd_type)
++{
++ struct stf_vin_dev *vin = vin_dev->stfcamss->vin;
++ void __iomem *ispbase = stf_vin_get_ispbase(vin);
++
++ reg_set_bit(ispbase, ISP_REG_SC_CFG_1, 0x3 << 30, scd_type << 30);
++ reg_write(ispbase, ISP_REG_SCD_CFG_0, scd_addr);
++ reg_write(ispbase, ISP_REG_YHIST_CFG_4, yhist_addr);
++}
++
++void dump_vin_reg(void *__iomem regbase)
++{
++ st_debug(ST_VIN, "DUMP VIN register:\n");
++ print_reg(ST_VIN, regbase, 0x00);
++ print_reg(ST_VIN, regbase, 0x04);
++ print_reg(ST_VIN, regbase, 0x08);
++ print_reg(ST_VIN, regbase, 0x0c);
++ print_reg(ST_VIN, regbase, 0x10);
++ print_reg(ST_VIN, regbase, 0x14);
++ print_reg(ST_VIN, regbase, 0x18);
++ print_reg(ST_VIN, regbase, 0x1c);
++ print_reg(ST_VIN, regbase, 0x20);
++ print_reg(ST_VIN, regbase, 0x24);
++ print_reg(ST_VIN, regbase, 0x28);
++}
++
++struct vin_hw_ops vin_ops = {
++ .vin_clk_enable = stf_vin_clk_enable,
++ .vin_clk_disable = stf_vin_clk_disable,
++ .vin_config_set = stf_vin_config_set,
++ .vin_wr_stream_set = stf_vin_wr_stream_set,
++ .vin_wr_irq_enable = stf_vin_wr_irq_enable,
++ .wr_rd_set_addr = stf_vin_wr_rd_set_addr,
++ .vin_wr_set_ping_addr = stf_vin_wr_set_ping_addr,
++ .vin_wr_set_pong_addr = stf_vin_wr_set_pong_addr,
++ .vin_isp_set_yuv_addr = stf_vin_isp_set_yuv_addr,
++ .vin_isp_set_raw_addr = stf_vin_isp_set_raw_addr,
++ .vin_isp_set_ss0_addr = stf_vin_isp_set_ss0_addr,
++ .vin_isp_set_ss1_addr = stf_vin_isp_set_ss1_addr,
++ .vin_isp_set_itiw_addr = stf_vin_isp_set_itiw_addr,
++ .vin_isp_set_itir_addr = stf_vin_isp_set_itir_addr,
++ .vin_isp_set_scd_addr = stf_vin_isp_set_scd_addr,
++ .vin_isp_get_scd_type = stf_vin_isp_get_scd_type,
++ .vin_wr_irq_handler = stf_vin_wr_irq_handler,
++ .vin_isp_irq_handler = stf_vin_isp_irq_handler,
++ .vin_isp_csi_irq_handler = stf_vin_isp_csi_irq_handler,
++ .vin_isp_scd_irq_handler = stf_vin_isp_scd_irq_handler,
++ .vin_isp_irq_csiline_handler = stf_vin_isp_irq_csiline_handler,
++};
+--- /dev/null
++++ b/drivers/media/platform/starfive/v4l2_driver/stfcamss.c
+@@ -0,0 +1,1369 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
++ *
++ */
++
++#include <linux/completion.h>
++#include <linux/delay.h>
++#include <linux/dmaengine.h>
++#include <linux/init.h>
++#include <linux/interrupt.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/of_device.h>
++#include <linux/of_reserved_mem.h>
++#include <linux/of_graph.h>
++#include <linux/of_address.h>
++#include <linux/pinctrl/consumer.h>
++#include <linux/platform_device.h>
++#include <linux/pm_runtime.h>
++#include <linux/io.h>
++#include <linux/dma-mapping.h>
++#include <linux/uaccess.h>
++#include <linux/mfd/syscon.h>
++
++#include <linux/videodev2.h>
++
++#include <media/media-device.h>
++#include <media/v4l2-async.h>
++#include <media/v4l2-device.h>
++#include <media/v4l2-mc.h>
++#include <media/v4l2-fwnode.h>
++#include <linux/debugfs.h>
++
++#include "stfcamss.h"
++
++#ifdef STF_DEBUG
++unsigned int stdbg_level = ST_DEBUG;
++unsigned int stdbg_mask = 0x7F;
++#else
++unsigned int stdbg_level = ST_ERR;
++unsigned int stdbg_mask = 0x7F;
++#endif
++EXPORT_SYMBOL_GPL(stdbg_level);
++EXPORT_SYMBOL_GPL(stdbg_mask);
++
++static const struct reg_name mem_reg_name[] = {
++ {"csi2rx"},
++ {"vclk"},
++ {"vrst"},
++ {"sctrl"},
++ {"isp"},
++ {"trst"},
++ {"pmu"},
++ {"syscrg"},
++};
++
++static struct clk_bulk_data stfcamss_clocks[] = {
++ { .id = "clk_apb_func" },
++ { .id = "clk_pclk" },
++ { .id = "clk_sys_clk" },
++ { .id = "clk_wrapper_clk_c" },
++ { .id = "clk_dvp_inv" },
++ { .id = "clk_axiwr" },
++ { .id = "clk_mipi_rx0_pxl" },
++ { .id = "clk_pixel_clk_if0" },
++ { .id = "clk_pixel_clk_if1" },
++ { .id = "clk_pixel_clk_if2" },
++ { .id = "clk_pixel_clk_if3" },
++ { .id = "clk_m31dphy_cfgclk_in" },
++ { .id = "clk_m31dphy_refclk_in" },
++ { .id = "clk_m31dphy_txclkesc_lan0" },
++ { .id = "clk_ispcore_2x" },
++ { .id = "clk_isp_axi" },
++};
++
++static struct reset_control_bulk_data stfcamss_resets[] = {
++ { .id = "rst_wrapper_p" },
++ { .id = "rst_wrapper_c" },
++ { .id = "rst_pclk" },
++ { .id = "rst_sys_clk" },
++ { .id = "rst_axird" },
++ { .id = "rst_axiwr" },
++ { .id = "rst_pixel_clk_if0" },
++ { .id = "rst_pixel_clk_if1" },
++ { .id = "rst_pixel_clk_if2" },
++ { .id = "rst_pixel_clk_if3" },
++ { .id = "rst_m31dphy_hw" },
++ { .id = "rst_m31dphy_b09_always_on" },
++ { .id = "rst_isp_top_n" },
++ { .id = "rst_isp_top_axi" },
++};
++
++int stfcamss_get_mem_res(struct platform_device *pdev, struct stf_vin_dev *vin)
++{
++ struct device *dev = &pdev->dev;
++ struct resource *res;
++ char *name;
++ int i;
++
++ for (i = 0; i < ARRAY_SIZE(mem_reg_name); i++) {
++ name = (char *)(&mem_reg_name[i]);
++ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name);
++
++ if (!res)
++ return -EINVAL;
++
++ if (!strcmp(name, "csi2rx")) {
++ vin->csi2rx_base = devm_ioremap_resource(dev, res);
++ if (IS_ERR(vin->csi2rx_base))
++ return PTR_ERR(vin->csi2rx_base);
++ } else if (!strcmp(name, "vclk")) {
++ vin->clkgen_base = ioremap(res->start, resource_size(res));
++ if (!vin->clkgen_base)
++ return -ENOMEM;
++ } else if (!strcmp(name, "vrst")) {
++ vin->rstgen_base = devm_ioremap_resource(dev, res);
++ if (IS_ERR(vin->rstgen_base))
++ return PTR_ERR(vin->rstgen_base);
++ } else if (!strcmp(name, "sctrl")) {
++ vin->sysctrl_base = devm_ioremap_resource(dev, res);
++ if (IS_ERR(vin->sysctrl_base))
++ return PTR_ERR(vin->sysctrl_base);
++ } else if (!strcmp(name, "isp")) {
++ vin->isp_base = devm_ioremap_resource(dev, res);
++ if (IS_ERR(vin->isp_base))
++ return PTR_ERR(vin->isp_base);
++ } else if (!strcmp(name, "trst")) {
++ vin->vin_top_rstgen_base = devm_ioremap_resource(dev, res);
++ if (IS_ERR(vin->vin_top_rstgen_base))
++ return PTR_ERR(vin->vin_top_rstgen_base);
++ } else if (!strcmp(name, "pmu")) {
++ vin->pmu_test = ioremap(res->start, resource_size(res));
++ if (!vin->pmu_test)
++ return -ENOMEM;
++ } else if (!strcmp(name, "syscrg")) {
++ vin->sys_crg = ioremap(res->start, resource_size(res));
++ if (!vin->sys_crg)
++ return -ENOMEM;
++ } else {
++ st_err(ST_CAMSS, "Could not match resource name\n");
++ }
++ }
++
++ return 0;
++}
++
++int vin_parse_dt(struct device *dev, struct stf_vin_dev *vin)
++{
++ int ret = 0;
++ struct device_node *np = dev->of_node;
++
++ if (!np)
++ return -EINVAL;
++
++ return ret;
++}
++
++struct media_entity *stfcamss_find_sensor(struct media_entity *entity)
++{
++ struct media_pad *pad;
++
++ while (1) {
++ if (!entity->pads)
++ return NULL;
++
++ pad = &entity->pads[0];
++ if (!(pad->flags & MEDIA_PAD_FL_SINK))
++ return NULL;
++
++ pad = media_pad_remote_pad_first(pad);
++ if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
++ return NULL;
++
++ entity = pad->entity;
++
++ if (entity->function == MEDIA_ENT_F_CAM_SENSOR)
++ return entity;
++ }
++}
++
++static int stfcamss_of_parse_endpoint_node(struct device *dev,
++ struct device_node *node,
++ struct stfcamss_async_subdev *csd)
++{
++ struct v4l2_fwnode_endpoint vep = { { 0 } };
++ struct v4l2_mbus_config_parallel *parallel_bus = &vep.bus.parallel;
++ struct v4l2_mbus_config_mipi_csi2 *csi2_bus = &vep.bus.mipi_csi2;
++ struct dvp_cfg *dvp = &csd->interface.dvp;
++ struct csi2phy_cfg *csiphy = &csd->interface.csiphy;
++
++ v4l2_fwnode_endpoint_parse(of_fwnode_handle(node), &vep);
++ st_debug(ST_CAMSS, "%s: vep.base.port = 0x%x, id = 0x%x\n",
++ __func__, vep.base.port, vep.base.id);
++
++ csd->port = vep.base.port;
++ switch (csd->port) {
++ case DVP_SENSOR_PORT_NUMBER:
++ st_debug(ST_CAMSS, "%s, flags = 0x%x\n", __func__,
++ parallel_bus->flags);
++ dvp->flags = parallel_bus->flags;
++ dvp->bus_width = parallel_bus->bus_width;
++ dvp->data_shift = parallel_bus->data_shift;
++ break;
++ case CSI2RX_SENSOR_PORT_NUMBER:
++ st_debug(ST_CAMSS, "%s, CSI2 flags = 0x%x\n",
++ __func__, parallel_bus->flags);
++ csiphy->flags = csi2_bus->flags;
++ memcpy(csiphy->data_lanes,
++ csi2_bus->data_lanes, csi2_bus->num_data_lanes);
++ csiphy->clock_lane = csi2_bus->clock_lane;
++ csiphy->num_data_lanes = csi2_bus->num_data_lanes;
++ memcpy(csiphy->lane_polarities,
++ csi2_bus->lane_polarities,
++ csi2_bus->num_data_lanes + 1);
++ break;
++ default:
++ break;
++ };
++
++ return 0;
++}
++
++static int stfcamss_of_parse_ports(struct stfcamss *stfcamss)
++{
++ struct device *dev = stfcamss->dev;
++ struct device_node *node = NULL;
++ struct device_node *remote = NULL;
++ int ret, num_subdevs = 0;
++
++ for_each_endpoint_of_node(dev->of_node, node) {
++ struct stfcamss_async_subdev *csd;
++
++ if (!of_device_is_available(node))
++ continue;
++
++ remote = of_graph_get_remote_port_parent(node);
++ if (!remote) {
++ st_err(ST_CAMSS, "Cannot get remote parent\n");
++ ret = -EINVAL;
++ goto err_cleanup;
++ }
++
++ csd = v4l2_async_nf_add_fwnode(&stfcamss->notifier,
++ of_fwnode_handle(remote),
++ struct stfcamss_async_subdev);
++ of_node_put(remote);
++ if (IS_ERR(csd)) {
++ ret = PTR_ERR(csd);
++ goto err_cleanup;
++ }
++
++ ret = stfcamss_of_parse_endpoint_node(dev, node, csd);
++ if (ret < 0)
++ goto err_cleanup;
++
++ num_subdevs++;
++ }
++
++ return num_subdevs;
++
++err_cleanup:
++ of_node_put(node);
++ return ret;
++}
++
++static int stfcamss_init_subdevices(struct stfcamss *stfcamss)
++{
++ int ret;
++
++ ret = stf_dvp_subdev_init(stfcamss);
++ if (ret < 0) {
++ st_err(ST_CAMSS,
++ "Failed to init stf_dvp sub-device: %d\n",
++ ret);
++ return ret;
++ }
++
++ ret = stf_csiphy_subdev_init(stfcamss);
++ if (ret < 0) {
++ st_err(ST_CAMSS,
++ "Failed to init stf_csiphy sub-device: %d\n",
++ ret);
++ return ret;
++ }
++
++ ret = stf_csi_subdev_init(stfcamss);
++ if (ret < 0) {
++ st_err(ST_CAMSS,
++ "Failed to init stf_csi sub-device: %d\n",
++ ret);
++ return ret;
++ }
++
++ ret = stf_isp_subdev_init(stfcamss);
++ if (ret < 0) {
++ st_err(ST_CAMSS,
++ "Failed to init stf_isp sub-device: %d\n",
++ ret);
++ return ret;
++ }
++
++ ret = stf_vin_subdev_init(stfcamss);
++ if (ret < 0) {
++ st_err(ST_CAMSS,
++ "Failed to init stf_vin sub-device: %d\n",
++ ret);
++ return ret;
++ }
++ return ret;
++}
++
++static int stfcamss_register_subdevices(struct stfcamss *stfcamss)
++{
++ int ret;
++ struct stf_vin2_dev *vin_dev = stfcamss->vin_dev;
++ struct stf_dvp_dev *dvp_dev = stfcamss->dvp_dev;
++ struct stf_csiphy_dev *csiphy_dev = stfcamss->csiphy_dev;
++ struct stf_csi_dev *csi_dev = stfcamss->csi_dev;
++ struct stf_isp_dev *isp_dev = stfcamss->isp_dev;
++
++ ret = stf_dvp_register(dvp_dev, &stfcamss->v4l2_dev);
++ if (ret < 0) {
++ st_err(ST_CAMSS,
++ "Failed to register stf dvp%d entity: %d\n",
++ 0, ret);
++ goto err_reg_dvp;
++ }
++
++ ret = stf_csiphy_register(csiphy_dev, &stfcamss->v4l2_dev);
++ if (ret < 0) {
++ st_err(ST_CAMSS,
++ "Failed to register stf csiphy%d entity: %d\n",
++ 0, ret);
++ goto err_reg_csiphy;
++ }
++
++ ret = stf_csi_register(csi_dev, &stfcamss->v4l2_dev);
++ if (ret < 0) {
++ st_err(ST_CAMSS,
++ "Failed to register stf csi%d entity: %d\n",
++ 0, ret);
++ goto err_reg_csi;
++ }
++
++ ret = stf_isp_register(isp_dev, &stfcamss->v4l2_dev);
++ if (ret < 0) {
++ st_err(ST_CAMSS,
++ "Failed to register stf isp%d entity: %d\n",
++ 0, ret);
++ goto err_reg_isp;
++ }
++
++ ret = stf_vin_register(vin_dev, &stfcamss->v4l2_dev);
++ if (ret < 0) {
++ st_err(ST_CAMSS,
++ "Failed to register vin entity: %d\n",
++ ret);
++ goto err_reg_vin;
++ }
++
++ ret = media_create_pad_link(
++ &dvp_dev->subdev.entity,
++ STF_DVP_PAD_SRC,
++ &vin_dev->line[VIN_LINE_WR].subdev.entity,
++ STF_VIN_PAD_SINK,
++ 0);
++ if (ret < 0) {
++ st_err(ST_CAMSS,
++ "Failed to link %s->vin entities: %d\n",
++ dvp_dev->subdev.entity.name,
++ ret);
++ goto err_link;
++ }
++
++ ret = media_create_pad_link(
++ &csi_dev->subdev.entity,
++ STF_CSI_PAD_SRC,
++ &vin_dev->line[VIN_LINE_WR].subdev.entity,
++ STF_VIN_PAD_SINK,
++ 0);
++ if (ret < 0) {
++ st_err(ST_CAMSS,
++ "Failed to link %s->vin entities: %d\n",
++ csi_dev->subdev.entity.name,
++ ret);
++ goto err_link;
++ }
++
++ ret = media_create_pad_link(
++ &csiphy_dev->subdev.entity,
++ STF_CSIPHY_PAD_SRC,
++ &csi_dev->subdev.entity,
++ STF_CSI_PAD_SINK,
++ MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED);
++ if (ret < 0) {
++ st_err(ST_CAMSS,
++ "Failed to link %s->%s entities: %d\n",
++ csiphy_dev->subdev.entity.name,
++ csi_dev->subdev.entity.name,
++ ret);
++ goto err_link;
++ }
++
++ ret = media_create_pad_link(
++ &isp_dev->subdev.entity,
++ STF_ISP_PAD_SRC,
++ &vin_dev->line[VIN_LINE_ISP].subdev.entity,
++ STF_VIN_PAD_SINK,
++ 0);
++ if (ret < 0) {
++ st_err(ST_CAMSS,
++ "Failed to link %s->%s entities: %d\n",
++ isp_dev->subdev.entity.name,
++ vin_dev->line[VIN_LINE_ISP]
++ .subdev.entity.name,
++ ret);
++ goto err_link;
++ }
++
++ ret = media_create_pad_link(
++ &isp_dev->subdev.entity,
++ STF_ISP_PAD_SRC_SS0,
++ &vin_dev->line[VIN_LINE_ISP_SS0].subdev.entity,
++ STF_VIN_PAD_SINK,
++ 0);
++ if (ret < 0) {
++ st_err(ST_CAMSS,
++ "Failed to link %s->%s entities: %d\n",
++ isp_dev->subdev.entity.name,
++ vin_dev->line[VIN_LINE_ISP_SS0]
++ .subdev.entity.name,
++ ret);
++ goto err_link;
++ }
++
++ ret = media_create_pad_link(
++ &isp_dev->subdev.entity,
++ STF_ISP_PAD_SRC_SS1,
++ &vin_dev->line[VIN_LINE_ISP_SS1].subdev.entity,
++ STF_VIN_PAD_SINK,
++ 0);
++ if (ret < 0) {
++ st_err(ST_CAMSS,
++ "Failed to link %s->%s entities: %d\n",
++ isp_dev->subdev.entity.name,
++ vin_dev->line[VIN_LINE_ISP_SS1]
++ .subdev.entity.name,
++ ret);
++ goto err_link;
++ }
++
++#ifndef STF_CAMSS_SKIP_ITI
++ ret = media_create_pad_link(
++ &isp_dev->subdev.entity,
++ STF_ISP_PAD_SRC_ITIW,
++ &vin_dev->line[VIN_LINE_ISP_ITIW].subdev.entity,
++ STF_VIN_PAD_SINK,
++ 0);
++ if (ret < 0) {
++ st_err(ST_CAMSS,
++ "Failed to link %s->%s entities: %d\n",
++ isp_dev->subdev.entity.name,
++ vin_dev->line[VIN_LINE_ISP_ITIW]
++ .subdev.entity.name,
++ ret);
++ goto err_link;
++ }
++
++ ret = media_create_pad_link(
++ &isp_dev->subdev.entity,
++ STF_ISP_PAD_SRC_ITIR,
++ &vin_dev->line[VIN_LINE_ISP_ITIR].subdev.entity,
++ STF_VIN_PAD_SINK,
++ 0);
++ if (ret < 0) {
++ st_err(ST_CAMSS,
++ "Failed to link %s->%s entities: %d\n",
++ isp_dev->subdev.entity.name,
++ vin_dev->line[VIN_LINE_ISP_ITIR]
++ .subdev.entity.name,
++ ret);
++ goto err_link;
++ }
++#endif
++
++ ret = media_create_pad_link(
++ &isp_dev->subdev.entity,
++ STF_ISP_PAD_SRC_RAW,
++ &vin_dev->line[VIN_LINE_ISP_RAW].subdev.entity,
++ STF_VIN_PAD_SINK,
++ 0);
++ if (ret < 0) {
++ st_err(ST_CAMSS,
++ "Failed to link %s->%s entities: %d\n",
++ isp_dev->subdev.entity.name,
++ vin_dev->line[VIN_LINE_ISP_RAW]
++ .subdev.entity.name,
++ ret);
++ goto err_link;
++ }
++
++ ret = media_create_pad_link(
++ &isp_dev->subdev.entity,
++ STF_ISP_PAD_SRC_SCD_Y,
++ &vin_dev->line[VIN_LINE_ISP_SCD_Y].subdev.entity,
++ STF_VIN_PAD_SINK,
++ 0);
++ if (ret < 0) {
++ st_err(ST_CAMSS,
++ "Failed to link %s->%s entities: %d\n",
++ isp_dev->subdev.entity.name,
++ vin_dev->line[VIN_LINE_ISP_SCD_Y]
++ .subdev.entity.name,
++ ret);
++ goto err_link;
++ }
++
++ ret = media_create_pad_link(
++ &dvp_dev->subdev.entity,
++ STF_DVP_PAD_SRC,
++ &isp_dev->subdev.entity,
++ STF_ISP_PAD_SINK,
++ 0);
++ if (ret < 0) {
++ st_err(ST_CAMSS,
++ "Failed to link %s->%s entities: %d\n",
++ dvp_dev->subdev.entity.name,
++ isp_dev->subdev.entity.name,
++ ret);
++ goto err_link;
++ }
++
++ ret = media_create_pad_link(
++ &csi_dev->subdev.entity,
++ STF_CSI_PAD_SRC,
++ &isp_dev->subdev.entity,
++ STF_ISP_PAD_SINK,
++ 0);
++ if (ret < 0) {
++ st_err(ST_CAMSS,
++ "Failed to link %s->%s entities: %d\n",
++ csi_dev->subdev.entity.name,
++ isp_dev->subdev.entity.name,
++ ret);
++ goto err_link;
++ }
++
++ return ret;
++
++err_link:
++ stf_vin_unregister(stfcamss->vin_dev);
++err_reg_vin:
++ stf_isp_unregister(stfcamss->isp_dev);
++err_reg_isp:
++ stf_csi_unregister(stfcamss->csi_dev);
++err_reg_csi:
++ stf_csiphy_unregister(stfcamss->csiphy_dev);
++err_reg_csiphy:
++ stf_dvp_unregister(stfcamss->dvp_dev);
++err_reg_dvp:
++ return ret;
++}
++
++static void stfcamss_unregister_subdevices(struct stfcamss *stfcamss)
++{
++ stf_dvp_unregister(stfcamss->dvp_dev);
++ stf_csiphy_unregister(stfcamss->csiphy_dev);
++ stf_csi_unregister(stfcamss->csi_dev);
++ stf_isp_unregister(stfcamss->isp_dev);
++ stf_vin_unregister(stfcamss->vin_dev);
++}
++
++static int stfcamss_register_mediadevice_subdevnodes(
++ struct v4l2_async_notifier *async,
++ struct v4l2_subdev *sd)
++{
++ struct stfcamss *stfcamss =
++ container_of(async, struct stfcamss, notifier);
++ int ret;
++
++ if (sd->host_priv) {
++ struct media_entity *sensor = &sd->entity;
++ struct media_entity *input = sd->host_priv;
++ unsigned int i;
++
++ for (i = 0; i < sensor->num_pads; i++) {
++ if (sensor->pads[i].flags & MEDIA_PAD_FL_SOURCE)
++ break;
++ }
++ if (i == sensor->num_pads) {
++ st_err(ST_CAMSS,
++ "No source pad in external entity\n");
++ return -EINVAL;
++ }
++
++ ret = media_create_pad_link(sensor, i,
++ input, STF_PAD_SINK,
++ MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED);
++ if (ret < 0) {
++ st_err(ST_CAMSS,
++ "Failed to link %s->%s entities: %d\n",
++ sensor->name, input->name, ret);
++ return ret;
++ }
++ }
++
++ ret = v4l2_device_register_subdev_nodes(&stfcamss->v4l2_dev);
++ if (ret < 0)
++ return ret;
++
++ if (stfcamss->media_dev.devnode)
++ return ret;
++
++ st_debug(ST_CAMSS, "stfcamss register media device\n");
++ return media_device_register(&stfcamss->media_dev);
++}
++
++static int stfcamss_subdev_notifier_bound(struct v4l2_async_notifier *async,
++ struct v4l2_subdev *subdev,
++ struct v4l2_async_connection *asd)
++{
++ struct stfcamss *stfcamss =
++ container_of(async, struct stfcamss, notifier);
++ struct stfcamss_async_subdev *csd =
++ container_of(asd, struct stfcamss_async_subdev, asd);
++ enum port_num port = csd->port;
++ struct stf_dvp_dev *dvp_dev = stfcamss->dvp_dev;
++ struct stf_csiphy_dev *csiphy_dev = stfcamss->csiphy_dev;
++
++ switch (port) {
++ case DVP_SENSOR_PORT_NUMBER:
++ dvp_dev->dvp = &csd->interface.dvp;
++ subdev->host_priv = &dvp_dev->subdev.entity;
++ break;
++ case CSI2RX_SENSOR_PORT_NUMBER:
++ csiphy_dev->csiphy = &csd->interface.csiphy;
++ subdev->host_priv = &csiphy_dev->subdev.entity;
++ break;
++ default:
++ break;
++ };
++
++ stfcamss_register_mediadevice_subdevnodes(async, subdev);
++
++ return 0;
++}
++
++#ifdef UNUSED_CODE
++static int stfcamss_subdev_notifier_complete(
++ struct v4l2_async_notifier *async)
++{
++ struct stfcamss *stfcamss =
++ container_of(async, struct stfcamss, notifier);
++ struct v4l2_device *v4l2_dev = &stfcamss->v4l2_dev;
++ struct v4l2_subdev *sd;
++ int ret;
++
++ list_for_each_entry(sd, &v4l2_dev->subdevs, list) {
++ if (sd->host_priv) {
++ struct media_entity *sensor = &sd->entity;
++ struct media_entity *input = sd->host_priv;
++ unsigned int i;
++
++ for (i = 0; i < sensor->num_pads; i++) {
++ if (sensor->pads[i].flags & MEDIA_PAD_FL_SOURCE)
++ break;
++ }
++ if (i == sensor->num_pads) {
++ st_err(ST_CAMSS,
++ "No source pad in external entity\n");
++ return -EINVAL;
++ }
++
++ ret = media_create_pad_link(sensor, i,
++ input, STF_PAD_SINK,
++ MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED);
++ if (ret < 0) {
++ st_err(ST_CAMSS,
++ "Failed to link %s->%s entities: %d\n",
++ sensor->name, input->name, ret);
++ return ret;
++ }
++ }
++ }
++
++ ret = v4l2_device_register_subdev_nodes(&stfcamss->v4l2_dev);
++ if (ret < 0)
++ return ret;
++
++ return media_device_register(&stfcamss->media_dev);
++}
++#endif
++
++static const struct v4l2_async_notifier_operations
++stfcamss_subdev_notifier_ops = {
++ .bound = stfcamss_subdev_notifier_bound,
++};
++
++static const struct media_device_ops stfcamss_media_ops = {
++ .link_notify = v4l2_pipeline_link_notify,
++};
++
++#ifdef CONFIG_DEBUG_FS
++enum module_id {
++ VIN_MODULE = 0,
++ ISP_MODULE,
++ CSI_MODULE,
++ CSIPHY_MODULE,
++ DVP_MODULE,
++ CLK_MODULE,
++};
++
++static enum module_id id_num = ISP_MODULE;
++
++void dump_clk_reg(void __iomem *reg_base)
++{
++ int i;
++
++ st_info(ST_CAMSS, "DUMP Clk register:\n");
++ for (i = 0; i <= CLK_C_ISP_CTRL; i += 4)
++ print_reg(ST_CAMSS, reg_base, i);
++}
++
++static ssize_t vin_debug_read(struct file *file, char __user *user_buf,
++ size_t count, loff_t *ppos)
++{
++ struct device *dev = file->private_data;
++ void __iomem *reg_base;
++ struct stfcamss *stfcamss = dev_get_drvdata(dev);
++ struct stf_vin_dev *vin = stfcamss->vin;
++ struct stf_vin2_dev *vin_dev = stfcamss->vin_dev;
++ struct stf_isp_dev *isp_dev = stfcamss->isp_dev;
++ struct stf_csi_dev *csi0_dev = stfcamss->csi_dev;
++
++ switch (id_num) {
++ case VIN_MODULE:
++ case CSIPHY_MODULE:
++ case DVP_MODULE:
++ mutex_lock(&vin_dev->power_lock);
++ if (vin_dev->power_count > 0) {
++ reg_base = vin->sysctrl_base;
++ dump_vin_reg(reg_base);
++ }
++ mutex_unlock(&vin_dev->power_lock);
++ break;
++ case ISP_MODULE:
++ mutex_lock(&isp_dev->stream_lock);
++ if (isp_dev->stream_count > 0) {
++ reg_base = vin->isp_base;
++ dump_isp_reg(reg_base);
++ }
++ mutex_unlock(&isp_dev->stream_lock);
++ break;
++ case CSI_MODULE:
++ mutex_lock(&csi0_dev->stream_lock);
++ if (csi0_dev->stream_count > 0) {
++ reg_base = vin->csi2rx_base;
++ dump_csi_reg(reg_base);
++ }
++ mutex_unlock(&csi0_dev->stream_lock);
++ break;
++ case CLK_MODULE:
++ mutex_lock(&vin_dev->power_lock);
++ if (vin_dev->power_count > 0) {
++ reg_base = vin->clkgen_base;
++ dump_clk_reg(reg_base);
++ }
++ mutex_unlock(&vin_dev->power_lock);
++ break;
++ default:
++ break;
++ }
++
++ return 0;
++}
++
++static void set_reg_val(struct stfcamss *stfcamss, int id, u32 offset, u32 val)
++{
++ struct stf_vin_dev *vin = stfcamss->vin;
++ struct stf_vin2_dev *vin_dev = stfcamss->vin_dev;
++ struct stf_isp_dev *isp_dev = stfcamss->isp_dev;
++ struct stf_csi_dev *csi_dev = stfcamss->csi_dev;
++ void __iomem *reg_base;
++
++ switch (id) {
++ case VIN_MODULE:
++ case CSIPHY_MODULE:
++ case DVP_MODULE:
++ mutex_lock(&vin_dev->power_lock);
++ if (vin_dev->power_count > 0) {
++ reg_base = vin->sysctrl_base;
++ print_reg(ST_VIN, reg_base, offset);
++ reg_write(reg_base, offset, val);
++ print_reg(ST_VIN, reg_base, offset);
++ }
++ mutex_unlock(&vin_dev->power_lock);
++ break;
++ case ISP_MODULE:
++ mutex_lock(&isp_dev->stream_lock);
++ if (isp_dev->stream_count > 0) {
++ reg_base = vin->isp_base;
++ print_reg(ST_ISP, reg_base, offset);
++ reg_write(reg_base, offset, val);
++ print_reg(ST_ISP, reg_base, offset);
++ }
++ mutex_unlock(&isp_dev->stream_lock);
++ break;
++ case CSI_MODULE:
++ mutex_lock(&csi_dev->stream_lock);
++ if (csi_dev->stream_count > 0) {
++ reg_base = vin->csi2rx_base;
++ print_reg(ST_CSI, reg_base, offset);
++ reg_write(reg_base, offset, val);
++ print_reg(ST_CSI, reg_base, offset);
++ }
++ mutex_unlock(&csi_dev->stream_lock);
++ break;
++ case CLK_MODULE:
++ mutex_lock(&vin_dev->power_lock);
++ if (vin_dev->power_count > 0) {
++ reg_base = vin->clkgen_base;
++ print_reg(ST_CAMSS, reg_base, offset);
++ reg_write(reg_base, offset, val);
++ print_reg(ST_CAMSS, reg_base, offset);
++ }
++ mutex_unlock(&vin_dev->power_lock);
++ break;
++ default:
++ break;
++
++ }
++}
++
++static u32 atoi(const char *s)
++{
++ u32 ret = 0, d = 0;
++ char ch;
++ int hex = 0;
++
++ if ((*s == '0') && (*(s+1) == 'x')) {
++ hex = 1;
++ s += 2;
++ }
++
++ while (1) {
++ if (!hex) {
++ d = (*s++) - '0';
++ if (d > 9)
++ break;
++ ret *= 10;
++ ret += d;
++ } else {
++ ch = tolower(*s++);
++ if (isdigit(ch))
++ d = ch - '0';
++ else if (islower(ch))
++ d = ch - 'a' + 10;
++ else
++ break;
++ if (d > 15)
++ break;
++ ret *= 16;
++ ret += d;
++ }
++ }
++
++ return ret;
++}
++
++static ssize_t vin_debug_write(struct file *file, const char __user *user_buf,
++ size_t count, loff_t *ppos)
++{
++ struct device *dev = file->private_data;
++ struct stfcamss *stfcamss = dev_get_drvdata(dev);
++ char *buf;
++ char *line;
++ char *p;
++ static const char *delims = " \t\r";
++ char *token;
++ u32 offset, val;
++
++ buf = memdup_user_nul(user_buf, min_t(size_t, PAGE_SIZE, count));
++ if (IS_ERR(buf))
++ return PTR_ERR(buf);
++ p = buf;
++ st_debug(ST_CAMSS, "dup buf: %s, len: %lu, count: %lu\n", p, strlen(p), count);
++ while (p && *p) {
++ p = skip_spaces(p);
++ line = strsep(&p, "\n");
++ if (!*line || *line == '#')
++ break;
++ token = strsep(&line, delims);
++ if (!token)
++ goto out;
++ id_num = atoi(token);
++ token = strsep(&line, delims);
++ if (!token)
++ goto out;
++ offset = atoi(token);
++ token = strsep(&line, delims);
++ if (!token)
++ goto out;
++ val = atoi(token);
++ }
++ set_reg_val(stfcamss, id_num, offset, val);
++out:
++ kfree(buf);
++ st_info(ST_CAMSS, "id_num = %d, offset = 0x%x, 0x%x\n", id_num, offset, val);
++ return count;
++}
++
++static const struct file_operations vin_debug_fops = {
++ .open = simple_open,
++ .read = vin_debug_read,
++ .write = vin_debug_write,
++};
++#endif /* CONFIG_DEBUG_FS */
++
++
++static int stfcamss_probe(struct platform_device *pdev)
++{
++ struct stfcamss *stfcamss;
++ struct stf_vin_dev *vin;
++ struct device *dev = &pdev->dev;
++ struct of_phandle_args args;
++ int ret = 0, num_subdevs;
++
++ dev_info(dev, "stfcamss probe enter!\n");
++
++ stfcamss = devm_kzalloc(dev, sizeof(struct stfcamss), GFP_KERNEL);
++ if (!stfcamss)
++ return -ENOMEM;
++
++ stfcamss->dvp_dev = devm_kzalloc(dev,
++ sizeof(*stfcamss->dvp_dev), GFP_KERNEL);
++ if (!stfcamss->dvp_dev) {
++ ret = -ENOMEM;
++ goto err_cam;
++ }
++
++ stfcamss->csiphy_dev = devm_kzalloc(dev,
++ sizeof(*stfcamss->csiphy_dev),
++ GFP_KERNEL);
++ if (!stfcamss->csiphy_dev) {
++ ret = -ENOMEM;
++ goto err_cam;
++ }
++
++ stfcamss->csi_dev = devm_kzalloc(dev,
++ sizeof(*stfcamss->csi_dev),
++ GFP_KERNEL);
++ if (!stfcamss->csi_dev) {
++ ret = -ENOMEM;
++ goto err_cam;
++ }
++
++ stfcamss->isp_dev = devm_kzalloc(dev,
++ sizeof(*stfcamss->isp_dev),
++ GFP_KERNEL);
++ if (!stfcamss->isp_dev) {
++ ret = -ENOMEM;
++ goto err_cam;
++ }
++
++ stfcamss->vin_dev = devm_kzalloc(dev,
++ sizeof(*stfcamss->vin_dev),
++ GFP_KERNEL);
++ if (!stfcamss->vin_dev) {
++ ret = -ENOMEM;
++ goto err_cam;
++ }
++
++ stfcamss->vin = devm_kzalloc(dev,
++ sizeof(struct stf_vin_dev),
++ GFP_KERNEL);
++ if (!stfcamss->vin) {
++ ret = -ENOMEM;
++ goto err_cam;
++ }
++
++ vin = stfcamss->vin;
++
++ vin->irq = platform_get_irq(pdev, 0);
++ if (vin->irq <= 0) {
++ st_err(ST_CAMSS, "Could not get irq\n");
++ goto err_cam;
++ }
++
++ vin->isp_irq = platform_get_irq(pdev, 1);
++ if (vin->isp_irq <= 0) {
++ st_err(ST_CAMSS, "Could not get isp irq\n");
++ goto err_cam;
++ }
++
++ vin->isp_csi_irq = platform_get_irq(pdev, 2);
++ if (vin->isp_csi_irq <= 0) {
++ st_err(ST_CAMSS, "Could not get isp csi irq\n");
++ goto err_cam;
++ }
++
++ vin->isp_scd_irq = platform_get_irq(pdev, 3);
++ if (vin->isp_scd_irq <= 0) {
++ st_err(ST_CAMSS, "Could not get isp scd irq\n");
++ goto err_cam;
++ }
++
++ vin->isp_irq_csiline = platform_get_irq(pdev, 4);
++ if (vin->isp_irq_csiline <= 0) {
++ st_err(ST_CAMSS, "Could not get isp irq csiline\n");
++ goto err_cam;
++ }
++
++ pm_runtime_enable(dev);
++
++ stfcamss->nclks = ARRAY_SIZE(stfcamss_clocks);
++ stfcamss->sys_clk = stfcamss_clocks;
++
++ ret = devm_clk_bulk_get(dev, stfcamss->nclks, stfcamss->sys_clk);
++ if (ret) {
++ st_err(ST_CAMSS, "Failed to get clk controls\n");
++ return ret;
++ }
++
++ stfcamss->nrsts = ARRAY_SIZE(stfcamss_resets);
++ stfcamss->sys_rst = stfcamss_resets;
++
++ ret = devm_reset_control_bulk_get_shared(dev, stfcamss->nrsts,
++ stfcamss->sys_rst);
++ if (ret) {
++ st_err(ST_CAMSS, "Failed to get reset controls\n");
++ return ret;
++ }
++
++ ret = of_parse_phandle_with_fixed_args(dev->of_node,
++ "starfive,aon-syscon", 1, 0, &args);
++ if (ret < 0) {
++ st_err(ST_CAMSS, "Failed to parse starfive,aon-syscon\n");
++ return -EINVAL;
++ }
++
++ stfcamss->stf_aon_syscon = syscon_node_to_regmap(args.np);
++ of_node_put(args.np);
++ if (IS_ERR(stfcamss->stf_aon_syscon))
++ return PTR_ERR(stfcamss->stf_aon_syscon);
++
++ stfcamss->aon_gp_reg = args.args[0];
++
++ ret = stfcamss_get_mem_res(pdev, vin);
++ if (ret) {
++ st_err(ST_CAMSS, "Could not map registers\n");
++ goto err_cam;
++ }
++
++ ret = vin_parse_dt(dev, vin);
++ if (ret)
++ goto err_cam;
++
++ vin->dev = dev;
++ stfcamss->dev = dev;
++ platform_set_drvdata(pdev, stfcamss);
++
++ v4l2_async_nf_init(&stfcamss->notifier, &stfcamss->v4l2_dev);
++
++ num_subdevs = stfcamss_of_parse_ports(stfcamss);
++ if (num_subdevs < 0) {
++ ret = num_subdevs;
++ goto err_cam_noti;
++ }
++
++ ret = stfcamss_init_subdevices(stfcamss);
++ if (ret < 0) {
++ st_err(ST_CAMSS, "Failed to init subdevice: %d\n", ret);
++ goto err_cam_noti;
++ }
++
++ stfcamss->media_dev.dev = stfcamss->dev;
++ strscpy(stfcamss->media_dev.model, "Starfive Camera Subsystem",
++ sizeof(stfcamss->media_dev.model));
++ strscpy(stfcamss->media_dev.serial, "0123456789ABCDEF",
++ sizeof(stfcamss->media_dev.serial));
++ snprintf(stfcamss->media_dev.bus_info, sizeof(stfcamss->media_dev.bus_info),
++ "%s:%s", dev_bus_name(dev), pdev->name);
++ stfcamss->media_dev.hw_revision = 0x01;
++ stfcamss->media_dev.ops = &stfcamss_media_ops;
++ media_device_init(&stfcamss->media_dev);
++
++ stfcamss->v4l2_dev.mdev = &stfcamss->media_dev;
++
++ ret = v4l2_device_register(stfcamss->dev, &stfcamss->v4l2_dev);
++ if (ret < 0) {
++ st_err(ST_CAMSS, "Failed to register V4L2 device: %d\n", ret);
++ goto err_cam_noti_med;
++ }
++
++ ret = stfcamss_register_subdevices(stfcamss);
++ if (ret < 0) {
++ st_err(ST_CAMSS, "Failed to register subdevice: %d\n", ret);
++ goto err_cam_noti_med_vreg;
++ }
++
++ if (num_subdevs) {
++ stfcamss->notifier.ops = &stfcamss_subdev_notifier_ops;
++ ret = v4l2_async_nf_register(&stfcamss->notifier);
++ if (ret) {
++ st_err(ST_CAMSS,
++ "Failed to register async subdev nodes: %d\n",
++ ret);
++ goto err_cam_noti_med_vreg_sub;
++ }
++ } else {
++ ret = v4l2_device_register_subdev_nodes(&stfcamss->v4l2_dev);
++ if (ret < 0) {
++ st_err(ST_CAMSS,
++ "Failed to register subdev nodes: %d\n",
++ ret);
++ goto err_cam_noti_med_vreg_sub;
++ }
++
++ ret = media_device_register(&stfcamss->media_dev);
++ if (ret < 0) {
++ st_err(ST_CAMSS, "Failed to register media device: %d\n",
++ ret);
++ goto err_cam_noti_med_vreg_sub_medreg;
++ }
++ }
++
++#ifdef CONFIG_DEBUG_FS
++ stfcamss->debugfs_entry = debugfs_create_dir("stfcamss", NULL);
++ stfcamss->vin_debugfs = debugfs_create_file("stf_vin",
++ 0644, stfcamss->debugfs_entry,
++ (void *)dev, &vin_debug_fops);
++ debugfs_create_u32("dbg_level",
++ 0644, stfcamss->debugfs_entry,
++ &stdbg_level);
++ debugfs_create_u32("dbg_mask",
++ 0644, stfcamss->debugfs_entry,
++ &stdbg_mask);
++#endif
++ dev_info(dev, "stfcamss probe success!\n");
++
++ return 0;
++
++#ifdef CONFIG_DEBUG_FS
++ debugfs_remove(stfcamss->vin_debugfs);
++ debugfs_remove_recursive(stfcamss->debugfs_entry);
++ stfcamss->debugfs_entry = NULL;
++#endif
++
++err_cam_noti_med_vreg_sub_medreg:
++err_cam_noti_med_vreg_sub:
++ stfcamss_unregister_subdevices(stfcamss);
++err_cam_noti_med_vreg:
++ v4l2_device_unregister(&stfcamss->v4l2_dev);
++err_cam_noti_med:
++ media_device_cleanup(&stfcamss->media_dev);
++err_cam_noti:
++ v4l2_async_nf_cleanup(&stfcamss->notifier);
++err_cam:
++ // kfree(stfcamss);
++ return ret;
++}
++
++static int stfcamss_remove(struct platform_device *pdev)
++{
++ struct stfcamss *stfcamss = platform_get_drvdata(pdev);
++
++ dev_info(&pdev->dev, "remove done\n");
++
++#ifdef CONFIG_DEBUG_FS
++ debugfs_remove(stfcamss->vin_debugfs);
++ debugfs_remove_recursive(stfcamss->debugfs_entry);
++ stfcamss->debugfs_entry = NULL;
++#endif
++
++ stfcamss_unregister_subdevices(stfcamss);
++ v4l2_device_unregister(&stfcamss->v4l2_dev);
++ media_device_cleanup(&stfcamss->media_dev);
++ pm_runtime_disable(&pdev->dev);
++
++ kfree(stfcamss);
++
++ return 0;
++}
++
++static const struct of_device_id stfcamss_of_match[] = {
++ { .compatible = "starfive,jh7110-vin" },
++ { /* end node */ },
++};
++
++MODULE_DEVICE_TABLE(of, stfcamss_of_match);
++
++#ifdef CONFIG_PM_SLEEP
++static int stfcamss_suspend(struct device *dev)
++{
++ struct stfcamss *stfcamss = dev_get_drvdata(dev);
++ struct stf_vin2_dev *vin_dev = stfcamss->vin_dev;
++ struct media_entity *entity;
++ struct media_pad *pad;
++ struct v4l2_subdev *subdev;
++ struct stfcamss_video *video;
++ struct video_device *vdev;
++ int i = 0;
++ int pm_power_count;
++ int pm_stream_count;
++
++ for (i = 0; i < VIN_LINE_MAX; i++) {
++ video = &vin_dev->line[i].video_out;
++ vdev = &vin_dev->line[i].video_out.vdev;
++ vin_dev->line[i].pm_power_count = vin_dev->line[i].power_count;
++ vin_dev->line[i].pm_stream_count = vin_dev->line[i].stream_count;
++ pm_power_count = vin_dev->line[i].pm_power_count;
++ pm_stream_count = vin_dev->line[i].pm_stream_count;
++
++ if (pm_stream_count) {
++ while (pm_stream_count--) {
++ entity = &vdev->entity;
++ while (1) {
++ pad = &entity->pads[0];
++ if (!(pad->flags & MEDIA_PAD_FL_SINK))
++ break;
++
++ pad = media_pad_remote_pad_first(pad);
++ if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
++ break;
++
++ entity = pad->entity;
++ subdev = media_entity_to_v4l2_subdev(entity);
++
++ v4l2_subdev_call(subdev, video, s_stream, 0);
++ }
++ }
++ video_device_pipeline_stop(vdev);
++ video->ops->flush_buffers(video, VB2_BUF_STATE_ERROR);
++ }
++
++ if (!pm_power_count)
++ continue;
++
++ v4l2_pipeline_pm_put(&vdev->entity);
++ }
++
++ return pm_runtime_force_suspend(dev);
++}
++
++static int stfcamss_resume(struct device *dev)
++{
++ struct stfcamss *stfcamss = dev_get_drvdata(dev);
++ struct stf_vin2_dev *vin_dev = stfcamss->vin_dev;
++ struct media_entity *entity;
++ struct media_pad *pad;
++ struct v4l2_subdev *subdev;
++ struct stfcamss_video *video;
++ struct video_device *vdev;
++ int i = 0;
++ int pm_power_count;
++ int pm_stream_count;
++ int ret = 0;
++
++ pm_runtime_force_resume(dev);
++
++ for (i = 0; i < VIN_LINE_MAX; i++) {
++ video = &vin_dev->line[i].video_out;
++ vdev = &vin_dev->line[i].video_out.vdev;
++ pm_power_count = vin_dev->line[i].pm_power_count;
++ pm_stream_count = vin_dev->line[i].pm_stream_count;
++
++ if (!pm_power_count)
++ continue;
++
++ ret = v4l2_pipeline_pm_get(&vdev->entity);
++ if (ret < 0)
++ goto err;
++
++ if (pm_stream_count) {
++ ret = video_device_pipeline_start(vdev, &video->stfcamss->pipe);
++ if (ret < 0)
++ goto err_pm_put;
++
++ while (pm_stream_count--) {
++ entity = &vdev->entity;
++ while (1) {
++ pad = &entity->pads[0];
++ if (!(pad->flags & MEDIA_PAD_FL_SINK))
++ break;
++
++ pad = media_pad_remote_pad_first(pad);
++ if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
++ break;
++
++ entity = pad->entity;
++ subdev = media_entity_to_v4l2_subdev(entity);
++
++ ret = v4l2_subdev_call(subdev, video, s_stream, 1);
++ if (ret < 0 && ret != -ENOIOCTLCMD)
++ goto err_pipeline_stop;
++ }
++ }
++ }
++ }
++
++ return 0;
++
++err_pipeline_stop:
++ video_device_pipeline_stop(vdev);
++err_pm_put:
++ v4l2_pipeline_pm_put(&vdev->entity);
++err:
++ return ret;
++}
++#endif /* CONFIG_PM_SLEEP */
++
++#ifdef CONFIG_PM
++static int stfcamss_runtime_suspend(struct device *dev)
++{
++ struct stfcamss *stfcamss = dev_get_drvdata(dev);
++
++ reset_control_assert(stfcamss->sys_rst[STFRST_ISP_TOP_AXI].rstc);
++ reset_control_assert(stfcamss->sys_rst[STFRST_ISP_TOP_N].rstc);
++ clk_disable_unprepare(stfcamss->sys_clk[STFCLK_ISP_AXI].clk);
++ clk_disable_unprepare(stfcamss->sys_clk[STFCLK_ISPCORE_2X].clk);
++
++ return 0;
++}
++
++static int stfcamss_runtime_resume(struct device *dev)
++{
++ struct stfcamss *stfcamss = dev_get_drvdata(dev);
++
++ clk_prepare_enable(stfcamss->sys_clk[STFCLK_ISPCORE_2X].clk);
++ clk_prepare_enable(stfcamss->sys_clk[STFCLK_ISP_AXI].clk);
++ reset_control_deassert(stfcamss->sys_rst[STFRST_ISP_TOP_N].rstc);
++ reset_control_deassert(stfcamss->sys_rst[STFRST_ISP_TOP_AXI].rstc);
++
++ return 0;
++}
++#endif /* CONFIG_PM */
++
++static const struct dev_pm_ops stfcamss_pm_ops = {
++ SET_SYSTEM_SLEEP_PM_OPS(stfcamss_suspend, stfcamss_resume)
++ SET_RUNTIME_PM_OPS(stfcamss_runtime_suspend, stfcamss_runtime_resume, NULL)
++};
++
++static struct platform_driver stfcamss_driver = {
++ .probe = stfcamss_probe,
++ .remove = stfcamss_remove,
++ .driver = {
++ .name = DRV_NAME,
++ .pm = &stfcamss_pm_ops,
++ .of_match_table = of_match_ptr(stfcamss_of_match),
++ },
++};
++
++static int __init stfcamss_init(void)
++{
++ return platform_driver_register(&stfcamss_driver);
++}
++
++static void __exit stfcamss_cleanup(void)
++{
++ platform_driver_unregister(&stfcamss_driver);
++}
++
++module_init(stfcamss_init);
++//fs_initcall(stfcamss_init);
++module_exit(stfcamss_cleanup);
++
++MODULE_LICENSE("GPL");
+--- /dev/null
++++ b/drivers/media/platform/starfive/v4l2_driver/stfcamss.h
+@@ -0,0 +1,117 @@
++/* SPDX-License-Identifier: GPL-2.0
++ *
++ * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
++ *
++ */
++
++#ifndef STFCAMSS_H
++#define STFCAMSS_H
++
++#include <linux/io.h>
++#include <linux/delay.h>
++#include <linux/reset.h>
++#include <linux/clk.h>
++
++enum sensor_type {
++ SENSOR_VIN,
++ /* need replace sensor */
++ SENSOR_ISP,
++};
++
++enum subdev_type {
++ VIN_DEV_TYPE,
++ ISP_DEV_TYPE,
++};
++
++#include "stf_common.h"
++#include "stf_dvp.h"
++#include "stf_csi.h"
++#include "stf_csiphy.h"
++#include "stf_isp.h"
++#include "stf_vin.h"
++
++#define STF_PAD_SINK 0
++#define STF_PAD_SRC 1
++#define STF_PADS_NUM 2
++
++#define STF_CAMSS_SKIP_ITI
++
++enum port_num {
++ DVP_SENSOR_PORT_NUMBER = 0,
++ CSI2RX_SENSOR_PORT_NUMBER
++};
++
++enum stf_clk_num {
++ STFCLK_APB_FUNC = 0,
++ STFCLK_PCLK,
++ STFCLK_SYS_CLK,
++ STFCLK_WRAPPER_CLK_C,
++ STFCLK_DVP_INV,
++ STFCLK_AXIWR,
++ STFCLK_MIPI_RX0_PXL,
++ STFCLK_PIXEL_CLK_IF0,
++ STFCLK_PIXEL_CLK_IF1,
++ STFCLK_PIXEL_CLK_IF2,
++ STFCLK_PIXEL_CLK_IF3,
++ STFCLK_M31DPHY_CFGCLK_IN,
++ STFCLK_M31DPHY_REFCLK_IN,
++ STFCLK_M31DPHY_TXCLKESC_LAN0,
++ STFCLK_ISPCORE_2X,
++ STFCLK_ISP_AXI,
++ STFCLK_NUM
++};
++
++enum stf_rst_num {
++ STFRST_WRAPPER_P = 0,
++ STFRST_WRAPPER_C,
++ STFRST_PCLK,
++ STFRST_SYS_CLK,
++ STFRST_AXIRD,
++ STFRST_AXIWR,
++ STFRST_PIXEL_CLK_IF0,
++ STFRST_PIXEL_CLK_IF1,
++ STFRST_PIXEL_CLK_IF2,
++ STFRST_PIXEL_CLK_IF3,
++ STFRST_M31DPHY_HW,
++ STFRST_M31DPHY_B09_ALWAYS_ON,
++ STFRST_ISP_TOP_N,
++ STFRST_ISP_TOP_AXI,
++ STFRST_NUM
++};
++
++struct stfcamss {
++ struct stf_vin_dev *vin; // stfcamss phy res
++ struct v4l2_device v4l2_dev;
++ struct media_device media_dev;
++ struct media_pipeline pipe;
++ struct device *dev;
++ struct stf_vin2_dev *vin_dev; // subdev
++ struct stf_dvp_dev *dvp_dev; // subdev
++ struct stf_csi_dev *csi_dev; // subdev
++ struct stf_csiphy_dev *csiphy_dev; // subdev
++ struct stf_isp_dev *isp_dev; // subdev
++ struct v4l2_async_notifier notifier;
++ struct clk_bulk_data *sys_clk;
++ int nclks;
++ struct reset_control_bulk_data *sys_rst;
++ int nrsts;
++ struct regmap *stf_aon_syscon;
++ uint32_t aon_gp_reg;
++#ifdef CONFIG_DEBUG_FS
++ struct dentry *debugfs_entry;
++ struct dentry *vin_debugfs;
++#endif
++};
++
++struct stfcamss_async_subdev {
++ struct v4l2_async_connection asd; // must be first
++ enum port_num port;
++ struct {
++ struct dvp_cfg dvp;
++ struct csi2phy_cfg csiphy;
++ } interface;
++};
++
++extern struct media_entity *stfcamss_find_sensor(struct media_entity *entity);
++
++#endif /* STFCAMSS_H */
+--- /dev/null
++++ b/include/uapi/linux/jh7110-isp.h
+@@ -0,0 +1,253 @@
++/* SPDX-License-Identifier: ((GPL-2.0+ WITH Linux-syscall-note) OR BSD-3-Clause) */
++/*
++ * jh7110-isp.h
++ *
++ * JH7110 ISP driver - user space header file.
++ *
++ * Copyright © 2023 Starfive Technology Co., Ltd.
++ *
++ * Author: Su Zejian (zejian.su@starfivetech.com)
++ *
++ */
++
++#ifndef __JH7110_ISP_H_
++#define __JH7110_ISP_H_
++
++#include <linux/v4l2-controls.h>
++
++#define V4L2_CID_USER_JH7110_ISP_WB_SETTING \
++ (V4L2_CID_USER_JH7110_ISP_BASE + 0x0001)
++#define V4L2_CID_USER_JH7110_ISP_CAR_SETTING \
++ (V4L2_CID_USER_JH7110_ISP_BASE + 0x0002)
++#define V4L2_CID_USER_JH7110_ISP_CCM_SETTING \
++ (V4L2_CID_USER_JH7110_ISP_BASE + 0x0003)
++#define V4L2_CID_USER_JH7110_ISP_CFA_SETTING \
++ (V4L2_CID_USER_JH7110_ISP_BASE + 0x0004)
++#define V4L2_CID_USER_JH7110_ISP_CTC_SETTING \
++ (V4L2_CID_USER_JH7110_ISP_BASE + 0x0005)
++#define V4L2_CID_USER_JH7110_ISP_DBC_SETTING \
++ (V4L2_CID_USER_JH7110_ISP_BASE + 0x0006)
++#define V4L2_CID_USER_JH7110_ISP_DNYUV_SETTING \
++ (V4L2_CID_USER_JH7110_ISP_BASE + 0x0007)
++#define V4L2_CID_USER_JH7110_ISP_GMARGB_SETTING \
++ (V4L2_CID_USER_JH7110_ISP_BASE + 0x0008)
++#define V4L2_CID_USER_JH7110_ISP_LCCF_SETTING \
++ (V4L2_CID_USER_JH7110_ISP_BASE + 0x0009)
++#define V4L2_CID_USER_JH7110_ISP_OBC_SETTING \
++ (V4L2_CID_USER_JH7110_ISP_BASE + 0x000a)
++#define V4L2_CID_USER_JH7110_ISP_OECF_SETTING \
++ (V4L2_CID_USER_JH7110_ISP_BASE + 0x000b)
++#define V4L2_CID_USER_JH7110_ISP_R2Y_SETTING \
++ (V4L2_CID_USER_JH7110_ISP_BASE + 0x000c)
++#define V4L2_CID_USER_JH7110_ISP_SAT_SETTING \
++ (V4L2_CID_USER_JH7110_ISP_BASE + 0x000d)
++#define V4L2_CID_USER_JH7110_ISP_SHRP_SETTING \
++ (V4L2_CID_USER_JH7110_ISP_BASE + 0x000e)
++#define V4L2_CID_USER_JH7110_ISP_YCRV_SETTING \
++ (V4L2_CID_USER_JH7110_ISP_BASE + 0x000f)
++
++struct jh7110_isp_wb_gain {
++ __u16 gain_r;
++ __u16 gain_g;
++ __u16 gain_b;
++};
++
++struct jh7110_isp_wb_setting {
++ __u32 enabled;
++ struct jh7110_isp_wb_gain gains;
++};
++
++struct jh7110_isp_car_setting {
++ __u32 enabled;
++};
++
++struct jh7110_isp_ccm_smlow {
++ __s32 ccm[3][3];
++ __s32 offsets[3];
++};
++
++struct jh7110_isp_ccm_setting {
++ __u32 enabled;
++ struct jh7110_isp_ccm_smlow ccm_smlow;
++};
++
++struct jh7110_isp_cfa_params {
++ __s32 hv_width;
++ __s32 cross_cov;
++};
++
++struct jh7110_isp_cfa_setting {
++ __u32 enabled;
++ struct jh7110_isp_cfa_params settings;
++};
++
++struct jh7110_isp_ctc_params {
++ __u8 saf_mode;
++ __u8 daf_mode;
++ __s32 max_gt;
++ __s32 min_gt;
++};
++
++struct jh7110_isp_ctc_setting {
++ __u32 enabled;
++ struct jh7110_isp_ctc_params settings;
++};
++
++struct jh7110_isp_dbc_params {
++ __s32 bad_gt;
++ __s32 bad_xt;
++};
++
++struct jh7110_isp_dbc_setting {
++ __u32 enabled;
++ struct jh7110_isp_dbc_params settings;
++};
++
++struct jh7110_isp_dnyuv_params {
++ __u8 y_sweight[10];
++ __u16 y_curve[7];
++ __u8 uv_sweight[10];
++ __u16 uv_curve[7];
++};
++
++struct jh7110_isp_dnyuv_setting {
++ __u32 enabled;
++ struct jh7110_isp_dnyuv_params settings;
++};
++
++struct jh7110_isp_gmargb_point {
++ __u16 g_val;
++ __u16 sg_val;
++};
++
++struct jh7110_isp_gmargb_setting {
++ __u32 enabled;
++ struct jh7110_isp_gmargb_point curve[15];
++};
++
++struct jh7110_isp_lccf_circle {
++ __s16 center_x;
++ __s16 center_y;
++ __u8 radius;
++};
++
++struct jh7110_isp_lccf_curve_param {
++ __s16 f1;
++ __s16 f2;
++};
++
++struct jh7110_isp_lccf_setting {
++ __u32 enabled;
++ struct jh7110_isp_lccf_circle circle;
++ struct jh7110_isp_lccf_curve_param r_param;
++ struct jh7110_isp_lccf_curve_param gr_param;
++ struct jh7110_isp_lccf_curve_param gb_param;
++ struct jh7110_isp_lccf_curve_param b_param;
++};
++
++struct jh7110_isp_blacklevel_win_size {
++ __u32 width;
++ __u32 height;
++};
++
++struct jh7110_isp_blacklevel_gain {
++ __u8 tl_gain;
++ __u8 tr_gain;
++ __u8 bl_gain;
++ __u8 br_gain;
++};
++
++struct jh7110_isp_blacklevel_offset {
++ __u8 tl_offset;
++ __u8 tr_offset;
++ __u8 bl_offset;
++ __u8 br_offset;
++};
++
++struct jh7110_isp_blacklevel_setting {
++ __u32 enabled;
++ struct jh7110_isp_blacklevel_win_size win_size;
++ struct jh7110_isp_blacklevel_gain gain[4];
++ struct jh7110_isp_blacklevel_offset offset[4];
++};
++
++struct jh7110_isp_oecf_point {
++ __u16 x;
++ __u16 y;
++ __s16 slope;
++};
++
++struct jh7110_isp_oecf_setting {
++ __u32 enabled;
++ struct jh7110_isp_oecf_point r_curve[16];
++ struct jh7110_isp_oecf_point gr_curve[16];
++ struct jh7110_isp_oecf_point gb_curve[16];
++ struct jh7110_isp_oecf_point b_curve[16];
++};
++
++struct jh7110_isp_r2y_matrix {
++ __s16 m[9];
++};
++
++struct jh7110_isp_r2y_setting {
++ __u32 enabled;
++ struct jh7110_isp_r2y_matrix matrix;
++};
++
++struct jh7110_isp_sat_curve {
++ __s16 yi_min;
++ __s16 yo_ir;
++ __s16 yo_min;
++ __s16 yo_max;
++};
++
++struct jh7110_isp_sat_hue_info {
++ __s16 sin;
++ __s16 cos;
++};
++
++struct jh7110_isp_sat_info {
++ __s16 gain_cmab;
++ __s16 gain_cmad;
++ __s16 threshold_cmb;
++ __s16 threshold_cmd;
++ __s16 offset_u;
++ __s16 offset_v;
++ __s16 cmsf;
++};
++
++struct jh7110_isp_sat_setting {
++ __u32 enabled;
++ struct jh7110_isp_sat_curve curve;
++ struct jh7110_isp_sat_hue_info hue_info;
++ struct jh7110_isp_sat_info sat_info;
++};
++
++struct jh7110_isp_sharp_weight {
++ __u8 weight[15];
++ __u32 recip_wei_sum;
++};
++
++struct jh7110_isp_sharp_strength {
++ __s16 diff[4];
++ __s16 f[4];
++};
++
++struct jh7110_isp_sharp_setting {
++ __u32 enabled;
++ struct jh7110_isp_sharp_weight weight;
++ struct jh7110_isp_sharp_strength strength;
++ __s8 pdirf;
++ __s8 ndirf;
++};
++
++struct jh7110_isp_ycrv_curve {
++ __s16 y[64];
++};
++
++struct jh7110_isp_ycrv_setting {
++ __u32 enabled;
++ struct jh7110_isp_ycrv_curve curve;
++};
++
++#endif
+--- a/include/uapi/linux/v4l2-controls.h
++++ b/include/uapi/linux/v4l2-controls.h
+@@ -203,6 +203,12 @@ enum v4l2_colorfx {
+ */
+ #define V4L2_CID_USER_ASPEED_BASE (V4L2_CID_USER_BASE + 0x11a0)
+
++/*
++ * The base for the jh7110-isp driver controls.
++ * We reserve 16 controls for this driver.
++ */
++#define V4L2_CID_USER_JH7110_ISP_BASE (V4L2_CID_USER_BASE + 0x1170)
++
+ /* MPEG-class control IDs */
+ /* The MPEG controls are applicable to all codec controls
+ * and the 'MPEG' part of the define is historical */
+--- /dev/null
++++ b/include/video/stf-vin.h
+@@ -0,0 +1,443 @@
++/* include/video/stf-vin.h
++ *
++ * Copyright 2020 starfive tech.
++ * Eric Tang <eric.tang@starfivetech.com>
++ *
++ * Generic vin notifier interface
++ *
++ * 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.
++ *
++*/
++#ifndef _VIDEO_VIN_H
++#define _VIDEO_VIN_H
++
++#include <linux/cdev.h>
++
++#define DRV_NAME "jh7110-vin"
++#define FB_FIRST_ADDR 0xf9000000
++#define FB_SECOND_ADDR 0xf97e9000
++
++#define RESERVED_MEM_SIZE 0x1000000
++
++#define VIN_MIPI_CONTROLLER0_OFFSET 0x00000
++#define VIN_CLKGEN_OFFSET 0x10000
++#define VIN_RSTGEN_OFFSET 0x20000
++#define VIN_MIPI_CONTROLLER1_OFFSET 0x30000
++#define VIN_SYSCONTROLLER_OFFSET 0x40000
++
++#define VD_1080P 1080
++#define VD_720P 720
++#define VD_PAL 480
++
++#define VD_HEIGHT_1080P VD_1080P
++#define VD_WIDTH_1080P 1920
++
++#define VD_HEIGHT_720P VD_720P
++#define VD_WIDTH_720P 1080
++
++#define VD_HEIGHT_480 480
++#define VD_WIDTH_640 640
++
++#define SEEED_WIDTH_800 800
++#define SEEED_HIGH_480 480
++
++#define VIN_TOP_CLKGEN_BASE_ADDR 0x11800000
++#define VIN_TOP_RSTGEN_BASE_ADDR 0x11840000
++#define VIN_TOP_IOPAD_BASE_ADDR 0x11858000
++
++#define ISP_BASE_MIPI0_ADDR 0x19800000
++#define ISP_BASE_CLKGEN_ADDR 0x19810000
++#define ISP_BASE_RSTGEN_ADDR 0x19820000
++#define ISP_BASE_MIPI1_ADDR 0x19830000
++#define ISP_BASE_SYSCTRL_ADDR 0x19840000
++#define ISP_BASE_ISP0_ADDR 0x19870000
++#define ISP_BASE_ISP1_ADDR 0x198a0000
++
++
++//vin clk registers
++#define CLK_VIN_SRC_CTRL 0x188
++#define CLK_ISP0_AXI_CTRL 0x190
++#define CLK_ISP0NOC_AXI_CTRL 0x194
++#define CLK_ISPSLV_AXI_CTRL 0x198
++#define CLK_ISP1_AXI_CTRL 0x1A0
++#define CLK_ISP1NOC_AXI_CTRL 0x1A4
++#define CLK_VIN_AXI 0x1AC
++#define CLK_VINNOC_AXI 0x1B0
++
++
++#define CLK_DOM4_APB_FUNC 0x0
++#define CLK_MUX_SEL 0xffffff
++
++#define CLK_MIPI_RX0_PXL 0x4
++
++#define CLK_DVP_INV 0x8
++#define CLK_U0_VIN_PCLK 0x18
++#define CLK_U0_VIN_PCLK_ICG (0x1<<31)
++
++#define CLK_U0_VIN_SYS_CLK 0x1c
++#define CLK_U0_VIN_CLK_P_AXIWR 0x30
++#define CLK_U0_VIN_MUX_SEL (BIT(24) | BIT(25) | BIT(26) | BIT(27) | BIT(28) | BIT(29))
++
++#define CLK_U0_VIN_PIXEL_CLK_IF0 0x20
++#define CLK_U0_VIN_PIXEL_CLK_IF1 0x24
++#define CLK_U0_VIN_PIXEL_CLK_IF2 0x28
++#define CLK_U0_VIN_PIXEL_CLK_IF3 0x2c
++
++#define CLK_U0_VIN_CLK_P_AXIWR 0x30
++
++#define CLK_U0_ISPV2_TOP_WRAPPER_CLK_C 0x34u
++#define CLK_U0_ISPV2_MUX_SEL (0x1<<24 | 0x1<<25 | 0x1<<26 | 0x1<<27 | 0x1<<28 | 0x1<< 29)
++
++#define CLK_U0_ISPV2_CLK_ICG (0x1<<31)
++
++#define SOFTWARE_RESET_ASSERT0_ASSERT_SET 0x38U
++#define SOFTWARE_RESET_ASSERT0_ASSERT_SET_STATE 0x3CU
++#define RST_U0_ISPV2_TOP_WRAPPER_RST_P BIT(0)
++#define RST_U0_ISPV2_TOP_WRAPPER_RST_C BIT(1)
++#define RSTN_U0_VIN_RST_N_PCLK BIT(4)
++#define RSTN_U0_VIN_RST_N_SYS_CLK BIT(9)
++#define RSTN_U0_VIN_RST_P_AXIRD BIT(10)
++#define RSTN_U0_VIN_RST_P_AXIWR BIT(11)
++
++
++#define CLK_POLARITY (0x1<<30)
++
++#define M31DPHY_APBCFGSAIF__SYSCFG_0 0x0
++#define M31DPHY_APBCFGSAIF__SYSCFG_4 0x4
++#define M31DPHY_APBCFGSAIF__SYSCFG_8 0x8
++#define M31DPHY_APBCFGSAIF__SYSCFG_12 0xc
++#define M31DPHY_APBCFGSAIF__SYSCFG_16 0x10
++#define M31DPHY_APBCFGSAIF__SYSCFG_20 0x14
++#define M31DPHY_APBCFGSAIF__SYSCFG_24 0x18
++#define M31DPHY_APBCFGSAIF__SYSCFG_28 0x1c
++#define M31DPHY_APBCFGSAIF__SYSCFG_32 0x20
++#define M31DPHY_APBCFGSAIF__SYSCFG_36 0x24
++#define M31DPHY_APBCFGSAIF__SYSCFG_40 0x28
++#define M31DPHY_APBCFGSAIF__SYSCFG_44 0x2c
++#define M31DPHY_APBCFGSAIF__SYSCFG_48 0x30
++#define M31DPHY_APBCFGSAIF__SYSCFG_52 0x34
++#define M31DPHY_APBCFGSAIF__SYSCFG_56 0x38
++#define M31DPHY_APBCFGSAIF__SYSCFG_60 0x3c
++#define M31DPHY_APBCFGSAIF__SYSCFG_64 0x40
++#define M31DPHY_APBCFGSAIF__SYSCFG_68 0x44
++#define M31DPHY_APBCFGSAIF__SYSCFG_72 0x48
++#define M31DPHY_APBCFGSAIF__SYSCFG_76 0x4c
++#define M31DPHY_APBCFGSAIF__SYSCFG_80 0x50
++#define M31DPHY_APBCFGSAIF__SYSCFG_84 0x54
++#define M31DPHY_APBCFGSAIF__SYSCFG_88 0x58
++#define M31DPHY_APBCFGSAIF__SYSCFG_92 0x5c
++#define M31DPHY_APBCFGSAIF__SYSCFG_96 0x60
++#define M31DPHY_APBCFGSAIF__SYSCFG_100 0x64
++#define M31DPHY_APBCFGSAIF__SYSCFG_104 0x68
++#define M31DPHY_APBCFGSAIF__SYSCFG_108 0x6c
++#define M31DPHY_APBCFGSAIF__SYSCFG_112 0x70
++#define M31DPHY_APBCFGSAIF__SYSCFG_116 0x74
++#define M31DPHY_APBCFGSAIF__SYSCFG_120 0x78
++#define M31DPHY_APBCFGSAIF__SYSCFG_124 0x7c
++#define M31DPHY_APBCFGSAIF__SYSCFG_128 0x80
++#define M31DPHY_APBCFGSAIF__SYSCFG_132 0x84
++#define M31DPHY_APBCFGSAIF__SYSCFG_136 0x88
++#define M31DPHY_APBCFGSAIF__SYSCFG_140 0x8c
++#define M31DPHY_APBCFGSAIF__SYSCFG_144 0x90
++#define M31DPHY_APBCFGSAIF__SYSCFG_184 0xb8
++
++//pmu registers
++#define SW_DEST_POWER_ON 0x0C
++#define SW_DEST_POWER_OFF 0x10
++#define SW_ENCOURAGE 0x44
++
++
++//isp clk registers
++#define CLK_DPHY_CFGCLK_ISPCORE_2X_CTRL 0x00
++#define CLK_DPHY_REFCLK_ISPCORE_2X_CTRL 0x04
++#define CLK_DPHY_TXCLKESC_IN_CTRL 0x08
++#define CLK_MIPI_RX0_PXL_CTRL 0x0c
++#define CLK_MIPI_RX1_PXL_CTRL 0x10
++#define CLK_MIPI_RX0_PXL_0_CTRL 0X14
++#define CLK_MIPI_RX0_PXL_1_CTRL 0X18
++#define CLK_MIPI_RX0_PXL_2_CTRL 0X1C
++#define CLK_MIPI_RX0_PXL_3_CTRL 0X20
++#define CLK_MIPI_RX0_SYS0_CTRL 0x24
++#define CLK_MIPI_RX1_PXL_0_CTRL 0X28
++#define CLK_MIPI_RX1_PXL_1_CTRL 0X2C
++#define CLK_MIPI_RX1_PXL_2_CTRL 0X30
++#define CLK_MIPI_RX1_PXL_3_CTRL 0X34
++#define CLK_MIPI_RX1_SYS1_CTRL 0x38
++#define CLK_ISP_CTRL 0x3c
++#define CLK_ISP_2X_CTRL 0x40
++#define CLK_ISP_MIPI_CTRL 0x44
++#define CLK_C_ISP_CTRL 0x64
++#define CLK_CSI2RX0_APB_CTRL 0x58
++
++
++#define CLK_VIN_AXI_WR_CTRL 0x5C
++
++#define SOFTWARE_RESET_ASSERT0 0x0
++#define SOFTWARE_RESET_ASSERT1 0x4
++#define SOFTWARE_RESET_STATUS 0x4
++
++#define IOPAD_REG81 0x144
++#define IOPAD_REG82 0x148
++#define IOPAD_REG83 0x14C
++#define IOPAD_REG84 0x150
++#define IOPAD_REG85 0x154
++#define IOPAD_REG86 0x158
++#define IOPAD_REG87 0x15C
++#define IOPAD_REG88 0x160
++#define IOPAD_REG89 0x164
++
++//sys control REG DEFINE
++#define SYSCONSAIF_SYSCFG_0 0X0
++#define U0_VIN_SCFG_SRAM_CONFIG (BIT(0) | BIT(1))
++
++#define SYSCONSAIF_SYSCFG_4 0x4
++#define U0_VIN_CNFG_AXIRD_END_ADDR 0xffffffff
++#define SYSCONSAIF_SYSCFG_8 0x8
++#define U0_VIN_CNFG_AXIRD_LINE_CNT_END (BIT(2) | BIT(3) | BIT(4) | BIT(5) | BIT(6) | BIT(7) | BIT(8) | BIT(9) | BIT(10) | BIT(11) | BIT(12) | BIT(13))
++#define U0_VIN_CNFG_AXIRD_LINE_CNT_START (BIT(14) | BIT(15) | BIT(16) | BIT(17) | BIT(18) | BIT(19) | BIT(20) | BIT(21) | BIT(22) | BIT(23) | BIT(24) | BIT(25))
++#define SYSCONSAIF_SYSCFG_12 0xc
++#define U0_VIN_CNFG_AXIRD_PIX_CNT_END (BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | BIT(6) | BIT(7) | BIT(8) | BIT(9) | BIT(10) | BIT(11) | BIT(12))
++#define U0_VIN_CNFG_AXIRD_PIX_CNT_START (BIT(13) | BIT(14) | BIT(15) | BIT(16) | BIT(17) | BIT(18) | BIT(19) | BIT(20) | BIT(21) | BIT(22) | BIT(23) | BIT(24) | BIT(25))
++#define U0_VIN_CNFG_AXIRD_PIX_CT (BIT(26) | BIT(27))
++#define SYSCONSAIF_SYSCFG_16 0x10
++#define U0_VIN_CNFG_AXIRD_START_ADDR 0xFFFFFFFF
++#define SYSCONSAIF_SYSCFG_20 0x14
++#define U0_VIN_CNFG_AXIWR0_EN BIT(4)
++#define U0_VIN_CNFG_AXIWR0_CHANNEL_SEL (BIT(0) | BIT(1) | BIT(2) | BIT(3))
++#define SYSCONSAIF_SYSCFG_24 0x18
++#define U0_VIN_CNFG_AXIWR0_END_ADDR 0xFFFFFFFF
++
++#define SYSCONSAIF_SYSCFG_28 0x1c
++#define U0_VIN_CNFG_AXIWR0_INTR_CLEAN BIT(0)
++#define U0_VIN_CNFG_AXIWR0_MASK BIT(1)
++#define U0_VIN_CNFG_AXIWR0_PIX_CNT_END (BIT(2) | BIT(3) | BIT(4) | BIT(5) | BIT(6) | BIT(7) | BIT(8) | BIT(9) | BIT(10) | BIT(11) | BIT(12))
++#define U0_VIN_CNFG_AXIWR0_PIX_CT (BIT(13) | BIT(14))
++#define UO_VIN_CNFG_AXIWR0_PIXEL_HEIGH_BIT_SEL (BIT(15) | BIT(16))
++#define SYSCONSAIF_SYSCFG_32 0x20
++
++#define SYSCONSAIF_SYSCFG_36 0x24
++#define UO_VIN_CNFG_COLOR_BAR_EN BIT(0)
++#define U0_VIN_CNFG_DVP_HS_POS (0x1<<1)
++#define U0_VIN_CNFG_DVP_SWAP_EN BIT(2)
++#define U0_VIN_CNFG_DVP_VS_POS (0x1<<3)
++#define U0_VIN_CNFG_GEN_EN_AXIRD BIT(4)
++#define U0_VIN_CNFG_ISP_DVP_EN0 BIT(5)
++#define U0_VIN_CNFG_MIPI_BYTE_EN_ISP0 (BIT(6) |BIT(7))
++#define U0_VIN_CNFG_P_I_MIPI_CHANNEL_SEL0 (BIT(8) |BIT(9) | BIT(10) | BIT(11))
++#define U0_VIN_CNFG_P_I_MIPI_HEADER_EN0 BIT(12)
++
++#define U0_VIN_CNFG_PIX_NUM (0x1<<13 | 0x1<<14 | 0x1<<15 | 0x1<<16)
++#define U0_VIN_CNFG_AXIRD_AXI_CNT_END (BIT(3) | BIT(4) | BIT(5) | BIT(6) | BIT(7) | BIT(8) | BIT(9) | BIT(10) | BIT(11) | BIT(12) | BIT(13))
++
++#define U0_VIN_CNFG_AXI_DVP_EN BIT(2)
++#define U0_VIN_CNFG_AXIRD_INTR_MASK BIT(1)
++#define U0_VIN_CNFG_AXIWRD_INTR_MASK BIT(1)
++#define U0_VIN_CNFG_AXIWR0_START_ADDR 0xffffffff
++#define U0_VIN_CNFG_COLOR_BAR_EN 0X0
++#define U0_VIN_CNFG_AXIWR0_PIX_CNT_CT (BIT(13) | BIT(14))
++#define U0_VIN_CNFG_AXIWR0_PIX_CNT_CNT_END (BIT(2) | BIT(3) | BIT(4) | BIT(5) | BIT(6) | BIT(7) | BIT(8) | BIT(9) | BIT(10) | BIT(11) | BIT(12))
++#define U0_VIN_CNFG_AXIWR0_PIXEL_HITH_BIT_SEL (BIT(15) | BIT(16))
++
++#define SYSCTRL_REG4 0x10
++#define SYSCTRL_DPHY_CTRL 0x14
++#define SYSCTRL_VIN_AXI_CTRL 0x18
++#define SYSCTRL_VIN_WR_START_ADDR 0x28
++#define SYSCTRL_VIN_RD_END_ADDR 0x2C
++#define SYSCTRL_VIN_WR_PIX_TOTAL 0x30
++#define SYSCTRL_VIN_RD_PIX_TOTAL 0x34
++#define SYSCTRL_VIN_RW_CTRL 0x38
++#define SYSCTRL_VIN_SRC_CHAN_SEL 0x24
++#define SYSCTRL_VIN_SRC_DW_SEL 0x40
++#define SYSCTRL_VIN_RD_VBLANK 0x44
++#define SYSCTRL_VIN_RD_VEND 0x48
++#define SYSCTRL_VIN_RD_HBLANK 0x4C
++#define SYSCTRL_VIN_RD_HEND 0x50
++#define SYSCTRL_VIN_INTP_CTRL 0x54
++
++#define ISP_NO_SCALE_ENABLE (0x1<<20)
++#define ISP_MULTI_FRAME_ENABLE (0x1<<17)
++#define ISP_SS0_ENABLE (0x1<<11)
++#define ISP_SS1_ENABLE (0x1<<12)
++#define ISP_RESET (0x1<<1)
++#define ISP_ENBALE (0x1)
++
++
++
++ //ISP REG DEFINE
++#define ISP_REG_DVP_POLARITY_CFG 0x00000014
++#define ISP_REG_RAW_FORMAT_CFG 0x00000018
++#define ISP_REG_CFA_MODE 0x00000A1C
++#define ISP_REG_PIC_CAPTURE_START_CFG 0x0000001C
++#define ISP_REG_PIC_CAPTURE_END_CFG 0x00000020
++#define ISP_REG_PIPELINE_XY_SIZE 0x00000A0C
++#define ISP_REG_Y_PLANE_START_ADDR 0x00000A80
++#define ISP_REG_UV_PLANE_START_ADDR 0x00000A84
++#define ISP_REG_STRIDE 0x00000A88
++#define ISP_REG_PIXEL_COORDINATE_GEN 0x00000A8C
++#define ISP_REG_PIXEL_AXI_CONTROL 0x00000A90
++#define ISP_REG_SS_AXI_CONTROL 0x00000AC4
++#define ISP_REG_RGB_TO_YUV_COVERSION0 0x00000E40
++#define ISP_REG_RGB_TO_YUV_COVERSION1 0x00000E44
++#define ISP_REG_RGB_TO_YUV_COVERSION2 0x00000E48
++#define ISP_REG_RGB_TO_YUV_COVERSION3 0x00000E4C
++#define ISP_REG_RGB_TO_YUV_COVERSION4 0x00000E50
++#define ISP_REG_RGB_TO_YUV_COVERSION5 0x00000E54
++#define ISP_REG_RGB_TO_YUV_COVERSION6 0x00000E58
++#define ISP_REG_RGB_TO_YUV_COVERSION7 0x00000E5C
++#define ISP_REG_RGB_TO_YUV_COVERSION8 0x00000E60
++#define ISP_REG_CSI_MODULE_CFG 0x00000010
++#define ISP_REG_ISP_CTRL_1 0x00000A08
++#define ISP_REG_ISP_CTRL_0 0x00000A00
++#define ISP_REG_DC_AXI_ID 0x00000044
++#define ISP_REG_CSI_INPUT_EN_AND_STATUS 0x00000000
++
++//CSI registers
++#define DEVICE_CONFIG 0x00
++#define SOFT_RESET 0x04
++#define STATIC_CFG 0x08
++#define ERROR_BYPASS_CFG 0x10
++#define MONITOR_IRQS 0x18
++#define MONITOR_IRQS_MASK_CFG 0x1c
++#define INFO_IRQS 0x20
++#define INFO_IRQS_MASK_CFG 0x24
++#define ERROR_IRQS 0x28
++#define ERROR_IRQS_MASK_CFG 0x2c
++#define DPHY_LANE_CONTROL 0x40
++#define DPHY_STATUS 0x48
++#define DPHY_ERR_STATUS_IRQ 0x4C
++#define DPHY_ERR_IRQ_MASK_CFG 0x50
++#define INTEGRATION_DEBUG 0x60
++#define ERROR_DEBUG 0x74
++
++#define STREAM0_CTRL 0x100
++#define STREAM0_STATUS 0x104
++#define STREAM0_DATA_CFG 0x108
++#define STREAM0_CFG 0x10c
++#define STREAM0_MONITOR_CTRL 0x110
++#define STREAM0_MONITOR_FRAME 0x114
++#define STREAM0_MONITOR_LB 0x118
++#define STREAM0_TIMER 0x11c
++#define STREAM0_FCC_CFG 0x120
++#define STREAM0_FCC_CTRL 0x124
++#define STREAM0_FIFO_FILL_LVL 0x128
++
++//m31_dphy registers
++#define M31DPHY_APBCFGSAIF__SYSCFG_188 0xbc
++#define M31DPHY_APBCFGSAIF__SYSCFG_192 0xc0
++#define M31DPHY_APBCFGSAIF__SYSCFG_196 0xc4
++#define M31DPHY_APBCFGSAIF__SYSCFG_200 0xc8
++
++typedef enum
++{
++ DT_RAW6 = 0x28,
++ DT_RAW7 = 0x29,
++ DT_RAW8 = 0x2a,
++ DT_RAW10 = 0x2b,
++ DT_RAW12 = 0x2c,
++ DT_RAW14 = 0x2d,
++} mipicam_data_type_t;
++
++
++enum VIN_SOURCE_FORMAT {
++ SRC_COLORBAR_VIN_ISP = 0,
++ SRC_DVP_SENSOR_VIN,
++ SRC_DVP_SENSOR_VIN_ISP,//need replace sensor
++ SRC_CSI2RX_VIN_ISP,
++ SRC_DVP_SENSOR_VIN_OV5640,
++};
++
++struct reg_name {
++ char name[10];
++};
++
++typedef struct
++{
++ int dlane_nb;
++ int dlane_map[4];
++ int dlane_en[4];
++ int dlane_pn_swap[4];
++ int clane_nb;
++ int clane_map[2];
++ int clane_pn_swap[2];
++} csi2rx_dphy_cfg_t;
++
++typedef struct
++{
++ int lane_nb;
++ int dlane_map[4];
++ int dt;
++ int hsize;
++ int vsize;
++} csi2rx_cfg_t;
++
++
++typedef struct
++{
++ int mipi_id, w, h, dt, bpp, fps,lane;
++ u8 clane_swap;
++ u8 clane_pn_swap;
++ u8 dlane_swap[4];
++ u8 dlane_pn_swap[4];
++} csi_format;
++
++struct vin_params {
++ void *paddr;
++ unsigned long size;
++};
++
++struct vin_buf {
++ void *vaddr;
++ dma_addr_t paddr;
++ u32 size;
++};
++
++struct vin_framesize {
++ u32 width;
++ u32 height;
++};
++
++struct vin_format {
++ enum VIN_SOURCE_FORMAT format;
++ u8 fps;
++};
++
++struct stf_vin_dev {
++ /* Protects the access of variables shared within the interrupt */
++ spinlock_t irqlock;
++ int irq;
++ struct device *dev;
++ struct cdev vin_cdev;
++ void __iomem *base;
++ void __iomem *csi2rx_base;
++ void __iomem *clkgen_base;
++ void __iomem *rstgen_base;
++ void __iomem *sysctrl_base;
++ void __iomem *isp_base;
++ void __iomem *vin_top_clkgen_base;
++ void __iomem *vin_top_rstgen_base;
++ void __iomem *vin_top_iopad_base;
++ void __iomem *pmu_test;
++ void __iomem *sys_crg;
++ struct vin_framesize frame;
++ struct vin_format format;
++ bool isp;
++ int isp_irq;
++ int isp_csi_irq;
++ int isp_scd_irq;
++ int isp_irq_csiline;
++ u32 major;
++ struct vin_buf buf;
++
++ wait_queue_head_t wq;
++ bool condition;
++ int odd;
++
++ csi_format csi_fmt;
++};
++
++extern int vin_notifier_register(struct notifier_block *nb);
++extern void vin_notifier_unregister(struct notifier_block *nb);
++extern int vin_notifier_call(unsigned long e, void *v);
++#endif
diff --git a/target/linux/starfive/patches-6.6/0086-dt-bindings-media-i2c-Add-IMX708-CMOS-sensor-binding.patch b/target/linux/starfive/patches-6.6/0086-dt-bindings-media-i2c-Add-IMX708-CMOS-sensor-binding.patch
new file mode 100644
index 0000000000..c2a97a1873
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0086-dt-bindings-media-i2c-Add-IMX708-CMOS-sensor-binding.patch
@@ -0,0 +1,135 @@
+From baec350a0994467584e7e390746e0bb365957a89 Mon Sep 17 00:00:00 2001
+From: Changhuang Liang <changhuang.liang@starfivetech.com>
+Date: Tue, 13 Jun 2023 16:55:23 +0800
+Subject: [PATCH 086/116] dt-bindings: media: i2c: Add IMX708 CMOS sensor
+ binding
+
+Add YAML devicetree binding for IMX708 CMOS image sensor.
+Let's also add a MAINTAINERS entry for the binding and driver.
+
+Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
+---
+ .../devicetree/bindings/media/i2c/imx708.yaml | 117 ++++++++++++++++++
+ 1 file changed, 117 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/media/i2c/imx708.yaml
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/media/i2c/imx708.yaml
+@@ -0,0 +1,117 @@
++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/media/i2c/imx708.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: Sony 1/2.3-Inch 12Mpixel CMOS Digital Image Sensor
++
++maintainers:
++ - Raspberry Pi Kernel Maintenance <kernel-list@raspberrypi.om>
++
++description: |-
++ The Sony IMX708 is a 1/2.3-inch CMOS active pixel digital mage sensor
++ with an active array size of 4608H x 2592V. It is rogrammable through
++ I2C interface. The I2C address is fixed to 0x1A as per ensor data sheet.
++ Image data is sent through MIPI CSI-2, which is configured s either 2 or
++ 4 data lanes.
++
++properties:
++ compatible:
++ const: sony,imx708
++
++ reg:
++ description: I2C device address
++ maxItems: 1
++
++ clocks:
++ maxItems: 1
++
++ VDIG-supply:
++ description:
++ Digital I/O voltage supply, 1.1 volts
++
++ VANA1-supply:
++ description:
++ Analog1 voltage supply, 2.8 volts
++
++ VANA2-supply:
++ description:
++ Analog2 voltage supply, 1.8 volts
++
++ VDDL-supply:
++ description:
++ Digital core voltage supply, 1.8 volts
++
++ reset-gpios:
++ description: |-
++ Reference to the GPIO connected to the xclr pin, if any.
++ Must be released (set high) after all supplies and INCK re applied.
++
++ # See ../video-interfaces.txt for more details
++ port:
++ type: object
++ properties:
++ endpoint:
++ type: object
++ properties:
++ data-lanes:
++ description: |-
++ The sensor supports either two-lane, or our-lane operation.
++ For two-lane operation the property must be set o <1 2>.
++ items:
++ - const: 1
++ - const: 2
++
++ clock-noncontinuous:
++ type: boolean
++ description: |-
++ MIPI CSI-2 clock is non-continuous if this roperty is present,
++ otherwise it's continuous.
++
++ link-frequencies:
++ allOf:
++ - $ref: /schemas/types.yaml#/definitions/int64-array
++ description:
++ Allowed data bus frequencies.
++
++ required:
++ - link-frequencies
++
++required:
++ - compatible
++ - reg
++ - clocks
++ - VANA1-supply
++ - VANA2-supply
++ - VDIG-supply
++ - VDDL-supply
++ - port
++
++additionalProperties: false
++
++examples:
++ - |
++ i2c0 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ imx708: sensor@1a {
++ compatible = "sony,imx708";
++ reg = <0x1a>;
++ clocks = <&imx708_clk>;
++ VANA1-supply = <&imx708_vana1>; /* 1.8v */
++ VANA2-supply = <&imx708_vana2>; /* 2.8v */
++ VDIG-supply = <&imx708_vdig>; /* 1.1v */
++ VDDL-supply = <&imx708_vddl>; /* 1.8v */
++
++ port {
++ imx708_0: endpoint {
++ remote-endpoint = <&csi1_ep>;
++ data-lanes = <1 2>;
++ clock-noncontinuous;
++ link-frequencies = /bits/ 64 <450000000>;
++ };
++ };
++ };
++ };
diff --git a/target/linux/starfive/patches-6.6/0087-media-i2c-Add-imx708-support.patch b/target/linux/starfive/patches-6.6/0087-media-i2c-Add-imx708-support.patch
new file mode 100644
index 0000000000..51e61817f8
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0087-media-i2c-Add-imx708-support.patch
@@ -0,0 +1,1971 @@
+From e89556802c5d29a80f5887995ab257d4e826a90f Mon Sep 17 00:00:00 2001
+From: Changhuang Liang <changhuang.liang@starfivetech.com>
+Date: Mon, 3 Apr 2023 13:52:17 +0800
+Subject: [PATCH 087/116] media: i2c: Add imx708 support
+
+Add imx708 support.
+
+Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
+---
+ drivers/media/i2c/Kconfig | 13 +
+ drivers/media/i2c/Makefile | 1 +
+ drivers/media/i2c/imx708.c | 1921 ++++++++++++++++++++++++++++++++++++
+ 3 files changed, 1935 insertions(+)
+ create mode 100644 drivers/media/i2c/imx708.c
+
+--- a/drivers/media/i2c/Kconfig
++++ b/drivers/media/i2c/Kconfig
+@@ -201,6 +201,19 @@ config VIDEO_IMX415
+ To compile this driver as a module, choose M here: the
+ module will be called imx415.
+
++config VIDEO_IMX708
++ tristate "Sony IMX708 sensor support"
++ depends on I2C && VIDEO_DEV
++ select MEDIA_CONTROLLER
++ select VIDEO_V4L2_SUBDEV_API
++ select V4L2_FWNODE
++ help
++ This is a Video4Linux2 sensor driver for the Sony
++ IMX708 camera.
++
++ To compile this driver as a module, choose M here: the
++ module will be called imx708.
++
+ config VIDEO_MAX9271_LIB
+ tristate
+
+--- a/drivers/media/i2c/Makefile
++++ b/drivers/media/i2c/Makefile
+@@ -53,6 +53,7 @@ obj-$(CONFIG_VIDEO_IMX335) += imx335.o
+ obj-$(CONFIG_VIDEO_IMX355) += imx355.o
+ obj-$(CONFIG_VIDEO_IMX412) += imx412.o
+ obj-$(CONFIG_VIDEO_IMX415) += imx415.o
++obj-$(CONFIG_VIDEO_IMX708) += imx708.o
+ obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o
+ obj-$(CONFIG_VIDEO_ISL7998X) += isl7998x.o
+ obj-$(CONFIG_VIDEO_KS0127) += ks0127.o
+--- /dev/null
++++ b/drivers/media/i2c/imx708.c
+@@ -0,0 +1,1921 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * A V4L2 driver for Sony IMX708 cameras.
++ * Copyright (C) 2022-2023, Raspberry Pi Ltd
++ *
++ * Based on Sony imx477 camera driver
++ * Copyright (C) 2020 Raspberry Pi Ltd
++ */
++#include <asm/unaligned.h>
++#include <linux/clk.h>
++#include <linux/delay.h>
++#include <linux/gpio/consumer.h>
++#include <linux/i2c.h>
++#include <linux/module.h>
++#include <linux/pm_runtime.h>
++#include <linux/regulator/consumer.h>
++#include <media/v4l2-ctrls.h>
++#include <media/v4l2-device.h>
++#include <media/v4l2-event.h>
++#include <media/v4l2-fwnode.h>
++#include <media/v4l2-mediabus.h>
++
++#define IMX708_REG_VALUE_08BIT 1
++#define IMX708_REG_VALUE_16BIT 2
++
++/* Chip ID */
++#define IMX708_REG_CHIP_ID 0x0016
++#define IMX708_CHIP_ID 0x0708
++
++#define IMX708_REG_MODE_SELECT 0x0100
++#define IMX708_MODE_STANDBY 0x00
++#define IMX708_MODE_STREAMING 0x01
++
++#define IMX708_REG_ORIENTATION 0x101
++
++#define IMX708_XCLK_FREQ 24000000
++
++#define IMX708_DEFAULT_LINK_FREQ 450000000
++
++/* V_TIMING internal */
++#define IMX708_REG_FRAME_LENGTH 0x0340
++#define IMX708_FRAME_LENGTH_MAX 0xffff
++
++/* Long exposure multiplier */
++#define IMX708_LONG_EXP_SHIFT_MAX 7
++#define IMX708_LONG_EXP_SHIFT_REG 0x3100
++
++/* Exposure control */
++#define IMX708_REG_EXPOSURE 0x0202
++#define IMX708_EXPOSURE_OFFSET 48
++#define IMX708_EXPOSURE_DEFAULT 0x640
++#define IMX708_EXPOSURE_STEP 1
++#define IMX708_EXPOSURE_MIN 1
++#define IMX708_EXPOSURE_MAX (IMX708_FRAME_LENGTH_MAX - \
++ IMX708_EXPOSURE_OFFSET)
++
++/* Analog gain control */
++#define IMX708_REG_ANALOG_GAIN 0x0204
++#define IMX708_ANA_GAIN_MIN 112
++#define IMX708_ANA_GAIN_MAX 960
++#define IMX708_ANA_GAIN_STEP 1
++#define IMX708_ANA_GAIN_DEFAULT IMX708_ANA_GAIN_MIN
++
++/* Digital gain control */
++#define IMX708_REG_DIGITAL_GAIN 0x020e
++#define IMX708_DGTL_GAIN_MIN 0x0100
++#define IMX708_DGTL_GAIN_MAX 0xffff
++#define IMX708_DGTL_GAIN_DEFAULT 0x0100
++#define IMX708_DGTL_GAIN_STEP 1
++
++/* Colour balance controls */
++#define IMX708_REG_COLOUR_BALANCE_RED 0x0b90
++#define IMX708_REG_COLOUR_BALANCE_BLUE 0x0b92
++#define IMX708_COLOUR_BALANCE_MIN 0x01
++#define IMX708_COLOUR_BALANCE_MAX 0xffff
++#define IMX708_COLOUR_BALANCE_STEP 0x01
++#define IMX708_COLOUR_BALANCE_DEFAULT 0x100
++
++/* Test Pattern Control */
++#define IMX708_REG_TEST_PATTERN 0x0600
++#define IMX708_TEST_PATTERN_DISABLE 0
++#define IMX708_TEST_PATTERN_SOLID_COLOR 1
++#define IMX708_TEST_PATTERN_COLOR_BARS 2
++#define IMX708_TEST_PATTERN_GREY_COLOR 3
++#define IMX708_TEST_PATTERN_PN9 4
++
++/* Test pattern colour components */
++#define IMX708_REG_TEST_PATTERN_R 0x0602
++#define IMX708_REG_TEST_PATTERN_GR 0x0604
++#define IMX708_REG_TEST_PATTERN_B 0x0606
++#define IMX708_REG_TEST_PATTERN_GB 0x0608
++#define IMX708_TEST_PATTERN_COLOUR_MIN 0
++#define IMX708_TEST_PATTERN_COLOUR_MAX 0x0fff
++#define IMX708_TEST_PATTERN_COLOUR_STEP 1
++
++#define IMX708_REG_BASE_SPC_GAINS_L 0x7b10
++#define IMX708_REG_BASE_SPC_GAINS_R 0x7c00
++
++/* HDR exposure ratio (long:med == med:short) */
++#define IMX708_HDR_EXPOSURE_RATIO 4
++#define IMX708_REG_MID_EXPOSURE 0x3116
++#define IMX708_REG_SHT_EXPOSURE 0x0224
++#define IMX708_REG_MID_ANALOG_GAIN 0x3118
++#define IMX708_REG_SHT_ANALOG_GAIN 0x0216
++
++/* IMX708 native and active pixel array size. */
++#define IMX708_NATIVE_WIDTH 4640U
++#define IMX708_NATIVE_HEIGHT 2658U
++#define IMX708_PIXEL_ARRAY_LEFT 16U
++#define IMX708_PIXEL_ARRAY_TOP 24U
++#define IMX708_PIXEL_ARRAY_WIDTH 4608U
++#define IMX708_PIXEL_ARRAY_HEIGHT 2592U
++
++struct imx708_reg {
++ u16 address;
++ u8 val;
++};
++
++struct imx708_reg_list {
++ unsigned int num_of_regs;
++ const struct imx708_reg *regs;
++};
++
++/* Mode : resolution and related config&values */
++struct imx708_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;
++
++ /* Highest possible framerate. */
++ unsigned int vblank_min;
++
++ /* Default framerate. */
++ unsigned int vblank_default;
++
++ /* Default register values */
++ struct imx708_reg_list reg_list;
++
++ /* Not all modes have the same pixel rate. */
++ u64 pixel_rate;
++
++ /* Not all modes have the same minimum exposure. */
++ u32 exposure_lines_min;
++
++ /* Not all modes have the same exposure lines step. */
++ u32 exposure_lines_step;
++
++ /* HDR flag, currently not used at runtime */
++ bool hdr;
++};
++
++/* Default PDAF pixel correction gains */
++static const u8 pdaf_gains[2][9] = {
++ { 0x4c, 0x4c, 0x4c, 0x46, 0x3e, 0x38, 0x35, 0x35, 0x35 },
++ { 0x35, 0x35, 0x35, 0x38, 0x3e, 0x46, 0x4c, 0x4c, 0x4c }
++};
++
++static const struct imx708_reg mode_common_regs[] = {
++ {0x0100, 0x00},
++ {0x0136, 0x18},
++ {0x0137, 0x00},
++ {0x33f0, 0x02},
++ {0x33f1, 0x05},
++ {0x3062, 0x00},
++ {0x3063, 0x12},
++ {0x3068, 0x00},
++ {0x3069, 0x12},
++ {0x306a, 0x00},
++ {0x306b, 0x30},
++ {0x3076, 0x00},
++ {0x3077, 0x30},
++ {0x3078, 0x00},
++ {0x3079, 0x30},
++ {0x5e54, 0x0c},
++ {0x6e44, 0x00},
++ {0xb0b6, 0x01},
++ {0xe829, 0x00},
++ {0xf001, 0x08},
++ {0xf003, 0x08},
++ {0xf00d, 0x10},
++ {0xf00f, 0x10},
++ {0xf031, 0x08},
++ {0xf033, 0x08},
++ {0xf03d, 0x10},
++ {0xf03f, 0x10},
++ {0x0112, 0x0a},
++ {0x0113, 0x0a},
++ {0x0114, 0x01},
++ {0x0b8e, 0x01},
++ {0x0b8f, 0x00},
++ {0x0b94, 0x01},
++ {0x0b95, 0x00},
++ {0x3400, 0x01},
++ {0x3478, 0x01},
++ {0x3479, 0x1c},
++ {0x3091, 0x01},
++ {0x3092, 0x00},
++ {0x3419, 0x00},
++ {0xbcf1, 0x02},
++ {0x3094, 0x01},
++ {0x3095, 0x01},
++ {0x3362, 0x00},
++ {0x3363, 0x00},
++ {0x3364, 0x00},
++ {0x3365, 0x00},
++ {0x0138, 0x01},
++};
++
++/* 10-bit. */
++static const struct imx708_reg mode_4608x2592_regs[] = {
++ {0x0342, 0x3d},
++ {0x0343, 0x20},
++ {0x0340, 0x0a},
++ {0x0341, 0x59},
++ {0x0344, 0x00},
++ {0x0345, 0x00},
++ {0x0346, 0x00},
++ {0x0347, 0x00},
++ {0x0348, 0x11},
++ {0x0349, 0xff},
++ {0x034a, 0x0a},
++ {0x034b, 0x1f},
++ {0x0220, 0x62},
++ {0x0222, 0x01},
++ {0x0900, 0x00},
++ {0x0901, 0x11},
++ {0x0902, 0x0a},
++ {0x3200, 0x01},
++ {0x3201, 0x01},
++ {0x32d5, 0x01},
++ {0x32d6, 0x00},
++ {0x32db, 0x01},
++ {0x32df, 0x00},
++ {0x350c, 0x00},
++ {0x350d, 0x00},
++ {0x0408, 0x00},
++ {0x0409, 0x00},
++ {0x040a, 0x00},
++ {0x040b, 0x00},
++ {0x040c, 0x12},
++ {0x040d, 0x00},
++ {0x040e, 0x0a},
++ {0x040f, 0x20},
++ {0x034c, 0x12},
++ {0x034d, 0x00},
++ {0x034e, 0x0a},
++ {0x034f, 0x20},
++ {0x0301, 0x05},
++ {0x0303, 0x02},
++ {0x0305, 0x02},
++ {0x0306, 0x00},
++ {0x0307, 0x7c},
++ {0x030b, 0x02},
++ {0x030d, 0x04},
++ {0x030e, 0x01},
++ {0x030f, 0x2c},
++ {0x0310, 0x01},
++ {0x3ca0, 0x00},
++ {0x3ca1, 0x64},
++ {0x3ca4, 0x00},
++ {0x3ca5, 0x00},
++ {0x3ca6, 0x00},
++ {0x3ca7, 0x00},
++ {0x3caa, 0x00},
++ {0x3cab, 0x00},
++ {0x3cb8, 0x00},
++ {0x3cb9, 0x08},
++ {0x3cba, 0x00},
++ {0x3cbb, 0x00},
++ {0x3cbc, 0x00},
++ {0x3cbd, 0x3c},
++ {0x3cbe, 0x00},
++ {0x3cbf, 0x00},
++ {0x0202, 0x0a},
++ {0x0203, 0x29},
++ {0x0224, 0x01},
++ {0x0225, 0xf4},
++ {0x3116, 0x01},
++ {0x3117, 0xf4},
++ {0x0204, 0x00},
++ {0x0205, 0x00},
++ {0x0216, 0x00},
++ {0x0217, 0x00},
++ {0x0218, 0x01},
++ {0x0219, 0x00},
++ {0x020e, 0x01},
++ {0x020f, 0x00},
++ {0x3118, 0x00},
++ {0x3119, 0x00},
++ {0x311a, 0x01},
++ {0x311b, 0x00},
++ {0x341a, 0x00},
++ {0x341b, 0x00},
++ {0x341c, 0x00},
++ {0x341d, 0x00},
++ {0x341e, 0x01},
++ {0x341f, 0x20},
++ {0x3420, 0x00},
++ {0x3421, 0xd8},
++ {0xc428, 0x00},
++ {0xc429, 0x04},
++ {0x3366, 0x00},
++ {0x3367, 0x00},
++ {0x3368, 0x00},
++ {0x3369, 0x00},
++};
++
++static const struct imx708_reg mode_2x2binned_regs[] = {
++ {0x0342, 0x1e},
++ {0x0343, 0x90},
++ {0x0340, 0x05},
++ {0x0341, 0x38},
++ {0x0344, 0x00},
++ {0x0345, 0x00},
++ {0x0346, 0x00},
++ {0x0347, 0x00},
++ {0x0348, 0x11},
++ {0x0349, 0xff},
++ {0x034a, 0x0a},
++ {0x034b, 0x1f},
++ {0x0220, 0x62},
++ {0x0222, 0x01},
++ {0x0900, 0x01},
++ {0x0901, 0x22},
++ {0x0902, 0x08},
++ {0x3200, 0x41},
++ {0x3201, 0x41},
++ {0x32d5, 0x00},
++ {0x32d6, 0x00},
++ {0x32db, 0x01},
++ {0x32df, 0x00},
++ {0x350c, 0x00},
++ {0x350d, 0x00},
++ {0x0408, 0x00},
++ {0x0409, 0x00},
++ {0x040a, 0x00},
++ {0x040b, 0x00},
++ {0x040c, 0x09},
++ {0x040d, 0x00},
++ {0x040e, 0x05},
++ {0x040f, 0x10},
++ {0x034c, 0x09},
++ {0x034d, 0x00},
++ {0x034e, 0x05},
++ {0x034f, 0x10},
++ {0x0301, 0x05},
++ {0x0303, 0x02},
++ {0x0305, 0x02},
++ {0x0306, 0x00},
++ {0x0307, 0x7a},
++ {0x030b, 0x02},
++ {0x030d, 0x04},
++ {0x030e, 0x01},
++ {0x030f, 0x2c},
++ {0x0310, 0x01},
++ {0x3ca0, 0x00},
++ {0x3ca1, 0x3c},
++ {0x3ca4, 0x00},
++ {0x3ca5, 0x3c},
++ {0x3ca6, 0x00},
++ {0x3ca7, 0x00},
++ {0x3caa, 0x00},
++ {0x3cab, 0x00},
++ {0x3cb8, 0x00},
++ {0x3cb9, 0x1c},
++ {0x3cba, 0x00},
++ {0x3cbb, 0x08},
++ {0x3cbc, 0x00},
++ {0x3cbd, 0x1e},
++ {0x3cbe, 0x00},
++ {0x3cbf, 0x0a},
++ {0x0202, 0x05},
++ {0x0203, 0x08},
++ {0x0224, 0x01},
++ {0x0225, 0xf4},
++ {0x3116, 0x01},
++ {0x3117, 0xf4},
++ {0x0204, 0x00},
++ {0x0205, 0x70},
++ {0x0216, 0x00},
++ {0x0217, 0x70},
++ {0x0218, 0x01},
++ {0x0219, 0x00},
++ {0x020e, 0x01},
++ {0x020f, 0x00},
++ {0x3118, 0x00},
++ {0x3119, 0x70},
++ {0x311a, 0x01},
++ {0x311b, 0x00},
++ {0x341a, 0x00},
++ {0x341b, 0x00},
++ {0x341c, 0x00},
++ {0x341d, 0x00},
++ {0x341e, 0x00},
++ {0x341f, 0x90},
++ {0x3420, 0x00},
++ {0x3421, 0x6c},
++ {0x3366, 0x00},
++ {0x3367, 0x00},
++ {0x3368, 0x00},
++ {0x3369, 0x00},
++};
++
++static const struct imx708_reg mode_2x2binned_720p_regs[] = {
++ {0x0342, 0x14},
++ {0x0343, 0x60},
++ {0x0340, 0x04},
++ {0x0341, 0xb6},
++ {0x0344, 0x03},
++ {0x0345, 0x00},
++ {0x0346, 0x01},
++ {0x0347, 0xb0},
++ {0x0348, 0x0e},
++ {0x0349, 0xff},
++ {0x034a, 0x08},
++ {0x034b, 0x6f},
++ {0x0220, 0x62},
++ {0x0222, 0x01},
++ {0x0900, 0x01},
++ {0x0901, 0x22},
++ {0x0902, 0x08},
++ {0x3200, 0x41},
++ {0x3201, 0x41},
++ {0x32d5, 0x00},
++ {0x32d6, 0x00},
++ {0x32db, 0x01},
++ {0x32df, 0x01},
++ {0x350c, 0x00},
++ {0x350d, 0x00},
++ {0x0408, 0x00},
++ {0x0409, 0x00},
++ {0x040a, 0x00},
++ {0x040b, 0x00},
++ {0x040c, 0x06},
++ {0x040d, 0x00},
++ {0x040e, 0x03},
++ {0x040f, 0x60},
++ {0x034c, 0x06},
++ {0x034d, 0x00},
++ {0x034e, 0x03},
++ {0x034f, 0x60},
++ {0x0301, 0x05},
++ {0x0303, 0x02},
++ {0x0305, 0x02},
++ {0x0306, 0x00},
++ {0x0307, 0x76},
++ {0x030b, 0x02},
++ {0x030d, 0x04},
++ {0x030e, 0x01},
++ {0x030f, 0x2c},
++ {0x0310, 0x01},
++ {0x3ca0, 0x00},
++ {0x3ca1, 0x3c},
++ {0x3ca4, 0x01},
++ {0x3ca5, 0x5e},
++ {0x3ca6, 0x00},
++ {0x3ca7, 0x00},
++ {0x3caa, 0x00},
++ {0x3cab, 0x00},
++ {0x3cb8, 0x00},
++ {0x3cb9, 0x0c},
++ {0x3cba, 0x00},
++ {0x3cbb, 0x04},
++ {0x3cbc, 0x00},
++ {0x3cbd, 0x1e},
++ {0x3cbe, 0x00},
++ {0x3cbf, 0x05},
++ {0x0202, 0x04},
++ {0x0203, 0x86},
++ {0x0224, 0x01},
++ {0x0225, 0xf4},
++ {0x3116, 0x01},
++ {0x3117, 0xf4},
++ {0x0204, 0x00},
++ {0x0205, 0x70},
++ {0x0216, 0x00},
++ {0x0217, 0x70},
++ {0x0218, 0x01},
++ {0x0219, 0x00},
++ {0x020e, 0x01},
++ {0x020f, 0x00},
++ {0x3118, 0x00},
++ {0x3119, 0x70},
++ {0x311a, 0x01},
++ {0x311b, 0x00},
++ {0x341a, 0x00},
++ {0x341b, 0x00},
++ {0x341c, 0x00},
++ {0x341d, 0x00},
++ {0x341e, 0x00},
++ {0x341f, 0x60},
++ {0x3420, 0x00},
++ {0x3421, 0x48},
++ {0x3366, 0x00},
++ {0x3367, 0x00},
++ {0x3368, 0x00},
++ {0x3369, 0x00},
++};
++
++static const struct imx708_reg mode_hdr_regs[] = {
++ {0x0342, 0x14},
++ {0x0343, 0x60},
++ {0x0340, 0x0a},
++ {0x0341, 0x5b},
++ {0x0344, 0x00},
++ {0x0345, 0x00},
++ {0x0346, 0x00},
++ {0x0347, 0x00},
++ {0x0348, 0x11},
++ {0x0349, 0xff},
++ {0x034a, 0x0a},
++ {0x034b, 0x1f},
++ {0x0220, 0x01},
++ {0x0222, IMX708_HDR_EXPOSURE_RATIO},
++ {0x0900, 0x00},
++ {0x0901, 0x11},
++ {0x0902, 0x0a},
++ {0x3200, 0x01},
++ {0x3201, 0x01},
++ {0x32d5, 0x00},
++ {0x32d6, 0x00},
++ {0x32db, 0x01},
++ {0x32df, 0x00},
++ {0x350c, 0x00},
++ {0x350d, 0x00},
++ {0x0408, 0x00},
++ {0x0409, 0x00},
++ {0x040a, 0x00},
++ {0x040b, 0x00},
++ {0x040c, 0x09},
++ {0x040d, 0x00},
++ {0x040e, 0x05},
++ {0x040f, 0x10},
++ {0x034c, 0x09},
++ {0x034d, 0x00},
++ {0x034e, 0x05},
++ {0x034f, 0x10},
++ {0x0301, 0x05},
++ {0x0303, 0x02},
++ {0x0305, 0x02},
++ {0x0306, 0x00},
++ {0x0307, 0xa2},
++ {0x030b, 0x02},
++ {0x030d, 0x04},
++ {0x030e, 0x01},
++ {0x030f, 0x2c},
++ {0x0310, 0x01},
++ {0x3ca0, 0x00},
++ {0x3ca1, 0x00},
++ {0x3ca4, 0x00},
++ {0x3ca5, 0x00},
++ {0x3ca6, 0x00},
++ {0x3ca7, 0x28},
++ {0x3caa, 0x00},
++ {0x3cab, 0x00},
++ {0x3cb8, 0x00},
++ {0x3cb9, 0x30},
++ {0x3cba, 0x00},
++ {0x3cbb, 0x00},
++ {0x3cbc, 0x00},
++ {0x3cbd, 0x32},
++ {0x3cbe, 0x00},
++ {0x3cbf, 0x00},
++ {0x0202, 0x0a},
++ {0x0203, 0x2b},
++ {0x0224, 0x0a},
++ {0x0225, 0x2b},
++ {0x3116, 0x0a},
++ {0x3117, 0x2b},
++ {0x0204, 0x00},
++ {0x0205, 0x00},
++ {0x0216, 0x00},
++ {0x0217, 0x00},
++ {0x0218, 0x01},
++ {0x0219, 0x00},
++ {0x020e, 0x01},
++ {0x020f, 0x00},
++ {0x3118, 0x00},
++ {0x3119, 0x00},
++ {0x311a, 0x01},
++ {0x311b, 0x00},
++ {0x341a, 0x00},
++ {0x341b, 0x00},
++ {0x341c, 0x00},
++ {0x341d, 0x00},
++ {0x341e, 0x00},
++ {0x341f, 0x90},
++ {0x3420, 0x00},
++ {0x3421, 0x6c},
++ {0x3360, 0x01},
++ {0x3361, 0x01},
++ {0x3366, 0x09},
++ {0x3367, 0x00},
++ {0x3368, 0x05},
++ {0x3369, 0x10},
++};
++
++/* Mode configs. Keep separate lists for when HDR is enabled or not. */
++static const struct imx708_mode supported_modes_10bit_no_hdr[] = {
++ {
++ /* Full resolution. */
++ .width = 4608,
++ .height = 2592,
++ .line_length_pix = 0x3d20,
++ .crop = {
++ .left = IMX708_PIXEL_ARRAY_LEFT,
++ .top = IMX708_PIXEL_ARRAY_TOP,
++ .width = 4608,
++ .height = 2592,
++ },
++ .vblank_min = 58,
++ .vblank_default = 58,
++ .reg_list = {
++ .num_of_regs = ARRAY_SIZE(mode_4608x2592_regs),
++ .regs = mode_4608x2592_regs,
++ },
++ .pixel_rate = 595200000,
++ .exposure_lines_min = 8,
++ .exposure_lines_step = 1,
++ .hdr = false
++ },
++ {
++ /* regular 2x2 binned. */
++ .width = 2304,
++ .height = 1296,
++ .line_length_pix = 0x1e90,
++ .crop = {
++ .left = IMX708_PIXEL_ARRAY_LEFT,
++ .top = IMX708_PIXEL_ARRAY_TOP,
++ .width = 4608,
++ .height = 2592,
++ },
++ .vblank_min = 40,
++ .vblank_default = 1198,
++ .reg_list = {
++ .num_of_regs = ARRAY_SIZE(mode_2x2binned_regs),
++ .regs = mode_2x2binned_regs,
++ },
++ .pixel_rate = 585600000,
++ .exposure_lines_min = 4,
++ .exposure_lines_step = 2,
++ .hdr = false
++ },
++ {
++ /* 2x2 binned and cropped for 720p. */
++ .width = 1536,
++ .height = 864,
++ .line_length_pix = 0x1460,
++ .crop = {
++ .left = IMX708_PIXEL_ARRAY_LEFT + 768,
++ .top = IMX708_PIXEL_ARRAY_TOP + 432,
++ .width = 3072,
++ .height = 1728,
++ },
++ .vblank_min = 40,
++ .vblank_default = 2755,
++ .reg_list = {
++ .num_of_regs = ARRAY_SIZE(mode_2x2binned_720p_regs),
++ .regs = mode_2x2binned_720p_regs,
++ },
++ .pixel_rate = 566400000,
++ .exposure_lines_min = 4,
++ .exposure_lines_step = 2,
++ .hdr = false
++ },
++};
++
++static const struct imx708_mode supported_modes_10bit_hdr[] = {
++ {
++ /* There's only one HDR mode, which is 2x2 downscaled */
++ .width = 2304,
++ .height = 1296,
++ .line_length_pix = 0x1460,
++ .crop = {
++ .left = IMX708_PIXEL_ARRAY_LEFT,
++ .top = IMX708_PIXEL_ARRAY_TOP,
++ .width = 4608,
++ .height = 2592,
++ },
++ .vblank_min = 3673,
++ .vblank_default = 3673,
++ .reg_list = {
++ .num_of_regs = ARRAY_SIZE(mode_hdr_regs),
++ .regs = mode_hdr_regs,
++ },
++ .pixel_rate = 777600000,
++ .exposure_lines_min = 8 * IMX708_HDR_EXPOSURE_RATIO *
++ IMX708_HDR_EXPOSURE_RATIO,
++ .exposure_lines_step = 2 * IMX708_HDR_EXPOSURE_RATIO *
++ IMX708_HDR_EXPOSURE_RATIO,
++ .hdr = true
++ }
++};
++
++/*
++ * 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,
++};
++
++static const char * const imx708_test_pattern_menu[] = {
++ "Disabled",
++ "Color Bars",
++ "Solid Color",
++ "Grey Color Bars",
++ "PN9"
++};
++
++static const int imx708_test_pattern_val[] = {
++ IMX708_TEST_PATTERN_DISABLE,
++ IMX708_TEST_PATTERN_COLOR_BARS,
++ IMX708_TEST_PATTERN_SOLID_COLOR,
++ IMX708_TEST_PATTERN_GREY_COLOR,
++ IMX708_TEST_PATTERN_PN9,
++};
++
++/* regulator supplies */
++static const char * const imx708_supply_name[] = {
++ /* Supplies can be enabled in any order */
++ "VANA1", /* Analog1 (2.8V) supply */
++ "VANA2", /* Analog2 (1.8V) supply */
++ "VDIG", /* Digital Core (1.1V) supply */
++ "VDDL", /* IF (1.8V) supply */
++};
++
++#define IMX708_NUM_SUPPLIES ARRAY_SIZE(imx708_supply_name)
++
++/*
++ * Initialisation delay between XCLR low->high and the moment when the sensor
++ * can start capture (i.e. can leave software standby), given by T7 in the
++ * datasheet is 8ms. This does include I2C setup time as well.
++ *
++ * Note, that delay between XCLR low->high and reading the CCI ID register (T6
++ * in the datasheet) is much smaller - 600us.
++ */
++#define IMX708_XCLR_MIN_DELAY_US 8000
++#define IMX708_XCLR_DELAY_RANGE_US 1000
++
++struct imx708 {
++ struct v4l2_subdev sd;
++ struct media_pad pad;
++
++ struct v4l2_mbus_framefmt fmt;
++
++ struct clk *xclk;
++ u32 xclk_freq;
++
++ struct gpio_desc *reset_gpio;
++ struct regulator_bulk_data supplies[IMX708_NUM_SUPPLIES];
++
++ struct v4l2_ctrl_handler ctrl_handler;
++ /* V4L2 Controls */
++ struct v4l2_ctrl *pixel_rate;
++ struct v4l2_ctrl *exposure;
++ struct v4l2_ctrl *vflip;
++ struct v4l2_ctrl *hflip;
++ struct v4l2_ctrl *vblank;
++ struct v4l2_ctrl *hblank;
++ struct v4l2_ctrl *red_balance;
++ struct v4l2_ctrl *blue_balance;
++ struct v4l2_ctrl *notify_gains;
++ struct v4l2_ctrl *hdr_mode;
++
++ /* Current mode */
++ const struct imx708_mode *mode;
++
++ /* Mutex for serialized access */
++ 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 imx708 *to_imx708(struct v4l2_subdev *_sd)
++{
++ return container_of(_sd, struct imx708, sd);
++}
++
++static inline void get_mode_table(const struct imx708_mode **mode_list,
++ unsigned int *num_modes,
++ bool hdr_enable)
++{
++ if (hdr_enable) {
++ *mode_list = supported_modes_10bit_hdr;
++ *num_modes = ARRAY_SIZE(supported_modes_10bit_hdr);
++ } else {
++ *mode_list = supported_modes_10bit_no_hdr;
++ *num_modes = ARRAY_SIZE(supported_modes_10bit_no_hdr);
++ }
++}
++
++/* Read registers up to 2 at a time */
++static int imx708_read_reg(struct imx708 *imx708, u16 reg, u32 len, u32 *val)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(&imx708->sd);
++ struct i2c_msg msgs[2];
++ u8 addr_buf[2] = { reg >> 8, reg & 0xff };
++ u8 data_buf[4] = { 0, };
++ int ret;
++
++ if (len > 4)
++ return -EINVAL;
++
++ /* Write register address */
++ msgs[0].addr = client->addr;
++ msgs[0].flags = 0;
++ msgs[0].len = ARRAY_SIZE(addr_buf);
++ msgs[0].buf = addr_buf;
++
++ /* Read data from register */
++ msgs[1].addr = client->addr;
++ msgs[1].flags = I2C_M_RD;
++ msgs[1].len = len;
++ msgs[1].buf = &data_buf[4 - len];
++
++ ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
++ if (ret != ARRAY_SIZE(msgs))
++ return -EIO;
++
++ *val = get_unaligned_be32(data_buf);
++
++ return 0;
++}
++
++/* Write registers up to 2 at a time */
++static int imx708_write_reg(struct imx708 *imx708, u16 reg, u32 len, u32 val)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(&imx708->sd);
++ u8 buf[6];
++
++ if (len > 4)
++ return -EINVAL;
++
++ put_unaligned_be16(reg, buf);
++ put_unaligned_be32(val << (8 * (4 - len)), buf + 2);
++ if (i2c_master_send(client, buf, len + 2) != len + 2)
++ return -EIO;
++
++ return 0;
++}
++
++/* Write a list of registers */
++static int imx708_write_regs(struct imx708 *imx708,
++ const struct imx708_reg *regs, u32 len)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(&imx708->sd);
++ unsigned int i;
++ int ret;
++
++ for (i = 0; i < len; i++) {
++ ret = imx708_write_reg(imx708, regs[i].address, 1, regs[i].val);
++ if (ret) {
++ dev_err_ratelimited(&client->dev,
++ "Failed to write reg 0x%4.4x. error = %d\n",
++ regs[i].address, ret);
++
++ return ret;
++ }
++ }
++
++ return 0;
++}
++
++/* Get bayer order based on flip setting. */
++static u32 imx708_get_format_code(struct imx708 *imx708)
++{
++ unsigned int i;
++
++ lockdep_assert_held(&imx708->mutex);
++
++ i = (imx708->vflip->val ? 2 : 0) |
++ (imx708->hflip->val ? 1 : 0);
++
++ return codes[i];
++}
++
++static void imx708_set_default_format(struct imx708 *imx708)
++{
++ struct v4l2_mbus_framefmt *fmt = &imx708->fmt;
++
++ /* Set default mode to max resolution */
++ imx708->mode = &supported_modes_10bit_no_hdr[0];
++
++ /* fmt->code not set as it will always be computed based on flips */
++ fmt->colorspace = V4L2_COLORSPACE_RAW;
++ fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->colorspace);
++ fmt->quantization = V4L2_MAP_QUANTIZATION_DEFAULT(true,
++ fmt->colorspace,
++ fmt->ycbcr_enc);
++ fmt->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(fmt->colorspace);
++ fmt->width = imx708->mode->width;
++ fmt->height = imx708->mode->height;
++ fmt->field = V4L2_FIELD_NONE;
++}
++
++static int imx708_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
++{
++ struct imx708 *imx708 = to_imx708(sd);
++ struct v4l2_mbus_framefmt *try_fmt_img =
++ v4l2_subdev_get_try_format(sd, fh->state, 0);
++ struct v4l2_rect *try_crop;
++
++ mutex_lock(&imx708->mutex);
++
++ /* Initialize try_fmt for the image pad */
++ if (imx708->hdr_mode->val) {
++ try_fmt_img->width = supported_modes_10bit_hdr[0].width;
++ try_fmt_img->height = supported_modes_10bit_hdr[0].height;
++ } else {
++ try_fmt_img->width = supported_modes_10bit_no_hdr[0].width;
++ try_fmt_img->height = supported_modes_10bit_no_hdr[0].height;
++ }
++ try_fmt_img->code = imx708_get_format_code(imx708);
++ try_fmt_img->field = V4L2_FIELD_NONE;
++
++ /* Initialize try_crop */
++ try_crop = v4l2_subdev_get_try_crop(sd, fh->state, 0);
++ try_crop->left = IMX708_PIXEL_ARRAY_LEFT;
++ try_crop->top = IMX708_PIXEL_ARRAY_TOP;
++ try_crop->width = IMX708_PIXEL_ARRAY_WIDTH;
++ try_crop->height = IMX708_PIXEL_ARRAY_HEIGHT;
++
++ mutex_unlock(&imx708->mutex);
++
++ return 0;
++}
++
++static int imx708_set_exposure(struct imx708 *imx708, unsigned int val)
++{
++ int ret;
++
++ val = max(val, imx708->mode->exposure_lines_min);
++ val -= val % imx708->mode->exposure_lines_step;
++
++ /*
++ * In HDR mode this will set the longest exposure. The sensor
++ * will automatically divide the medium and short ones by 4,16.
++ */
++ ret = imx708_write_reg(imx708, IMX708_REG_EXPOSURE,
++ IMX708_REG_VALUE_16BIT,
++ val >> imx708->long_exp_shift);
++
++ return ret;
++}
++
++static void imx708_adjust_exposure_range(struct imx708 *imx708,
++ struct v4l2_ctrl *ctrl)
++{
++ int exposure_max, exposure_def;
++
++ /* Honour the VBLANK limits when setting exposure. */
++ exposure_max = imx708->mode->height + imx708->vblank->val -
++ IMX708_EXPOSURE_OFFSET;
++ exposure_def = min(exposure_max, imx708->exposure->val);
++ __v4l2_ctrl_modify_range(imx708->exposure, imx708->exposure->minimum,
++ exposure_max, imx708->exposure->step,
++ exposure_def);
++}
++
++static int imx708_set_analogue_gain(struct imx708 *imx708, unsigned int val)
++{
++ int ret;
++
++ /*
++ * In HDR mode this will set the gain for the longest exposure,
++ * and by default the sensor uses the same gain for all of them.
++ */
++ ret = imx708_write_reg(imx708, IMX708_REG_ANALOG_GAIN,
++ IMX708_REG_VALUE_16BIT, val);
++
++ return ret;
++}
++
++static int imx708_set_frame_length(struct imx708 *imx708, unsigned int val)
++{
++ int ret = 0;
++
++ imx708->long_exp_shift = 0;
++
++ while (val > IMX708_FRAME_LENGTH_MAX) {
++ imx708->long_exp_shift++;
++ val >>= 1;
++ }
++
++ ret = imx708_write_reg(imx708, IMX708_REG_FRAME_LENGTH,
++ IMX708_REG_VALUE_16BIT, val);
++ if (ret)
++ return ret;
++
++ return imx708_write_reg(imx708, IMX708_LONG_EXP_SHIFT_REG,
++ IMX708_REG_VALUE_08BIT, imx708->long_exp_shift);
++}
++
++static void imx708_set_framing_limits(struct imx708 *imx708)
++{
++ unsigned int hblank;
++ const struct imx708_mode *mode = imx708->mode;
++
++ /* Default to no long exposure multiplier */
++ imx708->long_exp_shift = 0;
++
++ __v4l2_ctrl_modify_range(imx708->pixel_rate,
++ mode->pixel_rate, mode->pixel_rate,
++ 1, mode->pixel_rate);
++
++ /* Update limits and set FPS to default */
++ __v4l2_ctrl_modify_range(imx708->vblank, mode->vblank_min,
++ ((1 << IMX708_LONG_EXP_SHIFT_MAX) *
++ IMX708_FRAME_LENGTH_MAX) - mode->height,
++ 1, mode->vblank_default);
++
++ /*
++ * Currently PPL is fixed to the mode specified value, so hblank
++ * depends on mode->width only, and is not changeable in any
++ * way other than changing the mode.
++ */
++ hblank = mode->line_length_pix - mode->width;
++ __v4l2_ctrl_modify_range(imx708->hblank, hblank, hblank, 1, hblank);
++}
++
++static int imx708_set_ctrl(struct v4l2_ctrl *ctrl)
++{
++ struct imx708 *imx708 =
++ container_of(ctrl->handler, struct imx708, ctrl_handler);
++ struct i2c_client *client = v4l2_get_subdevdata(&imx708->sd);
++ const struct imx708_mode *mode_list;
++ unsigned int num_modes;
++ int ret;
++
++ /*
++ * The VBLANK control may change the limits of usable exposure, so check
++ * and adjust if necessary.
++ */
++ if (ctrl->id == V4L2_CID_VBLANK)
++ imx708_adjust_exposure_range(imx708, ctrl);
++
++ /*
++ * Applying V4L2 control value only happens
++ * when power is up for streaming
++ */
++ if (!pm_runtime_get_if_in_use(&client->dev))
++ return 0;
++
++ switch (ctrl->id) {
++ case V4L2_CID_ANALOGUE_GAIN:
++ ret = imx708_set_analogue_gain(imx708, ctrl->val);
++ break;
++ case V4L2_CID_EXPOSURE:
++ ret = imx708_set_exposure(imx708, ctrl->val);
++ break;
++ case V4L2_CID_DIGITAL_GAIN:
++ ret = imx708_write_reg(imx708, IMX708_REG_DIGITAL_GAIN,
++ IMX708_REG_VALUE_16BIT, ctrl->val);
++ break;
++ case V4L2_CID_TEST_PATTERN:
++ ret = imx708_write_reg(imx708, IMX708_REG_TEST_PATTERN,
++ IMX708_REG_VALUE_16BIT,
++ imx708_test_pattern_val[ctrl->val]);
++ break;
++ case V4L2_CID_TEST_PATTERN_RED:
++ ret = imx708_write_reg(imx708, IMX708_REG_TEST_PATTERN_R,
++ IMX708_REG_VALUE_16BIT, ctrl->val);
++ break;
++ case V4L2_CID_TEST_PATTERN_GREENR:
++ ret = imx708_write_reg(imx708, IMX708_REG_TEST_PATTERN_GR,
++ IMX708_REG_VALUE_16BIT, ctrl->val);
++ break;
++ case V4L2_CID_TEST_PATTERN_BLUE:
++ ret = imx708_write_reg(imx708, IMX708_REG_TEST_PATTERN_B,
++ IMX708_REG_VALUE_16BIT, ctrl->val);
++ break;
++ case V4L2_CID_TEST_PATTERN_GREENB:
++ ret = imx708_write_reg(imx708, IMX708_REG_TEST_PATTERN_GB,
++ IMX708_REG_VALUE_16BIT, ctrl->val);
++ break;
++ case V4L2_CID_HFLIP:
++ case V4L2_CID_VFLIP:
++ ret = imx708_write_reg(imx708, IMX708_REG_ORIENTATION, 1,
++ imx708->hflip->val |
++ imx708->vflip->val << 1);
++ break;
++ case V4L2_CID_VBLANK:
++ ret = imx708_set_frame_length(imx708,
++ imx708->mode->height + ctrl->val);
++ break;
++ case V4L2_CID_NOTIFY_GAINS:
++ ret = imx708_write_reg(imx708, IMX708_REG_COLOUR_BALANCE_BLUE,
++ IMX708_REG_VALUE_16BIT,
++ imx708->notify_gains->p_new.p_u32[0]);
++ if (ret)
++ break;
++ ret = imx708_write_reg(imx708, IMX708_REG_COLOUR_BALANCE_RED,
++ IMX708_REG_VALUE_16BIT,
++ imx708->notify_gains->p_new.p_u32[3]);
++ break;
++ case V4L2_CID_WIDE_DYNAMIC_RANGE:
++ get_mode_table(&mode_list, &num_modes, ctrl->val);
++ imx708->mode = v4l2_find_nearest_size(mode_list,
++ num_modes,
++ width, height,
++ imx708->mode->width,
++ imx708->mode->height);
++ imx708_set_framing_limits(imx708);
++ ret = 0;
++ 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 imx708_ctrl_ops = {
++ .s_ctrl = imx708_set_ctrl,
++};
++
++static int imx708_enum_mbus_code(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *sd_state,
++ struct v4l2_subdev_mbus_code_enum *code)
++{
++ struct imx708 *imx708 = to_imx708(sd);
++
++ if (code->index >= 1)
++ return -EINVAL;
++
++ code->code = imx708_get_format_code(imx708);
++
++ return 0;
++}
++
++static int imx708_enum_frame_size(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *sd_state,
++ struct v4l2_subdev_frame_size_enum *fse)
++{
++ struct imx708 *imx708 = to_imx708(sd);
++ const struct imx708_mode *mode_list;
++ unsigned int num_modes;
++
++ get_mode_table(&mode_list, &num_modes, imx708->hdr_mode->val);
++
++ if (fse->index >= num_modes)
++ return -EINVAL;
++
++ if (fse->code != imx708_get_format_code(imx708))
++ 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 imx708_reset_colorspace(struct v4l2_mbus_framefmt *fmt)
++{
++ fmt->colorspace = V4L2_COLORSPACE_RAW;
++ fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->colorspace);
++ fmt->quantization = V4L2_MAP_QUANTIZATION_DEFAULT(true,
++ fmt->colorspace,
++ fmt->ycbcr_enc);
++ fmt->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(fmt->colorspace);
++}
++
++static void imx708_update_image_pad_format(struct imx708 *imx708,
++ const struct imx708_mode *mode,
++ struct v4l2_subdev_format *fmt)
++{
++ fmt->format.width = mode->width;
++ fmt->format.height = mode->height;
++ fmt->format.field = V4L2_FIELD_NONE;
++ imx708_reset_colorspace(&fmt->format);
++}
++
++static int imx708_get_pad_format(struct v4l2_subdev *sd,
++ struct v4l2_subdev_state *sd_state,
++ struct v4l2_subdev_format *fmt)
++{
++ struct imx708 *imx708 = to_imx708(sd);
++
++ mutex_lock(&imx708->mutex);
++
++ if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
++ struct v4l2_mbus_framefmt *try_fmt =
++ v4l2_subdev_get_try_format(&imx708->sd, sd_state,
++ fmt->pad);
++ /* update the code which could change due to vflip or hflip */
++ try_fmt->code = imx708_get_format_code(imx708);
++ fmt->format = *try_fmt;
++ } else {
++ imx708_update_image_pad_format(imx708, imx708->mode, fmt);
++ fmt->format.code = imx708_get_format_code(imx708);
++ }
++
++ mutex_unlock(&imx708->mutex);
++ return 0;
++}
++
++static int imx708_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 imx708_mode *mode;
++ struct imx708 *imx708 = to_imx708(sd);
++ const struct imx708_mode *mode_list;
++ unsigned int num_modes;
++
++ mutex_lock(&imx708->mutex);
++
++ /* Bayer order varies with flips */
++ fmt->format.code = imx708_get_format_code(imx708);
++
++ get_mode_table(&mode_list, &num_modes, imx708->hdr_mode->val);
++
++ mode = v4l2_find_nearest_size(mode_list, num_modes, width, height,
++ fmt->format.width, fmt->format.height);
++ imx708_update_image_pad_format(imx708, mode, fmt);
++
++ if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
++ framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad);
++ *framefmt = fmt->format;
++ } else {
++ imx708->mode = mode;
++ imx708_set_framing_limits(imx708);
++ }
++
++ mutex_unlock(&imx708->mutex);
++
++ return 0;
++}
++
++static const struct v4l2_rect *
++__imx708_get_pad_crop(struct imx708 *imx708, 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(&imx708->sd, sd_state, pad);
++ case V4L2_SUBDEV_FORMAT_ACTIVE:
++ return &imx708->mode->crop;
++ }
++
++ return NULL;
++}
++
++static int imx708_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 imx708 *imx708 = to_imx708(sd);
++
++ mutex_lock(&imx708->mutex);
++ sel->r = *__imx708_get_pad_crop(imx708, sd_state, sel->pad,
++ sel->which);
++ mutex_unlock(&imx708->mutex);
++
++ return 0;
++ }
++
++ case V4L2_SEL_TGT_NATIVE_SIZE:
++ sel->r.left = 0;
++ sel->r.top = 0;
++ sel->r.width = IMX708_NATIVE_WIDTH;
++ sel->r.height = IMX708_NATIVE_HEIGHT;
++
++ return 0;
++
++ case V4L2_SEL_TGT_CROP_DEFAULT:
++ case V4L2_SEL_TGT_CROP_BOUNDS:
++ sel->r.left = IMX708_PIXEL_ARRAY_LEFT;
++ sel->r.top = IMX708_PIXEL_ARRAY_TOP;
++ sel->r.width = IMX708_PIXEL_ARRAY_WIDTH;
++ sel->r.height = IMX708_PIXEL_ARRAY_HEIGHT;
++
++ return 0;
++ }
++
++ return -EINVAL;
++}
++
++/* Start streaming */
++static int imx708_start_streaming(struct imx708 *imx708)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(&imx708->sd);
++ const struct imx708_reg_list *reg_list;
++ int i, ret;
++ u32 val;
++
++ if (!imx708->common_regs_written) {
++ ret = imx708_write_regs(imx708, mode_common_regs,
++ ARRAY_SIZE(mode_common_regs));
++ if (ret) {
++ dev_err(&client->dev, "%s failed to set common settings\n",
++ __func__);
++ return ret;
++ }
++
++ ret = imx708_read_reg(imx708, IMX708_REG_BASE_SPC_GAINS_L,
++ IMX708_REG_VALUE_08BIT, &val);
++ if (ret == 0 && val == 0x40) {
++ for (i = 0; i < 54 && ret == 0; i++) {
++ u16 reg = IMX708_REG_BASE_SPC_GAINS_L + i;
++
++ ret = imx708_write_reg(imx708, reg,
++ IMX708_REG_VALUE_08BIT,
++ pdaf_gains[0][i % 9]);
++ }
++ for (i = 0; i < 54 && ret == 0; i++) {
++ u16 reg = IMX708_REG_BASE_SPC_GAINS_R + i;
++
++ ret = imx708_write_reg(imx708, reg,
++ IMX708_REG_VALUE_08BIT,
++ pdaf_gains[1][i % 9]);
++ }
++ }
++ if (ret) {
++ dev_err(&client->dev, "%s failed to set PDAF gains\n",
++ __func__);
++ return ret;
++ }
++
++ imx708->common_regs_written = true;
++ }
++
++ /* Apply default values of current mode */
++ reg_list = &imx708->mode->reg_list;
++ ret = imx708_write_regs(imx708, reg_list->regs, reg_list->num_of_regs);
++ 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(imx708->sd.ctrl_handler);
++ if (ret)
++ return ret;
++
++ /* set stream on register */
++ return imx708_write_reg(imx708, IMX708_REG_MODE_SELECT,
++ IMX708_REG_VALUE_08BIT, IMX708_MODE_STREAMING);
++}
++
++/* Stop streaming */
++static void imx708_stop_streaming(struct imx708 *imx708)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(&imx708->sd);
++ int ret;
++
++ /* set stream off register */
++ ret = imx708_write_reg(imx708, IMX708_REG_MODE_SELECT,
++ IMX708_REG_VALUE_08BIT, IMX708_MODE_STANDBY);
++ if (ret)
++ dev_err(&client->dev, "%s failed to set stream\n", __func__);
++}
++
++static int imx708_set_stream(struct v4l2_subdev *sd, int enable)
++{
++ struct imx708 *imx708 = to_imx708(sd);
++ struct i2c_client *client = v4l2_get_subdevdata(sd);
++ int ret = 0;
++
++ mutex_lock(&imx708->mutex);
++ if (imx708->streaming == enable) {
++ mutex_unlock(&imx708->mutex);
++ return 0;
++ }
++
++ if (enable) {
++ ret = pm_runtime_resume_and_get(&client->dev);
++ if (ret < 0)
++ goto err_unlock;
++
++ /*
++ * Apply default & customized values
++ * and then start streaming.
++ */
++ ret = imx708_start_streaming(imx708);
++ if (ret)
++ goto err_rpm_put;
++ } else {
++ imx708_stop_streaming(imx708);
++ pm_runtime_mark_last_busy(&client->dev);
++ pm_runtime_put_autosuspend(&client->dev);
++ }
++
++ imx708->streaming = enable;
++
++ /* vflip/hflip and hdr mode cannot change during streaming */
++ __v4l2_ctrl_grab(imx708->vflip, enable);
++ __v4l2_ctrl_grab(imx708->hflip, enable);
++ __v4l2_ctrl_grab(imx708->hdr_mode, enable);
++
++ mutex_unlock(&imx708->mutex);
++
++ return ret;
++
++err_rpm_put:
++ pm_runtime_put_sync(&client->dev);
++err_unlock:
++ mutex_unlock(&imx708->mutex);
++
++ return ret;
++}
++
++/* Power/clock management functions */
++static int imx708_power_on(struct device *dev)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ struct v4l2_subdev *sd = i2c_get_clientdata(client);
++ struct imx708 *imx708 = to_imx708(sd);
++ int ret;
++
++ ret = regulator_bulk_enable(IMX708_NUM_SUPPLIES,
++ imx708->supplies);
++ if (ret) {
++ dev_err(&client->dev, "%s: failed to enable regulators\n",
++ __func__);
++ return ret;
++ }
++
++ ret = clk_prepare_enable(imx708->xclk);
++ if (ret) {
++ dev_err(&client->dev, "%s: failed to enable clock\n",
++ __func__);
++ goto reg_off;
++ }
++
++ gpiod_set_value_cansleep(imx708->reset_gpio, 1);
++ usleep_range(IMX708_XCLR_MIN_DELAY_US,
++ IMX708_XCLR_MIN_DELAY_US + IMX708_XCLR_DELAY_RANGE_US);
++
++ return 0;
++
++reg_off:
++ regulator_bulk_disable(IMX708_NUM_SUPPLIES, imx708->supplies);
++ return ret;
++}
++
++static int imx708_power_off(struct device *dev)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ struct v4l2_subdev *sd = i2c_get_clientdata(client);
++ struct imx708 *imx708 = to_imx708(sd);
++
++ gpiod_set_value_cansleep(imx708->reset_gpio, 0);
++ clk_disable_unprepare(imx708->xclk);
++ regulator_bulk_disable(IMX708_NUM_SUPPLIES, imx708->supplies);
++
++ /* Force reprogramming of the common registers when powered up again. */
++ imx708->common_regs_written = false;
++
++ return 0;
++}
++
++static int __maybe_unused imx708_suspend(struct device *dev)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ struct v4l2_subdev *sd = i2c_get_clientdata(client);
++ struct imx708 *imx708 = to_imx708(sd);
++
++ if (imx708->streaming)
++ imx708_stop_streaming(imx708);
++
++ return 0;
++}
++
++static int __maybe_unused imx708_resume(struct device *dev)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ struct v4l2_subdev *sd = i2c_get_clientdata(client);
++ struct imx708 *imx708 = to_imx708(sd);
++ int ret;
++
++ if (imx708->streaming) {
++ ret = imx708_start_streaming(imx708);
++ if (ret)
++ goto error;
++ }
++
++ return 0;
++
++error:
++ imx708_stop_streaming(imx708);
++ imx708->streaming = 0;
++ return ret;
++}
++
++static int imx708_get_regulators(struct imx708 *imx708)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(&imx708->sd);
++ unsigned int i;
++
++ for (i = 0; i < IMX708_NUM_SUPPLIES; i++)
++ imx708->supplies[i].supply = imx708_supply_name[i];
++
++ return devm_regulator_bulk_get(&client->dev,
++ IMX708_NUM_SUPPLIES,
++ imx708->supplies);
++}
++
++/* Verify chip ID */
++static int imx708_identify_module(struct imx708 *imx708)
++{
++ struct i2c_client *client = v4l2_get_subdevdata(&imx708->sd);
++ int ret;
++ u32 val;
++
++ ret = imx708_read_reg(imx708, IMX708_REG_CHIP_ID,
++ IMX708_REG_VALUE_16BIT, &val);
++ if (ret) {
++ dev_err(&client->dev, "failed to read chip id %x, with error %d\n",
++ IMX708_CHIP_ID, ret);
++ return ret;
++ }
++
++ if (val != IMX708_CHIP_ID) {
++ dev_err(&client->dev, "chip id mismatch: %x!=%x\n",
++ IMX708_CHIP_ID, val);
++ return -EIO;
++ }
++
++ return 0;
++}
++
++static const struct v4l2_subdev_core_ops imx708_core_ops = {
++ .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
++ .unsubscribe_event = v4l2_event_subdev_unsubscribe,
++};
++
++static const struct v4l2_subdev_video_ops imx708_video_ops = {
++ .s_stream = imx708_set_stream,
++};
++
++static const struct v4l2_subdev_pad_ops imx708_pad_ops = {
++ .enum_mbus_code = imx708_enum_mbus_code,
++ .get_fmt = imx708_get_pad_format,
++ .set_fmt = imx708_set_pad_format,
++ .get_selection = imx708_get_selection,
++ .enum_frame_size = imx708_enum_frame_size,
++};
++
++static const struct v4l2_subdev_ops imx708_subdev_ops = {
++ .core = &imx708_core_ops,
++ .video = &imx708_video_ops,
++ .pad = &imx708_pad_ops,
++};
++
++static const struct v4l2_subdev_internal_ops imx708_internal_ops = {
++ .open = imx708_open,
++};
++
++static const struct v4l2_ctrl_config imx708_notify_gains_ctrl = {
++ .ops = &imx708_ctrl_ops,
++ .id = V4L2_CID_NOTIFY_GAINS,
++ .type = V4L2_CTRL_TYPE_U32,
++ .min = IMX708_COLOUR_BALANCE_MIN,
++ .max = IMX708_COLOUR_BALANCE_MAX,
++ .step = IMX708_COLOUR_BALANCE_STEP,
++ .def = IMX708_COLOUR_BALANCE_DEFAULT,
++ .dims = { 4 },
++ .elem_size = sizeof(u32),
++};
++
++/* Initialize control handlers */
++static int imx708_init_controls(struct imx708 *imx708)
++{
++ struct v4l2_ctrl_handler *ctrl_hdlr;
++ struct i2c_client *client = v4l2_get_subdevdata(&imx708->sd);
++ struct v4l2_fwnode_device_properties props;
++ unsigned int i;
++ int ret;
++
++ ctrl_hdlr = &imx708->ctrl_handler;
++ ret = v4l2_ctrl_handler_init(ctrl_hdlr, 16);
++ if (ret)
++ return ret;
++
++ mutex_init(&imx708->mutex);
++ ctrl_hdlr->lock = &imx708->mutex;
++
++ /* By default, PIXEL_RATE is read only */
++ imx708->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &imx708_ctrl_ops,
++ V4L2_CID_PIXEL_RATE,
++ imx708->mode->pixel_rate,
++ imx708->mode->pixel_rate, 1,
++ imx708->mode->pixel_rate);
++
++ /*
++ * Create the controls here, but mode specific limits are setup
++ * in the imx708_set_framing_limits() call below.
++ */
++ imx708->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx708_ctrl_ops,
++ V4L2_CID_VBLANK, 0, 0xffff, 1, 0);
++ imx708->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx708_ctrl_ops,
++ V4L2_CID_HBLANK, 0, 0xffff, 1, 0);
++
++ imx708->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &imx708_ctrl_ops,
++ V4L2_CID_EXPOSURE,
++ IMX708_EXPOSURE_MIN,
++ IMX708_EXPOSURE_MAX,
++ IMX708_EXPOSURE_STEP,
++ IMX708_EXPOSURE_DEFAULT);
++
++ v4l2_ctrl_new_std(ctrl_hdlr, &imx708_ctrl_ops, V4L2_CID_ANALOGUE_GAIN,
++ IMX708_ANA_GAIN_MIN, IMX708_ANA_GAIN_MAX,
++ IMX708_ANA_GAIN_STEP, IMX708_ANA_GAIN_DEFAULT);
++
++ v4l2_ctrl_new_std(ctrl_hdlr, &imx708_ctrl_ops, V4L2_CID_DIGITAL_GAIN,
++ IMX708_DGTL_GAIN_MIN, IMX708_DGTL_GAIN_MAX,
++ IMX708_DGTL_GAIN_STEP, IMX708_DGTL_GAIN_DEFAULT);
++
++ imx708->hflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx708_ctrl_ops,
++ V4L2_CID_HFLIP, 0, 1, 1, 0);
++
++ imx708->vflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx708_ctrl_ops,
++ V4L2_CID_VFLIP, 0, 1, 1, 0);
++
++ v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &imx708_ctrl_ops,
++ V4L2_CID_TEST_PATTERN,
++ ARRAY_SIZE(imx708_test_pattern_menu) - 1,
++ 0, 0, imx708_test_pattern_menu);
++ for (i = 0; i < 4; i++) {
++ /*
++ * The assumption is that
++ * V4L2_CID_TEST_PATTERN_GREENR == V4L2_CID_TEST_PATTERN_RED + 1
++ * V4L2_CID_TEST_PATTERN_BLUE == V4L2_CID_TEST_PATTERN_RED + 2
++ * V4L2_CID_TEST_PATTERN_GREENB == V4L2_CID_TEST_PATTERN_RED + 3
++ */
++ v4l2_ctrl_new_std(ctrl_hdlr, &imx708_ctrl_ops,
++ V4L2_CID_TEST_PATTERN_RED + i,
++ IMX708_TEST_PATTERN_COLOUR_MIN,
++ IMX708_TEST_PATTERN_COLOUR_MAX,
++ IMX708_TEST_PATTERN_COLOUR_STEP,
++ IMX708_TEST_PATTERN_COLOUR_MAX);
++ /* The "Solid color" pattern is white by default */
++ }
++
++ imx708->notify_gains = v4l2_ctrl_new_custom(ctrl_hdlr,
++ &imx708_notify_gains_ctrl,
++ NULL);
++
++ imx708->hdr_mode = v4l2_ctrl_new_std(ctrl_hdlr, &imx708_ctrl_ops,
++ V4L2_CID_WIDE_DYNAMIC_RANGE,
++ 0, 1, 1, 0);
++
++ ret = v4l2_fwnode_device_parse(&client->dev, &props);
++ if (ret)
++ goto error;
++
++ v4l2_ctrl_new_fwnode_properties(ctrl_hdlr, &imx708_ctrl_ops, &props);
++
++ if (ctrl_hdlr->error) {
++ ret = ctrl_hdlr->error;
++ dev_err(&client->dev, "%s control init failed (%d)\n",
++ __func__, ret);
++ goto error;
++ }
++
++ imx708->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
++ imx708->hflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
++ imx708->vflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
++ imx708->hdr_mode->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
++
++ imx708->sd.ctrl_handler = ctrl_hdlr;
++
++ /* Setup exposure and frame/line length limits. */
++ imx708_set_framing_limits(imx708);
++
++ return 0;
++
++error:
++ v4l2_ctrl_handler_free(ctrl_hdlr);
++ mutex_destroy(&imx708->mutex);
++
++ return ret;
++}
++
++static void imx708_free_controls(struct imx708 *imx708)
++{
++ v4l2_ctrl_handler_free(imx708->sd.ctrl_handler);
++ mutex_destroy(&imx708->mutex);
++}
++
++static int imx708_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] != IMX708_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 imx708_probe(struct i2c_client *client)
++{
++ struct device *dev = &client->dev;
++ struct imx708 *imx708;
++ int ret;
++
++ imx708 = devm_kzalloc(&client->dev, sizeof(*imx708), GFP_KERNEL);
++ if (!imx708)
++ return -ENOMEM;
++
++ v4l2_i2c_subdev_init(&imx708->sd, client, &imx708_subdev_ops);
++
++ /* Check the hardware configuration in device tree */
++ if (imx708_check_hwcfg(dev))
++ return -EINVAL;
++
++ /* Get system clock (xclk) */
++ imx708->xclk = devm_clk_get(dev, NULL);
++ if (IS_ERR(imx708->xclk)) {
++ dev_err(dev, "failed to get xclk\n");
++ return PTR_ERR(imx708->xclk);
++ }
++
++ imx708->xclk_freq = clk_get_rate(imx708->xclk);
++ if (imx708->xclk_freq != IMX708_XCLK_FREQ) {
++ dev_err(dev, "xclk frequency not supported: %d Hz\n",
++ imx708->xclk_freq);
++ return -EINVAL;
++ }
++
++ ret = imx708_get_regulators(imx708);
++ if (ret) {
++ dev_err(dev, "failed to get regulators\n");
++ return ret;
++ }
++
++ /* Request optional enable pin */
++ imx708->reset_gpio = devm_gpiod_get_optional(dev, "reset",
++ GPIOD_OUT_HIGH);
++
++ /*
++ * The sensor must be powered for imx708_identify_module()
++ * to be able to read the CHIP_ID register
++ */
++ ret = imx708_power_on(dev);
++ if (ret)
++ return ret;
++
++ ret = imx708_identify_module(imx708);
++ if (ret)
++ goto error_power_off;
++
++ /* Initialize default format */
++ imx708_set_default_format(imx708);
++
++ /*
++ * Enable runtime PM with autosuspend. As the device has been powered
++ * manually, mark it as active, and increase the usage count without
++ * resuming the device.
++ */
++ pm_runtime_set_active(dev);
++ pm_runtime_get_noresume(dev);
++ pm_runtime_enable(dev);
++ pm_runtime_set_autosuspend_delay(dev, 1000);
++ pm_runtime_use_autosuspend(dev);
++
++ /* This needs the pm runtime to be registered. */
++ ret = imx708_init_controls(imx708);
++ if (ret)
++ goto error_power_off;
++
++ /* Initialize subdev */
++ imx708->sd.internal_ops = &imx708_internal_ops;
++ imx708->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
++ V4L2_SUBDEV_FL_HAS_EVENTS;
++ imx708->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
++
++ /* Initialize source pad */
++ imx708->pad.flags = MEDIA_PAD_FL_SOURCE;
++
++ ret = media_entity_pads_init(&imx708->sd.entity, 1, &imx708->pad);
++ if (ret) {
++ dev_err(dev, "failed to init entity pads: %d\n", ret);
++ goto error_handler_free;
++ }
++
++ ret = v4l2_async_register_subdev_sensor(&imx708->sd);
++ if (ret < 0) {
++ dev_err(dev, "failed to register sensor sub-device: %d\n", ret);
++ goto error_media_entity;
++ }
++
++ /*
++ * Decrease the PM usage count. The device will get suspended after the
++ * autosuspend delay, turning the power off.
++ */
++ pm_runtime_mark_last_busy(dev);
++ pm_runtime_put_autosuspend(dev);
++
++ return 0;
++
++error_media_entity:
++ media_entity_cleanup(&imx708->sd.entity);
++
++error_handler_free:
++ imx708_free_controls(imx708);
++
++error_power_off:
++ pm_runtime_disable(&client->dev);
++ pm_runtime_put_noidle(&client->dev);
++ imx708_power_off(&client->dev);
++
++ return ret;
++}
++
++static void imx708_remove(struct i2c_client *client)
++{
++ struct v4l2_subdev *sd = i2c_get_clientdata(client);
++ struct imx708 *imx708 = to_imx708(sd);
++
++ v4l2_async_unregister_subdev(sd);
++ media_entity_cleanup(&sd->entity);
++ imx708_free_controls(imx708);
++
++ pm_runtime_disable(&client->dev);
++ if (!pm_runtime_status_suspended(&client->dev))
++ imx708_power_off(&client->dev);
++ pm_runtime_set_suspended(&client->dev);
++}
++
++static const struct of_device_id imx708_dt_ids[] = {
++ { .compatible = "sony,imx708" },
++ { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, imx708_dt_ids);
++
++static const struct dev_pm_ops imx708_pm_ops = {
++ SET_SYSTEM_SLEEP_PM_OPS(imx708_suspend, imx708_resume)
++ SET_RUNTIME_PM_OPS(imx708_power_off, imx708_power_on, NULL)
++};
++
++static struct i2c_driver imx708_i2c_driver = {
++ .driver = {
++ .name = "imx708",
++ .of_match_table = imx708_dt_ids,
++ .pm = &imx708_pm_ops,
++ },
++ .probe = imx708_probe,
++ .remove = imx708_remove,
++};
++
++module_i2c_driver(imx708_i2c_driver);
++
++MODULE_AUTHOR("David Plowman <david.plowman@raspberrypi.com>");
++MODULE_DESCRIPTION("Sony IMX708 sensor driver");
++MODULE_LICENSE("GPL");
diff --git a/target/linux/starfive/patches-6.6/0088-media-i2c-imx708-Delete-gain.patch b/target/linux/starfive/patches-6.6/0088-media-i2c-imx708-Delete-gain.patch
new file mode 100644
index 0000000000..c3971ed62b
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0088-media-i2c-imx708-Delete-gain.patch
@@ -0,0 +1,69 @@
+From 280ab217867d0b934454a837540eab665e854b47 Mon Sep 17 00:00:00 2001
+From: Changhuang Liang <changhuang.liang@starfivetech.com>
+Date: Mon, 3 Apr 2023 15:28:11 +0800
+Subject: [PATCH 088/116] media: i2c: imx708: Delete gain
+
+Delete gain.
+
+Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
+---
+ drivers/media/i2c/imx708.c | 27 ---------------------------
+ 1 file changed, 27 deletions(-)
+
+--- a/drivers/media/i2c/imx708.c
++++ b/drivers/media/i2c/imx708.c
+@@ -777,7 +777,6 @@ struct imx708 {
+ struct v4l2_ctrl *hblank;
+ struct v4l2_ctrl *red_balance;
+ struct v4l2_ctrl *blue_balance;
+- struct v4l2_ctrl *notify_gains;
+ struct v4l2_ctrl *hdr_mode;
+
+ /* Current mode */
+@@ -1108,16 +1107,6 @@ static int imx708_set_ctrl(struct v4l2_c
+ ret = imx708_set_frame_length(imx708,
+ imx708->mode->height + ctrl->val);
+ break;
+- case V4L2_CID_NOTIFY_GAINS:
+- ret = imx708_write_reg(imx708, IMX708_REG_COLOUR_BALANCE_BLUE,
+- IMX708_REG_VALUE_16BIT,
+- imx708->notify_gains->p_new.p_u32[0]);
+- if (ret)
+- break;
+- ret = imx708_write_reg(imx708, IMX708_REG_COLOUR_BALANCE_RED,
+- IMX708_REG_VALUE_16BIT,
+- imx708->notify_gains->p_new.p_u32[3]);
+- break;
+ case V4L2_CID_WIDE_DYNAMIC_RANGE:
+ get_mode_table(&mode_list, &num_modes, ctrl->val);
+ imx708->mode = v4l2_find_nearest_size(mode_list,
+@@ -1584,18 +1573,6 @@ static const struct v4l2_subdev_internal
+ .open = imx708_open,
+ };
+
+-static const struct v4l2_ctrl_config imx708_notify_gains_ctrl = {
+- .ops = &imx708_ctrl_ops,
+- .id = V4L2_CID_NOTIFY_GAINS,
+- .type = V4L2_CTRL_TYPE_U32,
+- .min = IMX708_COLOUR_BALANCE_MIN,
+- .max = IMX708_COLOUR_BALANCE_MAX,
+- .step = IMX708_COLOUR_BALANCE_STEP,
+- .def = IMX708_COLOUR_BALANCE_DEFAULT,
+- .dims = { 4 },
+- .elem_size = sizeof(u32),
+-};
+-
+ /* Initialize control handlers */
+ static int imx708_init_controls(struct imx708 *imx708)
+ {
+@@ -1670,10 +1647,6 @@ static int imx708_init_controls(struct i
+ /* The "Solid color" pattern is white by default */
+ }
+
+- imx708->notify_gains = v4l2_ctrl_new_custom(ctrl_hdlr,
+- &imx708_notify_gains_ctrl,
+- NULL);
+-
+ imx708->hdr_mode = v4l2_ctrl_new_std(ctrl_hdlr, &imx708_ctrl_ops,
+ V4L2_CID_WIDE_DYNAMIC_RANGE,
+ 0, 1, 1, 0);
diff --git a/target/linux/starfive/patches-6.6/0089-dt-bindings-display-Add-yamls-for-JH7110-display-sys.patch b/target/linux/starfive/patches-6.6/0089-dt-bindings-display-Add-yamls-for-JH7110-display-sys.patch
new file mode 100644
index 0000000000..e8baa80eb9
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0089-dt-bindings-display-Add-yamls-for-JH7110-display-sys.patch
@@ -0,0 +1,270 @@
+From aa4febf074cbaad81c981a5c6b55324a6f676fb7 Mon Sep 17 00:00:00 2001
+From: "shengyang.chen" <shengyang.chen@starfivetech.com>
+Date: Tue, 13 Jun 2023 14:22:29 +0800
+Subject: [PATCH 089/116] dt-bindings: display: Add yamls for JH7110 display
+ system and hdmi
+
+StarFive SoCs like the jh7110 use display system based on verisilicon IP, use hdmi
+base on innosilicon IP. Add bindings for them.
+
+Signed-off-by: Shengyang Chen <shengyang.chen@starfivetech.com>
+---
+ .../display/verisilicon/starfive-hdmi.yaml | 92 +++++++++++++++
+ .../display/verisilicon/verisilicon-dc.yaml | 109 ++++++++++++++++++
+ .../display/verisilicon/verisilicon-drm.yaml | 41 +++++++
+ 3 files changed, 242 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/display/verisilicon/starfive-hdmi.yaml
+ create mode 100644 Documentation/devicetree/bindings/display/verisilicon/verisilicon-dc.yaml
+ create mode 100644 Documentation/devicetree/bindings/display/verisilicon/verisilicon-drm.yaml
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/display/verisilicon/starfive-hdmi.yaml
+@@ -0,0 +1,92 @@
++# SPDX-License-Identifier: GPL-2.0
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/display/verisilicon/starfive-hdmi.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: StarFive SoC HDMI transmiter
++
++description:
++ The StarFive SoC uses the HDMI signal transmiter based on innosilicon IP
++ to generate HDMI signal from its input and transmit the signal to the screen.
++
++maintainers:
++ - Keith Zhao <keith.zhao@starfivetech.com>
++
++properties:
++ compatible:
++ const: starfive,hdmi
++
++ reg:
++ minItems: 1
++
++ interrupts:
++ items:
++ - description: The HDMI hot plug detection interrupt.
++
++ clocks:
++ items:
++ - description: System clock of HDMI module.
++ - description: Mclk clock of HDMI audio.
++ - description: Bclk clock of HDMI audio.
++ - description: Pixel clock generated by HDMI module.
++
++ clock-names:
++ items:
++ - const: sysclk
++ - const: mclk
++ - const: bclk
++ - const: pclk
++
++ resets:
++ items:
++ - description: Reset for HDMI module.
++
++ reset-names:
++ items:
++ - const: hdmi_tx
++
++ '#sound-dai-cells':
++ const: 0
++
++ port:
++ $ref: /schemas/graph.yaml#/properties/port
++ description:
++ Port node with one endpoint connected to a display connector node.
++
++required:
++ - compatible
++ - reg
++ - interrupts
++ - clocks
++ - clock-names
++ - resets
++ - reset-names
++ - '#sound-dai-cells'
++ - port
++
++additionalProperties: false
++
++examples:
++ - |
++ hdmi: hdmi@29590000 {
++ compatible = "starfive,hdmi";
++ reg = <0x29590000 0x4000>;
++ interrupts = <99>;
++ clocks = <&voutcrg 17>,
++ <&voutcrg 15>,
++ <&voutcrg 16>,
++ <&hdmitx0_pixelclk>;
++ clock-names = "sysclk", "mclk","bclk","pclk";
++ resets = <&voutcrg 9>;
++ reset-names = "hdmi_tx";
++ #sound-dai-cells = <0>;
++ hdmi_in: port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ hdmi_input: endpoint@0 {
++ reg = <0>;
++ remote-endpoint = <&dc_out_dpi0>;
++ };
++ };
++ };
+--- /dev/null
++++ b/Documentation/devicetree/bindings/display/verisilicon/verisilicon-dc.yaml
+@@ -0,0 +1,109 @@
++# SPDX-License-Identifier: GPL-2.0
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/display/verisilicon/verisilicon-dc.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: StarFive SoC display controller
++
++description:
++ The StarFive SoC uses the display controller based on Verisilicon IP
++ to transfer the image data from a video memory
++ buffer to an external LCD interface.
++
++maintainers:
++ - Keith Zhao <keith.zhao@starfivetech.com>
++
++properties:
++ compatible:
++ const: verisilicon,dc8200
++
++ reg:
++ maxItems: 3
++
++ interrupts:
++ items:
++ - description: The interrupt will be generated when DC finish one frame
++
++ clocks:
++ items:
++ - description: Clock for display system noc bus.
++ - description: Pixel clock for display channel 0.
++ - description: Pixel clock for display channel 1.
++ - description: Clock for axi interface of display controller.
++ - description: Core clock for display controller.
++ - description: Clock for ahb interface of display controller.
++ - description: External HDMI pixel clock.
++ - description: Parent clock for pixel clock
++
++ clock-names:
++ items:
++ - const: clk_vout_noc_disp
++ - const: clk_vout_pix0
++ - const: clk_vout_pix1
++ - const: clk_vout_axi
++ - const: clk_vout_core
++ - const: clk_vout_vout_ahb
++ - const: hdmitx0_pixel
++ - const: clk_vout_dc8200
++
++ resets:
++ items:
++ - description: Reset for axi interface of display controller.
++ - description: Reset for ahb interface of display controller.
++ - description: Core reset of display controller.
++
++ reset-names:
++ items:
++ - const: rst_vout_axi
++ - const: rst_vout_ahb
++ - const: rst_vout_core
++
++ port:
++ $ref: /schemas/graph.yaml#/properties/port
++ description:
++ Port node with one endpoint connected to a hdmi node.
++
++required:
++ - compatible
++ - reg
++ - interrupts
++ - clocks
++ - clock-names
++ - resets
++ - reset-names
++ - port
++
++additionalProperties: false
++
++examples:
++ - |
++ dc8200: dc8200@29400000 {
++ compatible = "verisilicon,dc8200";
++ reg = <0x29400000 0x100>,
++ <0x29400800 0x2000>,
++ <0x295B0000 0x90>;
++ interrupts = <95>;
++ clocks = <&syscrg 60>,
++ <&voutcrg 7>,
++ <&voutcrg 8>,
++ <&voutcrg 4>,
++ <&voutcrg 5>,
++ <&voutcrg 6>,
++ <&hdmitx0_pixelclk>,
++ <&voutcrg 1>;
++ clock-names = "clk_vout_noc_disp", "clk_vout_pix0", "clk_vout_pix1", "clk_vout_axi",
++ "clk_vout_core", "clk_vout_vout_ahb", "hdmitx0_pixel","clk_vout_dc8200";
++ resets = <&voutcrg 0>,
++ <&voutcrg 1>,
++ <&voutcrg 2>;
++ reset-names = "rst_vout_axi","rst_vout_ahb","rst_vout_core";
++ dc_out: port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ dc_out_dpi0: endpoint@0 {
++ reg = <0>;
++ remote-endpoint = <&hdmi_input>;
++ };
++ };
++ };
+--- /dev/null
++++ b/Documentation/devicetree/bindings/display/verisilicon/verisilicon-drm.yaml
+@@ -0,0 +1,41 @@
++# SPDX-License-Identifier: (GPL-2.0-only)
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/display/verisilicon/verisilicon-drm.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: Verisilicon DRM master device
++
++maintainers:
++ - Keith Zhao <keith.zhao@starfivetech.com>
++
++description: |
++ The Verisilicon DRM master device is a virtual device needed to list all
++ display controller or other display interface nodes that comprise the
++ graphics subsystem.
++
++properties:
++ compatible:
++ const: verisilicon,display-subsystem
++
++ ports:
++ $ref: /schemas/types.yaml#/definitions/phandle-array
++ items:
++ maxItems: 1
++ description: |
++ Should contain a list of phandles pointing to display interface ports
++ of display controller devices. Display controller definitions as defined in
++ Documentation/devicetree/bindings/display/verisilicon/verisilicon-dc.yaml
++
++required:
++ - compatible
++ - ports
++
++additionalProperties: false
++
++examples:
++ - |
++ display-subsystem {
++ compatible = "verisilicon,display-subsystem";
++ ports = <&dc_out>;
++ };
diff --git a/target/linux/starfive/patches-6.6/0090-soc-starfive-jh71xx_pmu-Add-EVENT_TURN_OFF-register-.patch b/target/linux/starfive/patches-6.6/0090-soc-starfive-jh71xx_pmu-Add-EVENT_TURN_OFF-register-.patch
new file mode 100644
index 0000000000..7a6bfa8c4f
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0090-soc-starfive-jh71xx_pmu-Add-EVENT_TURN_OFF-register-.patch
@@ -0,0 +1,82 @@
+From 5cbf4154da600af8a2e6a2f8d57d1f212abf3f92 Mon Sep 17 00:00:00 2001
+From: Hal Feng <hal.feng@starfivetech.com>
+Date: Fri, 13 Oct 2023 14:10:24 +0800
+Subject: [PATCH 090/116] soc: starfive: jh71xx_pmu: Add EVENT_TURN_OFF
+ register writing support
+
+Add and export starfive_pmu_hw_event_turn_off_mask() to
+write EVENT_TURN_OFF register.
+
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ drivers/pmdomain/starfive/jh71xx-pmu.c | 11 ++++++++++
+ include/soc/starfive/jh7110_pmu.h | 29 ++++++++++++++++++++++++++
+ 2 files changed, 40 insertions(+)
+ create mode 100644 include/soc/starfive/jh7110_pmu.h
+
+--- a/drivers/pmdomain/starfive/jh71xx-pmu.c
++++ b/drivers/pmdomain/starfive/jh71xx-pmu.c
+@@ -16,6 +16,7 @@
+ #include <dt-bindings/power/starfive,jh7110-pmu.h>
+
+ /* register offset */
++#define JH71XX_PMU_HW_EVENT_TURN_OFF 0x08
+ #define JH71XX_PMU_SW_TURN_ON_POWER 0x0C
+ #define JH71XX_PMU_SW_TURN_OFF_POWER 0x10
+ #define JH71XX_PMU_SW_ENCOURAGE 0x44
+@@ -83,6 +84,14 @@ struct jh71xx_pmu_dev {
+ struct generic_pm_domain genpd;
+ };
+
++static void __iomem *pmu_base;
++
++void starfive_pmu_hw_event_turn_off_mask(u32 mask)
++{
++ writel(mask, pmu_base + JH71XX_PMU_HW_EVENT_TURN_OFF);
++}
++EXPORT_SYMBOL(starfive_pmu_hw_event_turn_off_mask);
++
+ static int jh71xx_pmu_get_state(struct jh71xx_pmu_dev *pmd, u32 mask, bool *is_on)
+ {
+ struct jh71xx_pmu *pmu = pmd->pmu;
+@@ -334,6 +343,8 @@ static int jh71xx_pmu_probe(struct platf
+ if (IS_ERR(pmu->base))
+ return PTR_ERR(pmu->base);
+
++ pmu_base = pmu->base;
++
+ spin_lock_init(&pmu->lock);
+
+ match_data = of_device_get_match_data(dev);
+--- /dev/null
++++ b/include/soc/starfive/jh7110_pmu.h
+@@ -0,0 +1,29 @@
++/* SPDX-License-Identifier: GPL-2.0-or-later */
++/*
++ * PMU driver for the StarFive JH7110 SoC
++ *
++ * Copyright (C) 2022 samin <samin.guo@starfivetech.com>
++ */
++
++#ifndef __SOC_STARFIVE_JH7110_PMU_H__
++#define __SOC_STARFIVE_JH7110_PMU_H__
++
++#include <linux/bits.h>
++#include <linux/types.h>
++
++enum PMU_HARD_EVENT {
++ PMU_HW_EVENT_RTC = BIT(0),
++ PMU_HW_EVENT_GMAC = BIT(1),
++ PMU_HW_EVENT_RFU = BIT(2),
++ PMU_HW_EVENT_RGPIO0 = BIT(3),
++ PMU_HW_EVENT_RGPIO1 = BIT(4),
++ PMU_HW_EVENT_RGPIO2 = BIT(5),
++ PMU_HW_EVENT_RGPIO3 = BIT(6),
++ PMU_HW_EVENT_GPU = BIT(7),
++ PMU_HW_EVENT_ALL = GENMASK(7, 0),
++};
++
++void starfive_pmu_hw_event_turn_off_mask(u32 mask);
++
++#endif /* __SOC_STARFIVE_JH7110_PMU_H__ */
++
diff --git a/target/linux/starfive/patches-6.6/0091-workqueue-Enable-flush_scheduled_work.patch b/target/linux/starfive/patches-6.6/0091-workqueue-Enable-flush_scheduled_work.patch
new file mode 100644
index 0000000000..a6b69660c3
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0091-workqueue-Enable-flush_scheduled_work.patch
@@ -0,0 +1,22 @@
+From ab436ea7ffb6c464616addad98632c81a321844a Mon Sep 17 00:00:00 2001
+From: Hal Feng <hal.feng@starfivetech.com>
+Date: Tue, 12 Dec 2023 17:56:58 +0800
+Subject: [PATCH 091/116] workqueue: Enable flush_scheduled_work()
+
+Enable flush_scheduled_work() for JH7110 GPU.
+
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ include/linux/workqueue.h | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/include/linux/workqueue.h
++++ b/include/linux/workqueue.h
+@@ -636,7 +636,6 @@ extern void __warn_flushing_systemwide_w
+ /* Please stop using this function, for this function will be removed in near future. */
+ #define flush_scheduled_work() \
+ ({ \
+- __warn_flushing_systemwide_wq(); \
+ __flush_workqueue(system_wq); \
+ })
+
diff --git a/target/linux/starfive/patches-6.6/0092-riscv-Optimize-memcpy-with-aligned-version.patch b/target/linux/starfive/patches-6.6/0092-riscv-Optimize-memcpy-with-aligned-version.patch
new file mode 100644
index 0000000000..39c27237b0
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0092-riscv-Optimize-memcpy-with-aligned-version.patch
@@ -0,0 +1,506 @@
+From dedbbfd891e4d0cdb825454eddfbf8386d0025b3 Mon Sep 17 00:00:00 2001
+From: Mason Huo <mason.huo@starfivetech.com>
+Date: Tue, 20 Jun 2023 13:37:52 +0800
+Subject: [PATCH 092/116] riscv: Optimize memcpy with aligned version
+
+Optimizing the 128 byte align case, this will improve the
+performance of large block memcpy.
+
+Here we combine the memcpy of glibc and kernel.
+
+Signed-off-by: Mason Huo <mason.huo@starfivetech.com>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ arch/riscv/lib/Makefile | 3 +-
+ arch/riscv/lib/{memcpy.S => memcpy_aligned.S} | 36 +--
+ arch/riscv/lib/string.c | 266 ++++++++++++++++++
+ 3 files changed, 273 insertions(+), 32 deletions(-)
+ rename arch/riscv/lib/{memcpy.S => memcpy_aligned.S} (67%)
+ create mode 100644 arch/riscv/lib/string.c
+
+--- a/arch/riscv/lib/Makefile
++++ b/arch/riscv/lib/Makefile
+@@ -1,6 +1,5 @@
+ # SPDX-License-Identifier: GPL-2.0-only
+ lib-y += delay.o
+-lib-y += memcpy.o
+ lib-y += memset.o
+ lib-y += memmove.o
+ lib-y += strcmp.o
+@@ -9,5 +8,7 @@ lib-y += strncmp.o
+ lib-$(CONFIG_MMU) += uaccess.o
+ lib-$(CONFIG_64BIT) += tishift.o
+ lib-$(CONFIG_RISCV_ISA_ZICBOZ) += clear_page.o
++lib-y += string.o
++lib-y += memcpy_aligned.o
+
+ obj-$(CONFIG_FUNCTION_ERROR_INJECTION) += error-inject.o
+--- a/arch/riscv/lib/memcpy.S
++++ /dev/null
+@@ -1,110 +0,0 @@
+-/* SPDX-License-Identifier: GPL-2.0-only */
+-/*
+- * Copyright (C) 2013 Regents of the University of California
+- */
+-
+-#include <linux/linkage.h>
+-#include <asm/asm.h>
+-
+-/* void *memcpy(void *, const void *, size_t) */
+-ENTRY(__memcpy)
+-WEAK(memcpy)
+- move t6, a0 /* Preserve return value */
+-
+- /* Defer to byte-oriented copy for small sizes */
+- sltiu a3, a2, 128
+- bnez a3, 4f
+- /* Use word-oriented copy only if low-order bits match */
+- andi a3, t6, SZREG-1
+- andi a4, a1, SZREG-1
+- bne a3, a4, 4f
+-
+- beqz a3, 2f /* Skip if already aligned */
+- /*
+- * Round to nearest double word-aligned address
+- * greater than or equal to start address
+- */
+- andi a3, a1, ~(SZREG-1)
+- addi a3, a3, SZREG
+- /* Handle initial misalignment */
+- sub a4, a3, a1
+-1:
+- lb a5, 0(a1)
+- addi a1, a1, 1
+- sb a5, 0(t6)
+- addi t6, t6, 1
+- bltu a1, a3, 1b
+- sub a2, a2, a4 /* Update count */
+-
+-2:
+- andi a4, a2, ~((16*SZREG)-1)
+- beqz a4, 4f
+- add a3, a1, a4
+-3:
+- REG_L a4, 0(a1)
+- REG_L a5, SZREG(a1)
+- REG_L a6, 2*SZREG(a1)
+- REG_L a7, 3*SZREG(a1)
+- REG_L t0, 4*SZREG(a1)
+- REG_L t1, 5*SZREG(a1)
+- REG_L t2, 6*SZREG(a1)
+- REG_L t3, 7*SZREG(a1)
+- REG_L t4, 8*SZREG(a1)
+- REG_L t5, 9*SZREG(a1)
+- REG_S a4, 0(t6)
+- REG_S a5, SZREG(t6)
+- REG_S a6, 2*SZREG(t6)
+- REG_S a7, 3*SZREG(t6)
+- REG_S t0, 4*SZREG(t6)
+- REG_S t1, 5*SZREG(t6)
+- REG_S t2, 6*SZREG(t6)
+- REG_S t3, 7*SZREG(t6)
+- REG_S t4, 8*SZREG(t6)
+- REG_S t5, 9*SZREG(t6)
+- REG_L a4, 10*SZREG(a1)
+- REG_L a5, 11*SZREG(a1)
+- REG_L a6, 12*SZREG(a1)
+- REG_L a7, 13*SZREG(a1)
+- REG_L t0, 14*SZREG(a1)
+- REG_L t1, 15*SZREG(a1)
+- addi a1, a1, 16*SZREG
+- REG_S a4, 10*SZREG(t6)
+- REG_S a5, 11*SZREG(t6)
+- REG_S a6, 12*SZREG(t6)
+- REG_S a7, 13*SZREG(t6)
+- REG_S t0, 14*SZREG(t6)
+- REG_S t1, 15*SZREG(t6)
+- addi t6, t6, 16*SZREG
+- bltu a1, a3, 3b
+- andi a2, a2, (16*SZREG)-1 /* Update count */
+-
+-4:
+- /* Handle trailing misalignment */
+- beqz a2, 6f
+- add a3, a1, a2
+-
+- /* Use word-oriented copy if co-aligned to word boundary */
+- or a5, a1, t6
+- or a5, a5, a3
+- andi a5, a5, 3
+- bnez a5, 5f
+-7:
+- lw a4, 0(a1)
+- addi a1, a1, 4
+- sw a4, 0(t6)
+- addi t6, t6, 4
+- bltu a1, a3, 7b
+-
+- ret
+-
+-5:
+- lb a4, 0(a1)
+- addi a1, a1, 1
+- sb a4, 0(t6)
+- addi t6, t6, 1
+- bltu a1, a3, 5b
+-6:
+- ret
+-END(__memcpy)
+-SYM_FUNC_ALIAS(__pi_memcpy, __memcpy)
+-SYM_FUNC_ALIAS(__pi___memcpy, __memcpy)
+--- /dev/null
++++ b/arch/riscv/lib/memcpy_aligned.S
+@@ -0,0 +1,84 @@
++/* SPDX-License-Identifier: GPL-2.0-only */
++/*
++ * Copyright (C) 2013 Regents of the University of California
++ */
++
++#include <linux/linkage.h>
++#include <asm/asm.h>
++
++/* void *__memcpy_aligned(void *, const void *, size_t) */
++ENTRY(__memcpy_aligned)
++ move t6, a0 /* Preserve return value */
++
++2:
++ andi a4, a2, ~((16*SZREG)-1)
++ beqz a4, 4f
++ add a3, a1, a4
++3:
++ REG_L a4, 0(a1)
++ REG_L a5, SZREG(a1)
++ REG_L a6, 2*SZREG(a1)
++ REG_L a7, 3*SZREG(a1)
++ REG_L t0, 4*SZREG(a1)
++ REG_L t1, 5*SZREG(a1)
++ REG_L t2, 6*SZREG(a1)
++ REG_L t3, 7*SZREG(a1)
++ REG_L t4, 8*SZREG(a1)
++ REG_L t5, 9*SZREG(a1)
++ REG_S a4, 0(t6)
++ REG_S a5, SZREG(t6)
++ REG_S a6, 2*SZREG(t6)
++ REG_S a7, 3*SZREG(t6)
++ REG_S t0, 4*SZREG(t6)
++ REG_S t1, 5*SZREG(t6)
++ REG_S t2, 6*SZREG(t6)
++ REG_S t3, 7*SZREG(t6)
++ REG_S t4, 8*SZREG(t6)
++ REG_S t5, 9*SZREG(t6)
++ REG_L a4, 10*SZREG(a1)
++ REG_L a5, 11*SZREG(a1)
++ REG_L a6, 12*SZREG(a1)
++ REG_L a7, 13*SZREG(a1)
++ REG_L t0, 14*SZREG(a1)
++ REG_L t1, 15*SZREG(a1)
++ addi a1, a1, 16*SZREG
++ REG_S a4, 10*SZREG(t6)
++ REG_S a5, 11*SZREG(t6)
++ REG_S a6, 12*SZREG(t6)
++ REG_S a7, 13*SZREG(t6)
++ REG_S t0, 14*SZREG(t6)
++ REG_S t1, 15*SZREG(t6)
++ addi t6, t6, 16*SZREG
++ bltu a1, a3, 3b
++ andi a2, a2, (16*SZREG)-1 /* Update count */
++
++4:
++ /* Handle trailing misalignment */
++ beqz a2, 6f
++ add a3, a1, a2
++
++ /* Use word-oriented copy if co-aligned to word boundary */
++ or a5, a1, t6
++ or a5, a5, a3
++ andi a5, a5, 3
++ bnez a5, 5f
++7:
++ lw a4, 0(a1)
++ addi a1, a1, 4
++ sw a4, 0(t6)
++ addi t6, t6, 4
++ bltu a1, a3, 7b
++
++ ret
++
++5:
++ lb a4, 0(a1)
++ addi a1, a1, 1
++ sb a4, 0(t6)
++ addi t6, t6, 1
++ bltu a1, a3, 5b
++6:
++ ret
++END(__memcpy_aligned)
++SYM_FUNC_ALIAS(__pi_memcpy, __memcpy_aligned)
++SYM_FUNC_ALIAS(__pi___memcpy, __memcpy_aligned)
+--- /dev/null
++++ b/arch/riscv/lib/string.c
+@@ -0,0 +1,266 @@
++// SPDX-License-Identifier: GPL-2.0-only
++/*
++ * Copy memory to memory until the specified number of bytes
++ * has been copied. Overlap is NOT handled correctly.
++ * Copyright (C) 1991-2020 Free Software Foundation, Inc.
++ * This file is part of the GNU C Library.
++ * Contributed by Torbjorn Granlund (tege@sics.se).
++ *
++ * The GNU C Library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; either
++ * version 2.1 of the License, or (at your option) any later version.
++ *
++ * The GNU C Library 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
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with the GNU C Library; if not, see
++ * <https://www.gnu.org/licenses/>.
++ *
++ */
++
++#define __NO_FORTIFY
++#include <linux/types.h>
++#include <linux/module.h>
++
++#define MERGE(w0, sh_1, w1, sh_2) (((w0) >> (sh_1)) | ((w1) << (sh_2)))
++#define OP_T_THRES 16
++#define op_t unsigned long
++#define OPSIZ (sizeof(op_t))
++#define OPSIZ_MASK (sizeof(op_t) - 1)
++#define FAST_COPY_THRES (128)
++#define byte unsigned char
++
++static void _wordcopy_fwd_aligned(long dstp, long srcp, size_t len)
++{
++ op_t a0, a1;
++
++ switch (len % 8) {
++ case 2:
++ a0 = ((op_t *) srcp)[0];
++ srcp -= 6 * OPSIZ;
++ dstp -= 7 * OPSIZ;
++ len += 6;
++ goto do1;
++ case 3:
++ a1 = ((op_t *) srcp)[0];
++ srcp -= 5 * OPSIZ;
++ dstp -= 6 * OPSIZ;
++ len += 5;
++ goto do2;
++ case 4:
++ a0 = ((op_t *) srcp)[0];
++ srcp -= 4 * OPSIZ;
++ dstp -= 5 * OPSIZ;
++ len += 4;
++ goto do3;
++ case 5:
++ a1 = ((op_t *) srcp)[0];
++ srcp -= 3 * OPSIZ;
++ dstp -= 4 * OPSIZ;
++ len += 3;
++ goto do4;
++ case 6:
++ a0 = ((op_t *) srcp)[0];
++ srcp -= 2 * OPSIZ;
++ dstp -= 3 * OPSIZ;
++ len += 2;
++ goto do5;
++ case 7:
++ a1 = ((op_t *) srcp)[0];
++ srcp -= 1 * OPSIZ;
++ dstp -= 2 * OPSIZ;
++ len += 1;
++ goto do6;
++
++ case 0:
++ if (OP_T_THRES <= 3 * OPSIZ && len == 0)
++ return;
++ a0 = ((op_t *) srcp)[0];
++ srcp -= 0 * OPSIZ;
++ dstp -= 1 * OPSIZ;
++ goto do7;
++ case 1:
++ a1 = ((op_t *) srcp)[0];
++ srcp -= -1 * OPSIZ;
++ dstp -= 0 * OPSIZ;
++ len -= 1;
++ if (OP_T_THRES <= 3 * OPSIZ && len == 0)
++ goto do0;
++ goto do8; /* No-op. */
++ }
++
++ do {
++do8:
++ a0 = ((op_t *) srcp)[0];
++ ((op_t *) dstp)[0] = a1;
++do7:
++ a1 = ((op_t *) srcp)[1];
++ ((op_t *) dstp)[1] = a0;
++do6:
++ a0 = ((op_t *) srcp)[2];
++ ((op_t *) dstp)[2] = a1;
++do5:
++ a1 = ((op_t *) srcp)[3];
++ ((op_t *) dstp)[3] = a0;
++do4:
++ a0 = ((op_t *) srcp)[4];
++ ((op_t *) dstp)[4] = a1;
++do3:
++ a1 = ((op_t *) srcp)[5];
++ ((op_t *) dstp)[5] = a0;
++do2:
++ a0 = ((op_t *) srcp)[6];
++ ((op_t *) dstp)[6] = a1;
++do1:
++ a1 = ((op_t *) srcp)[7];
++ ((op_t *) dstp)[7] = a0;
++
++ srcp += 8 * OPSIZ;
++ dstp += 8 * OPSIZ;
++ len -= 8;
++ } while (len != 0);
++
++ /* This is the right position for do0. Please don't move
++ * it into the loop.
++ */
++do0:
++ ((op_t *) dstp)[0] = a1;
++}
++
++static void _wordcopy_fwd_dest_aligned(long dstp, long srcp, size_t len)
++{
++ op_t a0, a1, a2, a3;
++ int sh_1, sh_2;
++
++ /* Calculate how to shift a word read at the memory operation
++ * aligned srcp to make it aligned for copy.
++ */
++
++ sh_1 = 8 * (srcp % OPSIZ);
++ sh_2 = 8 * OPSIZ - sh_1;
++
++ /* Make SRCP aligned by rounding it down to the beginning of the `op_t'
++ * it points in the middle of.
++ */
++ srcp &= -OPSIZ;
++
++ switch (len % 4) {
++ case 2:
++ a1 = ((op_t *) srcp)[0];
++ a2 = ((op_t *) srcp)[1];
++ srcp -= 1 * OPSIZ;
++ dstp -= 3 * OPSIZ;
++ len += 2;
++ goto do1;
++ case 3:
++ a0 = ((op_t *) srcp)[0];
++ a1 = ((op_t *) srcp)[1];
++ srcp -= 0 * OPSIZ;
++ dstp -= 2 * OPSIZ;
++ len += 1;
++ goto do2;
++ case 0:
++ if (OP_T_THRES <= 3 * OPSIZ && len == 0)
++ return;
++ a3 = ((op_t *) srcp)[0];
++ a0 = ((op_t *) srcp)[1];
++ srcp -= -1 * OPSIZ;
++ dstp -= 1 * OPSIZ;
++ len += 0;
++ goto do3;
++ case 1:
++ a2 = ((op_t *) srcp)[0];
++ a3 = ((op_t *) srcp)[1];
++ srcp -= -2 * OPSIZ;
++ dstp -= 0 * OPSIZ;
++ len -= 1;
++ if (OP_T_THRES <= 3 * OPSIZ && len == 0)
++ goto do0;
++ goto do4; /* No-op. */
++ }
++
++ do {
++do4:
++ a0 = ((op_t *) srcp)[0];
++ ((op_t *) dstp)[0] = MERGE(a2, sh_1, a3, sh_2);
++do3:
++ a1 = ((op_t *) srcp)[1];
++ ((op_t *) dstp)[1] = MERGE(a3, sh_1, a0, sh_2);
++do2:
++ a2 = ((op_t *) srcp)[2];
++ ((op_t *) dstp)[2] = MERGE(a0, sh_1, a1, sh_2);
++do1:
++ a3 = ((op_t *) srcp)[3];
++ ((op_t *) dstp)[3] = MERGE(a1, sh_1, a2, sh_2);
++
++ srcp += 4 * OPSIZ;
++ dstp += 4 * OPSIZ;
++ len -= 4;
++ } while (len != 0);
++
++ /* This is the right position for do0. Please don't move
++ * it into the loop.
++ */
++do0:
++ ((op_t *) dstp)[0] = MERGE(a2, sh_1, a3, sh_2);
++}
++
++#define BYTE_COPY_FWD(dst_bp, src_bp, nbytes) \
++do { \
++ size_t __nbytes = (nbytes); \
++ while (__nbytes > 0) { \
++ byte __x = ((byte *) src_bp)[0]; \
++ src_bp += 1; \
++ __nbytes -= 1; \
++ ((byte *) dst_bp)[0] = __x; \
++ dst_bp += 1; \
++ } \
++} while (0)
++
++#define WORD_COPY_FWD(dst_bp, src_bp, nbytes_left, nbytes) \
++do { \
++ if (src_bp % OPSIZ == 0) \
++ _wordcopy_fwd_aligned(dst_bp, src_bp, (nbytes) / OPSIZ); \
++ else \
++ _wordcopy_fwd_dest_aligned(dst_bp, src_bp, (nbytes) / OPSIZ); \
++ src_bp += (nbytes) & -OPSIZ; \
++ dst_bp += (nbytes) & -OPSIZ; \
++ (nbytes_left) = (nbytes) % OPSIZ; \
++} while (0)
++
++extern void *__memcpy_aligned(void *dest, const void *src, size_t len);
++void *__memcpy(void *dest, const void *src, size_t len)
++{
++ unsigned long dstp = (long) dest;
++ unsigned long srcp = (long) src;
++
++ /* If there not too few bytes to copy, use word copy. */
++ if (len >= OP_T_THRES) {
++ if ((len >= FAST_COPY_THRES) && ((dstp & OPSIZ_MASK) == 0) &&
++ ((srcp & OPSIZ_MASK) == 0)) {
++ __memcpy_aligned(dest, src, len);
++ return dest;
++ }
++ /* Copy just a few bytes to make DSTP aligned. */
++ len -= (-dstp) % OPSIZ;
++ BYTE_COPY_FWD(dstp, srcp, (-dstp) % OPSIZ);
++
++ /* Copy from SRCP to DSTP taking advantage of the known alignment of
++ * DSTP. Number of bytes remaining is put in the third argument,
++ * i.e. in LEN. This number may vary from machine to machine.
++ */
++ WORD_COPY_FWD(dstp, srcp, len, len);
++ /* Fall out and copy the tail. */
++ }
++
++ /* There are just a few bytes to copy. Use byte memory operations. */
++ BYTE_COPY_FWD(dstp, srcp, len);
++
++ return dest;
++}
++
++void *memcpy(void *dest, const void *src, size_t len) __weak __alias(__memcpy);
diff --git a/target/linux/starfive/patches-6.6/0093-riscv-purgatory-Change-memcpy-to-the-aligned-version.patch b/target/linux/starfive/patches-6.6/0093-riscv-purgatory-Change-memcpy-to-the-aligned-version.patch
new file mode 100644
index 0000000000..0b7418fcf9
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0093-riscv-purgatory-Change-memcpy-to-the-aligned-version.patch
@@ -0,0 +1,37 @@
+From 41c9e97bb70321f7848bd489e45246a9dc985974 Mon Sep 17 00:00:00 2001
+From: Hal Feng <hal.feng@starfivetech.com>
+Date: Sun, 4 Feb 2024 15:27:09 +0800
+Subject: [PATCH 093/116] riscv/purgatory: Change memcpy to the aligned version
+
+Change memcpy to the aligned version, for purgatory.
+
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ arch/riscv/purgatory/Makefile | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+--- a/arch/riscv/purgatory/Makefile
++++ b/arch/riscv/purgatory/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ OBJECT_FILES_NON_STANDARD := y
+
+-purgatory-y := purgatory.o sha256.o entry.o string.o ctype.o memcpy.o memset.o
++purgatory-y := purgatory.o sha256.o entry.o string.o ctype.o memcpy_aligned.o memcpy.o memset.o
+ purgatory-y += strcmp.o strlen.o strncmp.o
+
+ targets += $(purgatory-y)
+@@ -13,9 +13,12 @@ $(obj)/string.o: $(srctree)/lib/string.c
+ $(obj)/ctype.o: $(srctree)/lib/ctype.c FORCE
+ $(call if_changed_rule,cc_o_c)
+
+-$(obj)/memcpy.o: $(srctree)/arch/riscv/lib/memcpy.S FORCE
++$(obj)/memcpy_aligned.o: $(srctree)/arch/riscv/lib/memcpy_aligned.S FORCE
+ $(call if_changed_rule,as_o_S)
+
++$(obj)/memcpy.o: $(srctree)/arch/riscv/lib/string.c FORCE
++ $(call if_changed_rule,cc_o_c)
++
+ $(obj)/memset.o: $(srctree)/arch/riscv/lib/memset.S FORCE
+ $(call if_changed_rule,as_o_S)
+
diff --git a/target/linux/starfive/patches-6.6/0094-Add-16-ISP-controls-remove-the-frame-SYNC-event-to-v.patch b/target/linux/starfive/patches-6.6/0094-Add-16-ISP-controls-remove-the-frame-SYNC-event-to-v.patch
new file mode 100644
index 0000000000..7ce12c6d58
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0094-Add-16-ISP-controls-remove-the-frame-SYNC-event-to-v.patch
@@ -0,0 +1,856 @@
+From f36d458104101050478e290919ef4f05fbde0b3e Mon Sep 17 00:00:00 2001
+From: "zejian.su" <zejian.su@starfivetech.com>
+Date: Mon, 3 Jul 2023 16:52:13 +0800
+Subject: [PATCH 094/116] Add 16 ISP controls, remove the frame SYNC event to
+ video7 (SC) These controls are: WB, CAR, CCM, CFA, CTC, DBC, DNYUV, GMARGB,
+ LCCF, OBC, OECF, R2Y, SAT, SHRP, YCRV, SC
+
+---
+ .../platform/starfive/v4l2_driver/stf_isp.c | 628 ++++++++++++++++++
+ .../platform/starfive/v4l2_driver/stf_video.c | 22 +
+ .../platform/starfive/v4l2_driver/stf_vin.c | 16 +-
+ include/uapi/linux/jh7110-isp.h | 48 +-
+ 4 files changed, 706 insertions(+), 8 deletions(-)
+
+--- a/drivers/media/platform/starfive/v4l2_driver/stf_isp.c
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_isp.c
+@@ -195,6 +195,41 @@ static const char * const test_pattern_m
+ "Color squares w/ rolling bar",
+ };
+
++enum isp_modules_index {
++ imi_obc = 0,
++ imi_oecf,
++ imi_lccf,
++ imi_awb,
++ imi_dbc,
++ imi_ctc,
++ imi_cfa,
++ imi_car,
++ imi_ccm,
++ imi_gmargb,
++ imi_r2y,
++ imi_ycrv,
++ imi_shrp,
++ imi_dnyuv,
++ imi_sat,
++ imi_sc
++};
++
++#define MODULE_ENABLE_REGISTER0 0x10
++#define MODULE_ENABLE_REGISTER1 0xa08
++
++struct module_register_info {
++ __u32 en_reg;
++ __u32 en_nbit;
++ __u32 cfg_reg;
++};
++
++static const struct module_register_info mod_reg_info[] = {
++ {MODULE_ENABLE_REGISTER0, 2, 0x034}, {MODULE_ENABLE_REGISTER0, 4, 0x100}, {MODULE_ENABLE_REGISTER0, 6, 0x050}, {MODULE_ENABLE_REGISTER0, 7, 0x280},
++ {MODULE_ENABLE_REGISTER1, 22, 0xa14}, {MODULE_ENABLE_REGISTER1, 21, 0xa10}, {MODULE_ENABLE_REGISTER1, 1, 0xa1c}, {MODULE_ENABLE_REGISTER1, 2, 0x000},
++ {MODULE_ENABLE_REGISTER1, 3, 0xc40}, {MODULE_ENABLE_REGISTER1, 4, 0xe00}, {MODULE_ENABLE_REGISTER1, 5, 0xe40}, {MODULE_ENABLE_REGISTER1, 19, 0xf00},
++ {MODULE_ENABLE_REGISTER1, 7, 0xe80}, {MODULE_ENABLE_REGISTER1, 17, 0xc00}, {MODULE_ENABLE_REGISTER1, 8, 0xa30}, {MODULE_ENABLE_REGISTER0, 17, 0x09c}
++};
++
+ #define ISP_TEST_ENABLE BIT(7)
+ #define ISP_TEST_ROLLING BIT(6) /* rolling horizontal bar */
+ #define ISP_TEST_TRANSPARENT BIT(5)
+@@ -260,6 +295,401 @@ static int isp_g_volatile_ctrl(struct v4
+ return 0;
+ }
+
++#define CREATE_REG_VALUE_FUNCTION(type) \
++ static u32 create_reg_value_##type(const type * value, s32 size, u32 mask, s32 nbits) { \
++ s32 npos = 0; \
++ u32 res = 0; \
++ s32 sz = size; \
++ s32 i = 0; \
++ if(size * nbits > 32) sz = 32 / nbits; \
++ for(i = 0; i < sz; i++, npos += nbits, value++) res |= (u32)(value[0] & mask) << npos; \
++ return res; \
++}
++
++CREATE_REG_VALUE_FUNCTION(u8);
++CREATE_REG_VALUE_FUNCTION(u16);
++#define CREATE_REG_VALUE(type, value, size, mask, nbits) create_reg_value_##type(value, size, mask, nbits)
++
++#define FILL_ISP_REGS_FUNC(type) \
++static void fill_isp_regs_##type(void __iomem *ispbase, u32 offset, const type * value, s32 size, u32 mask, u32 nbits) { \
++ s32 i; \
++ for(i = 0; i < size; i++, value++) \
++ reg_write(ispbase, offset + i * 4, (u32)(value[0] & mask) << nbits); \
++}
++FILL_ISP_REGS_FUNC(u32);
++FILL_ISP_REGS_FUNC(u8);
++FILL_ISP_REGS_FUNC(u16);
++
++#define FILL_ISP_REGS(type, ispbase, offset, value, size, mask, nbits) \
++ fill_isp_regs_##type(ispbase, offset, value, size, mask, nbits)
++
++static int isp_set_ctrl_wb(struct stf_isp_dev *isp_dev, const void * value)
++{
++ const struct module_register_info * reg_info = &mod_reg_info[imi_awb];
++ const struct jh7110_isp_wb_setting * setting = (const struct jh7110_isp_wb_setting *)value;
++ const struct jh7110_isp_wb_gain * gains = &setting->gains;
++ u32 r_g = (((u32)gains->gain_r << 16) | gains->gain_r) & 0x03ff03ff;
++ u32 g_g = (((u32)gains->gain_g << 16) | gains->gain_g) & 0x03ff03ff;
++ u32 b_g = (((u32)gains->gain_b << 16) | gains->gain_b) & 0x03ff03ff;
++ u32 reg_addr = reg_info->cfg_reg + 16 * sizeof(u32);
++ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
++ void __iomem *ispbase = vin->isp_base;
++
++ reg_write(ispbase, reg_addr, r_g);
++ reg_write(ispbase, reg_addr + 1 * 4, r_g);
++ reg_write(ispbase, reg_addr + 2 * 4, g_g);
++ reg_write(ispbase, reg_addr + 3 * 4, g_g);
++ reg_write(ispbase, reg_addr + 4 * 4, g_g);
++ reg_write(ispbase, reg_addr + 5 * 4, g_g);
++ reg_write(ispbase, reg_addr + 6 * 4, b_g);
++ reg_write(ispbase, reg_addr + 7 * 4, b_g);
++ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
++
++ return 0;
++}
++
++static int isp_set_ctrl_car(struct stf_isp_dev *isp_dev, const void * value)
++{
++ const struct module_register_info * reg_info = &mod_reg_info[imi_car];
++ const struct jh7110_isp_car_setting * setting = (const struct jh7110_isp_car_setting *)value;
++ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
++ void __iomem *ispbase = vin->isp_base;
++
++ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
++
++ return 0;
++}
++
++static int isp_set_ctrl_ccm(struct stf_isp_dev *isp_dev, const void * value)
++{
++ const struct module_register_info * reg_info = &mod_reg_info[imi_ccm];
++ const struct jh7110_isp_ccm_setting * setting = (const struct jh7110_isp_ccm_setting *)value;
++ const struct jh7110_isp_ccm_smlow * ccm = (const struct jh7110_isp_ccm_smlow *)(&(setting->ccm_smlow));
++ u32 reg_addr = reg_info->cfg_reg + 12 * sizeof(u32);
++ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
++ void __iomem *ispbase = vin->isp_base;
++
++ reg_write(ispbase, reg_info->cfg_reg, 6 << 16);
++ FILL_ISP_REGS(u32, ispbase, reg_addr, (u32 *)ccm, 12, 0x7ff, 0);
++
++ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
++
++ return 0;
++}
++
++static int isp_set_ctrl_cfa(struct stf_isp_dev *isp_dev, const void * value)
++{
++ const struct module_register_info * reg_info = &mod_reg_info[imi_cfa];
++ const struct jh7110_isp_cfa_setting * setting = (const struct jh7110_isp_cfa_setting *)value;
++ const struct jh7110_isp_cfa_params * cfg = (const struct jh7110_isp_cfa_params *)(&(setting->settings));
++ u32 reg_addr = reg_info->cfg_reg;
++ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
++ void __iomem *ispbase = vin->isp_base;
++
++ reg_write(ispbase, reg_addr, ((u32)(cfg->cross_cov & 0x3) << 4) | (cfg->hv_width & 0xf));
++ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
++
++ return 0;
++}
++
++static int isp_set_ctrl_ctc(struct stf_isp_dev *isp_dev, const void * value)
++{
++ const struct module_register_info * reg_info = &mod_reg_info[imi_ctc];
++ const struct jh7110_isp_ctc_setting * setting = (const struct jh7110_isp_ctc_setting *)value;
++ const struct jh7110_isp_ctc_params * cfg = (const struct jh7110_isp_ctc_params *)(&(setting->settings));
++ u32 reg_addr = reg_info->cfg_reg;
++ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
++ void __iomem *ispbase = vin->isp_base;
++ u32 reg_value = (u32)(((cfg->saf_mode & 1) << 1) | (cfg->daf_mode & 1)) << 30;
++
++ reg_value |= ((u32)(cfg->max_gt & 0x3ff) << 16) | (cfg->min_gt & 0x3ff);
++ reg_write(ispbase, reg_addr, reg_value);
++ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
++
++ return 0;
++}
++
++static int isp_set_ctrl_dbc(struct stf_isp_dev *isp_dev, const void * value)
++{
++ const struct module_register_info * reg_info = &mod_reg_info[imi_dbc];
++ const struct jh7110_isp_dbc_setting * setting = (const struct jh7110_isp_dbc_setting *)value;
++ const struct jh7110_isp_dbc_params * cfg = (const struct jh7110_isp_dbc_params *)(&(setting->settings));
++ u32 reg_addr = reg_info->cfg_reg;
++ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
++ void __iomem *ispbase = vin->isp_base;
++
++ reg_write(ispbase, reg_addr, ((u32)(cfg->bad_gt & 0x3ff) << 16) | (cfg->bad_xt & 0x3ff));
++ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
++
++ return 0;
++}
++
++static int isp_set_ctrl_dnyuv(struct stf_isp_dev *isp_dev, const void * value)
++{
++ const struct module_register_info * reg_info = &mod_reg_info[imi_dnyuv];
++ const struct jh7110_isp_dnyuv_setting * setting = (const struct jh7110_isp_dnyuv_setting *)value;
++ const struct jh7110_isp_dnyuv_params * cfg = (const struct jh7110_isp_dnyuv_params *)(&(setting->settings));
++ u32 reg_addr = reg_info->cfg_reg;
++ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
++ void __iomem *ispbase = vin->isp_base;
++
++ reg_write(ispbase, reg_addr, CREATE_REG_VALUE(u8, cfg->y_sweight, 6, 0x7, 4));
++ reg_write(ispbase, reg_addr + 4, CREATE_REG_VALUE(u8, &cfg->y_sweight[6], 4, 0x7, 4));
++ reg_write(ispbase, reg_addr + 8, CREATE_REG_VALUE(u8, cfg->uv_sweight, 6, 0x7, 4));
++ reg_write(ispbase, reg_addr + 12, CREATE_REG_VALUE(u8, &cfg->uv_sweight[6], 4, 0x7, 4));
++ reg_write(ispbase, reg_addr + 16, CREATE_REG_VALUE(u16, &cfg->y_curve[0], 2, 0x3ff, 16));
++ reg_write(ispbase, reg_addr + 20, CREATE_REG_VALUE(u16, &cfg->y_curve[2], 2, 0x3ff, 16));
++ reg_write(ispbase, reg_addr + 24, CREATE_REG_VALUE(u16, &cfg->y_curve[4], 2, 0x3ff, 16));
++ reg_write(ispbase, reg_addr + 28, CREATE_REG_VALUE(u16, &cfg->uv_curve[0], 2, 0x3ff, 16));
++ reg_write(ispbase, reg_addr + 32, CREATE_REG_VALUE(u16, &cfg->uv_curve[2], 2, 0x3ff, 16));
++ reg_write(ispbase, reg_addr + 36, CREATE_REG_VALUE(u16, &cfg->uv_curve[4], 2, 0x3ff, 16));
++
++ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
++
++ return 0;
++}
++
++static int isp_set_ctrl_gmargb(struct stf_isp_dev *isp_dev, const void * value)
++{
++ const struct module_register_info * reg_info = &mod_reg_info[imi_gmargb];
++ const struct jh7110_isp_gmargb_setting * setting = (const struct jh7110_isp_gmargb_setting *)value;
++ const struct jh7110_isp_gmargb_point * curve = setting->curve;
++ u32 reg_addr = reg_info->cfg_reg;
++ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
++ void __iomem *ispbase = vin->isp_base;
++ s32 i;
++
++ for(i = 0; i < 15; i++, curve++, reg_addr += 4)
++ reg_write(ispbase, reg_addr, ((u32)curve->sg_val << 16) | (curve->g_val & 0x3ff));
++
++ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
++
++ return 0;
++}
++
++static int isp_set_ctrl_lccf(struct stf_isp_dev *isp_dev, const void * value)
++{
++ const struct module_register_info * reg_info = &mod_reg_info[imi_lccf];
++ const struct jh7110_isp_lccf_setting * setting = (const struct jh7110_isp_lccf_setting *)value;
++ const s16 * params = (s16 *)(&setting->r_param);
++ u32 reg_addr = reg_info->cfg_reg;
++ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
++ void __iomem *ispbase = vin->isp_base;
++ s32 i;
++
++ reg_write(ispbase, reg_addr, ((u32)(setting->circle.center_y & 0x7fff) << 16) | (setting->circle.center_x & 0x7fff));
++ reg_write(ispbase, reg_addr + 8, setting->circle.radius & 0xf);
++ reg_addr += 0x90;
++ for(i = 0; i < 4; i++, reg_addr += 4, params += 2)
++ reg_write(ispbase, reg_addr, CREATE_REG_VALUE(u16, params, 2, 0x1fff, 16));
++
++ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
++
++ return 0;
++}
++
++static int isp_set_ctrl_obc(struct stf_isp_dev *isp_dev, const void * value)
++{
++ const struct module_register_info * reg_info = &mod_reg_info[imi_obc];
++ const struct jh7110_isp_blacklevel_setting * setting = (const struct jh7110_isp_blacklevel_setting *)value;
++ const u8 * params = (u8 *)setting->gain;
++ u32 reg_addr = reg_info->cfg_reg;
++ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
++ void __iomem *ispbase = vin->isp_base;
++ s32 i;
++
++ reg_write(ispbase, reg_addr, ((u32)(setting->win_size.height & 0xf) << 4) | (setting->win_size.width & 0xf));
++
++ reg_addr += 0x2ac; //0x2e0
++ for(i = 0; i < 8; i++, reg_addr += 4, params += 4)
++ reg_write(ispbase, reg_addr, CREATE_REG_VALUE(u8, params, 4, 0xff, 8));
++
++ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
++
++ return 0;
++}
++
++static int isp_set_ctrl_oecf(struct stf_isp_dev *isp_dev, const void * value)
++{
++ const struct module_register_info * reg_info = &mod_reg_info[imi_oecf];
++ const struct jh7110_isp_oecf_setting * setting = (const struct jh7110_isp_oecf_setting *)value;
++ const struct jh7110_isp_oecf_point * pts = (struct jh7110_isp_oecf_point *)(setting->r_curve);
++ u32 reg_x_addr = reg_info->cfg_reg;
++ u32 reg_y_addr = reg_info->cfg_reg + 0x080;
++ u32 reg_s_addr = reg_info->cfg_reg + 0x100;
++ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
++ void __iomem *ispbase = vin->isp_base;
++ u32 x, y, slope;
++ s32 i;
++
++ for(i = 0; i < 32; i++, reg_x_addr += 4, reg_y_addr += 4, reg_s_addr += 4) {
++ x = pts->x & 0x3ff;
++ y = pts->y & 0x3ff;
++ slope = pts->slope & 0x3ff;
++ pts++;
++ x |= ((pts->x & 0x3ff) << 16);
++ y |= ((pts->y & 0x3ff) << 16);
++ slope |= ((pts->slope & 0x3ff) << 16);
++ pts++;
++
++ reg_write(ispbase, reg_x_addr, x);
++ reg_write(ispbase, reg_y_addr, y);
++ reg_write(ispbase, reg_s_addr, slope);
++ }
++
++ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
++
++ return 0;
++}
++
++static int isp_set_ctrl_r2y(struct stf_isp_dev *isp_dev, const void * value)
++{
++ const struct module_register_info * reg_info = &mod_reg_info[imi_r2y];
++ const struct jh7110_isp_r2y_setting * setting = (const struct jh7110_isp_r2y_setting *)value;
++ const s16 * params = setting->matrix.m;
++ u32 reg_addr = reg_info->cfg_reg;
++ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
++ void __iomem *ispbase = vin->isp_base;
++ s32 i;
++
++ for(i = 0; i < 9; i++, reg_addr += 4)
++ reg_write(ispbase, reg_addr, (u32)(params[i] & 0x1ff));
++
++ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
++
++ return 0;
++}
++
++
++static int isp_set_ctrl_sat(struct stf_isp_dev *isp_dev, const void * value)
++{
++ const struct module_register_info * reg_info = &mod_reg_info[imi_sat];
++ const struct jh7110_isp_sat_setting * setting = (const struct jh7110_isp_sat_setting *)value;
++ const u16 * params = (u16 *)(&setting->sat_info);
++ u32 reg_addr = reg_info->cfg_reg;
++ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
++ void __iomem *ispbase = vin->isp_base;
++ s32 i;
++
++ for(i = 0; i < 3; i++, reg_addr += 4, params += 2)
++ reg_write(ispbase, reg_addr, CREATE_REG_VALUE(u16, params, 2, 0xfff, 16));
++ reg_write(ispbase, reg_addr, CREATE_REG_VALUE(u16, &setting->hue_info.cos, 2, 0x3ff, 16));
++ reg_addr += 4;
++ reg_write(ispbase, reg_addr, setting->sat_info.cmsf & 0xf);
++
++ params = (u16 *)(&setting->curve);
++ reg_addr += 0x14; // 0xa54
++ for(i = 0; i < 2; i++, reg_addr += 4, params += 2)
++ reg_write(ispbase, reg_addr, CREATE_REG_VALUE(u16, params, 2, 0x3fff, 16));
++
++ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
++
++ return 0;
++}
++
++static int isp_set_ctrl_shrp(struct stf_isp_dev *isp_dev, const void * value)
++{
++ const struct module_register_info * reg_info = &mod_reg_info[imi_shrp];
++ const struct jh7110_isp_sharp_setting * setting = (const struct jh7110_isp_sharp_setting *)value;
++ u32 reg_addr = reg_info->cfg_reg;
++ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
++ void __iomem *ispbase = vin->isp_base;
++ s32 i;
++
++ for(i = 0; i < 4; i++, reg_addr += 4)
++ reg_write(ispbase, reg_addr, ((u32)(setting->strength.diff[i] & 0x3ff) << 16) | ((u32)(setting->weight.weight[i] & 0xf) << 8));
++ FILL_ISP_REGS(u8, ispbase, reg_addr, (u8 *)(&setting->weight.weight[4]), 15 - 4, 0xf, 8);
++ reg_addr += (15 - 4) * 4;
++
++ for(i = 0; i < 3; i++, reg_addr += 4)
++ reg_write(ispbase, reg_addr, ((u32)(setting->strength.f[i] & 0x7f) << 24) | (setting->strength.s[i] & 0x1fffff));
++
++ reg_addr += 3 * 4;
++ reg_write(ispbase, reg_addr, ((u32)(setting->pdirf & 0xf) << 28) | ((u32)(setting->ndirf & 0xf) << 24) | (setting->weight.recip_wei_sum & 0x3fffff));
++
++ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
++
++ return 0;
++}
++
++static int isp_set_ctrl_ycrv(struct stf_isp_dev *isp_dev, const void * value)
++{
++ const struct module_register_info * reg_info = &mod_reg_info[imi_ycrv];
++ const struct jh7110_isp_ycrv_setting * setting = (const struct jh7110_isp_ycrv_setting *)value;
++ u32 reg_addr = reg_info->cfg_reg;
++ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
++ void __iomem *ispbase = vin->isp_base;
++
++ FILL_ISP_REGS(u16, ispbase, reg_addr, (u16 *)(setting->curve.y), 64, 0x3ff, 0);
++
++ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
++
++ return 0;
++}
++
++static int isp_set_ctrl_sc(struct stf_isp_dev *isp_dev, const void * value)
++{
++ const struct module_register_info * reg_info = &mod_reg_info[imi_sc];
++ const struct jh7110_isp_sc_setting * setting = (const struct jh7110_isp_sc_setting *)value;
++ const u8 * params = setting->awb_config.awb_cw;
++ u32 reg_addr = 0x00;
++ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
++ void __iomem *ispbase = vin->isp_base;
++ u32 weight_cfg[6] = {0};
++ u32 * weight = weight_cfg;
++ u32 * w_diff = weight_cfg + 2;
++ s32 i;
++
++ // AF register
++ reg_write(ispbase, 0xc0,
++ ((u32)(setting->af_config.es_hor_thr & 0x1ff) << 16) |
++ ((u32)(setting->af_config.es_ver_thr & 0xff) << 8) |
++ ((setting->af_config.ver_en & 0x1) << 3) |
++ ((setting->af_config.hor_en & 0x1) << 2) |
++ ((setting->af_config.es_sum_mode & 0x1) << 1) |
++ (setting->af_config.es_hor_mode & 0x1));
++
++ // AWB weight sum register
++ reg_write(ispbase, 0x5d0, CREATE_REG_VALUE(u8, &setting->awb_config.ws_config.awb_ws_rl, 4, 0xff, 8));
++ reg_write(ispbase, 0x5d4, CREATE_REG_VALUE(u8, &setting->awb_config.ws_config.awb_ws_gbl, 4, 0xff, 8));
++
++ // AWB weight value point
++ reg_addr = 0x4d0;
++ for(i = 0; i < 13; i++) {
++ reg_write(ispbase, reg_addr, CREATE_REG_VALUE(u8, params, 8, 0xf, 4));
++ reg_addr += 4;
++ params += 8;
++ reg_write(ispbase, reg_addr, CREATE_REG_VALUE(u8, params, 5, 0xf, 4));
++ reg_addr += 4;
++ params += 5;
++ }
++
++ // AWB intensity weight curve register
++ reg_addr = 0x538;
++ for(i = 0; i < 4; i++) {
++ weight[0] |= (setting->awb_config.pts[i].weight & 0xf) << (i * 4);
++ w_diff[0] |= ((((s16)(setting->awb_config.pts[i + 1].weight & 0xf) - (s16)(setting->awb_config.pts[i].weight & 0xf)) * 2) & 0xff) << (i * 8);
++ }
++ for(w_diff++; i < 8; i++) {
++ weight[0] |= (setting->awb_config.pts[i].weight & 0xf) << (i * 4);
++ w_diff[0] |= ((((s16)(setting->awb_config.pts[i + 1].weight & 0xf) - (s16)(setting->awb_config.pts[i].weight & 0xf)) * 2) & 0xff) << (i * 8);
++ }
++ for(weight++, w_diff++; i < 12; i++) {
++ weight[0] |= (setting->awb_config.pts[i].weight & 0xf) << (i * 4);
++ w_diff[0] |= ((((s16)(setting->awb_config.pts[i + 1].weight & 0xf) - (s16)(setting->awb_config.pts[i].weight & 0xf)) * 2) & 0xff) << (i * 8);
++ }
++ for(w_diff++; i < 16; i++) {
++ weight[0] |= (setting->awb_config.pts[i].weight & 0xf) << (i * 4);
++ w_diff[0] |= ((((s16)(setting->awb_config.pts[i + 1].weight & 0xf) - (s16)(setting->awb_config.pts[i].weight & 0xf)) * 2) & 0xff) << (i * 8);
++ }
++
++ FILL_ISP_REGS(u32, ispbase, reg_addr, weight_cfg, 6, 0xffffffff, 0);
++
++ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
++
++ return 0;
++}
++
+ static int isp_s_ctrl(struct v4l2_ctrl *ctrl)
+ {
+ struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
+@@ -310,10 +740,52 @@ static int isp_s_ctrl(struct v4l2_ctrl *
+ ret = isp_set_ctrl_vflip(isp_dev, ctrl->val);
+ break;
+ case V4L2_CID_USER_JH7110_ISP_WB_SETTING:
++ ret = isp_set_ctrl_wb(isp_dev, ctrl->p_new.p_u8);
+ break;
+ case V4L2_CID_USER_JH7110_ISP_CAR_SETTING:
++ ret = isp_set_ctrl_car(isp_dev, ctrl->p_new.p_u8);
+ break;
+ case V4L2_CID_USER_JH7110_ISP_CCM_SETTING:
++ ret = isp_set_ctrl_ccm(isp_dev, ctrl->p_new.p_u8);
++ break;
++ case V4L2_CID_USER_JH7110_ISP_CFA_SETTING:
++ ret = isp_set_ctrl_cfa(isp_dev, ctrl->p_new.p_u8);
++ break;
++ case V4L2_CID_USER_JH7110_ISP_CTC_SETTING:
++ ret = isp_set_ctrl_ctc(isp_dev, ctrl->p_new.p_u8);
++ break;
++ case V4L2_CID_USER_JH7110_ISP_DBC_SETTING:
++ ret = isp_set_ctrl_dbc(isp_dev, ctrl->p_new.p_u8);
++ break;
++ case V4L2_CID_USER_JH7110_ISP_DNYUV_SETTING:
++ ret = isp_set_ctrl_dnyuv(isp_dev, ctrl->p_new.p_u8);
++ break;
++ case V4L2_CID_USER_JH7110_ISP_GMARGB_SETTING:
++ ret = isp_set_ctrl_gmargb(isp_dev, ctrl->p_new.p_u8);
++ break;
++ case V4L2_CID_USER_JH7110_ISP_LCCF_SETTING:
++ ret = isp_set_ctrl_lccf(isp_dev, ctrl->p_new.p_u8);
++ break;
++ case V4L2_CID_USER_JH7110_ISP_OBC_SETTING:
++ ret = isp_set_ctrl_obc(isp_dev, ctrl->p_new.p_u8);
++ break;
++ case V4L2_CID_USER_JH7110_ISP_OECF_SETTING:
++ ret = isp_set_ctrl_oecf(isp_dev, ctrl->p_new.p_u8);
++ break;
++ case V4L2_CID_USER_JH7110_ISP_R2Y_SETTING:
++ ret = isp_set_ctrl_r2y(isp_dev, ctrl->p_new.p_u8);
++ break;
++ case V4L2_CID_USER_JH7110_ISP_SAT_SETTING:
++ ret = isp_set_ctrl_sat(isp_dev, ctrl->p_new.p_u8);
++ break;
++ case V4L2_CID_USER_JH7110_ISP_SHRP_SETTING:
++ ret = isp_set_ctrl_shrp(isp_dev, ctrl->p_new.p_u8);
++ break;
++ case V4L2_CID_USER_JH7110_ISP_YCRV_SETTING:
++ ret = isp_set_ctrl_ycrv(isp_dev, ctrl->p_new.p_u8);
++ break;
++ case V4L2_CID_USER_JH7110_ISP_STAT_SETTING:
++ ret = isp_set_ctrl_sc(isp_dev, ctrl->p_new.p_u8);
+ break;
+ default:
+ ret = -EINVAL;
+@@ -365,6 +837,162 @@ struct v4l2_ctrl_config isp_ctrl[] = {
+ .dims[0] = sizeof(struct jh7110_isp_ccm_setting),
+ .flags = 0,
+ },
++ [3] = {
++ .ops = &isp_ctrl_ops,
++ .type = V4L2_CTRL_TYPE_U8,
++ .def = 0,
++ .min = 0x00,
++ .max = 0xff,
++ .step = 1,
++ .name = "CFA Setting",
++ .id = V4L2_CID_USER_JH7110_ISP_CFA_SETTING,
++ .dims[0] = sizeof(struct jh7110_isp_cfa_setting),
++ .flags = 0,
++ },
++ [4] = {
++ .ops = &isp_ctrl_ops,
++ .type = V4L2_CTRL_TYPE_U8,
++ .def = 0,
++ .min = 0x00,
++ .max = 0xff,
++ .step = 1,
++ .name = "CTC Setting",
++ .id = V4L2_CID_USER_JH7110_ISP_CTC_SETTING,
++ .dims[0] = sizeof(struct jh7110_isp_ctc_setting),
++ .flags = 0,
++ },
++ [5] = {
++ .ops = &isp_ctrl_ops,
++ .type = V4L2_CTRL_TYPE_U8,
++ .def = 0,
++ .min = 0x00,
++ .max = 0xff,
++ .step = 1,
++ .name = "CTC Setting",
++ .id = V4L2_CID_USER_JH7110_ISP_DBC_SETTING,
++ .dims[0] = sizeof(struct jh7110_isp_dbc_setting),
++ .flags = 0,
++ },
++ [6] = {
++ .ops = &isp_ctrl_ops,
++ .type = V4L2_CTRL_TYPE_U8,
++ .def = 0,
++ .min = 0x00,
++ .max = 0xff,
++ .step = 1,
++ .name = "DNYUV Setting",
++ .id = V4L2_CID_USER_JH7110_ISP_DNYUV_SETTING,
++ .dims[0] = sizeof(struct jh7110_isp_dnyuv_setting),
++ .flags = 0,
++ },
++ [7] = {
++ .ops = &isp_ctrl_ops,
++ .type = V4L2_CTRL_TYPE_U8,
++ .def = 0,
++ .min = 0x00,
++ .max = 0xff,
++ .step = 1,
++ .name = "DNYUV Setting",
++ .id = V4L2_CID_USER_JH7110_ISP_GMARGB_SETTING,
++ .dims[0] = sizeof(struct jh7110_isp_gmargb_setting),
++ .flags = 0,
++ },
++ [8] = {
++ .ops = &isp_ctrl_ops,
++ .type = V4L2_CTRL_TYPE_U8,
++ .def = 0,
++ .min = 0x00,
++ .max = 0xff,
++ .step = 1,
++ .name = "LCCF Setting",
++ .id = V4L2_CID_USER_JH7110_ISP_LCCF_SETTING,
++ .dims[0] = sizeof(struct jh7110_isp_lccf_setting),
++ .flags = 0,
++ },
++ [9] = {
++ .ops = &isp_ctrl_ops,
++ .type = V4L2_CTRL_TYPE_U8,
++ .def = 0,
++ .min = 0x00,
++ .max = 0xff,
++ .step = 1,
++ .name = "OBC Setting",
++ .id = V4L2_CID_USER_JH7110_ISP_OBC_SETTING,
++ .dims[0] = sizeof(struct jh7110_isp_blacklevel_setting),
++ .flags = 0,
++ },
++ [10] = {
++ .ops = &isp_ctrl_ops,
++ .type = V4L2_CTRL_TYPE_U8,
++ .def = 0,
++ .min = 0x00,
++ .max = 0xff,
++ .step = 1,
++ .name = "OECF Setting",
++ .id = V4L2_CID_USER_JH7110_ISP_OECF_SETTING,
++ .dims[0] = sizeof(struct jh7110_isp_oecf_setting),
++ .flags = 0,
++ },
++ [11] = {
++ .ops = &isp_ctrl_ops,
++ .type = V4L2_CTRL_TYPE_U8,
++ .def = 0,
++ .min = 0x00,
++ .max = 0xff,
++ .step = 1,
++ .name = "R2Y Setting",
++ .id = V4L2_CID_USER_JH7110_ISP_R2Y_SETTING,
++ .dims[0] = sizeof(struct jh7110_isp_r2y_setting),
++ .flags = 0,
++ },
++ [12] = {
++ .ops = &isp_ctrl_ops,
++ .type = V4L2_CTRL_TYPE_U8,
++ .def = 0,
++ .min = 0x00,
++ .max = 0xff,
++ .step = 1,
++ .name = "SAT Setting",
++ .id = V4L2_CID_USER_JH7110_ISP_SAT_SETTING,
++ .dims[0] = sizeof(struct jh7110_isp_sat_setting),
++ .flags = 0,
++ },
++ [13] = {
++ .ops = &isp_ctrl_ops,
++ .type = V4L2_CTRL_TYPE_U8,
++ .def = 0,
++ .min = 0x00,
++ .max = 0xff,
++ .step = 1,
++ .name = "SAT Setting",
++ .id = V4L2_CID_USER_JH7110_ISP_SHRP_SETTING,
++ .dims[0] = sizeof(struct jh7110_isp_sharp_setting),
++ .flags = 0,
++ },
++ [14] = {
++ .ops = &isp_ctrl_ops,
++ .type = V4L2_CTRL_TYPE_U8,
++ .def = 0,
++ .min = 0x00,
++ .max = 0xff,
++ .step = 1,
++ .name = "YCRV Setting",
++ .id = V4L2_CID_USER_JH7110_ISP_YCRV_SETTING,
++ .dims[0] = sizeof(struct jh7110_isp_ycrv_setting),
++ .flags = 0,
++ },
++ [15] = {
++ .ops = &isp_ctrl_ops,
++ .type = V4L2_CTRL_TYPE_U8,
++ .def = 0,
++ .min = 0x00,
++ .max = 0xff,
++ .step = 1,
++ .name = "SC Setting",
++ .id = V4L2_CID_USER_JH7110_ISP_STAT_SETTING,
++ .dims[0] = sizeof(struct jh7110_isp_sc_setting),
++ .flags = 0,
++ },
+ };
+
+ static int isp_init_controls(struct stf_isp_dev *isp_dev)
+--- a/drivers/media/platform/starfive/v4l2_driver/stf_video.c
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_video.c
+@@ -1281,6 +1281,22 @@ int video_s_selection(struct file *file,
+ return ret;
+ }
+
++static int stf_video_subscribe_event(struct v4l2_fh *fh,
++ const struct v4l2_event_subscription *sub)
++{
++ switch (sub->type) {
++ case V4L2_EVENT_FRAME_SYNC:
++ return v4l2_event_subscribe(fh, sub, 2, NULL);
++ //int ret = v4l2_event_subscribe(fh, sub, 2, NULL);
++ //pr_info("subscribe ret: %d\n", ret);
++ //return ret;
++ default:
++ return v4l2_ctrl_subscribe_event(fh, sub);
++ //st_debug(ST_VIN, "unsupport subscribe_event\n");
++ //return -EINVAL;
++ }
++}
++
+ static const struct v4l2_ioctl_ops stf_vid_ioctl_ops = {
+ .vidioc_querycap = video_querycap,
+ .vidioc_enum_fmt_vid_cap = video_enum_fmt,
+@@ -1305,6 +1321,8 @@ static const struct v4l2_ioctl_ops stf_v
+ .vidioc_s_parm = video_s_parm,
+ .vidioc_s_selection = video_s_selection,
+ .vidioc_g_selection = video_g_selection,
++ .vidioc_subscribe_event = stf_video_subscribe_event,
++ .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
+ };
+
+ static const struct v4l2_ioctl_ops stf_vid_ioctl_ops_mp = {
+@@ -1331,6 +1349,8 @@ static const struct v4l2_ioctl_ops stf_v
+ .vidioc_s_parm = video_s_parm,
+ .vidioc_s_selection = video_s_selection,
+ .vidioc_g_selection = video_g_selection,
++ .vidioc_subscribe_event = stf_video_subscribe_event,
++ .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
+ };
+
+ static const struct v4l2_ioctl_ops stf_vid_ioctl_ops_out = {
+@@ -1350,6 +1370,8 @@ static const struct v4l2_ioctl_ops stf_v
+ .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
+ .vidioc_streamon = vb2_ioctl_streamon,
+ .vidioc_streamoff = vb2_ioctl_streamoff,
++ .vidioc_subscribe_event = stf_video_subscribe_event,
++ .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
+ };
+
+ static int video_open(struct file *file)
+--- a/drivers/media/platform/starfive/v4l2_driver/stf_vin.c
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_vin.c
+@@ -1145,9 +1145,12 @@ static void vin_buffer_done(struct vin_l
+ spin_lock_irqsave(&line->output_lock, flags);
+
+ while ((ready_buf = vin_buf_get_ready(output))) {
+- if (line->id >= VIN_LINE_ISP && line->id <= VIN_LINE_ISP_SS1) {
++ //if (line->id >= VIN_LINE_ISP && line->id <= VIN_LINE_ISP_SS1) {
++ if (line->id == VIN_LINE_ISP_SCD_Y) {
+ event.u.frame_sync.frame_sequence = output->sequence;
+- v4l2_event_queue(line->subdev.devnode, &event);
++ v4l2_event_queue(&(line->video_out.vdev), &event);
++ //v4l2_event_queue(line->subdev.devnode, &event);
++ //pr_info("----------frame sync-----------\n");
+ }
+
+ ready_buf->vb.vb2_buf.timestamp = ts;
+@@ -1346,7 +1349,10 @@ static int stf_vin_subscribe_event(struc
+ {
+ switch (sub->type) {
+ case V4L2_EVENT_FRAME_SYNC:
+- return v4l2_event_subscribe(fh, sub, 0, NULL);
++ //return v4l2_event_subscribe(fh, sub, 2, NULL);
++ int ret = v4l2_event_subscribe(fh, sub, 2, NULL);
++ pr_info("subscribe ret: %d\n", ret);
++ return ret;
+ default:
+ st_debug(ST_VIN, "unsupport subscribe_event\n");
+ return -EINVAL;
+@@ -1355,8 +1361,8 @@ static int stf_vin_subscribe_event(struc
+
+ static const struct v4l2_subdev_core_ops vin_core_ops = {
+ .s_power = vin_set_power,
+- .subscribe_event = stf_vin_subscribe_event,
+- .unsubscribe_event = v4l2_event_subdev_unsubscribe,
++ //.subscribe_event = stf_vin_subscribe_event,
++ //.unsubscribe_event = v4l2_event_subdev_unsubscribe,
+ };
+
+ static const struct v4l2_subdev_video_ops vin_video_ops = {
+--- a/include/uapi/linux/jh7110-isp.h
++++ b/include/uapi/linux/jh7110-isp.h
+@@ -15,6 +15,8 @@
+
+ #include <linux/v4l2-controls.h>
+
++#define V4L2_CID_USER_JH7110_ISP_BASE (V4L2_CID_USER_BASE + 0x1170)
++
+ #define V4L2_CID_USER_JH7110_ISP_WB_SETTING \
+ (V4L2_CID_USER_JH7110_ISP_BASE + 0x0001)
+ #define V4L2_CID_USER_JH7110_ISP_CAR_SETTING \
+@@ -45,6 +47,8 @@
+ (V4L2_CID_USER_JH7110_ISP_BASE + 0x000e)
+ #define V4L2_CID_USER_JH7110_ISP_YCRV_SETTING \
+ (V4L2_CID_USER_JH7110_ISP_BASE + 0x000f)
++#define V4L2_CID_USER_JH7110_ISP_STAT_SETTING \
++ (V4L2_CID_USER_JH7110_ISP_BASE + 0x0010)
+
+ struct jh7110_isp_wb_gain {
+ __u16 gain_r;
+@@ -202,13 +206,13 @@ struct jh7110_isp_sat_curve {
+ };
+
+ struct jh7110_isp_sat_hue_info {
+- __s16 sin;
+ __s16 cos;
++ __s16 sin;
+ };
+
+ struct jh7110_isp_sat_info {
+ __s16 gain_cmab;
+- __s16 gain_cmad;
++ __s16 gain_cmmd;
+ __s16 threshold_cmb;
+ __s16 threshold_cmd;
+ __s16 offset_u;
+@@ -230,7 +234,8 @@ struct jh7110_isp_sharp_weight {
+
+ struct jh7110_isp_sharp_strength {
+ __s16 diff[4];
+- __s16 f[4];
++ __s16 f[3];
++ __s32 s[3];
+ };
+
+ struct jh7110_isp_sharp_setting {
+@@ -250,4 +255,41 @@ struct jh7110_isp_ycrv_setting {
+ struct jh7110_isp_ycrv_curve curve;
+ };
+
++struct jh7110_isp_sc_af_config {
++ __u8 es_hor_mode;
++ __u8 es_sum_mode;
++ __u8 hor_en;
++ __u8 ver_en;
++ __u8 es_ver_thr;
++ __u16 es_hor_thr;
++};
++
++struct jh7110_isp_sc_awb_ws {
++ __u8 awb_ws_rl;
++ __u8 awb_ws_ru;
++ __u8 awb_ws_grl;
++ __u8 awb_ws_gru;
++ __u8 awb_ws_gbl;
++ __u8 awb_ws_gbu;
++ __u8 awb_ws_bl;
++ __u8 awb_ws_bu;
++};
++
++struct jh7110_isp_sc_awb_point {
++ __u16 intensity;
++ __u8 weight;
++};
++
++struct jh7110_isp_sc_awb_config {
++ struct jh7110_isp_sc_awb_ws ws_config;
++ __u8 awb_cw[169];
++ struct jh7110_isp_sc_awb_point pts[17];
++};
++
++struct jh7110_isp_sc_setting {
++ __u32 enabled;
++ struct jh7110_isp_sc_af_config af_config;
++ struct jh7110_isp_sc_awb_config awb_config;
++};
++
+ #endif
diff --git a/target/linux/starfive/patches-6.6/0095-Expand-2-bytes-after-the-SC-buffer-for-the-AE-AWB-fl.patch b/target/linux/starfive/patches-6.6/0095-Expand-2-bytes-after-the-SC-buffer-for-the-AE-AWB-fl.patch
new file mode 100644
index 0000000000..d023674f79
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0095-Expand-2-bytes-after-the-SC-buffer-for-the-AE-AWB-fl.patch
@@ -0,0 +1,249 @@
+From 5d61c6fd10144605238311d68c99449c4667a345 Mon Sep 17 00:00:00 2001
+From: "zejian.su" <zejian.su@starfivetech.com>
+Date: Mon, 7 Aug 2023 10:38:36 +0800
+Subject: [PATCH 095/116] Expand 2 bytes after the SC buffer for the AE/AWB
+ flag and copy the histogram data to the SC buffer.
+
+---
+ .../platform/starfive/v4l2_driver/stf_isp.c | 37 ++++++++++++++++++-
+ .../platform/starfive/v4l2_driver/stf_isp.h | 2 +-
+ .../platform/starfive/v4l2_driver/stf_video.c | 5 ---
+ .../platform/starfive/v4l2_driver/stf_vin.c | 36 +++++++++---------
+ include/uapi/linux/jh7110-isp.h | 33 +++++++++++++++++
+ 5 files changed, 87 insertions(+), 26 deletions(-)
+
+--- a/drivers/media/platform/starfive/v4l2_driver/stf_isp.c
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_isp.c
+@@ -323,6 +323,13 @@ FILL_ISP_REGS_FUNC(u16);
+ #define FILL_ISP_REGS(type, ispbase, offset, value, size, mask, nbits) \
+ fill_isp_regs_##type(ispbase, offset, value, size, mask, nbits)
+
++static void fill_regs_with_zero(void __iomem *ispbase, u32 offset, u32 size)
++{
++ u32 i;
++ for(i = 0; i < size; i++, offset += 4)
++ reg_write(ispbase, offset, 0);
++}
++
+ static int isp_set_ctrl_wb(struct stf_isp_dev *isp_dev, const void * value)
+ {
+ const struct module_register_info * reg_info = &mod_reg_info[imi_awb];
+@@ -335,6 +342,8 @@ static int isp_set_ctrl_wb(struct stf_is
+ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
+ void __iomem *ispbase = vin->isp_base;
+
++ fill_regs_with_zero(ispbase, reg_info->cfg_reg, 16);
++
+ reg_write(ispbase, reg_addr, r_g);
+ reg_write(ispbase, reg_addr + 1 * 4, r_g);
+ reg_write(ispbase, reg_addr + 2 * 4, g_g);
+@@ -370,8 +379,13 @@ static int isp_set_ctrl_ccm(struct stf_i
+ void __iomem *ispbase = vin->isp_base;
+
+ reg_write(ispbase, reg_info->cfg_reg, 6 << 16);
++ fill_regs_with_zero(ispbase, reg_info->cfg_reg + 4, 11);
++
+ FILL_ISP_REGS(u32, ispbase, reg_addr, (u32 *)ccm, 12, 0x7ff, 0);
+
++ reg_addr += 12 * 4;
++ fill_regs_with_zero(ispbase, reg_addr, 2);
++
+ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
+
+ return 0;
+@@ -640,6 +654,27 @@ static int isp_set_ctrl_sc(struct stf_is
+ u32 * w_diff = weight_cfg + 2;
+ s32 i;
+
++ // SC dumping axi id
++ reg_write(ispbase, 0x9c, 1 << 24);
++
++ // SC frame crop
++ reg_write(ispbase, 0xb8, ((u32)(setting->crop_config.v_start) << 16) | setting->crop_config.h_start);
++
++ // SC config1
++ reg_write(ispbase, 0xbc, ((u32)(setting->awb_config.sel) << 30) | ((u32)(setting->awb_config.awb_ps_grb_ba) << 16) |
++ ((u32)(setting->crop_config.sw_height) << 8) | setting->crop_config.sw_width);
++
++ // SC decimation config
++ reg_write(ispbase, 0xd8, ((u32)(setting->crop_config.vkeep) << 24) | ((u32)(setting->crop_config.vperiod) << 16) |
++ ((u32)(setting->crop_config.hkeep) << 8) | setting->crop_config.hperiod);
++
++ // SC AWB pixel sum config
++ reg_write(ispbase, 0xc4, CREATE_REG_VALUE(u8, &setting->awb_config.ws_ps_config.awb_ps_rl, 4, 0xff, 8));
++ reg_write(ispbase, 0xc8, CREATE_REG_VALUE(u8, &setting->awb_config.ws_ps_config.awb_ps_bl, 4, 0xff, 8));
++ reg_write(ispbase, 0xcc, CREATE_REG_VALUE(u16, &setting->awb_config.ws_ps_config.awb_ps_grl, 2, 0xffff, 16));
++ reg_write(ispbase, 0xd0, CREATE_REG_VALUE(u16, &setting->awb_config.ws_ps_config.awb_ps_gbl, 2, 0xffff, 16));
++ reg_write(ispbase, 0xd4, CREATE_REG_VALUE(u16, &setting->awb_config.ws_ps_config.awb_ps_grbl, 2, 0xffff, 16));
++
+ // AF register
+ reg_write(ispbase, 0xc0,
+ ((u32)(setting->af_config.es_hor_thr & 0x1ff) << 16) |
+@@ -686,7 +721,7 @@ static int isp_set_ctrl_sc(struct stf_is
+ FILL_ISP_REGS(u32, ispbase, reg_addr, weight_cfg, 6, 0xffffffff, 0);
+
+ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
+-
++
+ return 0;
+ }
+
+--- a/drivers/media/platform/starfive/v4l2_driver/stf_isp.h
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_isp.h
+@@ -18,7 +18,7 @@
+
+ #define ISP_SCD_BUFFER_SIZE (19 * 256 * 4) // align 128
+ #define ISP_YHIST_BUFFER_SIZE (64 * 4)
+-#define ISP_SCD_Y_BUFFER_SIZE (ISP_SCD_BUFFER_SIZE + ISP_YHIST_BUFFER_SIZE)
++#define ISP_SCD_Y_BUFFER_SIZE (ISP_SCD_BUFFER_SIZE + ISP_YHIST_BUFFER_SIZE + 2)
+ #define ISP_RAW_DATA_BITS 12
+ #define SCALER_RATIO_MAX 1 // no compose function
+ #define STF_ISP_REG_OFFSET_MAX 0x0FFF
+--- a/drivers/media/platform/starfive/v4l2_driver/stf_video.c
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_video.c
+@@ -1287,13 +1287,8 @@ static int stf_video_subscribe_event(str
+ switch (sub->type) {
+ case V4L2_EVENT_FRAME_SYNC:
+ return v4l2_event_subscribe(fh, sub, 2, NULL);
+- //int ret = v4l2_event_subscribe(fh, sub, 2, NULL);
+- //pr_info("subscribe ret: %d\n", ret);
+- //return ret;
+ default:
+ return v4l2_ctrl_subscribe_event(fh, sub);
+- //st_debug(ST_VIN, "unsupport subscribe_event\n");
+- //return -EINVAL;
+ }
+ }
+
+--- a/drivers/media/platform/starfive/v4l2_driver/stf_vin.c
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_vin.c
+@@ -1147,6 +1147,17 @@ static void vin_buffer_done(struct vin_l
+ while ((ready_buf = vin_buf_get_ready(output))) {
+ //if (line->id >= VIN_LINE_ISP && line->id <= VIN_LINE_ISP_SS1) {
+ if (line->id == VIN_LINE_ISP_SCD_Y) {
++#define ADDR_REG_YHIST_ACC_0 0x0D00
++ struct stf_vin2_dev *vin_dev = line_to_vin2_dev(line);
++ struct stf_vin_dev *vin = vin_dev->stfcamss->vin;
++ void __iomem *ispbase = vin->isp_base;
++ u32 y_hist_reg_addr = ADDR_REG_YHIST_ACC_0;
++ u32 * y_hist_addr = (u32 *)ready_buf->vaddr_sc;
++ s32 i = 0;
++
++ for(i = 0; i < 64; i++, y_hist_reg_addr += 4)
++ y_hist_addr[i] = reg_read(ispbase, y_hist_reg_addr);
++
+ event.u.frame_sync.frame_sequence = output->sequence;
+ v4l2_event_queue(&(line->video_out.vdev), &event);
+ //v4l2_event_queue(line->subdev.devnode, &event);
+@@ -1246,9 +1257,14 @@ static void vin_change_buffer(struct vin
+ scd_type = vin_dev->hw_ops->vin_isp_get_scd_type(vin_dev);
+ ready_buf->vb.flags &= ~(V4L2_BUF_FLAG_PFRAME | V4L2_BUF_FLAG_BFRAME);
+ if (scd_type == AWB_TYPE)
++ {
+ ready_buf->vb.flags |= V4L2_BUF_FLAG_PFRAME;
+- else
++ *((u16 *)(ready_buf->vaddr_sc + ISP_SCD_BUFFER_SIZE + ISP_YHIST_BUFFER_SIZE)) = 0xffff;
++ }else{
+ ready_buf->vb.flags |= V4L2_BUF_FLAG_BFRAME;
++ *((u16 *)(ready_buf->vaddr_sc + ISP_SCD_BUFFER_SIZE + ISP_YHIST_BUFFER_SIZE)) = 0;
++ }
++
+ if (!output->frame_skip) {
+ output->frame_skip = ISP_AWB_OECF_SKIP_FRAME;
+ scd_type = scd_type == AWB_TYPE ? OECF_TYPE : AWB_TYPE;
+@@ -1343,26 +1359,8 @@ static int vin_link_setup(struct media_e
+ return 0;
+ }
+
+-static int stf_vin_subscribe_event(struct v4l2_subdev *sd,
+- struct v4l2_fh *fh,
+- struct v4l2_event_subscription *sub)
+-{
+- switch (sub->type) {
+- case V4L2_EVENT_FRAME_SYNC:
+- //return v4l2_event_subscribe(fh, sub, 2, NULL);
+- int ret = v4l2_event_subscribe(fh, sub, 2, NULL);
+- pr_info("subscribe ret: %d\n", ret);
+- return ret;
+- default:
+- st_debug(ST_VIN, "unsupport subscribe_event\n");
+- return -EINVAL;
+- }
+-}
+-
+ static const struct v4l2_subdev_core_ops vin_core_ops = {
+ .s_power = vin_set_power,
+- //.subscribe_event = stf_vin_subscribe_event,
+- //.unsubscribe_event = v4l2_event_subdev_unsubscribe,
+ };
+
+ static const struct v4l2_subdev_video_ops vin_video_ops = {
+--- a/include/uapi/linux/jh7110-isp.h
++++ b/include/uapi/linux/jh7110-isp.h
+@@ -255,6 +255,17 @@ struct jh7110_isp_ycrv_setting {
+ struct jh7110_isp_ycrv_curve curve;
+ };
+
++struct jh7110_isp_sc_config {
++ __u16 h_start;
++ __u16 v_start;
++ __u8 sw_width;
++ __u8 sw_height;
++ __u8 hperiod;
++ __u8 hkeep;
++ __u8 vperiod;
++ __u8 vkeep;
++};
++
+ struct jh7110_isp_sc_af_config {
+ __u8 es_hor_mode;
+ __u8 es_sum_mode;
+@@ -264,6 +275,23 @@ struct jh7110_isp_sc_af_config {
+ __u16 es_hor_thr;
+ };
+
++struct jh7110_isp_sc_awb_ps {
++ __u8 awb_ps_rl;
++ __u8 awb_ps_ru;
++ __u8 awb_ps_gl;
++ __u8 awb_ps_gu;
++ __u8 awb_ps_bl;
++ __u8 awb_ps_bu;
++ __u8 awb_ps_yl;
++ __u8 awb_ps_yu;
++ __u16 awb_ps_grl;
++ __u16 awb_ps_gru;
++ __u16 awb_ps_gbl;
++ __u16 awb_ps_gbu;
++ __u16 awb_ps_grbl;
++ __u16 awb_ps_grbu;
++};
++
+ struct jh7110_isp_sc_awb_ws {
+ __u8 awb_ws_rl;
+ __u8 awb_ws_ru;
+@@ -275,12 +303,16 @@ struct jh7110_isp_sc_awb_ws {
+ __u8 awb_ws_bu;
+ };
+
++
+ struct jh7110_isp_sc_awb_point {
+ __u16 intensity;
+ __u8 weight;
+ };
+
+ struct jh7110_isp_sc_awb_config {
++ struct jh7110_isp_sc_awb_ps ws_ps_config;
++ __u8 awb_ps_grb_ba;
++ __u8 sel;
+ struct jh7110_isp_sc_awb_ws ws_config;
+ __u8 awb_cw[169];
+ struct jh7110_isp_sc_awb_point pts[17];
+@@ -288,6 +320,7 @@ struct jh7110_isp_sc_awb_config {
+
+ struct jh7110_isp_sc_setting {
+ __u32 enabled;
++ struct jh7110_isp_sc_config crop_config;
+ struct jh7110_isp_sc_af_config af_config;
+ struct jh7110_isp_sc_awb_config awb_config;
+ };
diff --git a/target/linux/starfive/patches-6.6/0096-Add-ISP-control-for-video2-and-video3.patch b/target/linux/starfive/patches-6.6/0096-Add-ISP-control-for-video2-and-video3.patch
new file mode 100644
index 0000000000..5737fb255e
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0096-Add-ISP-control-for-video2-and-video3.patch
@@ -0,0 +1,117 @@
+From 04eff0f76091015cbecd39de41d45c493e7a91db Mon Sep 17 00:00:00 2001
+From: "zejian.su" <zejian.su@starfivetech.com>
+Date: Mon, 30 Oct 2023 16:09:58 +0800
+Subject: [PATCH 096/116] Add ISP control for video2 and video3.
+
+Signed-off-by: zejian.su <zejian.su@starfivetech.com>
+---
+ .../platform/starfive/v4l2_driver/stf_isp.c | 46 +++++++++++++++++++
+ include/uapi/linux/jh7110-isp.h | 23 ++++++++++
+ 2 files changed, 69 insertions(+)
+
+--- a/drivers/media/platform/starfive/v4l2_driver/stf_isp.c
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_isp.c
+@@ -725,6 +725,24 @@ static int isp_set_ctrl_sc(struct stf_is
+ return 0;
+ }
+
++static int isp_set_ctrl_outss(struct stf_isp_dev *isp_dev, const void * value)
++{
++ const struct jh7110_isp_outss_setting * setting = (const struct jh7110_isp_outss_setting *)value;
++ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
++ void __iomem *ispbase = vin->isp_base;
++ u32 reg_addr = !setting->which ? 0xa9c : 0xab4;
++
++ if(!setting->stride)
++ return 0;
++
++ // Output Image Stride Register, 8-byte(64bit) granularity.
++ reg_write(ispbase, reg_addr, setting->stride);
++ reg_write(ispbase, reg_addr + 4, ((setting->hsm << 16) | (setting->hsm & 0x3)));
++ reg_write(ispbase, reg_addr + 8, ((setting->vsm << 16) | (setting->vsm & 0x3)));
++
++ return 0;
++}
++
+ static int isp_s_ctrl(struct v4l2_ctrl *ctrl)
+ {
+ struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
+@@ -822,6 +840,10 @@ static int isp_s_ctrl(struct v4l2_ctrl *
+ case V4L2_CID_USER_JH7110_ISP_STAT_SETTING:
+ ret = isp_set_ctrl_sc(isp_dev, ctrl->p_new.p_u8);
+ break;
++ case V4L2_CID_USER_JH7110_ISP_OUTSS0_SETTING:
++ case V4L2_CID_USER_JH7110_ISP_OUTSS1_SETTING:
++ ret = isp_set_ctrl_outss(isp_dev, ctrl->p_new.p_u8);
++ break;
+ default:
+ ret = -EINVAL;
+ break;
+@@ -1028,6 +1050,30 @@ struct v4l2_ctrl_config isp_ctrl[] = {
+ .dims[0] = sizeof(struct jh7110_isp_sc_setting),
+ .flags = 0,
+ },
++ [16] = {
++ .ops = &isp_ctrl_ops,
++ .type = V4L2_CTRL_TYPE_U8,
++ .def = 0,
++ .min = 0x00,
++ .max = 0xff,
++ .step = 1,
++ .name = "OUTSS Setting",
++ .id = V4L2_CID_USER_JH7110_ISP_OUTSS0_SETTING,
++ .dims[0] = sizeof(struct jh7110_isp_outss_setting),
++ .flags = 0,
++ },
++ [17] = {
++ .ops = &isp_ctrl_ops,
++ .type = V4L2_CTRL_TYPE_U8,
++ .def = 0,
++ .min = 0x00,
++ .max = 0xff,
++ .step = 1,
++ .name = "OUTSS Setting",
++ .id = V4L2_CID_USER_JH7110_ISP_OUTSS1_SETTING,
++ .dims[0] = sizeof(struct jh7110_isp_outss_setting),
++ .flags = 0,
++ },
+ };
+
+ static int isp_init_controls(struct stf_isp_dev *isp_dev)
+--- a/include/uapi/linux/jh7110-isp.h
++++ b/include/uapi/linux/jh7110-isp.h
+@@ -49,6 +49,10 @@
+ (V4L2_CID_USER_JH7110_ISP_BASE + 0x000f)
+ #define V4L2_CID_USER_JH7110_ISP_STAT_SETTING \
+ (V4L2_CID_USER_JH7110_ISP_BASE + 0x0010)
++#define V4L2_CID_USER_JH7110_ISP_OUTSS0_SETTING \
++ (V4L2_CID_USER_JH7110_ISP_BASE + 0x0011)
++#define V4L2_CID_USER_JH7110_ISP_OUTSS1_SETTING \
++ (V4L2_CID_USER_JH7110_ISP_BASE + 0x0012)
+
+ struct jh7110_isp_wb_gain {
+ __u16 gain_r;
+@@ -325,4 +329,23 @@ struct jh7110_isp_sc_setting {
+ struct jh7110_isp_sc_awb_config awb_config;
+ };
+
++struct jh7110_isp_outss_setting {
++ __u8 which;
++ __u16 stride; // Output Image Stride Register, 8-byte(64bit) granularity.
++ __u8 hsm; // horizontal scale mode
++ __u32 hsf; // horizontal scale factor (time 4096)
++ __u8 vsm; // vertical scale mode
++ __u32 vsf; // vertical scale factor (time 4096)
++};
++
++struct jh7110_isp_sc_buffer {
++ __u32 y_histogram[64];
++ __u32 reserv0[33];
++ __u32 bright_sc[4096];
++ __u32 reserv1[96];
++ __u32 ae_hist_y[128];
++ __u32 reserv2[511];
++ __u16 flag;
++};
++
+ #endif
diff --git a/target/linux/starfive/patches-6.6/0097-media-starfive-Update-ISP-initialzation.patch b/target/linux/starfive/patches-6.6/0097-media-starfive-Update-ISP-initialzation.patch
new file mode 100644
index 0000000000..b1d857e3cf
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0097-media-starfive-Update-ISP-initialzation.patch
@@ -0,0 +1,226 @@
+From 883745d4728e524babfe7d04cbb8a925c22aa6b5 Mon Sep 17 00:00:00 2001
+From: Changhuang Liang <changhuang.liang@starfivetech.com>
+Date: Mon, 13 Nov 2023 14:46:50 +0800
+Subject: [PATCH 097/116] media: starfive: Update ISP initialzation
+
+ISP compatible stf_isp_ctrl and libcamera.
+
+Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
+---
+ .../platform/starfive/v4l2_driver/stf_isp.c | 55 ++++++++-----------
+ 1 file changed, 24 insertions(+), 31 deletions(-)
+
+--- a/drivers/media/platform/starfive/v4l2_driver/stf_isp.c
++++ b/drivers/media/platform/starfive/v4l2_driver/stf_isp.c
+@@ -402,7 +402,7 @@ static int isp_set_ctrl_cfa(struct stf_i
+
+ reg_write(ispbase, reg_addr, ((u32)(cfg->cross_cov & 0x3) << 4) | (cfg->hv_width & 0xf));
+ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
+-
++
+ return 0;
+ }
+
+@@ -419,7 +419,7 @@ static int isp_set_ctrl_ctc(struct stf_i
+ reg_value |= ((u32)(cfg->max_gt & 0x3ff) << 16) | (cfg->min_gt & 0x3ff);
+ reg_write(ispbase, reg_addr, reg_value);
+ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
+-
++
+ return 0;
+ }
+
+@@ -434,7 +434,7 @@ static int isp_set_ctrl_dbc(struct stf_i
+
+ reg_write(ispbase, reg_addr, ((u32)(cfg->bad_gt & 0x3ff) << 16) | (cfg->bad_xt & 0x3ff));
+ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
+-
++
+ return 0;
+ }
+
+@@ -459,7 +459,7 @@ static int isp_set_ctrl_dnyuv(struct stf
+ reg_write(ispbase, reg_addr + 36, CREATE_REG_VALUE(u16, &cfg->uv_curve[4], 2, 0x3ff, 16));
+
+ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
+-
++
+ return 0;
+ }
+
+@@ -472,7 +472,7 @@ static int isp_set_ctrl_gmargb(struct st
+ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
+ void __iomem *ispbase = vin->isp_base;
+ s32 i;
+-
++
+ for(i = 0; i < 15; i++, curve++, reg_addr += 4)
+ reg_write(ispbase, reg_addr, ((u32)curve->sg_val << 16) | (curve->g_val & 0x3ff));
+
+@@ -490,7 +490,7 @@ static int isp_set_ctrl_lccf(struct stf_
+ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
+ void __iomem *ispbase = vin->isp_base;
+ s32 i;
+-
++
+ reg_write(ispbase, reg_addr, ((u32)(setting->circle.center_y & 0x7fff) << 16) | (setting->circle.center_x & 0x7fff));
+ reg_write(ispbase, reg_addr + 8, setting->circle.radius & 0xf);
+ reg_addr += 0x90;
+@@ -498,7 +498,7 @@ static int isp_set_ctrl_lccf(struct stf_
+ reg_write(ispbase, reg_addr, CREATE_REG_VALUE(u16, params, 2, 0x1fff, 16));
+
+ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
+-
++
+ return 0;
+ }
+
+@@ -511,7 +511,7 @@ static int isp_set_ctrl_obc(struct stf_i
+ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
+ void __iomem *ispbase = vin->isp_base;
+ s32 i;
+-
++
+ reg_write(ispbase, reg_addr, ((u32)(setting->win_size.height & 0xf) << 4) | (setting->win_size.width & 0xf));
+
+ reg_addr += 0x2ac; //0x2e0
+@@ -519,7 +519,7 @@ static int isp_set_ctrl_obc(struct stf_i
+ reg_write(ispbase, reg_addr, CREATE_REG_VALUE(u8, params, 4, 0xff, 8));
+
+ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
+-
++
+ return 0;
+ }
+
+@@ -535,7 +535,7 @@ static int isp_set_ctrl_oecf(struct stf_
+ void __iomem *ispbase = vin->isp_base;
+ u32 x, y, slope;
+ s32 i;
+-
++
+ for(i = 0; i < 32; i++, reg_x_addr += 4, reg_y_addr += 4, reg_s_addr += 4) {
+ x = pts->x & 0x3ff;
+ y = pts->y & 0x3ff;
+@@ -565,12 +565,12 @@ static int isp_set_ctrl_r2y(struct stf_i
+ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
+ void __iomem *ispbase = vin->isp_base;
+ s32 i;
+-
++
+ for(i = 0; i < 9; i++, reg_addr += 4)
+ reg_write(ispbase, reg_addr, (u32)(params[i] & 0x1ff));
+
+ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
+-
++
+ return 0;
+ }
+
+@@ -584,7 +584,7 @@ static int isp_set_ctrl_sat(struct stf_i
+ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
+ void __iomem *ispbase = vin->isp_base;
+ s32 i;
+-
++
+ for(i = 0; i < 3; i++, reg_addr += 4, params += 2)
+ reg_write(ispbase, reg_addr, CREATE_REG_VALUE(u16, params, 2, 0xfff, 16));
+ reg_write(ispbase, reg_addr, CREATE_REG_VALUE(u16, &setting->hue_info.cos, 2, 0x3ff, 16));
+@@ -597,7 +597,7 @@ static int isp_set_ctrl_sat(struct stf_i
+ reg_write(ispbase, reg_addr, CREATE_REG_VALUE(u16, params, 2, 0x3fff, 16));
+
+ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
+-
++
+ return 0;
+ }
+
+@@ -609,7 +609,7 @@ static int isp_set_ctrl_shrp(struct stf_
+ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
+ void __iomem *ispbase = vin->isp_base;
+ s32 i;
+-
++
+ for(i = 0; i < 4; i++, reg_addr += 4)
+ reg_write(ispbase, reg_addr, ((u32)(setting->strength.diff[i] & 0x3ff) << 16) | ((u32)(setting->weight.weight[i] & 0xf) << 8));
+ FILL_ISP_REGS(u8, ispbase, reg_addr, (u8 *)(&setting->weight.weight[4]), 15 - 4, 0xf, 8);
+@@ -622,7 +622,7 @@ static int isp_set_ctrl_shrp(struct stf_
+ reg_write(ispbase, reg_addr, ((u32)(setting->pdirf & 0xf) << 28) | ((u32)(setting->ndirf & 0xf) << 24) | (setting->weight.recip_wei_sum & 0x3fffff));
+
+ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
+-
++
+ return 0;
+ }
+
+@@ -633,11 +633,11 @@ static int isp_set_ctrl_ycrv(struct stf_
+ u32 reg_addr = reg_info->cfg_reg;
+ struct stf_vin_dev *vin = isp_dev->stfcamss->vin;
+ void __iomem *ispbase = vin->isp_base;
+-
++
+ FILL_ISP_REGS(u16, ispbase, reg_addr, (u16 *)(setting->curve.y), 64, 0x3ff, 0);
+
+ reg_set_bit(ispbase, reg_info->en_reg, 1 << reg_info->en_nbit, setting->enabled ? 1 << reg_info->en_nbit : 0);
+-
++
+ return 0;
+ }
+
+@@ -661,11 +661,11 @@ static int isp_set_ctrl_sc(struct stf_is
+ reg_write(ispbase, 0xb8, ((u32)(setting->crop_config.v_start) << 16) | setting->crop_config.h_start);
+
+ // SC config1
+- reg_write(ispbase, 0xbc, ((u32)(setting->awb_config.sel) << 30) | ((u32)(setting->awb_config.awb_ps_grb_ba) << 16) |
++ reg_write(ispbase, 0xbc, ((u32)(setting->awb_config.sel) << 30) | ((u32)(setting->awb_config.awb_ps_grb_ba) << 16) |
+ ((u32)(setting->crop_config.sw_height) << 8) | setting->crop_config.sw_width);
+
+ // SC decimation config
+- reg_write(ispbase, 0xd8, ((u32)(setting->crop_config.vkeep) << 24) | ((u32)(setting->crop_config.vperiod) << 16) |
++ reg_write(ispbase, 0xd8, ((u32)(setting->crop_config.vkeep) << 24) | ((u32)(setting->crop_config.vperiod) << 16) |
+ ((u32)(setting->crop_config.hkeep) << 8) | setting->crop_config.hperiod);
+
+ // SC AWB pixel sum config
+@@ -676,7 +676,7 @@ static int isp_set_ctrl_sc(struct stf_is
+ reg_write(ispbase, 0xd4, CREATE_REG_VALUE(u16, &setting->awb_config.ws_ps_config.awb_ps_grbl, 2, 0xffff, 16));
+
+ // AF register
+- reg_write(ispbase, 0xc0,
++ reg_write(ispbase, 0xc0,
+ ((u32)(setting->af_config.es_hor_thr & 0x1ff) << 16) |
+ ((u32)(setting->af_config.es_ver_thr & 0xff) << 8) |
+ ((setting->af_config.ver_en & 0x1) << 3) |
+@@ -1217,7 +1217,7 @@ static int isp_get_interface_type(struct
+ static int isp_set_stream(struct v4l2_subdev *sd, int enable)
+ {
+ struct stf_isp_dev *isp_dev = v4l2_get_subdevdata(sd);
+- int ret = 0, interface_type;
++ int interface_type;
+ struct v4l2_mbus_framefmt *fmt;
+ struct v4l2_event src_ch = { 0 };
+
+@@ -1225,6 +1225,7 @@ static int isp_set_stream(struct v4l2_su
+ mutex_lock(&isp_dev->stream_lock);
+ if (enable) {
+ if (isp_dev->stream_count == 0) {
++ v4l2_ctrl_handler_setup(&isp_dev->ctrls.handler);
+ isp_dev->hw_ops->isp_clk_enable(isp_dev);
+ if (!user_config_isp)
+ isp_dev->hw_ops->isp_config_set(isp_dev);
+@@ -1256,15 +1257,7 @@ static int isp_set_stream(struct v4l2_su
+ exit:
+ mutex_unlock(&isp_dev->stream_lock);
+
+- mutex_lock(&isp_dev->power_lock);
+- /* restore controls */
+- if (enable && isp_dev->power_count == 1) {
+- mutex_unlock(&isp_dev->power_lock);
+- ret = v4l2_ctrl_handler_setup(&isp_dev->ctrls.handler);
+- } else
+- mutex_unlock(&isp_dev->power_lock);
+-
+- return ret;
++ return 0;
+ }
+
+ /*Try to match sensor format with sink, and then get the index as default.*/
diff --git a/target/linux/starfive/patches-6.6/0098-crypto-jh7110-Comment-RSA-algo-register.patch b/target/linux/starfive/patches-6.6/0098-crypto-jh7110-Comment-RSA-algo-register.patch
new file mode 100644
index 0000000000..ca36e5bf94
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0098-crypto-jh7110-Comment-RSA-algo-register.patch
@@ -0,0 +1,36 @@
+From 02f84ff43453b0f8dc2a1e4885e7003929349ee6 Mon Sep 17 00:00:00 2001
+From: Hal Feng <hal.feng@starfivetech.com>
+Date: Tue, 5 Mar 2024 11:00:21 +0800
+Subject: [PATCH 098/116] crypto: jh7110: Comment RSA algo register
+
+There are some issues in RSA algo, which will cause kernel crash.
+So comment RSA algo register temporarily.
+This commit should be reverted after the RSA issues are fixed.
+
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ drivers/crypto/starfive/jh7110-cryp.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+--- a/drivers/crypto/starfive/jh7110-cryp.c
++++ b/drivers/crypto/starfive/jh7110-cryp.c
+@@ -194,14 +194,14 @@ static int starfive_cryp_probe(struct pl
+ if (ret)
+ goto err_algs_hash;
+
+- ret = starfive_rsa_register_algs();
+- if (ret)
+- goto err_algs_rsa;
++// ret = starfive_rsa_register_algs();
++// if (ret)
++// goto err_algs_rsa;
+
+ return 0;
+
+-err_algs_rsa:
+- starfive_hash_unregister_algs();
++// err_algs_rsa:
++// starfive_hash_unregister_algs();
+ err_algs_hash:
+ starfive_aes_unregister_algs();
+ err_algs_aes:
diff --git a/target/linux/starfive/patches-6.6/0099-riscv-dts-starfive-jh7110-evb-Add-qspi-norflash-part.patch b/target/linux/starfive/patches-6.6/0099-riscv-dts-starfive-jh7110-evb-Add-qspi-norflash-part.patch
new file mode 100644
index 0000000000..d04b082d68
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0099-riscv-dts-starfive-jh7110-evb-Add-qspi-norflash-part.patch
@@ -0,0 +1,26 @@
+From a7ff2b51e2941526d6924dcf8f1760187d7e5d03 Mon Sep 17 00:00:00 2001
+From: Hal Feng <hal.feng@starfivetech.com>
+Date: Mon, 11 Mar 2024 11:10:45 +0800
+Subject: [PATCH 099/116] riscv: dts: starfive: jh7110-evb: Add qspi norflash
+ partition for uboot-env
+
+Add qspi norflash partition "uboot-env@f0000",
+for synchronizing with other branches.
+
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ arch/riscv/boot/dts/starfive/jh7110-evb.dtsi | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/arch/riscv/boot/dts/starfive/jh7110-evb.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7110-evb.dtsi
+@@ -568,6 +568,9 @@
+ spl@0 {
+ reg = <0x0 0x40000>;
+ };
++ uboot-env@f0000 {
++ reg = <0xf0000 0x10000>;
++ };
+ uboot@100000 {
+ reg = <0x100000 0x300000>;
+ };
diff --git a/target/linux/starfive/patches-6.6/0100-driver-regulator-pmic-driver-support-kernel-6.6.patch b/target/linux/starfive/patches-6.6/0100-driver-regulator-pmic-driver-support-kernel-6.6.patch
new file mode 100644
index 0000000000..ad8b98d17b
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0100-driver-regulator-pmic-driver-support-kernel-6.6.patch
@@ -0,0 +1,22 @@
+From f96ba2eb39ba950f67edf43e0c5c88ac660bc2a0 Mon Sep 17 00:00:00 2001
+From: Ziv Xu <ziv.xu@starfivetech.com>
+Date: Wed, 13 Mar 2024 18:43:27 +0800
+Subject: [PATCH 100/116] driver: regulator: pmic driver support kernel 6.6
+
+pmic driver support kernel 6.6
+
+Signed-off-by: Ziv Xu <ziv.xu@starfivetech.com>
+---
+ drivers/regulator/axp20x-regulator.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/regulator/axp20x-regulator.c
++++ b/drivers/regulator/axp20x-regulator.c
+@@ -20,6 +20,7 @@
+ #include <linux/mfd/axp20x.h>
+ #include <linux/module.h>
+ #include <linux/of.h>
++#include <linux/of_device.h>
+ #include <linux/platform_device.h>
+ #include <linux/regmap.h>
+ #include <linux/regulator/driver.h>
diff --git a/target/linux/starfive/patches-6.6/0101-spi-pl022-starfive-Add-platform-bus-register-to-adap.patch b/target/linux/starfive/patches-6.6/0101-spi-pl022-starfive-Add-platform-bus-register-to-adap.patch
new file mode 100644
index 0000000000..8112243bc7
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0101-spi-pl022-starfive-Add-platform-bus-register-to-adap.patch
@@ -0,0 +1,232 @@
+From c609818850807a1ae5fa17e165f2b66b914188b4 Mon Sep 17 00:00:00 2001
+From: "xingyu.wu" <xingyu.wu@starfivetech.com>
+Date: Tue, 28 Jun 2022 22:48:15 +0800
+Subject: [PATCH 101/116] spi-pl022:starfive:Add platform bus register to adapt
+ overlay
+
+Add platform bus register to adapt dtbo overlay.
+
+Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ drivers/spi/spi-pl022.c | 137 ++++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 131 insertions(+), 6 deletions(-)
+
+--- a/drivers/spi/spi-pl022.c
++++ b/drivers/spi/spi-pl022.c
+@@ -34,6 +34,7 @@
+ #include <linux/of.h>
+ #include <linux/pinctrl/consumer.h>
+ #include <linux/reset.h>
++#include <linux/platform_device.h>
+
+ /*
+ * This macro is used to define some register default values.
+@@ -2088,7 +2089,10 @@ pl022_platform_data_dt_get(struct device
+ return NULL;
+ }
+
+- pd = devm_kzalloc(dev, sizeof(struct pl022_ssp_controller), GFP_KERNEL);
++ if (strncmp(dev->bus->name, "platform", strlen("platform")))
++ pd = devm_kzalloc(dev, sizeof(struct pl022_ssp_controller), GFP_KERNEL);
++ else
++ pd = kzalloc(sizeof(struct pl022_ssp_controller), GFP_KERNEL);
+ if (!pd)
+ return NULL;
+
+@@ -2108,6 +2112,14 @@ static int pl022_probe(struct amba_devic
+ struct spi_controller *host;
+ struct pl022 *pl022 = NULL; /*Data for this driver */
+ int status = 0;
++ int platform_flag = 0;
++
++ if (strncmp(dev->bus->name, "platform", strlen("platform")))
++ platform_flag = 0;
++ else
++ platform_flag = 1;
++ dev_dbg(&adev->dev, "bus name:%s platform flag:%d",
++ dev->bus->name, platform_flag);
+
+ dev_info(&adev->dev,
+ "ARM PL022 driver, device ID: 0x%08x\n", adev->periphid);
+@@ -2161,7 +2173,11 @@ static int pl022_probe(struct amba_devic
+ goto err_no_ioregion;
+
+ pl022->phybase = adev->res.start;
+- pl022->virtbase = devm_ioremap(dev, adev->res.start,
++ if (platform_flag)
++ pl022->virtbase = ioremap(adev->res.start,
++ resource_size(&adev->res));
++ else
++ pl022->virtbase = devm_ioremap(dev, adev->res.start,
+ resource_size(&adev->res));
+ if (pl022->virtbase == NULL) {
+ status = -ENOMEM;
+@@ -2170,7 +2186,10 @@ static int pl022_probe(struct amba_devic
+ dev_info(&adev->dev, "mapped registers from %pa to %p\n",
+ &adev->res.start, pl022->virtbase);
+
+- pl022->clk = devm_clk_get(&adev->dev, NULL);
++ if (platform_flag)
++ pl022->clk = clk_get(&adev->dev, NULL);
++ else
++ pl022->clk = devm_clk_get(&adev->dev, NULL);
+ if (IS_ERR(pl022->clk)) {
+ status = PTR_ERR(pl022->clk);
+ dev_err(&adev->dev, "could not retrieve SSP/SPI bus clock\n");
+@@ -2183,7 +2202,10 @@ static int pl022_probe(struct amba_devic
+ goto err_no_clk_en;
+ }
+
+- pl022->rst = devm_reset_control_get(&adev->dev, NULL);
++ if (platform_flag)
++ pl022->rst = reset_control_get_exclusive(&adev->dev, NULL);
++ else
++ pl022->rst = devm_reset_control_get(&adev->dev, NULL);
+ if (IS_ERR(pl022->rst)) {
+ status = PTR_ERR(pl022->rst);
+ dev_err(&adev->dev, "could not retrieve SSP/SPI bus reset\n");
+@@ -2205,7 +2227,11 @@ static int pl022_probe(struct amba_devic
+ SSP_CR1(pl022->virtbase));
+ load_ssp_default_config(pl022);
+
+- status = devm_request_irq(dev, adev->irq[0], pl022_interrupt_handler,
++ if (platform_flag)
++ status = request_irq(adev->irq[0], pl022_interrupt_handler,
++ 0, "pl022", pl022);
++ else
++ status = devm_request_irq(dev, adev->irq[0], pl022_interrupt_handler,
+ 0, "pl022", pl022);
+ if (status < 0) {
+ dev_err(&adev->dev, "probe - cannot get IRQ (%d)\n", status);
+@@ -2230,7 +2256,10 @@ static int pl022_probe(struct amba_devic
+
+ /* Register with the SPI framework */
+ amba_set_drvdata(adev, pl022);
+- status = devm_spi_register_controller(&adev->dev, host);
++ if (platform_flag)
++ status = spi_register_controller(host);
++ else
++ status = devm_spi_register_controller(&adev->dev, host);
+ if (status != 0) {
+ dev_err_probe(&adev->dev, status,
+ "problem registering spi host\n");
+@@ -2255,15 +2284,26 @@ static int pl022_probe(struct amba_devic
+ if (platform_info->enable_dma)
+ pl022_dma_remove(pl022);
+ err_no_irq:
++ if (platform_flag)
++ free_irq(adev->irq[0], pl022);
++ reset_control_assert(pl022->rst);
+ err_no_rst_de:
++ if (platform_flag)
++ reset_control_put(pl022->rst);
+ err_no_rst:
+ clk_disable_unprepare(pl022->clk);
+ err_no_clk_en:
++ if (platform_flag)
++ clk_put(pl022->clk);
+ err_no_clk:
++ if (platform_flag)
++ iounmap(pl022->virtbase);
+ err_no_ioremap:
+ amba_release_regions(adev);
+ err_no_ioregion:
+ spi_controller_put(host);
++ if (platform_flag)
++ kfree(platform_info);
+ return status;
+ }
+
+@@ -2464,6 +2504,91 @@ static void __exit pl022_exit(void)
+ }
+ module_exit(pl022_exit);
+
++/*
++ * Register PL022 in platform bus to accommodate overlay use.
++ * Because overlay only trigger response from the platform bus
++ * not amba bus.
++ */
++static int starfive_of_pl022_probe(struct platform_device *pdev)
++{
++ int ret;
++ const struct amba_id id = {
++ .id = 0x00041022,
++ .mask = 0x000fffff,
++ .data = &vendor_arm
++ };
++ struct amba_device *pcdev;
++ struct device *dev = &pdev->dev;
++
++ pcdev = devm_kzalloc(&pdev->dev, sizeof(*pcdev), GFP_KERNEL);
++ if (!pcdev)
++ return -ENOMEM;
++
++ pcdev->dev = pdev->dev;
++ pcdev->periphid = id.id;
++ pcdev->res = *(pdev->resource);
++
++ pcdev->irq[0] = platform_get_irq(pdev, 0);
++ if (pcdev->irq[0] < 0) {
++ dev_err(dev, "failed to get irq\n");
++ ret = -EINVAL;
++ }
++
++ ret = pl022_probe(pcdev, &id);
++
++ return ret;
++}
++
++static int starfive_of_pl022_remove(struct platform_device *pdev)
++{
++ u32 size;
++ int irq;
++ struct pl022 *pl022 = dev_get_drvdata(&pdev->dev);
++
++ if (!pl022)
++ return 0;
++
++ pm_runtime_get_noresume(&pdev->dev);
++
++ load_ssp_default_config(pl022);
++ if (pl022->host_info->enable_dma)
++ pl022_dma_remove(pl022);
++
++ irq = platform_get_irq(pdev, 0);
++ free_irq(irq, pl022);
++ reset_control_assert(pl022->rst);
++ reset_control_put(pl022->rst);
++ clk_disable_unprepare(pl022->clk);
++ clk_put(pl022->clk);
++ iounmap(pl022->virtbase);
++ kfree(pl022->host_info);
++
++ size = resource_size(pdev->resource);
++ release_mem_region(pdev->resource->start, size);
++ tasklet_disable(&pl022->pump_transfers);
++ return 0;
++}
++
++static const struct of_device_id starfive_of_pl022_match[] = {
++ { .compatible = "starfive,jh7110-spi-pl022" },
++ { },
++};
++MODULE_DEVICE_TABLE(of, starfive_of_pl022_match);
++
++static struct platform_driver starfive_of_pl022_driver = {
++ .driver = {
++ .name = "starfive-spi-pl022",
++ .of_match_table = starfive_of_pl022_match,
++ .pm = &pl022_dev_pm_ops,
++ },
++ .probe = starfive_of_pl022_probe,
++ .remove = starfive_of_pl022_remove,
++};
++
++module_platform_driver(starfive_of_pl022_driver);
++/* platform register end */
++
++MODULE_AUTHOR("xingyu.wu <xingyu.wu@starfivetech.com>");
+ MODULE_AUTHOR("Linus Walleij <linus.walleij@stericsson.com>");
+ MODULE_DESCRIPTION("PL022 SSP Controller Driver");
+ MODULE_LICENSE("GPL");
diff --git a/target/linux/starfive/patches-6.6/0102-spi-pl022-starfive-Avoid-power-device-error-when-CON.patch b/target/linux/starfive/patches-6.6/0102-spi-pl022-starfive-Avoid-power-device-error-when-CON.patch
new file mode 100644
index 0000000000..bd4709f01d
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0102-spi-pl022-starfive-Avoid-power-device-error-when-CON.patch
@@ -0,0 +1,92 @@
+From f94a07310f18720faa0cc773a1aec5a7b1bf3928 Mon Sep 17 00:00:00 2001
+From: "xingyu.wu" <xingyu.wu@starfivetech.com>
+Date: Tue, 19 Jul 2022 14:49:20 +0800
+Subject: [PATCH 102/116] spi:pl022-starfive:Avoid power device error when
+ CONFIG_PM enable
+
+It would be error when CONFIG_PM enable and use overlay by of-platform to register.
+
+Add some power manager operation in platform probe function.
+
+Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
+Signed-off-by: Ziv Xu <ziv.xu@starfivetech.com>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ drivers/spi/spi-pl022.c | 36 ++++++++++++++++++++++++++++++++++--
+ 1 file changed, 34 insertions(+), 2 deletions(-)
+
+--- a/drivers/spi/spi-pl022.c
++++ b/drivers/spi/spi-pl022.c
+@@ -35,6 +35,8 @@
+ #include <linux/pinctrl/consumer.h>
+ #include <linux/reset.h>
+ #include <linux/platform_device.h>
++#include <linux/clk/clk-conf.h>
++#include <linux/pm_domain.h>
+
+ /*
+ * This macro is used to define some register default values.
+@@ -2266,7 +2268,8 @@ static int pl022_probe(struct amba_devic
+ goto err_spi_register;
+ }
+ dev_dbg(dev, "probe succeeded\n");
+-
++ if (!platform_flag)
++ platform_info->autosuspend_delay = 100;
+ /* let runtime pm put suspend */
+ if (platform_info->autosuspend_delay > 0) {
+ dev_info(&adev->dev,
+@@ -2276,7 +2279,10 @@ static int pl022_probe(struct amba_devic
+ platform_info->autosuspend_delay);
+ pm_runtime_use_autosuspend(dev);
+ }
+- pm_runtime_put(dev);
++ if (platform_flag)
++ clk_disable_unprepare(pl022->clk);
++ else
++ pm_runtime_put(dev);
+
+ return 0;
+
+@@ -2534,8 +2540,33 @@ static int starfive_of_pl022_probe(struc
+ ret = -EINVAL;
+ }
+
++ ret = of_clk_set_defaults(dev->of_node, false);
++ if (ret < 0)
++ goto err_probe;
++
++ ret = dev_pm_domain_attach(dev, true);
++ if (ret)
++ goto err_probe;
++
+ ret = pl022_probe(pcdev, &id);
+
++ struct pl022 *pl022 = amba_get_drvdata(pcdev);
++
++ pl022->host->dev.parent = &pdev->dev;
++ platform_set_drvdata(pdev, pl022);
++
++ pm_runtime_enable(&pdev->dev);
++ pm_runtime_set_autosuspend_delay(&pdev->dev, 100);
++ pm_runtime_use_autosuspend(&pdev->dev);
++
++ if (ret) {
++ pm_runtime_disable(dev);
++ pm_runtime_set_suspended(dev);
++ pm_runtime_put_noidle(dev);
++ dev_pm_domain_detach(dev, true);
++ }
++
++err_probe:
+ return ret;
+ }
+
+@@ -2566,6 +2597,7 @@ static int starfive_of_pl022_remove(stru
+ size = resource_size(pdev->resource);
+ release_mem_region(pdev->resource->start, size);
+ tasklet_disable(&pl022->pump_transfers);
++ pm_runtime_disable(&pdev->dev);
+ return 0;
+ }
+
diff --git a/target/linux/starfive/patches-6.6/0103-spi-pl022-starfive-fix-the-problem-of-spi-overlay-re.patch b/target/linux/starfive/patches-6.6/0103-spi-pl022-starfive-fix-the-problem-of-spi-overlay-re.patch
new file mode 100644
index 0000000000..3e36e84641
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0103-spi-pl022-starfive-fix-the-problem-of-spi-overlay-re.patch
@@ -0,0 +1,403 @@
+From 733e7bd23a1efad15a724fbdbce8d9f06aa6813a Mon Sep 17 00:00:00 2001
+From: "ziv.xu" <ziv.xu@starfive.com>
+Date: Wed, 23 Nov 2022 14:53:58 +0800
+Subject: [PATCH 103/116] spi-pl022-starfive:fix the problem of spi overlay
+ reload
+
+fix the problem of spi overlay reload
+
+Signed-off-by: ziv.xu <ziv.xu@starfive.com>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ drivers/spi/spi-pl022.c | 270 ++++++++++++++++++++++++++++------------
+ 1 file changed, 188 insertions(+), 82 deletions(-)
+
+--- a/drivers/spi/spi-pl022.c
++++ b/drivers/spi/spi-pl022.c
+@@ -2106,6 +2106,172 @@ pl022_platform_data_dt_get(struct device
+ return pd;
+ }
+
++static int pl022_platform_probe(struct platform_device *pdev, const struct amba_id *id)
++{
++ struct device *dev = &pdev->dev;
++ struct spi_controller *host;
++ struct pl022_ssp_controller *platform_info;
++ struct amba_device *adev;
++ struct pl022 *pl022 = NULL;
++ struct resource *res;
++ int status = 0;
++ int irq;
++
++ dev_info(dev,
++ "ARM PL022 driver for StarFive SoC platform, device ID: 0x%08x\n",
++ id->id);
++
++ adev = devm_kzalloc(dev, sizeof(*adev), GFP_KERNEL);
++ adev->dev = pdev->dev;
++ platform_info = pl022_platform_data_dt_get(dev);
++ if (!platform_info) {
++ dev_err(dev, "probe: no platform data defined\n");
++ return -ENODEV;
++ }
++ /* Allocate host with space for data */
++ host = spi_alloc_host(dev, sizeof(struct pl022));
++ if (host == NULL) {
++ dev_err(dev, "probe - cannot alloc SPI host\n");
++ return -ENOMEM;
++ }
++
++ pl022 = spi_controller_get_devdata(host);
++ pl022->host = host;
++ pl022->host_info = platform_info;
++ pl022->adev = adev;
++ pl022->vendor = id->data;
++ pl022->host->dev.parent = &pdev->dev;
++ /*
++ * Bus Number Which has been Assigned to this SSP controller
++ * on this board
++ */
++ host->bus_num = platform_info->bus_id;
++ host->cleanup = pl022_cleanup;
++ host->setup = pl022_setup;
++ /* If open CONFIG_PM, auto_runtime_pm should be false when of-platform.*/
++ host->auto_runtime_pm = true;
++ host->transfer_one_message = pl022_transfer_one_message;
++ host->unprepare_transfer_hardware = pl022_unprepare_transfer_hardware;
++ host->rt = platform_info->rt;
++ host->dev.of_node = dev->of_node;
++ host->use_gpio_descriptors = true;
++
++ /*
++ * Supports mode 0-3, loopback, and active low CS. Transfers are
++ * always MS bit first on the original pl022.
++ */
++ host->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LOOP;
++ if (pl022->vendor->extended_cr)
++ host->mode_bits |= SPI_LSB_FIRST;
++
++ dev_dbg(dev, "BUSNO: %d\n", host->bus_num);
++
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ pl022->phybase = res->start;
++ pl022->virtbase = devm_ioremap_resource(dev, res);
++ if (pl022->virtbase == NULL) {
++ status = -ENOMEM;
++ goto err_no_ioremap;
++ }
++ dev_info(dev, "mapped registers from %llx to %llx\n",
++ pdev->resource->start, pdev->resource->end);
++
++ pl022->clk = devm_clk_get(dev, NULL);
++ if (IS_ERR(pl022->clk)) {
++ status = PTR_ERR(pl022->clk);
++ dev_err(dev, "could not retrieve SSP/SPI bus clock\n");
++ goto err_no_clk;
++ }
++ status = clk_prepare_enable(pl022->clk);
++ if (status) {
++ dev_err(dev, "could not enable SSP/SPI bus clock\n");
++ goto err_no_clk_en;
++ }
++
++ pl022->rst = devm_reset_control_get_exclusive(dev, NULL);
++ if (!IS_ERR(pl022->rst)) {
++ status = reset_control_deassert(pl022->rst);
++ if (status) {
++ dev_err(dev, "could not deassert SSP/SPI bus reset\n");
++ goto err_no_rst_clr;
++ }
++ } else {
++ status = PTR_ERR(pl022->rst);
++ dev_err(dev, "could not retrieve SSP/SPI bus reset\n");
++ goto err_no_rst;
++ }
++
++ /* Initialize transfer pump */
++ tasklet_init(&pl022->pump_transfers, pump_transfers,
++ (unsigned long)pl022);
++
++ /* Disable SSP */
++ writew((readw(SSP_CR1(pl022->virtbase)) & (~SSP_CR1_MASK_SSE)),
++ SSP_CR1(pl022->virtbase));
++ load_ssp_default_config(pl022);
++
++ /* Obtain IRQ line. */
++ irq = platform_get_irq(pdev, 0);
++ if (irq < 0) {
++ status = -ENXIO;
++ goto err_no_irq;
++ }
++ status = devm_request_irq(dev, irq, pl022_interrupt_handler,
++ 0, "pl022", pl022);
++ if (status < 0) {
++ dev_err(dev, "probe - cannot get IRQ (%d)\n", status);
++ goto err_no_irq;
++ }
++
++ /* Get DMA channels, try autoconfiguration first */
++ status = pl022_dma_autoprobe(pl022);
++ if (status == -EPROBE_DEFER) {
++ dev_dbg(dev, "deferring probe to get DMA channel\n");
++ goto err_no_irq;
++ }
++
++ /* dma is not used unless configured in the device tree */
++ platform_info->enable_dma = 0;
++
++ /* If that failed, use channels from platform_info */
++ if (status == 0)
++ platform_info->enable_dma = 1;
++ else if (platform_info->enable_dma) {
++ status = pl022_dma_probe(pl022);
++ if (status != 0)
++ platform_info->enable_dma = 0;
++ }
++
++ /* Register with the SPI framework */
++ dev_set_drvdata(dev, pl022);
++
++ status = devm_spi_register_controller(dev, host);
++ if (status != 0) {
++ dev_err(dev,
++ "probe - problem registering spi host\n");
++ goto err_spi_register;
++ }
++ dev_dbg(dev, "probe succeeded\n");
++
++ clk_disable_unprepare(pl022->clk);
++
++ return 0;
++ err_spi_register:
++ if (platform_info->enable_dma)
++ pl022_dma_remove(pl022);
++ err_no_irq:
++ reset_control_assert(pl022->rst);
++ err_no_rst_clr:
++ err_no_rst:
++ clk_disable_unprepare(pl022->clk);
++ err_no_clk_en:
++ err_no_clk:
++ err_no_ioremap:
++ release_mem_region(pdev->resource->start, resource_size(pdev->resource));
++ spi_controller_put(host);
++ return status;
++}
++
+ static int pl022_probe(struct amba_device *adev, const struct amba_id *id)
+ {
+ struct device *dev = &adev->dev;
+@@ -2114,14 +2280,6 @@ static int pl022_probe(struct amba_devic
+ struct spi_controller *host;
+ struct pl022 *pl022 = NULL; /*Data for this driver */
+ int status = 0;
+- int platform_flag = 0;
+-
+- if (strncmp(dev->bus->name, "platform", strlen("platform")))
+- platform_flag = 0;
+- else
+- platform_flag = 1;
+- dev_dbg(&adev->dev, "bus name:%s platform flag:%d",
+- dev->bus->name, platform_flag);
+
+ dev_info(&adev->dev,
+ "ARM PL022 driver, device ID: 0x%08x\n", adev->periphid);
+@@ -2175,11 +2333,7 @@ static int pl022_probe(struct amba_devic
+ goto err_no_ioregion;
+
+ pl022->phybase = adev->res.start;
+- if (platform_flag)
+- pl022->virtbase = ioremap(adev->res.start,
+- resource_size(&adev->res));
+- else
+- pl022->virtbase = devm_ioremap(dev, adev->res.start,
++ pl022->virtbase = devm_ioremap(dev, adev->res.start,
+ resource_size(&adev->res));
+ if (pl022->virtbase == NULL) {
+ status = -ENOMEM;
+@@ -2188,10 +2342,7 @@ static int pl022_probe(struct amba_devic
+ dev_info(&adev->dev, "mapped registers from %pa to %p\n",
+ &adev->res.start, pl022->virtbase);
+
+- if (platform_flag)
+- pl022->clk = clk_get(&adev->dev, NULL);
+- else
+- pl022->clk = devm_clk_get(&adev->dev, NULL);
++ pl022->clk = devm_clk_get(&adev->dev, NULL);
+ if (IS_ERR(pl022->clk)) {
+ status = PTR_ERR(pl022->clk);
+ dev_err(&adev->dev, "could not retrieve SSP/SPI bus clock\n");
+@@ -2204,10 +2355,7 @@ static int pl022_probe(struct amba_devic
+ goto err_no_clk_en;
+ }
+
+- if (platform_flag)
+- pl022->rst = reset_control_get_exclusive(&adev->dev, NULL);
+- else
+- pl022->rst = devm_reset_control_get(&adev->dev, NULL);
++ pl022->rst = devm_reset_control_get(&adev->dev, NULL);
+ if (IS_ERR(pl022->rst)) {
+ status = PTR_ERR(pl022->rst);
+ dev_err(&adev->dev, "could not retrieve SSP/SPI bus reset\n");
+@@ -2229,11 +2377,7 @@ static int pl022_probe(struct amba_devic
+ SSP_CR1(pl022->virtbase));
+ load_ssp_default_config(pl022);
+
+- if (platform_flag)
+- status = request_irq(adev->irq[0], pl022_interrupt_handler,
+- 0, "pl022", pl022);
+- else
+- status = devm_request_irq(dev, adev->irq[0], pl022_interrupt_handler,
++ status = devm_request_irq(dev, adev->irq[0], pl022_interrupt_handler,
+ 0, "pl022", pl022);
+ if (status < 0) {
+ dev_err(&adev->dev, "probe - cannot get IRQ (%d)\n", status);
+@@ -2258,18 +2402,16 @@ static int pl022_probe(struct amba_devic
+
+ /* Register with the SPI framework */
+ amba_set_drvdata(adev, pl022);
+- if (platform_flag)
+- status = spi_register_controller(host);
+- else
+- status = devm_spi_register_controller(&adev->dev, host);
++
++ status = devm_spi_register_controller(&adev->dev, host);
+ if (status != 0) {
+ dev_err_probe(&adev->dev, status,
+ "problem registering spi host\n");
+ goto err_spi_register;
+ }
+ dev_dbg(dev, "probe succeeded\n");
+- if (!platform_flag)
+- platform_info->autosuspend_delay = 100;
++
++ platform_info->autosuspend_delay = 100;
+ /* let runtime pm put suspend */
+ if (platform_info->autosuspend_delay > 0) {
+ dev_info(&adev->dev,
+@@ -2279,10 +2421,8 @@ static int pl022_probe(struct amba_devic
+ platform_info->autosuspend_delay);
+ pm_runtime_use_autosuspend(dev);
+ }
+- if (platform_flag)
+- clk_disable_unprepare(pl022->clk);
+- else
+- pm_runtime_put(dev);
++
++ pm_runtime_put(dev);
+
+ return 0;
+
+@@ -2290,26 +2430,17 @@ static int pl022_probe(struct amba_devic
+ if (platform_info->enable_dma)
+ pl022_dma_remove(pl022);
+ err_no_irq:
+- if (platform_flag)
+- free_irq(adev->irq[0], pl022);
+ reset_control_assert(pl022->rst);
+ err_no_rst_de:
+- if (platform_flag)
+- reset_control_put(pl022->rst);
+ err_no_rst:
+ clk_disable_unprepare(pl022->clk);
+ err_no_clk_en:
+- if (platform_flag)
+- clk_put(pl022->clk);
+ err_no_clk:
+- if (platform_flag)
+- iounmap(pl022->virtbase);
+ err_no_ioremap:
+ amba_release_regions(adev);
+ err_no_ioregion:
+ spi_controller_put(host);
+- if (platform_flag)
+- kfree(platform_info);
++
+ return status;
+ }
+
+@@ -2523,23 +2654,8 @@ static int starfive_of_pl022_probe(struc
+ .mask = 0x000fffff,
+ .data = &vendor_arm
+ };
+- struct amba_device *pcdev;
+ struct device *dev = &pdev->dev;
+
+- pcdev = devm_kzalloc(&pdev->dev, sizeof(*pcdev), GFP_KERNEL);
+- if (!pcdev)
+- return -ENOMEM;
+-
+- pcdev->dev = pdev->dev;
+- pcdev->periphid = id.id;
+- pcdev->res = *(pdev->resource);
+-
+- pcdev->irq[0] = platform_get_irq(pdev, 0);
+- if (pcdev->irq[0] < 0) {
+- dev_err(dev, "failed to get irq\n");
+- ret = -EINVAL;
+- }
+-
+ ret = of_clk_set_defaults(dev->of_node, false);
+ if (ret < 0)
+ goto err_probe;
+@@ -2548,16 +2664,11 @@ static int starfive_of_pl022_probe(struc
+ if (ret)
+ goto err_probe;
+
+- ret = pl022_probe(pcdev, &id);
++ ret = pl022_platform_probe(pdev, &id);
+
+- struct pl022 *pl022 = amba_get_drvdata(pcdev);
+-
+- pl022->host->dev.parent = &pdev->dev;
+- platform_set_drvdata(pdev, pl022);
+-
+- pm_runtime_enable(&pdev->dev);
+- pm_runtime_set_autosuspend_delay(&pdev->dev, 100);
+- pm_runtime_use_autosuspend(&pdev->dev);
++ pm_runtime_enable(dev);
++ pm_runtime_set_autosuspend_delay(dev, 100);
++ pm_runtime_use_autosuspend(dev);
+
+ if (ret) {
+ pm_runtime_disable(dev);
+@@ -2572,32 +2683,27 @@ err_probe:
+
+ static int starfive_of_pl022_remove(struct platform_device *pdev)
+ {
+- u32 size;
+- int irq;
+ struct pl022 *pl022 = dev_get_drvdata(&pdev->dev);
+
+ if (!pl022)
+ return 0;
+
++ pm_runtime_get_sync(&pdev->dev);
+ pm_runtime_get_noresume(&pdev->dev);
+
+ load_ssp_default_config(pl022);
+ if (pl022->host_info->enable_dma)
+ pl022_dma_remove(pl022);
+
+- irq = platform_get_irq(pdev, 0);
+- free_irq(irq, pl022);
+- reset_control_assert(pl022->rst);
+- reset_control_put(pl022->rst);
+ clk_disable_unprepare(pl022->clk);
+- clk_put(pl022->clk);
+- iounmap(pl022->virtbase);
+- kfree(pl022->host_info);
+-
+- size = resource_size(pdev->resource);
+- release_mem_region(pdev->resource->start, size);
+ tasklet_disable(&pl022->pump_transfers);
++
++ pm_runtime_put_noidle(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
++ pm_runtime_set_suspended(&pdev->dev);
++ pm_runtime_put_noidle(&pdev->dev);
++ dev_pm_domain_detach(&pdev->dev, true);
++
+ return 0;
+ }
+
diff --git a/target/linux/starfive/patches-6.6/0104-spi-pl022-starfive-Enable-spi-to-be-compiled-into-mo.patch b/target/linux/starfive/patches-6.6/0104-spi-pl022-starfive-Enable-spi-to-be-compiled-into-mo.patch
new file mode 100644
index 0000000000..aecce737d9
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0104-spi-pl022-starfive-Enable-spi-to-be-compiled-into-mo.patch
@@ -0,0 +1,38 @@
+From 11a917bf429a5714e34584f90ab1ac376d399d8f Mon Sep 17 00:00:00 2001
+From: "ziv.xu" <ziv.xu@starfive.com>
+Date: Wed, 18 Jan 2023 15:50:47 +0800
+Subject: [PATCH 104/116] spi-pl022-starfive:Enable spi to be compiled into
+ modules
+
+Enable spi to be compiled into modules
+
+Signed-off-by: ziv.xu <ziv.xu@starfive.com>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ drivers/spi/spi-pl022.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/spi/spi-pl022.c
++++ b/drivers/spi/spi-pl022.c
+@@ -2633,7 +2633,11 @@ static int __init pl022_init(void)
+ {
+ return amba_driver_register(&pl022_driver);
+ }
++#if !IS_MODULE(CONFIG_SPI_PL022)
+ subsys_initcall(pl022_init);
++#else
++module_init(pl022_init);
++#endif
+
+ static void __exit pl022_exit(void)
+ {
+@@ -2723,7 +2727,9 @@ static struct platform_driver starfive_o
+ .remove = starfive_of_pl022_remove,
+ };
+
++#if !IS_MODULE(CONFIG_SPI_PL022)
+ module_platform_driver(starfive_of_pl022_driver);
++#endif
+ /* platform register end */
+
+ MODULE_AUTHOR("xingyu.wu <xingyu.wu@starfivetech.com>");
diff --git a/target/linux/starfive/patches-6.6/0105-riscv-configs-add-visionfive2-defconfig-to-kernel-6..patch b/target/linux/starfive/patches-6.6/0105-riscv-configs-add-visionfive2-defconfig-to-kernel-6..patch
new file mode 100644
index 0000000000..bc1d836c11
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0105-riscv-configs-add-visionfive2-defconfig-to-kernel-6..patch
@@ -0,0 +1,444 @@
+From e7b01c0a9ad79c1933ce85c4aeca6a037cc4f77f Mon Sep 17 00:00:00 2001
+From: Ziv Xu <ziv.xu@starfivetech.com>
+Date: Wed, 13 Mar 2024 18:37:31 +0800
+Subject: [PATCH 105/116] riscv: configs: add visionfive2 defconfig to kernel
+ 6.6
+
+add visionfive2 defconfig to kernel 6.6
+
+Signed-off-by: Ziv Xu <ziv.xu@starfivetech.com>
+---
+ .../configs/starfive_visionfive2_defconfig | 427 ++++++++++++++++++
+ 1 file changed, 427 insertions(+)
+ create mode 100644 arch/riscv/configs/starfive_visionfive2_defconfig
+
+--- /dev/null
++++ b/arch/riscv/configs/starfive_visionfive2_defconfig
+@@ -0,0 +1,427 @@
++CONFIG_COMPILE_TEST=y
++# CONFIG_WERROR is not set
++CONFIG_DEFAULT_HOSTNAME="StarFive"
++CONFIG_SYSVIPC=y
++CONFIG_POSIX_MQUEUE=y
++CONFIG_USELIB=y
++CONFIG_NO_HZ_IDLE=y
++CONFIG_HIGH_RES_TIMERS=y
++CONFIG_BPF_SYSCALL=y
++CONFIG_IKCONFIG=y
++CONFIG_IKCONFIG_PROC=y
++CONFIG_CGROUPS=y
++CONFIG_CGROUP_SCHED=y
++CONFIG_CFS_BANDWIDTH=y
++CONFIG_CGROUP_BPF=y
++CONFIG_NAMESPACES=y
++CONFIG_USER_NS=y
++CONFIG_CHECKPOINT_RESTORE=y
++CONFIG_BLK_DEV_INITRD=y
++CONFIG_EXPERT=y
++CONFIG_PERF_EVENTS=y
++CONFIG_SOC_STARFIVE=y
++CONFIG_NONPORTABLE=y
++CONFIG_SMP=y
++CONFIG_HZ_100=y
++CONFIG_HIBERNATION=y
++CONFIG_PM_DEBUG=y
++CONFIG_PM_ADVANCED_DEBUG=y
++CONFIG_PM_TEST_SUSPEND=y
++CONFIG_CPU_IDLE=y
++CONFIG_RISCV_SBI_CPUIDLE=y
++CONFIG_CPU_FREQ=y
++CONFIG_CPU_FREQ_STAT=y
++CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
++CONFIG_CPU_FREQ_GOV_POWERSAVE=y
++CONFIG_CPU_FREQ_GOV_USERSPACE=y
++CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
++CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
++CONFIG_CPUFREQ_DT=y
++# CONFIG_SECCOMP is not set
++CONFIG_MODULES=y
++CONFIG_MODULE_UNLOAD=y
++CONFIG_BINFMT_MISC=y
++CONFIG_PAGE_REPORTING=y
++CONFIG_CMA=y
++CONFIG_NET=y
++CONFIG_PACKET=y
++CONFIG_IP_MULTICAST=y
++CONFIG_IP_ADVANCED_ROUTER=y
++CONFIG_IP_PNP=y
++CONFIG_IP_PNP_DHCP=y
++CONFIG_IP_PNP_BOOTP=y
++CONFIG_IP_PNP_RARP=y
++CONFIG_NETFILTER=y
++CONFIG_NETFILTER_NETLINK_ACCT=y
++CONFIG_NETFILTER_NETLINK_QUEUE=y
++CONFIG_NF_CONNTRACK=y
++CONFIG_NF_TABLES=y
++CONFIG_NFT_CT=y
++CONFIG_NFT_COMPAT=y
++CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
++CONFIG_NETFILTER_XT_MATCH_IPCOMP=y
++CONFIG_NETFILTER_XT_MATCH_IPRANGE=y
++CONFIG_NETFILTER_XT_MATCH_MAC=y
++CONFIG_NETFILTER_XT_MATCH_MARK=y
++CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y
++CONFIG_NETFILTER_XT_MATCH_SOCKET=y
++CONFIG_NETFILTER_XT_MATCH_STATE=y
++CONFIG_NETFILTER_XT_MATCH_STRING=y
++CONFIG_NETFILTER_XT_MATCH_U32=y
++CONFIG_NF_TABLES_IPV4=y
++CONFIG_NFT_DUP_IPV4=y
++CONFIG_NFT_FIB_IPV4=y
++CONFIG_IP_NF_IPTABLES=y
++CONFIG_IP_NF_FILTER=y
++CONFIG_IP_NF_TARGET_REJECT=y
++CONFIG_IP_NF_NAT=y
++CONFIG_IP_NF_TARGET_MASQUERADE=y
++CONFIG_IP_NF_TARGET_NETMAP=y
++CONFIG_IP_NF_TARGET_REDIRECT=y
++CONFIG_NETLINK_DIAG=y
++CONFIG_CAN=y
++CONFIG_BT=y
++CONFIG_BT_RFCOMM=y
++CONFIG_BT_RFCOMM_TTY=y
++CONFIG_BT_BNEP=y
++CONFIG_BT_BNEP_MC_FILTER=y
++CONFIG_BT_BNEP_PROTO_FILTER=y
++CONFIG_BT_HCIBTUSB=m
++# CONFIG_BT_HCIBTUSB_BCM is not set
++CONFIG_CFG80211=y
++CONFIG_MAC80211=y
++CONFIG_RFKILL=y
++CONFIG_NET_9P=y
++CONFIG_NET_9P_VIRTIO=y
++CONFIG_PCI=y
++# CONFIG_PCIEASPM is not set
++CONFIG_PCIE_STARFIVE_HOST=y
++CONFIG_DEVTMPFS=y
++CONFIG_DEVTMPFS_MOUNT=y
++CONFIG_MTD=y
++CONFIG_MTD_BLOCK=y
++CONFIG_MTD_CFI=y
++CONFIG_MTD_CFI_ADV_OPTIONS=y
++CONFIG_MTD_SPI_NOR=y
++CONFIG_OF_CONFIGFS=y
++CONFIG_BLK_DEV_LOOP=y
++CONFIG_VIRTIO_BLK=y
++CONFIG_BLK_DEV_NVME=y
++CONFIG_EEPROM_AT24=y
++CONFIG_BLK_DEV_SD=y
++CONFIG_BLK_DEV_SR=y
++CONFIG_SCSI_VIRTIO=y
++CONFIG_ATA=y
++CONFIG_SATA_AHCI=y
++CONFIG_MD=y
++CONFIG_BLK_DEV_DM=m
++CONFIG_NETDEVICES=y
++CONFIG_VIRTIO_NET=y
++# CONFIG_NET_VENDOR_ALACRITECH is not set
++# CONFIG_NET_VENDOR_AMAZON is not set
++# CONFIG_NET_VENDOR_AQUANTIA is not set
++# CONFIG_NET_VENDOR_ARC is not set
++# CONFIG_NET_VENDOR_BROADCOM is not set
++# CONFIG_NET_VENDOR_CADENCE is not set
++# CONFIG_NET_VENDOR_CAVIUM is not set
++# CONFIG_NET_VENDOR_CORTINA is not set
++# CONFIG_NET_VENDOR_EZCHIP is not set
++# CONFIG_NET_VENDOR_GOOGLE is not set
++# CONFIG_NET_VENDOR_HUAWEI is not set
++# CONFIG_NET_VENDOR_INTEL is not set
++# CONFIG_NET_VENDOR_MARVELL is not set
++# CONFIG_NET_VENDOR_MELLANOX is not set
++# CONFIG_NET_VENDOR_MICREL is not set
++# CONFIG_NET_VENDOR_MICROCHIP is not set
++# CONFIG_NET_VENDOR_MICROSEMI is not set
++# CONFIG_NET_VENDOR_NI is not set
++# CONFIG_NET_VENDOR_NATSEMI is not set
++# CONFIG_NET_VENDOR_NETRONOME is not set
++# CONFIG_NET_VENDOR_PENSANDO is not set
++# CONFIG_NET_VENDOR_QUALCOMM is not set
++CONFIG_R8169=y
++# CONFIG_NET_VENDOR_RENESAS is not set
++# CONFIG_NET_VENDOR_ROCKER is not set
++# CONFIG_NET_VENDOR_SAMSUNG is not set
++# CONFIG_NET_VENDOR_SEEQ is not set
++# CONFIG_NET_VENDOR_SOLARFLARE is not set
++# CONFIG_NET_VENDOR_SOCIONEXT is not set
++CONFIG_STMMAC_ETH=y
++CONFIG_STMMAC_SELFTESTS=y
++CONFIG_DWMAC_DWC_QOS_ETH=y
++CONFIG_DWMAC_STARFIVE=y
++# CONFIG_NET_VENDOR_SYNOPSYS is not set
++# CONFIG_NET_VENDOR_VIA is not set
++# CONFIG_NET_VENDOR_WIZNET is not set
++# CONFIG_NET_VENDOR_XILINX is not set
++CONFIG_MARVELL_PHY=y
++CONFIG_MICREL_PHY=y
++CONFIG_MICROCHIP_PHY=y
++CONFIG_MOTORCOMM_PHY=y
++CONFIG_IPMS_CAN=y
++CONFIG_IWLWIFI=y
++CONFIG_IWLDVM=y
++CONFIG_IWLMVM=y
++CONFIG_HOSTAP=y
++# CONFIG_RTL_CARDS is not set
++CONFIG_USB_WIFI_ECR6600U=y
++CONFIG_AIC_WLAN_SUPPORT=y
++CONFIG_AIC8800_WLAN_SUPPORT=m
++CONFIG_AIC_LOADFW_SUPPORT=m
++CONFIG_INPUT_EVDEV=y
++# CONFIG_INPUT_KEYBOARD is not set
++# CONFIG_INPUT_MOUSE is not set
++CONFIG_INPUT_TOUCHSCREEN=y
++CONFIG_TOUCHSCREEN_GOODIX=y
++CONFIG_TOUCHSCREEN_TINKER_FT5406=y
++CONFIG_SERIO_LIBPS2=y
++CONFIG_SERIAL_8250=y
++CONFIG_SERIAL_8250_CONSOLE=y
++CONFIG_SERIAL_8250_NR_UARTS=6
++CONFIG_SERIAL_8250_RUNTIME_UARTS=6
++CONFIG_SERIAL_8250_EXTENDED=y
++CONFIG_SERIAL_8250_MANY_PORTS=y
++CONFIG_SERIAL_8250_DW=y
++CONFIG_SERIAL_OF_PLATFORM=y
++CONFIG_TTY_PRINTK=y
++CONFIG_VIRTIO_CONSOLE=y
++CONFIG_HW_RANDOM=y
++CONFIG_HW_RANDOM_JH7110=y
++CONFIG_I2C_CHARDEV=y
++CONFIG_I2C_DESIGNWARE_PLATFORM=y
++CONFIG_SPI=y
++CONFIG_SPI_CADENCE_QUADSPI=y
++CONFIG_SPI_PL022=y
++CONFIG_SPI_SIFIVE=y
++CONFIG_SPI_SPIDEV=y
++# CONFIG_PTP_1588_CLOCK is not set
++CONFIG_GPIO_SYSFS=y
++CONFIG_POWER_RESET=y
++CONFIG_POWER_RESET_GPIO_RESTART=y
++CONFIG_POWER_RESET_SYSCON=y
++CONFIG_POWER_RESET_SYSCON_POWEROFF=y
++CONFIG_SENSORS_SFCTEMP=y
++CONFIG_THERMAL=y
++CONFIG_THERMAL_WRITABLE_TRIPS=y
++CONFIG_CPU_THERMAL=y
++CONFIG_DEVFREQ_THERMAL=y
++CONFIG_THERMAL_EMULATION=y
++# CONFIG_HISI_THERMAL is not set
++CONFIG_WATCHDOG=y
++CONFIG_WATCHDOG_SYSFS=y
++CONFIG_MFD_AXP20X_I2C=y
++CONFIG_REGULATOR=y
++CONFIG_REGULATOR_AXP20X=y
++CONFIG_REGULATOR_GPIO=y
++CONFIG_REGULATOR_RASPBERRYPI_TOUCHSCREEN_ATTINY=y
++# CONFIG_MEDIA_CEC_SUPPORT is not set
++CONFIG_MEDIA_SUPPORT=y
++CONFIG_MEDIA_USB_SUPPORT=y
++CONFIG_USB_VIDEO_CLASS=y
++CONFIG_V4L_PLATFORM_DRIVERS=y
++CONFIG_V4L_MEM2MEM_DRIVERS=y
++CONFIG_VIDEO_CADENCE_CSI2RX=y
++CONFIG_VIDEO_WAVE_VPU=m
++CONFIG_VIN_SENSOR_OV4689=y
++CONFIG_VIN_SENSOR_IMX219=y
++CONFIG_VIDEO_STF_VIN=y
++CONFIG_VIDEO_IMX219=y
++CONFIG_VIDEO_IMX708=y
++CONFIG_DRM_PANEL_SIMPLE=y
++CONFIG_DRM_PANEL_JADARD_JD9365DA_H3=y
++CONFIG_DRM_TOSHIBA_TC358762=y
++CONFIG_DRM_VERISILICON=y
++CONFIG_STARFIVE_INNO_HDMI=y
++CONFIG_STARFIVE_DSI=y
++CONFIG_DRM_IMG_ROGUE=y
++CONFIG_DRM_LEGACY=y
++CONFIG_FB=y
++CONFIG_BACKLIGHT_CLASS_DEVICE=y
++CONFIG_SOUND=y
++CONFIG_SND=y
++CONFIG_SND_USB_AUDIO=y
++CONFIG_SND_SOC=y
++CONFIG_SND_DESIGNWARE_I2S=y
++CONFIG_SND_SOC_RZ=m
++CONFIG_SND_SOC_STARFIVE=y
++CONFIG_SND_SOC_JH7110_PWMDAC=y
++CONFIG_SND_SOC_JH7110_TDM=y
++CONFIG_SND_SOC_AC108=y
++CONFIG_SND_SOC_WM8960=y
++CONFIG_SND_SIMPLE_CARD=y
++CONFIG_UHID=y
++CONFIG_USB=y
++CONFIG_USB_OTG=y
++CONFIG_USB_XHCI_HCD=y
++CONFIG_USB_RENESAS_USBHS=y
++CONFIG_USB_STORAGE=y
++CONFIG_USB_UAS=y
++CONFIG_USB_CDNS_SUPPORT=y
++CONFIG_USB_CDNS3=y
++CONFIG_USB_CDNS3_GADGET=y
++CONFIG_USB_CDNS3_HOST=y
++CONFIG_USB_CDNS3_STARFIVE=y
++CONFIG_USB_SERIAL=m
++CONFIG_USB_SERIAL_GENERIC=y
++CONFIG_USB_SERIAL_AIRCABLE=m
++CONFIG_USB_SERIAL_ARK3116=m
++CONFIG_USB_SERIAL_BELKIN=m
++CONFIG_USB_SERIAL_CH341=m
++CONFIG_USB_SERIAL_WHITEHEAT=m
++CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
++CONFIG_USB_SERIAL_CP210X=m
++CONFIG_USB_SERIAL_CYPRESS_M8=m
++CONFIG_USB_SERIAL_EMPEG=m
++CONFIG_USB_SERIAL_FTDI_SIO=m
++CONFIG_USB_SERIAL_VISOR=m
++CONFIG_USB_SERIAL_IPAQ=m
++CONFIG_USB_SERIAL_IR=m
++CONFIG_USB_SERIAL_EDGEPORT=m
++CONFIG_USB_SERIAL_EDGEPORT_TI=m
++CONFIG_USB_SERIAL_F81232=m
++CONFIG_USB_SERIAL_GARMIN=m
++CONFIG_USB_SERIAL_IPW=m
++CONFIG_USB_SERIAL_IUU=m
++CONFIG_USB_SERIAL_KEYSPAN_PDA=m
++CONFIG_USB_SERIAL_KEYSPAN=m
++CONFIG_USB_SERIAL_KLSI=m
++CONFIG_USB_SERIAL_KOBIL_SCT=m
++CONFIG_USB_SERIAL_MCT_U232=m
++CONFIG_USB_SERIAL_METRO=m
++CONFIG_USB_SERIAL_MOS7720=m
++CONFIG_USB_SERIAL_MOS7840=m
++CONFIG_USB_SERIAL_NAVMAN=m
++CONFIG_USB_SERIAL_PL2303=m
++CONFIG_USB_SERIAL_OTI6858=m
++CONFIG_USB_SERIAL_QCAUX=m
++CONFIG_USB_SERIAL_QUALCOMM=m
++CONFIG_USB_SERIAL_SPCP8X5=m
++CONFIG_USB_SERIAL_SAFE=m
++CONFIG_USB_SERIAL_SIERRAWIRELESS=m
++CONFIG_USB_SERIAL_SYMBOL=m
++CONFIG_USB_SERIAL_TI=m
++CONFIG_USB_SERIAL_CYBERJACK=m
++CONFIG_USB_SERIAL_OMNINET=m
++CONFIG_USB_SERIAL_OPTICON=m
++CONFIG_USB_SERIAL_XSENS_MT=m
++CONFIG_USB_SERIAL_WISHBONE=m
++CONFIG_USB_SERIAL_SSU100=m
++CONFIG_USB_SERIAL_DEBUG=m
++CONFIG_USB_GADGET=y
++CONFIG_USB_RENESAS_USBHS_UDC=m
++CONFIG_USB_CONFIGFS=y
++CONFIG_USB_CONFIGFS_SERIAL=y
++CONFIG_USB_CONFIGFS_ACM=y
++CONFIG_USB_CONFIGFS_OBEX=y
++CONFIG_USB_CONFIGFS_NCM=y
++CONFIG_USB_CONFIGFS_ECM=y
++CONFIG_USB_CONFIGFS_ECM_SUBSET=y
++CONFIG_USB_CONFIGFS_RNDIS=y
++CONFIG_USB_CONFIGFS_EEM=y
++CONFIG_USB_CONFIGFS_MASS_STORAGE=y
++CONFIG_USB_CONFIGFS_F_FS=y
++CONFIG_MMC=y
++CONFIG_MMC_DEBUG=y
++CONFIG_MMC_SDHCI=y
++CONFIG_MMC_SDHCI_PLTFM=y
++CONFIG_MMC_SDHCI_OF_DWCMSHC=y
++CONFIG_MMC_SPI=y
++CONFIG_MMC_SDHI=y
++CONFIG_MMC_DW=y
++CONFIG_MMC_DW_STARFIVE=y
++CONFIG_NEW_LEDS=y
++CONFIG_LEDS_CLASS=y
++CONFIG_LEDS_GPIO=y
++CONFIG_LEDS_TRIGGER_HEARTBEAT=y
++CONFIG_RTC_CLASS=y
++CONFIG_RTC_DRV_STARFIVE=y
++CONFIG_RTC_DRV_GOLDFISH=y
++CONFIG_DMADEVICES=y
++CONFIG_AMBA_PL08X=y
++CONFIG_DW_AXI_DMAC=y
++CONFIG_DMATEST=y
++# CONFIG_VIRTIO_MENU is not set
++# CONFIG_VHOST_MENU is not set
++CONFIG_GOLDFISH=y
++CONFIG_CLK_STARFIVE_JH7110_AON=y
++CONFIG_CLK_STARFIVE_JH7110_STG=y
++CONFIG_CLK_STARFIVE_JH7110_ISP=y
++CONFIG_CLK_STARFIVE_JH7110_VOUT=y
++CONFIG_MAILBOX=y
++CONFIG_STARFIVE_MBOX=m
++CONFIG_STARFIVE_MBOX_TEST=m
++# CONFIG_IOMMU_SUPPORT is not set
++CONFIG_RPMSG_CHAR=y
++CONFIG_RPMSG_VIRTIO=y
++CONFIG_SIFIVE_CCACHE=y
++CONFIG_PM_DEVFREQ=y
++CONFIG_IIO=y
++CONFIG_IIO_ST_ACCEL_3AXIS=y
++CONFIG_PWM=y
++CONFIG_PWM_OCORES=y
++CONFIG_PHY_STARFIVE_JH7110_PCIE=y
++CONFIG_PHY_STARFIVE_JH7110_USB=y
++CONFIG_PHY_M31_DPHY_RX0=y
++CONFIG_RAS=y
++CONFIG_EXT4_FS=y
++CONFIG_EXT4_FS_POSIX_ACL=y
++CONFIG_BTRFS_FS=m
++CONFIG_BTRFS_FS_POSIX_ACL=y
++CONFIG_AUTOFS_FS=y
++CONFIG_FUSE_FS=y
++CONFIG_CUSE=y
++CONFIG_VIRTIO_FS=y
++CONFIG_FSCACHE=y
++CONFIG_FSCACHE_STATS=y
++CONFIG_MSDOS_FS=y
++CONFIG_VFAT_FS=y
++CONFIG_FAT_DEFAULT_UTF8=y
++CONFIG_EXFAT_FS=y
++CONFIG_NTFS_FS=y
++CONFIG_NTFS_RW=y
++CONFIG_TMPFS=y
++CONFIG_TMPFS_POSIX_ACL=y
++CONFIG_HUGETLBFS=y
++CONFIG_JFFS2_FS=y
++CONFIG_NFS_FS=y
++CONFIG_NFS_V4=y
++CONFIG_NFS_V4_1=y
++CONFIG_NFS_V4_2=y
++CONFIG_ROOT_NFS=y
++CONFIG_CIFS=m
++# CONFIG_CIFS_STATS2 is not set
++CONFIG_CIFS_UPCALL=y
++CONFIG_CIFS_XATTR=y
++CONFIG_CIFS_POSIX=y
++# CONFIG_CIFS_DEBUG is not set
++CONFIG_CIFS_DFS_UPCALL=y
++CONFIG_CIFS_FSCACHE=y
++CONFIG_SMB_SERVER=m
++CONFIG_NLS_CODEPAGE_437=y
++CONFIG_NLS_ISO8859_1=y
++CONFIG_INIT_STACK_NONE=y
++CONFIG_CRYPTO_USER=y
++CONFIG_CRYPTO_TEST=m
++CONFIG_CRYPTO_USER_API_HASH=y
++CONFIG_CRYPTO_USER_API_SKCIPHER=y
++CONFIG_CRYPTO_USER_API_RNG=y
++CONFIG_CRYPTO_USER_API_AEAD=y
++CONFIG_CRYPTO_DEV_VIRTIO=y
++CONFIG_CRYPTO_DEV_JH7110=y
++CONFIG_DMA_CMA=y
++CONFIG_PRINTK_TIME=y
++CONFIG_DEBUG_FS=y
++CONFIG_SOFTLOCKUP_DETECTOR=y
++CONFIG_WQ_WATCHDOG=y
++CONFIG_DEBUG_TIMEKEEPING=y
++CONFIG_DEBUG_RT_MUTEXES=y
++CONFIG_DEBUG_SPINLOCK=y
++CONFIG_DEBUG_RWSEMS=y
++CONFIG_DEBUG_LIST=y
++CONFIG_DEBUG_PLIST=y
++CONFIG_DEBUG_SG=y
++# CONFIG_RCU_TRACE is not set
++CONFIG_RCU_EQS_DEBUG=y
++# CONFIG_FTRACE is not set
++# CONFIG_RUNTIME_TESTING_MENU is not set
++CONFIG_MEMTEST=y
diff --git a/target/linux/starfive/patches-6.6/0106-riscv-dts-starfive-update-dts-to-kernel-6.6.patch b/target/linux/starfive/patches-6.6/0106-riscv-dts-starfive-update-dts-to-kernel-6.6.patch
new file mode 100644
index 0000000000..defc0e669a
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0106-riscv-dts-starfive-update-dts-to-kernel-6.6.patch
@@ -0,0 +1,759 @@
+From 51c1cccb202d741eeb1de57e0ecf8fcaa8f059e8 Mon Sep 17 00:00:00 2001
+From: Ziv Xu <ziv.xu@starfivetech.com>
+Date: Wed, 13 Mar 2024 18:36:31 +0800
+Subject: [PATCH 106/116] riscv: dts: starfive: update dts to kernel 6.6
+
+update dts to kernel 6.6
+
+Signed-off-by: Ziv Xu <ziv.xu@starfivetech.com>
+---
+ arch/riscv/boot/dts/starfive/Makefile | 5 +-
+ .../jh7110-starfive-visionfive-2-ac108.dts | 64 +++
+ .../jh7110-starfive-visionfive-2-tdm.dts | 59 +++
+ .../jh7110-starfive-visionfive-2-wm8960.dts | 71 +++
+ .../jh7110-starfive-visionfive-2.dtsi | 437 +++++++++++++++++-
+ 5 files changed, 633 insertions(+), 3 deletions(-)
+ create mode 100644 arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-ac108.dts
+ create mode 100644 arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-tdm.dts
+ create mode 100644 arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-wm8960.dts
+
+--- a/arch/riscv/boot/dts/starfive/Makefile
++++ b/arch/riscv/boot/dts/starfive/Makefile
+@@ -10,7 +10,10 @@ dtb-$(CONFIG_ARCH_STARFIVE) += jh7100-be
+ dtb-$(CONFIG_ARCH_STARFIVE) += jh7100-starfive-visionfive-v1.dtb
+
+ dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-starfive-visionfive-2-v1.2a.dtb
+-dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-starfive-visionfive-2-v1.3b.dtb
++dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-starfive-visionfive-2-v1.3b.dtb \
++ jh7110-starfive-visionfive-2-ac108.dtb \
++ jh7110-starfive-visionfive-2-tdm.dtb \
++ jh7110-starfive-visionfive-2-wm8960.dtb
+
+ subdir-y += evb-overlay
+ dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-evb.dtb \
+--- /dev/null
++++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-ac108.dts
+@@ -0,0 +1,64 @@
++// SPDX-License-Identifier: GPL-2.0 OR MIT
++/*
++ * Copyright (C) 2022 StarFive Technology Co., Ltd.
++ * Copyright (C) 2022 Hal Feng <hal.feng@starfivetech.com>
++ */
++
++/dts-v1/;
++#include "jh7110-starfive-visionfive-2-v1.3b.dts"
++
++/ {
++ /* i2s + ac108 */
++ sound0: snd-card0 {
++ compatible = "simple-audio-card";
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ simple-audio-card,name = "Starfive-AC108-Sound-Card";
++ simple-audio-card,dai-link@0 {
++ reg = <0>;
++ format = "i2s";
++ bitclock-master = <&sndcodec1>;
++ frame-master = <&sndcodec1>;
++
++ widgets =
++ "Microphone", "Mic Jack",
++ "Line", "Line In",
++ "Line", "Line Out",
++ "Speaker", "Speaker",
++ "Headphone", "Headphone Jack";
++ routing =
++ "Headphone Jack", "HP_L",
++ "Headphone Jack", "HP_R",
++ "Speaker", "SPK_LP",
++ "Speaker", "SPK_LN",
++ "LINPUT1", "Mic Jack",
++ "LINPUT3", "Mic Jack",
++ "RINPUT1", "Mic Jack",
++ "RINPUT2", "Mic Jack";
++
++ cpu {
++ sound-dai = <&i2srx_mst>;
++ };
++
++ sndcodec1: codec {
++ sound-dai = <&ac108>;
++ clocks = <&ac108_mclk>;
++ clock-names = "mclk";
++ };
++ };
++ };
++};
++
++&i2c0 {
++ ac108: ac108@3b {
++ compatible = "x-power,ac108_0";
++ reg = <0x3b>;
++ #sound-dai-cells = <0>;
++ data-protocol = <0>;
++ };
++};
++
++&i2srx_mst {
++ status = "okay";
++};
+--- /dev/null
++++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-tdm.dts
+@@ -0,0 +1,59 @@
++// SPDX-License-Identifier: GPL-2.0 OR MIT
++/*
++ * Copyright (C) 2022 StarFive Technology Co., Ltd.
++ * Copyright (C) 2022 Hal Feng <hal.feng@starfivetech.com>
++ */
++
++/dts-v1/;
++#include "jh7110-starfive-visionfive-2-v1.3b.dts"
++
++/ {
++ sound-tdm {
++ compatible = "simple-audio-card";
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ simple-audio-card,name = "Starfive-TDM-Sound-Card";
++ simple-audio-card,widgets = "Microphone", "Mic Jack",
++ "Line", "Line In",
++ "Line", "Line Out",
++ "Speaker", "Speaker",
++ "Headphone", "Headphone Jack";
++ simple-audio-card,routing = "Headphone Jack", "HP_L",
++ "Headphone Jack", "HP_R",
++ "Speaker", "SPK_LP",
++ "Speaker", "SPK_LN",
++ "LINPUT1", "Mic Jack",
++ "LINPUT3", "Mic Jack",
++ "RINPUT1", "Mic Jack",
++ "RINPUT2", "Mic Jack";
++
++ simple-audio-card,dai-link@0 {
++ reg = <0>;
++ format = "dsp_a";
++ bitclock-master = <&dailink_master>;
++ frame-master = <&dailink_master>;
++
++ cpu {
++ sound-dai = <&tdm>;
++ };
++ dailink_master: codec {
++ sound-dai = <&wm8960>;
++ clocks = <&wm8960_mclk>;
++ };
++ };
++ };
++};
++
++&i2c0 {
++ wm8960: codec@1a {
++ compatible = "wlf,wm8960";
++ reg = <0x1a>;
++ wlf,shared-lrclk;
++ #sound-dai-cells = <0>;
++ };
++};
++
++&tdm {
++ status = "okay";
++};
+--- /dev/null
++++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-wm8960.dts
+@@ -0,0 +1,71 @@
++// SPDX-License-Identifier: GPL-2.0 OR MIT
++/*
++ * Copyright (C) 2022 StarFive Technology Co., Ltd.
++ * Copyright (C) 2022 Hal Feng <hal.feng@starfivetech.com>
++ */
++
++/dts-v1/;
++#include "jh7110-starfive-visionfive-2-v1.3b.dts"
++
++/ {
++ /* i2s + wm8960 */
++ sound-wm8960 {
++ compatible = "simple-audio-card";
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ simple-audio-card,name = "Starfive-WM8960-Sound-Card";
++ simple-audio-card,dai-link@0 {
++ reg = <0>;
++ status = "okay";
++ format = "i2s";
++ bitclock-master = <&sndcodec1>;
++ frame-master = <&sndcodec1>;
++
++ widgets =
++ "Microphone", "Mic Jack",
++ "Line", "Line In",
++ "Line", "Line Out",
++ "Speaker", "Speaker",
++ "Headphone", "Headphone Jack";
++ routing =
++ "Headphone Jack", "HP_L",
++ "Headphone Jack", "HP_R",
++ "Speaker", "SPK_LP",
++ "Speaker", "SPK_LN",
++ "LINPUT1", "Mic Jack",
++ "LINPUT3", "Mic Jack",
++ "RINPUT1", "Mic Jack",
++ "RINPUT2", "Mic Jack";
++ cpu0 {
++ sound-dai = <&i2srx>;
++ };
++ cpu1 {
++ sound-dai = <&i2stx1>;
++ };
++
++ sndcodec1:codec {
++ sound-dai = <&wm8960>;
++ clocks = <&wm8960_mclk>;
++ clock-names = "mclk";
++ };
++ };
++ };
++};
++
++&i2c0 {
++ wm8960: codec@1a {
++ compatible = "wlf,wm8960";
++ reg = <0x1a>;
++ wlf,shared-lrclk;
++ #sound-dai-cells = <0>;
++ };
++};
++
++&i2srx {
++ status = "okay";
++};
++
++&i2stx1 {
++ status = "okay";
++};
+--- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
+@@ -7,6 +7,7 @@
+ /dts-v1/;
+ #include "jh7110.dtsi"
+ #include "jh7110-pinfunc.h"
++#include <dt-bindings/leds/common.h>
+ #include <dt-bindings/gpio/gpio.h>
+
+ / {
+@@ -37,6 +38,44 @@
+ reg = <0x0 0x40000000 0x1 0x0>;
+ };
+
++ reserved-memory {
++ #address-cells = <2>;
++ #size-cells = <2>;
++ ranges;
++
++ linux,cma {
++ compatible = "shared-dma-pool";
++ reusable;
++ size = <0x0 0x20000000>;
++ alignment = <0x0 0x1000>;
++ alloc-ranges = <0x0 0x70000000 0x0 0x20000000>;
++ linux,cma-default;
++ };
++
++ e24_mem: e24@c0000000 {
++ reg = <0x0 0x6ce00000 0x0 0x1600000>;
++ };
++
++ xrp_reserved: xrpbuffer@f0000000 {
++ reg = <0x0 0x69c00000 0x0 0x01ffffff
++ 0x0 0x6bc00000 0x0 0x00001000
++ 0x0 0x6bc01000 0x0 0x00fff000
++ 0x0 0x6cc00000 0x0 0x00001000>;
++ };
++ };
++
++ leds {
++ compatible = "gpio-leds";
++
++ led-ack {
++ gpios = <&aongpio 3 GPIO_ACTIVE_HIGH>;
++ color = <LED_COLOR_ID_GREEN>;
++ function = LED_FUNCTION_HEARTBEAT;
++ linux,default-trigger = "heartbeat";
++ label = "ack";
++ };
++ };
++
+ gpio-restart {
+ compatible = "gpio-restart";
+ gpios = <&sysgpio 35 GPIO_ACTIVE_HIGH>;
+@@ -69,6 +108,48 @@
+ };
+ };
+ };
++
++ sound-hdmi {
++ compatible = "simple-audio-card";
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ simple-audio-card,name = "StarFive-HDMI-Sound-Card";
++ simple-audio-card,dai-link@0 {
++ reg = <0>;
++ format = "i2s";
++ bitclock-master = <&sndi2s0>;
++ frame-master = <&sndi2s0>;
++ mclk-fs = <256>;
++ status = "okay";
++
++ sndi2s0: cpu {
++ sound-dai = <&i2stx0>;
++ };
++
++ codec {
++ sound-dai = <&hdmi>;
++ };
++ };
++ };
++
++ ac108_mclk: ac108_mclk {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <24000000>;
++ };
++
++ clk_ext_camera: clk-ext-camera {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <24000000>;
++ };
++
++ wm8960_mclk: wm8960_mclk {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <24576000>;
++ };
+ };
+
+ &dvp_clk {
+@@ -177,6 +258,42 @@
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_pins>;
+ status = "okay";
++
++ seeed_plane_i2c@45 {
++ compatible = "seeed_panel";
++ reg = <0x45>;
++
++ port {
++ panel_out0: endpoint {
++ remote-endpoint = <&dsi0_output>;
++ };
++ };
++ };
++
++ tinker_ft5406: tinker_ft5406@38 {
++ compatible = "tinker_ft5406";
++ reg = <0x38>;
++ };
++
++ touchscreen@14 {
++ compatible = "goodix,gt911";
++ reg = <0x14>;
++ irq-gpios = <&sysgpio 30 GPIO_ACTIVE_HIGH>;
++ reset-gpios = <&sysgpio 31 GPIO_ACTIVE_HIGH>;
++ };
++
++ panel_radxa@19 {
++ compatible ="starfive_jadard";
++ reg = <0x19>;
++ reset-gpio = <&sysgpio 23 0>;
++ enable-gpio = <&sysgpio 22 0>;
++
++ port {
++ panel_out1: endpoint {
++ remote-endpoint = <&dsi1_output>;
++ };
++ };
++ };
+ };
+
+ &i2c5 {
+@@ -195,11 +312,36 @@
+ #interrupt-cells = <1>;
+
+ regulators {
++ mipi_0p9: ALDO1 {
++ regulator-boot-on;
++ regulator-compatible = "aldo1";
++ regulator-name = "mipi_0p9";
++ regulator-min-microvolt = <900000>;
++ regulator-max-microvolt = <900000>;
++ };
++
++ hdmi_0p9: ALDO5 {
++ regulator-boot-on;
++ regulator-compatible = "aldo5";
++ regulator-name = "hdmi_0p9";
++ regulator-min-microvolt = <900000>;
++ regulator-max-microvolt = <900000>;
++ };
++
++ hdmi_1p8: ALDO3 {
++ regulator-boot-on;
++ regulator-compatible = "aldo3";
++ regulator-name = "hdmi_1p8";
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ };
++
+ vcc_3v3: dcdc1 {
+ regulator-boot-on;
+ regulator-always-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
++ regulator-compatible = "dcdc1";
+ regulator-name = "vcc_3v3";
+ };
+
+@@ -207,6 +349,7 @@
+ regulator-always-on;
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1540000>;
++ regulator-compatible = "dcdc2";
+ regulator-name = "vdd-cpu";
+ };
+
+@@ -215,6 +358,7 @@
+ regulator-always-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
++ regulator-compatible = "aldo4";
+ regulator-name = "emmc_vdd";
+ };
+ };
+@@ -229,12 +373,68 @@
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c6_pins>;
+ status = "okay";
++
++ imx219: imx219@10 {
++ compatible = "sony,imx219";
++ reg = <0x10>;
++ clocks = <&clk_ext_camera>;
++ clock-names = "xclk";
++ reset-gpio = <&sysgpio 18 0>;
++ rotation = <0>;
++ orientation = <1>; //CAMERA_ORIENTATION_BACK
++
++ port {
++ /* CSI2 bus endpoint */
++ imx219_to_csi2rx0: endpoint {
++ remote-endpoint = <&csi2rx0_from_imx219>;
++ bus-type = <4>; /* MIPI CSI-2 D-PHY */
++ clock-lanes = <4>;
++ data-lanes = <0 1>;
++ lane-polarities = <0 0 0>;
++ link-frequencies = /bits/ 64 <456000000>;
++ };
++ };
++ };
++
++ imx708: imx708@1a {
++ compatible = "sony,imx708";
++ reg = <0x1a>;
++ clocks = <&clk_ext_camera>;
++ reset-gpio = <&sysgpio 18 0>;
++
++ port {
++ imx708_to_csi2rx0: endpoint {
++ remote-endpoint = <&csi2rx0_from_imx708>;
++ data-lanes = <1 2>;
++ clock-noncontinuous;
++ link-frequencies = /bits/ 64 <450000000>;
++ };
++ };
++ };
++
++ ov4689: ov4689@36 {
++ compatible = "ovti,ov4689";
++ reg = <0x36>;
++ clocks = <&clk_ext_camera>;
++ clock-names = "xclk";
++ rotation = <180>;
++
++ port {
++ /* Parallel bus endpoint */
++ ov4689_to_csi2rx0: endpoint {
++ remote-endpoint = <&csi2rx0_from_ov4689>;
++ bus-type = <4>; /* MIPI CSI-2 D-PHY */
++ clock-lanes = <0>;
++ data-lanes = <1 2>;
++ };
++ };
++ };
+ };
+
+ &i2srx {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2srx_pins>;
+- status = "okay";
++ status = "disabled";
+ };
+
+ &i2stx0 {
+@@ -246,7 +446,7 @@
+ &i2stx1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2stx1_pins>;
+- status = "okay";
++ status = "disabled";
+ };
+
+ &mmc0 {
+@@ -661,6 +861,40 @@
+ slew-rate = <0>;
+ };
+ };
++
++ hdmi_pins: hdmi-0 {
++ scl-pins {
++ pinmux = <GPIOMUX(0, GPOUT_SYS_HDMI_DDC_SCL,
++ GPOEN_SYS_HDMI_DDC_SCL,
++ GPI_SYS_HDMI_DDC_SCL)>;
++ bias-pull-up;
++ input-enable;
++ };
++
++ sda-pins {
++ pinmux = <GPIOMUX(1, GPOUT_SYS_HDMI_DDC_SDA,
++ GPOEN_SYS_HDMI_DDC_SDA,
++ GPI_SYS_HDMI_DDC_SDA)>;
++ bias-pull-up;
++ input-enable;
++ };
++
++ cec-pins {
++ pinmux = <GPIOMUX(14, GPOUT_SYS_HDMI_CEC_SDA,
++ GPOEN_SYS_HDMI_CEC_SDA,
++ GPI_SYS_HDMI_CEC_SDA)>;
++ bias-pull-up;
++ input-enable;
++ };
++
++ hpd-pins {
++ pinmux = <GPIOMUX(15, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_HDMI_HPD)>;
++ bias-disable; /* external pull-up */
++ input-enable;
++ };
++ };
+ };
+
+ &uart0 {
+@@ -689,3 +923,202 @@
+ &U74_4 {
+ cpu-supply = <&vdd_cpu>;
+ };
++
++
++&display {
++ ports = <&dc_out_dpi0>;
++ status = "okay";
++};
++
++&dc8200 {
++ status = "okay";
++
++ dc_out: port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ dc_out_dpi0: endpoint@0 {
++ reg = <0>;
++ remote-endpoint = <&hdmi_input0>;
++ };
++ dc_out_dpi1: endpoint@1 {
++ reg = <1>;
++ remote-endpoint = <&hdmi_in_lcdc>;
++ };
++
++ dc_out_dpi2: endpoint@2 {
++ reg = <2>;
++ remote-endpoint = <&mipi_in>;
++ };
++ };
++};
++
++&hdmi {
++ status = "okay";
++ pinctrl-names = "default";
++ pinctrl-0 = <&hdmi_pins>;
++ hpd-gpio = <&sysgpio 15 GPIO_ACTIVE_HIGH>;
++
++ hdmi_in: port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ hdmi_in_lcdc: endpoint@0 {
++ reg = <0>;
++ remote-endpoint = <&dc_out_dpi1>;
++ };
++ };
++};
++
++&rgb_output {
++ status = "disabled";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ port@0 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0>;
++ hdmi_input0:endpoint@0 {
++ reg = <0>;
++ remote-endpoint = <&dc_out_dpi0>;
++ };
++ };
++ };
++};
++
++&dsi_output {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ reg = <0>;
++ mipi_in: endpoint {
++ remote-endpoint = <&dc_out_dpi2>;
++ };
++ };
++
++ port@1 {
++ reg = <1>;
++ sf_dpi_output: endpoint {
++ remote-endpoint = <&dsi_in_port>;
++ };
++ };
++ };
++};
++
++&mipi_dsi {
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@0 {
++ reg = <0>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ dsi0_output: endpoint@0 {
++ reg = <0>;
++ remote-endpoint = <&panel_out0>;
++ };
++
++ dsi1_output: endpoint@1 {
++ reg = <1>;
++ remote-endpoint = <&panel_out1>;
++ };
++
++ };
++
++ port@1{
++ reg = <1>;
++ dsi_in_port: endpoint {
++ remote-endpoint = <&sf_dpi_output>;
++ };
++ };
++
++ };
++};
++
++&mipi_dphy {
++ status = "okay";
++};
++
++&co_process {
++ memory-region = <&e24_mem>;
++ status = "okay";
++};
++
++
++&mailbox_contrl0 {
++ status = "okay";
++};
++
++&mailbox_client0 {
++ status = "okay";
++};
++
++&vpu_dec {
++ status = "okay";
++};
++
++&vpu_enc {
++ status = "okay";
++};
++
++&jpu {
++ status = "okay";
++};
++
++&gpu {
++ status = "okay";
++};
++
++&vin_sysctl {
++ /* when use dvp open this pinctrl*/
++ status = "okay";
++
++ ports {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ port@1 {
++ reg = <1>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ /* CSI2 bus endpoint */
++ csi2rx0_from_imx219: endpoint@0 {
++ reg = <0>;
++ remote-endpoint = <&imx219_to_csi2rx0>;
++ bus-type = <4>; /* MIPI CSI-2 D-PHY */
++ clock-lanes = <4>;
++ data-lanes = <0 1>;
++ lane-polarities = <0 0 0>;
++ status = "okay";
++ };
++
++ csi2rx0_from_imx708: endpoint@1 {
++ reg = <1>;
++ remote-endpoint = <&imx708_to_csi2rx0>;
++ bus-type = <4>; /* MIPI CSI-2 D-PHY */
++ clock-lanes = <4>;
++ data-lanes = <0 1>;
++ lane-polarities = <0 0 0>;
++ status = "okay";
++ };
++
++ csi2rx0_from_ov4689: endpoint@2 {
++ reg = <2>;
++ remote-endpoint = <&ov4689_to_csi2rx0>;
++ bus-type = <4>; /* MIPI CSI-2 D-PHY */
++ clock-lanes = <4>;
++ data-lanes = <0 1>;
++ status = "okay";
++ };
++ };
++ };
++};
diff --git a/target/linux/starfive/patches-6.6/0107-riscv-dts-starfive-evb-overlay-Support-SPI-overlay.patch b/target/linux/starfive/patches-6.6/0107-riscv-dts-starfive-evb-overlay-Support-SPI-overlay.patch
new file mode 100644
index 0000000000..873883101f
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0107-riscv-dts-starfive-evb-overlay-Support-SPI-overlay.patch
@@ -0,0 +1,71 @@
+From 17a781895079f8f9b2c089d13a1e4d9789e018c5 Mon Sep 17 00:00:00 2001
+From: Hal Feng <hal.feng@starfivetech.com>
+Date: Wed, 20 Mar 2024 17:36:14 +0800
+Subject: [PATCH 107/116] riscv: dts: starfive: evb-overlay: Support SPI
+ overlay
+
+Add new compatibles to support SPI overlay.
+
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ .../dts/starfive/evb-overlay/jh7110-evb-overlay-spi.dtso | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/arch/riscv/boot/dts/starfive/evb-overlay/jh7110-evb-overlay-spi.dtso
++++ b/arch/riscv/boot/dts/starfive/evb-overlay/jh7110-evb-overlay-spi.dtso
+@@ -9,6 +9,7 @@
+ fragment@0 {
+ target-path = "/soc/spi@10060000";
+ __overlay__ {
++ compatible = "starfive,jh7110-spi-pl022";
+ status = "okay";
+ };
+ };
+@@ -17,6 +18,7 @@
+ fragment@1 {
+ target-path = "/soc/spi@10070000";
+ __overlay__ {
++ compatible = "starfive,jh7110-spi-pl022";
+ status = "okay";
+ };
+ };
+@@ -25,6 +27,7 @@
+ fragment@2 {
+ target-path = "/soc/spi@10080000";
+ __overlay__ {
++ compatible = "starfive,jh7110-spi-pl022";
+ status = "okay";
+ };
+ };
+@@ -33,6 +36,7 @@
+ fragment@3 {
+ target-path = "/soc/spi@12070000";
+ __overlay__ {
++ compatible = "starfive,jh7110-spi-pl022";
+ status = "okay";
+ };
+ };
+@@ -41,6 +45,7 @@
+ fragment@4 {
+ target-path = "/soc/spi@12080000";
+ __overlay__ {
++ compatible = "starfive,jh7110-spi-pl022";
+ status = "okay";
+ };
+ };
+@@ -49,6 +54,7 @@
+ fragment@5 {
+ target-path = "/soc/spi@12090000";
+ __overlay__ {
++ compatible = "starfive,jh7110-spi-pl022";
+ status = "okay";
+ };
+ };
+@@ -57,6 +63,7 @@
+ fragment@6 {
+ target-path = "/soc/spi@120a0000";
+ __overlay__ {
++ compatible = "starfive,jh7110-spi-pl022";
+ status = "okay";
+ };
+ };
diff --git a/target/linux/starfive/patches-6.6/0108-riscv-configs-visionfive2-Add-standard-partition-for.patch b/target/linux/starfive/patches-6.6/0108-riscv-configs-visionfive2-Add-standard-partition-for.patch
new file mode 100644
index 0000000000..a4b2e14f9b
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0108-riscv-configs-visionfive2-Add-standard-partition-for.patch
@@ -0,0 +1,23 @@
+From 49b818cdd08fca7ff761277635c0e5ab659becb8 Mon Sep 17 00:00:00 2001
+From: Hal Feng <hal.feng@starfivetech.com>
+Date: Thu, 21 Mar 2024 16:53:51 +0800
+Subject: [PATCH 108/116] riscv: configs: visionfive2: Add standard partition
+ for hibernation
+
+Add CONFIG_PM_STD_PARTITION="PARTLABEL=hibernation".
+
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ arch/riscv/configs/starfive_visionfive2_defconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/arch/riscv/configs/starfive_visionfive2_defconfig
++++ b/arch/riscv/configs/starfive_visionfive2_defconfig
+@@ -24,6 +24,7 @@ CONFIG_NONPORTABLE=y
+ CONFIG_SMP=y
+ CONFIG_HZ_100=y
+ CONFIG_HIBERNATION=y
++CONFIG_PM_STD_PARTITION="PARTLABEL=hibernation"
+ CONFIG_PM_DEBUG=y
+ CONFIG_PM_ADVANCED_DEBUG=y
+ CONFIG_PM_TEST_SUSPEND=y
diff --git a/target/linux/starfive/patches-6.6/0109-usb-xhci-To-improve-performance-usb-using-lowmem-for.patch b/target/linux/starfive/patches-6.6/0109-usb-xhci-To-improve-performance-usb-using-lowmem-for.patch
new file mode 100644
index 0000000000..3f9499974c
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0109-usb-xhci-To-improve-performance-usb-using-lowmem-for.patch
@@ -0,0 +1,297 @@
+From 146eb94a08d12b5831e1d30455469750f7c5f2a3 Mon Sep 17 00:00:00 2001
+From: "minda.chen" <minda.chen@starfivetech.com>
+Date: Tue, 18 Oct 2022 09:57:39 +0800
+Subject: [PATCH 109/116] usb:xhci:To improve performance,usb using lowmem for
+ bulk xfer.
+
+Generate an usb low memory pool for usb 3.0 host
+read/write transfer, default size is 8M.
+
+Signed-off-by: minda.chen <minda.chen@starfivetech.com>
+---
+ arch/riscv/boot/dts/starfive/jh7110-evb.dts | 1 +
+ drivers/usb/core/hcd.c | 4 +-
+ drivers/usb/host/xhci-mem.c | 64 +++++++++++++++++++++
+ drivers/usb/host/xhci-plat.c | 8 +++
+ drivers/usb/host/xhci-ring.c | 3 +-
+ drivers/usb/host/xhci.c | 57 +++++++++++++++++-
+ drivers/usb/host/xhci.h | 11 ++++
+ 7 files changed, 145 insertions(+), 3 deletions(-)
+
+--- a/arch/riscv/boot/dts/starfive/jh7110-evb.dts
++++ b/arch/riscv/boot/dts/starfive/jh7110-evb.dts
+@@ -31,5 +31,6 @@
+ };
+
+ &usb0 {
++ xhci-lowmem-pool;
+ status = "okay";
+ };
+--- a/drivers/usb/core/hcd.c
++++ b/drivers/usb/core/hcd.c
+@@ -1439,7 +1439,9 @@ int usb_hcd_map_urb_for_dma(struct usb_h
+ if (ret == 0)
+ urb->transfer_flags |= URB_MAP_LOCAL;
+ } else if (hcd_uses_dma(hcd)) {
+- if (urb->num_sgs) {
++ if (urb->transfer_flags & URB_MAP_LOCAL)
++ return ret;
++ else if (urb->num_sgs) {
+ int n;
+
+ /* We don't support sg for isoc transfers ! */
+--- a/drivers/usb/host/xhci-mem.c
++++ b/drivers/usb/host/xhci-mem.c
+@@ -14,6 +14,7 @@
+ #include <linux/slab.h>
+ #include <linux/dmapool.h>
+ #include <linux/dma-mapping.h>
++#include <linux/genalloc.h>
+
+ #include "xhci.h"
+ #include "xhci-trace.h"
+@@ -1842,6 +1843,7 @@ xhci_free_interrupter(struct xhci_hcd *x
+ void xhci_mem_cleanup(struct xhci_hcd *xhci)
+ {
+ struct device *dev = xhci_to_hcd(xhci)->self.sysdev;
++ struct xhci_lowmem_pool *pool;
+ int i, j, num_ports;
+
+ cancel_delayed_work_sync(&xhci->cmd_timer);
+@@ -1887,6 +1889,13 @@ void xhci_mem_cleanup(struct xhci_hcd *x
+ xhci_dbg_trace(xhci, trace_xhci_dbg_init,
+ "Freed medium stream array pool");
+
++ if (xhci->lowmem_pool.pool) {
++ pool = &xhci->lowmem_pool;
++ dma_free_coherent(dev, pool->size, (void *)pool->cached_base, pool->dma_addr);
++ gen_pool_destroy(pool->pool);
++ pool->pool = NULL;
++ }
++
+ if (xhci->dcbaa)
+ dma_free_coherent(dev, sizeof(*xhci->dcbaa),
+ xhci->dcbaa, xhci->dcbaa->dma);
+@@ -2297,6 +2306,55 @@ xhci_add_interrupter(struct xhci_hcd *xh
+ return 0;
+ }
+
++int xhci_setup_local_lowmem(struct xhci_hcd *xhci, size_t size)
++{
++ int err;
++ void *buffer;
++ dma_addr_t dma_addr;
++ struct usb_hcd *hcd = xhci_to_hcd(xhci);
++ struct xhci_lowmem_pool *pool = &xhci->lowmem_pool;
++
++ if (!pool->pool) {
++ /* minimal alloc one page */
++ pool->pool = gen_pool_create(PAGE_SHIFT, dev_to_node(hcd->self.sysdev));
++ if (IS_ERR(pool->pool))
++ return PTR_ERR(pool->pool);
++ }
++
++ buffer = dma_alloc_coherent(hcd->self.sysdev, size, &dma_addr,
++ GFP_KERNEL | GFP_DMA32);
++
++ if (IS_ERR(buffer)) {
++ err = PTR_ERR(buffer);
++ goto destroy_pool;
++ }
++
++ /*
++ * Here we pass a dma_addr_t but the arg type is a phys_addr_t.
++ * It's not backed by system memory and thus there's no kernel mapping
++ * for it.
++ */
++ err = gen_pool_add_virt(pool->pool, (unsigned long)buffer,
++ dma_addr, size, dev_to_node(hcd->self.sysdev));
++ if (err < 0) {
++ dev_err(hcd->self.sysdev, "gen_pool_add_virt failed with %d\n",
++ err);
++ dma_free_coherent(hcd->self.sysdev, size, buffer, dma_addr);
++ goto destroy_pool;
++ }
++
++ pool->cached_base = (u64)buffer;
++ pool->dma_addr = dma_addr;
++
++ return 0;
++
++destroy_pool:
++ gen_pool_destroy(pool->pool);
++ pool->pool = NULL;
++ return err;
++}
++EXPORT_SYMBOL_GPL(xhci_setup_local_lowmem);
++
+ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
+ {
+ dma_addr_t dma;
+@@ -2433,6 +2491,12 @@ int xhci_mem_init(struct xhci_hcd *xhci,
+
+ xhci->isoc_bei_interval = AVOID_BEI_INTERVAL_MAX;
+
++ if (xhci->quirks & XHCI_LOCAL_BUFFER) {
++ if (xhci_setup_local_lowmem(xhci,
++ xhci->lowmem_pool.size))
++ goto fail;
++ }
++
+ /*
+ * XXX: Might need to set the Interrupter Moderation Register to
+ * something other than the default (~1ms minimum between interrupts).
+--- a/drivers/usb/host/xhci-plat.c
++++ b/drivers/usb/host/xhci-plat.c
+@@ -253,6 +253,14 @@ int xhci_plat_probe(struct platform_devi
+ if (device_property_read_bool(tmpdev, "xhci-sg-trb-cache-size-quirk"))
+ xhci->quirks |= XHCI_SG_TRB_CACHE_SIZE_QUIRK;
+
++ if (device_property_read_bool(tmpdev, "xhci-lowmem-pool")) {
++ xhci->quirks |= XHCI_LOCAL_BUFFER;
++ if (device_property_read_u32(tmpdev, "lowmem-pool-size",
++ &xhci->lowmem_pool.size)) {
++ xhci->lowmem_pool.size = 8 << 20;
++ } else
++ xhci->lowmem_pool.size <<= 20;
++ }
+ device_property_read_u32(tmpdev, "imod-interval-ns",
+ &xhci->imod_interval);
+ }
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -3650,7 +3650,8 @@ int xhci_queue_bulk_tx(struct xhci_hcd *
+
+ full_len = urb->transfer_buffer_length;
+ /* If we have scatter/gather list, we use it. */
+- if (urb->num_sgs && !(urb->transfer_flags & URB_DMA_MAP_SINGLE)) {
++ if (urb->num_sgs && !(urb->transfer_flags & URB_DMA_MAP_SINGLE)
++ && !(urb->transfer_flags & URB_MAP_LOCAL)) {
+ num_sgs = urb->num_mapped_sgs;
+ sg = urb->sg;
+ addr = (u64) sg_dma_address(sg);
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -18,6 +18,8 @@
+ #include <linux/slab.h>
+ #include <linux/dmi.h>
+ #include <linux/dma-mapping.h>
++#include <linux/dma-map-ops.h>
++#include <linux/genalloc.h>
+
+ #include "xhci.h"
+ #include "xhci-trace.h"
+@@ -1285,6 +1287,55 @@ static void xhci_unmap_temp_buf(struct u
+ urb->transfer_buffer = NULL;
+ }
+
++static void xhci_map_urb_local(struct usb_hcd *hcd, struct urb *urb,
++ gfp_t mem_flags)
++{
++ void *buffer;
++ dma_addr_t dma_handle;
++ struct xhci_hcd *xhci = hcd_to_xhci(hcd);
++ struct xhci_lowmem_pool *lowmem_pool = &xhci->lowmem_pool;
++
++ if (lowmem_pool->pool
++ && (usb_endpoint_type(&urb->ep->desc) == USB_ENDPOINT_XFER_BULK)
++ && (urb->transfer_buffer_length > PAGE_SIZE)
++ && urb->num_sgs && urb->sg && (sg_phys(urb->sg) > 0xffffffff)) {
++ buffer = gen_pool_dma_alloc(lowmem_pool->pool,
++ urb->transfer_buffer_length, &dma_handle);
++ if (buffer) {
++ urb->transfer_dma = dma_handle;
++ urb->transfer_buffer = buffer;
++ urb->transfer_flags |= URB_MAP_LOCAL;
++ if (usb_urb_dir_out(urb))
++ sg_copy_to_buffer(urb->sg, urb->num_sgs,
++ (void *)buffer,
++ urb->transfer_buffer_length);
++ }
++ }
++
++}
++
++static void xhci_unmap_urb_local(struct usb_hcd *hcd, struct urb *urb)
++{
++ dma_addr_t dma_handle;
++ u64 cached_buffer;
++ struct xhci_hcd *xhci = hcd_to_xhci(hcd);
++ struct xhci_lowmem_pool *lowmem_pool = &xhci->lowmem_pool;
++
++ if (urb->transfer_flags & URB_MAP_LOCAL) {
++ dma_handle = urb->transfer_dma;
++ cached_buffer = lowmem_pool->cached_base +
++ ((u32)urb->transfer_dma & (lowmem_pool->size - 1));
++ if (usb_urb_dir_in(urb))
++ sg_copy_from_buffer(urb->sg, urb->num_sgs,
++ (void *)cached_buffer, urb->transfer_buffer_length);
++ gen_pool_free(lowmem_pool->pool, (unsigned long)urb->transfer_buffer,
++ urb->transfer_buffer_length);
++ urb->transfer_flags &= ~URB_MAP_LOCAL;
++ urb->transfer_buffer = NULL;
++ }
++}
++
++
+ /*
+ * Bypass the DMA mapping if URB is suitable for Immediate Transfer (IDT),
+ * we'll copy the actual data into the TRB address register. This is limited to
+@@ -1305,9 +1356,11 @@ static int xhci_map_urb_for_dma(struct u
+ if (xhci_urb_temp_buffer_required(hcd, urb))
+ return xhci_map_temp_buffer(hcd, urb);
+ }
++ xhci_map_urb_local(hcd, urb, mem_flags);
+ return usb_hcd_map_urb_for_dma(hcd, urb, mem_flags);
+ }
+
++
+ static void xhci_unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb)
+ {
+ struct xhci_hcd *xhci;
+@@ -1320,8 +1373,10 @@ static void xhci_unmap_urb_for_dma(struc
+
+ if ((xhci->quirks & XHCI_SG_TRB_CACHE_SIZE_QUIRK) && unmap_temp_buf)
+ xhci_unmap_temp_buf(hcd, urb);
+- else
++ else {
++ xhci_unmap_urb_local(hcd, urb);
+ usb_hcd_unmap_urb_for_dma(hcd, urb);
++ }
+ }
+
+ /**
+--- a/drivers/usb/host/xhci.h
++++ b/drivers/usb/host/xhci.h
+@@ -1763,6 +1763,13 @@ struct xhci_hub {
+ u8 min_rev;
+ };
+
++struct xhci_lowmem_pool {
++ struct gen_pool *pool;
++ u64 cached_base;
++ dma_addr_t dma_addr;
++ unsigned int size;
++};
++
+ /* There is one xhci_hcd structure per controller */
+ struct xhci_hcd {
+ struct usb_hcd *main_hcd;
+@@ -1914,6 +1921,8 @@ struct xhci_hcd {
+ #define XHCI_ZHAOXIN_TRB_FETCH BIT_ULL(45)
+ #define XHCI_ZHAOXIN_HOST BIT_ULL(46)
+
++#define XHCI_LOCAL_BUFFER BIT_ULL(63)
++
+ unsigned int num_active_eps;
+ unsigned int limit_active_eps;
+ struct xhci_port *hw_ports;
+@@ -1943,6 +1952,8 @@ struct xhci_hcd {
+ struct list_head regset_list;
+
+ void *dbc;
++ struct xhci_lowmem_pool lowmem_pool;
++
+ /* platform-specific data -- must come last */
+ unsigned long priv[] __aligned(sizeof(s64));
+ };
diff --git a/target/linux/starfive/patches-6.6/0110-usb-xhci-using-dma_alloc_noncoherent-to-alloc-low-me.patch b/target/linux/starfive/patches-6.6/0110-usb-xhci-using-dma_alloc_noncoherent-to-alloc-low-me.patch
new file mode 100644
index 0000000000..739bc76e71
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0110-usb-xhci-using-dma_alloc_noncoherent-to-alloc-low-me.patch
@@ -0,0 +1,106 @@
+From a170cb9936bb0b00d58aaea40984dbce1169fe42 Mon Sep 17 00:00:00 2001
+From: Minda Chen <minda.chen@starfivetech.com>
+Date: Mon, 3 Jul 2023 16:14:20 +0800
+Subject: [PATCH 110/116] usb: xhci: using dma_alloc_noncoherent to alloc low
+ memory pool
+
+For RISCV_NONCACHEHERENT is set, using dma_alloc_noncoherent
+to alloc cached large block low memory buffer. And set default
+size to 4M. (largest size of continuous memory can be supported)
+
+Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
+---
+ drivers/usb/host/xhci-mem.c | 29 ++++++++++++++++-------------
+ drivers/usb/host/xhci-plat.c | 9 +++++----
+ 2 files changed, 21 insertions(+), 17 deletions(-)
+
+--- a/drivers/usb/host/xhci-mem.c
++++ b/drivers/usb/host/xhci-mem.c
+@@ -1891,7 +1891,8 @@ void xhci_mem_cleanup(struct xhci_hcd *x
+
+ if (xhci->lowmem_pool.pool) {
+ pool = &xhci->lowmem_pool;
+- dma_free_coherent(dev, pool->size, (void *)pool->cached_base, pool->dma_addr);
++ dma_free_noncoherent(dev, pool->size, (void *)pool->cached_base,
++ pool->dma_addr, DMA_BIDIRECTIONAL);
+ gen_pool_destroy(pool->pool);
+ pool->pool = NULL;
+ }
+@@ -2317,15 +2318,15 @@ int xhci_setup_local_lowmem(struct xhci_
+ if (!pool->pool) {
+ /* minimal alloc one page */
+ pool->pool = gen_pool_create(PAGE_SHIFT, dev_to_node(hcd->self.sysdev));
+- if (IS_ERR(pool->pool))
+- return PTR_ERR(pool->pool);
++ if (!pool->pool)
++ return -ENOMEM;
+ }
+
+- buffer = dma_alloc_coherent(hcd->self.sysdev, size, &dma_addr,
+- GFP_KERNEL | GFP_DMA32);
++ buffer = dma_alloc_noncoherent(hcd->self.sysdev, size, &dma_addr,
++ DMA_BIDIRECTIONAL, GFP_ATOMIC);
+
+- if (IS_ERR(buffer)) {
+- err = PTR_ERR(buffer);
++ if (!buffer) {
++ err = -ENOMEM;
+ goto destroy_pool;
+ }
+
+@@ -2335,11 +2336,11 @@ int xhci_setup_local_lowmem(struct xhci_
+ * for it.
+ */
+ err = gen_pool_add_virt(pool->pool, (unsigned long)buffer,
+- dma_addr, size, dev_to_node(hcd->self.sysdev));
++ dma_addr, size, dev_to_node(hcd->self.sysdev));
+ if (err < 0) {
+ dev_err(hcd->self.sysdev, "gen_pool_add_virt failed with %d\n",
+ err);
+- dma_free_coherent(hcd->self.sysdev, size, buffer, dma_addr);
++ dma_free_noncoherent(hcd->self.sysdev, size, buffer, dma_addr, DMA_BIDIRECTIONAL);
+ goto destroy_pool;
+ }
+
+@@ -2362,7 +2363,7 @@ int xhci_mem_init(struct xhci_hcd *xhci,
+ unsigned int val, val2;
+ u64 val_64;
+ u32 page_size, temp;
+- int i;
++ int i, ret;
+
+ INIT_LIST_HEAD(&xhci->cmd_list);
+
+@@ -2492,9 +2493,11 @@ int xhci_mem_init(struct xhci_hcd *xhci,
+ xhci->isoc_bei_interval = AVOID_BEI_INTERVAL_MAX;
+
+ if (xhci->quirks & XHCI_LOCAL_BUFFER) {
+- if (xhci_setup_local_lowmem(xhci,
+- xhci->lowmem_pool.size))
+- goto fail;
++ ret = xhci_setup_local_lowmem(xhci, xhci->lowmem_pool.size);
++ if (ret) {
++ xhci->quirks &= ~XHCI_LOCAL_BUFFER;
++ xhci_warn(xhci, "WARN: Can't alloc lowmem pool\n");
++ }
+ }
+
+ /*
+--- a/drivers/usb/host/xhci-plat.c
++++ b/drivers/usb/host/xhci-plat.c
+@@ -255,10 +255,11 @@ int xhci_plat_probe(struct platform_devi
+
+ if (device_property_read_bool(tmpdev, "xhci-lowmem-pool")) {
+ xhci->quirks |= XHCI_LOCAL_BUFFER;
+- if (device_property_read_u32(tmpdev, "lowmem-pool-size",
+- &xhci->lowmem_pool.size)) {
+- xhci->lowmem_pool.size = 8 << 20;
+- } else
++ ret = device_property_read_u32(tmpdev, "lowmem-pool-size",
++ &xhci->lowmem_pool.size);
++ if (ret || xhci->lowmem_pool.size >= 4)
++ xhci->lowmem_pool.size = 4 << 20;
++ else
+ xhci->lowmem_pool.size <<= 20;
+ }
+ device_property_read_u32(tmpdev, "imod-interval-ns",
diff --git a/target/linux/starfive/patches-6.6/0111-riscv-dts-starfive-Add-vf2-overlay-dtso-subdir.patch b/target/linux/starfive/patches-6.6/0111-riscv-dts-starfive-Add-vf2-overlay-dtso-subdir.patch
new file mode 100644
index 0000000000..451b1c16fd
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0111-riscv-dts-starfive-Add-vf2-overlay-dtso-subdir.patch
@@ -0,0 +1,139 @@
+From fc86405992c37b1898fd9b9bc077be673d774269 Mon Sep 17 00:00:00 2001
+From: Hal Feng <hal.feng@starfivetech.com>
+Date: Fri, 22 Mar 2024 09:54:28 +0800
+Subject: [PATCH 111/116] riscv: dts: starfive: Add vf2-overlay dtso subdir
+
+Create subdir vf2-overlay/ and add overlay .dtso for VF2 board.
+The code is ported from tag JH7110_VF2_6.1_v5.11.4
+
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ arch/riscv/boot/dts/starfive/Makefile | 1 +
+ .../boot/dts/starfive/vf2-overlay/Makefile | 3 +
+ .../starfive/vf2-overlay/vf2-overlay-can.dtso | 23 ++++++
+ .../vf2-overlay/vf2-overlay-uart3-i2c.dtso | 75 +++++++++++++++++++
+ 4 files changed, 102 insertions(+)
+ create mode 100644 arch/riscv/boot/dts/starfive/vf2-overlay/Makefile
+ create mode 100644 arch/riscv/boot/dts/starfive/vf2-overlay/vf2-overlay-can.dtso
+ create mode 100644 arch/riscv/boot/dts/starfive/vf2-overlay/vf2-overlay-uart3-i2c.dtso
+
+--- a/arch/riscv/boot/dts/starfive/Makefile
++++ b/arch/riscv/boot/dts/starfive/Makefile
+@@ -9,6 +9,7 @@ DTC_FLAGS_jh7110-evb := -@
+ dtb-$(CONFIG_ARCH_STARFIVE) += jh7100-beaglev-starlight.dtb
+ dtb-$(CONFIG_ARCH_STARFIVE) += jh7100-starfive-visionfive-v1.dtb
+
++subdir-y += vf2-overlay
+ dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-starfive-visionfive-2-v1.2a.dtb
+ dtb-$(CONFIG_ARCH_STARFIVE) += jh7110-starfive-visionfive-2-v1.3b.dtb \
+ jh7110-starfive-visionfive-2-ac108.dtb \
+--- /dev/null
++++ b/arch/riscv/boot/dts/starfive/vf2-overlay/Makefile
+@@ -0,0 +1,3 @@
++# SPDX-License-Identifier: GPL-2.0
++dtb-$(CONFIG_ARCH_STARFIVE) += vf2-overlay-uart3-i2c.dtbo \
++ vf2-overlay-can.dtbo
+--- /dev/null
++++ b/arch/riscv/boot/dts/starfive/vf2-overlay/vf2-overlay-can.dtso
+@@ -0,0 +1,23 @@
++/dts-v1/;
++/plugin/;
++#include <dt-bindings/gpio/gpio.h>
++#include "../jh7110-pinfunc.h"
++/ {
++ compatible = "starfive,jh7110";
++
++ //can0
++ fragment@0 {
++ target-path = "/soc/can@130d0000";
++ __overlay__ {
++ status = "okay";
++ };
++ };
++
++ //can1
++ fragment@1 {
++ target-path = "/soc/can@130e0000";
++ __overlay__ {
++ status = "okay";
++ };
++ };
++};
+--- /dev/null
++++ b/arch/riscv/boot/dts/starfive/vf2-overlay/vf2-overlay-uart3-i2c.dtso
+@@ -0,0 +1,75 @@
++/dts-v1/;
++/plugin/;
++#include <dt-bindings/gpio/gpio.h>
++#include "../jh7110-pinfunc.h"
++/ {
++ compatible = "starfive,jh7110";
++
++ //sysgpio
++ fragment@0 {
++ target-path = "/soc/pinctrl@13040000";
++ __overlay__ {
++ dt_uart3_pins: dt-uart3-0 {
++ tx-pins {
++ pinmux = <GPIOMUX(60, GPOUT_SYS_UART3_TX,
++ GPOEN_ENABLE,
++ GPI_NONE)>;
++ bias-disable;
++ drive-strength = <12>;
++ input-disable;
++ input-schmitt-disable;
++ slew-rate = <0>;
++ };
++
++ rx-pins {
++ pinmux = <GPIOMUX(63, GPOUT_LOW,
++ GPOEN_DISABLE,
++ GPI_SYS_UART3_RX)>;
++ bias-pull-up;
++ drive-strength = <2>;
++ input-enable;
++ input-schmitt-enable;
++ slew-rate = <0>;
++ };
++ };
++
++ dt_i2c1_pins: dt-i2c1-0 {
++ i2c-pins {
++ pinmux = <GPIOMUX(42, GPOUT_LOW,
++ GPOEN_SYS_I2C1_CLK,
++ GPI_SYS_I2C1_CLK)>,
++ <GPIOMUX(43, GPOUT_LOW,
++ GPOEN_SYS_I2C1_DATA,
++ GPI_SYS_I2C1_DATA)>;
++ bias-pull-up;
++ input-enable;
++ input-schmitt-enable;
++ };
++ };
++ };
++ };
++
++ //uart3
++ fragment@1 {
++ target-path = "/soc/serial@12000000";
++ __overlay__ {
++ pinctrl-names = "default";
++ pinctrl-0 = <&dt_uart3_pins>;
++ status = "okay";
++ };
++ };
++
++ //i2c1
++ fragment@2 {
++ target-path = "/soc/i2c@10040000";
++ __overlay__ {
++ clock-frequency = <100000>;
++ i2c-sda-hold-time-ns = <300>;
++ i2c-sda-falling-time-ns = <510>;
++ i2c-scl-falling-time-ns = <510>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&dt_i2c1_pins>;
++ status = "okay";
++ };
++ };
++};
diff --git a/target/linux/starfive/patches-6.6/0112-riscv-dts-starfive-visionfive-2-Add-aliases-for-i2c-.patch b/target/linux/starfive/patches-6.6/0112-riscv-dts-starfive-visionfive-2-Add-aliases-for-i2c-.patch
new file mode 100644
index 0000000000..17dcf726ef
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0112-riscv-dts-starfive-visionfive-2-Add-aliases-for-i2c-.patch
@@ -0,0 +1,34 @@
+From 2b098da69f9497e725683caf67fbecf79202b7fc Mon Sep 17 00:00:00 2001
+From: Hal Feng <hal.feng@starfivetech.com>
+Date: Fri, 22 Mar 2024 11:33:40 +0800
+Subject: [PATCH 112/116] riscv: dts: starfive: visionfive 2: Add aliases for
+ i2c* and uart3
+
+Fix the numbers of i2c and uart3.
+
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ .../riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
+@@ -15,7 +15,10 @@
+ ethernet0 = &gmac0;
+ ethernet1 = &gmac1;
+ i2c0 = &i2c0;
++ i2c1 = &i2c1;
+ i2c2 = &i2c2;
++ i2c3 = &i2c3;
++ i2c4 = &i2c4;
+ i2c5 = &i2c5;
+ i2c6 = &i2c6;
+ mmc0 = &mmc0;
+@@ -23,6 +26,7 @@
+ pcie0 = &pcie0;
+ pcie1 = &pcie1;
+ serial0 = &uart0;
++ serial3 = &uart3;
+ };
+
+ chosen {
diff --git a/target/linux/starfive/patches-6.6/0113-driver-bluetooth-add-aic8800-driver-support.patch b/target/linux/starfive/patches-6.6/0113-driver-bluetooth-add-aic8800-driver-support.patch
new file mode 100644
index 0000000000..3651976081
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0113-driver-bluetooth-add-aic8800-driver-support.patch
@@ -0,0 +1,6063 @@
+From 18b70b6f5192ee5363515b57e1f213d0698224ed Mon Sep 17 00:00:00 2001
+From: "ziv.xu" <ziv.xu@starfive.com>
+Date: Tue, 28 Nov 2023 15:37:14 +0800
+Subject: [PATCH 113/116] driver: bluetooth: add aic8800 driver support
+
+add aic8800 driver that can support sco profile
+
+Signed-off-by: ziv.xu <ziv.xu@starfive.com>
+---
+ .../configs/starfive_visionfive2_defconfig | 3 +-
+ drivers/bluetooth/Kconfig | 4 +
+ drivers/bluetooth/Makefile | 1 +
+ drivers/bluetooth/aic_btusb/Makefile | 80 +
+ drivers/bluetooth/aic_btusb/aic_btusb.c | 5031 +++++++++++++++++
+ drivers/bluetooth/aic_btusb/aic_btusb.h | 753 +++
+ .../aic_btusb/aic_btusb_external_featrue.c | 126 +
+ .../aic_btusb/aic_btusb_external_featrue.h | 3 +
+ 8 files changed, 5999 insertions(+), 2 deletions(-)
+ create mode 100644 drivers/bluetooth/aic_btusb/Makefile
+ create mode 100644 drivers/bluetooth/aic_btusb/aic_btusb.c
+ create mode 100644 drivers/bluetooth/aic_btusb/aic_btusb.h
+ create mode 100644 drivers/bluetooth/aic_btusb/aic_btusb_external_featrue.c
+ create mode 100644 drivers/bluetooth/aic_btusb/aic_btusb_external_featrue.h
+
+--- a/arch/riscv/configs/starfive_visionfive2_defconfig
++++ b/arch/riscv/configs/starfive_visionfive2_defconfig
+@@ -87,8 +87,7 @@ CONFIG_BT_RFCOMM_TTY=y
+ CONFIG_BT_BNEP=y
+ CONFIG_BT_BNEP_MC_FILTER=y
+ CONFIG_BT_BNEP_PROTO_FILTER=y
+-CONFIG_BT_HCIBTUSB=m
+-# CONFIG_BT_HCIBTUSB_BCM is not set
++CONFIG_BT_AICUSB=y
+ CONFIG_CFG80211=y
+ CONFIG_MAC80211=y
+ CONFIG_RFKILL=y
+--- a/drivers/bluetooth/Kconfig
++++ b/drivers/bluetooth/Kconfig
+@@ -478,5 +478,9 @@ config BT_NXPUART
+ Say Y here to compile support for NXP Bluetooth UART device into
+ the kernel, or say M here to compile as a module (btnxpuart).
+
++config BT_AICUSB
++ tristate "AIC8800 btusb driver"
++ help
++ AIC8800 usb dongle bluetooth support driver
+
+ endmenu
+--- a/drivers/bluetooth/Makefile
++++ b/drivers/bluetooth/Makefile
+@@ -51,3 +51,4 @@ hci_uart-$(CONFIG_BT_HCIUART_QCA) += hci
+ hci_uart-$(CONFIG_BT_HCIUART_AG6XX) += hci_ag6xx.o
+ hci_uart-$(CONFIG_BT_HCIUART_MRVL) += hci_mrvl.o
+ hci_uart-objs := $(hci_uart-y)
++obj-$(CONFIG_BT_AICUSB) += aic_btusb/
+--- /dev/null
++++ b/drivers/bluetooth/aic_btusb/Makefile
+@@ -0,0 +1,80 @@
++MODULE_NAME = aic_btusb
++
++CONFIG_AIC8800_BTUSB_SUPPORT = m
++CONFIG_SUPPORT_VENDOR_APCF = n
++# Need to set fw path in BOARD_KERNEL_CMDLINE
++CONFIG_USE_FW_REQUEST = n
++
++ifeq ($(CONFIG_SUPPORT_VENDOR_APCF), y)
++obj-$(CONFIG_AIC8800_BTUSB_SUPPORT) := $(MODULE_NAME).o aic_btusb_external_featrue.o
++else
++obj-$(CONFIG_AIC8800_BTUSB_SUPPORT) := $(MODULE_NAME).o
++endif
++
++ccflags-$(CONFIG_SUPPORT_VENDOR_APCF) += -DCONFIG_SUPPORT_VENDOR_APCF
++#$(MODULE_NAME)-y := aic_btusb_ioctl.o\
++# aic_btusb.o \
++
++ccflags-$(CONFIG_USE_FW_REQUEST) += -DCONFIG_USE_FW_REQUEST
++
++
++# Platform support list
++CONFIG_PLATFORM_ROCKCHIP ?= n
++CONFIG_PLATFORM_ALLWINNER ?= n
++CONFIG_PLATFORM_AMLOGIC ?= n
++CONFIG_PLATFORM_UBUNTU ?= y
++CONFIG_PLATFORM_ING ?= n
++
++ifeq ($(CONFIG_PLATFORM_ING), y)
++ARCH := mips
++KDIR ?= /home/yaya/E/Ingenic/T31/Ingenic-SDK-T31-1.1.5-20220428/opensource/kernel
++CROSS_COMPILE := /home/yaya/E/Ingenic/T31/Ingenic-SDK-T31-1.1.5-20220428/resource/toolchain/gcc_472/mips-gcc472-glibc216-32bit/bin/mips-linux-gnu-
++endif
++
++ifeq ($(CONFIG_PLATFORM_ROCKCHIP), y)
++ccflags-$(CONFIG_PLATFORM_ROCKCHIP) += -DCONFIG_PLATFORM_ROCKCHIP
++#KDIR := /home/yaya/E/Rockchip/3229/Android9/rk3229_android9.0_box/kernel
++#ARCH ?= arm
++#CROSS_COMPILE ?= /home/yaya/E/Rockchip/3229/Android9/rk3229_android9.0_box/prebuilts/gcc/linux-x86/arm/gcc-linaro-6.3.1-2017.05-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-
++#KDIR := /home/yaya/E/Rockchip/3229/Android7/RK3229_ANDROID7.1_v1.01_20170914/rk3229_Android7.1_v1.01_xml0914/kernel
++#ARCH ?= arm
++#CROSS_COMPILE ?= /home/yaya/E/Rockchip/3229/Android7/RK3229_ANDROID7.1_v1.01_20170914/rk3229_Android7.1_v1.01_xml0914/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin/arm-eabi-
++ARCH := arm64
++KDIR ?= /home/yaya/E/Rockchip/3566/firefly/Android11.0/Firefly-RK356X_Android11.0_git_20210824/RK356X_Android11.0/kernel
++CROSS_COMPILE := /home/yaya/E/Rockchip/3566/firefly/Android11.0/Firefly-RK356X_Android11.0_git_20210824/RK356X_Android11.0/prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-
++
++endif
++
++ifeq ($(CONFIG_PLATFORM_ALLWINNER), y)
++ccflags-$(CONFIG_PLATFORM_ALLWINNER) += -DCONFIG_PLATFORM_ALLWINNER
++KDIR := /home/yaya/E/Allwinner/R818/R818/AndroidQ/lichee/kernel/linux-4.9
++ARCH ?= arm64
++CROSS_COMPILE ?= /home/yaya/E/Allwinner/R818/R818/AndroidQ/lichee/out/gcc-linaro-5.3.1-2016.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-
++endif
++
++ifeq ($(CONFIG_PLATFORM_AMLOGIC), y)
++ ccflags-$(CONFIG_PLATFORM_AMLOGIC) += -DCONFIG_PLATFORM_AMLOGIC
++endif
++
++ifeq ($(CONFIG_PLATFORM_UBUNTU), y)
++ccflags-$(CONFIG_PLATFORM_UBUNTU) += -DCONFIG_PLATFORM_UBUNTU
++endif
++
++all: modules
++modules:
++ make -C $(KDIR) M=$(PWD) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) modules
++
++install:
++ mkdir -p $(MODDESTDIR)
++ install -p -m 644 $(MODULE_NAME).ko $(MODDESTDIR)/
++ /sbin/depmod -a ${KVER}
++ echo $(MODULE_NAME) >> /etc/modules-load.d/aic_bt.conf
++
++uninstall:
++ rm -rfv $(MODDESTDIR)/$(MODULE_NAME).ko
++ /sbin/depmod -a ${KVER}
++ rm -f /etc/modules-load.d/aic_bt.conf
++
++clean:
++ rm -rf *.o *.ko *.o.* *.mod.* modules.* Module.* .a* .o* .*.o.* *.mod .tmp* .cache.mk .Module.symvers.cmd .modules.order.cmd
++
+--- /dev/null
++++ b/drivers/bluetooth/aic_btusb/aic_btusb.c
+@@ -0,0 +1,5031 @@
++/*
++ *
++ * AicSemi Bluetooth USB driver
++ *
++ *
++ *
++ * 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
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * 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.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/slab.h>
++#include <linux/types.h>
++#include <linux/sched.h>
++#include <linux/errno.h>
++#include <linux/skbuff.h>
++#include <linux/usb.h>
++
++#include <linux/ioctl.h>
++#include <linux/io.h>
++#include <linux/firmware.h>
++#include <linux/vmalloc.h>
++#include <linux/fs.h>
++#include <linux/uaccess.h>
++#include <linux/reboot.h>
++
++#include "aic_btusb.h"
++
++#ifdef CONFIG_USE_FW_REQUEST
++#include <linux/firmware.h>
++#endif
++
++#define AICBT_RELEASE_NAME "202012_ANDROID"
++#define VERSION "2.1.0"
++
++#define SUSPNED_DW_FW 0
++
++
++static spinlock_t queue_lock;
++static spinlock_t dlfw_lock;
++static volatile uint16_t dlfw_dis_state = 0;
++
++/* USB Device ID */
++#define USB_VENDOR_ID_AIC 0xA69C
++#define USB_PRODUCT_ID_AIC8801 0x8801
++#define USB_PRODUCT_ID_AIC8800DC 0x88dc
++#define USB_PRODUCT_ID_AIC8800D80 0x8d81
++
++enum AICWF_IC{
++ PRODUCT_ID_AIC8801 = 0,
++ PRODUCT_ID_AIC8800DC,
++ PRODUCT_ID_AIC8800DW,
++ PRODUCT_ID_AIC8800D80
++};
++
++u16 g_chipid = PRODUCT_ID_AIC8801;
++u8 chip_id = 0;
++u8 sub_chip_id = 0;
++
++struct btusb_data {
++ struct hci_dev *hdev;
++ struct usb_device *udev;
++ struct usb_interface *intf;
++ struct usb_interface *isoc;
++
++ spinlock_t lock;
++
++ unsigned long flags;
++
++ struct work_struct work;
++ struct work_struct waker;
++
++ struct usb_anchor tx_anchor;
++ struct usb_anchor intr_anchor;
++ struct usb_anchor bulk_anchor;
++ struct usb_anchor isoc_anchor;
++ struct usb_anchor deferred;
++ int tx_in_flight;
++ spinlock_t txlock;
++
++#if (CONFIG_BLUEDROID == 0)
++#if HCI_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)
++ spinlock_t rxlock;
++ struct sk_buff *evt_skb;
++ struct sk_buff *acl_skb;
++ struct sk_buff *sco_skb;
++#endif
++#endif
++
++ struct usb_endpoint_descriptor *intr_ep;
++ struct usb_endpoint_descriptor *bulk_tx_ep;
++ struct usb_endpoint_descriptor *bulk_rx_ep;
++ struct usb_endpoint_descriptor *isoc_tx_ep;
++ struct usb_endpoint_descriptor *isoc_rx_ep;
++
++ __u8 cmdreq_type;
++
++ unsigned int sco_num;
++ int isoc_altsetting;
++ int suspend_count;
++ uint16_t sco_handle;
++
++#if (CONFIG_BLUEDROID == 0)
++#if HCI_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)
++ int (*recv_bulk) (struct btusb_data * data, void *buffer, int count);
++#endif
++#endif
++
++//#ifdef CONFIG_HAS_EARLYSUSPEND
++#if 0
++ struct early_suspend early_suspend;
++#else
++ struct notifier_block pm_notifier;
++ struct notifier_block reboot_notifier;
++#endif
++ firmware_info *fw_info;
++
++#ifdef CONFIG_SCO_OVER_HCI
++ AIC_sco_card_t *pSCOSnd;
++#endif
++};
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 1)
++static bool reset_on_close = 0;
++#endif
++
++#ifdef CONFIG_SCO_OVER_HCI
++struct snd_sco_cap_timer {
++ struct timer_list cap_timer;
++ struct timer_list play_timer;
++ struct btusb_data snd_usb_data;
++ int snd_sco_length;
++};
++static struct snd_sco_cap_timer snd_cap_timer;
++#endif
++
++
++int bt_support = 0;
++module_param(bt_support, int, 0660);
++
++#ifdef CONFIG_SUPPORT_VENDOR_APCF
++int vendor_apcf_sent_done = 0;
++#endif
++
++static inline int check_set_dlfw_state_value(uint16_t change_value)
++{
++ spin_lock(&dlfw_lock);
++ if(!dlfw_dis_state) {
++ dlfw_dis_state = change_value;
++ }
++ spin_unlock(&dlfw_lock);
++ return dlfw_dis_state;
++}
++
++static inline void set_dlfw_state_value(uint16_t change_value)
++{
++ spin_lock(&dlfw_lock);
++ dlfw_dis_state = change_value;
++ spin_unlock(&dlfw_lock);
++}
++
++
++
++
++static void aic_free( struct btusb_data *data)
++{
++#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 1)
++ kfree(data);
++#endif
++ return;
++}
++
++static struct btusb_data *aic_alloc(struct usb_interface *intf)
++{
++ struct btusb_data *data;
++#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 1)
++ data = kzalloc(sizeof(*data), GFP_KERNEL);
++#else
++ data = devm_kzalloc(&intf->dev, sizeof(*data), GFP_KERNEL);
++#endif
++ return data;
++}
++
++static void print_acl(struct sk_buff *skb, int direction)
++{
++#if PRINT_ACL_DATA
++ //uint wlength = skb->len;
++ u16 *handle = (u16 *)(skb->data);
++ u16 len = *(handle+1);
++ //u8 *acl_data = (u8 *)(skb->data);
++
++ AICBT_INFO("aic %s: direction %d, handle %04x, len %d",
++ __func__, direction, *handle, len);
++#endif
++}
++
++static void print_sco(struct sk_buff *skb, int direction)
++{
++#if PRINT_SCO_DATA
++ uint wlength = skb->len;
++ u16 *handle = (u16 *)(skb->data);
++ u8 len = *(u8 *)(handle+1);
++ //u8 *sco_data =(u8 *)(skb->data);
++
++ AICBT_INFO("aic %s: direction %d, handle %04x, len %d,wlength %d",
++ __func__, direction, *handle, len,wlength);
++#endif
++}
++
++static void print_error_command(struct sk_buff *skb)
++{
++ u16 *opcode = (u16*)(skb->data);
++ u8 *cmd_data = (u8*)(skb->data);
++ u8 len = *(cmd_data+2);
++
++ printk(" 0x%04x,len:%d,", *opcode, len);
++#if CONFIG_BLUEDROID
++ switch (*opcode) {
++ case HCI_OP_INQUIRY:
++ printk("HCI_OP_INQUIRY");
++ break;
++ case HCI_OP_INQUIRY_CANCEL:
++ printk("HCI_OP_INQUIRY_CANCEL");
++ break;
++ case HCI_OP_EXIT_PERIODIC_INQ:
++ printk("HCI_OP_EXIT_PERIODIC_INQ");
++ break;
++ case HCI_OP_CREATE_CONN:
++ printk("HCI_OP_CREATE_CONN");
++ break;
++ case HCI_OP_DISCONNECT:
++ printk("HCI_OP_DISCONNECT");
++ break;
++ case HCI_OP_CREATE_CONN_CANCEL:
++ printk("HCI_OP_CREATE_CONN_CANCEL");
++ break;
++ case HCI_OP_ACCEPT_CONN_REQ:
++ printk("HCI_OP_ACCEPT_CONN_REQ");
++ break;
++ case HCI_OP_REJECT_CONN_REQ:
++ printk("HCI_OP_REJECT_CONN_REQ");
++ break;
++ case HCI_OP_AUTH_REQUESTED:
++ printk("HCI_OP_AUTH_REQUESTED");
++ break;
++ case HCI_OP_SET_CONN_ENCRYPT:
++ printk("HCI_OP_SET_CONN_ENCRYPT");
++ break;
++ case HCI_OP_REMOTE_NAME_REQ:
++ printk("HCI_OP_REMOTE_NAME_REQ");
++ break;
++ case HCI_OP_READ_REMOTE_FEATURES:
++ printk("HCI_OP_READ_REMOTE_FEATURES");
++ break;
++ case HCI_OP_SNIFF_MODE:
++ printk("HCI_OP_SNIFF_MODE");
++ break;
++ case HCI_OP_EXIT_SNIFF_MODE:
++ printk("HCI_OP_EXIT_SNIFF_MODE");
++ break;
++ case HCI_OP_SWITCH_ROLE:
++ printk("HCI_OP_SWITCH_ROLE");
++ break;
++ case HCI_OP_SNIFF_SUBRATE:
++ printk("HCI_OP_SNIFF_SUBRATE");
++ break;
++ case HCI_OP_RESET:
++ printk("HCI_OP_RESET");
++ break;
++ case HCI_OP_Write_Extended_Inquiry_Response:
++ printk("HCI_Write_Extended_Inquiry_Response");
++ break;
++ case HCI_OP_Write_Simple_Pairing_Mode:
++ printk("HCI_OP_Write_Simple_Pairing_Mode");
++ break;
++ case HCI_OP_Read_Buffer_Size:
++ printk("HCI_OP_Read_Buffer_Size");
++ break;
++ case HCI_OP_Host_Buffer_Size:
++ printk("HCI_OP_Host_Buffer_Size");
++ break;
++ case HCI_OP_Read_Local_Version_Information:
++ printk("HCI_OP_Read_Local_Version_Information");
++ break;
++ case HCI_OP_Read_BD_ADDR:
++ printk("HCI_OP_Read_BD_ADDR");
++ break;
++ case HCI_OP_Read_Local_Supported_Commands:
++ printk("HCI_OP_Read_Local_Supported_Commands");
++ break;
++ case HCI_OP_Write_Scan_Enable:
++ printk("HCI_OP_Write_Scan_Enable");
++ break;
++ case HCI_OP_Write_Current_IAC_LAP:
++ printk("HCI_OP_Write_Current_IAC_LAP");
++ break;
++ case HCI_OP_Write_Inquiry_Scan_Activity:
++ printk("HCI_OP_Write_Inquiry_Scan_Activity");
++ break;
++ case HCI_OP_Write_Class_of_Device:
++ printk("HCI_OP_Write_Class_of_Device");
++ break;
++ case HCI_OP_LE_Rand:
++ printk("HCI_OP_LE_Rand");
++ break;
++ case HCI_OP_LE_Set_Random_Address:
++ printk("HCI_OP_LE_Set_Random_Address");
++ break;
++ case HCI_OP_LE_Set_Extended_Scan_Enable:
++ printk("HCI_OP_LE_Set_Extended_Scan_Enable");
++ break;
++ case HCI_OP_LE_Set_Extended_Scan_Parameters:
++ printk("HCI_OP_LE_Set_Extended_Scan_Parameters");
++ break;
++ case HCI_OP_Set_Event_Filter:
++ printk("HCI_OP_Set_Event_Filter");
++ break;
++ case HCI_OP_Write_Voice_Setting:
++ printk("HCI_OP_Write_Voice_Setting");
++ break;
++ case HCI_OP_Change_Local_Name:
++ printk("HCI_OP_Change_Local_Name");
++ break;
++ case HCI_OP_Read_Local_Name:
++ printk("HCI_OP_Read_Local_Name");
++ break;
++ case HCI_OP_Wirte_Page_Timeout:
++ printk("HCI_OP_Wirte_Page_Timeout");
++ break;
++ case HCI_OP_LE_Clear_Resolving_List:
++ printk("HCI_OP_LE_Clear_Resolving_List");
++ break;
++ case HCI_OP_LE_Set_Addres_Resolution_Enable_Command:
++ printk("HCI_OP_LE_Set_Addres_Resolution_Enable_Command");
++ break;
++ case HCI_OP_Write_Inquiry_mode:
++ printk("HCI_OP_Write_Inquiry_mode");
++ break;
++ case HCI_OP_Write_Page_Scan_Type:
++ printk("HCI_OP_Write_Page_Scan_Type");
++ break;
++ case HCI_OP_Write_Inquiry_Scan_Type:
++ printk("HCI_OP_Write_Inquiry_Scan_Type");
++ break;
++ case HCI_OP_Delete_Stored_Link_Key:
++ printk("HCI_OP_Delete_Stored_Link_Key");
++ break;
++ case HCI_OP_LE_Read_Local_Resolvable_Address:
++ printk("HCI_OP_LE_Read_Local_Resolvable_Address");
++ break;
++ case HCI_OP_LE_Extended_Create_Connection:
++ printk("HCI_OP_LE_Extended_Create_Connection");
++ break;
++ case HCI_OP_Read_Remote_Version_Information:
++ printk("HCI_OP_Read_Remote_Version_Information");
++ break;
++ case HCI_OP_LE_Start_Encryption:
++ printk("HCI_OP_LE_Start_Encryption");
++ break;
++ case HCI_OP_LE_Add_Device_to_Resolving_List:
++ printk("HCI_OP_LE_Add_Device_to_Resolving_List");
++ break;
++ case HCI_OP_LE_Set_Privacy_Mode:
++ printk("HCI_OP_LE_Set_Privacy_Mode");
++ break;
++ case HCI_OP_LE_Connection_Update:
++ printk("HCI_OP_LE_Connection_Update");
++ break;
++ default:
++ printk("UNKNOW_HCI_COMMAND");
++ break;
++ }
++#endif //CONFIG_BLUEDROID
++}
++
++static void print_command(struct sk_buff *skb)
++{
++#if PRINT_CMD_EVENT
++ print_error_command(skb);
++#endif
++}
++
++
++enum CODEC_TYPE{
++ CODEC_CVSD,
++ CODEC_MSBC,
++};
++
++static enum CODEC_TYPE codec_type = CODEC_CVSD;
++static void set_select_msbc(enum CODEC_TYPE type);
++static enum CODEC_TYPE check_select_msbc(void);
++
++
++#if CONFIG_BLUEDROID
++
++/* Global parameters for bt usb char driver */
++#define BT_CHAR_DEVICE_NAME "aicbt_dev"
++struct mutex btchr_mutex;
++static struct sk_buff_head btchr_readq;
++static wait_queue_head_t btchr_read_wait;
++static wait_queue_head_t bt_dlfw_wait;
++static int bt_char_dev_registered;
++static dev_t bt_devid; /* bt char device number */
++static struct cdev bt_char_dev; /* bt character device structure */
++static struct class *bt_char_class; /* device class for usb char driver */
++static int bt_reset = 0;
++
++/* HCI device & lock */
++DEFINE_RWLOCK(hci_dev_lock);
++struct hci_dev *ghdev = NULL;
++
++#ifdef CONFIG_SUPPORT_VENDOR_APCF
++static int bypass_event(struct sk_buff *skb)
++{
++ int ret = 0;
++ u8 *opcode = (u8*)(skb->data);
++ //u8 len = *(opcode+1);
++ u16 sub_opcpde;
++
++ switch(*opcode) {
++ case HCI_EV_CMD_COMPLETE:
++ sub_opcpde = ((u16)opcode[3]|(u16)(opcode[4])<<8);
++ if(sub_opcpde == 0xfd57){
++ if(vendor_apcf_sent_done){
++ vendor_apcf_sent_done--;
++ printk("apcf bypass\r\n");
++ ret = 1;
++ }
++ }
++ break;
++ default:
++ break;
++ }
++ return ret;
++}
++#endif//CONFIG_SUPPORT_VENDOR_APCF
++static void print_event(struct sk_buff *skb)
++{
++#if PRINT_CMD_EVENT
++ //uint wlength = skb->len;
++ //uint icount = 0;
++ u8 *opcode = (u8*)(skb->data);
++ //u8 len = *(opcode+1);
++
++ printk("aic %s ", __func__);
++ switch (*opcode) {
++ case HCI_EV_INQUIRY_COMPLETE:
++ printk("HCI_EV_INQUIRY_COMPLETE");
++ break;
++ case HCI_EV_INQUIRY_RESULT:
++ printk("HCI_EV_INQUIRY_RESULT");
++ break;
++ case HCI_EV_CONN_COMPLETE:
++ printk("HCI_EV_CONN_COMPLETE");
++ break;
++ case HCI_EV_CONN_REQUEST:
++ printk("HCI_EV_CONN_REQUEST");
++ break;
++ case HCI_EV_DISCONN_COMPLETE:
++ printk("HCI_EV_DISCONN_COMPLETE");
++ break;
++ case HCI_EV_AUTH_COMPLETE:
++ printk("HCI_EV_AUTH_COMPLETE");
++ break;
++ case HCI_EV_REMOTE_NAME:
++ printk("HCI_EV_REMOTE_NAME");
++ break;
++ case HCI_EV_ENCRYPT_CHANGE:
++ printk("HCI_EV_ENCRYPT_CHANGE");
++ break;
++ case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
++ printk("HCI_EV_CHANGE_LINK_KEY_COMPLETE");
++ break;
++ case HCI_EV_REMOTE_FEATURES:
++ printk("HCI_EV_REMOTE_FEATURES");
++ break;
++ case HCI_EV_REMOTE_VERSION:
++ printk("HCI_EV_REMOTE_VERSION");
++ break;
++ case HCI_EV_QOS_SETUP_COMPLETE:
++ printk("HCI_EV_QOS_SETUP_COMPLETE");
++ break;
++ case HCI_EV_CMD_COMPLETE:
++ printk("HCI_EV_CMD_COMPLETE");
++ break;
++ case HCI_EV_CMD_STATUS:
++ printk("HCI_EV_CMD_STATUS");
++ break;
++ case HCI_EV_ROLE_CHANGE:
++ printk("HCI_EV_ROLE_CHANGE");
++ break;
++ case HCI_EV_NUM_COMP_PKTS:
++ printk("HCI_EV_NUM_COMP_PKTS");
++ break;
++ case HCI_EV_MODE_CHANGE:
++ printk("HCI_EV_MODE_CHANGE");
++ break;
++ case HCI_EV_PIN_CODE_REQ:
++ printk("HCI_EV_PIN_CODE_REQ");
++ break;
++ case HCI_EV_LINK_KEY_REQ:
++ printk("HCI_EV_LINK_KEY_REQ");
++ break;
++ case HCI_EV_LINK_KEY_NOTIFY:
++ printk("HCI_EV_LINK_KEY_NOTIFY");
++ break;
++ case HCI_EV_CLOCK_OFFSET:
++ printk("HCI_EV_CLOCK_OFFSET");
++ break;
++ case HCI_EV_PKT_TYPE_CHANGE:
++ printk("HCI_EV_PKT_TYPE_CHANGE");
++ break;
++ case HCI_EV_PSCAN_REP_MODE:
++ printk("HCI_EV_PSCAN_REP_MODE");
++ break;
++ case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
++ printk("HCI_EV_INQUIRY_RESULT_WITH_RSSI");
++ break;
++ case HCI_EV_REMOTE_EXT_FEATURES:
++ printk("HCI_EV_REMOTE_EXT_FEATURES");
++ break;
++ case HCI_EV_SYNC_CONN_COMPLETE:
++ printk("HCI_EV_SYNC_CONN_COMPLETE");
++ break;
++ case HCI_EV_SYNC_CONN_CHANGED:
++ printk("HCI_EV_SYNC_CONN_CHANGED");
++ break;
++ case HCI_EV_SNIFF_SUBRATE:
++ printk("HCI_EV_SNIFF_SUBRATE");
++ break;
++ case HCI_EV_EXTENDED_INQUIRY_RESULT:
++ printk("HCI_EV_EXTENDED_INQUIRY_RESULT");
++ break;
++ case HCI_EV_IO_CAPA_REQUEST:
++ printk("HCI_EV_IO_CAPA_REQUEST");
++ break;
++ case HCI_EV_SIMPLE_PAIR_COMPLETE:
++ printk("HCI_EV_SIMPLE_PAIR_COMPLETE");
++ break;
++ case HCI_EV_REMOTE_HOST_FEATURES:
++ printk("HCI_EV_REMOTE_HOST_FEATURES");
++ break;
++ default:
++ printk("unknow event");
++ break;
++ }
++ printk("\n");
++#if 0
++ printk("%02x,len:%d,", *opcode,len);
++ for (icount = 2; (icount < wlength) && (icount < 24); icount++)
++ printk("%02x ", *(opcode+icount));
++ printk("\n");
++#endif
++#endif
++}
++
++static inline ssize_t usb_put_user(struct sk_buff *skb,
++ char __user *buf, int count)
++{
++ char __user *ptr = buf;
++ int len = min_t(unsigned int, skb->len, count);
++
++ if (copy_to_user(ptr, skb->data, len))
++ return -EFAULT;
++
++ return len;
++}
++
++static struct sk_buff *aic_skb_queue[QUEUE_SIZE];
++static int aic_skb_queue_front = 0;
++static int aic_skb_queue_rear = 0;
++
++static void aic_enqueue(struct sk_buff *skb)
++{
++ spin_lock(&queue_lock);
++ if (aic_skb_queue_front == (aic_skb_queue_rear + 1) % QUEUE_SIZE) {
++ /*
++ * If queue is full, current solution is to drop
++ * the following entries.
++ */
++ AICBT_WARN("%s: Queue is full, entry will be dropped", __func__);
++ } else {
++ aic_skb_queue[aic_skb_queue_rear] = skb;
++
++ aic_skb_queue_rear++;
++ aic_skb_queue_rear %= QUEUE_SIZE;
++
++ }
++ spin_unlock(&queue_lock);
++}
++
++static struct sk_buff *aic_dequeue_try(unsigned int deq_len)
++{
++ struct sk_buff *skb;
++ struct sk_buff *skb_copy;
++
++ if (aic_skb_queue_front == aic_skb_queue_rear) {
++ AICBT_WARN("%s: Queue is empty", __func__);
++ return NULL;
++ }
++
++ skb = aic_skb_queue[aic_skb_queue_front];
++ if (deq_len >= skb->len) {
++
++ aic_skb_queue_front++;
++ aic_skb_queue_front %= QUEUE_SIZE;
++
++ /*
++ * Return skb addr to be dequeued, and the caller
++ * should free the skb eventually.
++ */
++ return skb;
++ } else {
++ skb_copy = pskb_copy(skb, GFP_ATOMIC);
++ skb_pull(skb, deq_len);
++ /* Return its copy to be freed */
++ return skb_copy;
++ }
++}
++
++static inline int is_queue_empty(void)
++{
++ return (aic_skb_queue_front == aic_skb_queue_rear) ? 1 : 0;
++}
++
++static void aic_clear_queue(void)
++{
++ struct sk_buff *skb;
++ spin_lock(&queue_lock);
++ while(!is_queue_empty()) {
++ skb = aic_skb_queue[aic_skb_queue_front];
++ aic_skb_queue[aic_skb_queue_front] = NULL;
++ aic_skb_queue_front++;
++ aic_skb_queue_front %= QUEUE_SIZE;
++ if (skb) {
++ kfree_skb(skb);
++ }
++ }
++ spin_unlock(&queue_lock);
++}
++
++/*
++ * AicSemi - Integrate from hci_core.c
++ */
++
++/* Get HCI device by index.
++ * Device is held on return. */
++static struct hci_dev *hci_dev_get(int index)
++{
++ if (index != 0)
++ return NULL;
++
++ return ghdev;
++}
++
++/* ---- HCI ioctl helpers ---- */
++static int hci_dev_open(__u16 dev)
++{
++ struct hci_dev *hdev;
++ int ret = 0;
++
++ AICBT_DBG("%s: dev %d", __func__, dev);
++
++ hdev = hci_dev_get(dev);
++ if (!hdev) {
++ AICBT_ERR("%s: Failed to get hci dev[Null]", __func__);
++ return -ENODEV;
++ }
++
++ if (test_bit(HCI_UNREGISTER, &hdev->dev_flags)) {
++ ret = -ENODEV;
++ goto done;
++ }
++
++ if (test_bit(HCI_UP, &hdev->flags)) {
++ ret = -EALREADY;
++ goto done;
++ }
++
++done:
++ return ret;
++}
++
++static int hci_dev_do_close(struct hci_dev *hdev)
++{
++ if (hdev->flush)
++ hdev->flush(hdev);
++ /* After this point our queues are empty
++ * and no tasks are scheduled. */
++ hdev->close(hdev);
++ /* Clear flags */
++ hdev->flags = 0;
++ return 0;
++}
++
++static int hci_dev_close(__u16 dev)
++{
++ struct hci_dev *hdev;
++ int err;
++ hdev = hci_dev_get(dev);
++ if (!hdev) {
++ AICBT_ERR("%s: failed to get hci dev[Null]", __func__);
++ return -ENODEV;
++ }
++
++ err = hci_dev_do_close(hdev);
++
++ return err;
++}
++
++#ifdef CONFIG_SCO_OVER_HCI
++/* copy data from the URB buffer into the ALSA ring buffer */
++static bool aic_copy_capture_data_to_alsa(struct btusb_data *data, uint8_t* p_data, unsigned int frames)
++{
++ struct snd_pcm_runtime *runtime;
++ unsigned int frame_bytes, frames1;
++ u8 *dest;
++ AIC_sco_card_t *pSCOSnd = data->pSCOSnd;
++
++ runtime = pSCOSnd->capture.substream->runtime;
++ frame_bytes = 2;
++
++ dest = runtime->dma_area + pSCOSnd->capture.buffer_pos * frame_bytes;
++ if (pSCOSnd->capture.buffer_pos + frames <= runtime->buffer_size) {
++ memcpy(dest, p_data, frames * frame_bytes);
++ } else {
++ /* wrap around at end of ring buffer */
++ frames1 = runtime->buffer_size - pSCOSnd->capture.buffer_pos;
++ memcpy(dest, p_data, frames1 * frame_bytes);
++ memcpy(runtime->dma_area,
++ p_data + frames1 * frame_bytes,
++ (frames - frames1) * frame_bytes);
++ }
++
++ pSCOSnd->capture.buffer_pos += frames;
++ if (pSCOSnd->capture.buffer_pos >= runtime->buffer_size) {
++ pSCOSnd->capture.buffer_pos -= runtime->buffer_size;
++ }
++
++ if((pSCOSnd->capture.buffer_pos%runtime->period_size) == 0) {
++ snd_pcm_period_elapsed(pSCOSnd->capture.substream);
++ }
++
++ return false;
++}
++
++
++static void hci_send_to_alsa_ringbuffer(struct hci_dev *hdev, struct sk_buff *skb)
++{
++ struct btusb_data *data = GET_DRV_DATA(hdev);
++ AIC_sco_card_t *pSCOSnd = data->pSCOSnd;
++ uint8_t* p_data;
++ int sco_length = skb->len - HCI_SCO_HDR_SIZE;
++ u16 *handle = (u16 *) (skb->data);
++ //u8 errflg = (u8)((*handle & 0x3000) >> 12);
++
++ pSCOSnd->usb_data->sco_handle = (*handle & 0x0fff);
++
++ AICBT_DBG("%s, %x, %x %x\n", __func__,pSCOSnd->usb_data->sco_handle, *handle, errflg);
++
++ if (!hdev) {
++ AICBT_INFO("%s: Frame for unknown HCI device", __func__);
++ return;
++ }
++
++ if (!test_bit(ALSA_CAPTURE_RUNNING, &pSCOSnd->states)) {
++ AICBT_INFO("%s: ALSA is not running", __func__);
++ return;
++ }
++ snd_cap_timer.snd_sco_length = sco_length;
++ p_data = (uint8_t *)skb->data + HCI_SCO_HDR_SIZE;
++ aic_copy_capture_data_to_alsa(data, p_data, sco_length/2);
++}
++
++#endif
++
++#if CONFIG_BLUEDROID
++static struct hci_dev *hci_alloc_dev(void)
++{
++ struct hci_dev *hdev;
++
++ hdev = kzalloc(sizeof(struct hci_dev), GFP_KERNEL);
++ if (!hdev)
++ return NULL;
++
++ return hdev;
++}
++
++/* Free HCI device */
++static void hci_free_dev(struct hci_dev *hdev)
++{
++ kfree(hdev);
++}
++
++/* Register HCI device */
++static int hci_register_dev(struct hci_dev *hdev)
++{
++ int i, id;
++
++ AICBT_DBG("%s: %p name %s bus %d", __func__, hdev, hdev->name, hdev->bus);
++ /* Do not allow HCI_AMP devices to register at index 0,
++ * so the index can be used as the AMP controller ID.
++ */
++ id = (hdev->dev_type == HCI_BREDR) ? 0 : 1;
++
++ write_lock(&hci_dev_lock);
++
++ sprintf(hdev->name, "hci%d", id);
++ hdev->id = id;
++ hdev->flags = 0;
++ hdev->dev_flags = 0;
++ mutex_init(&hdev->lock);
++
++ AICBT_DBG("%s: id %d, name %s", __func__, hdev->id, hdev->name);
++
++
++ for (i = 0; i < NUM_REASSEMBLY; i++)
++ hdev->reassembly[i] = NULL;
++
++ memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
++ atomic_set(&hdev->promisc, 0);
++
++ if (ghdev) {
++ write_unlock(&hci_dev_lock);
++ AICBT_ERR("%s: Hci device has been registered already", __func__);
++ return -1;
++ } else
++ ghdev = hdev;
++
++ write_unlock(&hci_dev_lock);
++
++ return id;
++}
++
++/* Unregister HCI device */
++static void hci_unregister_dev(struct hci_dev *hdev)
++{
++ int i;
++
++ AICBT_DBG("%s: hdev %p name %s bus %d", __func__, hdev, hdev->name, hdev->bus);
++ set_bit(HCI_UNREGISTER, &hdev->dev_flags);
++
++ write_lock(&hci_dev_lock);
++ ghdev = NULL;
++ write_unlock(&hci_dev_lock);
++
++ hci_dev_do_close(hdev);
++ for (i = 0; i < NUM_REASSEMBLY; i++)
++ kfree_skb(hdev->reassembly[i]);
++}
++
++static void hci_send_to_stack(struct hci_dev *hdev, struct sk_buff *skb)
++{
++ struct sk_buff *aic_skb_copy = NULL;
++
++ //AICBT_DBG("%s", __func__);
++
++ if (!hdev) {
++ AICBT_ERR("%s: Frame for unknown HCI device", __func__);
++ return;
++ }
++
++ if (!test_bit(HCI_RUNNING, &hdev->flags)) {
++ AICBT_ERR("%s: HCI not running", __func__);
++ return;
++ }
++
++ aic_skb_copy = pskb_copy(skb, GFP_ATOMIC);
++ if (!aic_skb_copy) {
++ AICBT_ERR("%s: Copy skb error", __func__);
++ return;
++ }
++
++ memcpy(skb_push(aic_skb_copy, 1), &bt_cb(skb)->pkt_type, 1);
++ aic_enqueue(aic_skb_copy);
++
++ /* Make sure bt char device existing before wakeup read queue */
++ hdev = hci_dev_get(0);
++ if (hdev) {
++ //AICBT_DBG("%s: Try to wakeup read queue", __func__);
++ AICBT_DBG("%s", __func__);
++ wake_up_interruptible(&btchr_read_wait);
++ }
++
++
++ return;
++}
++
++/* Receive frame from HCI drivers */
++static int hci_recv_frame(struct sk_buff *skb)
++{
++ struct hci_dev *hdev = (struct hci_dev *) skb->dev;
++
++ if (!hdev ||
++ (!test_bit(HCI_UP, &hdev->flags) && !test_bit(HCI_INIT, &hdev->flags))) {
++ kfree_skb(skb);
++ return -ENXIO;
++ }
++
++ /* Incomming skb */
++ bt_cb(skb)->incoming = 1;
++
++ /* Time stamp */
++ __net_timestamp(skb);
++
++ if (atomic_read(&hdev->promisc)) {
++#ifdef CONFIG_SCO_OVER_HCI
++ if(bt_cb(skb)->pkt_type == HCI_SCODATA_PKT){
++ hci_send_to_alsa_ringbuffer(hdev, skb);
++ }else{
++#ifdef CONFIG_SUPPORT_VENDOR_APCF
++ if(bt_cb(skb)->pkt_type == HCI_EVENT_PKT){
++ if(bypass_event(skb)){
++ kfree_skb(skb);
++ return 0;
++ }
++ }
++#endif //CONFIG_SUPPORT_VENDOR_APCF
++ hci_send_to_stack(hdev, skb);
++ }
++#else
++#ifdef CONFIG_SUPPORT_VENDOR_APCF
++ if(bt_cb(skb)->pkt_type == HCI_EVENT_PKT){
++ if(bypass_event(skb)){
++ kfree_skb(skb);
++ return 0;
++ }
++ }
++#endif //CONFIG_SUPPORT_VENDOR_APCF
++ /* Send copy to the sockets */
++ hci_send_to_stack(hdev, skb);
++#endif
++
++ }
++
++ kfree_skb(skb);
++ return 0;
++}
++
++
++
++static int hci_reassembly(struct hci_dev *hdev, int type, void *data,
++ int count, __u8 index)
++{
++ int len = 0;
++ int hlen = 0;
++ int remain = count;
++ struct sk_buff *skb;
++ struct bt_skb_cb *scb;
++
++ //AICBT_DBG("%s", __func__);
++
++ if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) ||
++ index >= NUM_REASSEMBLY)
++ return -EILSEQ;
++
++ skb = hdev->reassembly[index];
++
++ if (!skb) {
++ switch (type) {
++ case HCI_ACLDATA_PKT:
++ len = HCI_MAX_FRAME_SIZE;
++ hlen = HCI_ACL_HDR_SIZE;
++ break;
++ case HCI_EVENT_PKT:
++ len = HCI_MAX_EVENT_SIZE;
++ hlen = HCI_EVENT_HDR_SIZE;
++ break;
++ case HCI_SCODATA_PKT:
++ len = HCI_MAX_SCO_SIZE;
++ hlen = HCI_SCO_HDR_SIZE;
++ break;
++ }
++
++ skb = bt_skb_alloc(len, GFP_ATOMIC);
++ if (!skb)
++ return -ENOMEM;
++
++ scb = (void *) skb->cb;
++ scb->expect = hlen;
++ scb->pkt_type = type;
++
++ skb->dev = (void *) hdev;
++ hdev->reassembly[index] = skb;
++ }
++
++ while (count) {
++ scb = (void *) skb->cb;
++ len = min_t(uint, scb->expect, count);
++
++ memcpy(skb_put(skb, len), data, len);
++
++ count -= len;
++ data += len;
++ scb->expect -= len;
++ remain = count;
++
++ switch (type) {
++ case HCI_EVENT_PKT:
++ if (skb->len == HCI_EVENT_HDR_SIZE) {
++ struct hci_event_hdr *h = hci_event_hdr(skb);
++ scb->expect = h->plen;
++
++ if (skb_tailroom(skb) < scb->expect) {
++ kfree_skb(skb);
++ hdev->reassembly[index] = NULL;
++ return -ENOMEM;
++ }
++ }
++ break;
++
++ case HCI_ACLDATA_PKT:
++ if (skb->len == HCI_ACL_HDR_SIZE) {
++ struct hci_acl_hdr *h = hci_acl_hdr(skb);
++ scb->expect = __le16_to_cpu(h->dlen);
++
++ if (skb_tailroom(skb) < scb->expect) {
++ kfree_skb(skb);
++ hdev->reassembly[index] = NULL;
++ return -ENOMEM;
++ }
++ }
++ break;
++
++ case HCI_SCODATA_PKT:
++ if (skb->len == HCI_SCO_HDR_SIZE) {
++ struct hci_sco_hdr *h = hci_sco_hdr(skb);
++ scb->expect = h->dlen;
++
++ if (skb_tailroom(skb) < scb->expect) {
++ kfree_skb(skb);
++ hdev->reassembly[index] = NULL;
++ return -ENOMEM;
++ }
++ }
++ break;
++ }
++
++ if (scb->expect == 0) {
++ /* Complete frame */
++ if(HCI_ACLDATA_PKT == type)
++ print_acl(skb,0);
++ if(HCI_SCODATA_PKT == type)
++ print_sco(skb,0);
++ if(HCI_EVENT_PKT == type)
++ print_event(skb);
++
++ bt_cb(skb)->pkt_type = type;
++ hci_recv_frame(skb);
++
++ hdev->reassembly[index] = NULL;
++ return remain;
++ }
++ }
++
++ return remain;
++}
++
++static int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count)
++{
++ int rem = 0;
++
++ if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT)
++ return -EILSEQ;
++
++ while (count) {
++ rem = hci_reassembly(hdev, type, data, count, type - 1);
++ if (rem < 0)
++ return rem;
++
++ data += (count - rem);
++ count = rem;
++ }
++
++ return rem;
++}
++#endif //CONFIG_BLUEDROID
++
++void hci_hardware_error(void)
++{
++ struct sk_buff *aic_skb_copy = NULL;
++ int len = 3;
++ uint8_t hardware_err_pkt[4] = {HCI_EVENT_PKT, 0x10, 0x01, HCI_VENDOR_USB_DISC_HARDWARE_ERROR};
++
++ aic_skb_copy = alloc_skb(len, GFP_ATOMIC);
++ if (!aic_skb_copy) {
++ AICBT_ERR("%s: Failed to allocate mem", __func__);
++ return;
++ }
++
++ memcpy(skb_put(aic_skb_copy, len), hardware_err_pkt, len);
++ aic_enqueue(aic_skb_copy);
++
++ wake_up_interruptible(&btchr_read_wait);
++}
++
++static int btchr_open(struct inode *inode_p, struct file *file_p)
++{
++ struct btusb_data *data;
++ struct hci_dev *hdev;
++
++ AICBT_DBG("%s: BT usb char device is opening", __func__);
++ /* Not open unless wanna tracing log */
++ /* trace_printk("%s: open....\n", __func__); */
++
++ hdev = hci_dev_get(0);
++ if (!hdev) {
++ AICBT_DBG("%s: Failed to get hci dev[NULL]", __func__);
++ return -ENODEV;
++ }
++ data = GET_DRV_DATA(hdev);
++
++ atomic_inc(&hdev->promisc);
++ /*
++ * As bt device is not re-opened when hotplugged out, we cannot
++ * trust on file's private data(may be null) when other file ops
++ * are invoked.
++ */
++ file_p->private_data = data;
++
++ mutex_lock(&btchr_mutex);
++ hci_dev_open(0);
++ mutex_unlock(&btchr_mutex);
++
++ aic_clear_queue();
++ return nonseekable_open(inode_p, file_p);
++}
++
++static int btchr_close(struct inode *inode_p, struct file *file_p)
++{
++ struct btusb_data *data;
++ struct hci_dev *hdev;
++
++ AICBT_INFO("%s: BT usb char device is closing", __func__);
++ /* Not open unless wanna tracing log */
++ /* trace_printk("%s: close....\n", __func__); */
++
++ data = file_p->private_data;
++ file_p->private_data = NULL;
++
++#if CONFIG_BLUEDROID
++ /*
++ * If the upper layer closes bt char interfaces, no reset
++ * action required even bt device hotplugged out.
++ */
++ bt_reset = 0;
++#endif
++
++ hdev = hci_dev_get(0);
++ if (hdev) {
++ atomic_set(&hdev->promisc, 0);
++ mutex_lock(&btchr_mutex);
++ hci_dev_close(0);
++ mutex_unlock(&btchr_mutex);
++ }
++
++ return 0;
++}
++
++static ssize_t btchr_read(struct file *file_p,
++ char __user *buf_p,
++ size_t count,
++ loff_t *pos_p)
++{
++ struct hci_dev *hdev;
++ struct sk_buff *skb;
++ ssize_t ret = 0;
++
++ while (count) {
++ hdev = hci_dev_get(0);
++ if (!hdev) {
++ /*
++ * Note: Only when BT device hotplugged out, we wil get
++ * into such situation. In order to keep the upper layer
++ * stack alive (blocking the read), we should never return
++ * EFAULT or break the loop.
++ */
++ AICBT_ERR("%s: Failed to get hci dev[Null]", __func__);
++ }
++
++ ret = wait_event_interruptible(btchr_read_wait, !is_queue_empty());
++ if (ret < 0) {
++ AICBT_ERR("%s: wait event is signaled %d", __func__, (int)ret);
++ break;
++ }
++
++ skb = aic_dequeue_try(count);
++ if (skb) {
++ ret = usb_put_user(skb, buf_p, count);
++ if (ret < 0)
++ AICBT_ERR("%s: Failed to put data to user space", __func__);
++ kfree_skb(skb);
++ break;
++ }
++ }
++
++ return ret;
++}
++
++#ifdef CONFIG_SUPPORT_VENDOR_APCF
++void btchr_external_write(char* buff, int len){
++ struct hci_dev *hdev;
++ struct sk_buff *skb;
++ int i;
++ struct btusb_data *data;
++
++ AICBT_INFO("%s \r\n", __func__);
++ for(i=0;i<len;i++){
++ printk("0x%x ",(u8)buff[i]);
++ }
++ printk("\r\n");
++ hdev = hci_dev_get(0);
++ if (!hdev) {
++ AICBT_WARN("%s: Failed to get hci dev[Null]", __func__);
++ return;
++ }
++ /* Never trust on btusb_data, as bt device may be hotplugged out */
++ data = GET_DRV_DATA(hdev);
++ if (!data) {
++ AICBT_WARN("%s: Failed to get bt usb driver data[Null]", __func__);
++ return;
++ }
++ vendor_apcf_sent_done++;
++
++ skb = bt_skb_alloc(len, GFP_ATOMIC);
++ if (!skb)
++ return;
++ skb_reserve(skb, -1); // Add this line
++ skb->dev = (void *)hdev;
++ memcpy((__u8 *)skb->data,(__u8 *)buff,len);
++ skb_put(skb, len);
++ bt_cb(skb)->pkt_type = *((__u8 *)skb->data);
++ skb_pull(skb, 1);
++ data->hdev->send(skb);
++}
++
++EXPORT_SYMBOL(btchr_external_write);
++#endif //CONFIG_SUPPORT_VENDOR_APCF
++
++static ssize_t btchr_write(struct file *file_p,
++ const char __user *buf_p,
++ size_t count,
++ loff_t *pos_p)
++{
++ struct btusb_data *data = file_p->private_data;
++ struct hci_dev *hdev;
++ struct sk_buff *skb;
++
++ //AICBT_DBG("%s: BT usb char device is writing", __func__);
++ AICBT_DBG("%s", __func__);
++
++ hdev = hci_dev_get(0);
++ if (!hdev) {
++ AICBT_WARN("%s: Failed to get hci dev[Null]", __func__);
++ /*
++ * Note: we bypass the data from the upper layer if bt device
++ * is hotplugged out. Fortunatelly, H4 or H5 HCI stack does
++ * NOT check btchr_write's return value. However, returning
++ * count instead of EFAULT is preferable.
++ */
++ /* return -EFAULT; */
++ return count;
++ }
++
++ /* Never trust on btusb_data, as bt device may be hotplugged out */
++ data = GET_DRV_DATA(hdev);
++ if (!data) {
++ AICBT_WARN("%s: Failed to get bt usb driver data[Null]", __func__);
++ return count;
++ }
++
++ if (count > HCI_MAX_FRAME_SIZE)
++ return -EINVAL;
++
++ skb = bt_skb_alloc(count, GFP_ATOMIC);
++ if (!skb)
++ return -ENOMEM;
++ skb_reserve(skb, -1); // Add this line
++
++ if (copy_from_user(skb_put(skb, count), buf_p, count)) {
++ AICBT_ERR("%s: Failed to get data from user space", __func__);
++ kfree_skb(skb);
++ return -EFAULT;
++ }
++
++ skb->dev = (void *)hdev;
++ bt_cb(skb)->pkt_type = *((__u8 *)skb->data);
++ skb_pull(skb, 1);
++ data->hdev->send(skb);
++
++ return count;
++}
++
++static unsigned int btchr_poll(struct file *file_p, poll_table *wait)
++{
++ struct btusb_data *data = file_p->private_data;
++ struct hci_dev *hdev;
++
++ //AICBT_DBG("%s: BT usb char device is polling", __func__);
++
++ if(!bt_char_dev_registered) {
++ AICBT_ERR("%s: char device has not registered!", __func__);
++ return POLLERR | POLLHUP;
++ }
++
++ poll_wait(file_p, &btchr_read_wait, wait);
++
++ hdev = hci_dev_get(0);
++ if (!hdev) {
++ AICBT_ERR("%s: Failed to get hci dev[Null]", __func__);
++ mdelay(URB_CANCELING_DELAY_MS);
++ return POLLERR | POLLHUP;
++ return POLLOUT | POLLWRNORM;
++ }
++
++ /* Never trust on btusb_data, as bt device may be hotplugged out */
++ data = GET_DRV_DATA(hdev);
++ if (!data) {
++ /*
++ * When bt device is hotplugged out, btusb_data will
++ * be freed in disconnect.
++ */
++ AICBT_ERR("%s: Failed to get bt usb driver data[Null]", __func__);
++ mdelay(URB_CANCELING_DELAY_MS);
++ return POLLOUT | POLLWRNORM;
++ }
++
++ if (!is_queue_empty())
++ return POLLIN | POLLRDNORM;
++
++ return POLLOUT | POLLWRNORM;
++}
++static long btchr_ioctl(struct file *file_p,unsigned int cmd, unsigned long arg)
++{
++ int ret = 0;
++ struct hci_dev *hdev;
++ struct btusb_data *data;
++ firmware_info *fw_info;
++
++ if(!bt_char_dev_registered) {
++ return -ENODEV;
++ }
++
++ if(check_set_dlfw_state_value(1) != 1) {
++ AICBT_ERR("%s bt controller is disconnecting!", __func__);
++ return 0;
++ }
++
++ hdev = hci_dev_get(0);
++ if(!hdev) {
++ AICBT_ERR("%s device is NULL!", __func__);
++ set_dlfw_state_value(0);
++ return 0;
++ }
++ data = GET_DRV_DATA(hdev);
++ fw_info = data->fw_info;
++
++ AICBT_INFO(" btchr_ioctl DOWN_FW_CFG with Cmd:%d",cmd);
++ switch (cmd) {
++ case DOWN_FW_CFG:
++ AICBT_INFO(" btchr_ioctl DOWN_FW_CFG");
++ ret = usb_autopm_get_interface(data->intf);
++ if (ret < 0){
++ goto failed;
++ }
++
++ //ret = download_patch(fw_info,1);
++ usb_autopm_put_interface(data->intf);
++ if(ret < 0){
++ AICBT_ERR("%s:Failed in download_patch with ret:%d",__func__,ret);
++ goto failed;
++ }
++
++ ret = hdev->open(hdev);
++ if(ret < 0){
++ AICBT_ERR("%s:Failed in hdev->open(hdev):%d",__func__,ret);
++ goto failed;
++ }
++ set_bit(HCI_UP, &hdev->flags);
++ set_dlfw_state_value(0);
++ wake_up_interruptible(&bt_dlfw_wait);
++ return 1;
++ case DWFW_CMPLT:
++ AICBT_INFO(" btchr_ioctl DWFW_CMPLT");
++#if 1
++ case SET_ISO_CFG:
++ AICBT_INFO("btchr_ioctl SET_ISO_CFG");
++ if(copy_from_user(&(hdev->voice_setting), (__u16*)arg, sizeof(__u16))){
++ AICBT_INFO(" voice settings err");
++ }
++ //hdev->voice_setting = *(uint16_t*)arg;
++ AICBT_INFO(" voice settings = %d", hdev->voice_setting);
++ //return 1;
++#endif
++ case GET_USB_INFO:
++ //ret = download_patch(fw_info,1);
++ AICBT_INFO(" btchr_ioctl GET_USB_INFO");
++ ret = hdev->open(hdev);
++ if(ret < 0){
++ AICBT_ERR("%s:Failed in hdev->open(hdev):%d",__func__,ret);
++ //goto done;
++ }
++ set_bit(HCI_UP, &hdev->flags);
++ set_dlfw_state_value(0);
++ wake_up_interruptible(&bt_dlfw_wait);
++ return 1;
++ case RESET_CONTROLLER:
++ AICBT_INFO(" btchr_ioctl RESET_CONTROLLER");
++ //reset_controller(fw_info);
++ return 1;
++ default:
++ AICBT_ERR("%s:Failed with wrong Cmd:%d",__func__,cmd);
++ goto failed;
++ }
++ failed:
++ set_dlfw_state_value(0);
++ wake_up_interruptible(&bt_dlfw_wait);
++ return ret;
++
++}
++
++#ifdef CONFIG_PLATFORM_UBUNTU//AIDEN
++typedef u32 compat_uptr_t;
++static inline void __user *compat_ptr(compat_uptr_t uptr)
++{
++ return (void __user *)(unsigned long)uptr;
++}
++#endif
++
++#ifdef CONFIG_COMPAT
++static long compat_btchr_ioctl (struct file *filp, unsigned int cmd, unsigned long arg)
++{
++ AICBT_DBG("%s: enter",__func__);
++ return btchr_ioctl(filp, cmd, (unsigned long) compat_ptr(arg));
++}
++#endif
++static struct file_operations bt_chrdev_ops = {
++ open : btchr_open,
++ release : btchr_close,
++ read : btchr_read,
++ write : btchr_write,
++ poll : btchr_poll,
++ unlocked_ioctl : btchr_ioctl,
++#ifdef CONFIG_COMPAT
++ compat_ioctl : compat_btchr_ioctl,
++#endif
++};
++
++static int btchr_init(void)
++{
++ int res = 0;
++ struct device *dev;
++
++ AICBT_INFO("Register usb char device interface for BT driver");
++ /*
++ * btchr mutex is used to sync between
++ * 1) downloading patch and opening bt char driver
++ * 2) the file operations of bt char driver
++ */
++ mutex_init(&btchr_mutex);
++
++ skb_queue_head_init(&btchr_readq);
++ init_waitqueue_head(&btchr_read_wait);
++ init_waitqueue_head(&bt_dlfw_wait);
++
++ bt_char_class = class_create(THIS_MODULE, BT_CHAR_DEVICE_NAME);
++ if (IS_ERR(bt_char_class)) {
++ AICBT_ERR("Failed to create bt char class");
++ return PTR_ERR(bt_char_class);
++ }
++
++ res = alloc_chrdev_region(&bt_devid, 0, 1, BT_CHAR_DEVICE_NAME);
++ if (res < 0) {
++ AICBT_ERR("Failed to allocate bt char device");
++ goto err_alloc;
++ }
++
++ dev = device_create(bt_char_class, NULL, bt_devid, NULL, BT_CHAR_DEVICE_NAME);
++ if (IS_ERR(dev)) {
++ AICBT_ERR("Failed to create bt char device");
++ res = PTR_ERR(dev);
++ goto err_create;
++ }
++
++ cdev_init(&bt_char_dev, &bt_chrdev_ops);
++ res = cdev_add(&bt_char_dev, bt_devid, 1);
++ if (res < 0) {
++ AICBT_ERR("Failed to add bt char device");
++ goto err_add;
++ }
++
++ return 0;
++
++err_add:
++ device_destroy(bt_char_class, bt_devid);
++err_create:
++ unregister_chrdev_region(bt_devid, 1);
++err_alloc:
++ class_destroy(bt_char_class);
++ return res;
++}
++
++static void btchr_exit(void)
++{
++ AICBT_INFO("Unregister usb char device interface for BT driver");
++
++ device_destroy(bt_char_class, bt_devid);
++ cdev_del(&bt_char_dev);
++ unregister_chrdev_region(bt_devid, 1);
++ class_destroy(bt_char_class);
++
++ return;
++}
++#endif
++
++int send_hci_cmd(firmware_info *fw_info)
++{
++
++ int len = 0;
++ int ret_val = -1;
++ int i = 0;
++
++ if(g_chipid == PRODUCT_ID_AIC8801 || g_chipid == PRODUCT_ID_AIC8800D80){
++ ret_val = usb_bulk_msg(fw_info->udev, fw_info->pipe_out, fw_info->send_pkt, fw_info->pkt_len,
++ &len, 3000);
++ if (ret_val || (len != fw_info->pkt_len)) {
++ AICBT_INFO("Error in send hci cmd = %d,"
++ "len = %d, size = %d", ret_val, len, fw_info->pkt_len);
++ }
++ }else if(g_chipid == PRODUCT_ID_AIC8800DC){
++ while((ret_val<0)&&(i++<3))
++ {
++ ret_val = usb_control_msg(
++ fw_info->udev, fw_info->pipe_out,
++ 0, USB_TYPE_CLASS, 0, 0,
++ (void *)(fw_info->send_pkt),
++ fw_info->pkt_len, MSG_TO);
++ }
++
++ }
++ return ret_val;
++
++}
++
++int rcv_hci_evt(firmware_info *fw_info)
++{
++ int ret_len = 0, ret_val = 0;
++ int i;
++
++ while (1) {
++ for(i = 0; i < 5; i++) {
++ ret_val = usb_interrupt_msg(
++ fw_info->udev, fw_info->pipe_in,
++ (void *)(fw_info->rcv_pkt), RCV_PKT_LEN,
++ &ret_len, MSG_TO);
++ if (ret_val >= 0)
++ break;
++ }
++
++ if (ret_val < 0)
++ return ret_val;
++
++ if (CMD_CMP_EVT == fw_info->evt_hdr->evt) {
++ if (fw_info->cmd_hdr->opcode == fw_info->cmd_cmp->opcode)
++ return ret_len;
++ }
++ }
++}
++
++int set_bt_onoff(firmware_info *fw_info, uint8_t onoff)
++{
++ int ret_val;
++
++ AICBT_INFO("%s: %s", __func__, onoff != 0 ? "on" : "off");
++
++ fw_info->cmd_hdr->opcode = cpu_to_le16(BTOFF_OPCODE);
++ fw_info->cmd_hdr->plen = 1;
++ fw_info->pkt_len = CMD_HDR_LEN + 1;
++ fw_info->send_pkt[CMD_HDR_LEN] = onoff;
++
++ ret_val = send_hci_cmd(fw_info);
++ if (ret_val < 0) {
++ AICBT_ERR("%s: Failed to send bt %s cmd, errno %d",
++ __func__, onoff != 0 ? "on" : "off", ret_val);
++ return ret_val;
++ }
++
++ ret_val = rcv_hci_evt(fw_info);
++ if (ret_val < 0) {
++ AICBT_ERR("%s: Failed to receive bt %s event, errno %d",
++ __func__, onoff != 0 ? "on" : "off", ret_val);
++ return ret_val;
++ }
++
++ return ret_val;
++}
++
++//for 8800DC start
++u32 fwcfg_tbl[][2] = {
++ {0x40200028, 0x0021047e},
++ {0x40200024, 0x0000011d},
++};
++
++int fw_config(firmware_info* fw_info)
++{
++ int ret_val = -1;
++ struct hci_dbg_rd_mem_cmd *rd_cmd;
++ struct hci_dbg_rd_mem_cmd_evt *evt_para;
++ int len = 0, i = 0;
++ struct fw_status *evt_status;
++
++ rd_cmd = (struct hci_dbg_rd_mem_cmd *)(fw_info->req_para);
++ if (!rd_cmd)
++ return -ENOMEM;
++
++ rd_cmd->start_addr = 0x40200024;
++ rd_cmd->type = 32;
++ rd_cmd->length = 4;
++ fw_info->cmd_hdr->opcode = cpu_to_le16(HCI_VSC_DBG_RD_MEM_CMD);
++ fw_info->cmd_hdr->plen = sizeof(struct hci_dbg_rd_mem_cmd);
++ fw_info->pkt_len = CMD_HDR_LEN + sizeof(struct hci_dbg_rd_mem_cmd);
++
++ ret_val = send_hci_cmd(fw_info);
++ if (ret_val < 0) {
++ printk("%s: Failed to send hci cmd 0x%04x, errno %d",
++ __func__, fw_info->cmd_hdr->opcode, ret_val);
++ return ret_val;
++ }
++
++ ret_val = rcv_hci_evt(fw_info);
++ if (ret_val < 0) {
++ printk("%s: Failed to receive hci event, errno %d",
++ __func__, ret_val);
++ return ret_val;
++ }
++
++ evt_para = (struct hci_dbg_rd_mem_cmd_evt *)(fw_info->rsp_para);
++
++ printk("%s: fw status = 0x%04x, length %d, %x %x %x %x",
++ __func__, evt_para->status, evt_para->length,
++ evt_para->data[0],
++ evt_para->data[1],
++ evt_para->data[2],
++ evt_para->data[3]);
++
++ ret_val = evt_para->status;
++ if (evt_para->status == 0) {
++ uint16_t rd_data = (evt_para->data[0] | (evt_para->data[1] << 8));
++ printk("%s rd_data is %x\n", __func__, rd_data);
++ if (rd_data == 0x119) {
++ struct aicbt_patch_table_cmd *patch_table_cmd = (struct aicbt_patch_table_cmd *)(fw_info->req_para);
++ len = sizeof(fwcfg_tbl) / sizeof(u32) / 2;
++ patch_table_cmd->patch_num = len;
++ for (i = 0; i < len; i++) {
++ memcpy(&patch_table_cmd->patch_table_addr[i], &fwcfg_tbl[i][0], sizeof(uint32_t));
++ memcpy(&patch_table_cmd->patch_table_data[i], &fwcfg_tbl[i][1], sizeof(uint32_t));
++ printk("%s [%d] data: %08x %08x\n", __func__, i, patch_table_cmd->patch_table_addr[i],patch_table_cmd->patch_table_data[i]);
++ }
++ fw_info->cmd_hdr->opcode = cpu_to_le16(HCI_VSC_UPDATE_PT_CMD);
++ fw_info->cmd_hdr->plen = HCI_VSC_UPDATE_PT_SIZE;
++ fw_info->pkt_len = fw_info->cmd_hdr->plen + 3;
++ ret_val = send_hci_cmd(fw_info);
++ if (ret_val < 0) {
++ AICBT_ERR("%s: rcv_hci_evt err %d", __func__, ret_val);
++ return ret_val;
++ }
++ ret_val = rcv_hci_evt(fw_info);
++ if (ret_val < 0) {
++ printk("%s: Failed to receive hci event, errno %d",
++ __func__, ret_val);
++ return ret_val;
++ }
++ evt_status = (struct fw_status *)fw_info->rsp_para;
++ ret_val = evt_status->status;
++ if (0 != evt_status->status) {
++ ret_val = -1;
++ } else {
++ ret_val = 0;
++ }
++
++ }
++ }
++ return ret_val;
++}
++
++int system_config(firmware_info *fw_info)
++{
++ int ret_val = -1;
++ struct hci_dbg_rd_mem_cmd *rd_cmd;
++ struct hci_dbg_rd_mem_cmd_evt *evt_para;
++ //int len = 0, i = 0;
++ //struct fw_status *evt_status;
++
++ rd_cmd = (struct hci_dbg_rd_mem_cmd *)(fw_info->req_para);
++ if (!rd_cmd)
++ return -ENOMEM;
++
++ rd_cmd->start_addr = 0x40500000;
++ rd_cmd->type = 32;
++ rd_cmd->length = 4;
++ fw_info->cmd_hdr->opcode = cpu_to_le16(HCI_VSC_DBG_RD_MEM_CMD);
++ fw_info->cmd_hdr->plen = sizeof(struct hci_dbg_rd_mem_cmd);
++ fw_info->pkt_len = CMD_HDR_LEN + sizeof(struct hci_dbg_rd_mem_cmd);
++
++ ret_val = send_hci_cmd(fw_info);
++ if (ret_val < 0)
++ {
++ printk("%s: Failed to send hci cmd 0x%04x, errno %d",
++ __func__, fw_info->cmd_hdr->opcode, ret_val);
++ return ret_val;
++ }
++
++ ret_val = rcv_hci_evt(fw_info);
++ if (ret_val < 0)
++ {
++ printk("%s: Failed to receive hci event, errno %d",
++ __func__, ret_val);
++ return ret_val;
++ }
++
++ evt_para = (struct hci_dbg_rd_mem_cmd_evt *)(fw_info->rsp_para);
++
++ printk("%s: fw status = 0x%04x, length %d, %x %x %x %x",
++ __func__, evt_para->status, evt_para->length,
++ evt_para->data[0],
++ evt_para->data[1],
++ evt_para->data[2],
++ evt_para->data[3]);
++
++ ret_val = evt_para->status;
++ if (evt_para->status == 0)
++ {
++ uint32_t rd_data = (evt_para->data[0] | (evt_para->data[1] << 8) | (evt_para->data[2] << 16) | (evt_para->data[3] << 24));
++ //printk("%s 0x40500000 rd_data is %x\n", __func__, rd_data);
++ chip_id = (u8) (rd_data >> 16);
++ }
++
++ rd_cmd->start_addr = 0x20;
++ rd_cmd->type = 32;
++ rd_cmd->length = 4;
++ fw_info->cmd_hdr->opcode = cpu_to_le16(HCI_VSC_DBG_RD_MEM_CMD);
++ fw_info->cmd_hdr->plen = sizeof(struct hci_dbg_rd_mem_cmd);
++ fw_info->pkt_len = CMD_HDR_LEN + sizeof(struct hci_dbg_rd_mem_cmd);
++
++ ret_val = send_hci_cmd(fw_info);
++ if (ret_val < 0)
++ {
++ printk("%s: Failed to send hci cmd 0x%04x, errno %d",
++ __func__, fw_info->cmd_hdr->opcode, ret_val);
++ return ret_val;
++ }
++
++ ret_val = rcv_hci_evt(fw_info);
++ if (ret_val < 0)
++ {
++ printk("%s: Failed to receive hci event, errno %d",
++ __func__, ret_val);
++ return ret_val;
++ }
++
++ evt_para = (struct hci_dbg_rd_mem_cmd_evt *)(fw_info->rsp_para);
++
++ printk("%s: fw status = 0x%04x, length %d, %x %x %x %x",
++ __func__, evt_para->status, evt_para->length,
++ evt_para->data[0],
++ evt_para->data[1],
++ evt_para->data[2],
++ evt_para->data[3]);
++
++ ret_val = evt_para->status;
++ if (evt_para->status == 0)
++ {
++ uint32_t rd_data = (evt_para->data[0] | (evt_para->data[1] << 8) | (evt_para->data[2] << 16) | (evt_para->data[3] << 24));
++ //printk("%s 0x02 rd_data is %x\n", __func__, rd_data);
++ sub_chip_id = (u8) (rd_data);
++ }
++ printk("chip_id = %x, sub_chip_id = %x\n", chip_id, sub_chip_id);
++ return ret_val;
++}
++
++int check_fw_status(firmware_info* fw_info)
++{
++ struct fw_status *read_ver_rsp;
++ int ret_val = -1;
++
++ fw_info->cmd_hdr->opcode = cpu_to_le16(HCI_VSC_FW_STATUS_GET_CMD);
++ fw_info->cmd_hdr->plen = 0;
++ fw_info->pkt_len = CMD_HDR_LEN;
++
++ ret_val = send_hci_cmd(fw_info);
++ if (ret_val < 0) {
++ printk("%s: Failed to send hci cmd 0x%04x, errno %d",
++ __func__, fw_info->cmd_hdr->opcode, ret_val);
++ return ret_val;
++ }
++
++ ret_val = rcv_hci_evt(fw_info);
++ if (ret_val < 0) {
++ printk("%s: Failed to receive hci event, errno %d",
++ __func__, ret_val);
++ return ret_val;
++ }
++
++ read_ver_rsp = (struct fw_status *)(fw_info->rsp_para);
++
++ printk("%s: fw status = 0x%04x",
++ __func__, read_ver_rsp->status);
++ return read_ver_rsp->status;
++}
++
++int download_data(firmware_info *fw_info, u32 fw_addr, char *filename)
++{
++ unsigned int i=0;
++ int size;
++ u8 *dst=NULL;
++ int err=0;
++ struct hci_dbg_wr_mem_cmd *dl_cmd;
++ int hdr_len = sizeof(__le32) + sizeof(__u8) + sizeof(__u8);
++ int data_len = HCI_VSC_MEM_WR_SIZE;
++ int frag_len = data_len + hdr_len;
++ int ret_val;
++ int ncmd = 1;
++ struct fw_status *evt_para;
++
++ /* load aic firmware */
++ size = aic_load_firmware(&dst, filename, NULL);
++ if(size <= 0){
++ printk("wrong size of firmware file\n");
++ vfree(dst);
++ dst = NULL;
++ return -1;
++ }
++
++ dl_cmd = (struct hci_dbg_wr_mem_cmd *)(fw_info->req_para);
++ if (!dl_cmd)
++ return -ENOMEM;
++ evt_para = (struct fw_status *)fw_info->rsp_para;
++
++ /* Copy the file on the Embedded side */
++ printk("### Upload %s firmware, @ = %x size=%d\n", filename, fw_addr, size);
++
++ if (size > HCI_VSC_MEM_WR_SIZE) {// > 1KB data
++ for (i = 0; i < (size - HCI_VSC_MEM_WR_SIZE); i += HCI_VSC_MEM_WR_SIZE) {//each time write 240 bytes
++ data_len = HCI_VSC_MEM_WR_SIZE;
++ frag_len = data_len + hdr_len;
++ memcpy(dl_cmd->data, dst + i, data_len);
++ dl_cmd->length = data_len;
++ dl_cmd->type = 32;
++ dl_cmd->start_addr = fw_addr + i;
++ fw_info->cmd_hdr->opcode = cpu_to_le16(DOWNLOAD_OPCODE);
++ fw_info->cmd_hdr->plen = frag_len;
++ fw_info->pkt_len = frag_len + 3;
++ #if 0
++ printk("[%d] data_len %d, src %x, dst %x\n", i, data_len, dst + i, fw_addr + i);
++ printk("%p , %d\n", dl_cmd, fw_info->pkt_len);
++ print_hex_dump(KERN_ERR,"payload:",DUMP_PREFIX_NONE,16,1,dl_cmd->data,32,false);
++ /* Send download command */
++ print_hex_dump(KERN_ERR,"data:",DUMP_PREFIX_NONE,16,1,fw_info->send_pkt,32,false);
++ #endif
++ ret_val = send_hci_cmd(fw_info);
++
++ while (ncmd > 0) {
++ ret_val = rcv_hci_evt(fw_info);
++ printk("rcv_hci_evt %d\n", ret_val);
++ if (ret_val < 0) {
++ AICBT_ERR("%s: rcv_hci_evt err %d", __func__, ret_val);
++ goto out;
++ } else {
++ AICBT_DBG("%s: Receive acked frag num %d", __func__, evt_para->status);
++ ncmd--;
++ }
++ if (0 != evt_para->status) {
++ AICBT_ERR("%s: Receive acked frag num %d, err status %d",
++ __func__, ret_val, evt_para->status);
++ ret_val = -1;
++ goto out;
++ } else {
++ ret_val = 0;
++ }
++ }
++ ncmd = 1;
++ }
++ }
++
++ if (!err && (i < size)) {// <1KB data
++ data_len = size - i;
++ frag_len = data_len + hdr_len;
++ memcpy(dl_cmd->data, dst + i, data_len);
++ dl_cmd->length = data_len;
++ dl_cmd->type = 32;
++ dl_cmd->start_addr = fw_addr + i;
++ fw_info->cmd_hdr->opcode = cpu_to_le16(DOWNLOAD_OPCODE);
++ fw_info->cmd_hdr->plen = frag_len;
++ fw_info->pkt_len = frag_len + 3;
++ ret_val = send_hci_cmd(fw_info);
++ //printk("(%d) data_len %d, src %x, dst %x\n", i, data_len, (dst + i), fw_addr + i);
++ //printk("%p , %d\n", dl_cmd, fw_info->pkt_len);
++ while (ncmd > 0) {
++ ret_val = rcv_hci_evt(fw_info);
++ if (ret_val < 0) {
++ AICBT_ERR("%s: rcv_hci_evt err %d", __func__, ret_val);
++ goto out;
++ } else {
++ AICBT_DBG("%s: Receive acked frag num %d", __func__, evt_para->status);
++ ncmd--;
++ }
++ if (0 != evt_para->status) {
++ AICBT_ERR("%s: Receive acked frag num %d, err status %d",
++ __func__, ret_val, evt_para->status);
++ ret_val = -1;
++ goto out;
++ } else {
++ ret_val = 0;
++ }
++ }
++ ncmd = 0;
++ }
++
++out:
++ if (dst) {
++ vfree(dst);
++ dst = NULL;
++ }
++
++ printk("fw download complete\n\n");
++ return ret_val;
++
++}
++
++
++struct aicbt_info_t {
++ uint32_t btmode;
++ uint32_t btport;
++ uint32_t uart_baud;
++ uint32_t uart_flowctrl;
++ uint32_t lpm_enable;
++ uint32_t txpwr_lvl;
++};
++
++struct aicbsp_info_t {
++ int hwinfo;
++ uint32_t cpmode;
++};
++
++enum aicbsp_cpmode_type {
++ AICBSP_CPMODE_WORK,
++ AICBSP_CPMODE_TEST,
++};
++
++/* btmode
++ * used for force bt mode,if not AICBSP_MODE_NULL
++ * efuse valid and vendor_info will be invalid, even has beed set valid
++*/
++enum aicbt_btmode_type {
++ AICBT_BTMODE_BT_ONLY_SW = 0x0, // bt only mode with switch
++ AICBT_BTMODE_BT_WIFI_COMBO, // wifi/bt combo mode
++ AICBT_BTMODE_BT_ONLY, // bt only mode without switch
++ AICBT_BTMODE_BT_ONLY_TEST, // bt only test mode
++ AICBT_BTMODE_BT_WIFI_COMBO_TEST, // wifi/bt combo test mode
++ AICBT_MODE_NULL = 0xFF, // invalid value
++};
++
++enum aicbt_btport_type {
++ AICBT_BTPORT_NULL,
++ AICBT_BTPORT_MB,
++ AICBT_BTPORT_UART,
++};
++
++enum aicbt_uart_baud_type {
++ AICBT_UART_BAUD_115200 = 115200,
++ AICBT_UART_BAUD_921600 = 921600,
++ AICBT_UART_BAUD_1_5M = 1500000,
++ AICBT_UART_BAUD_3_25M = 3250000,
++};
++
++enum aicbt_uart_flowctrl_type {
++ AICBT_UART_FLOWCTRL_DISABLE = 0x0, // uart without flow ctrl
++ AICBT_UART_FLOWCTRL_ENABLE, // uart with flow ctrl
++};
++
++#define AICBSP_HWINFO_DEFAULT (-1)
++#define AICBSP_CPMODE_DEFAULT AICBSP_CPMODE_WORK
++#define AICBT_TXPWR_DFT 0x6F2F
++
++
++#define AICBT_BTMODE_DEFAULT AICBT_BTMODE_BT_WIFI_COMBO
++#define AICBT_BTPORT_DEFAULT AICBT_BTPORT_MB
++#define AICBT_UART_BAUD_DEFAULT AICBT_UART_BAUD_1_5M
++#define AICBT_UART_FC_DEFAULT AICBT_UART_FLOWCTRL_ENABLE
++#define AICBT_LPM_ENABLE_DEFAULT 0
++#define AICBT_TXPWR_LVL_DEFAULT AICBT_TXPWR_DFT
++
++struct aicbsp_info_t aicbsp_info = {
++ .hwinfo = AICBSP_HWINFO_DEFAULT,
++ .cpmode = AICBSP_CPMODE_DEFAULT,
++};
++
++#ifndef CONFIG_USE_FW_REQUEST
++#define FW_PATH_MAX 200
++
++char aic_fw_path[FW_PATH_MAX];
++#if (CONFIG_BLUEDROID == 0)
++static const char* aic_default_fw_path = "/lib/firmware/aic8800DC";
++#else
++static const char* aic_default_fw_path = "/vendor/etc/firmware";
++#endif
++#endif //CONFIG_USE_FW_REQUEST
++
++static struct aicbt_info_t aicbt_info = {
++ .btmode = AICBT_BTMODE_DEFAULT,
++ .btport = AICBT_BTPORT_DEFAULT,
++ .uart_baud = AICBT_UART_BAUD_DEFAULT,
++ .uart_flowctrl = AICBT_UART_FC_DEFAULT,
++ .lpm_enable = AICBT_LPM_ENABLE_DEFAULT,
++ .txpwr_lvl = AICBT_TXPWR_LVL_DEFAULT,
++};
++
++int patch_table_load(firmware_info *fw_info, struct aicbt_patch_table *_head)
++{
++ struct aicbt_patch_table *head, *p;
++ int i;
++ uint32_t *data = NULL;
++ struct aicbt_patch_table_cmd *patch_table_cmd = (struct aicbt_patch_table_cmd *)(fw_info->req_para);
++ struct fw_status *evt_para;
++ int ret_val = 0;
++ int ncmd = 1;
++ uint32_t len = 0;
++ uint32_t tot_len = 0;
++ head = _head;
++ for (p = head; p != NULL; p = p->next) {
++ data = p->data;
++ if(AICBT_PT_BTMODE == p->type){
++ *(data + 1) = aicbsp_info.hwinfo < 0;
++ *(data + 3) = aicbsp_info.hwinfo;
++ *(data + 5) = aicbsp_info.cpmode;
++
++ *(data + 7) = aicbt_info.btmode;
++ *(data + 9) = aicbt_info.btport;
++ *(data + 11) = aicbt_info.uart_baud;
++ *(data + 13) = aicbt_info.uart_flowctrl;
++ *(data + 15) = aicbt_info.lpm_enable;
++ *(data + 17) = aicbt_info.txpwr_lvl;
++
++ }
++ if (p->type == AICBT_PT_NULL || p->type == AICBT_PT_PWRON) {
++ continue;
++ }
++ if (p->type == AICBT_PT_VER) {
++ char *data_s = (char *)p->data;
++ printk("patch version %s\n", data_s);
++ continue;
++ }
++ if (p->len == 0) {
++ printk("len is 0\n");
++ continue;
++ }
++ tot_len = p->len;
++ while (tot_len) {
++ if (tot_len > HCI_PT_MAX_LEN) {
++ len = HCI_PT_MAX_LEN;
++ } else {
++ len = tot_len;
++ }
++ for (i = 0; i < len; i++) {
++ patch_table_cmd->patch_num = len;
++ memcpy(&patch_table_cmd->patch_table_addr[i], data, sizeof(uint32_t));
++ memcpy(&patch_table_cmd->patch_table_data[i], data + 1, sizeof(uint32_t));
++ printk("[%d] data: %08x %08x\n", i, patch_table_cmd->patch_table_addr[i],patch_table_cmd->patch_table_data[i]);
++ data += 2;
++ }
++ tot_len -= len;
++ evt_para = (struct fw_status *)fw_info->rsp_para;
++ //print_hex_dump(KERN_ERR,"data0:",DUMP_PREFIX_NONE,16,1,patch_table_cmd,sizeof(struct aicbt_patch_table_cmd),false);
++
++ //printk("patch num %x %d\n", patch_table_cmd->patch_num, sizeof(struct aicbt_patch_table_cmd));
++ fw_info->cmd_hdr->opcode = cpu_to_le16(HCI_VSC_UPDATE_PT_CMD);
++ fw_info->cmd_hdr->plen = HCI_VSC_UPDATE_PT_SIZE;
++ fw_info->pkt_len = fw_info->cmd_hdr->plen + 3;
++ AICBT_DBG("patch num 0x%x, plen 0x%x\n", patch_table_cmd->patch_num, fw_info->cmd_hdr->plen );
++ //print_hex_dump(KERN_ERR,"patch table:",DUMP_PREFIX_NONE,16,1,fw_info->send_pkt,32,false);
++ ret_val = send_hci_cmd(fw_info);
++ while (ncmd > 0) {
++ ret_val = rcv_hci_evt(fw_info);
++ if (ret_val < 0) {
++ AICBT_ERR("%s: rcv_hci_evt err %d", __func__, ret_val);
++ goto out;
++ } else {
++ AICBT_DBG("%s: Receive acked frag num %d", __func__, evt_para->status);
++ ncmd--;
++ }
++ if (0 != evt_para->status) {
++ AICBT_ERR("%s: Receive acked frag num %d, err status %d",
++ __func__, ret_val, evt_para->status);
++ ret_val = -1;
++ goto out;
++ }
++ }
++ ncmd = 1;
++ }
++ }
++out:
++ aicbt_patch_table_free(&head);
++ return ret_val;
++}
++
++int aic_load_firmware(u8 ** fw_buf, const char *name, struct device *device)
++{
++
++#ifdef CONFIG_USE_FW_REQUEST
++ const struct firmware *fw = NULL;
++ u32 *dst = NULL;
++ void *buffer=NULL;
++ int size = 0;
++ int ret = 0;
++
++ printk("%s: request firmware = %s \n", __func__ ,name);
++
++
++ ret = request_firmware(&fw, name, NULL);
++
++ if (ret < 0) {
++ printk("Load %s fail\n", name);
++ release_firmware(fw);
++ return -1;
++ }
++
++ size = fw->size;
++ dst = (u32 *)fw->data;
++
++ if (size <= 0) {
++ printk("wrong size of firmware file\n");
++ release_firmware(fw);
++ return -1;
++ }
++
++
++ buffer = vmalloc(size);
++ memset(buffer, 0, size);
++ memcpy(buffer, dst, size);
++
++ *fw_buf = buffer;
++
++ release_firmware(fw);
++
++ return size;
++
++#else
++ u8 *buffer=NULL;
++ char *path=NULL;
++ struct file *fp=NULL;
++ int size = 0, len=0;
++ ssize_t rdlen=0;
++
++ /* get the firmware path */
++ path = __getname();
++ if (!path){
++ *fw_buf=NULL;
++ return -1;
++ }
++
++ if (strlen(aic_fw_path) > 0) {
++ printk("%s: use customer define fw_path\n", __func__);
++ len = snprintf(path, FW_PATH_MAX, "%s/%s", aic_fw_path, name);
++ } else {
++ len = snprintf(path, FW_PATH_MAX, "%s/%s",aic_default_fw_path, name);
++ }
++
++ if (len >= FW_PATH_MAX) {
++ printk("%s: %s file's path too long\n", __func__, name);
++ *fw_buf=NULL;
++ __putname(path);
++ return -1;
++ }
++
++ printk("%s :firmware path = %s \n", __func__ ,path);
++
++
++ /* open the firmware file */
++ fp=filp_open(path, O_RDONLY, 0);
++ if(IS_ERR(fp) || (!fp)){
++ printk("%s: %s file failed to open\n", __func__, name);
++ if(IS_ERR(fp))
++ printk("is_Err\n");
++ if((!fp))
++ printk("null\n");
++ *fw_buf=NULL;
++ __putname(path);
++ fp=NULL;
++ return -1;
++ }
++
++ size = i_size_read(file_inode(fp));
++ if(size<=0){
++ printk("%s: %s file size invalid %d\n", __func__, name, size);
++ *fw_buf=NULL;
++ __putname(path);
++ filp_close(fp,NULL);
++ fp=NULL;
++ return -1;
++}
++
++ /* start to read from firmware file */
++ buffer = vmalloc(size);
++ memset(buffer, 0, size);
++ if(!buffer){
++ *fw_buf=NULL;
++ __putname(path);
++ filp_close(fp,NULL);
++ fp=NULL;
++ return -1;
++ }
++
++
++ #if LINUX_VERSION_CODE > KERNEL_VERSION(4, 13, 16)
++ rdlen = kernel_read(fp, buffer, size, &fp->f_pos);
++ #else
++ rdlen = kernel_read(fp, fp->f_pos, buffer, size);
++ #endif
++
++ if(size != rdlen){
++ printk("%s: %s file rdlen invalid %d %d\n", __func__, name, (int)rdlen, size);
++ *fw_buf=NULL;
++ __putname(path);
++ filp_close(fp,NULL);
++ fp=NULL;
++ vfree(buffer);
++ buffer=NULL;
++ return -1;
++ }
++ if(rdlen > 0){
++ fp->f_pos += rdlen;
++ //printk("f_pos=%d\n", (int)fp->f_pos);
++ }
++ *fw_buf = buffer;
++
++#if 0
++ MD5Init(&md5);
++ MD5Update(&md5, (unsigned char *)dst, size);
++ MD5Final(&md5, decrypt);
++
++ printk(MD5PINRT, MD5(decrypt));
++
++#endif
++ return size;
++#endif
++}
++
++int aicbt_patch_table_free(struct aicbt_patch_table **head)
++{
++ struct aicbt_patch_table *p = *head, *n = NULL;
++ while (p) {
++ n = p->next;
++ kfree(p->name);
++ kfree(p->data);
++ kfree(p);
++ p = n;
++ }
++ *head = NULL;
++ return 0;
++}
++
++int get_patch_addr_from_patch_table(firmware_info *fw_info, char *filename, uint32_t *fw_patch_base_addr)
++{
++ int size;
++ int ret = 0;
++ uint8_t *rawdata=NULL;
++ uint8_t *p = NULL;
++ uint32_t *data = NULL;
++ uint32_t type = 0, len = 0;
++ int j;
++
++ /* load aic firmware */
++ size = aic_load_firmware((u8 **)&rawdata, filename, NULL);
++
++ /* Copy the file on the Embedded side */
++ printk("### Upload %s fw_patch_table, size=%d\n", filename, size);
++
++ if (size <= 0) {
++ printk("wrong size of firmware file\n");
++ ret = -1;
++ goto err;
++ }
++
++ p = rawdata;
++
++ if (memcmp(p, AICBT_PT_TAG, sizeof(AICBT_PT_TAG) < 16 ? sizeof(AICBT_PT_TAG) : 16)) {
++ printk("TAG err\n");
++ ret = -1;
++ goto err;
++ }
++ p += 16;
++
++ while (p - rawdata < size) {
++ printk("size = %d p - rawdata = 0x%0lx \r\n", size, p - rawdata);
++ p += 16;
++
++ type = *(uint32_t *)p;
++ p += 4;
++
++ len = *(uint32_t *)p;
++ p += 4;
++ printk("cur->type %x, len %d\n", type, len);
++
++ if(type >= 1000 ) {//Temp Workaround
++ len = 0;
++ }else{
++ data = (uint32_t *)p;
++ if (type == AICBT_PT_NULL) {
++ *(fw_patch_base_addr) = *(data + 3);
++ printk("addr found %x\n", *(fw_patch_base_addr));
++ for (j = 0; j < len; j++) {
++ printk("addr %x\n", *(data+j));
++ }
++ break;
++ }
++ p += len * 8;
++ }
++ }
++
++ vfree(rawdata);
++ return ret;
++err:
++ //aicbt_patch_table_free(&head);
++
++ if (rawdata){
++ vfree(rawdata);
++ }
++ return ret;
++}
++
++
++
++int patch_table_download(firmware_info *fw_info, char *filename)
++{
++ struct aicbt_patch_table *head = NULL;
++ struct aicbt_patch_table *new = NULL;
++ struct aicbt_patch_table *cur = NULL;
++ int size;
++ int ret = 0;
++ uint8_t *rawdata=NULL;
++ uint8_t *p = NULL;
++
++ /* load aic firmware */
++ size = aic_load_firmware((u8 **)&rawdata, filename, NULL);
++
++ /* Copy the file on the Embedded side */
++ printk("### Upload %s fw_patch_table, size=%d\n", filename, size);
++
++ if (size <= 0) {
++ printk("wrong size of firmware file\n");
++ ret = -1;
++ goto err;
++ }
++
++ p = rawdata;
++
++ if (memcmp(p, AICBT_PT_TAG, sizeof(AICBT_PT_TAG) < 16 ? sizeof(AICBT_PT_TAG) : 16)) {
++ printk("TAG err\n");
++ ret = -1;
++ goto err;
++ }
++ p += 16;
++
++ while (p - rawdata < size) {
++ printk("size = %d p - rawdata = 0x%0lx \r\n", size, p - rawdata);
++ new = (struct aicbt_patch_table *)kmalloc(sizeof(struct aicbt_patch_table), GFP_KERNEL);
++ memset(new, 0, sizeof(struct aicbt_patch_table));
++ if (head == NULL) {
++ head = new;
++ cur = new;
++ } else {
++ cur->next = new;
++ cur = cur->next;
++ }
++
++ cur->name = (char *)kmalloc(sizeof(char) * 16, GFP_KERNEL);
++ memset(cur->name, 0, sizeof(char) * 16);
++ memcpy(cur->name, p, 16);
++ p += 16;
++
++ cur->type = *(uint32_t *)p;
++ p += 4;
++
++ cur->len = *(uint32_t *)p;
++ p += 4;
++ printk("cur->type %x, len %d\n", cur->type, cur->len);
++
++ if((cur->type ) >= 1000 ) {//Temp Workaround
++ cur->len = 0;
++ }else{
++ cur->data = (uint32_t *)kmalloc(sizeof(uint8_t) * cur->len * 8, GFP_KERNEL);
++ memset(cur->data, 0, sizeof(uint8_t) * cur->len * 8);
++ memcpy(cur->data, p, cur->len * 8);
++ p += cur->len * 8;
++ }
++ }
++
++ vfree(rawdata);
++ patch_table_load(fw_info, head);
++ printk("fw_patch_table download complete\n\n");
++
++ return ret;
++err:
++ //aicbt_patch_table_free(&head);
++
++ if (rawdata){
++ vfree(rawdata);
++ }
++ return ret;
++}
++
++
++int download_patch(firmware_info *fw_info, int cached)
++{
++ int ret_val = 0;
++
++ printk("%s: Download fw patch start, cached %d", __func__, cached);
++
++ if (!fw_info) {
++ printk("%s: No patch entry exists(fw_info %p)", __func__, fw_info);
++ ret_val = -1;
++ goto end;
++ }
++
++ ret_val = fw_config(fw_info);
++ if (ret_val) {
++ printk("%s: fw config failed %d", __func__, ret_val);
++ goto free;
++ }
++
++ ret_val = system_config(fw_info);
++ if (ret_val)
++ {
++ printk("%s: system config failed %d", __func__, ret_val);
++ goto free;
++ }
++
++ /*
++ * step1: check firmware statis
++ * step2: download firmware if updated
++ */
++
++
++ ret_val = check_fw_status(fw_info);
++
++
++ if (ret_val) {
++ #if 0
++ ret_val = download_data(fw_info, FW_RAM_ADID_BASE_ADDR, FW_ADID_BASE_NAME);
++ if (ret_val) {
++ printk("aic load adid fail %d\n", ret_val);
++ goto free;
++ }
++ #endif
++ if (sub_chip_id == 0) {
++ ret_val= download_data(fw_info, FW_RAM_PATCH_BASE_ADDR, FW_PATCH_BASE_NAME);
++ if (ret_val) {
++ printk("aic load patch fail %d\n", ret_val);
++ goto free;
++ }
++
++ ret_val= patch_table_download(fw_info, FW_PATCH_TABLE_NAME);
++ if (ret_val) {
++ printk("aic load patch ftable ail %d\n", ret_val);
++ goto free;
++ }
++ } else if (sub_chip_id == 1) {
++ uint32_t fw_ram_patch_base_addr = FW_RAM_PATCH_BASE_ADDR;
++
++ ret_val = get_patch_addr_from_patch_table(fw_info, FW_PATCH_TABLE_NAME_U02, &fw_ram_patch_base_addr);
++ if (ret_val)
++ {
++ printk("aic get patch addr fail %d\n", ret_val);
++ goto free;
++ }
++ printk("%s %x\n", __func__, fw_ram_patch_base_addr);
++ ret_val = download_data(fw_info, fw_ram_patch_base_addr, FW_PATCH_BASE_NAME_U02);
++ if (ret_val)
++ {
++ printk("aic load patch fail %d\n", ret_val);
++ goto free;
++ }
++
++ ret_val = patch_table_download(fw_info, FW_PATCH_TABLE_NAME_U02);
++ if (ret_val)
++ {
++ printk("aic load patch ftable ail %d\n", ret_val);
++ goto free;
++ }
++ } else if (sub_chip_id == 2) {
++ uint32_t fw_ram_patch_base_addr = FW_RAM_PATCH_BASE_ADDR;
++
++ ret_val = get_patch_addr_from_patch_table(fw_info, FW_PATCH_TABLE_NAME_U02H, &fw_ram_patch_base_addr);
++ if (ret_val)
++ {
++ printk("aic get patch addr fail %d\n", ret_val);
++ goto free;
++ }
++ printk("U02H %s %x\n", __func__, fw_ram_patch_base_addr);
++ ret_val = download_data(fw_info, fw_ram_patch_base_addr, FW_PATCH_BASE_NAME_U02H);
++ if (ret_val)
++ {
++ printk("aic load patch fail %d\n", ret_val);
++ goto free;
++ }
++
++ ret_val = patch_table_download(fw_info, FW_PATCH_TABLE_NAME_U02H);
++ if (ret_val)
++ {
++ printk("aic load patch ftable ail %d\n", ret_val);
++ goto free;
++ }
++ } else {
++ printk("%s unsupported sub_chip_id %x\n", __func__, sub_chip_id);
++ }
++ }
++
++free:
++ /* Free fw data after download finished */
++ kfree(fw_info->fw_data);
++ fw_info->fw_data = NULL;
++
++end:
++ return ret_val;
++}
++
++//for 8800dc end
++
++firmware_info *firmware_info_init(struct usb_interface *intf)
++{
++ struct usb_device *udev = interface_to_usbdev(intf);
++ firmware_info *fw_info;
++
++ AICBT_DBG("%s: start", __func__);
++
++ fw_info = kzalloc(sizeof(*fw_info), GFP_KERNEL);
++ if (!fw_info)
++ return NULL;
++
++ fw_info->send_pkt = kzalloc(SEND_PKT_LEN, GFP_KERNEL);
++ if (!fw_info->send_pkt) {
++ kfree(fw_info);
++ return NULL;
++ }
++
++ fw_info->rcv_pkt = kzalloc(RCV_PKT_LEN, GFP_KERNEL);
++ if (!fw_info->rcv_pkt) {
++ kfree(fw_info->send_pkt);
++ kfree(fw_info);
++ return NULL;
++ }
++
++ fw_info->intf = intf;
++ fw_info->udev = udev;
++if(g_chipid == PRODUCT_ID_AIC8801 || g_chipid == PRODUCT_ID_AIC8800D80){
++ fw_info->pipe_in = usb_rcvbulkpipe(fw_info->udev, BULK_EP);
++ fw_info->pipe_out = usb_rcvbulkpipe(fw_info->udev, CTRL_EP);
++}else if(g_chipid == PRODUCT_ID_AIC8800DC){
++ fw_info->pipe_in = usb_rcvintpipe(fw_info->udev, INTR_EP);
++ fw_info->pipe_out = usb_sndctrlpipe(fw_info->udev, CTRL_EP);
++}
++ fw_info->cmd_hdr = (struct hci_command_hdr *)(fw_info->send_pkt);
++ fw_info->evt_hdr = (struct hci_event_hdr *)(fw_info->rcv_pkt);
++ fw_info->cmd_cmp = (struct hci_ev_cmd_complete *)(fw_info->rcv_pkt + EVT_HDR_LEN);
++ fw_info->req_para = fw_info->send_pkt + CMD_HDR_LEN;
++ fw_info->rsp_para = fw_info->rcv_pkt + EVT_HDR_LEN + CMD_CMP_LEN;
++
++#if BTUSB_RPM
++ AICBT_INFO("%s: Auto suspend is enabled", __func__);
++ usb_enable_autosuspend(udev);
++ pm_runtime_set_autosuspend_delay(&(udev->dev), 2000);
++#else
++ AICBT_INFO("%s: Auto suspend is disabled", __func__);
++ usb_disable_autosuspend(udev);
++#endif
++
++#if BTUSB_WAKEUP_HOST
++ device_wakeup_enable(&udev->dev);
++#endif
++
++ return fw_info;
++}
++
++
++void firmware_info_destroy(struct usb_interface *intf)
++{
++ firmware_info *fw_info;
++ struct usb_device *udev;
++ struct btusb_data *data;
++
++ udev = interface_to_usbdev(intf);
++ data = usb_get_intfdata(intf);
++
++ fw_info = data->fw_info;
++ if (!fw_info)
++ return;
++
++#if BTUSB_RPM
++ usb_disable_autosuspend(udev);
++#endif
++
++ /*
++ * In order to reclaim fw data mem, we free fw_data immediately
++ * after download patch finished instead of here.
++ */
++ kfree(fw_info->rcv_pkt);
++ kfree(fw_info->send_pkt);
++ kfree(fw_info);
++
++
++}
++
++static struct usb_driver btusb_driver;
++
++static struct usb_device_id btusb_table[] = {
++ #if 0
++ { .match_flags = USB_DEVICE_ID_MATCH_VENDOR |
++ USB_DEVICE_ID_MATCH_INT_INFO,
++ .idVendor = 0xa69d,
++ .bInterfaceClass = 0xe0,
++ .bInterfaceSubClass = 0x01,
++ .bInterfaceProtocol = 0x01 },
++ #endif
++ {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC, USB_PRODUCT_ID_AIC8801, 0xe0, 0x01,0x01)},
++ {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC, USB_PRODUCT_ID_AIC8800D80, 0xe0, 0x01,0x01)},
++ {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC, USB_PRODUCT_ID_AIC8800DC, 0xe0, 0x01,0x01)},
++ {}
++};
++
++MODULE_DEVICE_TABLE(usb, btusb_table);
++
++static int inc_tx(struct btusb_data *data)
++{
++ unsigned long flags;
++ int rv;
++
++ spin_lock_irqsave(&data->txlock, flags);
++ rv = test_bit(BTUSB_SUSPENDING, &data->flags);
++ if (!rv)
++ data->tx_in_flight++;
++ spin_unlock_irqrestore(&data->txlock, flags);
++
++ return rv;
++}
++
++void check_sco_event(struct urb *urb)
++{
++ u8* opcode = (u8*)(urb->transfer_buffer);
++ u8 status;
++ static uint16_t sco_handle = 0;
++ uint16_t handle;
++ u8 air_mode = 0;
++ struct hci_dev *hdev = urb->context;
++#ifdef CONFIG_SCO_OVER_HCI
++ struct btusb_data *data = GET_DRV_DATA(hdev);
++ AIC_sco_card_t *pSCOSnd = data->pSCOSnd;
++#endif
++
++ switch (*opcode) {
++ case HCI_EV_SYNC_CONN_COMPLETE:
++ AICBT_INFO("%s: HCI_EV_SYNC_CONN_COMPLETE(0x%02x)", __func__, *opcode);
++ status = *(opcode + 2);
++ sco_handle = *(opcode + 3) | *(opcode + 4) << 8;
++ air_mode = *(opcode + 18);
++ printk("%s status:%d,air_mode:%d \r\n", __func__, status,air_mode);
++ if (status == 0) {
++ hdev->conn_hash.sco_num++;
++ hdev->notify(hdev, 0);
++ //schedule_work(&data->work);
++ if (air_mode == 0x03) {
++ set_select_msbc(CODEC_MSBC);
++ }
++ }
++ break;
++ case HCI_EV_DISCONN_COMPLETE:
++ AICBT_INFO("%s: HCI_EV_DISCONN_COMPLETE(0x%02x)", __func__, *opcode);
++ status = *(opcode + 2);
++ handle = *(opcode + 3) | *(opcode + 4) << 8;
++ if (status == 0 && sco_handle == handle) {
++ hdev->conn_hash.sco_num--;
++ hdev->notify(hdev, 0);
++ set_select_msbc(CODEC_CVSD);
++ //schedule_work(&data->work);
++#ifdef CONFIG_SCO_OVER_HCI
++ if (test_bit(ALSA_CAPTURE_RUNNING, &pSCOSnd->states)) {
++ mod_timer(&snd_cap_timer.cap_timer,jiffies + msecs_to_jiffies(3));
++ }
++#endif
++ }
++ break;
++ default:
++ AICBT_DBG("%s: event 0x%02x", __func__, *opcode);
++ break;
++ }
++}
++
++#if (CONFIG_BLUEDROID == 0)
++#if HCI_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)
++static inline void btusb_free_frags(struct btusb_data *data)
++{
++ unsigned long flags;
++
++ spin_lock_irqsave(&data->rxlock, flags);
++
++ kfree_skb(data->evt_skb);
++ data->evt_skb = NULL;
++
++ kfree_skb(data->acl_skb);
++ data->acl_skb = NULL;
++
++ kfree_skb(data->sco_skb);
++ data->sco_skb = NULL;
++
++ spin_unlock_irqrestore(&data->rxlock, flags);
++}
++
++static int btusb_recv_intr(struct btusb_data *data, void *buffer, int count)
++{
++ struct sk_buff *skb;
++ int err = 0;
++
++ spin_lock(&data->rxlock);
++ skb = data->evt_skb;
++ //printk("%s count %d\n", __func__, count);
++
++#if 1
++ while (count) {
++ int len;
++
++ if (!skb) {
++ skb = bt_skb_alloc(HCI_MAX_EVENT_SIZE, GFP_ATOMIC);
++ if (!skb) {
++ err = -ENOMEM;
++ break;
++ }
++
++ bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
++ bt_cb(skb)->expect = HCI_EVENT_HDR_SIZE;
++ }
++
++ len = min_t(uint, bt_cb(skb)->expect, count);
++ memcpy(skb_put(skb, len), buffer, len);
++
++ count -= len;
++ buffer += len;
++ bt_cb(skb)->expect -= len;
++
++ if (skb->len == HCI_EVENT_HDR_SIZE) {
++ /* Complete event header */
++ bt_cb(skb)->expect = hci_event_hdr(skb)->plen;
++
++ if (skb_tailroom(skb) < bt_cb(skb)->expect) {
++ kfree_skb(skb);
++ skb = NULL;
++
++ err = -EILSEQ;
++ break;
++ }
++ }
++
++ if (bt_cb(skb)->expect == 0) {
++ /* Complete frame */
++ hci_recv_frame(data->hdev, skb);
++ skb = NULL;
++ }
++ }
++#endif
++
++ data->evt_skb = skb;
++ spin_unlock(&data->rxlock);
++
++ return err;
++}
++
++static int btusb_recv_bulk(struct btusb_data *data, void *buffer, int count)
++{
++ struct sk_buff *skb;
++ int err = 0;
++
++ spin_lock(&data->rxlock);
++ skb = data->acl_skb;
++
++ while (count) {
++ int len;
++
++ if (!skb) {
++ skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC);
++ if (!skb) {
++ err = -ENOMEM;
++ break;
++ }
++
++ bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
++ bt_cb(skb)->expect = HCI_ACL_HDR_SIZE;
++ }
++
++ len = min_t(uint, bt_cb(skb)->expect, count);
++ memcpy(skb_put(skb, len), buffer, len);
++
++ count -= len;
++ buffer += len;
++ bt_cb(skb)->expect -= len;
++
++ if (skb->len == HCI_ACL_HDR_SIZE) {
++ __le16 dlen = hci_acl_hdr(skb)->dlen;
++
++ /* Complete ACL header */
++ bt_cb(skb)->expect = __le16_to_cpu(dlen);
++
++ if (skb_tailroom(skb) < bt_cb(skb)->expect) {
++ kfree_skb(skb);
++ skb = NULL;
++
++ err = -EILSEQ;
++ break;
++ }
++ }
++
++ if (bt_cb(skb)->expect == 0) {
++ /* Complete frame */
++ hci_recv_frame(data->hdev, skb);
++ skb = NULL;
++ }
++ }
++
++ data->acl_skb = skb;
++ spin_unlock(&data->rxlock);
++
++ return err;
++}
++
++static int btusb_recv_isoc(struct btusb_data *data, void *buffer, int count)
++{
++ struct sk_buff *skb;
++ int err = 0;
++
++ spin_lock(&data->rxlock);
++ skb = data->sco_skb;
++
++ while (count) {
++ int len;
++
++ if (!skb) {
++ skb = bt_skb_alloc(HCI_MAX_SCO_SIZE, GFP_ATOMIC);
++ if (!skb) {
++ err = -ENOMEM;
++ break;
++ }
++
++ bt_cb(skb)->pkt_type = HCI_SCODATA_PKT;
++ bt_cb(skb)->expect = HCI_SCO_HDR_SIZE;
++ }
++
++ len = min_t(uint, bt_cb(skb)->expect, count);
++ memcpy(skb_put(skb, len), buffer, len);
++
++ count -= len;
++ buffer += len;
++ bt_cb(skb)->expect -= len;
++
++ if (skb->len == HCI_SCO_HDR_SIZE) {
++ /* Complete SCO header */
++ bt_cb(skb)->expect = hci_sco_hdr(skb)->dlen;
++
++ if (skb_tailroom(skb) < bt_cb(skb)->expect) {
++ kfree_skb(skb);
++ skb = NULL;
++
++ err = -EILSEQ;
++ break;
++ }
++ }
++
++ if (bt_cb(skb)->expect == 0) {
++ /* Complete frame */
++ hci_recv_frame(data->hdev, skb);
++ skb = NULL;
++ }
++ }
++
++ data->sco_skb = skb;
++ spin_unlock(&data->rxlock);
++
++ return err;
++}
++#endif
++#endif // (CONFIG_BLUEDROID == 0)
++
++
++static void btusb_intr_complete(struct urb *urb)
++{
++ struct hci_dev *hdev = urb->context;
++ struct btusb_data *data = GET_DRV_DATA(hdev);
++ int err;
++
++ AICBT_DBG("%s: urb %p status %d count %d ", __func__,
++ urb, urb->status, urb->actual_length);
++
++ if (!test_bit(HCI_RUNNING, &hdev->flags)) {
++ printk("%s return \n", __func__);
++ return;
++ }
++ if (urb->status == 0) {
++ hdev->stat.byte_rx += urb->actual_length;
++
++#if (CONFIG_BLUEDROID) || (HCI_VERSION_CODE < KERNEL_VERSION(3, 18, 0))
++ if (hci_recv_fragment(hdev, HCI_EVENT_PKT,
++ urb->transfer_buffer,
++ urb->actual_length) < 0) {
++ AICBT_ERR("%s: Corrupted event packet", __func__);
++ hdev->stat.err_rx++;
++ }
++#else
++ if (btusb_recv_intr(data, urb->transfer_buffer,
++ urb->actual_length) < 0) {
++ AICBT_ERR("%s corrupted event packet", hdev->name);
++ hdev->stat.err_rx++;
++ }
++#endif
++
++#ifdef CONFIG_SCO_OVER_HCI
++ check_sco_event(urb);
++#endif
++#ifdef CONFIG_USB_AIC_UART_SCO_DRIVER
++ check_sco_event(urb);
++#endif
++
++ }
++ /* Avoid suspend failed when usb_kill_urb */
++ else if(urb->status == -ENOENT) {
++ return;
++ }
++
++
++ if (!test_bit(BTUSB_INTR_RUNNING, &data->flags))
++ return;
++
++ usb_mark_last_busy(data->udev);
++ usb_anchor_urb(urb, &data->intr_anchor);
++
++ err = usb_submit_urb(urb, GFP_ATOMIC);
++ if (err < 0) {
++ if (err != -EPERM && err != -ENODEV)
++ AICBT_ERR("%s: Failed to re-submit urb %p, err %d",
++ __func__, urb, err);
++ usb_unanchor_urb(urb);
++ }
++}
++
++static int btusb_submit_intr_urb(struct hci_dev *hdev, gfp_t mem_flags)
++{
++ struct btusb_data *data = GET_DRV_DATA(hdev);
++ struct urb *urb;
++ unsigned char *buf;
++ unsigned int pipe;
++ int err, size;
++
++ if (!data->intr_ep)
++ return -ENODEV;
++
++ urb = usb_alloc_urb(0, mem_flags);
++ if (!urb)
++ return -ENOMEM;
++
++ size = le16_to_cpu(data->intr_ep->wMaxPacketSize);
++
++ buf = kmalloc(size, mem_flags);
++ if (!buf) {
++ usb_free_urb(urb);
++ return -ENOMEM;
++ }
++
++ AICBT_DBG("%s: mMaxPacketSize %d, bEndpointAddress 0x%02x",
++ __func__, size, data->intr_ep->bEndpointAddress);
++
++ pipe = usb_rcvintpipe(data->udev, data->intr_ep->bEndpointAddress);
++
++ usb_fill_int_urb(urb, data->udev, pipe, buf, size,
++ btusb_intr_complete, hdev,
++ data->intr_ep->bInterval);
++
++ urb->transfer_flags |= URB_FREE_BUFFER;
++
++ usb_anchor_urb(urb, &data->intr_anchor);
++
++ err = usb_submit_urb(urb, mem_flags);
++ if (err < 0) {
++ AICBT_ERR("%s: Failed to submit urb %p, err %d",
++ __func__, urb, err);
++ usb_unanchor_urb(urb);
++ }
++
++ usb_free_urb(urb);
++
++ return err;
++}
++
++static void btusb_bulk_complete(struct urb *urb)
++{
++ struct hci_dev *hdev = urb->context;
++ struct btusb_data *data = GET_DRV_DATA(hdev);
++ int err;
++
++ AICBT_DBG("%s: urb %p status %d count %d",
++ __func__, urb, urb->status, urb->actual_length);
++
++ if (!test_bit(HCI_RUNNING, &hdev->flags)) {
++ printk("%s HCI_RUNNING\n", __func__);
++ return;
++ }
++ if (urb->status == 0) {
++ hdev->stat.byte_rx += urb->actual_length;
++
++#if (CONFIG_BLUEDROID) || (HCI_VERSION_CODE < KERNEL_VERSION(3, 18, 0))
++ if (hci_recv_fragment(hdev, HCI_ACLDATA_PKT,
++ urb->transfer_buffer,
++ urb->actual_length) < 0) {
++ AICBT_ERR("%s: Corrupted ACL packet", __func__);
++ hdev->stat.err_rx++;
++ }
++#else
++ if (data->recv_bulk(data, urb->transfer_buffer,
++ urb->actual_length) < 0) {
++ AICBT_ERR("%s Corrupted ACL packet", hdev->name);
++ hdev->stat.err_rx++;
++ }
++#endif
++
++ }
++ /* Avoid suspend failed when usb_kill_urb */
++ else if(urb->status == -ENOENT) {
++ printk("%s ENOENT\n", __func__);
++ return;
++ }
++ AICBT_DBG("%s: OUT", __func__);
++
++ if (!test_bit(BTUSB_BULK_RUNNING, &data->flags)) {
++ printk("%s BTUSB_BULK_RUNNING\n", __func__);
++ return;
++ }
++ usb_anchor_urb(urb, &data->bulk_anchor);
++ usb_mark_last_busy(data->udev);
++
++ //printk("LIULI bulk submit\n");
++ err = usb_submit_urb(urb, GFP_ATOMIC);
++ if (err < 0) {
++ /* -EPERM: urb is being killed;
++ * -ENODEV: device got disconnected */
++ if (err != -EPERM && err != -ENODEV)
++ AICBT_ERR("btusb_bulk_complete %s urb %p failed to resubmit (%d)",
++ hdev->name, urb, -err);
++ usb_unanchor_urb(urb);
++ }
++}
++
++static int btusb_submit_bulk_urb(struct hci_dev *hdev, gfp_t mem_flags)
++{
++ struct btusb_data *data = GET_DRV_DATA(hdev);
++ struct urb *urb;
++ unsigned char *buf;
++ unsigned int pipe;
++ int err, size = HCI_MAX_FRAME_SIZE;
++
++ AICBT_DBG("%s: hdev name %s", __func__, hdev->name);
++ AICBT_DBG("%s: mMaxPacketSize %d, bEndpointAddress 0x%02x",
++ __func__, size, data->bulk_rx_ep->bEndpointAddress);
++
++ if (!data->bulk_rx_ep)
++ return -ENODEV;
++
++ urb = usb_alloc_urb(0, mem_flags);
++ if (!urb)
++ return -ENOMEM;
++
++ buf = kmalloc(size, mem_flags);
++ if (!buf) {
++ usb_free_urb(urb);
++ return -ENOMEM;
++ }
++
++ pipe = usb_rcvbulkpipe(data->udev, data->bulk_rx_ep->bEndpointAddress);
++
++ usb_fill_bulk_urb(urb, data->udev, pipe,
++ buf, size, btusb_bulk_complete, hdev);
++
++ urb->transfer_flags |= URB_FREE_BUFFER;
++
++ usb_mark_last_busy(data->udev);
++ usb_anchor_urb(urb, &data->bulk_anchor);
++
++ err = usb_submit_urb(urb, mem_flags);
++ if (err < 0) {
++ AICBT_ERR("%s: Failed to submit urb %p, err %d", __func__, urb, err);
++ usb_unanchor_urb(urb);
++ }
++
++ usb_free_urb(urb);
++
++ return err;
++}
++
++static void btusb_isoc_complete(struct urb *urb)
++{
++ struct hci_dev *hdev = urb->context;
++ struct btusb_data *data = GET_DRV_DATA(hdev);
++ int i, err;
++ unsigned int total_length = 0;
++
++ AICBT_DBG("%s: urb %p status %d count %d",
++ __func__, urb, urb->status, urb->actual_length);
++
++ if (!test_bit(HCI_RUNNING, &hdev->flags))
++ return;
++
++ if (urb->status == 0) {
++ for (i = 0; i < urb->number_of_packets; i++) {
++ unsigned int offset = urb->iso_frame_desc[i].offset;
++ unsigned int length = urb->iso_frame_desc[i].actual_length;
++ //u8 *data = (u8 *)(urb->transfer_buffer + offset);
++ //AICBT_DBG("%d,%d ,%x,%x,%x s %d.",
++ //offset, length, data[0], data[1],data[2],urb->iso_frame_desc[i].status);
++
++ if(total_length >= urb->actual_length){
++ AICBT_ERR("total_len >= actual_length ,return");
++ break;
++ }
++ total_length += length;
++
++ if (urb->iso_frame_desc[i].status)
++ continue;
++
++ hdev->stat.byte_rx += length;
++ if(length){
++#if (CONFIG_BLUEDROID) || (HCI_VERSION_CODE < KERNEL_VERSION(3, 18, 0))
++ if (hci_recv_fragment(hdev, HCI_SCODATA_PKT,
++ urb->transfer_buffer + offset,
++ length) < 0) {
++ AICBT_ERR("%s: Corrupted SCO packet", __func__);
++ hdev->stat.err_rx++;
++ }
++#else
++ if (btusb_recv_isoc(data, urb->transfer_buffer + offset,
++ length) < 0) {
++ AICBT_ERR("%s corrupted SCO packet",
++ hdev->name);
++ hdev->stat.err_rx++;
++ }
++#endif
++
++ }
++ }
++ }
++ /* Avoid suspend failed when usb_kill_urb */
++ else if(urb->status == -ENOENT) {
++ return;
++ }
++
++
++ if (!test_bit(BTUSB_ISOC_RUNNING, &data->flags))
++ return;
++
++ usb_anchor_urb(urb, &data->isoc_anchor);
++ i = 0;
++retry:
++ err = usb_submit_urb(urb, GFP_ATOMIC);
++ if (err < 0) {
++ /* -EPERM: urb is being killed;
++ * -ENODEV: device got disconnected */
++ if (err != -EPERM && err != -ENODEV)
++ AICBT_ERR("%s: Failed to re-sumbit urb %p, retry %d, err %d",
++ __func__, urb, i, err);
++ if (i < 10) {
++ i++;
++ mdelay(1);
++ goto retry;
++ }
++
++ usb_unanchor_urb(urb);
++ }
++}
++
++static inline void fill_isoc_descriptor(struct urb *urb, int len, int mtu)
++{
++ int i, offset = 0;
++
++ AICBT_DBG("%s: len %d mtu %d", __func__, len, mtu);
++
++ for (i = 0; i < BTUSB_MAX_ISOC_FRAMES && len >= mtu;
++ i++, offset += mtu, len -= mtu) {
++ urb->iso_frame_desc[i].offset = offset;
++ urb->iso_frame_desc[i].length = mtu;
++ }
++
++ if (len && i < BTUSB_MAX_ISOC_FRAMES) {
++ urb->iso_frame_desc[i].offset = offset;
++ urb->iso_frame_desc[i].length = len;
++ i++;
++ }
++
++ urb->number_of_packets = i;
++}
++
++static int btusb_submit_isoc_urb(struct hci_dev *hdev, gfp_t mem_flags)
++{
++ struct btusb_data *data = GET_DRV_DATA(hdev);
++ struct urb *urb;
++ unsigned char *buf;
++ unsigned int pipe;
++ int err, size;
++ int interval;
++
++ if (!data->isoc_rx_ep)
++ return -ENODEV;
++ AICBT_DBG("%s: mMaxPacketSize %d, bEndpointAddress 0x%02x",
++ __func__, size, data->isoc_rx_ep->bEndpointAddress);
++
++ urb = usb_alloc_urb(BTUSB_MAX_ISOC_FRAMES, mem_flags);
++ if (!urb)
++ return -ENOMEM;
++
++ size = le16_to_cpu(data->isoc_rx_ep->wMaxPacketSize) *
++ BTUSB_MAX_ISOC_FRAMES;
++
++ buf = kmalloc(size, mem_flags);
++ if (!buf) {
++ usb_free_urb(urb);
++ return -ENOMEM;
++ }
++
++ pipe = usb_rcvisocpipe(data->udev, data->isoc_rx_ep->bEndpointAddress);
++
++ urb->dev = data->udev;
++ urb->pipe = pipe;
++ urb->context = hdev;
++ urb->complete = btusb_isoc_complete;
++ if (urb->dev->speed == USB_SPEED_HIGH || urb->dev->speed >= USB_SPEED_SUPER) {
++ /* make sure interval is within allowed range */
++ interval = clamp((int)data->isoc_rx_ep->bInterval, 1, 16);
++ urb->interval = 1 << (interval - 1);
++ } else {
++ urb->interval = data->isoc_rx_ep->bInterval;
++ }
++
++ AICBT_INFO("urb->interval %d \r\n", urb->interval);
++
++ urb->transfer_flags = URB_FREE_BUFFER | URB_ISO_ASAP;
++ urb->transfer_buffer = buf;
++ urb->transfer_buffer_length = size;
++
++ fill_isoc_descriptor(urb, size,
++ le16_to_cpu(data->isoc_rx_ep->wMaxPacketSize));
++
++ usb_anchor_urb(urb, &data->isoc_anchor);
++
++ err = usb_submit_urb(urb, mem_flags);
++ if (err < 0) {
++ AICBT_ERR("%s: Failed to submit urb %p, err %d", __func__, urb, err);
++ usb_unanchor_urb(urb);
++ }
++
++ usb_free_urb(urb);
++
++ return err;
++}
++
++static void btusb_tx_complete(struct urb *urb)
++{
++ struct sk_buff *skb = urb->context;
++ struct hci_dev *hdev = (struct hci_dev *) skb->dev;
++ struct btusb_data *data = GET_DRV_DATA(hdev);
++
++ if (!test_bit(HCI_RUNNING, &hdev->flags))
++ goto done;
++
++ if (!urb->status)
++ hdev->stat.byte_tx += urb->transfer_buffer_length;
++ else
++ hdev->stat.err_tx++;
++
++done:
++ spin_lock(&data->txlock);
++ data->tx_in_flight--;
++ spin_unlock(&data->txlock);
++
++ kfree(urb->setup_packet);
++
++ kfree_skb(skb);
++}
++
++static void btusb_isoc_tx_complete(struct urb *urb)
++{
++ struct sk_buff *skb = urb->context;
++ struct hci_dev *hdev = (struct hci_dev *) skb->dev;
++
++ AICBT_DBG("%s: urb %p status %d count %d",
++ __func__, urb, urb->status, urb->actual_length);
++
++ if (skb && hdev) {
++ if (!test_bit(HCI_RUNNING, &hdev->flags))
++ goto done;
++
++ if (!urb->status)
++ hdev->stat.byte_tx += urb->transfer_buffer_length;
++ else
++ hdev->stat.err_tx++;
++ } else
++ AICBT_ERR("%s: skb 0x%p hdev 0x%p", __func__, skb, hdev);
++
++done:
++ kfree(urb->setup_packet);
++
++ kfree_skb(skb);
++}
++
++#if (CONFIG_BLUEDROID == 0)
++#if LINUX_VERSION_CODE > KERNEL_VERSION(4, 0, 9)
++static int btusb_shutdown(struct hci_dev *hdev)
++{
++ struct sk_buff *skb;
++ printk("aic %s\n", __func__);
++
++ skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, HCI_INIT_TIMEOUT);
++ if (IS_ERR(skb)) {
++ printk("HCI reset during shutdown failed\n");
++ return PTR_ERR(skb);
++ }
++ kfree_skb(skb);
++
++ return 0;
++}
++#endif
++#endif //(CONFIG_BLUEDROID == 0)
++
++static int btusb_open(struct hci_dev *hdev)
++{
++ struct btusb_data *data = GET_DRV_DATA(hdev);
++ int err = 0;
++
++ AICBT_INFO("%s: Start", __func__);
++
++ err = usb_autopm_get_interface(data->intf);
++ if (err < 0)
++ return err;
++
++ data->intf->needs_remote_wakeup = 1;
++
++#if (CONFIG_BLUEDROID == 0)
++ //err = download_patch(data->fw_info,1);
++ printk(" download_patch %d", err);
++ if (err < 0) {
++ goto failed;
++ }
++#endif
++
++
++ if (test_and_set_bit(HCI_RUNNING, &hdev->flags)){
++ goto done;
++ }
++
++ if (test_and_set_bit(BTUSB_INTR_RUNNING, &data->flags)){
++ goto done;
++ }
++
++ err = btusb_submit_intr_urb(hdev, GFP_KERNEL);
++ if (err < 0)
++ goto failed;
++
++ err = btusb_submit_bulk_urb(hdev, GFP_KERNEL);
++ if (err < 0) {
++ mdelay(URB_CANCELING_DELAY_MS);
++ usb_kill_anchored_urbs(&data->intr_anchor);
++ goto failed;
++ }
++
++ set_bit(BTUSB_BULK_RUNNING, &data->flags);
++ btusb_submit_bulk_urb(hdev, GFP_KERNEL);
++
++done:
++ usb_autopm_put_interface(data->intf);
++ AICBT_INFO("%s: End", __func__);
++ return 0;
++
++failed:
++ clear_bit(BTUSB_INTR_RUNNING, &data->flags);
++ clear_bit(HCI_RUNNING, &hdev->flags);
++ usb_autopm_put_interface(data->intf);
++ AICBT_ERR("%s: Failed", __func__);
++ return err;
++}
++
++static void btusb_stop_traffic(struct btusb_data *data)
++{
++ mdelay(URB_CANCELING_DELAY_MS);
++ usb_kill_anchored_urbs(&data->intr_anchor);
++ usb_kill_anchored_urbs(&data->bulk_anchor);
++ usb_kill_anchored_urbs(&data->isoc_anchor);
++}
++
++static int btusb_close(struct hci_dev *hdev)
++{
++ struct btusb_data *data = GET_DRV_DATA(hdev);
++#if (CONFIG_BLUEDROID) || (HCI_VERSION_CODE < KERNEL_VERSION(4, 1, 0))
++ int i;
++#endif
++ int err;
++
++ AICBT_INFO("%s: hci running %lu", __func__, hdev->flags & HCI_RUNNING);
++
++ if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags)){
++ return 0;
++ }
++
++ if (!test_and_clear_bit(BTUSB_INTR_RUNNING, &data->flags)){
++ return 0;
++ }
++
++#if (CONFIG_BLUEDROID) || (HCI_VERSION_CODE < KERNEL_VERSION(4, 1, 0))
++ for (i = 0; i < NUM_REASSEMBLY; i++) {
++ if (hdev->reassembly[i]) {
++ AICBT_DBG("%s: free ressembly[%d]", __func__, i);
++ kfree_skb(hdev->reassembly[i]);
++ hdev->reassembly[i] = NULL;
++ }
++ }
++#endif
++
++ cancel_work_sync(&data->work);
++ cancel_work_sync(&data->waker);
++
++ clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
++ clear_bit(BTUSB_BULK_RUNNING, &data->flags);
++ clear_bit(BTUSB_INTR_RUNNING, &data->flags);
++
++ btusb_stop_traffic(data);
++ err = usb_autopm_get_interface(data->intf);
++ if (err < 0)
++ goto failed;
++
++ data->intf->needs_remote_wakeup = 0;
++ usb_autopm_put_interface(data->intf);
++
++failed:
++ mdelay(URB_CANCELING_DELAY_MS);
++ usb_scuttle_anchored_urbs(&data->deferred);
++ return 0;
++}
++
++static int btusb_flush(struct hci_dev *hdev)
++{
++ struct btusb_data *data = GET_DRV_DATA(hdev);
++
++ AICBT_DBG("%s", __func__);
++
++ mdelay(URB_CANCELING_DELAY_MS);
++ usb_kill_anchored_urbs(&data->tx_anchor);
++
++ return 0;
++}
++
++#ifdef CONFIG_SCO_OVER_HCI
++static void btusb_isoc_snd_tx_complete(struct urb *urb);
++
++static int snd_send_sco_frame(struct sk_buff *skb)
++{
++ struct hci_dev *hdev = (struct hci_dev *) skb->dev;
++
++ struct btusb_data *data = GET_DRV_DATA(hdev);
++ //struct usb_ctrlrequest *dr;
++ struct urb *urb;
++ unsigned int pipe;
++ int err;
++
++ AICBT_DBG("%s:pkt type %d, packet_len : %d",
++ __func__,bt_cb(skb)->pkt_type, skb->len);
++
++ if (!hdev && !test_bit(HCI_RUNNING, &hdev->flags))
++ return -EBUSY;
++
++ if (!data->isoc_tx_ep || hdev->conn_hash.sco_num < 1) {
++ kfree(skb);
++ return -ENODEV;
++ }
++
++ urb = usb_alloc_urb(BTUSB_MAX_ISOC_FRAMES, GFP_ATOMIC);
++ if (!urb) {
++ AICBT_ERR("%s: Failed to allocate mem for sco pkts", __func__);
++ kfree(skb);
++ return -ENOMEM;
++ }
++
++ pipe = usb_sndisocpipe(data->udev, data->isoc_tx_ep->bEndpointAddress);
++
++ usb_fill_int_urb(urb, data->udev, pipe,
++ skb->data, skb->len, btusb_isoc_snd_tx_complete,
++ skb, data->isoc_tx_ep->bInterval);
++
++ urb->transfer_flags = URB_ISO_ASAP;
++
++ fill_isoc_descriptor(urb, skb->len,
++ le16_to_cpu(data->isoc_tx_ep->wMaxPacketSize));
++
++ hdev->stat.sco_tx++;
++
++ usb_anchor_urb(urb, &data->tx_anchor);
++
++ err = usb_submit_urb(urb, GFP_ATOMIC);
++ if (err < 0) {
++ AICBT_ERR("%s: Failed to submit urb %p, pkt type %d, err %d",
++ __func__, urb, bt_cb(skb)->pkt_type, err);
++ kfree(urb->setup_packet);
++ usb_unanchor_urb(urb);
++ } else
++ usb_mark_last_busy(data->udev);
++ usb_free_urb(urb);
++
++ return err;
++
++}
++
++static bool snd_copy_send_sco_data( AIC_sco_card_t *pSCOSnd)
++{
++ struct snd_pcm_runtime *runtime = pSCOSnd->playback.substream->runtime;
++ unsigned int frame_bytes = 2, frames1;
++ const u8 *source;
++
++ snd_pcm_uframes_t period_size = runtime->period_size;
++ int i, count;
++ u8 buffer[period_size * 3];
++ int sco_packet_bytes = pSCOSnd->playback.sco_packet_bytes;
++ struct sk_buff *skb;
++
++ count = frames_to_bytes(runtime, period_size)/sco_packet_bytes;
++ skb = bt_skb_alloc(((sco_packet_bytes + HCI_SCO_HDR_SIZE) * count), GFP_ATOMIC);
++ skb->dev = (void *)hci_dev_get(0);
++ bt_cb(skb)->pkt_type = HCI_SCODATA_PKT;
++ skb_put(skb, ((sco_packet_bytes + HCI_SCO_HDR_SIZE) * count));
++ if(!skb)
++ return false;
++
++ AICBT_DBG("%s, buffer_pos:%d sco_handle:%d sco_packet_bytes:%d count:%d", __FUNCTION__, pSCOSnd->playback.buffer_pos, pSCOSnd->usb_data->sco_handle,
++ sco_packet_bytes, count);
++
++ source = runtime->dma_area + pSCOSnd->playback.buffer_pos * frame_bytes;
++
++ if (pSCOSnd->playback.buffer_pos + period_size <= runtime->buffer_size) {
++ memcpy(buffer, source, period_size * frame_bytes);
++ } else {
++ /* wrap around at end of ring buffer */
++ frames1 = runtime->buffer_size - pSCOSnd->playback.buffer_pos;
++ memcpy(buffer, source, frames1 * frame_bytes);
++ memcpy(&buffer[frames1 * frame_bytes],
++ runtime->dma_area, (period_size - frames1) * frame_bytes);
++ }
++
++ pSCOSnd->playback.buffer_pos += period_size;
++ if ( pSCOSnd->playback.buffer_pos >= runtime->buffer_size)
++ pSCOSnd->playback.buffer_pos -= runtime->buffer_size;
++
++ for(i = 0; i < count; i++) {
++ *((__u16 *)(skb->data + i * (sco_packet_bytes + HCI_SCO_HDR_SIZE))) = pSCOSnd->usb_data->sco_handle;
++ *((__u8 *)(skb->data + i*(sco_packet_bytes + HCI_SCO_HDR_SIZE) + 2)) = sco_packet_bytes;
++ memcpy((skb->data + i * (sco_packet_bytes + HCI_SCO_HDR_SIZE) + HCI_SCO_HDR_SIZE),
++ &buffer[sco_packet_bytes * i], sco_packet_bytes);
++ }
++
++ if(test_bit(ALSA_PLAYBACK_RUNNING, &pSCOSnd->states)) {
++ snd_pcm_period_elapsed(pSCOSnd->playback.substream);
++ }
++ snd_send_sco_frame(skb);
++ return true;
++}
++
++static void btusb_isoc_snd_tx_complete(struct urb *urb)
++{
++ struct sk_buff *skb = urb->context;
++ struct hci_dev *hdev = (struct hci_dev *) skb->dev;
++ struct btusb_data *data = GET_DRV_DATA(hdev);
++ AIC_sco_card_t *pSCOSnd = data->pSCOSnd;
++
++ AICBT_DBG("%s: status %d count %d",
++ __func__,urb->status, urb->actual_length);
++
++ if (skb && hdev) {
++ if (!test_bit(HCI_RUNNING, &hdev->flags))
++ goto done;
++
++ if (!urb->status)
++ hdev->stat.byte_tx += urb->transfer_buffer_length;
++ else
++ hdev->stat.err_tx++;
++ } else
++ AICBT_ERR("%s: skb 0x%p hdev 0x%p", __func__, skb, hdev);
++
++done:
++ kfree(urb->setup_packet);
++ kfree_skb(skb);
++ if(test_bit(ALSA_PLAYBACK_RUNNING, &pSCOSnd->states)){
++ snd_copy_send_sco_data(pSCOSnd);
++ //schedule_work(&pSCOSnd->send_sco_work);
++ }
++}
++
++static void playback_work(struct work_struct *work)
++{
++ AIC_sco_card_t *pSCOSnd = container_of(work, AIC_sco_card_t, send_sco_work);
++
++ snd_copy_send_sco_data(pSCOSnd);
++}
++
++#endif
++
++#if (CONFIG_BLUEDROID) || (HCI_VERSION_CODE < KERNEL_VERSION(3, 13, 0))
++int btusb_send_frame(struct sk_buff *skb)
++{
++ struct hci_dev *hdev = (struct hci_dev *) skb->dev;
++#else
++int btusb_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
++{
++#endif
++ //struct hci_dev *hdev = (struct hci_dev *) skb->dev;
++
++ struct btusb_data *data = GET_DRV_DATA(hdev);
++ struct usb_ctrlrequest *dr;
++ struct urb *urb;
++ unsigned int pipe;
++ int err = 0;
++ int retries = 0;
++ u16 *opcode = NULL;
++
++ AICBT_DBG("%s: hdev %p, btusb data %p, pkt type %d",
++ __func__, hdev, data, bt_cb(skb)->pkt_type);
++
++ //printk("aic %d %d\r\n", bt_cb(skb)->pkt_type, skb->len);
++ if (!test_bit(HCI_RUNNING, &hdev->flags))
++ return -EBUSY;
++
++#if (CONFIG_BLUEDROID == 0)
++#if HCI_VERSION_CODE >= KERNEL_VERSION(3, 13, 0)
++ skb->dev = (void *)hdev;
++#endif
++#endif
++
++ switch (bt_cb(skb)->pkt_type) {
++ case HCI_COMMAND_PKT:
++ print_command(skb);
++ urb = usb_alloc_urb(0, GFP_ATOMIC);
++ if (!urb)
++ return -ENOMEM;
++
++ dr = kmalloc(sizeof(*dr), GFP_ATOMIC);
++ if (!dr) {
++ usb_free_urb(urb);
++ return -ENOMEM;
++ }
++
++ dr->bRequestType = data->cmdreq_type;
++ dr->bRequest = 0;
++ dr->wIndex = 0;
++ dr->wValue = 0;
++ dr->wLength = __cpu_to_le16(skb->len);
++
++ pipe = usb_sndctrlpipe(data->udev, 0x00);
++
++ usb_fill_control_urb(urb, data->udev, pipe, (void *) dr,
++ skb->data, skb->len, btusb_tx_complete, skb);
++
++ hdev->stat.cmd_tx++;
++ break;
++
++ case HCI_ACLDATA_PKT:
++ if (bt_cb(skb)->pkt_type == HCI_COMMAND_PKT) {
++ print_command(skb);
++ opcode = (u16*)(skb->data);
++ printk("aic cmd:0x%04x", *opcode);
++ } else {
++ print_acl(skb, 1);
++ }
++ if (!data->bulk_tx_ep)
++ return -ENODEV;
++
++ urb = usb_alloc_urb(0, GFP_ATOMIC);
++ if (!urb)
++ return -ENOMEM;
++
++ pipe = usb_sndbulkpipe(data->udev,
++ data->bulk_tx_ep->bEndpointAddress);
++
++ usb_fill_bulk_urb(urb, data->udev, pipe,
++ skb->data, skb->len, btusb_tx_complete, skb);
++
++ hdev->stat.acl_tx++;
++ break;
++
++ case HCI_SCODATA_PKT:
++ print_sco(skb, 1);
++ if (!data->isoc_tx_ep || SCO_NUM < 1) {
++ kfree(skb);
++ return -ENODEV;
++ }
++
++ urb = usb_alloc_urb(BTUSB_MAX_ISOC_FRAMES, GFP_ATOMIC);
++ if (!urb) {
++ AICBT_ERR("%s: Failed to allocate mem for sco pkts", __func__);
++ kfree(skb);
++ return -ENOMEM;
++ }
++
++ pipe = usb_sndisocpipe(data->udev, data->isoc_tx_ep->bEndpointAddress);
++
++ usb_fill_int_urb(urb, data->udev, pipe,
++ skb->data, skb->len, btusb_isoc_tx_complete,
++ skb, data->isoc_tx_ep->bInterval);
++
++ urb->transfer_flags = URB_ISO_ASAP;
++
++ fill_isoc_descriptor(urb, skb->len,
++ le16_to_cpu(data->isoc_tx_ep->wMaxPacketSize));
++
++ hdev->stat.sco_tx++;
++ goto skip_waking;
++
++ default:
++ return -EILSEQ;
++ }
++
++ err = inc_tx(data);
++ if (err) {
++ usb_anchor_urb(urb, &data->deferred);
++ schedule_work(&data->waker);
++ err = 0;
++ goto done;
++ }
++
++skip_waking:
++ usb_anchor_urb(urb, &data->tx_anchor);
++retry:
++ err = usb_submit_urb(urb, GFP_ATOMIC);
++ if (err < 0) {
++ AICBT_ERR("%s: Failed to submit urb %p, pkt type %d, err %d, retries %d",
++ __func__, urb, bt_cb(skb)->pkt_type, err, retries);
++ if ((bt_cb(skb)->pkt_type != HCI_SCODATA_PKT) && (retries < 10)) {
++ mdelay(1);
++
++ if (bt_cb(skb)->pkt_type == HCI_COMMAND_PKT)
++ print_error_command(skb);
++ retries++;
++ goto retry;
++ }
++ kfree(urb->setup_packet);
++ usb_unanchor_urb(urb);
++ } else
++ usb_mark_last_busy(data->udev);
++ usb_free_urb(urb);
++
++done:
++ return err;
++}
++
++#if LINUX_VERSION_CODE <= KERNEL_VERSION(3, 4, 0)
++static void btusb_destruct(struct hci_dev *hdev)
++{
++ struct btusb_data *data = GET_DRV_DATA(hdev);
++
++ AICBT_DBG("%s: name %s", __func__, hdev->name);
++
++ kfree(data);
++}
++#endif
++
++static void btusb_notify(struct hci_dev *hdev, unsigned int evt)
++{
++ struct btusb_data *data = GET_DRV_DATA(hdev);
++
++ AICBT_DBG("%s: name %s, evt %d", __func__, hdev->name, evt);
++
++ if (SCO_NUM != data->sco_num) {
++ data->sco_num = SCO_NUM;
++ schedule_work(&data->work);
++ }
++}
++
++static inline int set_isoc_interface(struct hci_dev *hdev, int altsetting)
++{
++ struct btusb_data *data = GET_DRV_DATA(hdev);
++ struct usb_interface *intf = data->isoc;
++ struct usb_endpoint_descriptor *ep_desc;
++ int i, err;
++
++ if (!data->isoc)
++ return -ENODEV;
++
++ err = usb_set_interface(data->udev, 1, altsetting);
++ if (err < 0) {
++ AICBT_ERR("%s: Failed to set interface, altsetting %d, err %d",
++ __func__, altsetting, err);
++ return err;
++ }
++
++ data->isoc_altsetting = altsetting;
++
++ data->isoc_tx_ep = NULL;
++ data->isoc_rx_ep = NULL;
++
++ for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) {
++ ep_desc = &intf->cur_altsetting->endpoint[i].desc;
++
++ if (!data->isoc_tx_ep && usb_endpoint_is_isoc_out(ep_desc)) {
++ data->isoc_tx_ep = ep_desc;
++ continue;
++ }
++
++ if (!data->isoc_rx_ep && usb_endpoint_is_isoc_in(ep_desc)) {
++ data->isoc_rx_ep = ep_desc;
++ continue;
++ }
++ }
++
++ if (!data->isoc_tx_ep || !data->isoc_rx_ep) {
++ AICBT_ERR("%s: Invalid SCO descriptors", __func__);
++ return -ENODEV;
++ }
++
++ AICBT_ERR("%s: hdev->reassembly implemant\r\n",
++ __func__);
++
++#if CONFIG_BLUEDROID
++ if(hdev->reassembly[HCI_SCODATA_PKT - 1]) {
++ kfree_skb(hdev->reassembly[HCI_SCODATA_PKT - 1]);
++ hdev->reassembly[HCI_SCODATA_PKT - 1] = NULL;
++ }
++#endif
++ return 0;
++}
++
++static void set_select_msbc(enum CODEC_TYPE type)
++{
++ printk("%s codec type = %d", __func__, (int)type);
++ codec_type = type;
++}
++
++static enum CODEC_TYPE check_select_msbc(void)
++{
++ return codec_type;
++}
++
++#ifdef CONFIG_SCO_OVER_HCI
++static int check_controller_support_msbc( struct usb_device *udev)
++{
++ //fix this in the future,when new card support msbc decode and encode
++ AICBT_INFO("%s:pid = 0x%02x, vid = 0x%02x",__func__,udev->descriptor.idProduct, udev->descriptor.idVendor);
++ switch (udev->descriptor.idProduct) {
++
++ default:
++ return 0;
++ }
++ return 0;
++}
++#endif
++static void btusb_work(struct work_struct *work)
++{
++ struct btusb_data *data = container_of(work, struct btusb_data, work);
++ struct hci_dev *hdev = data->hdev;
++ int err;
++ int new_alts;
++#ifdef CONFIG_SCO_OVER_HCI
++ AIC_sco_card_t *pSCOSnd = data->pSCOSnd;
++#endif
++ printk("%s data->sco_num:%d \r\n", __func__, data->sco_num);
++
++ if (data->sco_num > 0) {
++ if (!test_bit(BTUSB_DID_ISO_RESUME, &data->flags)) {
++ err = usb_autopm_get_interface(data->isoc ? data->isoc : data->intf);
++ if (err < 0) {
++ clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
++ mdelay(URB_CANCELING_DELAY_MS);
++ usb_kill_anchored_urbs(&data->isoc_anchor);
++ printk("%s usb_kill_anchored_urbs after \r\n", __func__);
++ return;
++ }
++
++ set_bit(BTUSB_DID_ISO_RESUME, &data->flags);
++ }
++
++ hdev->voice_setting = 93;
++ AICBT_INFO("%s voice settings = 0x%04x", __func__, hdev->voice_setting);
++ if (!(hdev->voice_setting & 0x0003)) {
++ if(data->sco_num == 1)
++ if(check_select_msbc()) {
++ new_alts = 1;
++ } else {
++ new_alts = 2;
++ }
++ else {
++ AICBT_INFO("%s: we don't support mutiple sco link for cvsd", __func__);
++ return;
++ }
++ } else{
++ if(check_select_msbc()) {
++ if(data->sco_num == 1)
++ new_alts = 1;
++ else {
++ AICBT_INFO("%s: we don't support mutiple sco link for msbc", __func__);
++ return;
++ }
++ } else {
++ new_alts = 2;
++ }
++ }
++ if (data->isoc_altsetting != new_alts) {
++
++ clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
++ mdelay(URB_CANCELING_DELAY_MS);
++ usb_kill_anchored_urbs(&data->isoc_anchor);
++
++ printk("%s set_isoc_interface in \r\n", __func__);
++ if (set_isoc_interface(hdev, new_alts) < 0)
++ return;
++
++ }
++
++ printk("%s set_isoc_interface out \r\n", __func__);
++
++ if (!test_and_set_bit(BTUSB_ISOC_RUNNING, &data->flags)) {
++ printk("%s btusb_submit_isoc_urb\r\n", __func__);
++ if (btusb_submit_isoc_urb(hdev, GFP_KERNEL) < 0)
++ clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
++ else
++ btusb_submit_isoc_urb(hdev, GFP_KERNEL);
++ }
++#ifdef CONFIG_SCO_OVER_HCI
++ if(test_bit(BTUSB_ISOC_RUNNING, &data->flags)) {
++ set_bit(USB_CAPTURE_RUNNING, &data->pSCOSnd->states);
++ set_bit(USB_PLAYBACK_RUNNING, &data->pSCOSnd->states);
++ }
++ if (test_bit(ALSA_PLAYBACK_RUNNING, &pSCOSnd->states)) {
++ schedule_work(&pSCOSnd->send_sco_work);
++ AICBT_INFO("%s: play_timer restart", __func__);
++ }
++#endif
++ } else {
++ clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
++#ifdef CONFIG_SCO_OVER_HCI
++ clear_bit(USB_CAPTURE_RUNNING, &data->pSCOSnd->states);
++ clear_bit(USB_PLAYBACK_RUNNING, &data->pSCOSnd->states);
++ //AIC_sco_card_t *pSCOSnd = data->pSCOSnd;
++ if (test_bit(ALSA_PLAYBACK_RUNNING, &pSCOSnd->states)) {
++ mod_timer(&snd_cap_timer.play_timer,jiffies + msecs_to_jiffies(30));
++ AICBT_INFO("%s: play_timer start", __func__);
++ }
++#endif
++ mdelay(URB_CANCELING_DELAY_MS);
++ usb_kill_anchored_urbs(&data->isoc_anchor);
++
++ set_isoc_interface(hdev, 0);
++ if (test_and_clear_bit(BTUSB_DID_ISO_RESUME, &data->flags))
++ usb_autopm_put_interface(data->isoc ? data->isoc : data->intf);
++ }
++}
++
++static void btusb_waker(struct work_struct *work)
++{
++ struct btusb_data *data = container_of(work, struct btusb_data, waker);
++ int err;
++
++ AICBT_DBG("%s", __func__);
++
++ err = usb_autopm_get_interface(data->intf);
++ if (err < 0)
++ return;
++
++ usb_autopm_put_interface(data->intf);
++}
++
++int bt_pm_notify(struct notifier_block *notifier, ulong pm_event, void *unused)
++{
++ struct btusb_data *data;
++ firmware_info *fw_info;
++ struct usb_device *udev;
++
++ AICBT_INFO("%s: pm event %ld", __func__, pm_event);
++
++ data = container_of(notifier, struct btusb_data, pm_notifier);
++ fw_info = data->fw_info;
++ udev = fw_info->udev;
++
++ switch (pm_event) {
++ case PM_SUSPEND_PREPARE:
++ case PM_HIBERNATION_PREPARE:
++#if 0
++ patch_entry->fw_len = load_firmware(fw_info, &patch_entry->fw_cache);
++ if (patch_entry->fw_len <= 0) {
++ /* We may encount failure in loading firmware, just give a warning */
++ AICBT_WARN("%s: Failed to load firmware", __func__);
++ }
++#endif
++ if (!device_may_wakeup(&udev->dev)) {
++#if (CONFIG_RESET_RESUME || CONFIG_BLUEDROID)
++ AICBT_INFO("%s:remote wakeup not supported, reset resume supported", __func__);
++#else
++ fw_info->intf->needs_binding = 1;
++ AICBT_INFO("%s:remote wakeup not supported, binding needed", __func__);
++#endif
++ }
++ break;
++
++ case PM_POST_SUSPEND:
++ case PM_POST_HIBERNATION:
++ case PM_POST_RESTORE:
++#if 0
++ /* Reclaim fw buffer when bt usb resumed */
++ if (patch_entry->fw_len > 0) {
++ kfree(patch_entry->fw_cache);
++ patch_entry->fw_cache = NULL;
++ patch_entry->fw_len = 0;
++ }
++#endif
++
++#if BTUSB_RPM
++ usb_disable_autosuspend(udev);
++ usb_enable_autosuspend(udev);
++ pm_runtime_set_autosuspend_delay(&(udev->dev), 2000);
++#endif
++ break;
++
++ default:
++ break;
++ }
++
++ return NOTIFY_DONE;
++}
++
++int bt_reboot_notify(struct notifier_block *notifier, ulong pm_event, void *unused)
++{
++ struct btusb_data *data;
++ firmware_info *fw_info;
++ struct usb_device *udev;
++
++ AICBT_INFO("%s: pm event %ld", __func__, pm_event);
++
++ data = container_of(notifier, struct btusb_data, reboot_notifier);
++ fw_info = data->fw_info;
++ udev = fw_info->udev;
++
++ switch (pm_event) {
++ case SYS_DOWN:
++ AICBT_DBG("%s:system down or restart", __func__);
++ break;
++
++ case SYS_HALT:
++ case SYS_POWER_OFF:
++#if SUSPNED_DW_FW
++ cancel_work_sync(&data->work);
++
++ btusb_stop_traffic(data);
++ mdelay(URB_CANCELING_DELAY_MS);
++ usb_kill_anchored_urbs(&data->tx_anchor);
++
++
++ if(fw_info_4_suspend) {
++ download_suspend_patch(fw_info_4_suspend,1);
++ }
++ else
++ AICBT_ERR("%s: Failed to download suspend fw", __func__);
++#endif
++
++#ifdef SET_WAKEUP_DEVICE
++ set_wakeup_device_from_conf(fw_info_4_suspend);
++#endif
++ AICBT_DBG("%s:system halt or power off", __func__);
++ break;
++
++ default:
++ break;
++ }
++
++ return NOTIFY_DONE;
++}
++
++
++#ifdef CONFIG_SCO_OVER_HCI
++#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
++void aic_snd_capture_timeout(ulong data)
++#else
++void aic_snd_capture_timeout(struct timer_list *t)
++#endif
++{
++ uint8_t null_data[255];
++ struct btusb_data *usb_data;
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
++ usb_data = (struct btusb_data *)data;
++#else
++ usb_data = &snd_cap_timer.snd_usb_data;
++#endif
++ aic_copy_capture_data_to_alsa(usb_data, null_data, snd_cap_timer.snd_sco_length/2);
++ //printk("%s enter\r\n", __func__);
++ mod_timer(&snd_cap_timer.cap_timer,jiffies + msecs_to_jiffies(3));
++}
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
++void aic_snd_play_timeout(ulong data)
++#else
++void aic_snd_play_timeout(struct timer_list *t)
++#endif
++{
++ AIC_sco_card_t *pSCOSnd;
++ struct snd_pcm_runtime *runtime;
++ snd_pcm_uframes_t period_size;
++ int count;
++ struct btusb_data *usb_data;
++ int sco_packet_bytes;
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
++ usb_data = (struct btusb_data *)data;
++#else
++ usb_data = &snd_cap_timer.snd_usb_data;
++#endif
++ pSCOSnd = usb_data->pSCOSnd;
++
++ if(test_bit(USB_PLAYBACK_RUNNING, &pSCOSnd->states)) {
++ return;
++ }
++
++ if(!test_bit(ALSA_PLAYBACK_RUNNING, &pSCOSnd->states)) {
++ return;
++ }
++
++ runtime = pSCOSnd->playback.substream->runtime;
++ period_size = runtime->period_size;
++ sco_packet_bytes = pSCOSnd->playback.sco_packet_bytes;
++ count = frames_to_bytes(runtime, period_size)/sco_packet_bytes;
++
++ pSCOSnd->playback.buffer_pos += period_size;
++ if ( pSCOSnd->playback.buffer_pos >= runtime->buffer_size)
++ pSCOSnd->playback.buffer_pos -= runtime->buffer_size;
++
++ if(test_bit(ALSA_PLAYBACK_RUNNING, &pSCOSnd->states)) {
++ snd_pcm_period_elapsed(pSCOSnd->playback.substream);
++ }
++ //AICBT_DBG("%s,play_timer restart buffer_pos:%d sco_handle:%d sco_packet_bytes:%d count:%d", __FUNCTION__, pSCOSnd->playback.buffer_pos, pSCOSnd->usb_data->sco_handle,
++ //sco_packet_bytes, count);
++ mod_timer(&snd_cap_timer.play_timer,jiffies + msecs_to_jiffies(3*count));
++}
++
++static const struct snd_pcm_hardware snd_card_sco_capture_default =
++{
++ .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_NONINTERLEAVED |
++ SNDRV_PCM_ACCESS_RW_INTERLEAVED | SNDRV_PCM_INFO_FIFO_IN_FRAMES),
++ .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8,
++ .rates = (SNDRV_PCM_RATE_8000),
++ .rate_min = 8000,
++ .rate_max = 8000,
++ .channels_min = 1,
++ .channels_max = 1,
++ .buffer_bytes_max = 8 * 768,
++ .period_bytes_min = 48,
++ .period_bytes_max = 768,
++ .periods_min = 1,
++ .periods_max = 8,
++ .fifo_size = 8,
++
++};
++
++static int snd_sco_capture_pcm_open(struct snd_pcm_substream * substream)
++{
++ AIC_sco_card_t *pSCOSnd = substream->private_data;
++
++ AICBT_INFO("%s", __FUNCTION__);
++ pSCOSnd->capture.substream = substream;
++
++ memcpy(&substream->runtime->hw, &snd_card_sco_capture_default, sizeof(struct snd_pcm_hardware));
++ pSCOSnd->capture.buffer_pos = 0;
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
++ init_timer(&snd_cap_timer.cap_timer);
++ snd_cap_timer.cap_timer.data = (unsigned long)pSCOSnd->usb_data;
++ snd_cap_timer.cap_timer.function = aic_snd_capture_timeout;
++#else
++ timer_setup(&snd_cap_timer.cap_timer, aic_snd_capture_timeout, 0);
++ snd_cap_timer.snd_usb_data = *(pSCOSnd->usb_data);
++#endif
++
++ if(check_controller_support_msbc(pSCOSnd->dev)) {
++ substream->runtime->hw.rates |= SNDRV_PCM_RATE_16000;
++ substream->runtime->hw.rate_max = 16000;
++ substream->runtime->hw.period_bytes_min = 96;
++ substream->runtime->hw.period_bytes_max = 16 * 96;
++ substream->runtime->hw.buffer_bytes_max = 8 * 16 * 96;
++ }
++ set_bit(ALSA_CAPTURE_OPEN, &pSCOSnd->states);
++ return 0;
++}
++
++static int snd_sco_capture_pcm_close(struct snd_pcm_substream *substream)
++{
++ AIC_sco_card_t *pSCOSnd = substream->private_data;
++
++ del_timer(&snd_cap_timer.cap_timer);
++ clear_bit(ALSA_CAPTURE_OPEN, &pSCOSnd->states);
++ return 0;
++}
++
++static int snd_sco_capture_ioctl(struct snd_pcm_substream *substream, unsigned int cmd, void *arg)
++{
++ AICBT_DBG("%s, cmd = %d", __FUNCTION__, cmd);
++ switch (cmd)
++ {
++ default:
++ return snd_pcm_lib_ioctl(substream, cmd, arg);
++ }
++ return 0;
++}
++
++static int snd_sco_capture_pcm_hw_params(struct snd_pcm_substream * substream, struct snd_pcm_hw_params * hw_params)
++{
++
++ int err;
++ struct snd_pcm_runtime *runtime = substream->runtime;
++ err = snd_pcm_lib_alloc_vmalloc_buffer(substream, params_buffer_bytes(hw_params));
++ AICBT_INFO("%s,err : %d, runtime state : %d", __FUNCTION__, err, runtime->status->state);
++ return err;
++}
++
++static int snd_sco_capture_pcm_hw_free(struct snd_pcm_substream * substream)
++{
++ AICBT_DBG("%s", __FUNCTION__);
++ return snd_pcm_lib_free_vmalloc_buffer(substream);;
++}
++
++static int snd_sco_capture_pcm_prepare(struct snd_pcm_substream *substream)
++{
++ AIC_sco_card_t *pSCOSnd = substream->private_data;
++ struct snd_pcm_runtime *runtime = substream->runtime;
++
++ AICBT_INFO("%s %d\n", __FUNCTION__, (int)runtime->period_size);
++ if (test_bit(DISCONNECTED, &pSCOSnd->states))
++ return -ENODEV;
++ if (!test_bit(USB_CAPTURE_RUNNING, &pSCOSnd->states))
++ return -EIO;
++
++ if(runtime->rate == 8000) {
++ if(pSCOSnd->usb_data->isoc_altsetting != 2)
++ return -ENOEXEC;
++ pSCOSnd->capture.sco_packet_bytes = 48;
++ }
++ else if(runtime->rate == 16000 && check_controller_support_msbc(pSCOSnd->dev)) {
++ if(pSCOSnd->usb_data->isoc_altsetting != 4)
++ return -ENOEXEC;
++ pSCOSnd->capture.sco_packet_bytes = 96;
++ }
++ else if(pSCOSnd->usb_data->isoc_altsetting == 2) {
++ pSCOSnd->capture.sco_packet_bytes = 48;
++ }
++ else if(pSCOSnd->usb_data->isoc_altsetting == 1) {
++ pSCOSnd->capture.sco_packet_bytes = 24;
++ }
++ return 0;
++}
++
++static int snd_sco_capture_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
++{
++ AIC_sco_card_t *pSCOSnd = substream->private_data;
++ AICBT_INFO("%s, cmd : %d", __FUNCTION__, cmd);
++
++ switch (cmd) {
++ case SNDRV_PCM_TRIGGER_START:
++ if (!test_bit(USB_CAPTURE_RUNNING, &pSCOSnd->states))
++ return -EIO;
++ set_bit(ALSA_CAPTURE_RUNNING, &pSCOSnd->states);
++ return 0;
++ case SNDRV_PCM_TRIGGER_STOP:
++ clear_bit(ALSA_CAPTURE_RUNNING, &pSCOSnd->states);
++ return 0;
++ default:
++ return -EINVAL;
++ }
++}
++
++static snd_pcm_uframes_t snd_sco_capture_pcm_pointer(struct snd_pcm_substream *substream)
++{
++ AIC_sco_card_t *pSCOSnd = substream->private_data;
++
++ return pSCOSnd->capture.buffer_pos;
++}
++
++
++static struct snd_pcm_ops snd_sco_capture_pcm_ops = {
++ .open = snd_sco_capture_pcm_open,
++ .close = snd_sco_capture_pcm_close,
++ .ioctl = snd_sco_capture_ioctl,
++ .hw_params = snd_sco_capture_pcm_hw_params,
++ .hw_free = snd_sco_capture_pcm_hw_free,
++ .prepare = snd_sco_capture_pcm_prepare,
++ .trigger = snd_sco_capture_pcm_trigger,
++ .pointer = snd_sco_capture_pcm_pointer,
++};
++
++
++static const struct snd_pcm_hardware snd_card_sco_playback_default =
++{
++ .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_NONINTERLEAVED |
++ SNDRV_PCM_ACCESS_RW_INTERLEAVED | SNDRV_PCM_INFO_FIFO_IN_FRAMES),
++ .formats = SNDRV_PCM_FMTBIT_S16_LE,
++ .rates = (SNDRV_PCM_RATE_8000),
++ .rate_min = 8000,
++ .rate_max = 8000,
++ .channels_min = 1,
++ .channels_max = 1,
++ .buffer_bytes_max = 8 * 768,
++ .period_bytes_min = 48,
++ .period_bytes_max = 768,
++ .periods_min = 1,
++ .periods_max = 8,
++ .fifo_size = 8,
++};
++
++static int snd_sco_playback_pcm_open(struct snd_pcm_substream * substream)
++{
++ AIC_sco_card_t *pSCOSnd = substream->private_data;
++ int err = 0;
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
++ init_timer(&snd_cap_timer.play_timer);
++ snd_cap_timer.play_timer.data = (unsigned long)pSCOSnd->usb_data;
++ snd_cap_timer.play_timer.function = aic_snd_play_timeout;
++#else
++ timer_setup(&snd_cap_timer.play_timer, aic_snd_play_timeout, 0);
++ snd_cap_timer.snd_usb_data = *(pSCOSnd->usb_data);
++#endif
++ pSCOSnd->playback.buffer_pos = 0;
++
++ AICBT_INFO("%s, rate : %d", __FUNCTION__, substream->runtime->rate);
++ memcpy(&substream->runtime->hw, &snd_card_sco_playback_default, sizeof(struct snd_pcm_hardware));
++ if(check_controller_support_msbc(pSCOSnd->dev)) {
++ substream->runtime->hw.rates |= SNDRV_PCM_RATE_16000;
++ substream->runtime->hw.rate_max = 16000;
++ substream->runtime->hw.period_bytes_min = 96;
++ substream->runtime->hw.period_bytes_max = 16 * 96;
++ substream->runtime->hw.buffer_bytes_max = 8 * 16 * 96;
++ }
++ pSCOSnd->playback.substream = substream;
++ set_bit(ALSA_PLAYBACK_OPEN, &pSCOSnd->states);
++
++ return err;
++}
++
++static int snd_sco_playback_pcm_close(struct snd_pcm_substream *substream)
++{
++ AIC_sco_card_t *pSCOSnd = substream->private_data;
++
++ del_timer(&snd_cap_timer.play_timer);
++ AICBT_INFO("%s: play_timer delete", __func__);
++ clear_bit(ALSA_PLAYBACK_OPEN, &pSCOSnd->states);
++ cancel_work_sync(&pSCOSnd->send_sco_work);
++ return 0;
++}
++
++static int snd_sco_playback_ioctl(struct snd_pcm_substream *substream, unsigned int cmd, void *arg)
++{
++ AICBT_DBG("%s, cmd : %d", __FUNCTION__, cmd);
++ switch (cmd)
++ {
++ default:
++ return snd_pcm_lib_ioctl(substream, cmd, arg);
++ break;
++ }
++ return 0;
++}
++
++static int snd_sco_playback_pcm_hw_params(struct snd_pcm_substream * substream, struct snd_pcm_hw_params * hw_params)
++{
++ int err;
++ err = snd_pcm_lib_alloc_vmalloc_buffer(substream, params_buffer_bytes(hw_params));
++ return err;
++}
++
++static int snd_sco_palyback_pcm_hw_free(struct snd_pcm_substream * substream)
++{
++ AICBT_DBG("%s", __FUNCTION__);
++ return snd_pcm_lib_free_vmalloc_buffer(substream);
++}
++
++static int snd_sco_playback_pcm_prepare(struct snd_pcm_substream *substream)
++{
++ AIC_sco_card_t *pSCOSnd = substream->private_data;
++ struct snd_pcm_runtime *runtime = substream->runtime;
++
++ AICBT_INFO("%s, bound_rate = %d", __FUNCTION__, runtime->rate);
++
++ if (test_bit(DISCONNECTED, &pSCOSnd->states))
++ return -ENODEV;
++ if (!test_bit(USB_PLAYBACK_RUNNING, &pSCOSnd->states))
++ return -EIO;
++
++ if(runtime->rate == 8000) {
++ if(pSCOSnd->usb_data->isoc_altsetting != 2)
++ return -ENOEXEC;
++ pSCOSnd->playback.sco_packet_bytes = 48;
++ }
++ else if(runtime->rate == 16000) {
++ if(pSCOSnd->usb_data->isoc_altsetting != 4)
++ return -ENOEXEC;
++ pSCOSnd->playback.sco_packet_bytes = 96;
++ }
++
++ return 0;
++}
++
++static int snd_sco_playback_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
++{
++ AIC_sco_card_t *pSCOSnd = substream->private_data;
++
++ AICBT_INFO("%s, cmd = %d", __FUNCTION__, cmd);
++ switch (cmd) {
++ case SNDRV_PCM_TRIGGER_START:
++ if (!test_bit(USB_PLAYBACK_RUNNING, &pSCOSnd->states))
++ return -EIO;
++ set_bit(ALSA_PLAYBACK_RUNNING, &pSCOSnd->states);
++ schedule_work(&pSCOSnd->send_sco_work);
++#ifdef CONFIG_SCO_OVER_HCI
++ if (!test_bit(USB_PLAYBACK_RUNNING, &pSCOSnd->states)) {
++ AICBT_INFO("%s: play_timer cmd 1 start ", __func__);
++ mod_timer(&snd_cap_timer.play_timer,jiffies + msecs_to_jiffies(3));
++ }
++#endif
++ return 0;
++ case SNDRV_PCM_TRIGGER_STOP:
++ clear_bit(ALSA_PLAYBACK_RUNNING, &pSCOSnd->states);
++ return 0;
++ default:
++ return -EINVAL;
++ }
++}
++
++static snd_pcm_uframes_t snd_sco_playback_pcm_pointer(struct snd_pcm_substream *substream)
++{
++ AIC_sco_card_t *pSCOSnd = substream->private_data;
++
++ return pSCOSnd->playback.buffer_pos;
++}
++
++
++static struct snd_pcm_ops snd_sco_playback_pcm_ops = {
++ .open = snd_sco_playback_pcm_open,
++ .close = snd_sco_playback_pcm_close,
++ .ioctl = snd_sco_playback_ioctl,
++ .hw_params = snd_sco_playback_pcm_hw_params,
++ .hw_free = snd_sco_palyback_pcm_hw_free,
++ .prepare = snd_sco_playback_pcm_prepare,
++ .trigger = snd_sco_playback_pcm_trigger,
++ .pointer = snd_sco_playback_pcm_pointer,
++};
++
++
++static AIC_sco_card_t* btusb_snd_init(struct usb_interface *intf, const struct usb_device_id *id, struct btusb_data *data)
++{
++ struct snd_card *card;
++ AIC_sco_card_t *pSCOSnd;
++ int err=0;
++ AICBT_INFO("%s", __func__);
++ err = snd_card_new(&intf->dev,
++ -1, AIC_SCO_ID, THIS_MODULE,
++ sizeof(AIC_sco_card_t), &card);
++ if (err < 0) {
++ AICBT_ERR("%s: sco snd card create fail", __func__);
++ return NULL;
++ }
++ // private data
++ pSCOSnd = (AIC_sco_card_t *)card->private_data;
++ pSCOSnd->card = card;
++ pSCOSnd->dev = interface_to_usbdev(intf);
++ pSCOSnd->usb_data = data;
++
++ strcpy(card->driver, AIC_SCO_ID);
++ strcpy(card->shortname, "Aicsemi sco snd");
++ sprintf(card->longname, "Aicsemi sco over hci: VID:0x%04x, PID:0x%04x",
++ id->idVendor, pSCOSnd->dev->descriptor.idProduct);
++
++ err = snd_pcm_new(card, AIC_SCO_ID, 0, 1, 1, &pSCOSnd->pcm);
++ if (err < 0) {
++ AICBT_ERR("%s: sco snd card new pcm fail", __func__);
++ return NULL;
++ }
++ pSCOSnd->pcm->private_data = pSCOSnd;
++ sprintf(pSCOSnd->pcm->name, "sco_pcm:VID:0x%04x, PID:0x%04x",
++ id->idVendor, pSCOSnd->dev->descriptor.idProduct);
++
++ snd_pcm_set_ops(pSCOSnd->pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_sco_playback_pcm_ops);
++ snd_pcm_set_ops(pSCOSnd->pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_sco_capture_pcm_ops);
++
++ err = snd_card_register(card);
++ if (err < 0) {
++ AICBT_ERR("%s: sco snd card register card fail", __func__);
++ return NULL;
++ }
++
++ spin_lock_init(&pSCOSnd->capture_lock);
++ spin_lock_init(&pSCOSnd->playback_lock);
++ INIT_WORK(&pSCOSnd->send_sco_work, playback_work);
++ return pSCOSnd;
++}
++#endif
++
++static int aicwf_usb_chipmatch(u16 vid, u16 pid){
++
++ if(pid == USB_PRODUCT_ID_AIC8801){
++ g_chipid = PRODUCT_ID_AIC8801;
++ printk("%s USE AIC8801\r\n", __func__);
++ return 0;
++ }else if(pid == USB_PRODUCT_ID_AIC8800DC){
++ g_chipid = PRODUCT_ID_AIC8800DC;
++ printk("%s USE AIC8800DC\r\n", __func__);
++ return 0;
++ }else if(pid == USB_PRODUCT_ID_AIC8800D80){
++ g_chipid = PRODUCT_ID_AIC8800D80;
++ printk("%s USE AIC8800D80\r\n", __func__);
++ return 0;
++ }else{
++ return -1;
++ }
++}
++
++
++static int btusb_probe(struct usb_interface *intf, const struct usb_device_id *id)
++{
++ struct usb_device *udev = interface_to_usbdev(intf);
++ struct usb_endpoint_descriptor *ep_desc;
++ u8 endpoint_num;
++ struct btusb_data *data;
++ struct hci_dev *hdev;
++ firmware_info *fw_info;
++ int i, err=0;
++
++ bt_support = 1;
++
++ AICBT_INFO("%s: usb_interface %p, bInterfaceNumber %d, idVendor 0x%04x, "
++ "idProduct 0x%04x", __func__, intf,
++ intf->cur_altsetting->desc.bInterfaceNumber,
++ id->idVendor, id->idProduct);
++
++ aicwf_usb_chipmatch(id->idVendor, id->idProduct);
++
++ /* interface numbers are hardcoded in the spec */
++ if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
++ return -ENODEV;
++
++ AICBT_DBG("%s: can wakeup = %x, may wakeup = %x", __func__,
++ device_can_wakeup(&udev->dev), device_may_wakeup(&udev->dev));
++
++ data = aic_alloc(intf);
++ if (!data)
++ return -ENOMEM;
++
++ for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) {
++ ep_desc = &intf->cur_altsetting->endpoint[i].desc;
++
++ endpoint_num = usb_endpoint_num(ep_desc);
++ printk("endpoint num %d\n", endpoint_num);
++
++ if (!data->intr_ep && usb_endpoint_is_int_in(ep_desc)) {
++ data->intr_ep = ep_desc;
++ continue;
++ }
++
++ if (!data->bulk_tx_ep && usb_endpoint_is_bulk_out(ep_desc)) {
++ data->bulk_tx_ep = ep_desc;
++ continue;
++ }
++
++ if (!data->bulk_rx_ep && usb_endpoint_is_bulk_in(ep_desc)) {
++ data->bulk_rx_ep = ep_desc;
++ continue;
++ }
++ }
++
++ if (!data->intr_ep || !data->bulk_tx_ep || !data->bulk_rx_ep) {
++ aic_free(data);
++ return -ENODEV;
++ }
++
++ data->cmdreq_type = USB_TYPE_CLASS;
++
++ data->udev = udev;
++ data->intf = intf;
++
++ dlfw_dis_state = 0;
++ spin_lock_init(&queue_lock);
++ spin_lock_init(&dlfw_lock);
++ spin_lock_init(&data->lock);
++
++ INIT_WORK(&data->work, btusb_work);
++ INIT_WORK(&data->waker, btusb_waker);
++ spin_lock_init(&data->txlock);
++
++ init_usb_anchor(&data->tx_anchor);
++ init_usb_anchor(&data->intr_anchor);
++ init_usb_anchor(&data->bulk_anchor);
++ init_usb_anchor(&data->isoc_anchor);
++ init_usb_anchor(&data->deferred);
++
++#if (CONFIG_BLUEDROID == 0)
++#if HCI_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)
++ spin_lock_init(&data->rxlock);
++ data->recv_bulk = btusb_recv_bulk;
++#endif
++#endif
++
++
++ fw_info = firmware_info_init(intf);
++ if (fw_info)
++ data->fw_info = fw_info;
++ else {
++ AICBT_WARN("%s: Failed to initialize fw info", __func__);
++ /* Skip download patch */
++ goto end;
++ }
++
++ AICBT_INFO("%s: download begining...", __func__);
++
++#if CONFIG_BLUEDROID
++ mutex_lock(&btchr_mutex);
++#endif
++ if(g_chipid == PRODUCT_ID_AIC8800DC){
++ err = download_patch(data->fw_info,1);
++ }
++
++#if CONFIG_BLUEDROID
++ mutex_unlock(&btchr_mutex);
++#endif
++
++ AICBT_INFO("%s: download ending...", __func__);
++ if (err < 0) {
++ return err;
++ }
++
++
++ hdev = hci_alloc_dev();
++ if (!hdev) {
++ aic_free(data);
++ data = NULL;
++ return -ENOMEM;
++ }
++
++ HDEV_BUS = HCI_USB;
++
++ data->hdev = hdev;
++
++ SET_HCIDEV_DEV(hdev, &intf->dev);
++
++ hdev->open = btusb_open;
++ hdev->close = btusb_close;
++ hdev->flush = btusb_flush;
++ hdev->send = btusb_send_frame;
++ hdev->notify = btusb_notify;
++#if (CONFIG_BLUEDROID == 0)
++#if LINUX_VERSION_CODE > KERNEL_VERSION(4, 0, 9)
++ hdev->shutdown = btusb_shutdown;
++#endif
++#endif //(CONFIG_BLUEDROIF == 0)
++
++#if LINUX_VERSION_CODE > KERNEL_VERSION(3, 4, 0)
++ hci_set_drvdata(hdev, data);
++#else
++ hdev->driver_data = data;
++ hdev->destruct = btusb_destruct;
++ hdev->owner = THIS_MODULE;
++#endif
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 1)
++ if (!reset_on_close){
++ /* set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks); */
++ AICBT_DBG("%s: Set HCI_QUIRK_RESET_ON_CLOSE", __func__);
++ }
++#endif
++
++ /* Interface numbers are hardcoded in the specification */
++ data->isoc = usb_ifnum_to_if(data->udev, 1);
++ if (data->isoc) {
++ err = usb_driver_claim_interface(&btusb_driver,
++ data->isoc, data);
++ if (err < 0) {
++ hci_free_dev(hdev);
++ hdev = NULL;
++ aic_free(data);
++ data = NULL;
++ return err;
++ }
++#ifdef CONFIG_SCO_OVER_HCI
++ data->pSCOSnd = btusb_snd_init(intf, id, data);
++#endif
++ }
++
++ err = hci_register_dev(hdev);
++ if (err < 0) {
++ hci_free_dev(hdev);
++ hdev = NULL;
++ aic_free(data);
++ data = NULL;
++ return err;
++ }
++
++ usb_set_intfdata(intf, data);
++
++//#ifdef CONFIG_HAS_EARLYSUSPEND
++#if 0
++ data->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN;
++ data->early_suspend.suspend = btusb_early_suspend;
++ data->early_suspend.resume = btusb_late_resume;
++ register_early_suspend(&data->early_suspend);
++#else
++ data->pm_notifier.notifier_call = bt_pm_notify;
++ data->reboot_notifier.notifier_call = bt_reboot_notify;
++ register_pm_notifier(&data->pm_notifier);
++ register_reboot_notifier(&data->reboot_notifier);
++#endif
++
++#if CONFIG_BLUEDROID
++ AICBT_INFO("%s: Check bt reset flag %d", __func__, bt_reset);
++ /* Report hci hardware error after everthing is ready,
++ * especially hci register is completed. Or, btchr_poll
++ * will get null hci dev when hotplug in.
++ */
++ if (bt_reset == 1) {
++ hci_hardware_error();
++ bt_reset = 0;
++ } else
++ bt_reset = 0; /* Clear and reset it anyway */
++#endif
++
++end:
++ return 0;
++}
++
++static void btusb_disconnect(struct usb_interface *intf)
++{
++ struct btusb_data *data;
++ struct hci_dev *hdev = NULL;
++#if CONFIG_BLUEDROID
++ wait_event_interruptible(bt_dlfw_wait, (check_set_dlfw_state_value(2) == 2));
++#endif
++
++ bt_support = 0;
++
++ AICBT_INFO("%s: usb_interface %p, bInterfaceNumber %d",
++ __func__, intf, intf->cur_altsetting->desc.bInterfaceNumber);
++
++ data = usb_get_intfdata(intf);
++
++ if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
++ return;
++
++ if (data)
++ hdev = data->hdev;
++ else {
++ AICBT_WARN("%s: Failed to get bt usb data[Null]", __func__);
++ return;
++ }
++
++#ifdef CONFIG_SCO_OVER_HCI
++ if (intf->cur_altsetting->desc.bInterfaceNumber == 0) {
++ AIC_sco_card_t *pSCOSnd = data->pSCOSnd;
++ if(!pSCOSnd) {
++ AICBT_ERR("%s: sco private data is null", __func__);
++ return;
++ }
++ set_bit(DISCONNECTED, &pSCOSnd->states);
++ snd_card_disconnect(pSCOSnd->card);
++ snd_card_free_when_closed(pSCOSnd->card);
++ }
++#endif
++
++//#ifdef CONFIG_HAS_EARLYSUSPEND
++#if 0
++ unregister_early_suspend(&data->early_suspend);
++#else
++ unregister_pm_notifier(&data->pm_notifier);
++ unregister_reboot_notifier(&data->reboot_notifier);
++#endif
++
++ firmware_info_destroy(intf);
++
++#if CONFIG_BLUEDROID
++ if (test_bit(HCI_RUNNING, &hdev->flags)) {
++ AICBT_INFO("%s: Set BT reset flag", __func__);
++ bt_reset = 1;
++ }
++#endif
++
++ usb_set_intfdata(data->intf, NULL);
++
++ if (data->isoc)
++ usb_set_intfdata(data->isoc, NULL);
++
++ hci_unregister_dev(hdev);
++
++ if (intf == data->isoc)
++ usb_driver_release_interface(&btusb_driver, data->intf);
++ else if (data->isoc)
++ usb_driver_release_interface(&btusb_driver, data->isoc);
++
++#if !CONFIG_BLUEDROID
++#if LINUX_VERSION_CODE <= KERNEL_VERSION(3, 4, 0)
++ __hci_dev_put(hdev);
++#endif
++#endif
++
++ hci_free_dev(hdev);
++ aic_free(data);
++ data = NULL;
++ set_dlfw_state_value(0);
++}
++
++#ifdef CONFIG_PM
++static int btusb_suspend(struct usb_interface *intf, pm_message_t message)
++{
++ struct btusb_data *data = usb_get_intfdata(intf);
++ //firmware_info *fw_info = data->fw_info;
++
++ AICBT_INFO("%s: event 0x%x, suspend count %d", __func__,
++ message.event, data->suspend_count);
++
++ if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
++ return 0;
++#if 0
++ if (!test_bit(HCI_RUNNING, &data->hdev->flags))
++ set_bt_onoff(fw_info, 1);
++#endif
++ if (data->suspend_count++)
++ return 0;
++
++ spin_lock_irq(&data->txlock);
++ if (!((message.event & PM_EVENT_AUTO) && data->tx_in_flight)) {
++ set_bit(BTUSB_SUSPENDING, &data->flags);
++ spin_unlock_irq(&data->txlock);
++ } else {
++ spin_unlock_irq(&data->txlock);
++ data->suspend_count--;
++ AICBT_ERR("%s: Failed to enter suspend", __func__);
++ return -EBUSY;
++ }
++
++ cancel_work_sync(&data->work);
++
++ btusb_stop_traffic(data);
++ mdelay(URB_CANCELING_DELAY_MS);
++ usb_kill_anchored_urbs(&data->tx_anchor);
++
++ return 0;
++}
++
++static void play_deferred(struct btusb_data *data)
++{
++ struct urb *urb;
++ int err;
++
++ while ((urb = usb_get_from_anchor(&data->deferred))) {
++ usb_anchor_urb(urb, &data->tx_anchor);
++ err = usb_submit_urb(urb, GFP_ATOMIC);
++ if (err < 0) {
++ AICBT_ERR("%s: Failed to submit urb %p, err %d",
++ __func__, urb, err);
++ kfree(urb->setup_packet);
++ usb_unanchor_urb(urb);
++ } else {
++ usb_mark_last_busy(data->udev);
++ }
++ usb_free_urb(urb);
++
++ data->tx_in_flight++;
++ }
++ mdelay(URB_CANCELING_DELAY_MS);
++ usb_scuttle_anchored_urbs(&data->deferred);
++}
++
++static int btusb_resume(struct usb_interface *intf)
++{
++ struct btusb_data *data = usb_get_intfdata(intf);
++ struct hci_dev *hdev = data->hdev;
++ int err = 0;
++
++ AICBT_INFO("%s: Suspend count %d", __func__, data->suspend_count);
++
++ if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
++ return 0;
++
++ if (--data->suspend_count)
++ return 0;
++
++ #if 0
++ /*check_fw_version to check the status of the BT Controller after USB Resume*/
++ err = check_fw_version(fw_info);
++ if (err !=0)
++ {
++ AICBT_INFO("%s: BT Controller Power OFF And Return hci_hardware_error:%d", __func__, err);
++ hci_hardware_error();
++ }
++ #endif
++
++ AICBT_INFO("%s g_chipid %x\n", __func__, g_chipid);
++ if(g_chipid == PRODUCT_ID_AIC8800DC){
++ if(data->fw_info){
++ err = download_patch(data->fw_info,1);
++ }else{
++ AICBT_WARN("%s: Failed to initialize fw info", __func__);
++ }
++ }
++
++ #if 1
++ if (test_bit(BTUSB_INTR_RUNNING, &data->flags)) {
++ err = btusb_submit_intr_urb(hdev, GFP_NOIO);
++ if (err < 0) {
++ clear_bit(BTUSB_INTR_RUNNING, &data->flags);
++ goto failed;
++ }
++ }
++ #endif
++
++ if (test_bit(BTUSB_BULK_RUNNING, &data->flags)) {
++ err = btusb_submit_bulk_urb(hdev, GFP_NOIO);
++ if (err < 0) {
++ clear_bit(BTUSB_BULK_RUNNING, &data->flags);
++ goto failed;
++ }
++
++ btusb_submit_bulk_urb(hdev, GFP_NOIO);
++ }
++
++ if (test_bit(BTUSB_ISOC_RUNNING, &data->flags)) {
++ if (btusb_submit_isoc_urb(hdev, GFP_NOIO) < 0)
++ clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
++ else
++ btusb_submit_isoc_urb(hdev, GFP_NOIO);
++ }
++
++ spin_lock_irq(&data->txlock);
++ play_deferred(data);
++ clear_bit(BTUSB_SUSPENDING, &data->flags);
++ spin_unlock_irq(&data->txlock);
++ schedule_work(&data->work);
++
++ return 0;
++
++failed:
++ mdelay(URB_CANCELING_DELAY_MS);
++ usb_scuttle_anchored_urbs(&data->deferred);
++ spin_lock_irq(&data->txlock);
++ clear_bit(BTUSB_SUSPENDING, &data->flags);
++ spin_unlock_irq(&data->txlock);
++
++ return err;
++}
++#endif
++
++static struct usb_driver btusb_driver = {
++ .name = "aic_btusb",
++ .probe = btusb_probe,
++ .disconnect = btusb_disconnect,
++#ifdef CONFIG_PM
++ .suspend = btusb_suspend,
++ .resume = btusb_resume,
++#if CONFIG_RESET_RESUME
++ .reset_resume = btusb_resume,
++#endif
++#endif
++ .id_table = btusb_table,
++ .supports_autosuspend = 1,
++#if LINUX_VERSION_CODE > KERNEL_VERSION(3, 7, 1)
++ .disable_hub_initiated_lpm = 1,
++#endif
++};
++
++static int __init btusb_init(void)
++{
++ int err;
++
++ AICBT_INFO("AICBT_RELEASE_NAME: %s",AICBT_RELEASE_NAME);
++ AICBT_INFO("AicSemi Bluetooth USB driver module init, version %s", VERSION);
++ AICBT_INFO("RELEASE DATE: 2023_0506_1635 \r\n");
++#if CONFIG_BLUEDROID
++ err = btchr_init();
++ if (err < 0) {
++ /* usb register will go on, even bt char register failed */
++ AICBT_ERR("Failed to register usb char device interfaces");
++ } else
++ bt_char_dev_registered = 1;
++#endif
++ err = usb_register(&btusb_driver);
++ if (err < 0)
++ AICBT_ERR("Failed to register aic bluetooth USB driver");
++ return err;
++}
++
++static void __exit btusb_exit(void)
++{
++ AICBT_INFO("AicSemi Bluetooth USB driver module exit");
++#if CONFIG_BLUEDROID
++ if (bt_char_dev_registered > 0)
++ btchr_exit();
++#endif
++ usb_deregister(&btusb_driver);
++}
++
++module_init(btusb_init);
++module_exit(btusb_exit);
++
++
++module_param(mp_drv_mode, int, 0644);
++MODULE_PARM_DESC(mp_drv_mode, "0: NORMAL; 1: MP MODE");
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)
++MODULE_IMPORT_NS(VFS_internal_I_am_really_a_filesystem_and_am_NOT_a_driver);
++#endif
++
++MODULE_AUTHOR("AicSemi Corporation");
++MODULE_DESCRIPTION("AicSemi Bluetooth USB driver version");
++MODULE_VERSION(VERSION);
++MODULE_LICENSE("GPL");
+--- /dev/null
++++ b/drivers/bluetooth/aic_btusb/aic_btusb.h
+@@ -0,0 +1,753 @@
++/*
++ *
++ * Aic Bluetooth USB driver
++ *
++ *
++ * 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 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.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++#include <linux/interrupt.h>
++#include <linux/module.h>
++#include <linux/slab.h>
++#include <linux/types.h>
++#include <linux/sched.h>
++#include <linux/skbuff.h>
++#include <linux/errno.h>
++#include <linux/usb.h>
++#include <linux/cdev.h>
++#include <linux/device.h>
++#include <linux/poll.h>
++
++#include <linux/version.h>
++#include <linux/pm_runtime.h>
++#include <linux/firmware.h>
++#include <linux/suspend.h>
++
++
++#ifdef CONFIG_PLATFORM_UBUNTU
++#define CONFIG_BLUEDROID 0 /* bleuz 0, bluedroid 1 */
++#else
++#define CONFIG_BLUEDROID 1 /* bleuz 0, bluedroid 1 */
++#endif
++
++
++//#define CONFIG_SCO_OVER_HCI
++#define CONFIG_USB_AIC_UART_SCO_DRIVER
++
++#ifdef CONFIG_SCO_OVER_HCI
++#include <linux/usb/audio.h>
++#include <sound/core.h>
++#include <sound/initval.h>
++#include <sound/pcm.h>
++#include <sound/pcm_params.h>
++
++#define AIC_SCO_ID "snd_sco_aic"
++enum {
++ USB_CAPTURE_RUNNING,
++ USB_PLAYBACK_RUNNING,
++ ALSA_CAPTURE_OPEN,
++ ALSA_PLAYBACK_OPEN,
++ ALSA_CAPTURE_RUNNING,
++ ALSA_PLAYBACK_RUNNING,
++ CAPTURE_URB_COMPLETED,
++ PLAYBACK_URB_COMPLETED,
++ DISCONNECTED,
++};
++
++// AIC sound card
++typedef struct AIC_sco_card {
++ struct snd_card *card;
++ struct snd_pcm *pcm;
++ struct usb_device *dev;
++ struct btusb_data *usb_data;
++ unsigned long states;
++ struct aic_sco_stream {
++ struct snd_pcm_substream *substream;
++ unsigned int sco_packet_bytes;
++ snd_pcm_uframes_t buffer_pos;
++ } capture, playback;
++ spinlock_t capture_lock;
++ spinlock_t playback_lock;
++ struct work_struct send_sco_work;
++} AIC_sco_card_t;
++#endif
++/* Some Android system may use standard Linux kernel, while
++ * standard Linux may also implement early suspend feature.
++ * So exclude earysuspend.h from CONFIG_BLUEDROID.
++ */
++#ifdef CONFIG_HAS_EARLYSUSPEND
++#include <linux/earlysuspend.h>
++#endif
++
++#if CONFIG_BLUEDROID
++#else
++#include <net/bluetooth/bluetooth.h>
++#include <net/bluetooth/hci_core.h>
++#include <net/bluetooth/hci.h>
++#endif
++
++
++/***********************************
++** AicSemi - For aic_btusb driver **
++***********************************/
++#define URB_CANCELING_DELAY_MS 10
++/* when OS suspended, module is still powered,usb is not powered,
++ * this may set to 1, and must comply with special patch code.
++ */
++#define CONFIG_RESET_RESUME 1
++#define PRINT_CMD_EVENT 0
++#define PRINT_ACL_DATA 0
++#define PRINT_SCO_DATA 0
++
++#define AICBT_DBG_FLAG 0
++
++#if AICBT_DBG_FLAG
++#define AICBT_DBG(fmt, arg...) printk( "aic_btusb: " fmt "\n" , ## arg)
++#else
++#define AICBT_DBG(fmt, arg...)
++#endif
++
++#define AICBT_INFO(fmt, arg...) printk("aic_btusb: " fmt "\n" , ## arg)
++#define AICBT_WARN(fmt, arg...) printk("aic_btusb: " fmt "\n" , ## arg)
++#define AICBT_ERR(fmt, arg...) printk("aic_btusb: " fmt "\n" , ## arg)
++
++
++#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 33)
++#define HDEV_BUS hdev->bus
++#define USB_RPM 1
++#else
++#define HDEV_BUS hdev->type
++#define USB_RPM 0
++#endif
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 38)
++#define NUM_REASSEMBLY 3
++#endif
++
++#if LINUX_VERSION_CODE > KERNEL_VERSION(3, 4, 0)
++#define GET_DRV_DATA(x) hci_get_drvdata(x)
++#else
++#define GET_DRV_DATA(x) x->driver_data
++#endif
++
++#define SCO_NUM hdev->conn_hash.sco_num
++
++
++#define BTUSB_RPM (0 * USB_RPM) /* 1 SS enable; 0 SS disable */
++#define BTUSB_WAKEUP_HOST 0 /* 1 enable; 0 disable */
++#define BTUSB_MAX_ISOC_FRAMES 48
++#define BTUSB_INTR_RUNNING 0
++#define BTUSB_BULK_RUNNING 1
++#define BTUSB_ISOC_RUNNING 2
++#define BTUSB_SUSPENDING 3
++#define BTUSB_DID_ISO_RESUME 4
++
++#define HCI_VENDOR_USB_DISC_HARDWARE_ERROR 0xFF
++
++#define HCI_CMD_READ_BD_ADDR 0x1009
++#define HCI_VENDOR_READ_LMP_VERISION 0x1001
++#define HCI_VENDOR_RESET 0x0C03
++
++#define DRV_NORMAL_MODE 0
++#define DRV_MP_MODE 1
++int mp_drv_mode = 0; /* 1 Mptool Fw; 0 Normal Fw */
++
++
++#if CONFIG_BLUEDROID
++#define QUEUE_SIZE 500
++
++/***************************************
++** AicSemi - Integrate from bluetooth.h **
++*****************************************/
++/* Reserv for core and drivers use */
++#define BT_SKB_RESERVE 8
++
++/* BD Address */
++typedef struct {
++ __u8 b[6];
++} __packed bdaddr_t;
++
++/* Skb helpers */
++struct bt_skb_cb {
++ __u8 pkt_type;
++ __u8 incoming;
++ __u16 expect;
++ __u16 tx_seq;
++ __u8 retries;
++ __u8 sar;
++ __u8 force_active;
++};
++
++#define bt_cb(skb) ((struct bt_skb_cb *)((skb)->cb))
++
++static inline struct sk_buff *bt_skb_alloc(unsigned int len, gfp_t how)
++{
++ struct sk_buff *skb;
++
++ if ((skb = alloc_skb(len + BT_SKB_RESERVE, how))) {
++ skb_reserve(skb, BT_SKB_RESERVE);
++ bt_cb(skb)->incoming = 0;
++ }
++ return skb;
++}
++/* AicSemi - Integrate from bluetooth.h end */
++
++/***********************************
++** AicSemi - Integrate from hci.h **
++***********************************/
++#define HCI_MAX_ACL_SIZE 1024
++#define HCI_MAX_SCO_SIZE 255
++#define HCI_MAX_EVENT_SIZE 260
++#define HCI_MAX_FRAME_SIZE (HCI_MAX_ACL_SIZE + 4)
++
++/* HCI bus types */
++#define HCI_VIRTUAL 0
++#define HCI_USB 1
++#define HCI_PCCARD 2
++#define HCI_UART 3
++#define HCI_RS232 4
++#define HCI_PCI 5
++#define HCI_SDIO 6
++
++/* HCI controller types */
++#define HCI_BREDR 0x00
++#define HCI_AMP 0x01
++
++/* HCI device flags */
++enum {
++ HCI_UP,
++ HCI_INIT,
++ HCI_RUNNING,
++
++ HCI_PSCAN,
++ HCI_ISCAN,
++ HCI_AUTH,
++ HCI_ENCRYPT,
++ HCI_INQUIRY,
++
++ HCI_RAW,
++
++ HCI_RESET,
++};
++
++/*
++ * BR/EDR and/or LE controller flags: the flags defined here should represent
++ * states from the controller.
++ */
++enum {
++ HCI_SETUP,
++ HCI_AUTO_OFF,
++ HCI_MGMT,
++ HCI_PAIRABLE,
++ HCI_SERVICE_CACHE,
++ HCI_LINK_KEYS,
++ HCI_DEBUG_KEYS,
++ HCI_UNREGISTER,
++
++ HCI_LE_SCAN,
++ HCI_SSP_ENABLED,
++ HCI_HS_ENABLED,
++ HCI_LE_ENABLED,
++ HCI_CONNECTABLE,
++ HCI_DISCOVERABLE,
++ HCI_LINK_SECURITY,
++ HCI_PENDING_CLASS,
++};
++
++/* HCI data types */
++#define HCI_COMMAND_PKT 0x01
++#define HCI_ACLDATA_PKT 0x02
++#define HCI_SCODATA_PKT 0x03
++#define HCI_EVENT_PKT 0x04
++#define HCI_VENDOR_PKT 0xff
++
++#define HCI_MAX_NAME_LENGTH 248
++#define HCI_MAX_EIR_LENGTH 240
++
++#define HCI_OP_READ_LOCAL_VERSION 0x1001
++struct hci_rp_read_local_version {
++ __u8 status;
++ __u8 hci_ver;
++ __le16 hci_rev;
++ __u8 lmp_ver;
++ __le16 manufacturer;
++ __le16 lmp_subver;
++} __packed;
++
++#define HCI_EV_CMD_COMPLETE 0x0e
++struct hci_ev_cmd_complete {
++ __u8 ncmd;
++ __le16 opcode;
++} __packed;
++
++/* ---- HCI Packet structures ---- */
++#define HCI_COMMAND_HDR_SIZE 3
++#define HCI_EVENT_HDR_SIZE 2
++#define HCI_ACL_HDR_SIZE 4
++#define HCI_SCO_HDR_SIZE 3
++
++struct hci_command_hdr {
++ __le16 opcode; /* OCF & OGF */
++ __u8 plen;
++} __packed;
++
++struct hci_event_hdr {
++ __u8 evt;
++ __u8 plen;
++} __packed;
++
++struct hci_acl_hdr {
++ __le16 handle; /* Handle & Flags(PB, BC) */
++ __le16 dlen;
++} __packed;
++
++struct hci_sco_hdr {
++ __le16 handle;
++ __u8 dlen;
++} __packed;
++
++static inline struct hci_event_hdr *hci_event_hdr(const struct sk_buff *skb)
++{
++ return (struct hci_event_hdr *) skb->data;
++}
++
++static inline struct hci_acl_hdr *hci_acl_hdr(const struct sk_buff *skb)
++{
++ return (struct hci_acl_hdr *) skb->data;
++}
++
++static inline struct hci_sco_hdr *hci_sco_hdr(const struct sk_buff *skb)
++{
++ return (struct hci_sco_hdr *) skb->data;
++}
++
++/* ---- HCI Ioctl requests structures ---- */
++struct hci_dev_stats {
++ __u32 err_rx;
++ __u32 err_tx;
++ __u32 cmd_tx;
++ __u32 evt_rx;
++ __u32 acl_tx;
++ __u32 acl_rx;
++ __u32 sco_tx;
++ __u32 sco_rx;
++ __u32 byte_rx;
++ __u32 byte_tx;
++};
++/* AicSemi - Integrate from hci.h end */
++
++/*****************************************
++** AicSemi - Integrate from hci_core.h **
++*****************************************/
++struct hci_conn_hash {
++ struct list_head list;
++ unsigned int acl_num;
++ unsigned int sco_num;
++ unsigned int le_num;
++};
++
++#define HCI_MAX_SHORT_NAME_LENGTH 10
++
++#define NUM_REASSEMBLY 4
++struct hci_dev {
++ struct mutex lock;
++
++ char name[8];
++ unsigned long flags;
++ __u16 id;
++ __u8 bus;
++ __u8 dev_type;
++
++ struct sk_buff *reassembly[NUM_REASSEMBLY];
++
++ struct hci_conn_hash conn_hash;
++
++ struct hci_dev_stats stat;
++
++#if LINUX_VERSION_CODE <= KERNEL_VERSION(3, 4, 0)
++ atomic_t refcnt;
++ struct module *owner;
++ void *driver_data;
++#endif
++
++ atomic_t promisc;
++
++ struct device *parent;
++ struct device dev;
++
++ unsigned long dev_flags;
++
++ int (*open)(struct hci_dev *hdev);
++ int (*close)(struct hci_dev *hdev);
++ int (*flush)(struct hci_dev *hdev);
++ int (*send)(struct sk_buff *skb);
++#if LINUX_VERSION_CODE <= KERNEL_VERSION(3, 4, 0)
++ void (*destruct)(struct hci_dev *hdev);
++#endif
++#if LINUX_VERSION_CODE > KERNEL_VERSION(3, 7, 1)
++ __u16 voice_setting;
++#endif
++ void (*notify)(struct hci_dev *hdev, unsigned int evt);
++ int (*ioctl)(struct hci_dev *hdev, unsigned int cmd, unsigned long arg);
++ u8 *align_data;
++};
++
++#if LINUX_VERSION_CODE <= KERNEL_VERSION(3, 4, 0)
++static inline struct hci_dev *__hci_dev_hold(struct hci_dev *d)
++{
++ atomic_inc(&d->refcnt);
++ return d;
++}
++
++static inline void __hci_dev_put(struct hci_dev *d)
++{
++ if (atomic_dec_and_test(&d->refcnt))
++ d->destruct(d);
++}
++#endif
++
++static inline void *hci_get_drvdata(struct hci_dev *hdev)
++{
++ return dev_get_drvdata(&hdev->dev);
++}
++
++static inline void hci_set_drvdata(struct hci_dev *hdev, void *data)
++{
++ dev_set_drvdata(&hdev->dev, data);
++}
++
++#define SET_HCIDEV_DEV(hdev, pdev) ((hdev)->parent = (pdev))
++/* AicSemi - Integrate from hci_core.h end */
++
++/* ----- HCI Commands ---- */
++#define HCI_OP_INQUIRY 0x0401
++#define HCI_OP_INQUIRY_CANCEL 0x0402
++#define HCI_OP_EXIT_PERIODIC_INQ 0x0404
++#define HCI_OP_CREATE_CONN 0x0405
++#define HCI_OP_DISCONNECT 0x0406
++#define HCI_OP_ADD_SCO 0x0407
++#define HCI_OP_CREATE_CONN_CANCEL 0x0408
++#define HCI_OP_ACCEPT_CONN_REQ 0x0409
++#define HCI_OP_REJECT_CONN_REQ 0x040a
++#define HCI_OP_LINK_KEY_REPLY 0x040b
++#define HCI_OP_LINK_KEY_NEG_REPLY 0x040c
++#define HCI_OP_PIN_CODE_REPLY 0x040d
++#define HCI_OP_PIN_CODE_NEG_REPLY 0x040e
++#define HCI_OP_CHANGE_CONN_PTYPE 0x040f
++#define HCI_OP_AUTH_REQUESTED 0x0411
++#define HCI_OP_SET_CONN_ENCRYPT 0x0413
++#define HCI_OP_CHANGE_CONN_LINK_KEY 0x0415
++#define HCI_OP_REMOTE_NAME_REQ 0x0419
++#define HCI_OP_REMOTE_NAME_REQ_CANCEL 0x041a
++#define HCI_OP_READ_REMOTE_FEATURES 0x041b
++#define HCI_OP_READ_REMOTE_EXT_FEATURES 0x041c
++#define HCI_OP_READ_REMOTE_VERSION 0x041d
++#define HCI_OP_SETUP_SYNC_CONN 0x0428
++#define HCI_OP_ACCEPT_SYNC_CONN_REQ 0x0429
++#define HCI_OP_REJECT_SYNC_CONN_REQ 0x042a
++#define HCI_OP_SNIFF_MODE 0x0803
++#define HCI_OP_EXIT_SNIFF_MODE 0x0804
++#define HCI_OP_ROLE_DISCOVERY 0x0809
++#define HCI_OP_SWITCH_ROLE 0x080b
++#define HCI_OP_READ_LINK_POLICY 0x080c
++#define HCI_OP_WRITE_LINK_POLICY 0x080d
++#define HCI_OP_READ_DEF_LINK_POLICY 0x080e
++#define HCI_OP_WRITE_DEF_LINK_POLICY 0x080f
++#define HCI_OP_SNIFF_SUBRATE 0x0811
++#define HCI_OP_Write_Link_Policy_Settings 0x080d
++#define HCI_OP_SET_EVENT_MASK 0x0c01
++#define HCI_OP_RESET 0x0c03
++#define HCI_OP_SET_EVENT_FLT 0x0c05
++#define HCI_OP_Write_Extended_Inquiry_Response 0x0c52
++#define HCI_OP_Write_Simple_Pairing_Mode 0x0c56
++#define HCI_OP_Read_Buffer_Size 0x1005
++#define HCI_OP_Host_Buffer_Size 0x0c33
++#define HCI_OP_Read_Local_Version_Information 0x1001
++#define HCI_OP_Read_BD_ADDR 0x1009
++#define HCI_OP_Read_Local_Supported_Commands 0x1002
++#define HCI_OP_Write_Scan_Enable 0x0c1a
++#define HCI_OP_Write_Current_IAC_LAP 0x0c3a
++#define HCI_OP_Write_Inquiry_Scan_Activity 0x0c1e
++#define HCI_OP_Write_Class_of_Device 0x0c24
++#define HCI_OP_LE_Rand 0x2018
++#define HCI_OP_LE_Set_Random_Address 0x2005
++#define HCI_OP_LE_Set_Extended_Scan_Enable 0x2042
++#define HCI_OP_LE_Set_Extended_Scan_Parameters 0x2041
++#define HCI_OP_Set_Event_Filter 0x0c05
++#define HCI_OP_Write_Voice_Setting 0x0c26
++#define HCI_OP_Change_Local_Name 0x0c13
++#define HCI_OP_Read_Local_Name 0x0c14
++#define HCI_OP_Wirte_Page_Timeout 0x0c18
++#define HCI_OP_LE_Clear_Resolving_List 0x0c29
++#define HCI_OP_LE_Set_Addres_Resolution_Enable_Command 0x0c2e
++#define HCI_OP_Write_Inquiry_mode 0x0c45
++#define HCI_OP_Write_Page_Scan_Type 0x0c47
++#define HCI_OP_Write_Inquiry_Scan_Type 0x0c43
++
++#define HCI_OP_Delete_Stored_Link_Key 0x0c12
++#define HCI_OP_LE_Read_Local_Resolvable_Address 0x202d
++#define HCI_OP_LE_Extended_Create_Connection 0x2043
++#define HCI_OP_Read_Remote_Version_Information 0x041d
++#define HCI_OP_LE_Start_Encryption 0x2019
++#define HCI_OP_LE_Add_Device_to_Resolving_List 0x2027
++#define HCI_OP_LE_Set_Privacy_Mode 0x204e
++#define HCI_OP_LE_Connection_Update 0x2013
++
++/* ----- HCI events---- */
++#define HCI_OP_DISCONNECT 0x0406
++#define HCI_EV_INQUIRY_COMPLETE 0x01
++#define HCI_EV_INQUIRY_RESULT 0x02
++#define HCI_EV_CONN_COMPLETE 0x03
++#define HCI_EV_CONN_REQUEST 0x04
++#define HCI_EV_DISCONN_COMPLETE 0x05
++#define HCI_EV_AUTH_COMPLETE 0x06
++#define HCI_EV_REMOTE_NAME 0x07
++#define HCI_EV_ENCRYPT_CHANGE 0x08
++#define HCI_EV_CHANGE_LINK_KEY_COMPLETE 0x09
++
++#define HCI_EV_REMOTE_FEATURES 0x0b
++#define HCI_EV_REMOTE_VERSION 0x0c
++#define HCI_EV_QOS_SETUP_COMPLETE 0x0d
++#define HCI_EV_CMD_COMPLETE 0x0e
++#define HCI_EV_CMD_STATUS 0x0f
++
++#define HCI_EV_ROLE_CHANGE 0x12
++#define HCI_EV_NUM_COMP_PKTS 0x13
++#define HCI_EV_MODE_CHANGE 0x14
++#define HCI_EV_PIN_CODE_REQ 0x16
++#define HCI_EV_LINK_KEY_REQ 0x17
++#define HCI_EV_LINK_KEY_NOTIFY 0x18
++#define HCI_EV_CLOCK_OFFSET 0x1c
++#define HCI_EV_PKT_TYPE_CHANGE 0x1d
++#define HCI_EV_PSCAN_REP_MODE 0x20
++
++#define HCI_EV_INQUIRY_RESULT_WITH_RSSI 0x22
++#define HCI_EV_REMOTE_EXT_FEATURES 0x23
++#define HCI_EV_SYNC_CONN_COMPLETE 0x2c
++#define HCI_EV_SYNC_CONN_CHANGED 0x2d
++#define HCI_EV_SNIFF_SUBRATE 0x2e
++#define HCI_EV_EXTENDED_INQUIRY_RESULT 0x2f
++#define HCI_EV_IO_CAPA_REQUEST 0x31
++#define HCI_EV_SIMPLE_PAIR_COMPLETE 0x36
++#define HCI_EV_REMOTE_HOST_FEATURES 0x3d
++#define HCI_EV_LE_Meta 0x3e
++
++#define CONFIG_MAC_OFFSET_GEN_1_2 (0x3C) //MAC's OFFSET in config/efuse for aic generation 1~2 bluetooth chip
++#define CONFIG_MAC_OFFSET_GEN_3PLUS (0x44) //MAC's OFFSET in config/efuse for aic generation 3+ bluetooth chip
++
++
++typedef struct {
++ uint16_t vid;
++ uint16_t pid;
++ uint16_t lmp_sub_default;
++ uint16_t lmp_sub;
++ uint16_t eversion;
++ char *mp_patch_name;
++ char *patch_name;
++ char *config_name;
++ uint8_t *fw_cache;
++ int fw_len;
++ uint16_t mac_offset;
++ uint32_t max_patch_size;
++} patch_info;
++
++//Define ioctl cmd the same as HCIDEVUP in the kernel
++#define DOWN_FW_CFG _IOW('E', 176, int)
++//#ifdef CONFIG_SCO_OVER_HCI
++//#define SET_ISO_CFG _IOW('H', 202, int)
++//#else
++#define SET_ISO_CFG _IOW('E', 177, int)
++//#endif
++#define RESET_CONTROLLER _IOW('E', 178, int)
++#define DWFW_CMPLT _IOW('E', 179, int)
++
++#define GET_USB_INFO _IOR('E', 180, int)
++
++/* for altsettings*/
++#include <linux/fs.h>
++#define BDADDR_FILE "/data/misc/bluetooth/bdaddr"
++#define FACTORY_BT_BDADDR_STORAGE_LEN 17
++#if 0
++static inline int getmacaddr(uint8_t * vnd_local_bd_addr)
++{
++ struct file *bdaddr_file;
++ mm_segment_t oldfs;
++ char buf[FACTORY_BT_BDADDR_STORAGE_LEN];
++ int32_t i = 0;
++ memset(buf, 0, FACTORY_BT_BDADDR_STORAGE_LEN);
++ bdaddr_file = filp_open(BDADDR_FILE, O_RDONLY, 0);
++ if (IS_ERR(bdaddr_file)){
++ AICBT_INFO("No Mac Config for BT\n");
++ return -1;
++ }
++ oldfs = get_fs();
++ set_fs(KERNEL_DS);
++ bdaddr_file->f_op->llseek(bdaddr_file, 0, 0);
++ bdaddr_file->f_op->read(bdaddr_file, buf, FACTORY_BT_BDADDR_STORAGE_LEN, &bdaddr_file->f_pos);
++ for (i = 0; i < 6; i++) {
++ if(buf[3*i]>'9')
++ {
++ if(buf[3*i]>'Z')
++ buf[3*i] -=('a'-'A'); //change a to A
++ buf[3*i] -= ('A'-'9'-1);
++ }
++ if(buf[3*i+1]>'9')
++ {
++ if(buf[3*i+1]>'Z')
++ buf[3*i+1] -=('a'-'A'); //change a to A
++ buf[3*i+1] -= ('A'-'9'-1);
++ }
++ vnd_local_bd_addr[5-i] = ((uint8_t)buf[3*i]-'0')*16 + ((uint8_t)buf[3*i+1]-'0');
++ }
++ set_fs(oldfs);
++ filp_close(bdaddr_file, NULL);
++ return 0;
++}
++#endif
++
++#endif /* CONFIG_BLUEDROID */
++
++
++typedef struct {
++ struct usb_interface *intf;
++ struct usb_device *udev;
++ int pipe_in, pipe_out;
++ uint8_t *send_pkt;
++ uint8_t *rcv_pkt;
++ struct hci_command_hdr *cmd_hdr;
++ struct hci_event_hdr *evt_hdr;
++ struct hci_ev_cmd_complete *cmd_cmp;
++ uint8_t *req_para, *rsp_para;
++ uint8_t *fw_data;
++ int pkt_len;
++ int fw_len;
++} firmware_info;
++
++/*******************************
++** Reasil patch code
++********************************/
++#define CMD_CMP_EVT 0x0e
++#define RCV_PKT_LEN 64
++#define SEND_PKT_LEN 300
++#define MSG_TO 1000
++#define PATCH_SEG_MAX 252
++#define DATA_END 0x80
++#define DOWNLOAD_OPCODE 0xfc02
++#define HCI_VSC_UPDATE_PT_CMD 0xFC75
++#define BTOFF_OPCODE 0xfc28
++#define TRUE 1
++#define FALSE 0
++#define CMD_HDR_LEN sizeof(struct hci_command_hdr)
++#define EVT_HDR_LEN sizeof(struct hci_event_hdr)
++#define CMD_CMP_LEN sizeof(struct hci_ev_cmd_complete)
++#define MAX_PATCH_SIZE_24K (1024*24)
++#define MAX_PATCH_SIZE_40K (1024*40)
++
++
++#define FW_RAM_ADID_BASE_ADDR 0x101788
++#define FW_RAM_PATCH_BASE_ADDR 0x184000
++#define FW_ADID_BASE_NAME "fw_adid_8800dc.bin"
++#define FW_PATCH_TABLE_NAME "fw_patch_table_8800dc.bin"
++#define FW_PATCH_BASE_NAME "fw_patch_8800dc.bin"
++#define FW_PATCH_TABLE_NAME_U02 "fw_patch_table_8800dc_u02.bin"
++#define FW_PATCH_BASE_NAME_U02 "fw_patch_8800dc_u02.bin"
++#define FW_PATCH_TABLE_NAME_U02H "fw_patch_table_8800dc_u02h.bin"
++#define FW_PATCH_BASE_NAME_U02H "fw_patch_8800dc_u02h.bin"
++#define AICBT_PT_TAG "AICBT_PT_TAG"
++
++enum aicbt_patch_table_type {
++ AICBT_PT_NULL = 0x00,
++ AICBT_PT_TRAP,
++ AICBT_PT_B4,
++ AICBT_PT_BTMODE,
++ AICBT_PT_PWRON,
++ AICBT_PT_AF,
++ AICBT_PT_VER,
++ AICBT_PT_MAX,
++};
++
++#define HCI_VSC_FW_STATUS_GET_CMD 0xFC78
++
++struct fw_status {
++ u8 status;
++} __packed;
++
++#define HCI_PATCH_DATA_MAX_LEN 240
++#define HCI_VSC_MEM_WR_SIZE 240
++#define HCI_VSC_MEM_RD_SIZE 128
++#define HCI_VSC_UPDATE_PT_SIZE 249
++#define HCI_PT_MAX_LEN 31
++
++#define HCI_VSC_DBG_RD_MEM_CMD 0xFC01
++
++struct hci_dbg_rd_mem_cmd {
++ __le32 start_addr;
++ __u8 type;
++ __u8 length;
++}__attribute__ ((packed));
++
++struct hci_dbg_rd_mem_cmd_evt {
++ __u8 status;
++ __u8 length;
++ __u8 data[HCI_VSC_MEM_RD_SIZE];
++}__attribute__ ((packed));
++
++struct long_buffer_tag {
++ __u8 length;
++ __u8 data[HCI_VSC_MEM_WR_SIZE];
++};
++
++struct hci_dbg_wr_mem_cmd {
++ __le32 start_addr;
++ __u8 type;
++ __u8 length;
++ __u8 data[HCI_VSC_MEM_WR_SIZE];
++};
++
++struct aicbt_patch_table {
++ char *name;
++ uint32_t type;
++ uint32_t *data;
++ uint32_t len;
++ struct aicbt_patch_table *next;
++};
++
++struct aicbt_patch_table_cmd {
++ uint8_t patch_num;
++ uint32_t patch_table_addr[31];
++ uint32_t patch_table_data[31];
++}__attribute__ ((packed));
++
++
++enum aic_endpoit {
++ CTRL_EP = 0,
++ INTR_EP = 3,
++ BULK_EP = 1,
++ ISOC_EP = 4
++};
++
++/* #define HCI_VERSION_CODE KERNEL_VERSION(3, 14, 41) */
++#define HCI_VERSION_CODE LINUX_VERSION_CODE
++
++int aic_load_firmware(u8 ** fw_buf, const char *name, struct device *device);
++int aicbt_patch_table_free(struct aicbt_patch_table **head);
++int download_patch(firmware_info *fw_info, int cached);
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 38)
++#define NUM_REASSEMBLY 3
++#else
++#define NUM_REASSEMBLY 4
++#endif
++
+--- /dev/null
++++ b/drivers/bluetooth/aic_btusb/aic_btusb_external_featrue.c
+@@ -0,0 +1,126 @@
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/slab.h>
++#include <linux/types.h>
++#include <linux/sched.h>
++#include <linux/errno.h>
++#include <linux/skbuff.h>
++#include <linux/usb.h>
++#include <linux/poll.h>
++#include <linux/cdev.h>
++#include <linux/device.h>
++
++
++
++#define IOCTL_CHAR_DEVICE_NAME "aic_btusb_ex_dev"
++
++#define SET_APCF_PARAMETER _IOR('E', 181, int)
++
++static dev_t ioctl_devid; /* bt char device number */
++static struct cdev ioctl_char_dev; /* bt character device structure */
++static struct class *ioctl_char_class; /* device class for usb char driver */
++
++extern struct file_operations ioctl_chrdev_ops;
++
++extern void btchr_external_write(char* data, int len);
++
++static long ioctl_ioctl(struct file *file_p,unsigned int cmd, unsigned long arg)
++{
++ char data[1024];
++ int ret = 0;
++
++ printk("%s enter\r\n", __func__);
++ memset(data, 0, 1024);
++ switch(cmd)
++ {
++ case SET_APCF_PARAMETER:
++ printk("set apcf parameter\r\n");
++ ret = copy_from_user(data, (int __user *)arg, 1024);
++ btchr_external_write(&data[1], (int)data[0]);
++ break;
++
++ default:
++ printk("unknow cmdr\r\n");
++ break;
++ }
++ return 0;
++}
++
++
++#ifdef CONFIG_COMPAT
++static long compat_ioctlchr_ioctl (struct file *filp, unsigned int cmd, unsigned long arg)
++{
++ return ioctl_ioctl(filp, cmd, (unsigned long) compat_ptr(arg));
++}
++#endif
++
++
++struct file_operations ioctl_chrdev_ops = {
++ unlocked_ioctl : ioctl_ioctl,
++#ifdef CONFIG_COMPAT
++ compat_ioctl : compat_ioctlchr_ioctl,
++#endif
++
++};
++
++static int __init init_extenal_ioctl(void){
++ int res = 0;
++ struct device *dev;
++
++ printk("%s enter\r\n", __func__);
++
++ ioctl_char_class = class_create(THIS_MODULE, IOCTL_CHAR_DEVICE_NAME);
++ if (IS_ERR(ioctl_char_class)) {
++ printk("Failed to create ioctl char class");
++ }
++
++ res = alloc_chrdev_region(&ioctl_devid, 0, 1, IOCTL_CHAR_DEVICE_NAME);
++ if (res < 0) {
++ printk("Failed to allocate ioctl char device");
++ goto err_alloc;
++ }
++
++ dev = device_create(ioctl_char_class, NULL, ioctl_devid, NULL, IOCTL_CHAR_DEVICE_NAME);
++ if (IS_ERR(dev)) {
++ printk("Failed to create ioctl char device");
++ res = PTR_ERR(dev);
++ goto err_create;
++ }
++
++ cdev_init(&ioctl_char_dev, &ioctl_chrdev_ops);
++ res = cdev_add(&ioctl_char_dev, ioctl_devid, 1);
++ if (res < 0) {
++ printk("Failed to add ioctl char device");
++ goto err_add;
++ }
++
++ return res;
++
++err_add:
++ device_destroy(ioctl_char_class, ioctl_devid);
++err_create:
++ unregister_chrdev_region(ioctl_devid, 1);
++err_alloc:
++ class_destroy(ioctl_char_class);
++
++ return res;
++
++}
++static void __exit deinit_extenal_ioctl(void){
++ printk("%s enter\r\n", __func__);
++ device_destroy(ioctl_char_class, ioctl_devid);
++ cdev_del(&ioctl_char_dev);
++ unregister_chrdev_region(ioctl_devid, 1);
++ class_destroy(ioctl_char_class);
++
++}
++
++module_init(init_extenal_ioctl);
++module_exit(deinit_extenal_ioctl);
++
++
++MODULE_AUTHOR("AicSemi Corporation");
++MODULE_DESCRIPTION("AicSemi Bluetooth USB driver version");
++MODULE_LICENSE("GPL");
++
+--- /dev/null
++++ b/drivers/bluetooth/aic_btusb/aic_btusb_external_featrue.h
+@@ -0,0 +1,3 @@
++
++void btchr_external_write(char* data, int len);
++
diff --git a/target/linux/starfive/patches-6.6/0114-riscv-dts-starfive-visionfive-2-Sync-the-sound-card-.patch b/target/linux/starfive/patches-6.6/0114-riscv-dts-starfive-visionfive-2-Sync-the-sound-card-.patch
new file mode 100644
index 0000000000..c599a44cf7
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0114-riscv-dts-starfive-visionfive-2-Sync-the-sound-card-.patch
@@ -0,0 +1,67 @@
+From fdb2822982887c7048f34601688ae2406ccbcfcc Mon Sep 17 00:00:00 2001
+From: Hal Feng <hal.feng@starfivetech.com>
+Date: Mon, 15 Apr 2024 11:29:17 +0800
+Subject: [PATCH 114/116] riscv: dts: starfive: visionfive 2: Sync the sound
+ card names with v5.15 and v6.1
+
+Sync the sound card names. So we can build Debian images with the
+same process.
+
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ .../dts/starfive/jh7110-starfive-visionfive-2-tdm.dts | 2 +-
+ .../dts/starfive/jh7110-starfive-visionfive-2-wm8960.dts | 2 +-
+ .../boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi | 8 ++++----
+ 3 files changed, 6 insertions(+), 6 deletions(-)
+
+--- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-tdm.dts
++++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-tdm.dts
+@@ -8,7 +8,7 @@
+ #include "jh7110-starfive-visionfive-2-v1.3b.dts"
+
+ / {
+- sound-tdm {
++ sound5: snd-card5 {
+ compatible = "simple-audio-card";
+ #address-cells = <1>;
+ #size-cells = <0>;
+--- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-wm8960.dts
++++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-wm8960.dts
+@@ -9,7 +9,7 @@
+
+ / {
+ /* i2s + wm8960 */
+- sound-wm8960 {
++ sound6: snd-card6 {
+ compatible = "simple-audio-card";
+ #address-cells = <1>;
+ #size-cells = <0>;
+--- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
+@@ -91,9 +91,9 @@
+ #sound-dai-cells = <0>;
+ };
+
+- sound-pwmdac {
++ sound3: snd-card3 {
+ compatible = "simple-audio-card";
+- simple-audio-card,name = "StarFive-PWMDAC-Sound-Card";
++ simple-audio-card,name = "Starfive-PWMDAC-Sound-Card";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+@@ -113,12 +113,12 @@
+ };
+ };
+
+- sound-hdmi {
++ sound1: snd-card1 {
+ compatible = "simple-audio-card";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+- simple-audio-card,name = "StarFive-HDMI-Sound-Card";
++ simple-audio-card,name = "Starfive-HDMI-Sound-Card";
+ simple-audio-card,dai-link@0 {
+ reg = <0>;
+ format = "i2s";
diff --git a/target/linux/starfive/patches-6.6/0115-clk-starfive-jh7110-Change-uart3-uart5-clk-register-.patch b/target/linux/starfive/patches-6.6/0115-clk-starfive-jh7110-Change-uart3-uart5-clk-register-.patch
new file mode 100644
index 0000000000..6b34f0ec56
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0115-clk-starfive-jh7110-Change-uart3-uart5-clk-register-.patch
@@ -0,0 +1,53 @@
+From dac6f3021895e7678552789edff22f1dc909e274 Mon Sep 17 00:00:00 2001
+From: Hal Feng <hal.feng@starfivetech.com>
+Date: Mon, 15 Apr 2024 20:59:35 +0800
+Subject: [PATCH 115/116] clk: starfive: jh7110: Change uart3-uart5 clk
+ register info
+
+The core_clk division register of uart3-uart5 include fractional and
+integral parts, but now only use the integral part, so include shift
+operation. The integral part include 8 bit, so the max value can be
+configed is 255.
+
+Signed-off-by: Yanhong Wang <yanhong.wang@starfivetech.com>
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ drivers/clk/starfive/clk-starfive-jh71x0.c | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+--- a/drivers/clk/starfive/clk-starfive-jh71x0.c
++++ b/drivers/clk/starfive/clk-starfive-jh71x0.c
+@@ -10,6 +10,8 @@
+ #include <linux/device.h>
+ #include <linux/io.h>
+
++#include <dt-bindings/clock/starfive,jh7110-crg.h>
++
+ #include "clk-starfive-jh71x0.h"
+
+ static struct jh71x0_clk *jh71x0_clk_from(struct clk_hw *hw)
+@@ -70,6 +72,11 @@ static unsigned long jh71x0_clk_recalc_r
+ struct jh71x0_clk *clk = jh71x0_clk_from(hw);
+ u32 div = jh71x0_clk_reg_get(clk) & JH71X0_CLK_DIV_MASK;
+
++ if (clk->idx == JH7110_SYSCLK_UART3_CORE ||
++ clk->idx == JH7110_SYSCLK_UART4_CORE ||
++ clk->idx == JH7110_SYSCLK_UART5_CORE)
++ div >>= 8;
++
+ return div ? parent_rate / div : 0;
+ }
+
+@@ -110,6 +117,12 @@ static int jh71x0_clk_set_rate(struct cl
+ unsigned long div = clamp(DIV_ROUND_CLOSEST(parent_rate, rate),
+ 1UL, (unsigned long)clk->max_div);
+
++ /* UART3-5: [15:8]: integer part of the divisor. [7:0] fraction part of the divisor */
++ if (clk->idx == JH7110_SYSCLK_UART3_CORE ||
++ clk->idx == JH7110_SYSCLK_UART4_CORE ||
++ clk->idx == JH7110_SYSCLK_UART5_CORE)
++ div <<= 8;
++
+ jh71x0_clk_reg_rmw(clk, JH71X0_CLK_DIV_MASK, div);
+ return 0;
+ }
diff --git a/target/linux/starfive/patches-6.6/0116-riscv-dts-starfive-visionfive-2-Quote-corresponding-.patch b/target/linux/starfive/patches-6.6/0116-riscv-dts-starfive-visionfive-2-Quote-corresponding-.patch
new file mode 100644
index 0000000000..659c442c82
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/0116-riscv-dts-starfive-visionfive-2-Quote-corresponding-.patch
@@ -0,0 +1,32 @@
+From 1ea169bb83d3b556eb9054f1a3e8ce0411370293 Mon Sep 17 00:00:00 2001
+From: Hal Feng <hal.feng@starfivetech.com>
+Date: Wed, 24 Apr 2024 14:23:07 +0800
+Subject: [PATCH 116/116] riscv: dts: starfive: visionfive 2: Quote
+ corresponding regulators in hdmi and vin
+
+So PMIC can start to work before HDMI and VIN.
+
+Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
+---
+ arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
+@@ -961,6 +961,8 @@
+ pinctrl-names = "default";
+ pinctrl-0 = <&hdmi_pins>;
+ hpd-gpio = <&sysgpio 15 GPIO_ACTIVE_HIGH>;
++ hdmi_0p9-supply = <&hdmi_0p9>;
++ hdmi_1p8-supply = <&hdmi_1p8>;
+
+ hdmi_in: port {
+ #address-cells = <1>;
+@@ -1084,6 +1086,7 @@
+ &vin_sysctl {
+ /* when use dvp open this pinctrl*/
+ status = "okay";
++ mipi_0p9-supply = <&mipi_0p9>;
+
+ ports {
+ #address-cells = <1>;
diff --git a/target/linux/starfive/patches-6.6/1000-serial-8250_dw-Add-starfive-jh7100-hsuart-compatible.patch b/target/linux/starfive/patches-6.6/1000-serial-8250_dw-Add-starfive-jh7100-hsuart-compatible.patch
new file mode 100644
index 0000000000..463c7eb7b6
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/1000-serial-8250_dw-Add-starfive-jh7100-hsuart-compatible.patch
@@ -0,0 +1,25 @@
+From b7b4fad8784d7ab4fcd929a56c3e5366046fe7fc Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <kernel@esmil.dk>
+Date: Thu, 14 Oct 2021 20:56:54 +0200
+Subject: [PATCH 1000/1024] serial: 8250_dw: Add starfive,jh7100-hsuart
+ compatible
+
+This adds a compatible for the high speed UARTs on the StarFive JH7100
+RISC-V SoC. Just like the regular uarts we also need to keep the input
+clocks at their default rate and rely only on the divisor in the UART.
+
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+---
+ drivers/tty/serial/8250/8250_dw.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/tty/serial/8250/8250_dw.c
++++ b/drivers/tty/serial/8250/8250_dw.c
+@@ -802,6 +802,7 @@ static const struct of_device_id dw8250_
+ { .compatible = "cavium,octeon-3860-uart", .data = &dw8250_octeon_3860_data },
+ { .compatible = "marvell,armada-38x-uart", .data = &dw8250_armada_38x_data },
+ { .compatible = "renesas,rzn1-uart", .data = &dw8250_renesas_rzn1_data },
++ { .compatible = "starfive,jh7100-hsuart", .data = &dw8250_starfive_jh7100_data },
+ { .compatible = "starfive,jh7100-uart", .data = &dw8250_starfive_jh7100_data },
+ { /* Sentinel */ }
+ };
diff --git a/target/linux/starfive/patches-6.6/1001-RISC-V-Add-StarFive-JH7100-audio-clock-node.patch b/target/linux/starfive/patches-6.6/1001-RISC-V-Add-StarFive-JH7100-audio-clock-node.patch
new file mode 100644
index 0000000000..4cfa2a1678
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/1001-RISC-V-Add-StarFive-JH7100-audio-clock-node.patch
@@ -0,0 +1,32 @@
+From 3051ab0102aaf969dd85f07b6ab731dadf97ef6c Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <kernel@esmil.dk>
+Date: Sat, 20 Nov 2021 17:13:22 +0100
+Subject: [PATCH 1001/1024] RISC-V: Add StarFive JH7100 audio clock node
+
+Add device tree node for the audio clocks on the StarFive JH7100 RISC-V
+SoC.
+
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+---
+ arch/riscv/boot/dts/starfive/jh7100.dtsi | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+--- a/arch/riscv/boot/dts/starfive/jh7100.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7100.dtsi
+@@ -158,6 +158,16 @@
+ riscv,ndev = <133>;
+ };
+
++ audclk: clock-controller@10480000 {
++ compatible = "starfive,jh7100-audclk";
++ reg = <0x0 0x10480000 0x0 0x10000>;
++ clocks = <&clkgen JH7100_CLK_AUDIO_SRC>,
++ <&clkgen JH7100_CLK_AUDIO_12288>,
++ <&clkgen JH7100_CLK_DOM7AHB_BUS>;
++ clock-names = "audio_src", "audio_12288", "dom7ahb_bus";
++ #clock-cells = <1>;
++ };
++
+ clkgen: clock-controller@11800000 {
+ compatible = "starfive,jh7100-clkgen";
+ reg = <0x0 0x11800000 0x0 0x10000>;
diff --git a/target/linux/starfive/patches-6.6/1002-drivers-tty-serial-8250-update-driver-for-JH7100.patch b/target/linux/starfive/patches-6.6/1002-drivers-tty-serial-8250-update-driver-for-JH7100.patch
new file mode 100644
index 0000000000..73d25f5163
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/1002-drivers-tty-serial-8250-update-driver-for-JH7100.patch
@@ -0,0 +1,28 @@
+From 8ef30667e97363ca921416a60e50eb28bf88cc4f Mon Sep 17 00:00:00 2001
+From: Samin Guo <samin.guo@starfivetech.com>
+Date: Fri, 8 Jan 2021 03:11:04 +0800
+Subject: [PATCH 1002/1024] drivers/tty/serial/8250: update driver for JH7100
+
+---
+ drivers/tty/serial/8250/8250_port.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/drivers/tty/serial/8250/8250_port.c
++++ b/drivers/tty/serial/8250/8250_port.c
+@@ -72,8 +72,16 @@ static const struct serial8250_config ua
+ },
+ [PORT_16550] = {
+ .name = "16550",
++#ifdef CONFIG_SOC_STARFIVE
++ .fifo_size = 16,
++ .tx_loadsz = 16,
++ .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_00,
++ .rxtrig_bytes = {1, 4, 8, 14},
++ .flags = UART_CAP_FIFO,
++#else
+ .fifo_size = 1,
+ .tx_loadsz = 1,
++#endif
+ },
+ [PORT_16550A] = {
+ .name = "16550A",
diff --git a/target/linux/starfive/patches-6.6/1003-dmaengine-dw-axi-dmac-Handle-xfer-start-while-non-id.patch b/target/linux/starfive/patches-6.6/1003-dmaengine-dw-axi-dmac-Handle-xfer-start-while-non-id.patch
new file mode 100644
index 0000000000..d0c692e1a5
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/1003-dmaengine-dw-axi-dmac-Handle-xfer-start-while-non-id.patch
@@ -0,0 +1,55 @@
+From 2d5b71006c6a93e26eb86b7efd37440c020bab46 Mon Sep 17 00:00:00 2001
+From: Samin Guo <samin.guo@starfivetech.com>
+Date: Wed, 17 Nov 2021 14:50:45 +0800
+Subject: [PATCH 1003/1024] dmaengine: dw-axi-dmac: Handle xfer start while
+ non-idle
+
+Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
+Signed-off-by: Curry Zhang <curry.zhang@starfivetech.com>
+---
+ drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 12 +++++++++++-
+ drivers/dma/dw-axi-dmac/dw-axi-dmac.h | 1 +
+ 2 files changed, 12 insertions(+), 1 deletion(-)
+
+--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
++++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+@@ -382,11 +382,13 @@ static void axi_chan_block_xfer_start(st
+ u32 irq_mask;
+ u8 lms = 0; /* Select AXI0 master for LLI fetching */
+
++ chan->is_err = false;
+ if (unlikely(axi_chan_is_hw_enable(chan))) {
+ dev_err(chan2dev(chan), "%s is non-idle!\n",
+ axi_chan_name(chan));
+
+- return;
++ axi_chan_disable(chan);
++ chan->is_err = true;
+ }
+
+ axi_dma_enable(chan->chip);
+@@ -1028,6 +1030,14 @@ static noinline void axi_chan_handle_err
+ axi_chan_name(chan));
+ goto out;
+ }
++ if (chan->is_err) {
++ struct axi_dma_desc *desc = vd_to_axi_desc(vd);
++
++ axi_chan_block_xfer_start(chan, desc);
++ chan->is_err = false;
++ goto out;
++ }
++
+ /* Remove the completed descriptor from issued list */
+ list_del(&vd->node);
+
+--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
++++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
+@@ -50,6 +50,7 @@ struct axi_dma_chan {
+ struct dma_slave_config config;
+ enum dma_transfer_direction direction;
+ bool cyclic;
++ bool is_err;
+ /* these other elements are all protected by vc.lock */
+ bool is_paused;
+ };
diff --git a/target/linux/starfive/patches-6.6/1004-dmaengine-dw-axi-dmac-Add-StarFive-JH7100-support.patch b/target/linux/starfive/patches-6.6/1004-dmaengine-dw-axi-dmac-Add-StarFive-JH7100-support.patch
new file mode 100644
index 0000000000..74a05cf80a
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/1004-dmaengine-dw-axi-dmac-Add-StarFive-JH7100-support.patch
@@ -0,0 +1,64 @@
+From 933f8c33d466de20e9894ef8de5b6afe478a420d Mon Sep 17 00:00:00 2001
+From: Samin Guo <samin.guo@starfivetech.com>
+Date: Wed, 17 Nov 2021 14:50:45 +0800
+Subject: [PATCH 1004/1024] dmaengine: dw-axi-dmac: Add StarFive JH7100 support
+
+Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+---
+ drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 12 ++++++++++++
+ drivers/dma/dw-axi-dmac/dw-axi-dmac.h | 4 ++++
+ 2 files changed, 16 insertions(+)
+
+--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
++++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+@@ -677,8 +677,13 @@ static int dw_axi_dma_set_hw_desc(struct
+
+ hw_desc->lli->block_ts_lo = cpu_to_le32(block_ts - 1);
+
++#ifdef CONFIG_SOC_STARFIVE
++ ctllo |= DWAXIDMAC_BURST_TRANS_LEN_16 << CH_CTL_L_DST_MSIZE_POS |
++ DWAXIDMAC_BURST_TRANS_LEN_16 << CH_CTL_L_SRC_MSIZE_POS;
++#else
+ ctllo |= DWAXIDMAC_BURST_TRANS_LEN_4 << CH_CTL_L_DST_MSIZE_POS |
+ DWAXIDMAC_BURST_TRANS_LEN_4 << CH_CTL_L_SRC_MSIZE_POS;
++#endif
+ hw_desc->lli->ctl_lo = cpu_to_le32(ctllo);
+
+ set_desc_src_master(hw_desc);
+@@ -1502,7 +1507,11 @@ static int dw_probe(struct platform_devi
+ * Therefore, set constraint to 1024 * 4.
+ */
+ dw->dma.dev->dma_parms = &dw->dma_parms;
++#ifdef CONFIG_SOC_STARFIVE
++ dma_set_max_seg_size(&pdev->dev, DMAC_MAX_BLK_SIZE);
++#else
+ dma_set_max_seg_size(&pdev->dev, MAX_BLOCK_SIZE);
++#endif
+ platform_set_drvdata(pdev, chip);
+
+ pm_runtime_enable(chip->dev);
+@@ -1587,6 +1596,9 @@ static const struct of_device_id dw_dma_
+ .compatible = "intel,kmb-axi-dma",
+ .data = (void *)AXI_DMA_FLAG_HAS_APB_REGS,
+ }, {
++ .compatible = "starfive,jh7100-axi-dma",
++ .data = (void *)(AXI_DMA_FLAG_HAS_RESETS | AXI_DMA_FLAG_USE_CFG2),
++ }, {
+ .compatible = "starfive,jh7110-axi-dma",
+ .data = (void *)(AXI_DMA_FLAG_HAS_RESETS | AXI_DMA_FLAG_USE_CFG2),
+ },
+--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
++++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
+@@ -284,7 +284,11 @@ enum {
+ #define CH_CTL_L_SRC_MAST BIT(0)
+
+ /* CH_CFG_H */
++#ifdef CONFIG_SOC_STARFIVE
++#define CH_CFG_H_PRIORITY_POS 15
++#else
+ #define CH_CFG_H_PRIORITY_POS 17
++#endif
+ #define CH_CFG_H_DST_PER_POS 12
+ #define CH_CFG_H_SRC_PER_POS 7
+ #define CH_CFG_H_HS_SEL_DST_POS 4
diff --git a/target/linux/starfive/patches-6.6/1005-pinctrl-starfive-Reset-pinmux-settings.patch b/target/linux/starfive/patches-6.6/1005-pinctrl-starfive-Reset-pinmux-settings.patch
new file mode 100644
index 0000000000..63a7a0cee9
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/1005-pinctrl-starfive-Reset-pinmux-settings.patch
@@ -0,0 +1,127 @@
+From c5019bf73d1e178beb6055cca254e7d3c916db7c Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <kernel@esmil.dk>
+Date: Sat, 17 Jul 2021 21:50:38 +0200
+Subject: [PATCH 1005/1024] pinctrl: starfive: Reset pinmux settings
+
+Current u-boot doesn't seem to take into account that some GPIOs are
+configured as inputs/outputs of certain peripherals on power-up. This
+means it ends up configuring some GPIOs as inputs to more than one
+peripheral which the documentation explicitly says is illegal. Similarly
+it also ends up configuring more than one GPIO as output of the same
+peripheral. While not explicitly mentioned by the documentation this
+also seems like a bad idea.
+
+The easiest way to remedy this mess is to just disconnect all GPIOs from
+peripherals and have our pinmux configuration set everything up
+properly. This, however, means that we'd disconnect the serial console
+from its pins for a while, so add a device tree property to keep
+certain GPIOs from being reset.
+
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+---
+ .../pinctrl/starfive,jh7100-pinctrl.yaml | 4 ++
+ .../starfive/pinctrl-starfive-jh7100.c | 66 +++++++++++++++++++
+ 2 files changed, 70 insertions(+)
+
+--- a/Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml
++++ b/Documentation/devicetree/bindings/pinctrl/starfive,jh7100-pinctrl.yaml
+@@ -88,6 +88,10 @@ properties:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ enum: [0, 1, 2, 3, 4, 5, 6]
+
++ starfive,keep-gpiomux:
++ description: Keep pinmux for these GPIOs from being reset at boot.
++ $ref: /schemas/types.yaml#/definitions/uint32-array
++
+ required:
+ - compatible
+ - reg
+--- a/drivers/pinctrl/starfive/pinctrl-starfive-jh7100.c
++++ b/drivers/pinctrl/starfive/pinctrl-starfive-jh7100.c
+@@ -203,6 +203,10 @@ static u16 starfive_drive_strength_from_
+ return (clamp(i, 14U, 63U) - 14) / 7;
+ }
+
++static bool keepmux;
++module_param(keepmux, bool, 0644);
++MODULE_PARM_DESC(keepmux, "Keep pinmux settings from previous boot stage");
++
+ struct starfive_pinctrl {
+ struct gpio_chip gc;
+ struct pinctrl_gpio_range gpios;
+@@ -1225,6 +1229,65 @@ static void starfive_disable_clock(void
+ clk_disable_unprepare(data);
+ }
+
++#define GPI_END (GPI_USB_OVER_CURRENT + 1)
++static void starfive_pinmux_reset(struct starfive_pinctrl *sfp)
++{
++ static const DECLARE_BITMAP(defaults, GPI_END) = {
++ BIT_MASK(GPI_I2C0_PAD_SCK_IN) |
++ BIT_MASK(GPI_I2C0_PAD_SDA_IN) |
++ BIT_MASK(GPI_I2C1_PAD_SCK_IN) |
++ BIT_MASK(GPI_I2C1_PAD_SDA_IN) |
++ BIT_MASK(GPI_I2C2_PAD_SCK_IN) |
++ BIT_MASK(GPI_I2C2_PAD_SDA_IN) |
++ BIT_MASK(GPI_I2C3_PAD_SCK_IN) |
++ BIT_MASK(GPI_I2C3_PAD_SDA_IN) |
++ BIT_MASK(GPI_SDIO0_PAD_CARD_DETECT_N) |
++
++ BIT_MASK(GPI_SDIO1_PAD_CARD_DETECT_N) |
++ BIT_MASK(GPI_SPI0_PAD_SS_IN_N) |
++ BIT_MASK(GPI_SPI1_PAD_SS_IN_N) |
++ BIT_MASK(GPI_SPI2_PAD_SS_IN_N) |
++ BIT_MASK(GPI_SPI2AHB_PAD_SS_N) |
++ BIT_MASK(GPI_SPI3_PAD_SS_IN_N),
++
++ BIT_MASK(GPI_UART0_PAD_SIN) |
++ BIT_MASK(GPI_UART1_PAD_SIN) |
++ BIT_MASK(GPI_UART2_PAD_SIN) |
++ BIT_MASK(GPI_UART3_PAD_SIN) |
++ BIT_MASK(GPI_USB_OVER_CURRENT)
++ };
++ DECLARE_BITMAP(keep, NR_GPIOS) = {};
++ struct device_node *np = sfp->gc.parent->of_node;
++ int len = of_property_count_u32_elems(np, "starfive,keep-gpiomux");
++ int i;
++
++ for (i = 0; i < len; i++) {
++ u32 gpio;
++
++ of_property_read_u32_index(np, "starfive,keep-gpiomux", i, &gpio);
++ if (gpio < NR_GPIOS)
++ set_bit(gpio, keep);
++ }
++
++ for (i = 0; i < NR_GPIOS; i++) {
++ if (test_bit(i, keep))
++ continue;
++
++ writel_relaxed(GPO_DISABLE, sfp->base + GPON_DOEN_CFG + 8 * i);
++ writel_relaxed(GPO_LOW, sfp->base + GPON_DOUT_CFG + 8 * i);
++ }
++
++ for (i = 0; i < GPI_END; i++) {
++ void __iomem *reg = sfp->base + GPI_CFG_OFFSET + 4 * i;
++ u32 din = readl_relaxed(reg);
++
++ if (din >= 2 && din < (NR_GPIOS + 2) && test_bit(din - 2, keep))
++ continue;
++
++ writel_relaxed(test_bit(i, defaults), reg);
++ }
++}
++
+ static int starfive_probe(struct platform_device *pdev)
+ {
+ struct device *dev = &pdev->dev;
+@@ -1286,6 +1349,9 @@ static int starfive_probe(struct platfor
+ writel(value, sfp->padctl + IO_PADSHARE_SEL);
+ }
+
++ if (!keepmux)
++ starfive_pinmux_reset(sfp);
++
+ value = readl(sfp->padctl + IO_PADSHARE_SEL);
+ switch (value) {
+ case 0:
diff --git a/target/linux/starfive/patches-6.6/1006-clk-starfive-Add-flags-argument-to-JH71X0__MUX-macro.patch b/target/linux/starfive/patches-6.6/1006-clk-starfive-Add-flags-argument-to-JH71X0__MUX-macro.patch
new file mode 100644
index 0000000000..a6a1bb827e
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/1006-clk-starfive-Add-flags-argument-to-JH71X0__MUX-macro.patch
@@ -0,0 +1,302 @@
+From a4a2a8886c97e14643fe3e0ab8cf67a75c1bf14d Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <emil.renner.berthing@canonical.com>
+Date: Sat, 25 Mar 2023 22:57:06 +0100
+Subject: [PATCH 1006/1024] clk: starfive: Add flags argument to JH71X0__MUX
+ macro
+
+This flag is needed to add the CLK_SET_RATE_PARENT flag on the gmac_tx
+clock on the JH7100, which in turn is needed by the dwmac-starfive
+driver to set the clock properly for 1000, 100 and 10 Mbps links.
+
+This change was mostly made using coccinelle:
+
+@ match @
+expression idx, name, nparents;
+@@
+ JH71X0__MUX(
+-idx, name, nparents,
++idx, name, 0, nparents,
+ ...)
+
+Signed-off-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
+---
+ .../clk/starfive/clk-starfive-jh7100-audio.c | 2 +-
+ drivers/clk/starfive/clk-starfive-jh7100.c | 32 +++++++++----------
+ .../clk/starfive/clk-starfive-jh7110-aon.c | 6 ++--
+ .../clk/starfive/clk-starfive-jh7110-isp.c | 2 +-
+ .../clk/starfive/clk-starfive-jh7110-sys.c | 26 +++++++--------
+ drivers/clk/starfive/clk-starfive-jh71x0.h | 4 +--
+ 6 files changed, 36 insertions(+), 36 deletions(-)
+
+--- a/drivers/clk/starfive/clk-starfive-jh7100-audio.c
++++ b/drivers/clk/starfive/clk-starfive-jh7100-audio.c
+@@ -79,7 +79,7 @@ static const struct jh71x0_clk_data jh71
+ JH71X0_GDIV(JH7100_AUDCLK_USB_LPM, "usb_lpm", CLK_IGNORE_UNUSED, 4, JH7100_AUDCLK_USB_APB),
+ JH71X0_GDIV(JH7100_AUDCLK_USB_STB, "usb_stb", CLK_IGNORE_UNUSED, 3, JH7100_AUDCLK_USB_APB),
+ JH71X0__DIV(JH7100_AUDCLK_APB_EN, "apb_en", 8, JH7100_AUDCLK_DOM7AHB_BUS),
+- JH71X0__MUX(JH7100_AUDCLK_VAD_MEM, "vad_mem", 2,
++ JH71X0__MUX(JH7100_AUDCLK_VAD_MEM, "vad_mem", 0, 2,
+ JH7100_AUDCLK_VAD_INTMEM,
+ JH7100_AUDCLK_AUDIO_12288),
+ };
+--- a/drivers/clk/starfive/clk-starfive-jh7100.c
++++ b/drivers/clk/starfive/clk-starfive-jh7100.c
+@@ -24,48 +24,48 @@
+ #define JH7100_CLK_GMAC_GR_MII_RX (JH7100_CLK_END + 3)
+
+ static const struct jh71x0_clk_data jh7100_clk_data[] __initconst = {
+- JH71X0__MUX(JH7100_CLK_CPUNDBUS_ROOT, "cpundbus_root", 4,
++ JH71X0__MUX(JH7100_CLK_CPUNDBUS_ROOT, "cpundbus_root", 0, 4,
+ JH7100_CLK_OSC_SYS,
+ JH7100_CLK_PLL0_OUT,
+ JH7100_CLK_PLL1_OUT,
+ JH7100_CLK_PLL2_OUT),
+- JH71X0__MUX(JH7100_CLK_DLA_ROOT, "dla_root", 3,
++ JH71X0__MUX(JH7100_CLK_DLA_ROOT, "dla_root", 0, 3,
+ JH7100_CLK_OSC_SYS,
+ JH7100_CLK_PLL1_OUT,
+ JH7100_CLK_PLL2_OUT),
+- JH71X0__MUX(JH7100_CLK_DSP_ROOT, "dsp_root", 4,
++ JH71X0__MUX(JH7100_CLK_DSP_ROOT, "dsp_root", 0, 4,
+ JH7100_CLK_OSC_SYS,
+ JH7100_CLK_PLL0_OUT,
+ JH7100_CLK_PLL1_OUT,
+ JH7100_CLK_PLL2_OUT),
+- JH71X0__MUX(JH7100_CLK_GMACUSB_ROOT, "gmacusb_root", 3,
++ JH71X0__MUX(JH7100_CLK_GMACUSB_ROOT, "gmacusb_root", 0, 3,
+ JH7100_CLK_OSC_SYS,
+ JH7100_CLK_PLL0_OUT,
+ JH7100_CLK_PLL2_OUT),
+- JH71X0__MUX(JH7100_CLK_PERH0_ROOT, "perh0_root", 2,
++ JH71X0__MUX(JH7100_CLK_PERH0_ROOT, "perh0_root", 0, 2,
+ JH7100_CLK_OSC_SYS,
+ JH7100_CLK_PLL0_OUT),
+- JH71X0__MUX(JH7100_CLK_PERH1_ROOT, "perh1_root", 2,
++ JH71X0__MUX(JH7100_CLK_PERH1_ROOT, "perh1_root", 0, 2,
+ JH7100_CLK_OSC_SYS,
+ JH7100_CLK_PLL2_OUT),
+- JH71X0__MUX(JH7100_CLK_VIN_ROOT, "vin_root", 3,
++ JH71X0__MUX(JH7100_CLK_VIN_ROOT, "vin_root", 0, 3,
+ JH7100_CLK_OSC_SYS,
+ JH7100_CLK_PLL1_OUT,
+ JH7100_CLK_PLL2_OUT),
+- JH71X0__MUX(JH7100_CLK_VOUT_ROOT, "vout_root", 3,
++ JH71X0__MUX(JH7100_CLK_VOUT_ROOT, "vout_root", 0, 3,
+ JH7100_CLK_OSC_AUD,
+ JH7100_CLK_PLL0_OUT,
+ JH7100_CLK_PLL2_OUT),
+ JH71X0_GDIV(JH7100_CLK_AUDIO_ROOT, "audio_root", 0, 8, JH7100_CLK_PLL0_OUT),
+- JH71X0__MUX(JH7100_CLK_CDECHIFI4_ROOT, "cdechifi4_root", 3,
++ JH71X0__MUX(JH7100_CLK_CDECHIFI4_ROOT, "cdechifi4_root", 0, 3,
+ JH7100_CLK_OSC_SYS,
+ JH7100_CLK_PLL1_OUT,
+ JH7100_CLK_PLL2_OUT),
+- JH71X0__MUX(JH7100_CLK_CDEC_ROOT, "cdec_root", 3,
++ JH71X0__MUX(JH7100_CLK_CDEC_ROOT, "cdec_root", 0, 3,
+ JH7100_CLK_OSC_SYS,
+ JH7100_CLK_PLL0_OUT,
+ JH7100_CLK_PLL1_OUT),
+- JH71X0__MUX(JH7100_CLK_VOUTBUS_ROOT, "voutbus_root", 3,
++ JH71X0__MUX(JH7100_CLK_VOUTBUS_ROOT, "voutbus_root", 0, 3,
+ JH7100_CLK_OSC_AUD,
+ JH7100_CLK_PLL0_OUT,
+ JH7100_CLK_PLL2_OUT),
+@@ -76,7 +76,7 @@ static const struct jh71x0_clk_data jh71
+ JH71X0_GDIV(JH7100_CLK_PLL0_TESTOUT, "pll0_testout", 0, 31, JH7100_CLK_PERH0_SRC),
+ JH71X0_GDIV(JH7100_CLK_PLL1_TESTOUT, "pll1_testout", 0, 31, JH7100_CLK_DLA_ROOT),
+ JH71X0_GDIV(JH7100_CLK_PLL2_TESTOUT, "pll2_testout", 0, 31, JH7100_CLK_PERH1_SRC),
+- JH71X0__MUX(JH7100_CLK_PLL2_REF, "pll2_refclk", 2,
++ JH71X0__MUX(JH7100_CLK_PLL2_REF, "pll2_refclk", 0, 2,
+ JH7100_CLK_OSC_SYS,
+ JH7100_CLK_OSC_AUD),
+ JH71X0__DIV(JH7100_CLK_CPU_CORE, "cpu_core", 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
+@@ -142,7 +142,7 @@ static const struct jh71x0_clk_data jh71
+ JH71X0__DIV(JH7100_CLK_NOC_COG, "noc_cog", 8, JH7100_CLK_DLA_ROOT),
+ JH71X0_GATE(JH7100_CLK_NNE_AHB, "nne_ahb", 0, JH7100_CLK_AHB_BUS),
+ JH71X0__DIV(JH7100_CLK_NNEBUS_SRC1, "nnebus_src1", 4, JH7100_CLK_DSP_ROOT),
+- JH71X0__MUX(JH7100_CLK_NNE_BUS, "nne_bus", 2,
++ JH71X0__MUX(JH7100_CLK_NNE_BUS, "nne_bus", 0, 2,
+ JH7100_CLK_CPU_AXI,
+ JH7100_CLK_NNEBUS_SRC1),
+ JH71X0_GATE(JH7100_CLK_NNE_AXI, "nne_axi", 0, JH7100_CLK_NNE_BUS),
+@@ -166,7 +166,7 @@ static const struct jh71x0_clk_data jh71
+ JH71X0_GDIV(JH7100_CLK_USBPHY_125M, "usbphy_125m", 0, 8, JH7100_CLK_USBPHY_ROOTDIV),
+ JH71X0_GDIV(JH7100_CLK_USBPHY_PLLDIV25M, "usbphy_plldiv25m", 0, 32,
+ JH7100_CLK_USBPHY_ROOTDIV),
+- JH71X0__MUX(JH7100_CLK_USBPHY_25M, "usbphy_25m", 2,
++ JH71X0__MUX(JH7100_CLK_USBPHY_25M, "usbphy_25m", 0, 2,
+ JH7100_CLK_OSC_SYS,
+ JH7100_CLK_USBPHY_PLLDIV25M),
+ JH71X0_FDIV(JH7100_CLK_AUDIO_DIV, "audio_div", JH7100_CLK_AUDIO_ROOT),
+@@ -200,12 +200,12 @@ static const struct jh71x0_clk_data jh71
+ JH71X0_GDIV(JH7100_CLK_GMAC_GTX, "gmac_gtxclk", 0, 255, JH7100_CLK_GMAC_ROOT_DIV),
+ JH71X0_GDIV(JH7100_CLK_GMAC_RMII_TX, "gmac_rmii_txclk", 0, 8, JH7100_CLK_GMAC_RMII_REF),
+ JH71X0_GDIV(JH7100_CLK_GMAC_RMII_RX, "gmac_rmii_rxclk", 0, 8, JH7100_CLK_GMAC_RMII_REF),
+- JH71X0__MUX(JH7100_CLK_GMAC_TX, "gmac_tx", 3,
++ JH71X0__MUX(JH7100_CLK_GMAC_TX, "gmac_tx", 0, 3,
+ JH7100_CLK_GMAC_GTX,
+ JH7100_CLK_GMAC_TX_INV,
+ JH7100_CLK_GMAC_RMII_TX),
+ JH71X0__INV(JH7100_CLK_GMAC_TX_INV, "gmac_tx_inv", JH7100_CLK_GMAC_TX),
+- JH71X0__MUX(JH7100_CLK_GMAC_RX_PRE, "gmac_rx_pre", 2,
++ JH71X0__MUX(JH7100_CLK_GMAC_RX_PRE, "gmac_rx_pre", 0, 2,
+ JH7100_CLK_GMAC_GR_MII_RX,
+ JH7100_CLK_GMAC_RMII_RX),
+ JH71X0__INV(JH7100_CLK_GMAC_RX_INV, "gmac_rx_inv", JH7100_CLK_GMAC_RX_PRE),
+--- a/drivers/clk/starfive/clk-starfive-jh7110-aon.c
++++ b/drivers/clk/starfive/clk-starfive-jh7110-aon.c
+@@ -26,7 +26,7 @@
+ static const struct jh71x0_clk_data jh7110_aonclk_data[] = {
+ /* source */
+ JH71X0__DIV(JH7110_AONCLK_OSC_DIV4, "osc_div4", 4, JH7110_AONCLK_OSC),
+- JH71X0__MUX(JH7110_AONCLK_APB_FUNC, "apb_func", 2,
++ JH71X0__MUX(JH7110_AONCLK_APB_FUNC, "apb_func", 0, 2,
+ JH7110_AONCLK_OSC_DIV4,
+ JH7110_AONCLK_OSC),
+ /* gmac0 */
+@@ -39,7 +39,7 @@ static const struct jh71x0_clk_data jh71
+ JH7110_AONCLK_GMAC0_GTXCLK,
+ JH7110_AONCLK_GMAC0_RMII_RTX),
+ JH71X0__INV(JH7110_AONCLK_GMAC0_TX_INV, "gmac0_tx_inv", JH7110_AONCLK_GMAC0_TX),
+- JH71X0__MUX(JH7110_AONCLK_GMAC0_RX, "gmac0_rx", 2,
++ JH71X0__MUX(JH7110_AONCLK_GMAC0_RX, "gmac0_rx", 0, 2,
+ JH7110_AONCLK_GMAC0_RGMII_RXIN,
+ JH7110_AONCLK_GMAC0_RMII_RTX),
+ JH71X0__INV(JH7110_AONCLK_GMAC0_RX_INV, "gmac0_rx_inv", JH7110_AONCLK_GMAC0_RX),
+@@ -48,7 +48,7 @@ static const struct jh71x0_clk_data jh71
+ /* rtc */
+ JH71X0_GATE(JH7110_AONCLK_RTC_APB, "rtc_apb", 0, JH7110_AONCLK_APB_BUS),
+ JH71X0__DIV(JH7110_AONCLK_RTC_INTERNAL, "rtc_internal", 1022, JH7110_AONCLK_OSC),
+- JH71X0__MUX(JH7110_AONCLK_RTC_32K, "rtc_32k", 2,
++ JH71X0__MUX(JH7110_AONCLK_RTC_32K, "rtc_32k", 0, 2,
+ JH7110_AONCLK_RTC_OSC,
+ JH7110_AONCLK_RTC_INTERNAL),
+ JH71X0_GATE(JH7110_AONCLK_RTC_CAL, "rtc_cal", 0, JH7110_AONCLK_OSC),
+--- a/drivers/clk/starfive/clk-starfive-jh7110-isp.c
++++ b/drivers/clk/starfive/clk-starfive-jh7110-isp.c
+@@ -53,7 +53,7 @@ static const struct jh71x0_clk_data jh71
+ JH7110_ISPCLK_MIPI_RX0_PXL),
+ JH71X0_GATE(JH7110_ISPCLK_VIN_PIXEL_IF3, "vin_pixel_if3", 0,
+ JH7110_ISPCLK_MIPI_RX0_PXL),
+- JH71X0__MUX(JH7110_ISPCLK_VIN_P_AXI_WR, "vin_p_axi_wr", 2,
++ JH71X0__MUX(JH7110_ISPCLK_VIN_P_AXI_WR, "vin_p_axi_wr", 0, 2,
+ JH7110_ISPCLK_MIPI_RX0_PXL,
+ JH7110_ISPCLK_DVP_INV),
+ /* ispv2_top_wrapper */
+--- a/drivers/clk/starfive/clk-starfive-jh7110-sys.c
++++ b/drivers/clk/starfive/clk-starfive-jh7110-sys.c
+@@ -36,18 +36,18 @@
+
+ static const struct jh71x0_clk_data jh7110_sysclk_data[] __initconst = {
+ /* root */
+- JH71X0__MUX(JH7110_SYSCLK_CPU_ROOT, "cpu_root", 2,
++ JH71X0__MUX(JH7110_SYSCLK_CPU_ROOT, "cpu_root", 0, 2,
+ JH7110_SYSCLK_OSC,
+ JH7110_SYSCLK_PLL0_OUT),
+ JH71X0__DIV(JH7110_SYSCLK_CPU_CORE, "cpu_core", 7, JH7110_SYSCLK_CPU_ROOT),
+ JH71X0__DIV(JH7110_SYSCLK_CPU_BUS, "cpu_bus", 2, JH7110_SYSCLK_CPU_CORE),
+- JH71X0__MUX(JH7110_SYSCLK_GPU_ROOT, "gpu_root", 2,
++ JH71X0__MUX(JH7110_SYSCLK_GPU_ROOT, "gpu_root", 0, 2,
+ JH7110_SYSCLK_PLL2_OUT,
+ JH7110_SYSCLK_PLL1_OUT),
+ JH71X0_MDIV(JH7110_SYSCLK_PERH_ROOT, "perh_root", 2, 2,
+ JH7110_SYSCLK_PLL0_OUT,
+ JH7110_SYSCLK_PLL2_OUT),
+- JH71X0__MUX(JH7110_SYSCLK_BUS_ROOT, "bus_root", 2,
++ JH71X0__MUX(JH7110_SYSCLK_BUS_ROOT, "bus_root", 0, 2,
+ JH7110_SYSCLK_OSC,
+ JH7110_SYSCLK_PLL2_OUT),
+ JH71X0__DIV(JH7110_SYSCLK_NOCSTG_BUS, "nocstg_bus", 3, JH7110_SYSCLK_BUS_ROOT),
+@@ -62,7 +62,7 @@ static const struct jh71x0_clk_data jh71
+ JH71X0__DIV(JH7110_SYSCLK_PLL2_DIV2, "pll2_div2", 2, JH7110_SYSCLK_PLL2_OUT),
+ JH71X0__DIV(JH7110_SYSCLK_AUDIO_ROOT, "audio_root", 8, JH7110_SYSCLK_PLL2_OUT),
+ JH71X0__DIV(JH7110_SYSCLK_MCLK_INNER, "mclk_inner", 64, JH7110_SYSCLK_AUDIO_ROOT),
+- JH71X0__MUX(JH7110_SYSCLK_MCLK, "mclk", 2,
++ JH71X0__MUX(JH7110_SYSCLK_MCLK, "mclk", 0, 2,
+ JH7110_SYSCLK_MCLK_INNER,
+ JH7110_SYSCLK_MCLK_EXT),
+ JH71X0_GATE(JH7110_SYSCLK_MCLK_OUT, "mclk_out", 0, JH7110_SYSCLK_MCLK_INNER),
+@@ -96,7 +96,7 @@ static const struct jh71x0_clk_data jh71
+ JH71X0__DIV(JH7110_SYSCLK_OSC_DIV2, "osc_div2", 2, JH7110_SYSCLK_OSC),
+ JH71X0__DIV(JH7110_SYSCLK_PLL1_DIV4, "pll1_div4", 2, JH7110_SYSCLK_PLL1_DIV2),
+ JH71X0__DIV(JH7110_SYSCLK_PLL1_DIV8, "pll1_div8", 2, JH7110_SYSCLK_PLL1_DIV4),
+- JH71X0__MUX(JH7110_SYSCLK_DDR_BUS, "ddr_bus", 4,
++ JH71X0__MUX(JH7110_SYSCLK_DDR_BUS, "ddr_bus", 0, 4,
+ JH7110_SYSCLK_OSC_DIV2,
+ JH7110_SYSCLK_PLL1_DIV2,
+ JH7110_SYSCLK_PLL1_DIV4,
+@@ -186,7 +186,7 @@ static const struct jh71x0_clk_data jh71
+ JH71X0__DIV(JH7110_SYSCLK_GMAC1_RMII_RTX, "gmac1_rmii_rtx", 30,
+ JH7110_SYSCLK_GMAC1_RMII_REFIN),
+ JH71X0_GDIV(JH7110_SYSCLK_GMAC1_PTP, "gmac1_ptp", 0, 31, JH7110_SYSCLK_GMAC_SRC),
+- JH71X0__MUX(JH7110_SYSCLK_GMAC1_RX, "gmac1_rx", 2,
++ JH71X0__MUX(JH7110_SYSCLK_GMAC1_RX, "gmac1_rx", 0, 2,
+ JH7110_SYSCLK_GMAC1_RGMII_RXIN,
+ JH7110_SYSCLK_GMAC1_RMII_RTX),
+ JH71X0__INV(JH7110_SYSCLK_GMAC1_RX_INV, "gmac1_rx_inv", JH7110_SYSCLK_GMAC1_RX),
+@@ -270,11 +270,11 @@ static const struct jh71x0_clk_data jh71
+ JH71X0_MDIV(JH7110_SYSCLK_I2STX0_LRCK_MST, "i2stx0_lrck_mst", 64, 2,
+ JH7110_SYSCLK_I2STX0_BCLK_MST_INV,
+ JH7110_SYSCLK_I2STX0_BCLK_MST),
+- JH71X0__MUX(JH7110_SYSCLK_I2STX0_BCLK, "i2stx0_bclk", 2,
++ JH71X0__MUX(JH7110_SYSCLK_I2STX0_BCLK, "i2stx0_bclk", 0, 2,
+ JH7110_SYSCLK_I2STX0_BCLK_MST,
+ JH7110_SYSCLK_I2STX_BCLK_EXT),
+ JH71X0__INV(JH7110_SYSCLK_I2STX0_BCLK_INV, "i2stx0_bclk_inv", JH7110_SYSCLK_I2STX0_BCLK),
+- JH71X0__MUX(JH7110_SYSCLK_I2STX0_LRCK, "i2stx0_lrck", 2,
++ JH71X0__MUX(JH7110_SYSCLK_I2STX0_LRCK, "i2stx0_lrck", 0, 2,
+ JH7110_SYSCLK_I2STX0_LRCK_MST,
+ JH7110_SYSCLK_I2STX_LRCK_EXT),
+ /* i2stx1 */
+@@ -285,11 +285,11 @@ static const struct jh71x0_clk_data jh71
+ JH71X0_MDIV(JH7110_SYSCLK_I2STX1_LRCK_MST, "i2stx1_lrck_mst", 64, 2,
+ JH7110_SYSCLK_I2STX1_BCLK_MST_INV,
+ JH7110_SYSCLK_I2STX1_BCLK_MST),
+- JH71X0__MUX(JH7110_SYSCLK_I2STX1_BCLK, "i2stx1_bclk", 2,
++ JH71X0__MUX(JH7110_SYSCLK_I2STX1_BCLK, "i2stx1_bclk", 0, 2,
+ JH7110_SYSCLK_I2STX1_BCLK_MST,
+ JH7110_SYSCLK_I2STX_BCLK_EXT),
+ JH71X0__INV(JH7110_SYSCLK_I2STX1_BCLK_INV, "i2stx1_bclk_inv", JH7110_SYSCLK_I2STX1_BCLK),
+- JH71X0__MUX(JH7110_SYSCLK_I2STX1_LRCK, "i2stx1_lrck", 2,
++ JH71X0__MUX(JH7110_SYSCLK_I2STX1_LRCK, "i2stx1_lrck", 0, 2,
+ JH7110_SYSCLK_I2STX1_LRCK_MST,
+ JH7110_SYSCLK_I2STX_LRCK_EXT),
+ /* i2srx */
+@@ -300,11 +300,11 @@ static const struct jh71x0_clk_data jh71
+ JH71X0_MDIV(JH7110_SYSCLK_I2SRX_LRCK_MST, "i2srx_lrck_mst", 64, 2,
+ JH7110_SYSCLK_I2SRX_BCLK_MST_INV,
+ JH7110_SYSCLK_I2SRX_BCLK_MST),
+- JH71X0__MUX(JH7110_SYSCLK_I2SRX_BCLK, "i2srx_bclk", 2,
++ JH71X0__MUX(JH7110_SYSCLK_I2SRX_BCLK, "i2srx_bclk", 0, 2,
+ JH7110_SYSCLK_I2SRX_BCLK_MST,
+ JH7110_SYSCLK_I2SRX_BCLK_EXT),
+ JH71X0__INV(JH7110_SYSCLK_I2SRX_BCLK_INV, "i2srx_bclk_inv", JH7110_SYSCLK_I2SRX_BCLK),
+- JH71X0__MUX(JH7110_SYSCLK_I2SRX_LRCK, "i2srx_lrck", 2,
++ JH71X0__MUX(JH7110_SYSCLK_I2SRX_LRCK, "i2srx_lrck", 0, 2,
+ JH7110_SYSCLK_I2SRX_LRCK_MST,
+ JH7110_SYSCLK_I2SRX_LRCK_EXT),
+ /* pdm */
+@@ -314,7 +314,7 @@ static const struct jh71x0_clk_data jh71
+ JH71X0_GATE(JH7110_SYSCLK_TDM_AHB, "tdm_ahb", 0, JH7110_SYSCLK_AHB0),
+ JH71X0_GATE(JH7110_SYSCLK_TDM_APB, "tdm_apb", 0, JH7110_SYSCLK_APB0),
+ JH71X0_GDIV(JH7110_SYSCLK_TDM_INTERNAL, "tdm_internal", 0, 64, JH7110_SYSCLK_MCLK),
+- JH71X0__MUX(JH7110_SYSCLK_TDM_TDM, "tdm_tdm", 2,
++ JH71X0__MUX(JH7110_SYSCLK_TDM_TDM, "tdm_tdm", 0, 2,
+ JH7110_SYSCLK_TDM_INTERNAL,
+ JH7110_SYSCLK_TDM_EXT),
+ JH71X0__INV(JH7110_SYSCLK_TDM_TDM_INV, "tdm_tdm_inv", JH7110_SYSCLK_TDM_TDM),
+--- a/drivers/clk/starfive/clk-starfive-jh71x0.h
++++ b/drivers/clk/starfive/clk-starfive-jh71x0.h
+@@ -61,10 +61,10 @@ struct jh71x0_clk_data {
+ .parents = { [0] = _parent }, \
+ }
+
+-#define JH71X0__MUX(_idx, _name, _nparents, ...) \
++#define JH71X0__MUX(_idx, _name, _flags, _nparents, ...) \
+ [_idx] = { \
+ .name = _name, \
+- .flags = 0, \
++ .flags = _flags, \
+ .max = ((_nparents) - 1) << JH71X0_CLK_MUX_SHIFT, \
+ .parents = { __VA_ARGS__ }, \
+ }
diff --git a/target/linux/starfive/patches-6.6/1007-clk-starfive-jh7100-Add-CLK_SET_RATE_PARENT-to-gmac_.patch b/target/linux/starfive/patches-6.6/1007-clk-starfive-jh7100-Add-CLK_SET_RATE_PARENT-to-gmac_.patch
new file mode 100644
index 0000000000..74e695c03c
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/1007-clk-starfive-jh7100-Add-CLK_SET_RATE_PARENT-to-gmac_.patch
@@ -0,0 +1,25 @@
+From 7dfed4b67bd6ba8c33caf90c01821b67cf3260dd Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <emil.renner.berthing@canonical.com>
+Date: Sat, 25 Mar 2023 23:04:31 +0100
+Subject: [PATCH 1007/1024] clk: starfive: jh7100: Add CLK_SET_RATE_PARENT to
+ gmac_tx
+
+This is needed by the dwmac-starfive ethernet driver to set the clock
+for 1000, 100 and 10 Mbps links properly.
+
+Signed-off-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
+---
+ drivers/clk/starfive/clk-starfive-jh7100.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/clk/starfive/clk-starfive-jh7100.c
++++ b/drivers/clk/starfive/clk-starfive-jh7100.c
+@@ -200,7 +200,7 @@ static const struct jh71x0_clk_data jh71
+ JH71X0_GDIV(JH7100_CLK_GMAC_GTX, "gmac_gtxclk", 0, 255, JH7100_CLK_GMAC_ROOT_DIV),
+ JH71X0_GDIV(JH7100_CLK_GMAC_RMII_TX, "gmac_rmii_txclk", 0, 8, JH7100_CLK_GMAC_RMII_REF),
+ JH71X0_GDIV(JH7100_CLK_GMAC_RMII_RX, "gmac_rmii_rxclk", 0, 8, JH7100_CLK_GMAC_RMII_REF),
+- JH71X0__MUX(JH7100_CLK_GMAC_TX, "gmac_tx", 0, 3,
++ JH71X0__MUX(JH7100_CLK_GMAC_TX, "gmac_tx", CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, 3,
+ JH7100_CLK_GMAC_GTX,
+ JH7100_CLK_GMAC_TX_INV,
+ JH7100_CLK_GMAC_RMII_TX),
diff --git a/target/linux/starfive/patches-6.6/1008-clk-starfive-jh7100-Keep-more-clocks-alive.patch b/target/linux/starfive/patches-6.6/1008-clk-starfive-jh7100-Keep-more-clocks-alive.patch
new file mode 100644
index 0000000000..27346b4df7
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/1008-clk-starfive-jh7100-Keep-more-clocks-alive.patch
@@ -0,0 +1,94 @@
+From f8d08ec17674e56c7c689f5ca43c4dd3a4b76d13 Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <kernel@esmil.dk>
+Date: Thu, 14 Oct 2021 20:35:43 +0200
+Subject: [PATCH 1008/1024] clk: starfive: jh7100: Keep more clocks alive
+
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+---
+ drivers/clk/starfive/clk-starfive-jh7100.c | 37 +++++++++++-----------
+ 1 file changed, 19 insertions(+), 18 deletions(-)
+
+--- a/drivers/clk/starfive/clk-starfive-jh7100.c
++++ b/drivers/clk/starfive/clk-starfive-jh7100.c
+@@ -94,9 +94,9 @@ static const struct jh71x0_clk_data jh71
+ JH71X0_GATE(JH7100_CLK_DMA2PNOC_AXI, "dma2pnoc_axi", 0, JH7100_CLK_CPU_AXI),
+ JH71X0_GATE(JH7100_CLK_SGDMA2P_AHB, "sgdma2p_ahb", 0, JH7100_CLK_AHB_BUS),
+ JH71X0__DIV(JH7100_CLK_DLA_BUS, "dla_bus", 4, JH7100_CLK_DLA_ROOT),
+- JH71X0_GATE(JH7100_CLK_DLA_AXI, "dla_axi", 0, JH7100_CLK_DLA_BUS),
+- JH71X0_GATE(JH7100_CLK_DLANOC_AXI, "dlanoc_axi", 0, JH7100_CLK_DLA_BUS),
+- JH71X0_GATE(JH7100_CLK_DLA_APB, "dla_apb", 0, JH7100_CLK_APB1_BUS),
++ JH71X0_GATE(JH7100_CLK_DLA_AXI, "dla_axi", CLK_IGNORE_UNUSED, JH7100_CLK_DLA_BUS),
++ JH71X0_GATE(JH7100_CLK_DLANOC_AXI, "dlanoc_axi", CLK_IGNORE_UNUSED, JH7100_CLK_DLA_BUS),
++ JH71X0_GATE(JH7100_CLK_DLA_APB, "dla_apb", CLK_IGNORE_UNUSED, JH7100_CLK_APB1_BUS),
+ JH71X0_GDIV(JH7100_CLK_VP6_CORE, "vp6_core", 0, 4, JH7100_CLK_DSP_ROOT_DIV),
+ JH71X0__DIV(JH7100_CLK_VP6BUS_SRC, "vp6bus_src", 4, JH7100_CLK_DSP_ROOT),
+ JH71X0_GDIV(JH7100_CLK_VP6_AXI, "vp6_axi", 0, 4, JH7100_CLK_VP6BUS_SRC),
+@@ -160,11 +160,12 @@ static const struct jh71x0_clk_data jh71
+ JH71X0_GATE(JH7100_CLK_DMA1P_AXI, "dma1p_axi", 0, JH7100_CLK_SGDMA1P_BUS),
+ JH71X0_GDIV(JH7100_CLK_X2C_AXI, "x2c_axi", CLK_IS_CRITICAL, 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
+ JH71X0__DIV(JH7100_CLK_USB_BUS, "usb_bus", 8, JH7100_CLK_CPUNBUS_ROOT_DIV),
+- JH71X0_GATE(JH7100_CLK_USB_AXI, "usb_axi", 0, JH7100_CLK_USB_BUS),
+- JH71X0_GATE(JH7100_CLK_USBNOC_AXI, "usbnoc_axi", 0, JH7100_CLK_USB_BUS),
++ JH71X0_GATE(JH7100_CLK_USB_AXI, "usb_axi", CLK_IGNORE_UNUSED, JH7100_CLK_USB_BUS),
++ JH71X0_GATE(JH7100_CLK_USBNOC_AXI, "usbnoc_axi", CLK_IGNORE_UNUSED, JH7100_CLK_USB_BUS),
+ JH71X0__DIV(JH7100_CLK_USBPHY_ROOTDIV, "usbphy_rootdiv", 4, JH7100_CLK_GMACUSB_ROOT),
+- JH71X0_GDIV(JH7100_CLK_USBPHY_125M, "usbphy_125m", 0, 8, JH7100_CLK_USBPHY_ROOTDIV),
+- JH71X0_GDIV(JH7100_CLK_USBPHY_PLLDIV25M, "usbphy_plldiv25m", 0, 32,
++ JH71X0_GDIV(JH7100_CLK_USBPHY_125M, "usbphy_125m", CLK_IGNORE_UNUSED, 8,
++ JH7100_CLK_USBPHY_ROOTDIV),
++ JH71X0_GDIV(JH7100_CLK_USBPHY_PLLDIV25M, "usbphy_plldiv25m", CLK_IGNORE_UNUSED, 32,
+ JH7100_CLK_USBPHY_ROOTDIV),
+ JH71X0__MUX(JH7100_CLK_USBPHY_25M, "usbphy_25m", 0, 2,
+ JH7100_CLK_OSC_SYS,
+@@ -183,23 +184,23 @@ static const struct jh71x0_clk_data jh71
+ JH71X0__DIV(JH7100_CLK_VIN_BUS, "vin_bus", 8, JH7100_CLK_VIN_SRC),
+ JH71X0_GATE(JH7100_CLK_VIN_AXI, "vin_axi", 0, JH7100_CLK_VIN_BUS),
+ JH71X0_GATE(JH7100_CLK_VINNOC_AXI, "vinnoc_axi", 0, JH7100_CLK_VIN_BUS),
+- JH71X0_GDIV(JH7100_CLK_VOUT_SRC, "vout_src", 0, 4, JH7100_CLK_VOUT_ROOT),
++ JH71X0_GDIV(JH7100_CLK_VOUT_SRC, "vout_src", CLK_IGNORE_UNUSED, 4, JH7100_CLK_VOUT_ROOT),
+ JH71X0__DIV(JH7100_CLK_DISPBUS_SRC, "dispbus_src", 4, JH7100_CLK_VOUTBUS_ROOT),
+ JH71X0__DIV(JH7100_CLK_DISP_BUS, "disp_bus", 4, JH7100_CLK_DISPBUS_SRC),
+- JH71X0_GATE(JH7100_CLK_DISP_AXI, "disp_axi", 0, JH7100_CLK_DISP_BUS),
+- JH71X0_GATE(JH7100_CLK_DISPNOC_AXI, "dispnoc_axi", 0, JH7100_CLK_DISP_BUS),
++ JH71X0_GATE(JH7100_CLK_DISP_AXI, "disp_axi", CLK_IGNORE_UNUSED, JH7100_CLK_DISP_BUS),
++ JH71X0_GATE(JH7100_CLK_DISPNOC_AXI, "dispnoc_axi", CLK_IGNORE_UNUSED, JH7100_CLK_DISP_BUS),
+ JH71X0_GATE(JH7100_CLK_SDIO0_AHB, "sdio0_ahb", 0, JH7100_CLK_AHB_BUS),
+ JH71X0_GDIV(JH7100_CLK_SDIO0_CCLKINT, "sdio0_cclkint", 0, 24, JH7100_CLK_PERH0_SRC),
+ JH71X0__INV(JH7100_CLK_SDIO0_CCLKINT_INV, "sdio0_cclkint_inv", JH7100_CLK_SDIO0_CCLKINT),
+ JH71X0_GATE(JH7100_CLK_SDIO1_AHB, "sdio1_ahb", 0, JH7100_CLK_AHB_BUS),
+ JH71X0_GDIV(JH7100_CLK_SDIO1_CCLKINT, "sdio1_cclkint", 0, 24, JH7100_CLK_PERH1_SRC),
+ JH71X0__INV(JH7100_CLK_SDIO1_CCLKINT_INV, "sdio1_cclkint_inv", JH7100_CLK_SDIO1_CCLKINT),
+- JH71X0_GATE(JH7100_CLK_GMAC_AHB, "gmac_ahb", 0, JH7100_CLK_AHB_BUS),
++ JH71X0_GATE(JH7100_CLK_GMAC_AHB, "gmac_ahb", CLK_IGNORE_UNUSED, JH7100_CLK_AHB_BUS),
+ JH71X0__DIV(JH7100_CLK_GMAC_ROOT_DIV, "gmac_root_div", 8, JH7100_CLK_GMACUSB_ROOT),
+- JH71X0_GDIV(JH7100_CLK_GMAC_PTP_REF, "gmac_ptp_refclk", 0, 31, JH7100_CLK_GMAC_ROOT_DIV),
+- JH71X0_GDIV(JH7100_CLK_GMAC_GTX, "gmac_gtxclk", 0, 255, JH7100_CLK_GMAC_ROOT_DIV),
+- JH71X0_GDIV(JH7100_CLK_GMAC_RMII_TX, "gmac_rmii_txclk", 0, 8, JH7100_CLK_GMAC_RMII_REF),
+- JH71X0_GDIV(JH7100_CLK_GMAC_RMII_RX, "gmac_rmii_rxclk", 0, 8, JH7100_CLK_GMAC_RMII_REF),
++ JH71X0_GDIV(JH7100_CLK_GMAC_PTP_REF, "gmac_ptp_refclk", CLK_IGNORE_UNUSED, 31, JH7100_CLK_GMAC_ROOT_DIV),
++ JH71X0_GDIV(JH7100_CLK_GMAC_GTX, "gmac_gtxclk", CLK_IGNORE_UNUSED, 255, JH7100_CLK_GMAC_ROOT_DIV),
++ JH71X0_GDIV(JH7100_CLK_GMAC_RMII_TX, "gmac_rmii_txclk", CLK_IGNORE_UNUSED, 8, JH7100_CLK_GMAC_RMII_REF),
++ JH71X0_GDIV(JH7100_CLK_GMAC_RMII_RX, "gmac_rmii_rxclk", CLK_IGNORE_UNUSED, 8, JH7100_CLK_GMAC_RMII_REF),
+ JH71X0__MUX(JH7100_CLK_GMAC_TX, "gmac_tx", CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, 3,
+ JH7100_CLK_GMAC_GTX,
+ JH7100_CLK_GMAC_TX_INV,
+@@ -209,8 +210,8 @@ static const struct jh71x0_clk_data jh71
+ JH7100_CLK_GMAC_GR_MII_RX,
+ JH7100_CLK_GMAC_RMII_RX),
+ JH71X0__INV(JH7100_CLK_GMAC_RX_INV, "gmac_rx_inv", JH7100_CLK_GMAC_RX_PRE),
+- JH71X0_GATE(JH7100_CLK_GMAC_RMII, "gmac_rmii", 0, JH7100_CLK_GMAC_RMII_REF),
+- JH71X0_GDIV(JH7100_CLK_GMAC_TOPHYREF, "gmac_tophyref", 0, 127, JH7100_CLK_GMAC_ROOT_DIV),
++ JH71X0_GATE(JH7100_CLK_GMAC_RMII, "gmac_rmii", CLK_IGNORE_UNUSED, JH7100_CLK_GMAC_RMII_REF),
++ JH71X0_GDIV(JH7100_CLK_GMAC_TOPHYREF, "gmac_tophyref", CLK_IGNORE_UNUSED, 127, JH7100_CLK_GMAC_ROOT_DIV),
+ JH71X0_GATE(JH7100_CLK_SPI2AHB_AHB, "spi2ahb_ahb", 0, JH7100_CLK_AHB_BUS),
+ JH71X0_GDIV(JH7100_CLK_SPI2AHB_CORE, "spi2ahb_core", 0, 31, JH7100_CLK_PERH0_SRC),
+ JH71X0_GATE(JH7100_CLK_EZMASTER_AHB, "ezmaster_ahb", 0, JH7100_CLK_AHB_BUS),
+@@ -223,7 +224,7 @@ static const struct jh71x0_clk_data jh71
+ JH71X0_GATE(JH7100_CLK_AES, "aes_clk", 0, JH7100_CLK_SEC_AHB),
+ JH71X0_GATE(JH7100_CLK_SHA, "sha_clk", 0, JH7100_CLK_SEC_AHB),
+ JH71X0_GATE(JH7100_CLK_PKA, "pka_clk", 0, JH7100_CLK_SEC_AHB),
+- JH71X0_GATE(JH7100_CLK_TRNG_APB, "trng_apb", 0, JH7100_CLK_APB1_BUS),
++ JH71X0_GATE(JH7100_CLK_TRNG_APB, "trng_apb", CLK_IGNORE_UNUSED, JH7100_CLK_APB1_BUS),
+ JH71X0_GATE(JH7100_CLK_OTP_APB, "otp_apb", 0, JH7100_CLK_APB1_BUS),
+ JH71X0_GATE(JH7100_CLK_UART0_APB, "uart0_apb", 0, JH7100_CLK_APB1_BUS),
+ JH71X0_GDIV(JH7100_CLK_UART0_CORE, "uart0_core", 0, 63, JH7100_CLK_PERH1_SRC),
diff --git a/target/linux/starfive/patches-6.6/1009-net-stmmac-use-GFP_DMA32.patch b/target/linux/starfive/patches-6.6/1009-net-stmmac-use-GFP_DMA32.patch
new file mode 100644
index 0000000000..ad8b92f715
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/1009-net-stmmac-use-GFP_DMA32.patch
@@ -0,0 +1,30 @@
+From 980f1e9ef19d472e72c36e142db7fb4e224f0f3e Mon Sep 17 00:00:00 2001
+From: Matteo Croce <technoboy85@gmail.com>
+Date: Fri, 21 May 2021 03:26:38 +0200
+Subject: [PATCH 1009/1024] net: stmmac: use GFP_DMA32
+
+Signed-off-by: Matteo Croce <mcroce@microsoft.com>
+---
+ drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -1434,7 +1434,7 @@ static int stmmac_init_rx_buffers(struct
+ {
+ struct stmmac_rx_queue *rx_q = &dma_conf->rx_queue[queue];
+ struct stmmac_rx_buffer *buf = &rx_q->buf_pool[i];
+- gfp_t gfp = (GFP_ATOMIC | __GFP_NOWARN);
++ gfp_t gfp = (GFP_ATOMIC | __GFP_NOWARN | GFP_DMA32);
+
+ if (priv->dma_cap.host_dma_width <= 32)
+ gfp |= GFP_DMA32;
+@@ -4673,7 +4673,7 @@ static inline void stmmac_rx_refill(stru
+ struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue];
+ int dirty = stmmac_rx_dirty(priv, queue);
+ unsigned int entry = rx_q->dirty_rx;
+- gfp_t gfp = (GFP_ATOMIC | __GFP_NOWARN);
++ gfp_t gfp = (GFP_ATOMIC | __GFP_NOWARN | GFP_DMA32);
+
+ if (priv->dma_cap.host_dma_width <= 32)
+ gfp |= GFP_DMA32;
diff --git a/target/linux/starfive/patches-6.6/1010-hwrng-Add-StarFive-JH7100-Random-Number-Generator-dr.patch b/target/linux/starfive/patches-6.6/1010-hwrng-Add-StarFive-JH7100-Random-Number-Generator-dr.patch
new file mode 100644
index 0000000000..b625014dd9
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/1010-hwrng-Add-StarFive-JH7100-Random-Number-Generator-dr.patch
@@ -0,0 +1,477 @@
+From 4989e7aa5ed5ef9bc2532b3a47ff381572f389b5 Mon Sep 17 00:00:00 2001
+From: Huan Feng <huan.feng@starfivetech.com>
+Date: Fri, 8 Jan 2021 03:35:42 +0800
+Subject: [PATCH 1010/1024] hwrng: Add StarFive JH7100 Random Number Generator
+ driver
+
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+---
+ drivers/char/hw_random/Kconfig | 13 ++
+ drivers/char/hw_random/Makefile | 1 +
+ drivers/char/hw_random/starfive-vic-rng.c | 256 ++++++++++++++++++++++
+ drivers/char/hw_random/starfive-vic-rng.h | 167 ++++++++++++++
+ 4 files changed, 437 insertions(+)
+ create mode 100644 drivers/char/hw_random/starfive-vic-rng.c
+ create mode 100644 drivers/char/hw_random/starfive-vic-rng.h
+
+--- a/drivers/char/hw_random/Kconfig
++++ b/drivers/char/hw_random/Kconfig
+@@ -322,6 +322,19 @@ config HW_RANDOM_POWERNV
+
+ If unsure, say Y.
+
++config HW_RANDOM_STARFIVE_VIC
++ tristate "Starfive VIC Random Number Generator support"
++ depends on HW_RANDOM && (SOC_STARFIVE || COMPILE_TEST)
++ default SOC_STARFIVE
++ help
++ This driver provides kernel-side support for the Random Number
++ Generator hardware found on Starfive VIC SoC.
++
++ To compile this driver as a module, choose M here: the
++ module will be called starfive-vic-rng.
++
++ If unsure, say Y.
++
+ config HW_RANDOM_HISI
+ tristate "Hisilicon Random Number Generator support"
+ depends on ARCH_HISI || COMPILE_TEST
+--- a/drivers/char/hw_random/Makefile
++++ b/drivers/char/hw_random/Makefile
+@@ -28,6 +28,7 @@ obj-$(CONFIG_HW_RANDOM_OCTEON) += octeon
+ obj-$(CONFIG_HW_RANDOM_NOMADIK) += nomadik-rng.o
+ obj-$(CONFIG_HW_RANDOM_PSERIES) += pseries-rng.o
+ obj-$(CONFIG_HW_RANDOM_POWERNV) += powernv-rng.o
++obj-$(CONFIG_HW_RANDOM_STARFIVE_VIC) += starfive-vic-rng.o
+ obj-$(CONFIG_HW_RANDOM_HISI) += hisi-rng.o
+ obj-$(CONFIG_HW_RANDOM_HISTB) += histb-rng.o
+ obj-$(CONFIG_HW_RANDOM_BCM2835) += bcm2835-rng.o
+--- /dev/null
++++ b/drivers/char/hw_random/starfive-vic-rng.c
+@@ -0,0 +1,256 @@
++/*
++ ******************************************************************************
++ * @file starfive-vic-rng.c
++ * @author StarFive Technology
++ * @version V1.0
++ * @date 08/13/2020
++ * @brief
++ ******************************************************************************
++ * @copy
++ *
++ * THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
++ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
++ * TIME. AS A RESULT, STARFIVE SHALL NOT BE HELD LIABLE FOR ANY
++ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
++ * FROM THE CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
++ * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
++ *
++ * COPYRIGHT 2020 Shanghai StarFive Technology Co., Ltd.
++ */
++#include <linux/err.h>
++#include <linux/kernel.h>
++#include <linux/hw_random.h>
++#include <linux/io.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/platform_device.h>
++#include <linux/interrupt.h>
++#include <linux/random.h>
++
++#include "starfive-vic-rng.h"
++
++#define to_vic_rng(p) container_of(p, struct vic_rng, rng)
++
++struct vic_rng {
++ struct device *dev;
++ void __iomem *base;
++ struct hwrng rng;
++};
++
++static inline void vic_wait_till_idle(struct vic_rng *hrng)
++{
++ while(readl(hrng->base + VIC_STAT) & VIC_STAT_BUSY)
++ ;
++}
++
++static inline void vic_rng_irq_mask_clear(struct vic_rng *hrng)
++{
++ // clear register: ISTAT
++ u32 data = readl(hrng->base + VIC_ISTAT);
++ writel(data, hrng->base + VIC_ISTAT);
++ writel(0, hrng->base + VIC_ALARM);
++}
++
++static int vic_trng_cmd(struct vic_rng *hrng, u32 cmd) {
++ int res = 0;
++ // wait till idle
++ vic_wait_till_idle(hrng);
++ switch (cmd) {
++ case VIC_CTRL_CMD_NOP:
++ case VIC_CTRL_CMD_GEN_NOISE:
++ case VIC_CTRL_CMD_GEN_NONCE:
++ case VIC_CTRL_CMD_CREATE_STATE:
++ case VIC_CTRL_CMD_RENEW_STATE:
++ case VIC_CTRL_CMD_REFRESH_ADDIN:
++ case VIC_CTRL_CMD_GEN_RANDOM:
++ case VIC_CTRL_CMD_ADVANCE_STATE:
++ case VIC_CTRL_CMD_KAT:
++ case VIC_CTRL_CMD_ZEROIZE:
++ writel(cmd, hrng->base + VIC_CTRL);
++ break;
++ default:
++ res = -1;
++ break;
++ }
++
++ return res;
++}
++
++static int vic_rng_init(struct hwrng *rng)
++{
++ struct vic_rng *hrng = to_vic_rng(rng);
++
++ // wait till idle
++
++ // clear register: ISTAT
++ vic_rng_irq_mask_clear(hrng);
++
++ // set mission mode
++ writel(VIC_SMODE_SECURE_EN(1), hrng->base + VIC_SMODE);
++
++ vic_trng_cmd(hrng, VIC_CTRL_CMD_GEN_NOISE);
++ vic_wait_till_idle(hrng);
++
++ // set interrupt
++ writel(VIC_IE_ALL, hrng->base + VIC_IE);
++
++ // zeroize
++ vic_trng_cmd(hrng, VIC_CTRL_CMD_ZEROIZE);
++
++ vic_wait_till_idle(hrng);
++
++ return 0;
++}
++
++static irqreturn_t vic_rng_irq(int irq, void *priv)
++{
++ u32 status, val;
++ struct vic_rng *hrng = (struct vic_rng *)priv;
++
++ /*
++ * clearing the interrupt will also clear the error register
++ * read error and status before clearing
++ */
++ status = readl(hrng->base + VIC_ISTAT);
++
++ if (status & VIC_ISTAT_ALARMS) {
++ writel(VIC_ISTAT_ALARMS, hrng->base + VIC_ISTAT);
++ val = readl(hrng->base + VIC_ALARM);
++ if (val & VIC_ALARM_ILLEGAL_CMD_SEQ) {
++ writel(VIC_ALARM_ILLEGAL_CMD_SEQ, hrng->base + VIC_ALARM);
++ //dev_info(hrng->dev, "ILLEGAL CMD SEQ: LAST_CMD=0x%x\r\n",
++ //VIC_STAT_LAST_CMD(readl(hrng->base + VIC_STAT)));
++ } else {
++ dev_info(hrng->dev, "Failed test: %x\r\n", val);
++ }
++ }
++
++ if (status & VIC_ISTAT_ZEROIZE) {
++ writel(VIC_ISTAT_ZEROIZE, hrng->base + VIC_ISTAT);
++ //dev_info(hrng->dev, "zeroized\r\n");
++ }
++
++ if (status & VIC_ISTAT_KAT_COMPLETE) {
++ writel(VIC_ISTAT_KAT_COMPLETE, hrng->base + VIC_ISTAT);
++ //dev_info(hrng->dev, "kat_completed\r\n");
++ }
++
++ if (status & VIC_ISTAT_NOISE_RDY) {
++ writel(VIC_ISTAT_NOISE_RDY, hrng->base + VIC_ISTAT);
++ //dev_info(hrng->dev, "noise_rdy\r\n");
++ }
++
++ if (status & VIC_ISTAT_DONE) {
++ writel(VIC_ISTAT_DONE, hrng->base + VIC_ISTAT);
++ //dev_info(hrng->dev, "done\r\n");
++ /*
++ if (VIC_STAT_LAST_CMD(readl(hrng->base + VIC_STAT)) ==
++ VIC_CTRL_CMD_GEN_RANDOM) {
++ dev_info(hrng->dev, "Need Update Buffer\r\n");
++ }
++ */
++ }
++ vic_rng_irq_mask_clear(hrng);
++
++ return IRQ_HANDLED;
++}
++
++static void vic_rng_cleanup(struct hwrng *rng)
++{
++ struct vic_rng *hrng = to_vic_rng(rng);
++
++ writel(0, hrng->base + VIC_CTRL);
++}
++
++static int vic_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait)
++{
++ struct vic_rng *hrng = to_vic_rng(rng);
++
++ vic_trng_cmd(hrng, VIC_CTRL_CMD_ZEROIZE);
++ vic_trng_cmd(hrng, VIC_CTRL_CMD_GEN_NOISE);
++ vic_trng_cmd(hrng, VIC_CTRL_CMD_CREATE_STATE);
++
++ vic_wait_till_idle(hrng);
++ max = min_t(size_t, max, (VIC_RAND_LEN * 4));
++
++ writel(0x0, hrng->base + VIC_MODE);
++ vic_trng_cmd(hrng, VIC_CTRL_CMD_GEN_RANDOM);
++
++ vic_wait_till_idle(hrng);
++ memcpy_fromio(buf, hrng->base + VIC_RAND0, max);
++ vic_trng_cmd(hrng, VIC_CTRL_CMD_ZEROIZE);
++
++ vic_wait_till_idle(hrng);
++ return max;
++}
++
++static int vic_rng_probe(struct platform_device *pdev)
++{
++ int ret;
++ int irq;
++ struct vic_rng *rng;
++ struct resource *res;
++
++ rng = devm_kzalloc(&pdev->dev, sizeof(*rng), GFP_KERNEL);
++ if (!rng){
++ return -ENOMEM;
++ }
++
++ platform_set_drvdata(pdev, rng);
++
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ rng->base = devm_ioremap_resource(&pdev->dev, res);
++ if (IS_ERR(rng->base)){
++ return PTR_ERR(rng->base);
++ }
++
++ irq = platform_get_irq(pdev, 0);
++ if (irq <= 0) {
++ dev_err(&pdev->dev, "Couldn't get irq %d\n", irq);
++ return irq;
++ }
++
++ ret = devm_request_irq(&pdev->dev, irq, vic_rng_irq, 0, pdev->name,
++ (void *)rng);
++ if (ret) {
++ dev_err(&pdev->dev, "Can't get interrupt working.\n");
++ return ret;
++ }
++
++ rng->rng.name = pdev->name;
++ rng->rng.init = vic_rng_init;
++ rng->rng.cleanup = vic_rng_cleanup;
++ rng->rng.read = vic_rng_read;
++
++ rng->dev = &pdev->dev;
++
++ ret = devm_hwrng_register(&pdev->dev, &rng->rng);
++ if (ret) {
++ dev_err(&pdev->dev, "failed to register hwrng\n");
++ return ret;
++ }
++
++ dev_info(&pdev->dev, "Initialized\n");
++
++ return 0;
++}
++
++static const struct of_device_id vic_rng_dt_ids[] = {
++ { .compatible = "starfive,vic-rng" },
++ { }
++};
++MODULE_DEVICE_TABLE(of, vic_rng_dt_ids);
++
++static struct platform_driver vic_rng_driver = {
++ .probe = vic_rng_probe,
++ .driver = {
++ .name = "vic-rng",
++ .of_match_table = vic_rng_dt_ids,
++ },
++};
++
++module_platform_driver(vic_rng_driver);
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Huan Feng <huan.feng@starfivetech.com>");
++MODULE_DESCRIPTION("Starfive VIC random number generator driver");
+--- /dev/null
++++ b/drivers/char/hw_random/starfive-vic-rng.h
+@@ -0,0 +1,167 @@
++/*
++ ******************************************************************************
++ * @file starfive-vic-rng.h
++ * @author StarFive Technology
++ * @version V1.0
++ * @date 08/13/2020
++ * @brief
++ ******************************************************************************
++ * @copy
++ *
++ * THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
++ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
++ * TIME. AS A RESULT, STARFIVE SHALL NOT BE HELD LIABLE FOR ANY
++ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
++ * FROM THE CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
++ * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
++ *
++ * COPYRIGHT 2020 Shanghai StarFive Technology Co., Ltd.
++ */
++
++#define VIC_CTRL 0x00
++#define VIC_MODE 0x04
++#define VIC_SMODE 0x08
++#define VIC_STAT 0x0C
++#define VIC_IE 0x10
++#define VIC_ISTAT 0x14
++#define VIC_ALARM 0x18
++#define VIC_BUILD_ID 0x1C
++#define VIC_FEATURES 0x20
++#define VIC_RAND0 0x24
++#define VIC_NPA_DATA0 0x34
++#define VIC_SEED0 0x74
++#define VIC_IA_RDATA 0xA4
++#define VIC_IA_WDATA 0xA8
++#define VIC_IA_ADDR 0xAC
++#define VIC_IA_CMD 0xB0
++
++/* CTRL */
++#define VIC_CTRL_CMD_NOP 0
++#define VIC_CTRL_CMD_GEN_NOISE 1
++#define VIC_CTRL_CMD_GEN_NONCE 2
++#define VIC_CTRL_CMD_CREATE_STATE 3
++#define VIC_CTRL_CMD_RENEW_STATE 4
++#define VIC_CTRL_CMD_REFRESH_ADDIN 5
++#define VIC_CTRL_CMD_GEN_RANDOM 6
++#define VIC_CTRL_CMD_ADVANCE_STATE 7
++#define VIC_CTRL_CMD_KAT 8
++#define VIC_CTRL_CMD_ZEROIZE 15
++
++/* MODE */
++#define _VIC_MODE_ADDIN_PRESENT 4
++#define _VIC_MODE_PRED_RESIST 3
++#define _VIC_MODE_KAT_SEL 2
++#define _VIC_MODE_KAT_VEC 1
++#define _VIC_MODE_SEC_ALG 0
++
++#define VIC_MODE_ADDIN_PRESENT (1UL << _VIC_MODE_ADDIN_PRESENT)
++#define VIC_MODE_PRED_RESIST (1UL << _VIC_MODE_PRED_RESIST)
++#define VIC_MODE_KAT_SEL (1UL << _VIC_MODE_KAT_SEL)
++#define VIC_MODE_KAT_VEC (1UL << _VIC_MODE_KAT_VEC)
++#define VIC_MODE_SEC_ALG (1UL << _VIC_MODE_SEC_ALG)
++
++/* SMODE */
++#define _VIC_SMODE_MAX_REJECTS 2
++#define _VIC_SMODE_SECURE_EN 1
++#define _VIC_SMODE_NONCE 0
++
++#define VIC_SMODE_MAX_REJECTS(x) ((x) << _VIC_SMODE_MAX_REJECTS)
++#define VIC_SMODE_SECURE_EN(x) ((x) << _VIC_SMODE_SECURE_EN)
++#define VIC_SMODE_NONCE (1UL << _VIC_SMODE_NONCE)
++
++/* STAT */
++#define _VIC_STAT_BUSY 31
++#define _VIC_STAT_DRBG_STATE 7
++#define _VIC_STAT_SECURE 6
++#define _VIC_STAT_NONCE_MODE 5
++#define _VIC_STAT_SEC_ALG 4
++#define _VIC_STAT_LAST_CMD 0
++
++#define VIC_STAT_BUSY (1UL << _VIC_STAT_BUSY)
++#define VIC_STAT_DRBG_STATE (1UL << _VIC_STAT_DRBG_STATE)
++#define VIC_STAT_SECURE (1UL << _VIC_STAT_SECURE)
++#define VIC_STAT_NONCE_MODE (1UL << _VIC_STAT_NONCE_MODE)
++#define VIC_STAT_SEC_ALG (1UL << _VIC_STAT_SEC_ALG)
++#define VIC_STAT_LAST_CMD(x) (((x) >> _VIC_STAT_LAST_CMD) & 0xF)
++
++/* IE */
++#define _VIC_IE_GLBL 31
++#define _VIC_IE_DONE 4
++#define _VIC_IE_ALARMS 3
++#define _VIC_IE_NOISE_RDY 2
++#define _VIC_IE_KAT_COMPLETE 1
++#define _VIC_IE_ZEROIZE 0
++
++#define VIC_IE_GLBL (1UL << _VIC_IE_GLBL)
++#define VIC_IE_DONE (1UL << _VIC_IE_DONE)
++#define VIC_IE_ALARMS (1UL << _VIC_IE_ALARMS)
++#define VIC_IE_NOISE_RDY (1UL << _VIC_IE_NOISE_RDY)
++#define VIC_IE_KAT_COMPLETE (1UL << _VIC_IE_KAT_COMPLETE)
++#define VIC_IE_ZEROIZE (1UL << _VIC_IE_ZEROIZE)
++#define VIC_IE_ALL (VIC_IE_GLBL | VIC_IE_DONE | VIC_IE_ALARMS | \
++ VIC_IE_NOISE_RDY | VIC_IE_KAT_COMPLETE | VIC_IE_ZEROIZE)
++
++/* ISTAT */
++#define _VIC_ISTAT_DONE 4
++#define _VIC_ISTAT_ALARMS 3
++#define _VIC_ISTAT_NOISE_RDY 2
++#define _VIC_ISTAT_KAT_COMPLETE 1
++#define _VIC_ISTAT_ZEROIZE 0
++
++#define VIC_ISTAT_DONE (1UL << _VIC_ISTAT_DONE)
++#define VIC_ISTAT_ALARMS (1UL << _VIC_ISTAT_ALARMS)
++#define VIC_ISTAT_NOISE_RDY (1UL << _VIC_ISTAT_NOISE_RDY)
++#define VIC_ISTAT_KAT_COMPLETE (1UL << _VIC_ISTAT_KAT_COMPLETE)
++#define VIC_ISTAT_ZEROIZE (1UL << _VIC_ISTAT_ZEROIZE)
++
++/* ALARMS */
++#define VIC_ALARM_ILLEGAL_CMD_SEQ (1UL << 4)
++#define VIC_ALARM_FAILED_TEST_ID_OK 0
++#define VIC_ALARM_FAILED_TEST_ID_KAT_STAT 1
++#define VIC_ALARM_FAILED_TEST_ID_KAT 2
++#define VIC_ALARM_FAILED_TEST_ID_MONOBIT 3
++#define VIC_ALARM_FAILED_TEST_ID_RUN 4
++#define VIC_ALARM_FAILED_TEST_ID_LONGRUN 5
++#define VIC_ALARM_FAILED_TEST_ID_AUTOCORRELATION 6
++#define VIC_ALARM_FAILED_TEST_ID_POKER 7
++#define VIC_ALARM_FAILED_TEST_ID_REPETITION_COUNT 8
++#define VIC_ALARM_FAILED_TEST_ID_ADAPATIVE_PROPORTION 9
++
++/* BUILD_ID */
++#define VIC_BUILD_ID_STEPPING(x) (((x) >> 28) & 0xF)
++#define VIC_BUILD_ID_EPN(x) ((x) & 0xFFFF)
++
++/* FEATURES */
++#define VIC_FEATURES_AES_256(x) (((x) >> 9) & 1)
++#define VIC_FEATURES_EXTRA_PS_PRESENT(x) (((x) >> 8) & 1)
++#define VIC_FEATURES_DIAG_LEVEL_NS(x) (((x) >> 7) & 1)
++#define VIC_FEATURES_DIAG_LEVEL_CLP800(x) (((x) >> 4) & 7)
++#define VIC_FEATURES_DIAG_LEVEL_ST_HLT(x) (((x) >> 1) & 7)
++#define VIC_FEATURES_SECURE_RST_STATE(x) ((x) & 1)
++
++/* IA_CMD */
++#define VIC_IA_CMD_GO (1UL << 31)
++#define VIC_IA_CMD_WR (1)
++
++#define _VIC_SMODE_MAX_REJECTS_MASK 255UL
++#define _VIC_SMODE_SECURE_EN_MASK 1UL
++#define _VIC_SMODE_NONCE_MASK 1UL
++#define _VIC_MODE_SEC_ALG_MASK 1UL
++#define _VIC_MODE_ADDIN_PRESENT_MASK 1UL
++#define _VIC_MODE_PRED_RESIST_MASK 1UL
++
++#define VIC_SMODE_SET_MAX_REJECTS(y, x) (((y) & ~(_VIC_SMODE_MAX_REJECTS_MASK << _VIC_SMODE_MAX_REJECTS)) | ((x) << _VIC_SMODE_MAX_REJECTS))
++#define VIC_SMODE_SET_SECURE_EN(y, x) (((y) & ~(_VIC_SMODE_SECURE_EN_MASK << _VIC_SMODE_SECURE_EN)) | ((x) << _VIC_SMODE_SECURE_EN))
++#define VIC_SMODE_SET_NONCE(y, x) (((y) & ~(_VIC_SMODE_NONCE_MASK << _VIC_SMODE_NONCE)) | ((x) << _VIC_SMODE_NONCE))
++#define VIC_SMODE_GET_MAX_REJECTS(x) (((x) >> _VIC_SMODE_MAX_REJECTS) & _VIC_SMODE_MAX_REJECTS_MASK)
++#define VIC_SMODE_GET_SECURE_EN(x) (((x) >> _VIC_SMODE_SECURE_EN) & _VIC_SMODE_SECURE_EN_MASK)
++#define VIC_SMODE_GET_NONCE(x) (((x) >> _VIC_SMODE_NONCE) & _VIC_SMODE_NONCE_MASK)
++
++#define VIC_MODE_SET_SEC_ALG(y, x) (((y) & ~(_VIC_MODE_SEC_ALG_MASK << _VIC_MODE_SEC_ALG)) | ((x) << _VIC_MODE_SEC_ALG))
++#define VIC_MODE_SET_PRED_RESIST(y, x) (((y) & ~(_VIC_MODE_PRED_RESIST_MASK << _VIC_MODE_PRED_RESIST)) | ((x) << _VIC_MODE_PRED_RESIST))
++#define VIC_MODE_SET_ADDIN_PRESENT(y, x) (((y) & ~(_VIC_MODE_ADDIN_PRESENT_MASK << _VIC_MODE_ADDIN_PRESENT)) | ((x) << _VIC_MODE_ADDIN_PRESENT))
++#define VIC_MODE_GET_SEC_ALG(x) (((x) >> _VIC_MODE_SEC_ALG) & _VIC_MODE_SEC_ALG_MASK)
++#define VIC_MODE_GET_PRED_RESIST(x) (((x) >> _VIC_MODE_PRED_RESIST) & _VIC_MODE_PRED_RESIST_MASK)
++#define VIC_MODE_GET_ADDIN_PRESENT(x) (((x) >> _VIC_MODE_ADDIN_PRESENT) & _VIC_MODE_ADDIN_PRESENT_MASK)
++
++#define VIC_RAND_LEN 4
diff --git a/target/linux/starfive/patches-6.6/1011-pwm-sifive-ptc-Add-SiFive-PWM-PTC-driver.patch b/target/linux/starfive/patches-6.6/1011-pwm-sifive-ptc-Add-SiFive-PWM-PTC-driver.patch
new file mode 100644
index 0000000000..7a588c27c4
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/1011-pwm-sifive-ptc-Add-SiFive-PWM-PTC-driver.patch
@@ -0,0 +1,309 @@
+From 34fd7b7f92deef97f03c80d056e2f51bc08b7dc6 Mon Sep 17 00:00:00 2001
+From: Chenjieqin <Jessica.Chen@starfivetech.com>
+Date: Fri, 8 Jan 2021 03:56:54 +0800
+Subject: [PATCH 1011/1024] pwm: sifive-ptc: Add SiFive PWM PTC driver
+
+yiming.li: clear CNTR of PWM after setting period & duty_cycle
+Emil: cleanups, clock, reset and div_u64
+
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+---
+ drivers/pwm/Kconfig | 11 ++
+ drivers/pwm/Makefile | 1 +
+ drivers/pwm/pwm-sifive-ptc.c | 260 +++++++++++++++++++++++++++++++++++
+ 3 files changed, 272 insertions(+)
+ create mode 100644 drivers/pwm/pwm-sifive-ptc.c
+
+--- a/drivers/pwm/Kconfig
++++ b/drivers/pwm/Kconfig
+@@ -549,6 +549,17 @@ config PWM_SIFIVE
+ To compile this driver as a module, choose M here: the module
+ will be called pwm-sifive.
+
++config PWM_SIFIVE_PTC
++ tristate "SiFive PWM PTC support"
++ depends on SOC_SIFIVE || SOC_STARFIVE || COMPILE_TEST
++ depends on OF
++ depends on COMMON_CLK
++ help
++ Generic PWM framework driver for SiFive SoCs.
++
++ To compile this driver as a module, choose M here: the module
++ will be called pwm-sifive-ptc.
++
+ config PWM_SL28CPLD
+ tristate "Kontron sl28cpld PWM support"
+ depends on MFD_SL28CPLD || COMPILE_TEST
+--- a/drivers/pwm/Makefile
++++ b/drivers/pwm/Makefile
+@@ -50,6 +50,7 @@ obj-$(CONFIG_PWM_ROCKCHIP) += pwm-rockch
+ obj-$(CONFIG_PWM_RZ_MTU3) += pwm-rz-mtu3.o
+ obj-$(CONFIG_PWM_SAMSUNG) += pwm-samsung.o
+ obj-$(CONFIG_PWM_SIFIVE) += pwm-sifive.o
++obj-$(CONFIG_PWM_SIFIVE_PTC) += pwm-sifive-ptc.o
+ obj-$(CONFIG_PWM_SL28CPLD) += pwm-sl28cpld.o
+ obj-$(CONFIG_PWM_SPEAR) += pwm-spear.o
+ obj-$(CONFIG_PWM_SPRD) += pwm-sprd.o
+--- /dev/null
++++ b/drivers/pwm/pwm-sifive-ptc.c
+@@ -0,0 +1,260 @@
++/*
++ * Copyright (C) 2018 SiFive, Inc
++ *
++ * 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.
++ */
++
++#include <linux/clk.h>
++#include <linux/io.h>
++#include <linux/math64.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/pwm.h>
++#include <linux/reset.h>
++
++#include <dt-bindings/pwm/pwm.h>
++
++/* max channel of pwm */
++#define MAX_PWM 8
++
++/* PTC Register offsets */
++#define REG_RPTC_CNTR 0x0
++#define REG_RPTC_HRC 0x4
++#define REG_RPTC_LRC 0x8
++#define REG_RPTC_CTRL 0xC
++
++/* Bit for PWM clock */
++#define BIT_PWM_CLOCK_EN 31
++
++/* Bit for clock gen soft reset */
++#define BIT_CLK_GEN_SOFT_RESET 13
++
++#define NS_1 1000000000U
++
++/* Access PTC register (cntr hrc lrc and ctrl), need to replace PWM_BASE_ADDR */
++#define REG_PTC_BASE_ADDR_SUB(base, N) \
++ ((base) + (((N) > 3) ? (((N) - 4) * 0x10 + (1 << 15)) : ((N) * 0x10)))
++#define REG_PTC_RPTC_CNTR(base, N) (REG_PTC_BASE_ADDR_SUB(base, N))
++#define REG_PTC_RPTC_HRC(base, N) (REG_PTC_BASE_ADDR_SUB(base, N) + 0x4)
++#define REG_PTC_RPTC_LRC(base, N) (REG_PTC_BASE_ADDR_SUB(base, N) + 0x8)
++#define REG_PTC_RPTC_CTRL(base, N) (REG_PTC_BASE_ADDR_SUB(base, N) + 0xC)
++
++/* pwm ptc device */
++struct sifive_pwm_ptc_device {
++ struct pwm_chip chip;
++ struct clk *clk;
++ void __iomem *regs;
++};
++
++static inline struct sifive_pwm_ptc_device *chip_to_sifive_ptc(struct pwm_chip *c)
++{
++ return container_of(c, struct sifive_pwm_ptc_device, chip);
++}
++
++static int sifive_pwm_ptc_get_state(struct pwm_chip *chip, struct pwm_device *dev,
++ struct pwm_state *state)
++{
++ struct sifive_pwm_ptc_device *pwm = chip_to_sifive_ptc(chip);
++ u32 data_lrc;
++ u32 data_hrc;
++ u32 pwm_clk_ns = 0;
++
++ /* get lrc and hrc data from registe */
++ data_lrc = ioread32(REG_PTC_RPTC_LRC(pwm->regs, dev->hwpwm));
++ data_hrc = ioread32(REG_PTC_RPTC_HRC(pwm->regs, dev->hwpwm));
++
++ /* how many ns does apb clock elapse */
++ pwm_clk_ns = NS_1 / clk_get_rate(pwm->clk);
++
++ /* pwm period(ns) */
++ state->period = data_lrc * pwm_clk_ns;
++
++ /* duty cycle(ns) means high level eclapse ns if it is normal polarity */
++ state->duty_cycle = data_hrc * pwm_clk_ns;
++
++ /* polarity, we don't use it now because it is not in dts */
++ state->polarity = PWM_POLARITY_NORMAL;
++
++ /* enabled or not */
++ state->enabled = 1;
++
++ dev_dbg(pwm->chip.dev, "%s: no:%d\n", __func__, dev->hwpwm);
++ dev_dbg(pwm->chip.dev, "data_hrc:0x%x 0x%x\n", data_hrc, data_lrc);
++ dev_dbg(pwm->chip.dev, "period:%llu\n", state->period);
++ dev_dbg(pwm->chip.dev, "duty_cycle:%llu\n", state->duty_cycle);
++ dev_dbg(pwm->chip.dev, "polarity:%d\n", state->polarity);
++ dev_dbg(pwm->chip.dev, "enabled:%d\n", state->enabled);
++
++ return 0;
++}
++
++static int sifive_pwm_ptc_apply(struct pwm_chip *chip, struct pwm_device *dev,
++ const struct pwm_state *state)
++{
++ struct sifive_pwm_ptc_device *pwm = chip_to_sifive_ptc(chip);
++ void __iomem *reg_addr;
++ u32 pwm_clk_ns = 0;
++ u32 data_hrc = 0;
++ u32 data_lrc = 0;
++ u32 period_data = 0;
++ u32 duty_data = 0;
++
++ dev_dbg(pwm->chip.dev, "%s: no:%d\n", __func__, dev->hwpwm);
++ dev_dbg(pwm->chip.dev, "period:%llu\n", state->period);
++ dev_dbg(pwm->chip.dev, "duty_cycle:%llu\n", state->duty_cycle);
++ dev_dbg(pwm->chip.dev, "polarity:%d\n", state->polarity);
++ dev_dbg(pwm->chip.dev, "enabled:%d\n", state->enabled);
++
++ /* duty_cycle should be less or equal than period */
++ if (state->duty_cycle > state->period)
++ return -EINVAL;
++
++ /* calculate pwm real period (ns) */
++ pwm_clk_ns = NS_1 / clk_get_rate(pwm->clk);
++
++ dev_dbg(pwm->chip.dev, "pwm_clk_ns:%u\n", pwm_clk_ns);
++
++ /* calculate period count */
++ period_data = div_u64(state->period, pwm_clk_ns);
++
++ if (!state->enabled)
++ /* if disabled, just set duty_data to 0, which means low level always */
++ duty_data = 0;
++ else
++ /* calculate duty count */
++ duty_data = div_u64(state->duty_cycle, pwm_clk_ns);
++
++ dev_dbg(pwm->chip.dev, "period_data:%u, duty_data:%u\n",
++ period_data, duty_data);
++
++ if (state->polarity == PWM_POLARITY_NORMAL)
++ /* calculate data_hrc */
++ data_hrc = period_data - duty_data;
++ else
++ /* calculate data_hrc */
++ data_hrc = duty_data;
++
++ data_lrc = period_data;
++
++ /* set hrc */
++ reg_addr = REG_PTC_RPTC_HRC(pwm->regs, dev->hwpwm);
++ dev_dbg(pwm->chip.dev, "%s: reg_addr:%p, data:%u\n",
++ __func__, reg_addr, data_hrc);
++
++ iowrite32(data_hrc, reg_addr);
++
++ dev_dbg(pwm->chip.dev, "%s: hrc ok\n", __func__);
++
++ /* set lrc */
++ reg_addr = REG_PTC_RPTC_LRC(pwm->regs, dev->hwpwm);
++ dev_dbg(pwm->chip.dev, "%s: reg_addr:%p, data:%u\n",
++ __func__, reg_addr, data_lrc);
++
++ iowrite32(data_lrc, reg_addr);
++ dev_dbg(pwm->chip.dev, "%s: lrc ok\n", __func__);
++
++ /* Clear REG_RPTC_CNTR after setting period & duty_cycle */
++ reg_addr = REG_PTC_RPTC_CNTR(pwm->regs, dev->hwpwm);
++ iowrite32(0, reg_addr);
++ return 0;
++}
++
++static const struct pwm_ops sifive_pwm_ptc_ops = {
++ .get_state = sifive_pwm_ptc_get_state,
++ .apply = sifive_pwm_ptc_apply,
++ .owner = THIS_MODULE,
++};
++
++static void sifive_pwm_ptc_disable_action(void *data)
++{
++ clk_disable_unprepare(data);
++}
++
++static int sifive_pwm_ptc_probe(struct platform_device *pdev)
++{
++ struct device *dev = &pdev->dev;
++ struct device_node *node = pdev->dev.of_node;
++ struct sifive_pwm_ptc_device *pwm;
++ struct pwm_chip *chip;
++ struct reset_control *rst;
++ int ret;
++
++ pwm = devm_kzalloc(dev, sizeof(*pwm), GFP_KERNEL);
++ if (!pwm)
++ return -ENOMEM;
++
++ platform_set_drvdata(pdev, pwm);
++
++ chip = &pwm->chip;
++ chip->dev = dev;
++ chip->ops = &sifive_pwm_ptc_ops;
++
++ /* how many parameters can be transferred to ptc, need to fix */
++ chip->of_pwm_n_cells = 3;
++ chip->base = -1;
++
++ /* get pwm channels count, max value is 8 */
++ ret = of_property_read_u32(node, "starfive,npwm", &chip->npwm);
++ if (ret < 0 || chip->npwm > MAX_PWM)
++ chip->npwm = MAX_PWM;
++
++ dev_dbg(dev, "%s: npwm:0x%x\n", __func__, chip->npwm);
++
++ /* get IO base address */
++ pwm->regs = devm_platform_ioremap_resource(pdev, 0);
++ if (IS_ERR(pwm->regs))
++ return dev_err_probe(dev, PTR_ERR(pwm->regs),
++ "Unable to map IO resources\n");
++
++ pwm->clk = devm_clk_get(dev, NULL);
++ if (IS_ERR(pwm->clk))
++ return dev_err_probe(dev, PTR_ERR(pwm->clk),
++ "Unable to get controller clock\n");
++
++ ret = clk_prepare_enable(pwm->clk);
++ if (ret)
++ return dev_err_probe(dev, ret, "Unable to enable clock\n");
++
++ ret = devm_add_action_or_reset(dev, sifive_pwm_ptc_disable_action, pwm->clk);
++ if (ret)
++ return ret;
++
++ rst = devm_reset_control_get_exclusive(dev, NULL);
++ if (IS_ERR(rst))
++ return dev_err_probe(dev, PTR_ERR(rst), "Unable to get reset\n");
++
++ ret = reset_control_deassert(rst);
++ if (ret)
++ return dev_err_probe(dev, ret, "Unable to deassert reset\n");
++
++ /*
++ * after pwmchip_add it will show up as /sys/class/pwm/pwmchip0,
++ * 0 is chip->base, pwm0 can be seen after running echo 0 > export
++ */
++ ret = devm_pwmchip_add(dev, chip);
++ if (ret)
++ return dev_err_probe(dev, ret, "cannot register PTC: %d\n", ret);
++
++ dev_dbg(dev, "SiFive PWM PTC chip registered %d PWMs\n", chip->npwm);
++ return 0;
++}
++
++static const struct of_device_id sifive_pwm_ptc_of_match[] = {
++ { .compatible = "starfive,pwm0" },
++ { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, sifive_pwm_ptc_of_match);
++
++static struct platform_driver sifive_pwm_ptc_driver = {
++ .probe = sifive_pwm_ptc_probe,
++ .driver = {
++ .name = "pwm-sifive-ptc",
++ .of_match_table = sifive_pwm_ptc_of_match,
++ },
++};
++module_platform_driver(sifive_pwm_ptc_driver);
++
++MODULE_DESCRIPTION("SiFive PWM PTC driver");
++MODULE_LICENSE("GPL v2");
diff --git a/target/linux/starfive/patches-6.6/1012-dt-bindings-reset-Add-StarFive-JH7100-audio-reset-de.patch b/target/linux/starfive/patches-6.6/1012-dt-bindings-reset-Add-StarFive-JH7100-audio-reset-de.patch
new file mode 100644
index 0000000000..6986d4b1cd
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/1012-dt-bindings-reset-Add-StarFive-JH7100-audio-reset-de.patch
@@ -0,0 +1,48 @@
+From 4f3335c302b7f944b61f564095505b3c7a1b62ee Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <kernel@esmil.dk>
+Date: Sat, 20 Nov 2021 19:29:25 +0100
+Subject: [PATCH 1012/1024] dt-bindings: reset: Add StarFive JH7100 audio reset
+ definitions
+
+Add all resets for the StarFive JH7100 audio reset controller.
+
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+---
+ .../dt-bindings/reset/starfive-jh7100-audio.h | 31 +++++++++++++++++++
+ 1 file changed, 31 insertions(+)
+ create mode 100644 include/dt-bindings/reset/starfive-jh7100-audio.h
+
+--- /dev/null
++++ b/include/dt-bindings/reset/starfive-jh7100-audio.h
+@@ -0,0 +1,31 @@
++/* SPDX-License-Identifier: GPL-2.0 OR MIT */
++/*
++ * Copyright (C) 2021 Emil Renner Berthing
++ */
++
++#ifndef __DT_BINDINGS_RESET_STARFIVE_JH7100_AUDIO_H__
++#define __DT_BINDINGS_RESET_STARFIVE_JH7100_AUDIO_H__
++
++#define JH7100_AUDRSTN_APB_BUS 0
++#define JH7100_AUDRSTN_I2SADC_APB 1
++#define JH7100_AUDRSTN_I2SADC_SRST 2
++#define JH7100_AUDRSTN_PDM_APB 3
++#define JH7100_AUDRSTN_I2SVAD_APB 4
++#define JH7100_AUDRSTN_I2SVAD_SRST 5
++#define JH7100_AUDRSTN_SPDIF_APB 6
++#define JH7100_AUDRSTN_PWMDAC_APB 7
++#define JH7100_AUDRSTN_I2SDAC_APB 8
++#define JH7100_AUDRSTN_I2SDAC_SRST 9
++#define JH7100_AUDRSTN_I2S1_APB 10
++#define JH7100_AUDRSTN_I2S1_SRST 11
++#define JH7100_AUDRSTN_I2SDAC16K_APB 12
++#define JH7100_AUDRSTN_I2SDAC16K_SRST 13
++#define JH7100_AUDRSTN_DMA1P_AHB 14
++#define JH7100_AUDRSTN_USB_APB 15
++#define JH7100_AUDRST_USB_AXI 16
++#define JH7100_AUDRST_USB_PWRUP_RST_N 17
++#define JH7100_AUDRST_USB_PONRST 18
++
++#define JH7100_AUDRSTN_END 19
++
++#endif /* __DT_BINDINGS_RESET_STARFIVE_JH7100_AUDIO_H__ */
diff --git a/target/linux/starfive/patches-6.6/1013-dt-bindings-reset-Add-starfive-jh7100-audrst-binding.patch b/target/linux/starfive/patches-6.6/1013-dt-bindings-reset-Add-starfive-jh7100-audrst-binding.patch
new file mode 100644
index 0000000000..5eac29e006
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/1013-dt-bindings-reset-Add-starfive-jh7100-audrst-binding.patch
@@ -0,0 +1,56 @@
+From 1e428568e486b40f78febddf2958ba27289bd49f Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <kernel@esmil.dk>
+Date: Tue, 7 Dec 2021 21:48:51 +0100
+Subject: [PATCH 1013/1024] dt-bindings: reset: Add starfive,jh7100-audrst
+ bindings
+
+Add bindings for the audio reset controller on the StarFive JH7100
+RISC-V SoC.
+
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+---
+ .../reset/starfive,jh7100-audrst.yaml | 38 +++++++++++++++++++
+ 1 file changed, 38 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/reset/starfive,jh7100-audrst.yaml
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/reset/starfive,jh7100-audrst.yaml
+@@ -0,0 +1,38 @@
++# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/reset/starfive,jh7100-audrst.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: StarFive JH7100 SoC Audio Reset Controller Device Tree Bindings
++
++maintainers:
++ - Emil Renner Berthing <kernel@esmil.dk>
++
++properties:
++ compatible:
++ enum:
++ - starfive,jh7100-audrst
++
++ reg:
++ maxItems: 1
++
++ "#reset-cells":
++ const: 1
++
++required:
++ - compatible
++ - reg
++ - "#reset-cells"
++
++additionalProperties: false
++
++examples:
++ - |
++ reset-controller@10490000 {
++ compatible = "starfive,jh7100-audrst";
++ reg = <0x10490000 0x10000>;
++ #reset-cells = <1>;
++ };
++
++...
diff --git a/target/linux/starfive/patches-6.6/1014-reset-starfive-Add-JH7100-audio-reset-driver.patch b/target/linux/starfive/patches-6.6/1014-reset-starfive-Add-JH7100-audio-reset-driver.patch
new file mode 100644
index 0000000000..bc33188a44
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/1014-reset-starfive-Add-JH7100-audio-reset-driver.patch
@@ -0,0 +1,144 @@
+From 91559ced47de9e6fb1e6dd65a5544fcc86dea806 Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <kernel@esmil.dk>
+Date: Sat, 20 Nov 2021 19:30:49 +0100
+Subject: [PATCH 1014/1024] reset: starfive: Add JH7100 audio reset driver
+
+The audio resets are almost identical to the system resets, there are
+just fewer of them. So factor out and export a generic probe function,
+so most of the reset controller implementation can be shared.
+
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+---
+ MAINTAINERS | 2 +-
+ drivers/reset/starfive/Kconfig | 7 ++
+ drivers/reset/starfive/Makefile | 2 +
+ .../starfive/reset-starfive-jh7100-audio.c | 66 +++++++++++++++++++
+ .../reset/starfive/reset-starfive-jh7100.h | 16 +++++
+ 5 files changed, 92 insertions(+), 1 deletion(-)
+ create mode 100644 drivers/reset/starfive/reset-starfive-jh7100-audio.c
+ create mode 100644 drivers/reset/starfive/reset-starfive-jh7100.h
+
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -20554,7 +20554,7 @@ STARFIVE JH71X0 RESET CONTROLLER DRIVERS
+ M: Emil Renner Berthing <kernel@esmil.dk>
+ M: Hal Feng <hal.feng@starfivetech.com>
+ S: Maintained
+-F: Documentation/devicetree/bindings/reset/starfive,jh7100-reset.yaml
++F: Documentation/devicetree/bindings/reset/starfive,jh7100-*.yaml
+ F: drivers/reset/starfive/reset-starfive-jh71*
+ F: include/dt-bindings/reset/starfive?jh71*.h
+
+--- a/drivers/reset/starfive/Kconfig
++++ b/drivers/reset/starfive/Kconfig
+@@ -11,6 +11,13 @@ config RESET_STARFIVE_JH7100
+ help
+ This enables the reset controller driver for the StarFive JH7100 SoC.
+
++config RESET_STARFIVE_JH7100_AUDIO
++ tristate "StarFive JH7100 Audio Reset Driver"
++ depends on RESET_STARFIVE_JH7100
++ default m if SOC_STARFIVE
++ help
++ This enables the audio reset driver for the StarFive JH7100 SoC.
++
+ config RESET_STARFIVE_JH7110
+ bool "StarFive JH7110 Reset Driver"
+ depends on CLK_STARFIVE_JH7110_SYS
+--- a/drivers/reset/starfive/Makefile
++++ b/drivers/reset/starfive/Makefile
+@@ -2,4 +2,6 @@
+ obj-$(CONFIG_RESET_STARFIVE_JH71X0) += reset-starfive-jh71x0.o
+
+ obj-$(CONFIG_RESET_STARFIVE_JH7100) += reset-starfive-jh7100.o
++obj-$(CONFIG_RESET_STARFIVE_JH7100_AUDIO) += reset-starfive-jh7100-audio.o
++
+ obj-$(CONFIG_RESET_STARFIVE_JH7110) += reset-starfive-jh7110.o
+--- /dev/null
++++ b/drivers/reset/starfive/reset-starfive-jh7100-audio.c
+@@ -0,0 +1,66 @@
++// SPDX-License-Identifier: GPL-2.0-or-later
++/*
++ * Audio reset driver for the StarFive JH7100 SoC
++ *
++ * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
++ */
++
++#include <linux/mod_devicetable.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++
++#include "reset-starfive-jh71x0.h"
++
++#include <dt-bindings/reset/starfive-jh7100-audio.h>
++
++/* register offsets */
++#define JH7100_AUDRST_ASSERT0 0x00
++#define JH7100_AUDRST_STATUS0 0x04
++
++/*
++ * Writing a 1 to the n'th bit of the ASSERT register asserts
++ * line n, and writing a 0 deasserts the same line.
++ * Most reset lines have their status inverted so a 0 bit in the STATUS
++ * register means the line is asserted and a 1 means it's deasserted. A few
++ * lines don't though, so store the expected value of the status registers when
++ * all lines are asserted.
++ */
++static const u32 jh7100_audrst_asserted[1] = {
++ BIT(JH7100_AUDRST_USB_AXI) |
++ BIT(JH7100_AUDRST_USB_PWRUP_RST_N) |
++ BIT(JH7100_AUDRST_USB_PONRST)
++};
++
++static int jh7100_audrst_probe(struct platform_device *pdev)
++{
++ void __iomem *base = devm_platform_ioremap_resource(pdev, 0);
++
++ if (IS_ERR(base))
++ return PTR_ERR(base);
++
++ return reset_starfive_jh71x0_register(&pdev->dev, pdev->dev.of_node,
++ base + JH7100_AUDRST_ASSERT0,
++ base + JH7100_AUDRST_STATUS0,
++ jh7100_audrst_asserted,
++ JH7100_AUDRSTN_END,
++ THIS_MODULE);
++}
++
++static const struct of_device_id jh7100_audrst_dt_ids[] = {
++ { .compatible = "starfive,jh7100-audrst" },
++ { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, jh7100_audrst_dt_ids);
++
++static struct platform_driver jh7100_audrst_driver = {
++ .probe = jh7100_audrst_probe,
++ .driver = {
++ .name = "jh7100-reset-audio",
++ .of_match_table = jh7100_audrst_dt_ids,
++ },
++};
++module_platform_driver(jh7100_audrst_driver);
++
++MODULE_AUTHOR("Emil Renner Berthing");
++MODULE_DESCRIPTION("StarFive JH7100 audio reset driver");
++MODULE_LICENSE("GPL");
+--- /dev/null
++++ b/drivers/reset/starfive/reset-starfive-jh7100.h
+@@ -0,0 +1,16 @@
++// SPDX-License-Identifier: GPL-2.0-or-later
++/*
++ * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
++ */
++
++#ifndef _RESET_STARFIVE_JH7100_H_
++#define _RESET_STARFIVE_JH7100_H_
++
++#include <linux/platform_device.h>
++
++int reset_starfive_jh7100_generic_probe(struct platform_device *pdev,
++ const u32 *asserted,
++ unsigned int status_offset,
++ unsigned int nr_resets);
++
++#endif
diff --git a/target/linux/starfive/patches-6.6/1015-RISC-V-Add-StarFive-JH7100-audio-reset-node.patch b/target/linux/starfive/patches-6.6/1015-RISC-V-Add-StarFive-JH7100-audio-reset-node.patch
new file mode 100644
index 0000000000..521144c9f0
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/1015-RISC-V-Add-StarFive-JH7100-audio-reset-node.patch
@@ -0,0 +1,28 @@
+From 418603fdce51212d4547aacfe2b4801fc5e61978 Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <kernel@esmil.dk>
+Date: Sat, 20 Nov 2021 21:33:08 +0100
+Subject: [PATCH 1015/1024] RISC-V: Add StarFive JH7100 audio reset node
+
+Add device tree node for the audio resets on the StarFive JH7100 RISC-V
+SoC.
+
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+---
+ arch/riscv/boot/dts/starfive/jh7100.dtsi | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/arch/riscv/boot/dts/starfive/jh7100.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7100.dtsi
+@@ -168,6 +168,12 @@
+ #clock-cells = <1>;
+ };
+
++ audrst: reset-controller@10490000 {
++ compatible = "starfive,jh7100-audrst";
++ reg = <0x0 0x10490000 0x0 0x10000>;
++ #reset-cells = <1>;
++ };
++
+ clkgen: clock-controller@11800000 {
+ compatible = "starfive,jh7100-clkgen";
+ reg = <0x0 0x11800000 0x0 0x10000>;
diff --git a/target/linux/starfive/patches-6.6/1016-soc-sifive-ccache-Add-StarFive-JH7100-support.patch b/target/linux/starfive/patches-6.6/1016-soc-sifive-ccache-Add-StarFive-JH7100-support.patch
new file mode 100644
index 0000000000..2906e1605c
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/1016-soc-sifive-ccache-Add-StarFive-JH7100-support.patch
@@ -0,0 +1,160 @@
+From 8e090d271683d5869cdab0729f54a8af8c79c476 Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <kernel@esmil.dk>
+Date: Tue, 31 Oct 2023 15:14:44 +0100
+Subject: [PATCH 1016/1024] soc: sifive: ccache: Add StarFive JH7100 support
+
+This adds support for the StarFive JH7100 SoC which also features this
+SiFive cache controller.
+
+The JH7100 has non-coherent DMAs but predate the standard RISC-V Zicbom
+exension, so instead we need to use this cache controller for
+non-standard cache management operations.
+
+Unfortunately the interrupt for uncorrected data is broken on the JH7100
+and fires continuously, so add a quirk to not register a handler for it.
+
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
+---
+ drivers/soc/sifive/sifive_ccache.c | 62 +++++++++++++++++++++++++++++-
+ 1 file changed, 60 insertions(+), 2 deletions(-)
+
+--- a/drivers/soc/sifive/sifive_ccache.c
++++ b/drivers/soc/sifive/sifive_ccache.c
+@@ -8,13 +8,16 @@
+
+ #define pr_fmt(fmt) "CCACHE: " fmt
+
++#include <linux/align.h>
+ #include <linux/debugfs.h>
+ #include <linux/interrupt.h>
+ #include <linux/of_irq.h>
+ #include <linux/of_address.h>
+ #include <linux/device.h>
+ #include <linux/bitfield.h>
++#include <asm/cacheflush.h>
+ #include <asm/cacheinfo.h>
++#include <asm/dma-noncoherent.h>
+ #include <soc/sifive/sifive_ccache.h>
+
+ #define SIFIVE_CCACHE_DIRECCFIX_LOW 0x100
+@@ -39,10 +42,14 @@
+ #define SIFIVE_CCACHE_CONFIG_SETS_MASK GENMASK_ULL(23, 16)
+ #define SIFIVE_CCACHE_CONFIG_BLKS_MASK GENMASK_ULL(31, 24)
+
++#define SIFIVE_CCACHE_FLUSH64 0x200
++#define SIFIVE_CCACHE_FLUSH32 0x240
++
+ #define SIFIVE_CCACHE_WAYENABLE 0x08
+ #define SIFIVE_CCACHE_ECCINJECTERR 0x40
+
+ #define SIFIVE_CCACHE_MAX_ECCINTR 4
++#define SIFIVE_CCACHE_LINE_SIZE 64
+
+ static void __iomem *ccache_base;
+ static int g_irq[SIFIVE_CCACHE_MAX_ECCINTR];
+@@ -56,6 +63,11 @@ enum {
+ DIR_UNCORR,
+ };
+
++enum {
++ QUIRK_NONSTANDARD_CACHE_OPS = BIT(0),
++ QUIRK_BROKEN_DATA_UNCORR = BIT(1),
++};
++
+ #ifdef CONFIG_DEBUG_FS
+ static struct dentry *sifive_test;
+
+@@ -106,6 +118,8 @@ static void ccache_config_read(void)
+ static const struct of_device_id sifive_ccache_ids[] = {
+ { .compatible = "sifive,fu540-c000-ccache" },
+ { .compatible = "sifive,fu740-c000-ccache" },
++ { .compatible = "starfive,jh7100-ccache",
++ .data = (void *)(QUIRK_NONSTANDARD_CACHE_OPS | QUIRK_BROKEN_DATA_UNCORR) },
+ { .compatible = "sifive,ccache0" },
+ { /* end of table */ }
+ };
+@@ -124,6 +138,34 @@ int unregister_sifive_ccache_error_notif
+ }
+ EXPORT_SYMBOL_GPL(unregister_sifive_ccache_error_notifier);
+
++#ifdef CONFIG_RISCV_NONSTANDARD_CACHE_OPS
++static void ccache_flush_range(phys_addr_t start, size_t len)
++{
++ phys_addr_t end = start + len;
++ phys_addr_t line;
++
++ if (!len)
++ return;
++
++ mb();
++ for (line = ALIGN_DOWN(start, SIFIVE_CCACHE_LINE_SIZE); line < end;
++ line += SIFIVE_CCACHE_LINE_SIZE) {
++#ifdef CONFIG_32BIT
++ writel(line >> 4, ccache_base + SIFIVE_CCACHE_FLUSH32);
++#else
++ writeq(line, ccache_base + SIFIVE_CCACHE_FLUSH64);
++#endif
++ mb();
++ }
++}
++
++static const struct riscv_nonstd_cache_ops ccache_mgmt_ops __initconst = {
++ .wback = &ccache_flush_range,
++ .inv = &ccache_flush_range,
++ .wback_inv = &ccache_flush_range,
++};
++#endif /* CONFIG_RISCV_NONSTANDARD_CACHE_OPS */
++
+ static int ccache_largest_wayenabled(void)
+ {
+ return readl(ccache_base + SIFIVE_CCACHE_WAYENABLE) & 0xFF;
+@@ -210,11 +252,15 @@ static int __init sifive_ccache_init(voi
+ struct device_node *np;
+ struct resource res;
+ int i, rc, intr_num;
++ const struct of_device_id *match;
++ unsigned long quirks;
+
+- np = of_find_matching_node(NULL, sifive_ccache_ids);
++ np = of_find_matching_node_and_match(NULL, sifive_ccache_ids, &match);
+ if (!np)
+ return -ENODEV;
+
++ quirks = (uintptr_t)match->data;
++
+ if (of_address_to_resource(np, 0, &res)) {
+ rc = -ENODEV;
+ goto err_node_put;
+@@ -240,6 +286,10 @@ static int __init sifive_ccache_init(voi
+
+ for (i = 0; i < intr_num; i++) {
+ g_irq[i] = irq_of_parse_and_map(np, i);
++
++ if (i == DATA_UNCORR && (quirks & QUIRK_BROKEN_DATA_UNCORR))
++ continue;
++
+ rc = request_irq(g_irq[i], ccache_int_handler, 0, "ccache_ecc",
+ NULL);
+ if (rc) {
+@@ -249,6 +299,14 @@ static int __init sifive_ccache_init(voi
+ }
+ of_node_put(np);
+
++#ifdef CONFIG_RISCV_NONSTANDARD_CACHE_OPS
++ if (quirks & QUIRK_NONSTANDARD_CACHE_OPS) {
++ riscv_cbom_block_size = SIFIVE_CCACHE_LINE_SIZE;
++ riscv_noncoherent_supported();
++ riscv_noncoherent_register_cache_ops(&ccache_mgmt_ops);
++ }
++#endif
++
+ ccache_config_read();
+
+ ccache_cache_ops.get_priv_group = ccache_get_priv_group;
+@@ -269,4 +327,4 @@ err_node_put:
+ return rc;
+ }
+
+-device_initcall(sifive_ccache_init);
++arch_initcall(sifive_ccache_init);
diff --git a/target/linux/starfive/patches-6.6/1017-riscv-errata-Add-StarFive-JH7100-errata.patch b/target/linux/starfive/patches-6.6/1017-riscv-errata-Add-StarFive-JH7100-errata.patch
new file mode 100644
index 0000000000..91b3adfac1
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/1017-riscv-errata-Add-StarFive-JH7100-errata.patch
@@ -0,0 +1,44 @@
+From 30fb5963f4cf3b7d114a8212358147615480685c Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <emil.renner.berthing@canonical.com>
+Date: Thu, 30 Nov 2023 16:19:25 +0100
+Subject: [PATCH 1017/1024] riscv: errata: Add StarFive JH7100 errata
+
+This not really an errata, but since the JH7100 was made before
+the standard Zicbom extension it needs the DMA_GLOBAL_POOL and
+RISCV_NONSTANDARD_CACHE_OPS enabled to work correctly.
+
+Acked-by: Conor Dooley <conor.dooley@microchip.com>
+Signed-off-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
+Reviewed-by: Palmer Dabbelt <palmer@rivosinc.com>
+Acked-by: Palmer Dabbelt <palmer@rivosinc.com>
+Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
+---
+ arch/riscv/Kconfig.errata | 17 +++++++++++++++++
+ 1 file changed, 17 insertions(+)
+
+--- a/arch/riscv/Kconfig.errata
++++ b/arch/riscv/Kconfig.errata
+@@ -53,6 +53,23 @@ config ERRATA_SIFIVE_CIP_1200
+
+ If you don't know what to do here, say "Y".
+
++config ERRATA_STARFIVE_JH7100
++ bool "StarFive JH7100 support"
++ depends on ARCH_STARFIVE && NONPORTABLE
++ select DMA_GLOBAL_POOL
++ select RISCV_DMA_NONCOHERENT
++ select RISCV_NONSTANDARD_CACHE_OPS
++ select SIFIVE_CCACHE
++ default n
++ help
++ The StarFive JH7100 was a test chip for the JH7110 and has
++ caches that are non-coherent with respect to peripheral DMAs.
++ It was designed before the Zicbom extension so needs non-standard
++ cache operations through the SiFive cache controller.
++
++ Say "Y" if you want to support the BeagleV Starlight and/or
++ StarFive VisionFive V1 boards.
++
+ config ERRATA_THEAD
+ bool "T-HEAD errata"
+ depends on RISCV_ALTERNATIVE
diff --git a/target/linux/starfive/patches-6.6/1018-riscv-dts-starfive-Mark-the-JH7100-as-having-non-coh.patch b/target/linux/starfive/patches-6.6/1018-riscv-dts-starfive-Mark-the-JH7100-as-having-non-coh.patch
new file mode 100644
index 0000000000..0b223c5925
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/1018-riscv-dts-starfive-Mark-the-JH7100-as-having-non-coh.patch
@@ -0,0 +1,26 @@
+From 29e4bc0fafd9add93acc967f3992948b3afe7176 Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <kernel@esmil.dk>
+Date: Thu, 30 Nov 2023 16:19:27 +0100
+Subject: [PATCH 1018/1024] riscv: dts: starfive: Mark the JH7100 as having
+ non-coherent DMAs
+
+The StarFive JH7100 SoC has non-coherent device DMAs, so mark the
+soc bus as such.
+
+Link: https://github.com/starfive-tech/JH7100_Docs/blob/main/JH7100%20Cache%20Coherence%20V1.0.pdf
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
+---
+ arch/riscv/boot/dts/starfive/jh7100.dtsi | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/arch/riscv/boot/dts/starfive/jh7100.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7100.dtsi
+@@ -138,6 +138,7 @@
+ interrupt-parent = <&plic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
++ dma-noncoherent;
+ ranges;
+
+ clint: clint@2000000 {
diff --git a/target/linux/starfive/patches-6.6/1019-riscv-dts-starfive-Add-JH7100-cache-controller.patch b/target/linux/starfive/patches-6.6/1019-riscv-dts-starfive-Add-JH7100-cache-controller.patch
new file mode 100644
index 0000000000..cdc63fac65
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/1019-riscv-dts-starfive-Add-JH7100-cache-controller.patch
@@ -0,0 +1,50 @@
+From e1918356dcc285eb7c50f271795e6fcc18d6c092 Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <emil.renner.berthing@canonical.com>
+Date: Thu, 30 Nov 2023 16:19:28 +0100
+Subject: [PATCH 1019/1024] riscv: dts: starfive: Add JH7100 cache controller
+
+The StarFive JH7100 SoC also features the SiFive L2 cache controller,
+so add the device tree nodes for it.
+
+Signed-off-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
+Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
+---
+ arch/riscv/boot/dts/starfive/jh7100.dtsi | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+--- a/arch/riscv/boot/dts/starfive/jh7100.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7100.dtsi
+@@ -32,6 +32,7 @@
+ i-tlb-sets = <1>;
+ i-tlb-size = <32>;
+ mmu-type = "riscv,sv39";
++ next-level-cache = <&ccache>;
+ riscv,isa = "rv64imafdc";
+ tlb-split;
+
+@@ -57,6 +58,7 @@
+ i-tlb-sets = <1>;
+ i-tlb-size = <32>;
+ mmu-type = "riscv,sv39";
++ next-level-cache = <&ccache>;
+ riscv,isa = "rv64imafdc";
+ tlb-split;
+
+@@ -148,6 +150,17 @@
+ &cpu1_intc 3 &cpu1_intc 7>;
+ };
+
++ ccache: cache-controller@2010000 {
++ compatible = "starfive,jh7100-ccache", "sifive,ccache0", "cache";
++ reg = <0x0 0x2010000 0x0 0x1000>;
++ interrupts = <128>, <130>, <131>, <129>;
++ cache-block-size = <64>;
++ cache-level = <2>;
++ cache-sets = <2048>;
++ cache-size = <2097152>;
++ cache-unified;
++ };
++
+ plic: interrupt-controller@c000000 {
+ compatible = "starfive,jh7100-plic", "sifive,plic-1.0.0";
+ reg = <0x0 0xc000000 0x0 0x4000000>;
diff --git a/target/linux/starfive/patches-6.6/1020-riscv-dts-starfive-Add-pool-for-coherent-DMA-memory-.patch b/target/linux/starfive/patches-6.6/1020-riscv-dts-starfive-Add-pool-for-coherent-DMA-memory-.patch
new file mode 100644
index 0000000000..c9ba3884f6
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/1020-riscv-dts-starfive-Add-pool-for-coherent-DMA-memory-.patch
@@ -0,0 +1,61 @@
+From 3cbd661b811bda9a33253f65b5cf0c25b8c5447f Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <emil.renner.berthing@canonical.com>
+Date: Thu, 30 Nov 2023 16:19:29 +0100
+Subject: [PATCH 1020/1024] riscv: dts: starfive: Add pool for coherent DMA
+ memory on JH7100 boards
+
+The StarFive JH7100 SoC has non-coherent device DMAs, but most drivers
+expect to be able to allocate coherent memory for DMA descriptors and
+such. However on the JH7100 DDR memory appears twice in the physical
+memory map, once cached and once uncached:
+
+ 0x00_8000_0000 - 0x08_7fff_ffff : Off chip DDR memory, cached
+ 0x10_0000_0000 - 0x17_ffff_ffff : Off chip DDR memory, uncached
+
+To use this uncached region we create a global DMA memory pool there and
+reserve the corresponding area in the cached region.
+
+However the uncached region is fully above the 32bit address limit, so add
+a dma-ranges map so the DMA address used for peripherals is still in the
+regular cached region below the limit.
+
+Link: https://github.com/starfive-tech/JH7100_Docs/blob/main/JH7100%20Data%20Sheet%20V01.01.04-EN%20(4-21-2021).pdf
+Signed-off-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
+Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
+---
+ .../boot/dts/starfive/jh7100-common.dtsi | 24 +++++++++++++++++++
+ 1 file changed, 24 insertions(+)
+
+--- a/arch/riscv/boot/dts/starfive/jh7100-common.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7100-common.dtsi
+@@ -39,6 +39,30 @@
+ label = "ack";
+ };
+ };
++
++ reserved-memory {
++ #address-cells = <2>;
++ #size-cells = <2>;
++ ranges;
++
++ dma-reserved@fa000000 {
++ reg = <0x0 0xfa000000 0x0 0x1000000>;
++ no-map;
++ };
++
++ linux,dma@107a000000 {
++ compatible = "shared-dma-pool";
++ reg = <0x10 0x7a000000 0x0 0x1000000>;
++ no-map;
++ linux,dma-default;
++ };
++ };
++
++ soc {
++ dma-ranges = <0x00 0x80000000 0x00 0x80000000 0x00 0x7a000000>,
++ <0x00 0xfa000000 0x10 0x7a000000 0x00 0x01000000>,
++ <0x00 0xfb000000 0x00 0xfb000000 0x07 0x85000000>;
++ };
+ };
+
+ &gpio {
diff --git a/target/linux/starfive/patches-6.6/1021-riscv-dts-starfive-Add-JH7100-MMC-nodes.patch b/target/linux/starfive/patches-6.6/1021-riscv-dts-starfive-Add-JH7100-MMC-nodes.patch
new file mode 100644
index 0000000000..fb3ba521c9
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/1021-riscv-dts-starfive-Add-JH7100-MMC-nodes.patch
@@ -0,0 +1,49 @@
+From 7be159c760aa8a1ece1354892af215b2f8c21152 Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <emil.renner.berthing@canonical.com>
+Date: Thu, 30 Nov 2023 16:19:30 +0100
+Subject: [PATCH 1021/1024] riscv: dts: starfive: Add JH7100 MMC nodes
+
+Add device tree nodes for the Synopsis MMC controllers on the
+StarFive JH7100 SoC.
+
+Signed-off-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
+Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
+---
+ arch/riscv/boot/dts/starfive/jh7100.dtsi | 26 ++++++++++++++++++++++++
+ 1 file changed, 26 insertions(+)
+
+--- a/arch/riscv/boot/dts/starfive/jh7100.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7100.dtsi
+@@ -188,6 +188,32 @@
+ #reset-cells = <1>;
+ };
+
++ sdio0: mmc@10000000 {
++ compatible = "snps,dw-mshc";
++ reg = <0x0 0x10000000 0x0 0x10000>;
++ clocks = <&clkgen JH7100_CLK_SDIO0_AHB>,
++ <&clkgen JH7100_CLK_SDIO0_CCLKINT_INV>;
++ clock-names = "biu", "ciu";
++ interrupts = <4>;
++ data-addr = <0>;
++ fifo-depth = <32>;
++ fifo-watermark-aligned;
++ status = "disabled";
++ };
++
++ sdio1: mmc@10010000 {
++ compatible = "snps,dw-mshc";
++ reg = <0x0 0x10010000 0x0 0x10000>;
++ clocks = <&clkgen JH7100_CLK_SDIO1_AHB>,
++ <&clkgen JH7100_CLK_SDIO1_CCLKINT_INV>;
++ clock-names = "biu", "ciu";
++ interrupts = <5>;
++ data-addr = <0>;
++ fifo-depth = <32>;
++ fifo-watermark-aligned;
++ status = "disabled";
++ };
++
+ clkgen: clock-controller@11800000 {
+ compatible = "starfive,jh7100-clkgen";
+ reg = <0x0 0x11800000 0x0 0x10000>;
diff --git a/target/linux/starfive/patches-6.6/1022-riscv-dts-starfive-Enable-SD-card-on-JH7100-boards.patch b/target/linux/starfive/patches-6.6/1022-riscv-dts-starfive-Enable-SD-card-on-JH7100-boards.patch
new file mode 100644
index 0000000000..bf380eb833
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/1022-riscv-dts-starfive-Enable-SD-card-on-JH7100-boards.patch
@@ -0,0 +1,85 @@
+From 015edaccef82200d913d5f1e99fd95641f526bc6 Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <emil.renner.berthing@canonical.com>
+Date: Thu, 30 Nov 2023 16:19:31 +0100
+Subject: [PATCH 1022/1024] riscv: dts: starfive: Enable SD-card on JH7100
+ boards
+
+Add pinctrl and MMC device tree nodes for the SD-card on the
+BeagleV Starlight and StarFive VisionFive V1 boards.
+
+Signed-off-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
+Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
+---
+ .../boot/dts/starfive/jh7100-common.dtsi | 47 +++++++++++++++++++
+ 1 file changed, 47 insertions(+)
+
+--- a/arch/riscv/boot/dts/starfive/jh7100-common.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7100-common.dtsi
+@@ -12,6 +12,7 @@
+
+ / {
+ aliases {
++ mmc0 = &sdio0;
+ serial0 = &uart3;
+ };
+
+@@ -108,6 +109,43 @@
+ };
+ };
+
++ sdio0_pins: sdio0-0 {
++ clk-pins {
++ pinmux = <GPIOMUX(54, GPO_SDIO0_PAD_CCLK_OUT,
++ GPO_ENABLE, GPI_NONE)>;
++ bias-disable;
++ input-disable;
++ input-schmitt-disable;
++ };
++ sdio-pins {
++ pinmux = <GPIOMUX(55, GPO_LOW, GPO_DISABLE,
++ GPI_SDIO0_PAD_CARD_DETECT_N)>,
++ <GPIOMUX(53,
++ GPO_SDIO0_PAD_CCMD_OUT,
++ GPO_SDIO0_PAD_CCMD_OEN,
++ GPI_SDIO0_PAD_CCMD_IN)>,
++ <GPIOMUX(49,
++ GPO_SDIO0_PAD_CDATA_OUT_BIT0,
++ GPO_SDIO0_PAD_CDATA_OEN_BIT0,
++ GPI_SDIO0_PAD_CDATA_IN_BIT0)>,
++ <GPIOMUX(50,
++ GPO_SDIO0_PAD_CDATA_OUT_BIT1,
++ GPO_SDIO0_PAD_CDATA_OEN_BIT1,
++ GPI_SDIO0_PAD_CDATA_IN_BIT1)>,
++ <GPIOMUX(51,
++ GPO_SDIO0_PAD_CDATA_OUT_BIT2,
++ GPO_SDIO0_PAD_CDATA_OEN_BIT2,
++ GPI_SDIO0_PAD_CDATA_IN_BIT2)>,
++ <GPIOMUX(52,
++ GPO_SDIO0_PAD_CDATA_OUT_BIT3,
++ GPO_SDIO0_PAD_CDATA_OEN_BIT3,
++ GPI_SDIO0_PAD_CDATA_IN_BIT3)>;
++ bias-pull-up;
++ input-enable;
++ input-schmitt-enable;
++ };
++ };
++
+ uart3_pins: uart3-0 {
+ rx-pins {
+ pinmux = <GPIOMUX(13, GPO_LOW, GPO_DISABLE,
+@@ -178,6 +216,15 @@
+ clock-frequency = <27000000>;
+ };
+
++&sdio0 {
++ broken-cd;
++ bus-width = <4>;
++ cap-sd-highspeed;
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdio0_pins>;
++ status = "okay";
++};
++
+ &uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart3_pins>;
diff --git a/target/linux/starfive/patches-6.6/1023-riscv-errata-Make-ERRATA_STARFIVE_JH7100-depend-on-D.patch b/target/linux/starfive/patches-6.6/1023-riscv-errata-Make-ERRATA_STARFIVE_JH7100-depend-on-D.patch
new file mode 100644
index 0000000000..2b782e1129
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/1023-riscv-errata-Make-ERRATA_STARFIVE_JH7100-depend-on-D.patch
@@ -0,0 +1,33 @@
+From 1e70a0772165dd552f82434c9072dabfaaaf4c2a Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <emil.renner.berthing@canonical.com>
+Date: Fri, 15 Dec 2023 20:09:09 +0100
+Subject: [PATCH 1023/1024] riscv: errata: Make ERRATA_STARFIVE_JH7100 depend
+ on !DMA_DIRECT_REMAP
+
+Similar to the Renesas RZ/Five[1] the JH7100 SoC needs the non-portable
+CONFIG_DMA_GLOBAL_POOL enabled which is incompatible with DMA_DIRECT_REMAP
+selected by RISCV_ISA_ZICBOM.
+
+[1]: commit 31b2daea0764 ("soc: renesas: Make RZ/Five depend on !DMA_DIRECT_REMAP")
+
+Link: https://lore.kernel.org/all/24942b4d-d16a-463f-b39a-f9dfcb89d742@infradead.org/
+Fixes: 64fc984a8a54 ("riscv: errata: Add StarFive JH7100 errata")
+Signed-off-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
+Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
+---
+ arch/riscv/Kconfig.errata | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/arch/riscv/Kconfig.errata
++++ b/arch/riscv/Kconfig.errata
+@@ -55,7 +55,9 @@ config ERRATA_SIFIVE_CIP_1200
+
+ config ERRATA_STARFIVE_JH7100
+ bool "StarFive JH7100 support"
+- depends on ARCH_STARFIVE && NONPORTABLE
++ depends on ARCH_STARFIVE
++ depends on !DMA_DIRECT_REMAP
++ depends on NONPORTABLE
+ select DMA_GLOBAL_POOL
+ select RISCV_DMA_NONCOHERENT
+ select RISCV_NONSTANDARD_CACHE_OPS
diff --git a/target/linux/starfive/patches-6.6/1024-riscv-dts-Add-full-JH7100-Starlight-and-VisionFive-s.patch b/target/linux/starfive/patches-6.6/1024-riscv-dts-Add-full-JH7100-Starlight-and-VisionFive-s.patch
new file mode 100644
index 0000000000..b20c2d8bf5
--- /dev/null
+++ b/target/linux/starfive/patches-6.6/1024-riscv-dts-Add-full-JH7100-Starlight-and-VisionFive-s.patch
@@ -0,0 +1,1138 @@
+From 782f99cc437d975c9ef5a1f351bb8fb83d50039b Mon Sep 17 00:00:00 2001
+From: Emil Renner Berthing <kernel@esmil.dk>
+Date: Sun, 1 Sep 2024 12:43:01 +0000
+Subject: [PATCH 1024/1024] riscv: dts: Add full JH7100, Starlight and
+ VisionFive support
+
+Based on the device tree in https://github.com/starfive-tech/u-boot/
+with contributions from:
+yanhong.wang <yanhong.wang@starfivetech.com>
+Huan.Feng <huan.feng@starfivetech.com>
+ke.zhu <ke.zhu@starfivetech.com>
+yiming.li <yiming.li@starfivetech.com>
+jack.zhu <jack.zhu@starfivetech.com>
+Samin Guo <samin.guo@starfivetech.com>
+Chenjieqin <Jessica.Chen@starfivetech.com>
+bo.li <bo.li@starfivetech.com>
+
+Rearranged, cleanups, fixes, pins and resets added by Emil.
+Cleanups, fixes, clocks added by Geert.
+Cleanups and GPIO fixes from Drew.
+Thermal zone added by Stephen.
+PWM pins added by Jianlong.
+cpu-map added by Jonas.
+
+Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
+Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
+Signed-off-by: Stephen L Arnold <nerdboy@gentoo.org>
+Signed-off-by: Drew Fustini <drew@beagleboard.org>
+Signed-off-by: Jianlong Huang <jianlong.huang@starfivetech.com>
+Signed-off-by: Jonas Hahnfeld <hahnjo@hahnjo.de>
+---
+ .../dts/starfive/jh7100-beaglev-starlight.dts | 16 +
+ .../boot/dts/starfive/jh7100-common.dtsi | 432 +++++++++++++++
+ .../jh7100-starfive-visionfive-v1.dts | 19 +
+ arch/riscv/boot/dts/starfive/jh7100.dtsi | 503 ++++++++++++++++++
+ 4 files changed, 970 insertions(+)
+
+--- a/arch/riscv/boot/dts/starfive/jh7100-beaglev-starlight.dts
++++ b/arch/riscv/boot/dts/starfive/jh7100-beaglev-starlight.dts
+@@ -6,8 +6,24 @@
+
+ /dts-v1/;
+ #include "jh7100-common.dtsi"
++#include <dt-bindings/gpio/gpio.h>
+
+ / {
+ model = "BeagleV Starlight Beta";
+ compatible = "beagle,beaglev-starlight-jh7100-r0", "starfive,jh7100";
+ };
++
++&gmac {
++ snps,reset-gpios = <&gpio 63 GPIO_ACTIVE_LOW>;
++};
++
++&gpio {
++ /* don't reset gpio mux for serial console on uart3 */
++ starfive,keep-gpiomux = <13 14>;
++};
++
++&mdio {
++ phy: ethernet-phy@7 {
++ reg = <7>;
++ };
++};
+--- a/arch/riscv/boot/dts/starfive/jh7100-common.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7100-common.dtsi
+@@ -14,6 +14,7 @@
+ aliases {
+ mmc0 = &sdio0;
+ serial0 = &uart3;
++ serial1 = &uart0;
+ };
+
+ chosen {
+@@ -64,9 +65,174 @@
+ <0x00 0xfa000000 0x10 0x7a000000 0x00 0x01000000>,
+ <0x00 0xfb000000 0x00 0xfb000000 0x07 0x85000000>;
+ };
++
++ reserved-memory {
++ #address-cells = <2>;
++ #size-cells = <2>;
++ ranges;
++
++ linux,cma {
++ compatible = "shared-dma-pool";
++ reusable;
++ size = <0x0 0x28000000>;
++ alignment = <0x0 0x1000>;
++ alloc-ranges = <0x0 0xa0000000 0x0 0x28000000>;
++ linux,cma-default;
++ };
++
++ jpu_reserved: framebuffer@c9000000 {
++ reg = <0x0 0xc9000000 0x0 0x4000000>;
++ };
++
++ nvdla_reserved: framebuffer@d0000000 {
++ no-map;
++ reg = <0x0 0xd0000000 0x0 0x28000000>;
++ };
++
++ vin_reserved: framebuffer@f9000000 {
++ compatible = "shared-dma-pool";
++ no-map;
++ reg = <0x0 0xf9000000 0x0 0x1000000>;
++ };
++
++ sffb_reserved: framebuffer@fb000000 {
++ compatible = "shared-dma-pool";
++ no-map;
++ reg = <0x0 0xfb000000 0x0 0x2000000>;
++ };
++ };
++
++ wifi_pwrseq: wifi-pwrseq {
++ compatible = "mmc-pwrseq-simple";
++ reset-gpios = <&gpio 37 GPIO_ACTIVE_LOW>;
++ };
++};
++
++&display {
++ memory-region = <&sffb_reserved>;
++ status = "okay";
++};
++
++&crtc {
++ ddr-format = <4>; //<WIN_FMT_RGB565>;
++ status = "okay";
++
++ port: port@0 {
++ reg = <0>;
++
++ crtc_0_out: endpoint {
++ remote-endpoint = <&hdmi_input0>;
++ };
++ };
++};
++
++&encoder {
++ encoder-type = <2>; // 2-TMDS, 3-LVDS, 6-DSI, 8-DPI
++ status = "okay";
++
++ ports {
++ port@0 {
++ hdmi_out: endpoint {
++ remote-endpoint = <&tda998x_0_input>;
++ };
++ };
++
++ port@1 {
++ hdmi_input0: endpoint {
++ remote-endpoint = <&crtc_0_out>;
++ };
++ };
++
++ };
++};
++
++&gmac {
++ starfive,gtxclk-dlychain = <4>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&gmac_pins>;
++ phy-mode = "rgmii-txid";
++ phy-handle = <&phy>;
++ status = "okay";
++
++ mdio: mdio {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ compatible = "snps,dwmac-mdio";
++ };
+ };
+
+ &gpio {
++ gmac_pins: gmac-0 {
++ gtxclk-pins {
++ pins = <PAD_FUNC_SHARE(115)>;
++ bias-pull-up;
++ drive-strength = <35>;
++ input-enable;
++ input-schmitt-enable;
++ slew-rate = <0>;
++ };
++ miitxclk-pins {
++ pins = <PAD_FUNC_SHARE(116)>;
++ bias-pull-up;
++ drive-strength = <14>;
++ input-enable;
++ input-schmitt-disable;
++ slew-rate = <0>;
++ };
++ tx-pins {
++ pins = <PAD_FUNC_SHARE(117)>,
++ <PAD_FUNC_SHARE(119)>,
++ <PAD_FUNC_SHARE(120)>,
++ <PAD_FUNC_SHARE(121)>,
++ <PAD_FUNC_SHARE(122)>,
++ <PAD_FUNC_SHARE(123)>,
++ <PAD_FUNC_SHARE(124)>,
++ <PAD_FUNC_SHARE(125)>,
++ <PAD_FUNC_SHARE(126)>;
++ bias-pull-up;
++ drive-strength = <35>;
++ input-disable;
++ input-schmitt-disable;
++ slew-rate = <0>;
++ };
++ rxclk-pins {
++ pins = <PAD_FUNC_SHARE(127)>;
++ bias-pull-up;
++ drive-strength = <14>;
++ input-enable;
++ input-schmitt-disable;
++ slew-rate = <6>;
++ };
++ rxer-pins {
++ pins = <PAD_FUNC_SHARE(129)>;
++ bias-pull-up;
++ drive-strength = <14>;
++ input-enable;
++ input-schmitt-disable;
++ slew-rate = <0>;
++ };
++ rx-pins {
++ pins = <PAD_FUNC_SHARE(128)>,
++ <PAD_FUNC_SHARE(130)>,
++ <PAD_FUNC_SHARE(131)>,
++ <PAD_FUNC_SHARE(132)>,
++ <PAD_FUNC_SHARE(133)>,
++ <PAD_FUNC_SHARE(134)>,
++ <PAD_FUNC_SHARE(135)>,
++ <PAD_FUNC_SHARE(136)>,
++ <PAD_FUNC_SHARE(137)>,
++ <PAD_FUNC_SHARE(138)>,
++ <PAD_FUNC_SHARE(139)>,
++ <PAD_FUNC_SHARE(140)>,
++ <PAD_FUNC_SHARE(141)>;
++ bias-pull-up;
++ drive-strength = <14>;
++ input-enable;
++ input-schmitt-enable;
++ slew-rate = <0>;
++ };
++ };
++
+ i2c0_pins: i2c0-0 {
+ i2c-pins {
+ pinmux = <GPIOMUX(62, GPO_LOW,
+@@ -146,6 +312,166 @@
+ };
+ };
+
++ pwmdac_pins: pwmdac-0 {
++ pwmdac-pins {
++ pinmux = <GPIOMUX(23, GPO_PWMDAC_LEFT_OUT,
++ GPO_ENABLE, GPI_NONE)>,
++ <GPIOMUX(24, GPO_PWMDAC_RIGHT_OUT,
++ GPO_ENABLE, GPI_NONE)>;
++ bias-disable;
++ drive-strength = <35>;
++ input-disable;
++ input-schmitt-disable;
++ slew-rate = <0>;
++ };
++ };
++
++ pwm_pins: pwm-0 {
++ pwm-pins {
++ pinmux = <GPIOMUX(7,
++ GPO_PWM_PAD_OUT_BIT0,
++ GPO_PWM_PAD_OE_N_BIT0,
++ GPI_NONE)>,
++ <GPIOMUX(5,
++ GPO_PWM_PAD_OUT_BIT1,
++ GPO_PWM_PAD_OE_N_BIT1,
++ GPI_NONE)>;
++ bias-disable;
++ drive-strength = <35>;
++ input-disable;
++ input-schmitt-disable;
++ slew-rate = <0>;
++ };
++ };
++
++ sdio0_pins: sdio0-0 {
++ clk-pins {
++ pinmux = <GPIOMUX(54, GPO_SDIO0_PAD_CCLK_OUT,
++ GPO_ENABLE, GPI_NONE)>;
++ bias-disable;
++ input-disable;
++ input-schmitt-disable;
++ };
++ sdio-pins {
++ pinmux = <GPIOMUX(55, GPO_LOW, GPO_DISABLE,
++ GPI_SDIO0_PAD_CARD_DETECT_N)>,
++ <GPIOMUX(53,
++ GPO_SDIO0_PAD_CCMD_OUT,
++ GPO_SDIO0_PAD_CCMD_OEN,
++ GPI_SDIO0_PAD_CCMD_IN)>,
++ <GPIOMUX(49,
++ GPO_SDIO0_PAD_CDATA_OUT_BIT0,
++ GPO_SDIO0_PAD_CDATA_OEN_BIT0,
++ GPI_SDIO0_PAD_CDATA_IN_BIT0)>,
++ <GPIOMUX(50,
++ GPO_SDIO0_PAD_CDATA_OUT_BIT1,
++ GPO_SDIO0_PAD_CDATA_OEN_BIT1,
++ GPI_SDIO0_PAD_CDATA_IN_BIT1)>,
++ <GPIOMUX(51,
++ GPO_SDIO0_PAD_CDATA_OUT_BIT2,
++ GPO_SDIO0_PAD_CDATA_OEN_BIT2,
++ GPI_SDIO0_PAD_CDATA_IN_BIT2)>,
++ <GPIOMUX(52,
++ GPO_SDIO0_PAD_CDATA_OUT_BIT3,
++ GPO_SDIO0_PAD_CDATA_OEN_BIT3,
++ GPI_SDIO0_PAD_CDATA_IN_BIT3)>;
++ bias-pull-up;
++ input-enable;
++ input-schmitt-enable;
++ };
++ };
++
++ sdio1_pins: sdio1-0 {
++ clk-pins {
++ pinmux = <GPIOMUX(33, GPO_SDIO1_PAD_CCLK_OUT,
++ GPO_ENABLE, GPI_NONE)>;
++ bias-disable;
++ input-disable;
++ input-schmitt-disable;
++ };
++ sdio-pins {
++ pinmux = <GPIOMUX(29,
++ GPO_SDIO1_PAD_CCMD_OUT,
++ GPO_SDIO1_PAD_CCMD_OEN,
++ GPI_SDIO1_PAD_CCMD_IN)>,
++ <GPIOMUX(36,
++ GPO_SDIO1_PAD_CDATA_OUT_BIT0,
++ GPO_SDIO1_PAD_CDATA_OEN_BIT0,
++ GPI_SDIO1_PAD_CDATA_IN_BIT0)>,
++ <GPIOMUX(30,
++ GPO_SDIO1_PAD_CDATA_OUT_BIT1,
++ GPO_SDIO1_PAD_CDATA_OEN_BIT1,
++ GPI_SDIO1_PAD_CDATA_IN_BIT1)>,
++ <GPIOMUX(34,
++ GPO_SDIO1_PAD_CDATA_OUT_BIT2,
++ GPO_SDIO1_PAD_CDATA_OEN_BIT2,
++ GPI_SDIO1_PAD_CDATA_IN_BIT2)>,
++ <GPIOMUX(31,
++ GPO_SDIO1_PAD_CDATA_OUT_BIT3,
++ GPO_SDIO1_PAD_CDATA_OEN_BIT3,
++ GPI_SDIO1_PAD_CDATA_IN_BIT3)>;
++ bias-pull-up;
++ input-enable;
++ input-schmitt-enable;
++ };
++ };
++
++ spi2_pins: spi2-0 {
++ mosi-pins {
++ pinmux = <GPIOMUX(18, GPO_SPI2_PAD_TXD,
++ GPO_ENABLE, GPI_NONE)>;
++ bias-disable;
++ input-disable;
++ input-schmitt-disable;
++ };
++ miso-pins {
++ pinmux = <GPIOMUX(16, GPO_LOW, GPO_DISABLE,
++ GPI_SPI2_PAD_RXD)>;
++ bias-pull-up;
++ input-enable;
++ input-schmitt-enable;
++ };
++ sck-pins {
++ pinmux = <GPIOMUX(12, GPO_SPI2_PAD_SCK_OUT,
++ GPO_ENABLE, GPI_NONE)>;
++ bias-disable;
++ input-disable;
++ input-schmitt-disable;
++ };
++ ss-pins {
++ pinmux = <GPIOMUX(15, GPO_SPI2_PAD_SS_0_N,
++ GPO_ENABLE, GPI_NONE)>,
++ <GPIOMUX(11, GPO_SPI2_PAD_SS_1_N,
++ GPO_ENABLE, GPI_NONE)>;
++ bias-disable;
++ input-disable;
++ input-schmitt-disable;
++ };
++ };
++
++ uart0_pins: uart0-0 {
++ rx-pins {
++ pinmux = <GPIOMUX(40, GPO_LOW, GPO_DISABLE,
++ GPI_UART0_PAD_SIN)>,
++ <GPIOMUX(39, GPO_LOW, GPO_DISABLE,
++ GPI_UART0_PAD_CTSN)>;
++ bias-pull-up;
++ drive-strength = <14>;
++ input-enable;
++ input-schmitt-enable;
++ };
++ tx-pins {
++ pinmux = <GPIOMUX(41, GPO_UART0_PAD_SOUT,
++ GPO_ENABLE, GPI_NONE)>,
++ <GPIOMUX(42, GPO_UART0_PAD_RTSN,
++ GPO_ENABLE, GPI_NONE)>;
++ bias-disable;
++ drive-strength = <35>;
++ input-disable;
++ input-schmitt-disable;
++ };
++ };
++
+ uart3_pins: uart3-0 {
+ rx-pins {
+ pinmux = <GPIOMUX(13, GPO_LOW, GPO_DISABLE,
+@@ -186,6 +512,17 @@
+ regulators {
+ };
+ };
++
++ tda998x@70 {
++ compatible = "nxp,tda998x";
++ reg = <0x70>;
++
++ port {
++ tda998x_0_input: endpoint {
++ remote-endpoint = <&hdmi_out>;
++ };
++ };
++ };
+ };
+
+ &i2c1 {
+@@ -225,8 +562,104 @@
+ status = "okay";
+ };
+
++&ptc {
++ pinctrl-names = "default";
++ pinctrl-0 = <&pwm_pins>;
++ status = "okay";
++};
++
++&pwmdac {
++ pinctrl-names = "default";
++ pinctrl-0 = <&pwmdac_pins>;
++ status = "okay";
++};
++
++&qspi {
++ nor_flash: nor-flash@0 {
++ compatible = "spi-flash";
++ reg = <0>;
++ spi-max-frequency = <31250000>;
++ page-size = <256>;
++ block-size = <16>;
++ cdns,read-delay = <4>;
++ cdns,tshsl-ns = <1>;
++ cdns,tsd2d-ns = <1>;
++ cdns,tchsh-ns = <1>;
++ cdns,tslch-ns = <1>;
++ spi-tx-bus-width = <1>;
++ spi-rx-bus-width = <1>;
++ };
++
++ nand_flash: nand-flash@1 {
++ compatible = "spi-flash-nand";
++ reg = <1>;
++ spi-max-frequency = <31250000>;
++ page-size = <2048>;
++ block-size = <17>;
++ cdns,read-delay = <4>;
++ cdns,tshsl-ns = <1>;
++ cdns,tsd2d-ns = <1>;
++ cdns,tchsh-ns = <1>;
++ cdns,tslch-ns = <1>;
++ spi-tx-bus-width = <1>;
++ spi-rx-bus-width = <1>;
++ };
++};
++
++&sdio0 {
++ broken-cd;
++ bus-width = <4>;
++ cap-sd-highspeed;
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdio0_pins>;
++ max-frequency = <10000000>;
++ status = "okay";
++};
++
++&sdio1 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ bus-width = <4>;
++ cap-sd-highspeed;
++ cap-sdio-irq;
++ cap-power-off-card;
++ mmc-pwrseq = <&wifi_pwrseq>;
++ non-removable;
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdio1_pins>;
++ status = "okay";
++
++ wifi@1 {
++ compatible = "brcm,bcm4329-fmac";
++ reg = <1>;
++ };
++};
++
++&spi2 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&spi2_pins>;
++ status = "okay";
++
++ spi_dev0: spi@0 {
++ compatible = "rohm,dh2228fv";
++ spi-max-frequency = <10000000>;
++ reg = <0>;
++ };
++};
++
++&uart0 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&uart0_pins>;
++ status = "okay";
++};
++
+ &uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart3_pins>;
+ status = "okay";
+ };
++
++&usb3 {
++ dr_mode = "host";
++ status = "okay";
++};
+--- a/arch/riscv/boot/dts/starfive/jh7100-starfive-visionfive-v1.dts
++++ b/arch/riscv/boot/dts/starfive/jh7100-starfive-visionfive-v1.dts
+@@ -18,3 +18,22 @@
+ priority = <224>;
+ };
+ };
++
++&gpio {
++ /* don't reset gpio mux for serial console and reset gpio */
++ starfive,keep-gpiomux = <13 14 63>;
++};
++
++&i2c0 {
++ eeprom@50 {
++ compatible = "atmel,24c04";
++ reg = <0x50>;
++ pagesize = <16>;
++ };
++};
++
++&mdio {
++ phy: ethernet-phy@0 {
++ reg = <0>;
++ };
++};
+--- a/arch/riscv/boot/dts/starfive/jh7100.dtsi
++++ b/arch/riscv/boot/dts/starfive/jh7100.dtsi
+@@ -6,7 +6,9 @@
+
+ /dts-v1/;
+ #include <dt-bindings/clock/starfive-jh7100.h>
++#include <dt-bindings/clock/starfive-jh7100-audio.h>
+ #include <dt-bindings/reset/starfive-jh7100.h>
++#include <dt-bindings/reset/starfive-jh7100-audio.h>
+
+ / {
+ compatible = "starfive,jh7100";
+@@ -135,6 +137,13 @@
+ clock-frequency = <0>;
+ };
+
++ /* gmac device configuration */
++ stmmac_axi_setup: stmmac-axi-config {
++ snps,wr_osr_lmt = <0xf>;
++ snps,rd_osr_lmt = <0xf>;
++ snps,blen = <256 128 64 32 0 0 0>;
++ };
++
+ soc {
+ compatible = "simple-bus";
+ interrupt-parent = <&plic>;
+@@ -143,6 +152,24 @@
+ dma-noncoherent;
+ ranges;
+
++ dtim: dtim@1000000 {
++ compatible = "starfive,dtim0";
++ reg = <0x0 0x1000000 0x0 0x2000>;
++ reg-names = "mem";
++ };
++
++ itim0: itim@1808000 {
++ compatible = "starfive,itim0";
++ reg = <0x0 0x1808000 0x0 0x8000>;
++ reg-names = "mem";
++ };
++
++ itim1: itim@1820000 {
++ compatible = "starfive,itim0";
++ reg = <0x0 0x1820000 0x0 0x8000>;
++ reg-names = "mem";
++ };
++
+ clint: clint@2000000 {
+ compatible = "starfive,jh7100-clint", "sifive,clint0";
+ reg = <0x0 0x2000000 0x0 0x10000>;
+@@ -172,6 +199,151 @@
+ riscv,ndev = <133>;
+ };
+
++ gmac: ethernet@10020000 {
++ compatible = "starfive,jh7100-dwmac", "snps,dwmac";
++ reg = <0x0 0x10020000 0x0 0x10000>;
++ clocks = <&clkgen JH7100_CLK_GMAC_ROOT_DIV>,
++ <&clkgen JH7100_CLK_GMAC_AHB>,
++ <&clkgen JH7100_CLK_GMAC_PTP_REF>,
++ <&clkgen JH7100_CLK_GMAC_TX_INV>,
++ <&clkgen JH7100_CLK_GMAC_GTX>;
++ clock-names = "stmmaceth", "pclk", "ptp_ref", "tx", "gtx";
++ resets = <&rstgen JH7100_RSTN_GMAC_AHB>;
++ reset-names = "ahb";
++ interrupts = <6>, <7>;
++ interrupt-names = "macirq", "eth_wake_irq";
++ max-frame-size = <9000>;
++ snps,multicast-filter-bins = <0>;
++ snps,perfect-filter-entries = <128>;
++ starfive,syscon = <&sysmain 0x70 0>;
++ rx-fifo-depth = <32768>;
++ tx-fifo-depth = <16384>;
++ snps,axi-config = <&stmmac_axi_setup>;
++ snps,fixed-burst;
++ /*snps,force_sf_dma_mode;*/
++ snps,force_thresh_dma_mode;
++ snps,no-pbl-x8;
++ status = "disabled";
++ };
++
++ dma2p: dma-controller@100b0000 {
++ compatible = "starfive,jh7100-axi-dma";
++ reg = <0x0 0x100b0000 0x0 0x10000>;
++ clocks = <&clkgen JH7100_CLK_SGDMA2P_AXI>,
++ <&clkgen JH7100_CLK_SGDMA2P_AHB>;
++ clock-names = "core-clk", "cfgr-clk";
++ resets = <&rstgen JH7100_RSTN_SGDMA2P_AXI>,
++ <&rstgen JH7100_RSTN_SGDMA2P_AHB>;
++ reset-names = "axi", "ahb";
++ interrupts = <2>;
++ #dma-cells = <1>;
++ dma-channels = <4>;
++ snps,dma-masters = <1>;
++ snps,data-width = <4>;
++ snps,block-size = <4096 4096 4096 4096>;
++ snps,priority = <0 1 2 3>;
++ snps,axi-max-burst-len = <128>;
++ dma-coherent;
++ };
++
++ crypto: crypto@100d0000 {
++ compatible = "starfive,vic-sec";
++ reg = <0x0 0x100d0000 0x0 0x20000>,
++ <0x0 0x11800234 0x0 0xc>;
++ reg-names = "secmem", "secclk";
++ clocks = <&clkgen JH7100_CLK_SEC_AHB>;
++ interrupts = <31>;
++ };
++
++ i2sadc0: i2sadc0@10400000 {
++ compatible = "snps,designware-i2sadc0";
++ reg = <0x0 0x10400000 0x0 0x1000>;
++ clocks = <&clkgen JH7100_CLK_APB1_BUS>;
++ clock-names = "i2sclk";
++ interrupt-parent = <&plic>;
++ #sound-dai-cells = <0>;
++ dmas = <&dma2p 28>;
++ dma-names = "rx";
++ };
++
++ i2svad: i2svad@10420000 {
++ compatible = "starfive,sf-i2svad";
++ reg = <0x0 0x10420000 0x0 0x1000> ;
++ clocks = <&audclk JH7100_AUDCLK_I2SVAD_APB>;
++ clock-names = "i2svad_apb";
++ resets = <&audrst JH7100_AUDRSTN_I2SVAD_APB>,
++ <&audrst JH7100_AUDRSTN_I2SVAD_SRST>;
++ reset-names = "apb_i2svad", "i2svad_srst";
++ interrupts = <60>, <61>;
++ interrupt-names = "spintr", "slintr";
++ #sound-dai-cells = <0>;
++ };
++
++ pwmdac: pwmdac@10440000 {
++ compatible = "starfive,pwmdac";
++ reg = <0x0 0x10440000 0x0 0x1000>;
++ clocks = <&clkgen JH7100_CLK_AUDIO_ROOT>,
++ <&clkgen JH7100_CLK_AUDIO_SRC>,
++ <&clkgen JH7100_CLK_AUDIO_12288>,
++ <&audclk JH7100_AUDCLK_DMA1P_AHB>,
++ <&audclk JH7100_AUDCLK_PWMDAC_APB>,
++ <&audclk JH7100_AUDCLK_DAC_MCLK>;
++ clock-names = "audio_root",
++ "audio_src",
++ "audio_12288",
++ "dma1p_ahb",
++ "pwmdac_apb",
++ "dac_mclk";
++ resets = <&audrst JH7100_AUDRSTN_APB_BUS>,
++ <&audrst JH7100_AUDRSTN_DMA1P_AHB>,
++ <&audrst JH7100_AUDRSTN_PWMDAC_APB>;
++ reset-names = "apb_bus", "dma1p_ahb", "apb_pwmdac";
++ dmas = <&dma2p 23>;
++ dma-names = "tx";
++ #sound-dai-cells = <0>;
++ };
++
++ i2sdac0: i2sdac0@10450000 {
++ compatible = "snps,designware-i2sdac0";
++ reg = <0x0 0x10450000 0x0 0x1000>;
++ clocks = <&audclk JH7100_AUDCLK_DAC_MCLK>,
++ <&audclk JH7100_AUDCLK_I2SDAC_BCLK>,
++ <&audclk JH7100_AUDCLK_I2SDAC_LRCLK>,
++ <&audclk JH7100_AUDCLK_I2SDAC_APB>;
++ clock-names = "dac_mclk", "i2sdac0_bclk", "i2sdac0_lrclk", "i2sdac_apb";
++ resets = <&audrst JH7100_AUDRSTN_I2SDAC_APB>,
++ <&audrst JH7100_AUDRSTN_I2SDAC_SRST>;
++ reset-names = "apb_i2sdac", "i2sdac_srst";
++ #sound-dai-cells = <0>;
++ dmas = <&dma2p 30>;
++ dma-names = "tx";
++ };
++
++ i2sdac1: i2sdac1@10460000 {
++ compatible = "snps,designware-i2sdac1";
++ reg = <0x0 0x10460000 0x0 0x1000>;
++ clocks = <&audclk JH7100_AUDCLK_DAC_MCLK>,
++ <&audclk JH7100_AUDCLK_I2S1_BCLK>,
++ <&audclk JH7100_AUDCLK_I2S1_LRCLK>,
++ <&audclk JH7100_AUDCLK_I2S1_APB>;
++ clock-names = "dac_mclk", "i2sdac1_bclk", "i2sdac1_lrclk", "i2s1_apb";
++ resets = <&audrst JH7100_AUDRSTN_I2S1_APB>,
++ <&audrst JH7100_AUDRSTN_I2S1_SRST>;
++ #sound-dai-cells = <0>;
++ dmas = <&dma2p 31>;
++ dma-names = "tx";
++ };
++
++ i2sdac16k: i2sdac16k@10470000 {
++ compatible = "snps,designware-i2sdac16k";
++ reg = <0x0 0x10470000 0x0 0x1000>;
++ clocks = <&clkgen JH7100_CLK_APB1_BUS>;
++ clock-names = "i2sclk";
++ #sound-dai-cells = <0>;
++ dmas = <&dma2p 29>;
++ dma-names = "tx";
++ };
++
+ audclk: clock-controller@10480000 {
+ compatible = "starfive,jh7100-audclk";
+ reg = <0x0 0x10480000 0x0 0x10000>;
+@@ -214,6 +386,82 @@
+ status = "disabled";
+ };
+
++ spdif_transmitter: spdif-transmitter {
++ compatible = "linux,spdif-dit";
++ #sound-dai-cells = <0>;
++ };
++
++ spdif_receiver: spdif-receiver {
++ compatible = "linux,spdif-dir";
++ #sound-dai-cells = <0>;
++ };
++
++ pwmdac_codec: pwmdac-transmitter {
++ compatible = "linux,pwmdac-dit";
++ #sound-dai-cells = <0>;
++ };
++
++ dmic_codec: dmic {
++ compatible = "dmic-codec";
++ #sound-dai-cells = <0>;
++ };
++
++ sound: snd-card {
++ compatible = "simple-audio-card";
++ simple-audio-card,name = "Starfive-Multi-Sound-Card";
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ /* pwmdac */
++ simple-audio-card,dai-link@0 {
++ reg = <0>;
++ status = "okay";
++ format = "left_j";
++ bitclock-master = <&sndcpu0>;
++ frame-master = <&sndcpu0>;
++
++ sndcpu0: cpu {
++ sound-dai = <&pwmdac>;
++ };
++
++ codec {
++ sound-dai = <&pwmdac_codec>;
++ };
++ };
++ };
++
++ usb3: usb@104c0000 {
++ compatible = "cdns,usb3";
++ reg = <0x0 0x104c0000 0x0 0x10000>, // memory area for HOST registers
++ <0x0 0x104d0000 0x0 0x10000>, // memory area for DEVICE registers
++ <0x0 0x104e0000 0x0 0x10000>; // memory area for OTG/DRD registers
++ reg-names = "otg", "xhci", "dev";
++ interrupts = <44>, <52>, <43>;
++ interrupt-names = "host", "peripheral", "otg";
++ phy-names = "cdns3,usb3-phy", "cdns3,usb2-phy";
++ maximum-speed = "super-speed";
++ status = "disabled";
++ };
++
++ dma1p: dma-controller@10500000 {
++ compatible = "starfive,jh7100-axi-dma";
++ reg = <0x0 0x10500000 0x0 0x10000>;
++ clocks = <&clkgen JH7100_CLK_SGDMA1P_AXI>,
++ <&clkgen JH7100_CLK_SGDMA1P_BUS>;
++ clock-names = "core-clk", "cfgr-clk";
++ resets = <&rstgen JH7100_RSTN_DMA1P_AXI>,
++ <&rstgen JH7100_RSTN_SGDMA1P_AXI>;
++ reset-names = "axi", "ahb";
++ interrupts = <1>;
++ #dma-cells = <1>;
++ dma-channels = <16>;
++ snps,dma-masters = <1>;
++ snps,data-width = <3>;
++ snps,block-size = <4096 4096 4096 4096 4096 4096 4096 4096 4096 4096 4096 4096 4096 4096 4096 4096>;
++ snps,priority = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15>;
++ snps,axi-max-burst-len = <64>;
++ };
++
+ clkgen: clock-controller@11800000 {
+ compatible = "starfive,jh7100-clkgen";
+ reg = <0x0 0x11800000 0x0 0x10000>;
+@@ -222,12 +470,93 @@
+ #clock-cells = <1>;
+ };
+
++ otp: otp@11810000 {
++ compatible = "starfive,fu740-otp";
++ reg = <0x0 0x11810000 0x0 0x10000>;
++ clocks = <&clkgen JH7100_CLK_OTP_APB>;
++ fuse-count = <0x200>;
++ };
++
+ rstgen: reset-controller@11840000 {
+ compatible = "starfive,jh7100-reset";
+ reg = <0x0 0x11840000 0x0 0x10000>;
+ #reset-cells = <1>;
+ };
+
++ sysmain: syscon@11850000 {
++ compatible = "starfive,jh7100-sysmain", "syscon";
++ reg = <0x0 0x11850000 0x0 0x10000>;
++ };
++
++ qspi: spi@11860000 {
++ compatible = "cdns,qspi-nor";
++ reg = <0x0 0x11860000 0x0 0x10000>,
++ <0x0 0x20000000 0x0 0x20000000>;
++ clocks = <&clkgen JH7100_CLK_QSPI_AHB>;
++ interrupts = <3>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ cdns,fifo-depth = <256>;
++ cdns,fifo-width = <4>;
++ cdns,trigger-address = <0x0>;
++ spi-max-frequency = <250000000>;
++ status = "disabled";
++ };
++
++ uart0: serial@11870000 {
++ compatible = "starfive,jh7100-hsuart", "snps,dw-apb-uart";
++ reg = <0x0 0x11870000 0x0 0x10000>;
++ clocks = <&clkgen JH7100_CLK_UART0_CORE>,
++ <&clkgen JH7100_CLK_UART0_APB>;
++ clock-names = "baudclk", "apb_pclk";
++ resets = <&rstgen JH7100_RSTN_UART0_APB>;
++ interrupts = <92>;
++ reg-io-width = <4>;
++ reg-shift = <2>;
++ status = "disabled";
++ };
++
++ uart1: serial@11880000 {
++ compatible = "starfive,jh7100-hsuart", "snps,dw-apb-uart";
++ reg = <0x0 0x11880000 0x0 0x10000>;
++ clocks = <&clkgen JH7100_CLK_UART1_CORE>,
++ <&clkgen JH7100_CLK_UART1_APB>;
++ clock-names = "baudclk", "apb_pclk";
++ resets = <&rstgen JH7100_RSTN_UART1_APB>;
++ interrupts = <93>;
++ reg-io-width = <4>;
++ reg-shift = <2>;
++ status = "disabled";
++ };
++
++ spi0: spi@11890000 {
++ compatible = "snps,dw-apb-ssi";
++ reg = <0x0 0x11890000 0x0 0x10000>;
++ clocks = <&clkgen JH7100_CLK_SPI0_CORE>,
++ <&clkgen JH7100_CLK_SPI0_APB>;
++ clock-names = "ssi_clk", "pclk";
++ resets = <&rstgen JH7100_RSTN_SPI0_APB>;
++ reset-names = "spi";
++ interrupts = <94>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ spi1: spi@118a0000 {
++ compatible = "snps,dw-apb-ssi";
++ reg = <0x0 0x118a0000 0x0 0x10000>;
++ clocks = <&clkgen JH7100_CLK_SPI1_CORE>,
++ <&clkgen JH7100_CLK_SPI1_APB>;
++ clock-names = "ssi_clk", "pclk";
++ resets = <&rstgen JH7100_RSTN_SPI1_APB>;
++ reset-names = "spi";
++ interrupts = <95>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
+ i2c0: i2c@118b0000 {
+ compatible = "snps,designware-i2c";
+ reg = <0x0 0x118b0000 0x0 0x10000>;
+@@ -254,6 +583,41 @@
+ status = "disabled";
+ };
+
++ trng: trng@118d0000 {
++ compatible = "starfive,vic-rng";
++ reg = <0x0 0x118d0000 0x0 0x10000>;
++ clocks = <&clkgen JH7100_CLK_TRNG_APB>;
++ interrupts = <98>;
++ };
++
++ vpu_enc: vpu_enc@118e0000 {
++ compatible = "cm,cm521-vpu";
++ reg = <0x0 0x118e0000 0x0 0x4000>;
++ reg-names = "control";
++ clocks = <&clkgen JH7100_CLK_VP6_CORE>;
++ clock-names = "vcodec";
++ interrupts = <26>;
++ };
++
++ vpu_dec: vpu_dec@118f0000 {
++ compatible = "c&m,cm511-vpu";
++ reg = <0 0x118f0000 0 0x10000>;
++ clocks = <&clkgen JH7100_CLK_VP6_CORE>;
++ clock-names = "vcodec";
++ interrupts = <23>;
++ //memory-region = <&vpu_reserved>;
++ };
++
++ jpu: coadj12@11900000 {
++ compatible = "cm,codaj12-jpu-1";
++ reg = <0x0 0x11900000 0x0 0x300>;
++ reg-names = "control";
++ clocks = <&clkgen JH7100_CLK_JPEG_APB>;
++ clock-names = "jpege";
++ interrupts = <24>;
++ memory-region = <&jpu_reserved>;
++ };
++
+ gpio: pinctrl@11910000 {
+ compatible = "starfive,jh7100-pinctrl";
+ reg = <0x0 0x11910000 0x0 0x10000>,
+@@ -268,6 +632,86 @@
+ #interrupt-cells = <2>;
+ };
+
++ nvdla@11940000 {
++ compatible = "nvidia,nvdla_os_initial";
++ interrupts = <22>;
++ memory-region = <&nvdla_reserved>;
++ reg = <0x0 0x11940000 0x0 0x40000>;
++ status = "okay";
++ };
++
++ display: display-subsystem {
++ compatible = "starfive,display-subsystem";
++ dma-coherent;
++ status = "disabled";
++ };
++
++ encoder: display-encoder {
++ compatible = "starfive,display-encoder";
++ status = "disabled";
++ };
++
++ crtc: crtc@12000000 {
++ compatible = "starfive,jh7100-crtc";
++ reg = <0x0 0x12000000 0x0 0x10000>,
++ <0x0 0x12040000 0x0 0x10000>,
++ <0x0 0x12080000 0x0 0x10000>,
++ <0x0 0x120c0000 0x0 0x10000>,
++ <0x0 0x12240000 0x0 0x10000>,
++ <0x0 0x12250000 0x0 0x10000>,
++ <0x0 0x12260000 0x0 0x10000>;
++ reg-names = "lcdc", "vpp0", "vpp1", "vpp2", "clk", "rst", "sys";
++ clocks = <&clkgen JH7100_CLK_DISP_AXI>, <&clkgen JH7100_CLK_VOUT_SRC>;
++ clock-names = "disp_axi", "vout_src";
++ resets = <&rstgen JH7100_RSTN_DISP_AXI>, <&rstgen JH7100_RSTN_VOUT_SRC>;
++ reset-names = "disp_axi", "vout_src";
++ interrupts = <101>, <103>;
++ interrupt-names = "lcdc_irq", "vpp1_irq";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++
++ pp1 {
++ pp-id = <1>;
++ fifo-out;
++ //sys-bus-out;
++ src-format = <11>; //<COLOR_RGB565>;
++ src-width = <1920>;
++ src-height = <1080>;
++ dst-format = <7>; //<COLOR_RGB888_ARGB>;
++ dst-width = <1920>;
++ dst-height = <1080>;
++ };
++ };
++
++ spi2: spi@12410000 {
++ compatible = "snps,dw-apb-ssi";
++ reg = <0x0 0x12410000 0x0 0x10000>;
++ clocks = <&clkgen JH7100_CLK_SPI2_CORE>,
++ <&clkgen JH7100_CLK_SPI2_APB>;
++ clock-names = "ssi_clk", "pclk";
++ resets = <&rstgen JH7100_RSTN_SPI2_APB>;
++ reset-names = "spi";
++ interrupts = <70>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
++ spi3: spi@12420000 {
++ compatible = "snps,dw-apb-ssi";
++ reg = <0x0 0x12420000 0x0 0x10000>;
++ clocks = <&clkgen JH7100_CLK_SPI3_CORE>,
++ <&clkgen JH7100_CLK_SPI3_APB>;
++ clock-names = "ssi_clk", "pclk";
++ resets = <&rstgen JH7100_RSTN_SPI3_APB>;
++ reset-names = "spi";
++ interrupts = <71>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
+ uart2: serial@12430000 {
+ compatible = "starfive,jh7100-uart", "snps,dw-apb-uart";
+ reg = <0x0 0x12430000 0x0 0x10000>;
+@@ -341,5 +785,64 @@
+ reset-names = "sense", "bus";
+ #thermal-sensor-cells = <0>;
+ };
++
++ ptc: pwm@12490000 {
++ compatible = "starfive,pwm0";
++ reg = <0x0 0x12490000 0x0 0x10000>;
++ clocks = <&clkgen JH7100_CLK_PWM_APB>;
++ resets = <&rstgen JH7100_RSTN_PWM_APB>;
++ #pwm-cells = <3>;
++ sifive,npwm = <8>;
++ status = "disabled";
++ };
++
++ thermal-zones {
++ cpu-thermal {
++ polling-delay-passive = <250>;
++ polling-delay = <15000>;
++
++ thermal-sensors = <&sfctemp>;
++
++ cooling-maps {
++ };
++
++ trips {
++ cpu_alert0: cpu_alert0 {
++ /* milliCelsius */
++ temperature = <75000>;
++ hysteresis = <2000>;
++ type = "passive";
++ };
++
++ cpu_crit: cpu_crit {
++ /* milliCelsius */
++ temperature = <90000>;
++ hysteresis = <2000>;
++ type = "critical";
++ };
++ };
++ };
++ };
++
++ xrp@f0000000 {
++ compatible = "cdns,xrp";
++ reg = <0x0 0xf0000000 0x0 0x01ffffff>,
++ <0x10 0x72000000 0x0 0x00001000>,
++ <0x10 0x72001000 0x0 0x00fff000>,
++ <0x0 0x124b0000 0x0 0x00010000>;
++ clocks = <&clkgen JH7100_CLK_VP6_CORE>;
++ interrupts = <27>, <28>;
++ firmware-name = "vp6_elf";
++ dsp-irq = <19 20>;
++ dsp-irq-src = <0x20 0x21>;
++ intc-irq-mode = <1>;
++ intc-irq = <0 1>;
++ #address-cells = <1>;
++ #size-cells = <1>;
++ ranges = <0x40000000 0x0 0x40000000 0x01000000>,
++ <0xb0000000 0x10 0x70000000 0x3000000>;
++ dsp@0 {
++ };
++ };
+ };
+ };
diff --git a/target/linux/sunxi/config-6.6 b/target/linux/sunxi/config-6.6
index 3e73f44c90..6a31400b48 100644
--- a/target/linux/sunxi/config-6.6
+++ b/target/linux/sunxi/config-6.6
@@ -168,7 +168,6 @@ CONFIG_FRAME_WARN=2048
CONFIG_FREEZER=y
CONFIG_FS_IOMAP=y
CONFIG_FS_MBCACHE=y
-CONFIG_FS_POSIX_ACL=y
CONFIG_FWNODE_MDIO=y
CONFIG_FW_CACHE=y
CONFIG_FW_LOADER_PAGED_BUF=y
@@ -482,7 +481,6 @@ CONFIG_THERMAL_OF=y
CONFIG_TICK_CPU_ACCOUNTING=y
CONFIG_TIMER_OF=y
CONFIG_TIMER_PROBE=y
-CONFIG_TMPFS_POSIX_ACL=y
CONFIG_TOUCHSCREEN_SUN4I=y
CONFIG_TREE_RCU=y
CONFIG_TREE_SRCU=y
diff --git a/target/linux/sunxi/patches-6.6/017-v6.10-firmware-smccc-Export-revision-soc_id-function.patch b/target/linux/sunxi/patches-6.6/017-v6.10-firmware-smccc-Export-revision-soc_id-function.patch
new file mode 100644
index 0000000000..538484dd82
--- /dev/null
+++ b/target/linux/sunxi/patches-6.6/017-v6.10-firmware-smccc-Export-revision-soc_id-function.patch
@@ -0,0 +1,32 @@
+From 9cf3415ade2d7598d78d2ce6d35d6d6d06132201 Mon Sep 17 00:00:00 2001
+From: Martin Botka <martin.botka@somainline.org>
+Date: Thu, 18 Apr 2024 16:44:01 +0100
+Subject: [PATCH] firmware: smccc: Export revision soc_id function
+
+The "SoC ID revision" as provided via the SMCCC SOCID interface can be
+valuable information for drivers, when certain functionality depends
+on a die revision, for instance.
+One example is the sun50i-cpufreq-nvmem driver, which needs this
+information to determine the speed bin of the SoC.
+
+Export the arm_smccc_get_soc_id_revision() function so that it can be
+called by any driver.
+
+Signed-off-by: Martin Botka <martin.botka@somainline.org>
+Signed-off-by: Andre Przywara <andre.przywara@arm.com>
+Acked-by: Sudeep Holla <sudeep.holla@arm.com>
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+---
+ drivers/firmware/smccc/smccc.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/firmware/smccc/smccc.c
++++ b/drivers/firmware/smccc/smccc.c
+@@ -69,6 +69,7 @@ s32 arm_smccc_get_soc_id_revision(void)
+ {
+ return smccc_soc_id_revision;
+ }
++EXPORT_SYMBOL_GPL(arm_smccc_get_soc_id_revision);
+
+ static int __init smccc_devices_init(void)
+ {
diff --git a/target/linux/sunxi/patches-6.6/018-v6.10-cpufreq-dt-platdev-Blocklist-Allwinner-H616-618-SoCs.patch b/target/linux/sunxi/patches-6.6/018-v6.10-cpufreq-dt-platdev-Blocklist-Allwinner-H616-618-SoCs.patch
new file mode 100644
index 0000000000..d67b35ee71
--- /dev/null
+++ b/target/linux/sunxi/patches-6.6/018-v6.10-cpufreq-dt-platdev-Blocklist-Allwinner-H616-618-SoCs.patch
@@ -0,0 +1,29 @@
+From 6ae07744cf334b750762ba881492c0cfba524b38 Mon Sep 17 00:00:00 2001
+From: Martin Botka <martin.botka@somainline.org>
+Date: Thu, 18 Apr 2024 16:44:02 +0100
+Subject: [PATCH] cpufreq: dt-platdev: Blocklist Allwinner H616/618 SoCs
+
+The AllWinner H616 SoC will use the (extended) H6 OPP driver, so add
+them to the cpufreq-dt blocklist, to not create the device twice.
+This also affects the closely related sibling SoCs H618 and H700.
+
+Signed-off-by: Martin Botka <martin.botka@somainline.org>
+Signed-off-by: Andre Przywara <andre.przywara@arm.com>
+Reviewed-by: Jernej Skrabec <jernej.skrabec@gmail.com>
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+---
+ drivers/cpufreq/cpufreq-dt-platdev.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/cpufreq/cpufreq-dt-platdev.c
++++ b/drivers/cpufreq/cpufreq-dt-platdev.c
+@@ -104,6 +104,9 @@ static const struct of_device_id allowli
+ */
+ static const struct of_device_id blocklist[] __initconst = {
+ { .compatible = "allwinner,sun50i-h6", },
++ { .compatible = "allwinner,sun50i-h616", },
++ { .compatible = "allwinner,sun50i-h618", },
++ { .compatible = "allwinner,sun50i-h700", },
+
+ { .compatible = "apple,arm-platform", },
+
diff --git a/target/linux/sunxi/patches-6.6/019-v6.10-cpufreq-sun50i-Refactor-speed-bin-decoding.patch b/target/linux/sunxi/patches-6.6/019-v6.10-cpufreq-sun50i-Refactor-speed-bin-decoding.patch
new file mode 100644
index 0000000000..9a81906996
--- /dev/null
+++ b/target/linux/sunxi/patches-6.6/019-v6.10-cpufreq-sun50i-Refactor-speed-bin-decoding.patch
@@ -0,0 +1,149 @@
+From 6cc4bcceff9af0e6be9738096d95e4ba75e75123 Mon Sep 17 00:00:00 2001
+From: Brandon Cheo Fusi <fusibrandon13@gmail.com>
+Date: Thu, 18 Apr 2024 16:44:04 +0100
+Subject: [PATCH] cpufreq: sun50i: Refactor speed bin decoding
+
+Make converting the speed bin value into a speed grade generic and
+determined by a platform specific callback. Also change the prototypes
+involved to encode the speed bin directly in the return value.
+
+This allows to extend the driver more easily to support more SoCs.
+
+Signed-off-by: Brandon Cheo Fusi <fusibrandon13@gmail.com>
+[Andre: merge output into return value]
+Signed-off-by: Andre Przywara <andre.przywara@arm.com>
+Reviewed-by: Jernej Skrabec <jernej.skrabec@gmail.com>
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+---
+ drivers/cpufreq/sun50i-cpufreq-nvmem.c | 74 +++++++++++++++++---------
+ 1 file changed, 49 insertions(+), 25 deletions(-)
+
+--- a/drivers/cpufreq/sun50i-cpufreq-nvmem.c
++++ b/drivers/cpufreq/sun50i-cpufreq-nvmem.c
+@@ -25,19 +25,52 @@
+
+ static struct platform_device *cpufreq_dt_pdev, *sun50i_cpufreq_pdev;
+
++struct sunxi_cpufreq_data {
++ u32 (*efuse_xlate)(u32 speedbin);
++};
++
++static u32 sun50i_h6_efuse_xlate(u32 speedbin)
++{
++ u32 efuse_value;
++
++ efuse_value = (speedbin >> NVMEM_SHIFT) & NVMEM_MASK;
++
++ /*
++ * We treat unexpected efuse values as if the SoC was from
++ * the slowest bin. Expected efuse values are 1-3, slowest
++ * to fastest.
++ */
++ if (efuse_value >= 1 && efuse_value <= 3)
++ return efuse_value - 1;
++ else
++ return 0;
++}
++
++static struct sunxi_cpufreq_data sun50i_h6_cpufreq_data = {
++ .efuse_xlate = sun50i_h6_efuse_xlate,
++};
++
++static const struct of_device_id cpu_opp_match_list[] = {
++ { .compatible = "allwinner,sun50i-h6-operating-points",
++ .data = &sun50i_h6_cpufreq_data,
++ },
++ {}
++};
++
+ /**
+ * sun50i_cpufreq_get_efuse() - Determine speed grade from efuse value
+- * @versions: Set to the value parsed from efuse
+ *
+- * Returns 0 if success.
++ * Returns non-negative speed bin index on success, a negative error
++ * value otherwise.
+ */
+-static int sun50i_cpufreq_get_efuse(u32 *versions)
++static int sun50i_cpufreq_get_efuse(void)
+ {
++ const struct sunxi_cpufreq_data *opp_data;
+ struct nvmem_cell *speedbin_nvmem;
++ const struct of_device_id *match;
+ struct device_node *np;
+ struct device *cpu_dev;
+- u32 *speedbin, efuse_value;
+- size_t len;
++ u32 *speedbin;
+ int ret;
+
+ cpu_dev = get_cpu_device(0);
+@@ -48,12 +81,12 @@ static int sun50i_cpufreq_get_efuse(u32
+ if (!np)
+ return -ENOENT;
+
+- ret = of_device_is_compatible(np,
+- "allwinner,sun50i-h6-operating-points");
+- if (!ret) {
++ match = of_match_node(cpu_opp_match_list, np);
++ if (!match) {
+ of_node_put(np);
+ return -ENOENT;
+ }
++ opp_data = match->data;
+
+ speedbin_nvmem = of_nvmem_cell_get(np, NULL);
+ of_node_put(np);
+@@ -61,25 +94,16 @@ static int sun50i_cpufreq_get_efuse(u32
+ return dev_err_probe(cpu_dev, PTR_ERR(speedbin_nvmem),
+ "Could not get nvmem cell\n");
+
+- speedbin = nvmem_cell_read(speedbin_nvmem, &len);
++ speedbin = nvmem_cell_read(speedbin_nvmem, NULL);
+ nvmem_cell_put(speedbin_nvmem);
+ if (IS_ERR(speedbin))
+ return PTR_ERR(speedbin);
+
+- efuse_value = (*speedbin >> NVMEM_SHIFT) & NVMEM_MASK;
+-
+- /*
+- * We treat unexpected efuse values as if the SoC was from
+- * the slowest bin. Expected efuse values are 1-3, slowest
+- * to fastest.
+- */
+- if (efuse_value >= 1 && efuse_value <= 3)
+- *versions = efuse_value - 1;
+- else
+- *versions = 0;
++ ret = opp_data->efuse_xlate(*speedbin);
+
+ kfree(speedbin);
+- return 0;
++
++ return ret;
+ };
+
+ static int sun50i_cpufreq_nvmem_probe(struct platform_device *pdev)
+@@ -87,7 +111,7 @@ static int sun50i_cpufreq_nvmem_probe(st
+ int *opp_tokens;
+ char name[MAX_NAME_LEN];
+ unsigned int cpu;
+- u32 speed = 0;
++ int speed;
+ int ret;
+
+ opp_tokens = kcalloc(num_possible_cpus(), sizeof(*opp_tokens),
+@@ -95,10 +119,10 @@ static int sun50i_cpufreq_nvmem_probe(st
+ if (!opp_tokens)
+ return -ENOMEM;
+
+- ret = sun50i_cpufreq_get_efuse(&speed);
+- if (ret) {
++ speed = sun50i_cpufreq_get_efuse();
++ if (speed < 0) {
+ kfree(opp_tokens);
+- return ret;
++ return speed;
+ }
+
+ snprintf(name, MAX_NAME_LEN, "speed%d", speed);
diff --git a/target/linux/sunxi/patches-6.6/020-v6.10-cpufreq-sun50i-Add-support-for-opp_supported_hw.patch b/target/linux/sunxi/patches-6.6/020-v6.10-cpufreq-sun50i-Add-support-for-opp_supported_hw.patch
new file mode 100644
index 0000000000..e0c68f9aad
--- /dev/null
+++ b/target/linux/sunxi/patches-6.6/020-v6.10-cpufreq-sun50i-Add-support-for-opp_supported_hw.patch
@@ -0,0 +1,132 @@
+From fa5aec9561cfc4f4370983ca5818c90227c9d90e Mon Sep 17 00:00:00 2001
+From: Andre Przywara <andre.przywara@arm.com>
+Date: Thu, 18 Apr 2024 16:44:05 +0100
+Subject: [PATCH] cpufreq: sun50i: Add support for opp_supported_hw
+
+The opp_supported_hw DT property allows the DT to specify a mask of chip
+revisions that a certain OPP is eligible for. This allows for easy
+limiting of maximum frequencies, for instance.
+
+Add support for that in the sun50i-cpufreq-nvmem driver. We support both
+the existing opp-microvolt suffix properties as well as the
+opp-supported-hw property, the generic code figures out which is needed
+automatically.
+However if none of the DT OPP nodes contain an opp-supported-hw
+property, the core code will ignore all OPPs and the driver will fail
+probing. So check the DT's eligibility first before using that feature.
+
+Signed-off-by: Andre Przywara <andre.przywara@arm.com>
+Reviewed-by: Jernej Skrabec <jernej.skrabec@gmail.com>
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+---
+ drivers/cpufreq/sun50i-cpufreq-nvmem.c | 62 ++++++++++++++++++++++----
+ 1 file changed, 54 insertions(+), 8 deletions(-)
+
+--- a/drivers/cpufreq/sun50i-cpufreq-nvmem.c
++++ b/drivers/cpufreq/sun50i-cpufreq-nvmem.c
+@@ -58,6 +58,41 @@ static const struct of_device_id cpu_opp
+ };
+
+ /**
++ * dt_has_supported_hw() - Check if any OPPs use opp-supported-hw
++ *
++ * If we ask the cpufreq framework to use the opp-supported-hw feature, it
++ * will ignore every OPP node without that DT property. If none of the OPPs
++ * have it, the driver will fail probing, due to the lack of OPPs.
++ *
++ * Returns true if we have at least one OPP with the opp-supported-hw property.
++ */
++static bool dt_has_supported_hw(void)
++{
++ bool has_opp_supported_hw = false;
++ struct device_node *np, *opp;
++ struct device *cpu_dev;
++
++ cpu_dev = get_cpu_device(0);
++ if (!cpu_dev)
++ return -ENODEV;
++
++ np = dev_pm_opp_of_get_opp_desc_node(cpu_dev);
++ if (!np)
++ return -ENOENT;
++
++ for_each_child_of_node(np, opp) {
++ if (of_find_property(opp, "opp-supported-hw", NULL)) {
++ has_opp_supported_hw = true;
++ break;
++ }
++ }
++
++ of_node_put(np);
++
++ return has_opp_supported_hw;
++}
++
++/**
+ * sun50i_cpufreq_get_efuse() - Determine speed grade from efuse value
+ *
+ * Returns non-negative speed bin index on success, a negative error
+@@ -110,7 +145,8 @@ static int sun50i_cpufreq_nvmem_probe(st
+ {
+ int *opp_tokens;
+ char name[MAX_NAME_LEN];
+- unsigned int cpu;
++ unsigned int cpu, supported_hw;
++ struct dev_pm_opp_config config = {};
+ int speed;
+ int ret;
+
+@@ -125,7 +161,18 @@ static int sun50i_cpufreq_nvmem_probe(st
+ return speed;
+ }
+
++ /*
++ * We need at least one OPP with the "opp-supported-hw" property,
++ * or else the upper layers will ignore every OPP and will bail out.
++ */
++ if (dt_has_supported_hw()) {
++ supported_hw = 1U << speed;
++ config.supported_hw = &supported_hw;
++ config.supported_hw_count = 1;
++ }
++
+ snprintf(name, MAX_NAME_LEN, "speed%d", speed);
++ config.prop_name = name;
+
+ for_each_possible_cpu(cpu) {
+ struct device *cpu_dev = get_cpu_device(cpu);
+@@ -135,12 +182,11 @@ static int sun50i_cpufreq_nvmem_probe(st
+ goto free_opp;
+ }
+
+- opp_tokens[cpu] = dev_pm_opp_set_prop_name(cpu_dev, name);
+- if (opp_tokens[cpu] < 0) {
+- ret = opp_tokens[cpu];
+- pr_err("Failed to set prop name\n");
++ ret = dev_pm_opp_set_config(cpu_dev, &config);
++ if (ret < 0)
+ goto free_opp;
+- }
++
++ opp_tokens[cpu] = ret;
+ }
+
+ cpufreq_dt_pdev = platform_device_register_simple("cpufreq-dt", -1,
+@@ -155,7 +201,7 @@ static int sun50i_cpufreq_nvmem_probe(st
+
+ free_opp:
+ for_each_possible_cpu(cpu)
+- dev_pm_opp_put_prop_name(opp_tokens[cpu]);
++ dev_pm_opp_clear_config(opp_tokens[cpu]);
+ kfree(opp_tokens);
+
+ return ret;
+@@ -169,7 +215,7 @@ static void sun50i_cpufreq_nvmem_remove(
+ platform_device_unregister(cpufreq_dt_pdev);
+
+ for_each_possible_cpu(cpu)
+- dev_pm_opp_put_prop_name(opp_tokens[cpu]);
++ dev_pm_opp_clear_config(opp_tokens[cpu]);
+
+ kfree(opp_tokens);
+ }
diff --git a/target/linux/sunxi/patches-6.6/021-v6.10-cpufreq-sun50i-Add-H616-support.patch b/target/linux/sunxi/patches-6.6/021-v6.10-cpufreq-sun50i-Add-H616-support.patch
new file mode 100644
index 0000000000..c891f5722a
--- /dev/null
+++ b/target/linux/sunxi/patches-6.6/021-v6.10-cpufreq-sun50i-Add-H616-support.patch
@@ -0,0 +1,122 @@
+From e2e2dcd2e944fe6167cb731864f8a1343f1bbee7 Mon Sep 17 00:00:00 2001
+From: Martin Botka <martin.botka@somainline.org>
+Date: Thu, 18 Apr 2024 16:44:06 +0100
+Subject: [PATCH] cpufreq: sun50i: Add H616 support
+
+The Allwinner H616/H618 SoCs have different OPP tables per SoC version
+and die revision. The SoC version is stored in NVMEM, as before, though
+encoded differently. The die revision is in a different register, in the
+SRAM controller. Firmware already exports that value in a standardised
+way, through the SMCCC SoCID mechanism. We need both values, as some chips
+have the same SoC version, but they don't support the same frequencies and
+they get differentiated by the die revision.
+
+Add the new compatible string and tie the new translation function to
+it. This mechanism not only covers the original H616 SoC, but also its
+very close sibling SoCs H618 and H700, so add them to the list as well.
+
+Signed-off-by: Martin Botka <martin.botka@somainline.org>
+Signed-off-by: Andre Przywara <andre.przywara@arm.com>
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+---
+ drivers/cpufreq/sun50i-cpufreq-nvmem.c | 67 ++++++++++++++++++++++++++
+ 1 file changed, 67 insertions(+)
+
+--- a/drivers/cpufreq/sun50i-cpufreq-nvmem.c
++++ b/drivers/cpufreq/sun50i-cpufreq-nvmem.c
+@@ -10,6 +10,7 @@
+
+ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
++#include <linux/arm-smccc.h>
+ #include <linux/cpu.h>
+ #include <linux/module.h>
+ #include <linux/nvmem-consumer.h>
+@@ -46,14 +47,77 @@ static u32 sun50i_h6_efuse_xlate(u32 spe
+ return 0;
+ }
+
++static int get_soc_id_revision(void)
++{
++#ifdef CONFIG_HAVE_ARM_SMCCC_DISCOVERY
++ return arm_smccc_get_soc_id_revision();
++#else
++ return SMCCC_RET_NOT_SUPPORTED;
++#endif
++}
++
++/*
++ * Judging by the OPP tables in the vendor BSP, the quality order of the
++ * returned speedbin index is 4 -> 0/2 -> 3 -> 1, from worst to best.
++ * 0 and 2 seem identical from the OPP tables' point of view.
++ */
++static u32 sun50i_h616_efuse_xlate(u32 speedbin)
++{
++ int ver_bits = get_soc_id_revision();
++ u32 value = 0;
++
++ switch (speedbin & 0xffff) {
++ case 0x2000:
++ value = 0;
++ break;
++ case 0x2400:
++ case 0x7400:
++ case 0x2c00:
++ case 0x7c00:
++ if (ver_bits != SMCCC_RET_NOT_SUPPORTED && ver_bits <= 1) {
++ /* ic version A/B */
++ value = 1;
++ } else {
++ /* ic version C and later version */
++ value = 2;
++ }
++ break;
++ case 0x5000:
++ case 0x5400:
++ case 0x6000:
++ value = 3;
++ break;
++ case 0x5c00:
++ value = 4;
++ break;
++ case 0x5d00:
++ value = 0;
++ break;
++ default:
++ pr_warn("sun50i-cpufreq-nvmem: unknown speed bin 0x%x, using default bin 0\n",
++ speedbin & 0xffff);
++ value = 0;
++ break;
++ }
++
++ return value;
++}
++
+ static struct sunxi_cpufreq_data sun50i_h6_cpufreq_data = {
+ .efuse_xlate = sun50i_h6_efuse_xlate,
+ };
+
++static struct sunxi_cpufreq_data sun50i_h616_cpufreq_data = {
++ .efuse_xlate = sun50i_h616_efuse_xlate,
++};
++
+ static const struct of_device_id cpu_opp_match_list[] = {
+ { .compatible = "allwinner,sun50i-h6-operating-points",
+ .data = &sun50i_h6_cpufreq_data,
+ },
++ { .compatible = "allwinner,sun50i-h616-operating-points",
++ .data = &sun50i_h616_cpufreq_data,
++ },
+ {}
+ };
+
+@@ -230,6 +294,9 @@ static struct platform_driver sun50i_cpu
+
+ static const struct of_device_id sun50i_cpufreq_match_list[] = {
+ { .compatible = "allwinner,sun50i-h6" },
++ { .compatible = "allwinner,sun50i-h616" },
++ { .compatible = "allwinner,sun50i-h618" },
++ { .compatible = "allwinner,sun50i-h700" },
+ {}
+ };
+ MODULE_DEVICE_TABLE(of, sun50i_cpufreq_match_list);
diff --git a/target/linux/sunxi/patches-6.6/022-v6.10-arm64-dts-allwinner-h616-Add-CPU-OPPs-table.patch b/target/linux/sunxi/patches-6.6/022-v6.10-arm64-dts-allwinner-h616-Add-CPU-OPPs-table.patch
new file mode 100644
index 0000000000..4665286d0f
--- /dev/null
+++ b/target/linux/sunxi/patches-6.6/022-v6.10-arm64-dts-allwinner-h616-Add-CPU-OPPs-table.patch
@@ -0,0 +1,188 @@
+From 3e057e05b3b281bcc29db573eb51f87ee6b5afc0 Mon Sep 17 00:00:00 2001
+From: Martin Botka <martin.botka@somainline.org>
+Date: Thu, 18 Apr 2024 16:44:07 +0100
+Subject: [PATCH] arm64: dts: allwinner: h616: Add CPU OPPs table
+
+Add an Operating Performance Points table for the CPU cores to enable
+Dynamic Voltage & Frequency Scaling (DVFS) on the H616.
+The values were taken from the BSP sources. There is a separate OPP set
+seen on some H700 devices, but they didn't really work out in testing, so
+they are not included for now.
+
+Also add the needed cpu_speed_grade nvmem cell and the cooling cells
+properties, to enable passive cooling.
+
+Signed-off-by: Martin Botka <martin.botka@somainline.org>
+[Andre: rework to minimise opp-microvolt properties]
+Signed-off-by: Andre Przywara <andre.przywara@arm.com>
+Acked-by: Jernej Skrabec <jernej.skrabec@gmail.com>
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+---
+ .../dts/allwinner/sun50i-h616-cpu-opp.dtsi | 115 ++++++++++++++++++
+ .../arm64/boot/dts/allwinner/sun50i-h616.dtsi | 8 ++
+ 2 files changed, 123 insertions(+)
+ create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h616-cpu-opp.dtsi
+
+--- /dev/null
++++ b/arch/arm64/boot/dts/allwinner/sun50i-h616-cpu-opp.dtsi
+@@ -0,0 +1,115 @@
++// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
++// Copyright (C) 2023 Martin Botka <martin@somainline.org>
++
++/ {
++ cpu_opp_table: opp-table-cpu {
++ compatible = "allwinner,sun50i-h616-operating-points";
++ nvmem-cells = <&cpu_speed_grade>;
++ opp-shared;
++
++ opp-480000000 {
++ opp-hz = /bits/ 64 <480000000>;
++ opp-microvolt = <900000>;
++ clock-latency-ns = <244144>; /* 8 32k periods */
++ opp-supported-hw = <0x1f>;
++ };
++
++ opp-600000000 {
++ opp-hz = /bits/ 64 <600000000>;
++ opp-microvolt = <900000>;
++ clock-latency-ns = <244144>; /* 8 32k periods */
++ opp-supported-hw = <0x12>;
++ };
++
++ opp-720000000 {
++ opp-hz = /bits/ 64 <720000000>;
++ opp-microvolt = <900000>;
++ clock-latency-ns = <244144>; /* 8 32k periods */
++ opp-supported-hw = <0x0d>;
++ };
++
++ opp-792000000 {
++ opp-hz = /bits/ 64 <792000000>;
++ opp-microvolt-speed1 = <900000>;
++ opp-microvolt-speed4 = <940000>;
++ clock-latency-ns = <244144>; /* 8 32k periods */
++ opp-supported-hw = <0x12>;
++ };
++
++ opp-936000000 {
++ opp-hz = /bits/ 64 <936000000>;
++ opp-microvolt = <900000>;
++ clock-latency-ns = <244144>; /* 8 32k periods */
++ opp-supported-hw = <0x0d>;
++ };
++
++ opp-1008000000 {
++ opp-hz = /bits/ 64 <1008000000>;
++ opp-microvolt-speed0 = <950000>;
++ opp-microvolt-speed1 = <940000>;
++ opp-microvolt-speed2 = <950000>;
++ opp-microvolt-speed3 = <950000>;
++ opp-microvolt-speed4 = <1020000>;
++ clock-latency-ns = <244144>; /* 8 32k periods */
++ opp-supported-hw = <0x1f>;
++ };
++
++ opp-1104000000 {
++ opp-hz = /bits/ 64 <1104000000>;
++ opp-microvolt-speed0 = <1000000>;
++ opp-microvolt-speed2 = <1000000>;
++ opp-microvolt-speed3 = <1000000>;
++ clock-latency-ns = <244144>; /* 8 32k periods */
++ opp-supported-hw = <0x0d>;
++ };
++
++ opp-1200000000 {
++ opp-hz = /bits/ 64 <1200000000>;
++ opp-microvolt-speed0 = <1050000>;
++ opp-microvolt-speed1 = <1020000>;
++ opp-microvolt-speed2 = <1050000>;
++ opp-microvolt-speed3 = <1050000>;
++ opp-microvolt-speed4 = <1100000>;
++ clock-latency-ns = <244144>; /* 8 32k periods */
++ opp-supported-hw = <0x1f>;
++ };
++
++ opp-1320000000 {
++ opp-hz = /bits/ 64 <1320000000>;
++ opp-microvolt = <1100000>;
++ clock-latency-ns = <244144>; /* 8 32k periods */
++ opp-supported-hw = <0x1d>;
++ };
++
++ opp-1416000000 {
++ opp-hz = /bits/ 64 <1416000000>;
++ opp-microvolt = <1100000>;
++ clock-latency-ns = <244144>; /* 8 32k periods */
++ opp-supported-hw = <0x0d>;
++ };
++
++ opp-1512000000 {
++ opp-hz = /bits/ 64 <1512000000>;
++ opp-microvolt-speed1 = <1100000>;
++ opp-microvolt-speed3 = <1100000>;
++ clock-latency-ns = <244144>; /* 8 32k periods */
++ opp-supported-hw = <0x0a>;
++ };
++ };
++};
++
++&cpu0 {
++ operating-points-v2 = <&cpu_opp_table>;
++};
++
++&cpu1 {
++ operating-points-v2 = <&cpu_opp_table>;
++};
++
++&cpu2 {
++ operating-points-v2 = <&cpu_opp_table>;
++};
++
++&cpu3 {
++ operating-points-v2 = <&cpu_opp_table>;
++};
+--- a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
++++ b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
+@@ -26,6 +26,7 @@
+ reg = <0>;
+ enable-method = "psci";
+ clocks = <&ccu CLK_CPUX>;
++ #cooling-cells = <2>;
+ };
+
+ cpu1: cpu@1 {
+@@ -34,6 +35,7 @@
+ reg = <1>;
+ enable-method = "psci";
+ clocks = <&ccu CLK_CPUX>;
++ #cooling-cells = <2>;
+ };
+
+ cpu2: cpu@2 {
+@@ -42,6 +44,7 @@
+ reg = <2>;
+ enable-method = "psci";
+ clocks = <&ccu CLK_CPUX>;
++ #cooling-cells = <2>;
+ };
+
+ cpu3: cpu@3 {
+@@ -50,6 +53,7 @@
+ reg = <3>;
+ enable-method = "psci";
+ clocks = <&ccu CLK_CPUX>;
++ #cooling-cells = <2>;
+ };
+ };
+
+@@ -143,6 +147,10 @@
+ ths_calibration: thermal-sensor-calibration@14 {
+ reg = <0x14 0x8>;
+ };
++
++ cpu_speed_grade: cpu-speed-grade@0 {
++ reg = <0x0 2>;
++ };
+ };
+
+ watchdog: watchdog@30090a0 {
diff --git a/target/linux/sunxi/patches-6.6/023-v6.10-arm64-dts-allwinner-h616-enable-DVFS-for-all-boards.patch b/target/linux/sunxi/patches-6.6/023-v6.10-arm64-dts-allwinner-h616-enable-DVFS-for-all-boards.patch
new file mode 100644
index 0000000000..8c91184117
--- /dev/null
+++ b/target/linux/sunxi/patches-6.6/023-v6.10-arm64-dts-allwinner-h616-enable-DVFS-for-all-boards.patch
@@ -0,0 +1,86 @@
+From 09d0aaa0ae9c80ff9569393b206226c1008801b1 Mon Sep 17 00:00:00 2001
+From: Andre Przywara <andre.przywara@arm.com>
+Date: Thu, 18 Apr 2024 16:44:08 +0100
+Subject: [PATCH] arm64: dts: allwinner: h616: enable DVFS for all boards
+
+With the DT bindings now describing the format of the CPU OPP tables, we
+can include the OPP table in each board's .dts file, and specify the CPU
+power supply.
+This allows to enable DVFS, and get up to 50% of performance benefit in
+the highest OPP, or up to 60% power savings in the lowest OPP, compared
+to the fixed 1GHz @ 1.0V OPP we are running in by default at the moment.
+
+Signed-off-by: Andre Przywara <andre.przywara@arm.com>
+Acked-by: Jernej Skrabec <jernej.skrabec@gmail.com>
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+---
+ .../boot/dts/allwinner/sun50i-h616-bigtreetech-cb1.dtsi | 5 +++++
+ arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero2.dts | 5 +++++
+ arch/arm64/boot/dts/allwinner/sun50i-h616-x96-mate.dts | 5 +++++
+ .../boot/dts/allwinner/sun50i-h618-longan-module-3h.dtsi | 5 +++++
+ .../arm64/boot/dts/allwinner/sun50i-h618-orangepi-zero2w.dts | 5 +++++
+ arch/arm64/boot/dts/allwinner/sun50i-h618-orangepi-zero3.dts | 5 +++++
+ .../boot/dts/allwinner/sun50i-h618-transpeed-8k618-t.dts | 5 +++++
+ 7 files changed, 35 insertions(+)
+
+--- a/arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero2.dts
++++ b/arch/arm64/boot/dts/allwinner/sun50i-h616-orangepi-zero2.dts
+@@ -6,12 +6,17 @@
+ /dts-v1/;
+
+ #include "sun50i-h616-orangepi-zero.dtsi"
++#include "sun50i-h616-cpu-opp.dtsi"
+
+ / {
+ model = "OrangePi Zero2";
+ compatible = "xunlong,orangepi-zero2", "allwinner,sun50i-h616";
+ };
+
++&cpu0 {
++ cpu-supply = <&reg_dcdca>;
++};
++
+ &emac0 {
+ allwinner,rx-delay-ps = <3100>;
+ allwinner,tx-delay-ps = <700>;
+--- a/arch/arm64/boot/dts/allwinner/sun50i-h616-x96-mate.dts
++++ b/arch/arm64/boot/dts/allwinner/sun50i-h616-x96-mate.dts
+@@ -6,6 +6,7 @@
+ /dts-v1/;
+
+ #include "sun50i-h616.dtsi"
++#include "sun50i-h616-cpu-opp.dtsi"
+
+ #include <dt-bindings/gpio/gpio.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+@@ -32,6 +33,10 @@
+ };
+ };
+
++&cpu0 {
++ cpu-supply = <&reg_dcdca>;
++};
++
+ &ehci0 {
+ status = "okay";
+ };
+--- a/arch/arm64/boot/dts/allwinner/sun50i-h618-orangepi-zero3.dts
++++ b/arch/arm64/boot/dts/allwinner/sun50i-h618-orangepi-zero3.dts
+@@ -6,12 +6,17 @@
+ /dts-v1/;
+
+ #include "sun50i-h616-orangepi-zero.dtsi"
++#include "sun50i-h616-cpu-opp.dtsi"
+
+ / {
+ model = "OrangePi Zero3";
+ compatible = "xunlong,orangepi-zero3", "allwinner,sun50i-h618";
+ };
+
++&cpu0 {
++ cpu-supply = <&reg_dcdc2>;
++};
++
+ &emac0 {
+ allwinner,tx-delay-ps = <700>;
+ phy-mode = "rgmii-rxid";
diff --git a/target/linux/sunxi/patches-6.6/024-v6.10-cpufreq-sun50i-Fix-build-warning-around-snprint.patch b/target/linux/sunxi/patches-6.6/024-v6.10-cpufreq-sun50i-Fix-build-warning-around-snprint.patch
new file mode 100644
index 0000000000..8bfd6c2d09
--- /dev/null
+++ b/target/linux/sunxi/patches-6.6/024-v6.10-cpufreq-sun50i-Fix-build-warning-around-snprint.patch
@@ -0,0 +1,51 @@
+From d2059d3b548409905b20b4f52495bffbd7c8da8b Mon Sep 17 00:00:00 2001
+From: Viresh Kumar <viresh.kumar@linaro.org>
+Date: Mon, 22 Apr 2024 08:58:51 +0530
+Subject: [PATCH] cpufreq: sun50i: Fix build warning around snprint()
+
+The Sun50i driver generates a warning with W=1:
+
+warning: '%d' directive output may be truncated writing between 1 and 10 bytes into a region of size 2 [-Wformat-truncation=]
+
+Fix it by allocating a big enough array to print an integer.
+
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202404191715.LDwMm2gP-lkp@intel.com/
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+Acked-by: Chen-Yu Tsai <wens@csie.org>
+Reviewed-by: Andre Przywara <andre.przywara@arm.com>
+Tested-by: Andre Przywara <andre.przywara@arm.com>
+Reviewed-by: Julian Calaby <julian.calaby@gmail.com>
+---
+ drivers/cpufreq/sun50i-cpufreq-nvmem.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+--- a/drivers/cpufreq/sun50i-cpufreq-nvmem.c
++++ b/drivers/cpufreq/sun50i-cpufreq-nvmem.c
+@@ -19,8 +19,6 @@
+ #include <linux/pm_opp.h>
+ #include <linux/slab.h>
+
+-#define MAX_NAME_LEN 7
+-
+ #define NVMEM_MASK 0x7
+ #define NVMEM_SHIFT 5
+
+@@ -208,7 +206,7 @@ static int sun50i_cpufreq_get_efuse(void
+ static int sun50i_cpufreq_nvmem_probe(struct platform_device *pdev)
+ {
+ int *opp_tokens;
+- char name[MAX_NAME_LEN];
++ char name[] = "speedXXXXXXXXXXX"; /* Integers can take 11 chars max */
+ unsigned int cpu, supported_hw;
+ struct dev_pm_opp_config config = {};
+ int speed;
+@@ -235,7 +233,7 @@ static int sun50i_cpufreq_nvmem_probe(st
+ config.supported_hw_count = 1;
+ }
+
+- snprintf(name, MAX_NAME_LEN, "speed%d", speed);
++ snprintf(name, sizeof(name), "speed%d", speed);
+ config.prop_name = name;
+
+ for_each_possible_cpu(cpu) {
diff --git a/target/linux/sunxi/patches-6.6/025-v6.10-cpufreq-sun50i-fix-error-returns-in-dt_has_supported_hw.patch b/target/linux/sunxi/patches-6.6/025-v6.10-cpufreq-sun50i-fix-error-returns-in-dt_has_supported_hw.patch
new file mode 100644
index 0000000000..2304a6af79
--- /dev/null
+++ b/target/linux/sunxi/patches-6.6/025-v6.10-cpufreq-sun50i-fix-error-returns-in-dt_has_supported_hw.patch
@@ -0,0 +1,34 @@
+From 76a6fc5644b2a1c70868bec24a078f784600ef2a Mon Sep 17 00:00:00 2001
+From: Dan Carpenter <dan.carpenter@linaro.org>
+Date: Wed, 24 Apr 2024 14:40:11 +0300
+Subject: [PATCH] cpufreq: sun50i: fix error returns in dt_has_supported_hw()
+
+The dt_has_supported_hw() function returns type bool. That means these
+negative error codes are cast to true but the function should return
+false instead.
+
+Fixes: fa5aec9561cf ("cpufreq: sun50i: Add support for opp_supported_hw")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Reviewed-by: Andre Przywara <andre.przywara@arm.com>
+Reviewed-by: Jernej Skrabec <jernej.skrabec@gmail.com>
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+---
+ drivers/cpufreq/sun50i-cpufreq-nvmem.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/cpufreq/sun50i-cpufreq-nvmem.c
++++ b/drivers/cpufreq/sun50i-cpufreq-nvmem.c
+@@ -136,11 +136,11 @@ static bool dt_has_supported_hw(void)
+
+ cpu_dev = get_cpu_device(0);
+ if (!cpu_dev)
+- return -ENODEV;
++ return false;
+
+ np = dev_pm_opp_of_get_opp_desc_node(cpu_dev);
+ if (!np)
+- return -ENOENT;
++ return false;
+
+ for_each_child_of_node(np, opp) {
+ if (of_find_property(opp, "opp-supported-hw", NULL)) {
diff --git a/target/linux/sunxi/patches-6.6/410-sunxi-add-bananapi-p2-zero.patch b/target/linux/sunxi/patches-6.6/410-sunxi-add-bananapi-p2-zero.patch
index 350d7f0403..f605292dcd 100644
--- a/target/linux/sunxi/patches-6.6/410-sunxi-add-bananapi-p2-zero.patch
+++ b/target/linux/sunxi/patches-6.6/410-sunxi-add-bananapi-p2-zero.patch
@@ -1,6 +1,6 @@
--- a/arch/arm/boot/dts/allwinner/Makefile
+++ b/arch/arm/boot/dts/allwinner/Makefile
-@@ -280,6 +280,7 @@ dtb-$(CONFIG_MACH_SUN8I) += \
+@@ -219,6 +219,7 @@ dtb-$(CONFIG_MACH_SUN8I) += \
sun8i-a83t-cubietruck-plus.dtb \
sun8i-a83t-tbs-a711.dtb \
sun8i-h2-plus-bananapi-m2-zero.dtb \
diff --git a/target/linux/sunxi/patches-6.6/451-sunxi-add-csi-video-support-for-nanopi-neo-air.patch b/target/linux/sunxi/patches-6.6/451-sunxi-add-csi-video-support-for-nanopi-neo-air.patch
new file mode 100644
index 0000000000..c17d28c691
--- /dev/null
+++ b/target/linux/sunxi/patches-6.6/451-sunxi-add-csi-video-support-for-nanopi-neo-air.patch
@@ -0,0 +1,107 @@
+From 4c3a3af679bd59660ac80889b560bddaf475ba81 Mon Sep 17 00:00:00 2001
+From: Michel Promonet <michel.promonet@free.fr>
+Date: Sun, 21 Jul 2024 19:04:19 +0200
+Subject: [PATCH] sunxi: add csi video support for nanopi-neo-air
+
+---
+ .../dts/allwinner/sun8i-h3-nanopi-neo-air.dts | 85 +++++++++++++++++++
+ 1 file changed, 85 insertions(+)
+
+--- a/arch/arm/boot/dts/allwinner/sun8i-h3-nanopi-neo-air.dts
++++ b/arch/arm/boot/dts/allwinner/sun8i-h3-nanopi-neo-air.dts
+@@ -77,6 +77,39 @@
+ compatible = "mmc-pwrseq-simple";
+ reset-gpios = <&r_pio 0 7 GPIO_ACTIVE_LOW>; /* PL7 */
+ };
++
++ cam_xclk: cam-xclk {
++ #clock-cells = <0>;
++ compatible = "fixed-clock";
++ clock-frequency = <24000000>;
++ clock-output-names = "cam-xclk";
++ };
++
++ reg_cam_avdd: cam-avdd {
++ compatible = "regulator-fixed";
++ regulator-name = "cam-avdd";
++ regulator-min-microvolt = <2800000>;
++ regulator-max-microvolt = <2800000>;
++ vin-supply = <&reg_vcc3v3>;
++ };
++
++ reg_cam_dovdd: cam-dovdd {
++ compatible = "regulator-fixed";
++ regulator-name = "cam-dovdd";
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ vin-supply = <&reg_vcc3v3>;
++ };
++
++ reg_cam_dvdd: cam-dvdd {
++ compatible = "regulator-fixed";
++ regulator-name = "cam-dvdd";
++ regulator-min-microvolt = <1500000>;
++ regulator-max-microvolt = <1500000>;
++ vin-supply = <&reg_vcc3v3>;
++ };
++
++
+ };
+
+ &mmc0 {
+@@ -141,3 +174,55 @@
+ /* USB VBUS is always on */
+ status = "okay";
+ };
++
++&csi {
++ status = "okay";
++
++ port {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ /* Parallel bus endpoint */
++ csi_from_ov5640: endpoint {
++ remote-endpoint = <&ov5640_to_csi>;
++ bus-width = <8>;
++ data-shift = <2>;
++ hsync-active = <1>; /* Active high */
++ vsync-active = <0>; /* Active low */
++ data-active = <1>; /* Active high */
++ pclk-sample = <1>; /* Rising */
++ };
++ };
++};
++
++&i2c2 {
++ status = "okay";
++
++ ov5640: camera@3c {
++ compatible = "ovti,ov5640";
++ reg = <0x3c>;
++ clocks = <&cam_xclk>;
++ clock-names = "xclk";
++
++ reset-gpios = <&pio 4 14 GPIO_ACTIVE_LOW>;
++ powerdown-gpios = <&pio 4 15 GPIO_ACTIVE_HIGH>;
++ AVDD-supply = <&reg_cam_avdd>;
++ DOVDD-supply = <&reg_cam_dovdd>;
++ DVDD-supply = <&reg_cam_dvdd>;
++
++ port {
++ ov5640_to_csi: endpoint {
++ remote-endpoint = <&csi_from_ov5640>;
++ bus-width = <8>;
++ data-shift = <2>;
++ hsync-active = <1>; /* Active high */
++ vsync-active = <0>; /* Active low */
++ data-active = <1>; /* Active high */
++ pclk-sample = <1>; /* Rising */
++ };
++ };
++ };
++};
++&i2c2_pins {
++ bias-pull-up;
++};
diff --git a/target/linux/x86/64/config-6.6 b/target/linux/x86/64/config-6.6
index d5f86141b0..b443231120 100644
--- a/target/linux/x86/64/config-6.6
+++ b/target/linux/x86/64/config-6.6
@@ -255,7 +255,10 @@ CONFIG_HALTPOLL_CPUIDLE=y
CONFIG_HARDLOCKUP_CHECK_TIMESTAMP=y
CONFIG_HDMI=y
CONFIG_HIBERNATE_CALLBACKS=y
+CONFIG_HID=y
+CONFIG_HID_GENERIC=y
CONFIG_HID_HYPERV_MOUSE=y
+CONFIG_HID_SUPPORT=y
CONFIG_HOTPLUG_CORE_SYNC=y
CONFIG_HOTPLUG_CORE_SYNC_DEAD=y
CONFIG_HOTPLUG_CORE_SYNC_FULL=y
@@ -540,6 +543,8 @@ CONFIG_TREE_SRCU=y
CONFIG_UCS2_STRING=y
CONFIG_UNACCEPTED_MEMORY=y
# CONFIG_UNWINDER_ORC is not set
+CONFIG_USB_HID=y
+CONFIG_USB_HIDDEV=y
CONFIG_USB_STORAGE=y
CONFIG_VIDEO_CMDLINE=y
# CONFIG_VIDEO_IPU3_CIO2 is not set
diff --git a/target/linux/x86/base-files/etc/board.d/02_network b/target/linux/x86/base-files/etc/board.d/02_network
index 5174906264..c4c2d3fa21 100644
--- a/target/linux/x86/base-files/etc/board.d/02_network
+++ b/target/linux/x86/base-files/etc/board.d/02_network
@@ -31,6 +31,9 @@ cisco-mx100-hw)
ucidef_set_network_device_path "eth11" "pci0000:00/0000:00:01.1/0000:02:00.2"
ucidef_set_interfaces_lan_wan "mgmt eth2 eth3 eth4 eth5 eth6 eth7 eth8 eth9 eth10 eth11" "wan"
;;
+dell-emc-edge620)
+ ucidef_set_interfaces_lan_wan "eth0 eth1 eth2 eth3 eth7" "eth6"
+ ;;
pc-engines-apu1|pc-engines-apu2|pc-engines-apu3)
ucidef_set_interfaces_lan_wan "eth1 eth2" "eth0"
;;
diff --git a/target/linux/x86/generic/config-6.6 b/target/linux/x86/generic/config-6.6
index 4c0a052c7b..6729f0e9cd 100644
--- a/target/linux/x86/generic/config-6.6
+++ b/target/linux/x86/generic/config-6.6
@@ -182,7 +182,10 @@ CONFIG_GUP_GET_PXX_LOW_HIGH=y
CONFIG_HALTPOLL_CPUIDLE=y
CONFIG_HDMI=y
CONFIG_HIBERNATE_CALLBACKS=y
+CONFIG_HID=y
+CONFIG_HID_GENERIC=y
CONFIG_HID_HYPERV_MOUSE=y
+CONFIG_HID_SUPPORT=y
# CONFIG_HIGHMEM4G is not set
CONFIG_HIGHMEM64G=y
CONFIG_HOTPLUG_CORE_SYNC=y
@@ -449,6 +452,8 @@ CONFIG_TREE_RCU=y
CONFIG_TREE_SRCU=y
# CONFIG_UCLAMP_TASK is not set
CONFIG_UCS2_STRING=y
+CONFIG_USB_HID=y
+CONFIG_USB_HIDDEV=y
CONFIG_USB_STORAGE=y
CONFIG_USER_RETURN_NOTIFIER=y
CONFIG_VHOST=y
diff --git a/target/linux/x86/image/Makefile b/target/linux/x86/image/Makefile
index 6e59f2e465..29bebeb748 100644
--- a/target/linux/x86/image/Makefile
+++ b/target/linux/x86/image/Makefile
@@ -12,7 +12,7 @@ GRUB_TERMINAL_CONFIG =
GRUB_CONSOLE_CMDLINE =
ifneq ($(CONFIG_GRUB_CONSOLE),)
- GRUB_CONSOLE_CMDLINE += console=tty0
+ GRUB_CONSOLE_CMDLINE += console=tty1
GRUB_TERMINALS += console
endif
diff --git a/target/linux/x86/legacy/config-6.6 b/target/linux/x86/legacy/config-6.6
index 323f20dba6..d5c4a55e5e 100644
--- a/target/linux/x86/legacy/config-6.6
+++ b/target/linux/x86/legacy/config-6.6
@@ -133,6 +133,9 @@ CONFIG_FUNCTION_PADDING_CFI=0
# CONFIG_GIGABYTE_WMI is not set
CONFIG_GPIO_ACPI=y
CONFIG_HDMI=y
+CONFIG_HID=y
+CONFIG_HID_GENERIC=y
+CONFIG_HID_SUPPORT=y
# CONFIG_HIGHMEM4G is not set
CONFIG_HPET=y
CONFIG_HPET_MMAP=y
@@ -253,6 +256,8 @@ CONFIG_SYNC_FILE=y
# CONFIG_THINKPAD_LMI is not set
# CONFIG_TOSHIBA_BT_RFKILL is not set
# CONFIG_TOSHIBA_WMI is not set
+CONFIG_USB_HID=y
+CONFIG_USB_HIDDEV=y
CONFIG_USB_STORAGE=y
CONFIG_VIDEO_CMDLINE=y
# CONFIG_VIDEO_IPU3_CIO2 is not set
diff --git a/target/linux/zynq/Makefile b/target/linux/zynq/Makefile
index 90e49df878..c570fae73b 100644
--- a/target/linux/zynq/Makefile
+++ b/target/linux/zynq/Makefile
@@ -18,7 +18,7 @@ define Target/Description
Build firmware image for Zynq 7000 SoC devices.
endef
-KERNEL_PATCHVER:=6.1
+KERNEL_PATCHVER:=6.6
include $(INCLUDE_DIR)/target.mk
diff --git a/target/linux/zynq/config-6.1 b/target/linux/zynq/config-6.1
deleted file mode 100644
index b6318a776c..0000000000
--- a/target/linux/zynq/config-6.1
+++ /dev/null
@@ -1,566 +0,0 @@
-CONFIG_ALIGNMENT_TRAP=y
-# CONFIG_ALTERA_FREEZE_BRIDGE is not set
-# CONFIG_ALTERA_PR_IP_CORE is not set
-CONFIG_ARCH_32BIT_OFF_T=y
-CONFIG_ARCH_HIBERNATION_POSSIBLE=y
-CONFIG_ARCH_KEEP_MEMBLOCK=y
-CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
-CONFIG_ARCH_MULTIPLATFORM=y
-CONFIG_ARCH_MULTI_V6_V7=y
-CONFIG_ARCH_MULTI_V7=y
-CONFIG_ARCH_NR_GPIO=1024
-CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y
-CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y
-CONFIG_ARCH_SELECT_MEMORY_MODEL=y
-CONFIG_ARCH_SPARSEMEM_ENABLE=y
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
-CONFIG_ARCH_VEXPRESS=y
-CONFIG_ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA=y
-# CONFIG_ARCH_VEXPRESS_SPC is not set
-CONFIG_ARCH_ZYNQ=y
-CONFIG_ARM=y
-CONFIG_ARM_AMBA=y
-CONFIG_ARM_CPU_SUSPEND=y
-CONFIG_ARM_ERRATA_643719=y
-CONFIG_ARM_ERRATA_720789=y
-CONFIG_ARM_ERRATA_754322=y
-CONFIG_ARM_ERRATA_754327=y
-CONFIG_ARM_ERRATA_764369=y
-CONFIG_ARM_ERRATA_775420=y
-CONFIG_ARM_GIC=y
-CONFIG_ARM_GLOBAL_TIMER=y
-CONFIG_ARM_GT_INITIAL_PRESCALER_VAL=2
-CONFIG_ARM_HAS_GROUP_RELOCS=y
-CONFIG_ARM_HEAVY_MB=y
-CONFIG_ARM_L1_CACHE_SHIFT=6
-CONFIG_ARM_L1_CACHE_SHIFT_6=y
-CONFIG_ARM_PATCH_IDIV=y
-CONFIG_ARM_PATCH_PHYS_VIRT=y
-# CONFIG_ARM_PL172_MPMC is not set
-# CONFIG_ARM_SMMU is not set
-CONFIG_ARM_THUMB=y
-CONFIG_ARM_TIMER_SP804=y
-CONFIG_ARM_UNWIND=y
-CONFIG_ARM_VIRT_EXT=y
-CONFIG_ARM_ZYNQ_CPUIDLE=y
-CONFIG_ATAGS=y
-CONFIG_AUTO_ZRELADDR=y
-# CONFIG_AXI_DMAC is not set
-CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_BLK_DEV_RAM_SIZE=16384
-CONFIG_BLK_MQ_PCI=y
-CONFIG_BLK_PM=y
-CONFIG_BOUNCE=y
-CONFIG_CACHE_L2X0=y
-CONFIG_CADENCE_TTC_TIMER=y
-CONFIG_CADENCE_WATCHDOG=y
-CONFIG_CC_HAVE_STACKPROTECTOR_TLS=y
-CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
-CONFIG_CC_NO_ARRAY_BOUNDS=y
-CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK=y
-CONFIG_CLKSRC_MMIO=y
-CONFIG_CLKSRC_VERSATILE=y
-CONFIG_CLK_ICST=y
-CONFIG_CLK_SP810=y
-CONFIG_CLK_VEXPRESS_OSC=y
-CONFIG_CLONE_BACKWARDS=y
-CONFIG_CMA=y
-CONFIG_CMA_ALIGNMENT=8
-CONFIG_CMA_AREAS=7
-# CONFIG_CMA_DEBUG is not set
-# CONFIG_CMA_DEBUGFS is not set
-CONFIG_CMA_SIZE_MBYTES=16
-# CONFIG_CMA_SIZE_SEL_MAX is not set
-CONFIG_CMA_SIZE_SEL_MBYTES=y
-# CONFIG_CMA_SIZE_SEL_MIN is not set
-# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set
-# CONFIG_CMA_SYSFS is not set
-CONFIG_COMMON_CLK=y
-CONFIG_COMMON_CLK_SI570=y
-CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
-CONFIG_COMPAT_32BIT_TIME=y
-CONFIG_CONNECTOR=y
-CONFIG_CONSOLE_TRANSLATIONS=y
-CONFIG_CONTEXT_TRACKING=y
-CONFIG_CONTEXT_TRACKING_IDLE=y
-CONFIG_CONTIG_ALLOC=y
-CONFIG_COREDUMP=y
-# CONFIG_CPUFREQ_DT is not set
-CONFIG_CPU_32v6K=y
-CONFIG_CPU_32v7=y
-CONFIG_CPU_ABRT_EV7=y
-CONFIG_CPU_CACHE_V7=y
-CONFIG_CPU_CACHE_VIPT=y
-CONFIG_CPU_COPY_V6=y
-CONFIG_CPU_CP15=y
-CONFIG_CPU_CP15_MMU=y
-CONFIG_CPU_FREQ=y
-# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
-CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
-CONFIG_CPU_FREQ_GOV_ATTR_SET=y
-CONFIG_CPU_FREQ_GOV_COMMON=y
-CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
-CONFIG_CPU_FREQ_GOV_ONDEMAND=y
-CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
-CONFIG_CPU_FREQ_GOV_POWERSAVE=y
-CONFIG_CPU_FREQ_GOV_USERSPACE=y
-CONFIG_CPU_FREQ_STAT=y
-CONFIG_CPU_HAS_ASID=y
-CONFIG_CPU_IDLE=y
-CONFIG_CPU_IDLE_GOV_LADDER=y
-CONFIG_CPU_IDLE_GOV_MENU=y
-CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_CPU_PABRT_V7=y
-CONFIG_CPU_PM=y
-CONFIG_CPU_RMAP=y
-CONFIG_CPU_SPECTRE=y
-CONFIG_CPU_THERMAL=y
-CONFIG_CPU_THUMB_CAPABLE=y
-CONFIG_CPU_TLB_V7=y
-CONFIG_CPU_V7=y
-CONFIG_CRC16=y
-# CONFIG_CRC32_SARWATE is not set
-CONFIG_CRC32_SLICEBY8=y
-CONFIG_CROSS_MEMORY_ATTACH=y
-CONFIG_CRYPTO_CRC32=y
-CONFIG_CRYPTO_CRC32C=y
-CONFIG_CRYPTO_HW=y
-CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
-CONFIG_CRYPTO_LIB_SHA1=y
-CONFIG_CRYPTO_LIB_UTILS=y
-CONFIG_CRYPTO_RNG2=y
-CONFIG_CURRENT_POINTER_IN_TPIDRURO=y
-CONFIG_DCACHE_WORD_ACCESS=y
-CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
-CONFIG_DMADEVICES=y
-CONFIG_DMA_CMA=y
-CONFIG_DMA_ENGINE=y
-CONFIG_DMA_OF=y
-CONFIG_DMA_OPS=y
-CONFIG_DMA_SHARED_BUFFER=y
-CONFIG_DRM=y
-CONFIG_DRM_BRIDGE=y
-CONFIG_DRM_NOMODESET=y
-CONFIG_DRM_PANEL=y
-CONFIG_DRM_PANEL_BRIDGE=y
-CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y
-CONFIG_DTC=y
-CONFIG_DUMMY_CONSOLE=y
-CONFIG_E1000E=y
-CONFIG_EDAC=y
-CONFIG_EDAC_ATOMIC_SCRUB=y
-# CONFIG_EDAC_DEBUG is not set
-CONFIG_EDAC_LEGACY_SYSFS=y
-CONFIG_EDAC_SUPPORT=y
-# CONFIG_EDAC_SYNOPSYS is not set
-CONFIG_EEPROM_AT24=y
-CONFIG_EEPROM_AT25=y
-CONFIG_ELF_CORE=y
-CONFIG_EXCLUSIVE_SYSTEM_RAM=y
-CONFIG_EXT4_FS=y
-CONFIG_EXTCON=y
-CONFIG_F2FS_FS=y
-CONFIG_FB=y
-CONFIG_FB_CMDLINE=y
-# CONFIG_FB_XILINX is not set
-CONFIG_FHANDLE=y
-CONFIG_FIXED_PHY=y
-CONFIG_FIX_EARLYCON_MEM=y
-CONFIG_FPGA=y
-CONFIG_FPGA_BRIDGE=y
-# CONFIG_FPGA_DFL is not set
-# CONFIG_FPGA_MGR_ALTERA_CVP is not set
-# CONFIG_FPGA_MGR_ALTERA_PS_SPI is not set
-# CONFIG_FPGA_MGR_ICE40_SPI is not set
-# CONFIG_FPGA_MGR_MACHXO2_SPI is not set
-# CONFIG_FPGA_MGR_MICROCHIP_SPI is not set
-# CONFIG_FPGA_MGR_XILINX_SPI is not set
-CONFIG_FPGA_MGR_ZYNQ_FPGA=y
-CONFIG_FPGA_REGION=y
-CONFIG_FREEZER=y
-CONFIG_FS_IOMAP=y
-CONFIG_FS_MBCACHE=y
-CONFIG_FWNODE_MDIO=y
-CONFIG_FW_CACHE=y
-CONFIG_FW_LOADER_PAGED_BUF=y
-CONFIG_FW_LOADER_SYSFS=y
-CONFIG_GCC10_NO_ARRAY_BOUNDS=y
-CONFIG_GCC_ASM_GOTO_OUTPUT_WORKAROUND=y
-CONFIG_GENERIC_ALLOCATOR=y
-CONFIG_GENERIC_ARCH_TOPOLOGY=y
-CONFIG_GENERIC_BUG=y
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
-CONFIG_GENERIC_CPU_AUTOPROBE=y
-CONFIG_GENERIC_CPU_VULNERABILITIES=y
-CONFIG_GENERIC_EARLY_IOREMAP=y
-CONFIG_GENERIC_GETTIMEOFDAY=y
-CONFIG_GENERIC_IDLE_POLL_SETUP=y
-CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
-CONFIG_GENERIC_IRQ_MIGRATION=y
-CONFIG_GENERIC_IRQ_MULTI_HANDLER=y
-CONFIG_GENERIC_IRQ_SHOW=y
-CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
-CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y
-CONFIG_GENERIC_MSI_IRQ=y
-CONFIG_GENERIC_MSI_IRQ_DOMAIN=y
-CONFIG_GENERIC_PCI_IOMAP=y
-CONFIG_GENERIC_PINCONF=y
-CONFIG_GENERIC_SCHED_CLOCK=y
-CONFIG_GENERIC_SMP_IDLE_THREAD=y
-CONFIG_GENERIC_STRNCPY_FROM_USER=y
-CONFIG_GENERIC_STRNLEN_USER=y
-CONFIG_GENERIC_TIME_VSYSCALL=y
-CONFIG_GENERIC_VDSO_32=y
-CONFIG_GLOB=y
-CONFIG_GPIOLIB_IRQCHIP=y
-CONFIG_GPIO_CDEV=y
-CONFIG_GPIO_GENERIC=y
-CONFIG_GPIO_GENERIC_PLATFORM=y
-CONFIG_GPIO_ZYNQ=y
-CONFIG_HARDEN_BRANCH_PREDICTOR=y
-CONFIG_HARDIRQS_SW_RESEND=y
-CONFIG_HAS_DMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAVE_SMP=y
-CONFIG_HDMI=y
-CONFIG_HID=y
-CONFIG_HID_GENERIC=y
-CONFIG_HID_MICROSOFT=y
-CONFIG_HIGHMEM=y
-CONFIG_HIGHPTE=y
-CONFIG_HOTPLUG_CPU=y
-CONFIG_HWMON=y
-CONFIG_HW_CONSOLE=y
-CONFIG_HZ_FIXED=0
-CONFIG_I2C=y
-CONFIG_I2C_ALGOBIT=y
-CONFIG_I2C_BOARDINFO=y
-CONFIG_I2C_CADENCE=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_COMPAT=y
-CONFIG_I2C_HELPER_AUTO=y
-CONFIG_I2C_MUX=y
-CONFIG_I2C_MUX_PCA954x=y
-CONFIG_IIO=y
-CONFIG_IIO_BUFFER=y
-CONFIG_IIO_KFIFO_BUF=y
-CONFIG_IIO_TRIGGER=y
-CONFIG_IIO_TRIGGERED_BUFFER=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_INPUT=y
-CONFIG_INPUT_EVDEV=y
-CONFIG_INPUT_FF_MEMLESS=y
-CONFIG_INPUT_KEYBOARD=y
-CONFIG_INPUT_MOUSE=y
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-CONFIG_INPUT_SPARSEKMAP=y
-CONFIG_INPUT_VIVALDIFMAP=y
-# CONFIG_IOMMU_DEBUGFS is not set
-# CONFIG_IOMMU_IO_PGTABLE_ARMV7S is not set
-# CONFIG_IOMMU_IO_PGTABLE_LPAE is not set
-CONFIG_IOMMU_SUPPORT=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_BOOTP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_RARP=y
-CONFIG_IRQCHIP=y
-CONFIG_IRQSTACKS=y
-CONFIG_IRQ_DOMAIN=y
-CONFIG_IRQ_DOMAIN_HIERARCHY=y
-CONFIG_IRQ_FORCED_THREADING=y
-CONFIG_IRQ_WORK=y
-# CONFIG_ISDN is not set
-CONFIG_JBD2=y
-# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
-CONFIG_JFFS2_ZLIB=y
-CONFIG_KCMP=y
-CONFIG_KERNEL_GZIP=y
-# CONFIG_KERNEL_XZ is not set
-CONFIG_KEYBOARD_ATKBD=y
-CONFIG_KEYBOARD_GPIO=y
-CONFIG_KEYBOARD_GPIO_POLLED=y
-CONFIG_KMAP_LOCAL=y
-CONFIG_KMAP_LOCAL_NON_LINEAR_PTE_ARRAY=y
-CONFIG_LEDS_GPIO=y
-CONFIG_LEDS_TRIGGER_BACKLIGHT=y
-CONFIG_LEDS_TRIGGER_CAMERA=y
-CONFIG_LEDS_TRIGGER_CPU=y
-CONFIG_LEDS_TRIGGER_GPIO=y
-CONFIG_LEDS_TRIGGER_ONESHOT=y
-CONFIG_LEDS_TRIGGER_TRANSIENT=y
-CONFIG_LIBFDT=y
-CONFIG_LOCK_DEBUGGING_SUPPORT=y
-CONFIG_LOCK_SPIN_ON_OWNER=y
-CONFIG_MACB=y
-# CONFIG_MACB_PCI is not set
-CONFIG_MACB_USE_HWSTAMP=y
-CONFIG_MARVELL_PHY=y
-CONFIG_MDIO_BITBANG=y
-CONFIG_MDIO_BUS=y
-CONFIG_MDIO_DEVICE=y
-CONFIG_MDIO_DEVRES=y
-# CONFIG_MDIO_GPIO is not set
-CONFIG_MEMFD_CREATE=y
-CONFIG_MEMORY=y
-CONFIG_MEMORY_ISOLATION=y
-CONFIG_MFD_CORE=y
-CONFIG_MFD_SYSCON=y
-CONFIG_MFD_VEXPRESS_SYSREG=y
-CONFIG_MIGHT_HAVE_CACHE_L2X0=y
-CONFIG_MIGRATION=y
-CONFIG_MMC=y
-CONFIG_MMC_BLOCK=y
-CONFIG_MMC_CQHCI=y
-CONFIG_MMC_SDHCI=y
-CONFIG_MMC_SDHCI_OF_ARASAN=y
-# CONFIG_MMC_SDHCI_PCI is not set
-CONFIG_MMC_SDHCI_PLTFM=y
-CONFIG_MODULES_USE_ELF_REL=y
-CONFIG_MODULE_FORCE_UNLOAD=y
-# CONFIG_MODULE_STRIPPED is not set
-# CONFIG_MOUSE_BCM5974 is not set
-# CONFIG_MOUSE_CYAPA is not set
-CONFIG_MOUSE_PS2=y
-CONFIG_MOUSE_PS2_ALPS=y
-CONFIG_MOUSE_PS2_BYD=y
-CONFIG_MOUSE_PS2_CYPRESS=y
-# CONFIG_MOUSE_PS2_ELANTECH is not set
-CONFIG_MOUSE_PS2_FOCALTECH=y
-CONFIG_MOUSE_PS2_LOGIPS2PP=y
-CONFIG_MOUSE_PS2_SMBUS=y
-CONFIG_MOUSE_PS2_SYNAPTICS=y
-CONFIG_MOUSE_PS2_SYNAPTICS_SMBUS=y
-# CONFIG_MOUSE_PS2_TOUCHKIT is not set
-CONFIG_MOUSE_PS2_TRACKPOINT=y
-# CONFIG_MOUSE_SERIAL is not set
-# CONFIG_MOUSE_VSXXXAA is not set
-# CONFIG_MTD_CFI_INTELEXT is not set
-CONFIG_MTD_CMDLINE_PARTS=y
-# CONFIG_MTD_COMPLEX_MAPPINGS is not set
-CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_SPI_NOR=y
-CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y
-CONFIG_MTD_SPLIT_FIRMWARE=y
-# CONFIG_MTD_SPLIT_SQUASHFS_ROOT is not set
-CONFIG_MUTEX_SPIN_ON_OWNER=y
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NEON=y
-CONFIG_NET_FLOW_LIMIT=y
-CONFIG_NET_PTP_CLASSIFY=y
-CONFIG_NET_SELFTESTS=y
-# CONFIG_NET_VENDOR_CIRRUS is not set
-# CONFIG_NET_VENDOR_FARADAY is not set
-# CONFIG_NET_VENDOR_MARVELL is not set
-# CONFIG_NET_VENDOR_MICREL is not set
-# CONFIG_NET_VENDOR_MICROCHIP is not set
-# CONFIG_NET_VENDOR_NATSEMI is not set
-# CONFIG_NET_VENDOR_SEEQ is not set
-# CONFIG_NET_VENDOR_SMSC is not set
-# CONFIG_NET_VENDOR_STMICRO is not set
-# CONFIG_NET_VENDOR_VIA is not set
-CONFIG_NLS=y
-CONFIG_NLS_ASCII=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_NOP_USB_XCEIV=y
-CONFIG_NO_HZ=y
-CONFIG_NO_HZ_COMMON=y
-CONFIG_NO_HZ_IDLE=y
-CONFIG_NO_IOPORT_MAP=y
-CONFIG_NR_CPUS=4
-CONFIG_NVMEM=y
-CONFIG_NVMEM_LAYOUTS=y
-CONFIG_NVMEM_SYSFS=y
-CONFIG_OF=y
-CONFIG_OF_ADDRESS=y
-CONFIG_OF_EARLY_FLATTREE=y
-CONFIG_OF_FLATTREE=y
-# CONFIG_OF_FPGA_REGION is not set
-CONFIG_OF_GPIO=y
-CONFIG_OF_IRQ=y
-CONFIG_OF_KOBJ=y
-CONFIG_OF_MDIO=y
-CONFIG_OLD_SIGACTION=y
-CONFIG_OLD_SIGSUSPEND3=y
-CONFIG_OUTER_CACHE=y
-CONFIG_OUTER_CACHE_SYNC=y
-CONFIG_PADATA=y
-CONFIG_PAGE_OFFSET=0xC0000000
-CONFIG_PAGE_POOL=y
-CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
-CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
-CONFIG_PAHOLE_HAS_LANG_EXCLUDE=y
-# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_PCI=y
-CONFIG_PCIE_XILINX=y
-CONFIG_PCI_DOMAINS=y
-CONFIG_PCI_DOMAINS_GENERIC=y
-CONFIG_PCI_MSI=y
-CONFIG_PCI_MSI_IRQ_DOMAIN=y
-CONFIG_PERF_USE_VMALLOC=y
-CONFIG_PGTABLE_LEVELS=2
-CONFIG_PHYLIB=y
-CONFIG_PHYLIB_LEDS=y
-CONFIG_PHYLINK=y
-CONFIG_PINCTRL=y
-# CONFIG_PINCTRL_SINGLE is not set
-CONFIG_PINCTRL_ZYNQ=y
-CONFIG_PL310_ERRATA_588369=y
-CONFIG_PL310_ERRATA_727915=y
-CONFIG_PL310_ERRATA_753970=y
-CONFIG_PL310_ERRATA_769419=y
-CONFIG_PL330_DMA=y
-# CONFIG_PL353_SMC is not set
-CONFIG_PLAT_VERSATILE=y
-CONFIG_PM=y
-CONFIG_PMBUS=y
-CONFIG_PM_CLK=y
-CONFIG_PM_SLEEP=y
-CONFIG_PM_SLEEP_SMP=y
-CONFIG_POWER_RESET=y
-CONFIG_POWER_RESET_VEXPRESS=y
-CONFIG_POWER_SUPPLY=y
-CONFIG_PPS=y
-CONFIG_PREEMPT_NONE_BUILD=y
-CONFIG_PROC_EVENTS=y
-CONFIG_PTP_1588_CLOCK=y
-CONFIG_PTP_1588_CLOCK_OPTIONAL=y
-CONFIG_R8169=y
-CONFIG_RANDSTRUCT_NONE=y
-CONFIG_RAS=y
-CONFIG_RATIONAL=y
-CONFIG_REALTEK_PHY=y
-CONFIG_REGMAP=y
-CONFIG_REGMAP_I2C=y
-CONFIG_REGMAP_MMIO=y
-CONFIG_REGULATOR=y
-CONFIG_REGULATOR_FIXED_VOLTAGE=y
-# CONFIG_REGULATOR_VEXPRESS is not set
-CONFIG_RESET_CONTROLLER=y
-CONFIG_RESET_ZYNQ=y
-CONFIG_RFS_ACCEL=y
-CONFIG_RPS=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_PCF8563=y
-CONFIG_RTC_I2C_AND_SPI=y
-CONFIG_RTC_MC146818_LIB=y
-CONFIG_RWSEM_SPIN_ON_OWNER=y
-# CONFIG_SCHED_CORE is not set
-CONFIG_SCHED_MC=y
-CONFIG_SCHED_SMT=y
-CONFIG_SENSORS_PMBUS=y
-CONFIG_SENSORS_UCD9000=y
-CONFIG_SENSORS_UCD9200=y
-# CONFIG_SERIAL_8250 is not set
-CONFIG_SERIAL_XILINX_PS_UART=y
-CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y
-CONFIG_SERIO=y
-CONFIG_SERIO_LIBPS2=y
-CONFIG_SERIO_SERPORT=y
-CONFIG_SMP=y
-CONFIG_SMP_ON_UP=y
-CONFIG_SOCK_RX_QUEUE_MAPPING=y
-CONFIG_SOC_BUS=y
-CONFIG_SOFTIRQ_ON_OWN_STACK=y
-CONFIG_SPARSE_IRQ=y
-CONFIG_SPI=y
-CONFIG_SPI_BITBANG=y
-CONFIG_SPI_CADENCE=y
-CONFIG_SPI_MASTER=y
-CONFIG_SPI_MEM=y
-CONFIG_SPI_XILINX=y
-CONFIG_SPI_ZYNQ_QSPI=y
-CONFIG_SRAM=y
-CONFIG_SRAM_EXEC=y
-CONFIG_SRCU=y
-# CONFIG_STRIP_ASM_SYMS is not set
-CONFIG_SUSPEND=y
-CONFIG_SUSPEND_FREEZER=y
-CONFIG_SWPHY=y
-CONFIG_SWP_EMULATE=y
-CONFIG_SYNC_FILE=y
-CONFIG_SYSFS_SYSCALL=y
-CONFIG_SYS_SUPPORTS_APM_EMULATION=y
-# CONFIG_TEXTSEARCH is not set
-CONFIG_THERMAL=y
-CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
-CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
-CONFIG_THERMAL_GOV_STEP_WISE=y
-CONFIG_THERMAL_HWMON=y
-CONFIG_THERMAL_OF=y
-CONFIG_THREAD_INFO_IN_TASK=y
-CONFIG_TICK_CPU_ACCOUNTING=y
-CONFIG_TIMER_OF=y
-CONFIG_TIMER_PROBE=y
-CONFIG_TREE_RCU=y
-CONFIG_TREE_SRCU=y
-CONFIG_UIO=y
-# CONFIG_UIO_AEC is not set
-# CONFIG_UIO_CIF is not set
-# CONFIG_UIO_DMEM_GENIRQ is not set
-# CONFIG_UIO_MF624 is not set
-# CONFIG_UIO_NETX is not set
-# CONFIG_UIO_PCI_GENERIC is not set
-CONFIG_UIO_PDRV_GENIRQ=y
-# CONFIG_UIO_PRUSS is not set
-# CONFIG_UIO_SERCOS3 is not set
-CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
-CONFIG_UNWINDER_ARM=y
-CONFIG_USB=y
-CONFIG_USB_CHIPIDEA=y
-CONFIG_USB_CHIPIDEA_HOST=y
-CONFIG_USB_CHIPIDEA_UDC=y
-CONFIG_USB_COMMON=y
-CONFIG_USB_EHCI_HCD=y
-# CONFIG_USB_EHCI_HCD_PLATFORM is not set
-# CONFIG_USB_EHCI_TT_NEWSCHED is not set
-CONFIG_USB_GADGET=y
-CONFIG_USB_GADGET_XILINX=y
-CONFIG_USB_HID=y
-CONFIG_USB_NET_DRIVERS=y
-CONFIG_USB_OTG=y
-CONFIG_USB_OTG_FSM=y
-CONFIG_USB_PHY=y
-CONFIG_USB_ROLE_SWITCH=y
-CONFIG_USB_SUPPORT=y
-CONFIG_USB_ULPI=y
-CONFIG_USB_ULPI_BUS=y
-CONFIG_USB_ULPI_VIEWPORT=y
-CONFIG_USE_OF=y
-CONFIG_VEXPRESS_CONFIG=y
-CONFIG_VFP=y
-CONFIG_VFPv3=y
-CONFIG_VGA_ARB=y
-CONFIG_VGA_ARB_MAX_GPUS=16
-CONFIG_VITESSE_PHY=y
-CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_VT_CONSOLE_SLEEP=y
-# CONFIG_VT_HW_CONSOLE_BINDING is not set
-CONFIG_WATCHDOG_CORE=y
-# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set
-CONFIG_XILINX_EMACLITE=y
-# CONFIG_XILINX_PR_DECOUPLER is not set
-CONFIG_XILINX_WATCHDOG=y
-CONFIG_XILINX_XADC=y
-CONFIG_XPS=y
-CONFIG_XZ_DEC_ARM=y
-CONFIG_XZ_DEC_ARMTHUMB=y
-CONFIG_XZ_DEC_BCJ=y
-CONFIG_XZ_DEC_IA64=y
-CONFIG_XZ_DEC_POWERPC=y
-CONFIG_XZ_DEC_SPARC=y
-CONFIG_XZ_DEC_X86=y
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_ZLIB_INFLATE=y
diff --git a/target/linux/zynq/config-6.6 b/target/linux/zynq/config-6.6
new file mode 100644
index 0000000000..15716a12cd
--- /dev/null
+++ b/target/linux/zynq/config-6.6
@@ -0,0 +1,570 @@
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_ALTERA_FREEZE_BRIDGE is not set
+# CONFIG_ALTERA_PR_IP_CORE is not set
+CONFIG_ARCH_32BIT_OFF_T=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_KEEP_MEMBLOCK=y
+CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
+CONFIG_ARCH_MULTIPLATFORM=y
+CONFIG_ARCH_MULTI_V6_V7=y
+CONFIG_ARCH_MULTI_V7=y
+CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y
+CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_STACKWALK=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARCH_VEXPRESS=y
+CONFIG_ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA=y
+# CONFIG_ARCH_VEXPRESS_SPC is not set
+CONFIG_ARCH_ZYNQ=y
+CONFIG_ARM=y
+CONFIG_ARM_AMBA=y
+CONFIG_ARM_CPU_SUSPEND=y
+CONFIG_ARM_ERRATA_643719=y
+CONFIG_ARM_ERRATA_720789=y
+CONFIG_ARM_ERRATA_754322=y
+CONFIG_ARM_ERRATA_754327=y
+CONFIG_ARM_ERRATA_764369=y
+CONFIG_ARM_ERRATA_775420=y
+CONFIG_ARM_GIC=y
+CONFIG_ARM_GLOBAL_TIMER=y
+CONFIG_ARM_GT_INITIAL_PRESCALER_VAL=2
+CONFIG_ARM_HAS_GROUP_RELOCS=y
+CONFIG_ARM_HEAVY_MB=y
+CONFIG_ARM_L1_CACHE_SHIFT=6
+CONFIG_ARM_L1_CACHE_SHIFT_6=y
+CONFIG_ARM_PATCH_IDIV=y
+CONFIG_ARM_PATCH_PHYS_VIRT=y
+# CONFIG_ARM_PL172_MPMC is not set
+# CONFIG_ARM_SMMU is not set
+CONFIG_ARM_THUMB=y
+CONFIG_ARM_TIMER_SP804=y
+CONFIG_ARM_UNWIND=y
+CONFIG_ARM_VIRT_EXT=y
+CONFIG_ARM_ZYNQ_CPUIDLE=y
+CONFIG_ATAGS=y
+CONFIG_AUTO_ZRELADDR=y
+# CONFIG_AXI_DMAC is not set
+CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+CONFIG_BLK_MQ_PCI=y
+CONFIG_BLK_PM=y
+CONFIG_BOUNCE=y
+CONFIG_BUFFER_HEAD=y
+CONFIG_CACHE_L2X0=y
+CONFIG_CADENCE_TTC_TIMER=y
+CONFIG_CADENCE_WATCHDOG=y
+CONFIG_CC_HAVE_STACKPROTECTOR_TLS=y
+CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
+CONFIG_CC_NO_ARRAY_BOUNDS=y
+CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK=y
+CONFIG_CLKSRC_MMIO=y
+CONFIG_CLKSRC_VERSATILE=y
+CONFIG_CLK_ICST=y
+CONFIG_CLK_SP810=y
+CONFIG_CLK_VEXPRESS_OSC=y
+CONFIG_CLONE_BACKWARDS=y
+CONFIG_CMA=y
+CONFIG_CMA_ALIGNMENT=8
+CONFIG_CMA_AREAS=7
+# CONFIG_CMA_DEBUG is not set
+# CONFIG_CMA_DEBUGFS is not set
+CONFIG_CMA_SIZE_MBYTES=16
+# CONFIG_CMA_SIZE_SEL_MAX is not set
+CONFIG_CMA_SIZE_SEL_MBYTES=y
+# CONFIG_CMA_SIZE_SEL_MIN is not set
+# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set
+# CONFIG_CMA_SYSFS is not set
+CONFIG_COMMON_CLK=y
+CONFIG_COMMON_CLK_SI570=y
+CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
+CONFIG_COMPAT_32BIT_TIME=y
+CONFIG_CONNECTOR=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_CONTEXT_TRACKING=y
+CONFIG_CONTEXT_TRACKING_IDLE=y
+CONFIG_CONTIG_ALLOC=y
+CONFIG_COREDUMP=y
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+CONFIG_CPU_FREQ=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ATTR_SET=y
+CONFIG_CPU_FREQ_GOV_COMMON=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_STAT=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_IDLE_GOV_LADDER=y
+CONFIG_CPU_IDLE_GOV_MENU=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_CPU_MITIGATIONS=y
+CONFIG_CPU_PABRT_V7=y
+CONFIG_CPU_PM=y
+CONFIG_CPU_RMAP=y
+CONFIG_CPU_SPECTRE=y
+CONFIG_CPU_THERMAL=y
+CONFIG_CPU_THUMB_CAPABLE=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_V7=y
+CONFIG_CRC16=y
+# CONFIG_CRC32_SARWATE is not set
+CONFIG_CRC32_SLICEBY8=y
+CONFIG_CROSS_MEMORY_ATTACH=y
+CONFIG_CRYPTO_CRC32=y
+CONFIG_CRYPTO_CRC32C=y
+CONFIG_CRYPTO_HW=y
+CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
+CONFIG_CRYPTO_LIB_GF128MUL=y
+CONFIG_CRYPTO_LIB_SHA1=y
+CONFIG_CRYPTO_LIB_UTILS=y
+CONFIG_CURRENT_POINTER_IN_TPIDRURO=y
+CONFIG_DCACHE_WORD_ACCESS=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
+CONFIG_DMADEVICES=y
+CONFIG_DMA_CMA=y
+CONFIG_DMA_ENGINE=y
+CONFIG_DMA_OF=y
+CONFIG_DMA_OPS=y
+CONFIG_DMA_SHARED_BUFFER=y
+CONFIG_DRM=y
+CONFIG_DRM_BRIDGE=y
+CONFIG_DRM_PANEL=y
+CONFIG_DRM_PANEL_BRIDGE=y
+CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y
+CONFIG_DTC=y
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_E1000E=y
+CONFIG_EDAC=y
+CONFIG_EDAC_ATOMIC_SCRUB=y
+# CONFIG_EDAC_DEBUG is not set
+CONFIG_EDAC_LEGACY_SYSFS=y
+CONFIG_EDAC_SUPPORT=y
+# CONFIG_EDAC_SYNOPSYS is not set
+CONFIG_EEPROM_AT24=y
+CONFIG_EEPROM_AT25=y
+CONFIG_ELF_CORE=y
+CONFIG_EXCLUSIVE_SYSTEM_RAM=y
+CONFIG_EXT4_FS=y
+CONFIG_EXTCON=y
+CONFIG_F2FS_FS=y
+CONFIG_FB=y
+CONFIG_FB_CORE=y
+CONFIG_FB_IOMEM_FOPS=y
+# CONFIG_FB_XILINX is not set
+CONFIG_FHANDLE=y
+CONFIG_FIXED_PHY=y
+CONFIG_FIX_EARLYCON_MEM=y
+CONFIG_FPGA=y
+CONFIG_FPGA_BRIDGE=y
+# CONFIG_FPGA_DFL is not set
+# CONFIG_FPGA_MGR_ALTERA_CVP is not set
+# CONFIG_FPGA_MGR_ALTERA_PS_SPI is not set
+# CONFIG_FPGA_MGR_ICE40_SPI is not set
+# CONFIG_FPGA_MGR_LATTICE_SYSCONFIG_SPI is not set
+# CONFIG_FPGA_MGR_MACHXO2_SPI is not set
+# CONFIG_FPGA_MGR_MICROCHIP_SPI is not set
+# CONFIG_FPGA_MGR_XILINX_SPI is not set
+CONFIG_FPGA_MGR_ZYNQ_FPGA=y
+CONFIG_FPGA_REGION=y
+CONFIG_FREEZER=y
+CONFIG_FS_IOMAP=y
+CONFIG_FS_MBCACHE=y
+CONFIG_FUNCTION_ALIGNMENT=0
+CONFIG_FWNODE_MDIO=y
+CONFIG_FW_CACHE=y
+CONFIG_FW_LOADER_PAGED_BUF=y
+CONFIG_FW_LOADER_SYSFS=y
+CONFIG_GCC10_NO_ARRAY_BOUNDS=y
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_GENERIC_ARCH_TOPOLOGY=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
+CONFIG_GENERIC_CPU_AUTOPROBE=y
+CONFIG_GENERIC_CPU_VULNERABILITIES=y
+CONFIG_GENERIC_EARLY_IOREMAP=y
+CONFIG_GENERIC_GETTIMEOFDAY=y
+CONFIG_GENERIC_IDLE_POLL_SETUP=y
+CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
+CONFIG_GENERIC_IRQ_MIGRATION=y
+CONFIG_GENERIC_IRQ_MULTI_HANDLER=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
+CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y
+CONFIG_GENERIC_MSI_IRQ=y
+CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_PINCONF=y
+CONFIG_GENERIC_SCHED_CLOCK=y
+CONFIG_GENERIC_SMP_IDLE_THREAD=y
+CONFIG_GENERIC_STRNCPY_FROM_USER=y
+CONFIG_GENERIC_STRNLEN_USER=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GENERIC_VDSO_32=y
+CONFIG_GLOB=y
+CONFIG_GPIOLIB_IRQCHIP=y
+CONFIG_GPIO_CDEV=y
+CONFIG_GPIO_GENERIC=y
+CONFIG_GPIO_GENERIC_PLATFORM=y
+CONFIG_GPIO_ZYNQ=y
+CONFIG_HARDEN_BRANCH_PREDICTOR=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_HAS_DMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAVE_SMP=y
+CONFIG_HDMI=y
+CONFIG_HIGHMEM=y
+CONFIG_HIGHPTE=y
+CONFIG_HOTPLUG_CORE_SYNC=y
+CONFIG_HOTPLUG_CORE_SYNC_DEAD=y
+CONFIG_HOTPLUG_CPU=y
+CONFIG_HWMON=y
+CONFIG_HW_CONSOLE=y
+CONFIG_HZ_FIXED=0
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CADENCE=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_HELPER_AUTO=y
+CONFIG_I2C_MUX=y
+CONFIG_I2C_MUX_PCA954x=y
+CONFIG_IIO=y
+CONFIG_IIO_BUFFER=y
+CONFIG_IIO_KFIFO_BUF=y
+CONFIG_IIO_TRIGGER=y
+CONFIG_IIO_TRIGGERED_BUFFER=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_INPUT=y
+CONFIG_INPUT_EVDEV=y
+CONFIG_INPUT_FF_MEMLESS=y
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_INPUT_MOUSE=y
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+CONFIG_INPUT_SPARSEKMAP=y
+CONFIG_INPUT_VIVALDIFMAP=y
+# CONFIG_IOMMUFD is not set
+# CONFIG_IOMMU_DEBUGFS is not set
+# CONFIG_IOMMU_IO_PGTABLE_ARMV7S is not set
+# CONFIG_IOMMU_IO_PGTABLE_LPAE is not set
+CONFIG_IOMMU_SUPPORT=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_RARP=y
+CONFIG_IRQCHIP=y
+CONFIG_IRQSTACKS=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_DOMAIN_HIERARCHY=y
+CONFIG_IRQ_FORCED_THREADING=y
+CONFIG_IRQ_WORK=y
+# CONFIG_ISDN is not set
+CONFIG_JBD2=y
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+CONFIG_KCMP=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_XZ is not set
+CONFIG_KEYBOARD_ATKBD=y
+CONFIG_KEYBOARD_GPIO=y
+CONFIG_KEYBOARD_GPIO_POLLED=y
+CONFIG_KMAP_LOCAL=y
+CONFIG_KMAP_LOCAL_NON_LINEAR_PTE_ARRAY=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGER_BACKLIGHT=y
+CONFIG_LEDS_TRIGGER_CAMERA=y
+CONFIG_LEDS_TRIGGER_CPU=y
+CONFIG_LEDS_TRIGGER_ONESHOT=y
+CONFIG_LEDS_TRIGGER_TRANSIENT=y
+CONFIG_LIBFDT=y
+CONFIG_LOCK_DEBUGGING_SUPPORT=y
+CONFIG_LOCK_SPIN_ON_OWNER=y
+CONFIG_MACB=y
+# CONFIG_MACB_PCI is not set
+CONFIG_MACB_USE_HWSTAMP=y
+CONFIG_MARVELL_PHY=y
+CONFIG_MDIO_BITBANG=y
+CONFIG_MDIO_BUS=y
+CONFIG_MDIO_DEVICE=y
+CONFIG_MDIO_DEVRES=y
+# CONFIG_MDIO_GPIO is not set
+CONFIG_MEMORY=y
+CONFIG_MEMORY_ISOLATION=y
+CONFIG_MFD_CORE=y
+CONFIG_MFD_SYSCON=y
+CONFIG_MFD_VEXPRESS_SYSREG=y
+CONFIG_MIGHT_HAVE_CACHE_L2X0=y
+CONFIG_MIGRATION=y
+CONFIG_MMC=y
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_CQHCI=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_OF_ARASAN=y
+# CONFIG_MMC_SDHCI_PCI is not set
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMU_LAZY_TLB_REFCOUNT=y
+CONFIG_MODULES_USE_ELF_REL=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+# CONFIG_MODULE_STRIPPED is not set
+# CONFIG_MOUSE_BCM5974 is not set
+# CONFIG_MOUSE_CYAPA is not set
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_BYD=y
+CONFIG_MOUSE_PS2_CYPRESS=y
+# CONFIG_MOUSE_PS2_ELANTECH is not set
+CONFIG_MOUSE_PS2_FOCALTECH=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SMBUS=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_SYNAPTICS_SMBUS=y
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_SPI_NOR=y
+CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y
+CONFIG_MTD_SPLIT_FIRMWARE=y
+# CONFIG_MTD_SPLIT_SQUASHFS_ROOT is not set
+CONFIG_MUTEX_SPIN_ON_OWNER=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_NEED_SRCU_NMI_SAFE=y
+CONFIG_NEON=y
+CONFIG_NET_EGRESS=y
+CONFIG_NET_FLOW_LIMIT=y
+CONFIG_NET_INGRESS=y
+CONFIG_NET_PTP_CLASSIFY=y
+CONFIG_NET_SELFTESTS=y
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_MICROCHIP is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_VIA is not set
+CONFIG_NET_XGRESS=y
+CONFIG_NLS=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NOP_USB_XCEIV=y
+CONFIG_NO_HZ=y
+CONFIG_NO_HZ_COMMON=y
+CONFIG_NO_HZ_IDLE=y
+CONFIG_NO_IOPORT_MAP=y
+CONFIG_NR_CPUS=4
+CONFIG_NVMEM=y
+CONFIG_NVMEM_LAYOUTS=y
+CONFIG_NVMEM_SYSFS=y
+CONFIG_OF=y
+CONFIG_OF_ADDRESS=y
+CONFIG_OF_EARLY_FLATTREE=y
+CONFIG_OF_FLATTREE=y
+# CONFIG_OF_FPGA_REGION is not set
+CONFIG_OF_GPIO=y
+CONFIG_OF_IRQ=y
+CONFIG_OF_KOBJ=y
+CONFIG_OF_MDIO=y
+CONFIG_OLD_SIGACTION=y
+CONFIG_OLD_SIGSUSPEND3=y
+CONFIG_OUTER_CACHE=y
+CONFIG_OUTER_CACHE_SYNC=y
+CONFIG_PADATA=y
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PAGE_POOL=y
+CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
+CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_PCI=y
+CONFIG_PCIE_XILINX=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_DOMAINS_GENERIC=y
+CONFIG_PCI_MSI=y
+CONFIG_PERF_USE_VMALLOC=y
+CONFIG_PGTABLE_LEVELS=2
+CONFIG_PHYLIB=y
+CONFIG_PHYLIB_LEDS=y
+CONFIG_PHYLINK=y
+CONFIG_PINCTRL=y
+# CONFIG_PINCTRL_SINGLE is not set
+CONFIG_PINCTRL_ZYNQ=y
+CONFIG_PL310_ERRATA_588369=y
+CONFIG_PL310_ERRATA_727915=y
+CONFIG_PL310_ERRATA_753970=y
+CONFIG_PL310_ERRATA_769419=y
+CONFIG_PL330_DMA=y
+# CONFIG_PL353_SMC is not set
+CONFIG_PLAT_VERSATILE=y
+CONFIG_PM=y
+CONFIG_PMBUS=y
+CONFIG_PM_CLK=y
+CONFIG_PM_SLEEP=y
+CONFIG_PM_SLEEP_SMP=y
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_VEXPRESS=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_PPS=y
+CONFIG_PREEMPT_NONE_BUILD=y
+CONFIG_PROC_EVENTS=y
+CONFIG_PTP_1588_CLOCK=y
+CONFIG_PTP_1588_CLOCK_OPTIONAL=y
+CONFIG_R8169=y
+CONFIG_R8169_LEDS=y
+CONFIG_RANDSTRUCT_NONE=y
+CONFIG_RAS=y
+CONFIG_RATIONAL=y
+CONFIG_REALTEK_PHY=y
+CONFIG_REGMAP=y
+CONFIG_REGMAP_I2C=y
+CONFIG_REGMAP_MMIO=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+# CONFIG_REGULATOR_VEXPRESS is not set
+CONFIG_RESET_CONTROLLER=y
+CONFIG_RESET_ZYNQ=y
+CONFIG_RFS_ACCEL=y
+CONFIG_RPS=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_PCF8563=y
+CONFIG_RTC_I2C_AND_SPI=y
+CONFIG_RTC_MC146818_LIB=y
+CONFIG_RWSEM_SPIN_ON_OWNER=y
+# CONFIG_SCHED_CORE is not set
+CONFIG_SCHED_MC=y
+CONFIG_SCHED_SMT=y
+CONFIG_SENSORS_PMBUS=y
+CONFIG_SENSORS_UCD9000=y
+CONFIG_SENSORS_UCD9200=y
+# CONFIG_SERIAL_8250 is not set
+CONFIG_SERIAL_XILINX_PS_UART=y
+CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y
+CONFIG_SERIO=y
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIO_SERPORT=y
+CONFIG_SMP=y
+CONFIG_SMP_ON_UP=y
+CONFIG_SOCK_RX_QUEUE_MAPPING=y
+CONFIG_SOC_BUS=y
+CONFIG_SOFTIRQ_ON_OWN_STACK=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_SPI=y
+CONFIG_SPI_BITBANG=y
+CONFIG_SPI_CADENCE=y
+CONFIG_SPI_MASTER=y
+CONFIG_SPI_MEM=y
+CONFIG_SPI_XILINX=y
+CONFIG_SPI_ZYNQ_QSPI=y
+CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y
+CONFIG_SRAM=y
+CONFIG_SRAM_EXEC=y
+# CONFIG_STRIP_ASM_SYMS is not set
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+CONFIG_SWPHY=y
+CONFIG_SWP_EMULATE=y
+CONFIG_SYNC_FILE=y
+CONFIG_SYSFS_SYSCALL=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+# CONFIG_TEXTSEARCH is not set
+CONFIG_THERMAL=y
+CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
+CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
+CONFIG_THERMAL_GOV_STEP_WISE=y
+CONFIG_THERMAL_HWMON=y
+CONFIG_THERMAL_OF=y
+CONFIG_THREAD_INFO_IN_TASK=y
+CONFIG_TICK_CPU_ACCOUNTING=y
+CONFIG_TIMER_OF=y
+CONFIG_TIMER_PROBE=y
+CONFIG_TREE_RCU=y
+CONFIG_TREE_SRCU=y
+CONFIG_UIO=y
+# CONFIG_UIO_AEC is not set
+# CONFIG_UIO_CIF is not set
+# CONFIG_UIO_DMEM_GENIRQ is not set
+# CONFIG_UIO_MF624 is not set
+# CONFIG_UIO_NETX is not set
+# CONFIG_UIO_PCI_GENERIC is not set
+CONFIG_UIO_PDRV_GENIRQ=y
+# CONFIG_UIO_PRUSS is not set
+# CONFIG_UIO_SERCOS3 is not set
+CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
+CONFIG_UNWINDER_ARM=y
+CONFIG_USB=y
+CONFIG_USB_CHIPIDEA=y
+CONFIG_USB_CHIPIDEA_HOST=y
+CONFIG_USB_CHIPIDEA_UDC=y
+CONFIG_USB_COMMON=y
+CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_HCD_PLATFORM is not set
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_XILINX=y
+CONFIG_USB_NET_DRIVERS=y
+CONFIG_USB_OTG=y
+CONFIG_USB_OTG_FSM=y
+CONFIG_USB_PHY=y
+CONFIG_USB_ROLE_SWITCH=y
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ULPI=y
+CONFIG_USB_ULPI_BUS=y
+CONFIG_USB_ULPI_VIEWPORT=y
+CONFIG_USE_OF=y
+CONFIG_VEXPRESS_CONFIG=y
+CONFIG_VFP=y
+CONFIG_VFPv3=y
+CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
+CONFIG_VIDEO_CMDLINE=y
+CONFIG_VIDEO_NOMODESET=y
+CONFIG_VITESSE_PHY=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_VT_CONSOLE_SLEEP=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_WATCHDOG_CORE=y
+# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set
+CONFIG_XILINX_EMACLITE=y
+# CONFIG_XILINX_PR_DECOUPLER is not set
+CONFIG_XILINX_WATCHDOG=y
+CONFIG_XILINX_XADC=y
+CONFIG_XPS=y
+CONFIG_XZ_DEC_ARM=y
+CONFIG_XZ_DEC_ARMTHUMB=y
+CONFIG_XZ_DEC_BCJ=y
+CONFIG_XZ_DEC_IA64=y
+CONFIG_XZ_DEC_POWERPC=y
+CONFIG_XZ_DEC_SPARC=y
+CONFIG_XZ_DEC_X86=y
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_ZLIB_INFLATE=y
diff --git a/target/linux/zynq/image/Makefile b/target/linux/zynq/image/Makefile
index 0931871624..4a9c2f047d 100644
--- a/target/linux/zynq/image/Makefile
+++ b/target/linux/zynq/image/Makefile
@@ -29,6 +29,7 @@ endef
define Device/Default
PROFILES := Default
+ DTS_DIR := $(DTS_DIR)/xilinx
DEVICE_DTS := $(lastword $(subst _, ,$(1)))
KERNEL_DEPENDS = $$(wildcard $(DTS_DIR)/$$(DEVICE_DTS).dts)
KERNEL_LOADADDR := 0x8000