From 7f2d7fbc2357c0826db3e44717325107b1236f2a Mon Sep 17 00:00:00 2001 From: Zoltan HERPAI Date: Thu, 12 Jun 2025 16:15:13 +0000 Subject: [PATCH] starfive: drop 6.6 support Drop configs and patches for Linux 6.6. Signed-off-by: Zoltan HERPAI --- target/linux/starfive/config-6.6 | 575 - ...110-sys-Fix-lower-rate-of-CPUfreq-by.patch | 76 - ...er-Add-timer-for-StarFive-JH7110-SoC.patch | 114 - ...-clocksource-Add-JH7110-timer-driver.patch | 428 - ...starfive-Remove-properties-from-requ.patch | 34 - ...tarfive-Change-tuning-implementation.patch | 199 - ...Add-bindings-for-OpenCores-PWM-Contr.patch | 79 - ...pwm-opencores-Add-PWM-driver-support.patch | 285 - ...remove-unnecessary-alignmask-for-aha.patch | 117 - ...-starfive-Update-driver-dependencies.patch | 25 - ...tarfive-RSA-poll-csr-for-done-status.patch | 200 - ...rypto-starfive-Pad-adata-with-zeroes.patch | 46 - ...2-crypto-starfive-Remove-cfb-and-ofb.patch | 125 - ...starfive-Remove-unneeded-NULL-checks.patch | 33 - ...Add-PLDA-XpressRICH-PCIe-host-common.patch | 183 - ...ve-pcie-microchip-host.c-to-plda-dir.patch | 2523 -- ...ve-PLDA-IP-register-macros-to-pcie-p.patch | 259 - ...d-bridge_addr-field-to-struct-mc_pci.patch | 107 - ...chip-Rename-two-PCIe-data-structures.patch | 347 - ...ve-PCIe-host-data-structures-to-plda.patch | 87 - ...microchip-Rename-two-setup-functions.patch | 76 - ...ange-the-argument-of-plda_pcie_setup.patch | 49 - ...ve-setup-functions-to-pcie-plda-host.patch | 200 - ...p-Rename-interrupt-related-functions.patch | 336 - ...d-num_events-field-to-struct-plda_pc.patch | 65 - ...d-request_event_irq-callback-functio.patch | 114 - ...d-INTx-and-MSI-event-num-to-struct-p.patch | 56 - ...d-get_events-callback-and-add-PLDA-g.patch | 167 - ...d-event-irqchip-field-to-host-port-a.patch | 144 - ...ve-IRQ-functions-to-pcie-plda-host.c.patch | 1028 - ...nt-bitmap-field-to-struct-plda_pcie_.patch | 67 - ...st-init-deinit-and-map-bus-functions.patch | 256 - ...-Add-StarFive-JH7110-PCIe-controller.patch | 140 - ...ET_CONFIG_DEVICE_WAIT_MS-waiting-tim.patch | 55 - ...-starfive-Add-JH7110-PCIe-controller.patch | 623 - ...-Add-StarFive-JH7110-PWM-DAC-control.patch | 97 - ...C-starfive-Add-JH7110-PWM-DAC-driver.patch | 574 - ...C-Update-jh7110-PWM-DAC-for-ops-move.patch | 32 - ...7110-pwmdac-Convert-to-platform-remo.patch | 52 - ...r-Add-power-domain-header-for-JH7110.patch | 35 - ...e-Replace-SOC_STARFIVE-with-ARCH_STA.patch | 31 - ...e-Extract-JH7110-pmu-private-operati.patch | 179 - ...-starfive-Add-JH7110-AON-PMU-support.patch | 122 - ...-to-move-Kconfig-files-into-the-pmdo.patch | 36 - ...e-Move-Kconfig-file-to-the-pmdomain-.patch | 69 - ...r-Update-prefixes-for-AON-power-doma.patch | 31 - ...e-Update-prefixes-for-AON-power-doma.patch | 32 - ...ve-pinfunc-Fix-the-pins-name-of-I2ST.patch | 30 - ...ve-Add-full-support-except-VIN-and-V.patch | 536 - ...NTAINERS-Update-all-StarFive-entries.patch | 147 - ...nge-the-voltage-to-adapt-to-JH7110-E.patch | 64 - ...l022-Get-and-deassert-reset-in-probe.patch | 60 - ...-getting-platform-data-error-for-Sta.patch | 30 - ...-RX-master-support-for-StarFive-JH71.patch | 67 - ...e-jh7110-Unset-.strict-in-pinmux_ops.patch | 24 - ...ric.c-Export-symbol-__pte_offset_map.patch | 22 - ...-starfive-Add-JH7110-EVB-device-tree.patch | 2623 -- ...ve-Add-JH7110-EVB-expanded-device-tr.patch | 728 - ...starfive-Add-evb-overlay-dtso-subdir.patch | 485 - ...onfigs-Add-starfive_jh7110_defconfig.patch | 385 - ...60-of-configfs-Add-configfs-function.patch | 318 - .../0061-usr-Add-gen_initramfs_list.sh.patch | 344 - ...ignware-Delete-SMBus-functionalities.patch | 33 - ...device-add-gd25lq256d-32M-flash-supp.patch | 26 - ...64-driver-mailbox-Add-mailbox-driver.patch | 808 - ...r-rtc-Add-StarFive-JH7110-rtc-driver.patch | 789 - ...t-8250-Add-dw-auto-flow-ctrl-support.patch | 96 - ...er-uart-fix-up-uart-communicate-fail.patch | 29 - ...50-add-reset-operation-in-runtime-PM.patch | 32 - ...bindings-CAN-Add-StarFive-CAN-module.patch | 113 - ...-CAN-starfive-Add-CAN-engine-support.patch | 1317 - ...ve-jh7110-Add-regulator-support-for-.patch | 204 - ...-precheck-and-delay-for-CQE-pending-.patch | 40 - ...te-unique-identification-for-SoC-PMU.patch | 93 - ...C-V-Support-CPUID-for-risc-v-in-perf.patch | 55 - ...C-V-Added-generic-pmu-events-mapfile.patch | 42 - ...erf-sbi-disable-cpu-hotplug-callback.patch | 30 - ...w-axi-dmac-Drop-unused-print-message.patch | 24 - ...9-ASoC-codecs-Add-AC108-Codec-driver.patch | 4748 --- ...oC-starfive-Add-SPDIF-and-PCM-driver.patch | 1169 - ...-ASoC-starfive-Add-JH7110-PDM-driver.patch | 537 - ...082-dt-binding-input-Add-tink_ft5406.patch | 55 - ...een-Add-tinker_ft5406-driver-support.patch | 444 - ...ng-media-Add-JH7110-Camera-Subsystem.patch | 246 - ...edia-starfive-Add-vin-driver-support.patch | 24014 ---------------- ...a-i2c-Add-IMX708-CMOS-sensor-binding.patch | 135 - .../0087-media-i2c-Add-imx708-support.patch | 1971 -- .../0088-media-i2c-imx708-Delete-gain.patch | 69 - ...lay-Add-yamls-for-JH7110-display-sys.patch | 270 - ...1xx_pmu-Add-EVENT_TURN_OFF-register-.patch | 82 - ...orkqueue-Enable-flush_scheduled_work.patch | 22 - ...Optimize-memcpy-with-aligned-version.patch | 506 - ...Change-memcpy-to-the-aligned-version.patch | 37 - ...ols-remove-the-frame-SYNC-event-to-v.patch | 856 - ...fter-the-SC-buffer-for-the-AE-AWB-fl.patch | 249 - ...dd-ISP-control-for-video2-and-video3.patch | 117 - ...ia-starfive-Update-ISP-initialzation.patch | 226 - ...pto-jh7110-Comment-RSA-algo-register.patch | 36 - ...ve-jh7110-evb-Add-qspi-norflash-part.patch | 26 - ...lator-pmic-driver-support-kernel-6.6.patch | 22 - ...ve-Add-platform-bus-register-to-adap.patch | 232 - ...ve-Avoid-power-device-error-when-CON.patch | 92 - ...ve-fix-the-problem-of-spi-overlay-re.patch | 403 - ...ve-Enable-spi-to-be-compiled-into-mo.patch | 38 - ...d-visionfive2-defconfig-to-kernel-6..patch | 444 - ...ts-starfive-update-dts-to-kernel-6.6.patch | 759 - ...five-evb-overlay-Support-SPI-overlay.patch | 71 - ...sionfive2-Add-standard-partition-for.patch | 23 - ...ove-performance-usb-using-lowmem-for.patch | 297 - ...ma_alloc_noncoherent-to-alloc-low-me.patch | 106 - ...starfive-Add-vf2-overlay-dtso-subdir.patch | 139 - ...ve-visionfive-2-Add-aliases-for-i2c-.patch | 34 - ...ve-visionfive-2-Sync-the-sound-card-.patch | 67 - ...110-Change-uart3-uart5-clk-register-.patch | 53 - ...ve-visionfive-2-Quote-corresponding-.patch | 32 - ...dd-starfive-jh7100-hsuart-compatible.patch | 25 - ...Add-StarFive-JH7100-audio-clock-node.patch | 32 - ...serial-8250-update-driver-for-JH7100.patch | 28 - ...-dmac-Handle-xfer-start-while-non-id.patch | 55 - ...axi-dmac-Add-StarFive-JH7100-support.patch | 64 - ...nctrl-starfive-Reset-pinmux-settings.patch | 127 - ...-flags-argument-to-JH71X0__MUX-macro.patch | 302 - ...100-Add-CLK_SET_RATE_PARENT-to-gmac_.patch | 25 - ...arfive-jh7100-Keep-more-clocks-alive.patch | 94 - .../1009-net-stmmac-use-GFP_DMA32.patch | 30 - ...ve-JH7100-Random-Number-Generator-dr.patch | 477 - ...sifive-ptc-Add-SiFive-PWM-PTC-driver.patch | 309 - ...t-Add-StarFive-JH7100-audio-reset-de.patch | 48 - ...t-Add-starfive-jh7100-audrst-binding.patch | 56 - ...arfive-Add-JH7100-audio-reset-driver.patch | 144 - ...Add-StarFive-JH7100-audio-reset-node.patch | 28 - ...e-ccache-Add-StarFive-JH7100-support.patch | 160 - ...cv-errata-Add-StarFive-JH7100-errata.patch | 44 - ...ve-Mark-the-JH7100-as-having-non-coh.patch | 26 - ...starfive-Add-JH7100-cache-controller.patch | 50 - ...ve-Add-pool-for-coherent-DMA-memory-.patch | 61 - ...cv-dts-starfive-Add-JH7100-MMC-nodes.patch | 49 - ...five-Enable-SD-card-on-JH7100-boards.patch | 85 - ...e-ERRATA_STARFIVE_JH7100-depend-on-D.patch | 33 - ...ll-JH7100-Starlight-and-VisionFive-s.patch | 1138 - 140 files changed, 62219 deletions(-) delete mode 100644 target/linux/starfive/config-6.6 delete mode 100644 target/linux/starfive/patches-6.6/0001-clk-starfive-jh7110-sys-Fix-lower-rate-of-CPUfreq-by.patch delete mode 100644 target/linux/starfive/patches-6.6/0002-dt-bindings-timer-Add-timer-for-StarFive-JH7110-SoC.patch delete mode 100644 target/linux/starfive/patches-6.6/0003-clocksource-Add-JH7110-timer-driver.patch delete mode 100644 target/linux/starfive/patches-6.6/0004-dt-bindings-mmc-starfive-Remove-properties-from-requ.patch delete mode 100644 target/linux/starfive/patches-6.6/0005-mmc-starfive-Change-tuning-implementation.patch delete mode 100644 target/linux/starfive/patches-6.6/0006-dt-bindings-pwm-Add-bindings-for-OpenCores-PWM-Contr.patch delete mode 100644 target/linux/starfive/patches-6.6/0007-pwm-opencores-Add-PWM-driver-support.patch delete mode 100644 target/linux/starfive/patches-6.6/0008-crypto-starfive-remove-unnecessary-alignmask-for-aha.patch delete mode 100644 target/linux/starfive/patches-6.6/0009-crypto-starfive-Update-driver-dependencies.patch delete mode 100644 target/linux/starfive/patches-6.6/0010-crypto-starfive-RSA-poll-csr-for-done-status.patch delete mode 100644 target/linux/starfive/patches-6.6/0011-crypto-starfive-Pad-adata-with-zeroes.patch delete mode 100644 target/linux/starfive/patches-6.6/0012-crypto-starfive-Remove-cfb-and-ofb.patch delete mode 100644 target/linux/starfive/patches-6.6/0013-crypto-starfive-Remove-unneeded-NULL-checks.patch delete mode 100644 target/linux/starfive/patches-6.6/0014-dt-bindings-PCI-Add-PLDA-XpressRICH-PCIe-host-common.patch delete mode 100644 target/linux/starfive/patches-6.6/0015-PCI-microchip-Move-pcie-microchip-host.c-to-plda-dir.patch delete mode 100644 target/linux/starfive/patches-6.6/0016-PCI-microchip-Move-PLDA-IP-register-macros-to-pcie-p.patch delete mode 100644 target/linux/starfive/patches-6.6/0017-PCI-microchip-Add-bridge_addr-field-to-struct-mc_pci.patch delete mode 100644 target/linux/starfive/patches-6.6/0018-PCI-microchip-Rename-two-PCIe-data-structures.patch delete mode 100644 target/linux/starfive/patches-6.6/0019-PCI-microchip-Move-PCIe-host-data-structures-to-plda.patch delete mode 100644 target/linux/starfive/patches-6.6/0020-PCI-microchip-Rename-two-setup-functions.patch delete mode 100644 target/linux/starfive/patches-6.6/0021-PCI-microchip-Change-the-argument-of-plda_pcie_setup.patch delete mode 100644 target/linux/starfive/patches-6.6/0022-PCI-microchip-Move-setup-functions-to-pcie-plda-host.patch delete mode 100644 target/linux/starfive/patches-6.6/0023-PCI-microchip-Rename-interrupt-related-functions.patch delete mode 100644 target/linux/starfive/patches-6.6/0024-PCI-microchip-Add-num_events-field-to-struct-plda_pc.patch delete mode 100644 target/linux/starfive/patches-6.6/0025-PCI-microchip-Add-request_event_irq-callback-functio.patch delete mode 100644 target/linux/starfive/patches-6.6/0026-PCI-microchip-Add-INTx-and-MSI-event-num-to-struct-p.patch delete mode 100644 target/linux/starfive/patches-6.6/0027-PCI-microchip-Add-get_events-callback-and-add-PLDA-g.patch delete mode 100644 target/linux/starfive/patches-6.6/0028-PCI-microchip-Add-event-irqchip-field-to-host-port-a.patch delete mode 100644 target/linux/starfive/patches-6.6/0029-PCI-microchip-Move-IRQ-functions-to-pcie-plda-host.c.patch delete mode 100644 target/linux/starfive/patches-6.6/0030-pci-plda-Add-event-bitmap-field-to-struct-plda_pcie_.patch delete mode 100644 target/linux/starfive/patches-6.6/0031-PCI-plda-Add-host-init-deinit-and-map-bus-functions.patch delete mode 100644 target/linux/starfive/patches-6.6/0032-dt-bindings-PCI-Add-StarFive-JH7110-PCIe-controller.patch delete mode 100644 target/linux/starfive/patches-6.6/0033-PCI-Add-PCIE_RESET_CONFIG_DEVICE_WAIT_MS-waiting-tim.patch delete mode 100644 target/linux/starfive/patches-6.6/0034-PCI-starfive-Add-JH7110-PCIe-controller.patch delete mode 100644 target/linux/starfive/patches-6.6/0035-ASoC-dt-bindings-Add-StarFive-JH7110-PWM-DAC-control.patch delete mode 100644 target/linux/starfive/patches-6.6/0036-ASoC-starfive-Add-JH7110-PWM-DAC-driver.patch delete mode 100644 target/linux/starfive/patches-6.6/0037-ASoC-Update-jh7110-PWM-DAC-for-ops-move.patch delete mode 100644 target/linux/starfive/patches-6.6/0038-ASoC-starfive-jh7110-pwmdac-Convert-to-platform-remo.patch delete mode 100644 target/linux/starfive/patches-6.6/0039-dt-bindings-power-Add-power-domain-header-for-JH7110.patch delete mode 100644 target/linux/starfive/patches-6.6/0040-pmdomain-starfive-Replace-SOC_STARFIVE-with-ARCH_STA.patch delete mode 100644 target/linux/starfive/patches-6.6/0041-pmdomain-starfive-Extract-JH7110-pmu-private-operati.patch delete mode 100644 target/linux/starfive/patches-6.6/0042-pmdomain-starfive-Add-JH7110-AON-PMU-support.patch delete mode 100644 target/linux/starfive/patches-6.6/0043-pmdomain-Prepare-to-move-Kconfig-files-into-the-pmdo.patch delete mode 100644 target/linux/starfive/patches-6.6/0044-pmdomain-starfive-Move-Kconfig-file-to-the-pmdomain-.patch delete mode 100644 target/linux/starfive/patches-6.6/0045-dt-bindings-power-Update-prefixes-for-AON-power-doma.patch delete mode 100644 target/linux/starfive/patches-6.6/0046-pmdomain-starfive-Update-prefixes-for-AON-power-doma.patch delete mode 100644 target/linux/starfive/patches-6.6/0047-riscv-dts-starfive-pinfunc-Fix-the-pins-name-of-I2ST.patch delete mode 100644 target/linux/starfive/patches-6.6/0048-riscv-dts-starfive-Add-full-support-except-VIN-and-V.patch delete mode 100644 target/linux/starfive/patches-6.6/0049-MAINTAINERS-Update-all-StarFive-entries.patch delete mode 100644 target/linux/starfive/patches-6.6/0050-mmc-starfive-Change-the-voltage-to-adapt-to-JH7110-E.patch delete mode 100644 target/linux/starfive/patches-6.6/0051-spi-spl022-Get-and-deassert-reset-in-probe.patch delete mode 100644 target/linux/starfive/patches-6.6/0052-ASoC-dwc-i2s-Fix-getting-platform-data-error-for-Sta.patch delete mode 100644 target/linux/starfive/patches-6.6/0053-ASoC-dwc-i2s-Add-RX-master-support-for-StarFive-JH71.patch delete mode 100644 target/linux/starfive/patches-6.6/0054-pinctrl-starfive-jh7110-Unset-.strict-in-pinmux_ops.patch delete mode 100644 target/linux/starfive/patches-6.6/0055-mm-pgtable-generic.c-Export-symbol-__pte_offset_map.patch delete mode 100644 target/linux/starfive/patches-6.6/0056-riscv-dts-starfive-Add-JH7110-EVB-device-tree.patch delete mode 100644 target/linux/starfive/patches-6.6/0057-riscv-dts-starfive-Add-JH7110-EVB-expanded-device-tr.patch delete mode 100644 target/linux/starfive/patches-6.6/0058-riscv-dts-starfive-Add-evb-overlay-dtso-subdir.patch delete mode 100644 target/linux/starfive/patches-6.6/0059-riscv-configs-Add-starfive_jh7110_defconfig.patch delete mode 100644 target/linux/starfive/patches-6.6/0060-of-configfs-Add-configfs-function.patch delete mode 100644 target/linux/starfive/patches-6.6/0061-usr-Add-gen_initramfs_list.sh.patch delete mode 100644 target/linux/starfive/patches-6.6/0062-i2c-designware-Delete-SMBus-functionalities.patch delete mode 100644 target/linux/starfive/patches-6.6/0063-drivers-mtd-gigadevice-add-gd25lq256d-32M-flash-supp.patch delete mode 100644 target/linux/starfive/patches-6.6/0064-driver-mailbox-Add-mailbox-driver.patch delete mode 100644 target/linux/starfive/patches-6.6/0065-driver-rtc-Add-StarFive-JH7110-rtc-driver.patch delete mode 100644 target/linux/starfive/patches-6.6/0066-uart-8250-Add-dw-auto-flow-ctrl-support.patch delete mode 100644 target/linux/starfive/patches-6.6/0067-driver-uart-fix-up-uart-communicate-fail.patch delete mode 100644 target/linux/starfive/patches-6.6/0068-uart-8250-add-reset-operation-in-runtime-PM.patch delete mode 100644 target/linux/starfive/patches-6.6/0069-dt-bindings-CAN-Add-StarFive-CAN-module.patch delete mode 100644 target/linux/starfive/patches-6.6/0070-CAN-starfive-Add-CAN-engine-support.patch delete mode 100644 target/linux/starfive/patches-6.6/0071-regulator-starfive-jh7110-Add-regulator-support-for-.patch delete mode 100644 target/linux/starfive/patches-6.6/0072-drivers-nvme-Add-precheck-and-delay-for-CQE-pending-.patch delete mode 100644 target/linux/starfive/patches-6.6/0073-RISC-V-Create-unique-identification-for-SoC-PMU.patch delete mode 100644 target/linux/starfive/patches-6.6/0074-RISC-V-Support-CPUID-for-risc-v-in-perf.patch delete mode 100644 target/linux/starfive/patches-6.6/0075-RISC-V-Added-generic-pmu-events-mapfile.patch delete mode 100644 target/linux/starfive/patches-6.6/0076-perf-sbi-disable-cpu-hotplug-callback.patch delete mode 100644 target/linux/starfive/patches-6.6/0077-dmaengine-dw-axi-dmac-Drop-unused-print-message.patch delete mode 100644 target/linux/starfive/patches-6.6/0079-ASoC-codecs-Add-AC108-Codec-driver.patch delete mode 100644 target/linux/starfive/patches-6.6/0080-ASoC-starfive-Add-SPDIF-and-PCM-driver.patch delete mode 100644 target/linux/starfive/patches-6.6/0081-ASoC-starfive-Add-JH7110-PDM-driver.patch delete mode 100644 target/linux/starfive/patches-6.6/0082-dt-binding-input-Add-tink_ft5406.patch delete mode 100644 target/linux/starfive/patches-6.6/0083-input-touchscreen-Add-tinker_ft5406-driver-support.patch delete mode 100644 target/linux/starfive/patches-6.6/0084-dt-binding-media-Add-JH7110-Camera-Subsystem.patch delete mode 100644 target/linux/starfive/patches-6.6/0085-media-starfive-Add-vin-driver-support.patch delete mode 100644 target/linux/starfive/patches-6.6/0086-dt-bindings-media-i2c-Add-IMX708-CMOS-sensor-binding.patch delete mode 100644 target/linux/starfive/patches-6.6/0087-media-i2c-Add-imx708-support.patch delete mode 100644 target/linux/starfive/patches-6.6/0088-media-i2c-imx708-Delete-gain.patch delete mode 100644 target/linux/starfive/patches-6.6/0089-dt-bindings-display-Add-yamls-for-JH7110-display-sys.patch delete mode 100644 target/linux/starfive/patches-6.6/0090-soc-starfive-jh71xx_pmu-Add-EVENT_TURN_OFF-register-.patch delete mode 100644 target/linux/starfive/patches-6.6/0091-workqueue-Enable-flush_scheduled_work.patch delete mode 100644 target/linux/starfive/patches-6.6/0092-riscv-Optimize-memcpy-with-aligned-version.patch delete mode 100644 target/linux/starfive/patches-6.6/0093-riscv-purgatory-Change-memcpy-to-the-aligned-version.patch delete mode 100644 target/linux/starfive/patches-6.6/0094-Add-16-ISP-controls-remove-the-frame-SYNC-event-to-v.patch delete mode 100644 target/linux/starfive/patches-6.6/0095-Expand-2-bytes-after-the-SC-buffer-for-the-AE-AWB-fl.patch delete mode 100644 target/linux/starfive/patches-6.6/0096-Add-ISP-control-for-video2-and-video3.patch delete mode 100644 target/linux/starfive/patches-6.6/0097-media-starfive-Update-ISP-initialzation.patch delete mode 100644 target/linux/starfive/patches-6.6/0098-crypto-jh7110-Comment-RSA-algo-register.patch delete mode 100644 target/linux/starfive/patches-6.6/0099-riscv-dts-starfive-jh7110-evb-Add-qspi-norflash-part.patch delete mode 100644 target/linux/starfive/patches-6.6/0100-driver-regulator-pmic-driver-support-kernel-6.6.patch delete mode 100644 target/linux/starfive/patches-6.6/0101-spi-pl022-starfive-Add-platform-bus-register-to-adap.patch delete mode 100644 target/linux/starfive/patches-6.6/0102-spi-pl022-starfive-Avoid-power-device-error-when-CON.patch delete mode 100644 target/linux/starfive/patches-6.6/0103-spi-pl022-starfive-fix-the-problem-of-spi-overlay-re.patch delete mode 100644 target/linux/starfive/patches-6.6/0104-spi-pl022-starfive-Enable-spi-to-be-compiled-into-mo.patch delete mode 100644 target/linux/starfive/patches-6.6/0105-riscv-configs-add-visionfive2-defconfig-to-kernel-6..patch delete mode 100644 target/linux/starfive/patches-6.6/0106-riscv-dts-starfive-update-dts-to-kernel-6.6.patch delete mode 100644 target/linux/starfive/patches-6.6/0107-riscv-dts-starfive-evb-overlay-Support-SPI-overlay.patch delete mode 100644 target/linux/starfive/patches-6.6/0108-riscv-configs-visionfive2-Add-standard-partition-for.patch delete mode 100644 target/linux/starfive/patches-6.6/0109-usb-xhci-To-improve-performance-usb-using-lowmem-for.patch delete mode 100644 target/linux/starfive/patches-6.6/0110-usb-xhci-using-dma_alloc_noncoherent-to-alloc-low-me.patch delete mode 100644 target/linux/starfive/patches-6.6/0111-riscv-dts-starfive-Add-vf2-overlay-dtso-subdir.patch delete mode 100644 target/linux/starfive/patches-6.6/0112-riscv-dts-starfive-visionfive-2-Add-aliases-for-i2c-.patch delete mode 100644 target/linux/starfive/patches-6.6/0114-riscv-dts-starfive-visionfive-2-Sync-the-sound-card-.patch delete mode 100644 target/linux/starfive/patches-6.6/0115-clk-starfive-jh7110-Change-uart3-uart5-clk-register-.patch delete mode 100644 target/linux/starfive/patches-6.6/0116-riscv-dts-starfive-visionfive-2-Quote-corresponding-.patch delete mode 100644 target/linux/starfive/patches-6.6/1000-serial-8250_dw-Add-starfive-jh7100-hsuart-compatible.patch delete mode 100644 target/linux/starfive/patches-6.6/1001-RISC-V-Add-StarFive-JH7100-audio-clock-node.patch delete mode 100644 target/linux/starfive/patches-6.6/1002-drivers-tty-serial-8250-update-driver-for-JH7100.patch delete mode 100644 target/linux/starfive/patches-6.6/1003-dmaengine-dw-axi-dmac-Handle-xfer-start-while-non-id.patch delete mode 100644 target/linux/starfive/patches-6.6/1004-dmaengine-dw-axi-dmac-Add-StarFive-JH7100-support.patch delete mode 100644 target/linux/starfive/patches-6.6/1005-pinctrl-starfive-Reset-pinmux-settings.patch delete mode 100644 target/linux/starfive/patches-6.6/1006-clk-starfive-Add-flags-argument-to-JH71X0__MUX-macro.patch delete mode 100644 target/linux/starfive/patches-6.6/1007-clk-starfive-jh7100-Add-CLK_SET_RATE_PARENT-to-gmac_.patch delete mode 100644 target/linux/starfive/patches-6.6/1008-clk-starfive-jh7100-Keep-more-clocks-alive.patch delete mode 100644 target/linux/starfive/patches-6.6/1009-net-stmmac-use-GFP_DMA32.patch delete mode 100644 target/linux/starfive/patches-6.6/1010-hwrng-Add-StarFive-JH7100-Random-Number-Generator-dr.patch delete mode 100644 target/linux/starfive/patches-6.6/1011-pwm-sifive-ptc-Add-SiFive-PWM-PTC-driver.patch delete mode 100644 target/linux/starfive/patches-6.6/1012-dt-bindings-reset-Add-StarFive-JH7100-audio-reset-de.patch delete mode 100644 target/linux/starfive/patches-6.6/1013-dt-bindings-reset-Add-starfive-jh7100-audrst-binding.patch delete mode 100644 target/linux/starfive/patches-6.6/1014-reset-starfive-Add-JH7100-audio-reset-driver.patch delete mode 100644 target/linux/starfive/patches-6.6/1015-RISC-V-Add-StarFive-JH7100-audio-reset-node.patch delete mode 100644 target/linux/starfive/patches-6.6/1016-soc-sifive-ccache-Add-StarFive-JH7100-support.patch delete mode 100644 target/linux/starfive/patches-6.6/1017-riscv-errata-Add-StarFive-JH7100-errata.patch delete mode 100644 target/linux/starfive/patches-6.6/1018-riscv-dts-starfive-Mark-the-JH7100-as-having-non-coh.patch delete mode 100644 target/linux/starfive/patches-6.6/1019-riscv-dts-starfive-Add-JH7100-cache-controller.patch delete mode 100644 target/linux/starfive/patches-6.6/1020-riscv-dts-starfive-Add-pool-for-coherent-DMA-memory-.patch delete mode 100644 target/linux/starfive/patches-6.6/1021-riscv-dts-starfive-Add-JH7100-MMC-nodes.patch delete mode 100644 target/linux/starfive/patches-6.6/1022-riscv-dts-starfive-Enable-SD-card-on-JH7100-boards.patch delete mode 100644 target/linux/starfive/patches-6.6/1023-riscv-errata-Make-ERRATA_STARFIVE_JH7100-depend-on-D.patch delete mode 100644 target/linux/starfive/patches-6.6/1024-riscv-dts-Add-full-JH7100-Starlight-and-VisionFive-s.patch diff --git a/target/linux/starfive/config-6.6 b/target/linux/starfive/config-6.6 deleted file mode 100644 index 61b2ce7c00d..00000000000 --- a/target/linux/starfive/config-6.6 +++ /dev/null @@ -1,575 +0,0 @@ -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_CC_HAVE_STACKPROTECTOR_TLS=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_SIFIVE=y -CONFIG_ERRATA_SIFIVE_CIP_1200=y -CONFIG_ERRATA_SIFIVE_CIP_453=y -CONFIG_ERRATA_STARFIVE_JH7100=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_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_NONPORTABLE=y -CONFIG_NO_HZ_COMMON=y -CONFIG_NO_HZ_IDLE=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_JH7110_TIMER=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_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.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 deleted file mode 100644 index e98e6dfaafe..00000000000 --- a/target/linux/starfive/patches-6.6/0001-clk-starfive-jh7110-sys-Fix-lower-rate-of-CPUfreq-by.patch +++ /dev/null @@ -1,76 +0,0 @@ -From 69275b667bd930cf5d5f577ba0ab1987c9d13987 Mon Sep 17 00:00:00 2001 -From: Xingyu Wu -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 -Fixes: e2c510d6d630 ("riscv: dts: starfive: Add cpu scaling for JH7110 SoC") -Signed-off-by: Xingyu Wu ---- - .../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 -@@ -530,7 +530,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 deleted file mode 100644 index 2b5318bb44f..00000000000 --- a/target/linux/starfive/patches-6.6/0002-dt-bindings-timer-Add-timer-for-StarFive-JH7110-SoC.patch +++ /dev/null @@ -1,114 +0,0 @@ -From 7d0dbcbc079e4f72b69f53442b7759da6ebc4f87 Mon Sep 17 00:00:00 2001 -From: Xingyu Wu -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 -Signed-off-by: Xingyu Wu ---- - .../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 -+ - Samin Guo -+ -+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 deleted file mode 100644 index b4398ef1468..00000000000 --- a/target/linux/starfive/patches-6.6/0003-clocksource-Add-JH7110-timer-driver.patch +++ /dev/null @@ -1,428 +0,0 @@ -From 7cb47848f8a10aed6e050c0ea483b4bb5eaa62a4 Mon Sep 17 00:00:00 2001 -From: Xingyu Wu -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 ---- - 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 -@@ -642,6 +642,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 -+ * Samin Guo -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* 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 "); -+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 deleted file mode 100644 index 9c1e78b29bf..00000000000 --- a/target/linux/starfive/patches-6.6/0004-dt-bindings-mmc-starfive-Remove-properties-from-requ.patch +++ /dev/null @@ -1,34 +0,0 @@ -From b513eb2cabee212ba1a23839f18c0026a21e653e Mon Sep 17 00:00:00 2001 -From: William Qiu -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 -Acked-by: Conor Dooley -Reviewed-by: Emil Renner Berthing -Link: https://lore.kernel.org/r/20230922062834.39212-2-william.qiu@starfivetech.com -Signed-off-by: Ulf Hansson ---- - 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 deleted file mode 100644 index b8ea96f3c85..00000000000 --- a/target/linux/starfive/patches-6.6/0005-mmc-starfive-Change-tuning-implementation.patch +++ /dev/null @@ -1,199 +0,0 @@ -From 3ae8cec8fd28e18847edb67dfea04718c2f3369f Mon Sep 17 00:00:00 2001 -From: William Qiu -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 -Reviewed-by: Emil Renner Berthing -Link: https://lore.kernel.org/r/20230922062834.39212-3-william.qiu@starfivetech.com -Signed-off-by: Ulf Hansson ---- - 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 - #include - #include - #include -@@ -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 deleted file mode 100644 index aafbee5d422..00000000000 --- a/target/linux/starfive/patches-6.6/0006-dt-bindings-pwm-Add-bindings-for-OpenCores-PWM-Contr.patch +++ /dev/null @@ -1,79 +0,0 @@ -From e366df2ff64e9f93a5b35eea6a198b005d5a0911 Mon Sep 17 00:00:00 2001 -From: William Qiu -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 -Reviewed-by: Hal Feng -Reviewed-by: Conor Dooley -Reviewed-by: Uwe Kleine-König -Acked-by: Uwe Kleine-König ---- - .../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 -+ -+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 deleted file mode 100644 index 27e510d86a0..00000000000 --- a/target/linux/starfive/patches-6.6/0007-pwm-opencores-Add-PWM-driver-support.patch +++ /dev/null @@ -1,285 +0,0 @@ -From 644bfe581dde9b762460a4916da4d71c148be06e Mon Sep 17 00:00:00 2001 -From: William Qiu -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 -Signed-off-by: Hal Feng -Signed-off-by: William Qiu ---- - 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* 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 "); -+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 deleted file mode 100644 index a6ede313424..00000000000 --- a/target/linux/starfive/patches-6.6/0008-crypto-starfive-remove-unnecessary-alignmask-for-aha.patch +++ /dev/null @@ -1,117 +0,0 @@ -From 7d9521cad6474d45e9056176982e6da54d40bc19 Mon Sep 17 00:00:00 2001 -From: Eric Biggers -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 -Signed-off-by: Herbert Xu ---- - 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 deleted file mode 100644 index 145c01377d1..00000000000 --- a/target/linux/starfive/patches-6.6/0009-crypto-starfive-Update-driver-dependencies.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 52de0270ed6453727936b5a793dc367d75280e84 Mon Sep 17 00:00:00 2001 -From: Jia Jie Ho -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 -Signed-off-by: Herbert Xu ---- - 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 deleted file mode 100644 index 5e353e35ad4..00000000000 --- a/target/linux/starfive/patches-6.6/0010-crypto-starfive-RSA-poll-csr-for-done-status.patch +++ /dev/null @@ -1,200 +0,0 @@ -From 68a1bbb99455fd5ea80b7e21ec726f369abc9572 Mon Sep 17 00:00:00 2001 -From: Jia Jie Ho -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 -Signed-off-by: Herbert Xu ---- - 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 -@@ -126,6 +126,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; -@@ -184,7 +193,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 --#include --#include --#include --#include - #include --#include --#include - #include - #include - #include -@@ -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_RESET 0x2 -@@ -42,21 +36,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) -@@ -113,10 +96,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++) -@@ -135,10 +117,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; -@@ -150,10 +131,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++) -@@ -171,10 +151,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; - } - -@@ -225,11 +204,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) { -@@ -241,10 +219,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 deleted file mode 100644 index 268e4055e0d..00000000000 --- a/target/linux/starfive/patches-6.6/0011-crypto-starfive-Pad-adata-with-zeroes.patch +++ /dev/null @@ -1,46 +0,0 @@ -From eea9f2c55cf944bbd5cdd43eb655416a867846af Mon Sep 17 00:00:00 2001 -From: Jia Jie Ho -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 -Signed-off-by: Herbert Xu ---- - 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 deleted file mode 100644 index 102fbabf377..00000000000 --- a/target/linux/starfive/patches-6.6/0012-crypto-starfive-Remove-cfb-and-ofb.patch +++ /dev/null @@ -1,125 +0,0 @@ -From 922b213ad22f93fb2788ce119084622ab3d25bf8 Mon Sep 17 00:00:00 2001 -From: Herbert Xu -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 ---- - 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 -@@ -51,8 +51,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 deleted file mode 100644 index 2e12cfa09ee..00000000000 --- a/target/linux/starfive/patches-6.6/0013-crypto-starfive-Remove-unneeded-NULL-checks.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 0dbdc763f10c5cfa968dffc290a7c060ee740172 Mon Sep 17 00:00:00 2001 -From: Jia Jie Ho -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 -Reported-by: kernel test robot -Closes: https://lore.kernel.org/oe-kbuild-all/202311301702.LxswfETY-lkp@intel.com/ -Signed-off-by: Herbert Xu ---- - 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 -@@ -44,12 +44,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 deleted file mode 100644 index 430571565a1..00000000000 --- a/target/linux/starfive/patches-6.6/0014-dt-bindings-PCI-Add-PLDA-XpressRICH-PCIe-host-common.patch +++ /dev/null @@ -1,183 +0,0 @@ -From 708695ebf1a779de9a1fd2f72f7938afa6c14ada Mon Sep 17 00:00:00 2001 -From: Minda Chen -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 -Reviewed-by: Hal Feng -Reviewed-by: Conor Dooley -Reviewed-by: Rob Herring -Tested-by: John Clark ---- - .../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 - - 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 -+ - Kevin Xie -+ -+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 deleted file mode 100644 index 9e7717fa5d2..00000000000 --- a/target/linux/starfive/patches-6.6/0015-PCI-microchip-Move-pcie-microchip-host.c-to-plda-dir.patch +++ /dev/null @@ -1,2523 +0,0 @@ -From df67154aa92efdc774a8536ece6f431e7850aca2 Mon Sep 17 00:00:00 2001 -From: Minda Chen -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 -Reviewed-by: Conor Dooley ---- - 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 -- */ -- --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include -- --#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 "); ---- /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 -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#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 "); 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 deleted file mode 100644 index 0aacec2769b..00000000000 --- a/target/linux/starfive/patches-6.6/0016-PCI-microchip-Move-PLDA-IP-register-macros-to-pcie-p.patch +++ /dev/null @@ -1,259 +0,0 @@ -From eca1b864bb2d4e8d9811506979560a89351c2e37 Mon Sep 17 00:00:00 2001 -From: Minda Chen -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 -Reviewed-by: Conor Dooley ---- - .../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 - - #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 deleted file mode 100644 index bc3f9091165..00000000000 --- a/target/linux/starfive/patches-6.6/0017-PCI-microchip-Add-bridge_addr-field-to-struct-mc_pci.patch +++ /dev/null @@ -1,107 +0,0 @@ -From 6ee4d4568314425079ae88229bb9abbff9b92b8b Mon Sep 17 00:00:00 2001 -From: Minda Chen -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 -Reviewed-by: Conor Dooley ---- - .../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 deleted file mode 100644 index a9e7b8975b5..00000000000 --- a/target/linux/starfive/patches-6.6/0018-PCI-microchip-Rename-two-PCIe-data-structures.patch +++ /dev/null @@ -1,347 +0,0 @@ -From 7c1c679bdd0b6b727248edbee77836024c935f91 Mon Sep 17 00:00:00 2001 -From: Minda Chen -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 -Reviewed-by: Conor Dooley ---- - .../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 deleted file mode 100644 index 0823502cfd3..00000000000 --- a/target/linux/starfive/patches-6.6/0019-PCI-microchip-Move-PCIe-host-data-structures-to-plda.patch +++ /dev/null @@ -1,87 +0,0 @@ -From a53cf9b237dd53c9538b51a8df592888935c8411 Mon Sep 17 00:00:00 2001 -From: Minda Chen -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 -Reviewed-by: Conor Dooley ---- - .../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 deleted file mode 100644 index 2bed6002164..00000000000 --- a/target/linux/starfive/patches-6.6/0020-PCI-microchip-Rename-two-setup-functions.patch +++ /dev/null @@ -1,76 +0,0 @@ -From d0e56d1ef7398bbf76be6e48d77943cbf644688e Mon Sep 17 00:00:00 2001 -From: Minda Chen -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 -Reviewed-by: Conor Dooley ---- - .../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 deleted file mode 100644 index de6868b9f6b..00000000000 --- a/target/linux/starfive/patches-6.6/0021-PCI-microchip-Change-the-argument-of-plda_pcie_setup.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 2fd7c88ef318fd39023ce1eb73f37a29fbd25d74 Mon Sep 17 00:00:00 2001 -From: Minda Chen -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 -Reviewed-by: Conor Dooley ---- - 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 deleted file mode 100644 index 62f458be4a7..00000000000 --- a/target/linux/starfive/patches-6.6/0022-PCI-microchip-Move-setup-functions-to-pcie-plda-host.patch +++ /dev/null @@ -1,200 +0,0 @@ -From 201ce99897ff5fff2612cb633406e90c1b2acbcf Mon Sep 17 00:00:00 2001 -From: Minda Chen -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 -Reviewed-by: Conor Dooley ---- - 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 -+ */ -+ -+#include -+#include -+ -+#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 deleted file mode 100644 index 09c1633b6f6..00000000000 --- a/target/linux/starfive/patches-6.6/0023-PCI-microchip-Rename-interrupt-related-functions.patch +++ /dev/null @@ -1,336 +0,0 @@ -From 2a48bc45dcf8cbe736b594d013cfa9d682214c43 Mon Sep 17 00:00:00 2001 -From: Minda Chen -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 -Acked-by: Conor Dooley ---- - .../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 deleted file mode 100644 index 4071feb1b5d..00000000000 --- a/target/linux/starfive/patches-6.6/0024-PCI-microchip-Add-num_events-field-to-struct-plda_pc.patch +++ /dev/null @@ -1,65 +0,0 @@ -From ab04dadb45a4150c9fd55b97fdd7397f4739a629 Mon Sep 17 00:00:00 2001 -From: Minda Chen -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 -Reviewed-by: Conor Dooley ---- - 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 deleted file mode 100644 index 2b299e01e98..00000000000 --- a/target/linux/starfive/patches-6.6/0025-PCI-microchip-Add-request_event_irq-callback-functio.patch +++ /dev/null @@ -1,114 +0,0 @@ -From 9f202f211cc79eefecbb03715c884e54eb95a62c Mon Sep 17 00:00:00 2001 -From: Minda Chen -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 -Acked-by: Conor Dooley ---- - .../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 deleted file mode 100644 index 85b81432688..00000000000 --- a/target/linux/starfive/patches-6.6/0026-PCI-microchip-Add-INTx-and-MSI-event-num-to-struct-p.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 3cdc20d9cc029ba9444be111bf4e55fd5331ccbe Mon Sep 17 00:00:00 2001 -From: Minda Chen -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 -Acked-by: Conor Dooley ---- - 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 deleted file mode 100644 index a0cb4789b8c..00000000000 --- a/target/linux/starfive/patches-6.6/0027-PCI-microchip-Add-get_events-callback-and-add-PLDA-g.patch +++ /dev/null @@ -1,167 +0,0 @@ -From b4a38ef87661f21fe2fb3e085ae98f25f78aaf99 Mon Sep 17 00:00:00 2001 -From: Minda Chen -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 -Acked-by: Conor Dooley ---- - .../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 deleted file mode 100644 index 9ed8119b1e9..00000000000 --- a/target/linux/starfive/patches-6.6/0028-PCI-microchip-Add-event-irqchip-field-to-host-port-a.patch +++ /dev/null @@ -1,144 +0,0 @@ -From 229ea8e7b674eb5c9bc4f70d43df1bd02a79862a Mon Sep 17 00:00:00 2001 -From: Minda Chen -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 -Acked-by: Conor Dooley ---- - .../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 deleted file mode 100644 index 840e334d20c..00000000000 --- a/target/linux/starfive/patches-6.6/0029-PCI-microchip-Move-IRQ-functions-to-pcie-plda-host.c.patch +++ /dev/null @@ -1,1028 +0,0 @@ -From 6be452d8e61594790ae57b282a612ec0df473e61 Mon Sep 17 00:00:00 2001 -From: Minda Chen -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 -Acked-by: Conor Dooley ---- - .../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 - */ - -+#include -+#include -+#include - #include - #include - - #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 deleted file mode 100644 index dcd2310e5ec..00000000000 --- a/target/linux/starfive/patches-6.6/0030-pci-plda-Add-event-bitmap-field-to-struct-plda_pcie_.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 142fc300fd7511a217783dcfa342031d8ad70188 Mon Sep 17 00:00:00 2001 -From: Minda Chen -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 ---- - 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 deleted file mode 100644 index eb22849da64..00000000000 --- a/target/linux/starfive/patches-6.6/0031-PCI-plda-Add-host-init-deinit-and-map-bus-functions.patch +++ /dev/null @@ -1,256 +0,0 @@ -From 3b9991438094dc472dacb4555603bdc379653411 Mon Sep 17 00:00:00 2001 -From: Minda Chen -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 -Reviewed-by: Mason Huo ---- - 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 - */ -@@ -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 deleted file mode 100644 index 9e33f7d68ab..00000000000 --- a/target/linux/starfive/patches-6.6/0032-dt-bindings-PCI-Add-StarFive-JH7110-PCIe-controller.patch +++ /dev/null @@ -1,140 +0,0 @@ -From bc3f8207d9f0af3cb96a7eae232074a644a175f6 Mon Sep 17 00:00:00 2001 -From: Minda Chen -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 -Reviewed-by: Hal Feng -Reviewed-by: Conor Dooley -Reviewed-by: Rob Herring ---- - .../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 -+ -+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 -+ 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 deleted file mode 100644 index ff089604681..00000000000 --- a/target/linux/starfive/patches-6.6/0033-PCI-Add-PCIE_RESET_CONFIG_DEVICE_WAIT_MS-waiting-tim.patch +++ /dev/null @@ -1,55 +0,0 @@ -From abb20b7b8f5e3a7f36dbd6264e6d346275434154 Mon Sep 17 00:00:00 2001 -From: Kevin Xie -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 , 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 -Reviewed-by: Mason Huo -Acked-by: Bjorn Helgaas ---- - drivers/pci/pci.h | 16 ++++++++++++++++ - 1 file changed, 16 insertions(+) - ---- a/drivers/pci/pci.h -+++ b/drivers/pci/pci.h -@@ -22,6 +22,22 @@ - */ - #define PCIE_PME_TO_L2_TIMEOUT_US 10000 - -+/* -+ * As described in PCI base specification r6.0, section 6.6.1 , 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 deleted file mode 100644 index 45a549f4896..00000000000 --- a/target/linux/starfive/patches-6.6/0034-PCI-starfive-Add-JH7110-PCIe-controller.patch +++ /dev/null @@ -1,623 +0,0 @@ -From 323aedef34315b758dc30ba23e2cabca259bb4b2 Mon Sep 17 00:00:00 2001 -From: Minda Chen -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 -Co-developed-by: Kevin Xie -Reviewed-by: Mason Huo ---- - 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#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 deleted file mode 100644 index cf14242f4a1..00000000000 --- a/target/linux/starfive/patches-6.6/0035-ASoC-dt-bindings-Add-StarFive-JH7110-PWM-DAC-control.patch +++ /dev/null @@ -1,97 +0,0 @@ -From a306724fd4f32808d1e27efbd87019d56f60db20 Mon Sep 17 00:00:00 2001 -From: Hal Feng -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 -Signed-off-by: Hal Feng -Link: https://lore.kernel.org/r/20230814080618.10036-2-hal.feng@starfivetech.com -Signed-off-by: Mark Brown ---- - .../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 -+ -+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 deleted file mode 100644 index acc859317b8..00000000000 --- a/target/linux/starfive/patches-6.6/0036-ASoC-starfive-Add-JH7110-PWM-DAC-driver.patch +++ /dev/null @@ -1,574 +0,0 @@ -From a79d2ec524012e35e32a2c4ae2401d0aa763697d Mon Sep 17 00:00:00 2001 -From: Hal Feng -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 -Signed-off-by: Hal Feng -Link: https://lore.kernel.org/r/20230814080618.10036-3-hal.feng@starfivetech.com -Signed-off-by: Mark Brown ---- - 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 -+ * Hal Feng -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#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 "); -+MODULE_AUTHOR("Hal Feng "); -+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 deleted file mode 100644 index 4833067bac5..00000000000 --- a/target/linux/starfive/patches-6.6/0037-ASoC-Update-jh7110-PWM-DAC-for-ops-move.patch +++ /dev/null @@ -1,32 +0,0 @@ -From c6b693f990e1f89ab5af0a139da31401b8cda74f Mon Sep 17 00:00:00 2001 -From: Mark Brown -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 ---- - 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 deleted file mode 100644 index 9b5f553f8c0..00000000000 --- a/target/linux/starfive/patches-6.6/0038-ASoC-starfive-jh7110-pwmdac-Convert-to-platform-remo.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 312c3c407c363f0ec7417d2d389cbe936c503729 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= -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 -Link: https://lore.kernel.org/r/20231013221945.1489203-12-u.kleine-koenig@pengutronix.de -Signed-off-by: Mark Brown ---- - 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 deleted file mode 100644 index bcc9af2d2c3..00000000000 --- a/target/linux/starfive/patches-6.6/0039-dt-bindings-power-Add-power-domain-header-for-JH7110.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 8d84bac6d7471ba2e29b33d19a2ef887822e9cce Mon Sep 17 00:00:00 2001 -From: Changhuang Liang -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 -Signed-off-by: Conor Dooley -Link: https://lore.kernel.org/r/20230913-grumbly-rewrite-34c85539f2ed@spud -Signed-off-by: Ulf Hansson ---- - 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 - */ - #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 deleted file mode 100644 index 335193fbb63..00000000000 --- a/target/linux/starfive/patches-6.6/0040-pmdomain-starfive-Replace-SOC_STARFIVE-with-ARCH_STA.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 0ac8e8b0e65d242f455401df0cc6c6d4772216e6 Mon Sep 17 00:00:00 2001 -From: Changhuang Liang -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 -Reviewed-by: Walker Chen -Signed-off-by: Changhuang Liang -Signed-off-by: Conor Dooley -Link: https://lore.kernel.org/r/20230913-legibly-treachery-567cffcb5604@spud -Signed-off-by: Ulf Hansson ---- - 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 deleted file mode 100644 index 7425dd6dbb3..00000000000 --- a/target/linux/starfive/patches-6.6/0041-pmdomain-starfive-Extract-JH7110-pmu-private-operati.patch +++ /dev/null @@ -1,179 +0,0 @@ -From a1ba60e35ca7f1b85243054556ecde2e259619e1 Mon Sep 17 00:00:00 2001 -From: Changhuang Liang -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 -Reviewed-by: Walker Chen -Signed-off-by: Conor Dooley -Link: https://lore.kernel.org/r/20230913-slideshow-luckiness-38ff17de84c6@spud -Signed-off-by: Ulf Hansson ---- - 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 deleted file mode 100644 index 2563d5421c4..00000000000 --- a/target/linux/starfive/patches-6.6/0042-pmdomain-starfive-Add-JH7110-AON-PMU-support.patch +++ /dev/null @@ -1,122 +0,0 @@ -From 1bf849b606d0b4cae643f96685d3d3981643683d Mon Sep 17 00:00:00 2001 -From: Changhuang Liang -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 -Signed-off-by: Changhuang Liang -Signed-off-by: Conor Dooley -Link: https://lore.kernel.org/r/20230913-dude-imprecise-fc32622bc947@spud -Signed-off-by: Ulf Hansson ---- - 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 -@@ -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 "); -+MODULE_AUTHOR("Changhuang Liang "); - 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 deleted file mode 100644 index 52be89f29e9..00000000000 --- a/target/linux/starfive/patches-6.6/0043-pmdomain-Prepare-to-move-Kconfig-files-into-the-pmdo.patch +++ /dev/null @@ -1,36 +0,0 @@ -From dff6605dcd1fc1e2af1437e59187a6f71ce389cd Mon Sep 17 00:00:00 2001 -From: Ulf Hansson -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 -Signed-off-by: Ulf Hansson ---- - 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 deleted file mode 100644 index 909f4cc63a1..00000000000 --- a/target/linux/starfive/patches-6.6/0044-pmdomain-starfive-Move-Kconfig-file-to-the-pmdomain-.patch +++ /dev/null @@ -1,69 +0,0 @@ -From de12fe43dbd0ea9fa980ffa05822bd7fd5eed330 Mon Sep 17 00:00:00 2001 -From: Ulf Hansson -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 -Cc: Conor Dooley -Acked-by: Conor Dooley -Signed-off-by: Ulf Hansson ---- - 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 deleted file mode 100644 index c6e00125282..00000000000 --- a/target/linux/starfive/patches-6.6/0045-dt-bindings-power-Update-prefixes-for-AON-power-doma.patch +++ /dev/null @@ -1,31 +0,0 @@ -From cac9ce9c7f388a741389b1ec47af65420254db55 Mon Sep 17 00:00:00 2001 -From: Changhuang Liang -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 -Signed-off-by: Changhuang Liang -Acked-by: Conor Dooley -Reviewed-by: Geert Uytterhoeven -Link: https://lore.kernel.org/r/20230927130734.9921-2-changhuang.liang@starfivetech.com -Signed-off-by: Ulf Hansson ---- - 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 deleted file mode 100644 index 5cb89ae0524..00000000000 --- a/target/linux/starfive/patches-6.6/0046-pmdomain-starfive-Update-prefixes-for-AON-power-doma.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 3ea89ffbd6cc5a15acca6bc2130572f8bd85b9d4 Mon Sep 17 00:00:00 2001 -From: Changhuang Liang -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 -Signed-off-by: Changhuang Liang -Link: https://lore.kernel.org/r/20230927130734.9921-3-changhuang.liang@starfivetech.com -Signed-off-by: Ulf Hansson ---- - 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 deleted file mode 100644 index 782e71a0eb2..00000000000 --- a/target/linux/starfive/patches-6.6/0047-riscv-dts-starfive-pinfunc-Fix-the-pins-name-of-I2ST.patch +++ /dev/null @@ -1,30 +0,0 @@ -From e7e3d62b7a470ddf15e30574232b52b2e23ba606 Mon Sep 17 00:00:00 2001 -From: Xingyu Wu -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 -Reviewed-by: Walker Chen -Acked-by: Rob Herring -Signed-off-by: Conor Dooley ---- - 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 deleted file mode 100644 index 75dd965c940..00000000000 --- a/target/linux/starfive/patches-6.6/0048-riscv-dts-starfive-Add-full-support-except-VIN-and-V.patch +++ /dev/null @@ -1,536 +0,0 @@ -From a3d3f611f31fa2dca3deefa7cd443abca02e03fa Mon Sep 17 00:00:00 2001 -From: Hal Feng -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 ---- - .../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,6 +231,24 @@ - 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>; -@@ -235,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>; -@@ -340,6 +415,46 @@ - }; - }; - -+ i2srx_pins: i2srx-0 { -+ clk-sd-pins { -+ pinmux = , -+ , -+ , -+ , -+ ; -+ input-enable; -+ }; -+ }; -+ -+ i2stx1_pins: i2stx1-0 { -+ sd-pins { -+ pinmux = ; -+ bias-disable; -+ input-disable; -+ }; -+ }; -+ -+ mclk_ext_pins: mclk-ext-0 { -+ mclk-ext-pins { -+ pinmux = ; -+ input-enable; -+ }; -+ }; -+ - mmc0_pins: mmc0-0 { - rst-pins { - pinmux = ; - }; - }; -+ -+ pcie0_pins: pcie0-0 { -+ clkreq-pins { -+ pinmux = ; -+ bias-pull-down; -+ drive-strength = <2>; -+ input-enable; -+ input-schmitt-disable; -+ slew-rate = <0>; -+ }; -+ -+ wake-pins { -+ pinmux = ; -+ bias-pull-up; -+ drive-strength = <2>; -+ input-enable; -+ input-schmitt-disable; -+ slew-rate = <0>; -+ }; -+ }; -+ -+ pcie1_pins: pcie1-0 { -+ clkreq-pins { -+ pinmux = ; -+ bias-pull-down; -+ drive-strength = <2>; -+ input-enable; -+ input-schmitt-disable; -+ slew-rate = <0>; -+ }; -+ -+ wake-pins { -+ pinmux = ; -+ bias-pull-up; -+ drive-strength = <2>; -+ input-enable; -+ input-schmitt-disable; -+ slew-rate = <0>; -+ }; -+ }; -+ -+ pwm_pins: pwm-0 { -+ pwm-pins { -+ pinmux = , -+ ; -+ bias-disable; -+ drive-strength = <12>; -+ input-disable; -+ input-schmitt-disable; -+ slew-rate = <0>; -+ }; -+ }; -+ -+ pwmdac_pins: pwmdac-0 { -+ pwmdac-pins { -+ pinmux = , -+ ; -+ 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 deleted file mode 100644 index 5f2c94914f7..00000000000 --- a/target/linux/starfive/patches-6.6/0049-MAINTAINERS-Update-all-StarFive-entries.patch +++ /dev/null @@ -1,147 +0,0 @@ -From ae7b57a0c69953f5ec06a378aedeed4c86637998 Mon Sep 17 00:00:00 2001 -From: Hal Feng -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 ---- - MAINTAINERS | 61 +++++++++++++++++++++++++++++++++++++++++++++++++---- - 1 file changed, 57 insertions(+), 4 deletions(-) - ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -7054,6 +7054,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 -+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 - L: dri-devel@lists.freedesktop.org -@@ -16018,6 +16026,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 -+M: Hal Feng -+S: Supported -+F: Documentation/devicetree/bindings/pwm/opencores,pwm.yaml -+F: drivers/pwm/pwm-ocores.c -+ - OPENRISC ARCHITECTURE - M: Jonas Bonn - M: Stefan Kristiansson -@@ -16429,6 +16444,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 -+M: Kevin Xie -+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 - M: Yoshihiro Shimoda -@@ -16660,7 +16683,7 @@ M: Daire McNamara -@@ -16684,6 +16707,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 -+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 - L: linux-pci@vger.kernel.org -@@ -18456,7 +18486,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 -@@ -20437,6 +20467,15 @@ M: Ion Badulescu - S: Odd Fixes - F: drivers/net/ethernet/adaptec/starfire* - -+STARFIVE CAMERA SUBSYSTEM DRIVER -+M: Jack Zhu -+M: Changhuang Liang -+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 - M: William Qiu -@@ -20475,6 +20514,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 -+M: Xingyu Wu -+S: Supported -+F: Documentation/devicetree/bindings/sound/starfive,jh7110-pwmdac.yaml -+F: sound/soc/starfive/jh7110_pwmdac.c -+ - STARFIVE JH7110 SYSCON - M: William Qiu - M: Xingyu Wu -@@ -20522,9 +20568,10 @@ F: drivers/usb/cdns3/cdns3-starfive.c - - STARFIVE JH71XX PMU CONTROLLER DRIVER - M: Walker Chen -+M: Changhuang Liang - 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 -@@ -20532,7 +20579,13 @@ M: Conor Dooley - 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 -+M: Xingyu Wu -+S: Supported -+F: Documentation/devicetree/bindings/timer/starfive,jh7110-timer.yaml -+F: drivers/clocksource/timer-jh7110.c - - STARFIVE TRNG DRIVER - M: Jia Jie Ho 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 deleted file mode 100644 index a38a8858943..00000000000 --- a/target/linux/starfive/patches-6.6/0050-mmc-starfive-Change-the-voltage-to-adapt-to-JH7110-E.patch +++ /dev/null @@ -1,64 +0,0 @@ -From e394195396995456ef98f52ac123c0cb64687748 Mon Sep 17 00:00:00 2001 -From: William Qiu -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 -Signed-off-by: Hal Feng ---- - 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 - #include - #include -+#include - #include - #include - #include -@@ -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 deleted file mode 100644 index 485ab0d9e19..00000000000 --- a/target/linux/starfive/patches-6.6/0051-spi-spl022-Get-and-deassert-reset-in-probe.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 2cd3e51cb76d49d8db6274ebdc1ba1eb5c872f10 Mon Sep 17 00:00:00 2001 -From: "ziv.xu" -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 -Signed-off-by: Hal Feng ---- - 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 - #include - #include -+#include - - /* - * 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 deleted file mode 100644 index 65ca992201d..00000000000 --- a/target/linux/starfive/patches-6.6/0052-ASoC-dwc-i2s-Fix-getting-platform-data-error-for-Sta.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 9cc8de0cdc1600f460f618e342e1f524adad07c4 Mon Sep 17 00:00:00 2001 -From: Xingyu Wu -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 -Signed-off-by: Hal Feng ---- - 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 -@@ -916,7 +916,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 deleted file mode 100644 index 48d47dce760..00000000000 --- a/target/linux/starfive/patches-6.6/0053-ASoC-dwc-i2s-Add-RX-master-support-for-StarFive-JH71.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 1be9bd37fdb5f50162dba0158e1fee295ebca9aa Mon Sep 17 00:00:00 2001 -From: Xingyu Wu -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 -Signed-off-by: Hal Feng ---- - 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 -@@ -905,6 +905,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); -@@ -1085,11 +1106,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 deleted file mode 100644 index 51976c656ed..00000000000 --- a/target/linux/starfive/patches-6.6/0054-pinctrl-starfive-jh7110-Unset-.strict-in-pinmux_ops.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 1ec26ba377d8ae59cd09811ec78623a750a9c150 Mon Sep 17 00:00:00 2001 -From: Hal Feng -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 ---- - 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 deleted file mode 100644 index 39699e8b97f..00000000000 --- a/target/linux/starfive/patches-6.6/0055-mm-pgtable-generic.c-Export-symbol-__pte_offset_map.patch +++ /dev/null @@ -1,22 +0,0 @@ -From 005549a2bd839335b0e3dc4152f00f642b524f07 Mon Sep 17 00:00:00 2001 -From: Hal Feng -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 ---- - 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 deleted file mode 100644 index 7b803d39975..00000000000 --- a/target/linux/starfive/patches-6.6/0056-riscv-dts-starfive-Add-JH7110-EVB-device-tree.patch +++ /dev/null @@ -1,2623 +0,0 @@ -From 9f46b0d43f8945ff3a8b81ddc6567df370b60911 Mon Sep 17 00:00:00 2001 -From: Hal Feng -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 ---- - 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 -+ */ -+ -+#include "jh7110-pinfunc.h" -+ -+&sysgpio { -+ can0_pins: can0-0 { -+ can-pins { -+ pinmux = , -+ , -+ ; -+ input-enable; -+ }; -+ }; -+ -+ can1_pins: can1-0 { -+ can-pins { -+ pinmux = , -+ , -+ ; -+ drive-strength = <12>; -+ input-enable; -+ }; -+ }; -+ -+ dvp_pins: dvp-0 { -+ dvp-pins{ -+ pinmux = , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ ; -+ input-enable; -+ }; -+ }; -+ -+ emmc0_pins: emmc0-0 { -+ emmc-pins { -+ pinmux = , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ ; -+ bias-pull-up; -+ drive-strength = <12>; -+ input-enable; -+ slew-rate = <1>; -+ }; -+ }; -+ -+ emmc1_pins: emmc1-0 { -+ emmc-pins { -+ pinmux = , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ ; -+ bias-pull-up; -+ input-enable; -+ }; -+ }; -+ -+ gmac0_pins: gmac0-0 { -+ reset-pins { -+ pinmux = ; -+ bias-pull-up; -+ }; -+ }; -+ -+ gmac1_pins: gmac1-0 { -+ mdc-pins { -+ pinmux = ; -+ }; -+ }; -+ -+ hdmi_pins: hdmi-0 { -+ scl-pins { -+ pinmux = ; -+ bias-pull-up; -+ input-enable; -+ }; -+ -+ sda-pins { -+ pinmux = ; -+ bias-pull-up; -+ input-enable; -+ }; -+ -+ cec-pins { -+ pinmux = ; -+ bias-pull-up; -+ input-enable; -+ }; -+ -+ hpd-pins { -+ pinmux = ; -+ bias-disable; /* external pull-up */ -+ input-enable; -+ }; -+ }; -+ -+ i2c0_pins: i2c0-0 { -+ i2c-pins { -+ pinmux = , -+ ; -+ bias-pull-up; -+ input-enable; -+ input-schmitt-enable; -+ }; -+ }; -+ -+ i2c1_pins: i2c1-0 { -+ i2c-pins { -+ pinmux = , -+ ; -+ bias-pull-up; -+ input-enable; -+ input-schmitt-enable; -+ }; -+ }; -+ -+ i2c2_pins: i2c2-0 { -+ i2c-pins { -+ pinmux = , -+ ; -+ bias-pull-up; -+ input-enable; -+ input-schmitt-enable; -+ }; -+ }; -+ -+ i2c3_pins: i2c3-0 { -+ i2c-pins { -+ pinmux = , -+ ; -+ bias-pull-up; -+ input-enable; -+ input-schmitt-enable; -+ }; -+ }; -+ -+ i2c4_pins: i2c4-0 { -+ i2c-pins { -+ pinmux = , -+ ; -+ bias-pull-up; -+ input-enable; -+ input-schmitt-enable; -+ }; -+ }; -+ -+ i2c5_pins: i2c5-0 { -+ i2c-pins { -+ pinmux = , -+ ; -+ bias-pull-up; -+ input-enable; -+ input-schmitt-enable; -+ }; -+ }; -+ -+ i2c6_pins: i2c6-0 { -+ i2c-pins { -+ pinmux = , -+ ; -+ bias-pull-up; -+ input-enable; -+ input-schmitt-enable; -+ }; -+ }; -+ -+ i2s_clk_pins: i2s-clk-0 { -+ bclk-lrck-pins { -+ pinmux = , -+ , -+ , -+ ; -+ input-enable; -+ }; -+ }; -+ -+ i2srx_clk_pins: i2srx-clk-0 { -+ mclk-pins { -+ pinmux = ; -+ input-enable; -+ }; -+ }; -+ -+ i2srx_pins: i2srx-0 { -+ i2srx-pins { -+ pinmux = ; -+ input-enable; -+ }; -+ }; -+ -+ i2stx_pins: i2stx-0 { -+ i2stx-pins { -+ pinmux = ; -+ input-enable; -+ }; -+ }; -+ -+ mclk_ext_pins: mclk-ext-0 { -+ mclk-ext-pins { -+ pinmux = ; -+ input-enable; -+ }; -+ }; -+ -+ pdm_pins: pdm-0 { -+ pdm-pins { -+ pinmux = , -+ ; -+ input-enable; -+ }; -+ }; -+ -+ pwm_ch0to3_pins: pwm-ch0to3-0 { -+ pwm-pins { -+ pinmux = , -+ , -+ , -+ ; -+ drive-strength = <12>; -+ }; -+ }; -+ -+ pwmdac_pins: pwmdac-0 { -+ pwmdac-pins { -+ pinmux = , -+ ; -+ }; -+ }; -+ -+ rgb_pad_pins: rgb-pad-pins { -+ rgb-0-pins { -+ pinmux = ; -+ drive-strength = <12>; -+ input-disable; -+ slew-rate = <1>; -+ }; -+ -+ rgb-pins { -+ pinmux = , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ ; -+ drive-strength = <12>; -+ input-disable; -+ }; -+ }; -+ -+ sdcard0_pins: sdcard0-0 { -+ sdcard-pins { -+ pinmux = , -+ , -+ , -+ , -+ , -+ , -+ ; -+ bias-pull-up; -+ drive-strength = <12>; -+ input-enable; -+ slew-rate = <1>; -+ }; -+ }; -+ -+ sdcard1_pins: sdcard1-0 { -+ sdcard-pins { -+ pinmux = , -+ , -+ , -+ , -+ , -+ ; -+ bias-pull-up; -+ input-enable; -+ }; -+ }; -+ -+ spdif_pins: spdif-0 { -+ spdif-pins { -+ pinmux = ; -+ bias-pull-up; -+ input-enable; -+ }; -+ }; -+ -+ spi0_pins: spi0-0 { -+ mosi-pins { -+ pinmux = ; -+ bias-disable; -+ input-disable; -+ input-schmitt-disable; -+ }; -+ -+ miso-pins { -+ pinmux = ; -+ bias-pull-up; -+ input-enable; -+ input-schmitt-enable; -+ }; -+ -+ sck-pins { -+ pinmux = ; -+ bias-disable; -+ input-disable; -+ input-schmitt-disable; -+ }; -+ -+ ss-pins { -+ pinmux = ; -+ bias-disable; -+ input-disable; -+ input-schmitt-disable; -+ }; -+ }; -+ -+ spi1_pins: spi1-0 { -+ mosi-pins { -+ pinmux = ; -+ bias-disable; -+ input-disable; -+ input-schmitt-disable; -+ }; -+ -+ miso-pins { -+ pinmux = ; -+ bias-pull-up; -+ input-enable; -+ input-schmitt-enable; -+ }; -+ -+ sck-pins { -+ pinmux = ; -+ bias-disable; -+ input-disable; -+ input-schmitt-disable; -+ }; -+ -+ ss-pins { -+ pinmux = ; -+ bias-disable; -+ input-disable; -+ input-schmitt-disable; -+ }; -+ }; -+ -+ spi2_pins: spi2-0 { -+ mosi-pins { -+ pinmux = ; -+ bias-disable; -+ input-disable; -+ input-schmitt-disable; -+ }; -+ -+ miso-pins { -+ pinmux = ; -+ bias-pull-up; -+ input-enable; -+ input-schmitt-enable; -+ }; -+ -+ sck-pins { -+ pinmux = ; -+ bias-disable; -+ input-disable; -+ input-schmitt-disable; -+ }; -+ -+ ss-pins { -+ pinmux = ; -+ bias-disable; -+ input-disable; -+ input-schmitt-disable; -+ }; -+ }; -+ -+ spi3_pins: spi3-0 { -+ mosi-pins { -+ pinmux = ; -+ bias-disable; -+ input-disable; -+ input-schmitt-disable; -+ }; -+ -+ miso-pins { -+ pinmux = ; -+ bias-pull-up; -+ input-enable; -+ input-schmitt-enable; -+ }; -+ -+ sck-pins { -+ pinmux = ; -+ bias-disable; -+ input-disable; -+ input-schmitt-disable; -+ }; -+ -+ ss-pins { -+ pinmux = ; -+ bias-disable; -+ input-disable; -+ input-schmitt-disable; -+ }; -+ }; -+ -+ spi4_pins: spi4-0 { -+ mosi-pins { -+ pinmux = ; -+ bias-disable; -+ input-disable; -+ input-schmitt-disable; -+ }; -+ -+ miso-pins { -+ pinmux = ; -+ bias-pull-up; -+ input-enable; -+ input-schmitt-enable; -+ }; -+ -+ sck-pins { -+ pinmux = ; -+ bias-disable; -+ input-disable; -+ input-schmitt-disable; -+ }; -+ -+ ss-pins { -+ pinmux = ; -+ bias-disable; -+ input-disable; -+ input-schmitt-disable; -+ }; -+ }; -+ -+ spi5_pins: spi5-0 { -+ mosi-pins { -+ pinmux = ; -+ bias-disable; -+ input-disable; -+ input-schmitt-disable; -+ }; -+ -+ miso-pins { -+ pinmux = ; -+ bias-pull-up; -+ input-enable; -+ input-schmitt-enable; -+ }; -+ -+ sck-pins { -+ pinmux = ; -+ bias-disable; -+ input-disable; -+ input-schmitt-disable; -+ }; -+ -+ ss-pins { -+ pinmux = ; -+ bias-disable; -+ input-disable; -+ input-schmitt-disable; -+ }; -+ }; -+ -+ spi6_pins: spi6-0 { -+ mosi-pins { -+ pinmux = ; -+ bias-disable; -+ input-disable; -+ input-schmitt-disable; -+ }; -+ -+ miso-pins { -+ pinmux = ; -+ bias-pull-up; -+ input-enable; -+ input-schmitt-enable; -+ }; -+ -+ sck-pins { -+ pinmux = ; -+ bias-disable; -+ input-disable; -+ input-schmitt-disable; -+ }; -+ -+ ss-pins { -+ pinmux = ; -+ bias-disable; -+ input-disable; -+ input-schmitt-disable; -+ }; -+ }; -+ -+ tdm_pins: tdm-0 { -+ tx-pins { -+ pinmux = ; -+ bias-pull-up; -+ drive-strength = <2>; -+ input-disable; -+ input-schmitt-disable; -+ slew-rate = <0>; -+ }; -+ -+ rx-pins { -+ pinmux = ; -+ input-enable; -+ }; -+ -+ sync-pins { -+ pinmux = ; -+ input-enable; -+ }; -+ -+ pcmclk-pins { -+ pinmux = ; -+ input-enable; -+ }; -+ }; -+ -+ uart0_pins: uart0-0 { -+ tx-pins { -+ pinmux = ; -+ bias-disable; -+ drive-strength = <12>; -+ input-disable; -+ input-schmitt-disable; -+ slew-rate = <0>; -+ }; -+ -+ rx-pins { -+ pinmux = ; -+ bias-pull-up; -+ drive-strength = <2>; -+ input-enable; -+ input-schmitt-enable; -+ slew-rate = <0>; -+ }; -+ }; -+ -+ uart1_pins: uart1-0 { -+ tx-pins { -+ pinmux = ; -+ bias-disable; -+ drive-strength = <12>; -+ input-disable; -+ input-schmitt-disable; -+ slew-rate = <0>; -+ }; -+ -+ rx-pins { -+ pinmux = ; -+ bias-pull-up; -+ drive-strength = <2>; -+ input-enable; -+ input-schmitt-enable; -+ slew-rate = <0>; -+ }; -+ -+ cts-pins { -+ pinmux = ; -+ input-enable; -+ }; -+ -+ rts-pins { -+ pinmux = ; -+ input-enable; -+ }; -+ }; -+ -+ uart2_pins: uart2-0 { -+ tx-pins { -+ pinmux = ; -+ bias-disable; -+ drive-strength = <12>; -+ input-disable; -+ input-schmitt-disable; -+ slew-rate = <0>; -+ }; -+ -+ rx-pins { -+ pinmux = ; -+ bias-pull-up; -+ drive-strength = <2>; -+ input-enable; -+ input-schmitt-enable; -+ slew-rate = <0>; -+ }; -+ -+ cts-pins { -+ pinmux = ; -+ input-enable; -+ }; -+ -+ rts-pins { -+ pinmux = ; -+ input-enable; -+ }; -+ }; -+ -+ uart3_pins: uart3-0 { -+ tx-pins { -+ pinmux = ; -+ bias-disable; -+ drive-strength = <12>; -+ input-disable; -+ input-schmitt-disable; -+ slew-rate = <0>; -+ }; -+ -+ rx-pins { -+ pinmux = ; -+ bias-pull-up; -+ drive-strength = <2>; -+ input-enable; -+ input-schmitt-enable; -+ slew-rate = <0>; -+ }; -+ }; -+ -+ uart4_pins: uart4-0 { -+ tx-pins { -+ pinmux = ; -+ bias-disable; -+ drive-strength = <12>; -+ input-disable; -+ input-schmitt-disable; -+ slew-rate = <0>; -+ }; -+ -+ rx-pins { -+ pinmux = ; -+ bias-pull-up; -+ drive-strength = <2>; -+ input-enable; -+ input-schmitt-enable; -+ slew-rate = <0>; -+ }; -+ -+ cts-pins { -+ pinmux = ; -+ input-enable; -+ }; -+ -+ rts-pins { -+ pinmux = ; -+ input-enable; -+ }; -+ }; -+ -+ uart5_pins: uart5-0 { -+ tx-pins { -+ pinmux = ; -+ bias-disable; -+ drive-strength = <12>; -+ input-disable; -+ input-schmitt-disable; -+ slew-rate = <0>; -+ }; -+ -+ rx-pins { -+ pinmux = ; -+ bias-pull-up; -+ drive-strength = <2>; -+ input-enable; -+ input-schmitt-enable; -+ slew-rate = <0>; -+ }; -+ -+ cts-pins { -+ pinmux = ; -+ input-enable; -+ }; -+ -+ rts-pins { -+ pinmux = ; -+ input-enable; -+ }; -+ }; -+ -+ usb_pins: usb-0 { -+ usb-pins { -+ pinmux = , -+ ; -+ input-enable; -+ }; -+ }; -+}; -+ -+&aongpio { -+ pwm_ch4to5_pins: pwm-ch4to5-0 { -+ pwm-pins { -+ pinmux = , -+ ; -+ drive-strength = <12>; -+ }; -+ }; -+ -+ pwm_ch6to7_pins: pwm-ch6to7-0 { -+ pwm-pins { -+ pinmux = , -+ ; -+ 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 -+ -+/ { -+ 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 = <¶llel_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 = ;*/ -+ /*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 deleted file mode 100644 index 7a23bf931be..00000000000 --- a/target/linux/starfive/patches-6.6/0057-riscv-dts-starfive-Add-JH7110-EVB-expanded-device-tr.patch +++ /dev/null @@ -1,728 +0,0 @@ -From cae7550054ca0cd940bbc1501ae5611f5d2957e6 Mon Sep 17 00:00:00 2001 -From: Hal Feng -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 ---- - 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 deleted file mode 100644 index a75ffc2aff8..00000000000 --- a/target/linux/starfive/patches-6.6/0058-riscv-dts-starfive-Add-evb-overlay-dtso-subdir.patch +++ /dev/null @@ -1,485 +0,0 @@ -From e9122ceaf2d8767753e2a126c14b29b78280446d Mon Sep 17 00:00:00 2001 -From: Hal Feng -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 ---- - 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 -+#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 -+#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 -+#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 = , -+ , -+ , -+ , -+ , -+ ; -+ 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 -+#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 -+#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 = , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ ; -+ bias-pull-up; -+ drive-strength = <12>; -+ input-enable; -+ slew-rate = <1>; -+ }; -+ }; -+ -+ dt_emmc1_pins: dt-emmc1-0 { -+ emmc-pins { -+ pinmux = , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ ; -+ 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 = , -+ ; -+ 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 -+#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 = , -+ , -+ , -+ ; -+ drive-strength = <12>; -+ }; -+ }; -+ }; -+ }; -+ -+ //aongpio -+ fragment@1 { -+ target-path = "/soc/pinctrl@17020000"; -+ __overlay__ { -+ dt_pwm_ch4to5_pins: dt-pwm-ch4to5-0 { -+ pwm-pins { -+ pinmux = , -+ ; -+ 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 deleted file mode 100644 index ddf72454eb7..00000000000 --- a/target/linux/starfive/patches-6.6/0059-riscv-configs-Add-starfive_jh7110_defconfig.patch +++ /dev/null @@ -1,385 +0,0 @@ -From 5c888fa081caf5d9473e733931d1c7b3d4b61e61 Mon Sep 17 00:00:00 2001 -From: Hal Feng -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 ---- - 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 deleted file mode 100644 index 68deb70c9b3..00000000000 --- a/target/linux/starfive/patches-6.6/0060-of-configfs-Add-configfs-function.patch +++ /dev/null @@ -1,318 +0,0 @@ -From 95c702022f5e4cb786719fcf90170334b1e562cc Mon Sep 17 00:00:00 2001 -From: Jianlong Huang -Date: Thu, 16 Jun 2022 17:13:57 +0800 -Subject: [PATCH 060/116] of: configfs: Add configfs function - -Signed-off-by: Jianlong Huang -Signed-off-by: Hal Feng ---- - 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 -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#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 deleted file mode 100644 index ade0f467a0f..00000000000 --- a/target/linux/starfive/patches-6.6/0061-usr-Add-gen_initramfs_list.sh.patch +++ /dev/null @@ -1,344 +0,0 @@ -From 7891826f8c2de9ee0f6459cf969f7b082e29b154 Mon Sep 17 00:00:00 2001 -From: Hal Feng -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 ---- - 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 -+# Copyright (C) 2006 Sam Ravnborg -+# -+# 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 ] [-u ] [-g ] {-d | } ... -+ -o Create compressed initramfs file named using -+ gen_init_cpio and compressor depending on the extension -+ -u User ID to map to user ID 0 (root). -+ is only meaningful if is a -+ directory. "squash" forces all files to uid 0. -+ -g Group ID to map to group ID 0 (root). -+ is only meaningful if is a -+ directory. "squash" forces all files to gid 0. -+ File list or directory for cpio archive. -+ If 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 -+ 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 -+# -+# 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 deleted file mode 100644 index 05561f1c51b..00000000000 --- a/target/linux/starfive/patches-6.6/0062-i2c-designware-Delete-SMBus-functionalities.patch +++ /dev/null @@ -1,33 +0,0 @@ -From dcc2827ed6e701a65731c05b0297745559837217 Mon Sep 17 00:00:00 2001 -From: Hal Feng -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 ---- - 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 - #include - --#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 deleted file mode 100644 index 43a7e5ba0d3..00000000000 --- a/target/linux/starfive/patches-6.6/0063-drivers-mtd-gigadevice-add-gd25lq256d-32M-flash-supp.patch +++ /dev/null @@ -1,26 +0,0 @@ -From b61cefc6c785aa8a7177a0b535db746fd0047bd8 Mon Sep 17 00:00:00 2001 -From: Ziv Xu -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 ---- - 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 deleted file mode 100644 index b733110f7d1..00000000000 --- a/target/linux/starfive/patches-6.6/0064-driver-mailbox-Add-mailbox-driver.patch +++ /dev/null @@ -1,808 +0,0 @@ -From 76bc13aa12bd111f5da01e107f8d487b20b5a40c Mon Sep 17 00:00:00 2001 -From: "shanlong.li" -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 -Signed-off-by: Hal Feng ---- - 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 -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#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, "\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 -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#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 "); -+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 deleted file mode 100644 index 0257cb004bd..00000000000 --- a/target/linux/starfive/patches-6.6/0065-driver-rtc-Add-StarFive-JH7110-rtc-driver.patch +++ /dev/null @@ -1,789 +0,0 @@ -From 0f44bd6bec708782f38bba4d03deecf927d1c83d Mon Sep 17 00:00:00 2001 -From: "ziv.xu" -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 -Signed-off-by: Hal Feng ---- - 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* 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 "); -+MODULE_AUTHOR("Hal Feng "); -+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 deleted file mode 100644 index 4fd92a46dc7..00000000000 --- a/target/linux/starfive/patches-6.6/0066-uart-8250-Add-dw-auto-flow-ctrl-support.patch +++ /dev/null @@ -1,96 +0,0 @@ -From 552114b8cbbd956ad8466261b5f11b059eba82ca Mon Sep 17 00:00:00 2001 -From: Minda Chen -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 ---- - 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 (uart_console_registered(&uart->port)) ---- 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; -+ } - } - - /* -@@ -2822,7 +2835,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 deleted file mode 100644 index 18d735b92d9..00000000000 --- a/target/linux/starfive/patches-6.6/0067-driver-uart-fix-up-uart-communicate-fail.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 6edee93a89254f30c3387c88231e7ecec06ba84a Mon Sep 17 00:00:00 2001 -From: "shanlong.li" -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 ---- - 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 deleted file mode 100644 index 56efebda6ca..00000000000 --- a/target/linux/starfive/patches-6.6/0068-uart-8250-add-reset-operation-in-runtime-PM.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 777d288f03a0b350f6c2d4367b01a80d9f25cd6e Mon Sep 17 00:00:00 2001 -From: William Qiu -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 ---- - 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 deleted file mode 100644 index eb46a963144..00000000000 --- a/target/linux/starfive/patches-6.6/0069-dt-bindings-CAN-Add-StarFive-CAN-module.patch +++ /dev/null @@ -1,113 +0,0 @@ -From 5eda2331a252436756fb40861f01a7a38b1502c7 Mon Sep 17 00:00:00 2001 -From: William Qiu -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 ---- - .../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 deleted file mode 100644 index 1bb41dd079e..00000000000 --- a/target/linux/starfive/patches-6.6/0070-CAN-starfive-Add-CAN-engine-support.patch +++ /dev/null @@ -1,1317 +0,0 @@ -From b1fbe15b87be654b1b280a76ec1470917d79f720 Mon Sep 17 00:00:00 2001 -From: William Qiu -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 -Signed-off-by: Hal Feng ---- - 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#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 -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 ---- - 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 -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#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 "); -+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 -+ */ -+ -+#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 deleted file mode 100644 index 7b768a9bc5a..00000000000 --- a/target/linux/starfive/patches-6.6/0072-drivers-nvme-Add-precheck-and-delay-for-CQE-pending-.patch +++ /dev/null @@ -1,40 +0,0 @@ -From f0b4cffe4d1813305f783d208f260747ecc56c50 Mon Sep 17 00:00:00 2001 -From: "Kevin.xie" -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 ---- - 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 - #include - #include -+#include - - #include "trace.h" - #include "nvme.h" -@@ -1058,6 +1059,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 deleted file mode 100644 index fff01c4c8fd..00000000000 --- a/target/linux/starfive/patches-6.6/0073-RISC-V-Create-unique-identification-for-SoC-PMU.patch +++ /dev/null @@ -1,93 +0,0 @@ -From eb294df4b9fab46bc5dbf676edf51e28e06d1968 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Jo=C3=A3o=20M=C3=A1rio=20Domingos?= - -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 ---- - 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 deleted file mode 100644 index 177b3b32d8a..00000000000 --- a/target/linux/starfive/patches-6.6/0074-RISC-V-Support-CPUID-for-risc-v-in-perf.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 1dc069ffadf4ce7817a716f9df2f480254e9b01d Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Jo=C3=A3o=20M=C3=A1rio=20Domingos?= - -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 -Signed-off-by: minda.chen ---- - 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 - -+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 deleted file mode 100644 index 01bb4f19ca5..00000000000 --- a/target/linux/starfive/patches-6.6/0075-RISC-V-Added-generic-pmu-events-mapfile.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 3e6ea12dda276c01a756764fcafa315b19860c33 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Jo=C3=A3o=20M=C3=A1rio=20Domingos?= - -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 ---- - .../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 deleted file mode 100644 index 152a60cfdaf..00000000000 --- a/target/linux/starfive/patches-6.6/0076-perf-sbi-disable-cpu-hotplug-callback.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 30e0cdcf9e05faa65ecde4ed8b70039568fdb660 Mon Sep 17 00:00:00 2001 -From: Minda Chen -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 -Signed-off-by: Hal Feng ---- - 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 deleted file mode 100644 index cdc6e4ec26f..00000000000 --- a/target/linux/starfive/patches-6.6/0077-dmaengine-dw-axi-dmac-Drop-unused-print-message.patch +++ /dev/null @@ -1,24 +0,0 @@ -From fc4b5c7c27e1b56b1f848e50511c4fd081b1b6c5 Mon Sep 17 00:00:00 2001 -From: Walker Chen -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 ---- - 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 deleted file mode 100644 index 2a828974ced..00000000000 --- a/target/linux/starfive/patches-6.6/0079-ASoC-codecs-Add-AC108-Codec-driver.patch +++ /dev/null @@ -1,4748 +0,0 @@ -From cd2254c6be9441ebacaa35693ecb5ce116b90622 Mon Sep 17 00:00:00 2001 -From: Xingyu Wu -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 -Signed-off-by: Hal Feng ---- - 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. -+ * -+ * PeterYang -+ * -+ * (C) Copyright 2014-2017 -+ * Reuuimlla Technology Co., Ltd. -+ * -+ * huangxin -+ * liushaohua -+ * -+ * 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#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<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<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<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<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<codec, SYSCLK_CTRL); -+ return (reg_val & (0x1<aif1_clken == 0){ -+ ret = ac101_update_bits(codec, SYSCLK_CTRL, (0x1<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<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< _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<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< 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<codec; -+ -+ AC101_DBG(); -+ -+ /* -+ * master or slave selection -+ * 0 = Master mode -+ * 1 = Slave mode -+ */ -+ reg_val = ac101_read(codec, AIF_CLK_CTRL); -+ reg_val &= ~(0x1<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<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<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<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<dev.kobj, &audio_debug_attr_group); -+ return 0; -+} -+ -+MODULE_DESCRIPTION("ASoC ac10x driver"); -+MODULE_AUTHOR("huangxin,liushaohua"); -+MODULE_AUTHOR("PeterYang"); ---- /dev/null -+++ b/sound/soc/codecs/ac101_regs.h -@@ -0,0 +1,431 @@ -+/* -+ * ac101_regs.h -+ * -+ * (C) Copyright 2017-2018 -+ * Seeed Technology Co., Ltd. -+ * -+ * PeterYang -+ * -+ * (C) Copyright 2010-2017 -+ * Reuuimlla Technology Co., Ltd. -+ * huangxin -+ * -+ * 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 -+ * -+ * 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#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*/ -+ ac108_multi_write(MOD_CLK_EN, 1 << I2S | 1 << ADC_DIGITAL | -+ 1 << MIC_OFFSET_CALIBRATION | 1 << ADC_ANALOG, ac10x); -+ /*0x22: Module reset de-asserted*/ -+ 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, ®, 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, ®, 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 */ -+ ac108_multi_write(MOD_CLK_EN, 0x0, ac10x); -+ /*0x22: Module reset asserted */ -+ 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"); -+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. -+ * -+ * PeterYang -+ * -+ * (C) Copyright 2010-2017 -+ * Reuuimlla Technology Co., Ltd. -+ * huangxin -+ * -+ * 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 -+ -+#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 deleted file mode 100644 index f2fb206947e..00000000000 --- a/target/linux/starfive/patches-6.6/0080-ASoC-starfive-Add-SPDIF-and-PCM-driver.patch +++ /dev/null @@ -1,1169 +0,0 @@ -From f03b7c834baef87e4f740e10a8bbcbfc57bd985a Mon Sep 17 00:00:00 2001 -From: Xingyu Wu -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 -Signed-off-by: Hal Feng ---- - 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#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<regmap, SPDIF_FIFO_CTRL, -+ ALLBITMASK, 0x20|(0x20<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 "); -+MODULE_AUTHOR("Xingyu Wu "); -+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 -+#include -+#include -+#include -+#include -+#include -+ -+#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 -+#include -+#include -+#include -+ -+#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 deleted file mode 100644 index 006760d7545..00000000000 --- a/target/linux/starfive/patches-6.6/0081-ASoC-starfive-Add-JH7110-PDM-driver.patch +++ /dev/null @@ -1,537 +0,0 @@ -From 9c4858f9fe4d8f8fe5cf347b3ca727016b7ba492 Mon Sep 17 00:00:00 2001 -From: Walker Chen -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 ---- - 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#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 "); -+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 deleted file mode 100644 index ed8a3af308c..00000000000 --- a/target/linux/starfive/patches-6.6/0082-dt-binding-input-Add-tink_ft5406.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 59cbdfeee0fc1ad382a0bc8f7fa897a9f5d03df0 Mon Sep 17 00:00:00 2001 -From: Changhuang Liang -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 ---- - .../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 -+ -+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 deleted file mode 100644 index f45085f495e..00000000000 --- a/target/linux/starfive/patches-6.6/0083-input-touchscreen-Add-tinker_ft5406-driver-support.patch +++ /dev/null @@ -1,444 +0,0 @@ -From 4800b6e0f2190d991cd4e5352167a9422841f195 Mon Sep 17 00:00:00 2001 -From: Changhuang Liang -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 ---- - 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#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, ®_addr, 1, &fw_ver[0], 1); -+ if (ret < 0) -+ goto error; -+ -+ reg_addr = FT_REG_FW_MIN_VER; -+ ret = fts_i2c_read(client, ®_addr, 1, &fw_ver[1], 1); -+ if (ret < 0) -+ goto error; -+ -+ reg_addr = FT_REG_FW_SUB_MIN_VER; -+ ret = fts_i2c_read(client, ®_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, ®_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<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 deleted file mode 100644 index 69d7c7f494d..00000000000 --- a/target/linux/starfive/patches-6.6/0084-dt-binding-media-Add-JH7110-Camera-Subsystem.patch +++ /dev/null @@ -1,246 +0,0 @@ -From b477a1a53553336edcfeb83be1b35817928daed8 Mon Sep 17 00:00:00 2001 -From: Changhuang Liang -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 -Signed-off-by: Jack Zhu ---- - .../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 -+ - Changhuang Liang -+ -+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 deleted file mode 100644 index b5d5f73f9d5..00000000000 --- a/target/linux/starfive/patches-6.6/0085-media-starfive-Add-vin-driver-support.patch +++ /dev/null @@ -1,24014 +0,0 @@ -From 908b10ebc95eb29caae8c4737b23a29af5c6298f Mon Sep 17 00:00:00 2001 -From: Changhuang Liang -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 ---- - 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#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 +