From f7b67e96b4a40dcaf9ed464b42d18410b1c406af Mon Sep 17 00:00:00 2001 From: Mingzheng Xing Date: Wed, 7 May 2025 12:01:40 +0800 Subject: [PATCH] riscv: upgrade to 6.6.0-88.0.0 - riscv kernel upgrade to 6.6.0-88.0.0 - RISC-V: Remove unnecessary include from compat.h - KVM AIA: Enable HW_ACCL - spacemit k1 dts/clk/reset/pinctrl/gpio/uart support - Enable ROCm-related kernel configs and update openeuler_defconfig - kconfig: enable zstd-compressed firmware support Signed-off-by: Mingzheng Xing --- 0001-riscv-kernel.patch | 13177 +++++++++++++++++++++++++++++++++++++- kernel.spec | 10 +- 2 files changed, 12890 insertions(+), 297 deletions(-) diff --git a/0001-riscv-kernel.patch b/0001-riscv-kernel.patch index b284eb30..f04a5ac7 100644 --- a/0001-riscv-kernel.patch +++ b/0001-riscv-kernel.patch @@ -1,6 +1,6 @@ -From aeaeeb3c790bff7d8d8d9a31d62685fbef521318 Mon Sep 17 00:00:00 2001 +From 96d87d109c0c54f7d7471963566c4c6c8e571505 Mon Sep 17 00:00:00 2001 From: Mingzheng Xing -Date: Mon, 17 Mar 2025 12:34:24 +0800 +Date: Wed, 7 May 2025 11:28:20 +0800 Subject: [PATCH] riscv kernel Signed-off-by: Mingzheng Xing @@ -38,10 +38,10 @@ Signed-off-by: Mingzheng Xing arch/loongarch/include/asm/pgalloc.h | 1 + arch/mips/include/asm/pgalloc.h | 1 + arch/riscv/Kconfig | 41 +- - arch/riscv/Kconfig.socs | 12 + + arch/riscv/Kconfig.socs | 49 + arch/riscv/Makefile | 19 +- arch/riscv/Makefile.isa | 18 + - arch/riscv/boot/dts/Makefile | 1 + + arch/riscv/boot/dts/Makefile | 2 + arch/riscv/boot/dts/sophgo/Makefile | 7 + .../riscv/boot/dts/sophgo/mango-2sockets.dtsi | 699 + .../boot/dts/sophgo/mango-clock-socket0.dtsi | 124 + @@ -63,6 +63,10 @@ Signed-off-by: Mingzheng Xing .../boot/dts/sophgo/mango-top-intc2.dtsi | 62 + .../boot/dts/sophgo/mango-yixin-s2110.dts | 63 + arch/riscv/boot/dts/sophgo/mango.dtsi | 938 + + arch/riscv/boot/dts/spacemit/Makefile | 2 + + .../boot/dts/spacemit/k1-bananapi-f3.dts | 82 + + arch/riscv/boot/dts/spacemit/k1-x.dtsi | 642 + + .../riscv/boot/dts/spacemit/k1-x_pinctrl.dtsi | 1192 ++ arch/riscv/boot/dts/thead/Makefile | 3 +- .../boot/dts/thead/th1520-beaglev-ahead.dts | 222 +- .../dts/thead/th1520-lichee-module-4a.dtsi | 440 +- @@ -72,13 +76,17 @@ Signed-off-by: Mingzheng Xing .../boot/dts/thead/th1520-lpi4a-hx8279.dts | 63 + arch/riscv/boot/dts/thead/th1520.dtsi | 2048 +- arch/riscv/configs/defconfig | 22 +- - arch/riscv/configs/openeuler_defconfig | 1913 +- + arch/riscv/configs/k1_defconfig | 14 + + arch/riscv/configs/openeuler_defconfig | 1942 +- arch/riscv/configs/sg2042_defconfig | 9 + arch/riscv/configs/th1520_defconfig | 470 + arch/riscv/include/asm/barrier.h | 22 + + arch/riscv/include/asm/compat.h | 1 - arch/riscv/include/asm/errata_list.h | 32 +- arch/riscv/include/asm/hwcap.h | 1 + arch/riscv/include/asm/io.h | 4 + + arch/riscv/include/asm/kvm_aia_aplic.h | 58 - + arch/riscv/include/asm/kvm_aia_imsic.h | 38 - arch/riscv/include/asm/membarrier.h | 19 + arch/riscv/include/asm/pgalloc.h | 53 +- arch/riscv/include/asm/pgtable-64.h | 14 +- @@ -94,6 +102,10 @@ Signed-off-by: Mingzheng Xing arch/riscv/kernel/sbi-ipi.c | 46 +- arch/riscv/kernel/suspend.c | 44 + arch/riscv/kernel/vector.c | 3 +- + arch/riscv/kvm/aia.c | 35 +- + arch/riscv/kvm/aia_aplic.c | 2 +- + arch/riscv/kvm/aia_device.c | 2 +- + arch/riscv/kvm/aia_imsic.c | 2 +- arch/riscv/mm/dma-noncoherent.c | 9 +- arch/riscv/mm/pgtable.c | 2 + arch/riscv/mm/tlbflush.c | 31 + @@ -103,13 +115,27 @@ Signed-off-by: Mingzheng Xing drivers/char/ipmi/ipmi_si_hardcode.c | 26 +- drivers/char/ipmi/ipmi_si_intf.c | 3 +- drivers/char/ipmi/ipmi_si_pci.c | 6 + - drivers/clk/Kconfig | 1 + - drivers/clk/Makefile | 2 + + drivers/clk/Kconfig | 2 + + drivers/clk/Makefile | 3 + drivers/clk/sophgo/Makefile | 3 + - drivers/clk/sophgo/clk-dummy.c | 600 + + drivers/clk/sophgo/clk-dummy.c | 594 + drivers/clk/sophgo/clk-mango.c | 977 + - drivers/clk/sophgo/clk.c | 883 + + drivers/clk/sophgo/clk.c | 881 + drivers/clk/sophgo/clk.h | 152 + + drivers/clk/spacemit/Kconfig | 9 + + drivers/clk/spacemit/Makefile | 11 + + drivers/clk/spacemit/ccu-spacemit-k1x.c | 2123 ++ + drivers/clk/spacemit/ccu-spacemit-k1x.h | 81 + + drivers/clk/spacemit/ccu_ddn.c | 161 + + drivers/clk/spacemit/ccu_ddn.h | 86 + + drivers/clk/spacemit/ccu_ddr.c | 272 + + drivers/clk/spacemit/ccu_ddr.h | 44 + + drivers/clk/spacemit/ccu_dpll.c | 124 + + drivers/clk/spacemit/ccu_dpll.h | 76 + + drivers/clk/spacemit/ccu_mix.c | 502 + + drivers/clk/spacemit/ccu_mix.h | 380 + + drivers/clk/spacemit/ccu_pll.c | 286 + + drivers/clk/spacemit/ccu_pll.h | 79 + drivers/clk/xuantie/Kconfig | 12 + drivers/clk/xuantie/Makefile | 7 + drivers/clk/xuantie/clk-th1520-fm.c | 646 + @@ -138,7 +164,10 @@ Signed-off-by: Mingzheng Xing drivers/firmware/xuantie/th1520_aon.c | 341 + drivers/firmware/xuantie/th1520_aon_pd.c | 414 + drivers/firmware/xuantie/th1520_proc_debug.c | 173 + + drivers/gpio/Kconfig | 9 + + drivers/gpio/Makefile | 1 + drivers/gpio/gpio-dwapb.c | 15 +- + drivers/gpio/gpio-k1x.c | 407 + drivers/gpio/gpio-pca953x.c | 12 +- drivers/gpu/drm/Kconfig | 4 + drivers/gpu/drm/Makefile | 2 + @@ -974,8 +1003,9 @@ Signed-off-by: Mingzheng Xing drivers/phy/synopsys/Kconfig | 13 + drivers/phy/synopsys/Makefile | 3 + drivers/phy/synopsys/phy-dw-mipi-dphy.c | 824 + - drivers/pinctrl/Kconfig | 11 +- - drivers/pinctrl/Makefile | 2 + + drivers/pinctrl/Kconfig | 22 +- + drivers/pinctrl/Makefile | 3 + + drivers/pinctrl/pinctrl-spacemit-k1x.c | 2101 ++ drivers/pinctrl/pinctrl-th1520.c | 1180 ++ drivers/pinctrl/sophgo/Makefile | 2 + drivers/pinctrl/sophgo/pinctrl-mango.c | 453 + @@ -988,9 +1018,10 @@ Signed-off-by: Mingzheng Xing drivers/regulator/Kconfig | 10 + drivers/regulator/Makefile | 1 + drivers/regulator/th1520-aon-regulator.c | 770 + - drivers/reset/Kconfig | 10 + - drivers/reset/Makefile | 2 + + drivers/reset/Kconfig | 16 + + drivers/reset/Makefile | 3 + drivers/reset/reset-sophgo.c | 163 + + drivers/reset/reset-spacemit-k1x.c | 669 + drivers/reset/reset-th1520.c | 170 + drivers/rpmsg/Kconfig | 4 + drivers/rpmsg/Makefile | 1 + @@ -1216,6 +1247,9 @@ Signed-off-by: Mingzheng Xing drivers/tty/serial/8250/8250_dma.c | 134 +- drivers/tty/serial/8250/8250_dw.c | 2 +- drivers/tty/serial/8250/8250_port.c | 12 +- + drivers/tty/serial/Kconfig | 19 +- + drivers/tty/serial/Makefile | 1 + + drivers/tty/serial/spacemit_k1x_uart.c | 1979 ++ drivers/ufs/host/ufs-qcom.c | 9 +- drivers/usb/dwc3/Kconfig | 20 + drivers/usb/dwc3/Makefile | 2 + @@ -1229,6 +1263,7 @@ Signed-off-by: Mingzheng Xing include/drm/bridge/dw_hdmi.h | 5 + .../dt-bindings/clock/sophgo-mango-clock.h | 165 + include/dt-bindings/clock/sophgo.h | 15 + + .../dt-bindings/clock/spacemit-k1x-clock.h | 223 + include/dt-bindings/clock/th1520-audiosys.h | 35 + include/dt-bindings/clock/th1520-dspsys.h | 33 + .../dt-bindings/clock/th1520-fm-ap-clock.h | 513 + @@ -1237,7 +1272,9 @@ Signed-off-by: Mingzheng Xing include/dt-bindings/clock/th1520-vosys.h | 41 + include/dt-bindings/clock/th1520-vpsys.h | 26 + include/dt-bindings/firmware/xuantie/rsrc.h | 18 + + include/dt-bindings/pinctrl/k1-x-pinctrl.h | 198 + .../dt-bindings/reset/sophgo-mango-resets.h | 96 + + .../dt-bindings/reset/spacemit-k1x-reset.h | 126 + .../dt-bindings/reset/xuantie,th1520-reset.h | 28 + .../dt-bindings/soc/th1520_system_status.h | 38 + .../dt-bindings/soc/xuantie,th1520-iopmp.h | 41 + @@ -1312,7 +1349,7 @@ Signed-off-by: Mingzheng Xing .../riscv/thead/c900-legacy/microarch.json | 80 + .../arch/riscv/thead/th1520-ddr/metrics.json | 713 + .../thead/th1520-ddr/uncore-ddr-pmu.json | 1550 ++ - 1307 files changed, 559540 insertions(+), 728 deletions(-) + 1344 files changed, 571537 insertions(+), 848 deletions(-) create mode 100644 Documentation/devicetree/bindings/hwlock/xuantie,th1520-hwspinlock.yaml create mode 100644 Documentation/devicetree/bindings/iio/adc/thead,th1520-adc.yaml create mode 100644 Documentation/devicetree/bindings/iio/adc/xuantie,th1520-adc.yaml @@ -1357,17 +1394,38 @@ Signed-off-by: Mingzheng Xing create mode 100644 arch/riscv/boot/dts/sophgo/mango-top-intc2.dtsi create mode 100644 arch/riscv/boot/dts/sophgo/mango-yixin-s2110.dts create mode 100644 arch/riscv/boot/dts/sophgo/mango.dtsi + create mode 100644 arch/riscv/boot/dts/spacemit/Makefile + create mode 100644 arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts + create mode 100644 arch/riscv/boot/dts/spacemit/k1-x.dtsi + create mode 100644 arch/riscv/boot/dts/spacemit/k1-x_pinctrl.dtsi create mode 100644 arch/riscv/boot/dts/thead/th1520-lichee-pi-4a-16g.dts create mode 100644 arch/riscv/boot/dts/thead/th1520-lpi4a-dsi0.dts create mode 100644 arch/riscv/boot/dts/thead/th1520-lpi4a-hx8279.dts + create mode 100644 arch/riscv/configs/k1_defconfig create mode 100644 arch/riscv/configs/sg2042_defconfig create mode 100644 arch/riscv/configs/th1520_defconfig + delete mode 100644 arch/riscv/include/asm/kvm_aia_aplic.h + delete mode 100644 arch/riscv/include/asm/kvm_aia_imsic.h create mode 100644 arch/riscv/include/asm/sync_core.h create mode 100644 drivers/clk/sophgo/Makefile create mode 100644 drivers/clk/sophgo/clk-dummy.c create mode 100644 drivers/clk/sophgo/clk-mango.c create mode 100644 drivers/clk/sophgo/clk.c create mode 100644 drivers/clk/sophgo/clk.h + create mode 100644 drivers/clk/spacemit/Kconfig + create mode 100644 drivers/clk/spacemit/Makefile + create mode 100644 drivers/clk/spacemit/ccu-spacemit-k1x.c + create mode 100644 drivers/clk/spacemit/ccu-spacemit-k1x.h + create mode 100644 drivers/clk/spacemit/ccu_ddn.c + create mode 100644 drivers/clk/spacemit/ccu_ddn.h + create mode 100644 drivers/clk/spacemit/ccu_ddr.c + create mode 100644 drivers/clk/spacemit/ccu_ddr.h + create mode 100644 drivers/clk/spacemit/ccu_dpll.c + create mode 100644 drivers/clk/spacemit/ccu_dpll.h + create mode 100644 drivers/clk/spacemit/ccu_mix.c + create mode 100644 drivers/clk/spacemit/ccu_mix.h + create mode 100644 drivers/clk/spacemit/ccu_pll.c + create mode 100644 drivers/clk/spacemit/ccu_pll.h create mode 100644 drivers/clk/xuantie/Kconfig create mode 100644 drivers/clk/xuantie/Makefile create mode 100644 drivers/clk/xuantie/clk-th1520-fm.c @@ -1388,6 +1446,7 @@ Signed-off-by: Mingzheng Xing create mode 100644 drivers/firmware/xuantie/th1520_aon.c create mode 100644 drivers/firmware/xuantie/th1520_aon_pd.c create mode 100644 drivers/firmware/xuantie/th1520_proc_debug.c + create mode 100644 drivers/gpio/gpio-k1x.c create mode 100644 drivers/gpu/drm/img-rogue/Kconfig create mode 100644 drivers/gpu/drm/img-rogue/Makefile create mode 100644 drivers/gpu/drm/img-rogue/allocmem.c @@ -2157,6 +2216,7 @@ Signed-off-by: Mingzheng Xing create mode 100644 drivers/phy/synopsys/Kconfig create mode 100644 drivers/phy/synopsys/Makefile create mode 100644 drivers/phy/synopsys/phy-dw-mipi-dphy.c + create mode 100644 drivers/pinctrl/pinctrl-spacemit-k1x.c create mode 100644 drivers/pinctrl/pinctrl-th1520.c create mode 100644 drivers/pinctrl/sophgo/Makefile create mode 100644 drivers/pinctrl/sophgo/pinctrl-mango.c @@ -2166,6 +2226,7 @@ Signed-off-by: Mingzheng Xing create mode 100644 drivers/pwm/pwm-xuantie.c create mode 100644 drivers/regulator/th1520-aon-regulator.c create mode 100644 drivers/reset/reset-sophgo.c + create mode 100644 drivers/reset/reset-spacemit-k1x.c create mode 100644 drivers/reset/reset-th1520.c create mode 100644 drivers/rpmsg/th1520_rpmsg.c create mode 100644 drivers/rtc/rtc-astbmc.c @@ -2374,10 +2435,12 @@ Signed-off-by: Mingzheng Xing create mode 100644 drivers/spi/spi-dw-mmio-quad.c create mode 100644 drivers/spi/spi-dw-quad.c create mode 100644 drivers/spi/spi-dw-quad.h + create mode 100644 drivers/tty/serial/spacemit_k1x_uart.c create mode 100644 drivers/usb/dwc3/dwc3-xuantie.c create mode 100644 drivers/watchdog/th1520_wdt.c create mode 100644 include/dt-bindings/clock/sophgo-mango-clock.h create mode 100644 include/dt-bindings/clock/sophgo.h + create mode 100644 include/dt-bindings/clock/spacemit-k1x-clock.h create mode 100644 include/dt-bindings/clock/th1520-audiosys.h create mode 100644 include/dt-bindings/clock/th1520-dspsys.h create mode 100644 include/dt-bindings/clock/th1520-fm-ap-clock.h @@ -2386,7 +2449,9 @@ Signed-off-by: Mingzheng Xing create mode 100644 include/dt-bindings/clock/th1520-vosys.h create mode 100644 include/dt-bindings/clock/th1520-vpsys.h create mode 100644 include/dt-bindings/firmware/xuantie/rsrc.h + create mode 100644 include/dt-bindings/pinctrl/k1-x-pinctrl.h create mode 100644 include/dt-bindings/reset/sophgo-mango-resets.h + create mode 100644 include/dt-bindings/reset/spacemit-k1x-reset.h create mode 100644 include/dt-bindings/reset/xuantie,th1520-reset.h create mode 100644 include/dt-bindings/soc/th1520_system_status.h create mode 100644 include/dt-bindings/soc/xuantie,th1520-iopmp.h @@ -4376,7 +4441,7 @@ index 000000000000..2387804b1c63 +The barrier matches a full barrier in the proximity of the membarrier system call +entry, cf. membarrier_{private,global}_expedited(). diff --git a/MAINTAINERS b/MAINTAINERS -index b22778025fa0..bd37632b3ca5 100644 +index c6a3ac61989c..75b4a363fcec 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -13781,7 +13781,9 @@ M: Mathieu Desnoyers @@ -4580,7 +4645,7 @@ index 3be10e723b2c..7b9125dd1209 100644 bool "Kernel support for 32-bit U-mode" default 64BIT diff --git a/arch/riscv/Kconfig.socs b/arch/riscv/Kconfig.socs -index 30fd6a512828..81faf077bde7 100644 +index 30fd6a512828..d468306a1a5c 100644 --- a/arch/riscv/Kconfig.socs +++ b/arch/riscv/Kconfig.socs @@ -22,6 +22,11 @@ config SOC_SIFIVE @@ -4609,6 +4674,48 @@ index 30fd6a512828..81faf077bde7 100644 config ARCH_VIRT def_bool SOC_VIRT +@@ -111,4 +123,41 @@ config SOC_CANAAN_K210_DTB_SOURCE + + endif # ARCH_CANAAN + ++config SOC_SPACEMIT ++ bool "Spacemit SoCs" ++ select SIFIVE_PLIC ++ help ++ This enables support for Spacemit SoCs platform hardware. ++ ++if SOC_SPACEMIT ++ ++choice ++ prompt "Spacemit SoCs platform" ++ default SOC_SPACEMIT_K1 ++ help ++ choice Spacemit Soc platform ++ ++ config SOC_SPACEMIT_K1 ++ bool "k1" ++ help ++ select Spacemit k1 Platform SoCs. ++endchoice ++ ++if SOC_SPACEMIT_K1 ++ ++choice ++ prompt "Spacemit K1 serial SoCs" ++ default SOC_SPACEMIT_K1X ++ help ++ choice Spacemit K1 SoC platform ++ ++ config SOC_SPACEMIT_K1X ++ bool "k1-x" ++ help ++ This enables support for Spacemit k1-x Platform Hardware. ++endchoice ++ ++endif ++endif ++ + endmenu # "SoC selection" diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile index b43a6bb7e4dc..c33a055a06f3 100644 --- a/arch/riscv/Makefile @@ -4671,14 +4778,15 @@ index 000000000000..322a83958b96 +# Check if the toolchain supports Zihintpause extension +riscv-march-$(CONFIG_TOOLCHAIN_HAS_ZIHINTPAUSE) := $(riscv-march-y)_zihintpause diff --git a/arch/riscv/boot/dts/Makefile b/arch/riscv/boot/dts/Makefile -index f60a280abb15..72030fd727af 100644 +index f60a280abb15..513e9f338637 100644 --- a/arch/riscv/boot/dts/Makefile +++ b/arch/riscv/boot/dts/Makefile -@@ -4,6 +4,7 @@ subdir-y += canaan +@@ -4,6 +4,8 @@ subdir-y += canaan subdir-y += microchip subdir-y += renesas subdir-y += sifive +subdir-y += sophgo ++subdir-y += spacemit subdir-y += starfive subdir-y += thead @@ -12769,6 +12877,1948 @@ index 000000000000..57f304fc778f + stdout-path = "serial0"; + }; +}; +diff --git a/arch/riscv/boot/dts/spacemit/Makefile b/arch/riscv/boot/dts/spacemit/Makefile +new file mode 100644 +index 000000000000..bc18f5f5cec9 +--- /dev/null ++++ b/arch/riscv/boot/dts/spacemit/Makefile +@@ -0,0 +1,2 @@ ++dtb-$(CONFIG_SOC_SPACEMIT_K1X) += k1-bananapi-f3.dtb ++obj-$(CONFIG_BUILTIN_DTB) += $(addsuffix .o, $(dtb-y)) +diff --git a/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts b/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts +new file mode 100644 +index 000000000000..05fb67e4eb23 +--- /dev/null ++++ b/arch/riscv/boot/dts/spacemit/k1-bananapi-f3.dts +@@ -0,0 +1,82 @@ ++// SPDX-License-Identifier: (GPL-2.0 OR MIT) ++/* Copyright (c) 2023 Spacemit, Inc */ ++ ++/dts-v1/; ++ ++#include "k1-x.dtsi" ++#include "k1-x_pinctrl.dtsi" ++ ++/ { ++ model = "Banana Pi BPI-F3"; ++ ++ memory@0 { ++ device_type = "memory"; ++ reg = <0x0 0x00000000 0x0 0x80000000>; ++ }; ++ ++ memory@100000000 { ++ device_type = "memory"; ++ reg = <0x1 0x00000000 0x0 0x80000000>; ++ }; ++ ++ chosen { ++ bootargs = "earlycon=sbi console=ttySP0,115200n8 loglevel=8 rdinit=/init"; ++ stdout-path = "serial0:115200n8"; ++ }; ++}; ++ ++&pinctrl { ++ pinctrl-single,gpio-range = < ++ &range GPIO_49 2 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_3V_DS4) ++ &range GPIO_58 1 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_1V8_DS2) ++ &range GPIO_63 2 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_1V8_DS2) ++ &range GPIO_65 1 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_1V8_DS2) ++ &range GPIO_67 1 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_3V_DS4) ++ &range PRI_TDI 2 (MUX_MODE1 | EDGE_NONE | PULL_UP | PAD_1V8_DS2) ++ &range PRI_TCK 1 (MUX_MODE1 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2) ++ &range PRI_TDO 1 (MUX_MODE1 | EDGE_NONE | PULL_UP | PAD_1V8_DS2) ++ &range GPIO_74 1 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_1V8_DS2) ++ &range GPIO_80 1 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_3V_DS4) ++ &range GPIO_81 3 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_1V8_DS2) ++ &range GPIO_90 1 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2) ++ &range GPIO_91 2 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_1V8_DS2) ++ &range DVL0 1 (MUX_MODE1 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2) ++ &range DVL1 1 (MUX_MODE1 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS0) ++ &range GPIO_110 1 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2) ++ &range GPIO_111 1 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2) ++ &range GPIO_113 1 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2) ++ &range GPIO_114 1 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2) ++ &range GPIO_115 1 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2) ++ &range GPIO_116 1 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_1V8_DS2) ++ &range GPIO_118 1 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_1V8_DS2) ++ &range GPIO_123 1 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS0) ++ &range GPIO_124 1 (MUX_MODE0 | EDGE_NONE | PULL_UP | PAD_1V8_DS2) ++ &range GPIO_125 3 (MUX_MODE0 | EDGE_NONE | PULL_DOWN | PAD_1V8_DS2) ++ >; ++}; ++ ++&gpio{ ++ gpio-ranges = < ++ &pinctrl 49 GPIO_49 2 ++ &pinctrl 58 GPIO_58 1 ++ &pinctrl 63 GPIO_63 3 ++ &pinctrl 67 GPIO_67 1 ++ &pinctrl 70 PRI_TDI 4 ++ &pinctrl 74 GPIO_74 1 ++ &pinctrl 80 GPIO_80 4 ++ &pinctrl 90 GPIO_90 3 ++ &pinctrl 96 DVL0 2 ++ &pinctrl 110 GPIO_110 1 ++ &pinctrl 111 GPIO_111 1 ++ &pinctrl 113 GPIO_113 1 ++ &pinctrl 114 GPIO_114 3 ++ &pinctrl 118 GPIO_118 1 ++ &pinctrl 123 GPIO_123 5 ++ >; ++}; ++ ++&uart0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_uart0_2>; ++ status = "okay"; ++}; +diff --git a/arch/riscv/boot/dts/spacemit/k1-x.dtsi b/arch/riscv/boot/dts/spacemit/k1-x.dtsi +new file mode 100644 +index 000000000000..5efbbacb1278 +--- /dev/null ++++ b/arch/riscv/boot/dts/spacemit/k1-x.dtsi +@@ -0,0 +1,642 @@ ++// SPDX-License-Identifier: (GPL-2.0 OR MIT) ++/* Copyright (c) 2022 Spacemit, Inc */ ++ ++/dts-v1/; ++ ++#include ++#include ++/ { ++ compatible = "spacemit,k1-x"; ++ #address-cells = <2>; ++ #size-cells = <2>; ++ ++ aliases { ++ serial0 = &uart0; ++ serial1 = &uart2; ++ serial2 = &uart3; ++ serial3 = &uart4; ++ serial4 = &uart5; ++ serial5 = &uart6; ++ serial6 = &uart7; ++ serial7 = &uart8; ++ serial8 = &uart9; ++ }; ++ ++ cpus: cpus { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ timebase-frequency = <24000000>; ++ cpu_0: cpu@0 { ++ compatible = "spacemit,x60", "riscv"; ++ device_type = "cpu"; ++ model = "Spacemit(R) X60"; ++ reg = <0>; ++ status = "okay"; ++ riscv,isa = "rv64imafdcv"; ++ riscv,isa-base = "rv64i"; ++ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "v", ++ "zicbom", "zicboz", "zicntr", "zicond", ++ "zicsr", "zifencei", "zihintpause", "zihpm", ++ "zfh", "zfhmin", "zba", "zbb", "zbc", "zbs", ++ "zkt", "zvfh", "zvfhmin", "zvkt", "sscofpmf", ++ "sstc", "svinval", "svnapot", "svpbmt" ; ++ riscv,cbom-block-size = <64>; ++ riscv,cboz-block-size = <64>; ++ i-cache-block-size = <64>; ++ i-cache-size = <32768>; ++ i-cache-sets = <128>; ++ d-cache-block-size = <64>; ++ d-cache-size = <32768>; ++ d-cache-sets = <128>; ++ next-level-cache = <&clst0_l2_cache>; ++ mmu-type = "riscv,sv39"; ++ cpu-ai = "true"; ++ ++ cpu0_intc: interrupt-controller { ++ #interrupt-cells = <1>; ++ compatible = "riscv,cpu-intc"; ++ interrupt-controller; ++ }; ++ }; ++ ++ cpu_1: cpu@1 { ++ device_type = "cpu"; ++ reg = <1>; ++ status = "okay"; ++ compatible = "spacemit,x60", "riscv"; ++ model = "Spacemit(R) X60"; ++ riscv,isa = "rv64imafdcv"; ++ riscv,isa-base = "rv64i"; ++ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "v", ++ "zicbom", "zicboz", "zicntr", "zicond", ++ "zicsr", "zifencei", "zihintpause", "zihpm", ++ "zfh", "zfhmin", "zba", "zbb", "zbc", "zbs", ++ "zkt", "zvfh", "zvfhmin", "zvkt", "sscofpmf", ++ "sstc", "svinval", "svnapot", "svpbmt" ; ++ riscv,cbom-block-size = <64>; ++ riscv,cboz-block-size = <64>; ++ i-cache-block-size = <64>; ++ i-cache-size = <32768>; ++ i-cache-sets = <128>; ++ d-cache-block-size = <64>; ++ d-cache-size = <32768>; ++ d-cache-sets = <128>; ++ next-level-cache = <&clst0_l2_cache>; ++ mmu-type = "riscv,sv39"; ++ cpu-ai = "true"; ++ ++ cpu1_intc: interrupt-controller { ++ #interrupt-cells = <1>; ++ compatible = "riscv,cpu-intc"; ++ interrupt-controller; ++ }; ++ }; ++ ++ cpu_2: cpu@2 { ++ device_type = "cpu"; ++ reg = <2>; ++ status = "okay"; ++ compatible = "spacemit,x60", "riscv"; ++ model = "Spacemit(R) X60"; ++ riscv,isa = "rv64imafdcv"; ++ riscv,isa-base = "rv64i"; ++ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "v", ++ "zicbom", "zicboz", "zicntr", "zicond", ++ "zicsr", "zifencei", "zihintpause", "zihpm", ++ "zfh", "zfhmin", "zba", "zbb", "zbc", "zbs", ++ "zkt", "zvfh", "zvfhmin", "zvkt", "sscofpmf", ++ "sstc", "svinval", "svnapot", "svpbmt" ; ++ riscv,cbom-block-size = <64>; ++ riscv,cboz-block-size = <64>; ++ i-cache-block-size = <64>; ++ i-cache-size = <32768>; ++ i-cache-sets = <128>; ++ d-cache-block-size = <64>; ++ d-cache-size = <32768>; ++ d-cache-sets = <128>; ++ next-level-cache = <&clst0_l2_cache>; ++ mmu-type = "riscv,sv39"; ++ cpu-ai = "true"; ++ ++ cpu2_intc: interrupt-controller { ++ #interrupt-cells = <1>; ++ compatible = "riscv,cpu-intc"; ++ interrupt-controller; ++ }; ++ }; ++ ++ cpu_3: cpu@3 { ++ device_type = "cpu"; ++ reg = <3>; ++ status = "okay"; ++ compatible = "spacemit,x60", "riscv"; ++ model = "Spacemit(R) X60"; ++ riscv,isa = "rv64imafdcv"; ++ riscv,isa-base = "rv64i"; ++ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "v", ++ "zicbom", "zicboz", "zicntr", "zicond", ++ "zicsr", "zifencei", "zihintpause", "zihpm", ++ "zfh", "zfhmin", "zba", "zbb", "zbc", "zbs", ++ "zkt", "zvfh", "zvfhmin", "zvkt", "sscofpmf", ++ "sstc", "svinval", "svnapot", "svpbmt" ; ++ riscv,cbom-block-size = <64>; ++ riscv,cboz-block-size = <64>; ++ i-cache-block-size = <64>; ++ i-cache-size = <32768>; ++ i-cache-sets = <128>; ++ d-cache-block-size = <64>; ++ d-cache-size = <32768>; ++ d-cache-sets = <128>; ++ next-level-cache = <&clst0_l2_cache>; ++ mmu-type = "riscv,sv39"; ++ cpu-ai = "true"; ++ ++ cpu3_intc: interrupt-controller { ++ #interrupt-cells = <1>; ++ compatible = "riscv,cpu-intc"; ++ interrupt-controller; ++ }; ++ }; ++ ++ cpu_4: cpu@4 { ++ device_type = "cpu"; ++ reg = <4>; ++ status = "okay"; ++ compatible = "spacemit,x60", "riscv"; ++ model = "Spacemit(R) X60"; ++ riscv,isa = "rv64imafdcv"; ++ riscv,isa-base = "rv64i"; ++ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "v", ++ "zicbom", "zicboz", "zicntr", "zicond", ++ "zicsr", "zifencei", "zihintpause", "zihpm", ++ "zfh", "zfhmin", "zba", "zbb", "zbc", "zbs", ++ "zkt", "zvfh", "zvfhmin", "zvkt", "sscofpmf", ++ "sstc", "svinval", "svnapot", "svpbmt" ; ++ riscv,cbom-block-size = <64>; ++ riscv,cboz-block-size = <64>; ++ i-cache-block-size = <64>; ++ i-cache-size = <32768>; ++ i-cache-sets = <128>; ++ d-cache-block-size = <64>; ++ d-cache-size = <32768>; ++ d-cache-sets = <128>; ++ next-level-cache = <&clst1_l2_cache>; ++ mmu-type = "riscv,sv39"; ++ ++ cpu4_intc: interrupt-controller { ++ #interrupt-cells = <1>; ++ compatible = "riscv,cpu-intc"; ++ interrupt-controller; ++ }; ++ }; ++ ++ cpu_5: cpu@5 { ++ device_type = "cpu"; ++ reg = <5>; ++ status = "okay"; ++ compatible = "spacemit,x60", "riscv"; ++ model = "Spacemit(R) X60"; ++ riscv,isa = "rv64imafdcv"; ++ riscv,isa-base = "rv64i"; ++ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "v", ++ "zicbom", "zicboz", "zicntr", "zicond", ++ "zicsr", "zifencei", "zihintpause", "zihpm", ++ "zfh", "zfhmin", "zba", "zbb", "zbc", "zbs", ++ "zkt", "zvfh", "zvfhmin", "zvkt", "sscofpmf", ++ "sstc", "svinval", "svnapot", "svpbmt" ; ++ riscv,cbom-block-size = <64>; ++ riscv,cboz-block-size = <64>; ++ i-cache-block-size = <64>; ++ i-cache-size = <32768>; ++ i-cache-sets = <128>; ++ d-cache-block-size = <64>; ++ d-cache-size = <32768>; ++ d-cache-sets = <128>; ++ next-level-cache = <&clst1_l2_cache>; ++ mmu-type = "riscv,sv39"; ++ ++ cpu5_intc: interrupt-controller { ++ #interrupt-cells = <1>; ++ compatible = "riscv,cpu-intc"; ++ interrupt-controller; ++ }; ++ }; ++ ++ cpu_6: cpu@6 { ++ device_type = "cpu"; ++ reg = <6>; ++ status = "okay"; ++ compatible = "spacemit,x60", "riscv"; ++ model = "Spacemit(R) X60"; ++ riscv,isa = "rv64imafdcv"; ++ riscv,isa-base = "rv64i"; ++ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "v", ++ "zicbom", "zicboz", "zicntr", "zicond", ++ "zicsr", "zifencei", "zihintpause", "zihpm", ++ "zfh", "zfhmin", "zba", "zbb", "zbc", "zbs", ++ "zkt", "zvfh", "zvfhmin", "zvkt", "sscofpmf", ++ "sstc", "svinval", "svnapot", "svpbmt" ; ++ riscv,cbom-block-size = <64>; ++ riscv,cboz-block-size = <64>; ++ i-cache-block-size = <64>; ++ i-cache-size = <32768>; ++ i-cache-sets = <128>; ++ d-cache-block-size = <64>; ++ d-cache-size = <32768>; ++ d-cache-sets = <128>; ++ next-level-cache = <&clst1_l2_cache>; ++ mmu-type = "riscv,sv39"; ++ ++ cpu6_intc: interrupt-controller { ++ #interrupt-cells = <1>; ++ compatible = "riscv,cpu-intc"; ++ interrupt-controller; ++ }; ++ }; ++ ++ cpu_7: cpu@7 { ++ device_type = "cpu"; ++ reg = <7>; ++ status = "okay"; ++ compatible = "spacemit,x60", "riscv"; ++ model = "Spacemit(R) X60"; ++ riscv,isa = "rv64imafdcv"; ++ riscv,isa-base = "rv64i"; ++ riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "v", ++ "zicbom", "zicboz", "zicntr", "zicond", ++ "zicsr", "zifencei", "zihintpause", "zihpm", ++ "zfh", "zfhmin", "zba", "zbb", "zbc", "zbs", ++ "zkt", "zvfh", "zvfhmin", "zvkt", "sscofpmf", ++ "sstc", "svinval", "svnapot", "svpbmt" ; ++ riscv,cbom-block-size = <64>; ++ riscv,cboz-block-size = <64>; ++ i-cache-block-size = <64>; ++ i-cache-size = <32768>; ++ i-cache-sets = <128>; ++ d-cache-block-size = <64>; ++ d-cache-size = <32768>; ++ d-cache-sets = <128>; ++ next-level-cache = <&clst1_l2_cache>; ++ mmu-type = "riscv,sv39"; ++ ++ cpu7_intc: interrupt-controller { ++ #interrupt-cells = <1>; ++ compatible = "riscv,cpu-intc"; ++ interrupt-controller; ++ }; ++ }; ++ ++ cpu-map { ++ cluster0 { ++ core0 { ++ cpu = <&cpu_0>; ++ }; ++ ++ core1 { ++ cpu = <&cpu_1>; ++ }; ++ ++ core2 { ++ cpu = <&cpu_2>; ++ }; ++ ++ core3 { ++ cpu = <&cpu_3>; ++ }; ++ }; ++ ++ cluster1 { ++ core0 { ++ cpu = <&cpu_4>; ++ }; ++ ++ core1 { ++ cpu = <&cpu_5>; ++ }; ++ ++ core2 { ++ cpu = <&cpu_6>; ++ }; ++ ++ core3 { ++ cpu = <&cpu_7>; ++ }; ++ }; ++ }; ++ ++ clst0_l2_cache: l2-cache0 { ++ compatible = "cache"; ++ cache-block-size = <64>; ++ cache-level = <2>; ++ cache-size = <524288>; ++ cache-sets = <512>; ++ cache-unified; ++ }; ++ ++ clst1_l2_cache: l2-cache1 { ++ compatible = "cache"; ++ cache-block-size = <64>; ++ cache-level = <2>; ++ cache-size = <524288>; ++ cache-sets = <512>; ++ cache-unified; ++ }; ++ }; ++ ++ clocks { ++ #address-cells = <0x2>; ++ #size-cells = <0x2>; ++ ranges; ++ ++ vctcxo_24: clock-vctcxo_24 { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <24000000>; ++ clock-output-names = "vctcxo_24"; ++ }; ++ ++ vctcxo_3: clock-vctcxo_3 { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <3000000>; ++ clock-output-names = "vctcxo_3"; ++ }; ++ ++ vctcxo_1: clock-vctcxo_1 { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <1000000>; ++ clock-output-names = "vctcxo_1"; ++ }; ++ ++ pll1_2457p6_vco: clock-pll1_2457p6_vco { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <2457600000>; ++ clock-output-names = "pll1_2457p6_vco"; ++ }; ++ ++ clk_32k: clock-clk32k { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <32000>; ++ clock-output-names = "clk_32k"; ++ }; ++ ++ pll_clk_cluster0: clock-pll_clk_cluster0 { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <10000000>; ++ clock-output-names = "pll_clk_cluster0"; ++ }; ++ ++ pll_clk_cluster1: clock-pll_clk_cluster1 { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <10000000>; ++ clock-output-names = "pll_clk_cluster1"; ++ }; ++ }; ++ ++ soc: soc { ++ compatible = "simple-bus"; ++ #address-cells = <2>; ++ #size-cells = <2>; ++ dma-noncoherent; ++ ranges; ++ ++ clint0: clint@e4000000 { ++ compatible = "riscv,clint0"; ++ interrupts-extended = < ++ &cpu0_intc 3 &cpu0_intc 7 ++ &cpu1_intc 3 &cpu1_intc 7 ++ &cpu2_intc 3 &cpu2_intc 7 ++ &cpu3_intc 3 &cpu3_intc 7 ++ &cpu4_intc 3 &cpu4_intc 7 ++ &cpu5_intc 3 &cpu5_intc 7 ++ &cpu6_intc 3 &cpu6_intc 7 ++ &cpu7_intc 3 &cpu7_intc 7 ++ >; ++ reg = <0x0 0xE4000000 0x0 0x00010000>; ++ }; ++ ++ ccu: clock-controller@d4050000 { ++ compatible = "spacemit,k1x-clock"; ++ reg = <0x0 0xd4050000 0x0 0x209c>, ++ <0x0 0xd4282800 0x0 0x400>, ++ <0x0 0xd4015000 0x0 0x1000>, ++ <0x0 0xd4090000 0x0 0x1000>, ++ <0x0 0xd4282c00 0x0 0x400>, ++ <0x0 0xd8440000 0x0 0x98>, ++ <0x0 0xc0000000 0x0 0x4280>, ++ <0x0 0xf0610000 0x0 0x20>, ++ <0x0 0xc0880000 0x0 0x2050>, ++ <0x0 0xc0888000 0x0 0x30>; ++ reg-names = "mpmu", "apmu", "apbc", "apbs", "ciu", ++ "dciu", "ddrc", "apbc2", "rcpu", "rcpu2"; ++ clocks = <&vctcxo_24>, <&vctcxo_3>, <&vctcxo_1>, ++ <&pll1_2457p6_vco>, <&clk_32k>; ++ clock-names = "vctcxo_24", "vctcxo_3", "vctcxo_1", ++ "pll1_2457p6_vco", ++ "clk_32k"; ++ #clock-cells = <1>; ++ status = "okay"; ++ }; ++ ++ reset: reset-controller@d4050000 { ++ compatible = "spacemit,k1x-reset"; ++ reg = <0x0 0xd4050000 0x0 0x209c>, ++ <0x0 0xd4282800 0x0 0x400>, ++ <0x0 0xd4015000 0x0 0x1000>, ++ <0x0 0xd4090000 0x0 0x1000>, ++ <0x0 0xd4282c00 0x0 0x400>, ++ <0x0 0xd8440000 0x0 0x98>, ++ <0x0 0xc0000000 0x0 0x4280>, ++ <0x0 0xf0610000 0x0 0x20>, ++ <0x0 0xc0880000 0x0 0x2050>, ++ <0x0 0xc0888000 0x0 0x30>; ++ reg-names = "mpmu", "apmu", "apbc", "apbs", "ciu", ++ "dciu", "ddrc", "apbc2", "rcpu", "rcpu2"; ++ #reset-cells = <1>; ++ status = "okay"; ++ }; ++ ++ intc: interrupt-controller@e0000000 { ++ #interrupt-cells = <1>; ++ compatible = "riscv,plic0"; ++ interrupt-controller; ++ interrupts-extended = < ++ &cpu0_intc 11 &cpu0_intc 9 ++ &cpu1_intc 11 &cpu1_intc 9 ++ &cpu2_intc 11 &cpu2_intc 9 ++ &cpu3_intc 11 &cpu3_intc 9 ++ &cpu4_intc 11 &cpu4_intc 9 ++ &cpu5_intc 11 &cpu5_intc 9 ++ &cpu6_intc 11 &cpu6_intc 9 ++ &cpu7_intc 11 &cpu7_intc 9 ++ >; ++ reg = <0x0 0xE0000000 0x0 0x04000000>; ++ reg-names = "control"; ++ riscv,max-priority = <7>; ++ riscv,ndev = <159>; ++ }; ++ ++ pinctrl: pinctrl@d401e000 { ++ compatible = "pinctrl-spacemit-k1x"; ++ reg = <0x0 0xd401e000 0x0 0x250>, ++ <0x0 0xd4019800 0x0 0x10>, ++ <0x0 0xd4019000 0x0 0x800>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ #pinctrl-cells = <2>; ++ #gpio-range-cells = <3>; ++ ++ pinctrl-single,register-width = <32>; ++ pinctrl-single,function-mask = <0xff77>; ++ ++ clocks = <&ccu CLK_AIB>; ++ clock-names = "clk_aib"; ++ resets = <&reset RESET_AIB>; ++ reset-names = "aib_rst"; ++ ++ interrupt-parent = <&intc>; ++ interrupts = <60>; ++ interrupt-controller; ++ #interrupt-cells = <1>; ++ ++ range: gpio-range { ++ #pinctrl-single,gpio-range-cells = <3>; ++ }; ++ }; ++ ++ uart0: serial@d4017000 { ++ compatible = "spacemit,k1x-uart"; ++ reg = <0x0 0xd4017000 0x0 0x100>; ++ interrupt-parent = <&intc>; ++ interrupts = <42>; ++ clocks = <&ccu CLK_UART1>, <&ccu CLK_SLOW_UART>; ++ clock-names = "func", "gate"; ++ resets = <&reset RESET_UART1>; ++ reg-shift = <2>; ++ reg-io-width = <4>; ++ status = "disabled"; ++ }; ++ ++ uart2: uart@d4017100 { ++ compatible = "spacemit,k1x-uart"; ++ reg = <0x0 0xd4017100 0x0 0x100>; ++ interrupt-parent = <&intc>; ++ interrupts = <44>; ++ clocks = <&ccu CLK_UART2>, <&ccu CLK_SLOW_UART>; ++ clock-names = "func", "gate"; ++ resets = <&reset RESET_UART2>; ++ status = "disabled"; ++ }; ++ ++ uart3: uart@d4017200 { ++ compatible = "spacemit,k1x-uart"; ++ reg = <0x0 0xd4017200 0x0 0x100>; ++ interrupt-parent = <&intc>; ++ interrupts = <45>; ++ clocks = <&ccu CLK_UART3>, <&ccu CLK_SLOW_UART>; ++ clock-names = "func", "gate"; ++ resets = <&reset RESET_UART3>; ++ status = "disabled"; ++ }; ++ ++ uart4: uart@d4017300 { ++ compatible = "spacemit,k1x-uart"; ++ interrupt-parent = <&intc>; ++ reg = <0x0 0xd4017300 0x0 0x100>; ++ interrupts = <46>; ++ clocks = <&ccu CLK_UART4>, <&ccu CLK_SLOW_UART>; ++ clock-names = "func", "gate"; ++ resets = <&reset RESET_UART4>; ++ status = "disabled"; ++ }; ++ ++ uart5: uart@d4017400 { ++ compatible = "spacemit,k1x-uart"; ++ interrupt-parent = <&intc>; ++ reg = <0x0 0xd4017400 0x0 0x100>; ++ interrupts = <47>; ++ clocks = <&ccu CLK_UART5>, <&ccu CLK_SLOW_UART>; ++ clock-names = "func", "gate"; ++ resets = <&reset RESET_UART5>; ++ status = "disabled"; ++ }; ++ ++ uart6: uart@d4017500 { ++ compatible = "spacemit,k1x-uart"; ++ interrupt-parent = <&intc>; ++ reg = <0x0 0xd4017500 0x0 0x100>; ++ interrupts = <48>; ++ clocks = <&ccu CLK_UART6>, <&ccu CLK_SLOW_UART>; ++ clock-names = "func", "gate"; ++ resets = <&reset RESET_UART6>; ++ status = "disabled"; ++ }; ++ ++ uart7: uart@d4017600 { ++ compatible = "spacemit,k1x-uart"; ++ interrupt-parent = <&intc>; ++ reg = <0x0 0xd4017600 0x0 0x100>; ++ interrupts = <49>; ++ clocks = <&ccu CLK_UART7>, <&ccu CLK_SLOW_UART>; ++ clock-names = "func", "gate"; ++ resets = <&reset RESET_UART7>; ++ status = "disabled"; ++ }; ++ ++ uart8: uart@d4017700 { ++ compatible = "spacemit,k1x-uart"; ++ interrupt-parent = <&intc>; ++ reg = <0x0 0xd4017700 0x0 0x100>; ++ interrupts = <50>; ++ clocks = <&ccu CLK_UART8>, <&ccu CLK_SLOW_UART>; ++ clock-names = "func", "gate"; ++ resets = <&reset RESET_UART8>; ++ status = "disabled"; ++ }; ++ ++ uart9: uart@d4017800 { ++ compatible = "spacemit,k1x-uart"; ++ interrupt-parent = <&intc>; ++ reg = <0x0 0xd4017800 0x0 0x100>; ++ interrupts = <51>; ++ clocks = <&ccu CLK_UART9>, <&ccu CLK_SLOW_UART>; ++ clock-names = "func", "gate"; ++ resets = <&reset RESET_UART9>; ++ status = "disabled"; ++ }; ++ ++ gpio: gpio@d4019000 { ++ compatible = "spacemit,k1x-gpio"; ++ reg = <0x0 0xd4019000 0x0 0x800>; ++ gpio-controller; ++ #gpio-cells = <2>; ++ interrupts = <58>; ++ clocks = <&ccu CLK_GPIO>; ++ interrupt-names = "gpio_mux"; ++ interrupt-parent = <&intc>; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ ++ gcb0: gpio0 { ++ reg-offset = <0x0>; ++ }; ++ ++ gcb1: gpio1 { ++ reg-offset = <0x4>; ++ }; ++ ++ gcb2: gpio2 { ++ reg-offset = <0x8>; ++ }; ++ ++ gcb3: gpio3 { ++ reg-offset = <0x100>; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/riscv/boot/dts/spacemit/k1-x_pinctrl.dtsi b/arch/riscv/boot/dts/spacemit/k1-x_pinctrl.dtsi +new file mode 100644 +index 000000000000..46b826f6b681 +--- /dev/null ++++ b/arch/riscv/boot/dts/spacemit/k1-x_pinctrl.dtsi +@@ -0,0 +1,1192 @@ ++// SPDX-License-Identifier: (GPL-2.0 OR MIT) ++/* Copyright (c) 2023 Spacemit, Inc */ ++ ++#include ++/* Pin Configuration Node: */ ++/* Format: */ ++&pinctrl { ++ pinctrl_uart0_0: uart0_0_grp { ++ pinctrl-single,pins = < ++ K1X_PADCONF(MMC1_DAT3, MUX_MODE3, (EDGE_NONE | PULL_UP | PAD_3V_DS4)) ++ K1X_PADCONF(MMC1_DAT2, MUX_MODE3, (EDGE_NONE | PULL_UP | PAD_3V_DS4)) ++ >; ++ }; ++ ++ pinctrl_uart0_1: uart0_1_grp { ++ pinctrl-single,pins = < ++ K1X_PADCONF(MMC1_CMD, MUX_MODE1, (EDGE_NONE | PULL_UP | PAD_3V_DS4)) ++ K1X_PADCONF(GPIO_80, MUX_MODE3, (EDGE_NONE | PULL_UP | PAD_3V_DS4)) ++ >; ++ }; ++ ++ pinctrl_uart0_2: uart0_2_grp { ++ pinctrl-single,pins = < ++ K1X_PADCONF(GPIO_68, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_69, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_uart2: uart2_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_21, MUX_MODE1, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_22, MUX_MODE1, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_23, MUX_MODE1, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_24, MUX_MODE1, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_uart3_0: uart3_0_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_81, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_82, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_83, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_84, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_uart3_1: uart3_1_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_18, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_19, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_20, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_21, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_uart3_2: uart3_2_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_53, MUX_MODE4, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_54, MUX_MODE4, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_55, MUX_MODE4, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_56, MUX_MODE4, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_uart4_0: uart4_0_grp { ++ pinctrl-single,pins = < ++ K1X_PADCONF(QSPI_DAT1, MUX_MODE4, (EDGE_NONE | PULL_UP | PAD_3V_DS4)) ++ K1X_PADCONF(QSPI_DAT0, MUX_MODE4, (EDGE_NONE | PULL_UP | PAD_3V_DS4)) ++ >; ++ }; ++ ++ pinctrl_uart4_1: uart4_1_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_81, MUX_MODE3, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_82, MUX_MODE3, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_83, MUX_MODE3, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_84, MUX_MODE3, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_uart4_2: uart4_2_grp { ++ pinctrl-single,pins = < ++ K1X_PADCONF(GPIO_23, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_24, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_uart4_3: uart4_3_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_33, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_34, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_35, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_36, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_uart4_4: uart4_4_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_111, MUX_MODE4, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_112, MUX_MODE4, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_113, MUX_MODE4, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_114, MUX_MODE4, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_uart5_0: uart5_0_grp { ++ pinctrl-single,pins = < ++ K1X_PADCONF(QSPI_CLK, MUX_MODE3, (EDGE_NONE | PULL_UP | PAD_3V_DS4)) ++ K1X_PADCONF(QSPI_CSI, MUX_MODE3, (EDGE_NONE | PULL_UP | PAD_3V_DS4)) ++ >; ++ }; ++ ++ pinctrl_uart5_1: uart5_1_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_25, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_26, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_27, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_28, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_uart5_2: uart5_2_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_42, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_43, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_44, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_45, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_uart5_3: uart5_3_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(PRI_TDI, MUX_MODE4, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(PRI_TMS, MUX_MODE4, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(PRI_TCK, MUX_MODE4, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(PRI_TDO, MUX_MODE4, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_uart6_0: uart6_0_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_85, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_86, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_87, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_90, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_uart6_1: uart6_1_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_00, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_01, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_02, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_03, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_uart6_2: uart6_2_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_56, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_57, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_uart7_0: uart7_0_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_88, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_89, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_uart7_1: uart7_1_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_04, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_05, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_06, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_07, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_uart8_0: uart8_0_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_82, MUX_MODE4, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_83, MUX_MODE4, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_uart8_1: uart8_1_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_08, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_09, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_10, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_11, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_uart8_2: uart8_2_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_75, MUX_MODE4, (EDGE_NONE | PULL_UP | PAD_3V_DS4)) ++ K1X_PADCONF(GPIO_76, MUX_MODE4, (EDGE_NONE | PULL_UP | PAD_3V_DS4)) ++ K1X_PADCONF(GPIO_77, MUX_MODE4, (EDGE_NONE | PULL_UP | PAD_3V_DS4)) ++ K1X_PADCONF(GPIO_78, MUX_MODE4, (EDGE_NONE | PULL_UP | PAD_3V_DS4)) ++ >; ++ }; ++ ++ pinctrl_uart9_0: uart9_0_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_12, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_13, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_uart9_1: uart9_1_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_110, MUX_MODE3, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_115, MUX_MODE3, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_116, MUX_MODE3, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_117, MUX_MODE3, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_uart9_2: uart9_2_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(PRI_TCK, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(PRI_TDO, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_i2c0: i2c0_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_54, MUX_MODE1, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_55, MUX_MODE1, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_r_uart1: r_uart1_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_49, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_3V_DS4)) ++ K1X_PADCONF(GPIO_50, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_3V_DS4)) ++ K1X_PADCONF(GPIO_51, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_3V_DS4)) ++ K1X_PADCONF(GPIO_52, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_3V_DS4)) ++ >; ++ }; ++ ++ pinctrl_i2c1: i2c1_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_56, MUX_MODE1, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_57, MUX_MODE1, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_i2c2_0: i2c2_0_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_84, MUX_MODE4, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_85, MUX_MODE4, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_i2c2_1: i2c2_1_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(PRI_TDI, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(PRI_TMS, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_i2c2_2: i2c2_2_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_68, MUX_MODE3, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_69, MUX_MODE3, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_i2c3_0: i2c3_0_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_38, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_39, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_i2c3_1: i2c3_1_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_47, MUX_MODE4, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_48, MUX_MODE4, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_i2c3_2: i2c3_2_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_77, MUX_MODE3, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_78, MUX_MODE3, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_i2c4_0: i2c4_0_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_40, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_41, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_i2c4_1: i2c4_1_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_75, MUX_MODE5, (EDGE_NONE | PULL_UP | PAD_3V_DS2)) ++ K1X_PADCONF(GPIO_76, MUX_MODE5, (EDGE_NONE | PULL_UP | PAD_3V_DS2)) ++ >; ++ }; ++ ++ pinctrl_i2c4_2: i2c4_2_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_51, MUX_MODE4, (EDGE_NONE | PULL_UP | PAD_3V_DS2)) ++ K1X_PADCONF(GPIO_52, MUX_MODE4, (EDGE_NONE | PULL_UP | PAD_3V_DS2)) ++ >; ++ }; ++ ++ pinctrl_i2c5_0: i2c5_0_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_81, MUX_MODE5, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_82, MUX_MODE5, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_i2c5_1: i2c5_1_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_54, MUX_MODE5, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_55, MUX_MODE5, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_i2c6_0: i2c6_0_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_83, MUX_MODE5, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_90, MUX_MODE5, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_i2c6_1: i2c6_1_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_118, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_119, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_i2c6_2: i2c6_2_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_56, MUX_MODE5, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_57, MUX_MODE5, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_i2c7: i2c7_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_118, MUX_MODE1, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_119, MUX_MODE1, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_i2c8: i2c8_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(PWR_SCL, MUX_MODE0, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(PWR_SDA, MUX_MODE0, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_one_wire_0: one_wire_0_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_110, MUX_MODE5, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_one_wire_1: one_wire_1_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_47, MUX_MODE5, (EDGE_NONE | PULL_UP | PAD_3V_DS4)) ++ >; ++ }; ++ ++ pinctrl_ir_rx_0: ir_rx_0_grp { ++ pinctrl-single,pins = < ++ K1X_PADCONF(DVL1, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_ir_rx_1: ir_rx_1_grp { ++ pinctrl-single,pins = < ++ K1X_PADCONF(GPIO_79, MUX_MODE1, (EDGE_NONE | PULL_UP | PAD_3V_DS4)) ++ >; ++ }; ++ ++ pinctrl_ir_rx_2: ir_rx_2_grp { ++ pinctrl-single,pins = < ++ K1X_PADCONF(GPIO_58, MUX_MODE4, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_r_ir_rx_0: r_ir_rx_0_grp { ++ pinctrl-single,pins = < ++ K1X_PADCONF(GPIO_48, MUX_MODE3, (EDGE_NONE | PULL_UP | PAD_3V_DS4)) ++ >; ++ }; ++ ++ pinctrl_r_ir_rx_1: r_ir_rx_1_grp { ++ pinctrl-single,pins = < ++ K1X_PADCONF(GPIO_44, MUX_MODE3, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_pwm0_0: pwm0_0_grp { ++ pinctrl-single,pins = < ++ K1X_PADCONF(MMC1_DAT3, MUX_MODE5, (EDGE_NONE | PULL_UP | PAD_3V_DS4)) ++ >; ++ }; ++ ++ pinctrl_pwm0_1: pwm0_1_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_14, MUX_MODE3, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_pwm0_2: pwm0_2_grp { ++ pinctrl-single,pins = < ++ K1X_PADCONF(GPIO_22, MUX_MODE4, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_pwm1_0: pwm1_0_grp { ++ pinctrl-single,pins = < ++ K1X_PADCONF(MMC1_DAT2, MUX_MODE5, (EDGE_NONE | PULL_UP | PAD_3V_DS4)) ++ >; ++ }; ++ ++ pinctrl_pwm1_1: pwm1_1_grp { ++ pinctrl-single,pins = < ++ K1X_PADCONF(GPIO_29, MUX_MODE3, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_pwm1_2: pwm1_2_grp { ++ pinctrl-single,pins = < ++ K1X_PADCONF(GPIO_23, MUX_MODE4, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_pwm2_0: pwm2_0_grp { ++ pinctrl-single,pins = < ++ K1X_PADCONF(MMC1_DAT1, MUX_MODE5, (EDGE_NONE | PULL_UP | PAD_3V_DS4)) ++ >; ++ }; ++ ++ pinctrl_pwm2_1: pwm2_1_grp { ++ pinctrl-single,pins = < ++ K1X_PADCONF(GPIO_22, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_pwm2_2: pwm2_2_grp { ++ pinctrl-single,pins = < ++ K1X_PADCONF(GPIO_30, MUX_MODE3, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_pwm2_3: pwm2_3_grp { ++ pinctrl-single,pins = < ++ K1X_PADCONF(GPIO_24, MUX_MODE4, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_pwm3_0: pwm3_0_grp { ++ pinctrl-single,pins = < ++ K1X_PADCONF(MMC1_DAT0, MUX_MODE5, (EDGE_NONE | PULL_UP | PAD_3V_DS4)) ++ >; ++ }; ++ ++ pinctrl_pwm3_1: pwm3_1_grp { ++ pinctrl-single,pins = < ++ K1X_PADCONF(GPIO_33, MUX_MODE3, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_pwm3_2: pwm3_2_grp { ++ pinctrl-single,pins = < ++ K1X_PADCONF(GPIO_25, MUX_MODE4, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_pwm4_0: pwm4_0_grp { ++ pinctrl-single,pins = < ++ K1X_PADCONF(MMC1_CMD, MUX_MODE5, (EDGE_NONE | PULL_UP | PAD_3V_DS4)) ++ >; ++ }; ++ ++ pinctrl_pwm4_1: pwm4_1_grp { ++ pinctrl-single,pins = < ++ K1X_PADCONF(GPIO_34, MUX_MODE3, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_pwm5_0: pwm5_0_grp { ++ pinctrl-single,pins = < ++ K1X_PADCONF(MMC1_CLK, MUX_MODE5, (EDGE_NONE | PULL_UP | PAD_3V_DS4)) ++ >; ++ }; ++ ++ pinctrl_pwm5_1: pwm5_1_grp { ++ pinctrl-single,pins = < ++ K1X_PADCONF(GPIO_35, MUX_MODE3, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_pwm6_0: pwm6_0_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_88, MUX_MODE4, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_pwm6_1: pwm6_1_grp { ++ pinctrl-single,pins = < ++ K1X_PADCONF(GPIO_36, MUX_MODE3, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_pwm7_0: pwm7_0_grp { ++ pinctrl-single,pins = < ++ K1X_PADCONF(GPIO_92, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_pwm7_1: pwm7_1_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_37, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_pwm8_0: pwm8_0_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_00, MUX_MODE3, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_pwm8_1: pwm8_1_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_38, MUX_MODE4, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_pwm9_0: pwm9_0_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_01, MUX_MODE3, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_pwm9_1: pwm9_1_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_39, MUX_MODE4, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_pwm10_0: pwm10_0_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_02, MUX_MODE3, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_pwm10_1: pwm10_1_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_40, MUX_MODE4, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_pwm11_0: pwm11_0_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_03, MUX_MODE3, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_pwm11_1: pwm11_1_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_41, MUX_MODE4, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_pwm12_0: pwm12_0_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_04, MUX_MODE3, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_pwm12_1: pwm12_1_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_42, MUX_MODE4, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_pwm13_0: pwm13_0_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_05, MUX_MODE3, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_pwm13_1: pwm13_1_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_43, MUX_MODE4, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_pwm14_0: pwm14_0_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_06, MUX_MODE3, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_pwm14_1: pwm14_1_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_44, MUX_MODE4, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_pwm15_0: pwm15_0_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_07, MUX_MODE3, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_pwm15_1: pwm15_1_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_45, MUX_MODE4, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_pwm16_0: pwm16_0_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_09, MUX_MODE3, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_pwm16_1: pwm16_1_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_46, MUX_MODE4, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_pwm17_0: pwm17_0_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_10, MUX_MODE3, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_pwm17_1: pwm17_1_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_53, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_pwm18_0: pwm18_0_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_11, MUX_MODE3, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_pwm18_1: pwm18_1_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_57, MUX_MODE4, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_pwm19_0: pwm19_0_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_13, MUX_MODE3, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_pwm19_1: pwm19_1_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_63, MUX_MODE4, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_rpwm2_0: rpwm2_0_grp { ++ pinctrl-single,pins = < ++ K1X_PADCONF(GPIO_79, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_3V_DS4)) ++ >; ++ }; ++ ++ pinctrl_rpwm9_0: rpwm9_0_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_74, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_sspa0_0: sspa0_0_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_118, MUX_MODE3, (EDGE_NONE | PULL_UP | PAD_1V8_DS0)) ++ K1X_PADCONF(GPIO_119, MUX_MODE3, (EDGE_NONE | PULL_UP | PAD_1V8_DS0)) ++ K1X_PADCONF(GPIO_120, MUX_MODE3, (EDGE_NONE | PULL_UP | PAD_1V8_DS0)) ++ K1X_PADCONF(GPIO_121, MUX_MODE3, (EDGE_NONE | PULL_UP | PAD_1V8_DS0)) ++ K1X_PADCONF(GPIO_122, MUX_MODE3, (EDGE_NONE | PULL_UP | PAD_1V8_DS0)) ++ >; ++ }; ++ ++ pinctrl_sspa0_1: sspa0_1_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_58, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS0)) ++ K1X_PADCONF(GPIO_111, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS0)) ++ K1X_PADCONF(GPIO_112, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS0)) ++ K1X_PADCONF(GPIO_113, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS0)) ++ K1X_PADCONF(GPIO_114, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS0)) ++ >; ++ }; ++ ++ pinctrl_sspa1: sspa1_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_24, MUX_MODE3, (EDGE_NONE | PULL_UP | PAD_1V8_DS0)) ++ K1X_PADCONF(GPIO_25, MUX_MODE1, (EDGE_NONE | PULL_UP | PAD_1V8_DS0)) ++ K1X_PADCONF(GPIO_26, MUX_MODE1, (EDGE_NONE | PULL_UP | PAD_1V8_DS0)) ++ K1X_PADCONF(GPIO_27, MUX_MODE1, (EDGE_NONE | PULL_UP | PAD_1V8_DS0)) ++ K1X_PADCONF(GPIO_28, MUX_MODE1, (EDGE_NONE | PULL_UP | PAD_1V8_DS0)) ++ >; ++ }; ++ ++ pinctrl_ssp2_0: ssp2_0_grp { ++ pinctrl-single,pins = < ++ K1X_PADCONF(GPIO_75, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_3V_DS4)) ++ K1X_PADCONF(GPIO_76, MUX_MODE1, (EDGE_NONE | PULL_UP | PAD_3V_DS4)) ++ K1X_PADCONF(GPIO_77, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_3V_DS4)) ++ K1X_PADCONF(GPIO_78, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_3V_DS4)) ++ >; ++ }; ++ ++ pinctrl_ssp2_1: ssp2_1_grp { ++ pinctrl-single,pins = < ++ K1X_PADCONF(GPIO_64, MUX_MODE3, (EDGE_NONE | PULL_DIS | PAD_3V_DS4)) ++ K1X_PADCONF(GPIO_65, MUX_MODE3, (EDGE_NONE | PULL_UP | PAD_3V_DS4)) ++ K1X_PADCONF(GPIO_66, MUX_MODE3, (EDGE_NONE | PULL_DIS | PAD_3V_DS4)) ++ K1X_PADCONF(GPIO_67, MUX_MODE3, (EDGE_NONE | PULL_DIS | PAD_3V_DS4)) ++ >; ++ }; ++ ++ pinctrl_ssp3_0: ssp3_0_grp { ++ pinctrl-single,pins = < ++ K1X_PADCONF(GPIO_75, MUX_MODE2, (EDGE_NONE | PULL_DIS | PAD_3V_DS4)) ++ K1X_PADCONF(GPIO_76, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_3V_DS4)) ++ K1X_PADCONF(GPIO_77, MUX_MODE2, (EDGE_NONE | PULL_DIS | PAD_3V_DS4)) ++ K1X_PADCONF(GPIO_78, MUX_MODE2, (EDGE_NONE | PULL_DIS | PAD_3V_DS4)) ++ >; ++ }; ++ ++ pinctrl_ssp3_1: ssp3_1_grp { ++ pinctrl-single,pins = < ++ K1X_PADCONF(GPIO_59, MUX_MODE2, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_60, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_61, MUX_MODE2, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_62, MUX_MODE2, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_qspi: qspi_grp { ++ pinctrl-single,pins = < ++ K1X_PADCONF(QSPI_DAT3, MUX_MODE0, (EDGE_NONE | PULL_DIS | PAD_3V_DS4)) ++ K1X_PADCONF(QSPI_DAT2, MUX_MODE0, (EDGE_NONE | PULL_DIS | PAD_3V_DS4)) ++ K1X_PADCONF(QSPI_DAT1, MUX_MODE0, (EDGE_NONE | PULL_DIS | PAD_3V_DS4)) ++ K1X_PADCONF(QSPI_DAT0, MUX_MODE0, (EDGE_NONE | PULL_DIS | PAD_3V_DS4)) ++ K1X_PADCONF(QSPI_CLK, MUX_MODE0, (EDGE_NONE | PULL_DIS | PAD_3V_DS4)) ++ K1X_PADCONF(QSPI_CSI, MUX_MODE0, (EDGE_NONE | PULL_UP | PAD_3V_DS4)) ++ >; ++ }; ++ ++ pinctrl_mmc1: mmc1_grp { ++ pinctrl-single,pins = < ++ K1X_PADCONF(MMC1_DAT3, MUX_MODE0, (EDGE_NONE | PULL_UP | PAD_3V_DS4)) ++ K1X_PADCONF(MMC1_DAT2, MUX_MODE0, (EDGE_NONE | PULL_UP | PAD_3V_DS4)) ++ K1X_PADCONF(MMC1_DAT1, MUX_MODE0, (EDGE_NONE | PULL_UP | PAD_3V_DS4)) ++ K1X_PADCONF(MMC1_DAT0, MUX_MODE0, (EDGE_NONE | PULL_UP | PAD_3V_DS4)) ++ K1X_PADCONF(MMC1_CMD, MUX_MODE0, (EDGE_NONE | PULL_UP | PAD_3V_DS4)) ++ K1X_PADCONF(MMC1_CLK, MUX_MODE0, (EDGE_NONE | PULL_DOWN | PAD_3V_DS4)) ++ >; ++ }; ++ ++ pinctrl_mmc1_fast: mmc1_fast_grp { ++ pinctrl-single,pins = < ++ K1X_PADCONF(MMC1_DAT3, MUX_MODE0, (EDGE_NONE | PULL_UP | PAD_1V8_DS3)) ++ K1X_PADCONF(MMC1_DAT2, MUX_MODE0, (EDGE_NONE | PULL_UP | PAD_1V8_DS3)) ++ K1X_PADCONF(MMC1_DAT1, MUX_MODE0, (EDGE_NONE | PULL_UP | PAD_1V8_DS3)) ++ K1X_PADCONF(MMC1_DAT0, MUX_MODE0, (EDGE_NONE | PULL_UP | PAD_1V8_DS3)) ++ K1X_PADCONF(MMC1_CMD, MUX_MODE0, (EDGE_NONE | PULL_UP | PAD_1V8_DS3)) ++ K1X_PADCONF(MMC1_CLK, MUX_MODE0, (EDGE_NONE | PULL_DOWN | PAD_1V8_DS3)) ++ >; ++ }; ++ ++ pinctrl_mmc2: mmc2_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_15, MUX_MODE1, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_16, MUX_MODE1, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_17, MUX_MODE1, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_18, MUX_MODE1, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_19, MUX_MODE1, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_20, MUX_MODE1, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_usb0_0: usb0_0_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_125, MUX_MODE1, (EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_126, MUX_MODE1, (EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_127, MUX_MODE1, (EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_usb0_1: usb0_1_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_64, MUX_MODE1, (EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_65, MUX_MODE1, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_63, MUX_MODE1, (EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_usb1_0: usb1_0_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_124, MUX_MODE1, (EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_usb1_1: usb1_1_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_66, MUX_MODE1, (EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_usb2_0: usb2_0_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_121, MUX_MODE2, (EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_122, MUX_MODE2, (EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_123, MUX_MODE1, (EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_usb2_1: usb2_1_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_68, MUX_MODE1, (EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_69, MUX_MODE1, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_67, MUX_MODE1, (EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_pcie0_0: pcie0_0_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_15, MUX_MODE2, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_16, MUX_MODE2, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_17, MUX_MODE2, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_pcie0_1: pcie0_1_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_29, MUX_MODE4, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_30, MUX_MODE4, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_31, MUX_MODE4, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_pcie0_2: pcie0_2_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_110, MUX_MODE4, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_115, MUX_MODE4, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_116, MUX_MODE4, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_pcie0_3: pcie0_3_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_53, MUX_MODE3, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_54, MUX_MODE3, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_55, MUX_MODE3, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_pcie1_0: pcie1_0_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_15, MUX_MODE4, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_16, MUX_MODE4, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_17, MUX_MODE4, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_pcie1_1: pcie1_1_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_32, MUX_MODE4, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_33, MUX_MODE4, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_34, MUX_MODE4, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_pcie1_2: pcie1_2_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_56, MUX_MODE3, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_57, MUX_MODE3, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_58, MUX_MODE3, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_pcie1_3: pcie1_3_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_59, MUX_MODE4, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_60, MUX_MODE4, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_61, MUX_MODE4, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_pcie2_0: pcie2_0_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_18, MUX_MODE4, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_19, MUX_MODE4, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_20, MUX_MODE4, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_pcie2_1: pcie2_1_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_35, MUX_MODE4, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_36, MUX_MODE4, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_37, MUX_MODE4, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_pcie2_2: pcie2_2_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_62, MUX_MODE4, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_74, MUX_MODE4, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_117, MUX_MODE4, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_pcie2_3: pcie2_3_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_111, MUX_MODE3, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_112, MUX_MODE3, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_113, MUX_MODE3, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_pcie2_4: pcie2_4_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_62, MUX_MODE4, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_112, MUX_MODE3, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_117, MUX_MODE4, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_gmac0: gmac0_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_00, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_01, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_02, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_03, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_04, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_05, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_06, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_07, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_08, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_09, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_10, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_11, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_12, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_13, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_14, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_45, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_gmac1: gmac1_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_29, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_30, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_31, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_32, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_33, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_34, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_35, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_36, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_37, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_38, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_39, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_40, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_41, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_42, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_43, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_46, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_can_0: can_0_grp { ++ pinctrl-single,pins = < ++ K1X_PADCONF(GPIO_75, MUX_MODE3, (EDGE_NONE | PULL_UP | PAD_3V_DS4)) ++ K1X_PADCONF(GPIO_76, MUX_MODE3, (EDGE_NONE | PULL_UP | PAD_3V_DS4)) ++ >; ++ }; ++ ++ pinctrl_can_1: can_1_grp { ++ pinctrl-single,pins = < ++ K1X_PADCONF(GPIO_54, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_55, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_r_can_0: r_can_0_grp { ++ pinctrl-single,pins = < ++ K1X_PADCONF(GPIO_47, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_48, MUX_MODE2, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_r_can_1: r_can_1_grp { ++ pinctrl-single,pins = < ++ K1X_PADCONF(GPIO_110, MUX_MODE1, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_115, MUX_MODE1, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_hdmi_0: hdmi_0_grp { ++ pinctrl-single,pins = < ++ K1X_PADCONF(GPIO_86, MUX_MODE1, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_87, MUX_MODE1, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_88, MUX_MODE1, (EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_89, MUX_MODE1, (EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_hdmi_1: hdmi_1_grp { ++ pinctrl-single,pins = < ++ K1X_PADCONF(GPIO_59, MUX_MODE1, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_60, MUX_MODE1, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_61, MUX_MODE1, (EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_62, MUX_MODE1, (EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_spi_lcd_0: spi_lcd_0_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_86, MUX_MODE3, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_87, MUX_MODE3, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_88, MUX_MODE3, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_89, MUX_MODE3, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_90, MUX_MODE3, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_91, MUX_MODE3, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_92, MUX_MODE3, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_spi_lcd_1: spi_lcd_1_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(PRI_TDI, MUX_MODE3, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(PRI_TMS, MUX_MODE3, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(PRI_TCK, MUX_MODE3, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(PRI_TDO, MUX_MODE3, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_74, MUX_MODE3, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_114, MUX_MODE3, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_63, MUX_MODE3, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_camera0: camera0_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_53, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_camera1: camera1_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_58, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_camera2: camera2_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_120, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_pmic: pmic_grp { ++ pinctrl-single,pins = < ++ K1X_PADCONF(VCXO_EN, MUX_MODE0, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(DVL0, MUX_MODE0, (EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)) ++ K1X_PADCONF(DVL1, MUX_MODE0, (EDGE_NONE | PULL_DOWN | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_mn_clk_0: mn_clk_0_grp { ++ pinctrl-single,pins = < ++ K1X_PADCONF(GPIO_92, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_mn_clk_1: mn_clk_1_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_81, MUX_MODE4, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_mn_clk_2: mn_clk_2_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_44, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_mn_clk_3: mn_clk_3_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_20, MUX_MODE3, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_mn_clk_4: mn_clk_4_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_23, MUX_MODE3, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_mn_clk_5: mn_clk_5_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_32, MUX_MODE3, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_mn_clk2_0: mn_clk2_0_grp { ++ pinctrl-single,pins = < ++ K1X_PADCONF(GPIO_91, MUX_MODE1, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_mn_clk2_1: mn_clk2_1_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_85, MUX_MODE3, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_vcxo_0: vcxo_0_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(DVL0, MUX_MODE3, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(DVL1, MUX_MODE3, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_vcxo_1: vcxo_1_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_16, MUX_MODE3, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_17, MUX_MODE3, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_vcxo_2: vcxo_2_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_89, MUX_MODE4, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ K1X_PADCONF(GPIO_90, MUX_MODE4, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_vcxo_out_0: vcxo_out_0_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_91, MUX_MODE2, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_vcxo_out_1: vcxo_out_1_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_12, MUX_MODE3, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_32k_out_0: 32k_out_0_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_21, MUX_MODE3, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_32k_out_1: 32k_out_1_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_31, MUX_MODE3, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_32k_out_2: 32k_out_2_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(GPIO_28, MUX_MODE4, (EDGE_NONE | PULL_DIS | PAD_1V8_DS2)) ++ >; ++ }; ++ ++ pinctrl_pri: pri_grp { ++ pinctrl-single,pins =< ++ K1X_PADCONF(PRI_TDI, MUX_MODE0, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(PRI_TMS, MUX_MODE0, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(PRI_TCK, MUX_MODE0, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ K1X_PADCONF(PRI_TDO, MUX_MODE0, (EDGE_NONE | PULL_UP | PAD_1V8_DS2)) ++ >; ++ }; ++}; ++ diff --git a/arch/riscv/boot/dts/thead/Makefile b/arch/riscv/boot/dts/thead/Makefile index b55a17127c2b..3e6311bc9976 100644 --- a/arch/riscv/boot/dts/thead/Makefile @@ -17392,19 +19442,40 @@ index ab86ec3b9eab..ee97fe565df7 100644 +CONFIG_MAILBOX=y +# TH1520 PMIC_WDT +CONFIG_TH1520_PMIC_WATCHDOG=y +diff --git a/arch/riscv/configs/k1_defconfig b/arch/riscv/configs/k1_defconfig +new file mode 100644 +index 000000000000..30cc6a1a0cd5 +--- /dev/null ++++ b/arch/riscv/configs/k1_defconfig +@@ -0,0 +1,14 @@ ++# ++# Spacemit k1 SoC support ++# ++CONFIG_SOC_SPACEMIT=y ++CONFIG_SOC_SPACEMIT_K1=y ++CONFIG_SOC_SPACEMIT_K1X=y ++CONFIG_SPACEMIT_K1X_CCU=y ++CONFIG_RESET_K1X_SPACEMIT=y ++CONFIG_PINCTRL_SPACEMIT_K1X=y ++CONFIG_GPIO_K1X=y ++CONFIG_SERIAL_SPACEMIT_K1X=y ++CONFIG_SERIAL_SPACEMIT_K1X_CONSOLE=y ++CONFIG_SERIAL_DEV_BUS=y ++ diff --git a/arch/riscv/configs/openeuler_defconfig b/arch/riscv/configs/openeuler_defconfig -index 61f2b2f12589..c39bbc3701b3 100644 +index 61f2b2f12589..aa2e29505884 100644 --- a/arch/riscv/configs/openeuler_defconfig +++ b/arch/riscv/configs/openeuler_defconfig -@@ -2,6 +2,7 @@ +@@ -2,6 +2,8 @@ # Automatically generated file; DO NOT EDIT. # Linux/riscv 6.6.0 Kernel Configuration # +CONFIG_GCC_ASM_GOTO_OUTPUT_BROKEN=y ++CONFIG_TOOLS_SUPPORT_RELR=y CONFIG_IRQ_WORK=y CONFIG_BUILDTIME_TABLE_SORT=y CONFIG_THREAD_INFO_IN_TASK=y -@@ -44,6 +45,7 @@ CONFIG_IRQ_DOMAIN_HIERARCHY=y +@@ -44,6 +46,7 @@ CONFIG_IRQ_DOMAIN_HIERARCHY=y CONFIG_GENERIC_IRQ_IPI=y CONFIG_GENERIC_IRQ_IPI_MUX=y CONFIG_GENERIC_MSI_IRQ=y @@ -17412,7 +19483,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_IRQ_FORCED_THREADING=y CONFIG_SPARSE_IRQ=y # CONFIG_GENERIC_IRQ_DEBUGFS is not set -@@ -90,11 +92,12 @@ CONFIG_BPF_JIT_DEFAULT_ON=y +@@ -90,11 +93,12 @@ CONFIG_BPF_JIT_DEFAULT_ON=y # CONFIG_BPF_SCHED is not set # end of BPF subsystem @@ -17428,7 +19499,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_PREEMPT_DYNAMIC is not set # -@@ -123,10 +126,11 @@ CONFIG_CPU_ISOLATION=y +@@ -123,10 +127,11 @@ CONFIG_CPU_ISOLATION=y # RCU Subsystem # CONFIG_TREE_RCU=y @@ -17441,7 +19512,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_TASKS_TRACE_RCU=y CONFIG_RCU_STALL_COMMON=y CONFIG_RCU_NEED_SEGCBLIST=y -@@ -148,7 +152,7 @@ CONFIG_GENERIC_SCHED_CLOCK=y +@@ -148,7 +153,7 @@ CONFIG_GENERIC_SCHED_CLOCK=y CONFIG_ARCH_SUPPORTS_NUMA_BALANCING=y CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5" @@ -17450,7 +19521,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_CC_NO_ARRAY_BOUNDS=y CONFIG_ARCH_SUPPORTS_INT128=y CONFIG_NUMA_BALANCING=y -@@ -169,7 +173,6 @@ CONFIG_FAIR_GROUP_SCHED=y +@@ -169,7 +174,6 @@ CONFIG_FAIR_GROUP_SCHED=y CONFIG_CFS_BANDWIDTH=y CONFIG_RT_GROUP_SCHED=y # CONFIG_QOS_SCHED_DYNAMIC_AFFINITY is not set @@ -17458,7 +19529,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_CGROUP_PIDS=y CONFIG_CGROUP_RDMA=y CONFIG_CGROUP_FREEZER=y -@@ -226,7 +229,7 @@ CONFIG_SYSFS_SYSCALL=y +@@ -226,7 +230,7 @@ CONFIG_SYSFS_SYSCALL=y CONFIG_FHANDLE=y CONFIG_POSIX_TIMERS=y CONFIG_PRINTK=y @@ -17467,7 +19538,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y -@@ -244,6 +247,8 @@ CONFIG_KALLSYMS=y +@@ -244,6 +248,8 @@ CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_SELFTEST is not set CONFIG_KALLSYMS_ALL=y CONFIG_KALLSYMS_BASE_RELATIVE=y @@ -17476,7 +19547,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_KCMP=y CONFIG_RSEQ=y CONFIG_CACHESTAT_SYSCALL=y -@@ -262,8 +267,6 @@ CONFIG_DEBUG_PERF_USE_VMALLOC=y +@@ -262,8 +268,6 @@ CONFIG_DEBUG_PERF_USE_VMALLOC=y CONFIG_SYSTEM_DATA_VERIFICATION=y CONFIG_PROFILING=y CONFIG_TRACEPOINTS=y @@ -17485,7 +19556,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # # Kexec and crash features -@@ -288,16 +291,16 @@ CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=17 +@@ -288,16 +292,16 @@ CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=17 CONFIG_RISCV_SBI=y CONFIG_MMU=y CONFIG_PAGE_OFFSET=0xff60000000000000 @@ -17504,7 +19575,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_PGTABLE_LEVELS=5 CONFIG_LOCKDEP_SUPPORT=y CONFIG_RISCV_DMA_NONCOHERENT=y -@@ -306,13 +309,15 @@ CONFIG_RISCV_DMA_NONCOHERENT=y +@@ -306,15 +310,20 @@ CONFIG_RISCV_DMA_NONCOHERENT=y # SoC selection # # CONFIG_SOC_MICROCHIP_POLARFIRE is not set @@ -17521,8 +19592,13 @@ index 61f2b2f12589..c39bbc3701b3 100644 +CONFIG_ARCH_XUANTIE=y CONFIG_ARCH_VIRT=y CONFIG_SOC_VIRT=y ++CONFIG_SOC_SPACEMIT=y ++CONFIG_SOC_SPACEMIT_K1=y ++CONFIG_SOC_SPACEMIT_K1X=y # end of SoC selection -@@ -339,7 +344,7 @@ CONFIG_ARCH_RV64I=y + + # +@@ -339,7 +348,7 @@ CONFIG_ARCH_RV64I=y CONFIG_CMODEL_MEDANY=y CONFIG_MODULE_SECTIONS=y CONFIG_SMP=y @@ -17531,19 +19607,30 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_NR_CPUS=512 CONFIG_HOTPLUG_CPU=y CONFIG_TUNE_GENERIC=y -@@ -351,9 +356,8 @@ CONFIG_RISCV_ISA_C=y +@@ -350,12 +359,8 @@ CONFIG_RISCV_ALTERNATIVE_EARLY=y + CONFIG_RISCV_ISA_C=y CONFIG_RISCV_ISA_SVNAPOT=y CONFIG_RISCV_ISA_SVPBMT=y - CONFIG_TOOLCHAIN_HAS_V=y +-CONFIG_TOOLCHAIN_HAS_V=y -CONFIG_RISCV_ISA_V=y -CONFIG_RISCV_ISA_V_DEFAULT_ENABLE=y -CONFIG_RISCV_ISA_ZICBOM=y -+# CONFIG_RISCV_ISA_V is not set +# CONFIG_RISCV_ISA_ZICBOM is not set CONFIG_RISCV_ISA_ZICBOZ=y - CONFIG_TOOLCHAIN_HAS_ZIHINTPAUSE=y +-CONFIG_TOOLCHAIN_HAS_ZIHINTPAUSE=y CONFIG_TOOLCHAIN_NEEDS_EXPLICIT_ZICSR_ZIFENCEI=y -@@ -400,27 +404,17 @@ CONFIG_PORTABLE=y + CONFIG_FPU=y + CONFIG_IRQ_STACKS=y +@@ -390,8 +395,6 @@ CONFIG_COMPAT=y + CONFIG_CMDLINE="" + CONFIG_EFI_STUB=y + CONFIG_EFI=y +-CONFIG_CC_HAVE_STACKPROTECTOR_TLS=y +-CONFIG_STACKPROTECTOR_PER_TASK=y + CONFIG_RISCV_ISA_FALLBACK=y + # end of Boot options + +@@ -400,27 +403,17 @@ CONFIG_PORTABLE=y # # Power management options # @@ -17573,7 +19660,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_ARCH_SUSPEND_POSSIBLE=y # end of Power management options -@@ -436,6 +430,7 @@ CONFIG_CPU_IDLE_MULTIPLE_DRIVERS=y +@@ -436,6 +429,7 @@ CONFIG_CPU_IDLE_MULTIPLE_DRIVERS=y # CONFIG_CPU_IDLE_GOV_LADDER is not set CONFIG_CPU_IDLE_GOV_MENU=y CONFIG_CPU_IDLE_GOV_TEO=y @@ -17581,7 +19668,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_DT_IDLE_STATES=y CONFIG_DT_IDLE_GENPD=y -@@ -471,6 +466,7 @@ CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y +@@ -471,6 +465,7 @@ CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y # CONFIG_CPUFREQ_DT=y CONFIG_CPUFREQ_DT_PLATDEV=y @@ -17589,7 +19676,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # end of CPU Frequency scaling # end of CPU Power Management -@@ -485,9 +481,44 @@ CONFIG_HAVE_KVM_VCPU_ASYNC_IOCTL=y +@@ -485,9 +480,44 @@ CONFIG_HAVE_KVM_VCPU_ASYNC_IOCTL=y CONFIG_KVM_XFER_TO_GUEST_WORK=y CONFIG_KVM_GENERIC_HARDWARE_ENABLING=y CONFIG_VIRTUALIZATION=y @@ -17636,7 +19723,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # # General architecture-dependent options -@@ -498,7 +529,6 @@ CONFIG_GENERIC_ENTRY=y +@@ -498,7 +528,6 @@ CONFIG_GENERIC_ENTRY=y CONFIG_KPROBES=y CONFIG_JUMP_LABEL=y # CONFIG_STATIC_KEYS_SELFTEST is not set @@ -17644,7 +19731,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_UPROBES=y CONFIG_HAVE_64BIT_ALIGNED_ACCESS=y CONFIG_KRETPROBES=y -@@ -524,6 +554,8 @@ CONFIG_HAVE_PERF_REGS=y +@@ -524,6 +553,8 @@ CONFIG_HAVE_PERF_REGS=y CONFIG_HAVE_PERF_USER_STACK_DUMP=y CONFIG_HAVE_ARCH_JUMP_LABEL=y CONFIG_HAVE_ARCH_JUMP_LABEL_RELATIVE=y @@ -17653,7 +19740,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_MMU_LAZY_TLB_REFCOUNT=y CONFIG_HAVE_ARCH_SECCOMP=y CONFIG_HAVE_ARCH_SECCOMP_FILTER=y -@@ -565,7 +597,7 @@ CONFIG_VMAP_STACK=y +@@ -565,7 +596,7 @@ CONFIG_VMAP_STACK=y CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y @@ -17662,7 +19749,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y CONFIG_STRICT_MODULE_RWX=y CONFIG_ARCH_USE_MEMREMAP_PROT=y -@@ -576,7 +608,6 @@ CONFIG_HAVE_PREEMPT_DYNAMIC_KEY=y +@@ -576,7 +607,6 @@ CONFIG_HAVE_PREEMPT_DYNAMIC_KEY=y CONFIG_ARCH_WANT_LD_ORPHAN_WARN=y CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y CONFIG_ARCH_SUPPORTS_PAGE_TABLE_CHECK=y @@ -17670,7 +19757,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # # GCOV-based kernel profiling -@@ -585,6 +616,11 @@ CONFIG_DYNAMIC_SIGFRAME=y +@@ -585,6 +615,11 @@ CONFIG_DYNAMIC_SIGFRAME=y CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y # end of GCOV-based kernel profiling @@ -17682,7 +19769,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_HAVE_GCC_PLUGINS=y CONFIG_FUNCTION_ALIGNMENT=0 # end of General architecture-dependent options -@@ -646,6 +682,7 @@ CONFIG_BLK_INLINE_ENCRYPTION=y +@@ -646,6 +681,7 @@ CONFIG_BLK_INLINE_ENCRYPTION=y CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y # CONFIG_BLK_DEV_DETECT_WRITING_PART0 is not set # CONFIG_BLK_DEV_WRITE_MOUNTED_DUMP is not set @@ -17690,7 +19777,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_BLK_IO_HIERARCHY_STATS is not set # -@@ -692,11 +729,7 @@ CONFIG_BFQ_GROUP_IOSCHED=y +@@ -692,11 +728,7 @@ CONFIG_BFQ_GROUP_IOSCHED=y CONFIG_PREEMPT_NOTIFIERS=y CONFIG_PADATA=y CONFIG_ASN1=y @@ -17703,7 +19790,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y CONFIG_MUTEX_SPIN_ON_OWNER=y CONFIG_RWSEM_SPIN_ON_OWNER=y -@@ -706,6 +739,8 @@ CONFIG_QUEUED_RWLOCKS=y +@@ -706,6 +738,8 @@ CONFIG_QUEUED_RWLOCKS=y CONFIG_ARCH_HAS_MMIOWB=y CONFIG_MMIOWB=y CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE=y @@ -17712,7 +19799,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_ARCH_HAS_SYSCALL_WRAPPER=y # CONFIG_PID_MAX_PER_NAMESPACE is not set CONFIG_FREEZER=y -@@ -771,6 +806,8 @@ CONFIG_SPARSEMEM_EXTREME=y +@@ -771,6 +805,8 @@ CONFIG_SPARSEMEM_EXTREME=y CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y CONFIG_SPARSEMEM_VMEMMAP=y CONFIG_ARCH_WANT_OPTIMIZE_HUGETLB_VMEMMAP=y @@ -17721,7 +19808,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_MEMORY_ISOLATION=y CONFIG_EXCLUSIVE_SYSTEM_RAM=y CONFIG_SPLIT_PTLOCK_CPUS=4 -@@ -795,13 +832,14 @@ CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y +@@ -795,13 +831,14 @@ CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y # CONFIG_TRANSPARENT_HUGEPAGE_MADVISE is not set CONFIG_THP_SWAP=y # CONFIG_READ_ONLY_THP_FOR_FS is not set @@ -17739,7 +19826,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_GENERIC_EARLY_IOREMAP=y # CONFIG_DEFERRED_STRUCT_PAGE_INIT is not set CONFIG_PAGE_IDLE_FLAG=y -@@ -1346,10 +1384,10 @@ CONFIG_L2TP_DEBUGFS=m +@@ -1346,10 +1383,10 @@ CONFIG_L2TP_DEBUGFS=m CONFIG_L2TP_V3=y CONFIG_L2TP_IP=m CONFIG_L2TP_ETH=m @@ -17752,7 +19839,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_BRIDGE_IGMP_SNOOPING=y CONFIG_BRIDGE_VLAN_FILTERING=y # CONFIG_BRIDGE_MRP is not set -@@ -1358,7 +1396,7 @@ CONFIG_BRIDGE_VLAN_FILTERING=y +@@ -1358,7 +1395,7 @@ CONFIG_BRIDGE_VLAN_FILTERING=y CONFIG_VLAN_8021Q=m CONFIG_VLAN_8021Q_GVRP=y CONFIG_VLAN_8021Q_MVRP=y @@ -17761,7 +19848,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_LLC2 is not set # CONFIG_ATALK is not set # CONFIG_X25 is not set -@@ -1513,7 +1551,44 @@ CONFIG_CAN_BCM=m +@@ -1513,7 +1550,54 @@ CONFIG_CAN_BCM=m CONFIG_CAN_GW=m # CONFIG_CAN_J1939 is not set # CONFIG_CAN_ISOTP is not set @@ -17789,11 +19876,19 @@ index 61f2b2f12589..c39bbc3701b3 100644 +# CONFIG_BT_HCIBTUSB is not set +# CONFIG_BT_HCIBTSDIO is not set +CONFIG_BT_HCIUART=y ++CONFIG_BT_HCIUART_SERDEV=y +CONFIG_BT_HCIUART_H4=y ++# CONFIG_BT_HCIUART_NOKIA is not set +# CONFIG_BT_HCIUART_BCSP is not set +# CONFIG_BT_HCIUART_ATH3K is not set ++# CONFIG_BT_HCIUART_LL is not set ++# CONFIG_BT_HCIUART_3WIRE is not set +# CONFIG_BT_HCIUART_INTEL is not set ++# CONFIG_BT_HCIUART_BCM is not set ++# CONFIG_BT_HCIUART_RTL is not set ++# CONFIG_BT_HCIUART_QCA is not set +# CONFIG_BT_HCIUART_AG6XX is not set ++# CONFIG_BT_HCIUART_MRVL is not set +# CONFIG_BT_HCIBCM203X is not set +# CONFIG_BT_HCIBCM4377 is not set +# CONFIG_BT_HCIBPA10X is not set @@ -17801,13 +19896,15 @@ index 61f2b2f12589..c39bbc3701b3 100644 +# CONFIG_BT_HCIVHCI is not set +# CONFIG_BT_MRVL is not set +# CONFIG_BT_MTKSDIO is not set ++# CONFIG_BT_MTKUART is not set +# CONFIG_BT_VIRTIO is not set ++# CONFIG_BT_NXPUART is not set +# end of Bluetooth device drivers + # CONFIG_AF_RXRPC is not set # CONFIG_AF_KCM is not set CONFIG_STREAM_PARSER=y -@@ -1522,7 +1597,7 @@ CONFIG_FIB_RULES=y +@@ -1522,7 +1606,7 @@ CONFIG_FIB_RULES=y CONFIG_WIRELESS=y CONFIG_WEXT_CORE=y CONFIG_WEXT_PROC=y @@ -17816,7 +19913,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_NL80211_TESTMODE is not set # CONFIG_CFG80211_DEVELOPER_WARNINGS is not set # CONFIG_CFG80211_CERTIFICATION_ONUS is not set -@@ -1532,7 +1607,7 @@ CONFIG_CFG80211_DEFAULT_PS=y +@@ -1532,7 +1616,7 @@ CONFIG_CFG80211_DEFAULT_PS=y # CONFIG_CFG80211_DEBUGFS is not set CONFIG_CFG80211_CRDA_SUPPORT=y CONFIG_CFG80211_WEXT=y @@ -17825,7 +19922,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_MAC80211_HAS_RC=y CONFIG_MAC80211_RC_MINSTREL=y CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y -@@ -1543,7 +1618,7 @@ CONFIG_MAC80211_DEBUGFS=y +@@ -1543,7 +1627,7 @@ CONFIG_MAC80211_DEBUGFS=y # CONFIG_MAC80211_MESSAGE_TRACING is not set # CONFIG_MAC80211_DEBUG_MENU is not set CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 @@ -17834,7 +19931,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_RFKILL_LEDS=y CONFIG_RFKILL_INPUT=y CONFIG_RFKILL_GPIO=m -@@ -1573,6 +1648,7 @@ CONFIG_FAILOVER=y +@@ -1573,6 +1657,7 @@ CONFIG_FAILOVER=y CONFIG_ETHTOOL_NETLINK=y CONFIG_NETACC_BPF=y CONFIG_NETACC_TERRACE=y @@ -17842,7 +19939,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # # Device Drivers -@@ -1595,6 +1671,7 @@ CONFIG_PCIEASPM_DEFAULT=y +@@ -1595,6 +1680,7 @@ CONFIG_PCIEASPM_DEFAULT=y CONFIG_PCIE_PME=y CONFIG_PCIE_DPC=y # CONFIG_PCIE_PTM is not set @@ -17850,7 +19947,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_PCI_MSI=y CONFIG_PCI_QUIRKS=y # CONFIG_PCI_DEBUG is not set -@@ -1606,6 +1683,7 @@ CONFIG_PCI_ECAM=y +@@ -1606,6 +1692,7 @@ CONFIG_PCI_ECAM=y CONFIG_PCI_IOV=y CONFIG_PCI_PRI=y CONFIG_PCI_PASID=y @@ -17858,7 +19955,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_PCI_DYNAMIC_OF_NODES is not set # CONFIG_PCIE_BUS_TUNE_OFF is not set CONFIG_PCIE_BUS_DEFAULT=y -@@ -1615,6 +1693,7 @@ CONFIG_PCIE_BUS_DEFAULT=y +@@ -1615,6 +1702,7 @@ CONFIG_PCIE_BUS_DEFAULT=y CONFIG_VGA_ARB=y CONFIG_VGA_ARB_MAX_GPUS=64 CONFIG_HOTPLUG_PCI=y @@ -17866,7 +19963,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_HOTPLUG_PCI_CPCI is not set CONFIG_HOTPLUG_PCI_SHPC=y -@@ -1625,6 +1704,8 @@ CONFIG_HOTPLUG_PCI_SHPC=y +@@ -1625,6 +1713,8 @@ CONFIG_HOTPLUG_PCI_SHPC=y CONFIG_PCI_HOST_COMMON=y CONFIG_PCI_HOST_GENERIC=y CONFIG_PCIE_MICROCHIP_HOST=y @@ -17875,7 +19972,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_PCIE_XILINX=y # -@@ -1636,6 +1717,7 @@ CONFIG_PCIE_CADENCE_EP=y +@@ -1636,6 +1726,7 @@ CONFIG_PCIE_CADENCE_EP=y CONFIG_PCIE_CADENCE_PLAT=y CONFIG_PCIE_CADENCE_PLAT_HOST=y CONFIG_PCIE_CADENCE_PLAT_EP=y @@ -17883,7 +19980,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_PCI_J721E=y CONFIG_PCI_J721E_HOST=y # CONFIG_PCI_J721E_EP is not set -@@ -1697,8 +1779,9 @@ CONFIG_FW_LOADER=y +@@ -1697,8 +1788,9 @@ CONFIG_FW_LOADER=y CONFIG_FW_LOADER_DEBUG=y CONFIG_EXTRA_FIRMWARE="" # CONFIG_FW_LOADER_USER_HELPER is not set @@ -17895,7 +19992,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_FW_UPLOAD is not set # end of Firmware loader -@@ -1709,9 +1792,10 @@ CONFIG_WANT_DEV_COREDUMP=y +@@ -1709,9 +1801,10 @@ CONFIG_WANT_DEV_COREDUMP=y # CONFIG_DEBUG_TEST_DRIVER_REMOVE is not set # CONFIG_TEST_ASYNC_DRIVER_PROBE is not set CONFIG_GENERIC_CPU_DEVICES=y @@ -17908,7 +20005,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_REGMAP_MMIO=y CONFIG_DMA_SHARED_BUFFER=y # CONFIG_DMA_FENCE_TRACE is not set -@@ -1724,6 +1808,8 @@ CONFIG_GENERIC_ARCH_NUMA=y +@@ -1724,6 +1817,8 @@ CONFIG_GENERIC_ARCH_NUMA=y # Bus devices # # CONFIG_MOXTET is not set @@ -17917,7 +20014,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_MHI_BUS is not set # CONFIG_MHI_BUS_EP is not set # end of Bus devices -@@ -1747,6 +1833,7 @@ CONFIG_PROC_EVENTS=y +@@ -1747,6 +1842,7 @@ CONFIG_PROC_EVENTS=y # end of ARM System Control and Management Interface Protocol # CONFIG_FIRMWARE_MEMMAP is not set @@ -17925,7 +20022,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_SYSFB=y CONFIG_SYSFB_SIMPLEFB=y # CONFIG_GOOGLE_FIRMWARE is not set -@@ -1767,6 +1854,7 @@ CONFIG_EFI_GENERIC_STUB=y +@@ -1767,6 +1863,7 @@ CONFIG_EFI_GENERIC_STUB=y # CONFIG_RESET_ATTACK_MITIGATION is not set # CONFIG_EFI_DISABLE_PCI_DMA is not set CONFIG_EFI_EARLYCON=y @@ -17933,7 +20030,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_EFI_DISABLE_RUNTIME is not set # CONFIG_EFI_COCO_SECRET is not set # end of EFI (Extensible Firmware Interface) Support -@@ -1775,11 +1863,14 @@ CONFIG_EFI_EARLYCON=y +@@ -1775,11 +1872,14 @@ CONFIG_EFI_EARLYCON=y # Tegra firmware driver # # end of Tegra firmware driver @@ -17950,7 +20047,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # # Partition parsers -@@ -1793,9 +1884,8 @@ CONFIG_MTD_OF_PARTS=m +@@ -1793,9 +1893,8 @@ CONFIG_MTD_OF_PARTS=m # # User Modules And Translation Layers # @@ -17962,7 +20059,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # # Note that in some cases UBI block is preferred. See MTD_UBI_BLOCK. -@@ -1862,8 +1952,8 @@ CONFIG_MTD_PHYSMAP_OF=y +@@ -1862,8 +1961,8 @@ CONFIG_MTD_PHYSMAP_OF=y # CONFIG_MTD_MCHP23K256 is not set # CONFIG_MTD_MCHP48L640 is not set # CONFIG_MTD_SST25L is not set @@ -17973,7 +20070,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_MTD_MTDRAM is not set CONFIG_MTD_BLOCK2MTD=m -@@ -1876,13 +1966,15 @@ CONFIG_MTD_BLOCK2MTD=m +@@ -1876,13 +1975,15 @@ CONFIG_MTD_BLOCK2MTD=m # # NAND # @@ -17990,7 +20087,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_MTD_NAND_ECC_SW_HAMMING is not set # CONFIG_MTD_NAND_ECC_SW_BCH is not set # CONFIG_MTD_NAND_ECC_MXIC is not set -@@ -1895,12 +1987,13 @@ CONFIG_MTD_BLOCK2MTD=m +@@ -1895,12 +1996,13 @@ CONFIG_MTD_BLOCK2MTD=m # CONFIG_MTD_LPDDR is not set # end of LPDDR & LPDDR2 PCM memory drivers @@ -18006,7 +20103,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_MTD_UBI_WL_THRESHOLD=4096 CONFIG_MTD_UBI_BEB_LIMIT=20 # CONFIG_MTD_UBI_FASTMAP is not set -@@ -1921,6 +2014,13 @@ CONFIG_OF_RESOLVE=y +@@ -1921,6 +2023,13 @@ CONFIG_OF_RESOLVE=y CONFIG_OF_OVERLAY=y CONFIG_OF_NUMA=y # CONFIG_PARPORT is not set @@ -18020,7 +20117,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_BLK_DEV=y CONFIG_BLK_DEV_NULL_BLK=m CONFIG_CDROM=y -@@ -1939,7 +2039,7 @@ CONFIG_BLK_DEV_LOOP=y +@@ -1939,7 +2048,7 @@ CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_LOOP_MIN_COUNT=0 CONFIG_BLK_DEV_DRBD=m # CONFIG_DRBD_FAULT_INJECTION is not set @@ -18029,7 +20126,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_BLK_DEV_RAM=m CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=16384 -@@ -2008,7 +2108,7 @@ CONFIG_MISC_RTSX=m +@@ -2008,7 +2117,7 @@ CONFIG_MISC_RTSX=m # # EEPROM support # @@ -18038,7 +20135,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_EEPROM_AT25 is not set CONFIG_EEPROM_LEGACY=m CONFIG_EEPROM_MAX6875=m -@@ -2028,7 +2128,6 @@ CONFIG_CB710_DEBUG_ASSUMPTIONS=y +@@ -2028,7 +2137,6 @@ CONFIG_CB710_DEBUG_ASSUMPTIONS=y # CONFIG_TI_ST is not set # end of Texas Instruments shared transport line discipline @@ -18046,7 +20143,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_SENSORS_LIS3_I2C=m CONFIG_ALTERA_STAPL=m # CONFIG_GENWQE is not set -@@ -2110,6 +2209,7 @@ CONFIG_SCSI_MPT2SAS_MAX_SGE=128 +@@ -2110,6 +2218,7 @@ CONFIG_SCSI_MPT2SAS_MAX_SGE=128 CONFIG_SCSI_MPT3SAS_MAX_SGE=128 CONFIG_SCSI_MPT2SAS=m # CONFIG_SCSI_MPI3MR is not set @@ -18054,7 +20151,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_SCSI_SMARTPQI=m # CONFIG_SCSI_HPTIOP is not set # CONFIG_SCSI_BUSLOGIC is not set -@@ -2156,8 +2256,11 @@ CONFIG_SCSI_DH_ALUA=y +@@ -2156,8 +2265,11 @@ CONFIG_SCSI_DH_ALUA=y CONFIG_ATA=y CONFIG_SATA_HOST=y @@ -18066,7 +20163,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_SATA_PMP=y # -@@ -2168,6 +2271,7 @@ CONFIG_SATA_MOBILE_LPM_POLICY=0 +@@ -2168,6 +2280,7 @@ CONFIG_SATA_MOBILE_LPM_POLICY=0 CONFIG_SATA_AHCI_PLATFORM=y # CONFIG_AHCI_DWC is not set # CONFIG_AHCI_CEVA is not set @@ -18074,7 +20171,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_SATA_INIC162X is not set # CONFIG_SATA_ACARD_AHCI is not set # CONFIG_SATA_SIL24 is not set -@@ -2189,6 +2293,7 @@ CONFIG_ATA_PIIX=m +@@ -2189,6 +2302,7 @@ CONFIG_ATA_PIIX=m # CONFIG_SATA_MV is not set # CONFIG_SATA_NV is not set # CONFIG_SATA_PROMISE is not set @@ -18082,7 +20179,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_SATA_SIL is not set # CONFIG_SATA_SIS is not set # CONFIG_SATA_SVW is not set -@@ -2247,6 +2352,7 @@ CONFIG_ATA_PIIX=m +@@ -2247,6 +2361,7 @@ CONFIG_ATA_PIIX=m # # Generic fallback / legacy drivers # @@ -18090,7 +20187,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_ATA_GENERIC=m # CONFIG_PATA_LEGACY is not set CONFIG_MD=y -@@ -2265,14 +2371,14 @@ CONFIG_BCACHE=m +@@ -2265,14 +2380,14 @@ CONFIG_BCACHE=m # CONFIG_BCACHE_CLOSURES_DEBUG is not set # CONFIG_BCACHE_ASYNC_REGISTRATION is not set CONFIG_BLK_DEV_DM_BUILTIN=y @@ -18107,7 +20204,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_DM_SNAPSHOT=m CONFIG_DM_THIN_PROVISIONING=m CONFIG_DM_CACHE=m -@@ -2292,6 +2398,7 @@ CONFIG_DM_MULTIPATH_ST=m +@@ -2292,6 +2407,7 @@ CONFIG_DM_MULTIPATH_ST=m # CONFIG_DM_MULTIPATH_IOA is not set CONFIG_DM_DELAY=m # CONFIG_DM_DUST is not set @@ -18115,7 +20212,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_DM_UEVENT=y CONFIG_DM_FLAKEY=m CONFIG_DM_VERITY=m -@@ -2322,7 +2429,7 @@ CONFIG_ISCSI_TARGET_CXGB4=m +@@ -2322,7 +2438,7 @@ CONFIG_ISCSI_TARGET_CXGB4=m # end of IEEE 1394 (FireWire) support CONFIG_NETDEVICES=y @@ -18124,7 +20221,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_NET_CORE=y CONFIG_BONDING=m CONFIG_DUMMY=m -@@ -2366,10 +2473,13 @@ CONFIG_VSOCKMON=m +@@ -2366,10 +2482,13 @@ CONFIG_VSOCKMON=m CONFIG_ETHERNET=y CONFIG_MDIO=m # CONFIG_NET_VENDOR_3COM is not set @@ -18138,7 +20235,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_NET_VENDOR_ALTEON is not set # CONFIG_ALTERA_TSE is not set CONFIG_NET_VENDOR_AMAZON=y -@@ -2406,14 +2516,13 @@ CONFIG_BNXT_DCB=y +@@ -2406,14 +2525,13 @@ CONFIG_BNXT_DCB=y # CONFIG_BNXT_HWMON is not set CONFIG_NET_VENDOR_CADENCE=y CONFIG_MACB=y @@ -18154,7 +20251,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_LIQUIDIO_CORE=m CONFIG_LIQUIDIO=m CONFIG_LIQUIDIO_VF=m -@@ -2441,7 +2550,10 @@ CONFIG_NET_VENDOR_ENGLEDER=y +@@ -2441,7 +2559,10 @@ CONFIG_NET_VENDOR_ENGLEDER=y CONFIG_NET_VENDOR_FUNGIBLE=y # CONFIG_FUN_ETH is not set CONFIG_NET_VENDOR_GOOGLE=y @@ -18165,7 +20262,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_NET_VENDOR_I825XX is not set CONFIG_NET_VENDOR_INTEL=y # CONFIG_E100 is not set -@@ -2466,6 +2578,10 @@ CONFIG_FM10K=m +@@ -2466,6 +2587,10 @@ CONFIG_FM10K=m # CONFIG_IGC is not set CONFIG_NET_VENDOR_MUCSE=y # CONFIG_MXGBE is not set @@ -18176,7 +20273,15 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_JME is not set CONFIG_NET_VENDOR_ADI=y # CONFIG_ADIN1110 is not set -@@ -2564,13 +2680,24 @@ CONFIG_SFC_MCDI_MON=y +@@ -2539,6 +2664,7 @@ CONFIG_QED_OOO=y + # CONFIG_NET_VENDOR_BROCADE is not set + CONFIG_NET_VENDOR_QUALCOMM=y + # CONFIG_QCA7000_SPI is not set ++# CONFIG_QCA7000_UART is not set + CONFIG_QCOM_EMAC=m + # CONFIG_RMNET is not set + # CONFIG_NET_VENDOR_RDC is not set +@@ -2564,13 +2690,24 @@ CONFIG_SFC_MCDI_MON=y CONFIG_SFC_SRIOV=y CONFIG_SFC_MCDI_LOGGING=y # CONFIG_SFC_FALCON is not set @@ -18203,7 +20308,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_NET_VENDOR_SUN is not set # CONFIG_NET_VENDOR_SYNOPSYS is not set # CONFIG_NET_VENDOR_TEHUTI is not set -@@ -2584,8 +2711,12 @@ CONFIG_NGBE=m +@@ -2584,8 +2721,12 @@ CONFIG_NGBE=m CONFIG_TXGBE=m # CONFIG_NET_VENDOR_WIZNET is not set # CONFIG_NET_VENDOR_XILINX is not set @@ -18216,7 +20321,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_PHYLINK=y CONFIG_PHYLIB=y CONFIG_SWPHY=y -@@ -2661,6 +2792,7 @@ CONFIG_CAN_CALC_BITTIMING=y +@@ -2661,6 +2802,7 @@ CONFIG_CAN_CALC_BITTIMING=y # CONFIG_CAN_GRCAN is not set # CONFIG_CAN_KVASER_PCIEFD is not set CONFIG_CAN_SLCAN=m @@ -18224,7 +20329,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_CAN_C_CAN=m CONFIG_CAN_C_CAN_PLATFORM=m CONFIG_CAN_C_CAN_PCI=m -@@ -2672,6 +2804,8 @@ CONFIG_CAN_CC770_PLATFORM=m +@@ -2672,6 +2814,8 @@ CONFIG_CAN_CC770_PLATFORM=m # CONFIG_CAN_IFI_CANFD is not set # CONFIG_CAN_M_CAN is not set # CONFIG_CAN_PEAK_PCIEFD is not set @@ -18233,7 +20338,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_CAN_SJA1000=m CONFIG_CAN_EMS_PCI=m # CONFIG_CAN_F81601 is not set -@@ -2711,7 +2845,9 @@ CONFIG_MDIO_DEVICE=y +@@ -2711,7 +2855,9 @@ CONFIG_MDIO_DEVICE=y CONFIG_MDIO_BUS=y CONFIG_FWNODE_MDIO=y CONFIG_OF_MDIO=y @@ -18243,7 +20348,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_MDIO_BITBANG=m CONFIG_MDIO_BCM_UNIMAC=m CONFIG_MDIO_CAVIUM=m -@@ -2728,6 +2864,7 @@ CONFIG_MDIO_THUNDER=m +@@ -2728,6 +2874,7 @@ CONFIG_MDIO_THUNDER=m # # MDIO Multiplexers # @@ -18251,7 +20356,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_MDIO_BUS_MUX_GPIO is not set # CONFIG_MDIO_BUS_MUX_MULTIPLEXER is not set # CONFIG_MDIO_BUS_MUX_MMIOREG is not set -@@ -2735,7 +2872,7 @@ CONFIG_MDIO_THUNDER=m +@@ -2735,7 +2882,7 @@ CONFIG_MDIO_THUNDER=m # # PCS device drivers # @@ -18260,7 +20365,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # end of PCS device drivers CONFIG_PPP=m -@@ -2768,8 +2905,8 @@ CONFIG_USB_RTL8150=m +@@ -2768,8 +2915,8 @@ CONFIG_USB_RTL8150=m CONFIG_USB_RTL8152=m CONFIG_USB_LAN78XX=m CONFIG_USB_USBNET=m @@ -18271,7 +20376,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_USB_NET_CDCETHER=m CONFIG_USB_NET_CDC_EEM=m CONFIG_USB_NET_CDC_NCM=m -@@ -2781,7 +2918,7 @@ CONFIG_USB_NET_SR9700=m +@@ -2781,7 +2928,7 @@ CONFIG_USB_NET_SR9700=m CONFIG_USB_NET_SMSC75XX=m CONFIG_USB_NET_SMSC95XX=m CONFIG_USB_NET_GL620A=m @@ -18280,7 +20385,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_USB_NET_PLUSB=m CONFIG_USB_NET_MCS7830=m CONFIG_USB_NET_RNDIS_HOST=m -@@ -2865,7 +3002,39 @@ CONFIG_RT2X00_LIB_CRYPTO=y +@@ -2865,7 +3012,39 @@ CONFIG_RT2X00_LIB_CRYPTO=y CONFIG_RT2X00_LIB_LEDS=y # CONFIG_RT2X00_LIB_DEBUGFS is not set # CONFIG_RT2X00_DEBUG is not set @@ -18321,7 +20426,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_WLAN_VENDOR_RSI is not set CONFIG_WLAN_VENDOR_SILABS=y # CONFIG_WFX is not set -@@ -2876,6 +3045,10 @@ CONFIG_WLAN_VENDOR_SILABS=y +@@ -2876,6 +3055,10 @@ CONFIG_WLAN_VENDOR_SILABS=y # CONFIG_USB_NET_RNDIS_WLAN is not set # CONFIG_MAC80211_HWSIM is not set # CONFIG_VIRT_WIFI is not set @@ -18332,7 +20437,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_WAN=y CONFIG_HDLC=m CONFIG_HDLC_RAW=m -@@ -2900,6 +3073,7 @@ CONFIG_HDLC_PPP=m +@@ -2900,6 +3083,7 @@ CONFIG_HDLC_PPP=m # end of Wireless WAN # CONFIG_VMXNET3 is not set @@ -18340,7 +20445,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_USB4_NET=m # CONFIG_NETDEVSIM is not set CONFIG_NET_FAILOVER=y -@@ -2930,6 +3104,7 @@ CONFIG_INPUT_EVDEV=y +@@ -2930,6 +3114,7 @@ CONFIG_INPUT_EVDEV=y # Input Device Drivers # CONFIG_INPUT_KEYBOARD=y @@ -18348,7 +20453,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_KEYBOARD_ADP5588 is not set # CONFIG_KEYBOARD_ADP5589 is not set CONFIG_KEYBOARD_ATKBD=y -@@ -2955,6 +3130,7 @@ CONFIG_KEYBOARD_GPIO=y +@@ -2955,6 +3140,7 @@ CONFIG_KEYBOARD_GPIO=y # CONFIG_KEYBOARD_GOLDFISH_EVENTS is not set # CONFIG_KEYBOARD_STOWAWAY is not set # CONFIG_KEYBOARD_SUNKBD is not set @@ -18356,7 +20461,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_KEYBOARD_OMAP4 is not set # CONFIG_KEYBOARD_TM2_TOUCHKEY is not set # CONFIG_KEYBOARD_XTKBD is not set -@@ -2987,7 +3163,83 @@ CONFIG_MOUSE_SYNAPTICS_I2C=m +@@ -2987,7 +3173,83 @@ CONFIG_MOUSE_SYNAPTICS_I2C=m CONFIG_MOUSE_SYNAPTICS_USB=m # CONFIG_INPUT_JOYSTICK is not set # CONFIG_INPUT_TABLET is not set @@ -18441,7 +20546,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_INPUT_MISC=y # CONFIG_INPUT_AD714X is not set # CONFIG_INPUT_ATMEL_CAPTOUCH is not set -@@ -3004,7 +3256,7 @@ CONFIG_INPUT_MISC=y +@@ -3004,7 +3266,7 @@ CONFIG_INPUT_MISC=y # CONFIG_INPUT_YEALINK is not set # CONFIG_INPUT_CM109 is not set # CONFIG_INPUT_REGULATOR_HAPTIC is not set @@ -18450,7 +20555,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_INPUT_PCF8574 is not set # CONFIG_INPUT_PWM_BEEPER is not set # CONFIG_INPUT_PWM_VIBRA is not set -@@ -3017,6 +3269,7 @@ CONFIG_INPUT_UINPUT=m +@@ -3017,6 +3279,7 @@ CONFIG_INPUT_UINPUT=m # CONFIG_INPUT_IQS626A is not set # CONFIG_INPUT_IQS7222 is not set # CONFIG_INPUT_CMA3000 is not set @@ -18458,7 +20563,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_INPUT_DRV260X_HAPTICS is not set # CONFIG_INPUT_DRV2665_HAPTICS is not set # CONFIG_INPUT_DRV2667_HAPTICS is not set -@@ -3048,6 +3301,7 @@ CONFIG_SERIO_ALTERA_PS2=m +@@ -3048,6 +3311,7 @@ CONFIG_SERIO_ALTERA_PS2=m # CONFIG_SERIO_PS2MULT is not set CONFIG_SERIO_ARC_PS2=m # CONFIG_SERIO_APBPS2 is not set @@ -18466,7 +20571,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_SERIO_GPIO_PS2 is not set # CONFIG_USERIO is not set # CONFIG_GAMEPORT is not set -@@ -3061,7 +3315,6 @@ CONFIG_TTY=y +@@ -3061,7 +3325,6 @@ CONFIG_TTY=y CONFIG_VT=y CONFIG_CONSOLE_TRANSLATIONS=y CONFIG_VT_CONSOLE=y @@ -18474,7 +20579,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_HW_CONSOLE=y CONFIG_VT_HW_CONSOLE_BINDING=y CONFIG_UNIX98_PTYS=y -@@ -3075,6 +3328,7 @@ CONFIG_LDISC_AUTOLOAD=y +@@ -3075,6 +3338,7 @@ CONFIG_LDISC_AUTOLOAD=y CONFIG_SERIAL_EARLYCON=y CONFIG_SERIAL_8250=y # CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set @@ -18482,7 +20587,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_SERIAL_8250_16550A_VARIANTS=y # CONFIG_SERIAL_8250_FINTEK is not set CONFIG_SERIAL_8250_CONSOLE=y -@@ -3082,8 +3336,8 @@ CONFIG_SERIAL_8250_DMA=y +@@ -3082,8 +3346,8 @@ CONFIG_SERIAL_8250_DMA=y CONFIG_SERIAL_8250_PCILIB=y CONFIG_SERIAL_8250_PCI=y CONFIG_SERIAL_8250_EXAR=y @@ -18493,7 +20598,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_MANY_PORTS=y # CONFIG_SERIAL_8250_PCI1XXXX is not set -@@ -3092,6 +3346,7 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y +@@ -3092,6 +3356,7 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y CONFIG_SERIAL_8250_RSA=y CONFIG_SERIAL_8250_DWLIB=y CONFIG_SERIAL_8250_DW=y @@ -18501,9 +20606,12 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_SERIAL_8250_RT288X=y CONFIG_SERIAL_8250_PERICOM=y CONFIG_SERIAL_OF_PLATFORM=y -@@ -3106,6 +3361,11 @@ CONFIG_SERIAL_OF_PLATFORM=y +@@ -3105,7 +3370,14 @@ CONFIG_SERIAL_OF_PLATFORM=y + # CONFIG_SERIAL_KGDB_NMI is not set # CONFIG_SERIAL_MAX3100 is not set # CONFIG_SERIAL_MAX310X is not set ++CONFIG_SERIAL_SPACEMIT_K1X=y ++CONFIG_SERIAL_SPACEMIT_K1X_CONSOLE=y # CONFIG_SERIAL_UARTLITE is not set +CONFIG_SERIAL_SH_SCI=y +CONFIG_SERIAL_SH_SCI_NR_UARTS=18 @@ -18513,7 +20621,17 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_CONSOLE_POLL=y -@@ -3154,6 +3414,7 @@ CONFIG_HW_RANDOM=y +@@ -3136,7 +3408,8 @@ CONFIG_N_GSM=m + # CONFIG_NULL_TTY is not set + CONFIG_HVC_DRIVER=y + # CONFIG_RPMSG_TTY is not set +-# CONFIG_SERIAL_DEV_BUS is not set ++CONFIG_SERIAL_DEV_BUS=y ++CONFIG_SERIAL_DEV_CTRL_TTYPORT=y + # CONFIG_TTY_PRINTK is not set + CONFIG_VIRTIO_CONSOLE=y + CONFIG_IPMI_HANDLER=m +@@ -3154,6 +3427,7 @@ CONFIG_HW_RANDOM=y CONFIG_HW_RANDOM_TIMERIOMEM=m # CONFIG_HW_RANDOM_BA431 is not set CONFIG_HW_RANDOM_VIRTIO=y @@ -18521,7 +20639,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_HW_RANDOM_CCTRNG is not set # CONFIG_HW_RANDOM_XIPHERA is not set # CONFIG_HW_RANDOM_JH7110 is not set -@@ -3172,7 +3433,10 @@ CONFIG_TCG_TIS_I2C_ATMEL=m +@@ -3172,7 +3446,10 @@ CONFIG_TCG_TIS_I2C_ATMEL=m CONFIG_TCG_TIS_I2C_INFINEON=m CONFIG_TCG_TIS_I2C_NUVOTON=m CONFIG_TCG_ATMEL=m @@ -18532,7 +20650,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_TCG_TIS_ST33ZP24=m CONFIG_TCG_TIS_ST33ZP24_I2C=m CONFIG_TCG_TIS_ST33ZP24_SPI=m -@@ -3184,6 +3448,7 @@ CONFIG_TCG_TIS_ST33ZP24_SPI=m +@@ -3184,6 +3461,7 @@ CONFIG_TCG_TIS_ST33ZP24_SPI=m # I2C support # CONFIG_I2C=y @@ -18540,7 +20658,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_I2C_BOARDINFO=y CONFIG_I2C_COMPAT=y CONFIG_I2C_CHARDEV=y -@@ -3221,6 +3486,7 @@ CONFIG_I2C_CCGX_UCSI=m +@@ -3221,6 +3499,7 @@ CONFIG_I2C_CCGX_UCSI=m # CONFIG_I2C_ALI15X3 is not set # CONFIG_I2C_AMD756 is not set # CONFIG_I2C_AMD8111 is not set @@ -18548,7 +20666,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_I2C_I801 is not set # CONFIG_I2C_ISCH is not set # CONFIG_I2C_PIIX4 is not set -@@ -3232,6 +3498,11 @@ CONFIG_I2C_NFORCE2=m +@@ -3232,6 +3511,11 @@ CONFIG_I2C_NFORCE2=m # CONFIG_I2C_VIA is not set # CONFIG_I2C_VIAPRO is not set @@ -18560,7 +20678,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # # I2C system bus drivers (mostly embedded / system-on-chip) # -@@ -3243,12 +3514,17 @@ CONFIG_I2C_DESIGNWARE_PCI=m +@@ -3243,12 +3527,17 @@ CONFIG_I2C_DESIGNWARE_PCI=m # CONFIG_I2C_EMEV2 is not set CONFIG_I2C_GPIO=m # CONFIG_I2C_GPIO_FAULT_INJECTOR is not set @@ -18578,7 +20696,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # # External I2C/SMBus adapter drivers -@@ -3290,6 +3566,7 @@ CONFIG_SPI_MEM=y +@@ -3290,6 +3579,7 @@ CONFIG_SPI_MEM=y CONFIG_SPI_CADENCE=m # CONFIG_SPI_CADENCE_QUADSPI is not set # CONFIG_SPI_CADENCE_XSPI is not set @@ -18586,7 +20704,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_SPI_DESIGNWARE=y # CONFIG_SPI_DW_DMA is not set CONFIG_SPI_DW_PCI=m -@@ -3302,9 +3579,15 @@ CONFIG_SPI_DW_MMIO=y +@@ -3302,9 +3592,15 @@ CONFIG_SPI_DW_MMIO=y # CONFIG_SPI_PCI1XXXX is not set # CONFIG_SPI_PL022 is not set # CONFIG_SPI_PXA2XX is not set @@ -18602,7 +20720,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_SPI_MXIC is not set # CONFIG_SPI_XCOMM is not set # CONFIG_SPI_XILINX is not set -@@ -3319,7 +3602,7 @@ CONFIG_SPI_SIFIVE=y +@@ -3319,7 +3615,7 @@ CONFIG_SPI_SIFIVE=y # # SPI Protocol Masters # @@ -18611,7 +20729,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_SPI_LOOPBACK_TEST is not set # CONFIG_SPI_TLE62X0 is not set # CONFIG_SPI_SLAVE is not set -@@ -3343,14 +3626,8 @@ CONFIG_PPS_CLIENT_GPIO=m +@@ -3343,14 +3639,8 @@ CONFIG_PPS_CLIENT_GPIO=m # # PTP clock support # @@ -18627,7 +20745,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # end of PTP clock support CONFIG_PINCTRL=y -@@ -3360,6 +3637,7 @@ CONFIG_GENERIC_PINMUX_FUNCTIONS=y +@@ -3360,6 +3650,7 @@ CONFIG_GENERIC_PINMUX_FUNCTIONS=y CONFIG_PINCONF=y CONFIG_GENERIC_PINCONF=y # CONFIG_DEBUG_PINCTRL is not set @@ -18635,11 +20753,12 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_PINCTRL_CY8C95X0 is not set # CONFIG_PINCTRL_MCP23S08 is not set # CONFIG_PINCTRL_MICROCHIP_SGPIO is not set -@@ -3367,19 +3645,47 @@ CONFIG_GENERIC_PINCONF=y +@@ -3367,19 +3658,48 @@ CONFIG_GENERIC_PINCONF=y # CONFIG_PINCTRL_SINGLE is not set # CONFIG_PINCTRL_STMFX is not set # CONFIG_PINCTRL_SX150X is not set +CONFIG_PINCTRL_TH1520=y ++CONFIG_PINCTRL_SPACEMIT_K1X=y # # Renesas pinctrl drivers @@ -18683,7 +20802,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_GPIOLIB_IRQCHIP=y # CONFIG_DEBUG_GPIO is not set CONFIG_GPIO_SYSFS=y -@@ -3392,6 +3698,7 @@ CONFIG_GPIO_GENERIC=y +@@ -3392,6 +3712,7 @@ CONFIG_GPIO_GENERIC=y # # CONFIG_GPIO_74XX_MMIO is not set # CONFIG_GPIO_ALTERA is not set @@ -18691,7 +20810,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_GPIO_CADENCE=m CONFIG_GPIO_DWAPB=y # CONFIG_GPIO_EXAR is not set -@@ -3402,6 +3709,7 @@ CONFIG_GPIO_GENERIC_PLATFORM=m +@@ -3402,6 +3723,7 @@ CONFIG_GPIO_GENERIC_PLATFORM=m # CONFIG_GPIO_LOGICVC is not set # CONFIG_GPIO_MB86S7X is not set # CONFIG_GPIO_PL061 is not set @@ -18699,7 +20818,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_GPIO_SIFIVE=y # CONFIG_GPIO_SYSCON is not set # CONFIG_GPIO_XILINX is not set -@@ -3417,7 +3725,8 @@ CONFIG_GPIO_SIFIVE=y +@@ -3417,7 +3739,8 @@ CONFIG_GPIO_SIFIVE=y # CONFIG_GPIO_GW_PLD is not set # CONFIG_GPIO_MAX7300 is not set # CONFIG_GPIO_MAX732X is not set @@ -18709,7 +20828,15 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_GPIO_PCA9570 is not set # CONFIG_GPIO_PCF857X is not set # CONFIG_GPIO_TPIC2810 is not set -@@ -3477,6 +3786,7 @@ CONFIG_POWER_RESET_SYSCON_POWEROFF=y +@@ -3461,6 +3784,7 @@ CONFIG_GPIO_SIFIVE=y + # CONFIG_GPIO_MOCKUP is not set + # CONFIG_GPIO_VIRTIO is not set + # CONFIG_GPIO_SIM is not set ++CONFIG_GPIO_K1X=y + # end of Virtual GPIO drivers + + # CONFIG_W1 is not set +@@ -3477,6 +3801,7 @@ CONFIG_POWER_RESET_SYSCON_POWEROFF=y CONFIG_POWER_SUPPLY=y # CONFIG_POWER_SUPPLY_DEBUG is not set CONFIG_POWER_SUPPLY_HWMON=y @@ -18717,7 +20844,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_IP5XXX_POWER is not set # CONFIG_TEST_POWER is not set # CONFIG_CHARGER_ADP5061 is not set -@@ -3565,6 +3875,7 @@ CONFIG_SENSORS_G762=m +@@ -3565,6 +3890,7 @@ CONFIG_SENSORS_G762=m # CONFIG_SENSORS_HS3001 is not set CONFIG_SENSORS_IBMAEM=m CONFIG_SENSORS_IBMPEX=m @@ -18725,7 +20852,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_SENSORS_IT87=m CONFIG_SENSORS_JC42=m CONFIG_SENSORS_POWR1220=m -@@ -3600,7 +3911,7 @@ CONFIG_SENSORS_MAX31790=m +@@ -3600,7 +3926,7 @@ CONFIG_SENSORS_MAX31790=m CONFIG_SENSORS_MCP3021=m # CONFIG_SENSORS_TC654 is not set # CONFIG_SENSORS_TPS23861 is not set @@ -18734,7 +20861,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_SENSORS_ADCXX=m CONFIG_SENSORS_LM63=m CONFIG_SENSORS_LM70=m -@@ -3620,6 +3931,7 @@ CONFIG_SENSORS_LM95241=m +@@ -3620,6 +3946,7 @@ CONFIG_SENSORS_LM95241=m CONFIG_SENSORS_LM95245=m CONFIG_SENSORS_PC87360=m CONFIG_SENSORS_PC87427=m @@ -18742,7 +20869,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_SENSORS_NCT6683=m # CONFIG_SENSORS_NCT6775 is not set # CONFIG_SENSORS_NCT6775_I2C is not set -@@ -3680,7 +3992,7 @@ CONFIG_SENSORS_UCD9200=m +@@ -3680,7 +4007,7 @@ CONFIG_SENSORS_UCD9200=m # CONFIG_SENSORS_XDPE152 is not set # CONFIG_SENSORS_XDPE122 is not set CONFIG_SENSORS_ZL6100=m @@ -18751,7 +20878,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_SENSORS_SBTSI is not set # CONFIG_SENSORS_SBRMI is not set CONFIG_SENSORS_SHT15=m -@@ -3733,9 +4045,14 @@ CONFIG_SENSORS_W83L785TS=m +@@ -3733,9 +4060,14 @@ CONFIG_SENSORS_W83L785TS=m CONFIG_SENSORS_W83L786NG=m CONFIG_SENSORS_W83627HF=m CONFIG_SENSORS_W83627EHF=m @@ -18767,7 +20894,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 CONFIG_THERMAL_HWMON=y CONFIG_THERMAL_OF=y -@@ -3743,41 +4060,62 @@ CONFIG_THERMAL_OF=y +@@ -3743,41 +4075,62 @@ CONFIG_THERMAL_OF=y CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y # CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set # CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set @@ -18833,7 +20960,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # # PCI-based Watchdog Cards -@@ -3806,6 +4144,7 @@ CONFIG_BCMA_DRIVER_GPIO=y +@@ -3806,6 +4159,7 @@ CONFIG_BCMA_DRIVER_GPIO=y # CONFIG_MFD_CORE=m # CONFIG_MFD_ACT8945A is not set @@ -18841,7 +20968,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_MFD_AS3711 is not set # CONFIG_MFD_SMPRO is not set # CONFIG_MFD_AS3722 is not set -@@ -3877,8 +4216,8 @@ CONFIG_MFD_CORE=m +@@ -3877,8 +4231,8 @@ CONFIG_MFD_CORE=m # CONFIG_MFD_SM501 is not set # CONFIG_MFD_SKY81452 is not set # CONFIG_MFD_STMPE is not set @@ -18851,7 +20978,15 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_MFD_LP3943 is not set # CONFIG_MFD_LP8788 is not set # CONFIG_MFD_TI_LMU is not set -@@ -3999,6 +4338,7 @@ CONFIG_REGULATOR_PWM=y +@@ -3921,6 +4275,7 @@ CONFIG_MFD_SYSCON=y + # CONFIG_MFD_STMFX is not set + # CONFIG_MFD_ATC260X_I2C is not set + # CONFIG_MFD_QCOM_PM8008 is not set ++# CONFIG_RAVE_SP_CORE is not set + # CONFIG_MFD_INTEL_M10_BMC_SPI is not set + # CONFIG_MFD_RSMU_I2C is not set + # CONFIG_MFD_RSMU_SPI is not set +@@ -3999,6 +4354,7 @@ CONFIG_REGULATOR_PWM=y # CONFIG_REGULATOR_TPS65132 is not set # CONFIG_REGULATOR_TPS6524X is not set # CONFIG_REGULATOR_VCTRL is not set @@ -18859,7 +20994,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_RC_CORE is not set # -@@ -4007,7 +4347,7 @@ CONFIG_REGULATOR_PWM=y +@@ -4007,7 +4363,7 @@ CONFIG_REGULATOR_PWM=y # CONFIG_MEDIA_CEC_SUPPORT is not set # end of CEC support @@ -18868,7 +21003,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_MEDIA_SUPPORT_FILTER is not set # CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set -@@ -4131,10 +4471,12 @@ CONFIG_RADIO_ADAPTERS=m +@@ -4131,10 +4487,12 @@ CONFIG_RADIO_ADAPTERS=m # CONFIG_USB_RAREMONO is not set # CONFIG_RADIO_SI470X is not set CONFIG_MEDIA_PLATFORM_DRIVERS=y @@ -18883,7 +21018,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # # Allegro DVT media platform drivers -@@ -4173,6 +4515,7 @@ CONFIG_MEDIA_PLATFORM_DRIVERS=y +@@ -4173,6 +4531,7 @@ CONFIG_MEDIA_PLATFORM_DRIVERS=y # # Marvell media platform drivers # @@ -18891,7 +21026,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # # Mediatek media platform drivers -@@ -4197,6 +4540,15 @@ CONFIG_MEDIA_PLATFORM_DRIVERS=y +@@ -4197,6 +4556,15 @@ CONFIG_MEDIA_PLATFORM_DRIVERS=y # # Renesas media platform drivers # @@ -18907,7 +21042,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # # Rockchip media platform drivers -@@ -4213,6 +4565,11 @@ CONFIG_MEDIA_PLATFORM_DRIVERS=y +@@ -4213,6 +4581,11 @@ CONFIG_MEDIA_PLATFORM_DRIVERS=y # # Sunxi media platform drivers # @@ -18919,7 +21054,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # # Texas Instruments drivers -@@ -4221,6 +4578,7 @@ CONFIG_MEDIA_PLATFORM_DRIVERS=y +@@ -4221,6 +4594,7 @@ CONFIG_MEDIA_PLATFORM_DRIVERS=y # # Verisilicon media platform drivers # @@ -18927,7 +21062,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # # VIA media platform drivers -@@ -4229,6 +4587,7 @@ CONFIG_MEDIA_PLATFORM_DRIVERS=y +@@ -4229,6 +4603,7 @@ CONFIG_MEDIA_PLATFORM_DRIVERS=y # # Xilinx media platform drivers # @@ -18935,7 +21070,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # # MMC/SDIO DVB adapters -@@ -4283,6 +4642,7 @@ CONFIG_VIDEO_CAMERA_SENSOR=y +@@ -4283,6 +4658,7 @@ CONFIG_VIDEO_CAMERA_SENSOR=y # CONFIG_VIDEO_OV2659 is not set # CONFIG_VIDEO_OV2680 is not set # CONFIG_VIDEO_OV2685 is not set @@ -18943,7 +21078,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_VIDEO_OV4689 is not set # CONFIG_VIDEO_OV5640 is not set # CONFIG_VIDEO_OV5645 is not set -@@ -4304,6 +4664,7 @@ CONFIG_VIDEO_CAMERA_SENSOR=y +@@ -4304,6 +4680,7 @@ CONFIG_VIDEO_CAMERA_SENSOR=y # CONFIG_VIDEO_OV9282 is not set # CONFIG_VIDEO_OV9640 is not set # CONFIG_VIDEO_OV9650 is not set @@ -18951,7 +21086,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_VIDEO_RDACM20 is not set # CONFIG_VIDEO_RDACM21 is not set # CONFIG_VIDEO_RJ54N1 is not set -@@ -4341,6 +4702,7 @@ CONFIG_VIDEO_CAMERA_SENSOR=y +@@ -4341,6 +4718,7 @@ CONFIG_VIDEO_CAMERA_SENSOR=y # CONFIG_VIDEO_CS53L32A is not set # CONFIG_VIDEO_MSP3400 is not set # CONFIG_VIDEO_SONY_BTF_MPX is not set @@ -18959,7 +21094,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_VIDEO_TDA7432 is not set # CONFIG_VIDEO_TDA9840 is not set # CONFIG_VIDEO_TEA6415C is not set -@@ -4451,7 +4813,7 @@ CONFIG_CXD2880_SPI_DRV=m +@@ -4451,7 +4829,7 @@ CONFIG_CXD2880_SPI_DRV=m # CONFIG_VIDEO_GS1662 is not set # end of Media SPI Adapters @@ -18968,7 +21103,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # # Customize TV tuners -@@ -4668,6 +5030,7 @@ CONFIG_DVB_SP2=m +@@ -4668,6 +5046,7 @@ CONFIG_DVB_SP2=m # Graphics support # CONFIG_APERTURE_HELPERS=y @@ -18976,7 +21111,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_VIDEO_CMDLINE=y CONFIG_VIDEO_NOMODESET=y CONFIG_AUXDISPLAY=y -@@ -4679,6 +5042,7 @@ CONFIG_AUXDISPLAY=y +@@ -4679,6 +5058,7 @@ CONFIG_AUXDISPLAY=y # CONFIG_CHARLCD_BL_ON is not set CONFIG_CHARLCD_BL_FLASH=y CONFIG_DRM=y @@ -18984,7 +21119,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_DRM_DEBUG_MM is not set CONFIG_DRM_KMS_HELPER=y # CONFIG_DRM_DEBUG_DP_MST_TOPOLOGY_REFS is not set -@@ -4687,7 +5051,7 @@ CONFIG_DRM_FBDEV_EMULATION=y +@@ -4687,7 +5067,7 @@ CONFIG_DRM_FBDEV_EMULATION=y CONFIG_DRM_FBDEV_OVERALLOC=100 # CONFIG_DRM_FBDEV_LEAK_PHYS_SMEM is not set CONFIG_DRM_LOAD_EDID_FIRMWARE=y @@ -18993,7 +21128,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_DRM_DISPLAY_DP_HELPER=y CONFIG_DRM_DISPLAY_HDCP_HELPER=y CONFIG_DRM_DISPLAY_HDMI_HELPER=y -@@ -4720,7 +5084,7 @@ CONFIG_DRM_I2C_NXP_TDA998X=m +@@ -4720,7 +5100,7 @@ CONFIG_DRM_I2C_NXP_TDA998X=m CONFIG_DRM_RADEON=m CONFIG_DRM_RADEON_USERPTR=y CONFIG_DRM_AMDGPU=m @@ -19002,7 +21137,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_DRM_AMDGPU_CIK=y CONFIG_DRM_AMDGPU_USERPTR=y # CONFIG_DRM_AMDGPU_WERROR is not set -@@ -4735,9 +5099,13 @@ CONFIG_DRM_AMDGPU_USERPTR=y +@@ -4735,9 +5115,13 @@ CONFIG_DRM_AMDGPU_USERPTR=y # Display Engine Configuration # CONFIG_DRM_AMD_DC=y @@ -19016,7 +21151,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_DRM_NOUVEAU=m CONFIG_NOUVEAU_DEBUG=5 CONFIG_NOUVEAU_DEBUG_DEFAULT=3 -@@ -4749,6 +5117,9 @@ CONFIG_DRM_NOUVEAU_BACKLIGHT=y +@@ -4749,6 +5133,9 @@ CONFIG_DRM_NOUVEAU_BACKLIGHT=y CONFIG_DRM_UDL=m CONFIG_DRM_AST=m CONFIG_DRM_MGAG200=m @@ -19026,7 +21161,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_DRM_QXL=m CONFIG_DRM_VIRTIO_GPU=m CONFIG_DRM_VIRTIO_GPU_KMS=y -@@ -4759,36 +5130,89 @@ CONFIG_DRM_PANEL=y +@@ -4759,36 +5146,89 @@ CONFIG_DRM_PANEL=y # # CONFIG_DRM_PANEL_ABT_Y030XX067A is not set # CONFIG_DRM_PANEL_ARM_VERSATILE is not set @@ -19117,7 +21252,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # end of Display Panels CONFIG_DRM_BRIDGE=y -@@ -4834,10 +5258,16 @@ CONFIG_DRM_PANEL_BRIDGE=y +@@ -4834,10 +5274,16 @@ CONFIG_DRM_PANEL_BRIDGE=y # CONFIG_DRM_I2C_ADV7511 is not set # CONFIG_DRM_CDNS_DSI is not set # CONFIG_DRM_CDNS_MHDP8546 is not set @@ -19135,7 +21270,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_DRM_LOGICVC is not set # CONFIG_DRM_ARCPGU is not set CONFIG_DRM_BOCHS=m -@@ -4856,6 +5286,14 @@ CONFIG_DRM_CIRRUS_QEMU=m +@@ -4856,6 +5302,14 @@ CONFIG_DRM_CIRRUS_QEMU=m # CONFIG_TINYDRM_ST7735R is not set # CONFIG_DRM_GUD is not set # CONFIG_DRM_SSD130X is not set @@ -19150,7 +21285,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_DRM_LEGACY is not set CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y -@@ -4894,6 +5332,7 @@ CONFIG_FB_RADEON_BACKLIGHT=y +@@ -4894,6 +5348,7 @@ CONFIG_FB_RADEON_BACKLIGHT=y # CONFIG_FB_ARK is not set # CONFIG_FB_PM3 is not set # CONFIG_FB_CARMINE is not set @@ -19158,7 +21293,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_FB_SMSCUFX is not set # CONFIG_FB_UDL is not set # CONFIG_FB_IBM_GXT4500 is not set -@@ -4919,6 +5358,7 @@ CONFIG_FB_SYS_IMAGEBLIT=y +@@ -4919,6 +5374,7 @@ CONFIG_FB_SYS_IMAGEBLIT=y # CONFIG_FB_FOREIGN_ENDIAN is not set CONFIG_FB_SYS_FOPS=y CONFIG_FB_DEFERRED_IO=y @@ -19166,7 +21301,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_FB_IOMEM_HELPERS=y CONFIG_FB_SYSMEM_HELPERS=y CONFIG_FB_SYSMEM_HELPERS_DEFERRED=y -@@ -4946,7 +5386,7 @@ CONFIG_LCD_PLATFORM=m +@@ -4946,7 +5402,7 @@ CONFIG_LCD_PLATFORM=m CONFIG_BACKLIGHT_CLASS_DEVICE=y # CONFIG_BACKLIGHT_KTD253 is not set # CONFIG_BACKLIGHT_KTZ8866 is not set @@ -19175,7 +21310,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_BACKLIGHT_QCOM_WLED is not set # CONFIG_BACKLIGHT_ADP8860 is not set # CONFIG_BACKLIGHT_ADP8870 is not set -@@ -4960,6 +5400,7 @@ CONFIG_BACKLIGHT_GPIO=m +@@ -4960,6 +5416,7 @@ CONFIG_BACKLIGHT_GPIO=m # CONFIG_BACKLIGHT_LED is not set # end of Backlight & LCD device support @@ -19183,7 +21318,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_HDMI=y # -@@ -4983,10 +5424,13 @@ CONFIG_LOGO_LINUX_CLUT224=y +@@ -4983,10 +5440,13 @@ CONFIG_LOGO_LINUX_CLUT224=y # end of Graphics support # CONFIG_DRM_ACCEL is not set @@ -19201,7 +21336,15 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_SND_HWDEP=m CONFIG_SND_RAWMIDI=m CONFIG_SND_JACK=y -@@ -5074,6 +5518,11 @@ CONFIG_SND_HDA_INTEL=m +@@ -5010,6 +5470,7 @@ CONFIG_SND_ALOOP=m + # CONFIG_SND_PCMTEST is not set + # CONFIG_SND_MTPAV is not set + # CONFIG_SND_SERIAL_U16550 is not set ++# CONFIG_SND_SERIAL_GENERIC is not set + # CONFIG_SND_MPU401 is not set + CONFIG_SND_PCI=y + # CONFIG_SND_AD1889 is not set +@@ -5074,6 +5535,11 @@ CONFIG_SND_HDA_INTEL=m # CONFIG_SND_HDA_RECONFIG is not set # CONFIG_SND_HDA_INPUT_BEEP is not set # CONFIG_SND_HDA_PATCH_LOADER is not set @@ -19213,7 +21356,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_SND_HDA_CODEC_REALTEK is not set # CONFIG_SND_HDA_CODEC_ANALOG is not set # CONFIG_SND_HDA_CODEC_SIGMATEL is not set -@@ -5095,7 +5544,9 @@ CONFIG_SND_HDA_POWER_SAVE_DEFAULT=0 +@@ -5095,7 +5561,9 @@ CONFIG_SND_HDA_POWER_SAVE_DEFAULT=0 CONFIG_SND_HDA_CORE=m CONFIG_SND_HDA_COMPONENT=y CONFIG_SND_HDA_PREALLOC_SIZE=64 @@ -19223,7 +21366,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_SND_SPI=y CONFIG_SND_USB=y CONFIG_SND_USB_AUDIO=m -@@ -5110,7 +5561,273 @@ CONFIG_SND_USB_AUDIO_USE_MEDIA_CONTROLLER=y +@@ -5110,7 +5578,273 @@ CONFIG_SND_USB_AUDIO_USE_MEDIA_CONTROLLER=y # CONFIG_SND_USB_PODHD is not set # CONFIG_SND_USB_TONEPORT is not set # CONFIG_SND_USB_VARIAX is not set @@ -19498,7 +21641,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_SND_VIRTIO is not set CONFIG_HID_SUPPORT=y CONFIG_HID=y -@@ -5195,6 +5912,7 @@ CONFIG_HID_MULTITOUCH=m +@@ -5195,6 +5929,7 @@ CONFIG_HID_MULTITOUCH=m # CONFIG_HID_NINTENDO is not set # CONFIG_HID_NTI is not set CONFIG_HID_NTRIG=y @@ -19506,7 +21649,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_HID_ORTEK=m CONFIG_HID_PANTHERLORD=m # CONFIG_PANTHERLORD_FF is not set -@@ -5261,6 +5979,7 @@ CONFIG_USB_HIDDEV=y +@@ -5261,6 +5996,7 @@ CONFIG_USB_HIDDEV=y # end of USB HID support CONFIG_I2C_HID=y @@ -19514,7 +21657,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_I2C_HID_OF is not set # CONFIG_I2C_HID_OF_ELAN is not set # CONFIG_I2C_HID_OF_GOODIX is not set -@@ -5297,6 +6016,7 @@ CONFIG_USB_XHCI_HCD=y +@@ -5297,6 +6033,7 @@ CONFIG_USB_XHCI_HCD=y CONFIG_USB_XHCI_PCI=y # CONFIG_USB_XHCI_PCI_RENESAS is not set CONFIG_USB_XHCI_PLATFORM=y @@ -19522,7 +21665,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_ROOT_HUB_TT=y CONFIG_USB_EHCI_TT_NEWSCHED=y -@@ -5314,6 +6034,7 @@ CONFIG_USB_UHCI_HCD=y +@@ -5314,6 +6051,7 @@ CONFIG_USB_UHCI_HCD=y # CONFIG_USB_R8A66597_HCD is not set # CONFIG_USB_HCD_BCMA is not set # CONFIG_USB_HCD_TEST_MODE is not set @@ -19530,7 +21673,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # # USB Device Class drivers -@@ -5338,8 +6059,8 @@ CONFIG_USB_STORAGE_DATAFAB=m +@@ -5338,8 +6076,8 @@ CONFIG_USB_STORAGE_DATAFAB=m CONFIG_USB_STORAGE_FREECOM=m CONFIG_USB_STORAGE_ISD200=m CONFIG_USB_STORAGE_USBAT=m @@ -19541,7 +21684,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_USB_STORAGE_JUMPSHOT=m CONFIG_USB_STORAGE_ALAUDA=m CONFIG_USB_STORAGE_ONETOUCH=m -@@ -5360,7 +6081,19 @@ CONFIG_USB_MICROTEK=m +@@ -5360,7 +6098,19 @@ CONFIG_USB_MICROTEK=m # # CONFIG_USB_CDNS_SUPPORT is not set # CONFIG_USB_MUSB_HDRC is not set @@ -19562,7 +21705,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_USB_DWC2 is not set # CONFIG_USB_CHIPIDEA is not set # CONFIG_USB_ISP1760 is not set -@@ -5452,7 +6185,7 @@ CONFIG_USB_HSIC_USB3503=m +@@ -5452,7 +6202,7 @@ CONFIG_USB_HSIC_USB3503=m # CONFIG_USB_HSIC_USB4604 is not set # CONFIG_USB_LINK_LAYER_TEST is not set CONFIG_USB_CHAOSKEY=m @@ -19571,7 +21714,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_USB_ATM=m # CONFIG_USB_SPEEDTOUCH is not set CONFIG_USB_CXACRU=m -@@ -5467,7 +6200,101 @@ CONFIG_USB_XUSBATM=m +@@ -5467,7 +6217,101 @@ CONFIG_USB_XUSBATM=m # CONFIG_USB_ISP1301 is not set # end of USB Physical Layer drivers @@ -19674,7 +21817,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_TYPEC=m CONFIG_TYPEC_TCPM=m CONFIG_TYPEC_TCPCI=m -@@ -5476,6 +6303,7 @@ CONFIG_TYPEC_TCPCI=m +@@ -5476,6 +6320,7 @@ CONFIG_TYPEC_TCPCI=m # CONFIG_TYPEC_FUSB302 is not set CONFIG_TYPEC_UCSI=m # CONFIG_UCSI_CCG is not set @@ -19682,7 +21825,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_UCSI_STM32G0 is not set # CONFIG_TYPEC_TPS6598X is not set # CONFIG_TYPEC_ANX7411 is not set -@@ -5500,7 +6328,7 @@ CONFIG_TYPEC_DP_ALTMODE=m +@@ -5500,7 +6345,7 @@ CONFIG_TYPEC_DP_ALTMODE=m # CONFIG_TYPEC_NVIDIA_ALTMODE is not set # end of USB Type-C Alternate Mode drivers @@ -19691,7 +21834,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_MMC=y CONFIG_PWRSEQ_EMMC=m CONFIG_PWRSEQ_SIMPLE=m -@@ -5519,15 +6347,18 @@ CONFIG_MMC_SDHCI=y +@@ -5519,15 +6364,18 @@ CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_IO_ACCESSORS=y CONFIG_MMC_SDHCI_PCI=m CONFIG_MMC_RICOH_MMC=y @@ -19711,7 +21854,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_MMC_CB710=m CONFIG_MMC_VIA_SDMMC=m CONFIG_MMC_DW=m -@@ -5538,18 +6369,18 @@ CONFIG_MMC_DW_BLUEFIELD=m +@@ -5538,18 +6386,18 @@ CONFIG_MMC_DW_BLUEFIELD=m # CONFIG_MMC_DW_K3 is not set CONFIG_MMC_DW_PCI=m # CONFIG_MMC_DW_STARFIVE is not set @@ -19732,7 +21875,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_SCSI_UFSHCD is not set CONFIG_MEMSTICK=m # CONFIG_MEMSTICK_DEBUG is not set -@@ -5590,7 +6421,7 @@ CONFIG_LEDS_LM3530=m +@@ -5590,7 +6438,7 @@ CONFIG_LEDS_LM3530=m # CONFIG_LEDS_LM3642 is not set # CONFIG_LEDS_LM3692X is not set # CONFIG_LEDS_PCA9532 is not set @@ -19741,7 +21884,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_LEDS_LP3944=m # CONFIG_LEDS_LP3952 is not set # CONFIG_LEDS_LP50XX is not set -@@ -5672,6 +6503,7 @@ CONFIG_INFINIBAND_USER_MEM=y +@@ -5672,6 +6520,7 @@ CONFIG_INFINIBAND_USER_MEM=y CONFIG_INFINIBAND_ON_DEMAND_PAGING=y CONFIG_INFINIBAND_ADDR_TRANS=y CONFIG_INFINIBAND_ADDR_TRANS_CONFIGFS=y @@ -19749,7 +21892,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_INFINIBAND_VIRT_DMA=y CONFIG_INFINIBAND_BNXT_RE=m CONFIG_INFINIBAND_CXGB4=m -@@ -5804,21 +6636,28 @@ CONFIG_RTC_DRV_M48T35=m +@@ -5804,21 +6653,28 @@ CONFIG_RTC_DRV_M48T35=m CONFIG_RTC_DRV_M48T59=m CONFIG_RTC_DRV_MSM6242=m CONFIG_RTC_DRV_RP5C01=m @@ -19778,7 +21921,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_DMADEVICES=y # CONFIG_DMADEVICES_DEBUG is not set -@@ -5826,10 +6665,13 @@ CONFIG_DMADEVICES=y +@@ -5826,10 +6682,13 @@ CONFIG_DMADEVICES=y # DMA Devices # CONFIG_DMA_ENGINE=y @@ -19793,7 +21936,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_FSL_EDMA is not set # CONFIG_INTEL_IDMA64 is not set # CONFIG_PL330_DMA is not set -@@ -5844,22 +6686,25 @@ CONFIG_DW_DMAC=m +@@ -5844,22 +6703,25 @@ CONFIG_DW_DMAC=m CONFIG_DW_DMAC_PCI=m # CONFIG_DW_EDMA is not set # CONFIG_SF_PDMA is not set @@ -19823,7 +21966,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_DMABUF_HEAPS is not set # CONFIG_DMABUF_SYSFS_STATS is not set # end of DMABUF options -@@ -5948,6 +6793,8 @@ CONFIG_COMMON_CLK=y +@@ -5948,8 +6810,11 @@ CONFIG_COMMON_CLK=y # CONFIG_COMMON_CLK_VC7 is not set # CONFIG_COMMON_CLK_FIXED_MMIO is not set CONFIG_CLK_ANALOGBITS_WRPLL_CLN28HPC=y @@ -19831,8 +21974,11 @@ index 61f2b2f12589..c39bbc3701b3 100644 +# CONFIG_CLK_RCAR_USB2_CLOCK_SEL is not set CONFIG_CLK_SIFIVE=y CONFIG_CLK_SIFIVE_PRCI=y ++CONFIG_SPACEMIT_K1X_CCU=y CONFIG_CLK_STARFIVE_JH71X0=y -@@ -5959,15 +6806,27 @@ CONFIG_CLK_STARFIVE_JH7110_AON=m + CONFIG_CLK_STARFIVE_JH7100=y + CONFIG_CLK_STARFIVE_JH7100_AUDIO=m +@@ -5959,15 +6824,27 @@ CONFIG_CLK_STARFIVE_JH7110_AON=m CONFIG_CLK_STARFIVE_JH7110_STG=m CONFIG_CLK_STARFIVE_JH7110_ISP=m CONFIG_CLK_STARFIVE_JH7110_VOUT=m @@ -19860,7 +22006,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_RISCV_TIMER=y # end of Clock Source drivers -@@ -5976,8 +6835,11 @@ CONFIG_MAILBOX=y +@@ -5976,8 +6853,11 @@ CONFIG_MAILBOX=y # CONFIG_ARM_MHU_V2 is not set # CONFIG_PLATFORM_MHU is not set # CONFIG_PL320_MBOX is not set @@ -19872,7 +22018,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_IOMMU_API=y CONFIG_IOMMU_SUPPORT=y -@@ -5992,6 +6854,7 @@ CONFIG_IOMMU_DEFAULT_DMA_LAZY=y +@@ -5992,6 +6872,7 @@ CONFIG_IOMMU_DEFAULT_DMA_LAZY=y # CONFIG_IOMMU_DEFAULT_PASSTHROUGH is not set CONFIG_OF_IOMMU=y # CONFIG_IOMMUFD is not set @@ -19880,7 +22026,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # # Remoteproc drivers -@@ -6007,6 +6870,7 @@ CONFIG_RPMSG_CHAR=y +@@ -6007,6 +6888,7 @@ CONFIG_RPMSG_CHAR=y CONFIG_RPMSG_CTRL=y CONFIG_RPMSG_NS=y # CONFIG_RPMSG_QCOM_GLINK_RPM is not set @@ -19888,7 +22034,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_RPMSG_VIRTIO=y # end of Rpmsg drivers -@@ -6055,22 +6919,65 @@ CONFIG_RPMSG_VIRTIO=y +@@ -6055,22 +6937,65 @@ CONFIG_RPMSG_VIRTIO=y # CONFIG_QCOM_PMIC_GLINK is not set # end of Qualcomm SoC drivers @@ -19955,7 +22101,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_EXTCON_FSA9480 is not set CONFIG_EXTCON_GPIO=m # CONFIG_EXTCON_MAX3355 is not set -@@ -6080,7 +6987,536 @@ CONFIG_EXTCON_GPIO=m +@@ -6080,7 +7005,539 @@ CONFIG_EXTCON_GPIO=m # CONFIG_EXTCON_USB_GPIO is not set # CONFIG_EXTCON_USBC_TUSB320 is not set # CONFIG_MEMORY is not set @@ -20126,11 +22272,13 @@ index 61f2b2f12589..c39bbc3701b3 100644 +# CONFIG_BME680 is not set +# CONFIG_CCS811 is not set +# CONFIG_IAQCORE is not set ++# CONFIG_PMS7003 is not set +# CONFIG_SCD30_CORE is not set +# CONFIG_SCD4X is not set +# CONFIG_SENSIRION_SGP30 is not set +# CONFIG_SENSIRION_SGP40 is not set +# CONFIG_SPS30_I2C is not set ++# CONFIG_SPS30_SERIAL is not set +# CONFIG_SENSEAIR_SUNRISE_CO2 is not set +# CONFIG_VZ89X is not set +# end of Chemical Sensors @@ -20286,6 +22434,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 +# CONFIG_ADIS16480 is not set +# CONFIG_BMI160_I2C is not set +# CONFIG_BMI160_SPI is not set ++# CONFIG_BOSCH_BNO055_SERIAL is not set +# CONFIG_BOSCH_BNO055_I2C is not set +# CONFIG_FXOS8700_I2C is not set +# CONFIG_FXOS8700_SPI is not set @@ -20493,7 +22642,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_NTB is not set CONFIG_PWM=y CONFIG_PWM_SYSFS=y -@@ -6090,7 +7526,11 @@ CONFIG_PWM_SYSFS=y +@@ -6090,7 +7547,11 @@ CONFIG_PWM_SYSFS=y # CONFIG_PWM_DWC is not set # CONFIG_PWM_FSL_FTM is not set # CONFIG_PWM_PCA9685 is not set @@ -20505,7 +22654,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_PWM_XILINX is not set # -@@ -6100,12 +7540,18 @@ CONFIG_IRQCHIP=y +@@ -6100,14 +7561,21 @@ CONFIG_IRQCHIP=y # CONFIG_AL_FIC is not set # CONFIG_XILINX_INTC is not set CONFIG_RISCV_INTC=y @@ -20523,8 +22672,11 @@ index 61f2b2f12589..c39bbc3701b3 100644 +CONFIG_RESET_TH1520=y # CONFIG_RESET_TI_SYSCON is not set # CONFIG_RESET_TI_TPS380X is not set ++CONFIG_RESET_K1X_SPACEMIT=y CONFIG_RESET_STARFIVE_JH71X0=y -@@ -6116,7 +7562,12 @@ CONFIG_RESET_STARFIVE_JH7110=y + CONFIG_RESET_STARFIVE_JH7100=y + CONFIG_RESET_STARFIVE_JH7110=y +@@ -6116,7 +7584,12 @@ CONFIG_RESET_STARFIVE_JH7110=y # PHY Subsystem # CONFIG_GENERIC_PHY=y @@ -20537,7 +22689,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # # PHY drivers for Broadcom platforms -@@ -6132,14 +7583,21 @@ CONFIG_GENERIC_PHY=y +@@ -6132,14 +7605,21 @@ CONFIG_GENERIC_PHY=y # CONFIG_PHY_PXA_28NM_HSIC is not set # CONFIG_PHY_PXA_28NM_USB2 is not set # CONFIG_PHY_LAN966X_SERDES is not set @@ -20559,7 +22711,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # end of PHY Subsystem # CONFIG_POWERCAP is not set -@@ -6191,7 +7649,9 @@ CONFIG_NVMEM_SYSFS=y +@@ -6191,7 +7671,9 @@ CONFIG_NVMEM_SYSFS=y # end of Layout Types # CONFIG_NVMEM_RMEM is not set @@ -20569,7 +22721,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # # HW tracing support -@@ -6202,6 +7662,8 @@ CONFIG_NVMEM_SYSFS=y +@@ -6202,6 +7684,8 @@ CONFIG_NVMEM_SYSFS=y # CONFIG_FPGA is not set # CONFIG_FSI is not set @@ -20578,7 +22730,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_PM_OPP=y # CONFIG_SIOX is not set # CONFIG_SLIMBUS is not set -@@ -6235,6 +7697,7 @@ CONFIG_EXT4_FS_POSIX_ACL=y +@@ -6235,6 +7719,7 @@ CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_EXT4_FS_SECURITY=y # CONFIG_EXT4_DEBUG is not set # CONFIG_EXT4_ERROR_REPORT is not set @@ -20586,7 +22738,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_JBD2=y # CONFIG_JBD2_DEBUG is not set CONFIG_FS_MBCACHE=y -@@ -6289,10 +7752,10 @@ CONFIG_QUOTA_TREE=y +@@ -6289,10 +7774,10 @@ CONFIG_QUOTA_TREE=y CONFIG_QFMT_V2=y CONFIG_QUOTACTL=y CONFIG_AUTOFS_FS=y @@ -20599,7 +22751,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_OVERLAY_FS_REDIRECT_DIR is not set CONFIG_OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW=y # CONFIG_OVERLAY_FS_INDEX is not set -@@ -6382,8 +7845,24 @@ CONFIG_MISC_FILESYSTEMS=y +@@ -6382,8 +7867,24 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set @@ -20626,7 +22778,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_CRAMFS=m CONFIG_CRAMFS_BLOCKDEV=y # CONFIG_CRAMFS_MTD is not set -@@ -6416,7 +7895,6 @@ CONFIG_PSTORE_DEFAULT_KMSG_BYTES=10240 +@@ -6416,7 +7917,6 @@ CONFIG_PSTORE_DEFAULT_KMSG_BYTES=10240 CONFIG_PSTORE_COMPRESS=y # CONFIG_PSTORE_CONSOLE is not set # CONFIG_PSTORE_PMSG is not set @@ -20634,7 +22786,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_PSTORE_RAM=m # CONFIG_PSTORE_BLK is not set # CONFIG_SYSV_FS is not set -@@ -6432,7 +7910,7 @@ CONFIG_NFS_V4=y +@@ -6432,7 +7932,7 @@ CONFIG_NFS_V4=y CONFIG_NFS_V4_1=y CONFIG_NFS_V4_2=y CONFIG_PNFS_FILE_LAYOUT=y @@ -20643,7 +22795,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_PNFS_FLEXFILE_LAYOUT=m CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN="kernel.org" # CONFIG_NFS_V4_1_MIGRATION is not set -@@ -6518,7 +7996,7 @@ CONFIG_NLS_ISO8859_8=m +@@ -6518,7 +8018,7 @@ CONFIG_NLS_ISO8859_8=m CONFIG_NLS_CODEPAGE_1250=m CONFIG_NLS_CODEPAGE_1251=m CONFIG_NLS_ASCII=y @@ -20652,7 +22804,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_NLS_ISO8859_2=m CONFIG_NLS_ISO8859_3=m CONFIG_NLS_ISO8859_4=m -@@ -6557,6 +8035,7 @@ CONFIG_KEYS=y +@@ -6557,6 +8057,7 @@ CONFIG_KEYS=y CONFIG_PERSISTENT_KEYRINGS=y CONFIG_TRUSTED_KEYS=y CONFIG_TRUSTED_KEYS_TPM=y @@ -20660,7 +22812,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_ENCRYPTED_KEYS=y # CONFIG_USER_DECRYPTED_DATA is not set # CONFIG_KEY_DH_OPERATIONS is not set -@@ -6635,6 +8114,7 @@ CONFIG_IMA_MEASURE_ASYMMETRIC_KEYS=y +@@ -6635,6 +8136,7 @@ CONFIG_IMA_MEASURE_ASYMMETRIC_KEYS=y CONFIG_IMA_QUEUE_EARLY_BOOT_KEYS=y # CONFIG_IMA_DISABLE_HTABLE is not set # CONFIG_IMA_DIGEST_LIST is not set @@ -20668,16 +22820,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_EVM=y # CONFIG_EVM_DEFAULT_HASH_SHA1 is not set CONFIG_EVM_DEFAULT_HASH_SHA256=y -@@ -6657,6 +8137,8 @@ CONFIG_LSM="lockdown,yama,loadpin,safesetid,integrity,selinux,smack,tomoyo,appar - # Memory initialization - # - CONFIG_INIT_STACK_NONE=y -+# CONFIG_INIT_STACK_ALL_PATTERN is not set -+# CONFIG_INIT_STACK_ALL_ZERO is not set - # CONFIG_INIT_ON_ALLOC_DEFAULT_ON is not set - # CONFIG_INIT_ON_FREE_DEFAULT_ON is not set - # CONFIG_ZERO_CALL_USED_REGS is not set -@@ -6671,8 +8153,6 @@ CONFIG_LIST_HARDENED=y +@@ -6671,8 +8173,6 @@ CONFIG_LIST_HARDENED=y CONFIG_RANDSTRUCT_NONE=y # end of Kernel hardening options @@ -20686,7 +22829,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # end of Security options CONFIG_XOR_BLOCKS=m -@@ -6693,6 +8173,7 @@ CONFIG_CRYPTO_ALGAPI=y +@@ -6693,6 +8193,7 @@ CONFIG_CRYPTO_ALGAPI=y CONFIG_CRYPTO_ALGAPI2=y CONFIG_CRYPTO_AEAD=y CONFIG_CRYPTO_AEAD2=y @@ -20694,7 +22837,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_CRYPTO_SIG2=y CONFIG_CRYPTO_SKCIPHER=y CONFIG_CRYPTO_SKCIPHER2=y -@@ -6704,18 +8185,18 @@ CONFIG_CRYPTO_RNG_DEFAULT=y +@@ -6704,18 +8205,18 @@ CONFIG_CRYPTO_RNG_DEFAULT=y CONFIG_CRYPTO_AKCIPHER2=y CONFIG_CRYPTO_AKCIPHER=y CONFIG_CRYPTO_KPP2=y @@ -20716,7 +22859,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_CRYPTO_TEST=m CONFIG_CRYPTO_ENGINE=y # end of Crypto core or helper -@@ -6724,14 +8205,14 @@ CONFIG_CRYPTO_ENGINE=y +@@ -6724,14 +8225,14 @@ CONFIG_CRYPTO_ENGINE=y # Public-key cryptography # CONFIG_CRYPTO_RSA=y @@ -20735,7 +22878,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # end of Public-key cryptography # -@@ -6747,7 +8228,7 @@ CONFIG_CRYPTO_CAMELLIA=m +@@ -6747,7 +8248,7 @@ CONFIG_CRYPTO_CAMELLIA=m CONFIG_CRYPTO_CAST_COMMON=m CONFIG_CRYPTO_CAST5=m CONFIG_CRYPTO_CAST6=m @@ -20744,7 +22887,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_CRYPTO_FCRYPT=m CONFIG_CRYPTO_KHAZAD=m CONFIG_CRYPTO_SEED=m -@@ -6764,7 +8245,7 @@ CONFIG_CRYPTO_TWOFISH_COMMON=m +@@ -6764,7 +8265,7 @@ CONFIG_CRYPTO_TWOFISH_COMMON=m # # CONFIG_CRYPTO_ADIANTUM is not set CONFIG_CRYPTO_ARC4=m @@ -20753,7 +22896,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_CRYPTO_CBC=y # CONFIG_CRYPTO_CFB is not set CONFIG_CRYPTO_CTR=y -@@ -6773,35 +8254,35 @@ CONFIG_CRYPTO_ECB=y +@@ -6773,35 +8274,35 @@ CONFIG_CRYPTO_ECB=y # CONFIG_CRYPTO_HCTR2 is not set # CONFIG_CRYPTO_KEYWRAP is not set CONFIG_CRYPTO_LRW=m @@ -20796,7 +22939,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_CRYPTO_RMD160=m CONFIG_CRYPTO_SHA1=y CONFIG_CRYPTO_SHA256=y -@@ -6864,6 +8345,10 @@ CONFIG_CRYPTO_USER_API_ENABLE_OBSOLETE=y +@@ -6864,6 +8365,10 @@ CONFIG_CRYPTO_USER_API_ENABLE_OBSOLETE=y CONFIG_CRYPTO_HASH_INFO=y CONFIG_CRYPTO_HW=y @@ -20807,7 +22950,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_CRYPTO_DEV_ATMEL_ECC is not set # CONFIG_CRYPTO_DEV_ATMEL_SHA204A is not set # CONFIG_CRYPTO_DEV_NITROX_CNN55XX is not set -@@ -6871,6 +8356,7 @@ CONFIG_CRYPTO_HW=y +@@ -6871,6 +8376,7 @@ CONFIG_CRYPTO_HW=y # CONFIG_CRYPTO_DEV_QAT_C3XXX is not set # CONFIG_CRYPTO_DEV_QAT_C62X is not set # CONFIG_CRYPTO_DEV_QAT_4XXX is not set @@ -20815,7 +22958,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_CRYPTO_DEV_QAT_DH895xCCVF is not set # CONFIG_CRYPTO_DEV_QAT_C3XXXVF is not set # CONFIG_CRYPTO_DEV_QAT_C62XVF is not set -@@ -6933,16 +8419,16 @@ CONFIG_GENERIC_PCI_IOMAP=y +@@ -6933,16 +8439,16 @@ CONFIG_GENERIC_PCI_IOMAP=y # CONFIG_CRYPTO_LIB_UTILS=y CONFIG_CRYPTO_LIB_AES=y @@ -20837,7 +22980,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_CRYPTO_LIB_POLY1305 is not set # CONFIG_CRYPTO_LIB_CHACHA20POLY1305 is not set CONFIG_CRYPTO_LIB_SHA1=y -@@ -7013,6 +8499,7 @@ CONFIG_HAS_IOPORT_MAP=y +@@ -7013,6 +8519,7 @@ CONFIG_HAS_IOPORT_MAP=y CONFIG_HAS_DMA=y CONFIG_NEED_DMA_MAP_STATE=y CONFIG_ARCH_DMA_ADDR_T_64BIT=y @@ -20845,7 +22988,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_DMA_DECLARE_COHERENT=y CONFIG_ARCH_HAS_SETUP_DMA_OPS=y CONFIG_ARCH_HAS_SYNC_DMA_FOR_DEVICE=y -@@ -7032,7 +8519,7 @@ CONFIG_DMA_CMA=y +@@ -7032,7 +8539,7 @@ CONFIG_DMA_CMA=y # # Default contiguous memory area size: # @@ -20854,7 +22997,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_CMA_SIZE_SEL_MBYTES=y # CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set # CONFIG_CMA_SIZE_SEL_MIN is not set -@@ -7043,7 +8530,6 @@ CONFIG_DMA_MAP_BENCHMARK=y +@@ -7043,7 +8550,6 @@ CONFIG_DMA_MAP_BENCHMARK=y CONFIG_SGL_ALLOC=y CONFIG_CHECK_SIGNATURE=y # CONFIG_CPUMASK_OFFSTACK is not set @@ -20862,7 +23005,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_CPU_RMAP=y CONFIG_DQL=y CONFIG_GLOB=y -@@ -7096,7 +8582,6 @@ CONFIG_BOOT_PRINTK_DELAY=y +@@ -7096,7 +8602,6 @@ CONFIG_BOOT_PRINTK_DELAY=y CONFIG_DYNAMIC_DEBUG=y CONFIG_DYNAMIC_DEBUG_CORE=y CONFIG_SYMBOLIC_ERRNAME=y @@ -20870,15 +23013,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # end of printk and dmesg options CONFIG_DEBUG_KERNEL=y -@@ -7113,6 +8598,7 @@ CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y - # CONFIG_DEBUG_INFO_REDUCED is not set - CONFIG_DEBUG_INFO_COMPRESSED_NONE=y - # CONFIG_DEBUG_INFO_COMPRESSED_ZLIB is not set -+# CONFIG_DEBUG_INFO_SPLIT is not set - CONFIG_DEBUG_INFO_BTF=y - CONFIG_PAHOLE_HAS_SPLIT_BTF=y - CONFIG_PAHOLE_HAS_LANG_EXCLUDE=y -@@ -7179,7 +8665,6 @@ CONFIG_SLUB_DEBUG=y +@@ -7179,7 +8684,6 @@ CONFIG_SLUB_DEBUG=y # CONFIG_PAGE_TABLE_CHECK is not set # CONFIG_PAGE_POISONING is not set # CONFIG_DEBUG_PAGE_REF is not set @@ -20886,7 +23021,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_ARCH_HAS_DEBUG_WX=y # CONFIG_DEBUG_WX is not set CONFIG_GENERIC_PTDUMP=y -@@ -7242,6 +8727,7 @@ CONFIG_SCHEDSTATS=y +@@ -7242,6 +8746,7 @@ CONFIG_SCHEDSTATS=y # end of Scheduler Debugging # CONFIG_DEBUG_TIMEKEEPING is not set @@ -20894,7 +23029,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # # Lock Debugging (spinlocks, mutexes, etc...) -@@ -7257,7 +8743,7 @@ CONFIG_LOCK_DEBUGGING_SUPPORT=y +@@ -7257,7 +8762,7 @@ CONFIG_LOCK_DEBUGGING_SUPPORT=y # CONFIG_DEBUG_LOCK_ALLOC is not set CONFIG_DEBUG_ATOMIC_SLEEP=y # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set @@ -20903,7 +23038,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_WW_MUTEX_SELFTEST is not set # CONFIG_SCF_TORTURE_TEST is not set # CONFIG_CSD_LOCK_WAIT_DEBUG is not set -@@ -7281,8 +8767,9 @@ CONFIG_DEBUG_LIST=y +@@ -7281,8 +8786,9 @@ CONFIG_DEBUG_LIST=y # # RCU Debugging # @@ -20914,7 +23049,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_RCU_REF_SCALE_TEST is not set CONFIG_RCU_CPU_STALL_TIMEOUT=60 CONFIG_RCU_EXP_CPU_STALL_TIMEOUT=0 -@@ -7298,7 +8785,6 @@ CONFIG_RCU_EXP_CPU_STALL_TIMEOUT=0 +@@ -7298,7 +8804,6 @@ CONFIG_RCU_EXP_CPU_STALL_TIMEOUT=0 CONFIG_NOP_TRACER=y CONFIG_HAVE_RETHOOK=y CONFIG_RETHOOK=y @@ -20922,7 +23057,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_RETVAL=y CONFIG_HAVE_DYNAMIC_FTRACE=y -@@ -7315,15 +8801,8 @@ CONFIG_GENERIC_TRACER=y +@@ -7315,15 +8820,8 @@ CONFIG_GENERIC_TRACER=y CONFIG_TRACING_SUPPORT=y CONFIG_FTRACE=y CONFIG_BOOTTIME_TRACING=y @@ -20939,7 +23074,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_SCHED_TRACER=y CONFIG_HWLAT_TRACER=y CONFIG_OSNOISE_TRACER=y -@@ -7336,21 +8815,17 @@ CONFIG_BRANCH_PROFILE_NONE=y +@@ -7336,21 +8834,17 @@ CONFIG_BRANCH_PROFILE_NONE=y CONFIG_BLK_DEV_IO_TRACE=y CONFIG_PROBE_EVENTS_BTF_ARGS=y CONFIG_KPROBE_EVENTS=y @@ -20961,7 +23096,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 # CONFIG_FTRACE_STARTUP_TEST is not set # CONFIG_RING_BUFFER_STARTUP_TEST is not set # CONFIG_RING_BUFFER_VALIDATE_TIME_DELTAS is not set -@@ -7358,7 +8833,37 @@ CONFIG_RING_BUFFER_BENCHMARK=m +@@ -7358,7 +8852,37 @@ CONFIG_RING_BUFFER_BENCHMARK=m # CONFIG_SYNTH_EVENT_GEN_TEST is not set # CONFIG_KPROBE_EVENT_GEN_TEST is not set # CONFIG_RV is not set @@ -21000,7 +23135,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_STRICT_DEVMEM=y CONFIG_IO_STRICT_DEVMEM=y -@@ -7376,7 +8881,47 @@ CONFIG_FUNCTION_ERROR_INJECTION=y +@@ -7376,7 +8900,47 @@ CONFIG_FUNCTION_ERROR_INJECTION=y # CONFIG_FAULT_INJECTION is not set CONFIG_ARCH_HAS_KCOV=y # CONFIG_KCOV is not set @@ -21049,7 +23184,7 @@ index 61f2b2f12589..c39bbc3701b3 100644 CONFIG_ARCH_USE_MEMTEST=y # CONFIG_MEMTEST is not set # end of Kernel Testing and Coverage -@@ -7388,9 +8933,3 @@ CONFIG_ARCH_USE_MEMTEST=y +@@ -7388,9 +8952,3 @@ CONFIG_ARCH_USE_MEMTEST=y # end of Kernel hacking # CONFIG_KWORKER_NUMA_AFFINITY is not set @@ -21596,6 +23731,18 @@ index 110752594228..2b1f98b7e9bf 100644 /* * This is a very specific barrier: it's currently only used in two places in * the kernel, both in the scheduler. See include/linux/spinlock.h for the two +diff --git a/arch/riscv/include/asm/compat.h b/arch/riscv/include/asm/compat.h +index 2ac955b51148..6b79287baecc 100644 +--- a/arch/riscv/include/asm/compat.h ++++ b/arch/riscv/include/asm/compat.h +@@ -9,7 +9,6 @@ + */ + #include + #include +-#include + #include + + static inline int is_compat_task(void) diff --git a/arch/riscv/include/asm/errata_list.h b/arch/riscv/include/asm/errata_list.h index d3f3c237adad..c7fd111e3a50 100644 --- a/arch/riscv/include/asm/errata_list.h @@ -21673,6 +23820,114 @@ index 42497d487a17..bbdc3c7ed6ca 100644 + ioremap_prot((addr), (size), _PAGE_IOREMAP_WC) + #endif /* _ASM_RISCV_IO_H */ +diff --git a/arch/riscv/include/asm/kvm_aia_aplic.h b/arch/riscv/include/asm/kvm_aia_aplic.h +deleted file mode 100644 +index 6dd1a4809ec1..000000000000 +--- a/arch/riscv/include/asm/kvm_aia_aplic.h ++++ /dev/null +@@ -1,58 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0-only */ +-/* +- * Copyright (C) 2021 Western Digital Corporation or its affiliates. +- * Copyright (C) 2022 Ventana Micro Systems Inc. +- */ +-#ifndef __KVM_RISCV_AIA_IMSIC_H +-#define __KVM_RISCV_AIA_IMSIC_H +- +-#include +- +-#define APLIC_MAX_IDC BIT(14) +-#define APLIC_MAX_SOURCE 1024 +- +-#define APLIC_DOMAINCFG 0x0000 +-#define APLIC_DOMAINCFG_RDONLY 0x80000000 +-#define APLIC_DOMAINCFG_IE BIT(8) +-#define APLIC_DOMAINCFG_DM BIT(2) +-#define APLIC_DOMAINCFG_BE BIT(0) +- +-#define APLIC_SOURCECFG_BASE 0x0004 +-#define APLIC_SOURCECFG_D BIT(10) +-#define APLIC_SOURCECFG_CHILDIDX_MASK 0x000003ff +-#define APLIC_SOURCECFG_SM_MASK 0x00000007 +-#define APLIC_SOURCECFG_SM_INACTIVE 0x0 +-#define APLIC_SOURCECFG_SM_DETACH 0x1 +-#define APLIC_SOURCECFG_SM_EDGE_RISE 0x4 +-#define APLIC_SOURCECFG_SM_EDGE_FALL 0x5 +-#define APLIC_SOURCECFG_SM_LEVEL_HIGH 0x6 +-#define APLIC_SOURCECFG_SM_LEVEL_LOW 0x7 +- +-#define APLIC_IRQBITS_PER_REG 32 +- +-#define APLIC_SETIP_BASE 0x1c00 +-#define APLIC_SETIPNUM 0x1cdc +- +-#define APLIC_CLRIP_BASE 0x1d00 +-#define APLIC_CLRIPNUM 0x1ddc +- +-#define APLIC_SETIE_BASE 0x1e00 +-#define APLIC_SETIENUM 0x1edc +- +-#define APLIC_CLRIE_BASE 0x1f00 +-#define APLIC_CLRIENUM 0x1fdc +- +-#define APLIC_SETIPNUM_LE 0x2000 +-#define APLIC_SETIPNUM_BE 0x2004 +- +-#define APLIC_GENMSI 0x3000 +- +-#define APLIC_TARGET_BASE 0x3004 +-#define APLIC_TARGET_HART_IDX_SHIFT 18 +-#define APLIC_TARGET_HART_IDX_MASK 0x3fff +-#define APLIC_TARGET_GUEST_IDX_SHIFT 12 +-#define APLIC_TARGET_GUEST_IDX_MASK 0x3f +-#define APLIC_TARGET_IPRIO_MASK 0xff +-#define APLIC_TARGET_EIID_MASK 0x7ff +- +-#endif +diff --git a/arch/riscv/include/asm/kvm_aia_imsic.h b/arch/riscv/include/asm/kvm_aia_imsic.h +deleted file mode 100644 +index da5881d2bde0..000000000000 +--- a/arch/riscv/include/asm/kvm_aia_imsic.h ++++ /dev/null +@@ -1,38 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0-only */ +-/* +- * Copyright (C) 2021 Western Digital Corporation or its affiliates. +- * Copyright (C) 2022 Ventana Micro Systems Inc. +- */ +-#ifndef __KVM_RISCV_AIA_IMSIC_H +-#define __KVM_RISCV_AIA_IMSIC_H +- +-#include +-#include +- +-#define IMSIC_MMIO_PAGE_SHIFT 12 +-#define IMSIC_MMIO_PAGE_SZ (1UL << IMSIC_MMIO_PAGE_SHIFT) +-#define IMSIC_MMIO_PAGE_LE 0x00 +-#define IMSIC_MMIO_PAGE_BE 0x04 +- +-#define IMSIC_MIN_ID 63 +-#define IMSIC_MAX_ID 2048 +- +-#define IMSIC_EIDELIVERY 0x70 +- +-#define IMSIC_EITHRESHOLD 0x72 +- +-#define IMSIC_EIP0 0x80 +-#define IMSIC_EIP63 0xbf +-#define IMSIC_EIPx_BITS 32 +- +-#define IMSIC_EIE0 0xc0 +-#define IMSIC_EIE63 0xff +-#define IMSIC_EIEx_BITS 32 +- +-#define IMSIC_FIRST IMSIC_EIDELIVERY +-#define IMSIC_LAST IMSIC_EIE63 +- +-#define IMSIC_MMIO_SETIPNUM_LE 0x00 +-#define IMSIC_MMIO_SETIPNUM_BE 0x04 +- +-#endif diff --git a/arch/riscv/include/asm/membarrier.h b/arch/riscv/include/asm/membarrier.h index 6c016ebb5020..47b240d0d596 100644 --- a/arch/riscv/include/asm/membarrier.h @@ -22250,7 +24505,7 @@ index 3c89b8ec69c4..239509367e42 100644 +arch_initcall(sbi_system_suspend_init); +#endif /* CONFIG_RISCV_SBI */ diff --git a/arch/riscv/kernel/vector.c b/arch/riscv/kernel/vector.c -index 8d92fb6c522c..2c1f6c87d955 100644 +index 81886fc36ed6..c05ac070379f 100644 --- a/arch/riscv/kernel/vector.c +++ b/arch/riscv/kernel/vector.c @@ -83,7 +83,8 @@ static bool insn_is_vector(u32 insn_buf) @@ -22263,6 +24518,143 @@ index 8d92fb6c522c..2c1f6c87d955 100644 datap = kzalloc(riscv_v_vsize, GFP_KERNEL); if (!datap) return -ENOMEM; +diff --git a/arch/riscv/kvm/aia.c b/arch/riscv/kvm/aia.c +index 74bb27440527..29f0d1e299b8 100644 +--- a/arch/riscv/kvm/aia.c ++++ b/arch/riscv/kvm/aia.c +@@ -10,12 +10,12 @@ + #include + #include + #include ++#include + #include + #include + #include + #include + #include +-#include + + struct aia_hgei_control { + raw_spinlock_t lock; +@@ -394,6 +394,8 @@ int kvm_riscv_aia_alloc_hgei(int cpu, struct kvm_vcpu *owner, + { + int ret = -ENOENT; + unsigned long flags; ++ const struct imsic_global_config *gc; ++ const struct imsic_local_config *lc; + struct aia_hgei_control *hgctrl = per_cpu_ptr(&aia_hgei, cpu); + + if (!kvm_riscv_aia_available() || !hgctrl) +@@ -409,11 +411,14 @@ int kvm_riscv_aia_alloc_hgei(int cpu, struct kvm_vcpu *owner, + + raw_spin_unlock_irqrestore(&hgctrl->lock, flags); + +- /* TODO: To be updated later by AIA IMSIC HW guest file support */ +- if (hgei_va) +- *hgei_va = NULL; +- if (hgei_pa) +- *hgei_pa = 0; ++ gc = imsic_get_global_config(); ++ lc = (gc) ? per_cpu_ptr(gc->local, cpu) : NULL; ++ if (lc && ret > 0) { ++ if (hgei_va) ++ *hgei_va = lc->msi_va + (ret * IMSIC_MMIO_PAGE_SZ); ++ if (hgei_pa) ++ *hgei_pa = lc->msi_pa + (ret * IMSIC_MMIO_PAGE_SZ); ++ } + + return ret; + } +@@ -600,9 +605,11 @@ void kvm_riscv_aia_disable(void) + int kvm_riscv_aia_init(void) + { + int rc; ++ const struct imsic_global_config *gc; + + if (!riscv_isa_extension_available(NULL, SxAIA)) + return -ENODEV; ++ gc = imsic_get_global_config(); + + /* Figure-out number of bits in HGEIE */ + csr_write(CSR_HGEIE, -1UL); +@@ -614,17 +621,17 @@ int kvm_riscv_aia_init(void) + /* + * Number of usable HGEI lines should be minimum of per-HART + * IMSIC guest files and number of bits in HGEIE +- * +- * TODO: To be updated later by AIA IMSIC HW guest file support + */ +- kvm_riscv_aia_nr_hgei = 0; ++ if (gc) ++ kvm_riscv_aia_nr_hgei = min((ulong)kvm_riscv_aia_nr_hgei, ++ BIT(gc->guest_index_bits) - 1); ++ else ++ kvm_riscv_aia_nr_hgei = 0; + +- /* +- * Find number of guest MSI IDs +- * +- * TODO: To be updated later by AIA IMSIC HW guest file support +- */ ++ /* Find number of guest MSI IDs */ + kvm_riscv_aia_max_ids = IMSIC_MAX_ID; ++ if (gc && kvm_riscv_aia_nr_hgei) ++ kvm_riscv_aia_max_ids = gc->nr_guest_ids + 1; + + /* Initialize guest external interrupt line management */ + rc = aia_hgei_init(); +diff --git a/arch/riscv/kvm/aia_aplic.c b/arch/riscv/kvm/aia_aplic.c +index 9d5b04c971c4..f59d1c0c8c43 100644 +--- a/arch/riscv/kvm/aia_aplic.c ++++ b/arch/riscv/kvm/aia_aplic.c +@@ -7,12 +7,12 @@ + * Anup Patel + */ + ++#include + #include + #include + #include + #include + #include +-#include + + struct aplic_irq { + raw_spinlock_t lock; +diff --git a/arch/riscv/kvm/aia_device.c b/arch/riscv/kvm/aia_device.c +index 5cd407c6a8e4..39cd26af5a69 100644 +--- a/arch/riscv/kvm/aia_device.c ++++ b/arch/riscv/kvm/aia_device.c +@@ -8,9 +8,9 @@ + */ + + #include ++#include + #include + #include +-#include + + static void unlock_vcpus(struct kvm *kvm, int vcpu_lock_idx) + { +diff --git a/arch/riscv/kvm/aia_imsic.c b/arch/riscv/kvm/aia_imsic.c +index c1585444f856..a8085cd8215e 100644 +--- a/arch/riscv/kvm/aia_imsic.c ++++ b/arch/riscv/kvm/aia_imsic.c +@@ -9,13 +9,13 @@ + + #include + #include ++#include + #include + #include + #include + #include + #include + #include +-#include + + #define IMSIC_MAX_EIX (IMSIC_MAX_ID / BITS_PER_TYPE(u64)) + diff --git a/arch/riscv/mm/dma-noncoherent.c b/arch/riscv/mm/dma-noncoherent.c index a77342eb3489..32031a7d96d4 100644 --- a/arch/riscv/mm/dma-noncoherent.c @@ -22675,10 +25067,18 @@ index 74fa2055868b..6a935100e1ae 100644 if (io.irq) io.irq_setup = ipmi_std_irq_setup; diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig -index c30099866174..c8b005b647dd 100644 +index c30099866174..83976f7b9755 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig -@@ -501,6 +501,7 @@ source "drivers/clk/visconti/Kconfig" +@@ -490,6 +490,7 @@ source "drivers/clk/rockchip/Kconfig" + source "drivers/clk/samsung/Kconfig" + source "drivers/clk/sifive/Kconfig" + source "drivers/clk/socfpga/Kconfig" ++source "drivers/clk/spacemit/Kconfig" + source "drivers/clk/sprd/Kconfig" + source "drivers/clk/starfive/Kconfig" + source "drivers/clk/sunxi/Kconfig" +@@ -501,6 +502,7 @@ source "drivers/clk/visconti/Kconfig" source "drivers/clk/x86/Kconfig" source "drivers/clk/xilinx/Kconfig" source "drivers/clk/zynqmp/Kconfig" @@ -22687,10 +25087,18 @@ index c30099866174..c8b005b647dd 100644 # Kunit test cases config CLK_KUNIT_TEST diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile -index 18969cbd4bb1..adcbb9f95baa 100644 +index 18969cbd4bb1..1e4e2e292f5d 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile -@@ -124,6 +124,7 @@ obj-$(CONFIG_ARCH_STM32) += stm32/ +@@ -117,6 +117,7 @@ obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/ + obj-$(CONFIG_COMMON_CLK_SAMSUNG) += samsung/ + obj-$(CONFIG_CLK_SIFIVE) += sifive/ + obj-y += socfpga/ ++obj-$(CONFIG_SOC_SPACEMIT) += spacemit/ + obj-$(CONFIG_PLAT_SPEAR) += spear/ + obj-y += sprd/ + obj-$(CONFIG_ARCH_STI) += st/ +@@ -124,6 +125,7 @@ obj-$(CONFIG_ARCH_STM32) += stm32/ obj-y += starfive/ obj-$(CONFIG_ARCH_SUNXI) += sunxi/ obj-y += sunxi-ng/ @@ -22698,7 +25106,7 @@ index 18969cbd4bb1..adcbb9f95baa 100644 obj-$(CONFIG_ARCH_TEGRA) += tegra/ obj-y += ti/ obj-$(CONFIG_CLK_UNIPHIER) += uniphier/ -@@ -136,3 +137,4 @@ endif +@@ -136,3 +138,4 @@ endif obj-y += xilinx/ obj-$(CONFIG_ARCH_ZYNQ) += zynq/ obj-$(CONFIG_COMMON_CLK_ZYNQMP) += zynqmp/ @@ -22714,10 +25122,10 @@ index 000000000000..55997fc07b5b +obj-$(CONFIG_ARCH_SOPHGO) += clk-mango.o diff --git a/drivers/clk/sophgo/clk-dummy.c b/drivers/clk/sophgo/clk-dummy.c new file mode 100644 -index 000000000000..99af0e6dae6a +index 000000000000..ddbbcf55b964 --- /dev/null +++ b/drivers/clk/sophgo/clk-dummy.c -@@ -0,0 +1,600 @@ +@@ -0,0 +1,594 @@ +/* + * Copyright (c) 2022 SOPHGO + * @@ -22765,13 +25173,11 @@ index 000000000000..99af0e6dae6a + struct of_phandle_args clkspec; + int rc, index = 0; + u32 rate; -+ struct property *prop; -+ const __be32 *cur; + struct clk *clk; + + node = of_find_node_by_name(NULL, "default_rates"); + -+ of_property_for_each_u32 (node, "clock-rates", prop, cur, rate) { ++ of_property_for_each_u32 (node, "clock-rates", rate) { + if (rate) { + rc = of_parse_phandle_with_args(node, "clocks", + "#clock-cells", index, &clkspec); @@ -22820,12 +25226,10 @@ index 000000000000..99af0e6dae6a + struct of_phandle_args clkspec; + int rc, index = 0; + u32 rate; -+ struct property *prop; -+ const __be32 *cur; + + node = of_find_node_by_name(NULL, "default_rates"); + -+ of_property_for_each_u32 (node, "clock-rates", prop, cur, rate) { ++ of_property_for_each_u32 (node, "clock-rates", rate) { + if (rate) { + rc = of_parse_phandle_with_args(node, "clocks", + "#clock-cells", index, &clkspec); @@ -22948,13 +25352,11 @@ index 000000000000..99af0e6dae6a +int dm_set_default_clk_rates(struct device_node *node) +{ + struct of_phandle_args clkspec; -+ struct property *prop; -+ const __be32 *cur; + int rc, index = 0; + struct clk *clk; + u32 rate; + -+ of_property_for_each_u32 (node, "clock-rates", prop, cur, rate) { ++ of_property_for_each_u32 (node, "clock-rates", rate) { + if (rate) { + rc = of_parse_phandle_with_args(node, "clocks", + "#clock-cells", index, &clkspec); @@ -24303,10 +26705,10 @@ index 000000000000..7f386092f764 +CLK_OF_DECLARE(dm_mango_clk_default_rate, "mango, dm-clk-default-rates", mango_clk_init); diff --git a/drivers/clk/sophgo/clk.c b/drivers/clk/sophgo/clk.c new file mode 100644 -index 000000000000..4d3893ace2b9 +index 000000000000..c77f2f631a8c --- /dev/null +++ b/drivers/clk/sophgo/clk.c -@@ -0,0 +1,883 @@ +@@ -0,0 +1,881 @@ +/* + * Copyright (c) 2022 SOPHGO + * @@ -24820,13 +27222,11 @@ index 000000000000..4d3893ace2b9 +int set_default_clk_rates(struct device_node *node) +{ + struct of_phandle_args clkspec; -+ struct property *prop; -+ const __be32 *cur; + int rc, index = 0; + struct clk *clk; + u32 rate; + -+ of_property_for_each_u32 (node, "clock-rates", prop, cur, rate) { ++ of_property_for_each_u32 (node, "clock-rates", rate) { + if (rate) { + rc = of_parse_phandle_with_args(node, "clocks", + "#clock-cells", index, &clkspec); @@ -25348,6 +27748,4324 @@ index 000000000000..81e9f9eb1b20 +(struct device_node *node, struct mango_clk_data *clk_data, const char *name); +int dm_set_default_clk_rates(struct device_node *node); +#endif +diff --git a/drivers/clk/spacemit/Kconfig b/drivers/clk/spacemit/Kconfig +new file mode 100644 +index 000000000000..fe905e7cf2d3 +--- /dev/null ++++ b/drivers/clk/spacemit/Kconfig +@@ -0,0 +1,9 @@ ++# SPDX-License-Identifier: GPL-2.0 ++# common clock support for SPACEMIT SoC family. ++ ++config SPACEMIT_K1X_CCU ++ tristate "Clock support for Spacemit k1x SoCs" ++ depends on SOC_SPACEMIT_K1X ++ help ++ Build the driver for Spacemit K1x Clock Driver. ++ +diff --git a/drivers/clk/spacemit/Makefile b/drivers/clk/spacemit/Makefile +new file mode 100644 +index 000000000000..6bfb749658d7 +--- /dev/null ++++ b/drivers/clk/spacemit/Makefile +@@ -0,0 +1,11 @@ ++# SPDX-License-Identifier: GPL-2.0 ++# ++# Spacemit Clock specific Makefile ++# ++ ++obj-$(CONFIG_SPACEMIT_K1X_CCU) += ccu-spacemit-k1x.o ++obj-$(CONFIG_SPACEMIT_K1X_CCU) += ccu_mix.o ++obj-$(CONFIG_SPACEMIT_K1X_CCU) += ccu_pll.o ++obj-$(CONFIG_SPACEMIT_K1X_CCU) += ccu_dpll.o ++obj-$(CONFIG_SPACEMIT_K1X_CCU) += ccu_ddn.o ++obj-$(CONFIG_SPACEMIT_K1X_CCU) += ccu_ddr.o +diff --git a/drivers/clk/spacemit/ccu-spacemit-k1x.c b/drivers/clk/spacemit/ccu-spacemit-k1x.c +new file mode 100644 +index 000000000000..e4b176b39247 +--- /dev/null ++++ b/drivers/clk/spacemit/ccu-spacemit-k1x.c +@@ -0,0 +1,2123 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Spacemit k1x clock controller driver ++ * ++ * Copyright (c) 2023, spacemit Corporation. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "ccu-spacemit-k1x.h" ++#include "ccu_mix.h" ++#include "ccu_pll.h" ++#include "ccu_ddn.h" ++#include "ccu_dpll.h" ++#include "ccu_ddr.h" ++ ++DEFINE_SPINLOCK(g_cru_lock); ++ ++/* APBS register offset */ ++/* pll1 */ ++#define APB_SPARE1_REG 0x100 ++#define APB_SPARE2_REG 0x104 ++#define APB_SPARE3_REG 0x108 ++/* pll2 */ ++#define APB_SPARE7_REG 0x118 ++#define APB_SPARE8_REG 0x11c ++#define APB_SPARE9_REG 0x120 ++/* pll3 */ ++#define APB_SPARE10_REG 0x124 ++#define APB_SPARE11_REG 0x128 ++#define APB_SPARE12_REG 0x12c ++/* end of APBS register offset */ ++ ++/* APBC register offset */ ++#define APBC_UART1_CLK_RST 0x0 ++#define APBC_UART2_CLK_RST 0x4 ++#define APBC_GPIO_CLK_RST 0x8 ++#define APBC_PWM0_CLK_RST 0xc ++#define APBC_PWM1_CLK_RST 0x10 ++#define APBC_PWM2_CLK_RST 0x14 ++#define APBC_PWM3_CLK_RST 0x18 ++#define APBC_TWSI8_CLK_RST 0x20 ++#define APBC_UART3_CLK_RST 0x24 ++#define APBC_RTC_CLK_RST 0x28 ++#define APBC_TWSI0_CLK_RST 0x2c ++#define APBC_TWSI1_CLK_RST 0x30 ++#define APBC_TIMERS1_CLK_RST 0x34 ++#define APBC_TWSI2_CLK_RST 0x38 ++#define APBC_AIB_CLK_RST 0x3c ++#define APBC_TWSI4_CLK_RST 0x40 ++#define APBC_TIMERS2_CLK_RST 0x44 ++#define APBC_ONEWIRE_CLK_RST 0x48 ++#define APBC_TWSI5_CLK_RST 0x4c ++#define APBC_DRO_CLK_RST 0x58 ++#define APBC_IR_CLK_RST 0x5c ++#define APBC_TWSI6_CLK_RST 0x60 ++#define APBC_COUNTER_CLK_SEL 0x64 ++ ++#define APBC_TWSI7_CLK_RST 0x68 ++#define APBC_TSEN_CLK_RST 0x6c ++ ++#define APBC_UART4_CLK_RST 0x70 ++#define APBC_UART5_CLK_RST 0x74 ++#define APBC_UART6_CLK_RST 0x78 ++#define APBC_SSP3_CLK_RST 0x7c ++ ++#define APBC_SSPA0_CLK_RST 0x80 ++#define APBC_SSPA1_CLK_RST 0x84 ++ ++#define APBC_IPC_AP2AUD_CLK_RST 0x90 ++#define APBC_UART7_CLK_RST 0x94 ++#define APBC_UART8_CLK_RST 0x98 ++#define APBC_UART9_CLK_RST 0x9c ++ ++#define APBC_CAN0_CLK_RST 0xa0 ++#define APBC_PWM4_CLK_RST 0xa8 ++#define APBC_PWM5_CLK_RST 0xac ++#define APBC_PWM6_CLK_RST 0xb0 ++#define APBC_PWM7_CLK_RST 0xb4 ++#define APBC_PWM8_CLK_RST 0xb8 ++#define APBC_PWM9_CLK_RST 0xbc ++#define APBC_PWM10_CLK_RST 0xc0 ++#define APBC_PWM11_CLK_RST 0xc4 ++#define APBC_PWM12_CLK_RST 0xc8 ++#define APBC_PWM13_CLK_RST 0xcc ++#define APBC_PWM14_CLK_RST 0xd0 ++#define APBC_PWM15_CLK_RST 0xd4 ++#define APBC_PWM16_CLK_RST 0xd8 ++#define APBC_PWM17_CLK_RST 0xdc ++#define APBC_PWM18_CLK_RST 0xe0 ++#define APBC_PWM19_CLK_RST 0xe4 ++/* end of APBC register offset */ ++ ++/* MPMU register offset */ ++#define MPMU_POSR 0x10 ++#define POSR_PLL1_LOCK BIT(27) ++#define POSR_PLL2_LOCK BIT(28) ++#define POSR_PLL3_LOCK BIT(29) ++ ++#define MPMU_VRCR 0x18 ++#define MPMU_VRCR_REQ_EN0 BIT(0) ++#define MPMU_VRCR_REQ_EN2 BIT(2) ++#define MPMU_VRCR_REQ_POL2 BIT(6) ++#define MPMU_VRCR_VCXO_OUT_REQ_EN2 BIT(14) ++ ++#define MPMU_WDTPCR 0x200 ++#define MPMU_RIPCCR 0x210 ++#define MPMU_ACGR 0x1024 ++#define MPMU_SUCCR 0x14 ++#define MPMU_ISCCR 0x44 ++#define MPMU_SUCCR_1 0x10b0 ++#define MPMU_APBCSCR 0x1050 ++ ++/* end of MPMU register offset */ ++ ++/* APMU register offset */ ++#define APMU_JPG_CLK_RES_CTRL 0x20 ++#define APMU_CSI_CCIC2_CLK_RES_CTRL 0x24 ++#define APMU_ISP_CLK_RES_CTRL 0x38 ++#define APMU_LCD_CLK_RES_CTRL1 0x44 ++#define APMU_LCD_SPI_CLK_RES_CTRL 0x48 ++#define APMU_LCD_CLK_RES_CTRL2 0x4c ++#define APMU_CCIC_CLK_RES_CTRL 0x50 ++#define APMU_SDH0_CLK_RES_CTRL 0x54 ++#define APMU_SDH1_CLK_RES_CTRL 0x58 ++#define APMU_USB_CLK_RES_CTRL 0x5c ++#define APMU_QSPI_CLK_RES_CTRL 0x60 ++#define APMU_USB_CLK_RES_CTRL 0x5c ++#define APMU_DMA_CLK_RES_CTRL 0x64 ++#define APMU_AES_CLK_RES_CTRL 0x68 ++#define APMU_VPU_CLK_RES_CTRL 0xa4 ++#define APMU_GPU_CLK_RES_CTRL 0xcc ++#define APMU_SDH2_CLK_RES_CTRL 0xe0 ++#define APMU_PMUA_MC_CTRL 0xe8 ++#define APMU_PMU_CC2_AP 0x100 ++#define APMU_PMUA_EM_CLK_RES_CTRL 0x104 ++ ++#define APMU_AUDIO_CLK_RES_CTRL 0x14c ++#define APMU_HDMI_CLK_RES_CTRL 0x1B8 ++#define APMU_CCI550_CLK_CTRL 0x300 ++#define APMU_ACLK_CLK_CTRL 0x388 ++#define APMU_CPU_C0_CLK_CTRL 0x38C ++#define APMU_CPU_C1_CLK_CTRL 0x390 ++ ++#define APMU_PCIE_CLK_RES_CTRL_0 0x3cc ++#define APMU_PCIE_CLK_RES_CTRL_1 0x3d4 ++#define APMU_PCIE_CLK_RES_CTRL_2 0x3dc ++ ++#define APMU_EMAC0_CLK_RES_CTRL 0x3e4 ++#define APMU_EMAC1_CLK_RES_CTRL 0x3ec ++ ++#define APMU_DFC_AP 0x180 ++#define APMU_DFC_STATUS 0x188 ++ ++#define APMU_DFC_LEVEL0 0x190 ++#define APMU_DFC_LEVEL1 0x194 ++#define APMU_DFC_LEVEL2 0x198 ++#define APMU_DFC_LEVEL3 0x19c ++#define APMU_DFC_LEVEL4 0x1a0 ++#define APMU_DFC_LEVEL5 0x1a4 ++#define APMU_DFC_LEVEL6 0x1a8 ++#define APMU_DFC_LEVEL7 0x1ac ++ ++#define APMU_DPLL1_CLK_CTRL1 0x39c ++#define APMU_DPLL1_CLK_CTRL2 0x3a0 ++#define APMU_DPLL2_CLK_CTRL1 0x3a8 ++#define APMU_DPLL2_CLK_CTRL2 0x3ac ++/* end of APMU register offset */ ++ ++/* APBC2 register offset */ ++#define APBC2_UART1_CLK_RST 0x00 ++#define APBC2_SSP2_CLK_RST 0x04 ++#define APBC2_TWSI3_CLK_RST 0x08 ++#define APBC2_RTC_CLK_RST 0x0c ++#define APBC2_TIMERS0_CLK_RST 0x10 ++#define APBC2_KPC_CLK_RST 0x14 ++#define APBC2_GPIO_CLK_RST 0x1c ++/* end of APBC2 register offset */ ++ ++/* RCPU register offset */ ++#define RCPU_HDMI_CLK_RST 0x2044 ++#define RCPU_CAN_CLK_RST 0x4c ++#define RCPU_I2C0_CLK_RST 0x30 ++ ++#define RCPU_SSP0_CLK_RST 0x28 ++#define RCPU_IR_CLK_RST 0x48 ++#define RCPU_UART0_CLK_RST 0xd8 ++#define RCPU_UART1_CLK_RST 0x3c ++/* end of RCPU register offset */ ++ ++/* RCPU2 register offset */ ++#define RCPU2_PWM0_CLK_RST 0x00 ++#define RCPU2_PWM1_CLK_RST 0x04 ++#define RCPU2_PWM2_CLK_RST 0x08 ++#define RCPU2_PWM3_CLK_RST 0x0c ++#define RCPU2_PWM4_CLK_RST 0x10 ++#define RCPU2_PWM5_CLK_RST 0x14 ++#define RCPU2_PWM6_CLK_RST 0x18 ++#define RCPU2_PWM7_CLK_RST 0x1c ++#define RCPU2_PWM8_CLK_RST 0x20 ++#define RCPU2_PWM9_CLK_RST 0x24 ++/* end of RCPU2 register offset */ ++ ++struct spacemit_k1x_clk k1x_clock_controller; ++ ++static const struct ccu_pll_rate_tbl pll2_rate_tbl[] = { ++ PLL_RATE(3000000000UL, 0x66, 0xdd, 0x50, 0x00, 0x3f, 0xe00000), ++ PLL_RATE(3200000000UL, 0x67, 0xdd, 0x50, 0x00, 0x43, 0xeaaaab), ++ PLL_RATE(2457600000UL, 0x64, 0xdd, 0x50, 0x00, 0x33, 0x0ccccd), ++ PLL_RATE(2800000000UL, 0x66, 0xdd, 0x50, 0x00, 0x3a, 0x155555), ++}; ++ ++static const struct ccu_pll_rate_tbl pll3_rate_tbl[] = { ++ PLL_RATE(1600000000UL, 0x61, 0xcd, 0x50, 0x00, 0x43, 0xeaaaab), ++ PLL_RATE(1800000000UL, 0x61, 0xcd, 0x50, 0x00, 0x4b, 0x000000), ++ PLL_RATE(2000000000UL, 0x62, 0xdd, 0x50, 0x00, 0x2a, 0xeaaaab), ++ PLL_RATE(3000000000UL, 0x66, 0xdd, 0x50, 0x00, 0x3f, 0xe00000), ++ PLL_RATE(3200000000UL, 0x67, 0xdd, 0x50, 0x00, 0x43, 0xeaaaab), ++ PLL_RATE(2457600000UL, 0x64, 0xdd, 0x50, 0x00, 0x33, 0x0ccccd), ++}; ++ ++static SPACEMIT_CCU_PLL(pll2, "pll2", &pll2_rate_tbl, ++ ARRAY_SIZE(pll2_rate_tbl), ++ BASE_TYPE_APBS, APB_SPARE7_REG, APB_SPARE8_REG, APB_SPARE9_REG, ++ MPMU_POSR, POSR_PLL2_LOCK, 1, ++ CLK_IGNORE_UNUSED); ++ ++static SPACEMIT_CCU_PLL(pll3, "pll3", &pll3_rate_tbl, ++ ARRAY_SIZE(pll3_rate_tbl), ++ BASE_TYPE_APBS, APB_SPARE10_REG, APB_SPARE11_REG, APB_SPARE12_REG, ++ MPMU_POSR, POSR_PLL3_LOCK, 1, ++ CLK_IGNORE_UNUSED); ++ ++/* pll1 */ ++static SPACEMIT_CCU_GATE_FACTOR(pll1_d2, "pll1_d2", "pll1_2457p6_vco", ++ BASE_TYPE_APBS, APB_SPARE2_REG, ++ BIT(1), BIT(1), 0x0, ++ 2, 1, CLK_IGNORE_UNUSED); ++ ++static SPACEMIT_CCU_GATE_FACTOR(pll1_d3, "pll1_d3", "pll1_2457p6_vco", ++ BASE_TYPE_APBS, APB_SPARE2_REG, ++ BIT(2), BIT(2), 0x0, ++ 3, 1, CLK_IGNORE_UNUSED); ++ ++static SPACEMIT_CCU_GATE_FACTOR(pll1_d4, "pll1_d4", "pll1_2457p6_vco", ++ BASE_TYPE_APBS, APB_SPARE2_REG, ++ BIT(3), BIT(3), 0x0, ++ 4, 1, CLK_IGNORE_UNUSED); ++ ++static SPACEMIT_CCU_GATE_FACTOR(pll1_d5, "pll1_d5", "pll1_2457p6_vco", ++ BASE_TYPE_APBS, APB_SPARE2_REG, ++ BIT(4), BIT(4), 0x0, ++ 5, 1, CLK_IGNORE_UNUSED); ++ ++static SPACEMIT_CCU_GATE_FACTOR(pll1_d6, "pll1_d6", "pll1_2457p6_vco", ++ BASE_TYPE_APBS, APB_SPARE2_REG, ++ BIT(5), BIT(5), 0x0, ++ 6, 1, CLK_IGNORE_UNUSED); ++ ++static SPACEMIT_CCU_GATE_FACTOR(pll1_d7, "pll1_d7", "pll1_2457p6_vco", ++ BASE_TYPE_APBS, APB_SPARE2_REG, ++ BIT(6), BIT(6), 0x0, ++ 7, 1, CLK_IGNORE_UNUSED); ++ ++static SPACEMIT_CCU_GATE_FACTOR(pll1_d8, "pll1_d8", "pll1_2457p6_vco", ++ BASE_TYPE_APBS, APB_SPARE2_REG, ++ BIT(7), BIT(7), 0x0, ++ 8, 1, CLK_IGNORE_UNUSED); ++ ++static SPACEMIT_CCU_GATE_FACTOR(pll1_d11_223p4, "pll1_d11_223p4", ++ "pll1_2457p6_vco", ++ BASE_TYPE_APBS, APB_SPARE2_REG, ++ BIT(15), BIT(15), 0x0, ++ 11, 1, CLK_IGNORE_UNUSED); ++ ++static SPACEMIT_CCU_GATE_FACTOR(pll1_d13_189, "pll1_d13_189", ++ "pll1_2457p6_vco", ++ BASE_TYPE_APBS, APB_SPARE2_REG, ++ BIT(16), BIT(16), 0x0, ++ 13, 1, CLK_IGNORE_UNUSED); ++ ++static SPACEMIT_CCU_GATE_FACTOR(pll1_d23_106p8, "pll1_d23_106p8", ++ "pll1_2457p6_vco", ++ BASE_TYPE_APBS, APB_SPARE2_REG, ++ BIT(20), BIT(20), 0x0, ++ 23, 1, CLK_IGNORE_UNUSED); ++ ++static SPACEMIT_CCU_GATE_FACTOR(pll1_d64_38p4, "pll1_d64_38p4", ++ "pll1_2457p6_vco", ++ BASE_TYPE_APBS, APB_SPARE2_REG, ++ BIT(0), BIT(0), 0x0, ++ 64, 1, CLK_IGNORE_UNUSED); ++ ++static SPACEMIT_CCU_GATE_FACTOR(pll1_aud_245p7, "pll1_aud_245p7", ++ "pll1_2457p6_vco", ++ BASE_TYPE_APBS, APB_SPARE2_REG, ++ BIT(10), BIT(10), 0x0, ++ 10, 1, CLK_IGNORE_UNUSED); ++ ++static SPACEMIT_CCU_GATE_FACTOR(pll1_aud_24p5, "pll1_aud_24p5", ++ "pll1_2457p6_vco", ++ BASE_TYPE_APBS, APB_SPARE2_REG, ++ BIT(11), BIT(11), 0x0, ++ 100, 1, CLK_IGNORE_UNUSED); ++ ++/* pll2 */ ++static SPACEMIT_CCU_GATE_FACTOR(pll2_d1, "pll2_d1", "pll2", ++ BASE_TYPE_APBS, APB_SPARE8_REG, ++ BIT(0), BIT(0), 0x0, ++ 1, 1, CLK_IGNORE_UNUSED); ++ ++static SPACEMIT_CCU_GATE_FACTOR(pll2_d2, "pll2_d2", "pll2", ++ BASE_TYPE_APBS, APB_SPARE8_REG, ++ BIT(1), BIT(1), 0x0, ++ 2, 1, CLK_IGNORE_UNUSED); ++ ++static SPACEMIT_CCU_GATE_FACTOR(pll2_d3, "pll2_d3", "pll2", ++ BASE_TYPE_APBS, APB_SPARE8_REG, ++ BIT(2), BIT(2), 0x0, ++ 3, 1, CLK_IGNORE_UNUSED); ++ ++static SPACEMIT_CCU_GATE_FACTOR(pll2_d4, "pll2_d4", "pll2", ++ BASE_TYPE_APBS, APB_SPARE8_REG, ++ BIT(3), BIT(3), 0x0, ++ 4, 1, CLK_IGNORE_UNUSED); ++ ++static SPACEMIT_CCU_GATE_FACTOR(pll2_d5, "pll2_d5", "pll2", ++ BASE_TYPE_APBS, APB_SPARE8_REG, ++ BIT(4), BIT(4), 0x0, ++ 5, 1, CLK_IGNORE_UNUSED); ++ ++static SPACEMIT_CCU_GATE_FACTOR(pll2_d6, "pll2_d6", "pll2", ++ BASE_TYPE_APBS, APB_SPARE8_REG, ++ BIT(5), BIT(5), 0x0, ++ 6, 1, CLK_IGNORE_UNUSED); ++ ++static SPACEMIT_CCU_GATE_FACTOR(pll2_d7, "pll2_d7", "pll2", ++ BASE_TYPE_APBS, APB_SPARE8_REG, ++ BIT(6), BIT(6), 0x0, ++ 7, 1, CLK_IGNORE_UNUSED); ++ ++static SPACEMIT_CCU_GATE_FACTOR(pll2_d8, "pll2_d8", "pll2", ++ BASE_TYPE_APBS, APB_SPARE8_REG, ++ BIT(7), BIT(7), 0x0, ++ 8, 1, CLK_IGNORE_UNUSED); ++ ++/* pll3 */ ++static SPACEMIT_CCU_GATE_FACTOR(pll3_d1, "pll3_d1", "pll3", ++ BASE_TYPE_APBS, APB_SPARE11_REG, ++ BIT(0), BIT(0), 0x0, ++ 1, 1, CLK_IGNORE_UNUSED); ++ ++static SPACEMIT_CCU_GATE_FACTOR(pll3_d2, "pll3_d2", "pll3", ++ BASE_TYPE_APBS, APB_SPARE11_REG, ++ BIT(1), BIT(1), 0x0, ++ 2, 1, CLK_IGNORE_UNUSED); ++ ++static SPACEMIT_CCU_GATE_FACTOR(pll3_d3, "pll3_d3", "pll3", ++ BASE_TYPE_APBS, APB_SPARE11_REG, ++ BIT(2), BIT(2), 0x0, ++ 3, 1, CLK_IGNORE_UNUSED); ++ ++static SPACEMIT_CCU_GATE_FACTOR(pll3_d4, "pll3_d4", "pll3", ++ BASE_TYPE_APBS, APB_SPARE11_REG, ++ BIT(3), BIT(3), 0x0, ++ 4, 1, CLK_IGNORE_UNUSED); ++ ++static SPACEMIT_CCU_GATE_FACTOR(pll3_d5, "pll3_d5", "pll3", ++ BASE_TYPE_APBS, APB_SPARE11_REG, ++ BIT(4), BIT(4), 0x0, ++ 5, 1, CLK_IGNORE_UNUSED); ++ ++static SPACEMIT_CCU_GATE_FACTOR(pll3_d6, "pll3_d6", "pll3", ++ BASE_TYPE_APBS, APB_SPARE11_REG, ++ BIT(5), BIT(5), 0x0, ++ 6, 1, CLK_IGNORE_UNUSED); ++ ++static SPACEMIT_CCU_GATE_FACTOR(pll3_d7, "pll3_d7", "pll3", ++ BASE_TYPE_APBS, APB_SPARE11_REG, ++ BIT(6), BIT(6), 0x0, ++ 7, 1, CLK_IGNORE_UNUSED); ++ ++static SPACEMIT_CCU_GATE_FACTOR(pll3_d8, "pll3_d8", "pll3", ++ BASE_TYPE_APBS, APB_SPARE11_REG, ++ BIT(7), BIT(7), 0x0, ++ 8, 1, CLK_IGNORE_UNUSED); ++ ++/* pll3_div */ ++static SPACEMIT_CCU_FACTOR(pll3_80, "pll3_80", "pll3_d8", ++ 5, 1); ++ ++static SPACEMIT_CCU_FACTOR(pll3_40, "pll3_40", "pll3_d8", ++ 10, 1); ++ ++static SPACEMIT_CCU_FACTOR(pll3_20, "pll3_20", "pll3_d8", ++ 20, 1); ++ ++/* pll1_d8 */ ++static SPACEMIT_CCU_GATE(pll1_d8_307p2, "pll1_d8_307p2", "pll1_d8", ++ BASE_TYPE_MPMU, MPMU_ACGR, ++ BIT(13), BIT(13), 0x0, ++ CLK_IGNORE_UNUSED); ++ ++static SPACEMIT_CCU_FACTOR(pll1_d32_76p8, ++ "pll1_d32_76p8", "pll1_d8_307p2", ++ 4, 1); ++ ++static SPACEMIT_CCU_FACTOR(pll1_d40_61p44, ++ "pll1_d40_61p44", "pll1_d8_307p2", ++ 5, 1); ++ ++static SPACEMIT_CCU_FACTOR(pll1_d16_153p6, ++ "pll1_d16_153p6", "pll1_d8", ++ 2, 1); ++ ++static SPACEMIT_CCU_GATE_FACTOR(pll1_d24_102p4, ++ "pll1_d24_102p4", "pll1_d8", ++ BASE_TYPE_MPMU, MPMU_ACGR, ++ BIT(12), BIT(12), 0x0, ++ 3, 1, CLK_IGNORE_UNUSED); ++ ++static SPACEMIT_CCU_GATE_FACTOR(pll1_d48_51p2, ++ "pll1_d48_51p2", "pll1_d8", ++ BASE_TYPE_MPMU, MPMU_ACGR, ++ BIT(7), BIT(7), 0x0, ++ 6, 1, CLK_IGNORE_UNUSED); ++ ++static SPACEMIT_CCU_GATE_FACTOR(pll1_d48_51p2_ap, ++ "pll1_d48_51p2_ap", "pll1_d8", ++ BASE_TYPE_MPMU, MPMU_ACGR, ++ BIT(11), BIT(11), 0x0, ++ 6, 1, CLK_IGNORE_UNUSED); ++ ++static SPACEMIT_CCU_GATE_FACTOR(pll1_m3d128_57p6, ++ "pll1_m3d128_57p6", "pll1_d8", ++ BASE_TYPE_MPMU, MPMU_ACGR, ++ BIT(8), BIT(8), 0x0, ++ 16, 3, CLK_IGNORE_UNUSED); ++ ++static SPACEMIT_CCU_GATE_FACTOR(pll1_d96_25p6, ++ "pll1_d96_25p6", "pll1_d8", ++ BASE_TYPE_MPMU, MPMU_ACGR, ++ BIT(4), BIT(4), 0x0, ++ 12, 1, CLK_IGNORE_UNUSED); ++ ++static SPACEMIT_CCU_GATE_FACTOR(pll1_d192_12p8, ++ "pll1_d192_12p8", "pll1_d8", ++ BASE_TYPE_MPMU, MPMU_ACGR, ++ BIT(3), BIT(3), 0x0, ++ 24, 1, CLK_IGNORE_UNUSED); ++ ++static SPACEMIT_CCU_GATE_FACTOR(pll1_d192_12p8_wdt, ++ "pll1_d192_12p8_wdt", ++ "pll1_d8", ++ BASE_TYPE_MPMU, MPMU_ACGR, ++ BIT(19), BIT(19), 0x0, ++ 24, 1, CLK_IGNORE_UNUSED); ++ ++static SPACEMIT_CCU_GATE_FACTOR(pll1_d384_6p4, ++ "pll1_d384_6p4", "pll1_d8", ++ BASE_TYPE_MPMU, MPMU_ACGR, ++ BIT(2), BIT(2), 0x0, ++ 48, 1, CLK_IGNORE_UNUSED); ++ ++static SPACEMIT_CCU_FACTOR(pll1_d768_3p2, ++ "pll1_d768_3p2", "pll1_d384_6p4", ++ 2, 1); ++ ++static SPACEMIT_CCU_FACTOR(pll1_d1536_1p6, ++ "pll1_d1536_1p6", "pll1_d384_6p4", ++ 4, 1); ++ ++static SPACEMIT_CCU_FACTOR(pll1_d3072_0p8, ++ "pll1_d3072_0p8", "pll1_d384_6p4", ++ 8, 1); ++ ++/* pll1_d7 */ ++static SPACEMIT_CCU_FACTOR(pll1_d7_351p08, ++ "pll1_d7_351p08", "pll1_d7", ++ 1, 1); ++ ++/* pll1_d6 */ ++static SPACEMIT_CCU_GATE(pll1_d6_409p6, ++ "pll1_d6_409p6", "pll1_d6", ++ BASE_TYPE_MPMU, MPMU_ACGR, ++ BIT(0), BIT(0), 0x0, ++ CLK_IGNORE_UNUSED); ++ ++static SPACEMIT_CCU_GATE_FACTOR(pll1_d12_204p8, ++ "pll1_d12_204p8", "pll1_d6", ++ BASE_TYPE_MPMU, MPMU_ACGR, ++ BIT(5), BIT(5), 0x0, ++ 2, 1, CLK_IGNORE_UNUSED); ++ ++/* pll1_d5 */ ++static SPACEMIT_CCU_GATE(pll1_d5_491p52, ++ "pll1_d5_491p52", "pll1_d5", ++ BASE_TYPE_MPMU, MPMU_ACGR, ++ BIT(21), BIT(21), 0x0, ++ CLK_IGNORE_UNUSED); ++ ++static SPACEMIT_CCU_GATE_FACTOR(pll1_d10_245p76, ++ "pll1_d10_245p76", "pll1_d5", ++ BASE_TYPE_MPMU, MPMU_ACGR, ++ BIT(18), BIT(18), 0x0, ++ 2, 1, CLK_IGNORE_UNUSED); ++ ++/* pll1_d4 */ ++static SPACEMIT_CCU_GATE(pll1_d4_614p4, ++ "pll1_d4_614p4", "pll1_d4", ++ BASE_TYPE_MPMU, MPMU_ACGR, ++ BIT(15), BIT(15), 0x0, ++ CLK_IGNORE_UNUSED); ++ ++static SPACEMIT_CCU_GATE_FACTOR(pll1_d52_47p26, ++ "pll1_d52_47p26", "pll1_d4", ++ BASE_TYPE_MPMU, MPMU_ACGR, ++ BIT(10), BIT(10), 0x0, ++ 13, 1, CLK_IGNORE_UNUSED); ++ ++static SPACEMIT_CCU_GATE_FACTOR(pll1_d78_31p5, ++ "pll1_d78_31p5", "pll1_d4", ++ BASE_TYPE_MPMU, MPMU_ACGR, ++ BIT(6), BIT(6), 0x0, ++ 39, 2, CLK_IGNORE_UNUSED); ++ ++/* pll1_d3 */ ++static SPACEMIT_CCU_GATE(pll1_d3_819p2, ++ "pll1_d3_819p2", "pll1_d3", ++ BASE_TYPE_MPMU, MPMU_ACGR, ++ BIT(14), BIT(14), 0x0, ++ CLK_IGNORE_UNUSED); ++ ++/* pll1_d2 */ ++static SPACEMIT_CCU_GATE(pll1_d2_1228p8, ++ "pll1_d2_1228p8", "pll1_d2", ++ BASE_TYPE_MPMU, MPMU_ACGR, ++ BIT(16), BIT(16), 0x0, ++ CLK_IGNORE_UNUSED); ++ ++/* dpll */ ++static const struct ccu_dpll_rate_tbl dpll1_rate_tbl[] = { ++ DPLL_RATE(2400000000UL, 0x00, 0x00, 0x20, ++ 0x2a, 0x32, 0x64, 0xdd, 0x50), ++ DPLL_RATE(2400000000UL, 0x00, 0x3b, 0x20, ++ 0x2a, 0x32, 0x64, 0xdd, 0x50), ++}; ++ ++static const struct ccu_dpll_rate_tbl dpll2_rate_tbl[] = { ++ DPLL_RATE(3200000000UL, 0x55, 0x55, 0x3d, ++ 0x2a, 0x43, 0x67, 0xdd, 0x50), ++}; ++ ++static SPACEMIT_CCU_DPLL(dpll1, "dpll1", &dpll1_rate_tbl, ++ ARRAY_SIZE(dpll1_rate_tbl), ++ BASE_TYPE_APMU, APMU_DPLL1_CLK_CTRL1, APMU_DPLL1_CLK_CTRL2, ++ 0, CLK_IGNORE_UNUSED); ++ ++static SPACEMIT_CCU_DPLL(dpll2, "dpll2", &dpll2_rate_tbl, ++ ARRAY_SIZE(dpll2_rate_tbl), ++ BASE_TYPE_APMU, APMU_DPLL2_CLK_CTRL1, APMU_DPLL2_CLK_CTRL2, ++ 0, CLK_IGNORE_UNUSED); ++ ++static const char * const dfc_lvl_parents[] = { ++ "dpll2", "dpll1" ++}; ++ ++static SPACEMIT_CCU_DIV_MUX(dfc_lvl0, "dfc_lvl0", ++ dfc_lvl_parents, BASE_TYPE_APMU, APMU_DFC_LEVEL0, ++ 14, 2, 8, 1, 0); ++ ++static SPACEMIT_CCU_DIV_MUX(dfc_lvl1, "dfc_lvl1", ++ dfc_lvl_parents, BASE_TYPE_APMU, APMU_DFC_LEVEL1, ++ 14, 2, 8, 1, 0); ++ ++static SPACEMIT_CCU_DIV_MUX(dfc_lvl2, "dfc_lvl2", ++ dfc_lvl_parents, BASE_TYPE_APMU, APMU_DFC_LEVEL2, ++ 14, 2, 8, 1, 0); ++ ++static SPACEMIT_CCU_DIV_MUX(dfc_lvl3, "dfc_lvl3", ++ dfc_lvl_parents, BASE_TYPE_APMU, APMU_DFC_LEVEL3, ++ 14, 2, 8, 1, 0); ++ ++static SPACEMIT_CCU_DIV_MUX(dfc_lvl4, "dfc_lvl4", ++ dfc_lvl_parents, BASE_TYPE_APMU, APMU_DFC_LEVEL4, ++ 14, 2, 8, 1, 0); ++ ++static SPACEMIT_CCU_DIV_MUX(dfc_lvl5, "dfc_lvl5", ++ dfc_lvl_parents, BASE_TYPE_APMU, APMU_DFC_LEVEL5, ++ 14, 2, 8, 1, 0); ++ ++static SPACEMIT_CCU_DIV_MUX(dfc_lvl6, "dfc_lvl6", ++ dfc_lvl_parents, BASE_TYPE_APMU, APMU_DFC_LEVEL6, ++ 14, 2, 8, 1, 0); ++ ++static SPACEMIT_CCU_DIV_MUX(dfc_lvl7, "dfc_lvl7", ++ dfc_lvl_parents, BASE_TYPE_APMU, APMU_DFC_LEVEL7, ++ 14, 2, 8, 1, 0); ++ ++static const char * const ddr_clk_parents[] = { ++ "dfc_lvl0", "dfc_lvl1", "dfc_lvl2", "dfc_lvl3", ++ "dfc_lvl4", "dfc_lvl5", "dfc_lvl6", "dfc_lvl7" ++}; ++ ++static SPACEMIT_CCU_DDR_FC(ddr, "ddr", ddr_clk_parents, ++ BASE_TYPE_APMU, APMU_DFC_AP, BIT(0), ++ 1, 3, 0); ++ ++static struct ccu_ddn_info uart_ddn_mask_info = { ++ .factor = 2, ++ .num_mask = 0x1fff, ++ .den_mask = 0x1fff, ++ .num_shift = 16, ++ .den_shift = 0, ++}; ++ ++static struct ccu_ddn_tbl slow_uart1_tbl[] = { ++ {.num = 125, .den = 24}, ++}; ++ ++static struct ccu_ddn_tbl slow_uart2_tbl[] = { ++ {.num = 6144, .den = 960}, ++}; ++ ++static SPACEMIT_CCU_GATE_NO_PARENT(slow_uart, ++ "slow_uart", NULL, ++ BASE_TYPE_MPMU, MPMU_ACGR, ++ BIT(1), BIT(1), 0x0, ++ 0); ++ ++static SPACEMIT_CCU_DDN(slow_uart1_14p74, ++ "slow_uart1_14p74", "pll1_d16_153p6", ++ &uart_ddn_mask_info, &slow_uart1_tbl, ++ ARRAY_SIZE(slow_uart1_tbl), ++ BASE_TYPE_MPMU, MPMU_SUCCR, ++ CLK_IGNORE_UNUSED); ++ ++static SPACEMIT_CCU_DDN(slow_uart2_48, ++ "slow_uart2_48", "pll1_d4_614p4", ++ &uart_ddn_mask_info, &slow_uart2_tbl, ++ ARRAY_SIZE(slow_uart2_tbl), ++ BASE_TYPE_MPMU, MPMU_SUCCR_1, ++ CLK_IGNORE_UNUSED); ++ ++static const char * const uart_parent_names[] = { ++ "pll1_m3d128_57p6", "slow_uart1_14p74", "slow_uart2_48" ++}; ++ ++static SPACEMIT_CCU_MUX_GATE(uart1_clk, "uart1_clk", ++ uart_parent_names, BASE_TYPE_APBC, APBC_UART1_CLK_RST, ++ 4, 3, 0x3, 0x3, 0x0, ++ 0); ++ ++static SPACEMIT_CCU_MUX_GATE(uart2_clk, "uart2_clk", ++ uart_parent_names, BASE_TYPE_APBC, APBC_UART2_CLK_RST, ++ 4, 3, 0x3, 0x3, 0x0, ++ 0); ++ ++static SPACEMIT_CCU_MUX_GATE(uart3_clk, "uart3_clk", ++ uart_parent_names, BASE_TYPE_APBC, APBC_UART3_CLK_RST, ++ 4, 3, 0x3, 0x3, 0x0, ++ 0); ++ ++static SPACEMIT_CCU_MUX_GATE(uart4_clk, "uart4_clk", ++ uart_parent_names, BASE_TYPE_APBC, APBC_UART4_CLK_RST, ++ 4, 3, 0x3, 0x3, 0x0, ++ 0); ++ ++static SPACEMIT_CCU_MUX_GATE(uart5_clk, "uart5_clk", ++ uart_parent_names, BASE_TYPE_APBC, APBC_UART5_CLK_RST, ++ 4, 3, 0x3, 0x3, 0x0, ++ 0); ++ ++static SPACEMIT_CCU_MUX_GATE(uart6_clk, "uart6_clk", ++ uart_parent_names, BASE_TYPE_APBC, APBC_UART6_CLK_RST, ++ 4, 3, 0x3, 0x3, 0x0, ++ 0); ++ ++static SPACEMIT_CCU_MUX_GATE(uart7_clk, "uart7_clk", ++ uart_parent_names, BASE_TYPE_APBC, APBC_UART7_CLK_RST, ++ 4, 3, 0x3, 0x3, 0x0, ++ 0); ++ ++static SPACEMIT_CCU_MUX_GATE(uart8_clk, "uart8_clk", ++ uart_parent_names, BASE_TYPE_APBC, APBC_UART8_CLK_RST, ++ 4, 3, 0x3, 0x3, 0x0, ++ 0); ++ ++static SPACEMIT_CCU_MUX_GATE(uart9_clk, "uart9_clk", ++ uart_parent_names, BASE_TYPE_APBC, APBC_UART9_CLK_RST, ++ 4, 3, 0x3, 0x3, 0x0, ++ 0); ++ ++static SPACEMIT_CCU_GATE(gpio_clk, "gpio_clk", "vctcxo_24", ++ BASE_TYPE_APBC, APBC_GPIO_CLK_RST, ++ 0x3, 0x3, 0x0, ++ 0); ++ ++static const char * const pwm_parent_names[] = { ++ "pll1_d192_12p8", "clk_32k" ++}; ++ ++static SPACEMIT_CCU_MUX_GATE(pwm0_clk, "pwm0_clk", ++ pwm_parent_names, BASE_TYPE_APBC, APBC_PWM0_CLK_RST, ++ 4, 3, 0x2, 0x2, 0x0, ++ 0); ++ ++static SPACEMIT_CCU_MUX_GATE(pwm1_clk, "pwm1_clk", ++ pwm_parent_names, BASE_TYPE_APBC, APBC_PWM1_CLK_RST, ++ 4, 3, 0x2, 0x2, 0x0, ++ 0); ++ ++static SPACEMIT_CCU_MUX_GATE(pwm2_clk, "pwm2_clk", ++ pwm_parent_names, BASE_TYPE_APBC, APBC_PWM2_CLK_RST, ++ 4, 3, 0x2, 0x2, 0x0, ++ 0); ++ ++static SPACEMIT_CCU_MUX_GATE(pwm3_clk, "pwm3_clk", ++ pwm_parent_names, BASE_TYPE_APBC, APBC_PWM3_CLK_RST, ++ 4, 3, 0x2, 0x2, 0x0, ++ 0); ++ ++static SPACEMIT_CCU_MUX_GATE(pwm4_clk, "pwm4_clk", ++ pwm_parent_names, BASE_TYPE_APBC, APBC_PWM4_CLK_RST, ++ 4, 3, 0x2, 0x2, 0x0, ++ 0); ++ ++static SPACEMIT_CCU_MUX_GATE(pwm5_clk, "pwm5_clk", ++ pwm_parent_names, BASE_TYPE_APBC, APBC_PWM5_CLK_RST, ++ 4, 3, 0x2, 0x2, 0x0, ++ 0); ++ ++static SPACEMIT_CCU_MUX_GATE(pwm6_clk, "pwm6_clk", ++ pwm_parent_names, BASE_TYPE_APBC, APBC_PWM6_CLK_RST, ++ 4, 3, 0x2, 0x2, 0x0, ++ 0); ++ ++static SPACEMIT_CCU_MUX_GATE(pwm7_clk, "pwm7_clk", ++ pwm_parent_names, BASE_TYPE_APBC, APBC_PWM7_CLK_RST, ++ 4, 3, 0x2, 0x2, 0x0, ++ 0); ++ ++static SPACEMIT_CCU_MUX_GATE(pwm8_clk, "pwm8_clk", ++ pwm_parent_names, BASE_TYPE_APBC, APBC_PWM8_CLK_RST, ++ 4, 3, 0x2, 0x2, 0x0, ++ 0); ++ ++static SPACEMIT_CCU_MUX_GATE(pwm9_clk, "pwm9_clk", ++ pwm_parent_names, BASE_TYPE_APBC, APBC_PWM9_CLK_RST, ++ 4, 3, 0x2, 0x2, 0x0, ++ 0); ++ ++static SPACEMIT_CCU_MUX_GATE(pwm10_clk, "pwm10_clk", ++ pwm_parent_names, BASE_TYPE_APBC, APBC_PWM10_CLK_RST, ++ 4, 3, 0x2, 0x2, 0x0, ++ 0); ++ ++static SPACEMIT_CCU_MUX_GATE(pwm11_clk, "pwm11_clk", ++ pwm_parent_names, BASE_TYPE_APBC, APBC_PWM11_CLK_RST, ++ 4, 3, 0x2, 0x2, 0x0, ++ 0); ++ ++static SPACEMIT_CCU_MUX_GATE(pwm12_clk, "pwm12_clk", ++ pwm_parent_names, BASE_TYPE_APBC, APBC_PWM12_CLK_RST, ++ 4, 3, 0x2, 0x2, 0x0, ++ 0); ++ ++static SPACEMIT_CCU_MUX_GATE(pwm13_clk, "pwm13_clk", ++ pwm_parent_names, BASE_TYPE_APBC, APBC_PWM13_CLK_RST, ++ 4, 3, 0x2, 0x2, 0x0, ++ 0); ++ ++static SPACEMIT_CCU_MUX_GATE(pwm14_clk, "pwm14_clk", ++ pwm_parent_names, BASE_TYPE_APBC, APBC_PWM14_CLK_RST, ++ 4, 3, 0x2, 0x2, 0x0, ++ 0); ++ ++static SPACEMIT_CCU_MUX_GATE(pwm15_clk, "pwm15_clk", ++ pwm_parent_names, BASE_TYPE_APBC, APBC_PWM15_CLK_RST, ++ 4, 3, 0x2, 0x2, 0x0, ++ 0); ++ ++static SPACEMIT_CCU_MUX_GATE(pwm16_clk, "pwm16_clk", ++ pwm_parent_names, BASE_TYPE_APBC, APBC_PWM16_CLK_RST, ++ 4, 3, 0x2, 0x2, 0x0, ++ 0); ++ ++static SPACEMIT_CCU_MUX_GATE(pwm17_clk, "pwm17_clk", ++ pwm_parent_names, BASE_TYPE_APBC, APBC_PWM17_CLK_RST, ++ 4, 3, 0x2, 0x2, 0x0, ++ 0); ++ ++static SPACEMIT_CCU_MUX_GATE(pwm18_clk, "pwm18_clk", ++ pwm_parent_names, BASE_TYPE_APBC, APBC_PWM18_CLK_RST, ++ 4, 3, 0x2, 0x2, 0x0, ++ 0); ++ ++static SPACEMIT_CCU_MUX_GATE(pwm19_clk, "pwm19_clk", ++ pwm_parent_names, BASE_TYPE_APBC, APBC_PWM19_CLK_RST, ++ 4, 3, 0x2, 0x2, 0x0, ++ 0); ++ ++static const char * const ssp_parent_names[] = { ++ "pll1_d384_6p4", "pll1_d192_12p8", "pll1_d96_25p6", ++ "pll1_d48_51p2", "pll1_d768_3p2", "pll1_d1536_1p6", ++ "pll1_d3072_0p8" ++}; ++ ++static SPACEMIT_CCU_MUX_GATE(ssp3_clk, ++ "ssp3_clk", ssp_parent_names, ++ BASE_TYPE_APBC, APBC_SSP3_CLK_RST, ++ 4, 3, 0x3, 0x3, 0x0, ++ 0); ++ ++static SPACEMIT_CCU_GATE(rtc_clk, "rtc_clk", "clk_32k", ++ BASE_TYPE_APBC, APBC_RTC_CLK_RST, ++ 0x83, 0x83, 0x0, 0); ++ ++static const char * const twsi_parent_names[] = { ++ "pll1_d78_31p5", "pll1_d48_51p2", "pll1_d40_61p44" ++}; ++ ++static SPACEMIT_CCU_MUX_GATE(twsi0_clk, "twsi0_clk", ++ twsi_parent_names, BASE_TYPE_APBC, APBC_TWSI0_CLK_RST, ++ 4, 3, 0x3, 0x3, 0x0, ++ 0); ++ ++static SPACEMIT_CCU_MUX_GATE(twsi1_clk, "twsi1_clk", ++ twsi_parent_names, BASE_TYPE_APBC, APBC_TWSI1_CLK_RST, ++ 4, 3, 0x3, 0x3, 0x0, ++ 0); ++ ++static SPACEMIT_CCU_MUX_GATE(twsi2_clk, "twsi2_clk", ++ twsi_parent_names, BASE_TYPE_APBC, APBC_TWSI2_CLK_RST, ++ 4, 3, 0x3, 0x3, 0x0, ++ 0); ++ ++static SPACEMIT_CCU_MUX_GATE(twsi4_clk, "twsi4_clk", ++ twsi_parent_names, BASE_TYPE_APBC, APBC_TWSI4_CLK_RST, ++ 4, 3, 0x3, 0x3, 0x0, ++ 0); ++ ++static SPACEMIT_CCU_MUX_GATE(twsi5_clk, "twsi5_clk", ++ twsi_parent_names, BASE_TYPE_APBC, APBC_TWSI5_CLK_RST, ++ 4, 3, 0x3, 0x3, 0x0, ++ 0); ++ ++static SPACEMIT_CCU_MUX_GATE(twsi6_clk, "twsi6_clk", ++ twsi_parent_names, BASE_TYPE_APBC, APBC_TWSI6_CLK_RST, ++ 4, 3, 0x3, 0x3, 0x0, ++ 0); ++ ++static SPACEMIT_CCU_MUX_GATE(twsi7_clk, "twsi7_clk", ++ twsi_parent_names, BASE_TYPE_APBC, APBC_TWSI7_CLK_RST, ++ 4, 3, 0x3, 0x3, 0x0, ++ 0); ++ ++static SPACEMIT_CCU_MUX_GATE(twsi8_clk, "twsi8_clk", ++ twsi_parent_names, BASE_TYPE_APBC, APBC_TWSI8_CLK_RST, ++ 4, 3, 0x7, 0x3, 0x4, ++ 0); ++ ++static const char * const timer_parent_names[] = { ++ "pll1_d192_12p8", "clk_32k", "pll1_d384_6p4", ++ "vctcxo_3", "vctcxo_1" ++}; ++ ++static SPACEMIT_CCU_MUX_GATE(timers1_clk, "timers1_clk", ++ timer_parent_names, BASE_TYPE_APBC, APBC_TIMERS1_CLK_RST, ++ 4, 3, 0x3, 0x3, 0x0, ++ 0); ++ ++static SPACEMIT_CCU_MUX_GATE(timers2_clk, ++ "timers2_clk", timer_parent_names, ++ BASE_TYPE_APBC, APBC_TIMERS2_CLK_RST, ++ 4, 3, 0x3, 0x3, 0x0, ++ 0); ++ ++static SPACEMIT_CCU_GATE(aib_clk, "aib_clk", "vctcxo_24", ++ BASE_TYPE_APBC, APBC_AIB_CLK_RST, ++ 0x3, 0x3, 0x0, 0); ++ ++static SPACEMIT_CCU_GATE_NO_PARENT(onewire_clk, ++ "onewire_clk", NULL, ++ BASE_TYPE_APBC, APBC_ONEWIRE_CLK_RST, ++ 0x3, 0x3, 0x0, 0); ++ ++static SPACEMIT_CCU_GATE_FACTOR(i2s_sysclk, ++ "i2s_sysclk", "pll1_d8_307p2", ++ BASE_TYPE_MPMU, MPMU_ISCCR, ++ BIT(31), BIT(31), 0x0, ++ 200, 1, 0); ++ ++static SPACEMIT_CCU_GATE_FACTOR(i2s_bclk, ++ "i2s_bclk", "i2s_sysclk", ++ BASE_TYPE_MPMU, MPMU_ISCCR, ++ BIT(29), BIT(29), 0x0, ++ 1, 1, 0); ++ ++static const char * const sspa_parent_names[] = { ++ "pll1_d384_6p4", "pll1_d192_12p8", "pll1_d96_25p6", ++ "pll1_d48_51p2", "pll1_d768_3p2", "pll1_d1536_1p6", ++ "pll1_d3072_0p8", "i2s_bclk" ++}; ++ ++static SPACEMIT_CCU_MUX_GATE(sspa0_clk, "sspa0_clk", sspa_parent_names, ++ BASE_TYPE_APBC, APBC_SSPA0_CLK_RST, ++ 4, 3, 0x3, 0x3, 0x0, ++ 0); ++ ++static SPACEMIT_CCU_MUX_GATE(sspa1_clk, "sspa1_clk", sspa_parent_names, ++ BASE_TYPE_APBC, APBC_SSPA1_CLK_RST, ++ 4, 3, 0x3, 0x3, 0x0, ++ 0); ++ ++static SPACEMIT_CCU_GATE_NO_PARENT(dro_clk, "dro_clk", NULL, ++ BASE_TYPE_APBC, APBC_DRO_CLK_RST, ++ 0x1, 0x1, 0x0, 0); ++ ++static SPACEMIT_CCU_GATE_NO_PARENT(ir_clk, "ir_clk", NULL, ++ BASE_TYPE_APBC, APBC_IR_CLK_RST, ++ 0x1, 0x1, 0x0, 0); ++ ++static SPACEMIT_CCU_GATE_NO_PARENT(tsen_clk, "tsen_clk", NULL, ++ BASE_TYPE_APBC, APBC_TSEN_CLK_RST, ++ 0x3, 0x3, 0x0, 0); ++ ++static SPACEMIT_CCU_GATE_NO_PARENT(ipc_ap2aud_clk, "ipc_ap2aud_clk", ++ NULL, BASE_TYPE_APBC, APBC_IPC_AP2AUD_CLK_RST, ++ 0x3, 0x3, 0x0, 0); ++ ++static const char * const can_parent_names[] = { ++ "pll3_20", "pll3_40", "pll3_80" ++}; ++ ++static SPACEMIT_CCU_MUX_GATE(can0_clk, "can0_clk", can_parent_names, ++ BASE_TYPE_APBC, APBC_CAN0_CLK_RST, ++ 4, 3, BIT(1), BIT(1), 0x0, ++ 0); ++ ++static SPACEMIT_CCU_GATE_NO_PARENT(can0_bus_clk, "can0_bus_clk", NULL, ++ BASE_TYPE_APBC, APBC_CAN0_CLK_RST, ++ BIT(0), BIT(0), 0x0, 0); ++ ++static SPACEMIT_CCU_GATE(wdt_clk, "wdt_clk", "pll1_d96_25p6", ++ BASE_TYPE_MPMU, MPMU_WDTPCR, ++ 0x3, 0x3, 0x0, 0); ++ ++static SPACEMIT_CCU_GATE_NO_PARENT(ripc_clk, "ripc_clk", NULL, ++ BASE_TYPE_MPMU, MPMU_RIPCCR, ++ 0x3, 0x3, 0x0, 0); ++ ++static const char * const jpg_parent_names[] = { ++ "pll1_d4_614p4", "pll1_d6_409p6", "pll1_d5_491p52", ++ "pll1_d3_819p2", "pll1_d2_1228p8", "pll2_d4", "pll2_d3" ++}; ++ ++static SPACEMIT_CCU_DIV_FC_MUX_GATE(jpg_clk, "jpg_clk", ++ jpg_parent_names, BASE_TYPE_APMU, APMU_JPG_CLK_RES_CTRL, ++ 5, 3, BIT(15), ++ 2, 3, BIT(1), BIT(1), 0x0, ++ 0); ++ ++static SPACEMIT_CCU_GATE_NO_PARENT(jpg_4kafbc_clk, "jpg_4kafbc_clk", ++ NULL, BASE_TYPE_APMU, APMU_JPG_CLK_RES_CTRL, ++ BIT(16), BIT(16), 0x0, 0); ++ ++static SPACEMIT_CCU_GATE_NO_PARENT(jpg_2kafbc_clk, "jpg_2kafbc_clk", ++ NULL, BASE_TYPE_APMU, APMU_JPG_CLK_RES_CTRL, ++ BIT(17), BIT(17), 0x0, 0); ++ ++static const char * const ccic2phy_parent_names[] = { ++ "pll1_d24_102p4", "pll1_d48_51p2_ap" ++}; ++ ++static SPACEMIT_CCU_MUX_GATE(ccic2phy_clk, "ccic2phy_clk", ++ ccic2phy_parent_names, ++ BASE_TYPE_APMU, APMU_CSI_CCIC2_CLK_RES_CTRL, ++ 7, 1, BIT(5), BIT(5), 0x0, ++ 0); ++ ++static const char * const ccic3phy_parent_names[] = { ++ "pll1_d24_102p4", "pll1_d48_51p2_ap" ++}; ++ ++static SPACEMIT_CCU_MUX_GATE(ccic3phy_clk, "ccic3phy_clk", ++ ccic3phy_parent_names, ++ BASE_TYPE_APMU, APMU_CSI_CCIC2_CLK_RES_CTRL, ++ 31, 1, BIT(30), BIT(30), 0x0, 0); ++ ++static const char * const csi_parent_names[] = { ++ "pll1_d5_491p52", "pll1_d6_409p6", "pll1_d4_614p4", ++ "pll1_d3_819p2", "pll2_d2", "pll2_d3", "pll2_d4", ++ "pll1_d2_1228p8" ++}; ++ ++static SPACEMIT_CCU_DIV_FC_MUX_GATE(csi_clk, "csi_clk", ++ csi_parent_names, BASE_TYPE_APMU, APMU_CSI_CCIC2_CLK_RES_CTRL, ++ 20, 3, BIT(15), ++ 16, 3, BIT(4), BIT(4), 0x0, ++ 0); ++ ++static const char * const camm_parent_names[] = { ++ "pll1_d8_307p2", "pll2_d5", "pll1_d6_409p6", "vctcxo_24" ++}; ++ ++static SPACEMIT_CCU_DIV_MUX_GATE(camm0_clk, "camm0_clk", ++ camm_parent_names, BASE_TYPE_APMU, APMU_CSI_CCIC2_CLK_RES_CTRL, ++ 23, 4, 8, 2, ++ BIT(28), BIT(28), 0x0, ++ 0); ++ ++static SPACEMIT_CCU_DIV_MUX_GATE(camm1_clk, "camm1_clk", ++ camm_parent_names, BASE_TYPE_APMU, APMU_CSI_CCIC2_CLK_RES_CTRL, ++ 23, 4, 8, 2, ++ BIT(6), BIT(6), 0x0, ++ 0); ++ ++static SPACEMIT_CCU_DIV_MUX_GATE(camm2_clk, "camm2_clk", ++ camm_parent_names, BASE_TYPE_APMU, APMU_CSI_CCIC2_CLK_RES_CTRL, ++ 23, 4, 8, 2, ++ BIT(3), BIT(3), 0x0, ++ 0); ++ ++static const char * const isp_cpp_parent_names[] = { ++ "pll1_d8_307p2", "pll1_d6_409p6" ++}; ++ ++static SPACEMIT_CCU_DIV_MUX_GATE(isp_cpp_clk, "isp_cpp_clk", ++ isp_cpp_parent_names, ++ BASE_TYPE_APMU, APMU_ISP_CLK_RES_CTRL, ++ 24, 2, 26, 1, ++ BIT(28), BIT(28), 0x0, ++ 0); ++ ++static const char * const isp_bus_parent_names[] = { ++ "pll1_d6_409p6", "pll1_d5_491p52", "pll1_d8_307p2", ++ "pll1_d10_245p76" ++}; ++ ++static SPACEMIT_CCU_DIV_FC_MUX_GATE(isp_bus_clk, "isp_bus_clk", ++ isp_bus_parent_names, ++ BASE_TYPE_APMU, APMU_ISP_CLK_RES_CTRL, ++ 18, 3, BIT(23), ++ 21, 2, BIT(17), BIT(17), 0x0, ++ 0); ++ ++static const char * const isp_parent_names[] = { ++ "pll1_d6_409p6", "pll1_d5_491p52", "pll1_d4_614p4", ++ "pll1_d8_307p2" ++}; ++ ++static SPACEMIT_CCU_DIV_FC_MUX_GATE(isp_clk, "isp_clk", ++ isp_parent_names, BASE_TYPE_APMU, APMU_ISP_CLK_RES_CTRL, ++ 4, 3, BIT(7), ++ 8, 2, BIT(1), BIT(1), 0x0, ++ 0); ++ ++static const char * const dpumclk_parent_names[] = { ++ "pll1_d6_409p6", "pll1_d5_491p52", "pll1_d4_614p4", ++ "pll1_d8_307p2" ++}; ++ ++static SPACEMIT_CCU_DIV2_FC_MUX_GATE(dpu_mclk, "dpu_mclk", ++ dpumclk_parent_names, BASE_TYPE_APMU, ++ APMU_LCD_CLK_RES_CTRL1, APMU_LCD_CLK_RES_CTRL2, ++ 1, 4, BIT(29), ++ 5, 3, BIT(0), BIT(0), 0x0, ++ 0); ++ ++static const char * const dpuesc_parent_names[] = { ++ "pll1_d48_51p2_ap", "pll1_d52_47p26", "pll1_d96_25p6", ++ "pll1_d32_76p8" ++}; ++ ++static SPACEMIT_CCU_MUX_GATE(dpu_esc_clk, "dpu_esc_clk", dpuesc_parent_names, ++ BASE_TYPE_APMU, APMU_LCD_CLK_RES_CTRL1, ++ 0, 2, BIT(2), BIT(2), 0x0, ++ 0); ++ ++static const char * const dpubit_parent_names[] = { ++ "pll1_d3_819p2", "pll2_d2", "pll2_d3", "pll1_d2_1228p8", ++ "pll2_d4", "pll2_d5", "pll2_d8", "pll2_d8" ++}; ++ ++static SPACEMIT_CCU_DIV_FC_MUX_GATE(dpu_bit_clk, "dpu_bit_clk", ++ dpubit_parent_names, ++ BASE_TYPE_APMU, APMU_LCD_CLK_RES_CTRL1, ++ 17, 3, BIT(31), ++ 20, 3, BIT(16), BIT(16), 0x0, ++ 0); ++ ++static const char * const dpupx_parent_names[] = { ++ "pll1_d6_409p6", "pll1_d5_491p52", "pll1_d4_614p4", ++ "pll1_d8_307p2", "pll2_d7", "pll2_d8" ++}; ++ ++static SPACEMIT_CCU_DIV2_FC_MUX_GATE(dpu_pxclk, "dpu_pxclk", dpupx_parent_names, ++ BASE_TYPE_APMU, APMU_LCD_CLK_RES_CTRL1, APMU_LCD_CLK_RES_CTRL2, ++ 17, 4, BIT(30), ++ 21, 3, BIT(16), BIT(16), 0x0, ++ 0); ++ ++static SPACEMIT_CCU_GATE_NO_PARENT(dpu_hclk, "dpu_hclk", NULL, ++ BASE_TYPE_APMU, APMU_LCD_CLK_RES_CTRL1, ++ BIT(5), BIT(5), 0x0, ++ 0); ++ ++static const char * const dpu_spi_parent_names[] = { ++ "pll1_d8_307p2", "pll1_d6_409p6", "pll1_d10_245p76", ++ "pll1_d11_223p4", "pll1_d13_189", "pll1_d23_106p8", ++ "pll2_d3", "pll2_d5" ++}; ++ ++static SPACEMIT_CCU_DIV_FC_MUX_GATE(dpu_spi_clk, "dpu_spi_clk", ++ dpu_spi_parent_names, ++ BASE_TYPE_APMU, APMU_LCD_SPI_CLK_RES_CTRL, ++ 8, 3, BIT(7), ++ 12, 3, BIT(1), BIT(1), 0x0, ++ 0); ++ ++static SPACEMIT_CCU_GATE_NO_PARENT(dpu_spi_hbus_clk, "dpu_spi_hbus_clk", NULL, ++ BASE_TYPE_APMU, APMU_LCD_SPI_CLK_RES_CTRL, ++ BIT(3), BIT(3), 0x0, ++ 0); ++ ++static SPACEMIT_CCU_GATE_NO_PARENT(dpu_spi_bus_clk, "dpu_spi_bus_clk", NULL, ++ BASE_TYPE_APMU, APMU_LCD_SPI_CLK_RES_CTRL, ++ BIT(5), BIT(5), 0x0, ++ 0); ++ ++static SPACEMIT_CCU_GATE_NO_PARENT(dpu_spi_aclk, "dpu_spi_aclk", NULL, ++ BASE_TYPE_APMU, APMU_LCD_SPI_CLK_RES_CTRL, ++ BIT(6), BIT(6), 0x0, ++ 0); ++ ++static const char * const v2d_parent_names[] = { ++ "pll1_d5_491p52", "pll1_d6_409p6", "pll1_d8_307p2", ++ "pll1_d4_614p4", ++}; ++ ++static SPACEMIT_CCU_DIV_FC_MUX_GATE(v2d_clk, "v2d_clk", v2d_parent_names, ++ BASE_TYPE_APMU, APMU_LCD_CLK_RES_CTRL1, ++ 9, 3, BIT(28), ++ 12, 2, BIT(8), BIT(8), 0x0, ++ 0); ++ ++static const char * const ccic_4x_parent_names[] = { ++ "pll1_d5_491p52", "pll1_d6_409p6", "pll1_d4_614p4", ++ "pll1_d3_819p2", "pll2_d2", "pll2_d3", "pll2_d4", ++ "pll1_d2_1228p8" ++}; ++ ++static SPACEMIT_CCU_DIV_FC_MUX_GATE(ccic_4x_clk, "ccic_4x_clk", ++ ccic_4x_parent_names, ++ BASE_TYPE_APMU, APMU_CCIC_CLK_RES_CTRL, ++ 18, 3, BIT(15), ++ 23, 2, BIT(4), BIT(4), 0x0, ++ 0); ++ ++static const char * const ccic1phy_parent_names[] = { ++ "pll1_d24_102p4", "pll1_d48_51p2_ap" ++}; ++ ++static SPACEMIT_CCU_MUX_GATE(ccic1phy_clk, "ccic1phy_clk", ++ ccic1phy_parent_names, ++ BASE_TYPE_APMU, APMU_CCIC_CLK_RES_CTRL, ++ 7, 1, BIT(5), BIT(5), 0x0, ++ 0); ++ ++static SPACEMIT_CCU_GATE_NO_PARENT(sdh_axi_aclk, "sdh_axi_aclk", NULL, ++ BASE_TYPE_APMU, APMU_SDH0_CLK_RES_CTRL, ++ BIT(3), BIT(3), 0x0, ++ 0); ++ ++static const char * const sdh01_parent_names[] = { ++ "pll1_d6_409p6", "pll1_d4_614p4", "pll2_d8", "pll2_d5", ++ "pll1_d11_223p4", "pll1_d13_189", "pll1_d23_106p8" ++}; ++ ++static SPACEMIT_CCU_DIV_FC_MUX_GATE(sdh0_clk, "sdh0_clk", sdh01_parent_names, ++ BASE_TYPE_APMU, APMU_SDH0_CLK_RES_CTRL, ++ 8, 3, BIT(11), ++ 5, 3, BIT(4), BIT(4), 0x0, ++ 0); ++ ++static SPACEMIT_CCU_DIV_FC_MUX_GATE(sdh1_clk, "sdh1_clk", sdh01_parent_names, ++ BASE_TYPE_APMU, APMU_SDH1_CLK_RES_CTRL, ++ 8, 3, BIT(11), ++ 5, 3, BIT(4), BIT(4), 0x0, ++ 0); ++ ++static const char * const sdh2_parent_names[] = { ++ "pll1_d6_409p6", "pll1_d4_614p4", "pll2_d8", ++ "pll1_d3_819p2", "pll1_d11_223p4", "pll1_d13_189", ++ "pll1_d23_106p8" ++}; ++ ++static SPACEMIT_CCU_DIV_FC_MUX_GATE(sdh2_clk, "sdh2_clk", sdh2_parent_names, ++ BASE_TYPE_APMU, APMU_SDH2_CLK_RES_CTRL, ++ 8, 3, BIT(11), ++ 5, 3, BIT(4), BIT(4), 0x0, ++ 0); ++ ++static SPACEMIT_CCU_GATE_NO_PARENT(usb_axi_clk, "usb_axi_clk", NULL, ++ BASE_TYPE_APMU, APMU_USB_CLK_RES_CTRL, ++ BIT(1), BIT(1), 0x0, ++ 0); ++ ++static SPACEMIT_CCU_GATE_NO_PARENT(usb_p1_aclk, "usb_p1_aclk", NULL, ++ BASE_TYPE_APMU, APMU_USB_CLK_RES_CTRL, ++ BIT(5), BIT(5), 0x0, ++ 0); ++ ++static SPACEMIT_CCU_GATE_NO_PARENT(usb30_clk, "usb30_clk", NULL, ++ BASE_TYPE_APMU, APMU_USB_CLK_RES_CTRL, ++ BIT(8), BIT(8), 0x0, ++ 0); ++ ++static const char * const qspi_parent_names[] = { ++ "pll1_d6_409p6", "pll2_d8", "pll1_d8_307p2", ++ "pll1_d10_245p76", "pll1_d11_223p4", "pll1_d23_106p8", ++ "pll1_d5_491p52", "pll1_d13_189" ++}; ++ ++static SPACEMIT_CCU_DIV_MUX_GATE(qspi_clk, "qspi_clk", qspi_parent_names, ++ BASE_TYPE_APMU, APMU_QSPI_CLK_RES_CTRL, ++ 9, 3, ++ 6, 3, BIT(4), BIT(4), 0x0, ++ 0); ++ ++static SPACEMIT_CCU_GATE_NO_PARENT(qspi_bus_clk, "qspi_bus_clk", NULL, ++ BASE_TYPE_APMU, APMU_QSPI_CLK_RES_CTRL, ++ BIT(3), BIT(3), 0x0, ++ 0); ++ ++static SPACEMIT_CCU_GATE_NO_PARENT(dma_clk, "dma_clk", NULL, ++ BASE_TYPE_APMU, APMU_DMA_CLK_RES_CTRL, ++ BIT(3), BIT(3), 0x0, ++ 0); ++ ++static const char * const aes_parent_names[] = { ++ "pll1_d12_204p8", "pll1_d24_102p4" ++}; ++ ++static SPACEMIT_CCU_MUX_GATE(aes_clk, "aes_clk", aes_parent_names, ++ BASE_TYPE_APMU, APMU_AES_CLK_RES_CTRL, ++ 6, 1, BIT(5), BIT(5), 0x0, ++ 0); ++ ++static const char * const vpu_parent_names[] = { ++ "pll1_d4_614p4", "pll1_d5_491p52", "pll1_d3_819p2", ++ "pll1_d6_409p6", "pll3_d6", "pll2_d3", "pll2_d4", "pll2_d5" ++}; ++ ++static SPACEMIT_CCU_DIV_FC_MUX_GATE(vpu_clk, "vpu_clk", vpu_parent_names, ++ BASE_TYPE_APMU, APMU_VPU_CLK_RES_CTRL, ++ 13, 3, BIT(21), ++ 10, 3, ++ BIT(3), BIT(3), 0x0, ++ 0); ++ ++static const char * const gpu_parent_names[] = { ++ "pll1_d4_614p4", "pll1_d5_491p52", "pll1_d3_819p2", "pll1_d6_409p6", ++ "pll3_d6", "pll2_d3", "pll2_d4", "pll2_d5" ++}; ++ ++static SPACEMIT_CCU_DIV_FC_MUX_GATE(gpu_clk, "gpu_clk", gpu_parent_names, ++ BASE_TYPE_APMU, APMU_GPU_CLK_RES_CTRL, ++ 12, 3, BIT(15), ++ 18, 3, ++ BIT(4), BIT(4), 0x0, ++ 0); ++ ++static const char * const emmc_parent_names[] = { ++ "pll1_d6_409p6", "pll1_d4_614p4", "pll1_d52_47p26", "pll1_d3_819p2" ++}; ++ ++static SPACEMIT_CCU_DIV_FC_MUX_GATE(emmc_clk, "emmc_clk", emmc_parent_names, ++ BASE_TYPE_APMU, APMU_PMUA_EM_CLK_RES_CTRL, ++ 8, 3, BIT(11), ++ 6, 2, ++ 0x18, 0x18, 0x0, ++ 0); ++ ++static SPACEMIT_CCU_DIV_GATE(emmc_x_clk, "emmc_x_clk", "pll1_d2_1228p8", ++ BASE_TYPE_APMU, APMU_PMUA_EM_CLK_RES_CTRL, ++ 12, 3, BIT(15), BIT(15), 0x0, ++ 0); ++ ++static const char * const audio_parent_names[] = { ++ "pll1_aud_245p7", "pll1_d8_307p2", "pll1_d6_409p6" ++}; ++ ++static SPACEMIT_CCU_DIV_FC_MUX_GATE(audio_clk, "audio_clk", audio_parent_names, ++ BASE_TYPE_APMU, APMU_AUDIO_CLK_RES_CTRL, ++ 4, 3, BIT(15), ++ 7, 3, ++ BIT(12), BIT(12), 0x0, ++ 0); ++ ++static const char * const hdmi_parent_names[] = { ++ "pll1_d6_409p6", "pll1_d5_491p52", "pll1_d4_614p4", "pll1_d8_307p2" ++}; ++ ++static SPACEMIT_CCU_DIV_FC_MUX_GATE(hdmi_mclk, "hdmi_mclk", hdmi_parent_names, ++ BASE_TYPE_APMU, APMU_HDMI_CLK_RES_CTRL, ++ 1, 4, BIT(29), ++ 5, 3, ++ BIT(0), BIT(0), 0x0, ++ 0); ++ ++static const char * const cci550_parent_names[] = { ++ "pll1_d5_491p52", "pll1_d4_614p4", "pll1_d3_819p2", "pll2_d3" ++}; ++ ++static SPACEMIT_CCU_DIV_FC_MUX(cci550_clk, "cci550_clk", cci550_parent_names, ++ BASE_TYPE_APMU, APMU_CCI550_CLK_CTRL, ++ 8, 3, BIT(12), ++ 0, 2, ++ 0); ++ ++static const char * const pmua_aclk_parent_names[] = { ++ "pll1_d10_245p76", "pll1_d8_307p2" ++}; ++ ++static SPACEMIT_CCU_DIV_FC_MUX(pmua_aclk, "pmua_aclk", pmua_aclk_parent_names, ++ BASE_TYPE_APMU, APMU_ACLK_CLK_CTRL, ++ 1, 2, BIT(4), ++ 0, 1, ++ 0); ++ ++static const char * const cpu_c0_hi_parent_names[] = { ++ "pll3_d2", "pll3_d1" ++}; ++ ++static SPACEMIT_CCU_MUX(cpu_c0_hi_clk, "cpu_c0_hi_clk", cpu_c0_hi_parent_names, ++ BASE_TYPE_APMU, APMU_CPU_C0_CLK_CTRL, ++ 13, 1, ++ 0); ++ ++static const char * const cpu_c0_parent_names[] = { ++ "pll1_d4_614p4", "pll1_d3_819p2", "pll1_d6_409p6", ++ "pll1_d5_491p52", "pll1_d2_1228p8", "pll3_d3", ++ "pll2_d3", "cpu_c0_hi_clk" ++}; ++ ++static SPACEMIT_CCU_MUX_FC(cpu_c0_core_clk, "cpu_c0_core_clk", ++ cpu_c0_parent_names, ++ BASE_TYPE_APMU, APMU_CPU_C0_CLK_CTRL, ++ BIT(12), ++ 0, 3, ++ 0); ++ ++static SPACEMIT_CCU_DIV(cpu_c0_ace_clk, "cpu_c0_ace_clk", "cpu_c0_core_clk", ++ BASE_TYPE_APMU, APMU_CPU_C0_CLK_CTRL, ++ 6, 3, ++ 0); ++ ++static SPACEMIT_CCU_DIV(cpu_c0_tcm_clk, "cpu_c0_tcm_clk", "cpu_c0_core_clk", ++ BASE_TYPE_APMU, APMU_CPU_C0_CLK_CTRL, ++ 9, 3, ++ 0); ++ ++static const char * const cpu_c1_hi_parent_names[] = { ++ "pll3_d2", "pll3_d1" ++}; ++ ++static SPACEMIT_CCU_MUX(cpu_c1_hi_clk, "cpu_c1_hi_clk", cpu_c1_hi_parent_names, ++ BASE_TYPE_APMU, APMU_CPU_C1_CLK_CTRL, ++ 13, 1, ++ 0); ++ ++static const char * const cpu_c1_parent_names[] = { ++ "pll1_d4_614p4", "pll1_d3_819p2", "pll1_d6_409p6", ++ "pll1_d5_491p52", "pll1_d2_1228p8", "pll3_d3", ++ "pll2_d3", "cpu_c1_hi_clk" ++}; ++ ++static SPACEMIT_CCU_MUX_FC(cpu_c1_pclk, "cpu_c1_pclk", cpu_c1_parent_names, ++ BASE_TYPE_APMU, APMU_CPU_C1_CLK_CTRL, ++ BIT(12), ++ 0, 3, ++ 0); ++ ++static SPACEMIT_CCU_DIV(cpu_c1_ace_clk, "cpu_c1_ace_clk", "cpu_c1_pclk", ++ BASE_TYPE_APMU, APMU_CPU_C1_CLK_CTRL, ++ 6, 3, ++ 0); ++ ++static SPACEMIT_CCU_GATE_NO_PARENT(pcie0_clk, "pcie0_clk", NULL, ++ BASE_TYPE_APMU, APMU_PCIE_CLK_RES_CTRL_0, ++ 0x7, 0x7, 0x0, ++ 0); ++ ++static SPACEMIT_CCU_GATE_NO_PARENT(pcie1_clk, "pcie1_clk", NULL, ++ BASE_TYPE_APMU, APMU_PCIE_CLK_RES_CTRL_1, ++ 0x7, 0x7, 0x0, ++ 0); ++ ++static SPACEMIT_CCU_GATE_NO_PARENT(pcie2_clk, "pcie2_clk", NULL, ++ BASE_TYPE_APMU, APMU_PCIE_CLK_RES_CTRL_2, ++ 0x7, 0x7, 0x0, ++ 0); ++ ++static SPACEMIT_CCU_GATE_NO_PARENT(emac0_bus_clk, "emac0_bus_clk", NULL, ++ BASE_TYPE_APMU, APMU_EMAC0_CLK_RES_CTRL, ++ BIT(0), BIT(0), 0x0, ++ 0); ++ ++static SPACEMIT_CCU_GATE(emac0_ptp_clk, "emac0_ptp_clk", "pll2_d6", ++ BASE_TYPE_APMU, APMU_EMAC0_CLK_RES_CTRL, ++ BIT(15), BIT(15), 0x0, ++ 0); ++ ++static SPACEMIT_CCU_GATE_NO_PARENT(emac1_bus_clk, "emac1_bus_clk", NULL, ++ BASE_TYPE_APMU, APMU_EMAC1_CLK_RES_CTRL, ++ BIT(0), BIT(0), 0x0, ++ 0); ++ ++static SPACEMIT_CCU_GATE(emac1_ptp_clk, "emac1_ptp_clk", "pll2_d6", ++ BASE_TYPE_APMU, APMU_EMAC1_CLK_RES_CTRL, ++ BIT(15), BIT(15), 0x0, ++ 0); ++ ++static const char * const uart1_sec_parent_names[] = { ++ "pll1_m3d128_57p6", "slow_uart1_14p74", "slow_uart2_48" ++}; ++ ++static SPACEMIT_CCU_MUX_GATE(uart1_sec_clk, "uart1_sec_clk", ++ uart1_sec_parent_names, ++ BASE_TYPE_APBC2, APBC2_UART1_CLK_RST, ++ 4, 3, 0x3, 0x3, 0x0, ++ 0); ++ ++static const char * const ssp2_sec_parent_names[] = { ++ "pll1_d384_6p4", "pll1_d192_12p8", "pll1_d96_25p6", ++ "pll1_d48_51p2", "pll1_d768_3p2", "pll1_d1536_1p6", ++ "pll1_d3072_0p8" ++}; ++ ++static SPACEMIT_CCU_MUX_GATE(ssp2_sec_clk, "ssp2_sec_clk", ++ ssp2_sec_parent_names, ++ BASE_TYPE_APBC2, APBC2_SSP2_CLK_RST, ++ 4, 3, 0x3, 0x3, 0x0, ++ 0); ++ ++static const char * const twsi3_sec_parent_names[] = { ++ "pll1_d78_31p5", "pll1_d48_51p2", "pll1_d40_61p44" ++}; ++ ++static SPACEMIT_CCU_MUX_GATE(twsi3_sec_clk, "twsi3_sec_clk", ++ twsi3_sec_parent_names, ++ BASE_TYPE_APBC2, APBC2_TWSI3_CLK_RST, ++ 4, 3, 0x3, 0x3, 0x0, ++ 0); ++ ++static SPACEMIT_CCU_GATE(rtc_sec_clk, "rtc_sec_clk", "clk_32k", ++ BASE_TYPE_APBC2, APBC2_RTC_CLK_RST, ++ 0x83, 0x83, 0x0, 0); ++ ++static const char * const timer_sec_parent_names[] = { ++ "pll1_d192_12p8", "clk_32k", "pll1_d384_6p4", "vctcxo_3", "vctcxo_1" ++}; ++ ++static SPACEMIT_CCU_MUX_GATE(timers0_sec_clk, "timers0_sec_clk", ++ timer_sec_parent_names, ++ BASE_TYPE_APBC2, APBC2_TIMERS0_CLK_RST, ++ 4, 3, 0x3, 0x3, 0x0, ++ 0); ++ ++static const char * const kpc_sec_parent_names[] = { ++ "pll1_d192_12p8", "clk_32k", "pll1_d384_6p4", "vctcxo_3", "vctcxo_1" ++}; ++ ++static SPACEMIT_CCU_MUX_GATE(kpc_sec_clk, "kpc_sec_clk", kpc_sec_parent_names, ++ BASE_TYPE_APBC2, APBC2_KPC_CLK_RST, ++ 4, 3, 0x3, 0x3, 0x0, ++ 0); ++ ++static SPACEMIT_CCU_GATE(gpio_sec_clk, "gpio_sec_clk", "vctcxo_24", ++ BASE_TYPE_APBC2, APBC2_GPIO_CLK_RST, ++ 0x3, 0x3, 0x0, ++ 0); ++ ++static const char * const apb_parent_names[] = { ++ "pll1_d96_25p6", "pll1_d48_51p2", "pll1_d96_25p6", "pll1_d24_102p4" ++}; ++ ++static SPACEMIT_CCU_MUX(apb_clk, "apb_clk", apb_parent_names, ++ BASE_TYPE_MPMU, MPMU_APBCSCR, ++ 0, 2, 0); ++ ++static const char * const rhdmi_audio_parent_names[] = { ++ "pll1_aud_24p5", "pll1_aud_245p7" ++}; ++ ++static SPACEMIT_CCU_DIV_MUX_GATE(rhdmi_audio_clk, "rhdmi_audio_clk", ++ rhdmi_audio_parent_names, ++ BASE_TYPE_RCPU, RCPU_HDMI_CLK_RST, ++ 4, 11, 16, 2, ++ 0x6, 0x6, 0x0, ++ 0); ++ ++static const char * const rcan_parent_names[] = { ++ "pll3_20", "pll3_40", "pll3_80" ++}; ++ ++static SPACEMIT_CCU_DIV_MUX_GATE(rcan_clk, "rcan_clk", rcan_parent_names, ++ BASE_TYPE_RCPU, RCPU_CAN_CLK_RST, ++ 8, 11, 4, 2, ++ BIT(1), BIT(1), 0x0, ++ 0); ++ ++static SPACEMIT_CCU_GATE_NO_PARENT(rcan_bus_clk, "rcan_bus_clk", NULL, ++ BASE_TYPE_RCPU, RCPU_CAN_CLK_RST, ++ BIT(2), BIT(2), 0x0, 0); ++ ++static const char * const rpwm_parent_names[] = { ++ "pll1_aud_245p7", "pll1_aud_24p5" ++}; ++ ++static SPACEMIT_CCU_DIV_MUX_GATE(rpwm0_clk, "rpwm0_clk", rpwm_parent_names, ++ BASE_TYPE_RCPU2, RCPU2_PWM0_CLK_RST, ++ 8, 11, 4, 2, ++ BIT(1), BIT(1), 0x0, ++ 0); ++ ++static SPACEMIT_CCU_DIV_MUX_GATE(rpwm1_clk, "rpwm1_clk", rpwm_parent_names, ++ BASE_TYPE_RCPU2, RCPU2_PWM1_CLK_RST, ++ 8, 11, 4, 2, ++ BIT(1), BIT(1), 0x0, ++ 0); ++ ++static SPACEMIT_CCU_DIV_MUX_GATE(rpwm2_clk, "rpwm2_clk", rpwm_parent_names, ++ BASE_TYPE_RCPU2, RCPU2_PWM2_CLK_RST, ++ 8, 11, 4, 2, ++ BIT(1), BIT(1), 0x0, ++ 0); ++ ++static SPACEMIT_CCU_DIV_MUX_GATE(rpwm3_clk, "rpwm3_clk", rpwm_parent_names, ++ BASE_TYPE_RCPU2, RCPU2_PWM3_CLK_RST, ++ 8, 11, 4, 2, ++ BIT(1), BIT(1), 0x0, ++ 0); ++ ++static SPACEMIT_CCU_DIV_MUX_GATE(rpwm4_clk, "rpwm4_clk", rpwm_parent_names, ++ BASE_TYPE_RCPU2, RCPU2_PWM4_CLK_RST, ++ 8, 11, 4, 2, ++ BIT(1), BIT(1), 0x0, ++ 0); ++ ++static SPACEMIT_CCU_DIV_MUX_GATE(rpwm5_clk, "rpwm5_clk", rpwm_parent_names, ++ BASE_TYPE_RCPU2, RCPU2_PWM5_CLK_RST, ++ 8, 11, 4, 2, ++ BIT(1), BIT(1), 0x0, ++ 0); ++ ++static SPACEMIT_CCU_DIV_MUX_GATE(rpwm6_clk, "rpwm6_clk", rpwm_parent_names, ++ BASE_TYPE_RCPU2, RCPU2_PWM6_CLK_RST, ++ 8, 11, 4, 2, ++ BIT(1), BIT(1), 0x0, ++ 0); ++ ++static SPACEMIT_CCU_DIV_MUX_GATE(rpwm7_clk, "rpwm7_clk", rpwm_parent_names, ++ BASE_TYPE_RCPU2, RCPU2_PWM7_CLK_RST, ++ 8, 11, 4, 2, ++ BIT(1), BIT(1), 0x0, ++ 0); ++ ++static SPACEMIT_CCU_DIV_MUX_GATE(rpwm8_clk, "rpwm8_clk", rpwm_parent_names, ++ BASE_TYPE_RCPU2, RCPU2_PWM8_CLK_RST, ++ 8, 11, 4, 2, ++ BIT(1), BIT(1), 0x0, ++ 0); ++ ++static SPACEMIT_CCU_DIV_MUX_GATE(rpwm9_clk, "rpwm9_clk", rpwm_parent_names, ++ BASE_TYPE_RCPU2, RCPU2_PWM9_CLK_RST, ++ 8, 11, 4, 2, ++ BIT(1), BIT(1), 0x0, ++ 0); ++ ++static const char * const ri2c_parent_names[] = { ++ "pll1_d40_61p44", "pll1_d96_25p6", "pll1_d192_12p8", "vctcxo_3" ++}; ++ ++static SPACEMIT_CCU_DIV_MUX_GATE(ri2c0_clk, "ri2c0_clk", ri2c_parent_names, ++ BASE_TYPE_RCPU, RCPU_I2C0_CLK_RST, ++ 8, 11, 4, 2, ++ 0x6, 0x6, 0x0, ++ 0); ++ ++static const char * const rssp0_parent_names[] = { ++ "pll1_d40_61p44", "pll1_d96_25p6", "pll1_d192_12p8", "vctcxo_3" ++}; ++ ++static SPACEMIT_CCU_DIV_MUX_GATE(rssp0_clk, "rssp0_clk", rssp0_parent_names, ++ BASE_TYPE_RCPU, RCPU_SSP0_CLK_RST, ++ 8, 11, 4, 2, ++ 0x6, 0x6, 0x0, ++ 0); ++ ++static SPACEMIT_CCU_GATE_NO_PARENT(rir_clk, "rir_clk", NULL, ++ BASE_TYPE_RCPU, RCPU_IR_CLK_RST, ++ BIT(2), BIT(2), 0x0, ++ 0); ++ ++static const char * const ruart0_parent_names[] = { ++ "pll1_aud_24p5", "pll1_aud_245p7", "vctcxo_24", "vctcxo_3" ++}; ++ ++static SPACEMIT_CCU_DIV_MUX_GATE(ruart0_clk, "ruart0_clk", ruart0_parent_names, ++ BASE_TYPE_RCPU, RCPU_UART0_CLK_RST, ++ 8, 11, 4, 2, ++ 0x6, 0x6, 0x0, ++ 0); ++ ++static const char * const ruart1_parent_names[] = { ++ "pll1_aud_24p5", "pll1_aud_245p7", "vctcxo_24", "vctcxo_3" ++}; ++ ++static SPACEMIT_CCU_DIV_MUX_GATE(ruart1_clk, "ruart1_clk", ruart1_parent_names, ++ BASE_TYPE_RCPU, RCPU_UART1_CLK_RST, ++ 8, 11, 4, 2, ++ 0x6, 0x6, 0x0, ++ 0); ++ ++static struct clk_hw_onecell_data spacemit_k1x_hw_clks = { ++ .hws = { ++ [CLK_PLL2] = &pll2.common.hw, ++ [CLK_PLL3] = &pll3.common.hw, ++ [CLK_PLL1_D2] = &pll1_d2.common.hw, ++ [CLK_PLL1_D3] = &pll1_d3.common.hw, ++ [CLK_PLL1_D4] = &pll1_d4.common.hw, ++ [CLK_PLL1_D5] = &pll1_d5.common.hw, ++ [CLK_PLL1_D6] = &pll1_d6.common.hw, ++ [CLK_PLL1_D7] = &pll1_d7.common.hw, ++ [CLK_PLL1_D8] = &pll1_d8.common.hw, ++ [CLK_PLL1_D11] = &pll1_d11_223p4.common.hw, ++ [CLK_PLL1_D13] = &pll1_d13_189.common.hw, ++ [CLK_PLL1_D23] = &pll1_d23_106p8.common.hw, ++ [CLK_PLL1_D64] = &pll1_d64_38p4.common.hw, ++ [CLK_PLL1_D10_AUD] = &pll1_aud_245p7.common.hw, ++ [CLK_PLL1_D100_AUD] = &pll1_aud_24p5.common.hw, ++ [CLK_PLL2_D1] = &pll2_d1.common.hw, ++ [CLK_PLL2_D2] = &pll2_d2.common.hw, ++ [CLK_PLL2_D3] = &pll2_d3.common.hw, ++ [CLK_PLL2_D4] = &pll2_d4.common.hw, ++ [CLK_PLL2_D5] = &pll2_d5.common.hw, ++ [CLK_PLL2_D6] = &pll2_d6.common.hw, ++ [CLK_PLL2_D7] = &pll2_d7.common.hw, ++ [CLK_PLL2_D8] = &pll2_d8.common.hw, ++ [CLK_PLL3_D1] = &pll3_d1.common.hw, ++ [CLK_PLL3_D2] = &pll3_d2.common.hw, ++ [CLK_PLL3_D3] = &pll3_d3.common.hw, ++ [CLK_PLL3_D4] = &pll3_d4.common.hw, ++ [CLK_PLL3_D5] = &pll3_d5.common.hw, ++ [CLK_PLL3_D6] = &pll3_d6.common.hw, ++ [CLK_PLL3_D7] = &pll3_d7.common.hw, ++ [CLK_PLL3_D8] = &pll3_d8.common.hw, ++ [CLK_PLL3_80] = &pll3_80.common.hw, ++ [CLK_PLL3_40] = &pll3_40.common.hw, ++ [CLK_PLL3_20] = &pll3_20.common.hw, ++ [CLK_PLL1_307P2] = &pll1_d8_307p2.common.hw, ++ [CLK_PLL1_76P8] = &pll1_d32_76p8.common.hw, ++ [CLK_PLL1_61P44] = &pll1_d40_61p44.common.hw, ++ [CLK_PLL1_153P6] = &pll1_d16_153p6.common.hw, ++ [CLK_PLL1_102P4] = &pll1_d24_102p4.common.hw, ++ [CLK_PLL1_51P2] = &pll1_d48_51p2.common.hw, ++ [CLK_PLL1_51P2_AP] = &pll1_d48_51p2_ap.common.hw, ++ [CLK_PLL1_57P6] = &pll1_m3d128_57p6.common.hw, ++ [CLK_PLL1_25P6] = &pll1_d96_25p6.common.hw, ++ [CLK_PLL1_12P8] = &pll1_d192_12p8.common.hw, ++ [CLK_PLL1_12P8_WDT] = &pll1_d192_12p8_wdt.common.hw, ++ [CLK_PLL1_6P4] = &pll1_d384_6p4.common.hw, ++ [CLK_PLL1_3P2] = &pll1_d768_3p2.common.hw, ++ [CLK_PLL1_1P6] = &pll1_d1536_1p6.common.hw, ++ [CLK_PLL1_0P8] = &pll1_d3072_0p8.common.hw, ++ [CLK_PLL1_351] = &pll1_d7_351p08.common.hw, ++ [CLK_PLL1_409P6] = &pll1_d6_409p6.common.hw, ++ [CLK_PLL1_204P8] = &pll1_d12_204p8.common.hw, ++ [CLK_PLL1_491] = &pll1_d5_491p52.common.hw, ++ [CLK_PLL1_245P76] = &pll1_d10_245p76.common.hw, ++ [CLK_PLL1_614] = &pll1_d4_614p4.common.hw, ++ [CLK_PLL1_47P26] = &pll1_d52_47p26.common.hw, ++ [CLK_PLL1_31P5] = &pll1_d78_31p5.common.hw, ++ [CLK_PLL1_819] = &pll1_d3_819p2.common.hw, ++ [CLK_PLL1_1228] = &pll1_d2_1228p8.common.hw, ++ [CLK_SLOW_UART1] = &slow_uart1_14p74.common.hw, ++ [CLK_SLOW_UART2] = &slow_uart2_48.common.hw, ++ [CLK_UART1] = &uart1_clk.common.hw, ++ [CLK_UART2] = &uart2_clk.common.hw, ++ [CLK_UART3] = &uart3_clk.common.hw, ++ [CLK_UART4] = &uart4_clk.common.hw, ++ [CLK_UART5] = &uart5_clk.common.hw, ++ [CLK_UART6] = &uart6_clk.common.hw, ++ [CLK_UART7] = &uart7_clk.common.hw, ++ [CLK_UART8] = &uart8_clk.common.hw, ++ [CLK_UART9] = &uart9_clk.common.hw, ++ [CLK_GPIO] = &gpio_clk.common.hw, ++ [CLK_PWM0] = &pwm0_clk.common.hw, ++ [CLK_PWM1] = &pwm1_clk.common.hw, ++ [CLK_PWM2] = &pwm2_clk.common.hw, ++ [CLK_PWM3] = &pwm3_clk.common.hw, ++ [CLK_PWM4] = &pwm4_clk.common.hw, ++ [CLK_PWM5] = &pwm5_clk.common.hw, ++ [CLK_PWM6] = &pwm6_clk.common.hw, ++ [CLK_PWM7] = &pwm7_clk.common.hw, ++ [CLK_PWM8] = &pwm8_clk.common.hw, ++ [CLK_PWM9] = &pwm9_clk.common.hw, ++ [CLK_PWM10] = &pwm10_clk.common.hw, ++ [CLK_PWM11] = &pwm11_clk.common.hw, ++ [CLK_PWM12] = &pwm12_clk.common.hw, ++ [CLK_PWM13] = &pwm13_clk.common.hw, ++ [CLK_PWM14] = &pwm14_clk.common.hw, ++ [CLK_PWM15] = &pwm15_clk.common.hw, ++ [CLK_PWM16] = &pwm16_clk.common.hw, ++ [CLK_PWM17] = &pwm17_clk.common.hw, ++ [CLK_PWM18] = &pwm18_clk.common.hw, ++ [CLK_PWM19] = &pwm19_clk.common.hw, ++ [CLK_SSP3] = &ssp3_clk.common.hw, ++ [CLK_RTC] = &rtc_clk.common.hw, ++ [CLK_TWSI0] = &twsi0_clk.common.hw, ++ [CLK_TWSI1] = &twsi1_clk.common.hw, ++ [CLK_TWSI2] = &twsi2_clk.common.hw, ++ [CLK_TWSI4] = &twsi4_clk.common.hw, ++ [CLK_TWSI5] = &twsi5_clk.common.hw, ++ [CLK_TWSI6] = &twsi6_clk.common.hw, ++ [CLK_TWSI7] = &twsi7_clk.common.hw, ++ [CLK_TWSI8] = &twsi8_clk.common.hw, ++ [CLK_TIMERS1] = &timers1_clk.common.hw, ++ [CLK_TIMERS2] = &timers2_clk.common.hw, ++ [CLK_AIB] = &aib_clk.common.hw, ++ [CLK_ONEWIRE] = &onewire_clk.common.hw, ++ [CLK_SSPA0] = &sspa0_clk.common.hw, ++ [CLK_SSPA1] = &sspa1_clk.common.hw, ++ [CLK_DRO] = &dro_clk.common.hw, ++ [CLK_IR] = &ir_clk.common.hw, ++ [CLK_TSEN] = &tsen_clk.common.hw, ++ [CLK_IPC_AP2AUD] = &ipc_ap2aud_clk.common.hw, ++ [CLK_CAN0] = &can0_clk.common.hw, ++ [CLK_CAN0_BUS] = &can0_bus_clk.common.hw, ++ [CLK_WDT] = &wdt_clk.common.hw, ++ [CLK_RIPC] = &ripc_clk.common.hw, ++ [CLK_JPG] = &jpg_clk.common.hw, ++ [CLK_JPF_4KAFBC] = &jpg_4kafbc_clk.common.hw, ++ [CLK_JPF_2KAFBC] = &jpg_2kafbc_clk.common.hw, ++ [CLK_CCIC2PHY] = &ccic2phy_clk.common.hw, ++ [CLK_CCIC3PHY] = &ccic3phy_clk.common.hw, ++ [CLK_CSI] = &csi_clk.common.hw, ++ [CLK_CAMM0] = &camm0_clk.common.hw, ++ [CLK_CAMM1] = &camm1_clk.common.hw, ++ [CLK_CAMM2] = &camm2_clk.common.hw, ++ [CLK_ISP_CPP] = &isp_cpp_clk.common.hw, ++ [CLK_ISP_BUS] = &isp_bus_clk.common.hw, ++ [CLK_ISP] = &isp_clk.common.hw, ++ [CLK_DPU_MCLK] = &dpu_mclk.common.hw, ++ [CLK_DPU_ESC] = &dpu_esc_clk.common.hw, ++ [CLK_DPU_BIT] = &dpu_bit_clk.common.hw, ++ [CLK_DPU_PXCLK] = &dpu_pxclk.common.hw, ++ [CLK_DPU_HCLK] = &dpu_hclk.common.hw, ++ [CLK_DPU_SPI] = &dpu_spi_clk.common.hw, ++ [CLK_DPU_SPI_HBUS] = &dpu_spi_hbus_clk.common.hw, ++ [CLK_DPU_SPIBUS] = &dpu_spi_bus_clk.common.hw, ++ [CLK_SPU_SPI_ACLK] = &dpu_spi_aclk.common.hw, ++ [CLK_V2D] = &v2d_clk.common.hw, ++ [CLK_CCIC_4X] = &ccic_4x_clk.common.hw, ++ [CLK_CCIC1PHY] = &ccic1phy_clk.common.hw, ++ [CLK_SDH_AXI] = &sdh_axi_aclk.common.hw, ++ [CLK_SDH0] = &sdh0_clk.common.hw, ++ [CLK_SDH1] = &sdh1_clk.common.hw, ++ [CLK_SDH2] = &sdh2_clk.common.hw, ++ [CLK_USB_P1] = &usb_p1_aclk.common.hw, ++ [CLK_USB_AXI] = &usb_axi_clk.common.hw, ++ [CLK_USB30] = &usb30_clk.common.hw, ++ [CLK_QSPI] = &qspi_clk.common.hw, ++ [CLK_QSPI_BUS] = &qspi_bus_clk.common.hw, ++ [CLK_DMA] = &dma_clk.common.hw, ++ [CLK_AES] = &aes_clk.common.hw, ++ [CLK_VPU] = &vpu_clk.common.hw, ++ [CLK_GPU] = &gpu_clk.common.hw, ++ [CLK_EMMC] = &emmc_clk.common.hw, ++ [CLK_EMMC_X] = &emmc_x_clk.common.hw, ++ [CLK_AUDIO] = &audio_clk.common.hw, ++ [CLK_HDMI] = &hdmi_mclk.common.hw, ++ [CLK_CCI550] = &cci550_clk.common.hw, ++ [CLK_PMUA_ACLK] = &pmua_aclk.common.hw, ++ [CLK_CPU_C0_HI] = &cpu_c0_hi_clk.common.hw, ++ [CLK_CPU_C0_CORE] = &cpu_c0_core_clk.common.hw, ++ [CLK_CPU_C0_ACE] = &cpu_c0_ace_clk.common.hw, ++ [CLK_CPU_C0_TCM] = &cpu_c0_tcm_clk.common.hw, ++ [CLK_CPU_C1_HI] = &cpu_c1_hi_clk.common.hw, ++ [CLK_CPU_C1_CORE] = &cpu_c1_pclk.common.hw, ++ [CLK_CPU_C1_ACE] = &cpu_c1_ace_clk.common.hw, ++ [CLK_PCIE0] = &pcie0_clk.common.hw, ++ [CLK_PCIE1] = &pcie1_clk.common.hw, ++ [CLK_PCIE2] = &pcie2_clk.common.hw, ++ [CLK_EMAC0_BUS] = &emac0_bus_clk.common.hw, ++ [CLK_EMAC0_PTP] = &emac0_ptp_clk.common.hw, ++ [CLK_EMAC1_BUS] = &emac1_bus_clk.common.hw, ++ [CLK_EMAC1_PTP] = &emac1_ptp_clk.common.hw, ++ [CLK_SEC_UART1] = &uart1_sec_clk.common.hw, ++ [CLK_SEC_SSP2] = &ssp2_sec_clk.common.hw, ++ [CLK_SEC_TWSI3] = &twsi3_sec_clk.common.hw, ++ [CLK_SEC_RTC] = &rtc_sec_clk.common.hw, ++ [CLK_SEC_TIMERS0] = &timers0_sec_clk.common.hw, ++ [CLK_SEC_KPC] = &kpc_sec_clk.common.hw, ++ [CLK_SEC_GPIO] = &gpio_sec_clk.common.hw, ++ [CLK_APB] = &apb_clk.common.hw, ++ [CLK_SLOW_UART] = &slow_uart.common.hw, ++ [CLK_I2S_SYSCLK] = &i2s_sysclk.common.hw, ++ [CLK_I2S_BCLK] = &i2s_bclk.common.hw, ++ [CLK_RCPU_HDMIAUDIO] = &rhdmi_audio_clk.common.hw, ++ [CLK_RCPU_CAN] = &rcan_clk.common.hw, ++ [CLK_RCPU_CAN_BUS] = &rcan_bus_clk.common.hw, ++ [CLK_RCPU_I2C0] = &ri2c0_clk.common.hw, ++ [CLK_RCPU_SSP0] = &rssp0_clk.common.hw, ++ [CLK_RCPU_IR] = &rir_clk.common.hw, ++ [CLK_RCPU_UART0] = &ruart0_clk.common.hw, ++ [CLK_RCPU_UART1] = &ruart1_clk.common.hw, ++ [CLK_DPLL1] = &dpll1.common.hw, ++ [CLK_DPLL2] = &dpll2.common.hw, ++ [CLK_DFC_LVL0] = &dfc_lvl0.common.hw, ++ [CLK_DFC_LVL1] = &dfc_lvl1.common.hw, ++ [CLK_DFC_LVL2] = &dfc_lvl2.common.hw, ++ [CLK_DFC_LVL3] = &dfc_lvl3.common.hw, ++ [CLK_DFC_LVL4] = &dfc_lvl4.common.hw, ++ [CLK_DFC_LVL5] = &dfc_lvl5.common.hw, ++ [CLK_DFC_LVL6] = &dfc_lvl6.common.hw, ++ [CLK_DFC_LVL7] = &dfc_lvl7.common.hw, ++ [CLK_DDR] = &ddr.common.hw, ++ [CLK_RCPU2_PWM0] = &rpwm0_clk.common.hw, ++ [CLK_RCPU2_PWM1] = &rpwm1_clk.common.hw, ++ [CLK_RCPU2_PWM2] = &rpwm2_clk.common.hw, ++ [CLK_RCPU2_PWM3] = &rpwm3_clk.common.hw, ++ [CLK_RCPU2_PWM4] = &rpwm4_clk.common.hw, ++ [CLK_RCPU2_PWM5] = &rpwm5_clk.common.hw, ++ [CLK_RCPU2_PWM6] = &rpwm6_clk.common.hw, ++ [CLK_RCPU2_PWM7] = &rpwm7_clk.common.hw, ++ [CLK_RCPU2_PWM8] = &rpwm8_clk.common.hw, ++ [CLK_RCPU2_PWM9] = &rpwm9_clk.common.hw, ++ }, ++ .num = CLK_MAX_NO, ++}; ++ ++static struct clk_hw_table bootup_enable_clk_table[] = { ++ {"pll1_d8_307p2", CLK_PLL1_307P2}, ++ {"pll1_d6_409p6", CLK_PLL1_409P6}, ++ {"pll1_d5_491p52", CLK_PLL1_491}, ++ {"pll1_d4_614p4", CLK_PLL1_614}, ++ {"pll1_d3_819p2", CLK_PLL1_819}, ++ {"pll1_d2_1228p8", CLK_PLL1_1228}, ++ {"pll1_d10_245p76", CLK_PLL1_245P76}, ++ {"pll1_d48_51p2", CLK_PLL1_51P2}, ++ {"pll1_d48_51p2_ap", CLK_PLL1_51P2_AP}, ++ {"pll1_d96_25p6", CLK_PLL1_25P6}, ++ {"pll3_d1", CLK_PLL3_D1}, ++ {"pll3_d2", CLK_PLL3_D2}, ++ {"pll3_d3", CLK_PLL3_D3}, ++ {"pll2_d3", CLK_PLL2_D3}, ++ {"apb_clk", CLK_APB}, ++ {"pmua_aclk", CLK_PMUA_ACLK}, ++ {"dma_clk", CLK_DMA}, ++}; ++ ++void spacemit_clocks_enable(struct clk_hw_table *tbl, int tbl_size) ++{ ++ int i; ++ struct clk *clk; ++ struct clk_hw *hw_clk; ++ ++ for (i = 0; i < tbl_size; i++) { ++ hw_clk = spacemit_k1x_hw_clks.hws[tbl[i].clk_hw_id]; ++ clk = clk_hw_get_clk(hw_clk, tbl[i].name); ++ if (!IS_ERR_OR_NULL(clk)) ++ clk_prepare_enable(clk); ++ else ++ pr_err("%s : can't find clk %s\n", ++ __func__, tbl[i].name); ++ } ++} ++ ++unsigned long spacemit_k1x_ddr_freq_tbl[MAX_FREQ_LV + 1] = {0}; ++ ++void spacemit_fill_ddr_freq_tbl(void) ++{ ++ int i; ++ struct clk *clk; ++ struct clk_hw *hw_clk; ++ ++ for (i = 0; i < ARRAY_SIZE(spacemit_k1x_ddr_freq_tbl); i++) { ++ hw_clk = spacemit_k1x_hw_clks.hws[CLK_DFC_LVL0 + i]; ++ clk = clk_hw_get_clk(hw_clk, ddr_clk_parents[i]); ++ ++ if (!IS_ERR_OR_NULL(clk)) ++ spacemit_k1x_ddr_freq_tbl[i] = clk_get_rate(clk); ++ else ++ pr_err("%s : can't find clk %s\n", ++ __func__, ddr_clk_parents[i]); ++ } ++} ++ ++int ccu_common_init(struct clk_hw *hw, struct spacemit_k1x_clk *clk_info) ++{ ++ struct ccu_common *common = hw_to_ccu_common(hw); ++ struct ccu_pll *pll = hw_to_ccu_pll(hw); ++ ++ if (!common) ++ return -1; ++ ++ common->lock = &g_cru_lock; ++ ++ switch (common->base_type) { ++ case BASE_TYPE_MPMU: ++ common->base = clk_info->mpmu_base; ++ break; ++ case BASE_TYPE_APMU: ++ common->base = clk_info->apmu_base; ++ break; ++ case BASE_TYPE_APBC: ++ common->base = clk_info->apbc_base; ++ break; ++ case BASE_TYPE_APBS: ++ common->base = clk_info->apbs_base; ++ break; ++ case BASE_TYPE_CIU: ++ common->base = clk_info->ciu_base; ++ break; ++ case BASE_TYPE_DCIU: ++ common->base = clk_info->dciu_base; ++ break; ++ case BASE_TYPE_DDRC: ++ common->base = clk_info->ddrc_base; ++ break; ++ case BASE_TYPE_AUDC: ++ common->base = clk_info->audio_ctrl_base; ++ break; ++ case BASE_TYPE_APBC2: ++ common->base = clk_info->apbc2_base; ++ break; ++ case BASE_TYPE_RCPU: ++ common->base = clk_info->rcpu_base; ++ break; ++ case BASE_TYPE_RCPU2: ++ common->base = clk_info->rcpu2_base; ++ break; ++ default: ++ common->base = clk_info->apbc_base; ++ break; ++ } ++ ++ if (common->is_pll) ++ pll->pll.lock_base = clk_info->mpmu_base; ++ ++ return 0; ++} ++ ++int spacemit_ccu_probe(struct device_node *node, ++ struct spacemit_k1x_clk *clk_info, ++ struct clk_hw_onecell_data *hw_clks) ++{ ++ int i, ret; ++ ++ for (i = 0; i < hw_clks->num; i++) { ++ struct clk_hw *hw = hw_clks->hws[i]; ++ const char *name; ++ ++ if (!hw) ++ continue; ++ if (!hw->init) ++ continue; ++ ++ ccu_common_init(hw, clk_info); ++ name = hw->init->name; ++ ++ ret = of_clk_hw_register(node, hw); ++ if (ret) { ++ pr_err("Couldn't register clock %d - %s\n", i, name); ++ goto err_clk_unreg; ++ } ++ } ++ ret = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, hw_clks); ++ if (ret) ++ goto err_clk_unreg; ++ ++ spacemit_clocks_enable(bootup_enable_clk_table, ++ ARRAY_SIZE(bootup_enable_clk_table)); ++ spacemit_fill_ddr_freq_tbl(); ++ ++ return 0; ++ ++err_clk_unreg: ++ while (--i >= 0) { ++ struct clk_hw *hw = hw_clks->hws[i]; ++ ++ if (!hw) ++ continue; ++ clk_hw_unregister(hw); ++ } ++ ++ return ret; ++} ++ ++static void spacemit_k1x_ccu_probe(struct device_node *np) ++{ ++ int ret; ++ struct spacemit_k1x_clk *clk_info; ++ struct clk_hw_onecell_data *hw_clks = &spacemit_k1x_hw_clks; ++ ++ if (of_device_is_compatible(np, "spacemit,k1x-clock")) { ++ clk_info = &k1x_clock_controller; ++ ++ clk_info->mpmu_base = of_iomap(np, 0); ++ if (!clk_info->mpmu_base) { ++ pr_err("failed to map mpmu registers\n"); ++ goto out; ++ } ++ ++ clk_info->apmu_base = of_iomap(np, 1); ++ if (!clk_info->apmu_base) { ++ pr_err("failed to map apmu registers\n"); ++ goto out; ++ } ++ ++ clk_info->apbc_base = of_iomap(np, 2); ++ if (!clk_info->apbc_base) { ++ pr_err("failed to map apbc registers\n"); ++ goto out; ++ } ++ ++ clk_info->apbs_base = of_iomap(np, 3); ++ if (!clk_info->apbs_base) { ++ pr_err("failed to map apbs registers\n"); ++ goto out; ++ } ++ ++ clk_info->ciu_base = of_iomap(np, 4); ++ if (!clk_info->ciu_base) { ++ pr_err("failed to map ciu registers\n"); ++ goto out; ++ } ++ ++ clk_info->dciu_base = of_iomap(np, 5); ++ if (!clk_info->dciu_base) { ++ pr_err("failed to map dragon ciu registers\n"); ++ goto out; ++ } ++ ++ clk_info->ddrc_base = of_iomap(np, 6); ++ if (!clk_info->ddrc_base) { ++ pr_err("failed to map ddrc registers\n"); ++ goto out; ++ } ++ ++ clk_info->apbc2_base = of_iomap(np, 7); ++ if (!clk_info->apbc2_base) { ++ pr_err("failed to map apbc2 registers\n"); ++ goto out; ++ } ++ ++ clk_info->rcpu_base = of_iomap(np, 8); ++ if (!clk_info->rcpu_base) { ++ pr_err("failed to map rcpu registers\n"); ++ goto out; ++ } ++ ++ clk_info->rcpu2_base = of_iomap(np, 9); ++ if (!clk_info->rcpu2_base) { ++ pr_err("failed to map rcpu2 registers\n"); ++ goto out; ++ } ++ } else { ++ pr_err("not spacemit,k1x-clock\n"); ++ goto out; ++ } ++ ret = spacemit_ccu_probe(np, clk_info, hw_clks); ++ if (ret) ++ return; ++out: ++ return; ++} ++ ++void *spacemit_get_ddr_freq_tbl(void) ++{ ++ return spacemit_k1x_ddr_freq_tbl; ++} ++EXPORT_SYMBOL_GPL(spacemit_get_ddr_freq_tbl); ++ ++u32 spacemit_get_ddr_freq_level(void) ++{ ++ u32 ddr_freq_lvl = 0; ++ struct clk_hw *hw = spacemit_k1x_hw_clks.hws[CLK_DDR]; ++ ++ ddr_freq_lvl = clk_hw_get_parent_index(hw); ++ ++ return ddr_freq_lvl; ++} ++EXPORT_SYMBOL_GPL(spacemit_get_ddr_freq_level); ++ ++int spacemit_set_ddr_freq_level(u32 level) ++{ ++ int ret = 0; ++ struct clk_hw *hw = spacemit_k1x_hw_clks.hws[CLK_DDR]; ++ ++ if (level < 0 || level > MAX_FREQ_LV) ++ return -EINVAL; ++ ++ ret = clk_hw_set_parent(hw, clk_hw_get_parent_by_index(hw, level)); ++ if (ret) ++ pr_err("%s : set ddr freq fail\n", __func__); ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(spacemit_set_ddr_freq_level); ++ ++CLK_OF_DECLARE(k1x_clock, "spacemit,k1x-clock", spacemit_k1x_ccu_probe); ++ +diff --git a/drivers/clk/spacemit/ccu-spacemit-k1x.h b/drivers/clk/spacemit/ccu-spacemit-k1x.h +new file mode 100644 +index 000000000000..2662b9e40400 +--- /dev/null ++++ b/drivers/clk/spacemit/ccu-spacemit-k1x.h +@@ -0,0 +1,81 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* Copyright (c) 2023, spacemit Corporation. */ ++ ++#ifndef _CCU_SPACEMIT_K1X_H_ ++#define _CCU_SPACEMIT_K1X_H_ ++ ++#include ++#include ++ ++enum ccu_base_type { ++ BASE_TYPE_MPMU = 0, ++ BASE_TYPE_APMU = 1, ++ BASE_TYPE_APBC = 2, ++ BASE_TYPE_APBS = 3, ++ BASE_TYPE_CIU = 4, ++ BASE_TYPE_DCIU = 5, ++ BASE_TYPE_DDRC = 6, ++ BASE_TYPE_AUDC = 7, ++ BASE_TYPE_APBC2 = 8, ++ BASE_TYPE_RCPU = 9, ++ BASE_TYPE_RCPU2 = 10, ++}; ++ ++enum { ++ CLK_DIV_TYPE_1REG_NOFC_V1 = 0, ++ CLK_DIV_TYPE_1REG_FC_V2, ++ CLK_DIV_TYPE_2REG_NOFC_V3, ++ CLK_DIV_TYPE_2REG_FC_V4, ++ CLK_DIV_TYPE_1REG_FC_DIV_V5, ++ CLK_DIV_TYPE_1REG_FC_MUX_V6, ++}; ++ ++struct ccu_common { ++ void __iomem *base; ++ enum ccu_base_type base_type; ++ u32 reg_type; ++ u32 reg_ctrl; ++ u32 reg_sel; ++ u32 reg_xtc; ++ u32 fc; ++ bool is_pll; ++ const char *name; ++ const struct clk_ops *ops; ++ const char * const *parent_names; ++ u8 num_parents; ++ unsigned long flags; ++ spinlock_t *lock; ++ struct clk_hw hw; ++}; ++ ++struct spacemit_k1x_clk { ++ void __iomem *mpmu_base; ++ void __iomem *apmu_base; ++ void __iomem *apbc_base; ++ void __iomem *apbs_base; ++ void __iomem *ciu_base; ++ void __iomem *dciu_base; ++ void __iomem *ddrc_base; ++ void __iomem *audio_ctrl_base; ++ void __iomem *apbc2_base; ++ void __iomem *rcpu_base; ++ void __iomem *rcpu2_base; ++}; ++ ++struct clk_hw_table { ++ char *name; ++ u32 clk_hw_id; ++}; ++ ++extern spinlock_t g_cru_lock; ++ ++static inline struct ccu_common *hw_to_ccu_common(struct clk_hw *hw) ++{ ++ return container_of(hw, struct ccu_common, hw); ++} ++ ++int spacemit_ccu_probe(struct device_node *node, ++ struct spacemit_k1x_clk *clk_info, ++ struct clk_hw_onecell_data *desc); ++ ++#endif /* _CCU_SPACEMIT_K1X_H_ */ +diff --git a/drivers/clk/spacemit/ccu_ddn.c b/drivers/clk/spacemit/ccu_ddn.c +new file mode 100644 +index 000000000000..a23d9dad8e32 +--- /dev/null ++++ b/drivers/clk/spacemit/ccu_ddn.c +@@ -0,0 +1,161 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Spacemit clock type ddn ++ * ++ * Copyright (c) 2023, spacemit Corporation. ++ * ++ */ ++ ++#include ++#include ++#include "ccu_ddn.h" ++ ++/* ++ * It is M/N clock ++ * ++ * Fout from synthesizer can be given from two equations: ++ * numerator/denominator = Fin / (Fout * factor) ++ */ ++ ++static void ccu_ddn_disable(struct clk_hw *hw) ++{ ++ struct ccu_ddn *ddn = hw_to_ccu_ddn(hw); ++ struct ccu_common *common = &ddn->common; ++ unsigned long flags; ++ u32 reg; ++ ++ if (!ddn->gate) ++ return; ++ ++ spin_lock_irqsave(common->lock, flags); ++ reg = readl(common->base + common->reg_sel); ++ writel(reg & ~ddn->gate, common->base + common->reg_sel); ++ spin_unlock_irqrestore(common->lock, flags); ++} ++ ++static int ccu_ddn_enable(struct clk_hw *hw) ++{ ++ struct ccu_ddn *ddn = hw_to_ccu_ddn(hw); ++ struct ccu_common *common = &ddn->common; ++ unsigned long flags; ++ u32 reg; ++ ++ if (!ddn->gate) ++ return 0; ++ ++ spin_lock_irqsave(common->lock, flags); ++ reg = readl(common->base + common->reg_sel); ++ writel(reg | ddn->gate, common->base + common->reg_sel); ++ spin_unlock_irqrestore(common->lock, flags); ++ ++ return 0; ++} ++ ++static int ccu_ddn_is_enabled(struct clk_hw *hw) ++{ ++ struct ccu_ddn *ddn = hw_to_ccu_ddn(hw); ++ struct ccu_common *common = &ddn->common; ++ ++ if (!ddn->gate) ++ return 1; ++ ++ return readl(common->base + common->reg_sel) & ddn->gate; ++} ++ ++static long clk_ddn_round_rate(struct clk_hw *hw, unsigned long drate, ++ unsigned long *prate) ++{ ++ struct ccu_ddn *ddn = hw_to_ccu_ddn(hw); ++ struct ccu_ddn_config *params = &ddn->ddn; ++ unsigned long rate = 0, prev_rate; ++ unsigned long result; ++ int i; ++ ++ for (i = 0; i < params->tbl_size; i++) { ++ prev_rate = rate; ++ rate = (((*prate / 10000) * params->tbl[i].den) / ++ (params->tbl[i].num * params->info->factor)) * 10000; ++ if (rate > drate) ++ break; ++ } ++ ++ if (i == 0 || i == params->tbl_size) { ++ result = rate; ++ } else { ++ if ((drate - prev_rate) > (rate - drate)) ++ result = rate; ++ else ++ result = prev_rate; ++ } ++ return result; ++} ++ ++static unsigned long clk_ddn_recalc_rate(struct clk_hw *hw, ++ unsigned long parent_rate) ++{ ++ struct ccu_ddn *ddn = hw_to_ccu_ddn(hw); ++ struct ccu_ddn_config *params = &ddn->ddn; ++ unsigned int val, num, den; ++ unsigned long rate; ++ ++ val = readl(ddn->common.base + ddn->common.reg_ctrl); ++ num = (val >> params->info->num_shift) & params->info->num_mask; ++ den = (val >> params->info->den_shift) & params->info->den_mask; ++ if (!den) ++ return 0; ++ ++ rate = (((parent_rate / 10000) * den) / ++ (num * params->info->factor)) * 10000; ++ ++ return rate; ++} ++ ++/* Configures new clock rate*/ ++static int clk_ddn_set_rate(struct clk_hw *hw, unsigned long drate, ++ unsigned long prate) ++{ ++ struct ccu_ddn *ddn = hw_to_ccu_ddn(hw); ++ struct ccu_ddn_config *params = &ddn->ddn; ++ int i; ++ unsigned long val; ++ unsigned long prev_rate, rate = 0; ++ unsigned long flags = 0; ++ ++ for (i = 0; i < params->tbl_size; i++) { ++ prev_rate = rate; ++ rate = (((prate / 10000) * params->tbl[i].den) / ++ (params->tbl[i].num * params->info->factor)) * 10000; ++ if (rate > drate) ++ break; ++ } ++ ++ if (i > 0) ++ i--; ++ ++ if (ddn->common.lock) ++ spin_lock_irqsave(ddn->common.lock, flags); ++ ++ val = readl(ddn->common.base + ddn->common.reg_ctrl); ++ val &= ~(params->info->num_mask << params->info->num_shift); ++ val |= (params->tbl[i].num & params->info->num_mask) ++ << params->info->num_shift; ++ val &= ~(params->info->den_mask << params->info->den_shift); ++ val |= (params->tbl[i].den & params->info->den_mask) ++ << params->info->den_shift; ++ writel(val, ddn->common.base + ddn->common.reg_ctrl); ++ ++ if (ddn->common.lock) ++ spin_unlock_irqrestore(ddn->common.lock, flags); ++ ++ return 0; ++} ++ ++const struct clk_ops ccu_ddn_ops = { ++ .disable = ccu_ddn_disable, ++ .enable = ccu_ddn_enable, ++ .is_enabled = ccu_ddn_is_enabled, ++ .recalc_rate = clk_ddn_recalc_rate, ++ .round_rate = clk_ddn_round_rate, ++ .set_rate = clk_ddn_set_rate, ++}; ++ +diff --git a/drivers/clk/spacemit/ccu_ddn.h b/drivers/clk/spacemit/ccu_ddn.h +new file mode 100644 +index 000000000000..577f25250a11 +--- /dev/null ++++ b/drivers/clk/spacemit/ccu_ddn.h +@@ -0,0 +1,86 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* Copyright (c) 2023, spacemit Corporation. */ ++ ++#ifndef _CCU_DDN_H_ ++#define _CCU_DDN_H_ ++ ++#include ++#include ++ ++#include "ccu-spacemit-k1x.h" ++ ++struct ccu_ddn_tbl { ++ unsigned int num; ++ unsigned int den; ++}; ++ ++struct ccu_ddn_info { ++ unsigned int factor; ++ unsigned int num_mask; ++ unsigned int den_mask; ++ unsigned int num_shift; ++ unsigned int den_shift; ++}; ++ ++struct ccu_ddn_config { ++ struct ccu_ddn_info *info; ++ struct ccu_ddn_tbl *tbl; ++ u32 tbl_size; ++}; ++ ++#define PLL_DDN_TBL(_num, _den) \ ++ { \ ++ .num = (_num), \ ++ .den = (_den), \ ++ } ++ ++struct ccu_ddn { ++ u32 gate; ++ struct ccu_ddn_config ddn; ++ struct ccu_common common; ++}; ++ ++#define _SPACEMIT_CCU_DDN_CONFIG(_info, _table, _size) \ ++ { \ ++ .info = (struct ccu_ddn_info *)_info, \ ++ .tbl = (struct ccu_ddn_tbl *)_table, \ ++ .tbl_size = _size, \ ++ } ++ ++#define SPACEMIT_CCU_DDN(_struct, _name, _parent, _info, _table, \ ++ _size, _base_type, _reg_ctrl, _flags) \ ++ struct ccu_ddn _struct = { \ ++ .ddn = _SPACEMIT_CCU_DDN_CONFIG(_info, _table, _size), \ ++ .common = { \ ++ .reg_ctrl = _reg_ctrl, \ ++ .base_type = _base_type, \ ++ .hw.init = CLK_HW_INIT(_name, \ ++ _parent, &ccu_ddn_ops, _flags), \ ++ } \ ++ } ++ ++#define SPACEMIT_CCU_DDN_GATE(_struct, _name, _parent, _info, \ ++ _table, _size, _base_type, _reg_ddn, \ ++ __reg_gate, _gate_mask, _flags) \ ++ struct ccu_ddn _struct = { \ ++ .gate = _gate_mask, \ ++ .ddn = _SPACEMIT_CCU_DDN_CONFIG(_info, _table, _size), \ ++ .common = { \ ++ .reg_ctrl = _reg_ddn, \ ++ .reg_sel = __reg_gate, \ ++ .base_type = _base_type, \ ++ .hw.init = CLK_HW_INIT(_name, \ ++ _parent, &ccu_ddn_ops, _flags), \ ++ } \ ++ } ++ ++static inline struct ccu_ddn *hw_to_ccu_ddn(struct clk_hw *hw) ++{ ++ struct ccu_common *common = hw_to_ccu_common(hw); ++ ++ return container_of(common, struct ccu_ddn, common); ++} ++ ++extern const struct clk_ops ccu_ddn_ops; ++ ++#endif +diff --git a/drivers/clk/spacemit/ccu_ddr.c b/drivers/clk/spacemit/ccu_ddr.c +new file mode 100644 +index 000000000000..ffd8650a6e79 +--- /dev/null ++++ b/drivers/clk/spacemit/ccu_ddr.c +@@ -0,0 +1,272 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Spacemit clock type ddr ++ * ++ * Copyright (c) 2023, spacemit Corporation. ++ * ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include "ccu_ddr.h" ++ ++#define PMU_AP_IMR (0x098) ++#define AP_DCLK_FC_DONE_INT_MSK BIT(15) ++#define DCLK_FC_DONE_INT_MSK BIT(4) ++ ++#define PMU_AP_ISR (0x0a0) ++#define AP_DCLK_FC_DONE_INT_STS BIT(15) ++#define DCLK_FC_DONE_INT_STS BIT(4) ++#define AP_FC_STS BIT(1) ++ ++#define DFC_AP (0x180) ++#define DFC_FREQ_LV 0x1 ++#define DFC_REQ BIT(0) ++ ++#define DFC_STATUS (0x188) ++#define DFC_CAUSE_SHIFT 0x7 ++#define DFC_STS BIT(0) ++ ++/* enable/disable ddr frequency change done interrupt */ ++static void ccu_ddr_enable_dfc_int(struct ccu_common *common, bool enable) ++{ ++ u32 val; ++ unsigned long flags; ++ ++ spin_lock_irqsave(common->lock, flags); ++ val = readl(common->base + PMU_AP_IMR); ++ if (enable) ++ val |= AP_DCLK_FC_DONE_INT_MSK; ++ else ++ val &= ~AP_DCLK_FC_DONE_INT_MSK; ++ ++ writel(val, common->base + PMU_AP_IMR); ++ spin_unlock_irqrestore(common->lock, flags); ++} ++ ++/* clear ddr frequency change done interrupt status*/ ++static void ccu_ddr_clear_dfc_int_status(struct ccu_common *common) ++{ ++ u32 val; ++ unsigned long flags; ++ ++ spin_lock_irqsave(common->lock, flags); ++ val = readl(common->base + PMU_AP_ISR); ++ val &= ~(AP_DCLK_FC_DONE_INT_STS | AP_FC_STS); ++ writel(val, common->base + PMU_AP_ISR); ++ spin_unlock_irqrestore(common->lock, flags); ++} ++ ++static int ccu_ddr_wait_freq_change_done(struct ccu_common *common) ++{ ++ int timeout = 100; ++ u32 val; ++ ++ while (--timeout) { ++ udelay(10); ++ val = readl(common->base + PMU_AP_ISR); ++ if (val & AP_DCLK_FC_DONE_INT_STS) ++ break; ++ } ++ if (!timeout) { ++ pr_err("%s: wait dfc done timeout!\n", __func__); ++ return -EBUSY; ++ } ++ return 0; ++} ++ ++static int ccu_ddr_freq_chg(struct ccu_common *common, ++ struct ccu_mux_config *mux, u8 level) ++{ ++ u32 reg; ++ u32 timeout; ++ unsigned long flags; ++ ++ if (level > MAX_FREQ_LV) { ++ pr_err("%s: invalid %d freq level\n", __func__, level); ++ return -EINVAL; ++ } ++ ++ /* check if dfc in progress */ ++ timeout = 1000; ++ while (--timeout) { ++ if (!(readl(common->base + DFC_STATUS) & DFC_STS)) ++ break; ++ udelay(10); ++ } ++ ++ if (!timeout) { ++ pr_err("%s: another dfc is in pregress. status:0x%x\n", ++ __func__, readl(common->base + DFC_STATUS)); ++ return -EBUSY; ++ } ++ ++ spin_lock_irqsave(common->lock, flags); ++ reg = readl(common->base + common->reg_sel); ++ reg &= ~GENMASK(mux->width + mux->shift - 1, mux->shift); ++ writel(reg | (level << mux->shift) | common->fc, ++ common->base + common->reg_sel); ++ spin_unlock_irqrestore(common->lock, flags); ++ ++ timeout = 1000; ++ while (--timeout) { ++ udelay(10); ++ if (!(readl(common->base + DFC_STATUS) & DFC_STS)) ++ break; ++ } ++ ++ if (!timeout) { ++ pr_err("dfc error! status:0x%x\n", ++ readl(common->base + DFC_STATUS)); ++ return -EBUSY; ++ } ++ ++ return 0; ++} ++ ++static unsigned long ccu_ddr_recalc_rate(struct clk_hw *hw, ++ unsigned long parent_rate) ++{ ++ return parent_rate; ++} ++ ++static long ccu_ddr_round_rate(struct clk_hw *hw, unsigned long rate, ++ unsigned long *prate) ++{ ++ return rate; ++} ++ ++unsigned long ccu_ddr_calc_best_rate(struct clk_hw *hw, unsigned long rate, ++ u32 *mux_val) ++{ ++ struct ccu_ddr *ddr = hw_to_ccu_ddr(hw); ++ struct ccu_common *common = &ddr->common; ++ struct clk_hw *parent; ++ unsigned long parent_rate = 0, best_rate = 0; ++ u32 i; ++ ++ for (i = 0; i < common->num_parents; i++) { ++ parent = clk_hw_get_parent_by_index(hw, i); ++ if (!parent) ++ continue; ++ parent_rate = clk_get_rate(clk_hw_get_clk(parent, ++ common->name)); ++ if (abs(parent_rate - rate) < abs(best_rate - rate)) { ++ best_rate = parent_rate; ++ *mux_val = i; ++ } ++ } ++ return best_rate; ++} ++ ++static int ccu_ddr_set_rate(struct clk_hw *hw, unsigned long rate, ++ unsigned long parent_rate) ++{ ++ struct ccu_ddr *ddr = hw_to_ccu_ddr(hw); ++ struct ccu_common *common = &ddr->common; ++ struct ccu_mux_config *mux = ddr->mux ? ddr->mux : NULL; ++ unsigned long best_rate = 0; ++ u32 cur_mux, mux_val = 0; ++ u32 reg = 0; ++ ++ if (!mux) ++ return 0; ++ ++ best_rate = ccu_ddr_calc_best_rate(hw, rate, &mux_val); ++ ++ reg = readl(common->base + common->reg_sel); ++ if (mux) { ++ cur_mux = reg >> mux->shift; ++ cur_mux &= (1 << mux->width) - 1; ++ if (cur_mux != mux_val) ++ clk_hw_set_parent(hw, clk_hw_get_parent_by_index(hw, mux_val)); ++ } ++ return 0; ++} ++ ++static u8 ccu_ddr_get_parent(struct clk_hw *hw) ++{ ++ struct ccu_ddr *ddr = hw_to_ccu_ddr(hw); ++ struct ccu_common *common = &ddr->common; ++ struct ccu_mux_config *mux = ddr->mux; ++ u32 reg; ++ u8 parent; ++ ++ if (!mux) ++ return 0; ++ ++ reg = readl(common->base + common->reg_sel); ++ ++ parent = reg >> mux->shift; ++ parent &= (1 << mux->width) - 1; ++ ++ if (mux->table) { ++ int num_parents = clk_hw_get_num_parents(&common->hw); ++ int i; ++ ++ for (i = 0; i < num_parents; i++) ++ if (mux->table[i] == parent) ++ return i; ++ } ++ return parent; ++} ++ ++static int ccu_ddr_set_parent(struct clk_hw *hw, u8 index) ++{ ++ struct ccu_ddr *ddr = hw_to_ccu_ddr(hw); ++ struct ccu_common *common = &ddr->common; ++ struct ccu_mux_config *mux = ddr->mux; ++ int ret = 0; ++ ++ if (!mux) ++ return 0; ++ ++ if (mux->table) ++ index = mux->table[index]; ++ ++ /* request change begin */ ++ ccu_ddr_enable_dfc_int(common, true); ++ ++ /* change parent*/ ++ ret = ccu_ddr_freq_chg(common, mux, index); ++ if (ret < 0) { ++ pr_err("%s: ddr_freq_chg fail. ret = %d\n", __func__, ret); ++ return ret; ++ } ++ ++ /* wait for frequency change done */ ++ ret = ccu_ddr_wait_freq_change_done(common); ++ if (ret < 0) { ++ pr_err("%s: wait_freq_change_done timeout. ret = %d\n", ++ __func__, ret); ++ return ret; ++ } ++ ccu_ddr_clear_dfc_int_status(common); ++ ccu_ddr_enable_dfc_int(common, false); ++ ++ return 0; ++} ++ ++static int ccu_ddr_determine_rate(struct clk_hw *hw, ++ struct clk_rate_request *req) ++{ ++ unsigned long best_rate = req->rate; ++ u32 mux_val = 0; ++ ++ best_rate = ccu_ddr_calc_best_rate(hw, req->rate, &mux_val); ++ req->rate = best_rate; ++ return 0; ++} ++ ++const struct clk_ops ccu_ddr_ops = { ++ .get_parent = ccu_ddr_get_parent, ++ .set_parent = ccu_ddr_set_parent, ++ .determine_rate = ccu_ddr_determine_rate, ++ .round_rate = ccu_ddr_round_rate, ++ .recalc_rate = ccu_ddr_recalc_rate, ++ .set_rate = ccu_ddr_set_rate, ++}; ++ +diff --git a/drivers/clk/spacemit/ccu_ddr.h b/drivers/clk/spacemit/ccu_ddr.h +new file mode 100644 +index 000000000000..960ca3456796 +--- /dev/null ++++ b/drivers/clk/spacemit/ccu_ddr.h +@@ -0,0 +1,44 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* Copyright (c) 2023, spacemit Corporation. */ ++ ++#ifndef _CCU_DDR_H_ ++#define _CCU_DDR_H_ ++ ++#include ++#include "ccu-spacemit-k1x.h" ++#include "ccu_mix.h" ++ ++struct ccu_ddr { ++ struct ccu_mux_config *mux; ++ struct ccu_common common; ++}; ++ ++#define MAX_FREQ_LV 7 ++ ++#define SPACEMIT_CCU_DDR_FC(_struct, _name, _parents, _base_type, \ ++ _reg, _fc, _shift, _width, _flags) \ ++ struct ccu_ddr _struct = { \ ++ .mux = CCU_MUX_INIT(_shift, _width, NULL, 0), \ ++ .common = { \ ++ .reg_sel = _reg, \ ++ .fc = _fc, \ ++ .base_type = _base_type, \ ++ .name = _name, \ ++ .parent_names = _parents, \ ++ .num_parents = ARRAY_SIZE(_parents), \ ++ .hw.init = CLK_HW_INIT_PARENTS(_name, \ ++ _parents, &ccu_ddr_ops, \ ++ (_flags) | CLK_GET_RATE_NOCACHE), \ ++ } \ ++ } ++ ++static inline struct ccu_ddr *hw_to_ccu_ddr(struct clk_hw *hw) ++{ ++ struct ccu_common *common = hw_to_ccu_common(hw); ++ ++ return container_of(common, struct ccu_ddr, common); ++} ++ ++extern const struct clk_ops ccu_ddr_ops; ++ ++#endif /* _CCU_DDR_H_ */ +diff --git a/drivers/clk/spacemit/ccu_dpll.c b/drivers/clk/spacemit/ccu_dpll.c +new file mode 100644 +index 000000000000..ff8b699e1ba2 +--- /dev/null ++++ b/drivers/clk/spacemit/ccu_dpll.c +@@ -0,0 +1,124 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Spacemit clock type pll ++ * ++ * Copyright (c) 2023, spacemit Corporation. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include "ccu_dpll.h" ++ ++#define DPLL_MIN_FREQ 1700000000 ++#define DPLL_MAX_FREQ 3400000000 ++ ++#define pll_readl(reg) readl(reg) ++#define pll_readl_pll_swcr1(p) pll_readl(p.base + p.reg_ctrl) ++#define pll_readl_pll_swcr2(p) pll_readl(p.base + p.reg_sel) ++ ++#define pll_writel(val, reg) writel(val, reg) ++#define pll_writel_pll_swcr1(val, p) pll_writel(val, p.base + p.reg_ctrl) ++#define pll_writel_pll_swcr2(val, p) pll_writel(val, p.base + p.reg_sel) ++ ++/* unified dpllx_swcr1 for dpll1~2 */ ++union dpllx_swcr1 { ++ struct { ++ unsigned int reg0:8; ++ unsigned int reg1:8; ++ unsigned int reg2:8; ++ unsigned int reg3:8; ++ } b; ++ unsigned int v; ++}; ++ ++/* unified dpllx_swcr2 for dpll1~2 */ ++union dpllx_swcr2 { ++ struct { ++ unsigned int reg4:8; ++ unsigned int reg5:8; ++ unsigned int reg6:8; ++ unsigned int reg7:8; ++ } b; ++ unsigned int v; ++}; ++ ++/* frequency unit Mhz, return pll vco freq */ ++static unsigned long __get_vco_freq(struct clk_hw *hw) ++{ ++ unsigned int reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7, size, i; ++ struct ccu_dpll_rate_tbl *freq_pll_regs_table, *pll_reg; ++ struct ccu_dpll *p = hw_to_ccu_dpll(hw); ++ union dpllx_swcr1 swcr1; ++ union dpllx_swcr2 swcr2; ++ ++ swcr1.v = pll_readl_pll_swcr1(p->common); ++ swcr2.v = pll_readl_pll_swcr2(p->common); ++ ++ reg0 = swcr1.b.reg0; ++ reg1 = swcr1.b.reg1; ++ reg2 = swcr1.b.reg2; ++ reg3 = swcr1.b.reg3; ++ reg4 = swcr2.b.reg4; ++ reg5 = swcr2.b.reg5; ++ reg6 = swcr2.b.reg6; ++ reg7 = swcr2.b.reg7; ++ ++ freq_pll_regs_table = p->dpll.rate_tbl; ++ size = p->dpll.tbl_size; ++ ++ for (i = 0; i < size; i++) { ++ pll_reg = &freq_pll_regs_table[i]; ++ if (pll_reg->reg0 == reg0 && pll_reg->reg1 == reg1 && ++ pll_reg->reg2 == reg2 && pll_reg->reg3 == reg3 && ++ pll_reg->reg4 == reg4 && pll_reg->reg5 == reg5 && ++ pll_reg->reg6 == reg6 && pll_reg->reg7 == reg7) ++ return pll_reg->rate; ++ } ++ ++ pr_err("Unknown rate for clock %s\n", __clk_get_name(hw->clk)); ++ return 0; ++} ++ ++static unsigned long ccu_dpll_recalc_rate(struct clk_hw *hw, ++ unsigned long parent_rate) ++{ ++ return __get_vco_freq(hw); ++} ++ ++static long ccu_dpll_round_rate(struct clk_hw *hw, unsigned long rate, ++ unsigned long *prate) ++{ ++ struct ccu_dpll *p = hw_to_ccu_dpll(hw); ++ unsigned long max_rate = 0; ++ unsigned int i; ++ struct ccu_dpll_config *params = &p->dpll; ++ ++ if (rate > DPLL_MAX_FREQ || rate < DPLL_MIN_FREQ) { ++ pr_err("%lu rate out of range!\n", rate); ++ return -EINVAL; ++ } ++ ++ if (params->rate_tbl) { ++ for (i = 0; i < params->tbl_size; i++) { ++ if (params->rate_tbl[i].rate <= rate) { ++ if (max_rate < params->rate_tbl[i].rate) ++ max_rate = params->rate_tbl[i].rate; ++ } ++ } ++ } else { ++ pr_err("don't find freq table for pll\n"); ++ } ++ ++ return max_rate; ++} ++ ++const struct clk_ops ccu_dpll_ops = { ++ .recalc_rate = ccu_dpll_recalc_rate, ++ .round_rate = ccu_dpll_round_rate, ++}; ++ +diff --git a/drivers/clk/spacemit/ccu_dpll.h b/drivers/clk/spacemit/ccu_dpll.h +new file mode 100644 +index 000000000000..d5632528dc1f +--- /dev/null ++++ b/drivers/clk/spacemit/ccu_dpll.h +@@ -0,0 +1,76 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* Copyright (c) 2023, spacemit Corporation. */ ++ ++#ifndef _CCU_DPLL_H_ ++#define _CCU_DPLL_H_ ++ ++#include ++#include ++#include "ccu-spacemit-k1x.h" ++ ++struct ccu_dpll_rate_tbl { ++ unsigned long long rate; ++ u32 reg0; ++ u32 reg1; ++ u32 reg2; ++ u32 reg3; ++ u32 reg4; ++ u32 reg5; ++ u32 reg6; ++ u32 reg7; ++}; ++ ++struct ccu_dpll_config { ++ struct ccu_dpll_rate_tbl *rate_tbl; ++ u32 tbl_size; ++}; ++ ++#define DPLL_RATE(_rate, _reg0, _reg1, _reg2, _reg3, _reg4, \ ++ _reg5, _reg6, _reg7) \ ++ { \ ++ .rate = (_rate), \ ++ .reg0 = (_reg0), \ ++ .reg1 = (_reg1), \ ++ .reg2 = (_reg2), \ ++ .reg3 = (_reg3), \ ++ .reg4 = (_reg4), \ ++ .reg5 = (_reg5), \ ++ .reg6 = (_reg6), \ ++ .reg7 = (_reg7), \ ++ } ++ ++struct ccu_dpll { ++ struct ccu_dpll_config dpll; ++ struct ccu_common common; ++}; ++ ++#define _SPACEMIT_CCU_DPLL_CONFIG(_table, _size) \ ++ { \ ++ .rate_tbl = (struct ccu_dpll_rate_tbl *)_table, \ ++ .tbl_size = _size, \ ++ } ++ ++#define SPACEMIT_CCU_DPLL(_struct, _name, _table, _size, _base_type, \ ++ _reg_ctrl, _reg_sel, _is_pll, _flags) \ ++ struct ccu_dpll _struct = { \ ++ .dpll = _SPACEMIT_CCU_DPLL_CONFIG(_table, _size), \ ++ .common = { \ ++ .reg_ctrl = _reg_ctrl, \ ++ .reg_sel = _reg_sel, \ ++ .base_type = _base_type, \ ++ .is_pll = 0, \ ++ .hw.init = CLK_HW_INIT_NO_PARENT(_name, \ ++ &ccu_dpll_ops, _flags), \ ++ } \ ++ } ++ ++static inline struct ccu_dpll *hw_to_ccu_dpll(struct clk_hw *hw) ++{ ++ struct ccu_common *common = hw_to_ccu_common(hw); ++ ++ return container_of(common, struct ccu_dpll, common); ++} ++ ++extern const struct clk_ops ccu_dpll_ops; ++ ++#endif +diff --git a/drivers/clk/spacemit/ccu_mix.c b/drivers/clk/spacemit/ccu_mix.c +new file mode 100644 +index 000000000000..baa341090f53 +--- /dev/null ++++ b/drivers/clk/spacemit/ccu_mix.c +@@ -0,0 +1,502 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Spacemit clock type mix(div/mux/gate/factor) ++ * ++ * Copyright (c) 2023, spacemit Corporation. ++ * ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include "ccu_mix.h" ++ ++#define TIMEOUT_LIMIT (20000) ++static int twsi8_reg_val = 0x04; ++const char *tswi8_clk_name = "twsi8_clk"; ++ ++static void ccu_mix_disable(struct clk_hw *hw) ++{ ++ struct ccu_mix *mix = hw_to_ccu_mix(hw); ++ struct ccu_common *common = &mix->common; ++ struct ccu_gate_config *gate = mix->gate; ++ unsigned long flags = 0; ++ unsigned long rate; ++ u32 tmp; ++ ++ if (!gate) ++ return; ++ ++ if (!strcmp(common->name, tswi8_clk_name)) { ++ twsi8_reg_val &= ~gate->gate_mask; ++ twsi8_reg_val |= gate->val_disable; ++ tmp = twsi8_reg_val; ++ if (common->reg_type == CLK_DIV_TYPE_2REG_NOFC_V3 || ++ common->reg_type == CLK_DIV_TYPE_2REG_FC_V4) ++ writel(tmp, common->base + common->reg_sel); ++ else ++ writel(tmp, common->base + common->reg_ctrl); ++ return; ++ } ++ ++ if (common->lock) ++ spin_lock_irqsave(common->lock, flags); ++ ++ if (common->reg_type == CLK_DIV_TYPE_2REG_NOFC_V3 || ++ common->reg_type == CLK_DIV_TYPE_2REG_FC_V4) ++ tmp = readl(common->base + common->reg_sel); ++ else ++ tmp = readl(common->base + common->reg_ctrl); ++ ++ tmp &= ~gate->gate_mask; ++ tmp |= gate->val_disable; ++ ++ if (common->reg_type == CLK_DIV_TYPE_2REG_NOFC_V3 || ++ common->reg_type == CLK_DIV_TYPE_2REG_FC_V4) ++ writel(tmp, common->base + common->reg_sel); ++ else ++ writel(tmp, common->base + common->reg_ctrl); ++ ++ if (common->lock) ++ spin_unlock_irqrestore(common->lock, flags); ++ ++ if (gate->flags & SPACEMIT_CLK_GATE_NEED_DELAY) { ++ rate = clk_hw_get_rate(&common->hw); ++ ++ if (rate == 0) ++ pr_err("clock rate of %s is 0.\n", ++ clk_hw_get_name(&common->hw)); ++ else ++ udelay(DIV_ROUND_UP(2000000, rate)); ++ } ++} ++ ++static int ccu_mix_enable(struct clk_hw *hw) ++{ ++ struct ccu_mix *mix = hw_to_ccu_mix(hw); ++ struct ccu_common *common = &mix->common; ++ struct ccu_gate_config *gate = mix->gate; ++ unsigned long flags = 0; ++ unsigned long rate; ++ u32 tmp; ++ u32 val = 0; ++ int timeout_power = 1; ++ ++ if (!gate) ++ return 0; ++ ++ if (!strcmp(common->name, tswi8_clk_name)) { ++ twsi8_reg_val &= ~gate->gate_mask; ++ twsi8_reg_val |= gate->val_enable; ++ tmp = twsi8_reg_val; ++ if (common->reg_type == CLK_DIV_TYPE_2REG_NOFC_V3 || ++ common->reg_type == CLK_DIV_TYPE_2REG_FC_V4) ++ writel(tmp, common->base + common->reg_sel); ++ else ++ writel(tmp, common->base + common->reg_ctrl); ++ return 0; ++ } ++ ++ if (common->lock) ++ spin_lock_irqsave(common->lock, flags); ++ ++ if (common->reg_type == CLK_DIV_TYPE_2REG_NOFC_V3 || ++ common->reg_type == CLK_DIV_TYPE_2REG_FC_V4) ++ tmp = readl(common->base + common->reg_sel); ++ else ++ tmp = readl(common->base + common->reg_ctrl); ++ ++ tmp &= ~gate->gate_mask; ++ tmp |= gate->val_enable; ++ ++ if (common->reg_type == CLK_DIV_TYPE_2REG_NOFC_V3 || ++ common->reg_type == CLK_DIV_TYPE_2REG_FC_V4) ++ writel(tmp, common->base + common->reg_sel); ++ else ++ writel(tmp, common->base + common->reg_ctrl); ++ ++ if (common->reg_type == CLK_DIV_TYPE_2REG_NOFC_V3 || ++ common->reg_type == CLK_DIV_TYPE_2REG_FC_V4) ++ val = readl(common->base + common->reg_sel); ++ else ++ val = readl(common->base + common->reg_ctrl); ++ ++ if (common->lock) ++ spin_unlock_irqrestore(common->lock, flags); ++ ++ while ((val & gate->gate_mask) != gate->val_enable && ++ (timeout_power < TIMEOUT_LIMIT)) { ++ udelay(timeout_power); ++ if (common->reg_type == CLK_DIV_TYPE_2REG_NOFC_V3 || ++ common->reg_type == CLK_DIV_TYPE_2REG_FC_V4) ++ val = readl(common->base + common->reg_sel); ++ else ++ val = readl(common->base + common->reg_ctrl); ++ timeout_power *= 10; ++ } ++ ++ if (timeout_power > 1) { ++ if (val == tmp) ++ pr_err("write clk_gate %s timeout occur, read pass after %d us delay\n", ++ clk_hw_get_name(&common->hw), timeout_power); ++ else ++ pr_err("write clk_gate %s timeout after %d us!\n", ++ clk_hw_get_name(&common->hw), timeout_power); ++ } ++ ++ if (gate->flags & SPACEMIT_CLK_GATE_NEED_DELAY) { ++ rate = clk_hw_get_rate(&common->hw); ++ ++ if (rate == 0) ++ pr_err("clock rate of %s is 0.\n", ++ clk_hw_get_name(&common->hw)); ++ else ++ udelay(DIV_ROUND_UP(2000000, rate)); ++ } ++ ++ return 0; ++} ++ ++static int ccu_mix_is_enabled(struct clk_hw *hw) ++{ ++ struct ccu_mix *mix = hw_to_ccu_mix(hw); ++ struct ccu_common *common = &mix->common; ++ struct ccu_gate_config *gate = mix->gate; ++ unsigned long flags = 0; ++ u32 tmp; ++ ++ if (!gate) ++ return 1; ++ ++ if (!strcmp(common->name, tswi8_clk_name)) ++ return (twsi8_reg_val & gate->gate_mask) == gate->val_enable; ++ ++ if (common->lock) ++ spin_lock_irqsave(common->lock, flags); ++ ++ if (common->reg_type == CLK_DIV_TYPE_2REG_NOFC_V3 || ++ common->reg_type == CLK_DIV_TYPE_2REG_FC_V4) ++ tmp = readl(common->base + common->reg_sel); ++ else ++ tmp = readl(common->base + common->reg_ctrl); ++ ++ if (common->lock) ++ spin_unlock_irqrestore(common->lock, flags); ++ ++ return (tmp & gate->gate_mask) == gate->val_enable; ++} ++ ++static unsigned long ccu_mix_recalc_rate(struct clk_hw *hw, ++ unsigned long parent_rate) ++{ ++ struct ccu_mix *mix = hw_to_ccu_mix(hw); ++ struct ccu_common *common = &mix->common; ++ struct ccu_div_config *div = mix->div; ++ unsigned long val; ++ u32 reg; ++ ++ if (!div) { ++ if (mix->factor) ++ parent_rate = parent_rate * mix->factor->mul / mix->factor->div; ++ return parent_rate; ++ } ++ ++ if (common->reg_type == CLK_DIV_TYPE_2REG_NOFC_V3 || ++ common->reg_type == CLK_DIV_TYPE_2REG_FC_V4) ++ reg = readl(common->base + common->reg_sel); ++ else ++ reg = readl(common->base + common->reg_ctrl); ++ ++ val = reg >> div->shift; ++ val &= (1 << div->width) - 1; ++ ++ val = divider_recalc_rate(hw, parent_rate, val, div->table, ++ div->flags, div->width); ++ ++ return val; ++} ++ ++static int ccu_mix_trigger_fc(struct clk_hw *hw) ++{ ++ struct ccu_mix *mix = hw_to_ccu_mix(hw); ++ struct ccu_common *common = &mix->common; ++ unsigned long val = 0; ++ ++ int ret = 0, timeout = 50; ++ ++ if (common->reg_type == CLK_DIV_TYPE_1REG_FC_V2 || ++ common->reg_type == CLK_DIV_TYPE_2REG_FC_V4 || ++ common->reg_type == CLK_DIV_TYPE_1REG_FC_DIV_V5 || ++ common->reg_type == CLK_DIV_TYPE_1REG_FC_MUX_V6) { ++ timeout = 50; ++ val = readl(common->base + common->reg_ctrl); ++ val |= common->fc; ++ writel(val, common->base + common->reg_ctrl); ++ ++ do { ++ val = readl(common->base + common->reg_ctrl); ++ timeout--; ++ if (!(val & common->fc)) ++ break; ++ } while (timeout); ++ ++ if (timeout == 0) { ++ timeout = 5000; ++ do { ++ val = readl(common->base + common->reg_ctrl); ++ timeout--; ++ if (!(val & common->fc)) ++ break; ++ } while (timeout); ++ if (timeout != 0) ++ ret = 0; ++ else ++ ret = -1; ++ } ++ } ++ ++ return ret; ++} ++ ++static long ccu_mix_round_rate(struct clk_hw *hw, unsigned long rate, ++ unsigned long *prate) ++{ ++ return rate; ++} ++ ++unsigned long ccu_mix_calc_best_rate(struct clk_hw *hw, ++ unsigned long rate, u32 *mux_val, ++ u32 *div_val) ++{ ++ struct ccu_mix *mix = hw_to_ccu_mix(hw); ++ struct ccu_common *common = &mix->common; ++ struct ccu_div_config *div = mix->div ? mix->div : NULL; ++ struct clk *clk; ++ struct clk_hw *parent; ++ unsigned long parent_rate = 0, best_rate = 0; ++ u32 i, j, div_max; ++ ++ for (i = 0; i < common->num_parents; i++) { ++ parent = clk_hw_get_parent_by_index(hw, i); ++ if (!parent) ++ continue; ++ clk = clk_hw_get_clk(parent, common->name); ++ parent_rate = clk_get_rate(clk); ++ ++ if (div) ++ div_max = 1 << div->width; ++ else ++ div_max = 1; ++ ++ for (j = 1; j <= div_max; j++) { ++ if (abs(parent_rate / j - rate) ++ < abs(best_rate - rate)) { ++ best_rate = DIV_ROUND_UP_ULL(parent_rate, j); ++ *mux_val = i; ++ *div_val = j - 1; ++ } ++ } ++ } ++ ++ return best_rate; ++} ++ ++static int ccu_mix_determine_rate(struct clk_hw *hw, ++ struct clk_rate_request *req) ++{ ++ return 0; ++} ++ ++static int ccu_mix_set_rate(struct clk_hw *hw, unsigned long rate, ++ unsigned long parent_rate) ++{ ++ struct ccu_mix *mix = hw_to_ccu_mix(hw); ++ struct ccu_common *common = &mix->common; ++ struct ccu_div_config *div = mix->div ? mix->div : NULL; ++ struct ccu_mux_config *mux = mix->mux ? mix->mux : NULL; ++ struct clk_hw *parent; ++ unsigned long best_rate = 0; ++ unsigned long flags; ++ u32 cur_mux, cur_div, mux_val = 0, div_val = 0; ++ u32 reg = 0; ++ int ret = 0; ++ ++ if (!div && !mux) ++ return 0; ++ ++ best_rate = ccu_mix_calc_best_rate(hw, rate, &mux_val, &div_val); ++ if (!strcmp(common->name, tswi8_clk_name)) { ++ if (mux) { ++ cur_mux = twsi8_reg_val >> mux->shift; ++ cur_mux &= (1 << mux->width) - 1; ++ parent = clk_hw_get_parent_by_index(hw, mux_val); ++ if (cur_mux != mux_val) ++ clk_hw_set_parent(hw, parent); ++ } ++ return 0; ++ } ++ if (common->reg_type == CLK_DIV_TYPE_2REG_NOFC_V3 || ++ common->reg_type == CLK_DIV_TYPE_2REG_FC_V4) ++ reg = readl(common->base + common->reg_sel); ++ else ++ reg = readl(common->base + common->reg_ctrl); ++ ++ if (mux) { ++ cur_mux = reg >> mux->shift; ++ cur_mux &= (1 << mux->width) - 1; ++ parent = clk_hw_get_parent_by_index(hw, mux_val); ++ if (cur_mux != mux_val) ++ clk_hw_set_parent(hw, parent); ++ } ++ ++ if (div) { ++ cur_div = reg >> div->shift; ++ cur_div &= (1 << div->width) - 1; ++ if (cur_div == div_val) ++ return 0; ++ } else { ++ return 0; ++ } ++ ++ spin_lock_irqsave(common->lock, flags); ++ if (common->reg_type == CLK_DIV_TYPE_2REG_NOFC_V3 || ++ common->reg_type == CLK_DIV_TYPE_2REG_FC_V4) ++ reg = readl(common->base + common->reg_sel); ++ else ++ reg = readl(common->base + common->reg_ctrl); ++ ++ reg &= ~GENMASK(div->width + div->shift - 1, div->shift); ++ ++ if (common->reg_type == CLK_DIV_TYPE_2REG_NOFC_V3 || ++ common->reg_type == CLK_DIV_TYPE_2REG_FC_V4) ++ writel(reg | (div_val << div->shift), ++ common->base + common->reg_sel); ++ else ++ writel(reg | (div_val << div->shift), ++ common->base + common->reg_ctrl); ++ ++ if (common->reg_type == CLK_DIV_TYPE_1REG_FC_V2 || ++ common->reg_type == CLK_DIV_TYPE_2REG_FC_V4 || ++ common->reg_type == CLK_DIV_TYPE_1REG_FC_DIV_V5) { ++ ret = ccu_mix_trigger_fc(hw); ++ } ++ spin_unlock_irqrestore(common->lock, flags); ++ ++ if (ret) ++ pr_err("%s of %s timeout\n", __func__, ++ clk_hw_get_name(&common->hw)); ++ ++ return ret; ++} ++ ++static u8 ccu_mix_get_parent(struct clk_hw *hw) ++{ ++ struct ccu_mix *mix = hw_to_ccu_mix(hw); ++ struct ccu_common *common = &mix->common; ++ struct ccu_mux_config *mux = mix->mux; ++ u32 reg; ++ u8 parent; ++ ++ if (!mux) ++ return 0; ++ ++ if (!strcmp(common->name, tswi8_clk_name)) { ++ parent = twsi8_reg_val >> mux->shift; ++ parent &= (1 << mux->width) - 1; ++ return parent; ++ } ++ ++ if (common->reg_type == CLK_DIV_TYPE_2REG_NOFC_V3 || ++ common->reg_type == CLK_DIV_TYPE_2REG_FC_V4) ++ reg = readl(common->base + common->reg_sel); ++ else ++ reg = readl(common->base + common->reg_ctrl); ++ ++ parent = reg >> mux->shift; ++ parent &= (1 << mux->width) - 1; ++ ++ if (mux->table) { ++ int num_parents = clk_hw_get_num_parents(&common->hw); ++ int i; ++ ++ for (i = 0; i < num_parents; i++) ++ if (mux->table[i] == parent) ++ return i; ++ } ++ return parent; ++} ++ ++static int ccu_mix_set_parent(struct clk_hw *hw, u8 index) ++{ ++ struct ccu_mix *mix = hw_to_ccu_mix(hw); ++ struct ccu_common *common = &mix->common; ++ struct ccu_mux_config *mux = mix->mux; ++ unsigned long flags; ++ u32 reg = 0; ++ int ret = 0; ++ ++ if (!mux) ++ return 0; ++ ++ if (mux->table) ++ index = mux->table[index]; ++ ++ if (!strcmp(common->name, tswi8_clk_name)) { ++ twsi8_reg_val &= ~GENMASK(mux->width ++ + mux->shift - 1, mux->shift); ++ twsi8_reg_val |= (index << mux->shift); ++ reg = twsi8_reg_val; ++ if (common->reg_type == CLK_DIV_TYPE_2REG_NOFC_V3 || ++ common->reg_type == CLK_DIV_TYPE_2REG_FC_V4) ++ writel(reg, common->base + common->reg_sel); ++ else ++ writel(reg, common->base + common->reg_ctrl); ++ return 0; ++ } ++ ++ spin_lock_irqsave(common->lock, flags); ++ ++ if (common->reg_type == CLK_DIV_TYPE_2REG_NOFC_V3 || ++ common->reg_type == CLK_DIV_TYPE_2REG_FC_V4) ++ reg = readl(common->base + common->reg_sel); ++ else ++ reg = readl(common->base + common->reg_ctrl); ++ ++ reg &= ~GENMASK(mux->width + mux->shift - 1, mux->shift); ++ ++ if (common->reg_type == CLK_DIV_TYPE_2REG_NOFC_V3 || ++ common->reg_type == CLK_DIV_TYPE_2REG_FC_V4) ++ writel(reg | (index << mux->shift), ++ common->base + common->reg_sel); ++ else ++ writel(reg | (index << mux->shift), ++ common->base + common->reg_ctrl); ++ ++ if (common->reg_type == CLK_DIV_TYPE_1REG_FC_V2 || ++ common->reg_type == CLK_DIV_TYPE_2REG_FC_V4 || ++ common->reg_type == CLK_DIV_TYPE_1REG_FC_MUX_V6) { ++ ret = ccu_mix_trigger_fc(hw); ++ } ++ spin_unlock_irqrestore(common->lock, flags); ++ ++ if (ret) ++ pr_err("%s of %s timeout\n", __func__, ++ clk_hw_get_name(&common->hw)); ++ ++ return 0; ++} ++ ++const struct clk_ops ccu_mix_ops = { ++ .disable = ccu_mix_disable, ++ .enable = ccu_mix_enable, ++ .is_enabled = ccu_mix_is_enabled, ++ .get_parent = ccu_mix_get_parent, ++ .set_parent = ccu_mix_set_parent, ++ .determine_rate = ccu_mix_determine_rate, ++ .round_rate = ccu_mix_round_rate, ++ .recalc_rate = ccu_mix_recalc_rate, ++ .set_rate = ccu_mix_set_rate, ++}; ++ +diff --git a/drivers/clk/spacemit/ccu_mix.h b/drivers/clk/spacemit/ccu_mix.h +new file mode 100644 +index 000000000000..4b7d67cb0225 +--- /dev/null ++++ b/drivers/clk/spacemit/ccu_mix.h +@@ -0,0 +1,380 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* Copyright (c) 2023, spacemit Corporation. */ ++ ++#ifndef _CCU_MIX_H_ ++#define _CCU_MIX_H_ ++ ++#include ++#include "ccu-spacemit-k1x.h" ++ ++#define SPACEMIT_CLK_GATE_NEED_DELAY BIT(0) ++ ++struct ccu_gate_config { ++ u32 gate_mask; ++ u32 val_enable; ++ u32 val_disable; ++ u32 flags; ++}; ++ ++struct ccu_factor_config { ++ u32 div; ++ u32 mul; ++}; ++ ++struct ccu_mux_config { ++ u8 shift; ++ u8 width; ++ const u8 *table; ++ u32 flags; ++}; ++ ++struct ccu_div_config { ++ u8 shift; ++ u8 width; ++ u32 max; ++ u32 offset; ++ u32 flags; ++ struct clk_div_table *table; ++}; ++ ++struct ccu_mix { ++ struct ccu_gate_config *gate; ++ struct ccu_factor_config *factor; ++ struct ccu_div_config *div; ++ struct ccu_mux_config *mux; ++ struct ccu_common common; ++}; ++ ++#define CCU_GATE_INIT(_gate_mask, _val_enable, _val_disable, _flags) \ ++ (&(struct ccu_gate_config) { \ ++ .gate_mask = _gate_mask, \ ++ .val_enable = _val_enable, \ ++ .val_disable = _val_disable, \ ++ .flags = _flags, \ ++ }) ++ ++#define CCU_FACTOR_INIT(_div, _mul) \ ++ (&(struct ccu_factor_config) { \ ++ .div = _div, \ ++ .mul = _mul, \ ++ }) ++ ++#define CCU_MUX_INIT(_shift, _width, _table, _flags) \ ++ (&(struct ccu_mux_config) { \ ++ .shift = _shift, \ ++ .width = _width, \ ++ .table = _table, \ ++ .flags = _flags, \ ++ }) ++ ++#define CCU_DIV_INIT(_shift, _width, _table, _flags) \ ++ (&(struct ccu_div_config) { \ ++ .shift = _shift, \ ++ .width = _width, \ ++ .flags = _flags, \ ++ .table = _table, \ ++ }) ++ ++#define SPACEMIT_CCU_GATE(_struct, _name, _parent, _base_type, _reg, \ ++ _gate_mask, _val_enable, _val_disable, _flags) \ ++ struct ccu_mix _struct = { \ ++ .gate = CCU_GATE_INIT(_gate_mask, _val_enable, \ ++ _val_disable, 0), \ ++ .common = { \ ++ .reg_ctrl = _reg, \ ++ .base_type = _base_type, \ ++ .name = _name, \ ++ .num_parents = 1, \ ++ .hw.init = CLK_HW_INIT(_name, _parent, \ ++ &ccu_mix_ops, _flags), \ ++ } \ ++ } ++ ++#define SPACEMIT_CCU_GATE_NO_PARENT(_struct, _name, _parent, \ ++ _base_type, _reg, _gate_mask, _val_enable, \ ++ _val_disable, _flags) \ ++ struct ccu_mix _struct = { \ ++ .gate = CCU_GATE_INIT(_gate_mask, _val_enable, \ ++ _val_disable, 0), \ ++ .common = { \ ++ .reg_ctrl = _reg, \ ++ .base_type = _base_type, \ ++ .name = _name, \ ++ .num_parents = 0, \ ++ .hw.init = CLK_HW_INIT_NO_PARENT(_name, \ ++ &ccu_mix_ops, _flags), \ ++ } \ ++ } ++ ++#define SPACEMIT_CCU_FACTOR(_struct, _name, _parent, _div, _mul) \ ++ struct ccu_mix _struct = { \ ++ .factor = CCU_FACTOR_INIT(_div, _mul), \ ++ .common = { \ ++ .name = _name, \ ++ .num_parents = 1, \ ++ .hw.init = CLK_HW_INIT(_name, \ ++ _parent, &ccu_mix_ops, 0), \ ++ } \ ++ } ++ ++#define SPACEMIT_CCU_MUX(_struct, _name, _parents, _base_type, \ ++ _reg, _shift, _width, _flags) \ ++ struct ccu_mix _struct = { \ ++ .mux = CCU_MUX_INIT(_shift, _width, NULL, 0), \ ++ .common = { \ ++ .reg_ctrl = _reg, \ ++ .base_type = _base_type, \ ++ .name = _name, \ ++ .parent_names = _parents, \ ++ .num_parents = ARRAY_SIZE(_parents), \ ++ .hw.init = CLK_HW_INIT_PARENTS(_name, \ ++ _parents, &ccu_mix_ops, \ ++ (_flags) | CLK_GET_RATE_NOCACHE), \ ++ } \ ++ } ++ ++#define SPACEMIT_CCU_DIV(_struct, _name, _parent, _base_type, \ ++ _reg, _shift, _width, _flags) \ ++ struct ccu_mix _struct = { \ ++ .div = CCU_DIV_INIT(_shift, _width, NULL, 0), \ ++ .common = { \ ++ .reg_ctrl = _reg, \ ++ .base_type = _base_type, \ ++ .name = _name, \ ++ .num_parents = 1, \ ++ .hw.init = CLK_HW_INIT(_name, _parent, \ ++ &ccu_mix_ops, \ ++ (_flags) | CLK_GET_RATE_NOCACHE), \ ++ } \ ++ } ++ ++#define SPACEMIT_CCU_GATE_FACTOR(_struct, _name, _parent, _base_type, \ ++ _reg, _gate_mask, _val_enable, _val_disable, \ ++ _div, _mul, _flags) \ ++ struct ccu_mix _struct = { \ ++ .gate = CCU_GATE_INIT(_gate_mask, _val_enable, \ ++ _val_disable, 0), \ ++ .factor = CCU_FACTOR_INIT(_div, _mul), \ ++ .common = { \ ++ .reg_ctrl = _reg, \ ++ .base_type = _base_type, \ ++ .name = _name, \ ++ .num_parents = 1, \ ++ .hw.init = CLK_HW_INIT(_name, _parent, \ ++ &ccu_mix_ops, _flags), \ ++ } \ ++ } ++ ++#define SPACEMIT_CCU_MUX_GATE(_struct, _name, _parents, _base_type, \ ++ _reg, _shift, _width, _gate_mask, _val_enable, \ ++ _val_disable, _flags) \ ++ struct ccu_mix _struct = { \ ++ .gate = CCU_GATE_INIT(_gate_mask, _val_enable, \ ++ _val_disable, 0), \ ++ .mux = CCU_MUX_INIT(_shift, _width, NULL, 0), \ ++ .common = { \ ++ .reg_ctrl = _reg, \ ++ .base_type = _base_type, \ ++ .name = _name, \ ++ .parent_names = _parents, \ ++ .num_parents = ARRAY_SIZE(_parents), \ ++ .hw.init = CLK_HW_INIT_PARENTS(_name, \ ++ _parents, &ccu_mix_ops, \ ++ (_flags) | CLK_GET_RATE_NOCACHE), \ ++ } \ ++ } ++ ++#define SPACEMIT_CCU_DIV_GATE(_struct, _name, _parent, _base_type, \ ++ _reg, _shift, _width, _gate_mask, _val_enable, \ ++ _val_disable, _flags) \ ++ struct ccu_mix _struct = { \ ++ .gate = CCU_GATE_INIT(_gate_mask, _val_enable, \ ++ _val_disable, 0), \ ++ .div = CCU_DIV_INIT(_shift, _width, NULL, 0), \ ++ .common = { \ ++ .reg_ctrl = _reg, \ ++ .base_type = _base_type, \ ++ .name = _name, \ ++ .num_parents = 1, \ ++ .hw.init = CLK_HW_INIT(_name, _parent, \ ++ &ccu_mix_ops, \ ++ (_flags) | CLK_GET_RATE_NOCACHE), \ ++ } \ ++ } ++ ++#define SPACEMIT_CCU_DIV_MUX_GATE(_struct, _name, _parents, _base_type, \ ++ _reg_ctrl, _mshift, _mwidth, _muxshift, \ ++ _muxwidth, _gate_mask, _val_enable, \ ++ _val_disable, _flags) \ ++ struct ccu_mix _struct = { \ ++ .gate = CCU_GATE_INIT(_gate_mask, _val_enable, \ ++ _val_disable, 0), \ ++ .div = CCU_DIV_INIT(_mshift, _mwidth, NULL, 0), \ ++ .mux = CCU_MUX_INIT(_muxshift, _muxwidth, NULL, 0), \ ++ .common = { \ ++ .reg_ctrl = _reg_ctrl, \ ++ .base_type = _base_type, \ ++ .name = _name, \ ++ .parent_names = _parents, \ ++ .num_parents = ARRAY_SIZE(_parents), \ ++ .hw.init = CLK_HW_INIT_PARENTS(_name, \ ++ _parents, &ccu_mix_ops, \ ++ (_flags) | CLK_GET_RATE_NOCACHE), \ ++ }, \ ++ } ++ ++#define SPACEMIT_CCU_DIV2_FC_MUX_GATE(_struct, _name, _parents, \ ++ _base_type, _reg_ctrl, _reg_sel, _mshift, \ ++ _mwidth, _fc, _muxshift, _muxwidth, _gate_mask, \ ++ _val_enable, _val_disable, _flags) \ ++ struct ccu_mix _struct = { \ ++ .gate = CCU_GATE_INIT(_gate_mask, _val_enable, \ ++ _val_disable, 0), \ ++ .div = CCU_DIV_INIT(_mshift, _mwidth, NULL, 0), \ ++ .mux = CCU_MUX_INIT(_muxshift, _muxwidth, NULL, 0), \ ++ .common = { \ ++ .reg_type = CLK_DIV_TYPE_2REG_FC_V4, \ ++ .reg_ctrl = _reg_ctrl, \ ++ .reg_sel = _reg_sel, \ ++ .fc = _fc, \ ++ .base_type = _base_type, \ ++ .name = _name, \ ++ .parent_names = _parents, \ ++ .num_parents = ARRAY_SIZE(_parents), \ ++ .hw.init = CLK_HW_INIT_PARENTS(_name, \ ++ _parents, &ccu_mix_ops, \ ++ (_flags) | CLK_GET_RATE_NOCACHE), \ ++ }, \ ++ } ++ ++#define SPACEMIT_CCU_DIV_FC_MUX_GATE(_struct, _name, _parents, \ ++ _base_type, _reg_ctrl, _mshift, _mwidth, _fc, \ ++ _muxshift, _muxwidth, _gate_mask, _val_enable, \ ++ _val_disable, _flags) \ ++ struct ccu_mix _struct = { \ ++ .gate = CCU_GATE_INIT(_gate_mask, _val_enable, \ ++ _val_disable, 0), \ ++ .div = CCU_DIV_INIT(_mshift, _mwidth, NULL, 0), \ ++ .mux = CCU_MUX_INIT(_muxshift, _muxwidth, NULL, 0), \ ++ .common = { \ ++ .reg_type = CLK_DIV_TYPE_1REG_FC_V2, \ ++ .reg_ctrl = _reg_ctrl, \ ++ .fc = _fc, \ ++ .base_type = _base_type, \ ++ .name = _name, \ ++ .parent_names = _parents, \ ++ .num_parents = ARRAY_SIZE(_parents), \ ++ .hw.init = CLK_HW_INIT_PARENTS(_name, \ ++ _parents, &ccu_mix_ops, \ ++ (_flags) | CLK_GET_RATE_NOCACHE), \ ++ }, \ ++ } ++ ++#define SPACEMIT_CCU_DIV_MFC_MUX_GATE(_struct, _name, _parents, _base_type, \ ++ _reg_ctrl, _mshift, _mwidth, _fc, _muxshift, \ ++ _muxwidth, _gate_mask, _val_enable, \ ++ _val_disable, _flags) \ ++ struct ccu_mix _struct = { \ ++ .gate = CCU_GATE_INIT(_gate_mask, \ ++ _val_enable, _val_disable, 0), \ ++ .div = CCU_DIV_INIT(_mshift, _mwidth, NULL, 0), \ ++ .mux = CCU_MUX_INIT(_muxshift, _muxwidth, NULL, 0), \ ++ .common = { \ ++ .reg_type = CLK_DIV_TYPE_1REG_FC_MUX_V6, \ ++ .reg_ctrl = _reg_ctrl, \ ++ .fc = _fc, \ ++ .base_type = _base_type, \ ++ .name = _name, \ ++ .parent_names = _parents, \ ++ .num_parents = ARRAY_SIZE(_parents), \ ++ .hw.init = CLK_HW_INIT_PARENTS(_name, \ ++ _parents, &ccu_mix_ops, \ ++ (_flags) | CLK_GET_RATE_NOCACHE), \ ++ }, \ ++ } ++ ++#define SPACEMIT_CCU_DIV_FC_WITH_GATE(_struct, _name, _parent, _base_type, \ ++ _reg_ctrl, _mshift, _mwidth, _fc, _gate_mask, \ ++ _val_enable, _val_disable, _flags) \ ++ struct ccu_mix _struct = { \ ++ .gate = CCU_GATE_INIT(_gate_mask, _val_enable, \ ++ _val_disable, 0), \ ++ .div = CCU_DIV_INIT(_mshift, _mwidth, NULL, 0), \ ++ .common = { \ ++ .reg_type = CLK_DIV_TYPE_1REG_FC_V2, \ ++ .reg_ctrl = _reg_ctrl, \ ++ .fc = _fc, \ ++ .base_type = _base_type, \ ++ .name = _name, \ ++ .num_parents = 1, \ ++ .hw.init = CLK_HW_INIT(_name, \ ++ _parent, &ccu_mix_ops, \ ++ (_flags) | CLK_GET_RATE_NOCACHE), \ ++ }, \ ++ } ++ ++#define SPACEMIT_CCU_DIV_MUX(_struct, _name, _parents, _base_type, \ ++ _reg_ctrl, _mshift, _mwidth, _muxshift, _muxwidth, _flags) \ ++ struct ccu_mix _struct = { \ ++ .div = CCU_DIV_INIT(_mshift, _mwidth, NULL, 0), \ ++ .mux = CCU_MUX_INIT(_muxshift, _muxwidth, NULL, 0), \ ++ .common = { \ ++ .reg_ctrl = _reg_ctrl, \ ++ .base_type = _base_type, \ ++ .name = _name, \ ++ .parent_names = _parents, \ ++ .num_parents = ARRAY_SIZE(_parents), \ ++ .hw.init = CLK_HW_INIT_PARENTS(_name, \ ++ _parents, &ccu_mix_ops, \ ++ (_flags) | CLK_GET_RATE_NOCACHE), \ ++ }, \ ++ } ++ ++#define SPACEMIT_CCU_DIV_FC_MUX(_struct, _name, _parents, _base_type, \ ++ _reg_ctrl, _mshift, _mwidth, _fc, _muxshift, \ ++ _muxwidth, _flags) \ ++ struct ccu_mix _struct = { \ ++ .div = CCU_DIV_INIT(_mshift, _mwidth, NULL, 0), \ ++ .mux = CCU_MUX_INIT(_muxshift, _muxwidth, NULL, 0), \ ++ .common = { \ ++ .reg_type = CLK_DIV_TYPE_1REG_FC_V2, \ ++ .reg_ctrl = _reg_ctrl, \ ++ .fc = _fc, \ ++ .base_type = _base_type, \ ++ .name = _name, \ ++ .parent_names = _parents, \ ++ .num_parents = ARRAY_SIZE(_parents), \ ++ .hw.init = CLK_HW_INIT_PARENTS(_name, \ ++ _parents, &ccu_mix_ops, \ ++ (_flags) | CLK_GET_RATE_NOCACHE), \ ++ }, \ ++ } ++ ++#define SPACEMIT_CCU_MUX_FC(_struct, _name, _parents, _base_type, \ ++ _reg_ctrl, _fc, _muxshift, _muxwidth, _flags) \ ++ struct ccu_mix _struct = { \ ++ .mux = CCU_MUX_INIT(_muxshift, _muxwidth, NULL, 0), \ ++ .common = { \ ++ .reg_type = CLK_DIV_TYPE_1REG_FC_V2, \ ++ .reg_ctrl = _reg_ctrl, \ ++ .fc = _fc, \ ++ .base_type = _base_type, \ ++ .name = _name, \ ++ .parent_names = _parents, \ ++ .num_parents = ARRAY_SIZE(_parents), \ ++ .hw.init = CLK_HW_INIT_PARENTS(_name, \ ++ _parents, &ccu_mix_ops, \ ++ (_flags) | CLK_GET_RATE_NOCACHE), \ ++ }, \ ++ } ++ ++static inline struct ccu_mix *hw_to_ccu_mix(struct clk_hw *hw) ++{ ++ struct ccu_common *common = hw_to_ccu_common(hw); ++ ++ return container_of(common, struct ccu_mix, common); ++} ++ ++extern const struct clk_ops ccu_mix_ops; ++ ++#endif /* _CCU_DIV_H_ */ +diff --git a/drivers/clk/spacemit/ccu_pll.c b/drivers/clk/spacemit/ccu_pll.c +new file mode 100644 +index 000000000000..9bc4d1de8b33 +--- /dev/null ++++ b/drivers/clk/spacemit/ccu_pll.c +@@ -0,0 +1,286 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Spacemit clock type pll ++ * ++ * Copyright (c) 2023, spacemit Corporation. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include "ccu_pll.h" ++ ++#define PLL_MIN_FREQ 600000000 ++#define PLL_MAX_FREQ 3400000000 ++#define PLL_DELAYTIME 590 ++ ++#define pll_readl(reg) readl(reg) ++#define pll_readl_pll_swcr1(p) pll_readl(p.base + p.reg_ctrl) ++#define pll_readl_pll_swcr2(p) pll_readl(p.base + p.reg_sel) ++#define pll_readl_pll_swcr3(p) pll_readl(p.base + p.reg_xtc) ++ ++#define pll_writel(val, reg) writel(val, reg) ++#define pll_writel_pll_swcr1(val, p) pll_writel(val, p.base + p.reg_ctrl) ++#define pll_writel_pll_swcr2(val, p) pll_writel(val, p.base + p.reg_sel) ++#define pll_writel_pll_swcr3(val, p) pll_writel(val, p.base + p.reg_xtc) ++ ++/* unified pllx_swcr1 for pll1~3 */ ++union pllx_swcr1 { ++ struct { ++ unsigned int reg5:8; ++ unsigned int reg6:8; ++ unsigned int reg7:8; ++ unsigned int reg8:8; ++ } b; ++ unsigned int v; ++}; ++ ++/* unified pllx_swcr2 for pll1~3 */ ++union pllx_swcr2 { ++ struct { ++ unsigned int div1_en:1; ++ unsigned int div2_en:1; ++ unsigned int div3_en:1; ++ unsigned int div4_en:1; ++ unsigned int div5_en:1; ++ unsigned int div6_en:1; ++ unsigned int div7_en:1; ++ unsigned int div8_en:1; ++ unsigned int reserved1:4; ++ unsigned int atest_en:1; ++ unsigned int cktest_en:1; ++ unsigned int dtest_en:1; ++ unsigned int rdo:2; ++ unsigned int mon_cfg:4; ++ unsigned int reserved2:11; ++ } b; ++ unsigned int v; ++}; ++ ++union pllx_swcr3 { ++ struct { ++ unsigned int div_frc:24; ++ unsigned int div_int:7; ++ unsigned int pll_en:1; ++ } b; ++ ++ unsigned int v; ++}; ++ ++static int ccu_pll_is_enabled(struct clk_hw *hw) ++{ ++ struct ccu_pll *p = hw_to_ccu_pll(hw); ++ union pllx_swcr3 swcr3; ++ unsigned int enabled; ++ ++ swcr3.v = pll_readl_pll_swcr3(p->common); ++ enabled = swcr3.b.pll_en; ++ ++ return enabled; ++} ++ ++static unsigned long __get_vco_freq(struct clk_hw *hw) ++{ ++ unsigned int reg5, reg6, reg7, reg8, size, i; ++ unsigned int div_int, div_frc; ++ struct ccu_pll_rate_tbl *freq_pll_regs_table, *pll_regs; ++ struct ccu_pll *p = hw_to_ccu_pll(hw); ++ union pllx_swcr1 swcr1; ++ union pllx_swcr3 swcr3; ++ ++ swcr1.v = pll_readl_pll_swcr1(p->common); ++ swcr3.v = pll_readl_pll_swcr3(p->common); ++ ++ reg5 = swcr1.b.reg5; ++ reg6 = swcr1.b.reg6; ++ reg7 = swcr1.b.reg7; ++ reg8 = swcr1.b.reg8; ++ ++ div_int = swcr3.b.div_int; ++ div_frc = swcr3.b.div_frc; ++ ++ freq_pll_regs_table = p->pll.rate_tbl; ++ size = p->pll.tbl_size; ++ ++ for (i = 0; i < size; i++) { ++ pll_regs = &freq_pll_regs_table[i]; ++ if (pll_regs->reg5 == reg5 && pll_regs->reg6 == reg6 && ++ pll_regs->reg7 == reg7 && pll_regs->reg8 == reg8 && ++ pll_regs->div_int == div_int && ++ pll_regs->div_frac == div_frc) ++ return pll_regs->rate; ++ } ++ ++ pr_err("Unknown rate for clock %s\n", __clk_get_name(hw->clk)); ++ ++ return 0; ++} ++ ++static int ccu_pll_enable(struct clk_hw *hw) ++{ ++ unsigned int delaytime = PLL_DELAYTIME; ++ unsigned long flags; ++ struct ccu_pll *p = hw_to_ccu_pll(hw); ++ union pllx_swcr3 swcr3; ++ ++ if (ccu_pll_is_enabled(hw)) ++ return 0; ++ ++ spin_lock_irqsave(p->common.lock, flags); ++ swcr3.v = pll_readl_pll_swcr3(p->common); ++ swcr3.b.pll_en = 1; ++ pll_writel_pll_swcr3(swcr3.v, p->common); ++ spin_unlock_irqrestore(p->common.lock, flags); ++ ++ /* check lock status */ ++ udelay(50); ++ ++ while ((!(readl(p->pll.lock_base + p->pll.reg_lock) ++ & p->pll.lock_enable_bit)) && delaytime) { ++ udelay(5); ++ delaytime--; ++ } ++ ++ if (unlikely(!delaytime)) { ++ pr_err("%s enabling didn't get stable within 3000us!!!\n", ++ __clk_get_name(hw->clk)); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static void ccu_pll_disable(struct clk_hw *hw) ++{ ++ unsigned long flags; ++ struct ccu_pll *p = hw_to_ccu_pll(hw); ++ union pllx_swcr3 swcr3; ++ ++ spin_lock_irqsave(p->common.lock, flags); ++ swcr3.v = pll_readl_pll_swcr3(p->common); ++ swcr3.b.pll_en = 0; ++ pll_writel_pll_swcr3(swcr3.v, p->common); ++ spin_unlock_irqrestore(p->common.lock, flags); ++} ++ ++/* ++ * pll rate change requires sequence: ++ * clock off -> change rate setting -> clock on ++ * This function doesn't really change rate, but cache the config ++ */ ++static int ccu_pll_set_rate(struct clk_hw *hw, unsigned long rate, ++ unsigned long parent_rate) ++{ ++ unsigned int i, reg5 = 0, reg6 = 0, reg7 = 0, reg8 = 0; ++ unsigned int div_int, div_frc; ++ unsigned long flags; ++ unsigned long new_rate = rate, old_rate; ++ struct ccu_pll *p = hw_to_ccu_pll(hw); ++ struct ccu_pll_config *params = &p->pll; ++ union pllx_swcr1 swcr1; ++ union pllx_swcr3 swcr3; ++ bool found = false; ++ bool pll_enabled = false; ++ ++ if (ccu_pll_is_enabled(hw)) { ++ pll_enabled = true; ++ ccu_pll_disable(hw); ++ } ++ ++ old_rate = __get_vco_freq(hw); ++ ++ /* setp 1: calculate fbd frcd kvco and band */ ++ if (params->rate_tbl) { ++ for (i = 0; i < params->tbl_size; i++) { ++ if (rate == params->rate_tbl[i].rate) { ++ found = true; ++ ++ reg5 = params->rate_tbl[i].reg5; ++ reg6 = params->rate_tbl[i].reg6; ++ reg7 = params->rate_tbl[i].reg7; ++ reg8 = params->rate_tbl[i].reg8; ++ div_int = params->rate_tbl[i].div_int; ++ div_frc = params->rate_tbl[i].div_frac; ++ break; ++ } ++ } ++ ++ WARN_ON_ONCE(!found); ++ } else { ++ pr_err("don't find freq table for pll\n"); ++ if (pll_enabled) ++ ccu_pll_enable(hw); ++ return -EINVAL; ++ } ++ ++ spin_lock_irqsave(p->common.lock, flags); ++ ++ /* setp 2: set pll kvco/band and fbd/frcd setting */ ++ swcr1.v = pll_readl_pll_swcr1(p->common); ++ swcr1.b.reg5 = reg5; ++ swcr1.b.reg6 = reg6; ++ swcr1.b.reg7 = reg7; ++ swcr1.b.reg8 = reg8; ++ pll_writel_pll_swcr1(swcr1.v, p->common); ++ ++ swcr3.v = pll_readl_pll_swcr3(p->common); ++ swcr3.b.div_int = div_int; ++ swcr3.b.div_frc = div_frc; ++ pll_writel_pll_swcr3(swcr3.v, p->common); ++ ++ spin_unlock_irqrestore(p->common.lock, flags); ++ ++ if (pll_enabled) ++ ccu_pll_enable(hw); ++ ++ pr_debug("%s %s rate %lu->%lu!\n", __func__, ++ __clk_get_name(hw->clk), old_rate, new_rate); ++ return 0; ++} ++ ++static unsigned long ccu_pll_recalc_rate(struct clk_hw *hw, ++ unsigned long parent_rate) ++{ ++ return __get_vco_freq(hw); ++} ++ ++static long ccu_pll_round_rate(struct clk_hw *hw, unsigned long rate, ++ unsigned long *prate) ++{ ++ struct ccu_pll *p = hw_to_ccu_pll(hw); ++ unsigned long max_rate = 0; ++ unsigned int i; ++ struct ccu_pll_config *params = &p->pll; ++ ++ if (rate > PLL_MAX_FREQ || rate < PLL_MIN_FREQ) { ++ pr_err("%lu rate out of range!\n", rate); ++ return -EINVAL; ++ } ++ ++ if (params->rate_tbl) { ++ for (i = 0; i < params->tbl_size; i++) { ++ if (params->rate_tbl[i].rate <= rate) { ++ if (max_rate < params->rate_tbl[i].rate) ++ max_rate = params->rate_tbl[i].rate; ++ } ++ } ++ } else { ++ pr_err("don't find freq table for pll\n"); ++ } ++ ++ return max_rate; ++} ++ ++const struct clk_ops ccu_pll_ops = { ++ .enable = ccu_pll_enable, ++ .disable = ccu_pll_disable, ++ .set_rate = ccu_pll_set_rate, ++ .recalc_rate = ccu_pll_recalc_rate, ++ .round_rate = ccu_pll_round_rate, ++ .is_enabled = ccu_pll_is_enabled, ++}; ++ +diff --git a/drivers/clk/spacemit/ccu_pll.h b/drivers/clk/spacemit/ccu_pll.h +new file mode 100644 +index 000000000000..0f6f2ed397da +--- /dev/null ++++ b/drivers/clk/spacemit/ccu_pll.h +@@ -0,0 +1,79 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* Copyright (c) 2023, spacemit Corporation. */ ++ ++#ifndef _CCU_PLL_H_ ++#define _CCU_PLL_H_ ++ ++#include ++#include ++#include "ccu-spacemit-k1x.h" ++ ++struct ccu_pll_rate_tbl { ++ unsigned long long rate; ++ u32 reg5; ++ u32 reg6; ++ u32 reg7; ++ u32 reg8; ++ unsigned int div_int; ++ unsigned int div_frac; ++}; ++ ++struct ccu_pll_config { ++ struct ccu_pll_rate_tbl *rate_tbl; ++ u32 tbl_size; ++ void __iomem *lock_base; ++ u32 reg_lock; ++ u32 lock_enable_bit; ++}; ++ ++#define PLL_RATE(_rate, _reg5, _reg6, _reg7, _reg8, _div_int, _div_frac) \ ++ { \ ++ .rate = (_rate), \ ++ .reg5 = (_reg5), \ ++ .reg6 = (_reg6), \ ++ .reg7 = (_reg7), \ ++ .reg8 = (_reg8), \ ++ .div_int = (_div_int), \ ++ .div_frac = (_div_frac), \ ++ } ++ ++struct ccu_pll { ++ struct ccu_pll_config pll; ++ struct ccu_common common; ++}; ++ ++#define _SPACEMIT_CCU_PLL_CONFIG(_table, _size, _reg_lock, _lock_enable_bit) \ ++ { \ ++ .rate_tbl = (struct ccu_pll_rate_tbl *)_table, \ ++ .tbl_size = _size, \ ++ .reg_lock = _reg_lock, \ ++ .lock_enable_bit = _lock_enable_bit, \ ++ } ++ ++#define SPACEMIT_CCU_PLL(_struct, _name, _table, _size, _base_type, \ ++ _reg_ctrl, _reg_sel, _reg_xtc, _reg_lock, \ ++ _lock_enable_bit, _is_pll, _flags) \ ++ struct ccu_pll _struct = { \ ++ .pll = _SPACEMIT_CCU_PLL_CONFIG(_table, _size, \ ++ _reg_lock, _lock_enable_bit), \ ++ .common = { \ ++ .reg_ctrl = _reg_ctrl, \ ++ .reg_sel = _reg_sel, \ ++ .reg_xtc = _reg_xtc, \ ++ .base_type = _base_type, \ ++ .is_pll = _is_pll, \ ++ .hw.init = CLK_HW_INIT_NO_PARENT(_name, \ ++ &ccu_pll_ops, _flags), \ ++ } \ ++ } ++ ++static inline struct ccu_pll *hw_to_ccu_pll(struct clk_hw *hw) ++{ ++ struct ccu_common *common = hw_to_ccu_common(hw); ++ ++ return container_of(common, struct ccu_pll, common); ++} ++ ++extern const struct clk_ops ccu_pll_ops; ++ ++#endif diff --git a/drivers/clk/xuantie/Kconfig b/drivers/clk/xuantie/Kconfig new file mode 100644 index 000000000000..9a2ee8c01bf3 @@ -27851,7 +34569,7 @@ index 000000000000..8bf7a18776f8 + return clk; +} diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig -index 6432eb93a80f..79434f69518c 100644 +index 6265e0b94f8b..8e355170ab07 100644 --- a/drivers/cpufreq/Kconfig +++ b/drivers/cpufreq/Kconfig @@ -365,5 +365,14 @@ config QORIQ_CPUFREQ @@ -28804,7 +35522,7 @@ index 834ae519c15d..f2b299c23b1e 100644 return rc; diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig -index cc4716c037a6..a8c03e495ac4 100644 +index 0f3cd1b05ae3..6e1aca97de85 100644 --- a/drivers/firmware/Kconfig +++ b/drivers/firmware/Kconfig @@ -315,5 +315,6 @@ source "drivers/firmware/psci/Kconfig" @@ -29809,6 +36527,38 @@ index 000000000000..20d216522c81 + pr_debug("th1520 proc log removed\n"); +} \ No newline at end of file +diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig +index 904b71c06eba..77d2d065a1b2 100644 +--- a/drivers/gpio/Kconfig ++++ b/drivers/gpio/Kconfig +@@ -1828,6 +1828,15 @@ config GPIO_SIM + This enables the GPIO simulator - a configfs-based GPIO testing + driver. + ++config GPIO_K1X ++ bool "Spacemit k1x GPIO support" ++ depends on PINCTRL_SPACEMIT_K1X ++ help ++ Say yes here to support the k1x GPIO device. ++ The k1x GPIO device may have several banks, and each ++ bank control at most 32 GPIO pins. The number of banks ++ is passed by device tree or platform data. ++ + endmenu + + endif +diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile +index e44a700ec7d3..06e2c4fcb6c3 100644 +--- a/drivers/gpio/Makefile ++++ b/drivers/gpio/Makefile +@@ -78,6 +78,7 @@ obj-$(CONFIG_GPIO_IMX_SCU) += gpio-imx-scu.o + obj-$(CONFIG_GPIO_IT87) += gpio-it87.o + obj-$(CONFIG_GPIO_IXP4XX) += gpio-ixp4xx.o + obj-$(CONFIG_GPIO_JANZ_TTL) += gpio-janz-ttl.o ++obj-$(CONFIG_GPIO_K1X) += gpio-k1x.o + obj-$(CONFIG_GPIO_KEMPLD) += gpio-kempld.o + obj-$(CONFIG_GPIO_LATCH) += gpio-latch.o + obj-$(CONFIG_GPIO_LJCA) += gpio-ljca.o diff --git a/drivers/gpio/gpio-dwapb.c b/drivers/gpio/gpio-dwapb.c index 6b7d47a52b10..8a63ff1e5f73 100644 --- a/drivers/gpio/gpio-dwapb.c @@ -29847,11 +36597,424 @@ index 6b7d47a52b10..8a63ff1e5f73 100644 /* Only port A can provide interrupts in all configurations of the IP */ if (pp->idx == 0) +diff --git a/drivers/gpio/gpio-k1x.c b/drivers/gpio/gpio-k1x.c +new file mode 100644 +index 000000000000..4491a9ca4169 +--- /dev/null ++++ b/drivers/gpio/gpio-k1x.c +@@ -0,0 +1,407 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * spacemit-k1x gpio driver file ++ * ++ * Copyright (C) 2023 Spacemit ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define GPLR 0x0 ++#define GPDR 0xc ++#define GPSR 0x18 ++#define GPCR 0x24 ++#define GRER 0x30 ++#define GFER 0x3c ++#define GEDR 0x48 ++#define GSDR 0x54 ++#define GCDR 0x60 ++#define GSRER 0x6c ++#define GCRER 0x78 ++#define GSFER 0x84 ++#define GCFER 0x90 ++#define GAPMASK 0x9c ++#define GCPMASK 0xa8 ++ ++#define K1X_BANK_GPIO_NUMBER (32) ++#define BANK_GPIO_MASK (K1X_BANK_GPIO_NUMBER - 1) ++ ++#define k1x_gpio_to_bank_idx(gpio) ((gpio) / K1X_BANK_GPIO_NUMBER) ++#define k1x_gpio_to_bank_offset(gpio) ((gpio) & BANK_GPIO_MASK) ++#define k1x_bank_to_gpio(idx, offset) (((idx) * K1X_BANK_GPIO_NUMBER) | \ ++ ((offset) & BANK_GPIO_MASK)) ++ ++struct k1x_gpio_bank { ++ void __iomem *reg_bank; ++ u32 irq_mask; ++ u32 irq_rising_edge; ++ u32 irq_falling_edge; ++}; ++ ++struct k1x_gpio_chip { ++ struct gpio_chip chip; ++ void __iomem *reg_base; ++ int irq; ++ struct irq_domain *domain; ++ unsigned int ngpio; ++ unsigned int nbank; ++ struct k1x_gpio_bank *banks; ++}; ++ ++static int k1x_gpio_to_irq(struct gpio_chip *chip, unsigned int offset) ++{ ++ struct k1x_gpio_chip *k1x_chip = container_of(chip, struct k1x_gpio_chip, chip); ++ ++ return irq_create_mapping(k1x_chip->domain, offset); ++} ++ ++static int k1x_gpio_direction_input(struct gpio_chip *chip, unsigned int offset) ++{ ++ struct k1x_gpio_chip *k1x_chip = container_of(chip, struct k1x_gpio_chip, chip); ++ struct k1x_gpio_bank *bank = &k1x_chip->banks[k1x_gpio_to_bank_idx(offset)]; ++ u32 bit = (1 << k1x_gpio_to_bank_offset(offset)); ++ ++ writel(bit, bank->reg_bank + GCDR); ++ ++ return 0; ++} ++ ++static int k1x_gpio_direction_output(struct gpio_chip *chip, unsigned int offset, int value) ++{ ++ struct k1x_gpio_chip *k1x_chip = ++ container_of(chip, struct k1x_gpio_chip, chip); ++ struct k1x_gpio_bank *bank = ++ &k1x_chip->banks[k1x_gpio_to_bank_idx(offset)]; ++ u32 bit = (1 << k1x_gpio_to_bank_offset(offset)); ++ ++ /* Set value first. */ ++ writel(bit, bank->reg_bank + (value ? GPSR : GPCR)); ++ writel(bit, bank->reg_bank + GSDR); ++ ++ return 0; ++} ++ ++static int k1x_gpio_get(struct gpio_chip *chip, unsigned int offset) ++{ ++ struct k1x_gpio_chip *k1x_chip = container_of(chip, struct k1x_gpio_chip, chip); ++ struct k1x_gpio_bank *bank = &k1x_chip->banks[k1x_gpio_to_bank_idx(offset)]; ++ u32 bit = (1 << k1x_gpio_to_bank_offset(offset)); ++ u32 gplr; ++ ++ gplr = readl(bank->reg_bank + GPLR); ++ ++ return !!(gplr & bit); ++} ++ ++static void k1x_gpio_set(struct gpio_chip *chip, unsigned int offset, int value) ++{ ++ struct k1x_gpio_chip *k1x_chip = container_of(chip, struct k1x_gpio_chip, chip); ++ struct k1x_gpio_bank *bank = &k1x_chip->banks[k1x_gpio_to_bank_idx(offset)]; ++ u32 bit = (1 << k1x_gpio_to_bank_offset(offset)); ++ u32 gpdr; ++ ++ gpdr = readl(bank->reg_bank + GPDR); ++ /* Is it configured as output? */ ++ if (gpdr & bit) ++ writel(bit, bank->reg_bank + (value ? GPSR : GPCR)); ++} ++ ++#ifdef CONFIG_OF_GPIO ++static int k1x_gpio_of_xlate(struct gpio_chip *chip, ++ const struct of_phandle_args *gpiospec, ++ u32 *flags) ++{ ++ struct k1x_gpio_chip *k1x_chip = container_of(chip, struct k1x_gpio_chip, chip); ++ ++ /* GPIO index start from 0. */ ++ if (gpiospec->args[0] >= k1x_chip->ngpio) ++ return -EINVAL; ++ ++ if (flags) ++ *flags = gpiospec->args[1]; ++ ++ return gpiospec->args[0]; ++} ++#endif ++ ++static int k1x_gpio_irq_type(struct irq_data *d, unsigned int type) ++{ ++ struct k1x_gpio_chip *k1x_chip = irq_data_get_irq_chip_data(d); ++ int gpio = irqd_to_hwirq(d); ++ struct k1x_gpio_bank *bank = &k1x_chip->banks[k1x_gpio_to_bank_idx(gpio)]; ++ u32 bit = (1 << k1x_gpio_to_bank_offset(gpio)); ++ ++ if (type & IRQ_TYPE_EDGE_RISING) { ++ bank->irq_rising_edge |= bit; ++ writel(bit, bank->reg_bank + GSRER); ++ } else { ++ bank->irq_rising_edge &= ~bit; ++ writel(bit, bank->reg_bank + GCRER); ++ } ++ ++ if (type & IRQ_TYPE_EDGE_FALLING) { ++ bank->irq_falling_edge |= bit; ++ writel(bit, bank->reg_bank + GSFER); ++ } else { ++ bank->irq_falling_edge &= ~bit; ++ writel(bit, bank->reg_bank + GCFER); ++ } ++ ++ return 0; ++} ++ ++static irqreturn_t k1x_gpio_demux_handler(int irq, void *data) ++{ ++ int i, n; ++ u32 gedr; ++ unsigned long pending = 0; ++ unsigned int irq_num, irqs_handled = 0; ++ struct k1x_gpio_bank *bank; ++ struct k1x_gpio_chip *k1x_chip = (struct k1x_gpio_chip *)data; ++ ++ for (i = 0; i < k1x_chip->nbank; i++) { ++ bank = &k1x_chip->banks[i]; ++ ++ gedr = readl(bank->reg_bank + GEDR); ++ if (!gedr) ++ continue; ++ ++ writel(gedr, bank->reg_bank + GEDR); ++ gedr = gedr & bank->irq_mask; ++ ++ if (!gedr) ++ continue; ++ pending = gedr; ++ for_each_set_bit(n, &pending, BITS_PER_LONG) { ++ irq_num = irq_find_mapping(k1x_chip->domain, ++ k1x_bank_to_gpio(i, n)); ++ generic_handle_irq(irq_num); ++ } ++ irqs_handled++; ++ } ++ ++ return irqs_handled ? IRQ_HANDLED : IRQ_NONE; ++} ++ ++static void k1x_ack_muxed_gpio(struct irq_data *d) ++{ ++ struct k1x_gpio_chip *k1x_chip = irq_data_get_irq_chip_data(d); ++ int gpio = irqd_to_hwirq(d); ++ struct k1x_gpio_bank *bank = &k1x_chip->banks[k1x_gpio_to_bank_idx(gpio)]; ++ u32 bit = (1 << k1x_gpio_to_bank_offset(gpio)); ++ ++ writel(bit, bank->reg_bank + GEDR); ++} ++ ++static void k1x_mask_muxed_gpio(struct irq_data *d) ++{ ++ struct k1x_gpio_chip *k1x_chip = irq_data_get_irq_chip_data(d); ++ int gpio = irqd_to_hwirq(d); ++ struct k1x_gpio_bank *bank = &k1x_chip->banks[k1x_gpio_to_bank_idx(gpio)]; ++ u32 bit = (1 << k1x_gpio_to_bank_offset(gpio)); ++ ++ bank->irq_mask &= ~bit; ++ ++ /* Clear the bit of rising and falling edge detection. */ ++ writel(bit, bank->reg_bank + GCRER); ++ writel(bit, bank->reg_bank + GCFER); ++} ++ ++static void k1x_unmask_muxed_gpio(struct irq_data *d) ++{ ++ int gpio = irqd_to_hwirq(d); ++ u32 bit = (1 << k1x_gpio_to_bank_offset(gpio)); ++ struct k1x_gpio_chip *k1x_chip = irq_data_get_irq_chip_data(d); ++ struct k1x_gpio_bank *bank = &k1x_chip->banks[k1x_gpio_to_bank_idx(gpio)]; ++ ++ bank->irq_mask |= bit; ++ ++ /* Set the bit of rising and falling edge detection if the gpio has. */ ++ writel(bit & bank->irq_rising_edge, bank->reg_bank + GSRER); ++ writel(bit & bank->irq_falling_edge, bank->reg_bank + GSFER); ++} ++ ++static struct irq_chip k1x_muxed_gpio_chip = { ++ .name = "k1x-gpio-irqchip", ++ .irq_ack = k1x_ack_muxed_gpio, ++ .irq_mask = k1x_mask_muxed_gpio, ++ .irq_unmask = k1x_unmask_muxed_gpio, ++ .irq_set_type = k1x_gpio_irq_type, ++ .flags = IRQCHIP_SKIP_SET_WAKE, ++}; ++ ++static const struct of_device_id k1x_gpio_dt_ids[] = { ++ { .compatible = "spacemit,k1x-gpio"}, ++ {} ++}; ++ ++static int k1x_irq_domain_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) ++{ ++ irq_set_chip_and_handler(irq, &k1x_muxed_gpio_chip, handle_edge_irq); ++ irq_set_chip_data(irq, d->host_data); ++ ++ return 0; ++} ++ ++static const struct irq_domain_ops k1x_gpio_irq_domain_ops = { ++ .map = k1x_irq_domain_map, ++ .xlate = irq_domain_xlate_twocell, ++}; ++ ++static int k1x_gpio_probe_dt(struct platform_device *pdev, struct k1x_gpio_chip *k1x_chip) ++{ ++ u32 offset; ++ int i, nbank, ret; ++ struct device_node *child; ++ struct device_node *np = pdev->dev.of_node; ++ ++ nbank = of_get_child_count(np); ++ if (nbank == 0) ++ return -EINVAL; ++ ++ k1x_chip->banks = devm_kzalloc(&pdev->dev, ++ sizeof(*k1x_chip->banks) * nbank, ++ GFP_KERNEL); ++ if (!k1x_chip->banks) ++ return -ENOMEM; ++ ++ i = 0; ++ for_each_child_of_node(np, child) { ++ ret = of_property_read_u32(child, "reg-offset", &offset); ++ if (ret) { ++ of_node_put(child); ++ return ret; ++ } ++ k1x_chip->banks[i].reg_bank = k1x_chip->reg_base + offset; ++ i++; ++ } ++ ++ k1x_chip->nbank = nbank; ++ k1x_chip->ngpio = k1x_chip->nbank * K1X_BANK_GPIO_NUMBER; ++ ++ return 0; ++} ++ ++static int k1x_gpio_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct device_node *np; ++ struct k1x_gpio_chip *k1x_chip; ++ struct k1x_gpio_bank *bank; ++ struct resource *res; ++ struct irq_domain *domain; ++ struct clk *clk; ++ ++ int irq, i, ret; ++ void __iomem *base; ++ ++ np = pdev->dev.of_node; ++ if (!np) ++ return -EINVAL; ++ ++ k1x_chip = devm_kzalloc(dev, sizeof(*k1x_chip), GFP_KERNEL); ++ if (!k1x_chip) ++ return -ENOMEM; ++ ++ irq = platform_get_irq(pdev, 0); ++ if (irq < 0) ++ return irq; ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (!res) ++ return -EINVAL; ++ base = devm_ioremap_resource(dev, res); ++ if (!base) ++ return -EINVAL; ++ ++ k1x_chip->irq = irq; ++ k1x_chip->reg_base = base; ++ ++ ret = k1x_gpio_probe_dt(pdev, k1x_chip); ++ if (ret) { ++ dev_err(dev, "Fail to initialize gpio unit, error %d.\n", ret); ++ return ret; ++ } ++ ++ clk = devm_clk_get(dev, NULL); ++ if (IS_ERR(clk)) { ++ dev_err(dev, "Fail to get gpio clock, error %ld.\n", ++ PTR_ERR(clk)); ++ return PTR_ERR(clk); ++ } ++ ret = clk_prepare_enable(clk); ++ if (ret) { ++ dev_err(dev, "Fail to enable gpio clock, error %d.\n", ret); ++ return ret; ++ } ++ ++ domain = irq_domain_add_linear(np, k1x_chip->ngpio, &k1x_gpio_irq_domain_ops, k1x_chip); ++ if (!domain) ++ return -EINVAL; ++ ++ k1x_chip->domain = domain; ++ ++ /* Initialize the gpio chip */ ++ k1x_chip->chip.label = "k1x-gpio"; ++ k1x_chip->chip.request = gpiochip_generic_request; ++ k1x_chip->chip.free = gpiochip_generic_free; ++ k1x_chip->chip.direction_input = k1x_gpio_direction_input; ++ k1x_chip->chip.direction_output = k1x_gpio_direction_output; ++ k1x_chip->chip.get = k1x_gpio_get; ++ k1x_chip->chip.set = k1x_gpio_set; ++ k1x_chip->chip.to_irq = k1x_gpio_to_irq; ++#ifdef CONFIG_OF_GPIO ++ k1x_chip->chip.fwnode = of_fwnode_handle(np); ++ k1x_chip->chip.of_xlate = k1x_gpio_of_xlate; ++ k1x_chip->chip.of_gpio_n_cells = 2; ++#endif ++ k1x_chip->chip.ngpio = k1x_chip->ngpio; ++ ++ if (devm_request_irq(&pdev->dev, irq, k1x_gpio_demux_handler, 0, ++ k1x_chip->chip.label, k1x_chip)) { ++ dev_err(&pdev->dev, "failed to request high IRQ\n"); ++ ret = -ENOENT; ++ goto err; ++ } ++ ++ gpiochip_add(&k1x_chip->chip); ++ ++ /* clear all GPIO edge detects */ ++ for (i = 0; i < k1x_chip->nbank; i++) { ++ bank = &k1x_chip->banks[i]; ++ writel(0xffffffff, bank->reg_bank + GCFER); ++ writel(0xffffffff, bank->reg_bank + GCRER); ++ /* Unmask edge detection to AP. */ ++ writel(0xffffffff, bank->reg_bank + GAPMASK); ++ } ++ ++ return 0; ++err: ++ irq_domain_remove(domain); ++ return ret; ++} ++ ++static struct platform_driver k1x_gpio_driver = { ++ .probe = k1x_gpio_probe, ++ .driver = { ++ .name = "k1x-gpio", ++ .of_match_table = k1x_gpio_dt_ids, ++ }, ++}; ++ ++static int __init k1x_gpio_init(void) ++{ ++ return platform_driver_register(&k1x_gpio_driver); ++} ++subsys_initcall(k1x_gpio_init); diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c -index ce9a94e33280..329d2c434161 100644 +index b882b26ab500..d502bb36434b 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c -@@ -1358,12 +1358,20 @@ static const struct of_device_id pca953x_dt_ids[] = { +@@ -1322,12 +1322,20 @@ static const struct of_device_id pca953x_dt_ids[] = { MODULE_DEVICE_TABLE(of, pca953x_dt_ids); @@ -29907,7 +37070,7 @@ index 7ba2ec90c3f7..183e306f0c6e 100644 obj-$(CONFIG_HYDCU_FIXUP_HEADER) += hygon/hydcu-fixup-header/ +obj-$(CONFIG_DRM_VERISILICON) += verisilicon/ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c -index 2f64c6871935..2d2f0714ea73 100644 +index 1f1198e7c93e..74d602dc575d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -1109,6 +1109,8 @@ int amdgpu_device_resize_fb_bar(struct amdgpu_device *adev) @@ -350757,10 +357920,10 @@ index 000000000000..8a4f21e1cb17 + struct mutex mlock; +}; diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c -index 6ef522ce745b..d16d701a4447 100644 +index f778936d7579..58584729f4bd 100644 --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c -@@ -4320,7 +4320,8 @@ static int arm_smmu_update_gbpa(struct arm_smmu_device *smmu, u32 set, u32 clr) +@@ -4433,7 +4433,8 @@ static int arm_smmu_update_gbpa(struct arm_smmu_device *smmu, u32 set, u32 clr) static void arm_smmu_free_msis(void *data) { struct device *dev = data; @@ -350770,7 +357933,7 @@ index 6ef522ce745b..d16d701a4447 100644 } static void arm_smmu_write_msi_msg(struct msi_desc *desc, struct msi_msg *msg) -@@ -4377,7 +4378,7 @@ static void arm_smmu_setup_msis(struct arm_smmu_device *smmu) +@@ -4490,7 +4491,7 @@ static void arm_smmu_setup_msis(struct arm_smmu_device *smmu) } /* Allocate MSIs for evtq, gerror and priq. Ignore cmdq */ @@ -445428,7 +452591,7 @@ index 000000000000..931c9d9124e9 +MODULE_DESCRIPTION("Synopsys DesignWare MIPI DPHY driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig -index 79753411b778..12e411726bcc 100644 +index 79753411b778..14d7e6ac352c 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -22,7 +22,7 @@ config PINCONF @@ -445456,11 +452619,34 @@ index 79753411b778..12e411726bcc 100644 config PINCTRL_ZYNQ bool "Pinctrl driver for Xilinx Zynq" depends on ARCH_ZYNQ +@@ -505,6 +514,17 @@ config PINCTRL_MLXBF3 + each pin. This driver can also be built as a module called + pinctrl-mlxbf3. + ++config PINCTRL_SPACEMIT_K1X ++ bool "Spacemit k1x pinctrl driver" ++ depends on SOC_SPACEMIT_K1X ++ depends on OF ++ depends on HAS_IOMEM ++ select GENERIC_PINCTRL_GROUPS ++ select GENERIC_PINMUX_FUNCTIONS ++ select GENERIC_PINCONF ++ help ++ This support pinctrl driver for Spacemit k1x SoC. ++ + source "drivers/pinctrl/actions/Kconfig" + source "drivers/pinctrl/aspeed/Kconfig" + source "drivers/pinctrl/bcm/Kconfig" diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile -index 4275eca92488..f07a2ee92197 100644 +index 4275eca92488..1eb39567728c 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile -@@ -48,6 +48,7 @@ obj-$(CONFIG_PINCTRL_ST) += pinctrl-st.o +@@ -44,10 +44,12 @@ obj-$(CONFIG_PINCTRL_PISTACHIO) += pinctrl-pistachio.o + obj-$(CONFIG_PINCTRL_RK805) += pinctrl-rk805.o + obj-$(CONFIG_PINCTRL_ROCKCHIP) += pinctrl-rockchip.o + obj-$(CONFIG_PINCTRL_SINGLE) += pinctrl-single.o ++obj-$(CONFIG_PINCTRL_SPACEMIT_K1X) += pinctrl-spacemit-k1x.o + obj-$(CONFIG_PINCTRL_ST) += pinctrl-st.o obj-$(CONFIG_PINCTRL_STMFX) += pinctrl-stmfx.o obj-$(CONFIG_PINCTRL_SX150X) += pinctrl-sx150x.o obj-$(CONFIG_PINCTRL_TB10X) += pinctrl-tb10x.o @@ -445468,7 +452654,7 @@ index 4275eca92488..f07a2ee92197 100644 obj-$(CONFIG_PINCTRL_ZYNQMP) += pinctrl-zynqmp.o obj-$(CONFIG_PINCTRL_ZYNQ) += pinctrl-zynq.o -@@ -75,6 +76,7 @@ obj-$(CONFIG_SOC_STARFIVE) += starfive/ +@@ -75,6 +77,7 @@ obj-$(CONFIG_SOC_STARFIVE) += starfive/ obj-$(CONFIG_PINCTRL_STM32) += stm32/ obj-y += sunplus/ obj-$(CONFIG_PINCTRL_SUNXI) += sunxi/ @@ -445476,6 +452662,2113 @@ index 4275eca92488..f07a2ee92197 100644 obj-$(CONFIG_ARCH_TEGRA) += tegra/ obj-y += ti/ obj-$(CONFIG_PINCTRL_UNIPHIER) += uniphier/ +diff --git a/drivers/pinctrl/pinctrl-spacemit-k1x.c b/drivers/pinctrl/pinctrl-spacemit-k1x.c +new file mode 100644 +index 000000000000..feed95179f33 +--- /dev/null ++++ b/drivers/pinctrl/pinctrl-spacemit-k1x.c +@@ -0,0 +1,2101 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Generic device tree based pinctrl driver for one register per pin ++ * type pinmux controllers ++ * ++ * Copyright (C) 2012 Texas Instruments, Inc. ++ * Copyright (C) 2023 Spacemit Co., Ltd. ++ * ++ * This file is licensed under the terms of the GNU General Public ++ * License version 2. This program is licensed "as is" without any ++ * warranty of any kind, whether express or implied. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include "core.h" ++#include "devicetree.h" ++#include "pinconf.h" ++#include "pinmux.h" ++ ++#define DRIVER_NAME "pinctrl-single" ++#define PCS_OFF_DISABLED ~0U ++ ++#define EDGE_CLEAR 6 ++#define EDGE_FALL_EN 5 ++#define EDGE_RISE_EN 4 ++ ++#define PCS_CONTEXT_LOSS_OFF BIT(3) ++#define PCS_QUIRK_SHARED_IRQ BIT(2) ++#define PCS_FEAT_IRQ BIT(1) ++#define PCS_FEAT_PINCONF BIT(0) ++ ++#define PCS_QUIRK_HAS_SHARED_IRQ(_pcs) (_pcs->flags & PCS_QUIRK_SHARED_IRQ) ++#define PCS_HAS_IRQ(_pcs) (_pcs->flags & PCS_FEAT_IRQ) ++#define PCS_HAS_PINCONF(_pcs) (_pcs->flags & PCS_FEAT_PINCONF) ++ ++/** ++ * struct pcs_func_vals - mux function register offset and value pair ++ * @reg: register virtual address ++ * @val: register value ++ * @mask: mask ++ */ ++struct pcs_func_vals { ++ void __iomem *reg; ++ unsigned int val; ++ unsigned int mask; ++}; ++ ++/** ++ * struct pcs_conf_vals - pinconf parameter, pinconf register offset ++ * and value, enable, disable, mask ++ * @param: config parameter ++ * @val: user input bits in the pinconf register ++ * @enable: enable bits in the pinconf register ++ * @disable: disable bits in the pinconf register ++ * @mask: mask bits in the register value ++ */ ++struct pcs_conf_vals { ++ enum pin_config_param param; ++ unsigned int val; ++ unsigned int enable; ++ unsigned int disable; ++ unsigned int mask; ++}; ++ ++/** ++ * struct pcs_conf_type - pinconf property name, pinconf param pair ++ * @name: property name in DTS file ++ * @param: config parameter ++ */ ++struct pcs_conf_type { ++ const char *name; ++ enum pin_config_param param; ++}; ++ ++/** ++ * struct pcs_function - pinctrl function ++ * @name: pinctrl function name ++ * @vals: register and vals array ++ * @nvals: number of entries in vals array ++ * @pgnames: array of pingroup names the function uses ++ * @npgnames: number of pingroup names the function uses ++ * @conf: array of pin configurations ++ * @nconfs: number of pin configurations available ++ * @node: list node ++ */ ++struct pcs_function { ++ const char *name; ++ struct pcs_func_vals *vals; ++ unsigned int nvals; ++ const char **pgnames; ++ int npgnames; ++ struct pcs_conf_vals *conf; ++ int nconfs; ++ struct list_head node; ++}; ++ ++/** ++ * struct pcs_gpiofunc_range - pin ranges with same mux value of gpio function ++ * @offset: offset base of pins ++ * @npins: number pins with the same mux value of gpio function ++ * @gpiofunc: mux value of gpio function ++ * @node: list node ++ */ ++struct pcs_gpiofunc_range { ++ unsigned int offset; ++ unsigned int npins; ++ unsigned int gpiofunc; ++ struct list_head node; ++}; ++ ++/** ++ * struct pcs_data - wrapper for data needed by pinctrl framework ++ * @pa: pindesc array ++ * @cur: index to current element ++ * ++ * REVISIT: We should be able to drop this eventually by adding ++ * support for registering pins individually in the pinctrl ++ * framework for those drivers that don't need a static array. ++ */ ++struct pcs_data { ++ struct pinctrl_pin_desc *pa; ++ int cur; ++}; ++ ++/** ++ * struct pcs_soc_data - SoC specific settings ++ * @flags: initial SoC specific PCS_FEAT_xxx values ++ * @irq: optional interrupt for the controller ++ * @irq_enable_mask: optional SoC specific interrupt enable mask ++ * @irq_status_mask: optional SoC specific interrupt status mask ++ * @rearm: optional SoC specific wake-up rearm function ++ */ ++struct pcs_soc_data { ++ unsigned int flags; ++ int irq; ++ unsigned int irq_enable_mask; ++ unsigned int irq_status_mask; ++ void (*rearm)(void); ++}; ++ ++/** ++ * struct pcs_device - pinctrl device instance ++ * @res: resources ++ * @base: virtual address of the controller ++ * @saved_vals: saved values for the controller ++ * @size: size of the ioremapped area ++ * @dev: device entry ++ * @np: device tree node ++ * @pctl: pin controller device ++ * @flags: mask of PCS_FEAT_xxx values ++ * @missing_nr_pinctrl_cells: for legacy binding, may go away ++ * @socdata: soc specific data ++ * @lock: spinlock for register access ++ * @mutex: mutex protecting the lists ++ * @width: bits per mux register ++ * @fmask: function register mask ++ * @fshift: function register shift ++ * @foff: value to turn mux off ++ * @fmax: max number of functions in fmask ++ * @bits_per_mux: number of bits per mux ++ * @bits_per_pin: number of bits per pin ++ * @pins: physical pins on the SoC ++ * @gpiofuncs: list of gpio functions ++ * @irqs: list of interrupt registers ++ * @chip: chip container for this instance ++ * @domain: IRQ domain for this instance ++ * @desc: pin controller descriptor ++ * @read: register read function to use ++ * @write: register write function to use ++ */ ++struct pcs_device { ++ struct resource *res; ++ void __iomem *base; ++ struct resource *gedge_flag_res; ++ void __iomem *gedge_flag_base; ++ unsigned int gedge_flag_size; ++ struct resource gpio_res; ++ void __iomem *gpio_base; ++ unsigned int gpio_size; ++ void *saved_vals; ++ unsigned int size; ++ struct device *dev; ++ struct device_node *np; ++ struct pinctrl_dev *pctl; ++ unsigned int flags; ++ struct property *missing_nr_pinctrl_cells; ++ struct pcs_soc_data socdata; ++ raw_spinlock_t lock; ++ struct mutex mutex; ++ unsigned int width; ++ unsigned int fmask; ++ unsigned int fshift; ++ unsigned int foff; ++ unsigned int fmax; ++ bool bits_per_mux; ++ unsigned int bits_per_pin; ++ struct pcs_data pins; ++ struct list_head gpiofuncs; ++ struct list_head irqs; ++ struct irq_chip chip; ++ struct irq_domain *domain; ++ struct pinctrl_desc desc; ++ unsigned int (*read)(void __iomem *reg); ++ void (*write)(unsigned int val, void __iomem *reg); ++}; ++ ++static int pcs_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin, ++ unsigned long *config); ++static int pcs_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, ++ unsigned long *configs, unsigned int num_configs); ++ ++static enum pin_config_param pcs_bias[] = { ++ PIN_CONFIG_BIAS_PULL_DOWN, ++ PIN_CONFIG_BIAS_PULL_UP, ++}; ++ ++/* ++ * This lock class tells lockdep that irqchip core that this single ++ * pinctrl can be in a different category than its parents, so it won't ++ * report false recursion. ++ */ ++static struct lock_class_key pcs_lock_class; ++ ++/* Class for the IRQ request mutex */ ++static struct lock_class_key pcs_request_class; ++ ++/* ++ * REVISIT: Reads and writes could eventually use regmap or something ++ * generic. But at least on omaps, some mux registers are performance ++ * critical as they may need to be remuxed every time before and after ++ * idle. Adding tests for register access width for every read and ++ * write like regmap is doing is not desired, and caching the registers ++ * does not help in this case. ++ */ ++ ++static unsigned int __maybe_unused pcs_readb(void __iomem *reg) ++{ ++ return readb(reg); ++} ++ ++static unsigned int __maybe_unused pcs_readw(void __iomem *reg) ++{ ++ return readw(reg); ++} ++ ++static unsigned int __maybe_unused pcs_readl(void __iomem *reg) ++{ ++ return readl(reg); ++} ++ ++static void __maybe_unused pcs_writeb(unsigned int val, void __iomem *reg) ++{ ++ writeb(val, reg); ++} ++ ++static void __maybe_unused pcs_writew(unsigned int val, void __iomem *reg) ++{ ++ writew(val, reg); ++} ++ ++static void __maybe_unused pcs_writel(unsigned int val, void __iomem *reg) ++{ ++ writel(val, reg); ++} ++ ++static unsigned int pcs_pin_reg_offset_get(struct pcs_device *pcs, ++ unsigned int pin) ++{ ++ unsigned int pin_offset_bytes; ++ unsigned int mux_bytes = pcs->width / BITS_PER_BYTE; ++ ++ if (pcs->bits_per_mux) { ++ pin_offset_bytes = (pcs->bits_per_pin * pin) / BITS_PER_BYTE; ++ return (pin_offset_bytes / mux_bytes) * mux_bytes; ++ } ++ ++ return pin * mux_bytes; ++} ++ ++static unsigned int pcs_pin_shift_reg_get(struct pcs_device *pcs, ++ unsigned int pin) ++{ ++ return (pin % (pcs->width / pcs->bits_per_pin)) * pcs->bits_per_pin; ++} ++ ++static void pcs_pin_dbg_show(struct pinctrl_dev *pctldev, ++ struct seq_file *s, ++ unsigned int pin) ++{ ++ struct pcs_device *pcs; ++ unsigned int val; ++ unsigned long offset; ++ size_t pa; ++ ++ pcs = pinctrl_dev_get_drvdata(pctldev); ++ ++ offset = pcs_pin_reg_offset_get(pcs, pin); ++ val = pcs->read(pcs->base + offset); ++ ++ if (pcs->bits_per_mux) ++ val &= pcs->fmask << pcs_pin_shift_reg_get(pcs, pin); ++ ++ pa = pcs->res->start + offset; ++ ++ seq_printf(s, "%zx %08x %s ", pa, val, DRIVER_NAME); ++} ++ ++static void pcs_dt_free_map(struct pinctrl_dev *pctldev, struct pinctrl_map *map, ++ unsigned int num_maps) ++{ ++ struct pcs_device *pcs; ++ ++ pcs = pinctrl_dev_get_drvdata(pctldev); ++ devm_kfree(pcs->dev, map); ++} ++ ++static int pcs_dt_node_to_map(struct pinctrl_dev *pctldev, struct device_node *np_config, ++ struct pinctrl_map **map, unsigned int *num_maps); ++ ++static const struct pinctrl_ops pcs_pinctrl_ops = { ++ .get_groups_count = pinctrl_generic_get_group_count, ++ .get_group_name = pinctrl_generic_get_group_name, ++ .get_group_pins = pinctrl_generic_get_group_pins, ++ .pin_dbg_show = pcs_pin_dbg_show, ++ .dt_node_to_map = pcs_dt_node_to_map, ++ .dt_free_map = pcs_dt_free_map, ++}; ++ ++static int pcs_get_function(struct pinctrl_dev *pctldev, unsigned int pin, ++ struct pcs_function **func) ++{ ++ unsigned int fselector; ++ struct function_desc *function; ++ const struct pinctrl_setting_mux *setting; ++ struct pin_desc *pdesc = pin_desc_get(pctldev, pin); ++ struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev); ++ ++ /* If pin is not described in DTS & enabled, mux_setting is NULL. */ ++ setting = pdesc->mux_setting; ++ if (!setting) ++ return -EOPNOTSUPP; ++ fselector = setting->func; ++ function = pinmux_generic_get_function(pctldev, fselector); ++ if (!function) ++ return -EINVAL; ++ *func = function->data; ++ if (!(*func)) { ++ dev_err(pcs->dev, "%s could not find function%i\n", ++ __func__, fselector); ++ return -EOPNOTSUPP; ++ } ++ return 0; ++} ++ ++static int pcs_set_mux(struct pinctrl_dev *pctldev, unsigned int fselector, unsigned int group) ++{ ++ int i; ++ unsigned long flags; ++ unsigned int val, mask; ++ struct pcs_device *pcs; ++ struct pcs_function *func; ++ struct pcs_func_vals *vals; ++ struct function_desc *function; ++ ++ pcs = pinctrl_dev_get_drvdata(pctldev); ++ /* If function mask is null, needn't enable it. */ ++ if (!pcs->fmask) ++ return 0; ++ function = pinmux_generic_get_function(pctldev, fselector); ++ if (!function) ++ return -EINVAL; ++ func = function->data; ++ if (!func) ++ return -EINVAL; ++ ++ dev_dbg(pcs->dev, "enabling %s function%i\n", ++ func->name, fselector); ++ ++ for (i = 0; i < func->nvals; i++) { ++ vals = &func->vals[i]; ++ raw_spin_lock_irqsave(&pcs->lock, flags); ++ val = pcs->read(vals->reg); ++ ++ if (pcs->bits_per_mux) ++ mask = vals->mask; ++ else ++ mask = pcs->fmask; ++ ++ val &= ~mask; ++ val |= (vals->val & mask); ++ pcs->write(val, vals->reg); ++ raw_spin_unlock_irqrestore(&pcs->lock, flags); ++ } ++ ++ return 0; ++} ++ ++static int pcs_request_gpio(struct pinctrl_dev *pctldev, ++ struct pinctrl_gpio_range *range, unsigned int pin) ++{ ++ u32 offset; ++ int pin_shift; ++ unsigned int data; ++ struct list_head *pos, *tmp; ++ struct pcs_gpiofunc_range *frange = NULL; ++ struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev); ++ ++ /* If function mask is null, return directly. */ ++ if (!pcs->fmask) ++ return -EOPNOTSUPP; ++ ++ list_for_each_safe(pos, tmp, &pcs->gpiofuncs) { ++ frange = list_entry(pos, struct pcs_gpiofunc_range, node); ++ if (pin >= frange->offset + frange->npins || ++ pin < frange->offset) ++ continue; ++ ++ offset = pcs_pin_reg_offset_get(pcs, pin); ++ ++ if (pcs->bits_per_mux) { ++ pin_shift = pcs_pin_shift_reg_get(pcs, pin); ++ data = pcs->read(pcs->base + offset); ++ data &= ~(pcs->fmask << pin_shift); ++ data |= frange->gpiofunc << pin_shift; ++ pcs->write(data, pcs->base + offset); ++ } else { ++ data = pcs->read(pcs->base + offset); ++ data &= ~pcs->fmask; ++ data |= frange->gpiofunc; ++ pcs->write(data, pcs->base + offset); ++ } ++ break; ++ } ++ return 0; ++} ++ ++static const struct pinmux_ops pcs_pinmux_ops = { ++ .get_functions_count = pinmux_generic_get_function_count, ++ .get_function_name = pinmux_generic_get_function_name, ++ .get_function_groups = pinmux_generic_get_function_groups, ++ .set_mux = pcs_set_mux, ++ .gpio_request_enable = pcs_request_gpio, ++}; ++ ++/* Clear BIAS value */ ++static void pcs_pinconf_clear_bias(struct pinctrl_dev *pctldev, unsigned int pin) ++{ ++ int i; ++ unsigned long config; ++ ++ for (i = 0; i < ARRAY_SIZE(pcs_bias); i++) { ++ config = pinconf_to_config_packed(pcs_bias[i], 0); ++ pcs_pinconf_set(pctldev, pin, &config, 1); ++ } ++} ++ ++/* ++ * Check whether PIN_CONFIG_BIAS_DISABLE is valid. ++ * It's depend on that PULL_DOWN & PULL_UP configs are all invalid. ++ */ ++static bool pcs_pinconf_bias_disable(struct pinctrl_dev *pctldev, unsigned int pin) ++{ ++ int i; ++ unsigned long config; ++ ++ for (i = 0; i < ARRAY_SIZE(pcs_bias); i++) { ++ config = pinconf_to_config_packed(pcs_bias[i], 0); ++ if (!pcs_pinconf_get(pctldev, pin, &config)) ++ goto out; ++ } ++ return true; ++out: ++ return false; ++} ++ ++static int pcs_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin, unsigned long *config) ++{ ++ struct pcs_function *func; ++ enum pin_config_param param; ++ unsigned int offset = 0, data = 0, i, j, ret; ++ struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev); ++ ++ ret = pcs_get_function(pctldev, pin, &func); ++ if (ret) ++ return ret; ++ ++ for (i = 0; i < func->nconfs; i++) { ++ param = pinconf_to_config_param(*config); ++ if (param == PIN_CONFIG_BIAS_DISABLE) { ++ if (pcs_pinconf_bias_disable(pctldev, pin)) { ++ *config = 0; ++ return 0; ++ } else { ++ return -EOPNOTSUPP; ++ } ++ } else if (param != func->conf[i].param) { ++ continue; ++ } ++ ++ offset = pin * (pcs->width / BITS_PER_BYTE); ++ data = pcs->read(pcs->base + offset) & func->conf[i].mask; ++ switch (func->conf[i].param) { ++ /* 4 parameters */ ++ case PIN_CONFIG_BIAS_PULL_DOWN: ++ case PIN_CONFIG_BIAS_PULL_UP: ++ case PIN_CONFIG_INPUT_SCHMITT_ENABLE: ++ if (data != func->conf[i].enable || data == func->conf[i].disable) ++ return -EOPNOTSUPP; ++ *config = 0; ++ break; ++ /* 2 parameters */ ++ case PIN_CONFIG_INPUT_SCHMITT: ++ for (j = 0; j < func->nconfs; j++) { ++ switch (func->conf[j].param) { ++ case PIN_CONFIG_INPUT_SCHMITT_ENABLE: ++ if (data != func->conf[j].enable) ++ return -EOPNOTSUPP; ++ break; ++ default: ++ break; ++ } ++ } ++ *config = data; ++ break; ++ case PIN_CONFIG_DRIVE_STRENGTH: ++ case PIN_CONFIG_SLEW_RATE: ++ case PIN_CONFIG_MODE_LOW_POWER: ++ case PIN_CONFIG_INPUT_ENABLE: ++ default: ++ *config = data; ++ break; ++ } ++ return 0; ++ } ++ return -EOPNOTSUPP; ++} ++ ++static int pin_to_gpio_number[] = { ++ 0, 1, 2, 3, 4, 5, 6, 7, ++ 8, 9, 10, 11, 12, 13, 14, 15, ++ 16, 17, 18, 19, 20, 21, 22, 23, ++ 24, 25, 26, 27, 28, 29, 30, 31, ++ 32, 33, 34, 35, 36, 37, 38, 39, ++ 40, 41, 42, 43, 44, 45, 46, 47, ++ 48, 49, 50, 51, 52, 53, 54, 55, ++ 56, 57, 58, 59, 60, 61, 62, 63, ++ 64, 65, 66, 67, 68, 69, 70, 71, ++ 72, 73, 74, 75, 76, 77, 78, 79, ++ 80, 81, 82, 83, 84, 85, 0, 0, ++ 0, 101, 100, 99, 98, 103, 102, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 104, 105, 106, ++ 107, 108, 109, 110, 93, 94, 95, 96, ++ 97, 0, 86, 87, 88, 89, 90, 91, ++ 92, 0, 111, 112, 113, 114, 115, 116, ++ 117, 118, 119, 120, 121, 122, 123, 124, ++ 125, 126, 127 ++}; ++ ++static int pcs_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, ++ unsigned long *configs, unsigned int num_configs) ++{ ++ int i, j, ret, gpio_number; ++ unsigned int arg, data, offset = 0, shift = 0; ++ void __iomem *gpio_base; ++ struct pcs_function *func; ++ struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev); ++ ++ ret = pcs_get_function(pctldev, pin, &func); ++ if (ret) ++ return ret; ++ ++ for (j = 0; j < num_configs; j++) { ++ for (i = 0; i < func->nconfs; i++) { ++ if (pinconf_to_config_param(configs[j]) != func->conf[i].param) ++ continue; ++ ++ offset = pin * (pcs->width / BITS_PER_BYTE); ++ data = pcs->read(pcs->base + offset); ++ arg = pinconf_to_config_argument(configs[j]); ++ ++ switch (func->conf[i].param) { ++ /* 2 parameters */ ++ case PIN_CONFIG_OUTPUT_ENABLE: ++ gpio_number = pin_to_gpio_number[pin - 1]; ++ switch (gpio_number) { ++ case 0 ... 31: ++ gpio_base = pcs->gpio_base + 0xc; ++ offset = gpio_number; ++ break; ++ case 32 ... 63: ++ gpio_base = pcs->gpio_base + 0x4 + 0xc; ++ offset = gpio_number - 32; ++ break; ++ case 64 ... 95: ++ gpio_base = pcs->gpio_base + 0x8 + 0xc; ++ offset = gpio_number - 64; ++ break; ++ case 96 ... 127: ++ gpio_base = pcs->gpio_base + 0x100 + 0xc; ++ offset = gpio_number - 96; ++ break; ++ default: ++ pr_err("Bad pin number\n"); ++ break; ++ } ++ ++ data = pcs->read(gpio_base); ++ data |= (arg << offset); ++ pcs->write(data, gpio_base); ++ ++ break; ++ case PIN_CONFIG_OUTPUT: ++ gpio_number = pin_to_gpio_number[pin - 1]; ++ switch (gpio_number) { ++ case 0 ... 31: ++ gpio_base = pcs->gpio_base + ++ ((arg == 1) ? 0x18 : 0x24); ++ offset = gpio_number; ++ break; ++ case 32 ... 63: ++ gpio_base = pcs->gpio_base + 0x4 + ++ ((arg == 1) ? 0x18 : 0x24); ++ offset = gpio_number - 32; ++ break; ++ case 64 ... 95: ++ gpio_base = pcs->gpio_base + 0x8 + ++ ((arg == 1) ? 0x18 : 0x24); ++ offset = gpio_number - 64; ++ break; ++ case 96 ... 127: ++ gpio_base = pcs->gpio_base + 0x100 + ++ ((arg == 1) ? 0x18 : 0x24); ++ offset = gpio_number - 96; ++ break; ++ default: ++ pr_err("Bad pin number\n"); ++ break; ++ } ++ ++ /* ++ * if we want to set output low, ++ * we should set the arg to 1 ++ * ++ */ ++ if (arg == 0) ++ arg = 1; ++ ++ data = 0; ++ data |= (arg << offset); ++ pcs->write(data, gpio_base); ++ break; ++ case PIN_CONFIG_INPUT_SCHMITT: ++ case PIN_CONFIG_DRIVE_STRENGTH: ++ case PIN_CONFIG_SLEW_RATE: ++ case PIN_CONFIG_MODE_LOW_POWER: ++ case PIN_CONFIG_INPUT_ENABLE: ++ shift = ffs(func->conf[i].mask) - 1; ++ data &= ~func->conf[i].mask; ++ data |= (arg << shift) & func->conf[i].mask; ++ pcs->write(data, pcs->base + offset); ++ break; ++ /* 4 parameters */ ++ case PIN_CONFIG_BIAS_DISABLE: ++ pcs_pinconf_clear_bias(pctldev, pin); ++ pcs->write(data, pcs->base + offset); ++ break; ++ case PIN_CONFIG_BIAS_PULL_DOWN: ++ case PIN_CONFIG_BIAS_PULL_UP: ++ if (arg) ++ pcs_pinconf_clear_bias(pctldev, pin); ++ fallthrough; ++ case PIN_CONFIG_INPUT_SCHMITT_ENABLE: ++ data &= ~func->conf[i].mask; ++ if (arg) ++ data |= func->conf[i].enable; ++ else ++ data |= func->conf[i].disable; ++ pcs->write(data, pcs->base + offset); ++ break; ++ default: ++ return -EOPNOTSUPP; ++ } ++ ++ break; ++ } ++ if (i >= func->nconfs) ++ return -EOPNOTSUPP; ++ } ++ ++ return 0; ++} ++ ++static int pcs_pinconf_group_get(struct pinctrl_dev *pctldev, unsigned int group, ++ unsigned long *config) ++{ ++ int i, ret; ++ const unsigned int *pins; ++ unsigned int npins, old = 0; ++ ++ ret = pinctrl_generic_get_group_pins(pctldev, group, &pins, &npins); ++ if (ret) ++ return ret; ++ for (i = 0; i < npins; i++) { ++ if (pcs_pinconf_get(pctldev, pins[i], config)) ++ return -EOPNOTSUPP; ++ /* configs do not match between two pins */ ++ if (i && old != *config) ++ return -EOPNOTSUPP; ++ old = *config; ++ } ++ return 0; ++} ++ ++static int pcs_pinconf_group_set(struct pinctrl_dev *pctldev, ++ unsigned int group, unsigned long *configs, ++ unsigned int num_configs) ++{ ++ int i, ret; ++ unsigned int npins; ++ const unsigned int *pins; ++ ++ ret = pinctrl_generic_get_group_pins(pctldev, group, &pins, &npins); ++ if (ret) ++ return ret; ++ for (i = 0; i < npins; i++) { ++ if (pcs_pinconf_set(pctldev, pins[i], configs, num_configs)) ++ return -EOPNOTSUPP; ++ } ++ return 0; ++} ++ ++static void pcs_pinconf_dbg_show(struct pinctrl_dev *pctldev, ++ struct seq_file *s, unsigned int pin) ++{ ++} ++ ++static void pcs_pinconf_group_dbg_show(struct pinctrl_dev *pctldev, ++ struct seq_file *s, ++ unsigned int selector) ++{ ++} ++ ++static void pcs_pinconf_config_dbg_show(struct pinctrl_dev *pctldev, ++ struct seq_file *s, ++ unsigned long config) ++{ ++ pinconf_generic_dump_config(pctldev, s, config); ++} ++ ++static const struct pinconf_ops pcs_pinconf_ops = { ++ .pin_config_get = pcs_pinconf_get, ++ .pin_config_set = pcs_pinconf_set, ++ .pin_config_group_get = pcs_pinconf_group_get, ++ .pin_config_group_set = pcs_pinconf_group_set, ++ .pin_config_dbg_show = pcs_pinconf_dbg_show, ++ .pin_config_group_dbg_show = pcs_pinconf_group_dbg_show, ++ .pin_config_config_dbg_show = pcs_pinconf_config_dbg_show, ++ .is_generic = true, ++}; ++ ++/** ++ * pcs_add_pin() - add a pin to the static per controller pin array ++ * @pcs: pcs driver instance ++ * @offset: register offset from base ++ */ ++static int pcs_add_pin(struct pcs_device *pcs, unsigned int offset) ++{ ++ int i; ++ unsigned int val; ++ struct pinctrl_pin_desc *pin; ++ struct pcs_soc_data *pcs_soc = &pcs->socdata; ++ ++ i = pcs->pins.cur; ++ if (i >= pcs->desc.npins) { ++ dev_err(pcs->dev, "too many pins, max %i\n", pcs->desc.npins); ++ return -ENOMEM; ++ } ++ ++ if (pcs_soc->irq_enable_mask) { ++ val = pcs->read(pcs->base + offset); ++ if (val & pcs_soc->irq_enable_mask) { ++ dev_dbg(pcs->dev, "irq enabled at boot for pin at %lx (%x), clearing\n", ++ (unsigned long)pcs->res->start + offset, val); ++ val &= ~pcs_soc->irq_enable_mask; ++ pcs->write(val, pcs->base + offset); ++ } ++ } ++ ++ pin = &pcs->pins.pa[i]; ++ pin->number = i; ++ pcs->pins.cur++; ++ ++ return i; ++} ++ ++/** ++ * pcs_allocate_pin_table() - adds all the pins for the pinctrl driver ++ * @pcs: pcs driver instance ++ * ++ * In case of errors, resources are freed in pcs_free_resources. ++ * ++ * If your hardware needs holes in the address space, then just set ++ * up multiple driver instances. ++ */ ++static int pcs_allocate_pin_table(struct pcs_device *pcs) ++{ ++ int i, res, mux_bytes, nr_pins; ++ unsigned int offset; ++ ++ mux_bytes = pcs->width / BITS_PER_BYTE; ++ ++ if (pcs->bits_per_mux && pcs->fmask) { ++ pcs->bits_per_pin = fls(pcs->fmask); ++ nr_pins = (pcs->size * BITS_PER_BYTE) / pcs->bits_per_pin; ++ } else { ++ nr_pins = pcs->size / mux_bytes; ++ } ++ ++ dev_dbg(pcs->dev, "allocating %i pins\n", nr_pins); ++ pcs->pins.pa = devm_kcalloc(pcs->dev, nr_pins, sizeof(*pcs->pins.pa), ++ GFP_KERNEL); ++ if (!pcs->pins.pa) ++ return -ENOMEM; ++ ++ pcs->desc.pins = pcs->pins.pa; ++ pcs->desc.npins = nr_pins; ++ ++ for (i = 0; i < pcs->desc.npins; i++) { ++ offset = pcs_pin_reg_offset_get(pcs, i); ++ res = pcs_add_pin(pcs, offset); ++ if (res < 0) { ++ dev_err(pcs->dev, "error adding pins: %i\n", res); ++ return res; ++ } ++ } ++ ++ return 0; ++} ++ ++/** ++ * pcs_add_function() - adds a new function to the function list ++ * @pcs: pcs driver instance ++ * @fcn: new function allocated ++ * @name: name of the function ++ * @vals: array of mux register value pairs used by the function ++ * @nvals: number of mux register value pairs ++ * @pgnames: array of pingroup names for the function ++ * @npgnames: number of pingroup names ++ * ++ * Caller must take care of locking. ++ */ ++static int pcs_add_function(struct pcs_device *pcs, struct pcs_function **fcn, ++ const char *name, struct pcs_func_vals *vals, ++ unsigned int nvals, const char **pgnames, ++ unsigned int npgnames) ++{ ++ int selector; ++ struct pcs_function *function; ++ ++ function = devm_kzalloc(pcs->dev, sizeof(*function), GFP_KERNEL); ++ if (!function) ++ return -ENOMEM; ++ ++ function->vals = vals; ++ function->nvals = nvals; ++ function->name = name; ++ ++ selector = pinmux_generic_add_function(pcs->pctl, name, pgnames, npgnames, function); ++ if (selector < 0) { ++ devm_kfree(pcs->dev, function); ++ *fcn = NULL; ++ } else { ++ *fcn = function; ++ } ++ ++ return selector; ++} ++ ++/** ++ * pcs_get_pin_by_offset() - get a pin index based on the register offset ++ * @pcs: pcs driver instance ++ * @offset: register offset from the base ++ * ++ * Note that this is OK as long as the pins are in a static array. ++ */ ++static int pcs_get_pin_by_offset(struct pcs_device *pcs, unsigned int offset) ++{ ++ unsigned int index; ++ ++ if (offset >= pcs->size) { ++ dev_err(pcs->dev, "mux offset out of range: 0x%x (0x%x)\n", offset, pcs->size); ++ return -EINVAL; ++ } ++ ++ if (pcs->bits_per_mux) ++ index = (offset * BITS_PER_BYTE) / pcs->bits_per_pin; ++ else ++ index = offset / (pcs->width / BITS_PER_BYTE); ++ ++ return index; ++} ++ ++/* ++ * check whether data matches enable bits or disable bits ++ * Return value: 1 for matching enable bits, 0 for matching disable bits, ++ * and negative value for matching failure. ++ */ ++static int pcs_config_match(unsigned int data, unsigned int enable, unsigned int disable) ++{ ++ int ret = -EINVAL; ++ ++ if (data == enable) ++ ret = 1; ++ else if (data == disable) ++ ret = 0; ++ return ret; ++} ++ ++static void add_config(struct pcs_conf_vals **conf, ++ enum pin_config_param param, ++ unsigned int value, unsigned int enable, ++ unsigned int disable, unsigned int mask) ++{ ++ (*conf)->param = param; ++ (*conf)->val = value; ++ (*conf)->enable = enable; ++ (*conf)->disable = disable; ++ (*conf)->mask = mask; ++ (*conf)++; ++} ++ ++static void add_setting(unsigned long **setting, enum pin_config_param param, unsigned int arg) ++{ ++ **setting = pinconf_to_config_packed(param, arg); ++ (*setting)++; ++} ++ ++/* add pinconf setting with 2 parameters */ ++static void pcs_add_conf2(struct pcs_device *pcs, struct device_node *np, ++ const char *name, enum pin_config_param param, ++ struct pcs_conf_vals **conf, unsigned long **settings) ++{ ++ int ret; ++ unsigned int value[2], shift; ++ ++ ret = of_property_read_u32_array(np, name, value, 2); ++ if (ret) ++ return; ++ /* set value & mask */ ++ value[0] &= value[1]; ++ shift = ffs(value[1]) - 1; ++ /* skip enable & disable */ ++ add_config(conf, param, value[0], 0, 0, value[1]); ++ add_setting(settings, param, value[0] >> shift); ++} ++ ++/* add pinconf setting with 4 parameters */ ++static void pcs_add_conf4(struct pcs_device *pcs, struct device_node *np, ++ const char *name, enum pin_config_param param, ++ struct pcs_conf_vals **conf, unsigned long **settings) ++{ ++ int ret; ++ unsigned int value[4]; ++ ++ /* value to set, enable, disable, mask */ ++ ret = of_property_read_u32_array(np, name, value, 4); ++ if (ret) ++ return; ++ if (!value[3]) { ++ dev_err(pcs->dev, "mask field of the property can't be 0\n"); ++ return; ++ } ++ value[0] &= value[3]; ++ value[1] &= value[3]; ++ value[2] &= value[3]; ++ ret = pcs_config_match(value[0], value[1], value[2]); ++ if (ret < 0) ++ dev_dbg(pcs->dev, "failed to match enable or disable bits\n"); ++ add_config(conf, param, value[0], value[1], value[2], value[3]); ++ add_setting(settings, param, ret); ++} ++ ++static int pcs_parse_pinconf(struct pcs_device *pcs, struct device_node *np, ++ struct pcs_function *func, ++ struct pinctrl_map **map) ++ ++{ ++ int i = 0, nconfs = 0; ++ struct pinctrl_map *m = *map; ++ unsigned long *settings = NULL, *s = NULL; ++ struct pcs_conf_vals *conf = NULL; ++ static const struct pcs_conf_type prop2[] = { ++ { "pinctrl-single,drive-strength", PIN_CONFIG_DRIVE_STRENGTH, }, ++ { "pinctrl-single,slew-rate", PIN_CONFIG_SLEW_RATE, }, ++ { "pinctrl-single,input-enable", PIN_CONFIG_INPUT_ENABLE, }, ++ { "pinctrl-single,input-schmitt", PIN_CONFIG_INPUT_SCHMITT, }, ++ { "pinctrl-single,output-enable", PIN_CONFIG_OUTPUT_ENABLE, }, ++ { "pinctrl-single,output", PIN_CONFIG_OUTPUT, }, ++ { "pinctrl-single,low-power-mode", PIN_CONFIG_MODE_LOW_POWER, }, ++ }; ++ static const struct pcs_conf_type prop4[] = { ++ { "pinctrl-single,bias-pullup", PIN_CONFIG_BIAS_PULL_UP, }, ++ { "pinctrl-single,bias-pulldown", PIN_CONFIG_BIAS_PULL_DOWN, }, ++ { "pinctrl-single,input-schmitt-enable", ++ PIN_CONFIG_INPUT_SCHMITT_ENABLE, }, ++ }; ++ ++ /* If pinconf isn't supported, don't parse properties in below. */ ++ if (!PCS_HAS_PINCONF(pcs)) ++ return -EOPNOTSUPP; ++ ++ /* cacluate how much properties are supported in current node */ ++ for (i = 0; i < ARRAY_SIZE(prop2); i++) { ++ if (of_property_present(np, prop2[i].name)) ++ nconfs++; ++ } ++ for (i = 0; i < ARRAY_SIZE(prop4); i++) { ++ if (of_property_present(np, prop4[i].name)) ++ nconfs++; ++ } ++ if (!nconfs) ++ return -EOPNOTSUPP; ++ ++ func->conf = devm_kcalloc(pcs->dev, nconfs, sizeof(struct pcs_conf_vals), GFP_KERNEL); ++ if (!func->conf) ++ return -ENOMEM; ++ func->nconfs = nconfs; ++ conf = &func->conf[0]; ++ m++; ++ settings = devm_kcalloc(pcs->dev, nconfs, sizeof(unsigned long), GFP_KERNEL); ++ if (!settings) ++ return -ENOMEM; ++ s = &settings[0]; ++ ++ for (i = 0; i < ARRAY_SIZE(prop2); i++) ++ pcs_add_conf2(pcs, np, prop2[i].name, prop2[i].param, ++ &conf, &s); ++ for (i = 0; i < ARRAY_SIZE(prop4); i++) ++ pcs_add_conf4(pcs, np, prop4[i].name, prop4[i].param, ++ &conf, &s); ++ m->type = PIN_MAP_TYPE_CONFIGS_GROUP; ++ m->data.configs.group_or_pin = np->name; ++ m->data.configs.configs = settings; ++ m->data.configs.num_configs = nconfs; ++ return 0; ++} ++ ++/** ++ * pcs_parse_one_pinctrl_entry() - parses a device tree mux entry ++ * @pcs: pinctrl driver instance ++ * @np: device node of the mux entry ++ * @map: map entry ++ * @num_maps: number of map ++ * @pgnames: pingroup names ++ * ++ * Note that this binding currently supports only sets of one register + value. ++ * ++ * Also note that this driver tries to avoid understanding pin and function ++ * names because of the extra bloat they would cause especially in the case of ++ * a large number of pins. This driver just sets what is specified for the board ++ * in the .dts file. Further user space debugging tools can be developed to ++ * decipher the pin and function names using debugfs. ++ * ++ * If you are concerned about the boot time, set up the static pins in ++ * the bootloader, and only set up selected pins as device tree entries. ++ */ ++static int pcs_parse_one_pinctrl_entry(struct pcs_device *pcs, ++ struct device_node *np, ++ struct pinctrl_map **map, ++ unsigned int *num_maps, ++ const char **pgnames) ++{ ++ unsigned int offset; ++ struct pcs_func_vals *vals; ++ int i, fsel, gsel, pin, rows, *pins, found = 0, res = -ENOMEM; ++ struct pcs_function *function = NULL; ++ struct of_phandle_args pinctrl_spec; ++ const char *name = "pinctrl-single,pins"; ++ ++ rows = pinctrl_count_index_with_args(np, name); ++ if (rows <= 0) { ++ dev_err(pcs->dev, "Invalid number of rows: %d\n", rows); ++ return -EINVAL; ++ } ++ ++ vals = devm_kcalloc(pcs->dev, rows, sizeof(*vals), GFP_KERNEL); ++ if (!vals) ++ return -ENOMEM; ++ ++ pins = devm_kcalloc(pcs->dev, rows, sizeof(*pins), GFP_KERNEL); ++ if (!pins) ++ goto free_vals; ++ ++ for (i = 0; i < rows; i++) { ++ res = pinctrl_parse_index_with_args(np, name, i, &pinctrl_spec); ++ if (res) ++ return res; ++ ++ if (pinctrl_spec.args_count < 2 || pinctrl_spec.args_count > 3) { ++ dev_err(pcs->dev, "invalid args_count for spec: %i\n", ++ pinctrl_spec.args_count); ++ break; ++ } ++ ++ offset = pinctrl_spec.args[0]; ++ vals[found].reg = pcs->base + offset; ++ ++ switch (pinctrl_spec.args_count) { ++ case 2: ++ vals[found].val = pinctrl_spec.args[1]; ++ break; ++ case 3: ++ vals[found].val = (pinctrl_spec.args[1] | pinctrl_spec.args[2]); ++ break; ++ default: ++ break; ++ } ++ ++ dev_dbg(pcs->dev, "%pOFn index: 0x%x value: 0x%x\n", ++ pinctrl_spec.np, offset, vals[found].val); ++ ++ pin = pcs_get_pin_by_offset(pcs, offset); ++ if (pin < 0) { ++ dev_err(pcs->dev, ++ "could not add functions for %pOFn %ux\n", ++ np, offset); ++ break; ++ } ++ pins[found++] = pin; ++ } ++ ++ pgnames[0] = np->name; ++ mutex_lock(&pcs->mutex); ++ fsel = pcs_add_function(pcs, &function, np->name, vals, found, pgnames, 1); ++ if (fsel < 0) { ++ res = fsel; ++ goto free_pins; ++ } ++ ++ gsel = pinctrl_generic_add_group(pcs->pctl, np->name, pins, found, pcs); ++ if (gsel < 0) { ++ res = gsel; ++ goto free_function; ++ } ++ ++ (*map)->type = PIN_MAP_TYPE_MUX_GROUP; ++ (*map)->data.mux.group = np->name; ++ (*map)->data.mux.function = np->name; ++ ++ if (PCS_HAS_PINCONF(pcs) && function) { ++ res = pcs_parse_pinconf(pcs, np, function, map); ++ if (res == 0) ++ *num_maps = 2; ++ else if (res == -EOPNOTSUPP) ++ *num_maps = 1; ++ else ++ goto free_pingroups; ++ } else { ++ *num_maps = 1; ++ } ++ mutex_unlock(&pcs->mutex); ++ ++ return 0; ++ ++free_pingroups: ++ pinctrl_generic_remove_group(pcs->pctl, gsel); ++ *num_maps = 1; ++free_function: ++ pinmux_generic_remove_function(pcs->pctl, fsel); ++free_pins: ++ mutex_unlock(&pcs->mutex); ++ devm_kfree(pcs->dev, pins); ++ ++free_vals: ++ devm_kfree(pcs->dev, vals); ++ ++ return res; ++} ++ ++static int pcs_parse_bits_in_pinctrl_entry(struct pcs_device *pcs, ++ struct device_node *np, ++ struct pinctrl_map **map, ++ unsigned int *num_maps, ++ const char **pgnames) ++{ ++ const char *name = "pinctrl-single,bits"; ++ struct pcs_func_vals *vals; ++ int i, fsel, pin, rows, *pins, npins_in_row, found = 0, res = -ENOMEM; ++ struct pcs_function *function = NULL; ++ struct of_phandle_args pinctrl_spec; ++ unsigned int offset, val, pin_num_from_lsb; ++ unsigned int mask, bit_pos, val_pos, mask_pos, submask; ++ ++ rows = pinctrl_count_index_with_args(np, name); ++ if (rows <= 0) { ++ dev_err(pcs->dev, "Invalid number of rows: %d\n", rows); ++ return -EINVAL; ++ } ++ ++ if (PCS_HAS_PINCONF(pcs)) { ++ dev_err(pcs->dev, "pinconf not supported\n"); ++ return -EOPNOTSUPP; ++ } ++ ++ npins_in_row = pcs->width / pcs->bits_per_pin; ++ ++ vals = devm_kzalloc(pcs->dev, ++ array3_size(rows, npins_in_row, sizeof(*vals)), ++ GFP_KERNEL); ++ if (!vals) ++ return -ENOMEM; ++ ++ pins = devm_kzalloc(pcs->dev, ++ array3_size(rows, npins_in_row, sizeof(*pins)), ++ GFP_KERNEL); ++ if (!pins) ++ goto free_vals; ++ ++ for (i = 0; i < rows; i++) { ++ res = pinctrl_parse_index_with_args(np, name, i, &pinctrl_spec); ++ if (res) ++ return res; ++ ++ if (pinctrl_spec.args_count < 3) { ++ dev_err(pcs->dev, "invalid args_count for spec: %i\n", ++ pinctrl_spec.args_count); ++ break; ++ } ++ ++ /* Index plus two value cells */ ++ offset = pinctrl_spec.args[0]; ++ val = pinctrl_spec.args[1]; ++ mask = pinctrl_spec.args[2]; ++ ++ dev_dbg(pcs->dev, "%pOFn index: 0x%x value: 0x%x mask: 0x%x\n", ++ pinctrl_spec.np, offset, val, mask); ++ ++ /* Parse pins in each row from LSB */ ++ while (mask) { ++ bit_pos = __ffs(mask); ++ pin_num_from_lsb = bit_pos / pcs->bits_per_pin; ++ mask_pos = ((pcs->fmask) << bit_pos); ++ val_pos = val & mask_pos; ++ submask = mask & mask_pos; ++ ++ if ((mask & mask_pos) == 0) { ++ dev_err(pcs->dev, ++ "Invalid mask for %pOFn at 0x%x\n", ++ np, offset); ++ break; ++ } ++ ++ mask &= ~mask_pos; ++ ++ if (submask != mask_pos) { ++ dev_warn(pcs->dev, ++ "Invalid submask 0x%x for %pOFn at 0x%x\n", ++ submask, np, offset); ++ continue; ++ } ++ ++ vals[found].mask = submask; ++ vals[found].reg = pcs->base + offset; ++ vals[found].val = val_pos; ++ ++ pin = pcs_get_pin_by_offset(pcs, offset); ++ if (pin < 0) { ++ dev_err(pcs->dev, ++ "could not add functions for %pOFn %ux\n", ++ np, offset); ++ break; ++ } ++ pins[found++] = pin + pin_num_from_lsb; ++ } ++ } ++ ++ pgnames[0] = np->name; ++ mutex_lock(&pcs->mutex); ++ fsel = pcs_add_function(pcs, &function, np->name, vals, found, pgnames, 1); ++ if (fsel < 0) { ++ res = fsel; ++ goto free_pins; ++ } ++ ++ res = pinctrl_generic_add_group(pcs->pctl, np->name, pins, found, pcs); ++ if (res < 0) ++ goto free_function; ++ ++ (*map)->type = PIN_MAP_TYPE_MUX_GROUP; ++ (*map)->data.mux.group = np->name; ++ (*map)->data.mux.function = np->name; ++ ++ *num_maps = 1; ++ mutex_unlock(&pcs->mutex); ++ ++ return 0; ++ ++free_function: ++ pinmux_generic_remove_function(pcs->pctl, fsel); ++free_pins: ++ mutex_unlock(&pcs->mutex); ++ devm_kfree(pcs->dev, pins); ++ ++free_vals: ++ devm_kfree(pcs->dev, vals); ++ ++ return res; ++} ++ ++/** ++ * pcs_dt_node_to_map() - allocates and parses pinctrl maps ++ * @pctldev: pinctrl instance ++ * @np_config: device tree pinmux entry ++ * @map: array of map entries ++ * @num_maps: number of maps ++ */ ++static int pcs_dt_node_to_map(struct pinctrl_dev *pctldev, ++ struct device_node *np_config, ++ struct pinctrl_map **map, unsigned int *num_maps) ++{ ++ int ret; ++ const char **pgnames; ++ struct pcs_device *pcs; ++ ++ pcs = pinctrl_dev_get_drvdata(pctldev); ++ ++ /* create 2 maps. One is for pinmux, and the other is for pinconf. */ ++ *map = devm_kcalloc(pcs->dev, 2, sizeof(**map), GFP_KERNEL); ++ if (!*map) ++ return -ENOMEM; ++ ++ *num_maps = 0; ++ ++ pgnames = devm_kzalloc(pcs->dev, sizeof(*pgnames), GFP_KERNEL); ++ if (!pgnames) { ++ ret = -ENOMEM; ++ goto free_map; ++ } ++ ++ if (pcs->bits_per_mux) { ++ ret = pcs_parse_bits_in_pinctrl_entry(pcs, np_config, map, ++ num_maps, pgnames); ++ if (ret < 0) { ++ dev_err(pcs->dev, "no pins entries for %pOFn\n", ++ np_config); ++ goto free_pgnames; ++ } ++ } else { ++ ret = pcs_parse_one_pinctrl_entry(pcs, np_config, map, ++ num_maps, pgnames); ++ if (ret < 0) { ++ dev_err(pcs->dev, "no pins entries for %pOFn\n", ++ np_config); ++ goto free_pgnames; ++ } ++ } ++ ++ return 0; ++ ++free_pgnames: ++ devm_kfree(pcs->dev, pgnames); ++free_map: ++ devm_kfree(pcs->dev, *map); ++ ++ return ret; ++} ++ ++/** ++ * pcs_irq_free() - free interrupt ++ * @pcs: pcs driver instance ++ */ ++static void pcs_irq_free(struct pcs_device *pcs) ++{ ++ struct pcs_soc_data *pcs_soc = &pcs->socdata; ++ ++ if (pcs_soc->irq < 0) ++ return; ++ ++ if (pcs->domain) ++ irq_domain_remove(pcs->domain); ++ ++ if (PCS_QUIRK_HAS_SHARED_IRQ(pcs)) ++ free_irq(pcs_soc->irq, pcs_soc); ++ else ++ irq_set_chained_handler(pcs_soc->irq, NULL); ++} ++ ++/** ++ * pcs_free_resources() - free memory used by this driver ++ * @pcs: pcs driver instance ++ */ ++static void pcs_free_resources(struct pcs_device *pcs) ++{ ++ pcs_irq_free(pcs); ++ ++#if IS_BUILTIN(CONFIG_PINCTRL_SINGLE) ++ if (pcs->missing_nr_pinctrl_cells) ++ of_remove_property(pcs->np, pcs->missing_nr_pinctrl_cells); ++#endif ++} ++ ++static int pcs_add_gpio_func(struct device_node *node, struct pcs_device *pcs) ++{ ++ int ret, i; ++ struct of_phandle_args gpiospec; ++ struct pcs_gpiofunc_range *range; ++ const char *propname = "pinctrl-single,gpio-range"; ++ const char *cellname = "#pinctrl-single,gpio-range-cells"; ++ ++ for (i = 0; ; i++) { ++ ret = of_parse_phandle_with_args(node, propname, cellname, ++ i, &gpiospec); ++ /* Do not treat it as error. Only treat it as end condition. */ ++ if (ret) { ++ ret = 0; ++ break; ++ } ++ range = devm_kzalloc(pcs->dev, sizeof(*range), GFP_KERNEL); ++ if (!range) { ++ ret = -ENOMEM; ++ break; ++ } ++ range->offset = gpiospec.args[0]; ++ range->npins = gpiospec.args[1]; ++ range->gpiofunc = gpiospec.args[2]; ++ mutex_lock(&pcs->mutex); ++ list_add_tail(&range->node, &pcs->gpiofuncs); ++ mutex_unlock(&pcs->mutex); ++ } ++ return ret; ++} ++ ++/** ++ * struct pcs_interrupt ++ * @reg: virtual address of interrupt register ++ * @hwirq: hardware irq number ++ * @irq: virtual irq number ++ * @node: list node ++ */ ++struct pcs_interrupt { ++ void __iomem *reg; ++ irq_hw_number_t hwirq; ++ unsigned int irq; ++ struct list_head node; ++}; ++ ++/** ++ * pcs_irq_set() - enables or disables an interrupt ++ * @pcs_soc: SoC specific settings ++ * @irq: interrupt ++ * @enable: enable or disable the interrupt ++ * ++ * Note that this currently assumes one interrupt per pinctrl ++ * register that is typically used for wake-up events. ++ */ ++static inline void pcs_irq_set(struct pcs_soc_data *pcs_soc, int irq, const bool enable) ++{ ++ struct pcs_device *pcs; ++ struct list_head *pos; ++ unsigned int mask, soc_mask; ++ struct pcs_interrupt *pcswi; ++ ++ pcs = container_of(pcs_soc, struct pcs_device, socdata); ++ list_for_each(pos, &pcs->irqs) { ++ pcswi = list_entry(pos, struct pcs_interrupt, node); ++ if (irq != pcswi->irq) ++ continue; ++ ++ soc_mask = pcs_soc->irq_enable_mask; ++ raw_spin_lock(&pcs->lock); ++ mask = pcs->read(pcswi->reg); ++ if (enable) ++ mask |= soc_mask; ++ else ++ mask &= ~soc_mask; ++ pcs->write(mask, pcswi->reg); ++ ++ /* flush posted write */ ++ mask = pcs->read(pcswi->reg); ++ raw_spin_unlock(&pcs->lock); ++ } ++ ++ if (pcs_soc->rearm) ++ pcs_soc->rearm(); ++} ++ ++/** ++ * pcs_irq_mask() - mask pinctrl interrupt ++ * @d: interrupt data ++ */ ++static void pcs_irq_mask(struct irq_data *d) ++{ ++ struct pcs_soc_data *pcs_soc = irq_data_get_irq_chip_data(d); ++ ++ pcs_irq_set(pcs_soc, d->irq, true); ++} ++ ++/** ++ * pcs_irq_unmask() - unmask pinctrl interrupt ++ * @d: interrupt data ++ */ ++static void pcs_irq_unmask(struct irq_data *d) ++{ ++ struct pcs_soc_data *pcs_soc = irq_data_get_irq_chip_data(d); ++ ++ pcs_irq_set(pcs_soc, d->irq, false); ++} ++ ++/** ++ * pcs_irq_set_wake() - toggle the suspend and resume wake up ++ * @d: interrupt data ++ * @state: wake-up state ++ * ++ * Note that this should be called only for suspend and resume. ++ * For runtime PM, the wake-up events should be enabled by default. ++ */ ++static int pcs_irq_set_wake(struct irq_data *d, unsigned int state) ++{ ++ if (state) ++ pcs_irq_unmask(d); ++ else ++ pcs_irq_mask(d); ++ ++ return 0; ++} ++ ++static inline void _pcs_irq_set_type(struct pcs_soc_data *pcs_soc, int irq, int flow_type) ++{ ++ struct pcs_device *pcs; ++ struct list_head *pos; ++ unsigned int mask, soc_mask; ++ struct pcs_interrupt *pcswi; ++ ++ pcs = container_of(pcs_soc, struct pcs_device, socdata); ++ list_for_each(pos, &pcs->irqs) { ++ pcswi = list_entry(pos, struct pcs_interrupt, node); ++ if (irq != pcswi->irq) ++ continue; ++ ++ soc_mask = pcs_soc->irq_enable_mask; ++ raw_spin_lock(&pcs->lock); ++ mask = pcs->read(pcswi->reg); ++ ++ if (flow_type == IRQ_TYPE_EDGE_RISING) ++ mask |= (1 << EDGE_RISE_EN); ++ else ++ mask &= ~(1 << EDGE_RISE_EN); ++ ++ if (flow_type == IRQ_TYPE_EDGE_FALLING) ++ mask |= (1 << EDGE_FALL_EN); ++ else ++ mask &= ~(1 << EDGE_FALL_EN); ++ ++ pcs->write(mask, pcswi->reg); ++ ++ /* flush posted write */ ++ mask = pcs->read(pcswi->reg); ++ raw_spin_unlock(&pcs->lock); ++ } ++} ++ ++static int pcs_irq_set_type(struct irq_data *d, unsigned int flow_type) ++{ ++ struct pcs_soc_data *pcs_soc = irq_data_get_irq_chip_data(d); ++ ++ _pcs_irq_set_type(pcs_soc, d->irq, flow_type); ++ ++ return 0; ++} ++ ++/** ++ * pcs_irq_handle() - common interrupt handler ++ * @pcs_soc: SoC specific settings ++ * ++ * Note that this currently assumes we have one interrupt bit per ++ * mux register. This interrupt is typically used for wake-up events. ++ * For more complex interrupts different handlers can be specified. ++ */ ++static int pcs_irq_handle(struct pcs_soc_data *pcs_soc) ++{ ++ int count = 0; ++ struct list_head *pos; ++ struct pcs_device *pcs; ++ struct pcs_interrupt *pcswi; ++ unsigned int mask, reg_offset, bit_offset; ++ ++ pcs = container_of(pcs_soc, struct pcs_device, socdata); ++ list_for_each(pos, &pcs->irqs) { ++ pcswi = list_entry(pos, struct pcs_interrupt, node); ++ reg_offset = (pcswi->hwirq / 4 - 1) / 32 * 4; ++ bit_offset = (pcswi->hwirq / 4 - 1) - reg_offset / 4 * 32; ++ ++ raw_spin_lock(&pcs->lock); ++ mask = pcs->read(pcs->gedge_flag_base + reg_offset); ++ raw_spin_unlock(&pcs->lock); ++ ++ if (mask & (1 << bit_offset)) { ++ generic_handle_domain_irq(pcs->domain, pcswi->hwirq); ++ count++; ++ } ++ } ++ ++ return count; ++} ++ ++/** ++ * pcs_irq_handler() - handler for the shared interrupt case ++ * @irq: interrupt ++ * @d: data ++ * ++ * Use this for cases where multiple instances of ++ * pinctrl-single share a single interrupt like on omaps. ++ */ ++static irqreturn_t pcs_irq_handler(int irq, void *d) ++{ ++ struct pcs_soc_data *pcs_soc = d; ++ ++ return pcs_irq_handle(pcs_soc) ? IRQ_HANDLED : IRQ_NONE; ++} ++ ++/** ++ * pcs_irq_chain_handler() - handler for the dedicated chained interrupt case ++ * @desc: interrupt descriptor ++ * ++ * Use this if you have a separate interrupt for each ++ * pinctrl-single instance. ++ */ ++static void pcs_irq_chain_handler(struct irq_desc *desc) ++{ ++ struct irq_chip *chip; ++ struct pcs_soc_data *pcs_soc = irq_desc_get_handler_data(desc); ++ ++ chip = irq_desc_get_chip(desc); ++ chained_irq_enter(chip, desc); ++ pcs_irq_handle(pcs_soc); ++ chained_irq_exit(chip, desc); ++} ++ ++static int pcs_irqdomain_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hwirq) ++{ ++ struct pcs_device *pcs; ++ struct pcs_interrupt *pcswi; ++ struct pcs_soc_data *pcs_soc = d->host_data; ++ ++ pcs = container_of(pcs_soc, struct pcs_device, socdata); ++ pcswi = devm_kzalloc(pcs->dev, sizeof(*pcswi), GFP_KERNEL); ++ if (!pcswi) ++ return -ENOMEM; ++ ++ pcswi->reg = pcs->base + hwirq; ++ pcswi->hwirq = hwirq; ++ pcswi->irq = irq; ++ ++ mutex_lock(&pcs->mutex); ++ list_add_tail(&pcswi->node, &pcs->irqs); ++ mutex_unlock(&pcs->mutex); ++ ++ irq_set_chip_data(irq, pcs_soc); ++ irq_set_chip_and_handler(irq, &pcs->chip, ++ handle_level_irq); ++ irq_set_lockdep_class(irq, &pcs_lock_class, &pcs_request_class); ++ irq_set_noprobe(irq); ++ ++ return 0; ++} ++ ++static const struct irq_domain_ops pcs_irqdomain_ops = { ++ .map = pcs_irqdomain_map, ++ .xlate = irq_domain_xlate_onecell, ++}; ++ ++/** ++ * pcs_irq_init_chained_handler() - set up a chained interrupt handler ++ * @pcs: pcs driver instance ++ * @np: device node pointer ++ */ ++static int pcs_irq_init_chained_handler(struct pcs_device *pcs, struct device_node *np) ++{ ++ int num_irqs; ++ const char *name = "pinctrl"; ++ struct pcs_soc_data *pcs_soc = &pcs->socdata; ++ ++ if (!pcs_soc->irq_enable_mask || !pcs_soc->irq_status_mask) { ++ pcs_soc->irq = -1; ++ return -EINVAL; ++ } ++ ++ INIT_LIST_HEAD(&pcs->irqs); ++ pcs->chip.name = name; ++ pcs->chip.irq_ack = pcs_irq_mask; ++ pcs->chip.irq_mask = pcs_irq_mask; ++ pcs->chip.irq_unmask = pcs_irq_unmask; ++ pcs->chip.irq_set_wake = pcs_irq_set_wake; ++ pcs->chip.flags = IRQCHIP_SKIP_SET_WAKE; ++ pcs->chip.irq_set_type = pcs_irq_set_type; ++ ++ if (PCS_QUIRK_HAS_SHARED_IRQ(pcs)) { ++ int res; ++ ++ res = request_irq(pcs_soc->irq, pcs_irq_handler, ++ IRQF_SHARED | IRQF_NO_SUSPEND | IRQF_NO_THREAD, ++ name, pcs_soc); ++ if (res) { ++ pcs_soc->irq = -1; ++ return res; ++ } ++ } else { ++ irq_set_chained_handler_and_data(pcs_soc->irq, ++ pcs_irq_chain_handler, ++ pcs_soc); ++ } ++ ++ /* ++ * We can use the register offset as the hardirq ++ * number as irq_domain_add_simple maps them lazily. ++ * This way we can easily support more than one ++ * interrupt per function if needed. ++ */ ++ num_irqs = pcs->size; ++ ++ pcs->domain = irq_domain_add_simple(np, num_irqs, 0, ++ &pcs_irqdomain_ops, ++ pcs_soc); ++ if (!pcs->domain) { ++ irq_set_chained_handler(pcs_soc->irq, NULL); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++#ifdef CONFIG_PM_SLEEP ++static struct pcs_device *pinctrl_pcs; ++ ++static int pinctrl_syscore_suspend(void) ++{ ++ pinctrl_force_sleep(pinctrl_pcs->pctl); ++ ++ return 0; ++} ++ ++static void pinctrl_syscore_resume(void) ++{ ++ pinctrl_force_default(pinctrl_pcs->pctl); ++} ++ ++static struct syscore_ops pinctrl_syscore_ops = { ++ .suspend = pinctrl_syscore_suspend, ++ .resume = pinctrl_syscore_resume, ++}; ++#endif ++ ++/** ++ * pcs_quirk_missing_pinctrl_cells - handle legacy binding ++ * @pcs: pinctrl driver instance ++ * @np: device tree node ++ * @cells: number of cells ++ * ++ * Handle legacy binding with no #pinctrl-cells. This should be ++ * always two pinctrl-single,bit-per-mux and one for others. ++ * At some point we may want to consider removing this. ++ */ ++static int pcs_quirk_missing_pinctrl_cells(struct pcs_device *pcs, ++ struct device_node *np, ++ int cells) ++{ ++ u32 val; ++ int error; ++ struct property *p; ++ const char *name = "#pinctrl-cells"; ++ ++ error = of_property_read_u32(np, name, &val); ++ if (!error) ++ return 0; ++ ++ dev_warn(pcs->dev, "please update dts to use %s = <%i>\n", name, cells); ++ ++ p = devm_kzalloc(pcs->dev, sizeof(*p), GFP_KERNEL); ++ if (!p) ++ return -ENOMEM; ++ ++ p->length = sizeof(__be32); ++ p->value = devm_kzalloc(pcs->dev, sizeof(__be32), GFP_KERNEL); ++ if (!p->value) ++ return -ENOMEM; ++ *(__be32 *)p->value = cpu_to_be32(cells); ++ ++ p->name = devm_kstrdup(pcs->dev, name, GFP_KERNEL); ++ if (!p->name) ++ return -ENOMEM; ++ ++ pcs->missing_nr_pinctrl_cells = p; ++ ++#if IS_BUILTIN(CONFIG_PINCTRL_SINGLE) ++ error = of_add_property(np, pcs->missing_nr_pinctrl_cells); ++#endif ++ ++ return error; ++} ++ ++static struct clk *psc_clk; ++static struct reset_control *psc_rst; ++ ++static int pcs_probe(struct platform_device *pdev) ++{ ++ int ret; ++ u32 regval, i; ++ void __iomem *base; ++ struct pcs_pdata *pdata; ++ struct resource *res; ++ struct pcs_device *pcs; ++ const struct pcs_soc_data *soc; ++ struct device_node *np = pdev->dev.of_node; ++ ++ soc = of_device_get_match_data(&pdev->dev); ++ if (WARN_ON(!soc)) ++ return -EINVAL; ++ ++ psc_rst = devm_reset_control_get_exclusive(&pdev->dev, "aib_rst"); ++ if (IS_ERR(psc_rst)) { ++ ret = PTR_ERR(psc_rst); ++ dev_err(&pdev->dev, "Failed to get reset: %d\n", ret); ++ return -EINVAL; ++ } ++ ++ /* deasser clk */ ++ ret = reset_control_deassert(psc_rst); ++ if (ret) { ++ dev_err(&pdev->dev, "Failed to deassert reset: %d\n", ret); ++ return -EINVAL; ++ } ++ ++ psc_clk = devm_clk_get(&pdev->dev, NULL); ++ if (IS_ERR(psc_clk)) { ++ dev_err(&pdev->dev, "Fail to get pinctrl clock, error %ld.\n", ++ PTR_ERR(psc_clk)); ++ return PTR_ERR(psc_clk); ++ } ++ ++ ret = clk_prepare_enable(psc_clk); ++ if (ret) { ++ dev_err(&pdev->dev, "Fail to enable pinctrl clock, error %d.\n", ret); ++ return ret; ++ } ++ ++ pcs = devm_kzalloc(&pdev->dev, sizeof(*pcs), GFP_KERNEL); ++ if (!pcs) ++ return -ENOMEM; ++ ++ pcs->dev = &pdev->dev; ++ pcs->np = np; ++ raw_spin_lock_init(&pcs->lock); ++ mutex_init(&pcs->mutex); ++ INIT_LIST_HEAD(&pcs->gpiofuncs); ++ pcs->flags = soc->flags; ++ memcpy(&pcs->socdata, soc, sizeof(*soc)); ++ ++ ret = of_property_read_u32(np, "pinctrl-single,register-width", &pcs->width); ++ if (ret) { ++ dev_err(pcs->dev, "register width not specified\n"); ++ ++ return ret; ++ } ++ ++ ret = of_property_read_u32(np, "pinctrl-single,function-mask", &pcs->fmask); ++ if (!ret) { ++ pcs->fshift = __ffs(pcs->fmask); ++ pcs->fmax = pcs->fmask >> pcs->fshift; ++ } else { ++ /* If mask property doesn't exist, function mux is invalid. */ ++ pcs->fmask = 0; ++ pcs->fshift = 0; ++ pcs->fmax = 0; ++ } ++ ++ ret = of_property_read_u32(np, "pinctrl-single,function-off", &pcs->foff); ++ if (ret) ++ pcs->foff = PCS_OFF_DISABLED; ++ ++ pcs->bits_per_mux = of_property_read_bool(np, "pinctrl-single,bit-per-mux"); ++ ret = pcs_quirk_missing_pinctrl_cells(pcs, np, pcs->bits_per_mux ? 2 : 1); ++ if (ret) { ++ dev_err(&pdev->dev, "unable to patch #pinctrl-cells\n"); ++ ++ return ret; ++ } ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (!res) { ++ dev_err(pcs->dev, "could not get resource\n"); ++ return -ENODEV; ++ } ++ ++ pcs->res = devm_request_mem_region(pcs->dev, res->start, ++ resource_size(res), DRIVER_NAME); ++ if (!pcs->res) { ++ dev_err(pcs->dev, "could not get mem_region\n"); ++ return -EBUSY; ++ } ++ ++ pcs->size = resource_size(pcs->res); ++ pcs->base = devm_ioremap(pcs->dev, pcs->res->start, pcs->size); ++ if (!pcs->base) { ++ dev_err(pcs->dev, "could not ioremap\n"); ++ return -ENODEV; ++ } ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 1); ++ if (!res) { ++ dev_err(pcs->dev, "could not get resource\n"); ++ return -ENODEV; ++ } ++ ++ pcs->gedge_flag_res = devm_request_mem_region(pcs->dev, res->start, ++ resource_size(res), ++ DRIVER_NAME); ++ if (!pcs->gedge_flag_res) { ++ dev_err(pcs->dev, "could not get mem_region\n"); ++ return -EBUSY; ++ } ++ ++ pcs->gedge_flag_size = resource_size(pcs->gedge_flag_res); ++ pcs->gedge_flag_base = devm_ioremap(pcs->dev, pcs->gedge_flag_res->start, ++ pcs->gedge_flag_size); ++ if (!pcs->gedge_flag_base) { ++ dev_err(pcs->dev, "could not ioremap\n"); ++ return -ENODEV; ++ } ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 2); ++ if (!res) { ++ dev_err(pcs->dev, "could not get resource\n"); ++ return -ENODEV; ++ } ++ ++ pcs->gpio_base = ioremap(res->start, resource_size(res)); ++ if (!pcs->gpio_base) { ++ dev_err(pcs->dev, "could not ioremap\n"); ++ return -ENODEV; ++ } ++ ++ platform_set_drvdata(pdev, pcs); ++ ++ switch (pcs->width) { ++ case 8: ++ pcs->read = pcs_readb; ++ pcs->write = pcs_writeb; ++ break; ++ case 16: ++ pcs->read = pcs_readw; ++ pcs->write = pcs_writew; ++ break; ++ case 32: ++ pcs->read = pcs_readl; ++ pcs->write = pcs_writel; ++ break; ++ default: ++ break; ++ } ++ ++ pcs->desc.name = DRIVER_NAME; ++ pcs->desc.pctlops = &pcs_pinctrl_ops; ++ pcs->desc.pmxops = &pcs_pinmux_ops; ++ if (PCS_HAS_PINCONF(pcs)) ++ pcs->desc.confops = &pcs_pinconf_ops; ++ pcs->desc.owner = THIS_MODULE; ++ ++ for (i = 4, base = pcs->base + 4; i < pcs->size; i += 4, base += 4) { ++ regval = pcs->read((void __iomem *)base); ++ regval |= (1 << EDGE_CLEAR); ++ regval &= ~(1 << EDGE_FALL_EN); ++ regval &= ~(1 << EDGE_RISE_EN); ++ pcs->write(regval, (void __iomem *)base); ++ } ++ ++ ret = pcs_allocate_pin_table(pcs); ++ if (ret < 0) ++ goto free; ++ ++ ret = devm_pinctrl_register_and_init(pcs->dev, &pcs->desc, pcs, &pcs->pctl); ++ if (ret) { ++ dev_err(pcs->dev, "could not register single pinctrl driver\n"); ++ goto free; ++ } ++ ++ ret = pcs_add_gpio_func(np, pcs); ++ if (ret < 0) ++ goto free; ++ ++ pcs->socdata.irq = irq_of_parse_and_map(np, 0); ++ if (pcs->socdata.irq) ++ pcs->flags |= PCS_FEAT_IRQ; ++ ++ /* We still need auxdata for some omaps for PRM interrupts */ ++ pdata = dev_get_platdata(&pdev->dev); ++ if (pdata) { ++ if (pdata->rearm) ++ pcs->socdata.rearm = pdata->rearm; ++ if (pdata->irq) { ++ pcs->socdata.irq = pdata->irq; ++ pcs->flags |= PCS_FEAT_IRQ; ++ } ++ } ++ ++ if (PCS_HAS_IRQ(pcs)) { ++ ret = pcs_irq_init_chained_handler(pcs, np); ++ if (ret < 0) ++ dev_warn(pcs->dev, "initialized with no interrupts\n"); ++ } ++ ++ dev_info(pcs->dev, "%i pins, size %u\n", pcs->desc.npins, pcs->size); ++ ++ dev_pm_set_wake_irq(&pdev->dev, pcs->socdata.irq); ++ device_init_wakeup(&pdev->dev, true); ++ ++#ifdef CONFIG_PM_SLEEP ++ pinctrl_pcs = pcs; ++ register_syscore_ops(&pinctrl_syscore_ops); ++#endif ++ ++ ret = pinctrl_enable(pcs->pctl); ++ if (ret) ++ goto free; ++ ++ return 0; ++free: ++ pcs_free_resources(pcs); ++ ++ return ret; ++} ++ ++static int pcs_remove(struct platform_device *pdev) ++{ ++ struct pcs_device *pcs = platform_get_drvdata(pdev); ++ ++ if (!pcs) ++ return 0; ++ ++ pcs_free_resources(pcs); ++ clk_disable_unprepare(psc_clk); ++ reset_control_assert(psc_rst); ++ ++ return 0; ++} ++ ++static const struct pcs_soc_data pinctrl_spacemit_k1x = { ++ .flags = PCS_QUIRK_SHARED_IRQ | PCS_FEAT_PINCONF, ++ .irq_enable_mask = (1 << EDGE_CLEAR), /* WAKEUPENABLE */ ++ .irq_status_mask = (1 << EDGE_CLEAR), /* WAKEUPENABLE */ ++}; ++ ++static const struct of_device_id pcs_of_match[] = { ++ { .compatible = "pinctrl-spacemit-k1x", .data = &pinctrl_spacemit_k1x }, ++ { }, ++}; ++MODULE_DEVICE_TABLE(of, pcs_of_match); ++ ++static struct platform_driver pcs_driver = { ++ .probe = pcs_probe, ++ .remove = pcs_remove, ++ .driver = { ++ .name = DRIVER_NAME, ++ .of_match_table = pcs_of_match, ++ }, ++}; ++ ++static int __init pcs_driver_init(void) ++{ ++ return platform_driver_register(&pcs_driver); ++} ++postcore_initcall(pcs_driver_init); ++ ++static void __exit pcs_driver_exit(void) ++{ ++ platform_driver_unregister(&pcs_driver); ++} ++module_exit(pcs_driver_exit); diff --git a/drivers/pinctrl/pinctrl-th1520.c b/drivers/pinctrl/pinctrl-th1520.c new file mode 100644 index 000000000000..2247ace7a7c7 @@ -448910,7 +458203,7 @@ index 000000000000..dea23e7d127e +MODULE_DESCRIPTION("XuanTie TH1520 Aon regulator virtual driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig -index ccd59ddd7610..b72f8626e03b 100644 +index ccd59ddd7610..663427a27d87 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -253,6 +253,16 @@ config RESET_SUNXI @@ -448930,8 +458223,21 @@ index ccd59ddd7610..b72f8626e03b 100644 config RESET_TI_SCI tristate "TI System Control Interface (TI-SCI) reset driver" depends on TI_SCI_PROTOCOL || (COMPILE_TEST && TI_SCI_PROTOCOL=n) +@@ -318,6 +328,12 @@ config RESET_ZYNQ + help + This enables the reset controller driver for Xilinx Zynq SoCs. + ++config RESET_K1X_SPACEMIT ++ tristate "Reset controller driver for Spacemit K1X SoCs" ++ depends on SOC_SPACEMIT_K1X ++ help ++ Support for reset controllers on Spacemit K1X SoCs. ++ + source "drivers/reset/starfive/Kconfig" + source "drivers/reset/sti/Kconfig" + source "drivers/reset/hisilicon/Kconfig" diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile -index 8270da8a4baa..ca0abdce468d 100644 +index 8270da8a4baa..4d61ad1991f2 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile @@ -33,6 +33,8 @@ obj-$(CONFIG_RESET_SIMPLE) += reset-simple.o @@ -448943,6 +458249,11 @@ index 8270da8a4baa..ca0abdce468d 100644 obj-$(CONFIG_RESET_TI_SCI) += reset-ti-sci.o obj-$(CONFIG_RESET_TI_SYSCON) += reset-ti-syscon.o obj-$(CONFIG_RESET_TI_TPS380X) += reset-tps380x.o +@@ -41,3 +43,4 @@ obj-$(CONFIG_RESET_UNIPHIER) += reset-uniphier.o + obj-$(CONFIG_RESET_UNIPHIER_GLUE) += reset-uniphier-glue.o + obj-$(CONFIG_RESET_ZYNQ) += reset-zynq.o + obj-$(CONFIG_ARCH_ZYNQMP) += reset-zynqmp.o ++obj-$(CONFIG_RESET_K1X_SPACEMIT) += reset-spacemit-k1x.o diff --git a/drivers/reset/reset-sophgo.c b/drivers/reset/reset-sophgo.c new file mode 100644 index 000000000000..3c46a43e24ba @@ -449112,6 +458423,681 @@ index 000000000000..3c46a43e24ba +MODULE_AUTHOR("Wei Huang"); +MODULE_DESCRIPTION("Bitmain SoC Reset Controoler Driver"); +MODULE_LICENSE("GPL"); +diff --git a/drivers/reset/reset-spacemit-k1x.c b/drivers/reset/reset-spacemit-k1x.c +new file mode 100644 +index 000000000000..d2ea9c9f196c +--- /dev/null ++++ b/drivers/reset/reset-spacemit-k1x.c +@@ -0,0 +1,669 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Spacemit k1x reset controller driver ++ * ++ * Copyright (c) 2023, spacemit Corporation. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* APBC register offset */ ++#define APBC_UART1_CLK_RST 0x0 ++#define APBC_UART2_CLK_RST 0x4 ++#define APBC_GPIO_CLK_RST 0x8 ++#define APBC_PWM0_CLK_RST 0xc ++#define APBC_PWM1_CLK_RST 0x10 ++#define APBC_PWM2_CLK_RST 0x14 ++#define APBC_PWM3_CLK_RST 0x18 ++#define APBC_TWSI8_CLK_RST 0x20 ++#define APBC_UART3_CLK_RST 0x24 ++#define APBC_RTC_CLK_RST 0x28 ++#define APBC_TWSI0_CLK_RST 0x2c ++#define APBC_TWSI1_CLK_RST 0x30 ++#define APBC_TIMERS1_CLK_RST 0x34 ++#define APBC_TWSI2_CLK_RST 0x38 ++#define APBC_AIB_CLK_RST 0x3c ++#define APBC_TWSI4_CLK_RST 0x40 ++#define APBC_TIMERS2_CLK_RST 0x44 ++#define APBC_ONEWIRE_CLK_RST 0x48 ++#define APBC_TWSI5_CLK_RST 0x4c ++#define APBC_DRO_CLK_RST 0x58 ++#define APBC_IR_CLK_RST 0x5c ++#define APBC_TWSI6_CLK_RST 0x60 ++#define APBC_TWSI7_CLK_RST 0x68 ++#define APBC_TSEN_CLK_RST 0x6c ++#define APBC_UART4_CLK_RST 0x70 ++#define APBC_UART5_CLK_RST 0x74 ++#define APBC_UART6_CLK_RST 0x78 ++#define APBC_SSP3_CLK_RST 0x7c ++#define APBC_SSPA0_CLK_RST 0x80 ++#define APBC_SSPA1_CLK_RST 0x84 ++#define APBC_IPC_AP2AUD_CLK_RST 0x90 ++#define APBC_UART7_CLK_RST 0x94 ++#define APBC_UART8_CLK_RST 0x98 ++#define APBC_UART9_CLK_RST 0x9c ++#define APBC_CAN0_CLK_RST 0xa0 ++#define APBC_PWM4_CLK_RST 0xa8 ++#define APBC_PWM5_CLK_RST 0xac ++#define APBC_PWM6_CLK_RST 0xb0 ++#define APBC_PWM7_CLK_RST 0xb4 ++#define APBC_PWM8_CLK_RST 0xb8 ++#define APBC_PWM9_CLK_RST 0xbc ++#define APBC_PWM10_CLK_RST 0xc0 ++#define APBC_PWM11_CLK_RST 0xc4 ++#define APBC_PWM12_CLK_RST 0xc8 ++#define APBC_PWM13_CLK_RST 0xcc ++#define APBC_PWM14_CLK_RST 0xd0 ++#define APBC_PWM15_CLK_RST 0xd4 ++#define APBC_PWM16_CLK_RST 0xd8 ++#define APBC_PWM17_CLK_RST 0xdc ++#define APBC_PWM18_CLK_RST 0xe0 ++#define APBC_PWM19_CLK_RST 0xe4 ++ ++/* MPMU register offset */ ++#define MPMU_WDTPCR 0x200 ++ ++/* APMU register offset */ ++#define APMU_JPG_CLK_RES_CTRL 0x20 ++#define APMU_CSI_CCIC2_CLK_RES_CTRL 0x24 ++#define APMU_ISP_CLK_RES_CTRL 0x38 ++#define APMU_LCD_CLK_RES_CTRL1 0x44 ++#define APMU_LCD_SPI_CLK_RES_CTRL 0x48 ++#define APMU_LCD_CLK_RES_CTRL2 0x4c ++#define APMU_CCIC_CLK_RES_CTRL 0x50 ++#define APMU_SDH0_CLK_RES_CTRL 0x54 ++#define APMU_SDH1_CLK_RES_CTRL 0x58 ++#define APMU_USB_CLK_RES_CTRL 0x5c ++#define APMU_QSPI_CLK_RES_CTRL 0x60 ++#define APMU_USB_CLK_RES_CTRL 0x5c ++#define APMU_DMA_CLK_RES_CTRL 0x64 ++#define APMU_AES_CLK_RES_CTRL 0x68 ++#define APMU_VPU_CLK_RES_CTRL 0xa4 ++#define APMU_GPU_CLK_RES_CTRL 0xcc ++#define APMU_SDH2_CLK_RES_CTRL 0xe0 ++#define APMU_PMUA_MC_CTRL 0xe8 ++#define APMU_PMU_CC2_AP 0x100 ++#define APMU_PMUA_EM_CLK_RES_CTRL 0x104 ++#define APMU_AUDIO_CLK_RES_CTRL 0x14c ++#define APMU_HDMI_CLK_RES_CTRL 0x1B8 ++#define APMU_PCIE_CLK_RES_CTRL_0 0x3cc ++#define APMU_PCIE_CLK_RES_CTRL_1 0x3d4 ++#define APMU_PCIE_CLK_RES_CTRL_2 0x3dc ++#define APMU_EMAC0_CLK_RES_CTRL 0x3e4 ++#define APMU_EMAC1_CLK_RES_CTRL 0x3ec ++ ++/* APBC2 register offset */ ++#define APBC2_UART1_CLK_RST 0x00 ++#define APBC2_SSP2_CLK_RST 0x04 ++#define APBC2_TWSI3_CLK_RST 0x08 ++#define APBC2_RTC_CLK_RST 0x0c ++#define APBC2_TIMERS0_CLK_RST 0x10 ++#define APBC2_KPC_CLK_RST 0x14 ++#define APBC2_GPIO_CLK_RST 0x1c ++/* end of APBC2 register offset */ ++ ++/* RCPU register offset */ ++#define RCPU_HDMI_CLK_RST 0x2044 ++#define RCPU_CAN_CLK_RST 0x4c ++#define RCPU_I2C0_CLK_RST 0x30 ++#define RCPU_SSP0_CLK_RST 0x28 ++#define RCPU_IR_CLK_RST 0x48 ++#define RCPU_UART0_CLK_RST 0xd8 ++#define RCPU_UART1_CLK_RST 0x3c ++ ++/* RCPU2 register offset */ ++#define RCPU2_PWM0_CLK_RST 0x00 ++#define RCPU2_PWM1_CLK_RST 0x04 ++#define RCPU2_PWM2_CLK_RST 0x08 ++#define RCPU2_PWM3_CLK_RST 0x0c ++#define RCPU2_PWM4_CLK_RST 0x10 ++#define RCPU2_PWM5_CLK_RST 0x14 ++#define RCPU2_PWM6_CLK_RST 0x18 ++#define RCPU2_PWM7_CLK_RST 0x1c ++#define RCPU2_PWM8_CLK_RST 0x20 ++#define RCPU2_PWM9_CLK_RST 0x24 ++ ++enum spacemit_reset_base_type { ++ RST_BASE_TYPE_MPMU = 0, ++ RST_BASE_TYPE_APMU = 1, ++ RST_BASE_TYPE_APBC = 2, ++ RST_BASE_TYPE_APBS = 3, ++ RST_BASE_TYPE_CIU = 4, ++ RST_BASE_TYPE_DCIU = 5, ++ RST_BASE_TYPE_DDRC = 6, ++ RST_BASE_TYPE_AUDC = 7, ++ RST_BASE_TYPE_APBC2 = 8, ++ RST_BASE_TYPE_RCPU = 9, ++ RST_BASE_TYPE_RCPU2 = 10, ++}; ++ ++struct spacemit_reset_signal { ++ u32 offset; ++ u32 mask; ++ u32 deassert_val; ++ u32 assert_val; ++ enum spacemit_reset_base_type type; ++}; ++ ++struct spacemit_reset_variant { ++ const struct spacemit_reset_signal *signals; ++ u32 signals_num; ++ const struct reset_control_ops ops; ++}; ++ ++struct spacemit_reset { ++ spinlock_t *lock; ++ struct reset_controller_dev rcdev; ++ void __iomem *mpmu_base; ++ void __iomem *apmu_base; ++ void __iomem *apbc_base; ++ void __iomem *apbs_base; ++ void __iomem *ciu_base; ++ void __iomem *dciu_base; ++ void __iomem *ddrc_base; ++ void __iomem *audio_ctrl_base; ++ void __iomem *apbc2_base; ++ void __iomem *rcpu_base; ++ void __iomem *rcpu2_base; ++ const struct spacemit_reset_signal *signals; ++}; ++ ++/* for register access protection */ ++extern spinlock_t g_cru_lock; ++struct spacemit_reset k1x_reset_controller; ++ ++static const struct spacemit_reset_signal ++ k1x_reset_signals[RESET_NUMBER] = { ++ [RESET_UART1] = { APBC_UART1_CLK_RST, BIT(2), 0, ++ BIT(2), RST_BASE_TYPE_APBC }, ++ [RESET_UART2] = { APBC_UART2_CLK_RST, BIT(2), 0, ++ BIT(2), RST_BASE_TYPE_APBC }, ++ [RESET_GPIO] = { APBC_GPIO_CLK_RST, BIT(2), 0, ++ BIT(2), RST_BASE_TYPE_APBC }, ++ [RESET_PWM0] = { APBC_PWM0_CLK_RST, BIT(2) | BIT(0), ++ BIT(0), BIT(2), RST_BASE_TYPE_APBC }, ++ [RESET_PWM1] = { APBC_PWM1_CLK_RST, BIT(2) | BIT(0), ++ BIT(0), BIT(2), RST_BASE_TYPE_APBC }, ++ [RESET_PWM2] = { APBC_PWM2_CLK_RST, BIT(2) | BIT(0), ++ BIT(0), BIT(2), RST_BASE_TYPE_APBC }, ++ [RESET_PWM3] = { APBC_PWM3_CLK_RST, BIT(2) | BIT(0), ++ BIT(0), BIT(2), RST_BASE_TYPE_APBC }, ++ [RESET_PWM4] = { APBC_PWM4_CLK_RST, BIT(2) | BIT(0), ++ BIT(0), BIT(2), RST_BASE_TYPE_APBC }, ++ [RESET_PWM5] = { APBC_PWM5_CLK_RST, BIT(2) | BIT(0), ++ BIT(0), BIT(2), RST_BASE_TYPE_APBC }, ++ [RESET_PWM6] = { APBC_PWM6_CLK_RST, BIT(2) | BIT(0), ++ BIT(0), BIT(2), RST_BASE_TYPE_APBC }, ++ [RESET_PWM7] = { APBC_PWM7_CLK_RST, BIT(2) | BIT(0), ++ BIT(0), BIT(2), RST_BASE_TYPE_APBC }, ++ [RESET_PWM8] = { APBC_PWM8_CLK_RST, BIT(2) | BIT(0), ++ BIT(0), BIT(2), RST_BASE_TYPE_APBC }, ++ [RESET_PWM9] = { APBC_PWM9_CLK_RST, BIT(2) | BIT(0), ++ BIT(0), BIT(2), RST_BASE_TYPE_APBC }, ++ [RESET_PWM10] = { APBC_PWM10_CLK_RST, BIT(2) | BIT(0), ++ BIT(0), BIT(2), RST_BASE_TYPE_APBC }, ++ [RESET_PWM11] = { APBC_PWM11_CLK_RST, BIT(2) | BIT(0), ++ BIT(0), BIT(2), RST_BASE_TYPE_APBC }, ++ [RESET_PWM12] = { APBC_PWM12_CLK_RST, BIT(2) | BIT(0), ++ BIT(0), BIT(2), RST_BASE_TYPE_APBC }, ++ [RESET_PWM13] = { APBC_PWM13_CLK_RST, BIT(2) | BIT(0), ++ BIT(0), BIT(2), RST_BASE_TYPE_APBC }, ++ [RESET_PWM14] = { APBC_PWM14_CLK_RST, BIT(2) | BIT(0), ++ BIT(0), BIT(2), RST_BASE_TYPE_APBC }, ++ [RESET_PWM15] = { APBC_PWM15_CLK_RST, BIT(2) | BIT(0), ++ BIT(0), BIT(2), RST_BASE_TYPE_APBC }, ++ [RESET_PWM16] = { APBC_PWM16_CLK_RST, BIT(2) | BIT(0), ++ BIT(0), BIT(2), RST_BASE_TYPE_APBC }, ++ [RESET_PWM17] = { APBC_PWM17_CLK_RST, BIT(2) | BIT(0), ++ BIT(0), BIT(2), RST_BASE_TYPE_APBC }, ++ [RESET_PWM18] = { APBC_PWM18_CLK_RST, BIT(2) | BIT(0), ++ BIT(0), BIT(2), RST_BASE_TYPE_APBC }, ++ [RESET_PWM19] = { APBC_PWM19_CLK_RST, BIT(2) | BIT(0), ++ BIT(0), BIT(2), RST_BASE_TYPE_APBC }, ++ [RESET_SSP3] = { APBC_SSP3_CLK_RST, BIT(2), 0, BIT(2), ++ RST_BASE_TYPE_APBC }, ++ [RESET_UART3] = { APBC_UART3_CLK_RST, BIT(2), 0, ++ BIT(2), RST_BASE_TYPE_APBC }, ++ [RESET_RTC] = { APBC_RTC_CLK_RST, BIT(2), 0, ++ BIT(2), RST_BASE_TYPE_APBC }, ++ [RESET_TWSI0] = { APBC_TWSI0_CLK_RST, BIT(2), 0, ++ BIT(2), RST_BASE_TYPE_APBC }, ++ [RESET_TIMERS1] = { APBC_TIMERS1_CLK_RST, BIT(2), 0, ++ BIT(2), RST_BASE_TYPE_APBC }, ++ [RESET_AIB] = { APBC_AIB_CLK_RST, BIT(2), 0, ++ BIT(2), RST_BASE_TYPE_APBC }, ++ [RESET_TIMERS2] = { APBC_TIMERS2_CLK_RST, BIT(2), 0, ++ BIT(2), RST_BASE_TYPE_APBC }, ++ [RESET_ONEWIRE] = { APBC_ONEWIRE_CLK_RST, BIT(2), 0, ++ BIT(2), RST_BASE_TYPE_APBC }, ++ [RESET_SSPA0] = { APBC_SSPA0_CLK_RST, BIT(2), 0, ++ BIT(2), RST_BASE_TYPE_APBC }, ++ [RESET_SSPA1] = { APBC_SSPA1_CLK_RST, BIT(2), 0, ++ BIT(2), RST_BASE_TYPE_APBC }, ++ [RESET_DRO] = { APBC_DRO_CLK_RST, BIT(2), 0, ++ BIT(2), RST_BASE_TYPE_APBC }, ++ [RESET_IR] = { APBC_IR_CLK_RST, BIT(2), 0, ++ BIT(2), RST_BASE_TYPE_APBC }, ++ [RESET_TWSI1] = { APBC_TWSI1_CLK_RST, BIT(2), 0, ++ BIT(2), RST_BASE_TYPE_APBC }, ++ [RESET_TSEN] = { APBC_TSEN_CLK_RST, BIT(2), 0, ++ BIT(2), RST_BASE_TYPE_APBC }, ++ [RESET_TWSI2] = { APBC_TWSI2_CLK_RST, BIT(2), 0, ++ BIT(2), RST_BASE_TYPE_APBC }, ++ [RESET_TWSI4] = { APBC_TWSI4_CLK_RST, BIT(2), 0, ++ BIT(2), RST_BASE_TYPE_APBC }, ++ [RESET_TWSI5] = { APBC_TWSI5_CLK_RST, BIT(2), 0, ++ BIT(2), RST_BASE_TYPE_APBC }, ++ [RESET_TWSI6] = { APBC_TWSI6_CLK_RST, BIT(2), 0, ++ BIT(2), RST_BASE_TYPE_APBC }, ++ [RESET_TWSI7] = { APBC_TWSI7_CLK_RST, BIT(2), 0, ++ BIT(2), RST_BASE_TYPE_APBC }, ++ [RESET_TWSI8] = { APBC_TWSI8_CLK_RST, BIT(2), 0, ++ BIT(2), RST_BASE_TYPE_APBC }, ++ [RESET_IPC_AP2AUD] = { APBC_IPC_AP2AUD_CLK_RST, ++ BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC }, ++ [RESET_UART4] = { APBC_UART4_CLK_RST, BIT(2), 0, ++ BIT(2), RST_BASE_TYPE_APBC }, ++ [RESET_UART5] = { APBC_UART5_CLK_RST, BIT(2), 0, ++ BIT(2), RST_BASE_TYPE_APBC }, ++ [RESET_UART6] = { APBC_UART6_CLK_RST, BIT(2), 0, ++ BIT(2), RST_BASE_TYPE_APBC }, ++ [RESET_UART7] = { APBC_UART7_CLK_RST, BIT(2), 0, ++ BIT(2), RST_BASE_TYPE_APBC }, ++ [RESET_UART8] = { APBC_UART8_CLK_RST, BIT(2), 0, ++ BIT(2), RST_BASE_TYPE_APBC }, ++ [RESET_UART9] = { APBC_UART9_CLK_RST, BIT(2), 0, ++ BIT(2), RST_BASE_TYPE_APBC }, ++ [RESET_CAN0] = { APBC_CAN0_CLK_RST, BIT(2), 0, ++ BIT(2), RST_BASE_TYPE_APBC }, ++ [RESET_WDT] = { MPMU_WDTPCR, BIT(2), 0, ++ BIT(2), RST_BASE_TYPE_MPMU }, ++ [RESET_JPG] = { APMU_JPG_CLK_RES_CTRL, BIT(0), ++ BIT(0), 0, RST_BASE_TYPE_APMU }, ++ [RESET_CSI] = { APMU_CSI_CCIC2_CLK_RES_CTRL, ++ BIT(1), BIT(1), 0, RST_BASE_TYPE_APMU }, ++ [RESET_CCIC2_PHY] = { APMU_CSI_CCIC2_CLK_RES_CTRL, ++ BIT(2), BIT(2), 0, RST_BASE_TYPE_APMU }, ++ [RESET_CCIC3_PHY] = { APMU_CSI_CCIC2_CLK_RES_CTRL, ++ BIT(29), BIT(29), 0, RST_BASE_TYPE_APMU }, ++ [RESET_ISP] = { APMU_ISP_CLK_RES_CTRL, BIT(0), ++ BIT(0), 0, RST_BASE_TYPE_APMU }, ++ [RESET_ISP_AHB] = { APMU_ISP_CLK_RES_CTRL, BIT(3), ++ BIT(3), 0, RST_BASE_TYPE_APMU }, ++ [RESET_ISP_CI] = { APMU_ISP_CLK_RES_CTRL, BIT(16), ++ BIT(16), 0, RST_BASE_TYPE_APMU }, ++ [RESET_ISP_CPP] = { APMU_ISP_CLK_RES_CTRL, BIT(27), ++ BIT(27), 0, RST_BASE_TYPE_APMU }, ++ [RESET_LCD] = { APMU_LCD_CLK_RES_CTRL1, BIT(4), ++ BIT(4), 0, RST_BASE_TYPE_APMU }, ++ [RESET_DSI_ESC] = { APMU_LCD_CLK_RES_CTRL1, BIT(3), ++ BIT(3), 0, RST_BASE_TYPE_APMU }, ++ [RESET_V2D] = { APMU_LCD_CLK_RES_CTRL1, BIT(27), ++ BIT(27), 0, RST_BASE_TYPE_APMU }, ++ [RESET_MIPI] = { APMU_LCD_CLK_RES_CTRL1, BIT(15), ++ BIT(15), 0, RST_BASE_TYPE_APMU }, ++ [RESET_LCD_SPI] = { APMU_LCD_SPI_CLK_RES_CTRL, ++ BIT(0), BIT(0), 0, RST_BASE_TYPE_APMU }, ++ [RESET_LCD_SPI_BUS] = { APMU_LCD_SPI_CLK_RES_CTRL, ++ BIT(4), BIT(4), 0, RST_BASE_TYPE_APMU }, ++ [RESET_LCD_SPI_HBUS] = { APMU_LCD_SPI_CLK_RES_CTRL, ++ BIT(2), BIT(2), 0, RST_BASE_TYPE_APMU }, ++ [RESET_LCD_MCLK] = { APMU_LCD_CLK_RES_CTRL2, BIT(9), ++ BIT(9), 0, RST_BASE_TYPE_APMU }, ++ [RESET_CCIC_4X] = { APMU_CCIC_CLK_RES_CTRL, ++ BIT(1), BIT(1), 0, RST_BASE_TYPE_APMU }, ++ [RESET_CCIC1_PHY] = { APMU_CCIC_CLK_RES_CTRL, ++ BIT(2), BIT(2), 0, RST_BASE_TYPE_APMU }, ++ [RESET_SDH_AXI] = { APMU_SDH0_CLK_RES_CTRL, BIT(0), ++ BIT(0), 0, RST_BASE_TYPE_APMU }, ++ [RESET_SDH0] = { APMU_SDH0_CLK_RES_CTRL, BIT(1), ++ BIT(1), 0, RST_BASE_TYPE_APMU }, ++ [RESET_SDH1] = { APMU_SDH1_CLK_RES_CTRL, BIT(1), ++ BIT(1), 0, RST_BASE_TYPE_APMU }, ++ [RESET_USB_AXI] = { APMU_USB_CLK_RES_CTRL, BIT(0), ++ BIT(0), 0, RST_BASE_TYPE_APMU }, ++ [RESET_USBP1_AXI] = { APMU_USB_CLK_RES_CTRL, BIT(4), ++ BIT(4), 0, RST_BASE_TYPE_APMU }, ++ [RESET_USB3_0] = { APMU_USB_CLK_RES_CTRL, ++ BIT(9) | BIT(10) | BIT(11), BIT(9) | BIT(10) | BIT(11), ++ 0, RST_BASE_TYPE_APMU }, ++ [RESET_QSPI] = { APMU_QSPI_CLK_RES_CTRL, BIT(1), ++ BIT(1), 0, RST_BASE_TYPE_APMU }, ++ [RESET_QSPI_BUS] = { APMU_QSPI_CLK_RES_CTRL, BIT(0), ++ BIT(0), 0, RST_BASE_TYPE_APMU }, ++ [RESET_DMA] = { APMU_DMA_CLK_RES_CTRL, BIT(0), ++ BIT(0), 0, RST_BASE_TYPE_APMU }, ++ [RESET_AES] = { APMU_AES_CLK_RES_CTRL, BIT(4), ++ BIT(4), 0, RST_BASE_TYPE_APMU }, ++ [RESET_VPU] = { APMU_VPU_CLK_RES_CTRL, BIT(0), ++ BIT(0), 0, RST_BASE_TYPE_APMU }, ++ [RESET_GPU] = { APMU_GPU_CLK_RES_CTRL, BIT(1), ++ BIT(1), 0, RST_BASE_TYPE_APMU }, ++ [RESET_SDH2] = { APMU_SDH2_CLK_RES_CTRL, BIT(1), ++ BIT(1), 0, RST_BASE_TYPE_APMU }, ++ [RESET_MC] = { APMU_PMUA_MC_CTRL, BIT(0), ++ BIT(0), 0, RST_BASE_TYPE_APMU }, ++ [RESET_EM_AXI] = { APMU_PMUA_EM_CLK_RES_CTRL, BIT(0), ++ BIT(0), 0, RST_BASE_TYPE_APMU }, ++ [RESET_EM] = { APMU_PMUA_EM_CLK_RES_CTRL, BIT(1), ++ BIT(1), 0, RST_BASE_TYPE_APMU }, ++ [RESET_AUDIO_SYS] = { APMU_AUDIO_CLK_RES_CTRL, ++ BIT(0) | BIT(2) | BIT(3), BIT(0) | BIT(2) | BIT(3), ++ 0, RST_BASE_TYPE_APMU }, ++ [RESET_HDMI] = { APMU_HDMI_CLK_RES_CTRL, BIT(9), ++ BIT(9), 0, RST_BASE_TYPE_APMU }, ++ [RESET_PCIE0] = { APMU_PCIE_CLK_RES_CTRL_0, ++ BIT(3) | BIT(4) | BIT(5) | BIT(8), ++ BIT(3) | BIT(4) | BIT(5), BIT(8), ++ RST_BASE_TYPE_APMU }, ++ [RESET_PCIE1] = { APMU_PCIE_CLK_RES_CTRL_1, ++ BIT(3) | BIT(4) | BIT(5) | BIT(8), ++ BIT(3) | BIT(4) | BIT(5), BIT(8), ++ RST_BASE_TYPE_APMU }, ++ [RESET_PCIE2] = { APMU_PCIE_CLK_RES_CTRL_2, ++ 0x138, 0x38, 0x100, RST_BASE_TYPE_APMU }, ++ [RESET_EMAC0] = { APMU_EMAC0_CLK_RES_CTRL, BIT(1), ++ BIT(1), 0, RST_BASE_TYPE_APMU }, ++ [RESET_EMAC1] = { APMU_EMAC1_CLK_RES_CTRL, BIT(1), ++ BIT(1), 0, RST_BASE_TYPE_APMU }, ++ [RESET_SEC_UART1] = { APBC2_UART1_CLK_RST, BIT(2), 0, ++ BIT(2), RST_BASE_TYPE_APBC2 }, ++ [RESET_SEC_SSP2] = { APBC2_SSP2_CLK_RST, BIT(2), 0, ++ BIT(2), RST_BASE_TYPE_APBC2 }, ++ [RESET_SEC_TWSI3] = { APBC2_TWSI3_CLK_RST, BIT(2), 0, ++ BIT(2), RST_BASE_TYPE_APBC2 }, ++ [RESET_SEC_RTC] = { APBC2_RTC_CLK_RST, BIT(2), 0, ++ BIT(2), RST_BASE_TYPE_APBC2 }, ++ [RESET_SEC_TIMERS0] = { APBC2_TIMERS0_CLK_RST, ++ BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC2 }, ++ [RESET_SEC_KPC] = { APBC2_KPC_CLK_RST, BIT(2), 0, ++ BIT(2), RST_BASE_TYPE_APBC2 }, ++ [RESET_SEC_GPIO] = { APBC2_GPIO_CLK_RST, BIT(2), 0, ++ BIT(2), RST_BASE_TYPE_APBC2 }, ++ [RESET_RCPU_HDMIAUDIO] = { RCPU_HDMI_CLK_RST, BIT(0), ++ BIT(0), 0, RST_BASE_TYPE_RCPU }, ++ [RESET_RCPU_CAN] = { RCPU_CAN_CLK_RST, BIT(0), ++ BIT(0), 0, RST_BASE_TYPE_RCPU }, ++ ++ [RESET_RCPU_I2C0] = { RCPU_I2C0_CLK_RST, BIT(0), ++ BIT(0), 0, RST_BASE_TYPE_RCPU }, ++ [RESET_RCPU_SSP0] = { RCPU_SSP0_CLK_RST, BIT(0), ++ BIT(0), 0, RST_BASE_TYPE_RCPU }, ++ [RESET_RCPU_IR] = { RCPU_IR_CLK_RST, BIT(0), ++ BIT(0), 0, RST_BASE_TYPE_RCPU }, ++ [RESET_RCPU_UART0] = { RCPU_UART0_CLK_RST, BIT(0), ++ BIT(0), 0, RST_BASE_TYPE_RCPU }, ++ [RESET_RCPU_UART1] = { RCPU_UART1_CLK_RST, BIT(0), ++ BIT(0), 0, RST_BASE_TYPE_RCPU }, ++ ++ [RESET_RCPU2_PWM0] = { RCPU2_PWM0_CLK_RST, BIT(2) | BIT(0), ++ BIT(0), BIT(2), RST_BASE_TYPE_RCPU2 }, ++ [RESET_RCPU2_PWM1] = { RCPU2_PWM1_CLK_RST, BIT(2) | BIT(0), ++ BIT(0), BIT(2), RST_BASE_TYPE_RCPU2 }, ++ [RESET_RCPU2_PWM2] = { RCPU2_PWM2_CLK_RST, BIT(2) | BIT(0), ++ BIT(0), BIT(2), RST_BASE_TYPE_RCPU2 }, ++ [RESET_RCPU2_PWM3] = { RCPU2_PWM3_CLK_RST, BIT(2) | BIT(0), ++ BIT(0), BIT(2), RST_BASE_TYPE_RCPU2 }, ++ [RESET_RCPU2_PWM4] = { RCPU2_PWM4_CLK_RST, BIT(2) | BIT(0), ++ BIT(0), BIT(2), RST_BASE_TYPE_RCPU2 }, ++ [RESET_RCPU2_PWM5] = { RCPU2_PWM5_CLK_RST, BIT(2) | BIT(0), ++ BIT(0), BIT(2), RST_BASE_TYPE_RCPU2 }, ++ [RESET_RCPU2_PWM6] = { RCPU2_PWM6_CLK_RST, BIT(2) | BIT(0), ++ BIT(0), BIT(2), RST_BASE_TYPE_RCPU2 }, ++ [RESET_RCPU2_PWM7] = { RCPU2_PWM7_CLK_RST, BIT(2) | BIT(0), ++ BIT(0), BIT(2), RST_BASE_TYPE_RCPU2 }, ++ [RESET_RCPU2_PWM8] = { RCPU2_PWM8_CLK_RST, BIT(2) | BIT(0), ++ BIT(0), BIT(2), RST_BASE_TYPE_RCPU2 }, ++ [RESET_RCPU2_PWM9] = { RCPU2_PWM9_CLK_RST, BIT(2) | BIT(0), ++ BIT(0), BIT(2), RST_BASE_TYPE_RCPU2 }, ++}; ++ ++static struct spacemit_reset *to_spacemit_reset(struct reset_controller_dev *rcdev) ++{ ++ return container_of(rcdev, struct spacemit_reset, rcdev); ++} ++ ++static u32 spacemit_reset_read(struct spacemit_reset *reset, u32 id) ++{ ++ void __iomem *base; ++ ++ switch (reset->signals[id].type) { ++ case RST_BASE_TYPE_MPMU: ++ base = reset->mpmu_base; ++ break; ++ case RST_BASE_TYPE_APMU: ++ base = reset->apmu_base; ++ break; ++ case RST_BASE_TYPE_APBC: ++ base = reset->apbc_base; ++ break; ++ case RST_BASE_TYPE_APBS: ++ base = reset->apbs_base; ++ break; ++ case RST_BASE_TYPE_CIU: ++ base = reset->ciu_base; ++ break; ++ case RST_BASE_TYPE_DCIU: ++ base = reset->dciu_base; ++ break; ++ case RST_BASE_TYPE_DDRC: ++ base = reset->ddrc_base; ++ break; ++ case RST_BASE_TYPE_AUDC: ++ base = reset->audio_ctrl_base; ++ break; ++ case RST_BASE_TYPE_APBC2: ++ base = reset->apbc2_base; ++ break; ++ case RST_BASE_TYPE_RCPU: ++ base = reset->rcpu_base; ++ break; ++ case RST_BASE_TYPE_RCPU2: ++ base = reset->rcpu2_base; ++ break; ++ default: ++ base = reset->apbc_base; ++ break; ++ } ++ ++ return readl(base + reset->signals[id].offset); ++} ++ ++static void spacemit_reset_write(struct spacemit_reset *reset, u32 value, u32 id) ++{ ++ void __iomem *base; ++ ++ switch (reset->signals[id].type) { ++ case RST_BASE_TYPE_MPMU: ++ base = reset->mpmu_base; ++ break; ++ case RST_BASE_TYPE_APMU: ++ base = reset->apmu_base; ++ break; ++ case RST_BASE_TYPE_APBC: ++ base = reset->apbc_base; ++ break; ++ case RST_BASE_TYPE_APBS: ++ base = reset->apbs_base; ++ break; ++ case RST_BASE_TYPE_CIU: ++ base = reset->ciu_base; ++ break; ++ case RST_BASE_TYPE_DCIU: ++ base = reset->dciu_base; ++ break; ++ case RST_BASE_TYPE_DDRC: ++ base = reset->ddrc_base; ++ break; ++ case RST_BASE_TYPE_AUDC: ++ base = reset->audio_ctrl_base; ++ break; ++ case RST_BASE_TYPE_APBC2: ++ base = reset->apbc2_base; ++ break; ++ case RST_BASE_TYPE_RCPU: ++ base = reset->rcpu_base; ++ break; ++ case RST_BASE_TYPE_RCPU2: ++ base = reset->rcpu2_base; ++ break; ++ default: ++ base = reset->apbc_base; ++ break; ++ } ++ ++ writel(value, base + reset->signals[id].offset); ++} ++ ++static void spacemit_reset_set(struct reset_controller_dev *rcdev, u32 id, bool assert) ++{ ++ u32 value; ++ struct spacemit_reset *reset = to_spacemit_reset(rcdev); ++ ++ value = spacemit_reset_read(reset, id); ++ if (assert) { ++ value &= ~reset->signals[id].mask; ++ value |= reset->signals[id].assert_val; ++ } else { ++ value &= ~reset->signals[id].mask; ++ value |= reset->signals[id].deassert_val; ++ } ++ spacemit_reset_write(reset, value, id); ++} ++ ++static int spacemit_reset_update(struct reset_controller_dev *rcdev, ++ unsigned long id, bool assert) ++{ ++ unsigned long flags; ++ struct spacemit_reset *reset = to_spacemit_reset(rcdev); ++ ++ if (id < RESET_UART1 || id >= RESET_NUMBER) ++ return 0; ++ ++ if (id == RESET_TWSI8) ++ return 0; ++ ++ spin_lock_irqsave(reset->lock, flags); ++ if (assert) ++ spacemit_reset_set(rcdev, id, assert); ++ else ++ spacemit_reset_set(rcdev, id, assert); ++ spin_unlock_irqrestore(reset->lock, flags); ++ ++ return 0; ++} ++ ++static int spacemit_reset_assert(struct reset_controller_dev *rcdev, unsigned long id) ++{ ++ return spacemit_reset_update(rcdev, id, true); ++} ++ ++static int spacemit_reset_deassert(struct reset_controller_dev *rcdev, ++ unsigned long id) ++{ ++ return spacemit_reset_update(rcdev, id, false); ++} ++ ++static const struct spacemit_reset_variant k1x_reset_data = { ++ .signals = k1x_reset_signals, ++ .signals_num = ARRAY_SIZE(k1x_reset_signals), ++ .ops = { ++ .assert = spacemit_reset_assert, ++ .deassert = spacemit_reset_deassert, ++ }, ++}; ++ ++static void spacemit_reset_init(struct device_node *np) ++{ ++ struct spacemit_reset *reset; ++ ++ if (of_device_is_compatible(np, "spacemit,k1x-reset")) { ++ reset = &k1x_reset_controller; ++ reset->mpmu_base = of_iomap(np, 0); ++ if (!reset->mpmu_base) { ++ pr_err("failed to map mpmu registers\n"); ++ goto out; ++ } ++ ++ reset->apmu_base = of_iomap(np, 1); ++ if (!reset->apmu_base) { ++ pr_err("failed to map apmu registers\n"); ++ goto out; ++ } ++ ++ reset->apbc_base = of_iomap(np, 2); ++ if (!reset->apbc_base) { ++ pr_err("failed to map apbc registers\n"); ++ goto out; ++ } ++ ++ reset->apbs_base = of_iomap(np, 3); ++ if (!reset->apbs_base) { ++ pr_err("failed to map apbs registers\n"); ++ goto out; ++ } ++ ++ reset->ciu_base = of_iomap(np, 4); ++ if (!reset->ciu_base) { ++ pr_err("failed to map ciu registers\n"); ++ goto out; ++ } ++ ++ reset->dciu_base = of_iomap(np, 5); ++ if (!reset->dciu_base) { ++ pr_err("failed to map dragon ciu registers\n"); ++ goto out; ++ } ++ ++ reset->ddrc_base = of_iomap(np, 6); ++ if (!reset->ddrc_base) { ++ pr_err("failed to map ddrc registers\n"); ++ goto out; ++ } ++ ++ reset->apbc2_base = of_iomap(np, 7); ++ if (!reset->apbc2_base) { ++ pr_err("failed to map apbc2 registers\n"); ++ goto out; ++ } ++ ++ reset->rcpu_base = of_iomap(np, 8); ++ if (!reset->rcpu_base) { ++ pr_err("failed to map rcpu registers\n"); ++ goto out; ++ } ++ ++ reset->rcpu2_base = of_iomap(np, 9); ++ if (!reset->rcpu2_base) { ++ pr_err("failed to map rcpu2 registers\n"); ++ goto out; ++ } ++ } else { ++ pr_err("not spacemit,k1x-reset\n"); ++ goto out; ++ } ++ ++ reset->lock = &g_cru_lock; ++ reset->signals = k1x_reset_data.signals; ++ reset->rcdev.owner = THIS_MODULE; ++ reset->rcdev.nr_resets = k1x_reset_data.signals_num; ++ reset->rcdev.ops = &k1x_reset_data.ops; ++ reset->rcdev.of_node = np; ++ reset_controller_register(&reset->rcdev); ++out: ++ return; ++} ++ ++CLK_OF_DECLARE(k1x_reset, "spacemit,k1x-reset", spacemit_reset_init); ++ diff --git a/drivers/reset/reset-th1520.c b/drivers/reset/reset-th1520.c new file mode 100644 index 000000000000..06f82be725be @@ -559454,10 +569440,10 @@ index d5b28fd35d66..9eb9da3291cc 100644 pr_warn("invalid \"method\" property: %s\n", method); return ERR_PTR(-EINVAL); diff --git a/drivers/tty/serial/8250/8250_dma.c b/drivers/tty/serial/8250/8250_dma.c -index 7fa66501792d..57900b189e99 100644 +index 7f23037813bc..eaa808e16861 100644 --- a/drivers/tty/serial/8250/8250_dma.c +++ b/drivers/tty/serial/8250/8250_dma.c -@@ -205,66 +205,68 @@ int serial8250_request_dma(struct uart_8250_port *p) +@@ -221,66 +221,68 @@ int serial8250_request_dma(struct uart_8250_port *p) dma->rxchan = dma_request_slave_channel_compat(mask, dma->fn, dma->rx_param, p->port.dev, "rx"); @@ -559576,7 +569562,7 @@ index 7fa66501792d..57900b189e99 100644 return 0; err: dma_release_channel(dma->txchan); -@@ -281,21 +283,23 @@ void serial8250_release_dma(struct uart_8250_port *p) +@@ -297,21 +299,23 @@ void serial8250_release_dma(struct uart_8250_port *p) if (!dma) return; @@ -559629,7 +569615,7 @@ index 72f9aab75ab1..65a9865eb6cb 100644 status = serial_lsr_in(up); diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c -index a17803da83f8..dde4293f3109 100644 +index c2778300e151..231c1233e876 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -1535,7 +1535,7 @@ static inline void __start_tx(struct uart_port *port) @@ -559650,7 +569636,7 @@ index a17803da83f8..dde4293f3109 100644 status = serial8250_rx_chars(up, status); } serial8250_modem_status(up); -@@ -2450,6 +2450,14 @@ int serial8250_do_startup(struct uart_port *port) +@@ -2451,6 +2451,14 @@ int serial8250_do_startup(struct uart_port *port) dev_warn_ratelimited(port->dev, "%s\n", msg); up->dma = NULL; } @@ -559665,11 +569651,2045 @@ index a17803da83f8..dde4293f3109 100644 } /* +diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig +index bdc568a4ab66..6336fadff23e 100644 +--- a/drivers/tty/serial/Kconfig ++++ b/drivers/tty/serial/Kconfig +@@ -411,7 +411,8 @@ config SERIAL_PXA + depends on ARCH_PXA || ARCH_MMP + select SERIAL_CORE + select SERIAL_8250_PXA if SERIAL_8250=y +- select SERIAL_PXA_NON8250 if !SERIAL_8250=y ++ select SERIAL_PXA_NON8250 if !SERIAL_8250=y && !SOC_SPACEMIT_K1X ++ select SERIAL_PXA_K1X if !SERIAL_8250=y && SOC_SPACEMIT_K1X + help + If you have a machine based on an Intel XScale PXA2xx CPU you + can enable its onboard serial ports by enabling this option. +@@ -442,6 +443,22 @@ config SERIAL_PXA_CONSOLE + Unless you have a specific need, you should use SERIAL_8250_PXA + and SERIAL_8250_CONSOLE instead of this. + ++config SERIAL_SPACEMIT_K1X ++ bool "Spacemit k1x serial port support" ++ depends on SOC_SPACEMIT_K1X ++ depends on SERIAL_CORE ++ help ++ If you have a machine based on Spacemit k1x soc, ++ can enable its onboard serial port by enabling this option. ++ ++config SERIAL_SPACEMIT_K1X_CONSOLE ++ bool "Console on spacemit k1x serial port" ++ depends on SERIAL_SPACEMIT_K1X ++ depends on SERIAL_CORE_CONSOLE ++ help ++ If you have enabled the serial port on the Spacemit k1 chip, ++ you can make it the console by answering Y to this option. ++ + config SERIAL_SA1100 + bool "SA1100 serial port support" + depends on ARCH_SA1100 +diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile +index 138abbc89738..0feb268753fb 100644 +--- a/drivers/tty/serial/Makefile ++++ b/drivers/tty/serial/Makefile +@@ -28,6 +28,7 @@ obj-$(CONFIG_SERIAL_AMBA_PL010) += amba-pl010.o + obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o + obj-$(CONFIG_SERIAL_CLPS711X) += clps711x.o + obj-$(CONFIG_SERIAL_PXA_NON8250) += pxa.o ++obj-$(CONFIG_SERIAL_SPACEMIT_K1X) += spacemit_k1x_uart.o + obj-$(CONFIG_SERIAL_SA1100) += sa1100.o + obj-$(CONFIG_SERIAL_BCM63XX) += bcm63xx_uart.o + obj-$(CONFIG_SERIAL_SAMSUNG) += samsung_tty.o +diff --git a/drivers/tty/serial/spacemit_k1x_uart.c b/drivers/tty/serial/spacemit_k1x_uart.c +new file mode 100644 +index 000000000000..6fa51bc4be80 +--- /dev/null ++++ b/drivers/tty/serial/spacemit_k1x_uart.c +@@ -0,0 +1,1979 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Based on drivers/serial/8250.c by Russell King. ++ * ++ * Author: Nicolas Pitre ++ * Created: Feb 20, 2003 ++ * Copyright: (C) 2003 Monta Vista Software, Inc. ++ * Copyright: (C) 2023 Spacemit Co., Ltd. ++ * Note 1: This driver is made separate from the already too overloaded ++ * 8250.c because it needs some kirks of its own and that'll make it ++ * easier to add DMA support. ++ * ++ * Note 2: I'm too sick of device allocation policies for serial ports. ++ * If someone else wants to request an "official" allocation of major/minor ++ * for this driver please be my guest. And don't forget that new hardware ++ * to come from Intel might have more than 3 or 4 of those UARTs. Let's ++ * hope for a better port registration and dynamic device allocation scheme ++ * with the serial core maintainer satisfaction to appear soon. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define DMA_BLOCK UART_XMIT_SIZE ++#define DMA_BURST_SIZE (8) ++#define DMA_FIFO_THRESHOLD (32) ++#define DMA_RX_BLOCK_SIZE DMA_BLOCK ++#define DMA_BUF_POLLING_SWITCH (1) ++ ++#define PXA_UART_TX (0) ++#define PXA_UART_RX (1) ++ ++#define NUM_UART_PORTS (10) ++#define BT_UART_PORT (2) ++ ++#define UART_FCR_PXA_BUS32 (0x20) ++#define UART_FCR_PXA_TRAIL (0x10) ++#define UART_FOR (9) ++ ++#define PXA_NAME_LEN (8) ++ ++#define SUPPORT_POWER_QOS (1) ++ ++#define TX_DMA_RUNNING BIT(0) ++#define RX_DMA_RUNNING BIT(1) ++ ++#define PXA_TIMER_TIMEOUT (3 * HZ) ++#define BLOCK_SUSPEND_TIMEOUT (3000) ++ ++struct uart_pxa_dma { ++ unsigned int dma_status; ++ struct dma_chan *txdma_chan; ++ struct dma_chan *rxdma_chan; ++ struct dma_async_tx_descriptor *rx_desc; ++ struct dma_async_tx_descriptor *tx_desc; ++ void *txdma_addr; ++ void *rxdma_addr; ++ dma_addr_t txdma_addr_phys; ++ dma_addr_t rxdma_addr_phys; ++ int tx_stop; ++ int rx_stop; ++ dma_cookie_t rx_cookie; ++ dma_cookie_t tx_cookie; ++ int tx_size; ++ struct tasklet_struct tklet; ++ ++#ifdef CONFIG_PM ++ void *tx_buf_save; ++ int tx_saved_len; ++#endif ++ ++ bool dma_init; ++ ++#if (DMA_BUF_POLLING_SWITCH == 1) ++ int dma_poll_timeout; ++ int dma_poll_max_time; ++#endif ++}; ++ ++struct uart_pxa_port { ++ struct uart_port port; ++ unsigned char ier; ++ unsigned char lcr; ++ unsigned char mcr; ++ unsigned int lsr_break_flag; ++ struct clk *fclk; ++ struct clk *gclk; ++ struct reset_control *resets; ++ char name[PXA_NAME_LEN]; ++ ++ struct timer_list pxa_timer; ++ int edge_wakeup_gpio; ++ struct work_struct uart_tx_lpm_work; ++ int dma_enable; ++ struct uart_pxa_dma uart_dma; ++ unsigned long flags; ++ unsigned int cons_udelay; ++ bool from_resume; ++ bool device_ctrl_rts; ++ bool in_resume; ++ unsigned int current_baud; ++}; ++ ++static void pxa_uart_transmit_dma_cb(void *data); ++static void pxa_uart_receive_dma_cb(void *data); ++static void pxa_uart_transmit_dma_start(struct uart_pxa_port *up, int count); ++static void pxa_uart_receive_dma_start(struct uart_pxa_port *up); ++static inline void wait_for_xmitr(struct uart_pxa_port *up); ++static unsigned int serial_pxa_tx_empty(struct uart_port *port); ++#ifdef CONFIG_PM ++static void _pxa_timer_handler(struct uart_pxa_port *up); ++#endif ++ ++static inline void stop_dma(struct uart_pxa_port *up, int read) ++{ ++ unsigned long flags; ++ struct uart_pxa_dma *pxa_dma = &up->uart_dma; ++ struct dma_chan *channel; ++ ++ if (!pxa_dma->dma_init) ++ return; ++ ++ channel = read ? pxa_dma->rxdma_chan : pxa_dma->txdma_chan; ++ ++ dmaengine_terminate_all(channel); ++ spin_lock_irqsave(&up->port.lock, flags); ++ if (read) ++ pxa_dma->dma_status &= ~RX_DMA_RUNNING; ++ else ++ pxa_dma->dma_status &= ~TX_DMA_RUNNING; ++ spin_unlock_irqrestore(&up->port.lock, flags); ++} ++ ++static inline unsigned int serial_in(struct uart_pxa_port *up, int offset) ++{ ++ offset <<= 2; ++ return readl(up->port.membase + offset); ++} ++ ++static inline void serial_out(struct uart_pxa_port *up, int offset, int value) ++{ ++ offset <<= 2; ++ writel(value, up->port.membase + offset); ++} ++ ++static void serial_pxa_enable_ms(struct uart_port *port) ++{ ++ struct uart_pxa_port *up = (struct uart_pxa_port *)port; ++ ++ if (up->dma_enable) ++ return; ++ ++ up->ier |= UART_IER_MSI; ++ serial_out(up, UART_IER, up->ier); ++} ++ ++static void serial_pxa_stop_tx(struct uart_port *port) ++{ ++ struct uart_pxa_port *up = (struct uart_pxa_port *)port; ++ unsigned int timeout = 0x100000 / up->cons_udelay; ++ unsigned long flags; ++ ++ if (up->dma_enable) { ++ up->uart_dma.tx_stop = 1; ++ ++ if (up->ier & UART_IER_DMAE && up->uart_dma.dma_init) { ++ while (dma_async_is_tx_complete(up->uart_dma.txdma_chan, ++ up->uart_dma.tx_cookie, NULL, NULL) ++ != DMA_COMPLETE && (timeout-- > 0)) { ++ spin_unlock(&up->port.lock); ++ local_irq_save(flags); ++ local_irq_enable(); ++ udelay(up->cons_udelay); ++ local_irq_disable(); ++ local_irq_restore(flags); ++ spin_lock(&up->port.lock); ++ } ++ ++ WARN_ON_ONCE(timeout == 0); ++ } ++ } else { ++ if (up->ier & UART_IER_THRI) { ++ up->ier &= ~UART_IER_THRI; ++ serial_out(up, UART_IER, up->ier); ++ } ++ } ++} ++ ++static void serial_pxa_stop_rx(struct uart_port *port) ++{ ++ struct uart_pxa_port *up = (struct uart_pxa_port *)port; ++ ++ if (up->dma_enable) { ++ if (up->ier & UART_IER_DMAE) { ++ spin_unlock_irqrestore(&up->port.lock, up->flags); ++ stop_dma(up, PXA_UART_RX); ++ spin_lock_irqsave(&up->port.lock, up->flags); ++ } ++ up->uart_dma.rx_stop = 1; ++ } else { ++ up->ier &= ~UART_IER_RLSI; ++ up->port.read_status_mask &= ~UART_LSR_DR; ++ serial_out(up, UART_IER, up->ier); ++ } ++} ++ ++static inline void receive_chars(struct uart_pxa_port *up, int *status) ++{ ++ unsigned int ch, flag; ++ int max_count = 256; ++ ++ do { ++ spin_lock_irqsave(&up->port.lock, up->flags); ++ up->ier &= ~UART_IER_RTOIE; ++ serial_out(up, UART_IER, up->ier); ++ spin_unlock_irqrestore(&up->port.lock, up->flags); ++ ++ ch = serial_in(up, UART_RX); ++ flag = TTY_NORMAL; ++ up->port.icount.rx++; ++ ++ if (unlikely(*status & (UART_LSR_BI | UART_LSR_PE | ++ UART_LSR_FE | UART_LSR_OE))) { ++ if (*status & UART_LSR_BI) { ++ *status &= ~(UART_LSR_FE | UART_LSR_PE); ++ up->port.icount.brk++; ++ if (uart_handle_break(&up->port)) ++ goto ignore_char; ++ } else if (*status & UART_LSR_PE) { ++ up->port.icount.parity++; ++ } else if (*status & UART_LSR_FE) { ++ up->port.icount.frame++; ++ } ++ ++ if (*status & UART_LSR_OE) ++ up->port.icount.overrun++; ++ ++ *status &= up->port.read_status_mask; ++ ++#ifdef CONFIG_SERIAL_SPACEMIT_K1X_CONSOLE ++ if (up->port.line == up->port.cons->index) { ++ *status |= up->lsr_break_flag; ++ up->lsr_break_flag = 0; ++ } ++#endif ++ if (*status & UART_LSR_BI) ++ flag = TTY_BREAK; ++ else if (*status & UART_LSR_PE) ++ flag = TTY_PARITY; ++ else if (*status & UART_LSR_FE) ++ flag = TTY_FRAME; ++ } ++ if (!uart_handle_sysrq_char(&up->port, ch)) ++ uart_insert_char(&up->port, *status, UART_LSR_OE, ch, flag); ++ ++ignore_char: ++ *status = serial_in(up, UART_LSR); ++ } while ((*status & UART_LSR_DR) && (max_count-- > 0)); ++ tty_flip_buffer_push(&up->port.state->port); ++ ++ spin_lock_irqsave(&up->port.lock, up->flags); ++ up->ier |= UART_IER_RTOIE; ++ serial_out(up, UART_IER, up->ier); ++ spin_unlock_irqrestore(&up->port.lock, up->flags); ++} ++ ++static void transmit_chars(struct uart_pxa_port *up) ++{ ++ struct circ_buf *xmit = &up->port.state->xmit; ++ int count; ++ ++ if (up->port.x_char) { ++ serial_out(up, UART_TX, up->port.x_char); ++ up->port.icount.tx++; ++ up->port.x_char = 0; ++ return; ++ } ++ if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) { ++ spin_lock_irqsave(&up->port.lock, up->flags); ++ serial_pxa_stop_tx(&up->port); ++ spin_unlock_irqrestore(&up->port.lock, up->flags); ++ return; ++ } ++ ++ count = up->port.fifosize / 2; ++ do { ++ serial_out(up, UART_TX, xmit->buf[xmit->tail]); ++ xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); ++ up->port.icount.tx++; ++ if (uart_circ_empty(xmit)) ++ break; ++ } while (--count > 0); ++ ++ if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) ++ uart_write_wakeup(&up->port); ++ ++ if (uart_circ_empty(xmit)) { ++ spin_lock_irqsave(&up->port.lock, up->flags); ++ serial_pxa_stop_tx(&up->port); ++ spin_unlock_irqrestore(&up->port.lock, up->flags); ++ } ++} ++ ++static inline void dma_receive_chars(struct uart_pxa_port *up, int *status) ++{ ++ struct tty_port *port = &up->port.state->port; ++ unsigned char ch; ++ int max_count = 256; ++ int count = 0; ++ unsigned char *tmp; ++ unsigned int flag = TTY_NORMAL; ++ struct uart_pxa_dma *pxa_dma = &up->uart_dma; ++ struct dma_tx_state dma_state; ++ ++ if (!pxa_dma->dma_init) ++ return; ++ ++ dmaengine_pause(pxa_dma->rxdma_chan); ++ dmaengine_tx_status(pxa_dma->rxdma_chan, pxa_dma->rx_cookie, ++ &dma_state); ++ count = DMA_RX_BLOCK_SIZE - dma_state.residue; ++ tmp = pxa_dma->rxdma_addr; ++ if (up->port.sysrq) { ++ while (count > 0) { ++ if (!uart_handle_sysrq_char(&up->port, *tmp)) { ++ uart_insert_char(&up->port, *status, 0, *tmp, flag); ++ up->port.icount.rx++; ++ } ++ tmp++; ++ count--; ++ } ++ } else { ++ tty_insert_flip_string(port, tmp, count); ++ up->port.icount.rx += count; ++ } ++ ++ do { ++ ch = serial_in(up, UART_RX); ++ flag = TTY_NORMAL; ++ up->port.icount.rx++; ++ ++ if (unlikely(*status & (UART_LSR_BI | UART_LSR_PE | ++ UART_LSR_FE | UART_LSR_OE))) { ++ if (*status & UART_LSR_BI) { ++ *status &= ~(UART_LSR_FE | UART_LSR_PE); ++ up->port.icount.brk++; ++ if (uart_handle_break(&up->port)) ++ goto ignore_char2; ++ } else if (*status & UART_LSR_PE) { ++ up->port.icount.parity++; ++ } else if (*status & UART_LSR_FE) { ++ up->port.icount.frame++; ++ } ++ ++ if (*status & UART_LSR_OE) ++ up->port.icount.overrun++; ++ ++ *status &= up->port.read_status_mask; ++ ++#ifdef CONFIG_SERIAL_SPACEMIT_K1X_CONSOLE ++ if (up->port.line == up->port.cons->index) { ++ *status |= up->lsr_break_flag; ++ up->lsr_break_flag = 0; ++ } ++#endif ++ if (*status & UART_LSR_BI) ++ flag = TTY_BREAK; ++ else if (*status & UART_LSR_PE) ++ flag = TTY_PARITY; ++ else if (*status & UART_LSR_FE) ++ flag = TTY_FRAME; ++ } ++ if (!uart_handle_sysrq_char(&up->port, ch)) ++ uart_insert_char(&up->port, *status, UART_LSR_OE, ++ ch, flag); ++ignore_char2: ++ *status = serial_in(up, UART_LSR); ++ } while ((*status & UART_LSR_DR) && (max_count-- > 0)); ++ ++ tty_flip_buffer_push(port); ++ stop_dma(up, 1); ++ if (pxa_dma->rx_stop) ++ return; ++ pxa_uart_receive_dma_start(up); ++} ++ ++static void serial_pxa_start_tx(struct uart_port *port) ++{ ++ struct uart_pxa_port *up = (struct uart_pxa_port *)port; ++ ++ if (up->dma_enable) { ++ up->uart_dma.tx_stop = 0; ++ tasklet_schedule(&up->uart_dma.tklet); ++ } else { ++ if (!(up->ier & UART_IER_THRI)) { ++ up->ier |= UART_IER_THRI; ++ serial_out(up, UART_IER, up->ier); ++ } ++ } ++} ++ ++static inline void check_modem_status(struct uart_pxa_port *up) ++{ ++ int status; ++ ++ status = serial_in(up, UART_MSR); ++ ++ if ((status & UART_MSR_ANY_DELTA) == 0) ++ return; ++ ++ spin_lock(&up->port.lock); ++ if (status & UART_MSR_TERI) ++ up->port.icount.rng++; ++ if (status & UART_MSR_DDSR) ++ up->port.icount.dsr++; ++ if (status & UART_MSR_DDCD) ++ uart_handle_dcd_change(&up->port, status & UART_MSR_DCD); ++ if (status & UART_MSR_DCTS) ++ uart_handle_cts_change(&up->port, status & UART_MSR_CTS); ++ spin_unlock(&up->port.lock); ++ ++ wake_up_interruptible(&up->port.state->port.delta_msr_wait); ++} ++ ++static int serial_pxa_is_open(struct uart_pxa_port *up); ++ ++static inline irqreturn_t serial_pxa_irq(int irq, void *dev_id) ++{ ++ struct uart_pxa_port *up = dev_id; ++ unsigned int iir, lsr; ++ ++ iir = serial_in(up, UART_IIR); ++ if (iir & UART_IIR_NO_INT) ++ return IRQ_NONE; ++ ++ if (!serial_pxa_is_open(up)) ++ return IRQ_HANDLED; ++ ++#ifdef CONFIG_PM ++#if SUPPORT_POWER_QOS ++ if (!mod_timer(&up->pxa_timer, jiffies + PXA_TIMER_TIMEOUT)) ++ pm_runtime_get_sync(up->port.dev); ++#endif ++#endif ++ ++ lsr = serial_in(up, UART_LSR); ++ if (up->dma_enable) { ++ if (lsr & UART_LSR_FIFOE) ++ dma_receive_chars(up, &lsr); ++ } else { ++ if (lsr & UART_LSR_DR) { ++ receive_chars(up, &lsr); ++ if (up->edge_wakeup_gpio >= 0) ++ pm_wakeup_event(up->port.dev, BLOCK_SUSPEND_TIMEOUT); ++ } ++ ++ check_modem_status(up); ++ if (lsr & UART_LSR_THRE) { ++ transmit_chars(up); ++ while (!serial_pxa_tx_empty((struct uart_port *)dev_id)) ++ ; ++ } ++ } ++ ++ return IRQ_HANDLED; ++} ++ ++static unsigned int serial_pxa_tx_empty(struct uart_port *port) ++{ ++ struct uart_pxa_port *up = (struct uart_pxa_port *)port; ++ unsigned long flags; ++ unsigned int ret; ++ ++ spin_lock_irqsave(&up->port.lock, flags); ++ if (up->dma_enable) { ++ if (up->ier & UART_IER_DMAE) { ++ if (up->uart_dma.dma_status & TX_DMA_RUNNING) { ++ spin_unlock_irqrestore(&up->port.lock, flags); ++ return 0; ++ } ++ } ++ } ++ ret = serial_in(up, UART_LSR) & UART_LSR_TEMT ? TIOCSER_TEMT : 0; ++ spin_unlock_irqrestore(&up->port.lock, flags); ++ ++ return ret; ++} ++ ++static unsigned int serial_pxa_get_mctrl(struct uart_port *port) ++{ ++ struct uart_pxa_port *up = (struct uart_pxa_port *)port; ++ unsigned char status; ++ unsigned int ret; ++ ++ status = serial_in(up, UART_MSR); ++ ++ ret = 0; ++ if (status & UART_MSR_DCD) ++ ret |= TIOCM_CAR; ++ if (status & UART_MSR_RI) ++ ret |= TIOCM_RNG; ++ if (status & UART_MSR_DSR) ++ ret |= TIOCM_DSR; ++ if (status & UART_MSR_CTS) ++ ret |= TIOCM_CTS; ++ return ret; ++} ++ ++static void serial_pxa_set_mctrl(struct uart_port *port, unsigned int mctrl) ++{ ++ struct uart_pxa_port *up = (struct uart_pxa_port *)port; ++ unsigned char mcr = 0; ++ int hostwake = 0; ++ ++ if (mctrl & TIOCM_RTS) ++ mcr |= UART_MCR_RTS; ++ if (mctrl & TIOCM_DTR) ++ mcr |= UART_MCR_DTR; ++ if (mctrl & TIOCM_OUT1) ++ mcr |= UART_MCR_OUT1; ++ if (mctrl & TIOCM_OUT2) ++ mcr |= UART_MCR_OUT2; ++ if (mctrl & TIOCM_LOOP) ++ mcr |= UART_MCR_LOOP; ++ ++ if (up->device_ctrl_rts) { ++ if ((hostwake || up->in_resume) && (mctrl & TIOCM_RTS)) ++ mcr &= ~UART_MCR_RTS; ++ } ++ ++ mcr |= up->mcr; ++ ++ serial_out(up, UART_MCR, mcr); ++ ++#ifdef CONFIG_BT ++ if (up->port.line == BT_UART_PORT) ++ pr_debug("%s: rts: 0x%x\n", __func__, mcr & UART_MCR_RTS); ++#endif ++} ++ ++static void serial_pxa_break_ctl(struct uart_port *port, int break_state) ++{ ++ struct uart_pxa_port *up = (struct uart_pxa_port *)port; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&up->port.lock, flags); ++ if (break_state == -1) ++ up->lcr |= UART_LCR_SBC; ++ else ++ up->lcr &= ~UART_LCR_SBC; ++ serial_out(up, UART_LCR, up->lcr); ++ spin_unlock_irqrestore(&up->port.lock, flags); ++} ++ ++static void pxa_uart_transmit_dma_start(struct uart_pxa_port *up, int count) ++{ ++ struct uart_pxa_dma *pxa_dma = &up->uart_dma; ++ struct dma_slave_config slave_config; ++ int ret; ++ ++ if (!pxa_dma->txdma_chan) { ++ dev_err(up->port.dev, "tx dma channel is not initialized\n"); ++ return; ++ } ++ ++ slave_config.direction = DMA_MEM_TO_DEV; ++ slave_config.dst_addr = up->port.mapbase; ++ slave_config.dst_maxburst = DMA_BURST_SIZE; ++ slave_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; ++ ++ ret = dmaengine_slave_config(pxa_dma->txdma_chan, &slave_config); ++ if (ret) { ++ dev_err(up->port.dev, ++ "%s: dmaengine slave config err.\n", __func__); ++ return; ++ } ++ ++ pxa_dma->tx_size = count; ++ pxa_dma->tx_desc = ++ dmaengine_prep_slave_single(pxa_dma->txdma_chan, pxa_dma->txdma_addr_phys, ++ count, DMA_MEM_TO_DEV, 0); ++ if (!pxa_dma->tx_desc) { ++ dev_err(up->port.dev, ++ "%s: Unable to get desc for Tx\n", __func__); ++ return; ++ } ++ pxa_dma->tx_desc->callback = pxa_uart_transmit_dma_cb; ++ pxa_dma->tx_desc->callback_param = up; ++ ++ pxa_dma->tx_cookie = dmaengine_submit(pxa_dma->tx_desc); ++#ifdef CONFIG_PM ++#if SUPPORT_POWER_QOS ++ pm_runtime_get_sync(up->port.dev); ++#endif ++#endif ++ ++ dma_async_issue_pending(pxa_dma->txdma_chan); ++} ++ ++static void pxa_uart_receive_dma_start(struct uart_pxa_port *up) ++{ ++ unsigned long flags; ++ struct uart_pxa_dma *uart_dma = &up->uart_dma; ++ struct dma_slave_config slave_config; ++ int ret; ++ ++ if (!uart_dma->rxdma_chan) { ++ dev_err(up->port.dev, "rx dma channel is not initialized\n"); ++ return; ++ } ++ ++ spin_lock_irqsave(&up->port.lock, flags); ++ if (uart_dma->dma_status & RX_DMA_RUNNING) { ++ spin_unlock_irqrestore(&up->port.lock, flags); ++ return; ++ } ++ uart_dma->dma_status |= RX_DMA_RUNNING; ++ spin_unlock_irqrestore(&up->port.lock, flags); ++ ++ slave_config.direction = DMA_DEV_TO_MEM; ++ slave_config.src_addr = up->port.mapbase; ++ slave_config.src_maxburst = DMA_BURST_SIZE; ++ slave_config.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; ++ ++ ret = dmaengine_slave_config(uart_dma->rxdma_chan, &slave_config); ++ if (ret) { ++ dev_err(up->port.dev, "%s: dmaengine slave config err.\n", __func__); ++ return; ++ } ++ ++ uart_dma->rx_desc = ++ dmaengine_prep_slave_single(uart_dma->rxdma_chan, ++ uart_dma->rxdma_addr_phys, DMA_RX_BLOCK_SIZE, ++ DMA_DEV_TO_MEM, 0); ++ if (!uart_dma->rx_desc) { ++ dev_err(up->port.dev, "%s: Unable to get desc for Rx\n", __func__); ++ return; ++ } ++ uart_dma->rx_desc->callback = pxa_uart_receive_dma_cb; ++ uart_dma->rx_desc->callback_param = up; ++ ++ uart_dma->rx_cookie = dmaengine_submit(uart_dma->rx_desc); ++ dma_async_issue_pending(uart_dma->rxdma_chan); ++} ++ ++static void pxa_uart_receive_dma_cb(void *data) ++{ ++ unsigned long flags; ++ struct uart_pxa_port *up = (struct uart_pxa_port *)data; ++ struct uart_pxa_dma *pxa_dma = &up->uart_dma; ++ struct tty_port *port = &up->port.state->port; ++ unsigned int count; ++ unsigned char *tmp = pxa_dma->rxdma_addr; ++ struct dma_tx_state dma_state; ++#if (DMA_BUF_POLLING_SWITCH == 1) ++ unsigned int buf_used, trail_cnt = 0; ++ unsigned char *trail_addr, *last_burst_addr; ++ u8 mark_1bytes = 0xff; ++ int timeout = 5000, cycle = 2; /* us */ ++ int times_1 = 0, times_2 = 0, duration_time_us; ++#endif ++ ++#ifdef CONFIG_PM ++#if SUPPORT_POWER_QOS ++ if (!mod_timer(&up->pxa_timer, jiffies + PXA_TIMER_TIMEOUT)) ++ pm_runtime_get_sync(up->port.dev); ++#endif ++#endif ++ ++ dmaengine_tx_status(pxa_dma->rxdma_chan, pxa_dma->rx_cookie, &dma_state); ++ count = DMA_RX_BLOCK_SIZE - dma_state.residue; ++ ++#if (DMA_BUF_POLLING_SWITCH == 1) ++ buf_used = count; ++ if (count > 0 && count < DMA_FIFO_THRESHOLD) { ++ trail_cnt = count; ++ trail_addr = tmp; ++ times_1 = timeout / cycle; ++ times_2 = timeout / cycle; ++ ++ while ((*trail_addr == mark_1bytes) && (times_1-- >= 0)) ++ udelay(cycle); ++ ++ if (trail_cnt > 1) { ++ trail_addr = trail_addr + trail_cnt - 1; ++ while ((*trail_addr == mark_1bytes) && (times_2-- >= 0)) ++ udelay(cycle); ++ } ++ ++ if (times_1 <= 0 || times_2 <= 0) ++ pxa_dma->dma_poll_timeout++; ++ } ++ ++ if (count >= DMA_FIFO_THRESHOLD && count < DMA_RX_BLOCK_SIZE) { ++ trail_cnt = (count % DMA_BURST_SIZE) + (DMA_FIFO_THRESHOLD - DMA_BURST_SIZE); ++ trail_addr = tmp + count - trail_cnt; ++ ++ #if (DMA_BURST_SIZE == DMA_FIFO_THRESHOLD) ++ if (trail_cnt == 0) { ++ trail_addr = tmp + count - DMA_BURST_SIZE; ++ trail_cnt = DMA_BURST_SIZE; ++ } ++ #endif ++ ++ times_1 = timeout / cycle; ++ times_2 = timeout / cycle; ++ ++ while ((*trail_addr == mark_1bytes) && (times_1-- >= 0)) ++ udelay(cycle); ++ ++ if (trail_cnt > 1) { ++ trail_addr = trail_addr + trail_cnt - 1; ++ while ((*trail_addr == mark_1bytes) && (times_2-- >= 0)) ++ udelay(cycle); ++ } ++ ++ if (times_1 <= 0 || times_2 <= 0) ++ pxa_dma->dma_poll_timeout++; ++ } ++ ++ if (count == DMA_RX_BLOCK_SIZE) { ++ last_burst_addr = tmp + DMA_RX_BLOCK_SIZE - DMA_BURST_SIZE; ++ trail_cnt = DMA_BURST_SIZE; ++ times_1 = timeout / cycle; ++ times_2 = timeout / cycle; ++ ++ while ((*last_burst_addr == mark_1bytes) && (times_1-- >= 0)) ++ udelay(cycle); ++ ++ if (trail_cnt > 1) { ++ last_burst_addr = tmp + DMA_RX_BLOCK_SIZE - 1; ++ while ((*last_burst_addr == mark_1bytes) && (times_2-- >= 0)) ++ udelay(cycle); ++ } ++ ++ if (times_1 <= 0 || times_2 <= 0) ++ pxa_dma->dma_poll_timeout++; ++ } ++#endif /* #if (DMA_BUF_POLLING_SWITCH == 1) */ ++ ++ if (up->port.sysrq) { ++ while (count > 0) { ++ if (!uart_handle_sysrq_char(&up->port, *tmp)) { ++ tty_insert_flip_char(port, *tmp, TTY_NORMAL); ++ up->port.icount.rx++; ++ } ++ tmp++; ++ count--; ++ } ++ } else { ++ tty_insert_flip_string(port, tmp, count); ++ up->port.icount.rx += count; ++ } ++ tty_flip_buffer_push(port); ++ ++ spin_lock_irqsave(&up->port.lock, flags); ++ pxa_dma->dma_status &= ~RX_DMA_RUNNING; ++ spin_unlock_irqrestore(&up->port.lock, flags); ++ ++#if (DMA_BUF_POLLING_SWITCH == 1) ++ if (buf_used > 0) { ++ tmp = pxa_dma->rxdma_addr; ++ memset(tmp, mark_1bytes, buf_used); ++ } ++ ++ if (times_1 > 0) { ++ duration_time_us = (timeout / cycle - times_1) * cycle; ++ if (pxa_dma->dma_poll_max_time < duration_time_us) ++ pxa_dma->dma_poll_max_time = duration_time_us; ++ } ++ if (times_2 > 0) { ++ duration_time_us = (timeout / cycle - times_2) * cycle; ++ if (pxa_dma->dma_poll_max_time < duration_time_us) ++ pxa_dma->dma_poll_max_time = duration_time_us; ++ } ++ if (times_1 > 0 && times_2 > 0) { ++ duration_time_us = (2 * timeout / cycle - times_1 - times_2) * cycle; ++ if (pxa_dma->dma_poll_max_time < duration_time_us) ++ pxa_dma->dma_poll_max_time = duration_time_us; ++ } ++#endif /* #if (DMA_BUF_POLLING_SWITCH == 1) */ ++ ++ if (pxa_dma->rx_stop || !serial_pxa_is_open(up)) ++ return; ++ pxa_uart_receive_dma_start(up); ++ if (up->edge_wakeup_gpio >= 0) ++ pm_wakeup_event(up->port.dev, BLOCK_SUSPEND_TIMEOUT); ++} ++ ++static void pxa_uart_transmit_dma_cb(void *data) ++{ ++ struct uart_pxa_port *up = (struct uart_pxa_port *)data; ++ struct uart_pxa_dma *pxa_dma = &up->uart_dma; ++ struct circ_buf *xmit = &up->port.state->xmit; ++ ++ if (up->from_resume) ++ up->from_resume = false; ++ ++ if (dma_async_is_tx_complete(pxa_dma->txdma_chan, pxa_dma->tx_cookie, ++ NULL, NULL) == DMA_COMPLETE) ++ schedule_work(&up->uart_tx_lpm_work); ++ ++ spin_lock_irqsave(&up->port.lock, up->flags); ++ pxa_dma->dma_status &= ~TX_DMA_RUNNING; ++ spin_unlock_irqrestore(&up->port.lock, up->flags); ++ ++ if (pxa_dma->tx_stop || !serial_pxa_is_open(up)) ++ return; ++ ++ if (up->port.x_char) { ++ serial_out(up, UART_TX, up->port.x_char); ++ up->port.icount.tx++; ++ up->port.x_char = 0; ++ } ++ ++ if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) ++ uart_write_wakeup(&up->port); ++ ++ if (!uart_circ_empty(xmit)) ++ tasklet_schedule(&pxa_dma->tklet); ++} ++ ++static void pxa_uart_dma_init(struct uart_pxa_port *up) ++{ ++ struct uart_pxa_dma *pxa_dma = &up->uart_dma; ++ dma_cap_mask_t mask; ++ ++ dma_cap_zero(mask); ++ dma_cap_set(DMA_SLAVE, mask); ++ ++ if (!pxa_dma->rxdma_chan) { ++ pxa_dma->rxdma_chan = dma_request_slave_channel(up->port.dev, "rx"); ++ if (IS_ERR_OR_NULL(pxa_dma->rxdma_chan)) { ++ dev_WARN_ONCE(up->port.dev, 1, "failed to request rx dma channel\n"); ++ goto out; ++ } ++ } ++ ++ if (!pxa_dma->txdma_chan) { ++ pxa_dma->txdma_chan = dma_request_slave_channel(up->port.dev, "tx"); ++ if (IS_ERR_OR_NULL(pxa_dma->txdma_chan)) { ++ dev_WARN_ONCE(up->port.dev, 1, "failed to request tx dma channel\n"); ++ goto err_txdma; ++ } ++ } ++ ++ if (!pxa_dma->txdma_addr) { ++ pxa_dma->txdma_addr = ++ dma_direct_alloc(up->port.dev, DMA_BLOCK, ++ &pxa_dma->txdma_addr_phys, GFP_KERNEL, ++ DMA_ATTR_FORCE_CONTIGUOUS); ++ if (!pxa_dma->txdma_addr) { ++ dev_WARN_ONCE(up->port.dev, 1, "failed to allocate tx dma memory\n"); ++ goto txdma_err_alloc; ++ } ++ } ++ ++ if (!pxa_dma->rxdma_addr) { ++ pxa_dma->rxdma_addr = ++ dma_direct_alloc(up->port.dev, DMA_RX_BLOCK_SIZE, ++ &pxa_dma->rxdma_addr_phys, GFP_KERNEL, ++ DMA_ATTR_FORCE_CONTIGUOUS); ++ if (!pxa_dma->rxdma_addr) { ++ dev_WARN_ONCE(up->port.dev, 1, "failed to allocate rx dma memory\n"); ++ goto rxdma_err_alloc; ++ } ++ } ++ ++ pxa_dma->dma_status = 0; ++ pxa_dma->dma_init = true; ++ return; ++ ++rxdma_err_alloc: ++ dma_direct_free(up->port.dev, DMA_BLOCK, pxa_dma->txdma_addr, ++ pxa_dma->txdma_addr_phys, DMA_ATTR_FORCE_CONTIGUOUS); ++ pxa_dma->txdma_addr = NULL; ++txdma_err_alloc: ++ dma_release_channel(pxa_dma->txdma_chan); ++ pxa_dma->txdma_chan = NULL; ++err_txdma: ++ dma_release_channel(pxa_dma->rxdma_chan); ++ pxa_dma->rxdma_chan = NULL; ++out: ++ pxa_dma->dma_init = false; ++} ++ ++static void pxa_uart_dma_uninit(struct uart_pxa_port *up) ++{ ++ struct uart_pxa_dma *pxa_dma; ++ ++ pxa_dma = &up->uart_dma; ++ ++ stop_dma(up, PXA_UART_TX); ++ stop_dma(up, PXA_UART_RX); ++ ++ pxa_dma->dma_init = false; ++ ++ if (pxa_dma->txdma_chan) { ++ dma_release_channel(pxa_dma->txdma_chan); ++ pxa_dma->txdma_chan = NULL; ++ } ++ ++ if (pxa_dma->txdma_addr) { ++ dma_direct_free(up->port.dev, DMA_BLOCK, pxa_dma->txdma_addr, ++ pxa_dma->txdma_addr_phys, ++ DMA_ATTR_FORCE_CONTIGUOUS); ++ pxa_dma->txdma_addr = NULL; ++ } ++ ++ if (pxa_dma->rxdma_chan) { ++ dma_release_channel(pxa_dma->rxdma_chan); ++ pxa_dma->rxdma_chan = NULL; ++ } ++ ++ if (pxa_dma->rxdma_addr) { ++ dma_direct_free(up->port.dev, DMA_RX_BLOCK_SIZE, pxa_dma->rxdma_addr, ++ pxa_dma->rxdma_addr_phys, ++ DMA_ATTR_FORCE_CONTIGUOUS); ++ pxa_dma->rxdma_addr = NULL; ++ } ++} ++ ++static void uart_task_action(unsigned long data) ++{ ++ struct uart_pxa_port *up = (struct uart_pxa_port *)data; ++ struct circ_buf *xmit = &up->port.state->xmit; ++ unsigned char *tmp = up->uart_dma.txdma_addr; ++ unsigned long flags; ++ int count = 0, c; ++ ++ if (up->uart_dma.tx_stop || up->port.suspended || ++ !serial_pxa_is_open(up) || up->from_resume) ++ return; ++ ++ spin_lock_irqsave(&up->port.lock, flags); ++ if (up->uart_dma.dma_status & TX_DMA_RUNNING) { ++ spin_unlock_irqrestore(&up->port.lock, flags); ++ return; ++ } ++ ++ up->uart_dma.dma_status |= TX_DMA_RUNNING; ++ while (1) { ++ c = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE); ++ if (c <= 0) ++ break; ++ ++ memcpy(tmp, xmit->buf + xmit->tail, c); ++ xmit->tail = (xmit->tail + c) & (UART_XMIT_SIZE - 1); ++ tmp += c; ++ count += c; ++ up->port.icount.tx += c; ++ } ++ spin_unlock_irqrestore(&up->port.lock, flags); ++ ++ pr_debug("count =%d", count); ++ pxa_uart_transmit_dma_start(up, count); ++} ++ ++static int serial_pxa_startup(struct uart_port *port) ++{ ++ struct uart_pxa_port *up = (struct uart_pxa_port *)port; ++ unsigned long flags; ++ int tmp = 0; ++ ++ if (port->line == 3) ++ up->mcr |= UART_MCR_AFE; ++ else ++ up->mcr = 0; ++ ++ up->port.uartclk = clk_get_rate(up->fclk); ++ ++ enable_irq(up->port.irq); ++ ++ serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO); ++ serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | ++ UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); ++ serial_out(up, UART_FCR, 0); ++ ++ (void)serial_in(up, UART_LSR); ++ (void)serial_in(up, UART_RX); ++ (void)serial_in(up, UART_IIR); ++ (void)serial_in(up, UART_MSR); ++ ++ serial_out(up, UART_LCR, UART_LCR_WLEN8); ++ ++ spin_lock_irqsave(&up->port.lock, flags); ++ up->port.mctrl |= TIOCM_OUT2; ++ tmp = serial_in(up, UART_MCR); ++ tmp |= TIOCM_OUT2; ++ serial_out(up, UART_MCR, tmp); ++ spin_unlock_irqrestore(&up->port.lock, flags); ++ ++ if (up->dma_enable) { ++ pxa_uart_dma_init(up); ++ up->uart_dma.rx_stop = 0; ++ pxa_uart_receive_dma_start(up); ++ tasklet_init(&up->uart_dma.tklet, uart_task_action, (unsigned long)up); ++ } ++ ++ spin_lock_irqsave(&up->port.lock, flags); ++ if (up->dma_enable) ++ up->ier = UART_IER_DMAE | UART_IER_UUE; ++ else ++ up->ier = UART_IER_RLSI | UART_IER_RDI | UART_IER_RTOIE | UART_IER_UUE; ++ serial_out(up, UART_IER, up->ier); ++ spin_unlock_irqrestore(&up->port.lock, flags); ++ ++ (void)serial_in(up, UART_LSR); ++ (void)serial_in(up, UART_RX); ++ (void)serial_in(up, UART_IIR); ++ (void)serial_in(up, UART_MSR); ++ ++ return 0; ++} ++ ++static void serial_pxa_shutdown(struct uart_port *port) ++{ ++ struct uart_pxa_port *up = (struct uart_pxa_port *)port; ++ unsigned long flags; ++ unsigned int tmp = 0; ++ ++ disable_irq(up->port.irq); ++ if (up->dma_enable) { ++ tasklet_kill(&up->uart_dma.tklet); ++ up->uart_dma.tx_stop = 1; ++ up->uart_dma.rx_stop = 1; ++ pxa_uart_dma_uninit(up); ++ } ++ ++ flush_work(&up->uart_tx_lpm_work); ++ ++ spin_lock_irqsave(&up->port.lock, flags); ++ up->ier = 0; ++ serial_out(up, UART_IER, 0); ++ ++ up->port.mctrl &= ~TIOCM_OUT2; ++ tmp = serial_in(up, UART_MCR); ++ tmp &= ~TIOCM_OUT2; ++ serial_out(up, UART_MCR, tmp); ++ spin_unlock_irqrestore(&up->port.lock, flags); ++ ++ serial_out(up, UART_LCR, serial_in(up, UART_LCR) & ~UART_LCR_SBC); ++ serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | ++ UART_FCR_CLEAR_RCVR | ++ UART_FCR_CLEAR_XMIT); ++ serial_out(up, UART_FCR, 0); ++} ++ ++static int pxa_set_baudrate_clk(struct uart_port *port, unsigned int baud) ++{ ++ struct uart_pxa_port *up = (struct uart_pxa_port *)port; ++ unsigned long rate; ++ int ret; ++ ++ if (up->current_baud == baud) ++ return 0; ++ ++ switch (baud) { ++ case 500000: ++ case 1000000: ++ case 1500000: ++ case 3000000: ++ rate = 48000000; ++ break; ++ case 576000: ++ case 1152000: ++ case 2500000: ++ case 4000000: ++ rate = 73000000; ++ break; ++ case 2000000: ++ case 3500000: ++ rate = 58000000; ++ break; ++ default: ++ rate = 14700000; ++ break; ++ } ++ ++ ret = clk_set_rate(up->fclk, rate); ++ if (ret < 0) { ++ dev_err(port->dev, ++ "Failed to set clk rate %lu\n", rate); ++ return ret; ++ } ++ ++ up->port.uartclk = clk_get_rate(up->fclk); ++ up->current_baud = baud; ++ ++ return 0; ++} ++ ++static void serial_pxa_set_termios(struct uart_port *port, ++ struct ktermios *termios, ++ const struct ktermios *old) ++{ ++ struct uart_pxa_port *up = (struct uart_pxa_port *)port; ++ unsigned char cval, fcr = 0; ++ unsigned long flags; ++ unsigned int baud, quot; ++ unsigned int dll; ++ int ret; ++ ++ if (up->dma_enable && up->uart_dma.dma_init) ++ stop_dma(up, PXA_UART_RX); ++ ++ cval = UART_LCR_WLEN(tty_get_char_size(termios->c_cflag)); ++ ++ if (termios->c_cflag & CSTOPB) ++ cval |= UART_LCR_STOP; ++ if (termios->c_cflag & PARENB) ++ cval |= UART_LCR_PARITY; ++ if (!(termios->c_cflag & PARODD)) ++ cval |= UART_LCR_EPAR; ++ ++ baud = uart_get_baud_rate(port, termios, old, 0, 4000000); ++ if (!baud) ++ baud = 9600; ++ ret = pxa_set_baudrate_clk(port, baud); ++ if (ret < 0) { ++ dev_err(port->dev, "Failed to set baud rate clk: %d\n", ret); ++ return; ++ } ++ if (tty_termios_baud_rate(termios)) ++ tty_termios_encode_baud_rate(termios, baud, baud); ++ ++ quot = uart_get_divisor(port, baud); ++ ++ if (!quot) ++ quot = 1; ++ if (up->dma_enable) { ++ fcr = UART_FCR_ENABLE_FIFO | UART_FCR_PXAR32 | UART_FCR_PXA_TRAIL; ++ fcr &= ~UART_FCR_PXA_BUS32; ++ } else { ++ if ((up->port.uartclk / quot) < (2400 * 16)) ++ fcr = UART_FCR_ENABLE_FIFO | UART_FCR_PXAR1; ++ else if ((up->port.uartclk / quot) < (230400 * 16)) ++ fcr = UART_FCR_ENABLE_FIFO | UART_FCR_PXAR8; ++ else ++ fcr = UART_FCR_ENABLE_FIFO | UART_FCR_PXAR32; ++ } ++ ++ spin_lock_irqsave(&up->port.lock, flags); ++ up->ier |= UART_IER_UUE; ++ uart_update_timeout(port, termios->c_cflag, baud); ++ up->port.read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR; ++ if (termios->c_iflag & INPCK) ++ up->port.read_status_mask |= UART_LSR_FE | UART_LSR_PE; ++ if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK)) ++ up->port.read_status_mask |= UART_LSR_BI; ++ ++ up->port.ignore_status_mask = 0; ++ if (termios->c_iflag & IGNPAR) ++ up->port.ignore_status_mask |= UART_LSR_PE | UART_LSR_FE; ++ if (termios->c_iflag & IGNBRK) { ++ up->port.ignore_status_mask |= UART_LSR_BI; ++ if (termios->c_iflag & IGNPAR) ++ up->port.ignore_status_mask |= UART_LSR_OE; ++ } ++ ++ if ((termios->c_cflag & CREAD) == 0) ++ up->port.ignore_status_mask |= UART_LSR_DR; ++ ++ if (!up->dma_enable) { ++ up->ier &= ~UART_IER_MSI; ++ if (UART_ENABLE_MS(&up->port, termios->c_cflag)) ++ up->ier |= UART_IER_MSI; ++ } ++ ++ serial_out(up, UART_IER, up->ier); ++ ++ if (termios->c_cflag & CRTSCTS) ++ up->mcr |= UART_MCR_AFE; ++ else ++ up->mcr &= ~UART_MCR_AFE; ++ ++ serial_out(up, UART_LCR, cval | UART_LCR_DLAB); ++ serial_out(up, UART_DLM, (quot >> 8) & 0xff); ++ (void)serial_in(up, UART_DLM); ++ serial_out(up, UART_DLL, quot & 0xff); ++ ++ (void)serial_in(up, UART_DLL); ++ dll = serial_in(up, UART_DLL); ++ WARN(dll != (quot & 0xff), "uart %d baud %d target 0x%x real 0x%x\n", ++ up->port.line, baud, quot & 0xff, dll); ++ ++ serial_out(up, UART_LCR, cval); ++ up->lcr = cval; ++ serial_pxa_set_mctrl(&up->port, up->port.mctrl); ++ serial_out(up, UART_FCR, fcr); ++ spin_unlock_irqrestore(&up->port.lock, flags); ++ ++ if (uart_console(&up->port)) { ++ up->cons_udelay = 1000000000 / baud * 10 / 8 / 1000; ++ if (up->cons_udelay <= 0) ++ up->cons_udelay = 1; ++ if (up->cons_udelay > 20) ++ up->cons_udelay = 20; ++ } ++ ++ if (up->dma_enable && up->uart_dma.dma_init) ++ pxa_uart_receive_dma_start(up); ++} ++ ++static void serial_pxa_pm(struct uart_port *port, unsigned int state, unsigned int oldstate) ++{ ++ struct uart_pxa_port *up = (struct uart_pxa_port *)port; ++ ++ if (!state) { ++ clk_prepare_enable(up->gclk); ++ clk_prepare_enable(up->fclk); ++ } else { ++ clk_disable_unprepare(up->fclk); ++ clk_disable_unprepare(up->gclk); ++ } ++} ++ ++static void serial_pxa_release_port(struct uart_port *port) ++{ ++} ++ ++static int serial_pxa_request_port(struct uart_port *port) ++{ ++ return 0; ++} ++ ++static void serial_pxa_config_port(struct uart_port *port, int flags) ++{ ++ struct uart_pxa_port *up = (struct uart_pxa_port *)port; ++ ++ up->port.type = PORT_PXA; ++} ++ ++static int serial_pxa_verify_port(struct uart_port *port, struct serial_struct *ser) ++{ ++ return -EINVAL; ++} ++ ++static const char *serial_pxa_type(struct uart_port *port) ++{ ++ struct uart_pxa_port *up = (struct uart_pxa_port *)port; ++ ++ return up->name; ++} ++ ++static struct uart_pxa_port *serial_pxa_ports[NUM_UART_PORTS]; ++static struct uart_driver serial_pxa_reg; ++ ++#ifdef CONFIG_PM ++void serial_pxa_get_qos(int port) ++{ ++ struct uart_pxa_port *up; ++ ++ if (port < 0 || port >= NUM_UART_PORTS) { ++ pr_err("%s: wrong uart port %d\n", __func__, port); ++ return; ++ } ++ ++ up = serial_pxa_ports[port]; ++ if (!mod_timer(&up->pxa_timer, jiffies + PXA_TIMER_TIMEOUT)) ++ pm_runtime_get_sync(up->port.dev); ++} ++EXPORT_SYMBOL_GPL(serial_pxa_get_qos); ++#endif ++ ++void serial_pxa_assert_rts(int port) ++{ ++ struct uart_pxa_port *up; ++ unsigned long flags; ++ ++ if (port < 0 || port >= NUM_UART_PORTS) { ++ pr_err("%s: wrong uart port %d\n", __func__, port); ++ return; ++ } ++ ++ up = serial_pxa_ports[port]; ++ ++ spin_lock_irqsave(&up->port.lock, flags); ++ if (!serial_pxa_is_open(up)) { ++ spin_unlock_irqrestore(&up->port.lock, flags); ++ pr_err("%s: uart %d is shutdown\n", __func__, port); ++ return; ++ } ++ serial_pxa_set_mctrl(&up->port, up->port.mctrl | TIOCM_RTS); ++ uart_handle_cts_change(&up->port, UART_MSR_CTS); ++ spin_unlock_irqrestore(&up->port.lock, flags); ++} ++EXPORT_SYMBOL_GPL(serial_pxa_assert_rts); ++ ++void serial_pxa_deassert_rts(int port) ++{ ++ struct uart_pxa_port *up; ++ unsigned long flags; ++ ++ if (port < 0 || port >= NUM_UART_PORTS) { ++ pr_err("%s: wrong uart port %d\n", __func__, port); ++ return; ++ } ++ ++ up = serial_pxa_ports[port]; ++ ++ spin_lock_irqsave(&up->port.lock, flags); ++ if (!serial_pxa_is_open(up)) { ++ spin_unlock_irqrestore(&up->port.lock, flags); ++ pr_err("%s: uart %d is shutdown\n", __func__, port); ++ return; ++ } ++ serial_pxa_set_mctrl(&up->port, up->port.mctrl & ~TIOCM_RTS); ++ spin_unlock_irqrestore(&up->port.lock, flags); ++} ++EXPORT_SYMBOL_GPL(serial_pxa_deassert_rts); ++ ++#ifdef CONFIG_SERIAL_SPACEMIT_K1X_CONSOLE ++ ++#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) ++ ++static void wait_for_xmitr(struct uart_pxa_port *up) ++{ ++ unsigned int status, tmout = 10000; ++ unsigned int cycle; ++ ++ if (uart_console(&up->port)) ++ cycle = up->cons_udelay; ++ else ++ cycle = 1; ++ ++ tmout = 10000 / cycle; ++ ++ do { ++ status = serial_in(up, UART_LSR); ++ ++ if (status & UART_LSR_BI) ++ up->lsr_break_flag = UART_LSR_BI; ++ ++ if ((status & BOTH_EMPTY) == BOTH_EMPTY) ++ break; ++ udelay(cycle); ++ } while (--tmout); ++ ++ if (up->port.flags & UPF_CONS_FLOW) { ++ tmout = 1000000; ++ while (--tmout && ((serial_in(up, UART_MSR) & UART_MSR_CTS) == 0)) ++ udelay(cycle); ++ } ++ ++ if (!tmout) { ++ if (up->port.flags & UPF_CONS_FLOW) ++ status = serial_in(up, UART_MSR); ++ else ++ status = serial_in(up, UART_LSR); ++ panic("failed to read uart status, status:0x%08x\n", status); ++ } ++} ++ ++static void serial_pxa_console_putchar(struct uart_port *port, unsigned char ch) ++{ ++ struct uart_pxa_port *up = (struct uart_pxa_port *)port; ++ ++ wait_for_xmitr(up); ++ serial_out(up, UART_TX, ch); ++} ++ ++static void serial_pxa_console_write(struct console *co, const char *s, unsigned int count) ++{ ++ struct uart_pxa_port *up = serial_pxa_ports[co->index]; ++ unsigned int ier; ++ unsigned long flags; ++ int locked = 1; ++ ++ clk_enable(up->gclk); ++ clk_enable(up->fclk); ++ ++ local_irq_save(flags); ++ if (up->port.sysrq) ++ locked = 0; ++ else if (oops_in_progress) ++ locked = spin_trylock(&up->port.lock); ++ else ++ spin_lock(&up->port.lock); ++ ++ ier = serial_in(up, UART_IER); ++ serial_out(up, UART_IER, UART_IER_UUE); ++ ++ uart_console_write(&up->port, s, count, serial_pxa_console_putchar); ++ ++ wait_for_xmitr(up); ++ serial_out(up, UART_IER, ier); ++ ++ if (locked) ++ spin_unlock(&up->port.lock); ++ local_irq_restore(flags); ++ clk_disable(up->fclk); ++ clk_disable(up->gclk); ++} ++ ++#ifdef CONFIG_CONSOLE_POLL ++static int serial_pxa_get_poll_char(struct uart_port *port) ++{ ++ struct uart_pxa_port *up = (struct uart_pxa_port *)port; ++ unsigned char lsr = serial_in(up, UART_LSR); ++ ++ while (!(lsr & UART_LSR_DR)) ++ lsr = serial_in(up, UART_LSR); ++ ++ return serial_in(up, UART_RX); ++} ++ ++static void serial_pxa_put_poll_char(struct uart_port *port, ++ unsigned char c) ++{ ++ unsigned int ier; ++ struct uart_pxa_port *up = (struct uart_pxa_port *)port; ++ ++ ier = serial_in(up, UART_IER); ++ serial_out(up, UART_IER, UART_IER_UUE); ++ ++ wait_for_xmitr(up); ++ serial_out(up, UART_TX, c); ++ if (c == 10) { ++ wait_for_xmitr(up); ++ serial_out(up, UART_TX, 13); ++ } ++ ++ wait_for_xmitr(up); ++ serial_out(up, UART_IER, ier); ++} ++ ++#endif /* CONFIG_CONSOLE_POLL */ ++ ++static int __init ++serial_pxa_console_setup(struct console *co, char *options) ++{ ++ struct uart_pxa_port *up; ++ int baud = 9600; ++ int bits = 8; ++ int parity = 'n'; ++ int flow = 'n'; ++ ++ if (co->index == -1 || co->index >= serial_pxa_reg.nr) ++ co->index = 0; ++ up = serial_pxa_ports[co->index]; ++ if (!up) ++ return -ENODEV; ++ ++ if (options) ++ uart_parse_options(options, &baud, &parity, &bits, &flow); ++ ++ return uart_set_options(&up->port, co, baud, parity, bits, flow); ++} ++ ++static struct console serial_pxa_console = { ++ .name = "ttySP", ++ .write = serial_pxa_console_write, ++ .device = uart_console_device, ++ .setup = serial_pxa_console_setup, ++ .flags = CON_PRINTBUFFER, ++ .index = -1, ++ .data = &serial_pxa_reg, ++}; ++ ++static void pxa_early_write(struct console *con, const char *s, ++ unsigned int n) ++{ ++ struct earlycon_device *dev = con->data; ++ ++ uart_console_write(&dev->port, s, n, serial_pxa_console_putchar); ++} ++ ++static int __init pxa_early_console_setup(struct earlycon_device *device, const char *opt) ++{ ++ if (!device->port.membase) ++ return -ENODEV; ++ ++ device->con->write = pxa_early_write; ++ return 0; ++} ++ ++EARLYCON_DECLARE(pxa_serial, pxa_early_console_setup); ++OF_EARLYCON_DECLARE(pxa_serial, "spacemit,pxa-uart", pxa_early_console_setup); ++ ++#define PXA_CONSOLE (&serial_pxa_console) ++#else ++#define PXA_CONSOLE NULL ++#endif /* CONFIG_SERIAL_SPACEMIT_K1X_CONSOLE */ ++ ++static const struct uart_ops serial_pxa_pops = { ++ .tx_empty = serial_pxa_tx_empty, ++ .set_mctrl = serial_pxa_set_mctrl, ++ .get_mctrl = serial_pxa_get_mctrl, ++ .stop_tx = serial_pxa_stop_tx, ++ .start_tx = serial_pxa_start_tx, ++ .stop_rx = serial_pxa_stop_rx, ++ .enable_ms = serial_pxa_enable_ms, ++ .break_ctl = serial_pxa_break_ctl, ++ .startup = serial_pxa_startup, ++ .shutdown = serial_pxa_shutdown, ++ .set_termios = serial_pxa_set_termios, ++ .pm = serial_pxa_pm, ++ .type = serial_pxa_type, ++ .release_port = serial_pxa_release_port, ++ .request_port = serial_pxa_request_port, ++ .config_port = serial_pxa_config_port, ++ .verify_port = serial_pxa_verify_port, ++#if defined(CONFIG_CONSOLE_POLL) && defined(CONFIG_SERIAL_SPACEMIT_K1X_CONSOLE) ++ .poll_get_char = serial_pxa_get_poll_char, ++ .poll_put_char = serial_pxa_put_poll_char, ++#endif ++}; ++ ++static struct uart_driver serial_pxa_reg = { ++ .owner = THIS_MODULE, ++ .driver_name = "PXA serial", ++ .dev_name = "ttySP", ++ .major = TTY_MAJOR, ++ .minor = 128, ++ .nr = NUM_UART_PORTS, ++ .cons = PXA_CONSOLE, ++}; ++ ++static int serial_pxa_is_open(struct uart_pxa_port *up) ++{ ++ struct uart_state *state; ++ struct uart_pxa_dma *pxa_dma; ++ ++ if (!up) ++ return 0; ++ ++ state = serial_pxa_reg.state + up->port.line; ++ pxa_dma = &up->uart_dma; ++ ++ if (up->dma_enable) { ++ return ((up->ier & UART_IER_DMAE) && pxa_dma->dma_init && ++ (state->pm_state == UART_PM_STATE_ON)); ++ } else { ++ return (state->pm_state == UART_PM_STATE_ON); ++ } ++} ++ ++#ifdef CONFIG_PM ++ ++#ifdef CONFIG_HIBERNATION ++unsigned long pxa_clk_freq; ++struct clk *pxa_clk_parent; ++#endif ++ ++static int __maybe_unused serial_pxa_suspend(struct device *dev) ++{ ++ struct uart_pxa_port *sport = dev_get_drvdata(dev); ++ struct uart_pxa_dma *pxa_dma = &sport->uart_dma; ++ struct dma_tx_state dma_state; ++ unsigned char tmp[256]; ++ int fifo_cnt, cnt = 0; ++ ++ if (!console_suspend_enabled || !sport) ++ return 0; ++ ++ if (serial_pxa_is_open(sport) && sport->dma_enable) { ++ int sent = 0; ++ unsigned long flags; ++ ++ local_irq_save(flags); ++ pxa_dma->tx_stop = 1; ++ pxa_dma->rx_stop = 1; ++ pxa_dma->tx_saved_len = 0; ++ if (dma_async_is_tx_complete(pxa_dma->txdma_chan, ++ pxa_dma->tx_cookie, NULL, NULL) != DMA_COMPLETE) { ++ dmaengine_pause(pxa_dma->txdma_chan); ++ udelay(100); ++ dmaengine_tx_status(pxa_dma->txdma_chan, ++ pxa_dma->tx_cookie, &dma_state); ++ sent = pxa_dma->tx_size - dma_state.residue; ++ pxa_dma->tx_saved_len = dma_state.residue; ++ memcpy(pxa_dma->tx_buf_save, pxa_dma->txdma_addr + sent, ++ dma_state.residue); ++ stop_dma(sport, PXA_UART_TX); ++ } ++ ++ if (dma_async_is_tx_complete(pxa_dma->rxdma_chan, ++ pxa_dma->rx_cookie, NULL, NULL) != DMA_COMPLETE) { ++ spin_lock(&sport->port.lock); ++ serial_pxa_set_mctrl(&sport->port, sport->port.mctrl & ~TIOCM_RTS); ++ spin_unlock(&sport->port.lock); ++ udelay(100); ++ dmaengine_pause(pxa_dma->rxdma_chan); ++ udelay(100); ++ pxa_uart_receive_dma_cb(sport); ++ stop_dma(sport, PXA_UART_RX); ++ ++ fifo_cnt = serial_in(sport, UART_FOR); ++ while (fifo_cnt > 0) { ++ *(tmp + cnt) = serial_in(sport, UART_RX) & 0xff; ++ cnt++; ++ fifo_cnt = serial_in(sport, UART_FOR); ++ } ++ ++ if (cnt > 0) { ++ tty_insert_flip_string(&sport->port.state->port, tmp, cnt); ++ sport->port.icount.rx += cnt; ++ tty_flip_buffer_push(&sport->port.state->port); ++ } ++ } ++ local_irq_restore(flags); ++ } ++ ++ if (sport) { ++#ifdef CONFIG_HIBERNATION ++ pxa_clk_freq = clk_get_rate(sport->fclk); ++ pxa_clk_parent = clk_get_parent(sport->fclk); ++#endif ++ uart_suspend_port(&serial_pxa_reg, &sport->port); ++#ifdef CONFIG_HIBERNATION ++ clk_set_parent(sport->fclk, NULL); ++#endif ++ } ++ ++ if (del_timer_sync(&sport->pxa_timer)) ++ _pxa_timer_handler(sport); ++ ++ return 0; ++} ++ ++static int __maybe_unused serial_pxa_resume(struct device *dev) ++{ ++ struct uart_pxa_port *sport = dev_get_drvdata(dev); ++ struct uart_pxa_dma *pxa_dma = &sport->uart_dma; ++ ++ if (!console_suspend_enabled || !sport) ++ return 0; ++ ++ sport->in_resume = true; ++ ++#ifdef CONFIG_HIBERNATION ++ clk_set_parent(sport->fclk, pxa_clk_parent); ++ clk_set_rate(sport->fclk, pxa_clk_freq); ++#endif ++ uart_resume_port(&serial_pxa_reg, &sport->port); ++ ++ if (serial_pxa_is_open(sport) && sport->dma_enable) { ++ if (pxa_dma->tx_saved_len > 0) { ++ sport->from_resume = true; ++ memcpy(pxa_dma->txdma_addr, pxa_dma->tx_buf_save, ++ pxa_dma->tx_saved_len); ++ pxa_uart_transmit_dma_start(sport, ++ pxa_dma->tx_saved_len); ++ } else { ++ tasklet_schedule(&pxa_dma->tklet); ++ } ++ ++ pxa_uart_receive_dma_start(sport); ++ } ++ sport->in_resume = false; ++ ++ return 0; ++} ++ ++static SIMPLE_DEV_PM_OPS(serial_pxa_pm_ops, serial_pxa_suspend, serial_pxa_resume); ++ ++static void _pxa_timer_handler(struct uart_pxa_port *up) ++{ ++#if SUPPORT_POWER_QOS ++ pm_runtime_put_sync(up->port.dev); ++#endif ++} ++ ++static void pxa_timer_handler(struct timer_list *t) ++{ ++ struct uart_pxa_port *up = from_timer(up, t, pxa_timer); ++ ++ _pxa_timer_handler(up); ++} ++ ++static void __maybe_unused uart_edge_wakeup_handler(int gpio, void *data) ++{ ++ struct uart_pxa_port *up = (struct uart_pxa_port *)data; ++ ++ if (!mod_timer(&up->pxa_timer, jiffies + PXA_TIMER_TIMEOUT)) { ++#if SUPPORT_POWER_QOS ++ pm_runtime_get_sync(up->port.dev); ++#endif ++ } ++ pm_wakeup_event(up->port.dev, BLOCK_SUSPEND_TIMEOUT); ++} ++ ++static void uart_tx_lpm_handler(struct work_struct *work) ++{ ++ struct uart_pxa_port *up = container_of(work, struct uart_pxa_port, uart_tx_lpm_work); ++ ++ while (!(serial_in(up, UART_LSR) & UART_LSR_TEMT)) ++ usleep_range(1000, 2000); ++ ++#if SUPPORT_POWER_QOS ++ pm_runtime_put_sync(up->port.dev); ++#endif ++} ++#endif ++ ++static const struct of_device_id serial_k1x_dt_ids[] = { ++ { .compatible = "spacemit,k1x-uart", }, ++ {} ++}; ++ ++static int serial_pxa_probe_dt(struct platform_device *pdev, struct uart_pxa_port *sport) ++{ ++ struct device_node *np = pdev->dev.of_node; ++ int ret; ++ ++ if (!np) ++ return 1; ++ ++ if (of_get_property(np, "dmas", NULL)) ++ sport->dma_enable = 1; ++ ++ ret = of_alias_get_id(np, "serial"); ++ if (ret < 0) { ++ dev_err(&pdev->dev, "failed to get alias id, errno %d\n", ret); ++ return ret; ++ } ++ sport->port.line = ret; ++ ++#ifdef CONFIG_PM ++ if (of_property_read_u32(np, "edge-wakeup-pin", &sport->edge_wakeup_gpio)) ++ dev_dbg(&pdev->dev, "no edge-wakeup-pin defined\n"); ++#endif ++ sport->device_ctrl_rts = of_property_read_bool(np, "device-control-rts"); ++ ++ return 0; ++} ++ ++static int serial_pxa_probe(struct platform_device *dev) ++{ ++ struct uart_pxa_port *sport; ++ struct resource *mmres; ++ int ret; ++ int irq; ++ struct resource *dmares; ++ struct uart_pxa_dma *pxa_dma; ++ ++ mmres = platform_get_resource(dev, IORESOURCE_MEM, 0); ++ if (!mmres) ++ return -ENODEV; ++ ++ irq = platform_get_irq(dev, 0); ++ if (irq < 0) ++ return irq; ++ ++ sport = kzalloc(sizeof(*sport), GFP_KERNEL); ++ if (!sport) ++ return -ENOMEM; ++ ++#ifdef CONFIG_PM ++ sport->uart_dma.tx_buf_save = kmalloc(DMA_BLOCK, GFP_KERNEL); ++ if (!sport->uart_dma.tx_buf_save) { ++ kfree(sport); ++ return -ENOMEM; ++ } ++#endif ++ sport->gclk = devm_clk_get(&dev->dev, "gate"); ++ if (IS_ERR(sport->gclk)) { ++ ret = PTR_ERR(sport->gclk); ++ goto err_free; ++ } ++ ++ sport->fclk = devm_clk_get(&dev->dev, "func"); ++ if (IS_ERR(sport->fclk)) { ++ ret = PTR_ERR(sport->fclk); ++ goto err_free; ++ } ++ ++ if (sport->gclk) { ++ ret = clk_prepare(sport->gclk); ++ if (ret) { ++ clk_put(sport->gclk); ++ goto err_free; ++ } ++ } ++ ++ if (sport->fclk) { ++ ret = clk_prepare(sport->fclk); ++ if (ret) { ++ clk_put(sport->fclk); ++ goto err_free; ++ } ++ } ++ ++ sport->port.type = PORT_PXA; ++ sport->port.iotype = UPIO_MEM; ++ sport->port.mapbase = mmres->start; ++ sport->port.irq = irq; ++ sport->port.fifosize = 64; ++ sport->port.ops = &serial_pxa_pops; ++ sport->port.dev = &dev->dev; ++ sport->port.flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF; ++ sport->port.uartclk = clk_get_rate(sport->fclk); ++ sport->resets = devm_reset_control_get_optional(&dev->dev, NULL); ++ if (IS_ERR(sport->resets)) { ++ ret = PTR_ERR(sport->resets); ++ goto err_clk; ++ } ++ reset_control_deassert(sport->resets); ++ ++ sport->port.has_sysrq = IS_ENABLED(CONFIG_SERIAL_SPACEMIT_K1X_CONSOLE); ++ ++ sport->edge_wakeup_gpio = -1; ++ ++ pxa_dma = &sport->uart_dma; ++ pxa_dma->txdma_chan = NULL; ++ pxa_dma->rxdma_chan = NULL; ++ pxa_dma->txdma_addr = NULL; ++ pxa_dma->rxdma_addr = NULL; ++ pxa_dma->dma_init = false; ++ sport->dma_enable = 0; ++ sport->cons_udelay = 1; ++ sport->in_resume = false; ++ ++ ret = serial_pxa_probe_dt(dev, sport); ++ if (ret > 0) ++ sport->port.line = dev->id; ++ else if (ret < 0) ++ goto err_rst; ++ ++ if (sport->port.line >= ARRAY_SIZE(serial_pxa_ports)) { ++ dev_err(&dev->dev, "serial%d out of range\n", sport->port.line); ++ ret = -EINVAL; ++ goto err_rst; ++ } ++ snprintf(sport->name, PXA_NAME_LEN - 1, "UART%d", sport->port.line + 1); ++ ++ dma_set_mask(&dev->dev, DMA_BIT_MASK(64)); ++ dma_set_coherent_mask(&dev->dev, DMA_BIT_MASK(64)); ++ if (ret > 0 && sport->dma_enable) { ++ dmares = platform_get_resource(dev, IORESOURCE_DMA, 0); ++ if (dmares) { ++ dmares = platform_get_resource(dev, IORESOURCE_DMA, 1); ++ if (dmares) ++ sport->dma_enable = 1; ++ } ++ } ++ ++ ret = request_irq(sport->port.irq, serial_pxa_irq, 0, sport->name, sport); ++ if (ret) ++ goto err_rst; ++ ++ disable_irq(sport->port.irq); ++ ++#ifdef CONFIG_PM ++#if SUPPORT_POWER_QOS ++ pm_runtime_enable(&dev->dev); ++ pm_runtime_set_active(&dev->dev); ++ pm_runtime_irq_safe(&dev->dev); ++#endif ++#endif ++ ++ sport->port.membase = ioremap(mmres->start, resource_size(mmres)); ++ if (!sport->port.membase) { ++ ret = -ENOMEM; ++ goto err_qos; ++ } ++ ++#ifdef CONFIG_PM ++ INIT_WORK(&sport->uart_tx_lpm_work, uart_tx_lpm_handler); ++ ++ timer_setup(&sport->pxa_timer, pxa_timer_handler, 0); ++#endif ++ ++ serial_pxa_ports[sport->port.line] = sport; ++ uart_add_one_port(&serial_pxa_reg, &sport->port); ++ dev_dbg(&dev->dev, "uart clk_rate: %lu\n", clk_get_rate(sport->fclk)); ++ platform_set_drvdata(dev, sport); ++ ++ return 0; ++ ++#ifdef CONFIG_PM ++ uart_remove_one_port(&serial_pxa_reg, &sport->port); ++ iounmap(sport->port.membase); ++#endif ++err_qos: ++#ifdef CONFIG_PM ++ pm_runtime_disable(&dev->dev); ++#endif ++ free_irq(sport->port.irq, sport); ++err_rst: ++ reset_control_assert(sport->resets); ++err_clk: ++ clk_unprepare(sport->fclk); ++ clk_unprepare(sport->gclk); ++ clk_put(sport->fclk); ++ clk_put(sport->gclk); ++err_free: ++ kfree(sport); ++ return ret; ++} ++ ++static int serial_pxa_remove(struct platform_device *dev) ++{ ++ struct uart_pxa_port *sport = platform_get_drvdata(dev); ++ ++#ifdef CONFIG_PM ++ pm_runtime_disable(&dev->dev); ++#endif ++ ++ uart_remove_one_port(&serial_pxa_reg, &sport->port); ++ ++ reset_control_assert(sport->resets); ++ free_irq(sport->port.irq, sport); ++ clk_unprepare(sport->fclk); ++ clk_unprepare(sport->gclk); ++ clk_put(sport->fclk); ++ clk_put(sport->gclk); ++ ++#ifdef CONFIG_PM ++ kfree(sport->uart_dma.tx_buf_save); ++#endif ++ kfree(sport); ++ serial_pxa_ports[dev->id] = NULL; ++ ++ return 0; ++} ++ ++static struct platform_driver serial_pxa_driver = { ++ .probe = serial_pxa_probe, ++ .remove = serial_pxa_remove, ++ .driver = { ++ .name = "spacemit-k1x-uart", ++#ifdef CONFIG_PM ++ .pm = &serial_pxa_pm_ops, ++#endif ++ .suppress_bind_attrs = true, ++ .of_match_table = serial_k1x_dt_ids, ++ }, ++}; ++ ++static int __init serial_pxa_init(void) ++{ ++ int ret; ++ ++ ret = uart_register_driver(&serial_pxa_reg); ++ if (ret != 0) ++ return ret; ++ ++ ret = platform_driver_register(&serial_pxa_driver); ++ if (ret != 0) ++ uart_unregister_driver(&serial_pxa_reg); ++ ++ return ret; ++} ++ ++static void __exit serial_pxa_exit(void) ++{ ++ platform_driver_unregister(&serial_pxa_driver); ++ uart_unregister_driver(&serial_pxa_reg); ++} ++module_init(serial_pxa_init); ++module_exit(serial_pxa_exit); ++ diff --git a/drivers/ufs/host/ufs-qcom.c b/drivers/ufs/host/ufs-qcom.c -index 3ec391d06020..8a684e489ca9 100644 +index 3491de5272e8..ed952dc4ce3b 100644 --- a/drivers/ufs/host/ufs-qcom.c +++ b/drivers/ufs/host/ufs-qcom.c -@@ -1814,8 +1814,8 @@ static int ufs_qcom_config_esi(struct ufs_hba *hba) +@@ -1812,8 +1812,8 @@ static int ufs_qcom_config_esi(struct ufs_hba *hba) * 2. Poll queues do not need ESI. */ nr_irqs = hba->nr_hw_queues - hba->nr_queues[HCTX_TYPE_POLL]; @@ -559680,7 +571700,7 @@ index 3ec391d06020..8a684e489ca9 100644 if (ret) { dev_err(hba->dev, "Failed to request Platform MSI %d\n", ret); goto out; -@@ -1844,7 +1844,7 @@ static int ufs_qcom_config_esi(struct ufs_hba *hba) +@@ -1842,7 +1842,7 @@ static int ufs_qcom_config_esi(struct ufs_hba *hba) devm_free_irq(hba->dev, desc->irq, hba); } msi_unlock_descs(hba->dev); @@ -559689,7 +571709,7 @@ index 3ec391d06020..8a684e489ca9 100644 } else { if (host->hw_ver.major == 6 && host->hw_ver.minor == 0 && host->hw_ver.step == 0) { -@@ -1924,7 +1924,8 @@ static void ufs_qcom_remove(struct platform_device *pdev) +@@ -1922,7 +1922,8 @@ static void ufs_qcom_remove(struct platform_device *pdev) ufshcd_pltfrm_remove(pdev); if (host->esi_enabled) @@ -559739,7 +571759,7 @@ index fe1493d4bbe5..9422571d469d 100644 +obj-$(CONFIG_USB_DWC3_RTK) += dwc3-rtk.o +obj-$(CONFIG_USB_DWC3_XUANTIE) += dwc3-xuantie.o diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c -index fcb509059d7c..4b1dd437e5f2 100644 +index 318ae24a41f4..ecf5c9afdc8b 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -42,6 +42,14 @@ @@ -559757,7 +571777,7 @@ index fcb509059d7c..4b1dd437e5f2 100644 /** * dwc3_get_dr_mode - Validates and sets dr_mode * @dwc: pointer to our context structure -@@ -1520,6 +1528,9 @@ static void dwc3_get_properties(struct dwc3 *dwc) +@@ -1518,6 +1526,9 @@ static void dwc3_get_properties(struct dwc3 *dwc) */ hird_threshold = 12; @@ -559767,7 +571787,7 @@ index fcb509059d7c..4b1dd437e5f2 100644 /* * default to a TXFIFO size large enough to fit 6 max packets. This * allows for systems with larger bus latencies to have some headroom -@@ -1527,11 +1538,16 @@ static void dwc3_get_properties(struct dwc3 *dwc) +@@ -1525,11 +1536,16 @@ static void dwc3_get_properties(struct dwc3 *dwc) */ tx_fifo_resize_max_num = 6; @@ -560795,6 +572815,235 @@ index 000000000000..5584243f9135 +#define SAFE_MODE 2 +#define BYPASS_MODE 3 +#endif +diff --git a/include/dt-bindings/clock/spacemit-k1x-clock.h b/include/dt-bindings/clock/spacemit-k1x-clock.h +new file mode 100644 +index 000000000000..5dd92a6cde71 +--- /dev/null ++++ b/include/dt-bindings/clock/spacemit-k1x-clock.h +@@ -0,0 +1,223 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++/* ++ * Copyright (c) 2022 Spacemit, Inc ++ */ ++ ++#ifndef _DT_BINDINGS_CLK_SPACEMIT_K1X_H_ ++#define _DT_BINDINGS_CLK_SPACEMIT_K1X_H_ ++ ++#define CLK_PLL2 0 ++#define CLK_PLL3 1 ++#define CLK_PLL1_D2 2 ++#define CLK_PLL1_D3 3 ++#define CLK_PLL1_D4 4 ++#define CLK_PLL1_D5 5 ++#define CLK_PLL1_D6 6 ++#define CLK_PLL1_D7 7 ++#define CLK_PLL1_D8 8 ++#define CLK_PLL1_D11 9 ++#define CLK_PLL1_D13 10 ++#define CLK_PLL1_D23 11 ++#define CLK_PLL1_D64 12 ++#define CLK_PLL1_D10_AUD 13 ++#define CLK_PLL1_D100_AUD 14 ++#define CLK_PLL2_D1 15 ++#define CLK_PLL2_D2 16 ++#define CLK_PLL2_D3 17 ++#define CLK_PLL2_D4 18 ++#define CLK_PLL2_D5 19 ++#define CLK_PLL2_D6 20 ++#define CLK_PLL2_D7 21 ++#define CLK_PLL2_D8 22 ++#define CLK_PLL3_D1 23 ++#define CLK_PLL3_D2 24 ++#define CLK_PLL3_D3 25 ++#define CLK_PLL3_D4 26 ++#define CLK_PLL3_D5 27 ++#define CLK_PLL3_D6 28 ++#define CLK_PLL3_D7 29 ++#define CLK_PLL3_D8 30 ++#define CLK_PLL1_307P2 31 ++#define CLK_PLL1_76P8 32 ++#define CLK_PLL1_61P44 33 ++#define CLK_PLL1_153P6 34 ++#define CLK_PLL1_102P4 35 ++#define CLK_PLL1_51P2 36 ++#define CLK_PLL1_51P2_AP 37 ++#define CLK_PLL1_57P6 38 ++#define CLK_PLL1_25P6 39 ++#define CLK_PLL1_12P8 40 ++#define CLK_PLL1_12P8_WDT 41 ++#define CLK_PLL1_6P4 42 ++#define CLK_PLL1_3P2 43 ++#define CLK_PLL1_1P6 44 ++#define CLK_PLL1_0P8 45 ++#define CLK_PLL1_351 46 ++#define CLK_PLL1_409P6 47 ++#define CLK_PLL1_204P8 48 ++#define CLK_PLL1_491 49 ++#define CLK_PLL1_245P76 50 ++#define CLK_PLL1_614 51 ++#define CLK_PLL1_47P26 52 ++#define CLK_PLL1_31P5 53 ++#define CLK_PLL1_819 54 ++#define CLK_PLL1_1228 55 ++#define CLK_SLOW_UART1 56 ++#define CLK_SLOW_UART2 57 ++#define CLK_UART1 58 ++#define CLK_UART2 59 ++#define CLK_UART3 60 ++#define CLK_UART4 61 ++#define CLK_UART5 62 ++#define CLK_UART6 63 ++#define CLK_UART7 64 ++#define CLK_UART8 65 ++#define CLK_UART9 66 ++#define CLK_GPIO 67 ++#define CLK_PWM0 68 ++#define CLK_PWM1 69 ++#define CLK_PWM2 70 ++#define CLK_PWM3 71 ++#define CLK_PWM4 72 ++#define CLK_PWM5 73 ++#define CLK_PWM6 74 ++#define CLK_PWM7 75 ++#define CLK_PWM8 76 ++#define CLK_PWM9 77 ++#define CLK_PWM10 78 ++#define CLK_PWM11 79 ++#define CLK_PWM12 80 ++#define CLK_PWM13 81 ++#define CLK_PWM14 82 ++#define CLK_PWM15 83 ++#define CLK_PWM16 84 ++#define CLK_PWM17 85 ++#define CLK_PWM18 86 ++#define CLK_PWM19 87 ++#define CLK_SSP3 88 ++#define CLK_RTC 89 ++#define CLK_TWSI0 90 ++#define CLK_TWSI1 91 ++#define CLK_TWSI2 92 ++#define CLK_TWSI4 93 ++#define CLK_TWSI5 94 ++#define CLK_TWSI6 95 ++#define CLK_TWSI7 96 ++#define CLK_TWSI8 97 ++#define CLK_TIMERS1 98 ++#define CLK_TIMERS2 99 ++#define CLK_AIB 100 ++#define CLK_ONEWIRE 101 ++#define CLK_SSPA0 102 ++#define CLK_SSPA1 103 ++#define CLK_DRO 104 ++#define CLK_IR 105 ++#define CLK_TSEN 106 ++#define CLK_IPC_AP2AUD 107 ++#define CLK_CAN0 108 ++#define CLK_CAN0_BUS 109 ++#define CLK_WDT 110 ++#define CLK_RIPC 111 ++#define CLK_JPG 112 ++#define CLK_JPF_4KAFBC 113 ++#define CLK_JPF_2KAFBC 114 ++#define CLK_CCIC2PHY 115 ++#define CLK_CCIC3PHY 116 ++#define CLK_CSI 117 ++#define CLK_CAMM0 118 ++#define CLK_CAMM1 119 ++#define CLK_CAMM2 120 ++#define CLK_ISP_CPP 121 ++#define CLK_ISP_BUS 122 ++#define CLK_ISP 123 ++#define CLK_DPU_MCLK 124 ++#define CLK_DPU_ESC 125 ++#define CLK_DPU_BIT 126 ++#define CLK_DPU_PXCLK 127 ++#define CLK_DPU_HCLK 128 ++#define CLK_DPU_SPI 129 ++#define CLK_DPU_SPI_HBUS 130 ++#define CLK_DPU_SPIBUS 131 ++#define CLK_SPU_SPI_ACLK 132 ++#define CLK_V2D 133 ++#define CLK_CCIC_4X 134 ++#define CLK_CCIC1PHY 135 ++#define CLK_SDH_AXI 136 ++#define CLK_SDH0 137 ++#define CLK_SDH1 138 ++#define CLK_SDH2 139 ++#define CLK_USB_P1 140 ++#define CLK_USB_AXI 141 ++#define CLK_USB30 142 ++#define CLK_QSPI 143 ++#define CLK_QSPI_BUS 144 ++#define CLK_DMA 145 ++#define CLK_AES 146 ++#define CLK_VPU 147 ++#define CLK_GPU 148 ++#define CLK_EMMC 149 ++#define CLK_EMMC_X 150 ++#define CLK_AUDIO 151 ++#define CLK_HDMI 152 ++#define CLK_CCI550 153 ++#define CLK_PMUA_ACLK 154 ++#define CLK_CPU_C0_HI 155 ++#define CLK_CPU_C0_CORE 156 ++#define CLK_CPU_C0_ACE 157 ++#define CLK_CPU_C0_TCM 158 ++#define CLK_CPU_C1_HI 159 ++#define CLK_CPU_C1_CORE 160 ++#define CLK_CPU_C1_ACE 161 ++#define CLK_PCIE0 162 ++#define CLK_PCIE1 163 ++#define CLK_PCIE2 164 ++#define CLK_EMAC0_BUS 165 ++#define CLK_EMAC0_PTP 166 ++#define CLK_EMAC1_BUS 167 ++#define CLK_EMAC1_PTP 168 ++#define CLK_SEC_UART1 169 ++#define CLK_SEC_SSP2 170 ++#define CLK_SEC_TWSI3 171 ++#define CLK_SEC_RTC 172 ++#define CLK_SEC_TIMERS0 173 ++#define CLK_SEC_KPC 174 ++#define CLK_SEC_GPIO 175 ++#define CLK_APB 176 ++#define CLK_PLL3_80 177 ++#define CLK_PLL3_40 178 ++#define CLK_PLL3_20 179 ++#define CLK_SLOW_UART 180 ++#define CLK_I2S_SYSCLK 181 ++#define CLK_I2S_BCLK 182 ++#define CLK_RCPU_HDMIAUDIO 183 ++#define CLK_RCPU_CAN 184 ++#define CLK_RCPU_CAN_BUS 185 ++#define CLK_RCPU_I2C0 186 ++#define CLK_RCPU_SSP0 187 ++#define CLK_RCPU_IR 188 ++#define CLK_RCPU_UART0 189 ++#define CLK_RCPU_UART1 190 ++#define CLK_DPLL1 191 ++#define CLK_DPLL2 192 ++#define CLK_DFC_LVL0 193 ++#define CLK_DFC_LVL1 194 ++#define CLK_DFC_LVL2 195 ++#define CLK_DFC_LVL3 196 ++#define CLK_DFC_LVL4 197 ++#define CLK_DFC_LVL5 198 ++#define CLK_DFC_LVL6 199 ++#define CLK_DFC_LVL7 200 ++#define CLK_DDR 201 ++#define CLK_RCPU2_PWM0 202 ++#define CLK_RCPU2_PWM1 203 ++#define CLK_RCPU2_PWM2 204 ++#define CLK_RCPU2_PWM3 205 ++#define CLK_RCPU2_PWM4 206 ++#define CLK_RCPU2_PWM5 207 ++#define CLK_RCPU2_PWM6 208 ++#define CLK_RCPU2_PWM7 209 ++#define CLK_RCPU2_PWM8 210 ++#define CLK_RCPU2_PWM9 211 ++#define CLK_MAX_NO 212 ++ ++#endif /* _DT_BINDINGS_CLK_SPACEMIT_K1X_H_ */ diff --git a/include/dt-bindings/clock/th1520-audiosys.h b/include/dt-bindings/clock/th1520-audiosys.h new file mode 100644 index 000000000000..2001545b68b8 @@ -561591,6 +573840,210 @@ index 000000000000..58789da8a237 +#define TH1520_AON_R_LAST 7 + +#endif +diff --git a/include/dt-bindings/pinctrl/k1-x-pinctrl.h b/include/dt-bindings/pinctrl/k1-x-pinctrl.h +new file mode 100644 +index 000000000000..3d3cb59e8aa3 +--- /dev/null ++++ b/include/dt-bindings/pinctrl/k1-x-pinctrl.h +@@ -0,0 +1,198 @@ ++/* SPDX-License-Identifier: GPL-2.0-or-later */ ++/*Copyright (C) 2023 Spacemit Co., Ltd. */ ++#ifndef __DT_BINDINGS_K1X_PINCTRL_H ++#define __DT_BINDINGS_K1X_PINCTRL_H ++ ++/* pin offset */ ++#define PINID(x) ((x) + 1) ++ ++#define GPIO_00 PINID(0) ++#define GPIO_01 PINID(1) ++#define GPIO_02 PINID(2) ++#define GPIO_03 PINID(3) ++#define GPIO_04 PINID(4) ++#define GPIO_05 PINID(5) ++#define GPIO_06 PINID(6) ++#define GPIO_07 PINID(7) ++#define GPIO_08 PINID(8) ++#define GPIO_09 PINID(9) ++#define GPIO_10 PINID(10) ++#define GPIO_11 PINID(11) ++#define GPIO_12 PINID(12) ++#define GPIO_13 PINID(13) ++#define GPIO_14 PINID(14) ++#define GPIO_15 PINID(15) ++#define GPIO_16 PINID(16) ++#define GPIO_17 PINID(17) ++#define GPIO_18 PINID(18) ++#define GPIO_19 PINID(19) ++#define GPIO_20 PINID(20) ++#define GPIO_21 PINID(21) ++#define GPIO_22 PINID(22) ++#define GPIO_23 PINID(23) ++#define GPIO_24 PINID(24) ++#define GPIO_25 PINID(25) ++#define GPIO_26 PINID(26) ++#define GPIO_27 PINID(27) ++#define GPIO_28 PINID(28) ++#define GPIO_29 PINID(29) ++#define GPIO_30 PINID(30) ++#define GPIO_31 PINID(31) ++ ++#define GPIO_32 PINID(32) ++#define GPIO_33 PINID(33) ++#define GPIO_34 PINID(34) ++#define GPIO_35 PINID(35) ++#define GPIO_36 PINID(36) ++#define GPIO_37 PINID(37) ++#define GPIO_38 PINID(38) ++#define GPIO_39 PINID(39) ++#define GPIO_40 PINID(40) ++#define GPIO_41 PINID(41) ++#define GPIO_42 PINID(42) ++#define GPIO_43 PINID(43) ++#define GPIO_44 PINID(44) ++#define GPIO_45 PINID(45) ++#define GPIO_46 PINID(46) ++#define GPIO_47 PINID(47) ++#define GPIO_48 PINID(48) ++#define GPIO_49 PINID(49) ++#define GPIO_50 PINID(50) ++#define GPIO_51 PINID(51) ++#define GPIO_52 PINID(52) ++#define GPIO_53 PINID(53) ++#define GPIO_54 PINID(54) ++#define GPIO_55 PINID(55) ++#define GPIO_56 PINID(56) ++#define GPIO_57 PINID(57) ++#define GPIO_58 PINID(58) ++#define GPIO_59 PINID(59) ++#define GPIO_60 PINID(60) ++#define GPIO_61 PINID(61) ++#define GPIO_62 PINID(62) ++#define GPIO_63 PINID(63) ++ ++#define GPIO_64 PINID(64) ++#define GPIO_65 PINID(65) ++#define GPIO_66 PINID(66) ++#define GPIO_67 PINID(67) ++#define GPIO_68 PINID(68) ++#define GPIO_69 PINID(69) ++#define PRI_TDI PINID(70) ++#define PRI_TMS PINID(71) ++#define PRI_TCK PINID(72) ++#define PRI_TDO PINID(73) ++#define GPIO_74 PINID(74) ++#define GPIO_75 PINID(75) ++#define GPIO_76 PINID(76) ++#define GPIO_77 PINID(77) ++#define GPIO_78 PINID(78) ++#define GPIO_79 PINID(79) ++#define GPIO_80 PINID(80) ++#define GPIO_81 PINID(81) ++#define GPIO_82 PINID(82) ++#define GPIO_83 PINID(83) ++#define GPIO_84 PINID(84) ++#define GPIO_85 PINID(85) ++ ++#define QSPI_DAT0 PINID(89) ++#define QSPI_DAT1 PINID(90) ++#define QSPI_DAT2 PINID(91) ++#define QSPI_DAT3 PINID(92) ++#define QSPI_CSI PINID(93) ++#define QSPI_CLK PINID(94) ++ ++#define MMC1_DAT3 PINID(109) ++#define MMC1_DAT2 PINID(110) ++#define MMC1_DAT1 PINID(111) ++#define MMC1_DAT0 PINID(112) ++#define MMC1_CMD PINID(113) ++#define MMC1_CLK PINID(114) ++#define GPIO_110 PINID(115) ++#define PWR_SCL PINID(116) ++#define PWR_SDA PINID(117) ++#define VCXO_EN PINID(118) ++#define DVL0 PINID(119) ++#define DVL1 PINID(120) ++#define PMIC_INT_N PINID(121) ++#define GPIO_86 PINID(122) ++#define GPIO_87 PINID(123) ++#define GPIO_88 PINID(124) ++#define GPIO_89 PINID(125) ++#define GPIO_90 PINID(126) ++#define GPIO_91 PINID(127) ++#define GPIO_92 PINID(128) ++ ++#define GPIO_111 PINID(130) ++#define GPIO_112 PINID(131) ++#define GPIO_113 PINID(132) ++#define GPIO_114 PINID(133) ++#define GPIO_115 PINID(134) ++#define GPIO_116 PINID(135) ++#define GPIO_117 PINID(136) ++#define GPIO_118 PINID(137) ++#define GPIO_119 PINID(138) ++#define GPIO_120 PINID(139) ++#define GPIO_121 PINID(140) ++#define GPIO_122 PINID(141) ++#define GPIO_123 PINID(142) ++#define GPIO_124 PINID(143) ++#define GPIO_125 PINID(144) ++#define GPIO_126 PINID(145) ++#define GPIO_127 PINID(146) ++ ++/* pin mux */ ++#define MUX_MODE0 0 ++#define MUX_MODE1 1 ++#define MUX_MODE2 2 ++#define MUX_MODE3 3 ++#define MUX_MODE4 4 ++#define MUX_MODE5 5 ++#define MUX_MODE6 6 ++#define MUX_MODE7 7 ++ ++/* strong pull resistor */ ++#define SPU_EN (1 << 3) ++ ++/* edge detect */ ++#define EDGE_NONE (1 << 6) ++#define EDGE_RISE (1 << 4) ++#define EDGE_FALL (1 << 5) ++#define EDGE_BOTH (3 << 4) ++ ++/* slew rate output control */ ++#define SLE_EN (1 << 7) ++ ++/* schmitter trigger input threshold */ ++#define ST00 (0 << 8) ++#define ST01 (1 << 8) ++#define ST02 (2 << 8) ++#define ST03 (3 << 8) ++ ++/* driver strength*/ ++#define PAD_1V8_DS0 (0 << 11) ++#define PAD_1V8_DS1 (1 << 11) ++#define PAD_1V8_DS2 (2 << 11) ++#define PAD_1V8_DS3 (3 << 11) ++ ++/* ++ * notice: !!! ++ * ds2 ---> bit10, ds1 ----> bit12, ds0 ----> bit11 ++ */ ++#define PAD_3V_DS0 (0 << 10) /* bit[12:10] 000 */ ++#define PAD_3V_DS1 (2 << 10) /* bit[12:10] 010 */ ++#define PAD_3V_DS2 (4 << 10) /* bit[12:10] 100 */ ++#define PAD_3V_DS3 (6 << 10) /* bit[12:10] 110 */ ++#define PAD_3V_DS4 (1 << 10) /* bit[12:10] 001 */ ++#define PAD_3V_DS5 (3 << 10) /* bit[12:10] 011 */ ++#define PAD_3V_DS6 (5 << 10) /* bit[12:10] 101 */ ++#define PAD_3V_DS7 (7 << 10) /* bit[12:10] 111 */ ++ ++/* pull up/down */ ++#define PULL_DIS (0 << 13) /* bit[15:13] 000 */ ++#define PULL_UP (6 << 13) /* bit[15:13] 110 */ ++#define PULL_DOWN (5 << 13) /* bit[15:13] 101 */ ++ ++#define K1X_PADCONF(pinid, conf, mux) ((pinid) * 4) (conf) (mux) ++ ++#endif /* __DT_BINDINGS_K1PRO_PINCTRL_H */ diff --git a/include/dt-bindings/reset/sophgo-mango-resets.h b/include/dt-bindings/reset/sophgo-mango-resets.h new file mode 100644 index 000000000000..9ff8ca4c3d67 @@ -561693,6 +574146,138 @@ index 000000000000..9ff8ca4c3d67 +#define RST_MAX_NUM (RST_RXU31+1) + +#endif +diff --git a/include/dt-bindings/reset/spacemit-k1x-reset.h b/include/dt-bindings/reset/spacemit-k1x-reset.h +new file mode 100644 +index 000000000000..dc5779b818fe +--- /dev/null ++++ b/include/dt-bindings/reset/spacemit-k1x-reset.h +@@ -0,0 +1,126 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* Copyright (c) 2023, spacemit Corporation. */ ++ ++#ifndef __DT_BINDINGS_RESET_SAPCEMIT_K1X_H__ ++#define __DT_BINDINGS_RESET_SAPCEMIT_K1X_H__ ++ ++#define RESET_UART1 1 ++#define RESET_UART2 2 ++#define RESET_GPIO 3 ++#define RESET_PWM0 4 ++#define RESET_PWM1 5 ++#define RESET_PWM2 6 ++#define RESET_PWM3 7 ++#define RESET_PWM4 8 ++#define RESET_PWM5 9 ++#define RESET_PWM6 10 ++#define RESET_PWM7 11 ++#define RESET_PWM8 12 ++#define RESET_PWM9 13 ++#define RESET_PWM10 14 ++#define RESET_PWM11 15 ++#define RESET_PWM12 16 ++#define RESET_PWM13 17 ++#define RESET_PWM14 18 ++#define RESET_PWM15 19 ++#define RESET_PWM16 20 ++#define RESET_PWM17 21 ++#define RESET_PWM18 22 ++#define RESET_PWM19 23 ++#define RESET_SSP3 24 ++#define RESET_UART3 25 ++#define RESET_RTC 26 ++#define RESET_TWSI0 27 ++#define RESET_TIMERS1 28 ++#define RESET_AIB 29 ++#define RESET_TIMERS2 30 ++#define RESET_ONEWIRE 31 ++#define RESET_SSPA0 32 ++#define RESET_SSPA1 33 ++#define RESET_DRO 34 ++#define RESET_IR 35 ++#define RESET_TWSI1 36 ++#define RESET_TSEN 37 ++#define RESET_TWSI2 38 ++#define RESET_TWSI4 39 ++#define RESET_TWSI5 40 ++#define RESET_TWSI6 41 ++#define RESET_TWSI7 42 ++#define RESET_TWSI8 43 ++#define RESET_IPC_AP2AUD 44 ++#define RESET_UART4 45 ++#define RESET_UART5 46 ++#define RESET_UART6 47 ++#define RESET_UART7 48 ++#define RESET_UART8 49 ++#define RESET_UART9 50 ++#define RESET_CAN0 51 ++#define RESET_WDT 52 ++#define RESET_JPG 53 ++#define RESET_CSI 54 ++#define RESET_CCIC2_PHY 55 ++#define RESET_CCIC3_PHY 56 ++#define RESET_ISP 57 ++#define RESET_ISP_AHB 58 ++#define RESET_ISP_CI 59 ++#define RESET_ISP_CPP 60 ++#define RESET_LCD 61 ++#define RESET_DSI_ESC 62 ++#define RESET_V2D 63 ++#define RESET_MIPI 64 ++#define RESET_LCD_SPI 65 ++#define RESET_LCD_SPI_BUS 66 ++#define RESET_LCD_SPI_HBUS 67 ++#define RESET_LCD_MCLK 68 ++#define RESET_CCIC_4X 69 ++#define RESET_CCIC1_PHY 70 ++#define RESET_SDH_AXI 71 ++#define RESET_SDH0 72 ++#define RESET_SDH1 73 ++#define RESET_USB_AXI 74 ++#define RESET_USBP1_AXI 75 ++#define RESET_USB3_0 76 ++#define RESET_QSPI 77 ++#define RESET_QSPI_BUS 78 ++#define RESET_DMA 79 ++#define RESET_AES 80 ++#define RESET_VPU 81 ++#define RESET_GPU 82 ++#define RESET_SDH2 83 ++#define RESET_MC 84 ++#define RESET_EM_AXI 85 ++#define RESET_EM 86 ++#define RESET_AUDIO_SYS 87 ++#define RESET_HDMI 88 ++#define RESET_PCIE0 89 ++#define RESET_PCIE1 90 ++#define RESET_PCIE2 91 ++#define RESET_EMAC0 92 ++#define RESET_EMAC1 93 ++#define RESET_SEC_UART1 94 ++#define RESET_SEC_SSP2 95 ++#define RESET_SEC_TWSI3 96 ++#define RESET_SEC_RTC 97 ++#define RESET_SEC_TIMERS0 98 ++#define RESET_SEC_KPC 99 ++#define RESET_SEC_GPIO 100 ++#define RESET_RCPU_HDMIAUDIO 101 ++#define RESET_RCPU_CAN 102 ++#define RESET_RCPU_I2C0 103 ++#define RESET_RCPU_SSP0 104 ++#define RESET_RCPU_IR 105 ++#define RESET_RCPU_UART0 106 ++#define RESET_RCPU_UART1 107 ++#define RESET_RCPU2_PWM0 108 ++#define RESET_RCPU2_PWM1 109 ++#define RESET_RCPU2_PWM2 110 ++#define RESET_RCPU2_PWM3 111 ++#define RESET_RCPU2_PWM4 112 ++#define RESET_RCPU2_PWM5 113 ++#define RESET_RCPU2_PWM6 114 ++#define RESET_RCPU2_PWM7 115 ++#define RESET_RCPU2_PWM8 116 ++#define RESET_RCPU2_PWM9 117 ++#define RESET_NUMBER 118 ++ ++#endif /* __DT_BINDINGS_RESET_SAPCEMIT_K1X_H__ */ diff --git a/include/dt-bindings/reset/xuantie,th1520-reset.h b/include/dt-bindings/reset/xuantie,th1520-reset.h new file mode 100644 index 000000000000..44a4581cc229 @@ -563430,10 +576015,10 @@ index ef9f9a4e928d..824220b20ad7 100644 /* * This thread may hit another WARN() in the panic path. diff --git a/kernel/sched/core.c b/kernel/sched/core.c -index 6a01cd02b579..615126e2eac2 100644 +index 7dc4ceebd5ec..f8f3117e0c42 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c -@@ -6663,7 +6663,9 @@ static void __sched notrace __schedule(unsigned int sched_mode) +@@ -6665,7 +6665,9 @@ static void __sched notrace __schedule(unsigned int sched_mode) * if (signal_pending_state()) if (p->state & @state) * * Also, the membarrier system call requires a full memory barrier @@ -563444,7 +576029,7 @@ index 6a01cd02b579..615126e2eac2 100644 */ rq_lock(rq, &rf); smp_mb__after_spinlock(); -@@ -6741,6 +6743,13 @@ static void __sched notrace __schedule(unsigned int sched_mode) +@@ -6743,6 +6745,13 @@ static void __sched notrace __schedule(unsigned int sched_mode) * architectures where spin_unlock is a full barrier, * - switch_to() for arm64 (weakly-ordered, spin_unlock * is a RELEASE barrier), @@ -563459,7 +576044,7 @@ index 6a01cd02b579..615126e2eac2 100644 ++*switch_count; diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c -index c9a4ea466689..5755f9978166 100644 +index c530d501bb48..e7bf6ef150be 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -10614,6 +10614,9 @@ int can_migrate_task(struct task_struct *p, struct lb_env *env) @@ -564200,7 +576785,7 @@ index a11cd7d6295f..03ecfa43bc3a 100644 return -EPIPE; } diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c -index 77ed507fc6e1..82e4d8d8801f 100644 +index 986c38a50166..d6683050c62b 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -298,8 +298,7 @@ enum { @@ -564244,7 +576829,7 @@ index 8376fdb217ed..1b211fbb873b 100644 obj-$(CONFIG_SND_SOC) += xtensa/ +obj-$(CONFIG_SND_SOC) += xuantie/ diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig -index f1e1dbc509f6..fc394a65f681 100644 +index 6d105a23c828..68e7aa0479b4 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -54,6 +54,7 @@ config SND_SOC_ALL_CODECS diff --git a/kernel.spec b/kernel.spec index 87519e45..84b3ba5a 100644 --- a/kernel.spec +++ b/kernel.spec @@ -42,7 +42,7 @@ rm -f test_openEuler_sign.ko test_openEuler_sign.ko.sig %global upstream_sublevel 0 %global devel_release 88 %global maintenance_release .0.0 -%global pkg_release .91 +%global pkg_release .92 %global openeuler_lts 1 %global openeuler_major 2403 @@ -1087,6 +1087,14 @@ fi %endif %changelog +* Wed May 07 2025 Mingzheng Xing - 6.6.0-88.0.0.92 +- riscv kernel upgrade to 6.6.0-88.0.0 +- RISC-V: Remove unnecessary include from compat.h +- KVM AIA: Enable HW_ACCL +- spacemit k1 dts/clk/reset/pinctrl/gpio/uart support +- Enable ROCm-related kernel configs and update openeuler_defconfig +- kconfig: enable zstd-compressed firmware support + * Fri Apr 25 2025 Li Nan - 6.6.0-88.0.0.91 - !16007 compile error: implicit declaration of - kvm: hisi_virt: Fix compilation error due to missing ACPI configuration -- Gitee